From cd998aaadd946d023567381a59512c639932e468 Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Sun, 16 Sep 2007 16:23:21 +0000 Subject: [PATCH 001/246] Initial checkin of cloth files + changes --- extern/bullet2/src/Bullet-C-Api.h | 15 + .../bullet2/src/BulletDynamics/CMakeLists.txt | 1 + .../BulletDynamics/Dynamics/Bullet-C-Api.cpp | 92 + extern/bullet2/src/SConscript | 1 + source/blender/blenkernel/BKE_cloth.h | 243 +++ source/blender/blenkernel/SConscript | 1 + source/blender/blenkernel/intern/cloth.c | 1344 +++++++++++++++ source/blender/blenkernel/intern/collision.c | 638 +++++++ source/blender/blenkernel/intern/implicit.c | 1511 +++++++++++++++++ source/blender/blenkernel/intern/kdop.c | 861 ++++++++++ source/blender/blenkernel/intern/modifier.c | 105 ++ source/blender/blenloader/intern/readfile.c | 15 +- source/blender/blenloader/intern/writefile.c | 16 + source/blender/include/butspace.h | 7 + source/blender/makesdna/DNA_cloth_types.h | 150 ++ source/blender/makesdna/DNA_modifier_types.h | 11 + source/blender/makesdna/intern/makesdna.c | 2 + source/blender/src/buttons_object.c | 291 +++- 18 files changed, 5299 insertions(+), 5 deletions(-) create mode 100644 extern/bullet2/src/Bullet-C-Api.h create mode 100644 extern/bullet2/src/BulletDynamics/Dynamics/Bullet-C-Api.cpp create mode 100644 source/blender/blenkernel/BKE_cloth.h create mode 100644 source/blender/blenkernel/intern/cloth.c create mode 100644 source/blender/blenkernel/intern/collision.c create mode 100644 source/blender/blenkernel/intern/implicit.c create mode 100644 source/blender/blenkernel/intern/kdop.c create mode 100644 source/blender/makesdna/DNA_cloth_types.h diff --git a/extern/bullet2/src/Bullet-C-Api.h b/extern/bullet2/src/Bullet-C-Api.h new file mode 100644 index 00000000000..2d35383e902 --- /dev/null +++ b/extern/bullet2/src/Bullet-C-Api.h @@ -0,0 +1,15 @@ +#ifndef Bullet_C_API_H +#define Bullet_C_API_H + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +double plNearestPoints(float p[3][3], float q[3][3], float *pa, float *pb, float normal[3]); + +#ifdef __cplusplus +} +#endif // __cplusplus + +#endif + diff --git a/extern/bullet2/src/BulletDynamics/CMakeLists.txt b/extern/bullet2/src/BulletDynamics/CMakeLists.txt index 79e07b7f77b..4cda87a146a 100644 --- a/extern/bullet2/src/BulletDynamics/CMakeLists.txt +++ b/extern/bullet2/src/BulletDynamics/CMakeLists.txt @@ -14,6 +14,7 @@ ADD_LIBRARY(LibBulletDynamics Dynamics/btDiscreteDynamicsWorld.cpp Dynamics/btSimpleDynamicsWorld.cpp Dynamics/btRigidBody.cpp + Dynamics/Bullet-C-Api.cpp Vehicle/btRaycastVehicle.cpp Vehicle/btWheelInfo.cpp ) diff --git a/extern/bullet2/src/BulletDynamics/Dynamics/Bullet-C-Api.cpp b/extern/bullet2/src/BulletDynamics/Dynamics/Bullet-C-Api.cpp new file mode 100644 index 00000000000..2ae30e851dc --- /dev/null +++ b/extern/bullet2/src/BulletDynamics/Dynamics/Bullet-C-Api.cpp @@ -0,0 +1,92 @@ +#include "LinearMath/btVector3.h" +#include "LinearMath/btScalar.h" +#include "LinearMath/btMatrix3x3.h" +#include "LinearMath/btTransform.h" +#include "BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.h" +#include "BulletCollision/CollisionShapes/btTriangleShape.h" + +#include "BulletCollision/NarrowPhaseCollision/btGjkPairDetector.h" +#include "BulletCollision/NarrowPhaseCollision/btPointCollector.h" +#include "BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.h" +#include "BulletCollision/NarrowPhaseCollision/btSubSimplexConvexCast.h" +#include "BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.h" +#include "BulletCollision/NarrowPhaseCollision/btGjkEpa.h" +#include "BulletCollision/CollisionShapes/btMinkowskiSumShape.h" +#include "BulletCollision/NarrowPhaseCollision/btSubSimplexConvexCast.h" +#include "BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.h" +#include "BulletCollision/NarrowPhaseCollision/btGjkPairDetector.h" + +#include "BulletCollision/NarrowPhaseCollision/btDiscreteCollisionDetectorInterface.h" +#include "BulletCollision/NarrowPhaseCollision/btSimplexSolverInterface.h" +#include "BulletCollision/NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.h" +#include "BulletCollision/NarrowPhaseCollision/btGjkPairDetector.h" +#include "BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.h" +#include "LinearMath/btStackAlloc.h" + + +extern "C" +double plNearestPoints(float p[3][3], float q[3][3], float *pa, float *pb, float normal[3]) +{ + btTriangleShape trishapeA(btVector3(p[0][0], p[0][1], p[0][2]), btVector3(p[1][0], p[1][1], p[1][2]), btVector3(p[2][0], p[2][1], p[2][2])); + trishapeA.setMargin(0.001f); + + btTriangleShape trishapeB(btVector3(q[0][0], q[0][1], q[0][2]), btVector3(q[1][0], q[1][1], q[1][2]), btVector3(q[2][0], q[2][1], q[2][2])); + trishapeB.setMargin(0.001f); + + // btVoronoiSimplexSolver sGjkSimplexSolver; + // btGjkEpaPenetrationDepthSolver penSolverPtr; + + static btSimplexSolverInterface sGjkSimplexSolver; + sGjkSimplexSolver.reset(); + + static btGjkEpaPenetrationDepthSolver Solver0; + static btMinkowskiPenetrationDepthSolver Solver1; + + btConvexPenetrationDepthSolver* Solver = NULL; + + Solver = &Solver1; + + + btGjkPairDetector convexConvex(&trishapeA ,&trishapeB,&sGjkSimplexSolver,Solver); + + convexConvex.m_catchDegeneracies = 1; + + // btGjkPairDetector convexConvex(&trishapeA ,&trishapeB,&sGjkSimplexSolver,0); + + btPointCollector gjkOutput; + btGjkPairDetector::ClosestPointInput input; + + btStackAlloc gStackAlloc(1024*1024*2); + + input.m_stackAlloc = &gStackAlloc; + + btTransform tr; + tr.setIdentity(); + + input.m_transformA = tr; + input.m_transformB = tr; + + convexConvex.getClosestPoints(input, gjkOutput, 0); + + + if (gjkOutput.m_hasResult) + { + + pb[0] = pa[0] = gjkOutput.m_pointInWorld[0]; + pb[1] = pa[1] = gjkOutput.m_pointInWorld[1]; + pb[2] = pa[2] = gjkOutput.m_pointInWorld[2]; + + pb[0]+= gjkOutput.m_normalOnBInWorld[0] * gjkOutput.m_distance; + pb[1]+= gjkOutput.m_normalOnBInWorld[1] * gjkOutput.m_distance; + pb[2]+= gjkOutput.m_normalOnBInWorld[2] * gjkOutput.m_distance; + + normal[0] = gjkOutput.m_normalOnBInWorld[0]; + normal[1] = gjkOutput.m_normalOnBInWorld[1]; + normal[2] = gjkOutput.m_normalOnBInWorld[2]; + + return gjkOutput.m_distance; + } + return -1.0f; +} + + diff --git a/extern/bullet2/src/SConscript b/extern/bullet2/src/SConscript index 6280c49066d..127752777c8 100644 --- a/extern/bullet2/src/SConscript +++ b/extern/bullet2/src/SConscript @@ -33,6 +33,7 @@ bulletdyn_src = ["BulletDynamics/ConstraintSolver/btContactConstraint.cpp", "BulletDynamics/Dynamics/btDiscreteDynamicsWorld.cpp", "BulletDynamics/Dynamics/btSimpleDynamicsWorld.cpp", "BulletDynamics/Dynamics/btRigidBody.cpp", + "BulletDynamics/Dynamics/Bullet-C-Api.cpp", "BulletDynamics/Vehicle/btRaycastVehicle.cpp", "BulletDynamics/Vehicle/btWheelInfo.cpp"] collision_src = ["BulletCollision/BroadphaseCollision/btAxisSweep3.cpp", diff --git a/source/blender/blenkernel/BKE_cloth.h b/source/blender/blenkernel/BKE_cloth.h new file mode 100644 index 00000000000..e843079f412 --- /dev/null +++ b/source/blender/blenkernel/BKE_cloth.h @@ -0,0 +1,243 @@ +/** +* BKE_cloth.h +* +* $Id: BKE_cloth.h,v 1.1 2007/08/01 02:07:27 daniel Exp $ +* +* ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* as published by the Free Software Foundation; either version 2 +* of the License, or (at your option) any later version. The Blender +* Foundation also sells licenses for use in proprietary software under +* the Blender License. See http://www.blender.org/BL/ for information +* about this. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software Foundation, +* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +* +* The Original Code is Copyright (C) Blender Foundation. +* All rights reserved. +* +* The Original Code is: all of this file. +* +* Contributor(s): none yet. +* +* ***** END GPL/BL DUAL LICENSE BLOCK ***** +*/ +#ifndef BKE_CLOTH_H +#define BKE_CLOTH_H + +#include "BKE_DerivedMesh.h" +#include "DNA_customdata_types.h" +#include "BKE_customdata.h" +#include "DNA_meshdata_types.h" + +struct Object; +struct Cloth; +struct MFace; +struct DerivedMesh; + +// this is needed for inlining behaviour +#ifndef _WIN32 + #define LINUX + #define DO_INLINE inline +#else + #define DO_INLINE +#endif + + +/* goal defines */ +#define SOFTGOALSNAP 0.999f + +/* This is approximately the smallest number that can be +* represented by a float, given its precision. */ +#define ALMOST_ZERO 0.0000001 + +/* Bits to or into the ClothVertex.flags. */ +#define CVERT_FLAG_PINNED 1 +#define CVERT_FLAG_COLLISION 2 + + +// some macro enhancements for vector treatment +#define VECADDADD(v1,v2,v3) {*(v1)+= *(v2) + *(v3); *(v1+1)+= *(v2+1) + *(v3+1); *(v1+2)+= *(v2+2) + *(v3+2);} +#define VECSUBADD(v1,v2,v3) {*(v1)-= *(v2) + *(v3); *(v1+1)-= *(v2+1) + *(v3+1); *(v1+2)-= *(v2+2) + *(v3+2);} +#define VECADDSUB(v1,v2,v3) {*(v1)+= *(v2) - *(v3); *(v1+1)+= *(v2+1) - *(v3+1); *(v1+2)+= *(v2+2) - *(v3+2);} +#define VECSUBADDSS(v1,v2,aS,v3,bS) {*(v1)-= *(v2)*aS + *(v3)*bS; *(v1+1)-= *(v2+1)*aS + *(v3+1)*bS; *(v1+2)-= *(v2+2)*aS + *(v3+2)*bS;} +#define VECADDSUBSS(v1,v2,aS,v3,bS) {*(v1)+= *(v2)*aS - *(v3)*bS; *(v1+1)+= *(v2+1)*aS - *(v3+1)*bS; *(v1+2)+= *(v2+2)*aS - *(v3+2)*bS;} +#define VECADDSS(v1,v2,aS,v3,bS) {*(v1)= *(v2)*aS + *(v3)*bS; *(v1+1)= *(v2+1)*aS + *(v3+1)*bS; *(v1+2)= *(v2+2)*aS + *(v3+2)*bS;} +#define VECADDS(v1,v2,v3,bS) {*(v1)= *(v2) + *(v3)*bS; *(v1+1)= *(v2+1) + *(v3+1)*bS; *(v1+2)= *(v2+2) + *(v3+2)*bS;} +#define VECSUBMUL(v1,v2,aS) {*(v1)-= *(v2) * aS; *(v1+1)-= *(v2+1) * aS; *(v1+2)-= *(v2+2) * aS;} +#define VECSUBS(v1,v2,v3,bS) {*(v1)= *(v2) - *(v3)*bS; *(v1+1)= *(v2+1) - *(v3+1)*bS; *(v1+2)= *(v2+2) - *(v3+2)*bS;} +#define VECSUBSB(v1,v2, v3,bS) {*(v1)= (*(v2)- *(v3))*bS; *(v1+1)= (*(v2+1) - *(v3+1))*bS; *(v1+2)= (*(v2+2) - *(v3+2))*bS;} +#define VECMULS(v1,aS) {*(v1)*= aS; *(v1+1)*= aS; *(v1+2)*= *aS;} +#define VECADDMUL(v1,v2,aS) {*(v1)+= *(v2) * aS; *(v1+1)+= *(v2+1) * aS; *(v1+2)+= *(v2+2) * aS;} + +/* SIMULATION FLAGS: goal flags,.. */ +/* These are the bits used in SimSettings.flags. */ +typedef enum +{ + CSIMSETT_FLAG_RESET = (1 << 1), // The CM object requires a reinitializaiton. + CSIMSETT_FLAG_COLLOBJ = (1 << 2), // object is only collision object, no cloth simulation is done + CSIMSETT_FLAG_GOAL = (1 << 3), // we have goals enabled + CSIMSETT_FLAG_CCACHE_FREE_ALL = (1 << 4), // delete all from cache + CSIMSETT_FLAG_CCACHE_FREE_PART = (1 << 5), // delete some part of cache + CSIMSETT_FLAG_TEARING_ENABLED = (1 << 6), // true if tearing is enabled +} CSIMSETT_FLAGS; + +/* Spring types as defined in the paper.*/ +typedef enum +{ + STRUCTURAL = 0, + SHEAR, + BENDING, +} springType; + +/* SPRING FLAGS */ +typedef enum +{ + CSPRING_FLAG_DEACTIVATE = (1 << 1), +} CSPRINGS_FLAGS; + +// needed for buttons_object.c +void cloth_cache_free(ClothModifierData *clmd, float time); + +// needed for cloth.c +void implicit_set_positions (ClothModifierData *clmd); + +// from cloth.c, needed for modifier.c +void clothModifier_do(ClothModifierData *clmd, Object *ob, DerivedMesh *dm, float (*vertexCos)[3], int numverts); + +// used in collision.c +typedef struct Tree { + struct Tree *nodes[4]; // 4 children --> quad-tree + struct Tree *parent; + struct Tree *nextLeaf; + struct Tree *prevLeaf; + float bv[26]; // Bounding volume of all nodes / we have 7 axes on a 14-DOP + unsigned int tri_index; // this saves the index of the face + int count_nodes; // how many nodes are used + int traversed; // how many nodes already traversed until this level? + int isleaf; +} Tree; + +typedef struct Tree TreeNode; + +typedef struct BVH{ + unsigned int numfaces; + unsigned int numverts; + ClothVertex *verts; // just a pointer to the original datastructure + MFace *mfaces; // just a pointer to the original datastructure + struct LinkNode *tree; + TreeNode *root; // TODO: saving the root --> is this really needed? YES! + TreeNode *leaf_tree; /* Tail of the leaf linked list. */ + TreeNode *leaf_root; /* Head of the leaf linked list. */ + float epsilon; /* epslion is used for inflation of the k-dop */ + int flags; /* bvhFlags */ +} BVH; + +typedef void (*CM_COLLISION_RESPONSE) (ClothModifierData *clmd, ClothModifierData *coll_clmd, Tree * tree1, Tree * tree2); + + +///////////////////////////////////////////////// +// collision.c +//////////////////////////////////////////////// + +// needed for implicit.c +void bvh_collision_response(ClothModifierData *clmd, ClothModifierData *coll_clmd, Tree * tree1, Tree * tree2); +int cloth_bvh_objcollision(ClothModifierData * clmd, float step, CM_COLLISION_RESPONSE collision_response, float dt); + +//////////////////////////////////////////////// + + +///////////////////////////////////////////////// +// kdop.c +//////////////////////////////////////////////// + +// needed for implicit.c +void bvh_update_static(ClothModifierData * clmd, BVH * bvh); +void bvh_update_moving(ClothModifierData * clmd, BVH * bvh); + +// needed for cloth.c +void bvh_free(BVH * bvh); +BVH *bvh_build (ClothModifierData *clmd, float epsilon); + +// needed for collision.c +int bvh_traverse(ClothModifierData * clmd, ClothModifierData * coll_clmd, Tree * tree1, Tree * tree2, float step, CM_COLLISION_RESPONSE collision_response); + +//////////////////////////////////////////////// + + + +///////////////////////////////////////////////// +// cloth.c +//////////////////////////////////////////////// +void cloth_free_modifier (ClothModifierData *clmd); +void cloth_init (ClothModifierData *clmd); +void cloth_deform_verts(struct Object *ob, float framenr, float (*vertexCos)[3], int numVerts, void *derivedData, ClothModifierData *clmd); +void cloth_update_normals (ClothVertex *verts, int nVerts, MFace *face, int totface); + +//////////////////////////////////////////////// + + +/* Typedefs for function pointers we need for solvers and collision detection. */ +typedef void (*CM_COLLISION_SELF) (ClothModifierData *clmd, int step); +typedef void (*CM_COLLISION_OBJ) (ClothModifierData *clmd, int step, CM_COLLISION_RESPONSE collision_response); + + +/* This enum provides the IDs for our solvers. */ +// only one available in the moment +typedef enum { + CM_IMPLICIT = 0, +} CM_SOLVER_ID; + + +/* This structure defines how to call the solver. +*/ +typedef struct { + char *name; + CM_SOLVER_ID id; + int (*init) (Object *ob, ClothModifierData *clmd); + int (*solver) (Object *ob, float framenr, ClothModifierData *clmd, ListBase *effectors, + CM_COLLISION_SELF self_collision, CM_COLLISION_OBJ obj_collision); + int (*free) (ClothModifierData *clmd); +} CM_SOLVER_DEF; + + +/* new C implicit simulator */ +int implicit_init (Object *ob, ClothModifierData *clmd); +int implicit_free (ClothModifierData *clmd); +int implicit_solver (Object *ob, float frame, ClothModifierData *clmd, ListBase *effectors, + CM_COLLISION_SELF self_collision, CM_COLLISION_OBJ obj_collision); + +/* used for caching in implicit.c */ +typedef struct Frame +{ + ClothVertex *verts; + ClothSpring *springs; + float time; /* we need float since we want to support sub-frames */ +} Frame; + +/* used for collisions in collision.c */ +typedef struct CollPair +{ + unsigned int face1; // cloth face + unsigned int face2; // object face + double distance; // magnitude of vector + float normal[3]; + float vector[3]; // unnormalized collision vector: p2-p1 + float p1[3], p2[3]; // collision point p1 on face1, p2 on face2 + int lastsign; // indicates if the distance sign has changed, unused itm + float time; // collision time, from 0 up to 1 + int quadA, quadB; // indicates the used triangle of the quad: 0 means verts 1,2,3; 1 means verts 4,1,3 +} CollPair; + + +#endif + diff --git a/source/blender/blenkernel/SConscript b/source/blender/blenkernel/SConscript index 5316c50694a..3403490b778 100644 --- a/source/blender/blenkernel/SConscript +++ b/source/blender/blenkernel/SConscript @@ -7,6 +7,7 @@ incs = '. #/intern/guardedalloc ../include ../blenlib ../makesdna' incs += ' ../python ../render/extern/include #/intern/decimation/extern' incs += ' ../imbuf ../avi #/intern/elbeem/extern ../nodes' incs += ' #/intern/iksolver/extern ../blenloader ../quicktime' +incs += ' #/extern/bullet2/src ' incs += ' ' + env['BF_OPENGL_INC'] incs += ' ' + env['BF_ZLIB_INC'] diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c new file mode 100644 index 00000000000..4b4aa2d0d1d --- /dev/null +++ b/source/blender/blenkernel/intern/cloth.c @@ -0,0 +1,1344 @@ +/* cloth.c +* +* +* ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* as published by the Free Software Foundation; either version 2 +* of the License, or (at your option) any later version. The Blender +* Foundation also sells licenses for use in proprietary software under +* the Blender License. See http://www.blender.org/BL/ for information +* about this. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software Foundation, +* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +* +* The Original Code is Copyright (C) Blender Foundation +* All rights reserved. +* +* The Original Code is: all of this file. +* +* Contributor(s): none yet. +* +* ***** END GPL/BL DUAL LICENSE BLOCK ***** +*/ + + +#include +#include +#include + +#include "MEM_guardedalloc.h" + +/* types */ +#include "DNA_curve_types.h" +#include "DNA_object_types.h" +#include "DNA_object_force.h" +#include "DNA_cloth_types.h" +#include "DNA_key_types.h" +#include "DNA_mesh_types.h" +#include "DNA_meshdata_types.h" +#include "DNA_lattice_types.h" +#include "DNA_scene_types.h" +#include "DNA_modifier_types.h" + +#include "BLI_blenlib.h" +#include "BLI_arithb.h" +#include "BLI_edgehash.h" +#include "BLI_linklist.h" + +#include "BKE_curve.h" +#include "BKE_deform.h" +#include "BKE_DerivedMesh.h" +#include "BKE_cdderivedmesh.h" +#include "BKE_displist.h" +#include "BKE_effect.h" +#include "BKE_global.h" +#include "BKE_key.h" +#include "BKE_mesh.h" +#include "BKE_object.h" +#include "BKE_cloth.h" +#include "BKE_modifier.h" +#include "BKE_utildefines.h" +#include "BKE_DerivedMesh.h" +#include "BIF_editdeform.h" +#include "BIF_editkey.h" +#include "DNA_screen_types.h" +#include "BSE_headerbuttons.h" +#include "BIF_screen.h" +#include "BIF_space.h" +#include "mydevice.h" + +#ifdef _WIN32 +void tstart(void) +{ +} +void tend(void) +{ + +} +double tval() +{ + return 0; +} +#else +#include +static struct timeval _tstart, _tend; +static struct timezone tz; +void tstart(void) +{ + gettimeofday(&_tstart, &tz); +} +void tend(void) +{ + gettimeofday(&_tend,&tz); +} +double tval() +{ + double t1, t2; + t1 = (double)_tstart.tv_sec + (double)_tstart.tv_usec/(1000*1000); + t2 = (double)_tend.tv_sec + (double)_tend.tv_usec/(1000*1000); + return t2-t1; +} +#endif + +/* Our available solvers. */ +// 255 is the magic reserved number, so NEVER try to put 255 solvers in here! +// 254 = MAX! +static CM_SOLVER_DEF solvers [] = { + { "Implicit", CM_IMPLICIT, implicit_init, implicit_solver, implicit_free }, + // { "Implicit C++", CM_IMPLICITCPP, implicitcpp_init, implicitcpp_solver, implicitcpp_free }, +}; + +#define DEBUG_CLOTH_VERBOSE 1000 +static int DEBUG_CLOTH = 0; +/* ********** cloth engine ******* */ +/* Prototypes for internal functions. +*/ +static void cloth_to_object (Object *ob, ClothModifierData *clmd, float (*vertexCos)[3], unsigned int numverts); +static void cloth_from_mesh (Object *ob, ClothModifierData *clmd, DerivedMesh *dm); +static int cloth_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *dm, float (*vertexCos)[3], unsigned int numverts); +static int collobj_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *dm, float (*vertexCos)[3], unsigned int numverts); +int cloth_build_springs(Cloth *cloth, DerivedMesh *dm); +static void cloth_apply_vgroup(ClothModifierData *clmd, DerivedMesh *dm, short vgroup); +/****************************************************************************** +* +* External interface called by modifier.c clothModifier functions. +* +******************************************************************************/ +/** +* cloth_init - creates a new cloth simulation. +* +* 1. create object +* 2. fill object with standard values or with the GUI settings if given +*/ +void cloth_init (ClothModifierData *clmd) +{ + /* Initialize our new data structure to reasonable values. */ + clmd->sim_parms.gravity [0] = 0.0; + clmd->sim_parms.gravity [1] = 0.0; + clmd->sim_parms.gravity [2] = -9.81; + clmd->sim_parms.structural = 100.0; + clmd->sim_parms.shear = 100.0; + clmd->sim_parms.bending = 1.0; + clmd->sim_parms.Cdis = 5.0; + clmd->sim_parms.Cvi = 1.0; + clmd->sim_parms.mass = 1.0f; + clmd->sim_parms.stepsPerFrame = 5; + clmd->sim_parms.sim_time = 1.0; + clmd->sim_parms.flags = CSIMSETT_FLAG_RESET; + clmd->sim_parms.solver_type = 0; + clmd->sim_parms.preroll = 0; + clmd->sim_parms.maxspringlen = 10; + clmd->coll_parms.self_friction = 5.0; + clmd->coll_parms.friction = 10.0; + clmd->coll_parms.loop_count = 1; + clmd->coll_parms.epsilon = 0.01f; + + /* These defaults are copied from softbody.c's + * softbody_calc_forces() function. + */ + clmd->sim_parms.eff_force_scale = 1000.0; + clmd->sim_parms.eff_wind_scale = 250.0; + + // also from softbodies + clmd->sim_parms.maxgoal = 1.0f; + clmd->sim_parms.mingoal = 0.0f; + clmd->sim_parms.defgoal = 0.7f; + clmd->sim_parms.goalspring = 100.0f; + clmd->sim_parms.goalfrict = 0.0f; + + clmd->sim_parms.cache = NULL; +} + +// unused in the moment, cloth needs quads from mesh +DerivedMesh *CDDM_convert_to_triangle(DerivedMesh *dm) +{ + DerivedMesh *result = NULL; + int i; + int numverts = dm->getNumVerts(dm); + int numedges = dm->getNumEdges(dm); + int numfaces = dm->getNumFaces(dm); + + MVert *mvert = CDDM_get_verts(dm); + MEdge *medge = CDDM_get_edges(dm); + MFace *mface = CDDM_get_faces(dm); + + MVert *mvert2; + MFace *mface2; + unsigned int numtris=0; + unsigned int numquads=0; + int a = 0; + int random = 0; + int firsttime = 0; + float vec1[3], vec2[3], vec3[3], vec4[3], vec5[3]; + float mag1=0, mag2=0; + + for(i = 0; i < numfaces; i++) + { + if(mface[i].v4) + numquads++; + else + numtris++; + } + + result = CDDM_from_template(dm, numverts, 0, numtris + 2*numquads); + + if(!result) + return NULL; + + // do verts + mvert2 = CDDM_get_verts(result); + for(a=0; av1 = mface[a].v2; + mf->v2 = mface[a].v3; + mf->v3 = mface[a].v4; + } + else + { + mf->v1 = mface[a].v1; + mf->v2 = mface[a].v2; + mf->v3 = mface[a].v3; + } + + mf->v4 = 0; + mf->flag |= ME_SMOOTH; + + test_index_face(mf, NULL, 0, 3); + + if(mface[a].v4) + { + MFace *mf2; + + i++; + + mf2 = &mface2[i]; + /* + DM_copy_face_data(dm, result, a, i, 1); + + *mf2 = *inMF; + */ + + if(random==1) + { + mf2->v1 = mface[a].v1; + mf2->v2 = mface[a].v2; + mf2->v3 = mface[a].v4; + } + else + { + mf2->v1 = mface[a].v4; + mf2->v2 = mface[a].v1; + mf2->v3 = mface[a].v3; + } + mf2->v4 = 0; + mf2->flag |= ME_SMOOTH; + + test_index_face(mf2, NULL, 0, 3); + } + + i++; + } + + CDDM_calc_edges(result); + CDDM_calc_normals(result); + + return result; + +} + + +DerivedMesh *CDDM_create_tearing(ClothModifierData *clmd, DerivedMesh *dm) +{ + DerivedMesh *result = NULL; + unsigned int i = 0, a = 0, j=0; + int numverts = dm->getNumVerts(dm); + int numedges = dm->getNumEdges(dm); + int numfaces = dm->getNumFaces(dm); + + MVert *mvert = CDDM_get_verts(dm); + MEdge *medge = CDDM_get_edges(dm); + MFace *mface = CDDM_get_faces(dm); + + MVert *mvert2; + MFace *mface2; + unsigned int numtris=0; + unsigned int numquads=0; + EdgeHash *edgehash = NULL; + Cloth *cloth = clmd->clothObject; + ClothSpring *springs = cloth->springs; + unsigned int numsprings = cloth->numsprings; + + // create spring tearing hash + edgehash = BLI_edgehash_new(); + + for(i = 0; i < numsprings; i++) + { + if((springs[i].flags & CSPRING_FLAG_DEACTIVATE) + &&(!BLI_edgehash_haskey(edgehash, springs[i].ij, springs[i].kl))) + { + BLI_edgehash_insert(edgehash, springs[i].ij, springs[i].kl, NULL); + BLI_edgehash_insert(edgehash, springs[i].kl, springs[i].ij, NULL); + j++; + } + } + + // printf("found %d tears\n", j); + + result = CDDM_from_template(dm, numverts, 0, numfaces); + + if(!result) + return NULL; + + // do verts + mvert2 = CDDM_get_verts(result); + for(a=0; av1 = mface[a].v1; + mf->v2 = mface[a].v2; + mf->v3 = mface[a].v3; + mf->v4 = mface[a].v4; + + test_index_face(mf, NULL, 0, 4); + + i++; + } + } + + CDDM_lower_num_faces(result, i); + CDDM_calc_edges(result); + CDDM_calc_normals(result); + + BLI_edgehash_free(edgehash, NULL); + + return result; +} + + +int cloth_cache_search_frame(ClothModifierData *clmd, float time) +{ + Frame *frame = NULL; + LinkNode *search = NULL; + int newtime = time + clmd->sim_parms.preroll; + + Cloth *cloth = NULL; + + if(!clmd) + return 0; + + cloth = clmd->clothObject; + + if(!cloth) + return 0; + + if(clmd->sim_parms.cache) + { + search = clmd->sim_parms.cache; + + // check if frame exists + while(search) + { + frame = search->link; + + if(frame->time == newtime) + break; + + frame = NULL; + + search = search->next; + } + } + + if(!frame) + return 0; + + return 1; +} + +void cloth_cache_get_frame(ClothModifierData *clmd, float time) +{ + Frame *frame = NULL; + LinkNode *search = NULL; + unsigned int i = 0; + Cloth *cloth = NULL; + int newtime = time + clmd->sim_parms.preroll; + + if(clmd) + { + cloth = clmd->clothObject; + + if(!cloth) + return; + + // get cache + if(clmd->sim_parms.cache) + { + search = clmd->sim_parms.cache; + frame = NULL; + // check if frame exists + while(search) + { + frame = search->link; + if(frame->time == newtime) + break; + + frame = NULL; + + search = search->next; + } + + if(frame) + { + if(frame->verts) + { + + // copy ClothVertex struct + memcpy(cloth->verts, frame->verts, cloth->numverts*sizeof(ClothVertex)); + implicit_set_positions(clmd); + } + + if(frame->springs) + { + // copy ClothSpring struct + memcpy(cloth->springs, frame->springs, cloth->numsprings*sizeof(ClothSpring)); + } + } + } + } + +} + +void cloth_cache_set_frame(ClothModifierData *clmd, float time) +{ + Frame *frame = NULL; + unsigned int i = 0; + Cloth *cloth = NULL; + int newtime = time + clmd->sim_parms.preroll; + + if(clmd) + { + cloth = clmd->clothObject; + + if(cloth) + { + // creat new frame cache + frame = (Frame *)MEM_callocN(sizeof(Frame), "cloth frame cache"); + frame->verts = (ClothVertex *)MEM_callocN(sizeof(ClothVertex)*cloth->numverts, "cloth frame vertex cache"); + frame->springs = (ClothSpring *)MEM_callocN(sizeof(ClothSpring)*cloth->numsprings, "cloth frame spring cache"); + frame->time = newtime; + + // copy ClothVertex struct + for(i = 0; i < cloth->numverts; i++) + { + memcpy(&frame->verts[i], &cloth->verts[i], sizeof(ClothVertex)); + } + + // copy ClothSpring struct + for(i = 0; i < cloth->numsprings; i++) + { + memcpy(&frame->springs[i], &cloth->springs[i], sizeof(ClothSpring)); + } + + } + if(frame) + { + if(!clmd->sim_parms.cache) + BLI_linklist_prepend(&clmd->sim_parms.cache, frame); + else + BLI_linklist_append(&clmd->sim_parms.cache, frame); + } + } +} + +void cloth_cache_free(ClothModifierData *clmd, float time) +{ + Frame *frame = NULL; + LinkNode *search, *last_search; + int newtime = time + clmd->sim_parms.preroll; + + // do never free first cached frame + if((newtime<1.0f) && !(clmd->sim_parms.flags & CSIMSETT_FLAG_CCACHE_FREE_ALL)) + return; + + /* Calls the solver and collision frees first as they + * might depend on data in clmd->clothObject. */ + + if (clmd) + { + if(clmd->sim_parms.cache) + { + last_search = search = clmd->sim_parms.cache; + while(search) + { + LinkNode *next= search->next; + frame = search->link; + + // free part of cache, but not preroll cache and first framer + if((clmd->sim_parms.flags & CSIMSETT_FLAG_CCACHE_FREE_PART) + && (frame->time > newtime)) // do not delete the first frame + { + MEM_freeN(frame->verts); + MEM_freeN(frame->springs); + MEM_freeN(frame); + MEM_freeN(search); + last_search->next = next; + } + else if(clmd->sim_parms.flags & CSIMSETT_FLAG_CCACHE_FREE_ALL) // free COMPLETE cache + { + MEM_freeN(frame->verts); + MEM_freeN(frame->springs); + MEM_freeN(frame); + } + else + last_search = search; + search = next; + } + + if(clmd->sim_parms.flags & CSIMSETT_FLAG_CCACHE_FREE_ALL) + { + BLI_linklist_free(clmd->sim_parms.cache,NULL); + clmd->sim_parms.cache = NULL; + } + } + } + + /* clear flags */ + clmd->sim_parms.flags &= ~CSIMSETT_FLAG_CCACHE_FREE_ALL; + clmd->sim_parms.flags &= ~CSIMSETT_FLAG_CCACHE_FREE_PART; + +} + + +/** +* cloth_deform_verts - simulates one step, framenr is in frames. +* +**/ +void clothModifier_do(ClothModifierData *clmd, Object *ob, DerivedMesh *dm, + float (*vertexCos)[3], int numverts) +{ + unsigned int i; + unsigned int numedges = -1; + unsigned int numfaces = -1; + MVert *mvert = NULL; + MEdge *medge = NULL; + MFace *mface = NULL; + DerivedMesh *result = NULL, *result2 = NULL; + Cloth *cloth = clmd->clothObject; + unsigned int framenr = (float)G.scene->r.cfra; + float current_time = bsystem_time(ob, (float)G.scene->r.cfra, 0.0); + ListBase *effectors = NULL; + ClothVertex *newframe= NULL, *verts; + Frame *frame = NULL; + LinkNode *search = NULL; + float deltaTime = current_time - clmd->sim_parms.sim_time; + + clmd->sim_parms.dt = 1.0f / (clmd->sim_parms.stepsPerFrame * G.scene->r.frs_sec); + + clmd->sim_parms.sim_time = current_time; + + // check if cloth object was some collision object before and needs freeing now + if (!(clmd->sim_parms.flags & CSIMSETT_FLAG_COLLOBJ) && (clmd->clothObject != NULL) && (clmd->clothObject->old_solver_type == 255)) + { + // temporary set CSIMSETT_FLAG_COLLOBJ flag for proper freeing + clmd->sim_parms.flags |= CSIMSETT_FLAG_COLLOBJ; + cloth_free_modifier(clmd); + clmd->sim_parms.flags &= ~CSIMSETT_FLAG_COLLOBJ; + } + + // This is for collisions objects: check special case CSIMSETT_FLAG_COLLOBJ + if (clmd->sim_parms.flags & CSIMSETT_FLAG_COLLOBJ) + { + + // save next position + time + if ((clmd->clothObject == NULL) || (numverts != clmd->clothObject->numverts) ) + { + if(!collobj_from_object (ob, clmd, dm, vertexCos, framenr)) + return; + + if(clmd->clothObject == NULL) + return; + + cloth = clmd->clothObject; + } + + // Save old position + clmd->sim_parms.sim_time_old = clmd->sim_parms.sim_time; + clmd->sim_parms.sim_time = current_time; + + verts = cloth->verts; + + for (i = 0; i < clmd->clothObject->numverts; i++, verts++) + { + // Save the previous position. + VECCOPY (verts->xold, verts->x); + VECCOPY (verts->txold, verts->x); + + // Get the current position. + VECCOPY (verts->x, mvert[i].co); + Mat4MulVecfl(ob->obmat, verts->x); + + // Compute the vertices velocity. + VECSUB (verts->v, verts->x, verts->xold); + } + + return; + } + + if(deltaTime == 1.0f) + { + if ((clmd->clothObject == NULL) || (numverts != clmd->clothObject->numverts) ) + { + if(!cloth_from_object (ob, clmd, dm, vertexCos, numverts)) + return; + + if(clmd->clothObject == NULL) + return; + + cloth = clmd->clothObject; + } + + clmd->clothObject->old_solver_type = clmd->sim_parms.solver_type; + + // Insure we have a clmd->clothObject, in case allocation failed. + if (clmd->clothObject != NULL) + { + if(!cloth_cache_search_frame(clmd, framenr)) + { + verts = cloth->verts; + + /* Force any pinned verts to their constrained location. */ + for (i = 0; i < clmd->clothObject->numverts; i++, verts++) + { + /* Save the previous position. */ + VECCOPY (verts->xold, verts->xconst); + VECCOPY (verts->txold, verts->x); + + /* Get the current position. */ + VECCOPY (verts->xconst, vertexCos[i]); + Mat4MulVecfl(ob->obmat, verts->xconst); + + /* Compute the vertices velocity. */ + VECSUB (verts->v, verts->x, verts->xold); + } + + tstart(); + + /* Call the solver. */ + + if (solvers [clmd->sim_parms.solver_type].solver) + solvers [clmd->sim_parms.solver_type].solver (ob, framenr, clmd, effectors,0,0); + + tend(); + printf("Cloth simulation time: %f\n", (float)tval()); + + cloth_cache_set_frame(clmd, framenr); + + } + else // just retrieve the cached frame + { + cloth_cache_get_frame(clmd, framenr); + } + + // Copy the result back to the object. + cloth_to_object (ob, clmd, vertexCos, numverts); + + // bvh_free(clmd->clothObject->tree); + // clmd->clothObject->tree = bvh_build(clmd, clmd->coll_parms.epsilon); + } + + } + else if((deltaTime <= 0.0f)||(deltaTime > 1.0f)) + { + if(cloth_cache_search_frame(clmd, framenr)) + { + cloth_cache_get_frame(clmd, framenr); + cloth_to_object (ob, clmd, vertexCos, numverts); + } + } +} + +/* frees all */ +void cloth_free_modifier (ClothModifierData *clmd) +{ + Cloth *cloth = NULL; + + if(!clmd) + return; + + cloth = clmd->clothObject; + + // free our frame cache + clmd->sim_parms.flags |= CSIMSETT_FLAG_CCACHE_FREE_ALL; + cloth_cache_free(clmd, 0); + + /* Calls the solver and collision frees first as they + * might depend on data in clmd->clothObject. */ + + if (cloth) + { + // If our solver provides a free function, call it + if (cloth->old_solver_type < 255 && solvers [cloth->old_solver_type].free) + { + solvers [cloth->old_solver_type].free (clmd); + } + + // Free the verts. + if (cloth->verts != NULL) + MEM_freeN (cloth->verts); + + cloth->verts = NULL; + cloth->numverts = -1; + + // Free the springs. + if (cloth->springs != NULL) + MEM_freeN (cloth->springs); + + cloth->springs = NULL; + cloth->numsprings = -1; + + // free BVH collision tree + if(cloth->tree) + bvh_free((BVH *)cloth->tree); + + // we save our faces for collision objects + if(cloth->mfaces) + MEM_freeN(cloth->mfaces); + + if(clmd->clothObject->facemarks) + MEM_freeN(clmd->clothObject->facemarks); + + MEM_freeN (cloth); + clmd->clothObject = NULL; + } + +} + + + +/****************************************************************************** +* +* Internal functions. +* +******************************************************************************/ + +/** +* cloth_to_object - copies the deformed vertices to the object. +* +* This function is a modified version of the softbody.c:softbody_to_object() function. +**/ +static void cloth_to_object (Object *ob, ClothModifierData *clmd, float (*vertexCos)[3], unsigned int numverts) +{ + ClothVertex *verts = NULL; + unsigned int i = 0; + + if (clmd->clothObject) { + verts = clmd->clothObject->verts; + + /* inverse matrix is not uptodate... */ + Mat4Invert (ob->imat, ob->obmat); + + for (i = 0; i < numverts; i++, verts++) + { + VECCOPY (vertexCos[i], verts->x); + Mat4MulVecfl (ob->imat, vertexCos[i]); /* softbody is in global coords */ + } + } + else if (DEBUG_CLOTH) + printf ("cloth_to_object: clmd->clothObject was NULL.\n"); +} + + +/** +* cloth_apply_vgroup - applies a vertex group as specified by type +* +**/ +static void cloth_apply_vgroup(ClothModifierData *clmd, DerivedMesh *dm, short vgroup) +{ + unsigned int i; + int j; + MDeformVert *dvert = NULL; + Cloth *clothObj; + unsigned int numverts = dm->getNumVerts(dm); + float goalfac = 0; + ClothVertex *verts = NULL; + + clothObj = clmd->clothObject; + + /* vgroup is 1 based, decrement so we can match the right group. */ + --vgroup; + + verts = clothObj->verts; + + for (i = 0; i < numverts; i++, verts++) + { + /* so this will definily be below SOFTGOALSNAP */ + verts->goal= 0.0f; + + // LATER ON, support also mass painting here + if(clmd->sim_parms.flags & CSIMSETT_FLAG_GOAL) + { + dvert = dm->getVertData(dm, i, CD_MDEFORMVERT); + if(dvert) + { + for(j = 0; j < dvert->totweight; j++) + { + if(dvert->dw[j].def_nr == vgroup) + { + verts->goal = dvert->dw [j].weight; + + goalfac= ABS(clmd->sim_parms.maxgoal - clmd->sim_parms.mingoal); + verts->goal = (float)pow(verts->goal , 4.0f); + + if(dvert->dw [j].weight >=SOFTGOALSNAP) + { + verts->flags |= CVERT_FLAG_PINNED; + } + + // TODO enable mass painting here, for the moment i let "goals" go first + + break; + } + } + } + } + } +} + +// only meshes supported at the moment +/* collision objects */ +static int collobj_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *dm, float (*vertexCos)[3], unsigned int numverts) +{ + unsigned int i; + MVert *mvert = NULL; + ClothVertex *verts = NULL; + + switch (ob->type) + { + case OB_MESH: + + // mesh input objects need DerivedMesh + if(!dm) + return 0; + + cloth_from_mesh (ob, clmd, dm); + + if (clmd->clothObject != NULL) + { + mvert = CDDM_get_verts(dm); + verts = clmd->clothObject->verts; + + for (i = 0; i < numverts; i++, verts++) + { + VECCOPY (verts->x, mvert[i].co); + Mat4MulVecfl(ob->obmat, verts->x); + verts->flags = 0; + VECCOPY(verts->xold, verts->x); + VECCOPY(verts->txold, verts->x); + VECCOPY(verts->tx, verts->x); + VecMulf(verts->v, 0.0f); + } + clmd->clothObject->tree = bvh_build(clmd,clmd->coll_parms.epsilon); + + } + + return 1; + default: return 0; // TODO - we do not support changing meshes + } +} + +/* +helper function to get proper spring length +when object is rescaled +*/ +float cloth_globallen(float *v1,float *v2,Object *ob) +{ + float p1[3],p2[3]; + VECCOPY(p1,v1); + Mat4MulVecfl(ob->obmat, p1); + VECCOPY(p2,v2); + Mat4MulVecfl(ob->obmat, p2); + return VecLenf(p1,p2); +} + +static void curve_surf_to_cloth(Object *ob, ClothModifierData *clmd, float (*vertexCos)[3]) +{ + Curve *cu= ob->data; + Nurb *nu; + BezTriple *bezt; + float goalfac; + unsigned int a, curindex=0, i=0; + unsigned int numverts, numsprings = 0, setgoal=0; + Cloth *clothObj; + ClothVertex *verts = NULL; + + clmd->clothObject->numverts = numverts= count_curveverts(&cu->nurb); + clothObj = clmd->clothObject; + + if(ob->type==OB_CURVE) + { + numsprings = numverts - BLI_countlist(&cu->nurb); + } + + /* Allocate our vertices. + */ + clmd->clothObject->numverts = numverts; + clmd->clothObject->verts = MEM_callocN (sizeof (ClothVertex) * clmd->clothObject->numverts, "clothVertex"); + if (clmd->clothObject->verts == NULL) + { + cloth_free_modifier (clmd); + modifier_setError (&(clmd->modifier), "Out of memory on allocating clmd->clothObject->verts."); + return; + } + + verts = clmd->clothObject->verts; + + // copy vertex positions + for (i = 0; i < numverts; i++) + { + VECCOPY (verts->x, vertexCos[i]); + Mat4MulVecfl(ob->obmat, verts->x); + + verts->mass = clmd->sim_parms.mass; + // verts->goal= clmd->sim_parms.defgoal; + verts->flags = 0; + VECCOPY(verts->xold, verts->x); + VECCOPY(verts->xconst, verts->x); + VECCOPY(verts->txold, verts->x); + VecMulf(verts->v, 0.0f); + } + + clmd->clothObject->mfaces = NULL; // update face pointer + clmd->clothObject->numfaces = 0; + + clmd->clothObject->springs = MEM_callocN (sizeof (ClothSpring) * (numsprings), "cloth_springs_alloc"); + + // set vars now + goalfac= ABS(clmd->sim_parms.maxgoal - clmd->sim_parms.mingoal); + // clothObj->verts [i].goal = clmd->sim_parms.mingoal + bezt->weight*goalfac; + + /* apply / set vertex groups */ + if(clmd->sim_parms.flags & CSIMSETT_FLAG_GOAL) + { + if (clmd->sim_parms.vgroup_mass > 0) + { + setgoal = 1; + } + } + +/* + for(nu= cu->nurb.first; nu; nu= nu->next) + { + if(nu->bezt) + { + for(bezt=nu->bezt, a=0; apntsu; a++, bezt++, bp+=3, curindex+=3) + { + if(setgoal) + { + bp->goal= sb->mingoal + bezt->weight*goalfac; + // a little ad hoc changing the goal control to be less *sharp* + bp->goal = (float)pow(bp->goal, 4.0f); + + // all three triples + (bp+1)->goal= bp->goal; + (bp+2)->goal= bp->goal; + } + + if(totspring) + { + if(a>0) + { + bs->v1= curindex-1; + bs->v2= curindex; + bs->strength= 1.0; + bs->order=1; + bs->len= globallen( (bezt-1)->vec[2], bezt->vec[0], ob ); + bs++; + } + bs->v1= curindex; + bs->v2= curindex+1; + bs->strength= 1.0; + bs->order=1; + bs->len= globallen( bezt->vec[0], bezt->vec[1], ob ); + bs++; + + bs->v1= curindex+1; + bs->v2= curindex+2; + bs->strength= 1.0; + bs->order=1; + bs->len= globallen( bezt->vec[1], bezt->vec[2], ob ); + bs++; + } + } + } + else { + for(bpnt=nu->bp, a=0; apntsu*nu->pntsv; a++, bpnt++, bp++, curindex++) + { + if(setgoal) + { + bp->goal= sb->mingoal + bpnt->weight*goalfac; + // a little ad hoc changing the goal control to be less *sharp* + bp->goal = (float)pow(bp->goal, 4.0f); + } + if(totspring && a>0) + { + bs->v1= curindex-1; + bs->v2= curindex; + bs->strength= 1.0; + bs->order=1; + bs->len= globallen( (bpnt-1)->vec, bpnt->vec , ob ); + bs++; + } + } + } + } + */ +} + +// only meshes supported at the moment +static int cloth_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *dm, float (*vertexCos)[3], unsigned int numverts) +{ + unsigned int i = 0; + // dm->getNumVerts(dm); + MVert *mvert = NULL; // CDDM_get_verts(dm); + ClothVertex *verts = NULL; + + /* If we have a clothObject, free it. */ + if (clmd->clothObject != NULL) + cloth_free_modifier (clmd); + + /* Allocate a new cloth object. */ + clmd->clothObject = MEM_callocN (sizeof(Cloth), "cloth"); + if (clmd->clothObject) + { + clmd->clothObject->old_solver_type = -1; + clmd->clothObject->old_collision_type = -1; + } + else if (clmd->clothObject == NULL) + { + modifier_setError (&(clmd->modifier), "Out of memory on allocating clmd->clothObject."); + return 0; + } + + switch (ob->type) + { + case OB_MESH: + + // mesh input objects need DerivedMesh + if(!dm) + return 0; + + cloth_from_mesh (ob, clmd, dm); + + if (clmd->clothObject != NULL) + { + /* create springs */ + clmd->clothObject->springs = NULL; + clmd->clothObject->numsprings = -1; + + if (!cloth_build_springs (clmd->clothObject, dm) ) + { + modifier_setError (&(clmd->modifier), "Can't build springs."); + return 0; + } + + mvert = CDDM_get_verts(dm); + verts = clmd->clothObject->verts; + + /* set initial values */ + for (i = 0; i < numverts; i++, verts++) + { + VECCOPY (verts->x, mvert[i].co); + Mat4MulVecfl(ob->obmat, verts->x); + + verts->mass = clmd->sim_parms.mass; + verts->goal= clmd->sim_parms.defgoal; + verts->flags = 0; + VECCOPY(verts->xold, verts->x); + VECCOPY(verts->xconst, verts->x); + VECCOPY(verts->txold, verts->x); + VecMulf(verts->v, 0.0f); + } + + /* apply / set vertex groups */ + if (clmd->sim_parms.vgroup_mass > 0) + cloth_apply_vgroup (clmd, dm, clmd->sim_parms.vgroup_mass); + + /* init our solver */ + if (solvers [clmd->sim_parms.solver_type].init) + solvers [clmd->sim_parms.solver_type].init (ob, clmd); + + clmd->clothObject->tree = bvh_build(clmd, clmd->coll_parms.epsilon); + + cloth_cache_set_frame(clmd, 1); + } + + return 1; + case OB_LATTICE: + printf("OB_LATTICE\n"); + // lattice_to_softbody(ob); + return 1; + case OB_CURVE: + case OB_SURF: + printf("OB_SURF| OB_CURVE\n"); + curve_surf_to_cloth(ob, clmd, vertexCos); + return 1; + default: return 0; // TODO - we do not support changing meshes + } + + return 0; +} + +static void cloth_from_mesh (Object *ob, ClothModifierData *clmd, DerivedMesh *dm) +{ + unsigned int numverts = dm->getNumVerts(dm); + unsigned int numfaces = dm->getNumFaces(dm); + MFace *mface = CDDM_get_faces(dm); + unsigned int i = 0; + + /* Allocate our vertices. + */ + clmd->clothObject->numverts = numverts; + clmd->clothObject->verts = MEM_callocN (sizeof (ClothVertex) * clmd->clothObject->numverts, "clothVertex"); + if (clmd->clothObject->verts == NULL) + { + cloth_free_modifier (clmd); + modifier_setError (&(clmd->modifier), "Out of memory on allocating clmd->clothObject->verts."); + return; + } + + // save face information + clmd->clothObject->numfaces = numfaces; + clmd->clothObject->mfaces = MEM_callocN (sizeof (MFace) * clmd->clothObject->numfaces, "clothMFaces"); + if (clmd->clothObject->mfaces == NULL) + { + cloth_free_modifier (clmd); + modifier_setError (&(clmd->modifier), "Out of memory on allocating clmd->clothObject->mfaces."); + return; + } + for(i = 0; i < numfaces; i++) + memcpy(&clmd->clothObject->mfaces[i], &mface[i], sizeof(MFace)); + + + // for SIP code + // clmd->clothObject->facemarks = MEM_callocN (sizeof (unsigned char) * clmd->clothObject->numfaces, "clothFaceMarks"); + + /* Free the springs since they can't be correct if the vertices + * changed. + */ + if (clmd->clothObject->springs != NULL) + MEM_freeN (clmd->clothObject->springs); + +} + +/*************************************************************************************** +* SPRING NETWORK BUILDING IMPLEMENTATION BEGIN +***************************************************************************************/ + +int cloth_build_springs(Cloth *cloth, DerivedMesh *dm) +{ + ClothSpring *springs = NULL; + unsigned int struct_springs = 0, shear_springs=0, bend_springs = 0; + unsigned int i = 0; + unsigned int numverts = dm->getNumVerts(dm); + unsigned int numedges = dm->getNumEdges(dm); + unsigned int numfaces = dm->getNumFaces(dm); + MVert *mvert = CDDM_get_verts(dm); + MEdge *medge = CDDM_get_edges(dm); + MFace *mface = CDDM_get_faces(dm); + unsigned int index2 = 0; // our second vertex index + LinkNode **edgelist = NULL; + EdgeHash *edgehash = NULL; + LinkNode *search = NULL; + float temp[3]; + unsigned int temp_index = 0; + ClothSpring *tspring = NULL; + + // error handling + if(numedges==0) + return 0; + + edgelist = MEM_callocN (sizeof (LinkNode *) * numverts, "cloth_edgelist_alloc"); + for(i = 0; i < numverts; i++) + { + edgelist[i] = NULL; + } + + if(cloth->springs) + MEM_freeN(cloth->springs); + + // create spring network hash + edgehash = BLI_edgehash_new(); + + // should be 4 for maximal bending springs, using 5 to be sure ;) + springs = cloth->springs = MEM_callocN (sizeof (ClothSpring) * (numedges + numfaces * 2 + 6 * numverts), "cloth_springs_alloc"); + + // structural springs + for(i = 0; i < numedges; i++) + { + springs[i].ij = medge[i].v1; + springs[i].kl = medge[i].v2; + VECSUB(temp, mvert[springs[i].kl].co, mvert[springs[i].ij].co); + springs[i].restlen = sqrt(INPR(temp, temp)); + springs[i].type = STRUCTURAL; + springs[i].flags = 0; + struct_springs++; + } + + // shear springs + for(i = 0; i < numfaces; i++) + { + temp_index = struct_springs + shear_springs; + + springs[temp_index].ij = mface[i].v1; + springs[temp_index].kl = mface[i].v3; + VECSUB(temp, mvert[springs[temp_index].kl].co, mvert[springs[temp_index].ij].co); + springs[temp_index].restlen = sqrt(INPR(temp, temp)); + springs[temp_index].type = SHEAR; + + BLI_linklist_append(&edgelist[springs[temp_index].ij], &(springs[temp_index])); + BLI_linklist_append(&edgelist[springs[temp_index].kl], &(springs[temp_index])); + + shear_springs++; + temp_index++; + + springs[temp_index].ij = mface[i].v2; + springs[temp_index].kl = mface[i].v4; + VECSUB(temp, mvert[springs[temp_index].kl].co, mvert[springs[temp_index].ij].co); + springs[temp_index].restlen = sqrt(INPR(temp, temp)); + springs[temp_index].type = SHEAR; + + BLI_linklist_append(&edgelist[springs[temp_index].ij], &(springs[temp_index])); + BLI_linklist_append(&edgelist[springs[temp_index].kl], &(springs[temp_index])); + + shear_springs++; + } + + // bending springs + for(i = struct_springs; i < struct_springs+shear_springs; i++) + { + search = edgelist[springs[i].kl]; + while(search) + { + tspring = search->link; + index2 = ((tspring->ij==springs[i].kl) ? (tspring->kl) : (tspring->ij)); + + if(!BLI_edgehash_haskey(edgehash, index2, springs[i].ij) // check for existing spring + && !BLI_edgehash_haskey(edgehash, springs[i].ij, index2) // same + && (index2!=springs[i].ij)) // check if startpoint is equal to endpoint + { + temp_index = struct_springs + shear_springs + bend_springs; + + springs[temp_index].ij = springs[i].ij; + springs[temp_index].kl = index2; + VECSUB(temp, mvert[index2].co, mvert[springs[i].ij].co); + springs[temp_index].restlen = sqrt(INPR(temp, temp)); + springs[temp_index].type = BENDING; + BLI_edgehash_insert(edgehash, springs[temp_index].ij, index2, NULL); + bend_springs++; + + } + search = search->next; + } + } + + cloth->numsprings = struct_springs + shear_springs + bend_springs; + + for(i = 0; i < numverts; i++) + { + BLI_linklist_free(edgelist[i],NULL); + } + if(edgelist) + MEM_freeN(edgelist); + + BLI_edgehash_free(edgehash, NULL); + + return 1; + +} /* cloth_build_springs */ +/*************************************************************************************** +* SPRING NETWORK BUILDING IMPLEMENTATION END +***************************************************************************************/ + diff --git a/source/blender/blenkernel/intern/collision.c b/source/blender/blenkernel/intern/collision.c new file mode 100644 index 00000000000..cdbac692b35 --- /dev/null +++ b/source/blender/blenkernel/intern/collision.c @@ -0,0 +1,638 @@ +/* collision.c +* +* +* ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* as published by the Free Software Foundation; either version 2 +* of the License, or (at your option) any later version. The Blender +* Foundation also sells licenses for use in proprietary software under +* the Blender License. See http://www.blender.org/BL/ for information +* about this. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software Foundation, +* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +* +* The Original Code is Copyright (C) Blender Foundation +* All rights reserved. +* +* The Original Code is: all of this file. +* +* Contributor(s): none yet. +* +* ***** END GPL/BL DUAL LICENSE BLOCK ***** +*/ + +#include +#include +#include +#include "MEM_guardedalloc.h" +/* types */ +#include "DNA_curve_types.h" +#include "DNA_object_types.h" +#include "DNA_object_force.h" +#include "DNA_cloth_types.h" +#include "DNA_key_types.h" +#include "DNA_mesh_types.h" +#include "DNA_meshdata_types.h" +#include "DNA_lattice_types.h" +#include "DNA_scene_types.h" +#include "DNA_modifier_types.h" +#include "BLI_blenlib.h" +#include "BLI_arithb.h" +#include "BLI_edgehash.h" +#include "BLI_linklist.h" +#include "BKE_curve.h" +#include "BKE_deform.h" +#include "BKE_DerivedMesh.h" +#include "BKE_cdderivedmesh.h" +#include "BKE_displist.h" +#include "BKE_effect.h" +#include "BKE_global.h" +#include "BKE_mesh.h" +#include "BKE_object.h" +#include "BKE_cloth.h" +#include "BKE_modifier.h" +#include "BKE_utildefines.h" +#include "BKE_DerivedMesh.h" +#include "DNA_screen_types.h" +#include "BSE_headerbuttons.h" +#include "BIF_screen.h" +#include "BIF_space.h" +#include "mydevice.h" + +#include "Bullet-C-Api.h" + + +#define DERANDOMIZE 1 + + +enum TRIANGLE_MARK +{ + TM_MV = 1, + TM_ME = 2, + TM_V1 = 4, + TM_V2 = 8, + TM_V3 = 16, + TM_E1 = 32, + TM_E2 = 64, + TM_E3 = 128 +}; + +DO_INLINE int hasTriangleMark(unsigned char mark, unsigned char bit) { return mark & bit; } +DO_INLINE void setTriangleMark(unsigned char *mark, unsigned char bit) { mark[0] |= bit; } +DO_INLINE void clearTriangleMark(unsigned char *mark, unsigned char bit) { mark[0] &= ~bit; } + + +void generateTriangleMarks() +{ + /* + unsigned int firstEdge = 0; + + // 1. Initialization + memset(m_triangleMarks, 0, sizeof(unsigned char) * m_triangleCount); + + // 2. The Marking Process + + // 2.1 Randomly mark triangles for covering vertices. + for (unsigned int v = 0; v < m_vertexCount; ++v) + { + if (vertexCover(v) == 0) + { + + // Randomly select an edge whose first triangle we're going to flag. + +#ifndef DERANDOMIZE + firstEdge = (unsigned int)((float)(random() & 0x7FFFFFFF) / + (float)(0x80000000) * + (float)(m_vertices[v].getEdgeCount())); +#endif + for (unsigned int ofs = 0; ofs < m_vertices[v].getEdgeCount(); ++ofs) + { + unsigned int edgeIdx = (firstEdge + ofs) % m_vertices[v].getEdgeCount(); + if (m_edges[m_vertices[v].getEdge(edgeIdx)].getTriangleCount()) + setTriangleMark(m_triangleMarks[m_edges[m_vertices[v].getEdge(edgeIdx)].getTriangle(0)], TM_MV); + } + } + } + */ + /* If the Cloth is malformed (vertices without adjacent triangles) there might still be uncovered vertices. (Bad luck.) */ + /* + // 2.2 Randomly mark triangles for covering edges. + for (unsigned int e = 0; e < m_edgeCount; ++e) + { + if (m_edges[e].getTriangleCount() && (edgeCover(e) == 0)) + { +#ifndef DERANDOMIZE + setTriangleMark(m_triangleMarks[m_edges[e].getTriangle(static_cast((float)(random() & 0x7FFFFFFF) / + (float)(0x80000000) * + (float)(m_edges[e].getTriangleCount())))], TM_ME); +#else + setTriangleMark(m_triangleMarks[m_edges[e].getTriangle(0)], TM_ME); +#endif + } + } + + + // 3. The Unmarking Process + for (unsigned int t = 0; (t < m_triangleCount); ++t) + { + bool overCoveredVertices = true; + bool overCoveredEdges = true; + for (unsigned char i = 0; (i < 3) && (overCoveredVertices || overCoveredEdges); ++i) + { + + if (vertexCover(m_triangles[t].getVertex(i)) == 1) + overCoveredVertices = false; + if (edgeCover(m_triangles[t].getEdge(i)) == 1) + overCoveredEdges = false; + + assert(vertexCover(m_triangles[t].getVertex(i)) > 0); + assert(edgeCover(m_triangles[t].getEdge(i)) > 0); + } + if (overCoveredVertices) + clearTriangleMark(m_triangleMarks[t], TM_MV); + if (overCoveredEdges) + clearTriangleMark(m_triangleMarks[t], TM_ME); + } + + + // 4. The Bit Masking Process + vector vertexAssigned(m_vertexCount, false); + vector edgeAssigned(m_edgeCount, false); + for (unsigned int t = 0; (t < m_triangleCount); ++t) + { + for (unsigned char i = 0; i < 3; ++i) + { + if (!vertexAssigned[m_triangles[t].getVertex(i)]) + { + vertexAssigned[m_triangles[t].getVertex(i)] = true; + setTriangleMark(m_triangleMarks[t], 1 << (2 + i)); + } + if (!edgeAssigned[m_triangles[t].getEdge(i)]) + { + edgeAssigned[m_triangles[t].getEdge(i)] = true; + setTriangleMark(m_triangleMarks[t], 1 << (5 + i)); + } + } + } + */ +} + + +void bvh_compute_barycentric (float pv[3], float p1[3], float p2[3], float p3[3], double *w1, double *w2, double *w3) +{ + float tempV1[3], tempV2[3], tempV4[3]; + double a,b,c,e,f; + + VECSUB (tempV1, p1, p3); /* x1 - x3 */ + VECSUB (tempV2, p2, p3); /* x2 - x3 */ + VECSUB (tempV4, pv, p3); /* pv - x3 */ + + a = INPR (tempV1, tempV1); + b = INPR (tempV1, tempV2); + c = INPR (tempV2, tempV2); + e = INPR (tempV1, tempV4); + f = INPR (tempV2, tempV4); + + + w1[0] = (e * c - b * f) / (a * c - b * b); + w2[0] = (f - b * w1[0]) / c; + w3[0] = 1.0 - w1[0] - w2[0]; +} + +DO_INLINE void interpolateOnTriangle(float to[3], float v1[3], float v2[3], float v3[3], double w1, double w2, double w3) +{ + to[0] = to[1] = to[2] = 0; + VECADDMUL(to, v1, w1); + VECADDMUL(to, v2, w2); + VECADDMUL(to, v3, w3); +} + +DO_INLINE void calculateFrictionImpulse(float to[3], float vrel[3], float normal[3], double normalVelocity, + double frictionConstant, double delta_V_n) +{ + float vrel_t_pre[3]; + float vrel_t[3]; + VECSUBS(vrel_t_pre, vrel, normal, normalVelocity); + VECCOPY(vrel_t, vrel_t_pre); + VecMulf(vrel_t, MAX2(1.0f - frictionConstant * delta_V_n / INPR(vrel_t_pre,vrel_t_pre), 0.0f)); + VECSUB(to, vrel_t_pre, vrel_t); + VecMulf(to, 1.0f / 2.0f); +} + +int collision_static(ClothModifierData *clmd, ClothModifierData *coll_clmd, LinkNode **collision_list) +{ + unsigned int i = 0, numverts=0; + int result = 0; + LinkNode *search = NULL; + CollPair *collpair = NULL; + Cloth *cloth1, *cloth2; + MFace *face1, *face2; + double w1, w2, w3, u1, u2, u3; + float v1[3], v2[3], relativeVelocity[3]; + float magrelVel; + + cloth1 = clmd->clothObject; + cloth2 = coll_clmd->clothObject; + + numverts = clmd->clothObject->numverts; + + /* + for(i = 0; i < LIST_LENGTH; i++) + { + // calc SIP-code + // TODO for later: calculateSipCode() + + // calc distance (?) + + // calc impulse + + // apply impulse + } + */ + + for(i = 0; i < numverts; i++) + { + search = collision_list[i]; + + while(search) + { + collpair = search->link; + + face1 = &(cloth1->mfaces[collpair->face1]); + face2 = &(cloth2->mfaces[collpair->face2]); + + // compute barycentric coordinates for both collision points + if(!collpair->quadA) + bvh_compute_barycentric(collpair->p1, + cloth1->verts[face1->v1].txold, + cloth1->verts[face1->v2].txold, + cloth1->verts[face1->v3].txold, + &w1, &w2, &w3); + else + bvh_compute_barycentric(collpair->p1, + cloth1->verts[face1->v4].txold, + cloth1->verts[face1->v1].txold, + cloth1->verts[face1->v3].txold, + &w1, &w2, &w3); + + if(!collpair->quadB) + bvh_compute_barycentric(collpair->p2, + cloth2->verts[face2->v1].txold, + cloth2->verts[face2->v2].txold, + cloth2->verts[face2->v3].txold, + &u1, &u2, &u3); + else + bvh_compute_barycentric(collpair->p2, + cloth2->verts[face2->v4].txold, + cloth2->verts[face2->v1].txold, + cloth2->verts[face2->v3].txold, + &u1, &u2, &u3); + + // Calculate relative velocity. + if(!collpair->quadA) + interpolateOnTriangle(v1, cloth1->verts[face1->v1].v, cloth1->verts[face1->v2].v, cloth1->verts[face1->v3].v, w1, w2, w3); + else + interpolateOnTriangle(v1, cloth1->verts[face1->v4].v, cloth1->verts[face1->v1].v, cloth1->verts[face1->v3].v, w1, w2, w3); + + if(!collpair->quadB) + interpolateOnTriangle(v2, cloth2->verts[face2->v1].v, cloth2->verts[face2->v2].v, cloth2->verts[face2->v3].v, u1, u2, u3); + else + interpolateOnTriangle(v2, cloth2->verts[face2->v4].v, cloth2->verts[face2->v1].v, cloth2->verts[face2->v3].v, u1, u2, u3); + + VECSUB(relativeVelocity, v1, v2); + + // Calculate the normal component of the relative velocity (actually only the magnitude - the direction is stored in 'normal'). + magrelVel = INPR(relativeVelocity, collpair->normal); + + // Calculate masses of points. + + // printf("relativeVelocity -> x: %f, y: %f, z: %f\n", relativeVelocity[0], relativeVelocity[1],relativeVelocity[2]); + + // If v_n_mag > 0 the edges are approaching each other. + if(magrelVel > ALMOST_ZERO) + { + // Calculate Impulse magnitude to stop all motion in normal direction. + // const double I_mag = v_n_mag / (1/m1 + 1/m2); + float magnitude_i = magrelVel / 2.0f; // TODO implement masses + float tangential[3], magtangent; + + calculateFrictionImpulse(tangential, relativeVelocity, collpair->normal, magrelVel, clmd->coll_parms.friction*0.01, magrelVel); + + magtangent = INPR(tangential, tangential); + + // Apply friction impulse. + if (magtangent > ALMOST_ZERO) + { + /* + printf("friction applied: %f\n", magtangent); + // TODO check original code + VECSUB(cloth1->verts[face1->v1].tv, cloth1->verts[face1->v1].tv,tangential); + VECSUB(cloth1->verts[face1->v1].tv, cloth1->verts[face1->v2].tv,tangential); + VECSUB(cloth1->verts[face1->v1].tv, cloth1->verts[face1->v3].tv,tangential); + VECSUB(cloth1->verts[face1->v1].tv, cloth1->verts[face1->v4].tv,tangential); + */ + } + + // printf("magnitude_i: %f\n", magnitude_i); // negative before collision in my case + + // Apply the impulse and increase impulse counters. + /* + VECADDMUL(cloth1->verts[face1->v1].tv,collpair->normal, -magnitude_i); + VECADDMUL(cloth1->verts[face1->v2].tv,collpair->normal, -magnitude_i); + VECADDMUL(cloth1->verts[face1->v3].tv,collpair->normal, -magnitude_i); + VECADDMUL(cloth1->verts[face1->v4].tv,collpair->normal, -magnitude_i); + */ + + // my try + magtangent = INPR(cloth1->verts[face1->v1].tv, collpair->normal); + VECADDMUL(cloth1->verts[face1->v1].tv, collpair->normal, -magtangent); + + magtangent = INPR(cloth1->verts[face1->v2].tv, collpair->normal); + VECADDMUL(cloth1->verts[face1->v2].tv, collpair->normal, -magtangent); + + magtangent = INPR(cloth1->verts[face1->v3].tv, collpair->normal); + VECADDMUL(cloth1->verts[face1->v3].tv, collpair->normal, -magtangent); + + magtangent = INPR(cloth1->verts[face1->v4].tv, collpair->normal); + VECADDMUL(cloth1->verts[face1->v4].tv, collpair->normal, -magtangent); + + result = 1; + + } + + search = search->next; + } + } + + return result; +} + +// return distance between two triangles using bullet engine +double implicit_tri_check_coherence (ClothModifierData *clmd, ClothModifierData *coll_clmd, unsigned int tri_index1, unsigned int tri_index2, float pa[3], float pb[3], float normal[3], int quadA, int quadB) +{ + MFace *face1=NULL, *face2=NULL; + float a[3][3]; + float b[3][3]; + double distance=0, tempdistance=0; + Cloth *cloth1=NULL, *cloth2=NULL; + float tpa[3], tpb[3], tnormal[3]; + unsigned int indexA=0, indexB=0, indexC=0, indexD=0, indexE=0, indexF=0; + int i = 0; + + cloth1 = clmd->clothObject; + cloth2 = coll_clmd->clothObject; + + face1 = &(cloth1->mfaces[tri_index1]); + face2 = &(cloth2->mfaces[tri_index2]); + + // face a1 + face b1 + VECCOPY(a[0], cloth1->verts[face1->v1].txold); + VECCOPY(a[1], cloth1->verts[face1->v2].txold); + VECCOPY(a[2], cloth1->verts[face1->v3].txold); + + + VECCOPY(b[0], cloth2->verts[face2->v1].txold); + VECCOPY(b[1], cloth2->verts[face2->v2].txold); + VECCOPY(b[2], cloth2->verts[face2->v3].txold); + + distance = plNearestPoints(a,b,pa,pb,normal); + + quadA = quadB = 0; + + for(i = 0; i < 3; i++) + { + if(i == 0) + { + indexA = face1->v4; + indexB = face1->v1; + indexC = face1->v3; + + indexD = face2->v1; + indexE = face2->v2; + indexF = face2->v3; + } + else if(i == 1) + { + indexA = face1->v4; + indexB = face1->v1; + indexC = face1->v3; + + indexD = face2->v4; + indexE = face2->v1; + indexF = face2->v3; + } + else if(i == 2) + { + indexA = face1->v1; + indexB = face1->v2; + indexC = face1->v3; + + indexD = face2->v4; + indexE = face2->v1; + indexF = face2->v3; + } + + // face a2 + face b1 + VECCOPY(a[0], cloth1->verts[indexA].txold); + VECCOPY(a[1], cloth1->verts[indexB].txold); + VECCOPY(a[2], cloth1->verts[indexC].txold); + + + VECCOPY(b[0], cloth2->verts[indexD].txold); + VECCOPY(b[1], cloth2->verts[indexE].txold); + VECCOPY(b[2], cloth2->verts[indexF].txold); + + tempdistance = plNearestPoints(a,b,tpa,tpb,tnormal); + + if(tempdistance < distance) + { + VECCOPY(pa, tpa); + VECCOPY(pb, tpb); + VECCOPY(normal, tnormal); + distance = tempdistance; + + if(i == 0) + { + quadA = 1; quadB = 0; + } + else if(i == 1) + { + quadA = quadB = 1; + } + else if(i == 2) + { + quadA = 0; quadB = 1; + } + } + } + return distance; +} + +void bvh_collision_response(ClothModifierData *clmd, ClothModifierData *coll_clmd, Tree * tree1, Tree * tree2) +{ + CollPair *collpair = NULL; + LinkNode **linknode; + double distance = 0; + float epsilon = clmd->coll_parms.epsilon; + + collpair = (CollPair *)MEM_callocN(sizeof(CollPair), "cloth coll pair"); + linknode = clmd->coll_parms.temp; + + // calc SIPcode (?) + + // calc distance + normal + distance = implicit_tri_check_coherence(clmd, coll_clmd, tree1->tri_index, tree2->tri_index, collpair->p1, collpair->p2, collpair->vector, collpair->quadA, collpair->quadB); + + if (ABS(distance) <= (epsilon + ALMOST_ZERO)) + { + // printf("distance: %f, epsilon: %f\n", (float)distance, epsilon + ALMOST_ZERO); + + collpair->face1 = tree1->tri_index; + collpair->face2 = tree2->tri_index; + + VECCOPY(collpair->normal, collpair->vector); + Normalize(collpair->normal); + + // printf("normal x: %f, y: %f, z: %f\n", collpair->normal[0], collpair->normal[1], collpair->normal[2]); + + collpair->distance = distance; + + BLI_linklist_append(&linknode[tree1->tri_index], collpair); + } + else + { + MEM_freeN(collpair); + } +} + + +int cloth_bvh_objcollision(ClothModifierData * clmd, float step, CM_COLLISION_RESPONSE collision_response, float dt) +{ + Base *base=NULL; + ClothModifierData *coll_clmd=NULL; + Cloth *cloth=NULL; + Object *coll_ob=NULL; + BVH *cloth_bvh=NULL; + unsigned int i=0, numverts=0; + int result = 0; + + if ((clmd->sim_parms.flags & CSIMSETT_FLAG_COLLOBJ) || !(((Cloth *)clmd->clothObject)->tree)) + { + return 0; + } + cloth = clmd->clothObject; + cloth_bvh = (BVH *) cloth->tree; + numverts = clmd->clothObject->numverts; + + //////////////////////////////////////////////////////////// + // static collisions + //////////////////////////////////////////////////////////// + + // update cloth bvh + bvh_update_static(clmd, cloth_bvh); + + // search all objects for collision object + for (base = G.scene->base.first; base; base = base->next) + { + + coll_ob = base->object; + coll_clmd = (ClothModifierData *) modifiers_findByType (coll_ob, eModifierType_Cloth); + if (!coll_clmd) + continue; + + // if collision object go on + if (coll_clmd->sim_parms.flags & CSIMSETT_FLAG_COLLOBJ) + { + if (coll_clmd->clothObject && coll_clmd->clothObject->tree) + { + unsigned int coll_numverts = coll_clmd->clothObject->numverts; + Cloth *coll_cloth = coll_clmd->clothObject; + + LinkNode **collision_list = MEM_callocN (sizeof(LinkNode *)*numverts, "collision_list"); + BVH *coll_bvh = coll_clmd->clothObject->tree; + + if(collision_list) + { + // memset(collision_list, 0, sizeof(LinkNode *)*numverts); + + for(i = 0; i < numverts; i++) + { + collision_list[i] = NULL; + } + + clmd->coll_parms.temp = collision_list; + + // update position of collision object + for(i = 0; i < coll_numverts; i++) + { + VECCOPY(coll_cloth->verts[i].txold, coll_cloth->verts[i].tx); + + VECADDS(coll_cloth->verts[i].tx, coll_cloth->verts[i].xold, coll_cloth->verts[i].v, step); + + VECSUB(coll_cloth->verts[i].tv, coll_cloth->verts[i].tx, coll_cloth->verts[i].txold); + } + + // update BVH of collision object + bvh_update_static(coll_clmd, coll_bvh); + + bvh_traverse(clmd, coll_clmd, cloth_bvh->root, coll_bvh->root, step, collision_response); + + result += collision_static(clmd, coll_clmd, collision_list); + + // calculate velocities + + // free temporary list + for(i = 0; i < numverts; i++) + { + LinkNode *search = collision_list[i]; + while(search) + { + LinkNode *next= search->next; + CollPair *collpair = search->link; + + if(collpair) + MEM_freeN(collpair); + + search = next; + } + + BLI_linklist_free(collision_list[i],NULL); + } + if(collision_list) + MEM_freeN(collision_list); + + clmd->coll_parms.temp = NULL; + } + + + } + else + printf ("cloth_bvh_objcollision: found a collision object with clothObject or collData NULL.\n"); + } + } + + //////////////////////////////////////////////////////////// + // update positions + velocities + //////////////////////////////////////////////////////////// + + // TODO + + + //////////////////////////////////////////////////////////// + // moving collisions + //////////////////////////////////////////////////////////// + + // TODO + // bvh_update_moving(clmd, clmd->clothObject->tree); + + return MIN2(result, 1); +} diff --git a/source/blender/blenkernel/intern/implicit.c b/source/blender/blenkernel/intern/implicit.c new file mode 100644 index 00000000000..5d386036b7b --- /dev/null +++ b/source/blender/blenkernel/intern/implicit.c @@ -0,0 +1,1511 @@ +/* implicit.c +* +* +* ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* as published by the Free Software Foundation; either version 2 +* of the License, or (at your option) any later version. The Blender +* Foundation also sells licenses for use in proprietary software under +* the Blender License. See http://www.blender.org/BL/ for information +* about this. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software Foundation, +* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +* +* The Original Code is Copyright (C) Blender Foundation +* All rights reserved. +* +* The Original Code is: all of this file. +* +* Contributor(s): none yet. +* +* ***** END GPL/BL DUAL LICENSE BLOCK ***** +*/ +#include +#include +#include +#include +#include "MEM_guardedalloc.h" +/* types */ +#include "DNA_curve_types.h" +#include "DNA_object_types.h" +#include "DNA_object_force.h" +#include "DNA_cloth_types.h" +#include "DNA_key_types.h" +#include "DNA_mesh_types.h" +#include "DNA_modifier_types.h" +#include "DNA_meshdata_types.h" +#include "DNA_lattice_types.h" +#include "DNA_scene_types.h" +#include "DNA_modifier_types.h" +#include "BLI_blenlib.h" +#include "BLI_arithb.h" +#include "BLI_threads.h" +#include "BKE_curve.h" +#include "BKE_displist.h" +#include "BKE_effect.h" +#include "BKE_global.h" +#include "BKE_key.h" +#include "BKE_object.h" +#include "BKE_cloth.h" +#include "BKE_modifier.h" +#include "BKE_utildefines.h" +#include "BKE_global.h" +#include "BIF_editdeform.h" + + +#ifdef _WIN32 +#include +static LARGE_INTEGER _itstart, _itend; +static LARGE_INTEGER ifreq; +void itstart(void) +{ + static int first = 1; + if(first) { + QueryPerformanceFrequency(&ifreq); + first = 0; + } + QueryPerformanceCounter(&_itstart); +} +void itend(void) +{ + QueryPerformanceCounter(&_itend); +} +double itval() +{ + return ((double)_itend.QuadPart - + (double)_itstart.QuadPart)/((double)ifreq.QuadPart); +} +#else +#include +// intrinsics need better compile flag checking +// #include +// #include +#include + +static struct timeval _itstart, _itend; +static struct timezone itz; +void itstart(void) +{ + gettimeofday(&_itstart, &itz); +} +void itend(void) +{ + gettimeofday(&_itend,&itz); +} +double itval() +{ + double t1, t2; + t1 = (double)_itstart.tv_sec + (double)_itstart.tv_usec/(1000*1000); + t2 = (double)_itend.tv_sec + (double)_itend.tv_usec/(1000*1000); + return t2-t1; +} +#endif +/* +#define C99 +#ifdef C99 +#defineDO_INLINE inline +#else +#defineDO_INLINE static +#endif +*/ +struct Cloth; + +////////////////////////////////////////// +/* fast vector / matrix library, enhancements are welcome :) -dg */ +///////////////////////////////////////// + +/* DEFINITIONS */ +typedef float lfVector[3]; +typedef struct fmatrix3x3 { + float m[3][3]; /* 4x4 matrix */ + unsigned int c,r; /* column and row number */ + int pinned; /* is this vertex allowed to move? */ + float n1,n2,n3; /* three normal vectors for collision constrains */ + unsigned int vcount; /* vertex count */ + unsigned int scount; /* spring count */ +} fmatrix3x3; + +/////////////////////////// +// float[3] vector +/////////////////////////// +/* simple vector code */ +/* STATUS: verified */ +DO_INLINE void mul_fvector_S(float to[3], float from[3], float scalar) +{ + to[0] = from[0] * scalar; + to[1] = from[1] * scalar; + to[2] = from[2] * scalar; +} +/* simple cross product */ +/* STATUS: verified */ +DO_INLINE void cross_fvector(float to[3], float vectorA[3], float vectorB[3]) +{ + to[0] = vectorA[1] * vectorB[2] - vectorA[2] * vectorB[1]; + to[1] = vectorA[2] * vectorB[0] - vectorA[0] * vectorB[2]; + to[2] = vectorA[0] * vectorB[1] - vectorA[1] * vectorB[0]; +} +/* simple v^T * v product ("outer product") */ +/* STATUS: HAS TO BE verified (*should* work) */ +DO_INLINE void mul_fvectorT_fvector(float to[3][3], float vectorA[3], float vectorB[3]) +{ + mul_fvector_S(to[0], vectorB, vectorA[0]); + mul_fvector_S(to[1], vectorB, vectorA[1]); + mul_fvector_S(to[2], vectorB, vectorA[2]); +} +/* simple v^T * v product with scalar ("outer product") */ +/* STATUS: HAS TO BE verified (*should* work) */ +DO_INLINE void mul_fvectorT_fvectorS(float to[3][3], float vectorA[3], float vectorB[3], float aS) +{ + mul_fvector_S(to[0], vectorB, vectorA[0]* aS); + mul_fvector_S(to[1], vectorB, vectorA[1]* aS); + mul_fvector_S(to[2], vectorB, vectorA[2]* aS); +} + +/* printf vector[3] on console: for debug output */ +void print_fvector(float m3[3]) +{ + printf("%f\n%f\n%f\n\n",m3[0],m3[1],m3[2]); +} + +/////////////////////////// +// long float vector float (*)[3] +/////////////////////////// +/* print long vector on console: for debug output */ +DO_INLINE void print_lfvector(float (*fLongVector)[3], unsigned int verts) +{ + unsigned int i = 0; + for(i = 0; i < verts; i++) + { + print_fvector(fLongVector[i]); + } +} +/* create long vector */ +DO_INLINE lfVector *create_lfvector(unsigned int verts) +{ + // TODO: check if memory allocation was successfull */ + return (lfVector *)MEM_callocN (verts * sizeof(lfVector), "cloth_implicit_alloc_vector"); + // return (lfVector *)cloth_aligned_malloc(&MEMORY_BASE, verts * sizeof(lfVector)); +} +/* delete long vector */ +DO_INLINE void del_lfvector(float (*fLongVector)[3]) +{ + if (fLongVector != NULL) + { + MEM_freeN (fLongVector); + // cloth_aligned_free(&MEMORY_BASE, fLongVector); + } +} +/* copy long vector */ +DO_INLINE void cp_lfvector(float (*to)[3], float (*from)[3], unsigned int verts) +{ + memcpy(to, from, verts * sizeof(lfVector)); +} +/* init long vector with float[3] */ +DO_INLINE void init_lfvector(float (*fLongVector)[3], float vector[3], unsigned int verts) +{ + unsigned int i = 0; + for(i = 0; i < verts; i++) + { + VECCOPY(fLongVector[i], vector); + } +} +/* zero long vector with float[3] */ +DO_INLINE void zero_lfvector(float (*to)[3], unsigned int verts) +{ + memset(to, 0.0f, verts * sizeof(lfVector)); +} +/* multiply long vector with scalar*/ +DO_INLINE void mul_lfvectorS(float (*to)[3], float (*fLongVector)[3], float scalar, unsigned int verts) +{ + unsigned int i = 0; + + for(i = 0; i < verts; i++) + { + mul_fvector_S(to[i], fLongVector[i], scalar); + } +} +/* multiply long vector with scalar*/ +/* A -= B * float */ +DO_INLINE void submul_lfvectorS(float (*to)[3], float (*fLongVector)[3], float scalar, unsigned int verts) +{ + unsigned int i = 0; + for(i = 0; i < verts; i++) + { + VECSUBMUL(to[i], fLongVector[i], scalar); + } +} +/* dot product for big vector */ +DO_INLINE float dot_lfvector(float (*fLongVectorA)[3], float (*fLongVectorB)[3], unsigned int verts) +{ + unsigned int i = 0; + +#ifndef _WIN32 + float temp __attribute__ ((aligned (16) ) )= 0.0f; // __declspec(align(16)) +#else + float temp = 0.0f; +#endif + +#pragma omp parallel for reduction(+: temp) schedule(guided, 1) + for(i = 0; i < verts; i++) + { + temp += INPR(fLongVectorA[i], fLongVectorB[i]); + } + return temp; +} +/* A = B + C --> for big vector */ +DO_INLINE void add_lfvector_lfvector(float (*to)[3], float (*fLongVectorA)[3], float (*fLongVectorB)[3], unsigned int verts) +{ + + unsigned int i = 0; + + for(i = 0; i < verts; i++) + { + VECADD(to[i], fLongVectorA[i], fLongVectorB[i]); + } + +} +/* A = B + C * float --> for big vector */ +DO_INLINE void add_lfvector_lfvectorS(float (*to)[3], float (*fLongVectorA)[3], float (*fLongVectorB)[3], float bS, unsigned int verts) +{ + unsigned int i = 0; + + for(i = 0; i < verts; i++) + { + VECADDS(to[i], fLongVectorA[i], fLongVectorB[i], bS); + + } +} +/* A = B * float + C * float --> for big vector */ +DO_INLINE void add_lfvectorS_lfvectorS(float (*to)[3], float (*fLongVectorA)[3], float aS, float (*fLongVectorB)[3], float bS, unsigned int verts) +{ + unsigned int i = 0; + + for(i = 0; i < verts; i++) + { + VECADDSS(to[i], fLongVectorA[i], aS, fLongVectorB[i], bS); + } +} +/* A = B - C * float --> for big vector */ +DO_INLINE void sub_lfvector_lfvectorS(float (*to)[3], float (*fLongVectorA)[3], float (*fLongVectorB)[3], float bS, unsigned int verts) +{ + unsigned int i = 0; + for(i = 0; i < verts; i++) + { + VECSUBS(to[i], fLongVectorA[i], fLongVectorB[i], bS); + } + +} +/* A = B - C --> for big vector */ +DO_INLINE void sub_lfvector_lfvector(float (*to)[3], float (*fLongVectorA)[3], float (*fLongVectorB)[3], unsigned int verts) +{ + unsigned int i = 0; + + for(i = 0; i < verts; i++) + { + VECSUB(to[i], fLongVectorA[i], fLongVectorB[i]); + } + +} +/////////////////////////// +// 4x4 matrix +/////////////////////////// +/* printf 4x4 matrix on console: for debug output */ +void print_fmatrix(float m3[3][3]) +{ + printf("%f\t%f\t%f\n",m3[0][0],m3[0][1],m3[0][2]); + printf("%f\t%f\t%f\n",m3[1][0],m3[1][1],m3[1][2]); + printf("%f\t%f\t%f\n\n",m3[2][0],m3[2][1],m3[2][2]); +} +/* copy 4x4 matrix */ +DO_INLINE void cp_fmatrix(float to[3][3], float from[3][3]) +{ + // memcpy(to, from, sizeof (float) * 9); + VECCOPY(to[0], from[0]); + VECCOPY(to[1], from[1]); + VECCOPY(to[2], from[2]); +} +/* calculate determinant of 4x4 matrix */ +DO_INLINE float det_fmatrix(float m[3][3]) +{ + return m[0][0]*m[1][1]*m[2][2] + m[1][0]*m[2][1]*m[0][2] + m[0][1]*m[1][2]*m[2][0] + -m[0][0]*m[1][2]*m[2][1] - m[0][1]*m[1][0]*m[2][2] - m[2][0]*m[1][1]*m[0][2]; +} +DO_INLINE void inverse_fmatrix(float to[3][3], float from[3][3]) +{ + unsigned int i, j; + float d; + + if((d=det_fmatrix(from))==0) + { + printf("can't build inverse"); + exit(0); + } + for(i=0;i<3;i++) + { + for(j=0;j<3;j++) + { + int i1=(i+1)%3; + int i2=(i+2)%3; + int j1=(j+1)%3; + int j2=(j+2)%3; + // reverse indexs i&j to take transpose + to[j][i] = (from[i1][j1]*from[i2][j2]-from[i1][j2]*from[i2][j1])/d; + /* + if(i==j) + to[i][j] = 1.0f / from[i][j]; + else + to[i][j] = 0; + */ + } + } + +} + +/* 4x4 matrix multiplied by a scalar */ +/* STATUS: verified */ +DO_INLINE void mul_fmatrix_S(float matrix[3][3], float scalar) +{ + mul_fvector_S(matrix[0], matrix[0],scalar); + mul_fvector_S(matrix[1], matrix[1],scalar); + mul_fvector_S(matrix[2], matrix[2],scalar); +} + +/* a vector multiplied by a 4x4 matrix */ +/* STATUS: verified */ +DO_INLINE void mul_fvector_fmatrix(float *to, float *from, float matrix[3][3]) +{ + to[0] = matrix[0][0]*from[0] + matrix[1][0]*from[1] + matrix[2][0]*from[2]; + to[1] = matrix[0][1]*from[0] + matrix[1][1]*from[1] + matrix[2][1]*from[2]; + to[2] = matrix[0][2]*from[0] + matrix[1][2]*from[1] + matrix[2][2]*from[2]; +} + +/* 4x4 matrix multiplied by a vector */ +/* STATUS: verified */ +DO_INLINE void mul_fmatrix_fvector(float *to, float matrix[3][3], float *from) +{ + to[0] = INPR(matrix[0],from); + to[1] = INPR(matrix[1],from); + to[2] = INPR(matrix[2],from); +} +/* 4x4 matrix multiplied by a 4x4 matrix */ +/* STATUS: verified */ +DO_INLINE void mul_fmatrix_fmatrix(float to[3][3], float matrixA[3][3], float matrixB[3][3]) +{ + mul_fvector_fmatrix(to[0], matrixA[0],matrixB); + mul_fvector_fmatrix(to[1], matrixA[1],matrixB); + mul_fvector_fmatrix(to[2], matrixA[2],matrixB); +} +/* 4x4 matrix addition with 4x4 matrix */ +DO_INLINE void add_fmatrix_fmatrix(float to[3][3], float matrixA[3][3], float matrixB[3][3]) +{ + VECADD(to[0], matrixA[0], matrixB[0]); + VECADD(to[1], matrixA[1], matrixB[1]); + VECADD(to[2], matrixA[2], matrixB[2]); +} +/* 4x4 matrix add-addition with 4x4 matrix */ +DO_INLINE void addadd_fmatrix_fmatrix(float to[3][3], float matrixA[3][3], float matrixB[3][3]) +{ + VECADDADD(to[0], matrixA[0], matrixB[0]); + VECADDADD(to[1], matrixA[1], matrixB[1]); + VECADDADD(to[2], matrixA[2], matrixB[2]); +} +/* 4x4 matrix sub-addition with 4x4 matrix */ +DO_INLINE void addsub_fmatrixS_fmatrixS(float to[3][3], float matrixA[3][3], float aS, float matrixB[3][3], float bS) +{ + VECADDSUBSS(to[0], matrixA[0], aS, matrixB[0], bS); + VECADDSUBSS(to[1], matrixA[1], aS, matrixB[1], bS); + VECADDSUBSS(to[2], matrixA[2], aS, matrixB[2], bS); +} +/* A -= B + C (4x4 matrix sub-addition with 4x4 matrix) */ +DO_INLINE void subadd_fmatrix_fmatrix(float to[3][3], float matrixA[3][3], float matrixB[3][3]) +{ + VECSUBADD(to[0], matrixA[0], matrixB[0]); + VECSUBADD(to[1], matrixA[1], matrixB[1]); + VECSUBADD(to[2], matrixA[2], matrixB[2]); +} +/* A -= B*x + C*y (4x4 matrix sub-addition with 4x4 matrix) */ +DO_INLINE void subadd_fmatrixS_fmatrixS(float to[3][3], float matrixA[3][3], float aS, float matrixB[3][3], float bS) +{ + VECSUBADDSS(to[0], matrixA[0], aS, matrixB[0], bS); + VECSUBADDSS(to[1], matrixA[1], aS, matrixB[1], bS); + VECSUBADDSS(to[2], matrixA[2], aS, matrixB[2], bS); +} +/* A = B - C (4x4 matrix subtraction with 4x4 matrix) */ +DO_INLINE void sub_fmatrix_fmatrix(float to[3][3], float matrixA[3][3], float matrixB[3][3]) +{ + VECSUB(to[0], matrixA[0], matrixB[0]); + VECSUB(to[1], matrixA[1], matrixB[1]); + VECSUB(to[2], matrixA[2], matrixB[2]); +} +/* A += B - C (4x4 matrix add-subtraction with 4x4 matrix) */ +DO_INLINE void addsub_fmatrix_fmatrix(float to[3][3], float matrixA[3][3], float matrixB[3][3]) +{ + VECADDSUB(to[0], matrixA[0], matrixB[0]); + VECADDSUB(to[1], matrixA[1], matrixB[1]); + VECADDSUB(to[2], matrixA[2], matrixB[2]); +} +///////////////////////////////////////////////////////////////// +// special functions +///////////////////////////////////////////////////////////////// +/* a vector multiplied and added to/by a 4x4 matrix */ +DO_INLINE void muladd_fvector_fmatrix(float to[3], float from[3], float matrix[3][3]) +{ + to[0] += matrix[0][0]*from[0] + matrix[1][0]*from[1] + matrix[2][0]*from[2]; + to[1] += matrix[0][1]*from[0] + matrix[1][1]*from[1] + matrix[2][1]*from[2]; + to[2] += matrix[0][2]*from[0] + matrix[1][2]*from[1] + matrix[2][2]*from[2]; +} +/* 4x4 matrix multiplied and added to/by a 4x4 matrix and added to another 4x4 matrix */ +DO_INLINE void muladd_fmatrix_fmatrix(float to[3][3], float matrixA[3][3], float matrixB[3][3]) +{ + muladd_fvector_fmatrix(to[0], matrixA[0],matrixB); + muladd_fvector_fmatrix(to[1], matrixA[1],matrixB); + muladd_fvector_fmatrix(to[2], matrixA[2],matrixB); +} +/* a vector multiplied and sub'd to/by a 4x4 matrix */ +DO_INLINE void mulsub_fvector_fmatrix(float to[3], float from[3], float matrix[3][3]) +{ + to[0] -= matrix[0][0]*from[0] + matrix[1][0]*from[1] + matrix[2][0]*from[2]; + to[1] -= matrix[0][1]*from[0] + matrix[1][1]*from[1] + matrix[2][1]*from[2]; + to[2] -= matrix[0][2]*from[0] + matrix[1][2]*from[1] + matrix[2][2]*from[2]; +} +/* 4x4 matrix multiplied and sub'd to/by a 4x4 matrix and added to another 4x4 matrix */ +DO_INLINE void mulsub_fmatrix_fmatrix(float to[3][3], float matrixA[3][3], float matrixB[3][3]) +{ + mulsub_fvector_fmatrix(to[0], matrixA[0],matrixB); + mulsub_fvector_fmatrix(to[1], matrixA[1],matrixB); + mulsub_fvector_fmatrix(to[2], matrixA[2],matrixB); +} +/* 4x4 matrix multiplied+added by a vector */ +/* STATUS: verified */ +DO_INLINE void muladd_fmatrix_fvector(float to[3], float matrix[3][3], float from[3]) +{ + to[0] += INPR(matrix[0],from); + to[1] += INPR(matrix[1],from); + to[2] += INPR(matrix[2],from); +} +/* 4x4 matrix multiplied+sub'ed by a vector */ +DO_INLINE void mulsub_fmatrix_fvector(float to[3], float matrix[3][3], float from[3]) +{ + to[0] -= INPR(matrix[0],from); + to[1] -= INPR(matrix[1],from); + to[2] -= INPR(matrix[2],from); +} +///////////////////////////////////////////////////////////////// + +/////////////////////////// +// SPARSE SYMMETRIC big matrix with 4x4 matrix entries +/////////////////////////// +/* printf a big matrix on console: for debug output */ +void print_bfmatrix(fmatrix3x3 *m3) +{ + unsigned int i = 0; + + for(i = 0; i < m3[0].vcount + m3[0].scount; i++) + { + print_fmatrix(m3[i].m); + } +} +/* create big matrix */ +DO_INLINE fmatrix3x3 *create_bfmatrix(unsigned int verts, unsigned int springs) +{ + // TODO: check if memory allocation was successfull */ + fmatrix3x3 *temp = (fmatrix3x3 *)MEM_callocN (sizeof (fmatrix3x3) * (verts + springs), "cloth_implicit_alloc_matrix"); + temp[0].vcount = verts; + temp[0].scount = springs; + return temp; +} +/* delete big matrix */ +DO_INLINE void del_bfmatrix(fmatrix3x3 *matrix) +{ + if (matrix != NULL) + { + MEM_freeN (matrix); + } +} +/* copy big matrix */ +DO_INLINE void cp_bfmatrix(fmatrix3x3 *to, fmatrix3x3 *from) +{ + // TODO bounds checking + memcpy(to, from, sizeof(fmatrix3x3) * (from[0].vcount+from[0].scount) ); +} +/* init the diagonal of big matrix */ +// slow in parallel +DO_INLINE void initdiag_bfmatrix(fmatrix3x3 *matrix, float m3[3][3]) +{ + unsigned int i,j; + float tmatrix[3][3] = {{0,0,0},{0,0,0},{0,0,0}}; + + for(i = 0; i < matrix[0].vcount; i++) + { + cp_fmatrix(matrix[i].m, m3); + } + for(j = matrix[0].vcount; j < matrix[0].vcount+matrix[0].scount; j++) + { + cp_fmatrix(matrix[j].m, tmatrix); + } +} +/* init big matrix */ +DO_INLINE void init_bfmatrix(fmatrix3x3 *matrix, float m3[3][3]) +{ + unsigned int i; + + for(i = 0; i < matrix[0].vcount+matrix[0].scount; i++) + { + cp_fmatrix(matrix[i].m, m3); + } +} +/* multiply big matrix with scalar*/ +DO_INLINE void mul_bfmatrix_S(fmatrix3x3 *matrix, float scalar) +{ + unsigned int i = 0; + for(i = 0; i < matrix[0].vcount+matrix[0].scount; i++) + { + mul_fmatrix_S(matrix[i].m, scalar); + } +} +/* SPARSE SYMMETRIC multiply big matrix with long vector*/ +/* STATUS: verified */ +DO_INLINE void mul_bfmatrix_lfvector( float (*to)[3], fmatrix3x3 *from, float (*fLongVector)[3]) +{ + unsigned int i = 0,j=0; + zero_lfvector(to, from[0].vcount); + /* process diagonal elements */ + for(i = 0; i < from[0].vcount; i++) + { + muladd_fmatrix_fvector(to[from[i].r], from[i].m, fLongVector[from[i].c]); + } + + /* process off-diagonal entries (every off-diagonal entry needs to be symmetric) */ + for(j = from[0].vcount; j < from[0].vcount+from[0].scount; j++) + { + muladd_fmatrix_fvector(to[from[j].c], from[j].m, fLongVector[from[j].r]); + muladd_fmatrix_fvector(to[from[j].r], from[j].m, fLongVector[from[j].c]); + } + +} +/* SPARSE SYMMETRIC add big matrix with big matrix: A = B + C*/ +DO_INLINE void add_bfmatrix_bfmatrix( fmatrix3x3 *to, fmatrix3x3 *from, fmatrix3x3 *matrix) +{ + unsigned int i = 0; + + /* process diagonal elements */ + for(i = 0; i < matrix[0].vcount+matrix[0].scount; i++) + { + add_fmatrix_fmatrix(to[i].m, from[i].m, matrix[i].m); + } + +} +/* SPARSE SYMMETRIC add big matrix with big matrix: A += B + C */ +DO_INLINE void addadd_bfmatrix_bfmatrix( fmatrix3x3 *to, fmatrix3x3 *from, fmatrix3x3 *matrix) +{ + unsigned int i = 0; + + /* process diagonal elements */ + for(i = 0; i < matrix[0].vcount+matrix[0].scount; i++) + { + addadd_fmatrix_fmatrix(to[i].m, from[i].m, matrix[i].m); + } + +} +/* SPARSE SYMMETRIC subadd big matrix with big matrix: A -= B + C */ +DO_INLINE void subadd_bfmatrix_bfmatrix( fmatrix3x3 *to, fmatrix3x3 *from, fmatrix3x3 *matrix) +{ + unsigned int i = 0; + + /* process diagonal elements */ + for(i = 0; i < matrix[0].vcount+matrix[0].scount; i++) + { + subadd_fmatrix_fmatrix(to[i].m, from[i].m, matrix[i].m); + } + +} +/* A = B - C (SPARSE SYMMETRIC sub big matrix with big matrix) */ +DO_INLINE void sub_bfmatrix_bfmatrix( fmatrix3x3 *to, fmatrix3x3 *from, fmatrix3x3 *matrix) +{ + unsigned int i = 0; + + /* process diagonal elements */ + for(i = 0; i < matrix[0].vcount+matrix[0].scount; i++) + { + sub_fmatrix_fmatrix(to[i].m, from[i].m, matrix[i].m); + } + +} +/* SPARSE SYMMETRIC sub big matrix with big matrix S (special constraint matrix with limited entries) */ +DO_INLINE void sub_bfmatrix_Smatrix( fmatrix3x3 *to, fmatrix3x3 *from, fmatrix3x3 *matrix) +{ + unsigned int i = 0; + + /* process diagonal elements */ + for(i = 0; i < matrix[0].vcount; i++) + { + sub_fmatrix_fmatrix(to[matrix[i].c].m, from[matrix[i].c].m, matrix[i].m); + } + +} +/* A += B - C (SPARSE SYMMETRIC addsub big matrix with big matrix) */ +DO_INLINE void addsub_bfmatrix_bfmatrix( fmatrix3x3 *to, fmatrix3x3 *from, fmatrix3x3 *matrix) +{ + unsigned int i = 0; + + /* process diagonal elements */ + for(i = 0; i < matrix[0].vcount+matrix[0].scount; i++) + { + addsub_fmatrix_fmatrix(to[i].m, from[i].m, matrix[i].m); + } + +} +/* SPARSE SYMMETRIC sub big matrix with big matrix*/ +/* A -= B * float + C * float --> for big matrix */ +/* VERIFIED */ +DO_INLINE void subadd_bfmatrixS_bfmatrixS( fmatrix3x3 *to, fmatrix3x3 *from, float aS, fmatrix3x3 *matrix, float bS) +{ + unsigned int i = 0; + + /* process diagonal elements */ + for(i = 0; i < matrix[0].vcount+matrix[0].scount; i++) + { + subadd_fmatrixS_fmatrixS(to[i].m, from[i].m, aS, matrix[i].m, bS); + } + +} + +/////////////////////////////////////////////////////////////////// +// simulator start +/////////////////////////////////////////////////////////////////// +static float I[3][3] = {{1,0,0},{0,1,0},{0,0,1}}; +static float ZERO[3][3] = {{0,0,0}, {0,0,0}, {0,0,0}}; +typedef struct Implicit_Data +{ + lfVector *X, *V, *Xnew, *Vnew, *olddV, *F, *B, *dV, *z; + fmatrix3x3 *A, *dFdV, *dFdX, *S, *P, *Pinv, *bigI; +} Implicit_Data; +int implicit_init (Object *ob, ClothModifierData *clmd) +{ + unsigned int i = 0; + unsigned int pinned = 0; + Cloth *cloth; + ClothVertex *verts; + ClothSpring *springs; + Implicit_Data *id; + + // init memory guard + // MEMORY_BASE.first = MEMORY_BASE.last = NULL; + + cloth = (Cloth *)clmd->clothObject; + verts = cloth->verts; + springs = cloth->springs; + + // create implicit base + id = (Implicit_Data *)MEM_callocN (sizeof(Implicit_Data), "implicit vecmat"); + cloth->implicit = id; + + /* process diagonal elements */ + id->A = create_bfmatrix(cloth->numverts, cloth->numsprings); + id->dFdV = create_bfmatrix(cloth->numverts, cloth->numsprings); + id->dFdX = create_bfmatrix(cloth->numverts, cloth->numsprings); + id->S = create_bfmatrix(cloth->numverts, 0); + id->Pinv = create_bfmatrix(cloth->numverts, cloth->numsprings); + id->P = create_bfmatrix(cloth->numverts, cloth->numsprings); + id->bigI = create_bfmatrix(cloth->numverts, cloth->numsprings); // TODO 0 springs + id->X = create_lfvector(cloth->numverts); + id->Xnew = create_lfvector(cloth->numverts); + id->V = create_lfvector(cloth->numverts); + id->Vnew = create_lfvector(cloth->numverts); + id->olddV = create_lfvector(cloth->numverts); + zero_lfvector(id->olddV, cloth->numverts); + id->F = create_lfvector(cloth->numverts); + id->B = create_lfvector(cloth->numverts); + id->dV = create_lfvector(cloth->numverts); + id->z = create_lfvector(cloth->numverts); + for(i=0;inumverts;i++) + { + id->A[i].r = id->A[i].c = id->dFdV[i].r = id->dFdV[i].c = id->dFdX[i].r = id->dFdX[i].c = id->P[i].c = id->P[i].r = id->Pinv[i].c = id->Pinv[i].r = id->bigI[i].c = id->bigI[i].r = i; + + if(verts [i].flags & CVERT_FLAG_PINNED) + { + id->S[pinned].pinned = 1; + id->S[pinned].c = id->S[pinned].r = i; + pinned++; + } + } + + // S is special and needs specific vcount and scount + id->S[0].vcount = pinned; id->S[0].scount = 0; + + // init springs */ + for(i=0;inumsprings;i++) + { + // dFdV_start[i].r = big_I[i].r = big_zero[i].r = + id->A[i+cloth->numverts].r = id->dFdV[i+cloth->numverts].r = id->dFdX[i+cloth->numverts].r = + id->P[i+cloth->numverts].r = id->Pinv[i+cloth->numverts].r = id->bigI[i+cloth->numverts].r = springs[i].ij; + + // dFdV_start[i].c = big_I[i].c = big_zero[i].c = + id->A[i+cloth->numverts].c = id->dFdV[i+cloth->numverts].c = id->dFdX[i+cloth->numverts].c = + id->P[i+cloth->numverts].c = id->Pinv[i+cloth->numverts].c = id->bigI[i+cloth->numverts].c = springs[i].kl; + + springs[i].matrix_index = i + cloth->numverts; + } + + for(i = 0; i < cloth->numverts; i++) + { + VECCOPY(id->X[i], verts[i].x); + } + + return 1; +} +int implicit_free (ClothModifierData *clmd) +{ + Implicit_Data *id; + Cloth *cloth; + cloth = (Cloth *)clmd->clothObject; + + if(cloth) + { + id = cloth->implicit; + + if(id) + { + del_bfmatrix(id->A); + del_bfmatrix(id->dFdV); + del_bfmatrix(id->dFdX); + del_bfmatrix(id->S); + del_bfmatrix(id->P); + del_bfmatrix(id->Pinv); + del_bfmatrix(id->bigI); + + del_lfvector(id->X); + del_lfvector(id->Xnew); + del_lfvector(id->V); + del_lfvector(id->Vnew); + del_lfvector(id->olddV); + del_lfvector(id->F); + del_lfvector(id->B); + del_lfvector(id->dV); + del_lfvector(id->z); + + MEM_freeN(id); + } + } + + return 1; +} +DO_INLINE float fb(float length, float L) +{ + float x = length/L; + return (-11.541f*pow(x,4)+34.193f*pow(x,3)-39.083f*pow(x,2)+23.116f*x-9.713f); +} +DO_INLINE float fbderiv(float length, float L) +{ + float x = length/L; + + return (-46.164f*pow(x,3)+102.579f*pow(x,2)-78.166f*x+23.116f); +} + +DO_INLINE float fbstar(float length, float L, float kb, float cb) +{ + float tempfb = kb * fb(length, L); + + float fbstar = cb * (length - L); + + if(tempfb < fbstar) + return fbstar; + else + return tempfb; +} +DO_INLINE float fbstar_jacobi(float length, float L, float kb, float cb) +{ + float tempfb = kb * fb(length, L); + float fbstar = cb * (length - L); + + if(tempfb < fbstar) + { + return cb; + } + else + { + return kb * fbderiv(length, L); + } +} +DO_INLINE void filter(lfVector *V, fmatrix3x3 *S) +{ + unsigned int i=0; + + for(i=0;istarget && conjgrad_loopcount < conjgrad_looplimit)) + { + // Mul(q,A,d); // q = A*d; + mul_bfmatrix_lfvector(q, lA, d); + + filter(q,S); + + a = s/dot_lfvector(d, q, numverts); + + // X = X + d*a; + add_lfvector_lfvectorS(ldV, ldV, d, a, numverts); + + // r = r - q*a; + sub_lfvector_lfvectorS(r, r, q, a, numverts); + + s_prev = s; + s = dot_lfvector(r, r, numverts); + + //d = r+d*(s/s_prev); + add_lfvector_lfvectorS(d, r, d, (s/s_prev), numverts); + + filter(d,S); + + conjgrad_loopcount++; + } + conjgrad_lasterror = s; + + del_lfvector(q); + del_lfvector(d); + del_lfvector(tmp); + del_lfvector(r); + // printf("W/O conjgrad_loopcount: %d\n", conjgrad_loopcount); + + return conjgrad_loopcount(epsilon_sqr*delta0))&& (conjgrad_loopcount++ < conjgrad_looplimit)) +{ +////////////////////////// +// (s) = q = S*A*c +////////////////////////// +// q = A*c; +mul_bfmatrix_lfvector(q, lA, c); +filter(q,S); +////////////////////////// + +////////////////////////// +// alpha = deltanew / (c^T * q) +////////////////////////// +alpha = deltanew/dot_lfvector(c, q, numverts); +////////////////////////// + +//X = X + c*alpha; +add_lfvector_lfvectorS(ldV, ldV, c, alpha, numverts); +//r = r - q*alpha; +sub_lfvector_lfvectorS(r, r, q, alpha, numverts); + +////////////////////////// +// (h) = s = P^-1 * r +////////////////////////// +// s = Pinv * r; +mul_bfmatrix_lfvector(s, Pinv, r); +filter(s,S); +////////////////////////// + +deltaold = deltanew; + +// deltanew = dot(r,s); +deltanew = dot_lfvector(r, s, numverts); + +////////////////////////// +// c = S * (s + (deltanew/deltaold)*c) +////////////////////////// +// c = s + c * (deltanew/deltaold); +add_lfvector_lfvectorS(c, s, c, (deltanew/deltaold), numverts); +filter(c,S); +////////////////////////// + +} +conjgrad_lasterror = deltanew; +del_lfvector(q); +del_lfvector(c); +del_lfvector(tmp); +del_lfvector(r); +del_lfvector(s); +del_lfvector(filterX0); +del_lfvector(p_fb); +del_lfvector(bhat); +printf("Bconjgrad_loopcount: %d\n", conjgrad_loopcount); + +return conjgrad_loopcount 1.0f) ? (1.0f): (L/length))); + sub_fmatrix_fmatrix(to, to, I); + mul_fmatrix_S(to, -k); +} +DO_INLINE void dfdx_damp(float to[3][3], float dir[3],float length,const float vel[3],float rest,float damping) +{ + // inner spring damping vel is the relative velocity of the endpoints. + // return (I-outerprod(dir,dir)) * (-damping * -(dot(dir,vel)/Max(length,rest))); + mul_fvectorT_fvector(to, dir, dir); + sub_fmatrix_fmatrix(to, I, to); + mul_fmatrix_S(to, (-damping * -(INPR(dir,vel)/MAX2(length,rest)))); + +} + +DO_INLINE void calc_spring_force(ClothModifierData *clmd, ClothSpring *s, lfVector *lF, lfVector *X, lfVector *V, fmatrix3x3 *dFdV, fmatrix3x3 *dFdX) +{ + float extent[3]; + float length = 0; + float dir[3] = {0,0,0}; + float vel[3]; + float k = 0.0f; + float L = s->restlen; + float cb = clmd->sim_parms.structural; + + float f[3] = {0,0,0}; + float stretch_force[3] = {0,0,0}; + float bending_force[3] = {0,0,0}; + float damping_force[3] = {0,0,0}; + float dfdx[3][3]={ {0,0,0}, {0,0,0}, {0,0,0}}; + float dfdv[3][3]; + int needed = 0; + Cloth *cloth = clmd->clothObject; + ClothVertex *verts = cloth->verts; + + // calculate elonglation + VECSUB(extent, X[s->kl], X[s->ij]); + VECSUB(vel, V[s->kl], V[s->ij]); + length = sqrt(INPR(extent, extent)); + + + + if(length > ABS(ALMOST_ZERO)) + { + if(length>L) + { + if((clmd->sim_parms.flags & CSIMSETT_FLAG_TEARING_ENABLED) + && ((((length-L)*100.0f/L) > clmd->sim_parms.maxspringlen))) // cut spring! + { + s->flags |= CSPRING_FLAG_DEACTIVATE; + return; + } + } + + mul_fvector_S(dir, extent, 1.0f/length); + } + else + { + mul_fvector_S(dir, extent, 0.0f); + } + + + // calculate force of structural springs + if(s->type != BENDING) + { + if(length > L) // only on elonglation + { + needed++; + + k = clmd->sim_parms.structural; + + mul_fvector_S(stretch_force, dir, (k*(length-L))); + + VECADD(f, f, stretch_force); + + // Ascher & Boxman, p.21: Damping only during elonglation + mul_fvector_S(damping_force, extent, clmd->sim_parms.Cdis * ((INPR(vel,extent)/length))); + VECADD(f, f, damping_force); + + dfdx_spring_type1(dfdx, dir,length,L,k); + + dfdv_damp(dfdv, dir,clmd->sim_parms.Cdis); + sub_fmatrix_fmatrix(dFdV[s->ij].m, dFdV[s->ij].m, dfdv); + sub_fmatrix_fmatrix(dFdV[s->kl].m, dFdV[s->kl].m, dfdv); + + add_fmatrix_fmatrix(dFdV[s->matrix_index].m, dFdV[s->matrix_index].m, dfdv); + + } + } + else // calculate force of bending springs + { + if(length < L) + { + k = clmd->sim_parms.bending; + + needed++; + + mul_fvector_S(bending_force, dir, fbstar(length, L, k, cb)); + VECADD(f, f, bending_force); + + dfdx_spring_type2(dfdx, dir,length,L,k, cb); + } + } + + if(needed) + { + VECADD(lF[s->ij], lF[s->ij], f); + VECSUB(lF[s->kl], lF[s->kl], f); + + sub_fmatrix_fmatrix(dFdX[s->ij].m, dFdX[s->ij].m, dfdx); + sub_fmatrix_fmatrix(dFdX[s->kl].m, dFdX[s->kl].m, dfdx); + + add_fmatrix_fmatrix(dFdX[s->matrix_index].m, dFdX[s->matrix_index].m, dfdx); + } +} + +DO_INLINE void calculateTriangleNormal(float to[3], lfVector *X, MFace mface) +{ + float v1[3], v2[3]; + + VECSUB(v1, X[mface.v2], X[mface.v1]); + VECSUB(v2, X[mface.v3], X[mface.v1]); + cross_fvector(to, v1, v2); +} +DO_INLINE void calculatQuadNormal(float to[3], lfVector *X, MFace mface) +{ + float temp = CalcNormFloat4(X[mface.v1],X[mface.v2],X[mface.v3],X[mface.v4],to); + mul_fvector_S(to, to, temp); +} + +void calculateWeightedVertexNormal(ClothModifierData *clmd, MFace *mfaces, float to[3], int index, lfVector *X) +{ + float temp[3]; + int i; + Cloth *cloth = clmd->clothObject; + + for(i = 0; i < cloth->numfaces; i++) + { + // check if this triangle contains the selected vertex + if(mfaces[i].v1 == index || mfaces[i].v2 == index || mfaces[i].v3 == index || mfaces[i].v4 == index) + { + calculatQuadNormal(temp, X, mfaces[i]); + VECADD(to, to, temp); + } + } +} +float calculateVertexWindForce(int index, float wind[3], float vertexnormal[3]) +{ + return fabs(INPR(wind, vertexnormal) * 0.5f); +} + +DO_INLINE void calc_triangle_force(ClothModifierData *clmd, MFace mface, lfVector *F, lfVector *X, lfVector *V, fmatrix3x3 *dFdV, fmatrix3x3 *dFdX, ListBase *effectors) +{ + +} + +void calc_force(ClothModifierData *clmd, lfVector *lF, lfVector *lX, lfVector *lV, fmatrix3x3 *dFdV, fmatrix3x3 *dFdX, ListBase *effectors, float time) +{ + /* Collect forces and derivatives: F,dFdX,dFdV */ + Cloth *cloth = clmd->clothObject; + unsigned int i = 0; + float spring_air = clmd->sim_parms.Cvi * 0.01f; /* viscosity of air scaled in percent */ + float gravity[3]; + float tm2[3][3] = {{-spring_air,0,0}, {0,-spring_air,0},{0,0,-spring_air}}; + ClothVertex *verts = cloth->verts; + ClothSpring *springs = cloth->springs; + MFace *mfaces = cloth->mfaces; + float wind_normalized[3]; + unsigned int numverts = cloth->numverts; + float auxvect[3], velgoal[3], tvect[3]; + float kd, ks; + + + VECCOPY(gravity, clmd->sim_parms.gravity); + mul_fvector_S(gravity, gravity, 0.001f); /* scale gravity force */ + + /* set dFdX jacobi matrix to zero */ + init_bfmatrix(dFdX, ZERO); + /* set dFdX jacobi matrix diagonal entries to -spring_air */ + initdiag_bfmatrix(dFdV, tm2); + + init_lfvector(lF, gravity, numverts); + + submul_lfvectorS(lF, lV, spring_air, numverts); + + /* do goal stuff */ + if(clmd->sim_parms.flags & CSIMSETT_FLAG_GOAL) + { + for(i = 0; i < numverts; i++) + { + if(verts [i].goal < SOFTGOALSNAP) + { + // current_position = xold + t * (newposition - xold) + VECSUB(tvect, verts[i].xconst, verts[i].xold); + mul_fvector_S(tvect, tvect, time); + VECADD(tvect, tvect, verts[i].xold); + + VecSubf(auxvect, tvect, lX[i]); + ks = 1.0f/(1.0f- verts [i].goal*clmd->sim_parms.goalspring)-1.0f ; + VECADDS(lF[i], lF[i], auxvect, -ks); + + /* calulate damping forces generated by goals*/ + VECSUB(velgoal,verts[i].xold, verts[i].xconst); + kd = clmd->sim_parms.goalfrict * 0.01f; // friction force scale taken from SB + VECSUBADDSS(lF[i], velgoal, kd, lV[i], kd); + + } + } + } + + /* handle external forces like wind */ + if(effectors) + { + float wind[3] = {0,1.0f,0}; + float force[3]= {0.0f, 0.0f, 0.0f}; + + for(i = 0; i < cloth->numverts; i++) + { + float vertexnormal[3]={0,0,0}; + + pdDoEffectors(effectors, lX[i], force, wind, (float)G.scene->r.cfra, 0.0f, PE_WIND_AS_SPEED); + + VECCOPY(wind_normalized, wind); + Normalize(wind_normalized); + + calculateWeightedVertexNormal(clmd, mfaces, vertexnormal, i, lX); + VECADDS(lF[i], lF[i], wind_normalized, -calculateVertexWindForce(i, wind, vertexnormal)); + } + } + + /* calculate and apply spring forces */ + for(i = 0; i < cloth->numsprings; i++) + { + // only handle active springs + if(((clmd->sim_parms.flags & CSIMSETT_FLAG_TEARING_ENABLED) && !(springs[i].flags & CSPRING_FLAG_DEACTIVATE))|| !(clmd->sim_parms.flags & CSIMSETT_FLAG_TEARING_ENABLED)) + { + calc_spring_force(clmd, &springs[i], lF, lX, lV, dFdV, dFdX); + } + } + +} + +void simulate_implicit_euler(lfVector *Vnew, lfVector *lX, lfVector *lV, lfVector *lF, fmatrix3x3 *dFdV, fmatrix3x3 *dFdX, float dt, fmatrix3x3 *A, lfVector *B, lfVector *dV, fmatrix3x3 *S, lfVector *z, lfVector *olddV) +{ + unsigned int numverts = dFdV[0].vcount; + + lfVector *dFdXmV = create_lfvector(numverts); + + initdiag_bfmatrix(A, I); + zero_lfvector(dV, numverts); + + subadd_bfmatrixS_bfmatrixS(A, dFdV, dt, dFdX, (dt*dt)); + + mul_bfmatrix_lfvector(dFdXmV, dFdX, lV); + + add_lfvectorS_lfvectorS(B, lF, dt, dFdXmV, (dt*dt), numverts); + cg_filtered(dV, A, B, z, S); /* conjugate gradient algorithm to solve Ax=b */ + // cg_filtered_pre(dV, A, B, z, olddV, dt); + cp_lfvector(olddV, dV, numverts); + + // advance velocities + add_lfvector_lfvector(Vnew, lV, dV, numverts); + + del_lfvector(dFdXmV); +} + +int implicit_solver (Object *ob, float frame, ClothModifierData *clmd, ListBase *effectors, + CM_COLLISION_SELF self_collision, CM_COLLISION_OBJ obj_collision) +{ + unsigned int i=0, j; + float step=0.0f, tf=1.0f; + Cloth *cloth = clmd->clothObject; + ClothVertex *verts = cloth->verts; + unsigned int numverts = cloth->numverts; + float dt = 1.0f / clmd->sim_parms.stepsPerFrame; + Implicit_Data *id = cloth->implicit; + int result = 0; + + if(clmd->sim_parms.flags & CSIMSETT_FLAG_GOAL) /* do goal stuff */ + { + for(i = 0; i < numverts; i++) + { + // update velocities with constrained velocities from pinned verts + if(verts [i].goal >= SOFTGOALSNAP) + { + VECSUB(id->V[i], verts[i].xconst, verts[i].xold); + } + } + } + + while(step < tf) + { + effectors= pdInitEffectors(ob,NULL); + + // calculate + calc_force(clmd, id->F, id->X, id->V, id->dFdV, id->dFdX, effectors, step); + simulate_implicit_euler(id->Vnew, id->X, id->V, id->F, id->dFdV, id->dFdX, dt, id->A, id->B, id->dV, id->S, id->z, id->olddV); + add_lfvector_lfvectorS(id->Xnew, id->X, id->Vnew, dt, numverts); + + // collisions + itstart(); + // update verts to current positions + for(i = 0; i < numverts; i++) + { + VECCOPY(verts[i].tx, id->Xnew[i]); + + VECSUB(verts[i].tv, verts[i].tx, verts[i].txold); + } + + // call collision function + // result = cloth_bvh_objcollision(clmd, step + dt, bvh_collision_response, dt); + + // copy corrected positions back to simulation + for(i = 0; i < numverts; i++) + { + // TODO: calculate v_n+1 from v_n+1/2 + if(result) + { + VECADD(verts[i].tx, verts[i].txold, verts[i].tv); + + VECCOPY(verts[i].txold, verts[i].tx); + + VECCOPY(id->Xnew[i], verts[i].tx); + + VECCOPY(id->Vnew[i], verts[i].tv); + VecMulf(id->Vnew[i], 1.0f / dt); + } + else + { + VECCOPY(verts[i].txold, id->Xnew[i]); + } + } + + // X = Xnew; + cp_lfvector(id->X, id->Xnew, numverts); + + // if there were collisions, advance the velocity from v_n+1/2 to v_n+1 + if(result) + { + // V = Vnew; + cp_lfvector(id->V, id->Vnew, numverts); + + // calculate + calc_force(clmd, id->F, id->X, id->V, id->dFdV, id->dFdX, effectors, step); + simulate_implicit_euler(id->Vnew, id->X, id->V, id->F, id->dFdV, id->dFdX, dt / 2.0f, id->A, id->B, id->dV, id->S, id->z, id->olddV); + } + + itend(); + // printf("collision time: %f\n", (float)itval()); + + // V = Vnew; + cp_lfvector(id->V, id->Vnew, numverts); + + step += dt; + + if(effectors) pdEndEffectors(effectors); + } + + for(i = 0; i < numverts; i++) + { + if(clmd->sim_parms.flags & CSIMSETT_FLAG_GOAL) + { + if(verts [i].goal < SOFTGOALSNAP) + { + VECCOPY(verts[i].txold, id->X[i]); + VECCOPY(verts[i].x, id->X[i]); + VECCOPY(verts[i].v, id->V[i]); + } + else + { + VECCOPY(verts[i].txold, verts[i].xconst); + VECCOPY(verts[i].x, verts[i].xconst); + VECCOPY(verts[i].v, id->V[i]); + } + } + else + { + VECCOPY(verts[i].txold, id->X[i]); + VECCOPY(verts[i].x, id->X[i]); + VECCOPY(verts[i].v, id->V[i]); + } + } + return 1; +} + +void implicit_set_positions (ClothModifierData *clmd) +{ + Cloth *cloth = clmd->clothObject; + ClothVertex *verts = cloth->verts; + unsigned int numverts = cloth->numverts, i; + Implicit_Data *id = cloth->implicit; + for(i = 0; i < numverts; i++) + { + VECCOPY(id->X[i], verts[i].x); + VECCOPY(id->V[i], verts[i].v); + } +} diff --git a/source/blender/blenkernel/intern/kdop.c b/source/blender/blenkernel/intern/kdop.c new file mode 100644 index 00000000000..cdcb16c67f6 --- /dev/null +++ b/source/blender/blenkernel/intern/kdop.c @@ -0,0 +1,861 @@ +/* collision.c +* +* +* ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* as published by the Free Software Foundation; either version 2 +* of the License, or (at your option) any later version. The Blender +* Foundation also sells licenses for use in proprietary software under +* the Blender License. See http://www.blender.org/BL/ for information +* about this. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software Foundation, +* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +* +* The Original Code is Copyright (C) Blender Foundation +* All rights reserved. +* +* The Original Code is: all of this file. +* +* Contributor(s): none yet. +* +* ***** END GPL/BL DUAL LICENSE BLOCK ***** +*/ + +#include +#include +#include +#include "MEM_guardedalloc.h" +/* types */ +#include "DNA_curve_types.h" +#include "DNA_object_types.h" +#include "DNA_object_force.h" +#include "DNA_cloth_types.h" +#include "DNA_key_types.h" +#include "DNA_mesh_types.h" +#include "DNA_meshdata_types.h" +#include "DNA_lattice_types.h" +#include "DNA_scene_types.h" +#include "DNA_modifier_types.h" +#include "BLI_blenlib.h" +#include "BLI_arithb.h" +#include "BLI_edgehash.h" +#include "BLI_linklist.h" +#include "BKE_curve.h" +#include "BKE_deform.h" +#include "BKE_DerivedMesh.h" +#include "BKE_cdderivedmesh.h" +#include "BKE_displist.h" +#include "BKE_effect.h" +#include "BKE_global.h" +#include "BKE_key.h" +#include "BKE_mesh.h" +#include "BKE_object.h" +#include "BKE_cloth.h" +#include "BKE_modifier.h" +#include "BKE_utildefines.h" +#include "BKE_DerivedMesh.h" +#include "BIF_editdeform.h" +#include "BIF_editkey.h" +#include "DNA_screen_types.h" +#include "BSE_headerbuttons.h" +#include "BIF_screen.h" +#include "BIF_space.h" +#include "mydevice.h" + + +//////////////////////////////////////////////////////////////////////// +// Additional fastened appending function +// It uses the link to the last inserted node as start value +// for searching the end of the list +// NEW: in compare to the original function, this one returns +// the reference to the last inserted node +//////////////////////////////////////////////////////////////////////// +LinkNode *BLI_linklist_append_fast(LinkNode **listp, void *ptr) { + LinkNode *nlink= MEM_mallocN(sizeof(*nlink), "nlink"); + LinkNode *node = *listp; + + nlink->link = ptr; + nlink->next = NULL; + + if(node == NULL){ + *listp = nlink; + } else { + while(node->next != NULL){ + node = node->next; + } + node->next = nlink; + } + return nlink; +} + + + +//////////////////////////////////////////////////////////////////////// +// Bounding Volume Hierarchy Definition +// +// Notes: From OBB until 26-DOP --> all bounding volumes possible, just choose type below +// Notes: You have to choose the type at compile time ITM +// Notes: You can choose the tree type --> binary, quad, octree, choose below +//////////////////////////////////////////////////////////////////////// + +static float KDOP_AXES[13][3] = +{ {1, 0, 0}, {0, 1, 0}, {0, 0, 1}, {1, 1, 1}, {1, -1, 1}, {1, 1, -1}, +{1, -1, -1}, {1, 1, 0}, {1, 0, 1}, {0, 1, 1}, {1, -1, 0}, {1, 0, -1}, +{0, 1, -1} +}; + +///////////// choose bounding volume here! ///////////// + +// #define KDOP_26 + +// #define KDOP_14 + +// AABB: +// #define KDOP_8 + +// OBB: +#define KDOP_14 + + + +#ifdef KDOP_26 +#define KDOP_END 13 +#define KDOP_START 0 +#endif + +// I didn't test this one! +#ifdef KDOP_18 +#define KDOP_END 7 +#define KDOP_START 13 +#endif + +#ifdef KDOP_14 +#define KDOP_END 7 +#define KDOP_START 0 +#endif + +// this is basicly some AABB +#ifdef KDOP_8 +#define KDOP_END 4 +#define KDOP_START 0 +#endif + +// this is basicly some OBB +#ifdef KDOP_6 +#define KDOP_END 3 +#define KDOP_START 0 +#endif + +////////////////////////////////////////////////////////////////////////////////////////////////////// +// Introsort +// with permission deriven from the following Java code: +// http://ralphunden.net/content/tutorials/a-guide-to-introsort/ +// and he derived it from the SUN STL +////////////////////////////////////////////////////////////////////////////////////////////////////// +static int size_threshold = 16; +/* +* Common methods for all algorithms +*/ +DO_INLINE void exchange(Tree **a, int i, int j) +{ + Tree *t=a[i]; + a[i]=a[j]; + a[j]=t; +} +DO_INLINE int floor_lg(int a) +{ + return (int)(floor(log(a)/log(2))); +} + +/* +* Insertion sort algorithm +*/ +static void insertionsort(Tree **a, int lo, int hi, int axis) +{ + int i,j; + Tree *t; + for (i=lo; i < hi; i++) + { + j=i; + t = a[i]; + while((j!=lo) && (t->bv[axis] < (a[j-1])->bv[axis])) + { + a[j] = a[j-1]; + j--; + } + a[j] = t; + } +} + +static int partition(Tree **a, int lo, int hi, Tree * x, int axis) +{ + int i=lo, j=hi; + while (1) + { + while ((a[i])->bv[axis] < x->bv[axis]) i++; + j=j-1; + while (x->bv[axis] < (a[j])->bv[axis]) j=j-1; + if(!(i < j)) + return i; + exchange(a, i,j); + i++; + } +} + +/* +* Heapsort algorithm +*/ +static void downheap(Tree **a, int i, int n, int lo, int axis) +{ + Tree * d = a[lo+i-1]; + int child; + while (i<=n/2) + { + child = 2*i; + if ((child < n) && ((a[lo+child-1])->bv[axis] < (a[lo+child])->bv[axis])) + { + child++; + } + if (!(d->bv[axis] < (a[lo+child-1])->bv[axis])) break; + a[lo+i-1] = a[lo+child-1]; + i = child; + } + a[lo+i-1] = d; +} + +static void heapsort(Tree **a, int lo, int hi, int axis) +{ + int n = hi-lo, i; + for (i=n/2; i>=1; i=i-1) + { + downheap(a, i,n,lo, axis); + } + for (i=n; i>1; i=i-1) + { + exchange(a, lo,lo+i-1); + downheap(a, 1,i-1,lo, axis); + } +} + +static Tree *medianof3(Tree **a, int lo, int mid, int hi, int axis) // returns Sortable +{ + if ((a[mid])->bv[axis] < (a[lo])->bv[axis]) + { + if ((a[hi])->bv[axis] < (a[mid])->bv[axis]) + return a[mid]; + else + { + if ((a[hi])->bv[axis] < (a[lo])->bv[axis]) + return a[hi]; + else + return a[lo]; + } + } + else + { + if ((a[hi])->bv[axis] < (a[mid])->bv[axis]) + { + if ((a[hi])->bv[axis] < (a[lo])->bv[axis]) + return a[lo]; + else + return a[hi]; + } + else + return a[mid]; + } +} +/* +* Quicksort algorithm modified for Introsort +*/ +static void introsort_loop (Tree **a, int lo, int hi, int depth_limit, int axis) +{ + int p; + + while (hi-lo > size_threshold) + { + if (depth_limit == 0) + { + heapsort(a, lo, hi, axis); + return; + } + depth_limit=depth_limit-1; + p=partition(a, lo, hi, medianof3(a, lo, lo+((hi-lo)/2)+1, hi-1, axis), axis); + introsort_loop(a, p, hi, depth_limit, axis); + hi=p; + } +} + +DO_INLINE void sort(Tree **a0, int begin, int end, int axis) +{ + if (begin < end) + { + Tree **a=a0; + introsort_loop(a, begin, end, 2*floor_lg(end-begin), axis); + insertionsort(a, begin, end, axis); + } +} +DO_INLINE void bvh_sort_along_axis(Tree **face_list, int start, int end, int axis) +{ + sort(face_list, start, end, axis); +} +//////////////////////////////////////////////////////////////////////////////////////////////// +void bvh_free(BVH * bvh) +{ + LinkNode *search = NULL; + Tree *tree = NULL; + + if (bvh) + { + + search = bvh->tree; + + while(search) + { + LinkNode *next= search->next; + tree = search->link; + + MEM_freeN(tree); + + search = next; + } + + BLI_linklist_free(bvh->tree,NULL); + bvh->tree = NULL; + + MEM_freeN(bvh); + bvh = NULL; + } +} + +// only supports x,y,z axis in the moment +// but we should use a plain and simple function here for speed sake +DO_INLINE int bvh_largest_axis(float *bv) +{ + float middle_point[3]; + + middle_point[0] = (bv[1]) - (bv[0]); // x axis + middle_point[1] = (bv[3]) - (bv[2]); // y axis + middle_point[2] = (bv[5]) - (bv[4]); // z axis + if (middle_point[0] > middle_point[1]) + { + if (middle_point[0] > middle_point[2]) + return 1; // max x axis + else + return 5; // max z axis + } + else + { + if (middle_point[1] > middle_point[2]) + return 3; // max y axis + else + return 5; // max z axis + } +} + +// depends on the fact that the BVH's for each face is already build +DO_INLINE void bvh_calc_DOP_hull_from_faces(BVH * bvh, Tree **tri, int numfaces, float *bv) +{ + float newmin,newmax; + int i, j; + for (j = 0; j < numfaces; j++) + { + // for all Axes. + for (i = KDOP_START; i < KDOP_END; i++) + { + newmin = (tri [j])->bv[(2 * i)]; + if ((newmin < bv[(2 * i)]) || (j == 0)) + { + bv[(2 * i)] = newmin; + } + + newmax = (tri [j])->bv[(2 * i) + 1]; + if ((newmax > bv[(2 * i) + 1]) || (j == 0)) + { + bv[(2 * i) + 1] = newmax; + } + } + } +} + +DO_INLINE void bvh_calc_DOP_hull_static(BVH * bvh, Tree **tri, int numfaces, float *bv) +{ + ClothVertex *tempMVert = bvh->verts; + MFace *tempMFace = bvh->mfaces; + float *tempBV = bv; + float newminmax; + int i, j, k; + for (j = 0; j < numfaces; j++) + { + tempMFace = bvh->mfaces + (tri [j])->tri_index; + // 3 or 4 vertices per face. + for (k = 0; k < 4; k++) + { + int temp = 0; + // If this is a triangle. + if (k == 3 && !tempMFace->v4) + continue; + // TODO: other name for "temp" this gets all vertices of a face + if (k == 0) + temp = tempMFace->v1; + else if (k == 1) + temp = tempMFace->v2; + else if (k == 2) + temp = tempMFace->v3; + else if (k == 3) + temp = tempMFace->v4; + // for all Axes. + for (i = KDOP_START; i < KDOP_END; i++) + { + newminmax = INPR(tempMVert[temp].txold, KDOP_AXES[i]); + if ((newminmax < tempBV[(2 * i)]) || (k == 0 && j == 0)) + tempBV[(2 * i)] = newminmax; + if ((newminmax > tempBV[(2 * i) + 1])|| (k == 0 && j == 0)) + tempBV[(2 * i) + 1] = newminmax; + } + } + } +} +/* +DO_INLINE void bvh_calc_DOP_hull_moving(BVH * bvh, Tree **tri, int numfaces, float *bv) +{ +ClothVertex *tempMVert = bvh->verts; +MFace *tempMFace = bvh->mfaces; +float *tempBV = bv; +float newminmax; +int i, j, k; +for (j = 0; j < numfaces; j++) +{ +tempMFace = bvh->mfaces + (tri [j])->tri_index; +// 3 or 4 vertices per face. +for (k = 0; k < 4; k++) +{ +int temp = 0; +// If this is a triangle. +if (k == 3 && !tempMFace->v4) +continue; +// TODO: other name for "temp" this gets all vertices of a face +if (k == 0) +temp = tempMFace->v1; +else if (k == 1) +temp = tempMFace->v2; +else if (k == 2) +temp = tempMFace->v3; +else if (k == 3) +temp = tempMFace->v4; +// for all Axes. +for (i = KDOP_START; i < KDOP_END; i++) +{ +newminmax = INPR(tempMVert[temp].tx, KDOP_AXES[i]); +if ((newminmax < tempBV[(2 * i)]) || (k == 0 && j == 0)) +tempBV[(2 * i)] = newminmax; +// the same like some "else if" but with that condition I +// don't need to insert the first entry manually +if ((newminmax > tempBV[(2 * i) + 1])|| (k == 0 && j == 0)) +tempBV[(2 * i) + 1] = newminmax; + +newminmax = INPR(tempMVert[temp].txold, KDOP_AXES[i]); +if (newminmax < tempBV[(2 * i)]) +tempBV[(2 * i)] = newminmax; +if (newminmax > tempBV[(2 * i) + 1]) +tempBV[(2 * i) + 1] = newminmax; +} +} +} +} +*/ +static void bvh_div_env_node(BVH * bvh, TreeNode *tree, Tree **face_list, unsigned int start, unsigned int end, int lastaxis, LinkNode *nlink) +{ + int i = 0; + Tree *newtree = NULL; + int laxis = 0, max_nodes=4; + unsigned int tstart, tend; + LinkNode *nlink1 = nlink; + LinkNode *tnlink; + tree->traversed = 0; + // Determine which axis to split along + laxis = bvh_largest_axis(tree->bv); + + // Sort along longest axis + if(laxis!=lastaxis) + bvh_sort_along_axis(face_list, start, end, laxis); + + max_nodes = MIN2((end-start + 1 ),4); + + for (i = 0; i < max_nodes; i++) + { + tree->count_nodes++; + + if(end-start > 4) + { + int quarter = ((float)((float)(end - start + 1) / 4.0f)); + tstart = start + i * quarter; + tend = tstart + quarter - 1; + + // be sure that we get all faces + if(i==3) + { + tend = end; + } + } + else + { + tend = tstart = start + i; + } + + // Build tree until 4 node left. + if ((tend-tstart + 1 ) > 1) + { + newtree = (Tree *)MEM_callocN(sizeof(Tree), "Tree"); + tnlink = BLI_linklist_append_fast(&nlink1->next, newtree); + + newtree->nodes[0] = newtree->nodes[1] = newtree->nodes[2] = newtree->nodes[3] = NULL; + newtree->count_nodes = 0; + newtree->parent = tree; + newtree->isleaf = 0; + + tree->nodes[i] = newtree; + + nlink1 = tnlink; + + bvh_calc_DOP_hull_from_faces(bvh, &face_list[tstart], tend-tstart + 1, tree->nodes[i]->bv); + + bvh_div_env_node(bvh, tree->nodes[i], face_list, tstart, tend, laxis, nlink1); + } + else // ok, we have 1 left for this node + { + Tree *tnode = face_list[tstart]; + tree->nodes[i] = tnode; + tree->nodes[i]->parent = tree; + } + } + return; +} + +BVH *bvh_build (ClothModifierData *clmd, float epsilon) +{ + unsigned int i = 0, j = 0, k = 0; + Tree **face_list=NULL; + BVH *bvh=NULL; + Cloth *cloth = NULL; + Tree *tree=NULL; + LinkNode *nlink = NULL; + EdgeHash *edgehash = NULL; + ClothSpring *springs = NULL; + unsigned int numsprings = 0; + MFace *mface = NULL; + + if(!clmd) + return NULL; + + cloth = clmd->clothObject; + + if(!cloth) + return NULL; + + bvh = MEM_callocN(sizeof(BVH), "BVH"); + if (bvh == NULL) + { + printf("bvh: Out of memory.\n"); + return NULL; + } + + springs = cloth->springs; + numsprings = cloth->numsprings; + + bvh->flags = 0; + bvh->leaf_tree = NULL; + bvh->leaf_root = NULL; + + bvh->epsilon = epsilon; + bvh->numfaces = cloth->numfaces; + mface = bvh->mfaces = cloth->mfaces; + + bvh->numverts = cloth->numverts; + bvh->verts = cloth->verts; + tree = (Tree *)MEM_callocN(sizeof(Tree), "Tree"); + // TODO: check succesfull alloc + BLI_linklist_prepend(&bvh->tree, tree); + + nlink = bvh->tree; + + if (tree == NULL) + { + printf("bvh_build: Out of memory for nodes.\n"); + bvh_free(bvh); + return NULL; + } + bvh->root = bvh->tree->link; + bvh->root->isleaf = 0; + bvh->root->parent = NULL; + bvh->root->nodes[0] = bvh->root->nodes[1] = bvh->root->nodes[1] = bvh->root->nodes[3] = NULL; + + if(bvh->numfaces<=1) + { + bvh->root->tri_index = 0; // Why that? --> only one face there + bvh->root->isleaf = 1; + bvh->root->traversed = 0; + bvh->root->count_nodes = 0; + bvh->leaf_root = bvh->root; + bvh->leaf_tree = bvh->root; + bvh->root->nextLeaf = NULL; + bvh->root->prevLeaf = NULL; + } + else + { + // create spring tearing hash + /* + edgehash = BLI_edgehash_new(); + if(clmd->sim_parms.flags & CSIMSETT_FLAG_TEARING_ENABLED) + for(i = 0; i < numsprings; i++) + { + if((springs[i].flags & CSPRING_FLAG_DEACTIVATE) + &&(!BLI_edgehash_haskey(edgehash, springs[i].ij, springs[i].kl))) + { + BLI_edgehash_insert(edgehash, springs[i].ij, springs[i].kl, NULL); + BLI_edgehash_insert(edgehash, springs[i].kl, springs[i].ij, NULL); + } + } + */ + + // create face boxes + face_list = MEM_callocN (bvh->numfaces * sizeof (Tree *), "Tree"); + if (face_list == NULL) + { + printf("bvh_build: Out of memory for face_list.\n"); + bvh_free(bvh); + return NULL; + } + + // create face boxes + for(i = 0, k = 0; i < bvh->numfaces; i++) + { + LinkNode *tnlink; + /* + if((!BLI_edgehash_haskey(edgehash, mface[i].v1, mface[i].v2)) + &&(!BLI_edgehash_haskey(edgehash, mface[i].v2, mface[i].v3)) + &&(!BLI_edgehash_haskey(edgehash, mface[i].v3, mface[i].v4)) + &&(!BLI_edgehash_haskey(edgehash, mface[i].v4, mface[i].v1))) + */ + { + tree = (Tree *)MEM_callocN(sizeof(Tree), "Tree"); + // TODO: check succesfull alloc + + tnlink = BLI_linklist_append_fast(&nlink->next, tree); + + face_list[i] = tree; + tree->tri_index = i; + tree->isleaf = 1; + tree->nextLeaf = NULL; + tree->prevLeaf = bvh->leaf_tree; + tree->parent = NULL; + tree->count_nodes = 0; + + if(i==0) + { + bvh->leaf_tree = bvh->leaf_root = tree; + } + else + { + bvh->leaf_tree->nextLeaf = tree; + bvh->leaf_tree = bvh->leaf_tree->nextLeaf; + } + + tree->nodes[0] = tree->nodes[1] = tree->nodes[2] = tree->nodes[3] = NULL; + + bvh_calc_DOP_hull_static(bvh, &face_list[i], 1, tree->bv); + + // inflate the bv with some epsilon + for (j = KDOP_START; j < KDOP_END; j++) + { + tree->bv[(2 * j)] -= bvh->epsilon; // minimum + tree->bv[(2 * j) + 1] += bvh->epsilon; // maximum + } + + nlink = tnlink; + } + } + + // build root bvh + bvh_calc_DOP_hull_from_faces(bvh, face_list, bvh->numfaces, bvh->root->bv); + + // This is the traversal function. + bvh_div_env_node(bvh, bvh->root, face_list, 0, bvh->numfaces-1, 0, nlink); + if (face_list) + MEM_freeN(face_list); + + // BLI_edgehash_free(edgehash, NULL); + } + + + return bvh; +} + +// bvh_overlap - is it possbile for 2 bv's to collide ? +DO_INLINE int bvh_overlap(float *bv1, float *bv2) +{ + int i = 0; + for (i = KDOP_START; i < KDOP_END; i++) + { + // Minimum test. + if (bv1[(2 * i)] > bv2[(2 * i) + 1]) + { + return 0; + } + // Maxiumum test. + if (bv2[(2 * i)] > bv1[(2 * i) + 1]) + { + return 0; + } + } + + return 1; +} +/** + * bvh_traverse - traverse two bvh trees looking for potential collisions. + * + * max collisions are n*n collisions --> every triangle collide with + * every other triangle that doesn't require any realloc, but uses + * much memory + */ +int bvh_traverse(ClothModifierData * clmd, ClothModifierData * coll_clmd, Tree * tree1, Tree * tree2, float step, CM_COLLISION_RESPONSE collision_response) +{ + int i = 0, ret=0; + + /* + // Shouldn't be possible + if(!tree1 || !tree2) + { + printf("Error: no tree there\n"); + return 0; +} + */ + + if (bvh_overlap(tree1->bv, tree2->bv)) + { + // Check if this node in the first tree is a leaf + if (tree1->isleaf) + { + // Check if this node in the second tree a leaf + if (tree2->isleaf) + { + // Provide the collision response. + + if(collision_response) + collision_response (clmd, coll_clmd, tree1, tree2); + return 1; + } + else + { + // Process the quad tree. + for (i = 0; i < 4; i++) + { + // Only traverse nodes that exist. + if (tree2->nodes[i] && bvh_traverse (clmd, coll_clmd, tree1, tree2->nodes[i], step, collision_response)) + ret = 1; + } + } + } + else + { + // Process the quad tree. + for (i = 0; i < 4; i++) + { + // Only traverse nodes that exist. + if (tree1->nodes [i] && bvh_traverse (clmd, coll_clmd, tree1->nodes[i], tree2, step, collision_response)) + ret = 1; + } + } + } + return ret; +} + +// bottom up update of bvh tree: +// join the 4 children here +void bvh_join(Tree * tree) +{ + int i = 0, j = 0; + if (!tree) + return; + + for (i = 0; i < 4; i++) + { + if (tree->nodes[i]) + { + for (j = KDOP_START; j < KDOP_END; j++) + { + // update minimum + if ((tree->nodes[i]->bv[(2 * j)] < tree->bv[(2 * j)]) || (i == 0)) + { + tree->bv[(2 * j)] = tree->nodes[i]->bv[(2 * j)]; + } + // update maximum + if ((tree->nodes[i]->bv[(2 * j) + 1] > tree->bv[(2 * j) + 1])|| (i == 0)) + { + tree->bv[(2 * j) + 1] = tree->nodes[i]->bv[(2 * j) + 1]; + } + } + } + else + break; + } +} + +// update static bvh +void bvh_update_static(ClothModifierData * clmd, BVH * bvh) +{ + TreeNode *leaf, *parent; + int traversecheck = 1; // if this is zero we don't go further + unsigned int j = 0; + + for (leaf = bvh->leaf_root; leaf; leaf = leaf->nextLeaf) + { + traversecheck = 1; + if ((leaf->parent) && (leaf->parent->traversed == leaf->parent->count_nodes)) + { + leaf->parent->traversed = 0; + } + bvh_calc_DOP_hull_static(bvh, &leaf, 1, leaf->bv); + + // inflate the bv with some epsilon + for (j = KDOP_START; j < KDOP_END; j++) + { + leaf->bv[(2 * j)] -= bvh->epsilon; // minimum + leaf->bv[(2 * j) + 1] += bvh->epsilon; // maximum + } + + for (parent = leaf->parent; parent; parent = parent->parent) + { + if (traversecheck) + { + parent->traversed++; // we tried to go up in hierarchy + if (parent->traversed < parent->count_nodes) + { + traversecheck = 0; + + if (parent->parent) + { + if (parent->parent->traversed == parent->parent->count_nodes) + { + parent->parent->traversed = 0; + } + } + break; // we do not need to check further + } + else + { + bvh_join(parent); + } + } + + } + } +} diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c index bb5d4039336..0d7668e0ccc 100644 --- a/source/blender/blenkernel/intern/modifier.c +++ b/source/blender/blenkernel/intern/modifier.c @@ -51,6 +51,7 @@ #include "MEM_guardedalloc.h" #include "DNA_armature_types.h" +#include "DNA_cloth_types.h" #include "DNA_effect_types.h" #include "DNA_material_types.h" #include "DNA_mesh_types.h" @@ -84,6 +85,7 @@ #include "BKE_object.h" #include "BKE_mesh.h" #include "BKE_softbody.h" +#include "BKE_cloth.h" #include "BKE_material.h" #include "depsgraph_private.h" @@ -4855,6 +4857,94 @@ static void softbodyModifier_deformVerts( sbObjectStep(ob, (float)G.scene->r.cfra, vertexCos, numVerts); } + +/* Cloth */ + +static void clothModifier_initData(ModifierData *md) +{ + ClothModifierData *clmd = (ClothModifierData*) md; + cloth_init (clmd); +} + +static void clothModifier_deformVerts( + ModifierData *md, Object *ob, DerivedMesh *derivedData, + float (*vertexCos)[3], int numVerts) +{ + DerivedMesh *dm = NULL; + + // if possible use/create DerivedMesh + if(derivedData) dm = CDDM_copy(derivedData); + else if(ob->type==OB_MESH) dm = CDDM_from_mesh(ob->data, ob); + + if(dm) + { + CDDM_apply_vert_coords(dm, vertexCos); + CDDM_calc_normals(dm); + } + + clothModifier_do((ClothModifierData *)md, ob, dm, vertexCos, numVerts); + + if(dm) + dm->release(dm); +} + +static void clothModifier_updateDepgraph( + ModifierData *md, DagForest *forest, Object *ob, + DagNode *obNode) +{ + ClothModifierData *clmd = (ClothModifierData*) md; + + Base *base; + + if(clmd) + { + for(base = G.scene->base.first; base; base= base->next) + { + Object *ob1= base->object; + if(ob1 != ob) + { + ClothModifierData *coll_clmd = (ClothModifierData *)modifiers_findByType(ob1, eModifierType_Cloth); + if(coll_clmd) + { + if (coll_clmd->sim_parms.flags & CSIMSETT_FLAG_COLLOBJ) + { + DagNode *curNode = dag_get_node(forest, ob1); + dag_add_relation(forest, curNode, obNode, DAG_RL_DATA_DATA|DAG_RL_OB_DATA); + } + } + } + } + } + +} + +CustomDataMask clothModifier_requiredDataMask(ModifierData *md) +{ + ClothModifierData *clmd = (HookModifierData *)md; + CustomDataMask dataMask = 0; + + /* ask for vertexgroups if we need them */ + if(clmd->sim_parms.flags & CSIMSETT_FLAG_GOAL) + if (clmd->sim_parms.vgroup_mass > 0) + dataMask |= (1 << CD_MDEFORMVERT); + + return dataMask; +} + + +static int clothModifier_dependsOnTime(ModifierData *md) +{ + return 1; +} + +static void clothModifier_freeData(ModifierData *md) +{ + ClothModifierData *clmd = (ClothModifierData*) md; + + if (clmd) + cloth_free_modifier (clmd); +} + /* Boolean */ static void booleanModifier_copyData(ModifierData *md, ModifierData *target) @@ -5139,6 +5229,21 @@ ModifierTypeInfo *modifierType_getInfo(ModifierType type) mti->flags = eModifierTypeFlag_AcceptsCVs | eModifierTypeFlag_RequiresOriginalData; mti->deformVerts = softbodyModifier_deformVerts; + + mti = INIT_TYPE(Cloth); + mti->type = eModifierTypeType_OnlyDeform; + mti->initData = clothModifier_initData; + mti->flags = eModifierTypeFlag_AcceptsCVs; + // | eModifierTypeFlag_RequiresOriginalData; + // | eModifierTypeFlag_SupportsMapping + // | eModifierTypeFlag_SupportsEditmode + // | eModifierTypeFlag_EnableInEditmode; + mti->dependsOnTime = clothModifier_dependsOnTime; + mti->freeData = clothModifier_freeData; + mti->requiredDataMask = clothModifier_requiredDataMask; + // mti->copyData = clothModifier_copyData; + mti->deformVerts = clothModifier_deformVerts; + mti->updateDepgraph = clothModifier_updateDepgraph; mti = INIT_TYPE(Boolean); mti->type = eModifierTypeType_Nonconstructive; diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 624bfedf6cd..19f74096e54 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -60,6 +60,7 @@ #include "DNA_actuator_types.h" #include "DNA_brush_types.h" #include "DNA_camera_types.h" +#include "DNA_cloth_types.h" #include "DNA_color_types.h" #include "DNA_controller_types.h" #include "DNA_constraint_types.h" @@ -112,6 +113,7 @@ #include "BKE_action.h" #include "BKE_armature.h" +#include "BKE_cloth.h" #include "BKE_colortools.h" #include "BKE_constraint.h" #include "BKE_curve.h" @@ -2871,7 +2873,18 @@ static void direct_link_modifiers(FileData *fd, ListBase *lb) SubsurfModifierData *smd = (SubsurfModifierData*) md; smd->emCache = smd->mCache = 0; - } else if (md->type==eModifierType_Hook) { + } + else if (md->type==eModifierType_Cloth) { + ClothModifierData *clmd = (ClothModifierData*) md; + + clmd->clothObject = NULL; + /* + if (clmd->sim_parms.flags & CSIMSETT_FLAG_BAKED) { + clmd->baked_data = newdataadr (fd, clmd->baked_data); + printf ("direct_link_modifiers: read cloth baked_data.\n"); + }*/ + } + else if (md->type==eModifierType_Hook) { HookModifierData *hmd = (HookModifierData*) md; hmd->indexar= newdataadr(fd, hmd->indexar); diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c index 4f09f51bc87..4203824ae65 100644 --- a/source/blender/blenloader/intern/writefile.c +++ b/source/blender/blenloader/intern/writefile.c @@ -107,6 +107,7 @@ Important to know is that 'streaming' has been added to files, for Blender Publi #include "DNA_actuator_types.h" #include "DNA_brush_types.h" #include "DNA_camera_types.h" +#include "DNA_cloth_types.h" #include "DNA_color_types.h" #include "DNA_constraint_types.h" #include "DNA_controller_types.h" @@ -154,6 +155,7 @@ Important to know is that 'streaming' has been added to files, for Blender Publi #include "BKE_action.h" #include "BKE_bad_level_calls.h" // build_seqar (from WHILE_SEQ) free_oops error #include "BKE_blender.h" +#include "BKE_cloth.h" #include "BKE_curve.h" #include "BKE_customdata.h" #include "BKE_constraint.h" @@ -826,6 +828,20 @@ static void write_modifiers(WriteData *wd, ListBase *modbase) HookModifierData *hmd = (HookModifierData*) md; writedata(wd, DATA, sizeof(int)*hmd->totindex, hmd->indexar); + } + else if (md->type==eModifierType_Cloth) { + int n; + ClothModifierData *clmd = (ClothModifierData *) md; + /* + if ((clmd->sim_parms.flags & CSIMSETT_FLAG_BAKED) && clmd->baked_data) { + // Compute the number of vertices we're saving. + + n = (clmd->sim_parms.bake_end_frame - clmd->sim_parms.bake_start_frame + 1) * + clmd->sim_parms.bake_num_verts; + writedata (wd, DATA, n * sizeof (clmd->baked_data [0]), clmd->baked_data); + printf ("write_modifiers: wrote %d elements of size %d for cloth baked data.\n", + n, sizeof (clmd->baked_data [0])); + }*/ } } } diff --git a/source/blender/include/butspace.h b/source/blender/include/butspace.h index 4f09ad716d7..cb17f81b87d 100644 --- a/source/blender/include/butspace.h +++ b/source/blender/include/butspace.h @@ -283,6 +283,13 @@ void curvemap_buttons(struct uiBlock *block, struct CurveMapping *cumap, char la #define B_GROUP_RELINK 1460 #define B_OBJECT_IPOFLAG 1461 + +/* Cloth sim button defines */ +#define B_CLOTH_CLEARCACHEALL 1470 +#define B_CLOTH_CLEARCACHEFRAME 1471 +#define B_CLOTH_CHANGEPREROLL 1472 +#define B_CLOTH_DEL_VG 1473 + /* *********************** */ #define B_WORLDBUTS 1600 diff --git a/source/blender/makesdna/DNA_cloth_types.h b/source/blender/makesdna/DNA_cloth_types.h new file mode 100644 index 00000000000..bed04c2fa71 --- /dev/null +++ b/source/blender/makesdna/DNA_cloth_types.h @@ -0,0 +1,150 @@ +/** +* $Id: DNA_cloth_types.h,v 1.1 2007/08/01 02:28:34 daniel Exp $ +* +* ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* as published by the Free Software Foundation; either version 2 +* of the License, or (at your option) any later version. The Blender +* Foundation also sells licenses for use in proprietary software under +* the Blender License. See http://www.blender.org/BL/ for information +* about this. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software Foundation, +* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +* +* The Original Code is Copyright (C) 2006 by NaN Holding BV. +* All rights reserved. +* +* The Original Code is: all of this file. +* +* Contributor(s): Daniel (Genscher), Todd Koeckeritz (zaz) +* +* ***** END GPL/BL DUAL LICENSE BLOCK ***** +*/ +#ifndef DNA_CLOTH_TYPES_H +#define DNA_CLOTH_TYPES_H + +#include "DNA_listBase.h" + + +/** +* Pin and unpin frames are the frames on which the vertices stop moving. +* They will assume the position they had prior to pinFrame until unpinFrame +* is reached. +*/ +typedef struct ClothVertex { + int flags; /* General flags per vertex. */ + float v [3]; /* The velocity of the point. */ + float xconst [3]; /* constrained position */ + float x [3]; /* The current position of this vertice. */ + float xold [3]; /* The previous position of this vertice. */ + float tx [3]; + float txold [3]; + float tv[3]; + float mass; /* mass / weight of the vertex */ + float goal; /* goal, from SB */ +} ClothVertex; + + +/** +* The definition of a spring. +*/ +typedef struct ClothSpring { + int ij; /* Pij from the paper, one end of the spring. */ + int kl; /* Pkl from the paper, one end of the spring. */ + float restlen; /* The original length of the spring. */ + int matrix_index; /* needed for implicit */ + int type; + int flags; /* defined in BKE_cloth.h, e.g. deactivated due to tearing */ +} ClothSpring; + + + +/** +* This struct contains all the global data required to run a simulation. +* At the time of this writing, this structure contains data appropriate +* to run a simulation as described in Deformation Constraints in a +* Mass-Spring Model to Describe Rigid Cloth Behavior by Xavier Provot. +* +* I've tried to keep similar, if not exact names for the variables as +* are presented in the paper. Where I've changed the concept slightly, +* as in stepsPerFrame comapred to the time step in the paper, I've used +* variables with different names to minimize confusion. +**/ +typedef struct SimulationSettings { + short vgroup_mass; /* optional vertexgroup name for assigning weight. */ + short pad; + float mingoal; /* see SB */ + int preroll; /* How many frames of simulation to do before we start. */ + float Cdis; /* Mechanical damping of springs. */ + float Cvi; /* Viscous/fluid damping. */ + int stepsPerFrame; /* Number of time steps per frame. */ + float gravity [3]; /* Gravity/external force vector. */ + float ufluid [3]; /* Velocity vector of the fluid. */ + float dt; /* This is the duration of our time step, computed. */ + float mass; /* The mass of the entire cloth. */ + float structural; /* Structural spring stiffness. */ + float shear; /* Shear spring stiffness. */ + float bending; /* Flexion spring stiffness. */ + float sim_time; + int flags; /* flags, see CSIMSETT_FLAGS enum above. */ + short solver_type; /* which solver should be used? */ + short pad2; + float maxgoal; /* see SB */ + float eff_force_scale;/* Scaling of effector forces (see softbody_calc_forces).*/ + float eff_wind_scale; /* Scaling of effector wind (see softbody_calc_forces). */ + float sim_time_old; + struct LinkNode *cache; + float defgoal; + int goalfrict; + float goalspring; + int maxspringlen; /* in percent!; if tearing enabled, a spring will get cut */ +} SimulationSettings; + + +typedef struct CollisionSettings { + float epsilon; /* The radius of a particle in the cloth. */ + float self_friction; /* Fiction/damping with self contact. */ + float friction; /* Friction/damping applied on contact with other object.*/ + short collision_type; /* which collision system is used. */ + short loop_count; /* How many iterations for the collision loop. */ + void *temp; /* e.g. pointer to temp memory for collisions */ +} CollisionSettings; + + +/** +* This structure describes a cloth object against which the +* simulation can run. +* +* The m and n members of this structure represent the assumed +* rectangular ordered grid for which the original paper is written. +* At some point they need to disappear and we need to determine out +* own connectivity of the mesh based on the actual edges in the mesh. +* +**/ +typedef struct Cloth { + struct ClothVertex *verts; /* The vertices that represent this cloth. */ + struct ClothSpring *springs; /* The springs connecting the mesh. */ + unsigned int numverts; /* The number of verts == m * n. */ + unsigned int numsprings; /* The count of springs. */ + unsigned char *facemarks; + char old_solver_type; /* Needed to allow call to free if solver changes. */ + char old_collision_type; /* Needed to allow call to free if collision changes.*/ + short pad7; + unsigned int numfaces; + int pad2; + int pad4; + void *tree; /* collision tree for this cloth object */ + struct MFace *mfaces; + void *implicit; +} Cloth; + +#endif diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h index 71e850e4368..4c9fbdcc7b7 100644 --- a/source/blender/makesdna/DNA_modifier_types.h +++ b/source/blender/makesdna/DNA_modifier_types.h @@ -9,6 +9,8 @@ /* WARNING ALERT! TYPEDEF VALUES ARE WRITTEN IN FILES! SO DO NOT CHANGE! */ +#include "DNA_cloth_types.h" + typedef enum ModifierType { eModifierType_None = 0, eModifierType_Subsurf, @@ -28,6 +30,7 @@ typedef enum ModifierType { eModifierType_UVProject, eModifierType_Smooth, eModifierType_Cast, + eModifierType_Cloth, NUM_MODIFIER_TYPES } ModifierType; @@ -335,6 +338,14 @@ typedef struct SoftbodyModifierData { ModifierData modifier; } SoftbodyModifierData; +typedef struct ClothModifierData { + ModifierData modifier; + + Cloth *clothObject; /* The internal data structure for cloth. */ + SimulationSettings sim_parms; /* definition is in DNA_cloth_types.h */ + CollisionSettings coll_parms; /* definition is in DNA_cloth_types.h */ +} ClothModifierData; + typedef enum { eBooleanModifierOp_Intersect, eBooleanModifierOp_Union, diff --git a/source/blender/makesdna/intern/makesdna.c b/source/blender/makesdna/intern/makesdna.c index 4d437861751..d13b964622d 100644 --- a/source/blender/makesdna/intern/makesdna.c +++ b/source/blender/makesdna/intern/makesdna.c @@ -127,6 +127,7 @@ char *includefiles[] = { "DNA_color_types.h", "DNA_brush_types.h", "DNA_customdata_types.h", + "DNA_cloth_types.h", // if you add files here, please add them at the end // of makesdna.c (this file) as well @@ -1144,4 +1145,5 @@ int main(int argc, char ** argv) #include "DNA_color_types.h" #include "DNA_brush_types.h" #include "DNA_customdata_types.h" +#include "DNA_cloth_types.h" /* end of list */ diff --git a/source/blender/src/buttons_object.c b/source/blender/src/buttons_object.c index a998c568619..de1d8f8c0ac 100644 --- a/source/blender/src/buttons_object.c +++ b/source/blender/src/buttons_object.c @@ -86,6 +86,7 @@ #include "DNA_action_types.h" #include "DNA_armature_types.h" #include "DNA_camera_types.h" +#include "DNA_cloth_types.h" #include "DNA_constraint_types.h" #include "DNA_curve_types.h" #include "DNA_effect_types.h" @@ -113,6 +114,7 @@ #include "BKE_anim.h" #include "BKE_armature.h" +#include "BKE_cloth.h" #include "BKE_constraint.h" #include "BKE_curve.h" #include "BKE_deform.h" @@ -844,7 +846,7 @@ static void draw_constraint (uiBlock *block, ListBase *list, bConstraint *con, s /* Draw target parameters */ uiBlockBeginAlign(block); uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_CONSTRAINT_CHANGETARGET, "OB:", *xco+120, *yco-24, 135, 18, &data->tar, "Target Object"); - + if (is_armature_target) { but= uiDefBut(block, TEX, B_CONSTRAINT_CHANGETARGET, "BO:", *xco+120, *yco-42,135,18, &data->subtarget, 0, 24, 0, 0, "Subtarget Bone"); uiButSetCompleteFunc(but, autocomplete_bone, (void *)data->tar); @@ -900,7 +902,7 @@ static void draw_constraint (uiBlock *block, ListBase *list, bConstraint *con, s } uiBlockEndAlign(block); - + /* Draw XYZ toggles */ uiBlockBeginAlign(block); but=uiDefButBitI(block, TOG, SIZELIKE_X, B_CONSTRAINT_TEST, "X", *xco+((width/2)-48), *yco-64, 32, 18, &data->flag, 0, 24, 0, 0, "Copy X component"); @@ -920,7 +922,7 @@ static void draw_constraint (uiBlock *block, ListBase *list, bConstraint *con, s uiDefBut(block, ROUNDBOX, B_DIFF, "", *xco-10, *yco-height, width+40,height-1, NULL, 5.0, 0.0, 12, rb_col, ""); uiDefBut(block, LABEL, B_CONSTRAINT_TEST, "Target:", *xco+65, *yco-24, 50, 18, NULL, 0.0, 0.0, 0.0, 0.0, ""); - + /* Draw target parameters */ uiDefButBitS(block, TOG, CONSTRAINT_IK_ROT, B_CONSTRAINT_TEST, "Rot", *xco, *yco-24,60,19, &data->flag, 0, 0, 0, 0, "Chain follows rotation of target"); @@ -2144,8 +2146,61 @@ void do_object_panels(unsigned short event) case B_OBJECT_IPOFLAG: if(ob->ipo) ob->ipo->showkey= (ob->ipoflag & OB_DRAWKEY)?1:0; allqueue(REDRAWVIEW3D, 0); + case B_CLOTH_CLEARCACHEALL: + { + ClothModifierData *clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth); + if(clmd) + { + CFRA= 1; + update_for_newframe_muted(); + DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA); + clmd->sim_parms.flags |= CSIMSETT_FLAG_CCACHE_FREE_PART; + cloth_cache_free(clmd, 1); + allqueue(REDRAWBUTSOBJECT, 0); + allqueue(REDRAWVIEW3D, 0); + } + } + break; + case B_CLOTH_CLEARCACHEFRAME: + { + ClothModifierData *clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth); + if(clmd) + { + clmd->sim_parms.flags |= CSIMSETT_FLAG_CCACHE_FREE_PART; + cloth_cache_free(clmd, G.scene->r.cfra); + DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA); + allqueue(REDRAWBUTSOBJECT, 0); + allqueue(REDRAWVIEW3D, 0); + } + } + break; + case B_CLOTH_CHANGEPREROLL: + { + ClothModifierData *clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth); + if(clmd) + { + if(clmd->sim_parms.cache) + { + CFRA= 1; + update_for_newframe_muted(); + DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA); + allqueue(REDRAWBUTSOBJECT, 0); + allqueue(REDRAWVIEW3D, 0); + } + } + } break; - + case B_CLOTH_DEL_VG: + { + ClothModifierData *clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth); + if(clmd) + { + clmd->sim_parms.vgroup_mass = 0; + } + + allqueue(REDRAWBUTSOBJECT, 0); + } + break; default: if(event>=B_SELEFFECT && eventmodifiers, md); + } + else { + BLI_remlink(&ob->modifiers, md); + modifier_free(md); + } + + allqueue(REDRAWBUTSEDIT, 0); +} + +static void object_panel_cloth(Object *ob) +{ + uiBlock *block; + static int val, val2; + uiBut *but; + ClothModifierData *clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth); + block= uiNewBlock(&curarea->uiblocks, "object_panel_cloth", UI_EMBOSS, UI_HELV, curarea->win); + if(uiNewPanel(curarea, block, "Cloth", "Physics", 640, 0, 318, 204)==0) return; + + if(ob->id.lib) uiSetButLock(1, "Can't edit library data"); + val = ((clmd)?(1):(0)); + + but = uiDefButI(block, TOG, REDRAWBUTSOBJECT, "Cloth Object", 10,200,130,20, &val, 0, 0, 0, 0, "Sets object to become cloth"); + uiButSetFunc(but, object_cloth__enabletoggle, ob, NULL); + uiDefBut(block, LABEL, 0, "",10,10,300,0, NULL, 0.0, 0, 0, 0, ""); /* tell UI we go to 10,10*/ + + if(clmd) + { + but = uiDefButBitI(block, TOG, CSIMSETT_FLAG_COLLOBJ, B_EFFECT_DEP, "Collision Object", 170,200,130,20, &clmd->sim_parms.flags, 0, 0, 0, 0, "Sets object to become a cloth collision object"); + // uiButSetFunc(but, object_cloth__enabletoggle, ob, NULL); + + if (!(clmd->sim_parms.flags & CSIMSETT_FLAG_COLLOBJ)) + { + Cloth *cloth = clmd->clothObject; + int defCount; + char *clvg1, *clvg2; + char clmvg [] = "Mass Vertex Group%t|None%x0|"; + + val2=0; + + // uiDefButBitI(block, TOG, CSIMSETT_FLAG_ADVANCED, REDRAWBUTSOBJECT, "Advanced", 180,200,130,20, &clmd->sim_parms.flags, 0, 0, 0, 0, "Enable advanced mode"); + + /* GENERAL STUFF */ + uiClearButLock(); + uiBlockBeginAlign(block); + uiDefButF(block, NUM, B_DIFF, "StructStiff:", 10,170,150,20, &clmd->sim_parms.structural, 1.0, 5000.0, 100, 0, "Overall stiffness of structure"); + uiDefButF(block, NUM, B_DIFF, "BendStiff:", 160,170,150,20, &clmd->sim_parms.bending, 0.0, 1000.0, 1000, 0, "Wrinkle possibility"); + uiDefButI(block, NUM, B_DIFF, "Steps per Frame:", 10,150,150,20, &clmd->sim_parms.stepsPerFrame, 1.0, 100.0, 5, 0, "Quality of the simulation (higher=better=slower)"); + uiBlockEndAlign(block); + uiBlockBeginAlign(block); + uiDefButF(block, NUM, B_DIFF, "Spring Damp:", 160,150,150,20, &clmd->sim_parms.Cdis, 0.0, 10.0, 10, 0, "Apply gravitation to point movement"); + uiDefButF(block, NUM, B_DIFF, "Air Damp:", 10,130,150,20, &clmd->sim_parms.Cvi, 0.0, 10.0, 10, 0, "Apply gravitation to point movement"); + uiBlockEndAlign(block); + + uiClearButLock(); + + uiBlockBeginAlign(block); + uiDefBut(block, LABEL, 0, "Gravity:", 10,100,60,20, NULL, 0.0, 0, 0, 0, ""); + // uiClearButLock(); + + uiDefButF(block, NUM, B_DIFF, "X:", 70,100,80,20, &clmd->sim_parms.gravity[0], -100.0, 100.0, 10, 0, "Apply gravitation to point movement"); + uiDefButF(block, NUM, B_DIFF, "Y:", 150,100,80,20, &clmd->sim_parms.gravity[1], -100.0, 100.0, 10, 0, "Apply gravitation to point movement"); + uiDefButF(block, NUM, B_DIFF, "Z:", 230,100,80,20, &clmd->sim_parms.gravity[2], -100.0, 100.0, 10, 0, "Apply gravitation to point movement"); + uiBlockEndAlign(block); + + /* GOAL STUFF */ + uiBlockBeginAlign(block); + uiDefButBitI(block, TOG, CSIMSETT_FLAG_GOAL, REDRAWVIEW3D, "Use Goal", 10,70,130,20, &clmd->sim_parms.flags, 0, 0, 0, 0, "Define forces for vertices to stick to animated position"); + if (clmd->sim_parms.flags & CSIMSETT_FLAG_GOAL) + { + if(ob->type==OB_MESH) + { + + defCount = sizeof (clmvg); + clvg1 = get_vertexgroup_menustr (ob); + clvg2 = MEM_callocN (strlen (clvg1) + 1 + defCount, "clothVgMS"); + if (! clvg2) { + printf ("draw_modifier: error allocating memory for cloth vertex group menu string.\n"); + return; + } + defCount = BLI_countlist (&ob->defbase); + if (defCount == 0) + { + clmd->sim_parms.vgroup_mass = 0; + } + sprintf (clvg2, "%s%s", clmvg, clvg1); + + uiDefButS(block, MENU, REDRAWVIEW3D, clvg2, 140,70,20,20, &clmd->sim_parms.vgroup_mass, 0, defCount, 0, 0, "Browses available vertex groups"); + MEM_freeN (clvg1); + MEM_freeN (clvg2); + + if(clmd->sim_parms.vgroup_mass) + { + bDeformGroup *defGroup = BLI_findlink(&ob->defbase, clmd->sim_parms.vgroup_mass-1); + if(defGroup) + uiDefBut(block, BUT, B_DIFF, defGroup->name, 160,70,130,20, NULL, 0.0, 0.0, 0, 0, "Name of current vertex group"); + else + uiDefBut(block, BUT, B_DIFF, "(no group)", 160,70,130,20, NULL, 0.0, 0.0, 0, 0, "Vertex Group doesn't exist anymore"); + + uiDefIconBut(block, BUT, B_CLOTH_DEL_VG, ICON_X, 290,70,20,20, 0, 0, 0, 0, 0, "Disable use of vertex group"); + + } + else + uiDefButF(block, NUM, REDRAWVIEW3D, "Goal:", 160,70,150,20, &clmd->sim_parms.defgoal, 0.0, 1.0, 10, 0, "Default Goal (vertex target position) value, when no Vertex Group used"); + + } + else + { + uiDefButS(block, TOG, REDRAWVIEW3D, "W", 140,70,20,20, &clmd->sim_parms.vgroup_mass, 0, 1, 0, 0, "Use control point weight values"); + uiDefButF(block, NUM, REDRAWVIEW3D, "Goal:", 160,70,150,20, &clmd->sim_parms.defgoal, 0.0, 1.0, 10, 0, "Default Goal (vertex target position) value, when no Vertex Group used"); + } + + uiDefButF(block, NUM, B_DIFF, "G Stiff:", 10,50,150,20, &clmd->sim_parms.goalspring, 0.0, 500.0, 10, 0, "Goal (vertex target position) spring stiffness"); + uiDefButF(block, NUM, B_DIFF, "G Damp:", 160,50,150,20, &clmd->sim_parms.goalfrict , 0.0, 50.0, 10, 0, "Goal (vertex target position) friction"); + uiDefButF(block, NUM, REDRAWVIEW3D, "G Min:", 10,30,150,20, &clmd->sim_parms.mingoal, 0.0, 1.0, 10, 0, "Goal minimum, vertex group weights are scaled to match this range"); + uiDefButF(block, NUM, REDRAWVIEW3D, "G Max:", 160,30,150,20, &clmd->sim_parms.maxgoal, 0.0, 1.0, 10, 0, "Goal maximum, vertex group weights are scaled to match this range"); + } + uiBlockEndAlign(block); + + /* + // no tearing supported anymore since modifier stack restrictions + uiBlockBeginAlign(block); + uiDefButBitI(block, TOG, CSIMSETT_FLAG_TEARING_ENABLED, B_EFFECT_DEP, "Tearing", 10,0,150,20, &clmd->sim_parms.flags, 0, 0, 0, 0, "Sets object to become a cloth collision object"); + + if (clmd->sim_parms.flags & CSIMSETT_FLAG_TEARING_ENABLED) + { + uiDefButI(block, NUM, B_DIFF, "Max extent:", 160,0,150,20, &clmd->sim_parms.maxspringlen, 1.0, 1000.0, 10, 0, "Maximum extension before spring gets cut"); + } + + uiBlockEndAlign(block); + */ + } + } +} + + +static void object_panel_cloth_II(Object *ob) +{ + uiBlock *block; + static int val; + uiBut *but; + ClothModifierData *clmd = NULL; + + clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth); + if(clmd) + { + if (!(clmd->sim_parms.flags & CSIMSETT_FLAG_COLLOBJ)) + { + Cloth *cloth = clmd->clothObject; + char str[128]; + + block= uiNewBlock(&curarea->uiblocks, "object_panel_cloth_II", UI_EMBOSS, UI_HELV, curarea->win); + uiNewPanelTabbed("Cloth", "Physics"); + if(uiNewPanel(curarea, block, "Cloth Cache", "Physics", 651, 0, 318, 204)==0) return; + + uiSetButLock(object_data_is_libdata(ob), ERROR_LIBDATA_MESSAGE); + + if(clmd->sim_parms.cache) + { + int length = BLI_linklist_length(clmd->sim_parms.cache); + + /* correct spelling if only 1 frame cacheed --> only gimmick */ + if(length-clmd->sim_parms.preroll>1) + sprintf (str, "Frame 1 - %d cached. [%d in preroll, %d in total]", length-clmd->sim_parms.preroll, clmd->sim_parms.preroll, length); + else + sprintf (str, "Frame %d cached. [%d in preroll, %d in total]", length-clmd->sim_parms.preroll, clmd->sim_parms.preroll, length); + + uiDefBut(block, LABEL, 0, str, 10,160,290,20, NULL, 0.0, 0, 0, 0, ""); + uiDefBut(block, LABEL, 0, "Clear cache:", 10,140,290,20, NULL, 0.0, 0, 0, 0, ""); + uiBlockBeginAlign (block); + uiDefBut(block, BUT, B_CLOTH_CLEARCACHEALL, "All", 10, 120,145,20, NULL, 0.0, 0.0, 0, 0, "Free cloth cache without preroll"); + uiDefBut(block, BUT, B_CLOTH_CLEARCACHEFRAME, "From next frame", 155, 120,145,20, NULL, 0.0, 0.0, 0, 0, "Free cloth cache"); + if(length>1) // B_CLOTH_CHANGEPREROLL + uiDefButI(block, NUM, B_CLOTH_CHANGEPREROLL, "Preroll:", 10,100,145,20, &clmd->sim_parms.preroll, 0, length-1, 1, 0, "Simulation starts on this frame"); + } + else + { + uiDefBut(block, LABEL, 0, "No frames cached.", 10,140,290,20, NULL, 0.0, 0, 0, 0, ""); + } + uiBlockEndAlign(block); + } + } + // uiBlockEndAlign(block); +} + +static void object_panel_cloth_III(Object *ob) +{ + uiBlock *block; + static int val; + uiBut *but; + ClothModifierData *clmd = NULL; + + clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth); + if(clmd) + { + if (!(clmd->sim_parms.flags & CSIMSETT_FLAG_COLLOBJ)) + { + Cloth *cloth = clmd->clothObject; + char str[128]; + + block= uiNewBlock(&curarea->uiblocks, "object_panel_cloth_III", UI_EMBOSS, UI_HELV, curarea->win); + uiNewPanelTabbed("Cloth", "Physics"); + if(uiNewPanel(curarea, block, "Cloth Collisions", "Physics", 651, 0, 318, 204)==0) return; + + uiSetButLock(object_data_is_libdata(ob), ERROR_LIBDATA_MESSAGE); + + uiBlockBeginAlign(block); + // uiDefBut(block, LABEL, 0, "",10,10,300,20, NULL, 0.0, 0, 0, 0, ""); /* tell UI we go to 10,10*/ + uiDefButF(block, NUM, B_DIFF, "Min Distance:", 10,10,150,20, &clmd->coll_parms.epsilon, 0.001f, 1.0, 0.01f, 0, "Minimum distance between collision objects before collision response takes in"); + uiDefBut(block, LABEL, 0, "",160,10,150,20, NULL, 0.0, 0, 0, 0, ""); + uiBlockEndAlign(block); + } + } + // uiBlockEndAlign(block); +} + + static void object_panel_particles_motion(Object *ob) { uiBlock *block; @@ -3503,6 +3783,9 @@ void physics_panels() object_panel_particles_motion(ob); object_softbodies(ob); object_softbodies_II(ob); + object_panel_cloth(ob); + object_panel_cloth_II(ob); + object_panel_cloth_III(ob); object_panel_fluidsim(ob); } } From 9d0420c1acd983cc0ae6ab2f61d63d31956d081c Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Sun, 16 Sep 2007 16:33:42 +0000 Subject: [PATCH 002/246] Little project: Getting fluidsim multithreaded. Can be actuvated by adding "PARALLEL" to compiler flags in elbeem folder. ----- Code already works for MAX_THREADS=1 so there seems to be some bug in openMP code in paraloopstart.h Help appeciated :) --- intern/elbeem/intern/paraloop.h | 51 ++++++++++++++++++++++++++++ intern/elbeem/intern/paraloopend.h | 14 ++++++++ intern/elbeem/intern/paraloopstart.h | 3 ++ 3 files changed, 68 insertions(+) create mode 100644 intern/elbeem/intern/paraloop.h create mode 100644 intern/elbeem/intern/paraloopend.h create mode 100644 intern/elbeem/intern/paraloopstart.h diff --git a/intern/elbeem/intern/paraloop.h b/intern/elbeem/intern/paraloop.h new file mode 100644 index 00000000000..e8bef648a8d --- /dev/null +++ b/intern/elbeem/intern/paraloop.h @@ -0,0 +1,51 @@ + +#define PERFORM_USQRMAXCHECK \ +_Pragma("omp critical") {\ +USQRMAXCHECK(usqr,ux,uy,uz, mMaxVlen, mMxvx,mMxvy,mMxvz); \ +} \ + + +#define LIST_EMPTY(x) \ +_Pragma("omp critical") {\ +mListEmpty.push_back( x ); } + +#define LIST_FULL(x) \ +_Pragma("omp critical") {\ +mListFull.push_back( x ); } + +#define FSGR_ADDPART(x) \ +_Pragma("omp critical") { \ +mpParticles->addFullParticle( x ); } \ + + +#define MAX_THREADS 2 + +#define GRID_REGION_START() \ +{ /* main_region */ \ + int kstart=getForZMinBnd(), kend=getForZMaxBnd(mMaxRefine); \ + if(gridLoopBound>0){ kstart=getForZMin1(), kend=getForZMax1(mMaxRefine); } \ + int kdir = 1; \ + const int id=omp_get_thread_num(); \ + int jstart = (id*((mLevel[mMaxRefine].lSizey-gridLoopBound) / MAX_THREADS))+gridLoopBound; \ + int jend = (id+1)*((mLevel[mMaxRefine].lSizey-gridLoopBound)/ MAX_THREADS); \ + if(id+1 == MAX_THREADS) \ + { \ + jend = mLevel[mMaxRefine].lSizey-gridLoopBound; \ + } \ + if(jstart<1) jstart = 1; \ + LbmFloat *ccel = NULL, *tcel = NULL; \ + CellFlagType *pFlagSrc=NULL, *pFlagDst=NULL; \ + if(mLevel[mMaxRefine].setCurr==1) { \ + kdir = -1; \ + int temp = kend; \ + kend = kstart-1; \ + kstart = temp-1; \ + temp = id; /* dummy remove warning */ \ +} \ + + + +#define unused_GRID_REGION_END() \ +} /* main_region */ \ + // end unusedGRID_REGION_END + diff --git a/intern/elbeem/intern/paraloopend.h b/intern/elbeem/intern/paraloopend.h new file mode 100644 index 00000000000..6ea636e8d23 --- /dev/null +++ b/intern/elbeem/intern/paraloopend.h @@ -0,0 +1,14 @@ +// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +} /* i */ + int i=0; + ADVANCE_POINTERS(2*gridLoopBound); +} /* j */ + /* COMPRESSGRIDS!=1 */ +#pragma omp barrier + + /* int i=0; */ + /* ADVANCE_POINTERS(mLevel[lev].lSizex*2); */ +} /* all cell loop k,j,i */ + if(doReduce) { } /* dummy remove warning */ +} /* main_region */ + diff --git a/intern/elbeem/intern/paraloopstart.h b/intern/elbeem/intern/paraloopstart.h new file mode 100644 index 00000000000..9f13eb3207b --- /dev/null +++ b/intern/elbeem/intern/paraloopstart.h @@ -0,0 +1,3 @@ + +#pragma omp parallel section num_threads(MAX_THREADS) \ +reduction(+: calcCurrentMass, calcCurrentVolume, calcCellsFilled, calcCellsEmptied, calcNumUsedCells) From 1138bd30145c0d961266a150d86d59f9c38418d1 Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Sun, 16 Sep 2007 23:19:02 +0000 Subject: [PATCH 003/246] New: Min & MaxFrame of simulation; Fixed: Many reset problems gone --- source/blender/blenkernel/BKE_cloth.h | 1 + source/blender/blenkernel/BKE_modifier.h | 1 + source/blender/blenkernel/intern/cloth.c | 36 ++++++++----- source/blender/blenkernel/intern/implicit.c | 24 +++++++-- source/blender/blenkernel/intern/modifier.c | 11 +++- source/blender/include/butspace.h | 1 + source/blender/makesdna/DNA_cloth_types.h | 6 ++- source/blender/src/buttons_editing.c | 12 ++++- source/blender/src/buttons_object.c | 58 +++++++++++++-------- source/blender/src/editmesh.c | 8 ++- source/blender/src/editobject.c | 4 ++ source/blender/src/transform_conversions.c | 9 ++-- source/blender/src/transform_generics.c | 24 +++++++-- source/blender/src/vpaint.c | 6 +++ 14 files changed, 147 insertions(+), 54 deletions(-) diff --git a/source/blender/blenkernel/BKE_cloth.h b/source/blender/blenkernel/BKE_cloth.h index e843079f412..0a50feeb9b0 100644 --- a/source/blender/blenkernel/BKE_cloth.h +++ b/source/blender/blenkernel/BKE_cloth.h @@ -107,6 +107,7 @@ typedef enum // needed for buttons_object.c void cloth_cache_free(ClothModifierData *clmd, float time); +void cloth_free_modifier (ClothModifierData *clmd); // needed for cloth.c void implicit_set_positions (ClothModifierData *clmd); diff --git a/source/blender/blenkernel/BKE_modifier.h b/source/blender/blenkernel/BKE_modifier.h index 297443b883d..365381f5cdd 100644 --- a/source/blender/blenkernel/BKE_modifier.h +++ b/source/blender/blenkernel/BKE_modifier.h @@ -277,6 +277,7 @@ int modifiers_getCageIndex(struct Object *ob, int *lastPossibleCageIndex_r); int modifiers_isSoftbodyEnabled(struct Object *ob); +struct ModifierData *modifiers_isClothEnabled(struct Object *ob); struct Object *modifiers_isDeformedByArmature(struct Object *ob); struct Object *modifiers_isDeformedByLattice(struct Object *ob); int modifiers_usesArmature(struct Object *ob, struct bArmature *arm); diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c index 4b4aa2d0d1d..18e1d4a6cde 100644 --- a/source/blender/blenkernel/intern/cloth.c +++ b/source/blender/blenkernel/intern/cloth.c @@ -119,6 +119,8 @@ static CM_SOLVER_DEF solvers [] = { #define DEBUG_CLOTH_VERBOSE 1000 static int DEBUG_CLOTH = 0; + + /* ********** cloth engine ******* */ /* Prototypes for internal functions. */ @@ -128,6 +130,8 @@ static int cloth_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *d static int collobj_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *dm, float (*vertexCos)[3], unsigned int numverts); int cloth_build_springs(Cloth *cloth, DerivedMesh *dm); static void cloth_apply_vgroup(ClothModifierData *clmd, DerivedMesh *dm, short vgroup); + + /****************************************************************************** * * External interface called by modifier.c clothModifier functions. @@ -157,6 +161,8 @@ void cloth_init (ClothModifierData *clmd) clmd->sim_parms.solver_type = 0; clmd->sim_parms.preroll = 0; clmd->sim_parms.maxspringlen = 10; + clmd->sim_parms.firstframe = 1; + clmd->sim_parms.lastframe = 250; clmd->coll_parms.self_friction = 5.0; clmd->coll_parms.friction = 10.0; clmd->coll_parms.loop_count = 1; @@ -614,8 +620,13 @@ void clothModifier_do(ClothModifierData *clmd, Object *ob, DerivedMesh *dm, Frame *frame = NULL; LinkNode *search = NULL; float deltaTime = current_time - clmd->sim_parms.sim_time; - - clmd->sim_parms.dt = 1.0f / (clmd->sim_parms.stepsPerFrame * G.scene->r.frs_sec); + + // only be active during a specific period + if((current_time < clmd->sim_parms.firstframe)||(current_time > clmd->sim_parms.lastframe)) + return; + + // unused in the moment + clmd->sim_parms.dt = 1.0f / clmd->sim_parms.stepsPerFrame; clmd->sim_parms.sim_time = current_time; @@ -707,7 +718,6 @@ void clothModifier_do(ClothModifierData *clmd, Object *ob, DerivedMesh *dm, tstart(); /* Call the solver. */ - if (solvers [clmd->sim_parms.solver_type].solver) solvers [clmd->sim_parms.solver_type].solver (ob, framenr, clmd, effectors,0,0); @@ -754,9 +764,6 @@ void cloth_free_modifier (ClothModifierData *clmd) clmd->sim_parms.flags |= CSIMSETT_FLAG_CCACHE_FREE_ALL; cloth_cache_free(clmd, 0); - /* Calls the solver and collision frees first as they - * might depend on data in clmd->clothObject. */ - if (cloth) { // If our solver provides a free function, call it @@ -793,11 +800,9 @@ void cloth_free_modifier (ClothModifierData *clmd) MEM_freeN (cloth); clmd->clothObject = NULL; } - } - /****************************************************************************** * * Internal functions. @@ -826,8 +831,6 @@ static void cloth_to_object (Object *ob, ClothModifierData *clmd, float (*vertex Mat4MulVecfl (ob->imat, vertexCos[i]); /* softbody is in global coords */ } } - else if (DEBUG_CLOTH) - printf ("cloth_to_object: clmd->clothObject was NULL.\n"); } @@ -837,15 +840,20 @@ static void cloth_to_object (Object *ob, ClothModifierData *clmd, float (*vertex **/ static void cloth_apply_vgroup(ClothModifierData *clmd, DerivedMesh *dm, short vgroup) { - unsigned int i; - int j; - MDeformVert *dvert = NULL; - Cloth *clothObj; + unsigned int i = 0; + unsigned int j = 0; + MDeformVert *dvert = NULL; + Cloth *clothObj = NULL; unsigned int numverts = dm->getNumVerts(dm); float goalfac = 0; ClothVertex *verts = NULL; clothObj = clmd->clothObject; + + if(!dm) + return; + + numverts = dm->getNumVerts(dm); /* vgroup is 1 based, decrement so we can match the right group. */ --vgroup; diff --git a/source/blender/blenkernel/intern/implicit.c b/source/blender/blenkernel/intern/implicit.c index 5d386036b7b..c756c220fe6 100644 --- a/source/blender/blenkernel/intern/implicit.c +++ b/source/blender/blenkernel/intern/implicit.c @@ -689,14 +689,15 @@ typedef struct Implicit_Data lfVector *X, *V, *Xnew, *Vnew, *olddV, *F, *B, *dV, *z; fmatrix3x3 *A, *dFdV, *dFdX, *S, *P, *Pinv, *bigI; } Implicit_Data; + int implicit_init (Object *ob, ClothModifierData *clmd) { unsigned int i = 0; unsigned int pinned = 0; - Cloth *cloth; - ClothVertex *verts; - ClothSpring *springs; - Implicit_Data *id; + Cloth *cloth = NULL; + ClothVertex *verts = NULL; + ClothSpring *springs = NULL; + Implicit_Data *id = NULL; // init memory guard // MEMORY_BASE.first = MEMORY_BASE.last = NULL; @@ -727,6 +728,7 @@ int implicit_init (Object *ob, ClothModifierData *clmd) id->B = create_lfvector(cloth->numverts); id->dV = create_lfvector(cloth->numverts); id->z = create_lfvector(cloth->numverts); + for(i=0;inumverts;i++) { id->A[i].r = id->A[i].c = id->dFdV[i].r = id->dFdV[i].c = id->dFdX[i].r = id->dFdX[i].c = id->P[i].c = id->P[i].r = id->Pinv[i].c = id->Pinv[i].r = id->bigI[i].c = id->bigI[i].r = i; @@ -1503,9 +1505,23 @@ void implicit_set_positions (ClothModifierData *clmd) ClothVertex *verts = cloth->verts; unsigned int numverts = cloth->numverts, i; Implicit_Data *id = cloth->implicit; + unsigned int pinned = 0; + + // reset pinned verts in S matrix to zero + // id->S[0].vcount = 0; id->S[0].scount = 0; + for(i = 0; i < numverts; i++) { VECCOPY(id->X[i], verts[i].x); VECCOPY(id->V[i], verts[i].v); + /* + if(verts [i].flags & CVERT_FLAG_PINNED) + { + id->S[pinned].pinned = 1; + id->S[pinned].c = id->S[pinned].r = i; + pinned++; + } + */ } + // id->S[0].vcount = pinned; } diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c index 0d7668e0ccc..d3d41e70d57 100644 --- a/source/blender/blenkernel/intern/modifier.c +++ b/source/blender/blenkernel/intern/modifier.c @@ -5233,8 +5233,8 @@ ModifierTypeInfo *modifierType_getInfo(ModifierType type) mti = INIT_TYPE(Cloth); mti->type = eModifierTypeType_OnlyDeform; mti->initData = clothModifier_initData; - mti->flags = eModifierTypeFlag_AcceptsCVs; - // | eModifierTypeFlag_RequiresOriginalData; + mti->flags = eModifierTypeFlag_AcceptsCVs + | eModifierTypeFlag_RequiresOriginalData; // | eModifierTypeFlag_SupportsMapping // | eModifierTypeFlag_SupportsEditmode // | eModifierTypeFlag_EnableInEditmode; @@ -5446,6 +5446,13 @@ int modifiers_isSoftbodyEnabled(Object *ob) return (md && md->mode & (eModifierMode_Realtime | eModifierMode_Render)); } +ModifierData * modifiers_isClothEnabled(Object *ob) +{ + ModifierData *md = modifiers_findByType(ob, eModifierType_Cloth); + + return md; +} + LinkNode *modifiers_calcDataMasks(ModifierData *md, CustomDataMask dataMask) { LinkNode *dataMasks = NULL; diff --git a/source/blender/include/butspace.h b/source/blender/include/butspace.h index cb17f81b87d..b017dd950e2 100644 --- a/source/blender/include/butspace.h +++ b/source/blender/include/butspace.h @@ -289,6 +289,7 @@ void curvemap_buttons(struct uiBlock *block, struct CurveMapping *cumap, char la #define B_CLOTH_CLEARCACHEFRAME 1471 #define B_CLOTH_CHANGEPREROLL 1472 #define B_CLOTH_DEL_VG 1473 +#define B_CLOTH_RENEW 1474 /* *********************** */ #define B_WORLDBUTS 1600 diff --git a/source/blender/makesdna/DNA_cloth_types.h b/source/blender/makesdna/DNA_cloth_types.h index bed04c2fa71..c756c29f467 100644 --- a/source/blender/makesdna/DNA_cloth_types.h +++ b/source/blender/makesdna/DNA_cloth_types.h @@ -106,7 +106,9 @@ typedef struct SimulationSettings { float defgoal; int goalfrict; float goalspring; - int maxspringlen; /* in percent!; if tearing enabled, a spring will get cut */ + int maxspringlen; /* in percent!; if tearing enabled, a spring will get cut */ + int lastframe; /* frame on which simulation stops */ + int firstframe; /* frame on which simulation starts */ } SimulationSettings; @@ -144,7 +146,7 @@ typedef struct Cloth { int pad4; void *tree; /* collision tree for this cloth object */ struct MFace *mfaces; - void *implicit; + void *implicit; /* our implicit solver connects to this pointer */ } Cloth; #endif diff --git a/source/blender/src/buttons_editing.c b/source/blender/src/buttons_editing.c index ea90f6fdc16..2ab5397f493 100644 --- a/source/blender/src/buttons_editing.c +++ b/source/blender/src/buttons_editing.c @@ -949,7 +949,7 @@ static uiBlock *modifiers_add_menu(void *ob_v) ModifierTypeInfo *mti = modifierType_getInfo(i); /* Only allow adding through appropriate other interfaces */ - if(ELEM(i, eModifierType_Softbody, eModifierType_Hook)) continue; + if(ELEM3(i, eModifierType_Softbody, eModifierType_Hook, eModifierType_Cloth)) continue; if((mti->flags&eModifierTypeFlag_AcceptsCVs) || (ob->type==OB_MESH && (mti->flags&eModifierTypeFlag_AcceptsMesh))) { @@ -1600,6 +1600,8 @@ static void draw_modifier(uiBlock *block, Object *ob, ModifierData *md, int *xco height += 20; } else if (md->type==eModifierType_Softbody) { height = 26; + } else if (md->type==eModifierType_Cloth) { + height = 26; } else if (md->type==eModifierType_Boolean) { height = 48; } else if (md->type==eModifierType_Array) { @@ -1615,7 +1617,7 @@ static void draw_modifier(uiBlock *block, Object *ob, ModifierData *md, int *xco uiBlockBeginAlign(block); but = uiDefBut(block, BUT, B_MODIFIER_RECALC, "Apply", lx,(cy-=19),60,19, 0, 0, 0, 0, 0, "Apply the current modifier and remove from the stack"); uiButSetFunc(but, modifiers_applyModifier, ob, md); - if (md->type!=eModifierType_Softbody) { + if ((md->type!=eModifierType_Softbody) && (md->type!=eModifierType_Cloth)) { but = uiDefBut(block, BUT, B_MODIFIER_RECALC, "Copy", lx,(cy-=19),60,19, 0, 0, 0, 0, 0, "Duplicate the current modifier at the same position in the stack"); uiButSetFunc(but, modifiers_copyModifier, ob, md); } @@ -3308,6 +3310,9 @@ void do_latticebuts(unsigned short event) if(ob==G.obedit) resizelattice(editLatt, lt->opntsu, lt->opntsv, lt->opntsw, NULL); else resizelattice(ob->data, lt->opntsu, lt->opntsv, lt->opntsw, NULL); ob->softflag |= OB_SB_REDO; + if(modifiers_isClothEnabled(ob)) { + cloth_free_modifier(modifiers_isClothEnabled(ob)); + } DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA); allqueue(REDRAWVIEW3D, 0); } @@ -3316,6 +3321,9 @@ void do_latticebuts(unsigned short event) lt = ob->data; resizelattice(ob->data, lt->opntsu, lt->opntsv, lt->opntsw, ob); ob->softflag |= OB_SB_REDO; + if(modifiers_isClothEnabled(ob)) { + cloth_free_modifier(modifiers_isClothEnabled(ob)); + } DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA); allqueue(REDRAWVIEW3D, 0); } diff --git a/source/blender/src/buttons_object.c b/source/blender/src/buttons_object.c index de1d8f8c0ac..df6d88bddd0 100644 --- a/source/blender/src/buttons_object.c +++ b/source/blender/src/buttons_object.c @@ -2196,11 +2196,22 @@ void do_object_panels(unsigned short event) if(clmd) { clmd->sim_parms.vgroup_mass = 0; + do_object_panels(B_CLOTH_RENEW); } allqueue(REDRAWBUTSOBJECT, 0); } break; + case B_CLOTH_RENEW: + { + ClothModifierData *clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth); + if(clmd) + { + do_object_panels(B_CLOTH_CLEARCACHEALL); + cloth_free_modifier (clmd); + } + } + break; default: if(event>=B_SELEFFECT && eventsim_parms.structural, 1.0, 5000.0, 100, 0, "Overall stiffness of structure"); - uiDefButF(block, NUM, B_DIFF, "BendStiff:", 160,170,150,20, &clmd->sim_parms.bending, 0.0, 1000.0, 1000, 0, "Wrinkle possibility"); - uiDefButI(block, NUM, B_DIFF, "Steps per Frame:", 10,150,150,20, &clmd->sim_parms.stepsPerFrame, 1.0, 100.0, 5, 0, "Quality of the simulation (higher=better=slower)"); + uiDefButF(block, NUM, B_CLOTH_RENEW, "StructStiff:", 10,170,150,20, &clmd->sim_parms.structural, 1.0, 5000.0, 100, 0, "Overall stiffness of structure"); + uiDefButF(block, NUM, B_CLOTH_RENEW, "BendStiff:", 160,170,150,20, &clmd->sim_parms.bending, 0.0, 1000.0, 1000, 0, "Wrinkle possibility"); + uiDefButI(block, NUM, B_CLOTH_RENEW, "Steps per Frame:", 10,150,150,20, &clmd->sim_parms.stepsPerFrame, 1.0, 100.0, 5, 0, "Quality of the simulation (higher=better=slower)"); uiBlockEndAlign(block); uiBlockBeginAlign(block); - uiDefButF(block, NUM, B_DIFF, "Spring Damp:", 160,150,150,20, &clmd->sim_parms.Cdis, 0.0, 10.0, 10, 0, "Apply gravitation to point movement"); + uiDefButF(block, NUM, B_CLOTH_RENEW, "Spring Damp:", 160,150,150,20, &clmd->sim_parms.Cdis, 0.0, 10.0, 10, 0, "Spring damping"); uiDefButF(block, NUM, B_DIFF, "Air Damp:", 10,130,150,20, &clmd->sim_parms.Cvi, 0.0, 10.0, 10, 0, "Apply gravitation to point movement"); uiBlockEndAlign(block); @@ -3123,9 +3134,9 @@ static void object_panel_cloth(Object *ob) uiDefBut(block, LABEL, 0, "Gravity:", 10,100,60,20, NULL, 0.0, 0, 0, 0, ""); // uiClearButLock(); - uiDefButF(block, NUM, B_DIFF, "X:", 70,100,80,20, &clmd->sim_parms.gravity[0], -100.0, 100.0, 10, 0, "Apply gravitation to point movement"); - uiDefButF(block, NUM, B_DIFF, "Y:", 150,100,80,20, &clmd->sim_parms.gravity[1], -100.0, 100.0, 10, 0, "Apply gravitation to point movement"); - uiDefButF(block, NUM, B_DIFF, "Z:", 230,100,80,20, &clmd->sim_parms.gravity[2], -100.0, 100.0, 10, 0, "Apply gravitation to point movement"); + uiDefButF(block, NUM, B_CLOTH_RENEW, "X:", 70,100,80,20, &clmd->sim_parms.gravity[0], -100.0, 100.0, 10, 0, "Apply gravitation to point movement"); + uiDefButF(block, NUM, B_CLOTH_RENEW, "Y:", 150,100,80,20, &clmd->sim_parms.gravity[1], -100.0, 100.0, 10, 0, "Apply gravitation to point movement"); + uiDefButF(block, NUM, B_CLOTH_RENEW, "Z:", 230,100,80,20, &clmd->sim_parms.gravity[2], -100.0, 100.0, 10, 0, "Apply gravitation to point movement"); uiBlockEndAlign(block); /* GOAL STUFF */ @@ -3150,7 +3161,7 @@ static void object_panel_cloth(Object *ob) } sprintf (clvg2, "%s%s", clmvg, clvg1); - uiDefButS(block, MENU, REDRAWVIEW3D, clvg2, 140,70,20,20, &clmd->sim_parms.vgroup_mass, 0, defCount, 0, 0, "Browses available vertex groups"); + uiDefButS(block, MENU, B_CLOTH_RENEW, clvg2, 140,70,20,20, &clmd->sim_parms.vgroup_mass, 0, defCount, 0, 0, "Browses available vertex groups"); MEM_freeN (clvg1); MEM_freeN (clvg2); @@ -3166,19 +3177,19 @@ static void object_panel_cloth(Object *ob) } else - uiDefButF(block, NUM, REDRAWVIEW3D, "Goal:", 160,70,150,20, &clmd->sim_parms.defgoal, 0.0, 1.0, 10, 0, "Default Goal (vertex target position) value, when no Vertex Group used"); + uiDefButF(block, NUM, B_CLOTH_RENEW, "Goal:", 160,70,150,20, &clmd->sim_parms.defgoal, 0.0, 1.0, 10, 0, "Default Goal (vertex target position) value, when no Vertex Group used"); } else { - uiDefButS(block, TOG, REDRAWVIEW3D, "W", 140,70,20,20, &clmd->sim_parms.vgroup_mass, 0, 1, 0, 0, "Use control point weight values"); - uiDefButF(block, NUM, REDRAWVIEW3D, "Goal:", 160,70,150,20, &clmd->sim_parms.defgoal, 0.0, 1.0, 10, 0, "Default Goal (vertex target position) value, when no Vertex Group used"); + uiDefButS(block, TOG, B_CLOTH_RENEW, "W", 140,70,20,20, &clmd->sim_parms.vgroup_mass, 0, 1, 0, 0, "Use control point weight values"); + uiDefButF(block, NUM, B_CLOTH_RENEW, "Goal:", 160,70,150,20, &clmd->sim_parms.defgoal, 0.0, 1.0, 10, 0, "Default Goal (vertex target position) value, when no Vertex Group used"); } - uiDefButF(block, NUM, B_DIFF, "G Stiff:", 10,50,150,20, &clmd->sim_parms.goalspring, 0.0, 500.0, 10, 0, "Goal (vertex target position) spring stiffness"); - uiDefButF(block, NUM, B_DIFF, "G Damp:", 160,50,150,20, &clmd->sim_parms.goalfrict , 0.0, 50.0, 10, 0, "Goal (vertex target position) friction"); - uiDefButF(block, NUM, REDRAWVIEW3D, "G Min:", 10,30,150,20, &clmd->sim_parms.mingoal, 0.0, 1.0, 10, 0, "Goal minimum, vertex group weights are scaled to match this range"); - uiDefButF(block, NUM, REDRAWVIEW3D, "G Max:", 160,30,150,20, &clmd->sim_parms.maxgoal, 0.0, 1.0, 10, 0, "Goal maximum, vertex group weights are scaled to match this range"); + uiDefButF(block, NUM, B_CLOTH_RENEW, "G Stiff:", 10,50,150,20, &clmd->sim_parms.goalspring, 0.0, 500.0, 10, 0, "Goal (vertex target position) spring stiffness"); + uiDefButF(block, NUM, B_CLOTH_RENEW, "G Damp:", 160,50,150,20, &clmd->sim_parms.goalfrict , 0.0, 50.0, 10, 0, "Goal (vertex target position) friction"); + uiDefButF(block, NUM, B_CLOTH_RENEW, "G Min:", 10,30,150,20, &clmd->sim_parms.mingoal, 0.0, 1.0, 10, 0, "Goal minimum, vertex group weights are scaled to match this range"); + uiDefButF(block, NUM, B_CLOTH_RENEW, "G Max:", 160,30,150,20, &clmd->sim_parms.maxgoal, 0.0, 1.0, 10, 0, "Goal maximum, vertex group weights are scaled to match this range"); } uiBlockEndAlign(block); @@ -3219,6 +3230,9 @@ static void object_panel_cloth_II(Object *ob) if(uiNewPanel(curarea, block, "Cloth Cache", "Physics", 651, 0, 318, 204)==0) return; uiSetButLock(object_data_is_libdata(ob), ERROR_LIBDATA_MESSAGE); + + uiDefButI(block, NUM, B_CLOTH_RENEW, "First Frame:", 10,160,150,20, &clmd->sim_parms.firstframe, 0, MAXFRAME, 1, 0, "Frame on which the simulation starts"); + uiDefButI(block, NUM, B_CLOTH_RENEW, "Last Frame:", 160,160,150,20, &clmd->sim_parms.lastframe, 0, MAXFRAME, 10, 0, "Frame on which the simulation stops"); if(clmd->sim_parms.cache) { @@ -3230,17 +3244,17 @@ static void object_panel_cloth_II(Object *ob) else sprintf (str, "Frame %d cached. [%d in preroll, %d in total]", length-clmd->sim_parms.preroll, clmd->sim_parms.preroll, length); - uiDefBut(block, LABEL, 0, str, 10,160,290,20, NULL, 0.0, 0, 0, 0, ""); - uiDefBut(block, LABEL, 0, "Clear cache:", 10,140,290,20, NULL, 0.0, 0, 0, 0, ""); + uiDefBut(block, LABEL, 0, str, 10,140,290,20, NULL, 0.0, 0, 0, 0, ""); + uiDefBut(block, LABEL, 0, "Clear cache:", 10,120,290,20, NULL, 0.0, 0, 0, 0, ""); uiBlockBeginAlign (block); - uiDefBut(block, BUT, B_CLOTH_CLEARCACHEALL, "All", 10, 120,145,20, NULL, 0.0, 0.0, 0, 0, "Free cloth cache without preroll"); - uiDefBut(block, BUT, B_CLOTH_CLEARCACHEFRAME, "From next frame", 155, 120,145,20, NULL, 0.0, 0.0, 0, 0, "Free cloth cache"); + uiDefBut(block, BUT, B_CLOTH_CLEARCACHEALL, "All", 10, 100,145,20, NULL, 0.0, 0.0, 0, 0, "Free cloth cache without preroll"); + uiDefBut(block, BUT, B_CLOTH_CLEARCACHEFRAME, "From next frame", 155, 100,145,20, NULL, 0.0, 0.0, 0, 0, "Free cloth cache"); if(length>1) // B_CLOTH_CHANGEPREROLL - uiDefButI(block, NUM, B_CLOTH_CHANGEPREROLL, "Preroll:", 10,100,145,20, &clmd->sim_parms.preroll, 0, length-1, 1, 0, "Simulation starts on this frame"); + uiDefButI(block, NUM, B_CLOTH_CHANGEPREROLL, "Preroll:", 10,80,145,20, &clmd->sim_parms.preroll, 0, length-1, 1, 0, "Simulation starts on this frame"); } else { - uiDefBut(block, LABEL, 0, "No frames cached.", 10,140,290,20, NULL, 0.0, 0, 0, 0, ""); + uiDefBut(block, LABEL, 0, "No frames cached.", 10,120,290,20, NULL, 0.0, 0, 0, 0, ""); } uiBlockEndAlign(block); } @@ -3271,7 +3285,7 @@ static void object_panel_cloth_III(Object *ob) uiBlockBeginAlign(block); // uiDefBut(block, LABEL, 0, "",10,10,300,20, NULL, 0.0, 0, 0, 0, ""); /* tell UI we go to 10,10*/ - uiDefButF(block, NUM, B_DIFF, "Min Distance:", 10,10,150,20, &clmd->coll_parms.epsilon, 0.001f, 1.0, 0.01f, 0, "Minimum distance between collision objects before collision response takes in"); + uiDefButF(block, NUM, B_CLOTH_RENEW, "Min Distance:", 10,10,150,20, &clmd->coll_parms.epsilon, 0.001f, 1.0, 0.01f, 0, "Minimum distance between collision objects before collision response takes in"); uiDefBut(block, LABEL, 0, "",160,10,150,20, NULL, 0.0, 0, 0, 0, ""); uiBlockEndAlign(block); } diff --git a/source/blender/src/editmesh.c b/source/blender/src/editmesh.c index fcfb1a5c40f..0874f4c3342 100644 --- a/source/blender/src/editmesh.c +++ b/source/blender/src/editmesh.c @@ -65,6 +65,7 @@ #include "BKE_DerivedMesh.h" #include "BKE_depsgraph.h" +#include "BKE_cloth.h" #include "BKE_customdata.h" #include "BKE_global.h" #include "BKE_key.h" @@ -72,6 +73,7 @@ #include "BKE_main.h" #include "BKE_material.h" #include "BKE_mesh.h" +#include "BKE_modifier.h" #include "BKE_object.h" #include "BKE_texture.h" #include "BKE_utildefines.h" @@ -1312,7 +1314,11 @@ void load_editMesh(void) if(me->id.us>1) { Base *base; for(base= G.scene->base.first; base; base= base->next) { - if(base->object->data==me) { + if(base->object->data==me) { + if(modifiers_isClothEnabled(base->object)) { + cloth_free_modifier(modifiers_isClothEnabled(base->object)); + } + base->object->softflag |= OB_SB_REDO; base->object->recalc |= OB_RECALC_DATA; } diff --git a/source/blender/src/editobject.c b/source/blender/src/editobject.c index 44b93789690..81a111e62c2 100644 --- a/source/blender/src/editobject.c +++ b/source/blender/src/editobject.c @@ -1746,6 +1746,10 @@ void exit_editmode(int flag) /* freedata==0 at render, 1= freedata, 2= do undo b sbObjectToSoftbody(ob); } + if(modifiers_isClothEnabled(ob)) { + cloth_free_modifier(modifiers_isClothEnabled(ob)); + } + if(ob->type==OB_MESH && get_mesh(ob)->mr) multires_edge_level_update(ob, get_mesh(ob)); diff --git a/source/blender/src/transform_conversions.c b/source/blender/src/transform_conversions.c index 2fdf68951b8..12c1265e7ca 100644 --- a/source/blender/src/transform_conversions.c +++ b/source/blender/src/transform_conversions.c @@ -75,6 +75,7 @@ #include "BKE_action.h" #include "BKE_armature.h" #include "BKE_blender.h" +#include "BKE_cloth.h" #include "BKE_curve.h" #include "BKE_constraint.h" #include "BKE_depsgraph.h" @@ -2414,7 +2415,7 @@ void autokeyframe_pose_cb_func(Object *ob, int tmode, short targetless_ik) } } -/* inserting keys, refresh ipo-keys, softbody, redraw events... (ton) */ +/* inserting keys, refresh ipo-keys, softbody, cloth, redraw events... (ton) */ /* note; transdata has been freed already! */ void special_aftertrans_update(TransInfo *t) { @@ -2476,13 +2477,15 @@ void special_aftertrans_update(TransInfo *t) } else { base= FIRSTBASE; - while(base) { - + while(base) { if(base->flag & BA_DO_IPO) redrawipo= 1; ob= base->object; if(modifiers_isSoftbodyEnabled(ob)) ob->softflag |= OB_SB_REDO; + else if(modifiers_isClothEnabled(ob)) { + cloth_free_modifier(modifiers_isClothEnabled(ob)); + } /* Set autokey if necessary */ if ((!cancelled) && (base->flag & SELECT)){ diff --git a/source/blender/src/transform_generics.c b/source/blender/src/transform_generics.c index 8e92fdda38a..ae65b1d9fa6 100644 --- a/source/blender/src/transform_generics.c +++ b/source/blender/src/transform_generics.c @@ -67,6 +67,7 @@ #include "BKE_action.h" #include "BKE_anim.h" #include "BKE_armature.h" +#include "BKE_cloth.h" #include "BKE_curve.h" #include "BKE_depsgraph.h" #include "BKE_displist.h" @@ -313,8 +314,16 @@ void recalcData(TransInfo *t) /* bah, softbody exception... recalcdata doesnt reset */ for(base= FIRSTBASE; base; base= base->next) { if(base->object->recalc & OB_RECALC_DATA) + { + ClothModifierData *clmd = NULL; + if(modifiers_isSoftbodyEnabled(base->object)) { base->object->softflag |= OB_SB_REDO; + } + else if(modifiers_isClothEnabled(ob)) { + cloth_free_modifier(modifiers_isClothEnabled(ob)); + } + } } } @@ -347,10 +356,17 @@ void recalcData(TransInfo *t) } } - /* softbody exception */ - if(modifiers_isSoftbodyEnabled(ob)) { - if(ob->recalc & OB_RECALC_DATA) - ob->softflag |= OB_SB_REDO; + /* softbody & cloth exception */ + if(ob->recalc & OB_RECALC_DATA) + { + ClothModifierData *clmd = NULL; + + if(modifiers_isSoftbodyEnabled(ob)) { + ob->softflag |= OB_SB_REDO; + } + else if(modifiers_isClothEnabled(ob)) { + cloth_free_modifier(modifiers_isClothEnabled(ob)); + } } /* proxy exception */ diff --git a/source/blender/src/vpaint.c b/source/blender/src/vpaint.c index 2f82cd2e2b2..102aa79d47e 100644 --- a/source/blender/src/vpaint.c +++ b/source/blender/src/vpaint.c @@ -64,6 +64,7 @@ #include "BKE_armature.h" #include "BKE_DerivedMesh.h" +#include "BKE_cloth.h" #include "BKE_customdata.h" #include "BKE_depsgraph.h" #include "BKE_deform.h" @@ -1346,6 +1347,11 @@ void weight_paint(void) /* this flag is event for softbody to refresh weightpaint values */ if(ob->soft) ob->softflag |= OB_SB_REDO; + // same goes for cloth + if(modifiers_isClothEnabled(ob)) { + cloth_free_modifier(modifiers_isClothEnabled(ob)); + } + BIF_undo_push("Weight Paint"); allqueue(REDRAWVIEW3D, 0); } From 7c05d8eb2b254d2f73f50fe3b2ad95c20c689be4 Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Mon, 17 Sep 2007 10:41:20 +0000 Subject: [PATCH 004/246] Fixed 2 crashers when activating collision object; Also put some additional openMP code in (doesn't hurt since #pragma gets ignored if no openMP available) --- source/blender/blenkernel/intern/cloth.c | 73 +++++++++++++++++++- source/blender/blenkernel/intern/collision.c | 7 +- source/blender/blenkernel/intern/implicit.c | 42 ++++++----- source/blender/blenkernel/intern/kdop.c | 12 ++-- source/blender/src/buttons_object.c | 4 +- 5 files changed, 105 insertions(+), 33 deletions(-) diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c index 18e1d4a6cde..47925e352eb 100644 --- a/source/blender/blenkernel/intern/cloth.c +++ b/source/blender/blenkernel/intern/cloth.c @@ -444,6 +444,43 @@ int cloth_cache_search_frame(ClothModifierData *clmd, float time) return 1; } +int cloth_cache_last_frame(ClothModifierData *clmd) +{ + Frame *frame = NULL; + LinkNode *search = NULL; + int temptime = 0; + + Cloth *cloth = NULL; + + if(!clmd) + return 0; + + cloth = clmd->clothObject; + + if(!cloth) + return 0; + + if(clmd->sim_parms.cache) + { + search = clmd->sim_parms.cache; + + // check if frame exists + while(search) + { + frame = search->link; + + if(frame->time > temptime) + { + temptime = frame->time; + } + + search = search->next; + } + } + + return temptime; +} + void cloth_cache_get_frame(ClothModifierData *clmd, float time) { Frame *frame = NULL; @@ -622,8 +659,23 @@ void clothModifier_do(ClothModifierData *clmd, Object *ob, DerivedMesh *dm, float deltaTime = current_time - clmd->sim_parms.sim_time; // only be active during a specific period - if((current_time < clmd->sim_parms.firstframe)||(current_time > clmd->sim_parms.lastframe)) + if(current_time < clmd->sim_parms.firstframe) return; + else if(current_time > clmd->sim_parms.lastframe) + { + int frametime = cloth_cache_last_frame(clmd); + if(cloth_cache_search_frame(clmd, frametime)) + { + cloth_cache_get_frame(clmd, frametime); + cloth_to_object (ob, clmd, vertexCos, numverts); + } + return; + } + else if(ABS(deltaTime) >= 2.0f ) // no timewarps allowed + { + if(!cloth_cache_search_frame(clmd, framenr)) + return; + } // unused in the moment clmd->sim_parms.dt = 1.0f / clmd->sim_parms.stepsPerFrame; @@ -668,7 +720,7 @@ void clothModifier_do(ClothModifierData *clmd, Object *ob, DerivedMesh *dm, VECCOPY (verts->txold, verts->x); // Get the current position. - VECCOPY (verts->x, mvert[i].co); + VECCOPY (verts->x, vertexCos[i]); Mat4MulVecfl(ob->obmat, verts->x); // Compute the vertices velocity. @@ -902,6 +954,23 @@ static int collobj_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh unsigned int i; MVert *mvert = NULL; ClothVertex *verts = NULL; + + /* If we have a clothObject, free it. */ + if (clmd->clothObject != NULL) + cloth_free_modifier (clmd); + + /* Allocate a new cloth object. */ + clmd->clothObject = MEM_callocN (sizeof(Cloth), "cloth"); + if (clmd->clothObject) + { + clmd->clothObject->old_solver_type = -1; + clmd->clothObject->old_collision_type = -1; + } + else if (clmd->clothObject == NULL) + { + modifier_setError (&(clmd->modifier), "Out of memory on allocating clmd->clothObject."); + return 0; + } switch (ob->type) { diff --git a/source/blender/blenkernel/intern/collision.c b/source/blender/blenkernel/intern/collision.c index cdbac692b35..13327c16006 100644 --- a/source/blender/blenkernel/intern/collision.c +++ b/source/blender/blenkernel/intern/collision.c @@ -403,7 +403,7 @@ double implicit_tri_check_coherence (ClothModifierData *clmd, ClothModifierData VECCOPY(b[0], cloth2->verts[face2->v1].txold); VECCOPY(b[1], cloth2->verts[face2->v2].txold); VECCOPY(b[2], cloth2->verts[face2->v3].txold); - +#pragma omp critical distance = plNearestPoints(a,b,pa,pb,normal); quadA = quadB = 0; @@ -450,7 +450,7 @@ double implicit_tri_check_coherence (ClothModifierData *clmd, ClothModifierData VECCOPY(b[0], cloth2->verts[indexD].txold); VECCOPY(b[1], cloth2->verts[indexE].txold); VECCOPY(b[2], cloth2->verts[indexF].txold); - +#pragma omp critical tempdistance = plNearestPoints(a,b,tpa,tpb,tnormal); if(tempdistance < distance) @@ -483,7 +483,7 @@ void bvh_collision_response(ClothModifierData *clmd, ClothModifierData *coll_clm LinkNode **linknode; double distance = 0; float epsilon = clmd->coll_parms.epsilon; - + collpair = (CollPair *)MEM_callocN(sizeof(CollPair), "cloth coll pair"); linknode = clmd->coll_parms.temp; @@ -505,7 +505,6 @@ void bvh_collision_response(ClothModifierData *clmd, ClothModifierData *coll_clm // printf("normal x: %f, y: %f, z: %f\n", collpair->normal[0], collpair->normal[1], collpair->normal[2]); collpair->distance = distance; - BLI_linklist_append(&linknode[tree1->tri_index], collpair); } else diff --git a/source/blender/blenkernel/intern/implicit.c b/source/blender/blenkernel/intern/implicit.c index c756c220fe6..18044db6049 100644 --- a/source/blender/blenkernel/intern/implicit.c +++ b/source/blender/blenkernel/intern/implicit.c @@ -89,7 +89,7 @@ double itval() // intrinsics need better compile flag checking // #include // #include -#include +// #include static struct timeval _itstart, _itend; static struct timezone itz; @@ -247,14 +247,9 @@ DO_INLINE void submul_lfvectorS(float (*to)[3], float (*fLongVector)[3], float s DO_INLINE float dot_lfvector(float (*fLongVectorA)[3], float (*fLongVectorB)[3], unsigned int verts) { unsigned int i = 0; - -#ifndef _WIN32 - float temp __attribute__ ((aligned (16) ) )= 0.0f; // __declspec(align(16)) -#else - float temp = 0.0f; -#endif - -#pragma omp parallel for reduction(+: temp) schedule(guided, 1) + float temp = 0.0; +// schedule(guided, 2) +#pragma omp parallel for reduction(+: temp) for(i = 0; i < verts; i++) { temp += INPR(fLongVectorA[i], fLongVectorB[i]); @@ -264,7 +259,6 @@ DO_INLINE float dot_lfvector(float (*fLongVectorA)[3], float (*fLongVectorB)[3], /* A = B + C --> for big vector */ DO_INLINE void add_lfvector_lfvector(float (*to)[3], float (*fLongVectorA)[3], float (*fLongVectorB)[3], unsigned int verts) { - unsigned int i = 0; for(i = 0; i < verts; i++) @@ -576,7 +570,7 @@ DO_INLINE void mul_bfmatrix_S(fmatrix3x3 *matrix, float scalar) /* STATUS: verified */ DO_INLINE void mul_bfmatrix_lfvector( float (*to)[3], fmatrix3x3 *from, float (*fLongVector)[3]) { - unsigned int i = 0,j=0; + int i = 0,j=0; zero_lfvector(to, from[0].vcount); /* process diagonal elements */ for(i = 0; i < from[0].vcount; i++) @@ -585,12 +579,21 @@ DO_INLINE void mul_bfmatrix_lfvector( float (*to)[3], fmatrix3x3 *from, float (* } /* process off-diagonal entries (every off-diagonal entry needs to be symmetric) */ - for(j = from[0].vcount; j < from[0].vcount+from[0].scount; j++) +#pragma parallel for shared(to,from, fLongVector) private(i) + for(i = from[0].vcount; i < from[0].vcount+from[0].scount; i++) { - muladd_fmatrix_fvector(to[from[j].c], from[j].m, fLongVector[from[j].r]); - muladd_fmatrix_fvector(to[from[j].r], from[j].m, fLongVector[from[j].c]); - } - + // muladd_fmatrix_fvector(to[from[i].c], from[i].m, fLongVector[from[i].r]); + + to[from[i].c][0] += INPR(from[i].m[0],fLongVector[from[i].r]); + to[from[i].c][1] += INPR(from[i].m[1],fLongVector[from[i].r]); + to[from[i].c][2] += INPR(from[i].m[2],fLongVector[from[i].r]); + + // muladd_fmatrix_fvector(to[from[i].r], from[i].m, fLongVector[from[i].c]); + + to[from[i].r][0] += INPR(from[i].m[0],fLongVector[from[i].c]); + to[from[i].r][1] += INPR(from[i].m[1],fLongVector[from[i].c]); + to[from[i].r][2] += INPR(from[i].m[2],fLongVector[from[i].c]); + } } /* SPARSE SYMMETRIC add big matrix with big matrix: A = B + C*/ DO_INLINE void add_bfmatrix_bfmatrix( fmatrix3x3 *to, fmatrix3x3 *from, fmatrix3x3 *matrix) @@ -1195,12 +1198,13 @@ DO_INLINE void calc_spring_force(ClothModifierData *clmd, ClothSpring *s, lfVect dfdx_spring_type1(dfdx, dir,length,L,k); - dfdv_damp(dfdv, dir,clmd->sim_parms.Cdis); + dfdv_damp(dfdv, dir,clmd->sim_parms.Cdis); + sub_fmatrix_fmatrix(dFdV[s->ij].m, dFdV[s->ij].m, dfdv); sub_fmatrix_fmatrix(dFdV[s->kl].m, dFdV[s->kl].m, dfdv); add_fmatrix_fmatrix(dFdV[s->matrix_index].m, dFdV[s->matrix_index].m, dfdv); - + } } else // calculate force of bending springs @@ -1424,7 +1428,7 @@ int implicit_solver (Object *ob, float frame, ClothModifierData *clmd, ListBase } // call collision function - // result = cloth_bvh_objcollision(clmd, step + dt, bvh_collision_response, dt); + result = cloth_bvh_objcollision(clmd, step + dt, bvh_collision_response, dt); // copy corrected positions back to simulation for(i = 0; i < numverts; i++) diff --git a/source/blender/blenkernel/intern/kdop.c b/source/blender/blenkernel/intern/kdop.c index cdcb16c67f6..0d9fddf0211 100644 --- a/source/blender/blenkernel/intern/kdop.c +++ b/source/blender/blenkernel/intern/kdop.c @@ -728,7 +728,7 @@ DO_INLINE int bvh_overlap(float *bv1, float *bv2) */ int bvh_traverse(ClothModifierData * clmd, ClothModifierData * coll_clmd, Tree * tree1, Tree * tree2, float step, CM_COLLISION_RESPONSE collision_response) { - int i = 0, ret=0; + int i = 0, j = 0, ret=0; /* // Shouldn't be possible @@ -737,8 +737,7 @@ int bvh_traverse(ClothModifierData * clmd, ClothModifierData * coll_clmd, Tree * printf("Error: no tree there\n"); return 0; } - */ - + */ if (bvh_overlap(tree1->bv, tree2->bv)) { // Check if this node in the first tree is a leaf @@ -751,7 +750,7 @@ int bvh_traverse(ClothModifierData * clmd, ClothModifierData * coll_clmd, Tree * if(collision_response) collision_response (clmd, coll_clmd, tree1, tree2); - return 1; + ret = 1; } else { @@ -767,14 +766,15 @@ int bvh_traverse(ClothModifierData * clmd, ClothModifierData * coll_clmd, Tree * else { // Process the quad tree. - for (i = 0; i < 4; i++) + for (j = 0; j < 4; j++) { // Only traverse nodes that exist. - if (tree1->nodes [i] && bvh_traverse (clmd, coll_clmd, tree1->nodes[i], tree2, step, collision_response)) + if (tree1->nodes [j] && bvh_traverse (clmd, coll_clmd, tree1->nodes[j], tree2, step, collision_response)) ret = 1; } } } + return ret; } diff --git a/source/blender/src/buttons_object.c b/source/blender/src/buttons_object.c index df6d88bddd0..2106525e9b2 100644 --- a/source/blender/src/buttons_object.c +++ b/source/blender/src/buttons_object.c @@ -3231,8 +3231,8 @@ static void object_panel_cloth_II(Object *ob) uiSetButLock(object_data_is_libdata(ob), ERROR_LIBDATA_MESSAGE); - uiDefButI(block, NUM, B_CLOTH_RENEW, "First Frame:", 10,160,150,20, &clmd->sim_parms.firstframe, 0, MAXFRAME, 1, 0, "Frame on which the simulation starts"); - uiDefButI(block, NUM, B_CLOTH_RENEW, "Last Frame:", 160,160,150,20, &clmd->sim_parms.lastframe, 0, MAXFRAME, 10, 0, "Frame on which the simulation stops"); + uiDefButI(block, NUM, B_DIFF, "First Frame:", 10,160,150,20, &clmd->sim_parms.firstframe, 0, MAXFRAME, 1, 0, "Frame on which the simulation starts"); + uiDefButI(block, NUM, B_DIFF, "Last Frame:", 160,160,150,20, &clmd->sim_parms.lastframe, 0, MAXFRAME, 10, 0, "Frame on which the simulation stops"); if(clmd->sim_parms.cache) { From 26a0473c8ca6dd0e0c86f09a74ec91a59cc90516 Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Mon, 17 Sep 2007 11:18:04 +0000 Subject: [PATCH 005/246] compile fix from elubie special request from mfoxdogg: place modifier where you want --- source/blender/blenkernel/intern/modifier.c | 2 +- source/blender/imbuf/intern/thumbs.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c index d3d41e70d57..7607ce63b9d 100644 --- a/source/blender/blenkernel/intern/modifier.c +++ b/source/blender/blenkernel/intern/modifier.c @@ -5234,7 +5234,7 @@ ModifierTypeInfo *modifierType_getInfo(ModifierType type) mti->type = eModifierTypeType_OnlyDeform; mti->initData = clothModifier_initData; mti->flags = eModifierTypeFlag_AcceptsCVs - | eModifierTypeFlag_RequiresOriginalData; + // | eModifierTypeFlag_RequiresOriginalData; // | eModifierTypeFlag_SupportsMapping // | eModifierTypeFlag_SupportsEditmode // | eModifierTypeFlag_EnableInEditmode; diff --git a/source/blender/imbuf/intern/thumbs.c b/source/blender/imbuf/intern/thumbs.c index c2e30b091c2..b071331e46b 100644 --- a/source/blender/imbuf/intern/thumbs.c +++ b/source/blender/imbuf/intern/thumbs.c @@ -69,7 +69,7 @@ static int get_thumb_dir( char* dir , ThumbSize size) /* yes, applications shouldn't store data there, but so does GIMP :)*/ SHGetSpecialFolderPath(0, dir, CSIDL_PROFILE, 0); #else - home = getenv("HOME"); + char* home = getenv("HOME"); if (!home) return 0; BLI_strncpy(dir, home, FILE_MAX); #endif From ca6e59bc487afeafebdbf4bf76524cfaf767624c Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Mon, 17 Sep 2007 11:19:07 +0000 Subject: [PATCH 006/246] stupid missing ";" --- source/blender/blenkernel/intern/modifier.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c index 7607ce63b9d..4f1e9a5644c 100644 --- a/source/blender/blenkernel/intern/modifier.c +++ b/source/blender/blenkernel/intern/modifier.c @@ -5233,7 +5233,7 @@ ModifierTypeInfo *modifierType_getInfo(ModifierType type) mti = INIT_TYPE(Cloth); mti->type = eModifierTypeType_OnlyDeform; mti->initData = clothModifier_initData; - mti->flags = eModifierTypeFlag_AcceptsCVs + mti->flags = eModifierTypeFlag_AcceptsCVs; // | eModifierTypeFlag_RequiresOriginalData; // | eModifierTypeFlag_SupportsMapping // | eModifierTypeFlag_SupportsEditmode From 0e502338fc68e35412c108252e8c1c6f4a544ec2 Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Mon, 17 Sep 2007 13:25:29 +0000 Subject: [PATCH 007/246] disable parallel for users --- intern/elbeem/SConscript | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/intern/elbeem/SConscript b/intern/elbeem/SConscript index 75d9b98c82a..bb6637ba32d 100644 --- a/intern/elbeem/SConscript +++ b/intern/elbeem/SConscript @@ -5,7 +5,7 @@ Import('env') sources = env.Glob('intern/*.cpp') -defs = 'PARALLEL NOGUI ELBEEM_BLENDER=1' +defs = 'NOGUI ELBEEM_BLENDER=1' if env['OURPLATFORM']=='win32-vc': defs += ' USE_MSVC6FIXES' incs = env['BF_PNG_INC'] + ' ' + env['BF_ZLIB_INC'] + ' ' +env['BF_SDL_INC'] From deceff52d132041d3f6761a102966dc1aa1299be Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Mon, 17 Sep 2007 19:32:15 +0000 Subject: [PATCH 008/246] Add WITH_BF_OPENMP for openmp usage, untested on msvc --- SConstruct | 12 ++++++++++++ intern/elbeem/SConscript | 6 +++++- source/blender/blenkernel/BKE_blender.h | 2 +- tools/btools.py | 7 +++++-- 4 files changed, 23 insertions(+), 4 deletions(-) diff --git a/SConstruct b/SConstruct index 2cacb91d103..c7a7ac5e298 100644 --- a/SConstruct +++ b/SConstruct @@ -176,6 +176,18 @@ if env['BF_NO_ELBEEM'] == 1: env['CXXFLAGS'].append('-DDISABLE_ELBEEM') env['CCFLAGS'].append('-DDISABLE_ELBEEM') +if env['WITH_BF_OPENMP'] == 1: + if env['OURPLATFORM']=='win32-vc': + env['PLATFORM_LINKFLAGS'].append('/openmp') + env['CCFLAGS'].append('/openmp') + env['CPPFLAGS'].append('/openmp') + env['CXXFLAGS'].append('/openmp') + else: + env['PLATFORM_LINKFLAGS'].append('-lgomp') + env['CCFLAGS'].append('-fopenmp') + env['CPPFLAGS'].append('-fopenmp') + env['CXXFLAGS'].append('-fopenmp') + #check for additional debug libnames if env.has_key('BF_DEBUG_LIBS'): diff --git a/intern/elbeem/SConscript b/intern/elbeem/SConscript index bb6637ba32d..bdcb0507987 100644 --- a/intern/elbeem/SConscript +++ b/intern/elbeem/SConscript @@ -5,7 +5,11 @@ Import('env') sources = env.Glob('intern/*.cpp') -defs = 'NOGUI ELBEEM_BLENDER=1' +defs = ' NOGUI ELBEEM_BLENDER=1' + +if env['WITH_BF_OPENMP'] == 1: + defs += ' PARALLEL' + if env['OURPLATFORM']=='win32-vc': defs += ' USE_MSVC6FIXES' incs = env['BF_PNG_INC'] + ' ' + env['BF_ZLIB_INC'] + ' ' +env['BF_SDL_INC'] diff --git a/source/blender/blenkernel/BKE_blender.h b/source/blender/blenkernel/BKE_blender.h index e2d2dab9aae..6bddd9de932 100644 --- a/source/blender/blenkernel/BKE_blender.h +++ b/source/blender/blenkernel/BKE_blender.h @@ -44,7 +44,7 @@ struct ListBase; struct MemFile; #define BLENDER_VERSION 245 -#define BLENDER_SUBVERSION 0 +#define BLENDER_SUBVERSION 1 #define BLENDER_MINVERSION 240 #define BLENDER_MINSUBVERSION 0 diff --git a/tools/btools.py b/tools/btools.py index eb8f844df4d..1b91a3343dc 100755 --- a/tools/btools.py +++ b/tools/btools.py @@ -55,8 +55,9 @@ def validate_arguments(args, bc): 'BF_VERSE_INCLUDE', 'VERSE_BUILD_BINARY', 'VERSE_BUILD_DIR', 'VERSE_REGEN_PROTO', 'BF_TWEAK_MODE', - 'WITHOUT_BF_INSTALL' - ] + 'WITHOUT_BF_INSTALL', + 'WITH_BF_OPENMP' + ] arg_list = ['BF_DEBUG', 'BF_QUIET', 'BF_CROSS', 'BF_UPDATE', 'BF_INSTALLDIR', 'BF_TOOLSET', 'BF_BINNAME', @@ -247,6 +248,8 @@ def read_opts(cfg, args): ('BF_FREETYPE_LIB', 'Freetype library', ''), ('BF_FREETYPE_LIBPATH', 'Freetype library path', ''), + (BoolOption('WITH_BF_OPENMP', 'Use OpenMP if true', 'false')), + (BoolOption('WITH_BF_QUICKTIME', 'Use QuickTime if true', 'false')), ('BF_QUICKTIME', 'QuickTime base path', ''), ('BF_QUICKTIME_INC', 'QuickTime include path', ''), From 969397ced28159562ad350ba595da9833266f6ae Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Mon, 17 Sep 2007 19:57:47 +0000 Subject: [PATCH 009/246] bf-blender/trunk/blender rev 12059 + 12060 + 12064 merged (this commit is only 12059, others are already merged) --- source/blender/src/editview.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/source/blender/src/editview.c b/source/blender/src/editview.c index 176821e0cc9..bd90d887cd0 100644 --- a/source/blender/src/editview.c +++ b/source/blender/src/editview.c @@ -2063,15 +2063,23 @@ void set_render_border(void) G.scene->r.border.ymin= ((float)rect.ymin-vb.ymin)/(vb.ymax-vb.ymin); G.scene->r.border.xmax= ((float)rect.xmax-vb.xmin)/(vb.xmax-vb.xmin); G.scene->r.border.ymax= ((float)rect.ymax-vb.ymin)/(vb.ymax-vb.ymin); - + CLAMP(G.scene->r.border.xmin, 0.0, 1.0); CLAMP(G.scene->r.border.ymin, 0.0, 1.0); CLAMP(G.scene->r.border.xmax, 0.0, 1.0); CLAMP(G.scene->r.border.ymax, 0.0, 1.0); - + allqueue(REDRAWVIEWCAM, 1); - /* if it was not set, we do this */ - G.scene->r.mode |= R_BORDER; + + /* drawing a border surrounding the entire camera view switches off border rendering */ + if (G.scene->r.border.xmin <= 0.0 && G.scene->r.border.xmax >= 1.0 && + G.scene->r.border.ymin <= 0.0 && G.scene->r.border.ymax >= 1.0) + { + G.scene->r.mode &= ~R_BORDER; + } else { + G.scene->r.mode |= R_BORDER; + } + allqueue(REDRAWBUTSSCENE, 1); } } From f473f4ee7987e9f2d66c5f0821bb826ab194a082 Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Mon, 17 Sep 2007 21:03:45 +0000 Subject: [PATCH 010/246] Fix: No GAMEENGINE=1 needed anymore, only WITH_BF_BULLET=1. Fix: (Hopefully) some fix for linking openmp --- SConstruct | 4 ++-- extern/SConscript | 5 +++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/SConstruct b/SConstruct index c7a7ac5e298..7fad247ec07 100644 --- a/SConstruct +++ b/SConstruct @@ -178,12 +178,12 @@ if env['BF_NO_ELBEEM'] == 1: if env['WITH_BF_OPENMP'] == 1: if env['OURPLATFORM']=='win32-vc': - env['PLATFORM_LINKFLAGS'].append('/openmp') + env.Append(LINKFLAGS=['/openmp']) env['CCFLAGS'].append('/openmp') env['CPPFLAGS'].append('/openmp') env['CXXFLAGS'].append('/openmp') else: - env['PLATFORM_LINKFLAGS'].append('-lgomp') + env.Append(LINKFLAGS=['-lgomp']) env['CCFLAGS'].append('-fopenmp') env['CPPFLAGS'].append('-fopenmp') env['CXXFLAGS'].append('-fopenmp') diff --git a/extern/SConscript b/extern/SConscript index 0cdf9676862..77e8998e359 100644 --- a/extern/SConscript +++ b/extern/SConscript @@ -5,8 +5,9 @@ Import('env') if env['WITH_BF_GAMEENGINE']: SConscript(['qhull/SConscript', 'solid/SConscript']) - if env['WITH_BF_BULLET']: - SConscript(['bullet2/src/SConscript']) + +if env['WITH_BF_BULLET']: + SConscript(['bullet2/src/SConscript']) if env['WITH_BF_INTERNATIONAL']: SConscript(['bFTGL/SConscript']) From 9dbcffadec1b537e68435d01e5b632d4763a7150 Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Tue, 18 Sep 2007 07:16:57 +0000 Subject: [PATCH 011/246] Temporary fix for loading crash of .blends with cached frames. Also fixed some goal behavior/init problem to match SB behaviour --- source/blender/blenkernel/intern/cloth.c | 14 ++++++---- source/blender/blenkernel/intern/implicit.c | 2 +- source/blender/blenkernel/intern/modifier.c | 1 + source/blender/blenloader/intern/readfile.c | 10 ++++--- source/blender/blenloader/intern/writefile.c | 29 +++++++++++++++++--- 5 files changed, 41 insertions(+), 15 deletions(-) diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c index 47925e352eb..14370b59d68 100644 --- a/source/blender/blenkernel/intern/cloth.c +++ b/source/blender/blenkernel/intern/cloth.c @@ -913,13 +913,10 @@ static void cloth_apply_vgroup(ClothModifierData *clmd, DerivedMesh *dm, short v verts = clothObj->verts; for (i = 0; i < numverts; i++, verts++) - { - /* so this will definily be below SOFTGOALSNAP */ - verts->goal= 0.0f; - + { // LATER ON, support also mass painting here if(clmd->sim_parms.flags & CSIMSETT_FLAG_GOAL) - { + { dvert = dm->getVertData(dm, i, CD_MDEFORMVERT); if(dvert) { @@ -1211,7 +1208,12 @@ static int cloth_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *d Mat4MulVecfl(ob->obmat, verts->x); verts->mass = clmd->sim_parms.mass; - verts->goal= clmd->sim_parms.defgoal; + + if(clmd->sim_parms.flags & CSIMSETT_FLAG_GOAL) + verts->goal= clmd->sim_parms.defgoal; + else + verts->goal= 0.0f; + verts->flags = 0; VECCOPY(verts->xold, verts->x); VECCOPY(verts->xconst, verts->x); diff --git a/source/blender/blenkernel/intern/implicit.c b/source/blender/blenkernel/intern/implicit.c index 18044db6049..aa28f0a2086 100644 --- a/source/blender/blenkernel/intern/implicit.c +++ b/source/blender/blenkernel/intern/implicit.c @@ -570,7 +570,7 @@ DO_INLINE void mul_bfmatrix_S(fmatrix3x3 *matrix, float scalar) /* STATUS: verified */ DO_INLINE void mul_bfmatrix_lfvector( float (*to)[3], fmatrix3x3 *from, float (*fLongVector)[3]) { - int i = 0,j=0; + unsigned int i = 0,j=0; zero_lfvector(to, from[0].vcount); /* process diagonal elements */ for(i = 0; i < from[0].vcount; i++) diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c index 4f1e9a5644c..546247f8e35 100644 --- a/source/blender/blenkernel/intern/modifier.c +++ b/source/blender/blenkernel/intern/modifier.c @@ -4873,6 +4873,7 @@ static void clothModifier_deformVerts( DerivedMesh *dm = NULL; // if possible use/create DerivedMesh + if(derivedData) dm = CDDM_copy(derivedData); else if(ob->type==OB_MESH) dm = CDDM_from_mesh(ob->data, ob); diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 19f74096e54..3fbfef12f1f 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -2878,11 +2878,13 @@ static void direct_link_modifiers(FileData *fd, ListBase *lb) ClothModifierData *clmd = (ClothModifierData*) md; clmd->clothObject = NULL; - /* - if (clmd->sim_parms.flags & CSIMSETT_FLAG_BAKED) { - clmd->baked_data = newdataadr (fd, clmd->baked_data); + clmd->sim_parms.cache = NULL; + + if (clmd->sim_parms.cache) { + // TODO + // clmd->cache = newdataadr (fd, clmd->cache); printf ("direct_link_modifiers: read cloth baked_data.\n"); - }*/ + } } else if (md->type==eModifierType_Hook) { HookModifierData *hmd = (HookModifierData*) md; diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c index 4203824ae65..0a0c49c5ef8 100644 --- a/source/blender/blenloader/intern/writefile.c +++ b/source/blender/blenloader/intern/writefile.c @@ -813,6 +813,23 @@ static void write_constraint_channels(WriteData *wd, ListBase *chanbase) } +/* +// TODO: finish this +static void write_cloth_cache(WriteData *wd, LinkNode *ln) +{ + + while(ln) { + writestruct(wd, DATA, "cloth_cache", 1, ln); + writestruct(wd, DATA, "cloth_cache_frame", 1, ln->link); + writestruct(wd, DATA, "cloth_cache_frame_verts", 1, ln->link); + writestruct(wd, DATA, "cloth_cache_frame_springs", 1, ln->link); + } + + ln = ln->next; + } +} +*/ + static void write_modifiers(WriteData *wd, ListBase *modbase) { ModifierData *md; @@ -832,16 +849,20 @@ static void write_modifiers(WriteData *wd, ListBase *modbase) else if (md->type==eModifierType_Cloth) { int n; ClothModifierData *clmd = (ClothModifierData *) md; - /* - if ((clmd->sim_parms.flags & CSIMSETT_FLAG_BAKED) && clmd->baked_data) { + + if (clmd->sim_parms.cache) { // Compute the number of vertices we're saving. - + // TODO + // write_cloth_cache(); + /* + // old code n = (clmd->sim_parms.bake_end_frame - clmd->sim_parms.bake_start_frame + 1) * clmd->sim_parms.bake_num_verts; writedata (wd, DATA, n * sizeof (clmd->baked_data [0]), clmd->baked_data); printf ("write_modifiers: wrote %d elements of size %d for cloth baked data.\n", n, sizeof (clmd->baked_data [0])); - }*/ + */ + } } } } From 138b436914e6d42acae589633443477bae4425ad Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Tue, 18 Sep 2007 11:42:52 +0000 Subject: [PATCH 012/246] Fixed floating point rounding error in goal velocity computation, pointed out my mfoxdogg, additional code cleanup --- source/blender/blenkernel/intern/cloth.c | 2 +- source/blender/blenkernel/intern/implicit.c | 43 +++++++++++---------- 2 files changed, 24 insertions(+), 21 deletions(-) diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c index 14370b59d68..40f3c9816a6 100644 --- a/source/blender/blenkernel/intern/cloth.c +++ b/source/blender/blenkernel/intern/cloth.c @@ -764,7 +764,7 @@ void clothModifier_do(ClothModifierData *clmd, Object *ob, DerivedMesh *dm, Mat4MulVecfl(ob->obmat, verts->xconst); /* Compute the vertices velocity. */ - VECSUB (verts->v, verts->x, verts->xold); + VECSUB (verts->v, verts->xconst, verts->xold); } tstart(); diff --git a/source/blender/blenkernel/intern/implicit.c b/source/blender/blenkernel/intern/implicit.c index aa28f0a2086..df5830f6a77 100644 --- a/source/blender/blenkernel/intern/implicit.c +++ b/source/blender/blenkernel/intern/implicit.c @@ -736,7 +736,7 @@ int implicit_init (Object *ob, ClothModifierData *clmd) { id->A[i].r = id->A[i].c = id->dFdV[i].r = id->dFdV[i].c = id->dFdX[i].r = id->dFdX[i].c = id->P[i].c = id->P[i].r = id->Pinv[i].c = id->Pinv[i].r = id->bigI[i].c = id->bigI[i].r = i; - if(verts [i].flags & CVERT_FLAG_PINNED) + if(verts [i].goal >= SOFTGOALSNAP) { id->S[pinned].pinned = 1; id->S[pinned].c = id->S[pinned].r = i; @@ -1199,8 +1199,9 @@ DO_INLINE void calc_spring_force(ClothModifierData *clmd, ClothSpring *s, lfVect dfdx_spring_type1(dfdx, dir,length,L,k); dfdv_damp(dfdv, dir,clmd->sim_parms.Cdis); - + sub_fmatrix_fmatrix(dFdV[s->ij].m, dFdV[s->ij].m, dfdv); + sub_fmatrix_fmatrix(dFdV[s->kl].m, dFdV[s->kl].m, dfdv); add_fmatrix_fmatrix(dFdV[s->matrix_index].m, dFdV[s->matrix_index].m, dfdv); @@ -1315,15 +1316,15 @@ void calc_force(ClothModifierData *clmd, lfVector *lF, lfVector *lX, lfVector *l mul_fvector_S(tvect, tvect, time); VECADD(tvect, tvect, verts[i].xold); - VecSubf(auxvect, tvect, lX[i]); + VECSUB(auxvect, tvect, lX[i]); ks = 1.0f/(1.0f- verts [i].goal*clmd->sim_parms.goalspring)-1.0f ; VECADDS(lF[i], lF[i], auxvect, -ks); - /* calulate damping forces generated by goals*/ + // calulate damping forces generated by goals VECSUB(velgoal,verts[i].xold, verts[i].xconst); kd = clmd->sim_parms.goalfrict * 0.01f; // friction force scale taken from SB VECSUBADDSS(lF[i], velgoal, kd, lV[i], kd); - + } } } @@ -1404,6 +1405,7 @@ int implicit_solver (Object *ob, float frame, ClothModifierData *clmd, ListBase if(verts [i].goal >= SOFTGOALSNAP) { VECSUB(id->V[i], verts[i].xconst, verts[i].xold); + // VecMulf(id->V[i], 1.0 / dt); } } } @@ -1413,15 +1415,30 @@ int implicit_solver (Object *ob, float frame, ClothModifierData *clmd, ListBase effectors= pdInitEffectors(ob,NULL); // calculate - calc_force(clmd, id->F, id->X, id->V, id->dFdV, id->dFdX, effectors, step); + calc_force(clmd, id->F, id->X, id->V, id->dFdV, id->dFdX, effectors, step ); simulate_implicit_euler(id->Vnew, id->X, id->V, id->F, id->dFdV, id->dFdX, dt, id->A, id->B, id->dV, id->S, id->z, id->olddV); + add_lfvector_lfvectorS(id->Xnew, id->X, id->Vnew, dt, numverts); // collisions itstart(); + // update verts to current positions for(i = 0; i < numverts; i++) { + if(clmd->sim_parms.flags & CSIMSETT_FLAG_GOAL) /* do goal stuff */ + { + if(verts [i].goal >= SOFTGOALSNAP) + { + float tvect[3] = {.0,.0,.0}; + // VECSUB(tvect, id->Xnew[i], verts[i].xold); + mul_fvector_S(tvect, id->V[i], step+dt); + VECADD(tvect, tvect, verts[i].xold); + VECCOPY(id->Xnew[i], tvect); + } + + } + VECCOPY(verts[i].tx, id->Xnew[i]); VECSUB(verts[i].tv, verts[i].tx, verts[i].txold); @@ -1433,7 +1450,6 @@ int implicit_solver (Object *ob, float frame, ClothModifierData *clmd, ListBase // copy corrected positions back to simulation for(i = 0; i < numverts; i++) { - // TODO: calculate v_n+1 from v_n+1/2 if(result) { VECADD(verts[i].tx, verts[i].txold, verts[i].tv); @@ -1509,23 +1525,10 @@ void implicit_set_positions (ClothModifierData *clmd) ClothVertex *verts = cloth->verts; unsigned int numverts = cloth->numverts, i; Implicit_Data *id = cloth->implicit; - unsigned int pinned = 0; - - // reset pinned verts in S matrix to zero - // id->S[0].vcount = 0; id->S[0].scount = 0; for(i = 0; i < numverts; i++) { VECCOPY(id->X[i], verts[i].x); VECCOPY(id->V[i], verts[i].v); - /* - if(verts [i].flags & CVERT_FLAG_PINNED) - { - id->S[pinned].pinned = 1; - id->S[pinned].c = id->S[pinned].r = i; - pinned++; - } - */ } - // id->S[0].vcount = pinned; } From b852223456d9b12ee2e80488ccedc5af65be48e6 Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Tue, 18 Sep 2007 14:05:36 +0000 Subject: [PATCH 013/246] arround 50% speedup in calculating spring force using OpenMP --- source/blender/blenkernel/BKE_cloth.h | 3 + source/blender/blenkernel/intern/cloth.c | 6 +- source/blender/blenkernel/intern/implicit.c | 139 +++++++++++++------- source/blender/makesdna/DNA_cloth_types.h | 3 + 4 files changed, 98 insertions(+), 53 deletions(-) diff --git a/source/blender/blenkernel/BKE_cloth.h b/source/blender/blenkernel/BKE_cloth.h index 0a50feeb9b0..b9861049fb4 100644 --- a/source/blender/blenkernel/BKE_cloth.h +++ b/source/blender/blenkernel/BKE_cloth.h @@ -52,6 +52,8 @@ struct DerivedMesh; #define DO_INLINE #endif +#define CLOTH_MAX_THREAD 2 + /* goal defines */ #define SOFTGOALSNAP 0.999f @@ -103,6 +105,7 @@ typedef enum typedef enum { CSPRING_FLAG_DEACTIVATE = (1 << 1), + CSPRING_FLAG_NEEDED = (1 << 2), // springs has values to be applied } CSPRINGS_FLAGS; // needed for buttons_object.c diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c index 40f3c9816a6..57975e56cc3 100644 --- a/source/blender/blenkernel/intern/cloth.c +++ b/source/blender/blenkernel/intern/cloth.c @@ -117,10 +117,6 @@ static CM_SOLVER_DEF solvers [] = { // { "Implicit C++", CM_IMPLICITCPP, implicitcpp_init, implicitcpp_solver, implicitcpp_free }, }; -#define DEBUG_CLOTH_VERBOSE 1000 -static int DEBUG_CLOTH = 0; - - /* ********** cloth engine ******* */ /* Prototypes for internal functions. */ @@ -774,7 +770,7 @@ void clothModifier_do(ClothModifierData *clmd, Object *ob, DerivedMesh *dm, solvers [clmd->sim_parms.solver_type].solver (ob, framenr, clmd, effectors,0,0); tend(); - printf("Cloth simulation time: %f\n", (float)tval()); + // printf("Cloth simulation time: %f\n", (float)tval()); cloth_cache_set_frame(clmd, framenr); diff --git a/source/blender/blenkernel/intern/implicit.c b/source/blender/blenkernel/intern/implicit.c index df5830f6a77..a6fcf7a9a5e 100644 --- a/source/blender/blenkernel/intern/implicit.c +++ b/source/blender/blenkernel/intern/implicit.c @@ -570,7 +570,7 @@ DO_INLINE void mul_bfmatrix_S(fmatrix3x3 *matrix, float scalar) /* STATUS: verified */ DO_INLINE void mul_bfmatrix_lfvector( float (*to)[3], fmatrix3x3 *from, float (*fLongVector)[3]) { - unsigned int i = 0,j=0; + unsigned int i = 0; zero_lfvector(to, from[0].vcount); /* process diagonal elements */ for(i = 0; i < from[0].vcount; i++) @@ -579,7 +579,8 @@ DO_INLINE void mul_bfmatrix_lfvector( float (*to)[3], fmatrix3x3 *from, float (* } /* process off-diagonal entries (every off-diagonal entry needs to be symmetric) */ -#pragma parallel for shared(to,from, fLongVector) private(i) + // TODO: pragma below is wrong, correct it! + // #pragma omp parallel for shared(to,from, fLongVector) private(i) for(i = from[0].vcount; i < from[0].vcount+from[0].scount; i++) { // muladd_fmatrix_fvector(to[from[i].c], from[i].m, fLongVector[from[i].r]); @@ -804,11 +805,13 @@ int implicit_free (ClothModifierData *clmd) return 1; } + DO_INLINE float fb(float length, float L) { float x = length/L; return (-11.541f*pow(x,4)+34.193f*pow(x,3)-39.083f*pow(x,2)+23.116f*x-9.713f); } + DO_INLINE float fbderiv(float length, float L) { float x = length/L; @@ -827,6 +830,7 @@ DO_INLINE float fbstar(float length, float L, float kb, float cb) else return tempfb; } + DO_INLINE float fbstar_jacobi(float length, float L, float kb, float cb) { float tempfb = kb * fb(length, L); @@ -841,6 +845,7 @@ DO_INLINE float fbstar_jacobi(float length, float L, float kb, float cb) return kb * fbderiv(length, L); } } + DO_INLINE void filter(lfVector *V, fmatrix3x3 *S) { unsigned int i=0; @@ -850,6 +855,7 @@ DO_INLINE void filter(lfVector *V, fmatrix3x3 *S) mul_fvector_fmatrix(V[S[i].r], V[S[i].r], S[i].m); } } + // block diagonalizer void BuildPPinv(fmatrix3x3 *lA, fmatrix3x3 *P, fmatrix3x3 *Pinv, fmatrix3x3 *S, fmatrix3x3 *bigI) { @@ -874,6 +880,7 @@ void BuildPPinv(fmatrix3x3 *lA, fmatrix3x3 *P, fmatrix3x3 *Pinv, fmatrix3x3 *S, } } + int cg_filtered(lfVector *ldV, fmatrix3x3 *lA, lfVector *lB, lfVector *z, fmatrix3x3 *S) { // Solves for unknown X in equation AX=B @@ -1101,17 +1108,20 @@ DO_INLINE void dfdx_spring_type1(float to[3][3], float dir[3],float length,float mul_fmatrix_S(temp, k); add_fmatrix_fmatrix(to, temp, to); } + DO_INLINE void dfdx_spring_type2(float to[3][3], float dir[3],float length,float L,float k, float cb) { // return outerprod(dir,dir)*fbstar_jacobi(length, L, k, cb); mul_fvectorT_fvectorS(to, dir, dir, fbstar_jacobi(length, L, k, cb)); } + DO_INLINE void dfdv_damp(float to[3][3], float dir[3], float damping) { // derivative of force wrt velocity. // return outerprod(dir,dir) * damping; mul_fvectorT_fvectorS(to, dir, dir, damping); } + DO_INLINE void dfdx_spring(float to[3][3], float dir[3],float length,float L,float k) { // dir is unit length direction, rest is spring's restlength, k is spring constant. @@ -1122,6 +1132,7 @@ DO_INLINE void dfdx_spring(float to[3][3], float dir[3],float length,float L,fl sub_fmatrix_fmatrix(to, to, I); mul_fmatrix_S(to, -k); } + DO_INLINE void dfdx_damp(float to[3][3], float dir[3],float length,const float vel[3],float rest,float damping) { // inner spring damping vel is the relative velocity of the endpoints. @@ -1132,7 +1143,7 @@ DO_INLINE void dfdx_damp(float to[3][3], float dir[3],float length,const float } -DO_INLINE void calc_spring_force(ClothModifierData *clmd, ClothSpring *s, lfVector *lF, lfVector *X, lfVector *V, fmatrix3x3 *dFdV, fmatrix3x3 *dFdX) +DO_INLINE void cloth_calc_spring_force(ClothModifierData *clmd, ClothSpring *s, lfVector *lF, lfVector *X, lfVector *V, fmatrix3x3 *dFdV, fmatrix3x3 *dFdX) { float extent[3]; float length = 0; @@ -1142,25 +1153,28 @@ DO_INLINE void calc_spring_force(ClothModifierData *clmd, ClothSpring *s, lfVect float L = s->restlen; float cb = clmd->sim_parms.structural; - float f[3] = {0,0,0}; + float nullf[3] = {0,0,0}; float stretch_force[3] = {0,0,0}; float bending_force[3] = {0,0,0}; float damping_force[3] = {0,0,0}; - float dfdx[3][3]={ {0,0,0}, {0,0,0}, {0,0,0}}; - float dfdv[3][3]; - int needed = 0; + float nulldfdx[3][3]={ {0,0,0}, {0,0,0}, {0,0,0}}; Cloth *cloth = clmd->clothObject; ClothVertex *verts = cloth->verts; + + VECCOPY(s->f, nullf); + cp_fmatrix(s->dfdx, nulldfdx); + cp_fmatrix(s->dfdv, nulldfdx); // calculate elonglation VECSUB(extent, X[s->kl], X[s->ij]); VECSUB(vel, V[s->kl], V[s->ij]); length = sqrt(INPR(extent, extent)); - + s->flags &= ~CSPRING_FLAG_NEEDED; if(length > ABS(ALMOST_ZERO)) { + /* if(length>L) { if((clmd->sim_parms.flags & CSIMSETT_FLAG_TEARING_ENABLED) @@ -1170,7 +1184,7 @@ DO_INLINE void calc_spring_force(ClothModifierData *clmd, ClothSpring *s, lfVect return; } } - + */ mul_fvector_S(dir, extent, 1.0f/length); } else @@ -1184,55 +1198,37 @@ DO_INLINE void calc_spring_force(ClothModifierData *clmd, ClothSpring *s, lfVect { if(length > L) // only on elonglation { - needed++; + s->flags |= CSPRING_FLAG_NEEDED; k = clmd->sim_parms.structural; mul_fvector_S(stretch_force, dir, (k*(length-L))); - VECADD(f, f, stretch_force); + VECADD(s->f, s->f, stretch_force); // Ascher & Boxman, p.21: Damping only during elonglation mul_fvector_S(damping_force, extent, clmd->sim_parms.Cdis * ((INPR(vel,extent)/length))); - VECADD(f, f, damping_force); + VECADD(s->f, s->f, damping_force); - dfdx_spring_type1(dfdx, dir,length,L,k); + dfdx_spring_type1(s->dfdx, dir,length,L,k); - dfdv_damp(dfdv, dir,clmd->sim_parms.Cdis); - - sub_fmatrix_fmatrix(dFdV[s->ij].m, dFdV[s->ij].m, dfdv); - - sub_fmatrix_fmatrix(dFdV[s->kl].m, dFdV[s->kl].m, dfdv); - - add_fmatrix_fmatrix(dFdV[s->matrix_index].m, dFdV[s->matrix_index].m, dfdv); - + dfdv_damp(s->dfdv, dir,clmd->sim_parms.Cdis); } } else // calculate force of bending springs { if(length < L) { - k = clmd->sim_parms.bending; - - needed++; + s->flags |= CSPRING_FLAG_NEEDED; + + k = clmd->sim_parms.bending; mul_fvector_S(bending_force, dir, fbstar(length, L, k, cb)); - VECADD(f, f, bending_force); + VECADD(s->f, s->f, bending_force); - dfdx_spring_type2(dfdx, dir,length,L,k, cb); + dfdx_spring_type2(s->dfdx, dir,length,L,k, cb); } } - - if(needed) - { - VECADD(lF[s->ij], lF[s->ij], f); - VECSUB(lF[s->kl], lF[s->kl], f); - - sub_fmatrix_fmatrix(dFdX[s->ij].m, dFdX[s->ij].m, dfdx); - sub_fmatrix_fmatrix(dFdX[s->kl].m, dFdX[s->kl].m, dfdx); - - add_fmatrix_fmatrix(dFdX[s->matrix_index].m, dFdX[s->matrix_index].m, dfdx); - } } DO_INLINE void calculateTriangleNormal(float to[3], lfVector *X, MFace mface) @@ -1275,7 +1271,7 @@ DO_INLINE void calc_triangle_force(ClothModifierData *clmd, MFace mface, lfVecto } -void calc_force(ClothModifierData *clmd, lfVector *lF, lfVector *lX, lfVector *lV, fmatrix3x3 *dFdV, fmatrix3x3 *dFdX, ListBase *effectors, float time) +void cloth_calc_force(ClothModifierData *clmd, lfVector *lF, lfVector *lX, lfVector *lV, fmatrix3x3 *dFdV, fmatrix3x3 *dFdX, ListBase *effectors, float time) { /* Collect forces and derivatives: F,dFdX,dFdV */ Cloth *cloth = clmd->clothObject; @@ -1332,9 +1328,10 @@ void calc_force(ClothModifierData *clmd, lfVector *lF, lfVector *lX, lfVector *l /* handle external forces like wind */ if(effectors) { - float wind[3] = {0,1.0f,0}; + float wind[3] = {0.0f,1.0f,0.0f}; float force[3]= {0.0f, 0.0f, 0.0f}; - + + #pragma omp parallel for private (i) shared(lF) for(i = 0; i < cloth->numverts; i++) { float vertexnormal[3]={0,0,0}; @@ -1348,17 +1345,55 @@ void calc_force(ClothModifierData *clmd, lfVector *lF, lfVector *lX, lfVector *l VECADDS(lF[i], lF[i], wind_normalized, -calculateVertexWindForce(i, wind, vertexnormal)); } } - + /* calculate and apply spring forces */ +#pragma omp parallel private(i) + { +#pragma omp for nowait + for(i = 0; i < cloth->numsprings/2; i++) + { + // only handle active springs + // if(((clmd->sim_parms.flags & CSIMSETT_FLAG_TEARING_ENABLED) && !(springs[i].flags & CSPRING_FLAG_DEACTIVATE))|| !(clmd->sim_parms.flags & CSIMSETT_FLAG_TEARING_ENABLED)) + // { + cloth_calc_spring_force(clmd, &springs[i], lF, lX, lV, dFdV, dFdX); + // } + } +#pragma omp for nowait + for(i = cloth->numsprings/2; i < cloth->numsprings; i++) + { + // only handle active springs + // if(((clmd->sim_parms.flags & CSIMSETT_FLAG_TEARING_ENABLED) && !(springs[i].flags & CSPRING_FLAG_DEACTIVATE))|| !(clmd->sim_parms.flags & CSIMSETT_FLAG_TEARING_ENABLED)) + // { + cloth_calc_spring_force(clmd, &springs[i], lF, lX, lV, dFdV, dFdX); + // } + } +#pragma omp for nowait for(i = 0; i < cloth->numsprings; i++) { // only handle active springs - if(((clmd->sim_parms.flags & CSIMSETT_FLAG_TEARING_ENABLED) && !(springs[i].flags & CSPRING_FLAG_DEACTIVATE))|| !(clmd->sim_parms.flags & CSIMSETT_FLAG_TEARING_ENABLED)) + // if(((clmd->sim_parms.flags & CSIMSETT_FLAG_TEARING_ENABLED) && !(springs[i].flags & CSPRING_FLAG_DEACTIVATE))|| !(clmd->sim_parms.flags & CSIMSETT_FLAG_TEARING_ENABLED)) { - calc_spring_force(clmd, &springs[i], lF, lX, lV, dFdV, dFdX); + ClothSpring *s = &springs[i]; + if(s->flags & CSPRING_FLAG_NEEDED) + { + if(s->type != BENDING) + { + sub_fmatrix_fmatrix(dFdV[s->ij].m, dFdV[s->ij].m, s->dfdv); + sub_fmatrix_fmatrix(dFdV[s->kl].m, dFdV[s->kl].m, s->dfdv); + add_fmatrix_fmatrix(dFdV[s->matrix_index].m, dFdV[s->matrix_index].m, s->dfdv); + } + + VECADD(lF[s->ij], lF[s->ij], s->f); + VECSUB(lF[s->kl], lF[s->kl], s->f); + + sub_fmatrix_fmatrix(dFdX[s->ij].m, dFdX[s->ij].m, s->dfdx); + sub_fmatrix_fmatrix(dFdX[s->kl].m, dFdX[s->kl].m, s->dfdx); + + add_fmatrix_fmatrix(dFdX[s->matrix_index].m, dFdX[s->matrix_index].m, s->dfdx); + } } } - + } } void simulate_implicit_euler(lfVector *Vnew, lfVector *lX, lfVector *lV, lfVector *lF, fmatrix3x3 *dFdV, fmatrix3x3 *dFdX, float dt, fmatrix3x3 *A, lfVector *B, lfVector *dV, fmatrix3x3 *S, lfVector *z, lfVector *olddV) @@ -1375,12 +1410,20 @@ void simulate_implicit_euler(lfVector *Vnew, lfVector *lX, lfVector *lV, lfVecto mul_bfmatrix_lfvector(dFdXmV, dFdX, lV); add_lfvectorS_lfvectorS(B, lF, dt, dFdXmV, (dt*dt), numverts); + + itstart(); + cg_filtered(dV, A, B, z, S); /* conjugate gradient algorithm to solve Ax=b */ // cg_filtered_pre(dV, A, B, z, olddV, dt); + + itend(); + // printf("cg_filtered calc time: %f\n", (float)itval()); + cp_lfvector(olddV, dV, numverts); // advance velocities add_lfvector_lfvector(Vnew, lV, dV, numverts); + del_lfvector(dFdXmV); } @@ -1415,13 +1458,13 @@ int implicit_solver (Object *ob, float frame, ClothModifierData *clmd, ListBase effectors= pdInitEffectors(ob,NULL); // calculate - calc_force(clmd, id->F, id->X, id->V, id->dFdV, id->dFdX, effectors, step ); + cloth_calc_force(clmd, id->F, id->X, id->V, id->dFdV, id->dFdX, effectors, step ); simulate_implicit_euler(id->Vnew, id->X, id->V, id->F, id->dFdV, id->dFdX, dt, id->A, id->B, id->dV, id->S, id->z, id->olddV); add_lfvector_lfvectorS(id->Xnew, id->X, id->Vnew, dt, numverts); // collisions - itstart(); + // itstart(); // update verts to current positions for(i = 0; i < numverts; i++) @@ -1477,11 +1520,11 @@ int implicit_solver (Object *ob, float frame, ClothModifierData *clmd, ListBase cp_lfvector(id->V, id->Vnew, numverts); // calculate - calc_force(clmd, id->F, id->X, id->V, id->dFdV, id->dFdX, effectors, step); + cloth_calc_force(clmd, id->F, id->X, id->V, id->dFdV, id->dFdX, effectors, step); simulate_implicit_euler(id->Vnew, id->X, id->V, id->F, id->dFdV, id->dFdX, dt / 2.0f, id->A, id->B, id->dV, id->S, id->z, id->olddV); } - itend(); + // itend(); // printf("collision time: %f\n", (float)itval()); // V = Vnew; diff --git a/source/blender/makesdna/DNA_cloth_types.h b/source/blender/makesdna/DNA_cloth_types.h index c756c29f467..c0a47452e3e 100644 --- a/source/blender/makesdna/DNA_cloth_types.h +++ b/source/blender/makesdna/DNA_cloth_types.h @@ -64,6 +64,9 @@ typedef struct ClothSpring { int matrix_index; /* needed for implicit */ int type; int flags; /* defined in BKE_cloth.h, e.g. deactivated due to tearing */ + float dfdx[3][3]; + float dfdv[3][3]; + float f[3]; } ClothSpring; From 98e8486bafc3cb506bb9dead50e9ca9ddbbf857d Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Tue, 18 Sep 2007 19:56:58 +0000 Subject: [PATCH 014/246] Fix: kicked springs caching since it's unused and needs lots of memory --- source/blender/blenkernel/intern/cloth.c | 16 ++++++++++------ source/blender/blenkernel/intern/implicit.c | 17 ++++++++--------- 2 files changed, 18 insertions(+), 15 deletions(-) diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c index 57975e56cc3..194aa06fc3b 100644 --- a/source/blender/blenkernel/intern/cloth.c +++ b/source/blender/blenkernel/intern/cloth.c @@ -518,12 +518,13 @@ void cloth_cache_get_frame(ClothModifierData *clmd, float time) memcpy(cloth->verts, frame->verts, cloth->numverts*sizeof(ClothVertex)); implicit_set_positions(clmd); } - + /* if(frame->springs) { // copy ClothSpring struct memcpy(cloth->springs, frame->springs, cloth->numsprings*sizeof(ClothSpring)); } + */ } } } @@ -546,7 +547,10 @@ void cloth_cache_set_frame(ClothModifierData *clmd, float time) // creat new frame cache frame = (Frame *)MEM_callocN(sizeof(Frame), "cloth frame cache"); frame->verts = (ClothVertex *)MEM_callocN(sizeof(ClothVertex)*cloth->numverts, "cloth frame vertex cache"); + frame->springs = NULL; + /* frame->springs = (ClothSpring *)MEM_callocN(sizeof(ClothSpring)*cloth->numsprings, "cloth frame spring cache"); + */ frame->time = newtime; // copy ClothVertex struct @@ -554,13 +558,13 @@ void cloth_cache_set_frame(ClothModifierData *clmd, float time) { memcpy(&frame->verts[i], &cloth->verts[i], sizeof(ClothVertex)); } - + /* // copy ClothSpring struct for(i = 0; i < cloth->numsprings; i++) { memcpy(&frame->springs[i], &cloth->springs[i], sizeof(ClothSpring)); } - + */ } if(frame) { @@ -600,7 +604,7 @@ void cloth_cache_free(ClothModifierData *clmd, float time) && (frame->time > newtime)) // do not delete the first frame { MEM_freeN(frame->verts); - MEM_freeN(frame->springs); + // MEM_freeN(frame->springs); MEM_freeN(frame); MEM_freeN(search); last_search->next = next; @@ -608,7 +612,7 @@ void cloth_cache_free(ClothModifierData *clmd, float time) else if(clmd->sim_parms.flags & CSIMSETT_FLAG_CCACHE_FREE_ALL) // free COMPLETE cache { MEM_freeN(frame->verts); - MEM_freeN(frame->springs); + // MEM_freeN(frame->springs); MEM_freeN(frame); } else @@ -770,7 +774,7 @@ void clothModifier_do(ClothModifierData *clmd, Object *ob, DerivedMesh *dm, solvers [clmd->sim_parms.solver_type].solver (ob, framenr, clmd, effectors,0,0); tend(); - // printf("Cloth simulation time: %f\n", (float)tval()); + printf("Cloth simulation time: %f\n", (float)tval()); cloth_cache_set_frame(clmd, framenr); diff --git a/source/blender/blenkernel/intern/implicit.c b/source/blender/blenkernel/intern/implicit.c index a6fcf7a9a5e..3b19839c77d 100644 --- a/source/blender/blenkernel/intern/implicit.c +++ b/source/blender/blenkernel/intern/implicit.c @@ -947,7 +947,7 @@ int cg_filtered(lfVector *ldV, fmatrix3x3 *lA, lfVector *lB, lfVector *z, fmatr return conjgrad_loopcountnumsprings/2; i++) { @@ -1367,7 +1367,8 @@ void cloth_calc_force(ClothModifierData *clmd, lfVector *lF, lfVector *lX, lfVec cloth_calc_spring_force(clmd, &springs[i], lF, lX, lV, dFdV, dFdX); // } } -#pragma omp for nowait +} // pragma omp parallel + for(i = 0; i < cloth->numsprings; i++) { // only handle active springs @@ -1393,15 +1394,13 @@ void cloth_calc_force(ClothModifierData *clmd, lfVector *lF, lfVector *lX, lfVec } } } - } } -void simulate_implicit_euler(lfVector *Vnew, lfVector *lX, lfVector *lV, lfVector *lF, fmatrix3x3 *dFdV, fmatrix3x3 *dFdX, float dt, fmatrix3x3 *A, lfVector *B, lfVector *dV, fmatrix3x3 *S, lfVector *z, lfVector *olddV) +void simulate_implicit_euler(lfVector *Vnew, lfVector *lX, lfVector *lV, lfVector *lF, fmatrix3x3 *dFdV, fmatrix3x3 *dFdX, float dt, fmatrix3x3 *A, lfVector *B, lfVector *dV, fmatrix3x3 *S, lfVector *z, lfVector *olddV, fmatrix3x3 *P, fmatrix3x3 *Pinv) { unsigned int numverts = dFdV[0].vcount; lfVector *dFdXmV = create_lfvector(numverts); - initdiag_bfmatrix(A, I); zero_lfvector(dV, numverts); @@ -1414,7 +1413,7 @@ void simulate_implicit_euler(lfVector *Vnew, lfVector *lX, lfVector *lV, lfVecto itstart(); cg_filtered(dV, A, B, z, S); /* conjugate gradient algorithm to solve Ax=b */ - // cg_filtered_pre(dV, A, B, z, olddV, dt); + // cg_filtered_pre(dV, A, B, z, olddV, P, Pinv, dt); itend(); // printf("cg_filtered calc time: %f\n", (float)itval()); @@ -1459,7 +1458,7 @@ int implicit_solver (Object *ob, float frame, ClothModifierData *clmd, ListBase // calculate cloth_calc_force(clmd, id->F, id->X, id->V, id->dFdV, id->dFdX, effectors, step ); - simulate_implicit_euler(id->Vnew, id->X, id->V, id->F, id->dFdV, id->dFdX, dt, id->A, id->B, id->dV, id->S, id->z, id->olddV); + simulate_implicit_euler(id->Vnew, id->X, id->V, id->F, id->dFdV, id->dFdX, dt, id->A, id->B, id->dV, id->S, id->z, id->olddV, id->P, id->Pinv); add_lfvector_lfvectorS(id->Xnew, id->X, id->Vnew, dt, numverts); @@ -1521,7 +1520,7 @@ int implicit_solver (Object *ob, float frame, ClothModifierData *clmd, ListBase // calculate cloth_calc_force(clmd, id->F, id->X, id->V, id->dFdV, id->dFdX, effectors, step); - simulate_implicit_euler(id->Vnew, id->X, id->V, id->F, id->dFdV, id->dFdX, dt / 2.0f, id->A, id->B, id->dV, id->S, id->z, id->olddV); + simulate_implicit_euler(id->Vnew, id->X, id->V, id->F, id->dFdV, id->dFdX, dt / 2.0f, id->A, id->B, id->dV, id->S, id->z, id->olddV, id->P, id->Pinv); } // itend(); From 6e755b908951e85c03e15d1e836413ecac58f4bf Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Wed, 19 Sep 2007 08:07:47 +0000 Subject: [PATCH 015/246] Fixed wind force direction (reported by mfoxdogg) --- source/blender/blenkernel/intern/collision.c | 8 ++++---- source/blender/blenkernel/intern/implicit.c | 2 +- source/blender/blenkernel/intern/kdop.c | 8 ++++---- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/source/blender/blenkernel/intern/collision.c b/source/blender/blenkernel/intern/collision.c index 13327c16006..c70bf461920 100644 --- a/source/blender/blenkernel/intern/collision.c +++ b/source/blender/blenkernel/intern/collision.c @@ -403,7 +403,7 @@ double implicit_tri_check_coherence (ClothModifierData *clmd, ClothModifierData VECCOPY(b[0], cloth2->verts[face2->v1].txold); VECCOPY(b[1], cloth2->verts[face2->v2].txold); VECCOPY(b[2], cloth2->verts[face2->v3].txold); -#pragma omp critical + distance = plNearestPoints(a,b,pa,pb,normal); quadA = quadB = 0; @@ -450,7 +450,7 @@ double implicit_tri_check_coherence (ClothModifierData *clmd, ClothModifierData VECCOPY(b[0], cloth2->verts[indexD].txold); VECCOPY(b[1], cloth2->verts[indexE].txold); VECCOPY(b[2], cloth2->verts[indexF].txold); -#pragma omp critical + tempdistance = plNearestPoints(a,b,tpa,tpb,tnormal); if(tempdistance < distance) @@ -531,7 +531,7 @@ int cloth_bvh_objcollision(ClothModifierData * clmd, float step, CM_COLLISION_RE cloth = clmd->clothObject; cloth_bvh = (BVH *) cloth->tree; numverts = clmd->clothObject->numverts; - + //////////////////////////////////////////////////////////// // static collisions //////////////////////////////////////////////////////////// @@ -586,7 +586,7 @@ int cloth_bvh_objcollision(ClothModifierData * clmd, float step, CM_COLLISION_RE bvh_traverse(clmd, coll_clmd, cloth_bvh->root, coll_bvh->root, step, collision_response); result += collision_static(clmd, coll_clmd, collision_list); - + printf("result: %d\n", result); // calculate velocities // free temporary list diff --git a/source/blender/blenkernel/intern/implicit.c b/source/blender/blenkernel/intern/implicit.c index 3b19839c77d..cfe17376797 100644 --- a/source/blender/blenkernel/intern/implicit.c +++ b/source/blender/blenkernel/intern/implicit.c @@ -1342,7 +1342,7 @@ void cloth_calc_force(ClothModifierData *clmd, lfVector *lF, lfVector *lX, lfVec Normalize(wind_normalized); calculateWeightedVertexNormal(clmd, mfaces, vertexnormal, i, lX); - VECADDS(lF[i], lF[i], wind_normalized, -calculateVertexWindForce(i, wind, vertexnormal)); + VECADDS(lF[i], lF[i], wind_normalized, calculateVertexWindForce(i, wind, vertexnormal)); } } diff --git a/source/blender/blenkernel/intern/kdop.c b/source/blender/blenkernel/intern/kdop.c index 0d9fddf0211..0088ff92364 100644 --- a/source/blender/blenkernel/intern/kdop.c +++ b/source/blender/blenkernel/intern/kdop.c @@ -728,7 +728,7 @@ DO_INLINE int bvh_overlap(float *bv1, float *bv2) */ int bvh_traverse(ClothModifierData * clmd, ClothModifierData * coll_clmd, Tree * tree1, Tree * tree2, float step, CM_COLLISION_RESPONSE collision_response) { - int i = 0, j = 0, ret=0; + int i = 0, ret=0; /* // Shouldn't be possible @@ -750,7 +750,7 @@ int bvh_traverse(ClothModifierData * clmd, ClothModifierData * coll_clmd, Tree * if(collision_response) collision_response (clmd, coll_clmd, tree1, tree2); - ret = 1; + return 1; } else { @@ -766,10 +766,10 @@ int bvh_traverse(ClothModifierData * clmd, ClothModifierData * coll_clmd, Tree * else { // Process the quad tree. - for (j = 0; j < 4; j++) + for (i = 0; i < 4; i++) { // Only traverse nodes that exist. - if (tree1->nodes [j] && bvh_traverse (clmd, coll_clmd, tree1->nodes[j], tree2, step, collision_response)) + if (tree1->nodes [i] && bvh_traverse (clmd, coll_clmd, tree1->nodes[i], tree2, step, collision_response)) ret = 1; } } From 4c7c711b8a7fb14e15934fa300bfcef2f038c4f7 Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Wed, 19 Sep 2007 12:13:16 +0000 Subject: [PATCH 016/246] Fixed collision object init, New: Apply collision impulses so minimum distance is preserved (friction still missing) --- source/blender/blenkernel/intern/cloth.c | 41 ++++----- source/blender/blenkernel/intern/collision.c | 92 +++++++++++++------- source/blender/blenkernel/intern/implicit.c | 1 + source/blender/src/buttons_object.c | 1 - 4 files changed, 84 insertions(+), 51 deletions(-) diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c index 194aa06fc3b..635da0515cb 100644 --- a/source/blender/blenkernel/intern/cloth.c +++ b/source/blender/blenkernel/intern/cloth.c @@ -657,24 +657,28 @@ void clothModifier_do(ClothModifierData *clmd, Object *ob, DerivedMesh *dm, Frame *frame = NULL; LinkNode *search = NULL; float deltaTime = current_time - clmd->sim_parms.sim_time; + // only be active during a specific period - if(current_time < clmd->sim_parms.firstframe) - return; - else if(current_time > clmd->sim_parms.lastframe) + if (!(clmd->sim_parms.flags & CSIMSETT_FLAG_COLLOBJ)) { - int frametime = cloth_cache_last_frame(clmd); - if(cloth_cache_search_frame(clmd, frametime)) - { - cloth_cache_get_frame(clmd, frametime); - cloth_to_object (ob, clmd, vertexCos, numverts); - } - return; - } - else if(ABS(deltaTime) >= 2.0f ) // no timewarps allowed - { - if(!cloth_cache_search_frame(clmd, framenr)) + if(current_time < clmd->sim_parms.firstframe) return; + else if(current_time > clmd->sim_parms.lastframe) + { + int frametime = cloth_cache_last_frame(clmd); + if(cloth_cache_search_frame(clmd, frametime)) + { + cloth_cache_get_frame(clmd, frametime); + cloth_to_object (ob, clmd, vertexCos, numverts); + } + return; + } + else if(ABS(deltaTime) >= 2.0f ) // no timewarps allowed + { + if(!cloth_cache_search_frame(clmd, framenr)) + return; + } } // unused in the moment @@ -693,8 +697,7 @@ void clothModifier_do(ClothModifierData *clmd, Object *ob, DerivedMesh *dm, // This is for collisions objects: check special case CSIMSETT_FLAG_COLLOBJ if (clmd->sim_parms.flags & CSIMSETT_FLAG_COLLOBJ) - { - + { // save next position + time if ((clmd->clothObject == NULL) || (numverts != clmd->clothObject->numverts) ) { @@ -723,7 +726,8 @@ void clothModifier_do(ClothModifierData *clmd, Object *ob, DerivedMesh *dm, VECCOPY (verts->x, vertexCos[i]); Mat4MulVecfl(ob->obmat, verts->x); - // Compute the vertices velocity. + // Compute the vertices "velocity". + // (no dt correction here because of float error) VECSUB (verts->v, verts->x, verts->xold); } @@ -762,9 +766,6 @@ void clothModifier_do(ClothModifierData *clmd, Object *ob, DerivedMesh *dm, /* Get the current position. */ VECCOPY (verts->xconst, vertexCos[i]); Mat4MulVecfl(ob->obmat, verts->xconst); - - /* Compute the vertices velocity. */ - VECSUB (verts->v, verts->xconst, verts->xold); } tstart(); diff --git a/source/blender/blenkernel/intern/collision.c b/source/blender/blenkernel/intern/collision.c index c70bf461920..32a2f820894 100644 --- a/source/blender/blenkernel/intern/collision.c +++ b/source/blender/blenkernel/intern/collision.c @@ -216,18 +216,18 @@ DO_INLINE void interpolateOnTriangle(float to[3], float v1[3], float v2[3], floa VECADDMUL(to, v3, w3); } + DO_INLINE void calculateFrictionImpulse(float to[3], float vrel[3], float normal[3], double normalVelocity, double frictionConstant, double delta_V_n) { float vrel_t_pre[3]; float vrel_t[3]; VECSUBS(vrel_t_pre, vrel, normal, normalVelocity); - VECCOPY(vrel_t, vrel_t_pre); - VecMulf(vrel_t, MAX2(1.0f - frictionConstant * delta_V_n / INPR(vrel_t_pre,vrel_t_pre), 0.0f)); - VECSUB(to, vrel_t_pre, vrel_t); - VecMulf(to, 1.0f / 2.0f); + VECCOPY(to, vrel_t_pre); + VecMulf(to, MAX2(1.0f - frictionConstant * delta_V_n / INPR(vrel_t_pre,vrel_t_pre), 0.0f)); } + int collision_static(ClothModifierData *clmd, ClothModifierData *coll_clmd, LinkNode **collision_list) { unsigned int i = 0, numverts=0; @@ -271,6 +271,7 @@ int collision_static(ClothModifierData *clmd, ClothModifierData *coll_clmd, Link face2 = &(cloth2->mfaces[collpair->face2]); // compute barycentric coordinates for both collision points + if(!collpair->quadA) bvh_compute_barycentric(collpair->p1, cloth1->verts[face1->v1].txold, @@ -297,16 +298,17 @@ int collision_static(ClothModifierData *clmd, ClothModifierData *coll_clmd, Link cloth2->verts[face2->v3].txold, &u1, &u2, &u3); - // Calculate relative velocity. + // Calculate relative "velocity". + if(!collpair->quadA) - interpolateOnTriangle(v1, cloth1->verts[face1->v1].v, cloth1->verts[face1->v2].v, cloth1->verts[face1->v3].v, w1, w2, w3); + interpolateOnTriangle(v1, cloth1->verts[face1->v1].tv, cloth1->verts[face1->v2].tv, cloth1->verts[face1->v3].tv, w1, w2, w3); else - interpolateOnTriangle(v1, cloth1->verts[face1->v4].v, cloth1->verts[face1->v1].v, cloth1->verts[face1->v3].v, w1, w2, w3); + interpolateOnTriangle(v1, cloth1->verts[face1->v4].tv, cloth1->verts[face1->v1].tv, cloth1->verts[face1->v3].tv, w1, w2, w3); if(!collpair->quadB) - interpolateOnTriangle(v2, cloth2->verts[face2->v1].v, cloth2->verts[face2->v2].v, cloth2->verts[face2->v3].v, u1, u2, u3); + interpolateOnTriangle(v2, cloth2->verts[face2->v1].tv, cloth2->verts[face2->v2].tv, cloth2->verts[face2->v3].tv, u1, u2, u3); else - interpolateOnTriangle(v2, cloth2->verts[face2->v4].v, cloth2->verts[face2->v1].v, cloth2->verts[face2->v3].v, u1, u2, u3); + interpolateOnTriangle(v2, cloth2->verts[face2->v4].tv, cloth2->verts[face2->v1].tv, cloth2->verts[face2->v3].tv, u1, u2, u3); VECSUB(relativeVelocity, v1, v2); @@ -323,18 +325,22 @@ int collision_static(ClothModifierData *clmd, ClothModifierData *coll_clmd, Link // Calculate Impulse magnitude to stop all motion in normal direction. // const double I_mag = v_n_mag / (1/m1 + 1/m2); float magnitude_i = magrelVel / 2.0f; // TODO implement masses - float tangential[3], magtangent; + float tangential[3], magtangent, magnormal, collvel[3]; + float vrel_t_pre[3]; + float vrel_t[3], impulse; + float epsilon = clmd->coll_parms.epsilon; - calculateFrictionImpulse(tangential, relativeVelocity, collpair->normal, magrelVel, clmd->coll_parms.friction*0.01, magrelVel); + // calculateFrictionImpulse(tangential, relativeVelocity, collpair->normal, magrelVel, clmd->coll_parms.friction*0.01, magrelVel); - magtangent = INPR(tangential, tangential); + // magtangent = INPR(tangential, tangential); // Apply friction impulse. if (magtangent > ALMOST_ZERO) { - /* - printf("friction applied: %f\n", magtangent); + + // printf("friction applied: %f\n", magtangent); // TODO check original code + /* VECSUB(cloth1->verts[face1->v1].tv, cloth1->verts[face1->v1].tv,tangential); VECSUB(cloth1->verts[face1->v1].tv, cloth1->verts[face1->v2].tv,tangential); VECSUB(cloth1->verts[face1->v1].tv, cloth1->verts[face1->v3].tv,tangential); @@ -345,26 +351,52 @@ int collision_static(ClothModifierData *clmd, ClothModifierData *coll_clmd, Link // printf("magnitude_i: %f\n", magnitude_i); // negative before collision in my case // Apply the impulse and increase impulse counters. - /* - VECADDMUL(cloth1->verts[face1->v1].tv,collpair->normal, -magnitude_i); - VECADDMUL(cloth1->verts[face1->v2].tv,collpair->normal, -magnitude_i); - VECADDMUL(cloth1->verts[face1->v3].tv,collpair->normal, -magnitude_i); - VECADDMUL(cloth1->verts[face1->v4].tv,collpair->normal, -magnitude_i); - */ + // my try, works better than the papers ones (maybe i did just something wrong) + VECSUB(collvel, cloth1->verts[face1->v1].tv, v2); + magnormal = INPR(collvel, collpair->normal); + if(magnormalverts[face1->v1].tv, collpair->normal); - VECADDMUL(cloth1->verts[face1->v1].tv, collpair->normal, -magtangent); + impulse = (epsilon + ALMOST_ZERO-collpair->distance) / 4.0f; + VECADDMUL(cloth1->verts[face1->v1].tv, collpair->normal, -magnormal + impulse); - magtangent = INPR(cloth1->verts[face1->v2].tv, collpair->normal); - VECADDMUL(cloth1->verts[face1->v2].tv, collpair->normal, -magtangent); + // calculateFrictionImpulse(tangential, collvel, collpair->normal, magtangent, clmd->coll_parms.friction*0.01, magtangent); - magtangent = INPR(cloth1->verts[face1->v3].tv, collpair->normal); - VECADDMUL(cloth1->verts[face1->v3].tv, collpair->normal, -magtangent); +/* + VECSUBS(vrel_t_pre, collvel, collpair->normal, magnormal); + // VecMulf(vrel_t_pre, clmd->coll_parms.friction*0.01f/INPR(vrel_t_pre,vrel_t_pre)); + magtangent = Normalize(vrel_t_pre); + VecMulf(vrel_t_pre, MIN2(clmd->coll_parms.friction*0.01f*magnormal,magtangent)); - magtangent = INPR(cloth1->verts[face1->v4].tv, collpair->normal); - VECADDMUL(cloth1->verts[face1->v4].tv, collpair->normal, -magtangent); + VECSUB(cloth1->verts[face1->v1].tv, cloth1->verts[face1->v1].tv,vrel_t_pre); +*/ + VECSUB(collvel, cloth1->verts[face1->v2].tv, v2); + magnormal = INPR(collvel, collpair->normal); + if(magnormaldistance) / 4.0f; + VECADDMUL(cloth1->verts[face1->v2].tv, collpair->normal, -magnormal+ impulse); + + + VECSUB(collvel, cloth1->verts[face1->v3].tv, v2); + magnormal = INPR(collvel, collpair->normal); + if(magnormaldistance) / 4.0f; + VECADDMUL(cloth1->verts[face1->v3].tv, collpair->normal, -magnormal+ impulse); + + + VECSUB(collvel, cloth1->verts[face1->v4].tv, v2); + magnormal = INPR(collvel, collpair->normal); + if(magnormaldistance) / 4.0f; + VECADDMUL(cloth1->verts[face1->v4].tv, collpair->normal, -magnormal+ impulse); + result = 1; } @@ -586,7 +618,7 @@ int cloth_bvh_objcollision(ClothModifierData * clmd, float step, CM_COLLISION_RE bvh_traverse(clmd, coll_clmd, cloth_bvh->root, coll_bvh->root, step, collision_response); result += collision_static(clmd, coll_clmd, collision_list); - printf("result: %d\n", result); + // calculate velocities // free temporary list diff --git a/source/blender/blenkernel/intern/implicit.c b/source/blender/blenkernel/intern/implicit.c index cfe17376797..c54897cc89c 100644 --- a/source/blender/blenkernel/intern/implicit.c +++ b/source/blender/blenkernel/intern/implicit.c @@ -1484,6 +1484,7 @@ int implicit_solver (Object *ob, float frame, ClothModifierData *clmd, ListBase VECCOPY(verts[i].tx, id->Xnew[i]); VECSUB(verts[i].tv, verts[i].tx, verts[i].txold); + VECSUB(verts[i].v, verts[i].tx, verts[i].txold); } // call collision function diff --git a/source/blender/src/buttons_object.c b/source/blender/src/buttons_object.c index 2106525e9b2..1e3439d41b5 100644 --- a/source/blender/src/buttons_object.c +++ b/source/blender/src/buttons_object.c @@ -3103,7 +3103,6 @@ static void object_panel_cloth(Object *ob) if(clmd) { but = uiDefButBitI(block, TOG, CSIMSETT_FLAG_COLLOBJ, B_EFFECT_DEP, "Collision Object", 170,200,130,20, &clmd->sim_parms.flags, 0, 0, 0, 0, "Sets object to become a cloth collision object"); - // uiButSetFunc(but, object_cloth__enabletoggle, ob, NULL); if (!(clmd->sim_parms.flags & CSIMSETT_FLAG_COLLOBJ)) { From 5b9140a2093852f58e9d2de8fcc5c0db6b98ea3c Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Fri, 21 Sep 2007 13:34:19 +0000 Subject: [PATCH 017/246] Fixed some collision response issues. (weekend commit, some half done work in) --- .../BulletDynamics/Dynamics/Bullet-C-Api.cpp | 5 +- source/blender/blenkernel/BKE_cloth.h | 3 +- source/blender/blenkernel/intern/cloth.c | 121 +++-- source/blender/blenkernel/intern/collision.c | 500 ++++++++++-------- source/blender/blenkernel/intern/implicit.c | 2 +- source/blender/blenkernel/intern/modifier.c | 7 +- source/blender/makesdna/DNA_cloth_types.h | 22 +- source/blender/src/buttons_object.c | 7 +- 8 files changed, 388 insertions(+), 279 deletions(-) diff --git a/extern/bullet2/src/BulletDynamics/Dynamics/Bullet-C-Api.cpp b/extern/bullet2/src/BulletDynamics/Dynamics/Bullet-C-Api.cpp index 2ae30e851dc..1b843774609 100644 --- a/extern/bullet2/src/BulletDynamics/Dynamics/Bullet-C-Api.cpp +++ b/extern/bullet2/src/BulletDynamics/Dynamics/Bullet-C-Api.cpp @@ -41,11 +41,10 @@ double plNearestPoints(float p[3][3], float q[3][3], float *pa, float *pb, float static btGjkEpaPenetrationDepthSolver Solver0; static btMinkowskiPenetrationDepthSolver Solver1; - + btConvexPenetrationDepthSolver* Solver = NULL; - Solver = &Solver1; - + Solver = &Solver0; btGjkPairDetector convexConvex(&trishapeA ,&trishapeB,&sGjkSimplexSolver,Solver); diff --git a/source/blender/blenkernel/BKE_cloth.h b/source/blender/blenkernel/BKE_cloth.h index b9861049fb4..e4d1fb0ca99 100644 --- a/source/blender/blenkernel/BKE_cloth.h +++ b/source/blender/blenkernel/BKE_cloth.h @@ -60,7 +60,7 @@ struct DerivedMesh; /* This is approximately the smallest number that can be * represented by a float, given its precision. */ -#define ALMOST_ZERO 0.0000001 +#define ALMOST_ZERO 0.00001 /* Bits to or into the ClothVertex.flags. */ #define CVERT_FLAG_PINNED 1 @@ -91,6 +91,7 @@ typedef enum CSIMSETT_FLAG_CCACHE_FREE_ALL = (1 << 4), // delete all from cache CSIMSETT_FLAG_CCACHE_FREE_PART = (1 << 5), // delete some part of cache CSIMSETT_FLAG_TEARING_ENABLED = (1 << 6), // true if tearing is enabled + CSIMSETT_FLAG_CCACHE_PROTECT = (1 << 7), // true if tearing is enabled } CSIMSETT_FLAGS; /* Spring types as defined in the paper.*/ diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c index 635da0515cb..7059c59c65b 100644 --- a/source/blender/blenkernel/intern/cloth.c +++ b/source/blender/blenkernel/intern/cloth.c @@ -153,7 +153,7 @@ void cloth_init (ClothModifierData *clmd) clmd->sim_parms.mass = 1.0f; clmd->sim_parms.stepsPerFrame = 5; clmd->sim_parms.sim_time = 1.0; - clmd->sim_parms.flags = CSIMSETT_FLAG_RESET; + clmd->sim_parms.flags = CSIMSETT_FLAG_RESET | CSIMSETT_FLAG_CCACHE_PROTECT; clmd->sim_parms.solver_type = 0; clmd->sim_parms.preroll = 0; clmd->sim_parms.maxspringlen = 10; @@ -576,6 +576,7 @@ void cloth_cache_set_frame(ClothModifierData *clmd, float time) } } +// free cloth cache void cloth_cache_free(ClothModifierData *clmd, float time) { Frame *frame = NULL; @@ -659,7 +660,8 @@ void clothModifier_do(ClothModifierData *clmd, Object *ob, DerivedMesh *dm, float deltaTime = current_time - clmd->sim_parms.sim_time; - // only be active during a specific period + // only be active during a specific period: + // that's "first frame" and "last frame" on GUI if (!(clmd->sim_parms.flags & CSIMSETT_FLAG_COLLOBJ)) { if(current_time < clmd->sim_parms.firstframe) @@ -681,7 +683,7 @@ void clothModifier_do(ClothModifierData *clmd, Object *ob, DerivedMesh *dm, } } - // unused in the moment + // unused in the moment, calculated seperately in implicit.c clmd->sim_parms.dt = 1.0f / clmd->sim_parms.stepsPerFrame; clmd->sim_parms.sim_time = current_time; @@ -812,46 +814,49 @@ void cloth_free_modifier (ClothModifierData *clmd) return; cloth = clmd->clothObject; - - // free our frame cache - clmd->sim_parms.flags |= CSIMSETT_FLAG_CCACHE_FREE_ALL; - cloth_cache_free(clmd, 0); - - if (cloth) - { - // If our solver provides a free function, call it - if (cloth->old_solver_type < 255 && solvers [cloth->old_solver_type].free) - { - solvers [cloth->old_solver_type].free (clmd); - } - - // Free the verts. - if (cloth->verts != NULL) - MEM_freeN (cloth->verts); - - cloth->verts = NULL; - cloth->numverts = -1; - - // Free the springs. - if (cloth->springs != NULL) - MEM_freeN (cloth->springs); - - cloth->springs = NULL; - cloth->numsprings = -1; - - // free BVH collision tree - if(cloth->tree) - bvh_free((BVH *)cloth->tree); - - // we save our faces for collision objects - if(cloth->mfaces) - MEM_freeN(cloth->mfaces); - if(clmd->clothObject->facemarks) - MEM_freeN(clmd->clothObject->facemarks); + if(!(clmd->sim_parms.flags & CSIMSETT_FLAG_CCACHE_PROTECT)) + { + // free our frame cache + clmd->sim_parms.flags |= CSIMSETT_FLAG_CCACHE_FREE_ALL; + cloth_cache_free(clmd, 0); + + if (cloth) + { + // If our solver provides a free function, call it + if (cloth->old_solver_type < 255 && solvers [cloth->old_solver_type].free) + { + solvers [cloth->old_solver_type].free (clmd); + } + + // Free the verts. + if (cloth->verts != NULL) + MEM_freeN (cloth->verts); + + cloth->verts = NULL; + cloth->numverts = -1; + + // Free the springs. + if (cloth->springs != NULL) + MEM_freeN (cloth->springs); + + cloth->springs = NULL; + cloth->numsprings = -1; + + // free BVH collision tree + if(cloth->tree) + bvh_free((BVH *)cloth->tree); + + // we save our faces for collision objects + if(cloth->mfaces) + MEM_freeN(cloth->mfaces); - MEM_freeN (cloth); - clmd->clothObject = NULL; + if(clmd->clothObject->facemarks) + MEM_freeN(clmd->clothObject->facemarks); + + MEM_freeN (cloth); + clmd->clothObject = NULL; + } } } @@ -952,6 +957,7 @@ static int collobj_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh unsigned int i; MVert *mvert = NULL; ClothVertex *verts = NULL; + float tnull[3] = {0,0,0}; /* If we have a clothObject, free it. */ if (clmd->clothObject != NULL) @@ -993,7 +999,9 @@ static int collobj_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh VECCOPY(verts->xold, verts->x); VECCOPY(verts->txold, verts->x); VECCOPY(verts->tx, verts->x); - VecMulf(verts->v, 0.0f); + VecMulf(verts->v, 0.0f); + verts->impulse_count = 0; + VECCOPY(verts->impulse, tnull); } clmd->clothObject->tree = bvh_build(clmd,clmd->coll_parms.epsilon); @@ -1159,6 +1167,7 @@ static int cloth_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *d // dm->getNumVerts(dm); MVert *mvert = NULL; // CDDM_get_verts(dm); ClothVertex *verts = NULL; + float tnull[3] = {0,0,0}; /* If we have a clothObject, free it. */ if (clmd->clothObject != NULL) @@ -1220,6 +1229,9 @@ static int cloth_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *d VECCOPY(verts->xconst, verts->x); VECCOPY(verts->txold, verts->x); VecMulf(verts->v, 0.0f); + + verts->impulse_count = 0; + VECCOPY(verts->impulse, tnull); } /* apply / set vertex groups */ @@ -1363,17 +1375,20 @@ int cloth_build_springs(Cloth *cloth, DerivedMesh *dm) shear_springs++; temp_index++; - - springs[temp_index].ij = mface[i].v2; - springs[temp_index].kl = mface[i].v4; - VECSUB(temp, mvert[springs[temp_index].kl].co, mvert[springs[temp_index].ij].co); - springs[temp_index].restlen = sqrt(INPR(temp, temp)); - springs[temp_index].type = SHEAR; - - BLI_linklist_append(&edgelist[springs[temp_index].ij], &(springs[temp_index])); - BLI_linklist_append(&edgelist[springs[temp_index].kl], &(springs[temp_index])); - - shear_springs++; + + if(mface[i].v4) + { + springs[temp_index].ij = mface[i].v2; + springs[temp_index].kl = mface[i].v4; + VECSUB(temp, mvert[springs[temp_index].kl].co, mvert[springs[temp_index].ij].co); + springs[temp_index].restlen = sqrt(INPR(temp, temp)); + springs[temp_index].type = SHEAR; + + BLI_linklist_append(&edgelist[springs[temp_index].ij], &(springs[temp_index])); + BLI_linklist_append(&edgelist[springs[temp_index].kl], &(springs[temp_index])); + + shear_springs++; + } } // bending springs diff --git a/source/blender/blenkernel/intern/collision.c b/source/blender/blenkernel/intern/collision.c index 32a2f820894..8c6a17c4e42 100644 --- a/source/blender/blenkernel/intern/collision.c +++ b/source/blender/blenkernel/intern/collision.c @@ -186,15 +186,15 @@ void generateTriangleMarks() */ } - +// w3 is not perfect void bvh_compute_barycentric (float pv[3], float p1[3], float p2[3], float p3[3], double *w1, double *w2, double *w3) { - float tempV1[3], tempV2[3], tempV4[3]; - double a,b,c,e,f; + double tempV1[3], tempV2[3], tempV4[3]; + double a,b,c,d,e,f; - VECSUB (tempV1, p1, p3); /* x1 - x3 */ - VECSUB (tempV2, p2, p3); /* x2 - x3 */ - VECSUB (tempV4, pv, p3); /* pv - x3 */ + VECSUB (tempV1, p1, p3); + VECSUB (tempV2, p2, p3); + VECSUB (tempV4, pv, p3); a = INPR (tempV1, tempV1); b = INPR (tempV1, tempV2); @@ -202,10 +202,24 @@ void bvh_compute_barycentric (float pv[3], float p1[3], float p2[3], float p3[3] e = INPR (tempV1, tempV4); f = INPR (tempV2, tempV4); + d = (a * c - b * b); + + if (ABS(d) < ALMOST_ZERO) { + *w1 = *w2 = *w3 = 1.0f / 3.0f; + return; + } + + w1[0] = (e * c - b * f) / d; + + if(w1[0] < 0) + w1[0] = 0.0; - w1[0] = (e * c - b * f) / (a * c - b * b); w2[0] = (f - b * w1[0]) / c; - w3[0] = 1.0 - w1[0] - w2[0]; + + if(w2[0] < 0) + w2[0] = 0.0; + + w3[0] = 1.0f - w1[0] - w2[0]; } DO_INLINE void interpolateOnTriangle(float to[3], float v1[3], float v2[3], float v3[3], double w1, double w2, double w3) @@ -230,36 +244,22 @@ DO_INLINE void calculateFrictionImpulse(float to[3], float vrel[3], float normal int collision_static(ClothModifierData *clmd, ClothModifierData *coll_clmd, LinkNode **collision_list) { - unsigned int i = 0, numverts=0; + unsigned int i = 0, numfaces = 0; int result = 0; LinkNode *search = NULL; CollPair *collpair = NULL; Cloth *cloth1, *cloth2; MFace *face1, *face2; - double w1, w2, w3, u1, u2, u3; + double w1, w2, w3, u1, u2, u3, a1, a2, a3; float v1[3], v2[3], relativeVelocity[3]; float magrelVel; cloth1 = clmd->clothObject; cloth2 = coll_clmd->clothObject; - numverts = clmd->clothObject->numverts; - - /* - for(i = 0; i < LIST_LENGTH; i++) - { - // calc SIP-code - // TODO for later: calculateSipCode() - - // calc distance (?) + numfaces = clmd->clothObject->numfaces; - // calc impulse - - // apply impulse - } - */ - - for(i = 0; i < numverts; i++) + for(i = 0; i < numfaces; i++) { search = collision_list[i]; @@ -273,11 +273,13 @@ int collision_static(ClothModifierData *clmd, ClothModifierData *coll_clmd, Link // compute barycentric coordinates for both collision points if(!collpair->quadA) + { bvh_compute_barycentric(collpair->p1, cloth1->verts[face1->v1].txold, cloth1->verts[face1->v2].txold, cloth1->verts[face1->v3].txold, &w1, &w2, &w3); + } else bvh_compute_barycentric(collpair->p1, cloth1->verts[face1->v4].txold, @@ -317,25 +319,26 @@ int collision_static(ClothModifierData *clmd, ClothModifierData *coll_clmd, Link // Calculate masses of points. - // printf("relativeVelocity -> x: %f, y: %f, z: %f\n", relativeVelocity[0], relativeVelocity[1],relativeVelocity[2]); - // If v_n_mag > 0 the edges are approaching each other. - if(magrelVel > ALMOST_ZERO) + + if(magrelVel < -ALMOST_ZERO) { // Calculate Impulse magnitude to stop all motion in normal direction. // const double I_mag = v_n_mag / (1/m1 + 1/m2); float magnitude_i = magrelVel / 2.0f; // TODO implement masses float tangential[3], magtangent, magnormal, collvel[3]; float vrel_t_pre[3]; - float vrel_t[3], impulse; + float vrel_t[3]; + double impulse; float epsilon = clmd->coll_parms.epsilon; + float overlap = (epsilon + ALMOST_ZERO-collpair->distance); // calculateFrictionImpulse(tangential, relativeVelocity, collpair->normal, magrelVel, clmd->coll_parms.friction*0.01, magrelVel); // magtangent = INPR(tangential, tangential); // Apply friction impulse. - if (magtangent > ALMOST_ZERO) + if (magtangent < ALMOST_ZERO) { // printf("friction applied: %f\n", magtangent); @@ -347,57 +350,64 @@ int collision_static(ClothModifierData *clmd, ClothModifierData *coll_clmd, Link VECSUB(cloth1->verts[face1->v1].tv, cloth1->verts[face1->v4].tv,tangential); */ } + + impulse = -magrelVel / ( 1.0 + w1*w1 + w2*w2 + w3*w3); + VECADDMUL(cloth1->verts[face1->v1].impulse, collpair->normal, impulse); + cloth1->verts[face1->v1].impulse_count++; + + VECADDMUL(cloth1->verts[face1->v2].impulse, collpair->normal, impulse); + cloth1->verts[face1->v2].impulse_count++; + + VECADDMUL(cloth1->verts[face1->v3].impulse, collpair->normal, impulse); + cloth1->verts[face1->v3].impulse_count++; + + if(face1->v4) + { + VECADDMUL(cloth1->verts[face1->v4].impulse, collpair->normal, impulse); + cloth1->verts[face1->v4].impulse_count++; + } + + + if (overlap > ALMOST_ZERO) { + double I_mag = overlap * 0.1; + + impulse = I_mag / ( 1.0 + w1*w1 + w2*w2 + w3*w3); + + VECADDMUL(cloth1->verts[face1->v1].impulse, collpair->normal, impulse); + cloth1->verts[face1->v1].impulse_count++; + + VECADDMUL(cloth1->verts[face1->v2].impulse, collpair->normal, impulse); + cloth1->verts[face1->v2].impulse_count++; + + VECADDMUL(cloth1->verts[face1->v3].impulse, collpair->normal, impulse); + cloth1->verts[face1->v3].impulse_count++; + + if(face1->v4) + { + VECADDMUL(cloth1->verts[face1->v4].impulse, collpair->normal, impulse); + cloth1->verts[face1->v4].impulse_count++; + } + + } + + result = 1; + // printf("magnitude_i: %f\n", magnitude_i); // negative before collision in my case // Apply the impulse and increase impulse counters. - // my try, works better than the papers ones (maybe i did just something wrong) - VECSUB(collvel, cloth1->verts[face1->v1].tv, v2); - magnormal = INPR(collvel, collpair->normal); - if(magnormaldistance) / 4.0f; - VECADDMUL(cloth1->verts[face1->v1].tv, collpair->normal, -magnormal + impulse); - + + /* // calculateFrictionImpulse(tangential, collvel, collpair->normal, magtangent, clmd->coll_parms.friction*0.01, magtangent); - -/* VECSUBS(vrel_t_pre, collvel, collpair->normal, magnormal); // VecMulf(vrel_t_pre, clmd->coll_parms.friction*0.01f/INPR(vrel_t_pre,vrel_t_pre)); magtangent = Normalize(vrel_t_pre); VecMulf(vrel_t_pre, MIN2(clmd->coll_parms.friction*0.01f*magnormal,magtangent)); VECSUB(cloth1->verts[face1->v1].tv, cloth1->verts[face1->v1].tv,vrel_t_pre); -*/ - - VECSUB(collvel, cloth1->verts[face1->v2].tv, v2); - magnormal = INPR(collvel, collpair->normal); - if(magnormaldistance) / 4.0f; - VECADDMUL(cloth1->verts[face1->v2].tv, collpair->normal, -magnormal+ impulse); + */ - VECSUB(collvel, cloth1->verts[face1->v3].tv, v2); - magnormal = INPR(collvel, collpair->normal); - if(magnormaldistance) / 4.0f; - VECADDMUL(cloth1->verts[face1->v3].tv, collpair->normal, -magnormal+ impulse); - - - VECSUB(collvel, cloth1->verts[face1->v4].tv, v2); - magnormal = INPR(collvel, collpair->normal); - if(magnormaldistance) / 4.0f; - VECADDMUL(cloth1->verts[face1->v4].tv, collpair->normal, -magnormal+ impulse); - - result = 1; } @@ -444,65 +454,86 @@ double implicit_tri_check_coherence (ClothModifierData *clmd, ClothModifierData { if(i == 0) { - indexA = face1->v4; - indexB = face1->v1; - indexC = face1->v3; - - indexD = face2->v1; - indexE = face2->v2; - indexF = face2->v3; - } - else if(i == 1) - { - indexA = face1->v4; - indexB = face1->v1; - indexC = face1->v3; - - indexD = face2->v4; - indexE = face2->v1; - indexF = face2->v3; - } - else if(i == 2) - { - indexA = face1->v1; - indexB = face1->v2; - indexC = face1->v3; - - indexD = face2->v4; - indexE = face2->v1; - indexF = face2->v3; - } - - // face a2 + face b1 - VECCOPY(a[0], cloth1->verts[indexA].txold); - VECCOPY(a[1], cloth1->verts[indexB].txold); - VECCOPY(a[2], cloth1->verts[indexC].txold); - - - VECCOPY(b[0], cloth2->verts[indexD].txold); - VECCOPY(b[1], cloth2->verts[indexE].txold); - VECCOPY(b[2], cloth2->verts[indexF].txold); - - tempdistance = plNearestPoints(a,b,tpa,tpb,tnormal); - - if(tempdistance < distance) - { - VECCOPY(pa, tpa); - VECCOPY(pb, tpb); - VECCOPY(normal, tnormal); - distance = tempdistance; - - if(i == 0) + if(face1->v4) { - quadA = 1; quadB = 0; + indexA = face1->v4; + indexB = face1->v1; + indexC = face1->v3; + + indexD = face2->v1; + indexE = face2->v2; + indexF = face2->v3; } - else if(i == 1) + else + i+=2; + } + + if(i == 1) + { + if((face1->v4)&&(face2->v4)) { - quadA = quadB = 1; + indexA = face1->v4; + indexB = face1->v1; + indexC = face1->v3; + + indexD = face2->v4; + indexE = face2->v1; + indexF = face2->v3; } - else if(i == 2) + else + i++; + } + + if(i == 2) + { + if(face2->v4) { - quadA = 0; quadB = 1; + indexA = face1->v1; + indexB = face1->v2; + indexC = face1->v3; + + indexD = face2->v4; + indexE = face2->v1; + indexF = face2->v3; + } + else + i++; + + } + + if(i<3) + { + // face a2 + face b1 + VECCOPY(a[0], cloth1->verts[indexA].txold); + VECCOPY(a[1], cloth1->verts[indexB].txold); + VECCOPY(a[2], cloth1->verts[indexC].txold); + + + VECCOPY(b[0], cloth2->verts[indexD].txold); + VECCOPY(b[1], cloth2->verts[indexE].txold); + VECCOPY(b[2], cloth2->verts[indexF].txold); + + tempdistance = plNearestPoints(a,b,tpa,tpb,tnormal); + + if(tempdistance < distance) + { + VECCOPY(pa, tpa); + VECCOPY(pb, tpb); + VECCOPY(normal, tnormal); + distance = tempdistance; + + if(i == 0) + { + quadA = 1; quadB = 0; + } + else if(i == 1) + { + quadA = quadB = 1; + } + else if(i == 2) + { + quadA = 0; quadB = 1; + } } } } @@ -524,20 +555,18 @@ void bvh_collision_response(ClothModifierData *clmd, ClothModifierData *coll_clm // calc distance + normal distance = implicit_tri_check_coherence(clmd, coll_clmd, tree1->tri_index, tree2->tri_index, collpair->p1, collpair->p2, collpair->vector, collpair->quadA, collpair->quadB); - if (ABS(distance) <= (epsilon + ALMOST_ZERO)) + if ((distance <= (epsilon + ALMOST_ZERO)) && (distance > -1.0f)) // max overlap = 1.0 { - // printf("distance: %f, epsilon: %f\n", (float)distance, epsilon + ALMOST_ZERO); - + // printf("dist: %f\n", (float)distance); + collpair->face1 = tree1->tri_index; collpair->face2 = tree2->tri_index; VECCOPY(collpair->normal, collpair->vector); Normalize(collpair->normal); - // printf("normal x: %f, y: %f, z: %f\n", collpair->normal[0], collpair->normal[1], collpair->normal[2]); - collpair->distance = distance; - BLI_linklist_append(&linknode[tree1->tri_index], collpair); + BLI_linklist_append(&linknode[tree1->tri_index], collpair); } else { @@ -545,32 +574,14 @@ void bvh_collision_response(ClothModifierData *clmd, ClothModifierData *coll_clm } } - -int cloth_bvh_objcollision(ClothModifierData * clmd, float step, CM_COLLISION_RESPONSE collision_response, float dt) +// move collision objects forward in time and update static bounding boxes +void cloth_update_collision_objects(float step) { Base *base=NULL; ClothModifierData *coll_clmd=NULL; - Cloth *cloth=NULL; Object *coll_ob=NULL; - BVH *cloth_bvh=NULL; - unsigned int i=0, numverts=0; - int result = 0; - - if ((clmd->sim_parms.flags & CSIMSETT_FLAG_COLLOBJ) || !(((Cloth *)clmd->clothObject)->tree)) - { - return 0; - } - cloth = clmd->clothObject; - cloth_bvh = (BVH *) cloth->tree; - numverts = clmd->clothObject->numverts; + unsigned int i=0; - //////////////////////////////////////////////////////////// - // static collisions - //////////////////////////////////////////////////////////// - - // update cloth bvh - bvh_update_static(clmd, cloth_bvh); - // search all objects for collision object for (base = G.scene->base.first; base; base = base->next) { @@ -584,73 +595,150 @@ int cloth_bvh_objcollision(ClothModifierData * clmd, float step, CM_COLLISION_RE if (coll_clmd->sim_parms.flags & CSIMSETT_FLAG_COLLOBJ) { if (coll_clmd->clothObject && coll_clmd->clothObject->tree) - { - unsigned int coll_numverts = coll_clmd->clothObject->numverts; + { Cloth *coll_cloth = coll_clmd->clothObject; - - LinkNode **collision_list = MEM_callocN (sizeof(LinkNode *)*numverts, "collision_list"); BVH *coll_bvh = coll_clmd->clothObject->tree; + unsigned int coll_numverts = coll_cloth->numverts; - if(collision_list) - { - // memset(collision_list, 0, sizeof(LinkNode *)*numverts); + // update position of collision object + for(i = 0; i < coll_numverts; i++) + { + VECCOPY(coll_cloth->verts[i].txold, coll_cloth->verts[i].tx); + + VECADDS(coll_cloth->verts[i].tx, coll_cloth->verts[i].xold, coll_cloth->verts[i].v, step); - for(i = 0; i < numverts; i++) - { - collision_list[i] = NULL; - } - - clmd->coll_parms.temp = collision_list; - - // update position of collision object - for(i = 0; i < coll_numverts; i++) - { - VECCOPY(coll_cloth->verts[i].txold, coll_cloth->verts[i].tx); - - VECADDS(coll_cloth->verts[i].tx, coll_cloth->verts[i].xold, coll_cloth->verts[i].v, step); - - VECSUB(coll_cloth->verts[i].tv, coll_cloth->verts[i].tx, coll_cloth->verts[i].txold); - } - - // update BVH of collision object - bvh_update_static(coll_clmd, coll_bvh); - - bvh_traverse(clmd, coll_clmd, cloth_bvh->root, coll_bvh->root, step, collision_response); - - result += collision_static(clmd, coll_clmd, collision_list); - - // calculate velocities - - // free temporary list - for(i = 0; i < numverts; i++) - { - LinkNode *search = collision_list[i]; - while(search) - { - LinkNode *next= search->next; - CollPair *collpair = search->link; - - if(collpair) - MEM_freeN(collpair); - - search = next; - } - - BLI_linklist_free(collision_list[i],NULL); - } - if(collision_list) - MEM_freeN(collision_list); - - clmd->coll_parms.temp = NULL; + // no dt here because of float rounding errors + VECSUB(coll_cloth->verts[i].tv, coll_cloth->verts[i].tx, coll_cloth->verts[i].txold); } - - + + // update BVH of collision object + bvh_update_static(coll_clmd, coll_bvh); } else printf ("cloth_bvh_objcollision: found a collision object with clothObject or collData NULL.\n"); } } +} +#define CLOTH_MAX_THRESHOLD 5 + +// cloth - object collisions +int cloth_bvh_objcollision(ClothModifierData * clmd, float step, CM_COLLISION_RESPONSE collision_response, float dt) +{ + Base *base=NULL; + ClothModifierData *coll_clmd=NULL; + Cloth *cloth=NULL; + Object *coll_ob=NULL; + BVH *cloth_bvh=NULL; + unsigned int i=0, numfaces = 0, numverts = 0; + unsigned int result = 0, ic = 0, rounds = 0; + ClothVertex *verts = NULL; + float tnull[3] = {0,0,0}; + + if ((clmd->sim_parms.flags & CSIMSETT_FLAG_COLLOBJ) || !(((Cloth *)clmd->clothObject)->tree)) + { + return 0; + } + cloth = clmd->clothObject; + verts = cloth->verts; + cloth_bvh = (BVH *) cloth->tree; + numfaces = clmd->clothObject->numfaces; + numverts = clmd->clothObject->numverts; + + //////////////////////////////////////////////////////////// + // static collisions + //////////////////////////////////////////////////////////// + + // update cloth bvh + bvh_update_static(clmd, cloth_bvh); + + // update collision objects + cloth_update_collision_objects(step); + + do + { + result = 0; + ic = 0; + + // handle all collision objects + for (base = G.scene->base.first; base; base = base->next) + { + + coll_ob = base->object; + coll_clmd = (ClothModifierData *) modifiers_findByType (coll_ob, eModifierType_Cloth); + if (!coll_clmd) + continue; + + // if collision object go on + if (coll_clmd->sim_parms.flags & CSIMSETT_FLAG_COLLOBJ) + { + if (coll_clmd->clothObject && coll_clmd->clothObject->tree) + { + LinkNode **collision_list = MEM_callocN (sizeof(LinkNode *)*(numfaces), "collision_list"); + BVH *coll_bvh = coll_clmd->clothObject->tree; + + if(collision_list) + { + memset(collision_list, 0, sizeof(LinkNode *)*numfaces); + clmd->coll_parms.temp = collision_list; + + bvh_traverse(clmd, coll_clmd, cloth_bvh->root, coll_bvh->root, step, collision_response); + + result += collision_static(clmd, coll_clmd, collision_list); + + // calculate velocities + + // free temporary list + for(i = 0; i < numfaces; i++) + { + LinkNode *search = collision_list[i]; + while(search) + { + LinkNode *next= search->next; + CollPair *collpair = search->link; + + if(collpair) + MEM_freeN(collpair); + + search = next; + } + + BLI_linklist_free(collision_list[i],NULL); + } + if(collision_list) + MEM_freeN(collision_list); + + clmd->coll_parms.temp = NULL; + } + + + } + else + printf ("cloth_bvh_objcollision: found a collision object with clothObject or collData NULL.\n"); + } + } + + // now apply impulses parallel + + for(i = 0; i < numverts; i++) + { + if(verts[i].impulse_count) + { + VECADDMUL(verts[i].tv, verts[i].impulse, 1.0f / verts[i].impulse_count); + VECCOPY(verts[i].impulse, tnull); + verts[i].impulse_count = 0; + + ic++; + } + } + + printf("ic: %d\n", ic); + rounds++; + } + while(result && (CLOTH_MAX_THRESHOLD>rounds)); + + printf("\n"); + //////////////////////////////////////////////////////////// // update positions + velocities //////////////////////////////////////////////////////////// diff --git a/source/blender/blenkernel/intern/implicit.c b/source/blender/blenkernel/intern/implicit.c index c54897cc89c..0d0c7ff0f7b 100644 --- a/source/blender/blenkernel/intern/implicit.c +++ b/source/blender/blenkernel/intern/implicit.c @@ -1484,7 +1484,7 @@ int implicit_solver (Object *ob, float frame, ClothModifierData *clmd, ListBase VECCOPY(verts[i].tx, id->Xnew[i]); VECSUB(verts[i].tv, verts[i].tx, verts[i].txold); - VECSUB(verts[i].v, verts[i].tx, verts[i].txold); + VECCOPY(verts[i].v, verts[i].tv); } // call collision function diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c index 546247f8e35..5ba3df9a720 100644 --- a/source/blender/blenkernel/intern/modifier.c +++ b/source/blender/blenkernel/intern/modifier.c @@ -4941,9 +4941,12 @@ static int clothModifier_dependsOnTime(ModifierData *md) static void clothModifier_freeData(ModifierData *md) { ClothModifierData *clmd = (ClothModifierData*) md; - + if (clmd) - cloth_free_modifier (clmd); + { + clmd->sim_parms.flags &= ~CSIMSETT_FLAG_CCACHE_PROTECT; + cloth_free_modifier (clmd); + } } /* Boolean */ diff --git a/source/blender/makesdna/DNA_cloth_types.h b/source/blender/makesdna/DNA_cloth_types.h index c0a47452e3e..574537f2589 100644 --- a/source/blender/makesdna/DNA_cloth_types.h +++ b/source/blender/makesdna/DNA_cloth_types.h @@ -41,16 +41,18 @@ * is reached. */ typedef struct ClothVertex { - int flags; /* General flags per vertex. */ - float v [3]; /* The velocity of the point. */ - float xconst [3]; /* constrained position */ - float x [3]; /* The current position of this vertice. */ - float xold [3]; /* The previous position of this vertice. */ - float tx [3]; - float txold [3]; - float tv[3]; - float mass; /* mass / weight of the vertex */ - float goal; /* goal, from SB */ + int flags; /* General flags per vertex. */ + float v [3]; /* The velocity of the point. */ + float xconst [3]; /* constrained position */ + float x [3]; /* The current position of this vertex. */ + float xold [3]; /* The previous position of this vertex.*/ + float tx [3]; /* temporary position */ + float txold [3]; /* temporary old position */ + float tv[3]; /* temporary "velocity", mostly used as tv = tx-txold */ + float mass; /* mass / weight of the vertex */ + float goal; /* goal, from SB */ + float impulse[3]; /* used in collision.c */ + unsigned int impulse_count; /* same as above */ } ClothVertex; diff --git a/source/blender/src/buttons_object.c b/source/blender/src/buttons_object.c index 1e3439d41b5..a10ffa09442 100644 --- a/source/blender/src/buttons_object.c +++ b/source/blender/src/buttons_object.c @@ -3118,8 +3118,8 @@ static void object_panel_cloth(Object *ob) /* GENERAL STUFF */ uiClearButLock(); uiBlockBeginAlign(block); - uiDefButF(block, NUM, B_CLOTH_RENEW, "StructStiff:", 10,170,150,20, &clmd->sim_parms.structural, 1.0, 5000.0, 100, 0, "Overall stiffness of structure"); - uiDefButF(block, NUM, B_CLOTH_RENEW, "BendStiff:", 160,170,150,20, &clmd->sim_parms.bending, 0.0, 1000.0, 1000, 0, "Wrinkle possibility"); + uiDefButF(block, NUM, B_CLOTH_RENEW, "StructStiff:", 10,170,150,20, &clmd->sim_parms.structural, 1.0, 10000.0, 100, 0, "Overall stiffness of structure"); + uiDefButF(block, NUM, B_CLOTH_RENEW, "BendStiff:", 160,170,150,20, &clmd->sim_parms.bending, 0.0, 10000.0, 1000, 0, "Wrinkle possibility"); uiDefButI(block, NUM, B_CLOTH_RENEW, "Steps per Frame:", 10,150,150,20, &clmd->sim_parms.stepsPerFrame, 1.0, 100.0, 5, 0, "Quality of the simulation (higher=better=slower)"); uiBlockEndAlign(block); uiBlockBeginAlign(block); @@ -3249,12 +3249,13 @@ static void object_panel_cloth_II(Object *ob) uiDefBut(block, BUT, B_CLOTH_CLEARCACHEALL, "All", 10, 100,145,20, NULL, 0.0, 0.0, 0, 0, "Free cloth cache without preroll"); uiDefBut(block, BUT, B_CLOTH_CLEARCACHEFRAME, "From next frame", 155, 100,145,20, NULL, 0.0, 0.0, 0, 0, "Free cloth cache"); if(length>1) // B_CLOTH_CHANGEPREROLL - uiDefButI(block, NUM, B_CLOTH_CHANGEPREROLL, "Preroll:", 10,80,145,20, &clmd->sim_parms.preroll, 0, length-1, 1, 0, "Simulation starts on this frame"); + uiDefButI(block, NUM, B_CLOTH_CHANGEPREROLL, "Preroll:", 10,80,145,20, &clmd->sim_parms.preroll, 0, length-1, 1, 0, "Simulation starts on this frame"); } else { uiDefBut(block, LABEL, 0, "No frames cached.", 10,120,290,20, NULL, 0.0, 0, 0, 0, ""); } + uiDefButBitI(block, TOG, CSIMSETT_FLAG_CCACHE_PROTECT, REDRAWVIEW3D, "Protect Cache", 10,50,145,20, &clmd->sim_parms.flags, 0, 0, 0, 0, "Protect cache from automatic freeing when scene changed"); uiBlockEndAlign(block); } } From b4fb141ea571ee9c9edefa277eb6f034d54d26d2 Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Sun, 23 Sep 2007 17:40:44 +0000 Subject: [PATCH 018/246] In the middle of switching to own collision detection, WIP commit (don't expect anything to work, but compile) --- source/blender/blenkernel/BKE_cloth.h | 4 +- source/blender/blenkernel/intern/cloth.c | 2 +- source/blender/blenkernel/intern/collision.c | 351 +++++++++++++++++-- 3 files changed, 323 insertions(+), 34 deletions(-) diff --git a/source/blender/blenkernel/BKE_cloth.h b/source/blender/blenkernel/BKE_cloth.h index e4d1fb0ca99..ec58382b86a 100644 --- a/source/blender/blenkernel/BKE_cloth.h +++ b/source/blender/blenkernel/BKE_cloth.h @@ -60,7 +60,7 @@ struct DerivedMesh; /* This is approximately the smallest number that can be * represented by a float, given its precision. */ -#define ALMOST_ZERO 0.00001 +#define ALMOST_ZERO 0.000001 /* Bits to or into the ClothVertex.flags. */ #define CVERT_FLAG_PINNED 1 @@ -240,7 +240,7 @@ typedef struct CollPair float p1[3], p2[3]; // collision point p1 on face1, p2 on face2 int lastsign; // indicates if the distance sign has changed, unused itm float time; // collision time, from 0 up to 1 - int quadA, quadB; // indicates the used triangle of the quad: 0 means verts 1,2,3; 1 means verts 4,1,3 + unsigned int Aindex1, Aindex2, Aindex3, Aindex4, Bindex1, Bindex2, Bindex3, Bindex4; } CollPair; diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c index 7059c59c65b..d9f0bef9f43 100644 --- a/source/blender/blenkernel/intern/cloth.c +++ b/source/blender/blenkernel/intern/cloth.c @@ -153,7 +153,7 @@ void cloth_init (ClothModifierData *clmd) clmd->sim_parms.mass = 1.0f; clmd->sim_parms.stepsPerFrame = 5; clmd->sim_parms.sim_time = 1.0; - clmd->sim_parms.flags = CSIMSETT_FLAG_RESET | CSIMSETT_FLAG_CCACHE_PROTECT; + clmd->sim_parms.flags = CSIMSETT_FLAG_RESET; clmd->sim_parms.solver_type = 0; clmd->sim_parms.preroll = 0; clmd->sim_parms.maxspringlen = 10; diff --git a/source/blender/blenkernel/intern/collision.c b/source/blender/blenkernel/intern/collision.c index 8c6a17c4e42..7eec315e386 100644 --- a/source/blender/blenkernel/intern/collision.c +++ b/source/blender/blenkernel/intern/collision.c @@ -211,14 +211,8 @@ void bvh_compute_barycentric (float pv[3], float p1[3], float p2[3], float p3[3] w1[0] = (e * c - b * f) / d; - if(w1[0] < 0) - w1[0] = 0.0; - w2[0] = (f - b * w1[0]) / c; - if(w2[0] < 0) - w2[0] = 0.0; - w3[0] = 1.0f - w1[0] - w2[0]; } @@ -241,7 +235,7 @@ DO_INLINE void calculateFrictionImpulse(float to[3], float vrel[3], float normal VecMulf(to, MAX2(1.0f - frictionConstant * delta_V_n / INPR(vrel_t_pre,vrel_t_pre), 0.0f)); } - +/* int collision_static(ClothModifierData *clmd, ClothModifierData *coll_clmd, LinkNode **collision_list) { unsigned int i = 0, numfaces = 0; @@ -343,12 +337,12 @@ int collision_static(ClothModifierData *clmd, ClothModifierData *coll_clmd, Link // printf("friction applied: %f\n", magtangent); // TODO check original code - /* + VECSUB(cloth1->verts[face1->v1].tv, cloth1->verts[face1->v1].tv,tangential); VECSUB(cloth1->verts[face1->v1].tv, cloth1->verts[face1->v2].tv,tangential); VECSUB(cloth1->verts[face1->v1].tv, cloth1->verts[face1->v3].tv,tangential); VECSUB(cloth1->verts[face1->v1].tv, cloth1->verts[face1->v4].tv,tangential); - */ + } impulse = -magrelVel / ( 1.0 + w1*w1 + w2*w2 + w3*w3); @@ -397,7 +391,7 @@ int collision_static(ClothModifierData *clmd, ClothModifierData *coll_clmd, Link // Apply the impulse and increase impulse counters. - /* + / // calculateFrictionImpulse(tangential, collvel, collpair->normal, magtangent, clmd->coll_parms.friction*0.01, magtangent); VECSUBS(vrel_t_pre, collvel, collpair->normal, magnormal); // VecMulf(vrel_t_pre, clmd->coll_parms.friction*0.01f/INPR(vrel_t_pre,vrel_t_pre)); @@ -405,7 +399,7 @@ int collision_static(ClothModifierData *clmd, ClothModifierData *coll_clmd, Link VecMulf(vrel_t_pre, MIN2(clmd->coll_parms.friction*0.01f*magnormal,magtangent)); VECSUB(cloth1->verts[face1->v1].tv, cloth1->verts[face1->v1].tv,vrel_t_pre); - */ + @@ -417,7 +411,8 @@ int collision_static(ClothModifierData *clmd, ClothModifierData *coll_clmd, Link return result; } - +*/ + // return distance between two triangles using bullet engine double implicit_tri_check_coherence (ClothModifierData *clmd, ClothModifierData *coll_clmd, unsigned int tri_index1, unsigned int tri_index2, float pa[3], float pb[3], float normal[3], int quadA, int quadB) { @@ -540,37 +535,331 @@ double implicit_tri_check_coherence (ClothModifierData *clmd, ClothModifierData return distance; } +// calculate plane normal +void calcPlaneNormal(float normal[3], float p11[3], float p12[3], float p13[3]) +{ + float temp1[3], temp2[3]; + float tnormal[3]; + + VECSUB(temp1, p12,p11); + VECSUB(temp2, p13,p11); + Crossf(normal, temp1, temp2); + Normalize(normal); + // VECCOPY(normal, tnormal); +} + +float distance_triangle_point( float p11[3], float p12[3], float p13[3], float p21[3], float normal[3]) +{ + float temp[3]; + float magnitude = 0; + + VECSUB(temp, p21, p13); + magnitude = INPR(temp, normal); + + if(magnitude < 0) + { + magnitude *= -1.0f; + // VecMulf(normal, -1.0f); + } + + return magnitude; +} + +float nearest_point_triangle_triangle(float p11[3], float p12[3], float p13[3], float p21[3], float p22[3], float p23[3], float normal[3]) +{ + float distance = 0, tdistance = 0, tnormal[3]; + + // first triangle 1-2-3 versus second triangle 1-2-3 + calcPlaneNormal(normal, p11, p12, p13); + distance = distance_triangle_point(p11, p12, p13, p21, normal); + + tdistance = distance_triangle_point(p11, p12, p13, p22, normal); + + if(tdistance < distance) + { + distance = tdistance; + } + + tdistance = distance_triangle_point(p11, p12, p13, p23, normal); + + if(tdistance < distance) + { + distance = tdistance; + } + + // second triangle 1-2-3 versus first triangle 1-2-3 + calcPlaneNormal(tnormal, p21, p22, p23); + + tdistance = distance_triangle_point(p21, p22, p23, p11, tnormal); + + if(tdistance < distance) + { + distance = tdistance; + VECCOPY(normal, tnormal); + } + + tdistance = distance_triangle_point(p21, p22, p23, p12, tnormal); + + if(tdistance < distance) + { + distance = tdistance; + VECCOPY(normal, tnormal); + } + + tdistance = distance_triangle_point(p21, p22, p23, p13, tnormal); + + if(tdistance < distance) + { + distance = tdistance; + VECCOPY(normal, tnormal); + } + + + if (distance < 0) { + VecMulf(normal, -1.0f); + distance = -distance; + } + + return distance; +} + + +int collision_static2(ClothModifierData *clmd, ClothModifierData *coll_clmd, LinkNode **collision_list) +{ + unsigned int i = 0, numfaces = 0; + int result = 0; + LinkNode *search = NULL; + CollPair *collpair = NULL; + Cloth *cloth1, *cloth2; + MFace *face1, *face2; + double w1, w2, w3, u1, u2, u3, a1, a2, a3; + float v1[3], v2[3], relativeVelocity[3]; + float magrelVel; + + cloth1 = clmd->clothObject; + cloth2 = coll_clmd->clothObject; + + numfaces = clmd->clothObject->numfaces; + + for(i = 0; i < numfaces; i++) + { + search = collision_list[i]; + + while(search) + { + collpair = search->link; + + face1 = &(cloth1->mfaces[collpair->face1]); + face2 = &(cloth2->mfaces[collpair->face2]); + + // compute barycentric coordinates for both collision points + + + bvh_compute_barycentric(collpair->p1, + cloth1->verts[collpair->Aindex1].txold, + cloth1->verts[collpair->Aindex2].txold, + cloth1->verts[collpair->Aindex3].txold, + &w1, &w2, &w3); + + bvh_compute_barycentric(collpair->p2, + cloth2->verts[collpair->Bindex1].txold, + cloth2->verts[collpair->Bindex1].txold, + cloth2->verts[collpair->Bindex3].txold, + &u1, &u2, &u3); + + // Calculate relative "velocity". + interpolateOnTriangle(v1, cloth1->verts[collpair->Aindex1].tv, cloth1->verts[collpair->Aindex2].tv, cloth1->verts[collpair->Aindex3].tv, w1, w2, w3); + + interpolateOnTriangle(v2, cloth2->verts[collpair->Bindex1].tv, cloth2->verts[collpair->Bindex2].tv, cloth2->verts[collpair->Bindex3].tv, u1, u2, u3); + + VECSUB(relativeVelocity, v1, v2); + + // Calculate the normal component of the relative velocity (actually only the magnitude - the direction is stored in 'normal'). + magrelVel = INPR(relativeVelocity, collpair->normal); + + // Calculate masses of points. + + // If v_n_mag > 0 the edges are approaching each other. + + if(magrelVel < -ALMOST_ZERO) + { + // Calculate Impulse magnitude to stop all motion in normal direction. + // const double I_mag = v_n_mag / (1/m1 + 1/m2); + float magnitude_i = magrelVel / 2.0f; // TODO implement masses + float tangential[3], magtangent, magnormal, collvel[3]; + float vrel_t_pre[3]; + float vrel_t[3]; + double impulse; + float epsilon = clmd->coll_parms.epsilon; + float overlap = (epsilon + ALMOST_ZERO-collpair->distance); + + /* + impulse = -magrelVel / ( 1.0 + w1*w1 + w2*w2 + w3*w3); + VECADDMUL(cloth1->verts[face1->v1].impulse, collpair->normal, impulse); + cloth1->verts[face1->v1].impulse_count++; + + VECADDMUL(cloth1->verts[face1->v2].impulse, collpair->normal, impulse); + cloth1->verts[face1->v2].impulse_count++; + + VECADDMUL(cloth1->verts[face1->v3].impulse, collpair->normal, impulse); + cloth1->verts[face1->v3].impulse_count++; + */ + + + /* + if (overlap > ALMOST_ZERO) { + double I_mag = overlap * 0.1; + + impulse = I_mag / ( 1.0 + w1*w1 + w2*w2 + w3*w3); + + VECADDMUL(cloth1->verts[face1->v1].impulse, collpair->normal, impulse); + cloth1->verts[face1->v1].impulse_count++; + + VECADDMUL(cloth1->verts[face1->v2].impulse, collpair->normal, impulse); + cloth1->verts[face1->v2].impulse_count++; + + VECADDMUL(cloth1->verts[face1->v3].impulse, collpair->normal, impulse); + cloth1->verts[face1->v3].impulse_count++; + + if(face1->v4) + { + VECADDMUL(cloth1->verts[face1->v4].impulse, collpair->normal, impulse); + cloth1->verts[face1->v4].impulse_count++; + } + + } + */ + + result = 1; + } + + search = search->next; + } + } + + return result; +} + void bvh_collision_response(ClothModifierData *clmd, ClothModifierData *coll_clmd, Tree * tree1, Tree * tree2) { CollPair *collpair = NULL; LinkNode **linknode; double distance = 0; - float epsilon = clmd->coll_parms.epsilon; - - collpair = (CollPair *)MEM_callocN(sizeof(CollPair), "cloth coll pair"); + float epsilon = clmd->coll_parms.epsilon, tdistance=0; + MFace *face1, *face2; + ClothVertex *verts1, *verts2; + Cloth *cloth1=NULL, *cloth2=NULL; + int i = 0; + linknode = clmd->coll_parms.temp; + cloth1 = clmd->clothObject; + cloth2 = coll_clmd->clothObject; + // calc SIPcode (?) - // calc distance + normal - distance = implicit_tri_check_coherence(clmd, coll_clmd, tree1->tri_index, tree2->tri_index, collpair->p1, collpair->p2, collpair->vector, collpair->quadA, collpair->quadB); - - if ((distance <= (epsilon + ALMOST_ZERO)) && (distance > -1.0f)) // max overlap = 1.0 + for(i = 0; i < 4; i++) { - // printf("dist: %f\n", (float)distance); + collpair = (CollPair *)MEM_callocN(sizeof(CollPair), "cloth coll pair"); - collpair->face1 = tree1->tri_index; - collpair->face2 = tree2->tri_index; + face1 = &(cloth1->mfaces[tree1->tri_index]); + face2 = &(cloth2->mfaces[tree2->tri_index]); + + verts1 = cloth1->verts; + verts2 = cloth2->verts; - VECCOPY(collpair->normal, collpair->vector); - Normalize(collpair->normal); + if(i == 0) + { + collpair->Aindex1 = face1->v1; + collpair->Aindex2 = face1->v2; + collpair->Aindex3 = face1->v3; + collpair->Aindex4 = face1->v4; + + collpair->Bindex1 = face2->v1; + collpair->Bindex2 = face2->v2; + collpair->Bindex3 = face2->v3; + collpair->Bindex4 = face2->v4; + + } - collpair->distance = distance; - BLI_linklist_append(&linknode[tree1->tri_index], collpair); - } - else - { - MEM_freeN(collpair); + if(i == 1) + { + if(face2->v4) + { + collpair->Aindex1 = face1->v1; + collpair->Aindex2 = face1->v2; + collpair->Aindex3 = face1->v3; + collpair->Aindex4 = face1->v4; + + collpair->Bindex1 = face2->v4; + collpair->Bindex2 = face2->v3; + collpair->Bindex3 = face2->v1; + collpair->Bindex4 = face2->v1; + } + else + i++; + + } + + if(i == 2) + { + if(face1->v4) + { + collpair->Aindex1 = face1->v4; + collpair->Aindex2 = face1->v3; + collpair->Aindex3 = face1->v1; + collpair->Aindex4 = face1->v2; + + collpair->Bindex1 = face2->v1; + collpair->Bindex2 = face2->v2; + collpair->Bindex3 = face2->v3; + collpair->Bindex4 = face2->v4; + } + else + i++; + } + + if(i == 3) + { + if((face2->v4) && (face1->v4)) + { + collpair->Aindex1 = face1->v4; + collpair->Aindex2 = face1->v3; + collpair->Aindex3 = face1->v1; + collpair->Aindex4 = face1->v2; + + collpair->Bindex1 = face2->v4; + collpair->Bindex2 = face2->v3; + collpair->Bindex3 = face2->v1; + collpair->Bindex4 = face2->v2; + } + else + i++; + } + + if(i < 4) + { + distance = nearest_point_triangle_triangle(verts1[collpair->Aindex1].txold, verts1[collpair->Aindex2].txold, verts1[collpair->Aindex3].txold, verts2[collpair->Bindex1].txold, verts2[collpair->Bindex2].txold, verts2[collpair->Bindex3].txold, collpair->normal); + + // calc distance + normal + // distance = implicit_tri_check_coherence(clmd, coll_clmd, tree1->tri_index, tree2->tri_index, collpair->p1, collpair->p2, collpair->vector, collpair->quadA, collpair->quadB); + + if (distance <= (epsilon + ALMOST_ZERO)) // max overlap = 1.0 + { + + printf("dist: %f, tdist: %f\n", (float)distance, tdistance); + + collpair->face1 = tree1->tri_index; + collpair->face2 = tree2->tri_index; + + collpair->distance = distance; + BLI_linklist_append(&linknode[tree1->tri_index], collpair); + } + else + { + MEM_freeN(collpair); + } + } } } @@ -684,7 +973,7 @@ int cloth_bvh_objcollision(ClothModifierData * clmd, float step, CM_COLLISION_RE bvh_traverse(clmd, coll_clmd, cloth_bvh->root, coll_bvh->root, step, collision_response); - result += collision_static(clmd, coll_clmd, collision_list); + result += collision_static2(clmd, coll_clmd, collision_list); // calculate velocities From 6a72fecca73d9f45e04ee942dc85310e12b137cb Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Fri, 28 Sep 2007 11:06:13 +0000 Subject: [PATCH 019/246] Some additional wind problems (hopefully) fixed, added force fields, reported by Rui Paulo Sanguinheira Diogo --- source/blender/blenkernel/intern/implicit.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/source/blender/blenkernel/intern/implicit.c b/source/blender/blenkernel/intern/implicit.c index 0d0c7ff0f7b..3994bbf2b40 100644 --- a/source/blender/blenkernel/intern/implicit.c +++ b/source/blender/blenkernel/intern/implicit.c @@ -1261,7 +1261,7 @@ void calculateWeightedVertexNormal(ClothModifierData *clmd, MFace *mfaces, float } } } -float calculateVertexWindForce(int index, float wind[3], float vertexnormal[3]) +float calculateVertexWindForce(float wind[3], float vertexnormal[3]) { return fabs(INPR(wind, vertexnormal) * 0.5f); } @@ -1328,21 +1328,25 @@ void cloth_calc_force(ClothModifierData *clmd, lfVector *lF, lfVector *lX, lfVec /* handle external forces like wind */ if(effectors) { - float wind[3] = {0.0f,1.0f,0.0f}; + float speed[3] = {0.0f, 0.0f,0.0f}; float force[3]= {0.0f, 0.0f, 0.0f}; #pragma omp parallel for private (i) shared(lF) for(i = 0; i < cloth->numverts; i++) { float vertexnormal[3]={0,0,0}; + float fieldfactor = 1000.0f, windfactor = 250.0f; // from sb + + pdDoEffectors(effectors, lX[i], force, speed, (float)G.scene->r.cfra, 0.0f, PE_WIND_AS_SPEED); + + // TODO apply forcefields here + VECADDS(lF[i], lF[i], force, fieldfactor*0.01f); - pdDoEffectors(effectors, lX[i], force, wind, (float)G.scene->r.cfra, 0.0f, PE_WIND_AS_SPEED); - - VECCOPY(wind_normalized, wind); + VECCOPY(wind_normalized, speed); Normalize(wind_normalized); - + calculateWeightedVertexNormal(clmd, mfaces, vertexnormal, i, lX); - VECADDS(lF[i], lF[i], wind_normalized, calculateVertexWindForce(i, wind, vertexnormal)); + VECADDS(lF[i], lF[i], wind_normalized, -calculateVertexWindForce(speed, vertexnormal)); } } From 777c16d444d0227a9e59c7beb2ab2be3374fdef2 Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Mon, 1 Oct 2007 20:19:22 +0000 Subject: [PATCH 020/246] Bullet is back, but now generalized enough to allow own distance/calculation. Some bullet makefile-fix by 'gsr b3d'- please test it. Also fixed some crasher with cache. Also implemented moving-collisions enabled kdop (response missing in the moment) --- extern/bullet2/src/Bullet-C-Api.h | 2 +- .../BulletDynamics/Dynamics/Bullet-C-Api.cpp | 12 +- source/Makefile | 4 +- source/blender/blenkernel/BKE_cloth.h | 105 +- source/blender/blenkernel/intern/Makefile | 3 + source/blender/blenkernel/intern/cloth.c | 20 +- source/blender/blenkernel/intern/collision.c | 1265 ++++++++--------- source/blender/blenkernel/intern/implicit.c | 7 +- source/blender/blenkernel/intern/kdop.c | 98 +- source/blender/makesdna/DNA_cloth_types.h | 2 +- 10 files changed, 712 insertions(+), 806 deletions(-) diff --git a/extern/bullet2/src/Bullet-C-Api.h b/extern/bullet2/src/Bullet-C-Api.h index 2d35383e902..ccb0c452f3e 100644 --- a/extern/bullet2/src/Bullet-C-Api.h +++ b/extern/bullet2/src/Bullet-C-Api.h @@ -5,7 +5,7 @@ extern "C" { #endif // __cplusplus -double plNearestPoints(float p[3][3], float q[3][3], float *pa, float *pb, float normal[3]); +double plNearestPoints(float p1[3], float p2[3], float p3[3], float q1[3], float q2[3], float q3[3], float *pa, float *pb, float normal[3]); #ifdef __cplusplus } diff --git a/extern/bullet2/src/BulletDynamics/Dynamics/Bullet-C-Api.cpp b/extern/bullet2/src/BulletDynamics/Dynamics/Bullet-C-Api.cpp index 1b843774609..4051d3f3e1f 100644 --- a/extern/bullet2/src/BulletDynamics/Dynamics/Bullet-C-Api.cpp +++ b/extern/bullet2/src/BulletDynamics/Dynamics/Bullet-C-Api.cpp @@ -25,13 +25,13 @@ extern "C" -double plNearestPoints(float p[3][3], float q[3][3], float *pa, float *pb, float normal[3]) +double plNearestPoints(float p1[3], float p2[3], float p3[3], float q1[3], float q2[3], float q3[3], float *pa, float *pb, float normal[3]) { - btTriangleShape trishapeA(btVector3(p[0][0], p[0][1], p[0][2]), btVector3(p[1][0], p[1][1], p[1][2]), btVector3(p[2][0], p[2][1], p[2][2])); - trishapeA.setMargin(0.001f); + btTriangleShape trishapeA(btVector3(p1[0], p1[1], p1[2]), btVector3(p2[0], p2[1], p2[2]), btVector3(p3[0], p3[1], p3[2])); + trishapeA.setMargin(0.000001f); - btTriangleShape trishapeB(btVector3(q[0][0], q[0][1], q[0][2]), btVector3(q[1][0], q[1][1], q[1][2]), btVector3(q[2][0], q[2][1], q[2][2])); - trishapeB.setMargin(0.001f); + btTriangleShape trishapeB(btVector3(q1[0], q1[1], q1[2]), btVector3(q2[0], q2[1], q2[2]), btVector3(q3[0], q3[1], q3[2])); + trishapeB.setMargin(0.000001f); // btVoronoiSimplexSolver sGjkSimplexSolver; // btGjkEpaPenetrationDepthSolver penSolverPtr; @@ -44,7 +44,7 @@ double plNearestPoints(float p[3][3], float q[3][3], float *pa, float *pb, float btConvexPenetrationDepthSolver* Solver = NULL; - Solver = &Solver0; + Solver = &Solver1; btGjkPairDetector convexConvex(&trishapeA ,&trishapeB,&sGjkSimplexSolver,Solver); diff --git a/source/Makefile b/source/Makefile index 5161f6b73c5..e68aca215a1 100644 --- a/source/Makefile +++ b/source/Makefile @@ -149,9 +149,11 @@ ifneq ($(NAN_NO_KETSJI),true) COMLIB += $(OCGDIR)/gameengine/ketsji/KXNetwork/$(DEBUG_DIR)libKXNetwork.a COMLIB += $(OCGDIR)/gameengine/Network/$(DEBUG_DIR)libNetwork.a COMLIB += $(OCGDIR)/gameengine/Network/LoopBackNetwork/$(DEBUG_DIR)libLoopBackNetwork.a - COMLIB += $(NAN_BULLET2)/lib/libbullet2.a endif +# Required by cloth, not gameengine only anymore +COMLIB += $(NAN_BULLET2)/lib/$(DEBUG_DIR)libbullet2.a + COMLIB += $(NAN_GUARDEDALLOC)/lib/libguardedalloc.a COMLIB += $(NAN_MEMUTIL)/lib/libmemutil.a COMLIB += $(NAN_BMFONT)/lib/$(DEBUG_DIR)libbmfont.a diff --git a/source/blender/blenkernel/BKE_cloth.h b/source/blender/blenkernel/BKE_cloth.h index ec58382b86a..bbdf4bc01c9 100644 --- a/source/blender/blenkernel/BKE_cloth.h +++ b/source/blender/blenkernel/BKE_cloth.h @@ -1,36 +1,36 @@ /** -* BKE_cloth.h -* -* $Id: BKE_cloth.h,v 1.1 2007/08/01 02:07:27 daniel Exp $ -* -* ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** -* -* This program is free software; you can redistribute it and/or -* modify it under the terms of the GNU General Public License -* as published by the Free Software Foundation; either version 2 -* of the License, or (at your option) any later version. The Blender -* Foundation also sells licenses for use in proprietary software under -* the Blender License. See http://www.blender.org/BL/ for information -* about this. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program; if not, write to the Free Software Foundation, -* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -* -* The Original Code is Copyright (C) Blender Foundation. -* All rights reserved. -* -* The Original Code is: all of this file. -* -* Contributor(s): none yet. -* -* ***** END GPL/BL DUAL LICENSE BLOCK ***** -*/ + * BKE_cloth.h + * + * $Id: BKE_cloth.h,v 1.1 2007/08/01 02:07:27 daniel Exp $ + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) Blender Foundation. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + */ #ifndef BKE_CLOTH_H #define BKE_CLOTH_H @@ -46,10 +46,10 @@ struct DerivedMesh; // this is needed for inlining behaviour #ifndef _WIN32 - #define LINUX - #define DO_INLINE inline +#define LINUX +#define DO_INLINE inline #else - #define DO_INLINE +#define DO_INLINE #endif #define CLOTH_MAX_THREAD 2 @@ -86,27 +86,27 @@ struct DerivedMesh; typedef enum { CSIMSETT_FLAG_RESET = (1 << 1), // The CM object requires a reinitializaiton. - CSIMSETT_FLAG_COLLOBJ = (1 << 2), // object is only collision object, no cloth simulation is done - CSIMSETT_FLAG_GOAL = (1 << 3), // we have goals enabled - CSIMSETT_FLAG_CCACHE_FREE_ALL = (1 << 4), // delete all from cache - CSIMSETT_FLAG_CCACHE_FREE_PART = (1 << 5), // delete some part of cache - CSIMSETT_FLAG_TEARING_ENABLED = (1 << 6), // true if tearing is enabled - CSIMSETT_FLAG_CCACHE_PROTECT = (1 << 7), // true if tearing is enabled + CSIMSETT_FLAG_COLLOBJ = (1 << 2), // object is only collision object, no cloth simulation is done + CSIMSETT_FLAG_GOAL = (1 << 3), // we have goals enabled + CSIMSETT_FLAG_CCACHE_FREE_ALL = (1 << 4), // delete all from cache + CSIMSETT_FLAG_CCACHE_FREE_PART = (1 << 5), // delete some part of cache + CSIMSETT_FLAG_TEARING_ENABLED = (1 << 6), // true if tearing is enabled + CSIMSETT_FLAG_CCACHE_PROTECT = (1 << 7), // true if tearing is enabled } CSIMSETT_FLAGS; /* Spring types as defined in the paper.*/ typedef enum { STRUCTURAL = 0, - SHEAR, - BENDING, + SHEAR, + BENDING, } springType; /* SPRING FLAGS */ typedef enum { CSPRING_FLAG_DEACTIVATE = (1 << 1), - CSPRING_FLAG_NEEDED = (1 << 2), // springs has values to be applied + CSPRING_FLAG_NEEDED = (1 << 2), // springs has values to be applied } CSPRINGS_FLAGS; // needed for buttons_object.c @@ -156,7 +156,7 @@ typedef void (*CM_COLLISION_RESPONSE) (ClothModifierData *clmd, ClothModifierDat // needed for implicit.c void bvh_collision_response(ClothModifierData *clmd, ClothModifierData *coll_clmd, Tree * tree1, Tree * tree2); -int cloth_bvh_objcollision(ClothModifierData * clmd, float step, CM_COLLISION_RESPONSE collision_response, float dt); +int cloth_bvh_objcollision(ClothModifierData * clmd, float step, float dt); //////////////////////////////////////////////// @@ -165,16 +165,13 @@ int cloth_bvh_objcollision(ClothModifierData * clmd, float step, CM_COLLISION_RE // kdop.c //////////////////////////////////////////////// -// needed for implicit.c -void bvh_update_static(ClothModifierData * clmd, BVH * bvh); -void bvh_update_moving(ClothModifierData * clmd, BVH * bvh); - // needed for cloth.c void bvh_free(BVH * bvh); BVH *bvh_build (ClothModifierData *clmd, float epsilon); // needed for collision.c int bvh_traverse(ClothModifierData * clmd, ClothModifierData * coll_clmd, Tree * tree1, Tree * tree2, float step, CM_COLLISION_RESPONSE collision_response); +void bvh_update(ClothModifierData * clmd, BVH * bvh, int moving); //////////////////////////////////////////////// @@ -209,8 +206,7 @@ typedef struct { char *name; CM_SOLVER_ID id; int (*init) (Object *ob, ClothModifierData *clmd); - int (*solver) (Object *ob, float framenr, ClothModifierData *clmd, ListBase *effectors, - CM_COLLISION_SELF self_collision, CM_COLLISION_OBJ obj_collision); + int (*solver) (Object *ob, float framenr, ClothModifierData *clmd, ListBase *effectors); int (*free) (ClothModifierData *clmd); } CM_SOLVER_DEF; @@ -218,8 +214,7 @@ typedef struct { /* new C implicit simulator */ int implicit_init (Object *ob, ClothModifierData *clmd); int implicit_free (ClothModifierData *clmd); -int implicit_solver (Object *ob, float frame, ClothModifierData *clmd, ListBase *effectors, - CM_COLLISION_SELF self_collision, CM_COLLISION_OBJ obj_collision); +int implicit_solver (Object *ob, float frame, ClothModifierData *clmd, ListBase *effectors); /* used for caching in implicit.c */ typedef struct Frame @@ -237,10 +232,10 @@ typedef struct CollPair double distance; // magnitude of vector float normal[3]; float vector[3]; // unnormalized collision vector: p2-p1 - float p1[3], p2[3]; // collision point p1 on face1, p2 on face2 + float pa[3], pb[3]; // collision point p1 on face1, p2 on face2 int lastsign; // indicates if the distance sign has changed, unused itm float time; // collision time, from 0 up to 1 - unsigned int Aindex1, Aindex2, Aindex3, Aindex4, Bindex1, Bindex2, Bindex3, Bindex4; + unsigned int ap1, ap2, ap3, bp1, bp2, bp3; } CollPair; diff --git a/source/blender/blenkernel/intern/Makefile b/source/blender/blenkernel/intern/Makefile index 72fcc466de8..e87eb2a3e3f 100644 --- a/source/blender/blenkernel/intern/Makefile +++ b/source/blender/blenkernel/intern/Makefile @@ -77,6 +77,9 @@ CPPFLAGS += -I../../nodes # path to our own external headerfiles CPPFLAGS += -I.. +# path to bullet2, for cloth +CPPFLAGS += -I../../../../extern/bullet2/src + ifeq ($(WITH_FREETYPE2), true) CPPFLAGS += -DWITH_FREETYPE2 CPPFLAGS += -I$(NAN_FREETYPE)/include diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c index d9f0bef9f43..940fc8b6c5b 100644 --- a/source/blender/blenkernel/intern/cloth.c +++ b/source/blender/blenkernel/intern/cloth.c @@ -473,7 +473,6 @@ int cloth_cache_last_frame(ClothModifierData *clmd) search = search->next; } } - return temptime; } @@ -567,12 +566,7 @@ void cloth_cache_set_frame(ClothModifierData *clmd, float time) */ } if(frame) - { - if(!clmd->sim_parms.cache) - BLI_linklist_prepend(&clmd->sim_parms.cache, frame); - else - BLI_linklist_append(&clmd->sim_parms.cache, frame); - } + BLI_linklist_append(&clmd->sim_parms.cache, frame); } } @@ -683,6 +677,7 @@ void clothModifier_do(ClothModifierData *clmd, Object *ob, DerivedMesh *dm, } } + // unused in the moment, calculated seperately in implicit.c clmd->sim_parms.dt = 1.0f / clmd->sim_parms.stepsPerFrame; @@ -774,7 +769,7 @@ void clothModifier_do(ClothModifierData *clmd, Object *ob, DerivedMesh *dm, /* Call the solver. */ if (solvers [clmd->sim_parms.solver_type].solver) - solvers [clmd->sim_parms.solver_type].solver (ob, framenr, clmd, effectors,0,0); + solvers [clmd->sim_parms.solver_type].solver (ob, framenr, clmd, effectors); tend(); printf("Cloth simulation time: %f\n", (float)tval()); @@ -797,10 +792,13 @@ void clothModifier_do(ClothModifierData *clmd, Object *ob, DerivedMesh *dm, } else if((deltaTime <= 0.0f)||(deltaTime > 1.0f)) { - if(cloth_cache_search_frame(clmd, framenr)) + if((clmd->clothObject != NULL) && (clmd->sim_parms.cache)) { - cloth_cache_get_frame(clmd, framenr); - cloth_to_object (ob, clmd, vertexCos, numverts); + if(cloth_cache_search_frame(clmd, framenr)) + { + cloth_cache_get_frame(clmd, framenr); + cloth_to_object (ob, clmd, vertexCos, numverts); + } } } } diff --git a/source/blender/blenkernel/intern/collision.c b/source/blender/blenkernel/intern/collision.c index 7eec315e386..20c1548e14b 100644 --- a/source/blender/blenkernel/intern/collision.c +++ b/source/blender/blenkernel/intern/collision.c @@ -77,13 +77,13 @@ enum TRIANGLE_MARK { TM_MV = 1, - TM_ME = 2, - TM_V1 = 4, - TM_V2 = 8, - TM_V3 = 16, - TM_E1 = 32, - TM_E2 = 64, - TM_E3 = 128 + TM_ME = 2, + TM_V1 = 4, + TM_V2 = 8, + TM_V3 = 16, + TM_E1 = 32, + TM_E2 = 64, + TM_E3 = 128 }; DO_INLINE int hasTriangleMark(unsigned char mark, unsigned char bit) { return mark & bit; } @@ -104,64 +104,64 @@ void generateTriangleMarks() // 2.1 Randomly mark triangles for covering vertices. for (unsigned int v = 0; v < m_vertexCount; ++v) { - if (vertexCover(v) == 0) - { + if (vertexCover(v) == 0) + { // Randomly select an edge whose first triangle we're going to flag. #ifndef DERANDOMIZE - firstEdge = (unsigned int)((float)(random() & 0x7FFFFFFF) / - (float)(0x80000000) * - (float)(m_vertices[v].getEdgeCount())); + firstEdge = (unsigned int)((float)(random() & 0x7FFFFFFF) / + (float)(0x80000000) * + (float)(m_vertices[v].getEdgeCount())); #endif - for (unsigned int ofs = 0; ofs < m_vertices[v].getEdgeCount(); ++ofs) - { - unsigned int edgeIdx = (firstEdge + ofs) % m_vertices[v].getEdgeCount(); - if (m_edges[m_vertices[v].getEdge(edgeIdx)].getTriangleCount()) - setTriangleMark(m_triangleMarks[m_edges[m_vertices[v].getEdge(edgeIdx)].getTriangle(0)], TM_MV); - } - } - } + for (unsigned int ofs = 0; ofs < m_vertices[v].getEdgeCount(); ++ofs) + { + unsigned int edgeIdx = (firstEdge + ofs) % m_vertices[v].getEdgeCount(); + if (m_edges[m_vertices[v].getEdge(edgeIdx)].getTriangleCount()) + setTriangleMark(m_triangleMarks[m_edges[m_vertices[v].getEdge(edgeIdx)].getTriangle(0)], TM_MV); +} +} +} */ /* If the Cloth is malformed (vertices without adjacent triangles) there might still be uncovered vertices. (Bad luck.) */ /* // 2.2 Randomly mark triangles for covering edges. for (unsigned int e = 0; e < m_edgeCount; ++e) { - if (m_edges[e].getTriangleCount() && (edgeCover(e) == 0)) - { + if (m_edges[e].getTriangleCount() && (edgeCover(e) == 0)) + { #ifndef DERANDOMIZE - setTriangleMark(m_triangleMarks[m_edges[e].getTriangle(static_cast((float)(random() & 0x7FFFFFFF) / - (float)(0x80000000) * - (float)(m_edges[e].getTriangleCount())))], TM_ME); + setTriangleMark(m_triangleMarks[m_edges[e].getTriangle(static_cast((float)(random() & 0x7FFFFFFF) / + (float)(0x80000000) * + (float)(m_edges[e].getTriangleCount())))], TM_ME); #else - setTriangleMark(m_triangleMarks[m_edges[e].getTriangle(0)], TM_ME); + setTriangleMark(m_triangleMarks[m_edges[e].getTriangle(0)], TM_ME); #endif - } - } +} +} // 3. The Unmarking Process for (unsigned int t = 0; (t < m_triangleCount); ++t) { - bool overCoveredVertices = true; - bool overCoveredEdges = true; - for (unsigned char i = 0; (i < 3) && (overCoveredVertices || overCoveredEdges); ++i) - { + bool overCoveredVertices = true; + bool overCoveredEdges = true; + for (unsigned char i = 0; (i < 3) && (overCoveredVertices || overCoveredEdges); ++i) + { - if (vertexCover(m_triangles[t].getVertex(i)) == 1) - overCoveredVertices = false; - if (edgeCover(m_triangles[t].getEdge(i)) == 1) - overCoveredEdges = false; + if (vertexCover(m_triangles[t].getVertex(i)) == 1) + overCoveredVertices = false; + if (edgeCover(m_triangles[t].getEdge(i)) == 1) + overCoveredEdges = false; - assert(vertexCover(m_triangles[t].getVertex(i)) > 0); - assert(edgeCover(m_triangles[t].getEdge(i)) > 0); - } - if (overCoveredVertices) - clearTriangleMark(m_triangleMarks[t], TM_MV); - if (overCoveredEdges) - clearTriangleMark(m_triangleMarks[t], TM_ME); - } + assert(vertexCover(m_triangles[t].getVertex(i)) > 0); + assert(edgeCover(m_triangles[t].getEdge(i)) > 0); +} + if (overCoveredVertices) + clearTriangleMark(m_triangleMarks[t], TM_MV); + if (overCoveredEdges) + clearTriangleMark(m_triangleMarks[t], TM_ME); +} // 4. The Bit Masking Process @@ -169,25 +169,25 @@ void generateTriangleMarks() vector edgeAssigned(m_edgeCount, false); for (unsigned int t = 0; (t < m_triangleCount); ++t) { - for (unsigned char i = 0; i < 3; ++i) - { - if (!vertexAssigned[m_triangles[t].getVertex(i)]) - { - vertexAssigned[m_triangles[t].getVertex(i)] = true; - setTriangleMark(m_triangleMarks[t], 1 << (2 + i)); - } - if (!edgeAssigned[m_triangles[t].getEdge(i)]) - { - edgeAssigned[m_triangles[t].getEdge(i)] = true; - setTriangleMark(m_triangleMarks[t], 1 << (5 + i)); - } - } - } + for (unsigned char i = 0; i < 3; ++i) + { + if (!vertexAssigned[m_triangles[t].getVertex(i)]) + { + vertexAssigned[m_triangles[t].getVertex(i)] = true; + setTriangleMark(m_triangleMarks[t], 1 << (2 + i)); +} + if (!edgeAssigned[m_triangles[t].getEdge(i)]) + { + edgeAssigned[m_triangles[t].getEdge(i)] = true; + setTriangleMark(m_triangleMarks[t], 1 << (5 + i)); +} +} +} */ } // w3 is not perfect -void bvh_compute_barycentric (float pv[3], float p1[3], float p2[3], float p3[3], double *w1, double *w2, double *w3) +void bvh_compute_barycentric (float pv[3], float p1[3], float p2[3], float p3[3], float *w1, float *w2, float *w3) { double tempV1[3], tempV2[3], tempV4[3]; double a,b,c,d,e,f; @@ -205,13 +205,19 @@ void bvh_compute_barycentric (float pv[3], float p1[3], float p2[3], float p3[3] d = (a * c - b * b); if (ABS(d) < ALMOST_ZERO) { - *w1 = *w2 = *w3 = 1.0f / 3.0f; + *w1 = *w2 = *w3 = 1.0 / 3.0; return; } - w1[0] = (e * c - b * f) / d; + w1[0] = (float)((e * c - b * f) / d); - w2[0] = (f - b * w1[0]) / c; + if(w1[0] < 0) + w1[0] = 0; + + w2[0] = (float)((f - b * (double)w1[0]) / c); + + if(w2[0] < 0) + w2[0] = 0; w3[0] = 1.0f - w1[0] - w2[0]; } @@ -226,7 +232,7 @@ DO_INLINE void interpolateOnTriangle(float to[3], float v1[3], float v2[3], floa DO_INLINE void calculateFrictionImpulse(float to[3], float vrel[3], float normal[3], double normalVelocity, - double frictionConstant, double delta_V_n) + double frictionConstant, double delta_V_n) { float vrel_t_pre[3]; float vrel_t[3]; @@ -235,631 +241,376 @@ DO_INLINE void calculateFrictionImpulse(float to[3], float vrel[3], float normal VecMulf(to, MAX2(1.0f - frictionConstant * delta_V_n / INPR(vrel_t_pre,vrel_t_pre), 0.0f)); } -/* -int collision_static(ClothModifierData *clmd, ClothModifierData *coll_clmd, LinkNode **collision_list) + +int collision_static(ClothModifierData *clmd, ClothModifierData *coll_clmd) { - unsigned int i = 0, numfaces = 0; + unsigned int i = 0; int result = 0; LinkNode *search = NULL; CollPair *collpair = NULL; Cloth *cloth1, *cloth2; - MFace *face1, *face2; - double w1, w2, w3, u1, u2, u3, a1, a2, a3; + float w1, w2, w3, u1, u2, u3; float v1[3], v2[3], relativeVelocity[3]; float magrelVel; cloth1 = clmd->clothObject; cloth2 = coll_clmd->clothObject; - - numfaces = clmd->clothObject->numfaces; - - for(i = 0; i < numfaces; i++) - { - search = collision_list[i]; - - while(search) - { - collpair = search->link; - - face1 = &(cloth1->mfaces[collpair->face1]); - face2 = &(cloth2->mfaces[collpair->face2]); - - // compute barycentric coordinates for both collision points - - if(!collpair->quadA) - { - bvh_compute_barycentric(collpair->p1, - cloth1->verts[face1->v1].txold, - cloth1->verts[face1->v2].txold, - cloth1->verts[face1->v3].txold, - &w1, &w2, &w3); - } - else - bvh_compute_barycentric(collpair->p1, - cloth1->verts[face1->v4].txold, - cloth1->verts[face1->v1].txold, - cloth1->verts[face1->v3].txold, - &w1, &w2, &w3); - - if(!collpair->quadB) - bvh_compute_barycentric(collpair->p2, - cloth2->verts[face2->v1].txold, - cloth2->verts[face2->v2].txold, - cloth2->verts[face2->v3].txold, - &u1, &u2, &u3); - else - bvh_compute_barycentric(collpair->p2, - cloth2->verts[face2->v4].txold, - cloth2->verts[face2->v1].txold, - cloth2->verts[face2->v3].txold, - &u1, &u2, &u3); - - // Calculate relative "velocity". - - if(!collpair->quadA) - interpolateOnTriangle(v1, cloth1->verts[face1->v1].tv, cloth1->verts[face1->v2].tv, cloth1->verts[face1->v3].tv, w1, w2, w3); - else - interpolateOnTriangle(v1, cloth1->verts[face1->v4].tv, cloth1->verts[face1->v1].tv, cloth1->verts[face1->v3].tv, w1, w2, w3); - - if(!collpair->quadB) - interpolateOnTriangle(v2, cloth2->verts[face2->v1].tv, cloth2->verts[face2->v2].tv, cloth2->verts[face2->v3].tv, u1, u2, u3); - else - interpolateOnTriangle(v2, cloth2->verts[face2->v4].tv, cloth2->verts[face2->v1].tv, cloth2->verts[face2->v3].tv, u1, u2, u3); - - VECSUB(relativeVelocity, v1, v2); - - // Calculate the normal component of the relative velocity (actually only the magnitude - the direction is stored in 'normal'). - magrelVel = INPR(relativeVelocity, collpair->normal); - - // Calculate masses of points. - - // If v_n_mag > 0 the edges are approaching each other. - - if(magrelVel < -ALMOST_ZERO) - { - // Calculate Impulse magnitude to stop all motion in normal direction. - // const double I_mag = v_n_mag / (1/m1 + 1/m2); - float magnitude_i = magrelVel / 2.0f; // TODO implement masses - float tangential[3], magtangent, magnormal, collvel[3]; - float vrel_t_pre[3]; - float vrel_t[3]; - double impulse; - float epsilon = clmd->coll_parms.epsilon; - float overlap = (epsilon + ALMOST_ZERO-collpair->distance); - - // calculateFrictionImpulse(tangential, relativeVelocity, collpair->normal, magrelVel, clmd->coll_parms.friction*0.01, magrelVel); - - // magtangent = INPR(tangential, tangential); - - // Apply friction impulse. - if (magtangent < ALMOST_ZERO) - { - - // printf("friction applied: %f\n", magtangent); - // TODO check original code - - VECSUB(cloth1->verts[face1->v1].tv, cloth1->verts[face1->v1].tv,tangential); - VECSUB(cloth1->verts[face1->v1].tv, cloth1->verts[face1->v2].tv,tangential); - VECSUB(cloth1->verts[face1->v1].tv, cloth1->verts[face1->v3].tv,tangential); - VECSUB(cloth1->verts[face1->v1].tv, cloth1->verts[face1->v4].tv,tangential); - - } - - impulse = -magrelVel / ( 1.0 + w1*w1 + w2*w2 + w3*w3); - VECADDMUL(cloth1->verts[face1->v1].impulse, collpair->normal, impulse); - cloth1->verts[face1->v1].impulse_count++; - - VECADDMUL(cloth1->verts[face1->v2].impulse, collpair->normal, impulse); - cloth1->verts[face1->v2].impulse_count++; - - VECADDMUL(cloth1->verts[face1->v3].impulse, collpair->normal, impulse); - cloth1->verts[face1->v3].impulse_count++; - - if(face1->v4) - { - VECADDMUL(cloth1->verts[face1->v4].impulse, collpair->normal, impulse); - cloth1->verts[face1->v4].impulse_count++; - } - - - if (overlap > ALMOST_ZERO) { - double I_mag = overlap * 0.1; - - impulse = I_mag / ( 1.0 + w1*w1 + w2*w2 + w3*w3); - - VECADDMUL(cloth1->verts[face1->v1].impulse, collpair->normal, impulse); - cloth1->verts[face1->v1].impulse_count++; - - VECADDMUL(cloth1->verts[face1->v2].impulse, collpair->normal, impulse); - cloth1->verts[face1->v2].impulse_count++; - - VECADDMUL(cloth1->verts[face1->v3].impulse, collpair->normal, impulse); - cloth1->verts[face1->v3].impulse_count++; - - if(face1->v4) - { - VECADDMUL(cloth1->verts[face1->v4].impulse, collpair->normal, impulse); - cloth1->verts[face1->v4].impulse_count++; - } - - } - - result = 1; - - - // printf("magnitude_i: %f\n", magnitude_i); // negative before collision in my case - - // Apply the impulse and increase impulse counters. - / - // calculateFrictionImpulse(tangential, collvel, collpair->normal, magtangent, clmd->coll_parms.friction*0.01, magtangent); - VECSUBS(vrel_t_pre, collvel, collpair->normal, magnormal); - // VecMulf(vrel_t_pre, clmd->coll_parms.friction*0.01f/INPR(vrel_t_pre,vrel_t_pre)); - magtangent = Normalize(vrel_t_pre); - VecMulf(vrel_t_pre, MIN2(clmd->coll_parms.friction*0.01f*magnormal,magtangent)); - - VECSUB(cloth1->verts[face1->v1].tv, cloth1->verts[face1->v1].tv,vrel_t_pre); - - + search = clmd->coll_parms.collision_list; + + while(search) + { + collpair = search->link; + + // compute barycentric coordinates for both collision points + bvh_compute_barycentric(collpair->pa, + cloth1->verts[collpair->ap1].txold, + cloth1->verts[collpair->ap2].txold, + cloth1->verts[collpair->ap3].txold, + &w1, &w2, &w3); + + bvh_compute_barycentric(collpair->pb, + cloth2->verts[collpair->bp1].txold, + cloth2->verts[collpair->bp2].txold, + cloth2->verts[collpair->bp3].txold, + &u1, &u2, &u3); + + // Calculate relative "velocity". + interpolateOnTriangle(v1, cloth1->verts[collpair->ap1].tv, cloth1->verts[collpair->ap2].tv, cloth1->verts[collpair->ap3].tv, w1, w2, w3); + + interpolateOnTriangle(v2, cloth2->verts[collpair->bp1].tv, cloth2->verts[collpair->bp2].tv, cloth2->verts[collpair->bp3].tv, u1, u2, u3); + + VECSUB(relativeVelocity, v1, v2); + + // Calculate the normal component of the relative velocity (actually only the magnitude - the direction is stored in 'normal'). + magrelVel = INPR(relativeVelocity, collpair->normal); + + // printf("magrelVel: %f\n", magrelVel); + // Calculate masses of points. + + // If v_n_mag < 0 the edges are approaching each other. + if(magrelVel < -ALMOST_ZERO) + { + // Calculate Impulse magnitude to stop all motion in normal direction. + // const double I_mag = v_n_mag / (1/m1 + 1/m2); + float magnitude_i = magrelVel / 2.0f; // TODO implement masses + float tangential[3], magtangent, magnormal, collvel[3]; + float vrel_t_pre[3]; + float vrel_t[3]; + double impulse; + float epsilon = clmd->coll_parms.epsilon; + float overlap = (epsilon + ALMOST_ZERO-collpair->distance); + + // calculateFrictionImpulse(tangential, relativeVelocity, collpair->normal, magrelVel, clmd->coll_parms.friction*0.01, magrelVel); + + // magtangent = INPR(tangential, tangential); + + // Apply friction impulse. + if (magtangent < -ALMOST_ZERO) + { + // printf("friction applied: %f\n", magtangent); + // TODO check original code + /* + VECSUB(cloth1->verts[face1->v1].tv, cloth1->verts[face1->v1].tv,tangential); + VECSUB(cloth1->verts[face1->v1].tv, cloth1->verts[face1->v2].tv,tangential); + VECSUB(cloth1->verts[face1->v1].tv, cloth1->verts[face1->v3].tv,tangential); + VECSUB(cloth1->verts[face1->v1].tv, cloth1->verts[face1->v4].tv,tangential); + */ } - search = search->next; + + impulse = -2.0f * magrelVel / ( 1.0 + w1*w1 + w2*w2 + w3*w3); + + // printf("impulse: %f\n", impulse); + + VECADDMUL(cloth1->verts[collpair->ap1].impulse, collpair->normal, w1 * impulse); + cloth1->verts[collpair->ap1].impulse_count++; + + VECADDMUL(cloth1->verts[collpair->ap2].impulse, collpair->normal, w2 * impulse); + cloth1->verts[collpair->ap2].impulse_count++; + + VECADDMUL(cloth1->verts[collpair->ap3].impulse, collpair->normal, w3 * impulse); + cloth1->verts[collpair->ap3].impulse_count++; + + result = 1; + + /* + if (overlap > ALMOST_ZERO) { + double I_mag = overlap * 0.1; + + impulse = -I_mag / ( 1.0 + w1*w1 + w2*w2 + w3*w3); + + VECADDMUL(cloth1->verts[collpair->ap1].impulse, collpair->normal, w1 * impulse); + cloth1->verts[collpair->ap1].impulse_count++; + + VECADDMUL(cloth1->verts[collpair->ap2].impulse, collpair->normal, w2 * impulse); + cloth1->verts[collpair->ap2].impulse_count++; + + VECADDMUL(cloth1->verts[collpair->ap3].impulse, collpair->normal, w3 * impulse); + cloth1->verts[collpair->ap3].impulse_count++; } + */ + + // printf("magnitude_i: %f\n", magnitude_i); // negative before collision in my case + + // Apply the impulse and increase impulse counters. + + /* + // calculateFrictionImpulse(tangential, collvel, collpair->normal, magtangent, clmd->coll_parms.friction*0.01, magtangent); + VECSUBS(vrel_t_pre, collvel, collpair->normal, magnormal); + // VecMulf(vrel_t_pre, clmd->coll_parms.friction*0.01f/INPR(vrel_t_pre,vrel_t_pre)); + magtangent = Normalize(vrel_t_pre); + VecMulf(vrel_t_pre, MIN2(clmd->coll_parms.friction*0.01f*magnormal,magtangent)); + + VECSUB(cloth1->verts[face1->v1].tv, cloth1->verts[face1->v1].tv,vrel_t_pre); + */ + + + + } + + search = search->next; } + return result; } -*/ - -// return distance between two triangles using bullet engine -double implicit_tri_check_coherence (ClothModifierData *clmd, ClothModifierData *coll_clmd, unsigned int tri_index1, unsigned int tri_index2, float pa[3], float pb[3], float normal[3], int quadA, int quadB) + +void bvh_collision_response_static(ClothModifierData *clmd, ClothModifierData *coll_clmd, Tree *tree1, Tree *tree2) { + CollPair *collpair = NULL; + Cloth *cloth1=NULL, *cloth2=NULL; MFace *face1=NULL, *face2=NULL; - float a[3][3]; - float b[3][3]; - double distance=0, tempdistance=0; - Cloth *cloth1=NULL, *cloth2=NULL; - float tpa[3], tpb[3], tnormal[3]; - unsigned int indexA=0, indexB=0, indexC=0, indexD=0, indexE=0, indexF=0; - int i = 0; - - cloth1 = clmd->clothObject; - cloth2 = coll_clmd->clothObject; - - face1 = &(cloth1->mfaces[tri_index1]); - face2 = &(cloth2->mfaces[tri_index2]); - - // face a1 + face b1 - VECCOPY(a[0], cloth1->verts[face1->v1].txold); - VECCOPY(a[1], cloth1->verts[face1->v2].txold); - VECCOPY(a[2], cloth1->verts[face1->v3].txold); - - - VECCOPY(b[0], cloth2->verts[face2->v1].txold); - VECCOPY(b[1], cloth2->verts[face2->v2].txold); - VECCOPY(b[2], cloth2->verts[face2->v3].txold); - - distance = plNearestPoints(a,b,pa,pb,normal); - - quadA = quadB = 0; - - for(i = 0; i < 3; i++) - { - if(i == 0) - { - if(face1->v4) - { - indexA = face1->v4; - indexB = face1->v1; - indexC = face1->v3; - - indexD = face2->v1; - indexE = face2->v2; - indexF = face2->v3; - } - else - i+=2; - } - - if(i == 1) - { - if((face1->v4)&&(face2->v4)) - { - indexA = face1->v4; - indexB = face1->v1; - indexC = face1->v3; - - indexD = face2->v4; - indexE = face2->v1; - indexF = face2->v3; - } - else - i++; - } - - if(i == 2) - { - if(face2->v4) - { - indexA = face1->v1; - indexB = face1->v2; - indexC = face1->v3; - - indexD = face2->v4; - indexE = face2->v1; - indexF = face2->v3; - } - else - i++; - - } - - if(i<3) - { - // face a2 + face b1 - VECCOPY(a[0], cloth1->verts[indexA].txold); - VECCOPY(a[1], cloth1->verts[indexB].txold); - VECCOPY(a[2], cloth1->verts[indexC].txold); - - - VECCOPY(b[0], cloth2->verts[indexD].txold); - VECCOPY(b[1], cloth2->verts[indexE].txold); - VECCOPY(b[2], cloth2->verts[indexF].txold); - - tempdistance = plNearestPoints(a,b,tpa,tpb,tnormal); - - if(tempdistance < distance) - { - VECCOPY(pa, tpa); - VECCOPY(pb, tpb); - VECCOPY(normal, tnormal); - distance = tempdistance; - - if(i == 0) - { - quadA = 1; quadB = 0; - } - else if(i == 1) - { - quadA = quadB = 1; - } - else if(i == 2) - { - quadA = 0; quadB = 1; - } - } - } - } - return distance; -} - -// calculate plane normal -void calcPlaneNormal(float normal[3], float p11[3], float p12[3], float p13[3]) -{ - float temp1[3], temp2[3]; - float tnormal[3]; - - VECSUB(temp1, p12,p11); - VECSUB(temp2, p13,p11); - Crossf(normal, temp1, temp2); - Normalize(normal); - // VECCOPY(normal, tnormal); -} - -float distance_triangle_point( float p11[3], float p12[3], float p13[3], float p21[3], float normal[3]) -{ - float temp[3]; - float magnitude = 0; - - VECSUB(temp, p21, p13); - magnitude = INPR(temp, normal); - - if(magnitude < 0) - { - magnitude *= -1.0f; - // VecMulf(normal, -1.0f); - } - - return magnitude; -} - -float nearest_point_triangle_triangle(float p11[3], float p12[3], float p13[3], float p21[3], float p22[3], float p23[3], float normal[3]) -{ - float distance = 0, tdistance = 0, tnormal[3]; - - // first triangle 1-2-3 versus second triangle 1-2-3 - calcPlaneNormal(normal, p11, p12, p13); - distance = distance_triangle_point(p11, p12, p13, p21, normal); - - tdistance = distance_triangle_point(p11, p12, p13, p22, normal); - - if(tdistance < distance) - { - distance = tdistance; - } - - tdistance = distance_triangle_point(p11, p12, p13, p23, normal); - - if(tdistance < distance) - { - distance = tdistance; - } - - // second triangle 1-2-3 versus first triangle 1-2-3 - calcPlaneNormal(tnormal, p21, p22, p23); - - tdistance = distance_triangle_point(p21, p22, p23, p11, tnormal); - - if(tdistance < distance) - { - distance = tdistance; - VECCOPY(normal, tnormal); - } - - tdistance = distance_triangle_point(p21, p22, p23, p12, tnormal); - - if(tdistance < distance) - { - distance = tdistance; - VECCOPY(normal, tnormal); - } - - tdistance = distance_triangle_point(p21, p22, p23, p13, tnormal); - - if(tdistance < distance) - { - distance = tdistance; - VECCOPY(normal, tnormal); - } - - - if (distance < 0) { - VecMulf(normal, -1.0f); - distance = -distance; - } - - return distance; -} - - -int collision_static2(ClothModifierData *clmd, ClothModifierData *coll_clmd, LinkNode **collision_list) -{ - unsigned int i = 0, numfaces = 0; - int result = 0; - LinkNode *search = NULL; - CollPair *collpair = NULL; - Cloth *cloth1, *cloth2; - MFace *face1, *face2; - double w1, w2, w3, u1, u2, u3, a1, a2, a3; - float v1[3], v2[3], relativeVelocity[3]; - float magrelVel; - - cloth1 = clmd->clothObject; - cloth2 = coll_clmd->clothObject; - - numfaces = clmd->clothObject->numfaces; - - for(i = 0; i < numfaces; i++) - { - search = collision_list[i]; - - while(search) - { - collpair = search->link; - - face1 = &(cloth1->mfaces[collpair->face1]); - face2 = &(cloth2->mfaces[collpair->face2]); - - // compute barycentric coordinates for both collision points - - - bvh_compute_barycentric(collpair->p1, - cloth1->verts[collpair->Aindex1].txold, - cloth1->verts[collpair->Aindex2].txold, - cloth1->verts[collpair->Aindex3].txold, - &w1, &w2, &w3); - - bvh_compute_barycentric(collpair->p2, - cloth2->verts[collpair->Bindex1].txold, - cloth2->verts[collpair->Bindex1].txold, - cloth2->verts[collpair->Bindex3].txold, - &u1, &u2, &u3); - - // Calculate relative "velocity". - interpolateOnTriangle(v1, cloth1->verts[collpair->Aindex1].tv, cloth1->verts[collpair->Aindex2].tv, cloth1->verts[collpair->Aindex3].tv, w1, w2, w3); - - interpolateOnTriangle(v2, cloth2->verts[collpair->Bindex1].tv, cloth2->verts[collpair->Bindex2].tv, cloth2->verts[collpair->Bindex3].tv, u1, u2, u3); - - VECSUB(relativeVelocity, v1, v2); - - // Calculate the normal component of the relative velocity (actually only the magnitude - the direction is stored in 'normal'). - magrelVel = INPR(relativeVelocity, collpair->normal); - - // Calculate masses of points. - - // If v_n_mag > 0 the edges are approaching each other. - - if(magrelVel < -ALMOST_ZERO) - { - // Calculate Impulse magnitude to stop all motion in normal direction. - // const double I_mag = v_n_mag / (1/m1 + 1/m2); - float magnitude_i = magrelVel / 2.0f; // TODO implement masses - float tangential[3], magtangent, magnormal, collvel[3]; - float vrel_t_pre[3]; - float vrel_t[3]; - double impulse; - float epsilon = clmd->coll_parms.epsilon; - float overlap = (epsilon + ALMOST_ZERO-collpair->distance); - - /* - impulse = -magrelVel / ( 1.0 + w1*w1 + w2*w2 + w3*w3); - VECADDMUL(cloth1->verts[face1->v1].impulse, collpair->normal, impulse); - cloth1->verts[face1->v1].impulse_count++; - - VECADDMUL(cloth1->verts[face1->v2].impulse, collpair->normal, impulse); - cloth1->verts[face1->v2].impulse_count++; - - VECADDMUL(cloth1->verts[face1->v3].impulse, collpair->normal, impulse); - cloth1->verts[face1->v3].impulse_count++; - */ - - - /* - if (overlap > ALMOST_ZERO) { - double I_mag = overlap * 0.1; - - impulse = I_mag / ( 1.0 + w1*w1 + w2*w2 + w3*w3); - - VECADDMUL(cloth1->verts[face1->v1].impulse, collpair->normal, impulse); - cloth1->verts[face1->v1].impulse_count++; - - VECADDMUL(cloth1->verts[face1->v2].impulse, collpair->normal, impulse); - cloth1->verts[face1->v2].impulse_count++; - - VECADDMUL(cloth1->verts[face1->v3].impulse, collpair->normal, impulse); - cloth1->verts[face1->v3].impulse_count++; - - if(face1->v4) - { - VECADDMUL(cloth1->verts[face1->v4].impulse, collpair->normal, impulse); - cloth1->verts[face1->v4].impulse_count++; - } - - } - */ - - result = 1; - } - - search = search->next; - } - } - - return result; -} - -void bvh_collision_response(ClothModifierData *clmd, ClothModifierData *coll_clmd, Tree * tree1, Tree * tree2) -{ - CollPair *collpair = NULL; - LinkNode **linknode; + ClothVertex *verts1=NULL, *verts2=NULL; double distance = 0; - float epsilon = clmd->coll_parms.epsilon, tdistance=0; - MFace *face1, *face2; - ClothVertex *verts1, *verts2; - Cloth *cloth1=NULL, *cloth2=NULL; - int i = 0; - - linknode = clmd->coll_parms.temp; - - cloth1 = clmd->clothObject; - cloth2 = coll_clmd->clothObject; - - // calc SIPcode (?) - + float epsilon = clmd->coll_parms.epsilon; + unsigned int i = 0; + for(i = 0; i < 4; i++) { - collpair = (CollPair *)MEM_callocN(sizeof(CollPair), "cloth coll pair"); + collpair = (CollPair *)MEM_callocN(sizeof(CollPair), "cloth coll pair"); + + cloth1 = clmd->clothObject; + cloth2 = coll_clmd->clothObject; - face1 = &(cloth1->mfaces[tree1->tri_index]); - face2 = &(cloth2->mfaces[tree2->tri_index]); - verts1 = cloth1->verts; verts2 = cloth2->verts; + + face1 = &(cloth1->mfaces[tree1->tri_index]); + face2 = &(cloth2->mfaces[tree2->tri_index]); + // check all possible pairs of triangles if(i == 0) { - collpair->Aindex1 = face1->v1; - collpair->Aindex2 = face1->v2; - collpair->Aindex3 = face1->v3; - collpair->Aindex4 = face1->v4; + collpair->ap1 = face1->v1; + collpair->ap2 = face1->v2; + collpair->ap3 = face1->v3; - collpair->Bindex1 = face2->v1; - collpair->Bindex2 = face2->v2; - collpair->Bindex3 = face2->v3; - collpair->Bindex4 = face2->v4; + collpair->bp1 = face2->v1; + collpair->bp2 = face2->v2; + collpair->bp3 = face2->v3; } if(i == 1) { - if(face2->v4) - { - collpair->Aindex1 = face1->v1; - collpair->Aindex2 = face1->v2; - collpair->Aindex3 = face1->v3; - collpair->Aindex4 = face1->v4; + if(face1->v4) + { + collpair->ap1 = face1->v3; + collpair->ap2 = face1->v4; + collpair->ap3 = face1->v1; - collpair->Bindex1 = face2->v4; - collpair->Bindex2 = face2->v3; - collpair->Bindex3 = face2->v1; - collpair->Bindex4 = face2->v1; + collpair->bp1 = face2->v1; + collpair->bp2 = face2->v2; + collpair->bp3 = face2->v3; } else i++; - } if(i == 2) { - if(face1->v4) - { - collpair->Aindex1 = face1->v4; - collpair->Aindex2 = face1->v3; - collpair->Aindex3 = face1->v1; - collpair->Aindex4 = face1->v2; + if(face2->v4) + { + collpair->ap1 = face1->v1; + collpair->ap2 = face1->v2; + collpair->ap3 = face1->v3; - collpair->Bindex1 = face2->v1; - collpair->Bindex2 = face2->v2; - collpair->Bindex3 = face2->v3; - collpair->Bindex4 = face2->v4; + collpair->bp1 = face2->v3; + collpair->bp2 = face2->v4; + collpair->bp3 = face2->v1; } else - i++; + i+=2; } if(i == 3) { - if((face2->v4) && (face1->v4)) - { - collpair->Aindex1 = face1->v4; - collpair->Aindex2 = face1->v3; - collpair->Aindex3 = face1->v1; - collpair->Aindex4 = face1->v2; + if((face1->v4)&&(face2->v4)) + { + collpair->ap1 = face1->v3; + collpair->ap2 = face1->v4; + collpair->ap3 = face1->v1; - collpair->Bindex1 = face2->v4; - collpair->Bindex2 = face2->v3; - collpair->Bindex3 = face2->v1; - collpair->Bindex4 = face2->v2; + collpair->bp1 = face2->v3; + collpair->bp2 = face2->v4; + collpair->bp3 = face2->v1; } else i++; } + // calc SIPcode (?) + if(i < 4) { - distance = nearest_point_triangle_triangle(verts1[collpair->Aindex1].txold, verts1[collpair->Aindex2].txold, verts1[collpair->Aindex3].txold, verts2[collpair->Bindex1].txold, verts2[collpair->Bindex2].txold, verts2[collpair->Bindex3].txold, collpair->normal); - // calc distance + normal - // distance = implicit_tri_check_coherence(clmd, coll_clmd, tree1->tri_index, tree2->tri_index, collpair->p1, collpair->p2, collpair->vector, collpair->quadA, collpair->quadB); + distance = plNearestPoints( + verts1[collpair->ap1].txold, verts1[collpair->ap2].txold, verts1[collpair->ap3].txold, verts2[collpair->bp1].txold, verts2[collpair->bp2].txold, verts2[collpair->bp3].txold, + collpair->pa, collpair->pb, collpair->vector); - if (distance <= (epsilon + ALMOST_ZERO)) // max overlap = 1.0 + if (distance <= (epsilon + ALMOST_ZERO)) { + // printf("dist: %f\n", (float)distance); - printf("dist: %f, tdist: %f\n", (float)distance, tdistance); + // collpair->face1 = tree1->tri_index; + // collpair->face2 = tree2->tri_index; - collpair->face1 = tree1->tri_index; - collpair->face2 = tree2->tri_index; + VECCOPY(collpair->normal, collpair->vector); + Normalize(collpair->normal); collpair->distance = distance; - BLI_linklist_append(&linknode[tree1->tri_index], collpair); + BLI_linklist_append(&clmd->coll_parms.collision_list, collpair); } else { MEM_freeN(collpair); } } + else + { + MEM_freeN(collpair); + } + } +} + +void bvh_collision_response_moving(ClothModifierData *clmd, ClothModifierData *coll_clmd, Tree *tree1, Tree *tree2) +{ + CollPair *collpair = NULL; + Cloth *cloth1=NULL, *cloth2=NULL; + MFace *face1=NULL, *face2=NULL; + ClothVertex *verts1=NULL, *verts2=NULL; + double distance = 0; + float epsilon = clmd->coll_parms.epsilon; + unsigned int i = 0; + + for(i = 0; i < 4; i++) + { + collpair = (CollPair *)MEM_callocN(sizeof(CollPair), "cloth coll pair"); + + cloth1 = clmd->clothObject; + cloth2 = coll_clmd->clothObject; + + verts1 = cloth1->verts; + verts2 = cloth2->verts; + + face1 = &(cloth1->mfaces[tree1->tri_index]); + face2 = &(cloth2->mfaces[tree2->tri_index]); + + // check all possible pairs of triangles + if(i == 0) + { + collpair->ap1 = face1->v1; + collpair->ap2 = face1->v2; + collpair->ap3 = face1->v3; + + collpair->bp1 = face2->v1; + collpair->bp2 = face2->v2; + collpair->bp3 = face2->v3; + + } + + if(i == 1) + { + if(face1->v4) + { + collpair->ap1 = face1->v3; + collpair->ap2 = face1->v4; + collpair->ap3 = face1->v1; + + collpair->bp1 = face2->v1; + collpair->bp2 = face2->v2; + collpair->bp3 = face2->v3; + } + else + i++; + } + + if(i == 2) + { + if(face2->v4) + { + collpair->ap1 = face1->v1; + collpair->ap2 = face1->v2; + collpair->ap3 = face1->v3; + + collpair->bp1 = face2->v3; + collpair->bp2 = face2->v4; + collpair->bp3 = face2->v1; + } + else + i+=2; + } + + if(i == 3) + { + if((face1->v4)&&(face2->v4)) + { + collpair->ap1 = face1->v3; + collpair->ap2 = face1->v4; + collpair->ap3 = face1->v1; + + collpair->bp1 = face2->v3; + collpair->bp2 = face2->v4; + collpair->bp3 = face2->v1; + } + else + i++; + } + + // calc SIPcode (?) + + if(i < 4) + { + // calc distance + normal + distance = plNearestPoints( + verts1[collpair->ap1].txold, verts1[collpair->ap2].txold, verts1[collpair->ap3].txold, verts2[collpair->bp1].txold, verts2[collpair->bp2].txold, verts2[collpair->bp3].txold, + collpair->pa, collpair->pb, collpair->vector); + + if (distance <= (epsilon + ALMOST_ZERO)) + { + // printf("dist: %f\n", (float)distance); + + // collpair->face1 = tree1->tri_index; + // collpair->face2 = tree2->tri_index; + + VECCOPY(collpair->normal, collpair->vector); + Normalize(collpair->normal); + + collpair->distance = distance; + BLI_linklist_append(&clmd->coll_parms.collision_list, collpair); + } + else + { + MEM_freeN(collpair); + } + } + else + { + MEM_freeN(collpair); + } } } @@ -899,9 +650,9 @@ void cloth_update_collision_objects(float step) // no dt here because of float rounding errors VECSUB(coll_cloth->verts[i].tv, coll_cloth->verts[i].tx, coll_cloth->verts[i].txold); } - + // update BVH of collision object - bvh_update_static(coll_clmd, coll_bvh); + bvh_update(coll_clmd, coll_bvh, 0); // 0 means STATIC, 1 means MOVING } else printf ("cloth_bvh_objcollision: found a collision object with clothObject or collData NULL.\n"); @@ -909,20 +660,22 @@ void cloth_update_collision_objects(float step) } } -#define CLOTH_MAX_THRESHOLD 5 +// CLOTH_MAX_THRESHOLD defines how much collision rounds/loops should be taken +#define CLOTH_MAX_THRESHOLD 10 // cloth - object collisions -int cloth_bvh_objcollision(ClothModifierData * clmd, float step, CM_COLLISION_RESPONSE collision_response, float dt) +int cloth_bvh_objcollision(ClothModifierData * clmd, float step, float dt) { Base *base=NULL; ClothModifierData *coll_clmd=NULL; Cloth *cloth=NULL; Object *coll_ob=NULL; BVH *cloth_bvh=NULL; - unsigned int i=0, numfaces = 0, numverts = 0; - unsigned int result = 0, ic = 0, rounds = 0; + unsigned int i=0, j = 0, numfaces = 0, numverts = 0; + unsigned int result = 0, ic = 0, rounds = 0; // result counts applied collisions; ic is for debug output; ClothVertex *verts = NULL; float tnull[3] = {0,0,0}; + int ret = 0; if ((clmd->sim_parms.flags & CSIMSETT_FLAG_COLLOBJ) || !(((Cloth *)clmd->clothObject)->tree)) { @@ -939,86 +692,96 @@ int cloth_bvh_objcollision(ClothModifierData * clmd, float step, CM_COLLISION_RE //////////////////////////////////////////////////////////// // update cloth bvh - bvh_update_static(clmd, cloth_bvh); + bvh_update(clmd, cloth_bvh, 0); // 0 means STATIC, 1 means MOVING (see later in this function) // update collision objects cloth_update_collision_objects(step); - + do { result = 0; ic = 0; - - // handle all collision objects + clmd->coll_parms.collision_list = NULL; + + // check all collision objects for (base = G.scene->base.first; base; base = base->next) { - coll_ob = base->object; coll_clmd = (ClothModifierData *) modifiers_findByType (coll_ob, eModifierType_Cloth); + if (!coll_clmd) continue; - + // if collision object go on if (coll_clmd->sim_parms.flags & CSIMSETT_FLAG_COLLOBJ) { if (coll_clmd->clothObject && coll_clmd->clothObject->tree) { - LinkNode **collision_list = MEM_callocN (sizeof(LinkNode *)*(numfaces), "collision_list"); BVH *coll_bvh = coll_clmd->clothObject->tree; - - if(collision_list) - { - memset(collision_list, 0, sizeof(LinkNode *)*numfaces); - clmd->coll_parms.temp = collision_list; - - bvh_traverse(clmd, coll_clmd, cloth_bvh->root, coll_bvh->root, step, collision_response); - - result += collision_static2(clmd, coll_clmd, collision_list); - - // calculate velocities - - // free temporary list - for(i = 0; i < numfaces; i++) - { - LinkNode *search = collision_list[i]; - while(search) - { - LinkNode *next= search->next; - CollPair *collpair = search->link; - - if(collpair) - MEM_freeN(collpair); - - search = next; - } - - BLI_linklist_free(collision_list[i],NULL); - } - if(collision_list) - MEM_freeN(collision_list); - - clmd->coll_parms.temp = NULL; - } - + bvh_traverse(clmd, coll_clmd, cloth_bvh->root, coll_bvh->root, step, bvh_collision_response_static); } else printf ("cloth_bvh_objcollision: found a collision object with clothObject or collData NULL.\n"); } } - // now apply impulses parallel - - for(i = 0; i < numverts; i++) + // process all collisions (calculate impulses, TODO: also repulses if distance too short) + result = 1; + for(j = 0; j < 50; j++) // 50 is just a value that ensures convergence { - if(verts[i].impulse_count) + result = 0; + + // handle all collision objects + for (base = G.scene->base.first; base; base = base->next) { - VECADDMUL(verts[i].tv, verts[i].impulse, 1.0f / verts[i].impulse_count); - VECCOPY(verts[i].impulse, tnull); - verts[i].impulse_count = 0; - - ic++; + + coll_ob = base->object; + coll_clmd = (ClothModifierData *) modifiers_findByType (coll_ob, eModifierType_Cloth); + if (!coll_clmd) + continue; + + // if collision object go on + if (coll_clmd->sim_parms.flags & CSIMSETT_FLAG_COLLOBJ) + { + if (coll_clmd->clothObject) + result += collision_static(clmd, coll_clmd); + else + printf ("cloth_bvh_objcollision: found a collision object with clothObject or collData NULL.\n"); + } } + + // apply impulses in parallel + ic=0; + for(i = 0; i < numverts; i++) + { + // calculate "velocities" (just xnew = xold + v; no dt in v) + if(verts[i].impulse_count) + { + VECADDMUL(verts[i].tv, verts[i].impulse, 1.0f / verts[i].impulse_count); + VECCOPY(verts[i].impulse, tnull); + verts[i].impulse_count = 0; + + ic++; + ret++; + } + } + } + + // free collision list + if(clmd->coll_parms.collision_list) + { + LinkNode *search = clmd->coll_parms.collision_list; + while(search) + { + CollPair *coll_pair = search->link; + + MEM_freeN(coll_pair); + search = search->next; + } + BLI_linklist_free(clmd->coll_parms.collision_list,NULL); + + clmd->coll_parms.collision_list = NULL; } printf("ic: %d\n", ic); @@ -1029,18 +792,162 @@ int cloth_bvh_objcollision(ClothModifierData * clmd, float step, CM_COLLISION_RE printf("\n"); //////////////////////////////////////////////////////////// - // update positions + velocities + // update positions + // this is needed for bvh_calc_DOP_hull_moving() [kdop.c] + //////////////////////////////////////////////////////////// + + // verts come from clmd + for(i = 0; i < numverts; i++) + { + VECADD(verts[i].tx, verts[i].txold, verts[i].tv); + } //////////////////////////////////////////////////////////// - - // TODO - //////////////////////////////////////////////////////////// // moving collisions //////////////////////////////////////////////////////////// - // TODO - // bvh_update_moving(clmd, clmd->clothObject->tree); + + // update cloth bvh + bvh_update(clmd, cloth_bvh, 1); // 0 means STATIC, 1 means MOVING + + // update moving bvh for collision object once + for (base = G.scene->base.first; base; base = base->next) + { + + coll_ob = base->object; + coll_clmd = (ClothModifierData *) modifiers_findByType (coll_ob, eModifierType_Cloth); + if (!coll_clmd) + continue; + + if(!coll_clmd->clothObject) + continue; + + // if collision object go on + if (coll_clmd->clothObject && coll_clmd->clothObject->tree) + { + BVH *coll_bvh = coll_clmd->clothObject->tree; + + bvh_update(coll_clmd, coll_bvh, 1); // 0 means STATIC, 1 means MOVING + } + } + + + do + { + result = 0; + ic = 0; + clmd->coll_parms.collision_list = NULL; + + // check all collision objects + for (base = G.scene->base.first; base; base = base->next) + { + coll_ob = base->object; + coll_clmd = (ClothModifierData *) modifiers_findByType (coll_ob, eModifierType_Cloth); + + if (!coll_clmd) + continue; + + // if collision object go on + if (coll_clmd->sim_parms.flags & CSIMSETT_FLAG_COLLOBJ) + { + if (coll_clmd->clothObject && coll_clmd->clothObject->tree) + { + BVH *coll_bvh = coll_clmd->clothObject->tree; + + bvh_traverse(clmd, coll_clmd, cloth_bvh->root, coll_bvh->root, step, bvh_collision_response_moving); + } + else + printf ("cloth_bvh_objcollision: found a collision object with clothObject or collData NULL.\n"); + } + } + /* + // process all collisions (calculate impulses, TODO: also repulses if distance too short) + result = 1; + for(j = 0; j < 50; j++) // 50 is just a value that ensures convergence + { + result = 0; + + // handle all collision objects + for (base = G.scene->base.first; base; base = base->next) + { + + coll_ob = base->object; + coll_clmd = (ClothModifierData *) modifiers_findByType (coll_ob, eModifierType_Cloth); + + if (!coll_clmd) + continue; + + // if collision object go on + if (coll_clmd->sim_parms.flags & CSIMSETT_FLAG_COLLOBJ) + { + if (coll_clmd->clothObject) + result += collision_moving(clmd, coll_clmd); + else + printf ("cloth_bvh_objcollision: found a collision object with clothObject or collData NULL.\n"); + } + } + + // apply impulses in parallel + ic=0; + for(i = 0; i < numverts; i++) + { + // calculate "velocities" (just xnew = xold + v; no dt in v) + if(verts[i].impulse_count) + { + VECADDMUL(verts[i].tv, verts[i].impulse, 1.0f / verts[i].impulse_count); + VECCOPY(verts[i].impulse, tnull); + verts[i].impulse_count = 0; + + ic++; + ret++; + } + } + } + */ + + // verts come from clmd + for(i = 0; i < numverts; i++) + { + VECADD(verts[i].tx, verts[i].txold, verts[i].tv); + } + + // update cloth bvh + bvh_update(clmd, cloth_bvh, 1); // 0 means STATIC, 1 means MOVING + + + // free collision list + if(clmd->coll_parms.collision_list) + { + LinkNode *search = clmd->coll_parms.collision_list; + while(search) + { + CollPair *coll_pair = search->link; + + MEM_freeN(coll_pair); + search = search->next; + } + BLI_linklist_free(clmd->coll_parms.collision_list,NULL); + + clmd->coll_parms.collision_list = NULL; + } + + printf("ic: %d\n", ic); + rounds++; + } + while(result && (CLOTH_MAX_THRESHOLD>rounds)); + + + //////////////////////////////////////////////////////////// + // update positions + velocities + //////////////////////////////////////////////////////////// + + // verts come from clmd + for(i = 0; i < numverts; i++) + { + VECADD(verts[i].tx, verts[i].txold, verts[i].tv); + } + //////////////////////////////////////////////////////////// - return MIN2(result, 1); + return MIN2(ret, 1); } diff --git a/source/blender/blenkernel/intern/implicit.c b/source/blender/blenkernel/intern/implicit.c index 3994bbf2b40..7f156acff71 100644 --- a/source/blender/blenkernel/intern/implicit.c +++ b/source/blender/blenkernel/intern/implicit.c @@ -1431,8 +1431,7 @@ void simulate_implicit_euler(lfVector *Vnew, lfVector *lX, lfVector *lV, lfVecto del_lfvector(dFdXmV); } -int implicit_solver (Object *ob, float frame, ClothModifierData *clmd, ListBase *effectors, - CM_COLLISION_SELF self_collision, CM_COLLISION_OBJ obj_collision) +int implicit_solver (Object *ob, float frame, ClothModifierData *clmd, ListBase *effectors) { unsigned int i=0, j; float step=0.0f, tf=1.0f; @@ -1492,14 +1491,14 @@ int implicit_solver (Object *ob, float frame, ClothModifierData *clmd, ListBase } // call collision function - result = cloth_bvh_objcollision(clmd, step + dt, bvh_collision_response, dt); + result = cloth_bvh_objcollision(clmd, step + dt, dt); // copy corrected positions back to simulation for(i = 0; i < numverts; i++) { if(result) { - VECADD(verts[i].tx, verts[i].txold, verts[i].tv); + // VECADD(verts[i].tx, verts[i].txold, verts[i].tv); VECCOPY(verts[i].txold, verts[i].tx); diff --git a/source/blender/blenkernel/intern/kdop.c b/source/blender/blenkernel/intern/kdop.c index 0088ff92364..51c571f1959 100644 --- a/source/blender/blenkernel/intern/kdop.c +++ b/source/blender/blenkernel/intern/kdop.c @@ -123,7 +123,7 @@ static float KDOP_AXES[13][3] = // #define KDOP_8 // OBB: -#define KDOP_14 +#define KDOP_6 @@ -424,54 +424,52 @@ DO_INLINE void bvh_calc_DOP_hull_static(BVH * bvh, Tree **tri, int numfaces, flo } } } -/* + DO_INLINE void bvh_calc_DOP_hull_moving(BVH * bvh, Tree **tri, int numfaces, float *bv) { -ClothVertex *tempMVert = bvh->verts; -MFace *tempMFace = bvh->mfaces; -float *tempBV = bv; -float newminmax; -int i, j, k; -for (j = 0; j < numfaces; j++) -{ -tempMFace = bvh->mfaces + (tri [j])->tri_index; -// 3 or 4 vertices per face. -for (k = 0; k < 4; k++) -{ -int temp = 0; -// If this is a triangle. -if (k == 3 && !tempMFace->v4) -continue; -// TODO: other name for "temp" this gets all vertices of a face -if (k == 0) -temp = tempMFace->v1; -else if (k == 1) -temp = tempMFace->v2; -else if (k == 2) -temp = tempMFace->v3; -else if (k == 3) -temp = tempMFace->v4; -// for all Axes. -for (i = KDOP_START; i < KDOP_END; i++) -{ -newminmax = INPR(tempMVert[temp].tx, KDOP_AXES[i]); -if ((newminmax < tempBV[(2 * i)]) || (k == 0 && j == 0)) -tempBV[(2 * i)] = newminmax; -// the same like some "else if" but with that condition I -// don't need to insert the first entry manually -if ((newminmax > tempBV[(2 * i) + 1])|| (k == 0 && j == 0)) -tempBV[(2 * i) + 1] = newminmax; + ClothVertex *tempMVert = bvh->verts; + MFace *tempMFace = bvh->mfaces; + float *tempBV = bv; + float newminmax; + int i, j, k; + for (j = 0; j < numfaces; j++) + { + tempMFace = bvh->mfaces + (tri [j])->tri_index; + // 3 or 4 vertices per face. + for (k = 0; k < 4; k++) + { + int temp = 0; + // If this is a triangle. + if (k == 3 && !tempMFace->v4) + continue; + // TODO: other name for "temp" this gets all vertices of a face + if (k == 0) + temp = tempMFace->v1; + else if (k == 1) + temp = tempMFace->v2; + else if (k == 2) + temp = tempMFace->v3; + else if (k == 3) + temp = tempMFace->v4; + // for all Axes. + for (i = KDOP_START; i < KDOP_END; i++) + { + newminmax = INPR(tempMVert[temp].txold, KDOP_AXES[i]); + if ((newminmax < tempBV[(2 * i)]) || (k == 0 && j == 0)) + tempBV[(2 * i)] = newminmax; + if ((newminmax > tempBV[(2 * i) + 1])|| (k == 0 && j == 0)) + tempBV[(2 * i) + 1] = newminmax; + + newminmax = INPR(tempMVert[temp].tx, KDOP_AXES[i]); + if ((newminmax < tempBV[(2 * i)]) || (k == 0 && j == 0)) + tempBV[(2 * i)] = newminmax; + if ((newminmax > tempBV[(2 * i) + 1])|| (k == 0 && j == 0)) + tempBV[(2 * i) + 1] = newminmax; + } + } + } +} -newminmax = INPR(tempMVert[temp].txold, KDOP_AXES[i]); -if (newminmax < tempBV[(2 * i)]) -tempBV[(2 * i)] = newminmax; -if (newminmax > tempBV[(2 * i) + 1]) -tempBV[(2 * i) + 1] = newminmax; -} -} -} -} -*/ static void bvh_div_env_node(BVH * bvh, TreeNode *tree, Tree **face_list, unsigned int start, unsigned int end, int lastaxis, LinkNode *nlink) { int i = 0; @@ -810,7 +808,7 @@ void bvh_join(Tree * tree) } // update static bvh -void bvh_update_static(ClothModifierData * clmd, BVH * bvh) +void bvh_update(ClothModifierData *clmd, BVH * bvh, int moving) { TreeNode *leaf, *parent; int traversecheck = 1; // if this is zero we don't go further @@ -823,7 +821,10 @@ void bvh_update_static(ClothModifierData * clmd, BVH * bvh) { leaf->parent->traversed = 0; } - bvh_calc_DOP_hull_static(bvh, &leaf, 1, leaf->bv); + if(!moving) + bvh_calc_DOP_hull_static(bvh, &leaf, 1, leaf->bv); + else + bvh_calc_DOP_hull_moving(bvh, &leaf, 1, leaf->bv); // inflate the bv with some epsilon for (j = KDOP_START; j < KDOP_END; j++) @@ -859,3 +860,4 @@ void bvh_update_static(ClothModifierData * clmd, BVH * bvh) } } } + diff --git a/source/blender/makesdna/DNA_cloth_types.h b/source/blender/makesdna/DNA_cloth_types.h index 574537f2589..6e986ae0067 100644 --- a/source/blender/makesdna/DNA_cloth_types.h +++ b/source/blender/makesdna/DNA_cloth_types.h @@ -123,7 +123,7 @@ typedef struct CollisionSettings { float friction; /* Friction/damping applied on contact with other object.*/ short collision_type; /* which collision system is used. */ short loop_count; /* How many iterations for the collision loop. */ - void *temp; /* e.g. pointer to temp memory for collisions */ + struct LinkNode *collision_list; /* e.g. pointer to temp memory for collisions */ } CollisionSettings; From a5db16f913f736b028e4afb190213d346a086233 Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Tue, 2 Oct 2007 09:47:08 +0000 Subject: [PATCH 021/246] Fixed crash with ipo'ed collision object --- source/blender/blenkernel/BKE_cloth.h | 14 ++++---- source/blender/blenkernel/intern/cloth.c | 44 +++++++++++++++--------- source/blender/blenkernel/intern/kdop.c | 3 +- source/blender/src/headerbuttons.c | 1 + 4 files changed, 37 insertions(+), 25 deletions(-) diff --git a/source/blender/blenkernel/BKE_cloth.h b/source/blender/blenkernel/BKE_cloth.h index bbdf4bc01c9..4a160275a99 100644 --- a/source/blender/blenkernel/BKE_cloth.h +++ b/source/blender/blenkernel/BKE_cloth.h @@ -86,12 +86,12 @@ struct DerivedMesh; typedef enum { CSIMSETT_FLAG_RESET = (1 << 1), // The CM object requires a reinitializaiton. - CSIMSETT_FLAG_COLLOBJ = (1 << 2), // object is only collision object, no cloth simulation is done - CSIMSETT_FLAG_GOAL = (1 << 3), // we have goals enabled - CSIMSETT_FLAG_CCACHE_FREE_ALL = (1 << 4), // delete all from cache - CSIMSETT_FLAG_CCACHE_FREE_PART = (1 << 5), // delete some part of cache - CSIMSETT_FLAG_TEARING_ENABLED = (1 << 6), // true if tearing is enabled - CSIMSETT_FLAG_CCACHE_PROTECT = (1 << 7), // true if tearing is enabled + CSIMSETT_FLAG_COLLOBJ = (1 << 2), // object is only collision object, no cloth simulation is done + CSIMSETT_FLAG_GOAL = (1 << 3), // we have goals enabled + CSIMSETT_FLAG_CCACHE_FREE_ALL = (1 << 4), // delete all from cache + CSIMSETT_FLAG_CCACHE_FREE_PART = (1 << 5), // delete some part of cache + CSIMSETT_FLAG_TEARING_ENABLED = (1 << 6), // true if tearing is enabled + CSIMSETT_FLAG_CCACHE_PROTECT = (1 << 7), // true if tearing is enabled } CSIMSETT_FLAGS; /* Spring types as defined in the paper.*/ @@ -106,7 +106,7 @@ typedef enum typedef enum { CSPRING_FLAG_DEACTIVATE = (1 << 1), - CSPRING_FLAG_NEEDED = (1 << 2), // springs has values to be applied + CSPRING_FLAG_NEEDED = (1 << 2), // springs has values to be applied } CSPRINGS_FLAGS; // needed for buttons_object.c diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c index 940fc8b6c5b..35d5771b135 100644 --- a/source/blender/blenkernel/intern/cloth.c +++ b/source/blender/blenkernel/intern/cloth.c @@ -656,6 +656,7 @@ void clothModifier_do(ClothModifierData *clmd, Object *ob, DerivedMesh *dm, // only be active during a specific period: // that's "first frame" and "last frame" on GUI + if (!(clmd->sim_parms.flags & CSIMSETT_FLAG_COLLOBJ)) { if(current_time < clmd->sim_parms.firstframe) @@ -699,7 +700,11 @@ void clothModifier_do(ClothModifierData *clmd, Object *ob, DerivedMesh *dm, if ((clmd->clothObject == NULL) || (numverts != clmd->clothObject->numverts) ) { if(!collobj_from_object (ob, clmd, dm, vertexCos, framenr)) + { + clmd->sim_parms.flags |= CSIMSETT_FLAG_COLLOBJ; + cloth_free_modifier(clmd); return; + } if(clmd->clothObject == NULL) return; @@ -712,7 +717,7 @@ void clothModifier_do(ClothModifierData *clmd, Object *ob, DerivedMesh *dm, clmd->sim_parms.sim_time = current_time; verts = cloth->verts; - + for (i = 0; i < clmd->clothObject->numverts; i++, verts++) { // Save the previous position. @@ -753,24 +758,24 @@ void clothModifier_do(ClothModifierData *clmd, Object *ob, DerivedMesh *dm, { verts = cloth->verts; - /* Force any pinned verts to their constrained location. */ + // Force any pinned verts to their constrained location. for (i = 0; i < clmd->clothObject->numverts; i++, verts++) { - /* Save the previous position. */ + // Save the previous position. VECCOPY (verts->xold, verts->xconst); VECCOPY (verts->txold, verts->x); - /* Get the current position. */ + // Get the current position. VECCOPY (verts->xconst, vertexCos[i]); Mat4MulVecfl(ob->obmat, verts->xconst); } tstart(); - /* Call the solver. */ + // Call the solver. if (solvers [clmd->sim_parms.solver_type].solver) solvers [clmd->sim_parms.solver_type].solver (ob, framenr, clmd, effectors); - + tend(); printf("Cloth simulation time: %f\n", (float)tval()); @@ -801,6 +806,7 @@ void clothModifier_do(ClothModifierData *clmd, Object *ob, DerivedMesh *dm, } } } + } /* frees all */ @@ -815,7 +821,7 @@ void cloth_free_modifier (ClothModifierData *clmd) if(!(clmd->sim_parms.flags & CSIMSETT_FLAG_CCACHE_PROTECT)) { - // free our frame cache + // free our frame cache, TODO: but get to first position before clmd->sim_parms.flags |= CSIMSETT_FLAG_CCACHE_FREE_ALL; cloth_cache_free(clmd, 0); @@ -848,10 +854,10 @@ void cloth_free_modifier (ClothModifierData *clmd) // we save our faces for collision objects if(cloth->mfaces) MEM_freeN(cloth->mfaces); - + /* if(clmd->clothObject->facemarks) MEM_freeN(clmd->clothObject->facemarks); - + */ MEM_freeN (cloth); clmd->clothObject = NULL; } @@ -965,8 +971,8 @@ static int collobj_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh clmd->clothObject = MEM_callocN (sizeof(Cloth), "cloth"); if (clmd->clothObject) { - clmd->clothObject->old_solver_type = -1; - clmd->clothObject->old_collision_type = -1; + clmd->clothObject->old_solver_type = 255; + clmd->clothObject->old_collision_type = 255; } else if (clmd->clothObject == NULL) { @@ -986,8 +992,12 @@ static int collobj_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh if (clmd->clothObject != NULL) { - mvert = CDDM_get_verts(dm); + if (!dm) return 0; + if (!dm->getNumVerts(dm) || !dm->getNumFaces(dm)) return 0; + + mvert = dm->getVertArray(dm); verts = clmd->clothObject->verts; + numverts = clmd->clothObject->numverts = dm->getNumVerts(dm); for (i = 0; i < numverts; i++, verts++) { @@ -1004,7 +1014,7 @@ static int collobj_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh clmd->clothObject->tree = bvh_build(clmd,clmd->coll_parms.epsilon); } - + return 1; default: return 0; // TODO - we do not support changing meshes } @@ -1175,8 +1185,8 @@ static int cloth_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *d clmd->clothObject = MEM_callocN (sizeof(Cloth), "cloth"); if (clmd->clothObject) { - clmd->clothObject->old_solver_type = -1; - clmd->clothObject->old_collision_type = -1; + clmd->clothObject->old_solver_type = 255; + clmd->clothObject->old_collision_type = 255; } else if (clmd->clothObject == NULL) { @@ -1242,7 +1252,7 @@ static int cloth_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *d clmd->clothObject->tree = bvh_build(clmd, clmd->coll_parms.epsilon); - cloth_cache_set_frame(clmd, 1); + // cloth_cache_set_frame(clmd, 1); } return 1; @@ -1265,7 +1275,7 @@ static void cloth_from_mesh (Object *ob, ClothModifierData *clmd, DerivedMesh *d { unsigned int numverts = dm->getNumVerts(dm); unsigned int numfaces = dm->getNumFaces(dm); - MFace *mface = CDDM_get_faces(dm); + MFace *mface = dm->getFaceArray(dm); unsigned int i = 0; /* Allocate our vertices. diff --git a/source/blender/blenkernel/intern/kdop.c b/source/blender/blenkernel/intern/kdop.c index 51c571f1959..a2d89be5d09 100644 --- a/source/blender/blenkernel/intern/kdop.c +++ b/source/blender/blenkernel/intern/kdop.c @@ -572,6 +572,7 @@ BVH *bvh_build (ClothModifierData *clmd, float epsilon) bvh->flags = 0; bvh->leaf_tree = NULL; bvh->leaf_root = NULL; + bvh->tree = NULL; bvh->epsilon = epsilon; bvh->numfaces = cloth->numfaces; @@ -581,7 +582,7 @@ BVH *bvh_build (ClothModifierData *clmd, float epsilon) bvh->verts = cloth->verts; tree = (Tree *)MEM_callocN(sizeof(Tree), "Tree"); // TODO: check succesfull alloc - BLI_linklist_prepend(&bvh->tree, tree); + BLI_linklist_append(&bvh->tree, tree); nlink = bvh->tree; diff --git a/source/blender/src/headerbuttons.c b/source/blender/src/headerbuttons.c index 4564db8d918..617bef705df 100644 --- a/source/blender/src/headerbuttons.c +++ b/source/blender/src/headerbuttons.c @@ -1067,6 +1067,7 @@ void do_global_buttons(unsigned short event) else if(nr==ID_LA) idtest= (ID *)add_ipo("LaIpo", nr); else if(nr==ID_CA) idtest= (ID *)add_ipo("CaIpo", nr); else if(nr==ID_SO) idtest= (ID *)add_ipo("SndIpo", nr); + else if(nr==ID_FLUIDSIM) idtest= (ID *)add_ipo("FluidsimIpo", nr); else error("Warn bugtracker!"); } idtest->us--; From 179a1b5bbc9d2bd238883e6135209357c53e4235 Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Tue, 2 Oct 2007 16:55:10 +0000 Subject: [PATCH 022/246] Compile fix for bug on OSX reported by Jens Verwiebe --- source/blender/blenkernel/intern/kdop.c | 36 ++++++++++++------------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/source/blender/blenkernel/intern/kdop.c b/source/blender/blenkernel/intern/kdop.c index a2d89be5d09..7ce5e6928ea 100644 --- a/source/blender/blenkernel/intern/kdop.c +++ b/source/blender/blenkernel/intern/kdop.c @@ -165,7 +165,7 @@ static int size_threshold = 16; /* * Common methods for all algorithms */ -DO_INLINE void exchange(Tree **a, int i, int j) +DO_INLINE void bvh_exchange(Tree **a, int i, int j) { Tree *t=a[i]; a[i]=a[j]; @@ -179,7 +179,7 @@ DO_INLINE int floor_lg(int a) /* * Insertion sort algorithm */ -static void insertionsort(Tree **a, int lo, int hi, int axis) +static void bvh_insertionsort(Tree **a, int lo, int hi, int axis) { int i,j; Tree *t; @@ -196,7 +196,7 @@ static void insertionsort(Tree **a, int lo, int hi, int axis) } } -static int partition(Tree **a, int lo, int hi, Tree * x, int axis) +static int bvh_partition(Tree **a, int lo, int hi, Tree * x, int axis) { int i=lo, j=hi; while (1) @@ -206,7 +206,7 @@ static int partition(Tree **a, int lo, int hi, Tree * x, int axis) while (x->bv[axis] < (a[j])->bv[axis]) j=j-1; if(!(i < j)) return i; - exchange(a, i,j); + bvh_exchange(a, i,j); i++; } } @@ -214,7 +214,7 @@ static int partition(Tree **a, int lo, int hi, Tree * x, int axis) /* * Heapsort algorithm */ -static void downheap(Tree **a, int i, int n, int lo, int axis) +static void bvh_downheap(Tree **a, int i, int n, int lo, int axis) { Tree * d = a[lo+i-1]; int child; @@ -232,21 +232,21 @@ static void downheap(Tree **a, int i, int n, int lo, int axis) a[lo+i-1] = d; } -static void heapsort(Tree **a, int lo, int hi, int axis) +static void bvh_heapsort(Tree **a, int lo, int hi, int axis) { int n = hi-lo, i; for (i=n/2; i>=1; i=i-1) { - downheap(a, i,n,lo, axis); + bvh_downheap(a, i,n,lo, axis); } for (i=n; i>1; i=i-1) { - exchange(a, lo,lo+i-1); - downheap(a, 1,i-1,lo, axis); + bvh_exchange(a, lo,lo+i-1); + bvh_downheap(a, 1,i-1,lo, axis); } } -static Tree *medianof3(Tree **a, int lo, int mid, int hi, int axis) // returns Sortable +static Tree *bvh_medianof3(Tree **a, int lo, int mid, int hi, int axis) // returns Sortable { if ((a[mid])->bv[axis] < (a[lo])->bv[axis]) { @@ -276,7 +276,7 @@ static Tree *medianof3(Tree **a, int lo, int mid, int hi, int axis) // returns S /* * Quicksort algorithm modified for Introsort */ -static void introsort_loop (Tree **a, int lo, int hi, int depth_limit, int axis) +static void bvh_introsort_loop (Tree **a, int lo, int hi, int depth_limit, int axis) { int p; @@ -284,28 +284,28 @@ static void introsort_loop (Tree **a, int lo, int hi, int depth_limit, int axis) { if (depth_limit == 0) { - heapsort(a, lo, hi, axis); + bvh_heapsort(a, lo, hi, axis); return; } depth_limit=depth_limit-1; - p=partition(a, lo, hi, medianof3(a, lo, lo+((hi-lo)/2)+1, hi-1, axis), axis); - introsort_loop(a, p, hi, depth_limit, axis); + p=bvh_partition(a, lo, hi, bvh_medianof3(a, lo, lo+((hi-lo)/2)+1, hi-1, axis), axis); + bvh_introsort_loop(a, p, hi, depth_limit, axis); hi=p; } } -DO_INLINE void sort(Tree **a0, int begin, int end, int axis) +DO_INLINE void bvh_sort(Tree **a0, int begin, int end, int axis) { if (begin < end) { Tree **a=a0; - introsort_loop(a, begin, end, 2*floor_lg(end-begin), axis); - insertionsort(a, begin, end, axis); + bvh_introsort_loop(a, begin, end, 2*floor_lg(end-begin), axis); + bvh_insertionsort(a, begin, end, axis); } } DO_INLINE void bvh_sort_along_axis(Tree **face_list, int start, int end, int axis) { - sort(face_list, start, end, axis); + bvh_sort(face_list, start, end, axis); } //////////////////////////////////////////////////////////////////////////////////////////////// void bvh_free(BVH * bvh) From 62107985dd1db0337827da9a919b2ee04da8a127 Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Wed, 3 Oct 2007 13:58:05 +0000 Subject: [PATCH 023/246] Recoded cache, fixed some crashes there --- source/blender/blenkernel/BKE_cloth.h | 8 +- source/blender/blenkernel/intern/cloth.c | 372 +++++++++++------------ source/blender/src/buttons_object.c | 10 +- 3 files changed, 187 insertions(+), 203 deletions(-) diff --git a/source/blender/blenkernel/BKE_cloth.h b/source/blender/blenkernel/BKE_cloth.h index 4a160275a99..8750fe3878c 100644 --- a/source/blender/blenkernel/BKE_cloth.h +++ b/source/blender/blenkernel/BKE_cloth.h @@ -34,6 +34,7 @@ #ifndef BKE_CLOTH_H #define BKE_CLOTH_H +#include "BLI_linklist.h" #include "BKE_DerivedMesh.h" #include "DNA_customdata_types.h" #include "BKE_customdata.h" @@ -88,10 +89,8 @@ typedef enum CSIMSETT_FLAG_RESET = (1 << 1), // The CM object requires a reinitializaiton. CSIMSETT_FLAG_COLLOBJ = (1 << 2), // object is only collision object, no cloth simulation is done CSIMSETT_FLAG_GOAL = (1 << 3), // we have goals enabled - CSIMSETT_FLAG_CCACHE_FREE_ALL = (1 << 4), // delete all from cache - CSIMSETT_FLAG_CCACHE_FREE_PART = (1 << 5), // delete some part of cache - CSIMSETT_FLAG_TEARING_ENABLED = (1 << 6), // true if tearing is enabled - CSIMSETT_FLAG_CCACHE_PROTECT = (1 << 7), // true if tearing is enabled + CSIMSETT_FLAG_TEARING_ENABLED = (1 << 4), // true if tearing is enabled + CSIMSETT_FLAG_CCACHE_PROTECT = (1 << 5), // true if tearing is enabled } CSIMSETT_FLAGS; /* Spring types as defined in the paper.*/ @@ -221,6 +220,7 @@ typedef struct Frame { ClothVertex *verts; ClothSpring *springs; + unsigned int numverts, numsprings; float time; /* we need float since we want to support sub-frames */ } Frame; diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c index 35d5771b135..e86d1c50b69 100644 --- a/source/blender/blenkernel/intern/cloth.c +++ b/source/blender/blenkernel/intern/cloth.c @@ -403,230 +403,198 @@ DerivedMesh *CDDM_create_tearing(ClothModifierData *clmd, DerivedMesh *dm) int cloth_cache_search_frame(ClothModifierData *clmd, float time) { Frame *frame = NULL; - LinkNode *search = NULL; - int newtime = time + clmd->sim_parms.preroll; - - Cloth *cloth = NULL; - - if(!clmd) - return 0; - - cloth = clmd->clothObject; - - if(!cloth) - return 0; - - if(clmd->sim_parms.cache) - { + LinkNode *search = NULL; + + if(clmd->clothObject) + { search = clmd->sim_parms.cache; - - // check if frame exists + while(search) { - frame = search->link; - - if(frame->time == newtime) - break; - - frame = NULL; - - search = search->next; - } - } - - if(!frame) - return 0; - - return 1; -} - -int cloth_cache_last_frame(ClothModifierData *clmd) -{ - Frame *frame = NULL; - LinkNode *search = NULL; - int temptime = 0; - - Cloth *cloth = NULL; - - if(!clmd) - return 0; - - cloth = clmd->clothObject; - - if(!cloth) - return 0; - - if(clmd->sim_parms.cache) - { - search = clmd->sim_parms.cache; - - // check if frame exists - while(search) - { - frame = search->link; - - if(frame->time > temptime) + frame = (Frame *)search->link; + + if(frame) { - temptime = frame->time; + if(frame->time == time) + return 1; } - + search = search->next; } - } - return temptime; + } + + return 0; + +} + +float cloth_cache_last_frame(ClothModifierData *clmd) +{ + Frame *frame = NULL; + LinkNode *search = NULL; + float time = 0; + + if(clmd->clothObject) + { + search = clmd->sim_parms.cache; + + while(search) + { + frame = (Frame *)search->link; + + if(frame) + { + if(frame->time > time) + time = frame->time; + } + } + } + return time; +} + +float cloth_cache_first_frame(ClothModifierData *clmd) +{ + Frame *frame = NULL; + LinkNode *search = NULL; + float time = -1.0; + + if(clmd->clothObject) + { + search = clmd->sim_parms.cache; + + while(search) + { + frame = (Frame *)search->link; + + if(frame) + { + if(time < 0.0) + time = frame->time; + else + { + if(frame->time < time) + time = frame->time; + } + } + } + } + return time; } void cloth_cache_get_frame(ClothModifierData *clmd, float time) { Frame *frame = NULL; LinkNode *search = NULL; - unsigned int i = 0; - Cloth *cloth = NULL; - int newtime = time + clmd->sim_parms.preroll; - - if(clmd) + float newtime = time + clmd->sim_parms.preroll; + + if(clmd->clothObject) { - cloth = clmd->clothObject; - - if(!cloth) - return; - - // get cache - if(clmd->sim_parms.cache) + search = clmd->sim_parms.cache; + + while(search) { - search = clmd->sim_parms.cache; - frame = NULL; - // check if frame exists - while(search) - { - frame = search->link; - if(frame->time == newtime) - break; - - frame = NULL; - - search = search->next; - } - + frame = (Frame *)search->link; + if(frame) { - if(frame->verts) + if(frame->time == newtime) { - - // copy ClothVertex struct - memcpy(cloth->verts, frame->verts, cloth->numverts*sizeof(ClothVertex)); + // something changed, free cache! + if(clmd->clothObject->numverts != frame->numverts) + { + cloth_cache_free(clmd, 0); + printf("clmd->clothObject->numverts != frame->numverts\n"); + return; + } + + memcpy(clmd->clothObject->verts, frame->verts, sizeof(ClothVertex)*frame->numverts); implicit_set_positions(clmd); + + return; } - /* - if(frame->springs) - { - // copy ClothSpring struct - memcpy(cloth->springs, frame->springs, cloth->numsprings*sizeof(ClothSpring)); - } - */ } + + search = search->next; } } - } void cloth_cache_set_frame(ClothModifierData *clmd, float time) { Frame *frame = NULL; - unsigned int i = 0; - Cloth *cloth = NULL; - int newtime = time + clmd->sim_parms.preroll; - - if(clmd) + LinkNode *search = NULL; + + if(clmd->clothObject) { - cloth = clmd->clothObject; - - if(cloth) - { - // creat new frame cache - frame = (Frame *)MEM_callocN(sizeof(Frame), "cloth frame cache"); - frame->verts = (ClothVertex *)MEM_callocN(sizeof(ClothVertex)*cloth->numverts, "cloth frame vertex cache"); - frame->springs = NULL; - /* - frame->springs = (ClothSpring *)MEM_callocN(sizeof(ClothSpring)*cloth->numsprings, "cloth frame spring cache"); - */ - frame->time = newtime; - - // copy ClothVertex struct - for(i = 0; i < cloth->numverts; i++) - { - memcpy(&frame->verts[i], &cloth->verts[i], sizeof(ClothVertex)); - } - /* - // copy ClothSpring struct - for(i = 0; i < cloth->numsprings; i++) - { - memcpy(&frame->springs[i], &cloth->springs[i], sizeof(ClothSpring)); - } - */ - } + frame = (Frame *)MEM_callocN (sizeof (Frame), "cloth_cache_frame"); + if(frame) + { + frame->time = time; + frame->numverts = clmd->clothObject->numverts; + frame->verts = MEM_dupallocN(clmd->clothObject->verts); + + if(!frame->verts) + { + MEM_freeN(frame); + return; + } + BLI_linklist_append(&clmd->sim_parms.cache, frame); - } + + } + } + } // free cloth cache void cloth_cache_free(ClothModifierData *clmd, float time) { Frame *frame = NULL; - LinkNode *search, *last_search; - int newtime = time + clmd->sim_parms.preroll; + LinkNode *search = NULL, *lastsearch = NULL; + float newtime = time + clmd->sim_parms.preroll; + + if(time <= 2.0) + newtime = time; - // do never free first cached frame - if((newtime<1.0f) && !(clmd->sim_parms.flags & CSIMSETT_FLAG_CCACHE_FREE_ALL)) - return; - - /* Calls the solver and collision frees first as they - * might depend on data in clmd->clothObject. */ - - if (clmd) + if(clmd->clothObject) { if(clmd->sim_parms.cache) - { - last_search = search = clmd->sim_parms.cache; + { + lastsearch = search = clmd->sim_parms.cache; + while(search) { - LinkNode *next= search->next; - frame = search->link; - - // free part of cache, but not preroll cache and first framer - if((clmd->sim_parms.flags & CSIMSETT_FLAG_CCACHE_FREE_PART) - && (frame->time > newtime)) // do not delete the first frame + frame = (Frame *)search->link; + + if(frame->time >= newtime) { - MEM_freeN(frame->verts); - // MEM_freeN(frame->springs); - MEM_freeN(frame); + if(frame->verts) + { + MEM_freeN(frame->verts); + } + MEM_freeN(frame); + + lastsearch->next = search->next; MEM_freeN(search); - last_search->next = next; - } - else if(clmd->sim_parms.flags & CSIMSETT_FLAG_CCACHE_FREE_ALL) // free COMPLETE cache - { - MEM_freeN(frame->verts); - // MEM_freeN(frame->springs); - MEM_freeN(frame); + search = lastsearch->next; + lastsearch->next = NULL; } else - last_search = search; - search = next; + { + lastsearch = search; + search = search->next; + } } - - if(clmd->sim_parms.flags & CSIMSETT_FLAG_CCACHE_FREE_ALL) + + if(time <= 1.0) { - BLI_linklist_free(clmd->sim_parms.cache,NULL); clmd->sim_parms.cache = NULL; } + + if(time <= 2.0) + clmd->sim_parms.preroll = 0; } } - - /* clear flags */ - clmd->sim_parms.flags &= ~CSIMSETT_FLAG_CCACHE_FREE_ALL; - clmd->sim_parms.flags &= ~CSIMSETT_FLAG_CCACHE_FREE_PART; - } @@ -656,25 +624,44 @@ void clothModifier_do(ClothModifierData *clmd, Object *ob, DerivedMesh *dm, // only be active during a specific period: // that's "first frame" and "last frame" on GUI - if (!(clmd->sim_parms.flags & CSIMSETT_FLAG_COLLOBJ)) { - if(current_time < clmd->sim_parms.firstframe) - return; - else if(current_time > clmd->sim_parms.lastframe) + if(clmd->clothObject) { - int frametime = cloth_cache_last_frame(clmd); - if(cloth_cache_search_frame(clmd, frametime)) + if(clmd->sim_parms.cache) { - cloth_cache_get_frame(clmd, frametime); - cloth_to_object (ob, clmd, vertexCos, numverts); + if(current_time < clmd->sim_parms.firstframe) + { + int frametime = cloth_cache_first_frame(clmd); + if(cloth_cache_search_frame(clmd, frametime)) + { + cloth_cache_get_frame(clmd, frametime); + cloth_to_object (ob, clmd, vertexCos, numverts); + } + return; + } + else if(current_time > clmd->sim_parms.lastframe) + { + int frametime = cloth_cache_last_frame(clmd); + if(cloth_cache_search_frame(clmd, frametime)) + { + cloth_cache_get_frame(clmd, frametime); + cloth_to_object (ob, clmd, vertexCos, numverts); + } + return; + } + else if(ABS(deltaTime) >= 2.0f ) // no timewarps allowed + { + if(cloth_cache_search_frame(clmd, framenr)) + { + cloth_cache_get_frame(clmd, framenr); + cloth_to_object (ob, clmd, vertexCos, numverts); + } + clmd->sim_parms.sim_time = current_time; + return; + } } - return; - } - else if(ABS(deltaTime) >= 2.0f ) // no timewarps allowed - { - if(!cloth_cache_search_frame(clmd, framenr)) - return; + } } @@ -822,7 +809,6 @@ void cloth_free_modifier (ClothModifierData *clmd) if(!(clmd->sim_parms.flags & CSIMSETT_FLAG_CCACHE_PROTECT)) { // free our frame cache, TODO: but get to first position before - clmd->sim_parms.flags |= CSIMSETT_FLAG_CCACHE_FREE_ALL; cloth_cache_free(clmd, 0); if (cloth) @@ -838,14 +824,14 @@ void cloth_free_modifier (ClothModifierData *clmd) MEM_freeN (cloth->verts); cloth->verts = NULL; - cloth->numverts = -1; + cloth->numverts = 0; // Free the springs. if (cloth->springs != NULL) MEM_freeN (cloth->springs); cloth->springs = NULL; - cloth->numsprings = -1; + cloth->numsprings = 0; // free BVH collision tree if(cloth->tree) @@ -1242,17 +1228,17 @@ static int cloth_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *d VECCOPY(verts->impulse, tnull); } - /* apply / set vertex groups */ + // apply / set vertex groups if (clmd->sim_parms.vgroup_mass > 0) cloth_apply_vgroup (clmd, dm, clmd->sim_parms.vgroup_mass); - /* init our solver */ + // init our solver if (solvers [clmd->sim_parms.solver_type].init) solvers [clmd->sim_parms.solver_type].init (ob, clmd); clmd->clothObject->tree = bvh_build(clmd, clmd->coll_parms.epsilon); - // cloth_cache_set_frame(clmd, 1); + cloth_cache_set_frame(clmd, 1); } return 1; @@ -1392,7 +1378,7 @@ int cloth_build_springs(Cloth *cloth, DerivedMesh *dm) springs[temp_index].restlen = sqrt(INPR(temp, temp)); springs[temp_index].type = SHEAR; - BLI_linklist_append(&edgelist[springs[temp_index].ij], &(springs[temp_index])); + BLI_linklist_append(&edgelist[springs[temp_index].ij], &(springs[temp_index])); BLI_linklist_append(&edgelist[springs[temp_index].kl], &(springs[temp_index])); shear_springs++; diff --git a/source/blender/src/buttons_object.c b/source/blender/src/buttons_object.c index 37e232a9f97..3faf298db0e 100644 --- a/source/blender/src/buttons_object.c +++ b/source/blender/src/buttons_object.c @@ -2160,8 +2160,7 @@ void do_object_panels(unsigned short event) CFRA= 1; update_for_newframe_muted(); DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA); - clmd->sim_parms.flags |= CSIMSETT_FLAG_CCACHE_FREE_PART; - cloth_cache_free(clmd, 1); + cloth_cache_free(clmd, 2); allqueue(REDRAWBUTSOBJECT, 0); allqueue(REDRAWVIEW3D, 0); } @@ -2172,11 +2171,8 @@ void do_object_panels(unsigned short event) ClothModifierData *clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth); if(clmd) { - clmd->sim_parms.flags |= CSIMSETT_FLAG_CCACHE_FREE_PART; - cloth_cache_free(clmd, G.scene->r.cfra); - DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA); + cloth_cache_free(clmd, MAX2(2.0,G.scene->r.cfra+1.0)); allqueue(REDRAWBUTSOBJECT, 0); - allqueue(REDRAWVIEW3D, 0); } } break; @@ -3256,6 +3252,8 @@ static void object_panel_cloth_II(Object *ob) uiDefBut(block, BUT, B_CLOTH_CLEARCACHEFRAME, "From next frame", 155, 100,145,20, NULL, 0.0, 0.0, 0, 0, "Free cloth cache"); if(length>1) // B_CLOTH_CHANGEPREROLL uiDefButI(block, NUM, B_CLOTH_CHANGEPREROLL, "Preroll:", 10,80,145,20, &clmd->sim_parms.preroll, 0, length-1, 1, 0, "Simulation starts on this frame"); + else + uiDefBut(block, LABEL, 0, " ", 10,80,145,20, NULL, 0.0, 0, 0, 0, ""); } else { From 265572744e00a9b746b01a57aac950298933623a Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Wed, 3 Oct 2007 22:43:26 +0000 Subject: [PATCH 024/246] New: Collision detection for inter-timestep-collisions for triangle-point contacts. No response yet though. --- source/blender/blenkernel/BKE_cloth.h | 24 +- source/blender/blenkernel/intern/collision.c | 506 +++++++++++-------- 2 files changed, 329 insertions(+), 201 deletions(-) diff --git a/source/blender/blenkernel/BKE_cloth.h b/source/blender/blenkernel/BKE_cloth.h index 8750fe3878c..dc8d33804ee 100644 --- a/source/blender/blenkernel/BKE_cloth.h +++ b/source/blender/blenkernel/BKE_cloth.h @@ -235,9 +235,31 @@ typedef struct CollPair float pa[3], pb[3]; // collision point p1 on face1, p2 on face2 int lastsign; // indicates if the distance sign has changed, unused itm float time; // collision time, from 0 up to 1 - unsigned int ap1, ap2, ap3, bp1, bp2, bp3; + unsigned int ap1, ap2, ap3, bp1, bp2, bp3, bp4; + unsigned int pointsb[4]; } CollPair; +/* used for collisions in collision.c */ +typedef struct EdgeCollPair +{ + unsigned int p11, p12, p21, p22; + float normal[3]; + float vector[3]; + float time; + int lastsign; + float pa[3], pb[3]; // collision point p1 on face1, p2 on face2 +} EdgeCollPair; + +/* used for collisions in collision.c */ +typedef struct FaceCollPair +{ + unsigned int p11, p12, p13, p21; + float normal[3]; + float vector[3]; + float time; + int lastsign; + float pa[3], pb[3]; // collision point p1 on face1, p2 on face2 +} FaceCollPair; #endif diff --git a/source/blender/blenkernel/intern/collision.c b/source/blender/blenkernel/intern/collision.c index 20c1548e14b..6100ff143d5 100644 --- a/source/blender/blenkernel/intern/collision.c +++ b/source/blender/blenkernel/intern/collision.c @@ -71,123 +71,254 @@ #include "Bullet-C-Api.h" -#define DERANDOMIZE 1 +/** + * gsl_poly_solve_cubic - + * + * copied from SOLVE_CUBIC.C --> GSL + */ +#define mySWAP(a,b) do { float tmp = b ; b = a ; a = tmp ; } while(0) -enum TRIANGLE_MARK -{ - TM_MV = 1, - TM_ME = 2, - TM_V1 = 4, - TM_V2 = 8, - TM_V3 = 16, - TM_E1 = 32, - TM_E2 = 64, - TM_E3 = 128 -}; - -DO_INLINE int hasTriangleMark(unsigned char mark, unsigned char bit) { return mark & bit; } -DO_INLINE void setTriangleMark(unsigned char *mark, unsigned char bit) { mark[0] |= bit; } -DO_INLINE void clearTriangleMark(unsigned char *mark, unsigned char bit) { mark[0] &= ~bit; } - - -void generateTriangleMarks() +int gsl_poly_solve_cubic (float a, float b, float c, float *x0, float *x1, float *x2) { - /* - unsigned int firstEdge = 0; + float q = (a * a - 3 * b); + float r = (2 * a * a * a - 9 * a * b + 27 * c); + + float Q = q / 9; + float R = r / 54; + + float Q3 = Q * Q * Q; + float R2 = R * R; + + float CR2 = 729 * r * r; + float CQ3 = 2916 * q * q * q; + + if (R == 0 && Q == 0) + { + *x0 = - a / 3 ; + *x1 = - a / 3 ; + *x2 = - a / 3 ; + return 3 ; + } + else if (CR2 == CQ3) + { + /* this test is actually R2 == Q3, written in a form suitable + for exact computation with integers */ + + /* Due to finite precision some float roots may be missed, and + considered to be a pair of complex roots z = x +/- epsilon i + close to the real axis. */ + + float sqrtQ = sqrtf (Q); + + if (R > 0) + { + *x0 = -2 * sqrtQ - a / 3; + *x1 = sqrtQ - a / 3; + *x2 = sqrtQ - a / 3; + } + else + { + *x0 = - sqrtQ - a / 3; + *x1 = - sqrtQ - a / 3; + *x2 = 2 * sqrtQ - a / 3; + } + return 3 ; + } + else if (CR2 < CQ3) /* equivalent to R2 < Q3 */ + { + float sqrtQ = sqrtf (Q); + float sqrtQ3 = sqrtQ * sqrtQ * sqrtQ; + float theta = acosf (R / sqrtQ3); + float norm = -2 * sqrtQ; + *x0 = norm * cosf (theta / 3) - a / 3; + *x1 = norm * cosf ((theta + 2.0 * M_PI) / 3) - a / 3; + *x2 = norm * cosf ((theta - 2.0 * M_PI) / 3) - a / 3; + + /* Sort *x0, *x1, *x2 into increasing order */ + + if (*x0 > *x1) + mySWAP(*x0, *x1) ; + + if (*x1 > *x2) + { + mySWAP(*x1, *x2) ; + + if (*x0 > *x1) + mySWAP(*x0, *x1) ; + } + + return 3; + } + else + { + float sgnR = (R >= 0 ? 1 : -1); + float A = -sgnR * powf (fabs (R) + sqrtf (R2 - Q3), 1.0/3.0); + float B = Q / A ; + *x0 = A + B - a / 3; + return 1; + } +} + + +/** + * gsl_poly_solve_quadratic + * + * copied from GSL + */ +int gsl_poly_solve_quadratic (float a, float b, float c, float *x0, float *x1) +{ + float disc = b * b - 4 * a * c; + + if (disc > 0) + { + if (b == 0) + { + float r = fabs (0.5 * sqrtf (disc) / a); + *x0 = -r; + *x1 = r; + } + else + { + float sgnb = (b > 0 ? 1 : -1); + float temp = -0.5 * (b + sgnb * sqrtf (disc)); + float r1 = temp / a ; + float r2 = c / temp ; + + if (r1 < r2) + { + *x0 = r1 ; + *x1 = r2 ; + } + else + { + *x0 = r2 ; + *x1 = r1 ; + } + } + return 2; + } + else if (disc == 0) + { + *x0 = -0.5 * b / a ; + *x1 = -0.5 * b / a ; + return 2 ; + } + else + { + return 0; + } +} + + + +/* + * See Bridson et al. "Robust Treatment of Collision, Contact and Friction for Cloth Animation" + * page 4, left column + */ + +int cloth_get_collision_time(float a[3], float b[3], float c[3], float d[3], float e[3], float f[3], float solution[3]) +{ + int num_sols = 0; - // 1. Initialization - memset(m_triangleMarks, 0, sizeof(unsigned char) * m_triangleCount); + float g = -a[2] * c[1] * e[0] + a[1] * c[2] * e[0] + + a[2] * c[0] * e[1] - a[0] * c[2] * e[1] - + a[1] * c[0] * e[2] + a[0] * c[1] * e[2]; - // 2. The Marking Process - - // 2.1 Randomly mark triangles for covering vertices. - for (unsigned int v = 0; v < m_vertexCount; ++v) + float h = -b[2] * c[1] * e[0] + b[1] * c[2] * e[0] - a[2] * d[1] * e[0] + + a[1] * d[2] * e[0] + b[2] * c[0] * e[1] - b[0] * c[2] * e[1] + + a[2] * d[0] * e[1] - a[0] * d[2] * e[1] - b[1] * c[0] * e[2] + + b[0] * c[1] * e[2] - a[1] * d[0] * e[2] + a[0] * d[1] * e[2] - + a[2] * c[1] * f[0] + a[1] * c[2] * f[0] + a[2] * c[0] * f[1] - + a[0] * c[2] * f[1] - a[1] * c[0] * f[2] + a[0] * c[1] * f[2]; + + float i = -b[2] * d[1] * e[0] + b[1] * d[2] * e[0] + + b[2] * d[0] * e[1] - b[0] * d[2] * e[1] - + b[1] * d[0] * e[2] + b[0] * d[1] * e[2] - + b[2] * c[1] * f[0] + b[1] * c[2] * f[0] - + a[2] * d[1] * f[0] + a[1] * d[2] * f[0] + + b[2] * c[0] * f[1] - b[0] * c[2] * f[1] + + a[2] * d[0] * f[1] - a[0] * d[2] * f[1] - + b[1] * c[0] * f[2] + b[0] * c[1] * f[2] - + a[1] * d[0] * f[2] + a[0] * d[1] * f[2]; + + float j = -b[2] * d[1] * f[0] + b[1] * d[2] * f[0] + + b[2] * d[0] * f[1] - b[0] * d[2] * f[1] - + b[1] * d[0] * f[2] + b[0] * d[1] * f[2]; + + // Solve cubic equation to determine times t1, t2, t3, when the collision will occur. + if(ABS(j) > ALMOST_ZERO) { - if (vertexCover(v) == 0) + i /= j; + h /= j; + g /= j; + + num_sols = gsl_poly_solve_cubic(i, h, g, &solution[0], &solution[1], &solution[2]); + } + else if(ABS(i) > ALMOST_ZERO) + { + num_sols = gsl_poly_solve_quadratic(i, h, g, &solution[0], &solution[1]); + solution[2] = -1.0; + } + else if(ABS(h) > ALMOST_ZERO) + { + solution[0] = -g / h; + solution[1] = solution[2] = -1.0; + num_sols = 1; + } + else if(ABS(g) > ALMOST_ZERO) + { + solution[0] = 0; + solution[1] = solution[2] = -1.0; + num_sols = 1; + } + + // Discard negative solutions + if ((num_sols >= 1) && (solution[0] < 0)) + { + --num_sols; + solution[0] = solution[num_sols]; + } + if ((num_sols >= 2) && (solution[1] < 0)) + { + --num_sols; + solution[1] = solution[num_sols]; + } + if ((num_sols == 3) && (solution[2] < 0)) + { + --num_sols; + } + + // Sort + if (num_sols == 2) + { + if (solution[0] > solution[1]) + { + double tmp = solution[0]; + solution[0] = solution[1]; + solution[1] = tmp; + } + } + else if (num_sols == 3) { - // Randomly select an edge whose first triangle we're going to flag. + // Bubblesort + if (solution[0] > solution[1]) { + double tmp = solution[0]; solution[0] = solution[1]; solution[1] = tmp; + } + if (solution[1] > solution[2]) { + double tmp = solution[1]; solution[1] = solution[2]; solution[2] = tmp; + } + if (solution[0] > solution[1]) { + double tmp = solution[0]; solution[0] = solution[1]; solution[1] = tmp; + } + } -#ifndef DERANDOMIZE - firstEdge = (unsigned int)((float)(random() & 0x7FFFFFFF) / - (float)(0x80000000) * - (float)(m_vertices[v].getEdgeCount())); -#endif - for (unsigned int ofs = 0; ofs < m_vertices[v].getEdgeCount(); ++ofs) - { - unsigned int edgeIdx = (firstEdge + ofs) % m_vertices[v].getEdgeCount(); - if (m_edges[m_vertices[v].getEdge(edgeIdx)].getTriangleCount()) - setTriangleMark(m_triangleMarks[m_edges[m_vertices[v].getEdge(edgeIdx)].getTriangle(0)], TM_MV); -} -} -} - */ - /* If the Cloth is malformed (vertices without adjacent triangles) there might still be uncovered vertices. (Bad luck.) */ - /* - // 2.2 Randomly mark triangles for covering edges. - for (unsigned int e = 0; e < m_edgeCount; ++e) - { - if (m_edges[e].getTriangleCount() && (edgeCover(e) == 0)) - { -#ifndef DERANDOMIZE - setTriangleMark(m_triangleMarks[m_edges[e].getTriangle(static_cast((float)(random() & 0x7FFFFFFF) / - (float)(0x80000000) * - (float)(m_edges[e].getTriangleCount())))], TM_ME); -#else - setTriangleMark(m_triangleMarks[m_edges[e].getTriangle(0)], TM_ME); -#endif -} -} - - - // 3. The Unmarking Process - for (unsigned int t = 0; (t < m_triangleCount); ++t) - { - bool overCoveredVertices = true; - bool overCoveredEdges = true; - for (unsigned char i = 0; (i < 3) && (overCoveredVertices || overCoveredEdges); ++i) - { - - if (vertexCover(m_triangles[t].getVertex(i)) == 1) - overCoveredVertices = false; - if (edgeCover(m_triangles[t].getEdge(i)) == 1) - overCoveredEdges = false; - - assert(vertexCover(m_triangles[t].getVertex(i)) > 0); - assert(edgeCover(m_triangles[t].getEdge(i)) > 0); -} - if (overCoveredVertices) - clearTriangleMark(m_triangleMarks[t], TM_MV); - if (overCoveredEdges) - clearTriangleMark(m_triangleMarks[t], TM_ME); -} - - - // 4. The Bit Masking Process - vector vertexAssigned(m_vertexCount, false); - vector edgeAssigned(m_edgeCount, false); - for (unsigned int t = 0; (t < m_triangleCount); ++t) - { - for (unsigned char i = 0; i < 3; ++i) - { - if (!vertexAssigned[m_triangles[t].getVertex(i)]) - { - vertexAssigned[m_triangles[t].getVertex(i)] = true; - setTriangleMark(m_triangleMarks[t], 1 << (2 + i)); -} - if (!edgeAssigned[m_triangles[t].getEdge(i)]) - { - edgeAssigned[m_triangles[t].getEdge(i)] = true; - setTriangleMark(m_triangleMarks[t], 1 << (5 + i)); -} -} -} - */ + return num_sols; } // w3 is not perfect -void bvh_compute_barycentric (float pv[3], float p1[3], float p2[3], float p3[3], float *w1, float *w2, float *w3) +void cloth_compute_barycentric (float pv[3], float p1[3], float p2[3], float p3[3], float *w1, float *w2, float *w3) { double tempV1[3], tempV2[3], tempV4[3]; double a,b,c,d,e,f; @@ -231,6 +362,8 @@ DO_INLINE void interpolateOnTriangle(float to[3], float v1[3], float v2[3], floa } + +// unused in the moment, has some bug in DO_INLINE void calculateFrictionImpulse(float to[3], float vrel[3], float normal[3], double normalVelocity, double frictionConstant, double delta_V_n) { @@ -241,8 +374,7 @@ DO_INLINE void calculateFrictionImpulse(float to[3], float vrel[3], float normal VecMulf(to, MAX2(1.0f - frictionConstant * delta_V_n / INPR(vrel_t_pre,vrel_t_pre), 0.0f)); } - -int collision_static(ClothModifierData *clmd, ClothModifierData *coll_clmd) +int cloth_collision_response_static(ClothModifierData *clmd, ClothModifierData *coll_clmd) { unsigned int i = 0; int result = 0; @@ -263,17 +395,17 @@ int collision_static(ClothModifierData *clmd, ClothModifierData *coll_clmd) collpair = search->link; // compute barycentric coordinates for both collision points - bvh_compute_barycentric(collpair->pa, + cloth_compute_barycentric(collpair->pa, cloth1->verts[collpair->ap1].txold, - cloth1->verts[collpair->ap2].txold, - cloth1->verts[collpair->ap3].txold, - &w1, &w2, &w3); + cloth1->verts[collpair->ap2].txold, + cloth1->verts[collpair->ap3].txold, + &w1, &w2, &w3); - bvh_compute_barycentric(collpair->pb, + cloth_compute_barycentric(collpair->pb, cloth2->verts[collpair->bp1].txold, - cloth2->verts[collpair->bp2].txold, - cloth2->verts[collpair->bp3].txold, - &u1, &u2, &u3); + cloth2->verts[collpair->bp2].txold, + cloth2->verts[collpair->bp3].txold, + &u1, &u2, &u3); // Calculate relative "velocity". interpolateOnTriangle(v1, cloth1->verts[collpair->ap1].tv, cloth1->verts[collpair->ap2].tv, cloth1->verts[collpair->ap3].tv, w1, w2, w3); @@ -378,7 +510,7 @@ int collision_static(ClothModifierData *clmd, ClothModifierData *coll_clmd) return result; } -void bvh_collision_response_static(ClothModifierData *clmd, ClothModifierData *coll_clmd, Tree *tree1, Tree *tree2) +void cloth_collision_static(ClothModifierData *clmd, ClothModifierData *coll_clmd, Tree *tree1, Tree *tree2) { CollPair *collpair = NULL; Cloth *cloth1=NULL, *cloth2=NULL; @@ -468,8 +600,7 @@ void bvh_collision_response_static(ClothModifierData *clmd, ClothModifierData *c { // calc distance + normal distance = plNearestPoints( - verts1[collpair->ap1].txold, verts1[collpair->ap2].txold, verts1[collpair->ap3].txold, verts2[collpair->bp1].txold, verts2[collpair->bp2].txold, verts2[collpair->bp3].txold, - collpair->pa, collpair->pb, collpair->vector); + verts1[collpair->ap1].txold, verts1[collpair->ap2].txold, verts1[collpair->ap3].txold, verts2[collpair->bp1].txold, verts2[collpair->bp2].txold, verts2[collpair->bp3].txold, collpair->pa,collpair->pb,collpair->vector); if (distance <= (epsilon + ALMOST_ZERO)) { @@ -496,20 +627,20 @@ void bvh_collision_response_static(ClothModifierData *clmd, ClothModifierData *c } } -void bvh_collision_response_moving(ClothModifierData *clmd, ClothModifierData *coll_clmd, Tree *tree1, Tree *tree2) +void cloth_collision_moving_tris(ClothModifierData *clmd, ClothModifierData *coll_clmd, Tree *tree1, Tree *tree2) { - CollPair *collpair = NULL; + CollPair collpair; Cloth *cloth1=NULL, *cloth2=NULL; MFace *face1=NULL, *face2=NULL; ClothVertex *verts1=NULL, *verts2=NULL; double distance = 0; float epsilon = clmd->coll_parms.epsilon; - unsigned int i = 0; + unsigned int i = 0, j = 0, k = 0; + int numsolutions = 0; + float a[3], b[3], c[3], d[3], e[3], f[3], solution[3]; - for(i = 0; i < 4; i++) - { - collpair = (CollPair *)MEM_callocN(sizeof(CollPair), "cloth coll pair"); - + for(i = 0; i < 2; i++) + { cloth1 = clmd->clothObject; cloth2 = coll_clmd->clothObject; @@ -522,59 +653,28 @@ void bvh_collision_response_moving(ClothModifierData *clmd, ClothModifierData *c // check all possible pairs of triangles if(i == 0) { - collpair->ap1 = face1->v1; - collpair->ap2 = face1->v2; - collpair->ap3 = face1->v3; - - collpair->bp1 = face2->v1; - collpair->bp2 = face2->v2; - collpair->bp3 = face2->v3; + collpair.ap1 = face1->v1; + collpair.ap2 = face1->v2; + collpair.ap3 = face1->v3; + collpair.pointsb[0] = face2->v1; + collpair.pointsb[1] = face2->v2; + collpair.pointsb[2] = face2->v3; + collpair.pointsb[3] = face2->v4; } if(i == 1) { if(face1->v4) { - collpair->ap1 = face1->v3; - collpair->ap2 = face1->v4; - collpair->ap3 = face1->v1; + collpair.ap1 = face1->v3; + collpair.ap2 = face1->v4; + collpair.ap3 = face1->v1; - collpair->bp1 = face2->v1; - collpair->bp2 = face2->v2; - collpair->bp3 = face2->v3; - } - else - i++; - } - - if(i == 2) - { - if(face2->v4) - { - collpair->ap1 = face1->v1; - collpair->ap2 = face1->v2; - collpair->ap3 = face1->v3; - - collpair->bp1 = face2->v3; - collpair->bp2 = face2->v4; - collpair->bp3 = face2->v1; - } - else - i+=2; - } - - if(i == 3) - { - if((face1->v4)&&(face2->v4)) - { - collpair->ap1 = face1->v3; - collpair->ap2 = face1->v4; - collpair->ap3 = face1->v1; - - collpair->bp1 = face2->v3; - collpair->bp2 = face2->v4; - collpair->bp3 = face2->v1; + collpair.pointsb[0] = face2->v1; + collpair.pointsb[1] = face2->v2; + collpair.pointsb[2] = face2->v3; + collpair.pointsb[3] = face2->v4; } else i++; @@ -582,34 +682,40 @@ void bvh_collision_response_moving(ClothModifierData *clmd, ClothModifierData *c // calc SIPcode (?) - if(i < 4) + if(i < 2) { - // calc distance + normal - distance = plNearestPoints( - verts1[collpair->ap1].txold, verts1[collpair->ap2].txold, verts1[collpair->ap3].txold, verts2[collpair->bp1].txold, verts2[collpair->bp2].txold, verts2[collpair->bp3].txold, - collpair->pa, collpair->pb, collpair->vector); + VECSUB(a, verts1[collpair.ap2].xold, verts1[collpair.ap1].xold); + VECSUB(b, verts1[collpair.ap2].v, verts1[collpair.ap1].v); + VECSUB(c, verts1[collpair.ap3].xold, verts1[collpair.ap1].xold); + VECSUB(d, verts1[collpair.ap3].v, verts1[collpair.ap1].v); + + for(j = 0; j < 4; j++) + { + if((j==3) && !(face2->v4)) + break; + + VECSUB(e, verts2[collpair.pointsb[j]].xold, verts1[collpair.ap1].xold); + VECSUB(f, verts2[collpair.pointsb[j]].v, verts1[collpair.ap1].v); + + numsolutions = cloth_get_collision_time(a, b, c, d, e, f, solution); + + for (k = 0; k < numsolutions; k++) + { + if ((solution[k] >= 0.0) && (solution[k] <= 1.0)) + { + float out_collisionTime = solution[k]; + + // TODO: check for collisions + + // TODO: put into collision list + + printf("Moving found!\n"); + } + } + + // TODO: check borders for collisions + } - if (distance <= (epsilon + ALMOST_ZERO)) - { - // printf("dist: %f\n", (float)distance); - - // collpair->face1 = tree1->tri_index; - // collpair->face2 = tree2->tri_index; - - VECCOPY(collpair->normal, collpair->vector); - Normalize(collpair->normal); - - collpair->distance = distance; - BLI_linklist_append(&clmd->coll_parms.collision_list, collpair); - } - else - { - MEM_freeN(collpair); - } - } - else - { - MEM_freeN(collpair); } } } @@ -719,7 +825,7 @@ int cloth_bvh_objcollision(ClothModifierData * clmd, float step, float dt) { BVH *coll_bvh = coll_clmd->clothObject->tree; - bvh_traverse(clmd, coll_clmd, cloth_bvh->root, coll_bvh->root, step, bvh_collision_response_static); + bvh_traverse(clmd, coll_clmd, cloth_bvh->root, coll_bvh->root, step, cloth_collision_static); } else printf ("cloth_bvh_objcollision: found a collision object with clothObject or collData NULL.\n"); @@ -745,7 +851,7 @@ int cloth_bvh_objcollision(ClothModifierData * clmd, float step, float dt) if (coll_clmd->sim_parms.flags & CSIMSETT_FLAG_COLLOBJ) { if (coll_clmd->clothObject) - result += collision_static(clmd, coll_clmd); + result += cloth_collision_response_static(clmd, coll_clmd); else printf ("cloth_bvh_objcollision: found a collision object with clothObject or collData NULL.\n"); } @@ -855,7 +961,7 @@ int cloth_bvh_objcollision(ClothModifierData * clmd, float step, float dt) { BVH *coll_bvh = coll_clmd->clothObject->tree; - bvh_traverse(clmd, coll_clmd, cloth_bvh->root, coll_bvh->root, step, bvh_collision_response_moving); + bvh_traverse(clmd, coll_clmd, cloth_bvh->root, coll_bvh->root, step, cloth_collision_moving_tris); } else printf ("cloth_bvh_objcollision: found a collision object with clothObject or collData NULL.\n"); @@ -882,7 +988,7 @@ int cloth_bvh_objcollision(ClothModifierData * clmd, float step, float dt) if (coll_clmd->sim_parms.flags & CSIMSETT_FLAG_COLLOBJ) { if (coll_clmd->clothObject) - result += collision_moving(clmd, coll_clmd); + result += cloth_collision_response_moving_tris(clmd, coll_clmd); else printf ("cloth_bvh_objcollision: found a collision object with clothObject or collData NULL.\n"); } From 626edd8de8c3ce237c0ece95f99fb56f1b90bbe8 Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Thu, 4 Oct 2007 00:19:59 +0000 Subject: [PATCH 025/246] New: Collision detection for inter-timestep-collisions for edge-edge contacts. --- source/blender/blenkernel/intern/collision.c | 226 +++++++++++++++++-- 1 file changed, 202 insertions(+), 24 deletions(-) diff --git a/source/blender/blenkernel/intern/collision.c b/source/blender/blenkernel/intern/collision.c index 6100ff143d5..a89cd3dc4b9 100644 --- a/source/blender/blenkernel/intern/collision.c +++ b/source/blender/blenkernel/intern/collision.c @@ -627,6 +627,175 @@ void cloth_collision_static(ClothModifierData *clmd, ClothModifierData *coll_clm } } +int cloth_are_edges_adjacent(ClothModifierData *clmd, ClothModifierData *coll_clmd, EdgeCollPair *edgecollpair) +{ + Cloth *cloth1, *cloth2; + ClothVertex *verts1, *verts2; + float temp[3]; + + cloth1 = clmd->clothObject; + cloth2 = coll_clmd->clothObject; + + verts1 = cloth1->verts; + verts2 = cloth2->verts; + + VECSUB(temp, verts1[edgecollpair->p11].xold, verts2[edgecollpair->p21].xold); + if(ABS(INPR(temp, temp)) < ALMOST_ZERO) + return 1; + + VECSUB(temp, verts1[edgecollpair->p11].xold, verts2[edgecollpair->p22].xold); + if(ABS(INPR(temp, temp)) < ALMOST_ZERO) + return 1; + + VECSUB(temp, verts1[edgecollpair->p12].xold, verts2[edgecollpair->p21].xold); + if(ABS(INPR(temp, temp)) < ALMOST_ZERO) + return 1; + + VECSUB(temp, verts1[edgecollpair->p12].xold, verts2[edgecollpair->p22].xold); + if(ABS(INPR(temp, temp)) < ALMOST_ZERO) + return 1; + + return 0; +} + +void cloth_collision_moving_edges(ClothModifierData *clmd, ClothModifierData *coll_clmd, Tree *tree1, Tree *tree2) +{ + EdgeCollPair edgecollpair; + Cloth *cloth1=NULL, *cloth2=NULL; + MFace *face1=NULL, *face2=NULL; + ClothVertex *verts1=NULL, *verts2=NULL; + double distance = 0; + float epsilon = clmd->coll_parms.epsilon; + unsigned int i = 0, j = 0, k = 0; + int numsolutions = 0; + float a[3], b[3], c[3], d[3], e[3], f[3], solution[3]; + + cloth1 = clmd->clothObject; + cloth2 = coll_clmd->clothObject; + + verts1 = cloth1->verts; + verts2 = cloth2->verts; + + face1 = &(cloth1->mfaces[tree1->tri_index]); + face2 = &(cloth2->mfaces[tree2->tri_index]); + + for( i = 0; i < 5; i++) + { + if(i == 0) + { + edgecollpair.p11 = face1->v1; + edgecollpair.p12 = face1->v2; + } + else if(i == 1) + { + edgecollpair.p11 = face1->v2; + edgecollpair.p12 = face1->v3; + } + else if(i == 2) + { + if(face1->v4) + { + edgecollpair.p11 = face1->v3; + edgecollpair.p12 = face1->v4; + } + else + { + edgecollpair.p11 = face1->v3; + edgecollpair.p12 = face1->v1; + i+=5; // get out of here! + } + } + else if(i == 3) + { + if(face1->v4) + { + edgecollpair.p11 = face1->v4; + edgecollpair.p12 = face1->v1; + } + else + continue; + } + else + { + edgecollpair.p11 = face1->v3; + edgecollpair.p12 = face1->v1; + } + + + for( j = 0; j < 5; j++) + { + if(j == 0) + { + edgecollpair.p21 = face2->v1; + edgecollpair.p22 = face2->v2; + } + else if(j == 1) + { + edgecollpair.p21 = face2->v2; + edgecollpair.p22 = face2->v3; + } + else if(j == 2) + { + if(face2->v4) + { + edgecollpair.p21 = face2->v3; + edgecollpair.p22 = face2->v4; + } + else + { + edgecollpair.p21 = face2->v3; + edgecollpair.p22 = face2->v1; + } + } + else if(j == 3) + { + if(face2->v4) + { + edgecollpair.p21 = face2->v4; + edgecollpair.p22 = face2->v1; + } + else + continue; + } + else + { + edgecollpair.p21 = face2->v3; + edgecollpair.p22 = face2->v1; + } + + + if(!cloth_are_edges_adjacent(clmd, coll_clmd, &edgecollpair)) + { + VECSUB(a, verts1[edgecollpair.p12].xold, verts1[edgecollpair.p11].xold); + VECSUB(b, verts1[edgecollpair.p12].v, verts1[edgecollpair.p11].v); + VECSUB(c, verts1[edgecollpair.p21].xold, verts1[edgecollpair.p11].xold); + VECSUB(d, verts1[edgecollpair.p21].v, verts1[edgecollpair.p11].v); + VECSUB(e, verts2[edgecollpair.p22].xold, verts1[edgecollpair.p11].xold); + VECSUB(f, verts2[edgecollpair.p22].v, verts1[edgecollpair.p11].v); + + numsolutions = cloth_get_collision_time(a, b, c, d, e, f, solution); + + for (k = 0; k < numsolutions; k++) + { + if ((solution[k] >= 0.0) && (solution[k] <= 1.0)) + { + float out_collisionTime = solution[k]; + + // TODO: check for collisions + + // TODO: put into collision list + + printf("Moving edge found!\n"); + } + } + } + } + } + + + +} + void cloth_collision_moving_tris(ClothModifierData *clmd, ClothModifierData *coll_clmd, Tree *tree1, Tree *tree2) { CollPair collpair; @@ -690,36 +859,45 @@ void cloth_collision_moving_tris(ClothModifierData *clmd, ClothModifierData *col VECSUB(d, verts1[collpair.ap3].v, verts1[collpair.ap1].v); for(j = 0; j < 4; j++) - { - if((j==3) && !(face2->v4)) - break; - - VECSUB(e, verts2[collpair.pointsb[j]].xold, verts1[collpair.ap1].xold); - VECSUB(f, verts2[collpair.pointsb[j]].v, verts1[collpair.ap1].v); - - numsolutions = cloth_get_collision_time(a, b, c, d, e, f, solution); - - for (k = 0; k < numsolutions; k++) - { - if ((solution[k] >= 0.0) && (solution[k] <= 1.0)) - { - float out_collisionTime = solution[k]; - - // TODO: check for collisions - - // TODO: put into collision list - - printf("Moving found!\n"); - } + { + if((j==3) && !(face2->v4)) + break; + + VECSUB(e, verts2[collpair.pointsb[j]].xold, verts1[collpair.ap1].xold); + VECSUB(f, verts2[collpair.pointsb[j]].v, verts1[collpair.ap1].v); + + numsolutions = cloth_get_collision_time(a, b, c, d, e, f, solution); + + for (k = 0; k < numsolutions; k++) + { + if ((solution[k] >= 0.0) && (solution[k] <= 1.0)) + { + float out_collisionTime = solution[k]; + + // TODO: check for collisions + + // TODO: put into collision list + + printf("Moving found!\n"); } - - // TODO: check borders for collisions } + + // TODO: check borders for collisions + } } } } +void cloth_collision_moving(ClothModifierData *clmd, ClothModifierData *coll_clmd, Tree *tree1, Tree *tree2) +{ + // TODO: check for adjacent + cloth_collision_moving_edges(clmd, coll_clmd, tree1, tree2); + + cloth_collision_moving_tris(clmd, coll_clmd, tree1, tree2); + // cloth_collision_moving_tris(coll_clmd, clmd, tree2, tree1); +} + // move collision objects forward in time and update static bounding boxes void cloth_update_collision_objects(float step) { @@ -961,7 +1139,7 @@ int cloth_bvh_objcollision(ClothModifierData * clmd, float step, float dt) { BVH *coll_bvh = coll_clmd->clothObject->tree; - bvh_traverse(clmd, coll_clmd, cloth_bvh->root, coll_bvh->root, step, cloth_collision_moving_tris); + bvh_traverse(clmd, coll_clmd, cloth_bvh->root, coll_bvh->root, step, cloth_collision_moving); } else printf ("cloth_bvh_objcollision: found a collision object with clothObject or collData NULL.\n"); From e59bf9fa6f54700f7ba8ef41da5d93b6f177c6e5 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 10 Oct 2007 09:33:34 +0000 Subject: [PATCH 026/246] initial splitting of egde/face response --- source/blender/blenkernel/intern/collision.c | 98 +++++++++++--------- 1 file changed, 54 insertions(+), 44 deletions(-) diff --git a/source/blender/blenkernel/intern/collision.c b/source/blender/blenkernel/intern/collision.c index 5e90dd581d8..c3dbc572b4e 100644 --- a/source/blender/blenkernel/intern/collision.c +++ b/source/blender/blenkernel/intern/collision.c @@ -510,6 +510,17 @@ int cloth_collision_response_static(ClothModifierData *clmd, ClothModifierData * return result; } +int cloth_collision_response_moving_tris(ClothModifierData *clmd, ClothModifierData *coll_clmd) +{ + +} + + +int cloth_collision_response_moving_edges(ClothModifierData *clmd, ClothModifierData *coll_clmd) +{ + +} + void cloth_collision_static(ClothModifierData *clmd, ClothModifierData *coll_clmd, Tree *tree1, Tree *tree2) { CollPair *collpair = NULL; @@ -783,15 +794,14 @@ void cloth_collision_moving_edges(ClothModifierData *clmd, ClothModifierData *co // TODO: check for collisions - // TODO: put into collision list + // TODO: put into (edge) collision list printf("Moving edge found!\n"); } } } } - } - + } } void cloth_collision_moving_tris(ClothModifierData *clmd, ClothModifierData *coll_clmd, Tree *tree1, Tree *tree2) @@ -874,7 +884,7 @@ void cloth_collision_moving_tris(ClothModifierData *clmd, ClothModifierData *col // TODO: check for collisions - // TODO: put into collision list + // TODO: put into (point-face) collision list printf("Moving found!\n"); } @@ -893,7 +903,7 @@ void cloth_collision_moving(ClothModifierData *clmd, ClothModifierData *coll_clm cloth_collision_moving_edges(clmd, coll_clmd, tree1, tree2); cloth_collision_moving_tris(clmd, coll_clmd, tree1, tree2); - // cloth_collision_moving_tris(coll_clmd, clmd, tree2, tree1); + cloth_collision_moving_tris(coll_clmd, clmd, tree2, tree1); } // move collision objects forward in time and update static bounding boxes @@ -1010,7 +1020,7 @@ int cloth_bvh_objcollision(ClothModifierData * clmd, float step, float dt) // process all collisions (calculate impulses, TODO: also repulses if distance too short) result = 1; - for(j = 0; j < 50; j++) // 50 is just a value that ensures convergence + for(j = 0; j < 10; j++) // 10 is just a value that ensures convergence { result = 0; @@ -1143,50 +1153,50 @@ int cloth_bvh_objcollision(ClothModifierData * clmd, float step, float dt) printf ("cloth_bvh_objcollision: found a collision object with clothObject or collData NULL.\n"); } } - /* + // process all collisions (calculate impulses, TODO: also repulses if distance too short) result = 1; - for(j = 0; j < 50; j++) // 50 is just a value that ensures convergence + for(j = 0; j < 10; j++) // 10 is just a value that ensures convergence { - result = 0; - + result = 0; + // handle all collision objects - for (base = G.scene->base.first; base; base = base->next) - { - - coll_ob = base->object; - coll_clmd = (ClothModifierData *) modifiers_findByType (coll_ob, eModifierType_Cloth); - - if (!coll_clmd) - continue; - - // if collision object go on - if (coll_clmd->sim_parms.flags & CSIMSETT_FLAG_COLLOBJ) - { - if (coll_clmd->clothObject) - result += cloth_collision_response_moving_tris(clmd, coll_clmd); - else - printf ("cloth_bvh_objcollision: found a collision object with clothObject or collData NULL.\n"); - } - } + for (base = G.scene->base.first; base; base = base->next) + { - // apply impulses in parallel - ic=0; - for(i = 0; i < numverts; i++) - { - // calculate "velocities" (just xnew = xold + v; no dt in v) - if(verts[i].impulse_count) - { - VECADDMUL(verts[i].tv, verts[i].impulse, 1.0f / verts[i].impulse_count); - VECCOPY(verts[i].impulse, tnull); - verts[i].impulse_count = 0; + coll_ob = base->object; + coll_clmd = (ClothModifierData *) modifiers_findByType (coll_ob, eModifierType_Cloth); + + if (!coll_clmd) + continue; - ic++; - ret++; - } - } - } - */ + // if collision object go on + if (coll_clmd->sim_parms.flags & CSIMSETT_FLAG_COLLOBJ) + { + if (coll_clmd->clothObject) + result += cloth_collision_response_moving_tris(clmd, coll_clmd); + else + printf ("cloth_bvh_objcollision: found a collision object with clothObject or collData NULL.\n"); + } + } + + // apply impulses in parallel + ic=0; + for(i = 0; i < numverts; i++) + { + // calculate "velocities" (just xnew = xold + v; no dt in v) + if(verts[i].impulse_count) + { + VECADDMUL(verts[i].tv, verts[i].impulse, 1.0f / verts[i].impulse_count); + VECCOPY(verts[i].impulse, tnull); + verts[i].impulse_count = 0; + + ic++; + ret++; + } + } + } + // verts come from clmd for(i = 0; i < numverts; i++) From 5b019072a8fb486278e653761b1c2864549615c9 Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Thu, 18 Oct 2007 23:12:30 +0000 Subject: [PATCH 027/246] Springs are in a dynamic list now, New function cloth_add_spring() for easier access to spring handling, cleared up names, functions, code. Collisions can be enabled/disabled for cloth objects now --- source/blender/blenkernel/BKE_cloth.h | 147 +- source/blender/blenkernel/intern/cloth.c | 1255 ++++++++---------- source/blender/blenkernel/intern/collision.c | 17 +- source/blender/blenkernel/intern/implicit.c | 213 +-- source/blender/blenkernel/intern/kdop.c | 2 +- source/blender/blenkernel/intern/modifier.c | 9 +- source/blender/makesdna/DNA_cloth_types.h | 59 +- source/blender/src/buttons_object.c | 26 +- 8 files changed, 840 insertions(+), 888 deletions(-) diff --git a/source/blender/blenkernel/BKE_cloth.h b/source/blender/blenkernel/BKE_cloth.h index dc8d33804ee..692692dbf5a 100644 --- a/source/blender/blenkernel/BKE_cloth.h +++ b/source/blender/blenkernel/BKE_cloth.h @@ -1,6 +1,6 @@ /** - * BKE_cloth.h - * + * BKE_cloth.h + * * $Id: BKE_cloth.h,v 1.1 2007/08/01 02:07:27 daniel Exp $ * * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** @@ -47,7 +47,7 @@ struct DerivedMesh; // this is needed for inlining behaviour #ifndef _WIN32 -#define LINUX +#define LINUX #define DO_INLINE inline #else #define DO_INLINE @@ -57,17 +57,12 @@ struct DerivedMesh; /* goal defines */ -#define SOFTGOALSNAP 0.999f +#define SOFTGOALSNAP 0.999f /* This is approximately the smallest number that can be * represented by a float, given its precision. */ #define ALMOST_ZERO 0.000001 -/* Bits to or into the ClothVertex.flags. */ -#define CVERT_FLAG_PINNED 1 -#define CVERT_FLAG_COLLISION 2 - - // some macro enhancements for vector treatment #define VECADDADD(v1,v2,v3) {*(v1)+= *(v2) + *(v3); *(v1+1)+= *(v2+1) + *(v3+1); *(v1+2)+= *(v2+2) + *(v3+2);} #define VECSUBADD(v1,v2,v3) {*(v1)-= *(v2) + *(v3); *(v1+1)-= *(v2+1) + *(v3+1); *(v1+2)-= *(v2+2) + *(v3+2);} @@ -84,56 +79,70 @@ struct DerivedMesh; /* SIMULATION FLAGS: goal flags,.. */ /* These are the bits used in SimSettings.flags. */ -typedef enum +typedef enum { - CSIMSETT_FLAG_RESET = (1 << 1), // The CM object requires a reinitializaiton. - CSIMSETT_FLAG_COLLOBJ = (1 << 2), // object is only collision object, no cloth simulation is done - CSIMSETT_FLAG_GOAL = (1 << 3), // we have goals enabled - CSIMSETT_FLAG_TEARING_ENABLED = (1 << 4), // true if tearing is enabled - CSIMSETT_FLAG_CCACHE_PROTECT = (1 << 5), // true if tearing is enabled -} CSIMSETT_FLAGS; - -/* Spring types as defined in the paper.*/ -typedef enum -{ - STRUCTURAL = 0, - SHEAR, - BENDING, -} springType; + CLOTH_SIMSETTINGS_FLAG_RESET = ( 1 << 1 ), // The CM object requires a reinitializaiton. + CLOTH_SIMSETTINGS_FLAG_COLLOBJ = ( 1 << 2 ), // object is only collision object, no cloth simulation is done + CLOTH_SIMSETTINGS_FLAG_GOAL = ( 1 << 3 ), // we have goals enabled + CLOTH_SIMSETTINGS_FLAG_TEARING = ( 1 << 4 ), // true if tearing is enabled + CLOTH_SIMSETTINGS_FLAG_CCACHE_PROTECT = ( 1 << 5 ), // true if tearing is enabled +} CLOTH_SIMSETTINGS_FLAGS; /* SPRING FLAGS */ -typedef enum +typedef enum { - CSPRING_FLAG_DEACTIVATE = (1 << 1), - CSPRING_FLAG_NEEDED = (1 << 2), // springs has values to be applied -} CSPRINGS_FLAGS; + CLOTH_COLLISIONSETTINGS_FLAG_ENABLED = ( 1 << 1 ), +} CLOTH_COLLISIONSETTINGS_FLAGS; + +/* Spring types as defined in the paper.*/ +typedef enum +{ + CLOTH_SPRING_TYPE_STRUCTURAL = 0, + CLOTH_SPRING_TYPE_SHEAR, + CLOTH_SPRING_TYPE_BENDING, +} CLOTH_SPRING_TYPES; + +/* SPRING FLAGS */ +typedef enum +{ + CLOTH_SPRING_FLAG_DEACTIVATE = ( 1 << 1 ), + CLOTH_SPRING_FLAG_NEEDED = ( 1 << 2 ), // springs has values to be applied +} CLOTH_SPRINGS_FLAGS; + +/* Bits to or into the ClothVertex.flags. */ +#define CVERT_FLAG_PINNED 1 +#define CVERT_FLAG_COLLISION 2 + // needed for buttons_object.c -void cloth_cache_free(ClothModifierData *clmd, float time); -void cloth_free_modifier (ClothModifierData *clmd); +void cloth_cache_free ( ClothModifierData *clmd, float time ); +void cloth_free_modifier ( ClothModifierData *clmd ); // needed for cloth.c -void implicit_set_positions (ClothModifierData *clmd); +void implicit_set_positions ( ClothModifierData *clmd ); // from cloth.c, needed for modifier.c -void clothModifier_do(ClothModifierData *clmd, Object *ob, DerivedMesh *dm, float (*vertexCos)[3], int numverts); +void clothModifier_do ( ClothModifierData *clmd, Object *ob, DerivedMesh *dm, float ( *vertexCos ) [3], int numverts ); // used in collision.c -typedef struct Tree { +typedef struct Tree +{ struct Tree *nodes[4]; // 4 children --> quad-tree struct Tree *parent; - struct Tree *nextLeaf; + struct Tree *nextLeaf; struct Tree *prevLeaf; float bv[26]; // Bounding volume of all nodes / we have 7 axes on a 14-DOP unsigned int tri_index; // this saves the index of the face int count_nodes; // how many nodes are used int traversed; // how many nodes already traversed until this level? int isleaf; -} Tree; +} +Tree; typedef struct Tree TreeNode; -typedef struct BVH{ +typedef struct BVH +{ unsigned int numfaces; unsigned int numverts; ClothVertex *verts; // just a pointer to the original datastructure @@ -143,10 +152,11 @@ typedef struct BVH{ TreeNode *leaf_tree; /* Tail of the leaf linked list. */ TreeNode *leaf_root; /* Head of the leaf linked list. */ float epsilon; /* epslion is used for inflation of the k-dop */ - int flags; /* bvhFlags */ -} BVH; + int flags; /* bvhFlags */ +} +BVH; -typedef void (*CM_COLLISION_RESPONSE) (ClothModifierData *clmd, ClothModifierData *coll_clmd, Tree * tree1, Tree * tree2); +typedef void ( *CM_COLLISION_RESPONSE ) ( ClothModifierData *clmd, ClothModifierData *coll_clmd, Tree * tree1, Tree * tree2 ); ///////////////////////////////////////////////// @@ -154,8 +164,8 @@ typedef void (*CM_COLLISION_RESPONSE) (ClothModifierData *clmd, ClothModifierDat //////////////////////////////////////////////// // needed for implicit.c -void bvh_collision_response(ClothModifierData *clmd, ClothModifierData *coll_clmd, Tree * tree1, Tree * tree2); -int cloth_bvh_objcollision(ClothModifierData * clmd, float step, float dt); +void bvh_collision_response ( ClothModifierData *clmd, ClothModifierData *coll_clmd, Tree * tree1, Tree * tree2 ); +int cloth_bvh_objcollision ( ClothModifierData * clmd, float step, float dt ); //////////////////////////////////////////////// @@ -165,12 +175,13 @@ int cloth_bvh_objcollision(ClothModifierData * clmd, float step, float dt); //////////////////////////////////////////////// // needed for cloth.c -void bvh_free(BVH * bvh); -BVH *bvh_build (ClothModifierData *clmd, float epsilon); +void bvh_free ( BVH * bvh ); +BVH *bvh_build ( ClothModifierData *clmd, float epsilon ); +LinkNode *BLI_linklist_append_fast ( LinkNode **listp, void *ptr ); // needed for collision.c -int bvh_traverse(ClothModifierData * clmd, ClothModifierData * coll_clmd, Tree * tree1, Tree * tree2, float step, CM_COLLISION_RESPONSE collision_response); -void bvh_update(ClothModifierData * clmd, BVH * bvh, int moving); +int bvh_traverse ( ClothModifierData * clmd, ClothModifierData * coll_clmd, Tree * tree1, Tree * tree2, float step, CM_COLLISION_RESPONSE collision_response ); +void bvh_update ( ClothModifierData * clmd, BVH * bvh, int moving ); //////////////////////////////////////////////// @@ -179,41 +190,43 @@ void bvh_update(ClothModifierData * clmd, BVH * bvh, int moving); ///////////////////////////////////////////////// // cloth.c //////////////////////////////////////////////// -void cloth_free_modifier (ClothModifierData *clmd); -void cloth_init (ClothModifierData *clmd); -void cloth_deform_verts(struct Object *ob, float framenr, float (*vertexCos)[3], int numVerts, void *derivedData, ClothModifierData *clmd); -void cloth_update_normals (ClothVertex *verts, int nVerts, MFace *face, int totface); +void cloth_free_modifier ( ClothModifierData *clmd ); +void cloth_init ( ClothModifierData *clmd ); +void cloth_deform_verts ( struct Object *ob, float framenr, float ( *vertexCos ) [3], int numVerts, void *derivedData, ClothModifierData *clmd ); +void cloth_update_normals ( ClothVertex *verts, int nVerts, MFace *face, int totface ); //////////////////////////////////////////////// /* Typedefs for function pointers we need for solvers and collision detection. */ -typedef void (*CM_COLLISION_SELF) (ClothModifierData *clmd, int step); -typedef void (*CM_COLLISION_OBJ) (ClothModifierData *clmd, int step, CM_COLLISION_RESPONSE collision_response); +typedef void ( *CM_COLLISION_SELF ) ( ClothModifierData *clmd, int step ); +typedef void ( *CM_COLLISION_OBJ ) ( ClothModifierData *clmd, int step, CM_COLLISION_RESPONSE collision_response ); /* This enum provides the IDs for our solvers. */ // only one available in the moment typedef enum { - CM_IMPLICIT = 0, + CM_IMPLICIT = 0, } CM_SOLVER_ID; /* This structure defines how to call the solver. */ -typedef struct { +typedef struct +{ char *name; CM_SOLVER_ID id; - int (*init) (Object *ob, ClothModifierData *clmd); - int (*solver) (Object *ob, float framenr, ClothModifierData *clmd, ListBase *effectors); - int (*free) (ClothModifierData *clmd); -} CM_SOLVER_DEF; + int ( *init ) ( Object *ob, ClothModifierData *clmd ); + int ( *solver ) ( Object *ob, float framenr, ClothModifierData *clmd, ListBase *effectors ); + int ( *free ) ( ClothModifierData *clmd ); +} +CM_SOLVER_DEF; /* new C implicit simulator */ -int implicit_init (Object *ob, ClothModifierData *clmd); -int implicit_free (ClothModifierData *clmd); -int implicit_solver (Object *ob, float frame, ClothModifierData *clmd, ListBase *effectors); +int implicit_init ( Object *ob, ClothModifierData *clmd ); +int implicit_free ( ClothModifierData *clmd ); +int implicit_solver ( Object *ob, float frame, ClothModifierData *clmd, ListBase *effectors ); /* used for caching in implicit.c */ typedef struct Frame @@ -222,7 +235,8 @@ typedef struct Frame ClothSpring *springs; unsigned int numverts, numsprings; float time; /* we need float since we want to support sub-frames */ -} Frame; +} +Frame; /* used for collisions in collision.c */ typedef struct CollPair @@ -230,14 +244,15 @@ typedef struct CollPair unsigned int face1; // cloth face unsigned int face2; // object face double distance; // magnitude of vector - float normal[3]; + float normal[3]; float vector[3]; // unnormalized collision vector: p2-p1 float pa[3], pb[3]; // collision point p1 on face1, p2 on face2 int lastsign; // indicates if the distance sign has changed, unused itm float time; // collision time, from 0 up to 1 unsigned int ap1, ap2, ap3, bp1, bp2, bp3, bp4; unsigned int pointsb[4]; -} CollPair; +} +CollPair; /* used for collisions in collision.c */ typedef struct EdgeCollPair @@ -248,7 +263,8 @@ typedef struct EdgeCollPair float time; int lastsign; float pa[3], pb[3]; // collision point p1 on face1, p2 on face2 -} EdgeCollPair; +} +EdgeCollPair; /* used for collisions in collision.c */ typedef struct FaceCollPair @@ -259,7 +275,8 @@ typedef struct FaceCollPair float time; int lastsign; float pa[3], pb[3]; // collision point p1 on face1, p2 on face2 -} FaceCollPair; +} +FaceCollPair; #endif diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c index e86d1c50b69..eb7454ccd42 100644 --- a/source/blender/blenkernel/intern/cloth.c +++ b/source/blender/blenkernel/intern/cloth.c @@ -1,5 +1,5 @@ -/* cloth.c -* +/* cloth.c +* * * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** * @@ -41,7 +41,7 @@ #include "DNA_curve_types.h" #include "DNA_object_types.h" #include "DNA_object_force.h" -#include "DNA_cloth_types.h" +#include "DNA_cloth_types.h" #include "DNA_key_types.h" #include "DNA_mesh_types.h" #include "DNA_meshdata_types.h" @@ -77,12 +77,10 @@ #include "mydevice.h" #ifdef _WIN32 -void tstart(void) +void tstart ( void ) +{} +void tend ( void ) { -} -void tend(void) -{ - } double tval() { @@ -92,19 +90,19 @@ double tval() #include static struct timeval _tstart, _tend; static struct timezone tz; -void tstart(void) +void tstart ( void ) { - gettimeofday(&_tstart, &tz); + gettimeofday ( &_tstart, &tz ); } -void tend(void) +void tend ( void ) { - gettimeofday(&_tend,&tz); + gettimeofday ( &_tend,&tz ); } double tval() { double t1, t2; - t1 = (double)_tstart.tv_sec + (double)_tstart.tv_usec/(1000*1000); - t2 = (double)_tend.tv_sec + (double)_tend.tv_usec/(1000*1000); + t1 = ( double ) _tstart.tv_sec + ( double ) _tstart.tv_usec/ ( 1000*1000 ); + t2 = ( double ) _tend.tv_sec + ( double ) _tend.tv_usec/ ( 1000*1000 ); return t2-t1; } #endif @@ -112,20 +110,21 @@ double tval() /* Our available solvers. */ // 255 is the magic reserved number, so NEVER try to put 255 solvers in here! // 254 = MAX! -static CM_SOLVER_DEF solvers [] = { - { "Implicit", CM_IMPLICIT, implicit_init, implicit_solver, implicit_free }, - // { "Implicit C++", CM_IMPLICITCPP, implicitcpp_init, implicitcpp_solver, implicitcpp_free }, -}; +static CM_SOLVER_DEF solvers [] = + { + { "Implicit", CM_IMPLICIT, implicit_init, implicit_solver, implicit_free }, + // { "Implicit C++", CM_IMPLICITCPP, implicitcpp_init, implicitcpp_solver, implicitcpp_free }, + }; /* ********** cloth engine ******* */ /* Prototypes for internal functions. */ -static void cloth_to_object (Object *ob, ClothModifierData *clmd, float (*vertexCos)[3], unsigned int numverts); -static void cloth_from_mesh (Object *ob, ClothModifierData *clmd, DerivedMesh *dm); -static int cloth_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *dm, float (*vertexCos)[3], unsigned int numverts); -static int collobj_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *dm, float (*vertexCos)[3], unsigned int numverts); -int cloth_build_springs(Cloth *cloth, DerivedMesh *dm); -static void cloth_apply_vgroup(ClothModifierData *clmd, DerivedMesh *dm, short vgroup); +static void cloth_to_object ( Object *ob, ClothModifierData *clmd, float ( *vertexCos ) [3], unsigned int numverts ); +static void cloth_from_mesh ( Object *ob, ClothModifierData *clmd, DerivedMesh *dm ); +static int cloth_from_object ( Object *ob, ClothModifierData *clmd, DerivedMesh *dm, float ( *vertexCos ) [3], unsigned int numverts ); +static int collobj_from_object ( Object *ob, ClothModifierData *clmd, DerivedMesh *dm, float ( *vertexCos ) [3], unsigned int numverts ); +int cloth_build_springs ( Cloth *cloth, DerivedMesh *dm ); +static void cloth_apply_vgroup ( ClothModifierData *clmd, DerivedMesh *dm, short vgroup ); /****************************************************************************** @@ -137,9 +136,9 @@ static void cloth_apply_vgroup(ClothModifierData *clmd, DerivedMesh *dm, short v * cloth_init - creates a new cloth simulation. * * 1. create object -* 2. fill object with standard values or with the GUI settings if given +* 2. fill object with standard values or with the GUI settings if given */ -void cloth_init (ClothModifierData *clmd) +void cloth_init ( ClothModifierData *clmd ) { /* Initialize our new data structure to reasonable values. */ clmd->sim_parms.gravity [0] = 0.0; @@ -153,8 +152,8 @@ void cloth_init (ClothModifierData *clmd) clmd->sim_parms.mass = 1.0f; clmd->sim_parms.stepsPerFrame = 5; clmd->sim_parms.sim_time = 1.0; - clmd->sim_parms.flags = CSIMSETT_FLAG_RESET; - clmd->sim_parms.solver_type = 0; + clmd->sim_parms.flags = CLOTH_SIMSETTINGS_FLAG_RESET; + clmd->sim_parms.solver_type = 0; clmd->sim_parms.preroll = 0; clmd->sim_parms.maxspringlen = 10; clmd->sim_parms.firstframe = 1; @@ -163,7 +162,8 @@ void cloth_init (ClothModifierData *clmd) clmd->coll_parms.friction = 10.0; clmd->coll_parms.loop_count = 1; clmd->coll_parms.epsilon = 0.01f; - + clmd->coll_parms.flags = 0; + /* These defaults are copied from softbody.c's * softbody_calc_forces() function. */ @@ -181,17 +181,17 @@ void cloth_init (ClothModifierData *clmd) } // unused in the moment, cloth needs quads from mesh -DerivedMesh *CDDM_convert_to_triangle(DerivedMesh *dm) +DerivedMesh *CDDM_convert_to_triangle ( DerivedMesh *dm ) { DerivedMesh *result = NULL; int i; - int numverts = dm->getNumVerts(dm); - int numedges = dm->getNumEdges(dm); - int numfaces = dm->getNumFaces(dm); + int numverts = dm->getNumVerts ( dm ); + int numedges = dm->getNumEdges ( dm ); + int numfaces = dm->getNumFaces ( dm ); - MVert *mvert = CDDM_get_verts(dm); - MEdge *medge = CDDM_get_edges(dm); - MFace *mface = CDDM_get_faces(dm); + MVert *mvert = CDDM_get_verts ( dm ); + MEdge *medge = CDDM_get_edges ( dm ); + MFace *mface = CDDM_get_faces ( dm ); MVert *mvert2; MFace *mface2; @@ -203,36 +203,36 @@ DerivedMesh *CDDM_convert_to_triangle(DerivedMesh *dm) float vec1[3], vec2[3], vec3[3], vec4[3], vec5[3]; float mag1=0, mag2=0; - for(i = 0; i < numfaces; i++) + for ( i = 0; i < numfaces; i++ ) { - if(mface[i].v4) + if ( mface[i].v4 ) numquads++; else - numtris++; + numtris++; } - result = CDDM_from_template(dm, numverts, 0, numtris + 2*numquads); + result = CDDM_from_template ( dm, numverts, 0, numtris + 2*numquads ); - if(!result) + if ( !result ) return NULL; // do verts - mvert2 = CDDM_get_verts(result); - for(a=0; av1 = mface[a].v2; mf->v2 = mface[a].v3; @@ -260,9 +260,9 @@ DerivedMesh *CDDM_convert_to_triangle(DerivedMesh *dm) mf->v4 = 0; mf->flag |= ME_SMOOTH; - test_index_face(mf, NULL, 0, 3); + test_index_face ( mf, NULL, 0, 3 ); - if(mface[a].v4) + if ( mface[a].v4 ) { MFace *mf2; @@ -275,7 +275,7 @@ DerivedMesh *CDDM_convert_to_triangle(DerivedMesh *dm) *mf2 = *inMF; */ - if(random==1) + if ( random==1 ) { mf2->v1 = mface[a].v1; mf2->v2 = mface[a].v2; @@ -290,31 +290,31 @@ DerivedMesh *CDDM_convert_to_triangle(DerivedMesh *dm) mf2->v4 = 0; mf2->flag |= ME_SMOOTH; - test_index_face(mf2, NULL, 0, 3); + test_index_face ( mf2, NULL, 0, 3 ); } i++; } - CDDM_calc_edges(result); - CDDM_calc_normals(result); + CDDM_calc_edges ( result ); + CDDM_calc_normals ( result ); return result; } -DerivedMesh *CDDM_create_tearing(ClothModifierData *clmd, DerivedMesh *dm) +DerivedMesh *CDDM_create_tearing ( ClothModifierData *clmd, DerivedMesh *dm ) { DerivedMesh *result = NULL; unsigned int i = 0, a = 0, j=0; - int numverts = dm->getNumVerts(dm); - int numedges = dm->getNumEdges(dm); - int numfaces = dm->getNumFaces(dm); + int numverts = dm->getNumVerts ( dm ); + int numedges = dm->getNumEdges ( dm ); + int numfaces = dm->getNumFaces ( dm ); - MVert *mvert = CDDM_get_verts(dm); - MEdge *medge = CDDM_get_edges(dm); - MFace *mface = CDDM_get_faces(dm); + MVert *mvert = CDDM_get_verts ( dm ); + MEdge *medge = CDDM_get_edges ( dm ); + MFace *mface = CDDM_get_faces ( dm ); MVert *mvert2; MFace *mface2; @@ -324,45 +324,45 @@ DerivedMesh *CDDM_create_tearing(ClothModifierData *clmd, DerivedMesh *dm) Cloth *cloth = clmd->clothObject; ClothSpring *springs = cloth->springs; unsigned int numsprings = cloth->numsprings; - + // create spring tearing hash edgehash = BLI_edgehash_new(); - - for(i = 0; i < numsprings; i++) + + for ( i = 0; i < numsprings; i++ ) { - if((springs[i].flags & CSPRING_FLAG_DEACTIVATE) - &&(!BLI_edgehash_haskey(edgehash, springs[i].ij, springs[i].kl))) + if ( ( springs[i].flags & CLOTH_SPRING_FLAG_DEACTIVATE ) + && ( !BLI_edgehash_haskey ( edgehash, springs[i].ij, springs[i].kl ) ) ) { - BLI_edgehash_insert(edgehash, springs[i].ij, springs[i].kl, NULL); - BLI_edgehash_insert(edgehash, springs[i].kl, springs[i].ij, NULL); + BLI_edgehash_insert ( edgehash, springs[i].ij, springs[i].kl, NULL ); + BLI_edgehash_insert ( edgehash, springs[i].kl, springs[i].ij, NULL ); j++; } } - - // printf("found %d tears\n", j); - - result = CDDM_from_template(dm, numverts, 0, numfaces); - if(!result) + // printf("found %d tears\n", j); + + result = CDDM_from_template ( dm, numverts, 0, numfaces ); + + if ( !result ) return NULL; // do verts - mvert2 = CDDM_get_verts(result); - for(a=0; av1 = mface[a].v1; mf->v2 = mface[a].v2; mf->v3 = mface[a].v3; mf->v4 = mface[a].v4; - - test_index_face(mf, NULL, 0, 4); - + + test_index_face ( mf, NULL, 0, 4 ); + i++; } } - CDDM_lower_num_faces(result, i); - CDDM_calc_edges(result); - CDDM_calc_normals(result); - - BLI_edgehash_free(edgehash, NULL); + CDDM_lower_num_faces ( result, i ); + CDDM_calc_edges ( result ); + CDDM_calc_normals ( result ); + + BLI_edgehash_free ( edgehash, NULL ); return result; } -int cloth_cache_search_frame(ClothModifierData *clmd, float time) +int cloth_cache_search_frame ( ClothModifierData *clmd, float time ) { Frame *frame = NULL; - LinkNode *search = NULL; - - if(clmd->clothObject) + LinkNode *search = NULL; + + if ( clmd->clothObject ) { search = clmd->sim_parms.cache; - - while(search) + + while ( search ) { - frame = (Frame *)search->link; - - if(frame) + frame = ( Frame * ) search->link; + + if ( frame ) { - if(frame->time == time) + if ( frame->time == time ) return 1; } - + search = search->next; } } - + return 0; - + } -float cloth_cache_last_frame(ClothModifierData *clmd) +float cloth_cache_last_frame ( ClothModifierData *clmd ) { Frame *frame = NULL; - LinkNode *search = NULL; + LinkNode *search = NULL; float time = 0; - - if(clmd->clothObject) + + if ( clmd->clothObject ) { search = clmd->sim_parms.cache; - - while(search) + + while ( search ) { - frame = (Frame *)search->link; - - if(frame) + frame = ( Frame * ) search->link; + + if ( frame ) { - if(frame->time > time) + if ( frame->time > time ) time = frame->time; } } @@ -451,27 +451,27 @@ float cloth_cache_last_frame(ClothModifierData *clmd) return time; } -float cloth_cache_first_frame(ClothModifierData *clmd) +float cloth_cache_first_frame ( ClothModifierData *clmd ) { Frame *frame = NULL; - LinkNode *search = NULL; + LinkNode *search = NULL; float time = -1.0; - - if(clmd->clothObject) + + if ( clmd->clothObject ) { search = clmd->sim_parms.cache; - - while(search) + + while ( search ) { - frame = (Frame *)search->link; - - if(frame) + frame = ( Frame * ) search->link; + + if ( frame ) { - if(time < 0.0) + if ( time < 0.0 ) time = frame->time; else { - if(frame->time < time) + if ( frame->time < time ) time = frame->time; } } @@ -480,102 +480,102 @@ float cloth_cache_first_frame(ClothModifierData *clmd) return time; } -void cloth_cache_get_frame(ClothModifierData *clmd, float time) +void cloth_cache_get_frame ( ClothModifierData *clmd, float time ) { Frame *frame = NULL; LinkNode *search = NULL; - float newtime = time + clmd->sim_parms.preroll; - - if(clmd->clothObject) + float newtime = time + clmd->sim_parms.preroll; + + if ( clmd->clothObject ) { search = clmd->sim_parms.cache; - - while(search) + + while ( search ) { - frame = (Frame *)search->link; - - if(frame) + frame = ( Frame * ) search->link; + + if ( frame ) { - if(frame->time == newtime) + if ( frame->time == newtime ) { // something changed, free cache! - if(clmd->clothObject->numverts != frame->numverts) + if ( clmd->clothObject->numverts != frame->numverts ) { - cloth_cache_free(clmd, 0); - printf("clmd->clothObject->numverts != frame->numverts\n"); + cloth_cache_free ( clmd, 0 ); + printf ( "clmd->clothObject->numverts != frame->numverts\n" ); return; } - - memcpy(clmd->clothObject->verts, frame->verts, sizeof(ClothVertex)*frame->numverts); - implicit_set_positions(clmd); - + + memcpy ( clmd->clothObject->verts, frame->verts, sizeof ( ClothVertex ) *frame->numverts ); + implicit_set_positions ( clmd ); + return; } } - + search = search->next; } } } -void cloth_cache_set_frame(ClothModifierData *clmd, float time) +void cloth_cache_set_frame ( ClothModifierData *clmd, float time ) { Frame *frame = NULL; LinkNode *search = NULL; - - if(clmd->clothObject) + + if ( clmd->clothObject ) { - frame = (Frame *)MEM_callocN (sizeof (Frame), "cloth_cache_frame"); - - if(frame) + frame = ( Frame * ) MEM_callocN ( sizeof ( Frame ), "cloth_cache_frame" ); + + if ( frame ) { frame->time = time; frame->numverts = clmd->clothObject->numverts; - frame->verts = MEM_dupallocN(clmd->clothObject->verts); - - if(!frame->verts) + frame->verts = MEM_dupallocN ( clmd->clothObject->verts ); + + if ( !frame->verts ) { - MEM_freeN(frame); + MEM_freeN ( frame ); return; } - - BLI_linklist_append(&clmd->sim_parms.cache, frame); - + + BLI_linklist_append ( &clmd->sim_parms.cache, frame ); + } - } - + } + } // free cloth cache -void cloth_cache_free(ClothModifierData *clmd, float time) +void cloth_cache_free ( ClothModifierData *clmd, float time ) { Frame *frame = NULL; - LinkNode *search = NULL, *lastsearch = NULL; + LinkNode *search = NULL, *lastsearch = NULL; float newtime = time + clmd->sim_parms.preroll; - - if(time <= 2.0) + + if ( time <= 2.0 ) newtime = time; - if(clmd->clothObject) + if ( clmd->clothObject ) { - if(clmd->sim_parms.cache) - { + if ( clmd->sim_parms.cache ) + { lastsearch = search = clmd->sim_parms.cache; - - while(search) + + while ( search ) { - frame = (Frame *)search->link; - - if(frame->time >= newtime) + frame = ( Frame * ) search->link; + + if ( frame->time >= newtime ) { - if(frame->verts) + if ( frame->verts ) { - MEM_freeN(frame->verts); + MEM_freeN ( frame->verts ); } - MEM_freeN(frame); - + MEM_freeN ( frame ); + lastsearch->next = search->next; - MEM_freeN(search); + MEM_freeN ( search ); search = lastsearch->next; lastsearch->next = NULL; } @@ -585,13 +585,13 @@ void cloth_cache_free(ClothModifierData *clmd, float time) search = search->next; } } - - if(time <= 1.0) + + if ( time <= 1.0 ) { clmd->sim_parms.cache = NULL; } - - if(time <= 2.0) + + if ( time <= 2.0 ) clmd->sim_parms.preroll = 0; } } @@ -600,10 +600,10 @@ void cloth_cache_free(ClothModifierData *clmd, float time) /** * cloth_deform_verts - simulates one step, framenr is in frames. -* +* **/ -void clothModifier_do(ClothModifierData *clmd, Object *ob, DerivedMesh *dm, - float (*vertexCos)[3], int numverts) +void clothModifier_do ( ClothModifierData *clmd, Object *ob, DerivedMesh *dm, + float ( *vertexCos ) [3], int numverts ) { unsigned int i; unsigned int numedges = -1; @@ -613,124 +613,124 @@ void clothModifier_do(ClothModifierData *clmd, Object *ob, DerivedMesh *dm, MFace *mface = NULL; DerivedMesh *result = NULL, *result2 = NULL; Cloth *cloth = clmd->clothObject; - unsigned int framenr = (float)G.scene->r.cfra; - float current_time = bsystem_time(ob, (float)G.scene->r.cfra, 0.0); + unsigned int framenr = ( float ) G.scene->r.cfra; + float current_time = bsystem_time ( ob, ( float ) G.scene->r.cfra, 0.0 ); ListBase *effectors = NULL; ClothVertex *newframe= NULL, *verts; Frame *frame = NULL; LinkNode *search = NULL; - float deltaTime = current_time - clmd->sim_parms.sim_time; - - + float deltaTime = current_time - clmd->sim_parms.sim_time; + + // only be active during a specific period: // that's "first frame" and "last frame" on GUI - if (!(clmd->sim_parms.flags & CSIMSETT_FLAG_COLLOBJ)) + if ( ! ( clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_COLLOBJ ) ) { - if(clmd->clothObject) + if ( clmd->clothObject ) { - if(clmd->sim_parms.cache) + if ( clmd->sim_parms.cache ) { - if(current_time < clmd->sim_parms.firstframe) + if ( current_time < clmd->sim_parms.firstframe ) { - int frametime = cloth_cache_first_frame(clmd); - if(cloth_cache_search_frame(clmd, frametime)) + int frametime = cloth_cache_first_frame ( clmd ); + if ( cloth_cache_search_frame ( clmd, frametime ) ) { - cloth_cache_get_frame(clmd, frametime); - cloth_to_object (ob, clmd, vertexCos, numverts); + cloth_cache_get_frame ( clmd, frametime ); + cloth_to_object ( ob, clmd, vertexCos, numverts ); } return; } - else if(current_time > clmd->sim_parms.lastframe) + else if ( current_time > clmd->sim_parms.lastframe ) { - int frametime = cloth_cache_last_frame(clmd); - if(cloth_cache_search_frame(clmd, frametime)) + int frametime = cloth_cache_last_frame ( clmd ); + if ( cloth_cache_search_frame ( clmd, frametime ) ) { - cloth_cache_get_frame(clmd, frametime); - cloth_to_object (ob, clmd, vertexCos, numverts); + cloth_cache_get_frame ( clmd, frametime ); + cloth_to_object ( ob, clmd, vertexCos, numverts ); } return; } - else if(ABS(deltaTime) >= 2.0f ) // no timewarps allowed + else if ( ABS ( deltaTime ) >= 2.0f ) // no timewarps allowed { - if(cloth_cache_search_frame(clmd, framenr)) + if ( cloth_cache_search_frame ( clmd, framenr ) ) { - cloth_cache_get_frame(clmd, framenr); - cloth_to_object (ob, clmd, vertexCos, numverts); + cloth_cache_get_frame ( clmd, framenr ); + cloth_to_object ( ob, clmd, vertexCos, numverts ); } clmd->sim_parms.sim_time = current_time; return; } } - + } } - - + + // unused in the moment, calculated seperately in implicit.c clmd->sim_parms.dt = 1.0f / clmd->sim_parms.stepsPerFrame; - + clmd->sim_parms.sim_time = current_time; - + // check if cloth object was some collision object before and needs freeing now - if (!(clmd->sim_parms.flags & CSIMSETT_FLAG_COLLOBJ) && (clmd->clothObject != NULL) && (clmd->clothObject->old_solver_type == 255)) + if ( ! ( clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_COLLOBJ ) && ( clmd->clothObject != NULL ) && ( clmd->clothObject->old_solver_type == 255 ) ) { - // temporary set CSIMSETT_FLAG_COLLOBJ flag for proper freeing - clmd->sim_parms.flags |= CSIMSETT_FLAG_COLLOBJ; - cloth_free_modifier(clmd); - clmd->sim_parms.flags &= ~CSIMSETT_FLAG_COLLOBJ; + // temporary set CSIMSETT_FLAG_COLLOBJ flag for proper freeing + clmd->sim_parms.flags |= CLOTH_SIMSETTINGS_FLAG_COLLOBJ; + cloth_free_modifier ( clmd ); + clmd->sim_parms.flags &= ~CLOTH_SIMSETTINGS_FLAG_COLLOBJ; } // This is for collisions objects: check special case CSIMSETT_FLAG_COLLOBJ - if (clmd->sim_parms.flags & CSIMSETT_FLAG_COLLOBJ) + if ( clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_COLLOBJ ) { - // save next position + time - if ((clmd->clothObject == NULL) || (numverts != clmd->clothObject->numverts) ) + // save next position + time + if ( ( clmd->clothObject == NULL ) || ( numverts != clmd->clothObject->numverts ) ) { - if(!collobj_from_object (ob, clmd, dm, vertexCos, framenr)) + if ( !collobj_from_object ( ob, clmd, dm, vertexCos, framenr ) ) { - clmd->sim_parms.flags |= CSIMSETT_FLAG_COLLOBJ; - cloth_free_modifier(clmd); + clmd->sim_parms.flags |= CLOTH_SIMSETTINGS_FLAG_COLLOBJ; + cloth_free_modifier ( clmd ); return; } - if(clmd->clothObject == NULL) + if ( clmd->clothObject == NULL ) return; cloth = clmd->clothObject; } - // Save old position + // Save old position clmd->sim_parms.sim_time_old = clmd->sim_parms.sim_time; - clmd->sim_parms.sim_time = current_time; - - verts = cloth->verts; - - for (i = 0; i < clmd->clothObject->numverts; i++, verts++) - { - // Save the previous position. - VECCOPY (verts->xold, verts->x); - VECCOPY (verts->txold, verts->x); + clmd->sim_parms.sim_time = current_time; - // Get the current position. - VECCOPY (verts->x, vertexCos[i]); - Mat4MulVecfl(ob->obmat, verts->x); + verts = cloth->verts; + + for ( i = 0; i < clmd->clothObject->numverts; i++, verts++ ) + { + // Save the previous position. + VECCOPY ( verts->xold, verts->x ); + VECCOPY ( verts->txold, verts->x ); + + // Get the current position. + VECCOPY ( verts->x, vertexCos[i] ); + Mat4MulVecfl ( ob->obmat, verts->x ); // Compute the vertices "velocity". // (no dt correction here because of float error) - VECSUB (verts->v, verts->x, verts->xold); + VECSUB ( verts->v, verts->x, verts->xold ); } - - return; - } - if(deltaTime == 1.0f) + return; + } + + if ( deltaTime == 1.0f ) { - if ((clmd->clothObject == NULL) || (numverts != clmd->clothObject->numverts) ) + if ( ( clmd->clothObject == NULL ) || ( numverts != clmd->clothObject->numverts ) ) { - if(!cloth_from_object (ob, clmd, dm, vertexCos, numverts)) + if ( !cloth_from_object ( ob, clmd, dm, vertexCos, numverts ) ) return; - if(clmd->clothObject == NULL) + if ( clmd->clothObject == NULL ) return; cloth = clmd->clothObject; @@ -739,112 +739,125 @@ void clothModifier_do(ClothModifierData *clmd, Object *ob, DerivedMesh *dm, clmd->clothObject->old_solver_type = clmd->sim_parms.solver_type; // Insure we have a clmd->clothObject, in case allocation failed. - if (clmd->clothObject != NULL) - { - if(!cloth_cache_search_frame(clmd, framenr)) + if ( clmd->clothObject != NULL ) + { + if ( !cloth_cache_search_frame ( clmd, framenr ) ) { verts = cloth->verts; - - // Force any pinned verts to their constrained location. - for (i = 0; i < clmd->clothObject->numverts; i++, verts++) - { - // Save the previous position. - VECCOPY (verts->xold, verts->xconst); - VECCOPY (verts->txold, verts->x); - // Get the current position. - VECCOPY (verts->xconst, vertexCos[i]); - Mat4MulVecfl(ob->obmat, verts->xconst); + // Force any pinned verts to their constrained location. + for ( i = 0; i < clmd->clothObject->numverts; i++, verts++ ) + { + // Save the previous position. + VECCOPY ( verts->xold, verts->xconst ); + VECCOPY ( verts->txold, verts->x ); + + // Get the current position. + VECCOPY ( verts->xconst, vertexCos[i] ); + Mat4MulVecfl ( ob->obmat, verts->xconst ); } tstart(); // Call the solver. - if (solvers [clmd->sim_parms.solver_type].solver) - solvers [clmd->sim_parms.solver_type].solver (ob, framenr, clmd, effectors); - - tend(); - printf("Cloth simulation time: %f\n", (float)tval()); + if ( solvers [clmd->sim_parms.solver_type].solver ) + solvers [clmd->sim_parms.solver_type].solver ( ob, framenr, clmd, effectors ); - cloth_cache_set_frame(clmd, framenr); + tend(); + printf ( "Cloth simulation time: %f\n", ( float ) tval() ); + + cloth_cache_set_frame ( clmd, framenr ); } else // just retrieve the cached frame { - cloth_cache_get_frame(clmd, framenr); + cloth_cache_get_frame ( clmd, framenr ); } // Copy the result back to the object. - cloth_to_object (ob, clmd, vertexCos, numverts); - + cloth_to_object ( ob, clmd, vertexCos, numverts ); + // bvh_free(clmd->clothObject->tree); // clmd->clothObject->tree = bvh_build(clmd, clmd->coll_parms.epsilon); - } + } } - else if((deltaTime <= 0.0f)||(deltaTime > 1.0f)) + else if ( ( deltaTime <= 0.0f ) || ( deltaTime > 1.0f ) ) { - if((clmd->clothObject != NULL) && (clmd->sim_parms.cache)) + if ( ( clmd->clothObject != NULL ) && ( clmd->sim_parms.cache ) ) { - if(cloth_cache_search_frame(clmd, framenr)) + if ( cloth_cache_search_frame ( clmd, framenr ) ) { - cloth_cache_get_frame(clmd, framenr); - cloth_to_object (ob, clmd, vertexCos, numverts); + cloth_cache_get_frame ( clmd, framenr ); + cloth_to_object ( ob, clmd, vertexCos, numverts ); } } } - + } /* frees all */ -void cloth_free_modifier (ClothModifierData *clmd) +void cloth_free_modifier ( ClothModifierData *clmd ) { Cloth *cloth = NULL; - if(!clmd) + if ( !clmd ) return; cloth = clmd->clothObject; - - if(!(clmd->sim_parms.flags & CSIMSETT_FLAG_CCACHE_PROTECT)) + + if ( ! ( clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_CCACHE_PROTECT ) ) { // free our frame cache, TODO: but get to first position before - cloth_cache_free(clmd, 0); - - if (cloth) - { + cloth_cache_free ( clmd, 0 ); + + if ( cloth ) + { + // If our solver provides a free function, call it - if (cloth->old_solver_type < 255 && solvers [cloth->old_solver_type].free) - { - solvers [cloth->old_solver_type].free (clmd); + if ( cloth->old_solver_type < 255 && solvers [cloth->old_solver_type].free ) + { + solvers [cloth->old_solver_type].free ( clmd ); } - + // Free the verts. - if (cloth->verts != NULL) - MEM_freeN (cloth->verts); - + if ( cloth->verts != NULL ) + MEM_freeN ( cloth->verts ); + cloth->verts = NULL; cloth->numverts = 0; - + // Free the springs. - if (cloth->springs != NULL) - MEM_freeN (cloth->springs); - + if ( cloth->springs != NULL ) + { + LinkNode *search = cloth->springs; + while(search) + { + ClothSpring *spring = search->link; + + MEM_freeN ( spring ); + search = search->next; + } + BLI_linklist_free(cloth->springs, NULL); + + cloth->springs = NULL; + } + cloth->springs = NULL; - cloth->numsprings = 0; - + cloth->numsprings = 0; + // free BVH collision tree - if(cloth->tree) - bvh_free((BVH *)cloth->tree); - + if ( cloth->tree ) + bvh_free ( ( BVH * ) cloth->tree ); + // we save our faces for collision objects - if(cloth->mfaces) - MEM_freeN(cloth->mfaces); + if ( cloth->mfaces ) + MEM_freeN ( cloth->mfaces ); /* if(clmd->clothObject->facemarks) MEM_freeN(clmd->clothObject->facemarks); */ - MEM_freeN (cloth); + MEM_freeN ( cloth ); clmd->clothObject = NULL; } } @@ -862,21 +875,22 @@ void cloth_free_modifier (ClothModifierData *clmd) * * This function is a modified version of the softbody.c:softbody_to_object() function. **/ -static void cloth_to_object (Object *ob, ClothModifierData *clmd, float (*vertexCos)[3], unsigned int numverts) +static void cloth_to_object ( Object *ob, ClothModifierData *clmd, float ( *vertexCos ) [3], unsigned int numverts ) { ClothVertex *verts = NULL; unsigned int i = 0; - if (clmd->clothObject) { + if ( clmd->clothObject ) + { verts = clmd->clothObject->verts; /* inverse matrix is not uptodate... */ - Mat4Invert (ob->imat, ob->obmat); + Mat4Invert ( ob->imat, ob->obmat ); - for (i = 0; i < numverts; i++, verts++) + for ( i = 0; i < numverts; i++, verts++ ) { - VECCOPY (vertexCos[i], verts->x); - Mat4MulVecfl (ob->imat, vertexCos[i]); /* softbody is in global coords */ + VECCOPY ( vertexCos[i], verts->x ); + Mat4MulVecfl ( ob->imat, vertexCos[i] ); /* softbody is in global coords */ } } } @@ -886,46 +900,46 @@ static void cloth_to_object (Object *ob, ClothModifierData *clmd, float (*vertex * cloth_apply_vgroup - applies a vertex group as specified by type * **/ -static void cloth_apply_vgroup(ClothModifierData *clmd, DerivedMesh *dm, short vgroup) +static void cloth_apply_vgroup ( ClothModifierData *clmd, DerivedMesh *dm, short vgroup ) { unsigned int i = 0; unsigned int j = 0; MDeformVert *dvert = NULL; Cloth *clothObj = NULL; - unsigned int numverts = dm->getNumVerts(dm); + unsigned int numverts = dm->getNumVerts ( dm ); float goalfac = 0; ClothVertex *verts = NULL; clothObj = clmd->clothObject; - - if(!dm) + + if ( !dm ) return; - - numverts = dm->getNumVerts(dm); + + numverts = dm->getNumVerts ( dm ); /* vgroup is 1 based, decrement so we can match the right group. */ --vgroup; - + verts = clothObj->verts; - for (i = 0; i < numverts; i++, verts++) - { + for ( i = 0; i < numverts; i++, verts++ ) + { // LATER ON, support also mass painting here - if(clmd->sim_parms.flags & CSIMSETT_FLAG_GOAL) - { - dvert = dm->getVertData(dm, i, CD_MDEFORMVERT); - if(dvert) - { - for(j = 0; j < dvert->totweight; j++) + if ( clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_GOAL ) + { + dvert = dm->getVertData ( dm, i, CD_MDEFORMVERT ); + if ( dvert ) + { + for ( j = 0; j < dvert->totweight; j++ ) { - if(dvert->dw[j].def_nr == vgroup) + if ( dvert->dw[j].def_nr == vgroup ) { verts->goal = dvert->dw [j].weight; - goalfac= ABS(clmd->sim_parms.maxgoal - clmd->sim_parms.mingoal); - verts->goal = (float)pow(verts->goal , 4.0f); + goalfac= ABS ( clmd->sim_parms.maxgoal - clmd->sim_parms.mingoal ); + verts->goal = ( float ) pow ( verts->goal , 4.0f ); - if(dvert->dw [j].weight >=SOFTGOALSNAP) + if ( dvert->dw [j].weight >=SOFTGOALSNAP ) { verts->flags |= CVERT_FLAG_PINNED; } @@ -942,360 +956,221 @@ static void cloth_apply_vgroup(ClothModifierData *clmd, DerivedMesh *dm, short v // only meshes supported at the moment /* collision objects */ -static int collobj_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *dm, float (*vertexCos)[3], unsigned int numverts) +static int collobj_from_object ( Object *ob, ClothModifierData *clmd, DerivedMesh *dm, float ( *vertexCos ) [3], unsigned int numverts ) { unsigned int i; - MVert *mvert = NULL; + MVert *mvert = NULL; ClothVertex *verts = NULL; - float tnull[3] = {0,0,0}; - + float tnull[3] = {0,0,0}; + /* If we have a clothObject, free it. */ - if (clmd->clothObject != NULL) - cloth_free_modifier (clmd); + if ( clmd->clothObject != NULL ) + cloth_free_modifier ( clmd ); /* Allocate a new cloth object. */ - clmd->clothObject = MEM_callocN (sizeof(Cloth), "cloth"); - if (clmd->clothObject) + clmd->clothObject = MEM_callocN ( sizeof ( Cloth ), "cloth" ); + if ( clmd->clothObject ) { clmd->clothObject->old_solver_type = 255; - clmd->clothObject->old_collision_type = 255; + // clmd->clothObject->old_collision_type = 255; } - else if (clmd->clothObject == NULL) + else if ( clmd->clothObject == NULL ) { - modifier_setError (&(clmd->modifier), "Out of memory on allocating clmd->clothObject."); + modifier_setError ( & ( clmd->modifier ), "Out of memory on allocating clmd->clothObject." ); return 0; } - switch (ob->type) + switch ( ob->type ) { - case OB_MESH: - - // mesh input objects need DerivedMesh - if(!dm) - return 0; - - cloth_from_mesh (ob, clmd, dm); - - if (clmd->clothObject != NULL) - { - if (!dm) return 0; - if (!dm->getNumVerts(dm) || !dm->getNumFaces(dm)) return 0; - - mvert = dm->getVertArray(dm); - verts = clmd->clothObject->verts; - numverts = clmd->clothObject->numverts = dm->getNumVerts(dm); - - for (i = 0; i < numverts; i++, verts++) + case OB_MESH: + + // mesh input objects need DerivedMesh + if ( !dm ) + return 0; + + cloth_from_mesh ( ob, clmd, dm ); + + if ( clmd->clothObject != NULL ) { - VECCOPY (verts->x, mvert[i].co); - Mat4MulVecfl(ob->obmat, verts->x); - verts->flags = 0; - VECCOPY(verts->xold, verts->x); - VECCOPY(verts->txold, verts->x); - VECCOPY(verts->tx, verts->x); - VecMulf(verts->v, 0.0f); - verts->impulse_count = 0; - VECCOPY(verts->impulse, tnull); + if ( !dm ) return 0; + if ( !dm->getNumVerts ( dm ) || !dm->getNumFaces ( dm ) ) return 0; + + mvert = dm->getVertArray ( dm ); + verts = clmd->clothObject->verts; + numverts = clmd->clothObject->numverts = dm->getNumVerts ( dm ); + + for ( i = 0; i < numverts; i++, verts++ ) + { + VECCOPY ( verts->x, mvert[i].co ); + Mat4MulVecfl ( ob->obmat, verts->x ); + verts->flags = 0; + VECCOPY ( verts->xold, verts->x ); + VECCOPY ( verts->txold, verts->x ); + VECCOPY ( verts->tx, verts->x ); + VecMulf ( verts->v, 0.0f ); + verts->impulse_count = 0; + VECCOPY ( verts->impulse, tnull ); + } + clmd->clothObject->tree = bvh_build ( clmd,clmd->coll_parms.epsilon ); + } - clmd->clothObject->tree = bvh_build(clmd,clmd->coll_parms.epsilon); - - } - - return 1; - default: return 0; // TODO - we do not support changing meshes + + return 1; + default: return 0; // TODO - we do not support changing meshes } } /* -helper function to get proper spring length +helper function to get proper spring length when object is rescaled */ -float cloth_globallen(float *v1,float *v2,Object *ob) +float cloth_globallen ( float *v1,float *v2,Object *ob ) { float p1[3],p2[3]; - VECCOPY(p1,v1); - Mat4MulVecfl(ob->obmat, p1); - VECCOPY(p2,v2); - Mat4MulVecfl(ob->obmat, p2); - return VecLenf(p1,p2); + VECCOPY ( p1,v1 ); + Mat4MulVecfl ( ob->obmat, p1 ); + VECCOPY ( p2,v2 ); + Mat4MulVecfl ( ob->obmat, p2 ); + return VecLenf ( p1,p2 ); } -static void curve_surf_to_cloth(Object *ob, ClothModifierData *clmd, float (*vertexCos)[3]) -{ - Curve *cu= ob->data; - Nurb *nu; - BezTriple *bezt; - float goalfac; - unsigned int a, curindex=0, i=0; - unsigned int numverts, numsprings = 0, setgoal=0; - Cloth *clothObj; - ClothVertex *verts = NULL; - - clmd->clothObject->numverts = numverts= count_curveverts(&cu->nurb); - clothObj = clmd->clothObject; - - if(ob->type==OB_CURVE) - { - numsprings = numverts - BLI_countlist(&cu->nurb); - } - - /* Allocate our vertices. - */ - clmd->clothObject->numverts = numverts; - clmd->clothObject->verts = MEM_callocN (sizeof (ClothVertex) * clmd->clothObject->numverts, "clothVertex"); - if (clmd->clothObject->verts == NULL) - { - cloth_free_modifier (clmd); - modifier_setError (&(clmd->modifier), "Out of memory on allocating clmd->clothObject->verts."); - return; - } - - verts = clmd->clothObject->verts; - - // copy vertex positions - for (i = 0; i < numverts; i++) - { - VECCOPY (verts->x, vertexCos[i]); - Mat4MulVecfl(ob->obmat, verts->x); - - verts->mass = clmd->sim_parms.mass; - // verts->goal= clmd->sim_parms.defgoal; - verts->flags = 0; - VECCOPY(verts->xold, verts->x); - VECCOPY(verts->xconst, verts->x); - VECCOPY(verts->txold, verts->x); - VecMulf(verts->v, 0.0f); - } - - clmd->clothObject->mfaces = NULL; // update face pointer - clmd->clothObject->numfaces = 0; - - clmd->clothObject->springs = MEM_callocN (sizeof (ClothSpring) * (numsprings), "cloth_springs_alloc"); - - // set vars now - goalfac= ABS(clmd->sim_parms.maxgoal - clmd->sim_parms.mingoal); - // clothObj->verts [i].goal = clmd->sim_parms.mingoal + bezt->weight*goalfac; - - /* apply / set vertex groups */ - if(clmd->sim_parms.flags & CSIMSETT_FLAG_GOAL) - { - if (clmd->sim_parms.vgroup_mass > 0) - { - setgoal = 1; - } - } - -/* - for(nu= cu->nurb.first; nu; nu= nu->next) - { - if(nu->bezt) - { - for(bezt=nu->bezt, a=0; apntsu; a++, bezt++, bp+=3, curindex+=3) - { - if(setgoal) - { - bp->goal= sb->mingoal + bezt->weight*goalfac; - // a little ad hoc changing the goal control to be less *sharp* - bp->goal = (float)pow(bp->goal, 4.0f); - - // all three triples - (bp+1)->goal= bp->goal; - (bp+2)->goal= bp->goal; - } - - if(totspring) - { - if(a>0) - { - bs->v1= curindex-1; - bs->v2= curindex; - bs->strength= 1.0; - bs->order=1; - bs->len= globallen( (bezt-1)->vec[2], bezt->vec[0], ob ); - bs++; - } - bs->v1= curindex; - bs->v2= curindex+1; - bs->strength= 1.0; - bs->order=1; - bs->len= globallen( bezt->vec[0], bezt->vec[1], ob ); - bs++; - - bs->v1= curindex+1; - bs->v2= curindex+2; - bs->strength= 1.0; - bs->order=1; - bs->len= globallen( bezt->vec[1], bezt->vec[2], ob ); - bs++; - } - } - } - else { - for(bpnt=nu->bp, a=0; apntsu*nu->pntsv; a++, bpnt++, bp++, curindex++) - { - if(setgoal) - { - bp->goal= sb->mingoal + bpnt->weight*goalfac; - // a little ad hoc changing the goal control to be less *sharp* - bp->goal = (float)pow(bp->goal, 4.0f); - } - if(totspring && a>0) - { - bs->v1= curindex-1; - bs->v2= curindex; - bs->strength= 1.0; - bs->order=1; - bs->len= globallen( (bpnt-1)->vec, bpnt->vec , ob ); - bs++; - } - } - } - } - */ -} - // only meshes supported at the moment -static int cloth_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *dm, float (*vertexCos)[3], unsigned int numverts) +static int cloth_from_object ( Object *ob, ClothModifierData *clmd, DerivedMesh *dm, float ( *vertexCos ) [3], unsigned int numverts ) { unsigned int i = 0; // dm->getNumVerts(dm); MVert *mvert = NULL; // CDDM_get_verts(dm); ClothVertex *verts = NULL; float tnull[3] = {0,0,0}; - + /* If we have a clothObject, free it. */ - if (clmd->clothObject != NULL) - cloth_free_modifier (clmd); + if ( clmd->clothObject != NULL ) + cloth_free_modifier ( clmd ); /* Allocate a new cloth object. */ - clmd->clothObject = MEM_callocN (sizeof(Cloth), "cloth"); - if (clmd->clothObject) + clmd->clothObject = MEM_callocN ( sizeof ( Cloth ), "cloth" ); + if ( clmd->clothObject ) { clmd->clothObject->old_solver_type = 255; - clmd->clothObject->old_collision_type = 255; + // clmd->clothObject->old_collision_type = 255; } - else if (clmd->clothObject == NULL) + else if ( !clmd->clothObject ) { - modifier_setError (&(clmd->modifier), "Out of memory on allocating clmd->clothObject."); + modifier_setError ( & ( clmd->modifier ), "Out of memory on allocating clmd->clothObject." ); return 0; } - switch (ob->type) + switch ( ob->type ) { case OB_MESH: - - // mesh input objects need DerivedMesh - if(!dm) - return 0; - - cloth_from_mesh (ob, clmd, dm); - if (clmd->clothObject != NULL) - { - /* create springs */ - clmd->clothObject->springs = NULL; - clmd->clothObject->numsprings = -1; - - if (!cloth_build_springs (clmd->clothObject, dm) ) - { - modifier_setError (&(clmd->modifier), "Can't build springs."); + // mesh input objects need DerivedMesh + if ( !dm ) return 0; - } - - mvert = CDDM_get_verts(dm); - verts = clmd->clothObject->verts; - /* set initial values */ - for (i = 0; i < numverts; i++, verts++) + cloth_from_mesh ( ob, clmd, dm ); + + if ( clmd->clothObject != NULL ) { - VECCOPY (verts->x, mvert[i].co); - Mat4MulVecfl(ob->obmat, verts->x); + /* create springs */ + clmd->clothObject->springs = NULL; + clmd->clothObject->numsprings = -1; - verts->mass = clmd->sim_parms.mass; - - if(clmd->sim_parms.flags & CSIMSETT_FLAG_GOAL) - verts->goal= clmd->sim_parms.defgoal; - else - verts->goal= 0.0f; - - verts->flags = 0; - VECCOPY(verts->xold, verts->x); - VECCOPY(verts->xconst, verts->x); - VECCOPY(verts->txold, verts->x); - VecMulf(verts->v, 0.0f); - - verts->impulse_count = 0; - VECCOPY(verts->impulse, tnull); + if ( !cloth_build_springs ( clmd->clothObject, dm ) ) + { + modifier_setError ( & ( clmd->modifier ), "Can't build springs." ); + return 0; + } + + mvert = CDDM_get_verts ( dm ); + verts = clmd->clothObject->verts; + + /* set initial values */ + for ( i = 0; i < numverts; i++, verts++ ) + { + VECCOPY ( verts->x, mvert[i].co ); + Mat4MulVecfl ( ob->obmat, verts->x ); + + verts->mass = clmd->sim_parms.mass; + + if ( clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_GOAL ) + verts->goal= clmd->sim_parms.defgoal; + else + verts->goal= 0.0f; + + verts->flags = 0; + VECCOPY ( verts->xold, verts->x ); + VECCOPY ( verts->xconst, verts->x ); + VECCOPY ( verts->txold, verts->x ); + VecMulf ( verts->v, 0.0f ); + + verts->impulse_count = 0; + VECCOPY ( verts->impulse, tnull ); + } + + // apply / set vertex groups + if ( clmd->sim_parms.vgroup_mass > 0 ) + cloth_apply_vgroup ( clmd, dm, clmd->sim_parms.vgroup_mass ); + + // init our solver + if ( solvers [clmd->sim_parms.solver_type].init ) + solvers [clmd->sim_parms.solver_type].init ( ob, clmd ); + + clmd->clothObject->tree = bvh_build ( clmd, clmd->coll_parms.epsilon ); + + cloth_cache_set_frame ( clmd, 1 ); } - // apply / set vertex groups - if (clmd->sim_parms.vgroup_mass > 0) - cloth_apply_vgroup (clmd, dm, clmd->sim_parms.vgroup_mass); - - // init our solver - if (solvers [clmd->sim_parms.solver_type].init) - solvers [clmd->sim_parms.solver_type].init (ob, clmd); - - clmd->clothObject->tree = bvh_build(clmd, clmd->coll_parms.epsilon); - - cloth_cache_set_frame(clmd, 1); - } - - return 1; + return 1; case OB_LATTICE: - printf("OB_LATTICE\n"); - // lattice_to_softbody(ob); - return 1; + printf ( "Not supported: OB_LATTICE\n" ); + // lattice_to_softbody(ob); + return 1; case OB_CURVE: case OB_SURF: - printf("OB_SURF| OB_CURVE\n"); - curve_surf_to_cloth(ob, clmd, vertexCos); - return 1; + printf ( "Not supported: OB_SURF| OB_CURVE\n" ); + return 1; default: return 0; // TODO - we do not support changing meshes } - + return 0; } -static void cloth_from_mesh (Object *ob, ClothModifierData *clmd, DerivedMesh *dm) +static void cloth_from_mesh ( Object *ob, ClothModifierData *clmd, DerivedMesh *dm ) { - unsigned int numverts = dm->getNumVerts(dm); - unsigned int numfaces = dm->getNumFaces(dm); - MFace *mface = dm->getFaceArray(dm); + unsigned int numverts = dm->getNumVerts ( dm ); + unsigned int numfaces = dm->getNumFaces ( dm ); + MFace *mface = dm->getFaceArray ( dm ); unsigned int i = 0; /* Allocate our vertices. */ clmd->clothObject->numverts = numverts; - clmd->clothObject->verts = MEM_callocN (sizeof (ClothVertex) * clmd->clothObject->numverts, "clothVertex"); - if (clmd->clothObject->verts == NULL) + clmd->clothObject->verts = MEM_callocN ( sizeof ( ClothVertex ) * clmd->clothObject->numverts, "clothVertex" ); + if ( clmd->clothObject->verts == NULL ) { - cloth_free_modifier (clmd); - modifier_setError (&(clmd->modifier), "Out of memory on allocating clmd->clothObject->verts."); + cloth_free_modifier ( clmd ); + modifier_setError ( & ( clmd->modifier ), "Out of memory on allocating clmd->clothObject->verts." ); return; } - + // save face information clmd->clothObject->numfaces = numfaces; - clmd->clothObject->mfaces = MEM_callocN (sizeof (MFace) * clmd->clothObject->numfaces, "clothMFaces"); - if (clmd->clothObject->mfaces == NULL) + clmd->clothObject->mfaces = MEM_callocN ( sizeof ( MFace ) * clmd->clothObject->numfaces, "clothMFaces" ); + if ( clmd->clothObject->mfaces == NULL ) { - cloth_free_modifier (clmd); - modifier_setError (&(clmd->modifier), "Out of memory on allocating clmd->clothObject->mfaces."); + cloth_free_modifier ( clmd ); + modifier_setError ( & ( clmd->modifier ), "Out of memory on allocating clmd->clothObject->mfaces." ); return; } - for(i = 0; i < numfaces; i++) - memcpy(&clmd->clothObject->mfaces[i], &mface[i], sizeof(MFace)); - - - // for SIP code - // clmd->clothObject->facemarks = MEM_callocN (sizeof (unsigned char) * clmd->clothObject->numfaces, "clothFaceMarks"); + for ( i = 0; i < numfaces; i++ ) + memcpy ( &clmd->clothObject->mfaces[i], &mface[i], sizeof ( MFace ) ); /* Free the springs since they can't be correct if the vertices * changed. */ - if (clmd->clothObject->springs != NULL) - MEM_freeN (clmd->clothObject->springs); + if ( clmd->clothObject->springs != NULL ) + MEM_freeN ( clmd->clothObject->springs ); } @@ -1303,126 +1178,166 @@ static void cloth_from_mesh (Object *ob, ClothModifierData *clmd, DerivedMesh *d * SPRING NETWORK BUILDING IMPLEMENTATION BEGIN ***************************************************************************************/ -int cloth_build_springs(Cloth *cloth, DerivedMesh *dm) +// be carefull: implicit solver has to be resettet when using this one! +int cloth_add_spring ( ClothModifierData *clmd, unsigned int indexA, unsigned int indexB, float restlength, int spring_type) { - ClothSpring *springs = NULL; + Cloth *cloth = clmd->clothObject; + ClothSpring *spring = NULL; + + if(cloth) + { + // TODO: look if this spring is already there + + spring = ( ClothSpring * ) MEM_callocN ( sizeof ( ClothSpring ), "cloth spring" ); + + spring->ij = indexA; + spring->kl = indexB; + spring->restlen = restlength; + spring->type = spring_type; + spring->flags = 0; + + cloth->numsprings++; + + BLI_linklist_append ( &cloth->springs, spring ); + } +} + +int cloth_build_springs ( Cloth *cloth, DerivedMesh *dm ) +{ + ClothSpring *spring = NULL, *tspring = NULL, *tspring2 = NULL; unsigned int struct_springs = 0, shear_springs=0, bend_springs = 0; unsigned int i = 0; - unsigned int numverts = dm->getNumVerts(dm); - unsigned int numedges = dm->getNumEdges(dm); - unsigned int numfaces = dm->getNumFaces(dm); - MVert *mvert = CDDM_get_verts(dm); - MEdge *medge = CDDM_get_edges(dm); - MFace *mface = CDDM_get_faces(dm); + unsigned int numverts = dm->getNumVerts ( dm ); + unsigned int numedges = dm->getNumEdges ( dm ); + unsigned int numfaces = dm->getNumFaces ( dm ); + MVert *mvert = CDDM_get_verts ( dm ); + MEdge *medge = CDDM_get_edges ( dm ); + MFace *mface = CDDM_get_faces ( dm ); unsigned int index2 = 0; // our second vertex index LinkNode **edgelist = NULL; EdgeHash *edgehash = NULL; - LinkNode *search = NULL; + LinkNode *search = NULL, *search2 = NULL; float temp[3]; - unsigned int temp_index = 0; - ClothSpring *tspring = NULL; // error handling - if(numedges==0) + if ( numedges==0 ) return 0; - edgelist = MEM_callocN (sizeof (LinkNode *) * numverts, "cloth_edgelist_alloc"); - for(i = 0; i < numverts; i++) + cloth->springs = NULL; + + edgelist = MEM_callocN ( sizeof ( LinkNode * ) * numverts, "cloth_edgelist_alloc" ); + for ( i = 0; i < numverts; i++ ) { edgelist[i] = NULL; } - if(cloth->springs) - MEM_freeN(cloth->springs); + if ( cloth->springs ) + MEM_freeN ( cloth->springs ); // create spring network hash edgehash = BLI_edgehash_new(); - // should be 4 for maximal bending springs, using 5 to be sure ;) - springs = cloth->springs = MEM_callocN (sizeof (ClothSpring) * (numedges + numfaces * 2 + 6 * numverts), "cloth_springs_alloc"); - // structural springs - for(i = 0; i < numedges; i++) + for ( i = 0; i < numedges; i++ ) { - springs[i].ij = medge[i].v1; - springs[i].kl = medge[i].v2; - VECSUB(temp, mvert[springs[i].kl].co, mvert[springs[i].ij].co); - springs[i].restlen = sqrt(INPR(temp, temp)); - springs[i].type = STRUCTURAL; - springs[i].flags = 0; - struct_springs++; + spring = ( ClothSpring * ) MEM_callocN ( sizeof ( ClothSpring ), "cloth spring" ); + + if ( spring ) + { + spring->ij = medge[i].v1; + spring->kl = medge[i].v2; + VECSUB ( temp, mvert[spring->kl].co, mvert[spring->ij].co ); + spring->restlen = sqrt ( INPR ( temp, temp ) ); + spring->type = CLOTH_SPRING_TYPE_STRUCTURAL; + spring->flags = 0; + struct_springs++; + + BLI_linklist_append ( &cloth->springs, spring ); + } } // shear springs - for(i = 0; i < numfaces; i++) + for ( i = 0; i < numfaces; i++ ) { - temp_index = struct_springs + shear_springs; + spring = ( ClothSpring *) MEM_callocN ( sizeof ( ClothSpring ), "cloth spring" ); - springs[temp_index].ij = mface[i].v1; - springs[temp_index].kl = mface[i].v3; - VECSUB(temp, mvert[springs[temp_index].kl].co, mvert[springs[temp_index].ij].co); - springs[temp_index].restlen = sqrt(INPR(temp, temp)); - springs[temp_index].type = SHEAR; - - BLI_linklist_append(&edgelist[springs[temp_index].ij], &(springs[temp_index])); - BLI_linklist_append(&edgelist[springs[temp_index].kl], &(springs[temp_index])); + spring->ij = mface[i].v1; + spring->kl = mface[i].v3; + VECSUB ( temp, mvert[spring->kl].co, mvert[spring->ij].co ); + spring->restlen = sqrt ( INPR ( temp, temp ) ); + spring->type = CLOTH_SPRING_TYPE_SHEAR; + BLI_linklist_append ( &edgelist[spring->ij], spring ); + BLI_linklist_append ( &edgelist[spring->kl], spring ); shear_springs++; - temp_index++; - - if(mface[i].v4) + + BLI_linklist_append ( &cloth->springs, spring ); + + if ( mface[i].v4 ) { - springs[temp_index].ij = mface[i].v2; - springs[temp_index].kl = mface[i].v4; - VECSUB(temp, mvert[springs[temp_index].kl].co, mvert[springs[temp_index].ij].co); - springs[temp_index].restlen = sqrt(INPR(temp, temp)); - springs[temp_index].type = SHEAR; - - BLI_linklist_append(&edgelist[springs[temp_index].ij], &(springs[temp_index])); - BLI_linklist_append(&edgelist[springs[temp_index].kl], &(springs[temp_index])); - - shear_springs++; + spring = ( ClothSpring * ) MEM_callocN ( sizeof ( ClothSpring ), "cloth spring" ); + + spring->ij = mface[i].v1; + spring->kl = mface[i].v3; + VECSUB ( temp, mvert[spring->kl].co, mvert[spring->ij].co ); + spring->restlen = sqrt ( INPR ( temp, temp ) ); + spring->type = CLOTH_SPRING_TYPE_SHEAR; + + BLI_linklist_append ( &edgelist[spring->ij], spring ); + BLI_linklist_append ( &edgelist[spring->kl], spring ); + shear_springs++; + + BLI_linklist_append ( &cloth->springs, spring ); } } // bending springs - for(i = struct_springs; i < struct_springs+shear_springs; i++) - { - search = edgelist[springs[i].kl]; - while(search) + search2 = cloth->springs; + for ( i = struct_springs; i < struct_springs+shear_springs; i++ ) + { + if ( !search2 ) + break; + + tspring2 = search2->link; + search = edgelist[tspring2->kl]; + while ( search ) { tspring = search->link; - index2 = ((tspring->ij==springs[i].kl) ? (tspring->kl) : (tspring->ij)); - - if(!BLI_edgehash_haskey(edgehash, index2, springs[i].ij) // check for existing spring - && !BLI_edgehash_haskey(edgehash, springs[i].ij, index2) // same - && (index2!=springs[i].ij)) // check if startpoint is equal to endpoint + index2 = ( ( tspring->ij==tspring2->kl ) ? ( tspring->kl ) : ( tspring->ij ) ); + + // check for existing spring + // check also if startpoint is equal to endpoint + if ( !BLI_edgehash_haskey ( edgehash, index2, tspring2->ij ) + && !BLI_edgehash_haskey ( edgehash, tspring2->ij, index2 ) + && ( index2!=tspring2->ij ) ) { - temp_index = struct_springs + shear_springs + bend_springs; + spring = ( ClothSpring * ) MEM_callocN ( sizeof ( ClothSpring ), "cloth spring" ); - springs[temp_index].ij = springs[i].ij; - springs[temp_index].kl = index2; - VECSUB(temp, mvert[index2].co, mvert[springs[i].ij].co); - springs[temp_index].restlen = sqrt(INPR(temp, temp)); - springs[temp_index].type = BENDING; - BLI_edgehash_insert(edgehash, springs[temp_index].ij, index2, NULL); + spring->ij = tspring2->ij; + spring->kl = index2; + VECSUB ( temp, mvert[index2].co, mvert[tspring2->ij].co ); + spring->restlen = sqrt ( INPR ( temp, temp ) ); + spring->type = CLOTH_SPRING_TYPE_BENDING; + BLI_edgehash_insert ( edgehash, spring->ij, index2, NULL ); bend_springs++; + BLI_linklist_append ( &cloth->springs, spring ); } - search = search->next; + search = search->next; } + search2 = search2->next; } cloth->numsprings = struct_springs + shear_springs + bend_springs; - for(i = 0; i < numverts; i++) + for ( i = 0; i < numverts; i++ ) { - BLI_linklist_free(edgelist[i],NULL); + BLI_linklist_free ( edgelist[i],NULL ); } - if(edgelist) - MEM_freeN(edgelist); + if ( edgelist ) + MEM_freeN ( edgelist ); - BLI_edgehash_free(edgehash, NULL); + BLI_edgehash_free ( edgehash, NULL ); return 1; diff --git a/source/blender/blenkernel/intern/collision.c b/source/blender/blenkernel/intern/collision.c index c3dbc572b4e..a5a382f7624 100644 --- a/source/blender/blenkernel/intern/collision.c +++ b/source/blender/blenkernel/intern/collision.c @@ -77,7 +77,7 @@ * * copied from SOLVE_CUBIC.C --> GSL */ -#define mySWAP(a,b) do { float tmp = b ; b = a ; a = tmp ; } while(0) +#define mySWAP(a,b) { float tmp = b ; b = a ; a = tmp ; } int gsl_poly_solve_cubic (float a, float b, float c, float *x0, float *x1, float *x2) { @@ -361,8 +361,6 @@ DO_INLINE void interpolateOnTriangle(float to[3], float v1[3], float v2[3], floa VECADDMUL(to, v3, w3); } - - // unused in the moment, has some bug in DO_INLINE void calculateFrictionImpulse(float to[3], float vrel[3], float normal[3], double normalVelocity, double frictionConstant, double delta_V_n) @@ -887,6 +885,7 @@ void cloth_collision_moving_tris(ClothModifierData *clmd, ClothModifierData *col // TODO: put into (point-face) collision list printf("Moving found!\n"); + } } @@ -924,7 +923,7 @@ void cloth_update_collision_objects(float step) continue; // if collision object go on - if (coll_clmd->sim_parms.flags & CSIMSETT_FLAG_COLLOBJ) + if (coll_clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_COLLOBJ) { if (coll_clmd->clothObject && coll_clmd->clothObject->tree) { @@ -969,7 +968,7 @@ int cloth_bvh_objcollision(ClothModifierData * clmd, float step, float dt) float tnull[3] = {0,0,0}; int ret = 0; - if ((clmd->sim_parms.flags & CSIMSETT_FLAG_COLLOBJ) || !(((Cloth *)clmd->clothObject)->tree)) + if ((clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_COLLOBJ) || !(((Cloth *)clmd->clothObject)->tree)) { return 0; } @@ -1005,7 +1004,7 @@ int cloth_bvh_objcollision(ClothModifierData * clmd, float step, float dt) continue; // if collision object go on - if (coll_clmd->sim_parms.flags & CSIMSETT_FLAG_COLLOBJ) + if (coll_clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_COLLOBJ) { if (coll_clmd->clothObject && coll_clmd->clothObject->tree) { @@ -1034,7 +1033,7 @@ int cloth_bvh_objcollision(ClothModifierData * clmd, float step, float dt) continue; // if collision object go on - if (coll_clmd->sim_parms.flags & CSIMSETT_FLAG_COLLOBJ) + if (coll_clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_COLLOBJ) { if (coll_clmd->clothObject) result += cloth_collision_response_static(clmd, coll_clmd); @@ -1141,7 +1140,7 @@ int cloth_bvh_objcollision(ClothModifierData * clmd, float step, float dt) continue; // if collision object go on - if (coll_clmd->sim_parms.flags & CSIMSETT_FLAG_COLLOBJ) + if (coll_clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_COLLOBJ) { if (coll_clmd->clothObject && coll_clmd->clothObject->tree) { @@ -1171,7 +1170,7 @@ int cloth_bvh_objcollision(ClothModifierData * clmd, float step, float dt) continue; // if collision object go on - if (coll_clmd->sim_parms.flags & CSIMSETT_FLAG_COLLOBJ) + if (coll_clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_COLLOBJ) { if (coll_clmd->clothObject) result += cloth_collision_response_moving_tris(clmd, coll_clmd); diff --git a/source/blender/blenkernel/intern/implicit.c b/source/blender/blenkernel/intern/implicit.c index 7f156acff71..1ee4475a6cc 100644 --- a/source/blender/blenkernel/intern/implicit.c +++ b/source/blender/blenkernel/intern/implicit.c @@ -700,15 +700,15 @@ int implicit_init (Object *ob, ClothModifierData *clmd) unsigned int pinned = 0; Cloth *cloth = NULL; ClothVertex *verts = NULL; - ClothSpring *springs = NULL; + ClothSpring *spring = NULL; Implicit_Data *id = NULL; + LinkNode *search = NULL; // init memory guard // MEMORY_BASE.first = MEMORY_BASE.last = NULL; cloth = (Cloth *)clmd->clothObject; verts = cloth->verts; - springs = cloth->springs; // create implicit base id = (Implicit_Data *)MEM_callocN (sizeof(Implicit_Data), "implicit vecmat"); @@ -749,17 +749,22 @@ int implicit_init (Object *ob, ClothModifierData *clmd) id->S[0].vcount = pinned; id->S[0].scount = 0; // init springs */ + search = cloth->springs; for(i=0;inumsprings;i++) { + spring = search->link; + // dFdV_start[i].r = big_I[i].r = big_zero[i].r = id->A[i+cloth->numverts].r = id->dFdV[i+cloth->numverts].r = id->dFdX[i+cloth->numverts].r = - id->P[i+cloth->numverts].r = id->Pinv[i+cloth->numverts].r = id->bigI[i+cloth->numverts].r = springs[i].ij; + id->P[i+cloth->numverts].r = id->Pinv[i+cloth->numverts].r = id->bigI[i+cloth->numverts].r = spring->ij; // dFdV_start[i].c = big_I[i].c = big_zero[i].c = id->A[i+cloth->numverts].c = id->dFdV[i+cloth->numverts].c = id->dFdX[i+cloth->numverts].c = - id->P[i+cloth->numverts].c = id->Pinv[i+cloth->numverts].c = id->bigI[i+cloth->numverts].c = springs[i].kl; + id->P[i+cloth->numverts].c = id->Pinv[i+cloth->numverts].c = id->bigI[i+cloth->numverts].c = spring->kl; - springs[i].matrix_index = i + cloth->numverts; + spring->matrix_index = i + cloth->numverts; + + search = search->next; } for(i = 0; i < cloth->numverts; i++) @@ -1170,7 +1175,7 @@ DO_INLINE void cloth_calc_spring_force(ClothModifierData *clmd, ClothSpring *s, VECSUB(vel, V[s->kl], V[s->ij]); length = sqrt(INPR(extent, extent)); - s->flags &= ~CSPRING_FLAG_NEEDED; + s->flags &= ~CLOTH_SPRING_FLAG_NEEDED; if(length > ABS(ALMOST_ZERO)) { @@ -1193,12 +1198,12 @@ DO_INLINE void cloth_calc_spring_force(ClothModifierData *clmd, ClothSpring *s, } - // calculate force of structural springs - if(s->type != BENDING) + // calculate force of structural + shear springs + if(s->type != CLOTH_SPRING_TYPE_BENDING) { if(length > L) // only on elonglation { - s->flags |= CSPRING_FLAG_NEEDED; + s->flags |= CLOTH_SPRING_FLAG_NEEDED; k = clmd->sim_parms.structural; @@ -1219,7 +1224,7 @@ DO_INLINE void cloth_calc_spring_force(ClothModifierData *clmd, ClothSpring *s, { if(length < L) { - s->flags |= CSPRING_FLAG_NEEDED; + s->flags |= CLOTH_SPRING_FLAG_NEEDED; k = clmd->sim_parms.bending; @@ -1231,6 +1236,27 @@ DO_INLINE void cloth_calc_spring_force(ClothModifierData *clmd, ClothSpring *s, } } +DO_INLINE void cloth_apply_spring_force(ClothModifierData *clmd, ClothSpring *s, lfVector *lF, lfVector *X, lfVector *V, fmatrix3x3 *dFdV, fmatrix3x3 *dFdX) +{ + if(s->flags & CLOTH_SPRING_FLAG_NEEDED) + { + if(s->type != CLOTH_SPRING_TYPE_BENDING) + { + sub_fmatrix_fmatrix(dFdV[s->ij].m, dFdV[s->ij].m, s->dfdv); + sub_fmatrix_fmatrix(dFdV[s->kl].m, dFdV[s->kl].m, s->dfdv); + add_fmatrix_fmatrix(dFdV[s->matrix_index].m, dFdV[s->matrix_index].m, s->dfdv); + } + + VECADD(lF[s->ij], lF[s->ij], s->f); + VECSUB(lF[s->kl], lF[s->kl], s->f); + + sub_fmatrix_fmatrix(dFdX[s->ij].m, dFdX[s->ij].m, s->dfdx); + sub_fmatrix_fmatrix(dFdX[s->kl].m, dFdX[s->kl].m, s->dfdx); + + add_fmatrix_fmatrix(dFdX[s->matrix_index].m, dFdX[s->matrix_index].m, s->dfdx); + } +} + DO_INLINE void calculateTriangleNormal(float to[3], lfVector *X, MFace mface) { float v1[3], v2[3]; @@ -1239,6 +1265,7 @@ DO_INLINE void calculateTriangleNormal(float to[3], lfVector *X, MFace mface) VECSUB(v2, X[mface.v3], X[mface.v1]); cross_fvector(to, v1, v2); } + DO_INLINE void calculatQuadNormal(float to[3], lfVector *X, MFace mface) { float temp = CalcNormFloat4(X[mface.v1],X[mface.v2],X[mface.v3],X[mface.v4],to); @@ -1280,12 +1307,12 @@ void cloth_calc_force(ClothModifierData *clmd, lfVector *lF, lfVector *lX, lfVec float gravity[3]; float tm2[3][3] = {{-spring_air,0,0}, {0,-spring_air,0},{0,0,-spring_air}}; ClothVertex *verts = cloth->verts; - ClothSpring *springs = cloth->springs; MFace *mfaces = cloth->mfaces; float wind_normalized[3]; unsigned int numverts = cloth->numverts; float auxvect[3], velgoal[3], tvect[3]; float kd, ks; + LinkNode *search = cloth->springs; VECCOPY(gravity, clmd->sim_parms.gravity); @@ -1301,7 +1328,7 @@ void cloth_calc_force(ClothModifierData *clmd, lfVector *lF, lfVector *lX, lfVec submul_lfvectorS(lF, lV, spring_air, numverts); /* do goal stuff */ - if(clmd->sim_parms.flags & CSIMSETT_FLAG_GOAL) + if(clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_GOAL) { for(i = 0; i < numverts; i++) { @@ -1350,53 +1377,25 @@ void cloth_calc_force(ClothModifierData *clmd, lfVector *lF, lfVector *lX, lfVec } } - /* calculate and apply spring forces */ -#pragma omp parallel private(i) -{ -#pragma omp for nowait - for(i = 0; i < cloth->numsprings/2; i++) + // calculate spring forces + search = cloth->springs; + while(search) { // only handle active springs - // if(((clmd->sim_parms.flags & CSIMSETT_FLAG_TEARING_ENABLED) && !(springs[i].flags & CSPRING_FLAG_DEACTIVATE))|| !(clmd->sim_parms.flags & CSIMSETT_FLAG_TEARING_ENABLED)) - // { - cloth_calc_spring_force(clmd, &springs[i], lF, lX, lV, dFdV, dFdX); - // } + // if(((clmd->sim_parms.flags & CSIMSETT_FLAG_TEARING_ENABLED) && !(springs[i].flags & CSPRING_FLAG_DEACTIVATE))|| !(clmd->sim_parms.flags & CSIMSETT_FLAG_TEARING_ENABLED)){} + cloth_calc_spring_force(clmd, search->link, lF, lX, lV, dFdV, dFdX); + + search = search->next; } -#pragma omp for nowait - for(i = cloth->numsprings/2; i < cloth->numsprings; i++) - { - // only handle active springs - // if(((clmd->sim_parms.flags & CSIMSETT_FLAG_TEARING_ENABLED) && !(springs[i].flags & CSPRING_FLAG_DEACTIVATE))|| !(clmd->sim_parms.flags & CSIMSETT_FLAG_TEARING_ENABLED)) - // { - cloth_calc_spring_force(clmd, &springs[i], lF, lX, lV, dFdV, dFdX); - // } - } -} // pragma omp parallel - for(i = 0; i < cloth->numsprings; i++) + // apply spring forces + search = cloth->springs; + while(search) { // only handle active springs - // if(((clmd->sim_parms.flags & CSIMSETT_FLAG_TEARING_ENABLED) && !(springs[i].flags & CSPRING_FLAG_DEACTIVATE))|| !(clmd->sim_parms.flags & CSIMSETT_FLAG_TEARING_ENABLED)) - { - ClothSpring *s = &springs[i]; - if(s->flags & CSPRING_FLAG_NEEDED) - { - if(s->type != BENDING) - { - sub_fmatrix_fmatrix(dFdV[s->ij].m, dFdV[s->ij].m, s->dfdv); - sub_fmatrix_fmatrix(dFdV[s->kl].m, dFdV[s->kl].m, s->dfdv); - add_fmatrix_fmatrix(dFdV[s->matrix_index].m, dFdV[s->matrix_index].m, s->dfdv); - } - - VECADD(lF[s->ij], lF[s->ij], s->f); - VECSUB(lF[s->kl], lF[s->kl], s->f); - - sub_fmatrix_fmatrix(dFdX[s->ij].m, dFdX[s->ij].m, s->dfdx); - sub_fmatrix_fmatrix(dFdX[s->kl].m, dFdX[s->kl].m, s->dfdx); - - add_fmatrix_fmatrix(dFdX[s->matrix_index].m, dFdX[s->matrix_index].m, s->dfdx); - } - } + // if(((clmd->sim_parms.flags & CSIMSETT_FLAG_TEARING_ENABLED) && !(springs[i].flags & CSPRING_FLAG_DEACTIVATE))|| !(clmd->sim_parms.flags & CSIMSETT_FLAG_TEARING_ENABLED)) + cloth_apply_spring_force(clmd, search->link, lF, lX, lV, dFdV, dFdX); + search = search->next; } } @@ -1442,7 +1441,7 @@ int implicit_solver (Object *ob, float frame, ClothModifierData *clmd, ListBase Implicit_Data *id = cloth->implicit; int result = 0; - if(clmd->sim_parms.flags & CSIMSETT_FLAG_GOAL) /* do goal stuff */ + if(clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_GOAL) /* do goal stuff */ { for(i = 0; i < numverts; i++) { @@ -1465,66 +1464,74 @@ int implicit_solver (Object *ob, float frame, ClothModifierData *clmd, ListBase add_lfvector_lfvectorS(id->Xnew, id->X, id->Vnew, dt, numverts); - // collisions - // itstart(); - - // update verts to current positions - for(i = 0; i < numverts; i++) - { - if(clmd->sim_parms.flags & CSIMSETT_FLAG_GOAL) /* do goal stuff */ - { - if(verts [i].goal >= SOFTGOALSNAP) + if(clmd->coll_parms.flags & CLOTH_COLLISIONSETTINGS_FLAG_ENABLED) + { + // collisions + // itstart(); + + // update verts to current positions + for(i = 0; i < numverts; i++) + { + if(clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_GOAL) /* do goal stuff */ { - float tvect[3] = {.0,.0,.0}; - // VECSUB(tvect, id->Xnew[i], verts[i].xold); - mul_fvector_S(tvect, id->V[i], step+dt); - VECADD(tvect, tvect, verts[i].xold); - VECCOPY(id->Xnew[i], tvect); + if(verts [i].goal >= SOFTGOALSNAP) + { + float tvect[3] = {.0,.0,.0}; + // VECSUB(tvect, id->Xnew[i], verts[i].xold); + mul_fvector_S(tvect, id->V[i], step+dt); + VECADD(tvect, tvect, verts[i].xold); + VECCOPY(id->Xnew[i], tvect); + } + } + + VECCOPY(verts[i].tx, id->Xnew[i]); + + VECSUB(verts[i].tv, verts[i].tx, verts[i].txold); + VECCOPY(verts[i].v, verts[i].tv); + } + + // call collision function + result = cloth_bvh_objcollision(clmd, step + dt, dt); + + // copy corrected positions back to simulation + for(i = 0; i < numverts; i++) + { + if(result) + { + // VECADD(verts[i].tx, verts[i].txold, verts[i].tv); + VECCOPY(verts[i].txold, verts[i].tx); + + VECCOPY(id->Xnew[i], verts[i].tx); + + VECCOPY(id->Vnew[i], verts[i].tv); + VecMulf(id->Vnew[i], 1.0f / dt); + } + else + { + VECCOPY(verts[i].txold, id->Xnew[i]); + } } - VECCOPY(verts[i].tx, id->Xnew[i]); + // X = Xnew; + cp_lfvector(id->X, id->Xnew, numverts); - VECSUB(verts[i].tv, verts[i].tx, verts[i].txold); - VECCOPY(verts[i].v, verts[i].tv); - } - - // call collision function - result = cloth_bvh_objcollision(clmd, step + dt, dt); - - // copy corrected positions back to simulation - for(i = 0; i < numverts; i++) - { + // if there were collisions, advance the velocity from v_n+1/2 to v_n+1 if(result) { - // VECADD(verts[i].tx, verts[i].txold, verts[i].tv); + // V = Vnew; + cp_lfvector(id->V, id->Vnew, numverts); - VECCOPY(verts[i].txold, verts[i].tx); - - VECCOPY(id->Xnew[i], verts[i].tx); - - VECCOPY(id->Vnew[i], verts[i].tv); - VecMulf(id->Vnew[i], 1.0f / dt); - } - else - { - VECCOPY(verts[i].txold, id->Xnew[i]); + // calculate + cloth_calc_force(clmd, id->F, id->X, id->V, id->dFdV, id->dFdX, effectors, step); + simulate_implicit_euler(id->Vnew, id->X, id->V, id->F, id->dFdV, id->dFdX, dt / 2.0f, id->A, id->B, id->dV, id->S, id->z, id->olddV, id->P, id->Pinv); } } - - // X = Xnew; - cp_lfvector(id->X, id->Xnew, numverts); - - // if there were collisions, advance the velocity from v_n+1/2 to v_n+1 - if(result) + else { - // V = Vnew; - cp_lfvector(id->V, id->Vnew, numverts); - - // calculate - cloth_calc_force(clmd, id->F, id->X, id->V, id->dFdV, id->dFdX, effectors, step); - simulate_implicit_euler(id->Vnew, id->X, id->V, id->F, id->dFdV, id->dFdX, dt / 2.0f, id->A, id->B, id->dV, id->S, id->z, id->olddV, id->P, id->Pinv); + // X = Xnew; + cp_lfvector(id->X, id->Xnew, numverts); } // itend(); @@ -1540,7 +1547,7 @@ int implicit_solver (Object *ob, float frame, ClothModifierData *clmd, ListBase for(i = 0; i < numverts; i++) { - if(clmd->sim_parms.flags & CSIMSETT_FLAG_GOAL) + if(clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_GOAL) { if(verts [i].goal < SOFTGOALSNAP) { diff --git a/source/blender/blenkernel/intern/kdop.c b/source/blender/blenkernel/intern/kdop.c index 7ce5e6928ea..b487f9a3b26 100644 --- a/source/blender/blenkernel/intern/kdop.c +++ b/source/blender/blenkernel/intern/kdop.c @@ -547,7 +547,7 @@ BVH *bvh_build (ClothModifierData *clmd, float epsilon) Tree *tree=NULL; LinkNode *nlink = NULL; EdgeHash *edgehash = NULL; - ClothSpring *springs = NULL; + LinkNode *springs = NULL; unsigned int numsprings = 0; MFace *mface = NULL; diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c index 5ba3df9a720..c1f097e8447 100644 --- a/source/blender/blenkernel/intern/modifier.c +++ b/source/blender/blenkernel/intern/modifier.c @@ -4907,7 +4907,7 @@ static void clothModifier_updateDepgraph( ClothModifierData *coll_clmd = (ClothModifierData *)modifiers_findByType(ob1, eModifierType_Cloth); if(coll_clmd) { - if (coll_clmd->sim_parms.flags & CSIMSETT_FLAG_COLLOBJ) + if (coll_clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_COLLOBJ) { DagNode *curNode = dag_get_node(forest, ob1); dag_add_relation(forest, curNode, obNode, DAG_RL_DATA_DATA|DAG_RL_OB_DATA); @@ -4915,8 +4915,7 @@ static void clothModifier_updateDepgraph( } } } - } - + } } CustomDataMask clothModifier_requiredDataMask(ModifierData *md) @@ -4925,7 +4924,7 @@ CustomDataMask clothModifier_requiredDataMask(ModifierData *md) CustomDataMask dataMask = 0; /* ask for vertexgroups if we need them */ - if(clmd->sim_parms.flags & CSIMSETT_FLAG_GOAL) + if(clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_GOAL) if (clmd->sim_parms.vgroup_mass > 0) dataMask |= (1 << CD_MDEFORMVERT); @@ -4944,7 +4943,7 @@ static void clothModifier_freeData(ModifierData *md) if (clmd) { - clmd->sim_parms.flags &= ~CSIMSETT_FLAG_CCACHE_PROTECT; + clmd->sim_parms.flags &= ~CLOTH_SIMSETTINGS_FLAG_CCACHE_PROTECT; cloth_free_modifier (clmd); } } diff --git a/source/blender/makesdna/DNA_cloth_types.h b/source/blender/makesdna/DNA_cloth_types.h index 6e986ae0067..7f5527466e4 100644 --- a/source/blender/makesdna/DNA_cloth_types.h +++ b/source/blender/makesdna/DNA_cloth_types.h @@ -40,7 +40,8 @@ * They will assume the position they had prior to pinFrame until unpinFrame * is reached. */ -typedef struct ClothVertex { +typedef struct ClothVertex +{ int flags; /* General flags per vertex. */ float v [3]; /* The velocity of the point. */ float xconst [3]; /* constrained position */ @@ -53,23 +54,26 @@ typedef struct ClothVertex { float goal; /* goal, from SB */ float impulse[3]; /* used in collision.c */ unsigned int impulse_count; /* same as above */ -} ClothVertex; +} +ClothVertex; /** * The definition of a spring. */ -typedef struct ClothSpring { +typedef struct ClothSpring +{ int ij; /* Pij from the paper, one end of the spring. */ int kl; /* Pkl from the paper, one end of the spring. */ float restlen; /* The original length of the spring. */ - int matrix_index; /* needed for implicit */ - int type; + int matrix_index; /* needed for implicit solver (fast lookup) */ + int type; /* types defined in BKE_cloth.h ("springType") */ int flags; /* defined in BKE_cloth.h, e.g. deactivated due to tearing */ float dfdx[3][3]; float dfdv[3][3]; float f[3]; -} ClothSpring; +} +ClothSpring; @@ -84,10 +88,11 @@ typedef struct ClothSpring { * as in stepsPerFrame comapred to the time step in the paper, I've used * variables with different names to minimize confusion. **/ -typedef struct SimulationSettings { +typedef struct SimulationSettings +{ short vgroup_mass; /* optional vertexgroup name for assigning weight. */ short pad; - float mingoal; /* see SB */ + float mingoal; /* see SB */ int preroll; /* How many frames of simulation to do before we start. */ float Cdis; /* Mechanical damping of springs. */ float Cvi; /* Viscous/fluid damping. */ @@ -99,11 +104,11 @@ typedef struct SimulationSettings { float structural; /* Structural spring stiffness. */ float shear; /* Shear spring stiffness. */ float bending; /* Flexion spring stiffness. */ - float sim_time; + float sim_time; int flags; /* flags, see CSIMSETT_FLAGS enum above. */ short solver_type; /* which solver should be used? */ short pad2; - float maxgoal; /* see SB */ + float maxgoal; /* see SB */ float eff_force_scale;/* Scaling of effector forces (see softbody_calc_forces).*/ float eff_wind_scale; /* Scaling of effector wind (see softbody_calc_forces). */ float sim_time_old; @@ -114,17 +119,22 @@ typedef struct SimulationSettings { int maxspringlen; /* in percent!; if tearing enabled, a spring will get cut */ int lastframe; /* frame on which simulation stops */ int firstframe; /* frame on which simulation starts */ -} SimulationSettings; +} +SimulationSettings; -typedef struct CollisionSettings { +typedef struct CollisionSettings +{ float epsilon; /* The radius of a particle in the cloth. */ float self_friction; /* Fiction/damping with self contact. */ float friction; /* Friction/damping applied on contact with other object.*/ short collision_type; /* which collision system is used. */ short loop_count; /* How many iterations for the collision loop. */ struct LinkNode *collision_list; /* e.g. pointer to temp memory for collisions */ -} CollisionSettings; + int flags; /* collision flags defined in BKE_cloth.h */ + int pad; +} +CollisionSettings; /** @@ -137,21 +147,20 @@ typedef struct CollisionSettings { * own connectivity of the mesh based on the actual edges in the mesh. * **/ -typedef struct Cloth { - struct ClothVertex *verts; /* The vertices that represent this cloth. */ - struct ClothSpring *springs; /* The springs connecting the mesh. */ - unsigned int numverts; /* The number of verts == m * n. */ - unsigned int numsprings; /* The count of springs. */ - unsigned char *facemarks; - char old_solver_type; /* Needed to allow call to free if solver changes. */ - char old_collision_type; /* Needed to allow call to free if collision changes.*/ - short pad7; +typedef struct Cloth +{ + struct ClothVertex *verts; /* The vertices that represent this cloth. */ + struct LinkNode *springs; /* The springs connecting the mesh. */ + unsigned int numverts; /* The number of verts == m * n. */ + unsigned int numsprings; /* The count of springs. */ unsigned int numfaces; - int pad2; - int pad4; + unsigned char old_solver_type; + unsigned char pad2; + short pad3; void *tree; /* collision tree for this cloth object */ struct MFace *mfaces; void *implicit; /* our implicit solver connects to this pointer */ -} Cloth; +} +Cloth; #endif diff --git a/source/blender/src/buttons_object.c b/source/blender/src/buttons_object.c index c0925f4eae1..10d4d544e86 100644 --- a/source/blender/src/buttons_object.c +++ b/source/blender/src/buttons_object.c @@ -3111,9 +3111,9 @@ static void object_panel_cloth(Object *ob) if(clmd) { - but = uiDefButBitI(block, TOG, CSIMSETT_FLAG_COLLOBJ, B_EFFECT_DEP, "Collision Object", 170,200,130,20, &clmd->sim_parms.flags, 0, 0, 0, 0, "Sets object to become a cloth collision object"); + but = uiDefButBitI(block, TOG, CLOTH_SIMSETTINGS_FLAG_COLLOBJ, B_EFFECT_DEP, "Collision Object", 170,200,130,20, &clmd->sim_parms.flags, 0, 0, 0, 0, "Sets object to become a cloth collision object"); - if (!(clmd->sim_parms.flags & CSIMSETT_FLAG_COLLOBJ)) + if (!(clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_COLLOBJ)) { Cloth *cloth = clmd->clothObject; int defCount; @@ -3149,8 +3149,8 @@ static void object_panel_cloth(Object *ob) /* GOAL STUFF */ uiBlockBeginAlign(block); - uiDefButBitI(block, TOG, CSIMSETT_FLAG_GOAL, REDRAWVIEW3D, "Use Goal", 10,70,130,20, &clmd->sim_parms.flags, 0, 0, 0, 0, "Define forces for vertices to stick to animated position"); - if (clmd->sim_parms.flags & CSIMSETT_FLAG_GOAL) + uiDefButBitI(block, TOG, CLOTH_SIMSETTINGS_FLAG_GOAL, REDRAWVIEW3D, "Use Goal", 10,70,130,20, &clmd->sim_parms.flags, 0, 0, 0, 0, "Define forces for vertices to stick to animated position"); + if (clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_GOAL) { if(ob->type==OB_MESH) { @@ -3228,7 +3228,7 @@ static void object_panel_cloth_II(Object *ob) clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth); if(clmd) { - if (!(clmd->sim_parms.flags & CSIMSETT_FLAG_COLLOBJ)) + if (!(clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_COLLOBJ)) { Cloth *cloth = clmd->clothObject; char str[128]; @@ -3266,7 +3266,7 @@ static void object_panel_cloth_II(Object *ob) { uiDefBut(block, LABEL, 0, "No frames cached.", 10,120,290,20, NULL, 0.0, 0, 0, 0, ""); } - uiDefButBitI(block, TOG, CSIMSETT_FLAG_CCACHE_PROTECT, REDRAWVIEW3D, "Protect Cache", 10,50,145,20, &clmd->sim_parms.flags, 0, 0, 0, 0, "Protect cache from automatic freeing when scene changed"); + uiDefButBitI(block, TOG, CLOTH_SIMSETTINGS_FLAG_CCACHE_PROTECT, REDRAWVIEW3D, "Protect Cache", 10,50,145,20, &clmd->sim_parms.flags, 0, 0, 0, 0, "Protect cache from automatic freeing when scene changed"); uiBlockEndAlign(block); } } @@ -3283,7 +3283,7 @@ static void object_panel_cloth_III(Object *ob) clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth); if(clmd) { - if (!(clmd->sim_parms.flags & CSIMSETT_FLAG_COLLOBJ)) + if (!(clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_COLLOBJ)) { Cloth *cloth = clmd->clothObject; char str[128]; @@ -3295,9 +3295,15 @@ static void object_panel_cloth_III(Object *ob) uiSetButLock(object_data_is_libdata(ob), ERROR_LIBDATA_MESSAGE); uiBlockBeginAlign(block); - // uiDefBut(block, LABEL, 0, "",10,10,300,20, NULL, 0.0, 0, 0, 0, ""); /* tell UI we go to 10,10*/ - uiDefButF(block, NUM, B_CLOTH_RENEW, "Min Distance:", 10,10,150,20, &clmd->coll_parms.epsilon, 0.001f, 1.0, 0.01f, 0, "Minimum distance between collision objects before collision response takes in"); - uiDefBut(block, LABEL, 0, "",160,10,150,20, NULL, 0.0, 0, 0, 0, ""); + uiDefButBitI(block, TOG, CLOTH_COLLISIONSETTINGS_FLAG_ENABLED, REDRAWVIEW3D, "Enable collisions", 10,70,130,20, &clmd->coll_parms.flags, 0, 0, 0, 0, "Enable collisions with this object"); + if (clmd->coll_parms.flags & CLOTH_COLLISIONSETTINGS_FLAG_ENABLED) + { + // uiDefBut(block, LABEL, 0, "",10,10,300,20, NULL, 0.0, 0, 0, 0, ""); /* tell UI we go to 10,10*/ + uiDefButF(block, NUM, B_CLOTH_RENEW, "Min Distance:", 10,30,150,20, &clmd->coll_parms.epsilon, 0.001f, 1.0, 0.01f, 0, "Minimum distance between collision objects before collision response takes in"); + uiDefBut(block, LABEL, 0, "",160,30,150,20, NULL, 0.0, 0, 0, 0, ""); + } + else + uiDefBut(block, LABEL, 0, "",140,10,170,20, NULL, 0.0, 0, 0, 0, ""); uiBlockEndAlign(block); } } From 8dbc71020c9217af659874240d730ce58305bad6 Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Sun, 21 Oct 2007 16:38:13 +0000 Subject: [PATCH 028/246] Disabled Cloth collision detection because of almost complete rewrite/seperation of the collision system like we discussed on the sprint. You can enable position caching/collision object now then enableing it as an deflection object. Problem: Some GUI glitch in the modifier stack, please help :) --- source/blender/blenkernel/BKE_cloth.h | 64 +--- source/blender/blenkernel/intern/cloth.c | 25 +- source/blender/blenkernel/intern/collision.c | 365 +++++++++---------- source/blender/blenkernel/intern/implicit.c | 2 +- source/blender/blenkernel/intern/kdop.c | 185 ++++------ source/blender/blenkernel/intern/modifier.c | 122 ++++++- source/blender/makesdna/DNA_cloth_types.h | 1 - source/blender/makesdna/DNA_modifier_types.h | 12 + source/blender/src/buttons_editing.c | 24 +- source/blender/src/buttons_object.c | 24 +- source/blender/src/transform_generics.c | 8 +- 11 files changed, 426 insertions(+), 406 deletions(-) diff --git a/source/blender/blenkernel/BKE_cloth.h b/source/blender/blenkernel/BKE_cloth.h index 692692dbf5a..1c5310c10d1 100644 --- a/source/blender/blenkernel/BKE_cloth.h +++ b/source/blender/blenkernel/BKE_cloth.h @@ -124,68 +124,8 @@ void implicit_set_positions ( ClothModifierData *clmd ); // from cloth.c, needed for modifier.c void clothModifier_do ( ClothModifierData *clmd, Object *ob, DerivedMesh *dm, float ( *vertexCos ) [3], int numverts ); -// used in collision.c -typedef struct Tree -{ - struct Tree *nodes[4]; // 4 children --> quad-tree - struct Tree *parent; - struct Tree *nextLeaf; - struct Tree *prevLeaf; - float bv[26]; // Bounding volume of all nodes / we have 7 axes on a 14-DOP - unsigned int tri_index; // this saves the index of the face - int count_nodes; // how many nodes are used - int traversed; // how many nodes already traversed until this level? - int isleaf; -} -Tree; - -typedef struct Tree TreeNode; - -typedef struct BVH -{ - unsigned int numfaces; - unsigned int numverts; - ClothVertex *verts; // just a pointer to the original datastructure - MFace *mfaces; // just a pointer to the original datastructure - struct LinkNode *tree; - TreeNode *root; // TODO: saving the root --> is this really needed? YES! - TreeNode *leaf_tree; /* Tail of the leaf linked list. */ - TreeNode *leaf_root; /* Head of the leaf linked list. */ - float epsilon; /* epslion is used for inflation of the k-dop */ - int flags; /* bvhFlags */ -} -BVH; - -typedef void ( *CM_COLLISION_RESPONSE ) ( ClothModifierData *clmd, ClothModifierData *coll_clmd, Tree * tree1, Tree * tree2 ); - - -///////////////////////////////////////////////// -// collision.c //////////////////////////////////////////////// -// needed for implicit.c -void bvh_collision_response ( ClothModifierData *clmd, ClothModifierData *coll_clmd, Tree * tree1, Tree * tree2 ); -int cloth_bvh_objcollision ( ClothModifierData * clmd, float step, float dt ); - -//////////////////////////////////////////////// - - -///////////////////////////////////////////////// -// kdop.c -//////////////////////////////////////////////// - -// needed for cloth.c -void bvh_free ( BVH * bvh ); -BVH *bvh_build ( ClothModifierData *clmd, float epsilon ); -LinkNode *BLI_linklist_append_fast ( LinkNode **listp, void *ptr ); - -// needed for collision.c -int bvh_traverse ( ClothModifierData * clmd, ClothModifierData * coll_clmd, Tree * tree1, Tree * tree2, float step, CM_COLLISION_RESPONSE collision_response ); -void bvh_update ( ClothModifierData * clmd, BVH * bvh, int moving ); - -//////////////////////////////////////////////// - - ///////////////////////////////////////////////// // cloth.c @@ -200,7 +140,7 @@ void cloth_update_normals ( ClothVertex *verts, int nVerts, MFace *face, int tot /* Typedefs for function pointers we need for solvers and collision detection. */ typedef void ( *CM_COLLISION_SELF ) ( ClothModifierData *clmd, int step ); -typedef void ( *CM_COLLISION_OBJ ) ( ClothModifierData *clmd, int step, CM_COLLISION_RESPONSE collision_response ); +// typedef void ( *CM_COLLISION_OBJ ) ( ClothModifierData *clmd, int step, CM_COLLISION_RESPONSE collision_response ); /* This enum provides the IDs for our solvers. */ @@ -239,6 +179,7 @@ typedef struct Frame Frame; /* used for collisions in collision.c */ +/* typedef struct CollPair { unsigned int face1; // cloth face @@ -253,6 +194,7 @@ typedef struct CollPair unsigned int pointsb[4]; } CollPair; +*/ /* used for collisions in collision.c */ typedef struct EdgeCollPair diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c index eb7454ccd42..d83c7bcb7f0 100644 --- a/source/blender/blenkernel/intern/cloth.c +++ b/source/blender/blenkernel/intern/cloth.c @@ -65,6 +65,7 @@ #include "BKE_mesh.h" #include "BKE_object.h" #include "BKE_cloth.h" +#include "BKE_collisions.h" #include "BKE_modifier.h" #include "BKE_utildefines.h" #include "BKE_DerivedMesh.h" @@ -845,11 +846,11 @@ void cloth_free_modifier ( ClothModifierData *clmd ) cloth->springs = NULL; cloth->numsprings = 0; - +/* // free BVH collision tree if ( cloth->tree ) bvh_free ( ( BVH * ) cloth->tree ); - +*/ // we save our faces for collision objects if ( cloth->mfaces ) MEM_freeN ( cloth->mfaces ); @@ -1011,7 +1012,7 @@ static int collobj_from_object ( Object *ob, ClothModifierData *clmd, DerivedMes verts->impulse_count = 0; VECCOPY ( verts->impulse, tnull ); } - clmd->clothObject->tree = bvh_build ( clmd,clmd->coll_parms.epsilon ); + // clmd->clothObject->tree = bvh_build ( dm, clmd->coll_parms.epsilon ); } @@ -1020,20 +1021,6 @@ static int collobj_from_object ( Object *ob, ClothModifierData *clmd, DerivedMes } } -/* -helper function to get proper spring length -when object is rescaled -*/ -float cloth_globallen ( float *v1,float *v2,Object *ob ) -{ - float p1[3],p2[3]; - VECCOPY ( p1,v1 ); - Mat4MulVecfl ( ob->obmat, p1 ); - VECCOPY ( p2,v2 ); - Mat4MulVecfl ( ob->obmat, p2 ); - return VecLenf ( p1,p2 ); -} - // only meshes supported at the moment static int cloth_from_object ( Object *ob, ClothModifierData *clmd, DerivedMesh *dm, float ( *vertexCos ) [3], unsigned int numverts ) { @@ -1082,7 +1069,7 @@ static int cloth_from_object ( Object *ob, ClothModifierData *clmd, DerivedMesh return 0; } - mvert = CDDM_get_verts ( dm ); + mvert = dm->getVertArray ( dm ); // CDDM_get_verts ( dm ); verts = clmd->clothObject->verts; /* set initial values */ @@ -1116,7 +1103,7 @@ static int cloth_from_object ( Object *ob, ClothModifierData *clmd, DerivedMesh if ( solvers [clmd->sim_parms.solver_type].init ) solvers [clmd->sim_parms.solver_type].init ( ob, clmd ); - clmd->clothObject->tree = bvh_build ( clmd, clmd->coll_parms.epsilon ); + // clmd->clothObject->tree = bvh_build ( dm, clmd->coll_parms.epsilon ); cloth_cache_set_frame ( clmd, 1 ); } diff --git a/source/blender/blenkernel/intern/collision.c b/source/blender/blenkernel/intern/collision.c index a5a382f7624..41823b0ad39 100644 --- a/source/blender/blenkernel/intern/collision.c +++ b/source/blender/blenkernel/intern/collision.c @@ -49,6 +49,7 @@ #include "BLI_arithb.h" #include "BLI_edgehash.h" #include "BLI_linklist.h" +#include "BKE_collisions.h" #include "BKE_curve.h" #include "BKE_deform.h" #include "BKE_DerivedMesh.h" @@ -217,7 +218,7 @@ int gsl_poly_solve_quadratic (float a, float b, float c, float *x0, float *x1) * page 4, left column */ -int cloth_get_collision_time(float a[3], float b[3], float c[3], float d[3], float e[3], float f[3], float solution[3]) +int collisions_get_collision_time(float a[3], float b[3], float c[3], float d[3], float e[3], float f[3], float solution[3]) { int num_sols = 0; @@ -318,7 +319,7 @@ int cloth_get_collision_time(float a[3], float b[3], float c[3], float d[3], flo } // w3 is not perfect -void cloth_compute_barycentric (float pv[3], float p1[3], float p2[3], float p3[3], float *w1, float *w2, float *w3) +void collisions_compute_barycentric (float pv[3], float p1[3], float p2[3], float p3[3], float *w1, float *w2, float *w3) { double tempV1[3], tempV2[3], tempV4[3]; double a,b,c,d,e,f; @@ -372,8 +373,9 @@ DO_INLINE void calculateFrictionImpulse(float to[3], float vrel[3], float normal VecMulf(to, MAX2(1.0f - frictionConstant * delta_V_n / INPR(vrel_t_pre,vrel_t_pre), 0.0f)); } -int cloth_collision_response_static(ClothModifierData *clmd, ClothModifierData *coll_clmd) +int collisions_collision_response_static(ClothModifierData *clmd, ClothModifierData *coll_clmd) { + /* unsigned int i = 0; int result = 0; LinkNode *search = NULL; @@ -386,20 +388,20 @@ int cloth_collision_response_static(ClothModifierData *clmd, ClothModifierData * cloth1 = clmd->clothObject; cloth2 = coll_clmd->clothObject; - search = clmd->coll_parms.collision_list; + // search = clmd->coll_parms.collision_list; while(search) { collpair = search->link; // compute barycentric coordinates for both collision points - cloth_compute_barycentric(collpair->pa, + collisions_compute_barycentric(collpair->pa, cloth1->verts[collpair->ap1].txold, cloth1->verts[collpair->ap2].txold, cloth1->verts[collpair->ap3].txold, &w1, &w2, &w3); - cloth_compute_barycentric(collpair->pb, + collisions_compute_barycentric(collpair->pb, cloth2->verts[collpair->bp1].txold, cloth2->verts[collpair->bp2].txold, cloth2->verts[collpair->bp3].txold, @@ -442,12 +444,6 @@ int cloth_collision_response_static(ClothModifierData *clmd, ClothModifierData * // printf("friction applied: %f\n", magtangent); // TODO check original code - /* - VECSUB(cloth1->verts[face1->v1].tv, cloth1->verts[face1->v1].tv,tangential); - VECSUB(cloth1->verts[face1->v1].tv, cloth1->verts[face1->v2].tv,tangential); - VECSUB(cloth1->verts[face1->v1].tv, cloth1->verts[face1->v3].tv,tangential); - VECSUB(cloth1->verts[face1->v1].tv, cloth1->verts[face1->v4].tv,tangential); - */ } @@ -455,6 +451,7 @@ int cloth_collision_response_static(ClothModifierData *clmd, ClothModifierData * // printf("impulse: %f\n", impulse); + // face A VECADDMUL(cloth1->verts[collpair->ap1].impulse, collpair->normal, w1 * impulse); cloth1->verts[collpair->ap1].impulse_count++; @@ -464,63 +461,50 @@ int cloth_collision_response_static(ClothModifierData *clmd, ClothModifierData * VECADDMUL(cloth1->verts[collpair->ap3].impulse, collpair->normal, w3 * impulse); cloth1->verts[collpair->ap3].impulse_count++; - result = 1; + // face B + VECADDMUL(cloth2->verts[collpair->bp1].impulse, collpair->normal, u1 * impulse); + cloth2->verts[collpair->bp1].impulse_count++; - /* - if (overlap > ALMOST_ZERO) { - double I_mag = overlap * 0.1; - - impulse = -I_mag / ( 1.0 + w1*w1 + w2*w2 + w3*w3); - - VECADDMUL(cloth1->verts[collpair->ap1].impulse, collpair->normal, w1 * impulse); - cloth1->verts[collpair->ap1].impulse_count++; - - VECADDMUL(cloth1->verts[collpair->ap2].impulse, collpair->normal, w2 * impulse); - cloth1->verts[collpair->ap2].impulse_count++; + VECADDMUL(cloth2->verts[collpair->bp2].impulse, collpair->normal, u2 * impulse); + cloth2->verts[collpair->bp2].impulse_count++; - VECADDMUL(cloth1->verts[collpair->ap3].impulse, collpair->normal, w3 * impulse); - cloth1->verts[collpair->ap3].impulse_count++; - } - */ + VECADDMUL(cloth2->verts[collpair->bp3].impulse, collpair->normal, u3 * impulse); + cloth2->verts[collpair->bp3].impulse_count++; + + + result = 1; // printf("magnitude_i: %f\n", magnitude_i); // negative before collision in my case // Apply the impulse and increase impulse counters. - - /* - // calculateFrictionImpulse(tangential, collvel, collpair->normal, magtangent, clmd->coll_parms.friction*0.01, magtangent); - VECSUBS(vrel_t_pre, collvel, collpair->normal, magnormal); - // VecMulf(vrel_t_pre, clmd->coll_parms.friction*0.01f/INPR(vrel_t_pre,vrel_t_pre)); - magtangent = Normalize(vrel_t_pre); - VecMulf(vrel_t_pre, MIN2(clmd->coll_parms.friction*0.01f*magnormal,magtangent)); - - VECSUB(cloth1->verts[face1->v1].tv, cloth1->verts[face1->v1].tv,vrel_t_pre); - */ - - + } search = search->next; } - + return result; + */ + return 0; } -int cloth_collision_response_moving_tris(ClothModifierData *clmd, ClothModifierData *coll_clmd) + +int collisions_collision_response_moving_tris(ClothModifierData *clmd, ClothModifierData *coll_clmd) { } -int cloth_collision_response_moving_edges(ClothModifierData *clmd, ClothModifierData *coll_clmd) +int collisions_collision_response_moving_edges(ClothModifierData *clmd, ClothModifierData *coll_clmd) { } void cloth_collision_static(ClothModifierData *clmd, ClothModifierData *coll_clmd, Tree *tree1, Tree *tree2) { + /* CollPair *collpair = NULL; Cloth *cloth1=NULL, *cloth2=NULL; MFace *face1=NULL, *face2=NULL; @@ -618,11 +602,11 @@ void cloth_collision_static(ClothModifierData *clmd, ClothModifierData *coll_clm // collpair->face1 = tree1->tri_index; // collpair->face2 = tree2->tri_index; - VECCOPY(collpair->normal, collpair->vector); - Normalize(collpair->normal); + // VECCOPY(collpair->normal, collpair->vector); + // Normalize(collpair->normal); + + // collpair->distance = distance; - collpair->distance = distance; - BLI_linklist_append(&clmd->coll_parms.collision_list, collpair); } else { @@ -634,9 +618,10 @@ void cloth_collision_static(ClothModifierData *clmd, ClothModifierData *coll_clm MEM_freeN(collpair); } } + */ } -int cloth_are_edges_adjacent(ClothModifierData *clmd, ClothModifierData *coll_clmd, EdgeCollPair *edgecollpair) +int collisions_are_edges_adjacent(ClothModifierData *clmd, ClothModifierData *coll_clmd, EdgeCollPair *edgecollpair) { Cloth *cloth1, *cloth2; ClothVertex *verts1, *verts2; @@ -667,7 +652,7 @@ int cloth_are_edges_adjacent(ClothModifierData *clmd, ClothModifierData *coll_cl return 0; } -void cloth_collision_moving_edges(ClothModifierData *clmd, ClothModifierData *coll_clmd, Tree *tree1, Tree *tree2) +void collisions_collision_moving_edges(ClothModifierData *clmd, ClothModifierData *coll_clmd, Tree *tree1, Tree *tree2) { EdgeCollPair edgecollpair; Cloth *cloth1=NULL, *cloth2=NULL; @@ -773,7 +758,7 @@ void cloth_collision_moving_edges(ClothModifierData *clmd, ClothModifierData *co } - if(!cloth_are_edges_adjacent(clmd, coll_clmd, &edgecollpair)) + if(!collisions_are_edges_adjacent(clmd, coll_clmd, &edgecollpair)) { VECSUB(a, verts1[edgecollpair.p12].xold, verts1[edgecollpair.p11].xold); VECSUB(b, verts1[edgecollpair.p12].v, verts1[edgecollpair.p11].v); @@ -782,7 +767,7 @@ void cloth_collision_moving_edges(ClothModifierData *clmd, ClothModifierData *co VECSUB(e, verts2[edgecollpair.p22].xold, verts1[edgecollpair.p11].xold); VECSUB(f, verts2[edgecollpair.p22].v, verts1[edgecollpair.p11].v); - numsolutions = cloth_get_collision_time(a, b, c, d, e, f, solution); + numsolutions = collisions_get_collision_time(a, b, c, d, e, f, solution); for (k = 0; k < numsolutions; k++) { @@ -802,8 +787,9 @@ void cloth_collision_moving_edges(ClothModifierData *clmd, ClothModifierData *co } } -void cloth_collision_moving_tris(ClothModifierData *clmd, ClothModifierData *coll_clmd, Tree *tree1, Tree *tree2) +void collisions_collision_moving_tris(ClothModifierData *clmd, ClothModifierData *coll_clmd, Tree *tree1, Tree *tree2) { + /* CollPair collpair; Cloth *cloth1=NULL, *cloth2=NULL; MFace *face1=NULL, *face2=NULL; @@ -872,7 +858,7 @@ void cloth_collision_moving_tris(ClothModifierData *clmd, ClothModifierData *col VECSUB(e, verts2[collpair.pointsb[j]].xold, verts1[collpair.ap1].xold); VECSUB(f, verts2[collpair.pointsb[j]].v, verts1[collpair.ap1].v); - numsolutions = cloth_get_collision_time(a, b, c, d, e, f, solution); + numsolutions = collisions_get_collision_time(a, b, c, d, e, f, solution); for (k = 0; k < numsolutions; k++) { @@ -894,19 +880,22 @@ void cloth_collision_moving_tris(ClothModifierData *clmd, ClothModifierData *col } } + */ } -void cloth_collision_moving(ClothModifierData *clmd, ClothModifierData *coll_clmd, Tree *tree1, Tree *tree2) +void collisions_collision_moving(ClothModifierData *clmd, ClothModifierData *coll_clmd, Tree *tree1, Tree *tree2) { + /* // TODO: check for adjacent - cloth_collision_moving_edges(clmd, coll_clmd, tree1, tree2); + collisions_collision_moving_edges(clmd, coll_clmd, tree1, tree2); - cloth_collision_moving_tris(clmd, coll_clmd, tree1, tree2); - cloth_collision_moving_tris(coll_clmd, clmd, tree2, tree1); + collisions_collision_moving_tris(clmd, coll_clmd, tree1, tree2); + collisions_collision_moving_tris(coll_clmd, clmd, tree2, tree1); + */ } // move collision objects forward in time and update static bounding boxes -void cloth_update_collision_objects(float step) +void collisions_update_collision_objects(float step) { Base *base=NULL; ClothModifierData *coll_clmd=NULL; @@ -943,15 +932,15 @@ void cloth_update_collision_objects(float step) } // update BVH of collision object - bvh_update(coll_clmd, coll_bvh, 0); // 0 means STATIC, 1 means MOVING + // bvh_update(coll_clmd, coll_bvh, 0); // 0 means STATIC, 1 means MOVING } else - printf ("cloth_bvh_objcollision: found a collision object with clothObject or collData NULL.\n"); + printf ("collisions_bvh_objcollision: found a collision object with clothObject or collData NULL.\n"); } } } -// CLOTH_MAX_THRESHOLD defines how much collision rounds/loops should be taken +// collisions_MAX_THRESHOLD defines how much collision rounds/loops should be taken #define CLOTH_MAX_THRESHOLD 10 // cloth - object collisions @@ -961,12 +950,13 @@ int cloth_bvh_objcollision(ClothModifierData * clmd, float step, float dt) ClothModifierData *coll_clmd=NULL; Cloth *cloth=NULL; Object *coll_ob=NULL; - BVH *cloth_bvh=NULL; + BVH *collisions_bvh=NULL; unsigned int i=0, j = 0, numfaces = 0, numverts = 0; unsigned int result = 0, ic = 0, rounds = 0; // result counts applied collisions; ic is for debug output; ClothVertex *verts = NULL; float tnull[3] = {0,0,0}; int ret = 0; + LinkNode *collision_list = NULL; if ((clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_COLLOBJ) || !(((Cloth *)clmd->clothObject)->tree)) { @@ -974,7 +964,7 @@ int cloth_bvh_objcollision(ClothModifierData * clmd, float step, float dt) } cloth = clmd->clothObject; verts = cloth->verts; - cloth_bvh = (BVH *) cloth->tree; + collisions_bvh = (BVH *) cloth->tree; numfaces = clmd->clothObject->numfaces; numverts = clmd->clothObject->numverts; @@ -983,16 +973,15 @@ int cloth_bvh_objcollision(ClothModifierData * clmd, float step, float dt) //////////////////////////////////////////////////////////// // update cloth bvh - bvh_update(clmd, cloth_bvh, 0); // 0 means STATIC, 1 means MOVING (see later in this function) + // bvh_update(clmd, collisions_bvh, 0); // 0 means STATIC, 1 means MOVING (see later in this function) // update collision objects - cloth_update_collision_objects(step); + collisions_update_collision_objects(step); do { result = 0; ic = 0; - clmd->coll_parms.collision_list = NULL; // check all collision objects for (base = G.scene->base.first; base; base = base->next) @@ -1010,71 +999,57 @@ int cloth_bvh_objcollision(ClothModifierData * clmd, float step, float dt) { BVH *coll_bvh = coll_clmd->clothObject->tree; - bvh_traverse(clmd, coll_clmd, cloth_bvh->root, coll_bvh->root, step, cloth_collision_static); + // fill collision list + bvh_traverse(collisions_bvh->root, coll_bvh->root, collision_list); + + // process all collisions (calculate impulses, TODO: also repulses if distance too short) + result = 1; + for(j = 0; j < 10; j++) // 10 is just a value that ensures convergence + { + result = 0; + + // result += collisions_collision_response_static_tris(clmd, coll_clmd, collision_list, 0); + + // result += collisions_collision_response_static_tris(coll_clmd, clmd, collision_list, 1); + + // apply impulses in parallel + ic=0; + for(i = 0; i < numverts; i++) + { + // calculate "velocities" (just xnew = xold + v; no dt in v) + if(verts[i].impulse_count) + { + VECADDMUL(verts[i].tv, verts[i].impulse, 1.0f / verts[i].impulse_count); + VECCOPY(verts[i].impulse, tnull); + verts[i].impulse_count = 0; + + ic++; + ret++; + } + } + } + + // free collision list + if(collision_list) + { + LinkNode *search = collision_list; + while(search) + { + CollisionPair *coll_pair = search->link; + + MEM_freeN(coll_pair); + search = search->next; + } + BLI_linklist_free(collision_list,NULL); + + collision_list = NULL; + } } else - printf ("cloth_bvh_objcollision: found a collision object with clothObject or collData NULL.\n"); + printf ("collisions_bvh_objcollision: found a collision object with clothObject or collData NULL.\n"); } } - // process all collisions (calculate impulses, TODO: also repulses if distance too short) - result = 1; - for(j = 0; j < 10; j++) // 10 is just a value that ensures convergence - { - result = 0; - - // handle all collision objects - for (base = G.scene->base.first; base; base = base->next) - { - - coll_ob = base->object; - coll_clmd = (ClothModifierData *) modifiers_findByType (coll_ob, eModifierType_Cloth); - if (!coll_clmd) - continue; - - // if collision object go on - if (coll_clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_COLLOBJ) - { - if (coll_clmd->clothObject) - result += cloth_collision_response_static(clmd, coll_clmd); - else - printf ("cloth_bvh_objcollision: found a collision object with clothObject or collData NULL.\n"); - } - } - - // apply impulses in parallel - ic=0; - for(i = 0; i < numverts; i++) - { - // calculate "velocities" (just xnew = xold + v; no dt in v) - if(verts[i].impulse_count) - { - VECADDMUL(verts[i].tv, verts[i].impulse, 1.0f / verts[i].impulse_count); - VECCOPY(verts[i].impulse, tnull); - verts[i].impulse_count = 0; - - ic++; - ret++; - } - } - } - - // free collision list - if(clmd->coll_parms.collision_list) - { - LinkNode *search = clmd->coll_parms.collision_list; - while(search) - { - CollPair *coll_pair = search->link; - - MEM_freeN(coll_pair); - search = search->next; - } - BLI_linklist_free(clmd->coll_parms.collision_list,NULL); - - clmd->coll_parms.collision_list = NULL; - } - printf("ic: %d\n", ic); rounds++; } @@ -1100,7 +1075,7 @@ int cloth_bvh_objcollision(ClothModifierData * clmd, float step, float dt) // update cloth bvh - bvh_update(clmd, cloth_bvh, 1); // 0 means STATIC, 1 means MOVING + // bvh_update(clmd, collisions_bvh, 1); // 0 means STATIC, 1 means MOVING // update moving bvh for collision object once for (base = G.scene->base.first; base; base = base->next) @@ -1119,7 +1094,7 @@ int cloth_bvh_objcollision(ClothModifierData * clmd, float step, float dt) { BVH *coll_bvh = coll_clmd->clothObject->tree; - bvh_update(coll_clmd, coll_bvh, 1); // 0 means STATIC, 1 means MOVING + // bvh_update(coll_clmd, coll_bvh, 1); // 0 means STATIC, 1 means MOVING } } @@ -1128,7 +1103,6 @@ int cloth_bvh_objcollision(ClothModifierData * clmd, float step, float dt) { result = 0; ic = 0; - clmd->coll_parms.collision_list = NULL; // check all collision objects for (base = G.scene->base.first; base; base = base->next) @@ -1146,83 +1120,72 @@ int cloth_bvh_objcollision(ClothModifierData * clmd, float step, float dt) { BVH *coll_bvh = coll_clmd->clothObject->tree; - bvh_traverse(clmd, coll_clmd, cloth_bvh->root, coll_bvh->root, step, cloth_collision_moving); + bvh_traverse(collisions_bvh->root, coll_bvh->root, collision_list); + + // process all collisions (calculate impulses, TODO: also repulses if distance too short) + result = 1; + for(j = 0; j < 10; j++) // 10 is just a value that ensures convergence + { + result = 0; + + // handle all collision objects + + /* + if (coll_clmd->clothObject) + result += collisions_collision_response_moving_tris(clmd, coll_clmd); + else + printf ("collisions_bvh_objcollision: found a collision object with clothObject or collData NULL.\n"); + */ + + // apply impulses in parallel + ic=0; + for(i = 0; i < numverts; i++) + { + // calculate "velocities" (just xnew = xold + v; no dt in v) + if(verts[i].impulse_count) + { + VECADDMUL(verts[i].tv, verts[i].impulse, 1.0f / verts[i].impulse_count); + VECCOPY(verts[i].impulse, tnull); + verts[i].impulse_count = 0; + + ic++; + ret++; + } + } + } + + + // verts come from clmd + for(i = 0; i < numverts; i++) + { + VECADD(verts[i].tx, verts[i].txold, verts[i].tv); + } + + // update cloth bvh + // bvh_update(clmd, collisions_bvh, 1); // 0 means STATIC, 1 means MOVING + + + // free collision list + if(collision_list) + { + LinkNode *search = collision_list; + while(search) + { + CollisionPair *coll_pair = search->link; + + MEM_freeN(coll_pair); + search = search->next; + } + BLI_linklist_free(collision_list,NULL); + + collision_list = NULL; + } } else - printf ("cloth_bvh_objcollision: found a collision object with clothObject or collData NULL.\n"); + printf ("collisions_bvh_objcollision: found a collision object with clothObject or collData NULL.\n"); } } - - // process all collisions (calculate impulses, TODO: also repulses if distance too short) - result = 1; - for(j = 0; j < 10; j++) // 10 is just a value that ensures convergence - { - result = 0; - // handle all collision objects - for (base = G.scene->base.first; base; base = base->next) - { - - coll_ob = base->object; - coll_clmd = (ClothModifierData *) modifiers_findByType (coll_ob, eModifierType_Cloth); - - if (!coll_clmd) - continue; - - // if collision object go on - if (coll_clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_COLLOBJ) - { - if (coll_clmd->clothObject) - result += cloth_collision_response_moving_tris(clmd, coll_clmd); - else - printf ("cloth_bvh_objcollision: found a collision object with clothObject or collData NULL.\n"); - } - } - - // apply impulses in parallel - ic=0; - for(i = 0; i < numverts; i++) - { - // calculate "velocities" (just xnew = xold + v; no dt in v) - if(verts[i].impulse_count) - { - VECADDMUL(verts[i].tv, verts[i].impulse, 1.0f / verts[i].impulse_count); - VECCOPY(verts[i].impulse, tnull); - verts[i].impulse_count = 0; - - ic++; - ret++; - } - } - } - - - // verts come from clmd - for(i = 0; i < numverts; i++) - { - VECADD(verts[i].tx, verts[i].txold, verts[i].tv); - } - - // update cloth bvh - bvh_update(clmd, cloth_bvh, 1); // 0 means STATIC, 1 means MOVING - - - // free collision list - if(clmd->coll_parms.collision_list) - { - LinkNode *search = clmd->coll_parms.collision_list; - while(search) - { - CollPair *coll_pair = search->link; - - MEM_freeN(coll_pair); - search = search->next; - } - BLI_linklist_free(clmd->coll_parms.collision_list,NULL); - - clmd->coll_parms.collision_list = NULL; - } - printf("ic: %d\n", ic); rounds++; } diff --git a/source/blender/blenkernel/intern/implicit.c b/source/blender/blenkernel/intern/implicit.c index 1ee4475a6cc..2ce00d0e38c 100644 --- a/source/blender/blenkernel/intern/implicit.c +++ b/source/blender/blenkernel/intern/implicit.c @@ -1492,7 +1492,7 @@ int implicit_solver (Object *ob, float frame, ClothModifierData *clmd, ListBase } // call collision function - result = cloth_bvh_objcollision(clmd, step + dt, dt); + result = 0; // cloth_bvh_objcollision(clmd, step + dt, dt); // copy corrected positions back to simulation for(i = 0; i < numverts; i++) diff --git a/source/blender/blenkernel/intern/kdop.c b/source/blender/blenkernel/intern/kdop.c index b487f9a3b26..8b2540c7d8a 100644 --- a/source/blender/blenkernel/intern/kdop.c +++ b/source/blender/blenkernel/intern/kdop.c @@ -38,7 +38,6 @@ #include "DNA_curve_types.h" #include "DNA_object_types.h" #include "DNA_object_force.h" -#include "DNA_cloth_types.h" #include "DNA_key_types.h" #include "DNA_mesh_types.h" #include "DNA_meshdata_types.h" @@ -59,7 +58,7 @@ #include "BKE_key.h" #include "BKE_mesh.h" #include "BKE_object.h" -#include "BKE_cloth.h" +#include "BKE_collisions.h" #include "BKE_modifier.h" #include "BKE_utildefines.h" #include "BKE_DerivedMesh.h" @@ -165,13 +164,13 @@ static int size_threshold = 16; /* * Common methods for all algorithms */ -DO_INLINE void bvh_exchange(Tree **a, int i, int j) +void bvh_exchange(Tree **a, int i, int j) { Tree *t=a[i]; a[i]=a[j]; a[j]=t; } -DO_INLINE int floor_lg(int a) +int floor_lg(int a) { return (int)(floor(log(a)/log(2))); } @@ -294,7 +293,7 @@ static void bvh_introsort_loop (Tree **a, int lo, int hi, int depth_limit, int a } } -DO_INLINE void bvh_sort(Tree **a0, int begin, int end, int axis) +void bvh_sort(Tree **a0, int begin, int end, int axis) { if (begin < end) { @@ -303,7 +302,7 @@ DO_INLINE void bvh_sort(Tree **a0, int begin, int end, int axis) bvh_insertionsort(a, begin, end, axis); } } -DO_INLINE void bvh_sort_along_axis(Tree **face_list, int start, int end, int axis) +void bvh_sort_along_axis(Tree **face_list, int start, int end, int axis) { bvh_sort(face_list, start, end, axis); } @@ -330,7 +329,7 @@ void bvh_free(BVH * bvh) BLI_linklist_free(bvh->tree,NULL); bvh->tree = NULL; - + MEM_freeN(bvh); bvh = NULL; } @@ -338,7 +337,7 @@ void bvh_free(BVH * bvh) // only supports x,y,z axis in the moment // but we should use a plain and simple function here for speed sake -DO_INLINE int bvh_largest_axis(float *bv) +int bvh_largest_axis(float *bv) { float middle_point[3]; @@ -362,7 +361,7 @@ DO_INLINE int bvh_largest_axis(float *bv) } // depends on the fact that the BVH's for each face is already build -DO_INLINE void bvh_calc_DOP_hull_from_faces(BVH * bvh, Tree **tri, int numfaces, float *bv) +void bvh_calc_DOP_hull_from_faces(BVH * bvh, Tree **tri, int numfaces, float *bv) { float newmin,newmax; int i, j; @@ -386,9 +385,9 @@ DO_INLINE void bvh_calc_DOP_hull_from_faces(BVH * bvh, Tree **tri, int numfaces, } } -DO_INLINE void bvh_calc_DOP_hull_static(BVH * bvh, Tree **tri, int numfaces, float *bv) +void bvh_calc_DOP_hull_static(BVH * bvh, Tree **tri, int numfaces, float *bv) { - ClothVertex *tempMVert = bvh->verts; + MVert *tempMVert = bvh->xold; MFace *tempMFace = bvh->mfaces; float *tempBV = bv; float newminmax; @@ -415,7 +414,7 @@ DO_INLINE void bvh_calc_DOP_hull_static(BVH * bvh, Tree **tri, int numfaces, flo // for all Axes. for (i = KDOP_START; i < KDOP_END; i++) { - newminmax = INPR(tempMVert[temp].txold, KDOP_AXES[i]); + newminmax = INPR(tempMVert[temp].co, KDOP_AXES[i]); if ((newminmax < tempBV[(2 * i)]) || (k == 0 && j == 0)) tempBV[(2 * i)] = newminmax; if ((newminmax > tempBV[(2 * i) + 1])|| (k == 0 && j == 0)) @@ -425,9 +424,10 @@ DO_INLINE void bvh_calc_DOP_hull_static(BVH * bvh, Tree **tri, int numfaces, flo } } -DO_INLINE void bvh_calc_DOP_hull_moving(BVH * bvh, Tree **tri, int numfaces, float *bv) +void bvh_calc_DOP_hull_moving(BVH * bvh, Tree **tri, int numfaces, float *bv) { - ClothVertex *tempMVert = bvh->verts; + MVert *tempMVert = bvh->xold; + MVert *tempMVert2 = bvh->x; MFace *tempMFace = bvh->mfaces; float *tempBV = bv; float newminmax; @@ -454,13 +454,13 @@ DO_INLINE void bvh_calc_DOP_hull_moving(BVH * bvh, Tree **tri, int numfaces, flo // for all Axes. for (i = KDOP_START; i < KDOP_END; i++) { - newminmax = INPR(tempMVert[temp].txold, KDOP_AXES[i]); + newminmax = INPR(tempMVert[temp].co, KDOP_AXES[i]); if ((newminmax < tempBV[(2 * i)]) || (k == 0 && j == 0)) tempBV[(2 * i)] = newminmax; if ((newminmax > tempBV[(2 * i) + 1])|| (k == 0 && j == 0)) tempBV[(2 * i) + 1] = newminmax; - newminmax = INPR(tempMVert[temp].tx, KDOP_AXES[i]); + newminmax = INPR(tempMVert2[temp].co, KDOP_AXES[i]); if ((newminmax < tempBV[(2 * i)]) || (k == 0 && j == 0)) tempBV[(2 * i)] = newminmax; if ((newminmax > tempBV[(2 * i) + 1])|| (k == 0 && j == 0)) @@ -538,25 +538,18 @@ static void bvh_div_env_node(BVH * bvh, TreeNode *tree, Tree **face_list, unsign return; } -BVH *bvh_build (ClothModifierData *clmd, float epsilon) +BVH *bvh_build (DerivedMesh *dm, MVert *x, MVert *xold, unsigned int numverts, float epsilon) { unsigned int i = 0, j = 0, k = 0; Tree **face_list=NULL; BVH *bvh=NULL; - Cloth *cloth = NULL; Tree *tree=NULL; LinkNode *nlink = NULL; EdgeHash *edgehash = NULL; - LinkNode *springs = NULL; unsigned int numsprings = 0; MFace *mface = NULL; - if(!clmd) - return NULL; - - cloth = clmd->clothObject; - - if(!cloth) + if(!dm) return NULL; bvh = MEM_callocN(sizeof(BVH), "BVH"); @@ -566,20 +559,18 @@ BVH *bvh_build (ClothModifierData *clmd, float epsilon) return NULL; } - springs = cloth->springs; - numsprings = cloth->numsprings; - bvh->flags = 0; bvh->leaf_tree = NULL; bvh->leaf_root = NULL; bvh->tree = NULL; bvh->epsilon = epsilon; - bvh->numfaces = cloth->numfaces; - mface = bvh->mfaces = cloth->mfaces; + bvh->numfaces = dm->getNumFaces(dm); + mface = bvh->mfaces = dm->getFaceArray(dm); - bvh->numverts = cloth->numverts; - bvh->verts = cloth->verts; + bvh->numverts = numverts; + bvh->x = x; + bvh->xold = xold; tree = (Tree *)MEM_callocN(sizeof(Tree), "Tree"); // TODO: check succesfull alloc BLI_linklist_append(&bvh->tree, tree); @@ -610,21 +601,6 @@ BVH *bvh_build (ClothModifierData *clmd, float epsilon) } else { - // create spring tearing hash - /* - edgehash = BLI_edgehash_new(); - if(clmd->sim_parms.flags & CSIMSETT_FLAG_TEARING_ENABLED) - for(i = 0; i < numsprings; i++) - { - if((springs[i].flags & CSPRING_FLAG_DEACTIVATE) - &&(!BLI_edgehash_haskey(edgehash, springs[i].ij, springs[i].kl))) - { - BLI_edgehash_insert(edgehash, springs[i].ij, springs[i].kl, NULL); - BLI_edgehash_insert(edgehash, springs[i].kl, springs[i].ij, NULL); - } - } - */ - // create face boxes face_list = MEM_callocN (bvh->numfaces * sizeof (Tree *), "Tree"); if (face_list == NULL) @@ -637,50 +613,43 @@ BVH *bvh_build (ClothModifierData *clmd, float epsilon) // create face boxes for(i = 0, k = 0; i < bvh->numfaces; i++) { - LinkNode *tnlink; - /* - if((!BLI_edgehash_haskey(edgehash, mface[i].v1, mface[i].v2)) - &&(!BLI_edgehash_haskey(edgehash, mface[i].v2, mface[i].v3)) - &&(!BLI_edgehash_haskey(edgehash, mface[i].v3, mface[i].v4)) - &&(!BLI_edgehash_haskey(edgehash, mface[i].v4, mface[i].v1))) - */ + LinkNode *tnlink = NULL; + + tree = (Tree *)MEM_callocN(sizeof(Tree), "Tree"); + // TODO: check succesfull alloc + + tnlink = BLI_linklist_append_fast(&nlink->next, tree); + + face_list[i] = tree; + tree->tri_index = i; + tree->isleaf = 1; + tree->nextLeaf = NULL; + tree->prevLeaf = bvh->leaf_tree; + tree->parent = NULL; + tree->count_nodes = 0; + + if(i==0) { - tree = (Tree *)MEM_callocN(sizeof(Tree), "Tree"); - // TODO: check succesfull alloc - - tnlink = BLI_linklist_append_fast(&nlink->next, tree); - - face_list[i] = tree; - tree->tri_index = i; - tree->isleaf = 1; - tree->nextLeaf = NULL; - tree->prevLeaf = bvh->leaf_tree; - tree->parent = NULL; - tree->count_nodes = 0; - - if(i==0) - { - bvh->leaf_tree = bvh->leaf_root = tree; - } - else - { - bvh->leaf_tree->nextLeaf = tree; - bvh->leaf_tree = bvh->leaf_tree->nextLeaf; - } - - tree->nodes[0] = tree->nodes[1] = tree->nodes[2] = tree->nodes[3] = NULL; - - bvh_calc_DOP_hull_static(bvh, &face_list[i], 1, tree->bv); - - // inflate the bv with some epsilon - for (j = KDOP_START; j < KDOP_END; j++) - { - tree->bv[(2 * j)] -= bvh->epsilon; // minimum - tree->bv[(2 * j) + 1] += bvh->epsilon; // maximum - } - - nlink = tnlink; + bvh->leaf_tree = bvh->leaf_root = tree; } + else + { + bvh->leaf_tree->nextLeaf = tree; + bvh->leaf_tree = bvh->leaf_tree->nextLeaf; + } + + tree->nodes[0] = tree->nodes[1] = tree->nodes[2] = tree->nodes[3] = NULL; + + bvh_calc_DOP_hull_static(bvh, &face_list[i], 1, tree->bv); + + // inflate the bv with some epsilon + for (j = KDOP_START; j < KDOP_END; j++) + { + tree->bv[(2 * j)] -= bvh->epsilon; // minimum + tree->bv[(2 * j) + 1] += bvh->epsilon; // maximum + } + + nlink = tnlink; } // build root bvh @@ -699,7 +668,7 @@ BVH *bvh_build (ClothModifierData *clmd, float epsilon) } // bvh_overlap - is it possbile for 2 bv's to collide ? -DO_INLINE int bvh_overlap(float *bv1, float *bv2) +int bvh_overlap(float *bv1, float *bv2) { int i = 0; for (i = KDOP_START; i < KDOP_END; i++) @@ -725,18 +694,10 @@ DO_INLINE int bvh_overlap(float *bv1, float *bv2) * every other triangle that doesn't require any realloc, but uses * much memory */ -int bvh_traverse(ClothModifierData * clmd, ClothModifierData * coll_clmd, Tree * tree1, Tree * tree2, float step, CM_COLLISION_RESPONSE collision_response) +int bvh_traverse(Tree * tree1, Tree * tree2, LinkNode *collision_list) { - int i = 0, ret=0; - - /* - // Shouldn't be possible - if(!tree1 || !tree2) - { - printf("Error: no tree there\n"); - return 0; -} - */ + int i = 0, ret = 0; + if (bvh_overlap(tree1->bv, tree2->bv)) { // Check if this node in the first tree is a leaf @@ -745,10 +706,14 @@ int bvh_traverse(ClothModifierData * clmd, ClothModifierData * coll_clmd, Tree * // Check if this node in the second tree a leaf if (tree2->isleaf) { - // Provide the collision response. + // save potential colliding triangles + CollisionPair *collpair = (CollisionPair *)MEM_callocN(sizeof(CollisionPair), "CollisionPair"); + + collpair->indexA = tree1->tri_index; + collpair->indexB = tree2->tri_index; + + BLI_linklist_append(&collision_list, collpair); - if(collision_response) - collision_response (clmd, coll_clmd, tree1, tree2); return 1; } else @@ -757,7 +722,7 @@ int bvh_traverse(ClothModifierData * clmd, ClothModifierData * coll_clmd, Tree * for (i = 0; i < 4; i++) { // Only traverse nodes that exist. - if (tree2->nodes[i] && bvh_traverse (clmd, coll_clmd, tree1, tree2->nodes[i], step, collision_response)) + if (tree2->nodes[i] && bvh_traverse (tree1, tree2->nodes[i], collision_list)) ret = 1; } } @@ -768,7 +733,7 @@ int bvh_traverse(ClothModifierData * clmd, ClothModifierData * coll_clmd, Tree * for (i = 0; i < 4; i++) { // Only traverse nodes that exist. - if (tree1->nodes [i] && bvh_traverse (clmd, coll_clmd, tree1->nodes[i], tree2, step, collision_response)) + if (tree1->nodes [i] && bvh_traverse (tree1->nodes[i], tree2, collision_list)) ret = 1; } } @@ -809,12 +774,18 @@ void bvh_join(Tree * tree) } // update static bvh -void bvh_update(ClothModifierData *clmd, BVH * bvh, int moving) +// needs new positions in bvh->x, bvh->xold +void bvh_update(DerivedMesh *dm, BVH * bvh, int moving) { TreeNode *leaf, *parent; int traversecheck = 1; // if this is zero we don't go further unsigned int j = 0; + if(bvh->numfaces != dm->getNumFaces(dm)) + return; + + bvh->mfaces = dm->getFaceArray(dm); + for (leaf = bvh->leaf_root; leaf; leaf = leaf->nextLeaf) { traversecheck = 1; diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c index bb6297361fe..59bd4b8253d 100644 --- a/source/blender/blenkernel/intern/modifier.c +++ b/source/blender/blenkernel/intern/modifier.c @@ -72,6 +72,7 @@ #include "BKE_main.h" #include "BKE_anim.h" #include "BKE_bad_level_calls.h" +#include "BKE_collisions.h" #include "BKE_customdata.h" #include "BKE_global.h" #include "BKE_utildefines.h" @@ -4920,7 +4921,7 @@ static void clothModifier_updateDepgraph( CustomDataMask clothModifier_requiredDataMask(ModifierData *md) { - ClothModifierData *clmd = (HookModifierData *)md; + ClothModifierData *clmd = (ClothModifierData *)md; CustomDataMask dataMask = 0; /* ask for vertexgroups if we need them */ @@ -4948,6 +4949,113 @@ static void clothModifier_freeData(ModifierData *md) } } +/* Collision */ + +static void collisionModifier_initData(ModifierData *md) +{ + CollisionModifierData *collmd = (CollisionModifierData*) md; + + collmd->x = NULL; + collmd->xold = NULL; + collmd->time = -1; + collmd->numverts = 0; + collmd->tree = NULL; +} + +static void collisionModifier_freeData(ModifierData *md) +{ + CollisionModifierData *collmd = (CollisionModifierData*) md; + + if (collmd) + { + if(collmd->tree) + bvh_free(collmd->tree); + if(collmd->x) + MEM_freeN(collmd->x); + if(collmd->xold) + MEM_freeN(collmd->xold); + + collmd->x = NULL; + collmd->xold = NULL; + collmd->time = -1; + collmd->numverts = 0; + collmd->tree = NULL; + } +} + +static void collisionModifier_deformVerts( + ModifierData *md, Object *ob, DerivedMesh *derivedData, + float (*vertexCos)[3], int numVerts) +{ + CollisionModifierData *collmd = (CollisionModifierData*) md; + DerivedMesh *dm = NULL; + MVert *mvert = NULL; + float current_time = 0; + unsigned int numverts = 0, i = 0; + MVert *tempVert = NULL; + + // if possible use/create DerivedMesh + + if(derivedData) dm = CDDM_copy(derivedData); + else if(ob->type==OB_MESH) dm = CDDM_from_mesh(ob->data, ob); + + if(dm) + { + CDDM_apply_vert_coords(dm, vertexCos); + CDDM_calc_normals(dm); + + + current_time = bsystem_time ( ob, ( float ) G.scene->r.cfra, 0.0 ); + + if(current_time > collmd->time) + { + numverts = dm->getNumVerts ( dm ); + + // check if mesh has changed + if(collmd->x && (numverts != collmd->numverts)) + collisionModifier_freeData(collmd); + + if(collmd->time == -1) // first time + { + collmd->x = dm->dupVertArray(dm); + collmd->xold = dm->dupVertArray(dm); + collmd->numverts = numverts; + + // TODO: epsilon + // create bounding box hierarchy + collmd->tree = bvh_build(dm, collmd->x, collmd->xold, numverts, 0.01); + } + else if(numverts == collmd->numverts) + { + // put positions to old positions + tempVert = collmd->xold; + collmd->xold = collmd->x; + collmd->x = tempVert; + + memcpy(collmd->x, dm->getVertArray(dm), numverts*sizeof(MVert)); + + for ( i = 0; i < numverts; i++ ) + { + // we save global positions + Mat4MulVecfl ( ob->obmat, collmd->x[i].co ); + } + + bvh_update(dm, collmd->tree, 0); // recalc static bounding boxes + } + + collmd->time = current_time; + } + } + + if(dm) + dm->release(dm); +} + +static int collisionModifier_dependsOnTime(ModifierData *md) +{ + return 1; +} + /* Boolean */ static void booleanModifier_copyData(ModifierData *md, ModifierData *target) @@ -5247,6 +5355,16 @@ ModifierTypeInfo *modifierType_getInfo(ModifierType type) // mti->copyData = clothModifier_copyData; mti->deformVerts = clothModifier_deformVerts; mti->updateDepgraph = clothModifier_updateDepgraph; + + mti = INIT_TYPE(Collision); + mti->type = eModifierTypeType_OnlyDeform; + mti->initData = collisionModifier_initData; + mti->flags = eModifierTypeFlag_AcceptsMesh + | eModifierTypeFlag_RequiresOriginalData; + mti->dependsOnTime = collisionModifier_dependsOnTime; + mti->freeData = collisionModifier_freeData; + mti->deformVerts = collisionModifier_deformVerts; + // mti->copyData = collisionModifier_copyData; mti = INIT_TYPE(Boolean); mti->type = eModifierTypeType_Nonconstructive; @@ -5449,7 +5567,7 @@ int modifiers_isSoftbodyEnabled(Object *ob) return (md && md->mode & (eModifierMode_Realtime | eModifierMode_Render)); } -ModifierData * modifiers_isClothEnabled(Object *ob) +ModifierData *modifiers_isClothEnabled(Object *ob) { ModifierData *md = modifiers_findByType(ob, eModifierType_Cloth); diff --git a/source/blender/makesdna/DNA_cloth_types.h b/source/blender/makesdna/DNA_cloth_types.h index 7f5527466e4..27f7431a9cf 100644 --- a/source/blender/makesdna/DNA_cloth_types.h +++ b/source/blender/makesdna/DNA_cloth_types.h @@ -130,7 +130,6 @@ typedef struct CollisionSettings float friction; /* Friction/damping applied on contact with other object.*/ short collision_type; /* which collision system is used. */ short loop_count; /* How many iterations for the collision loop. */ - struct LinkNode *collision_list; /* e.g. pointer to temp memory for collisions */ int flags; /* collision flags defined in BKE_cloth.h */ int pad; } diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h index 4c9fbdcc7b7..e6e73ea7d07 100644 --- a/source/blender/makesdna/DNA_modifier_types.h +++ b/source/blender/makesdna/DNA_modifier_types.h @@ -31,6 +31,7 @@ typedef enum ModifierType { eModifierType_Smooth, eModifierType_Cast, eModifierType_Cloth, + eModifierType_Collision, NUM_MODIFIER_TYPES } ModifierType; @@ -346,6 +347,17 @@ typedef struct ClothModifierData { CollisionSettings coll_parms; /* definition is in DNA_cloth_types.h */ } ClothModifierData; +typedef struct CollisionModifierData { + ModifierData modifier; + + struct MVert *x; + struct MVert *xold; + + unsigned int numverts; + float time; + void *tree; /* collision tree for this cloth object */ +} CollisionModifierData; + typedef enum { eBooleanModifierOp_Intersect, eBooleanModifierOp_Union, diff --git a/source/blender/src/buttons_editing.c b/source/blender/src/buttons_editing.c index 194241c4380..13aae388106 100644 --- a/source/blender/src/buttons_editing.c +++ b/source/blender/src/buttons_editing.c @@ -950,7 +950,9 @@ static uiBlock *modifiers_add_menu(void *ob_v) ModifierTypeInfo *mti = modifierType_getInfo(i); /* Only allow adding through appropriate other interfaces */ - if(ELEM3(i, eModifierType_Softbody, eModifierType_Hook, eModifierType_Cloth)) continue; + if(ELEM(i, eModifierType_Softbody, eModifierType_Hook)) continue; + + if(ELEM(i, eModifierType_Cloth, eModifierType_Collision)) continue; if((mti->flags&eModifierTypeFlag_AcceptsCVs) || (ob->type==OB_MESH && (mti->flags&eModifierTypeFlag_AcceptsMesh))) { @@ -1483,7 +1485,7 @@ static void draw_modifier(uiBlock *block, Object *ob, ModifierData *md, int *xco uiBlockSetCol(block, TH_AUTO); /* open/close icon */ - if (!isVirtual) { + if (!isVirtual && md->type!=eModifierType_Collision) { uiBlockSetEmboss(block, UI_EMBOSSN); uiDefIconButBitI(block, ICONTOG, eModifierMode_Expanded, B_MODIFIER_REDRAW, VICON_DISCLOSURE_TRI_RIGHT, x-10, y-2, 20, 20, &md->mode, 0.0, 0.0, 0.0, 0.0, "Collapse/Expand Modifier"); } @@ -1500,8 +1502,8 @@ static void draw_modifier(uiBlock *block, Object *ob, ModifierData *md, int *xco uiBlockBeginAlign(block); uiDefBut(block, TEX, B_MODIFIER_REDRAW, "", x+10, y-1, buttonWidth-60, 19, md->name, 0.0, sizeof(md->name)-1, 0.0, 0.0, "Modifier name"); - /* Softbody not allowed in this situation, enforce! */ - if (md->type!=eModifierType_Softbody || !(ob->pd && ob->pd->deflect)) { + /* Softbody not allowed in this situation, enforce! */ + if ((md->type!=eModifierType_Softbody && md->type!=eModifierType_Collision) || !(ob->pd && ob->pd->deflect)) { uiDefIconButBitI(block, TOG, eModifierMode_Render, B_MODIFIER_RECALC, ICON_SCENE, x+10+buttonWidth-60, y-1, 19, 19,&md->mode, 0, 0, 1, 0, "Enable modifier during rendering"); uiDefIconButBitI(block, TOG, eModifierMode_Realtime, B_MODIFIER_RECALC, VICON_VIEW3D, x+10+buttonWidth-40, y-1, 19, 19,&md->mode, 0, 0, 1, 0, "Enable modifier during interactive display"); if (mti->flags&eModifierTypeFlag_SupportsEditmode) { @@ -1540,9 +1542,13 @@ static void draw_modifier(uiBlock *block, Object *ob, ModifierData *md, int *xco uiButSetFunc(but, modifiers_moveDown, ob, md); uiBlockSetEmboss(block, UI_EMBOSSN); - - but = uiDefIconBut(block, BUT, B_MODIFIER_RECALC, VICON_X, x+width-70+40, y, 16, 16, NULL, 0.0, 0.0, 0.0, 0.0, "Delete modifier"); - uiButSetFunc(but, modifiers_del, ob, md); + + // deletion over the deflection panel + if(md->type!=eModifierType_Collision) + { + but = uiDefIconBut(block, BUT, B_MODIFIER_RECALC, VICON_X, x+width-70+40, y, 16, 16, NULL, 0.0, 0.0, 0.0, 0.0, "Delete modifier"); + uiButSetFunc(but, modifiers_del, ob, md); + } uiBlockSetCol(block, TH_AUTO); } @@ -1603,6 +1609,8 @@ static void draw_modifier(uiBlock *block, Object *ob, ModifierData *md, int *xco height = 26; } else if (md->type==eModifierType_Cloth) { height = 26; + } else if (md->type==eModifierType_Collision) { + height = 19; } else if (md->type==eModifierType_Boolean) { height = 48; } else if (md->type==eModifierType_Array) { @@ -1614,7 +1622,7 @@ static void draw_modifier(uiBlock *block, Object *ob, ModifierData *md, int *xco y -= 18; - if (!isVirtual) { + if (!isVirtual && (md->type!=eModifierType_Collision)) { uiBlockBeginAlign(block); but = uiDefBut(block, BUT, B_MODIFIER_RECALC, "Apply", lx,(cy-=19),60,19, 0, 0, 0, 0, 0, "Apply the current modifier and remove from the stack"); uiButSetFunc(but, modifiers_applyModifier, ob, md); diff --git a/source/blender/src/buttons_object.c b/source/blender/src/buttons_object.c index 10d4d544e86..3b232f49001 100644 --- a/source/blender/src/buttons_object.c +++ b/source/blender/src/buttons_object.c @@ -2741,10 +2741,29 @@ void do_effects_panels(unsigned short event) } +/* Panel for collision */ +static void object_collision__enabletoggle(void *ob_v, void *arg2) +{ + Object *ob = ob_v; + ModifierData *md = modifiers_findByType(ob, eModifierType_Collision); + + if (!md) { + md = modifier_new(eModifierType_Collision); + BLI_addhead(&ob->modifiers, md); + } + else { + BLI_remlink(&ob->modifiers, md); + modifier_free(md); + } + + allqueue(REDRAWBUTSEDIT, 0); +} + /* Panel for particle interaction settings */ static void object_panel_fields(Object *ob) { uiBlock *block; + uiBut *but; block= uiNewBlock(&curarea->uiblocks, "object_panel_fields", UI_EMBOSS, UI_HELV, curarea->win); if(uiNewPanel(curarea, block, "Fields and Deflection", "Physics", 0, 0, 318, 204)==0) return; @@ -2804,7 +2823,8 @@ static void object_panel_fields(Object *ob) /* only meshes collide now */ if(ob->type==OB_MESH) { - uiDefButBitS(block, TOG, 1, B_REDR, "Deflection",160,160,150,20, &pd->deflect, 0, 0, 0, 0, "Deflects particles based on collision"); + but = uiDefButBitS(block, TOG, 1, B_REDR, "Deflection/Collision",160,160,150,20, &pd->deflect, 0, 0, 0, 0, "Make object collision object for dynamics"); + uiButSetFunc(but, object_collision__enabletoggle, ob, NULL); if(pd->deflect) { uiDefBut(block, LABEL, 0, "Particles", 160,140,150,20, NULL, 0.0, 0, 0, 0, ""); @@ -3129,7 +3149,7 @@ static void object_panel_cloth(Object *ob) uiBlockBeginAlign(block); uiDefButF(block, NUM, B_CLOTH_RENEW, "StructStiff:", 10,170,150,20, &clmd->sim_parms.structural, 1.0, 10000.0, 100, 0, "Overall stiffness of structure"); uiDefButF(block, NUM, B_CLOTH_RENEW, "BendStiff:", 160,170,150,20, &clmd->sim_parms.bending, 0.0, 10000.0, 1000, 0, "Wrinkle possibility"); - uiDefButI(block, NUM, B_CLOTH_RENEW, "Steps per Frame:", 10,150,150,20, &clmd->sim_parms.stepsPerFrame, 1.0, 100.0, 5, 0, "Quality of the simulation (higher=better=slower)"); + uiDefButI(block, NUM, B_CLOTH_RENEW, "Quality:", 10,150,150,20, &clmd->sim_parms.stepsPerFrame, 1.0, 100.0, 5, 0, "Quality of the simulation (higher=>better=>slower)"); uiBlockEndAlign(block); uiBlockBeginAlign(block); uiDefButF(block, NUM, B_CLOTH_RENEW, "Spring Damp:", 160,150,150,20, &clmd->sim_parms.Cdis, 0.0, 10.0, 10, 0, "Spring damping"); diff --git a/source/blender/src/transform_generics.c b/source/blender/src/transform_generics.c index 9031ce48707..9f45bd7aaa0 100644 --- a/source/blender/src/transform_generics.c +++ b/source/blender/src/transform_generics.c @@ -426,8 +426,8 @@ void recalcData(TransInfo *t) if(modifiers_isSoftbodyEnabled(base->object)) { base->object->softflag |= OB_SB_REDO; } - else if(modifiers_isClothEnabled(ob)) { - cloth_free_modifier(modifiers_isClothEnabled(ob)); + else if((clmd = (ClothModifierData *)modifiers_isClothEnabled(ob))) { + cloth_free_modifier(clmd); } } @@ -470,8 +470,8 @@ void recalcData(TransInfo *t) if(modifiers_isSoftbodyEnabled(ob)) { ob->softflag |= OB_SB_REDO; } - else if(modifiers_isClothEnabled(ob)) { - cloth_free_modifier(modifiers_isClothEnabled(ob)); + else if((clmd = (ClothModifierData *)modifiers_isClothEnabled(ob))) { + cloth_free_modifier(clmd); } } From c8fe3c95a344d401ec3cb3d0be132be00a49a79c Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Sun, 21 Oct 2007 16:39:07 +0000 Subject: [PATCH 029/246] Forgot some new file for seperated collisions --- source/blender/blenkernel/BKE_collisions.h | 103 +++++++++++++++++++++ 1 file changed, 103 insertions(+) create mode 100644 source/blender/blenkernel/BKE_collisions.h diff --git a/source/blender/blenkernel/BKE_collisions.h b/source/blender/blenkernel/BKE_collisions.h new file mode 100644 index 00000000000..edd86f0f5f6 --- /dev/null +++ b/source/blender/blenkernel/BKE_collisions.h @@ -0,0 +1,103 @@ +/** + * BKE_cloth.h + * + * $Id: BKE_cloth.h,v 1.1 2007/08/01 02:07:27 daniel Exp $ + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) Blender Foundation. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + */ +#ifndef BKE_COLLISIONS_H +#define BKE_COLLISIONS_H + +#include +#include +#include +/* types */ +#include "BLI_linklist.h" +#include "BKE_DerivedMesh.h" +#include "BKE_object.h" +#include "BKE_DerivedMesh.h" + +// used in kdop.c and collision.c +typedef struct Tree +{ + struct Tree *nodes[4]; // 4 children --> quad-tree + struct Tree *parent; + struct Tree *nextLeaf; + struct Tree *prevLeaf; + float bv[26]; // Bounding volume of all nodes / we have 7 axes on a 14-DOP + unsigned int tri_index; // this saves the index of the face + int count_nodes; // how many nodes are used + int traversed; // how many nodes already traversed until this level? + int isleaf; +} +Tree; + +typedef struct Tree TreeNode; + +typedef struct BVH +{ + unsigned int numfaces; + unsigned int numverts; + MVert *x; // position of verts at time n + MVert *xold; // position of verts at time n-1 + MFace *mfaces; // just a pointer to the original datastructure + struct LinkNode *tree; + TreeNode *root; // TODO: saving the root --> is this really needed? YES! + TreeNode *leaf_tree; /* Tail of the leaf linked list. */ + TreeNode *leaf_root; /* Head of the leaf linked list. */ + float epsilon; /* epslion is used for inflation of the k-dop */ + int flags; /* bvhFlags */ +} +BVH; + +/* used for collisions in kdop.c and also collision.c*/ +typedef struct CollisionPair +{ + unsigned int indexA, indexB; +} +CollisionPair; + + +///////////////////////////////////////////////// +// forward declarations +///////////////////////////////////////////////// + +void bvh_free ( BVH *bvh ); +BVH *bvh_build (DerivedMesh *dm, MVert *x, MVert *xold, unsigned int numverts, float epsilon); + +int bvh_traverse(Tree *tree1, Tree *tree2, LinkNode *collision_list); +void bvh_update(DerivedMesh *dm, BVH * bvh, int moving); + +LinkNode *BLI_linklist_append_fast ( LinkNode **listp, void *ptr ); + + +///////////////////////////////////////////////// + +#endif + From 5bd2f5b08e006cb0f0fd281723ece3c6939b84d5 Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Sun, 21 Oct 2007 16:53:25 +0000 Subject: [PATCH 030/246] Fixed read/writing of blendfiles with collision modifier (saving not supported itm), also changed naming --- source/blender/blenkernel/BKE_collisions.h | 4 ++-- source/blender/blenkernel/intern/kdop.c | 12 +++++------ source/blender/blenkernel/intern/modifier.c | 22 ++++++++++---------- source/blender/blenloader/intern/readfile.c | 9 ++++++++ source/blender/makesdna/DNA_modifier_types.h | 2 +- 5 files changed, 29 insertions(+), 20 deletions(-) diff --git a/source/blender/blenkernel/BKE_collisions.h b/source/blender/blenkernel/BKE_collisions.h index edd86f0f5f6..7c9ced262a8 100644 --- a/source/blender/blenkernel/BKE_collisions.h +++ b/source/blender/blenkernel/BKE_collisions.h @@ -64,8 +64,8 @@ typedef struct BVH { unsigned int numfaces; unsigned int numverts; - MVert *x; // position of verts at time n - MVert *xold; // position of verts at time n-1 + MVert *xnew; // position of verts at time n + MVert *x; // position of verts at time n-1 MFace *mfaces; // just a pointer to the original datastructure struct LinkNode *tree; TreeNode *root; // TODO: saving the root --> is this really needed? YES! diff --git a/source/blender/blenkernel/intern/kdop.c b/source/blender/blenkernel/intern/kdop.c index 8b2540c7d8a..1e17ee4f03e 100644 --- a/source/blender/blenkernel/intern/kdop.c +++ b/source/blender/blenkernel/intern/kdop.c @@ -387,7 +387,7 @@ void bvh_calc_DOP_hull_from_faces(BVH * bvh, Tree **tri, int numfaces, float *bv void bvh_calc_DOP_hull_static(BVH * bvh, Tree **tri, int numfaces, float *bv) { - MVert *tempMVert = bvh->xold; + MVert *tempMVert = bvh->x; MFace *tempMFace = bvh->mfaces; float *tempBV = bv; float newminmax; @@ -426,8 +426,8 @@ void bvh_calc_DOP_hull_static(BVH * bvh, Tree **tri, int numfaces, float *bv) void bvh_calc_DOP_hull_moving(BVH * bvh, Tree **tri, int numfaces, float *bv) { - MVert *tempMVert = bvh->xold; - MVert *tempMVert2 = bvh->x; + MVert *tempMVert = bvh->x; + MVert *tempMVert2 = bvh->xnew; MFace *tempMFace = bvh->mfaces; float *tempBV = bv; float newminmax; @@ -538,7 +538,7 @@ static void bvh_div_env_node(BVH * bvh, TreeNode *tree, Tree **face_list, unsign return; } -BVH *bvh_build (DerivedMesh *dm, MVert *x, MVert *xold, unsigned int numverts, float epsilon) +BVH *bvh_build (DerivedMesh *dm, MVert *x, MVert *xnew, unsigned int numverts, float epsilon) { unsigned int i = 0, j = 0, k = 0; Tree **face_list=NULL; @@ -569,8 +569,8 @@ BVH *bvh_build (DerivedMesh *dm, MVert *x, MVert *xold, unsigned int numverts, f mface = bvh->mfaces = dm->getFaceArray(dm); bvh->numverts = numverts; + bvh->xnew = xnew; bvh->x = x; - bvh->xold = xold; tree = (Tree *)MEM_callocN(sizeof(Tree), "Tree"); // TODO: check succesfull alloc BLI_linklist_append(&bvh->tree, tree); @@ -774,7 +774,7 @@ void bvh_join(Tree * tree) } // update static bvh -// needs new positions in bvh->x, bvh->xold +// needs new positions in bvh->x, bvh->xnew void bvh_update(DerivedMesh *dm, BVH * bvh, int moving) { TreeNode *leaf, *parent; diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c index 59bd4b8253d..cb7fccd11c1 100644 --- a/source/blender/blenkernel/intern/modifier.c +++ b/source/blender/blenkernel/intern/modifier.c @@ -4956,7 +4956,7 @@ static void collisionModifier_initData(ModifierData *md) CollisionModifierData *collmd = (CollisionModifierData*) md; collmd->x = NULL; - collmd->xold = NULL; + collmd->xnew = NULL; collmd->time = -1; collmd->numverts = 0; collmd->tree = NULL; @@ -4972,11 +4972,11 @@ static void collisionModifier_freeData(ModifierData *md) bvh_free(collmd->tree); if(collmd->x) MEM_freeN(collmd->x); - if(collmd->xold) - MEM_freeN(collmd->xold); + if(collmd->xnew) + MEM_freeN(collmd->xnew); collmd->x = NULL; - collmd->xold = NULL; + collmd->xnew = NULL; collmd->time = -1; collmd->numverts = 0; collmd->tree = NULL; @@ -5018,26 +5018,26 @@ static void collisionModifier_deformVerts( if(collmd->time == -1) // first time { collmd->x = dm->dupVertArray(dm); - collmd->xold = dm->dupVertArray(dm); + collmd->xnew = dm->dupVertArray(dm); collmd->numverts = numverts; // TODO: epsilon // create bounding box hierarchy - collmd->tree = bvh_build(dm, collmd->x, collmd->xold, numverts, 0.01); + collmd->tree = bvh_build(dm, collmd->x, collmd->xnew, numverts, 0.01); } else if(numverts == collmd->numverts) { // put positions to old positions - tempVert = collmd->xold; - collmd->xold = collmd->x; - collmd->x = tempVert; + tempVert = collmd->x; + collmd->x = collmd->xnew; + collmd->xnew = tempVert; - memcpy(collmd->x, dm->getVertArray(dm), numverts*sizeof(MVert)); + memcpy(collmd->xnew, dm->getVertArray(dm), numverts*sizeof(MVert)); for ( i = 0; i < numverts; i++ ) { // we save global positions - Mat4MulVecfl ( ob->obmat, collmd->x[i].co ); + Mat4MulVecfl ( ob->obmat, collmd->xnew[i].co ); } bvh_update(dm, collmd->tree, 0); // recalc static bounding boxes diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 83bae60df30..99f0885b435 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -2888,6 +2888,15 @@ static void direct_link_modifiers(FileData *fd, ListBase *lb) printf ("direct_link_modifiers: read cloth baked_data.\n"); } } + else if (md->type==eModifierType_Collision) { + CollisionModifierData *collmd = (CollisionModifierData*) md; + + collmd->x = NULL; + collmd->xnew = NULL; + collmd->time = -1; + collmd->numverts = 0; + collmd->tree = NULL; + } else if (md->type==eModifierType_Hook) { HookModifierData *hmd = (HookModifierData*) md; diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h index e6e73ea7d07..81e27afbac4 100644 --- a/source/blender/makesdna/DNA_modifier_types.h +++ b/source/blender/makesdna/DNA_modifier_types.h @@ -351,7 +351,7 @@ typedef struct CollisionModifierData { ModifierData modifier; struct MVert *x; - struct MVert *xold; + struct MVert *xnew; unsigned int numverts; float time; From dfd9c71b56bf7b45f7764ca4a6968724bb243387 Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Sun, 21 Oct 2007 17:20:31 +0000 Subject: [PATCH 031/246] Code comments add to collision interface --- source/blender/blenkernel/BKE_collisions.h | 7 +- source/blender/blenkernel/intern/cloth.c | 123 +-------------------- source/blender/src/buttons_object.c | 2 +- 3 files changed, 9 insertions(+), 123 deletions(-) diff --git a/source/blender/blenkernel/BKE_collisions.h b/source/blender/blenkernel/BKE_collisions.h index 7c9ced262a8..0536a72d74b 100644 --- a/source/blender/blenkernel/BKE_collisions.h +++ b/source/blender/blenkernel/BKE_collisions.h @@ -88,10 +88,15 @@ CollisionPair; // forward declarations ///////////////////////////////////////////////// -void bvh_free ( BVH *bvh ); +// builds bounding volume hierarchy BVH *bvh_build (DerivedMesh *dm, MVert *x, MVert *xold, unsigned int numverts, float epsilon); +// frees the same +void bvh_free ( BVH *bvh ); +// checks two bounding volume hierarchies for potential collisions and returns some list with those int bvh_traverse(Tree *tree1, Tree *tree2, LinkNode *collision_list); + +// update bounding volumes, needs updated positions in bvh->x void bvh_update(DerivedMesh *dm, BVH * bvh, int moving); LinkNode *BLI_linklist_append_fast ( LinkNode **listp, void *ptr ); diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c index d83c7bcb7f0..dce36f543ee 100644 --- a/source/blender/blenkernel/intern/cloth.c +++ b/source/blender/blenkernel/intern/cloth.c @@ -621,8 +621,7 @@ void clothModifier_do ( ClothModifierData *clmd, Object *ob, DerivedMesh *dm, Frame *frame = NULL; LinkNode *search = NULL; float deltaTime = current_time - clmd->sim_parms.sim_time; - - + // only be active during a specific period: // that's "first frame" and "last frame" on GUI if ( ! ( clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_COLLOBJ ) ) @@ -671,59 +670,7 @@ void clothModifier_do ( ClothModifierData *clmd, Object *ob, DerivedMesh *dm, clmd->sim_parms.dt = 1.0f / clmd->sim_parms.stepsPerFrame; clmd->sim_parms.sim_time = current_time; - - // check if cloth object was some collision object before and needs freeing now - if ( ! ( clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_COLLOBJ ) && ( clmd->clothObject != NULL ) && ( clmd->clothObject->old_solver_type == 255 ) ) - { - // temporary set CSIMSETT_FLAG_COLLOBJ flag for proper freeing - clmd->sim_parms.flags |= CLOTH_SIMSETTINGS_FLAG_COLLOBJ; - cloth_free_modifier ( clmd ); - clmd->sim_parms.flags &= ~CLOTH_SIMSETTINGS_FLAG_COLLOBJ; - } - - // This is for collisions objects: check special case CSIMSETT_FLAG_COLLOBJ - if ( clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_COLLOBJ ) - { - // save next position + time - if ( ( clmd->clothObject == NULL ) || ( numverts != clmd->clothObject->numverts ) ) - { - if ( !collobj_from_object ( ob, clmd, dm, vertexCos, framenr ) ) - { - clmd->sim_parms.flags |= CLOTH_SIMSETTINGS_FLAG_COLLOBJ; - cloth_free_modifier ( clmd ); - return; - } - - if ( clmd->clothObject == NULL ) - return; - - cloth = clmd->clothObject; - } - - // Save old position - clmd->sim_parms.sim_time_old = clmd->sim_parms.sim_time; - clmd->sim_parms.sim_time = current_time; - - verts = cloth->verts; - - for ( i = 0; i < clmd->clothObject->numverts; i++, verts++ ) - { - // Save the previous position. - VECCOPY ( verts->xold, verts->x ); - VECCOPY ( verts->txold, verts->x ); - - // Get the current position. - VECCOPY ( verts->x, vertexCos[i] ); - Mat4MulVecfl ( ob->obmat, verts->x ); - - // Compute the vertices "velocity". - // (no dt correction here because of float error) - VECSUB ( verts->v, verts->x, verts->xold ); - } - - return; - } - + if ( deltaTime == 1.0f ) { if ( ( clmd->clothObject == NULL ) || ( numverts != clmd->clothObject->numverts ) ) @@ -955,72 +902,6 @@ static void cloth_apply_vgroup ( ClothModifierData *clmd, DerivedMesh *dm, short } } -// only meshes supported at the moment -/* collision objects */ -static int collobj_from_object ( Object *ob, ClothModifierData *clmd, DerivedMesh *dm, float ( *vertexCos ) [3], unsigned int numverts ) -{ - unsigned int i; - MVert *mvert = NULL; - ClothVertex *verts = NULL; - float tnull[3] = {0,0,0}; - - /* If we have a clothObject, free it. */ - if ( clmd->clothObject != NULL ) - cloth_free_modifier ( clmd ); - - /* Allocate a new cloth object. */ - clmd->clothObject = MEM_callocN ( sizeof ( Cloth ), "cloth" ); - if ( clmd->clothObject ) - { - clmd->clothObject->old_solver_type = 255; - // clmd->clothObject->old_collision_type = 255; - } - else if ( clmd->clothObject == NULL ) - { - modifier_setError ( & ( clmd->modifier ), "Out of memory on allocating clmd->clothObject." ); - return 0; - } - - switch ( ob->type ) - { - case OB_MESH: - - // mesh input objects need DerivedMesh - if ( !dm ) - return 0; - - cloth_from_mesh ( ob, clmd, dm ); - - if ( clmd->clothObject != NULL ) - { - if ( !dm ) return 0; - if ( !dm->getNumVerts ( dm ) || !dm->getNumFaces ( dm ) ) return 0; - - mvert = dm->getVertArray ( dm ); - verts = clmd->clothObject->verts; - numverts = clmd->clothObject->numverts = dm->getNumVerts ( dm ); - - for ( i = 0; i < numverts; i++, verts++ ) - { - VECCOPY ( verts->x, mvert[i].co ); - Mat4MulVecfl ( ob->obmat, verts->x ); - verts->flags = 0; - VECCOPY ( verts->xold, verts->x ); - VECCOPY ( verts->txold, verts->x ); - VECCOPY ( verts->tx, verts->x ); - VecMulf ( verts->v, 0.0f ); - verts->impulse_count = 0; - VECCOPY ( verts->impulse, tnull ); - } - // clmd->clothObject->tree = bvh_build ( dm, clmd->coll_parms.epsilon ); - - } - - return 1; - default: return 0; // TODO - we do not support changing meshes - } -} - // only meshes supported at the moment static int cloth_from_object ( Object *ob, ClothModifierData *clmd, DerivedMesh *dm, float ( *vertexCos ) [3], unsigned int numverts ) { diff --git a/source/blender/src/buttons_object.c b/source/blender/src/buttons_object.c index 3b232f49001..8bca629eeac 100644 --- a/source/blender/src/buttons_object.c +++ b/source/blender/src/buttons_object.c @@ -3131,7 +3131,7 @@ static void object_panel_cloth(Object *ob) if(clmd) { - but = uiDefButBitI(block, TOG, CLOTH_SIMSETTINGS_FLAG_COLLOBJ, B_EFFECT_DEP, "Collision Object", 170,200,130,20, &clmd->sim_parms.flags, 0, 0, 0, 0, "Sets object to become a cloth collision object"); + // but = uiDefButBitI(block, TOG, CLOTH_SIMSETTINGS_FLAG_COLLOBJ, B_EFFECT_DEP, "Collision Object", 170,200,130,20, &clmd->sim_parms.flags, 0, 0, 0, 0, "Sets object to become a cloth collision object"); if (!(clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_COLLOBJ)) { From 5a6ffd8441a092906bc445f7084d585624a7367b Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Mon, 22 Oct 2007 22:50:32 +0000 Subject: [PATCH 032/246] WIP commit, (just in case my HD breaks down). Don't expect anything to work. Code crashes and sim doesn't work ;) --- source/blender/blenkernel/BKE_cloth.h | 4 +- source/blender/blenkernel/BKE_collisions.h | 29 +- source/blender/blenkernel/BKE_modifier.h | 2 +- source/blender/blenkernel/intern/cloth.c | 143 +-- source/blender/blenkernel/intern/collision.c | 859 +------------------ source/blender/blenkernel/intern/implicit.c | 839 ++++++++++++++++++ source/blender/blenkernel/intern/kdop.c | 171 ++-- source/blender/blenkernel/intern/modifier.c | 80 +- source/blender/blenloader/intern/readfile.c | 3 +- source/blender/makesdna/DNA_cloth_types.h | 8 +- source/blender/makesdna/DNA_modifier_types.h | 8 +- source/blender/makesdna/DNA_object_force.h | 1 - source/blender/src/editobject.c | 1 + 13 files changed, 1125 insertions(+), 1023 deletions(-) diff --git a/source/blender/blenkernel/BKE_cloth.h b/source/blender/blenkernel/BKE_cloth.h index 1c5310c10d1..19851321b30 100644 --- a/source/blender/blenkernel/BKE_cloth.h +++ b/source/blender/blenkernel/BKE_cloth.h @@ -122,7 +122,7 @@ void cloth_free_modifier ( ClothModifierData *clmd ); void implicit_set_positions ( ClothModifierData *clmd ); // from cloth.c, needed for modifier.c -void clothModifier_do ( ClothModifierData *clmd, Object *ob, DerivedMesh *dm, float ( *vertexCos ) [3], int numverts ); +DerivedMesh *clothModifier_do(ClothModifierData *clmd, Object *ob, DerivedMesh *dm); //////////////////////////////////////////////// @@ -132,9 +132,7 @@ void clothModifier_do ( ClothModifierData *clmd, Object *ob, DerivedMesh *dm, fl //////////////////////////////////////////////// void cloth_free_modifier ( ClothModifierData *clmd ); void cloth_init ( ClothModifierData *clmd ); -void cloth_deform_verts ( struct Object *ob, float framenr, float ( *vertexCos ) [3], int numVerts, void *derivedData, ClothModifierData *clmd ); void cloth_update_normals ( ClothVertex *verts, int nVerts, MFace *face, int totface ); - //////////////////////////////////////////////// diff --git a/source/blender/blenkernel/BKE_collisions.h b/source/blender/blenkernel/BKE_collisions.h index 0536a72d74b..8c7933f3434 100644 --- a/source/blender/blenkernel/BKE_collisions.h +++ b/source/blender/blenkernel/BKE_collisions.h @@ -44,21 +44,21 @@ #include "BKE_DerivedMesh.h" // used in kdop.c and collision.c -typedef struct Tree +typedef struct CollisionTree { - struct Tree *nodes[4]; // 4 children --> quad-tree - struct Tree *parent; - struct Tree *nextLeaf; - struct Tree *prevLeaf; + struct CollisionTree *nodes[4]; // 4 children --> quad-tree + struct CollisionTree *parent; + struct CollisionTree *nextLeaf; + struct CollisionTree *prevLeaf; float bv[26]; // Bounding volume of all nodes / we have 7 axes on a 14-DOP - unsigned int tri_index; // this saves the index of the face + int point_index[4]; // supports up to 4 points in a leaf int count_nodes; // how many nodes are used int traversed; // how many nodes already traversed until this level? int isleaf; } -Tree; +CollisionTree; -typedef struct Tree TreeNode; +typedef struct CollisionTree TreeNode; typedef struct BVH { @@ -79,7 +79,7 @@ BVH; /* used for collisions in kdop.c and also collision.c*/ typedef struct CollisionPair { - unsigned int indexA, indexB; + int point_indexA[4], point_indexB[4]; } CollisionPair; @@ -89,18 +89,21 @@ CollisionPair; ///////////////////////////////////////////////// // builds bounding volume hierarchy -BVH *bvh_build (DerivedMesh *dm, MVert *x, MVert *xold, unsigned int numverts, float epsilon); +BVH *bvh_build (MFace *mfaces, unsigned int numfaces, MVert *x, MVert *xnew, unsigned int numverts, float epsilon); // frees the same void bvh_free ( BVH *bvh ); // checks two bounding volume hierarchies for potential collisions and returns some list with those -int bvh_traverse(Tree *tree1, Tree *tree2, LinkNode *collision_list); +int bvh_traverse(CollisionTree *tree1, CollisionTree *tree2, LinkNode *collision_list); // update bounding volumes, needs updated positions in bvh->x -void bvh_update(DerivedMesh *dm, BVH * bvh, int moving); +void bvh_update(BVH * bvh, int moving); -LinkNode *BLI_linklist_append_fast ( LinkNode **listp, void *ptr ); +LinkNode *BLI_linklist_append_fast (LinkNode **listp, void *ptr); +// move Collision modifier object inter-frame with step = [0,1] +// defined in collisions.c +void collision_move_object(CollisionModifierData *collmd, float step); ///////////////////////////////////////////////// diff --git a/source/blender/blenkernel/BKE_modifier.h b/source/blender/blenkernel/BKE_modifier.h index 365381f5cdd..644c3dd32f4 100644 --- a/source/blender/blenkernel/BKE_modifier.h +++ b/source/blender/blenkernel/BKE_modifier.h @@ -277,7 +277,7 @@ int modifiers_getCageIndex(struct Object *ob, int *lastPossibleCageIndex_r); int modifiers_isSoftbodyEnabled(struct Object *ob); -struct ModifierData *modifiers_isClothEnabled(struct Object *ob); +struct ClothModifierData *modifiers_isClothEnabled(Object *ob); struct Object *modifiers_isDeformedByArmature(struct Object *ob); struct Object *modifiers_isDeformedByLattice(struct Object *ob); int modifiers_usesArmature(struct Object *ob, struct bArmature *arm); diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c index dce36f543ee..4c4bac7bbf9 100644 --- a/source/blender/blenkernel/intern/cloth.c +++ b/source/blender/blenkernel/intern/cloth.c @@ -120,10 +120,9 @@ static CM_SOLVER_DEF solvers [] = /* ********** cloth engine ******* */ /* Prototypes for internal functions. */ -static void cloth_to_object ( Object *ob, ClothModifierData *clmd, float ( *vertexCos ) [3], unsigned int numverts ); +static void cloth_to_object ( Object *ob, ClothModifierData *clmd, DerivedMesh *dm ); static void cloth_from_mesh ( Object *ob, ClothModifierData *clmd, DerivedMesh *dm ); -static int cloth_from_object ( Object *ob, ClothModifierData *clmd, DerivedMesh *dm, float ( *vertexCos ) [3], unsigned int numverts ); -static int collobj_from_object ( Object *ob, ClothModifierData *clmd, DerivedMesh *dm, float ( *vertexCos ) [3], unsigned int numverts ); +static int cloth_from_object ( Object *ob, ClothModifierData *clmd, DerivedMesh *dm ); int cloth_build_springs ( Cloth *cloth, DerivedMesh *dm ); static void cloth_apply_vgroup ( ClothModifierData *clmd, DerivedMesh *dm, short vgroup ); @@ -603,69 +602,63 @@ void cloth_cache_free ( ClothModifierData *clmd, float time ) * cloth_deform_verts - simulates one step, framenr is in frames. * **/ -void clothModifier_do ( ClothModifierData *clmd, Object *ob, DerivedMesh *dm, - float ( *vertexCos ) [3], int numverts ) +DerivedMesh *clothModifier_do(ClothModifierData *clmd, + Object *ob, DerivedMesh *dm) { unsigned int i; - unsigned int numedges = -1; - unsigned int numfaces = -1; - MVert *mvert = NULL; - MEdge *medge = NULL; - MFace *mface = NULL; - DerivedMesh *result = NULL, *result2 = NULL; + DerivedMesh *result = NULL; Cloth *cloth = clmd->clothObject; unsigned int framenr = ( float ) G.scene->r.cfra; float current_time = bsystem_time ( ob, ( float ) G.scene->r.cfra, 0.0 ); - ListBase *effectors = NULL; - ClothVertex *newframe= NULL, *verts; + ListBase *effectors = NULL; + ClothVertex *verts = NULL; Frame *frame = NULL; LinkNode *search = NULL; float deltaTime = current_time - clmd->sim_parms.sim_time; + MVert *mverts = NULL; + + result = CDDM_copy(dm); // only be active during a specific period: // that's "first frame" and "last frame" on GUI - if ( ! ( clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_COLLOBJ ) ) + if ( clmd->clothObject ) { - if ( clmd->clothObject ) + if ( clmd->sim_parms.cache ) { - if ( clmd->sim_parms.cache ) + if ( current_time < clmd->sim_parms.firstframe ) { - if ( current_time < clmd->sim_parms.firstframe ) + int frametime = cloth_cache_first_frame ( clmd ); + if ( cloth_cache_search_frame ( clmd, frametime ) ) { - int frametime = cloth_cache_first_frame ( clmd ); - if ( cloth_cache_search_frame ( clmd, frametime ) ) - { - cloth_cache_get_frame ( clmd, frametime ); - cloth_to_object ( ob, clmd, vertexCos, numverts ); - } - return; - } - else if ( current_time > clmd->sim_parms.lastframe ) - { - int frametime = cloth_cache_last_frame ( clmd ); - if ( cloth_cache_search_frame ( clmd, frametime ) ) - { - cloth_cache_get_frame ( clmd, frametime ); - cloth_to_object ( ob, clmd, vertexCos, numverts ); - } - return; - } - else if ( ABS ( deltaTime ) >= 2.0f ) // no timewarps allowed - { - if ( cloth_cache_search_frame ( clmd, framenr ) ) - { - cloth_cache_get_frame ( clmd, framenr ); - cloth_to_object ( ob, clmd, vertexCos, numverts ); - } - clmd->sim_parms.sim_time = current_time; - return; + cloth_cache_get_frame ( clmd, frametime ); + cloth_to_object ( ob, clmd, result ); } + return; + } + else if ( current_time > clmd->sim_parms.lastframe ) + { + int frametime = cloth_cache_last_frame ( clmd ); + if ( cloth_cache_search_frame ( clmd, frametime ) ) + { + cloth_cache_get_frame ( clmd, frametime ); + cloth_to_object ( ob, clmd, result ); + } + return; + } + else if ( ABS ( deltaTime ) >= 2.0f ) // no timewarps allowed + { + if ( cloth_cache_search_frame ( clmd, framenr ) ) + { + cloth_cache_get_frame ( clmd, framenr ); + cloth_to_object ( ob, clmd, result ); + } + clmd->sim_parms.sim_time = current_time; + return; } - } + } - - + // unused in the moment, calculated seperately in implicit.c clmd->sim_parms.dt = 1.0f / clmd->sim_parms.stepsPerFrame; @@ -673,9 +666,9 @@ void clothModifier_do ( ClothModifierData *clmd, Object *ob, DerivedMesh *dm, if ( deltaTime == 1.0f ) { - if ( ( clmd->clothObject == NULL ) || ( numverts != clmd->clothObject->numverts ) ) + if ( ( clmd->clothObject == NULL ) || ( dm->getNumVerts(dm) != clmd->clothObject->numverts ) ) { - if ( !cloth_from_object ( ob, clmd, dm, vertexCos, numverts ) ) + if ( !cloth_from_object ( ob, clmd, dm ) ) return; if ( clmd->clothObject == NULL ) @@ -692,6 +685,7 @@ void clothModifier_do ( ClothModifierData *clmd, Object *ob, DerivedMesh *dm, if ( !cloth_cache_search_frame ( clmd, framenr ) ) { verts = cloth->verts; + mverts = dm->getVertArray(dm); // Force any pinned verts to their constrained location. for ( i = 0; i < clmd->clothObject->numverts; i++, verts++ ) @@ -699,9 +693,8 @@ void clothModifier_do ( ClothModifierData *clmd, Object *ob, DerivedMesh *dm, // Save the previous position. VECCOPY ( verts->xold, verts->xconst ); VECCOPY ( verts->txold, verts->x ); - // Get the current position. - VECCOPY ( verts->xconst, vertexCos[i] ); + VECCOPY ( verts->xconst, mverts[i].co ); Mat4MulVecfl ( ob->obmat, verts->xconst ); } @@ -723,7 +716,7 @@ void clothModifier_do ( ClothModifierData *clmd, Object *ob, DerivedMesh *dm, } // Copy the result back to the object. - cloth_to_object ( ob, clmd, vertexCos, numverts ); + cloth_to_object ( ob, clmd, result ); // bvh_free(clmd->clothObject->tree); // clmd->clothObject->tree = bvh_build(clmd, clmd->coll_parms.epsilon); @@ -737,11 +730,12 @@ void clothModifier_do ( ClothModifierData *clmd, Object *ob, DerivedMesh *dm, if ( cloth_cache_search_frame ( clmd, framenr ) ) { cloth_cache_get_frame ( clmd, framenr ); - cloth_to_object ( ob, clmd, vertexCos, numverts ); + cloth_to_object ( ob, clmd, result ); } } } - + + return result; } /* frees all */ @@ -771,6 +765,14 @@ void cloth_free_modifier ( ClothModifierData *clmd ) // Free the verts. if ( cloth->verts != NULL ) MEM_freeN ( cloth->verts ); + + // Free the verts. + if ( cloth->x != NULL ) + MEM_freeN ( cloth->x ); + + // Free the verts. + if ( cloth->xnew != NULL ) + MEM_freeN ( cloth->xnew ); cloth->verts = NULL; cloth->numverts = 0; @@ -823,22 +825,24 @@ void cloth_free_modifier ( ClothModifierData *clmd ) * * This function is a modified version of the softbody.c:softbody_to_object() function. **/ -static void cloth_to_object ( Object *ob, ClothModifierData *clmd, float ( *vertexCos ) [3], unsigned int numverts ) +static void cloth_to_object ( Object *ob, ClothModifierData *clmd, DerivedMesh *dm ) { ClothVertex *verts = NULL; unsigned int i = 0; + MVert *mvert = NULL; if ( clmd->clothObject ) { verts = clmd->clothObject->verts; + mvert = dm->getVertArray(dm); /* inverse matrix is not uptodate... */ Mat4Invert ( ob->imat, ob->obmat ); - for ( i = 0; i < numverts; i++, verts++ ) + for ( i = 0; i < dm->getNumVerts(dm); i++, verts++ ) { - VECCOPY ( vertexCos[i], verts->x ); - Mat4MulVecfl ( ob->imat, vertexCos[i] ); /* softbody is in global coords */ + VECCOPY ( mvert[i].co, verts->x ); + Mat4MulVecfl ( ob->imat, mvert[i].co ); /* softbody is in global coords */ } } } @@ -903,7 +907,7 @@ static void cloth_apply_vgroup ( ClothModifierData *clmd, DerivedMesh *dm, short } // only meshes supported at the moment -static int cloth_from_object ( Object *ob, ClothModifierData *clmd, DerivedMesh *dm, float ( *vertexCos ) [3], unsigned int numverts ) +static int cloth_from_object ( Object *ob, ClothModifierData *clmd, DerivedMesh *dm ) { unsigned int i = 0; // dm->getNumVerts(dm); @@ -954,7 +958,7 @@ static int cloth_from_object ( Object *ob, ClothModifierData *clmd, DerivedMesh verts = clmd->clothObject->verts; /* set initial values */ - for ( i = 0; i < numverts; i++, verts++ ) + for ( i = 0; i < dm->getNumVerts(dm); i++, verts++ ) { VECCOPY ( verts->x, mvert[i].co ); Mat4MulVecfl ( ob->obmat, verts->x ); @@ -1021,6 +1025,22 @@ static void cloth_from_mesh ( Object *ob, ClothModifierData *clmd, DerivedMesh * modifier_setError ( & ( clmd->modifier ), "Out of memory on allocating clmd->clothObject->verts." ); return; } + + clmd->clothObject->x = MEM_callocN ( sizeof ( MVert ) * clmd->clothObject->numverts, "Cloth MVert_x" ); + if ( clmd->clothObject->x == NULL ) + { + cloth_free_modifier ( clmd ); + modifier_setError ( & ( clmd->modifier ), "Out of memory on allocating clmd->clothObject->x." ); + return; + } + + clmd->clothObject->xnew = MEM_callocN ( sizeof ( MVert ) * clmd->clothObject->numverts, "Cloth MVert_xnew" ); + if ( clmd->clothObject->xnew == NULL ) + { + cloth_free_modifier ( clmd ); + modifier_setError ( & ( clmd->modifier ), "Out of memory on allocating clmd->clothObject->xnew." ); + return; + } // save face information clmd->clothObject->numfaces = numfaces; @@ -1067,7 +1087,10 @@ int cloth_add_spring ( ClothModifierData *clmd, unsigned int indexA, unsigned in cloth->numsprings++; BLI_linklist_append ( &cloth->springs, spring ); + + return 1; } + return 0; } int cloth_build_springs ( Cloth *cloth, DerivedMesh *dm ) diff --git a/source/blender/blenkernel/intern/collision.c b/source/blender/blenkernel/intern/collision.c index 41823b0ad39..f4b0ce7312b 100644 --- a/source/blender/blenkernel/intern/collision.c +++ b/source/blender/blenkernel/intern/collision.c @@ -72,6 +72,22 @@ #include "Bullet-C-Api.h" +// step is limited from 0 (frame start position) to 1 (frame end position) +void collision_move_object(CollisionModifierData *collmd, float step) +{ + float tv[3] = {0,0,0}; + unsigned int i = 0; + MVert *tempVert = collmd->current_x; + collmd->current_x = collmd->current_xnew; + collmd->current_xnew = tempVert; + + for ( i = 0; i < collmd->numverts; i++ ) + { + VECSUB(tv, collmd->xnew[i].co, collmd->x[i].co); + VECADDS(collmd->current_xnew[i].co, collmd->x[i].co, tv, step); + } +} + /** * gsl_poly_solve_cubic - @@ -362,846 +378,3 @@ DO_INLINE void interpolateOnTriangle(float to[3], float v1[3], float v2[3], floa VECADDMUL(to, v3, w3); } -// unused in the moment, has some bug in -DO_INLINE void calculateFrictionImpulse(float to[3], float vrel[3], float normal[3], double normalVelocity, - double frictionConstant, double delta_V_n) -{ - float vrel_t_pre[3]; - float vrel_t[3]; - VECSUBS(vrel_t_pre, vrel, normal, normalVelocity); - VECCOPY(to, vrel_t_pre); - VecMulf(to, MAX2(1.0f - frictionConstant * delta_V_n / INPR(vrel_t_pre,vrel_t_pre), 0.0f)); -} - -int collisions_collision_response_static(ClothModifierData *clmd, ClothModifierData *coll_clmd) -{ - /* - unsigned int i = 0; - int result = 0; - LinkNode *search = NULL; - CollPair *collpair = NULL; - Cloth *cloth1, *cloth2; - float w1, w2, w3, u1, u2, u3; - float v1[3], v2[3], relativeVelocity[3]; - float magrelVel; - - cloth1 = clmd->clothObject; - cloth2 = coll_clmd->clothObject; - - // search = clmd->coll_parms.collision_list; - - while(search) - { - collpair = search->link; - - // compute barycentric coordinates for both collision points - collisions_compute_barycentric(collpair->pa, - cloth1->verts[collpair->ap1].txold, - cloth1->verts[collpair->ap2].txold, - cloth1->verts[collpair->ap3].txold, - &w1, &w2, &w3); - - collisions_compute_barycentric(collpair->pb, - cloth2->verts[collpair->bp1].txold, - cloth2->verts[collpair->bp2].txold, - cloth2->verts[collpair->bp3].txold, - &u1, &u2, &u3); - - // Calculate relative "velocity". - interpolateOnTriangle(v1, cloth1->verts[collpair->ap1].tv, cloth1->verts[collpair->ap2].tv, cloth1->verts[collpair->ap3].tv, w1, w2, w3); - - interpolateOnTriangle(v2, cloth2->verts[collpair->bp1].tv, cloth2->verts[collpair->bp2].tv, cloth2->verts[collpair->bp3].tv, u1, u2, u3); - - VECSUB(relativeVelocity, v1, v2); - - // Calculate the normal component of the relative velocity (actually only the magnitude - the direction is stored in 'normal'). - magrelVel = INPR(relativeVelocity, collpair->normal); - - // printf("magrelVel: %f\n", magrelVel); - - // Calculate masses of points. - - // If v_n_mag < 0 the edges are approaching each other. - if(magrelVel < -ALMOST_ZERO) - { - // Calculate Impulse magnitude to stop all motion in normal direction. - // const double I_mag = v_n_mag / (1/m1 + 1/m2); - float magnitude_i = magrelVel / 2.0f; // TODO implement masses - float tangential[3], magtangent, magnormal, collvel[3]; - float vrel_t_pre[3]; - float vrel_t[3]; - double impulse; - float epsilon = clmd->coll_parms.epsilon; - float overlap = (epsilon + ALMOST_ZERO-collpair->distance); - - // calculateFrictionImpulse(tangential, relativeVelocity, collpair->normal, magrelVel, clmd->coll_parms.friction*0.01, magrelVel); - - // magtangent = INPR(tangential, tangential); - - // Apply friction impulse. - if (magtangent < -ALMOST_ZERO) - { - - // printf("friction applied: %f\n", magtangent); - // TODO check original code - } - - - impulse = -2.0f * magrelVel / ( 1.0 + w1*w1 + w2*w2 + w3*w3); - - // printf("impulse: %f\n", impulse); - - // face A - VECADDMUL(cloth1->verts[collpair->ap1].impulse, collpair->normal, w1 * impulse); - cloth1->verts[collpair->ap1].impulse_count++; - - VECADDMUL(cloth1->verts[collpair->ap2].impulse, collpair->normal, w2 * impulse); - cloth1->verts[collpair->ap2].impulse_count++; - - VECADDMUL(cloth1->verts[collpair->ap3].impulse, collpair->normal, w3 * impulse); - cloth1->verts[collpair->ap3].impulse_count++; - - // face B - VECADDMUL(cloth2->verts[collpair->bp1].impulse, collpair->normal, u1 * impulse); - cloth2->verts[collpair->bp1].impulse_count++; - - VECADDMUL(cloth2->verts[collpair->bp2].impulse, collpair->normal, u2 * impulse); - cloth2->verts[collpair->bp2].impulse_count++; - - VECADDMUL(cloth2->verts[collpair->bp3].impulse, collpair->normal, u3 * impulse); - cloth2->verts[collpair->bp3].impulse_count++; - - - result = 1; - - // printf("magnitude_i: %f\n", magnitude_i); // negative before collision in my case - - // Apply the impulse and increase impulse counters. - - - } - - search = search->next; - } - - - return result; - */ - return 0; -} - - -int collisions_collision_response_moving_tris(ClothModifierData *clmd, ClothModifierData *coll_clmd) -{ - -} - - -int collisions_collision_response_moving_edges(ClothModifierData *clmd, ClothModifierData *coll_clmd) -{ - -} - -void cloth_collision_static(ClothModifierData *clmd, ClothModifierData *coll_clmd, Tree *tree1, Tree *tree2) -{ - /* - CollPair *collpair = NULL; - Cloth *cloth1=NULL, *cloth2=NULL; - MFace *face1=NULL, *face2=NULL; - ClothVertex *verts1=NULL, *verts2=NULL; - double distance = 0; - float epsilon = clmd->coll_parms.epsilon; - unsigned int i = 0; - - for(i = 0; i < 4; i++) - { - collpair = (CollPair *)MEM_callocN(sizeof(CollPair), "cloth coll pair"); - - cloth1 = clmd->clothObject; - cloth2 = coll_clmd->clothObject; - - verts1 = cloth1->verts; - verts2 = cloth2->verts; - - face1 = &(cloth1->mfaces[tree1->tri_index]); - face2 = &(cloth2->mfaces[tree2->tri_index]); - - // check all possible pairs of triangles - if(i == 0) - { - collpair->ap1 = face1->v1; - collpair->ap2 = face1->v2; - collpair->ap3 = face1->v3; - - collpair->bp1 = face2->v1; - collpair->bp2 = face2->v2; - collpair->bp3 = face2->v3; - - } - - if(i == 1) - { - if(face1->v4) - { - collpair->ap1 = face1->v3; - collpair->ap2 = face1->v4; - collpair->ap3 = face1->v1; - - collpair->bp1 = face2->v1; - collpair->bp2 = face2->v2; - collpair->bp3 = face2->v3; - } - else - i++; - } - - if(i == 2) - { - if(face2->v4) - { - collpair->ap1 = face1->v1; - collpair->ap2 = face1->v2; - collpair->ap3 = face1->v3; - - collpair->bp1 = face2->v3; - collpair->bp2 = face2->v4; - collpair->bp3 = face2->v1; - } - else - i+=2; - } - - if(i == 3) - { - if((face1->v4)&&(face2->v4)) - { - collpair->ap1 = face1->v3; - collpair->ap2 = face1->v4; - collpair->ap3 = face1->v1; - - collpair->bp1 = face2->v3; - collpair->bp2 = face2->v4; - collpair->bp3 = face2->v1; - } - else - i++; - } - - // calc SIPcode (?) - - if(i < 4) - { - // calc distance + normal - distance = plNearestPoints( - verts1[collpair->ap1].txold, verts1[collpair->ap2].txold, verts1[collpair->ap3].txold, verts2[collpair->bp1].txold, verts2[collpair->bp2].txold, verts2[collpair->bp3].txold, collpair->pa,collpair->pb,collpair->vector); - - if (distance <= (epsilon + ALMOST_ZERO)) - { - // printf("dist: %f\n", (float)distance); - - // collpair->face1 = tree1->tri_index; - // collpair->face2 = tree2->tri_index; - - // VECCOPY(collpair->normal, collpair->vector); - // Normalize(collpair->normal); - - // collpair->distance = distance; - - } - else - { - MEM_freeN(collpair); - } - } - else - { - MEM_freeN(collpair); - } - } - */ -} - -int collisions_are_edges_adjacent(ClothModifierData *clmd, ClothModifierData *coll_clmd, EdgeCollPair *edgecollpair) -{ - Cloth *cloth1, *cloth2; - ClothVertex *verts1, *verts2; - float temp[3]; - - cloth1 = clmd->clothObject; - cloth2 = coll_clmd->clothObject; - - verts1 = cloth1->verts; - verts2 = cloth2->verts; - - VECSUB(temp, verts1[edgecollpair->p11].xold, verts2[edgecollpair->p21].xold); - if(ABS(INPR(temp, temp)) < ALMOST_ZERO) - return 1; - - VECSUB(temp, verts1[edgecollpair->p11].xold, verts2[edgecollpair->p22].xold); - if(ABS(INPR(temp, temp)) < ALMOST_ZERO) - return 1; - - VECSUB(temp, verts1[edgecollpair->p12].xold, verts2[edgecollpair->p21].xold); - if(ABS(INPR(temp, temp)) < ALMOST_ZERO) - return 1; - - VECSUB(temp, verts1[edgecollpair->p12].xold, verts2[edgecollpair->p22].xold); - if(ABS(INPR(temp, temp)) < ALMOST_ZERO) - return 1; - - return 0; -} - -void collisions_collision_moving_edges(ClothModifierData *clmd, ClothModifierData *coll_clmd, Tree *tree1, Tree *tree2) -{ - EdgeCollPair edgecollpair; - Cloth *cloth1=NULL, *cloth2=NULL; - MFace *face1=NULL, *face2=NULL; - ClothVertex *verts1=NULL, *verts2=NULL; - double distance = 0; - float epsilon = clmd->coll_parms.epsilon; - unsigned int i = 0, j = 0, k = 0; - int numsolutions = 0; - float a[3], b[3], c[3], d[3], e[3], f[3], solution[3]; - - cloth1 = clmd->clothObject; - cloth2 = coll_clmd->clothObject; - - verts1 = cloth1->verts; - verts2 = cloth2->verts; - - face1 = &(cloth1->mfaces[tree1->tri_index]); - face2 = &(cloth2->mfaces[tree2->tri_index]); - - for( i = 0; i < 5; i++) - { - if(i == 0) - { - edgecollpair.p11 = face1->v1; - edgecollpair.p12 = face1->v2; - } - else if(i == 1) - { - edgecollpair.p11 = face1->v2; - edgecollpair.p12 = face1->v3; - } - else if(i == 2) - { - if(face1->v4) - { - edgecollpair.p11 = face1->v3; - edgecollpair.p12 = face1->v4; - } - else - { - edgecollpair.p11 = face1->v3; - edgecollpair.p12 = face1->v1; - i+=5; // get out of here after this edge pair is handled - } - } - else if(i == 3) - { - if(face1->v4) - { - edgecollpair.p11 = face1->v4; - edgecollpair.p12 = face1->v1; - } - else - continue; - } - else - { - edgecollpair.p11 = face1->v3; - edgecollpair.p12 = face1->v1; - } - - - for( j = 0; j < 5; j++) - { - if(j == 0) - { - edgecollpair.p21 = face2->v1; - edgecollpair.p22 = face2->v2; - } - else if(j == 1) - { - edgecollpair.p21 = face2->v2; - edgecollpair.p22 = face2->v3; - } - else if(j == 2) - { - if(face2->v4) - { - edgecollpair.p21 = face2->v3; - edgecollpair.p22 = face2->v4; - } - else - { - edgecollpair.p21 = face2->v3; - edgecollpair.p22 = face2->v1; - } - } - else if(j == 3) - { - if(face2->v4) - { - edgecollpair.p21 = face2->v4; - edgecollpair.p22 = face2->v1; - } - else - continue; - } - else - { - edgecollpair.p21 = face2->v3; - edgecollpair.p22 = face2->v1; - } - - - if(!collisions_are_edges_adjacent(clmd, coll_clmd, &edgecollpair)) - { - VECSUB(a, verts1[edgecollpair.p12].xold, verts1[edgecollpair.p11].xold); - VECSUB(b, verts1[edgecollpair.p12].v, verts1[edgecollpair.p11].v); - VECSUB(c, verts1[edgecollpair.p21].xold, verts1[edgecollpair.p11].xold); - VECSUB(d, verts1[edgecollpair.p21].v, verts1[edgecollpair.p11].v); - VECSUB(e, verts2[edgecollpair.p22].xold, verts1[edgecollpair.p11].xold); - VECSUB(f, verts2[edgecollpair.p22].v, verts1[edgecollpair.p11].v); - - numsolutions = collisions_get_collision_time(a, b, c, d, e, f, solution); - - for (k = 0; k < numsolutions; k++) - { - if ((solution[k] >= 0.0) && (solution[k] <= 1.0)) - { - float out_collisionTime = solution[k]; - - // TODO: check for collisions - - // TODO: put into (edge) collision list - - printf("Moving edge found!\n"); - } - } - } - } - } -} - -void collisions_collision_moving_tris(ClothModifierData *clmd, ClothModifierData *coll_clmd, Tree *tree1, Tree *tree2) -{ - /* - CollPair collpair; - Cloth *cloth1=NULL, *cloth2=NULL; - MFace *face1=NULL, *face2=NULL; - ClothVertex *verts1=NULL, *verts2=NULL; - double distance = 0; - float epsilon = clmd->coll_parms.epsilon; - unsigned int i = 0, j = 0, k = 0; - int numsolutions = 0; - float a[3], b[3], c[3], d[3], e[3], f[3], solution[3]; - - for(i = 0; i < 2; i++) - { - cloth1 = clmd->clothObject; - cloth2 = coll_clmd->clothObject; - - verts1 = cloth1->verts; - verts2 = cloth2->verts; - - face1 = &(cloth1->mfaces[tree1->tri_index]); - face2 = &(cloth2->mfaces[tree2->tri_index]); - - // check all possible pairs of triangles - if(i == 0) - { - collpair.ap1 = face1->v1; - collpair.ap2 = face1->v2; - collpair.ap3 = face1->v3; - - collpair.pointsb[0] = face2->v1; - collpair.pointsb[1] = face2->v2; - collpair.pointsb[2] = face2->v3; - collpair.pointsb[3] = face2->v4; - } - - if(i == 1) - { - if(face1->v4) - { - collpair.ap1 = face1->v3; - collpair.ap2 = face1->v4; - collpair.ap3 = face1->v1; - - collpair.pointsb[0] = face2->v1; - collpair.pointsb[1] = face2->v2; - collpair.pointsb[2] = face2->v3; - collpair.pointsb[3] = face2->v4; - } - else - i++; - } - - // calc SIPcode (?) - - if(i < 2) - { - VECSUB(a, verts1[collpair.ap2].xold, verts1[collpair.ap1].xold); - VECSUB(b, verts1[collpair.ap2].v, verts1[collpair.ap1].v); - VECSUB(c, verts1[collpair.ap3].xold, verts1[collpair.ap1].xold); - VECSUB(d, verts1[collpair.ap3].v, verts1[collpair.ap1].v); - - for(j = 0; j < 4; j++) - { - if((j==3) && !(face2->v4)) - break; - - VECSUB(e, verts2[collpair.pointsb[j]].xold, verts1[collpair.ap1].xold); - VECSUB(f, verts2[collpair.pointsb[j]].v, verts1[collpair.ap1].v); - - numsolutions = collisions_get_collision_time(a, b, c, d, e, f, solution); - - for (k = 0; k < numsolutions; k++) - { - if ((solution[k] >= 0.0) && (solution[k] <= 1.0)) - { - float out_collisionTime = solution[k]; - - // TODO: check for collisions - - // TODO: put into (point-face) collision list - - printf("Moving found!\n"); - - } - } - - // TODO: check borders for collisions - } - - } - } - */ -} - -void collisions_collision_moving(ClothModifierData *clmd, ClothModifierData *coll_clmd, Tree *tree1, Tree *tree2) -{ - /* - // TODO: check for adjacent - collisions_collision_moving_edges(clmd, coll_clmd, tree1, tree2); - - collisions_collision_moving_tris(clmd, coll_clmd, tree1, tree2); - collisions_collision_moving_tris(coll_clmd, clmd, tree2, tree1); - */ -} - -// move collision objects forward in time and update static bounding boxes -void collisions_update_collision_objects(float step) -{ - Base *base=NULL; - ClothModifierData *coll_clmd=NULL; - Object *coll_ob=NULL; - unsigned int i=0; - - // search all objects for collision object - for (base = G.scene->base.first; base; base = base->next) - { - - coll_ob = base->object; - coll_clmd = (ClothModifierData *) modifiers_findByType (coll_ob, eModifierType_Cloth); - if (!coll_clmd) - continue; - - // if collision object go on - if (coll_clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_COLLOBJ) - { - if (coll_clmd->clothObject && coll_clmd->clothObject->tree) - { - Cloth *coll_cloth = coll_clmd->clothObject; - BVH *coll_bvh = coll_clmd->clothObject->tree; - unsigned int coll_numverts = coll_cloth->numverts; - - // update position of collision object - for(i = 0; i < coll_numverts; i++) - { - VECCOPY(coll_cloth->verts[i].txold, coll_cloth->verts[i].tx); - - VECADDS(coll_cloth->verts[i].tx, coll_cloth->verts[i].xold, coll_cloth->verts[i].v, step); - - // no dt here because of float rounding errors - VECSUB(coll_cloth->verts[i].tv, coll_cloth->verts[i].tx, coll_cloth->verts[i].txold); - } - - // update BVH of collision object - // bvh_update(coll_clmd, coll_bvh, 0); // 0 means STATIC, 1 means MOVING - } - else - printf ("collisions_bvh_objcollision: found a collision object with clothObject or collData NULL.\n"); - } - } -} - -// collisions_MAX_THRESHOLD defines how much collision rounds/loops should be taken -#define CLOTH_MAX_THRESHOLD 10 - -// cloth - object collisions -int cloth_bvh_objcollision(ClothModifierData * clmd, float step, float dt) -{ - Base *base=NULL; - ClothModifierData *coll_clmd=NULL; - Cloth *cloth=NULL; - Object *coll_ob=NULL; - BVH *collisions_bvh=NULL; - unsigned int i=0, j = 0, numfaces = 0, numverts = 0; - unsigned int result = 0, ic = 0, rounds = 0; // result counts applied collisions; ic is for debug output; - ClothVertex *verts = NULL; - float tnull[3] = {0,0,0}; - int ret = 0; - LinkNode *collision_list = NULL; - - if ((clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_COLLOBJ) || !(((Cloth *)clmd->clothObject)->tree)) - { - return 0; - } - cloth = clmd->clothObject; - verts = cloth->verts; - collisions_bvh = (BVH *) cloth->tree; - numfaces = clmd->clothObject->numfaces; - numverts = clmd->clothObject->numverts; - - //////////////////////////////////////////////////////////// - // static collisions - //////////////////////////////////////////////////////////// - - // update cloth bvh - // bvh_update(clmd, collisions_bvh, 0); // 0 means STATIC, 1 means MOVING (see later in this function) - - // update collision objects - collisions_update_collision_objects(step); - - do - { - result = 0; - ic = 0; - - // check all collision objects - for (base = G.scene->base.first; base; base = base->next) - { - coll_ob = base->object; - coll_clmd = (ClothModifierData *) modifiers_findByType (coll_ob, eModifierType_Cloth); - - if (!coll_clmd) - continue; - - // if collision object go on - if (coll_clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_COLLOBJ) - { - if (coll_clmd->clothObject && coll_clmd->clothObject->tree) - { - BVH *coll_bvh = coll_clmd->clothObject->tree; - - // fill collision list - bvh_traverse(collisions_bvh->root, coll_bvh->root, collision_list); - - // process all collisions (calculate impulses, TODO: also repulses if distance too short) - result = 1; - for(j = 0; j < 10; j++) // 10 is just a value that ensures convergence - { - result = 0; - - // result += collisions_collision_response_static_tris(clmd, coll_clmd, collision_list, 0); - - // result += collisions_collision_response_static_tris(coll_clmd, clmd, collision_list, 1); - - // apply impulses in parallel - ic=0; - for(i = 0; i < numverts; i++) - { - // calculate "velocities" (just xnew = xold + v; no dt in v) - if(verts[i].impulse_count) - { - VECADDMUL(verts[i].tv, verts[i].impulse, 1.0f / verts[i].impulse_count); - VECCOPY(verts[i].impulse, tnull); - verts[i].impulse_count = 0; - - ic++; - ret++; - } - } - } - - // free collision list - if(collision_list) - { - LinkNode *search = collision_list; - while(search) - { - CollisionPair *coll_pair = search->link; - - MEM_freeN(coll_pair); - search = search->next; - } - BLI_linklist_free(collision_list,NULL); - - collision_list = NULL; - } - } - else - printf ("collisions_bvh_objcollision: found a collision object with clothObject or collData NULL.\n"); - } - } - - printf("ic: %d\n", ic); - rounds++; - } - while(result && (CLOTH_MAX_THRESHOLD>rounds)); - - printf("\n"); - - //////////////////////////////////////////////////////////// - // update positions - // this is needed for bvh_calc_DOP_hull_moving() [kdop.c] - //////////////////////////////////////////////////////////// - - // verts come from clmd - for(i = 0; i < numverts; i++) - { - VECADD(verts[i].tx, verts[i].txold, verts[i].tv); - } - //////////////////////////////////////////////////////////// - - //////////////////////////////////////////////////////////// - // moving collisions - //////////////////////////////////////////////////////////// - - - // update cloth bvh - // bvh_update(clmd, collisions_bvh, 1); // 0 means STATIC, 1 means MOVING - - // update moving bvh for collision object once - for (base = G.scene->base.first; base; base = base->next) - { - - coll_ob = base->object; - coll_clmd = (ClothModifierData *) modifiers_findByType (coll_ob, eModifierType_Cloth); - if (!coll_clmd) - continue; - - if(!coll_clmd->clothObject) - continue; - - // if collision object go on - if (coll_clmd->clothObject && coll_clmd->clothObject->tree) - { - BVH *coll_bvh = coll_clmd->clothObject->tree; - - // bvh_update(coll_clmd, coll_bvh, 1); // 0 means STATIC, 1 means MOVING - } - } - - - do - { - result = 0; - ic = 0; - - // check all collision objects - for (base = G.scene->base.first; base; base = base->next) - { - coll_ob = base->object; - coll_clmd = (ClothModifierData *) modifiers_findByType (coll_ob, eModifierType_Cloth); - - if (!coll_clmd) - continue; - - // if collision object go on - if (coll_clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_COLLOBJ) - { - if (coll_clmd->clothObject && coll_clmd->clothObject->tree) - { - BVH *coll_bvh = coll_clmd->clothObject->tree; - - bvh_traverse(collisions_bvh->root, coll_bvh->root, collision_list); - - // process all collisions (calculate impulses, TODO: also repulses if distance too short) - result = 1; - for(j = 0; j < 10; j++) // 10 is just a value that ensures convergence - { - result = 0; - - // handle all collision objects - - /* - if (coll_clmd->clothObject) - result += collisions_collision_response_moving_tris(clmd, coll_clmd); - else - printf ("collisions_bvh_objcollision: found a collision object with clothObject or collData NULL.\n"); - */ - - // apply impulses in parallel - ic=0; - for(i = 0; i < numverts; i++) - { - // calculate "velocities" (just xnew = xold + v; no dt in v) - if(verts[i].impulse_count) - { - VECADDMUL(verts[i].tv, verts[i].impulse, 1.0f / verts[i].impulse_count); - VECCOPY(verts[i].impulse, tnull); - verts[i].impulse_count = 0; - - ic++; - ret++; - } - } - } - - - // verts come from clmd - for(i = 0; i < numverts; i++) - { - VECADD(verts[i].tx, verts[i].txold, verts[i].tv); - } - - // update cloth bvh - // bvh_update(clmd, collisions_bvh, 1); // 0 means STATIC, 1 means MOVING - - - // free collision list - if(collision_list) - { - LinkNode *search = collision_list; - while(search) - { - CollisionPair *coll_pair = search->link; - - MEM_freeN(coll_pair); - search = search->next; - } - BLI_linklist_free(collision_list,NULL); - - collision_list = NULL; - } - } - else - printf ("collisions_bvh_objcollision: found a collision object with clothObject or collData NULL.\n"); - } - } - - printf("ic: %d\n", ic); - rounds++; - } - while(result && (CLOTH_MAX_THRESHOLD>rounds)); - - - //////////////////////////////////////////////////////////// - // update positions + velocities - //////////////////////////////////////////////////////////// - - // verts come from clmd - for(i = 0; i < numverts; i++) - { - VECADD(verts[i].tx, verts[i].txold, verts[i].tv); - } - //////////////////////////////////////////////////////////// - - return MIN2(ret, 1); -} diff --git a/source/blender/blenkernel/intern/implicit.c b/source/blender/blenkernel/intern/implicit.c index 2ce00d0e38c..f61e2d22f1c 100644 --- a/source/blender/blenkernel/intern/implicit.c +++ b/source/blender/blenkernel/intern/implicit.c @@ -49,6 +49,7 @@ #include "BLI_blenlib.h" #include "BLI_arithb.h" #include "BLI_threads.h" +#include "BKE_collisions.h" #include "BKE_curve.h" #include "BKE_displist.h" #include "BKE_effect.h" @@ -1585,3 +1586,841 @@ void implicit_set_positions (ClothModifierData *clmd) VECCOPY(id->V[i], verts[i].v); } } + + +int collisions_collision_response_static(ClothModifierData *clmd, ClothModifierData *coll_clmd) +{ + /* + unsigned int i = 0; + int result = 0; + LinkNode *search = NULL; + CollPair *collpair = NULL; + Cloth *cloth1, *cloth2; + float w1, w2, w3, u1, u2, u3; + float v1[3], v2[3], relativeVelocity[3]; + float magrelVel; + + cloth1 = clmd->clothObject; + cloth2 = coll_clmd->clothObject; + + // search = clmd->coll_parms.collision_list; + + while(search) + { + collpair = search->link; + + // compute barycentric coordinates for both collision points + collisions_compute_barycentric(collpair->pa, + cloth1->verts[collpair->ap1].txold, + cloth1->verts[collpair->ap2].txold, + cloth1->verts[collpair->ap3].txold, + &w1, &w2, &w3); + + collisions_compute_barycentric(collpair->pb, + cloth2->verts[collpair->bp1].txold, + cloth2->verts[collpair->bp2].txold, + cloth2->verts[collpair->bp3].txold, + &u1, &u2, &u3); + + // Calculate relative "velocity". + interpolateOnTriangle(v1, cloth1->verts[collpair->ap1].tv, cloth1->verts[collpair->ap2].tv, cloth1->verts[collpair->ap3].tv, w1, w2, w3); + + interpolateOnTriangle(v2, cloth2->verts[collpair->bp1].tv, cloth2->verts[collpair->bp2].tv, cloth2->verts[collpair->bp3].tv, u1, u2, u3); + + VECSUB(relativeVelocity, v1, v2); + + // Calculate the normal component of the relative velocity (actually only the magnitude - the direction is stored in 'normal'). + magrelVel = INPR(relativeVelocity, collpair->normal); + + // printf("magrelVel: %f\n", magrelVel); + + // Calculate masses of points. + + // If v_n_mag < 0 the edges are approaching each other. + if(magrelVel < -ALMOST_ZERO) + { + // Calculate Impulse magnitude to stop all motion in normal direction. + // const double I_mag = v_n_mag / (1/m1 + 1/m2); + float magnitude_i = magrelVel / 2.0f; // TODO implement masses + float tangential[3], magtangent, magnormal, collvel[3]; + float vrel_t_pre[3]; + float vrel_t[3]; + double impulse; + float epsilon = clmd->coll_parms.epsilon; + float overlap = (epsilon + ALMOST_ZERO-collpair->distance); + + // calculateFrictionImpulse(tangential, relativeVelocity, collpair->normal, magrelVel, clmd->coll_parms.friction*0.01, magrelVel); + + // magtangent = INPR(tangential, tangential); + + // Apply friction impulse. + if (magtangent < -ALMOST_ZERO) + { + + // printf("friction applied: %f\n", magtangent); + // TODO check original code +} + + + impulse = -2.0f * magrelVel / ( 1.0 + w1*w1 + w2*w2 + w3*w3); + + // printf("impulse: %f\n", impulse); + + // face A + VECADDMUL(cloth1->verts[collpair->ap1].impulse, collpair->normal, w1 * impulse); + cloth1->verts[collpair->ap1].impulse_count++; + + VECADDMUL(cloth1->verts[collpair->ap2].impulse, collpair->normal, w2 * impulse); + cloth1->verts[collpair->ap2].impulse_count++; + + VECADDMUL(cloth1->verts[collpair->ap3].impulse, collpair->normal, w3 * impulse); + cloth1->verts[collpair->ap3].impulse_count++; + + // face B + VECADDMUL(cloth2->verts[collpair->bp1].impulse, collpair->normal, u1 * impulse); + cloth2->verts[collpair->bp1].impulse_count++; + + VECADDMUL(cloth2->verts[collpair->bp2].impulse, collpair->normal, u2 * impulse); + cloth2->verts[collpair->bp2].impulse_count++; + + VECADDMUL(cloth2->verts[collpair->bp3].impulse, collpair->normal, u3 * impulse); + cloth2->verts[collpair->bp3].impulse_count++; + + + result = 1; + + // printf("magnitude_i: %f\n", magnitude_i); // negative before collision in my case + + // Apply the impulse and increase impulse counters. + + +} + + search = search->next; +} + + + return result; + */ + return 0; +} + + +int collisions_collision_response_moving_tris(ClothModifierData *clmd, ClothModifierData *coll_clmd) +{ + +} + + +int collisions_collision_response_moving_edges(ClothModifierData *clmd, ClothModifierData *coll_clmd) +{ + +} + +void cloth_collision_static(ClothModifierData *clmd, ClothModifierData *coll_clmd, CollisionTree *tree1, CollisionTree *tree2) +{ + /* + CollPair *collpair = NULL; + Cloth *cloth1=NULL, *cloth2=NULL; + MFace *face1=NULL, *face2=NULL; + ClothVertex *verts1=NULL, *verts2=NULL; + double distance = 0; + float epsilon = clmd->coll_parms.epsilon; + unsigned int i = 0; + + for(i = 0; i < 4; i++) + { + collpair = (CollPair *)MEM_callocN(sizeof(CollPair), "cloth coll pair"); + + cloth1 = clmd->clothObject; + cloth2 = coll_clmd->clothObject; + + verts1 = cloth1->verts; + verts2 = cloth2->verts; + + face1 = &(cloth1->mfaces[tree1->tri_index]); + face2 = &(cloth2->mfaces[tree2->tri_index]); + + // check all possible pairs of triangles + if(i == 0) + { + collpair->ap1 = face1->v1; + collpair->ap2 = face1->v2; + collpair->ap3 = face1->v3; + + collpair->bp1 = face2->v1; + collpair->bp2 = face2->v2; + collpair->bp3 = face2->v3; + +} + + if(i == 1) + { + if(face1->v4) + { + collpair->ap1 = face1->v3; + collpair->ap2 = face1->v4; + collpair->ap3 = face1->v1; + + collpair->bp1 = face2->v1; + collpair->bp2 = face2->v2; + collpair->bp3 = face2->v3; +} + else + i++; +} + + if(i == 2) + { + if(face2->v4) + { + collpair->ap1 = face1->v1; + collpair->ap2 = face1->v2; + collpair->ap3 = face1->v3; + + collpair->bp1 = face2->v3; + collpair->bp2 = face2->v4; + collpair->bp3 = face2->v1; +} + else + i+=2; +} + + if(i == 3) + { + if((face1->v4)&&(face2->v4)) + { + collpair->ap1 = face1->v3; + collpair->ap2 = face1->v4; + collpair->ap3 = face1->v1; + + collpair->bp1 = face2->v3; + collpair->bp2 = face2->v4; + collpair->bp3 = face2->v1; +} + else + i++; +} + + // calc SIPcode (?) + + if(i < 4) + { + // calc distance + normal + distance = plNearestPoints( + verts1[collpair->ap1].txold, verts1[collpair->ap2].txold, verts1[collpair->ap3].txold, verts2[collpair->bp1].txold, verts2[collpair->bp2].txold, verts2[collpair->bp3].txold, collpair->pa,collpair->pb,collpair->vector); + + if (distance <= (epsilon + ALMOST_ZERO)) + { + // printf("dist: %f\n", (float)distance); + + // collpair->face1 = tree1->tri_index; + // collpair->face2 = tree2->tri_index; + + // VECCOPY(collpair->normal, collpair->vector); + // Normalize(collpair->normal); + + // collpair->distance = distance; + +} + else + { + MEM_freeN(collpair); +} +} + else + { + MEM_freeN(collpair); +} +} + */ +} + +int collisions_are_edges_adjacent(ClothModifierData *clmd, ClothModifierData *coll_clmd, EdgeCollPair *edgecollpair) +{ + Cloth *cloth1, *cloth2; + ClothVertex *verts1, *verts2; + float temp[3]; + + cloth1 = clmd->clothObject; + cloth2 = coll_clmd->clothObject; + + verts1 = cloth1->verts; + verts2 = cloth2->verts; + + VECSUB(temp, verts1[edgecollpair->p11].xold, verts2[edgecollpair->p21].xold); + if(ABS(INPR(temp, temp)) < ALMOST_ZERO) + return 1; + + VECSUB(temp, verts1[edgecollpair->p11].xold, verts2[edgecollpair->p22].xold); + if(ABS(INPR(temp, temp)) < ALMOST_ZERO) + return 1; + + VECSUB(temp, verts1[edgecollpair->p12].xold, verts2[edgecollpair->p21].xold); + if(ABS(INPR(temp, temp)) < ALMOST_ZERO) + return 1; + + VECSUB(temp, verts1[edgecollpair->p12].xold, verts2[edgecollpair->p22].xold); + if(ABS(INPR(temp, temp)) < ALMOST_ZERO) + return 1; + + return 0; +} + + +void collisions_collision_moving_edges(ClothModifierData *clmd, ClothModifierData *coll_clmd, CollisionTree *tree1, CollisionTree *tree2) +{ + /* + EdgeCollPair edgecollpair; + Cloth *cloth1=NULL, *cloth2=NULL; + MFace *face1=NULL, *face2=NULL; + ClothVertex *verts1=NULL, *verts2=NULL; + double distance = 0; + float epsilon = clmd->coll_parms.epsilon; + unsigned int i = 0, j = 0, k = 0; + int numsolutions = 0; + float a[3], b[3], c[3], d[3], e[3], f[3], solution[3]; + + cloth1 = clmd->clothObject; + cloth2 = coll_clmd->clothObject; + + verts1 = cloth1->verts; + verts2 = cloth2->verts; + + face1 = &(cloth1->mfaces[tree1->tri_index]); + face2 = &(cloth2->mfaces[tree2->tri_index]); + + for( i = 0; i < 5; i++) + { + if(i == 0) + { + edgecollpair.p11 = face1->v1; + edgecollpair.p12 = face1->v2; +} + else if(i == 1) + { + edgecollpair.p11 = face1->v2; + edgecollpair.p12 = face1->v3; +} + else if(i == 2) + { + if(face1->v4) + { + edgecollpair.p11 = face1->v3; + edgecollpair.p12 = face1->v4; +} + else + { + edgecollpair.p11 = face1->v3; + edgecollpair.p12 = face1->v1; + i+=5; // get out of here after this edge pair is handled +} +} + else if(i == 3) + { + if(face1->v4) + { + edgecollpair.p11 = face1->v4; + edgecollpair.p12 = face1->v1; +} + else + continue; +} + else + { + edgecollpair.p11 = face1->v3; + edgecollpair.p12 = face1->v1; +} + + + for( j = 0; j < 5; j++) + { + if(j == 0) + { + edgecollpair.p21 = face2->v1; + edgecollpair.p22 = face2->v2; +} + else if(j == 1) + { + edgecollpair.p21 = face2->v2; + edgecollpair.p22 = face2->v3; +} + else if(j == 2) + { + if(face2->v4) + { + edgecollpair.p21 = face2->v3; + edgecollpair.p22 = face2->v4; +} + else + { + edgecollpair.p21 = face2->v3; + edgecollpair.p22 = face2->v1; +} +} + else if(j == 3) + { + if(face2->v4) + { + edgecollpair.p21 = face2->v4; + edgecollpair.p22 = face2->v1; +} + else + continue; +} + else + { + edgecollpair.p21 = face2->v3; + edgecollpair.p22 = face2->v1; +} + + + if(!collisions_are_edges_adjacent(clmd, coll_clmd, &edgecollpair)) + { + VECSUB(a, verts1[edgecollpair.p12].xold, verts1[edgecollpair.p11].xold); + VECSUB(b, verts1[edgecollpair.p12].v, verts1[edgecollpair.p11].v); + VECSUB(c, verts1[edgecollpair.p21].xold, verts1[edgecollpair.p11].xold); + VECSUB(d, verts1[edgecollpair.p21].v, verts1[edgecollpair.p11].v); + VECSUB(e, verts2[edgecollpair.p22].xold, verts1[edgecollpair.p11].xold); + VECSUB(f, verts2[edgecollpair.p22].v, verts1[edgecollpair.p11].v); + + numsolutions = collisions_get_collision_time(a, b, c, d, e, f, solution); + + for (k = 0; k < numsolutions; k++) + { + if ((solution[k] >= 0.0) && (solution[k] <= 1.0)) + { + float out_collisionTime = solution[k]; + + // TODO: check for collisions + + // TODO: put into (edge) collision list + + printf("Moving edge found!\n"); +} +} +} +} +} + */ +} + +void collisions_collision_moving_tris(ClothModifierData *clmd, ClothModifierData *coll_clmd, CollisionTree *tree1, CollisionTree *tree2) +{ + /* + CollPair collpair; + Cloth *cloth1=NULL, *cloth2=NULL; + MFace *face1=NULL, *face2=NULL; + ClothVertex *verts1=NULL, *verts2=NULL; + double distance = 0; + float epsilon = clmd->coll_parms.epsilon; + unsigned int i = 0, j = 0, k = 0; + int numsolutions = 0; + float a[3], b[3], c[3], d[3], e[3], f[3], solution[3]; + + for(i = 0; i < 2; i++) + { + cloth1 = clmd->clothObject; + cloth2 = coll_clmd->clothObject; + + verts1 = cloth1->verts; + verts2 = cloth2->verts; + + face1 = &(cloth1->mfaces[tree1->tri_index]); + face2 = &(cloth2->mfaces[tree2->tri_index]); + + // check all possible pairs of triangles + if(i == 0) + { + collpair.ap1 = face1->v1; + collpair.ap2 = face1->v2; + collpair.ap3 = face1->v3; + + collpair.pointsb[0] = face2->v1; + collpair.pointsb[1] = face2->v2; + collpair.pointsb[2] = face2->v3; + collpair.pointsb[3] = face2->v4; +} + + if(i == 1) + { + if(face1->v4) + { + collpair.ap1 = face1->v3; + collpair.ap2 = face1->v4; + collpair.ap3 = face1->v1; + + collpair.pointsb[0] = face2->v1; + collpair.pointsb[1] = face2->v2; + collpair.pointsb[2] = face2->v3; + collpair.pointsb[3] = face2->v4; +} + else + i++; +} + + // calc SIPcode (?) + + if(i < 2) + { + VECSUB(a, verts1[collpair.ap2].xold, verts1[collpair.ap1].xold); + VECSUB(b, verts1[collpair.ap2].v, verts1[collpair.ap1].v); + VECSUB(c, verts1[collpair.ap3].xold, verts1[collpair.ap1].xold); + VECSUB(d, verts1[collpair.ap3].v, verts1[collpair.ap1].v); + + for(j = 0; j < 4; j++) + { + if((j==3) && !(face2->v4)) + break; + + VECSUB(e, verts2[collpair.pointsb[j]].xold, verts1[collpair.ap1].xold); + VECSUB(f, verts2[collpair.pointsb[j]].v, verts1[collpair.ap1].v); + + numsolutions = collisions_get_collision_time(a, b, c, d, e, f, solution); + + for (k = 0; k < numsolutions; k++) + { + if ((solution[k] >= 0.0) && (solution[k] <= 1.0)) + { + float out_collisionTime = solution[k]; + + // TODO: check for collisions + + // TODO: put into (point-face) collision list + + printf("Moving found!\n"); + +} +} + + // TODO: check borders for collisions +} + +} +} + */ +} + + +// move collision objects forward in time and update static bounding boxes +void collisions_update_collision_objects(float step) +{ + Base *base=NULL; + ClothModifierData *coll_clmd=NULL; + Object *coll_ob=NULL; + unsigned int i=0; + + // search all objects for collision object + for (base = G.scene->base.first; base; base = base->next) + { + + coll_ob = base->object; + coll_clmd = (ClothModifierData *) modifiers_findByType (coll_ob, eModifierType_Cloth); + if (!coll_clmd) + continue; + + // if collision object go on + if (coll_clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_COLLOBJ) + { + if (coll_clmd->clothObject && coll_clmd->clothObject->tree) + { + Cloth *coll_cloth = coll_clmd->clothObject; + BVH *coll_bvh = coll_clmd->clothObject->tree; + unsigned int coll_numverts = coll_cloth->numverts; + + // update position of collision object + for(i = 0; i < coll_numverts; i++) + { + VECCOPY(coll_cloth->verts[i].txold, coll_cloth->verts[i].tx); + + VECADDS(coll_cloth->verts[i].tx, coll_cloth->verts[i].xold, coll_cloth->verts[i].v, step); + + // no dt here because of float rounding errors + VECSUB(coll_cloth->verts[i].tv, coll_cloth->verts[i].tx, coll_cloth->verts[i].txold); + } + + // update BVH of collision object + // bvh_update(coll_clmd, coll_bvh, 0); // 0 means STATIC, 1 means MOVING + } + else + printf ("collisions_bvh_objcollision: found a collision object with clothObject or collData NULL.\n"); + } + } +} + + +void collisions_collision_moving(ClothModifierData *clmd, ClothModifierData *coll_clmd, CollisionTree *tree1, CollisionTree *tree2) +{ + /* + // TODO: check for adjacent + collisions_collision_moving_edges(clmd, coll_clmd, tree1, tree2); + + collisions_collision_moving_tris(clmd, coll_clmd, tree1, tree2); + collisions_collision_moving_tris(coll_clmd, clmd, tree2, tree1); + */ +} + +// cloth - object collisions +int cloth_bvh_objcollision(ClothModifierData * clmd, float step, float dt) +{ + /* + Base *base=NULL; + ClothModifierData *coll_clmd=NULL; + Cloth *cloth=NULL; + Object *coll_ob=NULL; + BVH *collisions_bvh=NULL; + unsigned int i=0, j = 0, numfaces = 0, numverts = 0; + unsigned int result = 0, ic = 0, rounds = 0; // result counts applied collisions; ic is for debug output; + ClothVertex *verts = NULL; + float tnull[3] = {0,0,0}; + int ret = 0; + LinkNode *collision_list = NULL; + + if ((clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_COLLOBJ) || !(((Cloth *)clmd->clothObject)->tree)) + { + return 0; + } + cloth = clmd->clothObject; + verts = cloth->verts; + collisions_bvh = (BVH *) cloth->tree; + numfaces = clmd->clothObject->numfaces; + numverts = clmd->clothObject->numverts; + + //////////////////////////////////////////////////////////// + // static collisions + //////////////////////////////////////////////////////////// + + // update cloth bvh + // bvh_update(clmd, collisions_bvh, 0); // 0 means STATIC, 1 means MOVING (see later in this function) + + // update collision objects + collisions_update_collision_objects(step); + + do + { + result = 0; + ic = 0; + + // check all collision objects + for (base = G.scene->base.first; base; base = base->next) + { + coll_ob = base->object; + coll_clmd = (ClothModifierData *) modifiers_findByType (coll_ob, eModifierType_Cloth); + + if (!coll_clmd) + continue; + + // if collision object go on + if (coll_clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_COLLOBJ) + { + if (coll_clmd->clothObject && coll_clmd->clothObject->tree) + { + BVH *coll_bvh = coll_clmd->clothObject->tree; + + // fill collision list + bvh_traverse(collisions_bvh->root, coll_bvh->root, collision_list); + + // process all collisions (calculate impulses, TODO: also repulses if distance too short) + result = 1; + for(j = 0; j < 10; j++) // 10 is just a value that ensures convergence + { + result = 0; + + // result += collisions_collision_response_static_tris(clmd, coll_clmd, collision_list, 0); + + // result += collisions_collision_response_static_tris(coll_clmd, clmd, collision_list, 1); + + // apply impulses in parallel + ic=0; + for(i = 0; i < numverts; i++) + { + // calculate "velocities" (just xnew = xold + v; no dt in v) + if(verts[i].impulse_count) + { + VECADDMUL(verts[i].tv, verts[i].impulse, 1.0f / verts[i].impulse_count); + VECCOPY(verts[i].impulse, tnull); + verts[i].impulse_count = 0; + + ic++; + ret++; + } + } + } + + // free collision list + if(collision_list) + { + LinkNode *search = collision_list; + while(search) + { + CollisionPair *coll_pair = search->link; + + MEM_freeN(coll_pair); + search = search->next; + } + BLI_linklist_free(collision_list,NULL); + + collision_list = NULL; + } + } + else + printf ("collisions_bvh_objcollision: found a collision object with clothObject or collData NULL.\n"); + } + } + + printf("ic: %d\n", ic); + rounds++; + } + while(result && (10>rounds));// CLOTH_MAX_THRESHOLD + + printf("\n"); + + //////////////////////////////////////////////////////////// + // update positions + // this is needed for bvh_calc_DOP_hull_moving() [kdop.c] + //////////////////////////////////////////////////////////// + + // verts come from clmd + for(i = 0; i < numverts; i++) + { + VECADD(verts[i].tx, verts[i].txold, verts[i].tv); + } + //////////////////////////////////////////////////////////// + + //////////////////////////////////////////////////////////// + // moving collisions + //////////////////////////////////////////////////////////// + + + // update cloth bvh + // bvh_update(clmd, collisions_bvh, 1); // 0 means STATIC, 1 means MOVING + + // update moving bvh for collision object once + for (base = G.scene->base.first; base; base = base->next) + { + + coll_ob = base->object; + coll_clmd = (ClothModifierData *) modifiers_findByType (coll_ob, eModifierType_Cloth); + if (!coll_clmd) + continue; + + if(!coll_clmd->clothObject) + continue; + + // if collision object go on + if (coll_clmd->clothObject && coll_clmd->clothObject->tree) + { + BVH *coll_bvh = coll_clmd->clothObject->tree; + + // bvh_update(coll_clmd, coll_bvh, 1); // 0 means STATIC, 1 means MOVING + } + } + + + do + { + result = 0; + ic = 0; + + // check all collision objects + for (base = G.scene->base.first; base; base = base->next) + { + coll_ob = base->object; + coll_clmd = (ClothModifierData *) modifiers_findByType (coll_ob, eModifierType_Cloth); + + if (!coll_clmd) + continue; + + // if collision object go on + if (coll_clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_COLLOBJ) + { + if (coll_clmd->clothObject && coll_clmd->clothObject->tree) + { + BVH *coll_bvh = coll_clmd->clothObject->tree; + + bvh_traverse(collisions_bvh->root, coll_bvh->root, collision_list); + + // process all collisions (calculate impulses, TODO: also repulses if distance too short) + result = 1; + for(j = 0; j < 10; j++) // 10 is just a value that ensures convergence + { + result = 0; + + // handle all collision objects + + + if (coll_clmd->clothObject) + result += collisions_collision_response_moving_tris(clmd, coll_clmd); + else + printf ("collisions_bvh_objcollision: found a collision object with clothObject or collData NULL.\n"); + + + // apply impulses in parallel + ic=0; + for(i = 0; i < numverts; i++) + { + // calculate "velocities" (just xnew = xold + v; no dt in v) + if(verts[i].impulse_count) + { + VECADDMUL(verts[i].tv, verts[i].impulse, 1.0f / verts[i].impulse_count); + VECCOPY(verts[i].impulse, tnull); + verts[i].impulse_count = 0; + + ic++; + ret++; + } + } + } + + + // verts come from clmd + for(i = 0; i < numverts; i++) + { + VECADD(verts[i].tx, verts[i].txold, verts[i].tv); + } + + // update cloth bvh + // bvh_update(clmd, collisions_bvh, 1); // 0 means STATIC, 1 means MOVING + + + // free collision list + if(collision_list) + { + LinkNode *search = collision_list; + while(search) + { + CollisionPair *coll_pair = search->link; + + MEM_freeN(coll_pair); + search = search->next; + } + BLI_linklist_free(collision_list,NULL); + + collision_list = NULL; + } + } + else + printf ("collisions_bvh_objcollision: found a collision object with clothObject or collData NULL.\n"); + } + } + + printf("ic: %d\n", ic); + rounds++; + } + while(result && (10>rounds)); // CLOTH_MAX_THRESHOLD + + + //////////////////////////////////////////////////////////// + // update positions + velocities + //////////////////////////////////////////////////////////// + + // verts come from clmd + for(i = 0; i < numverts; i++) + { + VECADD(verts[i].tx, verts[i].txold, verts[i].tv); + } + //////////////////////////////////////////////////////////// + + return MIN2(ret, 1); + */ +} \ No newline at end of file diff --git a/source/blender/blenkernel/intern/kdop.c b/source/blender/blenkernel/intern/kdop.c index 1e17ee4f03e..5ad08587266 100644 --- a/source/blender/blenkernel/intern/kdop.c +++ b/source/blender/blenkernel/intern/kdop.c @@ -164,9 +164,9 @@ static int size_threshold = 16; /* * Common methods for all algorithms */ -void bvh_exchange(Tree **a, int i, int j) +void bvh_exchange(CollisionTree **a, int i, int j) { - Tree *t=a[i]; + CollisionTree *t=a[i]; a[i]=a[j]; a[j]=t; } @@ -178,10 +178,10 @@ int floor_lg(int a) /* * Insertion sort algorithm */ -static void bvh_insertionsort(Tree **a, int lo, int hi, int axis) +static void bvh_insertionsort(CollisionTree **a, int lo, int hi, int axis) { int i,j; - Tree *t; + CollisionTree *t; for (i=lo; i < hi; i++) { j=i; @@ -195,7 +195,7 @@ static void bvh_insertionsort(Tree **a, int lo, int hi, int axis) } } -static int bvh_partition(Tree **a, int lo, int hi, Tree * x, int axis) +static int bvh_partition(CollisionTree **a, int lo, int hi, CollisionTree *x, int axis) { int i=lo, j=hi; while (1) @@ -213,9 +213,9 @@ static int bvh_partition(Tree **a, int lo, int hi, Tree * x, int axis) /* * Heapsort algorithm */ -static void bvh_downheap(Tree **a, int i, int n, int lo, int axis) +static void bvh_downheap(CollisionTree **a, int i, int n, int lo, int axis) { - Tree * d = a[lo+i-1]; + CollisionTree *d = a[lo+i-1]; int child; while (i<=n/2) { @@ -231,7 +231,7 @@ static void bvh_downheap(Tree **a, int i, int n, int lo, int axis) a[lo+i-1] = d; } -static void bvh_heapsort(Tree **a, int lo, int hi, int axis) +static void bvh_heapsort(CollisionTree **a, int lo, int hi, int axis) { int n = hi-lo, i; for (i=n/2; i>=1; i=i-1) @@ -245,7 +245,7 @@ static void bvh_heapsort(Tree **a, int lo, int hi, int axis) } } -static Tree *bvh_medianof3(Tree **a, int lo, int mid, int hi, int axis) // returns Sortable +static CollisionTree *bvh_medianof3(CollisionTree **a, int lo, int mid, int hi, int axis) // returns Sortable { if ((a[mid])->bv[axis] < (a[lo])->bv[axis]) { @@ -275,7 +275,7 @@ static Tree *bvh_medianof3(Tree **a, int lo, int mid, int hi, int axis) // retur /* * Quicksort algorithm modified for Introsort */ -static void bvh_introsort_loop (Tree **a, int lo, int hi, int depth_limit, int axis) +static void bvh_introsort_loop (CollisionTree **a, int lo, int hi, int depth_limit, int axis) { int p; @@ -293,16 +293,16 @@ static void bvh_introsort_loop (Tree **a, int lo, int hi, int depth_limit, int a } } -void bvh_sort(Tree **a0, int begin, int end, int axis) +void bvh_sort(CollisionTree **a0, int begin, int end, int axis) { if (begin < end) { - Tree **a=a0; + CollisionTree **a=a0; bvh_introsort_loop(a, begin, end, 2*floor_lg(end-begin), axis); bvh_insertionsort(a, begin, end, axis); } } -void bvh_sort_along_axis(Tree **face_list, int start, int end, int axis) +void bvh_sort_along_axis(CollisionTree **face_list, int start, int end, int axis) { bvh_sort(face_list, start, end, axis); } @@ -310,7 +310,7 @@ void bvh_sort_along_axis(Tree **face_list, int start, int end, int axis) void bvh_free(BVH * bvh) { LinkNode *search = NULL; - Tree *tree = NULL; + CollisionTree *tree = NULL; if (bvh) { @@ -361,7 +361,7 @@ int bvh_largest_axis(float *bv) } // depends on the fact that the BVH's for each face is already build -void bvh_calc_DOP_hull_from_faces(BVH * bvh, Tree **tri, int numfaces, float *bv) +void bvh_calc_DOP_hull_from_faces(BVH * bvh, CollisionTree **tri, int numfaces, float *bv) { float newmin,newmax; int i, j; @@ -385,32 +385,22 @@ void bvh_calc_DOP_hull_from_faces(BVH * bvh, Tree **tri, int numfaces, float *bv } } -void bvh_calc_DOP_hull_static(BVH * bvh, Tree **tri, int numfaces, float *bv) +void bvh_calc_DOP_hull_static(BVH * bvh, CollisionTree **tri, int numfaces, float *bv) { MVert *tempMVert = bvh->x; - MFace *tempMFace = bvh->mfaces; float *tempBV = bv; float newminmax; int i, j, k; for (j = 0; j < numfaces; j++) { - tempMFace = bvh->mfaces + (tri [j])->tri_index; - // 3 or 4 vertices per face. + // 1 up to 4 vertices per leaf. for (k = 0; k < 4; k++) { - int temp = 0; - // If this is a triangle. - if (k == 3 && !tempMFace->v4) + int temp = tri[j]->point_index[k]; + + if(temp < 0) continue; - // TODO: other name for "temp" this gets all vertices of a face - if (k == 0) - temp = tempMFace->v1; - else if (k == 1) - temp = tempMFace->v2; - else if (k == 2) - temp = tempMFace->v3; - else if (k == 3) - temp = tempMFace->v4; + // for all Axes. for (i = KDOP_START; i < KDOP_END; i++) { @@ -424,33 +414,23 @@ void bvh_calc_DOP_hull_static(BVH * bvh, Tree **tri, int numfaces, float *bv) } } -void bvh_calc_DOP_hull_moving(BVH * bvh, Tree **tri, int numfaces, float *bv) +void bvh_calc_DOP_hull_moving(BVH * bvh, CollisionTree **tri, int numfaces, float *bv) { MVert *tempMVert = bvh->x; MVert *tempMVert2 = bvh->xnew; - MFace *tempMFace = bvh->mfaces; float *tempBV = bv; float newminmax; int i, j, k; for (j = 0; j < numfaces; j++) { - tempMFace = bvh->mfaces + (tri [j])->tri_index; // 3 or 4 vertices per face. for (k = 0; k < 4; k++) { - int temp = 0; - // If this is a triangle. - if (k == 3 && !tempMFace->v4) + int temp = tri[j]->point_index[k]; + + if(temp < 0) continue; - // TODO: other name for "temp" this gets all vertices of a face - if (k == 0) - temp = tempMFace->v1; - else if (k == 1) - temp = tempMFace->v2; - else if (k == 2) - temp = tempMFace->v3; - else if (k == 3) - temp = tempMFace->v4; + // for all Axes. for (i = KDOP_START; i < KDOP_END; i++) { @@ -470,10 +450,10 @@ void bvh_calc_DOP_hull_moving(BVH * bvh, Tree **tri, int numfaces, float *bv) } } -static void bvh_div_env_node(BVH * bvh, TreeNode *tree, Tree **face_list, unsigned int start, unsigned int end, int lastaxis, LinkNode *nlink) +static void bvh_div_env_node(BVH * bvh, TreeNode *tree, CollisionTree **face_list, unsigned int start, unsigned int end, int lastaxis, LinkNode *nlink) { int i = 0; - Tree *newtree = NULL; + CollisionTree *newtree = NULL; int laxis = 0, max_nodes=4; unsigned int tstart, tend; LinkNode *nlink1 = nlink; @@ -512,7 +492,7 @@ static void bvh_div_env_node(BVH * bvh, TreeNode *tree, Tree **face_list, unsign // Build tree until 4 node left. if ((tend-tstart + 1 ) > 1) { - newtree = (Tree *)MEM_callocN(sizeof(Tree), "Tree"); + newtree = (CollisionTree *)MEM_callocN(sizeof(CollisionTree), "CollisionTree"); tnlink = BLI_linklist_append_fast(&nlink1->next, newtree); newtree->nodes[0] = newtree->nodes[1] = newtree->nodes[2] = newtree->nodes[3] = NULL; @@ -530,7 +510,7 @@ static void bvh_div_env_node(BVH * bvh, TreeNode *tree, Tree **face_list, unsign } else // ok, we have 1 left for this node { - Tree *tnode = face_list[tstart]; + CollisionTree *tnode = face_list[tstart]; tree->nodes[i] = tnode; tree->nodes[i]->parent = tree; } @@ -538,19 +518,16 @@ static void bvh_div_env_node(BVH * bvh, TreeNode *tree, Tree **face_list, unsign return; } -BVH *bvh_build (DerivedMesh *dm, MVert *x, MVert *xnew, unsigned int numverts, float epsilon) +// mfaces is allowed to be null +// just vertexes are used if mfaces=NULL +BVH *bvh_build (MFace *mfaces, unsigned int numfaces, MVert *x, MVert *xnew, unsigned int numverts, float epsilon) { - unsigned int i = 0, j = 0, k = 0; - Tree **face_list=NULL; + unsigned int i = 0, j = 0; + CollisionTree **face_list=NULL; BVH *bvh=NULL; - Tree *tree=NULL; + CollisionTree *tree=NULL; LinkNode *nlink = NULL; - EdgeHash *edgehash = NULL; - unsigned int numsprings = 0; MFace *mface = NULL; - - if(!dm) - return NULL; bvh = MEM_callocN(sizeof(BVH), "BVH"); if (bvh == NULL) @@ -565,13 +542,19 @@ BVH *bvh_build (DerivedMesh *dm, MVert *x, MVert *xnew, unsigned int numverts, f bvh->tree = NULL; bvh->epsilon = epsilon; - bvh->numfaces = dm->getNumFaces(dm); - mface = bvh->mfaces = dm->getFaceArray(dm); + bvh->numfaces = numfaces; + mface = bvh->mfaces = mfaces; + + // we have no faces, we save seperate points + if(!bvh->mfaces) + { + bvh->numfaces = numverts; + } bvh->numverts = numverts; bvh->xnew = xnew; bvh->x = x; - tree = (Tree *)MEM_callocN(sizeof(Tree), "Tree"); + tree = (CollisionTree *)MEM_callocN(sizeof(CollisionTree), "CollisionTree"); // TODO: check succesfull alloc BLI_linklist_append(&bvh->tree, tree); @@ -590,7 +573,25 @@ BVH *bvh_build (DerivedMesh *dm, MVert *x, MVert *xnew, unsigned int numverts, f if(bvh->numfaces<=1) { - bvh->root->tri_index = 0; // Why that? --> only one face there + // Why that? --> only one face there + if(bvh->mfaces) + { + bvh->root->point_index[0] = mfaces[0].v1; + bvh->root->point_index[1] = mfaces[0].v2; + bvh->root->point_index[2] = mfaces[0].v3; + if(mfaces[0].v4) + bvh->root->point_index[3] = mfaces[0].v4; + else + bvh->root->point_index[3] = -1; + } + else + { + bvh->root->point_index[0] = 0; + bvh->root->point_index[1] = -1; + bvh->root->point_index[2] = -1; + bvh->root->point_index[3] = -1; + } + bvh->root->isleaf = 1; bvh->root->traversed = 0; bvh->root->count_nodes = 0; @@ -602,7 +603,7 @@ BVH *bvh_build (DerivedMesh *dm, MVert *x, MVert *xnew, unsigned int numverts, f else { // create face boxes - face_list = MEM_callocN (bvh->numfaces * sizeof (Tree *), "Tree"); + face_list = MEM_callocN (bvh->numfaces * sizeof (CollisionTree *), "CollisionTree"); if (face_list == NULL) { printf("bvh_build: Out of memory for face_list.\n"); @@ -611,17 +612,35 @@ BVH *bvh_build (DerivedMesh *dm, MVert *x, MVert *xnew, unsigned int numverts, f } // create face boxes - for(i = 0, k = 0; i < bvh->numfaces; i++) + for(i = 0; i < bvh->numfaces; i++) { LinkNode *tnlink = NULL; - tree = (Tree *)MEM_callocN(sizeof(Tree), "Tree"); + tree = (CollisionTree *)MEM_callocN(sizeof(CollisionTree), "CollisionTree"); // TODO: check succesfull alloc tnlink = BLI_linklist_append_fast(&nlink->next, tree); face_list[i] = tree; - tree->tri_index = i; + + if(bvh->mfaces) + { + bvh->root->point_index[0] = mfaces[i].v1; + bvh->root->point_index[1] = mfaces[i].v2; + bvh->root->point_index[2] = mfaces[i].v3; + if(mfaces[i].v4) + bvh->root->point_index[3] = mfaces[i].v4; + else + bvh->root->point_index[3] = -1; + } + else + { + bvh->root->point_index[0] = i; + bvh->root->point_index[1] = -1; + bvh->root->point_index[2] = -1; + bvh->root->point_index[3] = -1; + } + tree->isleaf = 1; tree->nextLeaf = NULL; tree->prevLeaf = bvh->leaf_tree; @@ -694,7 +713,7 @@ int bvh_overlap(float *bv1, float *bv2) * every other triangle that doesn't require any realloc, but uses * much memory */ -int bvh_traverse(Tree * tree1, Tree * tree2, LinkNode *collision_list) +int bvh_traverse(CollisionTree *tree1, CollisionTree *tree2, LinkNode *collision_list) { int i = 0, ret = 0; @@ -709,8 +728,11 @@ int bvh_traverse(Tree * tree1, Tree * tree2, LinkNode *collision_list) // save potential colliding triangles CollisionPair *collpair = (CollisionPair *)MEM_callocN(sizeof(CollisionPair), "CollisionPair"); - collpair->indexA = tree1->tri_index; - collpair->indexB = tree2->tri_index; + VECCOPY(collpair->point_indexA, tree1->point_index); + collpair->point_indexA[3] = tree1->point_index[3]; + + VECCOPY(collpair->point_indexB, tree2->point_index); + collpair->point_indexB[3] = tree2->point_index[3]; BLI_linklist_append(&collision_list, collpair); @@ -744,7 +766,7 @@ int bvh_traverse(Tree * tree1, Tree * tree2, LinkNode *collision_list) // bottom up update of bvh tree: // join the 4 children here -void bvh_join(Tree * tree) +void bvh_join(CollisionTree *tree) { int i = 0, j = 0; if (!tree) @@ -775,17 +797,12 @@ void bvh_join(Tree * tree) // update static bvh // needs new positions in bvh->x, bvh->xnew -void bvh_update(DerivedMesh *dm, BVH * bvh, int moving) +void bvh_update(BVH * bvh, int moving) { TreeNode *leaf, *parent; int traversecheck = 1; // if this is zero we don't go further unsigned int j = 0; - if(bvh->numfaces != dm->getNumFaces(dm)) - return; - - bvh->mfaces = dm->getFaceArray(dm); - for (leaf = bvh->leaf_root; leaf; leaf = leaf->nextLeaf) { traversecheck = 1; diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c index cb7fccd11c1..42faf2b2c3f 100644 --- a/source/blender/blenkernel/intern/modifier.c +++ b/source/blender/blenkernel/intern/modifier.c @@ -4866,7 +4866,7 @@ static void clothModifier_initData(ModifierData *md) ClothModifierData *clmd = (ClothModifierData*) md; cloth_init (clmd); } - +/* static void clothModifier_deformVerts( ModifierData *md, Object *ob, DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts) @@ -4889,6 +4889,22 @@ static void clothModifier_deformVerts( if(dm) dm->release(dm); } +*/ + +static DerivedMesh *clothModifier_applyModifier( + ModifierData *md, Object *ob, DerivedMesh *derivedData, + int useRenderParams, int isFinalCalc) +{ + DerivedMesh *result = NULL; + + ClothModifierData *clmd = (ClothModifierData*) md; + + result = clothModifier_do(clmd, ob, derivedData); + + CDDM_calc_normals(result); + + return derivedData; +} static void clothModifier_updateDepgraph( ModifierData *md, DagForest *forest, Object *ob, @@ -4957,6 +4973,8 @@ static void collisionModifier_initData(ModifierData *md) collmd->x = NULL; collmd->xnew = NULL; + collmd->current_x = NULL; + collmd->current_xnew = NULL; collmd->time = -1; collmd->numverts = 0; collmd->tree = NULL; @@ -4974,22 +4992,32 @@ static void collisionModifier_freeData(ModifierData *md) MEM_freeN(collmd->x); if(collmd->xnew) MEM_freeN(collmd->xnew); + if(collmd->current_x) + MEM_freeN(collmd->current_x); + if(collmd->current_xnew) + MEM_freeN(collmd->current_xnew); collmd->x = NULL; collmd->xnew = NULL; + collmd->current_x = NULL; + collmd->current_xnew = NULL; collmd->time = -1; collmd->numverts = 0; collmd->tree = NULL; } } +static int collisionModifier_dependsOnTime(ModifierData *md) +{ + return 1; +} + static void collisionModifier_deformVerts( ModifierData *md, Object *ob, DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts) { CollisionModifierData *collmd = (CollisionModifierData*) md; DerivedMesh *dm = NULL; - MVert *mvert = NULL; float current_time = 0; unsigned int numverts = 0, i = 0; MVert *tempVert = NULL; @@ -4999,6 +5027,12 @@ static void collisionModifier_deformVerts( if(derivedData) dm = CDDM_copy(derivedData); else if(ob->type==OB_MESH) dm = CDDM_from_mesh(ob->data, ob); + if(!ob->pd) + { + printf("collisionModifier_deformVerts: Should not happen!\n"); + return; + } + if(dm) { CDDM_apply_vert_coords(dm, vertexCos); @@ -5013,17 +5047,26 @@ static void collisionModifier_deformVerts( // check if mesh has changed if(collmd->x && (numverts != collmd->numverts)) - collisionModifier_freeData(collmd); + collisionModifier_freeData((ModifierData *)collmd); if(collmd->time == -1) // first time { - collmd->x = dm->dupVertArray(dm); - collmd->xnew = dm->dupVertArray(dm); + collmd->x = dm->dupVertArray(dm); // frame start position + + for ( i = 0; i < numverts; i++ ) + { + // we save global positions + Mat4MulVecfl ( ob->obmat, collmd->x[i].co ); + } + + collmd->xnew = MEM_dupallocN(collmd->x); // frame end position + collmd->current_x = MEM_dupallocN(collmd->x); // inter-frame + collmd->current_xnew = MEM_dupallocN(collmd->x); // inter-frame collmd->numverts = numverts; // TODO: epsilon // create bounding box hierarchy - collmd->tree = bvh_build(dm, collmd->x, collmd->xnew, numverts, 0.01); + collmd->tree = bvh_build(dm->getFaceArray(dm), dm->getNumFaces(dm), collmd->current_x, collmd->current_xnew, numverts, ob->pd->pdef_sbift); } else if(numverts == collmd->numverts) { @@ -5040,7 +5083,10 @@ static void collisionModifier_deformVerts( Mat4MulVecfl ( ob->obmat, collmd->xnew[i].co ); } - bvh_update(dm, collmd->tree, 0); // recalc static bounding boxes + memcpy(collmd->current_xnew, dm->getVertArray(dm), numverts*sizeof(MVert)); + memcpy(collmd->current_x, dm->getVertArray(dm), numverts*sizeof(MVert)); + + bvh_update(collmd->tree, 0); // recalc static bounding boxes } collmd->time = current_time; @@ -5051,11 +5097,6 @@ static void collisionModifier_deformVerts( dm->release(dm); } -static int collisionModifier_dependsOnTime(ModifierData *md) -{ - return 1; -} - /* Boolean */ static void booleanModifier_copyData(ModifierData *md, ModifierData *target) @@ -5342,10 +5383,10 @@ ModifierTypeInfo *modifierType_getInfo(ModifierType type) mti->deformVerts = softbodyModifier_deformVerts; mti = INIT_TYPE(Cloth); - mti->type = eModifierTypeType_OnlyDeform; + mti->type = eModifierTypeType_Nonconstructive; mti->initData = clothModifier_initData; - mti->flags = eModifierTypeFlag_AcceptsCVs; - // | eModifierTypeFlag_RequiresOriginalData; + mti->flags = eModifierTypeFlag_AcceptsMesh + | eModifierTypeFlag_RequiresOriginalData; // | eModifierTypeFlag_SupportsMapping // | eModifierTypeFlag_SupportsEditmode // | eModifierTypeFlag_EnableInEditmode; @@ -5353,7 +5394,8 @@ ModifierTypeInfo *modifierType_getInfo(ModifierType type) mti->freeData = clothModifier_freeData; mti->requiredDataMask = clothModifier_requiredDataMask; // mti->copyData = clothModifier_copyData; - mti->deformVerts = clothModifier_deformVerts; + // mti->deformVerts = clothModifier_deformVerts; + mti->applyModifier = clothModifier_applyModifier; mti->updateDepgraph = clothModifier_updateDepgraph; mti = INIT_TYPE(Collision); @@ -5567,11 +5609,11 @@ int modifiers_isSoftbodyEnabled(Object *ob) return (md && md->mode & (eModifierMode_Realtime | eModifierMode_Render)); } -ModifierData *modifiers_isClothEnabled(Object *ob) +ClothModifierData *modifiers_isClothEnabled(Object *ob) { - ModifierData *md = modifiers_findByType(ob, eModifierType_Cloth); + ClothModifierData *clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth); - return md; + return clmd; } LinkNode *modifiers_calcDataMasks(ModifierData *md, CustomDataMask dataMask) diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 99f0885b435..56f1c817a50 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -2893,6 +2893,8 @@ static void direct_link_modifiers(FileData *fd, ListBase *lb) collmd->x = NULL; collmd->xnew = NULL; + collmd->current_x = NULL; + collmd->current_xnew = NULL; collmd->time = -1; collmd->numverts = 0; collmd->tree = NULL; @@ -3009,7 +3011,6 @@ static void direct_link_object(FileData *fd, Object *ob) sb->bpoint= NULL; // init pointers so it gets rebuilt nicely sb->bspring= NULL; sb->scratch= NULL; - sb->keys= newdataadr(fd, sb->keys); test_pointer_array(fd, (void **)&sb->keys); diff --git a/source/blender/makesdna/DNA_cloth_types.h b/source/blender/makesdna/DNA_cloth_types.h index 27f7431a9cf..b4592e4d724 100644 --- a/source/blender/makesdna/DNA_cloth_types.h +++ b/source/blender/makesdna/DNA_cloth_types.h @@ -156,9 +156,13 @@ typedef struct Cloth unsigned char old_solver_type; unsigned char pad2; short pad3; - void *tree; /* collision tree for this cloth object */ + struct CollisionTree *tree; /* collision tree for this cloth object */ struct MFace *mfaces; - void *implicit; /* our implicit solver connects to this pointer */ + struct Implicit_Data *implicit; /* our implicit solver connects to this pointer */ + struct MVert *x; + struct MVert *xnew; + struct MVert *current_x; + struct MVert *current_xnew; } Cloth; diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h index 81e27afbac4..b25c3e79921 100644 --- a/source/blender/makesdna/DNA_modifier_types.h +++ b/source/blender/makesdna/DNA_modifier_types.h @@ -350,12 +350,14 @@ typedef struct ClothModifierData { typedef struct CollisionModifierData { ModifierData modifier; - struct MVert *x; - struct MVert *xnew; + struct MVert *x; /* position at the beginning of the frame */ + struct MVert *xnew; /* position at the end of the frame */ + struct MVert *current_xnew; /* new position at the actual inter-frame step */ + struct MVert *current_x; /* position at the actual inter-frame step */ unsigned int numverts; float time; - void *tree; /* collision tree for this cloth object */ + struct BVH *tree; /* collision tree for this cloth object */ } CollisionModifierData; typedef enum { diff --git a/source/blender/makesdna/DNA_object_force.h b/source/blender/makesdna/DNA_object_force.h index a821e209ef0..062989d0754 100644 --- a/source/blender/makesdna/DNA_object_force.h +++ b/source/blender/makesdna/DNA_object_force.h @@ -113,7 +113,6 @@ typedef struct SoftBody { ; struct SBScratch *scratch; /* scratch pad/cache on live time not saved in file */ - } SoftBody; /* pd->forcefield: Effector Fields types */ diff --git a/source/blender/src/editobject.c b/source/blender/src/editobject.c index 8f35e64b79f..a68338e132b 100644 --- a/source/blender/src/editobject.c +++ b/source/blender/src/editobject.c @@ -99,6 +99,7 @@ #include "BKE_customdata.h" #include "BKE_blender.h" #include "BKE_booleanops.h" +#include "BKE_cloth.h" #include "BKE_curve.h" #include "BKE_displist.h" #include "BKE_depsgraph.h" From 8bca9e5977c61833250c49ecb46f26b3e6b8eba7 Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Tue, 23 Oct 2007 22:38:07 +0000 Subject: [PATCH 033/246] Another WIP commit. Building up bounding volume API --- source/blender/blenkernel/BKE_collisions.h | 5 +- source/blender/blenkernel/intern/kdop.c | 94 ++++++++++++++------- source/blender/blenkernel/intern/modifier.c | 5 +- source/blender/src/buttons_object.c | 41 ++++----- 4 files changed, 85 insertions(+), 60 deletions(-) diff --git a/source/blender/blenkernel/BKE_collisions.h b/source/blender/blenkernel/BKE_collisions.h index 8c7933f3434..0a79bb46262 100644 --- a/source/blender/blenkernel/BKE_collisions.h +++ b/source/blender/blenkernel/BKE_collisions.h @@ -89,7 +89,8 @@ CollisionPair; ///////////////////////////////////////////////// // builds bounding volume hierarchy -BVH *bvh_build (MFace *mfaces, unsigned int numfaces, MVert *x, MVert *xnew, unsigned int numverts, float epsilon); +BVH *bvh_build_from_mvert (MFace *mfaces, unsigned int numfaces, MVert *x, unsigned int numverts, float epsilon); + // frees the same void bvh_free ( BVH *bvh ); @@ -97,7 +98,7 @@ void bvh_free ( BVH *bvh ); int bvh_traverse(CollisionTree *tree1, CollisionTree *tree2, LinkNode *collision_list); // update bounding volumes, needs updated positions in bvh->x -void bvh_update(BVH * bvh, int moving); +void bvh_update_from_mvert(BVH * bvh, MVert *x, unsigned int numverts, MVert *xnew, int moving); LinkNode *BLI_linklist_append_fast (LinkNode **listp, void *ptr); diff --git a/source/blender/blenkernel/intern/kdop.c b/source/blender/blenkernel/intern/kdop.c index 5ad08587266..f2a1e895751 100644 --- a/source/blender/blenkernel/intern/kdop.c +++ b/source/blender/blenkernel/intern/kdop.c @@ -330,6 +330,11 @@ void bvh_free(BVH * bvh) BLI_linklist_free(bvh->tree,NULL); bvh->tree = NULL; + if(bvh->x) + MEM_freeN(bvh->x); + if(bvh->xnew) + MEM_freeN(bvh->xnew); + MEM_freeN(bvh); bvh = NULL; } @@ -520,44 +525,14 @@ static void bvh_div_env_node(BVH * bvh, TreeNode *tree, CollisionTree **face_lis // mfaces is allowed to be null // just vertexes are used if mfaces=NULL -BVH *bvh_build (MFace *mfaces, unsigned int numfaces, MVert *x, MVert *xnew, unsigned int numverts, float epsilon) +BVH *bvh_build (BVH *bvh, MFace *mfaces, unsigned int numfaces) { unsigned int i = 0, j = 0; CollisionTree **face_list=NULL; - BVH *bvh=NULL; CollisionTree *tree=NULL; LinkNode *nlink = NULL; MFace *mface = NULL; - bvh = MEM_callocN(sizeof(BVH), "BVH"); - if (bvh == NULL) - { - printf("bvh: Out of memory.\n"); - return NULL; - } - - bvh->flags = 0; - bvh->leaf_tree = NULL; - bvh->leaf_root = NULL; - bvh->tree = NULL; - - bvh->epsilon = epsilon; - bvh->numfaces = numfaces; - mface = bvh->mfaces = mfaces; - - // we have no faces, we save seperate points - if(!bvh->mfaces) - { - bvh->numfaces = numverts; - } - - bvh->numverts = numverts; - bvh->xnew = xnew; - bvh->x = x; - tree = (CollisionTree *)MEM_callocN(sizeof(CollisionTree), "CollisionTree"); - // TODO: check succesfull alloc - BLI_linklist_append(&bvh->tree, tree); - nlink = bvh->tree; if (tree == NULL) @@ -686,6 +661,46 @@ BVH *bvh_build (MFace *mfaces, unsigned int numfaces, MVert *x, MVert *xnew, uns return bvh; } +BVH *bvh_build_from_mvert (MFace *mfaces, unsigned int numfaces, MVert *x, unsigned int numverts, float epsilon) +{ + unsigned int i = 0, j = 0; + CollisionTree **face_list=NULL; + BVH *bvh=NULL; + CollisionTree *tree=NULL; + LinkNode *nlink = NULL; + MFace *mface = NULL; + + bvh = MEM_callocN(sizeof(BVH), "BVH"); + if (bvh == NULL) + { + printf("bvh: Out of memory.\n"); + return NULL; + } + + bvh->flags = 0; + bvh->leaf_tree = NULL; + bvh->leaf_root = NULL; + bvh->tree = NULL; + + bvh->epsilon = epsilon; + bvh->numfaces = numfaces; + + // we have no faces, we save seperate points + if(!mfaces) + { + bvh->numfaces = numverts; + } + + bvh->numverts = numverts; + bvh->xnew = MEM_dupallocN(x); + bvh->x = MEM_dupallocN(x); + tree = (CollisionTree *)MEM_callocN(sizeof(CollisionTree), "CollisionTree"); + // TODO: check succesfull alloc + BLI_linklist_append(&bvh->tree, tree); + + return bvh_build(bvh, mfaces, numfaces); +} + // bvh_overlap - is it possbile for 2 bv's to collide ? int bvh_overlap(float *bv1, float *bv2) { @@ -850,3 +865,20 @@ void bvh_update(BVH * bvh, int moving) } } +void bvh_update_from_mvert(BVH * bvh, MVert *x, unsigned int numverts, MVert *xnew, int moving) +{ + if(!bvh) + return; + + if(numverts!=bvh->numverts) + return; + + if(x) + memcpy(bvh->x, x, sizeof(MVert) * numverts); + + if(xnew) + memcpy(bvh->xnew, xnew, sizeof(MVert) * numverts); + + bvh_update(bvh, moving); +} + diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c index 42faf2b2c3f..e9ec26e56ec 100644 --- a/source/blender/blenkernel/intern/modifier.c +++ b/source/blender/blenkernel/intern/modifier.c @@ -5066,7 +5066,7 @@ static void collisionModifier_deformVerts( // TODO: epsilon // create bounding box hierarchy - collmd->tree = bvh_build(dm->getFaceArray(dm), dm->getNumFaces(dm), collmd->current_x, collmd->current_xnew, numverts, ob->pd->pdef_sbift); + collmd->tree = bvh_build_from_mvert(dm->getFaceArray(dm), dm->getNumFaces(dm), collmd->current_x, numverts, ob->pd->pdef_sbift); } else if(numverts == collmd->numverts) { @@ -5086,7 +5086,8 @@ static void collisionModifier_deformVerts( memcpy(collmd->current_xnew, dm->getVertArray(dm), numverts*sizeof(MVert)); memcpy(collmd->current_x, dm->getVertArray(dm), numverts*sizeof(MVert)); - bvh_update(collmd->tree, 0); // recalc static bounding boxes + // recalc static bounding boxes + bvh_update_from_mvert(collmd->tree, collmd->current_x, numverts, NULL, 0); } collmd->time = current_time; diff --git a/source/blender/src/buttons_object.c b/source/blender/src/buttons_object.c index 0e227f7efbc..c264d684d77 100644 --- a/source/blender/src/buttons_object.c +++ b/source/blender/src/buttons_object.c @@ -3268,38 +3268,29 @@ static void object_panel_cloth_II(Object *ob) static void object_panel_cloth_III(Object *ob) { uiBlock *block; - static int val; - uiBut *but; ClothModifierData *clmd = NULL; clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth); if(clmd) - { - if (!(clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_COLLOBJ)) - { - Cloth *cloth = clmd->clothObject; - char str[128]; - - block= uiNewBlock(&curarea->uiblocks, "object_panel_cloth_III", UI_EMBOSS, UI_HELV, curarea->win); - uiNewPanelTabbed("Cloth", "Physics"); - if(uiNewPanel(curarea, block, "Cloth Collisions", "Physics", 651, 0, 318, 204)==0) return; + { + block= uiNewBlock(&curarea->uiblocks, "object_panel_cloth_III", UI_EMBOSS, UI_HELV, curarea->win); + uiNewPanelTabbed("Cloth", "Physics"); + if(uiNewPanel(curarea, block, "Cloth Collisions", "Physics", 651, 0, 318, 204)==0) return; + + uiSetButLock(object_data_is_libdata(ob), ERROR_LIBDATA_MESSAGE); - uiSetButLock(object_data_is_libdata(ob), ERROR_LIBDATA_MESSAGE); - - uiBlockBeginAlign(block); - uiDefButBitI(block, TOG, CLOTH_COLLISIONSETTINGS_FLAG_ENABLED, REDRAWVIEW3D, "Enable collisions", 10,70,130,20, &clmd->coll_parms.flags, 0, 0, 0, 0, "Enable collisions with this object"); - if (clmd->coll_parms.flags & CLOTH_COLLISIONSETTINGS_FLAG_ENABLED) - { - // uiDefBut(block, LABEL, 0, "",10,10,300,20, NULL, 0.0, 0, 0, 0, ""); /* tell UI we go to 10,10*/ - uiDefButF(block, NUM, B_CLOTH_RENEW, "Min Distance:", 10,30,150,20, &clmd->coll_parms.epsilon, 0.001f, 1.0, 0.01f, 0, "Minimum distance between collision objects before collision response takes in"); - uiDefBut(block, LABEL, 0, "",160,30,150,20, NULL, 0.0, 0, 0, 0, ""); - } - else - uiDefBut(block, LABEL, 0, "",140,10,170,20, NULL, 0.0, 0, 0, 0, ""); - uiBlockEndAlign(block); + uiBlockBeginAlign(block); + uiDefButBitI(block, TOG, CLOTH_COLLISIONSETTINGS_FLAG_ENABLED, REDRAWVIEW3D, "Enable collisions", 10,70,130,20, &clmd->coll_parms.flags, 0, 0, 0, 0, "Enable collisions with this object"); + if (clmd->coll_parms.flags & CLOTH_COLLISIONSETTINGS_FLAG_ENABLED) + { + // uiDefBut(block, LABEL, 0, "",10,10,300,20, NULL, 0.0, 0, 0, 0, ""); /* tell UI we go to 10,10*/ + uiDefButF(block, NUM, B_CLOTH_RENEW, "Min Distance:", 10,30,150,20, &clmd->coll_parms.epsilon, 0.001f, 1.0, 0.01f, 0, "Minimum distance between collision objects before collision response takes in"); + uiDefBut(block, LABEL, 0, "",160,30,150,20, NULL, 0.0, 0, 0, 0, ""); } + else + uiDefBut(block, LABEL, 0, "",140,10,170,20, NULL, 0.0, 0, 0, 0, ""); + uiBlockEndAlign(block); } - // uiBlockEndAlign(block); } From 916cd17778ef306c283adcdffe872c9503358ee0 Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Wed, 24 Oct 2007 17:13:13 +0000 Subject: [PATCH 034/246] Fixed some bugs in bounding volumes, still some crasher in new cloth modifier --- source/blender/blenkernel/intern/cloth.c | 9 ++++++--- source/blender/blenkernel/intern/kdop.c | 16 ++++++++-------- source/blender/blenkernel/intern/modifier.c | 2 +- 3 files changed, 15 insertions(+), 12 deletions(-) diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c index 4c4bac7bbf9..5ea913788e7 100644 --- a/source/blender/blenkernel/intern/cloth.c +++ b/source/blender/blenkernel/intern/cloth.c @@ -699,11 +699,11 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd, } tstart(); - +/* // Call the solver. if ( solvers [clmd->sim_parms.solver_type].solver ) solvers [clmd->sim_parms.solver_type].solver ( ob, framenr, clmd, effectors ); - +*/ tend(); printf ( "Cloth simulation time: %f\n", ( float ) tval() ); @@ -735,7 +735,10 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd, } } - return result; + if(result) + return result; + else + return dm; } /* frees all */ diff --git a/source/blender/blenkernel/intern/kdop.c b/source/blender/blenkernel/intern/kdop.c index f2a1e895751..32bab0b4935 100644 --- a/source/blender/blenkernel/intern/kdop.c +++ b/source/blender/blenkernel/intern/kdop.c @@ -531,16 +531,9 @@ BVH *bvh_build (BVH *bvh, MFace *mfaces, unsigned int numfaces) CollisionTree **face_list=NULL; CollisionTree *tree=NULL; LinkNode *nlink = NULL; - MFace *mface = NULL; nlink = bvh->tree; - if (tree == NULL) - { - printf("bvh_build: Out of memory for nodes.\n"); - bvh_free(bvh); - return NULL; - } bvh->root = bvh->tree->link; bvh->root->isleaf = 0; bvh->root->parent = NULL; @@ -695,7 +688,14 @@ BVH *bvh_build_from_mvert (MFace *mfaces, unsigned int numfaces, MVert *x, unsig bvh->xnew = MEM_dupallocN(x); bvh->x = MEM_dupallocN(x); tree = (CollisionTree *)MEM_callocN(sizeof(CollisionTree), "CollisionTree"); - // TODO: check succesfull alloc + + if (tree == NULL) + { + printf("bvh_build: Out of memory for nodes.\n"); + bvh_free(bvh); + return NULL; + } + BLI_linklist_append(&bvh->tree, tree); return bvh_build(bvh, mfaces, numfaces); diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c index e9ec26e56ec..4b65381c3b7 100644 --- a/source/blender/blenkernel/intern/modifier.c +++ b/source/blender/blenkernel/intern/modifier.c @@ -4903,7 +4903,7 @@ static DerivedMesh *clothModifier_applyModifier( CDDM_calc_normals(result); - return derivedData; + return result; } static void clothModifier_updateDepgraph( From f310214cc5a40b20cc9189b60cbd726f9368d99d Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Thu, 25 Oct 2007 21:17:55 +0000 Subject: [PATCH 035/246] reverted part of cloth.c and modifier.c back to old code before switch to use "deform_only" modifier (not tested, needs cleanup but compiles) --- source/blender/blenkernel/intern/cloth.c | 686 ++++++++++---------- source/blender/blenkernel/intern/modifier.c | 17 +- 2 files changed, 344 insertions(+), 359 deletions(-) diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c index 5ea913788e7..4692ee5fa3f 100644 --- a/source/blender/blenkernel/intern/cloth.c +++ b/source/blender/blenkernel/intern/cloth.c @@ -120,13 +120,12 @@ static CM_SOLVER_DEF solvers [] = /* ********** cloth engine ******* */ /* Prototypes for internal functions. */ -static void cloth_to_object ( Object *ob, ClothModifierData *clmd, DerivedMesh *dm ); -static void cloth_from_mesh ( Object *ob, ClothModifierData *clmd, DerivedMesh *dm ); -static int cloth_from_object ( Object *ob, ClothModifierData *clmd, DerivedMesh *dm ); +static void cloth_to_object (Object *ob, DerivedMesh *dm, ClothModifierData *clmd); +static void cloth_from_mesh (Object *ob, ClothModifierData *clmd, DerivedMesh *dm, float framenr); +static int cloth_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *dm, DerivedMesh *olddm, float framenr); +static int collobj_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *dm, DerivedMesh *olddm, float framenr); int cloth_build_springs ( Cloth *cloth, DerivedMesh *dm ); -static void cloth_apply_vgroup ( ClothModifierData *clmd, DerivedMesh *dm, short vgroup ); - - +static void cloth_apply_vgroup(ClothModifierData *clmd, DerivedMesh *dm, short vgroup); /****************************************************************************** * * External interface called by modifier.c clothModifier functions. @@ -136,9 +135,9 @@ static void cloth_apply_vgroup ( ClothModifierData *clmd, DerivedMesh *dm, short * cloth_init - creates a new cloth simulation. * * 1. create object -* 2. fill object with standard values or with the GUI settings if given +* 2. fill object with standard values or with the GUI settings if given */ -void cloth_init ( ClothModifierData *clmd ) +void cloth_init (ClothModifierData *clmd) { /* Initialize our new data structure to reasonable values. */ clmd->sim_parms.gravity [0] = 0.0; @@ -153,17 +152,14 @@ void cloth_init ( ClothModifierData *clmd ) clmd->sim_parms.stepsPerFrame = 5; clmd->sim_parms.sim_time = 1.0; clmd->sim_parms.flags = CLOTH_SIMSETTINGS_FLAG_RESET; - clmd->sim_parms.solver_type = 0; + clmd->sim_parms.solver_type = 0; clmd->sim_parms.preroll = 0; clmd->sim_parms.maxspringlen = 10; - clmd->sim_parms.firstframe = 1; - clmd->sim_parms.lastframe = 250; clmd->coll_parms.self_friction = 5.0; clmd->coll_parms.friction = 10.0; clmd->coll_parms.loop_count = 1; clmd->coll_parms.epsilon = 0.01f; - clmd->coll_parms.flags = 0; - + /* These defaults are copied from softbody.c's * softbody_calc_forces() function. */ @@ -181,17 +177,17 @@ void cloth_init ( ClothModifierData *clmd ) } // unused in the moment, cloth needs quads from mesh -DerivedMesh *CDDM_convert_to_triangle ( DerivedMesh *dm ) +DerivedMesh *CDDM_convert_to_triangle(DerivedMesh *dm) { DerivedMesh *result = NULL; int i; - int numverts = dm->getNumVerts ( dm ); - int numedges = dm->getNumEdges ( dm ); - int numfaces = dm->getNumFaces ( dm ); + int numverts = dm->getNumVerts(dm); + int numedges = dm->getNumEdges(dm); + int numfaces = dm->getNumFaces(dm); - MVert *mvert = CDDM_get_verts ( dm ); - MEdge *medge = CDDM_get_edges ( dm ); - MFace *mface = CDDM_get_faces ( dm ); + MVert *mvert = CDDM_get_verts(dm); + MEdge *medge = CDDM_get_edges(dm); + MFace *mface = CDDM_get_faces(dm); MVert *mvert2; MFace *mface2; @@ -203,36 +199,36 @@ DerivedMesh *CDDM_convert_to_triangle ( DerivedMesh *dm ) float vec1[3], vec2[3], vec3[3], vec4[3], vec5[3]; float mag1=0, mag2=0; - for ( i = 0; i < numfaces; i++ ) + for(i = 0; i < numfaces; i++) { - if ( mface[i].v4 ) + if(mface[i].v4) numquads++; else - numtris++; + numtris++; } - result = CDDM_from_template ( dm, numverts, 0, numtris + 2*numquads ); + result = CDDM_from_template(dm, numverts, 0, numtris + 2*numquads); - if ( !result ) + if(!result) return NULL; // do verts - mvert2 = CDDM_get_verts ( result ); - for ( a=0; av1 = mface[a].v2; mf->v2 = mface[a].v3; @@ -260,9 +256,9 @@ DerivedMesh *CDDM_convert_to_triangle ( DerivedMesh *dm ) mf->v4 = 0; mf->flag |= ME_SMOOTH; - test_index_face ( mf, NULL, 0, 3 ); + test_index_face(mf, NULL, 0, 3); - if ( mface[a].v4 ) + if(mface[a].v4) { MFace *mf2; @@ -275,7 +271,7 @@ DerivedMesh *CDDM_convert_to_triangle ( DerivedMesh *dm ) *mf2 = *inMF; */ - if ( random==1 ) + if(random==1) { mf2->v1 = mface[a].v1; mf2->v2 = mface[a].v2; @@ -290,31 +286,32 @@ DerivedMesh *CDDM_convert_to_triangle ( DerivedMesh *dm ) mf2->v4 = 0; mf2->flag |= ME_SMOOTH; - test_index_face ( mf2, NULL, 0, 3 ); + test_index_face(mf2, NULL, 0, 3); } i++; } - CDDM_calc_edges ( result ); - CDDM_calc_normals ( result ); + CDDM_calc_edges(result); + CDDM_calc_normals(result); return result; } -DerivedMesh *CDDM_create_tearing ( ClothModifierData *clmd, DerivedMesh *dm ) +DerivedMesh *CDDM_create_tearing(ClothModifierData *clmd, DerivedMesh *dm) { + /* DerivedMesh *result = NULL; unsigned int i = 0, a = 0, j=0; - int numverts = dm->getNumVerts ( dm ); - int numedges = dm->getNumEdges ( dm ); - int numfaces = dm->getNumFaces ( dm ); + int numverts = dm->getNumVerts(dm); + int numedges = dm->getNumEdges(dm); + int numfaces = dm->getNumFaces(dm); - MVert *mvert = CDDM_get_verts ( dm ); - MEdge *medge = CDDM_get_edges ( dm ); - MFace *mface = CDDM_get_faces ( dm ); + MVert *mvert = CDDM_get_verts(dm); + MEdge *medge = CDDM_get_edges(dm); + MFace *mface = CDDM_get_faces(dm); MVert *mvert2; MFace *mface2; @@ -324,79 +321,80 @@ DerivedMesh *CDDM_create_tearing ( ClothModifierData *clmd, DerivedMesh *dm ) Cloth *cloth = clmd->clothObject; ClothSpring *springs = cloth->springs; unsigned int numsprings = cloth->numsprings; - + // create spring tearing hash edgehash = BLI_edgehash_new(); - - for ( i = 0; i < numsprings; i++ ) + + for(i = 0; i < numsprings; i++) { - if ( ( springs[i].flags & CLOTH_SPRING_FLAG_DEACTIVATE ) - && ( !BLI_edgehash_haskey ( edgehash, springs[i].ij, springs[i].kl ) ) ) + if((springs[i].flags & CSPRING_FLAG_DEACTIVATE) + &&(!BLI_edgehash_haskey(edgehash, springs[i].ij, springs[i].kl))) { - BLI_edgehash_insert ( edgehash, springs[i].ij, springs[i].kl, NULL ); - BLI_edgehash_insert ( edgehash, springs[i].kl, springs[i].ij, NULL ); + BLI_edgehash_insert(edgehash, springs[i].ij, springs[i].kl, NULL); + BLI_edgehash_insert(edgehash, springs[i].kl, springs[i].ij, NULL); j++; } } - + // printf("found %d tears\n", j); + + result = CDDM_from_template(dm, numverts, 0, numfaces); - result = CDDM_from_template ( dm, numverts, 0, numfaces ); - - if ( !result ) + if(!result) return NULL; // do verts - mvert2 = CDDM_get_verts ( result ); - for ( a=0; av1 = mface[a].v1; mf->v2 = mface[a].v2; mf->v3 = mface[a].v3; mf->v4 = mface[a].v4; - - test_index_face ( mf, NULL, 0, 4 ); - + + test_index_face(mf, NULL, 0, 4); + i++; } } - CDDM_lower_num_faces ( result, i ); - CDDM_calc_edges ( result ); - CDDM_calc_normals ( result ); - - BLI_edgehash_free ( edgehash, NULL ); + CDDM_lower_num_faces(result, i); + CDDM_calc_edges(result); + CDDM_calc_normals(result); + + BLI_edgehash_free(edgehash, NULL); return result; + */ } @@ -600,79 +598,54 @@ void cloth_cache_free ( ClothModifierData *clmd, float time ) /** * cloth_deform_verts - simulates one step, framenr is in frames. -* +* **/ -DerivedMesh *clothModifier_do(ClothModifierData *clmd, - Object *ob, DerivedMesh *dm) +DerivedMesh *clothModifier_do(ClothModifierData *clmd,Object *ob, DerivedMesh *dm, int useRenderParams, int isFinalCalc) { unsigned int i; - DerivedMesh *result = NULL; + unsigned int numverts = -1; + unsigned int numedges = -1; + unsigned int numfaces = -1; + MVert *mvert = NULL; + MEdge *medge = NULL; + MFace *mface = NULL; + DerivedMesh *result = NULL, *result2 = NULL; Cloth *cloth = clmd->clothObject; - unsigned int framenr = ( float ) G.scene->r.cfra; - float current_time = bsystem_time ( ob, ( float ) G.scene->r.cfra, 0.0 ); - ListBase *effectors = NULL; - ClothVertex *verts = NULL; + unsigned int framenr = (float)G.scene->r.cfra; + float current_time = bsystem_time(ob, (float)G.scene->r.cfra, 0.0); + ListBase *effectors = NULL; + ClothVertex *newframe= NULL; Frame *frame = NULL; LinkNode *search = NULL; - float deltaTime = current_time - clmd->sim_parms.sim_time; - MVert *mverts = NULL; - - result = CDDM_copy(dm); - - // only be active during a specific period: - // that's "first frame" and "last frame" on GUI - if ( clmd->clothObject ) - { - if ( clmd->sim_parms.cache ) - { - if ( current_time < clmd->sim_parms.firstframe ) - { - int frametime = cloth_cache_first_frame ( clmd ); - if ( cloth_cache_search_frame ( clmd, frametime ) ) - { - cloth_cache_get_frame ( clmd, frametime ); - cloth_to_object ( ob, clmd, result ); - } - return; - } - else if ( current_time > clmd->sim_parms.lastframe ) - { - int frametime = cloth_cache_last_frame ( clmd ); - if ( cloth_cache_search_frame ( clmd, frametime ) ) - { - cloth_cache_get_frame ( clmd, frametime ); - cloth_to_object ( ob, clmd, result ); - } - return; - } - else if ( ABS ( deltaTime ) >= 2.0f ) // no timewarps allowed - { - if ( cloth_cache_search_frame ( clmd, framenr ) ) - { - cloth_cache_get_frame ( clmd, framenr ); - cloth_to_object ( ob, clmd, result ); - } - clmd->sim_parms.sim_time = current_time; - return; - } - } + float deltaTime = current_time - clmd->sim_parms.sim_time; + clmd->sim_parms.dt = 1.0f / (clmd->sim_parms.stepsPerFrame * G.scene->r.frs_sec); + + result = CDDM_copy(dm); + + if(!result) + { + return dm; } - - // unused in the moment, calculated seperately in implicit.c - clmd->sim_parms.dt = 1.0f / clmd->sim_parms.stepsPerFrame; + + numverts = result->getNumVerts(result); + numedges = result->getNumEdges(result); + numfaces = result->getNumFaces(result); + mvert = CDDM_get_verts(result); + medge = CDDM_get_edges(result); + mface = CDDM_get_faces(result); clmd->sim_parms.sim_time = current_time; - if ( deltaTime == 1.0f ) + if(deltaTime == 1.0f) { - if ( ( clmd->clothObject == NULL ) || ( dm->getNumVerts(dm) != clmd->clothObject->numverts ) ) + if ((clmd->clothObject == NULL) || (numverts != clmd->clothObject->numverts) ) { - if ( !cloth_from_object ( ob, clmd, dm ) ) - return; + if(!cloth_from_object (ob, clmd, result, dm, framenr)) + return result; - if ( clmd->clothObject == NULL ) - return; + if(clmd->clothObject == NULL) + return result; cloth = clmd->clothObject; } @@ -680,47 +653,56 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd, clmd->clothObject->old_solver_type = clmd->sim_parms.solver_type; // Insure we have a clmd->clothObject, in case allocation failed. - if ( clmd->clothObject != NULL ) - { - if ( !cloth_cache_search_frame ( clmd, framenr ) ) - { - verts = cloth->verts; - mverts = dm->getVertArray(dm); + if (clmd->clothObject != NULL) + { + + cloth->mfaces = mface; // update face pointer + ((BVH *)cloth->tree)->mfaces = mface; + cloth->numfaces = numfaces; + ((BVH *)cloth->tree)->numfaces = numfaces; - // Force any pinned verts to their constrained location. - for ( i = 0; i < clmd->clothObject->numverts; i++, verts++ ) + if(!cloth_cache_search_frame(clmd, framenr)) + { + /* Force any pinned verts to their constrained location. */ + for (i = 0; i < clmd->clothObject->numverts; i++) { - // Save the previous position. - VECCOPY ( verts->xold, verts->xconst ); - VECCOPY ( verts->txold, verts->x ); - // Get the current position. - VECCOPY ( verts->xconst, mverts[i].co ); - Mat4MulVecfl ( ob->obmat, verts->xconst ); + /* Save the previous position. */ + VECCOPY (cloth->verts [i].xold, cloth->verts [i].xconst); + VECCOPY (cloth->verts [i].txold, cloth->verts [i].x); + + /* Get the current position. */ + VECCOPY (cloth->verts [i].xconst, mvert[i].co); + Mat4MulVecfl(ob->obmat, cloth->verts [i].xconst); + + /* Compute the vertices velocity. */ + VECSUB (cloth->verts [i].v, cloth->verts [i].x, cloth->verts [i].xold); } tstart(); -/* - // Call the solver. - if ( solvers [clmd->sim_parms.solver_type].solver ) - solvers [clmd->sim_parms.solver_type].solver ( ob, framenr, clmd, effectors ); -*/ - tend(); - printf ( "Cloth simulation time: %f\n", ( float ) tval() ); - cloth_cache_set_frame ( clmd, framenr ); + /* Call the solver. */ + + if (solvers [clmd->sim_parms.solver_type].solver) + solvers [clmd->sim_parms.solver_type].solver (ob, framenr, clmd, effectors); + + tend(); + + // printf("Cloth simulation time: %f\n", (float)tval()); + + cloth_cache_set_frame(clmd, framenr); } else // just retrieve the cached frame { - cloth_cache_get_frame ( clmd, framenr ); + cloth_cache_get_frame(clmd, framenr); } // Copy the result back to the object. - cloth_to_object ( ob, clmd, result ); - + cloth_to_object (ob, result, clmd); + // bvh_free(clmd->clothObject->tree); // clmd->clothObject->tree = bvh_build(clmd, clmd->coll_parms.epsilon); - } + } } else if ( ( deltaTime <= 0.0f ) || ( deltaTime > 1.0f ) ) @@ -729,47 +711,44 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd, { if ( cloth_cache_search_frame ( clmd, framenr ) ) { - cloth_cache_get_frame ( clmd, framenr ); - cloth_to_object ( ob, clmd, result ); + cloth_cache_get_frame(clmd, framenr); + cloth_to_object (ob, result, clmd); } } } - if(result) - return result; - else - return dm; + return result; } /* frees all */ -void cloth_free_modifier ( ClothModifierData *clmd ) +void cloth_free_modifier (ClothModifierData *clmd) { Cloth *cloth = NULL; - if ( !clmd ) + if(!clmd) return; cloth = clmd->clothObject; - if ( ! ( clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_CCACHE_PROTECT ) ) - { - // free our frame cache, TODO: but get to first position before - cloth_cache_free ( clmd, 0 ); + // free our frame cache + cloth_cache_free(clmd, 0); - if ( cloth ) - { + /* Calls the solver and collision frees first as they + * might depend on data in clmd->clothObject. */ - // If our solver provides a free function, call it - if ( cloth->old_solver_type < 255 && solvers [cloth->old_solver_type].free ) - { - solvers [cloth->old_solver_type].free ( clmd ); - } + if (cloth) + { + // If our solver provides a free function, call it + if (cloth->old_solver_type < 255 && solvers [cloth->old_solver_type].free) + { + solvers [cloth->old_solver_type].free (clmd); + } + + // Free the verts. + if (cloth->verts != NULL) + MEM_freeN (cloth->verts); - // Free the verts. - if ( cloth->verts != NULL ) - MEM_freeN ( cloth->verts ); - - // Free the verts. + // Free the verts. if ( cloth->x != NULL ) MEM_freeN ( cloth->x ); @@ -777,9 +756,9 @@ void cloth_free_modifier ( ClothModifierData *clmd ) if ( cloth->xnew != NULL ) MEM_freeN ( cloth->xnew ); - cloth->verts = NULL; - cloth->numverts = 0; - + cloth->verts = NULL; + cloth->numverts = -1; + // Free the springs. if ( cloth->springs != NULL ) { @@ -796,27 +775,20 @@ void cloth_free_modifier ( ClothModifierData *clmd ) cloth->springs = NULL; } - cloth->springs = NULL; - cloth->numsprings = 0; -/* - // free BVH collision tree - if ( cloth->tree ) - bvh_free ( ( BVH * ) cloth->tree ); -*/ - // we save our faces for collision objects - if ( cloth->mfaces ) - MEM_freeN ( cloth->mfaces ); - /* - if(clmd->clothObject->facemarks) - MEM_freeN(clmd->clothObject->facemarks); - */ - MEM_freeN ( cloth ); - clmd->clothObject = NULL; - } + cloth->numsprings = -1; + + // free BVH collision tree + if(cloth->tree) + bvh_free((BVH *)cloth->tree); + + MEM_freeN (cloth); + clmd->clothObject = NULL; } + } + /****************************************************************************** * * Internal functions. @@ -828,24 +800,26 @@ void cloth_free_modifier ( ClothModifierData *clmd ) * * This function is a modified version of the softbody.c:softbody_to_object() function. **/ -static void cloth_to_object ( Object *ob, ClothModifierData *clmd, DerivedMesh *dm ) +static void cloth_to_object (Object *ob, DerivedMesh *dm, ClothModifierData *clmd) { ClothVertex *verts = NULL; unsigned int i = 0; - MVert *mvert = NULL; + MVert *mvert = NULL; + unsigned int numverts; - if ( clmd->clothObject ) - { + if (clmd->clothObject) { verts = clmd->clothObject->verts; - mvert = dm->getVertArray(dm); /* inverse matrix is not uptodate... */ - Mat4Invert ( ob->imat, ob->obmat ); + Mat4Invert (ob->imat, ob->obmat); - for ( i = 0; i < dm->getNumVerts(dm); i++, verts++ ) + mvert = CDDM_get_verts(dm); + numverts = dm->getNumVerts(dm); + + for (i = 0; i < numverts; i++, verts++) { - VECCOPY ( mvert[i].co, verts->x ); - Mat4MulVecfl ( ob->imat, mvert[i].co ); /* softbody is in global coords */ + VECCOPY (mvert[i].co, verts->x); + Mat4MulVecfl (ob->imat, mvert[i].co); /* softbody is in global coords */ } } } @@ -855,48 +829,43 @@ static void cloth_to_object ( Object *ob, ClothModifierData *clmd, DerivedMesh * * cloth_apply_vgroup - applies a vertex group as specified by type * **/ -static void cloth_apply_vgroup ( ClothModifierData *clmd, DerivedMesh *dm, short vgroup ) +static void cloth_apply_vgroup(ClothModifierData *clmd, DerivedMesh *dm, short vgroup) { - unsigned int i = 0; - unsigned int j = 0; - MDeformVert *dvert = NULL; - Cloth *clothObj = NULL; - unsigned int numverts = dm->getNumVerts ( dm ); - float goalfac = 0; - ClothVertex *verts = NULL; + unsigned int i; + int j; + MDeformVert *dvert = NULL; + Cloth *clothObj; + unsigned int numverts = dm->getNumVerts(dm); + float goalfac; clothObj = clmd->clothObject; - if ( !dm ) - return; - - numverts = dm->getNumVerts ( dm ); - /* vgroup is 1 based, decrement so we can match the right group. */ --vgroup; - verts = clothObj->verts; - - for ( i = 0; i < numverts; i++, verts++ ) - { + for (i = 0; i < numverts; ++i) + { + /* so this will definily be below SOFTGOALSNAP */ + clothObj->verts [i].goal= 0.0f; + // LATER ON, support also mass painting here - if ( clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_GOAL ) - { - dvert = dm->getVertData ( dm, i, CD_MDEFORMVERT ); - if ( dvert ) - { - for ( j = 0; j < dvert->totweight; j++ ) + if(clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_GOAL) + { + dvert = dm->getVertData(dm, i, CD_MDEFORMVERT); + if(dvert) + { + for(j = 0; j < dvert->totweight; j++) { - if ( dvert->dw[j].def_nr == vgroup ) + if(dvert->dw[j].def_nr == vgroup) { - verts->goal = dvert->dw [j].weight; + clothObj->verts [i].goal = dvert->dw [j].weight; - goalfac= ABS ( clmd->sim_parms.maxgoal - clmd->sim_parms.mingoal ); - verts->goal = ( float ) pow ( verts->goal , 4.0f ); + goalfac= ABS(clmd->sim_parms.maxgoal - clmd->sim_parms.mingoal); + clothObj->verts [i].goal = (float)pow(clothObj->verts [i].goal , 4.0f); - if ( dvert->dw [j].weight >=SOFTGOALSNAP ) + if(dvert->dw [j].weight >=SOFTGOALSNAP) { - verts->flags |= CVERT_FLAG_PINNED; + clothObj->verts[i].flags |= CVERT_FLAG_PINNED; } // TODO enable mass painting here, for the moment i let "goals" go first @@ -910,158 +879,173 @@ static void cloth_apply_vgroup ( ClothModifierData *clmd, DerivedMesh *dm, short } // only meshes supported at the moment -static int cloth_from_object ( Object *ob, ClothModifierData *clmd, DerivedMesh *dm ) +/* collision objects */ +static int collobj_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *dm, DerivedMesh *olddm, float framenr) { - unsigned int i = 0; - // dm->getNumVerts(dm); - MVert *mvert = NULL; // CDDM_get_verts(dm); - ClothVertex *verts = NULL; - float tnull[3] = {0,0,0}; + unsigned int i; + unsigned int numverts = dm->getNumVerts(dm); + MVert *mvert = CDDM_get_verts(dm); + switch (ob->type) + { + case OB_MESH: + cloth_from_mesh (ob, clmd, dm, framenr); + + if (clmd->clothObject != NULL) + { + + for (i = 0; i < numverts; ++i) + { + VECCOPY (clmd->clothObject->verts [i].x, mvert[i].co); + Mat4MulVecfl(ob->obmat, clmd->clothObject->verts [i].x); + clmd->clothObject->verts [i].flags = 0; + VECCOPY(clmd->clothObject->verts [i].xold, clmd->clothObject->verts [i].x); + VECCOPY(clmd->clothObject->verts [i].txold, clmd->clothObject->verts [i].x); + VECCOPY(clmd->clothObject->verts [i].tx, clmd->clothObject->verts [i].x); + VecMulf(clmd->clothObject->verts [i].v, 0.0f); + } + clmd->clothObject->tree = bvh_build(clmd, 0.001f); + + } + + return 1; + default: return 0; // TODO - we do not support changing meshes + } +} + +// only meshes supported at the moment +static int cloth_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *dm, DerivedMesh *olddm, float framenr) +{ + unsigned int i; + unsigned int numverts = dm->getNumVerts(dm); + MVert *mvert = CDDM_get_verts(dm); + /* If we have a clothObject, free it. */ - if ( clmd->clothObject != NULL ) - cloth_free_modifier ( clmd ); + if (clmd->clothObject != NULL) + cloth_free_modifier (clmd); /* Allocate a new cloth object. */ - clmd->clothObject = MEM_callocN ( sizeof ( Cloth ), "cloth" ); - if ( clmd->clothObject ) + clmd->clothObject = MEM_callocN (sizeof(Cloth), "cloth"); + if (clmd->clothObject) { - clmd->clothObject->old_solver_type = 255; - // clmd->clothObject->old_collision_type = 255; + clmd->clothObject->old_solver_type = -1; } - else if ( !clmd->clothObject ) + else if (clmd->clothObject == NULL) { - modifier_setError ( & ( clmd->modifier ), "Out of memory on allocating clmd->clothObject." ); + modifier_setError (&(clmd->modifier), "Out of memory on allocating clmd->clothObject."); return 0; } + + printf("cloth_from_object\n"); - switch ( ob->type ) + switch (ob->type) { case OB_MESH: + + cloth_from_mesh (ob, clmd, dm, framenr); - // mesh input objects need DerivedMesh - if ( !dm ) - return 0; + if (clmd->clothObject != NULL) + { + /* create springs */ + clmd->clothObject->springs = NULL; + clmd->clothObject->numsprings = -1; - cloth_from_mesh ( ob, clmd, dm ); - - if ( clmd->clothObject != NULL ) + if (!cloth_build_springs (clmd->clothObject, dm) ) { - /* create springs */ - clmd->clothObject->springs = NULL; - clmd->clothObject->numsprings = -1; + modifier_setError (&(clmd->modifier), "Can't build springs."); + return 0; + } - if ( !cloth_build_springs ( clmd->clothObject, dm ) ) - { - modifier_setError ( & ( clmd->modifier ), "Can't build springs." ); - return 0; - } + /* set initial values */ + for (i = 0; i < numverts; ++i) + { + VECCOPY (clmd->clothObject->verts [i].x, mvert[i].co); + Mat4MulVecfl(ob->obmat, clmd->clothObject->verts [i].x); - mvert = dm->getVertArray ( dm ); // CDDM_get_verts ( dm ); - verts = clmd->clothObject->verts; - - /* set initial values */ - for ( i = 0; i < dm->getNumVerts(dm); i++, verts++ ) - { - VECCOPY ( verts->x, mvert[i].co ); - Mat4MulVecfl ( ob->obmat, verts->x ); - - verts->mass = clmd->sim_parms.mass; - - if ( clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_GOAL ) - verts->goal= clmd->sim_parms.defgoal; - else - verts->goal= 0.0f; - - verts->flags = 0; - VECCOPY ( verts->xold, verts->x ); - VECCOPY ( verts->xconst, verts->x ); - VECCOPY ( verts->txold, verts->x ); - VecMulf ( verts->v, 0.0f ); - - verts->impulse_count = 0; - VECCOPY ( verts->impulse, tnull ); - } - - // apply / set vertex groups - if ( clmd->sim_parms.vgroup_mass > 0 ) - cloth_apply_vgroup ( clmd, dm, clmd->sim_parms.vgroup_mass ); - - // init our solver - if ( solvers [clmd->sim_parms.solver_type].init ) - solvers [clmd->sim_parms.solver_type].init ( ob, clmd ); - - // clmd->clothObject->tree = bvh_build ( dm, clmd->coll_parms.epsilon ); - - cloth_cache_set_frame ( clmd, 1 ); + clmd->clothObject->verts [i].mass = clmd->sim_parms.mass; + clmd->clothObject->verts [i].goal= clmd->sim_parms.defgoal; + clmd->clothObject->verts [i].flags = 0; + VECCOPY(clmd->clothObject->verts [i].xold, clmd->clothObject->verts [i].x); + VECCOPY(clmd->clothObject->verts [i].xconst, clmd->clothObject->verts [i].x); + VECCOPY(clmd->clothObject->verts [i].txold, clmd->clothObject->verts [i].x); + VecMulf(clmd->clothObject->verts [i].v, 0.0f); } - return 1; + /* apply / set vertex groups */ + if (clmd->sim_parms.vgroup_mass > 0) + cloth_apply_vgroup (clmd, olddm, clmd->sim_parms.vgroup_mass); + + /* init our solver */ + if (solvers [clmd->sim_parms.solver_type].init) + solvers [clmd->sim_parms.solver_type].init (ob, clmd); + + clmd->clothObject->tree = bvh_build(clmd, clmd->coll_parms.epsilon); + + cloth_cache_set_frame(clmd, 1); + } + + return 1; case OB_LATTICE: - printf ( "Not supported: OB_LATTICE\n" ); - // lattice_to_softbody(ob); - return 1; + printf("OB_LATTICE\n"); + // lattice_to_softbody(ob); + return 1; case OB_CURVE: case OB_SURF: - printf ( "Not supported: OB_SURF| OB_CURVE\n" ); - return 1; + printf("OB_SURF| OB_CURVE\n"); + return 1; default: return 0; // TODO - we do not support changing meshes } - + return 0; } -static void cloth_from_mesh ( Object *ob, ClothModifierData *clmd, DerivedMesh *dm ) +static void cloth_from_mesh (Object *ob, ClothModifierData *clmd, DerivedMesh *dm, float framenr) { - unsigned int numverts = dm->getNumVerts ( dm ); - unsigned int numfaces = dm->getNumFaces ( dm ); - MFace *mface = dm->getFaceArray ( dm ); + unsigned int numverts = dm->getNumVerts(dm); + unsigned int numfaces = dm->getNumFaces(dm); + MFace *mface = CDDM_get_faces(dm); unsigned int i = 0; /* Allocate our vertices. */ clmd->clothObject->numverts = numverts; - clmd->clothObject->verts = MEM_callocN ( sizeof ( ClothVertex ) * clmd->clothObject->numverts, "clothVertex" ); - if ( clmd->clothObject->verts == NULL ) + clmd->clothObject->verts = MEM_callocN (sizeof (ClothVertex) * clmd->clothObject->numverts, "clothVertex"); + if (clmd->clothObject->verts == NULL) { - cloth_free_modifier ( clmd ); - modifier_setError ( & ( clmd->modifier ), "Out of memory on allocating clmd->clothObject->verts." ); + cloth_free_modifier (clmd); + modifier_setError (&(clmd->modifier), "Out of memory on allocating clmd->clothObject->verts."); return; } - clmd->clothObject->x = MEM_callocN ( sizeof ( MVert ) * clmd->clothObject->numverts, "Cloth MVert_x" ); - if ( clmd->clothObject->x == NULL ) + // collision objects need to cache face infos since they are needed during collision detection + // TODO: maybe cache it for cloth objects, too + if (clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_COLLOBJ) { - cloth_free_modifier ( clmd ); - modifier_setError ( & ( clmd->modifier ), "Out of memory on allocating clmd->clothObject->x." ); - return; + clmd->clothObject->numfaces = numfaces; + clmd->clothObject->mfaces = MEM_callocN (sizeof (MFace) * clmd->clothObject->numfaces, "clothMFaces"); + if (clmd->clothObject->mfaces == NULL) + { + cloth_free_modifier (clmd); + modifier_setError (&(clmd->modifier), "Out of memory on allocating clmd->clothObject->mfaces."); + return; + } + for(i = 0; i < numfaces; i++) + memcpy(&clmd->clothObject->mfaces[i], &mface[i], sizeof(MFace)); + } + else + { + clmd->clothObject->mfaces = mface; // update face pointer + clmd->clothObject->numfaces = numfaces; } - clmd->clothObject->xnew = MEM_callocN ( sizeof ( MVert ) * clmd->clothObject->numverts, "Cloth MVert_xnew" ); - if ( clmd->clothObject->xnew == NULL ) - { - cloth_free_modifier ( clmd ); - modifier_setError ( & ( clmd->modifier ), "Out of memory on allocating clmd->clothObject->xnew." ); - return; - } - - // save face information - clmd->clothObject->numfaces = numfaces; - clmd->clothObject->mfaces = MEM_callocN ( sizeof ( MFace ) * clmd->clothObject->numfaces, "clothMFaces" ); - if ( clmd->clothObject->mfaces == NULL ) - { - cloth_free_modifier ( clmd ); - modifier_setError ( & ( clmd->modifier ), "Out of memory on allocating clmd->clothObject->mfaces." ); - return; - } - for ( i = 0; i < numfaces; i++ ) - memcpy ( &clmd->clothObject->mfaces[i], &mface[i], sizeof ( MFace ) ); + // for SIP code + // clmd->clothObject->facemarks = MEM_callocN (sizeof (unsigned char) * clmd->clothObject->numfaces, "clothFaceMarks"); /* Free the springs since they can't be correct if the vertices * changed. */ - if ( clmd->clothObject->springs != NULL ) - MEM_freeN ( clmd->clothObject->springs ); + if (clmd->clothObject->springs != NULL) + MEM_freeN (clmd->clothObject->springs); } diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c index 4b65381c3b7..fcb56b56a5a 100644 --- a/source/blender/blenkernel/intern/modifier.c +++ b/source/blender/blenkernel/intern/modifier.c @@ -4892,18 +4892,19 @@ static void clothModifier_deformVerts( */ static DerivedMesh *clothModifier_applyModifier( - ModifierData *md, Object *ob, DerivedMesh *derivedData, - int useRenderParams, int isFinalCalc) + ModifierData *md, Object *ob, DerivedMesh *derivedData, + int useRenderParams, int isFinalCalc) { - DerivedMesh *result = NULL; - ClothModifierData *clmd = (ClothModifierData*) md; + DerivedMesh *result=NULL; - result = clothModifier_do(clmd, ob, derivedData); + result = clothModifier_do(clmd, ob, derivedData, useRenderParams, isFinalCalc); - CDDM_calc_normals(result); - - return result; + if(result) + { + return result; + } + return derivedData; } static void clothModifier_updateDepgraph( From 096a1e87fc179936edad72ef700bdf7fd672af8b Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Thu, 25 Oct 2007 22:09:06 +0000 Subject: [PATCH 036/246] Fixed all known crashers, still have to verify a few things, and compiling works on gxx too, now --- source/blender/blenkernel/BKE_cloth.h | 2 +- source/blender/blenkernel/intern/cloth.c | 131 ++++++----------------- 2 files changed, 36 insertions(+), 97 deletions(-) diff --git a/source/blender/blenkernel/BKE_cloth.h b/source/blender/blenkernel/BKE_cloth.h index 19851321b30..5379f0478d3 100644 --- a/source/blender/blenkernel/BKE_cloth.h +++ b/source/blender/blenkernel/BKE_cloth.h @@ -122,7 +122,7 @@ void cloth_free_modifier ( ClothModifierData *clmd ); void implicit_set_positions ( ClothModifierData *clmd ); // from cloth.c, needed for modifier.c -DerivedMesh *clothModifier_do(ClothModifierData *clmd, Object *ob, DerivedMesh *dm); +DerivedMesh *clothModifier_do(ClothModifierData *clmd,Object *ob, DerivedMesh *dm, int useRenderParams, int isFinalCalc); //////////////////////////////////////////////// diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c index 4692ee5fa3f..427b6bc6fe9 100644 --- a/source/blender/blenkernel/intern/cloth.c +++ b/source/blender/blenkernel/intern/cloth.c @@ -654,13 +654,7 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd,Object *ob, DerivedMesh *d // Insure we have a clmd->clothObject, in case allocation failed. if (clmd->clothObject != NULL) - { - - cloth->mfaces = mface; // update face pointer - ((BVH *)cloth->tree)->mfaces = mface; - cloth->numfaces = numfaces; - ((BVH *)cloth->tree)->numfaces = numfaces; - + { if(!cloth_cache_search_frame(clmd, framenr)) { /* Force any pinned verts to their constrained location. */ @@ -747,35 +741,39 @@ void cloth_free_modifier (ClothModifierData *clmd) // Free the verts. if (cloth->verts != NULL) MEM_freeN (cloth->verts); + + // Free the faces. + if ( cloth->mfaces != NULL ) + MEM_freeN ( cloth->mfaces ); // Free the verts. - if ( cloth->x != NULL ) - MEM_freeN ( cloth->x ); - - // Free the verts. - if ( cloth->xnew != NULL ) - MEM_freeN ( cloth->xnew ); + if ( cloth->x != NULL ) + MEM_freeN ( cloth->x ); + + // Free the verts. + if ( cloth->xnew != NULL ) + MEM_freeN ( cloth->xnew ); cloth->verts = NULL; cloth->numverts = -1; - // Free the springs. - if ( cloth->springs != NULL ) + // Free the springs. + if ( cloth->springs != NULL ) + { + LinkNode *search = cloth->springs; + while(search) { - LinkNode *search = cloth->springs; - while(search) - { - ClothSpring *spring = search->link; - - MEM_freeN ( spring ); - search = search->next; - } - BLI_linklist_free(cloth->springs, NULL); - - cloth->springs = NULL; + ClothSpring *spring = search->link; + + MEM_freeN ( spring ); + search = search->next; } + BLI_linklist_free(cloth->springs, NULL); + + cloth->springs = NULL; + } - cloth->numsprings = -1; + cloth->numsprings = -1; // free BVH collision tree if(cloth->tree) @@ -877,41 +875,6 @@ static void cloth_apply_vgroup(ClothModifierData *clmd, DerivedMesh *dm, short v } } } - -// only meshes supported at the moment -/* collision objects */ -static int collobj_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *dm, DerivedMesh *olddm, float framenr) -{ - unsigned int i; - unsigned int numverts = dm->getNumVerts(dm); - MVert *mvert = CDDM_get_verts(dm); - - switch (ob->type) - { - case OB_MESH: - cloth_from_mesh (ob, clmd, dm, framenr); - - if (clmd->clothObject != NULL) - { - - for (i = 0; i < numverts; ++i) - { - VECCOPY (clmd->clothObject->verts [i].x, mvert[i].co); - Mat4MulVecfl(ob->obmat, clmd->clothObject->verts [i].x); - clmd->clothObject->verts [i].flags = 0; - VECCOPY(clmd->clothObject->verts [i].xold, clmd->clothObject->verts [i].x); - VECCOPY(clmd->clothObject->verts [i].txold, clmd->clothObject->verts [i].x); - VECCOPY(clmd->clothObject->verts [i].tx, clmd->clothObject->verts [i].x); - VecMulf(clmd->clothObject->verts [i].v, 0.0f); - } - clmd->clothObject->tree = bvh_build(clmd, 0.001f); - - } - - return 1; - default: return 0; // TODO - we do not support changing meshes - } -} // only meshes supported at the moment static int cloth_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *dm, DerivedMesh *olddm, float framenr) @@ -928,15 +891,13 @@ static int cloth_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *d clmd->clothObject = MEM_callocN (sizeof(Cloth), "cloth"); if (clmd->clothObject) { - clmd->clothObject->old_solver_type = -1; + clmd->clothObject->old_solver_type = 255; } else if (clmd->clothObject == NULL) { modifier_setError (&(clmd->modifier), "Out of memory on allocating clmd->clothObject."); return 0; } - - printf("cloth_from_object\n"); switch (ob->type) { @@ -979,19 +940,11 @@ static int cloth_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *d if (solvers [clmd->sim_parms.solver_type].init) solvers [clmd->sim_parms.solver_type].init (ob, clmd); - clmd->clothObject->tree = bvh_build(clmd, clmd->coll_parms.epsilon); + clmd->clothObject->tree = NULL; // bvh_build(clmd, clmd->coll_parms.epsilon); cloth_cache_set_frame(clmd, 1); } - return 1; - case OB_LATTICE: - printf("OB_LATTICE\n"); - // lattice_to_softbody(ob); - return 1; - case OB_CURVE: - case OB_SURF: - printf("OB_SURF| OB_CURVE\n"); return 1; default: return 0; // TODO - we do not support changing meshes } @@ -1017,29 +970,15 @@ static void cloth_from_mesh (Object *ob, ClothModifierData *clmd, DerivedMesh *d return; } - // collision objects need to cache face infos since they are needed during collision detection - // TODO: maybe cache it for cloth objects, too - if (clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_COLLOBJ) + clmd->clothObject->numfaces = numfaces; + clmd->clothObject->mfaces = MEM_callocN (sizeof (MFace) * clmd->clothObject->numfaces, "clothMFaces"); + if (clmd->clothObject->mfaces == NULL) { - clmd->clothObject->numfaces = numfaces; - clmd->clothObject->mfaces = MEM_callocN (sizeof (MFace) * clmd->clothObject->numfaces, "clothMFaces"); - if (clmd->clothObject->mfaces == NULL) - { - cloth_free_modifier (clmd); - modifier_setError (&(clmd->modifier), "Out of memory on allocating clmd->clothObject->mfaces."); - return; - } - for(i = 0; i < numfaces; i++) - memcpy(&clmd->clothObject->mfaces[i], &mface[i], sizeof(MFace)); + cloth_free_modifier (clmd); + modifier_setError (&(clmd->modifier), "Out of memory on allocating clmd->clothObject->mfaces."); + return; } - else - { - clmd->clothObject->mfaces = mface; // update face pointer - clmd->clothObject->numfaces = numfaces; - } - - // for SIP code - // clmd->clothObject->facemarks = MEM_callocN (sizeof (unsigned char) * clmd->clothObject->numfaces, "clothFaceMarks"); + memcpy(clmd->clothObject->mfaces, mface, sizeof(MFace)*numfaces); /* Free the springs since they can't be correct if the vertices * changed. @@ -1133,7 +1072,7 @@ int cloth_build_springs ( Cloth *cloth, DerivedMesh *dm ) BLI_linklist_append ( &cloth->springs, spring ); } } - + // shear springs for ( i = 0; i < numfaces; i++ ) { From f59a4c22150f1db3f54e1d0847881e726518fc11 Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Thu, 25 Oct 2007 23:10:42 +0000 Subject: [PATCH 037/246] Fixing some goal problem --- source/blender/blenkernel/intern/cloth.c | 146 ++++++++++++++++------- 1 file changed, 106 insertions(+), 40 deletions(-) diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c index 427b6bc6fe9..5c23926e907 100644 --- a/source/blender/blenkernel/intern/cloth.c +++ b/source/blender/blenkernel/intern/cloth.c @@ -623,6 +623,44 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd,Object *ob, DerivedMesh *d result = CDDM_copy(dm); + // only be active during a specific period: + // that's "first frame" and "last frame" on GUI + if ( clmd->clothObject ) + { + if ( clmd->sim_parms.cache ) + { + if ( current_time < clmd->sim_parms.firstframe ) + { + int frametime = cloth_cache_first_frame ( clmd ); + if ( cloth_cache_search_frame ( clmd, frametime ) ) + { + cloth_cache_get_frame ( clmd, frametime ); + cloth_to_object ( ob, result, clmd ); + } + return; + } + else if ( current_time > clmd->sim_parms.lastframe ) + { + int frametime = cloth_cache_last_frame ( clmd ); + if ( cloth_cache_search_frame ( clmd, frametime ) ) + { + cloth_cache_get_frame ( clmd, frametime ); + cloth_to_object ( ob, result, clmd ); + } + return; + } + else if ( ABS ( deltaTime ) >= 2.0f ) // no timewarps allowed + { + if ( cloth_cache_search_frame ( clmd, framenr ) ) + { + cloth_cache_get_frame ( clmd, framenr ); + cloth_to_object ( ob, result, clmd ); + } + clmd->sim_parms.sim_time = current_time; + return; + } + } + if(!result) { return dm; @@ -657,19 +695,15 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd,Object *ob, DerivedMesh *d { if(!cloth_cache_search_frame(clmd, framenr)) { - /* Force any pinned verts to their constrained location. */ - for (i = 0; i < clmd->clothObject->numverts; i++) + // Force any pinned verts to their constrained location. + for ( i = 0; i < clmd->clothObject->numverts; i++, verts++ ) { - /* Save the previous position. */ - VECCOPY (cloth->verts [i].xold, cloth->verts [i].xconst); - VECCOPY (cloth->verts [i].txold, cloth->verts [i].x); - - /* Get the current position. */ - VECCOPY (cloth->verts [i].xconst, mvert[i].co); - Mat4MulVecfl(ob->obmat, cloth->verts [i].xconst); - - /* Compute the vertices velocity. */ - VECSUB (cloth->verts [i].v, cloth->verts [i].x, cloth->verts [i].xold); + // Save the previous position. + VECCOPY ( verts->xold, verts->xconst ); + VECCOPY ( verts->txold, verts->x ); + // Get the current position. + VECCOPY ( verts->xconst, mverts[i].co ); + Mat4MulVecfl ( ob->obmat, verts->xconst ); } tstart(); @@ -829,41 +863,46 @@ static void cloth_to_object (Object *ob, DerivedMesh *dm, ClothModifierData *cl **/ static void cloth_apply_vgroup(ClothModifierData *clmd, DerivedMesh *dm, short vgroup) { - unsigned int i; - int j; + unsigned int i = 0; + unsigned int j = 0; MDeformVert *dvert = NULL; - Cloth *clothObj; - unsigned int numverts = dm->getNumVerts(dm); - float goalfac; + Cloth *clothObj = NULL; + unsigned int numverts = 0; + float goalfac = 0; + ClothVertex *verts = NULL; clothObj = clmd->clothObject; + if ( !dm ) + return; + + numverts = dm->getNumVerts(dm); + /* vgroup is 1 based, decrement so we can match the right group. */ --vgroup; - for (i = 0; i < numverts; ++i) - { - /* so this will definily be below SOFTGOALSNAP */ - clothObj->verts [i].goal= 0.0f; - + verts = clothObj->verts; + + for ( i = 0; i < numverts; i++, verts++ ) + { // LATER ON, support also mass painting here - if(clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_GOAL) - { - dvert = dm->getVertData(dm, i, CD_MDEFORMVERT); - if(dvert) - { - for(j = 0; j < dvert->totweight; j++) + if ( clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_GOAL ) + { + dvert = dm->getVertData ( dm, i, CD_MDEFORMVERT ); + if ( dvert ) + { + for ( j = 0; j < dvert->totweight; j++ ) { - if(dvert->dw[j].def_nr == vgroup) + if ( dvert->dw[j].def_nr == vgroup ) { - clothObj->verts [i].goal = dvert->dw [j].weight; + verts->goal = dvert->dw [j].weight; - goalfac= ABS(clmd->sim_parms.maxgoal - clmd->sim_parms.mingoal); - clothObj->verts [i].goal = (float)pow(clothObj->verts [i].goal , 4.0f); + goalfac= ABS ( clmd->sim_parms.maxgoal - clmd->sim_parms.mingoal ); + verts->goal = ( float ) pow ( verts->goal , 4.0f ); - if(dvert->dw [j].weight >=SOFTGOALSNAP) + if ( dvert->dw [j].weight >=SOFTGOALSNAP ) { - clothObj->verts[i].flags |= CVERT_FLAG_PINNED; + verts->flags |= CVERT_FLAG_PINNED; } // TODO enable mass painting here, for the moment i let "goals" go first @@ -903,13 +942,17 @@ static int cloth_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *d { case OB_MESH: + // mesh input objects need DerivedMesh + if ( !dm ) + return 0; + cloth_from_mesh (ob, clmd, dm, framenr); - if (clmd->clothObject != NULL) - { - /* create springs */ - clmd->clothObject->springs = NULL; - clmd->clothObject->numsprings = -1; + if ( clmd->clothObject != NULL ) + { + /* create springs */ + clmd->clothObject->springs = NULL; + clmd->clothObject->numsprings = -1; if (!cloth_build_springs (clmd->clothObject, dm) ) { @@ -924,12 +967,18 @@ static int cloth_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *d Mat4MulVecfl(ob->obmat, clmd->clothObject->verts [i].x); clmd->clothObject->verts [i].mass = clmd->sim_parms.mass; - clmd->clothObject->verts [i].goal= clmd->sim_parms.defgoal; + if ( clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_GOAL ) + clmd->clothObject->verts [i].goal= clmd->sim_parms.defgoal; + else + clmd->clothObject->verts [i].goal= 0.0f; clmd->clothObject->verts [i].flags = 0; VECCOPY(clmd->clothObject->verts [i].xold, clmd->clothObject->verts [i].x); VECCOPY(clmd->clothObject->verts [i].xconst, clmd->clothObject->verts [i].x); VECCOPY(clmd->clothObject->verts [i].txold, clmd->clothObject->verts [i].x); VecMulf(clmd->clothObject->verts [i].v, 0.0f); + + clmd->clothObject->verts [i].impulse_count = 0; + VECCOPY ( clmd->clothObject->verts [i].impulse, tnull ); } /* apply / set vertex groups */ @@ -970,6 +1019,23 @@ static void cloth_from_mesh (Object *ob, ClothModifierData *clmd, DerivedMesh *d return; } + clmd->clothObject->x = MEM_callocN ( sizeof ( MVert ) * clmd->clothObject->numverts, "Cloth MVert_x" ); + if ( clmd->clothObject->x == NULL ) + { + cloth_free_modifier ( clmd ); + modifier_setError ( & ( clmd->modifier ), "Out of memory on allocating clmd->clothObject->x." ); + return; + } + + clmd->clothObject->xnew = MEM_callocN ( sizeof ( MVert ) * clmd->clothObject->numverts, "Cloth MVert_xnew" ); + if ( clmd->clothObject->xnew == NULL ) + { + cloth_free_modifier ( clmd ); + modifier_setError ( & ( clmd->modifier ), "Out of memory on allocating clmd->clothObject->xnew." ); + return; + } + + // save face information clmd->clothObject->numfaces = numfaces; clmd->clothObject->mfaces = MEM_callocN (sizeof (MFace) * clmd->clothObject->numfaces, "clothMFaces"); if (clmd->clothObject->mfaces == NULL) From a61fb914ecfe8ba6af4de33db6bbb89d74f67bcd Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Fri, 26 Oct 2007 10:46:40 +0000 Subject: [PATCH 038/246] Fixed compiling errors + introduced old speedup for springs again --- source/blender/blenkernel/BKE_cloth.h | 2 + source/blender/blenkernel/intern/cloth.c | 202 +++++++++++++------- source/blender/blenkernel/intern/implicit.c | 46 ++--- source/blender/makesdna/DNA_cloth_types.h | 12 +- 4 files changed, 164 insertions(+), 98 deletions(-) diff --git a/source/blender/blenkernel/BKE_cloth.h b/source/blender/blenkernel/BKE_cloth.h index 5379f0478d3..6b1110d6625 100644 --- a/source/blender/blenkernel/BKE_cloth.h +++ b/source/blender/blenkernel/BKE_cloth.h @@ -173,6 +173,8 @@ typedef struct Frame ClothSpring *springs; unsigned int numverts, numsprings; float time; /* we need float since we want to support sub-frames */ + float (*x)[3]; + float (*xold)[3]; } Frame; diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c index 5c23926e907..c4c32d48b82 100644 --- a/source/blender/blenkernel/intern/cloth.c +++ b/source/blender/blenkernel/intern/cloth.c @@ -123,7 +123,7 @@ static CM_SOLVER_DEF solvers [] = static void cloth_to_object (Object *ob, DerivedMesh *dm, ClothModifierData *clmd); static void cloth_from_mesh (Object *ob, ClothModifierData *clmd, DerivedMesh *dm, float framenr); static int cloth_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *dm, DerivedMesh *olddm, float framenr); -static int collobj_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *dm, DerivedMesh *olddm, float framenr); + int cloth_build_springs ( Cloth *cloth, DerivedMesh *dm ); static void cloth_apply_vgroup(ClothModifierData *clmd, DerivedMesh *dm, short vgroup); /****************************************************************************** @@ -179,6 +179,7 @@ void cloth_init (ClothModifierData *clmd) // unused in the moment, cloth needs quads from mesh DerivedMesh *CDDM_convert_to_triangle(DerivedMesh *dm) { + /* DerivedMesh *result = NULL; int i; int numverts = dm->getNumVerts(dm); @@ -234,11 +235,11 @@ DerivedMesh *CDDM_convert_to_triangle(DerivedMesh *dm) MFace *inMF; inMF = &mface[a]; - /* - DM_copy_face_data(dm, result, a, i, 1); + + // DM_copy_face_data(dm, result, a, i, 1); - *mf = *inMF; - */ + // *mf = *inMF; + if(mface[a].v4 && random==1) { @@ -265,11 +266,11 @@ DerivedMesh *CDDM_convert_to_triangle(DerivedMesh *dm) i++; mf2 = &mface2[i]; - /* - DM_copy_face_data(dm, result, a, i, 1); + + // DM_copy_face_data(dm, result, a, i, 1); - *mf2 = *inMF; - */ + // *mf2 = *inMF; + if(random==1) { @@ -296,7 +297,9 @@ DerivedMesh *CDDM_convert_to_triangle(DerivedMesh *dm) CDDM_calc_normals(result); return result; - + */ + + return NULL; } @@ -395,6 +398,8 @@ DerivedMesh *CDDM_create_tearing(ClothModifierData *clmd, DerivedMesh *dm) return result; */ + + return NULL; } @@ -505,6 +510,11 @@ void cloth_cache_get_frame ( ClothModifierData *clmd, float time ) } memcpy ( clmd->clothObject->verts, frame->verts, sizeof ( ClothVertex ) *frame->numverts ); + + memcpy ( clmd->clothObject->x, frame->x, sizeof ( float ) *frame->numverts * 3); + + memcpy ( clmd->clothObject->xold, frame->xold, sizeof ( float ) *frame->numverts * 3); + implicit_set_positions ( clmd ); return; @@ -519,7 +529,6 @@ void cloth_cache_get_frame ( ClothModifierData *clmd, float time ) void cloth_cache_set_frame ( ClothModifierData *clmd, float time ) { Frame *frame = NULL; - LinkNode *search = NULL; if ( clmd->clothObject ) { @@ -536,7 +545,26 @@ void cloth_cache_set_frame ( ClothModifierData *clmd, float time ) MEM_freeN ( frame ); return; } - + + frame->x = MEM_dupallocN ( clmd->clothObject->x ); + + if ( !frame->x ) + { + MEM_freeN ( frame->verts ); + MEM_freeN ( frame ); + return; + } + + frame->xold = MEM_dupallocN ( clmd->clothObject->xold ); + + if ( !frame->xold ) + { + MEM_freeN ( frame->verts ); + MEM_freeN ( frame->x ); + MEM_freeN ( frame ); + return; + } + BLI_linklist_append ( &clmd->sim_parms.cache, frame ); } @@ -570,6 +598,14 @@ void cloth_cache_free ( ClothModifierData *clmd, float time ) { MEM_freeN ( frame->verts ); } + if ( frame->x ) + { + MEM_freeN ( frame->x ); + } + if ( frame->xold ) + { + MEM_freeN ( frame->xold ); + } MEM_freeN ( frame ); lastsearch->next = search->next; @@ -609,22 +645,35 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd,Object *ob, DerivedMesh *d MVert *mvert = NULL; MEdge *medge = NULL; MFace *mface = NULL; - DerivedMesh *result = NULL, *result2 = NULL; + DerivedMesh *result = NULL; Cloth *cloth = clmd->clothObject; unsigned int framenr = (float)G.scene->r.cfra; float current_time = bsystem_time(ob, (float)G.scene->r.cfra, 0.0); - ListBase *effectors = NULL; - ClothVertex *newframe= NULL; - Frame *frame = NULL; - LinkNode *search = NULL; + ListBase *effectors = NULL; + ClothVertex *verts = NULL; float deltaTime = current_time - clmd->sim_parms.sim_time; clmd->sim_parms.dt = 1.0f / (clmd->sim_parms.stepsPerFrame * G.scene->r.frs_sec); result = CDDM_copy(dm); + + if(!result) + { + return dm; + } + + numverts = result->getNumVerts(result); + numedges = result->getNumEdges(result); + numfaces = result->getNumFaces(result); + mvert = CDDM_get_verts(result); + medge = CDDM_get_edges(result); + mface = CDDM_get_faces(result); + + clmd->sim_parms.sim_time = current_time; // only be active during a specific period: // that's "first frame" and "last frame" on GUI + /* if ( clmd->clothObject ) { if ( clmd->sim_parms.cache ) @@ -637,7 +686,7 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd,Object *ob, DerivedMesh *d cloth_cache_get_frame ( clmd, frametime ); cloth_to_object ( ob, result, clmd ); } - return; + return result; } else if ( current_time > clmd->sim_parms.lastframe ) { @@ -647,7 +696,7 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd,Object *ob, DerivedMesh *d cloth_cache_get_frame ( clmd, frametime ); cloth_to_object ( ob, result, clmd ); } - return; + return result; } else if ( ABS ( deltaTime ) >= 2.0f ) // no timewarps allowed { @@ -657,23 +706,11 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd,Object *ob, DerivedMesh *d cloth_to_object ( ob, result, clmd ); } clmd->sim_parms.sim_time = current_time; - return; + return result; } } - - if(!result) - { - return dm; } - - numverts = result->getNumVerts(result); - numedges = result->getNumEdges(result); - numfaces = result->getNumFaces(result); - mvert = CDDM_get_verts(result); - medge = CDDM_get_edges(result); - mface = CDDM_get_faces(result); - - clmd->sim_parms.sim_time = current_time; + */ if(deltaTime == 1.0f) { @@ -695,28 +732,29 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd,Object *ob, DerivedMesh *d { if(!cloth_cache_search_frame(clmd, framenr)) { + verts = cloth->verts; + // Force any pinned verts to their constrained location. for ( i = 0; i < clmd->clothObject->numverts; i++, verts++ ) { // Save the previous position. - VECCOPY ( verts->xold, verts->xconst ); - VECCOPY ( verts->txold, verts->x ); + VECCOPY ( cloth->xold[i], verts->xconst ); + VECCOPY ( cloth->current_xold[i], cloth->x[i] ); // Get the current position. - VECCOPY ( verts->xconst, mverts[i].co ); + VECCOPY ( verts->xconst, mvert[i].co ); Mat4MulVecfl ( ob->obmat, verts->xconst ); } - + tstart(); - + /* Call the solver. */ - if (solvers [clmd->sim_parms.solver_type].solver) solvers [clmd->sim_parms.solver_type].solver (ob, framenr, clmd, effectors); - + tend(); - - // printf("Cloth simulation time: %f\n", (float)tval()); - + + printf("Cloth simulation time: %f\n", tval()); + cloth_cache_set_frame(clmd, framenr); } @@ -785,8 +823,16 @@ void cloth_free_modifier (ClothModifierData *clmd) MEM_freeN ( cloth->x ); // Free the verts. - if ( cloth->xnew != NULL ) - MEM_freeN ( cloth->xnew ); + if ( cloth->xold != NULL ) + MEM_freeN ( cloth->xold ); + + // Free the verts. + if ( cloth->current_x != NULL ) + MEM_freeN ( cloth->current_x ); + + // Free the verts. + if ( cloth->current_xold != NULL ) + MEM_freeN ( cloth->current_xold ); cloth->verts = NULL; cloth->numverts = -1; @@ -834,23 +880,21 @@ void cloth_free_modifier (ClothModifierData *clmd) **/ static void cloth_to_object (Object *ob, DerivedMesh *dm, ClothModifierData *clmd) { - ClothVertex *verts = NULL; unsigned int i = 0; MVert *mvert = NULL; unsigned int numverts; + Cloth *cloth = clmd->clothObject; if (clmd->clothObject) { - verts = clmd->clothObject->verts; - /* inverse matrix is not uptodate... */ Mat4Invert (ob->imat, ob->obmat); mvert = CDDM_get_verts(dm); numverts = dm->getNumVerts(dm); - for (i = 0; i < numverts; i++, verts++) + for (i = 0; i < numverts; i++) { - VECCOPY (mvert[i].co, verts->x); + VECCOPY (mvert[i].co, cloth->x[i]); Mat4MulVecfl (ob->imat, mvert[i].co); /* softbody is in global coords */ } } @@ -921,6 +965,7 @@ static int cloth_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *d unsigned int i; unsigned int numverts = dm->getNumVerts(dm); MVert *mvert = CDDM_get_verts(dm); + float tnull[3] = {0,0,0}; /* If we have a clothObject, free it. */ if (clmd->clothObject != NULL) @@ -963,8 +1008,8 @@ static int cloth_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *d /* set initial values */ for (i = 0; i < numverts; ++i) { - VECCOPY (clmd->clothObject->verts [i].x, mvert[i].co); - Mat4MulVecfl(ob->obmat, clmd->clothObject->verts [i].x); + VECCOPY (clmd->clothObject->x[i], mvert[i].co); + Mat4MulVecfl(ob->obmat, clmd->clothObject->x[i]); clmd->clothObject->verts [i].mass = clmd->sim_parms.mass; if ( clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_GOAL ) @@ -972,9 +1017,9 @@ static int cloth_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *d else clmd->clothObject->verts [i].goal= 0.0f; clmd->clothObject->verts [i].flags = 0; - VECCOPY(clmd->clothObject->verts [i].xold, clmd->clothObject->verts [i].x); - VECCOPY(clmd->clothObject->verts [i].xconst, clmd->clothObject->verts [i].x); - VECCOPY(clmd->clothObject->verts [i].txold, clmd->clothObject->verts [i].x); + VECCOPY(clmd->clothObject->xold[i], clmd->clothObject->x[i]); + VECCOPY(clmd->clothObject->verts [i].xconst, clmd->clothObject->x[i]); + VECCOPY(clmd->clothObject->current_xold[i], clmd->clothObject->x[i]); VecMulf(clmd->clothObject->verts [i].v, 0.0f); clmd->clothObject->verts [i].impulse_count = 0; @@ -991,7 +1036,7 @@ static int cloth_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *d clmd->clothObject->tree = NULL; // bvh_build(clmd, clmd->coll_parms.epsilon); - cloth_cache_set_frame(clmd, 1); + // cloth_cache_set_frame(clmd, 1); } return 1; @@ -1006,7 +1051,6 @@ static void cloth_from_mesh (Object *ob, ClothModifierData *clmd, DerivedMesh *d unsigned int numverts = dm->getNumVerts(dm); unsigned int numfaces = dm->getNumFaces(dm); MFace *mface = CDDM_get_faces(dm); - unsigned int i = 0; /* Allocate our vertices. */ @@ -1019,7 +1063,7 @@ static void cloth_from_mesh (Object *ob, ClothModifierData *clmd, DerivedMesh *d return; } - clmd->clothObject->x = MEM_callocN ( sizeof ( MVert ) * clmd->clothObject->numverts, "Cloth MVert_x" ); + clmd->clothObject->x = MEM_callocN ( sizeof ( float ) * clmd->clothObject->numverts * 3, "Cloth MVert_x" ); if ( clmd->clothObject->x == NULL ) { cloth_free_modifier ( clmd ); @@ -1027,11 +1071,27 @@ static void cloth_from_mesh (Object *ob, ClothModifierData *clmd, DerivedMesh *d return; } - clmd->clothObject->xnew = MEM_callocN ( sizeof ( MVert ) * clmd->clothObject->numverts, "Cloth MVert_xnew" ); - if ( clmd->clothObject->xnew == NULL ) + clmd->clothObject->xold = MEM_callocN ( sizeof ( float ) * clmd->clothObject->numverts * 3, "Cloth MVert_xold" ); + if ( clmd->clothObject->xold == NULL ) { cloth_free_modifier ( clmd ); - modifier_setError ( & ( clmd->modifier ), "Out of memory on allocating clmd->clothObject->xnew." ); + modifier_setError ( & ( clmd->modifier ), "Out of memory on allocating clmd->clothObject->xold." ); + return; + } + + clmd->clothObject->current_x = MEM_callocN ( sizeof ( float ) * clmd->clothObject->numverts * 3, "Cloth MVert_current_x" ); + if ( clmd->clothObject->current_x == NULL ) + { + cloth_free_modifier ( clmd ); + modifier_setError ( & ( clmd->modifier ), "Out of memory on allocating clmd->clothObject->current_x." ); + return; + } + + clmd->clothObject->current_xold = MEM_callocN ( sizeof ( float ) * clmd->clothObject->numverts * 3, "Cloth MVert_current_xold" ); + if ( clmd->clothObject->current_xold == NULL ) + { + cloth_free_modifier ( clmd ); + modifier_setError ( & ( clmd->modifier ), "Out of memory on allocating clmd->clothObject->current_xold." ); return; } @@ -1101,7 +1161,8 @@ int cloth_build_springs ( Cloth *cloth, DerivedMesh *dm ) EdgeHash *edgehash = NULL; LinkNode *search = NULL, *search2 = NULL; float temp[3]; - + LinkNode *node = NULL, *node2 = NULL; + // error handling if ( numedges==0 ) return 0; @@ -1134,8 +1195,12 @@ int cloth_build_springs ( Cloth *cloth, DerivedMesh *dm ) spring->type = CLOTH_SPRING_TYPE_STRUCTURAL; spring->flags = 0; struct_springs++; - - BLI_linklist_append ( &cloth->springs, spring ); + + if(!i) + node2 = BLI_linklist_append_fast ( &cloth->springs, spring ); + else + node2 = BLI_linklist_append_fast ( &node->next, spring ); + node = node2; } } @@ -1154,7 +1219,8 @@ int cloth_build_springs ( Cloth *cloth, DerivedMesh *dm ) BLI_linklist_append ( &edgelist[spring->kl], spring ); shear_springs++; - BLI_linklist_append ( &cloth->springs, spring ); + node2 = BLI_linklist_append_fast ( &node->next, spring ); + node = node2; if ( mface[i].v4 ) { @@ -1170,7 +1236,8 @@ int cloth_build_springs ( Cloth *cloth, DerivedMesh *dm ) BLI_linklist_append ( &edgelist[spring->kl], spring ); shear_springs++; - BLI_linklist_append ( &cloth->springs, spring ); + node2 = BLI_linklist_append_fast ( &node->next, spring ); + node = node2; } } @@ -1204,7 +1271,8 @@ int cloth_build_springs ( Cloth *cloth, DerivedMesh *dm ) BLI_edgehash_insert ( edgehash, spring->ij, index2, NULL ); bend_springs++; - BLI_linklist_append ( &cloth->springs, spring ); + node2 = BLI_linklist_append_fast ( &node->next, spring ); + node = node2; } search = search->next; } diff --git a/source/blender/blenkernel/intern/implicit.c b/source/blender/blenkernel/intern/implicit.c index f61e2d22f1c..e28930fa052 100644 --- a/source/blender/blenkernel/intern/implicit.c +++ b/source/blender/blenkernel/intern/implicit.c @@ -770,7 +770,7 @@ int implicit_init (Object *ob, ClothModifierData *clmd) for(i = 0; i < cloth->numverts; i++) { - VECCOPY(id->X[i], verts[i].x); + VECCOPY(id->X[i], cloth->x[i]); } return 1; @@ -1165,7 +1165,6 @@ DO_INLINE void cloth_calc_spring_force(ClothModifierData *clmd, ClothSpring *s, float damping_force[3] = {0,0,0}; float nulldfdx[3][3]={ {0,0,0}, {0,0,0}, {0,0,0}}; Cloth *cloth = clmd->clothObject; - ClothVertex *verts = cloth->verts; VECCOPY(s->f, nullf); cp_fmatrix(s->dfdx, nulldfdx); @@ -1336,16 +1335,16 @@ void cloth_calc_force(ClothModifierData *clmd, lfVector *lF, lfVector *lX, lfVec if(verts [i].goal < SOFTGOALSNAP) { // current_position = xold + t * (newposition - xold) - VECSUB(tvect, verts[i].xconst, verts[i].xold); + VECSUB(tvect, verts[i].xconst, cloth->xold[i]); mul_fvector_S(tvect, tvect, time); - VECADD(tvect, tvect, verts[i].xold); + VECADD(tvect, tvect, cloth->xold[i]); VECSUB(auxvect, tvect, lX[i]); ks = 1.0f/(1.0f- verts [i].goal*clmd->sim_parms.goalspring)-1.0f ; VECADDS(lF[i], lF[i], auxvect, -ks); // calulate damping forces generated by goals - VECSUB(velgoal,verts[i].xold, verts[i].xconst); + VECSUB(velgoal, cloth->xold[i], verts[i].xconst); kd = clmd->sim_parms.goalfrict * 0.01f; // friction force scale taken from SB VECSUBADDSS(lF[i], velgoal, kd, lV[i], kd); @@ -1433,7 +1432,7 @@ void simulate_implicit_euler(lfVector *Vnew, lfVector *lX, lfVector *lV, lfVecto int implicit_solver (Object *ob, float frame, ClothModifierData *clmd, ListBase *effectors) { - unsigned int i=0, j; + unsigned int i=0; float step=0.0f, tf=1.0f; Cloth *cloth = clmd->clothObject; ClothVertex *verts = cloth->verts; @@ -1449,7 +1448,7 @@ int implicit_solver (Object *ob, float frame, ClothModifierData *clmd, ListBase // update velocities with constrained velocities from pinned verts if(verts [i].goal >= SOFTGOALSNAP) { - VECSUB(id->V[i], verts[i].xconst, verts[i].xold); + VECSUB(id->V[i], verts[i].xconst, cloth->xold[i]); // VecMulf(id->V[i], 1.0 / dt); } } @@ -1480,15 +1479,15 @@ int implicit_solver (Object *ob, float frame, ClothModifierData *clmd, ListBase float tvect[3] = {.0,.0,.0}; // VECSUB(tvect, id->Xnew[i], verts[i].xold); mul_fvector_S(tvect, id->V[i], step+dt); - VECADD(tvect, tvect, verts[i].xold); + VECADD(tvect, tvect, cloth->xold[i]); VECCOPY(id->Xnew[i], tvect); } } - VECCOPY(verts[i].tx, id->Xnew[i]); + VECCOPY(cloth->current_x[i], id->Xnew[i]); - VECSUB(verts[i].tv, verts[i].tx, verts[i].txold); + VECSUB(verts[i].tv, cloth->current_x[i], cloth->current_xold[i]); VECCOPY(verts[i].v, verts[i].tv); } @@ -1502,16 +1501,16 @@ int implicit_solver (Object *ob, float frame, ClothModifierData *clmd, ListBase { // VECADD(verts[i].tx, verts[i].txold, verts[i].tv); - VECCOPY(verts[i].txold, verts[i].tx); + VECCOPY(cloth->current_xold[i], cloth->current_x[i]); - VECCOPY(id->Xnew[i], verts[i].tx); + VECCOPY(id->Xnew[i], cloth->current_x[i]); VECCOPY(id->Vnew[i], verts[i].tv); VecMulf(id->Vnew[i], 1.0f / dt); } else { - VECCOPY(verts[i].txold, id->Xnew[i]); + VECCOPY(cloth->current_xold[i], id->Xnew[i]); } } @@ -1552,21 +1551,21 @@ int implicit_solver (Object *ob, float frame, ClothModifierData *clmd, ListBase { if(verts [i].goal < SOFTGOALSNAP) { - VECCOPY(verts[i].txold, id->X[i]); - VECCOPY(verts[i].x, id->X[i]); + VECCOPY(cloth->current_xold[i], id->X[i]); + VECCOPY(cloth->x[i], id->X[i]); VECCOPY(verts[i].v, id->V[i]); } else { - VECCOPY(verts[i].txold, verts[i].xconst); - VECCOPY(verts[i].x, verts[i].xconst); + VECCOPY(cloth->current_xold[i], verts[i].xconst); + VECCOPY(cloth->x[i], verts[i].xconst); VECCOPY(verts[i].v, id->V[i]); } } else { - VECCOPY(verts[i].txold, id->X[i]); - VECCOPY(verts[i].x, id->X[i]); + VECCOPY(cloth->current_xold[i], id->X[i]); + VECCOPY(cloth->x[i], id->X[i]); VECCOPY(verts[i].v, id->V[i]); } } @@ -1582,7 +1581,7 @@ void implicit_set_positions (ClothModifierData *clmd) for(i = 0; i < numverts; i++) { - VECCOPY(id->X[i], verts[i].x); + VECCOPY(id->X[i], cloth->x[i]); VECCOPY(id->V[i], verts[i].v); } } @@ -1841,7 +1840,7 @@ int collisions_are_edges_adjacent(ClothModifierData *clmd, ClothModifierData *co Cloth *cloth1, *cloth2; ClothVertex *verts1, *verts2; float temp[3]; - + /* cloth1 = clmd->clothObject; cloth2 = coll_clmd->clothObject; @@ -1863,7 +1862,7 @@ int collisions_are_edges_adjacent(ClothModifierData *clmd, ClothModifierData *co VECSUB(temp, verts1[edgecollpair->p12].xold, verts2[edgecollpair->p22].xold); if(ABS(INPR(temp, temp)) < ALMOST_ZERO) return 1; - + */ return 0; } @@ -2109,7 +2108,7 @@ void collisions_update_collision_objects(float step) ClothModifierData *coll_clmd=NULL; Object *coll_ob=NULL; unsigned int i=0; - + /* // search all objects for collision object for (base = G.scene->base.first; base; base = base->next) { @@ -2146,6 +2145,7 @@ void collisions_update_collision_objects(float step) printf ("collisions_bvh_objcollision: found a collision object with clothObject or collData NULL.\n"); } } + */ } diff --git a/source/blender/makesdna/DNA_cloth_types.h b/source/blender/makesdna/DNA_cloth_types.h index b4592e4d724..e1b1e3ce84a 100644 --- a/source/blender/makesdna/DNA_cloth_types.h +++ b/source/blender/makesdna/DNA_cloth_types.h @@ -45,10 +45,6 @@ typedef struct ClothVertex int flags; /* General flags per vertex. */ float v [3]; /* The velocity of the point. */ float xconst [3]; /* constrained position */ - float x [3]; /* The current position of this vertex. */ - float xold [3]; /* The previous position of this vertex.*/ - float tx [3]; /* temporary position */ - float txold [3]; /* temporary old position */ float tv[3]; /* temporary "velocity", mostly used as tv = tx-txold */ float mass; /* mass / weight of the vertex */ float goal; /* goal, from SB */ @@ -159,10 +155,10 @@ typedef struct Cloth struct CollisionTree *tree; /* collision tree for this cloth object */ struct MFace *mfaces; struct Implicit_Data *implicit; /* our implicit solver connects to this pointer */ - struct MVert *x; - struct MVert *xnew; - struct MVert *current_x; - struct MVert *current_xnew; + float (*x)[3]; /* The current position of all vertices.*/ + float (*xold)[3]; /* The previous position of all vertices.*/ + float (*current_x)[3]; /* The TEMPORARY current position of all vertices.*/ + float (*current_xold)[3]; /* The TEMPORARY previous position of all vertices.*/ } Cloth; From 4f72523654b0344e8398707edb228182a807d278 Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Fri, 26 Oct 2007 15:13:50 +0000 Subject: [PATCH 039/246] Weekend commit: Enabled bounding box check for cloth again, but there's a bug in it (no collisions detected) --- source/blender/blenkernel/BKE_cloth.h | 5 + source/blender/blenkernel/BKE_collisions.h | 10 +- source/blender/blenkernel/intern/cloth.c | 65 +++- source/blender/blenkernel/intern/collision.c | 8 +- source/blender/blenkernel/intern/implicit.c | 350 ++++--------------- source/blender/blenkernel/intern/kdop.c | 89 ++++- source/blender/blenkernel/intern/modifier.c | 15 +- source/blender/makesdna/DNA_cloth_types.h | 6 +- 8 files changed, 240 insertions(+), 308 deletions(-) diff --git a/source/blender/blenkernel/BKE_cloth.h b/source/blender/blenkernel/BKE_cloth.h index 6b1110d6625..c0327ebe6db 100644 --- a/source/blender/blenkernel/BKE_cloth.h +++ b/source/blender/blenkernel/BKE_cloth.h @@ -124,6 +124,9 @@ void implicit_set_positions ( ClothModifierData *clmd ); // from cloth.c, needed for modifier.c DerivedMesh *clothModifier_do(ClothModifierData *clmd,Object *ob, DerivedMesh *dm, int useRenderParams, int isFinalCalc); +// needed in implicit.c +int cloth_bvh_objcollision(ClothModifierData * clmd, float step, float prevstep, float dt); + //////////////////////////////////////////////// @@ -175,6 +178,8 @@ typedef struct Frame float time; /* we need float since we want to support sub-frames */ float (*x)[3]; float (*xold)[3]; + float (*v)[3]; + float (*current_xold)[3]; } Frame; diff --git a/source/blender/blenkernel/BKE_collisions.h b/source/blender/blenkernel/BKE_collisions.h index 0a79bb46262..6422ad65c0b 100644 --- a/source/blender/blenkernel/BKE_collisions.h +++ b/source/blender/blenkernel/BKE_collisions.h @@ -68,9 +68,9 @@ typedef struct BVH MVert *x; // position of verts at time n-1 MFace *mfaces; // just a pointer to the original datastructure struct LinkNode *tree; - TreeNode *root; // TODO: saving the root --> is this really needed? YES! - TreeNode *leaf_tree; /* Tail of the leaf linked list. */ - TreeNode *leaf_root; /* Head of the leaf linked list. */ + CollisionTree *root; // TODO: saving the root --> is this really needed? YES! + CollisionTree *leaf_tree; /* Tail of the leaf linked list. */ + CollisionTree *leaf_root; /* Head of the leaf linked list. */ float epsilon; /* epslion is used for inflation of the k-dop */ int flags; /* bvhFlags */ } @@ -90,6 +90,7 @@ CollisionPair; // builds bounding volume hierarchy BVH *bvh_build_from_mvert (MFace *mfaces, unsigned int numfaces, MVert *x, unsigned int numverts, float epsilon); +BVH *bvh_build_from_float3 (MFace *mfaces, unsigned int numfaces, float (*x)[3], unsigned int numverts, float epsilon); // frees the same void bvh_free ( BVH *bvh ); @@ -99,12 +100,13 @@ int bvh_traverse(CollisionTree *tree1, CollisionTree *tree2, LinkNode *collision // update bounding volumes, needs updated positions in bvh->x void bvh_update_from_mvert(BVH * bvh, MVert *x, unsigned int numverts, MVert *xnew, int moving); +void bvh_update_from_float3(BVH * bvh, float (*x)[3], unsigned int numverts, float (*xnew)[3], int moving); LinkNode *BLI_linklist_append_fast (LinkNode **listp, void *ptr); // move Collision modifier object inter-frame with step = [0,1] // defined in collisions.c -void collision_move_object(CollisionModifierData *collmd, float step); +void collision_move_object(CollisionModifierData *collmd, float step, float prevstep); ///////////////////////////////////////////////// diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c index c4c32d48b82..bb99709b73a 100644 --- a/source/blender/blenkernel/intern/cloth.c +++ b/source/blender/blenkernel/intern/cloth.c @@ -515,6 +515,10 @@ void cloth_cache_get_frame ( ClothModifierData *clmd, float time ) memcpy ( clmd->clothObject->xold, frame->xold, sizeof ( float ) *frame->numverts * 3); + memcpy ( clmd->clothObject->v, frame->v, sizeof ( float ) *frame->numverts * 3); + + memcpy ( clmd->clothObject->current_xold, frame->current_xold, sizeof ( float ) *frame->numverts * 3); + implicit_set_positions ( clmd ); return; @@ -565,6 +569,29 @@ void cloth_cache_set_frame ( ClothModifierData *clmd, float time ) return; } + frame->v = MEM_dupallocN ( clmd->clothObject->v ); + + if ( !frame->v ) + { + MEM_freeN ( frame->verts ); + MEM_freeN ( frame->x ); + MEM_freeN ( frame->xold ); + MEM_freeN ( frame ); + return; + } + + frame->current_xold= MEM_dupallocN ( clmd->clothObject->current_xold ); + + if ( !frame->current_xold ) + { + MEM_freeN ( frame->verts ); + MEM_freeN ( frame->x ); + MEM_freeN ( frame->xold ); + MEM_freeN ( frame->v ); + MEM_freeN ( frame ); + return; + } + BLI_linklist_append ( &clmd->sim_parms.cache, frame ); } @@ -606,6 +633,14 @@ void cloth_cache_free ( ClothModifierData *clmd, float time ) { MEM_freeN ( frame->xold ); } + if ( frame->v ) + { + MEM_freeN ( frame->v ); + } + if ( frame->current_xold ) + { + MEM_freeN ( frame->current_xold ); + } MEM_freeN ( frame ); lastsearch->next = search->next; @@ -825,6 +860,10 @@ void cloth_free_modifier (ClothModifierData *clmd) // Free the verts. if ( cloth->xold != NULL ) MEM_freeN ( cloth->xold ); + + // Free the verts. + if ( cloth->v != NULL ) + MEM_freeN ( cloth->v ); // Free the verts. if ( cloth->current_x != NULL ) @@ -833,6 +872,10 @@ void cloth_free_modifier (ClothModifierData *clmd) // Free the verts. if ( cloth->current_xold != NULL ) MEM_freeN ( cloth->current_xold ); + + // Free the verts. + if ( cloth->current_v != NULL ) + MEM_freeN ( cloth->current_v ); cloth->verts = NULL; cloth->numverts = -1; @@ -991,7 +1034,7 @@ static int cloth_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *d if ( !dm ) return 0; - cloth_from_mesh (ob, clmd, dm, framenr); + cloth_from_mesh (ob, clmd, dm, framenr); if ( clmd->clothObject != NULL ) { @@ -1020,7 +1063,7 @@ static int cloth_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *d VECCOPY(clmd->clothObject->xold[i], clmd->clothObject->x[i]); VECCOPY(clmd->clothObject->verts [i].xconst, clmd->clothObject->x[i]); VECCOPY(clmd->clothObject->current_xold[i], clmd->clothObject->x[i]); - VecMulf(clmd->clothObject->verts [i].v, 0.0f); + VecMulf(clmd->clothObject->v[i], 0.0f); clmd->clothObject->verts [i].impulse_count = 0; VECCOPY ( clmd->clothObject->verts [i].impulse, tnull ); @@ -1034,7 +1077,7 @@ static int cloth_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *d if (solvers [clmd->sim_parms.solver_type].init) solvers [clmd->sim_parms.solver_type].init (ob, clmd); - clmd->clothObject->tree = NULL; // bvh_build(clmd, clmd->coll_parms.epsilon); + clmd->clothObject->tree = bvh_build_from_float3(CDDM_get_faces(dm), dm->getNumFaces(dm), clmd->clothObject->x, numverts, clmd->coll_parms.epsilon); // cloth_cache_set_frame(clmd, 1); } @@ -1079,6 +1122,14 @@ static void cloth_from_mesh (Object *ob, ClothModifierData *clmd, DerivedMesh *d return; } + clmd->clothObject->v = MEM_callocN ( sizeof ( float ) * clmd->clothObject->numverts * 3, "Cloth MVert_v" ); + if ( clmd->clothObject->v == NULL ) + { + cloth_free_modifier ( clmd ); + modifier_setError ( & ( clmd->modifier ), "Out of memory on allocating clmd->clothObject->v." ); + return; + } + clmd->clothObject->current_x = MEM_callocN ( sizeof ( float ) * clmd->clothObject->numverts * 3, "Cloth MVert_current_x" ); if ( clmd->clothObject->current_x == NULL ) { @@ -1094,6 +1145,14 @@ static void cloth_from_mesh (Object *ob, ClothModifierData *clmd, DerivedMesh *d modifier_setError ( & ( clmd->modifier ), "Out of memory on allocating clmd->clothObject->current_xold." ); return; } + + clmd->clothObject->current_v = MEM_callocN ( sizeof ( float ) * clmd->clothObject->numverts * 3, "Cloth MVert_current_v" ); + if ( clmd->clothObject->current_v == NULL ) + { + cloth_free_modifier ( clmd ); + modifier_setError ( & ( clmd->modifier ), "Out of memory on allocating clmd->clothObject->current_v." ); + return; + } // save face information clmd->clothObject->numfaces = numfaces; diff --git a/source/blender/blenkernel/intern/collision.c b/source/blender/blenkernel/intern/collision.c index f4b0ce7312b..6f0ac5f8c6d 100644 --- a/source/blender/blenkernel/intern/collision.c +++ b/source/blender/blenkernel/intern/collision.c @@ -73,17 +73,15 @@ // step is limited from 0 (frame start position) to 1 (frame end position) -void collision_move_object(CollisionModifierData *collmd, float step) +void collision_move_object(CollisionModifierData *collmd, float step, float prevstep) { float tv[3] = {0,0,0}; unsigned int i = 0; - MVert *tempVert = collmd->current_x; - collmd->current_x = collmd->current_xnew; - collmd->current_xnew = tempVert; - + for ( i = 0; i < collmd->numverts; i++ ) { VECSUB(tv, collmd->xnew[i].co, collmd->x[i].co); + VECADDS(collmd->current_x[i].co, collmd->x[i].co, tv, prevstep); VECADDS(collmd->current_xnew[i].co, collmd->x[i].co, tv, step); } } diff --git a/source/blender/blenkernel/intern/implicit.c b/source/blender/blenkernel/intern/implicit.c index e28930fa052..adefcc32d52 100644 --- a/source/blender/blenkernel/intern/implicit.c +++ b/source/blender/blenkernel/intern/implicit.c @@ -1164,7 +1164,6 @@ DO_INLINE void cloth_calc_spring_force(ClothModifierData *clmd, ClothSpring *s, float bending_force[3] = {0,0,0}; float damping_force[3] = {0,0,0}; float nulldfdx[3][3]={ {0,0,0}, {0,0,0}, {0,0,0}}; - Cloth *cloth = clmd->clothObject; VECCOPY(s->f, nullf); cp_fmatrix(s->dfdx, nulldfdx); @@ -1486,32 +1485,28 @@ int implicit_solver (Object *ob, float frame, ClothModifierData *clmd, ListBase } VECCOPY(cloth->current_x[i], id->Xnew[i]); - - VECSUB(verts[i].tv, cloth->current_x[i], cloth->current_xold[i]); - VECCOPY(verts[i].v, verts[i].tv); + VECSUB(cloth->current_v[i], cloth->current_x[i], cloth->current_xold[i]); + VECCOPY(cloth->v[i], cloth->current_v[i]); } - + // call collision function - result = 0; // cloth_bvh_objcollision(clmd, step + dt, dt); - + result = cloth_bvh_objcollision(clmd, step + dt, step, dt); + // copy corrected positions back to simulation - for(i = 0; i < numverts; i++) - { - if(result) - { - // VECADD(verts[i].tx, verts[i].txold, verts[i].tv); - - VECCOPY(cloth->current_xold[i], cloth->current_x[i]); - - VECCOPY(id->Xnew[i], cloth->current_x[i]); - - VECCOPY(id->Vnew[i], verts[i].tv); + memcpy(cloth->current_xold, cloth->current_x, sizeof(lfVector) * numverts); + memcpy(id->Xnew, cloth->current_x, sizeof(lfVector) * numverts); + + if(result) + { + for(i = 0; i < numverts; i++) + { + VECCOPY(id->Vnew[i], cloth->current_v[i]); VecMulf(id->Vnew[i], 1.0f / dt); } - else - { - VECCOPY(cloth->current_xold[i], id->Xnew[i]); - } + } + else + { + memcpy(cloth->current_xold, id->Xnew, sizeof(lfVector) * numverts); } // X = Xnew; @@ -1544,46 +1539,42 @@ int implicit_solver (Object *ob, float frame, ClothModifierData *clmd, ListBase if(effectors) pdEndEffectors(effectors); } - - for(i = 0; i < numverts; i++) - { - if(clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_GOAL) + + if(clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_GOAL) + { + for(i = 0; i < numverts; i++) { if(verts [i].goal < SOFTGOALSNAP) { VECCOPY(cloth->current_xold[i], id->X[i]); VECCOPY(cloth->x[i], id->X[i]); - VECCOPY(verts[i].v, id->V[i]); } else { VECCOPY(cloth->current_xold[i], verts[i].xconst); VECCOPY(cloth->x[i], verts[i].xconst); - VECCOPY(verts[i].v, id->V[i]); } } - else - { - VECCOPY(cloth->current_xold[i], id->X[i]); - VECCOPY(cloth->x[i], id->X[i]); - VECCOPY(verts[i].v, id->V[i]); - } } + else + { + memcpy(cloth->current_xold, id->X, sizeof(lfVector) * numverts); + memcpy(cloth->x, id->X, sizeof(lfVector) * numverts); + } + + memcpy(cloth->v, id->V, sizeof(lfVector) * numverts); + return 1; } void implicit_set_positions (ClothModifierData *clmd) { Cloth *cloth = clmd->clothObject; - ClothVertex *verts = cloth->verts; - unsigned int numverts = cloth->numverts, i; + unsigned int numverts = cloth->numverts; Implicit_Data *id = cloth->implicit; - for(i = 0; i < numverts; i++) - { - VECCOPY(id->X[i], cloth->x[i]); - VECCOPY(id->V[i], verts[i].v); - } + memcpy(id->X, cloth->x, sizeof(lfVector) * numverts); + memcpy(id->V, cloth->v, sizeof(lfVector) * numverts); } @@ -1707,13 +1698,13 @@ int collisions_collision_response_static(ClothModifierData *clmd, ClothModifierD int collisions_collision_response_moving_tris(ClothModifierData *clmd, ClothModifierData *coll_clmd) { - + return 0; } int collisions_collision_response_moving_edges(ClothModifierData *clmd, ClothModifierData *coll_clmd) { - + return 0; } void cloth_collision_static(ClothModifierData *clmd, ClothModifierData *coll_clmd, CollisionTree *tree1, CollisionTree *tree2) @@ -2161,266 +2152,75 @@ void collisions_collision_moving(ClothModifierData *clmd, ClothModifierData *col } // cloth - object collisions -int cloth_bvh_objcollision(ClothModifierData * clmd, float step, float dt) +int cloth_bvh_objcollision(ClothModifierData * clmd, float step, float prevstep, float dt) { - /* - Base *base=NULL; - ClothModifierData *coll_clmd=NULL; - Cloth *cloth=NULL; - Object *coll_ob=NULL; - BVH *collisions_bvh=NULL; - unsigned int i=0, j = 0, numfaces = 0, numverts = 0; - unsigned int result = 0, ic = 0, rounds = 0; // result counts applied collisions; ic is for debug output; - ClothVertex *verts = NULL; - float tnull[3] = {0,0,0}; - int ret = 0; + + Base *base = NULL; + CollisionModifierData *collmd = NULL; + Cloth *cloth = NULL; + Object *ob2 = NULL; + BVH *bvh1 = NULL, *bvh2 = NULL; LinkNode *collision_list = NULL; - if ((clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_COLLOBJ) || !(((Cloth *)clmd->clothObject)->tree)) + if (!(((Cloth *)clmd->clothObject)->tree)) { + printf("No BVH found\n"); return 0; } + cloth = clmd->clothObject; - verts = cloth->verts; - collisions_bvh = (BVH *) cloth->tree; - numfaces = clmd->clothObject->numfaces; - numverts = clmd->clothObject->numverts; + bvh1 = cloth->tree; //////////////////////////////////////////////////////////// // static collisions //////////////////////////////////////////////////////////// // update cloth bvh - // bvh_update(clmd, collisions_bvh, 0); // 0 means STATIC, 1 means MOVING (see later in this function) + bvh_update_from_float3(bvh1, cloth->current_xold, cloth->numverts, cloth->current_x, 0); // 0 means STATIC, 1 means MOVING (see later in this function) - // update collision objects - collisions_update_collision_objects(step); - - do - { - result = 0; - ic = 0; - - // check all collision objects - for (base = G.scene->base.first; base; base = base->next) - { - coll_ob = base->object; - coll_clmd = (ClothModifierData *) modifiers_findByType (coll_ob, eModifierType_Cloth); - - if (!coll_clmd) - continue; - - // if collision object go on - if (coll_clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_COLLOBJ) - { - if (coll_clmd->clothObject && coll_clmd->clothObject->tree) - { - BVH *coll_bvh = coll_clmd->clothObject->tree; - - // fill collision list - bvh_traverse(collisions_bvh->root, coll_bvh->root, collision_list); - - // process all collisions (calculate impulses, TODO: also repulses if distance too short) - result = 1; - for(j = 0; j < 10; j++) // 10 is just a value that ensures convergence - { - result = 0; - - // result += collisions_collision_response_static_tris(clmd, coll_clmd, collision_list, 0); - - // result += collisions_collision_response_static_tris(coll_clmd, clmd, collision_list, 1); - - // apply impulses in parallel - ic=0; - for(i = 0; i < numverts; i++) - { - // calculate "velocities" (just xnew = xold + v; no dt in v) - if(verts[i].impulse_count) - { - VECADDMUL(verts[i].tv, verts[i].impulse, 1.0f / verts[i].impulse_count); - VECCOPY(verts[i].impulse, tnull); - verts[i].impulse_count = 0; - - ic++; - ret++; - } - } - } - - // free collision list - if(collision_list) - { - LinkNode *search = collision_list; - while(search) - { - CollisionPair *coll_pair = search->link; - - MEM_freeN(coll_pair); - search = search->next; - } - BLI_linklist_free(collision_list,NULL); - - collision_list = NULL; - } - } - else - printf ("collisions_bvh_objcollision: found a collision object with clothObject or collData NULL.\n"); - } - } - - printf("ic: %d\n", ic); - rounds++; - } - while(result && (10>rounds));// CLOTH_MAX_THRESHOLD - - printf("\n"); - - //////////////////////////////////////////////////////////// - // update positions - // this is needed for bvh_calc_DOP_hull_moving() [kdop.c] - //////////////////////////////////////////////////////////// - - // verts come from clmd - for(i = 0; i < numverts; i++) - { - VECADD(verts[i].tx, verts[i].txold, verts[i].tv); - } - //////////////////////////////////////////////////////////// - - //////////////////////////////////////////////////////////// - // moving collisions - //////////////////////////////////////////////////////////// - - - // update cloth bvh - // bvh_update(clmd, collisions_bvh, 1); // 0 means STATIC, 1 means MOVING - - // update moving bvh for collision object once + // check all collision objects for (base = G.scene->base.first; base; base = base->next) { + ob2 = base->object; + collmd = (CollisionModifierData *) modifiers_findByType (ob2, eModifierType_Collision); - coll_ob = base->object; - coll_clmd = (ClothModifierData *) modifiers_findByType (coll_ob, eModifierType_Cloth); - if (!coll_clmd) + if (!collmd) continue; - if(!coll_clmd->clothObject) - continue; - - // if collision object go on - if (coll_clmd->clothObject && coll_clmd->clothObject->tree) + // check if there is a bounding volume hierarchy + if (collmd->tree) { - BVH *coll_bvh = coll_clmd->clothObject->tree; + int collisions = 0; - // bvh_update(coll_clmd, coll_bvh, 1); // 0 means STATIC, 1 means MOVING - } - } - - - do - { - result = 0; - ic = 0; - - // check all collision objects - for (base = G.scene->base.first; base; base = base->next) - { - coll_ob = base->object; - coll_clmd = (ClothModifierData *) modifiers_findByType (coll_ob, eModifierType_Cloth); + bvh2 = collmd->tree; - if (!coll_clmd) - continue; + // update position + bvh of collision object + collision_move_object(collmd, step, prevstep); + bvh_update_from_mvert(collmd->tree, collmd->current_x, collmd->numverts, NULL, 0); - // if collision object go on - if (coll_clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_COLLOBJ) + // fill collision list + collisions = bvh_traverse(bvh1->root, bvh2->root, collision_list); + + printf("Found %d collisions.\n", collisions); + + // free collision list + if(collision_list) { - if (coll_clmd->clothObject && coll_clmd->clothObject->tree) + LinkNode *search = collision_list; + while(search) { - BVH *coll_bvh = coll_clmd->clothObject->tree; + CollisionPair *coll_pair = search->link; - bvh_traverse(collisions_bvh->root, coll_bvh->root, collision_list); - - // process all collisions (calculate impulses, TODO: also repulses if distance too short) - result = 1; - for(j = 0; j < 10; j++) // 10 is just a value that ensures convergence - { - result = 0; - - // handle all collision objects - - - if (coll_clmd->clothObject) - result += collisions_collision_response_moving_tris(clmd, coll_clmd); - else - printf ("collisions_bvh_objcollision: found a collision object with clothObject or collData NULL.\n"); - - - // apply impulses in parallel - ic=0; - for(i = 0; i < numverts; i++) - { - // calculate "velocities" (just xnew = xold + v; no dt in v) - if(verts[i].impulse_count) - { - VECADDMUL(verts[i].tv, verts[i].impulse, 1.0f / verts[i].impulse_count); - VECCOPY(verts[i].impulse, tnull); - verts[i].impulse_count = 0; - - ic++; - ret++; - } - } - } - - - // verts come from clmd - for(i = 0; i < numverts; i++) - { - VECADD(verts[i].tx, verts[i].txold, verts[i].tv); - } - - // update cloth bvh - // bvh_update(clmd, collisions_bvh, 1); // 0 means STATIC, 1 means MOVING - - - // free collision list - if(collision_list) - { - LinkNode *search = collision_list; - while(search) - { - CollisionPair *coll_pair = search->link; - - MEM_freeN(coll_pair); - search = search->next; - } - BLI_linklist_free(collision_list,NULL); - - collision_list = NULL; - } + MEM_freeN(coll_pair); + search = search->next; } - else - printf ("collisions_bvh_objcollision: found a collision object with clothObject or collData NULL.\n"); + BLI_linklist_free(collision_list,NULL); + + collision_list = NULL; } } - - printf("ic: %d\n", ic); - rounds++; } - while(result && (10>rounds)); // CLOTH_MAX_THRESHOLD - - - //////////////////////////////////////////////////////////// - // update positions + velocities - //////////////////////////////////////////////////////////// - - // verts come from clmd - for(i = 0; i < numverts; i++) - { - VECADD(verts[i].tx, verts[i].txold, verts[i].tv); - } - //////////////////////////////////////////////////////////// - return MIN2(ret, 1); - */ -} \ No newline at end of file + + return 0; +} diff --git a/source/blender/blenkernel/intern/kdop.c b/source/blender/blenkernel/intern/kdop.c index 32bab0b4935..22129fcbc43 100644 --- a/source/blender/blenkernel/intern/kdop.c +++ b/source/blender/blenkernel/intern/kdop.c @@ -656,12 +656,8 @@ BVH *bvh_build (BVH *bvh, MFace *mfaces, unsigned int numfaces) BVH *bvh_build_from_mvert (MFace *mfaces, unsigned int numfaces, MVert *x, unsigned int numverts, float epsilon) { - unsigned int i = 0, j = 0; - CollisionTree **face_list=NULL; - BVH *bvh=NULL; + BVH *bvh=NULL; CollisionTree *tree=NULL; - LinkNode *nlink = NULL; - MFace *mface = NULL; bvh = MEM_callocN(sizeof(BVH), "BVH"); if (bvh == NULL) @@ -701,6 +697,55 @@ BVH *bvh_build_from_mvert (MFace *mfaces, unsigned int numfaces, MVert *x, unsig return bvh_build(bvh, mfaces, numfaces); } + +BVH *bvh_build_from_float3 (MFace *mfaces, unsigned int numfaces, float (*x)[3], unsigned int numverts, float epsilon) +{ + BVH *bvh=NULL; + CollisionTree *tree=NULL; + unsigned int i = 0; + + bvh = MEM_callocN(sizeof(BVH), "BVH"); + if (bvh == NULL) + { + printf("bvh: Out of memory.\n"); + return NULL; + } + + bvh->flags = 0; + bvh->leaf_tree = NULL; + bvh->leaf_root = NULL; + bvh->tree = NULL; + + bvh->epsilon = epsilon; + bvh->numfaces = numfaces; + + // we have no faces, we save seperate points + if(!mfaces) + { + bvh->numfaces = numverts; + } + + bvh->numverts = numverts; + bvh->xnew = (MVert *)MEM_callocN(sizeof(MVert)*numverts, "BVH MVert"); + + for(i = 0; i < numverts; i++) + VECCOPY(bvh->xnew[i].co, x[i]); + + bvh->x = MEM_dupallocN(bvh->xnew); + tree = (CollisionTree *)MEM_callocN(sizeof(CollisionTree), "CollisionTree"); + + if (tree == NULL) + { + printf("bvh_build: Out of memory for nodes.\n"); + bvh_free(bvh); + return NULL; + } + + BLI_linklist_append(&bvh->tree, tree); + + return bvh_build(bvh, mfaces, numfaces); +} + // bvh_overlap - is it possbile for 2 bv's to collide ? int bvh_overlap(float *bv1, float *bv2) { @@ -730,7 +775,7 @@ int bvh_overlap(float *bv1, float *bv2) */ int bvh_traverse(CollisionTree *tree1, CollisionTree *tree2, LinkNode *collision_list) { - int i = 0, ret = 0; + int i = 0, ret = 0, tempret = 0; if (bvh_overlap(tree1->bv, tree2->bv)) { @@ -759,8 +804,8 @@ int bvh_traverse(CollisionTree *tree1, CollisionTree *tree2, LinkNode *collision for (i = 0; i < 4; i++) { // Only traverse nodes that exist. - if (tree2->nodes[i] && bvh_traverse (tree1, tree2->nodes[i], collision_list)) - ret = 1; + if (tree2->nodes[i] && (tempret = bvh_traverse (tree1, tree2->nodes[i], collision_list))) + ret += tempret; } } } @@ -770,8 +815,8 @@ int bvh_traverse(CollisionTree *tree1, CollisionTree *tree2, LinkNode *collision for (i = 0; i < 4; i++) { // Only traverse nodes that exist. - if (tree1->nodes [i] && bvh_traverse (tree1->nodes[i], tree2, collision_list)) - ret = 1; + if (tree1->nodes [i] && (tempret = bvh_traverse (tree1->nodes[i], tree2, collision_list))) + ret += tempret; } } } @@ -882,3 +927,27 @@ void bvh_update_from_mvert(BVH * bvh, MVert *x, unsigned int numverts, MVert *xn bvh_update(bvh, moving); } +void bvh_update_from_float3(BVH * bvh, float (*x)[3], unsigned int numverts, float (*xnew)[3], int moving) +{ + unsigned int i = 0; + + if(!bvh) + return; + + if(numverts!=bvh->numverts) + return; + + if(x) + { + for(i = 0; i < numverts; i++) + VECCOPY(bvh->x[i].co, x[i]); + } + + if(xnew) + { + for(i = 0; i < numverts; i++) + VECCOPY(bvh->xnew[i].co, xnew[i]); + } + + bvh_update(bvh, moving); +} diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c index fcb56b56a5a..245b2fdc9b2 100644 --- a/source/blender/blenkernel/intern/modifier.c +++ b/source/blender/blenkernel/intern/modifier.c @@ -4922,14 +4922,13 @@ static void clothModifier_updateDepgraph( Object *ob1= base->object; if(ob1 != ob) { - ClothModifierData *coll_clmd = (ClothModifierData *)modifiers_findByType(ob1, eModifierType_Cloth); - if(coll_clmd) - { - if (coll_clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_COLLOBJ) - { - DagNode *curNode = dag_get_node(forest, ob1); - dag_add_relation(forest, curNode, obNode, DAG_RL_DATA_DATA|DAG_RL_OB_DATA); - } + CollisionModifierData *collmd = (CollisionModifierData *)modifiers_findByType(ob1, eModifierType_Collision); + if(collmd) + { + DagNode *curNode = dag_get_node(forest, ob1); + + dag_add_relation(forest, curNode, obNode, DAG_RL_DATA_DATA|DAG_RL_OB_DATA); + } } } diff --git a/source/blender/makesdna/DNA_cloth_types.h b/source/blender/makesdna/DNA_cloth_types.h index e1b1e3ce84a..2db2de7e183 100644 --- a/source/blender/makesdna/DNA_cloth_types.h +++ b/source/blender/makesdna/DNA_cloth_types.h @@ -43,9 +43,7 @@ typedef struct ClothVertex { int flags; /* General flags per vertex. */ - float v [3]; /* The velocity of the point. */ float xconst [3]; /* constrained position */ - float tv[3]; /* temporary "velocity", mostly used as tv = tx-txold */ float mass; /* mass / weight of the vertex */ float goal; /* goal, from SB */ float impulse[3]; /* used in collision.c */ @@ -152,13 +150,15 @@ typedef struct Cloth unsigned char old_solver_type; unsigned char pad2; short pad3; - struct CollisionTree *tree; /* collision tree for this cloth object */ + struct BVH *tree; /* collision tree for this cloth object */ struct MFace *mfaces; struct Implicit_Data *implicit; /* our implicit solver connects to this pointer */ float (*x)[3]; /* The current position of all vertices.*/ float (*xold)[3]; /* The previous position of all vertices.*/ float (*current_x)[3]; /* The TEMPORARY current position of all vertices.*/ float (*current_xold)[3]; /* The TEMPORARY previous position of all vertices.*/ + float (*v)[3]; /* the current velocity of all vertices */ + float (*current_v)[3]; } Cloth; From 67f8ca0b66f1138636978df34664d7c5aaa9ff4b Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Sun, 28 Oct 2007 19:07:51 +0000 Subject: [PATCH 040/246] Fixed typo which resulted in jumping cloth when collisions where enabled, fixed collision list memory leak. Ready to put real collision detection/response in. --- source/blender/blenkernel/BKE_cloth.h | 3 +- source/blender/blenkernel/BKE_collisions.h | 2 +- source/blender/blenkernel/intern/implicit.c | 59 +++++++++++++-------- source/blender/blenkernel/intern/kdop.c | 33 +++++++----- 4 files changed, 61 insertions(+), 36 deletions(-) diff --git a/source/blender/blenkernel/BKE_cloth.h b/source/blender/blenkernel/BKE_cloth.h index c0327ebe6db..dfb706c6d9a 100644 --- a/source/blender/blenkernel/BKE_cloth.h +++ b/source/blender/blenkernel/BKE_cloth.h @@ -46,9 +46,10 @@ struct MFace; struct DerivedMesh; // this is needed for inlining behaviour + #ifndef _WIN32 #define LINUX -#define DO_INLINE inline +#define DO_INLINE #else #define DO_INLINE #endif diff --git a/source/blender/blenkernel/BKE_collisions.h b/source/blender/blenkernel/BKE_collisions.h index 6422ad65c0b..4271bc4fef3 100644 --- a/source/blender/blenkernel/BKE_collisions.h +++ b/source/blender/blenkernel/BKE_collisions.h @@ -96,7 +96,7 @@ BVH *bvh_build_from_float3 (MFace *mfaces, unsigned int numfaces, float (*x)[3], void bvh_free ( BVH *bvh ); // checks two bounding volume hierarchies for potential collisions and returns some list with those -int bvh_traverse(CollisionTree *tree1, CollisionTree *tree2, LinkNode *collision_list); +int bvh_traverse(CollisionTree *tree1, CollisionTree *tree2, LinkNode **collision_list); // update bounding volumes, needs updated positions in bvh->x void bvh_update_from_mvert(BVH * bvh, MVert *x, unsigned int numverts, MVert *xnew, int moving); diff --git a/source/blender/blenkernel/intern/implicit.c b/source/blender/blenkernel/intern/implicit.c index adefcc32d52..34cba02522d 100644 --- a/source/blender/blenkernel/intern/implicit.c +++ b/source/blender/blenkernel/intern/implicit.c @@ -581,21 +581,32 @@ DO_INLINE void mul_bfmatrix_lfvector( float (*to)[3], fmatrix3x3 *from, float (* /* process off-diagonal entries (every off-diagonal entry needs to be symmetric) */ // TODO: pragma below is wrong, correct it! - // #pragma omp parallel for shared(to,from, fLongVector) private(i) +#pragma omp parallel for shared(to,from, fLongVector) private(i) for(i = from[0].vcount; i < from[0].vcount+from[0].scount; i++) { + unsigned int row = from[i].r; + unsigned int column = from[i].c; + // muladd_fmatrix_fvector(to[from[i].c], from[i].m, fLongVector[from[i].r]); - to[from[i].c][0] += INPR(from[i].m[0],fLongVector[from[i].r]); - to[from[i].c][1] += INPR(from[i].m[1],fLongVector[from[i].r]); - to[from[i].c][2] += INPR(from[i].m[2],fLongVector[from[i].r]); + to[column][0] += INPR(from[i].m[0],fLongVector[row]); + to[column][1] += INPR(from[i].m[1],fLongVector[row]); + to[column][2] += INPR(from[i].m[2],fLongVector[row]); + } +#pragma omp parallel for shared(to,from, fLongVector) private(i) + for(i = from[0].vcount; i < from[0].vcount+from[0].scount; i++) + { + unsigned int row = from[i].r; + unsigned int column = from[i].c; // muladd_fmatrix_fvector(to[from[i].r], from[i].m, fLongVector[from[i].c]); - to[from[i].r][0] += INPR(from[i].m[0],fLongVector[from[i].c]); - to[from[i].r][1] += INPR(from[i].m[1],fLongVector[from[i].c]); - to[from[i].r][2] += INPR(from[i].m[2],fLongVector[from[i].c]); + to[row][0] += INPR(from[i].m[0],fLongVector[column]); + to[row][1] += INPR(from[i].m[1],fLongVector[column]); + to[row][2] += INPR(from[i].m[2],fLongVector[column]); } + + } /* SPARSE SYMMETRIC add big matrix with big matrix: A = B + C*/ DO_INLINE void add_bfmatrix_bfmatrix( fmatrix3x3 *to, fmatrix3x3 *from, fmatrix3x3 *matrix) @@ -1313,7 +1324,6 @@ void cloth_calc_force(ClothModifierData *clmd, lfVector *lF, lfVector *lX, lfVec float kd, ks; LinkNode *search = cloth->springs; - VECCOPY(gravity, clmd->sim_parms.gravity); mul_fvector_S(gravity, gravity, 0.001f); /* scale gravity force */ @@ -1406,7 +1416,7 @@ void simulate_implicit_euler(lfVector *Vnew, lfVector *lX, lfVector *lV, lfVecto initdiag_bfmatrix(A, I); zero_lfvector(dV, numverts); - subadd_bfmatrixS_bfmatrixS(A, dFdV, dt, dFdX, (dt*dt)); + subadd_bfmatrixS_bfmatrixS(A, dFdV, dt, dFdX, (dt*dt)); mul_bfmatrix_lfvector(dFdXmV, dFdX, lV); @@ -1492,12 +1502,12 @@ int implicit_solver (Object *ob, float frame, ClothModifierData *clmd, ListBase // call collision function result = cloth_bvh_objcollision(clmd, step + dt, step, dt); - // copy corrected positions back to simulation - memcpy(cloth->current_xold, cloth->current_x, sizeof(lfVector) * numverts); - memcpy(id->Xnew, cloth->current_x, sizeof(lfVector) * numverts); - + // copy corrected positions back to simulation if(result) { + memcpy(cloth->current_xold, cloth->current_x, sizeof(lfVector) * numverts); + memcpy(id->Xnew, cloth->current_x, sizeof(lfVector) * numverts); + for(i = 0; i < numverts; i++) { VECCOPY(id->Vnew[i], cloth->current_v[i]); @@ -2161,6 +2171,8 @@ int cloth_bvh_objcollision(ClothModifierData * clmd, float step, float prevstep, Object *ob2 = NULL; BVH *bvh1 = NULL, *bvh2 = NULL; LinkNode *collision_list = NULL; + unsigned int i = 0; + int collisions = 0; if (!(((Cloth *)clmd->clothObject)->tree)) { @@ -2189,9 +2201,7 @@ int cloth_bvh_objcollision(ClothModifierData * clmd, float step, float prevstep, // check if there is a bounding volume hierarchy if (collmd->tree) - { - int collisions = 0; - + { bvh2 = collmd->tree; // update position + bvh of collision object @@ -2199,14 +2209,13 @@ int cloth_bvh_objcollision(ClothModifierData * clmd, float step, float prevstep, bvh_update_from_mvert(collmd->tree, collmd->current_x, collmd->numverts, NULL, 0); // fill collision list - collisions = bvh_traverse(bvh1->root, bvh2->root, collision_list); - - printf("Found %d collisions.\n", collisions); + collisions += bvh_traverse(bvh1->root, bvh2->root, &collision_list); // free collision list if(collision_list) { LinkNode *search = collision_list; + while(search) { CollisionPair *coll_pair = search->link; @@ -2220,7 +2229,15 @@ int cloth_bvh_objcollision(ClothModifierData * clmd, float step, float prevstep, } } } - - return 0; + ////////////////////////////////////////////// + // update velocities + positions + ////////////////////////////////////////////// + for(i = 0; i < cloth->numverts; i++) + { + VECADD(cloth->current_x[i], cloth->current_xold[i], cloth->current_v[i]); + } + ////////////////////////////////////////////// + + return collisions; } diff --git a/source/blender/blenkernel/intern/kdop.c b/source/blender/blenkernel/intern/kdop.c index 22129fcbc43..f9049fbcfcb 100644 --- a/source/blender/blenkernel/intern/kdop.c +++ b/source/blender/blenkernel/intern/kdop.c @@ -414,7 +414,7 @@ void bvh_calc_DOP_hull_static(BVH * bvh, CollisionTree **tri, int numfaces, floa tempBV[(2 * i)] = newminmax; if ((newminmax > tempBV[(2 * i) + 1])|| (k == 0 && j == 0)) tempBV[(2 * i) + 1] = newminmax; - } + } } } } @@ -593,20 +593,20 @@ BVH *bvh_build (BVH *bvh, MFace *mfaces, unsigned int numfaces) if(bvh->mfaces) { - bvh->root->point_index[0] = mfaces[i].v1; - bvh->root->point_index[1] = mfaces[i].v2; - bvh->root->point_index[2] = mfaces[i].v3; + tree->point_index[0] = mfaces[i].v1; + tree->point_index[1] = mfaces[i].v2; + tree->point_index[2] = mfaces[i].v3; if(mfaces[i].v4) - bvh->root->point_index[3] = mfaces[i].v4; + tree->point_index[3] = mfaces[i].v4; else - bvh->root->point_index[3] = -1; + tree->point_index[3] = -1; } else { - bvh->root->point_index[0] = i; - bvh->root->point_index[1] = -1; - bvh->root->point_index[2] = -1; - bvh->root->point_index[3] = -1; + tree->point_index[0] = i; + tree->point_index[1] = -1; + tree->point_index[2] = -1; + tree->point_index[3] = -1; } tree->isleaf = 1; @@ -641,7 +641,7 @@ BVH *bvh_build (BVH *bvh, MFace *mfaces, unsigned int numfaces) // build root bvh bvh_calc_DOP_hull_from_faces(bvh, face_list, bvh->numfaces, bvh->root->bv); - + // This is the traversal function. bvh_div_env_node(bvh, bvh->root, face_list, 0, bvh->numfaces-1, 0, nlink); if (face_list) @@ -673,6 +673,7 @@ BVH *bvh_build_from_mvert (MFace *mfaces, unsigned int numfaces, MVert *x, unsig bvh->epsilon = epsilon; bvh->numfaces = numfaces; + bvh->mfaces = mfaces; // we have no faces, we save seperate points if(!mfaces) @@ -718,6 +719,7 @@ BVH *bvh_build_from_float3 (MFace *mfaces, unsigned int numfaces, float (*x)[3], bvh->epsilon = epsilon; bvh->numfaces = numfaces; + bvh->mfaces = mfaces; // we have no faces, we save seperate points if(!mfaces) @@ -729,9 +731,12 @@ BVH *bvh_build_from_float3 (MFace *mfaces, unsigned int numfaces, float (*x)[3], bvh->xnew = (MVert *)MEM_callocN(sizeof(MVert)*numverts, "BVH MVert"); for(i = 0; i < numverts; i++) + { VECCOPY(bvh->xnew[i].co, x[i]); + } bvh->x = MEM_dupallocN(bvh->xnew); + tree = (CollisionTree *)MEM_callocN(sizeof(CollisionTree), "CollisionTree"); if (tree == NULL) @@ -773,7 +778,7 @@ int bvh_overlap(float *bv1, float *bv2) * every other triangle that doesn't require any realloc, but uses * much memory */ -int bvh_traverse(CollisionTree *tree1, CollisionTree *tree2, LinkNode *collision_list) +int bvh_traverse(CollisionTree *tree1, CollisionTree *tree2, LinkNode **collision_list) { int i = 0, ret = 0, tempret = 0; @@ -786,6 +791,7 @@ int bvh_traverse(CollisionTree *tree1, CollisionTree *tree2, LinkNode *collision if (tree2->isleaf) { // save potential colliding triangles + CollisionPair *collpair = (CollisionPair *)MEM_callocN(sizeof(CollisionPair), "CollisionPair"); VECCOPY(collpair->point_indexA, tree1->point_index); @@ -794,7 +800,7 @@ int bvh_traverse(CollisionTree *tree1, CollisionTree *tree2, LinkNode *collision VECCOPY(collpair->point_indexB, tree2->point_index); collpair->point_indexB[3] = tree2->point_index[3]; - BLI_linklist_append(&collision_list, collpair); + BLI_linklist_append(&collision_list[0], collpair); return 1; } @@ -870,6 +876,7 @@ void bvh_update(BVH * bvh, int moving) { leaf->parent->traversed = 0; } + if(!moving) bvh_calc_DOP_hull_static(bvh, &leaf, 1, leaf->bv); else From 01d19261bb315b841390a98cfe48b67e9991ed53 Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Sun, 4 Nov 2007 21:02:37 +0000 Subject: [PATCH 041/246] Implemented simple selfcollisions with use of OpenMP (WITH_BF_OPENMP = 'true' - for NEW compilers like gcc 4.2.0 and MSVC prof) --- source/blender/blenkernel/BKE_cloth.h | 1 + source/blender/blenkernel/BKE_collisions.h | 2 + source/blender/blenkernel/intern/cloth.c | 58 ++++++++----- source/blender/blenkernel/intern/implicit.c | 96 +++++++++++++++++++-- source/blender/blenkernel/intern/kdop.c | 41 +++++---- source/blender/makesdna/DNA_cloth_types.h | 4 +- source/blender/src/buttons_object.c | 7 +- 7 files changed, 158 insertions(+), 51 deletions(-) diff --git a/source/blender/blenkernel/BKE_cloth.h b/source/blender/blenkernel/BKE_cloth.h index 1744b3f3393..42ea6db0430 100644 --- a/source/blender/blenkernel/BKE_cloth.h +++ b/source/blender/blenkernel/BKE_cloth.h @@ -149,6 +149,7 @@ typedef void ( *CM_COLLISION_SELF ) ( ClothModifierData *clmd, int step ); // only one available in the moment typedef enum { CM_IMPLICIT = 0, + CM_VERLET = 1, } CM_SOLVER_ID; diff --git a/source/blender/blenkernel/BKE_collisions.h b/source/blender/blenkernel/BKE_collisions.h index 4271bc4fef3..fa5956c5bec 100644 --- a/source/blender/blenkernel/BKE_collisions.h +++ b/source/blender/blenkernel/BKE_collisions.h @@ -88,6 +88,8 @@ CollisionPair; // forward declarations ///////////////////////////////////////////////// +// NOTICE: mvert-routines for building + update the BVH are the most native ones + // builds bounding volume hierarchy BVH *bvh_build_from_mvert (MFace *mfaces, unsigned int numfaces, MVert *x, unsigned int numverts, float epsilon); BVH *bvh_build_from_float3 (MFace *mfaces, unsigned int numfaces, float (*x)[3], unsigned int numverts, float epsilon); diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c index bb99709b73a..cc5c6a289cd 100644 --- a/source/blender/blenkernel/intern/cloth.c +++ b/source/blender/blenkernel/intern/cloth.c @@ -111,11 +111,11 @@ double tval() /* Our available solvers. */ // 255 is the magic reserved number, so NEVER try to put 255 solvers in here! // 254 = MAX! -static CM_SOLVER_DEF solvers [] = - { - { "Implicit", CM_IMPLICIT, implicit_init, implicit_solver, implicit_free }, - // { "Implicit C++", CM_IMPLICITCPP, implicitcpp_init, implicitcpp_solver, implicitcpp_free }, - }; +static CM_SOLVER_DEF solvers [] = +{ + { "Implicit", CM_IMPLICIT, implicit_init, implicit_solver, implicit_free }, + // { "Implicit", CM_VERLET, verlet_init, verlet_solver, verlet_free }, +}; /* ********** cloth engine ******* */ /* Prototypes for internal functions. @@ -158,7 +158,8 @@ void cloth_init (ClothModifierData *clmd) clmd->coll_parms.self_friction = 5.0; clmd->coll_parms.friction = 10.0; clmd->coll_parms.loop_count = 1; - clmd->coll_parms.epsilon = 0.01f; + clmd->coll_parms.epsilon = 0.01; + clmd->coll_parms.selfepsilon = 0.1; /* These defaults are copied from softbody.c's * softbody_calc_forces() function. @@ -167,11 +168,11 @@ void cloth_init (ClothModifierData *clmd) clmd->sim_parms.eff_wind_scale = 250.0; // also from softbodies - clmd->sim_parms.maxgoal = 1.0f; - clmd->sim_parms.mingoal = 0.0f; - clmd->sim_parms.defgoal = 0.7f; - clmd->sim_parms.goalspring = 100.0f; - clmd->sim_parms.goalfrict = 0.0f; + clmd->sim_parms.maxgoal = 1.0; + clmd->sim_parms.mingoal = 0.0; + clmd->sim_parms.defgoal = 0.7; + clmd->sim_parms.goalspring = 100.0; + clmd->sim_parms.goalfrict = 0.0; clmd->sim_parms.cache = NULL; } @@ -519,6 +520,7 @@ void cloth_cache_get_frame ( ClothModifierData *clmd, float time ) memcpy ( clmd->clothObject->current_xold, frame->current_xold, sizeof ( float ) *frame->numverts * 3); + // TODO: temp off implicit_set_positions ( clmd ); return; @@ -621,32 +623,37 @@ void cloth_cache_free ( ClothModifierData *clmd, float time ) if ( frame->time >= newtime ) { + if ( frame->verts ) { MEM_freeN ( frame->verts ); } + if ( frame->x ) { MEM_freeN ( frame->x ); } + if ( frame->xold ) { MEM_freeN ( frame->xold ); } + if ( frame->v ) { MEM_freeN ( frame->v ); } + if ( frame->current_xold ) { MEM_freeN ( frame->current_xold ); } + MEM_freeN ( frame ); lastsearch->next = search->next; MEM_freeN ( search ); search = lastsearch->next; - lastsearch->next = NULL; } else { @@ -657,6 +664,7 @@ void cloth_cache_free ( ClothModifierData *clmd, float time ) if ( time <= 1.0 ) { + BLI_linklist_free(clmd->sim_parms.cache, NULL); clmd->sim_parms.cache = NULL; } @@ -852,7 +860,7 @@ void cloth_free_modifier (ClothModifierData *clmd) // Free the faces. if ( cloth->mfaces != NULL ) MEM_freeN ( cloth->mfaces ); - + // Free the verts. if ( cloth->x != NULL ) MEM_freeN ( cloth->x ); @@ -860,7 +868,7 @@ void cloth_free_modifier (ClothModifierData *clmd) // Free the verts. if ( cloth->xold != NULL ) MEM_freeN ( cloth->xold ); - + // Free the verts. if ( cloth->v != NULL ) MEM_freeN ( cloth->v ); @@ -876,7 +884,7 @@ void cloth_free_modifier (ClothModifierData *clmd) // Free the verts. if ( cloth->current_v != NULL ) MEM_freeN ( cloth->current_v ); - + cloth->verts = NULL; cloth->numverts = -1; @@ -902,6 +910,13 @@ void cloth_free_modifier (ClothModifierData *clmd) if(cloth->tree) bvh_free((BVH *)cloth->tree); + // free BVH self collision tree + if(cloth->selftree) + bvh_free((BVH *)cloth->selftree); + + if(cloth->edgehash) + BLI_edgehash_free ( cloth->edgehash, NULL ); + MEM_freeN (cloth); clmd->clothObject = NULL; } @@ -1019,6 +1034,7 @@ static int cloth_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *d if (clmd->clothObject) { clmd->clothObject->old_solver_type = 255; + clmd->clothObject->edgehash = NULL; } else if (clmd->clothObject == NULL) { @@ -1058,12 +1074,12 @@ static int cloth_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *d if ( clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_GOAL ) clmd->clothObject->verts [i].goal= clmd->sim_parms.defgoal; else - clmd->clothObject->verts [i].goal= 0.0f; + clmd->clothObject->verts [i].goal= 0.0; clmd->clothObject->verts [i].flags = 0; VECCOPY(clmd->clothObject->xold[i], clmd->clothObject->x[i]); VECCOPY(clmd->clothObject->verts [i].xconst, clmd->clothObject->x[i]); VECCOPY(clmd->clothObject->current_xold[i], clmd->clothObject->x[i]); - VecMulf(clmd->clothObject->v[i], 0.0f); + VecMulf(clmd->clothObject->v[i], 0.0); clmd->clothObject->verts [i].impulse_count = 0; VECCOPY ( clmd->clothObject->verts [i].impulse, tnull ); @@ -1078,7 +1094,9 @@ static int cloth_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *d solvers [clmd->sim_parms.solver_type].init (ob, clmd); clmd->clothObject->tree = bvh_build_from_float3(CDDM_get_faces(dm), dm->getNumFaces(dm), clmd->clothObject->x, numverts, clmd->coll_parms.epsilon); - + + clmd->clothObject->selftree = bvh_build_from_float3(NULL, 0, clmd->clothObject->x, numverts, clmd->coll_parms.selfepsilon); + // cloth_cache_set_frame(clmd, 1); } @@ -1346,8 +1364,8 @@ int cloth_build_springs ( Cloth *cloth, DerivedMesh *dm ) } if ( edgelist ) MEM_freeN ( edgelist ); - - BLI_edgehash_free ( edgehash, NULL ); + + cloth->edgehash = edgehash; return 1; diff --git a/source/blender/blenkernel/intern/implicit.c b/source/blender/blenkernel/intern/implicit.c index 34cba02522d..a5777b991eb 100644 --- a/source/blender/blenkernel/intern/implicit.c +++ b/source/blender/blenkernel/intern/implicit.c @@ -46,8 +46,9 @@ #include "DNA_lattice_types.h" #include "DNA_scene_types.h" #include "DNA_modifier_types.h" -#include "BLI_blenlib.h" #include "BLI_arithb.h" +#include "BLI_blenlib.h" +#include "BLI_edgehash.h" #include "BLI_threads.h" #include "BKE_collisions.h" #include "BKE_curve.h" @@ -62,7 +63,6 @@ #include "BKE_global.h" #include "BIF_editdeform.h" - #ifdef _WIN32 #include static LARGE_INTEGER _itstart, _itend; @@ -581,7 +581,7 @@ DO_INLINE void mul_bfmatrix_lfvector( float (*to)[3], fmatrix3x3 *from, float (* /* process off-diagonal entries (every off-diagonal entry needs to be symmetric) */ // TODO: pragma below is wrong, correct it! -#pragma omp parallel for shared(to,from, fLongVector) private(i) +// #pragma omp parallel for shared(to,from, fLongVector) private(i) for(i = from[0].vcount; i < from[0].vcount+from[0].scount; i++) { unsigned int row = from[i].r; @@ -593,7 +593,7 @@ DO_INLINE void mul_bfmatrix_lfvector( float (*to)[3], fmatrix3x3 *from, float (* to[column][1] += INPR(from[i].m[1],fLongVector[row]); to[column][2] += INPR(from[i].m[2],fLongVector[row]); } -#pragma omp parallel for shared(to,from, fLongVector) private(i) +// #pragma omp parallel for shared(to,from, fLongVector) private(i) for(i = from[0].vcount; i < from[0].vcount+from[0].scount; i++) { unsigned int row = from[i].r; @@ -1505,6 +1505,8 @@ int implicit_solver (Object *ob, float frame, ClothModifierData *clmd, ListBase // copy corrected positions back to simulation if(result) { + printf("result: %d\n", result); + memcpy(cloth->current_xold, cloth->current_x, sizeof(lfVector) * numverts); memcpy(id->Xnew, cloth->current_x, sizeof(lfVector) * numverts); @@ -1532,6 +1534,7 @@ int implicit_solver (Object *ob, float frame, ClothModifierData *clmd, ListBase cloth_calc_force(clmd, id->F, id->X, id->V, id->dFdV, id->dFdX, effectors, step); simulate_implicit_euler(id->Vnew, id->X, id->V, id->F, id->dFdV, id->dFdX, dt / 2.0f, id->A, id->B, id->dV, id->S, id->z, id->olddV, id->P, id->Pinv); } + } else { @@ -1544,7 +1547,7 @@ int implicit_solver (Object *ob, float frame, ClothModifierData *clmd, ListBase // V = Vnew; cp_lfvector(id->V, id->Vnew, numverts); - + step += dt; if(effectors) pdEndEffectors(effectors); @@ -2171,8 +2174,9 @@ int cloth_bvh_objcollision(ClothModifierData * clmd, float step, float prevstep, Object *ob2 = NULL; BVH *bvh1 = NULL, *bvh2 = NULL; LinkNode *collision_list = NULL; - unsigned int i = 0; - int collisions = 0; + unsigned int i = 0, j = 0; + int collisions = 0, count = 0; + float (*current_x)[3]; if (!(((Cloth *)clmd->clothObject)->tree)) { @@ -2186,7 +2190,7 @@ int cloth_bvh_objcollision(ClothModifierData * clmd, float step, float prevstep, //////////////////////////////////////////////////////////// // static collisions //////////////////////////////////////////////////////////// - + /* // update cloth bvh bvh_update_from_float3(bvh1, cloth->current_xold, cloth->numverts, cloth->current_x, 0); // 0 means STATIC, 1 means MOVING (see later in this function) @@ -2238,6 +2242,80 @@ int cloth_bvh_objcollision(ClothModifierData * clmd, float step, float prevstep, VECADD(cloth->current_x[i], cloth->current_xold[i], cloth->current_v[i]); } ////////////////////////////////////////////// + */ + // Test on *simple* selfcollisions + collisions = 1; + count = 0; + current_x = cloth->current_x; // needed for openMP - return collisions; +#pragma omp parallel for private(i,j, collisions) shared(current_x) + for(count = 0; count < 6; count++) + { + collisions = 0; + + for(i = 0; i < cloth->numverts; i++) + { + for(j = i + 1; j < cloth->numverts; j++) + { + float temp[3]; + float length = 0; + float mindistance = cloth->selftree->epsilon; + + if(clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_GOAL) + { + if((cloth->verts [i].goal >= SOFTGOALSNAP) + && (cloth->verts [j].goal >= SOFTGOALSNAP)) + { + continue; + } + } + + // check for adjacent points + if(BLI_edgehash_haskey ( cloth->edgehash, i, j )) + { + continue; + } + + VECSUB(temp, current_x[i], current_x[j]); + + length = Normalize(temp); + + if(length < mindistance) + { + float correction = mindistance - length; + + if(cloth->verts [i].goal >= SOFTGOALSNAP) + { + VecMulf(temp, -correction); + VECADD(current_x[j], current_x[j], temp); + } + else if(cloth->verts [j].goal >= SOFTGOALSNAP) + { + VecMulf(temp, correction); + VECADD(current_x[i], current_x[i], temp); + } + else + { + VecMulf(temp, -correction*0.5); + VECADD(current_x[j], current_x[j], temp); + + VECSUB(current_x[i], current_x[i], temp); + } + + collisions = 1; + } + } + } + } + + ////////////////////////////////////////////// + // SELFCOLLISIONS: update velocities + ////////////////////////////////////////////// + for(i = 0; i < cloth->numverts; i++) + { + VECSUB(cloth->current_v[i], cloth->current_x[i], cloth->current_xold[i]); + } + ////////////////////////////////////////////// + + return 1; } diff --git a/source/blender/blenkernel/intern/kdop.c b/source/blender/blenkernel/intern/kdop.c index f9049fbcfcb..f39d5465b87 100644 --- a/source/blender/blenkernel/intern/kdop.c +++ b/source/blender/blenkernel/intern/kdop.c @@ -780,8 +780,7 @@ int bvh_overlap(float *bv1, float *bv2) */ int bvh_traverse(CollisionTree *tree1, CollisionTree *tree2, LinkNode **collision_list) { - int i = 0, ret = 0, tempret = 0; - + int i = 0, ret = 0; if (bvh_overlap(tree1->bv, tree2->bv)) { // Check if this node in the first tree is a leaf @@ -790,19 +789,25 @@ int bvh_traverse(CollisionTree *tree1, CollisionTree *tree2, LinkNode **collisio // Check if this node in the second tree a leaf if (tree2->isleaf) { - // save potential colliding triangles + CollisionPair *collpair = NULL; - CollisionPair *collpair = (CollisionPair *)MEM_callocN(sizeof(CollisionPair), "CollisionPair"); - - VECCOPY(collpair->point_indexA, tree1->point_index); - collpair->point_indexA[3] = tree1->point_index[3]; - - VECCOPY(collpair->point_indexB, tree2->point_index); - collpair->point_indexB[3] = tree2->point_index[3]; - - BLI_linklist_append(&collision_list[0], collpair); - - return 1; + if(tree1 != tree2) // do not collide same points + { + // save potential colliding triangles + collpair = (CollisionPair *)MEM_callocN(sizeof(CollisionPair), "CollisionPair"); + + VECCOPY(collpair->point_indexA, tree1->point_index); + collpair->point_indexA[3] = tree1->point_index[3]; + + VECCOPY(collpair->point_indexB, tree2->point_index); + collpair->point_indexB[3] = tree2->point_index[3]; + + BLI_linklist_append(&collision_list[0], collpair); + + return 1; + } + else + return 0; } else { @@ -810,8 +815,8 @@ int bvh_traverse(CollisionTree *tree1, CollisionTree *tree2, LinkNode **collisio for (i = 0; i < 4; i++) { // Only traverse nodes that exist. - if (tree2->nodes[i] && (tempret = bvh_traverse (tree1, tree2->nodes[i], collision_list))) - ret += tempret; + if (tree2->nodes[i] && (bvh_traverse (tree1, tree2->nodes[i], collision_list))) + ret = 1; } } } @@ -821,8 +826,8 @@ int bvh_traverse(CollisionTree *tree1, CollisionTree *tree2, LinkNode **collisio for (i = 0; i < 4; i++) { // Only traverse nodes that exist. - if (tree1->nodes [i] && (tempret = bvh_traverse (tree1->nodes[i], tree2, collision_list))) - ret += tempret; + if (tree1->nodes [i] && (bvh_traverse (tree1->nodes[i], tree2, collision_list))) + ret = 1; } } } diff --git a/source/blender/makesdna/DNA_cloth_types.h b/source/blender/makesdna/DNA_cloth_types.h index 2db2de7e183..0edfb64e92f 100644 --- a/source/blender/makesdna/DNA_cloth_types.h +++ b/source/blender/makesdna/DNA_cloth_types.h @@ -125,7 +125,7 @@ typedef struct CollisionSettings short collision_type; /* which collision system is used. */ short loop_count; /* How many iterations for the collision loop. */ int flags; /* collision flags defined in BKE_cloth.h */ - int pad; + float selfepsilon; } CollisionSettings; @@ -151,6 +151,7 @@ typedef struct Cloth unsigned char pad2; short pad3; struct BVH *tree; /* collision tree for this cloth object */ + struct BVH *selftree; /* self collision tree for this cloth object */ struct MFace *mfaces; struct Implicit_Data *implicit; /* our implicit solver connects to this pointer */ float (*x)[3]; /* The current position of all vertices.*/ @@ -159,6 +160,7 @@ typedef struct Cloth float (*current_xold)[3]; /* The TEMPORARY previous position of all vertices.*/ float (*v)[3]; /* the current velocity of all vertices */ float (*current_v)[3]; + struct EdgeHash *edgehash; // used for fast checking adjacent points } Cloth; diff --git a/source/blender/src/buttons_object.c b/source/blender/src/buttons_object.c index 0754aa62016..474236fd5b2 100644 --- a/source/blender/src/buttons_object.c +++ b/source/blender/src/buttons_object.c @@ -3329,12 +3329,13 @@ static void object_panel_cloth_III(Object *ob) uiSetButLock(object_data_is_libdata(ob), ERROR_LIBDATA_MESSAGE); uiBlockBeginAlign(block); - uiDefButBitI(block, TOG, CLOTH_COLLISIONSETTINGS_FLAG_ENABLED, REDRAWVIEW3D, "Enable collisions", 10,70,130,20, &clmd->coll_parms.flags, 0, 0, 0, 0, "Enable collisions with this object"); + uiDefButBitI(block, TOG, CLOTH_COLLISIONSETTINGS_FLAG_ENABLED, REDRAWVIEW3D, "Enable collisions", 10,160,130,20, &clmd->coll_parms.flags, 0, 0, 0, 0, "Enable collisions with this object"); if (clmd->coll_parms.flags & CLOTH_COLLISIONSETTINGS_FLAG_ENABLED) { // uiDefBut(block, LABEL, 0, "",10,10,300,20, NULL, 0.0, 0, 0, 0, ""); /* tell UI we go to 10,10*/ - uiDefButF(block, NUM, B_CLOTH_RENEW, "Min Distance:", 10,30,150,20, &clmd->coll_parms.epsilon, 0.001f, 1.0, 0.01f, 0, "Minimum distance between collision objects before collision response takes in"); - uiDefBut(block, LABEL, 0, "",160,30,150,20, NULL, 0.0, 0, 0, 0, ""); + uiDefButF(block, NUM, B_CLOTH_RENEW, "Min Distance:", 10,140,150,20, &clmd->coll_parms.epsilon, 0.001f, 1.0, 0.01f, 0, "Minimum distance between collision objects before collision response takes in"); + uiDefBut(block, LABEL, 0, "",160,140,150,20, NULL, 0.0, 0, 0, 0, ""); + uiDefButF(block, NUM, B_CLOTH_RENEW, "Selfcoll balls:", 10,120,150,20, &clmd->coll_parms.selfepsilon, 0.001f, 1.0, 0.01f, 0, "Minimum distance between two selfcollision points"); } else uiDefBut(block, LABEL, 0, "",140,10,170,20, NULL, 0.0, 0, 0, 0, ""); From 8c0968a01361af5f68a3ac83f552777eeb28aa49 Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Sun, 4 Nov 2007 22:11:00 +0000 Subject: [PATCH 042/246] Kicked my own cache code, will use point cache in the near feature --- source/blender/blenkernel/BKE_cloth.h | 2 +- source/blender/blenkernel/intern/cloth.c | 286 +---------------------- source/blender/src/buttons_object.c | 4 +- 3 files changed, 10 insertions(+), 282 deletions(-) diff --git a/source/blender/blenkernel/BKE_cloth.h b/source/blender/blenkernel/BKE_cloth.h index 42ea6db0430..dd62a24a036 100644 --- a/source/blender/blenkernel/BKE_cloth.h +++ b/source/blender/blenkernel/BKE_cloth.h @@ -116,7 +116,7 @@ typedef enum // needed for buttons_object.c -void cloth_cache_free ( ClothModifierData *clmd, float time ); +// void cloth_cache_free ( ClothModifierData *clmd, float time ); void cloth_free_modifier ( ClothModifierData *clmd ); // needed for cloth.c diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c index cc5c6a289cd..360bf421d71 100644 --- a/source/blender/blenkernel/intern/cloth.c +++ b/source/blender/blenkernel/intern/cloth.c @@ -403,278 +403,6 @@ DerivedMesh *CDDM_create_tearing(ClothModifierData *clmd, DerivedMesh *dm) return NULL; } - -int cloth_cache_search_frame ( ClothModifierData *clmd, float time ) -{ - Frame *frame = NULL; - LinkNode *search = NULL; - - if ( clmd->clothObject ) - { - search = clmd->sim_parms.cache; - - while ( search ) - { - frame = ( Frame * ) search->link; - - if ( frame ) - { - if ( frame->time == time ) - return 1; - } - - search = search->next; - } - } - - return 0; - -} - -float cloth_cache_last_frame ( ClothModifierData *clmd ) -{ - Frame *frame = NULL; - LinkNode *search = NULL; - float time = 0; - - if ( clmd->clothObject ) - { - search = clmd->sim_parms.cache; - - while ( search ) - { - frame = ( Frame * ) search->link; - - if ( frame ) - { - if ( frame->time > time ) - time = frame->time; - } - } - } - return time; -} - -float cloth_cache_first_frame ( ClothModifierData *clmd ) -{ - Frame *frame = NULL; - LinkNode *search = NULL; - float time = -1.0; - - if ( clmd->clothObject ) - { - search = clmd->sim_parms.cache; - - while ( search ) - { - frame = ( Frame * ) search->link; - - if ( frame ) - { - if ( time < 0.0 ) - time = frame->time; - else - { - if ( frame->time < time ) - time = frame->time; - } - } - } - } - return time; -} - -void cloth_cache_get_frame ( ClothModifierData *clmd, float time ) -{ - Frame *frame = NULL; - LinkNode *search = NULL; - float newtime = time + clmd->sim_parms.preroll; - - if ( clmd->clothObject ) - { - search = clmd->sim_parms.cache; - - while ( search ) - { - frame = ( Frame * ) search->link; - - if ( frame ) - { - if ( frame->time == newtime ) - { - // something changed, free cache! - if ( clmd->clothObject->numverts != frame->numverts ) - { - cloth_cache_free ( clmd, 0 ); - printf ( "clmd->clothObject->numverts != frame->numverts\n" ); - return; - } - - memcpy ( clmd->clothObject->verts, frame->verts, sizeof ( ClothVertex ) *frame->numverts ); - - memcpy ( clmd->clothObject->x, frame->x, sizeof ( float ) *frame->numverts * 3); - - memcpy ( clmd->clothObject->xold, frame->xold, sizeof ( float ) *frame->numverts * 3); - - memcpy ( clmd->clothObject->v, frame->v, sizeof ( float ) *frame->numverts * 3); - - memcpy ( clmd->clothObject->current_xold, frame->current_xold, sizeof ( float ) *frame->numverts * 3); - - // TODO: temp off - implicit_set_positions ( clmd ); - - return; - } - } - - search = search->next; - } - } -} - -void cloth_cache_set_frame ( ClothModifierData *clmd, float time ) -{ - Frame *frame = NULL; - - if ( clmd->clothObject ) - { - frame = ( Frame * ) MEM_callocN ( sizeof ( Frame ), "cloth_cache_frame" ); - - if ( frame ) - { - frame->time = time; - frame->numverts = clmd->clothObject->numverts; - frame->verts = MEM_dupallocN ( clmd->clothObject->verts ); - - if ( !frame->verts ) - { - MEM_freeN ( frame ); - return; - } - - frame->x = MEM_dupallocN ( clmd->clothObject->x ); - - if ( !frame->x ) - { - MEM_freeN ( frame->verts ); - MEM_freeN ( frame ); - return; - } - - frame->xold = MEM_dupallocN ( clmd->clothObject->xold ); - - if ( !frame->xold ) - { - MEM_freeN ( frame->verts ); - MEM_freeN ( frame->x ); - MEM_freeN ( frame ); - return; - } - - frame->v = MEM_dupallocN ( clmd->clothObject->v ); - - if ( !frame->v ) - { - MEM_freeN ( frame->verts ); - MEM_freeN ( frame->x ); - MEM_freeN ( frame->xold ); - MEM_freeN ( frame ); - return; - } - - frame->current_xold= MEM_dupallocN ( clmd->clothObject->current_xold ); - - if ( !frame->current_xold ) - { - MEM_freeN ( frame->verts ); - MEM_freeN ( frame->x ); - MEM_freeN ( frame->xold ); - MEM_freeN ( frame->v ); - MEM_freeN ( frame ); - return; - } - - BLI_linklist_append ( &clmd->sim_parms.cache, frame ); - - } - } - -} - -// free cloth cache -void cloth_cache_free ( ClothModifierData *clmd, float time ) -{ - Frame *frame = NULL; - LinkNode *search = NULL, *lastsearch = NULL; - float newtime = time + clmd->sim_parms.preroll; - - if ( time <= 2.0 ) - newtime = time; - - if ( clmd->clothObject ) - { - if ( clmd->sim_parms.cache ) - { - lastsearch = search = clmd->sim_parms.cache; - - while ( search ) - { - frame = ( Frame * ) search->link; - - if ( frame->time >= newtime ) - { - - if ( frame->verts ) - { - MEM_freeN ( frame->verts ); - } - - if ( frame->x ) - { - MEM_freeN ( frame->x ); - } - - if ( frame->xold ) - { - MEM_freeN ( frame->xold ); - } - - if ( frame->v ) - { - MEM_freeN ( frame->v ); - } - - if ( frame->current_xold ) - { - MEM_freeN ( frame->current_xold ); - } - - MEM_freeN ( frame ); - - lastsearch->next = search->next; - MEM_freeN ( search ); - search = lastsearch->next; - } - else - { - lastsearch = search; - search = search->next; - } - } - - if ( time <= 1.0 ) - { - BLI_linklist_free(clmd->sim_parms.cache, NULL); - clmd->sim_parms.cache = NULL; - } - - if ( time <= 2.0 ) - clmd->sim_parms.preroll = 0; - } - } -} - - /** * cloth_deform_verts - simulates one step, framenr is in frames. * @@ -773,7 +501,7 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd,Object *ob, DerivedMesh *d // Insure we have a clmd->clothObject, in case allocation failed. if (clmd->clothObject != NULL) { - if(!cloth_cache_search_frame(clmd, framenr)) + // if(!cloth_cache_search_frame(clmd, framenr)) { verts = cloth->verts; @@ -798,13 +526,13 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd,Object *ob, DerivedMesh *d printf("Cloth simulation time: %f\n", tval()); - cloth_cache_set_frame(clmd, framenr); + // cloth_cache_set_frame(clmd, framenr); - } + }/* else // just retrieve the cached frame { cloth_cache_get_frame(clmd, framenr); - } + }*/ // Copy the result back to the object. cloth_to_object (ob, result, clmd); @@ -813,7 +541,7 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd,Object *ob, DerivedMesh *d // clmd->clothObject->tree = bvh_build(clmd, clmd->coll_parms.epsilon); } - } + }/* else if ( ( deltaTime <= 0.0f ) || ( deltaTime > 1.0f ) ) { if ( ( clmd->clothObject != NULL ) && ( clmd->sim_parms.cache ) ) @@ -824,7 +552,7 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd,Object *ob, DerivedMesh *d cloth_to_object (ob, result, clmd); } } - } + }*/ return result; } @@ -840,7 +568,7 @@ void cloth_free_modifier (ClothModifierData *clmd) cloth = clmd->clothObject; // free our frame cache - cloth_cache_free(clmd, 0); + // cloth_cache_free(clmd, 0); /* Calls the solver and collision frees first as they * might depend on data in clmd->clothObject. */ diff --git a/source/blender/src/buttons_object.c b/source/blender/src/buttons_object.c index 474236fd5b2..45a1502840c 100644 --- a/source/blender/src/buttons_object.c +++ b/source/blender/src/buttons_object.c @@ -2181,7 +2181,7 @@ void do_object_panels(unsigned short event) CFRA= 1; update_for_newframe_muted(); DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA); - cloth_cache_free(clmd, 2); + // cloth_cache_free(clmd, 2); allqueue(REDRAWBUTSOBJECT, 0); allqueue(REDRAWVIEW3D, 0); } @@ -2192,7 +2192,7 @@ void do_object_panels(unsigned short event) ClothModifierData *clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth); if(clmd) { - cloth_cache_free(clmd, MAX2(2.0,G.scene->r.cfra+1.0)); + // cloth_cache_free(clmd, MAX2(2.0,G.scene->r.cfra+1.0)); allqueue(REDRAWBUTSOBJECT, 0); } } From 0a1be3e2cee4375c27155a8fe090542b8e25c7ed Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Mon, 5 Nov 2007 19:28:38 +0000 Subject: [PATCH 043/246] Fun commit: I put some 3-liner verlet integrator in, to activate it, set clmd->sim_parms.solver_type in cloth_init to 1 - bugs in there --- source/blender/blenkernel/BKE_cloth.h | 8 ++++++++ source/blender/blenkernel/intern/cloth.c | 6 +++--- source/blender/blenkernel/intern/implicit.c | 21 ++++----------------- 3 files changed, 15 insertions(+), 20 deletions(-) diff --git a/source/blender/blenkernel/BKE_cloth.h b/source/blender/blenkernel/BKE_cloth.h index dd62a24a036..783faf42e18 100644 --- a/source/blender/blenkernel/BKE_cloth.h +++ b/source/blender/blenkernel/BKE_cloth.h @@ -171,6 +171,11 @@ int implicit_init ( Object *ob, ClothModifierData *clmd ); int implicit_free ( ClothModifierData *clmd ); int implicit_solver ( Object *ob, float frame, ClothModifierData *clmd, ListBase *effectors ); +/* explicit verlet simulator */ +int verlet_init ( Object *ob, ClothModifierData *clmd ); +int verlet_free ( ClothModifierData *clmd ); +int verlet_solver ( Object *ob, float frame, ClothModifierData *clmd, ListBase *effectors ); + /* used for caching in implicit.c */ typedef struct Frame { @@ -227,5 +232,8 @@ typedef struct FaceCollPair } FaceCollPair; +// function definitions from implicit.c +DO_INLINE void mul_fvector_S(float to[3], float from[3], float scalar); + #endif diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c index 360bf421d71..4be365fdc86 100644 --- a/source/blender/blenkernel/intern/cloth.c +++ b/source/blender/blenkernel/intern/cloth.c @@ -114,7 +114,7 @@ double tval() static CM_SOLVER_DEF solvers [] = { { "Implicit", CM_IMPLICIT, implicit_init, implicit_solver, implicit_free }, - // { "Implicit", CM_VERLET, verlet_init, verlet_solver, verlet_free }, + { "Verlet", CM_VERLET, verlet_init, verlet_solver, verlet_free }, }; /* ********** cloth engine ******* */ @@ -504,7 +504,7 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd,Object *ob, DerivedMesh *d // if(!cloth_cache_search_frame(clmd, framenr)) { verts = cloth->verts; - + /* // Force any pinned verts to their constrained location. for ( i = 0; i < clmd->clothObject->numverts; i++, verts++ ) { @@ -515,7 +515,7 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd,Object *ob, DerivedMesh *d VECCOPY ( verts->xconst, mvert[i].co ); Mat4MulVecfl ( ob->obmat, verts->xconst ); } - + */ tstart(); /* Call the solver. */ diff --git a/source/blender/blenkernel/intern/implicit.c b/source/blender/blenkernel/intern/implicit.c index a5777b991eb..638f7350822 100644 --- a/source/blender/blenkernel/intern/implicit.c +++ b/source/blender/blenkernel/intern/implicit.c @@ -87,10 +87,6 @@ double itval() } #else #include -// intrinsics need better compile flag checking -// #include -// #include -// #include static struct timeval _itstart, _itend; static struct timezone itz; @@ -110,14 +106,7 @@ double itval() return t2-t1; } #endif -/* -#define C99 -#ifdef C99 -#defineDO_INLINE inline -#else -#defineDO_INLINE static -#endif -*/ + struct Cloth; ////////////////////////////////////////// @@ -1502,11 +1491,9 @@ int implicit_solver (Object *ob, float frame, ClothModifierData *clmd, ListBase // call collision function result = cloth_bvh_objcollision(clmd, step + dt, step, dt); - // copy corrected positions back to simulation + // copy corrected positions back to simulation if(result) { - printf("result: %d\n", result); - memcpy(cloth->current_xold, cloth->current_x, sizeof(lfVector) * numverts); memcpy(id->Xnew, cloth->current_x, sizeof(lfVector) * numverts); @@ -2284,12 +2271,12 @@ int cloth_bvh_objcollision(ClothModifierData * clmd, float step, float prevstep, { float correction = mindistance - length; - if(cloth->verts [i].goal >= SOFTGOALSNAP) + if((clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_GOAL) && (cloth->verts [i].goal >= SOFTGOALSNAP)) { VecMulf(temp, -correction); VECADD(current_x[j], current_x[j], temp); } - else if(cloth->verts [j].goal >= SOFTGOALSNAP) + else if((clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_GOAL) && (cloth->verts [j].goal >= SOFTGOALSNAP)) { VecMulf(temp, correction); VECADD(current_x[i], current_x[i], temp); From 873a26ff841e64c9b061779fa09b9461bb4a6681 Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Mon, 5 Nov 2007 19:29:14 +0000 Subject: [PATCH 044/246] best part (file) was missing --- source/blender/blenkernel/intern/verlet.c | 170 ++++++++++++++++++++++ 1 file changed, 170 insertions(+) create mode 100644 source/blender/blenkernel/intern/verlet.c diff --git a/source/blender/blenkernel/intern/verlet.c b/source/blender/blenkernel/intern/verlet.c new file mode 100644 index 00000000000..71001fa92a5 --- /dev/null +++ b/source/blender/blenkernel/intern/verlet.c @@ -0,0 +1,170 @@ +/* implicit.c +* +* +* ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* as published by the Free Software Foundation; either version 2 +* of the License, or (at your option) any later version. The Blender +* Foundation also sells licenses for use in proprietary software under +* the Blender License. See http://www.blender.org/BL/ for information +* about this. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software Foundation, +* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +* +* The Original Code is Copyright (C) Blender Foundation +* All rights reserved. +* +* The Original Code is: all of this file. +* +* Contributor(s): none yet. +* +* ***** END GPL/BL DUAL LICENSE BLOCK ***** +*/ +#include +#include +#include +#include +#include "MEM_guardedalloc.h" +/* types */ +#include "DNA_curve_types.h" +#include "DNA_object_types.h" +#include "DNA_object_force.h" +#include "DNA_cloth_types.h" +#include "DNA_key_types.h" +#include "DNA_mesh_types.h" +#include "DNA_modifier_types.h" +#include "DNA_meshdata_types.h" +#include "DNA_lattice_types.h" +#include "DNA_scene_types.h" +#include "DNA_modifier_types.h" +#include "BLI_arithb.h" +#include "BLI_blenlib.h" +#include "BLI_edgehash.h" +#include "BLI_threads.h" +#include "BKE_collisions.h" +#include "BKE_curve.h" +#include "BKE_displist.h" +#include "BKE_effect.h" +#include "BKE_global.h" +#include "BKE_key.h" +#include "BKE_object.h" +#include "BKE_cloth.h" +#include "BKE_modifier.h" +#include "BKE_utildefines.h" +#include "BKE_global.h" +#include "BIF_editdeform.h" + +struct Cloth; + +int verlet_init ( Object *ob, ClothModifierData *clmd ) +{ + return 1; +} + +int verlet_free ( ClothModifierData *clmd ) +{ + return 1; +} + +void integrate ( ClothModifierData *clmd, float dt ) +{ + Cloth *cloth = clmd->clothObject; + unsigned int i = 0; + + // temporary vectors + float temp[3], velocity[3], force[3]; + + mul_fvector_S( force, clmd->sim_parms.gravity, dt*dt ); + + // iterate through all control points + for(i = 0; i < cloth->numverts; i++) + { + if(((clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_GOAL) && (cloth->verts [i].goal < SOFTGOALSNAP)) || !(clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_GOAL)) + { + // save current control point location + VECCOPY ( temp, cloth->x[i] ); + + // update control point by the formula + // x += (x - old_x)*dampingFactor + force*timeStep^2 + VECSUB ( velocity, cloth->x[i], cloth->xold[i] ); + VECSUBMUL( force, velocity, -clmd->sim_parms.Cvi * 0.01f* dt * dt); + VecMulf(velocity, 0.99); + VECADD ( cloth->x[i], cloth->x[i], velocity ); + VECADD ( cloth->x[i], cloth->x[i], force ); + + // store old control point location + VECCOPY ( cloth->xold[i], temp ); + } + } +} + +void satisfyconstraints(ClothModifierData *clmd) +{ + float delta[3]; + Cloth *cloth = clmd->clothObject; + unsigned int i = 0; + + for(i = 0; i < 5; i++) + { + // calculate spring forces + LinkNode *search = cloth->springs; + while(search) + { + ClothSpring *spring = search->link; + float temp = 0; + float restlen2 = spring->restlen * spring->restlen; + float len2 = 0, len = 0; + + VECSUB(delta, cloth->x[spring->kl], cloth->x[spring->ij]); + len = sqrt(INPR(delta, delta)); + + if(spring->type != CLOTH_SPRING_TYPE_BENDING) + { + temp = (len - spring->restlen)/len; + + mul_fvector_S(delta, delta, temp*0.5); + + // check if vertex is pinned + if(((clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_GOAL) && (cloth->verts [spring->ij].goal < SOFTGOALSNAP)) || !(clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_GOAL)) + VECADD(cloth->x[spring->ij], cloth->x[spring->ij], delta); + + // check if vertex is pinned + if(((clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_GOAL) && (cloth->verts [spring->kl].goal < SOFTGOALSNAP)) || !(clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_GOAL)) + VECSUB(cloth->x[spring->kl], cloth->x[spring->kl], delta); + } + + search = search->next; + } + } +} + +int verlet_solver ( Object *ob, float frame, ClothModifierData *clmd, ListBase *effectors ) +{ + float dt = 0.01; + float step = 0; + + while(step < 1.0f) + { + integrate(clmd, dt); + satisfyconstraints(clmd); + + step+= dt; + } + + return 1; +} + + + + + + From 47c62453db41003b8a3959f102d2fa344cf0ad97 Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Tue, 6 Nov 2007 02:30:53 +0000 Subject: [PATCH 045/246] Bugfix for wrong springs (resulted in weird behaviour), Implemented two speedups: One for small bending/wrinkle values (1/3 speedup), another speedup is that cloth get automatically in sleep mode but wakes up every frame ([quality-1]/quality speedup) --- source/blender/blenkernel/BKE_cloth.h | 4 +- source/blender/blenkernel/intern/cloth.c | 20 +-- source/blender/blenkernel/intern/implicit.c | 96 +++++++++-- source/blender/blenkernel/intern/verlet.c | 170 -------------------- source/blender/makesdna/DNA_cloth_types.h | 2 + 5 files changed, 101 insertions(+), 191 deletions(-) delete mode 100644 source/blender/blenkernel/intern/verlet.c diff --git a/source/blender/blenkernel/BKE_cloth.h b/source/blender/blenkernel/BKE_cloth.h index 783faf42e18..8be27ace346 100644 --- a/source/blender/blenkernel/BKE_cloth.h +++ b/source/blender/blenkernel/BKE_cloth.h @@ -86,7 +86,9 @@ typedef enum CLOTH_SIMSETTINGS_FLAG_COLLOBJ = ( 1 << 2 ), // object is only collision object, no cloth simulation is done CLOTH_SIMSETTINGS_FLAG_GOAL = ( 1 << 3 ), // we have goals enabled CLOTH_SIMSETTINGS_FLAG_TEARING = ( 1 << 4 ), // true if tearing is enabled - CLOTH_SIMSETTINGS_FLAG_CCACHE_PROTECT = ( 1 << 5 ), // true if tearing is enabled + CLOTH_SIMSETTINGS_FLAG_CCACHE_PROTECT = ( 1 << 5 ), + CLOTH_SIMSETTINGS_FLAG_BIG_FORCE = ( 1 << 6 ), // true if we have big spring force for bending + CLOTH_SIMSETTINGS_FLAG_SLEEP = ( 1 << 7 ), // true if we let the cloth go to sleep } CLOTH_SIMSETTINGS_FLAGS; /* SPRING FLAGS */ diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c index 4be365fdc86..eba11bfedda 100644 --- a/source/blender/blenkernel/intern/cloth.c +++ b/source/blender/blenkernel/intern/cloth.c @@ -114,7 +114,7 @@ double tval() static CM_SOLVER_DEF solvers [] = { { "Implicit", CM_IMPLICIT, implicit_init, implicit_solver, implicit_free }, - { "Verlet", CM_VERLET, verlet_init, verlet_solver, verlet_free }, + // { "Verlet", CM_VERLET, verlet_init, verlet_solver, verlet_free }, }; /* ********** cloth engine ******* */ @@ -504,8 +504,9 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd,Object *ob, DerivedMesh *d // if(!cloth_cache_search_frame(clmd, framenr)) { verts = cloth->verts; - /* + // Force any pinned verts to their constrained location. + // has to be commented for verlet for ( i = 0; i < clmd->clothObject->numverts; i++, verts++ ) { // Save the previous position. @@ -515,7 +516,7 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd,Object *ob, DerivedMesh *d VECCOPY ( verts->xconst, mvert[i].co ); Mat4MulVecfl ( ob->obmat, verts->xconst ); } - */ + tstart(); /* Call the solver. */ @@ -1031,8 +1032,8 @@ int cloth_build_springs ( Cloth *cloth, DerivedMesh *dm ) { spring = ( ClothSpring * ) MEM_callocN ( sizeof ( ClothSpring ), "cloth spring" ); - spring->ij = mface[i].v1; - spring->kl = mface[i].v3; + spring->ij = mface[i].v2; + spring->kl = mface[i].v4; VECSUB ( temp, mvert[spring->kl].co, mvert[spring->ij].co ); spring->restlen = sqrt ( INPR ( temp, temp ) ); spring->type = CLOTH_SPRING_TYPE_SHEAR; @@ -1045,7 +1046,7 @@ int cloth_build_springs ( Cloth *cloth, DerivedMesh *dm ) node = node2; } } - + // bending springs search2 = cloth->springs; for ( i = struct_springs; i < struct_springs+shear_springs; i++ ) @@ -1083,9 +1084,10 @@ int cloth_build_springs ( Cloth *cloth, DerivedMesh *dm ) } search2 = search2->next; } - - cloth->numsprings = struct_springs + shear_springs + bend_springs; - + + cloth->numspringssave = cloth->numsprings = struct_springs + shear_springs + bend_springs; + cloth->numothersprings = struct_springs + shear_springs; + for ( i = 0; i < numverts; i++ ) { BLI_linklist_free ( edgelist[i],NULL ); diff --git a/source/blender/blenkernel/intern/implicit.c b/source/blender/blenkernel/intern/implicit.c index 638f7350822..091a0580232 100644 --- a/source/blender/blenkernel/intern/implicit.c +++ b/source/blender/blenkernel/intern/implicit.c @@ -812,6 +812,31 @@ int implicit_free (ClothModifierData *clmd) return 1; } +void cloth_bending_mode(ClothModifierData *clmd, int enabled) +{ + Cloth *cloth = clmd->clothObject; + Implicit_Data *id; + + if(cloth) + { + id = cloth->implicit; + + if(id) + { + if(enabled) + { + cloth->numsprings = cloth->numspringssave; + } + else + { + cloth->numsprings = cloth->numothersprings; + } + + id->A[0].scount = id->dFdV[0].scount = id->dFdX[0].scount = id->P[0].scount = id->Pinv[0].scount = id->bigI[0].scount = cloth->numsprings; + } + } +} + DO_INLINE float fb(float length, float L) { float x = length/L; @@ -1223,37 +1248,48 @@ DO_INLINE void cloth_calc_spring_force(ClothModifierData *clmd, ClothSpring *s, { if(length < L) { + // clmd->sim_parms.flags |= CLOTH_SIMSETTINGS_FLAG_BIG_FORCE; + s->flags |= CLOTH_SPRING_FLAG_NEEDED; k = clmd->sim_parms.bending; mul_fvector_S(bending_force, dir, fbstar(length, L, k, cb)); VECADD(s->f, s->f, bending_force); - + + if(INPR(bending_force,bending_force) > 0.13*0.13) + { + clmd->sim_parms.flags |= CLOTH_SIMSETTINGS_FLAG_BIG_FORCE; + } + dfdx_spring_type2(s->dfdx, dir,length,L,k, cb); } } } -DO_INLINE void cloth_apply_spring_force(ClothModifierData *clmd, ClothSpring *s, lfVector *lF, lfVector *X, lfVector *V, fmatrix3x3 *dFdV, fmatrix3x3 *dFdX) +DO_INLINE int cloth_apply_spring_force(ClothModifierData *clmd, ClothSpring *s, lfVector *lF, lfVector *X, lfVector *V, fmatrix3x3 *dFdV, fmatrix3x3 *dFdX) { if(s->flags & CLOTH_SPRING_FLAG_NEEDED) { + VECADD(lF[s->ij], lF[s->ij], s->f); + VECSUB(lF[s->kl], lF[s->kl], s->f); + if(s->type != CLOTH_SPRING_TYPE_BENDING) { sub_fmatrix_fmatrix(dFdV[s->ij].m, dFdV[s->ij].m, s->dfdv); sub_fmatrix_fmatrix(dFdV[s->kl].m, dFdV[s->kl].m, s->dfdv); add_fmatrix_fmatrix(dFdV[s->matrix_index].m, dFdV[s->matrix_index].m, s->dfdv); } - - VECADD(lF[s->ij], lF[s->ij], s->f); - VECSUB(lF[s->kl], lF[s->kl], s->f); - + else if(!(clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_BIG_FORCE)) + return 0; + sub_fmatrix_fmatrix(dFdX[s->ij].m, dFdX[s->ij].m, s->dfdx); sub_fmatrix_fmatrix(dFdX[s->kl].m, dFdX[s->kl].m, s->dfdx); add_fmatrix_fmatrix(dFdX[s->matrix_index].m, dFdX[s->matrix_index].m, s->dfdx); - } + } + + return 1; } DO_INLINE void calculateTriangleNormal(float to[3], lfVector *X, MFace mface) @@ -1386,15 +1422,34 @@ void cloth_calc_force(ClothModifierData *clmd, lfVector *lF, lfVector *lX, lfVec search = search->next; } + if(clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_BIG_FORCE) + { + if(cloth->numspringssave != cloth->numsprings) + { + cloth_bending_mode(clmd, 1); + } + } + else + { + if(cloth->numspringssave == cloth->numsprings) + { + cloth_bending_mode(clmd, 0); + } + } + // apply spring forces search = cloth->springs; while(search) { // only handle active springs // if(((clmd->sim_parms.flags & CSIMSETT_FLAG_TEARING_ENABLED) && !(springs[i].flags & CSPRING_FLAG_DEACTIVATE))|| !(clmd->sim_parms.flags & CSIMSETT_FLAG_TEARING_ENABLED)) - cloth_apply_spring_force(clmd, search->link, lF, lX, lV, dFdV, dFdX); + if(!cloth_apply_spring_force(clmd, search->link, lF, lX, lV, dFdV, dFdX)) + break; search = search->next; } + + clmd->sim_parms.flags &= ~CLOTH_SIMSETTINGS_FLAG_BIG_FORCE; + } void simulate_implicit_euler(lfVector *Vnew, lfVector *lX, lfVector *lV, lfVector *lF, fmatrix3x3 *dFdV, fmatrix3x3 *dFdX, float dt, fmatrix3x3 *A, lfVector *B, lfVector *dV, fmatrix3x3 *S, lfVector *z, lfVector *olddV, fmatrix3x3 *P, fmatrix3x3 *Pinv) @@ -1438,6 +1493,8 @@ int implicit_solver (Object *ob, float frame, ClothModifierData *clmd, ListBase float dt = 1.0f / clmd->sim_parms.stepsPerFrame; Implicit_Data *id = cloth->implicit; int result = 0; + float force = 0, lastforce = 0; + lfVector *dx; if(clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_GOAL) /* do goal stuff */ { @@ -1457,10 +1514,27 @@ int implicit_solver (Object *ob, float frame, ClothModifierData *clmd, ListBase effectors= pdInitEffectors(ob,NULL); // calculate - cloth_calc_force(clmd, id->F, id->X, id->V, id->dFdV, id->dFdX, effectors, step ); - simulate_implicit_euler(id->Vnew, id->X, id->V, id->F, id->dFdV, id->dFdX, dt, id->A, id->B, id->dV, id->S, id->z, id->olddV, id->P, id->Pinv); + cloth_calc_force(clmd, id->F, id->X, id->V, id->dFdV, id->dFdX, effectors, step ); - add_lfvector_lfvectorS(id->Xnew, id->X, id->Vnew, dt, numverts); + // check for sleeping + if(!(clmd->coll_parms.flags & CLOTH_SIMSETTINGS_FLAG_SLEEP)) + { + simulate_implicit_euler(id->Vnew, id->X, id->V, id->F, id->dFdV, id->dFdX, dt, id->A, id->B, id->dV, id->S, id->z, id->olddV, id->P, id->Pinv); + + add_lfvector_lfvectorS(id->Xnew, id->X, id->Vnew, dt, numverts); + } + + dx = create_lfvector(numverts); + sub_lfvector_lfvector(dx, id->Xnew, id->X, numverts); + force = dot_lfvector(dx, dx, numverts); + del_lfvector(dx); + + if((force < 0.00001) && (lastforce >= force)) + clmd->coll_parms.flags |= CLOTH_SIMSETTINGS_FLAG_SLEEP; + else if((lastforce*2 < force)) + clmd->coll_parms.flags &= ~CLOTH_SIMSETTINGS_FLAG_SLEEP; + + lastforce = force; if(clmd->coll_parms.flags & CLOTH_COLLISIONSETTINGS_FLAG_ENABLED) { diff --git a/source/blender/blenkernel/intern/verlet.c b/source/blender/blenkernel/intern/verlet.c deleted file mode 100644 index 71001fa92a5..00000000000 --- a/source/blender/blenkernel/intern/verlet.c +++ /dev/null @@ -1,170 +0,0 @@ -/* implicit.c -* -* -* ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** -* -* This program is free software; you can redistribute it and/or -* modify it under the terms of the GNU General Public License -* as published by the Free Software Foundation; either version 2 -* of the License, or (at your option) any later version. The Blender -* Foundation also sells licenses for use in proprietary software under -* the Blender License. See http://www.blender.org/BL/ for information -* about this. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program; if not, write to the Free Software Foundation, -* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -* -* The Original Code is Copyright (C) Blender Foundation -* All rights reserved. -* -* The Original Code is: all of this file. -* -* Contributor(s): none yet. -* -* ***** END GPL/BL DUAL LICENSE BLOCK ***** -*/ -#include -#include -#include -#include -#include "MEM_guardedalloc.h" -/* types */ -#include "DNA_curve_types.h" -#include "DNA_object_types.h" -#include "DNA_object_force.h" -#include "DNA_cloth_types.h" -#include "DNA_key_types.h" -#include "DNA_mesh_types.h" -#include "DNA_modifier_types.h" -#include "DNA_meshdata_types.h" -#include "DNA_lattice_types.h" -#include "DNA_scene_types.h" -#include "DNA_modifier_types.h" -#include "BLI_arithb.h" -#include "BLI_blenlib.h" -#include "BLI_edgehash.h" -#include "BLI_threads.h" -#include "BKE_collisions.h" -#include "BKE_curve.h" -#include "BKE_displist.h" -#include "BKE_effect.h" -#include "BKE_global.h" -#include "BKE_key.h" -#include "BKE_object.h" -#include "BKE_cloth.h" -#include "BKE_modifier.h" -#include "BKE_utildefines.h" -#include "BKE_global.h" -#include "BIF_editdeform.h" - -struct Cloth; - -int verlet_init ( Object *ob, ClothModifierData *clmd ) -{ - return 1; -} - -int verlet_free ( ClothModifierData *clmd ) -{ - return 1; -} - -void integrate ( ClothModifierData *clmd, float dt ) -{ - Cloth *cloth = clmd->clothObject; - unsigned int i = 0; - - // temporary vectors - float temp[3], velocity[3], force[3]; - - mul_fvector_S( force, clmd->sim_parms.gravity, dt*dt ); - - // iterate through all control points - for(i = 0; i < cloth->numverts; i++) - { - if(((clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_GOAL) && (cloth->verts [i].goal < SOFTGOALSNAP)) || !(clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_GOAL)) - { - // save current control point location - VECCOPY ( temp, cloth->x[i] ); - - // update control point by the formula - // x += (x - old_x)*dampingFactor + force*timeStep^2 - VECSUB ( velocity, cloth->x[i], cloth->xold[i] ); - VECSUBMUL( force, velocity, -clmd->sim_parms.Cvi * 0.01f* dt * dt); - VecMulf(velocity, 0.99); - VECADD ( cloth->x[i], cloth->x[i], velocity ); - VECADD ( cloth->x[i], cloth->x[i], force ); - - // store old control point location - VECCOPY ( cloth->xold[i], temp ); - } - } -} - -void satisfyconstraints(ClothModifierData *clmd) -{ - float delta[3]; - Cloth *cloth = clmd->clothObject; - unsigned int i = 0; - - for(i = 0; i < 5; i++) - { - // calculate spring forces - LinkNode *search = cloth->springs; - while(search) - { - ClothSpring *spring = search->link; - float temp = 0; - float restlen2 = spring->restlen * spring->restlen; - float len2 = 0, len = 0; - - VECSUB(delta, cloth->x[spring->kl], cloth->x[spring->ij]); - len = sqrt(INPR(delta, delta)); - - if(spring->type != CLOTH_SPRING_TYPE_BENDING) - { - temp = (len - spring->restlen)/len; - - mul_fvector_S(delta, delta, temp*0.5); - - // check if vertex is pinned - if(((clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_GOAL) && (cloth->verts [spring->ij].goal < SOFTGOALSNAP)) || !(clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_GOAL)) - VECADD(cloth->x[spring->ij], cloth->x[spring->ij], delta); - - // check if vertex is pinned - if(((clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_GOAL) && (cloth->verts [spring->kl].goal < SOFTGOALSNAP)) || !(clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_GOAL)) - VECSUB(cloth->x[spring->kl], cloth->x[spring->kl], delta); - } - - search = search->next; - } - } -} - -int verlet_solver ( Object *ob, float frame, ClothModifierData *clmd, ListBase *effectors ) -{ - float dt = 0.01; - float step = 0; - - while(step < 1.0f) - { - integrate(clmd, dt); - satisfyconstraints(clmd); - - step+= dt; - } - - return 1; -} - - - - - - diff --git a/source/blender/makesdna/DNA_cloth_types.h b/source/blender/makesdna/DNA_cloth_types.h index 0edfb64e92f..4d75f7a3778 100644 --- a/source/blender/makesdna/DNA_cloth_types.h +++ b/source/blender/makesdna/DNA_cloth_types.h @@ -161,6 +161,8 @@ typedef struct Cloth float (*v)[3]; /* the current velocity of all vertices */ float (*current_v)[3]; struct EdgeHash *edgehash; // used for fast checking adjacent points + unsigned int numothersprings; + unsigned int numspringssave; } Cloth; From cbc941e342478df6126068f84044d26a1b1aa4e1 Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Tue, 6 Nov 2007 09:44:09 +0000 Subject: [PATCH 046/246] Merged pointcache from particles branch, but is not used in the moment --- source/blender/blenkernel/BKE_pointcache.h | 41 +++++ source/blender/blenkernel/intern/modifier.c | 111 ++++++++++++ source/blender/blenkernel/intern/pointcache.c | 159 ++++++++++++++++++ source/blender/makesdna/DNA_modifier_types.h | 11 ++ source/blender/src/buttons_editing.c | 23 +++ 5 files changed, 345 insertions(+) create mode 100644 source/blender/blenkernel/BKE_pointcache.h create mode 100644 source/blender/blenkernel/intern/pointcache.c diff --git a/source/blender/blenkernel/BKE_pointcache.h b/source/blender/blenkernel/BKE_pointcache.h new file mode 100644 index 00000000000..9359177b4e9 --- /dev/null +++ b/source/blender/blenkernel/BKE_pointcache.h @@ -0,0 +1,41 @@ +/* +* +* ***** BEGIN GPL LICENSE BLOCK ***** +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* as published by the Free Software Foundation; either version 2 +* of the License, or (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software Foundation, +* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +* +* The Original Code is Copyright (C) 2006 Blender Foundation. +* All rights reserved. +* +* The Original Code is: all of this file. +* +* Contributor(s): Campbell Barton +* +* ***** END GPL LICENSE BLOCK ***** +*/ + +#ifndef BKE_POINTCACHE_H +#define BKE_POINTCACHE_H + +#include "DNA_ID.h" + +#define PTCache_EXT ".bphys" +#define PTCache_PATH "//pointcache/" + +int PTCache_id_filename(struct ID *id, char *filename, int cfra, int stack_index, short do_path, short do_ext); +FILE * PTCache_id_fopen(struct ID *id, char mode, int cfra, int stack_index); +void PTCache_id_clear(struct ID *id, int cfra, int stack_index); + +#endif diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c index b124395c207..22692f503e1 100644 --- a/source/blender/blenkernel/intern/modifier.c +++ b/source/blender/blenkernel/intern/modifier.c @@ -5382,6 +5382,83 @@ static void meshdeformModifier_deformVertsEM( dm->release(dm); } + +/* PointCache - example DONT USE SERIOUSLY */ +static void pointCacheModifier_initData(ModifierData *md) +{ + PointCacheModifierData *pcm= (PointCacheModifierData*) md; + + pcm->mode= ePointCache_Read; /* read */ +} +static void pointCacheModifier_freeData(ModifierData *md) +{ + PointCacheModifierData *pcm = (PointCacheModifierData*) md; +} +static void pointCacheModifier_copyData(ModifierData *md, ModifierData *target) +{ + PointCacheModifierData *pcm= (PointCacheModifierData*) md; + PointCacheModifierData *tpcm= (PointCacheModifierData*) target; + + tpcm->mode = pcm->mode; +} +static int pointCacheModifier_dependsOnTime(ModifierData *md) +{ + return 1; +} +CustomDataMask pointCacheModifier_requiredDataMask(ModifierData *md) +{ + PointCacheModifierData *pcm= (PointCacheModifierData*) md; + CustomDataMask dataMask = 0; + return dataMask; +} + +static void pointCacheModifier_deformVerts( + ModifierData *md, Object *ob, DerivedMesh *derivedData, + float (*vertexCos)[3], int numVerts) +{ + PointCacheModifierData *pcm = (PointCacheModifierData*) md; + + FILE *fp = NULL; + int i; + int stack_index = modifiers_indexInObject(ob, md); + int totvert; + MVert *mvert, *mv; + + DerivedMesh *dm; + + if(derivedData) dm = CDDM_copy(derivedData); + else if(ob->type==OB_MESH) dm = CDDM_from_mesh(ob->data, ob); + else return; + + CDDM_apply_vert_coords(dm, vertexCos); + CDDM_calc_normals(dm); + + mvert = mv = dm->getVertArray(dm); + totvert = dm->getNumVerts(dm); + + if (pcm->mode == ePointCache_Read) { + fp = PTCache_id_fopen((ID *)ob, 'w', G.scene->r.cfra, stack_index); + if (!fp) return; + for (mv=mvert, i=0; ico, sizeof(float), 3, fp); + } + fclose(fp); + } else if (pcm->mode == ePointCache_Write) { + float pt[3]; + fp = PTCache_id_fopen((ID *)ob, 'r', G.scene->r.cfra, stack_index); + if (!fp) return; + for (mv=mvert, i=0; irelease(dm); +} + /***/ static ModifierTypeInfo typeArr[NUM_MODIFIER_TYPES]; @@ -5649,6 +5726,16 @@ ModifierTypeInfo *modifierType_getInfo(ModifierType type) mti->updateDepgraph = meshdeformModifier_updateDepgraph; mti->deformVerts = meshdeformModifier_deformVerts; mti->deformVertsEM = meshdeformModifier_deformVertsEM; + + mti = INIT_TYPE(PointCache); + mti->type = eModifierTypeType_OnlyDeform; + mti->flags = eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_RequiresOriginalData; + mti->initData = pointCacheModifier_initData; + mti->freeData = pointCacheModifier_freeData; + mti->copyData = pointCacheModifier_copyData; + mti->dependsOnTime = pointCacheModifier_dependsOnTime; + mti->requiredDataMask = pointCacheModifier_requiredDataMask; + mti->deformVerts = pointCacheModifier_deformVerts; typeArrInit = 0; #undef INIT_TYPE @@ -6032,3 +6119,27 @@ int modifiers_isDeformed(Object *ob) return 0; } +/* checks we only have deform modifiers */ +int modifiers_isDeformedOnly(Object *ob) +{ + ModifierData *md = modifiers_getVirtualModifierList(ob); + ModifierTypeInfo *mti; + for (; md; md=md->next) { + mti = modifierType_getInfo(md->type); + /* TODO - check the modifier is being used! */ + if (mti->type != eModifierTypeType_OnlyDeform) { + return 0; + } + } + return 1; +} + +int modifiers_indexInObject(Object *ob, ModifierData *md_seek) +{ + int i= 0; + ModifierData *md; + + for (md=ob->modifiers.first; (md && md_seek!=md); md=md->next, i++); + if (!md) return -1; /* modifier isnt in the object */ + return i; +} diff --git a/source/blender/blenkernel/intern/pointcache.c b/source/blender/blenkernel/intern/pointcache.c new file mode 100644 index 00000000000..b87a43c30c3 --- /dev/null +++ b/source/blender/blenkernel/intern/pointcache.c @@ -0,0 +1,159 @@ +/** + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * +* Contributor(s): Campbell Barton + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + */ + + +#include +#include +#include +#include +#include + +#include "BKE_pointcache.h" + +#include "BKE_utildefines.h" +#include "BKE_global.h" +#include "BKE_library.h" + +#include "BLI_blenlib.h" +#include "BKE_utildefines.h" +#include "blendef.h" + +/* needed for directory lookup */ +#ifndef WIN32 + #include +#else + #include "BLI_winstuff.h" +#endif + +/* Takes an Object ID and returns a unique name + - id: object id + - cfra: frame for the cache, can be negative + - stack_index: index in the modifier stack. we can have cache for more then one stack_index +*/ + +int PTCache_path(char *filename) +{ + sprintf(filename, PTCache_PATH); + BLI_convertstringcode(filename, G.sce, 0); + return strlen(filename); +} + +int PTCache_id_filename(struct ID *id, char *filename, int cfra, int stack_index, short do_path, short do_ext) +{ + int len=0; + char *idname; + char *newname; + filename[0] = '\0'; + newname = filename; + + /* start with temp dir */ + if (do_path) { + len = PTCache_path(filename); + newname += len; + } + idname = (id->name+2); + /* convert chars to hex so they are always a valid file */ + while('\0' != *idname) { + sprintf(newname, "%02X", (char)(*idname++)); + newname+=2; + len += 2; + } + + if (do_ext) { + sprintf(newname, "_%06d_%02d"PTCache_EXT, cfra, stack_index); /* always 6 chars */ + len += 16; + } + + return len; /* make sure the above string is always 16 chars */ +} + +/* youll need to close yourself after! */ +FILE *PTCache_id_fopen(struct ID *id, char mode, int cfra, int stack_index) +{ + /* mode is same as fopen's modes */ + FILE *fp; + char filename[(FILE_MAXDIR+FILE_MAXFILE)*2]; + + PTCache_id_filename(id, filename, cfra, stack_index, 1, 1); + + if (mode=='r') { + if (!BLI_exists(filename)) { + printf("Error, file does not exist '%s'\n", filename); + return NULL; + } + fp = fopen(filename, "rb"); + } else if (mode=='w') { + BLI_make_existing_file(filename); /* will create the dir if needs be, same as //textures is created */ + fp = fopen(filename, "wb"); + } + + if (!fp) { + printf("Error creating file filename '%s'\n", filename); + return NULL; + } + + return fp; +} + +/* youll need to close yourself after! */ +void PTCache_id_clear(struct ID *id, int cfra, int stack_index) +{ + int len; /* store the length of the string */ + + /* mode is same as fopen's modes */ + DIR *dir; + struct dirent *de; + char path[FILE_MAX]; + char filename[(FILE_MAXDIR+FILE_MAXFILE)*2]; + char path_full[(FILE_MAXDIR+FILE_MAXFILE)*2]; + + PTCache_path(path); + len = PTCache_id_filename(id, filename, cfra, stack_index, 0, 0); /* no path */ + + /* clear all files in the temp dir with the prefix of the ID and the ".bphys" suffix */ + + dir = opendir(path); + if (dir==NULL) + return; + + while ((de = readdir(dir)) != NULL) { + //if (S_ISREG(status.st_mode)) { /* is file */ + if (strstr(de->d_name, PTCache_EXT)) { /* do we have the right extension?*/ + if (strncmp(filename, de->d_name, len ) == 0) { /* do we have the right prefix */ + BLI_join_dirfile(path_full, path, de->d_name); + BLI_delete(path_full, 0, 0); + } + } + //} + } + + closedir(dir); + return; +} + diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h index 0aa7d1d4d3d..ee28d7325c7 100644 --- a/source/blender/makesdna/DNA_modifier_types.h +++ b/source/blender/makesdna/DNA_modifier_types.h @@ -31,6 +31,7 @@ typedef enum ModifierType { eModifierType_Smooth, eModifierType_Cast, eModifierType_MeshDeform, + eModifierType_PointCache, eModifierType_Cloth, eModifierType_Collision, NUM_MODIFIER_TYPES @@ -386,4 +387,14 @@ typedef struct MeshDeformModifierData { int totvert, totcagevert; } MeshDeformModifierData; +typedef struct PointCacheModifierData { + ModifierData modifier; + short mode, pad1, pad2, pad3; +} PointCacheModifierData; + +typedef enum { + ePointCache_Read = (1<<0), + ePointCache_Write = (1<<1), +} PointCacheFlag; + #endif diff --git a/source/blender/src/buttons_editing.c b/source/blender/src/buttons_editing.c index 82ca6e5bed0..3da0196cc46 100644 --- a/source/blender/src/buttons_editing.c +++ b/source/blender/src/buttons_editing.c @@ -88,6 +88,7 @@ #include "BKE_main.h" #include "BKE_modifier.h" #include "BKE_packedFile.h" +#include "BKE_pointcache.h" #include "BKE_scene.h" #include "BLI_blenlib.h" @@ -1398,6 +1399,14 @@ static void modifiers_convertToReal(void *ob_v, void *md_v) BIF_undo_push("Modifier convert to real"); } +static void modifiers_pointCacheClearModifier(void *ob_v, void *md_v) +{ + Object *ob = ob_v; + ModifierData *md = md_v; + int stack_index = modifiers_indexInObject(ob_v, md_v); + PTCache_id_clear((ID *)ob, CFRA, stack_index); +} + static void build_uvlayer_menu_vars(CustomData *data, char **menu_string, int *uvlayer_tmp, char *uvlayer_name) { @@ -1646,6 +1655,8 @@ static void draw_modifier(uiBlock *block, Object *ob, ModifierData *md, int *xco height = 211; } else if (md->type==eModifierType_MeshDeform) { height = 73; + } else if (md->type==eModifierType_PointCache) { + height = 48; } /* roundbox 4 free variables: corner-rounding, nop, roundbox type, shade */ @@ -2144,6 +2155,18 @@ static void draw_modifier(uiBlock *block, Object *ob, ModifierData *md, int *xco uiDefButS(block, NUM, B_NOP, "Precision:", lx+(buttonWidth+1)/2,(cy-=24), buttonWidth/2,19, &mmd->gridsize, 2, 10, 0.5, 0, "The grid size for binding"); } uiBlockEndAlign(block); + } else if (md->type==eModifierType_PointCache) { + PointCacheModifierData *pcm = (PointCacheModifierData *) md; + uiBut *but; + cy -= 20; + uiBlockEndAlign(block); + + uiDefButS(block, ROW,B_MODIFIER_RECALC,"Write Cache", lx, cy, 75, 19, &pcm->mode, 12.0, ePointCache_Read, 0, 0, ""); + uiDefButS(block, ROW,B_MODIFIER_RECALC,"Read Cache", lx+75, cy, 75,19, &pcm->mode, 12.0, ePointCache_Write, 0, 0, ""); + cy -= 20; + but = uiDefBut(block, BUT, B_NOP, "Clear Cache", lx, cy, 150,19, 0, 0, 0, 0, 0, ""); + uiButSetFunc(but, modifiers_pointCacheClearModifier, ob, md); + } uiBlockEndAlign(block); From b37bbe9024e3da2efe01c48235993b426a3bb923 Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Tue, 6 Nov 2007 12:08:39 +0000 Subject: [PATCH 047/246] New: pointcache integrated with cloth. Maybe some little glitches left there --- source/blender/blenkernel/BKE_cloth.h | 2 +- source/blender/blenkernel/intern/cloth.c | 159 ++++++++++++++----- source/blender/blenkernel/intern/implicit.c | 10 +- source/blender/makesdna/DNA_cloth_types.h | 23 ++- source/blender/makesdna/DNA_modifier_types.h | 2 +- source/blender/src/buttons_object.c | 6 +- 6 files changed, 141 insertions(+), 61 deletions(-) diff --git a/source/blender/blenkernel/BKE_cloth.h b/source/blender/blenkernel/BKE_cloth.h index 8be27ace346..83891cc74d3 100644 --- a/source/blender/blenkernel/BKE_cloth.h +++ b/source/blender/blenkernel/BKE_cloth.h @@ -118,7 +118,7 @@ typedef enum // needed for buttons_object.c -// void cloth_cache_free ( ClothModifierData *clmd, float time ); +void cloth_clear_cache(Object *ob, ClothModifierData *clmd, float framenr); void cloth_free_modifier ( ClothModifierData *clmd ); // needed for cloth.c diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c index eba11bfedda..9720ec6b141 100644 --- a/source/blender/blenkernel/intern/cloth.c +++ b/source/blender/blenkernel/intern/cloth.c @@ -39,15 +39,15 @@ /* types */ #include "DNA_curve_types.h" +#include "DNA_cloth_types.h" #include "DNA_object_types.h" #include "DNA_object_force.h" -#include "DNA_cloth_types.h" #include "DNA_key_types.h" +#include "DNA_lattice_types.h" #include "DNA_mesh_types.h" #include "DNA_meshdata_types.h" -#include "DNA_lattice_types.h" -#include "DNA_scene_types.h" #include "DNA_modifier_types.h" +#include "DNA_scene_types.h" #include "BLI_blenlib.h" #include "BLI_arithb.h" @@ -55,6 +55,8 @@ #include "BLI_linklist.h" #include "BKE_curve.h" +#include "BKE_cloth.h" +#include "BKE_collisions.h" #include "BKE_deform.h" #include "BKE_DerivedMesh.h" #include "BKE_cdderivedmesh.h" @@ -63,12 +65,11 @@ #include "BKE_global.h" #include "BKE_key.h" #include "BKE_mesh.h" -#include "BKE_object.h" -#include "BKE_cloth.h" -#include "BKE_collisions.h" #include "BKE_modifier.h" +#include "BKE_object.h" +#include "BKE_pointcache.h" #include "BKE_utildefines.h" -#include "BKE_DerivedMesh.h" + #include "BIF_editdeform.h" #include "BIF_editkey.h" #include "DNA_screen_types.h" @@ -403,10 +404,89 @@ DerivedMesh *CDDM_create_tearing(ClothModifierData *clmd, DerivedMesh *dm) return NULL; } -/** -* cloth_deform_verts - simulates one step, framenr is in frames. -* -**/ +int modifiers_indexInObject(Object *ob, ModifierData *md_seek); + +void cloth_clear_cache(Object *ob, ClothModifierData *clmd, float framenr) +{ + int stack_index = -1; + + if(!(clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_CCACHE_PROTECT)) + { + stack_index = modifiers_indexInObject(ob, (ModifierData *)clmd); + + PTCache_id_clear((ID *)ob, framenr, stack_index); + } +} +static void cloth_write_cache(Object *ob, ClothModifierData *clmd, float framenr) +{ + FILE *fp = NULL; + int stack_index = -1; + unsigned int a; + Cloth *cloth = clmd->clothObject; + + if(!cloth) + return; + + stack_index = modifiers_indexInObject(ob, (ModifierData *)clmd); + + fp = PTCache_id_fopen((ID *)ob, 'w', framenr, stack_index); + if(!fp) return; + + for(a = 0; a < cloth->numverts; a++) + { + fwrite(&cloth->x[a], sizeof(float),3,fp); + fwrite(&cloth->xconst[a], sizeof(float),3,fp); + fwrite(&cloth->v[a], sizeof(float),3,fp); + } + + fclose(fp); +} +static int cloth_read_cache(Object *ob, ClothModifierData *clmd, float framenr) +{ + FILE *fp = NULL; + int stack_index = -1; + unsigned int a, ret = 1; + Cloth *cloth = clmd->clothObject; + + if(!cloth) + return 0; + + stack_index = modifiers_indexInObject(ob, (ModifierData *)clmd); + + fp = PTCache_id_fopen((ID *)ob, 'r', framenr, stack_index); + if(!fp) + ret = 0; + else { + for(a = 0; a < cloth->numverts; a++) + { + if(fread(&cloth->x[a], sizeof(float), 3, fp) != 3) + { + ret = 0; + break; + } + if(fread(&cloth->xconst[a], sizeof(float), 3, fp) != 3) + { + ret = 0; + break; + } + if(fread(&cloth->v[a], sizeof(float), 3, fp) != 3) + { + ret = 0; + break; + } + } + + fclose(fp); + } + + implicit_set_positions(clmd); + + return ret; +} + +/************************************************ + * clothModifier_do - main simulation function +************************************************/ DerivedMesh *clothModifier_do(ClothModifierData *clmd,Object *ob, DerivedMesh *dm, int useRenderParams, int isFinalCalc) { unsigned int i; @@ -421,7 +501,6 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd,Object *ob, DerivedMesh *d unsigned int framenr = (float)G.scene->r.cfra; float current_time = bsystem_time(ob, (float)G.scene->r.cfra, 0.0); ListBase *effectors = NULL; - ClothVertex *verts = NULL; float deltaTime = current_time - clmd->sim_parms.sim_time; clmd->sim_parms.dt = 1.0f / (clmd->sim_parms.stepsPerFrame * G.scene->r.frs_sec); @@ -441,7 +520,10 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd,Object *ob, DerivedMesh *d mface = CDDM_get_faces(result); clmd->sim_parms.sim_time = current_time; - + + if ( current_time < clmd->sim_parms.firstframe ) + return result; + // only be active during a specific period: // that's "first frame" and "last frame" on GUI /* @@ -501,20 +583,18 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd,Object *ob, DerivedMesh *d // Insure we have a clmd->clothObject, in case allocation failed. if (clmd->clothObject != NULL) { - // if(!cloth_cache_search_frame(clmd, framenr)) + if(!cloth_read_cache(ob, clmd, framenr)) { - verts = cloth->verts; - // Force any pinned verts to their constrained location. // has to be commented for verlet - for ( i = 0; i < clmd->clothObject->numverts; i++, verts++ ) + for ( i = 0; i < clmd->clothObject->numverts; i++ ) { // Save the previous position. - VECCOPY ( cloth->xold[i], verts->xconst ); + VECCOPY ( cloth->xold[i], cloth->xconst[i] ); VECCOPY ( cloth->current_xold[i], cloth->x[i] ); // Get the current position. - VECCOPY ( verts->xconst, mvert[i].co ); - Mat4MulVecfl ( ob->obmat, verts->xconst ); + VECCOPY ( cloth->xconst[i], mvert[i].co ); + Mat4MulVecfl ( ob->obmat, cloth->xconst[i] ); } tstart(); @@ -527,13 +607,8 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd,Object *ob, DerivedMesh *d printf("Cloth simulation time: %f\n", tval()); - // cloth_cache_set_frame(clmd, framenr); - - }/* - else // just retrieve the cached frame - { - cloth_cache_get_frame(clmd, framenr); - }*/ + cloth_write_cache(ob, clmd, framenr); + } // Copy the result back to the object. cloth_to_object (ob, result, clmd); @@ -542,18 +617,15 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd,Object *ob, DerivedMesh *d // clmd->clothObject->tree = bvh_build(clmd, clmd->coll_parms.epsilon); } - }/* + } else if ( ( deltaTime <= 0.0f ) || ( deltaTime > 1.0f ) ) { - if ( ( clmd->clothObject != NULL ) && ( clmd->sim_parms.cache ) ) + if ( clmd->clothObject != NULL ) { - if ( cloth_cache_search_frame ( clmd, framenr ) ) - { - cloth_cache_get_frame(clmd, framenr); + if(cloth_read_cache(ob, clmd, framenr)) cloth_to_object (ob, result, clmd); - } } - }*/ + } return result; } @@ -569,7 +641,7 @@ void cloth_free_modifier (ClothModifierData *clmd) cloth = clmd->clothObject; // free our frame cache - // cloth_cache_free(clmd, 0); + // cloth_clear_cache(ob, clmd, 0); /* Calls the solver and collision frees first as they * might depend on data in clmd->clothObject. */ @@ -614,6 +686,10 @@ void cloth_free_modifier (ClothModifierData *clmd) if ( cloth->current_v != NULL ) MEM_freeN ( cloth->current_v ); + // Free the verts. + if ( cloth->xconst != NULL ) + MEM_freeN ( cloth->xconst ); + cloth->verts = NULL; cloth->numverts = -1; @@ -806,7 +882,7 @@ static int cloth_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *d clmd->clothObject->verts [i].goal= 0.0; clmd->clothObject->verts [i].flags = 0; VECCOPY(clmd->clothObject->xold[i], clmd->clothObject->x[i]); - VECCOPY(clmd->clothObject->verts [i].xconst, clmd->clothObject->x[i]); + VECCOPY(clmd->clothObject->xconst[i], clmd->clothObject->x[i]); VECCOPY(clmd->clothObject->current_xold[i], clmd->clothObject->x[i]); VecMulf(clmd->clothObject->v[i], 0.0); @@ -826,7 +902,8 @@ static int cloth_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *d clmd->clothObject->selftree = bvh_build_from_float3(NULL, 0, clmd->clothObject->x, numverts, clmd->coll_parms.selfepsilon); - // cloth_cache_set_frame(clmd, 1); + // save initial state + cloth_write_cache(ob, clmd, framenr-1); } return 1; @@ -900,6 +977,14 @@ static void cloth_from_mesh (Object *ob, ClothModifierData *clmd, DerivedMesh *d modifier_setError ( & ( clmd->modifier ), "Out of memory on allocating clmd->clothObject->current_v." ); return; } + + clmd->clothObject->xconst = MEM_callocN ( sizeof ( float ) * clmd->clothObject->numverts * 3, "Cloth MVert_xconst" ); + if ( clmd->clothObject->xconst == NULL ) + { + cloth_free_modifier ( clmd ); + modifier_setError ( & ( clmd->modifier ), "Out of memory on allocating clmd->clothObject->xconst." ); + return; + } // save face information clmd->clothObject->numfaces = numfaces; diff --git a/source/blender/blenkernel/intern/implicit.c b/source/blender/blenkernel/intern/implicit.c index 091a0580232..41cc9e8cef4 100644 --- a/source/blender/blenkernel/intern/implicit.c +++ b/source/blender/blenkernel/intern/implicit.c @@ -1369,7 +1369,7 @@ void cloth_calc_force(ClothModifierData *clmd, lfVector *lF, lfVector *lX, lfVec if(verts [i].goal < SOFTGOALSNAP) { // current_position = xold + t * (newposition - xold) - VECSUB(tvect, verts[i].xconst, cloth->xold[i]); + VECSUB(tvect, cloth->xconst[i], cloth->xold[i]); mul_fvector_S(tvect, tvect, time); VECADD(tvect, tvect, cloth->xold[i]); @@ -1378,7 +1378,7 @@ void cloth_calc_force(ClothModifierData *clmd, lfVector *lF, lfVector *lX, lfVec VECADDS(lF[i], lF[i], auxvect, -ks); // calulate damping forces generated by goals - VECSUB(velgoal, cloth->xold[i], verts[i].xconst); + VECSUB(velgoal, cloth->xold[i], cloth->xconst[i]); kd = clmd->sim_parms.goalfrict * 0.01f; // friction force scale taken from SB VECSUBADDSS(lF[i], velgoal, kd, lV[i], kd); @@ -1503,7 +1503,7 @@ int implicit_solver (Object *ob, float frame, ClothModifierData *clmd, ListBase // update velocities with constrained velocities from pinned verts if(verts [i].goal >= SOFTGOALSNAP) { - VECSUB(id->V[i], verts[i].xconst, cloth->xold[i]); + VECSUB(id->V[i], cloth->xconst[i], cloth->xold[i]); // VecMulf(id->V[i], 1.0 / dt); } } @@ -1625,8 +1625,8 @@ int implicit_solver (Object *ob, float frame, ClothModifierData *clmd, ListBase } else { - VECCOPY(cloth->current_xold[i], verts[i].xconst); - VECCOPY(cloth->x[i], verts[i].xconst); + VECCOPY(cloth->current_xold[i], cloth->xconst[i]); + VECCOPY(cloth->x[i], cloth->xconst[i]); } } } diff --git a/source/blender/makesdna/DNA_cloth_types.h b/source/blender/makesdna/DNA_cloth_types.h index 4d75f7a3778..2441c8b721f 100644 --- a/source/blender/makesdna/DNA_cloth_types.h +++ b/source/blender/makesdna/DNA_cloth_types.h @@ -43,13 +43,11 @@ typedef struct ClothVertex { int flags; /* General flags per vertex. */ - float xconst [3]; /* constrained position */ float mass; /* mass / weight of the vertex */ float goal; /* goal, from SB */ float impulse[3]; /* used in collision.c */ unsigned int impulse_count; /* same as above */ -} -ClothVertex; +} ClothVertex; /** @@ -66,8 +64,7 @@ typedef struct ClothSpring float dfdx[3][3]; float dfdv[3][3]; float f[3]; -} -ClothSpring; +} ClothSpring; @@ -108,13 +105,12 @@ typedef struct SimulationSettings float sim_time_old; struct LinkNode *cache; float defgoal; - int goalfrict; + float goalfrict; float goalspring; int maxspringlen; /* in percent!; if tearing enabled, a spring will get cut */ int lastframe; /* frame on which simulation stops */ int firstframe; /* frame on which simulation starts */ -} -SimulationSettings; +} SimulationSettings; typedef struct CollisionSettings @@ -126,8 +122,7 @@ typedef struct CollisionSettings short loop_count; /* How many iterations for the collision loop. */ int flags; /* collision flags defined in BKE_cloth.h */ float selfepsilon; -} -CollisionSettings; +} CollisionSettings; /** @@ -143,7 +138,7 @@ CollisionSettings; typedef struct Cloth { struct ClothVertex *verts; /* The vertices that represent this cloth. */ - struct LinkNode *springs; /* The springs connecting the mesh. */ + struct LinkNode *springs; /* The springs connecting the mesh. */ unsigned int numverts; /* The number of verts == m * n. */ unsigned int numsprings; /* The count of springs. */ unsigned int numfaces; @@ -160,10 +155,10 @@ typedef struct Cloth float (*current_xold)[3]; /* The TEMPORARY previous position of all vertices.*/ float (*v)[3]; /* the current velocity of all vertices */ float (*current_v)[3]; - struct EdgeHash *edgehash; // used for fast checking adjacent points + float (*xconst)[3]; + struct EdgeHash *edgehash; /* used for fast checking adjacent points */ unsigned int numothersprings; unsigned int numspringssave; -} -Cloth; +} Cloth; #endif diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h index ee28d7325c7..151e652eef0 100644 --- a/source/blender/makesdna/DNA_modifier_types.h +++ b/source/blender/makesdna/DNA_modifier_types.h @@ -344,7 +344,7 @@ typedef struct SoftbodyModifierData { typedef struct ClothModifierData { ModifierData modifier; - Cloth *clothObject; /* The internal data structure for cloth. */ + struct Cloth *clothObject; /* The internal data structure for cloth. */ SimulationSettings sim_parms; /* definition is in DNA_cloth_types.h */ CollisionSettings coll_parms; /* definition is in DNA_cloth_types.h */ } ClothModifierData; diff --git a/source/blender/src/buttons_object.c b/source/blender/src/buttons_object.c index 2e3801135eb..70559d29f40 100644 --- a/source/blender/src/buttons_object.c +++ b/source/blender/src/buttons_object.c @@ -2187,7 +2187,7 @@ void do_object_panels(unsigned short event) CFRA= 1; update_for_newframe_muted(); DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA); - // cloth_cache_free(clmd, 2); + cloth_clear_cache(ob, clmd, 2); allqueue(REDRAWBUTSOBJECT, 0); allqueue(REDRAWVIEW3D, 0); } @@ -2198,7 +2198,7 @@ void do_object_panels(unsigned short event) ClothModifierData *clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth); if(clmd) { - // cloth_cache_free(clmd, MAX2(2.0,G.scene->r.cfra+1.0)); + cloth_clear_cache(ob, clmd, MAX2(2.0,G.scene->r.cfra+1.0)); allqueue(REDRAWBUTSOBJECT, 0); } } @@ -3242,7 +3242,7 @@ static void object_panel_cloth(Object *ob) } uiDefButF(block, NUM, B_CLOTH_RENEW, "G Stiff:", 10,50,150,20, &clmd->sim_parms.goalspring, 0.0, 500.0, 10, 0, "Goal (vertex target position) spring stiffness"); - uiDefButF(block, NUM, B_CLOTH_RENEW, "G Damp:", 160,50,150,20, &clmd->sim_parms.goalfrict , 0.0, 50.0, 10, 0, "Goal (vertex target position) friction"); + uiDefButF(block, NUM, B_CLOTH_RENEW, "G Damp:", 160,50,150,20, &clmd->sim_parms.goalfrict, 0.0, 50.0, 10, 0, "Goal (vertex target position) friction"); uiDefButF(block, NUM, B_CLOTH_RENEW, "G Min:", 10,30,150,20, &clmd->sim_parms.mingoal, 0.0, 1.0, 10, 0, "Goal minimum, vertex group weights are scaled to match this range"); uiDefButF(block, NUM, B_CLOTH_RENEW, "G Max:", 160,30,150,20, &clmd->sim_parms.maxgoal, 0.0, 1.0, 10, 0, "Goal maximum, vertex group weights are scaled to match this range"); } From c5d4e8a137437c047fc84cf9267b5b0d5c164188 Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Tue, 6 Nov 2007 14:26:08 +0000 Subject: [PATCH 048/246] updating bullet --- extern/bullet2/src/Bullet-C-Api.h | 170 +++- .../BroadphaseCollision/btAxisSweep3.cpp | 638 +------------- .../BroadphaseCollision/btAxisSweep3.h | 832 +++++++++++++++++- .../btBroadphaseInterface.h | 18 +- .../BroadphaseCollision/btBroadphaseProxy.h | 48 +- .../btCollisionAlgorithm.cpp | 2 +- .../btCollisionAlgorithm.h | 8 +- .../BroadphaseCollision/btDispatcher.h | 10 +- .../btMultiSapBroadphase.cpp | 204 +++++ .../btMultiSapBroadphase.h | 119 +++ .../btOverlappingPairCache.cpp | 452 ++++++++-- .../btOverlappingPairCache.h | 229 ++++- .../btOverlappingPairCallback.h | 37 + .../btSimpleBroadphase.cpp | 246 ++++-- .../BroadphaseCollision/btSimpleBroadphase.h | 82 +- .../src/BulletCollision/CMakeLists.txt | 8 + .../SphereTriangleDetector.h | 4 +- .../btCollisionConfiguration.h | 47 + .../CollisionDispatch/btCollisionCreateFunc.h | 2 +- .../btCollisionDispatcher.cpp | 206 ++--- .../CollisionDispatch/btCollisionDispatcher.h | 56 +- .../CollisionDispatch/btCollisionObject.cpp | 5 + .../CollisionDispatch/btCollisionObject.h | 21 +- .../CollisionDispatch/btCollisionWorld.cpp | 60 +- .../CollisionDispatch/btCollisionWorld.h | 30 +- .../btCompoundCollisionAlgorithm.cpp | 8 +- .../btCompoundCollisionAlgorithm.h | 19 +- .../btConvexConcaveCollisionAlgorithm.cpp | 12 +- .../btConvexConcaveCollisionAlgorithm.h | 22 +- .../btConvexConvexAlgorithm.cpp | 17 +- .../btConvexConvexAlgorithm.h | 17 +- .../btDefaultCollisionConfiguration.cpp | 237 +++++ .../btDefaultCollisionConfiguration.h | 87 ++ .../btEmptyCollisionAlgorithm.h | 6 +- .../CollisionDispatch/btManifoldResult.cpp | 23 +- .../CollisionDispatch/btManifoldResult.h | 29 +- .../btSimulationIslandManager.cpp | 80 +- .../btSimulationIslandManager.h | 12 +- .../btSphereBoxCollisionAlgorithm.cpp | 19 +- .../btSphereBoxCollisionAlgorithm.h | 15 +- .../btSphereSphereCollisionAlgorithm.cpp | 12 +- .../btSphereSphereCollisionAlgorithm.h | 11 +- .../btSphereTriangleCollisionAlgorithm.cpp | 10 +- .../btSphereTriangleCollisionAlgorithm.h | 11 +- .../CollisionDispatch/btUnionFind.cpp | 1 + .../CollisionDispatch/btUnionFind.h | 6 +- .../CollisionShapes/btBoxShape.cpp | 11 +- .../CollisionShapes/btBoxShape.h | 102 ++- .../btBvhTriangleMeshShape.cpp | 49 +- .../CollisionShapes/btBvhTriangleMeshShape.h | 25 +- .../CollisionShapes/btCapsuleShape.cpp | 2 +- .../CollisionShapes/btCapsuleShape.h | 10 +- .../CollisionShapes/btCollisionShape.h | 24 +- .../CollisionShapes/btCompoundShape.cpp | 13 +- .../CollisionShapes/btCompoundShape.h | 51 +- .../CollisionShapes/btConcaveShape.h | 2 +- .../CollisionShapes/btConeShape.h | 10 +- .../CollisionShapes/btConvexHullShape.h | 7 +- .../CollisionShapes/btConvexInternalShape.cpp | 78 ++ .../CollisionShapes/btConvexInternalShape.h | 99 +++ .../CollisionShapes/btConvexShape.cpp | 59 -- .../CollisionShapes/btConvexShape.h | 90 +- .../btConvexTriangleMeshShape.cpp | 2 +- .../btConvexTriangleMeshShape.h | 10 +- .../CollisionShapes/btCylinderShape.cpp | 14 +- .../CollisionShapes/btCylinderShape.h | 18 +- .../CollisionShapes/btEmptyShape.cpp | 2 +- .../CollisionShapes/btEmptyShape.h | 10 +- .../btHeightfieldTerrainShape.cpp | 52 +- .../btHeightfieldTerrainShape.h | 4 +- .../CollisionShapes/btMinkowskiSumShape.cpp | 2 +- .../CollisionShapes/btMinkowskiSumShape.h | 10 +- .../CollisionShapes/btMultiSphereShape.cpp | 2 +- .../CollisionShapes/btMultiSphereShape.h | 10 +- .../CollisionShapes/btOptimizedBvh.cpp | 394 ++++++++- .../CollisionShapes/btOptimizedBvh.h | 85 +- .../btPolyhedralConvexShape.cpp | 2 +- .../CollisionShapes/btPolyhedralConvexShape.h | 10 +- .../CollisionShapes/btSphereShape.cpp | 2 +- .../CollisionShapes/btSphereShape.h | 18 +- .../CollisionShapes/btStaticPlaneShape.cpp | 2 +- .../CollisionShapes/btStaticPlaneShape.h | 4 +- .../btStridingMeshInterface.cpp | 2 +- .../CollisionShapes/btStridingMeshInterface.h | 2 +- .../CollisionShapes/btTetrahedronShape.h | 4 +- .../CollisionShapes/btTriangleBuffer.h | 2 +- .../CollisionShapes/btTriangleCallback.h | 2 +- .../btTriangleIndexVertexArray.cpp | 23 +- .../btTriangleIndexVertexArray.h | 10 +- .../CollisionShapes/btTriangleMesh.h | 4 +- .../CollisionShapes/btTriangleMeshShape.cpp | 5 +- .../CollisionShapes/btTriangleMeshShape.h | 12 +- .../CollisionShapes/btTriangleShape.h | 4 +- .../CollisionShapes/btUniformScalingShape.cpp | 114 +++ .../CollisionShapes/btUniformScalingShape.h | 86 ++ .../btContinuousConvexCollision.cpp | 24 +- .../btContinuousConvexCollision.h | 6 +- .../NarrowPhaseCollision/btConvexCast.h | 8 +- .../btConvexPenetrationDepthSolver.h | 4 +- .../btDiscreteCollisionDetectorInterface.h | 4 +- .../NarrowPhaseCollision/btGjkConvexCast.cpp | 2 +- .../NarrowPhaseCollision/btGjkConvexCast.h | 10 +- .../NarrowPhaseCollision/btGjkEpa.cpp | 4 +- .../NarrowPhaseCollision/btGjkEpa.h | 6 +- .../btGjkEpaPenetrationDepthSolver.cpp | 2 +- .../btGjkEpaPenetrationDepthSolver.h | 2 +- .../btGjkPairDetector.cpp | 2 +- .../NarrowPhaseCollision/btGjkPairDetector.h | 10 +- .../NarrowPhaseCollision/btManifoldPoint.h | 4 +- .../btMinkowskiPenetrationDepthSolver.cpp | 5 +- .../btMinkowskiPenetrationDepthSolver.h | 2 +- .../btPersistentManifold.cpp | 24 +- .../btPersistentManifold.h | 46 +- .../NarrowPhaseCollision/btRaycastCallback.h | 2 +- .../btSimplexSolverInterface.h | 4 +- .../src/BulletCollision/ibmsdk/Makefile | 95 ++ .../bullet2/src/BulletDynamics/CMakeLists.txt | 3 +- .../btConeTwistConstraint.cpp | 12 +- .../ConstraintSolver/btConeTwistConstraint.h | 3 + .../ConstraintSolver/btConstraintSolver.h | 13 +- .../ConstraintSolver/btContactConstraint.cpp | 20 +- .../ConstraintSolver/btContactConstraint.h | 4 +- .../ConstraintSolver/btContactSolverInfo.h | 26 +- .../btGeneric6DofConstraint.cpp | 790 ++++++++++------- .../btGeneric6DofConstraint.h | 459 ++++++++-- .../ConstraintSolver/btHingeConstraint.cpp | 261 +++++- .../ConstraintSolver/btHingeConstraint.h | 69 +- .../ConstraintSolver/btJacobianEntry.h | 4 +- .../btPoint2PointConstraint.cpp | 5 +- .../btPoint2PointConstraint.h | 14 +- .../btSequentialImpulseConstraintSolver.cpp | 522 ++++++----- .../btSequentialImpulseConstraintSolver.h | 25 +- .../btSolve2LinearConstraint.h | 4 +- .../ConstraintSolver/btSolverBody.h | 25 +- .../ConstraintSolver/btSolverConstraint.h | 20 +- .../ConstraintSolver/btTypedConstraint.cpp | 15 +- .../ConstraintSolver/btTypedConstraint.h | 30 +- .../BulletDynamics/Dynamics/Bullet-C-API.cpp | 402 +++++++++ .../Dynamics/btContinuousDynamicsWorld.cpp | 194 ++++ .../Dynamics/btContinuousDynamicsWorld.h | 46 + .../Dynamics/btDiscreteDynamicsWorld.cpp | 132 ++- .../Dynamics/btDiscreteDynamicsWorld.h | 13 +- .../BulletDynamics/Dynamics/btDynamicsWorld.h | 17 +- .../BulletDynamics/Dynamics/btRigidBody.cpp | 11 +- .../src/BulletDynamics/Dynamics/btRigidBody.h | 58 +- .../Dynamics/btSimpleDynamicsWorld.cpp | 20 +- .../Dynamics/btSimpleDynamicsWorld.h | 16 +- .../Vehicle/btRaycastVehicle.cpp | 27 +- .../BulletDynamics/Vehicle/btRaycastVehicle.h | 6 +- .../Vehicle/btVehicleRaycaster.h | 2 +- .../src/BulletDynamics/Vehicle/btWheelInfo.h | 4 +- .../src/BulletDynamics/ibmsdk/Makefile | 45 + extern/bullet2/src/LinearMath/CMakeLists.txt | 1 + extern/bullet2/src/LinearMath/btAabbUtil2.h | 4 +- .../src/LinearMath/btAlignedAllocator.cpp | 119 ++- .../src/LinearMath/btAlignedAllocator.h | 18 +- .../src/LinearMath/btAlignedObjectArray.h | 25 +- extern/bullet2/src/LinearMath/btIDebugDraw.h | 2 + extern/bullet2/src/LinearMath/btMatrix3x3.h | 2 +- extern/bullet2/src/LinearMath/btMinMax.h | 12 +- .../bullet2/src/LinearMath/btPoolAllocator.h | 94 ++ extern/bullet2/src/LinearMath/btQuadWord.h | 64 +- extern/bullet2/src/LinearMath/btQuaternion.h | 6 +- extern/bullet2/src/LinearMath/btScalar.h | 235 ++++- extern/bullet2/src/LinearMath/btStackAlloc.h | 17 +- extern/bullet2/src/LinearMath/btTransform.h | 8 +- .../bullet2/src/LinearMath/btTransformUtil.h | 8 +- extern/bullet2/src/LinearMath/btVector3.h | 50 ++ extern/bullet2/src/LinearMath/ibmsdk/Makefile | 30 + extern/bullet2/src/SConscript | 70 +- extern/bullet2/src/btBulletCollisionCommon.h | 4 +- extern/bullet2/src/btBulletDynamicsCommon.h | 2 + extern/bullet2/src/ibmsdk/Makefile | 10 + 173 files changed, 7409 insertions(+), 2698 deletions(-) create mode 100644 extern/bullet2/src/BulletCollision/BroadphaseCollision/btMultiSapBroadphase.cpp create mode 100644 extern/bullet2/src/BulletCollision/BroadphaseCollision/btMultiSapBroadphase.h create mode 100644 extern/bullet2/src/BulletCollision/BroadphaseCollision/btOverlappingPairCallback.h create mode 100644 extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionConfiguration.h create mode 100644 extern/bullet2/src/BulletCollision/CollisionDispatch/btDefaultCollisionConfiguration.cpp create mode 100644 extern/bullet2/src/BulletCollision/CollisionDispatch/btDefaultCollisionConfiguration.h create mode 100644 extern/bullet2/src/BulletCollision/CollisionShapes/btConvexInternalShape.cpp create mode 100644 extern/bullet2/src/BulletCollision/CollisionShapes/btConvexInternalShape.h create mode 100644 extern/bullet2/src/BulletCollision/CollisionShapes/btUniformScalingShape.cpp create mode 100644 extern/bullet2/src/BulletCollision/CollisionShapes/btUniformScalingShape.h create mode 100644 extern/bullet2/src/BulletCollision/ibmsdk/Makefile create mode 100644 extern/bullet2/src/BulletDynamics/Dynamics/Bullet-C-API.cpp create mode 100644 extern/bullet2/src/BulletDynamics/Dynamics/btContinuousDynamicsWorld.cpp create mode 100644 extern/bullet2/src/BulletDynamics/Dynamics/btContinuousDynamicsWorld.h create mode 100644 extern/bullet2/src/BulletDynamics/ibmsdk/Makefile create mode 100755 extern/bullet2/src/LinearMath/btPoolAllocator.h create mode 100644 extern/bullet2/src/LinearMath/ibmsdk/Makefile create mode 100644 extern/bullet2/src/ibmsdk/Makefile diff --git a/extern/bullet2/src/Bullet-C-Api.h b/extern/bullet2/src/Bullet-C-Api.h index ccb0c452f3e..45a4f684858 100644 --- a/extern/bullet2/src/Bullet-C-Api.h +++ b/extern/bullet2/src/Bullet-C-Api.h @@ -1,15 +1,173 @@ -#ifndef Bullet_C_API_H -#define Bullet_C_API_H +/* +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. +*/ + +/* + Draft high-level generic physics C-API. For low-level access, use the physics SDK native API's. + Work in progress, functionality will be added on demand. + + If possible, use the richer Bullet C++ API, by including "btBulletDynamicsCommon.h" +*/ + +#ifndef BULLET_C_API_H +#define BULLET_C_API_H + +#define PL_DECLARE_HANDLE(name) typedef struct name##__ { int unused; } *name + +#ifdef BT_USE_DOUBLE_PRECISION +typedef double plReal; +#else +typedef float plReal; +#endif + +typedef plReal plVector3[3]; +typedef plReal plQuaternion[4]; #ifdef __cplusplus -extern "C" { -#endif // __cplusplus +extern "C" { +#endif + +/* Particular physics SDK */ + PL_DECLARE_HANDLE(plPhysicsSdkHandle); + +/* Dynamics world, belonging to some physics SDK */ + PL_DECLARE_HANDLE(plDynamicsWorldHandle); + +/* Rigid Body that can be part of a Dynamics World */ + PL_DECLARE_HANDLE(plRigidBodyHandle); + +/* Collision Shape/Geometry, property of a Rigid Body */ + PL_DECLARE_HANDLE(plCollisionShapeHandle); + +/* Constraint for Rigid Bodies */ + PL_DECLARE_HANDLE(plConstraintHandle); + +/* Triangle Mesh interface */ + PL_DECLARE_HANDLE(plMeshInterfaceHandle); + +/* Broadphase Scene/Proxy Handles */ + PL_DECLARE_HANDLE(plCollisionBroadphaseHandle); + PL_DECLARE_HANDLE(plBroadphaseProxyHandle); + PL_DECLARE_HANDLE(plCollisionWorldHandle); + +/* + Create and Delete a Physics SDK +*/ + + extern plPhysicsSdkHandle plNewBulletSdk(); //this could be also another sdk, like ODE, PhysX etc. + extern void plDeletePhysicsSdk(plPhysicsSdkHandle physicsSdk); + +/* Collision World, not strictly necessary, you can also just create a Dynamics World with Rigid Bodies which internally manages the Collision World with Collision Objects */ + + typedef void(*btBroadphaseCallback)(void* clientData, void* object1,void* object2); + + extern plCollisionBroadphaseHandle plCreateSapBroadphase(btBroadphaseCallback beginCallback,btBroadphaseCallback endCallback); + + extern void plDestroyBroadphase(plCollisionBroadphaseHandle bp); + + extern plBroadphaseProxyHandle plCreateProxy(plCollisionBroadphaseHandle bp, void* clientData, plReal minX,plReal minY,plReal minZ, plReal maxX,plReal maxY, plReal maxZ); + + extern void plDestroyProxy(plCollisionBroadphaseHandle bp, plBroadphaseProxyHandle proxyHandle); + + extern void plSetBoundingBox(plBroadphaseProxyHandle proxyHandle, plReal minX,plReal minY,plReal minZ, plReal maxX,plReal maxY, plReal maxZ); + +/* todo: add pair cache support with queries like add/remove/find pair */ + + extern plCollisionWorldHandle plCreateCollisionWorld(plPhysicsSdkHandle physicsSdk); + +/* todo: add/remove objects */ + + +/* Dynamics World */ + + extern plDynamicsWorldHandle plCreateDynamicsWorld(plPhysicsSdkHandle physicsSdk); + + extern void plDeleteDynamicsWorld(plDynamicsWorldHandle world); + + extern void plStepSimulation(plDynamicsWorldHandle, plReal timeStep); + + extern void plAddRigidBody(plDynamicsWorldHandle world, plRigidBodyHandle object); + + extern void plRemoveRigidBody(plDynamicsWorldHandle world, plRigidBodyHandle object); + + +/* Rigid Body */ + + extern plRigidBodyHandle plCreateRigidBody( void* user_data, float mass, plCollisionShapeHandle cshape ); + + extern void plDeleteRigidBody(plRigidBodyHandle body); + + +/* Collision Shape definition */ + + extern plCollisionShapeHandle plNewSphereShape(plReal radius); + extern plCollisionShapeHandle plNewBoxShape(plReal x, plReal y, plReal z); + extern plCollisionShapeHandle plNewCapsuleShape(plReal radius, plReal height); + extern plCollisionShapeHandle plNewConeShape(plReal radius, plReal height); + extern plCollisionShapeHandle plNewCylinderShape(plReal radius, plReal height); + extern plCollisionShapeHandle plNewCompoundShape(); + extern void plAddChildShape(plCollisionShapeHandle compoundShape,plCollisionShapeHandle childShape, plVector3 childPos,plQuaternion childOrn); + + extern void plDeleteShape(plCollisionShapeHandle shape); + + /* Convex Meshes */ + extern plCollisionShapeHandle plNewConvexHullShape(); + extern void plAddVertex(plCollisionShapeHandle convexHull, plReal x,plReal y,plReal z); +/* Concave static triangle meshes */ + extern plMeshInterfaceHandle plNewMeshInterface(); + extern void plAddTriangle(plMeshInterfaceHandle meshHandle, plVector3 v0,plVector3 v1,plVector3 v2); + extern plCollisionShapeHandle plNewStaticTriangleMeshShape(plMeshInterfaceHandle); + + extern void plSetScaling(plCollisionShapeHandle shape, plVector3 scaling); + +/* SOLID has Response Callback/Table/Management */ +/* PhysX has Triggers, User Callbacks and filtering */ +/* ODE has the typedef void dNearCallback (void *data, dGeomID o1, dGeomID o2); */ + +/* typedef void plUpdatedPositionCallback(void* userData, plRigidBodyHandle rbHandle, plVector3 pos); */ +/* typedef void plUpdatedOrientationCallback(void* userData, plRigidBodyHandle rbHandle, plQuaternion orientation); */ + + /* get world transform */ + extern void plGetOpenGLMatrix(plRigidBodyHandle object, plReal* matrix); + extern void plGetPosition(plRigidBodyHandle object,plVector3 position); + extern void plGetOrientation(plRigidBodyHandle object,plQuaternion orientation); + + /* set world transform (position/orientation) */ + extern void plSetPosition(plRigidBodyHandle object, const plVector3 position); + extern void plSetOrientation(plRigidBodyHandle object, const plQuaternion orientation); + extern void plSetEuler(plReal yaw,plReal pitch,plReal roll, plQuaternion orient); + + typedef struct plRayCastResult { + plRigidBodyHandle m_body; + plCollisionShapeHandle m_shape; + plVector3 m_positionWorld; + plVector3 m_normalWorld; + } plRayCastResult; + + extern int plRayCast(plDynamicsWorldHandle world, const plVector3 rayStart, const plVector3 rayEnd, plRayCastResult res); + + /* Sweep API */ + + /* extern plRigidBodyHandle plObjectCast(plDynamicsWorldHandle world, const plVector3 rayStart, const plVector3 rayEnd, plVector3 hitpoint, plVector3 normal); */ + + /* Continuous Collision Detection API */ double plNearestPoints(float p1[3], float p2[3], float p3[3], float q1[3], float q2[3], float q3[3], float *pa, float *pb, float normal[3]); #ifdef __cplusplus } -#endif // __cplusplus - #endif +#endif //BULLET_C_API_H + diff --git a/extern/bullet2/src/BulletCollision/BroadphaseCollision/btAxisSweep3.cpp b/extern/bullet2/src/BulletCollision/BroadphaseCollision/btAxisSweep3.cpp index be4a11506df..d7eea33ea41 100644 --- a/extern/bullet2/src/BulletCollision/BroadphaseCollision/btAxisSweep3.cpp +++ b/extern/bullet2/src/BulletCollision/BroadphaseCollision/btAxisSweep3.cpp @@ -21,640 +21,18 @@ #include -#ifdef DEBUG_BROADPHASE -#include -void btAxisSweep3::debugPrintAxis(int axis, bool checkCardinality) +btAxisSweep3::btAxisSweep3(const btPoint3& worldAabbMin,const btPoint3& worldAabbMax, unsigned short int maxHandles, btOverlappingPairCache* pairCache) +:btAxisSweep3Internal(worldAabbMin,worldAabbMax,0xfffe,0xffff,maxHandles,pairCache) { - int numEdges = m_pHandles[0].m_maxEdges[axis]; - printf("SAP Axis %d, numEdges=%d\n",axis,numEdges); - - int i; - for (i=0;im_handle); - int handleIndex = pEdge->IsMax()? pHandlePrev->m_maxEdges[axis] : pHandlePrev->m_minEdges[axis]; - char beginOrEnd; - beginOrEnd=pEdge->IsMax()?'E':'B'; - printf(" [%c,h=%d,p=%x,i=%d]\n",beginOrEnd,pEdge->m_handle,pEdge->m_pos,handleIndex); - } - - if (checkCardinality) - assert(numEdges == m_numHandles*2+1); -} -#endif //DEBUG_BROADPHASE - - -btBroadphaseProxy* btAxisSweep3::createProxy( const btVector3& min, const btVector3& max,int shapeType,void* userPtr,short int collisionFilterGroup,short int collisionFilterMask) -{ - (void)shapeType; - BP_FP_INT_TYPE handleId = addHandle(min,max, userPtr,collisionFilterGroup,collisionFilterMask); - - Handle* handle = getHandle(handleId); - - return handle; -} - -void btAxisSweep3::destroyProxy(btBroadphaseProxy* proxy) -{ - Handle* handle = static_cast(proxy); - removeHandle(handle->m_handleId); -} - -void btAxisSweep3::setAabb(btBroadphaseProxy* proxy,const btVector3& aabbMin,const btVector3& aabbMax) -{ - Handle* handle = static_cast(proxy); - updateHandle(handle->m_handleId,aabbMin,aabbMax); - -} - - - - - - -btAxisSweep3::btAxisSweep3(const btPoint3& worldAabbMin,const btPoint3& worldAabbMax, int maxHandles) -:btOverlappingPairCache() -{ - m_invalidPair = 0; - //assert(bounds.HasVolume()); - // 1 handle is reserved as sentinel - btAssert(maxHandles > 1 && maxHandles < BP_MAX_HANDLES); - - // init bounds - m_worldAabbMin = worldAabbMin; - m_worldAabbMax = worldAabbMax; - - btVector3 aabbSize = m_worldAabbMax - m_worldAabbMin; - - BP_FP_INT_TYPE maxInt = BP_HANDLE_SENTINEL; - - m_quantize = btVector3(btScalar(maxInt),btScalar(maxInt),btScalar(maxInt)) / aabbSize; - - // allocate handles buffer and put all handles on free list - m_pHandles = new Handle[maxHandles]; - m_maxHandles = maxHandles; - m_numHandles = 0; - - // handle 0 is reserved as the null index, and is also used as the sentinel - m_firstFreeHandle = 1; - { - for (BP_FP_INT_TYPE i = m_firstFreeHandle; i < maxHandles; i++) - m_pHandles[i].SetNextFree(i + 1); - m_pHandles[maxHandles - 1].SetNextFree(0); - } - - { - // allocate edge buffers - for (int i = 0; i < 3; i++) - m_pEdges[i] = new Edge[maxHandles * 2]; - } - //removed overlap management - - // make boundary sentinels - - m_pHandles[0].m_clientObject = 0; - - for (int axis = 0; axis < 3; axis++) - { - m_pHandles[0].m_minEdges[axis] = 0; - m_pHandles[0].m_maxEdges[axis] = 1; - - m_pEdges[axis][0].m_pos = 0; - m_pEdges[axis][0].m_handle = 0; - m_pEdges[axis][1].m_pos = BP_HANDLE_SENTINEL; - m_pEdges[axis][1].m_handle = 0; -#ifdef DEBUG_BROADPHASE - debugPrintAxis(axis); -#endif //DEBUG_BROADPHASE - - } + btAssert(maxHandles > 1 && maxHandles < 32767); } -btAxisSweep3::~btAxisSweep3() + +bt32BitAxisSweep3::bt32BitAxisSweep3(const btPoint3& worldAabbMin,const btPoint3& worldAabbMax, unsigned int maxHandles , btOverlappingPairCache* pairCache ) +:btAxisSweep3Internal(worldAabbMin,worldAabbMax,0xfffffffe,0x7fffffff,maxHandles,pairCache) { - - for (int i = 2; i >= 0; i--) - delete[] m_pEdges[i]; - delete[] m_pHandles; -} - -void btAxisSweep3::quantize(BP_FP_INT_TYPE* out, const btPoint3& point, int isMax) const -{ - btPoint3 clampedPoint(point); - - - - clampedPoint.setMax(m_worldAabbMin); - clampedPoint.setMin(m_worldAabbMax); - - btVector3 v = (clampedPoint - m_worldAabbMin) * m_quantize; - out[0] = (BP_FP_INT_TYPE)(((BP_FP_INT_TYPE)v.getX() & BP_HANDLE_MASK) | isMax); - out[1] = (BP_FP_INT_TYPE)(((BP_FP_INT_TYPE)v.getY() & BP_HANDLE_MASK) | isMax); - out[2] = (BP_FP_INT_TYPE)(((BP_FP_INT_TYPE)v.getZ() & BP_HANDLE_MASK) | isMax); - -} - - - -BP_FP_INT_TYPE btAxisSweep3::allocHandle() -{ - assert(m_firstFreeHandle); - - BP_FP_INT_TYPE handle = m_firstFreeHandle; - m_firstFreeHandle = getHandle(handle)->GetNextFree(); - m_numHandles++; - - return handle; -} - -void btAxisSweep3::freeHandle(BP_FP_INT_TYPE handle) -{ - assert(handle > 0 && handle < m_maxHandles); - - getHandle(handle)->SetNextFree(m_firstFreeHandle); - m_firstFreeHandle = handle; - - m_numHandles--; -} - - - -BP_FP_INT_TYPE btAxisSweep3::addHandle(const btPoint3& aabbMin,const btPoint3& aabbMax, void* pOwner,short int collisionFilterGroup,short int collisionFilterMask) -{ - // quantize the bounds - BP_FP_INT_TYPE min[3], max[3]; - quantize(min, aabbMin, 0); - quantize(max, aabbMax, 1); - - // allocate a handle - BP_FP_INT_TYPE handle = allocHandle(); - assert(handle!= 0xcdcd); - - Handle* pHandle = getHandle(handle); - - pHandle->m_handleId = handle; - //pHandle->m_pOverlaps = 0; - pHandle->m_clientObject = pOwner; - pHandle->m_collisionFilterGroup = collisionFilterGroup; - pHandle->m_collisionFilterMask = collisionFilterMask; - - // compute current limit of edge arrays - BP_FP_INT_TYPE limit = m_numHandles * 2; - - - // insert new edges just inside the max boundary edge - for (BP_FP_INT_TYPE axis = 0; axis < 3; axis++) - { - - m_pHandles[0].m_maxEdges[axis] += 2; - - m_pEdges[axis][limit + 1] = m_pEdges[axis][limit - 1]; - - m_pEdges[axis][limit - 1].m_pos = min[axis]; - m_pEdges[axis][limit - 1].m_handle = handle; - - m_pEdges[axis][limit].m_pos = max[axis]; - m_pEdges[axis][limit].m_handle = handle; - - pHandle->m_minEdges[axis] = limit - 1; - pHandle->m_maxEdges[axis] = limit; - } - - // now sort the new edges to their correct position - sortMinDown(0, pHandle->m_minEdges[0], false); - sortMaxDown(0, pHandle->m_maxEdges[0], false); - sortMinDown(1, pHandle->m_minEdges[1], false); - sortMaxDown(1, pHandle->m_maxEdges[1], false); - sortMinDown(2, pHandle->m_minEdges[2], true); - sortMaxDown(2, pHandle->m_maxEdges[2], true); - - - return handle; -} - - -void btAxisSweep3::removeHandle(BP_FP_INT_TYPE handle) -{ - - Handle* pHandle = getHandle(handle); - - //explicitly remove the pairs containing the proxy - //we could do it also in the sortMinUp (passing true) - //todo: compare performance - removeOverlappingPairsContainingProxy(pHandle); - - - // compute current limit of edge arrays - int limit = m_numHandles * 2; - - int axis; - - for (axis = 0;axis<3;axis++) - { - m_pHandles[0].m_maxEdges[axis] -= 2; - } - - // remove the edges by sorting them up to the end of the list - for ( axis = 0; axis < 3; axis++) - { - Edge* pEdges = m_pEdges[axis]; - BP_FP_INT_TYPE max = pHandle->m_maxEdges[axis]; - pEdges[max].m_pos = BP_HANDLE_SENTINEL; - - sortMaxUp(axis,max,false); - - - BP_FP_INT_TYPE i = pHandle->m_minEdges[axis]; - pEdges[i].m_pos = BP_HANDLE_SENTINEL; - - - sortMinUp(axis,i,false); - - pEdges[limit-1].m_handle = 0; - pEdges[limit-1].m_pos = BP_HANDLE_SENTINEL; - -#ifdef DEBUG_BROADPHASE - debugPrintAxis(axis,false); -#endif //DEBUG_BROADPHASE - - - } - - - // free the handle - freeHandle(handle); - - -} - -extern int gOverlappingPairs; - - -void btAxisSweep3::refreshOverlappingPairs() -{ - -} -void btAxisSweep3::processAllOverlappingPairs(btOverlapCallback* callback) -{ - - //perform a sort, to find duplicates and to sort 'invalid' pairs to the end - m_overlappingPairArray.heapSort(btBroadphasePairSortPredicate()); - - //remove the 'invalid' ones -#ifdef USE_POPBACK_REMOVAL - while (m_invalidPair>0) - { - m_invalidPair--; - m_overlappingPairArray.pop_back(); - } -#else - m_overlappingPairArray.resize(m_overlappingPairArray.size() - m_invalidPair); - m_invalidPair = 0; -#endif - - - int i; - - btBroadphasePair previousPair; - previousPair.m_pProxy0 = 0; - previousPair.m_pProxy1 = 0; - previousPair.m_algorithm = 0; - - - for (i=0;iprocessOverlap(pair); - } else - { - needsRemoval = true; - } - } else - { - //remove duplicate - needsRemoval = true; - //should have no algorithm - btAssert(!pair.m_algorithm); - } - - if (needsRemoval) - { - cleanOverlappingPair(pair); - - // m_overlappingPairArray.swap(i,m_overlappingPairArray.size()-1); - // m_overlappingPairArray.pop_back(); - pair.m_pProxy0 = 0; - pair.m_pProxy1 = 0; - m_invalidPair++; - gOverlappingPairs--; - } - - } -} - - -bool btAxisSweep3::testOverlap(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1) -{ - const Handle* pHandleA = static_cast(proxy0); - const Handle* pHandleB = static_cast(proxy1); - - //optimization 1: check the array index (memory address), instead of the m_pos - - for (int axis = 0; axis < 3; axis++) - { - if (pHandleA->m_maxEdges[axis] < pHandleB->m_minEdges[axis] || - pHandleB->m_maxEdges[axis] < pHandleA->m_minEdges[axis]) - { - return false; - } - } - return true; -} - -bool btAxisSweep3::testOverlap(int ignoreAxis,const Handle* pHandleA, const Handle* pHandleB) -{ - //optimization 1: check the array index (memory address), instead of the m_pos - - for (int axis = 0; axis < 3; axis++) - { - if (axis != ignoreAxis) - { - if (pHandleA->m_maxEdges[axis] < pHandleB->m_minEdges[axis] || - pHandleB->m_maxEdges[axis] < pHandleA->m_minEdges[axis]) - { - return false; - } - } - } - - //optimization 2: only 2 axis need to be tested (conflicts with 'delayed removal' optimization) - - /*for (int axis = 0; axis < 3; axis++) - { - if (m_pEdges[axis][pHandleA->m_maxEdges[axis]].m_pos < m_pEdges[axis][pHandleB->m_minEdges[axis]].m_pos || - m_pEdges[axis][pHandleB->m_maxEdges[axis]].m_pos < m_pEdges[axis][pHandleA->m_minEdges[axis]].m_pos) - { - return false; - } - } - */ - - return true; -} - -void btAxisSweep3::updateHandle(BP_FP_INT_TYPE handle, const btPoint3& aabbMin,const btPoint3& aabbMax) -{ -// assert(bounds.IsFinite()); - //assert(bounds.HasVolume()); - - Handle* pHandle = getHandle(handle); - - // quantize the new bounds - BP_FP_INT_TYPE min[3], max[3]; - quantize(min, aabbMin, 0); - quantize(max, aabbMax, 1); - - // update changed edges - for (int axis = 0; axis < 3; axis++) - { - BP_FP_INT_TYPE emin = pHandle->m_minEdges[axis]; - BP_FP_INT_TYPE emax = pHandle->m_maxEdges[axis]; - - int dmin = (int)min[axis] - (int)m_pEdges[axis][emin].m_pos; - int dmax = (int)max[axis] - (int)m_pEdges[axis][emax].m_pos; - - m_pEdges[axis][emin].m_pos = min[axis]; - m_pEdges[axis][emax].m_pos = max[axis]; - - // expand (only adds overlaps) - if (dmin < 0) - sortMinDown(axis, emin); - - if (dmax > 0) - sortMaxUp(axis, emax); - - // shrink (only removes overlaps) - if (dmin > 0) - sortMinUp(axis, emin); - - if (dmax < 0) - sortMaxDown(axis, emax); - -#ifdef DEBUG_BROADPHASE - debugPrintAxis(axis); -#endif //DEBUG_BROADPHASE - } - - -} - - - - -// sorting a min edge downwards can only ever *add* overlaps -void btAxisSweep3::sortMinDown(int axis, BP_FP_INT_TYPE edge, bool updateOverlaps) -{ - - Edge* pEdge = m_pEdges[axis] + edge; - Edge* pPrev = pEdge - 1; - Handle* pHandleEdge = getHandle(pEdge->m_handle); - - while (pEdge->m_pos < pPrev->m_pos) - { - Handle* pHandlePrev = getHandle(pPrev->m_handle); - - if (pPrev->IsMax()) - { - // if previous edge is a maximum check the bounds and add an overlap if necessary - if (updateOverlaps && testOverlap(axis,pHandleEdge, pHandlePrev)) - { - addOverlappingPair(pHandleEdge,pHandlePrev); - - //AddOverlap(pEdge->m_handle, pPrev->m_handle); - - } - - // update edge reference in other handle - pHandlePrev->m_maxEdges[axis]++; - } - else - pHandlePrev->m_minEdges[axis]++; - - pHandleEdge->m_minEdges[axis]--; - - // swap the edges - Edge swap = *pEdge; - *pEdge = *pPrev; - *pPrev = swap; - - // decrement - pEdge--; - pPrev--; - } - -#ifdef DEBUG_BROADPHASE - debugPrintAxis(axis); -#endif //DEBUG_BROADPHASE - -} - -// sorting a min edge upwards can only ever *remove* overlaps -void btAxisSweep3::sortMinUp(int axis, BP_FP_INT_TYPE edge, bool updateOverlaps) -{ - Edge* pEdge = m_pEdges[axis] + edge; - Edge* pNext = pEdge + 1; - Handle* pHandleEdge = getHandle(pEdge->m_handle); - - while (pNext->m_handle && (pEdge->m_pos >= pNext->m_pos)) - { - Handle* pHandleNext = getHandle(pNext->m_handle); - - if (pNext->IsMax()) - { - // if next edge is maximum remove any overlap between the two handles - if (updateOverlaps) - { - /* - Handle* handle0 = getHandle(pEdge->m_handle); - Handle* handle1 = getHandle(pNext->m_handle); - btBroadphasePair tmpPair(*handle0,*handle1); - removeOverlappingPair(tmpPair); - */ - - } - - // update edge reference in other handle - pHandleNext->m_maxEdges[axis]--; - } - else - pHandleNext->m_minEdges[axis]--; - - pHandleEdge->m_minEdges[axis]++; - - // swap the edges - Edge swap = *pEdge; - *pEdge = *pNext; - *pNext = swap; - - // increment - pEdge++; - pNext++; - } - - -} - -// sorting a max edge downwards can only ever *remove* overlaps -void btAxisSweep3::sortMaxDown(int axis, BP_FP_INT_TYPE edge, bool updateOverlaps) -{ - - Edge* pEdge = m_pEdges[axis] + edge; - Edge* pPrev = pEdge - 1; - Handle* pHandleEdge = getHandle(pEdge->m_handle); - - while (pEdge->m_pos < pPrev->m_pos) - { - Handle* pHandlePrev = getHandle(pPrev->m_handle); - - if (!pPrev->IsMax()) - { - // if previous edge was a minimum remove any overlap between the two handles - if (updateOverlaps) - { - //this is done during the overlappingpairarray iteration/narrowphase collision - /* - Handle* handle0 = getHandle(pEdge->m_handle); - Handle* handle1 = getHandle(pPrev->m_handle); - btBroadphasePair* pair = findPair(handle0,handle1); - //assert(pair); - - if (pair) - { - removeOverlappingPair(*pair); - } - */ - - } - - // update edge reference in other handle - pHandlePrev->m_minEdges[axis]++;; - } - else - pHandlePrev->m_maxEdges[axis]++; - - pHandleEdge->m_maxEdges[axis]--; - - // swap the edges - Edge swap = *pEdge; - *pEdge = *pPrev; - *pPrev = swap; - - // decrement - pEdge--; - pPrev--; - } - - -#ifdef DEBUG_BROADPHASE - debugPrintAxis(axis); -#endif //DEBUG_BROADPHASE - -} - -// sorting a max edge upwards can only ever *add* overlaps -void btAxisSweep3::sortMaxUp(int axis, BP_FP_INT_TYPE edge, bool updateOverlaps) -{ - Edge* pEdge = m_pEdges[axis] + edge; - Edge* pNext = pEdge + 1; - Handle* pHandleEdge = getHandle(pEdge->m_handle); - - while (pNext->m_handle && (pEdge->m_pos >= pNext->m_pos)) - { - Handle* pHandleNext = getHandle(pNext->m_handle); - - if (!pNext->IsMax()) - { - // if next edge is a minimum check the bounds and add an overlap if necessary - if (updateOverlaps && testOverlap(axis, pHandleEdge, pHandleNext)) - { - Handle* handle0 = getHandle(pEdge->m_handle); - Handle* handle1 = getHandle(pNext->m_handle); - addOverlappingPair(handle0,handle1); - } - - // update edge reference in other handle - pHandleNext->m_minEdges[axis]--; - } - else - pHandleNext->m_maxEdges[axis]--; - - pHandleEdge->m_maxEdges[axis]++; - - // swap the edges - Edge swap = *pEdge; - *pEdge = *pNext; - *pNext = swap; - - // increment - pEdge++; - pNext++; - } - + // 1 handle is reserved as sentinel + btAssert(maxHandles > 1 && maxHandles < 2147483647); } diff --git a/extern/bullet2/src/BulletCollision/BroadphaseCollision/btAxisSweep3.h b/extern/bullet2/src/BulletCollision/BroadphaseCollision/btAxisSweep3.h index 57bbb368672..d36df6e6621 100644 --- a/extern/bullet2/src/BulletCollision/BroadphaseCollision/btAxisSweep3.h +++ b/extern/bullet2/src/BulletCollision/BroadphaseCollision/btAxisSweep3.h @@ -19,34 +19,24 @@ #ifndef AXIS_SWEEP_3_H #define AXIS_SWEEP_3_H -#include "../../LinearMath/btPoint3.h" -#include "../../LinearMath/btVector3.h" +#include "LinearMath/btPoint3.h" +#include "LinearMath/btVector3.h" #include "btOverlappingPairCache.h" +#include "btBroadphaseInterface.h" #include "btBroadphaseProxy.h" - - -//Enable BP_USE_FIXEDPOINT_INT_32 if you need more then 32767 objects -//#define BP_USE_FIXEDPOINT_INT_32 1 - -#ifdef BP_USE_FIXEDPOINT_INT_32 - #define BP_FP_INT_TYPE unsigned int - #define BP_MAX_HANDLES 1500000 //arbitrary maximum number of handles - #define BP_HANDLE_SENTINEL 0x7fffffff - #define BP_HANDLE_MASK 0xfffffffe -#else - #define BP_FP_INT_TYPE unsigned short int - #define BP_MAX_HANDLES 32767 - #define BP_HANDLE_SENTINEL 0xffff - #define BP_HANDLE_MASK 0xfffe -#endif //BP_USE_FIXEDPOINT_INT_32 +#include "btOverlappingPairCallback.h" //#define DEBUG_BROADPHASE 1 -/// btAxisSweep3 is an efficient implementation of the 3d axis sweep and prune broadphase. -/// It uses arrays rather then lists for storage of the 3 axis. Also it operates using integer coordinates instead of floats. -/// The testOverlap check is optimized to check the array index, rather then the actual AABB coordinates/pos -class btAxisSweep3 : public btOverlappingPairCache +/// btAxisSweep3Internal is an internal template class that implements sweep and prune. +/// Dont use this class directly, use btAxisSweep3 or bt32BitAxisSweep3 instead. +template +class btAxisSweep3Internal : public btBroadphaseInterface { +protected: + + BP_FP_INT_TYPE m_bpHandleMask; + BP_FP_INT_TYPE m_handleSentinel; public: @@ -61,36 +51,44 @@ public: }; public: - class Handle : public btBroadphaseProxy + ATTRIBUTE_ALIGNED16(class) Handle : public btBroadphaseProxy { public: - + BT_DECLARE_ALIGNED_ALLOCATOR(); + // indexes into the edge arrays BP_FP_INT_TYPE m_minEdges[3], m_maxEdges[3]; // 6 * 2 = 12 - BP_FP_INT_TYPE m_handleId; +// BP_FP_INT_TYPE m_uniqueId; BP_FP_INT_TYPE m_pad; //void* m_pOwner; this is now in btBroadphaseProxy.m_clientObject - inline void SetNextFree(BP_FP_INT_TYPE next) {m_minEdges[0] = next;} - inline BP_FP_INT_TYPE GetNextFree() const {return m_minEdges[0];} + SIMD_FORCE_INLINE void SetNextFree(BP_FP_INT_TYPE next) {m_minEdges[0] = next;} + SIMD_FORCE_INLINE BP_FP_INT_TYPE GetNextFree() const {return m_minEdges[0];} }; // 24 bytes + 24 for Edge structures = 44 bytes total per entry -private: +protected: btPoint3 m_worldAabbMin; // overall system bounds btPoint3 m_worldAabbMax; // overall system bounds btVector3 m_quantize; // scaling factor for quantization BP_FP_INT_TYPE m_numHandles; // number of active handles - int m_maxHandles; // max number of handles + BP_FP_INT_TYPE m_maxHandles; // max number of handles Handle* m_pHandles; // handles pool BP_FP_INT_TYPE m_firstFreeHandle; // free handles list Edge* m_pEdges[3]; // edge arrays for the 3 axes (each array has m_maxHandles * 2 + 2 sentinel entries) - int m_invalidPair; + btOverlappingPairCache* m_pairCache; + + ///btOverlappingPairCallback is an additional optional user callback for adding/removing overlapping pairs, similar interface to btOverlappingPairCache. + btOverlappingPairCallback* m_userPairCallback; + + bool m_ownsPairCache; + + int m_invalidPair; // allocation/deallocation BP_FP_INT_TYPE allocHandle(); @@ -108,29 +106,773 @@ private: void quantize(BP_FP_INT_TYPE* out, const btPoint3& point, int isMax) const; - void sortMinDown(int axis, BP_FP_INT_TYPE edge, bool updateOverlaps = true); - void sortMinUp(int axis, BP_FP_INT_TYPE edge, bool updateOverlaps = true); - void sortMaxDown(int axis, BP_FP_INT_TYPE edge, bool updateOverlaps = true); - void sortMaxUp(int axis, BP_FP_INT_TYPE edge, bool updateOverlaps = true); + void sortMinDown(int axis, BP_FP_INT_TYPE edge, btDispatcher* dispatcher, bool updateOverlaps ); + void sortMinUp(int axis, BP_FP_INT_TYPE edge, btDispatcher* dispatcher, bool updateOverlaps ); + void sortMaxDown(int axis, BP_FP_INT_TYPE edge, btDispatcher* dispatcher, bool updateOverlaps ); + void sortMaxUp(int axis, BP_FP_INT_TYPE edge, btDispatcher* dispatcher, bool updateOverlaps ); public: - btAxisSweep3(const btPoint3& worldAabbMin,const btPoint3& worldAabbMax, int maxHandles = 16384); - virtual ~btAxisSweep3(); - virtual void refreshOverlappingPairs(); + btAxisSweep3Internal(const btPoint3& worldAabbMin,const btPoint3& worldAabbMax, BP_FP_INT_TYPE handleMask, BP_FP_INT_TYPE handleSentinel, BP_FP_INT_TYPE maxHandles = 16384, btOverlappingPairCache* pairCache=0); + + virtual ~btAxisSweep3Internal(); + + + virtual void calculateOverlappingPairs(btDispatcher* dispatcher); - BP_FP_INT_TYPE addHandle(const btPoint3& aabbMin,const btPoint3& aabbMax, void* pOwner,short int collisionFilterGroup,short int collisionFilterMask); - void removeHandle(BP_FP_INT_TYPE handle); - void updateHandle(BP_FP_INT_TYPE handle, const btPoint3& aabbMin,const btPoint3& aabbMax); - inline Handle* getHandle(BP_FP_INT_TYPE index) const {return m_pHandles + index;} + BP_FP_INT_TYPE addHandle(const btPoint3& aabbMin,const btPoint3& aabbMax, void* pOwner,short int collisionFilterGroup,short int collisionFilterMask,btDispatcher* dispatcher); + void removeHandle(BP_FP_INT_TYPE handle,btDispatcher* dispatcher); + void updateHandle(BP_FP_INT_TYPE handle, const btPoint3& aabbMin,const btPoint3& aabbMax,btDispatcher* dispatcher); + SIMD_FORCE_INLINE Handle* getHandle(BP_FP_INT_TYPE index) const {return m_pHandles + index;} void processAllOverlappingPairs(btOverlapCallback* callback); //Broadphase Interface - virtual btBroadphaseProxy* createProxy( const btVector3& min, const btVector3& max,int shapeType,void* userPtr ,short int collisionFilterGroup,short int collisionFilterMask); - virtual void destroyProxy(btBroadphaseProxy* proxy); - virtual void setAabb(btBroadphaseProxy* proxy,const btVector3& aabbMin,const btVector3& aabbMax); - bool testOverlap(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1); + virtual btBroadphaseProxy* createProxy( const btVector3& aabbMin, const btVector3& aabbMax,int shapeType,void* userPtr ,short int collisionFilterGroup,short int collisionFilterMask,btDispatcher* dispatcher); + virtual void destroyProxy(btBroadphaseProxy* proxy,btDispatcher* dispatcher); + virtual void setAabb(btBroadphaseProxy* proxy,const btVector3& aabbMin,const btVector3& aabbMax,btDispatcher* dispatcher); + + bool testAabbOverlap(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1); + + btOverlappingPairCache* getOverlappingPairCache() + { + return m_pairCache; + } + const btOverlappingPairCache* getOverlappingPairCache() const + { + return m_pairCache; + } + + void setOverlappingPairUserCallback(btOverlappingPairCallback* pairCallback) + { + m_userPairCallback = pairCallback; + } + const btOverlappingPairCallback* getOverlappingPairUserCallback() const + { + return m_userPairCallback; + } +}; + +//////////////////////////////////////////////////////////////////// + + + + +#ifdef DEBUG_BROADPHASE +#include + +template +void btAxisSweep3::debugPrintAxis(int axis, bool checkCardinality) +{ + int numEdges = m_pHandles[0].m_maxEdges[axis]; + printf("SAP Axis %d, numEdges=%d\n",axis,numEdges); + + int i; + for (i=0;im_handle); + int handleIndex = pEdge->IsMax()? pHandlePrev->m_maxEdges[axis] : pHandlePrev->m_minEdges[axis]; + char beginOrEnd; + beginOrEnd=pEdge->IsMax()?'E':'B'; + printf(" [%c,h=%d,p=%x,i=%d]\n",beginOrEnd,pEdge->m_handle,pEdge->m_pos,handleIndex); + } + + if (checkCardinality) + assert(numEdges == m_numHandles*2+1); +} +#endif //DEBUG_BROADPHASE + +template +btBroadphaseProxy* btAxisSweep3Internal::createProxy( const btVector3& aabbMin, const btVector3& aabbMax,int shapeType,void* userPtr,short int collisionFilterGroup,short int collisionFilterMask,btDispatcher* dispatcher) +{ + (void)shapeType; + BP_FP_INT_TYPE handleId = addHandle(aabbMin,aabbMax, userPtr,collisionFilterGroup,collisionFilterMask,dispatcher); + + Handle* handle = getHandle(handleId); + + return handle; +} + + + +template +void btAxisSweep3Internal::destroyProxy(btBroadphaseProxy* proxy,btDispatcher* dispatcher) +{ + Handle* handle = static_cast(proxy); + removeHandle(handle->m_uniqueId,dispatcher); +} + +template +void btAxisSweep3Internal::setAabb(btBroadphaseProxy* proxy,const btVector3& aabbMin,const btVector3& aabbMax,btDispatcher* dispatcher) +{ + Handle* handle = static_cast(proxy); + updateHandle(handle->m_uniqueId,aabbMin,aabbMax,dispatcher); + +} + + + + + +template +btAxisSweep3Internal::btAxisSweep3Internal(const btPoint3& worldAabbMin,const btPoint3& worldAabbMax, BP_FP_INT_TYPE handleMask, BP_FP_INT_TYPE handleSentinel,BP_FP_INT_TYPE maxHandles, btOverlappingPairCache* pairCache ) +:m_bpHandleMask(handleMask), +m_handleSentinel(handleSentinel), +m_pairCache(pairCache), +m_userPairCallback(0), +m_ownsPairCache(false), +m_invalidPair(0) +{ + if (!m_pairCache) + { + void* ptr = btAlignedAlloc(sizeof(btOverlappingPairCache),16); + m_pairCache = new(ptr) btOverlappingPairCache(); + m_ownsPairCache = true; + } + + //assert(bounds.HasVolume()); + + // init bounds + m_worldAabbMin = worldAabbMin; + m_worldAabbMax = worldAabbMax; + + btVector3 aabbSize = m_worldAabbMax - m_worldAabbMin; + + BP_FP_INT_TYPE maxInt = m_handleSentinel; + + m_quantize = btVector3(btScalar(maxInt),btScalar(maxInt),btScalar(maxInt)) / aabbSize; + + // allocate handles buffer and put all handles on free list + void* ptr = btAlignedAlloc(sizeof(Handle)*maxHandles,16); + m_pHandles = new(ptr) Handle[maxHandles]; + m_maxHandles = maxHandles; + m_numHandles = 0; + + // handle 0 is reserved as the null index, and is also used as the sentinel + m_firstFreeHandle = 1; + { + for (BP_FP_INT_TYPE i = m_firstFreeHandle; i < maxHandles; i++) + m_pHandles[i].SetNextFree(i + 1); + m_pHandles[maxHandles - 1].SetNextFree(0); + } + + { + // allocate edge buffers + for (int i = 0; i < 3; i++) + { + void* ptr = btAlignedAlloc(sizeof(Edge)*maxHandles*2,16); + m_pEdges[i] = new(ptr) Edge[maxHandles * 2]; + } + } + //removed overlap management + + // make boundary sentinels + + m_pHandles[0].m_clientObject = 0; + + for (int axis = 0; axis < 3; axis++) + { + m_pHandles[0].m_minEdges[axis] = 0; + m_pHandles[0].m_maxEdges[axis] = 1; + + m_pEdges[axis][0].m_pos = 0; + m_pEdges[axis][0].m_handle = 0; + m_pEdges[axis][1].m_pos = m_handleSentinel; + m_pEdges[axis][1].m_handle = 0; +#ifdef DEBUG_BROADPHASE + debugPrintAxis(axis); +#endif //DEBUG_BROADPHASE + + } + +} + +template +btAxisSweep3Internal::~btAxisSweep3Internal() +{ + + for (int i = 2; i >= 0; i--) + { + btAlignedFree(m_pEdges[i]); + } + btAlignedFree(m_pHandles); + + if (m_ownsPairCache) + { + m_pairCache->~btOverlappingPairCache(); + btAlignedFree(m_pairCache); + } +} + +template +void btAxisSweep3Internal::quantize(BP_FP_INT_TYPE* out, const btPoint3& point, int isMax) const +{ + btPoint3 clampedPoint(point); + + + + clampedPoint.setMax(m_worldAabbMin); + clampedPoint.setMin(m_worldAabbMax); + + btVector3 v = (clampedPoint - m_worldAabbMin) * m_quantize; + out[0] = (BP_FP_INT_TYPE)(((BP_FP_INT_TYPE)v.getX() & m_bpHandleMask) | isMax); + out[1] = (BP_FP_INT_TYPE)(((BP_FP_INT_TYPE)v.getY() & m_bpHandleMask) | isMax); + out[2] = (BP_FP_INT_TYPE)(((BP_FP_INT_TYPE)v.getZ() & m_bpHandleMask) | isMax); + +} + + +template +BP_FP_INT_TYPE btAxisSweep3Internal::allocHandle() +{ + assert(m_firstFreeHandle); + + BP_FP_INT_TYPE handle = m_firstFreeHandle; + m_firstFreeHandle = getHandle(handle)->GetNextFree(); + m_numHandles++; + + return handle; +} + +template +void btAxisSweep3Internal::freeHandle(BP_FP_INT_TYPE handle) +{ + assert(handle > 0 && handle < m_maxHandles); + + getHandle(handle)->SetNextFree(m_firstFreeHandle); + m_firstFreeHandle = handle; + + m_numHandles--; +} + + +template +BP_FP_INT_TYPE btAxisSweep3Internal::addHandle(const btPoint3& aabbMin,const btPoint3& aabbMax, void* pOwner,short int collisionFilterGroup,short int collisionFilterMask,btDispatcher* dispatcher) +{ + // quantize the bounds + BP_FP_INT_TYPE min[3], max[3]; + quantize(min, aabbMin, 0); + quantize(max, aabbMax, 1); + + // allocate a handle + BP_FP_INT_TYPE handle = allocHandle(); + + + Handle* pHandle = getHandle(handle); + + pHandle->m_uniqueId = handle; + //pHandle->m_pOverlaps = 0; + pHandle->m_clientObject = pOwner; + pHandle->m_collisionFilterGroup = collisionFilterGroup; + pHandle->m_collisionFilterMask = collisionFilterMask; + + // compute current limit of edge arrays + BP_FP_INT_TYPE limit = m_numHandles * 2; + + + // insert new edges just inside the max boundary edge + for (BP_FP_INT_TYPE axis = 0; axis < 3; axis++) + { + + m_pHandles[0].m_maxEdges[axis] += 2; + + m_pEdges[axis][limit + 1] = m_pEdges[axis][limit - 1]; + + m_pEdges[axis][limit - 1].m_pos = min[axis]; + m_pEdges[axis][limit - 1].m_handle = handle; + + m_pEdges[axis][limit].m_pos = max[axis]; + m_pEdges[axis][limit].m_handle = handle; + + pHandle->m_minEdges[axis] = limit - 1; + pHandle->m_maxEdges[axis] = limit; + } + + // now sort the new edges to their correct position + sortMinDown(0, pHandle->m_minEdges[0], dispatcher,false); + sortMaxDown(0, pHandle->m_maxEdges[0], dispatcher,false); + sortMinDown(1, pHandle->m_minEdges[1], dispatcher,false); + sortMaxDown(1, pHandle->m_maxEdges[1], dispatcher,false); + sortMinDown(2, pHandle->m_minEdges[2], dispatcher,true); + sortMaxDown(2, pHandle->m_maxEdges[2], dispatcher,true); + + + return handle; +} + + +template +void btAxisSweep3Internal::removeHandle(BP_FP_INT_TYPE handle,btDispatcher* dispatcher) +{ + + Handle* pHandle = getHandle(handle); + + //explicitly remove the pairs containing the proxy + //we could do it also in the sortMinUp (passing true) + //todo: compare performance + m_pairCache->removeOverlappingPairsContainingProxy(pHandle,dispatcher); + + + // compute current limit of edge arrays + int limit = m_numHandles * 2; + + int axis; + + for (axis = 0;axis<3;axis++) + { + m_pHandles[0].m_maxEdges[axis] -= 2; + } + + // remove the edges by sorting them up to the end of the list + for ( axis = 0; axis < 3; axis++) + { + Edge* pEdges = m_pEdges[axis]; + BP_FP_INT_TYPE max = pHandle->m_maxEdges[axis]; + pEdges[max].m_pos = m_handleSentinel; + + sortMaxUp(axis,max,dispatcher,false); + + + BP_FP_INT_TYPE i = pHandle->m_minEdges[axis]; + pEdges[i].m_pos = m_handleSentinel; + + + sortMinUp(axis,i,dispatcher,false); + + pEdges[limit-1].m_handle = 0; + pEdges[limit-1].m_pos = m_handleSentinel; + +#ifdef DEBUG_BROADPHASE + debugPrintAxis(axis,false); +#endif //DEBUG_BROADPHASE + + + } + + + // free the handle + freeHandle(handle); + + +} + +extern int gOverlappingPairs; +#include + +template +void btAxisSweep3Internal::calculateOverlappingPairs(btDispatcher* dispatcher) +{ +#ifdef USE_LAZY_REMOVAL + + if (m_ownsPairCache) + { + + btBroadphasePairArray& overlappingPairArray = m_pairCache->getOverlappingPairArray(); + + //perform a sort, to find duplicates and to sort 'invalid' pairs to the end + overlappingPairArray.heapSort(btBroadphasePairSortPredicate()); + + overlappingPairArray.resize(overlappingPairArray.size() - m_invalidPair); + m_invalidPair = 0; + + + int i; + + btBroadphasePair previousPair; + previousPair.m_pProxy0 = 0; + previousPair.m_pProxy1 = 0; + previousPair.m_algorithm = 0; + + + for (i=0;iprocessOverlap(pair); + } else + { + needsRemoval = true; + } + } else + { + //remove duplicate + needsRemoval = true; + //should have no algorithm + btAssert(!pair.m_algorithm); + } + + if (needsRemoval) + { + m_pairCache->cleanOverlappingPair(pair,dispatcher); + + // m_overlappingPairArray.swap(i,m_overlappingPairArray.size()-1); + // m_overlappingPairArray.pop_back(); + pair.m_pProxy0 = 0; + pair.m_pProxy1 = 0; + m_invalidPair++; + gOverlappingPairs--; + } + + } + + ///if you don't like to skip the invalid pairs in the array, execute following code: + #define CLEAN_INVALID_PAIRS 1 + #ifdef CLEAN_INVALID_PAIRS + + //perform a sort, to sort 'invalid' pairs to the end + overlappingPairArray.heapSort(btBroadphasePairSortPredicate()); + + overlappingPairArray.resize(overlappingPairArray.size() - m_invalidPair); + m_invalidPair = 0; + #endif//CLEAN_INVALID_PAIRS + + //printf("overlappingPairArray.size()=%d\n",overlappingPairArray.size()); + } +#endif //USE_LAZY_REMOVAL + + + + +} + + +template +bool btAxisSweep3Internal::testAabbOverlap(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1) +{ + const Handle* pHandleA = static_cast(proxy0); + const Handle* pHandleB = static_cast(proxy1); + + //optimization 1: check the array index (memory address), instead of the m_pos + + for (int axis = 0; axis < 3; axis++) + { + if (pHandleA->m_maxEdges[axis] < pHandleB->m_minEdges[axis] || + pHandleB->m_maxEdges[axis] < pHandleA->m_minEdges[axis]) + { + return false; + } + } + return true; +} + +template +bool btAxisSweep3Internal::testOverlap(int ignoreAxis,const Handle* pHandleA, const Handle* pHandleB) +{ + //optimization 1: check the array index (memory address), instead of the m_pos + + for (int axis = 0; axis < 3; axis++) + { + if (axis != ignoreAxis) + { + if (pHandleA->m_maxEdges[axis] < pHandleB->m_minEdges[axis] || + pHandleB->m_maxEdges[axis] < pHandleA->m_minEdges[axis]) + { + return false; + } + } + } + + //optimization 2: only 2 axis need to be tested (conflicts with 'delayed removal' optimization) + + /*for (int axis = 0; axis < 3; axis++) + { + if (m_pEdges[axis][pHandleA->m_maxEdges[axis]].m_pos < m_pEdges[axis][pHandleB->m_minEdges[axis]].m_pos || + m_pEdges[axis][pHandleB->m_maxEdges[axis]].m_pos < m_pEdges[axis][pHandleA->m_minEdges[axis]].m_pos) + { + return false; + } + } + */ + + return true; +} + +template +void btAxisSweep3Internal::updateHandle(BP_FP_INT_TYPE handle, const btPoint3& aabbMin,const btPoint3& aabbMax,btDispatcher* dispatcher) +{ +// assert(bounds.IsFinite()); + //assert(bounds.HasVolume()); + + Handle* pHandle = getHandle(handle); + + // quantize the new bounds + BP_FP_INT_TYPE min[3], max[3]; + quantize(min, aabbMin, 0); + quantize(max, aabbMax, 1); + + // update changed edges + for (int axis = 0; axis < 3; axis++) + { + BP_FP_INT_TYPE emin = pHandle->m_minEdges[axis]; + BP_FP_INT_TYPE emax = pHandle->m_maxEdges[axis]; + + int dmin = (int)min[axis] - (int)m_pEdges[axis][emin].m_pos; + int dmax = (int)max[axis] - (int)m_pEdges[axis][emax].m_pos; + + m_pEdges[axis][emin].m_pos = min[axis]; + m_pEdges[axis][emax].m_pos = max[axis]; + + // expand (only adds overlaps) + if (dmin < 0) + sortMinDown(axis, emin,dispatcher,true); + + if (dmax > 0) + sortMaxUp(axis, emax,dispatcher,true); + + // shrink (only removes overlaps) + if (dmin > 0) + sortMinUp(axis, emin,dispatcher,true); + + if (dmax < 0) + sortMaxDown(axis, emax,dispatcher,true); + +#ifdef DEBUG_BROADPHASE + debugPrintAxis(axis); +#endif //DEBUG_BROADPHASE + } + + +} + + + + +// sorting a min edge downwards can only ever *add* overlaps +template +void btAxisSweep3Internal::sortMinDown(int axis, BP_FP_INT_TYPE edge, btDispatcher* dispatcher, bool updateOverlaps) +{ + + Edge* pEdge = m_pEdges[axis] + edge; + Edge* pPrev = pEdge - 1; + Handle* pHandleEdge = getHandle(pEdge->m_handle); + + while (pEdge->m_pos < pPrev->m_pos) + { + Handle* pHandlePrev = getHandle(pPrev->m_handle); + + if (pPrev->IsMax()) + { + // if previous edge is a maximum check the bounds and add an overlap if necessary + if (updateOverlaps && testOverlap(axis,pHandleEdge, pHandlePrev)) + { + m_pairCache->addOverlappingPair(pHandleEdge,pHandlePrev); + if (m_userPairCallback) + m_userPairCallback->addOverlappingPair(pHandleEdge,pHandlePrev); + + //AddOverlap(pEdge->m_handle, pPrev->m_handle); + + } + + // update edge reference in other handle + pHandlePrev->m_maxEdges[axis]++; + } + else + pHandlePrev->m_minEdges[axis]++; + + pHandleEdge->m_minEdges[axis]--; + + // swap the edges + Edge swap = *pEdge; + *pEdge = *pPrev; + *pPrev = swap; + + // decrement + pEdge--; + pPrev--; + } + +#ifdef DEBUG_BROADPHASE + debugPrintAxis(axis); +#endif //DEBUG_BROADPHASE + +} + +// sorting a min edge upwards can only ever *remove* overlaps +template +void btAxisSweep3Internal::sortMinUp(int axis, BP_FP_INT_TYPE edge, btDispatcher* dispatcher, bool updateOverlaps) +{ + Edge* pEdge = m_pEdges[axis] + edge; + Edge* pNext = pEdge + 1; + Handle* pHandleEdge = getHandle(pEdge->m_handle); + + while (pNext->m_handle && (pEdge->m_pos >= pNext->m_pos)) + { + Handle* pHandleNext = getHandle(pNext->m_handle); + + if (pNext->IsMax()) + { +#ifndef USE_LAZY_REMOVAL + // if next edge is maximum remove any overlap between the two handles + if (updateOverlaps) + { + Handle* handle0 = getHandle(pEdge->m_handle); + Handle* handle1 = getHandle(pNext->m_handle); + + m_pairCache->removeOverlappingPair(handle0,handle1,dispatcher); + if (m_userPairCallback) + m_userPairCallback->removeOverlappingPair(handle0,handle1); + + } +#endif //USE_LAZY_REMOVAL + + // update edge reference in other handle + pHandleNext->m_maxEdges[axis]--; + } + else + pHandleNext->m_minEdges[axis]--; + + pHandleEdge->m_minEdges[axis]++; + + // swap the edges + Edge swap = *pEdge; + *pEdge = *pNext; + *pNext = swap; + + // increment + pEdge++; + pNext++; + } + + +} + +// sorting a max edge downwards can only ever *remove* overlaps +template +void btAxisSweep3Internal::sortMaxDown(int axis, BP_FP_INT_TYPE edge, btDispatcher* dispatcher, bool updateOverlaps) +{ + + Edge* pEdge = m_pEdges[axis] + edge; + Edge* pPrev = pEdge - 1; + Handle* pHandleEdge = getHandle(pEdge->m_handle); + + while (pEdge->m_pos < pPrev->m_pos) + { + Handle* pHandlePrev = getHandle(pPrev->m_handle); + + if (!pPrev->IsMax()) + { + // if previous edge was a minimum remove any overlap between the two handles + if (updateOverlaps) + { + //this is done during the overlappingpairarray iteration/narrowphase collision +#ifndef USE_LAZY_REMOVAL + Handle* handle0 = getHandle(pEdge->m_handle); + Handle* handle1 = getHandle(pPrev->m_handle); + m_pairCache->removeOverlappingPair(handle0,handle1,dispatcher); + if (m_userPairCallback) + m_userPairCallback->removeOverlappingPair(handle0,handle1); + +#endif //USE_LAZY_REMOVAL + + } + + // update edge reference in other handle + pHandlePrev->m_minEdges[axis]++;; + } + else + pHandlePrev->m_maxEdges[axis]++; + + pHandleEdge->m_maxEdges[axis]--; + + // swap the edges + Edge swap = *pEdge; + *pEdge = *pPrev; + *pPrev = swap; + + // decrement + pEdge--; + pPrev--; + } + + +#ifdef DEBUG_BROADPHASE + debugPrintAxis(axis); +#endif //DEBUG_BROADPHASE + +} + +// sorting a max edge upwards can only ever *add* overlaps +template +void btAxisSweep3Internal::sortMaxUp(int axis, BP_FP_INT_TYPE edge, btDispatcher* dispatcher, bool updateOverlaps) +{ + Edge* pEdge = m_pEdges[axis] + edge; + Edge* pNext = pEdge + 1; + Handle* pHandleEdge = getHandle(pEdge->m_handle); + + while (pNext->m_handle && (pEdge->m_pos >= pNext->m_pos)) + { + Handle* pHandleNext = getHandle(pNext->m_handle); + + if (!pNext->IsMax()) + { + // if next edge is a minimum check the bounds and add an overlap if necessary + if (updateOverlaps && testOverlap(axis, pHandleEdge, pHandleNext)) + { + Handle* handle0 = getHandle(pEdge->m_handle); + Handle* handle1 = getHandle(pNext->m_handle); + m_pairCache->addOverlappingPair(handle0,handle1); + if (m_userPairCallback) + m_userPairCallback->addOverlappingPair(handle0,handle1); + } + + // update edge reference in other handle + pHandleNext->m_minEdges[axis]--; + } + else + pHandleNext->m_maxEdges[axis]--; + + pHandleEdge->m_maxEdges[axis]++; + + // swap the edges + Edge swap = *pEdge; + *pEdge = *pNext; + *pNext = swap; + + // increment + pEdge++; + pNext++; + } + +} + + + +//////////////////////////////////////////////////////////////////// + + +/// btAxisSweep3 is an efficient implementation of the 3d axis sweep and prune broadphase. +/// It uses arrays rather then lists for storage of the 3 axis. Also it operates using 16 bit integer coordinates instead of floats. +/// For large worlds and many objects, use bt32BitAxisSweep3 instead. bt32BitAxisSweep3 has higher precision and allows more then 16384 objects at the cost of more memory and bit of performance. +class btAxisSweep3 : public btAxisSweep3Internal +{ +public: + + btAxisSweep3(const btPoint3& worldAabbMin,const btPoint3& worldAabbMax, unsigned short int maxHandles = 16384, btOverlappingPairCache* pairCache = 0); + +}; + +/// bt32BitAxisSweep3 allows higher precision quantization and more objects compared to the btAxisSweep3 sweep and prune. +/// This comes at the cost of more memory per handle, and a bit slower performance. +/// It uses arrays rather then lists for storage of the 3 axis. +class bt32BitAxisSweep3 : public btAxisSweep3Internal +{ +public: + + bt32BitAxisSweep3(const btPoint3& worldAabbMin,const btPoint3& worldAabbMax, unsigned int maxHandles = 1500000, btOverlappingPairCache* pairCache = 0); }; diff --git a/extern/bullet2/src/BulletCollision/BroadphaseCollision/btBroadphaseInterface.h b/extern/bullet2/src/BulletCollision/BroadphaseCollision/btBroadphaseInterface.h index b6ace03c07a..97ba20743d2 100644 --- a/extern/bullet2/src/BulletCollision/BroadphaseCollision/btBroadphaseInterface.h +++ b/extern/bullet2/src/BulletCollision/BroadphaseCollision/btBroadphaseInterface.h @@ -20,8 +20,10 @@ subject to the following restrictions: struct btDispatcherInfo; class btDispatcher; -struct btBroadphaseProxy; -#include "../../LinearMath/btVector3.h" +#include "btBroadphaseProxy.h" +class btOverlappingPairCache; + +#include "LinearMath/btVector3.h" ///BroadphaseInterface for aabb-overlapping object pairs class btBroadphaseInterface @@ -29,11 +31,15 @@ class btBroadphaseInterface public: virtual ~btBroadphaseInterface() {} - virtual btBroadphaseProxy* createProxy( const btVector3& min, const btVector3& max,int shapeType,void* userPtr, short int collisionFilterGroup,short int collisionFilterMask) =0; - virtual void destroyProxy(btBroadphaseProxy* proxy)=0; - virtual void setAabb(btBroadphaseProxy* proxy,const btVector3& aabbMin,const btVector3& aabbMax)=0; - virtual void cleanProxyFromPairs(btBroadphaseProxy* proxy)=0; + virtual btBroadphaseProxy* createProxy( const btVector3& aabbMin, const btVector3& aabbMax,int shapeType,void* userPtr, short int collisionFilterGroup,short int collisionFilterMask, btDispatcher* dispatcher) =0; + virtual void destroyProxy(btBroadphaseProxy* proxy,btDispatcher* dispatcher)=0; + virtual void setAabb(btBroadphaseProxy* proxy,const btVector3& aabbMin,const btVector3& aabbMax, btDispatcher* dispatcher)=0; + ///calculateOverlappingPairs is optional: incremental algorithms (sweep and prune) might do it during the set aabb + virtual void calculateOverlappingPairs(btDispatcher* dispatcher)=0; + + virtual btOverlappingPairCache* getOverlappingPairCache()=0; + virtual const btOverlappingPairCache* getOverlappingPairCache() const =0; }; diff --git a/extern/bullet2/src/BulletCollision/BroadphaseCollision/btBroadphaseProxy.h b/extern/bullet2/src/BulletCollision/BroadphaseCollision/btBroadphaseProxy.h index 40d9748ffa9..f0a462cce02 100644 --- a/extern/bullet2/src/BulletCollision/BroadphaseCollision/btBroadphaseProxy.h +++ b/extern/bullet2/src/BulletCollision/BroadphaseCollision/btBroadphaseProxy.h @@ -16,7 +16,8 @@ subject to the following restrictions: #ifndef BROADPHASE_PROXY_H #define BROADPHASE_PROXY_H -#include "../../LinearMath/btScalar.h" //for SIMD_FORCE_INLINE +#include "LinearMath/btScalar.h" //for SIMD_FORCE_INLINE +#include "LinearMath/btAlignedAllocator.h" /// btDispatcher uses these types @@ -38,6 +39,7 @@ IMPLICIT_CONVEX_SHAPES_START_HERE, CONE_SHAPE_PROXYTYPE, CONVEX_SHAPE_PROXYTYPE, CYLINDER_SHAPE_PROXYTYPE, + UNIFORM_SCALING_SHAPE_PROXYTYPE, MINKOWSKI_SUM_SHAPE_PROXYTYPE, MINKOWSKI_DIFFERENCE_SHAPE_PROXYTYPE, //concave shapes @@ -62,8 +64,10 @@ CONCAVE_SHAPES_END_HERE, ///btBroadphaseProxy -struct btBroadphaseProxy +ATTRIBUTE_ALIGNED16(struct) btBroadphaseProxy { + +BT_DECLARE_ALIGNED_ALLOCATOR(); ///optional filtering to cull potential collisions enum CollisionFilterGroups @@ -78,8 +82,27 @@ struct btBroadphaseProxy //Usually the client btCollisionObject or Rigidbody class void* m_clientObject; - short int m_collisionFilterGroup; - short int m_collisionFilterMask; + + ///in the case of btMultiSapBroadphase, we store the collifionFilterGroup/Mask in the m_multiSapParentProxy + union + { + struct + { + short int m_collisionFilterGroup; + short int m_collisionFilterMask; + }; + + void* m_multiSapParentProxy; + + }; + + int m_uniqueId;//m_uniqueId is introduced for paircache. could get rid of this, by calculating the address offset etc. + int m_unusedPadding; //making the structure 16 bytes, better for alignment etc. + + SIMD_FORCE_INLINE int getUid() + { + return m_uniqueId;//(int)this; + } //used for memory pools btBroadphaseProxy() :m_clientObject(0){} @@ -91,26 +114,28 @@ struct btBroadphaseProxy { } - static inline bool isPolyhedral(int proxyType) + + + static SIMD_FORCE_INLINE bool isPolyhedral(int proxyType) { return (proxyType < IMPLICIT_CONVEX_SHAPES_START_HERE); } - static inline bool isConvex(int proxyType) + static SIMD_FORCE_INLINE bool isConvex(int proxyType) { return (proxyType < CONCAVE_SHAPES_START_HERE); } - static inline bool isConcave(int proxyType) + static SIMD_FORCE_INLINE bool isConcave(int proxyType) { return ((proxyType > CONCAVE_SHAPES_START_HERE) && (proxyType < CONCAVE_SHAPES_END_HERE)); } - static inline bool isCompound(int proxyType) + static SIMD_FORCE_INLINE bool isCompound(int proxyType) { return (proxyType == COMPOUND_SHAPE_PROXYTYPE); } - static inline bool isInfinite(int proxyType) + static SIMD_FORCE_INLINE bool isInfinite(int proxyType) { return (proxyType == STATIC_PLANE_PROXYTYPE); } @@ -125,7 +150,7 @@ struct btBroadphaseProxy; /// contains a pair of aabb-overlapping objects -struct btBroadphasePair +ATTRIBUTE_ALIGNED16(struct) btBroadphasePair { btBroadphasePair () : @@ -136,6 +161,8 @@ struct btBroadphasePair { } +BT_DECLARE_ALIGNED_ALLOCATOR(); + btBroadphasePair(const btBroadphasePair& other) : m_pProxy0(other.m_pProxy0), m_pProxy1(other.m_pProxy1), @@ -181,6 +208,7 @@ SIMD_FORCE_INLINE bool operator<(const btBroadphasePair& a, const btBroadphasePa */ + class btBroadphasePairSortPredicate { public: diff --git a/extern/bullet2/src/BulletCollision/BroadphaseCollision/btCollisionAlgorithm.cpp b/extern/bullet2/src/BulletCollision/BroadphaseCollision/btCollisionAlgorithm.cpp index 2ad0c86d8a2..c95d1be0f2c 100644 --- a/extern/bullet2/src/BulletCollision/BroadphaseCollision/btCollisionAlgorithm.cpp +++ b/extern/bullet2/src/BulletCollision/BroadphaseCollision/btCollisionAlgorithm.cpp @@ -18,6 +18,6 @@ subject to the following restrictions: btCollisionAlgorithm::btCollisionAlgorithm(const btCollisionAlgorithmConstructionInfo& ci) { - m_dispatcher = ci.m_dispatcher; + m_dispatcher = ci.m_dispatcher1; } diff --git a/extern/bullet2/src/BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h b/extern/bullet2/src/BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h index 55cec386a7b..610eab4ce5e 100644 --- a/extern/bullet2/src/BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h +++ b/extern/bullet2/src/BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h @@ -16,7 +16,7 @@ subject to the following restrictions: #ifndef COLLISION_ALGORITHM_H #define COLLISION_ALGORITHM_H -#include "../../LinearMath/btScalar.h" +#include "LinearMath/btScalar.h" struct btBroadphaseProxy; class btDispatcher; @@ -29,17 +29,17 @@ class btPersistentManifold; struct btCollisionAlgorithmConstructionInfo { btCollisionAlgorithmConstructionInfo() - :m_dispatcher(0), + :m_dispatcher1(0), m_manifold(0) { } btCollisionAlgorithmConstructionInfo(btDispatcher* dispatcher,int temp) - :m_dispatcher(dispatcher) + :m_dispatcher1(dispatcher) { (void)temp; } - btDispatcher* m_dispatcher; + btDispatcher* m_dispatcher1; btPersistentManifold* m_manifold; int getDispatcherId(); diff --git a/extern/bullet2/src/BulletCollision/BroadphaseCollision/btDispatcher.h b/extern/bullet2/src/BulletCollision/BroadphaseCollision/btDispatcher.h index 3d958cc8fef..daea11f7788 100644 --- a/extern/bullet2/src/BulletCollision/BroadphaseCollision/btDispatcher.h +++ b/extern/bullet2/src/BulletCollision/BroadphaseCollision/btDispatcher.h @@ -16,7 +16,7 @@ subject to the following restrictions: #ifndef _DISPATCHER_H #define _DISPATCHER_H -#include "../../LinearMath/btScalar.h" +#include "LinearMath/btScalar.h" class btCollisionAlgorithm; struct btBroadphaseProxy; @@ -81,12 +81,18 @@ public: virtual bool needsResponse(btCollisionObject* body0,btCollisionObject* body1)=0; - virtual void dispatchAllCollisionPairs(btOverlappingPairCache* pairCache,btDispatcherInfo& dispatchInfo)=0; + virtual void dispatchAllCollisionPairs(btOverlappingPairCache* pairCache,btDispatcherInfo& dispatchInfo,btDispatcher* dispatcher)=0; virtual int getNumManifolds() const = 0; virtual btPersistentManifold* getManifoldByIndexInternal(int index) = 0; + virtual btPersistentManifold** getInternalManifoldPointer() = 0; + + virtual void* allocateCollisionAlgorithm(int size) = 0; + + virtual void freeCollisionAlgorithm(void* ptr) = 0; + }; diff --git a/extern/bullet2/src/BulletCollision/BroadphaseCollision/btMultiSapBroadphase.cpp b/extern/bullet2/src/BulletCollision/BroadphaseCollision/btMultiSapBroadphase.cpp new file mode 100644 index 00000000000..41406ff49f9 --- /dev/null +++ b/extern/bullet2/src/BulletCollision/BroadphaseCollision/btMultiSapBroadphase.cpp @@ -0,0 +1,204 @@ +/* +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 "btMultiSapBroadphase.h" + +#include "btSimpleBroadphase.h" +#include "LinearMath/btAabbUtil2.h" + +/// btSapBroadphaseArray m_sapBroadphases; + +/// btOverlappingPairCache* m_overlappingPairs; +extern int gOverlappingPairs; + +btMultiSapBroadphase::btMultiSapBroadphase(int maxProxies,btOverlappingPairCache* pairCache) +:m_overlappingPairs(pairCache), +m_ownsPairCache(false), +m_invalidPair(0) +{ + if (!m_overlappingPairs) + { + m_ownsPairCache = true; + void* mem = btAlignedAlloc(sizeof(btOverlappingPairCache),16); + m_overlappingPairs = new (mem)btOverlappingPairCache(); + } + + struct btMultiSapOverlapFilterCallback : public btOverlapFilterCallback + { + virtual ~btMultiSapOverlapFilterCallback() + {} + // return true when pairs need collision + virtual bool needBroadphaseCollision(btBroadphaseProxy* childProxy0,btBroadphaseProxy* childProxy1) const + { + btMultiSapBroadphase::btMultiSapProxy* multiSapProxy0 = (btMultiSapBroadphase::btMultiSapProxy*)childProxy0->m_multiSapParentProxy; + btMultiSapBroadphase::btMultiSapProxy* multiSapProxy1 = (btMultiSapBroadphase::btMultiSapProxy*)childProxy1->m_multiSapParentProxy; + + bool collides = (multiSapProxy0->m_collisionFilterGroup & multiSapProxy1->m_collisionFilterMask) != 0; + collides = collides && (multiSapProxy1->m_collisionFilterGroup & multiSapProxy0->m_collisionFilterMask); + + return collides; + } + }; + + void* mem = btAlignedAlloc(sizeof(btMultiSapOverlapFilterCallback),16); + m_filterCallback = new (mem)btMultiSapOverlapFilterCallback(); + + m_overlappingPairs->setOverlapFilterCallback(m_filterCallback); + mem = btAlignedAlloc(sizeof(btSimpleBroadphase),16); + m_simpleBroadphase = new (mem) btSimpleBroadphase(maxProxies,m_overlappingPairs); +} + +btMultiSapBroadphase::~btMultiSapBroadphase() +{ + if (m_ownsPairCache) + { + btAlignedFree(m_overlappingPairs); + } +} + +btBroadphaseProxy* btMultiSapBroadphase::createProxy( const btVector3& aabbMin, const btVector3& aabbMax,int shapeType,void* userPtr, short int collisionFilterGroup,short int collisionFilterMask, btDispatcher* dispatcher) +{ + void* mem = btAlignedAlloc(sizeof(btMultiSapProxy),16); + btMultiSapProxy* proxy = new (mem)btMultiSapProxy(aabbMin, aabbMax,shapeType,userPtr, collisionFilterGroup,collisionFilterMask); + m_multiSapProxies.push_back(proxy); + + ///we don't pass the userPtr but our multisap proxy. We need to patch this, before processing an actual collision + ///this is needed to be able to calculate the aabb overlap + btBroadphaseProxy* simpleProxy = m_simpleBroadphase->createProxy(aabbMin,aabbMax,shapeType,userPtr,collisionFilterGroup,collisionFilterMask, dispatcher); + simpleProxy->m_multiSapParentProxy = proxy; + + mem = btAlignedAlloc(sizeof(btChildProxy),16); + btChildProxy* childProxyRef = new btChildProxy(); + childProxyRef->m_proxy = simpleProxy; + childProxyRef->m_childBroadphase = m_simpleBroadphase; + proxy->m_childProxies.push_back(childProxyRef); + + ///this should deal with inserting/removal into child broadphases + setAabb(proxy,aabbMin,aabbMax,dispatcher); + return proxy; +} + +void btMultiSapBroadphase::destroyProxy(btBroadphaseProxy* proxy,btDispatcher* dispatcher) +{ + ///not yet + btAssert(0); + +} +void btMultiSapBroadphase::setAabb(btBroadphaseProxy* proxy,const btVector3& aabbMin,const btVector3& aabbMax, btDispatcher* dispatcher) +{ + btMultiSapProxy* multiProxy = static_cast(proxy); + multiProxy->m_aabbMin = aabbMin; + multiProxy->m_aabbMax = aabbMax; + + for (int i=0;im_childProxies.size();i++) + { + btChildProxy* childProxyRef = multiProxy->m_childProxies[i]; + childProxyRef->m_childBroadphase->setAabb(childProxyRef->m_proxy,aabbMin,aabbMax,dispatcher); + } + +} + + ///calculateOverlappingPairs is optional: incremental algorithms (sweep and prune) might do it during the set aabb +void btMultiSapBroadphase::calculateOverlappingPairs(btDispatcher* dispatcher) +{ + m_simpleBroadphase->calculateOverlappingPairs(dispatcher); + +#ifndef USE_HASH_PAIRCACHE + + btBroadphasePairArray& overlappingPairArray = m_overlappingPairs->getOverlappingPairArray(); + + //perform a sort, to find duplicates and to sort 'invalid' pairs to the end + overlappingPairArray.heapSort(btBroadphasePairSortPredicate()); + + overlappingPairArray.resize(overlappingPairArray.size() - m_invalidPair); + m_invalidPair = 0; + + + btBroadphasePair previousPair; + previousPair.m_pProxy0 = 0; + previousPair.m_pProxy1 = 0; + previousPair.m_algorithm = 0; + + int i; + + for (i=0;iprocessOverlap(pair); + } else + { + needsRemoval = true; + } + } else + { + //remove duplicate + needsRemoval = true; + //should have no algorithm + btAssert(!pair.m_algorithm); + } + + if (needsRemoval) + { + m_overlappingPairs->cleanOverlappingPair(pair,dispatcher); + + // m_overlappingPairArray.swap(i,m_overlappingPairArray.size()-1); + // m_overlappingPairArray.pop_back(); + pair.m_pProxy0 = 0; + pair.m_pProxy1 = 0; + m_invalidPair++; + gOverlappingPairs--; + } + + } + +///if you don't like to skip the invalid pairs in the array, execute following code: +#define CLEAN_INVALID_PAIRS 1 +#ifdef CLEAN_INVALID_PAIRS + + //perform a sort, to sort 'invalid' pairs to the end + overlappingPairArray.heapSort(btBroadphasePairSortPredicate()); + + overlappingPairArray.resize(overlappingPairArray.size() - m_invalidPair); + m_invalidPair = 0; +#endif//CLEAN_INVALID_PAIRS + +#endif //USE_HASH_PAIRCACHE + +} + + +bool btMultiSapBroadphase::testAabbOverlap(btBroadphaseProxy* childProxy0,btBroadphaseProxy* childProxy1) +{ + btMultiSapProxy* multiSapProxy0 = (btMultiSapProxy*)childProxy0->m_multiSapParentProxy; + btMultiSapProxy* multiSapProxy1 = (btMultiSapProxy*)childProxy1->m_multiSapParentProxy; + + return TestAabbAgainstAabb2(multiSapProxy0->m_aabbMin,multiSapProxy0->m_aabbMax, + multiSapProxy1->m_aabbMin,multiSapProxy1->m_aabbMax); + +} diff --git a/extern/bullet2/src/BulletCollision/BroadphaseCollision/btMultiSapBroadphase.h b/extern/bullet2/src/BulletCollision/BroadphaseCollision/btMultiSapBroadphase.h new file mode 100644 index 00000000000..1ee609b8d1f --- /dev/null +++ b/extern/bullet2/src/BulletCollision/BroadphaseCollision/btMultiSapBroadphase.h @@ -0,0 +1,119 @@ +/* +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 BT_MULTI_SAP_BROADPHASE +#define BT_MULTI_SAP_BROADPHASE + +#include "btBroadphaseInterface.h" +#include "LinearMath/btAlignedObjectArray.h" +#include "btOverlappingPairCache.h" + +class btAxisSweep3; +class btSimpleBroadphase; + + +typedef btAlignedObjectArray btSapBroadphaseArray; + +///multi SAP broadphase +///See http://www.continuousphysics.com/Bullet/phpBB2/viewtopic.php?t=328 +///and http://www.continuousphysics.com/Bullet/phpBB2/viewtopic.php?t=1329 +class btMultiSapBroadphase :public btBroadphaseInterface +{ + btSapBroadphaseArray m_sapBroadphases; + + btSimpleBroadphase* m_simpleBroadphase; + + btOverlappingPairCache* m_overlappingPairs; + + bool m_ownsPairCache; + + btOverlapFilterCallback* m_filterCallback; + + int m_invalidPair; + + struct btChildProxy + { + btBroadphaseProxy* m_proxy; + btBroadphaseInterface* m_childBroadphase; + }; + +public: + + struct btMultiSapProxy : public btBroadphaseProxy + { + + ///array with all the entries that this proxy belongs to + btAlignedObjectArray m_childProxies; + btVector3 m_aabbMin; + btVector3 m_aabbMax; + + int m_shapeType; + void* m_userPtr; + short int m_collisionFilterGroup; + short int m_collisionFilterMask; + + btMultiSapProxy(const btVector3& aabbMin, const btVector3& aabbMax,int shapeType,void* userPtr, short int collisionFilterGroup,short int collisionFilterMask) + :m_aabbMin(aabbMin), + m_aabbMax(aabbMax), + m_shapeType(shapeType), + m_userPtr(userPtr), + m_collisionFilterGroup(collisionFilterGroup), + m_collisionFilterMask(collisionFilterMask) + { + + } + + + }; + +protected: + + btAlignedObjectArray m_multiSapProxies; + +public: + + btMultiSapBroadphase(int maxProxies = 16384,btOverlappingPairCache* pairCache=0); + + btSapBroadphaseArray getBroadphaseArray() + { + return m_sapBroadphases; + } + + const btSapBroadphaseArray getBroadphaseArray() const + { + return m_sapBroadphases; + } + + virtual ~btMultiSapBroadphase(); + + virtual btBroadphaseProxy* createProxy( const btVector3& aabbMin, const btVector3& aabbMax,int shapeType,void* userPtr, short int collisionFilterGroup,short int collisionFilterMask, btDispatcher* dispatcher); + virtual void destroyProxy(btBroadphaseProxy* proxy,btDispatcher* dispatcher); + virtual void setAabb(btBroadphaseProxy* proxy,const btVector3& aabbMin,const btVector3& aabbMax, btDispatcher* dispatcher); + + ///calculateOverlappingPairs is optional: incremental algorithms (sweep and prune) might do it during the set aabb + virtual void calculateOverlappingPairs(btDispatcher* dispatcher); + + bool testAabbOverlap(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1); + + virtual btOverlappingPairCache* getOverlappingPairCache() + { + return m_overlappingPairs; + } + virtual const btOverlappingPairCache* getOverlappingPairCache() const + { + return m_overlappingPairs; + } +}; + +#endif //BT_MULTI_SAP_BROADPHASE diff --git a/extern/bullet2/src/BulletCollision/BroadphaseCollision/btOverlappingPairCache.cpp b/extern/bullet2/src/BulletCollision/BroadphaseCollision/btOverlappingPairCache.cpp index 60f0a41a9d7..e4ef043f064 100644 --- a/extern/bullet2/src/BulletCollision/BroadphaseCollision/btOverlappingPairCache.cpp +++ b/extern/bullet2/src/BulletCollision/BroadphaseCollision/btOverlappingPairCache.cpp @@ -23,11 +23,19 @@ subject to the following restrictions: int gOverlappingPairs = 0; +int gRemovePairs =0; +int gAddedPairs =0; +int gFindPairs =0; + btOverlappingPairCache::btOverlappingPairCache(): -m_blockedForChanges(false), -m_overlapFilterCallback(0) -//m_NumOverlapBroadphasePair(0) + m_overlapFilterCallback(0), + m_blockedForChanges(false) { + int initialAllocatedSize= 2; + m_overlappingPairArray.reserve(initialAllocatedSize); +#ifdef USE_HASH_PAIRCACHE + growTables(); +#endif //USE_HASH_PAIRCACHE } @@ -36,51 +44,373 @@ btOverlappingPairCache::~btOverlappingPairCache() //todo/test: show we erase/delete data, or is it automatic } - -void btOverlappingPairCache::removeOverlappingPair(btBroadphasePair& findPair) -{ - - int findIndex = m_overlappingPairArray.findLinearSearch(findPair); - if (findIndex < m_overlappingPairArray.size()) - { - gOverlappingPairs--; - btBroadphasePair& pair = m_overlappingPairArray[findIndex]; - cleanOverlappingPair(pair); - - m_overlappingPairArray.swap(findIndex,m_overlappingPairArray.size()-1); - m_overlappingPairArray.pop_back(); - } -} - - -void btOverlappingPairCache::cleanOverlappingPair(btBroadphasePair& pair) +void btOverlappingPairCache::cleanOverlappingPair(btBroadphasePair& pair,btDispatcher* dispatcher) { if (pair.m_algorithm) { { - delete pair.m_algorithm;; + pair.m_algorithm->~btCollisionAlgorithm(); + dispatcher->freeCollisionAlgorithm(pair.m_algorithm); pair.m_algorithm=0; } } } +void btOverlappingPairCache::cleanProxyFromPairs(btBroadphaseProxy* proxy,btDispatcher* dispatcher) +{ + + class CleanPairCallback : public btOverlapCallback + { + btBroadphaseProxy* m_cleanProxy; + btOverlappingPairCache* m_pairCache; + btDispatcher* m_dispatcher; + + public: + CleanPairCallback(btBroadphaseProxy* cleanProxy,btOverlappingPairCache* pairCache,btDispatcher* dispatcher) + :m_cleanProxy(cleanProxy), + m_pairCache(pairCache), + m_dispatcher(dispatcher) + { + } + virtual bool processOverlap(btBroadphasePair& pair) + { + if ((pair.m_pProxy0 == m_cleanProxy) || + (pair.m_pProxy1 == m_cleanProxy)) + { + m_pairCache->cleanOverlappingPair(pair,m_dispatcher); + } + return false; + } + + }; + + CleanPairCallback cleanPairs(proxy,this,dispatcher); + + processAllOverlappingPairs(&cleanPairs,dispatcher); + +} + +void btOverlappingPairCache::removeOverlappingPairsContainingProxy(btBroadphaseProxy* proxy,btDispatcher* dispatcher) +{ + + class RemovePairCallback : public btOverlapCallback + { + btBroadphaseProxy* m_obsoleteProxy; + + public: + RemovePairCallback(btBroadphaseProxy* obsoleteProxy) + :m_obsoleteProxy(obsoleteProxy) + { + } + virtual bool processOverlap(btBroadphasePair& pair) + { + return ((pair.m_pProxy0 == m_obsoleteProxy) || + (pair.m_pProxy1 == m_obsoleteProxy)); + } + + }; + + + RemovePairCallback removeCallback(proxy); + + processAllOverlappingPairs(&removeCallback,dispatcher); +} + + +#ifdef USE_HASH_PAIRCACHE -void btOverlappingPairCache::addOverlappingPair(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1) + + + + +btBroadphasePair* btOverlappingPairCache::findPair(btBroadphaseProxy* proxy0, btBroadphaseProxy* proxy1) +{ + gFindPairs++; + + int proxyId1 = proxy0->getUid(); + int proxyId2 = proxy1->getUid(); + + if (proxyId1 > proxyId2) + btSwap(proxyId1, proxyId2); + + int hash = getHash(proxyId1, proxyId2) & (m_overlappingPairArray.capacity()-1); + + int index = m_hashTable[hash]; + while (index != BT_NULL_PAIR && equalsPair(m_overlappingPairArray[index], proxyId1, proxyId2) == false) + { + index = m_next[index]; + } + + if (index == BT_NULL_PAIR) + { + return NULL; + } + + btAssert(index < m_overlappingPairArray.size()); + + return &m_overlappingPairArray[index]; +} + +#include + +void btOverlappingPairCache::growTables() +{ + + int newCapacity = m_overlappingPairArray.capacity(); + + if (m_hashTable.size() < newCapacity) + { + //grow hashtable and next table + int curHashtableSize = m_hashTable.size(); + + m_hashTable.resize(newCapacity); + m_next.resize(newCapacity); + + + int i; + + for (i= 0; i < newCapacity; ++i) + { + m_hashTable[i] = BT_NULL_PAIR; + } + for (i = 0; i < newCapacity; ++i) + { + m_next[i] = BT_NULL_PAIR; + } + + for(i=0;igetUid(); + int proxyId2 = pair.m_pProxy1->getUid(); + if (proxyId1 > proxyId2) + btSwap(proxyId1, proxyId2); + int hashValue = getHash(proxyId1,proxyId2) & (m_overlappingPairArray.capacity()-1); // New hash value with new mask + m_next[i] = m_hashTable[hashValue]; + m_hashTable[hashValue] = i; + } + + + } +} + +btBroadphasePair* btOverlappingPairCache::internalAddPair(btBroadphaseProxy* proxy0, btBroadphaseProxy* proxy1) +{ + int proxyId1 = proxy0->getUid(); + int proxyId2 = proxy1->getUid(); + + if (proxyId1 > proxyId2) + btSwap(proxyId1, proxyId2); + + int hash = getHash(proxyId1, proxyId2) & (m_overlappingPairArray.capacity()-1); + + + + btBroadphasePair* pair = internalFindPair(proxy0, proxy1, hash); + if (pair != NULL) + { + return pair; + } + + int count = m_overlappingPairArray.size(); + int oldCapacity = m_overlappingPairArray.capacity(); + void* mem = &m_overlappingPairArray.expand(); + int newCapacity = m_overlappingPairArray.capacity(); + + if (oldCapacity < newCapacity) + { + growTables(); + //hash with new capacity + hash = getHash(proxyId1, proxyId2) & (m_overlappingPairArray.capacity()-1); + } + + pair = new (mem) btBroadphasePair(*proxy0,*proxy1); +// pair->m_pProxy0 = proxy0; +// pair->m_pProxy1 = proxy1; + pair->m_algorithm = 0; + pair->m_userInfo = 0; + + + m_next[count] = m_hashTable[hash]; + m_hashTable[hash] = count; + + return pair; +} + + + +void* btOverlappingPairCache::removeOverlappingPair(btBroadphaseProxy* proxy0, btBroadphaseProxy* proxy1,btDispatcher* dispatcher) +{ + gRemovePairs++; + + int proxyId1 = proxy0->getUid(); + int proxyId2 = proxy1->getUid(); + + if (proxyId1 > proxyId2) + btSwap(proxyId1, proxyId2); + + int hash = getHash(proxyId1, proxyId2) & (m_overlappingPairArray.capacity()-1); + + btBroadphasePair* pair = internalFindPair(proxy0, proxy1, hash); + if (pair == NULL) + { + return 0; + } + + cleanOverlappingPair(*pair,dispatcher); + + void* userData = pair->m_userInfo; + + btAssert(pair->m_pProxy0->getUid() == proxyId1); + btAssert(pair->m_pProxy1->getUid() == proxyId2); + + int pairIndex = int(pair - &m_overlappingPairArray[0]); + btAssert(pairIndex < m_overlappingPairArray.size()); + + // Remove the pair from the hash table. + int index = m_hashTable[hash]; + btAssert(index != BT_NULL_PAIR); + + int previous = BT_NULL_PAIR; + while (index != pairIndex) + { + previous = index; + index = m_next[index]; + } + + if (previous != BT_NULL_PAIR) + { + btAssert(m_next[previous] == pairIndex); + m_next[previous] = m_next[pairIndex]; + } + else + { + m_hashTable[hash] = m_next[pairIndex]; + } + + // We now move the last pair into spot of the + // pair being removed. We need to fix the hash + // table indices to support the move. + + int lastPairIndex = m_overlappingPairArray.size() - 1; + + // If the removed pair is the last pair, we are done. + if (lastPairIndex == pairIndex) + { + m_overlappingPairArray.pop_back(); + return userData; + } + + // Remove the last pair from the hash table. + const btBroadphasePair* last = &m_overlappingPairArray[lastPairIndex]; + int lastHash = getHash(last->m_pProxy0->getUid(), last->m_pProxy1->getUid()) & (m_overlappingPairArray.capacity()-1); + + index = m_hashTable[lastHash]; + btAssert(index != BT_NULL_PAIR); + + previous = BT_NULL_PAIR; + while (index != lastPairIndex) + { + previous = index; + index = m_next[index]; + } + + if (previous != BT_NULL_PAIR) + { + btAssert(m_next[previous] == lastPairIndex); + m_next[previous] = m_next[lastPairIndex]; + } + else + { + m_hashTable[lastHash] = m_next[lastPairIndex]; + } + + // Copy the last pair into the remove pair's spot. + m_overlappingPairArray[pairIndex] = m_overlappingPairArray[lastPairIndex]; + + // Insert the last pair into the hash table + m_next[pairIndex] = m_hashTable[lastHash]; + m_hashTable[lastHash] = pairIndex; + + m_overlappingPairArray.pop_back(); + + return userData; +} +#include + +void btOverlappingPairCache::processAllOverlappingPairs(btOverlapCallback* callback,btDispatcher* dispatcher) +{ + + int i; + +// printf("m_overlappingPairArray.size()=%d\n",m_overlappingPairArray.size()); + for (i=0;iprocessOverlap(*pair)) + { + removeOverlappingPair(pair->m_pProxy0,pair->m_pProxy1,dispatcher); + + gOverlappingPairs--; + } else + { + i++; + } + } +} + +#else + + + + +void* btOverlappingPairCache::removeOverlappingPair(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1, btDispatcher* dispatcher ) +{ +#ifndef USE_LAZY_REMOVAL + + btBroadphasePair findPair(*proxy0,*proxy1); + + int findIndex = m_overlappingPairArray.findLinearSearch(findPair); + if (findIndex < m_overlappingPairArray.size()) + { + gOverlappingPairs--; + btBroadphasePair& pair = m_overlappingPairArray[findIndex]; + void* userData = pair.m_userInfo; + cleanOverlappingPair(pair,dispatcher); + + m_overlappingPairArray.swap(findIndex,m_overlappingPairArray.capacity()-1); + m_overlappingPairArray.pop_back(); + return userData; + } +#endif //USE_LAZY_REMOVAL + + return 0; +} + + + + + + + + +btBroadphasePair* btOverlappingPairCache::addOverlappingPair(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1) { //don't add overlap with own assert(proxy0 != proxy1); if (!needsBroadphaseCollision(proxy0,proxy1)) - return; - - - btBroadphasePair pair(*proxy0,*proxy1); + return 0; - m_overlappingPairArray.push_back(pair); + void* mem = &m_overlappingPairArray.expand(); + btBroadphasePair* pair = new (mem) btBroadphasePair(*proxy0,*proxy1); gOverlappingPairs++; + return pair; } @@ -109,69 +439,14 @@ void btOverlappingPairCache::addOverlappingPair(btBroadphaseProxy* proxy0,btBroa -void btOverlappingPairCache::cleanProxyFromPairs(btBroadphaseProxy* proxy) -{ - - class CleanPairCallback : public btOverlapCallback - { - btBroadphaseProxy* m_cleanProxy; - btOverlappingPairCache* m_pairCache; - - public: - CleanPairCallback(btBroadphaseProxy* cleanProxy,btOverlappingPairCache* pairCache) - :m_cleanProxy(cleanProxy), - m_pairCache(pairCache) - { - } - virtual bool processOverlap(btBroadphasePair& pair) - { - if ((pair.m_pProxy0 == m_cleanProxy) || - (pair.m_pProxy1 == m_cleanProxy)) - { - m_pairCache->cleanOverlappingPair(pair); - } - return false; - } - - }; - - CleanPairCallback cleanPairs(proxy,this); - - processAllOverlappingPairs(&cleanPairs); - -} -void btOverlappingPairCache::removeOverlappingPairsContainingProxy(btBroadphaseProxy* proxy) -{ - - class RemovePairCallback : public btOverlapCallback - { - btBroadphaseProxy* m_obsoleteProxy; - - public: - RemovePairCallback(btBroadphaseProxy* obsoleteProxy) - :m_obsoleteProxy(obsoleteProxy) - { - } - virtual bool processOverlap(btBroadphasePair& pair) - { - return ((pair.m_pProxy0 == m_obsoleteProxy) || - (pair.m_pProxy1 == m_obsoleteProxy)); - } - - }; - RemovePairCallback removeCallback(proxy); +#include - processAllOverlappingPairs(&removeCallback); -} - - - -void btOverlappingPairCache::processAllOverlappingPairs(btOverlapCallback* callback) +void btOverlappingPairCache::processAllOverlappingPairs(btOverlapCallback* callback,btDispatcher* dispatcher) { int i; @@ -182,9 +457,9 @@ void btOverlappingPairCache::processAllOverlappingPairs(btOverlapCallback* callb btBroadphasePair* pair = &m_overlappingPairArray[i]; if (callback->processOverlap(*pair)) { - cleanOverlappingPair(*pair); + cleanOverlappingPair(*pair,dispatcher); - m_overlappingPairArray.swap(i,m_overlappingPairArray.size()-1); + m_overlappingPairArray.swap(i,m_overlappingPairArray.capacity()-1); m_overlappingPairArray.pop_back(); gOverlappingPairs--; } else @@ -194,3 +469,6 @@ void btOverlappingPairCache::processAllOverlappingPairs(btOverlapCallback* callb } } + + +#endif //USE_HASH_PAIRCACHE diff --git a/extern/bullet2/src/BulletCollision/BroadphaseCollision/btOverlappingPairCache.h b/extern/bullet2/src/BulletCollision/BroadphaseCollision/btOverlappingPairCache.h index a81fe3264df..a387505d1be 100644 --- a/extern/bullet2/src/BulletCollision/BroadphaseCollision/btOverlappingPairCache.h +++ b/extern/bullet2/src/BulletCollision/BroadphaseCollision/btOverlappingPairCache.h @@ -20,8 +20,12 @@ subject to the following restrictions: #include "btBroadphaseInterface.h" #include "btBroadphaseProxy.h" -#include "../../LinearMath/btPoint3.h" -#include "../../LinearMath/btAlignedObjectArray.h" +#include "LinearMath/btPoint3.h" +#include "LinearMath/btAlignedObjectArray.h" +class btDispatcher; + +///disable the USE_HASH_PAIRCACHE define to use a pair manager that sorts the pairs to find duplicates/non-overlap +#define USE_HASH_PAIRCACHE 1 struct btOverlapCallback @@ -40,38 +44,226 @@ struct btOverlapFilterCallback virtual bool needBroadphaseCollision(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1) const = 0; }; +typedef btAlignedObjectArray btBroadphasePairArray; + +#ifdef USE_HASH_PAIRCACHE + + +/// Hash-space based Pair Cache, thanks to Erin Catto, Box2D, http://www.box2d.org, and Pierre Terdiman, Codercorner, http://codercorner.com + +extern int gRemovePairs; +extern int gAddedPairs; +extern int gFindPairs; + +const int BT_NULL_PAIR=0xffffffff; + +class btOverlappingPairCache +{ + btBroadphasePairArray m_overlappingPairArray; + btOverlapFilterCallback* m_overlapFilterCallback; + bool m_blockedForChanges; + + +public: + btOverlappingPairCache(); + virtual ~btOverlappingPairCache(); + + + void removeOverlappingPairsContainingProxy(btBroadphaseProxy* proxy,btDispatcher* dispatcher); + + void* removeOverlappingPair(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1,btDispatcher* dispatcher); + + SIMD_FORCE_INLINE bool needsBroadphaseCollision(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1) const + { + if (m_overlapFilterCallback) + return m_overlapFilterCallback->needBroadphaseCollision(proxy0,proxy1); + + bool collides = (proxy0->m_collisionFilterGroup & proxy1->m_collisionFilterMask) != 0; + collides = collides && (proxy1->m_collisionFilterGroup & proxy0->m_collisionFilterMask); + + return collides; + } + + // Add a pair and return the new pair. If the pair already exists, + // no new pair is created and the old one is returned. + SIMD_FORCE_INLINE btBroadphasePair* addOverlappingPair(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1) + { + gAddedPairs++; + + if (!needsBroadphaseCollision(proxy0,proxy1)) + return 0; + + return internalAddPair(proxy0,proxy1); + } + + + + void cleanProxyFromPairs(btBroadphaseProxy* proxy,btDispatcher* dispatcher); + + + virtual void processAllOverlappingPairs(btOverlapCallback*,btDispatcher* dispatcher); + + btBroadphasePair* getOverlappingPairArrayPtr() + { + return &m_overlappingPairArray[0]; + } + + const btBroadphasePair* getOverlappingPairArrayPtr() const + { + return &m_overlappingPairArray[0]; + } + + btBroadphasePairArray& getOverlappingPairArray() + { + return m_overlappingPairArray; + } + + const btBroadphasePairArray& getOverlappingPairArray() const + { + return m_overlappingPairArray; + } + + void cleanOverlappingPair(btBroadphasePair& pair,btDispatcher* dispatcher); + + + + btBroadphasePair* findPair(btBroadphaseProxy* proxy0, btBroadphaseProxy* proxy1); + + int GetCount() const { return m_overlappingPairArray.size(); } +// btBroadphasePair* GetPairs() { return m_pairs; } + + btOverlapFilterCallback* getOverlapFilterCallback() + { + return m_overlapFilterCallback; + } + + void setOverlapFilterCallback(btOverlapFilterCallback* callback) + { + m_overlapFilterCallback = callback; + } + + int getNumOverlappingPairs() const + { + return m_overlappingPairArray.size(); + } +private: + + btBroadphasePair* internalAddPair(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1); + + void growTables(); + + SIMD_FORCE_INLINE bool equalsPair(const btBroadphasePair& pair, int proxyId1, int proxyId2) + { + return pair.m_pProxy0->getUid() == proxyId1 && pair.m_pProxy1->getUid() == proxyId2; + } + + /* + // Thomas Wang's hash, see: http://www.concentric.net/~Ttwang/tech/inthash.htm + // This assumes proxyId1 and proxyId2 are 16-bit. + SIMD_FORCE_INLINE int getHash(int proxyId1, int proxyId2) + { + int key = (proxyId2 << 16) | proxyId1; + key = ~key + (key << 15); + key = key ^ (key >> 12); + key = key + (key << 2); + key = key ^ (key >> 4); + key = key * 2057; + key = key ^ (key >> 16); + return key; + } + */ + + + + SIMD_FORCE_INLINE unsigned int getHash(unsigned int proxyId1, unsigned int proxyId2) + { + int key = ((unsigned int)proxyId1) | (((unsigned int)proxyId1) <<16); + // Thomas Wang's hash + + key += ~(key << 15); + key ^= (key >> 10); + key += (key << 3); + key ^= (key >> 6); + key += ~(key << 11); + key ^= (key >> 16); + return key; + } + + + + + + SIMD_FORCE_INLINE btBroadphasePair* internalFindPair(btBroadphaseProxy* proxy0, btBroadphaseProxy* proxy1, int hash) + { + int proxyId1 = proxy0->getUid(); + int proxyId2 = proxy1->getUid(); + if (proxyId1 > proxyId2) + btSwap(proxyId1, proxyId2); + + int index = m_hashTable[hash]; + + while( index != BT_NULL_PAIR && equalsPair(m_overlappingPairArray[index], proxyId1, proxyId2) == false) + { + index = m_next[index]; + } + + if ( index == BT_NULL_PAIR ) + { + return NULL; + } + + btAssert(index < m_overlappingPairArray.size()); + + return &m_overlappingPairArray[index]; + } + + +public: + + btAlignedObjectArray m_hashTable; + btAlignedObjectArray m_next; + +}; + + + +#else//USE_HASH_PAIRCACHE + +#define USE_LAZY_REMOVAL 1 + ///btOverlappingPairCache maintains the objects with overlapping AABB ///Typically managed by the Broadphase, Axis3Sweep or btSimpleBroadphase -class btOverlappingPairCache : public btBroadphaseInterface +class btOverlappingPairCache { protected: //avoid brute-force finding all the time - btAlignedObjectArray m_overlappingPairArray; - + btBroadphasePairArray m_overlappingPairArray; + //during the dispatch, check that user doesn't destroy/create proxy bool m_blockedForChanges; //if set, use the callback instead of the built in filter in needBroadphaseCollision btOverlapFilterCallback* m_overlapFilterCallback; + public: btOverlappingPairCache(); virtual ~btOverlappingPairCache(); - virtual void processAllOverlappingPairs(btOverlapCallback*); + virtual void processAllOverlappingPairs(btOverlapCallback*,btDispatcher* dispatcher); - void removeOverlappingPair(btBroadphasePair& pair); + void* removeOverlappingPair(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1,btDispatcher* dispatcher); - void cleanOverlappingPair(btBroadphasePair& pair); + void cleanOverlappingPair(btBroadphasePair& pair,btDispatcher* dispatcher); - void addOverlappingPair(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1); + btBroadphasePair* addOverlappingPair(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1); btBroadphasePair* findPair(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1); - void cleanProxyFromPairs(btBroadphaseProxy* proxy); + void cleanProxyFromPairs(btBroadphaseProxy* proxy,btDispatcher* dispatcher); - void removeOverlappingPairsContainingProxy(btBroadphaseProxy* proxy); + void removeOverlappingPairsContainingProxy(btBroadphaseProxy* proxy,btDispatcher* dispatcher); inline bool needsBroadphaseCollision(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1) const @@ -84,10 +276,19 @@ class btOverlappingPairCache : public btBroadphaseInterface return collides; } - + + btBroadphasePairArray& getOverlappingPairArray() + { + return m_overlappingPairArray; + } + + const btBroadphasePairArray& getOverlappingPairArray() const + { + return m_overlappingPairArray; + } + - virtual void refreshOverlappingPairs() =0; btBroadphasePair* getOverlappingPairArrayPtr() { @@ -115,6 +316,8 @@ class btOverlappingPairCache : public btBroadphaseInterface } }; +#endif //USE_HASH_PAIRCACHE + #endif //OVERLAPPING_PAIR_CACHE_H diff --git a/extern/bullet2/src/BulletCollision/BroadphaseCollision/btOverlappingPairCallback.h b/extern/bullet2/src/BulletCollision/BroadphaseCollision/btOverlappingPairCallback.h new file mode 100644 index 00000000000..b8d967dc4b2 --- /dev/null +++ b/extern/bullet2/src/BulletCollision/BroadphaseCollision/btOverlappingPairCallback.h @@ -0,0 +1,37 @@ + +/* +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 OVERLAPPING_PAIR_CALLBACK_H +#define OVERLAPPING_PAIR_CALLBACK_H + +///btOverlappingPairCallback provides user callback to keep track of overlap between objects, like a collision sensor +class btOverlappingPairCallback +{ +public: + virtual ~btOverlappingPairCallback() + { + + } + + virtual void addOverlappingPair(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1) = 0; + + virtual void removeOverlappingPair(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1) = 0; + + virtual void removeOverlappingPairsContainingProxy(btBroadphaseProxy* proxy0) = 0; + +}; + +#endif //OVERLAPPING_PAIR_CALLBACK_H \ No newline at end of file diff --git a/extern/bullet2/src/BulletCollision/BroadphaseCollision/btSimpleBroadphase.cpp b/extern/bullet2/src/BulletCollision/BroadphaseCollision/btSimpleBroadphase.cpp index 30bcbe0c5f1..e0bb0992933 100644 --- a/extern/bullet2/src/BulletCollision/BroadphaseCollision/btSimpleBroadphase.cpp +++ b/extern/bullet2/src/BulletCollision/BroadphaseCollision/btSimpleBroadphase.cpp @@ -22,75 +22,78 @@ subject to the following restrictions: #include "LinearMath/btMatrix3x3.h" #include +extern int gOverlappingPairs; void btSimpleBroadphase::validate() { - for (int i=0;i=0;i--) + if (m_ownsPairCache) { - BP_Proxy* proxy = m_pProxies[i]; - destroyProxy(proxy); + m_pairCache->~btOverlappingPairCache(); + btAlignedFree(m_pairCache); } - */ } -btBroadphaseProxy* btSimpleBroadphase::createProxy( const btVector3& min, const btVector3& max,int shapeType,void* userPtr ,short int collisionFilterGroup,short int collisionFilterMask) +btBroadphaseProxy* btSimpleBroadphase::createProxy( const btVector3& aabbMin, const btVector3& aabbMax,int shapeType,void* userPtr ,short int collisionFilterGroup,short int collisionFilterMask, btDispatcher* dispatcher) { - if (m_numProxies >= m_maxProxies) + if (m_numHandles >= m_maxHandles) { - assert(0); + btAssert(0); return 0; //should never happen, but don't let the game crash ;-) } - assert(min[0]<= max[0] && min[1]<= max[1] && min[2]<= max[2]); + assert(aabbMin[0]<= aabbMax[0] && aabbMin[1]<= aabbMax[1] && aabbMin[2]<= aabbMax[2]); - int freeIndex= m_freeProxies[m_firstFreeProxy]; - btSimpleBroadphaseProxy* proxy = new (&m_proxies[freeIndex])btSimpleBroadphaseProxy(min,max,shapeType,userPtr,collisionFilterGroup,collisionFilterMask); - m_firstFreeProxy++; - - btSimpleBroadphaseProxy* proxy1 = &m_proxies[0]; - - int index = int(proxy - proxy1); - btAssert(index == freeIndex); - - m_pProxies[m_numProxies] = proxy; - m_numProxies++; - //validate(); + int newHandleIndex = allocHandle(); + btSimpleBroadphaseProxy* proxy = new (&m_pHandles[newHandleIndex])btSimpleBroadphaseProxy(aabbMin,aabbMax,shapeType,userPtr,collisionFilterGroup,collisionFilterMask); return proxy; } @@ -124,34 +127,19 @@ protected: }; }; -void btSimpleBroadphase::destroyProxy(btBroadphaseProxy* proxyOrg) +void btSimpleBroadphase::destroyProxy(btBroadphaseProxy* proxyOrg,btDispatcher* dispatcher) { - int i; - btSimpleBroadphaseProxy* proxy0 = static_cast(proxyOrg); - btSimpleBroadphaseProxy* proxy1 = &m_proxies[0]; - - int index = int(proxy0 - proxy1); - btAssert (index < m_maxProxies); - m_freeProxies[--m_firstFreeProxy] = index; + freeHandle(proxy0); + + m_pairCache->removeOverlappingPairsContainingProxy(proxyOrg,dispatcher); - removeOverlappingPairsContainingProxy(proxyOrg); - - for (i=0;im_min = aabbMin; @@ -186,37 +174,139 @@ public: } }; -void btSimpleBroadphase::refreshOverlappingPairs() +void btSimpleBroadphase::calculateOverlappingPairs(btDispatcher* dispatcher) { //first check for new overlapping pairs int i,j; - for (i=0;i= 0) { - btBroadphaseProxy* proxy0 = m_pProxies[i]; - for (j=i+1;jfindPair(proxy0,proxy1)) + { + m_pairCache->addOverlappingPair(proxy0,proxy1); + } + } else + { + #ifdef USE_HASH_PAIRCACHE + if ( m_pairCache->findPair(proxy0,proxy1)) + { + m_pairCache->removeOverlappingPair(proxy0,proxy1,dispatcher); + } + #endif //USE_HASH_PAIRCACHE + + } } + proxy1 = &m_pHandles[proxy1->GetNextAllocated()]; + } + proxy0 = &m_pHandles[proxy0->GetNextAllocated()]; } + + #ifndef USE_HASH_PAIRCACHE + + if (m_ownsPairCache) + { + + btBroadphasePairArray& overlappingPairArray = m_pairCache->getOverlappingPairArray(); + + //perform a sort, to find duplicates and to sort 'invalid' pairs to the end + overlappingPairArray.heapSort(btBroadphasePairSortPredicate()); + + overlappingPairArray.resize(overlappingPairArray.size() - m_invalidPair); + m_invalidPair = 0; + + + btBroadphasePair previousPair; + previousPair.m_pProxy0 = 0; + previousPair.m_pProxy1 = 0; + previousPair.m_algorithm = 0; + + + for (i=0;iprocessOverlap(pair); + } else + { + needsRemoval = true; + } + } else + { + //remove duplicate + needsRemoval = true; + //should have no algorithm + btAssert(!pair.m_algorithm); + } + + if (needsRemoval) + { + m_pairCache->cleanOverlappingPair(pair,dispatcher); + + // m_overlappingPairArray.swap(i,m_overlappingPairArray.size()-1); + // m_overlappingPairArray.pop_back(); + pair.m_pProxy0 = 0; + pair.m_pProxy1 = 0; + m_invalidPair++; + gOverlappingPairs--; + } + + } + + ///if you don't like to skip the invalid pairs in the array, execute following code: + #define CLEAN_INVALID_PAIRS 1 + #ifdef CLEAN_INVALID_PAIRS + + //perform a sort, to sort 'invalid' pairs to the end + overlappingPairArray.heapSort(btBroadphasePairSortPredicate()); + + overlappingPairArray.resize(overlappingPairArray.size() - m_invalidPair); + m_invalidPair = 0; + #endif//CLEAN_INVALID_PAIRS + + } + #endif //USE_HASH_PAIRCACHE } - - - CheckOverlapCallback checkOverlap; - - processAllOverlappingPairs(&checkOverlap); - - } +bool btSimpleBroadphase::testAabbOverlap(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1) +{ + btSimpleBroadphaseProxy* p0 = getSimpleProxyFromProxy(proxy0); + btSimpleBroadphaseProxy* p1 = getSimpleProxyFromProxy(proxy1); + return aabbOverlap(p0,p1); +} + + + diff --git a/extern/bullet2/src/BulletCollision/BroadphaseCollision/btSimpleBroadphase.h b/extern/bullet2/src/BulletCollision/BroadphaseCollision/btSimpleBroadphase.h index fb155e7047c..09367a79d2b 100644 --- a/extern/bullet2/src/BulletCollision/BroadphaseCollision/btSimpleBroadphase.h +++ b/extern/bullet2/src/BulletCollision/BroadphaseCollision/btSimpleBroadphase.h @@ -24,6 +24,10 @@ struct btSimpleBroadphaseProxy : public btBroadphaseProxy { btVector3 m_min; btVector3 m_max; + int m_nextFree; + int m_nextAllocated; +// int m_handleId; + btSimpleBroadphaseProxy() {}; @@ -34,25 +38,64 @@ struct btSimpleBroadphaseProxy : public btBroadphaseProxy (void)shapeType; } + + SIMD_FORCE_INLINE void SetNextFree(int next) {m_nextFree = next;} + SIMD_FORCE_INLINE int GetNextFree() const {return m_nextFree;} + + SIMD_FORCE_INLINE void SetNextAllocated(int next) {m_nextAllocated = next;} + SIMD_FORCE_INLINE int GetNextAllocated() const {return m_nextAllocated;} + }; ///SimpleBroadphase is a brute force aabb culling broadphase based on O(n^2) aabb checks -class btSimpleBroadphase : public btOverlappingPairCache +///btSimpleBroadphase is just a unit-test implementation to verify and test other broadphases. +///So please don't use this class, but use bt32BitAxisSweep3 or btAxisSweep3 instead! +class btSimpleBroadphase : public btBroadphaseInterface { protected: - btSimpleBroadphaseProxy* m_proxies; - int* m_freeProxies; - int m_firstFreeProxy; + int m_numHandles; // number of active handles + int m_maxHandles; // max number of handles + btSimpleBroadphaseProxy* m_pHandles; // handles pool + int m_firstFreeHandle; // free handles list + int m_firstAllocatedHandle; - btSimpleBroadphaseProxy** m_pProxies; - int m_numProxies; + int allocHandle() + { - + int freeHandle = m_firstFreeHandle; + m_firstFreeHandle = m_pHandles[freeHandle].GetNextFree(); + + m_pHandles[freeHandle].SetNextAllocated(m_firstAllocatedHandle); + m_firstAllocatedHandle = freeHandle; + + m_numHandles++; + + return freeHandle; + } + + void freeHandle(btSimpleBroadphaseProxy* proxy) + { + int handle = int(proxy-m_pHandles); + btAssert(handle >= 0 && handle < m_maxHandles); + + proxy->SetNextFree(m_firstFreeHandle); + m_firstFreeHandle = handle; + + m_firstAllocatedHandle = proxy->GetNextAllocated(); + proxy->SetNextAllocated(-1); + + m_numHandles--; + } + + + btOverlappingPairCache* m_pairCache; + bool m_ownsPairCache; + + int m_invalidPair; - int m_maxProxies; inline btSimpleBroadphaseProxy* getSimpleProxyFromProxy(btBroadphaseProxy* proxy) @@ -67,24 +110,33 @@ protected: protected: - virtual void refreshOverlappingPairs(); + + public: - btSimpleBroadphase(int maxProxies=16384); + btSimpleBroadphase(int maxProxies=16384,btOverlappingPairCache* overlappingPairCache=0); virtual ~btSimpleBroadphase(); static bool aabbOverlap(btSimpleBroadphaseProxy* proxy0,btSimpleBroadphaseProxy* proxy1); - virtual btBroadphaseProxy* createProxy( const btVector3& min, const btVector3& max,int shapeType,void* userPtr ,short int collisionFilterGroup,short int collisionFilterMask); + virtual btBroadphaseProxy* createProxy( const btVector3& aabbMin, const btVector3& aabbMax,int shapeType,void* userPtr ,short int collisionFilterGroup,short int collisionFilterMask, btDispatcher* dispatcher); + virtual void calculateOverlappingPairs(btDispatcher* dispatcher); - virtual void destroyProxy(btBroadphaseProxy* proxy); - virtual void setAabb(btBroadphaseProxy* proxy,const btVector3& aabbMin,const btVector3& aabbMax); + virtual void destroyProxy(btBroadphaseProxy* proxy,btDispatcher* dispatcher); + virtual void setAabb(btBroadphaseProxy* proxy,const btVector3& aabbMin,const btVector3& aabbMax, btDispatcher* dispatcher); - - + btOverlappingPairCache* getOverlappingPairCache() + { + return m_pairCache; + } + const btOverlappingPairCache* getOverlappingPairCache() const + { + return m_pairCache; + } + bool testAabbOverlap(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1); }; diff --git a/extern/bullet2/src/BulletCollision/CMakeLists.txt b/extern/bullet2/src/BulletCollision/CMakeLists.txt index e565bf7edea..d2d3dc6fabf 100644 --- a/extern/bullet2/src/BulletCollision/CMakeLists.txt +++ b/extern/bullet2/src/BulletCollision/CMakeLists.txt @@ -8,6 +8,7 @@ ADD_LIBRARY(LibBulletCollision BroadphaseCollision/btBroadphaseProxy.cpp BroadphaseCollision/btCollisionAlgorithm.cpp BroadphaseCollision/btDispatcher.cpp + BroadphaseCollision/btMultiSapBroadphase.cpp BroadphaseCollision/btOverlappingPairCache.cpp BroadphaseCollision/btSimpleBroadphase.cpp CollisionDispatch/btCollisionDispatcher.cpp @@ -15,24 +16,30 @@ ADD_LIBRARY(LibBulletCollision CollisionDispatch/btCollisionWorld.cpp CollisionDispatch/btCompoundCollisionAlgorithm.cpp CollisionDispatch/btConvexConcaveCollisionAlgorithm.cpp + CollisionDispatch/btDefaultCollisionConfiguration.cpp CollisionDispatch/btSphereSphereCollisionAlgorithm.cpp CollisionDispatch/btSphereBoxCollisionAlgorithm.cpp + CollisionDispatch/btSphereTriangleCollisionAlgorithm.cpp CollisionDispatch/btConvexConvexAlgorithm.cpp CollisionDispatch/btEmptyCollisionAlgorithm.cpp CollisionDispatch/btManifoldResult.cpp CollisionDispatch/btSimulationIslandManager.cpp CollisionDispatch/btUnionFind.cpp + CollisionDispatch/SphereTriangleDetector.cpp CollisionShapes/btBoxShape.cpp CollisionShapes/btBvhTriangleMeshShape.cpp + CollisionShapes/btCapsuleShape.cpp CollisionShapes/btCollisionShape.cpp CollisionShapes/btCompoundShape.cpp CollisionShapes/btConcaveShape.cpp CollisionShapes/btConeShape.cpp CollisionShapes/btConvexHullShape.cpp CollisionShapes/btConvexShape.cpp + CollisionShapes/btConvexInternalShape.cpp CollisionShapes/btConvexTriangleMeshShape.cpp CollisionShapes/btCylinderShape.cpp CollisionShapes/btEmptyShape.cpp + CollisionShapes/btHeightfieldTerrainShape.cpp CollisionShapes/btMinkowskiSumShape.cpp CollisionShapes/btMultiSphereShape.cpp CollisionShapes/btOptimizedBvh.cpp @@ -46,6 +53,7 @@ ADD_LIBRARY(LibBulletCollision CollisionShapes/btTriangleIndexVertexArray.cpp CollisionShapes/btTriangleMesh.cpp CollisionShapes/btTriangleMeshShape.cpp + CollisionShapes/btUniformScalingShape.cpp NarrowPhaseCollision/btContinuousConvexCollision.cpp NarrowPhaseCollision/btGjkEpa.cpp NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.cpp diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/SphereTriangleDetector.h b/extern/bullet2/src/BulletCollision/CollisionDispatch/SphereTriangleDetector.h index b32806a6846..0c817b221c8 100644 --- a/extern/bullet2/src/BulletCollision/CollisionDispatch/SphereTriangleDetector.h +++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/SphereTriangleDetector.h @@ -16,8 +16,8 @@ subject to the following restrictions: #ifndef SPHERE_TRIANGLE_DETECTOR_H #define SPHERE_TRIANGLE_DETECTOR_H -#include "../NarrowPhaseCollision/btDiscreteCollisionDetectorInterface.h" -#include "../../LinearMath/btPoint3.h" +#include "BulletCollision/NarrowPhaseCollision/btDiscreteCollisionDetectorInterface.h" +#include "LinearMath/btPoint3.h" class btSphereShape; diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionConfiguration.h b/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionConfiguration.h new file mode 100644 index 00000000000..fad770ac26d --- /dev/null +++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionConfiguration.h @@ -0,0 +1,47 @@ +/* +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 BT_COLLISION_CONFIGURATION +#define BT_COLLISION_CONFIGURATION +struct btCollisionAlgorithmCreateFunc; + +class btStackAlloc; +class btPoolAllocator; + +///btCollisionConfiguration allows to configure Bullet collision detection +///stack allocator size, default collision algorithms and persistent manifold pool size +///todo: describe the meaning +class btCollisionConfiguration +{ + +public: + + virtual ~btCollisionConfiguration() + { + } + + ///memory pools + virtual btPoolAllocator* getPersistentManifoldPool() = 0; + + virtual btPoolAllocator* getCollisionAlgorithmPool() = 0; + + virtual btStackAlloc* getStackAllocator() = 0; + + virtual btCollisionAlgorithmCreateFunc* getCollisionAlgorithmCreateFunc(int proxyType0,int proxyType1) =0; + +}; + +#endif //BT_COLLISION_CONFIGURATION + diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionCreateFunc.h b/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionCreateFunc.h index d51a59af7f0..c6728918d16 100644 --- a/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionCreateFunc.h +++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionCreateFunc.h @@ -16,7 +16,7 @@ subject to the following restrictions: #ifndef COLLISION_CREATE_FUNC #define COLLISION_CREATE_FUNC -#include "../../LinearMath/btAlignedObjectArray.h" +#include "LinearMath/btAlignedObjectArray.h" typedef btAlignedObjectArray btCollisionObjectArray; class btCollisionAlgorithm; class btCollisionObject; diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionDispatcher.cpp b/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionDispatcher.cpp index b535fac6563..644caf2677b 100644 --- a/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionDispatcher.cpp +++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionDispatcher.cpp @@ -19,69 +19,37 @@ subject to the following restrictions: #include "BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h" -#include "BulletCollision/CollisionDispatch/btConvexConvexAlgorithm.h" -#include "BulletCollision/CollisionDispatch/btEmptyCollisionAlgorithm.h" -#include "BulletCollision/CollisionDispatch/btConvexConcaveCollisionAlgorithm.h" -#include "BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.h" + #include "BulletCollision/CollisionShapes/btCollisionShape.h" #include "BulletCollision/CollisionDispatch/btCollisionObject.h" #include "BulletCollision/BroadphaseCollision/btOverlappingPairCache.h" +#include "LinearMath/btPoolAllocator.h" +#include "BulletCollision/CollisionDispatch/btCollisionConfiguration.h" int gNumManifold = 0; #include - -btCollisionDispatcher::btCollisionDispatcher(bool noDefaultAlgorithms): -m_count(0), -m_useIslands(true), -m_convexConvexCreateFunc(0), -m_convexConcaveCreateFunc(0), -m_swappedConvexConcaveCreateFunc(0), -m_compoundCreateFunc(0), -m_swappedCompoundCreateFunc(0), -m_emptyCreateFunc(0) -{ - (void)noDefaultAlgorithms; - int i; - setNearCallback(defaultNearCallback); - m_emptyCreateFunc = new btEmptyAlgorithm::CreateFunc; - for (i=0;igetCollisionAlgorithmPool(); + + m_persistentManifoldPoolAllocator = collisionConfiguration->getPersistentManifoldPool(); for (i=0;igetCollisionAlgorithmCreateFunc(i,j); assert(m_doubleDispatch[i][j]); } } @@ -89,8 +57,6 @@ btCollisionDispatcher::btCollisionDispatcher (): }; -#endif //BT_EXCLUDE_DEFAULT_COLLISIONALGORITHM_REGISTRATION - void btCollisionDispatcher::registerCollisionCreateFunc(int proxyType0, int proxyType1, btCollisionAlgorithmCreateFunc *createFunc) { @@ -99,12 +65,6 @@ void btCollisionDispatcher::registerCollisionCreateFunc(int proxyType0, int prox btCollisionDispatcher::~btCollisionDispatcher() { - delete m_convexConvexCreateFunc; - delete m_convexConcaveCreateFunc; - delete m_swappedConvexConcaveCreateFunc; - delete m_compoundCreateFunc; - delete m_swappedCompoundCreateFunc; - delete m_emptyCreateFunc; } btPersistentManifold* btCollisionDispatcher::getNewManifold(void* b0,void* b1) @@ -117,7 +77,18 @@ btPersistentManifold* btCollisionDispatcher::getNewManifold(void* b0,void* b1) btCollisionObject* body0 = (btCollisionObject*)b0; btCollisionObject* body1 = (btCollisionObject*)b1; - btPersistentManifold* manifold = new btPersistentManifold (body0,body1); + void* mem = 0; + + if (m_persistentManifoldPoolAllocator->getFreeCount()) + { + mem = m_persistentManifoldPoolAllocator->allocate(sizeof(btPersistentManifold)); + } else + { + mem = btAlignedAlloc(sizeof(btPersistentManifold),16); + + } + btPersistentManifold* manifold = new(mem) btPersistentManifold (body0,body1,0); + manifold->m_index1a = m_manifoldsPtr.size(); m_manifoldsPtr.push_back(manifold); return manifold; @@ -137,13 +108,19 @@ void btCollisionDispatcher::releaseManifold(btPersistentManifold* manifold) //printf("releaseManifold: gNumManifold %d\n",gNumManifold); clearManifold(manifold); - ///todo: this can be improved a lot, linear search might be slow part! - int findIndex = m_manifoldsPtr.findLinearSearch(manifold); - if (findIndex < m_manifoldsPtr.size()) + int findIndex = manifold->m_index1a; + btAssert(findIndex < m_manifoldsPtr.size()); + m_manifoldsPtr.swap(findIndex,m_manifoldsPtr.size()-1); + m_manifoldsPtr[findIndex]->m_index1a = findIndex; + m_manifoldsPtr.pop_back(); + + manifold->~btPersistentManifold(); + if (m_persistentManifoldPoolAllocator->validPtr(manifold)) { - m_manifoldsPtr.swap(findIndex,m_manifoldsPtr.size()-1); - m_manifoldsPtr.pop_back(); - delete manifold; + m_persistentManifoldPoolAllocator->free(manifold); + } else + { + btAlignedFree(manifold); } } @@ -152,99 +129,19 @@ void btCollisionDispatcher::releaseManifold(btPersistentManifold* manifold) btCollisionAlgorithm* btCollisionDispatcher::findAlgorithm(btCollisionObject* body0,btCollisionObject* body1,btPersistentManifold* sharedManifold) { - -#ifdef USE_DISPATCH_REGISTRY_ARRAY btCollisionAlgorithmConstructionInfo ci; - ci.m_dispatcher = this; + + ci.m_dispatcher1 = this; ci.m_manifold = sharedManifold; - btCollisionAlgorithm* algo = m_doubleDispatch[body0->getCollisionShape()->getShapeType()][body1->getCollisionShape()->getShapeType()] - ->CreateCollisionAlgorithm(ci,body0,body1); -#else - btCollisionAlgorithm* algo = internalFindAlgorithm(body0,body1); -#endif //USE_DISPATCH_REGISTRY_ARRAY + btCollisionAlgorithm* algo = m_doubleDispatch[body0->getCollisionShape()->getShapeType()][body1->getCollisionShape()->getShapeType()]->CreateCollisionAlgorithm(ci,body0,body1); + return algo; } -#ifndef BT_EXCLUDE_DEFAULT_COLLISIONALGORITHM_REGISTRATION - -btCollisionAlgorithmCreateFunc* btCollisionDispatcher::internalFindCreateFunc(int proxyType0,int proxyType1) -{ - - if (btBroadphaseProxy::isConvex(proxyType0) && btBroadphaseProxy::isConvex(proxyType1)) - { - return m_convexConvexCreateFunc; - } - - if (btBroadphaseProxy::isConvex(proxyType0) && btBroadphaseProxy::isConcave(proxyType1)) - { - return m_convexConcaveCreateFunc; - } - - if (btBroadphaseProxy::isConvex(proxyType1) && btBroadphaseProxy::isConcave(proxyType0)) - { - return m_swappedConvexConcaveCreateFunc; - } - - if (btBroadphaseProxy::isCompound(proxyType0)) - { - return m_compoundCreateFunc; - } else - { - if (btBroadphaseProxy::isCompound(proxyType1)) - { - return m_swappedCompoundCreateFunc; - } - } - - //failed to find an algorithm - return m_emptyCreateFunc; -} - -#endif //BT_EXCLUDE_DEFAULT_COLLISIONALGORITHM_REGISTRATION -#ifndef USE_DISPATCH_REGISTRY_ARRAY - -btCollisionAlgorithm* btCollisionDispatcher::internalFindAlgorithm(btCollisionObject* body0,btCollisionObject* body1,btPersistentManifold* sharedManifold) -{ - m_count++; - - btCollisionAlgorithmConstructionInfo ci; - ci.m_dispatcher = this; - - if (body0->getCollisionShape()->isConvex() && body1->getCollisionShape()->isConvex() ) - { - return new btConvexConvexAlgorithm(sharedManifold,ci,body0,body1); - } - - if (body0->getCollisionShape()->isConvex() && body1->getCollisionShape()->isConcave()) - { - return new btConvexConcaveCollisionAlgorithm(ci,body0,body1,false); - } - - if (body1->getCollisionShape()->isConvex() && body0->getCollisionShape()->isConcave()) - { - return new btConvexConcaveCollisionAlgorithm(ci,body0,body1,true); - } - - if (body0->getCollisionShape()->isCompound()) - { - return new btCompoundCollisionAlgorithm(ci,body0,body1,false); - } else - { - if (body1->getCollisionShape()->isCompound()) - { - return new btCompoundCollisionAlgorithm(ci,body0,body1,true); - } - } - - //failed to find an algorithm - return new btEmptyAlgorithm(ci); - -} -#endif //USE_DISPATCH_REGISTRY_ARRAY bool btCollisionDispatcher::needsResponse(btCollisionObject* body0,btCollisionObject* body1) { @@ -316,13 +213,13 @@ public: }; -void btCollisionDispatcher::dispatchAllCollisionPairs(btOverlappingPairCache* pairCache,btDispatcherInfo& dispatchInfo) +void btCollisionDispatcher::dispatchAllCollisionPairs(btOverlappingPairCache* pairCache,btDispatcherInfo& dispatchInfo,btDispatcher* dispatcher) { //m_blockedForChanges = true; btCollisionPairCallback collisionCallback(dispatchInfo,this); - pairCache->processAllOverlappingPairs(&collisionCallback); + pairCache->processAllOverlappingPairs(&collisionCallback,dispatcher); //m_blockedForChanges = false; @@ -365,3 +262,26 @@ void btCollisionDispatcher::defaultNearCallback(btBroadphasePair& collisionPair, } } + + +void* btCollisionDispatcher::allocateCollisionAlgorithm(int size) +{ + if (m_collisionAlgorithmPoolAllocator->getFreeCount()) + { + return m_collisionAlgorithmPoolAllocator->allocate(size); + } + + //warn user for overflow? + return btAlignedAlloc(size,16); +} + +void btCollisionDispatcher::freeCollisionAlgorithm(void* ptr) +{ + if (m_collisionAlgorithmPoolAllocator->validPtr(ptr)) + { + m_collisionAlgorithmPoolAllocator->free(ptr); + } else + { + btAlignedFree(ptr); + } +} diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionDispatcher.h b/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionDispatcher.h index ca5aba8f01c..45aaa1bd90d 100644 --- a/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionDispatcher.h +++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionDispatcher.h @@ -16,17 +16,18 @@ subject to the following restrictions: #ifndef COLLISION__DISPATCHER_H #define COLLISION__DISPATCHER_H -#include "../BroadphaseCollision/btDispatcher.h" -#include "../NarrowPhaseCollision/btPersistentManifold.h" +#include "BulletCollision/BroadphaseCollision/btDispatcher.h" +#include "BulletCollision/NarrowPhaseCollision/btPersistentManifold.h" -#include "../CollisionDispatch/btManifoldResult.h" +#include "BulletCollision/CollisionDispatch/btManifoldResult.h" -#include "../BroadphaseCollision/btBroadphaseProxy.h" -#include "../../LinearMath/btAlignedObjectArray.h" +#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" +#include "LinearMath/btAlignedObjectArray.h" class btIDebugDraw; class btOverlappingPairCache; - +class btPoolAllocator; +class btCollisionConfiguration; #include "btCollisionCreateFunc.h" @@ -51,21 +52,15 @@ class btCollisionDispatcher : public btDispatcher btNearCallback m_nearCallback; + btPoolAllocator* m_collisionAlgorithmPoolAllocator; + + btPoolAllocator* m_persistentManifoldPoolAllocator; + btCollisionAlgorithmCreateFunc* m_doubleDispatch[MAX_BROADPHASE_COLLISION_TYPES][MAX_BROADPHASE_COLLISION_TYPES]; - btCollisionAlgorithmCreateFunc* internalFindCreateFunc(int proxyType0,int proxyType1); - //default CreationFunctions, filling the m_doubleDispatch table - btCollisionAlgorithmCreateFunc* m_convexConvexCreateFunc; - btCollisionAlgorithmCreateFunc* m_convexConcaveCreateFunc; - btCollisionAlgorithmCreateFunc* m_swappedConvexConcaveCreateFunc; - btCollisionAlgorithmCreateFunc* m_compoundCreateFunc; - btCollisionAlgorithmCreateFunc* m_swappedCompoundCreateFunc; - btCollisionAlgorithmCreateFunc* m_emptyCreateFunc; + btCollisionConfiguration* m_collisionConfiguration; -#ifndef USE_DISPATCH_REGISTRY_ARRAY - btCollisionAlgorithm* internalFindAlgorithm(btCollisionObject* body0,btCollisionObject* body1,btPersistentManifold* sharedManifold = 0); -#endif //USE_DISPATCH_REGISTRY_ARRAY public: @@ -92,11 +87,7 @@ public: return m_manifoldsPtr[index]; } - ///the default constructor creates/register default collision algorithms, for convex, compound and concave shape support - btCollisionDispatcher (); - - ///a special constructor that doesn't create/register the default collision algorithms - btCollisionDispatcher(bool noDefaultAlgorithms); + btCollisionDispatcher (btCollisionConfiguration* collisionConfiguration); virtual ~btCollisionDispatcher(); @@ -114,7 +105,7 @@ public: virtual bool needsResponse(btCollisionObject* body0,btCollisionObject* body1); - virtual void dispatchAllCollisionPairs(btOverlappingPairCache* pairCache,btDispatcherInfo& dispatchInfo); + virtual void dispatchAllCollisionPairs(btOverlappingPairCache* pairCache,btDispatcherInfo& dispatchInfo,btDispatcher* dispatcher); void setNearCallback(btNearCallback nearCallback) { @@ -129,6 +120,25 @@ public: //by default, Bullet will use this near callback static void defaultNearCallback(btBroadphasePair& collisionPair, btCollisionDispatcher& dispatcher, btDispatcherInfo& dispatchInfo); + virtual void* allocateCollisionAlgorithm(int size); + + virtual void freeCollisionAlgorithm(void* ptr); + + btCollisionConfiguration* getCollisionConfiguration() + { + return m_collisionConfiguration; + } + + const btCollisionConfiguration* getCollisionConfiguration() const + { + return m_collisionConfiguration; + } + + void setCollisionConfiguration(btCollisionConfiguration* config) + { + m_collisionConfiguration = config; + } + }; #endif //COLLISION__DISPATCHER_H diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionObject.cpp b/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionObject.cpp index d4c0a4e8cb3..6b72a131c4f 100644 --- a/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionObject.cpp +++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionObject.cpp @@ -13,15 +13,19 @@ subject to the following restrictions: 3. This notice may not be removed or altered from any source distribution. */ + #include "btCollisionObject.h" btCollisionObject::btCollisionObject() : m_broadphaseHandle(0), m_collisionShape(0), m_collisionFlags(0), + m_islandTag1(-1), + m_companionId(-1), m_activationState1(1), m_deactivationTime(btScalar(0.)), m_userObjectPointer(0), + m_internalOwner(0), m_hitFraction(btScalar(1.)), m_ccdSweptSphereRadius(btScalar(0.)), m_ccdSquareMotionThreshold(btScalar(0.)), @@ -55,3 +59,4 @@ void btCollisionObject::activate(bool forceActivation) } + diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionObject.h b/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionObject.h index 9fb6a67c4a3..7c1ddbf1e2d 100644 --- a/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionObject.h +++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionObject.h @@ -16,7 +16,7 @@ subject to the following restrictions: #ifndef COLLISION_OBJECT_H #define COLLISION_OBJECT_H -#include "../../LinearMath/btTransform.h" +#include "LinearMath/btTransform.h" //island management, m_activationState1 #define ACTIVE_TAG 1 @@ -27,7 +27,8 @@ subject to the following restrictions: struct btBroadphaseProxy; class btCollisionShape; -#include "../../LinearMath/btMotionState.h" +#include "LinearMath/btMotionState.h" +#include "LinearMath/btAlignedAllocator.h" @@ -89,6 +90,8 @@ protected: public: + BT_DECLARE_ALIGNED_ALLOCATOR(); + enum CollisionFlags { CF_STATIC_OBJECT= 1, @@ -98,28 +101,28 @@ public: }; - inline bool mergesSimulationIslands() const + SIMD_FORCE_INLINE bool mergesSimulationIslands() const { ///static objects, kinematic and object without contact response don't merge islands return ((m_collisionFlags & (CF_STATIC_OBJECT | CF_KINEMATIC_OBJECT | CF_NO_CONTACT_RESPONSE) )==0); } - inline bool isStaticObject() const { + SIMD_FORCE_INLINE bool isStaticObject() const { return (m_collisionFlags & CF_STATIC_OBJECT) != 0; } - inline bool isKinematicObject() const + SIMD_FORCE_INLINE bool isKinematicObject() const { return (m_collisionFlags & CF_KINEMATIC_OBJECT) != 0; } - inline bool isStaticOrKinematicObject() const + SIMD_FORCE_INLINE bool isStaticOrKinematicObject() const { return (m_collisionFlags & (CF_KINEMATIC_OBJECT | CF_STATIC_OBJECT)) != 0 ; } - inline bool hasContactResponse() const { + SIMD_FORCE_INLINE bool hasContactResponse() const { return (m_collisionFlags & CF_NO_CONTACT_RESPONSE)==0; } @@ -133,12 +136,12 @@ public: m_collisionShape = collisionShape; } - const btCollisionShape* getCollisionShape() const + SIMD_FORCE_INLINE const btCollisionShape* getCollisionShape() const { return m_collisionShape; } - btCollisionShape* getCollisionShape() + SIMD_FORCE_INLINE btCollisionShape* getCollisionShape() { return m_collisionShape; } diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionWorld.cpp b/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionWorld.cpp index b49036a5b50..b4828508bcb 100644 --- a/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionWorld.cpp +++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionWorld.cpp @@ -24,6 +24,9 @@ subject to the following restrictions: #include "BulletCollision/NarrowPhaseCollision/btRaycastCallback.h" #include "BulletCollision/CollisionShapes/btCompoundShape.h" #include "BulletCollision/NarrowPhaseCollision/btSubSimplexConvexCast.h" +#include "BulletCollision/NarrowPhaseCollision/btGjkConvexCast.h" +#include "BulletCollision/NarrowPhaseCollision/btContinuousConvexCollision.h" + #include "BulletCollision/BroadphaseCollision/btBroadphaseInterface.h" #include "LinearMath/btAabbUtil2.h" #include "LinearMath/btQuickprof.h" @@ -32,23 +35,20 @@ subject to the following restrictions: //When the user doesn't provide dispatcher or broadphase, create basic versions (and delete them in destructor) #include "BulletCollision/CollisionDispatch/btCollisionDispatcher.h" #include "BulletCollision/BroadphaseCollision/btSimpleBroadphase.h" +#include "BulletCollision/CollisionDispatch/btCollisionConfiguration.h" -btCollisionWorld::btCollisionWorld(btDispatcher* dispatcher,btOverlappingPairCache* pairCache, int stackSize) +btCollisionWorld::btCollisionWorld(btDispatcher* dispatcher,btBroadphaseInterface* pairCache, btCollisionConfiguration* collisionConfiguration) :m_dispatcher1(dispatcher), -m_broadphasePairCache(pairCache), -m_ownsDispatcher(false), -m_ownsBroadphasePairCache(false) +m_broadphasePairCache(pairCache) { - m_stackAlloc = new btStackAlloc(stackSize); + m_stackAlloc = collisionConfiguration->getStackAllocator(); m_dispatchInfo.m_stackAllocator = m_stackAlloc; } btCollisionWorld::~btCollisionWorld() { - m_stackAlloc->destroy(); - delete m_stackAlloc; //clean up remaining objects int i; @@ -62,15 +62,11 @@ btCollisionWorld::~btCollisionWorld() // // only clear the cached algorithms // - getBroadphase()->cleanProxyFromPairs(bp); - getBroadphase()->destroyProxy(bp); + getBroadphase()->getOverlappingPairCache()->cleanProxyFromPairs(bp,m_dispatcher1); + getBroadphase()->destroyProxy(bp,m_dispatcher1); } } - if (m_ownsDispatcher) - delete m_dispatcher1; - if (m_ownsBroadphasePairCache) - delete m_broadphasePairCache; } @@ -105,7 +101,8 @@ void btCollisionWorld::addCollisionObject(btCollisionObject* collisionObject,sho type, collisionObject, collisionFilterGroup, - collisionFilterMask + collisionFilterMask, + m_dispatcher1 )) ; @@ -130,11 +127,10 @@ void btCollisionWorld::performDiscreteCollisionDetection() for (int i=0;igetCollisionShape()->getAabb(m_collisionObjects[i]->getWorldTransform(),aabbMin,aabbMax); - m_broadphasePairCache->setAabb(m_collisionObjects[i]->getBroadphaseHandle(),aabbMin,aabbMax); + m_broadphasePairCache->setAabb(m_collisionObjects[i]->getBroadphaseHandle(),aabbMin,aabbMax,m_dispatcher1); } - m_broadphasePairCache->refreshOverlappingPairs(); - + m_broadphasePairCache->calculateOverlappingPairs(m_dispatcher1); END_PROFILE("perform Broadphase Collision Detection"); @@ -142,13 +138,14 @@ void btCollisionWorld::performDiscreteCollisionDetection() btDispatcher* dispatcher = getDispatcher(); if (dispatcher) - dispatcher->dispatchAllCollisionPairs(m_broadphasePairCache,dispatchInfo); + dispatcher->dispatchAllCollisionPairs(m_broadphasePairCache->getOverlappingPairCache(),dispatchInfo,m_dispatcher1); END_PROFILE("performDiscreteCollisionDetection"); } + void btCollisionWorld::removeCollisionObject(btCollisionObject* collisionObject) { @@ -163,8 +160,8 @@ void btCollisionWorld::removeCollisionObject(btCollisionObject* collisionObject) // // only clear the cached algorithms // - getBroadphase()->cleanProxyFromPairs(bp); - getBroadphase()->destroyProxy(bp); + getBroadphase()->getOverlappingPairCache()->cleanProxyFromPairs(bp,m_dispatcher1); + getBroadphase()->destroyProxy(bp,m_dispatcher1); collisionObject->setBroadphaseHandle(0); } } @@ -209,19 +206,28 @@ void btCollisionWorld::objectQuerySingle(const btConvexShape* castShape,const bt btConvexShape* convexShape = (btConvexShape*) collisionShape; btVoronoiSimplexSolver simplexSolver; +#define USE_SUBSIMPLEX_CONVEX_CAST 1 +#ifdef USE_SUBSIMPLEX_CONVEX_CAST btSubsimplexConvexCast convexCaster(castShape,convexShape,&simplexSolver); - //GjkConvexCast convexCaster(castShape,convexShape,&simplexSolver); - //ContinuousConvexCollision convexCaster(castShape,convexShape,&simplexSolver,0); - +#else + //btGjkConvexCast convexCaster(castShape,convexShape,&simplexSolver); + //btContinuousConvexCollision convexCaster(castShape,convexShape,&simplexSolver,0); +#endif //#USE_SUBSIMPLEX_CONVEX_CAST + if (convexCaster.calcTimeOfImpact(rayFromTrans,rayToTrans,colObjWorldTransform,colObjWorldTransform,castResult)) { //add hit if (castResult.m_normal.length2() > btScalar(0.0001)) { - castResult.m_normal.normalize(); + if (castResult.m_fraction < resultCallback.m_closestHitFraction) { +#ifdef USE_SUBSIMPLEX_CONVEX_CAST + //rotate normal into worldspace + castResult.m_normal = rayFromTrans.getBasis() * castResult.m_normal; +#endif //USE_SUBSIMPLEX_CONVEX_CAST + castResult.m_normal.normalize(); btCollisionWorld::LocalRayResult localRayResult ( collisionObject, @@ -230,7 +236,8 @@ void btCollisionWorld::objectQuerySingle(const btConvexShape* castShape,const bt castResult.m_fraction ); - resultCallback.AddSingleResult(localRayResult); + bool normalInWorldSpace = true; + resultCallback.AddSingleResult(localRayResult, normalInWorldSpace); } } @@ -279,7 +286,8 @@ void btCollisionWorld::objectQuerySingle(const btConvexShape* castShape,const bt hitNormalLocal, hitFraction); - return m_resultCallback->AddSingleResult(rayResult); + bool normalInWorldSpace = false; + return m_resultCallback->AddSingleResult(rayResult,normalInWorldSpace); } diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionWorld.h b/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionWorld.h index b6d80233ab7..bda03ccedeb 100644 --- a/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionWorld.h +++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionWorld.h @@ -68,12 +68,12 @@ class btStackAlloc; class btCollisionShape; class btConvexShape; class btBroadphaseInterface; -#include "../../LinearMath/btVector3.h" -#include "../../LinearMath/btTransform.h" +#include "LinearMath/btVector3.h" +#include "LinearMath/btTransform.h" #include "btCollisionObject.h" #include "btCollisionDispatcher.h" //for definition of btCollisionObjectArray -#include "../BroadphaseCollision/btOverlappingPairCache.h" -#include "../../LinearMath/btAlignedObjectArray.h" +#include "BulletCollision/BroadphaseCollision/btOverlappingPairCache.h" +#include "LinearMath/btAlignedObjectArray.h" ///CollisionWorld is interface and container for the collision detection class btCollisionWorld @@ -90,15 +90,12 @@ protected: btStackAlloc* m_stackAlloc; - btOverlappingPairCache* m_broadphasePairCache; + btBroadphaseInterface* m_broadphasePairCache; - bool m_ownsDispatcher; - bool m_ownsBroadphasePairCache; - public: //this constructor doesn't own the dispatcher and paircache/broadphase - btCollisionWorld(btDispatcher* dispatcher,btOverlappingPairCache* pairCache, int stackSize = 2*1024*1024); + btCollisionWorld(btDispatcher* dispatcher,btBroadphaseInterface* broadphasePairCache, btCollisionConfiguration* collisionConfiguration); virtual ~btCollisionWorld(); @@ -110,7 +107,7 @@ public: btOverlappingPairCache* getPairCache() { - return m_broadphasePairCache; + return m_broadphasePairCache->getOverlappingPairCache(); } @@ -166,7 +163,7 @@ public: :m_closestHitFraction(btScalar(1.)) { } - virtual btScalar AddSingleResult(LocalRayResult& rayResult) = 0; + virtual btScalar AddSingleResult(LocalRayResult& rayResult,bool normalInWorldSpace) = 0; }; struct ClosestRayResultCallback : public RayResultCallback @@ -185,7 +182,7 @@ public: btVector3 m_hitPointWorld; btCollisionObject* m_collisionObject; - virtual btScalar AddSingleResult(LocalRayResult& rayResult) + virtual btScalar AddSingleResult(LocalRayResult& rayResult,bool normalInWorldSpace) { //caller already does the filter on the m_closestHitFraction @@ -193,7 +190,14 @@ public: m_closestHitFraction = rayResult.m_hitFraction; m_collisionObject = rayResult.m_collisionObject; - m_hitNormalWorld = m_collisionObject->getWorldTransform().getBasis()*rayResult.m_hitNormalLocal; + if (normalInWorldSpace) + { + m_hitNormalWorld = rayResult.m_hitNormalLocal; + } else + { + ///need to transform normal into worldspace + m_hitNormalWorld = m_collisionObject->getWorldTransform().getBasis()*rayResult.m_hitNormalLocal; + } m_hitPointWorld.setInterpolate3(m_rayFromWorld,m_rayToWorld,rayResult.m_hitFraction); return rayResult.m_hitFraction; } diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.cpp b/extern/bullet2/src/BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.cpp index 92f4c8b28a6..7c0c7a3b0a9 100644 --- a/extern/bullet2/src/BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.cpp +++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.cpp @@ -19,7 +19,8 @@ subject to the following restrictions: btCompoundCollisionAlgorithm::btCompoundCollisionAlgorithm( const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* body0,btCollisionObject* body1,bool isSwapped) -:m_isSwapped(isSwapped) +:btCollisionAlgorithm(ci), +m_isSwapped(isSwapped) { btCollisionObject* colObj = m_isSwapped? body1 : body0; btCollisionObject* otherObj = m_isSwapped? body0 : body1; @@ -35,7 +36,7 @@ btCompoundCollisionAlgorithm::btCompoundCollisionAlgorithm( const btCollisionAlg btCollisionShape* childShape = compoundShape->getChildShape(i); btCollisionShape* orgShape = colObj->getCollisionShape(); colObj->setCollisionShape( childShape ); - m_childCollisionAlgorithms[i] = ci.m_dispatcher->findAlgorithm(colObj,otherObj); + m_childCollisionAlgorithms[i] = ci.m_dispatcher1->findAlgorithm(colObj,otherObj); colObj->setCollisionShape( orgShape ); } } @@ -47,7 +48,8 @@ btCompoundCollisionAlgorithm::~btCompoundCollisionAlgorithm() int i; for (i=0;i~btCollisionAlgorithm(); + m_dispatcher->freeCollisionAlgorithm(m_childCollisionAlgorithms[i]); } } diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.h b/extern/bullet2/src/BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.h index 7091b233b46..a381d8b3c3f 100644 --- a/extern/bullet2/src/BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.h +++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.h @@ -16,15 +16,16 @@ subject to the following restrictions: #ifndef COMPOUND_COLLISION_ALGORITHM_H #define COMPOUND_COLLISION_ALGORITHM_H -#include "../BroadphaseCollision/btCollisionAlgorithm.h" -#include "../BroadphaseCollision/btDispatcher.h" -#include "../BroadphaseCollision/btBroadphaseInterface.h" +#include "BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h" +#include "BulletCollision/BroadphaseCollision/btDispatcher.h" +#include "BulletCollision/BroadphaseCollision/btBroadphaseInterface.h" -#include "../NarrowPhaseCollision/btPersistentManifold.h" +#include "BulletCollision/NarrowPhaseCollision/btPersistentManifold.h" class btDispatcher; -#include "../BroadphaseCollision/btBroadphaseProxy.h" +#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" #include "btCollisionCreateFunc.h" -#include "../../LinearMath/btAlignedObjectArray.h" +#include "LinearMath/btAlignedObjectArray.h" +class btDispatcher; /// btCompoundCollisionAlgorithm supports collision between CompoundCollisionShapes and other collision shapes /// Place holder, not fully implemented yet @@ -47,7 +48,8 @@ public: { virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, btCollisionObject* body0,btCollisionObject* body1) { - return new btCompoundCollisionAlgorithm(ci,body0,body1,false); + void* mem = ci.m_dispatcher1->allocateCollisionAlgorithm(sizeof(btCompoundCollisionAlgorithm)); + return new(mem) btCompoundCollisionAlgorithm(ci,body0,body1,false); } }; @@ -55,7 +57,8 @@ public: { virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, btCollisionObject* body0,btCollisionObject* body1) { - return new btCompoundCollisionAlgorithm(ci,body0,body1,true); + void* mem = ci.m_dispatcher1->allocateCollisionAlgorithm(sizeof(btCompoundCollisionAlgorithm)); + return new(mem) btCompoundCollisionAlgorithm(ci,body0,body1,true); } }; diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btConvexConcaveCollisionAlgorithm.cpp b/extern/bullet2/src/BulletCollision/CollisionDispatch/btConvexConcaveCollisionAlgorithm.cpp index 24ceacfd40d..559b633feb9 100644 --- a/extern/bullet2/src/BulletCollision/CollisionDispatch/btConvexConcaveCollisionAlgorithm.cpp +++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btConvexConcaveCollisionAlgorithm.cpp @@ -29,7 +29,7 @@ subject to the following restrictions: btConvexConcaveCollisionAlgorithm::btConvexConcaveCollisionAlgorithm( const btCollisionAlgorithmConstructionInfo& ci, btCollisionObject* body0,btCollisionObject* body1,bool isSwapped) : btCollisionAlgorithm(ci), m_isSwapped(isSwapped), -m_btConvexTriangleCallback(ci.m_dispatcher,body0,body1,isSwapped) +m_btConvexTriangleCallback(ci.m_dispatcher1,body0,body1,isSwapped) { } @@ -79,7 +79,7 @@ void btConvexTriangleCallback::processTriangle(btVector3* triangle,int partId, i //aabb filter is already applied! btCollisionAlgorithmConstructionInfo ci; - ci.m_dispatcher = m_dispatcher; + ci.m_dispatcher1 = m_dispatcher; btCollisionObject* ob = static_cast(m_triBody); @@ -115,7 +115,7 @@ void btConvexTriangleCallback::processTriangle(btVector3* triangle,int partId, i ob->setCollisionShape( &tm ); - btCollisionAlgorithm* colAlgo = ci.m_dispatcher->findAlgorithm(m_convexBody,m_triBody,m_manifoldPtr); + btCollisionAlgorithm* colAlgo = ci.m_dispatcher1->findAlgorithm(m_convexBody,m_triBody,m_manifoldPtr); ///this should use the btDispatcher, so the actual registered algorithm is used // btConvexConvexAlgorithm cvxcvxalgo(m_manifoldPtr,ci,m_convexBody,m_triBody); @@ -123,7 +123,8 @@ void btConvexTriangleCallback::processTriangle(btVector3* triangle,int partId, i // cvxcvxalgo.setShapeIdentifiers(-1,-1,partId,triangleIndex); // cvxcvxalgo.processCollision(m_convexBody,m_triBody,*m_dispatchInfoPtr,m_resultOut); colAlgo->processCollision(m_convexBody,m_triBody,*m_dispatchInfoPtr,m_resultOut); - delete colAlgo; + colAlgo->~btCollisionAlgorithm(); + ci.m_dispatcher1->freeCollisionAlgorithm(colAlgo); ob->setCollisionShape( tmpShape ); } @@ -188,9 +189,10 @@ void btConvexConcaveCollisionAlgorithm::processCollision (btCollisionObject* bod concaveShape->processAllTriangles( &m_btConvexTriangleCallback,m_btConvexTriangleCallback.getAabbMin(),m_btConvexTriangleCallback.getAabbMax()); + resultOut->refreshContactPoints(); } - + } } diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btConvexConcaveCollisionAlgorithm.h b/extern/bullet2/src/BulletCollision/CollisionDispatch/btConvexConcaveCollisionAlgorithm.h index 4915b6c20c8..da33e988991 100644 --- a/extern/bullet2/src/BulletCollision/CollisionDispatch/btConvexConcaveCollisionAlgorithm.h +++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btConvexConcaveCollisionAlgorithm.h @@ -16,13 +16,13 @@ subject to the following restrictions: #ifndef CONVEX_CONCAVE_COLLISION_ALGORITHM_H #define CONVEX_CONCAVE_COLLISION_ALGORITHM_H -#include "../BroadphaseCollision/btCollisionAlgorithm.h" -#include "../BroadphaseCollision/btDispatcher.h" -#include "../BroadphaseCollision/btBroadphaseInterface.h" -#include "../CollisionShapes/btTriangleCallback.h" -#include "../NarrowPhaseCollision/btPersistentManifold.h" +#include "BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h" +#include "BulletCollision/BroadphaseCollision/btDispatcher.h" +#include "BulletCollision/BroadphaseCollision/btBroadphaseInterface.h" +#include "BulletCollision/CollisionShapes/btTriangleCallback.h" +#include "BulletCollision/NarrowPhaseCollision/btPersistentManifold.h" class btDispatcher; -#include "../BroadphaseCollision/btBroadphaseProxy.h" +#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" #include "btCollisionCreateFunc.h" ///For each triangle in the concave mesh that overlaps with the AABB of a convex (m_convexProxy), processTriangle is called. @@ -55,11 +55,11 @@ int m_triangleCount; void clearCache(); - inline const btVector3& getAabbMin() const + SIMD_FORCE_INLINE const btVector3& getAabbMin() const { return m_aabbMin; } - inline const btVector3& getAabbMax() const + SIMD_FORCE_INLINE const btVector3& getAabbMax() const { return m_aabbMax; } @@ -94,7 +94,8 @@ public: { virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, btCollisionObject* body0,btCollisionObject* body1) { - return new btConvexConcaveCollisionAlgorithm(ci,body0,body1,false); + void* mem = ci.m_dispatcher1->allocateCollisionAlgorithm(sizeof(btConvexConcaveCollisionAlgorithm)); + return new(mem) btConvexConcaveCollisionAlgorithm(ci,body0,body1,false); } }; @@ -102,7 +103,8 @@ public: { virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, btCollisionObject* body0,btCollisionObject* body1) { - return new btConvexConcaveCollisionAlgorithm(ci,body0,body1,true); + void* mem = ci.m_dispatcher1->allocateCollisionAlgorithm(sizeof(btConvexConcaveCollisionAlgorithm)); + return new(mem) btConvexConcaveCollisionAlgorithm(ci,body0,body1,true); } }; diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btConvexConvexAlgorithm.cpp b/extern/bullet2/src/BulletCollision/CollisionDispatch/btConvexConvexAlgorithm.cpp index 9105fe20b49..d1692cdac69 100644 --- a/extern/bullet2/src/BulletCollision/CollisionDispatch/btConvexConvexAlgorithm.cpp +++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btConvexConvexAlgorithm.cpp @@ -48,26 +48,16 @@ subject to the following restrictions: -btConvexConvexAlgorithm::CreateFunc::CreateFunc() -{ - m_ownsSolvers = true; - m_simplexSolver = new btVoronoiSimplexSolver(); - m_pdSolver = new btGjkEpaPenetrationDepthSolver; -} + btConvexConvexAlgorithm::CreateFunc::CreateFunc(btSimplexSolverInterface* simplexSolver, btConvexPenetrationDepthSolver* pdSolver) { - m_ownsSolvers = false; m_simplexSolver = simplexSolver; m_pdSolver = pdSolver; } btConvexConvexAlgorithm::CreateFunc::~CreateFunc() { - if (m_ownsSolvers){ - delete m_simplexSolver; - delete m_pdSolver; - } } btConvexConvexAlgorithm::btConvexConvexAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* body0,btCollisionObject* body1,btSimplexSolverInterface* simplexSolver, btConvexPenetrationDepthSolver* pdSolver) @@ -152,6 +142,11 @@ void btConvexConvexAlgorithm ::processCollision (btCollisionObject* body0,btColl m_gjkPairDetector.getClosestPoints(input,*resultOut,dispatchInfo.m_debugDraw); #endif + if (m_ownManifold) + { + resultOut->refreshContactPoints(); + } + } diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btConvexConvexAlgorithm.h b/extern/bullet2/src/BulletCollision/CollisionDispatch/btConvexConvexAlgorithm.h index cbea9a92b75..ca58bce25f1 100644 --- a/extern/bullet2/src/BulletCollision/CollisionDispatch/btConvexConvexAlgorithm.h +++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btConvexConvexAlgorithm.h @@ -16,12 +16,13 @@ subject to the following restrictions: #ifndef CONVEX_CONVEX_ALGORITHM_H #define CONVEX_CONVEX_ALGORITHM_H -#include "../BroadphaseCollision/btCollisionAlgorithm.h" -#include "../NarrowPhaseCollision/btGjkPairDetector.h" -#include "../NarrowPhaseCollision/btPersistentManifold.h" -#include "../BroadphaseCollision/btBroadphaseProxy.h" -#include "../NarrowPhaseCollision/btVoronoiSimplexSolver.h" +#include "BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h" +#include "BulletCollision/NarrowPhaseCollision/btGjkPairDetector.h" +#include "BulletCollision/NarrowPhaseCollision/btPersistentManifold.h" +#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" +#include "BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.h" #include "btCollisionCreateFunc.h" +#include "btCollisionDispatcher.h" class btConvexPenetrationDepthSolver; @@ -58,15 +59,15 @@ public: { btConvexPenetrationDepthSolver* m_pdSolver; btSimplexSolverInterface* m_simplexSolver; - bool m_ownsSolvers; CreateFunc(btSimplexSolverInterface* simplexSolver, btConvexPenetrationDepthSolver* pdSolver); - CreateFunc(); + virtual ~CreateFunc(); virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, btCollisionObject* body0,btCollisionObject* body1) { - return new btConvexConvexAlgorithm(ci.m_manifold,ci,body0,body1,m_simplexSolver,m_pdSolver); + void* mem = ci.m_dispatcher1->allocateCollisionAlgorithm(sizeof(btConvexConvexAlgorithm)); + return new(mem) btConvexConvexAlgorithm(ci.m_manifold,ci,body0,body1,m_simplexSolver,m_pdSolver); } }; diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btDefaultCollisionConfiguration.cpp b/extern/bullet2/src/BulletCollision/CollisionDispatch/btDefaultCollisionConfiguration.cpp new file mode 100644 index 00000000000..661270b9bcb --- /dev/null +++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btDefaultCollisionConfiguration.cpp @@ -0,0 +1,237 @@ + +/* +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 "btDefaultCollisionConfiguration.h" + +#include "BulletCollision/CollisionDispatch/btConvexConvexAlgorithm.h" +#include "BulletCollision/CollisionDispatch/btEmptyCollisionAlgorithm.h" +#include "BulletCollision/CollisionDispatch/btConvexConcaveCollisionAlgorithm.h" +#include "BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.h" +#include "BulletCollision/CollisionDispatch/btSphereSphereCollisionAlgorithm.h" +#include "BulletCollision/CollisionDispatch/btSphereBoxCollisionAlgorithm.h" +#include "BulletCollision/CollisionDispatch/btSphereTriangleCollisionAlgorithm.h" +#include "BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.h" +#include "BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.h" + + + +#include "LinearMath/btStackAlloc.h" +#include "LinearMath/btPoolAllocator.h" + + + +#define DEFAULT_MAX_OVERLAPPING_PAIRS 65535 +#define DEFAULT_STACK_ALLOCATOR_SIZE (5*1024*1024) + + +btDefaultCollisionConfiguration::btDefaultCollisionConfiguration(btStackAlloc* stackAlloc,btPoolAllocator* persistentManifoldPool,btPoolAllocator* collisionAlgorithmPool) +{ + + void* mem = btAlignedAlloc(sizeof(btVoronoiSimplexSolver),16); + m_simplexSolver = new (mem)btVoronoiSimplexSolver(); + mem = btAlignedAlloc(sizeof(btGjkEpaPenetrationDepthSolver),16); + m_pdSolver = new (mem)btGjkEpaPenetrationDepthSolver; + + //default CreationFunctions, filling the m_doubleDispatch table + mem = btAlignedAlloc(sizeof(btConvexConvexAlgorithm::CreateFunc),16); + m_convexConvexCreateFunc = new(mem) btConvexConvexAlgorithm::CreateFunc(m_simplexSolver,m_pdSolver); + mem = btAlignedAlloc(sizeof(btConvexConcaveCollisionAlgorithm::CreateFunc),16); + m_convexConcaveCreateFunc = new (mem)btConvexConcaveCollisionAlgorithm::CreateFunc; + mem = btAlignedAlloc(sizeof(btConvexConcaveCollisionAlgorithm::CreateFunc),16); + m_swappedConvexConcaveCreateFunc = new (mem)btConvexConcaveCollisionAlgorithm::SwappedCreateFunc; + mem = btAlignedAlloc(sizeof(btCompoundCollisionAlgorithm::CreateFunc),16); + m_compoundCreateFunc = new (mem)btCompoundCollisionAlgorithm::CreateFunc; + mem = btAlignedAlloc(sizeof(btCompoundCollisionAlgorithm::SwappedCreateFunc),16); + m_swappedCompoundCreateFunc = new (mem)btCompoundCollisionAlgorithm::SwappedCreateFunc; + mem = btAlignedAlloc(sizeof(btEmptyAlgorithm::CreateFunc),16); + m_emptyCreateFunc = new(mem) btEmptyAlgorithm::CreateFunc; + + mem = btAlignedAlloc(sizeof(btSphereSphereCollisionAlgorithm::CreateFunc),16); + m_sphereSphereCF = new(mem) btSphereSphereCollisionAlgorithm::CreateFunc; + mem = btAlignedAlloc(sizeof(btSphereBoxCollisionAlgorithm::CreateFunc),16); + m_sphereBoxCF = new(mem) btSphereBoxCollisionAlgorithm::CreateFunc; + mem = btAlignedAlloc(sizeof(btSphereBoxCollisionAlgorithm::CreateFunc),16); + m_boxSphereCF = new (mem)btSphereBoxCollisionAlgorithm::CreateFunc; + m_boxSphereCF->m_swapped = true; + mem = btAlignedAlloc(sizeof(btSphereTriangleCollisionAlgorithm::CreateFunc),16); + m_sphereTriangleCF = new (mem)btSphereTriangleCollisionAlgorithm::CreateFunc; + mem = btAlignedAlloc(sizeof(btSphereTriangleCollisionAlgorithm::CreateFunc),16); + m_triangleSphereCF = new (mem)btSphereTriangleCollisionAlgorithm::CreateFunc; + m_triangleSphereCF->m_swapped = true; + + + ///calculate maximum element size, big enough to fit any collision algorithm in the memory pool + int maxSize = sizeof(btConvexConvexAlgorithm); + int maxSize2 = sizeof(btConvexConcaveCollisionAlgorithm); + int maxSize3 = sizeof(btCompoundCollisionAlgorithm); + int maxSize4 = sizeof(btEmptyAlgorithm); + + int collisionAlgorithmMaxElementSize = btMax(maxSize,maxSize2); + collisionAlgorithmMaxElementSize = btMax(collisionAlgorithmMaxElementSize,maxSize3); + collisionAlgorithmMaxElementSize = btMax(collisionAlgorithmMaxElementSize,maxSize4); + + if (stackAlloc) + { + m_ownsStackAllocator = false; + this->m_stackAlloc = stackAlloc; + } else + { + m_ownsStackAllocator = true; + void* mem = btAlignedAlloc(sizeof(btStackAlloc),16); + m_stackAlloc = new(mem)btStackAlloc(DEFAULT_STACK_ALLOCATOR_SIZE); + } + + if (persistentManifoldPool) + { + m_ownsPersistentManifoldPool = false; + m_persistentManifoldPool = persistentManifoldPool; + } else + { + m_ownsPersistentManifoldPool = true; + void* mem = btAlignedAlloc(sizeof(btPoolAllocator),16); + m_persistentManifoldPool = new (mem) btPoolAllocator(sizeof(btPersistentManifold),DEFAULT_MAX_OVERLAPPING_PAIRS); + } + + if (collisionAlgorithmPool) + { + m_ownsCollisionAlgorithmPool = false; + m_collisionAlgorithmPool = collisionAlgorithmPool; + } else + { + m_ownsCollisionAlgorithmPool = true; + void* mem = btAlignedAlloc(sizeof(btPoolAllocator),16); + m_collisionAlgorithmPool = new(mem) btPoolAllocator(collisionAlgorithmMaxElementSize,DEFAULT_MAX_OVERLAPPING_PAIRS); + } + + +} + +btDefaultCollisionConfiguration::~btDefaultCollisionConfiguration() +{ + if (m_ownsStackAllocator) + { + m_stackAlloc->destroy(); + m_stackAlloc->~btStackAlloc(); + btAlignedFree(m_stackAlloc); + } + if (m_ownsCollisionAlgorithmPool) + { + m_collisionAlgorithmPool->~btPoolAllocator(); + btAlignedFree(m_collisionAlgorithmPool); + } + if (m_ownsPersistentManifoldPool) + { + m_persistentManifoldPool->~btPoolAllocator(); + btAlignedFree(m_persistentManifoldPool); + } + + m_convexConvexCreateFunc->~btCollisionAlgorithmCreateFunc(); + btAlignedFree( m_convexConvexCreateFunc); + + m_convexConcaveCreateFunc->~btCollisionAlgorithmCreateFunc(); + btAlignedFree( m_convexConcaveCreateFunc); + m_swappedConvexConcaveCreateFunc->~btCollisionAlgorithmCreateFunc(); + btAlignedFree( m_swappedConvexConcaveCreateFunc); + + m_compoundCreateFunc->~btCollisionAlgorithmCreateFunc(); + btAlignedFree( m_compoundCreateFunc); + + m_swappedCompoundCreateFunc->~btCollisionAlgorithmCreateFunc(); + btAlignedFree( m_swappedCompoundCreateFunc); + + m_emptyCreateFunc->~btCollisionAlgorithmCreateFunc(); + btAlignedFree( m_emptyCreateFunc); + + m_sphereSphereCF->~btCollisionAlgorithmCreateFunc(); + btAlignedFree( m_sphereSphereCF); + + m_sphereBoxCF->~btCollisionAlgorithmCreateFunc(); + btAlignedFree( m_sphereBoxCF); + m_boxSphereCF->~btCollisionAlgorithmCreateFunc(); + btAlignedFree( m_boxSphereCF); + m_sphereTriangleCF->~btCollisionAlgorithmCreateFunc(); + btAlignedFree( m_sphereTriangleCF); + m_triangleSphereCF->~btCollisionAlgorithmCreateFunc(); + btAlignedFree( m_triangleSphereCF); + + m_simplexSolver->~btVoronoiSimplexSolver(); + btAlignedFree(m_simplexSolver); + m_pdSolver->~btGjkEpaPenetrationDepthSolver(); + btAlignedFree(m_pdSolver); + + +} + + +btCollisionAlgorithmCreateFunc* btDefaultCollisionConfiguration::getCollisionAlgorithmCreateFunc(int proxyType0,int proxyType1) +{ + + + if ((proxyType0 == SPHERE_SHAPE_PROXYTYPE) && (proxyType1==SPHERE_SHAPE_PROXYTYPE)) + { + return m_sphereSphereCF; + } + + if ((proxyType0 == SPHERE_SHAPE_PROXYTYPE) && (proxyType1==BOX_SHAPE_PROXYTYPE)) + { + return m_sphereBoxCF; + } + + if ((proxyType0 == BOX_SHAPE_PROXYTYPE ) && (proxyType1==SPHERE_SHAPE_PROXYTYPE)) + { + return m_boxSphereCF; + } + + if ((proxyType0 == SPHERE_SHAPE_PROXYTYPE ) && (proxyType1==TRIANGLE_SHAPE_PROXYTYPE)) + { + return m_sphereTriangleCF; + } + + if ((proxyType0 == TRIANGLE_SHAPE_PROXYTYPE ) && (proxyType1==SPHERE_SHAPE_PROXYTYPE)) + { + return m_triangleSphereCF; + } + + + if (btBroadphaseProxy::isConvex(proxyType0) && btBroadphaseProxy::isConvex(proxyType1)) + { + return m_convexConvexCreateFunc; + } + + if (btBroadphaseProxy::isConvex(proxyType0) && btBroadphaseProxy::isConcave(proxyType1)) + { + return m_convexConcaveCreateFunc; + } + + if (btBroadphaseProxy::isConvex(proxyType1) && btBroadphaseProxy::isConcave(proxyType0)) + { + return m_swappedConvexConcaveCreateFunc; + } + + if (btBroadphaseProxy::isCompound(proxyType0)) + { + return m_compoundCreateFunc; + } else + { + if (btBroadphaseProxy::isCompound(proxyType1)) + { + return m_swappedCompoundCreateFunc; + } + } + + //failed to find an algorithm + return m_emptyCreateFunc; +} diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btDefaultCollisionConfiguration.h b/extern/bullet2/src/BulletCollision/CollisionDispatch/btDefaultCollisionConfiguration.h new file mode 100644 index 00000000000..2e99f1db18f --- /dev/null +++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btDefaultCollisionConfiguration.h @@ -0,0 +1,87 @@ +/* +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 BT_DEFAULT_COLLISION_CONFIGURATION +#define BT_DEFAULT_COLLISION_CONFIGURATION + +#include "btCollisionConfiguration.h" +class btVoronoiSimplexSolver; +class btGjkEpaPenetrationDepthSolver; + + +///btCollisionConfiguration allows to configure Bullet collision detection +///stack allocator, pool memory allocators +///todo: describe the meaning +class btDefaultCollisionConfiguration : public btCollisionConfiguration +{ + + int m_persistentManifoldPoolSize; + + btStackAlloc* m_stackAlloc; + bool m_ownsStackAllocator; + + btPoolAllocator* m_persistentManifoldPool; + bool m_ownsPersistentManifoldPool; + + btPoolAllocator* m_collisionAlgorithmPool; + bool m_ownsCollisionAlgorithmPool; + + //default simplex/penetration depth solvers + btVoronoiSimplexSolver* m_simplexSolver; + btGjkEpaPenetrationDepthSolver* m_pdSolver; + + //default CreationFunctions, filling the m_doubleDispatch table + btCollisionAlgorithmCreateFunc* m_convexConvexCreateFunc; + btCollisionAlgorithmCreateFunc* m_convexConcaveCreateFunc; + btCollisionAlgorithmCreateFunc* m_swappedConvexConcaveCreateFunc; + btCollisionAlgorithmCreateFunc* m_compoundCreateFunc; + btCollisionAlgorithmCreateFunc* m_swappedCompoundCreateFunc; + btCollisionAlgorithmCreateFunc* m_emptyCreateFunc; + btCollisionAlgorithmCreateFunc* m_sphereSphereCF; + btCollisionAlgorithmCreateFunc* m_sphereBoxCF; + btCollisionAlgorithmCreateFunc* m_boxSphereCF; + btCollisionAlgorithmCreateFunc* m_sphereTriangleCF; + btCollisionAlgorithmCreateFunc* m_triangleSphereCF; + +public: + + btDefaultCollisionConfiguration(btStackAlloc* stackAlloc=0,btPoolAllocator* persistentManifoldPool=0,btPoolAllocator* collisionAlgorithmPool=0); + + virtual ~btDefaultCollisionConfiguration(); + + ///memory pools + virtual btPoolAllocator* getPersistentManifoldPool() + { + return m_persistentManifoldPool; + } + + virtual btPoolAllocator* getCollisionAlgorithmPool() + { + return m_collisionAlgorithmPool; + } + + virtual btStackAlloc* getStackAllocator() + { + return m_stackAlloc; + } + + + btCollisionAlgorithmCreateFunc* getCollisionAlgorithmCreateFunc(int proxyType0,int proxyType1); + + +}; + +#endif //BT_DEFAULT_COLLISION_CONFIGURATION + diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btEmptyCollisionAlgorithm.h b/extern/bullet2/src/BulletCollision/CollisionDispatch/btEmptyCollisionAlgorithm.h index b1a193d2cfd..89e7080780c 100644 --- a/extern/bullet2/src/BulletCollision/CollisionDispatch/btEmptyCollisionAlgorithm.h +++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btEmptyCollisionAlgorithm.h @@ -15,8 +15,9 @@ subject to the following restrictions: #ifndef EMPTY_ALGORITH #define EMPTY_ALGORITH -#include "../BroadphaseCollision/btCollisionAlgorithm.h" +#include "BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h" #include "btCollisionCreateFunc.h" +#include "btCollisionDispatcher.h" #define ATTRIBUTE_ALIGNED(a) @@ -39,7 +40,8 @@ public: { (void)body0; (void)body1; - return new btEmptyAlgorithm(ci); + void* mem = ci.m_dispatcher1->allocateCollisionAlgorithm(sizeof(btEmptyAlgorithm)); + return new(mem) btEmptyAlgorithm(ci); } }; diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btManifoldResult.cpp b/extern/bullet2/src/BulletCollision/CollisionDispatch/btManifoldResult.cpp index 490acc0b611..61c4c231da4 100644 --- a/extern/bullet2/src/BulletCollision/CollisionDispatch/btManifoldResult.cpp +++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btManifoldResult.cpp @@ -79,12 +79,25 @@ void btManifoldResult::addContactPoint(const btVector3& normalOnBInWorld,const b } btManifoldPoint newPt(localA,localB,normalOnBInWorld,depth); - + newPt.m_positionWorldOnA = pointA; + newPt.m_positionWorldOnB = pointInWorld; + int insertIndex = m_manifoldPtr->getCacheEntry(newPt); newPt.m_combinedFriction = calculateCombinedFriction(m_body0,m_body1); newPt.m_combinedRestitution = calculateCombinedRestitution(m_body0,m_body1); + + ///todo, check this for any side effects + if (insertIndex >= 0) + { + //const btManifoldPoint& oldPoint = m_manifoldPtr->getContactPoint(insertIndex); + m_manifoldPtr->replaceContactPoint(newPt,insertIndex); + } else + { + m_manifoldPtr->AddManifoldPoint(newPt); + } + //User can override friction and/or restitution if (gContactAddedCallback && //and if either of the two bodies requires custom material @@ -97,13 +110,5 @@ void btManifoldResult::addContactPoint(const btVector3& normalOnBInWorld,const b (*gContactAddedCallback)(newPt,obj0,m_partId0,m_index0,obj1,m_partId1,m_index1); } - if (insertIndex >= 0) - { - //const btManifoldPoint& oldPoint = m_manifoldPtr->getContactPoint(insertIndex); - m_manifoldPtr->replaceContactPoint(newPt,insertIndex); - } else - { - m_manifoldPtr->AddManifoldPoint(newPt); - } } diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btManifoldResult.h b/extern/bullet2/src/BulletCollision/CollisionDispatch/btManifoldResult.h index 77192625513..5aac9a46f6a 100644 --- a/extern/bullet2/src/BulletCollision/CollisionDispatch/btManifoldResult.h +++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btManifoldResult.h @@ -18,12 +18,12 @@ subject to the following restrictions: #define MANIFOLD_RESULT_H class btCollisionObject; -class btPersistentManifold; +#include "BulletCollision/NarrowPhaseCollision/btPersistentManifold.h" class btManifoldPoint; #include "BulletCollision/NarrowPhaseCollision/btDiscreteCollisionDetectorInterface.h" -#include "../../LinearMath/btTransform.h" +#include "LinearMath/btTransform.h" typedef bool (*ContactAddedCallback)(btManifoldPoint& cp, const btCollisionObject* colObj0,int partId0,int index0,const btCollisionObject* colObj1,int partId1,int index1); extern ContactAddedCallback gContactAddedCallback; @@ -60,6 +60,15 @@ public: m_manifoldPtr = manifoldPtr; } + const btPersistentManifold* getPersistentManifold() const + { + return m_manifoldPtr; + } + btPersistentManifold* getPersistentManifold() + { + return m_manifoldPtr; + } + virtual void setShapeIdentifiers(int partId0,int index0, int partId1,int index1) { m_partId0=partId0; @@ -70,6 +79,22 @@ public: virtual void addContactPoint(const btVector3& normalOnBInWorld,const btVector3& pointInWorld,btScalar depth); + SIMD_FORCE_INLINE void refreshContactPoints() + { + btAssert(m_manifoldPtr); + if (!m_manifoldPtr->getNumContacts()) + return; + + bool isSwapped = m_manifoldPtr->getBody0() != m_body0; + + if (isSwapped) + { + m_manifoldPtr->refreshContactPoints(m_rootTransB,m_rootTransA); + } else + { + m_manifoldPtr->refreshContactPoints(m_rootTransA,m_rootTransB); + } + } }; diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btSimulationIslandManager.cpp b/extern/bullet2/src/BulletCollision/CollisionDispatch/btSimulationIslandManager.cpp index ac2e8554c3a..6c42d1706ff 100644 --- a/extern/bullet2/src/BulletCollision/CollisionDispatch/btSimulationIslandManager.cpp +++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btSimulationIslandManager.cpp @@ -25,17 +25,17 @@ void btSimulationIslandManager::initUnionFind(int n) } -void btSimulationIslandManager::findUnions(btDispatcher* dispatcher) +void btSimulationIslandManager::findUnions(btDispatcher* dispatcher,btCollisionWorld* colWorld) { { - for (int i=0;igetNumManifolds();i++) - { - const btPersistentManifold* manifold = dispatcher->getManifoldByIndexInternal(i); - //static objects (invmass btScalar(0.)) don't merge ! + btBroadphasePair* pairPtr = colWorld->getPairCache()->getOverlappingPairArrayPtr(); - const btCollisionObject* colObj0 = static_cast(manifold->getBody0()); - const btCollisionObject* colObj1 = static_cast(manifold->getBody1()); + for (int i=0;igetPairCache()->getNumOverlappingPairs();i++) + { + const btBroadphasePair& collisionPair = pairPtr[i]; + btCollisionObject* colObj0 = (btCollisionObject*)collisionPair.m_pProxy0->m_clientObject; + btCollisionObject* colObj1 = (btCollisionObject*)collisionPair.m_pProxy1->m_clientObject; if (((colObj0) && ((colObj0)->mergesSimulationIslands())) && ((colObj1) && ((colObj1)->mergesSimulationIslands()))) @@ -71,7 +71,7 @@ void btSimulationIslandManager::updateActivationState(btCollisionWorld* colWorld } // do the union find - findUnions(dispatcher); + findUnions(dispatcher,colWorld); @@ -138,19 +138,6 @@ class btPersistentManifoldSortPredicate void btSimulationIslandManager::buildAndProcessIslands(btDispatcher* dispatcher,btCollisionObjectArray& collisionObjects, IslandCallback* callback) { - - - /*if (0) - { - int maxNumManifolds = dispatcher->getNumManifolds(); - btCollisionDispatcher* colDis = (btCollisionDispatcher*)dispatcher; - btPersistentManifold** manifold = colDis->getInternalManifoldPointer(); - callback->ProcessIsland(&collisionObjects[0],collisionObjects.size(),manifold,maxNumManifolds, 0); - return; - } - */ - - BEGIN_PROFILE("islandUnionFindAndHeapSort"); //we are going to sort the unionfind array, and store the element id in the size @@ -247,11 +234,17 @@ void btSimulationIslandManager::buildAndProcessIslands(btDispatcher* dispatcher, } } - btAlignedObjectArray islandmanifold; + int i; int maxNumManifolds = dispatcher->getNumManifolds(); - islandmanifold.reserve(maxNumManifolds); +#define SPLIT_ISLANDS 1 +#ifdef SPLIT_ISLANDS + + +#endif //SPLIT_ISLANDS + + for (i=0;igetManifoldByIndexInternal(i); @@ -265,29 +258,35 @@ void btSimulationIslandManager::buildAndProcessIslands(btDispatcher* dispatcher, { //kinematic objects don't merge islands, but wake up all connected objects - if (colObj0->isStaticOrKinematicObject() && colObj0->getActivationState() != ISLAND_SLEEPING) + if (colObj0->isKinematicObject() && colObj0->getActivationState() != ISLAND_SLEEPING) { colObj1->activate(); } - if (colObj1->isStaticOrKinematicObject() && colObj1->getActivationState() != ISLAND_SLEEPING) + if (colObj1->isKinematicObject() && colObj1->getActivationState() != ISLAND_SLEEPING) { colObj0->activate(); } - - //filtering for response +#ifdef SPLIT_ISLANDS + // //filtering for response if (dispatcher->needsResponse(colObj0,colObj1)) - islandmanifold.push_back(manifold); + m_islandmanifold.push_back(manifold); +#endif //SPLIT_ISLANDS } } - int numManifolds = int (islandmanifold.size()); - +#ifndef SPLIT_ISLANDS + btPersistentManifold** manifold = dispatcher->getInternalManifoldPointer(); + + callback->ProcessIsland(&collisionObjects[0],collisionObjects.size(),manifold,maxNumManifolds, -1); +#else // Sort manifolds, based on islands // Sort the vector using predicate and std::sort //std::sort(islandmanifold.begin(), islandmanifold.end(), btPersistentManifoldSortPredicate); + int numManifolds = int (m_islandmanifold.size()); + //we should do radix sort, it it much faster (O(n) instead of O (n log2(n)) - islandmanifold.heapSort(btPersistentManifoldSortPredicate()); + m_islandmanifold.heapSort(btPersistentManifoldSortPredicate()); //now process all active islands (sets of manifolds for now) @@ -298,8 +297,9 @@ void btSimulationIslandManager::buildAndProcessIslands(btDispatcher* dispatcher, END_PROFILE("islandUnionFindAndHeapSort"); - btAlignedObjectArray islandBodies; + +// printf("Start Islands\n"); //traverse the simulation islands, and call the solver, unless all objects are sleeping/deactivated for ( startIslandIndex=0;startIslandIndexisActive()) islandSleeping = true; } @@ -325,12 +325,12 @@ void btSimulationIslandManager::buildAndProcessIslands(btDispatcher* dispatcher, if (startManifoldIndexProcessIsland(&islandBodies[0],islandBodies.size(),startManifold,numIslandManifolds, islandId); + callback->ProcessIsland(&m_islandBodies[0],m_islandBodies.size(),startManifold,numIslandManifolds, islandId); +// printf("Island callback of size:%d bodies, %d manifolds\n",islandBodies.size(),numIslandManifolds); } if (numIslandManifolds) @@ -350,8 +351,9 @@ void btSimulationIslandManager::buildAndProcessIslands(btDispatcher* dispatcher, startManifoldIndex = endManifoldIndex; } - islandBodies.resize(0); + m_islandBodies.resize(0); } +#endif //SPLIT_ISLANDS - + m_islandmanifold.resize(0); } diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btSimulationIslandManager.h b/extern/bullet2/src/BulletCollision/CollisionDispatch/btSimulationIslandManager.h index d91ed1c20eb..01a059b5fbe 100644 --- a/extern/bullet2/src/BulletCollision/CollisionDispatch/btSimulationIslandManager.h +++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btSimulationIslandManager.h @@ -16,18 +16,26 @@ subject to the following restrictions: #ifndef SIMULATION_ISLAND_MANAGER_H #define SIMULATION_ISLAND_MANAGER_H -#include "../CollisionDispatch/btUnionFind.h" +#include "BulletCollision/CollisionDispatch/btUnionFind.h" #include "btCollisionCreateFunc.h" +#include "LinearMath/btAlignedObjectArray.h" + class btCollisionObject; class btCollisionWorld; class btDispatcher; +class btPersistentManifold; + ///SimulationIslandManager creates and handles simulation islands, using btUnionFind class btSimulationIslandManager { btUnionFind m_unionFind; + btAlignedObjectArray m_islandmanifold; + btAlignedObjectArray m_islandBodies; + + public: btSimulationIslandManager(); virtual ~btSimulationIslandManager(); @@ -42,7 +50,7 @@ public: virtual void storeIslandActivationState(btCollisionWorld* world); - void findUnions(btDispatcher* dispatcher); + void findUnions(btDispatcher* dispatcher,btCollisionWorld* colWorld); diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereBoxCollisionAlgorithm.cpp b/extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereBoxCollisionAlgorithm.cpp index 05556bd34e2..1e4bbce451d 100644 --- a/extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereBoxCollisionAlgorithm.cpp +++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereBoxCollisionAlgorithm.cpp @@ -68,18 +68,25 @@ void btSphereBoxCollisionAlgorithm::processCollision (btCollisionObject* body0,b btScalar dist = getSphereDistance(boxObj,pOnBox,pOnSphere,sphereCenter,radius); + resultOut->setPersistentManifold(m_manifoldPtr); + if (dist < SIMD_EPSILON) { btVector3 normalOnSurfaceB = (pOnBox- pOnSphere).normalize(); /// report a contact. internally this will be kept persistent, and contact reduction is done - resultOut->setPersistentManifold(m_manifoldPtr); resultOut->addContactPoint(normalOnSurfaceB,pOnBox,dist); } - + if (m_ownManifold) + { + if (m_manifoldPtr->getNumContacts()) + { + resultOut->refreshContactPoints(); + } + } } @@ -102,8 +109,8 @@ btScalar btSphereBoxCollisionAlgorithm::getSphereDistance(btCollisionObject* box btVector3 bounds[2]; btBoxShape* boxShape= (btBoxShape*)boxObj->getCollisionShape(); - bounds[0] = -boxShape->getHalfExtents(); - bounds[1] = boxShape->getHalfExtents(); + bounds[0] = -boxShape->getHalfExtentsWithoutMargin(); + bounds[1] = boxShape->getHalfExtentsWithoutMargin(); margins = boxShape->getMargin();//also add sphereShape margin? @@ -209,6 +216,10 @@ btScalar btSphereBoxCollisionAlgorithm::getSpherePenetration( btCollisionObject* btVector3 p0, tmp, prel, n[6], normal; btScalar fSep = btScalar(-10000000.0), fSepThis; + // set p0 and normal to a default value to shup up GCC + p0.setValue(btScalar(0.), btScalar(0.), btScalar(0.)); + normal.setValue(btScalar(0.), btScalar(0.), btScalar(0.)); + n[0].setValue( btScalar(-1.0), btScalar(0.0), btScalar(0.0) ); n[1].setValue( btScalar(0.0), btScalar(-1.0), btScalar(0.0) ); n[2].setValue( btScalar(0.0), btScalar(0.0), btScalar(-1.0) ); diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereBoxCollisionAlgorithm.h b/extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereBoxCollisionAlgorithm.h index 07592909200..b839dc4adb1 100644 --- a/extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereBoxCollisionAlgorithm.h +++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereBoxCollisionAlgorithm.h @@ -16,11 +16,13 @@ subject to the following restrictions: #ifndef SPHERE_BOX_COLLISION_ALGORITHM_H #define SPHERE_BOX_COLLISION_ALGORITHM_H -#include "../BroadphaseCollision/btCollisionAlgorithm.h" -#include "../BroadphaseCollision/btBroadphaseProxy.h" -#include "../CollisionDispatch/btCollisionCreateFunc.h" +#include "BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h" +#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" +#include "BulletCollision/CollisionDispatch/btCollisionCreateFunc.h" class btPersistentManifold; -#include "../../LinearMath/btVector3.h" +#include "btCollisionDispatcher.h" + +#include "LinearMath/btVector3.h" /// btSphereBoxCollisionAlgorithm provides sphere-box collision detection. /// Other features are frame-coherency (persistent data) and collision response. @@ -48,12 +50,13 @@ public: { virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, btCollisionObject* body0,btCollisionObject* body1) { + void* mem = ci.m_dispatcher1->allocateCollisionAlgorithm(sizeof(btSphereBoxCollisionAlgorithm)); if (!m_swapped) { - return new btSphereBoxCollisionAlgorithm(0,ci,body0,body1,false); + return new(mem) btSphereBoxCollisionAlgorithm(0,ci,body0,body1,false); } else { - return new btSphereBoxCollisionAlgorithm(0,ci,body0,body1,true); + return new(mem) btSphereBoxCollisionAlgorithm(0,ci,body0,body1,true); } } }; diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereSphereCollisionAlgorithm.cpp b/extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereSphereCollisionAlgorithm.cpp index 424ff432f84..e7f42647e61 100644 --- a/extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereSphereCollisionAlgorithm.cpp +++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereSphereCollisionAlgorithm.cpp @@ -46,6 +46,8 @@ void btSphereSphereCollisionAlgorithm::processCollision (btCollisionObject* col0 if (!m_manifoldPtr) return; + resultOut->setPersistentManifold(m_manifoldPtr); + btSphereShape* sphere0 = (btSphereShape*)col0->getCollisionShape(); btSphereShape* sphere1 = (btSphereShape*)col1->getCollisionShape(); @@ -54,10 +56,13 @@ void btSphereSphereCollisionAlgorithm::processCollision (btCollisionObject* col0 btScalar radius0 = sphere0->getRadius(); btScalar radius1 = sphere1->getRadius(); + m_manifoldPtr->clearManifold(); + ///iff distance positive, don't generate a new contact if ( len > (radius0+radius1)) + { return; - + } ///distance (negative means penetration) btScalar dist = len - (radius0+radius1); @@ -68,9 +73,12 @@ void btSphereSphereCollisionAlgorithm::processCollision (btCollisionObject* col0 btVector3 pos1 = col1->getWorldTransform().getOrigin() + radius1* normalOnSurfaceB; /// report a contact. internally this will be kept persistent, and contact reduction is done - resultOut->setPersistentManifold(m_manifoldPtr); + + resultOut->addContactPoint(normalOnSurfaceB,pos1,dist); + //no resultOut->refreshContactPoints(); needed, because of clearManifold (all points are new) + } btScalar btSphereSphereCollisionAlgorithm::calculateTimeOfImpact(btCollisionObject* col0,btCollisionObject* col1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut) diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereSphereCollisionAlgorithm.h b/extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereSphereCollisionAlgorithm.h index 7a19ff31edf..bcaa0d303a9 100644 --- a/extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereSphereCollisionAlgorithm.h +++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereSphereCollisionAlgorithm.h @@ -16,9 +16,11 @@ subject to the following restrictions: #ifndef SPHERE_SPHERE_COLLISION_ALGORITHM_H #define SPHERE_SPHERE_COLLISION_ALGORITHM_H -#include "../BroadphaseCollision/btCollisionAlgorithm.h" -#include "../BroadphaseCollision/btBroadphaseProxy.h" -#include "../CollisionDispatch/btCollisionCreateFunc.h" +#include "BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h" +#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" +#include "BulletCollision/CollisionDispatch/btCollisionCreateFunc.h" +#include "btCollisionDispatcher.h" + class btPersistentManifold; /// btSphereSphereCollisionAlgorithm provides sphere-sphere collision detection. @@ -46,7 +48,8 @@ public: { virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, btCollisionObject* body0,btCollisionObject* body1) { - return new btSphereSphereCollisionAlgorithm(0,ci,body0,body1); + void* mem = ci.m_dispatcher1->allocateCollisionAlgorithm(sizeof(btSphereSphereCollisionAlgorithm)); + return new(mem) btSphereSphereCollisionAlgorithm(0,ci,body0,body1); } }; diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereTriangleCollisionAlgorithm.cpp b/extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereTriangleCollisionAlgorithm.cpp index b011b707e3f..5d50bfed7a1 100644 --- a/extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereTriangleCollisionAlgorithm.cpp +++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereTriangleCollisionAlgorithm.cpp @@ -48,8 +48,11 @@ void btSphereTriangleCollisionAlgorithm::processCollision (btCollisionObject* co if (!m_manifoldPtr) return; - btSphereShape* sphere = (btSphereShape*)col0->getCollisionShape(); - btTriangleShape* triangle = (btTriangleShape*)col1->getCollisionShape(); + btCollisionObject* sphereObj = m_swapped? col1 : col0; + btCollisionObject* triObj = m_swapped? col0 : col1; + + btSphereShape* sphere = (btSphereShape*)sphereObj->getCollisionShape(); + btTriangleShape* triangle = (btTriangleShape*)triObj->getCollisionShape(); /// report a contact. internally this will be kept persistent, and contact reduction is done resultOut->setPersistentManifold(m_manifoldPtr); @@ -62,6 +65,9 @@ void btSphereTriangleCollisionAlgorithm::processCollision (btCollisionObject* co detector.getClosestPoints(input,*resultOut,dispatchInfo.m_debugDraw); + if (m_ownManifold) + resultOut->refreshContactPoints(); + } btScalar btSphereTriangleCollisionAlgorithm::calculateTimeOfImpact(btCollisionObject* col0,btCollisionObject* col1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut) diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereTriangleCollisionAlgorithm.h b/extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereTriangleCollisionAlgorithm.h index 57c6e6af619..4aefc0c43a5 100644 --- a/extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereTriangleCollisionAlgorithm.h +++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereTriangleCollisionAlgorithm.h @@ -16,10 +16,11 @@ subject to the following restrictions: #ifndef SPHERE_TRIANGLE_COLLISION_ALGORITHM_H #define SPHERE_TRIANGLE_COLLISION_ALGORITHM_H -#include "../BroadphaseCollision/btCollisionAlgorithm.h" -#include "../BroadphaseCollision/btBroadphaseProxy.h" -#include "../CollisionDispatch/btCollisionCreateFunc.h" +#include "BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h" +#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" +#include "BulletCollision/CollisionDispatch/btCollisionCreateFunc.h" class btPersistentManifold; +#include "btCollisionDispatcher.h" /// btSphereSphereCollisionAlgorithm provides sphere-sphere collision detection. /// Other features are frame-coherency (persistent data) and collision response. @@ -49,7 +50,9 @@ public: virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, btCollisionObject* body0,btCollisionObject* body1) { - return new btSphereTriangleCollisionAlgorithm(ci.m_manifold,ci,body0,body1,m_swapped); + void* mem = ci.m_dispatcher1->allocateCollisionAlgorithm(sizeof(btSphereTriangleCollisionAlgorithm)); + + return new(mem) btSphereTriangleCollisionAlgorithm(ci.m_manifold,ci,body0,body1,m_swapped); } }; diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btUnionFind.cpp b/extern/bullet2/src/BulletCollision/CollisionDispatch/btUnionFind.cpp index 62254335796..c81be8aa75c 100644 --- a/extern/bullet2/src/BulletCollision/CollisionDispatch/btUnionFind.cpp +++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btUnionFind.cpp @@ -18,6 +18,7 @@ subject to the following restrictions: + btUnionFind::~btUnionFind() { Free(); diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btUnionFind.h b/extern/bullet2/src/BulletCollision/CollisionDispatch/btUnionFind.h index 236cc33b94f..820c8bc858e 100644 --- a/extern/bullet2/src/BulletCollision/CollisionDispatch/btUnionFind.h +++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btUnionFind.h @@ -16,7 +16,7 @@ subject to the following restrictions: #ifndef UNION_FIND_H #define UNION_FIND_H -#include "../../LinearMath/btAlignedObjectArray.h" +#include "LinearMath/btAlignedObjectArray.h" #define USE_PATH_COMPRESSION 1 @@ -46,11 +46,11 @@ class btUnionFind void reset(int N); - inline int getNumElements() const + SIMD_FORCE_INLINE int getNumElements() const { return int(m_elements.size()); } - inline bool isRoot(int x) const + SIMD_FORCE_INLINE bool isRoot(int x) const { return (x == m_elements[x].m_id); } diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btBoxShape.cpp b/extern/bullet2/src/BulletCollision/CollisionShapes/btBoxShape.cpp index 636b0046c13..adac455bbcb 100644 --- a/extern/bullet2/src/BulletCollision/CollisionShapes/btBoxShape.cpp +++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btBoxShape.cpp @@ -15,16 +15,13 @@ subject to the following restrictions: #include "btBoxShape.h" -btVector3 btBoxShape::getHalfExtents() const -{ - return m_implicitShapeDimensions * m_localScaling; -} + //{ void btBoxShape::getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const { - btVector3 halfExtents = getHalfExtents(); + const btVector3& halfExtents = getHalfExtentsWithoutMargin(); btMatrix3x3 abs_b = t.getBasis().absolute(); btPoint3 center = t.getOrigin(); @@ -40,10 +37,10 @@ void btBoxShape::getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabb } -void btBoxShape::calculateLocalInertia(btScalar mass,btVector3& inertia) +void btBoxShape::calculateLocalInertia(btScalar mass,btVector3& inertia) const { //btScalar margin = btScalar(0.); - btVector3 halfExtents = getHalfExtents(); + btVector3 halfExtents = getHalfExtentsWithMargin(); btScalar lx=btScalar(2.)*(halfExtents.x()); btScalar ly=btScalar(2.)*(halfExtents.y()); diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btBoxShape.h b/extern/bullet2/src/BulletCollision/CollisionShapes/btBoxShape.h index bc42f146c7c..98f1bd34b09 100644 --- a/extern/bullet2/src/BulletCollision/CollisionShapes/btBoxShape.h +++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btBoxShape.h @@ -18,9 +18,9 @@ subject to the following restrictions: #include "btPolyhedralConvexShape.h" #include "btCollisionMargin.h" -#include "../BroadphaseCollision/btBroadphaseProxy.h" -#include "../../LinearMath/btPoint3.h" -#include "../../LinearMath/btSimdMinMax.h" +#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" +#include "LinearMath/btPoint3.h" +#include "LinearMath/btMinMax.h" ///btBoxShape implements both a feature based (vertex/edge/plane) and implicit (getSupportingVertex) Box class btBoxShape: public btPolyhedralConvexShape @@ -31,47 +31,52 @@ class btBoxShape: public btPolyhedralConvexShape public: - btVector3 getHalfExtents() const; - + btVector3 getHalfExtentsWithMargin() const + { + btVector3 halfExtents = getHalfExtentsWithoutMargin(); + btVector3 margin(getMargin(),getMargin(),getMargin()); + halfExtents += margin; + return halfExtents; + } + + const btVector3& getHalfExtentsWithoutMargin() const + { + return m_implicitShapeDimensions;//changed in Bullet 2.63: assume the scaling and margin are included + } + + virtual int getShapeType() const { return BOX_SHAPE_PROXYTYPE;} virtual btVector3 localGetSupportingVertex(const btVector3& vec) const { + btVector3 halfExtents = getHalfExtentsWithoutMargin(); + btVector3 margin(getMargin(),getMargin(),getMargin()); + halfExtents += margin; - btVector3 halfExtents = getHalfExtents(); - - btVector3 supVertex; - supVertex = btPoint3(vec.x() < btScalar(0.0) ? -halfExtents.x() : halfExtents.x(), - vec.y() < btScalar(0.0) ? -halfExtents.y() : halfExtents.y(), - vec.z() < btScalar(0.0) ? -halfExtents.z() : halfExtents.z()); - - return supVertex; + return btVector3(btFsels(vec.x(), halfExtents.x(), -halfExtents.x()), + btFsels(vec.y(), halfExtents.y(), -halfExtents.y()), + btFsels(vec.z(), halfExtents.z(), -halfExtents.z())); } - virtual inline btVector3 localGetSupportingVertexWithoutMargin(const btVector3& vec)const + SIMD_FORCE_INLINE btVector3 localGetSupportingVertexWithoutMargin(const btVector3& vec)const { - btVector3 halfExtents = getHalfExtents(); - btVector3 margin(getMargin(),getMargin(),getMargin()); - halfExtents -= margin; - - return btVector3(vec.x() < btScalar(0.0) ? -halfExtents.x() : halfExtents.x(), - vec.y() < btScalar(0.0) ? -halfExtents.y() : halfExtents.y(), - vec.z() < btScalar(0.0) ? -halfExtents.z() : halfExtents.z()); + const btVector3& halfExtents = getHalfExtentsWithoutMargin(); + + return btVector3(btFsels(vec.x(), halfExtents.x(), -halfExtents.x()), + btFsels(vec.y(), halfExtents.y(), -halfExtents.y()), + btFsels(vec.z(), halfExtents.z(), -halfExtents.z())); } virtual void batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const { - btVector3 halfExtents = getHalfExtents(); - btVector3 margin(getMargin(),getMargin(),getMargin()); - halfExtents -= margin; - - + const btVector3& halfExtents = getHalfExtentsWithoutMargin(); + for (int i=0;icalculateAabbBruteForce(bvhAabbMin,bvhAabbMax); - m_bvh->build(meshInterface,m_useQuantizedAabbCompression,bvhAabbMin,bvhAabbMax); + + if (buildBvh) + { + void* mem = btAlignedAlloc(sizeof(btOptimizedBvh),16); + m_bvh = new (mem) btOptimizedBvh(); + m_bvh->build(meshInterface,m_useQuantizedAabbCompression,bvhAabbMin,bvhAabbMax); + m_ownsBvh = true; + } #endif //DISABLE_BVH } -btBvhTriangleMeshShape::btBvhTriangleMeshShape(btStridingMeshInterface* meshInterface, bool useQuantizedAabbCompression,const btVector3& bvhAabbMin,const btVector3& bvhAabbMax) -:btTriangleMeshShape(meshInterface),m_useQuantizedAabbCompression(useQuantizedAabbCompression) +btBvhTriangleMeshShape::btBvhTriangleMeshShape(btStridingMeshInterface* meshInterface, bool useQuantizedAabbCompression,const btVector3& bvhAabbMin,const btVector3& bvhAabbMax,bool buildBvh) +:btTriangleMeshShape(meshInterface), +m_bvh(0), +m_useQuantizedAabbCompression(useQuantizedAabbCompression), +m_ownsBvh(false) { //construct bvh from meshInterface #ifndef DISABLE_BVH - m_bvh = new btOptimizedBvh(); - m_bvh->build(meshInterface,m_useQuantizedAabbCompression,bvhAabbMin,bvhAabbMax); + if (buildBvh) + { + void* mem = btAlignedAlloc(sizeof(btOptimizedBvh),16); + m_bvh = new (mem) btOptimizedBvh(); + + m_bvh->build(meshInterface,m_useQuantizedAabbCompression,bvhAabbMin,bvhAabbMax); + m_ownsBvh = true; + } #endif //DISABLE_BVH @@ -67,7 +85,11 @@ void btBvhTriangleMeshShape::refitTree() btBvhTriangleMeshShape::~btBvhTriangleMeshShape() { - delete m_bvh; + if (m_ownsBvh) + { + m_bvh->~btOptimizedBvh(); + btAlignedFree(m_bvh); + } } //perform bvh tree traversal and report overlapping triangles to 'callback' @@ -163,9 +185,14 @@ void btBvhTriangleMeshShape::setLocalScaling(const btVector3& scaling) if ((getLocalScaling() -scaling).length2() > SIMD_EPSILON) { btTriangleMeshShape::setLocalScaling(scaling); - delete m_bvh; + if (m_ownsBvh) + { + m_bvh->~btOptimizedBvh(); + btAlignedFree(m_bvh); + } ///m_localAabbMin/m_localAabbMax is already re-calculated in btTriangleMeshShape. We could just scale aabb, but this needs some more work - m_bvh = new btOptimizedBvh(); + void* mem = btAlignedAlloc(sizeof(btOptimizedBvh),16); + m_bvh = new(mem) btOptimizedBvh(); //rebuild the bvh... m_bvh->build(m_meshInterface,m_useQuantizedAabbCompression,m_localAabbMin,m_localAabbMax); diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btBvhTriangleMeshShape.h b/extern/bullet2/src/BulletCollision/CollisionShapes/btBvhTriangleMeshShape.h index 4914d9f959c..95c73b2441f 100644 --- a/extern/bullet2/src/BulletCollision/CollisionShapes/btBvhTriangleMeshShape.h +++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btBvhTriangleMeshShape.h @@ -18,6 +18,7 @@ subject to the following restrictions: #include "btTriangleMeshShape.h" #include "btOptimizedBvh.h" +#include "LinearMath/btAlignedAllocator.h" ///Bvh Concave triangle mesh is a static-triangle mesh shape with Bounding Volume Hierarchy optimization. ///Uses an interface to access the triangles to allow for sharing graphics/physics triangles. @@ -26,15 +27,18 @@ ATTRIBUTE_ALIGNED16(class) btBvhTriangleMeshShape : public btTriangleMeshShape btOptimizedBvh* m_bvh; bool m_useQuantizedAabbCompression; - bool m_pad[12];////need padding due to alignment + bool m_ownsBvh; + bool m_pad[11];////need padding due to alignment public: - btBvhTriangleMeshShape() :btTriangleMeshShape(0) {}; - btBvhTriangleMeshShape(btStridingMeshInterface* meshInterface, bool useQuantizedAabbCompression); + BT_DECLARE_ALIGNED_ALLOCATOR(); + + btBvhTriangleMeshShape() :btTriangleMeshShape(0),m_bvh(0),m_ownsBvh(false) {}; + btBvhTriangleMeshShape(btStridingMeshInterface* meshInterface, bool useQuantizedAabbCompression, bool buildBvh = true); ///optionally pass in a larger bvh aabb, used for quantization. This allows for deformations within this aabb - btBvhTriangleMeshShape(btStridingMeshInterface* meshInterface, bool useQuantizedAabbCompression,const btVector3& bvhAabbMin,const btVector3& bvhAabbMax); + btBvhTriangleMeshShape(btStridingMeshInterface* meshInterface, bool useQuantizedAabbCompression,const btVector3& bvhAabbMin,const btVector3& bvhAabbMax, bool buildBvh = true); virtual ~btBvhTriangleMeshShape(); @@ -56,7 +60,7 @@ public: void partialRefitTree(const btVector3& aabbMin,const btVector3& aabbMax); //debugging - virtual char* getName()const {return "BVHTRIANGLEMESH";} + virtual const char* getName()const {return "BVHTRIANGLEMESH";} virtual void setLocalScaling(const btVector3& scaling); @@ -65,6 +69,17 @@ public: { return m_bvh; } + + + void setOptimizedBvh(btOptimizedBvh* bvh) + { + btAssert(!m_bvh); + btAssert(!m_ownsBvh); + + m_bvh = bvh; + m_ownsBvh = false; + } + bool usesQuantizedAabbCompression() const { return m_useQuantizedAabbCompression; diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btCapsuleShape.cpp b/extern/bullet2/src/BulletCollision/CollisionShapes/btCapsuleShape.cpp index b7e15172da2..b4f21f38b3d 100644 --- a/extern/bullet2/src/BulletCollision/CollisionShapes/btCapsuleShape.cpp +++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btCapsuleShape.cpp @@ -112,7 +112,7 @@ btCapsuleShape::btCapsuleShape(btScalar radius, btScalar height) } -void btCapsuleShape::calculateLocalInertia(btScalar mass,btVector3& inertia) +void btCapsuleShape::calculateLocalInertia(btScalar mass,btVector3& inertia) const { //as an approximation, take the inertia of the box that bounds the spheres diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btCapsuleShape.h b/extern/bullet2/src/BulletCollision/CollisionShapes/btCapsuleShape.h index 27da8adefa5..0b566450fef 100644 --- a/extern/bullet2/src/BulletCollision/CollisionShapes/btCapsuleShape.h +++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btCapsuleShape.h @@ -16,20 +16,20 @@ subject to the following restrictions: #ifndef BT_CAPSULE_SHAPE_H #define BT_CAPSULE_SHAPE_H -#include "btConvexShape.h" -#include "../BroadphaseCollision/btBroadphaseProxy.h" // for the types +#include "btConvexInternalShape.h" +#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" // for the types ///btCapsuleShape represents a capsule around the Y axis ///A more general solution that can represent capsules is the btMultiSphereShape -class btCapsuleShape : public btConvexShape +class btCapsuleShape : public btConvexInternalShape { public: btCapsuleShape(btScalar radius,btScalar height); ///CollisionShape Interface - virtual void calculateLocalInertia(btScalar mass,btVector3& inertia); + virtual void calculateLocalInertia(btScalar mass,btVector3& inertia) const; /// btConvexShape Interface virtual btVector3 localGetSupportingVertexWithoutMargin(const btVector3& vec)const; @@ -38,7 +38,7 @@ public: virtual int getShapeType() const { return CAPSULE_SHAPE_PROXYTYPE; } - virtual char* getName()const + virtual const char* getName()const { return "CapsuleShape"; } diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btCollisionShape.h b/extern/bullet2/src/BulletCollision/CollisionShapes/btCollisionShape.h index 96268734a83..53fb12e33a1 100644 --- a/extern/bullet2/src/BulletCollision/CollisionShapes/btCollisionShape.h +++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btCollisionShape.h @@ -16,11 +16,11 @@ subject to the following restrictions: #ifndef COLLISION_SHAPE_H #define COLLISION_SHAPE_H -#include "../../LinearMath/btTransform.h" -#include "../../LinearMath/btVector3.h" -#include "../../LinearMath/btMatrix3x3.h" -#include "../../LinearMath/btPoint3.h" -#include "../BroadphaseCollision/btBroadphaseProxy.h" //for the shape types +#include "LinearMath/btTransform.h" +#include "LinearMath/btVector3.h" +#include "LinearMath/btMatrix3x3.h" +#include "LinearMath/btPoint3.h" +#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" //for the shape types ///btCollisionShape provides interface for collision shapes that can be shared among btCollisionObjects. class btCollisionShape @@ -49,26 +49,26 @@ public: #ifndef __SPU__ - inline bool isPolyhedral() const + SIMD_FORCE_INLINE bool isPolyhedral() const { return btBroadphaseProxy::isPolyhedral(getShapeType()); } - inline bool isConvex() const + SIMD_FORCE_INLINE bool isConvex() const { return btBroadphaseProxy::isConvex(getShapeType()); } - inline bool isConcave() const + SIMD_FORCE_INLINE bool isConcave() const { return btBroadphaseProxy::isConcave(getShapeType()); } - inline bool isCompound() const + SIMD_FORCE_INLINE bool isCompound() const { return btBroadphaseProxy::isCompound(getShapeType()); } ///isInfinite is used to catch simulation error (aabb check) - inline bool isInfinite() const + SIMD_FORCE_INLINE bool isInfinite() const { return btBroadphaseProxy::isInfinite(getShapeType()); } @@ -76,11 +76,11 @@ public: virtual int getShapeType() const=0; virtual void setLocalScaling(const btVector3& scaling) =0; virtual const btVector3& getLocalScaling() const =0; - virtual void calculateLocalInertia(btScalar mass,btVector3& inertia) = 0; + virtual void calculateLocalInertia(btScalar mass,btVector3& inertia) const = 0; //debugging support - virtual char* getName()const =0 ; + virtual const char* getName()const =0 ; #endif //__SPU__ diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btCompoundShape.cpp b/extern/bullet2/src/BulletCollision/CollisionShapes/btCompoundShape.cpp index a4712b3e925..114a1f4c1fc 100644 --- a/extern/bullet2/src/BulletCollision/CollisionShapes/btCompoundShape.cpp +++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btCompoundShape.cpp @@ -35,8 +35,15 @@ btCompoundShape::~btCompoundShape() void btCompoundShape::addChildShape(const btTransform& localTransform,btCollisionShape* shape) { - m_childTransforms.push_back(localTransform); - m_childShapes.push_back(shape); + //m_childTransforms.push_back(localTransform); + //m_childShapes.push_back(shape); + btCompoundShapeChild child; + child.m_transform = localTransform; + child.m_childShape = shape; + child.m_childShapeType = shape->getShapeType(); + child.m_childMargin = shape->getMargin(); + + m_children.push_back(child); //extend the local aabbMin/aabbMax btVector3 localAabbMin,localAabbMax; @@ -76,7 +83,7 @@ void btCompoundShape::getAabb(const btTransform& trans,btVector3& aabbMin,btVect aabbMax = center + extent; } -void btCompoundShape::calculateLocalInertia(btScalar mass,btVector3& inertia) +void btCompoundShape::calculateLocalInertia(btScalar mass,btVector3& inertia) const { //approximation: take the inertia from the aabb for now btTransform ident; diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btCompoundShape.h b/extern/bullet2/src/BulletCollision/CollisionShapes/btCompoundShape.h index 86dc1f80947..d23bd65b5e8 100644 --- a/extern/bullet2/src/BulletCollision/CollisionShapes/btCompoundShape.h +++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btCompoundShape.h @@ -18,26 +18,39 @@ subject to the following restrictions: #include "btCollisionShape.h" -#include "../../LinearMath/btVector3.h" -#include "../../LinearMath/btTransform.h" -#include "../../LinearMath/btMatrix3x3.h" +#include "LinearMath/btVector3.h" +#include "LinearMath/btTransform.h" +#include "LinearMath/btMatrix3x3.h" #include "btCollisionMargin.h" -#include "../../LinearMath/btAlignedObjectArray.h" +#include "LinearMath/btAlignedObjectArray.h" class btOptimizedBvh; +ATTRIBUTE_ALIGNED16(struct) btCompoundShapeChild +{ + BT_DECLARE_ALIGNED_ALLOCATOR(); + + btTransform m_transform; + btCollisionShape* m_childShape; + int m_childShapeType; + btScalar m_childMargin; +}; + /// btCompoundShape allows to store multiple other btCollisionShapes /// This allows for concave collision objects. This is more general then the Static Concave btTriangleMeshShape. -class btCompoundShape : public btCollisionShape +ATTRIBUTE_ALIGNED16(class) btCompoundShape : public btCollisionShape { - btAlignedObjectArray m_childTransforms; - btAlignedObjectArray m_childShapes; + //btAlignedObjectArray m_childTransforms; + //btAlignedObjectArray m_childShapes; + btAlignedObjectArray m_children; btVector3 m_localAabbMin; btVector3 m_localAabbMax; btOptimizedBvh* m_aabbTree; public: + BT_DECLARE_ALIGNED_ALLOCATOR(); + btCompoundShape(); virtual ~btCompoundShape(); @@ -46,25 +59,31 @@ public: int getNumChildShapes() const { - return int (m_childShapes.size()); + return int (m_children.size()); } btCollisionShape* getChildShape(int index) { - return m_childShapes[index]; + return m_children[index].m_childShape; } const btCollisionShape* getChildShape(int index) const { - return m_childShapes[index]; + return m_children[index].m_childShape; } - btTransform& getChildTransform(int index) + btTransform getChildTransform(int index) { - return m_childTransforms[index]; + return m_children[index].m_transform; } - const btTransform& getChildTransform(int index) const + const btTransform getChildTransform(int index) const { - return m_childTransforms[index]; + return m_children[index].m_transform; + } + + + btCompoundShapeChild* getChildList() + { + return &m_children[0]; } ///getAabb's default implementation is brute force, expected derived classes to implement a fast dedicated version @@ -80,7 +99,7 @@ public: return m_localScaling; } - virtual void calculateLocalInertia(btScalar mass,btVector3& inertia); + virtual void calculateLocalInertia(btScalar mass,btVector3& inertia) const; virtual int getShapeType() const { return COMPOUND_SHAPE_PROXYTYPE;} @@ -92,7 +111,7 @@ public: { return m_collisionMargin; } - virtual char* getName()const + virtual const char* getName()const { return "Compound"; } diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btConcaveShape.h b/extern/bullet2/src/BulletCollision/CollisionShapes/btConcaveShape.h index 73f974e4ee9..4db4e6513dd 100644 --- a/extern/bullet2/src/BulletCollision/CollisionShapes/btConcaveShape.h +++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btConcaveShape.h @@ -17,7 +17,7 @@ subject to the following restrictions: #define CONCAVE_SHAPE_H #include "btCollisionShape.h" -#include "../BroadphaseCollision/btBroadphaseProxy.h" // for the types +#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" // for the types #include "btTriangleCallback.h" diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btConeShape.h b/extern/bullet2/src/BulletCollision/CollisionShapes/btConeShape.h index 3ccda5b12c6..34f36b35f87 100644 --- a/extern/bullet2/src/BulletCollision/CollisionShapes/btConeShape.h +++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btConeShape.h @@ -16,11 +16,11 @@ subject to the following restrictions: #ifndef CONE_MINKOWSKI_H #define CONE_MINKOWSKI_H -#include "btConvexShape.h" -#include "../BroadphaseCollision/btBroadphaseProxy.h" // for the types +#include "btConvexInternalShape.h" +#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" // for the types ///btConeShape implements a Cone shape, around the Y axis -class btConeShape : public btConvexShape +class btConeShape : public btConvexInternalShape { @@ -42,7 +42,7 @@ public: btScalar getHeight() const { return m_height;} - virtual void calculateLocalInertia(btScalar mass,btVector3& inertia) + virtual void calculateLocalInertia(btScalar mass,btVector3& inertia) const { btTransform identity; identity.setIdentity(); @@ -72,7 +72,7 @@ public: virtual int getShapeType() const { return CONE_SHAPE_PROXYTYPE; } - virtual char* getName()const + virtual const char* getName()const { return "Cone"; } diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btConvexHullShape.h b/extern/bullet2/src/BulletCollision/CollisionShapes/btConvexHullShape.h index 3fd5e382525..0928d68b8fc 100644 --- a/extern/bullet2/src/BulletCollision/CollisionShapes/btConvexHullShape.h +++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btConvexHullShape.h @@ -17,8 +17,8 @@ subject to the following restrictions: #define CONVEX_HULL_SHAPE_H #include "btPolyhedralConvexShape.h" -#include "../BroadphaseCollision/btBroadphaseProxy.h" // for the types -#include "../../LinearMath/btAlignedObjectArray.h" +#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" // for the types +#include "LinearMath/btAlignedObjectArray.h" ///ConvexHullShape implements an implicit (getSupportingVertex) Convex Hull of a Point Cloud (vertices) ///No connectivity is needed. localGetSupportingVertex iterates linearly though all vertices. @@ -29,6 +29,7 @@ ATTRIBUTE_ALIGNED16(class) btConvexHullShape : public btPolyhedralConvexShape btAlignedObjectArray m_points; public: + BT_DECLARE_ALIGNED_ALLOCATOR(); ///this constructor optionally takes in a pointer to points. Each point is assumed to be 3 consecutive btScalar (x,y,z), the striding defines the number of bytes between each point, in memory. @@ -56,7 +57,7 @@ public: virtual int getShapeType()const { return CONVEX_HULL_SHAPE_PROXYTYPE; } //debugging - virtual char* getName()const {return "Convex";} + virtual const char* getName()const {return "Convex";} virtual int getNumVertices() const; diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btConvexInternalShape.cpp b/extern/bullet2/src/BulletCollision/CollisionShapes/btConvexInternalShape.cpp new file mode 100644 index 00000000000..f828d28e18c --- /dev/null +++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btConvexInternalShape.cpp @@ -0,0 +1,78 @@ +/* +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 "btConvexInternalShape.h" + + +btConvexInternalShape::btConvexInternalShape() +: m_localScaling(btScalar(1.),btScalar(1.),btScalar(1.)), +m_collisionMargin(CONVEX_DISTANCE_MARGIN) +{ +} + + +void btConvexInternalShape::setLocalScaling(const btVector3& scaling) +{ + m_localScaling = scaling; +} + + + +void btConvexInternalShape::getAabbSlow(const btTransform& trans,btVector3&minAabb,btVector3&maxAabb) const +{ + + btScalar margin = getMargin(); + for (int i=0;i<3;i++) + { + btVector3 vec(btScalar(0.),btScalar(0.),btScalar(0.)); + vec[i] = btScalar(1.); + + btVector3 sv = localGetSupportingVertex(vec*trans.getBasis()); + + btVector3 tmp = trans(sv); + maxAabb[i] = tmp[i]+margin; + vec[i] = btScalar(-1.); + tmp = trans(localGetSupportingVertex(vec*trans.getBasis())); + minAabb[i] = tmp[i]-margin; + } +}; + + +btVector3 btConvexInternalShape::localGetSupportingVertex(const btVector3& vec)const +{ +#ifndef __SPU__ + + btVector3 supVertex = localGetSupportingVertexWithoutMargin(vec); + + if ( getMargin()!=btScalar(0.) ) + { + btVector3 vecnorm = vec; + if (vecnorm .length2() < (SIMD_EPSILON*SIMD_EPSILON)) + { + vecnorm.setValue(btScalar(-1.),btScalar(-1.),btScalar(-1.)); + } + vecnorm.normalize(); + supVertex+= getMargin() * vecnorm; + } + return supVertex; + +#else + return btVector3(0,0,0); +#endif //__SPU__ + + } + + diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btConvexInternalShape.h b/extern/bullet2/src/BulletCollision/CollisionShapes/btConvexInternalShape.h new file mode 100644 index 00000000000..a03af873bd3 --- /dev/null +++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btConvexInternalShape.h @@ -0,0 +1,99 @@ + +#ifndef BT_CONVEX_INTERNAL_SHAPE_H +#define BT_CONVEX_INTERNAL_SHAPE_H + +#include "btConvexShape.h" + +///btConvexInternalShape carries some additional data, shared by most implementations +class btConvexInternalShape : public btConvexShape +{ + + protected: + + //local scaling. collisionMargin is not scaled ! + btVector3 m_localScaling; + + btVector3 m_implicitShapeDimensions; + + btScalar m_collisionMargin; + + btScalar m_padding[2]; + + + + +public: + + btConvexInternalShape(); + + virtual ~btConvexInternalShape() + { + + } + + + virtual btVector3 localGetSupportingVertex(const btVector3& vec)const; +#ifndef __SPU__ + virtual btVector3 localGetSupportingVertexWithoutMargin(const btVector3& vec) const= 0; + + //notice that the vectors should be unit length + virtual void batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const= 0; +#endif //#ifndef __SPU__ + + const btVector3& getImplicitShapeDimensions() const + { + return m_implicitShapeDimensions; + } + + ///getAabb's default implementation is brute force, expected derived classes to implement a fast dedicated version + void getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const + { + getAabbSlow(t,aabbMin,aabbMax); + } + + + + virtual void getAabbSlow(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const; + + + virtual void setLocalScaling(const btVector3& scaling); + virtual const btVector3& getLocalScaling() const + { + return m_localScaling; + } + + const btVector3& getLocalScalingNV() const + { + return m_localScaling; + } + + virtual void setMargin(btScalar margin) + { + m_collisionMargin = margin; + } + virtual btScalar getMargin() const + { + return m_collisionMargin; + } + + btScalar getMarginNV() const + { + return m_collisionMargin; + } + + virtual int getNumPreferredPenetrationDirections() const + { + return 0; + } + + virtual void getPreferredPenetrationDirection(int index, btVector3& penetrationVector) const + { + (void)penetrationVector; + (void)index; + btAssert(0); + } + +}; + + +#endif //BT_CONVEX_INTERNAL_SHAPE_H diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btConvexShape.cpp b/extern/bullet2/src/BulletCollision/CollisionShapes/btConvexShape.cpp index 7edf1ea6db8..7afcccf8b03 100644 --- a/extern/bullet2/src/BulletCollision/CollisionShapes/btConvexShape.cpp +++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btConvexShape.cpp @@ -16,62 +16,3 @@ subject to the following restrictions: #include "btConvexShape.h" -btConvexShape::btConvexShape() -: m_localScaling(btScalar(1.),btScalar(1.),btScalar(1.)), -m_collisionMargin(CONVEX_DISTANCE_MARGIN) -{ -} - - -void btConvexShape::setLocalScaling(const btVector3& scaling) -{ - m_localScaling = scaling; -} - - - -void btConvexShape::getAabbSlow(const btTransform& trans,btVector3&minAabb,btVector3&maxAabb) const -{ - - btScalar margin = getMargin(); - for (int i=0;i<3;i++) - { - btVector3 vec(btScalar(0.),btScalar(0.),btScalar(0.)); - vec[i] = btScalar(1.); - - btVector3 sv = localGetSupportingVertex(vec*trans.getBasis()); - - btVector3 tmp = trans(sv); - maxAabb[i] = tmp[i]+margin; - vec[i] = btScalar(-1.); - tmp = trans(localGetSupportingVertex(vec*trans.getBasis())); - minAabb[i] = tmp[i]-margin; - } -}; - - -btVector3 btConvexShape::localGetSupportingVertex(const btVector3& vec)const -{ -#ifndef __SPU__ - - btVector3 supVertex = localGetSupportingVertexWithoutMargin(vec); - - if ( getMargin()!=btScalar(0.) ) - { - btVector3 vecnorm = vec; - if (vecnorm .length2() < (SIMD_EPSILON*SIMD_EPSILON)) - { - vecnorm.setValue(btScalar(-1.),btScalar(-1.),btScalar(-1.)); - } - vecnorm.normalize(); - supVertex+= getMargin() * vecnorm; - } - return supVertex; - -#else - return btVector3(0,0,0); -#endif //__SPU__ - - } - - diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btConvexShape.h b/extern/bullet2/src/BulletCollision/CollisionShapes/btConvexShape.h index 746f383dfc7..6dfd288e05b 100644 --- a/extern/bullet2/src/BulletCollision/CollisionShapes/btConvexShape.h +++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btConvexShape.h @@ -18,37 +18,26 @@ subject to the following restrictions: #include "btCollisionShape.h" -#include "../../LinearMath/btVector3.h" -#include "../../LinearMath/btTransform.h" -#include "../../LinearMath/btMatrix3x3.h" +#include "LinearMath/btVector3.h" +#include "LinearMath/btTransform.h" +#include "LinearMath/btMatrix3x3.h" #include "btCollisionMargin.h" +#include "LinearMath/btAlignedAllocator.h" //todo: get rid of this btConvexCastResult thing! struct btConvexCastResult; #define MAX_PREFERRED_PENETRATION_DIRECTIONS 10 /// btConvexShape is an abstract shape interface. -/// The explicit part provides plane-equations, the implicit part provides GetClosestPoint interface. +/// It describes general convex shapes using the localGetSupportingVertex interface /// used in combination with GJK or btConvexCast ATTRIBUTE_ALIGNED16(class) btConvexShape : public btCollisionShape { -protected: - - //local scaling. collisionMargin is not scaled ! - btVector3 m_localScaling; - - btVector3 m_implicitShapeDimensions; - - btScalar m_collisionMargin; - - btScalar m_padding[2]; - - - public: - btConvexShape(); + + BT_DECLARE_ALIGNED_ALLOCATOR(); virtual ~btConvexShape() { @@ -56,7 +45,7 @@ public: } - virtual btVector3 localGetSupportingVertex(const btVector3& vec)const; + virtual btVector3 localGetSupportingVertex(const btVector3& vec)const =0; #ifndef __SPU__ virtual btVector3 localGetSupportingVertexWithoutMargin(const btVector3& vec) const= 0; @@ -64,63 +53,24 @@ public: virtual void batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const= 0; #endif //#ifndef __SPU__ - const btVector3& getImplicitShapeDimensions() const - { - return m_implicitShapeDimensions; - } ///getAabb's default implementation is brute force, expected derived classes to implement a fast dedicated version - void getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const - { - getAabbSlow(t,aabbMin,aabbMax); - } + void getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const =0; + virtual void getAabbSlow(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const =0; + virtual void setLocalScaling(const btVector3& scaling) =0; + virtual const btVector3& getLocalScaling() const =0; + + virtual void setMargin(btScalar margin)=0; + + virtual btScalar getMargin() const=0; + + virtual int getNumPreferredPenetrationDirections() const=0; - virtual void getAabbSlow(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const; + virtual void getPreferredPenetrationDirection(int index, btVector3& penetrationVector) const=0; - - virtual void setLocalScaling(const btVector3& scaling); - virtual const btVector3& getLocalScaling() const - { - return m_localScaling; - } - - const btVector3& getLocalScalingNV() const - { - return m_localScaling; - } - - virtual void setMargin(btScalar margin) - { - m_collisionMargin = margin; - } - virtual btScalar getMargin() const - { - return m_collisionMargin; - } - - btScalar getMarginNV() const - { - return m_collisionMargin; - } - - virtual int getNumPreferredPenetrationDirections() const - { - return 0; - } - - virtual void getPreferredPenetrationDirection(int index, btVector3& penetrationVector) const - { - (void)penetrationVector; - (void)index; - btAssert(0); - } - - - -} -; +}; diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btConvexTriangleMeshShape.cpp b/extern/bullet2/src/BulletCollision/CollisionShapes/btConvexTriangleMeshShape.cpp index 614ec977793..6941030b15f 100644 --- a/extern/bullet2/src/BulletCollision/CollisionShapes/btConvexTriangleMeshShape.cpp +++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btConvexTriangleMeshShape.cpp @@ -202,4 +202,4 @@ void btConvexTriangleMeshShape::setLocalScaling(const btVector3& scaling) const btVector3& btConvexTriangleMeshShape::getLocalScaling() const { return m_stridingMesh->getScaling(); -} \ No newline at end of file +} diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btConvexTriangleMeshShape.h b/extern/bullet2/src/BulletCollision/CollisionShapes/btConvexTriangleMeshShape.h index 34ee7af744c..f3daa58368f 100644 --- a/extern/bullet2/src/BulletCollision/CollisionShapes/btConvexTriangleMeshShape.h +++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btConvexTriangleMeshShape.h @@ -3,7 +3,7 @@ #include "btPolyhedralConvexShape.h" -#include "../BroadphaseCollision/btBroadphaseProxy.h" // for the types +#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" // for the types /// btConvexTriangleMeshShape is a convex hull of a triangle mesh. If you just have a point cloud, you can use btConvexHullShape instead. @@ -16,7 +16,11 @@ class btConvexTriangleMeshShape : public btPolyhedralConvexShape public: btConvexTriangleMeshShape(btStridingMeshInterface* meshInterface); - class btStridingMeshInterface* getStridingMesh() + class btStridingMeshInterface* getMeshInterface() + { + return m_stridingMesh; + } + const class btStridingMeshInterface* getMeshInterface() const { return m_stridingMesh; } @@ -28,7 +32,7 @@ public: virtual int getShapeType()const { return CONVEX_TRIANGLEMESH_SHAPE_PROXYTYPE; } //debugging - virtual char* getName()const {return "ConvexTrimesh";} + virtual const char* getName()const {return "ConvexTrimesh";} virtual int getNumVertices() const; virtual int getNumEdges() const; diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btCylinderShape.cpp b/extern/bullet2/src/BulletCollision/CollisionShapes/btCylinderShape.cpp index 1666afb3b88..3afef1c7550 100644 --- a/extern/bullet2/src/BulletCollision/CollisionShapes/btCylinderShape.cpp +++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btCylinderShape.cpp @@ -45,7 +45,7 @@ void btCylinderShape::getAabb(const btTransform& t,btVector3& aabbMin,btVector3& } -inline btVector3 CylinderLocalSupportX(const btVector3& halfExtents,const btVector3& v) +SIMD_FORCE_INLINE btVector3 CylinderLocalSupportX(const btVector3& halfExtents,const btVector3& v) { const int cylinderUpAxis = 0; const int XX = 1; @@ -163,24 +163,24 @@ const int ZZ = 1; btVector3 btCylinderShapeX::localGetSupportingVertexWithoutMargin(const btVector3& vec)const { - return CylinderLocalSupportX(getHalfExtents(),vec); + return CylinderLocalSupportX(getHalfExtentsWithoutMargin(),vec); } btVector3 btCylinderShapeZ::localGetSupportingVertexWithoutMargin(const btVector3& vec)const { - return CylinderLocalSupportZ(getHalfExtents(),vec); + return CylinderLocalSupportZ(getHalfExtentsWithoutMargin(),vec); } btVector3 btCylinderShape::localGetSupportingVertexWithoutMargin(const btVector3& vec)const { - return CylinderLocalSupportY(getHalfExtents(),vec); + return CylinderLocalSupportY(getHalfExtentsWithoutMargin(),vec); } void btCylinderShape::batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const { for (int i=0;iquantizeWithClamp(&node.m_quantizedAabbMin[0],aabbMin); m_optimizedTree->quantizeWithClamp(&node.m_quantizedAabbMax[0],aabbMax); @@ -170,6 +188,13 @@ void btOptimizedBvh::build(btStridingMeshInterface* triangles, bool useQuantized subtree.m_rootNodeIndex = 0; subtree.m_subtreeSize = m_quantizedContiguousNodes[0].isLeafNode() ? 1 : m_quantizedContiguousNodes[0].getEscapeIndex(); } + + //PCK: update the copy of the size + m_subtreeHeaderCount = m_SubtreeHeaders.size(); + + //PCK: clear m_quantizedLeafNodes and m_leafNodes, they are temporary + m_quantizedLeafNodes.clear(); + m_leafNodes.clear(); } @@ -201,8 +226,9 @@ void btOptimizedBvh::refitPartial(btStridingMeshInterface* meshInterface,const b { btBvhSubtreeInfo& subtree = m_SubtreeHeaders[i]; - bool overlap = testQuantizedAabbAgainstQuantizedAabb(quantizedQueryAabbMin,quantizedQueryAabbMax,subtree.m_quantizedAabbMin,subtree.m_quantizedAabbMax); - if (overlap) + //PCK: unsigned instead of bool + unsigned overlap = testQuantizedAabbAgainstQuantizedAabb(quantizedQueryAabbMin,quantizedQueryAabbMax,subtree.m_quantizedAabbMin,subtree.m_quantizedAabbMax); + if (overlap != 0) { updateBvhNodes(meshInterface,subtree.m_rootNodeIndex,subtree.m_rootNodeIndex+subtree.m_subtreeSize,i); @@ -479,6 +505,9 @@ void btOptimizedBvh::updateSubtreeHeaders(int leftChildNodexIndex,int rightChild subtree.m_rootNodeIndex = rightChildNodexIndex; subtree.m_subtreeSize = rightSubTreeSize; } + + //PCK: update the copy of the size + m_subtreeHeaderCount = m_SubtreeHeaders.size(); } @@ -568,7 +597,6 @@ void btOptimizedBvh::reportAabbOverlappingNodex(btNodeOverlapCallback* nodeCallb { //either choose recursive traversal (walkTree) or stackless (walkStacklessTree) - if (m_useQuantization) { ///quantize query AABB @@ -611,7 +639,9 @@ void btOptimizedBvh::walkStacklessTree(btNodeOverlapCallback* nodeCallback,const const btOptimizedBvhNode* rootNode = &m_contiguousNodes[0]; int escapeIndex, curIndex = 0; int walkIterations = 0; - bool aabbOverlap, isLeafNode; + bool isLeafNode; + //PCK: unsigned instead of bool + unsigned aabbOverlap; while (curIndex < m_curNodeIndex) { @@ -622,12 +652,14 @@ void btOptimizedBvh::walkStacklessTree(btNodeOverlapCallback* nodeCallback,const aabbOverlap = TestAabbAgainstAabb2(aabbMin,aabbMax,rootNode->m_aabbMinOrg,rootNode->m_aabbMaxOrg); isLeafNode = rootNode->m_escapeIndex == -1; - if (isLeafNode && aabbOverlap) + //PCK: unsigned instead of bool + if (isLeafNode && (aabbOverlap != 0)) { nodeCallback->processNode(rootNode->m_subPart,rootNode->m_triangleIndex); } - if (aabbOverlap || isLeafNode) + //PCK: unsigned instead of bool + if ((aabbOverlap != 0) || isLeafNode) { rootNode++; curIndex++; @@ -668,12 +700,16 @@ void btOptimizedBvh::walkRecursiveQuantizedTreeAgainstQueryAabb(const btQuantize { btAssert(m_useQuantization); - bool aabbOverlap, isLeafNode; + bool isLeafNode; + //PCK: unsigned instead of bool + unsigned aabbOverlap; + //PCK: unsigned instead of bool aabbOverlap = testQuantizedAabbAgainstQuantizedAabb(quantizedQueryAabbMin,quantizedQueryAabbMax,currentNode->m_quantizedAabbMin,currentNode->m_quantizedAabbMax); isLeafNode = currentNode->isLeafNode(); - if (aabbOverlap) + //PCK: unsigned instead of bool + if (aabbOverlap != 0) { if (isLeafNode) { @@ -707,7 +743,9 @@ void btOptimizedBvh::walkStacklessQuantizedTree(btNodeOverlapCallback* nodeCallb const btQuantizedBvhNode* rootNode = &m_quantizedContiguousNodes[startNodeIndex]; int escapeIndex; - bool aabbOverlap, isLeafNode; + bool isLeafNode; + //PCK: unsigned instead of bool + unsigned aabbOverlap; while (curIndex < endNodeIndex) { @@ -732,6 +770,7 @@ void btOptimizedBvh::walkStacklessQuantizedTree(btNodeOverlapCallback* nodeCallb assert (walkIterations < subTreeSize); walkIterations++; + //PCK: unsigned instead of bool aabbOverlap = testQuantizedAabbAgainstQuantizedAabb(quantizedQueryAabbMin,quantizedQueryAabbMax,rootNode->m_quantizedAabbMin,rootNode->m_quantizedAabbMax); isLeafNode = rootNode->isLeafNode(); @@ -740,7 +779,8 @@ void btOptimizedBvh::walkStacklessQuantizedTree(btNodeOverlapCallback* nodeCallb nodeCallback->processNode(0,rootNode->getTriangleIndex()); } - if (aabbOverlap || isLeafNode) + //PCK: unsigned instead of bool + if ((aabbOverlap != 0) || isLeafNode) { rootNode++; curIndex++; @@ -768,8 +808,9 @@ void btOptimizedBvh::walkStacklessQuantizedTreeCacheFriendly(btNodeOverlapCallba { const btBvhSubtreeInfo& subtree = m_SubtreeHeaders[i]; - bool overlap = testQuantizedAabbAgainstQuantizedAabb(quantizedQueryAabbMin,quantizedQueryAabbMax,subtree.m_quantizedAabbMin,subtree.m_quantizedAabbMax); - if (overlap) + //PCK: unsigned instead of bool + unsigned overlap = testQuantizedAabbAgainstQuantizedAabb(quantizedQueryAabbMin,quantizedQueryAabbMax,subtree.m_quantizedAabbMin,subtree.m_quantizedAabbMax); + if (overlap != 0) { walkStacklessQuantizedTree(nodeCallback,quantizedQueryAabbMin,quantizedQueryAabbMax, subtree.m_rootNodeIndex, @@ -791,20 +832,7 @@ void btOptimizedBvh::reportSphereOverlappingNodex(btNodeOverlapCallback* nodeCal } -void btOptimizedBvh::quantizeWithClamp(unsigned short* out, const btVector3& point) const -{ - btAssert(m_useQuantization); - - btVector3 clampedPoint(point); - clampedPoint.setMax(m_bvhAabbMin); - clampedPoint.setMin(m_bvhAabbMax); - - btVector3 v = (clampedPoint - m_bvhAabbMin) * m_bvhQuantization; - out[0] = (unsigned short)(v.getX()+0.5f); - out[1] = (unsigned short)(v.getY()+0.5f); - out[2] = (unsigned short)(v.getZ()+0.5f); -} btVector3 btOptimizedBvh::unQuantize(const unsigned short* vecIn) const { @@ -843,3 +871,311 @@ void btOptimizedBvh::assignInternalNodeFromLeafNode(int internalNode,int leafNod m_contiguousNodes[internalNode] = m_leafNodes[leafNodeIndex]; } } + +//PCK: include +#include + +//PCK: consts +static const unsigned BVH_ALIGNMENT = 16; +static const unsigned BVH_ALIGNMENT_MASK = BVH_ALIGNMENT-1; + +static const unsigned BVH_ALIGNMENT_BLOCKS = 2; + + + +unsigned int btOptimizedBvh::getAlignmentSerializationPadding() +{ + return BVH_ALIGNMENT_BLOCKS * BVH_ALIGNMENT; +} + +unsigned btOptimizedBvh::calculateSerializeBufferSize() +{ + unsigned baseSize = sizeof(btOptimizedBvh) + getAlignmentSerializationPadding(); + baseSize += sizeof(btBvhSubtreeInfo) * m_subtreeHeaderCount; + if (m_useQuantization) + { + return baseSize + m_curNodeIndex * sizeof(btQuantizedBvhNode); + } + return baseSize + m_curNodeIndex * sizeof(btOptimizedBvhNode); +} + +bool btOptimizedBvh::serialize(void *o_alignedDataBuffer, unsigned i_dataBufferSize, bool i_swapEndian) +{ + assert(m_subtreeHeaderCount == m_SubtreeHeaders.size()); + m_subtreeHeaderCount = m_SubtreeHeaders.size(); + +/* if (i_dataBufferSize < calculateSerializeBufferSize() || o_alignedDataBuffer == NULL || (((unsigned)o_alignedDataBuffer & BVH_ALIGNMENT_MASK) != 0)) + { + ///check alignedment for buffer? + btAssert(0); + return false; + } +*/ + + btOptimizedBvh *targetBvh = (btOptimizedBvh *)o_alignedDataBuffer; + + // construct the class so the virtual function table, etc will be set up + // Also, m_leafNodes and m_quantizedLeafNodes will be initialized to default values by the constructor + new (targetBvh) btOptimizedBvh; + + if (i_swapEndian) + { + targetBvh->m_curNodeIndex = btSwapEndian(m_curNodeIndex); + + + btSwapVector3Endian(m_bvhAabbMin,targetBvh->m_bvhAabbMin); + btSwapVector3Endian(m_bvhAabbMax,targetBvh->m_bvhAabbMax); + btSwapVector3Endian(m_bvhQuantization,targetBvh->m_bvhQuantization); + + targetBvh->m_traversalMode = (btTraversalMode)btSwapEndian(m_traversalMode); + targetBvh->m_subtreeHeaderCount = btSwapEndian(m_subtreeHeaderCount); + } + else + { + targetBvh->m_curNodeIndex = m_curNodeIndex; + targetBvh->m_bvhAabbMin = m_bvhAabbMin; + targetBvh->m_bvhAabbMax = m_bvhAabbMax; + targetBvh->m_bvhQuantization = m_bvhQuantization; + targetBvh->m_traversalMode = m_traversalMode; + targetBvh->m_subtreeHeaderCount = m_subtreeHeaderCount; + } + + targetBvh->m_useQuantization = m_useQuantization; + + unsigned char *nodeData = (unsigned char *)targetBvh; + nodeData += sizeof(btOptimizedBvh); + + unsigned sizeToAdd = 0;//(BVH_ALIGNMENT-((unsigned)nodeData & BVH_ALIGNMENT_MASK))&BVH_ALIGNMENT_MASK; + nodeData += sizeToAdd; + + int nodeCount = m_curNodeIndex; + + if (m_useQuantization) + { + targetBvh->m_quantizedContiguousNodes.initializeFromBuffer(nodeData, nodeCount, nodeCount); + + if (i_swapEndian) + { + for (int nodeIndex = 0; nodeIndex < nodeCount; nodeIndex++) + { + targetBvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[0] = btSwapEndian(m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[0]); + targetBvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[1] = btSwapEndian(m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[1]); + targetBvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[2] = btSwapEndian(m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[2]); + + targetBvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[0] = btSwapEndian(m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[0]); + targetBvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[1] = btSwapEndian(m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[1]); + targetBvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[2] = btSwapEndian(m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[2]); + + targetBvh->m_quantizedContiguousNodes[nodeIndex].m_escapeIndexOrTriangleIndex = btSwapEndian(m_quantizedContiguousNodes[nodeIndex].m_escapeIndexOrTriangleIndex); + } + } + else + { + for (int nodeIndex = 0; nodeIndex < nodeCount; nodeIndex++) + { + + targetBvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[0] = m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[0]; + targetBvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[1] = m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[1]; + targetBvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[2] = m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[2]; + + targetBvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[0] = m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[0]; + targetBvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[1] = m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[1]; + targetBvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[2] = m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[2]; + + targetBvh->m_quantizedContiguousNodes[nodeIndex].m_escapeIndexOrTriangleIndex = m_quantizedContiguousNodes[nodeIndex].m_escapeIndexOrTriangleIndex; + + + } + } + nodeData += sizeof(btQuantizedBvhNode) * nodeCount; + } + else + { + targetBvh->m_contiguousNodes.initializeFromBuffer(nodeData, nodeCount, nodeCount); + + if (i_swapEndian) + { + for (int nodeIndex = 0; nodeIndex < nodeCount; nodeIndex++) + { + btSwapVector3Endian(m_contiguousNodes[nodeIndex].m_aabbMinOrg, targetBvh->m_contiguousNodes[nodeIndex].m_aabbMinOrg); + btSwapVector3Endian(m_contiguousNodes[nodeIndex].m_aabbMaxOrg, targetBvh->m_contiguousNodes[nodeIndex].m_aabbMaxOrg); + + targetBvh->m_contiguousNodes[nodeIndex].m_escapeIndex = btSwapEndian(m_contiguousNodes[nodeIndex].m_escapeIndex); + targetBvh->m_contiguousNodes[nodeIndex].m_subPart = btSwapEndian(m_contiguousNodes[nodeIndex].m_subPart); + targetBvh->m_contiguousNodes[nodeIndex].m_triangleIndex = btSwapEndian(m_contiguousNodes[nodeIndex].m_triangleIndex); + } + } + else + { + for (int nodeIndex = 0; nodeIndex < nodeCount; nodeIndex++) + { + targetBvh->m_contiguousNodes[nodeIndex].m_aabbMinOrg = m_contiguousNodes[nodeIndex].m_aabbMinOrg; + targetBvh->m_contiguousNodes[nodeIndex].m_aabbMaxOrg = m_contiguousNodes[nodeIndex].m_aabbMaxOrg; + + targetBvh->m_contiguousNodes[nodeIndex].m_escapeIndex = m_contiguousNodes[nodeIndex].m_escapeIndex; + targetBvh->m_contiguousNodes[nodeIndex].m_subPart = m_contiguousNodes[nodeIndex].m_subPart; + targetBvh->m_contiguousNodes[nodeIndex].m_triangleIndex = m_contiguousNodes[nodeIndex].m_triangleIndex; + } + } + nodeData += sizeof(btOptimizedBvhNode) * nodeCount; + } + + sizeToAdd = 0;//(BVH_ALIGNMENT-((unsigned)nodeData & BVH_ALIGNMENT_MASK))&BVH_ALIGNMENT_MASK; + nodeData += sizeToAdd; + + // Now serialize the subtree headers + targetBvh->m_SubtreeHeaders.initializeFromBuffer(nodeData, m_subtreeHeaderCount, m_subtreeHeaderCount); + if (i_swapEndian) + { + for (int i = 0; i < m_subtreeHeaderCount; i++) + { + targetBvh->m_SubtreeHeaders[i].m_quantizedAabbMin[0] = btSwapEndian(m_SubtreeHeaders[i].m_quantizedAabbMin[0]); + targetBvh->m_SubtreeHeaders[i].m_quantizedAabbMin[1] = btSwapEndian(m_SubtreeHeaders[i].m_quantizedAabbMin[1]); + targetBvh->m_SubtreeHeaders[i].m_quantizedAabbMin[2] = btSwapEndian(m_SubtreeHeaders[i].m_quantizedAabbMin[2]); + + targetBvh->m_SubtreeHeaders[i].m_quantizedAabbMax[0] = btSwapEndian(m_SubtreeHeaders[i].m_quantizedAabbMax[0]); + targetBvh->m_SubtreeHeaders[i].m_quantizedAabbMax[1] = btSwapEndian(m_SubtreeHeaders[i].m_quantizedAabbMax[1]); + targetBvh->m_SubtreeHeaders[i].m_quantizedAabbMax[2] = btSwapEndian(m_SubtreeHeaders[i].m_quantizedAabbMax[2]); + + targetBvh->m_SubtreeHeaders[i].m_rootNodeIndex = btSwapEndian(m_SubtreeHeaders[i].m_rootNodeIndex); + targetBvh->m_SubtreeHeaders[i].m_subtreeSize = btSwapEndian(m_SubtreeHeaders[i].m_subtreeSize); + } + } + else + { + for (int i = 0; i < m_subtreeHeaderCount; i++) + { + targetBvh->m_SubtreeHeaders[i].m_quantizedAabbMin[0] = (m_SubtreeHeaders[i].m_quantizedAabbMin[0]); + targetBvh->m_SubtreeHeaders[i].m_quantizedAabbMin[1] = (m_SubtreeHeaders[i].m_quantizedAabbMin[1]); + targetBvh->m_SubtreeHeaders[i].m_quantizedAabbMin[2] = (m_SubtreeHeaders[i].m_quantizedAabbMin[2]); + + targetBvh->m_SubtreeHeaders[i].m_quantizedAabbMax[0] = (m_SubtreeHeaders[i].m_quantizedAabbMax[0]); + targetBvh->m_SubtreeHeaders[i].m_quantizedAabbMax[1] = (m_SubtreeHeaders[i].m_quantizedAabbMax[1]); + targetBvh->m_SubtreeHeaders[i].m_quantizedAabbMax[2] = (m_SubtreeHeaders[i].m_quantizedAabbMax[2]); + + targetBvh->m_SubtreeHeaders[i].m_rootNodeIndex = (m_SubtreeHeaders[i].m_rootNodeIndex); + targetBvh->m_SubtreeHeaders[i].m_subtreeSize = (m_SubtreeHeaders[i].m_subtreeSize); + targetBvh->m_SubtreeHeaders[i] = m_SubtreeHeaders[i]; + } + } + + nodeData += sizeof(btBvhSubtreeInfo) * m_subtreeHeaderCount; + + return true; +} + +btOptimizedBvh *btOptimizedBvh::deSerializeInPlace(void *i_alignedDataBuffer, unsigned i_dataBufferSize, bool i_swapEndian) +{ + + if (i_alignedDataBuffer == NULL)// || (((unsigned)i_alignedDataBuffer & BVH_ALIGNMENT_MASK) != 0)) + { + return NULL; + } + btOptimizedBvh *bvh = (btOptimizedBvh *)i_alignedDataBuffer; + + if (i_swapEndian) + { + bvh->m_curNodeIndex = btSwapEndian(bvh->m_curNodeIndex); + + btUnSwapVector3Endian(bvh->m_bvhAabbMin); + btUnSwapVector3Endian(bvh->m_bvhAabbMax); + btUnSwapVector3Endian(bvh->m_bvhQuantization); + + bvh->m_traversalMode = (btTraversalMode)btSwapEndian(bvh->m_traversalMode); + bvh->m_subtreeHeaderCount = btSwapEndian(bvh->m_subtreeHeaderCount); + } + + int calculatedBufSize = bvh->calculateSerializeBufferSize(); + btAssert(calculatedBufSize <= i_dataBufferSize); + + if (calculatedBufSize > i_dataBufferSize) + { + return NULL; + } + + unsigned char *nodeData = (unsigned char *)bvh; + nodeData += sizeof(btOptimizedBvh); + + unsigned sizeToAdd = 0;//(BVH_ALIGNMENT-((unsigned)nodeData & BVH_ALIGNMENT_MASK))&BVH_ALIGNMENT_MASK; + nodeData += sizeToAdd; + + int nodeCount = bvh->m_curNodeIndex; + + // Must call placement new to fill in virtual function table, etc, but we don't want to overwrite most data, so call a special version of the constructor + // Also, m_leafNodes and m_quantizedLeafNodes will be initialized to default values by the constructor + new (bvh) btOptimizedBvh(*bvh, false); + + if (bvh->m_useQuantization) + { + bvh->m_quantizedContiguousNodes.initializeFromBuffer(nodeData, nodeCount, nodeCount); + + if (i_swapEndian) + { + for (int nodeIndex = 0; nodeIndex < nodeCount; nodeIndex++) + { + bvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[0] = btSwapEndian(bvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[0]); + bvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[1] = btSwapEndian(bvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[1]); + bvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[2] = btSwapEndian(bvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[2]); + + bvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[0] = btSwapEndian(bvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[0]); + bvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[1] = btSwapEndian(bvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[1]); + bvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[2] = btSwapEndian(bvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[2]); + + bvh->m_quantizedContiguousNodes[nodeIndex].m_escapeIndexOrTriangleIndex = btSwapEndian(bvh->m_quantizedContiguousNodes[nodeIndex].m_escapeIndexOrTriangleIndex); + } + } + nodeData += sizeof(btQuantizedBvhNode) * nodeCount; + } + else + { + bvh->m_contiguousNodes.initializeFromBuffer(nodeData, nodeCount, nodeCount); + + if (i_swapEndian) + { + for (int nodeIndex = 0; nodeIndex < nodeCount; nodeIndex++) + { + btUnSwapVector3Endian(bvh->m_contiguousNodes[nodeIndex].m_aabbMinOrg); + btUnSwapVector3Endian(bvh->m_contiguousNodes[nodeIndex].m_aabbMaxOrg); + + bvh->m_contiguousNodes[nodeIndex].m_escapeIndex = btSwapEndian(bvh->m_contiguousNodes[nodeIndex].m_escapeIndex); + bvh->m_contiguousNodes[nodeIndex].m_subPart = btSwapEndian(bvh->m_contiguousNodes[nodeIndex].m_subPart); + bvh->m_contiguousNodes[nodeIndex].m_triangleIndex = btSwapEndian(bvh->m_contiguousNodes[nodeIndex].m_triangleIndex); + } + } + nodeData += sizeof(btOptimizedBvhNode) * nodeCount; + } + + sizeToAdd = 0;//(BVH_ALIGNMENT-((unsigned)nodeData & BVH_ALIGNMENT_MASK))&BVH_ALIGNMENT_MASK; + nodeData += sizeToAdd; + + // Now serialize the subtree headers + bvh->m_SubtreeHeaders.initializeFromBuffer(nodeData, bvh->m_subtreeHeaderCount, bvh->m_subtreeHeaderCount); + if (i_swapEndian) + { + for (int i = 0; i < bvh->m_subtreeHeaderCount; i++) + { + bvh->m_SubtreeHeaders[i].m_quantizedAabbMin[0] = btSwapEndian(bvh->m_SubtreeHeaders[i].m_quantizedAabbMin[0]); + bvh->m_SubtreeHeaders[i].m_quantizedAabbMin[1] = btSwapEndian(bvh->m_SubtreeHeaders[i].m_quantizedAabbMin[1]); + bvh->m_SubtreeHeaders[i].m_quantizedAabbMin[2] = btSwapEndian(bvh->m_SubtreeHeaders[i].m_quantizedAabbMin[2]); + + bvh->m_SubtreeHeaders[i].m_quantizedAabbMax[0] = btSwapEndian(bvh->m_SubtreeHeaders[i].m_quantizedAabbMax[0]); + bvh->m_SubtreeHeaders[i].m_quantizedAabbMax[1] = btSwapEndian(bvh->m_SubtreeHeaders[i].m_quantizedAabbMax[1]); + bvh->m_SubtreeHeaders[i].m_quantizedAabbMax[2] = btSwapEndian(bvh->m_SubtreeHeaders[i].m_quantizedAabbMax[2]); + + bvh->m_SubtreeHeaders[i].m_rootNodeIndex = btSwapEndian(bvh->m_SubtreeHeaders[i].m_rootNodeIndex); + bvh->m_SubtreeHeaders[i].m_subtreeSize = btSwapEndian(bvh->m_SubtreeHeaders[i].m_subtreeSize); + } + } + + return bvh; +} + +// Constructor that prevents btVector3's default constructor from being called +btOptimizedBvh::btOptimizedBvh(btOptimizedBvh &self, bool ownsMemory) : +m_bvhAabbMin(self.m_bvhAabbMin), +m_bvhAabbMax(self.m_bvhAabbMax), +m_bvhQuantization(self.m_bvhQuantization) +{ + +} + diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btOptimizedBvh.h b/extern/bullet2/src/BulletCollision/CollisionShapes/btOptimizedBvh.h index d5159586344..bcacdbe582b 100644 --- a/extern/bullet2/src/BulletCollision/CollisionShapes/btOptimizedBvh.h +++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btOptimizedBvh.h @@ -17,7 +17,9 @@ subject to the following restrictions: #define OPTIMIZED_BVH_H -#include "../../LinearMath/btVector3.h" + +#include "LinearMath/btVector3.h" +#include "LinearMath/btAlignedAllocator.h" //http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vclang/html/vclrf__m128.asp @@ -34,7 +36,8 @@ class btStridingMeshInterface; ///Node can be used for leafnode or internal node. Leafnodes can point to 32-bit triangle index (non-negative range). ATTRIBUTE_ALIGNED16 (struct) btQuantizedBvhNode { - + BT_DECLARE_ALIGNED_ALLOCATOR(); + //12 bytes unsigned short int m_quantizedAabbMin[3]; unsigned short int m_quantizedAabbMax[3]; @@ -63,6 +66,8 @@ ATTRIBUTE_ALIGNED16 (struct) btQuantizedBvhNode /// Total node size is 44 bytes / node. You can use the compressed version of 16 bytes. ATTRIBUTE_ALIGNED16 (struct) btOptimizedBvhNode { + BT_DECLARE_ALIGNED_ALLOCATOR(); + //32 bytes btVector3 m_aabbMinOrg; btVector3 m_aabbMaxOrg; @@ -84,6 +89,8 @@ ATTRIBUTE_ALIGNED16 (struct) btOptimizedBvhNode ATTRIBUTE_ALIGNED16(class) btBvhSubtreeInfo { public: + BT_DECLARE_ALIGNED_ALLOCATOR(); + //12 bytes unsigned short int m_quantizedAabbMin[3]; unsigned short int m_quantizedAabbMax[3]; @@ -93,6 +100,11 @@ public: int m_subtreeSize; int m_padding[3]; + btBvhSubtreeInfo() + { + //memset(&m_padding[0], 0, sizeof(m_padding)); + } + void setAabbFromQuantizeNode(const btQuantizedBvhNode& quantizedNode) { @@ -115,8 +127,8 @@ public: virtual void processNode(int subPart, int triangleIndex) = 0; }; -#include "../../LinearMath/btAlignedAllocator.h" -#include "../../LinearMath/btAlignedObjectArray.h" +#include "LinearMath/btAlignedAllocator.h" +#include "LinearMath/btAlignedObjectArray.h" @@ -144,6 +156,8 @@ ATTRIBUTE_ALIGNED16(class) btOptimizedBvh btVector3 m_bvhAabbMin; btVector3 m_bvhAabbMax; btVector3 m_bvhQuantization; +public: + BT_DECLARE_ALIGNED_ALLOCATOR(); enum btTraversalMode { @@ -151,14 +165,15 @@ ATTRIBUTE_ALIGNED16(class) btOptimizedBvh TRAVERSAL_STACKLESS_CACHE_FRIENDLY, TRAVERSAL_RECURSIVE }; +protected: btTraversalMode m_traversalMode; - - - BvhSubtreeInfoArray m_SubtreeHeaders; + //This is only used for serialization so we don't have to add serialization directly to btAlignedObjectArray + int m_subtreeHeaderCount; + ///two versions, one for quantized and normal nodes. This allows code-reuse while maintaining readability (no template/macro!) ///this might be refactored into a virtual, it is usually not calculated at run-time @@ -273,7 +288,18 @@ protected: void walkRecursiveQuantizedTreeAgainstQuantizedTree(const btQuantizedBvhNode* treeNodeA,const btQuantizedBvhNode* treeNodeB,btNodeOverlapCallback* nodeCallback) const; - inline bool testQuantizedAabbAgainstQuantizedAabb(unsigned short int* aabbMin1,unsigned short int* aabbMax1,const unsigned short int* aabbMin2,const unsigned short int* aabbMax2) const +#define USE_BANCHLESS 1 +#ifdef USE_BANCHLESS + //This block replaces the block below and uses no branches, and replaces the 8 bit return with a 32 bit return for improved performance (~3x on XBox 360) + SIMD_FORCE_INLINE unsigned testQuantizedAabbAgainstQuantizedAabb(unsigned short int* aabbMin1,unsigned short int* aabbMax1,const unsigned short int* aabbMin2,const unsigned short int* aabbMax2) const + { + return btSelect((unsigned)((aabbMin1[0] <= aabbMax2[0]) & (aabbMax1[0] >= aabbMin2[0]) + & (aabbMin1[2] <= aabbMax2[2]) & (aabbMax1[2] >= aabbMin2[2]) + & (aabbMin1[1] <= aabbMax2[1]) & (aabbMax1[1] >= aabbMin2[1])), + 1, 0); + } +#else + SIMD_FORCE_INLINE bool testQuantizedAabbAgainstQuantizedAabb(unsigned short int* aabbMin1,unsigned short int* aabbMax1,const unsigned short int* aabbMin2,const unsigned short int* aabbMax2) const { bool overlap = true; overlap = (aabbMin1[0] > aabbMax2[0] || aabbMax1[0] < aabbMin2[0]) ? false : overlap; @@ -281,6 +307,7 @@ protected: overlap = (aabbMin1[1] > aabbMax2[1] || aabbMax1[1] < aabbMin2[1]) ? false : overlap; return overlap; } +#endif //USE_BANCHLESS void updateSubtreeHeaders(int leftChildNodexIndex,int rightChildNodexIndex); @@ -294,8 +321,22 @@ public: void reportAabbOverlappingNodex(btNodeOverlapCallback* nodeCallback,const btVector3& aabbMin,const btVector3& aabbMax) const; void reportSphereOverlappingNodex(btNodeOverlapCallback* nodeCallback,const btVector3& aabbMin,const btVector3& aabbMax) const; + + SIMD_FORCE_INLINE void quantizeWithClamp(unsigned short* out, const btVector3& point) const + { + + btAssert(m_useQuantization); + + btVector3 clampedPoint(point); + clampedPoint.setMax(m_bvhAabbMin); + clampedPoint.setMin(m_bvhAabbMax); + + btVector3 v = (clampedPoint - m_bvhAabbMin) * m_bvhQuantization; + out[0] = (unsigned short)(v.getX()+0.5f); + out[1] = (unsigned short)(v.getY()+0.5f); + out[2] = (unsigned short)(v.getZ()+0.5f); + } - void quantizeWithClamp(unsigned short* out, const btVector3& point) const; btVector3 unQuantize(const unsigned short* vecIn) const; @@ -312,15 +353,37 @@ public: void updateBvhNodes(btStridingMeshInterface* meshInterface,int firstNode,int endNode,int index); - QuantizedNodeArray& getQuantizedNodeArray() + SIMD_FORCE_INLINE QuantizedNodeArray& getQuantizedNodeArray() { return m_quantizedContiguousNodes; } - BvhSubtreeInfoArray& getSubtreeInfoArray() + SIMD_FORCE_INLINE BvhSubtreeInfoArray& getSubtreeInfoArray() { return m_SubtreeHeaders; } + + /////Calculate space needed to store BVH for serialization + unsigned calculateSerializeBufferSize(); + + /// Data buffer MUST be 16 byte aligned + bool serialize(void *o_alignedDataBuffer, unsigned i_dataBufferSize, bool i_swapEndian); + + ///deSerializeInPlace loads and initializes a BVH from a buffer in memory 'in place' + static btOptimizedBvh *deSerializeInPlace(void *i_alignedDataBuffer, unsigned i_dataBufferSize, bool i_swapEndian); + + static unsigned int getAlignmentSerializationPadding(); + + SIMD_FORCE_INLINE bool isQuantized() + { + return m_useQuantization; + } + +private: + // Special "copy" constructor that allows for in-place deserialization + // Prevents btVector3's default constructor from being called, but doesn't inialize much else + // ownsMemory should most likely be false if deserializing, and if you are not, don't call this (it also changes the function signature, which we need) + btOptimizedBvh(btOptimizedBvh &other, bool ownsMemory); } ; diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btPolyhedralConvexShape.cpp b/extern/bullet2/src/BulletCollision/CollisionShapes/btPolyhedralConvexShape.cpp index bbc4ba62af6..30323deb3b5 100644 --- a/extern/bullet2/src/BulletCollision/CollisionShapes/btPolyhedralConvexShape.cpp +++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btPolyhedralConvexShape.cpp @@ -95,7 +95,7 @@ void btPolyhedralConvexShape::batchedUnitVectorGetSupportingVertexWithoutMargin( -void btPolyhedralConvexShape::calculateLocalInertia(btScalar mass,btVector3& inertia) +void btPolyhedralConvexShape::calculateLocalInertia(btScalar mass,btVector3& inertia) const { //not yet, return box inertia diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btPolyhedralConvexShape.h b/extern/bullet2/src/BulletCollision/CollisionShapes/btPolyhedralConvexShape.h index c35f7512663..9d46b991e10 100644 --- a/extern/bullet2/src/BulletCollision/CollisionShapes/btPolyhedralConvexShape.h +++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btPolyhedralConvexShape.h @@ -16,13 +16,13 @@ subject to the following restrictions: #ifndef BU_SHAPE #define BU_SHAPE -#include "../../LinearMath/btPoint3.h" -#include "../../LinearMath/btMatrix3x3.h" -#include "btConvexShape.h" +#include "LinearMath/btPoint3.h" +#include "LinearMath/btMatrix3x3.h" +#include "btConvexInternalShape.h" ///PolyhedralConvexShape is an interface class for feature based (vertex/edge/face) convex shapes. -class btPolyhedralConvexShape : public btConvexShape +class btPolyhedralConvexShape : public btConvexInternalShape { protected: @@ -38,7 +38,7 @@ public: virtual btVector3 localGetSupportingVertexWithoutMargin(const btVector3& vec)const; virtual void batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const; - virtual void calculateLocalInertia(btScalar mass,btVector3& inertia); + virtual void calculateLocalInertia(btScalar mass,btVector3& inertia) const; inline void getNonvirtualAabb(const btTransform& trans,btVector3& aabbMin,btVector3& aabbMax, btScalar margin) const diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btSphereShape.cpp b/extern/bullet2/src/BulletCollision/CollisionShapes/btSphereShape.cpp index ca65dd03f3e..15cfe432e27 100644 --- a/extern/bullet2/src/BulletCollision/CollisionShapes/btSphereShape.cpp +++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btSphereShape.cpp @@ -68,7 +68,7 @@ void btSphereShape::getAabb(const btTransform& t,btVector3& aabbMin,btVector3& a -void btSphereShape::calculateLocalInertia(btScalar mass,btVector3& inertia) +void btSphereShape::calculateLocalInertia(btScalar mass,btVector3& inertia) const { btScalar elem = btScalar(0.4) * mass * getMargin()*getMargin(); inertia.setValue(elem,elem,elem); diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btSphereShape.h b/extern/bullet2/src/BulletCollision/CollisionShapes/btSphereShape.h index 66521664087..d89a78b08e2 100644 --- a/extern/bullet2/src/BulletCollision/CollisionShapes/btSphereShape.h +++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btSphereShape.h @@ -16,15 +16,17 @@ subject to the following restrictions: #ifndef SPHERE_MINKOWSKI_H #define SPHERE_MINKOWSKI_H -#include "btConvexShape.h" -#include "../BroadphaseCollision/btBroadphaseProxy.h" // for the types +#include "btConvexInternalShape.h" +#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" // for the types ///btSphereShape implements an implicit (getSupportingVertex) Sphere -ATTRIBUTE_ALIGNED16(class) btSphereShape : public btConvexShape +ATTRIBUTE_ALIGNED16(class) btSphereShape : public btConvexInternalShape { public: + BT_DECLARE_ALIGNED_ALLOCATOR(); + btSphereShape (btScalar radius); @@ -34,26 +36,26 @@ public: virtual void batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const; - virtual void calculateLocalInertia(btScalar mass,btVector3& inertia); + virtual void calculateLocalInertia(btScalar mass,btVector3& inertia) const; virtual void getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const; virtual int getShapeType() const { return SPHERE_SHAPE_PROXYTYPE; } - btScalar getRadius() const { return m_implicitShapeDimensions.getX();} + btScalar getRadius() const { return m_implicitShapeDimensions.getX() * m_localScaling.getX();} //debugging - virtual char* getName()const {return "SPHERE";} + virtual const char* getName()const {return "SPHERE";} virtual void setMargin(btScalar margin) { - btConvexShape::setMargin(margin); + btConvexInternalShape::setMargin(margin); } virtual btScalar getMargin() const { //to improve gjk behaviour, use radius+margin as the full margin, so never get into the penetration case //this means, non-uniform scaling is not supported anymore - return m_localScaling.getX() * getRadius() + btConvexShape::getMargin(); + return getRadius(); } diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btStaticPlaneShape.cpp b/extern/bullet2/src/BulletCollision/CollisionShapes/btStaticPlaneShape.cpp index 4fbaafa1b93..7dd6425e0bd 100644 --- a/extern/bullet2/src/BulletCollision/CollisionShapes/btStaticPlaneShape.cpp +++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btStaticPlaneShape.cpp @@ -86,7 +86,7 @@ void btStaticPlaneShape::processAllTriangles(btTriangleCallback* callback,const } -void btStaticPlaneShape::calculateLocalInertia(btScalar mass,btVector3& inertia) +void btStaticPlaneShape::calculateLocalInertia(btScalar mass,btVector3& inertia) const { (void)mass; diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btStaticPlaneShape.h b/extern/bullet2/src/BulletCollision/CollisionShapes/btStaticPlaneShape.h index f59cc0c3347..0cbce3abd93 100644 --- a/extern/bullet2/src/BulletCollision/CollisionShapes/btStaticPlaneShape.h +++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btStaticPlaneShape.h @@ -46,14 +46,14 @@ public: virtual void processAllTriangles(btTriangleCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const; - virtual void calculateLocalInertia(btScalar mass,btVector3& inertia); + virtual void calculateLocalInertia(btScalar mass,btVector3& inertia) const; virtual void setLocalScaling(const btVector3& scaling); virtual const btVector3& getLocalScaling() const; //debugging - virtual char* getName()const {return "STATICPLANE";} + virtual const char* getName()const {return "STATICPLANE";} }; diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btStridingMeshInterface.cpp b/extern/bullet2/src/BulletCollision/CollisionShapes/btStridingMeshInterface.cpp index 03ca1ae7736..3129b7c83ce 100644 --- a/extern/bullet2/src/BulletCollision/CollisionShapes/btStridingMeshInterface.cpp +++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btStridingMeshInterface.cpp @@ -121,4 +121,4 @@ void btStridingMeshInterface::calculateAabbBruteForce(btVector3& aabbMin,btVecto aabbMin = aabbCallback.m_aabbMin; aabbMax = aabbCallback.m_aabbMax; -} \ No newline at end of file +} diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btStridingMeshInterface.h b/extern/bullet2/src/BulletCollision/CollisionShapes/btStridingMeshInterface.h index d7b354b7855..4ce0bd2e2f9 100644 --- a/extern/bullet2/src/BulletCollision/CollisionShapes/btStridingMeshInterface.h +++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btStridingMeshInterface.h @@ -16,7 +16,7 @@ subject to the following restrictions: #ifndef STRIDING_MESHINTERFACE_H #define STRIDING_MESHINTERFACE_H -#include "../../LinearMath/btVector3.h" +#include "LinearMath/btVector3.h" #include "btTriangleCallback.h" /// PHY_ScalarType enumerates possible scalar types. diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btTetrahedronShape.h b/extern/bullet2/src/BulletCollision/CollisionShapes/btTetrahedronShape.h index 94bc4ec0fa5..ca1b4b42a6f 100644 --- a/extern/bullet2/src/BulletCollision/CollisionShapes/btTetrahedronShape.h +++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btTetrahedronShape.h @@ -18,7 +18,7 @@ subject to the following restrictions: #include "btPolyhedralConvexShape.h" -#include "../BroadphaseCollision/btBroadphaseProxy.h" +#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" ///BU_Simplex1to4 implements feature based and implicit simplex of up to 4 vertices (tetrahedron, triangle, line, vertex). @@ -68,7 +68,7 @@ public: ///getName is for debugging - virtual char* getName()const { return "btBU_Simplex1to4";} + virtual const char* getName()const { return "btBU_Simplex1to4";} }; diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleBuffer.h b/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleBuffer.h index 3805c519d22..c97e58f121f 100644 --- a/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleBuffer.h +++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleBuffer.h @@ -17,7 +17,7 @@ subject to the following restrictions: #define BT_TRIANGLE_BUFFER_H #include "btTriangleCallback.h" -#include "../../LinearMath/btAlignedObjectArray.h" +#include "LinearMath/btAlignedObjectArray.h" struct btTriangle { diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleCallback.h b/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleCallback.h index fbb87bc4fd8..7b2337498ec 100644 --- a/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleCallback.h +++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleCallback.h @@ -16,7 +16,7 @@ subject to the following restrictions: #ifndef TRIANGLE_CALLBACK_H #define TRIANGLE_CALLBACK_H -#include "../../LinearMath/btVector3.h" +#include "LinearMath/btVector3.h" class btTriangleCallback diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleIndexVertexArray.cpp b/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleIndexVertexArray.cpp index 00847861cf1..554915a7058 100644 --- a/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleIndexVertexArray.cpp +++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleIndexVertexArray.cpp @@ -4,8 +4,8 @@ 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, +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. @@ -18,27 +18,36 @@ subject to the following restrictions: btTriangleIndexVertexArray::btTriangleIndexVertexArray(int numTriangles,int* triangleIndexBase,int triangleIndexStride,int numVertices,btScalar* vertexBase,int vertexStride) { btIndexedMesh mesh; - + mesh.m_numTriangles = numTriangles; mesh.m_triangleIndexBase = (const unsigned char *)triangleIndexBase; mesh.m_triangleIndexStride = triangleIndexStride; mesh.m_numVertices = numVertices; mesh.m_vertexBase = (const unsigned char *)vertexBase; mesh.m_vertexStride = vertexStride; - + addIndexedMesh(mesh); } +btTriangleIndexVertexArray::~btTriangleIndexVertexArray() +{ + +} + void btTriangleIndexVertexArray::getLockedVertexIndexBase(unsigned char **vertexbase, int& numverts,PHY_ScalarType& type, int& vertexStride,unsigned char **indexbase,int & indexstride,int& numfaces,PHY_ScalarType& indicestype,int subpart) { btAssert(subpart< getNumSubParts() ); - + btIndexedMesh& mesh = m_indexedMeshes[subpart]; numverts = mesh.m_numVertices; (*vertexbase) = (unsigned char *) mesh.m_vertexBase; + #ifdef BT_USE_DOUBLE_PRECISION + type = PHY_DOUBLE; + #else type = PHY_FLOAT; + #endif vertexStride = mesh.m_vertexStride; numfaces = mesh.m_numTriangles; @@ -54,7 +63,11 @@ void btTriangleIndexVertexArray::getLockedReadOnlyVertexIndexBase(const unsigned numverts = mesh.m_numVertices; (*vertexbase) = (const unsigned char *)mesh.m_vertexBase; + #ifdef BT_USE_DOUBLE_PRECISION + type = PHY_DOUBLE; + #else type = PHY_FLOAT; + #endif vertexStride = mesh.m_vertexStride; numfaces = mesh.m_numTriangles; diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleIndexVertexArray.h b/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleIndexVertexArray.h index 6ab6a762b39..3441a8325e2 100644 --- a/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleIndexVertexArray.h +++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleIndexVertexArray.h @@ -17,13 +17,17 @@ subject to the following restrictions: #define BT_TRIANGLE_INDEX_VERTEX_ARRAY_H #include "btStridingMeshInterface.h" -#include "../../LinearMath/btAlignedObjectArray.h" +#include "LinearMath/btAlignedObjectArray.h" +#include "LinearMath/btScalar.h" + ///IndexedMesh indexes into existing vertex and index arrays, in a similar way OpenGL glDrawElements ///instead of the number of indices, we pass the number of triangles ///todo: explain with pictures ATTRIBUTE_ALIGNED16( struct) btIndexedMesh { + BT_DECLARE_ALIGNED_ALLOCATOR(); + int m_numTriangles; const unsigned char * m_triangleIndexBase; int m_triangleIndexStride; @@ -49,10 +53,14 @@ ATTRIBUTE_ALIGNED16( class) btTriangleIndexVertexArray : public btStridingMeshIn public: + BT_DECLARE_ALIGNED_ALLOCATOR(); + btTriangleIndexVertexArray() { } + virtual ~btTriangleIndexVertexArray(); + //just to be backwards compatible btTriangleIndexVertexArray(int numTriangleIndices,int* triangleIndexBase,int triangleIndexStride,int numVertices,btScalar* vertexBase,int vertexStride); diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleMesh.h b/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleMesh.h index 525f5336b48..83e5a56d16a 100644 --- a/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleMesh.h +++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleMesh.h @@ -18,8 +18,8 @@ subject to the following restrictions: #define TRIANGLE_MESH_H #include "btStridingMeshInterface.h" -#include "../../LinearMath/btVector3.h" -#include "../../LinearMath/btAlignedObjectArray.h" +#include "LinearMath/btVector3.h" +#include "LinearMath/btAlignedObjectArray.h" ///TriangleMesh provides storage for a concave triangle mesh. It can be used as data for the btTriangleMeshShape. class btTriangleMesh : public btStridingMeshInterface diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleMeshShape.cpp b/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleMeshShape.cpp index ed81897b515..0d390c88b68 100644 --- a/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleMeshShape.cpp +++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleMeshShape.cpp @@ -20,7 +20,6 @@ subject to the following restrictions: #include "LinearMath/btAabbUtil2.h" #include "BulletCollision/CollisionShapes/btCollisionMargin.h" -#include "stdio.h" btTriangleMeshShape::btTriangleMeshShape(btStridingMeshInterface* meshInterface) : m_meshInterface(meshInterface) @@ -138,6 +137,7 @@ const btVector3& btTriangleMeshShape::getLocalScaling() const //#define DEBUG_TRIANGLE_MESH + void btTriangleMeshShape::processAllTriangles(btTriangleCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const { struct FilteredCallback : public btInternalTriangleIndexCallback @@ -174,8 +174,7 @@ void btTriangleMeshShape::processAllTriangles(btTriangleCallback* callback,const - -void btTriangleMeshShape::calculateLocalInertia(btScalar mass,btVector3& inertia) +void btTriangleMeshShape::calculateLocalInertia(btScalar mass,btVector3& inertia) const { (void)mass; //moving concave objects not supported diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleMeshShape.h b/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleMeshShape.h index e6173e47640..6657fc09147 100644 --- a/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleMeshShape.h +++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleMeshShape.h @@ -20,17 +20,19 @@ subject to the following restrictions: #include "btStridingMeshInterface.h" -///Concave triangle mesh. Uses an interface to access the triangles to allow for sharing graphics/physics triangles. +///Concave triangle mesh interface. Don't use this class directly, use btBvhTriangleMeshShape instead. class btTriangleMeshShape : public btConcaveShape { protected: btVector3 m_localAabbMin; btVector3 m_localAabbMax; btStridingMeshInterface* m_meshInterface; - + + ///btTriangleMeshShape constructor has been disabled/protected, so that users will not mistakenly use this class. + ///Don't use btTriangleMeshShape but use btBvhTriangleMeshShape instead! + btTriangleMeshShape(btStridingMeshInterface* meshInterface); public: - btTriangleMeshShape(btStridingMeshInterface* meshInterface); virtual ~btTriangleMeshShape(); @@ -53,7 +55,7 @@ public: virtual void processAllTriangles(btTriangleCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const; - virtual void calculateLocalInertia(btScalar mass,btVector3& inertia); + virtual void calculateLocalInertia(btScalar mass,btVector3& inertia) const; virtual void setLocalScaling(const btVector3& scaling); virtual const btVector3& getLocalScaling() const; @@ -70,7 +72,7 @@ public: //debugging - virtual char* getName()const {return "TRIANGLEMESH";} + virtual const char* getName()const {return "TRIANGLEMESH";} }; diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleShape.h b/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleShape.h index c2e240c051c..064c64fa6ab 100644 --- a/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleShape.h +++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleShape.h @@ -116,7 +116,7 @@ public: planeSupport = m_vertices1[0]; } - virtual void calculateLocalInertia(btScalar mass,btVector3& inertia) + virtual void calculateLocalInertia(btScalar mass,btVector3& inertia) const { (void)mass; btAssert(0); @@ -155,7 +155,7 @@ public: return false; } //debugging - virtual char* getName()const + virtual const char* getName()const { return "Triangle"; } diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btUniformScalingShape.cpp b/extern/bullet2/src/BulletCollision/CollisionShapes/btUniformScalingShape.cpp new file mode 100644 index 00000000000..ef340286cb0 --- /dev/null +++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btUniformScalingShape.cpp @@ -0,0 +1,114 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2007 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 "btUniformScalingShape.h" + +btUniformScalingShape::btUniformScalingShape( btConvexShape* convexChildShape,btScalar uniformScalingFactor): +m_childConvexShape(convexChildShape), +m_uniformScalingFactor(uniformScalingFactor) +{ +} + +btUniformScalingShape::~btUniformScalingShape() +{ +} + + +btVector3 btUniformScalingShape::localGetSupportingVertexWithoutMargin(const btVector3& vec)const +{ + btVector3 tmpVertex; + tmpVertex = m_childConvexShape->localGetSupportingVertexWithoutMargin(vec); + return tmpVertex*m_uniformScalingFactor; +} + +void btUniformScalingShape::batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const +{ + m_childConvexShape->batchedUnitVectorGetSupportingVertexWithoutMargin(vectors,supportVerticesOut,numVectors); + int i; + for (i=0;ilocalGetSupportingVertex(vec); + return tmpVertex*m_uniformScalingFactor; +} + + +void btUniformScalingShape::calculateLocalInertia(btScalar mass,btVector3& inertia) const +{ + + ///this linear upscaling is not realistic, but we don't deal with large mass ratios... + btVector3 tmpInertia; + m_childConvexShape->calculateLocalInertia(mass,tmpInertia); + inertia = tmpInertia * m_uniformScalingFactor; +} + + + ///getAabb's default implementation is brute force, expected derived classes to implement a fast dedicated version +void btUniformScalingShape::getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const +{ + m_childConvexShape->getAabb(t,aabbMin,aabbMax); + btVector3 aabbCenter = (aabbMax+aabbMin)*btScalar(0.5); + btVector3 scaledAabbHalfExtends = (aabbMax-aabbMin)*btScalar(0.5)*m_uniformScalingFactor; + + aabbMin = aabbCenter - scaledAabbHalfExtends; + aabbMax = aabbCenter + scaledAabbHalfExtends; + +} + +void btUniformScalingShape::getAabbSlow(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const +{ + m_childConvexShape->getAabbSlow(t,aabbMin,aabbMax); + btVector3 aabbCenter = (aabbMax+aabbMin)*btScalar(0.5); + btVector3 scaledAabbHalfExtends = (aabbMax-aabbMin)*btScalar(0.5)*m_uniformScalingFactor; + + aabbMin = aabbCenter - scaledAabbHalfExtends; + aabbMax = aabbCenter + scaledAabbHalfExtends; +} + +void btUniformScalingShape::setLocalScaling(const btVector3& scaling) +{ + m_childConvexShape->setLocalScaling(scaling); +} + +const btVector3& btUniformScalingShape::getLocalScaling() const +{ + return m_childConvexShape->getLocalScaling(); +} + +void btUniformScalingShape::setMargin(btScalar margin) +{ + m_childConvexShape->setMargin(margin); +} +btScalar btUniformScalingShape::getMargin() const +{ + return m_childConvexShape->getMargin() * m_uniformScalingFactor; +} + +int btUniformScalingShape::getNumPreferredPenetrationDirections() const +{ + return m_childConvexShape->getNumPreferredPenetrationDirections(); +} + +void btUniformScalingShape::getPreferredPenetrationDirection(int index, btVector3& penetrationVector) const +{ + m_childConvexShape->getPreferredPenetrationDirection(index,penetrationVector); +} diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btUniformScalingShape.h b/extern/bullet2/src/BulletCollision/CollisionShapes/btUniformScalingShape.h new file mode 100644 index 00000000000..3a0ecf021d3 --- /dev/null +++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btUniformScalingShape.h @@ -0,0 +1,86 @@ +/* +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 BT_UNIFORM_SCALING_SHAPE_H +#define BT_UNIFORM_SCALING_SHAPE_H + +#include "btConvexShape.h" +#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" // for the types + +class btUniformScalingShape : public btConvexShape +{ + btConvexShape* m_childConvexShape; + + btScalar m_uniformScalingFactor; + + public: + + btUniformScalingShape( btConvexShape* convexChildShape, btScalar uniformScalingFactor); + + virtual ~btUniformScalingShape(); + + virtual btVector3 localGetSupportingVertexWithoutMargin(const btVector3& vec)const; + + virtual btVector3 localGetSupportingVertex(const btVector3& vec)const; + + virtual void batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const; + + virtual void calculateLocalInertia(btScalar mass,btVector3& inertia) const; + + btScalar getUniformScalingFactor() const + { + return m_uniformScalingFactor; + } + + btConvexShape* getChildShape() + { + return m_childConvexShape; + } + + const btConvexShape* getChildShape() const + { + return m_childConvexShape; + } + + virtual const char* getName()const + { + return "UniformScalingShape"; + } + + virtual int getShapeType() const { return UNIFORM_SCALING_SHAPE_PROXYTYPE; } + + + /////////////////////////// + + + ///getAabb's default implementation is brute force, expected derived classes to implement a fast dedicated version + void getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const; + + virtual void getAabbSlow(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const; + + virtual void setLocalScaling(const btVector3& scaling) ; + virtual const btVector3& getLocalScaling() const ; + + virtual void setMargin(btScalar margin); + virtual btScalar getMargin() const; + + virtual int getNumPreferredPenetrationDirections() const; + + virtual void getPreferredPenetrationDirection(int index, btVector3& penetrationVector) const; + + +}; + +#endif //BT_UNIFORM_SCALING_SHAPE_H diff --git a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btContinuousConvexCollision.cpp b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btContinuousConvexCollision.cpp index 2c565734e97..c6a2b396d78 100644 --- a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btContinuousConvexCollision.cpp +++ b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btContinuousConvexCollision.cpp @@ -26,7 +26,7 @@ subject to the following restrictions: -btContinuousConvexCollision::btContinuousConvexCollision ( btConvexShape* convexA,btConvexShape* convexB,btSimplexSolverInterface* simplexSolver, btConvexPenetrationDepthSolver* penetrationDepthSolver) +btContinuousConvexCollision::btContinuousConvexCollision ( const btConvexShape* convexA,const btConvexShape* convexB,btSimplexSolverInterface* simplexSolver, btConvexPenetrationDepthSolver* penetrationDepthSolver) :m_simplexSolver(simplexSolver), m_penetrationDepthSolver(penetrationDepthSolver), m_convexA(convexA),m_convexB(convexB) @@ -93,7 +93,7 @@ bool btContinuousConvexCollision::calcTimeOfImpact( btGjkPairDetector::ClosestPointInput input; //we don't use margins during CCD - gjk.setIgnoreMargin(true); + // gjk.setIgnoreMargin(true); input.m_transformA = fromA; input.m_transformB = fromB; @@ -108,22 +108,26 @@ bool btContinuousConvexCollision::calcTimeOfImpact( btScalar dist; dist = pointCollector1.m_distance; n = pointCollector1.m_normalOnBInWorld; - + + + //not close enough while (dist > radius) { numIter++; if (numIter > maxIter) + { return false; //todo: report a failure - + } btScalar dLambda = btScalar(0.); + btScalar projectedLinearVelocity = (linVelB-linVelA).dot(n); + //calculate safe moving fraction from distance / (linear+rotational velocity) //btScalar clippedDist = GEN_min(angularConservativeRadius,dist); //btScalar clippedDist = dist; - btScalar projectedLinearVelocity = (linVelB-linVelA).dot(n); dLambda = dist / (projectedLinearVelocity+ maxAngularProjectedVelocity); @@ -135,9 +139,14 @@ bool btContinuousConvexCollision::calcTimeOfImpact( if (lambda < btScalar(0.)) return false; + //todo: next check with relative epsilon if (lambda <= lastLambda) + { + return false; + //n.setValue(0,0,0); break; + } lastLambda = lambda; @@ -163,11 +172,12 @@ bool btContinuousConvexCollision::calcTimeOfImpact( { //degenerate ?! result.m_fraction = lastLambda; - result.m_normal = n; + n = pointCollector.m_normalOnBInWorld; + result.m_normal=n;//.setValue(1,1,1);// = n; return true; } c = pointCollector.m_pointInWorld; - + n = pointCollector.m_normalOnBInWorld; dist = pointCollector.m_distance; } else { diff --git a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btContinuousConvexCollision.h b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btContinuousConvexCollision.h index 9901bab4b45..28c2b4d6156 100644 --- a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btContinuousConvexCollision.h +++ b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btContinuousConvexCollision.h @@ -30,13 +30,13 @@ class btContinuousConvexCollision : public btConvexCast { btSimplexSolverInterface* m_simplexSolver; btConvexPenetrationDepthSolver* m_penetrationDepthSolver; - btConvexShape* m_convexA; - btConvexShape* m_convexB; + const btConvexShape* m_convexA; + const btConvexShape* m_convexB; public: - btContinuousConvexCollision (btConvexShape* shapeA,btConvexShape* shapeB ,btSimplexSolverInterface* simplexSolver,btConvexPenetrationDepthSolver* penetrationDepthSolver); + btContinuousConvexCollision (const btConvexShape* shapeA,const btConvexShape* shapeB ,btSimplexSolverInterface* simplexSolver,btConvexPenetrationDepthSolver* penetrationDepthSolver); virtual bool calcTimeOfImpact( const btTransform& fromA, diff --git a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btConvexCast.h b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btConvexCast.h index 3101b59993d..cc80f0aa8da 100644 --- a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btConvexCast.h +++ b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btConvexCast.h @@ -17,11 +17,11 @@ subject to the following restrictions: #ifndef CONVEX_CAST_H #define CONVEX_CAST_H -#include "../../LinearMath/btTransform.h" -#include "../../LinearMath/btVector3.h" -#include "../../LinearMath/btScalar.h" +#include "LinearMath/btTransform.h" +#include "LinearMath/btVector3.h" +#include "LinearMath/btScalar.h" class btMinkowskiSumShape; -#include "../../LinearMath/btIDebugDraw.h" +#include "LinearMath/btIDebugDraw.h" /// btConvexCast is an interface for Casting class btConvexCast diff --git a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btConvexPenetrationDepthSolver.h b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btConvexPenetrationDepthSolver.h index 7caeba4be45..99690921317 100644 --- a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btConvexPenetrationDepthSolver.h +++ b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btConvexPenetrationDepthSolver.h @@ -21,7 +21,7 @@ class btStackAlloc; class btVector3; #include "btSimplexSolverInterface.h" class btConvexShape; -#include "../../LinearMath/btPoint3.h" +#include "LinearMath/btPoint3.h" class btTransform; ///ConvexPenetrationDepthSolver provides an interface for penetration depth calculation. @@ -31,7 +31,7 @@ public: virtual ~btConvexPenetrationDepthSolver() {}; virtual bool calcPenDepth( btSimplexSolverInterface& simplexSolver, - btConvexShape* convexA,btConvexShape* convexB, + const btConvexShape* convexA,const btConvexShape* convexB, const btTransform& transA,const btTransform& transB, btVector3& v, btPoint3& pa, btPoint3& pb, class btIDebugDraw* debugDraw,btStackAlloc* stackAlloc diff --git a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btDiscreteCollisionDetectorInterface.h b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btDiscreteCollisionDetectorInterface.h index 15000c1ab61..f11c8bd1290 100644 --- a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btDiscreteCollisionDetectorInterface.h +++ b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btDiscreteCollisionDetectorInterface.h @@ -16,8 +16,8 @@ subject to the following restrictions: #ifndef DISCRETE_COLLISION_DETECTOR1_INTERFACE_H #define DISCRETE_COLLISION_DETECTOR1_INTERFACE_H -#include "../../LinearMath/btTransform.h" -#include "../../LinearMath/btVector3.h" +#include "LinearMath/btTransform.h" +#include "LinearMath/btVector3.h" class btStackAlloc; /// This interface is made to be used by an iterative approach to do TimeOfImpact calculations diff --git a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkConvexCast.cpp b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkConvexCast.cpp index 93edffeafd6..da2a02b9839 100644 --- a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkConvexCast.cpp +++ b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkConvexCast.cpp @@ -22,7 +22,7 @@ subject to the following restrictions: #include "btPointCollector.h" -btGjkConvexCast::btGjkConvexCast(btConvexShape* convexA,btConvexShape* convexB,btSimplexSolverInterface* simplexSolver) +btGjkConvexCast::btGjkConvexCast(const btConvexShape* convexA,const btConvexShape* convexB,btSimplexSolverInterface* simplexSolver) :m_simplexSolver(simplexSolver), m_convexA(convexA), m_convexB(convexB) diff --git a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkConvexCast.h b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkConvexCast.h index 3905c45e6d6..a977c9e83f7 100644 --- a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkConvexCast.h +++ b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkConvexCast.h @@ -18,9 +18,9 @@ subject to the following restrictions: #ifndef GJK_CONVEX_CAST_H #define GJK_CONVEX_CAST_H -#include "../CollisionShapes/btCollisionMargin.h" +#include "BulletCollision/CollisionShapes/btCollisionMargin.h" -#include "../../LinearMath/btVector3.h" +#include "LinearMath/btVector3.h" #include "btConvexCast.h" class btConvexShape; class btMinkowskiSumShape; @@ -30,12 +30,12 @@ class btMinkowskiSumShape; class btGjkConvexCast : public btConvexCast { btSimplexSolverInterface* m_simplexSolver; - btConvexShape* m_convexA; - btConvexShape* m_convexB; + const btConvexShape* m_convexA; + const btConvexShape* m_convexB; public: - btGjkConvexCast(btConvexShape* convexA,btConvexShape* convexB,btSimplexSolverInterface* simplexSolver); + btGjkConvexCast(const btConvexShape* convexA,const btConvexShape* convexB,btSimplexSolverInterface* simplexSolver); /// cast a convex against another convex object virtual bool calcTimeOfImpact( diff --git a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkEpa.cpp b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkEpa.cpp index 8abdfdbb7e5..f57868be044 100644 --- a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkEpa.cpp +++ b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkEpa.cpp @@ -580,8 +580,8 @@ using namespace gjkepa_impl; // -bool btGjkEpaSolver::Collide(btConvexShape *shape0,const btTransform &wtrs0, - btConvexShape *shape1,const btTransform &wtrs1, +bool btGjkEpaSolver::Collide(const btConvexShape *shape0,const btTransform &wtrs0, + const btConvexShape *shape1,const btTransform &wtrs1, btScalar radialmargin, btStackAlloc* stackAlloc, sResults& results) diff --git a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkEpa.h b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkEpa.h index 759b30bb17f..1338e2714a8 100644 --- a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkEpa.h +++ b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkEpa.h @@ -21,7 +21,7 @@ Nov.2006 #ifndef _05E48D53_04E0_49ad_BB0A_D74FE62E7366_ #define _05E48D53_04E0_49ad_BB0A_D74FE62E7366_ -#include "../CollisionShapes/btConvexShape.h" +#include "BulletCollision/CollisionShapes/btConvexShape.h" class btStackAlloc; @@ -43,8 +43,8 @@ struct sResults int epa_iterations; int gjk_iterations; }; -static bool Collide(btConvexShape* shape0,const btTransform& wtrs0, - btConvexShape* shape1,const btTransform& wtrs1, +static bool Collide(const btConvexShape* shape0,const btTransform& wtrs0, + const btConvexShape* shape1,const btTransform& wtrs1, btScalar radialmargin, btStackAlloc* stackAlloc, sResults& results); diff --git a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.cpp b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.cpp index 87330493b60..9e600652333 100644 --- a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.cpp +++ b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.cpp @@ -20,7 +20,7 @@ subject to the following restrictions: #include "BulletCollision/NarrowPhaseCollision/btGjkEpa.h" bool btGjkEpaPenetrationDepthSolver::calcPenDepth( btSimplexSolverInterface& simplexSolver, - btConvexShape* pConvexA, btConvexShape* pConvexB, + const btConvexShape* pConvexA, const btConvexShape* pConvexB, const btTransform& transformA, const btTransform& transformB, btVector3& v, btPoint3& wWitnessOnA, btPoint3& wWitnessOnB, class btIDebugDraw* debugDraw, btStackAlloc* stackAlloc ) diff --git a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.h b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.h index 3916ba0776c..2dc069ce5cf 100644 --- a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.h +++ b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.h @@ -26,7 +26,7 @@ class btGjkEpaPenetrationDepthSolver : public btConvexPenetrationDepthSolver public : bool calcPenDepth( btSimplexSolverInterface& simplexSolver, - btConvexShape* pConvexA, btConvexShape* pConvexB, + const btConvexShape* pConvexA, const btConvexShape* pConvexB, const btTransform& transformA, const btTransform& transformB, btVector3& v, btPoint3& wWitnessOnA, btPoint3& wWitnessOnB, class btIDebugDraw* debugDraw,btStackAlloc* stackAlloc ); diff --git a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkPairDetector.cpp b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkPairDetector.cpp index f1f3f7f7f6c..c5f50d4dd1a 100644 --- a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkPairDetector.cpp +++ b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkPairDetector.cpp @@ -35,7 +35,7 @@ int gNumGjkChecks = 0; -btGjkPairDetector::btGjkPairDetector(btConvexShape* objectA,btConvexShape* objectB,btSimplexSolverInterface* simplexSolver,btConvexPenetrationDepthSolver* penetrationDepthSolver) +btGjkPairDetector::btGjkPairDetector(const btConvexShape* objectA,const btConvexShape* objectB,btSimplexSolverInterface* simplexSolver,btConvexPenetrationDepthSolver* penetrationDepthSolver) :m_cachedSeparatingAxis(btScalar(0.),btScalar(0.),btScalar(1.)), m_penetrationDepthSolver(penetrationDepthSolver), m_simplexSolver(simplexSolver), diff --git a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkPairDetector.h b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkPairDetector.h index af0fe32f6c7..1ec51f74069 100644 --- a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkPairDetector.h +++ b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkPairDetector.h @@ -20,8 +20,8 @@ subject to the following restrictions: #define GJK_PAIR_DETECTOR_H #include "btDiscreteCollisionDetectorInterface.h" -#include "../../LinearMath/btPoint3.h" -#include "../CollisionShapes/btCollisionMargin.h" +#include "LinearMath/btPoint3.h" +#include "BulletCollision/CollisionShapes/btCollisionMargin.h" class btConvexShape; #include "btSimplexSolverInterface.h" @@ -35,8 +35,8 @@ class btGjkPairDetector : public btDiscreteCollisionDetectorInterface btVector3 m_cachedSeparatingAxis; btConvexPenetrationDepthSolver* m_penetrationDepthSolver; btSimplexSolverInterface* m_simplexSolver; - btConvexShape* m_minkowskiA; - btConvexShape* m_minkowskiB; + const btConvexShape* m_minkowskiA; + const btConvexShape* m_minkowskiB; bool m_ignoreMargin; @@ -49,7 +49,7 @@ public: int m_catchDegeneracies; - btGjkPairDetector(btConvexShape* objectA,btConvexShape* objectB,btSimplexSolverInterface* simplexSolver,btConvexPenetrationDepthSolver* penetrationDepthSolver); + btGjkPairDetector(const btConvexShape* objectA,const btConvexShape* objectB,btSimplexSolverInterface* simplexSolver,btConvexPenetrationDepthSolver* penetrationDepthSolver); virtual ~btGjkPairDetector() {}; virtual void getClosestPoints(const ClosestPointInput& input,Result& output,class btIDebugDraw* debugDraw); diff --git a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btManifoldPoint.h b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btManifoldPoint.h index f6a893151da..1933d378f4f 100644 --- a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btManifoldPoint.h +++ b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btManifoldPoint.h @@ -16,8 +16,8 @@ subject to the following restrictions: #ifndef MANIFOLD_CONTACT_POINT_H #define MANIFOLD_CONTACT_POINT_H -#include "../../LinearMath/btVector3.h" -#include "../../LinearMath/btTransformUtil.h" +#include "LinearMath/btVector3.h" +#include "LinearMath/btTransformUtil.h" diff --git a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.cpp b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.cpp index c4bab3a134a..100bc240764 100644 --- a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.cpp +++ b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.cpp @@ -71,7 +71,7 @@ btVector3(btScalar(0.162456) , btScalar(0.499995),btScalar(0.850654)) bool btMinkowskiPenetrationDepthSolver::calcPenDepth(btSimplexSolverInterface& simplexSolver, - btConvexShape* convexA,btConvexShape* convexB, + const btConvexShape* convexA,const btConvexShape* convexB, const btTransform& transA,const btTransform& transB, btVector3& v, btPoint3& pa, btPoint3& pb, class btIDebugDraw* debugDraw,btStackAlloc* stackAlloc @@ -112,8 +112,7 @@ bool btMinkowskiPenetrationDepthSolver::calcPenDepth(btSimplexSolverInterface& s //just take fixed number of orientation, and sample the penetration depth in that direction btScalar minProj = btScalar(1e30); - btVector3 minNorm; - btVector3 minVertex; + btVector3 minNorm(btScalar(0.), btScalar(0.), btScalar(0.)); btVector3 minA,minB; btVector3 seperatingAxisInA,seperatingAxisInB; btVector3 pInA,qInB,pWorld,qWorld,w; diff --git a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.h b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.h index b348b21b52a..27b42c2b47e 100644 --- a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.h +++ b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.h @@ -25,7 +25,7 @@ class btMinkowskiPenetrationDepthSolver : public btConvexPenetrationDepthSolver public: virtual bool calcPenDepth( btSimplexSolverInterface& simplexSolver, - btConvexShape* convexA,btConvexShape* convexB, + const btConvexShape* convexA,const btConvexShape* convexB, const btTransform& transA,const btTransform& transB, btVector3& v, btPoint3& pa, btPoint3& pb, class btIDebugDraw* debugDraw,btStackAlloc* stackAlloc diff --git a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btPersistentManifold.cpp b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btPersistentManifold.cpp index 08cb3ed334d..ee94ee01149 100644 --- a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btPersistentManifold.cpp +++ b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btPersistentManifold.cpp @@ -27,20 +27,12 @@ btPersistentManifold::btPersistentManifold() :m_body0(0), m_body1(0), m_cachedPoints (0), -m_index1(0) +m_index1a(0) { } -void btPersistentManifold::clearManifold() -{ - int i; - for (i=0;i @@ -198,10 +190,20 @@ btScalar btPersistentManifold::getContactBreakingThreshold() const return gContactBreakingThreshold; } + + void btPersistentManifold::refreshContactPoints(const btTransform& trA,const btTransform& trB) { int i; - +#ifdef DEBUG_PERSISTENCY + printf("refreshContactPoints posA = (%f,%f,%f) posB = (%f,%f,%f)\n", + trA.getOrigin().getX(), + trA.getOrigin().getY(), + trA.getOrigin().getZ(), + trB.getOrigin().getX(), + trB.getOrigin().getY(), + trB.getOrigin().getZ()); +#endif //DEBUG_PERSISTENCY /// first refresh worldspace positions and distance for (i=getNumContacts()-1;i>=0;i--) { diff --git a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btPersistentManifold.h b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btPersistentManifold.h index a5918b84db3..f0b1ce58db7 100644 --- a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btPersistentManifold.h +++ b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btPersistentManifold.h @@ -17,9 +17,10 @@ subject to the following restrictions: #define PERSISTENT_MANIFOLD_H -#include "../../LinearMath/btVector3.h" -#include "../../LinearMath/btTransform.h" +#include "LinearMath/btVector3.h" +#include "LinearMath/btTransform.h" #include "btManifoldPoint.h" +#include "LinearMath/btAlignedAllocator.h" struct btCollisionResult; @@ -34,8 +35,13 @@ extern ContactDestroyedCallback gContactDestroyedCallback; #define MANIFOLD_CACHE_SIZE 4 -///btPersistentManifold maintains contact points, and reduces them to 4. -///It does contact filtering/contact reduction. +///btPersistentManifold is a contact point cache, it stays persistent as long as objects are overlapping in the broadphase. +///Those contact points are created by the collision narrow phase. +///The cache can be empty, or hold 1,2,3 or 4 points. Some collision algorithms (GJK) might only add one point at a time. +///updates/refreshes old contact points, and throw them away if necessary (distance becomes too large) +///reduces the cache to 4 points, when more then 4 points are added, using following rules: +///the contact point with deepest penetration is always kept, and it tries to maximuze the area covered by the points +///note that some pairs of objects might have more then one contact manifold. ATTRIBUTE_ALIGNED16( class) btPersistentManifold { @@ -55,20 +61,22 @@ ATTRIBUTE_ALIGNED16( class) btPersistentManifold public: - int m_index1; + BT_DECLARE_ALIGNED_ALLOCATOR(); + + int m_index1a; btPersistentManifold(); - btPersistentManifold(void* body0,void* body1) + btPersistentManifold(void* body0,void* body1,int bla) : m_body0(body0),m_body1(body1),m_cachedPoints(0) { } - inline void* getBody0() { return m_body0;} - inline void* getBody1() { return m_body1;} + SIMD_FORCE_INLINE void* getBody0() { return m_body0;} + SIMD_FORCE_INLINE void* getBody1() { return m_body1;} - inline const void* getBody0() const { return m_body0;} - inline const void* getBody1() const { return m_body1;} + SIMD_FORCE_INLINE const void* getBody0() const { return m_body0;} + SIMD_FORCE_INLINE const void* getBody1() const { return m_body1;} void setBodies(void* body0,void* body1) { @@ -82,15 +90,15 @@ public: void DebugPersistency(); #endif // - inline int getNumContacts() const { return m_cachedPoints;} + SIMD_FORCE_INLINE int getNumContacts() const { return m_cachedPoints;} - inline const btManifoldPoint& getContactPoint(int index) const + SIMD_FORCE_INLINE const btManifoldPoint& getContactPoint(int index) const { btAssert(index < m_cachedPoints); return m_pointCache[index]; } - inline btManifoldPoint& getContactPoint(int index) + SIMD_FORCE_INLINE btManifoldPoint& getContactPoint(int index) { btAssert(index < m_cachedPoints); return m_pointCache[index]; @@ -114,6 +122,7 @@ public: m_pointCache[index] = m_pointCache[lastUsedIndex]; //get rid of duplicated userPersistentData pointer m_pointCache[lastUsedIndex].m_userPersistentData = 0; + m_pointCache[lastUsedIndex].m_lifeTime = 0; } btAssert(m_pointCache[lastUsedIndex].m_userPersistentData==0); @@ -147,7 +156,16 @@ public: /// calculated new worldspace coordinates and depth, and reject points that exceed the collision margin void refreshContactPoints( const btTransform& trA,const btTransform& trB); - void clearManifold(); + + SIMD_FORCE_INLINE void clearManifold() + { + int i; + for (i=0;i btConeTwistConstraint::btConeTwistConstraint() +:btTypedConstraint(CONETWIST_CONSTRAINT_TYPE) { } btConeTwistConstraint::btConeTwistConstraint(btRigidBody& rbA,btRigidBody& rbB, const btTransform& rbAFrame,const btTransform& rbBFrame) - :btTypedConstraint(rbA,rbB),m_rbAFrame(rbAFrame),m_rbBFrame(rbBFrame), + :btTypedConstraint(CONETWIST_CONSTRAINT_TYPE, rbA,rbB),m_rbAFrame(rbAFrame),m_rbBFrame(rbBFrame), m_angularOnly(false) { // flip axis for correct angles @@ -49,7 +50,7 @@ btConeTwistConstraint::btConeTwistConstraint(btRigidBody& rbA,btRigidBody& rbB, } btConeTwistConstraint::btConeTwistConstraint(btRigidBody& rbA,const btTransform& rbAFrame) - :btTypedConstraint(rbA),m_rbAFrame(rbAFrame), + :btTypedConstraint(CONETWIST_CONSTRAINT_TYPE,rbA),m_rbAFrame(rbAFrame), m_angularOnly(false) { m_rbBFrame = m_rbAFrame; @@ -205,7 +206,6 @@ void btConeTwistConstraint::solveConstraint(btScalar timeStep) btVector3 pivotBInW = m_rbB.getCenterOfMassTransform()*m_rbBFrame.getOrigin(); btScalar tau = btScalar(0.3); - btScalar damping = btScalar(1.); //linear part if (!m_angularOnly) @@ -247,7 +247,7 @@ void btConeTwistConstraint::solveConstraint(btScalar timeStep) // Clamp the accumulated impulse btScalar temp = m_accSwingLimitImpulse; - m_accSwingLimitImpulse = btMax(m_accSwingLimitImpulse + impulseMag, 0.0f ); + m_accSwingLimitImpulse = btMax(m_accSwingLimitImpulse + impulseMag, btScalar(0.0) ); impulseMag = m_accSwingLimitImpulse - temp; btVector3 impulse = m_swingAxis * impulseMag; @@ -265,7 +265,7 @@ void btConeTwistConstraint::solveConstraint(btScalar timeStep) // Clamp the accumulated impulse btScalar temp = m_accTwistLimitImpulse; - m_accTwistLimitImpulse = btMax(m_accTwistLimitImpulse + impulseMag, 0.0f ); + m_accTwistLimitImpulse = btMax(m_accTwistLimitImpulse + impulseMag, btScalar(0.0) ); impulseMag = m_accTwistLimitImpulse - temp; btVector3 impulse = m_twistAxis * impulseMag; diff --git a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btConeTwistConstraint.h b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btConeTwistConstraint.h index 874669c80b3..f121919c8f9 100644 --- a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btConeTwistConstraint.h +++ b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btConeTwistConstraint.h @@ -30,6 +30,9 @@ class btRigidBody; ///btConeTwistConstraint can be used to simulate ragdoll joints (upper arm, leg etc) class btConeTwistConstraint : public btTypedConstraint { +#ifdef IN_PARALLELL_SOLVER +public: +#endif btJacobianEntry m_jac[3]; //3 orthogonal linear constraints btTransform m_rbAFrame; diff --git a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btConstraintSolver.h b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btConstraintSolver.h index 7e8458c2c7b..addfb67a839 100644 --- a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btConstraintSolver.h +++ b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btConstraintSolver.h @@ -16,7 +16,7 @@ subject to the following restrictions: #ifndef CONSTRAINT_SOLVER_H #define CONSTRAINT_SOLVER_H -#include "../../LinearMath/btScalar.h" +#include "LinearMath/btScalar.h" class btPersistentManifold; class btRigidBody; @@ -26,7 +26,7 @@ struct btContactSolverInfo; struct btBroadphaseProxy; class btIDebugDraw; class btStackAlloc; - +class btDispatcher; /// btConstraintSolver provides solver interface class btConstraintSolver { @@ -35,8 +35,15 @@ public: virtual ~btConstraintSolver() {} - virtual btScalar solveGroup(btCollisionObject** bodies,int numBodies,btPersistentManifold** manifold,int numManifolds,btTypedConstraint** constraints,int numConstraints, const btContactSolverInfo& info,class btIDebugDraw* debugDrawer, btStackAlloc* stackAlloc) = 0; + virtual void prepareSolve (int numBodies, int numManifolds) {;} + ///solve a group of constraints + virtual btScalar solveGroup(btCollisionObject** bodies,int numBodies,btPersistentManifold** manifold,int numManifolds,btTypedConstraint** constraints,int numConstraints, const btContactSolverInfo& info,class btIDebugDraw* debugDrawer, btStackAlloc* stackAlloc,btDispatcher* dispatcher) = 0; + + virtual void allSolved (const btContactSolverInfo& info,class btIDebugDraw* debugDrawer, btStackAlloc* stackAlloc) {;} + + ///clear internal cached data and reset random seed + virtual void reset() = 0; }; diff --git a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btContactConstraint.cpp b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btContactConstraint.cpp index bb3fe832592..1588428503a 100644 --- a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btContactConstraint.cpp +++ b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btContactConstraint.cpp @@ -192,8 +192,8 @@ btScalar resolveSingleFriction( j1 = -vrel * cpd->m_jacDiagABInvTangent0; btScalar oldTangentImpulse = cpd->m_accumulatedTangentImpulse0; cpd->m_accumulatedTangentImpulse0 = oldTangentImpulse + j1; - GEN_set_min(cpd->m_accumulatedTangentImpulse0, limit); - GEN_set_max(cpd->m_accumulatedTangentImpulse0, -limit); + btSetMin(cpd->m_accumulatedTangentImpulse0, limit); + btSetMax(cpd->m_accumulatedTangentImpulse0, -limit); j1 = cpd->m_accumulatedTangentImpulse0 - oldTangentImpulse; } @@ -206,8 +206,8 @@ btScalar resolveSingleFriction( j2 = -vrel * cpd->m_jacDiagABInvTangent1; btScalar oldTangentImpulse = cpd->m_accumulatedTangentImpulse1; cpd->m_accumulatedTangentImpulse1 = oldTangentImpulse + j2; - GEN_set_min(cpd->m_accumulatedTangentImpulse1, limit); - GEN_set_max(cpd->m_accumulatedTangentImpulse1, -limit); + btSetMin(cpd->m_accumulatedTangentImpulse1, limit); + btSetMax(cpd->m_accumulatedTangentImpulse1, -limit); j2 = cpd->m_accumulatedTangentImpulse1 - oldTangentImpulse; } @@ -270,8 +270,8 @@ btScalar resolveSingleFrictionOriginal( // calculate j that moves us to zero relative velocity btScalar j = -vrel * cpd->m_jacDiagABInvTangent0; btScalar total = cpd->m_accumulatedTangentImpulse0 + j; - GEN_set_min(total, limit); - GEN_set_max(total, -limit); + btSetMin(total, limit); + btSetMax(total, -limit); j = total - cpd->m_accumulatedTangentImpulse0; cpd->m_accumulatedTangentImpulse0 = total; body1.applyImpulse(j * cpd->m_frictionWorldTangential0, rel_pos1); @@ -290,8 +290,8 @@ btScalar resolveSingleFrictionOriginal( // calculate j that moves us to zero relative velocity btScalar j = -vrel * cpd->m_jacDiagABInvTangent1; btScalar total = cpd->m_accumulatedTangentImpulse1 + j; - GEN_set_min(total, limit); - GEN_set_max(total, -limit); + btSetMin(total, limit); + btSetMax(total, -limit); j = total - cpd->m_accumulatedTangentImpulse1; cpd->m_accumulatedTangentImpulse1 = total; body1.applyImpulse(j * cpd->m_frictionWorldTangential1, rel_pos1); @@ -388,8 +388,8 @@ btScalar resolveSingleCollisionCombined( (body1.getInvMass() + body2.getInvMass() + lat_vel.dot(temp1.cross(rel_pos1) + temp2.cross(rel_pos2))); btScalar normal_impulse = cpd->m_appliedImpulse * combinedFriction; - GEN_set_min(friction_impulse, normal_impulse); - GEN_set_max(friction_impulse, -normal_impulse); + btSetMin(friction_impulse, normal_impulse); + btSetMax(friction_impulse, -normal_impulse); body1.applyImpulse(lat_vel * -friction_impulse, rel_pos1); body2.applyImpulse(lat_vel * friction_impulse, rel_pos2); } diff --git a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btContactConstraint.h b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btContactConstraint.h index 0834deddeac..826e79f78bd 100644 --- a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btContactConstraint.h +++ b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btContactConstraint.h @@ -19,8 +19,8 @@ subject to the following restrictions: //todo: make into a proper class working with the iterative constraint solver class btRigidBody; -#include "../../LinearMath/btVector3.h" -#include "../../LinearMath/btScalar.h" +#include "LinearMath/btVector3.h" +#include "LinearMath/btScalar.h" struct btContactSolverInfo; class btManifoldPoint; diff --git a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btContactSolverInfo.h b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btContactSolverInfo.h index c3c73e300f4..ad2c40e2107 100644 --- a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btContactSolverInfo.h +++ b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btContactSolverInfo.h @@ -16,8 +16,21 @@ subject to the following restrictions: #ifndef CONTACT_SOLVER_INFO #define CONTACT_SOLVER_INFO +struct btContactSolverInfoData +{ + btScalar m_tau; + btScalar m_damping; + btScalar m_friction; + btScalar m_timeStep; + btScalar m_restitution; + int m_numIterations; + btScalar m_maxErrorReduction; + btScalar m_sor; + btScalar m_erp; -struct btContactSolverInfo +}; + +struct btContactSolverInfo : public btContactSolverInfoData { inline btContactSolverInfo() @@ -32,16 +45,7 @@ struct btContactSolverInfo m_sor = btScalar(1.3); } - btScalar m_tau; - btScalar m_damping; - btScalar m_friction; - btScalar m_timeStep; - btScalar m_restitution; - int m_numIterations; - btScalar m_maxErrorReduction; - btScalar m_sor; - btScalar m_erp; - + }; #endif //CONTACT_SOLVER_INFO diff --git a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.cpp b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.cpp index 747d10d1f8b..96d48f9f7dd 100644 --- a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.cpp +++ b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.cpp @@ -4,14 +4,20 @@ 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, +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. */ +/* +2007-09-09 +Refactored by Francisco León +email: projectileman@yahoo.com +http://gimpact.sf.net +*/ #include "btGeneric6DofConstraint.h" @@ -19,371 +25,473 @@ subject to the following restrictions: #include "LinearMath/btTransformUtil.h" #include + static const btScalar kSign[] = { btScalar(1.0), btScalar(-1.0), btScalar(1.0) }; static const int kAxisA[] = { 1, 0, 0 }; static const int kAxisB[] = { 2, 2, 1 }; #define GENERIC_D6_DISABLE_WARMSTARTING 1 -btGeneric6DofConstraint::btGeneric6DofConstraint() +btScalar btGetMatrixElem(const btMatrix3x3& mat, int index) { -} - -btGeneric6DofConstraint::btGeneric6DofConstraint(btRigidBody& rbA, btRigidBody& rbB, const btTransform& frameInA, const btTransform& frameInB) -: btTypedConstraint(rbA, rbB) -, m_frameInA(frameInA) -, m_frameInB(frameInB) -{ - //free means upper < lower, - //locked means upper == lower - //limited means upper > lower - //so start all locked - for (int i=0; i<6;++i) - { - m_lowerLimit[i] = btScalar(0.0); - m_upperLimit[i] = btScalar(0.0); - m_accumulatedImpulse[i] = btScalar(0.0); - } - -} - - -void btGeneric6DofConstraint::buildJacobian() -{ - btVector3 localNormalInA(0,0,0); - - const btVector3& pivotInA = m_frameInA.getOrigin(); - const btVector3& pivotInB = m_frameInB.getOrigin(); - - btVector3 pivotAInW = m_rbA.getCenterOfMassTransform() * m_frameInA.getOrigin(); - btVector3 pivotBInW = m_rbB.getCenterOfMassTransform() * m_frameInB.getOrigin(); - - btVector3 rel_pos1 = pivotAInW - m_rbA.getCenterOfMassPosition(); - btVector3 rel_pos2 = pivotBInW - m_rbB.getCenterOfMassPosition(); - - int i; - //linear part - for (i=0;i<3;i++) - { - if (isLimited(i)) - { - localNormalInA[i] = 1; - btVector3 normalWorld = m_rbA.getCenterOfMassTransform().getBasis() * localNormalInA; - - - // Create linear atom - new (&m_jacLinear[i]) btJacobianEntry( - m_rbA.getCenterOfMassTransform().getBasis().transpose(), - m_rbB.getCenterOfMassTransform().getBasis().transpose(), - m_rbA.getCenterOfMassTransform()*pivotInA - m_rbA.getCenterOfMassPosition(), - m_rbB.getCenterOfMassTransform()*pivotInB - m_rbB.getCenterOfMassPosition(), - normalWorld, - m_rbA.getInvInertiaDiagLocal(), - m_rbA.getInvMass(), - m_rbB.getInvInertiaDiagLocal(), - m_rbB.getInvMass()); - - //optionally disable warmstarting -#ifdef GENERIC_D6_DISABLE_WARMSTARTING - m_accumulatedImpulse[i] = btScalar(0.); -#endif //GENERIC_D6_DISABLE_WARMSTARTING - - // Apply accumulated impulse - btVector3 impulse_vector = m_accumulatedImpulse[i] * normalWorld; - - m_rbA.applyImpulse( impulse_vector, rel_pos1); - m_rbB.applyImpulse(-impulse_vector, rel_pos2); - - localNormalInA[i] = 0; - } - } - - // angular part - for (i=0;i<3;i++) - { - if (isLimited(i+3)) - { - btVector3 axisA = m_rbA.getCenterOfMassTransform().getBasis() * m_frameInA.getBasis().getColumn( kAxisA[i] ); - btVector3 axisB = m_rbB.getCenterOfMassTransform().getBasis() * m_frameInB.getBasis().getColumn( kAxisB[i] ); - - // Dirk: This is IMO mathematically the correct way, but we should consider axisA and axisB being near parallel maybe - btVector3 axis = kSign[i] * axisA.cross(axisB); - - // Create angular atom - new (&m_jacAng[i]) btJacobianEntry(axis, - m_rbA.getCenterOfMassTransform().getBasis().transpose(), - m_rbB.getCenterOfMassTransform().getBasis().transpose(), - m_rbA.getInvInertiaDiagLocal(), - m_rbB.getInvInertiaDiagLocal()); - -#ifdef GENERIC_D6_DISABLE_WARMSTARTING - m_accumulatedImpulse[i + 3] = btScalar(0.); -#endif //GENERIC_D6_DISABLE_WARMSTARTING - - // Apply accumulated impulse - btVector3 impulse_vector = m_accumulatedImpulse[i + 3] * axis; - - m_rbA.applyTorqueImpulse( impulse_vector); - m_rbB.applyTorqueImpulse(-impulse_vector); - } - } -} - -btScalar getMatrixElem(const btMatrix3x3& mat,int index) -{ - int row = index%3; - int col = index / 3; - return mat[row][col]; + int i = index%3; + int j = index/3; + return mat[i][j]; } ///MatrixToEulerXYZ from http://www.geometrictools.com/LibFoundation/Mathematics/Wm4Matrix3.inl.html -bool MatrixToEulerXYZ(const btMatrix3x3& mat,btVector3& xyz) +bool matrixToEulerXYZ(const btMatrix3x3& mat,btVector3& xyz) { - // rot = cy*cz -cy*sz sy - // cz*sx*sy+cx*sz cx*cz-sx*sy*sz -cy*sx - // -cx*cz*sy+sx*sz cz*sx+cx*sy*sz cx*cy +// // rot = cy*cz -cy*sz sy +// // cz*sx*sy+cx*sz cx*cz-sx*sy*sz -cy*sx +// // -cx*cz*sy+sx*sz cz*sx+cx*sy*sz cx*cy +// + + if (btGetMatrixElem(mat,2) < btScalar(1.0)) + { + if (btGetMatrixElem(mat,2) > btScalar(-1.0)) + { + xyz[0] = btAtan2(-btGetMatrixElem(mat,5),btGetMatrixElem(mat,8)); + xyz[1] = btAsin(btGetMatrixElem(mat,2)); + xyz[2] = btAtan2(-btGetMatrixElem(mat,1),btGetMatrixElem(mat,0)); + return true; + } + else + { + // WARNING. Not unique. XA - ZA = -atan2(r10,r11) + xyz[0] = -btAtan2(btGetMatrixElem(mat,3),btGetMatrixElem(mat,4)); + xyz[1] = -SIMD_HALF_PI; + xyz[2] = btScalar(0.0); + return false; + } + } + else + { + // WARNING. Not unique. XAngle + ZAngle = atan2(r10,r11) + xyz[0] = btAtan2(btGetMatrixElem(mat,3),btGetMatrixElem(mat,4)); + xyz[1] = SIMD_HALF_PI; + xyz[2] = 0.0; + + } -/// 0..8 - if (getMatrixElem(mat,2) < btScalar(1.0)) - { - if (getMatrixElem(mat,2) > btScalar(-1.0)) - { - xyz[0] = btAtan2(-getMatrixElem(mat,5),getMatrixElem(mat,8)); - xyz[1] = btAsin(getMatrixElem(mat,2)); - xyz[2] = btAtan2(-getMatrixElem(mat,1),getMatrixElem(mat,0)); - return true; - } - else - { - // WARNING. Not unique. XA - ZA = -atan2(r10,r11) - xyz[0] = -btAtan2(getMatrixElem(mat,3),getMatrixElem(mat,4)); - xyz[1] = -SIMD_HALF_PI; - xyz[2] = btScalar(0.0); - return false; - } - } - else - { - // WARNING. Not unique. XAngle + ZAngle = atan2(r10,r11) - xyz[0] = btAtan2(getMatrixElem(mat,3),getMatrixElem(mat,4)); - xyz[1] = SIMD_HALF_PI; - xyz[2] = 0.0; - - } - return false; } -void btGeneric6DofConstraint::solveConstraint(btScalar timeStep) + +//////////////////////////// btRotationalLimitMotor //////////////////////////////////// + + +int btRotationalLimitMotor::testLimitValue(btScalar test_value) { - btScalar tau = btScalar(0.1); - btScalar damping = btScalar(1.0); - - btVector3 pivotAInW = m_rbA.getCenterOfMassTransform() * m_frameInA.getOrigin(); - btVector3 pivotBInW = m_rbB.getCenterOfMassTransform() * m_frameInB.getOrigin(); - - btVector3 rel_pos1 = pivotAInW - m_rbA.getCenterOfMassPosition(); - btVector3 rel_pos2 = pivotBInW - m_rbB.getCenterOfMassPosition(); - - btVector3 localNormalInA(0,0,0); - int i; - - // linear - for (i=0;i<3;i++) - { - if (isLimited(i)) - { - btVector3 angvelA = m_rbA.getCenterOfMassTransform().getBasis().transpose() * m_rbA.getAngularVelocity(); - btVector3 angvelB = m_rbB.getCenterOfMassTransform().getBasis().transpose() * m_rbB.getAngularVelocity(); - - localNormalInA.setValue(0,0,0); - localNormalInA[i] = 1; - btVector3 normalWorld = m_rbA.getCenterOfMassTransform().getBasis() * localNormalInA; - - btScalar jacDiagABInv = btScalar(1.) / m_jacLinear[i].getDiagonal(); - - //velocity error (first order error) - btScalar rel_vel = m_jacLinear[i].getRelativeVelocity(m_rbA.getLinearVelocity(),angvelA, - m_rbB.getLinearVelocity(),angvelB); - - //positional error (zeroth order error) - btScalar depth = -(pivotAInW - pivotBInW).dot(normalWorld); - btScalar lo = btScalar(-1e30); - btScalar hi = btScalar(1e30); - - //handle the limits - if (m_lowerLimit[i] < m_upperLimit[i]) - { - { - if (depth > m_upperLimit[i]) - { - depth -= m_upperLimit[i]; - lo = btScalar(0.); - - } else - { - if (depth < m_lowerLimit[i]) - { - depth -= m_lowerLimit[i]; - hi = btScalar(0.); - } else - { - continue; - } - } - } - } - - btScalar normalImpulse= (tau*depth/timeStep - damping*rel_vel) * jacDiagABInv; - btScalar oldNormalImpulse = m_accumulatedImpulse[i]; - btScalar sum = oldNormalImpulse + normalImpulse; - m_accumulatedImpulse[i] = sum > hi ? btScalar(0.) : sum < lo ? btScalar(0.) : sum; - normalImpulse = m_accumulatedImpulse[i] - oldNormalImpulse; - - btVector3 impulse_vector = normalWorld * normalImpulse; - m_rbA.applyImpulse( impulse_vector, rel_pos1); - m_rbB.applyImpulse(-impulse_vector, rel_pos2); - - localNormalInA[i] = 0; - } - } - - btVector3 axis; - btScalar angle; - btTransform frameAWorld = m_rbA.getCenterOfMassTransform() * m_frameInA; - btTransform frameBWorld = m_rbB.getCenterOfMassTransform() * m_frameInB; - - btTransformUtil::calculateDiffAxisAngle(frameAWorld,frameBWorld,axis,angle); - btQuaternion diff(axis,angle); - btMatrix3x3 diffMat (diff); - btVector3 xyz; - ///this is not perfect, we can first check which axis are limited, and choose a more appropriate order - MatrixToEulerXYZ(diffMat,xyz); - - // angular - for (i=0;i<3;i++) + if(m_loLimit>m_hiLimit) { - if (isLimited(i+3)) - { - btVector3 angvelA = m_rbA.getCenterOfMassTransform().getBasis().transpose() * m_rbA.getAngularVelocity(); - btVector3 angvelB = m_rbB.getCenterOfMassTransform().getBasis().transpose() * m_rbB.getAngularVelocity(); - - btScalar jacDiagABInv = btScalar(1.) / m_jacAng[i].getDiagonal(); - - //velocity error (first order error) - btScalar rel_vel = m_jacAng[i].getRelativeVelocity(m_rbA.getLinearVelocity(),angvelA, - m_rbB.getLinearVelocity(),angvelB); - - //positional error (zeroth order error) - btVector3 axisA = m_rbA.getCenterOfMassTransform().getBasis() * m_frameInA.getBasis().getColumn( kAxisA[i] ); - btVector3 axisB = m_rbB.getCenterOfMassTransform().getBasis() * m_frameInB.getBasis().getColumn( kAxisB[i] ); - - btScalar rel_pos = kSign[i] * axisA.dot(axisB); - - btScalar lo = btScalar(-1e30); - btScalar hi = btScalar(1e30); - - //handle the twist limit - if (m_lowerLimit[i+3] < m_upperLimit[i+3]) - { - //clamp the values - btScalar loLimit = m_lowerLimit[i+3] > -3.1415 ? m_lowerLimit[i+3] : btScalar(-1e30); - btScalar hiLimit = m_upperLimit[i+3] < 3.1415 ? m_upperLimit[i+3] : btScalar(1e30); - - btScalar projAngle = btScalar(-1.)*xyz[i]; - - if (projAngle < loLimit) - { - hi = btScalar(0.); - rel_pos = (loLimit - projAngle); - } else - { - if (projAngle > hiLimit) - { - lo = btScalar(0.); - rel_pos = (hiLimit - projAngle); - } else - { - continue; - } - } - } - - //impulse - - btScalar normalImpulse= -(tau*rel_pos/timeStep + damping*rel_vel) * jacDiagABInv; - btScalar oldNormalImpulse = m_accumulatedImpulse[i+3]; - btScalar sum = oldNormalImpulse + normalImpulse; - m_accumulatedImpulse[i+3] = sum > hi ? btScalar(0.) : sum < lo ? btScalar(0.) : sum; - normalImpulse = m_accumulatedImpulse[i+3] - oldNormalImpulse; - - // Dirk: Not needed - we could actually project onto Jacobian entry here (same as above) - btVector3 axis = kSign[i] * axisA.cross(axisB); - btVector3 impulse_vector = axis * normalImpulse; - - m_rbA.applyTorqueImpulse( impulse_vector); - m_rbB.applyTorqueImpulse(-impulse_vector); - } + m_currentLimit = 0;//Free from violation + return 0; } + + if (test_value < m_loLimit) + { + m_currentLimit = 1;//low limit violation + m_currentLimitError = test_value - m_loLimit; + return 1; + } + else if (test_value> m_hiLimit) + { + m_currentLimit = 2;//High limit violation + m_currentLimitError = test_value - m_hiLimit; + return 2; + } + else + { + m_currentLimit = 0;//Free from violation + return 0; + } + return 0; +} + + +btScalar btRotationalLimitMotor::solveAngularLimits( + btScalar timeStep,btVector3& axis,btScalar jacDiagABInv, + btRigidBody * body0, btRigidBody * body1) +{ + if (needApplyTorques()==false) return 0.0f; + + btScalar target_velocity = m_targetVelocity; + btScalar maxMotorForce = m_maxMotorForce; + + //current error correction + if (m_currentLimit!=0) + { + target_velocity = -m_ERP*m_currentLimitError/(timeStep); + maxMotorForce = m_maxLimitForce; + } + + maxMotorForce *= timeStep; + + // current velocity difference + btVector3 vel_diff = body0->getAngularVelocity(); + if (body1) + { + vel_diff -= body1->getAngularVelocity(); + } + + + + btScalar rel_vel = axis.dot(vel_diff); + + // correction velocity + btScalar motor_relvel = m_limitSoftness*(target_velocity - m_damping*rel_vel); + + + if ( motor_relvel < SIMD_EPSILON && motor_relvel > -SIMD_EPSILON ) + { + return 0.0f;//no need for applying force + } + + + // correction impulse + btScalar unclippedMotorImpulse = (1+m_bounce)*motor_relvel*jacDiagABInv; + + // clip correction impulse + btScalar clippedMotorImpulse; + + //todo: should clip against accumulated impulse + if (unclippedMotorImpulse>0.0f) + { + clippedMotorImpulse = unclippedMotorImpulse > maxMotorForce? maxMotorForce: unclippedMotorImpulse; + } + else + { + clippedMotorImpulse = unclippedMotorImpulse < -maxMotorForce ? -maxMotorForce: unclippedMotorImpulse; + } + + + // sort with accumulated impulses + btScalar lo = btScalar(-1e30); + btScalar hi = btScalar(1e30); + + btScalar oldaccumImpulse = m_accumulatedImpulse; + btScalar sum = oldaccumImpulse + clippedMotorImpulse; + m_accumulatedImpulse = sum > hi ? btScalar(0.) : sum < lo ? btScalar(0.) : sum; + + clippedMotorImpulse = m_accumulatedImpulse - oldaccumImpulse; + + + + btVector3 motorImp = clippedMotorImpulse * axis; + + + body0->applyTorqueImpulse(motorImp); + if (body1) body1->applyTorqueImpulse(-motorImp); + + return clippedMotorImpulse; + + +} + +//////////////////////////// End btRotationalLimitMotor //////////////////////////////////// + +//////////////////////////// btTranslationalLimitMotor //////////////////////////////////// +btScalar btTranslationalLimitMotor::solveLinearAxis( + btScalar timeStep, + btScalar jacDiagABInv, + btRigidBody& body1,const btVector3 &pointInA, + btRigidBody& body2,const btVector3 &pointInB, + int limit_index, + const btVector3 & axis_normal_on_a) +{ + +///find relative velocity + btVector3 rel_pos1 = pointInA - body1.getCenterOfMassPosition(); + btVector3 rel_pos2 = pointInB - body2.getCenterOfMassPosition(); + + btVector3 vel1 = body1.getVelocityInLocalPoint(rel_pos1); + btVector3 vel2 = body2.getVelocityInLocalPoint(rel_pos2); + btVector3 vel = vel1 - vel2; + + btScalar rel_vel = axis_normal_on_a.dot(vel); + + + +/// apply displacement correction + +//positional error (zeroth order error) + btScalar depth = -(pointInA - pointInB).dot(axis_normal_on_a); + btScalar lo = btScalar(-1e30); + btScalar hi = btScalar(1e30); + + btScalar minLimit = m_lowerLimit[limit_index]; + btScalar maxLimit = m_upperLimit[limit_index]; + + //handle the limits + if (minLimit < maxLimit) + { + { + if (depth > maxLimit) + { + depth -= maxLimit; + lo = btScalar(0.); + + } + else + { + if (depth < minLimit) + { + depth -= minLimit; + hi = btScalar(0.); + } + else + { + return 0.0f; + } + } + } + } + + btScalar normalImpulse= m_limitSoftness*(m_restitution*depth/timeStep - m_damping*rel_vel) * jacDiagABInv; + + + + + btScalar oldNormalImpulse = m_accumulatedImpulse[limit_index]; + btScalar sum = oldNormalImpulse + normalImpulse; + m_accumulatedImpulse[limit_index] = sum > hi ? btScalar(0.) : sum < lo ? btScalar(0.) : sum; + normalImpulse = m_accumulatedImpulse[limit_index] - oldNormalImpulse; + + btVector3 impulse_vector = axis_normal_on_a * normalImpulse; + body1.applyImpulse( impulse_vector, rel_pos1); + body2.applyImpulse(-impulse_vector, rel_pos2); + return normalImpulse; +} + +//////////////////////////// btTranslationalLimitMotor //////////////////////////////////// + + +btGeneric6DofConstraint::btGeneric6DofConstraint() + :btTypedConstraint(D6_CONSTRAINT_TYPE), + m_useLinearReferenceFrameA(true) +{ +} + +btGeneric6DofConstraint::btGeneric6DofConstraint(btRigidBody& rbA, btRigidBody& rbB, const btTransform& frameInA, const btTransform& frameInB, bool useLinearReferenceFrameA) + : btTypedConstraint(D6_CONSTRAINT_TYPE, rbA, rbB) + , m_frameInA(frameInA) + , m_frameInB(frameInB), + m_useLinearReferenceFrameA(useLinearReferenceFrameA) +{ + +} + + + + + +void btGeneric6DofConstraint::calculateAngleInfo() +{ + btMatrix3x3 relative_frame = m_calculatedTransformA.getBasis().inverse()*m_calculatedTransformB.getBasis(); + + matrixToEulerXYZ(relative_frame,m_calculatedAxisAngleDiff); + + + + // in euler angle mode we do not actually constrain the angular velocity + // along the axes axis[0] and axis[2] (although we do use axis[1]) : + // + // to get constrain w2-w1 along ...not + // ------ --------------------- ------ + // d(angle[0])/dt = 0 ax[1] x ax[2] ax[0] + // d(angle[1])/dt = 0 ax[1] + // d(angle[2])/dt = 0 ax[0] x ax[1] ax[2] + // + // constraining w2-w1 along an axis 'a' means that a'*(w2-w1)=0. + // to prove the result for angle[0], write the expression for angle[0] from + // GetInfo1 then take the derivative. to prove this for angle[2] it is + // easier to take the euler rate expression for d(angle[2])/dt with respect + // to the components of w and set that to 0. + + btVector3 axis0 = m_calculatedTransformB.getBasis().getColumn(0); + btVector3 axis2 = m_calculatedTransformA.getBasis().getColumn(2); + + m_calculatedAxis[1] = axis2.cross(axis0); + m_calculatedAxis[0] = m_calculatedAxis[1].cross(axis2); + m_calculatedAxis[2] = axis0.cross(m_calculatedAxis[1]); + + +// if(m_debugDrawer) +// { +// +// char buff[300]; +// sprintf(buff,"\n X: %.2f ; Y: %.2f ; Z: %.2f ", +// m_calculatedAxisAngleDiff[0], +// m_calculatedAxisAngleDiff[1], +// m_calculatedAxisAngleDiff[2]); +// m_debugDrawer->reportErrorWarning(buff); +// } + +} + +void btGeneric6DofConstraint::calculateTransforms() +{ + m_calculatedTransformA = m_rbA.getCenterOfMassTransform() * m_frameInA; + m_calculatedTransformB = m_rbB.getCenterOfMassTransform() * m_frameInB; + + calculateAngleInfo(); +} + + +void btGeneric6DofConstraint::buildLinearJacobian( + btJacobianEntry & jacLinear,const btVector3 & normalWorld, + const btVector3 & pivotAInW,const btVector3 & pivotBInW) +{ + new (&jacLinear) btJacobianEntry( + m_rbA.getCenterOfMassTransform().getBasis().transpose(), + m_rbB.getCenterOfMassTransform().getBasis().transpose(), + pivotAInW - m_rbA.getCenterOfMassPosition(), + pivotBInW - m_rbB.getCenterOfMassPosition(), + normalWorld, + m_rbA.getInvInertiaDiagLocal(), + m_rbA.getInvMass(), + m_rbB.getInvInertiaDiagLocal(), + m_rbB.getInvMass()); + +} + +void btGeneric6DofConstraint::buildAngularJacobian( + btJacobianEntry & jacAngular,const btVector3 & jointAxisW) +{ + new (&jacAngular) btJacobianEntry(jointAxisW, + m_rbA.getCenterOfMassTransform().getBasis().transpose(), + m_rbB.getCenterOfMassTransform().getBasis().transpose(), + m_rbA.getInvInertiaDiagLocal(), + m_rbB.getInvInertiaDiagLocal()); + +} + +bool btGeneric6DofConstraint::testAngularLimitMotor(int axis_index) +{ + btScalar angle = m_calculatedAxisAngleDiff[axis_index]; + + //test limits + m_angularLimits[axis_index].testLimitValue(angle); + return m_angularLimits[axis_index].needApplyTorques(); +} + +void btGeneric6DofConstraint::buildJacobian() +{ + //calculates transform + calculateTransforms(); + + const btVector3& pivotAInW = m_calculatedTransformA.getOrigin(); + const btVector3& pivotBInW = m_calculatedTransformB.getOrigin(); + + + btVector3 rel_pos1 = pivotAInW - m_rbA.getCenterOfMassPosition(); + btVector3 rel_pos2 = pivotBInW - m_rbB.getCenterOfMassPosition(); + + btVector3 normalWorld; + int i; + //linear part + for (i=0;i<3;i++) + { + if (m_linearLimits.isLimited(i)) + { + if (m_useLinearReferenceFrameA) + normalWorld = m_calculatedTransformA.getBasis().getColumn(i); + else + normalWorld = m_calculatedTransformB.getBasis().getColumn(i); + + buildLinearJacobian( + m_jacLinear[i],normalWorld , + pivotAInW,pivotBInW); + + } + } + + // angular part + for (i=0;i<3;i++) + { + //calculates error angle + if (testAngularLimitMotor(i)) + { + normalWorld = this->getAxis(i); + // Create angular atom + buildAngularJacobian(m_jacAng[i],normalWorld); + } + } + + +} + + +void btGeneric6DofConstraint::solveConstraint(btScalar timeStep) +{ + m_timeStep = timeStep; + + //calculateTransforms(); + + int i; + + // linear + + btVector3 pointInA = m_calculatedTransformA.getOrigin(); + btVector3 pointInB = m_calculatedTransformB.getOrigin(); + + btScalar jacDiagABInv; + btVector3 linear_axis; + for (i=0;i<3;i++) + { + if (m_linearLimits.isLimited(i)) + { + jacDiagABInv = btScalar(1.) / m_jacLinear[i].getDiagonal(); + + if (m_useLinearReferenceFrameA) + linear_axis = m_calculatedTransformA.getBasis().getColumn(i); + else + linear_axis = m_calculatedTransformB.getBasis().getColumn(i); + + m_linearLimits.solveLinearAxis( + m_timeStep, + jacDiagABInv, + m_rbA,pointInA, + m_rbB,pointInB, + i,linear_axis); + + } + } + + // angular + btVector3 angular_axis; + btScalar angularJacDiagABInv; + for (i=0;i<3;i++) + { + if (m_angularLimits[i].needApplyTorques()) + { + + // get axis + angular_axis = getAxis(i); + + angularJacDiagABInv = btScalar(1.) / m_jacAng[i].getDiagonal(); + + m_angularLimits[i].solveAngularLimits(m_timeStep,angular_axis,angularJacDiagABInv, &m_rbA,&m_rbB); + } + } } void btGeneric6DofConstraint::updateRHS(btScalar timeStep) { - (void)timeStep; + (void)timeStep; } -btScalar btGeneric6DofConstraint::computeAngle(int axis) const - { - btScalar angle = btScalar(0.f); +btVector3 btGeneric6DofConstraint::getAxis(int axis_index) const +{ + return m_calculatedAxis[axis_index]; +} - switch (axis) - { - case 0: - { - btVector3 v1 = m_rbA.getCenterOfMassTransform().getBasis() * m_frameInA.getBasis().getColumn(1); - btVector3 v2 = m_rbB.getCenterOfMassTransform().getBasis() * m_frameInB.getBasis().getColumn(1); - btVector3 w2 = m_rbB.getCenterOfMassTransform().getBasis() * m_frameInB.getBasis().getColumn(2); +btScalar btGeneric6DofConstraint::getAngle(int axis_index) const +{ + return m_calculatedAxisAngleDiff[axis_index]; +} - btScalar s = v1.dot(w2); - btScalar c = v1.dot(v2); - - angle = btAtan2( s, c ); - } - break; - - case 1: - { - btVector3 w1 = m_rbA.getCenterOfMassTransform().getBasis() * m_frameInA.getBasis().getColumn(2); - btVector3 w2 = m_rbB.getCenterOfMassTransform().getBasis() * m_frameInB.getBasis().getColumn(2); - btVector3 u2 = m_rbB.getCenterOfMassTransform().getBasis() * m_frameInB.getBasis().getColumn(0); - - btScalar s = w1.dot(u2); - btScalar c = w1.dot(w2); - - angle = btAtan2( s, c ); - } - break; - - case 2: - { - btVector3 u1 = m_rbA.getCenterOfMassTransform().getBasis() * m_frameInA.getBasis().getColumn(0); - btVector3 u2 = m_rbB.getCenterOfMassTransform().getBasis() * m_frameInB.getBasis().getColumn(0); - btVector3 v2 = m_rbB.getCenterOfMassTransform().getBasis() * m_frameInB.getBasis().getColumn(1); - - btScalar s = u1.dot(v2); - btScalar c = u1.dot(u2); - - angle = btAtan2( s, c ); - } - break; - default: - btAssert ( 0 ) ; - - break ; - } - - return angle; - } diff --git a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.h b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.h index b114e54fa69..e4683b91b9e 100644 --- a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.h +++ b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.h @@ -4,116 +4,429 @@ 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, +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. */ +/* +2007-09-09 +btGeneric6DofConstraint Refactored by Francisco León +email: projectileman@yahoo.com +http://gimpact.sf.net +*/ + #ifndef GENERIC_6DOF_CONSTRAINT_H #define GENERIC_6DOF_CONSTRAINT_H -#include "../../LinearMath/btVector3.h" +#include "LinearMath/btVector3.h" #include "btJacobianEntry.h" #include "btTypedConstraint.h" class btRigidBody; +//! Rotation Limit structure for generic joints +class btRotationalLimitMotor +{ +public: + //! limit_parameters + //!@{ + btScalar m_loLimit;//!< joint limit + btScalar m_hiLimit;//!< joint limit + btScalar m_targetVelocity;//!< target motor velocity + btScalar m_maxMotorForce;//!< max force on motor + btScalar m_maxLimitForce;//!< max force on limit + btScalar m_damping;//!< Damping. + btScalar m_limitSoftness;//! Relaxation factor + btScalar m_ERP;//!< Error tolerance factor when joint is at limit + btScalar m_bounce;//!< restitution factor + bool m_enableMotor; + + //!@} + + //! temp_variables + //!@{ + btScalar m_currentLimitError;//! How much is violated this limit + int m_currentLimit;//!< 0=free, 1=at lo limit, 2=at hi limit + btScalar m_accumulatedImpulse; + //!@} + + btRotationalLimitMotor() + { + m_accumulatedImpulse = 0.f; + m_targetVelocity = 0; + m_maxMotorForce = 0.1f; + m_maxLimitForce = 300.0f; + m_loLimit = -SIMD_INFINITY; + m_hiLimit = SIMD_INFINITY; + m_ERP = 0.5f; + m_bounce = 0.0f; + m_damping = 1.0f; + m_limitSoftness = 0.5f; + m_currentLimit = 0; + m_currentLimitError = 0; + m_enableMotor = false; + } + + btRotationalLimitMotor(const btRotationalLimitMotor & limot) + { + m_targetVelocity = limot.m_targetVelocity; + m_maxMotorForce = limot.m_maxMotorForce; + m_limitSoftness = limot.m_limitSoftness; + m_loLimit = limot.m_loLimit; + m_hiLimit = limot.m_hiLimit; + m_ERP = limot.m_ERP; + m_bounce = limot.m_bounce; + m_currentLimit = limot.m_currentLimit; + m_currentLimitError = limot.m_currentLimitError; + m_enableMotor = limot.m_enableMotor; + } + + + + //! Is limited + bool isLimited() + { + if(m_loLimit>=m_hiLimit) return false; + return true; + } + + //! Need apply correction + bool needApplyTorques() + { + if(m_currentLimit == 0 && m_enableMotor == false) return false; + return true; + } + + //! calculates error + /*! + calculates m_currentLimit and m_currentLimitError. + */ + int testLimitValue(btScalar test_value); + + //! apply the correction impulses for two bodies + btScalar solveAngularLimits(btScalar timeStep,btVector3& axis, btScalar jacDiagABInv,btRigidBody * body0, btRigidBody * body1); + + +}; + + + +class btTranslationalLimitMotor +{ +public: + btVector3 m_lowerLimit;//!< the constraint lower limits + btVector3 m_upperLimit;//!< the constraint upper limits + btVector3 m_accumulatedImpulse; + //! Linear_Limit_parameters + //!@{ + btScalar m_limitSoftness;//!< Softness for linear limit + btScalar m_damping;//!< Damping for linear limit + btScalar m_restitution;//! Bounce parameter for linear limit + //!@} + + btTranslationalLimitMotor() + { + m_lowerLimit.setValue(0.f,0.f,0.f); + m_upperLimit.setValue(0.f,0.f,0.f); + m_accumulatedImpulse.setValue(0.f,0.f,0.f); + + m_limitSoftness = 0.7f; + m_damping = btScalar(1.0f); + m_restitution = btScalar(0.5f); + } + + btTranslationalLimitMotor(const btTranslationalLimitMotor & other ) + { + m_lowerLimit = other.m_lowerLimit; + m_upperLimit = other.m_upperLimit; + m_accumulatedImpulse = other.m_accumulatedImpulse; + + m_limitSoftness = other.m_limitSoftness ; + m_damping = other.m_damping; + m_restitution = other.m_restitution; + } + + //! Test limit + /*! + - free means upper < lower, + - locked means upper == lower + - limited means upper > lower + - limitIndex: first 3 are linear, next 3 are angular + */ + inline bool isLimited(int limitIndex) + { + return (m_upperLimit[limitIndex] >= m_lowerLimit[limitIndex]); + } + + + btScalar solveLinearAxis( + btScalar timeStep, + btScalar jacDiagABInv, + btRigidBody& body1,const btVector3 &pointInA, + btRigidBody& body2,const btVector3 &pointInB, + int limit_index, + const btVector3 & axis_normal_on_a); + + +}; /// btGeneric6DofConstraint between two rigidbodies each with a pivotpoint that descibes the axis location in local space -/// btGeneric6DofConstraint can leave any of the 6 degree of freedom 'free' or 'locked' -/// Work in progress (is still a Hinge actually) +/*! +btGeneric6DofConstraint can leave any of the 6 degree of freedom 'free' or 'locked'. +currently this limit supports rotational motors
+
    +
  • For Linear limits, use btGeneric6DofConstraint.setLinearUpperLimit, btGeneric6DofConstraint.setLinearLowerLimit. You can set the parameters with the btTranslationalLimitMotor structure accsesible through the btGeneric6DofConstraint.getTranslationalLimitMotor method. +At this moment translational motors are not supported. May be in the future.
  • + +
  • For Angular limits, use the btRotationalLimitMotor structure for configuring the limit. +This is accessible through btGeneric6DofConstraint.getLimitMotor method, +This brings support for limit parameters and motors.
  • + +
  • Angulars limits have these possible ranges: + +AXIS + + + + + + + + + + + + +
    MIN ANGLEMAX ANGLEX-PIPIY-PI/2PI/2Z-PI/2PI/2
    +
  • +
+ +*/ class btGeneric6DofConstraint : public btTypedConstraint { - btJacobianEntry m_jacLinear[3]; // 3 orthogonal linear constraints - btJacobianEntry m_jacAng[3]; // 3 orthogonal angular constraints +protected: - btTransform m_frameInA; // the constraint space w.r.t body A - btTransform m_frameInB; // the constraint space w.r.t body B + //! relative_frames + //!@{ + btTransform m_frameInA;//!< the constraint space w.r.t body A + btTransform m_frameInB;//!< the constraint space w.r.t body B + //!@} + + //! Jacobians + //!@{ + btJacobianEntry m_jacLinear[3];//!< 3 orthogonal linear constraints + btJacobianEntry m_jacAng[3];//!< 3 orthogonal angular constraints + //!@} + + //! Linear_Limit_parameters + //!@{ + btTranslationalLimitMotor m_linearLimits; + //!@} + + + //! hinge_parameters + //!@{ + btRotationalLimitMotor m_angularLimits[3]; + //!@} + + +protected: + //! temporal variables + //!@{ + btScalar m_timeStep; + btTransform m_calculatedTransformA; + btTransform m_calculatedTransformB; + btVector3 m_calculatedAxisAngleDiff; + btVector3 m_calculatedAxis[3]; + + bool m_useLinearReferenceFrameA; + + //!@} + + btGeneric6DofConstraint& operator=(btGeneric6DofConstraint& other) + { + btAssert(0); + (void) other; + return *this; + } + + + + void buildLinearJacobian( + btJacobianEntry & jacLinear,const btVector3 & normalWorld, + const btVector3 & pivotAInW,const btVector3 & pivotBInW); + + void buildAngularJacobian(btJacobianEntry & jacAngular,const btVector3 & jointAxisW); + + + //! calcs the euler angles between the two bodies. + void calculateAngleInfo(); - btScalar m_lowerLimit[6]; // the constraint lower limits - btScalar m_upperLimit[6]; // the constraint upper limits - btScalar m_accumulatedImpulse[6]; - btGeneric6DofConstraint& operator=(btGeneric6DofConstraint& other) - { - btAssert(0); - (void) other; - return *this; - } - public: - btGeneric6DofConstraint(btRigidBody& rbA, btRigidBody& rbB, const btTransform& frameInA, const btTransform& frameInB ); + btGeneric6DofConstraint(btRigidBody& rbA, btRigidBody& rbB, const btTransform& frameInA, const btTransform& frameInB ,bool useLinearReferenceFrameA); - btGeneric6DofConstraint(); + btGeneric6DofConstraint(); - - virtual void buildJacobian(); + //! Calcs global transform of the offsets + /*! + Calcs the global transform for the joint offset for body A an B, and also calcs the agle differences between the bodies. + \sa btGeneric6DofConstraint.getCalculatedTransformA , btGeneric6DofConstraint.getCalculatedTransformB, btGeneric6DofConstraint.calculateAngleInfo + */ + void calculateTransforms(); - virtual void solveConstraint(btScalar timeStep); + //! Gets the global transform of the offset for body A + /*! + \sa btGeneric6DofConstraint.getFrameOffsetA, btGeneric6DofConstraint.getFrameOffsetB, btGeneric6DofConstraint.calculateAngleInfo. + */ + const btTransform & getCalculatedTransformA() const + { + return m_calculatedTransformA; + } - void updateRHS(btScalar timeStep); + //! Gets the global transform of the offset for body B + /*! + \sa btGeneric6DofConstraint.getFrameOffsetA, btGeneric6DofConstraint.getFrameOffsetB, btGeneric6DofConstraint.calculateAngleInfo. + */ + const btTransform & getCalculatedTransformB() const + { + return m_calculatedTransformB; + } - btScalar computeAngle(int axis) const; + const btTransform & getFrameOffsetA() const + { + return m_frameInA; + } - void setLinearLowerLimit(const btVector3& linearLower) - { - m_lowerLimit[0] = linearLower.getX(); - m_lowerLimit[1] = linearLower.getY(); - m_lowerLimit[2] = linearLower.getZ(); - } + const btTransform & getFrameOffsetB() const + { + return m_frameInB; + } - void setLinearUpperLimit(const btVector3& linearUpper) - { - m_upperLimit[0] = linearUpper.getX(); - m_upperLimit[1] = linearUpper.getY(); - m_upperLimit[2] = linearUpper.getZ(); - } - void setAngularLowerLimit(const btVector3& angularLower) - { - m_lowerLimit[3] = angularLower.getX(); - m_lowerLimit[4] = angularLower.getY(); - m_lowerLimit[5] = angularLower.getZ(); - } + btTransform & getFrameOffsetA() + { + return m_frameInA; + } - void setAngularUpperLimit(const btVector3& angularUpper) - { - m_upperLimit[3] = angularUpper.getX(); - m_upperLimit[4] = angularUpper.getY(); - m_upperLimit[5] = angularUpper.getZ(); - } + btTransform & getFrameOffsetB() + { + return m_frameInB; + } - //first 3 are linear, next 3 are angular - void SetLimit(int axis, btScalar lo, btScalar hi) - { - m_lowerLimit[axis] = lo; - m_upperLimit[axis] = hi; - } - //free means upper < lower, - //locked means upper == lower - //limited means upper > lower - //limitIndex: first 3 are linear, next 3 are angular - bool isLimited(int limitIndex) - { - return (m_upperLimit[limitIndex] >= m_lowerLimit[limitIndex]); - } + //! performs Jacobian calculation, and also calculates angle differences and axis + virtual void buildJacobian(); + + virtual void solveConstraint(btScalar timeStep); + + void updateRHS(btScalar timeStep); + + //! Get the rotation axis in global coordinates + /*! + \pre btGeneric6DofConstraint.buildJacobian must be called previously. + */ + btVector3 getAxis(int axis_index) const; + + //! Get the relative Euler angle + /*! + \pre btGeneric6DofConstraint.buildJacobian must be called previously. + */ + btScalar getAngle(int axis_index) const; + + //! Test angular limit. + /*! + Calculates angular correction and returns true if limit needs to be corrected. + \pre btGeneric6DofConstraint.buildJacobian must be called previously. + */ + bool testAngularLimitMotor(int axis_index); + + void setLinearLowerLimit(const btVector3& linearLower) + { + m_linearLimits.m_lowerLimit = linearLower; + } + + void setLinearUpperLimit(const btVector3& linearUpper) + { + m_linearLimits.m_upperLimit = linearUpper; + } + + void setAngularLowerLimit(const btVector3& angularLower) + { + m_angularLimits[0].m_loLimit = angularLower.getX(); + m_angularLimits[1].m_loLimit = angularLower.getY(); + m_angularLimits[2].m_loLimit = angularLower.getZ(); + } + + void setAngularUpperLimit(const btVector3& angularUpper) + { + m_angularLimits[0].m_hiLimit = angularUpper.getX(); + m_angularLimits[1].m_hiLimit = angularUpper.getY(); + m_angularLimits[2].m_hiLimit = angularUpper.getZ(); + } + + //! Retrieves the angular limit informacion + btRotationalLimitMotor * getRotationalLimitMotor(int index) + { + return &m_angularLimits[index]; + } + + //! Retrieves the limit informacion + btTranslationalLimitMotor * getTranslationalLimitMotor() + { + return &m_linearLimits; + } + + //first 3 are linear, next 3 are angular + void setLimit(int axis, btScalar lo, btScalar hi) + { + if(axis<3) + { + m_linearLimits.m_lowerLimit[axis] = lo; + m_linearLimits.m_upperLimit[axis] = hi; + } + else + { + m_angularLimits[axis-3].m_loLimit = lo; + m_angularLimits[axis-3].m_hiLimit = hi; + } + } + + //! Test limit + /*! + - free means upper < lower, + - locked means upper == lower + - limited means upper > lower + - limitIndex: first 3 are linear, next 3 are angular + */ + bool isLimited(int limitIndex) + { + if(limitIndex<3) + { + return m_linearLimits.isLimited(limitIndex); + + } + return m_angularLimits[limitIndex-3].isLimited(); + } + + const btRigidBody& getRigidBodyA() const + { + return m_rbA; + } + const btRigidBody& getRigidBodyB() const + { + return m_rbB; + } - const btRigidBody& getRigidBodyA() const - { - return m_rbA; - } - const btRigidBody& getRigidBodyB() const - { - return m_rbB; - } - }; diff --git a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btHingeConstraint.cpp b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btHingeConstraint.cpp index 27e30987549..f71698fa6ee 100644 --- a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btHingeConstraint.cpp +++ b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btHingeConstraint.cpp @@ -17,58 +17,180 @@ subject to the following restrictions: #include "btHingeConstraint.h" #include "BulletDynamics/Dynamics/btRigidBody.h" #include "LinearMath/btTransformUtil.h" +#include "LinearMath/btMinMax.h" #include -btHingeConstraint::btHingeConstraint(): + +btHingeConstraint::btHingeConstraint() +: btTypedConstraint (HINGE_CONSTRAINT_TYPE), m_enableAngularMotor(false) { } btHingeConstraint::btHingeConstraint(btRigidBody& rbA,btRigidBody& rbB, const btVector3& pivotInA,const btVector3& pivotInB, - btVector3& axisInA,btVector3& axisInB) -:btTypedConstraint(rbA,rbB),m_pivotInA(pivotInA),m_pivotInB(pivotInB), -m_axisInA(axisInA), -m_axisInB(-axisInB), -m_angularOnly(false), -m_enableAngularMotor(false) + btVector3& axisInA,btVector3& axisInB) + :btTypedConstraint(HINGE_CONSTRAINT_TYPE, rbA,rbB), + m_angularOnly(false), + m_enableAngularMotor(false) { + m_rbAFrame.getOrigin() = pivotInA; + + // since no frame is given, assume this to be zero angle and just pick rb transform axis + btVector3 rbAxisA1 = rbA.getCenterOfMassTransform().getBasis().getColumn(0); + btScalar projection = rbAxisA1.dot(axisInA); + if (projection > SIMD_EPSILON) + rbAxisA1 = rbAxisA1*projection - axisInA; + else + rbAxisA1 = rbA.getCenterOfMassTransform().getBasis().getColumn(1); + + btVector3 rbAxisA2 = rbAxisA1.cross(axisInA); + + m_rbAFrame.getBasis().setValue( rbAxisA1.getX(),rbAxisA2.getX(),axisInA.getX(), + rbAxisA1.getY(),rbAxisA2.getY(),axisInA.getY(), + rbAxisA1.getZ(),rbAxisA2.getZ(),axisInA.getZ() ); + + btQuaternion rotationArc = shortestArcQuat(axisInA,axisInB); + btVector3 rbAxisB1 = quatRotate(rotationArc,rbAxisA1); + btVector3 rbAxisB2 = rbAxisB1.cross(axisInB); + + + m_rbBFrame.getOrigin() = pivotInB; + m_rbBFrame.getBasis().setValue( rbAxisB1.getX(),rbAxisB2.getX(),-axisInB.getX(), + rbAxisB1.getY(),rbAxisB2.getY(),-axisInB.getY(), + rbAxisB1.getZ(),rbAxisB2.getZ(),-axisInB.getZ() ); + + //start with free + m_lowerLimit = btScalar(1e30); + m_upperLimit = btScalar(-1e30); + m_biasFactor = 0.3f; + m_relaxationFactor = 1.0f; + m_limitSoftness = 0.9f; + m_solveLimit = false; } btHingeConstraint::btHingeConstraint(btRigidBody& rbA,const btVector3& pivotInA,btVector3& axisInA) -:btTypedConstraint(rbA),m_pivotInA(pivotInA),m_pivotInB(rbA.getCenterOfMassTransform()(pivotInA)), -m_axisInA(axisInA), -//fixed axis in worldspace -m_axisInB(rbA.getCenterOfMassTransform().getBasis() * -axisInA), +:btTypedConstraint(HINGE_CONSTRAINT_TYPE, rbA), m_angularOnly(false), m_enableAngularMotor(false) +{ + + // since no frame is given, assume this to be zero angle and just pick rb transform axis + // fixed axis in worldspace + btVector3 rbAxisA1 = rbA.getCenterOfMassTransform().getBasis().getColumn(0); + btScalar projection = rbAxisA1.dot(axisInA); + if (projection > SIMD_EPSILON) + rbAxisA1 = rbAxisA1*projection - axisInA; + else + rbAxisA1 = rbA.getCenterOfMassTransform().getBasis().getColumn(1); + + btVector3 rbAxisA2 = axisInA.cross(rbAxisA1); + + m_rbAFrame.getOrigin() = pivotInA; + m_rbAFrame.getBasis().setValue( rbAxisA1.getX(),rbAxisA2.getX(),axisInA.getX(), + rbAxisA1.getY(),rbAxisA2.getY(),axisInA.getY(), + rbAxisA1.getZ(),rbAxisA2.getZ(),axisInA.getZ() ); + + + btVector3 axisInB = rbA.getCenterOfMassTransform().getBasis() * -axisInA; + + btQuaternion rotationArc = shortestArcQuat(axisInA,axisInB); + btVector3 rbAxisB1 = quatRotate(rotationArc,rbAxisA1); + btVector3 rbAxisB2 = axisInB.cross(rbAxisB1); + + + m_rbBFrame.getOrigin() = rbA.getCenterOfMassTransform()(pivotInA); + m_rbBFrame.getBasis().setValue( rbAxisB1.getX(),rbAxisB2.getX(),axisInB.getX(), + rbAxisB1.getY(),rbAxisB2.getY(),axisInB.getY(), + rbAxisB1.getZ(),rbAxisB2.getZ(),axisInB.getZ() ); + + //start with free + m_lowerLimit = btScalar(1e30); + m_upperLimit = btScalar(-1e30); + m_biasFactor = 0.3f; + m_relaxationFactor = 1.0f; + m_limitSoftness = 0.9f; + m_solveLimit = false; +} + +btHingeConstraint::btHingeConstraint(btRigidBody& rbA,btRigidBody& rbB, + const btTransform& rbAFrame, const btTransform& rbBFrame) +:btTypedConstraint(HINGE_CONSTRAINT_TYPE, rbA,rbB),m_rbAFrame(rbAFrame),m_rbBFrame(rbBFrame), m_angularOnly(false), m_enableAngularMotor(false) { - + // flip axis + m_rbBFrame.getBasis()[0][2] *= btScalar(-1.); + m_rbBFrame.getBasis()[1][2] *= btScalar(-1.); + m_rbBFrame.getBasis()[2][2] *= btScalar(-1.); + + //start with free + m_lowerLimit = btScalar(1e30); + m_upperLimit = btScalar(-1e30); + m_biasFactor = 0.3f; + m_relaxationFactor = 1.0f; + m_limitSoftness = 0.9f; + m_solveLimit = false; +} + + + +btHingeConstraint::btHingeConstraint(btRigidBody& rbA, const btTransform& rbAFrame) +:btTypedConstraint(HINGE_CONSTRAINT_TYPE, rbA),m_rbAFrame(rbAFrame),m_rbBFrame(rbAFrame), +m_angularOnly(false), +m_enableAngularMotor(false) +{ + ///not providing rigidbody B means implicitly using worldspace for body B + + // flip axis + m_rbBFrame.getBasis()[0][2] *= btScalar(-1.); + m_rbBFrame.getBasis()[1][2] *= btScalar(-1.); + m_rbBFrame.getBasis()[2][2] *= btScalar(-1.); + + m_rbBFrame.getOrigin() = m_rbA.getCenterOfMassTransform()(m_rbAFrame.getOrigin()); + + //start with free + m_lowerLimit = btScalar(1e30); + m_upperLimit = btScalar(-1e30); + m_biasFactor = 0.3f; + m_relaxationFactor = 1.0f; + m_limitSoftness = 0.9f; + m_solveLimit = false; } void btHingeConstraint::buildJacobian() { m_appliedImpulse = btScalar(0.); - btVector3 normal(0,0,0); - if (!m_angularOnly) { + btVector3 pivotAInW = m_rbA.getCenterOfMassTransform()*m_rbAFrame.getOrigin(); + btVector3 pivotBInW = m_rbB.getCenterOfMassTransform()*m_rbBFrame.getOrigin(); + btVector3 relPos = pivotBInW - pivotAInW; + + btVector3 normal[3]; + if (relPos.length2() > SIMD_EPSILON) + { + normal[0] = relPos.normalized(); + } + else + { + normal[0].setValue(btScalar(1.0),0,0); + } + + btPlaneSpace1(normal[0], normal[1], normal[2]); + for (int i=0;i<3;i++) { - normal[i] = 1; new (&m_jac[i]) btJacobianEntry( m_rbA.getCenterOfMassTransform().getBasis().transpose(), m_rbB.getCenterOfMassTransform().getBasis().transpose(), - m_rbA.getCenterOfMassTransform()*m_pivotInA - m_rbA.getCenterOfMassPosition(), - m_rbB.getCenterOfMassTransform()*m_pivotInB - m_rbB.getCenterOfMassPosition(), - normal, + pivotAInW - m_rbA.getCenterOfMassPosition(), + pivotBInW - m_rbB.getCenterOfMassPosition(), + normal[i], m_rbA.getInvInertiaDiagLocal(), m_rbA.getInvMass(), m_rbB.getInvInertiaDiagLocal(), m_rbB.getInvMass()); - normal[i] = 0; } } @@ -79,12 +201,12 @@ void btHingeConstraint::buildJacobian() btVector3 jointAxis0local; btVector3 jointAxis1local; - btPlaneSpace1(m_axisInA,jointAxis0local,jointAxis1local); + btPlaneSpace1(m_rbAFrame.getBasis().getColumn(2),jointAxis0local,jointAxis1local); - getRigidBodyA().getCenterOfMassTransform().getBasis() * m_axisInA; + getRigidBodyA().getCenterOfMassTransform().getBasis() * m_rbAFrame.getBasis().getColumn(2); btVector3 jointAxis0 = getRigidBodyA().getCenterOfMassTransform().getBasis() * jointAxis0local; btVector3 jointAxis1 = getRigidBodyA().getCenterOfMassTransform().getBasis() * jointAxis1local; - btVector3 hingeAxisWorld = getRigidBodyA().getCenterOfMassTransform().getBasis() * m_axisInA; + btVector3 hingeAxisWorld = getRigidBodyA().getCenterOfMassTransform().getBasis() * m_rbAFrame.getBasis().getColumn(2); new (&m_jacAng[0]) btJacobianEntry(jointAxis0, m_rbA.getCenterOfMassTransform().getBasis().transpose(), @@ -105,44 +227,70 @@ void btHingeConstraint::buildJacobian() m_rbB.getInvInertiaDiagLocal()); + // Compute limit information + btScalar hingeAngle = getHingeAngle(); + + //set bias, sign, clear accumulator + m_correction = btScalar(0.); + m_limitSign = btScalar(0.); + m_solveLimit = false; + m_accLimitImpulse = btScalar(0.); + + if (m_lowerLimit < m_upperLimit) + { + if (hingeAngle <= m_lowerLimit*m_limitSoftness) + { + m_correction = (m_lowerLimit - hingeAngle); + m_limitSign = 1.0f; + m_solveLimit = true; + } + else if (hingeAngle >= m_upperLimit*m_limitSoftness) + { + m_correction = m_upperLimit - hingeAngle; + m_limitSign = -1.0f; + m_solveLimit = true; + } + } + + //Compute K = J*W*J' for hinge axis + btVector3 axisA = getRigidBodyA().getCenterOfMassTransform().getBasis() * m_rbAFrame.getBasis().getColumn(2); + m_kHinge = 1.0f / (getRigidBodyA().computeAngularImpulseDenominator(axisA) + + getRigidBodyB().computeAngularImpulseDenominator(axisA)); } void btHingeConstraint::solveConstraint(btScalar timeStep) { - btVector3 pivotAInW = m_rbA.getCenterOfMassTransform()*m_pivotInA; - btVector3 pivotBInW = m_rbB.getCenterOfMassTransform()*m_pivotInB; + btVector3 pivotAInW = m_rbA.getCenterOfMassTransform()*m_rbAFrame.getOrigin(); + btVector3 pivotBInW = m_rbB.getCenterOfMassTransform()*m_rbBFrame.getOrigin(); - btVector3 normal(0,0,0); btScalar tau = btScalar(0.3); - btScalar damping = btScalar(1.); -//linear part + //linear part if (!m_angularOnly) { + btVector3 rel_pos1 = pivotAInW - m_rbA.getCenterOfMassPosition(); + btVector3 rel_pos2 = pivotBInW - m_rbB.getCenterOfMassPosition(); + + btVector3 vel1 = m_rbA.getVelocityInLocalPoint(rel_pos1); + btVector3 vel2 = m_rbB.getVelocityInLocalPoint(rel_pos2); + btVector3 vel = vel1 - vel2; + for (int i=0;i<3;i++) { - normal[i] = 1; + const btVector3& normal = m_jac[i].m_linearJointAxis; btScalar jacDiagABInv = btScalar(1.) / m_jac[i].getDiagonal(); - btVector3 rel_pos1 = pivotAInW - m_rbA.getCenterOfMassPosition(); - btVector3 rel_pos2 = pivotBInW - m_rbB.getCenterOfMassPosition(); - - btVector3 vel1 = m_rbA.getVelocityInLocalPoint(rel_pos1); - btVector3 vel2 = m_rbB.getVelocityInLocalPoint(rel_pos2); - btVector3 vel = vel1 - vel2; btScalar rel_vel; rel_vel = normal.dot(vel); //positional error (zeroth order error) btScalar depth = -(pivotAInW - pivotBInW).dot(normal); //this is the error projected on the normal - btScalar impulse = depth*tau/timeStep * jacDiagABInv - damping * rel_vel * jacDiagABInv * damping; + btScalar impulse = depth*tau/timeStep * jacDiagABInv - rel_vel * jacDiagABInv; m_appliedImpulse += impulse; btVector3 impulse_vector = normal * impulse; m_rbA.applyImpulse(impulse_vector, pivotAInW - m_rbA.getCenterOfMassPosition()); m_rbB.applyImpulse(-impulse_vector, pivotBInW - m_rbB.getCenterOfMassPosition()); - - normal[i] = 0; } } @@ -151,8 +299,8 @@ void btHingeConstraint::solveConstraint(btScalar timeStep) ///solve angular part // get axes in world space - btVector3 axisA = getRigidBodyA().getCenterOfMassTransform().getBasis() * m_axisInA; - btVector3 axisB = getRigidBodyB().getCenterOfMassTransform().getBasis() * m_axisInB; + btVector3 axisA = getRigidBodyA().getCenterOfMassTransform().getBasis() * m_rbAFrame.getBasis().getColumn(2); + btVector3 axisB = getRigidBodyB().getCenterOfMassTransform().getBasis() * m_rbBFrame.getBasis().getColumn(2); const btVector3& angVelA = getRigidBodyA().getAngularVelocity(); const btVector3& angVelB = getRigidBodyB().getAngularVelocity(); @@ -174,7 +322,7 @@ void btHingeConstraint::solveConstraint(btScalar timeStep) getRigidBodyB().computeAngularImpulseDenominator(normal); // scale for mass and relaxation //todo: expose this 0.9 factor to developer - velrelOrthog *= (btScalar(1.)/denom) * btScalar(0.9); + velrelOrthog *= (btScalar(1.)/denom) * m_relaxationFactor; } //solve angular positional correction @@ -190,10 +338,28 @@ void btHingeConstraint::solveConstraint(btScalar timeStep) m_rbA.applyTorqueImpulse(-velrelOrthog+angularError); m_rbB.applyTorqueImpulse(velrelOrthog-angularError); + + // solve limit + if (m_solveLimit) + { + btScalar amplitude = ( (angVelB - angVelA).dot( axisA )*m_relaxationFactor + m_correction* (btScalar(1.)/timeStep)*m_biasFactor ) * m_limitSign; + + btScalar impulseMag = amplitude * m_kHinge; + + // Clamp the accumulated impulse + btScalar temp = m_accLimitImpulse; + m_accLimitImpulse = btMax(m_accLimitImpulse + impulseMag, btScalar(0) ); + impulseMag = m_accLimitImpulse - temp; + + + btVector3 impulse = axisA * impulseMag * m_limitSign; + m_rbA.applyTorqueImpulse(impulse); + m_rbB.applyTorqueImpulse(-impulse); + } } //apply motor - if (m_enableAngularMotor) + if (m_enableAngularMotor) { //todo: add limits too btVector3 angularLimit(0,0,0); @@ -204,10 +370,7 @@ void btHingeConstraint::solveConstraint(btScalar timeStep) btScalar desiredMotorVel = m_motorTargetVelocity; btScalar motor_relvel = desiredMotorVel - projRelVel; - btScalar denom3 = getRigidBodyA().computeAngularImpulseDenominator(axisA) + - getRigidBodyB().computeAngularImpulseDenominator(axisA); - - btScalar unclippedMotorImpulse = (btScalar(1.)/denom3) * motor_relvel;; + btScalar unclippedMotorImpulse = m_kHinge * motor_relvel;; //todo: should clip against accumulated impulse btScalar clippedMotorImpulse = unclippedMotorImpulse > m_maxMotorImpulse ? m_maxMotorImpulse : unclippedMotorImpulse; clippedMotorImpulse = clippedMotorImpulse < -m_maxMotorImpulse ? -m_maxMotorImpulse : clippedMotorImpulse; @@ -227,3 +390,11 @@ void btHingeConstraint::updateRHS(btScalar timeStep) } +btScalar btHingeConstraint::getHingeAngle() +{ + const btVector3 refAxis0 = getRigidBodyA().getCenterOfMassTransform().getBasis() * m_rbAFrame.getBasis().getColumn(0); + const btVector3 refAxis1 = getRigidBodyA().getCenterOfMassTransform().getBasis() * m_rbAFrame.getBasis().getColumn(1); + const btVector3 swingAxis = getRigidBodyB().getCenterOfMassTransform().getBasis() * m_rbBFrame.getBasis().getColumn(1); + + return btAtan2Fast( swingAxis.dot(refAxis0), swingAxis.dot(refAxis1) ); +} diff --git a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btHingeConstraint.h b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btHingeConstraint.h index 5c1ceafbc5b..8d8adfe9250 100644 --- a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btHingeConstraint.h +++ b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btHingeConstraint.h @@ -13,39 +13,61 @@ subject to the following restrictions: 3. This notice may not be removed or altered from any source distribution. */ +/* Hinge Constraint by Dirk Gregorius. Limits added by Marcus Hennix at Starbreeze Studios */ + #ifndef HINGECONSTRAINT_H #define HINGECONSTRAINT_H -#include "../../LinearMath/btVector3.h" +#include "LinearMath/btVector3.h" #include "btJacobianEntry.h" #include "btTypedConstraint.h" class btRigidBody; - /// hinge constraint between two rigidbodies each with a pivotpoint that descibes the axis location in local space /// axis defines the orientation of the hinge axis class btHingeConstraint : public btTypedConstraint { +#ifdef IN_PARALLELL_SOLVER +public: +#endif btJacobianEntry m_jac[3]; //3 orthogonal linear constraints btJacobianEntry m_jacAng[3]; //2 orthogonal angular constraints+ 1 for limit/motor - btVector3 m_pivotInA; - btVector3 m_pivotInB; - btVector3 m_axisInA; - btVector3 m_axisInB; + btTransform m_rbAFrame; // constraint axii. Assumes z is hinge axis. + btTransform m_rbBFrame; + + btScalar m_motorTargetVelocity; + btScalar m_maxMotorImpulse; + + btScalar m_limitSoftness; + btScalar m_biasFactor; + btScalar m_relaxationFactor; + + btScalar m_lowerLimit; + btScalar m_upperLimit; + + btScalar m_kHinge; + + btScalar m_limitSign; + btScalar m_correction; + + btScalar m_accLimitImpulse; bool m_angularOnly; - - btScalar m_motorTargetVelocity; - btScalar m_maxMotorImpulse; bool m_enableAngularMotor; + bool m_solveLimit; + public: - btHingeConstraint(btRigidBody& rbA,btRigidBody& rbB, const btVector3& pivotInA,const btVector3& pivotInB,btVector3& axisInA,btVector3& axisInB); + btHingeConstraint(btRigidBody& rbA,btRigidBody& rbB, const btVector3& pivotInA,const btVector3& pivotInB, btVector3& axisInA,btVector3& axisInB); btHingeConstraint(btRigidBody& rbA,const btVector3& pivotInA,btVector3& axisInA); + + btHingeConstraint(btRigidBody& rbA,btRigidBody& rbB, const btTransform& rbAFrame, const btTransform& rbBFrame); + + btHingeConstraint(btRigidBody& rbA,const btTransform& rbAFrame); btHingeConstraint(); @@ -76,6 +98,33 @@ public: m_maxMotorImpulse = maxMotorImpulse; } + void setLimit(btScalar low,btScalar high,btScalar _softness = 0.9f, btScalar _biasFactor = 0.3f, btScalar _relaxationFactor = 1.0f) + { + m_lowerLimit = low; + m_upperLimit = high; + + m_limitSoftness = _softness; + m_biasFactor = _biasFactor; + m_relaxationFactor = _relaxationFactor; + + } + + btScalar getHingeAngle(); + + + const btTransform& getAFrame() { return m_rbAFrame; }; + const btTransform& getBFrame() { return m_rbBFrame; }; + + inline int getSolveLimit() + { + return m_solveLimit; + } + + inline btScalar getLimitSign() + { + return m_limitSign; + } + }; #endif //HINGECONSTRAINT_H diff --git a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btJacobianEntry.h b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btJacobianEntry.h index aae3ed0373f..bfeb24c2dfb 100644 --- a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btJacobianEntry.h +++ b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btJacobianEntry.h @@ -16,8 +16,8 @@ subject to the following restrictions: #ifndef JACOBIAN_ENTRY_H #define JACOBIAN_ENTRY_H -#include "../../LinearMath/btVector3.h" -#include "../Dynamics/btRigidBody.h" +#include "LinearMath/btVector3.h" +#include "BulletDynamics/Dynamics/btRigidBody.h" //notes: diff --git a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btPoint2PointConstraint.cpp b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btPoint2PointConstraint.cpp index aacb0a3ea66..ff918ea5625 100644 --- a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btPoint2PointConstraint.cpp +++ b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btPoint2PointConstraint.cpp @@ -21,18 +21,19 @@ subject to the following restrictions: btPoint2PointConstraint::btPoint2PointConstraint() +:btTypedConstraint(POINT2POINT_CONSTRAINT_TYPE) { } btPoint2PointConstraint::btPoint2PointConstraint(btRigidBody& rbA,btRigidBody& rbB, const btVector3& pivotInA,const btVector3& pivotInB) -:btTypedConstraint(rbA,rbB),m_pivotInA(pivotInA),m_pivotInB(pivotInB) +:btTypedConstraint(POINT2POINT_CONSTRAINT_TYPE,rbA,rbB),m_pivotInA(pivotInA),m_pivotInB(pivotInB) { } btPoint2PointConstraint::btPoint2PointConstraint(btRigidBody& rbA,const btVector3& pivotInA) -:btTypedConstraint(rbA),m_pivotInA(pivotInA),m_pivotInB(rbA.getCenterOfMassTransform()(pivotInA)) +:btTypedConstraint(POINT2POINT_CONSTRAINT_TYPE,rbA),m_pivotInA(pivotInA),m_pivotInB(rbA.getCenterOfMassTransform()(pivotInA)) { } diff --git a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btPoint2PointConstraint.h b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btPoint2PointConstraint.h index 71da8ac0347..27872b9c8aa 100644 --- a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btPoint2PointConstraint.h +++ b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btPoint2PointConstraint.h @@ -16,7 +16,7 @@ subject to the following restrictions: #ifndef POINT2POINTCONSTRAINT_H #define POINT2POINTCONSTRAINT_H -#include "../../LinearMath/btVector3.h" +#include "LinearMath/btVector3.h" #include "btJacobianEntry.h" #include "btTypedConstraint.h" @@ -36,6 +36,9 @@ struct btConstraintSetting /// point to point constraint between two rigidbodies each with a pivotpoint that descibes the 'ballsocket' location in local space class btPoint2PointConstraint : public btTypedConstraint { +#ifdef IN_PARALLELL_SOLVER +public: +#endif btJacobianEntry m_jac[3]; //3 orthogonal linear constraints btVector3 m_pivotInA; @@ -70,6 +73,15 @@ public: m_pivotInB = pivotB; } + const btVector3& getPivotInA() const + { + return m_pivotInA; + } + + const btVector3& getPivotInB() const + { + return m_pivotInB; + } }; diff --git a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.cpp b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.cpp index 14b36ad44fd..7d4ed7856c3 100644 --- a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.cpp +++ b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.cpp @@ -13,6 +13,9 @@ subject to the following restrictions: 3. This notice may not be removed or altered from any source distribution. */ +//#define COMPUTE_IMPULSE_DENOM 1 +//It is not necessary (redundant) to refresh contact manifolds, this refresh has been moved to the collision algorithms. +//#define FORCE_REFESH_CONTACT_MANIFOLDS 1 #include "btSequentialImpulseConstraintSolver.h" #include "BulletCollision/NarrowPhaseCollision/btPersistentManifold.h" @@ -96,7 +99,7 @@ bool MyContactDestroyedCallback(void* userPersistentData) { assert (userPersistentData); btConstraintPersistentData* cpd = (btConstraintPersistentData*)userPersistentData; - delete cpd; + btAlignedFree(cpd); totalCpd--; //printf("totalCpd = %i. DELETED Ptr %x\n",totalCpd,userPersistentData); return true; @@ -121,6 +124,10 @@ m_btSeed2(0) } } +btSequentialImpulseConstraintSolver::~btSequentialImpulseConstraintSolver() +{ + +} void initSolverBody(btSolverBody* solverBody, btRigidBody* rigidbody) { @@ -155,64 +162,62 @@ btScalar restitutionCurve(btScalar rel_vel, btScalar restitution) //velocity + friction //response between two dynamic objects with friction -SIMD_FORCE_INLINE btScalar resolveSingleCollisionCombinedCacheFriendly( +//SIMD_FORCE_INLINE +btScalar resolveSingleCollisionCombinedCacheFriendly( btSolverBody& body1, btSolverBody& body2, - btSolverConstraint& contactConstraint, + const btSolverConstraint& contactConstraint, const btContactSolverInfo& solverInfo) { (void)solverInfo; - btScalar normalImpulse(0.f); - { - if (contactConstraint.m_penetration < 0.f) - return 0.f; - + btScalar normalImpulse; + // Optimized version of projected relative velocity, use precomputed cross products with normal // body1.getVelocityInLocalPoint(contactConstraint.m_rel_posA,vel1); // body2.getVelocityInLocalPoint(contactConstraint.m_rel_posB,vel2); // btVector3 vel = vel1 - vel2; // btScalar rel_vel = contactConstraint.m_contactNormal.dot(vel); - btScalar rel_vel; - btScalar vel1Dotn = contactConstraint.m_contactNormal.dot(body1.m_linearVelocity) - + contactConstraint.m_relpos1CrossNormal.dot(body1.m_angularVelocity); - btScalar vel2Dotn = contactConstraint.m_contactNormal.dot(body2.m_linearVelocity) - + contactConstraint.m_relpos2CrossNormal.dot(body2.m_angularVelocity); + btScalar rel_vel; + btScalar vel1Dotn = contactConstraint.m_contactNormal.dot(body1.m_linearVelocity) + + contactConstraint.m_relpos1CrossNormal.dot(body1.m_angularVelocity); + btScalar vel2Dotn = contactConstraint.m_contactNormal.dot(body2.m_linearVelocity) + + contactConstraint.m_relpos2CrossNormal.dot(body2.m_angularVelocity); - rel_vel = vel1Dotn-vel2Dotn; + rel_vel = vel1Dotn-vel2Dotn; - btScalar positionalError = contactConstraint.m_penetration; - btScalar velocityError = contactConstraint.m_restitution - rel_vel;// * damping; + btScalar positionalError = contactConstraint.m_penetration; + btScalar velocityError = contactConstraint.m_restitution - rel_vel;// * damping; - btScalar penetrationImpulse = positionalError * contactConstraint.m_jacDiagABInv; - btScalar velocityImpulse = velocityError * contactConstraint.m_jacDiagABInv; - btScalar normalImpulse = penetrationImpulse+velocityImpulse; - - // See Erin Catto's GDC 2006 paper: Clamp the accumulated impulse - btScalar oldNormalImpulse = contactConstraint.m_appliedImpulse; - btScalar sum = oldNormalImpulse + normalImpulse; - contactConstraint.m_appliedImpulse = btScalar(0.) > sum ? btScalar(0.): sum; + btScalar penetrationImpulse = positionalError * contactConstraint.m_jacDiagABInv; + btScalar velocityImpulse = velocityError * contactConstraint.m_jacDiagABInv; + normalImpulse = penetrationImpulse+velocityImpulse; + + // See Erin Catto's GDC 2006 paper: Clamp the accumulated impulse + btScalar oldNormalImpulse = contactConstraint.m_appliedImpulse; + btScalar sum = oldNormalImpulse + normalImpulse; + contactConstraint.m_appliedImpulse = btScalar(0.) > sum ? btScalar(0.): sum; - btScalar oldVelocityImpulse = contactConstraint.m_appliedVelocityImpulse; - btScalar velocitySum = oldVelocityImpulse + velocityImpulse; - contactConstraint.m_appliedVelocityImpulse = btScalar(0.) > velocitySum ? btScalar(0.): velocitySum; + btScalar oldVelocityImpulse = contactConstraint.m_appliedVelocityImpulse; + btScalar velocitySum = oldVelocityImpulse + velocityImpulse; + contactConstraint.m_appliedVelocityImpulse = btScalar(0.) > velocitySum ? btScalar(0.): velocitySum; - normalImpulse = contactConstraint.m_appliedImpulse - oldNormalImpulse; - - if (body1.m_invMass) - { - body1.internalApplyImpulse(contactConstraint.m_contactNormal*body1.m_invMass, - contactConstraint.m_angularComponentA,normalImpulse); - } - if (body2.m_invMass) - { - body2.internalApplyImpulse(contactConstraint.m_contactNormal*body2.m_invMass, - contactConstraint.m_angularComponentB,-normalImpulse); - } + normalImpulse = contactConstraint.m_appliedImpulse - oldNormalImpulse; + if (body1.m_invMass) + { + body1.internalApplyImpulse(contactConstraint.m_contactNormal*body1.m_invMass, + contactConstraint.m_angularComponentA,normalImpulse); } + if (body2.m_invMass) + { + body2.internalApplyImpulse(contactConstraint.m_contactNormal*body2.m_invMass, + contactConstraint.m_angularComponentB,-normalImpulse); + } + + @@ -222,10 +227,11 @@ SIMD_FORCE_INLINE btScalar resolveSingleCollisionCombinedCacheFriendly( #ifndef NO_FRICTION_TANGENTIALS -SIMD_FORCE_INLINE btScalar resolveSingleFrictionCacheFriendly( +//SIMD_FORCE_INLINE +btScalar resolveSingleFrictionCacheFriendly( btSolverBody& body1, btSolverBody& body2, - btSolverConstraint& contactConstraint, + const btSolverConstraint& contactConstraint, const btContactSolverInfo& solverInfo, btScalar appliedNormalImpulse) { @@ -252,11 +258,36 @@ SIMD_FORCE_INLINE btScalar resolveSingleFrictionCacheFriendly( // calculate j that moves us to zero relative velocity j1 = -rel_vel * contactConstraint.m_jacDiagABInv; +#define CLAMP_ACCUMULATED_FRICTION_IMPULSE 1 +#ifdef CLAMP_ACCUMULATED_FRICTION_IMPULSE btScalar oldTangentImpulse = contactConstraint.m_appliedImpulse; contactConstraint.m_appliedImpulse = oldTangentImpulse + j1; - GEN_set_min(contactConstraint.m_appliedImpulse, limit); - GEN_set_max(contactConstraint.m_appliedImpulse, -limit); + + if (limit < contactConstraint.m_appliedImpulse) + { + contactConstraint.m_appliedImpulse = limit; + } else + { + if (contactConstraint.m_appliedImpulse < -limit) + contactConstraint.m_appliedImpulse = -limit; + } j1 = contactConstraint.m_appliedImpulse - oldTangentImpulse; +#else + if (limit < j1) + { + j1 = limit; + } else + { + if (j1 < -limit) + j1 = -limit; + } + +#endif //CLAMP_ACCUMULATED_FRICTION_IMPULSE + + //GEN_set_min(contactConstraint.m_appliedImpulse, limit); + //GEN_set_max(contactConstraint.m_appliedImpulse, -limit); + + } @@ -333,12 +364,56 @@ btScalar resolveSingleFrictionCacheFriendly( #endif //NO_FRICTION_TANGENTIALS -btAlignedObjectArray tmpSolverBodyPool; -btAlignedObjectArray tmpSolverConstraintPool; -btAlignedObjectArray tmpSolverFrictionConstraintPool; -btScalar btSequentialImpulseConstraintSolver::solveGroupCacheFriendly(btCollisionObject** bodies,int numBodies,btPersistentManifold** manifoldPtr, int numManifolds,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& infoGlobal,btIDebugDraw* debugDrawer,btStackAlloc* stackAlloc) + + +void btSequentialImpulseConstraintSolver::addFrictionConstraint(const btVector3& normalAxis,int solverBodyIdA,int solverBodyIdB,int frictionIndex,btManifoldPoint& cp,const btVector3& rel_pos1,const btVector3& rel_pos2,btRigidBody* rb0,btRigidBody* rb1, btScalar relaxation) +{ + + btSolverConstraint& solverConstraint = m_tmpSolverFrictionConstraintPool.expand(); + solverConstraint.m_contactNormal = normalAxis; + + solverConstraint.m_solverBodyIdA = solverBodyIdA; + solverConstraint.m_solverBodyIdB = solverBodyIdB; + solverConstraint.m_constraintType = btSolverConstraint::BT_SOLVER_FRICTION_1D; + solverConstraint.m_frictionIndex = frictionIndex; + + solverConstraint.m_friction = cp.m_combinedFriction; + + solverConstraint.m_appliedImpulse = btScalar(0.); + solverConstraint.m_appliedVelocityImpulse = 0.f; + solverConstraint.m_penetration = 0.f; + { + btVector3 ftorqueAxis1 = rel_pos1.cross(solverConstraint.m_contactNormal); + solverConstraint.m_relpos1CrossNormal = ftorqueAxis1; + solverConstraint.m_angularComponentA = rb0->getInvInertiaTensorWorld()*ftorqueAxis1; + } + { + btVector3 ftorqueAxis1 = rel_pos2.cross(solverConstraint.m_contactNormal); + solverConstraint.m_relpos2CrossNormal = ftorqueAxis1; + solverConstraint.m_angularComponentB = rb1->getInvInertiaTensorWorld()*ftorqueAxis1; + } + +#ifdef COMPUTE_IMPULSE_DENOM + btScalar denom0 = rb0->computeImpulseDenominator(pos1,solverConstraint.m_contactNormal); + btScalar denom1 = rb1->computeImpulseDenominator(pos2,solverConstraint.m_contactNormal); +#else + btVector3 vec; + vec = ( solverConstraint.m_angularComponentA).cross(rel_pos1); + btScalar denom0 = rb0->getInvMass() + normalAxis.dot(vec); + vec = ( solverConstraint.m_angularComponentB).cross(rel_pos2); + btScalar denom1 = rb1->getInvMass() + normalAxis.dot(vec); + + +#endif //COMPUTE_IMPULSE_DENOM + btScalar denom = relaxation/(denom0+denom1); + solverConstraint.m_jacDiagABInv = denom; + +} + + +btScalar btSequentialImpulseConstraintSolver::solveGroupCacheFriendlySetup(btCollisionObject** bodies,int numBodies,btPersistentManifold** manifoldPtr, int numManifolds,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& infoGlobal,btIDebugDraw* debugDrawer,btStackAlloc* stackAlloc) { (void)stackAlloc; (void)debugDrawer; @@ -348,21 +423,31 @@ btScalar btSequentialImpulseConstraintSolver::solveGroupCacheFriendly(btCollisio // printf("empty\n"); return 0.f; } + btPersistentManifold* manifold = 0; + btRigidBody* rb0=0,*rb1=0; + +#ifdef FORCE_REFESH_CONTACT_MANIFOLDS BEGIN_PROFILE("refreshManifolds"); int i; + + + for (i=0;igetBody0(); - btRigidBody* rb1 = (btRigidBody*)manifold->getBody1(); - + manifold = manifoldPtr[i]; + rb1 = (btRigidBody*)manifold->getBody1(); + rb0 = (btRigidBody*)manifold->getBody0(); + manifold->refreshContactPoints(rb0->getCenterOfMassTransform(),rb1->getCenterOfMassTransform()); } - + END_PROFILE("refreshManifolds"); +#endif //FORCE_REFESH_CONTACT_MANIFOLDS + + btVector3 color(0,1,0); BEGIN_PROFILE("gatherSolverData"); @@ -384,8 +469,10 @@ btScalar btSequentialImpulseConstraintSolver::solveGroupCacheFriendly(btCollisio //todo: use stack allocator for this temp memory int minReservation = numManifolds*2; - tmpSolverBodyPool.reserve(minReservation); + //m_tmpSolverBodyPool.reserve(minReservation); + //don't convert all bodies, only the one we need so solver the constraints +/* { for (int i=0;igetIslandTag() >= 0)) { btAssert(rb->getCompanionId() < 0); - int solverBodyId = tmpSolverBodyPool.size(); - btSolverBody& solverBody = tmpSolverBodyPool.expand(); + int solverBodyId = m_tmpSolverBodyPool.size(); + btSolverBody& solverBody = m_tmpSolverBodyPool.expand(); initSolverBody(&solverBody,rb); rb->setCompanionId(solverBodyId); } } } - +*/ - tmpSolverConstraintPool.reserve(minReservation); - tmpSolverFrictionConstraintPool.reserve(minReservation); + //m_tmpSolverConstraintPool.reserve(minReservation); + //m_tmpSolverFrictionConstraintPool.reserve(minReservation); + { int i; for (i=0;igetBody0(); - btRigidBody* rb1 = (btRigidBody*)manifold->getBody1(); + manifold = manifoldPtr[i]; + rb1 = (btRigidBody*)manifold->getBody1(); + rb0 = (btRigidBody*)manifold->getBody0(); + int solverBodyIdA=-1; int solverBodyIdB=-1; @@ -424,59 +513,98 @@ btScalar btSequentialImpulseConstraintSolver::solveGroupCacheFriendly(btCollisio if (rb0->getIslandTag() >= 0) { - solverBodyIdA = rb0->getCompanionId(); + if (rb0->getCompanionId() >= 0) + { + //body has already been converted + solverBodyIdA = rb0->getCompanionId(); + } else + { + solverBodyIdA = m_tmpSolverBodyPool.size(); + btSolverBody& solverBody = m_tmpSolverBodyPool.expand(); + initSolverBody(&solverBody,rb0); + rb0->setCompanionId(solverBodyIdA); + } } else { //create a static body - solverBodyIdA = tmpSolverBodyPool.size(); - btSolverBody& solverBody = tmpSolverBodyPool.expand(); + solverBodyIdA = m_tmpSolverBodyPool.size(); + btSolverBody& solverBody = m_tmpSolverBodyPool.expand(); initSolverBody(&solverBody,rb0); } if (rb1->getIslandTag() >= 0) { - solverBodyIdB = rb1->getCompanionId(); + if (rb1->getCompanionId() >= 0) + { + solverBodyIdB = rb1->getCompanionId(); + } else + { + solverBodyIdB = m_tmpSolverBodyPool.size(); + btSolverBody& solverBody = m_tmpSolverBodyPool.expand(); + initSolverBody(&solverBody,rb1); + rb1->setCompanionId(solverBodyIdB); + } } else { //create a static body - solverBodyIdB = tmpSolverBodyPool.size(); - btSolverBody& solverBody = tmpSolverBodyPool.expand(); + solverBodyIdB = m_tmpSolverBodyPool.size(); + btSolverBody& solverBody = m_tmpSolverBodyPool.expand(); initSolverBody(&solverBody,rb1); } } + btVector3 rel_pos1; + btVector3 rel_pos2; + btScalar relaxation; + for (int j=0;jgetNumContacts();j++) { btManifoldPoint& cp = manifold->getContactPoint(j); + + if (debugDrawer) + debugDrawer->drawContactPoint(cp.m_positionWorldOnB,cp.m_normalWorldOnB,cp.getDistance(),cp.getLifeTime(),color); - int frictionIndex = tmpSolverConstraintPool.size(); - + if (cp.getDistance() <= btScalar(0.)) { const btVector3& pos1 = cp.getPositionWorldOnA(); const btVector3& pos2 = cp.getPositionWorldOnB(); - btVector3 rel_pos1 = pos1 - rb0->getCenterOfMassPosition(); - btVector3 rel_pos2 = pos2 - rb1->getCenterOfMassPosition(); + rel_pos1 = pos1 - rb0->getCenterOfMassPosition(); + rel_pos2 = pos2 - rb1->getCenterOfMassPosition(); - btScalar relaxation = 1.f; + relaxation = 1.f; + btScalar rel_vel; + btVector3 vel; + + int frictionIndex = m_tmpSolverConstraintPool.size(); { - btSolverConstraint& solverConstraint = tmpSolverConstraintPool.expand(); + btSolverConstraint& solverConstraint = m_tmpSolverConstraintPool.expand(); solverConstraint.m_solverBodyIdA = solverBodyIdA; solverConstraint.m_solverBodyIdB = solverBodyIdB; solverConstraint.m_constraintType = btSolverConstraint::BT_SOLVER_CONTACT_1D; - - + btVector3 torqueAxis0 = rel_pos1.cross(cp.m_normalWorldOnB); + solverConstraint.m_angularComponentA = rb0->getInvInertiaTensorWorld()*torqueAxis0; + btVector3 torqueAxis1 = rel_pos2.cross(cp.m_normalWorldOnB); + solverConstraint.m_angularComponentB = rb1->getInvInertiaTensorWorld()*torqueAxis1; { - //can be optimized, the cross products are already calculated +#ifdef COMPUTE_IMPULSE_DENOM btScalar denom0 = rb0->computeImpulseDenominator(pos1,cp.m_normalWorldOnB); btScalar denom1 = rb1->computeImpulseDenominator(pos2,cp.m_normalWorldOnB); +#else + btVector3 vec; + vec = ( solverConstraint.m_angularComponentA).cross(rel_pos1); + btScalar denom0 = rb0->getInvMass() + cp.m_normalWorldOnB.dot(vec); + vec = ( solverConstraint.m_angularComponentB).cross(rel_pos2); + btScalar denom1 = rb1->getInvMass() + cp.m_normalWorldOnB.dot(vec); +#endif //COMPUTE_IMPULSE_DENOM + btScalar denom = relaxation/(denom0+denom1); solverConstraint.m_jacDiagABInv = denom; } @@ -489,109 +617,57 @@ btScalar btSequentialImpulseConstraintSolver::solveGroupCacheFriendly(btCollisio btVector3 vel1 = rb0->getVelocityInLocalPoint(rel_pos1); btVector3 vel2 = rb1->getVelocityInLocalPoint(rel_pos2); - btVector3 vel = vel1 - vel2; - btScalar rel_vel; + vel = vel1 - vel2; + rel_vel = cp.m_normalWorldOnB.dot(vel); solverConstraint.m_penetration = cp.getDistance();///btScalar(infoGlobal.m_numIterations); solverConstraint.m_friction = cp.m_combinedFriction; - btScalar rest = restitutionCurve(rel_vel, cp.m_combinedRestitution); - if (rest <= btScalar(0.)) + solverConstraint.m_restitution = restitutionCurve(rel_vel, cp.m_combinedRestitution); + if (solverConstraint.m_restitution <= btScalar(0.)) { - rest = 0.f; + solverConstraint.m_restitution = 0.f; }; btScalar penVel = -solverConstraint.m_penetration/infoGlobal.m_timeStep; - if (rest > penVel) - { - rest = btScalar(0.); - } - solverConstraint.m_restitution = rest; - solverConstraint.m_penetration *= -(infoGlobal.m_erp/infoGlobal.m_timeStep); + if (solverConstraint.m_restitution > penVel) + { + solverConstraint.m_penetration = btScalar(0.); + } + + + solverConstraint.m_appliedImpulse = 0.f; solverConstraint.m_appliedVelocityImpulse = 0.f; - btVector3 torqueAxis0 = rel_pos1.cross(cp.m_normalWorldOnB); - solverConstraint.m_angularComponentA = rb0->getInvInertiaTensorWorld()*torqueAxis0; - btVector3 torqueAxis1 = rel_pos2.cross(cp.m_normalWorldOnB); - solverConstraint.m_angularComponentB = rb1->getInvInertiaTensorWorld()*torqueAxis1; - } - - //create 2 '1d axis' constraints for 2 tangential friction directions - - //re-calculate friction direction every frame, todo: check if this is really needed - btVector3 frictionTangential0a, frictionTangential1b; - - btPlaneSpace1(cp.m_normalWorldOnB,frictionTangential0a,frictionTangential1b); - - { - btSolverConstraint& solverConstraint = tmpSolverFrictionConstraintPool.expand(); - solverConstraint.m_contactNormal = frictionTangential0a; - - solverConstraint.m_solverBodyIdA = solverBodyIdA; - solverConstraint.m_solverBodyIdB = solverBodyIdB; - solverConstraint.m_constraintType = btSolverConstraint::BT_SOLVER_FRICTION_1D; - solverConstraint.m_frictionIndex = frictionIndex; - - solverConstraint.m_friction = cp.m_combinedFriction; - - solverConstraint.m_appliedImpulse = btScalar(0.); - solverConstraint.m_appliedVelocityImpulse = 0.f; - - btScalar denom0 = rb0->computeImpulseDenominator(pos1,solverConstraint.m_contactNormal); - btScalar denom1 = rb1->computeImpulseDenominator(pos2,solverConstraint.m_contactNormal); - btScalar denom = relaxation/(denom0+denom1); - solverConstraint.m_jacDiagABInv = denom; - - { - btVector3 ftorqueAxis0 = rel_pos1.cross(solverConstraint.m_contactNormal); - solverConstraint.m_relpos1CrossNormal = ftorqueAxis0; - solverConstraint.m_angularComponentA = rb0->getInvInertiaTensorWorld()*ftorqueAxis0; - } - { - btVector3 ftorqueAxis0 = rel_pos2.cross(solverConstraint.m_contactNormal); - solverConstraint.m_relpos2CrossNormal = ftorqueAxis0; - solverConstraint.m_angularComponentB = rb1->getInvInertiaTensorWorld()*ftorqueAxis0; - } - - } - - - { - - btSolverConstraint& solverConstraint = tmpSolverFrictionConstraintPool.expand(); - solverConstraint.m_contactNormal = frictionTangential1b; - - solverConstraint.m_solverBodyIdA = solverBodyIdA; - solverConstraint.m_solverBodyIdB = solverBodyIdB; - solverConstraint.m_constraintType = btSolverConstraint::BT_SOLVER_FRICTION_1D; - solverConstraint.m_frictionIndex = frictionIndex; - - solverConstraint.m_friction = cp.m_combinedFriction; - - solverConstraint.m_appliedImpulse = btScalar(0.); - solverConstraint.m_appliedVelocityImpulse = 0.f; - btScalar denom0 = rb0->computeImpulseDenominator(pos1,solverConstraint.m_contactNormal); - btScalar denom1 = rb1->computeImpulseDenominator(pos2,solverConstraint.m_contactNormal); - btScalar denom = relaxation/(denom0+denom1); - solverConstraint.m_jacDiagABInv = denom; + } + + + { + btVector3 frictionDir1 = vel - cp.m_normalWorldOnB * rel_vel; + btScalar lat_rel_vel = frictionDir1.length2(); + if (lat_rel_vel > SIMD_EPSILON)//0.0f) { - btVector3 ftorqueAxis1 = rel_pos1.cross(solverConstraint.m_contactNormal); - solverConstraint.m_relpos1CrossNormal = ftorqueAxis1; - solverConstraint.m_angularComponentA = rb0->getInvInertiaTensorWorld()*ftorqueAxis1; - } + frictionDir1 /= btSqrt(lat_rel_vel); + addFrictionConstraint(frictionDir1,solverBodyIdA,solverBodyIdB,frictionIndex,cp,rel_pos1,rel_pos2,rb0,rb1, relaxation); + btVector3 frictionDir2 = frictionDir1.cross(cp.m_normalWorldOnB); + frictionDir2.normalize();//?? + addFrictionConstraint(frictionDir2,solverBodyIdA,solverBodyIdB,frictionIndex,cp,rel_pos1,rel_pos2,rb0,rb1, relaxation); + } else { - btVector3 ftorqueAxis1 = rel_pos2.cross(solverConstraint.m_contactNormal); - solverConstraint.m_relpos2CrossNormal = ftorqueAxis1; - solverConstraint.m_angularComponentB = rb1->getInvInertiaTensorWorld()*ftorqueAxis1; - } + //re-calculate friction direction every frame, todo: check if this is really needed + btVector3 frictionDir1,frictionDir2; + btPlaneSpace1(cp.m_normalWorldOnB,frictionDir1,frictionDir2); + addFrictionConstraint(frictionDir1,solverBodyIdA,solverBodyIdB,frictionIndex,cp,rel_pos1,rel_pos2,rb0,rb1, relaxation); + addFrictionConstraint(frictionDir2,solverBodyIdA,solverBodyIdB,frictionIndex,cp,rel_pos1,rel_pos2,rb0,rb1, relaxation); } + } } } } @@ -612,24 +688,23 @@ btScalar btSequentialImpulseConstraintSolver::solveGroupCacheFriendly(btCollisio } } - btAlignedObjectArray gOrderTmpConstraintPool; - btAlignedObjectArray gOrderFrictionConstraintPool; + - int numConstraintPool = tmpSolverConstraintPool.size(); - int numFrictionPool = tmpSolverFrictionConstraintPool.size(); + int numConstraintPool = m_tmpSolverConstraintPool.size(); + int numFrictionPool = m_tmpSolverFrictionConstraintPool.size(); ///todo: use stack allocator for such temporarily memory, same for solver bodies/constraints - gOrderTmpConstraintPool.resize(numConstraintPool); - gOrderFrictionConstraintPool.resize(numFrictionPool); + m_orderTmpConstraintPool.resize(numConstraintPool); + m_orderFrictionConstraintPool.resize(numFrictionPool); { int i; for (i=0;igetRigidBodyA().getIslandTag() >= 0) && (constraint->getRigidBodyA().getCompanionId() >= 0)) { - tmpSolverBodyPool[constraint->getRigidBodyA().getCompanionId()].writebackVelocity(); + m_tmpSolverBodyPool[constraint->getRigidBodyA().getCompanionId()].writebackVelocity(); } if ((constraint->getRigidBodyB().getIslandTag() >= 0) && (constraint->getRigidBodyB().getCompanionId() >= 0)) { - tmpSolverBodyPool[constraint->getRigidBodyB().getCompanionId()].writebackVelocity(); + m_tmpSolverBodyPool[constraint->getRigidBodyB().getCompanionId()].writebackVelocity(); } - constraint->solveConstraint(info.m_timeStep); + constraint->solveConstraint(infoGlobal.m_timeStep); if ((constraint->getRigidBodyA().getIslandTag() >= 0) && (constraint->getRigidBodyA().getCompanionId() >= 0)) { - tmpSolverBodyPool[constraint->getRigidBodyA().getCompanionId()].readVelocity(); + m_tmpSolverBodyPool[constraint->getRigidBodyA().getCompanionId()].readVelocity(); } if ((constraint->getRigidBodyB().getIslandTag() >= 0) && (constraint->getRigidBodyB().getCompanionId() >= 0)) { - tmpSolverBodyPool[constraint->getRigidBodyB().getCompanionId()].readVelocity(); + m_tmpSolverBodyPool[constraint->getRigidBodyB().getCompanionId()].readVelocity(); } } { - int numPoolConstraints = tmpSolverConstraintPool.size(); + int numPoolConstraints = m_tmpSolverConstraintPool.size(); for (j=0;jgetBody0(), (btRigidBody*)manifold->getBody1(),manifold->getContactPoint(gOrder[j].m_pointIndex),info,iteration,debugDrawer); } + } } @@ -878,8 +977,9 @@ void btSequentialImpulseConstraintSolver::prepareConstraints(btPersistentManifol //only necessary to refresh the manifold once (first iteration). The integration is done outside the loop { +#ifdef FORCE_REFESH_CONTACT_MANIFOLDS manifoldPtr->refreshContactPoints(body0->getCenterOfMassTransform(),body1->getCenterOfMassTransform()); - +#endif //FORCE_REFESH_CONTACT_MANIFOLDS int numpoints = manifoldPtr->getNumContacts(); gTotalContactPoints += numpoints; @@ -925,7 +1025,9 @@ void btSequentialImpulseConstraintSolver::prepareConstraints(btPersistentManifol } else { - cpd = new btConstraintPersistentData; + //todo: should this be in a pool? + void* mem = btAlignedAlloc(sizeof(btConstraintPersistentData),16); + cpd = new (mem)btConstraintPersistentData; assert(cpd); totalCpd ++; @@ -972,7 +1074,6 @@ void btSequentialImpulseConstraintSolver::prepareConstraints(btPersistentManifol cpd->m_penetration = btScalar(0.); } - btScalar relaxation = info.m_damping; if (m_solverMode & SOLVER_USE_WARMSTARTING) @@ -1156,3 +1257,10 @@ btScalar btSequentialImpulseConstraintSolver::solveFriction(btRigidBody* body0,b } return btScalar(0.); } + + +void btSequentialImpulseConstraintSolver::reset() +{ + m_btSeed2 = 0; +} + diff --git a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.h b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.h index 13e70c41be4..83a96d4dc44 100644 --- a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.h +++ b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.h @@ -19,7 +19,8 @@ subject to the following restrictions: #include "btConstraintSolver.h" class btIDebugDraw; #include "btContactConstraint.h" - +#include "btSolverBody.h" +#include "btSolverConstraint.h" /// btSequentialImpulseConstraintSolver uses a Propagation Method and Sequentially applies impulses @@ -29,10 +30,18 @@ class btIDebugDraw; class btSequentialImpulseConstraintSolver : public btConstraintSolver { + btAlignedObjectArray m_tmpSolverBodyPool; + btAlignedObjectArray m_tmpSolverConstraintPool; + btAlignedObjectArray m_tmpSolverFrictionConstraintPool; + btAlignedObjectArray m_orderTmpConstraintPool; + btAlignedObjectArray m_orderFrictionConstraintPool; + + protected: btScalar solve(btRigidBody* body0,btRigidBody* body1, btManifoldPoint& cp, const btContactSolverInfo& info,int iter,btIDebugDraw* debugDrawer); btScalar solveFriction(btRigidBody* body0,btRigidBody* body1, btManifoldPoint& cp, const btContactSolverInfo& info,int iter,btIDebugDraw* debugDrawer); void prepareConstraints(btPersistentManifold* manifoldPtr, const btContactSolverInfo& info,btIDebugDraw* debugDrawer); + void addFrictionConstraint(const btVector3& normalAxis,int solverBodyIdA,int solverBodyIdB,int frictionIndex,btManifoldPoint& cp,const btVector3& rel_pos1,const btVector3& rel_pos2,btRigidBody* rb0,btRigidBody* rb1, btScalar relaxation); ContactSolverFunc m_contactDispatch[MAX_CONTACT_SOLVER_TYPES][MAX_CONTACT_SOLVER_TYPES]; ContactSolverFunc m_frictionDispatch[MAX_CONTACT_SOLVER_TYPES][MAX_CONTACT_SOLVER_TYPES]; @@ -68,11 +77,17 @@ public: m_frictionDispatch[type0][type1] = func; } - virtual ~btSequentialImpulseConstraintSolver() {} + virtual ~btSequentialImpulseConstraintSolver(); - virtual btScalar solveGroup(btCollisionObject** bodies,int numBodies,btPersistentManifold** manifold,int numManifolds,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& info, btIDebugDraw* debugDrawer, btStackAlloc* stackAlloc); + virtual btScalar solveGroup(btCollisionObject** bodies,int numBodies,btPersistentManifold** manifold,int numManifolds,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& info, btIDebugDraw* debugDrawer, btStackAlloc* stackAlloc,btDispatcher* dispatcher); virtual btScalar solveGroupCacheFriendly(btCollisionObject** bodies,int numBodies,btPersistentManifold** manifoldPtr, int numManifolds,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& infoGlobal,btIDebugDraw* debugDrawer,btStackAlloc* stackAlloc); + btScalar solveGroupCacheFriendlyIterations(btCollisionObject** bodies,int numBodies,btPersistentManifold** manifoldPtr, int numManifolds,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& infoGlobal,btIDebugDraw* debugDrawer,btStackAlloc* stackAlloc); + btScalar solveGroupCacheFriendlySetup(btCollisionObject** bodies,int numBodies,btPersistentManifold** manifoldPtr, int numManifolds,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& infoGlobal,btIDebugDraw* debugDrawer,btStackAlloc* stackAlloc); + + + ///clear internal cached data and reset random seed + virtual void reset(); btScalar solveCombinedContactFriction(btRigidBody* body0,btRigidBody* body1, btManifoldPoint& cp, const btContactSolverInfo& info,int iter,btIDebugDraw* debugDrawer); @@ -102,7 +117,9 @@ public: }; - +#ifndef BT_PREFER_SIMD +typedef btSequentialImpulseConstraintSolver btSequentialImpulseConstraintSolverPrefered; +#endif #endif //SEQUENTIAL_IMPULSE_CONSTRAINT_SOLVER_H diff --git a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSolve2LinearConstraint.h b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSolve2LinearConstraint.h index e7d26645c6a..057d3fac827 100644 --- a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSolve2LinearConstraint.h +++ b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSolve2LinearConstraint.h @@ -16,8 +16,8 @@ subject to the following restrictions: #ifndef SOLVE_2LINEAR_CONSTRAINT_H #define SOLVE_2LINEAR_CONSTRAINT_H -#include "../../LinearMath/btMatrix3x3.h" -#include "../../LinearMath/btVector3.h" +#include "LinearMath/btMatrix3x3.h" +#include "LinearMath/btVector3.h" class btRigidBody; diff --git a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSolverBody.h b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSolverBody.h index 0ab536f42b3..21305b3164e 100644 --- a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSolverBody.h +++ b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSolverBody.h @@ -19,30 +19,33 @@ subject to the following restrictions: class btRigidBody; #include "LinearMath/btVector3.h" #include "LinearMath/btMatrix3x3.h" +#include "BulletDynamics/Dynamics/btRigidBody.h" +#include "LinearMath/btAlignedAllocator.h" - - +///btSolverBody is an internal datastructure for the constraint solver. Only necessary data is packed to increase cache coherence/performance. ATTRIBUTE_ALIGNED16 (struct) btSolverBody { - btVector3 m_centerOfMassPosition; - btVector3 m_linearVelocity; + BT_DECLARE_ALIGNED_ALLOCATOR(); + btVector3 m_angularVelocity; - btRigidBody* m_originalBody; + float m_angularFactor; float m_invMass; float m_friction; - float m_angularFactor; - - inline void getVelocityInLocalPoint(const btVector3& rel_pos, btVector3& velocity ) const + btRigidBody* m_originalBody; + btVector3 m_linearVelocity; + btVector3 m_centerOfMassPosition; + + SIMD_FORCE_INLINE void getVelocityInLocalPoint(const btVector3& rel_pos, btVector3& velocity ) const { velocity = m_linearVelocity + m_angularVelocity.cross(rel_pos); } //Optimization for the iterative solver: avoid calculating constant terms involving inertia, normal, relative position - inline void internalApplyImpulse(const btVector3& linearComponent, const btVector3& angularComponent,btScalar impulseMagnitude) + SIMD_FORCE_INLINE void internalApplyImpulse(const btVector3& linearComponent, const btVector3& angularComponent,btScalar impulseMagnitude) { m_linearVelocity += linearComponent*impulseMagnitude; - m_angularVelocity += angularComponent*impulseMagnitude*m_angularFactor; + m_angularVelocity += angularComponent*(impulseMagnitude*m_angularFactor); } void writebackVelocity() @@ -51,6 +54,7 @@ ATTRIBUTE_ALIGNED16 (struct) btSolverBody { m_originalBody->setLinearVelocity(m_linearVelocity); m_originalBody->setAngularVelocity(m_angularVelocity); + //m_originalBody->setCompanionId(-1); } } @@ -69,3 +73,4 @@ ATTRIBUTE_ALIGNED16 (struct) btSolverBody }; #endif //BT_SOLVER_BODY_H + diff --git a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSolverConstraint.h b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSolverConstraint.h index f1f40ffdf19..a750560d33c 100644 --- a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSolverConstraint.h +++ b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSolverConstraint.h @@ -27,21 +27,27 @@ class btRigidBody; ///1D constraint along a normal axis between bodyA and bodyB. It can be combined to solve contact and friction constraints. ATTRIBUTE_ALIGNED16 (struct) btSolverConstraint { - btVector3 m_relpos1CrossNormal; - btVector3 m_relpos2CrossNormal; - btVector3 m_contactNormal; - btVector3 m_angularComponentA; - btVector3 m_angularComponentB; + BT_DECLARE_ALIGNED_ALLOCATOR(); - btScalar m_appliedVelocityImpulse; + btVector3 m_relpos1CrossNormal; + btVector3 m_contactNormal; + + btVector3 m_relpos2CrossNormal; + btVector3 m_angularComponentA; + + btVector3 m_angularComponentB; + mutable btScalar m_appliedVelocityImpulse; + mutable btScalar m_appliedImpulse; int m_solverBodyIdA; int m_solverBodyIdB; + btScalar m_friction; btScalar m_restitution; btScalar m_jacDiagABInv; btScalar m_penetration; - btScalar m_appliedImpulse; + + int m_constraintType; int m_frictionIndex; int m_unusedPadding[2]; diff --git a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btTypedConstraint.cpp b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btTypedConstraint.cpp index a15b3e026cd..6e8b552dbbc 100644 --- a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btTypedConstraint.cpp +++ b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btTypedConstraint.cpp @@ -19,18 +19,20 @@ subject to the following restrictions: static btRigidBody s_fixed(0, 0,0); -btTypedConstraint::btTypedConstraint() -: m_userConstraintType(-1), +btTypedConstraint::btTypedConstraint(btTypedConstraintType type) +:m_userConstraintType(-1), m_userConstraintId(-1), +m_constraintType (type), m_rbA(s_fixed), m_rbB(s_fixed), m_appliedImpulse(btScalar(0.)) { s_fixed.setMassProps(btScalar(0.),btVector3(btScalar(0.),btScalar(0.),btScalar(0.))); } -btTypedConstraint::btTypedConstraint(btRigidBody& rbA) -: m_userConstraintType(-1), +btTypedConstraint::btTypedConstraint(btTypedConstraintType type, btRigidBody& rbA) +:m_userConstraintType(-1), m_userConstraintId(-1), +m_constraintType (type), m_rbA(rbA), m_rbB(s_fixed), m_appliedImpulse(btScalar(0.)) @@ -40,9 +42,10 @@ m_appliedImpulse(btScalar(0.)) } -btTypedConstraint::btTypedConstraint(btRigidBody& rbA,btRigidBody& rbB) -: m_userConstraintType(-1), +btTypedConstraint::btTypedConstraint(btTypedConstraintType type, btRigidBody& rbA,btRigidBody& rbB) +:m_userConstraintType(-1), m_userConstraintId(-1), +m_constraintType (type), m_rbA(rbA), m_rbB(rbB), m_appliedImpulse(btScalar(0.)) diff --git a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btTypedConstraint.h b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btTypedConstraint.h index dfee6e80d0e..745d0afde6d 100644 --- a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btTypedConstraint.h +++ b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btTypedConstraint.h @@ -17,7 +17,16 @@ subject to the following restrictions: #define TYPED_CONSTRAINT_H class btRigidBody; -#include "../../LinearMath/btScalar.h" +#include "LinearMath/btScalar.h" + +enum btTypedConstraintType +{ + POINT2POINT_CONSTRAINT_TYPE, + HINGE_CONSTRAINT_TYPE, + CONETWIST_CONSTRAINT_TYPE, + D6_CONSTRAINT_TYPE, + VEHICLE_CONSTRAINT_TYPE +}; ///TypedConstraint is the baseclass for Bullet constraints and vehicles class btTypedConstraint @@ -25,6 +34,8 @@ class btTypedConstraint int m_userConstraintType; int m_userConstraintId; + btTypedConstraintType m_constraintType; + btTypedConstraint& operator=(btTypedConstraint& other) { btAssert(0); @@ -40,11 +51,11 @@ protected: public: - btTypedConstraint(); + btTypedConstraint(btTypedConstraintType type); virtual ~btTypedConstraint() {}; - btTypedConstraint(btRigidBody& rbA); + btTypedConstraint(btTypedConstraintType type, btRigidBody& rbA); - btTypedConstraint(btRigidBody& rbA,btRigidBody& rbB); + btTypedConstraint(btTypedConstraintType type, btRigidBody& rbA,btRigidBody& rbB); virtual void buildJacobian() = 0; @@ -59,7 +70,7 @@ public: return m_rbB; } - btRigidBody& getRigidBodyA() + btRigidBody& getRigidBodyA() { return m_rbA; } @@ -83,14 +94,19 @@ public: m_userConstraintId = uid; } - int getUserConstraintId() + int getUserConstraintId() const { return m_userConstraintId; } - btScalar getAppliedImpulse() + btScalar getAppliedImpulse() const { return m_appliedImpulse; } + + btTypedConstraintType getConstraintType () const + { + return m_constraintType; + } }; #endif //TYPED_CONSTRAINT_H diff --git a/extern/bullet2/src/BulletDynamics/Dynamics/Bullet-C-API.cpp b/extern/bullet2/src/BulletDynamics/Dynamics/Bullet-C-API.cpp new file mode 100644 index 00000000000..3f1c8e1a13b --- /dev/null +++ b/extern/bullet2/src/BulletDynamics/Dynamics/Bullet-C-API.cpp @@ -0,0 +1,402 @@ +/* +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. +*/ + +/* + Draft high-level generic physics C-API. For low-level access, use the physics SDK native API's. + Work in progress, functionality will be added on demand. + + If possible, use the richer Bullet C++ API, by including +*/ + +#include "Bullet-C-Api.h" +#include "btBulletDynamicsCommon.h" +#include "LinearMath/btAlignedAllocator.h" + + +#include "LinearMath/btVector3.h" +#include "LinearMath/btScalar.h" +#include "LinearMath/btMatrix3x3.h" +#include "LinearMath/btTransform.h" +#include "BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.h" +#include "BulletCollision/CollisionShapes/btTriangleShape.h" + +#include "BulletCollision/NarrowPhaseCollision/btGjkPairDetector.h" +#include "BulletCollision/NarrowPhaseCollision/btPointCollector.h" +#include "BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.h" +#include "BulletCollision/NarrowPhaseCollision/btSubSimplexConvexCast.h" +#include "BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.h" +#include "BulletCollision/NarrowPhaseCollision/btGjkEpa.h" +#include "BulletCollision/CollisionShapes/btMinkowskiSumShape.h" +#include "BulletCollision/NarrowPhaseCollision/btSubSimplexConvexCast.h" +#include "BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.h" +#include "BulletCollision/NarrowPhaseCollision/btGjkPairDetector.h" + +#include "BulletCollision/NarrowPhaseCollision/btDiscreteCollisionDetectorInterface.h" +#include "BulletCollision/NarrowPhaseCollision/btSimplexSolverInterface.h" +#include "BulletCollision/NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.h" +#include "BulletCollision/NarrowPhaseCollision/btGjkPairDetector.h" +#include "BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.h" +#include "LinearMath/btStackAlloc.h" + + +/* + Create and Delete a Physics SDK +*/ + +struct btPhysicsSdk +{ + +// btDispatcher* m_dispatcher; +// btOverlappingPairCache* m_pairCache; +// btConstraintSolver* m_constraintSolver + + btVector3 m_worldAabbMin; + btVector3 m_worldAabbMax; + + + //todo: version, hardware/optimization settings etc? + btPhysicsSdk() + :m_worldAabbMin(-1000,-1000,-1000), + m_worldAabbMax(1000,1000,1000) + { + + } + + +}; + +plPhysicsSdkHandle plNewBulletSdk() +{ + void* mem = btAlignedAlloc(sizeof(btPhysicsSdk),16); + return (plPhysicsSdkHandle)new (mem)btPhysicsSdk; +} + +void plDeletePhysicsSdk(plPhysicsSdkHandle physicsSdk) +{ + btPhysicsSdk* phys = reinterpret_cast(physicsSdk); + btAlignedFree(phys); +} + + +/* Dynamics World */ +plDynamicsWorldHandle plCreateDynamicsWorld(plPhysicsSdkHandle physicsSdkHandle) +{ + btPhysicsSdk* physicsSdk = reinterpret_cast(physicsSdkHandle); + void* mem = btAlignedAlloc(sizeof(btDefaultCollisionConfiguration),16); + btDefaultCollisionConfiguration* collisionConfiguration = new (mem)btDefaultCollisionConfiguration(); + mem = btAlignedAlloc(sizeof(btCollisionDispatcher),16); + btDispatcher* dispatcher = new (mem)btCollisionDispatcher(collisionConfiguration); + mem = btAlignedAlloc(sizeof(btAxisSweep3),16); + btBroadphaseInterface* pairCache = new (mem)btAxisSweep3(physicsSdk->m_worldAabbMin,physicsSdk->m_worldAabbMax); + mem = btAlignedAlloc(sizeof(btSequentialImpulseConstraintSolver),16); + btConstraintSolver* constraintSolver = new(mem) btSequentialImpulseConstraintSolver(); + + mem = btAlignedAlloc(sizeof(btDiscreteDynamicsWorld),16); + return (plDynamicsWorldHandle) new (mem)btDiscreteDynamicsWorld(dispatcher,pairCache,constraintSolver,collisionConfiguration); +} +void plDeleteDynamicsWorld(plDynamicsWorldHandle world) +{ + //todo: also clean up the other allocations, axisSweep, pairCache,dispatcher,constraintSolver,collisionConfiguration + btDynamicsWorld* dynamicsWorld = reinterpret_cast< btDynamicsWorld* >(world); + btAlignedFree(dynamicsWorld); +} + +void plStepSimulation(plDynamicsWorldHandle world, plReal timeStep) +{ + btDynamicsWorld* dynamicsWorld = reinterpret_cast< btDynamicsWorld* >(world); + assert(dynamicsWorld); + dynamicsWorld->stepSimulation(timeStep); +} + +void plAddRigidBody(plDynamicsWorldHandle world, plRigidBodyHandle object) +{ + btDynamicsWorld* dynamicsWorld = reinterpret_cast< btDynamicsWorld* >(world); + assert(dynamicsWorld); + btRigidBody* body = reinterpret_cast< btRigidBody* >(object); + assert(body); + + dynamicsWorld->addRigidBody(body); +} + +void plRemoveRigidBody(plDynamicsWorldHandle world, plRigidBodyHandle object) +{ + btDynamicsWorld* dynamicsWorld = reinterpret_cast< btDynamicsWorld* >(world); + assert(dynamicsWorld); + btRigidBody* body = reinterpret_cast< btRigidBody* >(object); + assert(body); + + dynamicsWorld->removeRigidBody(body); +} + +/* Rigid Body */ + +plRigidBodyHandle plCreateRigidBody( void* user_data, float mass, plCollisionShapeHandle cshape ) +{ + btTransform trans; + trans.setIdentity(); + btVector3 localInertia(0,0,0); + btCollisionShape* shape = reinterpret_cast( cshape); + assert(shape); + if (mass) + { + shape->calculateLocalInertia(mass,localInertia); + } + void* mem = btAlignedAlloc(sizeof(btRigidBody),16); + btRigidBody* body = new (mem)btRigidBody(mass, 0,shape,localInertia); + body->setWorldTransform(trans); + body->setUserPointer(user_data); + return (plRigidBodyHandle) body; +} + +void plDeleteRigidBody(plRigidBodyHandle cbody) +{ + btRigidBody* body = reinterpret_cast< btRigidBody* >(cbody); + assert(body); + btAlignedFree( body); +} + + +/* Collision Shape definition */ + +plCollisionShapeHandle plNewSphereShape(plReal radius) +{ + void* mem = btAlignedAlloc(sizeof(btSphereShape),16); + return (plCollisionShapeHandle) new (mem)btSphereShape(radius); + +} + +plCollisionShapeHandle plNewBoxShape(plReal x, plReal y, plReal z) +{ + void* mem = btAlignedAlloc(sizeof(btBoxShape),16); + return (plCollisionShapeHandle) new (mem)btBoxShape(btVector3(x,y,z)); +} + +plCollisionShapeHandle plNewCapsuleShape(plReal radius, plReal height) +{ + //capsule is convex hull of 2 spheres, so use btMultiSphereShape + btVector3 inertiaHalfExtents(radius,height,radius); + const int numSpheres = 2; + btVector3 positions[numSpheres] = {btVector3(0,height,0),btVector3(0,-height,0)}; + btScalar radi[numSpheres] = {radius,radius}; + void* mem = btAlignedAlloc(sizeof(btMultiSphereShape),16); + return (plCollisionShapeHandle) new (mem)btMultiSphereShape(inertiaHalfExtents,positions,radi,numSpheres); +} +plCollisionShapeHandle plNewConeShape(plReal radius, plReal height) +{ + void* mem = btAlignedAlloc(sizeof(btConeShape),16); + return (plCollisionShapeHandle) new (mem)btConeShape(radius,height); +} + +plCollisionShapeHandle plNewCylinderShape(plReal radius, plReal height) +{ + void* mem = btAlignedAlloc(sizeof(btCylinderShape),16); + return (plCollisionShapeHandle) new (mem)btCylinderShape(btVector3(radius,height,radius)); +} + +/* Convex Meshes */ +plCollisionShapeHandle plNewConvexHullShape() +{ + void* mem = btAlignedAlloc(sizeof(btConvexHullShape),16); + return (plCollisionShapeHandle) new (mem)btConvexHullShape(); +} + + +/* Concave static triangle meshes */ +plMeshInterfaceHandle plNewMeshInterface() +{ + return 0; +} + +plCollisionShapeHandle plNewCompoundShape() +{ + void* mem = btAlignedAlloc(sizeof(btCompoundShape),16); + return (plCollisionShapeHandle) new (mem)btCompoundShape(); +} + +void plAddChildShape(plCollisionShapeHandle compoundShapeHandle,plCollisionShapeHandle childShapeHandle, plVector3 childPos,plQuaternion childOrn) +{ + btCollisionShape* colShape = reinterpret_cast(compoundShapeHandle); + btAssert(colShape->getShapeType() == COMPOUND_SHAPE_PROXYTYPE); + btCompoundShape* compoundShape = reinterpret_cast(colShape); + btCollisionShape* childShape = reinterpret_cast(childShapeHandle); + btTransform localTrans; + localTrans.setIdentity(); + localTrans.setOrigin(btVector3(childPos[0],childPos[1],childPos[2])); + localTrans.setRotation(btQuaternion(childOrn[0],childOrn[1],childOrn[2],childOrn[3])); + compoundShape->addChildShape(localTrans,childShape); +} + +void plSetEuler(plReal yaw,plReal pitch,plReal roll, plQuaternion orient) +{ + btQuaternion orn; + orn.setEuler(yaw,pitch,roll); + orient[0] = orn.getX(); + orient[1] = orn.getY(); + orient[2] = orn.getZ(); + orient[3] = orn.getW(); + +} + + +// extern void plAddTriangle(plMeshInterfaceHandle meshHandle, plVector3 v0,plVector3 v1,plVector3 v2); +// extern plCollisionShapeHandle plNewStaticTriangleMeshShape(plMeshInterfaceHandle); + + +void plAddVertex(plCollisionShapeHandle cshape, plReal x,plReal y,plReal z) +{ + btCollisionShape* colShape = reinterpret_cast( cshape); + btAssert(colShape->getShapeType()==CONVEX_HULL_SHAPE_PROXYTYPE); + btConvexHullShape* convexHullShape = reinterpret_cast( cshape); + convexHullShape->addPoint(btPoint3(x,y,z)); + +} + +void plDeleteShape(plCollisionShapeHandle cshape) +{ + btCollisionShape* shape = reinterpret_cast( cshape); + assert(shape); + btAlignedFree(shape); +} +void plSetScaling(plCollisionShapeHandle cshape, plVector3 cscaling) +{ + btCollisionShape* shape = reinterpret_cast( cshape); + assert(shape); + btVector3 scaling(cscaling[0],cscaling[1],cscaling[2]); + shape->setLocalScaling(scaling); +} + + + +void plSetPosition(plRigidBodyHandle object, const plVector3 position) +{ + btRigidBody* body = reinterpret_cast< btRigidBody* >(object); + btAssert(body); + btVector3 pos(position[0],position[1],position[2]); + btTransform worldTrans = body->getWorldTransform(); + worldTrans.setOrigin(pos); + body->setWorldTransform(worldTrans); +} + +void plSetOrientation(plRigidBodyHandle object, const plQuaternion orientation) +{ + btRigidBody* body = reinterpret_cast< btRigidBody* >(object); + btAssert(body); + btQuaternion orn(orientation[0],orientation[1],orientation[2],orientation[3]); + btTransform worldTrans = body->getWorldTransform(); + worldTrans.setRotation(orn); + body->setWorldTransform(worldTrans); +} + +void plGetOpenGLMatrix(plRigidBodyHandle object, plReal* matrix) +{ + btRigidBody* body = reinterpret_cast< btRigidBody* >(object); + btAssert(body); + body->getWorldTransform().getOpenGLMatrix(matrix); + +} + +void plGetPosition(plRigidBodyHandle object,plVector3 position) +{ + btRigidBody* body = reinterpret_cast< btRigidBody* >(object); + btAssert(body); + const btVector3& pos = body->getWorldTransform().getOrigin(); + position[0] = pos.getX(); + position[1] = pos.getY(); + position[2] = pos.getZ(); +} + +void plGetOrientation(plRigidBodyHandle object,plQuaternion orientation) +{ + btRigidBody* body = reinterpret_cast< btRigidBody* >(object); + btAssert(body); + const btQuaternion& orn = body->getWorldTransform().getRotation(); + orientation[0] = orn.getX(); + orientation[1] = orn.getY(); + orientation[2] = orn.getZ(); + orientation[3] = orn.getW(); +} + + + +//plRigidBodyHandle plRayCast(plDynamicsWorldHandle world, const plVector3 rayStart, const plVector3 rayEnd, plVector3 hitpoint, plVector3 normal); + +// extern plRigidBodyHandle plObjectCast(plDynamicsWorldHandle world, const plVector3 rayStart, const plVector3 rayEnd, plVector3 hitpoint, plVector3 normal); + + + + +extern "C" +double plNearestPoints(float p1[3], float p2[3], float p3[3], float q1[3], float q2[3], float q3[3], float *pa, float *pb, float normal[3]) +{ + btTriangleShape trishapeA(btVector3(p1[0], p1[1], p1[2]), btVector3(p2[0], p2[1], p2[2]), btVector3(p3[0], p3[1], p3[2])); + trishapeA.setMargin(0.000001f); + + btTriangleShape trishapeB(btVector3(q1[0], q1[1], q1[2]), btVector3(q2[0], q2[1], q2[2]), btVector3(q3[0], q3[1], q3[2])); + trishapeB.setMargin(0.000001f); + + // btVoronoiSimplexSolver sGjkSimplexSolver; + // btGjkEpaPenetrationDepthSolver penSolverPtr; + + static btSimplexSolverInterface sGjkSimplexSolver; + sGjkSimplexSolver.reset(); + + static btGjkEpaPenetrationDepthSolver Solver0; + static btMinkowskiPenetrationDepthSolver Solver1; + + btConvexPenetrationDepthSolver* Solver = NULL; + + Solver = &Solver1; + + btGjkPairDetector convexConvex(&trishapeA ,&trishapeB,&sGjkSimplexSolver,Solver); + + convexConvex.m_catchDegeneracies = 1; + + // btGjkPairDetector convexConvex(&trishapeA ,&trishapeB,&sGjkSimplexSolver,0); + + btPointCollector gjkOutput; + btGjkPairDetector::ClosestPointInput input; + + btStackAlloc gStackAlloc(1024*1024*2); + + input.m_stackAlloc = &gStackAlloc; + + btTransform tr; + tr.setIdentity(); + + input.m_transformA = tr; + input.m_transformB = tr; + + convexConvex.getClosestPoints(input, gjkOutput, 0); + + + if (gjkOutput.m_hasResult) + { + + pb[0] = pa[0] = gjkOutput.m_pointInWorld[0]; + pb[1] = pa[1] = gjkOutput.m_pointInWorld[1]; + pb[2] = pa[2] = gjkOutput.m_pointInWorld[2]; + + pb[0]+= gjkOutput.m_normalOnBInWorld[0] * gjkOutput.m_distance; + pb[1]+= gjkOutput.m_normalOnBInWorld[1] * gjkOutput.m_distance; + pb[2]+= gjkOutput.m_normalOnBInWorld[2] * gjkOutput.m_distance; + + normal[0] = gjkOutput.m_normalOnBInWorld[0]; + normal[1] = gjkOutput.m_normalOnBInWorld[1]; + normal[2] = gjkOutput.m_normalOnBInWorld[2]; + + return gjkOutput.m_distance; + } + return -1.0f; +} diff --git a/extern/bullet2/src/BulletDynamics/Dynamics/btContinuousDynamicsWorld.cpp b/extern/bullet2/src/BulletDynamics/Dynamics/btContinuousDynamicsWorld.cpp new file mode 100644 index 00000000000..5e330cb64f2 --- /dev/null +++ b/extern/bullet2/src/BulletDynamics/Dynamics/btContinuousDynamicsWorld.cpp @@ -0,0 +1,194 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2007 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 "btContinuousDynamicsWorld.h" +#include "LinearMath/btQuickprof.h" + +//collision detection +#include "BulletCollision/CollisionDispatch/btCollisionDispatcher.h" +#include "BulletCollision/BroadphaseCollision/btSimpleBroadphase.h" +#include "BulletCollision/CollisionShapes/btCollisionShape.h" +#include "BulletCollision/CollisionDispatch/btSimulationIslandManager.h" + +//rigidbody & constraints +#include "BulletDynamics/Dynamics/btRigidBody.h" +#include "BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.h" +#include "BulletDynamics/ConstraintSolver/btContactSolverInfo.h" +#include "BulletDynamics/ConstraintSolver/btTypedConstraint.h" + + + +#include + +btContinuousDynamicsWorld::btContinuousDynamicsWorld(btDispatcher* dispatcher,btBroadphaseInterface* pairCache,btConstraintSolver* constraintSolver,btCollisionConfiguration* collisionConfiguration) +:btDiscreteDynamicsWorld(dispatcher,pairCache,constraintSolver,collisionConfiguration) +{ +} + +btContinuousDynamicsWorld::~btContinuousDynamicsWorld() +{ +} + + +void btContinuousDynamicsWorld::internalSingleStepSimulation( btScalar timeStep) +{ + + startProfiling(timeStep); + + ///update aabbs information + updateAabbs(); + //static int frame=0; +// printf("frame %d\n",frame++); + + ///apply gravity, predict motion + predictUnconstraintMotion(timeStep); + + btDispatcherInfo& dispatchInfo = getDispatchInfo(); + + dispatchInfo.m_timeStep = timeStep; + dispatchInfo.m_stepCount = 0; + dispatchInfo.m_debugDraw = getDebugDrawer(); + + ///perform collision detection + performDiscreteCollisionDetection(); + + calculateSimulationIslands(); + + + getSolverInfo().m_timeStep = timeStep; + + + + ///solve contact and other joint constraints + solveConstraints(getSolverInfo()); + + ///CallbackTriggers(); + + calculateTimeOfImpacts(timeStep); + + btScalar toi = dispatchInfo.m_timeOfImpact; +// if (toi < 1.f) +// printf("toi = %f\n",toi); + if (toi < 0.f) + printf("toi = %f\n",toi); + + + ///integrate transforms + integrateTransforms(timeStep * toi); + + ///update vehicle simulation + updateVehicles(timeStep); + + + updateActivationState( timeStep ); + +} + +void btContinuousDynamicsWorld::calculateTimeOfImpacts(btScalar timeStep) +{ + ///these should be 'temporal' aabbs! + updateTemporalAabbs(timeStep); + + ///'toi' is the global smallest time of impact. However, we just calculate the time of impact for each object individually. + ///so we handle the case moving versus static properly, and we cheat for moving versus moving + float toi = 1.f; + + + btDispatcherInfo& dispatchInfo = getDispatchInfo(); + dispatchInfo.m_timeStep = timeStep; + dispatchInfo.m_timeOfImpact = 1.f; + dispatchInfo.m_stepCount = 0; + dispatchInfo.m_dispatchFunc = btDispatcherInfo::DISPATCH_CONTINUOUS; + + ///calculate time of impact for overlapping pairs + + BEGIN_PROFILE("performContinuousCollisionDetection"); + + btDispatcher* dispatcher = getDispatcher(); + if (dispatcher) + dispatcher->dispatchAllCollisionPairs(m_broadphasePairCache->getOverlappingPairCache(),dispatchInfo,m_dispatcher1); + + END_PROFILE("performContinuousCollisionDetection"); + + toi = dispatchInfo.m_timeOfImpact; + + dispatchInfo.m_dispatchFunc = btDispatcherInfo::DISPATCH_DISCRETE; + +} + +void btContinuousDynamicsWorld::updateTemporalAabbs(btScalar timeStep) +{ + BEGIN_PROFILE("perform Temporal Broadphase Collision Detection"); + + btVector3 temporalAabbMin,temporalAabbMax; + + for ( int i=0;igetCollisionShape()->getAabb(m_collisionObjects[i]->getWorldTransform(),temporalAabbMin,temporalAabbMax); + const btVector3& linvel = body->getLinearVelocity(); + + //make the AABB temporal + float temporalAabbMaxx = temporalAabbMax.getX(); + float temporalAabbMaxy = temporalAabbMax.getY(); + float temporalAabbMaxz = temporalAabbMax.getZ(); + float temporalAabbMinx = temporalAabbMin.getX(); + float temporalAabbMiny = temporalAabbMin.getY(); + float temporalAabbMinz = temporalAabbMin.getZ(); + + // add linear motion + btVector3 linMotion = linvel*timeStep; + + if (linMotion.x() > 0.f) + temporalAabbMaxx += linMotion.x(); + else + temporalAabbMinx += linMotion.x(); + if (linMotion.y() > 0.f) + temporalAabbMaxy += linMotion.y(); + else + temporalAabbMiny += linMotion.y(); + if (linMotion.z() > 0.f) + temporalAabbMaxz += linMotion.z(); + else + temporalAabbMinz += linMotion.z(); + + //add conservative angular motion + btScalar angularMotion(0);// = angvel.length() * GetAngularMotionDisc() * timeStep; + btVector3 angularMotion3d(angularMotion,angularMotion,angularMotion); + temporalAabbMin = btVector3(temporalAabbMinx,temporalAabbMiny,temporalAabbMinz); + temporalAabbMax = btVector3(temporalAabbMaxx,temporalAabbMaxy,temporalAabbMaxz); + + temporalAabbMin -= angularMotion3d; + temporalAabbMax += angularMotion3d; + + m_broadphasePairCache->setAabb(body->getBroadphaseHandle(),temporalAabbMin,temporalAabbMax,m_dispatcher1); + } + } + + //update aabb (of all moved objects) + + m_broadphasePairCache->calculateOverlappingPairs(m_dispatcher1); + + END_PROFILE("perform Temporal Broadphase Collision Detection"); + + +} + + diff --git a/extern/bullet2/src/BulletDynamics/Dynamics/btContinuousDynamicsWorld.h b/extern/bullet2/src/BulletDynamics/Dynamics/btContinuousDynamicsWorld.h new file mode 100644 index 00000000000..61c8dea03eb --- /dev/null +++ b/extern/bullet2/src/BulletDynamics/Dynamics/btContinuousDynamicsWorld.h @@ -0,0 +1,46 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2007 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 BT_CONTINUOUS_DYNAMICS_WORLD_H +#define BT_CONTINUOUS_DYNAMICS_WORLD_H + +#include "btDiscreteDynamicsWorld.h" + +///btContinuousDynamicsWorld adds optional (per object) continuous collision detection for fast moving objects to the btDiscreteDynamicsWorld. +///This copes with fast moving objects that otherwise would tunnel/miss collisions. +///Under construction, don't use yet! Please use btDiscreteDynamicsWorld instead. +class btContinuousDynamicsWorld : public btDiscreteDynamicsWorld +{ + + void updateTemporalAabbs(btScalar timeStep); + + public: + + btContinuousDynamicsWorld(btDispatcher* dispatcher,btBroadphaseInterface* pairCache,btConstraintSolver* constraintSolver,btCollisionConfiguration* collisionConfiguration); + virtual ~btContinuousDynamicsWorld(); + + ///time stepping with calculation of time of impact for selected fast moving objects + virtual void internalSingleStepSimulation( btScalar timeStep); + + virtual void calculateTimeOfImpacts(btScalar timeStep); + + virtual btDynamicsWorldType getWorldType() const + { + return BT_CONTINUOUS_DYNAMICS_WORLD; + } + +}; + +#endif //BT_CONTINUOUS_DYNAMICS_WORLD_H diff --git a/extern/bullet2/src/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.cpp b/extern/bullet2/src/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.cpp index 29719ec9a3e..88b11c878c5 100644 --- a/extern/bullet2/src/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.cpp +++ b/extern/bullet2/src/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.cpp @@ -57,17 +57,30 @@ subject to the following restrictions: -btDiscreteDynamicsWorld::btDiscreteDynamicsWorld(btDispatcher* dispatcher,btOverlappingPairCache* pairCache,btConstraintSolver* constraintSolver) -:btDynamicsWorld(dispatcher,pairCache), -m_constraintSolver(constraintSolver? constraintSolver: new btSequentialImpulseConstraintSolver), +btDiscreteDynamicsWorld::btDiscreteDynamicsWorld(btDispatcher* dispatcher,btBroadphaseInterface* pairCache,btConstraintSolver* constraintSolver, btCollisionConfiguration* collisionConfiguration) +:btDynamicsWorld(dispatcher,pairCache,collisionConfiguration), +m_constraintSolver(constraintSolver), m_debugDrawer(0), m_gravity(0,-10,0), m_localTime(btScalar(1.)/btScalar(60.)), m_profileTimings(0) { - m_islandManager = new btSimulationIslandManager(); + if (!m_constraintSolver) + { + void* mem = btAlignedAlloc(sizeof(btSequentialImpulseConstraintSolver),16); + m_constraintSolver = new (mem) btSequentialImpulseConstraintSolver; + m_ownsConstraintSolver = true; + } else + { + m_ownsConstraintSolver = false; + } + + { + void* mem = btAlignedAlloc(sizeof(btSimulationIslandManager),16); + m_islandManager = new (mem) btSimulationIslandManager(); + } + m_ownsIslandManager = true; - m_ownsConstraintSolver = (constraintSolver==0); } @@ -75,9 +88,16 @@ btDiscreteDynamicsWorld::~btDiscreteDynamicsWorld() { //only delete it when we created it if (m_ownsIslandManager) - delete m_islandManager; + { + m_islandManager->~btSimulationIslandManager(); + btAlignedFree( m_islandManager); + } if (m_ownsConstraintSolver) - delete m_constraintSolver; + { + + m_constraintSolver->~btConstraintSolver(); + btAlignedFree(m_constraintSolver); + } } void btDiscreteDynamicsWorld::saveKinematicState(btScalar timeStep) @@ -412,7 +432,7 @@ void btDiscreteDynamicsWorld::removeVehicle(btRaycastVehicle* vehicle) m_vehicles.remove(vehicle); } -inline int btGetConstraintIslandId(const btTypedConstraint* lhs) +SIMD_FORCE_INLINE int btGetConstraintIslandId(const btTypedConstraint* lhs) { int islandId; @@ -452,7 +472,7 @@ void btDiscreteDynamicsWorld::solveConstraints(btContactSolverInfo& solverInfo) int m_numConstraints; btIDebugDraw* m_debugDrawer; btStackAlloc* m_stackAlloc; - + btDispatcher* m_dispatcher; InplaceSolverIslandCallback( btContactSolverInfo& solverInfo, @@ -460,13 +480,15 @@ void btDiscreteDynamicsWorld::solveConstraints(btContactSolverInfo& solverInfo) btTypedConstraint** sortedConstraints, int numConstraints, btIDebugDraw* debugDrawer, - btStackAlloc* stackAlloc) + btStackAlloc* stackAlloc, + btDispatcher* dispatcher) :m_solverInfo(solverInfo), m_solver(solver), m_sortedConstraints(sortedConstraints), m_numConstraints(numConstraints), m_debugDrawer(debugDrawer), - m_stackAlloc(stackAlloc) + m_stackAlloc(stackAlloc), + m_dispatcher(dispatcher) { } @@ -479,30 +501,38 @@ void btDiscreteDynamicsWorld::solveConstraints(btContactSolverInfo& solverInfo) } virtual void ProcessIsland(btCollisionObject** bodies,int numBodies,btPersistentManifold** manifolds,int numManifolds, int islandId) { - //also add all non-contact constraints/joints for this island - btTypedConstraint** startConstraint = 0; - int numCurConstraints = 0; - int i; - - //find the first constraint for this island - for (i=0;isolveGroup( bodies,numBodies,manifolds, numManifolds,&m_sortedConstraints[0],m_numConstraints,m_solverInfo,m_debugDrawer,m_stackAlloc,m_dispatcher); + } else { - if (btGetConstraintIslandId(m_sortedConstraints[i]) == islandId) + //also add all non-contact constraints/joints for this island + btTypedConstraint** startConstraint = 0; + int numCurConstraints = 0; + int i; + + //find the first constraint for this island + for (i=0;isolveGroup( bodies,numBodies,manifolds, numManifolds,startConstraint,numCurConstraints,m_solverInfo,m_debugDrawer,m_stackAlloc); + m_solver->solveGroup( bodies,numBodies,manifolds, numManifolds,startConstraint,numCurConstraints,m_solverInfo,m_debugDrawer,m_stackAlloc,m_dispatcher); + + } } }; @@ -524,14 +554,14 @@ void btDiscreteDynamicsWorld::solveConstraints(btContactSolverInfo& solverInfo) btTypedConstraint** constraintsPtr = getNumConstraints() ? &sortedConstraints[0] : 0; - InplaceSolverIslandCallback solverCallback( solverInfo, m_constraintSolver, constraintsPtr,sortedConstraints.size(), m_debugDrawer,m_stackAlloc); - + InplaceSolverIslandCallback solverCallback( solverInfo, m_constraintSolver, constraintsPtr,sortedConstraints.size(), m_debugDrawer,m_stackAlloc,m_dispatcher1); + m_constraintSolver->prepareSolve(getCollisionWorld()->getNumCollisionObjects(), getCollisionWorld()->getDispatcher()->getNumManifolds()); /// solve all the constraints for this island m_islandManager->buildAndProcessIslands(getCollisionWorld()->getDispatcher(),getCollisionWorld()->getCollisionObjectArray(),&solverCallback); - + m_constraintSolver->allSolved(solverInfo, m_debugDrawer, m_stackAlloc); } @@ -596,7 +626,7 @@ void btDiscreteDynamicsWorld::updateAabbs() //moving objects should be moderately sized, probably something wrong if not if ( colObj->isStaticObject() || ((maxAabb-minAabb).length2() < btScalar(1e12))) { - bp->setAabb(body->getBroadphaseHandle(),minAabb,maxAabb); + bp->setAabb(body->getBroadphaseHandle(),minAabb,maxAabb, m_dispatcher1); } else { //something went wrong, investigate @@ -856,10 +886,24 @@ void btDiscreteDynamicsWorld::debugDrawObject(const btTransform& worldTransform, btScalar radius = coneShape->getRadius();//+coneShape->getMargin(); btScalar height = coneShape->getHeight();//+coneShape->getMargin(); btVector3 start = worldTransform.getOrigin(); - getDebugDrawer()->drawLine(start+worldTransform.getBasis() * btVector3(btScalar(0.),btScalar(0.),btScalar(0.5)*height),start+worldTransform.getBasis() * btVector3(radius,btScalar(0.),btScalar(-0.5)*height),color); - getDebugDrawer()->drawLine(start+worldTransform.getBasis() * btVector3(btScalar(0.),btScalar(0.),btScalar(0.5)*height),start+worldTransform.getBasis() * btVector3(-radius,btScalar(0.),btScalar(-0.5)*height),color); - getDebugDrawer()->drawLine(start+worldTransform.getBasis() * btVector3(btScalar(0.),btScalar(0.),btScalar(0.5)*height),start+worldTransform.getBasis() * btVector3(btScalar(0.),radius,btScalar(-0.5)*height),color); - getDebugDrawer()->drawLine(start+worldTransform.getBasis() * btVector3(btScalar(0.),btScalar(0.),btScalar(0.5)*height),start+worldTransform.getBasis() * btVector3(btScalar(0.),-radius,btScalar(-0.5)*height),color); + + int upAxis= coneShape->getConeUpIndex(); + + + btVector3 offsetHeight(0,0,0); + offsetHeight[upAxis] = height * btScalar(0.5); + btVector3 offsetRadius(0,0,0); + offsetRadius[(upAxis+1)%3] = radius; + btVector3 offset2Radius(0,0,0); + offset2Radius[(upAxis+2)%3] = radius; + + getDebugDrawer()->drawLine(start+worldTransform.getBasis() * (offsetHeight),start+worldTransform.getBasis() * (-offsetHeight+offsetRadius),color); + getDebugDrawer()->drawLine(start+worldTransform.getBasis() * (offsetHeight),start+worldTransform.getBasis() * (-offsetHeight-offsetRadius),color); + getDebugDrawer()->drawLine(start+worldTransform.getBasis() * (offsetHeight),start+worldTransform.getBasis() * (-offsetHeight+offset2Radius),color); + getDebugDrawer()->drawLine(start+worldTransform.getBasis() * (offsetHeight),start+worldTransform.getBasis() * (-offsetHeight-offset2Radius),color); + + + break; } @@ -868,7 +912,7 @@ void btDiscreteDynamicsWorld::debugDrawObject(const btTransform& worldTransform, const btCylinderShape* cylinder = static_cast(shape); int upAxis = cylinder->getUpAxis(); btScalar radius = cylinder->getRadius(); - btScalar halfHeight = cylinder->getHalfExtents()[upAxis]; + btScalar halfHeight = cylinder->getHalfExtentsWithMargin()[upAxis]; btVector3 start = worldTransform.getOrigin(); btVector3 offsetHeight(0,0,0); offsetHeight[upAxis] = halfHeight; @@ -902,7 +946,7 @@ void btDiscreteDynamicsWorld::debugDrawObject(const btTransform& worldTransform, btVector3 aabbMin(btScalar(-1e30),btScalar(-1e30),btScalar(-1e30)); //DebugDrawcallback drawCallback; DebugDrawcallback drawCallback(getDebugDrawer(),worldTransform,color); - convexMesh->getStridingMesh()->InternalProcessAllTriangles(&drawCallback,aabbMin,aabbMax); + convexMesh->getMeshInterface()->InternalProcessAllTriangles(&drawCallback,aabbMin,aabbMax); } @@ -934,12 +978,18 @@ void btDiscreteDynamicsWorld::setConstraintSolver(btConstraintSolver* solver) { if (m_ownsConstraintSolver) { - delete m_constraintSolver; + btAlignedFree( m_constraintSolver); } m_ownsConstraintSolver = false; m_constraintSolver = solver; } +btConstraintSolver* btDiscreteDynamicsWorld::getConstraintSolver() +{ + return m_constraintSolver; +} + + int btDiscreteDynamicsWorld::getNumConstraints() const { return int(m_constraints.size()); diff --git a/extern/bullet2/src/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.h b/extern/bullet2/src/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.h index 83b90bfeebc..7364c4cd6b9 100644 --- a/extern/bullet2/src/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.h +++ b/extern/bullet2/src/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.h @@ -23,11 +23,11 @@ class btOverlappingPairCache; class btConstraintSolver; class btSimulationIslandManager; class btTypedConstraint; -#include "../ConstraintSolver/btContactSolverInfo.h" +#include "BulletDynamics/ConstraintSolver/btContactSolverInfo.h" class btRaycastVehicle; class btIDebugDraw; -#include "../../LinearMath/btAlignedObjectArray.h" +#include "LinearMath/btAlignedObjectArray.h" ///btDiscreteDynamicsWorld provides discrete rigid body simulation @@ -86,7 +86,7 @@ public: ///this btDiscreteDynamicsWorld constructor gets created objects from the user, and will not delete those - btDiscreteDynamicsWorld(btDispatcher* dispatcher,btOverlappingPairCache* pairCache,btConstraintSolver* constraintSolver); + btDiscreteDynamicsWorld(btDispatcher* dispatcher,btBroadphaseInterface* pairCache,btConstraintSolver* constraintSolver,btCollisionConfiguration* collisionConfiguration); virtual ~btDiscreteDynamicsWorld(); @@ -139,6 +139,8 @@ public: void debugDrawObject(const btTransform& worldTransform, const btCollisionShape* shape, const btVector3& color); virtual void setConstraintSolver(btConstraintSolver* solver); + + virtual btConstraintSolver* getConstraintSolver(); virtual int getNumConstraints() const; @@ -151,6 +153,11 @@ public: return m_solverInfo; } + virtual btDynamicsWorldType getWorldType() const + { + return BT_DISCRETE_DYNAMICS_WORLD; + } + }; diff --git a/extern/bullet2/src/BulletDynamics/Dynamics/btDynamicsWorld.h b/extern/bullet2/src/BulletDynamics/Dynamics/btDynamicsWorld.h index 65b63fad4b5..a4c8bf3c559 100644 --- a/extern/bullet2/src/BulletDynamics/Dynamics/btDynamicsWorld.h +++ b/extern/bullet2/src/BulletDynamics/Dynamics/btDynamicsWorld.h @@ -16,20 +16,27 @@ subject to the following restrictions: #ifndef BT_DYNAMICS_WORLD_H #define BT_DYNAMICS_WORLD_H -#include "../../BulletCollision/CollisionDispatch/btCollisionWorld.h" +#include "BulletCollision/CollisionDispatch/btCollisionWorld.h" class btTypedConstraint; class btRaycastVehicle; class btConstraintSolver; +enum btDynamicsWorldType +{ + BT_SIMPLE_DYNAMICS_WORLD=1, + BT_DISCRETE_DYNAMICS_WORLD=2, + BT_CONTINUOUS_DYNAMICS_WORLD=3 +}; + ///btDynamicsWorld is the baseclass for several dynamics implementation, basic, discrete, parallel, and continuous class btDynamicsWorld : public btCollisionWorld { public: - btDynamicsWorld(btDispatcher* dispatcher,btOverlappingPairCache* pairCache) - :btCollisionWorld(dispatcher,pairCache) + btDynamicsWorld(btDispatcher* dispatcher,btBroadphaseInterface* broadphase,btCollisionConfiguration* collisionConfiguration) + :btCollisionWorld(dispatcher,broadphase,collisionConfiguration) { } @@ -65,6 +72,8 @@ class btDynamicsWorld : public btCollisionWorld virtual void removeRigidBody(btRigidBody* body) = 0; virtual void setConstraintSolver(btConstraintSolver* solver) = 0; + + virtual btConstraintSolver* getConstraintSolver() = 0; virtual int getNumConstraints() const { return 0; } @@ -72,6 +81,8 @@ class btDynamicsWorld : public btCollisionWorld virtual const btTypedConstraint* getConstraint(int index) const { (void)index; return 0; } + virtual btDynamicsWorldType getWorldType() const=0; + }; #endif //BT_DYNAMICS_WORLD_H diff --git a/extern/bullet2/src/BulletDynamics/Dynamics/btRigidBody.cpp b/extern/bullet2/src/BulletDynamics/Dynamics/btRigidBody.cpp index 02cf44d0cfa..03e60acdb19 100644 --- a/extern/bullet2/src/BulletDynamics/Dynamics/btRigidBody.cpp +++ b/extern/bullet2/src/BulletDynamics/Dynamics/btRigidBody.cpp @@ -39,6 +39,8 @@ btRigidBody::btRigidBody(btScalar mass, btMotionState* motionState, btCollisionS m_totalTorque(btScalar(0.0), btScalar(0.0), btScalar(0.0)), m_linearDamping(btScalar(0.)), m_angularDamping(btScalar(0.5)), + m_linearSleepingThreshold(gLinearSleepingThreshold), + m_angularSleepingThreshold(gAngularSleepingThreshold), m_optionalMotionState(motionState), m_contactSolverType(0), m_frictionSolverType(0) @@ -79,12 +81,15 @@ btRigidBody::btRigidBody( btScalar mass,const btTransform& worldTransform,btColl m_totalForce(btScalar(0.0), btScalar(0.0), btScalar(0.0)), m_totalTorque(btScalar(0.0), btScalar(0.0), btScalar(0.0)), m_linearVelocity(btScalar(0.0), btScalar(0.0), btScalar(0.0)), - m_angularVelocity(btScalar(0.),btScalar(0.),btScalar(0.)), + m_angularVelocity(btScalar(0.),btScalar(0.),btScalar(0.)), + m_linearSleepingThreshold(gLinearSleepingThreshold), + m_angularSleepingThreshold(gAngularSleepingThreshold), m_linearDamping(btScalar(0.)), m_angularDamping(btScalar(0.5)), m_optionalMotionState(0), m_contactSolverType(0), m_frictionSolverType(0) + { m_worldTransform = worldTransform; @@ -113,7 +118,7 @@ btRigidBody::btRigidBody( btScalar mass,const btTransform& worldTransform,btColl -//#define EXPERIMENTAL_JITTER_REMOVAL 1 +#define EXPERIMENTAL_JITTER_REMOVAL 1 #ifdef EXPERIMENTAL_JITTER_REMOVAL //Bullet 2.20b has experimental damping code to reduce jitter just before objects fall asleep/deactivate //doesn't work very well yet (value 0 disabled this damping) @@ -342,4 +347,4 @@ void btRigidBody::removeConstraintRef(btTypedConstraint* c) { m_constraintRefs.remove(c); m_checkCollideWith = m_constraintRefs.size() > 0; -} \ No newline at end of file +} diff --git a/extern/bullet2/src/BulletDynamics/Dynamics/btRigidBody.h b/extern/bullet2/src/BulletDynamics/Dynamics/btRigidBody.h index 0707595d48e..b11f9f76d7d 100644 --- a/extern/bullet2/src/BulletDynamics/Dynamics/btRigidBody.h +++ b/extern/bullet2/src/BulletDynamics/Dynamics/btRigidBody.h @@ -16,11 +16,11 @@ subject to the following restrictions: #ifndef RIGIDBODY_H #define RIGIDBODY_H -#include "../../LinearMath/btAlignedObjectArray.h" -#include "../../LinearMath/btPoint3.h" -#include "../../LinearMath/btTransform.h" -#include "../../BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" -#include "../../BulletCollision/CollisionDispatch/btCollisionObject.h" +#include "LinearMath/btAlignedObjectArray.h" +#include "LinearMath/btPoint3.h" +#include "LinearMath/btTransform.h" +#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" +#include "BulletCollision/CollisionDispatch/btCollisionObject.h" class btCollisionShape; class btMotionState; @@ -53,7 +53,10 @@ class btRigidBody : public btCollisionObject btScalar m_linearDamping; btScalar m_angularDamping; - + + btScalar m_linearSleepingThreshold; + btScalar m_angularSleepingThreshold; + //m_optionalMotionState allows to automatic synchronize the world transform for active objects btMotionState* m_optionalMotionState; @@ -70,6 +73,14 @@ public: btRigidBody(btScalar mass, btMotionState* motionState, btCollisionShape* collisionShape, const btVector3& localInertia=btVector3(0,0,0),btScalar linearDamping=btScalar(0.),btScalar angularDamping=btScalar(0.),btScalar friction=btScalar(0.5),btScalar restitution=btScalar(0.)); + virtual ~btRigidBody() + { + //No constraints should point to this rigidbody + //Remove constraints from the dynamics world before you delete the related rigidbodies. + btAssert(m_constraintRefs.size()==0); + } + + void proceedToTransform(const btTransform& newTrans); ///to keep collision detection and dynamics separate we don't store a rigidbody pointer @@ -100,11 +111,11 @@ public: void setDamping(btScalar lin_damping, btScalar ang_damping); - inline const btCollisionShape* getCollisionShape() const { + SIMD_FORCE_INLINE const btCollisionShape* getCollisionShape() const { return m_collisionShape; } - inline btCollisionShape* getCollisionShape() { + SIMD_FORCE_INLINE btCollisionShape* getCollisionShape() { return m_collisionShape; } @@ -134,6 +145,12 @@ public: m_invInertiaLocal = diagInvInertia; } + void setSleepingThresholds(btScalar linear,btScalar angular) + { + m_linearSleepingThreshold = linear; + m_angularSleepingThreshold = angular; + } + void applyTorque(const btVector3& torque) { m_totalTorque += torque; @@ -168,7 +185,7 @@ public: } //Optimization for the iterative solver: avoid calculating constant terms involving inertia, normal, relative position - inline void internalApplyImpulse(const btVector3& linearComponent, const btVector3& angularComponent,btScalar impulseMagnitude) + SIMD_FORCE_INLINE void internalApplyImpulse(const btVector3& linearComponent, const btVector3& angularComponent,btScalar impulseMagnitude) { if (m_inverseMass != btScalar(0.)) { @@ -238,7 +255,7 @@ public: - inline btScalar computeImpulseDenominator(const btPoint3& pos, const btVector3& normal) const + SIMD_FORCE_INLINE btScalar computeImpulseDenominator(const btPoint3& pos, const btVector3& normal) const { btVector3 r0 = pos - getCenterOfMassPosition(); @@ -250,19 +267,19 @@ public: } - inline btScalar computeAngularImpulseDenominator(const btVector3& axis) const + SIMD_FORCE_INLINE btScalar computeAngularImpulseDenominator(const btVector3& axis) const { btVector3 vec = axis * getInvInertiaTensorWorld(); return axis.dot(vec); } - inline void updateDeactivation(btScalar timeStep) + SIMD_FORCE_INLINE void updateDeactivation(btScalar timeStep) { if ( (getActivationState() == ISLAND_SLEEPING) || (getActivationState() == DISABLE_DEACTIVATION)) return; - if ((getLinearVelocity().length2() < gLinearSleepingThreshold*gLinearSleepingThreshold) && - (getAngularVelocity().length2() < gAngularSleepingThreshold*gAngularSleepingThreshold)) + if ((getLinearVelocity().length2() < m_linearSleepingThreshold*m_linearSleepingThreshold) && + (getAngularVelocity().length2() < m_angularSleepingThreshold*m_angularSleepingThreshold)) { m_deactivationTime += timeStep; } else @@ -273,7 +290,7 @@ public: } - inline bool wantsSleeping() + SIMD_FORCE_INLINE bool wantsSleeping() { if (getActivationState() == DISABLE_DEACTIVATION) @@ -348,6 +365,17 @@ public: void addConstraintRef(btTypedConstraint* c); void removeConstraintRef(btTypedConstraint* c); + btTypedConstraint* getConstraintRef(int index) + { + return m_constraintRefs[index]; + } + + int getNumConstraintRefs() + { + return m_constraintRefs.size(); + } + + int m_debugBodyId; }; diff --git a/extern/bullet2/src/BulletDynamics/Dynamics/btSimpleDynamicsWorld.cpp b/extern/bullet2/src/BulletDynamics/Dynamics/btSimpleDynamicsWorld.cpp index 4ebcb8e7517..3a78ec54f1c 100644 --- a/extern/bullet2/src/BulletDynamics/Dynamics/btSimpleDynamicsWorld.cpp +++ b/extern/bullet2/src/BulletDynamics/Dynamics/btSimpleDynamicsWorld.cpp @@ -32,8 +32,8 @@ extern "C" void btBulletDynamicsProbe () {} -btSimpleDynamicsWorld::btSimpleDynamicsWorld(btDispatcher* dispatcher,btOverlappingPairCache* pairCache,btConstraintSolver* constraintSolver) -:btDynamicsWorld(dispatcher,pairCache), +btSimpleDynamicsWorld::btSimpleDynamicsWorld(btDispatcher* dispatcher,btBroadphaseInterface* pairCache,btConstraintSolver* constraintSolver,btCollisionConfiguration* collisionConfiguration) +:btDynamicsWorld(dispatcher,pairCache,collisionConfiguration), m_constraintSolver(constraintSolver), m_ownsConstraintSolver(false), m_debugDrawer(0), @@ -46,7 +46,7 @@ m_gravity(0,0,-10) btSimpleDynamicsWorld::~btSimpleDynamicsWorld() { if (m_ownsConstraintSolver) - delete m_constraintSolver; + btAlignedFree( m_constraintSolver); } int btSimpleDynamicsWorld::stepSimulation( btScalar timeStep,int maxSubSteps, btScalar fixedTimeStep) @@ -74,8 +74,9 @@ int btSimpleDynamicsWorld::stepSimulation( btScalar timeStep,int maxSubSteps, b btContactSolverInfo infoGlobal; infoGlobal.m_timeStep = timeStep; - - m_constraintSolver->solveGroup(0,0,manifoldPtr, numManifolds,0,0,infoGlobal,m_debugDrawer, m_stackAlloc); + m_constraintSolver->prepareSolve(0,numManifolds); + m_constraintSolver->solveGroup(0,0,manifoldPtr, numManifolds,0,0,infoGlobal,m_debugDrawer, m_stackAlloc,m_dispatcher1); + m_constraintSolver->allSolved(infoGlobal,m_debugDrawer, m_stackAlloc); } ///integrate transforms @@ -133,7 +134,7 @@ void btSimpleDynamicsWorld::updateAabbs() btPoint3 minAabb,maxAabb; colObj->getCollisionShape()->getAabb(colObj->getWorldTransform(), minAabb,maxAabb); btBroadphaseInterface* bp = getBroadphase(); - bp->setAabb(body->getBroadphaseHandle(),minAabb,maxAabb); + bp->setAabb(body->getBroadphaseHandle(),minAabb,maxAabb, m_dispatcher1); } } } @@ -204,8 +205,13 @@ void btSimpleDynamicsWorld::setConstraintSolver(btConstraintSolver* solver) { if (m_ownsConstraintSolver) { - delete m_constraintSolver; + btAlignedFree(m_constraintSolver); } m_ownsConstraintSolver = false; m_constraintSolver = solver; } + +btConstraintSolver* btSimpleDynamicsWorld::getConstraintSolver() +{ + return m_constraintSolver; +} diff --git a/extern/bullet2/src/BulletDynamics/Dynamics/btSimpleDynamicsWorld.h b/extern/bullet2/src/BulletDynamics/Dynamics/btSimpleDynamicsWorld.h index 25f4ccd8e68..4e38f74a731 100644 --- a/extern/bullet2/src/BulletDynamics/Dynamics/btSimpleDynamicsWorld.h +++ b/extern/bullet2/src/BulletDynamics/Dynamics/btSimpleDynamicsWorld.h @@ -22,11 +22,8 @@ class btDispatcher; class btOverlappingPairCache; class btConstraintSolver; -///btSimpleDynamicsWorld demonstrates very basic usage of Bullet rigid body dynamics -///It can be used for basic simulations, and as a starting point for porting Bullet -///btSimpleDynamicsWorld lacks object deactivation, island management and other concepts. -///For more complicated simulations, btDiscreteDynamicsWorld and btContinuousDynamicsWorld are recommended -///those classes replace the obsolete CcdPhysicsEnvironment/CcdPhysicsController +///btSimpleDynamicsWorld serves as unit-test and to verify more complicated and optimized dynamics worlds. +///Please use btDiscreteDynamicsWorld instead (or btContinuousDynamicsWorld once it is finished). class btSimpleDynamicsWorld : public btDynamicsWorld { protected: @@ -48,7 +45,7 @@ public: ///this btSimpleDynamicsWorld constructor creates dispatcher, broadphase pairCache and constraintSolver - btSimpleDynamicsWorld(btDispatcher* dispatcher,btOverlappingPairCache* pairCache,btConstraintSolver* constraintSolver); + btSimpleDynamicsWorld(btDispatcher* dispatcher,btBroadphaseInterface* pairCache,btConstraintSolver* constraintSolver,btCollisionConfiguration* collisionConfiguration); virtual ~btSimpleDynamicsWorld(); @@ -77,6 +74,13 @@ public: virtual void setConstraintSolver(btConstraintSolver* solver); + virtual btConstraintSolver* getConstraintSolver(); + + virtual btDynamicsWorldType getWorldType() const + { + return BT_SIMPLE_DYNAMICS_WORLD; + } + }; #endif //BT_SIMPLE_DYNAMICS_WORLD_H diff --git a/extern/bullet2/src/BulletDynamics/Vehicle/btRaycastVehicle.cpp b/extern/bullet2/src/BulletDynamics/Vehicle/btRaycastVehicle.cpp index d53de7f3687..8dcd6d895e4 100644 --- a/extern/bullet2/src/BulletDynamics/Vehicle/btRaycastVehicle.cpp +++ b/extern/bullet2/src/BulletDynamics/Vehicle/btRaycastVehicle.cpp @@ -28,7 +28,8 @@ static btRigidBody s_fixedObject( 0,0,0); btRaycastVehicle::btRaycastVehicle(const btVehicleTuning& tuning,btRigidBody* chassis, btVehicleRaycaster* raycaster ) -:m_vehicleRaycaster(raycaster), +: btTypedConstraint(VEHICLE_CONSTRAINT_TYPE), +m_vehicleRaycaster(raycaster), m_pitchControl(btScalar(0.)) { m_chassisBody = chassis; @@ -507,8 +508,8 @@ btScalar calcRollingFriction(btWheelContactPoint& contactPoint) // calculate j that moves us to zero relative velocity j1 = -vrel * contactPoint.m_jacDiagABInv; - GEN_set_min(j1, maxImpulse); - GEN_set_max(j1, -maxImpulse); + btSetMin(j1, maxImpulse); + btSetMax(j1, -maxImpulse); return j1; } @@ -526,10 +527,14 @@ void btRaycastVehicle::updateFriction(btScalar timeStep) return; - btVector3* forwardWS = new btVector3[numWheel]; - btVector3* axle = new btVector3[numWheel]; - btScalar* forwardImpulse = new btScalar[numWheel]; - btScalar* sideImpulse = new btScalar[numWheel]; + void* mem = btAlignedAlloc(numWheel*sizeof(btVector3),16); + btVector3* forwardWS = new (mem)btVector3[numWheel]; + mem = btAlignedAlloc(numWheel*sizeof(btVector3),16); + btVector3* axle = new (mem)btVector3[numWheel]; + mem = btAlignedAlloc(numWheel*sizeof(btScalar),16); + btScalar* forwardImpulse = new (mem)btScalar[numWheel]; + mem = btAlignedAlloc(numWheel*sizeof(btScalar),16); + btScalar* sideImpulse = new(mem) btScalar[numWheel]; int numWheelsOnGround = 0; @@ -701,10 +706,10 @@ void btRaycastVehicle::updateFriction(btScalar timeStep) } } - delete []forwardWS; - delete [] axle; - delete[]forwardImpulse; - delete[] sideImpulse; + btAlignedFree(forwardWS); + btAlignedFree(axle); + btAlignedFree(forwardImpulse); + btAlignedFree(sideImpulse); } diff --git a/extern/bullet2/src/BulletDynamics/Vehicle/btRaycastVehicle.h b/extern/bullet2/src/BulletDynamics/Vehicle/btRaycastVehicle.h index f4249599615..a84b185e947 100644 --- a/extern/bullet2/src/BulletDynamics/Vehicle/btRaycastVehicle.h +++ b/extern/bullet2/src/BulletDynamics/Vehicle/btRaycastVehicle.h @@ -11,11 +11,11 @@ #ifndef RAYCASTVEHICLE_H #define RAYCASTVEHICLE_H -#include "../Dynamics/btRigidBody.h" -#include "../ConstraintSolver/btTypedConstraint.h" +#include "BulletDynamics/Dynamics/btRigidBody.h" +#include "BulletDynamics/ConstraintSolver/btTypedConstraint.h" #include "btVehicleRaycaster.h" class btDynamicsWorld; -#include "../../LinearMath/btAlignedObjectArray.h" +#include "LinearMath/btAlignedObjectArray.h" #include "btWheelInfo.h" class btVehicleTuning; diff --git a/extern/bullet2/src/BulletDynamics/Vehicle/btVehicleRaycaster.h b/extern/bullet2/src/BulletDynamics/Vehicle/btVehicleRaycaster.h index 64a47fcaada..5112ce6d420 100644 --- a/extern/bullet2/src/BulletDynamics/Vehicle/btVehicleRaycaster.h +++ b/extern/bullet2/src/BulletDynamics/Vehicle/btVehicleRaycaster.h @@ -11,7 +11,7 @@ #ifndef VEHICLE_RAYCASTER_H #define VEHICLE_RAYCASTER_H -#include "../../LinearMath/btVector3.h" +#include "LinearMath/btVector3.h" /// btVehicleRaycaster is provides interface for between vehicle simulation and raycasting struct btVehicleRaycaster diff --git a/extern/bullet2/src/BulletDynamics/Vehicle/btWheelInfo.h b/extern/bullet2/src/BulletDynamics/Vehicle/btWheelInfo.h index 2e349b3fde4..ac2729f4fd7 100644 --- a/extern/bullet2/src/BulletDynamics/Vehicle/btWheelInfo.h +++ b/extern/bullet2/src/BulletDynamics/Vehicle/btWheelInfo.h @@ -11,8 +11,8 @@ #ifndef WHEEL_INFO_H #define WHEEL_INFO_H -#include "../../LinearMath/btVector3.h" -#include "../../LinearMath/btTransform.h" +#include "LinearMath/btVector3.h" +#include "LinearMath/btTransform.h" class btRigidBody; diff --git a/extern/bullet2/src/BulletDynamics/ibmsdk/Makefile b/extern/bullet2/src/BulletDynamics/ibmsdk/Makefile new file mode 100644 index 00000000000..b599a0fd9a1 --- /dev/null +++ b/extern/bullet2/src/BulletDynamics/ibmsdk/Makefile @@ -0,0 +1,45 @@ +#### Source code Dirs +VPATH = \ +../ConstraintSolver \ +../Dynamics \ +../Vehicle + +ROOT = ../../.. + +#### Library +LIBRARY_ppu = bulletdynamics.a + +#### Compiler flags +CPPFLAGS = \ +-DUSE_LIBSPE2 \ +-I../ConstraintSolver \ +-I../Dynamics \ +-I../Vehicle \ +-I$(ROOT)/src \ +-I$(SDKINC) + +#### Optimization level flags +#CC_OPT_LEVEL = $(CC_OPT_LEVEL_DEBUG) +CC_OPT_LEVEL = -O3 + +##### Objects to be archived in lib + +OBJS = \ +btContactConstraint.o \ +btGeneric6DofConstraint.o \ +btHingeConstraint.o \ +btPoint2PointConstraint.o \ +btSequentialImpulseConstraintSolver.o \ +btSolve2LinearConstraint.o \ +btTypedConstraint.o \ +btDiscreteDynamicsWorld.o \ +btRigidBody.o \ +btSimpleDynamicsWorld.o \ +btRaycastVehicle.o \ +btWheelInfo.o +#### Install directories +INSTALL_DIR = $(ROOT)/lib/ibmsdk +INSTALL_FILES = $(LIBRARY_ppu) +CELL_TOP ?= /opt/ibm/cell-sdk/prototype + +include $(CELL_TOP)/make.footer diff --git a/extern/bullet2/src/LinearMath/CMakeLists.txt b/extern/bullet2/src/LinearMath/CMakeLists.txt index 207eed94a3e..82393547bfb 100644 --- a/extern/bullet2/src/LinearMath/CMakeLists.txt +++ b/extern/bullet2/src/LinearMath/CMakeLists.txt @@ -6,5 +6,6 @@ ${BULLET_PHYSICS_SOURCE_DIR}/src } ADD_LIBRARY(LibLinearMath btQuickprof.cpp btGeometryUtil.cpp +btAlignedAllocator.cpp ) diff --git a/extern/bullet2/src/LinearMath/btAabbUtil2.h b/extern/bullet2/src/LinearMath/btAabbUtil2.h index 429163c8138..9b320961ba1 100644 --- a/extern/bullet2/src/LinearMath/btAabbUtil2.h +++ b/extern/bullet2/src/LinearMath/btAabbUtil2.h @@ -18,11 +18,9 @@ subject to the following restrictions: #define AABB_UTIL2 #include "btVector3.h" -#include "btSimdMinMax.h" +#include "btMinMax.h" -#define btMin(a,b) ((a < b ? a : b)) -#define btMax(a,b) ((a > b ? a : b)) /// conservative test for overlap between two aabbs diff --git a/extern/bullet2/src/LinearMath/btAlignedAllocator.cpp b/extern/bullet2/src/LinearMath/btAlignedAllocator.cpp index 1f5877fa37e..6b33ddbb8cf 100644 --- a/extern/bullet2/src/LinearMath/btAlignedAllocator.cpp +++ b/extern/bullet2/src/LinearMath/btAlignedAllocator.cpp @@ -15,17 +15,83 @@ subject to the following restrictions: #include "btAlignedAllocator.h" +int gNumAlignedAllocs = 0; +int gNumAlignedFree = 0; +int gTotalBytesAlignedAllocs = 0;//detect memory leaks -#if defined (BT_HAS_ALIGNED_ALOCATOR) +#ifdef BT_DEBUG_MEMORY_ALLOCATIONS +//this generic allocator provides the total allocated number of bytes +#include -#include -void* btAlignedAlloc (int size, int alignment) +void* btAlignedAllocInternal (size_t size, int alignment,int line,char* filename) { - return _aligned_malloc(size,alignment); + void *ret; + char *real; + unsigned long offset; + + gTotalBytesAlignedAllocs += size; + gNumAlignedAllocs++; + + printf("allocation#%d from %s,line %d, size %d\n",gNumAlignedAllocs,filename,line,size); + real = (char *)malloc(size + 2*sizeof(void *) + (alignment-1)); + if (real) { + offset = (alignment - (unsigned long)(real + 2*sizeof(void *))) & +(alignment-1); + ret = (void *)((real + 2*sizeof(void *)) + offset); + *((void **)(ret)-1) = (void *)(real); + *((int*)(ret)-2) = size; + + } else { + ret = (void *)(real);//?? + } + int* ptr = (int*)ret; + *ptr = 12; + return (ret); +} +#include +void btAlignedFreeInternal (void* ptr,int line,char* filename) +{ + + void* real; + gNumAlignedFree++; + + if (ptr) { + real = *((void **)(ptr)-1); + int size = *((int*)(ptr)-2); + gTotalBytesAlignedAllocs -= size; + + printf("free #%d from %s,line %d, size %d\n",gNumAlignedFree,filename,line,size); + + free(real); + } else + { + printf("NULL ptr\n"); + } } -void btAlignedFree (void* ptr) +#else //BT_DEBUG_MEMORY_ALLOCATIONS + + +#if defined (BT_HAS_ALIGNED_ALLOCATOR) + + + + + +#include +void* btAlignedAllocInternal (size_t size, int alignment) { + gNumAlignedAllocs++; + + void* ptr = _aligned_malloc(size,alignment); +// printf("btAlignedAllocInternal %d, %x\n",size,ptr); + return ptr; +} + +void btAlignedFreeInternal (void* ptr) +{ + gNumAlignedFree++; +// printf("btAlignedFreeInternal %x\n",ptr); _aligned_free(ptr); } @@ -35,36 +101,55 @@ void btAlignedFree (void* ptr) #include -int numAllocs = 0; -int numFree = 0; -void* btAlignedAlloc (int size, int alignment) + +void* btAlignedAllocInternal (size_t size, int alignment) { - numAllocs++; + gNumAlignedAllocs++; return memalign(alignment, size); } -void btAlignedFree (void* ptr) +void btAlignedFreeInternal (void* ptr) { - numFree++; + gNumAlignedFree++; free(ptr); } #else -///todo -///will add some multi-platform version that works without _aligned_malloc/_aligned_free -void* btAlignedAlloc (int size, int alignment) +void* btAlignedAllocInternal (size_t size, int alignment) { - return new char[size]; + void *ret; + char *real; + unsigned long offset; + + gNumAlignedAllocs++; + + real = (char *)malloc(size + sizeof(void *) + (alignment-1)); + if (real) { + offset = (alignment - (unsigned long)(real + sizeof(void *))) & (alignment-1); + ret = (void *)((real + sizeof(void *)) + offset); + *((void **)(ret)-1) = (void *)(real); + } else { + ret = (void *)(real); + } + return (ret); } -void btAlignedFree (void* ptr) +void btAlignedFreeInternal (void* ptr) { - delete [] (char*) ptr; + + void* real; + gNumAlignedFree++; + + if (ptr) { + real = *((void **)(ptr)-1); + free(real); + } } #endif // #endif +#endif //BT_DEBUG_MEMORY_ALLOCATIONS diff --git a/extern/bullet2/src/LinearMath/btAlignedAllocator.h b/extern/bullet2/src/LinearMath/btAlignedAllocator.h index 07585717f45..2b48e79e497 100644 --- a/extern/bullet2/src/LinearMath/btAlignedAllocator.h +++ b/extern/bullet2/src/LinearMath/btAlignedAllocator.h @@ -21,12 +21,26 @@ subject to the following restrictions: ///that is better portable and more predictable #include "btScalar.h" +//#define BT_DEBUG_MEMORY_ALLOCATIONS 1 +#ifdef BT_DEBUG_MEMORY_ALLOCATIONS -void* btAlignedAlloc (int size, int alignment); +#define btAlignedAlloc(a,b) \ + btAlignedAllocInternal(a,b,__LINE__,__FILE__) -void btAlignedFree (void* ptr); +#define btAlignedFree(ptr) \ + btAlignedFreeInternal(ptr,__LINE__,__FILE__) +void* btAlignedAllocInternal (size_t size, int alignment,int line,char* filename); +void btAlignedFreeInternal (void* ptr,int line,char* filename); + +#else + void* btAlignedAllocInternal (size_t size, int alignment); + void btAlignedFreeInternal (void* ptr); + + #define btAlignedAlloc(a,b) btAlignedAllocInternal(a,b) + #define btAlignedFree(ptr) btAlignedFreeInternal(ptr) +#endif typedef int size_type; diff --git a/extern/bullet2/src/LinearMath/btAlignedObjectArray.h b/extern/bullet2/src/LinearMath/btAlignedObjectArray.h index 8bef5eb5d06..66911316fbb 100644 --- a/extern/bullet2/src/LinearMath/btAlignedObjectArray.h +++ b/extern/bullet2/src/LinearMath/btAlignedObjectArray.h @@ -50,6 +50,8 @@ class btAlignedObjectArray int m_size; int m_capacity; T* m_data; + //PCK: added this line + bool m_ownsMemory; protected: SIMD_FORCE_INLINE int allocSize(int size) @@ -69,6 +71,8 @@ class btAlignedObjectArray SIMD_FORCE_INLINE void init() { + //PCK: added this line + m_ownsMemory = true; m_data = 0; m_size = 0; m_capacity = 0; @@ -92,7 +96,11 @@ class btAlignedObjectArray SIMD_FORCE_INLINE void deallocate() { if(m_data) { - m_allocator.deallocate(m_data); + //PCK: enclosed the deallocation in this block + if (m_ownsMemory) + { + m_allocator.deallocate(m_data); + } m_data = 0; } } @@ -223,6 +231,9 @@ class btAlignedObjectArray destroy(0,size()); deallocate(); + + //PCK: added this line + m_ownsMemory = true; m_data = s; @@ -360,8 +371,16 @@ class btAlignedObjectArray } } + //PCK: whole function + void initializeFromBuffer(void *buffer, int size, int capacity) + { + clear(); + m_ownsMemory = false; + m_data = (T*)buffer; + m_size = size; + m_capacity = capacity; + } + }; #endif //BT_OBJECT_ARRAY__ - - diff --git a/extern/bullet2/src/LinearMath/btIDebugDraw.h b/extern/bullet2/src/LinearMath/btIDebugDraw.h index 5f40ca39157..2d96cff5055 100644 --- a/extern/bullet2/src/LinearMath/btIDebugDraw.h +++ b/extern/bullet2/src/LinearMath/btIDebugDraw.h @@ -60,6 +60,8 @@ class btIDebugDraw virtual void reportErrorWarning(const char* warningString) = 0; + virtual void draw3dText(const btVector3& location,const char* textString) = 0; + virtual void setDebugMode(int debugMode) =0; virtual int getDebugMode() const = 0; diff --git a/extern/bullet2/src/LinearMath/btMatrix3x3.h b/extern/bullet2/src/LinearMath/btMatrix3x3.h index 94f53c3c0a5..59680ff460d 100644 --- a/extern/bullet2/src/LinearMath/btMatrix3x3.h +++ b/extern/bullet2/src/LinearMath/btMatrix3x3.h @@ -356,7 +356,7 @@ class btMatrix3x3 { m_el[0].y() * m[0].z() + m_el[1].y() * m[1].z() + m_el[2].y() * m[2].z(), m_el[0].z() * m[0].x() + m_el[1].z() * m[1].x() + m_el[2].z() * m[2].x(), m_el[0].z() * m[0].y() + m_el[1].z() * m[1].y() + m_el[2].z() * m[2].y(), - m_el[0].z() * m[0].z() + m_el[1].z() * m[1].z() + m_el[2].z() * m[2].x()); + m_el[0].z() * m[0].z() + m_el[1].z() * m[1].z() + m_el[2].z() * m[2].z()); } SIMD_FORCE_INLINE btMatrix3x3 diff --git a/extern/bullet2/src/LinearMath/btMinMax.h b/extern/bullet2/src/LinearMath/btMinMax.h index 1b8a3633f38..5e27d62a4a4 100644 --- a/extern/bullet2/src/LinearMath/btMinMax.h +++ b/extern/bullet2/src/LinearMath/btMinMax.h @@ -18,15 +18,15 @@ subject to the following restrictions: #define GEN_MINMAX_H template -SIMD_FORCE_INLINE const T& GEN_min(const T& a, const T& b) +SIMD_FORCE_INLINE const T& btMin(const T& a, const T& b) { - return b < a ? b : a; + return a < b ? a : b ; } template -SIMD_FORCE_INLINE const T& GEN_max(const T& a, const T& b) +SIMD_FORCE_INLINE const T& btMax(const T& a, const T& b) { - return a < b ? b : a; + return a > b ? a : b; } template @@ -36,7 +36,7 @@ SIMD_FORCE_INLINE const T& GEN_clamped(const T& a, const T& lb, const T& ub) } template -SIMD_FORCE_INLINE void GEN_set_min(T& a, const T& b) +SIMD_FORCE_INLINE void btSetMin(T& a, const T& b) { if (b < a) { @@ -45,7 +45,7 @@ SIMD_FORCE_INLINE void GEN_set_min(T& a, const T& b) } template -SIMD_FORCE_INLINE void GEN_set_max(T& a, const T& b) +SIMD_FORCE_INLINE void btSetMax(T& a, const T& b) { if (a < b) { diff --git a/extern/bullet2/src/LinearMath/btPoolAllocator.h b/extern/bullet2/src/LinearMath/btPoolAllocator.h new file mode 100755 index 00000000000..ad772ae123f --- /dev/null +++ b/extern/bullet2/src/LinearMath/btPoolAllocator.h @@ -0,0 +1,94 @@ +/* +Copyright (c) 2003-2006 Gino van den Bergen / 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 _BT_POOL_ALLOCATOR_H +#define _BT_POOL_ALLOCATOR_H + +#include "btScalar.h" +#include "btAlignedAllocator.h" + +class btPoolAllocator +{ + int m_elemSize; + int m_maxElements; + int m_freeCount; + void* m_firstFree; + unsigned char* m_pool; + +public: + + btPoolAllocator(int elemSize, int maxElements) + :m_elemSize(elemSize), + m_maxElements(maxElements) + { + m_pool = (unsigned char*) btAlignedAlloc(m_elemSize*m_maxElements,16); + + unsigned char* p = m_pool; + m_firstFree = p; + m_freeCount = m_maxElements; + int count = m_maxElements; + while (--count) { + *(void**)p = (p + m_elemSize); + p += m_elemSize; + } + *(void**)p = 0; + } + + ~btPoolAllocator() + { + btAlignedFree( m_pool); + } + + int getFreeCount() const + { + return m_freeCount; + } + + void* allocate(int size) + { + btAssert(!size || size<=m_elemSize); + btAssert(m_freeCount>0); + void* result = m_firstFree; + m_firstFree = *(void**)m_firstFree; + --m_freeCount; + return result; + } + + bool validPtr(void* ptr) + { + if (ptr) { + if (((unsigned char*)ptr >= m_pool && (unsigned char*)ptr < m_pool + m_maxElements * m_elemSize)) + { + return true; + } + } + return false; + } + + void free(void* ptr) + { + if (ptr) { + btAssert((unsigned char*)ptr >= m_pool && (unsigned char*)ptr < m_pool + m_maxElements * m_elemSize); + + *(void**)ptr = m_firstFree; + m_firstFree = ptr; + ++m_freeCount; + } + } + + +}; + +#endif //_BT_POOL_ALLOCATOR_H diff --git a/extern/bullet2/src/LinearMath/btQuadWord.h b/extern/bullet2/src/LinearMath/btQuadWord.h index 961ac484d20..2e5950ebd5d 100644 --- a/extern/bullet2/src/LinearMath/btQuadWord.h +++ b/extern/bullet2/src/LinearMath/btQuadWord.h @@ -17,19 +17,24 @@ subject to the following restrictions: #define SIMD_QUADWORD_H #include "btScalar.h" +#include "btMinMax.h" +//ATTRIBUTE_ALIGNED16(class) btQuadWordStorage +//some issues under PS3 Linux with IBM 2.1 SDK, gcc compiler prevent from using aligned quadword. todo: look into this +class btQuadWordStorage +{ +protected: + btScalar m_x; + btScalar m_y; + btScalar m_z; + btScalar m_unusedW; +}; ///btQuadWord is base-class for vectors, points -class btQuadWord +class btQuadWord : public btQuadWordStorage { - protected: - btScalar m_x; - btScalar m_y; - btScalar m_z; - btScalar m_unusedW; - public: // SIMD_FORCE_INLINE btScalar& operator[](int i) { return (&m_x)[i]; } @@ -61,6 +66,8 @@ class btQuadWord SIMD_FORCE_INLINE operator btScalar *() { return &m_x; } SIMD_FORCE_INLINE operator const btScalar *() const { return &m_x; } + + SIMD_FORCE_INLINE void setValue(const btScalar& x, const btScalar& y, const btScalar& z) { m_x=x; @@ -89,47 +96,36 @@ class btQuadWord { } - SIMD_FORCE_INLINE btQuadWord(const btScalar& x, const btScalar& y, const btScalar& z) - :m_x(x),m_y(y),m_z(z) - //todo, remove this in release/simd ? - ,m_unusedW(btScalar(0.)) + SIMD_FORCE_INLINE btQuadWord(const btQuadWordStorage& q) { + *((btQuadWordStorage*)this) = q; + } + + SIMD_FORCE_INLINE btQuadWord(const btScalar& x, const btScalar& y, const btScalar& z) + { + m_x = x, m_y = y, m_z = z, m_unusedW = 0.0f; } SIMD_FORCE_INLINE btQuadWord(const btScalar& x, const btScalar& y, const btScalar& z,const btScalar& w) - :m_x(x),m_y(y),m_z(z),m_unusedW(w) { + m_x = x, m_y = y, m_z = z, m_unusedW = w; } SIMD_FORCE_INLINE void setMax(const btQuadWord& other) { - if (other.m_x > m_x) - m_x = other.m_x; - - if (other.m_y > m_y) - m_y = other.m_y; - - if (other.m_z > m_z) - m_z = other.m_z; - - if (other.m_unusedW > m_unusedW) - m_unusedW = other.m_unusedW; + btSetMax(m_x, other.m_x); + btSetMax(m_y, other.m_y); + btSetMax(m_z, other.m_z); + btSetMax(m_unusedW, other.m_unusedW); } SIMD_FORCE_INLINE void setMin(const btQuadWord& other) { - if (other.m_x < m_x) - m_x = other.m_x; - - if (other.m_y < m_y) - m_y = other.m_y; - - if (other.m_z < m_z) - m_z = other.m_z; - - if (other.m_unusedW < m_unusedW) - m_unusedW = other.m_unusedW; + btSetMin(m_x, other.m_x); + btSetMin(m_y, other.m_y); + btSetMin(m_z, other.m_z); + btSetMin(m_unusedW, other.m_unusedW); } diff --git a/extern/bullet2/src/LinearMath/btQuaternion.h b/extern/bullet2/src/LinearMath/btQuaternion.h index 50334970ba6..27ab1fcd2c3 100644 --- a/extern/bullet2/src/LinearMath/btQuaternion.h +++ b/extern/bullet2/src/LinearMath/btQuaternion.h @@ -285,7 +285,7 @@ slerp(const btQuaternion& q1, const btQuaternion& q2, const btScalar& t) } SIMD_FORCE_INLINE btVector3 -quatRotate(btQuaternion& rotation, btVector3& v) +quatRotate(const btQuaternion& rotation, const btVector3& v) { btQuaternion q = rotation * v; q *= rotation.inverse(); @@ -293,7 +293,7 @@ quatRotate(btQuaternion& rotation, btVector3& v) } SIMD_FORCE_INLINE btQuaternion -shortestArcQuat(btVector3& v0,btVector3& v1) // Game Programming Gems 2.10. make sure v0,v1 are normalized +shortestArcQuat(const btVector3& v0, const btVector3& v1) // Game Programming Gems 2.10. make sure v0,v1 are normalized { btVector3 c = v0.cross(v1); btScalar d = v0.dot(v1); @@ -308,7 +308,7 @@ shortestArcQuat(btVector3& v0,btVector3& v1) // Game Programming Gems 2.10. make } SIMD_FORCE_INLINE btQuaternion -shortestArcQuatNormalize(btVector3& v0,btVector3& v1) +shortestArcQuatNormalize2(btVector3& v0,btVector3& v1) { v0.normalize(); v1.normalize(); diff --git a/extern/bullet2/src/LinearMath/btScalar.h b/extern/bullet2/src/LinearMath/btScalar.h index 01ad93e786a..85dfaf3eb83 100644 --- a/extern/bullet2/src/LinearMath/btScalar.h +++ b/extern/bullet2/src/LinearMath/btScalar.h @@ -23,20 +23,33 @@ subject to the following restrictions: #include #include + +inline int btGetVersion() +{ + return 264; +} + #ifdef WIN32 #if defined(__MINGW32__) || defined(__CYGWIN__) || (defined (_MSC_VER) && _MSC_VER < 1300) + #define SIMD_FORCE_INLINE inline #define ATTRIBUTE_ALIGNED16(a) a + #define ATTRIBUTE_ALIGNED128(a) a #else - #define BT_HAS_ALIGNED_ALOCATOR + #define BT_HAS_ALIGNED_ALLOCATOR #pragma warning(disable:4530) #pragma warning(disable:4996) #pragma warning(disable:4786) #define SIMD_FORCE_INLINE __forceinline #define ATTRIBUTE_ALIGNED16(a) __declspec(align(16)) a + #define ATTRIBUTE_ALIGNED128(a) __declspec (align(128)) a #ifdef _XBOX #define BT_USE_VMX128 + + #include + #define BT_HAVE_NATIVE_FSEL + #define btFsel(a,b,c) __fsel((a),(b),(c)) #else #define BT_USE_SSE #endif @@ -46,29 +59,61 @@ subject to the following restrictions: #define btAssert assert //btFullAssert is optional, slows down a lot #define btFullAssert(x) + + #define btLikely(_c) _c + #define btUnlikely(_c) _c + #else #if defined (__CELLOS_LV2__) #define SIMD_FORCE_INLINE inline #define ATTRIBUTE_ALIGNED16(a) a __attribute__ ((aligned (16))) + #define ATTRIBUTE_ALIGNED128(a) a __attribute__ ((aligned (128))) #ifndef assert #include #endif #define btAssert assert //btFullAssert is optional, slows down a lot #define btFullAssert(x) + + #define btLikely(_c) _c + #define btUnlikely(_c) _c + #else +#ifdef USE_LIBSPE2 + + #define SIMD_FORCE_INLINE __inline + #define ATTRIBUTE_ALIGNED16(a) a __attribute__ ((aligned (16))) + #define ATTRIBUTE_ALIGNED128(a) a __attribute__ ((aligned (128))) + #ifndef assert + #include + #endif + #define btAssert assert + //btFullAssert is optional, slows down a lot + #define btFullAssert(x) + + + #define btLikely(_c) __builtin_expect((_c), 1) + #define btUnlikely(_c) __builtin_expect((_c), 0) + + +#else //non-windows systems #define SIMD_FORCE_INLINE inline #define ATTRIBUTE_ALIGNED16(a) a + #define ATTRIBUTE_ALIGNED128(a) a #ifndef assert #include #endif #define btAssert assert //btFullAssert is optional, slows down a lot #define btFullAssert(x) + + +#endif // LIBSPE2 + #endif //__CELLOS_LV2__ #endif @@ -88,6 +133,14 @@ typedef float btScalar; #endif +#define BT_DECLARE_ALIGNED_ALLOCATOR() \ + SIMD_FORCE_INLINE void* operator new(size_t sizeInBytes) { return btAlignedAlloc(sizeInBytes,16); } \ + SIMD_FORCE_INLINE void operator delete(void* ptr) { btAlignedFree(ptr); } \ + SIMD_FORCE_INLINE void* operator new(size_t, void* ptr) { return ptr; } \ + SIMD_FORCE_INLINE void operator delete(void*, void*) { } \ + + + #if defined(BT_USE_DOUBLE_PRECISION) || defined(BT_FORCE_DOUBLE_FUNCTIONS) SIMD_FORCE_INLINE btScalar btSqrt(btScalar x) { return sqrt(x); } @@ -105,12 +158,34 @@ SIMD_FORCE_INLINE btScalar btPow(btScalar x,btScalar y) { return pow(x,y); } #else -SIMD_FORCE_INLINE btScalar btSqrt(btScalar x) { return sqrtf(x); } +SIMD_FORCE_INLINE btScalar btSqrt(btScalar y) +{ +#ifdef USE_APPROXIMATION + double x, z, tempf; + unsigned long *tfptr = ((unsigned long *)&tempf) + 1; + + tempf = y; + *tfptr = (0xbfcdd90a - *tfptr)>>1; /* estimate of 1/sqrt(y) */ + x = tempf; + z = y*btScalar(0.5); /* hoist out the “/2” */ + x = (btScalar(1.5)*x)-(x*x)*(x*z); /* iteration formula */ + x = (btScalar(1.5)*x)-(x*x)*(x*z); + x = (btScalar(1.5)*x)-(x*x)*(x*z); + x = (btScalar(1.5)*x)-(x*x)*(x*z); + x = (btScalar(1.5)*x)-(x*x)*(x*z); + return x*y; +#else + return sqrtf(y); +#endif +} SIMD_FORCE_INLINE btScalar btFabs(btScalar x) { return fabsf(x); } SIMD_FORCE_INLINE btScalar btCos(btScalar x) { return cosf(x); } SIMD_FORCE_INLINE btScalar btSin(btScalar x) { return sinf(x); } SIMD_FORCE_INLINE btScalar btTan(btScalar x) { return tanf(x); } -SIMD_FORCE_INLINE btScalar btAcos(btScalar x) { return acosf(x); } +SIMD_FORCE_INLINE btScalar btAcos(btScalar x) { + btAssert(x <= btScalar(1.)); + return acosf(x); +} SIMD_FORCE_INLINE btScalar btAsin(btScalar x) { return asinf(x); } SIMD_FORCE_INLINE btScalar btAtan(btScalar x) { return atanf(x); } SIMD_FORCE_INLINE btScalar btAtan2(btScalar x, btScalar y) { return atan2f(x, y); } @@ -159,14 +234,6 @@ SIMD_FORCE_INLINE bool btGreaterEqual (btScalar a, btScalar eps) { return (!((a) <= eps)); } -/*SIMD_FORCE_INLINE btScalar btCos(btScalar x) { return cosf(x); } -SIMD_FORCE_INLINE btScalar btSin(btScalar x) { return sinf(x); } -SIMD_FORCE_INLINE btScalar btTan(btScalar x) { return tanf(x); } -SIMD_FORCE_INLINE btScalar btAcos(btScalar x) { return acosf(x); } -SIMD_FORCE_INLINE btScalar btAsin(btScalar x) { return asinf(x); } -SIMD_FORCE_INLINE btScalar btAtan(btScalar x) { return atanf(x); } -SIMD_FORCE_INLINE btScalar btAtan2(btScalar x, btScalar y) { return atan2f(x, y); } -*/ SIMD_FORCE_INLINE int btIsNegative(btScalar x) { return x < btScalar(0.0) ? 1 : 0; @@ -177,5 +244,151 @@ SIMD_FORCE_INLINE btScalar btDegrees(btScalar x) { return x * SIMD_DEGS_PER_RAD; #define BT_DECLARE_HANDLE(name) typedef struct name##__ { int unused; } *name +#ifndef btFsel +SIMD_FORCE_INLINE btScalar btFsel(btScalar a, btScalar b, btScalar c) +{ + return a >= 0 ? b : c; +} +#endif +#define btFsels(a,b,c) (btScalar)btFsel(a,b,c) + + +SIMD_FORCE_INLINE bool btMachineIsLittleEndian() +{ + long int i = 1; + const char *p = (const char *) &i; + if (p[0] == 1) // Lowest address contains the least significant byte + return true; + else + return false; +} + + + +///btSelect avoids branches, which makes performance much better for consoles like Playstation 3 and XBox 360 +///Thanks Phil Knight. See also http://www.cellperformance.com/articles/2006/04/more_techniques_for_eliminatin_1.html +SIMD_FORCE_INLINE unsigned btSelect(unsigned condition, unsigned valueIfConditionNonZero, unsigned valueIfConditionZero) +{ + // Set testNz to 0xFFFFFFFF if condition is nonzero, 0x00000000 if condition is zero + // Rely on positive value or'ed with its negative having sign bit on + // and zero value or'ed with its negative (which is still zero) having sign bit off + // Use arithmetic shift right, shifting the sign bit through all 32 bits + unsigned testNz = (unsigned)(((int)condition | -(int)condition) >> 31); + unsigned testEqz = ~testNz; + return ((valueIfConditionNonZero & testNz) | (valueIfConditionZero & testEqz)); +} +SIMD_FORCE_INLINE int btSelect(unsigned condition, int valueIfConditionNonZero, int valueIfConditionZero) +{ + unsigned testNz = (unsigned)(((int)condition | -(int)condition) >> 31); + unsigned testEqz = ~testNz; + return ((valueIfConditionNonZero & testNz) | (valueIfConditionZero & testEqz)); +} +SIMD_FORCE_INLINE float btSelect(unsigned condition, float valueIfConditionNonZero, float valueIfConditionZero) +{ +#ifdef BT_HAVE_NATIVE_FSEL + return (float)btFsel((btScalar)condition - btScalar(1.0f), valueIfConditionNonZero, valueIfConditionZero); +#else + return (condition != 0) ? valueIfConditionNonZero : valueIfConditionZero; +#endif +} + +template SIMD_FORCE_INLINE void btSwap(T& a, T& b) +{ + T tmp = a; + a = b; + b = tmp; +} + + +//PCK: endian swapping functions +SIMD_FORCE_INLINE unsigned btSwapEndian(unsigned val) +{ + return (((val & 0xff000000) >> 24) | ((val & 0x00ff0000) >> 8) | ((val & 0x0000ff00) << 8) | ((val & 0x000000ff) << 24)); +} + +SIMD_FORCE_INLINE unsigned short btSwapEndian(unsigned short val) +{ + return (((val & 0xff00) >> 8) | ((val & 0x00ff) << 8)); +} + +SIMD_FORCE_INLINE unsigned btSwapEndian(int val) +{ + return btSwapEndian((unsigned)val); +} + +SIMD_FORCE_INLINE unsigned short btSwapEndian(short val) +{ + return btSwapEndian((unsigned short) val); +} + +///btSwapFloat uses using char pointers to swap the endianness +////btSwapFloat/btSwapDouble will NOT return a float, because the machine might 'correct' invalid floating point values +///Not all values of sign/exponent/mantissa are valid floating point numbers according to IEEE 754. +///When a floating point unit is faced with an invalid value, it may actually change the value, or worse, throw an exception. +///In most systems, running user mode code, you wouldn't get an exception, but instead the hardware/os/runtime will 'fix' the number for you. +///so instead of returning a float/double, we return integer/long long integer +SIMD_FORCE_INLINE unsigned int btSwapEndianFloat(float d) +{ + unsigned int a; + unsigned char *dst = (unsigned char *)&a; + unsigned char *src = (unsigned char *)&d; + + dst[0] = src[3]; + dst[1] = src[2]; + dst[2] = src[1]; + dst[3] = src[0]; + return a; +} + +// unswap using char pointers +SIMD_FORCE_INLINE float btUnswapEndianFloat(unsigned int a) +{ + float d; + unsigned char *src = (unsigned char *)&a; + unsigned char *dst = (unsigned char *)&d; + + dst[0] = src[3]; + dst[1] = src[2]; + dst[2] = src[1]; + dst[3] = src[0]; + + return d; +} + + +// swap using char pointers +SIMD_FORCE_INLINE void btSwapEndianDouble(double d, unsigned char* dst) +{ + unsigned char *src = (unsigned char *)&d; + + dst[0] = src[7]; + dst[1] = src[6]; + dst[2] = src[5]; + dst[3] = src[4]; + dst[4] = src[3]; + dst[5] = src[2]; + dst[6] = src[1]; + dst[7] = src[0]; + +} + +// unswap using char pointers +SIMD_FORCE_INLINE double btUnswapEndianDouble(const unsigned char *src) +{ + double d; + unsigned char *dst = (unsigned char *)&d; + + dst[0] = src[7]; + dst[1] = src[6]; + dst[2] = src[5]; + dst[3] = src[4]; + dst[4] = src[3]; + dst[5] = src[2]; + dst[6] = src[1]; + dst[7] = src[0]; + + return d; +} + #endif //SIMD___SCALAR_H diff --git a/extern/bullet2/src/LinearMath/btStackAlloc.h b/extern/bullet2/src/LinearMath/btStackAlloc.h index d219b453537..ac940cd2edd 100644 --- a/extern/bullet2/src/LinearMath/btStackAlloc.h +++ b/extern/bullet2/src/LinearMath/btStackAlloc.h @@ -21,6 +21,7 @@ Nov.2006 #define BT_STACK_ALLOC #include "btScalar.h" //for btAssert +#include "btAlignedAllocator.h" struct btBlock { @@ -39,7 +40,7 @@ public: inline void create(unsigned int size) { destroy(); - data = new unsigned char[size]; + data = (unsigned char*) btAlignedAlloc(size,16); totalsize = size; } inline void destroy() @@ -49,12 +50,20 @@ public: if(usedsize==0) { - if(!ischild) delete[] data; + if(!ischild && data) + btAlignedFree(data); + data = 0; usedsize = 0; } } + + int getAvailableMemory() const + { + return totalsize - usedsize; + } + unsigned char* allocate(unsigned int size) { const unsigned int nus(usedsize+size); @@ -68,7 +77,7 @@ public: return(0); } - inline btBlock* beginBlock() + SIMD_FORCE_INLINE btBlock* beginBlock() { btBlock* pb = (btBlock*)allocate(sizeof(btBlock)); pb->previous = current; @@ -76,7 +85,7 @@ public: current = pb; return(pb); } - inline void endBlock(btBlock* block) + SIMD_FORCE_INLINE void endBlock(btBlock* block) { btAssert(block==current); //Raise(L"Unmatched blocks"); diff --git a/extern/bullet2/src/LinearMath/btTransform.h b/extern/bullet2/src/LinearMath/btTransform.h index 2d55fec83a4..883b3a5d2b7 100644 --- a/extern/bullet2/src/LinearMath/btTransform.h +++ b/extern/bullet2/src/LinearMath/btTransform.h @@ -92,13 +92,7 @@ public: m_basis.getRotation(q); return q; } - template - void setValue(const Scalar2 *m) - { - m_basis.setValue(m); - m_origin.setValue(&m[12]); - } - + void setFromOpenGLMatrix(const btScalar *m) { diff --git a/extern/bullet2/src/LinearMath/btTransformUtil.h b/extern/bullet2/src/LinearMath/btTransformUtil.h index bc42fd166b6..d39e2e10074 100644 --- a/extern/bullet2/src/LinearMath/btTransformUtil.h +++ b/extern/bullet2/src/LinearMath/btTransformUtil.h @@ -25,7 +25,7 @@ subject to the following restrictions: #define btRecipSqrt(x) ((btScalar)(btScalar(1.0)/btSqrt(btScalar(x)))) /* reciprocal square root */ -inline btVector3 btAabbSupport(const btVector3& halfExtents,const btVector3& supportDir) +SIMD_FORCE_INLINE btVector3 btAabbSupport(const btVector3& halfExtents,const btVector3& supportDir) { return btVector3(supportDir.x() < btScalar(0.0) ? -halfExtents.x() : halfExtents.x(), supportDir.y() < btScalar(0.0) ? -halfExtents.y() : halfExtents.y(), @@ -33,7 +33,7 @@ inline btVector3 btAabbSupport(const btVector3& halfExtents,const btVector3& sup } -inline void btPlaneSpace1 (const btVector3& n, btVector3& p, btVector3& q) +SIMD_FORCE_INLINE void btPlaneSpace1 (const btVector3& n, btVector3& p, btVector3& q) { if (btFabs(n.z()) > SIMDSQRT12) { // choose p in y-z plane @@ -121,6 +121,10 @@ public: dmat.getRotation(dorn); #endif//USE_QUATERNION_DIFF + ///floating point inaccuracy can lead to w component > 1..., which breaks + + dorn.normalize(); + angle = dorn.getAngle(); axis = btVector3(dorn.x(),dorn.y(),dorn.z()); axis[3] = btScalar(0.); diff --git a/extern/bullet2/src/LinearMath/btVector3.h b/extern/bullet2/src/LinearMath/btVector3.h index 74d41ad2a19..1e331272dd8 100644 --- a/extern/bullet2/src/LinearMath/btVector3.h +++ b/extern/bullet2/src/LinearMath/btVector3.h @@ -27,6 +27,10 @@ class btVector3 : public btQuadWord { public: SIMD_FORCE_INLINE btVector3() {} + SIMD_FORCE_INLINE btVector3(const btQuadWordStorage& q) + : btQuadWord(q) + { + } SIMD_FORCE_INLINE btVector3(const btScalar& x, const btScalar& y, const btScalar& z) @@ -399,4 +403,50 @@ public: }; + +///btSwapVector3Endian swaps vector endianness, useful for network and cross-platform serialization +SIMD_FORCE_INLINE void btSwapScalarEndian(const btScalar& sourceVal, btScalar& destVal) +{ + #ifdef BT_USE_DOUBLE_PRECISION + unsigned char* dest = (unsigned char*) &destVal; + unsigned char* src = (unsigned char*) &sourceVal; + dest[0] = src[7]; + dest[1] = src[6]; + dest[2] = src[5]; + dest[3] = src[4]; + dest[4] = src[3]; + dest[5] = src[2]; + dest[6] = src[1]; + dest[7] = src[0]; +#else + unsigned char* dest = (unsigned char*) &destVal; + unsigned char* src = (unsigned char*) &sourceVal; + dest[0] = src[3]; + dest[1] = src[2]; + dest[2] = src[1]; + dest[3] = src[0]; +#endif //BT_USE_DOUBLE_PRECISION +} +///btSwapVector3Endian swaps vector endianness, useful for network and cross-platform serialization +SIMD_FORCE_INLINE void btSwapVector3Endian(const btVector3& sourceVec, btVector3& destVec) +{ + for (int i=0;i<4;i++) + { + btSwapScalarEndian(sourceVec[i],destVec[i]); + } + +} + +///btUnSwapVector3Endian swaps vector endianness, useful for network and cross-platform serialization +SIMD_FORCE_INLINE void btUnSwapVector3Endian(btVector3& vector) +{ + + btVector3 swappedVec; + for (int i=0;i<4;i++) + { + btSwapScalarEndian(vector[i],swappedVec[i]); + } + vector = swappedVec; +} + #endif //SIMD__VECTOR3_H diff --git a/extern/bullet2/src/LinearMath/ibmsdk/Makefile b/extern/bullet2/src/LinearMath/ibmsdk/Makefile new file mode 100644 index 00000000000..2ad26576241 --- /dev/null +++ b/extern/bullet2/src/LinearMath/ibmsdk/Makefile @@ -0,0 +1,30 @@ +#### Source code Dirs +VPATH = ../ + +ROOT = ../../.. + +#### Library +LIBRARY_ppu = bulletmath.a + +#### Compiler flags +CPPFLAGS = \ +-DUSE_LIBSPE2 \ +-I$(ROOT)/src \ +-I$(SDKINC) + +#### Optimization level flags +#CC_OPT_LEVEL = $(CC_OPT_LEVEL_DEBUG) +CC_OPT_LEVEL = -O3 + +##### Objects to be archived in lib + +OBJS = \ +btAlignedAllocator.o \ +btGeometryUtil.o \ +btQuickprof.o + +#### Install directories +INSTALL_DIR = $(ROOT)/lib/ibmsdk +INSTALL_FILES = $(LIBRARY_ppu) +CELL_TOP ?= /opt/ibm/cell-sdk/prototype +include $(CELL_TOP)/make.footer diff --git a/extern/bullet2/src/SConscript b/extern/bullet2/src/SConscript index 127752777c8..7697a58d81b 100644 --- a/extern/bullet2/src/SConscript +++ b/extern/bullet2/src/SConscript @@ -22,74 +22,8 @@ elif sys.platform=='darwin': cflags += ['-O2','-pipe', '-fPIC', '-funsigned-char', '-ffast-math'] linearmath_src = env.Glob("LinearMath/*.cpp") -bulletdyn_src = ["BulletDynamics/ConstraintSolver/btContactConstraint.cpp", - "BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.cpp", - "BulletDynamics/ConstraintSolver/btHingeConstraint.cpp", - "BulletDynamics/ConstraintSolver/btPoint2PointConstraint.cpp", - "BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.cpp", - "BulletDynamics/ConstraintSolver/btSolve2LinearConstraint.cpp", - "BulletDynamics/ConstraintSolver/btTypedConstraint.cpp", - "BulletDynamics/ConstraintSolver/btConeTwistConstraint.cpp", - "BulletDynamics/Dynamics/btDiscreteDynamicsWorld.cpp", - "BulletDynamics/Dynamics/btSimpleDynamicsWorld.cpp", - "BulletDynamics/Dynamics/btRigidBody.cpp", - "BulletDynamics/Dynamics/Bullet-C-Api.cpp", - "BulletDynamics/Vehicle/btRaycastVehicle.cpp", - "BulletDynamics/Vehicle/btWheelInfo.cpp"] -collision_src = ["BulletCollision/BroadphaseCollision/btAxisSweep3.cpp", - "BulletCollision/BroadphaseCollision/btBroadphaseProxy.cpp", - "BulletCollision/BroadphaseCollision/btCollisionAlgorithm.cpp", - "BulletCollision/BroadphaseCollision/btDispatcher.cpp", - "BulletCollision/BroadphaseCollision/btOverlappingPairCache.cpp", - "BulletCollision/BroadphaseCollision/btSimpleBroadphase.cpp", - "BulletCollision/CollisionDispatch/btCollisionDispatcher.cpp", - "BulletCollision/CollisionDispatch/btCollisionObject.cpp", - "BulletCollision/CollisionDispatch/btCollisionWorld.cpp", - "BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.cpp", - "BulletCollision/CollisionDispatch/btConvexConcaveCollisionAlgorithm.cpp", - "BulletCollision/CollisionDispatch/btSphereSphereCollisionAlgorithm.cpp", - "BulletCollision/CollisionDispatch/btSphereBoxCollisionAlgorithm.cpp", - "BulletCollision/CollisionDispatch/btConvexConvexAlgorithm.cpp", - "BulletCollision/CollisionDispatch/btEmptyCollisionAlgorithm.cpp", - "BulletCollision/CollisionDispatch/btManifoldResult.cpp", - "BulletCollision/CollisionDispatch/btSimulationIslandManager.cpp", - "BulletCollision/CollisionDispatch/btUnionFind.cpp", - "BulletCollision/CollisionShapes/btBoxShape.cpp", - "BulletCollision/CollisionShapes/btBvhTriangleMeshShape.cpp", - "BulletCollision/CollisionShapes/btCollisionShape.cpp", - "BulletCollision/CollisionShapes/btCompoundShape.cpp", - "BulletCollision/CollisionShapes/btConcaveShape.cpp", - "BulletCollision/CollisionShapes/btConeShape.cpp", - "BulletCollision/CollisionShapes/btConvexHullShape.cpp", - "BulletCollision/CollisionShapes/btConvexShape.cpp", - "BulletCollision/CollisionShapes/btConvexTriangleMeshShape.cpp", - "BulletCollision/CollisionShapes/btCylinderShape.cpp", - "BulletCollision/CollisionShapes/btEmptyShape.cpp", - "BulletCollision/CollisionShapes/btMinkowskiSumShape.cpp", - "BulletCollision/CollisionShapes/btMultiSphereShape.cpp", - "BulletCollision/CollisionShapes/btOptimizedBvh.cpp", - "BulletCollision/CollisionShapes/btPolyhedralConvexShape.cpp", - "BulletCollision/CollisionShapes/btTetrahedronShape.cpp", - "BulletCollision/CollisionShapes/btSphereShape.cpp", - "BulletCollision/CollisionShapes/btStaticPlaneShape.cpp", - "BulletCollision/CollisionShapes/btStridingMeshInterface.cpp", - "BulletCollision/CollisionShapes/btTriangleCallback.cpp", - "BulletCollision/CollisionShapes/btTriangleBuffer.cpp", - "BulletCollision/CollisionShapes/btTriangleIndexVertexArray.cpp", - "BulletCollision/CollisionShapes/btTriangleMesh.cpp", - "BulletCollision/CollisionShapes/btTriangleMeshShape.cpp", - "BulletCollision/CollisionShapes/btHeightfieldTerrainShape.cpp", - "BulletCollision/NarrowPhaseCollision/btContinuousConvexCollision.cpp", - "BulletCollision/NarrowPhaseCollision/btGjkEpa.cpp", - "BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.cpp", - "BulletCollision/NarrowPhaseCollision/btConvexCast.cpp", - "BulletCollision/NarrowPhaseCollision/btGjkConvexCast.cpp", - "BulletCollision/NarrowPhaseCollision/btGjkPairDetector.cpp", - "BulletCollision/NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.cpp", - "BulletCollision/NarrowPhaseCollision/btPersistentManifold.cpp", - "BulletCollision/NarrowPhaseCollision/btRaycastCallback.cpp", - "BulletCollision/NarrowPhaseCollision/btSubSimplexConvexCast.cpp", - "BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.cpp"] +bulletdyn_src = env.Glob("BulletDynamics/ConstraintSolver/*.cpp") + env.Glob("BulletDynamics/Dynamics/*.cpp") + env.Glob("BulletDynamics/Vehicle/*.cpp") +collision_src = env.Glob("BulletCollision/BroadphaseCollision/*.cpp") + env.Glob("BulletCollision/CollisionDispatch/*.cpp") + env.Glob("BulletCollision/CollisionShapes/*.cpp") + env.Glob("BulletCollision/NarrowPhaseCollision/*.cpp") incs = '. BulletCollision BulletDynamics LinearMath' diff --git a/extern/bullet2/src/btBulletCollisionCommon.h b/extern/bullet2/src/btBulletCollisionCommon.h index 8417ccc671f..a309f7d76d2 100644 --- a/extern/bullet2/src/btBulletCollisionCommon.h +++ b/extern/bullet2/src/btBulletCollisionCommon.h @@ -32,17 +32,19 @@ subject to the following restrictions: #include "BulletCollision/CollisionShapes/btConvexHullShape.h" #include "BulletCollision/CollisionShapes/btTriangleMesh.h" #include "BulletCollision/CollisionShapes/btConvexTriangleMeshShape.h" +#include "BulletCollision/CollisionShapes/btBvhTriangleMeshShape.h" #include "BulletCollision/CollisionShapes/btTriangleMeshShape.h" #include "BulletCollision/CollisionShapes/btTriangleIndexVertexArray.h" #include "BulletCollision/CollisionShapes/btCompoundShape.h" #include "BulletCollision/CollisionShapes/btTetrahedronShape.h" #include "BulletCollision/CollisionShapes/btEmptyShape.h" -#include "BulletCollision/CollisionShapes/btBvhTriangleMeshShape.h" #include "BulletCollision/CollisionShapes/btMultiSphereShape.h" +#include "BulletCollision/CollisionShapes/btUniformScalingShape.h" ///Narrowphase Collision Detector #include "BulletCollision/CollisionDispatch/btSphereSphereCollisionAlgorithm.h" #include "BulletCollision/CollisionDispatch/btSphereBoxCollisionAlgorithm.h" +#include "BulletCollision/CollisionDispatch/btDefaultCollisionConfiguration.h" ///Dispatching and generation of collision pairs (broadphase) #include "BulletCollision/CollisionDispatch/btCollisionDispatcher.h" diff --git a/extern/bullet2/src/btBulletDynamicsCommon.h b/extern/bullet2/src/btBulletDynamicsCommon.h index 25f016cba8a..5d08dac0c0d 100644 --- a/extern/bullet2/src/btBulletDynamicsCommon.h +++ b/extern/bullet2/src/btBulletDynamicsCommon.h @@ -20,6 +20,8 @@ subject to the following restrictions: #include "btBulletCollisionCommon.h" #include "BulletDynamics/Dynamics/btDiscreteDynamicsWorld.h" +#include "BulletDynamics/Dynamics/btContinuousDynamicsWorld.h" + #include "BulletDynamics/Dynamics/btSimpleDynamicsWorld.h" #include "BulletDynamics/Dynamics/btRigidBody.h" diff --git a/extern/bullet2/src/ibmsdk/Makefile b/extern/bullet2/src/ibmsdk/Makefile new file mode 100644 index 00000000000..768fffd35a4 --- /dev/null +++ b/extern/bullet2/src/ibmsdk/Makefile @@ -0,0 +1,10 @@ +#### Visit Bullet library ibmsdk dirs and build code +CELL_TOP ?= /opt/ibm/cell-sdk/prototype + +DIRS := \ +../BulletCollision/ibmsdk \ +../BulletDynamics/ibmsdk \ +../LinearMath/ibmsdk + + +include $(CELL_TOP)/make.footer From e14457b921060b73491a306aee012e468116710c Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Tue, 6 Nov 2007 14:27:06 +0000 Subject: [PATCH 049/246] updated bullet to version 2.64 and hopefully didn't break too much things in CcdPhysicsEnvironment.cpp, but it compiles and works for me --- source/blender/blenkernel/intern/cloth.c | 2 +- source/blender/blenkernel/intern/implicit.c | 55 ++----------------- .../Converter/KX_BlenderSceneConverter.cpp | 2 +- .../Physics/Bullet/CcdPhysicsEnvironment.cpp | 29 +++++----- .../Physics/Bullet/CcdPhysicsEnvironment.h | 2 +- 5 files changed, 21 insertions(+), 69 deletions(-) diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c index 9720ec6b141..3b065fc16f5 100644 --- a/source/blender/blenkernel/intern/cloth.c +++ b/source/blender/blenkernel/intern/cloth.c @@ -171,7 +171,7 @@ void cloth_init (ClothModifierData *clmd) // also from softbodies clmd->sim_parms.maxgoal = 1.0; clmd->sim_parms.mingoal = 0.0; - clmd->sim_parms.defgoal = 0.7; + clmd->sim_parms.defgoal = 0.0; clmd->sim_parms.goalspring = 100.0; clmd->sim_parms.goalfrict = 0.0; diff --git a/source/blender/blenkernel/intern/implicit.c b/source/blender/blenkernel/intern/implicit.c index 41cc9e8cef4..a72887d7eb9 100644 --- a/source/blender/blenkernel/intern/implicit.c +++ b/source/blender/blenkernel/intern/implicit.c @@ -2165,55 +2165,6 @@ void collisions_collision_moving_tris(ClothModifierData *clmd, ClothModifierData */ } - -// move collision objects forward in time and update static bounding boxes -void collisions_update_collision_objects(float step) -{ - Base *base=NULL; - ClothModifierData *coll_clmd=NULL; - Object *coll_ob=NULL; - unsigned int i=0; - /* - // search all objects for collision object - for (base = G.scene->base.first; base; base = base->next) - { - - coll_ob = base->object; - coll_clmd = (ClothModifierData *) modifiers_findByType (coll_ob, eModifierType_Cloth); - if (!coll_clmd) - continue; - - // if collision object go on - if (coll_clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_COLLOBJ) - { - if (coll_clmd->clothObject && coll_clmd->clothObject->tree) - { - Cloth *coll_cloth = coll_clmd->clothObject; - BVH *coll_bvh = coll_clmd->clothObject->tree; - unsigned int coll_numverts = coll_cloth->numverts; - - // update position of collision object - for(i = 0; i < coll_numverts; i++) - { - VECCOPY(coll_cloth->verts[i].txold, coll_cloth->verts[i].tx); - - VECADDS(coll_cloth->verts[i].tx, coll_cloth->verts[i].xold, coll_cloth->verts[i].v, step); - - // no dt here because of float rounding errors - VECSUB(coll_cloth->verts[i].tv, coll_cloth->verts[i].tx, coll_cloth->verts[i].txold); - } - - // update BVH of collision object - // bvh_update(coll_clmd, coll_bvh, 0); // 0 means STATIC, 1 means MOVING - } - else - printf ("collisions_bvh_objcollision: found a collision object with clothObject or collData NULL.\n"); - } - } - */ -} - - void collisions_collision_moving(ClothModifierData *clmd, ClothModifierData *coll_clmd, CollisionTree *tree1, CollisionTree *tree2) { /* @@ -2251,7 +2202,7 @@ int cloth_bvh_objcollision(ClothModifierData * clmd, float step, float prevstep, //////////////////////////////////////////////////////////// // static collisions //////////////////////////////////////////////////////////// - /* + // update cloth bvh bvh_update_from_float3(bvh1, cloth->current_xold, cloth->numverts, cloth->current_x, 0); // 0 means STATIC, 1 means MOVING (see later in this function) @@ -2276,6 +2227,8 @@ int cloth_bvh_objcollision(ClothModifierData * clmd, float step, float prevstep, // fill collision list collisions += bvh_traverse(bvh1->root, bvh2->root, &collision_list); + // call static collision response + // free collision list if(collision_list) { @@ -2303,7 +2256,7 @@ int cloth_bvh_objcollision(ClothModifierData * clmd, float step, float prevstep, VECADD(cloth->current_x[i], cloth->current_xold[i], cloth->current_v[i]); } ////////////////////////////////////////////// - */ + // Test on *simple* selfcollisions collisions = 1; count = 0; diff --git a/source/gameengine/Converter/KX_BlenderSceneConverter.cpp b/source/gameengine/Converter/KX_BlenderSceneConverter.cpp index 47d8f186653..01289113bf1 100644 --- a/source/gameengine/Converter/KX_BlenderSceneConverter.cpp +++ b/source/gameengine/Converter/KX_BlenderSceneConverter.cpp @@ -307,7 +307,7 @@ void KX_BlenderSceneConverter::ConvertScene(const STR_String& scenename, case UseBullet: { CcdPhysicsEnvironment* ccdPhysEnv = new CcdPhysicsEnvironment(); - ccdPhysEnv->setDebugDrawer(new BlenderDebugDraw()); + // ccdPhysEnv->setDebugDrawer(new BlenderDebugDraw()); ccdPhysEnv->setDeactivationLinearTreshold(0.8f); // default, can be overridden by Python ccdPhysEnv->setDeactivationAngularTreshold(1.0f); // default, can be overridden by Python diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp b/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp index 99c3e5f77c7..db82dde9663 100644 --- a/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp +++ b/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp @@ -295,7 +295,7 @@ static void DrawAabb(btIDebugDraw* debugDrawer,const btVector3& from,const btVec -CcdPhysicsEnvironment::CcdPhysicsEnvironment(btDispatcher* dispatcher,btOverlappingPairCache* pairCache) +CcdPhysicsEnvironment::CcdPhysicsEnvironment(btDispatcher* dispatcher,btBroadphaseInterface* broadphase) :m_scalingPropagated(false), m_numIterations(10), m_numTimeSubSteps(1), @@ -303,32 +303,31 @@ m_ccdMode(0), m_solverType(-1), m_profileTimings(0), m_enableSatCollisionDetection(false) -{ - +{ for (int i=0;isetGravity(m_gravity); @@ -620,7 +619,7 @@ int CcdPhysicsEnvironment::createUniversalD6Constraint( genericConstraint = new btGeneric6DofConstraint( *rb0,*rb1, - frameInA,frameInB); + frameInA,frameInB, 1); genericConstraint->setLinearLowerLimit(linearMinLimits); genericConstraint->setLinearUpperLimit(linearMaxLimits); genericConstraint->setAngularLowerLimit(angularMinLimits); @@ -687,8 +686,8 @@ struct FilterClosestRayResultCallback : public btCollisionWorld::ClosestRayResul //ignore client... if (curHit != m_ignoreClient) { - //if valid - return ClosestRayResultCallback::AddSingleResult(rayResult); + //if valid; also return normal in world space + return ClosestRayResultCallback::AddSingleResult(rayResult, 1); } return m_closestHitFraction; } @@ -805,7 +804,7 @@ void CcdPhysicsEnvironment::setConstraintParam(int constraintId,int param,float { //param = 1..12, min0,max0,min1,max1...min6,max6 btGeneric6DofConstraint* genCons = (btGeneric6DofConstraint*)typedConstraint; - genCons->SetLimit(param,value0,value1); + genCons->setLimit(param,value0,value1); break; }; default: @@ -1099,7 +1098,7 @@ int CcdPhysicsEnvironment::createConstraint(class PHY_IPhysicsController* ctrl genericConstraint = new btGeneric6DofConstraint( *rb0,*rb1, - frameInA,frameInB); + frameInA,frameInB, 1); } else @@ -1122,7 +1121,7 @@ int CcdPhysicsEnvironment::createConstraint(class PHY_IPhysicsController* ctrl genericConstraint = new btGeneric6DofConstraint( *rb0,s_fixedObject2, - frameInA,frameInB); + frameInA,frameInB, 1); } if (genericConstraint) diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.h b/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.h index 66a6ed59c17..8d2b961db85 100644 --- a/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.h +++ b/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.h @@ -71,7 +71,7 @@ protected: public: - CcdPhysicsEnvironment(btDispatcher* dispatcher=0, btOverlappingPairCache* pairCache=0); + CcdPhysicsEnvironment(btDispatcher* dispatcher=0, btBroadphaseInterface* broadphase=0); virtual ~CcdPhysicsEnvironment(); From d4e881761dc3e7649f62d92a96648c2f2b69925d Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Thu, 8 Nov 2007 03:31:52 +0000 Subject: [PATCH 050/246] Introduced a selfmade AIMEX (adaptive implicit-explicit condition into force calculation for jacobi matrices -->results in ca. 15% speedup --- source/blender/blenkernel/intern/implicit.c | 73 ++++++++++--------- source/blender/blenkernel/intern/kdop.c | 4 +- source/blender/blenkernel/intern/pointcache.c | 2 +- source/blender/src/buttons_object.c | 2 +- 4 files changed, 44 insertions(+), 37 deletions(-) diff --git a/source/blender/blenkernel/intern/implicit.c b/source/blender/blenkernel/intern/implicit.c index a72887d7eb9..ee8a440735a 100644 --- a/source/blender/blenkernel/intern/implicit.c +++ b/source/blender/blenkernel/intern/implicit.c @@ -691,7 +691,7 @@ static float I[3][3] = {{1,0,0},{0,1,0},{0,0,1}}; static float ZERO[3][3] = {{0,0,0}, {0,0,0}, {0,0,0}}; typedef struct Implicit_Data { - lfVector *X, *V, *Xnew, *Vnew, *olddV, *F, *B, *dV, *z; + lfVector *X, *V, *Xnew, *Vnew, *F, *B, *dV, *z; fmatrix3x3 *A, *dFdV, *dFdX, *S, *P, *Pinv, *bigI; } Implicit_Data; @@ -727,11 +727,10 @@ int implicit_init (Object *ob, ClothModifierData *clmd) id->Xnew = create_lfvector(cloth->numverts); id->V = create_lfvector(cloth->numverts); id->Vnew = create_lfvector(cloth->numverts); - id->olddV = create_lfvector(cloth->numverts); - zero_lfvector(id->olddV, cloth->numverts); id->F = create_lfvector(cloth->numverts); id->B = create_lfvector(cloth->numverts); id->dV = create_lfvector(cloth->numverts); + zero_lfvector(id->dV, cloth->numverts); id->z = create_lfvector(cloth->numverts); for(i=0;inumverts;i++) @@ -799,7 +798,6 @@ int implicit_free (ClothModifierData *clmd) del_lfvector(id->Xnew); del_lfvector(id->V); del_lfvector(id->Vnew); - del_lfvector(id->olddV); del_lfvector(id->F); del_lfvector(id->B); del_lfvector(id->dV); @@ -924,8 +922,6 @@ int cg_filtered(lfVector *ldV, fmatrix3x3 *lA, lfVector *lB, lfVector *z, fmatr d = create_lfvector(numverts); tmp = create_lfvector(numverts); r = create_lfvector(numverts); - - // zero_lfvector(ldV, CLOTHPARTICLES); filter(ldV, S); add_lfvector_lfvector(ldV, ldV, z, numverts); @@ -1174,7 +1170,7 @@ DO_INLINE void dfdx_damp(float to[3][3], float dir[3],float length,const float } -DO_INLINE void cloth_calc_spring_force(ClothModifierData *clmd, ClothSpring *s, lfVector *lF, lfVector *X, lfVector *V, fmatrix3x3 *dFdV, fmatrix3x3 *dFdX) +DO_INLINE void cloth_calc_spring_force(ClothModifierData *clmd, ClothSpring *s, lfVector *lF, lfVector *X, lfVector *V, fmatrix3x3 *dFdV, fmatrix3x3 *dFdX, float dt) { float extent[3]; float length = 0; @@ -1229,19 +1225,23 @@ DO_INLINE void cloth_calc_spring_force(ClothModifierData *clmd, ClothSpring *s, { s->flags |= CLOTH_SPRING_FLAG_NEEDED; - k = clmd->sim_parms.structural; + k = (clmd->sim_parms.structural*(length-L)); - mul_fvector_S(stretch_force, dir, (k*(length-L))); + mul_fvector_S(stretch_force, dir, k); VECADD(s->f, s->f, stretch_force); // Ascher & Boxman, p.21: Damping only during elonglation - mul_fvector_S(damping_force, extent, clmd->sim_parms.Cdis * ((INPR(vel,extent)/length))); + mul_fvector_S(damping_force, extent, clmd->sim_parms.Cdis * 0.01 * ((INPR(vel,extent)/length))); VECADD(s->f, s->f, damping_force); - - dfdx_spring_type1(s->dfdx, dir,length,L,k); - - dfdv_damp(s->dfdv, dir,clmd->sim_parms.Cdis); + + // Formula from Ascher / Boxman, Speeding up cloth simulation + if((dt * (k*dt + 2 * clmd->sim_parms.Cdis * 0.01)) > 0.01 ) + { + dfdx_spring_type1(s->dfdx, dir,length,L,clmd->sim_parms.structural); + dfdv_damp(s->dfdv, dir,clmd->sim_parms.Cdis * 0.01); + } + // printf("(dt*k*dt) ): %f, k: %f\n", (dt * (k*dt + 2 * clmd->sim_parms.Cdis * 0.01) ), k); } } else // calculate force of bending springs @@ -1252,17 +1252,19 @@ DO_INLINE void cloth_calc_spring_force(ClothModifierData *clmd, ClothSpring *s, s->flags |= CLOTH_SPRING_FLAG_NEEDED; - k = clmd->sim_parms.bending; + k = fbstar(length, L, clmd->sim_parms.bending, cb); - mul_fvector_S(bending_force, dir, fbstar(length, L, k, cb)); + mul_fvector_S(bending_force, dir, k); VECADD(s->f, s->f, bending_force); - if(INPR(bending_force,bending_force) > 0.13*0.13) + // DG: My formula to handle bending for the AIMEX scheme + // multiply with 1000 because of numerical problems + if( ((k*1000)*dt*dt) < -0.18 ) { + dfdx_spring_type2(s->dfdx, dir,length,L,clmd->sim_parms.bending, cb); clmd->sim_parms.flags |= CLOTH_SIMSETTINGS_FLAG_BIG_FORCE; } - - dfdx_spring_type2(s->dfdx, dir,length,L,k, cb); + // printf("(dt*k*dt) ): %f, k: %f\n", (dt*dt*k*-1.0), k); } } } @@ -1333,7 +1335,7 @@ DO_INLINE void calc_triangle_force(ClothModifierData *clmd, MFace mface, lfVecto } -void cloth_calc_force(ClothModifierData *clmd, lfVector *lF, lfVector *lX, lfVector *lV, fmatrix3x3 *dFdV, fmatrix3x3 *dFdX, ListBase *effectors, float time) +void cloth_calc_force(ClothModifierData *clmd, lfVector *lF, lfVector *lX, lfVector *lV, fmatrix3x3 *dFdV, fmatrix3x3 *dFdX, ListBase *effectors, float time, float dt) { /* Collect forces and derivatives: F,dFdX,dFdV */ Cloth *cloth = clmd->clothObject; @@ -1417,7 +1419,7 @@ void cloth_calc_force(ClothModifierData *clmd, lfVector *lF, lfVector *lX, lfVec { // only handle active springs // if(((clmd->sim_parms.flags & CSIMSETT_FLAG_TEARING_ENABLED) && !(springs[i].flags & CSPRING_FLAG_DEACTIVATE))|| !(clmd->sim_parms.flags & CSIMSETT_FLAG_TEARING_ENABLED)){} - cloth_calc_spring_force(clmd, search->link, lF, lX, lV, dFdV, dFdX); + cloth_calc_spring_force(clmd, search->link, lF, lX, lV, dFdV, dFdX, dt); search = search->next; } @@ -1452,13 +1454,13 @@ void cloth_calc_force(ClothModifierData *clmd, lfVector *lF, lfVector *lX, lfVec } -void simulate_implicit_euler(lfVector *Vnew, lfVector *lX, lfVector *lV, lfVector *lF, fmatrix3x3 *dFdV, fmatrix3x3 *dFdX, float dt, fmatrix3x3 *A, lfVector *B, lfVector *dV, fmatrix3x3 *S, lfVector *z, lfVector *olddV, fmatrix3x3 *P, fmatrix3x3 *Pinv) +void simulate_implicit_euler(lfVector *Vnew, lfVector *lX, lfVector *lV, lfVector *lF, fmatrix3x3 *dFdV, fmatrix3x3 *dFdX, float dt, fmatrix3x3 *A, lfVector *B, lfVector *dV, fmatrix3x3 *S, lfVector *z, fmatrix3x3 *P, fmatrix3x3 *Pinv) { unsigned int numverts = dFdV[0].vcount; lfVector *dFdXmV = create_lfvector(numverts); initdiag_bfmatrix(A, I); - zero_lfvector(dV, numverts); + // zero_lfvector(dV, numverts); subadd_bfmatrixS_bfmatrixS(A, dFdV, dt, dFdX, (dt*dt)); @@ -1469,17 +1471,16 @@ void simulate_implicit_euler(lfVector *Vnew, lfVector *lX, lfVector *lV, lfVecto itstart(); cg_filtered(dV, A, B, z, S); /* conjugate gradient algorithm to solve Ax=b */ - // cg_filtered_pre(dV, A, B, z, olddV, P, Pinv, dt); + // cg_filtered_pre(dV, A, B, z, dV, P, Pinv, dt); itend(); // printf("cg_filtered calc time: %f\n", (float)itval()); - cp_lfvector(olddV, dV, numverts); + // advance velocities add_lfvector_lfvector(Vnew, lV, dV, numverts); - del_lfvector(dFdXmV); } @@ -1514,12 +1515,12 @@ int implicit_solver (Object *ob, float frame, ClothModifierData *clmd, ListBase effectors= pdInitEffectors(ob,NULL); // calculate - cloth_calc_force(clmd, id->F, id->X, id->V, id->dFdV, id->dFdX, effectors, step ); + cloth_calc_force(clmd, id->F, id->X, id->V, id->dFdV, id->dFdX, effectors, step, dt ); // check for sleeping if(!(clmd->coll_parms.flags & CLOTH_SIMSETTINGS_FLAG_SLEEP)) { - simulate_implicit_euler(id->Vnew, id->X, id->V, id->F, id->dFdV, id->dFdX, dt, id->A, id->B, id->dV, id->S, id->z, id->olddV, id->P, id->Pinv); + simulate_implicit_euler(id->Vnew, id->X, id->V, id->F, id->dFdV, id->dFdX, dt, id->A, id->B, id->dV, id->S, id->z, id->P, id->Pinv); add_lfvector_lfvectorS(id->Xnew, id->X, id->Vnew, dt, numverts); } @@ -1592,8 +1593,8 @@ int implicit_solver (Object *ob, float frame, ClothModifierData *clmd, ListBase cp_lfvector(id->V, id->Vnew, numverts); // calculate - cloth_calc_force(clmd, id->F, id->X, id->V, id->dFdV, id->dFdX, effectors, step); - simulate_implicit_euler(id->Vnew, id->X, id->V, id->F, id->dFdV, id->dFdX, dt / 2.0f, id->A, id->B, id->dV, id->S, id->z, id->olddV, id->P, id->Pinv); + cloth_calc_force(clmd, id->F, id->X, id->V, id->dFdV, id->dFdX, effectors, step, dt); + simulate_implicit_euler(id->Vnew, id->X, id->V, id->F, id->dFdV, id->dFdX, dt / 2.0f, id->A, id->B, id->dV, id->S, id->z, id->P, id->Pinv); } } @@ -1781,7 +1782,7 @@ int collisions_collision_response_moving_edges(ClothModifierData *clmd, ClothMod return 0; } -void cloth_collision_static(ClothModifierData *clmd, ClothModifierData *coll_clmd, CollisionTree *tree1, CollisionTree *tree2) +void cloth_collision_static(ClothModifierData *clmd, LinkNode *collision_list) { /* CollPair *collpair = NULL; @@ -1794,7 +1795,7 @@ void cloth_collision_static(ClothModifierData *clmd, ClothModifierData *coll_clm for(i = 0; i < 4; i++) { - collpair = (CollPair *)MEM_callocN(sizeof(CollPair), "cloth coll pair"); + collpair = (CollPair *)MEM_callocN(sizeof(CollPair), "cloth coll pair"); cloth1 = clmd->clothObject; cloth2 = coll_clmd->clothObject; @@ -1865,8 +1866,7 @@ void cloth_collision_static(ClothModifierData *clmd, ClothModifierData *coll_clm else i++; } - - // calc SIPcode (?) + if(i < 4) { @@ -2320,6 +2320,11 @@ int cloth_bvh_objcollision(ClothModifierData * clmd, float step, float prevstep, } } } + /* + // does not compile with OpenMP + if(!collisions) + break; + */ } ////////////////////////////////////////////// diff --git a/source/blender/blenkernel/intern/kdop.c b/source/blender/blenkernel/intern/kdop.c index f39d5465b87..e168d3a9954 100644 --- a/source/blender/blenkernel/intern/kdop.c +++ b/source/blender/blenkernel/intern/kdop.c @@ -802,7 +802,9 @@ int bvh_traverse(CollisionTree *tree1, CollisionTree *tree2, LinkNode **collisio VECCOPY(collpair->point_indexB, tree2->point_index); collpair->point_indexB[3] = tree2->point_index[3]; - BLI_linklist_append(&collision_list[0], collpair); + // we use prepend because lots of insertions at end + // of list are horrible slow! + BLI_linklist_prepend(&collision_list[0], collpair); return 1; } diff --git a/source/blender/blenkernel/intern/pointcache.c b/source/blender/blenkernel/intern/pointcache.c index b87a43c30c3..b9e6cd53f8d 100644 --- a/source/blender/blenkernel/intern/pointcache.c +++ b/source/blender/blenkernel/intern/pointcache.c @@ -104,7 +104,7 @@ FILE *PTCache_id_fopen(struct ID *id, char mode, int cfra, int stack_index) if (mode=='r') { if (!BLI_exists(filename)) { - printf("Error, file does not exist '%s'\n", filename); + // printf("Error, file does not exist '%s'\n", filename); return NULL; } fp = fopen(filename, "rb"); diff --git a/source/blender/src/buttons_object.c b/source/blender/src/buttons_object.c index 70559d29f40..2d5b54ac1c2 100644 --- a/source/blender/src/buttons_object.c +++ b/source/blender/src/buttons_object.c @@ -3176,7 +3176,7 @@ static void object_panel_cloth(Object *ob) uiBlockBeginAlign(block); uiDefButF(block, NUM, B_CLOTH_RENEW, "StructStiff:", 10,170,150,20, &clmd->sim_parms.structural, 1.0, 10000.0, 100, 0, "Overall stiffness of structure"); uiDefButF(block, NUM, B_CLOTH_RENEW, "BendStiff:", 160,170,150,20, &clmd->sim_parms.bending, 0.0, 10000.0, 1000, 0, "Wrinkle possibility"); - uiDefButI(block, NUM, B_CLOTH_RENEW, "Quality:", 10,150,150,20, &clmd->sim_parms.stepsPerFrame, 1.0, 100.0, 5, 0, "Quality of the simulation (higher=>better=>slower)"); + uiDefButI(block, NUM, B_CLOTH_RENEW, "Quality:", 10,150,150,20, &clmd->sim_parms.stepsPerFrame, 3.0, 10.0, 5, 0, "Quality of the simulation (higher=>better=>slower)"); uiBlockEndAlign(block); uiBlockBeginAlign(block); uiDefButF(block, NUM, B_CLOTH_RENEW, "Spring Damp:", 160,150,150,20, &clmd->sim_parms.Cdis, 0.0, 10.0, 10, 0, "Spring damping"); From 057060967e07b052c70010b4c6d7d38dd03f6925 Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Fri, 16 Nov 2007 14:24:43 +0000 Subject: [PATCH 051/246] Fixed DNA issue, some optional SSE stuff in (experimental, only 2 functions => not likely to be ever in trunk), BE AWARE: not compatible with old cloth files, many fixes in general, deactivated selfcollisions due to WIP --- source/blender/blenkernel/BKE_cloth.h | 57 +- source/blender/blenkernel/BKE_collisions.h | 5 + source/blender/blenkernel/intern/cloth.c | 130 ++- source/blender/blenkernel/intern/implicit.c | 933 ++++++++++++------- source/blender/blenkernel/intern/kdop.c | 141 ++- source/blender/blenkernel/intern/modifier.c | 16 +- source/blender/blenloader/intern/readfile.c | 11 +- source/blender/blenloader/intern/writefile.c | 42 +- source/blender/makesdna/DNA_cloth_types.h | 91 +- source/blender/makesdna/DNA_modifier_types.h | 10 +- source/blender/src/buttons_object.c | 96 +- 11 files changed, 910 insertions(+), 622 deletions(-) diff --git a/source/blender/blenkernel/BKE_cloth.h b/source/blender/blenkernel/BKE_cloth.h index 83891cc74d3..f3f566d2832 100644 --- a/source/blender/blenkernel/BKE_cloth.h +++ b/source/blender/blenkernel/BKE_cloth.h @@ -57,6 +57,49 @@ struct DerivedMesh; #define CLOTH_MAX_THREAD 2 +typedef struct ClothVertex { + int flags; /* General flags per vertex. */ + float mass; /* mass / weight of the vertex */ + float goal; /* goal, from SB */ + float impulse[3]; /* used in collision.c */ + unsigned int impulse_count; /* same as above */ +} ClothVertex; + +typedef struct ClothSpring { + int ij; /* Pij from the paper, one end of the spring. */ + int kl; /* Pkl from the paper, one end of the spring. */ + float restlen; /* The original length of the spring. */ + int matrix_index; /* needed for implicit solver (fast lookup) */ + int type; /* types defined in BKE_cloth.h ("springType") */ + int flags; /* defined in BKE_cloth.h, e.g. deactivated due to tearing */ + float dfdx[3][4]; + float dfdv[3][4]; + float f[3]; +} ClothSpring; + +typedef struct Cloth { + struct ClothVertex *verts; /* The vertices that represent this cloth. */ + struct LinkNode *springs; /* The springs connecting the mesh. */ + struct BVH *tree; /* collision tree for this cloth object */ + struct BVH *selftree; /* self collision tree for this cloth object */ + struct MFace *mfaces; + struct Implicit_Data *implicit; /* our implicit solver connects to this pointer */ + struct EdgeHash *edgehash; /* used for fast checking adjacent points */ + unsigned int numverts; /* The number of verts == m * n. */ + unsigned int numsprings; /* The count of springs. */ + unsigned int numfaces; + unsigned int numothersprings; + unsigned int numspringssave; + unsigned int old_solver_type; + float (*x)[4]; /* The current position of all vertices.*/ + float (*xold)[4]; /* The previous position of all vertices.*/ + float (*current_x)[4]; /* The TEMPORARY current position of all vertices.*/ + float (*current_xold)[4]; /* The TEMPORARY previous position of all vertices.*/ + float (*v)[4]; /* the current velocity of all vertices */ + float (*current_v)[4]; + float (*xconst)[4]; +} Cloth; + /* goal defines */ #define SOFTGOALSNAP 0.999f @@ -138,7 +181,6 @@ int cloth_bvh_objcollision(ClothModifierData * clmd, float step, float prevstep, //////////////////////////////////////////////// void cloth_free_modifier ( ClothModifierData *clmd ); void cloth_init ( ClothModifierData *clmd ); -void cloth_update_normals ( ClothVertex *verts, int nVerts, MFace *face, int totface ); //////////////////////////////////////////////// @@ -178,19 +220,6 @@ int verlet_init ( Object *ob, ClothModifierData *clmd ); int verlet_free ( ClothModifierData *clmd ); int verlet_solver ( Object *ob, float frame, ClothModifierData *clmd, ListBase *effectors ); -/* used for caching in implicit.c */ -typedef struct Frame -{ - ClothVertex *verts; - ClothSpring *springs; - unsigned int numverts, numsprings; - float time; /* we need float since we want to support sub-frames */ - float (*x)[3]; - float (*xold)[3]; - float (*v)[3]; - float (*current_xold)[3]; -} -Frame; /* used for collisions in collision.c */ /* diff --git a/source/blender/blenkernel/BKE_collisions.h b/source/blender/blenkernel/BKE_collisions.h index fa5956c5bec..f358bd629e6 100644 --- a/source/blender/blenkernel/BKE_collisions.h +++ b/source/blender/blenkernel/BKE_collisions.h @@ -73,6 +73,7 @@ typedef struct BVH CollisionTree *leaf_root; /* Head of the leaf linked list. */ float epsilon; /* epslion is used for inflation of the k-dop */ int flags; /* bvhFlags */ + } BVH; @@ -80,6 +81,8 @@ BVH; typedef struct CollisionPair { int point_indexA[4], point_indexB[4]; + float vector[3]; + float pa[3], pb[3]; } CollisionPair; @@ -93,6 +96,7 @@ CollisionPair; // builds bounding volume hierarchy BVH *bvh_build_from_mvert (MFace *mfaces, unsigned int numfaces, MVert *x, unsigned int numverts, float epsilon); BVH *bvh_build_from_float3 (MFace *mfaces, unsigned int numfaces, float (*x)[3], unsigned int numverts, float epsilon); +BVH *bvh_build_from_float4 (MFace *mfaces, unsigned int numfaces, float (*x)[4], unsigned int numverts, float epsilon); // frees the same void bvh_free ( BVH *bvh ); @@ -103,6 +107,7 @@ int bvh_traverse(CollisionTree *tree1, CollisionTree *tree2, LinkNode **collisio // update bounding volumes, needs updated positions in bvh->x void bvh_update_from_mvert(BVH * bvh, MVert *x, unsigned int numverts, MVert *xnew, int moving); void bvh_update_from_float3(BVH * bvh, float (*x)[3], unsigned int numverts, float (*xnew)[3], int moving); +void bvh_update_from_float4(BVH * bvh, float (*x)[4], unsigned int numverts, float (*xnew)[4], int moving); LinkNode *BLI_linklist_append_fast (LinkNode **listp, void *ptr); diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c index 3b065fc16f5..ea3c8dec0c0 100644 --- a/source/blender/blenkernel/intern/cloth.c +++ b/source/blender/blenkernel/intern/cloth.c @@ -141,41 +141,39 @@ static void cloth_apply_vgroup(ClothModifierData *clmd, DerivedMesh *dm, short v void cloth_init (ClothModifierData *clmd) { /* Initialize our new data structure to reasonable values. */ - clmd->sim_parms.gravity [0] = 0.0; - clmd->sim_parms.gravity [1] = 0.0; - clmd->sim_parms.gravity [2] = -9.81; - clmd->sim_parms.structural = 100.0; - clmd->sim_parms.shear = 100.0; - clmd->sim_parms.bending = 1.0; - clmd->sim_parms.Cdis = 5.0; - clmd->sim_parms.Cvi = 1.0; - clmd->sim_parms.mass = 1.0f; - clmd->sim_parms.stepsPerFrame = 5; - clmd->sim_parms.sim_time = 1.0; - clmd->sim_parms.flags = CLOTH_SIMSETTINGS_FLAG_RESET; - clmd->sim_parms.solver_type = 0; - clmd->sim_parms.preroll = 0; - clmd->sim_parms.maxspringlen = 10; - clmd->coll_parms.self_friction = 5.0; - clmd->coll_parms.friction = 10.0; - clmd->coll_parms.loop_count = 1; - clmd->coll_parms.epsilon = 0.01; - clmd->coll_parms.selfepsilon = 0.1; + clmd->sim_parms->gravity [0] = 0.0; + clmd->sim_parms->gravity [1] = 0.0; + clmd->sim_parms->gravity [2] = -9.81; + clmd->sim_parms->structural = 100.0; + clmd->sim_parms->shear = 100.0; + clmd->sim_parms->bending = 1.0; + clmd->sim_parms->Cdis = 5.0; + clmd->sim_parms->Cvi = 1.0; + clmd->sim_parms->mass = 1.0f; + clmd->sim_parms->stepsPerFrame = 5; + clmd->sim_parms->sim_time = 1.0; + clmd->sim_parms->flags = CLOTH_SIMSETTINGS_FLAG_RESET; + clmd->sim_parms->solver_type = 0; + clmd->sim_parms->preroll = 0; + clmd->sim_parms->maxspringlen = 10; + clmd->coll_parms->self_friction = 5.0; + clmd->coll_parms->friction = 10.0; + clmd->coll_parms->loop_count = 1; + clmd->coll_parms->epsilon = 0.01; + clmd->coll_parms->selfepsilon = 0.1; /* These defaults are copied from softbody.c's * softbody_calc_forces() function. */ - clmd->sim_parms.eff_force_scale = 1000.0; - clmd->sim_parms.eff_wind_scale = 250.0; + clmd->sim_parms->eff_force_scale = 1000.0; + clmd->sim_parms->eff_wind_scale = 250.0; // also from softbodies - clmd->sim_parms.maxgoal = 1.0; - clmd->sim_parms.mingoal = 0.0; - clmd->sim_parms.defgoal = 0.0; - clmd->sim_parms.goalspring = 100.0; - clmd->sim_parms.goalfrict = 0.0; - - clmd->sim_parms.cache = NULL; + clmd->sim_parms->maxgoal = 1.0; + clmd->sim_parms->mingoal = 0.0; + clmd->sim_parms->defgoal = 0.0; + clmd->sim_parms->goalspring = 100.0; + clmd->sim_parms->goalfrict = 0.0; } // unused in the moment, cloth needs quads from mesh @@ -410,7 +408,7 @@ void cloth_clear_cache(Object *ob, ClothModifierData *clmd, float framenr) { int stack_index = -1; - if(!(clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_CCACHE_PROTECT)) + if(!(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_CCACHE_PROTECT)) { stack_index = modifiers_indexInObject(ob, (ModifierData *)clmd); @@ -434,9 +432,9 @@ static void cloth_write_cache(Object *ob, ClothModifierData *clmd, float framenr for(a = 0; a < cloth->numverts; a++) { - fwrite(&cloth->x[a], sizeof(float),3,fp); - fwrite(&cloth->xconst[a], sizeof(float),3,fp); - fwrite(&cloth->v[a], sizeof(float),3,fp); + fwrite(&cloth->x[a], sizeof(float),4,fp); + fwrite(&cloth->xconst[a], sizeof(float),4,fp); + fwrite(&cloth->v[a], sizeof(float),4,fp); } fclose(fp); @@ -459,17 +457,17 @@ static int cloth_read_cache(Object *ob, ClothModifierData *clmd, float framenr) else { for(a = 0; a < cloth->numverts; a++) { - if(fread(&cloth->x[a], sizeof(float), 3, fp) != 3) + if(fread(&cloth->x[a], sizeof(float), 4, fp) != 4) { ret = 0; break; } - if(fread(&cloth->xconst[a], sizeof(float), 3, fp) != 3) + if(fread(&cloth->xconst[a], sizeof(float), 4, fp) != 4) { ret = 0; break; } - if(fread(&cloth->v[a], sizeof(float), 3, fp) != 3) + if(fread(&cloth->v[a], sizeof(float), 4, fp) != 4) { ret = 0; break; @@ -501,9 +499,9 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd,Object *ob, DerivedMesh *d unsigned int framenr = (float)G.scene->r.cfra; float current_time = bsystem_time(ob, (float)G.scene->r.cfra, 0.0); ListBase *effectors = NULL; - float deltaTime = current_time - clmd->sim_parms.sim_time; + float deltaTime = current_time - clmd->sim_parms->sim_time; - clmd->sim_parms.dt = 1.0f / (clmd->sim_parms.stepsPerFrame * G.scene->r.frs_sec); + clmd->sim_parms->dt = 1.0f / (clmd->sim_parms->stepsPerFrame * G.scene->r.frs_sec); result = CDDM_copy(dm); @@ -519,9 +517,9 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd,Object *ob, DerivedMesh *d medge = CDDM_get_edges(result); mface = CDDM_get_faces(result); - clmd->sim_parms.sim_time = current_time; + clmd->sim_parms->sim_time = current_time; - if ( current_time < clmd->sim_parms.firstframe ) + if ( current_time < clmd->sim_parms->firstframe ) return result; // only be active during a specific period: @@ -529,9 +527,9 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd,Object *ob, DerivedMesh *d /* if ( clmd->clothObject ) { - if ( clmd->sim_parms.cache ) + if ( clmd->sim_parms->cache ) { - if ( current_time < clmd->sim_parms.firstframe ) + if ( current_time < clmd->sim_parms->firstframe ) { int frametime = cloth_cache_first_frame ( clmd ); if ( cloth_cache_search_frame ( clmd, frametime ) ) @@ -541,7 +539,7 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd,Object *ob, DerivedMesh *d } return result; } - else if ( current_time > clmd->sim_parms.lastframe ) + else if ( current_time > clmd->sim_parms->lastframe ) { int frametime = cloth_cache_last_frame ( clmd ); if ( cloth_cache_search_frame ( clmd, frametime ) ) @@ -558,7 +556,7 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd,Object *ob, DerivedMesh *d cloth_cache_get_frame ( clmd, framenr ); cloth_to_object ( ob, result, clmd ); } - clmd->sim_parms.sim_time = current_time; + clmd->sim_parms->sim_time = current_time; return result; } } @@ -578,7 +576,7 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd,Object *ob, DerivedMesh *d cloth = clmd->clothObject; } - clmd->clothObject->old_solver_type = clmd->sim_parms.solver_type; + clmd->clothObject->old_solver_type = clmd->sim_parms->solver_type; // Insure we have a clmd->clothObject, in case allocation failed. if (clmd->clothObject != NULL) @@ -600,8 +598,8 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd,Object *ob, DerivedMesh *d tstart(); /* Call the solver. */ - if (solvers [clmd->sim_parms.solver_type].solver) - solvers [clmd->sim_parms.solver_type].solver (ob, framenr, clmd, effectors); + if (solvers [clmd->sim_parms->solver_type].solver) + solvers [clmd->sim_parms->solver_type].solver (ob, framenr, clmd, effectors); tend(); @@ -614,7 +612,7 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd,Object *ob, DerivedMesh *d cloth_to_object (ob, result, clmd); // bvh_free(clmd->clothObject->tree); - // clmd->clothObject->tree = bvh_build(clmd, clmd->coll_parms.epsilon); + // clmd->clothObject->tree = bvh_build(clmd, clmd->coll_parms->epsilon); } } @@ -793,7 +791,7 @@ static void cloth_apply_vgroup(ClothModifierData *clmd, DerivedMesh *dm, short v for ( i = 0; i < numverts; i++, verts++ ) { // LATER ON, support also mass painting here - if ( clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_GOAL ) + if ( clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL ) { dvert = dm->getVertData ( dm, i, CD_MDEFORMVERT ); if ( dvert ) @@ -804,7 +802,7 @@ static void cloth_apply_vgroup(ClothModifierData *clmd, DerivedMesh *dm, short v { verts->goal = dvert->dw [j].weight; - goalfac= ABS ( clmd->sim_parms.maxgoal - clmd->sim_parms.mingoal ); + goalfac= ABS ( clmd->sim_parms->maxgoal - clmd->sim_parms->mingoal ); verts->goal = ( float ) pow ( verts->goal , 4.0f ); if ( dvert->dw [j].weight >=SOFTGOALSNAP ) @@ -875,9 +873,9 @@ static int cloth_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *d VECCOPY (clmd->clothObject->x[i], mvert[i].co); Mat4MulVecfl(ob->obmat, clmd->clothObject->x[i]); - clmd->clothObject->verts [i].mass = clmd->sim_parms.mass; - if ( clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_GOAL ) - clmd->clothObject->verts [i].goal= clmd->sim_parms.defgoal; + clmd->clothObject->verts [i].mass = clmd->sim_parms->mass; + if ( clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL ) + clmd->clothObject->verts [i].goal= clmd->sim_parms->defgoal; else clmd->clothObject->verts [i].goal= 0.0; clmd->clothObject->verts [i].flags = 0; @@ -891,16 +889,16 @@ static int cloth_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *d } /* apply / set vertex groups */ - if (clmd->sim_parms.vgroup_mass > 0) - cloth_apply_vgroup (clmd, olddm, clmd->sim_parms.vgroup_mass); + if (clmd->sim_parms->vgroup_mass > 0) + cloth_apply_vgroup (clmd, olddm, clmd->sim_parms->vgroup_mass); /* init our solver */ - if (solvers [clmd->sim_parms.solver_type].init) - solvers [clmd->sim_parms.solver_type].init (ob, clmd); + if (solvers [clmd->sim_parms->solver_type].init) + solvers [clmd->sim_parms->solver_type].init (ob, clmd); - clmd->clothObject->tree = bvh_build_from_float3(CDDM_get_faces(dm), dm->getNumFaces(dm), clmd->clothObject->x, numverts, clmd->coll_parms.epsilon); + clmd->clothObject->tree = bvh_build_from_float4(CDDM_get_faces(dm), dm->getNumFaces(dm), clmd->clothObject->x, numverts, clmd->coll_parms->epsilon); - clmd->clothObject->selftree = bvh_build_from_float3(NULL, 0, clmd->clothObject->x, numverts, clmd->coll_parms.selfepsilon); + clmd->clothObject->selftree = bvh_build_from_float4(NULL, 0, clmd->clothObject->x, numverts, clmd->coll_parms->selfepsilon); // save initial state cloth_write_cache(ob, clmd, framenr-1); @@ -930,7 +928,7 @@ static void cloth_from_mesh (Object *ob, ClothModifierData *clmd, DerivedMesh *d return; } - clmd->clothObject->x = MEM_callocN ( sizeof ( float ) * clmd->clothObject->numverts * 3, "Cloth MVert_x" ); + clmd->clothObject->x = MEM_callocN ( sizeof ( float ) * clmd->clothObject->numverts * 4, "Cloth MVert_x" ); if ( clmd->clothObject->x == NULL ) { cloth_free_modifier ( clmd ); @@ -938,7 +936,7 @@ static void cloth_from_mesh (Object *ob, ClothModifierData *clmd, DerivedMesh *d return; } - clmd->clothObject->xold = MEM_callocN ( sizeof ( float ) * clmd->clothObject->numverts * 3, "Cloth MVert_xold" ); + clmd->clothObject->xold = MEM_callocN ( sizeof ( float ) * clmd->clothObject->numverts * 4, "Cloth MVert_xold" ); if ( clmd->clothObject->xold == NULL ) { cloth_free_modifier ( clmd ); @@ -946,7 +944,7 @@ static void cloth_from_mesh (Object *ob, ClothModifierData *clmd, DerivedMesh *d return; } - clmd->clothObject->v = MEM_callocN ( sizeof ( float ) * clmd->clothObject->numverts * 3, "Cloth MVert_v" ); + clmd->clothObject->v = MEM_callocN ( sizeof ( float ) * clmd->clothObject->numverts * 4, "Cloth MVert_v" ); if ( clmd->clothObject->v == NULL ) { cloth_free_modifier ( clmd ); @@ -954,7 +952,7 @@ static void cloth_from_mesh (Object *ob, ClothModifierData *clmd, DerivedMesh *d return; } - clmd->clothObject->current_x = MEM_callocN ( sizeof ( float ) * clmd->clothObject->numverts * 3, "Cloth MVert_current_x" ); + clmd->clothObject->current_x = MEM_callocN ( sizeof ( float ) * clmd->clothObject->numverts * 4, "Cloth MVert_current_x" ); if ( clmd->clothObject->current_x == NULL ) { cloth_free_modifier ( clmd ); @@ -962,7 +960,7 @@ static void cloth_from_mesh (Object *ob, ClothModifierData *clmd, DerivedMesh *d return; } - clmd->clothObject->current_xold = MEM_callocN ( sizeof ( float ) * clmd->clothObject->numverts * 3, "Cloth MVert_current_xold" ); + clmd->clothObject->current_xold = MEM_callocN ( sizeof ( float ) * clmd->clothObject->numverts * 4, "Cloth MVert_current_xold" ); if ( clmd->clothObject->current_xold == NULL ) { cloth_free_modifier ( clmd ); @@ -970,7 +968,7 @@ static void cloth_from_mesh (Object *ob, ClothModifierData *clmd, DerivedMesh *d return; } - clmd->clothObject->current_v = MEM_callocN ( sizeof ( float ) * clmd->clothObject->numverts * 3, "Cloth MVert_current_v" ); + clmd->clothObject->current_v = MEM_callocN ( sizeof ( float ) * clmd->clothObject->numverts * 4, "Cloth MVert_current_v" ); if ( clmd->clothObject->current_v == NULL ) { cloth_free_modifier ( clmd ); @@ -978,7 +976,7 @@ static void cloth_from_mesh (Object *ob, ClothModifierData *clmd, DerivedMesh *d return; } - clmd->clothObject->xconst = MEM_callocN ( sizeof ( float ) * clmd->clothObject->numverts * 3, "Cloth MVert_xconst" ); + clmd->clothObject->xconst = MEM_callocN ( sizeof ( float ) * clmd->clothObject->numverts * 4, "Cloth MVert_xconst" ); if ( clmd->clothObject->xconst == NULL ) { cloth_free_modifier ( clmd ); diff --git a/source/blender/blenkernel/intern/implicit.c b/source/blender/blenkernel/intern/implicit.c index ee8a440735a..c457064065c 100644 --- a/source/blender/blenkernel/intern/implicit.c +++ b/source/blender/blenkernel/intern/implicit.c @@ -63,6 +63,12 @@ #include "BKE_global.h" #include "BIF_editdeform.h" +#include "Bullet-C-Api.h" + +#include +#include +#include + #ifdef _WIN32 #include static LARGE_INTEGER _itstart, _itend; @@ -114,20 +120,39 @@ struct Cloth; ///////////////////////////////////////// /* DEFINITIONS */ -typedef float lfVector[3]; +#ifdef __GNUC__ +typedef float lfVector[4] __attribute__ ((aligned (16))); +#else +typedef __declspec(align(16)) lfVector[4]; +#endif + +#ifdef __GNUC__ typedef struct fmatrix3x3 { - float m[3][3]; /* 4x4 matrix */ + float m[3][4] __attribute__ ((aligned (16))); /* 3x3 matrix */ unsigned int c,r; /* column and row number */ int pinned; /* is this vertex allowed to move? */ float n1,n2,n3; /* three normal vectors for collision constrains */ unsigned int vcount; /* vertex count */ unsigned int scount; /* spring count */ } fmatrix3x3; +#else +typedef struct fmatrix3x3 { + __declspec(align(16)) + float m[3][4]; /* 3x3 matrix */ + unsigned int c,r; /* column and row number */ + int pinned; /* is this vertex allowed to move? */ + float n1,n2,n3; /* three normal vectors for collision constrains */ + unsigned int vcount; /* vertex count */ + unsigned int scount; /* spring count */ +} fmatrix3x3; +#endif + /////////////////////////// // float[3] vector /////////////////////////// /* simple vector code */ + /* STATUS: verified */ DO_INLINE void mul_fvector_S(float to[3], float from[3], float scalar) { @@ -139,13 +164,18 @@ DO_INLINE void mul_fvector_S(float to[3], float from[3], float scalar) /* STATUS: verified */ DO_INLINE void cross_fvector(float to[3], float vectorA[3], float vectorB[3]) { - to[0] = vectorA[1] * vectorB[2] - vectorA[2] * vectorB[1]; - to[1] = vectorA[2] * vectorB[0] - vectorA[0] * vectorB[2]; - to[2] = vectorA[0] * vectorB[1] - vectorA[1] * vectorB[0]; + float temp[3]; + + temp[0] = vectorA[1] * vectorB[2] - vectorA[2] * vectorB[1]; + temp[1] = vectorA[2] * vectorB[0] - vectorA[0] * vectorB[2]; + temp[2] = vectorA[0] * vectorB[1] - vectorA[1] * vectorB[0]; + + VECCOPY(to, temp); } + /* simple v^T * v product ("outer product") */ /* STATUS: HAS TO BE verified (*should* work) */ -DO_INLINE void mul_fvectorT_fvector(float to[3][3], float vectorA[3], float vectorB[3]) +DO_INLINE void mul_fvectorT_fvector(float to[3][4], float vectorA[3], float vectorB[3]) { mul_fvector_S(to[0], vectorB, vectorA[0]); mul_fvector_S(to[1], vectorB, vectorA[1]); @@ -153,7 +183,7 @@ DO_INLINE void mul_fvectorT_fvector(float to[3][3], float vectorA[3], float vect } /* simple v^T * v product with scalar ("outer product") */ /* STATUS: HAS TO BE verified (*should* work) */ -DO_INLINE void mul_fvectorT_fvectorS(float to[3][3], float vectorA[3], float vectorB[3], float aS) +DO_INLINE void mul_fvectorT_fvectorS(float to[3][4], float vectorA[3], float vectorB[3], float aS) { mul_fvector_S(to[0], vectorB, vectorA[0]* aS); mul_fvector_S(to[1], vectorB, vectorA[1]* aS); @@ -170,7 +200,7 @@ void print_fvector(float m3[3]) // long float vector float (*)[3] /////////////////////////// /* print long vector on console: for debug output */ -DO_INLINE void print_lfvector(float (*fLongVector)[3], unsigned int verts) +DO_INLINE void print_lfvector(lfVector *fLongVector, unsigned int verts) { unsigned int i = 0; for(i = 0; i < verts; i++) @@ -186,7 +216,7 @@ DO_INLINE lfVector *create_lfvector(unsigned int verts) // return (lfVector *)cloth_aligned_malloc(&MEMORY_BASE, verts * sizeof(lfVector)); } /* delete long vector */ -DO_INLINE void del_lfvector(float (*fLongVector)[3]) +DO_INLINE void del_lfvector(lfVector *fLongVector) { if (fLongVector != NULL) { @@ -195,12 +225,12 @@ DO_INLINE void del_lfvector(float (*fLongVector)[3]) } } /* copy long vector */ -DO_INLINE void cp_lfvector(float (*to)[3], float (*from)[3], unsigned int verts) +DO_INLINE void cp_lfvector(lfVector *to, lfVector *from, unsigned int verts) { memcpy(to, from, verts * sizeof(lfVector)); } /* init long vector with float[3] */ -DO_INLINE void init_lfvector(float (*fLongVector)[3], float vector[3], unsigned int verts) +DO_INLINE void init_lfvector(lfVector *fLongVector, float vector[3], unsigned int verts) { unsigned int i = 0; for(i = 0; i < verts; i++) @@ -209,12 +239,12 @@ DO_INLINE void init_lfvector(float (*fLongVector)[3], float vector[3], unsigned } } /* zero long vector with float[3] */ -DO_INLINE void zero_lfvector(float (*to)[3], unsigned int verts) +DO_INLINE void zero_lfvector(lfVector *to, unsigned int verts) { memset(to, 0.0f, verts * sizeof(lfVector)); } /* multiply long vector with scalar*/ -DO_INLINE void mul_lfvectorS(float (*to)[3], float (*fLongVector)[3], float scalar, unsigned int verts) +DO_INLINE void mul_lfvectorS(lfVector *to, lfVector *fLongVector, float scalar, unsigned int verts) { unsigned int i = 0; @@ -225,7 +255,7 @@ DO_INLINE void mul_lfvectorS(float (*to)[3], float (*fLongVector)[3], float scal } /* multiply long vector with scalar*/ /* A -= B * float */ -DO_INLINE void submul_lfvectorS(float (*to)[3], float (*fLongVector)[3], float scalar, unsigned int verts) +DO_INLINE void submul_lfvectorS(lfVector *to, lfVector *fLongVector, float scalar, unsigned int verts) { unsigned int i = 0; for(i = 0; i < verts; i++) @@ -234,12 +264,12 @@ DO_INLINE void submul_lfvectorS(float (*to)[3], float (*fLongVector)[3], float s } } /* dot product for big vector */ -DO_INLINE float dot_lfvector(float (*fLongVectorA)[3], float (*fLongVectorB)[3], unsigned int verts) +DO_INLINE float dot_lfvector(lfVector *fLongVectorA, lfVector *fLongVectorB, unsigned int verts) { unsigned int i = 0; float temp = 0.0; // schedule(guided, 2) -#pragma omp parallel for reduction(+: temp) +#pragma omp parallel for reduction(+: temp) schedule(static) for(i = 0; i < verts; i++) { temp += INPR(fLongVectorA[i], fLongVectorB[i]); @@ -247,7 +277,7 @@ DO_INLINE float dot_lfvector(float (*fLongVectorA)[3], float (*fLongVectorB)[3], return temp; } /* A = B + C --> for big vector */ -DO_INLINE void add_lfvector_lfvector(float (*to)[3], float (*fLongVectorA)[3], float (*fLongVectorB)[3], unsigned int verts) +DO_INLINE void add_lfvector_lfvector(lfVector *to, lfVector *fLongVectorA, lfVector *fLongVectorB, unsigned int verts) { unsigned int i = 0; @@ -258,7 +288,7 @@ DO_INLINE void add_lfvector_lfvector(float (*to)[3], float (*fLongVectorA)[3], f } /* A = B + C * float --> for big vector */ -DO_INLINE void add_lfvector_lfvectorS(float (*to)[3], float (*fLongVectorA)[3], float (*fLongVectorB)[3], float bS, unsigned int verts) +DO_INLINE void add_lfvector_lfvectorS(lfVector *to, lfVector *fLongVectorA, lfVector *fLongVectorB, float bS, unsigned int verts) { unsigned int i = 0; @@ -269,7 +299,7 @@ DO_INLINE void add_lfvector_lfvectorS(float (*to)[3], float (*fLongVectorA)[3], } } /* A = B * float + C * float --> for big vector */ -DO_INLINE void add_lfvectorS_lfvectorS(float (*to)[3], float (*fLongVectorA)[3], float aS, float (*fLongVectorB)[3], float bS, unsigned int verts) +DO_INLINE void add_lfvectorS_lfvectorS(lfVector *to, lfVector *fLongVectorA, float aS, lfVector *fLongVectorB, float bS, unsigned int verts) { unsigned int i = 0; @@ -279,7 +309,7 @@ DO_INLINE void add_lfvectorS_lfvectorS(float (*to)[3], float (*fLongVectorA)[3], } } /* A = B - C * float --> for big vector */ -DO_INLINE void sub_lfvector_lfvectorS(float (*to)[3], float (*fLongVectorA)[3], float (*fLongVectorB)[3], float bS, unsigned int verts) +DO_INLINE void sub_lfvector_lfvectorS(lfVector *to, lfVector *fLongVectorA, lfVector *fLongVectorB, float bS, unsigned int verts) { unsigned int i = 0; for(i = 0; i < verts; i++) @@ -289,7 +319,7 @@ DO_INLINE void sub_lfvector_lfvectorS(float (*to)[3], float (*fLongVectorA)[3], } /* A = B - C --> for big vector */ -DO_INLINE void sub_lfvector_lfvector(float (*to)[3], float (*fLongVectorA)[3], float (*fLongVectorB)[3], unsigned int verts) +DO_INLINE void sub_lfvector_lfvector(lfVector *to, lfVector *fLongVectorA, lfVector *fLongVectorB, unsigned int verts) { unsigned int i = 0; @@ -300,30 +330,32 @@ DO_INLINE void sub_lfvector_lfvector(float (*to)[3], float (*fLongVectorA)[3], f } /////////////////////////// -// 4x4 matrix +// 3x3 matrix /////////////////////////// -/* printf 4x4 matrix on console: for debug output */ -void print_fmatrix(float m3[3][3]) +/* printf 3x3 matrix on console: for debug output */ +void print_fmatrix(float m3[3][4]) { printf("%f\t%f\t%f\n",m3[0][0],m3[0][1],m3[0][2]); printf("%f\t%f\t%f\n",m3[1][0],m3[1][1],m3[1][2]); printf("%f\t%f\t%f\n\n",m3[2][0],m3[2][1],m3[2][2]); } -/* copy 4x4 matrix */ -DO_INLINE void cp_fmatrix(float to[3][3], float from[3][3]) +/* copy 3x3 matrix */ +DO_INLINE void cp_fmatrix(float to[3][4], float from[3][4]) { - // memcpy(to, from, sizeof (float) * 9); + memcpy(to, from, sizeof (float) * 12); + /* VECCOPY(to[0], from[0]); VECCOPY(to[1], from[1]); VECCOPY(to[2], from[2]); + */ } -/* calculate determinant of 4x4 matrix */ -DO_INLINE float det_fmatrix(float m[3][3]) +/* calculate determinant of 3x3 matrix */ +DO_INLINE float det_fmatrix(float m[3][4]) { return m[0][0]*m[1][1]*m[2][2] + m[1][0]*m[2][1]*m[0][2] + m[0][1]*m[1][2]*m[2][0] -m[0][0]*m[1][2]*m[2][1] - m[0][1]*m[1][0]*m[2][2] - m[2][0]*m[1][1]*m[0][2]; } -DO_INLINE void inverse_fmatrix(float to[3][3], float from[3][3]) +DO_INLINE void inverse_fmatrix(float to[3][4], float from[3][4]) { unsigned int i, j; float d; @@ -354,84 +386,110 @@ DO_INLINE void inverse_fmatrix(float to[3][3], float from[3][3]) } -/* 4x4 matrix multiplied by a scalar */ +/* 3x3 matrix multiplied by a scalar */ /* STATUS: verified */ -DO_INLINE void mul_fmatrix_S(float matrix[3][3], float scalar) +DO_INLINE void mul_fmatrix_S(float matrix[3][4], float scalar) { mul_fvector_S(matrix[0], matrix[0],scalar); mul_fvector_S(matrix[1], matrix[1],scalar); mul_fvector_S(matrix[2], matrix[2],scalar); } -/* a vector multiplied by a 4x4 matrix */ +/* a vector multiplied by a 3x3 matrix */ /* STATUS: verified */ -DO_INLINE void mul_fvector_fmatrix(float *to, float *from, float matrix[3][3]) +DO_INLINE void mul_fvector_fmatrix(float *to, float *from, float matrix[3][4]) { - to[0] = matrix[0][0]*from[0] + matrix[1][0]*from[1] + matrix[2][0]*from[2]; - to[1] = matrix[0][1]*from[0] + matrix[1][1]*from[1] + matrix[2][1]*from[2]; - to[2] = matrix[0][2]*from[0] + matrix[1][2]*from[1] + matrix[2][2]*from[2]; + float temp[3]; + + VECCOPY(temp, from); + + to[0] = matrix[0][0]*temp[0] + matrix[1][0]*temp[1] + matrix[2][0]*temp[2]; + to[1] = matrix[0][1]*temp[0] + matrix[1][1]*temp[1] + matrix[2][1]*temp[2]; + to[2] = matrix[0][2]*temp[0] + matrix[1][2]*temp[1] + matrix[2][2]*temp[2]; } -/* 4x4 matrix multiplied by a vector */ +/* 3x3 matrix multiplied by a vector */ /* STATUS: verified */ -DO_INLINE void mul_fmatrix_fvector(float *to, float matrix[3][3], float *from) +#ifdef SSE3 +DO_INLINE void mul_fmatrix_fvector(float *to, float matrix[3][4], float *from) { + __m128 v1, v2, v3, v4; + + v1 = _mm_load_ps(&matrix[0]); + v2 = _mm_load_ps(&matrix[1]); + v3 = _mm_load_ps(&matrix[2]); + v4 = _mm_load_ps(from); + + // stuff + v1 = _mm_mul_ps(v1, v4); + v2 = _mm_mul_ps(v2, v4); + v3 = _mm_mul_ps(v3, v4); + v1 = _mm_hadd_ps(v1, v2); + v3 = _mm_hadd_ps(v3, _mm_setzero_ps()); + v1 = _mm_hadd_ps(v1, v3); + + _mm_store_ps(to, v4); +} +#else +DO_INLINE void mul_fmatrix_fvector(float *to, float matrix[3][4], float *from) { to[0] = INPR(matrix[0],from); to[1] = INPR(matrix[1],from); to[2] = INPR(matrix[2],from); } -/* 4x4 matrix multiplied by a 4x4 matrix */ +#endif + +/* 3x3 matrix multiplied by a 3x3 matrix */ /* STATUS: verified */ -DO_INLINE void mul_fmatrix_fmatrix(float to[3][3], float matrixA[3][3], float matrixB[3][3]) +DO_INLINE void mul_fmatrix_fmatrix(float to[3][4], float matrixA[3][4], float matrixB[3][4]) { mul_fvector_fmatrix(to[0], matrixA[0],matrixB); mul_fvector_fmatrix(to[1], matrixA[1],matrixB); mul_fvector_fmatrix(to[2], matrixA[2],matrixB); } -/* 4x4 matrix addition with 4x4 matrix */ -DO_INLINE void add_fmatrix_fmatrix(float to[3][3], float matrixA[3][3], float matrixB[3][3]) +/* 3x3 matrix addition with 3x3 matrix */ +DO_INLINE void add_fmatrix_fmatrix(float to[3][4], float matrixA[3][4], float matrixB[3][4]) { VECADD(to[0], matrixA[0], matrixB[0]); VECADD(to[1], matrixA[1], matrixB[1]); VECADD(to[2], matrixA[2], matrixB[2]); } -/* 4x4 matrix add-addition with 4x4 matrix */ -DO_INLINE void addadd_fmatrix_fmatrix(float to[3][3], float matrixA[3][3], float matrixB[3][3]) +/* 3x3 matrix add-addition with 3x3 matrix */ +DO_INLINE void addadd_fmatrix_fmatrix(float to[3][4], float matrixA[3][4], float matrixB[3][4]) { VECADDADD(to[0], matrixA[0], matrixB[0]); VECADDADD(to[1], matrixA[1], matrixB[1]); VECADDADD(to[2], matrixA[2], matrixB[2]); } -/* 4x4 matrix sub-addition with 4x4 matrix */ -DO_INLINE void addsub_fmatrixS_fmatrixS(float to[3][3], float matrixA[3][3], float aS, float matrixB[3][3], float bS) +/* 3x3 matrix sub-addition with 3x3 matrix */ +DO_INLINE void addsub_fmatrixS_fmatrixS(float to[3][4], float matrixA[3][4], float aS, float matrixB[3][4], float bS) { VECADDSUBSS(to[0], matrixA[0], aS, matrixB[0], bS); VECADDSUBSS(to[1], matrixA[1], aS, matrixB[1], bS); VECADDSUBSS(to[2], matrixA[2], aS, matrixB[2], bS); } -/* A -= B + C (4x4 matrix sub-addition with 4x4 matrix) */ -DO_INLINE void subadd_fmatrix_fmatrix(float to[3][3], float matrixA[3][3], float matrixB[3][3]) +/* A -= B + C (3x3 matrix sub-addition with 3x3 matrix) */ +DO_INLINE void subadd_fmatrix_fmatrix(float to[3][4], float matrixA[3][4], float matrixB[3][4]) { VECSUBADD(to[0], matrixA[0], matrixB[0]); VECSUBADD(to[1], matrixA[1], matrixB[1]); VECSUBADD(to[2], matrixA[2], matrixB[2]); } -/* A -= B*x + C*y (4x4 matrix sub-addition with 4x4 matrix) */ -DO_INLINE void subadd_fmatrixS_fmatrixS(float to[3][3], float matrixA[3][3], float aS, float matrixB[3][3], float bS) +/* A -= B*x + C*y (3x3 matrix sub-addition with 3x3 matrix) */ +DO_INLINE void subadd_fmatrixS_fmatrixS(float to[3][4], float matrixA[3][4], float aS, float matrixB[3][4], float bS) { VECSUBADDSS(to[0], matrixA[0], aS, matrixB[0], bS); VECSUBADDSS(to[1], matrixA[1], aS, matrixB[1], bS); VECSUBADDSS(to[2], matrixA[2], aS, matrixB[2], bS); } -/* A = B - C (4x4 matrix subtraction with 4x4 matrix) */ -DO_INLINE void sub_fmatrix_fmatrix(float to[3][3], float matrixA[3][3], float matrixB[3][3]) +/* A = B - C (3x3 matrix subtraction with 3x3 matrix) */ +DO_INLINE void sub_fmatrix_fmatrix(float to[3][4], float matrixA[3][4], float matrixB[3][4]) { VECSUB(to[0], matrixA[0], matrixB[0]); VECSUB(to[1], matrixA[1], matrixB[1]); VECSUB(to[2], matrixA[2], matrixB[2]); } -/* A += B - C (4x4 matrix add-subtraction with 4x4 matrix) */ -DO_INLINE void addsub_fmatrix_fmatrix(float to[3][3], float matrixA[3][3], float matrixB[3][3]) +/* A += B - C (3x3 matrix add-subtraction with 3x3 matrix) */ +DO_INLINE void addsub_fmatrix_fmatrix(float to[3][4], float matrixA[3][4], float matrixB[3][4]) { VECADDSUB(to[0], matrixA[0], matrixB[0]); VECADDSUB(to[1], matrixA[1], matrixB[1]); @@ -440,53 +498,93 @@ DO_INLINE void addsub_fmatrix_fmatrix(float to[3][3], float matrixA[3][3], float ///////////////////////////////////////////////////////////////// // special functions ///////////////////////////////////////////////////////////////// -/* a vector multiplied and added to/by a 4x4 matrix */ +/* a vector multiplied and added to/by a 3x3 matrix */ +/* DO_INLINE void muladd_fvector_fmatrix(float to[3], float from[3], float matrix[3][3]) { to[0] += matrix[0][0]*from[0] + matrix[1][0]*from[1] + matrix[2][0]*from[2]; to[1] += matrix[0][1]*from[0] + matrix[1][1]*from[1] + matrix[2][1]*from[2]; to[2] += matrix[0][2]*from[0] + matrix[1][2]*from[1] + matrix[2][2]*from[2]; } -/* 4x4 matrix multiplied and added to/by a 4x4 matrix and added to another 4x4 matrix */ +*/ +/* 3x3 matrix multiplied and added to/by a 3x3 matrix and added to another 3x3 matrix */ +/* DO_INLINE void muladd_fmatrix_fmatrix(float to[3][3], float matrixA[3][3], float matrixB[3][3]) { muladd_fvector_fmatrix(to[0], matrixA[0],matrixB); muladd_fvector_fmatrix(to[1], matrixA[1],matrixB); muladd_fvector_fmatrix(to[2], matrixA[2],matrixB); } -/* a vector multiplied and sub'd to/by a 4x4 matrix */ +*/ +/* a vector multiplied and sub'd to/by a 3x3 matrix */ +/* DO_INLINE void mulsub_fvector_fmatrix(float to[3], float from[3], float matrix[3][3]) { to[0] -= matrix[0][0]*from[0] + matrix[1][0]*from[1] + matrix[2][0]*from[2]; to[1] -= matrix[0][1]*from[0] + matrix[1][1]*from[1] + matrix[2][1]*from[2]; to[2] -= matrix[0][2]*from[0] + matrix[1][2]*from[1] + matrix[2][2]*from[2]; } -/* 4x4 matrix multiplied and sub'd to/by a 4x4 matrix and added to another 4x4 matrix */ +*/ +/* 3x3 matrix multiplied and sub'd to/by a 3x3 matrix and added to another 3x3 matrix */ +/* DO_INLINE void mulsub_fmatrix_fmatrix(float to[3][3], float matrixA[3][3], float matrixB[3][3]) { mulsub_fvector_fmatrix(to[0], matrixA[0],matrixB); mulsub_fvector_fmatrix(to[1], matrixA[1],matrixB); mulsub_fvector_fmatrix(to[2], matrixA[2],matrixB); } -/* 4x4 matrix multiplied+added by a vector */ +*/ +/* 3x3 matrix multiplied+added by a vector */ /* STATUS: verified */ -DO_INLINE void muladd_fmatrix_fvector(float to[3], float matrix[3][3], float from[3]) -{ - to[0] += INPR(matrix[0],from); - to[1] += INPR(matrix[1],from); - to[2] += INPR(matrix[2],from); + +#ifdef SSE3 +DO_INLINE void muladd_fmatrix_fvector(float to[3], float matrix[3][4], float from[3]) { + __m128 v1, v2, v3, v4; + + v1 = _mm_load_ps(&matrix[0]); + v2 = _mm_load_ps(&matrix[1]); + v3 = _mm_load_ps(&matrix[2]); + v4 = _mm_load_ps(from); + + // stuff + v1 = _mm_mul_ps(v1, v4); + v2 = _mm_mul_ps(v2, v4); + v3 = _mm_mul_ps(v3, v4); + v1 = _mm_hadd_ps(v1, v2); + v3 = _mm_hadd_ps(v3, _mm_setzero_ps()); + v1 = _mm_hadd_ps(v1, v3); + + v4 = _mm_load_ps(to); + v4 = _mm_add_ps(v4,v1); + + _mm_store_ps(to, v4); } -/* 4x4 matrix multiplied+sub'ed by a vector */ +#else +DO_INLINE void muladd_fmatrix_fvector(float to[3], float matrix[3][4], float from[3]) +{ + float temp[3] = { 0,0,0 }; + + temp[0] = INPR(matrix[0],from); + temp[1] = INPR(matrix[1],from); + temp[2] = INPR(matrix[2],from); + + VECADD(to, to, temp); +} +#endif + +/* 3x3 matrix multiplied+sub'ed by a vector */ +/* DO_INLINE void mulsub_fmatrix_fvector(float to[3], float matrix[3][3], float from[3]) { to[0] -= INPR(matrix[0],from); to[1] -= INPR(matrix[1],from); to[2] -= INPR(matrix[2],from); } +*/ ///////////////////////////////////////////////////////////////// /////////////////////////// -// SPARSE SYMMETRIC big matrix with 4x4 matrix entries +// SPARSE SYMMETRIC big matrix with 3x3 matrix entries /////////////////////////// /* printf a big matrix on console: for debug output */ void print_bfmatrix(fmatrix3x3 *m3) @@ -523,10 +621,10 @@ DO_INLINE void cp_bfmatrix(fmatrix3x3 *to, fmatrix3x3 *from) } /* init the diagonal of big matrix */ // slow in parallel -DO_INLINE void initdiag_bfmatrix(fmatrix3x3 *matrix, float m3[3][3]) +DO_INLINE void initdiag_bfmatrix(fmatrix3x3 *matrix, float m3[3][4]) { unsigned int i,j; - float tmatrix[3][3] = {{0,0,0},{0,0,0},{0,0,0}}; + float tmatrix[3][4] = {{0,0,0,0},{0,0,0,0},{0,0,0,0}}; for(i = 0; i < matrix[0].vcount; i++) { @@ -538,7 +636,7 @@ DO_INLINE void initdiag_bfmatrix(fmatrix3x3 *matrix, float m3[3][3]) } } /* init big matrix */ -DO_INLINE void init_bfmatrix(fmatrix3x3 *matrix, float m3[3][3]) +DO_INLINE void init_bfmatrix(fmatrix3x3 *matrix, float m3[3][4]) { unsigned int i; @@ -558,45 +656,31 @@ DO_INLINE void mul_bfmatrix_S(fmatrix3x3 *matrix, float scalar) } /* SPARSE SYMMETRIC multiply big matrix with long vector*/ /* STATUS: verified */ -DO_INLINE void mul_bfmatrix_lfvector( float (*to)[3], fmatrix3x3 *from, float (*fLongVector)[3]) +void mul_bfmatrix_lfvector( lfVector *to, fmatrix3x3 *from, lfVector *fLongVector) { unsigned int i = 0; + float *tflongvector; + float temp[4]={0,0,0,0}; + zero_lfvector(to, from[0].vcount); + /* process diagonal elements */ for(i = 0; i < from[0].vcount; i++) { - muladd_fmatrix_fvector(to[from[i].r], from[i].m, fLongVector[from[i].c]); + mul_fmatrix_fvector(to[from[i].r], from[i].m, fLongVector[from[i].c]); } /* process off-diagonal entries (every off-diagonal entry needs to be symmetric) */ // TODO: pragma below is wrong, correct it! // #pragma omp parallel for shared(to,from, fLongVector) private(i) + for(i = from[0].vcount; i < from[0].vcount+from[0].scount; i++) { - unsigned int row = from[i].r; - unsigned int column = from[i].c; - - // muladd_fmatrix_fvector(to[from[i].c], from[i].m, fLongVector[from[i].r]); - - to[column][0] += INPR(from[i].m[0],fLongVector[row]); - to[column][1] += INPR(from[i].m[1],fLongVector[row]); - to[column][2] += INPR(from[i].m[2],fLongVector[row]); + muladd_fmatrix_fvector(to[from[i].c], from[i].m, fLongVector[from[i].r]); + muladd_fmatrix_fvector(to[from[i].r], from[i].m, fLongVector[from[i].c]); } -// #pragma omp parallel for shared(to,from, fLongVector) private(i) - for(i = from[0].vcount; i < from[0].vcount+from[0].scount; i++) - { - unsigned int row = from[i].r; - unsigned int column = from[i].c; - - // muladd_fmatrix_fvector(to[from[i].r], from[i].m, fLongVector[from[i].c]); - - to[row][0] += INPR(from[i].m[0],fLongVector[column]); - to[row][1] += INPR(from[i].m[1],fLongVector[column]); - to[row][2] += INPR(from[i].m[2],fLongVector[column]); - } - - } + /* SPARSE SYMMETRIC add big matrix with big matrix: A = B + C*/ DO_INLINE void add_bfmatrix_bfmatrix( fmatrix3x3 *to, fmatrix3x3 *from, fmatrix3x3 *matrix) { @@ -687,8 +771,8 @@ DO_INLINE void subadd_bfmatrixS_bfmatrixS( fmatrix3x3 *to, fmatrix3x3 *from, flo /////////////////////////////////////////////////////////////////// // simulator start /////////////////////////////////////////////////////////////////// -static float I[3][3] = {{1,0,0},{0,1,0},{0,0,1}}; -static float ZERO[3][3] = {{0,0,0}, {0,0,0}, {0,0,0}}; +static float I[3][4] = {{1,0,0,0},{0,1,0,0},{0,0,1,0}}; +static float ZERO[3][4] = {{0,0,0,0},{0,0,0,0},{0,0,0,0}}; typedef struct Implicit_Data { lfVector *X, *V, *Xnew, *Vnew, *F, *B, *dV, *z; @@ -885,31 +969,6 @@ DO_INLINE void filter(lfVector *V, fmatrix3x3 *S) } } -// block diagonalizer -void BuildPPinv(fmatrix3x3 *lA, fmatrix3x3 *P, fmatrix3x3 *Pinv, fmatrix3x3 *S, fmatrix3x3 *bigI) -{ - unsigned int i=0; - - // Take only the diagonal blocks of A - for(i=0;istarget && conjgrad_loopcount < conjgrad_looplimit)) { // Mul(q,A,d); // q = A*d; @@ -963,172 +1022,242 @@ int cg_filtered(lfVector *ldV, fmatrix3x3 *lA, lfVector *lB, lfVector *z, fmatr conjgrad_loopcount++; } + // itend(); + // printf("cg_filtered time: %f\n", (float)itval()); + conjgrad_lasterror = s; del_lfvector(q); del_lfvector(d); del_lfvector(tmp); del_lfvector(r); + // printf("W/O conjgrad_loopcount: %d\n", conjgrad_loopcount); return conjgrad_loopcount(epsilon_sqr*delta0))&& (conjgrad_loopcount++ < conjgrad_looplimit)) -{ -////////////////////////// -// (s) = q = S*A*c -////////////////////////// -// q = A*c; -mul_bfmatrix_lfvector(q, lA, c); -filter(q,S); -////////////////////////// - -////////////////////////// -// alpha = deltanew / (c^T * q) -////////////////////////// -alpha = deltanew/dot_lfvector(c, q, numverts); -////////////////////////// - -//X = X + c*alpha; -add_lfvector_lfvectorS(ldV, ldV, c, alpha, numverts); -//r = r - q*alpha; -sub_lfvector_lfvectorS(r, r, q, alpha, numverts); - -////////////////////////// -// (h) = s = P^-1 * r -////////////////////////// -// s = Pinv * r; -mul_bfmatrix_lfvector(s, Pinv, r); -filter(s,S); -////////////////////////// - -deltaold = deltanew; - -// deltanew = dot(r,s); -deltanew = dot_lfvector(r, s, numverts); - -////////////////////////// -// c = S * (s + (deltanew/deltaold)*c) -////////////////////////// -// c = s + c * (deltanew/deltaold); -add_lfvector_lfvectorS(c, s, c, (deltanew/deltaold), numverts); -filter(c,S); -////////////////////////// - + unsigned int i = 0; + + // Take only the diagonal blocks of A +// #pragma omp parallel for private(i) + for(i = 0; i (conjgrad_epsilon*conjgrad_epsilon*delta0)) && (iterations < conjgrad_looplimit)); + + del_lfvector(s); + del_lfvector(q); + del_lfvector(c); + del_lfvector(r); + del_lfvector(p_fb); + del_lfvector(filterb); + + printf("iterations: %d\n", iterations); + + return iterations (conjgrad_epsilon*conjgrad_epsilon*delta0)) && (iterations < conjgrad_looplimit)) + { + iterations++; + + mul_bfmatrix_lfvector(s, lA, p); + filter(s, S); + + alpha = deltaNew / dot_lfvector(p, s, numverts); + + add_lfvector_lfvectorS(dv, dv, p, alpha, numverts); + + add_lfvector_lfvectorS(r, r, s, -alpha, numverts); + + mul_bfmatrix_lfvector(h, Pinv, r); + + + deltaOld = deltaNew; + + deltaNew = dot_lfvector(r, h, numverts); + + add_lfvector_lfvectorS(p, h, p, deltaNew / deltaOld, numverts); + filter(p, S); + + } + + del_lfvector(h); + del_lfvector(s); + del_lfvector(p); + del_lfvector(r); + + printf("iterations: %d\n", iterations); + + return iterations (conjgrad_epsilon*delta0)) && (iterations < conjgrad_looplimit)) + { + iterations++; + + mul_bfmatrix_lfvector(s, lA, p); + filter(s, S); + + alpha = deltaNew / dot_lfvector(p, s, numverts); + + add_lfvector_lfvectorS(dv, dv, p, alpha, numverts); + + sub_lfvector_lfvectorS(r, r, s, alpha, numverts); + + mul_bfmatrix_lfvector(h, Pinv, r); + filter(h, S); + + deltaOld = deltaNew; + + deltaNew = dot_lfvector(r, h, numverts); + + add_lfvector_lfvectorS(p, h, p, deltaNew / deltaOld, numverts); + filter(p, S); + + } + + // itend(); + // printf("cg_filtered_pre time: %f\n", (float)itval()); + + del_lfvector(h); + del_lfvector(s); + del_lfvector(p); + del_lfvector(r); + + // printf("iterations: %d\n", iterations); + + return iterationsrestlen; - float cb = clmd->sim_parms.structural; + float cb = clmd->sim_parms->structural; float nullf[3] = {0,0,0}; float stretch_force[3] = {0,0,0}; float bending_force[3] = {0,0,0}; float damping_force[3] = {0,0,0}; - float nulldfdx[3][3]={ {0,0,0}, {0,0,0}, {0,0,0}}; + float nulldfdx[3][4]={ {0,0,0,0}, {0,0,0,0}, {0,0,0,0}}; VECCOPY(s->f, nullf); cp_fmatrix(s->dfdx, nulldfdx); @@ -1202,8 +1331,8 @@ DO_INLINE void cloth_calc_spring_force(ClothModifierData *clmd, ClothSpring *s, /* if(length>L) { - if((clmd->sim_parms.flags & CSIMSETT_FLAG_TEARING_ENABLED) - && ((((length-L)*100.0f/L) > clmd->sim_parms.maxspringlen))) // cut spring! + if((clmd->sim_parms->flags & CSIMSETT_FLAG_TEARING_ENABLED) + && ((((length-L)*100.0f/L) > clmd->sim_parms->maxspringlen))) // cut spring! { s->flags |= CSPRING_FLAG_DEACTIVATE; return; @@ -1225,44 +1354,44 @@ DO_INLINE void cloth_calc_spring_force(ClothModifierData *clmd, ClothSpring *s, { s->flags |= CLOTH_SPRING_FLAG_NEEDED; - k = (clmd->sim_parms.structural*(length-L)); + k = (clmd->sim_parms->structural*(length-L)); mul_fvector_S(stretch_force, dir, k); VECADD(s->f, s->f, stretch_force); // Ascher & Boxman, p.21: Damping only during elonglation - mul_fvector_S(damping_force, extent, clmd->sim_parms.Cdis * 0.01 * ((INPR(vel,extent)/length))); + mul_fvector_S(damping_force, extent, clmd->sim_parms->Cdis * 0.01 * ((INPR(vel,extent)/length))); VECADD(s->f, s->f, damping_force); // Formula from Ascher / Boxman, Speeding up cloth simulation - if((dt * (k*dt + 2 * clmd->sim_parms.Cdis * 0.01)) > 0.01 ) + // if((dt * (k*dt + 2 * clmd->sim_parms->Cdis * 0.01)) > 0.01 ) { - dfdx_spring_type1(s->dfdx, dir,length,L,clmd->sim_parms.structural); - dfdv_damp(s->dfdv, dir,clmd->sim_parms.Cdis * 0.01); + dfdx_spring_type1(s->dfdx, dir,length,L,clmd->sim_parms->structural); + dfdv_damp(s->dfdv, dir,clmd->sim_parms->Cdis * 0.01); } - // printf("(dt*k*dt) ): %f, k: %f\n", (dt * (k*dt + 2 * clmd->sim_parms.Cdis * 0.01) ), k); + // printf("(dt*k*dt) ): %f, k: %f\n", (dt * (k*dt + 2 * clmd->sim_parms->Cdis * 0.01) ), k); } } else // calculate force of bending springs { if(length < L) { - // clmd->sim_parms.flags |= CLOTH_SIMSETTINGS_FLAG_BIG_FORCE; + // clmd->sim_parms->flags |= CLOTH_SIMSETTINGS_FLAG_BIG_FORCE; s->flags |= CLOTH_SPRING_FLAG_NEEDED; - k = fbstar(length, L, clmd->sim_parms.bending, cb); + k = fbstar(length, L, clmd->sim_parms->bending, cb); mul_fvector_S(bending_force, dir, k); VECADD(s->f, s->f, bending_force); // DG: My formula to handle bending for the AIMEX scheme // multiply with 1000 because of numerical problems - if( ((k*1000)*dt*dt) < -0.18 ) + // if( ((k*1000)*dt*dt) < -0.18 ) { - dfdx_spring_type2(s->dfdx, dir,length,L,clmd->sim_parms.bending, cb); - clmd->sim_parms.flags |= CLOTH_SIMSETTINGS_FLAG_BIG_FORCE; + dfdx_spring_type2(s->dfdx, dir,length,L,clmd->sim_parms->bending, cb); + clmd->sim_parms->flags |= CLOTH_SIMSETTINGS_FLAG_BIG_FORCE; } // printf("(dt*k*dt) ): %f, k: %f\n", (dt*dt*k*-1.0), k); } @@ -1282,7 +1411,7 @@ DO_INLINE int cloth_apply_spring_force(ClothModifierData *clmd, ClothSpring *s, sub_fmatrix_fmatrix(dFdV[s->kl].m, dFdV[s->kl].m, s->dfdv); add_fmatrix_fmatrix(dFdV[s->matrix_index].m, dFdV[s->matrix_index].m, s->dfdv); } - else if(!(clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_BIG_FORCE)) + else if(!(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_BIG_FORCE)) return 0; sub_fmatrix_fmatrix(dFdX[s->ij].m, dFdX[s->ij].m, s->dfdx); @@ -1340,9 +1469,9 @@ void cloth_calc_force(ClothModifierData *clmd, lfVector *lF, lfVector *lX, lfVec /* Collect forces and derivatives: F,dFdX,dFdV */ Cloth *cloth = clmd->clothObject; unsigned int i = 0; - float spring_air = clmd->sim_parms.Cvi * 0.01f; /* viscosity of air scaled in percent */ + float spring_air = clmd->sim_parms->Cvi * 0.01f; /* viscosity of air scaled in percent */ float gravity[3]; - float tm2[3][3] = {{-spring_air,0,0}, {0,-spring_air,0},{0,0,-spring_air}}; + float tm2[3][4] = {{-spring_air,0,0,0}, {0,-spring_air,0,0},{0,0,-spring_air,0}}; ClothVertex *verts = cloth->verts; MFace *mfaces = cloth->mfaces; float wind_normalized[3]; @@ -1351,7 +1480,7 @@ void cloth_calc_force(ClothModifierData *clmd, lfVector *lF, lfVector *lX, lfVec float kd, ks; LinkNode *search = cloth->springs; - VECCOPY(gravity, clmd->sim_parms.gravity); + VECCOPY(gravity, clmd->sim_parms->gravity); mul_fvector_S(gravity, gravity, 0.001f); /* scale gravity force */ /* set dFdX jacobi matrix to zero */ @@ -1364,7 +1493,7 @@ void cloth_calc_force(ClothModifierData *clmd, lfVector *lF, lfVector *lX, lfVec submul_lfvectorS(lF, lV, spring_air, numverts); /* do goal stuff */ - if(clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_GOAL) + if(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL) { for(i = 0; i < numverts; i++) { @@ -1376,12 +1505,12 @@ void cloth_calc_force(ClothModifierData *clmd, lfVector *lF, lfVector *lX, lfVec VECADD(tvect, tvect, cloth->xold[i]); VECSUB(auxvect, tvect, lX[i]); - ks = 1.0f/(1.0f- verts [i].goal*clmd->sim_parms.goalspring)-1.0f ; + ks = 1.0f/(1.0f- verts [i].goal*clmd->sim_parms->goalspring)-1.0f ; VECADDS(lF[i], lF[i], auxvect, -ks); // calulate damping forces generated by goals VECSUB(velgoal, cloth->xold[i], cloth->xconst[i]); - kd = clmd->sim_parms.goalfrict * 0.01f; // friction force scale taken from SB + kd = clmd->sim_parms->goalfrict * 0.01f; // friction force scale taken from SB VECSUBADDSS(lF[i], velgoal, kd, lV[i], kd); } @@ -1418,13 +1547,13 @@ void cloth_calc_force(ClothModifierData *clmd, lfVector *lF, lfVector *lX, lfVec while(search) { // only handle active springs - // if(((clmd->sim_parms.flags & CSIMSETT_FLAG_TEARING_ENABLED) && !(springs[i].flags & CSPRING_FLAG_DEACTIVATE))|| !(clmd->sim_parms.flags & CSIMSETT_FLAG_TEARING_ENABLED)){} + // if(((clmd->sim_parms->flags & CSIMSETT_FLAG_TEARING_ENABLED) && !(springs[i].flags & CSPRING_FLAG_DEACTIVATE))|| !(clmd->sim_parms->flags & CSIMSETT_FLAG_TEARING_ENABLED)){} cloth_calc_spring_force(clmd, search->link, lF, lX, lV, dFdV, dFdX, dt); search = search->next; } - if(clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_BIG_FORCE) + if(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_BIG_FORCE) { if(cloth->numspringssave != cloth->numsprings) { @@ -1444,46 +1573,62 @@ void cloth_calc_force(ClothModifierData *clmd, lfVector *lF, lfVector *lX, lfVec while(search) { // only handle active springs - // if(((clmd->sim_parms.flags & CSIMSETT_FLAG_TEARING_ENABLED) && !(springs[i].flags & CSPRING_FLAG_DEACTIVATE))|| !(clmd->sim_parms.flags & CSIMSETT_FLAG_TEARING_ENABLED)) + // if(((clmd->sim_parms->flags & CSIMSETT_FLAG_TEARING_ENABLED) && !(springs[i].flags & CSPRING_FLAG_DEACTIVATE))|| !(clmd->sim_parms->flags & CSIMSETT_FLAG_TEARING_ENABLED)) if(!cloth_apply_spring_force(clmd, search->link, lF, lX, lV, dFdV, dFdX)) break; search = search->next; } - clmd->sim_parms.flags &= ~CLOTH_SIMSETTINGS_FLAG_BIG_FORCE; + clmd->sim_parms->flags &= ~CLOTH_SIMSETTINGS_FLAG_BIG_FORCE; } + void simulate_implicit_euler(lfVector *Vnew, lfVector *lX, lfVector *lV, lfVector *lF, fmatrix3x3 *dFdV, fmatrix3x3 *dFdX, float dt, fmatrix3x3 *A, lfVector *B, lfVector *dV, fmatrix3x3 *S, lfVector *z, fmatrix3x3 *P, fmatrix3x3 *Pinv) { unsigned int numverts = dFdV[0].vcount; lfVector *dFdXmV = create_lfvector(numverts); + initdiag_bfmatrix(A, I); - // zero_lfvector(dV, numverts); - + subadd_bfmatrixS_bfmatrixS(A, dFdV, dt, dFdX, (dt*dt)); mul_bfmatrix_lfvector(dFdXmV, dFdX, lV); add_lfvectorS_lfvectorS(B, lF, dt, dFdXmV, (dt*dt), numverts); - itstart(); + cg_filtered(dV, A, B, z, S); // conjugate gradient algorithm to solve Ax=b + // cg_filtered_pre(dV, A, B, z, S, P, Pinv); - cg_filtered(dV, A, B, z, S); /* conjugate gradient algorithm to solve Ax=b */ - // cg_filtered_pre(dV, A, B, z, dV, P, Pinv, dt); - - itend(); - // printf("cg_filtered calc time: %f\n", (float)itval()); - - - // advance velocities add_lfvector_lfvector(Vnew, lV, dV, numverts); del_lfvector(dFdXmV); } +/* +// this version solves for the new velocity +void simulate_implicit_euler(lfVector *Vnew, lfVector *lX, lfVector *lV, lfVector *lF, fmatrix3x3 *dFdV, fmatrix3x3 *dFdX, float dt, fmatrix3x3 *A, lfVector *B, lfVector *dV, fmatrix3x3 *S, lfVector *z, fmatrix3x3 *P, fmatrix3x3 *Pinv) +{ + unsigned int numverts = dFdV[0].vcount; + + lfVector *dFdXmV = create_lfvector(numverts); + + initdiag_bfmatrix(A, I); + + subadd_bfmatrixS_bfmatrixS(A, dFdV, dt, dFdX, (dt*dt)); + + mul_bfmatrix_lfvector(dFdXmV, dFdV, lV); + + add_lfvectorS_lfvectorS(B, lF, dt, dFdXmV, -dt, numverts); + add_lfvector_lfvector(B, B, lV, numverts); + + cg_filtered_pre(Vnew, A, B, z, S, P, Pinv); + + del_lfvector(dFdXmV); +} +*/ int implicit_solver (Object *ob, float frame, ClothModifierData *clmd, ListBase *effectors) { unsigned int i=0; @@ -1491,13 +1636,13 @@ int implicit_solver (Object *ob, float frame, ClothModifierData *clmd, ListBase Cloth *cloth = clmd->clothObject; ClothVertex *verts = cloth->verts; unsigned int numverts = cloth->numverts; - float dt = 1.0f / clmd->sim_parms.stepsPerFrame; + float dt = 1.0f / clmd->sim_parms->stepsPerFrame; Implicit_Data *id = cloth->implicit; int result = 0; float force = 0, lastforce = 0; lfVector *dx; - if(clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_GOAL) /* do goal stuff */ + if(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL) /* do goal stuff */ { for(i = 0; i < numverts; i++) { @@ -1518,7 +1663,7 @@ int implicit_solver (Object *ob, float frame, ClothModifierData *clmd, ListBase cloth_calc_force(clmd, id->F, id->X, id->V, id->dFdV, id->dFdX, effectors, step, dt ); // check for sleeping - if(!(clmd->coll_parms.flags & CLOTH_SIMSETTINGS_FLAG_SLEEP)) + // if(!(clmd->coll_parms->flags & CLOTH_SIMSETTINGS_FLAG_SLEEP)) { simulate_implicit_euler(id->Vnew, id->X, id->V, id->F, id->dFdV, id->dFdX, dt, id->A, id->B, id->dV, id->S, id->z, id->P, id->Pinv); @@ -1530,14 +1675,16 @@ int implicit_solver (Object *ob, float frame, ClothModifierData *clmd, ListBase force = dot_lfvector(dx, dx, numverts); del_lfvector(dx); + /* if((force < 0.00001) && (lastforce >= force)) - clmd->coll_parms.flags |= CLOTH_SIMSETTINGS_FLAG_SLEEP; + clmd->coll_parms->flags |= CLOTH_SIMSETTINGS_FLAG_SLEEP; else if((lastforce*2 < force)) - clmd->coll_parms.flags &= ~CLOTH_SIMSETTINGS_FLAG_SLEEP; + */ + clmd->coll_parms->flags &= ~CLOTH_SIMSETTINGS_FLAG_SLEEP; lastforce = force; - if(clmd->coll_parms.flags & CLOTH_COLLISIONSETTINGS_FLAG_ENABLED) + if(clmd->coll_parms->flags & CLOTH_COLLISIONSETTINGS_FLAG_ENABLED) { // collisions // itstart(); @@ -1545,7 +1692,7 @@ int implicit_solver (Object *ob, float frame, ClothModifierData *clmd, ListBase // update verts to current positions for(i = 0; i < numverts; i++) { - if(clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_GOAL) /* do goal stuff */ + if(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL) /* do goal stuff */ { if(verts [i].goal >= SOFTGOALSNAP) { @@ -1615,7 +1762,7 @@ int implicit_solver (Object *ob, float frame, ClothModifierData *clmd, ListBase if(effectors) pdEndEffectors(effectors); } - if(clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_GOAL) + if(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL) { for(i = 0; i < numverts; i++) { @@ -1633,11 +1780,19 @@ int implicit_solver (Object *ob, float frame, ClothModifierData *clmd, ListBase } else { - memcpy(cloth->current_xold, id->X, sizeof(lfVector) * numverts); - memcpy(cloth->x, id->X, sizeof(lfVector) * numverts); + for(i = 0; i < numverts; i++) + { + VECCOPY(cloth->current_xold[i], id->X[i]); + VECCOPY(cloth->x[i], id->X[i]); + } + // memcpy(cloth->current_xold, id->X, sizeof(lfVector) * numverts); + // memcpy(cloth->x, id->X, sizeof(lfVector) * numverts); } - memcpy(cloth->v, id->V, sizeof(lfVector) * numverts); + for(i = 0; i < numverts; i++) + VECCOPY(cloth->v[i], id->V[i]); + + // memcpy(cloth->v, id->V, sizeof(lfVector) * numverts); return 1; } @@ -1645,11 +1800,18 @@ int implicit_solver (Object *ob, float frame, ClothModifierData *clmd, ListBase void implicit_set_positions (ClothModifierData *clmd) { Cloth *cloth = clmd->clothObject; - unsigned int numverts = cloth->numverts; + unsigned int numverts = cloth->numverts, i = 0; Implicit_Data *id = cloth->implicit; - memcpy(id->X, cloth->x, sizeof(lfVector) * numverts); - memcpy(id->V, cloth->v, sizeof(lfVector) * numverts); + + for(i = 0; i < numverts; i++) + { + VECCOPY(id->X[i], cloth->x[i]); + VECCOPY(id->V[i], cloth->v[i]); + } + + // memcpy(id->X, cloth->x, sizeof(lfVector) * numverts); + // memcpy(id->V, cloth->v, sizeof(lfVector) * numverts); } @@ -1668,7 +1830,7 @@ int collisions_collision_response_static(ClothModifierData *clmd, ClothModifierD cloth1 = clmd->clothObject; cloth2 = coll_clmd->clothObject; - // search = clmd->coll_parms.collision_list; + // search = clmd->coll_parms->collision_list; while(search) { @@ -1711,10 +1873,10 @@ int collisions_collision_response_static(ClothModifierData *clmd, ClothModifierD float vrel_t_pre[3]; float vrel_t[3]; double impulse; - float epsilon = clmd->coll_parms.epsilon; + float epsilon = clmd->coll_parms->epsilon; float overlap = (epsilon + ALMOST_ZERO-collpair->distance); - // calculateFrictionImpulse(tangential, relativeVelocity, collpair->normal, magrelVel, clmd->coll_parms.friction*0.01, magrelVel); + // calculateFrictionImpulse(tangential, relativeVelocity, collpair->normal, magrelVel, clmd->coll_parms->friction*0.01, magrelVel); // magtangent = INPR(tangential, tangential); @@ -1790,7 +1952,7 @@ void cloth_collision_static(ClothModifierData *clmd, LinkNode *collision_list) MFace *face1=NULL, *face2=NULL; ClothVertex *verts1=NULL, *verts2=NULL; double distance = 0; - float epsilon = clmd->coll_parms.epsilon; + float epsilon = clmd->coll_parms->epsilon; unsigned int i = 0; for(i = 0; i < 4; i++) @@ -1940,7 +2102,7 @@ void collisions_collision_moving_edges(ClothModifierData *clmd, ClothModifierDat MFace *face1=NULL, *face2=NULL; ClothVertex *verts1=NULL, *verts2=NULL; double distance = 0; - float epsilon = clmd->coll_parms.epsilon; + float epsilon = clmd->coll_parms->epsilon; unsigned int i = 0, j = 0, k = 0; int numsolutions = 0; float a[3], b[3], c[3], d[3], e[3], f[3], solution[3]; @@ -2077,7 +2239,7 @@ void collisions_collision_moving_tris(ClothModifierData *clmd, ClothModifierData MFace *face1=NULL, *face2=NULL; ClothVertex *verts1=NULL, *verts2=NULL; double distance = 0; - float epsilon = clmd->coll_parms.epsilon; + float epsilon = clmd->coll_parms->epsilon; unsigned int i = 0, j = 0, k = 0; int numsolutions = 0; float a[3], b[3], c[3], d[3], e[3], f[3], solution[3]; @@ -2184,11 +2346,11 @@ int cloth_bvh_objcollision(ClothModifierData * clmd, float step, float prevstep, CollisionModifierData *collmd = NULL; Cloth *cloth = NULL; Object *ob2 = NULL; - BVH *bvh1 = NULL, *bvh2 = NULL; + BVH *bvh1 = NULL, *bvh2 = NULL, *self_bvh; LinkNode *collision_list = NULL; unsigned int i = 0, j = 0; int collisions = 0, count = 0; - float (*current_x)[3]; + float (*current_x)[4]; if (!(((Cloth *)clmd->clothObject)->tree)) { @@ -2198,14 +2360,15 @@ int cloth_bvh_objcollision(ClothModifierData * clmd, float step, float prevstep, cloth = clmd->clothObject; bvh1 = cloth->tree; + self_bvh = cloth->selftree; //////////////////////////////////////////////////////////// // static collisions //////////////////////////////////////////////////////////// // update cloth bvh - bvh_update_from_float3(bvh1, cloth->current_xold, cloth->numverts, cloth->current_x, 0); // 0 means STATIC, 1 means MOVING (see later in this function) - + bvh_update_from_float4(bvh1, cloth->current_xold, cloth->numverts, cloth->current_x, 0); // 0 means STATIC, 1 means MOVING (see later in this function) +/* // check all collision objects for (base = G.scene->base.first; base; base = base->next) { @@ -2256,12 +2419,84 @@ int cloth_bvh_objcollision(ClothModifierData * clmd, float step, float prevstep, VECADD(cloth->current_x[i], cloth->current_xold[i], cloth->current_v[i]); } ////////////////////////////////////////////// +*/ + /* + // fill collision list + collisions += bvh_traverse(self_bvh->root, self_bvh->root, &collision_list); + // call static collision response + + // free collision list + if(collision_list) + { + LinkNode *search = collision_list; + + while(search) + { + float distance = 0; + float mindistance = cloth->selftree->epsilon; + CollisionPair *collpair = (CollisionPair *)search->link; + + // get distance of faces + distance = plNearestPoints( + cloth->current_x[collpair->point_indexA[0]], cloth->current_x[collpair->point_indexA[1]], cloth->current_x[collpair->point_indexA[2]], cloth->current_x[collpair->point_indexB[0]], cloth->current_x[collpair->point_indexB[1]], cloth->current_x[collpair->point_indexB[2]], collpair->pa,collpair->pb,collpair->vector); + + if(distance < mindistance) + { + /////////////////////////////////////////// + // TODO: take velocity of the collision points into account! + /////////////////////////////////////////// + + float correction = mindistance - distance; + float temp[3]; + + VECCOPY(temp, collpair->vector); + Normalize(temp); + VecMulf(temp, -correction*0.5); + + if(!((clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL) && (cloth->verts [collpair->point_indexA[0]].goal >= SOFTGOALSNAP))) + VECSUB(cloth->current_x[collpair->point_indexA[0]], cloth->current_x[collpair->point_indexA[0]], temp); + + if(!((clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL) && (cloth->verts [collpair->point_indexA[1]].goal >= SOFTGOALSNAP))) + VECSUB(cloth->current_x[collpair->point_indexA[1]], cloth->current_x[collpair->point_indexA[1]], temp); + + if(!((clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL) && (cloth->verts [collpair->point_indexA[2]].goal >= SOFTGOALSNAP))) + VECSUB(cloth->current_x[collpair->point_indexA[2]], cloth->current_x[collpair->point_indexA[2]], temp); + + + if(!((clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL) && (cloth->verts [collpair->point_indexB[0]].goal >= SOFTGOALSNAP))) + VECSUB(cloth->current_x[collpair->point_indexB[0]], cloth->current_x[collpair->point_indexB[0]], temp); + + if(!((clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL) && (cloth->verts [collpair->point_indexB[1]].goal >= SOFTGOALSNAP))) + VECSUB(cloth->current_x[collpair->point_indexB[1]], cloth->current_x[collpair->point_indexB[1]], temp); + + if(!((clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL) && (cloth->verts [collpair->point_indexB[2]].goal >= SOFTGOALSNAP))) + VECSUB(cloth->current_x[collpair->point_indexB[2]], cloth->current_x[collpair->point_indexB[2]], temp); + + collisions = 1; + + } + + } + + search = collision_list; + while(search) + { + CollisionPair *coll_pair = search->link; + + MEM_freeN(coll_pair); + search = search->next; + } + BLI_linklist_free(collision_list,NULL); + + collision_list = NULL; + } + */ // Test on *simple* selfcollisions collisions = 1; count = 0; current_x = cloth->current_x; // needed for openMP - +/* #pragma omp parallel for private(i,j, collisions) shared(current_x) for(count = 0; count < 6; count++) { @@ -2275,7 +2510,7 @@ int cloth_bvh_objcollision(ClothModifierData * clmd, float step, float prevstep, float length = 0; float mindistance = cloth->selftree->epsilon; - if(clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_GOAL) + if(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL) { if((cloth->verts [i].goal >= SOFTGOALSNAP) && (cloth->verts [j].goal >= SOFTGOALSNAP)) @@ -2298,12 +2533,12 @@ int cloth_bvh_objcollision(ClothModifierData * clmd, float step, float prevstep, { float correction = mindistance - length; - if((clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_GOAL) && (cloth->verts [i].goal >= SOFTGOALSNAP)) + if((clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL) && (cloth->verts [i].goal >= SOFTGOALSNAP)) { VecMulf(temp, -correction); VECADD(current_x[j], current_x[j], temp); } - else if((clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_GOAL) && (cloth->verts [j].goal >= SOFTGOALSNAP)) + else if((clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL) && (cloth->verts [j].goal >= SOFTGOALSNAP)) { VecMulf(temp, correction); VECADD(current_x[i], current_x[i], temp); @@ -2320,12 +2555,8 @@ int cloth_bvh_objcollision(ClothModifierData * clmd, float step, float prevstep, } } } - /* - // does not compile with OpenMP - if(!collisions) - break; - */ } + ////////////////////////////////////////////// // SELFCOLLISIONS: update velocities @@ -2335,6 +2566,6 @@ int cloth_bvh_objcollision(ClothModifierData * clmd, float step, float prevstep, VECSUB(cloth->current_v[i], cloth->current_x[i], cloth->current_xold[i]); } ////////////////////////////////////////////// - +*/ return 1; } diff --git a/source/blender/blenkernel/intern/kdop.c b/source/blender/blenkernel/intern/kdop.c index e168d3a9954..234a6b75548 100644 --- a/source/blender/blenkernel/intern/kdop.c +++ b/source/blender/blenkernel/intern/kdop.c @@ -751,6 +751,58 @@ BVH *bvh_build_from_float3 (MFace *mfaces, unsigned int numfaces, float (*x)[3], return bvh_build(bvh, mfaces, numfaces); } +BVH *bvh_build_from_float4 (MFace *mfaces, unsigned int numfaces, float (*x)[4], unsigned int numverts, float epsilon) +{ + BVH *bvh=NULL; + CollisionTree *tree=NULL; + unsigned int i = 0; + + bvh = MEM_callocN(sizeof(BVH), "BVH"); + if (bvh == NULL) + { + printf("bvh: Out of memory.\n"); + return NULL; + } + + bvh->flags = 0; + bvh->leaf_tree = NULL; + bvh->leaf_root = NULL; + bvh->tree = NULL; + + bvh->epsilon = epsilon; + bvh->numfaces = numfaces; + bvh->mfaces = mfaces; + + // we have no faces, we save seperate points + if(!mfaces) + { + bvh->numfaces = numverts; + } + + bvh->numverts = numverts; + bvh->xnew = (MVert *)MEM_callocN(sizeof(MVert)*numverts, "BVH MVert"); + + for(i = 0; i < numverts; i++) + { + VECCOPY(bvh->xnew[i].co, x[i]); + } + + bvh->x = MEM_dupallocN(bvh->xnew); + + tree = (CollisionTree *)MEM_callocN(sizeof(CollisionTree), "CollisionTree"); + + if (tree == NULL) + { + printf("bvh_build: Out of memory for nodes.\n"); + bvh_free(bvh); + return NULL; + } + + BLI_linklist_append(&bvh->tree, tree); + + return bvh_build(bvh, mfaces, numfaces); +} + // bvh_overlap - is it possbile for 2 bv's to collide ? int bvh_overlap(float *bv1, float *bv2) { @@ -789,23 +841,80 @@ int bvh_traverse(CollisionTree *tree1, CollisionTree *tree2, LinkNode **collisio // Check if this node in the second tree a leaf if (tree2->isleaf) { + ////////////////////////////////// + // TODO: check for 3rd point if zero (triangle)!!! + ////////////////////////////////// + CollisionPair *collpair = NULL; if(tree1 != tree2) // do not collide same points { + //////////////////////////////////////// + // FIRST FACE + //////////////////////////////////////// + // save potential colliding triangles collpair = (CollisionPair *)MEM_callocN(sizeof(CollisionPair), "CollisionPair"); VECCOPY(collpair->point_indexA, tree1->point_index); - collpair->point_indexA[3] = tree1->point_index[3]; - VECCOPY(collpair->point_indexB, tree2->point_index); - collpair->point_indexB[3] = tree2->point_index[3]; // we use prepend because lots of insertions at end // of list are horrible slow! BLI_linklist_prepend(&collision_list[0], collpair); + //////////////////////////////////////// + // SECOND FACE + //////////////////////////////////////// + if(tree1->point_index[3]) // check for quad face + { + // save potential colliding triangles + collpair = (CollisionPair *)MEM_callocN(sizeof(CollisionPair), "CollisionPair"); + + VECCOPY(collpair->point_indexA, tree1->point_index); + collpair->point_indexA[2] = tree1->point_index[3]; + + VECCOPY(collpair->point_indexB, tree2->point_index); + + // we use prepend because lots of insertions at end + // of list are horrible slow! + BLI_linklist_prepend(&collision_list[0], collpair); + } + //////////////////////////////////////// + // THIRD FACE + //////////////////////////////////////// + if(tree2->point_index[3]) // check for quad face + { + // save potential colliding triangles + collpair = (CollisionPair *)MEM_callocN(sizeof(CollisionPair), "CollisionPair"); + + VECCOPY(collpair->point_indexA, tree1->point_index); + + VECCOPY(collpair->point_indexB, tree2->point_index); + collpair->point_indexB[2] = tree2->point_index[3]; + + // we use prepend because lots of insertions at end + // of list are horrible slow! + BLI_linklist_prepend(&collision_list[0], collpair); + } + //////////////////////////////////////// + // FOURTH FACE + //////////////////////////////////////// + if(tree1->point_index[3] && tree1->point_index[3]) // check for quad face + { + // save potential colliding triangles + collpair = (CollisionPair *)MEM_callocN(sizeof(CollisionPair), "CollisionPair"); + + VECCOPY(collpair->point_indexA, tree1->point_index); + collpair->point_indexA[2] = tree1->point_index[3]; + + VECCOPY(collpair->point_indexB, tree2->point_index); + collpair->point_indexB[2] = tree2->point_index[3]; + + // we use prepend because lots of insertions at end + // of list are horrible slow! + BLI_linklist_prepend(&collision_list[0], collpair); + } return 1; } else @@ -965,3 +1074,29 @@ void bvh_update_from_float3(BVH * bvh, float (*x)[3], unsigned int numverts, flo bvh_update(bvh, moving); } + +void bvh_update_from_float4(BVH * bvh, float (*x)[4], unsigned int numverts, float (*xnew)[4], int moving) +{ + unsigned int i = 0; + + if(!bvh) + return; + + if(numverts!=bvh->numverts) + return; + + if(x) + { + for(i = 0; i < numverts; i++) + VECCOPY(bvh->x[i].co, x[i]); + } + + if(xnew) + { + for(i = 0; i < numverts; i++) + VECCOPY(bvh->xnew[i].co, xnew[i]); + } + + bvh_update(bvh, moving); +} + diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c index 531cd78b3b2..f599edf52d9 100644 --- a/source/blender/blenkernel/intern/modifier.c +++ b/source/blender/blenkernel/intern/modifier.c @@ -4865,6 +4865,12 @@ static void softbodyModifier_deformVerts( static void clothModifier_initData(ModifierData *md) { ClothModifierData *clmd = (ClothModifierData*) md; + + clmd->sim_parms = MEM_callocN(sizeof(SimulationSettings), + "cloth sim parms"); + clmd->coll_parms = MEM_callocN(sizeof(CollisionSettings), + "cloth coll parms"); + cloth_init (clmd); } /* @@ -4942,8 +4948,8 @@ CustomDataMask clothModifier_requiredDataMask(ModifierData *md) CustomDataMask dataMask = 0; /* ask for vertexgroups if we need them */ - if(clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_GOAL) - if (clmd->sim_parms.vgroup_mass > 0) + if(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL) + if (clmd->sim_parms->vgroup_mass > 0) dataMask |= (1 << CD_MDEFORMVERT); return dataMask; @@ -4961,8 +4967,12 @@ static void clothModifier_freeData(ModifierData *md) if (clmd) { - clmd->sim_parms.flags &= ~CLOTH_SIMSETTINGS_FLAG_CCACHE_PROTECT; + + clmd->sim_parms->flags &= ~CLOTH_SIMSETTINGS_FLAG_CCACHE_PROTECT; cloth_free_modifier (clmd); + + MEM_freeN(clmd->sim_parms); + MEM_freeN(clmd->coll_parms); } } diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 8ee70d4efd2..afe342d8665 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -2885,13 +2885,10 @@ static void direct_link_modifiers(FileData *fd, ListBase *lb) ClothModifierData *clmd = (ClothModifierData*) md; clmd->clothObject = NULL; - clmd->sim_parms.cache = NULL; - - if (clmd->sim_parms.cache) { - // TODO - // clmd->cache = newdataadr (fd, clmd->cache); - printf ("direct_link_modifiers: read cloth baked_data.\n"); - } + + clmd->sim_parms= newdataadr(fd, clmd->sim_parms); + clmd->coll_parms= newdataadr(fd, clmd->coll_parms); + } else if (md->type==eModifierType_Collision) { CollisionModifierData *collmd = (CollisionModifierData*) md; diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c index 1887f95e1da..64849affdbf 100644 --- a/source/blender/blenloader/intern/writefile.c +++ b/source/blender/blenloader/intern/writefile.c @@ -771,23 +771,6 @@ static void write_constraint_channels(WriteData *wd, ListBase *chanbase) } -/* -// TODO: finish this -static void write_cloth_cache(WriteData *wd, LinkNode *ln) -{ - - while(ln) { - writestruct(wd, DATA, "cloth_cache", 1, ln); - writestruct(wd, DATA, "cloth_cache_frame", 1, ln->link); - writestruct(wd, DATA, "cloth_cache_frame_verts", 1, ln->link); - writestruct(wd, DATA, "cloth_cache_frame_springs", 1, ln->link); - } - - ln = ln->next; - } -} -*/ - static void write_modifiers(WriteData *wd, ListBase *modbase) { ModifierData *md; @@ -803,28 +786,15 @@ static void write_modifiers(WriteData *wd, ListBase *modbase) HookModifierData *hmd = (HookModifierData*) md; writedata(wd, DATA, sizeof(int)*hmd->totindex, hmd->indexar); - } - else if (md->type==eModifierType_Cloth) { - int n; - ClothModifierData *clmd = (ClothModifierData *) md; - - if (clmd->sim_parms.cache) { - // Compute the number of vertices we're saving. - // TODO - // write_cloth_cache(); - /* - // old code - n = (clmd->sim_parms.bake_end_frame - clmd->sim_parms.bake_start_frame + 1) * - clmd->sim_parms.bake_num_verts; - writedata (wd, DATA, n * sizeof (clmd->baked_data [0]), clmd->baked_data); - printf ("write_modifiers: wrote %d elements of size %d for cloth baked data.\n", - n, sizeof (clmd->baked_data [0])); - */ - } } + else if(md->type==eModifierType_Cloth) { + ClothModifierData *clmd = (ClothModifierData*) md; + writestruct(wd, DATA, "SimulationSettings", 1, clmd->sim_parms); + writestruct(wd, DATA, "CollisionSettings", 1, clmd->coll_parms); + } else if (md->type==eModifierType_MeshDeform) { MeshDeformModifierData *mmd = (MeshDeformModifierData*) md; - + writedata(wd, DATA, sizeof(float)*mmd->totvert*mmd->totcagevert, mmd->bindweights); writedata(wd, DATA, sizeof(float)*3*mmd->totcagevert, diff --git a/source/blender/makesdna/DNA_cloth_types.h b/source/blender/makesdna/DNA_cloth_types.h index 2441c8b721f..4d8fbf1a6fc 100644 --- a/source/blender/makesdna/DNA_cloth_types.h +++ b/source/blender/makesdna/DNA_cloth_types.h @@ -32,55 +32,7 @@ #ifndef DNA_CLOTH_TYPES_H #define DNA_CLOTH_TYPES_H -#include "DNA_listBase.h" - - -/** -* Pin and unpin frames are the frames on which the vertices stop moving. -* They will assume the position they had prior to pinFrame until unpinFrame -* is reached. -*/ -typedef struct ClothVertex -{ - int flags; /* General flags per vertex. */ - float mass; /* mass / weight of the vertex */ - float goal; /* goal, from SB */ - float impulse[3]; /* used in collision.c */ - unsigned int impulse_count; /* same as above */ -} ClothVertex; - - -/** -* The definition of a spring. -*/ -typedef struct ClothSpring -{ - int ij; /* Pij from the paper, one end of the spring. */ - int kl; /* Pkl from the paper, one end of the spring. */ - float restlen; /* The original length of the spring. */ - int matrix_index; /* needed for implicit solver (fast lookup) */ - int type; /* types defined in BKE_cloth.h ("springType") */ - int flags; /* defined in BKE_cloth.h, e.g. deactivated due to tearing */ - float dfdx[3][3]; - float dfdv[3][3]; - float f[3]; -} ClothSpring; - - - -/** -* This struct contains all the global data required to run a simulation. -* At the time of this writing, this structure contains data appropriate -* to run a simulation as described in Deformation Constraints in a -* Mass-Spring Model to Describe Rigid Cloth Behavior by Xavier Provot. -* -* I've tried to keep similar, if not exact names for the variables as -* are presented in the paper. Where I've changed the concept slightly, -* as in stepsPerFrame comapred to the time step in the paper, I've used -* variables with different names to minimize confusion. -**/ -typedef struct SimulationSettings -{ +typedef struct SimulationSettings { short vgroup_mass; /* optional vertexgroup name for assigning weight. */ short pad; float mingoal; /* see SB */ @@ -103,7 +55,6 @@ typedef struct SimulationSettings float eff_force_scale;/* Scaling of effector forces (see softbody_calc_forces).*/ float eff_wind_scale; /* Scaling of effector wind (see softbody_calc_forces). */ float sim_time_old; - struct LinkNode *cache; float defgoal; float goalfrict; float goalspring; @@ -112,9 +63,7 @@ typedef struct SimulationSettings int firstframe; /* frame on which simulation starts */ } SimulationSettings; - -typedef struct CollisionSettings -{ +typedef struct CollisionSettings { float epsilon; /* The radius of a particle in the cloth. */ float self_friction; /* Fiction/damping with self contact. */ float friction; /* Friction/damping applied on contact with other object.*/ @@ -125,40 +74,4 @@ typedef struct CollisionSettings } CollisionSettings; -/** -* This structure describes a cloth object against which the -* simulation can run. -* -* The m and n members of this structure represent the assumed -* rectangular ordered grid for which the original paper is written. -* At some point they need to disappear and we need to determine out -* own connectivity of the mesh based on the actual edges in the mesh. -* -**/ -typedef struct Cloth -{ - struct ClothVertex *verts; /* The vertices that represent this cloth. */ - struct LinkNode *springs; /* The springs connecting the mesh. */ - unsigned int numverts; /* The number of verts == m * n. */ - unsigned int numsprings; /* The count of springs. */ - unsigned int numfaces; - unsigned char old_solver_type; - unsigned char pad2; - short pad3; - struct BVH *tree; /* collision tree for this cloth object */ - struct BVH *selftree; /* self collision tree for this cloth object */ - struct MFace *mfaces; - struct Implicit_Data *implicit; /* our implicit solver connects to this pointer */ - float (*x)[3]; /* The current position of all vertices.*/ - float (*xold)[3]; /* The previous position of all vertices.*/ - float (*current_x)[3]; /* The TEMPORARY current position of all vertices.*/ - float (*current_xold)[3]; /* The TEMPORARY previous position of all vertices.*/ - float (*v)[3]; /* the current velocity of all vertices */ - float (*current_v)[3]; - float (*xconst)[3]; - struct EdgeHash *edgehash; /* used for fast checking adjacent points */ - unsigned int numothersprings; - unsigned int numspringssave; -} Cloth; - #endif diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h index ea7e67ddac4..48069f2d7b7 100644 --- a/source/blender/makesdna/DNA_modifier_types.h +++ b/source/blender/makesdna/DNA_modifier_types.h @@ -9,8 +9,6 @@ /* WARNING ALERT! TYPEDEF VALUES ARE WRITTEN IN FILES! SO DO NOT CHANGE! */ -#include "DNA_cloth_types.h" - typedef enum ModifierType { eModifierType_None = 0, eModifierType_Subsurf, @@ -343,10 +341,10 @@ typedef struct SoftbodyModifierData { typedef struct ClothModifierData { ModifierData modifier; - - struct Cloth *clothObject; /* The internal data structure for cloth. */ - SimulationSettings sim_parms; /* definition is in DNA_cloth_types.h */ - CollisionSettings coll_parms; /* definition is in DNA_cloth_types.h */ + + struct Cloth *clothObject; /* The internal data structure for cloth. */ + struct SimulationSettings *sim_parms; /* definition is in DNA_cloth_types.h */ + struct CollisionSettings *coll_parms; /* definition is in DNA_cloth_types.h */ } ClothModifierData; typedef struct CollisionModifierData { diff --git a/source/blender/src/buttons_object.c b/source/blender/src/buttons_object.c index 2d5b54ac1c2..3adc2862a94 100644 --- a/source/blender/src/buttons_object.c +++ b/source/blender/src/buttons_object.c @@ -2208,7 +2208,8 @@ void do_object_panels(unsigned short event) ClothModifierData *clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth); if(clmd) { - if(clmd->sim_parms.cache) + /* + if(clmd->sim_parms->cache) { CFRA= 1; update_for_newframe_muted(); @@ -2216,6 +2217,7 @@ void do_object_panels(unsigned short event) allqueue(REDRAWBUTSOBJECT, 0); allqueue(REDRAWVIEW3D, 0); } + */ } } break; @@ -2224,7 +2226,7 @@ void do_object_panels(unsigned short event) ClothModifierData *clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth); if(clmd) { - clmd->sim_parms.vgroup_mass = 0; + clmd->sim_parms->vgroup_mass = 0; do_object_panels(B_CLOTH_RENEW); } @@ -3158,9 +3160,9 @@ static void object_panel_cloth(Object *ob) if(clmd) { - // but = uiDefButBitI(block, TOG, CLOTH_SIMSETTINGS_FLAG_COLLOBJ, B_EFFECT_DEP, "Collision Object", 170,200,130,20, &clmd->sim_parms.flags, 0, 0, 0, 0, "Sets object to become a cloth collision object"); + // but = uiDefButBitI(block, TOG, CLOTH_SIMSETTINGS_FLAG_COLLOBJ, B_EFFECT_DEP, "Collision Object", 170,200,130,20, &clmd->sim_parms->flags, 0, 0, 0, 0, "Sets object to become a cloth collision object"); - if (!(clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_COLLOBJ)) + if (!(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_COLLOBJ)) { Cloth *cloth = clmd->clothObject; int defCount; @@ -3169,18 +3171,18 @@ static void object_panel_cloth(Object *ob) val2=0; - // uiDefButBitI(block, TOG, CSIMSETT_FLAG_ADVANCED, REDRAWBUTSOBJECT, "Advanced", 180,200,130,20, &clmd->sim_parms.flags, 0, 0, 0, 0, "Enable advanced mode"); + // uiDefButBitI(block, TOG, CSIMSETT_FLAG_ADVANCED, REDRAWBUTSOBJECT, "Advanced", 180,200,130,20, &clmd->sim_parms->flags, 0, 0, 0, 0, "Enable advanced mode"); /* GENERAL STUFF */ uiClearButLock(); uiBlockBeginAlign(block); - uiDefButF(block, NUM, B_CLOTH_RENEW, "StructStiff:", 10,170,150,20, &clmd->sim_parms.structural, 1.0, 10000.0, 100, 0, "Overall stiffness of structure"); - uiDefButF(block, NUM, B_CLOTH_RENEW, "BendStiff:", 160,170,150,20, &clmd->sim_parms.bending, 0.0, 10000.0, 1000, 0, "Wrinkle possibility"); - uiDefButI(block, NUM, B_CLOTH_RENEW, "Quality:", 10,150,150,20, &clmd->sim_parms.stepsPerFrame, 3.0, 10.0, 5, 0, "Quality of the simulation (higher=>better=>slower)"); + uiDefButF(block, NUM, B_CLOTH_RENEW, "StructStiff:", 10,170,150,20, &clmd->sim_parms->structural, 1.0, 10000.0, 100, 0, "Overall stiffness of structure"); + uiDefButF(block, NUM, B_CLOTH_RENEW, "BendStiff:", 160,170,150,20, &clmd->sim_parms->bending, 0.0, 10000.0, 1000, 0, "Wrinkle possibility"); + uiDefButI(block, NUM, B_CLOTH_RENEW, "Quality:", 10,150,150,20, &clmd->sim_parms->stepsPerFrame, 3.0, 10.0, 5, 0, "Quality of the simulation (higher=>better=>slower)"); uiBlockEndAlign(block); uiBlockBeginAlign(block); - uiDefButF(block, NUM, B_CLOTH_RENEW, "Spring Damp:", 160,150,150,20, &clmd->sim_parms.Cdis, 0.0, 10.0, 10, 0, "Spring damping"); - uiDefButF(block, NUM, B_DIFF, "Air Damp:", 10,130,150,20, &clmd->sim_parms.Cvi, 0.0, 10.0, 10, 0, "Apply gravitation to point movement"); + uiDefButF(block, NUM, B_CLOTH_RENEW, "Spring Damp:", 160,150,150,20, &clmd->sim_parms->Cdis, 0.0, 10.0, 10, 0, "Spring damping"); + uiDefButF(block, NUM, B_DIFF, "Air Damp:", 10,130,150,20, &clmd->sim_parms->Cvi, 0.0, 10.0, 10, 0, "Apply gravitation to point movement"); uiBlockEndAlign(block); uiClearButLock(); @@ -3189,15 +3191,15 @@ static void object_panel_cloth(Object *ob) uiDefBut(block, LABEL, 0, "Gravity:", 10,100,60,20, NULL, 0.0, 0, 0, 0, ""); // uiClearButLock(); - uiDefButF(block, NUM, B_CLOTH_RENEW, "X:", 70,100,80,20, &clmd->sim_parms.gravity[0], -100.0, 100.0, 10, 0, "Apply gravitation to point movement"); - uiDefButF(block, NUM, B_CLOTH_RENEW, "Y:", 150,100,80,20, &clmd->sim_parms.gravity[1], -100.0, 100.0, 10, 0, "Apply gravitation to point movement"); - uiDefButF(block, NUM, B_CLOTH_RENEW, "Z:", 230,100,80,20, &clmd->sim_parms.gravity[2], -100.0, 100.0, 10, 0, "Apply gravitation to point movement"); + uiDefButF(block, NUM, B_CLOTH_RENEW, "X:", 70,100,80,20, &clmd->sim_parms->gravity[0], -100.0, 100.0, 10, 0, "Apply gravitation to point movement"); + uiDefButF(block, NUM, B_CLOTH_RENEW, "Y:", 150,100,80,20, &clmd->sim_parms->gravity[1], -100.0, 100.0, 10, 0, "Apply gravitation to point movement"); + uiDefButF(block, NUM, B_CLOTH_RENEW, "Z:", 230,100,80,20, &clmd->sim_parms->gravity[2], -100.0, 100.0, 10, 0, "Apply gravitation to point movement"); uiBlockEndAlign(block); /* GOAL STUFF */ uiBlockBeginAlign(block); - uiDefButBitI(block, TOG, CLOTH_SIMSETTINGS_FLAG_GOAL, REDRAWVIEW3D, "Use Goal", 10,70,130,20, &clmd->sim_parms.flags, 0, 0, 0, 0, "Define forces for vertices to stick to animated position"); - if (clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_GOAL) + uiDefButBitI(block, TOG, CLOTH_SIMSETTINGS_FLAG_GOAL, REDRAWVIEW3D, "Use Goal", 10,70,130,20, &clmd->sim_parms->flags, 0, 0, 0, 0, "Define forces for vertices to stick to animated position"); + if (clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL) { if(ob->type==OB_MESH) { @@ -3212,17 +3214,17 @@ static void object_panel_cloth(Object *ob) defCount = BLI_countlist (&ob->defbase); if (defCount == 0) { - clmd->sim_parms.vgroup_mass = 0; + clmd->sim_parms->vgroup_mass = 0; } sprintf (clvg2, "%s%s", clmvg, clvg1); - uiDefButS(block, MENU, B_CLOTH_RENEW, clvg2, 140,70,20,20, &clmd->sim_parms.vgroup_mass, 0, defCount, 0, 0, "Browses available vertex groups"); + uiDefButS(block, MENU, B_CLOTH_RENEW, clvg2, 140,70,20,20, &clmd->sim_parms->vgroup_mass, 0, defCount, 0, 0, "Browses available vertex groups"); MEM_freeN (clvg1); MEM_freeN (clvg2); - if(clmd->sim_parms.vgroup_mass) + if(clmd->sim_parms->vgroup_mass) { - bDeformGroup *defGroup = BLI_findlink(&ob->defbase, clmd->sim_parms.vgroup_mass-1); + bDeformGroup *defGroup = BLI_findlink(&ob->defbase, clmd->sim_parms->vgroup_mass-1); if(defGroup) uiDefBut(block, BUT, B_DIFF, defGroup->name, 160,70,130,20, NULL, 0.0, 0.0, 0, 0, "Name of current vertex group"); else @@ -3232,30 +3234,30 @@ static void object_panel_cloth(Object *ob) } else - uiDefButF(block, NUM, B_CLOTH_RENEW, "Goal:", 160,70,150,20, &clmd->sim_parms.defgoal, 0.0, 1.0, 10, 0, "Default Goal (vertex target position) value, when no Vertex Group used"); + uiDefButF(block, NUM, B_CLOTH_RENEW, "Goal:", 160,70,150,20, &clmd->sim_parms->defgoal, 0.0, 1.0, 10, 0, "Default Goal (vertex target position) value, when no Vertex Group used"); } else { - uiDefButS(block, TOG, B_CLOTH_RENEW, "W", 140,70,20,20, &clmd->sim_parms.vgroup_mass, 0, 1, 0, 0, "Use control point weight values"); - uiDefButF(block, NUM, B_CLOTH_RENEW, "Goal:", 160,70,150,20, &clmd->sim_parms.defgoal, 0.0, 1.0, 10, 0, "Default Goal (vertex target position) value, when no Vertex Group used"); + uiDefButS(block, TOG, B_CLOTH_RENEW, "W", 140,70,20,20, &clmd->sim_parms->vgroup_mass, 0, 1, 0, 0, "Use control point weight values"); + uiDefButF(block, NUM, B_CLOTH_RENEW, "Goal:", 160,70,150,20, &clmd->sim_parms->defgoal, 0.0, 1.0, 10, 0, "Default Goal (vertex target position) value, when no Vertex Group used"); } - uiDefButF(block, NUM, B_CLOTH_RENEW, "G Stiff:", 10,50,150,20, &clmd->sim_parms.goalspring, 0.0, 500.0, 10, 0, "Goal (vertex target position) spring stiffness"); - uiDefButF(block, NUM, B_CLOTH_RENEW, "G Damp:", 160,50,150,20, &clmd->sim_parms.goalfrict, 0.0, 50.0, 10, 0, "Goal (vertex target position) friction"); - uiDefButF(block, NUM, B_CLOTH_RENEW, "G Min:", 10,30,150,20, &clmd->sim_parms.mingoal, 0.0, 1.0, 10, 0, "Goal minimum, vertex group weights are scaled to match this range"); - uiDefButF(block, NUM, B_CLOTH_RENEW, "G Max:", 160,30,150,20, &clmd->sim_parms.maxgoal, 0.0, 1.0, 10, 0, "Goal maximum, vertex group weights are scaled to match this range"); + uiDefButF(block, NUM, B_CLOTH_RENEW, "G Stiff:", 10,50,150,20, &clmd->sim_parms->goalspring, 0.0, 500.0, 10, 0, "Goal (vertex target position) spring stiffness"); + uiDefButF(block, NUM, B_CLOTH_RENEW, "G Damp:", 160,50,150,20, &clmd->sim_parms->goalfrict, 0.0, 50.0, 10, 0, "Goal (vertex target position) friction"); + uiDefButF(block, NUM, B_CLOTH_RENEW, "G Min:", 10,30,150,20, &clmd->sim_parms->mingoal, 0.0, 1.0, 10, 0, "Goal minimum, vertex group weights are scaled to match this range"); + uiDefButF(block, NUM, B_CLOTH_RENEW, "G Max:", 160,30,150,20, &clmd->sim_parms->maxgoal, 0.0, 1.0, 10, 0, "Goal maximum, vertex group weights are scaled to match this range"); } uiBlockEndAlign(block); /* // no tearing supported anymore since modifier stack restrictions uiBlockBeginAlign(block); - uiDefButBitI(block, TOG, CSIMSETT_FLAG_TEARING_ENABLED, B_EFFECT_DEP, "Tearing", 10,0,150,20, &clmd->sim_parms.flags, 0, 0, 0, 0, "Sets object to become a cloth collision object"); + uiDefButBitI(block, TOG, CSIMSETT_FLAG_TEARING_ENABLED, B_EFFECT_DEP, "Tearing", 10,0,150,20, &clmd->sim_parms->flags, 0, 0, 0, 0, "Sets object to become a cloth collision object"); - if (clmd->sim_parms.flags & CSIMSETT_FLAG_TEARING_ENABLED) + if (clmd->sim_parms->flags & CSIMSETT_FLAG_TEARING_ENABLED) { - uiDefButI(block, NUM, B_DIFF, "Max extent:", 160,0,150,20, &clmd->sim_parms.maxspringlen, 1.0, 1000.0, 10, 0, "Maximum extension before spring gets cut"); + uiDefButI(block, NUM, B_DIFF, "Max extent:", 160,0,150,20, &clmd->sim_parms->maxspringlen, 1.0, 1000.0, 10, 0, "Maximum extension before spring gets cut"); } uiBlockEndAlign(block); @@ -3275,7 +3277,7 @@ static void object_panel_cloth_II(Object *ob) clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth); if(clmd) { - if (!(clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_COLLOBJ)) + if (!(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_COLLOBJ)) { Cloth *cloth = clmd->clothObject; char str[128]; @@ -3286,18 +3288,18 @@ static void object_panel_cloth_II(Object *ob) uiSetButLock(object_data_is_libdata(ob), ERROR_LIBDATA_MESSAGE); - uiDefButI(block, NUM, B_DIFF, "First Frame:", 10,160,150,20, &clmd->sim_parms.firstframe, 0, MAXFRAME, 1, 0, "Frame on which the simulation starts"); - uiDefButI(block, NUM, B_DIFF, "Last Frame:", 160,160,150,20, &clmd->sim_parms.lastframe, 0, MAXFRAME, 10, 0, "Frame on which the simulation stops"); - - if(clmd->sim_parms.cache) + uiDefButI(block, NUM, B_DIFF, "First Frame:", 10,160,150,20, &clmd->sim_parms->firstframe, 0, MAXFRAME, 1, 0, "Frame on which the simulation starts"); + uiDefButI(block, NUM, B_DIFF, "Last Frame:", 160,160,150,20, &clmd->sim_parms->lastframe, 0, MAXFRAME, 10, 0, "Frame on which the simulation stops"); + /* + if(clmd->sim_parms->cache) { - int length = BLI_linklist_length(clmd->sim_parms.cache); + int length = BLI_linklist_length(clmd->sim_parms->cache); - /* correct spelling if only 1 frame cacheed --> only gimmick */ - if(length-clmd->sim_parms.preroll>1) - sprintf (str, "Frame 1 - %d cached. [%d in preroll, %d in total]", length-clmd->sim_parms.preroll, clmd->sim_parms.preroll, length); + // correct spelling if only 1 frame cacheed --> only gimmick + if(length-clmd->sim_parms->preroll>1) + sprintf (str, "Frame 1 - %d cached. [%d in preroll, %d in total]", length-clmd->sim_parms->preroll, clmd->sim_parms->preroll, length); else - sprintf (str, "Frame %d cached. [%d in preroll, %d in total]", length-clmd->sim_parms.preroll, clmd->sim_parms.preroll, length); + sprintf (str, "Frame %d cached. [%d in preroll, %d in total]", length-clmd->sim_parms->preroll, clmd->sim_parms->preroll, length); uiDefBut(block, LABEL, 0, str, 10,140,290,20, NULL, 0.0, 0, 0, 0, ""); uiDefBut(block, LABEL, 0, "Clear cache:", 10,120,290,20, NULL, 0.0, 0, 0, 0, ""); @@ -3305,15 +3307,15 @@ static void object_panel_cloth_II(Object *ob) uiDefBut(block, BUT, B_CLOTH_CLEARCACHEALL, "All", 10, 100,145,20, NULL, 0.0, 0.0, 0, 0, "Free cloth cache without preroll"); uiDefBut(block, BUT, B_CLOTH_CLEARCACHEFRAME, "From next frame", 155, 100,145,20, NULL, 0.0, 0.0, 0, 0, "Free cloth cache"); if(length>1) // B_CLOTH_CHANGEPREROLL - uiDefButI(block, NUM, B_CLOTH_CHANGEPREROLL, "Preroll:", 10,80,145,20, &clmd->sim_parms.preroll, 0, length-1, 1, 0, "Simulation starts on this frame"); + uiDefButI(block, NUM, B_CLOTH_CHANGEPREROLL, "Preroll:", 10,80,145,20, &clmd->sim_parms->preroll, 0, length-1, 1, 0, "Simulation starts on this frame"); else uiDefBut(block, LABEL, 0, " ", 10,80,145,20, NULL, 0.0, 0, 0, 0, ""); } - else + else { uiDefBut(block, LABEL, 0, "No frames cached.", 10,120,290,20, NULL, 0.0, 0, 0, 0, ""); - } - uiDefButBitI(block, TOG, CLOTH_SIMSETTINGS_FLAG_CCACHE_PROTECT, REDRAWVIEW3D, "Protect Cache", 10,50,145,20, &clmd->sim_parms.flags, 0, 0, 0, 0, "Protect cache from automatic freeing when scene changed"); + }*/ + uiDefButBitI(block, TOG, CLOTH_SIMSETTINGS_FLAG_CCACHE_PROTECT, REDRAWVIEW3D, "Protect Cache", 10,50,145,20, &clmd->sim_parms->flags, 0, 0, 0, 0, "Protect cache from automatic freeing when scene changed"); uiBlockEndAlign(block); } } @@ -3335,13 +3337,13 @@ static void object_panel_cloth_III(Object *ob) uiSetButLock(object_data_is_libdata(ob), ERROR_LIBDATA_MESSAGE); uiBlockBeginAlign(block); - uiDefButBitI(block, TOG, CLOTH_COLLISIONSETTINGS_FLAG_ENABLED, REDRAWVIEW3D, "Enable collisions", 10,160,130,20, &clmd->coll_parms.flags, 0, 0, 0, 0, "Enable collisions with this object"); - if (clmd->coll_parms.flags & CLOTH_COLLISIONSETTINGS_FLAG_ENABLED) + uiDefButBitI(block, TOG, CLOTH_COLLISIONSETTINGS_FLAG_ENABLED, REDRAWVIEW3D, "Enable collisions", 10,160,130,20, &clmd->coll_parms->flags, 0, 0, 0, 0, "Enable collisions with this object"); + if (clmd->coll_parms->flags & CLOTH_COLLISIONSETTINGS_FLAG_ENABLED) { // uiDefBut(block, LABEL, 0, "",10,10,300,20, NULL, 0.0, 0, 0, 0, ""); /* tell UI we go to 10,10*/ - uiDefButF(block, NUM, B_CLOTH_RENEW, "Min Distance:", 10,140,150,20, &clmd->coll_parms.epsilon, 0.001f, 1.0, 0.01f, 0, "Minimum distance between collision objects before collision response takes in"); + uiDefButF(block, NUM, B_CLOTH_RENEW, "Min Distance:", 10,140,150,20, &clmd->coll_parms->epsilon, 0.001f, 1.0, 0.01f, 0, "Minimum distance between collision objects before collision response takes in"); uiDefBut(block, LABEL, 0, "",160,140,150,20, NULL, 0.0, 0, 0, 0, ""); - uiDefButF(block, NUM, B_CLOTH_RENEW, "Selfcoll balls:", 10,120,150,20, &clmd->coll_parms.selfepsilon, 0.001f, 1.0, 0.01f, 0, "Minimum distance between two selfcollision points"); + uiDefButF(block, NUM, B_CLOTH_RENEW, "Selfcoll balls:", 10,120,150,20, &clmd->coll_parms->selfepsilon, 0.001f, 1.0, 0.01f, 0, "Minimum distance between two selfcollision points"); } else uiDefBut(block, LABEL, 0, "",140,10,170,20, NULL, 0.0, 0, 0, 0, ""); From 14de7f4a2b70c4c1d159542b73dc01fac48261f8 Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Mon, 19 Nov 2007 00:01:33 +0000 Subject: [PATCH 052/246] fixed sse copy-paste glitch + #define __SSE3__ thanks to Lynx3d --- source/blender/blenkernel/intern/cloth.c | 4 +- source/blender/blenkernel/intern/implicit.c | 157 ++------------------ 2 files changed, 15 insertions(+), 146 deletions(-) diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c index ea3c8dec0c0..b0a45b6e720 100644 --- a/source/blender/blenkernel/intern/cloth.c +++ b/source/blender/blenkernel/intern/cloth.c @@ -567,6 +567,8 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd,Object *ob, DerivedMesh *d { if ((clmd->clothObject == NULL) || (numverts != clmd->clothObject->numverts) ) { + cloth_clear_cache(ob, clmd, 0); + if(!cloth_from_object (ob, clmd, result, dm, framenr)) return result; @@ -756,7 +758,7 @@ static void cloth_to_object (Object *ob, DerivedMesh *dm, ClothModifierData *cl for (i = 0; i < numverts; i++) { VECCOPY (mvert[i].co, cloth->x[i]); - Mat4MulVecfl (ob->imat, mvert[i].co); /* softbody is in global coords */ + Mat4MulVecfl (ob->imat, mvert[i].co); /* cloth is in global coords */ } } } diff --git a/source/blender/blenkernel/intern/implicit.c b/source/blender/blenkernel/intern/implicit.c index c457064065c..eab5e992abe 100644 --- a/source/blender/blenkernel/intern/implicit.c +++ b/source/blender/blenkernel/intern/implicit.c @@ -410,14 +410,15 @@ DO_INLINE void mul_fvector_fmatrix(float *to, float *from, float matrix[3][4]) /* 3x3 matrix multiplied by a vector */ /* STATUS: verified */ -#ifdef SSE3 +#ifdef __SSE3__ DO_INLINE void mul_fmatrix_fvector(float *to, float matrix[3][4], float *from) { + float temp[4]; __m128 v1, v2, v3, v4; - v1 = _mm_load_ps(&matrix[0]); - v2 = _mm_load_ps(&matrix[1]); - v3 = _mm_load_ps(&matrix[2]); - v4 = _mm_load_ps(from); + v1 = _mm_loadu_ps(&matrix[0][0]); + v2 = _mm_loadu_ps(&matrix[1][0]); + v3 = _mm_loadu_ps(&matrix[2][0]); + v4 = _mm_loadu_ps(from); // stuff v1 = _mm_mul_ps(v1, v4); @@ -425,9 +426,9 @@ DO_INLINE void mul_fmatrix_fvector(float *to, float matrix[3][4], float *from) { v3 = _mm_mul_ps(v3, v4); v1 = _mm_hadd_ps(v1, v2); v3 = _mm_hadd_ps(v3, _mm_setzero_ps()); - v1 = _mm_hadd_ps(v1, v3); + v4 = _mm_hadd_ps(v1, v3); - _mm_store_ps(to, v4); + _mm_storeu_ps(to, v4); } #else DO_INLINE void mul_fmatrix_fvector(float *to, float matrix[3][4], float *from) @@ -537,7 +538,7 @@ DO_INLINE void mulsub_fmatrix_fmatrix(float to[3][3], float matrixA[3][3], float /* 3x3 matrix multiplied+added by a vector */ /* STATUS: verified */ -#ifdef SSE3 +#ifdef __SSE3__ DO_INLINE void muladd_fmatrix_fvector(float to[3], float matrix[3][4], float from[3]) { __m128 v1, v2, v3, v4; @@ -1053,141 +1054,7 @@ DO_INLINE void BuildPPinv(fmatrix3x3 *lA, fmatrix3x3 *P, fmatrix3x3 *Pinv) } } -/* -// 1.0 working PCG, but slow and unstable for bigger epsilon + strong forces -int cg_filtered_pre(lfVector *dv, fmatrix3x3 *lA, lfVector *lB, lfVector *z, fmatrix3x3 *S, fmatrix3x3 *P, fmatrix3x3 *Pinv) -{ - unsigned int numverts = lA[0].vcount, iterations = 0, conjgrad_looplimit=100; - float delta0 = 0, deltaNew = 0, deltaOld = 0, alpha = 0; - float conjgrad_epsilon=0.01f, conjgrad_lasterror=0; - lfVector *filterb = create_lfvector(numverts); - lfVector *p_fb = create_lfvector(numverts); - lfVector *r = create_lfvector(numverts); - lfVector *c = create_lfvector(numverts); - lfVector *q = create_lfvector(numverts); - lfVector *s = create_lfvector(numverts); - - BuildPPinv(lA, P, Pinv); - - cp_lfvector(dv, z, numverts); - cp_lfvector(filterb, lB, numverts); - filter(filterb, S); - mul_bfmatrix_lfvector(p_fb, P, filterb); - delta0 = dot_lfvector(filterb, p_fb, numverts); - - mul_bfmatrix_lfvector(r, lA, dv); - mul_lfvectorS(r, r, -1.0, numverts); - add_lfvector_lfvector(r, r, lB, numverts); - filter(r, S); - - mul_bfmatrix_lfvector(c, Pinv, r); - filter(c, S); - - deltaNew = dot_lfvector(r, c, numverts); - - do - { - iterations++; - - mul_bfmatrix_lfvector(q, lA, c); - filter(q, S); - - alpha = deltaNew / dot_lfvector(c, q, numverts); - - add_lfvector_lfvectorS(dv, dv, c, alpha, numverts); - - add_lfvector_lfvectorS(r, r, q, -alpha, numverts); - - mul_bfmatrix_lfvector(s, Pinv, r); - - - deltaOld = deltaNew; - - deltaNew = dot_lfvector(r, s, numverts); - - add_lfvector_lfvectorS(s, s, c, deltaNew / deltaOld, numverts); - filter(s, S); - - cp_lfvector(c, s, numverts); - } while ((deltaNew > (conjgrad_epsilon*conjgrad_epsilon*delta0)) && (iterations < conjgrad_looplimit)); - - del_lfvector(s); - del_lfvector(q); - del_lfvector(c); - del_lfvector(r); - del_lfvector(p_fb); - del_lfvector(filterb); - - printf("iterations: %d\n", iterations); - - return iterations (conjgrad_epsilon*conjgrad_epsilon*delta0)) && (iterations < conjgrad_looplimit)) - { - iterations++; - - mul_bfmatrix_lfvector(s, lA, p); - filter(s, S); - - alpha = deltaNew / dot_lfvector(p, s, numverts); - - add_lfvector_lfvectorS(dv, dv, p, alpha, numverts); - - add_lfvector_lfvectorS(r, r, s, -alpha, numverts); - - mul_bfmatrix_lfvector(h, Pinv, r); - - - deltaOld = deltaNew; - - deltaNew = dot_lfvector(r, h, numverts); - - add_lfvector_lfvectorS(p, h, p, deltaNew / deltaOld, numverts); - filter(p, S); - - } - - del_lfvector(h); - del_lfvector(s); - del_lfvector(p); - del_lfvector(r); - - printf("iterations: %d\n", iterations); - - return iterations Date: Mon, 19 Nov 2007 00:27:25 +0000 Subject: [PATCH 053/246] #ifdef sse headers --- source/blender/blenkernel/intern/implicit.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/source/blender/blenkernel/intern/implicit.c b/source/blender/blenkernel/intern/implicit.c index eab5e992abe..f562bd49fcc 100644 --- a/source/blender/blenkernel/intern/implicit.c +++ b/source/blender/blenkernel/intern/implicit.c @@ -65,9 +65,11 @@ #include "Bullet-C-Api.h" +#ifdef __SSE3__ #include #include #include +#endif #ifdef _WIN32 #include @@ -412,13 +414,12 @@ DO_INLINE void mul_fvector_fmatrix(float *to, float *from, float matrix[3][4]) /* STATUS: verified */ #ifdef __SSE3__ DO_INLINE void mul_fmatrix_fvector(float *to, float matrix[3][4], float *from) { - float temp[4]; __m128 v1, v2, v3, v4; - v1 = _mm_loadu_ps(&matrix[0][0]); - v2 = _mm_loadu_ps(&matrix[1][0]); - v3 = _mm_loadu_ps(&matrix[2][0]); - v4 = _mm_loadu_ps(from); + v1 = _mm_load_ps(&matrix[0][0]); + v2 = _mm_load_ps(&matrix[1][0]); + v3 = _mm_load_ps(&matrix[2][0]); + v4 = _mm_load_ps(from); // stuff v1 = _mm_mul_ps(v1, v4); @@ -428,7 +429,7 @@ DO_INLINE void mul_fmatrix_fvector(float *to, float matrix[3][4], float *from) { v3 = _mm_hadd_ps(v3, _mm_setzero_ps()); v4 = _mm_hadd_ps(v1, v3); - _mm_storeu_ps(to, v4); + _mm_store_ps(to, v4); } #else DO_INLINE void mul_fmatrix_fvector(float *to, float matrix[3][4], float *from) @@ -542,9 +543,9 @@ DO_INLINE void mulsub_fmatrix_fmatrix(float to[3][3], float matrixA[3][3], float DO_INLINE void muladd_fmatrix_fvector(float to[3], float matrix[3][4], float from[3]) { __m128 v1, v2, v3, v4; - v1 = _mm_load_ps(&matrix[0]); - v2 = _mm_load_ps(&matrix[1]); - v3 = _mm_load_ps(&matrix[2]); + v1 = _mm_load_ps(&matrix[0][0]); + v2 = _mm_load_ps(&matrix[1][0]); + v3 = _mm_load_ps(&matrix[2][0]); v4 = _mm_load_ps(from); // stuff From f28ab5de21b028a5726dc7e3975fd1a523287e37 Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Mon, 19 Nov 2007 23:45:26 +0000 Subject: [PATCH 054/246] Bugfix: scaling/rotation/translation works again --- source/blender/blenkernel/intern/cloth.c | 23 ++++++++++----------- source/blender/blenkernel/intern/implicit.c | 13 ++++++------ 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c index b0a45b6e720..d0ab7ce4ffb 100644 --- a/source/blender/blenkernel/intern/cloth.c +++ b/source/blender/blenkernel/intern/cloth.c @@ -862,13 +862,7 @@ static int cloth_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *d /* create springs */ clmd->clothObject->springs = NULL; clmd->clothObject->numsprings = -1; - - if (!cloth_build_springs (clmd->clothObject, dm) ) - { - modifier_setError (&(clmd->modifier), "Can't build springs."); - return 0; - } - + /* set initial values */ for (i = 0; i < numverts; ++i) { @@ -889,6 +883,12 @@ static int cloth_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *d clmd->clothObject->verts [i].impulse_count = 0; VECCOPY ( clmd->clothObject->verts [i].impulse, tnull ); } + + if (!cloth_build_springs (clmd->clothObject, dm) ) + { + modifier_setError (&(clmd->modifier), "Can't build springs."); + return 0; + } /* apply / set vertex groups */ if (clmd->sim_parms->vgroup_mass > 0) @@ -1044,7 +1044,6 @@ int cloth_build_springs ( Cloth *cloth, DerivedMesh *dm ) unsigned int numverts = dm->getNumVerts ( dm ); unsigned int numedges = dm->getNumEdges ( dm ); unsigned int numfaces = dm->getNumFaces ( dm ); - MVert *mvert = CDDM_get_verts ( dm ); MEdge *medge = CDDM_get_edges ( dm ); MFace *mface = CDDM_get_faces ( dm ); unsigned int index2 = 0; // our second vertex index @@ -1081,7 +1080,7 @@ int cloth_build_springs ( Cloth *cloth, DerivedMesh *dm ) { spring->ij = medge[i].v1; spring->kl = medge[i].v2; - VECSUB ( temp, mvert[spring->kl].co, mvert[spring->ij].co ); + VECSUB ( temp, cloth->x[spring->kl], cloth->x[spring->ij] ); spring->restlen = sqrt ( INPR ( temp, temp ) ); spring->type = CLOTH_SPRING_TYPE_STRUCTURAL; spring->flags = 0; @@ -1102,7 +1101,7 @@ int cloth_build_springs ( Cloth *cloth, DerivedMesh *dm ) spring->ij = mface[i].v1; spring->kl = mface[i].v3; - VECSUB ( temp, mvert[spring->kl].co, mvert[spring->ij].co ); + VECSUB ( temp, cloth->x[spring->kl], cloth->x[spring->ij] ); spring->restlen = sqrt ( INPR ( temp, temp ) ); spring->type = CLOTH_SPRING_TYPE_SHEAR; @@ -1119,7 +1118,7 @@ int cloth_build_springs ( Cloth *cloth, DerivedMesh *dm ) spring->ij = mface[i].v2; spring->kl = mface[i].v4; - VECSUB ( temp, mvert[spring->kl].co, mvert[spring->ij].co ); + VECSUB ( temp, cloth->x[spring->kl], cloth->x[spring->ij] ); spring->restlen = sqrt ( INPR ( temp, temp ) ); spring->type = CLOTH_SPRING_TYPE_SHEAR; @@ -1156,7 +1155,7 @@ int cloth_build_springs ( Cloth *cloth, DerivedMesh *dm ) spring->ij = tspring2->ij; spring->kl = index2; - VECSUB ( temp, mvert[index2].co, mvert[tspring2->ij].co ); + VECSUB ( temp, cloth->x[index2], cloth->x[tspring2->ij] ); spring->restlen = sqrt ( INPR ( temp, temp ) ); spring->type = CLOTH_SPRING_TYPE_BENDING; BLI_edgehash_insert ( edgehash, spring->ij, index2, NULL ); diff --git a/source/blender/blenkernel/intern/implicit.c b/source/blender/blenkernel/intern/implicit.c index f562bd49fcc..21f1d7d0c1c 100644 --- a/source/blender/blenkernel/intern/implicit.c +++ b/source/blender/blenkernel/intern/implicit.c @@ -1233,6 +1233,7 @@ DO_INLINE void cloth_calc_spring_force(ClothModifierData *clmd, ClothSpring *s, VECADD(s->f, s->f, damping_force); // Formula from Ascher / Boxman, Speeding up cloth simulation + // couldn't see any speedup // if((dt * (k*dt + 2 * clmd->sim_parms->Cdis * 0.01)) > 0.01 ) { dfdx_spring_type1(s->dfdx, dir,length,L,clmd->sim_parms->structural); @@ -1256,12 +1257,12 @@ DO_INLINE void cloth_calc_spring_force(ClothModifierData *clmd, ClothSpring *s, // DG: My formula to handle bending for the AIMEX scheme // multiply with 1000 because of numerical problems - // if( ((k*1000)*dt*dt) < -0.18 ) + if( ((k*1000.0)*dt*dt) < -0.18 ) { dfdx_spring_type2(s->dfdx, dir,length,L,clmd->sim_parms->bending, cb); clmd->sim_parms->flags |= CLOTH_SIMSETTINGS_FLAG_BIG_FORCE; } - // printf("(dt*k*dt) ): %f, k: %f\n", (dt*dt*k*-1.0), k); + // printf("(dt*k*dt) ): %f, k: %f\n", (dt*dt*(1000.0*k)), k); } } } @@ -1279,8 +1280,8 @@ DO_INLINE int cloth_apply_spring_force(ClothModifierData *clmd, ClothSpring *s, sub_fmatrix_fmatrix(dFdV[s->kl].m, dFdV[s->kl].m, s->dfdv); add_fmatrix_fmatrix(dFdV[s->matrix_index].m, dFdV[s->matrix_index].m, s->dfdv); } - else if(!(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_BIG_FORCE)) - return 0; + // else if(!(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_BIG_FORCE)) + // return 0; sub_fmatrix_fmatrix(dFdX[s->ij].m, dFdX[s->ij].m, s->dfdx); sub_fmatrix_fmatrix(dFdX[s->kl].m, dFdX[s->kl].m, s->dfdx); @@ -1466,8 +1467,8 @@ void simulate_implicit_euler(lfVector *Vnew, lfVector *lX, lfVector *lV, lfVecto add_lfvectorS_lfvectorS(B, lF, dt, dFdXmV, (dt*dt), numverts); - // cg_filtered(dV, A, B, z, S); // conjugate gradient algorithm to solve Ax=b - cg_filtered_pre(dV, A, B, z, S, P, Pinv); + cg_filtered(dV, A, B, z, S); // conjugate gradient algorithm to solve Ax=b + // cg_filtered_pre(dV, A, B, z, S, P, Pinv); // advance velocities add_lfvector_lfvector(Vnew, lV, dV, numverts); From 4cb5470f82bf6139418ef0530407ff21aa3f2272 Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Wed, 21 Nov 2007 08:13:00 +0000 Subject: [PATCH 055/246] WIP commit to be able to revert later (known bug: unstable without sse enabled - weird) --- source/blender/blenkernel/intern/implicit.c | 188 ++++++++++++++++---- 1 file changed, 157 insertions(+), 31 deletions(-) diff --git a/source/blender/blenkernel/intern/implicit.c b/source/blender/blenkernel/intern/implicit.c index 21f1d7d0c1c..3f3b3a66253 100644 --- a/source/blender/blenkernel/intern/implicit.c +++ b/source/blender/blenkernel/intern/implicit.c @@ -271,7 +271,7 @@ DO_INLINE float dot_lfvector(lfVector *fLongVectorA, lfVector *fLongVectorB, uns unsigned int i = 0; float temp = 0.0; // schedule(guided, 2) -#pragma omp parallel for reduction(+: temp) schedule(static) +#pragma omp parallel for reduction(+: temp) private(i) schedule(static) for(i = 0; i < verts; i++) { temp += INPR(fLongVectorA[i], fLongVectorB[i]); @@ -287,8 +287,34 @@ DO_INLINE void add_lfvector_lfvector(lfVector *to, lfVector *fLongVectorA, lfVec { VECADD(to[i], fLongVectorA[i], fLongVectorB[i]); } - } +/* +#ifdef __SSE3__ +DO_INLINE void add_lfvector(lfVector *to, lfVector *fLongVectorA, unsigned int verts) { + __m128 v1, v2; + unsigned int i = 0; + + for(i = 0; i < verts; i++) + { + v1 = _mm_load_ps(to[i]); + v2 = _mm_load_ps(fLongVectorA[i]); + + v1 = _mm_add_ps(v1, v2); + + _mm_store_ps(to[i], v1); + } +} +#else */ +DO_INLINE void add_lfvector(lfVector *to, lfVector *fLongVectorA, unsigned int verts) { + unsigned int i = 0; + + for(i = 0; i < verts; i++) + { + VECADD(to[i], to[i], fLongVectorA[i]); + } +} +// #endif + /* A = B + C * float --> for big vector */ DO_INLINE void add_lfvector_lfvectorS(lfVector *to, lfVector *fLongVectorA, lfVector *fLongVectorB, float bS, unsigned int verts) { @@ -300,6 +326,76 @@ DO_INLINE void add_lfvector_lfvectorS(lfVector *to, lfVector *fLongVectorA, lfVe } } + +/* A = A + B * float --> for big vector */ +// tested +/* +#ifdef __SSE3__ +DO_INLINE void add_lfvectorS(lfVector *to, lfVector *fLongVectorA, float bS, unsigned int verts) { + __m128 v1, v2, v3; + unsigned int i = 0; + + for(i = 0; i < verts; i++) + { + v1 = _mm_load_ps(to[i]); + v2 = _mm_load_ps(fLongVectorA[i]); + v3 = _mm_set1_ps(bS); + + v2 = _mm_mul_ps(v2, v3); + v1 = _mm_add_ps(v1, v2); + + _mm_store_ps(to[i], v1); + } +} +#else */ +DO_INLINE void add_lfvectorS(lfVector *to, lfVector *fLongVectorA, float bS, unsigned int verts) { + unsigned int i = 0; + + for(i = 0; i < verts; i++) + { + VECADDS(to[i], to[i], fLongVectorA[i], bS); + } +} +// #endif + + +// tested +/* +#ifdef __SSE3__ +DO_INLINE float add_lfvectorS_dot(lfVector *to, lfVector *fLongVectorA, float bS, unsigned int verts) { + register __m128 v1, v2, v3, v4; + unsigned int i = 0; + float temp; + + v4 = _mm_setzero_ps(); +// #pragma omp parallel for reduction(+: v4) private(i, v1, v2, v3) schedule(static) + for(i = 0; i < verts; i++) + { + v1 = _mm_load_ps(to[i]); + v2 = _mm_load_ps(fLongVectorA[i]); + v3 = _mm_set1_ps(bS); + + v2 = _mm_mul_ps(v2, v3); + v1 = _mm_add_ps(v1, v2); + + _mm_stream_ps(to[i], v1); + + v4 = _mm_add_ps(v4, _mm_mul_ps(v1,v1)); + } + + v4 = _mm_hadd_ps(v4, v4); + v4 = _mm_hadd_ps(v4, v4); + _mm_store_ss(&temp, v4); + + return temp; +} +#else */ +DO_INLINE float add_lfvectorS_dot(lfVector *to, lfVector *fLongVectorA, float bS, unsigned int verts) { + add_lfvectorS(to, fLongVectorA, bS, verts); + return dot_lfvector(to, to, verts); +} +// #endif + /* A = B * float + C * float --> for big vector */ DO_INLINE void add_lfvectorS_lfvectorS(lfVector *to, lfVector *fLongVectorA, float aS, lfVector *fLongVectorB, float bS, unsigned int verts) { @@ -412,8 +508,9 @@ DO_INLINE void mul_fvector_fmatrix(float *to, float *from, float matrix[3][4]) /* 3x3 matrix multiplied by a vector */ /* STATUS: verified */ +/* #ifdef __SSE3__ -DO_INLINE void mul_fmatrix_fvector(float *to, float matrix[3][4], float *from) { +DO_INLINE void mul_fmatrix_fvector(float to[4], float matrix[3][4], float from[4]) { __m128 v1, v2, v3, v4; v1 = _mm_load_ps(&matrix[0][0]); @@ -431,14 +528,18 @@ DO_INLINE void mul_fmatrix_fvector(float *to, float matrix[3][4], float *from) { _mm_store_ps(to, v4); } -#else -DO_INLINE void mul_fmatrix_fvector(float *to, float matrix[3][4], float *from) +#else */ +DO_INLINE void mul_fmatrix_fvector(float to[4], float matrix[3][4], float from[4]) { - to[0] = INPR(matrix[0],from); - to[1] = INPR(matrix[1],from); - to[2] = INPR(matrix[2],from); + float temp[3] = {0,0,0}; + + temp[0] = INPR(matrix[0],from); + temp[1] = INPR(matrix[1],from); + temp[2] = INPR(matrix[2],from); + + VECCOPY(to, temp); } -#endif +// #endif /* 3x3 matrix multiplied by a 3x3 matrix */ /* STATUS: verified */ @@ -538,9 +639,9 @@ DO_INLINE void mulsub_fmatrix_fmatrix(float to[3][3], float matrixA[3][3], float */ /* 3x3 matrix multiplied+added by a vector */ /* STATUS: verified */ - +/* #ifdef __SSE3__ -DO_INLINE void muladd_fmatrix_fvector(float to[3], float matrix[3][4], float from[3]) { +DO_INLINE void muladd_fmatrix_fvector(float to[4], float matrix[3][4], float from[4]) { __m128 v1, v2, v3, v4; v1 = _mm_load_ps(&matrix[0][0]); @@ -561,8 +662,8 @@ DO_INLINE void muladd_fmatrix_fvector(float to[3], float matrix[3][4], float fro _mm_store_ps(to, v4); } -#else -DO_INLINE void muladd_fmatrix_fvector(float to[3], float matrix[3][4], float from[3]) +#else */ +DO_INLINE void muladd_fmatrix_fvector(float to[4], float matrix[3][4], float from[4]) { float temp[3] = { 0,0,0 }; @@ -572,7 +673,7 @@ DO_INLINE void muladd_fmatrix_fvector(float to[3], float matrix[3][4], float fro VECADD(to, to, temp); } -#endif +// #endif /* 3x3 matrix multiplied+sub'ed by a vector */ /* @@ -660,27 +761,51 @@ DO_INLINE void mul_bfmatrix_S(fmatrix3x3 *matrix, float scalar) /* STATUS: verified */ void mul_bfmatrix_lfvector( lfVector *to, fmatrix3x3 *from, lfVector *fLongVector) { - unsigned int i = 0; - float *tflongvector; + unsigned int i = 0, numverts = from[0].vcount; + // lfVector *tflongvector = create_lfvector(numverts); float temp[4]={0,0,0,0}; - zero_lfvector(to, from[0].vcount); + zero_lfvector(to, numverts); + /* +#pragma omp parallel sections private(i) +{ +#pragma omp section + { + for(i = numverts; i < numverts+from[0].scount; i++) + { + muladd_fmatrix_fvector(to[from[i].c], from[i].m, fLongVector[from[i].r]); + + } + } +#pragma omp section + { + for(i = 0; i < numverts+from[0].scount; i++) + { + muladd_fmatrix_fvector(tflongvector[from[i].r], from[i].m, fLongVector[from[i].c]); + } + } +} + add_lfvector(to, tflongvector, numverts); + + del_lfvector(tflongvector); + */ + // alternative NON OpenMP code /* process diagonal elements */ + for(i = 0; i < from[0].vcount; i++) { mul_fmatrix_fvector(to[from[i].r], from[i].m, fLongVector[from[i].c]); } - + /* process off-diagonal entries (every off-diagonal entry needs to be symmetric) */ - // TODO: pragma below is wrong, correct it! -// #pragma omp parallel for shared(to,from, fLongVector) private(i) for(i = from[0].vcount; i < from[0].vcount+from[0].scount; i++) { muladd_fmatrix_fvector(to[from[i].c], from[i].m, fLongVector[from[i].r]); muladd_fmatrix_fvector(to[from[i].r], from[i].m, fLongVector[from[i].c]); } + } /* SPARSE SYMMETRIC add big matrix with big matrix: A = B + C*/ @@ -860,7 +985,7 @@ int implicit_init (Object *ob, ClothModifierData *clmd) return 1; } -int implicit_free (ClothModifierData *clmd) +int implicit_free (ClothModifierData *clmd) { Implicit_Data *id; Cloth *cloth; @@ -1010,12 +1135,13 @@ int cg_filtered(lfVector *ldV, fmatrix3x3 *lA, lfVector *lB, lfVector *z, fmatr // X = X + d*a; add_lfvector_lfvectorS(ldV, ldV, d, a, numverts); + + s_prev = s; // r = r - q*a; - sub_lfvector_lfvectorS(r, r, q, a, numverts); - - s_prev = s; + add_lfvector_lfvectorS(r, r, q, -a, numverts); s = dot_lfvector(r, r, numverts); + // s = add_lfvectorS_dot(r, q, -a, numverts); //d = r+d*(s/s_prev); add_lfvector_lfvectorS(d, r, d, (s/s_prev), numverts); @@ -1069,7 +1195,7 @@ int cg_filtered_pre(lfVector *dv, fmatrix3x3 *lA, lfVector *lB, lfVector *z, fma BuildPPinv(lA, P, Pinv); filter(dv, S); - add_lfvector_lfvector(dv, dv, z, numverts); + add_lfvector(dv, z, numverts); mul_bfmatrix_lfvector(r, lA, dv); sub_lfvector_lfvector(r, lB, r, numverts); @@ -1091,9 +1217,9 @@ int cg_filtered_pre(lfVector *dv, fmatrix3x3 *lA, lfVector *lB, lfVector *z, fma alpha = deltaNew / dot_lfvector(p, s, numverts); - add_lfvector_lfvectorS(dv, dv, p, alpha, numverts); + add_lfvectorS(dv, p, alpha, numverts); - sub_lfvector_lfvectorS(r, r, s, alpha, numverts); + add_lfvectorS(r, s, -alpha, numverts); mul_bfmatrix_lfvector(h, Pinv, r); filter(h, S); @@ -1257,7 +1383,7 @@ DO_INLINE void cloth_calc_spring_force(ClothModifierData *clmd, ClothSpring *s, // DG: My formula to handle bending for the AIMEX scheme // multiply with 1000 because of numerical problems - if( ((k*1000.0)*dt*dt) < -0.18 ) + // if( ((k*1000.0)*dt*dt) < -0.18 ) { dfdx_spring_type2(s->dfdx, dir,length,L,clmd->sim_parms->bending, cb); clmd->sim_parms->flags |= CLOTH_SIMSETTINGS_FLAG_BIG_FORCE; @@ -1392,7 +1518,7 @@ void cloth_calc_force(ClothModifierData *clmd, lfVector *lF, lfVector *lX, lfVec float speed[3] = {0.0f, 0.0f,0.0f}; float force[3]= {0.0f, 0.0f, 0.0f}; - #pragma omp parallel for private (i) shared(lF) + #pragma omp parallel for private (i) shared(lF) schedule(static) for(i = 0; i < cloth->numverts; i++) { float vertexnormal[3]={0,0,0}; @@ -1467,8 +1593,8 @@ void simulate_implicit_euler(lfVector *Vnew, lfVector *lX, lfVector *lV, lfVecto add_lfvectorS_lfvectorS(B, lF, dt, dFdXmV, (dt*dt), numverts); - cg_filtered(dV, A, B, z, S); // conjugate gradient algorithm to solve Ax=b - // cg_filtered_pre(dV, A, B, z, S, P, Pinv); + // cg_filtered(dV, A, B, z, S); // conjugate gradient algorithm to solve Ax=b + cg_filtered_pre(dV, A, B, z, S, P, Pinv); // advance velocities add_lfvector_lfvector(Vnew, lV, dV, numverts); From 83c1dd78a630cef4ae6db341440f437f3d04f124 Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Thu, 22 Nov 2007 17:02:37 +0000 Subject: [PATCH 056/246] Fixed numerical issues, hardened it again. --- source/blender/blenkernel/BKE_cloth.h | 16 +- source/blender/blenkernel/intern/cloth.c | 371 ++++---- source/blender/blenkernel/intern/implicit.c | 884 +++++++------------- 3 files changed, 507 insertions(+), 764 deletions(-) diff --git a/source/blender/blenkernel/BKE_cloth.h b/source/blender/blenkernel/BKE_cloth.h index f3f566d2832..38cd54085f5 100644 --- a/source/blender/blenkernel/BKE_cloth.h +++ b/source/blender/blenkernel/BKE_cloth.h @@ -72,8 +72,8 @@ typedef struct ClothSpring { int matrix_index; /* needed for implicit solver (fast lookup) */ int type; /* types defined in BKE_cloth.h ("springType") */ int flags; /* defined in BKE_cloth.h, e.g. deactivated due to tearing */ - float dfdx[3][4]; - float dfdv[3][4]; + float dfdx[3][3]; + float dfdv[3][3]; float f[3]; } ClothSpring; @@ -91,13 +91,13 @@ typedef struct Cloth { unsigned int numothersprings; unsigned int numspringssave; unsigned int old_solver_type; - float (*x)[4]; /* The current position of all vertices.*/ - float (*xold)[4]; /* The previous position of all vertices.*/ - float (*current_x)[4]; /* The TEMPORARY current position of all vertices.*/ - float (*current_xold)[4]; /* The TEMPORARY previous position of all vertices.*/ + float (*x)[3]; /* The current position of all vertices.*/ + float (*xold)[3]; /* The previous position of all vertices.*/ + float (*current_x)[3]; /* The TEMPORARY current position of all vertices.*/ + float (*current_xold)[3]; /* The TEMPORARY previous position of all vertices.*/ float (*v)[4]; /* the current velocity of all vertices */ - float (*current_v)[4]; - float (*xconst)[4]; + float (*current_v)[3]; + float (*xconst)[3]; } Cloth; /* goal defines */ diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c index d0ab7ce4ffb..436a14d1d6c 100644 --- a/source/blender/blenkernel/intern/cloth.c +++ b/source/blender/blenkernel/intern/cloth.c @@ -90,9 +90,9 @@ double tval() } #else #include -static struct timeval _tstart, _tend; -static struct timezone tz; -void tstart ( void ) + static struct timeval _tstart, _tend; + static struct timezone tz; + void tstart ( void ) { gettimeofday ( &_tstart, &tz ); } @@ -133,11 +133,11 @@ static void cloth_apply_vgroup(ClothModifierData *clmd, DerivedMesh *dm, short v * ******************************************************************************/ /** -* cloth_init - creates a new cloth simulation. -* -* 1. create object -* 2. fill object with standard values or with the GUI settings if given -*/ + * cloth_init - creates a new cloth simulation. + * + * 1. create object + * 2. fill object with standard values or with the GUI settings if given + */ void cloth_init (ClothModifierData *clmd) { /* Initialize our new data structure to reasonable values. */ @@ -202,38 +202,38 @@ DerivedMesh *CDDM_convert_to_triangle(DerivedMesh *dm) for(i = 0; i < numfaces; i++) { - if(mface[i].v4) - numquads++; - else - numtris++; - } + if(mface[i].v4) + numquads++; + else + numtris++; +} result = CDDM_from_template(dm, numverts, 0, numtris + 2*numquads); if(!result) - return NULL; + return NULL; // do verts mvert2 = CDDM_get_verts(result); for(a=0; av1 = mface[a].v2; - mf->v2 = mface[a].v3; - mf->v3 = mface[a].v4; - } - else - { - mf->v1 = mface[a].v1; - mf->v2 = mface[a].v2; - mf->v3 = mface[a].v3; - } + if(mface[a].v4 && random==1) + { + mf->v1 = mface[a].v2; + mf->v2 = mface[a].v3; + mf->v3 = mface[a].v4; +} + else + { + mf->v1 = mface[a].v1; + mf->v2 = mface[a].v2; + mf->v3 = mface[a].v3; +} - mf->v4 = 0; - mf->flag |= ME_SMOOTH; + mf->v4 = 0; + mf->flag |= ME_SMOOTH; - test_index_face(mf, NULL, 0, 3); + test_index_face(mf, NULL, 0, 3); - if(mface[a].v4) - { - MFace *mf2; + if(mface[a].v4) + { + MFace *mf2; - i++; + i++; - mf2 = &mface2[i]; + mf2 = &mface2[i]; // DM_copy_face_data(dm, result, a, i, 1); // *mf2 = *inMF; - if(random==1) - { - mf2->v1 = mface[a].v1; - mf2->v2 = mface[a].v2; - mf2->v3 = mface[a].v4; - } - else - { - mf2->v1 = mface[a].v4; - mf2->v2 = mface[a].v1; - mf2->v3 = mface[a].v3; - } - mf2->v4 = 0; - mf2->flag |= ME_SMOOTH; + if(random==1) + { + mf2->v1 = mface[a].v1; + mf2->v2 = mface[a].v2; + mf2->v3 = mface[a].v4; +} + else + { + mf2->v1 = mface[a].v4; + mf2->v2 = mface[a].v1; + mf2->v3 = mface[a].v3; +} + mf2->v4 = 0; + mf2->flag |= ME_SMOOTH; - test_index_face(mf2, NULL, 0, 3); - } + test_index_face(mf2, NULL, 0, 3); +} - i++; - } + i++; +} CDDM_calc_edges(result); CDDM_calc_normals(result); @@ -330,43 +330,43 @@ DerivedMesh *CDDM_create_tearing(ClothModifierData *clmd, DerivedMesh *dm) for(i = 0; i < numsprings; i++) { - if((springs[i].flags & CSPRING_FLAG_DEACTIVATE) - &&(!BLI_edgehash_haskey(edgehash, springs[i].ij, springs[i].kl))) - { - BLI_edgehash_insert(edgehash, springs[i].ij, springs[i].kl, NULL); - BLI_edgehash_insert(edgehash, springs[i].kl, springs[i].ij, NULL); - j++; - } - } + if((springs[i].flags & CSPRING_FLAG_DEACTIVATE) + &&(!BLI_edgehash_haskey(edgehash, springs[i].ij, springs[i].kl))) + { + BLI_edgehash_insert(edgehash, springs[i].ij, springs[i].kl, NULL); + BLI_edgehash_insert(edgehash, springs[i].kl, springs[i].ij, NULL); + j++; +} +} // printf("found %d tears\n", j); result = CDDM_from_template(dm, numverts, 0, numfaces); if(!result) - return NULL; + return NULL; // do verts mvert2 = CDDM_get_verts(result); for(a=0; av1 = mface[a].v1; - mf->v2 = mface[a].v2; - mf->v3 = mface[a].v3; - mf->v4 = mface[a].v4; + if((!BLI_edgehash_haskey(edgehash, mface[a].v1, mface[a].v2)) + &&(!BLI_edgehash_haskey(edgehash, mface[a].v2, mface[a].v3)) + &&(!BLI_edgehash_haskey(edgehash, mface[a].v3, mface[a].v4)) + &&(!BLI_edgehash_haskey(edgehash, mface[a].v4, mface[a].v1))) + { + mf->v1 = mface[a].v1; + mf->v2 = mface[a].v2; + mf->v3 = mface[a].v3; + mf->v4 = mface[a].v4; - test_index_face(mf, NULL, 0, 4); + test_index_face(mf, NULL, 0, 4); - i++; - } - } + i++; +} +} CDDM_lower_num_faces(result, i); CDDM_calc_edges(result); @@ -527,40 +527,40 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd,Object *ob, DerivedMesh *d /* if ( clmd->clothObject ) { - if ( clmd->sim_parms->cache ) - { - if ( current_time < clmd->sim_parms->firstframe ) - { - int frametime = cloth_cache_first_frame ( clmd ); - if ( cloth_cache_search_frame ( clmd, frametime ) ) - { - cloth_cache_get_frame ( clmd, frametime ); - cloth_to_object ( ob, result, clmd ); - } - return result; - } - else if ( current_time > clmd->sim_parms->lastframe ) - { - int frametime = cloth_cache_last_frame ( clmd ); - if ( cloth_cache_search_frame ( clmd, frametime ) ) - { - cloth_cache_get_frame ( clmd, frametime ); - cloth_to_object ( ob, result, clmd ); - } - return result; - } - else if ( ABS ( deltaTime ) >= 2.0f ) // no timewarps allowed - { - if ( cloth_cache_search_frame ( clmd, framenr ) ) - { - cloth_cache_get_frame ( clmd, framenr ); - cloth_to_object ( ob, result, clmd ); - } - clmd->sim_parms->sim_time = current_time; - return result; - } - } - } + if ( clmd->sim_parms->cache ) + { + if ( current_time < clmd->sim_parms->firstframe ) + { + int frametime = cloth_cache_first_frame ( clmd ); + if ( cloth_cache_search_frame ( clmd, frametime ) ) + { + cloth_cache_get_frame ( clmd, frametime ); + cloth_to_object ( ob, result, clmd ); +} + return result; +} + else if ( current_time > clmd->sim_parms->lastframe ) + { + int frametime = cloth_cache_last_frame ( clmd ); + if ( cloth_cache_search_frame ( clmd, frametime ) ) + { + cloth_cache_get_frame ( clmd, frametime ); + cloth_to_object ( ob, result, clmd ); +} + return result; +} + else if ( ABS ( deltaTime ) >= 2.0f ) // no timewarps allowed + { + if ( cloth_cache_search_frame ( clmd, framenr ) ) + { + cloth_cache_get_frame ( clmd, framenr ); + cloth_to_object ( ob, result, clmd ); +} + clmd->sim_parms->sim_time = current_time; + return result; +} +} +} */ if(deltaTime == 1.0f) @@ -737,10 +737,10 @@ void cloth_free_modifier (ClothModifierData *clmd) ******************************************************************************/ /** -* cloth_to_object - copies the deformed vertices to the object. -* -* This function is a modified version of the softbody.c:softbody_to_object() function. -**/ + * cloth_to_object - copies the deformed vertices to the object. + * + * This function is a modified version of the softbody.c:softbody_to_object() function. + **/ static void cloth_to_object (Object *ob, DerivedMesh *dm, ClothModifierData *clmd) { unsigned int i = 0; @@ -765,9 +765,9 @@ static void cloth_to_object (Object *ob, DerivedMesh *dm, ClothModifierData *cl /** -* cloth_apply_vgroup - applies a vertex group as specified by type -* -**/ + * cloth_apply_vgroup - applies a vertex group as specified by type + * + **/ static void cloth_apply_vgroup(ClothModifierData *clmd, DerivedMesh *dm, short vgroup) { unsigned int i = 0; @@ -862,52 +862,51 @@ static int cloth_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *d /* create springs */ clmd->clothObject->springs = NULL; clmd->clothObject->numsprings = -1; + + /* set initial values */ + for (i = 0; i < numverts; ++i) + { + VECCOPY (clmd->clothObject->x[i], mvert[i].co); + Mat4MulVecfl(ob->obmat, clmd->clothObject->x[i]); + + clmd->clothObject->verts [i].mass = clmd->sim_parms->mass; + if ( clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL ) + clmd->clothObject->verts [i].goal= clmd->sim_parms->defgoal; + else + clmd->clothObject->verts [i].goal= 0.0; + clmd->clothObject->verts [i].flags = 0; + VECCOPY(clmd->clothObject->xold[i], clmd->clothObject->x[i]); + VECCOPY(clmd->clothObject->xconst[i], clmd->clothObject->x[i]); + VECCOPY(clmd->clothObject->current_xold[i], clmd->clothObject->x[i]); + VecMulf(clmd->clothObject->v[i], 0.0); + + clmd->clothObject->verts [i].impulse_count = 0; + VECCOPY ( clmd->clothObject->verts [i].impulse, tnull ); + } - /* set initial values */ - for (i = 0; i < numverts; ++i) - { - VECCOPY (clmd->clothObject->x[i], mvert[i].co); - Mat4MulVecfl(ob->obmat, clmd->clothObject->x[i]); - - clmd->clothObject->verts [i].mass = clmd->sim_parms->mass; - if ( clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL ) - clmd->clothObject->verts [i].goal= clmd->sim_parms->defgoal; - else - clmd->clothObject->verts [i].goal= 0.0; - clmd->clothObject->verts [i].flags = 0; - VECCOPY(clmd->clothObject->xold[i], clmd->clothObject->x[i]); - VECCOPY(clmd->clothObject->xconst[i], clmd->clothObject->x[i]); - VECCOPY(clmd->clothObject->current_xold[i], clmd->clothObject->x[i]); - VecMulf(clmd->clothObject->v[i], 0.0); - - clmd->clothObject->verts [i].impulse_count = 0; - VECCOPY ( clmd->clothObject->verts [i].impulse, tnull ); + if (!cloth_build_springs (clmd->clothObject, dm) ) + { + modifier_setError (&(clmd->modifier), "Can't build springs."); + return 0; + } + + /* apply / set vertex groups */ + if (clmd->sim_parms->vgroup_mass > 0) + cloth_apply_vgroup (clmd, olddm, clmd->sim_parms->vgroup_mass); + + /* init our solver */ + if (solvers [clmd->sim_parms->solver_type].init) + solvers [clmd->sim_parms->solver_type].init (ob, clmd); + + clmd->clothObject->tree = bvh_build_from_float3(CDDM_get_faces(dm), dm->getNumFaces(dm), clmd->clothObject->x, numverts, clmd->coll_parms->epsilon); + + clmd->clothObject->selftree = bvh_build_from_float3(NULL, 0, clmd->clothObject->x, numverts, clmd->coll_parms->selfepsilon); + + // save initial state + cloth_write_cache(ob, clmd, framenr-1); } - - if (!cloth_build_springs (clmd->clothObject, dm) ) - { - modifier_setError (&(clmd->modifier), "Can't build springs."); - return 0; - } - - /* apply / set vertex groups */ - if (clmd->sim_parms->vgroup_mass > 0) - cloth_apply_vgroup (clmd, olddm, clmd->sim_parms->vgroup_mass); - - /* init our solver */ - if (solvers [clmd->sim_parms->solver_type].init) - solvers [clmd->sim_parms->solver_type].init (ob, clmd); - - clmd->clothObject->tree = bvh_build_from_float4(CDDM_get_faces(dm), dm->getNumFaces(dm), clmd->clothObject->x, numverts, clmd->coll_parms->epsilon); - - clmd->clothObject->selftree = bvh_build_from_float4(NULL, 0, clmd->clothObject->x, numverts, clmd->coll_parms->selfepsilon); - - // save initial state - cloth_write_cache(ob, clmd, framenr-1); - } - - return 1; - default: return 0; // TODO - we do not support changing meshes + return 1; + default: return 0; // TODO - we do not support changing meshes } return 0; @@ -1119,15 +1118,15 @@ int cloth_build_springs ( Cloth *cloth, DerivedMesh *dm ) spring->ij = mface[i].v2; spring->kl = mface[i].v4; VECSUB ( temp, cloth->x[spring->kl], cloth->x[spring->ij] ); - spring->restlen = sqrt ( INPR ( temp, temp ) ); - spring->type = CLOTH_SPRING_TYPE_SHEAR; + spring->restlen = sqrt ( INPR ( temp, temp ) ); + spring->type = CLOTH_SPRING_TYPE_SHEAR; - BLI_linklist_append ( &edgelist[spring->ij], spring ); - BLI_linklist_append ( &edgelist[spring->kl], spring ); - shear_springs++; + BLI_linklist_append ( &edgelist[spring->ij], spring ); + BLI_linklist_append ( &edgelist[spring->kl], spring ); + shear_springs++; - node2 = BLI_linklist_append_fast ( &node->next, spring ); - node = node2; + node2 = BLI_linklist_append_fast ( &node->next, spring ); + node = node2; } } @@ -1148,8 +1147,8 @@ int cloth_build_springs ( Cloth *cloth, DerivedMesh *dm ) // check for existing spring // check also if startpoint is equal to endpoint if ( !BLI_edgehash_haskey ( edgehash, index2, tspring2->ij ) - && !BLI_edgehash_haskey ( edgehash, tspring2->ij, index2 ) - && ( index2!=tspring2->ij ) ) + && !BLI_edgehash_haskey ( edgehash, tspring2->ij, index2 ) + && ( index2!=tspring2->ij ) ) { spring = ( ClothSpring * ) MEM_callocN ( sizeof ( ClothSpring ), "cloth spring" ); diff --git a/source/blender/blenkernel/intern/implicit.c b/source/blender/blenkernel/intern/implicit.c index 3f3b3a66253..6f8f96e58fb 100644 --- a/source/blender/blenkernel/intern/implicit.c +++ b/source/blender/blenkernel/intern/implicit.c @@ -63,14 +63,6 @@ #include "BKE_global.h" #include "BIF_editdeform.h" -#include "Bullet-C-Api.h" - -#ifdef __SSE3__ -#include -#include -#include -#endif - #ifdef _WIN32 #include static LARGE_INTEGER _itstart, _itend; @@ -91,14 +83,14 @@ void itend(void) double itval() { return ((double)_itend.QuadPart - - (double)_itstart.QuadPart)/((double)ifreq.QuadPart); + (double)_itstart.QuadPart)/((double)ifreq.QuadPart); } #else #include -static struct timeval _itstart, _itend; -static struct timezone itz; -void itstart(void) + static struct timeval _itstart, _itend; + static struct timezone itz; + void itstart(void) { gettimeofday(&_itstart, &itz); } @@ -122,39 +114,20 @@ struct Cloth; ///////////////////////////////////////// /* DEFINITIONS */ -#ifdef __GNUC__ -typedef float lfVector[4] __attribute__ ((aligned (16))); -#else -typedef __declspec(align(16)) lfVector[4]; -#endif - -#ifdef __GNUC__ +typedef float lfVector[3]; typedef struct fmatrix3x3 { - float m[3][4] __attribute__ ((aligned (16))); /* 3x3 matrix */ + float m[3][3]; /* 4x4 matrix */ unsigned int c,r; /* column and row number */ int pinned; /* is this vertex allowed to move? */ float n1,n2,n3; /* three normal vectors for collision constrains */ unsigned int vcount; /* vertex count */ unsigned int scount; /* spring count */ } fmatrix3x3; -#else -typedef struct fmatrix3x3 { - __declspec(align(16)) - float m[3][4]; /* 3x3 matrix */ - unsigned int c,r; /* column and row number */ - int pinned; /* is this vertex allowed to move? */ - float n1,n2,n3; /* three normal vectors for collision constrains */ - unsigned int vcount; /* vertex count */ - unsigned int scount; /* spring count */ -} fmatrix3x3; -#endif - /////////////////////////// // float[3] vector /////////////////////////// /* simple vector code */ - /* STATUS: verified */ DO_INLINE void mul_fvector_S(float to[3], float from[3], float scalar) { @@ -166,18 +139,13 @@ DO_INLINE void mul_fvector_S(float to[3], float from[3], float scalar) /* STATUS: verified */ DO_INLINE void cross_fvector(float to[3], float vectorA[3], float vectorB[3]) { - float temp[3]; - - temp[0] = vectorA[1] * vectorB[2] - vectorA[2] * vectorB[1]; - temp[1] = vectorA[2] * vectorB[0] - vectorA[0] * vectorB[2]; - temp[2] = vectorA[0] * vectorB[1] - vectorA[1] * vectorB[0]; - - VECCOPY(to, temp); + to[0] = vectorA[1] * vectorB[2] - vectorA[2] * vectorB[1]; + to[1] = vectorA[2] * vectorB[0] - vectorA[0] * vectorB[2]; + to[2] = vectorA[0] * vectorB[1] - vectorA[1] * vectorB[0]; } - /* simple v^T * v product ("outer product") */ /* STATUS: HAS TO BE verified (*should* work) */ -DO_INLINE void mul_fvectorT_fvector(float to[3][4], float vectorA[3], float vectorB[3]) +DO_INLINE void mul_fvectorT_fvector(float to[3][3], float vectorA[3], float vectorB[3]) { mul_fvector_S(to[0], vectorB, vectorA[0]); mul_fvector_S(to[1], vectorB, vectorA[1]); @@ -185,7 +153,7 @@ DO_INLINE void mul_fvectorT_fvector(float to[3][4], float vectorA[3], float vect } /* simple v^T * v product with scalar ("outer product") */ /* STATUS: HAS TO BE verified (*should* work) */ -DO_INLINE void mul_fvectorT_fvectorS(float to[3][4], float vectorA[3], float vectorB[3], float aS) +DO_INLINE void mul_fvectorT_fvectorS(float to[3][3], float vectorA[3], float vectorB[3], float aS) { mul_fvector_S(to[0], vectorB, vectorA[0]* aS); mul_fvector_S(to[1], vectorB, vectorA[1]* aS); @@ -227,7 +195,7 @@ DO_INLINE void del_lfvector(lfVector *fLongVector) } } /* copy long vector */ -DO_INLINE void cp_lfvector(lfVector *to, lfVector *from, unsigned int verts) +DO_INLINE void cp_lfvector(float (*to)[3], float (*from)[3], unsigned int verts) { memcpy(to, from, verts * sizeof(lfVector)); } @@ -241,12 +209,12 @@ DO_INLINE void init_lfvector(lfVector *fLongVector, float vector[3], unsigned in } } /* zero long vector with float[3] */ -DO_INLINE void zero_lfvector(lfVector *to, unsigned int verts) +DO_INLINE void zero_lfvector(float (*to)[3], unsigned int verts) { memset(to, 0.0f, verts * sizeof(lfVector)); } /* multiply long vector with scalar*/ -DO_INLINE void mul_lfvectorS(lfVector *to, lfVector *fLongVector, float scalar, unsigned int verts) +DO_INLINE void mul_lfvectorS(float (*to)[3], lfVector *fLongVector, float scalar, unsigned int verts) { unsigned int i = 0; @@ -257,7 +225,7 @@ DO_INLINE void mul_lfvectorS(lfVector *to, lfVector *fLongVector, float scalar, } /* multiply long vector with scalar*/ /* A -= B * float */ -DO_INLINE void submul_lfvectorS(lfVector *to, lfVector *fLongVector, float scalar, unsigned int verts) +DO_INLINE void submul_lfvectorS(float (*to)[3], lfVector *fLongVector, float scalar, unsigned int verts) { unsigned int i = 0; for(i = 0; i < verts; i++) @@ -271,7 +239,7 @@ DO_INLINE float dot_lfvector(lfVector *fLongVectorA, lfVector *fLongVectorB, uns unsigned int i = 0; float temp = 0.0; // schedule(guided, 2) -#pragma omp parallel for reduction(+: temp) private(i) schedule(static) +#pragma omp parallel for reduction(+: temp) for(i = 0; i < verts; i++) { temp += INPR(fLongVectorA[i], fLongVectorB[i]); @@ -279,7 +247,7 @@ DO_INLINE float dot_lfvector(lfVector *fLongVectorA, lfVector *fLongVectorB, uns return temp; } /* A = B + C --> for big vector */ -DO_INLINE void add_lfvector_lfvector(lfVector *to, lfVector *fLongVectorA, lfVector *fLongVectorB, unsigned int verts) +DO_INLINE void add_lfvector_lfvector(float (*to)[3], lfVector *fLongVectorA, lfVector *fLongVectorB, unsigned int verts) { unsigned int i = 0; @@ -287,36 +255,10 @@ DO_INLINE void add_lfvector_lfvector(lfVector *to, lfVector *fLongVectorA, lfVec { VECADD(to[i], fLongVectorA[i], fLongVectorB[i]); } -} -/* -#ifdef __SSE3__ -DO_INLINE void add_lfvector(lfVector *to, lfVector *fLongVectorA, unsigned int verts) { - __m128 v1, v2; - unsigned int i = 0; - - for(i = 0; i < verts; i++) - { - v1 = _mm_load_ps(to[i]); - v2 = _mm_load_ps(fLongVectorA[i]); - - v1 = _mm_add_ps(v1, v2); - - _mm_store_ps(to[i], v1); - } -} -#else */ -DO_INLINE void add_lfvector(lfVector *to, lfVector *fLongVectorA, unsigned int verts) { - unsigned int i = 0; - for(i = 0; i < verts; i++) - { - VECADD(to[i], to[i], fLongVectorA[i]); - } } -// #endif - /* A = B + C * float --> for big vector */ -DO_INLINE void add_lfvector_lfvectorS(lfVector *to, lfVector *fLongVectorA, lfVector *fLongVectorB, float bS, unsigned int verts) +DO_INLINE void add_lfvector_lfvectorS(float (*to)[3], lfVector *fLongVectorA, lfVector *fLongVectorB, float bS, unsigned int verts) { unsigned int i = 0; @@ -326,78 +268,8 @@ DO_INLINE void add_lfvector_lfvectorS(lfVector *to, lfVector *fLongVectorA, lfVe } } - -/* A = A + B * float --> for big vector */ -// tested -/* -#ifdef __SSE3__ -DO_INLINE void add_lfvectorS(lfVector *to, lfVector *fLongVectorA, float bS, unsigned int verts) { - __m128 v1, v2, v3; - unsigned int i = 0; - - for(i = 0; i < verts; i++) - { - v1 = _mm_load_ps(to[i]); - v2 = _mm_load_ps(fLongVectorA[i]); - v3 = _mm_set1_ps(bS); - - v2 = _mm_mul_ps(v2, v3); - v1 = _mm_add_ps(v1, v2); - - _mm_store_ps(to[i], v1); - } -} -#else */ -DO_INLINE void add_lfvectorS(lfVector *to, lfVector *fLongVectorA, float bS, unsigned int verts) { - unsigned int i = 0; - - for(i = 0; i < verts; i++) - { - VECADDS(to[i], to[i], fLongVectorA[i], bS); - } -} -// #endif - - -// tested -/* -#ifdef __SSE3__ -DO_INLINE float add_lfvectorS_dot(lfVector *to, lfVector *fLongVectorA, float bS, unsigned int verts) { - register __m128 v1, v2, v3, v4; - unsigned int i = 0; - float temp; - - v4 = _mm_setzero_ps(); -// #pragma omp parallel for reduction(+: v4) private(i, v1, v2, v3) schedule(static) - for(i = 0; i < verts; i++) - { - v1 = _mm_load_ps(to[i]); - v2 = _mm_load_ps(fLongVectorA[i]); - v3 = _mm_set1_ps(bS); - - v2 = _mm_mul_ps(v2, v3); - v1 = _mm_add_ps(v1, v2); - - _mm_stream_ps(to[i], v1); - - v4 = _mm_add_ps(v4, _mm_mul_ps(v1,v1)); - } - - v4 = _mm_hadd_ps(v4, v4); - v4 = _mm_hadd_ps(v4, v4); - _mm_store_ss(&temp, v4); - - return temp; -} -#else */ -DO_INLINE float add_lfvectorS_dot(lfVector *to, lfVector *fLongVectorA, float bS, unsigned int verts) { - add_lfvectorS(to, fLongVectorA, bS, verts); - return dot_lfvector(to, to, verts); -} -// #endif - /* A = B * float + C * float --> for big vector */ -DO_INLINE void add_lfvectorS_lfvectorS(lfVector *to, lfVector *fLongVectorA, float aS, lfVector *fLongVectorB, float bS, unsigned int verts) +DO_INLINE void add_lfvectorS_lfvectorS(float (*to)[3], lfVector *fLongVectorA, float aS, lfVector *fLongVectorB, float bS, unsigned int verts) { unsigned int i = 0; @@ -407,7 +279,7 @@ DO_INLINE void add_lfvectorS_lfvectorS(lfVector *to, lfVector *fLongVectorA, flo } } /* A = B - C * float --> for big vector */ -DO_INLINE void sub_lfvector_lfvectorS(lfVector *to, lfVector *fLongVectorA, lfVector *fLongVectorB, float bS, unsigned int verts) +DO_INLINE void sub_lfvector_lfvectorS(float (*to)[3], lfVector *fLongVectorA, lfVector *fLongVectorB, float bS, unsigned int verts) { unsigned int i = 0; for(i = 0; i < verts; i++) @@ -417,7 +289,7 @@ DO_INLINE void sub_lfvector_lfvectorS(lfVector *to, lfVector *fLongVectorA, lfVe } /* A = B - C --> for big vector */ -DO_INLINE void sub_lfvector_lfvector(lfVector *to, lfVector *fLongVectorA, lfVector *fLongVectorB, unsigned int verts) +DO_INLINE void sub_lfvector_lfvector(float (*to)[3], lfVector *fLongVectorA, lfVector *fLongVectorB, unsigned int verts) { unsigned int i = 0; @@ -428,32 +300,30 @@ DO_INLINE void sub_lfvector_lfvector(lfVector *to, lfVector *fLongVectorA, lfVec } /////////////////////////// -// 3x3 matrix +// 4x4 matrix /////////////////////////// -/* printf 3x3 matrix on console: for debug output */ -void print_fmatrix(float m3[3][4]) +/* printf 4x4 matrix on console: for debug output */ +void print_fmatrix(float m3[3][3]) { printf("%f\t%f\t%f\n",m3[0][0],m3[0][1],m3[0][2]); printf("%f\t%f\t%f\n",m3[1][0],m3[1][1],m3[1][2]); printf("%f\t%f\t%f\n\n",m3[2][0],m3[2][1],m3[2][2]); } -/* copy 3x3 matrix */ -DO_INLINE void cp_fmatrix(float to[3][4], float from[3][4]) +/* copy 4x4 matrix */ +DO_INLINE void cp_fmatrix(float to[3][3], float from[3][3]) { - memcpy(to, from, sizeof (float) * 12); - /* + // memcpy(to, from, sizeof (float) * 9); VECCOPY(to[0], from[0]); VECCOPY(to[1], from[1]); VECCOPY(to[2], from[2]); - */ } -/* calculate determinant of 3x3 matrix */ -DO_INLINE float det_fmatrix(float m[3][4]) +/* calculate determinant of 4x4 matrix */ +DO_INLINE float det_fmatrix(float m[3][3]) { return m[0][0]*m[1][1]*m[2][2] + m[1][0]*m[2][1]*m[0][2] + m[0][1]*m[1][2]*m[2][0] - -m[0][0]*m[1][2]*m[2][1] - m[0][1]*m[1][0]*m[2][2] - m[2][0]*m[1][1]*m[0][2]; + -m[0][0]*m[1][2]*m[2][1] - m[0][1]*m[1][0]*m[2][2] - m[2][0]*m[1][1]*m[0][2]; } -DO_INLINE void inverse_fmatrix(float to[3][4], float from[3][4]) +DO_INLINE void inverse_fmatrix(float to[3][3], float from[3][3]) { unsigned int i, j; float d; @@ -484,115 +354,84 @@ DO_INLINE void inverse_fmatrix(float to[3][4], float from[3][4]) } -/* 3x3 matrix multiplied by a scalar */ +/* 4x4 matrix multiplied by a scalar */ /* STATUS: verified */ -DO_INLINE void mul_fmatrix_S(float matrix[3][4], float scalar) +DO_INLINE void mul_fmatrix_S(float matrix[3][3], float scalar) { mul_fvector_S(matrix[0], matrix[0],scalar); mul_fvector_S(matrix[1], matrix[1],scalar); mul_fvector_S(matrix[2], matrix[2],scalar); } -/* a vector multiplied by a 3x3 matrix */ +/* a vector multiplied by a 4x4 matrix */ /* STATUS: verified */ -DO_INLINE void mul_fvector_fmatrix(float *to, float *from, float matrix[3][4]) +DO_INLINE void mul_fvector_fmatrix(float *to, float *from, float matrix[3][3]) { - float temp[3]; - - VECCOPY(temp, from); - - to[0] = matrix[0][0]*temp[0] + matrix[1][0]*temp[1] + matrix[2][0]*temp[2]; - to[1] = matrix[0][1]*temp[0] + matrix[1][1]*temp[1] + matrix[2][1]*temp[2]; - to[2] = matrix[0][2]*temp[0] + matrix[1][2]*temp[1] + matrix[2][2]*temp[2]; + to[0] = matrix[0][0]*from[0] + matrix[1][0]*from[1] + matrix[2][0]*from[2]; + to[1] = matrix[0][1]*from[0] + matrix[1][1]*from[1] + matrix[2][1]*from[2]; + to[2] = matrix[0][2]*from[0] + matrix[1][2]*from[1] + matrix[2][2]*from[2]; } -/* 3x3 matrix multiplied by a vector */ +/* 4x4 matrix multiplied by a vector */ /* STATUS: verified */ -/* -#ifdef __SSE3__ -DO_INLINE void mul_fmatrix_fvector(float to[4], float matrix[3][4], float from[4]) { - __m128 v1, v2, v3, v4; - - v1 = _mm_load_ps(&matrix[0][0]); - v2 = _mm_load_ps(&matrix[1][0]); - v3 = _mm_load_ps(&matrix[2][0]); - v4 = _mm_load_ps(from); - - // stuff - v1 = _mm_mul_ps(v1, v4); - v2 = _mm_mul_ps(v2, v4); - v3 = _mm_mul_ps(v3, v4); - v1 = _mm_hadd_ps(v1, v2); - v3 = _mm_hadd_ps(v3, _mm_setzero_ps()); - v4 = _mm_hadd_ps(v1, v3); - - _mm_store_ps(to, v4); -} -#else */ -DO_INLINE void mul_fmatrix_fvector(float to[4], float matrix[3][4], float from[4]) +DO_INLINE void mul_fmatrix_fvector(float *to, float matrix[3][3], float *from) { - float temp[3] = {0,0,0}; - - temp[0] = INPR(matrix[0],from); - temp[1] = INPR(matrix[1],from); - temp[2] = INPR(matrix[2],from); - - VECCOPY(to, temp); + to[0] = INPR(matrix[0],from); + to[1] = INPR(matrix[1],from); + to[2] = INPR(matrix[2],from); } -// #endif - -/* 3x3 matrix multiplied by a 3x3 matrix */ +/* 4x4 matrix multiplied by a 4x4 matrix */ /* STATUS: verified */ -DO_INLINE void mul_fmatrix_fmatrix(float to[3][4], float matrixA[3][4], float matrixB[3][4]) +DO_INLINE void mul_fmatrix_fmatrix(float to[3][3], float matrixA[3][3], float matrixB[3][3]) { mul_fvector_fmatrix(to[0], matrixA[0],matrixB); mul_fvector_fmatrix(to[1], matrixA[1],matrixB); mul_fvector_fmatrix(to[2], matrixA[2],matrixB); } -/* 3x3 matrix addition with 3x3 matrix */ -DO_INLINE void add_fmatrix_fmatrix(float to[3][4], float matrixA[3][4], float matrixB[3][4]) +/* 4x4 matrix addition with 4x4 matrix */ +DO_INLINE void add_fmatrix_fmatrix(float to[3][3], float matrixA[3][3], float matrixB[3][3]) { VECADD(to[0], matrixA[0], matrixB[0]); VECADD(to[1], matrixA[1], matrixB[1]); VECADD(to[2], matrixA[2], matrixB[2]); } -/* 3x3 matrix add-addition with 3x3 matrix */ -DO_INLINE void addadd_fmatrix_fmatrix(float to[3][4], float matrixA[3][4], float matrixB[3][4]) +/* 4x4 matrix add-addition with 4x4 matrix */ +DO_INLINE void addadd_fmatrix_fmatrix(float to[3][3], float matrixA[3][3], float matrixB[3][3]) { VECADDADD(to[0], matrixA[0], matrixB[0]); VECADDADD(to[1], matrixA[1], matrixB[1]); VECADDADD(to[2], matrixA[2], matrixB[2]); } -/* 3x3 matrix sub-addition with 3x3 matrix */ -DO_INLINE void addsub_fmatrixS_fmatrixS(float to[3][4], float matrixA[3][4], float aS, float matrixB[3][4], float bS) +/* 4x4 matrix sub-addition with 4x4 matrix */ +DO_INLINE void addsub_fmatrixS_fmatrixS(float to[3][3], float matrixA[3][3], float aS, float matrixB[3][3], float bS) { VECADDSUBSS(to[0], matrixA[0], aS, matrixB[0], bS); VECADDSUBSS(to[1], matrixA[1], aS, matrixB[1], bS); VECADDSUBSS(to[2], matrixA[2], aS, matrixB[2], bS); } -/* A -= B + C (3x3 matrix sub-addition with 3x3 matrix) */ -DO_INLINE void subadd_fmatrix_fmatrix(float to[3][4], float matrixA[3][4], float matrixB[3][4]) +/* A -= B + C (4x4 matrix sub-addition with 4x4 matrix) */ +DO_INLINE void subadd_fmatrix_fmatrix(float to[3][3], float matrixA[3][3], float matrixB[3][3]) { VECSUBADD(to[0], matrixA[0], matrixB[0]); VECSUBADD(to[1], matrixA[1], matrixB[1]); VECSUBADD(to[2], matrixA[2], matrixB[2]); } -/* A -= B*x + C*y (3x3 matrix sub-addition with 3x3 matrix) */ -DO_INLINE void subadd_fmatrixS_fmatrixS(float to[3][4], float matrixA[3][4], float aS, float matrixB[3][4], float bS) +/* A -= B*x + C*y (4x4 matrix sub-addition with 4x4 matrix) */ +DO_INLINE void subadd_fmatrixS_fmatrixS(float to[3][3], float matrixA[3][3], float aS, float matrixB[3][3], float bS) { VECSUBADDSS(to[0], matrixA[0], aS, matrixB[0], bS); VECSUBADDSS(to[1], matrixA[1], aS, matrixB[1], bS); VECSUBADDSS(to[2], matrixA[2], aS, matrixB[2], bS); } -/* A = B - C (3x3 matrix subtraction with 3x3 matrix) */ -DO_INLINE void sub_fmatrix_fmatrix(float to[3][4], float matrixA[3][4], float matrixB[3][4]) +/* A = B - C (4x4 matrix subtraction with 4x4 matrix) */ +DO_INLINE void sub_fmatrix_fmatrix(float to[3][3], float matrixA[3][3], float matrixB[3][3]) { VECSUB(to[0], matrixA[0], matrixB[0]); VECSUB(to[1], matrixA[1], matrixB[1]); VECSUB(to[2], matrixA[2], matrixB[2]); } -/* A += B - C (3x3 matrix add-subtraction with 3x3 matrix) */ -DO_INLINE void addsub_fmatrix_fmatrix(float to[3][4], float matrixA[3][4], float matrixB[3][4]) +/* A += B - C (4x4 matrix add-subtraction with 4x4 matrix) */ +DO_INLINE void addsub_fmatrix_fmatrix(float to[3][3], float matrixA[3][3], float matrixB[3][3]) { VECADDSUB(to[0], matrixA[0], matrixB[0]); VECADDSUB(to[1], matrixA[1], matrixB[1]); @@ -601,93 +440,53 @@ DO_INLINE void addsub_fmatrix_fmatrix(float to[3][4], float matrixA[3][4], float ///////////////////////////////////////////////////////////////// // special functions ///////////////////////////////////////////////////////////////// -/* a vector multiplied and added to/by a 3x3 matrix */ -/* +/* a vector multiplied and added to/by a 4x4 matrix */ DO_INLINE void muladd_fvector_fmatrix(float to[3], float from[3], float matrix[3][3]) { to[0] += matrix[0][0]*from[0] + matrix[1][0]*from[1] + matrix[2][0]*from[2]; to[1] += matrix[0][1]*from[0] + matrix[1][1]*from[1] + matrix[2][1]*from[2]; to[2] += matrix[0][2]*from[0] + matrix[1][2]*from[1] + matrix[2][2]*from[2]; } -*/ -/* 3x3 matrix multiplied and added to/by a 3x3 matrix and added to another 3x3 matrix */ -/* +/* 4x4 matrix multiplied and added to/by a 4x4 matrix and added to another 4x4 matrix */ DO_INLINE void muladd_fmatrix_fmatrix(float to[3][3], float matrixA[3][3], float matrixB[3][3]) { muladd_fvector_fmatrix(to[0], matrixA[0],matrixB); muladd_fvector_fmatrix(to[1], matrixA[1],matrixB); muladd_fvector_fmatrix(to[2], matrixA[2],matrixB); } -*/ -/* a vector multiplied and sub'd to/by a 3x3 matrix */ -/* +/* a vector multiplied and sub'd to/by a 4x4 matrix */ DO_INLINE void mulsub_fvector_fmatrix(float to[3], float from[3], float matrix[3][3]) { to[0] -= matrix[0][0]*from[0] + matrix[1][0]*from[1] + matrix[2][0]*from[2]; to[1] -= matrix[0][1]*from[0] + matrix[1][1]*from[1] + matrix[2][1]*from[2]; to[2] -= matrix[0][2]*from[0] + matrix[1][2]*from[1] + matrix[2][2]*from[2]; } -*/ -/* 3x3 matrix multiplied and sub'd to/by a 3x3 matrix and added to another 3x3 matrix */ -/* +/* 4x4 matrix multiplied and sub'd to/by a 4x4 matrix and added to another 4x4 matrix */ DO_INLINE void mulsub_fmatrix_fmatrix(float to[3][3], float matrixA[3][3], float matrixB[3][3]) { mulsub_fvector_fmatrix(to[0], matrixA[0],matrixB); mulsub_fvector_fmatrix(to[1], matrixA[1],matrixB); mulsub_fvector_fmatrix(to[2], matrixA[2],matrixB); } -*/ -/* 3x3 matrix multiplied+added by a vector */ +/* 4x4 matrix multiplied+added by a vector */ /* STATUS: verified */ -/* -#ifdef __SSE3__ -DO_INLINE void muladd_fmatrix_fvector(float to[4], float matrix[3][4], float from[4]) { - __m128 v1, v2, v3, v4; - - v1 = _mm_load_ps(&matrix[0][0]); - v2 = _mm_load_ps(&matrix[1][0]); - v3 = _mm_load_ps(&matrix[2][0]); - v4 = _mm_load_ps(from); - - // stuff - v1 = _mm_mul_ps(v1, v4); - v2 = _mm_mul_ps(v2, v4); - v3 = _mm_mul_ps(v3, v4); - v1 = _mm_hadd_ps(v1, v2); - v3 = _mm_hadd_ps(v3, _mm_setzero_ps()); - v1 = _mm_hadd_ps(v1, v3); - - v4 = _mm_load_ps(to); - v4 = _mm_add_ps(v4,v1); - - _mm_store_ps(to, v4); -} -#else */ -DO_INLINE void muladd_fmatrix_fvector(float to[4], float matrix[3][4], float from[4]) +DO_INLINE void muladd_fmatrix_fvector(float to[3], float matrix[3][3], float from[3]) { - float temp[3] = { 0,0,0 }; - - temp[0] = INPR(matrix[0],from); - temp[1] = INPR(matrix[1],from); - temp[2] = INPR(matrix[2],from); - - VECADD(to, to, temp); + to[0] += INPR(matrix[0],from); + to[1] += INPR(matrix[1],from); + to[2] += INPR(matrix[2],from); } -// #endif - -/* 3x3 matrix multiplied+sub'ed by a vector */ -/* +/* 4x4 matrix multiplied+sub'ed by a vector */ DO_INLINE void mulsub_fmatrix_fvector(float to[3], float matrix[3][3], float from[3]) { to[0] -= INPR(matrix[0],from); to[1] -= INPR(matrix[1],from); to[2] -= INPR(matrix[2],from); } -*/ ///////////////////////////////////////////////////////////////// /////////////////////////// -// SPARSE SYMMETRIC big matrix with 3x3 matrix entries +// SPARSE SYMMETRIC big matrix with 4x4 matrix entries /////////////////////////// /* printf a big matrix on console: for debug output */ void print_bfmatrix(fmatrix3x3 *m3) @@ -724,10 +523,10 @@ DO_INLINE void cp_bfmatrix(fmatrix3x3 *to, fmatrix3x3 *from) } /* init the diagonal of big matrix */ // slow in parallel -DO_INLINE void initdiag_bfmatrix(fmatrix3x3 *matrix, float m3[3][4]) +DO_INLINE void initdiag_bfmatrix(fmatrix3x3 *matrix, float m3[3][3]) { unsigned int i,j; - float tmatrix[3][4] = {{0,0,0,0},{0,0,0,0},{0,0,0,0}}; + float tmatrix[3][3] = {{0,0,0},{0,0,0},{0,0,0}}; for(i = 0; i < matrix[0].vcount; i++) { @@ -739,7 +538,7 @@ DO_INLINE void initdiag_bfmatrix(fmatrix3x3 *matrix, float m3[3][4]) } } /* init big matrix */ -DO_INLINE void init_bfmatrix(fmatrix3x3 *matrix, float m3[3][4]) +DO_INLINE void init_bfmatrix(fmatrix3x3 *matrix, float m3[3][3]) { unsigned int i; @@ -759,55 +558,36 @@ DO_INLINE void mul_bfmatrix_S(fmatrix3x3 *matrix, float scalar) } /* SPARSE SYMMETRIC multiply big matrix with long vector*/ /* STATUS: verified */ -void mul_bfmatrix_lfvector( lfVector *to, fmatrix3x3 *from, lfVector *fLongVector) +DO_INLINE void mul_bfmatrix_lfvector( float (*to)[3], fmatrix3x3 *from, lfVector *fLongVector) { - unsigned int i = 0, numverts = from[0].vcount; - // lfVector *tflongvector = create_lfvector(numverts); - float temp[4]={0,0,0,0}; + unsigned int i = 0; + lfVector *temp = create_lfvector(from[0].vcount); - zero_lfvector(to, numverts); - /* -#pragma omp parallel sections private(i) -{ -#pragma omp section - { - for(i = numverts; i < numverts+from[0].scount; i++) - { - muladd_fmatrix_fvector(to[from[i].c], from[i].m, fLongVector[from[i].r]); - - } - } -#pragma omp section - { - for(i = 0; i < numverts+from[0].scount; i++) - { - muladd_fmatrix_fvector(tflongvector[from[i].r], from[i].m, fLongVector[from[i].c]); - } - } -} - - add_lfvector(to, tflongvector, numverts); - - del_lfvector(tflongvector); - */ - // alternative NON OpenMP code - /* process diagonal elements */ - - for(i = 0; i < from[0].vcount; i++) - { - mul_fmatrix_fvector(to[from[i].r], from[i].m, fLongVector[from[i].c]); - } - - /* process off-diagonal entries (every off-diagonal entry needs to be symmetric) */ - - for(i = from[0].vcount; i < from[0].vcount+from[0].scount; i++) - { - muladd_fmatrix_fvector(to[from[i].c], from[i].m, fLongVector[from[i].r]); - muladd_fmatrix_fvector(to[from[i].r], from[i].m, fLongVector[from[i].c]); - } - -} + zero_lfvector(to, from[0].vcount); +#pragma omp parallel sections private(i) + { +#pragma omp section + { + for(i = from[0].vcount; i < from[0].vcount+from[0].scount; i++) + { + muladd_fmatrix_fvector(to[from[i].c], from[i].m, fLongVector[from[i].r]); + } + } +#pragma omp section + { + for(i = 0; i < from[0].vcount+from[0].scount; i++) + { + muladd_fmatrix_fvector(temp[from[i].r], from[i].m, fLongVector[from[i].c]); + } + } + } + add_lfvector_lfvector(to, to, temp, from[0].vcount); + + del_lfvector(temp); + + +} /* SPARSE SYMMETRIC add big matrix with big matrix: A = B + C*/ DO_INLINE void add_bfmatrix_bfmatrix( fmatrix3x3 *to, fmatrix3x3 *from, fmatrix3x3 *matrix) { @@ -898,8 +678,8 @@ DO_INLINE void subadd_bfmatrixS_bfmatrixS( fmatrix3x3 *to, fmatrix3x3 *from, flo /////////////////////////////////////////////////////////////////// // simulator start /////////////////////////////////////////////////////////////////// -static float I[3][4] = {{1,0,0,0},{0,1,0,0},{0,0,1,0}}; -static float ZERO[3][4] = {{0,0,0,0},{0,0,0,0},{0,0,0,0}}; +static float I[3][3] = {{1,0,0},{0,1,0},{0,0,1}}; +static float ZERO[3][3] = {{0,0,0}, {0,0,0}, {0,0,0}}; typedef struct Implicit_Data { lfVector *X, *V, *Xnew, *Vnew, *F, *B, *dV, *z; @@ -941,7 +721,6 @@ int implicit_init (Object *ob, ClothModifierData *clmd) id->F = create_lfvector(cloth->numverts); id->B = create_lfvector(cloth->numverts); id->dV = create_lfvector(cloth->numverts); - zero_lfvector(id->dV, cloth->numverts); id->z = create_lfvector(cloth->numverts); for(i=0;inumverts;i++) @@ -971,7 +750,7 @@ int implicit_init (Object *ob, ClothModifierData *clmd) // dFdV_start[i].c = big_I[i].c = big_zero[i].c = id->A[i+cloth->numverts].c = id->dFdV[i+cloth->numverts].c = id->dFdX[i+cloth->numverts].c = - id->P[i+cloth->numverts].c = id->Pinv[i+cloth->numverts].c = id->bigI[i+cloth->numverts].c = spring->kl; + id->P[i+cloth->numverts].c = id->Pinv[i+cloth->numverts].c = id->bigI[i+cloth->numverts].c = spring->kl; spring->matrix_index = i + cloth->numverts; @@ -985,7 +764,7 @@ int implicit_init (Object *ob, ClothModifierData *clmd) return 1; } -int implicit_free (ClothModifierData *clmd) +int implicit_free (ClothModifierData *clmd) { Implicit_Data *id; Cloth *cloth; @@ -1096,7 +875,7 @@ DO_INLINE void filter(lfVector *V, fmatrix3x3 *S) } } -int cg_filtered(lfVector *ldV, fmatrix3x3 *lA, lfVector *lB, lfVector *z, fmatrix3x3 *S) +int cg_filtered(lfVector *dv, fmatrix3x3 *lA, lfVector *lB, lfVector *z, fmatrix3x3 *S) { // Solves for unknown X in equation AX=B unsigned int conjgrad_loopcount=0, conjgrad_looplimit=100; @@ -1108,22 +887,24 @@ int cg_filtered(lfVector *ldV, fmatrix3x3 *lA, lfVector *lB, lfVector *z, fmatr d = create_lfvector(numverts); tmp = create_lfvector(numverts); r = create_lfvector(numverts); - - // zero_lfvector(ldV, numverts); - filter(ldV, S); - add_lfvector_lfvector(ldV, ldV, z, numverts); + + // zero_lfvector(dv, CLOTHPARTICLES); + filter(dv, S); + + add_lfvector_lfvector(dv, dv, z, numverts); // r = B - Mul(tmp,A,X); // just use B if X known to be zero - mul_bfmatrix_lfvector(r, lA, ldV); - sub_lfvector_lfvector(r, lB, r, numverts); - filter(r, S); + cp_lfvector(r, lB, numverts); + mul_bfmatrix_lfvector(tmp, lA, dv); + sub_lfvector_lfvector(r, r, tmp, numverts); + + filter(r,S); cp_lfvector(d, r, numverts); s = dot_lfvector(r, r, numverts); - starget = s * conjgrad_epsilon; - - // itstart(); + starget = s * sqrt(conjgrad_epsilon); + while((s>starget && conjgrad_loopcount < conjgrad_looplimit)) { // Mul(q,A,d); // q = A*d; @@ -1134,14 +915,13 @@ int cg_filtered(lfVector *ldV, fmatrix3x3 *lA, lfVector *lB, lfVector *z, fmatr a = s/dot_lfvector(d, q, numverts); // X = X + d*a; - add_lfvector_lfvectorS(ldV, ldV, d, a, numverts); - - s_prev = s; + add_lfvector_lfvectorS(dv, dv, d, a, numverts); // r = r - q*a; - add_lfvector_lfvectorS(r, r, q, -a, numverts); + sub_lfvector_lfvectorS(r, r, q, a, numverts); + + s_prev = s; s = dot_lfvector(r, r, numverts); - // s = add_lfvectorS_dot(r, q, -a, numverts); //d = r+d*(s/s_prev); add_lfvector_lfvectorS(d, r, d, (s/s_prev), numverts); @@ -1195,7 +975,7 @@ int cg_filtered_pre(lfVector *dv, fmatrix3x3 *lA, lfVector *lB, lfVector *z, fma BuildPPinv(lA, P, Pinv); filter(dv, S); - add_lfvector(dv, z, numverts); + add_lfvector_lfvector(dv, dv, z, numverts); mul_bfmatrix_lfvector(r, lA, dv); sub_lfvector_lfvector(r, lB, r, numverts); @@ -1204,11 +984,13 @@ int cg_filtered_pre(lfVector *dv, fmatrix3x3 *lA, lfVector *lB, lfVector *z, fma mul_bfmatrix_lfvector(p, Pinv, r); filter(p, S); - deltaNew = delta0 = dot_lfvector(r, p, numverts); + deltaNew = dot_lfvector(r, p, numverts); + + delta0 = deltaNew * sqrt(conjgrad_epsilon); // itstart(); - while ((deltaNew > (conjgrad_epsilon*delta0)) && (iterations < conjgrad_looplimit)) + while ((deltaNew > delta0) && (iterations < conjgrad_looplimit)) { iterations++; @@ -1217,9 +999,9 @@ int cg_filtered_pre(lfVector *dv, fmatrix3x3 *lA, lfVector *lB, lfVector *z, fma alpha = deltaNew / dot_lfvector(p, s, numverts); - add_lfvectorS(dv, p, alpha, numverts); + add_lfvector_lfvectorS(dv, dv, p, alpha, numverts); - add_lfvectorS(r, s, -alpha, numverts); + add_lfvector_lfvectorS(r, r, s, -alpha, numverts); mul_bfmatrix_lfvector(h, Pinv, r); filter(h, S); @@ -1247,11 +1029,11 @@ int cg_filtered_pre(lfVector *dv, fmatrix3x3 *lA, lfVector *lB, lfVector *z, fma } // outer product is NOT cross product!!! -DO_INLINE void dfdx_spring_type1(float to[3][4], float dir[3],float length,float L,float k) +DO_INLINE void dfdx_spring_type1(float to[3][3], float dir[3],float length,float L,float k) { // dir is unit length direction, rest is spring's restlength, k is spring constant. // return (outerprod(dir,dir)*k + (I - outerprod(dir,dir))*(k - ((k*L)/length))); - float temp[3][4]; + float temp[3][3]; mul_fvectorT_fvector(temp, dir, dir); sub_fmatrix_fmatrix(to, I, temp); mul_fmatrix_S(to, k* (1.0f-(L/length))); @@ -1259,20 +1041,20 @@ DO_INLINE void dfdx_spring_type1(float to[3][4], float dir[3],float length,float add_fmatrix_fmatrix(to, temp, to); } -DO_INLINE void dfdx_spring_type2(float to[3][4], float dir[3],float length,float L,float k, float cb) +DO_INLINE void dfdx_spring_type2(float to[3][3], float dir[3],float length,float L,float k, float cb) { // return outerprod(dir,dir)*fbstar_jacobi(length, L, k, cb); mul_fvectorT_fvectorS(to, dir, dir, fbstar_jacobi(length, L, k, cb)); } -DO_INLINE void dfdv_damp(float to[3][4], float dir[3], float damping) +DO_INLINE void dfdv_damp(float to[3][3], float dir[3], float damping) { // derivative of force wrt velocity. // return outerprod(dir,dir) * damping; mul_fvectorT_fvectorS(to, dir, dir, damping); } -DO_INLINE void dfdx_spring(float to[3][4], float dir[3],float length,float L,float k) +DO_INLINE void dfdx_spring(float to[3][3], float dir[3],float length,float L,float k) { // dir is unit length direction, rest is spring's restlength, k is spring constant. //return ( (I-outerprod(dir,dir))*Min(1.0f,rest/length) - I) * -k; @@ -1283,7 +1065,7 @@ DO_INLINE void dfdx_spring(float to[3][4], float dir[3],float length,float L,fl mul_fmatrix_S(to, -k); } -DO_INLINE void dfdx_damp(float to[3][4], float dir[3],float length,const float vel[3],float rest,float damping) +DO_INLINE void dfdx_damp(float to[3][3], float dir[3],float length,const float vel[3],float rest,float damping) { // inner spring damping vel is the relative velocity of the endpoints. // return (I-outerprod(dir,dir)) * (-damping * -(dot(dir,vel)/Max(length,rest))); @@ -1293,12 +1075,12 @@ DO_INLINE void dfdx_damp(float to[3][4], float dir[3],float length,const float } -DO_INLINE void cloth_calc_spring_force(ClothModifierData *clmd, ClothSpring *s, lfVector *lF, lfVector *X, lfVector *V, fmatrix3x3 *dFdV, fmatrix3x3 *dFdX, float dt) +DO_INLINE void cloth_calc_spring_force(ClothModifierData *clmd, ClothSpring *s, lfVector *lF, lfVector *X, lfVector *V, fmatrix3x3 *dFdV, fmatrix3x3 *dFdX) { float extent[3]; float length = 0; float dir[3] = {0,0,0}; - float vel[3] = {0,0,0}; + float vel[3]; float k = 0.0f; float L = s->restlen; float cb = clmd->sim_parms->structural; @@ -1307,7 +1089,7 @@ DO_INLINE void cloth_calc_spring_force(ClothModifierData *clmd, ClothSpring *s, float stretch_force[3] = {0,0,0}; float bending_force[3] = {0,0,0}; float damping_force[3] = {0,0,0}; - float nulldfdx[3][4]={ {0,0,0,0}, {0,0,0,0}, {0,0,0,0}}; + float nulldfdx[3][3]={ {0,0,0}, {0,0,0}, {0,0,0}}; VECCOPY(s->f, nullf); cp_fmatrix(s->dfdx, nulldfdx); @@ -1325,13 +1107,13 @@ DO_INLINE void cloth_calc_spring_force(ClothModifierData *clmd, ClothSpring *s, /* if(length>L) { - if((clmd->sim_parms->flags & CSIMSETT_FLAG_TEARING_ENABLED) - && ((((length-L)*100.0f/L) > clmd->sim_parms->maxspringlen))) // cut spring! - { - s->flags |= CSPRING_FLAG_DEACTIVATE; - return; - } - } + if((clmd->sim_parms->flags & CSIMSETT_FLAG_TEARING_ENABLED) + && ((((length-L)*100.0f/L) > clmd->sim_parms->maxspringlen))) // cut spring! + { + s->flags |= CSPRING_FLAG_DEACTIVATE; + return; + } + } */ mul_fvector_S(dir, extent, 1.0f/length); } @@ -1348,24 +1130,19 @@ DO_INLINE void cloth_calc_spring_force(ClothModifierData *clmd, ClothSpring *s, { s->flags |= CLOTH_SPRING_FLAG_NEEDED; - k = (clmd->sim_parms->structural*(length-L)); + k = clmd->sim_parms->structural; - mul_fvector_S(stretch_force, dir, k); + mul_fvector_S(stretch_force, dir, (k*(length-L))); VECADD(s->f, s->f, stretch_force); // Ascher & Boxman, p.21: Damping only during elonglation - mul_fvector_S(damping_force, extent, clmd->sim_parms->Cdis * 0.01 * ((INPR(vel,extent)/length))); + mul_fvector_S(damping_force, extent, clmd->sim_parms->Cdis * ((INPR(vel,extent)/length))); VECADD(s->f, s->f, damping_force); - - // Formula from Ascher / Boxman, Speeding up cloth simulation - // couldn't see any speedup - // if((dt * (k*dt + 2 * clmd->sim_parms->Cdis * 0.01)) > 0.01 ) - { - dfdx_spring_type1(s->dfdx, dir,length,L,clmd->sim_parms->structural); - dfdv_damp(s->dfdv, dir,clmd->sim_parms->Cdis * 0.01); - } - // printf("(dt*k*dt) ): %f, k: %f\n", (dt * (k*dt + 2 * clmd->sim_parms->Cdis * 0.01) ), k); + + dfdx_spring_type1(s->dfdx, dir,length,L,k); + + dfdv_damp(s->dfdv, dir,clmd->sim_parms->Cdis); } } else // calculate force of bending springs @@ -1376,19 +1153,17 @@ DO_INLINE void cloth_calc_spring_force(ClothModifierData *clmd, ClothSpring *s, s->flags |= CLOTH_SPRING_FLAG_NEEDED; - k = fbstar(length, L, clmd->sim_parms->bending, cb); + k = clmd->sim_parms->bending; - mul_fvector_S(bending_force, dir, k); + mul_fvector_S(bending_force, dir, fbstar(length, L, k, cb)); VECADD(s->f, s->f, bending_force); - // DG: My formula to handle bending for the AIMEX scheme - // multiply with 1000 because of numerical problems - // if( ((k*1000.0)*dt*dt) < -0.18 ) + if(INPR(bending_force,bending_force) > 0.13*0.13) { - dfdx_spring_type2(s->dfdx, dir,length,L,clmd->sim_parms->bending, cb); clmd->sim_parms->flags |= CLOTH_SIMSETTINGS_FLAG_BIG_FORCE; } - // printf("(dt*k*dt) ): %f, k: %f\n", (dt*dt*(1000.0*k)), k); + + dfdx_spring_type2(s->dfdx, dir,length,L,k, cb); } } } @@ -1406,8 +1181,8 @@ DO_INLINE int cloth_apply_spring_force(ClothModifierData *clmd, ClothSpring *s, sub_fmatrix_fmatrix(dFdV[s->kl].m, dFdV[s->kl].m, s->dfdv); add_fmatrix_fmatrix(dFdV[s->matrix_index].m, dFdV[s->matrix_index].m, s->dfdv); } - // else if(!(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_BIG_FORCE)) - // return 0; + else if(!(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_BIG_FORCE)) + return 0; sub_fmatrix_fmatrix(dFdX[s->ij].m, dFdX[s->ij].m, s->dfdx); sub_fmatrix_fmatrix(dFdX[s->kl].m, dFdX[s->kl].m, s->dfdx); @@ -1459,14 +1234,14 @@ DO_INLINE void calc_triangle_force(ClothModifierData *clmd, MFace mface, lfVecto } -void cloth_calc_force(ClothModifierData *clmd, lfVector *lF, lfVector *lX, lfVector *lV, fmatrix3x3 *dFdV, fmatrix3x3 *dFdX, ListBase *effectors, float time, float dt) +void cloth_calc_force(ClothModifierData *clmd, lfVector *lF, lfVector *lX, lfVector *lV, fmatrix3x3 *dFdV, fmatrix3x3 *dFdX, ListBase *effectors, float time) { /* Collect forces and derivatives: F,dFdX,dFdV */ Cloth *cloth = clmd->clothObject; unsigned int i = 0; float spring_air = clmd->sim_parms->Cvi * 0.01f; /* viscosity of air scaled in percent */ float gravity[3]; - float tm2[3][4] = {{-spring_air,0,0,0}, {0,-spring_air,0,0},{0,0,-spring_air,0}}; + float tm2[3][3] = {{-spring_air,0,0}, {0,-spring_air,0},{0,0,-spring_air}}; ClothVertex *verts = cloth->verts; MFace *mfaces = cloth->mfaces; float wind_normalized[3]; @@ -1518,7 +1293,7 @@ void cloth_calc_force(ClothModifierData *clmd, lfVector *lF, lfVector *lX, lfVec float speed[3] = {0.0f, 0.0f,0.0f}; float force[3]= {0.0f, 0.0f, 0.0f}; - #pragma omp parallel for private (i) shared(lF) schedule(static) +#pragma omp parallel for private (i) shared(lF) for(i = 0; i < cloth->numverts; i++) { float vertexnormal[3]={0,0,0}; @@ -1543,7 +1318,7 @@ void cloth_calc_force(ClothModifierData *clmd, lfVector *lF, lfVector *lX, lfVec { // only handle active springs // if(((clmd->sim_parms->flags & CSIMSETT_FLAG_TEARING_ENABLED) && !(springs[i].flags & CSPRING_FLAG_DEACTIVATE))|| !(clmd->sim_parms->flags & CSIMSETT_FLAG_TEARING_ENABLED)){} - cloth_calc_spring_force(clmd, search->link, lF, lX, lV, dFdV, dFdX, dt); + cloth_calc_spring_force(clmd, search->link, lF, lX, lV, dFdV, dFdX); search = search->next; } @@ -1578,52 +1353,38 @@ void cloth_calc_force(ClothModifierData *clmd, lfVector *lF, lfVector *lX, lfVec } - void simulate_implicit_euler(lfVector *Vnew, lfVector *lX, lfVector *lV, lfVector *lF, fmatrix3x3 *dFdV, fmatrix3x3 *dFdX, float dt, fmatrix3x3 *A, lfVector *B, lfVector *dV, fmatrix3x3 *S, lfVector *z, fmatrix3x3 *P, fmatrix3x3 *Pinv) { unsigned int numverts = dFdV[0].vcount; lfVector *dFdXmV = create_lfvector(numverts); - initdiag_bfmatrix(A, I); - + zero_lfvector(dV, numverts); + subadd_bfmatrixS_bfmatrixS(A, dFdV, dt, dFdX, (dt*dt)); mul_bfmatrix_lfvector(dFdXmV, dFdX, lV); add_lfvectorS_lfvectorS(B, lF, dt, dFdXmV, (dt*dt), numverts); - // cg_filtered(dV, A, B, z, S); // conjugate gradient algorithm to solve Ax=b - cg_filtered_pre(dV, A, B, z, S, P, Pinv); + // itstart(); + + cg_filtered(dV, A, B, z, S); /* conjugate gradient algorithm to solve Ax=b */ + + // TODO: if anyone finds a way to correct this function => + // explodes with stiffness = 3000 and 16k verts + pinned at 2 corners + // cg_filtered_pre(dV, A, B, z, S, P, Pinv); + + // itend(); + // printf("cg_filtered calc time: %f\n", (float)itval()); // advance velocities add_lfvector_lfvector(Vnew, lV, dV, numverts); + del_lfvector(dFdXmV); } -/* -// this version solves for the new velocity -void simulate_implicit_euler(lfVector *Vnew, lfVector *lX, lfVector *lV, lfVector *lF, fmatrix3x3 *dFdV, fmatrix3x3 *dFdX, float dt, fmatrix3x3 *A, lfVector *B, lfVector *dV, fmatrix3x3 *S, lfVector *z, fmatrix3x3 *P, fmatrix3x3 *Pinv) -{ - unsigned int numverts = dFdV[0].vcount; - - lfVector *dFdXmV = create_lfvector(numverts); - - initdiag_bfmatrix(A, I); - - subadd_bfmatrixS_bfmatrixS(A, dFdV, dt, dFdX, (dt*dt)); - - mul_bfmatrix_lfvector(dFdXmV, dFdV, lV); - - add_lfvectorS_lfvectorS(B, lF, dt, dFdXmV, -dt, numverts); - add_lfvector_lfvector(B, B, lV, numverts); - - cg_filtered_pre(Vnew, A, B, z, S, P, Pinv); - - del_lfvector(dFdXmV); -} -*/ int implicit_solver (Object *ob, float frame, ClothModifierData *clmd, ListBase *effectors) { unsigned int i=0; @@ -1635,7 +1396,7 @@ int implicit_solver (Object *ob, float frame, ClothModifierData *clmd, ListBase Implicit_Data *id = cloth->implicit; int result = 0; float force = 0, lastforce = 0; - lfVector *dx; + // lfVector *dx; if(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL) /* do goal stuff */ { @@ -1655,7 +1416,7 @@ int implicit_solver (Object *ob, float frame, ClothModifierData *clmd, ListBase effectors= pdInitEffectors(ob,NULL); // calculate - cloth_calc_force(clmd, id->F, id->X, id->V, id->dFdV, id->dFdX, effectors, step, dt ); + cloth_calc_force(clmd, id->F, id->X, id->V, id->dFdV, id->dFdX, effectors, step ); // check for sleeping // if(!(clmd->coll_parms->flags & CLOTH_SIMSETTINGS_FLAG_SLEEP)) @@ -1664,19 +1425,17 @@ int implicit_solver (Object *ob, float frame, ClothModifierData *clmd, ListBase add_lfvector_lfvectorS(id->Xnew, id->X, id->Vnew, dt, numverts); } - + /* dx = create_lfvector(numverts); sub_lfvector_lfvector(dx, id->Xnew, id->X, numverts); force = dot_lfvector(dx, dx, numverts); del_lfvector(dx); - /* if((force < 0.00001) && (lastforce >= force)) - clmd->coll_parms->flags |= CLOTH_SIMSETTINGS_FLAG_SLEEP; + clmd->coll_parms->flags |= CLOTH_SIMSETTINGS_FLAG_SLEEP; else if((lastforce*2 < force)) + clmd->coll_parms->flags &= ~CLOTH_SIMSETTINGS_FLAG_SLEEP; */ - clmd->coll_parms->flags &= ~CLOTH_SIMSETTINGS_FLAG_SLEEP; - lastforce = force; if(clmd->coll_parms->flags & CLOTH_COLLISIONSETTINGS_FLAG_ENABLED) @@ -1706,7 +1465,7 @@ int implicit_solver (Object *ob, float frame, ClothModifierData *clmd, ListBase } // call collision function - result = cloth_bvh_objcollision(clmd, step + dt, step, dt); + result = 0; // cloth_bvh_objcollision(clmd, step + dt, step, dt); // copy corrected positions back to simulation if(result) @@ -1735,7 +1494,7 @@ int implicit_solver (Object *ob, float frame, ClothModifierData *clmd, ListBase cp_lfvector(id->V, id->Vnew, numverts); // calculate - cloth_calc_force(clmd, id->F, id->X, id->V, id->dFdV, id->dFdX, effectors, step, dt); + cloth_calc_force(clmd, id->F, id->X, id->V, id->dFdV, id->dFdX, effectors, step); simulate_implicit_euler(id->Vnew, id->X, id->V, id->F, id->dFdV, id->dFdX, dt / 2.0f, id->A, id->B, id->dV, id->S, id->z, id->P, id->Pinv); } @@ -1775,19 +1534,11 @@ int implicit_solver (Object *ob, float frame, ClothModifierData *clmd, ListBase } else { - for(i = 0; i < numverts; i++) - { - VECCOPY(cloth->current_xold[i], id->X[i]); - VECCOPY(cloth->x[i], id->X[i]); - } - // memcpy(cloth->current_xold, id->X, sizeof(lfVector) * numverts); - // memcpy(cloth->x, id->X, sizeof(lfVector) * numverts); + memcpy(cloth->current_xold, id->X, sizeof(lfVector) * numverts); + memcpy(cloth->x, id->X, sizeof(lfVector) * numverts); } - for(i = 0; i < numverts; i++) - VECCOPY(cloth->v[i], id->V[i]); - - // memcpy(cloth->v, id->V, sizeof(lfVector) * numverts); + memcpy(cloth->v, id->V, sizeof(lfVector) * numverts); return 1; } @@ -1795,18 +1546,11 @@ int implicit_solver (Object *ob, float frame, ClothModifierData *clmd, ListBase void implicit_set_positions (ClothModifierData *clmd) { Cloth *cloth = clmd->clothObject; - unsigned int numverts = cloth->numverts, i = 0; + unsigned int numverts = cloth->numverts; Implicit_Data *id = cloth->implicit; - - for(i = 0; i < numverts; i++) - { - VECCOPY(id->X[i], cloth->x[i]); - VECCOPY(id->V[i], cloth->v[i]); - } - - // memcpy(id->X, cloth->x, sizeof(lfVector) * numverts); - // memcpy(id->V, cloth->v, sizeof(lfVector) * numverts); + memcpy(id->X, cloth->x, sizeof(lfVector) * numverts); + memcpy(id->V, cloth->v, sizeof(lfVector) * numverts); } @@ -1825,7 +1569,7 @@ int collisions_collision_response_static(ClothModifierData *clmd, ClothModifierD cloth1 = clmd->clothObject; cloth2 = coll_clmd->clothObject; - // search = clmd->coll_parms->collision_list; + // search = clmd->coll_parms.collision_list; while(search) { @@ -1868,10 +1612,10 @@ int collisions_collision_response_static(ClothModifierData *clmd, ClothModifierD float vrel_t_pre[3]; float vrel_t[3]; double impulse; - float epsilon = clmd->coll_parms->epsilon; + float epsilon = clmd->coll_parms.epsilon; float overlap = (epsilon + ALMOST_ZERO-collpair->distance); - // calculateFrictionImpulse(tangential, relativeVelocity, collpair->normal, magrelVel, clmd->coll_parms->friction*0.01, magrelVel); + // calculateFrictionImpulse(tangential, relativeVelocity, collpair->normal, magrelVel, clmd->coll_parms.friction*0.01, magrelVel); // magtangent = INPR(tangential, tangential); @@ -2071,20 +1815,20 @@ int collisions_are_edges_adjacent(ClothModifierData *clmd, ClothModifierData *co VECSUB(temp, verts1[edgecollpair->p11].xold, verts2[edgecollpair->p21].xold); if(ABS(INPR(temp, temp)) < ALMOST_ZERO) - return 1; + return 1; VECSUB(temp, verts1[edgecollpair->p11].xold, verts2[edgecollpair->p22].xold); if(ABS(INPR(temp, temp)) < ALMOST_ZERO) - return 1; + return 1; VECSUB(temp, verts1[edgecollpair->p12].xold, verts2[edgecollpair->p21].xold); if(ABS(INPR(temp, temp)) < ALMOST_ZERO) - return 1; + return 1; VECSUB(temp, verts1[edgecollpair->p12].xold, verts2[edgecollpair->p22].xold); if(ABS(INPR(temp, temp)) < ALMOST_ZERO) - return 1; - */ + return 1; + */ return 0; } @@ -2345,7 +2089,7 @@ int cloth_bvh_objcollision(ClothModifierData * clmd, float step, float prevstep, LinkNode *collision_list = NULL; unsigned int i = 0, j = 0; int collisions = 0, count = 0; - float (*current_x)[4]; + float (*current_x)[3]; if (!(((Cloth *)clmd->clothObject)->tree)) { @@ -2362,57 +2106,57 @@ int cloth_bvh_objcollision(ClothModifierData * clmd, float step, float prevstep, //////////////////////////////////////////////////////////// // update cloth bvh - bvh_update_from_float4(bvh1, cloth->current_xold, cloth->numverts, cloth->current_x, 0); // 0 means STATIC, 1 means MOVING (see later in this function) + bvh_update_from_float3(bvh1, cloth->current_xold, cloth->numverts, cloth->current_x, 0); // 0 means STATIC, 1 means MOVING (see later in this function) /* // check all collision objects for (base = G.scene->base.first; base; base = base->next) { - ob2 = base->object; - collmd = (CollisionModifierData *) modifiers_findByType (ob2, eModifierType_Collision); + ob2 = base->object; + collmd = (CollisionModifierData *) modifiers_findByType (ob2, eModifierType_Collision); - if (!collmd) - continue; + if (!collmd) + continue; // check if there is a bounding volume hierarchy - if (collmd->tree) - { - bvh2 = collmd->tree; + if (collmd->tree) + { + bvh2 = collmd->tree; // update position + bvh of collision object - collision_move_object(collmd, step, prevstep); - bvh_update_from_mvert(collmd->tree, collmd->current_x, collmd->numverts, NULL, 0); + collision_move_object(collmd, step, prevstep); + bvh_update_from_mvert(collmd->tree, collmd->current_x, collmd->numverts, NULL, 0); // fill collision list - collisions += bvh_traverse(bvh1->root, bvh2->root, &collision_list); + collisions += bvh_traverse(bvh1->root, bvh2->root, &collision_list); // call static collision response // free collision list - if(collision_list) - { - LinkNode *search = collision_list; + if(collision_list) + { + LinkNode *search = collision_list; - while(search) - { - CollisionPair *coll_pair = search->link; + while(search) + { + CollisionPair *coll_pair = search->link; - MEM_freeN(coll_pair); - search = search->next; - } - BLI_linklist_free(collision_list,NULL); + MEM_freeN(coll_pair); + search = search->next; +} + BLI_linklist_free(collision_list,NULL); - collision_list = NULL; - } - } - } + collision_list = NULL; +} +} +} ////////////////////////////////////////////// // update velocities + positions ////////////////////////////////////////////// for(i = 0; i < cloth->numverts; i++) { - VECADD(cloth->current_x[i], cloth->current_xold[i], cloth->current_v[i]); - } + VECADD(cloth->current_x[i], cloth->current_xold[i], cloth->current_v[i]); +} ////////////////////////////////////////////// */ /* @@ -2424,68 +2168,68 @@ int cloth_bvh_objcollision(ClothModifierData * clmd, float step, float prevstep, // free collision list if(collision_list) { - LinkNode *search = collision_list; + LinkNode *search = collision_list; - while(search) - { - float distance = 0; - float mindistance = cloth->selftree->epsilon; - CollisionPair *collpair = (CollisionPair *)search->link; + while(search) + { + float distance = 0; + float mindistance = cloth->selftree->epsilon; + CollisionPair *collpair = (CollisionPair *)search->link; // get distance of faces - distance = plNearestPoints( - cloth->current_x[collpair->point_indexA[0]], cloth->current_x[collpair->point_indexA[1]], cloth->current_x[collpair->point_indexA[2]], cloth->current_x[collpair->point_indexB[0]], cloth->current_x[collpair->point_indexB[1]], cloth->current_x[collpair->point_indexB[2]], collpair->pa,collpair->pb,collpair->vector); + distance = plNearestPoints( + cloth->current_x[collpair->point_indexA[0]], cloth->current_x[collpair->point_indexA[1]], cloth->current_x[collpair->point_indexA[2]], cloth->current_x[collpair->point_indexB[0]], cloth->current_x[collpair->point_indexB[1]], cloth->current_x[collpair->point_indexB[2]], collpair->pa,collpair->pb,collpair->vector); - if(distance < mindistance) - { - /////////////////////////////////////////// + if(distance < mindistance) + { + /////////////////////////////////////////// // TODO: take velocity of the collision points into account! - /////////////////////////////////////////// + /////////////////////////////////////////// - float correction = mindistance - distance; - float temp[3]; + float correction = mindistance - distance; + float temp[3]; - VECCOPY(temp, collpair->vector); - Normalize(temp); - VecMulf(temp, -correction*0.5); + VECCOPY(temp, collpair->vector); + Normalize(temp); + VecMulf(temp, -correction*0.5); - if(!((clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL) && (cloth->verts [collpair->point_indexA[0]].goal >= SOFTGOALSNAP))) - VECSUB(cloth->current_x[collpair->point_indexA[0]], cloth->current_x[collpair->point_indexA[0]], temp); + if(!((clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL) && (cloth->verts [collpair->point_indexA[0]].goal >= SOFTGOALSNAP))) + VECSUB(cloth->current_x[collpair->point_indexA[0]], cloth->current_x[collpair->point_indexA[0]], temp); - if(!((clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL) && (cloth->verts [collpair->point_indexA[1]].goal >= SOFTGOALSNAP))) - VECSUB(cloth->current_x[collpair->point_indexA[1]], cloth->current_x[collpair->point_indexA[1]], temp); + if(!((clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL) && (cloth->verts [collpair->point_indexA[1]].goal >= SOFTGOALSNAP))) + VECSUB(cloth->current_x[collpair->point_indexA[1]], cloth->current_x[collpair->point_indexA[1]], temp); - if(!((clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL) && (cloth->verts [collpair->point_indexA[2]].goal >= SOFTGOALSNAP))) - VECSUB(cloth->current_x[collpair->point_indexA[2]], cloth->current_x[collpair->point_indexA[2]], temp); + if(!((clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL) && (cloth->verts [collpair->point_indexA[2]].goal >= SOFTGOALSNAP))) + VECSUB(cloth->current_x[collpair->point_indexA[2]], cloth->current_x[collpair->point_indexA[2]], temp); - if(!((clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL) && (cloth->verts [collpair->point_indexB[0]].goal >= SOFTGOALSNAP))) - VECSUB(cloth->current_x[collpair->point_indexB[0]], cloth->current_x[collpair->point_indexB[0]], temp); + if(!((clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL) && (cloth->verts [collpair->point_indexB[0]].goal >= SOFTGOALSNAP))) + VECSUB(cloth->current_x[collpair->point_indexB[0]], cloth->current_x[collpair->point_indexB[0]], temp); - if(!((clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL) && (cloth->verts [collpair->point_indexB[1]].goal >= SOFTGOALSNAP))) - VECSUB(cloth->current_x[collpair->point_indexB[1]], cloth->current_x[collpair->point_indexB[1]], temp); + if(!((clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL) && (cloth->verts [collpair->point_indexB[1]].goal >= SOFTGOALSNAP))) + VECSUB(cloth->current_x[collpair->point_indexB[1]], cloth->current_x[collpair->point_indexB[1]], temp); - if(!((clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL) && (cloth->verts [collpair->point_indexB[2]].goal >= SOFTGOALSNAP))) - VECSUB(cloth->current_x[collpair->point_indexB[2]], cloth->current_x[collpair->point_indexB[2]], temp); + if(!((clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL) && (cloth->verts [collpair->point_indexB[2]].goal >= SOFTGOALSNAP))) + VECSUB(cloth->current_x[collpair->point_indexB[2]], cloth->current_x[collpair->point_indexB[2]], temp); - collisions = 1; + collisions = 1; - } +} - } +} - search = collision_list; - while(search) - { - CollisionPair *coll_pair = search->link; + search = collision_list; + while(search) + { + CollisionPair *coll_pair = search->link; - MEM_freeN(coll_pair); - search = search->next; - } - BLI_linklist_free(collision_list,NULL); + MEM_freeN(coll_pair); + search = search->next; +} + BLI_linklist_free(collision_list,NULL); - collision_list = NULL; - } + collision_list = NULL; +} */ // Test on *simple* selfcollisions collisions = 1; @@ -2495,62 +2239,62 @@ int cloth_bvh_objcollision(ClothModifierData * clmd, float step, float prevstep, #pragma omp parallel for private(i,j, collisions) shared(current_x) for(count = 0; count < 6; count++) { - collisions = 0; + collisions = 0; - for(i = 0; i < cloth->numverts; i++) - { - for(j = i + 1; j < cloth->numverts; j++) - { - float temp[3]; - float length = 0; - float mindistance = cloth->selftree->epsilon; + for(i = 0; i < cloth->numverts; i++) + { + for(j = i + 1; j < cloth->numverts; j++) + { + float temp[3]; + float length = 0; + float mindistance = cloth->selftree->epsilon; - if(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL) - { - if((cloth->verts [i].goal >= SOFTGOALSNAP) - && (cloth->verts [j].goal >= SOFTGOALSNAP)) - { - continue; - } - } + if(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL) + { + if((cloth->verts [i].goal >= SOFTGOALSNAP) + && (cloth->verts [j].goal >= SOFTGOALSNAP)) + { + continue; +} +} // check for adjacent points - if(BLI_edgehash_haskey ( cloth->edgehash, i, j )) - { - continue; - } + if(BLI_edgehash_haskey ( cloth->edgehash, i, j )) + { + continue; +} - VECSUB(temp, current_x[i], current_x[j]); + VECSUB(temp, current_x[i], current_x[j]); - length = Normalize(temp); + length = Normalize(temp); - if(length < mindistance) - { - float correction = mindistance - length; + if(length < mindistance) + { + float correction = mindistance - length; - if((clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL) && (cloth->verts [i].goal >= SOFTGOALSNAP)) - { - VecMulf(temp, -correction); - VECADD(current_x[j], current_x[j], temp); - } - else if((clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL) && (cloth->verts [j].goal >= SOFTGOALSNAP)) - { - VecMulf(temp, correction); - VECADD(current_x[i], current_x[i], temp); - } - else - { - VecMulf(temp, -correction*0.5); - VECADD(current_x[j], current_x[j], temp); + if((clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL) && (cloth->verts [i].goal >= SOFTGOALSNAP)) + { + VecMulf(temp, -correction); + VECADD(current_x[j], current_x[j], temp); +} + else if((clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL) && (cloth->verts [j].goal >= SOFTGOALSNAP)) + { + VecMulf(temp, correction); + VECADD(current_x[i], current_x[i], temp); +} + else + { + VecMulf(temp, -correction*0.5); + VECADD(current_x[j], current_x[j], temp); - VECSUB(current_x[i], current_x[i], temp); - } + VECSUB(current_x[i], current_x[i], temp); +} - collisions = 1; - } - } - } - } + collisions = 1; +} +} +} +} ////////////////////////////////////////////// @@ -2558,8 +2302,8 @@ int cloth_bvh_objcollision(ClothModifierData * clmd, float step, float prevstep, ////////////////////////////////////////////// for(i = 0; i < cloth->numverts; i++) { - VECSUB(cloth->current_v[i], cloth->current_x[i], cloth->current_xold[i]); - } + VECSUB(cloth->current_v[i], cloth->current_x[i], cloth->current_xold[i]); +} ////////////////////////////////////////////// */ return 1; From b5974a058610f9d1f799618724d9fb890fc0be26 Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Sun, 25 Nov 2007 03:46:41 +0000 Subject: [PATCH 057/246] little debug output for MT fluid --- intern/elbeem/intern/solver_main.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/intern/elbeem/intern/solver_main.cpp b/intern/elbeem/intern/solver_main.cpp index afc883972e2..8ec667b8cb6 100644 --- a/intern/elbeem/intern/solver_main.cpp +++ b/intern/elbeem/intern/solver_main.cpp @@ -363,7 +363,9 @@ LbmFsgrSolver::mainLoop(int lev) const int cutMin = 1; const int cutConst = mCutoff+2; - +#if PARALLEL==1 + printf("omp_get_num_threads: %d\n", omp_get_num_threads()); +#endif # if LBM_INCLUDE_TESTSOLVERS==1 // 3d region off... quit From c8a412cdcb4059990c2e23f42ee54691daedf13a Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Sun, 25 Nov 2007 21:14:52 +0000 Subject: [PATCH 058/246] Commit of fluid fix for 32/64bit and max 2.5gb ram issue --- intern/elbeem/intern/loop_tools.h | 2 +- intern/elbeem/intern/solver_init.cpp | 5 +++-- intern/elbeem/intern/solver_main.cpp | 5 +---- source/blender/blenkernel/BKE_cloth.h | 1 + source/blender/blenkernel/intern/implicit.c | 2 +- 5 files changed, 7 insertions(+), 8 deletions(-) diff --git a/intern/elbeem/intern/loop_tools.h b/intern/elbeem/intern/loop_tools.h index 70ecb9ce3e0..8ff51039bf2 100644 --- a/intern/elbeem/intern/loop_tools.h +++ b/intern/elbeem/intern/loop_tools.h @@ -91,7 +91,7 @@ calcListEmpty.reserve(mListEmpty.capacity() / omp_get_num_threads() ); \ calcListFull.reserve( mListFull.capacity() / omp_get_num_threads() ); \ calcListParts.reserve(mSizex); \ - \ + printf("omp_get_num_threads: %d\n", omp_get_num_threads()); \ \ const int id = omp_get_thread_num(); \ const int Nthrds = omp_get_num_threads(); \ diff --git a/intern/elbeem/intern/solver_init.cpp b/intern/elbeem/intern/solver_init.cpp index b0ce130c136..105c8ff3094 100644 --- a/intern/elbeem/intern/solver_init.cpp +++ b/intern/elbeem/intern/solver_init.cpp @@ -703,11 +703,12 @@ bool LbmFsgrSolver::initializeSolverMemory() memBlockAllocProblem = true; } #endif // Mac - if(sizeof(int)==4 && memEstFine>maxDefaultMemChunk) { + if(sizeof(void *)==4 && memEstFine>maxDefaultMemChunk) { // max memory chunk for 32bit systems 2gig memBlockAllocProblem = true; + } - + if(memEstFromFunc>memLimit || memBlockAllocProblem) { sizeReduction *= 0.9; mSizex = (int)(orgSx * sizeReduction); diff --git a/intern/elbeem/intern/solver_main.cpp b/intern/elbeem/intern/solver_main.cpp index 8ec667b8cb6..0f788af7955 100644 --- a/intern/elbeem/intern/solver_main.cpp +++ b/intern/elbeem/intern/solver_main.cpp @@ -363,10 +363,7 @@ LbmFsgrSolver::mainLoop(int lev) const int cutMin = 1; const int cutConst = mCutoff+2; -#if PARALLEL==1 - printf("omp_get_num_threads: %d\n", omp_get_num_threads()); -#endif - + # if LBM_INCLUDE_TESTSOLVERS==1 // 3d region off... quit if((mUseTestdata)&&(mpTest->mFarfMode>0)) { return; } diff --git a/source/blender/blenkernel/BKE_cloth.h b/source/blender/blenkernel/BKE_cloth.h index 38cd54085f5..f83cf0515df 100644 --- a/source/blender/blenkernel/BKE_cloth.h +++ b/source/blender/blenkernel/BKE_cloth.h @@ -63,6 +63,7 @@ typedef struct ClothVertex { float goal; /* goal, from SB */ float impulse[3]; /* used in collision.c */ unsigned int impulse_count; /* same as above */ + float collball; } ClothVertex; typedef struct ClothSpring { diff --git a/source/blender/blenkernel/intern/implicit.c b/source/blender/blenkernel/intern/implicit.c index 6f8f96e58fb..0f8357cee25 100644 --- a/source/blender/blenkernel/intern/implicit.c +++ b/source/blender/blenkernel/intern/implicit.c @@ -1465,7 +1465,7 @@ int implicit_solver (Object *ob, float frame, ClothModifierData *clmd, ListBase } // call collision function - result = 0; // cloth_bvh_objcollision(clmd, step + dt, step, dt); + result = cloth_bvh_objcollision(clmd, step + dt, step, dt); // copy corrected positions back to simulation if(result) From bc2c9336fdb6baf21bba58e042cbd4b039e25971 Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Mon, 26 Nov 2007 00:26:29 +0000 Subject: [PATCH 059/246] ccherrett pre-alpha subsurf openmp code --- intern/elbeem/intern/isosurface.cpp | 53 ++++++++++++++++++++--------- 1 file changed, 37 insertions(+), 16 deletions(-) diff --git a/intern/elbeem/intern/isosurface.cpp b/intern/elbeem/intern/isosurface.cpp index 9925565b85d..5d20e68ef34 100644 --- a/intern/elbeem/intern/isosurface.cpp +++ b/intern/elbeem/intern/isosurface.cpp @@ -156,13 +156,6 @@ void IsoSurface::triangulate( void ) mpEdgeVerticesZ[i] = -1; } - ntlVec3Gfx pos[8]; - float value[8]; - int cubeIndex; // index entry of the cube - int triIndices[12]; // vertex indices - int *eVert[12]; - IsoLevelVertex ilv; - // edges between which points? const int mcEdges[24] = { 0,1, 1,2, 2,3, 3,0, @@ -189,7 +182,12 @@ void IsoSurface::triangulate( void ) px = mStart[0]-gsx*0.5; for(int i=1;i<(mSizex-2);i++) { px += gsx; - + int cubeIndex; // index entry of the cube + float value[8]; + int triIndices[12]; // vertex indices + int *eVert[12]; + IsoLevelVertex ilv; + value[0] = *getData(i ,j ,k ); value[1] = *getData(i+1,j ,k ); value[2] = *getData(i+1,j+1,k ); @@ -235,6 +233,7 @@ void IsoSurface::triangulate( void ) eVert[11] = &mpEdgeVerticesZ[ ISOLEVEL_INDEX( i+0, j+1, edgek+0) ]; // grid positions + ntlVec3Gfx pos[8]; pos[0] = ntlVec3Gfx(px ,py ,pz); pos[1] = ntlVec3Gfx(px+gsx,py ,pz); pos[2] = ntlVec3Gfx(px+gsx,py+gsy,pz); @@ -340,10 +339,7 @@ void IsoSurface::triangulate( void ) if(mUseFullEdgeArrays) { errMsg("IsoSurface::triangulate","Disabling mUseFullEdgeArrays!"); } - - // subdiv local arrays - gfxReal orgval[8]; - gfxReal subdAr[2][11][11]; // max 10 subdivs! + ParticleObject* *arppnt = new ParticleObject*[mSizez*mSizey*mSizex]; // construct pointers @@ -404,13 +400,27 @@ void IsoSurface::triangulate( void ) debMsgStd("IsoSurface::triangulate",DM_MSG,"Starting. Parts in use:"< mPoints; + */ +#pragma omp parallel for for(int ok=1;ok<(mSizez-2)*mSubdivs;ok++) { pz += gsz; const int k = ok/mSubdivs; if(k<=0) continue; // skip zero plane for(int j=1;j<(mSizey-2);j++) { for(int i=1;i<(mSizex-2);i++) { - + float value[8]; + ntlVec3Gfx pos[8]; + int cubeIndex; // index entry of the cube + int triIndices[12]; // vertex indices + int *eVert[12]; + IsoLevelVertex ilv; + gfxReal orgval[8]; + gfxReal subdAr[2][11][11]; // max 10 subdivs! + orgval[0] = *getData(i ,j ,k ); orgval[1] = *getData(i+1,j ,k ); orgval[2] = *getData(i+1,j+1,k ); // with subdivs @@ -422,6 +432,7 @@ void IsoSurface::triangulate( void ) // prebuild subsampled array slice const int sdkOffset = ok-k*mSubdivs; + for(int sdk=0; sdk<2; sdk++) for(int sdj=0; sdj Date: Mon, 26 Nov 2007 00:57:46 +0000 Subject: [PATCH 060/246] Insert revert point (segfault) --- intern/elbeem/intern/isosurface.cpp | 57 ++++++++++++++++++++--------- 1 file changed, 39 insertions(+), 18 deletions(-) diff --git a/intern/elbeem/intern/isosurface.cpp b/intern/elbeem/intern/isosurface.cpp index 5d20e68ef34..0e3d37ea494 100644 --- a/intern/elbeem/intern/isosurface.cpp +++ b/intern/elbeem/intern/isosurface.cpp @@ -18,6 +18,8 @@ #define round(x) (x) #endif +#include + /****************************************************************************** * Constructor *****************************************************************************/ @@ -400,17 +402,28 @@ void IsoSurface::triangulate( void ) debMsgStd("IsoSurface::triangulate",DM_MSG,"Starting. Parts in use:"< mPoints; - */ -#pragma omp parallel for + vector calcPoints; + vector calcIndices; + const int id = omp_get_thread_num(); + const int Nthrds = omp_get_num_threads(); + + const int Nj = (mSizey-2); + + int jstart = 0+( id * (Nj / Nthrds) ); + int jend = 0+( (id+1) * (Nj / Nthrds) ); + + if(jstart<1) jstart = 1; + if(jend>(mSizey-2)) jend = (mSizey-2); + + for(int ok=1;ok<(mSizez-2)*mSubdivs;ok++) { pz += gsz; const int k = ok/mSubdivs; if(k<=0) continue; // skip zero plane - for(int j=1;j<(mSizey-2);j++) { + for(int j=jstart;j Date: Mon, 26 Nov 2007 01:04:01 +0000 Subject: [PATCH 061/246] Reverted to rev 12673 + test for ccherett --- intern/elbeem/intern/isosurface.cpp | 62 +++++++---------------------- 1 file changed, 15 insertions(+), 47 deletions(-) diff --git a/intern/elbeem/intern/isosurface.cpp b/intern/elbeem/intern/isosurface.cpp index 0e3d37ea494..3be4097a38a 100644 --- a/intern/elbeem/intern/isosurface.cpp +++ b/intern/elbeem/intern/isosurface.cpp @@ -18,8 +18,6 @@ #define round(x) (x) #endif -#include - /****************************************************************************** * Constructor *****************************************************************************/ @@ -134,7 +132,7 @@ void IsoSurface::triangulate( void ) { double gsx,gsy,gsz; // grid spacing in x,y,z direction double px,py,pz; // current position in grid in x,y,z direction - IsoLevelCube cubie; // struct for a small subcube + // IsoLevelCube cubie; // struct for a small subcube myTime_t tritimestart = getTime(); if(!mpData) { @@ -402,28 +400,12 @@ void IsoSurface::triangulate( void ) debMsgStd("IsoSurface::triangulate",DM_MSG,"Starting. Parts in use:"< calcPoints; - vector calcIndices; - const int id = omp_get_thread_num(); - const int Nthrds = omp_get_num_threads(); - - const int Nj = (mSizey-2); - - int jstart = 0+( id * (Nj / Nthrds) ); - int jend = 0+( (id+1) * (Nj / Nthrds) ); - - if(jstart<1) jstart = 1; - if(jend>(mSizey-2)) jend = (mSizey-2); - - for(int ok=1;ok<(mSizez-2)*mSubdivs;ok++) { pz += gsz; const int k = ok/mSubdivs; if(k<=0) continue; // skip zero plane - for(int j=jstart;j Date: Mon, 26 Nov 2007 02:41:06 +0000 Subject: [PATCH 062/246] New feature: Fluids internal subdiv (level >=2) uses OpenMP now --- intern/elbeem/intern/isosurface.cpp | 81 +++++++++++++++++++++++------ intern/elbeem/intern/loop_tools.h | 2 +- 2 files changed, 66 insertions(+), 17 deletions(-) diff --git a/intern/elbeem/intern/isosurface.cpp b/intern/elbeem/intern/isosurface.cpp index 3be4097a38a..6f8c6b11866 100644 --- a/intern/elbeem/intern/isosurface.cpp +++ b/intern/elbeem/intern/isosurface.cpp @@ -18,6 +18,10 @@ #define round(x) (x) #endif +#if PARALLEL==1 +#include +#endif + /****************************************************************************** * Constructor *****************************************************************************/ @@ -132,7 +136,7 @@ void IsoSurface::triangulate( void ) { double gsx,gsy,gsz; // grid spacing in x,y,z direction double px,py,pz; // current position in grid in x,y,z direction - // IsoLevelCube cubie; // struct for a small subcube + IsoLevelCube cubie; // struct for a small subcube myTime_t tritimestart = getTime(); if(!mpData) { @@ -327,6 +331,16 @@ void IsoSurface::triangulate( void ) ( (fi))*(1.-(fj))*( (fk))*orgval[5] + \ ( (fi))*( (fj))*( (fk))*orgval[6] + \ (1.-(fi))*( (fj))*( (fk))*orgval[7] ) + +#if PARALLEL==1 +#define LIST_POINT(x) calcPoints.push_back(x); +#define LIST_POINT_SIZE calcPoints.size() +#define LIST_INDEX(x) calcIndices.push_back(x); +#else +#define LIST_POINT(x) mPoints.push_back(x); +#define LIST_POINT_SIZE mPoints.size() +#define LIST_INDEX(x) mIndices.push_back(x); +#endif // use subdivisions gfxReal subdfac = 1./(gfxReal)(mSubdivs); @@ -400,12 +414,31 @@ void IsoSurface::triangulate( void ) debMsgStd("IsoSurface::triangulate",DM_MSG,"Starting. Parts in use:"< calcPoints; + vector calcIndices; + const int id = omp_get_thread_num(); + const int Nthrds = omp_get_num_threads(); + + const int Nj = (mSizey-2); + + int jstart = 0+( id * (Nj / Nthrds) ); + int jend = 0+( (id+1) * (Nj / Nthrds) ); + + if(jstart<1) jstart = 1; + if(jend>(mSizey-2)) jend = (mSizey-2); +#else + int jstart = 1; + int jend = (mSizey-2); +#endif + for(int ok=1;ok<(mSizez-2)*mSubdivs;ok++) { pz += gsz; const int k = ok/mSubdivs; if(k<=0) continue; // skip zero plane -#pragma omp parallel for - for(int j=1;j<(mSizey-2);j++) { + for(int j=jstart;j Date: Mon, 26 Nov 2007 14:50:27 +0000 Subject: [PATCH 063/246] Segfault revert, MT should work fine again for subdiv fluids --- intern/elbeem/intern/isosurface.cpp | 1125 +++++++++++++-------------- intern/elbeem/intern/loop_tools.h | 20 +- intern/elbeem/intern/paraloopend.h | 6 +- 3 files changed, 551 insertions(+), 600 deletions(-) diff --git a/intern/elbeem/intern/isosurface.cpp b/intern/elbeem/intern/isosurface.cpp index 6f8c6b11866..77530d413c7 100644 --- a/intern/elbeem/intern/isosurface.cpp +++ b/intern/elbeem/intern/isosurface.cpp @@ -18,32 +18,28 @@ #define round(x) (x) #endif -#if PARALLEL==1 -#include -#endif - /****************************************************************************** * Constructor *****************************************************************************/ IsoSurface::IsoSurface(double iso) : - ntlGeometryObject(), - mSizex(-1), mSizey(-1), mSizez(-1), - mpData(NULL), - mIsoValue( iso ), - mPoints(), - mUseFullEdgeArrays(false), - mpEdgeVerticesX(NULL), mpEdgeVerticesY(NULL), mpEdgeVerticesZ(NULL), - mEdgeArSize(-1), - mIndices(), + ntlGeometryObject(), + mSizex(-1), mSizey(-1), mSizez(-1), + mpData(NULL), + mIsoValue( iso ), + mPoints(), + mUseFullEdgeArrays(false), + mpEdgeVerticesX(NULL), mpEdgeVerticesY(NULL), mpEdgeVerticesZ(NULL), + mEdgeArSize(-1), + mIndices(), - mStart(0.0), mEnd(0.0), mDomainExtent(0.0), - mInitDone(false), - mSmoothSurface(0.0), mSmoothNormals(0.0), - mAcrossEdge(), mAdjacentFaces(), - mCutoff(-1), mCutArray(NULL), // off by default - mpIsoParts(NULL), mPartSize(0.), mSubdivs(0), - mFlagCnt(1), - mSCrad1(0.), mSCrad2(0.), mSCcenter(0.) + mStart(0.0), mEnd(0.0), mDomainExtent(0.0), + mInitDone(false), + mSmoothSurface(0.0), mSmoothNormals(0.0), + mAcrossEdge(), mAdjacentFaces(), + mCutoff(-1), mCutArray(NULL), // off by default + mpIsoParts(NULL), mPartSize(0.), mSubdivs(0), + mFlagCnt(1), + mSCrad1(0.), mSCrad2(0.), mSCcenter(0.) { } @@ -75,11 +71,11 @@ void IsoSurface::initializeIsosurface(int setx, int sety, int setz, ntlVec3Gfx e // init mIndices.clear(); - mPoints.clear(); + mPoints.clear(); int nodes = mSizez*mSizey*mSizex; - mpData = new float[nodes]; - for(int i=0;i0) && (kmSizex-2-coAdd-mCutoff) || - (j>mSizey-2-coAdd-mCutoff) ) { - if(mCutArray) { - if(k < mCutArray[j*this->mSizex+i]) continue; - } else { continue; } - } + if( (i0) && (kmSizex-2-coAdd-mCutoff) || + (j>mSizey-2-coAdd-mCutoff) ) { + if(mCutArray) { + if(k < mCutArray[j*this->mSizex+i]) continue; + } else { continue; } + } // Create the triangles... - for(int e=0; mcTriTable[cubeIndex][e]!=-1; e+=3) { - mIndices.push_back( triIndices[ mcTriTable[cubeIndex][e+0] ] ); - mIndices.push_back( triIndices[ mcTriTable[cubeIndex][e+1] ] ); - mIndices.push_back( triIndices[ mcTriTable[cubeIndex][e+2] ] ); - } + for(int e=0; mcTriTable[cubeIndex][e]!=-1; e+=3) { + mIndices.push_back( triIndices[ mcTriTable[cubeIndex][e+0] ] ); + mIndices.push_back( triIndices[ mcTriTable[cubeIndex][e+1] ] ); + mIndices.push_back( triIndices[ mcTriTable[cubeIndex][e+2] ] ); + } - }//i - }// j + }//i + }// j // copy edge arrays - if(!mUseFullEdgeArrays) { - for(int j=0;j<(mSizey-0);j++) - for(int i=0;i<(mSizex-0);i++) { + if(!mUseFullEdgeArrays) { + for(int j=0;j<(mSizey-0);j++) + for(int i=0;i<(mSizex-0);i++) { //int edgek = 0; - const int dst = ISOLEVEL_INDEX( i+0, j+0, 0); - const int src = ISOLEVEL_INDEX( i+0, j+0, 1); - mpEdgeVerticesX[ dst ] = mpEdgeVerticesX[ src ]; - mpEdgeVerticesY[ dst ] = mpEdgeVerticesY[ src ]; - mpEdgeVerticesZ[ dst ] = mpEdgeVerticesZ[ src ]; - mpEdgeVerticesX[ src ]=-1; - mpEdgeVerticesY[ src ]=-1; - mpEdgeVerticesZ[ src ]=-1; - } - } // */ + const int dst = ISOLEVEL_INDEX( i+0, j+0, 0); + const int src = ISOLEVEL_INDEX( i+0, j+0, 1); + mpEdgeVerticesX[ dst ] = mpEdgeVerticesX[ src ]; + mpEdgeVerticesY[ dst ] = mpEdgeVerticesY[ src ]; + mpEdgeVerticesZ[ dst ] = mpEdgeVerticesZ[ src ]; + mpEdgeVerticesX[ src ]=-1; + mpEdgeVerticesY[ src ]=-1; + mpEdgeVerticesZ[ src ]=-1; + } + } // */ - } // k + } // k // precalculate normals using an approximation of the scalar field gradient - for(int ni=0;ni<(int)mPoints.size();ni++) { normalize( mPoints[ni].n ); } + for(int ni=0;ni<(int)mPoints.size();ni++) { normalize( mPoints[ni].n ); } - } else { // subdivs + } else { // subdivs #define EDGEAR_INDEX(Ai,Aj,Ak, Bi,Bj) ((mSizex*mSizey*mSubdivs*mSubdivs*(Ak))+\ - (mSizex*mSubdivs*((Aj)*mSubdivs+(Bj)))+((Ai)*mSubdivs)+(Bi)) + (mSizex*mSubdivs*((Aj)*mSubdivs+(Bj)))+((Ai)*mSubdivs)+(Bi)) #define ISOTRILININT(fi,fj,fk) ( \ - (1.-(fi))*(1.-(fj))*(1.-(fk))*orgval[0] + \ - ( (fi))*(1.-(fj))*(1.-(fk))*orgval[1] + \ - ( (fi))*( (fj))*(1.-(fk))*orgval[2] + \ - (1.-(fi))*( (fj))*(1.-(fk))*orgval[3] + \ - (1.-(fi))*(1.-(fj))*( (fk))*orgval[4] + \ - ( (fi))*(1.-(fj))*( (fk))*orgval[5] + \ - ( (fi))*( (fj))*( (fk))*orgval[6] + \ - (1.-(fi))*( (fj))*( (fk))*orgval[7] ) - -#if PARALLEL==1 -#define LIST_POINT(x) calcPoints.push_back(x); -#define LIST_POINT_SIZE calcPoints.size() -#define LIST_INDEX(x) calcIndices.push_back(x); -#else -#define LIST_POINT(x) mPoints.push_back(x); -#define LIST_POINT_SIZE mPoints.size() -#define LIST_INDEX(x) mIndices.push_back(x); -#endif + (1.-(fi))*(1.-(fj))*(1.-(fk))*orgval[0] + \ + ( (fi))*(1.-(fj))*(1.-(fk))*orgval[1] + \ + ( (fi))*( (fj))*(1.-(fk))*orgval[2] + \ + (1.-(fi))*( (fj))*(1.-(fk))*orgval[3] + \ + (1.-(fi))*(1.-(fj))*( (fk))*orgval[4] + \ + ( (fi))*(1.-(fj))*( (fk))*orgval[5] + \ + ( (fi))*( (fj))*( (fk))*orgval[6] + \ + (1.-(fi))*( (fj))*( (fk))*orgval[7] ) // use subdivisions - gfxReal subdfac = 1./(gfxReal)(mSubdivs); - gfxReal orgGsx = gsx; - gfxReal orgGsy = gsy; - gfxReal orgGsz = gsz; - gsx *= subdfac; - gsy *= subdfac; - gsz *= subdfac; - if(mUseFullEdgeArrays) { - errMsg("IsoSurface::triangulate","Disabling mUseFullEdgeArrays!"); - } + gfxReal subdfac = 1./(gfxReal)(mSubdivs); + gfxReal orgGsx = gsx; + gfxReal orgGsy = gsy; + gfxReal orgGsz = gsz; + gsx *= subdfac; + gsy *= subdfac; + gsz *= subdfac; + if(mUseFullEdgeArrays) { + errMsg("IsoSurface::triangulate","Disabling mUseFullEdgeArrays!"); + } - ParticleObject* *arppnt = new ParticleObject*[mSizez*mSizey*mSizex]; + ParticleObject* *arppnt = new ParticleObject*[mSizez*mSizey*mSizex]; // construct pointers // part test - int pInUse = 0; - int pUsedTest = 0; + int pInUse = 0; + int pUsedTest = 0; // reset particles // reset list array - for(int k=0;k<(mSizez);k++) - for(int j=0;j<(mSizey);j++) - for(int i=0;i<(mSizex);i++) { - arppnt[ISOLEVEL_INDEX(i,j,k)] = NULL; - } - if(mpIsoParts) { - for(vector::iterator pit= mpIsoParts->getParticlesBegin(); - pit!= mpIsoParts->getParticlesEnd(); pit++) { - if( (*pit).getActive()==false ) continue; - if( (*pit).getType()!=PART_DROP) continue; - (*pit).setNext(NULL); - } + for(int k=0;k<(mSizez);k++) + for(int j=0;j<(mSizey);j++) + for(int i=0;i<(mSizex);i++) { + arppnt[ISOLEVEL_INDEX(i,j,k)] = NULL; + } + if(mpIsoParts) { + for(vector::iterator pit= mpIsoParts->getParticlesBegin(); + pit!= mpIsoParts->getParticlesEnd(); pit++) { + if( (*pit).getActive()==false ) continue; + if( (*pit).getType()!=PART_DROP) continue; + (*pit).setNext(NULL); + } // build per node lists - for(vector::iterator pit= mpIsoParts->getParticlesBegin(); - pit!= mpIsoParts->getParticlesEnd(); pit++) { - if( (*pit).getActive()==false ) continue; - if( (*pit).getType()!=PART_DROP) continue; + for(vector::iterator pit= mpIsoParts->getParticlesBegin(); + pit!= mpIsoParts->getParticlesEnd(); pit++) { + if( (*pit).getActive()==false ) continue; + if( (*pit).getType()!=PART_DROP) continue; // check lifetime ignored here - ParticleObject *p = &(*pit); - const ntlVec3Gfx ppos = p->getPos(); - const int pi= (int)round(ppos[0])+0; - const int pj= (int)round(ppos[1])+0; - int pk= (int)round(ppos[2])+0;// no offset necessary + ParticleObject *p = &(*pit); + const ntlVec3Gfx ppos = p->getPos(); + const int pi= (int)round(ppos[0])+0; + const int pj= (int)round(ppos[1])+0; + int pk= (int)round(ppos[2])+0;// no offset necessary // 2d should be handled by solver. if(LBMDIM==2) { pk = 0; } - if(pi<0) continue; - if(pj<0) continue; - if(pk<0) continue; - if(pi>mSizex-1) continue; - if(pj>mSizey-1) continue; - if(pk>mSizez-1) continue; - ParticleObject* &pnt = arppnt[ISOLEVEL_INDEX(pi,pj,pk)]; - if(pnt) { + if(pi<0) continue; + if(pj<0) continue; + if(pk<0) continue; + if(pi>mSizex-1) continue; + if(pj>mSizey-1) continue; + if(pk>mSizez-1) continue; + ParticleObject* &pnt = arppnt[ISOLEVEL_INDEX(pi,pj,pk)]; + if(pnt) { // append - ParticleObject* listpnt = pnt; - while(listpnt) { - if(!listpnt->getNext()) { - listpnt->setNext(p); listpnt = NULL; - } else { - listpnt = listpnt->getNext(); - } - } - } else { + ParticleObject* listpnt = pnt; + while(listpnt) { + if(!listpnt->getNext()) { + listpnt->setNext(p); listpnt = NULL; + } else { + listpnt = listpnt->getNext(); + } + } + } else { // start new list - pnt = p; - } - pInUse++; - } - } // mpIsoParts + pnt = p; + } + pInUse++; + } + } // mpIsoParts - debMsgStd("IsoSurface::triangulate",DM_MSG,"Starting. Parts in use:"< calcPoints; - vector calcIndices; - const int id = omp_get_thread_num(); - const int Nthrds = omp_get_num_threads(); - - const int Nj = (mSizey-2); - - int jstart = 0+( id * (Nj / Nthrds) ); - int jend = 0+( (id+1) * (Nj / Nthrds) ); - - if(jstart<1) jstart = 1; - if(jend>(mSizey-2)) jend = (mSizey-2); -#else - int jstart = 1; - int jend = (mSizey-2); -#endif - - for(int ok=1;ok<(mSizez-2)*mSubdivs;ok++) { - pz += gsz; - const int k = ok/mSubdivs; - if(k<=0) continue; // skip zero plane - for(int j=jstart;j=mSizez-1) continue; - for(int poj=-poDistOffset; poj<1+poDistOffset; poj++) { - if(j+poj<0) continue; - if(j+poj>=mSizey-1) continue; - for(int poi=-poDistOffset; poi<1+poDistOffset; poi++) { - if(i+poi<0) continue; - if(i+poi>=mSizex-1) continue; - ParticleObject *p; - p = arppnt[ISOLEVEL_INDEX(i+poi,j+poj,k+pok)]; - while(p) { // */ + const int poDistOffset=2; + for(int pok=-poDistOffset; pok<1+poDistOffset; pok++) { + if(k+pok<0) continue; + if(k+pok>=mSizez-1) continue; + for(int poj=-poDistOffset; poj<1+poDistOffset; poj++) { + if(j+poj<0) continue; + if(j+poj>=mSizey-1) continue; + for(int poi=-poDistOffset; poi<1+poDistOffset; poi++) { + if(i+poi<0) continue; + if(i+poi>=mSizex-1) continue; + ParticleObject *p; + p = arppnt[ISOLEVEL_INDEX(i+poi,j+poj,k+pok)]; + while(p) { // */ /* - for(vector::iterator pit= mpIsoParts->getParticlesBegin(); - pit!= mpIsoParts->getParticlesEnd(); pit++) { { { { + for(vector::iterator pit= mpIsoParts->getParticlesBegin(); + pit!= mpIsoParts->getParticlesEnd(); pit++) { { { { // debug test! , full list slow! - if(( (*pit).getActive()==false ) || ( (*pit).getType()!=PART_DROP)) continue; - ParticleObject *p; - p = &(*pit); // */ + if(( (*pit).getActive()==false ) || ( (*pit).getType()!=PART_DROP)) continue; + ParticleObject *p; + p = &(*pit); // */ - pUsedTest++; - ntlVec3Gfx ppos = p->getPos(); - const int spi= (int)round( (ppos[0]+1.-(gfxReal)i) *(gfxReal)mSubdivs-1.5); - const int spj= (int)round( (ppos[1]+1.-(gfxReal)j) *(gfxReal)mSubdivs-1.5); - const int spk= (int)round( (ppos[2]+1.-(gfxReal)k) *(gfxReal)mSubdivs-1.5)-sdkOffset; // why -2? + pUsedTest++; + ntlVec3Gfx ppos = p->getPos(); + const int spi= (int)round( (ppos[0]+1.-(gfxReal)i) *(gfxReal)mSubdivs-1.5); + const int spj= (int)round( (ppos[1]+1.-(gfxReal)j) *(gfxReal)mSubdivs-1.5); + const int spk= (int)round( (ppos[2]+1.-(gfxReal)k) *(gfxReal)mSubdivs-1.5)-sdkOffset; // why -2? // 2d should be handled by solver. if(LBMDIM==2) { spk = 0; } - gfxReal pfLen = p->getSize()*1.5*mPartSize; // test, was 1.1 - const gfxReal minPfLen = subdfac*0.8; - if(pfLengetSize()*1.5*mPartSize; // test, was 1.1 + const gfxReal minPfLen = subdfac*0.8; + if(pfLengetSize()<<" ps"< 1) { continue; } // */ - for(int swj=-icellpsize; swj<=icellpsize; swj++) { - if(spj+swj< 0) { continue; } - if(spj+swj>mSubdivs+0) { continue; } // */ - for(int swi=-icellpsize; swi<=icellpsize; swi++) { - if(spi+swi< 0) { continue; } - if(spi+swi>mSubdivs+0) { continue; } // */ - ntlVec3Gfx cellp = ntlVec3Gfx( + const int icellpsize = (int)(1.*pfLen*(gfxReal)mSubdivs)+1; + for(int swk=-icellpsize; swk<=icellpsize; swk++) { + if(spk+swk< 0) { continue; } + if(spk+swk> 1) { continue; } // */ + for(int swj=-icellpsize; swj<=icellpsize; swj++) { + if(spj+swj< 0) { continue; } + if(spj+swj>mSubdivs+0) { continue; } // */ + for(int swi=-icellpsize; swi<=icellpsize; swi++) { + if(spi+swi< 0) { continue; } + if(spi+swi>mSubdivs+0) { continue; } // */ + ntlVec3Gfx cellp = ntlVec3Gfx( (1.5+(gfxReal)(spi+swi)) *subdfac + (gfxReal)(i-1), (1.5+(gfxReal)(spj+swj)) *subdfac + (gfxReal)(j-1), (1.5+(gfxReal)(spk+swk)+sdkOffset) *subdfac + (gfxReal)(k-1) ); //if(swi==0 && swj==0 && swk==0) subdAr[spk][spj][spi] = 1.; // DEBUG // clip domain boundaries again - if(cellp[0]<1.) { continue; } - if(cellp[1]<1.) { continue; } - if(cellp[2]<1.) { continue; } - if(cellp[0]>(gfxReal)mSizex-3.) { continue; } - if(cellp[1]>(gfxReal)mSizey-3.) { continue; } - if(cellp[2]>(gfxReal)mSizez-3.) { continue; } - gfxReal len = norm(cellp-ppos); - gfxReal isoadd = 0.; - const gfxReal baseIsoVal = mIsoValue*1.1; - if(len(gfxReal)mSizex-3.) { continue; } + if(cellp[1]>(gfxReal)mSizey-3.) { continue; } + if(cellp[2]>(gfxReal)mSizez-3.) { continue; } + gfxReal len = norm(cellp-ppos); + gfxReal isoadd = 0.; + const gfxReal baseIsoVal = mIsoValue*1.1; + if(len1.) { continue; } - subdAr[spk+swk][spj+swj][spi+swi] = arval + isoadd; - } } } + const gfxReal arval = subdAr[spk+swk][spj+swj][spi+swi]; + if(arval>1.) { continue; } + subdAr[spk+swk][spj+swj][spi+swi] = arval + isoadd; + } } } - p = p->getNext(); - } - } } } // poDist loops */ + p = p->getNext(); + } + } } } // poDist loops */ - py = mStart[1]+(((double)j-0.5)*orgGsy)-gsy; - for(int sj=0;sj 0) { + if (mcEdgeTable[cubeIndex] > 0) { // where to look up if this point already exists - const int edgek = 0; - const int baseIn = EDGEAR_INDEX( i+0, j+0, edgek+0, si,sj); - eVert[ 0] = &mpEdgeVerticesX[ baseIn ]; - eVert[ 1] = &mpEdgeVerticesY[ baseIn + 1 ]; - eVert[ 2] = &mpEdgeVerticesX[ EDGEAR_INDEX( i, j, edgek+0, si+0,sj+1) ]; - eVert[ 3] = &mpEdgeVerticesY[ baseIn ]; + const int edgek = 0; + const int baseIn = EDGEAR_INDEX( i+0, j+0, edgek+0, si,sj); + eVert[ 0] = &mpEdgeVerticesX[ baseIn ]; + eVert[ 1] = &mpEdgeVerticesY[ baseIn + 1 ]; + eVert[ 2] = &mpEdgeVerticesX[ EDGEAR_INDEX( i, j, edgek+0, si+0,sj+1) ]; + eVert[ 3] = &mpEdgeVerticesY[ baseIn ]; - eVert[ 4] = &mpEdgeVerticesX[ EDGEAR_INDEX( i, j, edgek+1, si+0,sj+0) ]; - eVert[ 5] = &mpEdgeVerticesY[ EDGEAR_INDEX( i, j, edgek+1, si+1,sj+0) ]; // with subdivs - eVert[ 6] = &mpEdgeVerticesX[ EDGEAR_INDEX( i, j, edgek+1, si+0,sj+1) ]; - eVert[ 7] = &mpEdgeVerticesY[ EDGEAR_INDEX( i, j, edgek+1, si+0,sj+0) ]; + eVert[ 4] = &mpEdgeVerticesX[ EDGEAR_INDEX( i, j, edgek+1, si+0,sj+0) ]; + eVert[ 5] = &mpEdgeVerticesY[ EDGEAR_INDEX( i, j, edgek+1, si+1,sj+0) ]; // with subdivs + eVert[ 6] = &mpEdgeVerticesX[ EDGEAR_INDEX( i, j, edgek+1, si+0,sj+1) ]; + eVert[ 7] = &mpEdgeVerticesY[ EDGEAR_INDEX( i, j, edgek+1, si+0,sj+0) ]; - eVert[ 8] = &mpEdgeVerticesZ[ baseIn ]; - eVert[ 9] = &mpEdgeVerticesZ[ EDGEAR_INDEX( i, j, edgek+0, si+1,sj+0) ]; // with subdivs - eVert[10] = &mpEdgeVerticesZ[ EDGEAR_INDEX( i, j, edgek+0, si+1,sj+1) ]; - eVert[11] = &mpEdgeVerticesZ[ EDGEAR_INDEX( i, j, edgek+0, si+0,sj+1) ]; + eVert[ 8] = &mpEdgeVerticesZ[ baseIn ]; + eVert[ 9] = &mpEdgeVerticesZ[ EDGEAR_INDEX( i, j, edgek+0, si+1,sj+0) ]; // with subdivs + eVert[10] = &mpEdgeVerticesZ[ EDGEAR_INDEX( i, j, edgek+0, si+1,sj+1) ]; + eVert[11] = &mpEdgeVerticesZ[ EDGEAR_INDEX( i, j, edgek+0, si+0,sj+1) ]; // grid positions - pos[0] = ntlVec3Gfx(px ,py ,pz); - pos[1] = ntlVec3Gfx(px+gsx,py ,pz); - pos[2] = ntlVec3Gfx(px+gsx,py+gsy,pz); // with subdivs - pos[3] = ntlVec3Gfx(px ,py+gsy,pz); - pos[4] = ntlVec3Gfx(px ,py ,pz+gsz); - pos[5] = ntlVec3Gfx(px+gsx,py ,pz+gsz); - pos[6] = ntlVec3Gfx(px+gsx,py+gsy,pz+gsz); // with subdivs - pos[7] = ntlVec3Gfx(px ,py+gsy,pz+gsz); + pos[0] = ntlVec3Gfx(px ,py ,pz); + pos[1] = ntlVec3Gfx(px+gsx,py ,pz); + pos[2] = ntlVec3Gfx(px+gsx,py+gsy,pz); // with subdivs + pos[3] = ntlVec3Gfx(px ,py+gsy,pz); + pos[4] = ntlVec3Gfx(px ,py ,pz+gsz); + pos[5] = ntlVec3Gfx(px+gsx,py ,pz+gsz); + pos[6] = ntlVec3Gfx(px+gsx,py+gsy,pz+gsz); // with subdivs + pos[7] = ntlVec3Gfx(px ,py+gsy,pz+gsz); // check all edges - for(int e=0;e<12;e++) { - if (mcEdgeTable[cubeIndex] & (1<0) { + float smoSubdfac = 1.; + if(mSubdivs>0) { //smoSubdfac = 1./(float)(mSubdivs); - smoSubdfac = pow(0.55,(double)mSubdivs); // slightly stronger - } - if(mSmoothSurface>0. || mSmoothNormals>0.) debMsgStd("IsoSurface::triangulate",DM_MSG,"Smoothing...",10); - if(mSmoothSurface>0.0) { - smoothSurface(mSmoothSurface*smoSubdfac, (mSmoothNormals<=0.0) ); - } - if(mSmoothNormals>0.0) { - smoothNormals(mSmoothNormals*smoSubdfac); - } + smoSubdfac = pow(0.55,(double)mSubdivs); // slightly stronger + } + if(mSmoothSurface>0. || mSmoothNormals>0.) debMsgStd("IsoSurface::triangulate",DM_MSG,"Smoothing...",10); + if(mSmoothSurface>0.0) { + smoothSurface(mSmoothSurface*smoSubdfac, (mSmoothNormals<=0.0) ); + } + if(mSmoothNormals>0.0) { + smoothNormals(mSmoothNormals*smoSubdfac); + } - myTime_t tritimeend = getTime(); - debMsgStd("IsoSurface::triangulate",DM_MSG,"took "<< getTimeString(tritimeend-tritimestart)<<", S("<getNumParticles(), 10); + myTime_t tritimeend = getTime(); + debMsgStd("IsoSurface::triangulate",DM_MSG,"took "<< getTimeString(tritimeend-tritimestart)<<", S("<getNumParticles(), 10); } @@ -714,8 +665,8 @@ void IsoSurface::triangulate( void ) * Get triangles for rendering *****************************************************************************/ void IsoSurface::getTriangles(double t, vector *triangles, - vector *vertices, - vector *normals, int objectId ) + vector *vertices, + vector *normals, int objectId ) { if(!mInitDone) { debugOut("IsoSurface::getTriangles warning: Not initialized! ", 10); @@ -724,8 +675,8 @@ void IsoSurface::getTriangles(double t, vector *triangles, t = 0.; //return; // DEBUG - /* triangulate field */ - triangulate(); + /* triangulate field */ + triangulate(); //errMsg("TRIS"," "< *triangles, //errMsg("NM"," ivi"<size()<<" ns"<size()<<" ts"<size() ); //errMsg("NM"," ovs"<push_back( mPoints[i].v ); } - for(int i=0;i<(int)mPoints.size();i++) { + for(int i=0;i<(int)mPoints.size();i++) { normals->push_back( mPoints[i].n ); } //errMsg("N2"," ivi"<size()<<" ns"<size()<<" ts"<size() ); //errMsg("N2"," ovs"< *triangles, if(getCastShadows() ) { flag |= TRI_CASTSHADOWS; } - /* init geo init id */ - int geoiId = getGeoInitId(); - if(geoiId > 0) { - flag |= (1<< (geoiId+4)); - flag |= mGeoInitType; - } + /* init geo init id */ + int geoiId = getGeoInitId(); + if(geoiId > 0) { + flag |= (1<< (geoiId+4)); + flag |= mGeoInitType; + } - tri.setFlags( flag ); + tri.setFlags( flag ); - /* triangle normal missing */ - tri.setNormal( ntlVec3Gfx(0.0) ); - tri.setSmoothNormals( smooth ); - tri.setObjectId( objectId ); - triangles->push_back( tri ); + /* triangle normal missing */ + tri.setNormal( ntlVec3Gfx(0.0) ); + tri.setSmoothNormals( smooth ); + tri.setObjectId( objectId ); + triangles->push_back( tri ); } //errMsg("N3"," ivi"<size()<<" ns"<size()<<" ts"<size() ); return; @@ -792,11 +743,11 @@ inline ntlVec3Gfx IsoSurface::getNormal(int i, int j,int k) { // WARNING - this requires a security boundary layer... ntlVec3Gfx ret(0.0); ret[0] = *getData(i-1,j ,k ) - - *getData(i+1,j ,k ); + *getData(i+1,j ,k ); ret[1] = *getData(i ,j-1,k ) - - *getData(i ,j+1,k ); + *getData(i ,j+1,k ); ret[2] = *getData(i ,j ,k-1 ) - - *getData(i ,j ,k+1 ); + *getData(i ,j ,k+1 ); return ret; } @@ -818,13 +769,13 @@ void IsoSurface::setSmoothRad(float radi1, float radi2, ntlVec3Gfx mscc) { // compute normals for all generated triangles void IsoSurface::computeNormals() { - for(int i=0;i<(int)mPoints.size();i++) { + for(int i=0;i<(int)mPoints.size();i++) { mPoints[i].n = ntlVec3Gfx(0.); } - for(int i=0;i<(int)mIndices.size();i+=3) { - const int t1 = mIndices[i]; - const int t2 = mIndices[i+1]; + for(int i=0;i<(int)mIndices.size();i+=3) { + const int t1 = mIndices[i]; + const int t2 = mIndices[i+1]; const int t3 = mIndices[i+2]; const ntlVec3Gfx p1 = mPoints[t1].v; const ntlVec3Gfx p2 = mPoints[t2].v; @@ -841,7 +792,7 @@ void IsoSurface::computeNormals() { mPoints[t3].n += norm * (1./(len2*len3)); } - for(int i=0;i<(int)mPoints.size();i++) { + for(int i=0;i<(int)mPoints.size();i++) { normalize(mPoints[i].n); } } @@ -952,86 +903,86 @@ void IsoSurface::smoothSurface(float sigma, bool normSmooth) // Edges ntlVec3Gfx e[3] = { mPoints[mIndices[i*3+2]].v - mPoints[mIndices[i*3+1]].v, - mPoints[mIndices[i*3+0]].v - mPoints[mIndices[i*3+2]].v, - mPoints[mIndices[i*3+1]].v - mPoints[mIndices[i*3+0]].v }; + mPoints[mIndices[i*3+0]].v - mPoints[mIndices[i*3+2]].v, + mPoints[mIndices[i*3+1]].v - mPoints[mIndices[i*3+0]].v }; // Compute corner weights - float area = 0.5f * norm( cross(e[0], e[1])); - float l2[3] = { normNoSqrt(e[0]), normNoSqrt(e[1]), normNoSqrt(e[2]) }; - float ew[3] = { l2[0] * (l2[1] + l2[2] - l2[0]), - l2[1] * (l2[2] + l2[0] - l2[1]), - l2[2] * (l2[0] + l2[1] - l2[2]) }; - if (ew[0] <= 0.0f) { - cornerareas[i][1] = -0.25f * l2[2] * area / - dot(e[0] , e[2]); - cornerareas[i][2] = -0.25f * l2[1] * area / - dot(e[0] , e[1]); - cornerareas[i][0] = area - cornerareas[i][1] - - cornerareas[i][2]; - } else if (ew[1] <= 0.0f) { - cornerareas[i][2] = -0.25f * l2[0] * area / - dot(e[1] , e[0]); - cornerareas[i][0] = -0.25f * l2[2] * area / - dot(e[1] , e[2]); - cornerareas[i][1] = area - cornerareas[i][2] - - cornerareas[i][0]; - } else if (ew[2] <= 0.0f) { - cornerareas[i][0] = -0.25f * l2[1] * area / - dot(e[2] , e[1]); - cornerareas[i][1] = -0.25f * l2[0] * area / - dot(e[2] , e[0]); - cornerareas[i][2] = area - cornerareas[i][0] - - cornerareas[i][1]; - } else { - float ewscale = 0.5f * area / (ew[0] + ew[1] + ew[2]); - for (int j = 0; j < 3; j++) - cornerareas[i][j] = ewscale * (ew[(j+1)%3] + - ew[(j+2)%3]); - } + float area = 0.5f * norm( cross(e[0], e[1])); + float l2[3] = { normNoSqrt(e[0]), normNoSqrt(e[1]), normNoSqrt(e[2]) }; + float ew[3] = { l2[0] * (l2[1] + l2[2] - l2[0]), + l2[1] * (l2[2] + l2[0] - l2[1]), + l2[2] * (l2[0] + l2[1] - l2[2]) }; + if (ew[0] <= 0.0f) { + cornerareas[i][1] = -0.25f * l2[2] * area / + dot(e[0] , e[2]); + cornerareas[i][2] = -0.25f * l2[1] * area / + dot(e[0] , e[1]); + cornerareas[i][0] = area - cornerareas[i][1] - + cornerareas[i][2]; + } else if (ew[1] <= 0.0f) { + cornerareas[i][2] = -0.25f * l2[0] * area / + dot(e[1] , e[0]); + cornerareas[i][0] = -0.25f * l2[2] * area / + dot(e[1] , e[2]); + cornerareas[i][1] = area - cornerareas[i][2] - + cornerareas[i][0]; + } else if (ew[2] <= 0.0f) { + cornerareas[i][0] = -0.25f * l2[1] * area / + dot(e[2] , e[1]); + cornerareas[i][1] = -0.25f * l2[0] * area / + dot(e[2] , e[0]); + cornerareas[i][2] = area - cornerareas[i][0] - + cornerareas[i][1]; + } else { + float ewscale = 0.5f * area / (ew[0] + ew[1] + ew[2]); + for (int j = 0; j < 3; j++) + cornerareas[i][j] = ewscale * (ew[(j+1)%3] + + ew[(j+2)%3]); + } // NT important, check this... #ifndef WIN32 - if(! finite(cornerareas[i][0]) ) cornerareas[i][0]=1e-6; - if(! finite(cornerareas[i][1]) ) cornerareas[i][1]=1e-6; - if(! finite(cornerareas[i][2]) ) cornerareas[i][2]=1e-6; + if(! finite(cornerareas[i][0]) ) cornerareas[i][0]=1e-6; + if(! finite(cornerareas[i][1]) ) cornerareas[i][1]=1e-6; + if(! finite(cornerareas[i][2]) ) cornerareas[i][2]=1e-6; #else // WIN32 // FIXME check as well... - if(! (cornerareas[i][0]>=0.0) ) cornerareas[i][0]=1e-6; - if(! (cornerareas[i][1]>=0.0) ) cornerareas[i][1]=1e-6; - if(! (cornerareas[i][2]>=0.0) ) cornerareas[i][2]=1e-6; + if(! (cornerareas[i][0]>=0.0) ) cornerareas[i][0]=1e-6; + if(! (cornerareas[i][1]>=0.0) ) cornerareas[i][1]=1e-6; + if(! (cornerareas[i][2]>=0.0) ) cornerareas[i][2]=1e-6; #endif // WIN32 - pointareas[mIndices[i*3+0]] += cornerareas[i][0]; - pointareas[mIndices[i*3+1]] += cornerareas[i][1]; - pointareas[mIndices[i*3+2]] += cornerareas[i][2]; + pointareas[mIndices[i*3+0]] += cornerareas[i][0]; + pointareas[mIndices[i*3+1]] += cornerareas[i][1]; + pointareas[mIndices[i*3+2]] += cornerareas[i][2]; } } // need pointarea - // */ + // */ float invsigma2 = 1.0f / (sigma*sigma); vector dflt(nv); for (int i = 0; i < nv; i++) { if(diffuseVertexField( &mPoints[0].v, 2, - i, invsigma2, dflt[i])) { + i, invsigma2, dflt[i])) { // Just keep the displacement - dflt[i] -= mPoints[i].v; - } else { dflt[i] = 0.0; } //?mPoints[i].v; } + dflt[i] -= mPoints[i].v; + } else { dflt[i] = 0.0; } //?mPoints[i].v; } } // Slightly better small-neighborhood approximation for (int i = 0; i < nf; i++) { ntlVec3Gfx c = mPoints[mIndices[i*3+0]].v + - mPoints[mIndices[i*3+1]].v + - mPoints[mIndices[i*3+2]].v; + mPoints[mIndices[i*3+1]].v + + mPoints[mIndices[i*3+2]].v; c /= 3.0f; for (int j = 0; j < 3; j++) { int v = mIndices[i*3+j]; ntlVec3Gfx d =(c - mPoints[v].v) * 0.5f; dflt[v] += d * (cornerareas[i][j] / - pointareas[mIndices[i*3+j]] * - exp(-0.5f * invsigma2 * normNoSqrt(d)) ); + pointareas[mIndices[i*3+j]] * + exp(-0.5f * invsigma2 * normNoSqrt(d)) ); } } @@ -1039,7 +990,7 @@ void IsoSurface::smoothSurface(float sigma, bool normSmooth) vector dflt2(nv); for (int i = 0; i < nv; i++) { if(diffuseVertexField( &dflt[0], 1, - i, invsigma2, dflt2[i])) { } + i, invsigma2, dflt2[i])) { } else { /*mPoints[i].v=0.0;*/ dflt2[i] = 0.0; }//dflt2[i]; } } @@ -1111,58 +1062,58 @@ void IsoSurface::smoothNormals(float sigma) { // Edges ntlVec3Gfx e[3] = { mPoints[mIndices[i*3+2]].v - mPoints[mIndices[i*3+1]].v, - mPoints[mIndices[i*3+0]].v - mPoints[mIndices[i*3+2]].v, - mPoints[mIndices[i*3+1]].v - mPoints[mIndices[i*3+0]].v }; + mPoints[mIndices[i*3+0]].v - mPoints[mIndices[i*3+2]].v, + mPoints[mIndices[i*3+1]].v - mPoints[mIndices[i*3+0]].v }; // Compute corner weights - float area = 0.5f * norm( cross(e[0], e[1])); - float l2[3] = { normNoSqrt(e[0]), normNoSqrt(e[1]), normNoSqrt(e[2]) }; - float ew[3] = { l2[0] * (l2[1] + l2[2] - l2[0]), - l2[1] * (l2[2] + l2[0] - l2[1]), - l2[2] * (l2[0] + l2[1] - l2[2]) }; - if (ew[0] <= 0.0f) { - cornerareas[i][1] = -0.25f * l2[2] * area / - dot(e[0] , e[2]); - cornerareas[i][2] = -0.25f * l2[1] * area / - dot(e[0] , e[1]); - cornerareas[i][0] = area - cornerareas[i][1] - - cornerareas[i][2]; - } else if (ew[1] <= 0.0f) { - cornerareas[i][2] = -0.25f * l2[0] * area / - dot(e[1] , e[0]); - cornerareas[i][0] = -0.25f * l2[2] * area / - dot(e[1] , e[2]); - cornerareas[i][1] = area - cornerareas[i][2] - - cornerareas[i][0]; - } else if (ew[2] <= 0.0f) { - cornerareas[i][0] = -0.25f * l2[1] * area / - dot(e[2] , e[1]); - cornerareas[i][1] = -0.25f * l2[0] * area / - dot(e[2] , e[0]); - cornerareas[i][2] = area - cornerareas[i][0] - - cornerareas[i][1]; - } else { - float ewscale = 0.5f * area / (ew[0] + ew[1] + ew[2]); - for (int j = 0; j < 3; j++) - cornerareas[i][j] = ewscale * (ew[(j+1)%3] + - ew[(j+2)%3]); - } + float area = 0.5f * norm( cross(e[0], e[1])); + float l2[3] = { normNoSqrt(e[0]), normNoSqrt(e[1]), normNoSqrt(e[2]) }; + float ew[3] = { l2[0] * (l2[1] + l2[2] - l2[0]), + l2[1] * (l2[2] + l2[0] - l2[1]), + l2[2] * (l2[0] + l2[1] - l2[2]) }; + if (ew[0] <= 0.0f) { + cornerareas[i][1] = -0.25f * l2[2] * area / + dot(e[0] , e[2]); + cornerareas[i][2] = -0.25f * l2[1] * area / + dot(e[0] , e[1]); + cornerareas[i][0] = area - cornerareas[i][1] - + cornerareas[i][2]; + } else if (ew[1] <= 0.0f) { + cornerareas[i][2] = -0.25f * l2[0] * area / + dot(e[1] , e[0]); + cornerareas[i][0] = -0.25f * l2[2] * area / + dot(e[1] , e[2]); + cornerareas[i][1] = area - cornerareas[i][2] - + cornerareas[i][0]; + } else if (ew[2] <= 0.0f) { + cornerareas[i][0] = -0.25f * l2[1] * area / + dot(e[2] , e[1]); + cornerareas[i][1] = -0.25f * l2[0] * area / + dot(e[2] , e[0]); + cornerareas[i][2] = area - cornerareas[i][0] - + cornerareas[i][1]; + } else { + float ewscale = 0.5f * area / (ew[0] + ew[1] + ew[2]); + for (int j = 0; j < 3; j++) + cornerareas[i][j] = ewscale * (ew[(j+1)%3] + + ew[(j+2)%3]); + } // NT important, check this... #ifndef WIN32 - if(! finite(cornerareas[i][0]) ) cornerareas[i][0]=1e-6; - if(! finite(cornerareas[i][1]) ) cornerareas[i][1]=1e-6; - if(! finite(cornerareas[i][2]) ) cornerareas[i][2]=1e-6; + if(! finite(cornerareas[i][0]) ) cornerareas[i][0]=1e-6; + if(! finite(cornerareas[i][1]) ) cornerareas[i][1]=1e-6; + if(! finite(cornerareas[i][2]) ) cornerareas[i][2]=1e-6; #else // WIN32 // FIXME check as well... - if(! (cornerareas[i][0]>=0.0) ) cornerareas[i][0]=1e-6; - if(! (cornerareas[i][1]>=0.0) ) cornerareas[i][1]=1e-6; - if(! (cornerareas[i][2]>=0.0) ) cornerareas[i][2]=1e-6; + if(! (cornerareas[i][0]>=0.0) ) cornerareas[i][0]=1e-6; + if(! (cornerareas[i][1]>=0.0) ) cornerareas[i][1]=1e-6; + if(! (cornerareas[i][2]>=0.0) ) cornerareas[i][2]=1e-6; #endif // WIN32 - pointareas[mIndices[i*3+0]] += cornerareas[i][0]; - pointareas[mIndices[i*3+1]] += cornerareas[i][1]; - pointareas[mIndices[i*3+2]] += cornerareas[i][2]; + pointareas[mIndices[i*3+0]] += cornerareas[i][0]; + pointareas[mIndices[i*3+1]] += cornerareas[i][1]; + pointareas[mIndices[i*3+2]] += cornerareas[i][2]; } } // need pointarea diff --git a/intern/elbeem/intern/loop_tools.h b/intern/elbeem/intern/loop_tools.h index 70ecb9ce3e0..163965901e8 100644 --- a/intern/elbeem/intern/loop_tools.h +++ b/intern/elbeem/intern/loop_tools.h @@ -34,7 +34,7 @@ // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> #define GRID_REGION_START() \ - { /* main_region */ \ +{ /* main_region */ \ int kstart=getForZMinBnd(), kend=getForZMaxBnd(mMaxRefine); \ if(gridLoopBound>0){ kstart=getForZMin1(), kend=getForZMax1(mMaxRefine); } \ int kdir = 1; \ @@ -49,7 +49,7 @@ kend = kstart-1; \ kstart = temp-1; \ temp = id; /* dummy remove warning */ \ - } \ +} \ @@ -74,13 +74,13 @@ // loop start #define GRID_REGION_START() \ - { \ +{ \ \ \ if(mSizez<2) { \ mPanic = 1; \ errFatal("ParaLoop::2D","Not valid...!", SIMWORLD_GENERICERROR); \ - } \ +} \ \ \ vector calcListFull; \ @@ -113,14 +113,14 @@ int temp = kend; \ kend = kstart-1; \ kstart = temp-1; \ - } \ +} \ \ const int Nj = mLevel[mMaxRefine].lSizey; \ int jstart = 0+( id * (Nj / Nthrds) ); \ int jend = 0+( (id+1) * (Nj / Nthrds) ); \ if( ((Nj/Nthrds) *Nthrds) != Nj) { \ errMsg("LbmFsgrSolver","Invalid domain size Nj="<::iterator pit= mpIsoParts->getParticlesBegin(); - pit!= mpIsoParts->getParticlesEnd(); pit++) { - if( (*pit).getActive()==false ) continue; - if( (*pit).getType()!=PART_DROP) continue; - (*pit).setNext(NULL); - } + for(int k=0;k<(mSizez);k++) + for(int j=0;j<(mSizey);j++) + for(int i=0;i<(mSizex);i++) { + arppnt[ISOLEVEL_INDEX(i,j,k)] = NULL; + } + if(mpIsoParts) { + for(vector::iterator pit= mpIsoParts->getParticlesBegin(); + pit!= mpIsoParts->getParticlesEnd(); pit++) { + if( (*pit).getActive()==false ) continue; + if( (*pit).getType()!=PART_DROP) continue; + (*pit).setNext(NULL); + } // build per node lists - for(vector::iterator pit= mpIsoParts->getParticlesBegin(); - pit!= mpIsoParts->getParticlesEnd(); pit++) { - if( (*pit).getActive()==false ) continue; - if( (*pit).getType()!=PART_DROP) continue; + for(vector::iterator pit= mpIsoParts->getParticlesBegin(); + pit!= mpIsoParts->getParticlesEnd(); pit++) { + if( (*pit).getActive()==false ) continue; + if( (*pit).getType()!=PART_DROP) continue; // check lifetime ignored here - ParticleObject *p = &(*pit); - const ntlVec3Gfx ppos = p->getPos(); - const int pi= (int)round(ppos[0])+0; - const int pj= (int)round(ppos[1])+0; - int pk= (int)round(ppos[2])+0;// no offset necessary + ParticleObject *p = &(*pit); + const ntlVec3Gfx ppos = p->getPos(); + const int pi= (int)round(ppos[0])+0; + const int pj= (int)round(ppos[1])+0; + int pk= (int)round(ppos[2])+0;// no offset necessary // 2d should be handled by solver. if(LBMDIM==2) { pk = 0; } - if(pi<0) continue; - if(pj<0) continue; - if(pk<0) continue; - if(pi>mSizex-1) continue; - if(pj>mSizey-1) continue; - if(pk>mSizez-1) continue; - ParticleObject* &pnt = arppnt[ISOLEVEL_INDEX(pi,pj,pk)]; - if(pnt) { + if(pi<0) continue; + if(pj<0) continue; + if(pk<0) continue; + if(pi>mSizex-1) continue; + if(pj>mSizey-1) continue; + if(pk>mSizez-1) continue; + ParticleObject* &pnt = arppnt[ISOLEVEL_INDEX(pi,pj,pk)]; + if(pnt) { // append - ParticleObject* listpnt = pnt; - while(listpnt) { - if(!listpnt->getNext()) { - listpnt->setNext(p); listpnt = NULL; - } else { - listpnt = listpnt->getNext(); - } - } - } else { + ParticleObject* listpnt = pnt; + while(listpnt) { + if(!listpnt->getNext()) { + listpnt->setNext(p); listpnt = NULL; + } else { + listpnt = listpnt->getNext(); + } + } + } else { // start new list - pnt = p; - } - pInUse++; - } - } // mpIsoParts + pnt = p; + } + pInUse++; + } + } // mpIsoParts - debMsgStd("IsoSurface::triangulate",DM_MSG,"Starting. Parts in use:"<=mSizez-1) continue; - for(int poj=-poDistOffset; poj<1+poDistOffset; poj++) { - if(j+poj<0) continue; - if(j+poj>=mSizey-1) continue; - for(int poi=-poDistOffset; poi<1+poDistOffset; poi++) { - if(i+poi<0) continue; - if(i+poi>=mSizex-1) continue; - ParticleObject *p; - p = arppnt[ISOLEVEL_INDEX(i+poi,j+poj,k+pok)]; - while(p) { // */ + const int poDistOffset=2; + for(int pok=-poDistOffset; pok<1+poDistOffset; pok++) { + if(k+pok<0) continue; + if(k+pok>=mSizez-1) continue; + for(int poj=-poDistOffset; poj<1+poDistOffset; poj++) { + if(j+poj<0) continue; + if(j+poj>=mSizey-1) continue; + for(int poi=-poDistOffset; poi<1+poDistOffset; poi++) { + if(i+poi<0) continue; + if(i+poi>=mSizex-1) continue; + ParticleObject *p; + p = arppnt[ISOLEVEL_INDEX(i+poi,j+poj,k+pok)]; + while(p) { // */ /* - for(vector::iterator pit= mpIsoParts->getParticlesBegin(); - pit!= mpIsoParts->getParticlesEnd(); pit++) { { { { + for(vector::iterator pit= mpIsoParts->getParticlesBegin(); + pit!= mpIsoParts->getParticlesEnd(); pit++) { { { { // debug test! , full list slow! - if(( (*pit).getActive()==false ) || ( (*pit).getType()!=PART_DROP)) continue; - ParticleObject *p; - p = &(*pit); // */ + if(( (*pit).getActive()==false ) || ( (*pit).getType()!=PART_DROP)) continue; + ParticleObject *p; + p = &(*pit); // */ - pUsedTest++; - ntlVec3Gfx ppos = p->getPos(); - const int spi= (int)round( (ppos[0]+1.-(gfxReal)i) *(gfxReal)mSubdivs-1.5); - const int spj= (int)round( (ppos[1]+1.-(gfxReal)j) *(gfxReal)mSubdivs-1.5); - const int spk= (int)round( (ppos[2]+1.-(gfxReal)k) *(gfxReal)mSubdivs-1.5)-sdkOffset; // why -2? + pUsedTest++; + ntlVec3Gfx ppos = p->getPos(); + const int spi= (int)round( (ppos[0]+1.-(gfxReal)i) *(gfxReal)mSubdivs-1.5); + const int spj= (int)round( (ppos[1]+1.-(gfxReal)j) *(gfxReal)mSubdivs-1.5); + const int spk= (int)round( (ppos[2]+1.-(gfxReal)k) *(gfxReal)mSubdivs-1.5)-sdkOffset; // why -2? // 2d should be handled by solver. if(LBMDIM==2) { spk = 0; } - gfxReal pfLen = p->getSize()*1.5*mPartSize; // test, was 1.1 - const gfxReal minPfLen = subdfac*0.8; - if(pfLengetSize()*1.5*mPartSize; // test, was 1.1 + const gfxReal minPfLen = subdfac*0.8; + if(pfLengetSize()<<" ps"< 1) { continue; } // */ - for(int swj=-icellpsize; swj<=icellpsize; swj++) { - if(spj+swj< 0) { continue; } - if(spj+swj>mSubdivs+0) { continue; } // */ - for(int swi=-icellpsize; swi<=icellpsize; swi++) { - if(spi+swi< 0) { continue; } - if(spi+swi>mSubdivs+0) { continue; } // */ - ntlVec3Gfx cellp = ntlVec3Gfx( + const int icellpsize = (int)(1.*pfLen*(gfxReal)mSubdivs)+1; + for(int swk=-icellpsize; swk<=icellpsize; swk++) { + if(spk+swk< 0) { continue; } + if(spk+swk> 1) { continue; } // */ + for(int swj=-icellpsize; swj<=icellpsize; swj++) { + if(spj+swj< 0) { continue; } + if(spj+swj>mSubdivs+0) { continue; } // */ + for(int swi=-icellpsize; swi<=icellpsize; swi++) { + if(spi+swi< 0) { continue; } + if(spi+swi>mSubdivs+0) { continue; } // */ + ntlVec3Gfx cellp = ntlVec3Gfx( (1.5+(gfxReal)(spi+swi)) *subdfac + (gfxReal)(i-1), (1.5+(gfxReal)(spj+swj)) *subdfac + (gfxReal)(j-1), (1.5+(gfxReal)(spk+swk)+sdkOffset) *subdfac + (gfxReal)(k-1) ); //if(swi==0 && swj==0 && swk==0) subdAr[spk][spj][spi] = 1.; // DEBUG // clip domain boundaries again - if(cellp[0]<1.) { continue; } - if(cellp[1]<1.) { continue; } - if(cellp[2]<1.) { continue; } - if(cellp[0]>(gfxReal)mSizex-3.) { continue; } - if(cellp[1]>(gfxReal)mSizey-3.) { continue; } - if(cellp[2]>(gfxReal)mSizez-3.) { continue; } - gfxReal len = norm(cellp-ppos); - gfxReal isoadd = 0.; - const gfxReal baseIsoVal = mIsoValue*1.1; - if(len(gfxReal)mSizex-3.) { continue; } + if(cellp[1]>(gfxReal)mSizey-3.) { continue; } + if(cellp[2]>(gfxReal)mSizez-3.) { continue; } + gfxReal len = norm(cellp-ppos); + gfxReal isoadd = 0.; + const gfxReal baseIsoVal = mIsoValue*1.1; + if(len1.) { continue; } - subdAr[spk+swk][spj+swj][spi+swi] = arval + isoadd; - } } } + const gfxReal arval = subdAr[spk+swk][spj+swj][spi+swi]; + if(arval>1.) { continue; } + subdAr[spk+swk][spj+swj][spi+swi] = arval + isoadd; + } } } - p = p->getNext(); - } - } } } // poDist loops */ + p = p->getNext(); + } + } } } // poDist loops */ - py = mStart[1]+(((double)j-0.5)*orgGsy)-gsy; - for(int sj=0;sj 0) { + if (mcEdgeTable[cubeIndex] > 0) { // where to look up if this point already exists - const int edgek = 0; - const int baseIn = EDGEAR_INDEX( i+0, j+0, edgek+0, si,sj); - eVert[ 0] = &mpEdgeVerticesX[ baseIn ]; - eVert[ 1] = &mpEdgeVerticesY[ baseIn + 1 ]; - eVert[ 2] = &mpEdgeVerticesX[ EDGEAR_INDEX( i, j, edgek+0, si+0,sj+1) ]; - eVert[ 3] = &mpEdgeVerticesY[ baseIn ]; + const int edgek = 0; + const int baseIn = EDGEAR_INDEX( i+0, j+0, edgek+0, si,sj); + eVert[ 0] = &mpEdgeVerticesX[ baseIn ]; + eVert[ 1] = &mpEdgeVerticesY[ baseIn + 1 ]; + eVert[ 2] = &mpEdgeVerticesX[ EDGEAR_INDEX( i, j, edgek+0, si+0,sj+1) ]; + eVert[ 3] = &mpEdgeVerticesY[ baseIn ]; - eVert[ 4] = &mpEdgeVerticesX[ EDGEAR_INDEX( i, j, edgek+1, si+0,sj+0) ]; - eVert[ 5] = &mpEdgeVerticesY[ EDGEAR_INDEX( i, j, edgek+1, si+1,sj+0) ]; // with subdivs - eVert[ 6] = &mpEdgeVerticesX[ EDGEAR_INDEX( i, j, edgek+1, si+0,sj+1) ]; - eVert[ 7] = &mpEdgeVerticesY[ EDGEAR_INDEX( i, j, edgek+1, si+0,sj+0) ]; + eVert[ 4] = &mpEdgeVerticesX[ EDGEAR_INDEX( i, j, edgek+1, si+0,sj+0) ]; + eVert[ 5] = &mpEdgeVerticesY[ EDGEAR_INDEX( i, j, edgek+1, si+1,sj+0) ]; // with subdivs + eVert[ 6] = &mpEdgeVerticesX[ EDGEAR_INDEX( i, j, edgek+1, si+0,sj+1) ]; + eVert[ 7] = &mpEdgeVerticesY[ EDGEAR_INDEX( i, j, edgek+1, si+0,sj+0) ]; - eVert[ 8] = &mpEdgeVerticesZ[ baseIn ]; - eVert[ 9] = &mpEdgeVerticesZ[ EDGEAR_INDEX( i, j, edgek+0, si+1,sj+0) ]; // with subdivs - eVert[10] = &mpEdgeVerticesZ[ EDGEAR_INDEX( i, j, edgek+0, si+1,sj+1) ]; - eVert[11] = &mpEdgeVerticesZ[ EDGEAR_INDEX( i, j, edgek+0, si+0,sj+1) ]; + eVert[ 8] = &mpEdgeVerticesZ[ baseIn ]; + eVert[ 9] = &mpEdgeVerticesZ[ EDGEAR_INDEX( i, j, edgek+0, si+1,sj+0) ]; // with subdivs + eVert[10] = &mpEdgeVerticesZ[ EDGEAR_INDEX( i, j, edgek+0, si+1,sj+1) ]; + eVert[11] = &mpEdgeVerticesZ[ EDGEAR_INDEX( i, j, edgek+0, si+0,sj+1) ]; // grid positions - pos[0] = ntlVec3Gfx(px ,py ,pz); - pos[1] = ntlVec3Gfx(px+gsx,py ,pz); - pos[2] = ntlVec3Gfx(px+gsx,py+gsy,pz); // with subdivs - pos[3] = ntlVec3Gfx(px ,py+gsy,pz); - pos[4] = ntlVec3Gfx(px ,py ,pz+gsz); - pos[5] = ntlVec3Gfx(px+gsx,py ,pz+gsz); - pos[6] = ntlVec3Gfx(px+gsx,py+gsy,pz+gsz); // with subdivs - pos[7] = ntlVec3Gfx(px ,py+gsy,pz+gsz); + pos[0] = ntlVec3Gfx(px ,py ,pz); + pos[1] = ntlVec3Gfx(px+gsx,py ,pz); + pos[2] = ntlVec3Gfx(px+gsx,py+gsy,pz); // with subdivs + pos[3] = ntlVec3Gfx(px ,py+gsy,pz); + pos[4] = ntlVec3Gfx(px ,py ,pz+gsz); + pos[5] = ntlVec3Gfx(px+gsx,py ,pz+gsz); + pos[6] = ntlVec3Gfx(px+gsx,py+gsy,pz+gsz); // with subdivs + pos[7] = ntlVec3Gfx(px ,py+gsy,pz+gsz); // check all edges - for(int e=0;e<12;e++) { - if (mcEdgeTable[cubeIndex] & (1<0) { + float smoSubdfac = 1.; + if(mSubdivs>0) { //smoSubdfac = 1./(float)(mSubdivs); - smoSubdfac = pow(0.55,(double)mSubdivs); // slightly stronger - } - if(mSmoothSurface>0. || mSmoothNormals>0.) debMsgStd("IsoSurface::triangulate",DM_MSG,"Smoothing...",10); - if(mSmoothSurface>0.0) { - smoothSurface(mSmoothSurface*smoSubdfac, (mSmoothNormals<=0.0) ); - } - if(mSmoothNormals>0.0) { - smoothNormals(mSmoothNormals*smoSubdfac); - } + smoSubdfac = pow(0.55,(double)mSubdivs); // slightly stronger + } + if(mSmoothSurface>0. || mSmoothNormals>0.) debMsgStd("IsoSurface::triangulate",DM_MSG,"Smoothing...",10); + if(mSmoothSurface>0.0) { + smoothSurface(mSmoothSurface*smoSubdfac, (mSmoothNormals<=0.0) ); + } + if(mSmoothNormals>0.0) { + smoothNormals(mSmoothNormals*smoSubdfac); + } - myTime_t tritimeend = getTime(); - debMsgStd("IsoSurface::triangulate",DM_MSG,"took "<< getTimeString(tritimeend-tritimestart)<<", S("<getNumParticles(), 10); + myTime_t tritimeend = getTime(); + debMsgStd("IsoSurface::triangulate",DM_MSG,"took "<< getTimeString(tritimeend-tritimestart)<<", S("<getNumParticles(), 10); } @@ -665,8 +677,8 @@ void IsoSurface::triangulate( void ) * Get triangles for rendering *****************************************************************************/ void IsoSurface::getTriangles(double t, vector *triangles, - vector *vertices, - vector *normals, int objectId ) + vector *vertices, + vector *normals, int objectId ) { if(!mInitDone) { debugOut("IsoSurface::getTriangles warning: Not initialized! ", 10); @@ -675,8 +687,8 @@ void IsoSurface::getTriangles(double t, vector *triangles, t = 0.; //return; // DEBUG - /* triangulate field */ - triangulate(); + /* triangulate field */ + triangulate(); //errMsg("TRIS"," "< *triangles, //errMsg("NM"," ivi"<size()<<" ns"<size()<<" ts"<size() ); //errMsg("NM"," ovs"<push_back( mPoints[i].v ); } - for(int i=0;i<(int)mPoints.size();i++) { + for(int i=0;i<(int)mPoints.size();i++) { normals->push_back( mPoints[i].n ); } //errMsg("N2"," ivi"<size()<<" ns"<size()<<" ts"<size() ); //errMsg("N2"," ovs"< *triangles, if(getCastShadows() ) { flag |= TRI_CASTSHADOWS; } - /* init geo init id */ - int geoiId = getGeoInitId(); - if(geoiId > 0) { - flag |= (1<< (geoiId+4)); - flag |= mGeoInitType; - } + /* init geo init id */ + int geoiId = getGeoInitId(); + if(geoiId > 0) { + flag |= (1<< (geoiId+4)); + flag |= mGeoInitType; + } - tri.setFlags( flag ); + tri.setFlags( flag ); - /* triangle normal missing */ - tri.setNormal( ntlVec3Gfx(0.0) ); - tri.setSmoothNormals( smooth ); - tri.setObjectId( objectId ); - triangles->push_back( tri ); + /* triangle normal missing */ + tri.setNormal( ntlVec3Gfx(0.0) ); + tri.setSmoothNormals( smooth ); + tri.setObjectId( objectId ); + triangles->push_back( tri ); } //errMsg("N3"," ivi"<size()<<" ns"<size()<<" ts"<size() ); return; @@ -743,11 +755,11 @@ inline ntlVec3Gfx IsoSurface::getNormal(int i, int j,int k) { // WARNING - this requires a security boundary layer... ntlVec3Gfx ret(0.0); ret[0] = *getData(i-1,j ,k ) - - *getData(i+1,j ,k ); + *getData(i+1,j ,k ); ret[1] = *getData(i ,j-1,k ) - - *getData(i ,j+1,k ); + *getData(i ,j+1,k ); ret[2] = *getData(i ,j ,k-1 ) - - *getData(i ,j ,k+1 ); + *getData(i ,j ,k+1 ); return ret; } @@ -769,13 +781,13 @@ void IsoSurface::setSmoothRad(float radi1, float radi2, ntlVec3Gfx mscc) { // compute normals for all generated triangles void IsoSurface::computeNormals() { - for(int i=0;i<(int)mPoints.size();i++) { + for(int i=0;i<(int)mPoints.size();i++) { mPoints[i].n = ntlVec3Gfx(0.); } - for(int i=0;i<(int)mIndices.size();i+=3) { - const int t1 = mIndices[i]; - const int t2 = mIndices[i+1]; + for(int i=0;i<(int)mIndices.size();i+=3) { + const int t1 = mIndices[i]; + const int t2 = mIndices[i+1]; const int t3 = mIndices[i+2]; const ntlVec3Gfx p1 = mPoints[t1].v; const ntlVec3Gfx p2 = mPoints[t2].v; @@ -792,7 +804,7 @@ void IsoSurface::computeNormals() { mPoints[t3].n += norm * (1./(len2*len3)); } - for(int i=0;i<(int)mPoints.size();i++) { + for(int i=0;i<(int)mPoints.size();i++) { normalize(mPoints[i].n); } } @@ -903,86 +915,86 @@ void IsoSurface::smoothSurface(float sigma, bool normSmooth) // Edges ntlVec3Gfx e[3] = { mPoints[mIndices[i*3+2]].v - mPoints[mIndices[i*3+1]].v, - mPoints[mIndices[i*3+0]].v - mPoints[mIndices[i*3+2]].v, - mPoints[mIndices[i*3+1]].v - mPoints[mIndices[i*3+0]].v }; + mPoints[mIndices[i*3+0]].v - mPoints[mIndices[i*3+2]].v, + mPoints[mIndices[i*3+1]].v - mPoints[mIndices[i*3+0]].v }; // Compute corner weights - float area = 0.5f * norm( cross(e[0], e[1])); - float l2[3] = { normNoSqrt(e[0]), normNoSqrt(e[1]), normNoSqrt(e[2]) }; - float ew[3] = { l2[0] * (l2[1] + l2[2] - l2[0]), - l2[1] * (l2[2] + l2[0] - l2[1]), - l2[2] * (l2[0] + l2[1] - l2[2]) }; - if (ew[0] <= 0.0f) { - cornerareas[i][1] = -0.25f * l2[2] * area / - dot(e[0] , e[2]); - cornerareas[i][2] = -0.25f * l2[1] * area / - dot(e[0] , e[1]); - cornerareas[i][0] = area - cornerareas[i][1] - - cornerareas[i][2]; - } else if (ew[1] <= 0.0f) { - cornerareas[i][2] = -0.25f * l2[0] * area / - dot(e[1] , e[0]); - cornerareas[i][0] = -0.25f * l2[2] * area / - dot(e[1] , e[2]); - cornerareas[i][1] = area - cornerareas[i][2] - - cornerareas[i][0]; - } else if (ew[2] <= 0.0f) { - cornerareas[i][0] = -0.25f * l2[1] * area / - dot(e[2] , e[1]); - cornerareas[i][1] = -0.25f * l2[0] * area / - dot(e[2] , e[0]); - cornerareas[i][2] = area - cornerareas[i][0] - - cornerareas[i][1]; - } else { - float ewscale = 0.5f * area / (ew[0] + ew[1] + ew[2]); - for (int j = 0; j < 3; j++) - cornerareas[i][j] = ewscale * (ew[(j+1)%3] + - ew[(j+2)%3]); - } + float area = 0.5f * norm( cross(e[0], e[1])); + float l2[3] = { normNoSqrt(e[0]), normNoSqrt(e[1]), normNoSqrt(e[2]) }; + float ew[3] = { l2[0] * (l2[1] + l2[2] - l2[0]), + l2[1] * (l2[2] + l2[0] - l2[1]), + l2[2] * (l2[0] + l2[1] - l2[2]) }; + if (ew[0] <= 0.0f) { + cornerareas[i][1] = -0.25f * l2[2] * area / + dot(e[0] , e[2]); + cornerareas[i][2] = -0.25f * l2[1] * area / + dot(e[0] , e[1]); + cornerareas[i][0] = area - cornerareas[i][1] - + cornerareas[i][2]; + } else if (ew[1] <= 0.0f) { + cornerareas[i][2] = -0.25f * l2[0] * area / + dot(e[1] , e[0]); + cornerareas[i][0] = -0.25f * l2[2] * area / + dot(e[1] , e[2]); + cornerareas[i][1] = area - cornerareas[i][2] - + cornerareas[i][0]; + } else if (ew[2] <= 0.0f) { + cornerareas[i][0] = -0.25f * l2[1] * area / + dot(e[2] , e[1]); + cornerareas[i][1] = -0.25f * l2[0] * area / + dot(e[2] , e[0]); + cornerareas[i][2] = area - cornerareas[i][0] - + cornerareas[i][1]; + } else { + float ewscale = 0.5f * area / (ew[0] + ew[1] + ew[2]); + for (int j = 0; j < 3; j++) + cornerareas[i][j] = ewscale * (ew[(j+1)%3] + + ew[(j+2)%3]); + } // NT important, check this... #ifndef WIN32 - if(! finite(cornerareas[i][0]) ) cornerareas[i][0]=1e-6; - if(! finite(cornerareas[i][1]) ) cornerareas[i][1]=1e-6; - if(! finite(cornerareas[i][2]) ) cornerareas[i][2]=1e-6; + if(! finite(cornerareas[i][0]) ) cornerareas[i][0]=1e-6; + if(! finite(cornerareas[i][1]) ) cornerareas[i][1]=1e-6; + if(! finite(cornerareas[i][2]) ) cornerareas[i][2]=1e-6; #else // WIN32 // FIXME check as well... - if(! (cornerareas[i][0]>=0.0) ) cornerareas[i][0]=1e-6; - if(! (cornerareas[i][1]>=0.0) ) cornerareas[i][1]=1e-6; - if(! (cornerareas[i][2]>=0.0) ) cornerareas[i][2]=1e-6; + if(! (cornerareas[i][0]>=0.0) ) cornerareas[i][0]=1e-6; + if(! (cornerareas[i][1]>=0.0) ) cornerareas[i][1]=1e-6; + if(! (cornerareas[i][2]>=0.0) ) cornerareas[i][2]=1e-6; #endif // WIN32 - pointareas[mIndices[i*3+0]] += cornerareas[i][0]; - pointareas[mIndices[i*3+1]] += cornerareas[i][1]; - pointareas[mIndices[i*3+2]] += cornerareas[i][2]; + pointareas[mIndices[i*3+0]] += cornerareas[i][0]; + pointareas[mIndices[i*3+1]] += cornerareas[i][1]; + pointareas[mIndices[i*3+2]] += cornerareas[i][2]; } } // need pointarea - // */ + // */ float invsigma2 = 1.0f / (sigma*sigma); vector dflt(nv); for (int i = 0; i < nv; i++) { if(diffuseVertexField( &mPoints[0].v, 2, - i, invsigma2, dflt[i])) { + i, invsigma2, dflt[i])) { // Just keep the displacement - dflt[i] -= mPoints[i].v; - } else { dflt[i] = 0.0; } //?mPoints[i].v; } + dflt[i] -= mPoints[i].v; + } else { dflt[i] = 0.0; } //?mPoints[i].v; } } // Slightly better small-neighborhood approximation for (int i = 0; i < nf; i++) { ntlVec3Gfx c = mPoints[mIndices[i*3+0]].v + - mPoints[mIndices[i*3+1]].v + - mPoints[mIndices[i*3+2]].v; + mPoints[mIndices[i*3+1]].v + + mPoints[mIndices[i*3+2]].v; c /= 3.0f; for (int j = 0; j < 3; j++) { int v = mIndices[i*3+j]; ntlVec3Gfx d =(c - mPoints[v].v) * 0.5f; dflt[v] += d * (cornerareas[i][j] / - pointareas[mIndices[i*3+j]] * - exp(-0.5f * invsigma2 * normNoSqrt(d)) ); + pointareas[mIndices[i*3+j]] * + exp(-0.5f * invsigma2 * normNoSqrt(d)) ); } } @@ -990,7 +1002,7 @@ void IsoSurface::smoothSurface(float sigma, bool normSmooth) vector dflt2(nv); for (int i = 0; i < nv; i++) { if(diffuseVertexField( &dflt[0], 1, - i, invsigma2, dflt2[i])) { } + i, invsigma2, dflt2[i])) { } else { /*mPoints[i].v=0.0;*/ dflt2[i] = 0.0; }//dflt2[i]; } } @@ -1062,58 +1074,58 @@ void IsoSurface::smoothNormals(float sigma) { // Edges ntlVec3Gfx e[3] = { mPoints[mIndices[i*3+2]].v - mPoints[mIndices[i*3+1]].v, - mPoints[mIndices[i*3+0]].v - mPoints[mIndices[i*3+2]].v, - mPoints[mIndices[i*3+1]].v - mPoints[mIndices[i*3+0]].v }; + mPoints[mIndices[i*3+0]].v - mPoints[mIndices[i*3+2]].v, + mPoints[mIndices[i*3+1]].v - mPoints[mIndices[i*3+0]].v }; // Compute corner weights - float area = 0.5f * norm( cross(e[0], e[1])); - float l2[3] = { normNoSqrt(e[0]), normNoSqrt(e[1]), normNoSqrt(e[2]) }; - float ew[3] = { l2[0] * (l2[1] + l2[2] - l2[0]), - l2[1] * (l2[2] + l2[0] - l2[1]), - l2[2] * (l2[0] + l2[1] - l2[2]) }; - if (ew[0] <= 0.0f) { - cornerareas[i][1] = -0.25f * l2[2] * area / - dot(e[0] , e[2]); - cornerareas[i][2] = -0.25f * l2[1] * area / - dot(e[0] , e[1]); - cornerareas[i][0] = area - cornerareas[i][1] - - cornerareas[i][2]; - } else if (ew[1] <= 0.0f) { - cornerareas[i][2] = -0.25f * l2[0] * area / - dot(e[1] , e[0]); - cornerareas[i][0] = -0.25f * l2[2] * area / - dot(e[1] , e[2]); - cornerareas[i][1] = area - cornerareas[i][2] - - cornerareas[i][0]; - } else if (ew[2] <= 0.0f) { - cornerareas[i][0] = -0.25f * l2[1] * area / - dot(e[2] , e[1]); - cornerareas[i][1] = -0.25f * l2[0] * area / - dot(e[2] , e[0]); - cornerareas[i][2] = area - cornerareas[i][0] - - cornerareas[i][1]; - } else { - float ewscale = 0.5f * area / (ew[0] + ew[1] + ew[2]); - for (int j = 0; j < 3; j++) - cornerareas[i][j] = ewscale * (ew[(j+1)%3] + - ew[(j+2)%3]); - } + float area = 0.5f * norm( cross(e[0], e[1])); + float l2[3] = { normNoSqrt(e[0]), normNoSqrt(e[1]), normNoSqrt(e[2]) }; + float ew[3] = { l2[0] * (l2[1] + l2[2] - l2[0]), + l2[1] * (l2[2] + l2[0] - l2[1]), + l2[2] * (l2[0] + l2[1] - l2[2]) }; + if (ew[0] <= 0.0f) { + cornerareas[i][1] = -0.25f * l2[2] * area / + dot(e[0] , e[2]); + cornerareas[i][2] = -0.25f * l2[1] * area / + dot(e[0] , e[1]); + cornerareas[i][0] = area - cornerareas[i][1] - + cornerareas[i][2]; + } else if (ew[1] <= 0.0f) { + cornerareas[i][2] = -0.25f * l2[0] * area / + dot(e[1] , e[0]); + cornerareas[i][0] = -0.25f * l2[2] * area / + dot(e[1] , e[2]); + cornerareas[i][1] = area - cornerareas[i][2] - + cornerareas[i][0]; + } else if (ew[2] <= 0.0f) { + cornerareas[i][0] = -0.25f * l2[1] * area / + dot(e[2] , e[1]); + cornerareas[i][1] = -0.25f * l2[0] * area / + dot(e[2] , e[0]); + cornerareas[i][2] = area - cornerareas[i][0] - + cornerareas[i][1]; + } else { + float ewscale = 0.5f * area / (ew[0] + ew[1] + ew[2]); + for (int j = 0; j < 3; j++) + cornerareas[i][j] = ewscale * (ew[(j+1)%3] + + ew[(j+2)%3]); + } // NT important, check this... #ifndef WIN32 - if(! finite(cornerareas[i][0]) ) cornerareas[i][0]=1e-6; - if(! finite(cornerareas[i][1]) ) cornerareas[i][1]=1e-6; - if(! finite(cornerareas[i][2]) ) cornerareas[i][2]=1e-6; + if(! finite(cornerareas[i][0]) ) cornerareas[i][0]=1e-6; + if(! finite(cornerareas[i][1]) ) cornerareas[i][1]=1e-6; + if(! finite(cornerareas[i][2]) ) cornerareas[i][2]=1e-6; #else // WIN32 // FIXME check as well... - if(! (cornerareas[i][0]>=0.0) ) cornerareas[i][0]=1e-6; - if(! (cornerareas[i][1]>=0.0) ) cornerareas[i][1]=1e-6; - if(! (cornerareas[i][2]>=0.0) ) cornerareas[i][2]=1e-6; + if(! (cornerareas[i][0]>=0.0) ) cornerareas[i][0]=1e-6; + if(! (cornerareas[i][1]>=0.0) ) cornerareas[i][1]=1e-6; + if(! (cornerareas[i][2]>=0.0) ) cornerareas[i][2]=1e-6; #endif // WIN32 - pointareas[mIndices[i*3+0]] += cornerareas[i][0]; - pointareas[mIndices[i*3+1]] += cornerareas[i][1]; - pointareas[mIndices[i*3+2]] += cornerareas[i][2]; + pointareas[mIndices[i*3+0]] += cornerareas[i][0]; + pointareas[mIndices[i*3+1]] += cornerareas[i][1]; + pointareas[mIndices[i*3+2]] += cornerareas[i][2]; } } // need pointarea From 543f38c20a10f08eb11391b99c00ff6bf2add3d9 Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Thu, 29 Nov 2007 12:29:32 +0000 Subject: [PATCH 065/246] Fix: GUI cache reset should work again, same goes for collision modifier (enabled through 'deflection' panel --- source/blender/blenkernel/BKE_cloth.h | 7 +- source/blender/blenkernel/BKE_collisions.h | 10 +- source/blender/blenkernel/intern/cloth.c | 1 + source/blender/blenkernel/intern/collision.c | 2 +- source/blender/blenkernel/intern/implicit.c | 379 +++++++++++-------- source/blender/blenkernel/intern/modifier.c | 6 + source/blender/makesdna/DNA_modifier_types.h | 1 + source/blender/src/buttons_editing.c | 8 - source/blender/src/buttons_object.c | 50 ++- 9 files changed, 300 insertions(+), 164 deletions(-) diff --git a/source/blender/blenkernel/BKE_cloth.h b/source/blender/blenkernel/BKE_cloth.h index 2bb3e32d6b6..c8ec1698b86 100644 --- a/source/blender/blenkernel/BKE_cloth.h +++ b/source/blender/blenkernel/BKE_cloth.h @@ -72,10 +72,10 @@ typedef struct ClothVertex { } ClothVertex; typedef struct ClothSpring { - int ij; /* Pij from the paper, one end of the spring. */ - int kl; /* Pkl from the paper, one end of the spring. */ + unsigned int ij; /* Pij from the paper, one end of the spring. */ + unsigned int kl; /* Pkl from the paper, one end of the spring. */ float restlen; /* The original length of the spring. */ - int matrix_index; /* needed for implicit solver (fast lookup) */ + unsigned int matrix_index; /* needed for implicit solver (fast lookup) */ int type; /* types defined in BKE_cloth.h ("springType") */ int flags; /* defined in BKE_cloth.h, e.g. deactivated due to tearing */ float dfdx[3][3]; @@ -152,6 +152,7 @@ typedef enum CLOTH_SPRING_TYPE_STRUCTURAL = 0, CLOTH_SPRING_TYPE_SHEAR, CLOTH_SPRING_TYPE_BENDING, + CLOTH_SPRING_TYPE_COLLISION, } CLOTH_SPRING_TYPES; /* SPRING FLAGS */ diff --git a/source/blender/blenkernel/BKE_collisions.h b/source/blender/blenkernel/BKE_collisions.h index f358bd629e6..e38662fdf95 100644 --- a/source/blender/blenkernel/BKE_collisions.h +++ b/source/blender/blenkernel/BKE_collisions.h @@ -37,11 +37,13 @@ #include #include #include + /* types */ #include "BLI_linklist.h" #include "BKE_DerivedMesh.h" #include "BKE_object.h" -#include "BKE_DerivedMesh.h" + +#include "DNA_modifier_types.h" // used in kdop.c and collision.c typedef struct CollisionTree @@ -82,6 +84,8 @@ typedef struct CollisionPair { int point_indexA[4], point_indexB[4]; float vector[3]; + float normal[3]; // has to be calculated from vector + float distance; float pa[3], pb[3]; } CollisionPair; @@ -115,6 +119,10 @@ LinkNode *BLI_linklist_append_fast (LinkNode **listp, void *ptr); // defined in collisions.c void collision_move_object(CollisionModifierData *collmd, float step, float prevstep); +// interface for collision functions +void collisions_compute_barycentric (float pv[3], float p1[3], float p2[3], float p3[3], float *w1, float *w2, float *w3); +void interpolateOnTriangle(float to[3], float v1[3], float v2[3], float v3[3], double w1, double w2, double w3); + ///////////////////////////////////////////////// #endif diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c index 6eacb26c315..2dd4f1a0f0f 100644 --- a/source/blender/blenkernel/intern/cloth.c +++ b/source/blender/blenkernel/intern/cloth.c @@ -1009,6 +1009,7 @@ static void cloth_from_mesh (Object *ob, ClothModifierData *clmd, DerivedMesh *d ***************************************************************************************/ // be carefull: implicit solver has to be resettet when using this one! +// --> only for implicit handling of this spring! int cloth_add_spring ( ClothModifierData *clmd, unsigned int indexA, unsigned int indexB, float restlength, int spring_type) { Cloth *cloth = clmd->clothObject; diff --git a/source/blender/blenkernel/intern/collision.c b/source/blender/blenkernel/intern/collision.c index 6f0ac5f8c6d..4bc1efc1e70 100644 --- a/source/blender/blenkernel/intern/collision.c +++ b/source/blender/blenkernel/intern/collision.c @@ -71,7 +71,6 @@ #include "Bullet-C-Api.h" - // step is limited from 0 (frame start position) to 1 (frame end position) void collision_move_object(CollisionModifierData *collmd, float step, float prevstep) { @@ -83,6 +82,7 @@ void collision_move_object(CollisionModifierData *collmd, float step, float prev VECSUB(tv, collmd->xnew[i].co, collmd->x[i].co); VECADDS(collmd->current_x[i].co, collmd->x[i].co, tv, prevstep); VECADDS(collmd->current_xnew[i].co, collmd->x[i].co, tv, step); + VECSUB(collmd->current_v[i].co, collmd->current_xnew[i].co, collmd->current_x[i].co); } } diff --git a/source/blender/blenkernel/intern/implicit.c b/source/blender/blenkernel/intern/implicit.c index 12c5c190691..3b8f6ddd7d8 100644 --- a/source/blender/blenkernel/intern/implicit.c +++ b/source/blender/blenkernel/intern/implicit.c @@ -63,6 +63,8 @@ #include "BKE_global.h" #include "BIF_editdeform.h" +#include "Bullet-C-Api.h" + #ifdef _WIN32 #include static LARGE_INTEGER _itstart, _itend; @@ -1123,6 +1125,17 @@ DO_INLINE void cloth_calc_spring_force(ClothModifierData *clmd, ClothSpring *s, } + if(s->type == CLOTH_SPRING_TYPE_COLLISION) + { + if(length < L) + { + mul_fvector_S(stretch_force, dir, (100.0*(length-L))); + + VECADD(s->f, s->f, stretch_force); + } + return; + } + // calculate force of structural + shear springs if(s->type != CLOTH_SPRING_TYPE_BENDING) { @@ -1415,6 +1428,19 @@ int implicit_solver (Object *ob, float frame, ClothModifierData *clmd, ListBase { effectors= pdInitEffectors(ob,NULL); + // clear constraint matrix from collisions + if(clmd->coll_parms->flags & CLOTH_COLLISIONSETTINGS_FLAG_ENABLED) + { + for(i = 0; i < id->S[0].vcount; i++) + { + if(!(verts [id->S[i].r].goal >= SOFTGOALSNAP)) + { + id->S[0].vcount = i-1; + break; + } + } + } + // calculate cloth_calc_force(clmd, id->F, id->X, id->V, id->dFdV, id->dFdX, effectors, step ); @@ -1553,122 +1579,148 @@ void implicit_set_positions (ClothModifierData *clmd) memcpy(id->V, cloth->v, sizeof(lfVector) * numverts); } - -int collisions_collision_response_static(ClothModifierData *clmd, ClothModifierData *coll_clmd) +unsigned int implicit_getcreate_S_index(ClothModifierData *clmd, unsigned int index) { - /* + Cloth *cloth = clmd->clothObject; + Implicit_Data *id = cloth->implicit; + unsigned int i = 0, pinned = 0; + + pinned = id->S[0].vcount; + + for(i = 0; i < pinned; i++) + { + if(id->S[i].r == index) + { + return index; + } + } + + // create new PINNED entry in constraint matrix + id->S[0].vcount++; + id->S[pinned].c = id->S[pinned].r = index; + return pinned; +} + +int collisions_collision_response_static ( ClothModifierData *clmd, CollisionModifierData *collmd, CollisionPair *collpair ) +{ + unsigned int i = 0; int result = 0; LinkNode *search = NULL; - CollPair *collpair = NULL; - Cloth *cloth1, *cloth2; + Cloth *cloth1 = NULL; float w1, w2, w3, u1, u2, u3; float v1[3], v2[3], relativeVelocity[3]; - float magrelVel; - + float magrelVel = 0.0; + float epsilon = clmd->coll_parms->epsilon; + cloth1 = clmd->clothObject; - cloth2 = coll_clmd->clothObject; + + if(!collpair) + return 0; + + // TODO: check distance & calc normal + // calc distance + normal + collpair->distance = plNearestPoints( + cloth1->current_xold[collpair->point_indexA[0]], + cloth1->current_xold[collpair->point_indexA[1]], + cloth1->current_xold[collpair->point_indexA[2]], + collmd->current_x[collpair->point_indexB[0]].co, + collmd->current_x[collpair->point_indexB[1]].co, + collmd->current_x[collpair->point_indexB[2]].co, + collpair->pa,collpair->pb,collpair->vector); + + if (collpair->distance > (epsilon + ALMOST_ZERO)) + { + return 0; + } - // search = clmd->coll_parms.collision_list; - - while(search) - { - collpair = search->link; - - // compute barycentric coordinates for both collision points - collisions_compute_barycentric(collpair->pa, - cloth1->verts[collpair->ap1].txold, - cloth1->verts[collpair->ap2].txold, - cloth1->verts[collpair->ap3].txold, - &w1, &w2, &w3); - - collisions_compute_barycentric(collpair->pb, - cloth2->verts[collpair->bp1].txold, - cloth2->verts[collpair->bp2].txold, - cloth2->verts[collpair->bp3].txold, - &u1, &u2, &u3); - - // Calculate relative "velocity". - interpolateOnTriangle(v1, cloth1->verts[collpair->ap1].tv, cloth1->verts[collpair->ap2].tv, cloth1->verts[collpair->ap3].tv, w1, w2, w3); - - interpolateOnTriangle(v2, cloth2->verts[collpair->bp1].tv, cloth2->verts[collpair->bp2].tv, cloth2->verts[collpair->bp3].tv, u1, u2, u3); - - VECSUB(relativeVelocity, v1, v2); - - // Calculate the normal component of the relative velocity (actually only the magnitude - the direction is stored in 'normal'). - magrelVel = INPR(relativeVelocity, collpair->normal); - - // printf("magrelVel: %f\n", magrelVel); - - // Calculate masses of points. - - // If v_n_mag < 0 the edges are approaching each other. - if(magrelVel < -ALMOST_ZERO) - { - // Calculate Impulse magnitude to stop all motion in normal direction. - // const double I_mag = v_n_mag / (1/m1 + 1/m2); - float magnitude_i = magrelVel / 2.0f; // TODO implement masses - float tangential[3], magtangent, magnormal, collvel[3]; - float vrel_t_pre[3]; - float vrel_t[3]; - double impulse; - float epsilon = clmd->coll_parms.epsilon; - float overlap = (epsilon + ALMOST_ZERO-collpair->distance); - - // calculateFrictionImpulse(tangential, relativeVelocity, collpair->normal, magrelVel, clmd->coll_parms.friction*0.01, magrelVel); - - // magtangent = INPR(tangential, tangential); - - // Apply friction impulse. - if (magtangent < -ALMOST_ZERO) - { - - // printf("friction applied: %f\n", magtangent); - // TODO check original code -} - + // compute barycentric coordinates for both collision points + collisions_compute_barycentric (collpair->pa, + cloth1->current_xold[collpair->point_indexA[0]], + cloth1->current_xold[collpair->point_indexA[1]], + cloth1->current_xold[collpair->point_indexA[2]], + &w1, &w2, &w3 ); - impulse = -2.0f * magrelVel / ( 1.0 + w1*w1 + w2*w2 + w3*w3); - - // printf("impulse: %f\n", impulse); - - // face A - VECADDMUL(cloth1->verts[collpair->ap1].impulse, collpair->normal, w1 * impulse); - cloth1->verts[collpair->ap1].impulse_count++; - - VECADDMUL(cloth1->verts[collpair->ap2].impulse, collpair->normal, w2 * impulse); - cloth1->verts[collpair->ap2].impulse_count++; - - VECADDMUL(cloth1->verts[collpair->ap3].impulse, collpair->normal, w3 * impulse); - cloth1->verts[collpair->ap3].impulse_count++; - - // face B - VECADDMUL(cloth2->verts[collpair->bp1].impulse, collpair->normal, u1 * impulse); - cloth2->verts[collpair->bp1].impulse_count++; - - VECADDMUL(cloth2->verts[collpair->bp2].impulse, collpair->normal, u2 * impulse); - cloth2->verts[collpair->bp2].impulse_count++; - - VECADDMUL(cloth2->verts[collpair->bp3].impulse, collpair->normal, u3 * impulse); - cloth2->verts[collpair->bp3].impulse_count++; - - - result = 1; + collisions_compute_barycentric (collpair->pb, + collmd->current_x[collpair->point_indexB[0]].co, + collmd->current_x[collpair->point_indexB[1]].co, + collmd->current_x[collpair->point_indexB[2]].co, + &u1, &u2, &u3 ); + + // Calculate relative "velocity". + interpolateOnTriangle ( v1, cloth1->current_v[collpair->point_indexA[0]], cloth1->current_v[collpair->point_indexA[1]], cloth1->current_v[collpair->point_indexA[2]], w1, w2, w3 ); + + interpolateOnTriangle ( v2, collmd->current_v[collpair->point_indexB[0]].co, collmd->current_v[collpair->point_indexB[1]].co, collmd->current_v[collpair->point_indexB[2]].co, u1, u2, u3 ); + + VECSUB ( relativeVelocity, v1, v2 ); + + // Calculate the normal component of the relative velocity (actually only the magnitude - the direction is stored in 'normal'). + magrelVel = INPR ( relativeVelocity, collpair->normal ); + + // printf("magrelVel: %f\n", magrelVel); + + // Calculate masses of points. + + // If v_n_mag < 0 the edges are approaching each other. + if ( magrelVel < -ALMOST_ZERO ) + { + // Calculate Impulse magnitude to stop all motion in normal direction. + // const double I_mag = v_n_mag / (1/m1 + 1/m2); + float magnitude_i = magrelVel / 2.0f; // TODO implement masses + float tangential[3], magtangent, magnormal, collvel[3]; + float vrel_t_pre[3]; + float vrel_t[3]; + double impulse; + float overlap = ( epsilon + ALMOST_ZERO-collpair->distance ); + + // calculateFrictionImpulse(tangential, relativeVelocity, collpair->normal, magrelVel, clmd->coll_parms.friction*0.01, magrelVel); + + // magtangent = INPR(tangential, tangential); + + // Apply friction impulse. + if ( magtangent < -ALMOST_ZERO ) + { + + // printf("friction applied: %f\n", magtangent); + // TODO check original code + } + + + impulse = -2.0f * magrelVel / ( 1.0 + w1*w1 + w2*w2 + w3*w3 ); + + // printf("impulse: %f\n", impulse); + + // face A + VECADDMUL ( cloth1->verts[collpair->point_indexA[0]].impulse, collpair->normal, w1 * impulse ); + cloth1->verts[collpair->point_indexA[0]].impulse_count++; + + VECADDMUL ( cloth1->verts[collpair->point_indexA[1]].impulse, collpair->normal, w2 * impulse ); + cloth1->verts[collpair->point_indexA[1]].impulse_count++; + + VECADDMUL ( cloth1->verts[collpair->point_indexA[2]].impulse, collpair->normal, w3 * impulse ); + cloth1->verts[collpair->point_indexA[2]].impulse_count++; + + // face B + /* + VECADDMUL ( collmd->verts[collpair->point_indexB[0]].impulse, collpair->normal, u1 * impulse ); + collmd->verts[collpair->point_indexB[0]].impulse_count++; + + VECADDMUL ( collmd->verts[collpair->point_indexB[1]].impulse, collpair->normal, u2 * impulse ); + collmd->verts[collpair->point_indexB[1]].impulse_count++; + + VECADDMUL ( collmd->verts[collpair->point_indexB[2]].impulse, collpair->normal, u3 * impulse ); + collmd->verts[collpair->point_indexB[2]].impulse_count++; + */ - // printf("magnitude_i: %f\n", magnitude_i); // negative before collision in my case - - // Apply the impulse and increase impulse counters. - - -} - - search = search->next; -} - + result = 1; + + // printf("magnitude_i: %f\n", magnitude_i); // negative before collision in my case + + // Apply the impulse and increase impulse counters. + + } return result; - */ - return 0; } @@ -2087,10 +2139,11 @@ int cloth_bvh_objcollision(ClothModifierData * clmd, float step, float prevstep, Object *ob2 = NULL; BVH *bvh1 = NULL, *bvh2 = NULL, *self_bvh; LinkNode *collision_list = NULL; - unsigned int i = 0, j = 0; + unsigned int i = 0, j = 0, index; int collisions = 0, count = 0; float (*current_x)[3]; - + Implicit_Data *id = NULL; + /* if (!(((Cloth *)clmd->clothObject)->tree)) { printf("No BVH found\n"); @@ -2100,65 +2153,77 @@ int cloth_bvh_objcollision(ClothModifierData * clmd, float step, float prevstep, cloth = clmd->clothObject; bvh1 = cloth->tree; self_bvh = cloth->selftree; + id = cloth->implicit; //////////////////////////////////////////////////////////// // static collisions //////////////////////////////////////////////////////////// // update cloth bvh - bvh_update_from_float3(bvh1, cloth->current_xold, cloth->numverts, cloth->current_x, 0); // 0 means STATIC, 1 means MOVING (see later in this function) -/* + bvh_update_from_float3 ( bvh1, cloth->current_xold, cloth->numverts, cloth->current_x, 0 ); // 0 means STATIC, 1 means MOVING (see later in this function) + // check all collision objects - for (base = G.scene->base.first; base; base = base->next) + for ( base = G.scene->base.first; base; base = base->next ) { - ob2 = base->object; - collmd = (CollisionModifierData *) modifiers_findByType (ob2, eModifierType_Collision); - - if (!collmd) - continue; - + ob2 = base->object; + collmd = ( CollisionModifierData * ) modifiers_findByType ( ob2, eModifierType_Collision ); + + if ( !collmd ) + continue; + // check if there is a bounding volume hierarchy - if (collmd->tree) - { - bvh2 = collmd->tree; - + if ( collmd->tree ) + { + bvh2 = collmd->tree; + // update position + bvh of collision object - collision_move_object(collmd, step, prevstep); - bvh_update_from_mvert(collmd->tree, collmd->current_x, collmd->numverts, NULL, 0); - - // fill collision list - collisions += bvh_traverse(bvh1->root, bvh2->root, &collision_list); - + collision_move_object ( collmd, step, prevstep ); + bvh_update_from_mvert ( collmd->tree, collmd->current_x, collmd->numverts, NULL, 0 ); + + // fill collision list + collisions += bvh_traverse ( bvh1->root, bvh2->root, &collision_list ); + // call static collision response + if ( collision_list ) + { + LinkNode *search = collision_list; + + while ( search ) + { + collisions_collision_response_static(clmd, collmd, (CollisionPair *)search->link); + + search = search->next; + } + } // free collision list - if(collision_list) - { - LinkNode *search = collision_list; - - while(search) - { - CollisionPair *coll_pair = search->link; - - MEM_freeN(coll_pair); - search = search->next; -} - BLI_linklist_free(collision_list,NULL); + if ( collision_list ) + { + LinkNode *search = collision_list; - collision_list = NULL; -} -} -} + while ( search ) + { + CollisionPair *coll_pair = search->link; + + MEM_freeN ( coll_pair ); + search = search->next; + } + BLI_linklist_free ( collision_list,NULL ); + + collision_list = NULL; + } + } + } ////////////////////////////////////////////// // update velocities + positions ////////////////////////////////////////////// for(i = 0; i < cloth->numverts; i++) { - VECADD(cloth->current_x[i], cloth->current_xold[i], cloth->current_v[i]); -} + VECADD(cloth->current_x[i], cloth->current_xold[i], cloth->current_v[i]); + } ////////////////////////////////////////////// -*/ + */ /* // fill collision list collisions += bvh_traverse(self_bvh->root, self_bvh->root, &collision_list); @@ -2235,7 +2300,7 @@ int cloth_bvh_objcollision(ClothModifierData * clmd, float step, float prevstep, collisions = 1; count = 0; current_x = cloth->current_x; // needed for openMP - + /* // #pragma omp parallel for private(i,j, collisions) shared(current_x) // for ( count = 0; count < 6; count++ ) { @@ -2275,8 +2340,6 @@ int cloth_bvh_objcollision(ClothModifierData * clmd, float step, float prevstep, { float correction = ((mindistance1 + mindistance2)) - length; - printf("correction: %f\n", correction); - if ( ( clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL ) && ( cloth->verts [i].goal >= SOFTGOALSNAP ) ) { VecMulf ( temp, -correction ); @@ -2289,10 +2352,24 @@ int cloth_bvh_objcollision(ClothModifierData * clmd, float step, float prevstep, } else { + unsigned int pinned = id->S[0].vcount; + + printf("correction: %f\n", correction); + VecMulf ( temp, -correction*0.5 ); VECADD ( current_x[j], current_x[j], temp ); - + VECSUB ( cloth->current_v[j], cloth->current_x[j], cloth->current_xold[j] ); + + index = implicit_getcreate_S_index(clmd, j); + id->S[index].pinned = 1; + VECSUB ( current_x[i], current_x[i], temp ); + VECSUB ( cloth->current_v[i], cloth->current_x[i], cloth->current_xold[i] ); + + index = implicit_getcreate_S_index(clmd, i); + id->S[index].pinned = 1; + + cloth_add_spring (clmd, i, j, mindistance1 + mindistance2, CLOTH_SPRING_TYPE_COLLISION); } collisions = 1; @@ -2300,16 +2377,18 @@ int cloth_bvh_objcollision(ClothModifierData * clmd, float step, float prevstep, } } } - + */ ////////////////////////////////////////////// // SELFCOLLISIONS: update velocities ////////////////////////////////////////////// + /* for ( i = 0; i < cloth->numverts; i++ ) { VECSUB ( cloth->current_v[i], cloth->current_x[i], cloth->current_xold[i] ); } + */ ////////////////////////////////////////////// - return 1; + return 0; } diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c index af8b4aa8079..e433fb6ed88 100644 --- a/source/blender/blenkernel/intern/modifier.c +++ b/source/blender/blenkernel/intern/modifier.c @@ -5068,6 +5068,7 @@ static void collisionModifier_initData(ModifierData *md) collmd->xnew = NULL; collmd->current_x = NULL; collmd->current_xnew = NULL; + collmd->current_v = NULL; collmd->time = -1; collmd->numverts = 0; collmd->tree = NULL; @@ -5089,11 +5090,14 @@ static void collisionModifier_freeData(ModifierData *md) MEM_freeN(collmd->current_x); if(collmd->current_xnew) MEM_freeN(collmd->current_xnew); + if(collmd->current_v) + MEM_freeN(collmd->current_v); collmd->x = NULL; collmd->xnew = NULL; collmd->current_x = NULL; collmd->current_xnew = NULL; + collmd->current_v = NULL; collmd->time = -1; collmd->numverts = 0; collmd->tree = NULL; @@ -5155,6 +5159,8 @@ static void collisionModifier_deformVerts( collmd->xnew = MEM_dupallocN(collmd->x); // frame end position collmd->current_x = MEM_dupallocN(collmd->x); // inter-frame collmd->current_xnew = MEM_dupallocN(collmd->x); // inter-frame + collmd->current_v = MEM_dupallocN(collmd->x); // inter-frame + collmd->numverts = numverts; // TODO: epsilon diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h index 65eec871404..1bb8ce99c88 100644 --- a/source/blender/makesdna/DNA_modifier_types.h +++ b/source/blender/makesdna/DNA_modifier_types.h @@ -358,6 +358,7 @@ typedef struct CollisionModifierData { struct MVert *xnew; /* position at the end of the frame */ struct MVert *current_xnew; /* new position at the actual inter-frame step */ struct MVert *current_x; /* position at the actual inter-frame step */ + struct MVert *current_v; /* position at the actual inter-frame step */ unsigned int numverts; float time; diff --git a/source/blender/src/buttons_editing.c b/source/blender/src/buttons_editing.c index 959fd770959..83f04110974 100644 --- a/source/blender/src/buttons_editing.c +++ b/source/blender/src/buttons_editing.c @@ -1494,14 +1494,6 @@ static void modifiers_convertToReal(void *ob_v, void *md_v) BIF_undo_push("Modifier convert to real"); } -static void modifiers_pointCacheClearModifier(void *ob_v, void *md_v) -{ - Object *ob = ob_v; - ModifierData *md = md_v; - int stack_index = modifiers_indexInObject(ob_v, md_v); - PTCache_id_clear((ID *)ob, CFRA, stack_index); -} - static void build_uvlayer_menu_vars(CustomData *data, char **menu_string, int *uvlayer_tmp, char *uvlayer_name) { diff --git a/source/blender/src/buttons_object.c b/source/blender/src/buttons_object.c index 2ce543eec44..1808618d7b7 100644 --- a/source/blender/src/buttons_object.c +++ b/source/blender/src/buttons_object.c @@ -48,6 +48,7 @@ #include "BKE_action.h" #include "BKE_cloth.h" +#include "BKE_collisions.h" #include "BKE_global.h" #include "BKE_main.h" #include "BKE_library.h" @@ -2966,6 +2967,30 @@ void do_effects_panels(unsigned short event) } allqueue(REDRAWVIEW3D, 0); break; + case B_CLOTH_CLEARCACHEALL: + { + ClothModifierData *clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth); + if(clmd) + { + CFRA= 1; + update_for_newframe_muted(); + DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA); + cloth_clear_cache(ob, clmd, 2); + allqueue(REDRAWBUTSOBJECT, 0); + allqueue(REDRAWVIEW3D, 0); + } + } + break; + case B_CLOTH_RENEW: + { + ClothModifierData *clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth); + if(clmd) + { + do_object_panels(B_CLOTH_CLEARCACHEALL); + cloth_free_modifier (clmd); + } + } + break; default: if(event>=B_SELEFFECT && eventmodifiers, md ); + } + else + { + BLI_remlink ( &ob->modifiers, md ); + modifier_free ( md ); + allqueue(REDRAWBUTSEDIT, 0); + } +} + /* Panels for particle interaction settings */ static void object_panel_deflection(Object *ob) { uiBlock *block; + uiBut *but; block= uiNewBlock(&curarea->uiblocks, "object_panel_deflection", UI_EMBOSS, UI_HELV, curarea->win); if(uiNewPanel(curarea, block, "Deflection", "Physics", 0, 0, 318, 204)==0) return; @@ -3025,7 +3071,9 @@ static void object_panel_deflection(Object *ob) if(ob->pd && ob->type==OB_MESH) { PartDeflect *pd= ob->pd; - uiDefButBitS(block, TOG, 1, B_REDR, "Deflection",160,160,150,20, &pd->deflect, 0, 0, 0, 0, "Deflects particles based on collision"); + but = uiDefButBitS(block, TOG, 1, B_REDR, "Deflection",160,160,150,20, &pd->deflect, 0, 0, 0, 0, "Deflects particles based on collision"); + uiButSetFunc(but, object_collision__enabletoggle, ob, NULL); + if(pd->deflect) { uiDefBut(block, LABEL, 0, "Particles", 160,140,75,20, NULL, 0.0, 0, 0, 0, ""); uiDefButBitS(block, TOG, PDEFLE_KILL_PART, B_DIFF, "Kill",235,140,75,20, &pd->flag, 0, 0, 0, 0, "Kill collided particles"); From 42637b725267192bfe22731bf975cfb1a50541ee Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Wed, 12 Dec 2007 17:33:59 +0000 Subject: [PATCH 066/246] Fixed preconditioned conjugate to some degree but some issues left for stiffness>1000 (disabled therefore). There's also some issue with the springs function (some springs seem to be missing/not created) --- source/blender/blenkernel/BKE_cloth.h | 1 - source/blender/blenkernel/BKE_pointcache.h | 1 + source/blender/blenkernel/SConscript | 2 +- source/blender/blenkernel/intern/cloth.c | 11 +++- source/blender/blenkernel/intern/implicit.c | 65 ++++++++++++------- source/blender/blenkernel/intern/key.c | 10 +-- .../blenkernel/intern/particle_system.c | 2 +- source/blender/blenkernel/intern/pointcache.c | 8 +++ source/blender/makesdna/DNA_key_types.h | 5 +- .../nodes/intern/CMP_nodes/CMP_normalize.c | 5 +- source/blender/src/buttons_editing.c | 13 ++-- source/blender/src/buttons_object.c | 2 + source/blender/src/drawview.c | 52 ++++++++++++++- source/blender/src/editkey.c | 6 +- source/blender/src/editmesh_mods.c | 7 ++ source/blender/src/editparticle.c | 16 ++--- 16 files changed, 152 insertions(+), 54 deletions(-) diff --git a/source/blender/blenkernel/BKE_cloth.h b/source/blender/blenkernel/BKE_cloth.h index c8ec1698b86..e288e7ee082 100644 --- a/source/blender/blenkernel/BKE_cloth.h +++ b/source/blender/blenkernel/BKE_cloth.h @@ -200,7 +200,6 @@ typedef void ( *CM_COLLISION_SELF ) ( struct ClothModifierData *clmd, int step ) // only one available in the moment typedef enum { CM_IMPLICIT = 0, - CM_VERLET = 1, } CM_SOLVER_ID; diff --git a/source/blender/blenkernel/BKE_pointcache.h b/source/blender/blenkernel/BKE_pointcache.h index 020b9d15417..afaf9dbeee2 100644 --- a/source/blender/blenkernel/BKE_pointcache.h +++ b/source/blender/blenkernel/BKE_pointcache.h @@ -44,5 +44,6 @@ int BKE_ptcache_id_filename(struct ID *id, char *filename, int cfra, int stack_index, short do_path, short do_ext); FILE * BKE_ptcache_id_fopen(struct ID *id, char mode, int cfra, int stack_index); void BKE_ptcache_id_clear(struct ID *id, char mode, int cfra, int stack_index); +int BKE_ptcache_id_exist(struct ID *id, int cfra, int stack_index); #endif diff --git a/source/blender/blenkernel/SConscript b/source/blender/blenkernel/SConscript index c83e9f7fbe1..355cd19da33 100644 --- a/source/blender/blenkernel/SConscript +++ b/source/blender/blenkernel/SConscript @@ -7,7 +7,7 @@ incs = '. #/intern/guardedalloc ../include ../blenlib ../makesdna' incs += ' ../python ../render/extern/include #/intern/decimation/extern' incs += ' ../imbuf ../avi #/intern/elbeem/extern ../nodes' incs += ' #/intern/iksolver/extern ../blenloader ../quicktime' -incs += ' #/extern/bullet2/src ' +incs += ' #/extern/bullet2/src' incs += ' #/intern/bmfont' incs += ' ' + env['BF_OPENGL_INC'] diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c index 2dd4f1a0f0f..64166493caa 100644 --- a/source/blender/blenkernel/intern/cloth.c +++ b/source/blender/blenkernel/intern/cloth.c @@ -115,7 +115,6 @@ double tval() static CM_SOLVER_DEF solvers [] = { { "Implicit", CM_IMPLICIT, implicit_init, implicit_solver, implicit_free }, - // { "Verlet", CM_VERLET, verlet_init, verlet_solver, verlet_free }, }; /* ********** cloth engine ******* */ @@ -477,8 +476,9 @@ static int cloth_read_cache(Object *ob, ClothModifierData *clmd, float framenr) fclose(fp); } - implicit_set_positions(clmd); - + if(clmd->sim_parms->solver_type == 0) + implicit_set_positions(clmd); + return ret; } @@ -600,6 +600,7 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd,Object *ob, DerivedMesh *d tstart(); /* Call the solver. */ + if (solvers [clmd->sim_parms->solver_type].solver) solvers [clmd->sim_parms->solver_type].solver (ob, framenr, clmd, effectors); @@ -625,6 +626,10 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd,Object *ob, DerivedMesh *d if(cloth_read_cache(ob, clmd, framenr)) cloth_to_object (ob, result, clmd); } + else + { + cloth_clear_cache(ob, clmd, 0); + } } return result; diff --git a/source/blender/blenkernel/intern/implicit.c b/source/blender/blenkernel/intern/implicit.c index 3b8f6ddd7d8..7d7ad480026 100644 --- a/source/blender/blenkernel/intern/implicit.c +++ b/source/blender/blenkernel/intern/implicit.c @@ -241,7 +241,7 @@ DO_INLINE float dot_lfvector(lfVector *fLongVectorA, lfVector *fLongVectorB, uns unsigned int i = 0; float temp = 0.0; // schedule(guided, 2) -#pragma omp parallel for reduction(+: temp) +#pragma omp parallel for reduction(+: temp) private(i) for(i = 0; i < verts; i++) { temp += INPR(fLongVectorA[i], fLongVectorB[i]); @@ -558,6 +558,7 @@ DO_INLINE void mul_bfmatrix_S(fmatrix3x3 *matrix, float scalar) mul_fmatrix_S(matrix[i].m, scalar); } } + /* SPARSE SYMMETRIC multiply big matrix with long vector*/ /* STATUS: verified */ DO_INLINE void mul_bfmatrix_lfvector( float (*to)[3], fmatrix3x3 *from, lfVector *fLongVector) @@ -590,6 +591,20 @@ DO_INLINE void mul_bfmatrix_lfvector( float (*to)[3], fmatrix3x3 *from, lfVector } + + +/* SPARSE SYMMETRIC multiply big matrix with long vector (for diagonal preconditioner) */ +/* STATUS: verified */ +DO_INLINE void mul_prevfmatrix_lfvector( float (*to)[3], fmatrix3x3 *from, lfVector *fLongVector) +{ + unsigned int i = 0; + + for(i = 0; i < from[0].vcount; i++) + { + mul_fmatrix_fvector(to[from[i].r], from[i].m, fLongVector[from[i].c]); + } +} + /* SPARSE SYMMETRIC add big matrix with big matrix: A = B + C*/ DO_INLINE void add_bfmatrix_bfmatrix( fmatrix3x3 *to, fmatrix3x3 *from, fmatrix3x3 *matrix) { @@ -983,7 +998,7 @@ int cg_filtered_pre(lfVector *dv, fmatrix3x3 *lA, lfVector *lB, lfVector *z, fma sub_lfvector_lfvector(r, lB, r, numverts); filter(r, S); - mul_bfmatrix_lfvector(p, Pinv, r); + mul_prevfmatrix_lfvector(p, Pinv, r); filter(p, S); deltaNew = dot_lfvector(r, p, numverts); @@ -1005,7 +1020,7 @@ int cg_filtered_pre(lfVector *dv, fmatrix3x3 *lA, lfVector *lB, lfVector *z, fma add_lfvector_lfvectorS(r, r, s, -alpha, numverts); - mul_bfmatrix_lfvector(h, Pinv, r); + mul_prevfmatrix_lfvector(h, Pinv, r); filter(h, S); deltaOld = deltaNew; @@ -1013,6 +1028,7 @@ int cg_filtered_pre(lfVector *dv, fmatrix3x3 *lA, lfVector *lB, lfVector *z, fma deltaNew = dot_lfvector(r, h, numverts); add_lfvector_lfvectorS(p, h, p, deltaNew / deltaOld, numverts); + filter(p, S); } @@ -1125,6 +1141,7 @@ DO_INLINE void cloth_calc_spring_force(ClothModifierData *clmd, ClothSpring *s, } + /* if(s->type == CLOTH_SPRING_TYPE_COLLISION) { if(length < L) @@ -1135,6 +1152,7 @@ DO_INLINE void cloth_calc_spring_force(ClothModifierData *clmd, ClothSpring *s, } return; } + */ // calculate force of structural + shear springs if(s->type != CLOTH_SPRING_TYPE_BENDING) @@ -1150,7 +1168,7 @@ DO_INLINE void cloth_calc_spring_force(ClothModifierData *clmd, ClothSpring *s, VECADD(s->f, s->f, stretch_force); // Ascher & Boxman, p.21: Damping only during elonglation - mul_fvector_S(damping_force, extent, clmd->sim_parms->Cdis * ((INPR(vel,extent)/length))); + mul_fvector_S(damping_force, extent, clmd->sim_parms->Cdis * 0.01 * ((INPR(vel,extent)/length))); VECADD(s->f, s->f, damping_force); dfdx_spring_type1(s->dfdx, dir,length,L,k); @@ -1171,12 +1189,17 @@ DO_INLINE void cloth_calc_spring_force(ClothModifierData *clmd, ClothSpring *s, mul_fvector_S(bending_force, dir, fbstar(length, L, k, cb)); VECADD(s->f, s->f, bending_force); - if(INPR(bending_force,bending_force) > 0.13*0.13) + // if(INPR(bending_force,bending_force) > 0.13*0.13) { clmd->sim_parms->flags |= CLOTH_SIMSETTINGS_FLAG_BIG_FORCE; } + dfdx_spring_type2(s->dfdx, dir,length,L,k, cb); + /* + if(s->ij == 300 || s->kl == 300) + printf("id->F[0]: %f, id->F[1]: %f, id->F[2]: %f\n", s->f[0], s->f[1], s->f[2]); + */ } } } @@ -1192,7 +1215,7 @@ DO_INLINE int cloth_apply_spring_force(ClothModifierData *clmd, ClothSpring *s, { sub_fmatrix_fmatrix(dFdV[s->ij].m, dFdV[s->ij].m, s->dfdv); sub_fmatrix_fmatrix(dFdV[s->kl].m, dFdV[s->kl].m, s->dfdv); - add_fmatrix_fmatrix(dFdV[s->matrix_index].m, dFdV[s->matrix_index].m, s->dfdv); + add_fmatrix_fmatrix(dFdV[s->matrix_index].m, dFdV[s->matrix_index].m, s->dfdv); } else if(!(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_BIG_FORCE)) return 0; @@ -1306,7 +1329,7 @@ void cloth_calc_force(ClothModifierData *clmd, lfVector *lF, lfVector *lX, lfVec float speed[3] = {0.0f, 0.0f,0.0f}; float force[3]= {0.0f, 0.0f, 0.0f}; -#pragma omp parallel for private (i) shared(lF) +// #pragma omp parallel for private (i) shared(lF) for(i = 0; i < cloth->numverts; i++) { float vertexnormal[3]={0,0,0}; @@ -1363,7 +1386,6 @@ void cloth_calc_force(ClothModifierData *clmd, lfVector *lF, lfVector *lX, lfVec } clmd->sim_parms->flags &= ~CLOTH_SIMSETTINGS_FLAG_BIG_FORCE; - } void simulate_implicit_euler(lfVector *Vnew, lfVector *lX, lfVector *lV, lfVector *lF, fmatrix3x3 *dFdV, fmatrix3x3 *dFdX, float dt, fmatrix3x3 *A, lfVector *B, lfVector *dV, fmatrix3x3 *S, lfVector *z, fmatrix3x3 *P, fmatrix3x3 *Pinv) @@ -1375,31 +1397,23 @@ void simulate_implicit_euler(lfVector *Vnew, lfVector *lX, lfVector *lV, lfVecto zero_lfvector(dV, numverts); subadd_bfmatrixS_bfmatrixS(A, dFdV, dt, dFdX, (dt*dt)); - mul_bfmatrix_lfvector(dFdXmV, dFdX, lV); - add_lfvectorS_lfvectorS(B, lF, dt, dFdXmV, (dt*dt), numverts); - // itstart(); - + // TODO: unstable with quality=5 + stiffness=7000 + no zero_lfvector() cg_filtered(dV, A, B, z, S); /* conjugate gradient algorithm to solve Ax=b */ - // TODO: if anyone finds a way to correct this function => - // explodes with stiffness = 3000 and 16k verts + pinned at 2 corners + // TODO: unstable with quality=5 + stiffness=7000 // cg_filtered_pre(dV, A, B, z, S, P, Pinv); - // itend(); - // printf("cg_filtered calc time: %f\n", (float)itval()); - // advance velocities add_lfvector_lfvector(Vnew, lV, dV, numverts); - del_lfvector(dFdXmV); } int implicit_solver (Object *ob, float frame, ClothModifierData *clmd, ListBase *effectors) -{ +{ unsigned int i=0; float step=0.0f, tf=1.0f; Cloth *cloth = clmd->clothObject; @@ -1418,7 +1432,10 @@ int implicit_solver (Object *ob, float frame, ClothModifierData *clmd, ListBase // update velocities with constrained velocities from pinned verts if(verts [i].goal >= SOFTGOALSNAP) { - VECSUB(id->V[i], cloth->xconst[i], cloth->xold[i]); + float temp[3]; + VECSUB(temp, cloth->xconst[i], cloth->xold[i]); + VECSUB(id->z[i], temp, id->V[i]); + // VecMulf(id->V[i], 1.0 / dt); } } @@ -1612,6 +1629,8 @@ int collisions_collision_response_static ( ClothModifierData *clmd, CollisionMod float v1[3], v2[3], relativeVelocity[3]; float magrelVel = 0.0; float epsilon = clmd->coll_parms->epsilon; + + return 0; cloth1 = clmd->clothObject; @@ -2143,7 +2162,7 @@ int cloth_bvh_objcollision(ClothModifierData * clmd, float step, float prevstep, int collisions = 0, count = 0; float (*current_x)[3]; Implicit_Data *id = NULL; - /* + if (!(((Cloth *)clmd->clothObject)->tree)) { printf("No BVH found\n"); @@ -2182,7 +2201,7 @@ int cloth_bvh_objcollision(ClothModifierData * clmd, float step, float prevstep, // fill collision list collisions += bvh_traverse ( bvh1->root, bvh2->root, &collision_list ); - + // call static collision response if ( collision_list ) { @@ -2223,7 +2242,7 @@ int cloth_bvh_objcollision(ClothModifierData * clmd, float step, float prevstep, VECADD(cloth->current_x[i], cloth->current_xold[i], cloth->current_v[i]); } ////////////////////////////////////////////// - */ + /* // fill collision list collisions += bvh_traverse(self_bvh->root, self_bvh->root, &collision_list); diff --git a/source/blender/blenkernel/intern/key.c b/source/blender/blenkernel/intern/key.c index 234a096edce..b57b799001a 100644 --- a/source/blender/blenkernel/intern/key.c +++ b/source/blender/blenkernel/intern/key.c @@ -672,14 +672,12 @@ static void do_rel_key(int start, int end, int tot, char *basispoin, Key *key, i /* step 2: do it */ - kb= key->block.first; - while(kb) { - + for(kb=key->block.first; kb; kb=kb->next) { if(kb!=key->refkey) { float icuval= kb->curval; /* only with value, and no difference allowed */ - if(icuval!=0.0f && kb->totelem==tot) { + if(!(kb->flag & KEYBLOCK_MUTE) && icuval!=0.0f && kb->totelem==tot) { KeyBlock *refb; float weight, *weights= kb->weights; @@ -738,7 +736,6 @@ static void do_rel_key(int start, int end, int tot, char *basispoin, Key *key, i } } } - kb= kb->next; } } @@ -1312,6 +1309,9 @@ int do_ob_key(Object *ob) if(ob->shapeflag & (OB_SHAPE_LOCK|OB_SHAPE_TEMPLOCK)) { KeyBlock *kb= BLI_findlink(&key->block, ob->shapenr-1); + if(kb && (kb->flag & KEYBLOCK_MUTE)) + kb= key->refkey; + if(kb==NULL) { kb= key->block.first; ob->shapenr= 1; diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c index 5d3a4332b5d..1c7d235cd90 100644 --- a/source/blender/blenkernel/intern/particle_system.c +++ b/source/blender/blenkernel/intern/particle_system.c @@ -4271,7 +4271,7 @@ void psys_to_softbody(Object *ob, ParticleSystem *psys, int force_recalc) if((psys->softflag&OB_SB_ENABLE)==0) return; - if((ob->recalc&OB_RECALC_TIME)==0) + if(ob->recalc && (ob->recalc&OB_RECALC_TIME)==0) psys->softflag|=OB_SB_REDO; /* let's replace the object's own softbody with the particle softbody */ diff --git a/source/blender/blenkernel/intern/pointcache.c b/source/blender/blenkernel/intern/pointcache.c index 9492754260c..c4ef437019e 100644 --- a/source/blender/blenkernel/intern/pointcache.c +++ b/source/blender/blenkernel/intern/pointcache.c @@ -183,3 +183,11 @@ void BKE_ptcache_id_clear(struct ID *id, char mode, int cfra, int stack_index) return; } +int BKE_ptcache_id_exist(struct ID *id, int cfra, int stack_index) +{ + char filename[(FILE_MAXDIR+FILE_MAXFILE)*2]; + + BKE_ptcache_id_filename(id, filename, cfra, stack_index, 1, 1); + + return BLI_exists(filename); +} diff --git a/source/blender/makesdna/DNA_key_types.h b/source/blender/makesdna/DNA_key_types.h index 785cf515a42..87c09fb0ee4 100644 --- a/source/blender/makesdna/DNA_key_types.h +++ b/source/blender/makesdna/DNA_key_types.h @@ -44,7 +44,7 @@ typedef struct KeyBlock { float pos; float curval; - short type, adrcode, relative, pad1; /* relative == 0 means first key is reference */ + short type, adrcode, relative, flag; /* relative == 0 means first key is reference */ int totelem, pad2; void *data; @@ -87,5 +87,8 @@ typedef struct Key { #define KEY_CARDINAL 1 #define KEY_BSPLINE 2 +/* keyblock->flag */ +#define KEYBLOCK_MUTE 1 + #endif diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_normalize.c b/source/blender/nodes/intern/CMP_nodes/CMP_normalize.c index a62e4be4015..7f76cb40948 100644 --- a/source/blender/nodes/intern/CMP_nodes/CMP_normalize.c +++ b/source/blender/nodes/intern/CMP_nodes/CMP_normalize.c @@ -85,8 +85,11 @@ static void node_composit_exec_normalize(void *data, bNode *node, bNodeStack **i min = *val; } } + min = MIN2(0.1, min); + max = MAX2(0.9, max); + mult = 1.0f/(max-min); - + printf("min %f max %f\n", min, max); composit3_pixel_processor(node, stackbuf, in[0]->data, in[0]->vec, NULL, &min, NULL, &mult, do_normalize, CB_VAL, CB_VAL, CB_VAL); diff --git a/source/blender/src/buttons_editing.c b/source/blender/src/buttons_editing.c index 9ffb7578980..05fed2f8fbc 100644 --- a/source/blender/src/buttons_editing.c +++ b/source/blender/src/buttons_editing.c @@ -410,7 +410,6 @@ void do_common_editbuts(unsigned short event) // old name, is a mix of object an return; } } - efa= efa->next; } } else if ELEM(G.obedit->type, OB_CURVE, OB_SURF) { @@ -484,7 +483,7 @@ void do_common_editbuts(unsigned short event) // old name, is a mix of object an if(ma) { ob->actcol= find_material_index(ob, ma); if(ob->actcol==0) { - assign_material(ob, ma, ob->totcol); + assign_material(ob, ma, ob->totcol+1); ob->actcol= ob->totcol; } } @@ -2474,15 +2473,17 @@ static void editing_panel_shapes(Object *ob) uiBlockBeginAlign(block); if(ob->shapeflag & OB_SHAPE_LOCK) icon= ICON_PIN_HLT; else icon= ICON_PIN_DEHLT; uiDefIconButBitS(block, TOG, OB_SHAPE_LOCK, B_LOCKKEY, icon, 10,150,25,20, &ob->shapeflag, 0, 0, 0, 0, "Always show the current Shape for this Object"); + if(kb->flag & KEYBLOCK_MUTE) icon= ICON_MUTE_IPO_ON; else icon = ICON_MUTE_IPO_OFF; + uiDefIconButBitS(block, TOG, KEYBLOCK_MUTE, B_MODIFIER_RECALC, icon, 35,150,20,20, &kb->flag, 0, 0, 0, 0, "Mute the current Shape"); uiSetButLock(G.obedit==ob, "Unable to perform in EditMode"); - uiDefIconBut(block, BUT, B_PREVKEY, ICON_TRIA_LEFT, 35,150,20,20, NULL, 0, 0, 0, 0, "Previous Shape Key"); + uiDefIconBut(block, BUT, B_PREVKEY, ICON_TRIA_LEFT, 55,150,20,20, NULL, 0, 0, 0, 0, "Previous Shape Key"); strp= make_key_menu(key, 1); - uiDefButS(block, MENU, B_SETKEY, strp, 55,150,20,20, &ob->shapenr, 0, 0, 0, 0, "Browse existing choices"); + uiDefButS(block, MENU, B_SETKEY, strp, 75,150,20,20, &ob->shapenr, 0, 0, 0, 0, "Browse existing choices"); MEM_freeN(strp); - uiDefIconBut(block, BUT, B_NEXTKEY, ICON_TRIA_RIGHT, 75,150,20,20, NULL, 0, 0, 0, 0, "Next Shape Key"); + uiDefIconBut(block, BUT, B_NEXTKEY, ICON_TRIA_RIGHT, 95,150,20,20, NULL, 0, 0, 0, 0, "Next Shape Key"); uiClearButLock(); - uiDefBut(block, TEX, B_NAMEKEY, "", 95, 150, 190, 20, kb->name, 0.0, 31.0, 0, 0, "Current Shape Key name"); + uiDefBut(block, TEX, B_NAMEKEY, "", 115, 150, 170, 20, kb->name, 0.0, 31.0, 0, 0, "Current Shape Key name"); uiDefIconBut(block, BUT, B_DELKEY, ICON_X, 285,150,25,20, 0, 0, 0, 0, 0, "Deletes current Shape Key"); uiBlockEndAlign(block); diff --git a/source/blender/src/buttons_object.c b/source/blender/src/buttons_object.c index e7a2a654ba1..3360dab61f8 100644 --- a/source/blender/src/buttons_object.c +++ b/source/blender/src/buttons_object.c @@ -3298,6 +3298,7 @@ static void object_softbodies__enable(void *ob_v, void *arg2) if (!ob->soft) { ob->soft= sbNew(); ob->softflag |= OB_SB_GOAL|OB_SB_EDGES; + softbody_clear_cache(ob, CFRA); } } /* needed so that initial state is cached correctly */ @@ -3331,6 +3332,7 @@ static void object_softbodies__enable_psys(void *ob_v, void *psys_v) psys->soft= sbNew(); psys->softflag |= OB_SB_GOAL|OB_SB_EDGES; psys->soft->particles=psys; + clear_particles_from_cache(ob, psys, CFRA); } psys->softflag |= OB_SB_ENABLE; } diff --git a/source/blender/src/drawview.c b/source/blender/src/drawview.c index 14690b08d48..93915a0e92e 100644 --- a/source/blender/src/drawview.c +++ b/source/blender/src/drawview.c @@ -70,6 +70,8 @@ #include "DNA_mesh_types.h" #include "DNA_meshdata_types.h" #include "DNA_meta_types.h" +#include "DNA_modifier_types.h" +#include "DNA_object_force.h" #include "DNA_object_types.h" #include "DNA_particle_types.h" #include "DNA_screen_types.h" @@ -101,8 +103,10 @@ #include "BKE_key.h" #include "BKE_main.h" #include "BKE_mesh.h" +#include "BKE_modifier.h" #include "BKE_object.h" #include "BKE_particle.h" +#include "BKE_pointcache.h" #include "BKE_scene.h" #include "BKE_texture.h" #include "BKE_utildefines.h" @@ -3292,10 +3296,50 @@ static void inner_play_prefetch_shutdown(int mode) seq_stop_threads(); } +static int cached_dynamics(int sfra, int efra) +{ + Base *base = G.scene->base.first; + Object *ob; + ModifierData *md; + ParticleSystem *psys; + int i, stack_index, cached=1; + + while(base && cached) { + ob = base->object; + if(ob->softflag & OB_SB_ENABLE && ob->soft) { + for(i=0, md=ob->modifiers.first; md; i++, md=md->next) { + if(md->type == eModifierType_Softbody) { + stack_index = i; + break; + } + } + for(i=sfra; i<=efra && cached; i++) + cached &= BKE_ptcache_id_exist(&ob->id,i,stack_index); + } + + for(psys=ob->particlesystem.first; psys; psys=psys->next) { + stack_index = modifiers_indexInObject(ob,(ModifierData*)psys_get_modifier(ob,psys)); + if(psys->part->type==PART_HAIR) { + if(psys->softflag & OB_SB_ENABLE && psys->soft); + else + stack_index = -1; + } + + if(stack_index >= 0) + for(i=sfra; i<=efra && cached; i++) + cached &= BKE_ptcache_id_exist(&ob->id,i,stack_index); + } + + base = base->next; + } + + return cached; +} void inner_play_anim_loop(int init, int mode) { ScrArea *sa; static int last_cfra = -1; + static int cached = 0; /* init */ if(init) { @@ -3304,7 +3348,7 @@ void inner_play_anim_loop(int init, int mode) tottime= 0.0; curmode= mode; last_cfra = -1; - + cached = cached_dynamics(PSFRA,PEFRA); return; } @@ -3328,7 +3372,7 @@ void inner_play_anim_loop(int init, int mode) if (sa->spacetype == SPACE_SEQ) { scrarea_do_windraw(sa); } - } + } sa= sa->next; } @@ -3380,8 +3424,10 @@ void inner_play_anim_loop(int init, int mode) CFRA = PSFRA; audiostream_stop(); audiostream_start( CFRA ); + cached = cached_dynamics(PSFRA,PEFRA); } else { - if (U.mixbufsize + if (cached + && U.mixbufsize && (G.scene->audio.flag & AUDIO_SYNC)) { CFRA = audiostream_pos(); } else { diff --git a/source/blender/src/editkey.c b/source/blender/src/editkey.c index 0d861cda5d0..5cc193f8844 100644 --- a/source/blender/src/editkey.c +++ b/source/blender/src/editkey.c @@ -625,7 +625,7 @@ void insert_shapekey(Object *ob) void delete_key(Object *ob) { - KeyBlock *kb; + KeyBlock *kb, *rkb; Key *key; IpoCurve *icu; @@ -635,6 +635,10 @@ void delete_key(Object *ob) kb= BLI_findlink(&key->block, ob->shapenr-1); if(kb) { + for(rkb= key->block.first; rkb; rkb= rkb->next) + if(rkb->relative == ob->shapenr-1) + rkb->relative= 0; + BLI_remlink(&key->block, kb); key->totkey--; if(key->refkey== kb) key->refkey= key->block.first; diff --git a/source/blender/src/editmesh_mods.c b/source/blender/src/editmesh_mods.c index ae10cef0879..a74bd851aeb 100644 --- a/source/blender/src/editmesh_mods.c +++ b/source/blender/src/editmesh_mods.c @@ -82,6 +82,7 @@ editmesh_mods.c, UI level access, no geometry changes #include "BIF_interface.h" #include "BIF_meshtools.h" #include "BIF_mywindow.h" +#include "BIF_previewrender.h" #include "BIF_resources.h" #include "BIF_screen.h" #include "BIF_space.h" @@ -2126,6 +2127,12 @@ void mouse_mesh(void) allqueue(REDRAWIMAGE, 0); allqueue(REDRAWBUTSEDIT, 0); /* for the texture face panel */ } + if (efa && efa->mat_nr != G.obedit->actcol-1) { + G.obedit->actcol= efa->mat_nr+1; + allqueue(REDRAWBUTSEDIT, 0); + allqueue(REDRAWBUTSSHADING, 0); + BIF_preview_changed(ID_MA); + } } rightmouse_transform(); diff --git a/source/blender/src/editparticle.c b/source/blender/src/editparticle.c index e08ca3279d6..c9cf745fa44 100644 --- a/source/blender/src/editparticle.c +++ b/source/blender/src/editparticle.c @@ -1703,10 +1703,10 @@ static int remove_tagged_elements(Object *ob, ParticleSystem *psys) } } - MEM_freeN(psys->particles); + if(psys->particles) MEM_freeN(psys->particles); psys->particles = new_pars; - MEM_freeN(edit->keys); + if(edit->keys) MEM_freeN(edit->keys); edit->keys = new_keys; if(edit->mirror_cache) { @@ -2256,10 +2256,10 @@ static void brush_add(Object *ob, ParticleSystem *psys, short *mval, short numbe memcpy(new_keys, edit->keys, totpart * sizeof(ParticleEditKey*)); /* change old arrays to new ones */ - MEM_freeN(psys->particles); + if(psys->particles) MEM_freeN(psys->particles); psys->particles = new_pars; - MEM_freeN(edit->keys); + if(edit->keys) MEM_freeN(edit->keys); edit->keys = new_keys; if(edit->mirror_cache) { @@ -2267,8 +2267,6 @@ static void brush_add(Object *ob, ParticleSystem *psys, short *mval, short numbe edit->mirror_cache = NULL; } - psys->totpart = newtotpart; - /* create tree for interpolation */ if(pset->flag & PE_INTERPOLATE_ADDED && psys->totpart){ tree=BLI_kdtree_new(psys->totpart); @@ -2281,6 +2279,8 @@ static void brush_add(Object *ob, ParticleSystem *psys, short *mval, short numbe BLI_kdtree_balance(tree); } + psys->totpart = newtotpart; + /* create new elements */ pa = psys->particles + totpart; key = edit->keys + totpart; @@ -2691,10 +2691,10 @@ void PE_mirror_x(int tagged) memcpy(new_pars, psys->particles, totpart*sizeof(ParticleData)); memcpy(new_keys, edit->keys, totpart*sizeof(ParticleEditKey*)); - MEM_freeN(psys->particles); + if(psys->particles) MEM_freeN(psys->particles); psys->particles= new_pars; - MEM_freeN(edit->keys); + if(edit->keys) MEM_freeN(edit->keys); edit->keys= new_keys; if(edit->mirror_cache) { From 3bf1536f5ed210fb8832f782999ca6a072a6a3c6 Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Tue, 18 Dec 2007 16:54:12 +0000 Subject: [PATCH 067/246] Some User UI changes: a) Don't ask the user anymore if he wants to overwrite the file when he's doing a simple ctrl-s/ctrl-w; b) Ask for saving on exit when a file has changed, ontheless quit.blend is saved anyway. --> All branch changes, not likely to go into trunk --- source/blender/blenkernel/BKE_blender.h | 1 + source/blender/blenkernel/BKE_cloth.h | 14 + source/blender/blenkernel/intern/blender.c | 7 +- source/blender/blenkernel/intern/cloth.c | 698 ++- source/blender/blenkernel/intern/implicit.c | 102 +- source/blender/blenkernel/intern/kdop.c | 1 + source/blender/blenkernel/intern/modifier.c | 2 + source/blender/makesdna/DNA_userdef_types.h | 1 + source/blender/src/blenderbuttons.c | 4737 +++++++++++-------- source/blender/src/header_info.c | 3 +- source/blender/src/toets.c | 4 + source/blender/src/toolbox.c | 22 + source/blender/src/usiblender.c | 52 +- 13 files changed, 3551 insertions(+), 2093 deletions(-) diff --git a/source/blender/blenkernel/BKE_blender.h b/source/blender/blenkernel/BKE_blender.h index 243425db139..84ebd3102b3 100644 --- a/source/blender/blenkernel/BKE_blender.h +++ b/source/blender/blenkernel/BKE_blender.h @@ -70,6 +70,7 @@ extern void BKE_reset_undo(void); extern char *BKE_undo_menu_string(void); extern void BKE_undo_number(int nr); extern void BKE_undo_save_quit(void); +extern int BKE_undo_there(void); #ifdef __cplusplus } diff --git a/source/blender/blenkernel/BKE_cloth.h b/source/blender/blenkernel/BKE_cloth.h index e288e7ee082..d888ba28ebe 100644 --- a/source/blender/blenkernel/BKE_cloth.h +++ b/source/blender/blenkernel/BKE_cloth.h @@ -60,6 +60,18 @@ struct ClothModifierData; #define CLOTH_MAX_THREAD 2 +typedef struct fc +{ + float *d, *d0; // density + float *T, *T0; // temperature + float *u, *u0; // velocity in x direction + float *v, *v0; // velocity in y direction + float *w, *w0; // velocity in z direction +} fc; +fc *f_init(void); +void f_free(fc *m_fc); +void step(fc *m_fc, float dt); + typedef struct ClothVertex { int flags; /* General flags per vertex. */ @@ -69,6 +81,7 @@ typedef struct ClothVertex { unsigned int impulse_count; /* same as above */ float collball; char octantflag; + float weight; } ClothVertex; typedef struct ClothSpring { @@ -104,6 +117,7 @@ typedef struct Cloth { float (*v)[4]; /* the current velocity of all vertices */ float (*current_v)[3]; float (*xconst)[3]; + struct fc *m_fc; } Cloth; /* goal defines */ diff --git a/source/blender/blenkernel/intern/blender.c b/source/blender/blenkernel/intern/blender.c index 9845f571126..13b48559f75 100644 --- a/source/blender/blenkernel/intern/blender.c +++ b/source/blender/blenkernel/intern/blender.c @@ -85,6 +85,7 @@ #include "BKE_bad_level_calls.h" // for freeAllRad editNurb free_editMesh free_editText free_editArmature #include "BKE_utildefines.h" // O_BINARY FALSE #include "BIF_mainqueue.h" // mainqenter for onload script +#include "BIF_toolbox.h" #include "mydevice.h" #include "nla.h" #include "blendef.h" @@ -617,6 +618,10 @@ void BKE_write_undo(char *name) success= BLO_write_file_mem(prevfile, &curundo->memfile, G.fileflags, &err); } + + /* signals "file needs save" on exit */ + if(curundo!=NULL && curundo->prev!=NULL) + U.uiflag |= USER_UNDOSAVE; } /* 1= an undo, -1 is a redo. we have to make sure 'curundo' remains at current situation */ @@ -694,7 +699,7 @@ char *BKE_undo_menu_string(void) return menu; } - /* saves quit.blend */ +/* saves quit.blend */ void BKE_undo_save_quit(void) { UndoElem *uel; diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c index 64166493caa..95d487b2ec7 100644 --- a/source/blender/blenkernel/intern/cloth.c +++ b/source/blender/blenkernel/intern/cloth.c @@ -78,6 +78,22 @@ #include "BIF_space.h" #include "mydevice.h" +#ifdef WIN32 +#include +#endif // WIN32 +#ifdef __APPLE__ +#define GL_GLEXT_LEGACY 1 +#include +#include +#else +#include +#if defined(__sun__) && !defined(__sparc__) +#include +#else +#include +#endif +#endif + #ifdef _WIN32 void tstart ( void ) {} @@ -482,6 +498,309 @@ static int cloth_read_cache(Object *ob, ClothModifierData *clmd, float framenr) return ret; } +#define AMBIENT 50 +#define DECAY 0.04f +#define ALMOST_EQUAL(a, b) ((fabs(a-b)<0.00001f)?1:0) + + // cube vertices +GLfloat cv[][3] = { + {1.0f, 1.0f, 1.0f}, {-1.0f, 1.0f, 1.0f}, {-1.0f, -1.0f, 1.0f}, {1.0f, -1.0f, 1.0f}, + {1.0f, 1.0f, -1.0f}, {-1.0f, 1.0f, -1.0f}, {-1.0f, -1.0f, -1.0f}, {1.0f, -1.0f, -1.0f} +}; + + // edges have the form edges[n][0][xyz] + t*edges[n][1][xyz] +float edges[12][2][3] = { + {{1.0f, 1.0f, -1.0f}, {0.0f, 0.0f, 1.0f}}, + {{-1.0f, 1.0f, -1.0f}, {0.0f, 0.0f, 1.0f}}, + {{-1.0f, -1.0f, -1.0f}, {0.0f, 0.0f, 1.0f}}, + {{1.0f, -1.0f, -1.0f}, {0.0f, 0.0f, 1.0f}}, + + {{1.0f, -1.0f, 1.0f}, {0.0f, 1.0f, 0.0f}}, + {{-1.0f, -1.0f, 1.0f}, {0.0f, 1.0f, 0.0f}}, + {{-1.0f, -1.0f, -1.0f}, {0.0f, 1.0f, 0.0f}}, + {{1.0f, -1.0f, -1.0f}, {0.0f, 1.0f, 0.0f}}, + + {{-1.0f, 1.0f, 1.0f}, {1.0f, 0.0f, 0.0f}}, + {{-1.0f, -1.0f, 1.0f}, {1.0f, 0.0f, 0.0f}}, + {{-1.0f, -1.0f, -1.0f}, {1.0f, 0.0f, 0.0f}}, + {{-1.0f, 1.0f, -1.0f}, {1.0f, 0.0f, 0.0f}} +}; + +void light_ray(unsigned char* _texture_data, int _ray_templ[4096][3], int x, int y, int z, int n, float decay) +{ + int xx = x, yy = y, zz = z, i = 0; + int offset; + + int l = 255; + float d; + + do { + offset = ((((zz*n) + yy)*n + xx) << 2); + if (_texture_data[offset + 2] > 0) + _texture_data[offset + 2] = (unsigned char) ((_texture_data[offset + 2] + l)*0.5f); + else + _texture_data[offset + 2] = (unsigned char) l; + d = _texture_data[offset+1]; + if (l > AMBIENT) { + l -= d*decay; + if (l < AMBIENT) + l = AMBIENT; + } + + i++; + xx = x + _ray_templ[i][0]; + yy = y + _ray_templ[i][1]; + zz = z + _ray_templ[i][2]; + + } while ((xx>=0)&&(xx=0)&&(yy=0)&&(zz0) ? 0 : n-1; + int sy = (_light_dir[1]>0) ? 0 : n-1; + int sz = (_light_dir[2]>0) ? 0 : n-1; + + float decay = 1.0f/(n*DECAY); + + for (i=0; i 0) ? 1 : -1; + int yinc = (ly > 0) ? 1 : -1; + int zinc = (lz > 0) ? 1 : -1; + float tx, ty, tz; + int i = 1; + int len = 0; + int maxlen = 3*edgelen*edgelen; + _ray_templ[0][0] = _ray_templ[0][2] = _ray_templ[0][2] = 0; + + while (len <= maxlen) + { + // fx + t*lx = (x+1) -> t = (x+1-fx)/lx + tx = (x+xinc-fx)/lx; + ty = (y+yinc-fy)/ly; + tz = (z+zinc-fz)/lz; + + if ((tx<=ty)&&(tx<=tz)) { + _ray_templ[i][0] = _ray_templ[i-1][0] + xinc; + x =+ xinc; + fx = x; + + if (ALMOST_EQUAL(ty,tx)) { + _ray_templ[i][1] = _ray_templ[i-1][1] + yinc; + y += yinc; + fy = y; + } else { + _ray_templ[i][1] = _ray_templ[i-1][1]; + fy += tx*ly; + } + + if (ALMOST_EQUAL(tz,tx)) { + _ray_templ[i][2] = _ray_templ[i-1][2] + zinc; + z += zinc; + fz = z; + } else { + _ray_templ[i][2] = _ray_templ[i-1][2]; + fz += tx*lz; + } + } else if ((ty0)&&(t<2)) { + ret[num][0] = edges[i][0][0] + edges[i][1][0]*t; + ret[num][1] = edges[i][0][1] + edges[i][1][1]*t; + ret[num][2] = edges[i][0][2] + edges[i][1][2]*t; + num++; + } + } + + return num; +} + +void draw_slices(float m[][4]) +{ + int i; + + Vec3 viewdir(m[0][2], m[1][2], m[2][2]); + viewdir.Normalize(); + // find cube vertex that is closest to the viewer + for (i=0; i<8; i++) { + float x = cv[i][0] + viewdir[0]; + float y = cv[i][1] + viewdir[1]; + float z = cv[i][2] + viewdir[2]; + if ((x>=-1.0f)&&(x<=1.0f) + &&(y>=-1.0f)&&(y<=1.0f) + &&(z>=-1.0f)&&(z<=1.0f)) + { + break; + } + } + if(i != 8) return; + + glBlendFunc(GL_SRC_ALPHA, GL_ONE); + glDisable(GL_DEPTH_TEST); + // our slices are defined by the plane equation a*x + b*y +c*z + d = 0 + // (a,b,c), the plane normal, are given by viewdir + // d is the parameter along the view direction. the first d is given by + // inserting previously found vertex into the plane equation + float d0 = -(viewdir[0]*cv[i][0] + viewdir[1]*cv[i][1] + viewdir[2]*cv[i][2]); + float dd = 2*d0/64.0f; + int n = 0; + for (float d = -d0; d < d0; d += dd) { + // intersect_edges returns the intersection points of all cube edges with + // the given plane that lie within the cube + float pt[12][3]; + int num = intersect_edges(pt, viewdir[0], viewdir[1], viewdir[2], d); + + if (num > 2) { + // sort points to get a convex polygon + // std::sort(pt.begin()+1, pt.end(), Convexcomp(pt[0], viewdir)); + int shuffled = 1; + + while(shuffled) + { + int j; + shuffled = 0; + + for(j = 0; j < num-1; j++) + { + // Vec3 va = a-p0, vb = b-p0; + // return dot(up, cross(va, vb)) >= 0; + float va[3], vb[3], vc[3]; + + VECSUB(va, pt[j], pt[0]); + VECSUB(vb, pt[j+1], pt[0]); + Crossf(vc, va, vb); + + if(INPR(viewdir, vc)>= 0) + { + float temp[3]; + + VECCOPY(temp, pt[j]); + VECCOPY(pt[j], pt[j+1]); + VECCOPY(pt[j+1], temp); + + shuffled = 1; + } + } + } + + glEnable(GL_TEXTURE_3D); + glEnable(GL_FRAGMENT_PROGRAM_ARB); + glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, _prog[0]); + glActiveTextureARB(GL_TEXTURE0_ARB); + glBindTexture(GL_TEXTURE_3D, _txt[0]); + glBegin(GL_POLYGON); + for (i=0; ir.cfra; float current_time = bsystem_time(ob, (float)G.scene->r.cfra, 0.0); ListBase *effectors = NULL; - float deltaTime = current_time - clmd->sim_parms->sim_time; + float deltaTime = current_time - clmd->sim_parms->sim_time; + unsigned char* _texture_data=NULL; + float _light_dir[3]; + int _ray_templ[4096][3]; clmd->sim_parms->dt = 1.0f / (clmd->sim_parms->stepsPerFrame * G.scene->r.frs_sec); @@ -577,7 +899,14 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd,Object *ob, DerivedMesh *d cloth = clmd->clothObject; } - + /* + deltaTime = 0; + while( deltaTime < 1.0) + { + step(cloth->m_fc, 0.1); + deltaTime+=0.1; + } + */ clmd->clothObject->old_solver_type = clmd->sim_parms->solver_type; // Insure we have a clmd->clothObject, in case allocation failed. @@ -632,6 +961,34 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd,Object *ob, DerivedMesh *d } } + cloth = clmd->clothObject; + /* + if(cloth) + { + if (_texture_data == NULL) + _texture_data = (unsigned char*) malloc((30+2)*(30+2)*(30+2)*4); + + for (i=0; i<(30+2)*(30+2)*(30+2); i++) { + _texture_data[(i<<2)] = (unsigned char) (cloth->m_fc->T[i] * 255.0f); + _texture_data[(i<<2)+1] = (unsigned char) (cloth->m_fc->d[i] * 255.0f); + _texture_data[(i<<2)+2] = 0; + _texture_data[(i<<2)+3] = 255; + } + + // from ligth constructor + _light_dir[0] = -1.0f; + _light_dir[1] = 0.5f; + _light_dir[2] = 0.0f; + + gen_ray_templ(_ray_templ, _light_dir, 30 + 2); + + cast_light(_texture_data, _ray_templ, _light_dir, 30+2); + + glActiveTextureARB(GL_TEXTURE0_ARB); + glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA, 30+2, 30+2, 30+2, 0, GL_RGBA, GL_UNSIGNED_BYTE, _texture_data); + free(_texture_data); + } + */ return result; } @@ -653,6 +1010,8 @@ void cloth_free_modifier (ClothModifierData *clmd) if (cloth) { + f_free(cloth->m_fc); + // If our solver provides a free function, call it if (cloth->old_solver_type < 255 && solvers [cloth->old_solver_type].free) { @@ -834,6 +1193,7 @@ static int cloth_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *d unsigned int numverts = dm->getNumVerts(dm); MVert *mvert = CDDM_get_verts(dm); float tnull[3] = {0,0,0}; + Cloth *cloth = NULL; /* If we have a clothObject, free it. */ if (clmd->clothObject != NULL) @@ -851,6 +1211,10 @@ static int cloth_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *d modifier_setError (&(clmd->modifier), "Out of memory on allocating clmd->clothObject."); return 0; } + + cloth = clmd->clothObject; + + cloth->m_fc = f_init(); switch (ob->type) { @@ -1228,3 +1592,333 @@ int cloth_build_springs ( ClothModifierData *clmd, DerivedMesh *dm ) * SPRING NETWORK BUILDING IMPLEMENTATION END ***************************************************************************************/ +#define F_ITER 20 +#define m_diffusion 0.00001f +#define m_viscosity 0.000f +#define m_buoyancy 1.5f +#define m_cooling 1.0f +#define m_vc_eps 4.0f + +#define GRID_SIZE 30 +#define SIZE ((GRID_SIZE+2)*(GRID_SIZE+2)*(GRID_SIZE+2)) +#define _I(x,y,z) (((z)<<10)+((y)<<5)+x) + +#define SWAPFPTR(x,y) {float *t=x;x=y;y=t;} + +float buffers[10][SIZE]; +float sd[SIZE], su[SIZE], sv[SIZE], sw[SIZE], sT[SIZE]; + + +// nothing to do in this mode +// add code for 2nd mode +void set_bnd(int b, float* x, int N) +{ +} + +void lin_solve(int b, float *x, float *x0, float a, float c, int N) +{ + float cRecip = 1.0 / c; + int i, j, k, l; + for (l=0; lN+0.5) xx=N+0.5f; i0=(int)xx; i1=i0+1; + if (yy<0.5) yy=0.5f; if (yy>N+0.5) yy=N+0.5f; j0=(int)yy; j1=j0+1; + if (zz<0.5) zz=0.5f; if (zz>N+0.5) zz=N+0.5f; k0=(int)zz; k1=k0+1; + sx1 = xx-i0; sx0 = 1-sx1; + sy1 = yy-j0; sy0 = 1-sy1; + sz1 = zz-k0; sz0 = 1-sz1; + v0 = sx0*(sy0*x0[_I(i0,j0,k0)]+sy1*x0[_I(i0,j1,k0)])+sx1*(sy0*x0[_I(i1,j0,k0)]+sy1*x0[_I(i1,j1,k0)]); + v1 = sx0*(sy0*x0[_I(i0,j0,k1)]+sy1*x0[_I(i0,j1,k1)])+sx1*(sy0*x0[_I(i1,j0,k1)]+sy1*x0[_I(i1,j1,k1)]); + x[_I(i,j,k)] = sz0*v0 + sz1*v1; + } + } + } + set_bnd(b,x, N); +} + +void advect_cool(int b, float* x0, float* x, float* y0, float* y, float* uu, float* vv, float* ww, float dt, float cooling, int N) +{ + int i, j, k, i0, j0, k0, i1, j1, k1; + float sx0, sx1, sy0, sy1, sz0, sz1, v0, v1; + float xx, yy, zz, dt0, c0; + dt0 = dt*N; + c0 = 1.0f - cooling*dt; + for (k=1; k<=N; k++) + { + for (j=1; j<=N; j++) + { + for (i=1; i<=N; i++) + { + xx = i-dt0*uu[_I(i,j,k)]; + yy = j-dt0*vv[_I(i,j,k)]; + zz = k-dt0*ww[_I(i,j,k)]; + if (xx<0.5) xx=0.5f; if (xx>N+0.5) xx=N+0.5f; i0=(int)xx; i1=i0+1; + if (yy<0.5) yy=0.5f; if (yy>N+0.5) yy=N+0.5f; j0=(int)yy; j1=j0+1; + if (zz<0.5) zz=0.5f; if (zz>N+0.5) zz=N+0.5f; k0=(int)zz; k1=k0+1; + sx1 = xx-i0; sx0 = 1-sx1; + sy1 = yy-j0; sy0 = 1-sy1; + sz1 = zz-k0; sz0 = 1-sz1; + v0 = sx0*(sy0*x0[_I(i0,j0,k0)]+sy1*x0[_I(i0,j1,k0)])+sx1*(sy0*x0[_I(i1,j0,k0)]+sy1*x0[_I(i1,j1,k0)]); + v1 = sx0*(sy0*x0[_I(i0,j0,k1)]+sy1*x0[_I(i0,j1,k1)])+sx1*(sy0*x0[_I(i1,j0,k1)]+sy1*x0[_I(i1,j1,k1)]); + x[_I(i,j,k)] = sz0*v0 + sz1*v1; + v0 = sx0*(sy0*y0[_I(i0,j0,k0)]+sy1*y0[_I(i0,j1,k0)])+sx1*(sy0*y0[_I(i1,j0,k0)]+sy1*y0[_I(i1,j1,k0)]); + v1 = sx0*(sy0*y0[_I(i0,j0,k1)]+sy1*y0[_I(i0,j1,k1)])+sx1*(sy0*y0[_I(i1,j0,k1)]+sy1*y0[_I(i1,j1,k1)]); + y[_I(i,j,k)] = (sz0*v0 + sz1*v1)*c0; + } + } + } + set_bnd(b,x, N); + set_bnd(b,y, N); +} + +void fproject(float* u, float* u0, float* v, float* v0, float* w, float* w0, int N) +{ + float* p = u0; float* div = v0; // temporary buffers, use old velocity buffers + int i, j, k; + float h; + h = 1.0f/N; + for (k=1; k<=N; k++) { + for (j=1; j<=N; j++) { + for (i=1; i<=N; i++) { + div[_I(i,j,k)] = -h*( + u[_I(i+1,j,k)]-u[_I(i-1,j,k)]+ + v[_I(i,j+1,k)]-v[_I(i,j-1,k)]+ + w[_I(i,j,k+1)]-w[_I(i,j,k-1)])*0.5; + p[_I(i,j,k)] = 0; + } + } + } + set_bnd(0, div, N); + set_bnd(0, p, N); + lin_solve(0, p, div, 1, 6, N); + + for (k=1; k<=N; k++) { + for (j=1; j<=N; j++) { + for (i=1; i<=N; i++) { + u[_I(i,j,k)] -= (p[_I(i+1,j,k)]-p[_I(i-1,j,k)])*0.5*N; + v[_I(i,j,k)] -= (p[_I(i,j+1,k)]-p[_I(i,j-1,k)])*0.5*N; + w[_I(i,j,k)] -= (p[_I(i,j,k+1)]-p[_I(i,j,k-1)])*0.5*N; + } + } + } + set_bnd(1, u, N); + set_bnd(2, v, N); + set_bnd(3, w, N); +} + +void vorticity_confinement(float *T0, float* u, float* u0, float* v, float* v0, float* w, float* w0, float dt, float vc_eps, int N) +{ + int i,j,k,ijk; + float *curlx = u0, *curly = v0, *curlz=w0, *curl=T0; // temp buffers + float dt0 = dt * vc_eps; + float x,y,z; + + + for (k=1; ku, m_fc->u0, m_fc->v, m_fc->v0, m_fc->w, m_fc->w0, m_fc->T, m_fc->T0, dt, GRID_SIZE); + dens_temp_step(sd, sT, m_fc->T, m_fc->T0, m_fc->d, m_fc->d0, m_fc->u, m_fc->v, m_fc->w, dt, GRID_SIZE); +} + + + +void clear_buffer(float* x) +{ + int i; + for (i=0; id=buffers[i++]; m_fc->d0=buffers[i++]; + m_fc->T=buffers[i++]; m_fc->T0=buffers[i++]; + m_fc->u=buffers[i++]; m_fc->u0=buffers[i++]; + m_fc->v=buffers[i++]; m_fc->v0=buffers[i++]; + m_fc->w=buffers[i++]; m_fc->w0=buffers[i++]; + + clear_sources(sd, su, sv); + + size=(GRID_SIZE+2)*(GRID_SIZE+2)*(GRID_SIZE+2); + for (i=0; iv[i] = -0.5f; + + return m_fc; +} + +void f_free(fc *m_fc) +{ + if(m_fc) + MEM_freeN(m_fc); +} + diff --git a/source/blender/blenkernel/intern/implicit.c b/source/blender/blenkernel/intern/implicit.c index 7d7ad480026..9e4428c1055 100644 --- a/source/blender/blenkernel/intern/implicit.c +++ b/source/blender/blenkernel/intern/implicit.c @@ -1630,12 +1630,13 @@ int collisions_collision_response_static ( ClothModifierData *clmd, CollisionMod float magrelVel = 0.0; float epsilon = clmd->coll_parms->epsilon; - return 0; cloth1 = clmd->clothObject; if(!collpair) + { return 0; + } // TODO: check distance & calc normal // calc distance + normal @@ -1650,8 +1651,11 @@ int collisions_collision_response_static ( ClothModifierData *clmd, CollisionMod if (collpair->distance > (epsilon + ALMOST_ZERO)) { + printf("collpair->distance > (epsilon + ALMOST_ZERO)\n"); return 0; } + + printf("IN1\n"); // compute barycentric coordinates for both collision points collisions_compute_barycentric (collpair->pa, @@ -1683,6 +1687,8 @@ int collisions_collision_response_static ( ClothModifierData *clmd, CollisionMod // If v_n_mag < 0 the edges are approaching each other. if ( magrelVel < -ALMOST_ZERO ) { + printf("magrelVel < -ALMOST_ZERO\n"); + // Calculate Impulse magnitude to stop all motion in normal direction. // const double I_mag = v_n_mag / (1/m1 + 1/m2); float magnitude_i = magrelVel / 2.0f; // TODO implement masses @@ -2162,6 +2168,7 @@ int cloth_bvh_objcollision(ClothModifierData * clmd, float step, float prevstep, int collisions = 0, count = 0; float (*current_x)[3]; Implicit_Data *id = NULL; + int ret = 0; if (!(((Cloth *)clmd->clothObject)->tree)) { @@ -2206,7 +2213,7 @@ int cloth_bvh_objcollision(ClothModifierData * clmd, float step, float prevstep, if ( collision_list ) { LinkNode *search = collision_list; - + while ( search ) { collisions_collision_response_static(clmd, collmd, (CollisionPair *)search->link); @@ -2234,6 +2241,24 @@ int cloth_bvh_objcollision(ClothModifierData * clmd, float step, float prevstep, } } + // vertex weight = 2 + + for(i = 0; i < cloth->numverts; i++) + if ((cloth->verts[i].impulse_count > 0) && !(cloth->verts[i].flags & CVERT_FLAG_PINNED)) + { + printf("applying impulse\n"); + + VECADDS(cloth->current_v[i], cloth->current_v[i], cloth->verts[i].impulse, 1.0 / (cloth->verts[i].impulse_count * 2.0)); + + // reset + cloth->verts[i].impulse_count = 0; + cloth->verts[i].impulse[0] = 0.0; + cloth->verts[i].impulse[1] = 0.0; + cloth->verts[i].impulse[2] = 0.0; + + ret = 1; + } + ////////////////////////////////////////////// // update velocities + positions ////////////////////////////////////////////// @@ -2243,78 +2268,7 @@ int cloth_bvh_objcollision(ClothModifierData * clmd, float step, float prevstep, } ////////////////////////////////////////////// - /* - // fill collision list - collisions += bvh_traverse(self_bvh->root, self_bvh->root, &collision_list); - // call static collision response - - // free collision list - if(collision_list) - { - LinkNode *search = collision_list; - - while(search) - { - float distance = 0; - float mindistance = cloth->selftree->epsilon; - CollisionPair *collpair = (CollisionPair *)search->link; - - // get distance of faces - distance = plNearestPoints( - cloth->current_x[collpair->point_indexA[0]], cloth->current_x[collpair->point_indexA[1]], cloth->current_x[collpair->point_indexA[2]], cloth->current_x[collpair->point_indexB[0]], cloth->current_x[collpair->point_indexB[1]], cloth->current_x[collpair->point_indexB[2]], collpair->pa,collpair->pb,collpair->vector); - - if(distance < mindistance) - { - /////////////////////////////////////////// - // TODO: take velocity of the collision points into account! - /////////////////////////////////////////// - - float correction = mindistance - distance; - float temp[3]; - - VECCOPY(temp, collpair->vector); - Normalize(temp); - VecMulf(temp, -correction*0.5); - - if(!((clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL) && (cloth->verts [collpair->point_indexA[0]].goal >= SOFTGOALSNAP))) - VECSUB(cloth->current_x[collpair->point_indexA[0]], cloth->current_x[collpair->point_indexA[0]], temp); - - if(!((clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL) && (cloth->verts [collpair->point_indexA[1]].goal >= SOFTGOALSNAP))) - VECSUB(cloth->current_x[collpair->point_indexA[1]], cloth->current_x[collpair->point_indexA[1]], temp); - - if(!((clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL) && (cloth->verts [collpair->point_indexA[2]].goal >= SOFTGOALSNAP))) - VECSUB(cloth->current_x[collpair->point_indexA[2]], cloth->current_x[collpair->point_indexA[2]], temp); - - - if(!((clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL) && (cloth->verts [collpair->point_indexB[0]].goal >= SOFTGOALSNAP))) - VECSUB(cloth->current_x[collpair->point_indexB[0]], cloth->current_x[collpair->point_indexB[0]], temp); - - if(!((clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL) && (cloth->verts [collpair->point_indexB[1]].goal >= SOFTGOALSNAP))) - VECSUB(cloth->current_x[collpair->point_indexB[1]], cloth->current_x[collpair->point_indexB[1]], temp); - - if(!((clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL) && (cloth->verts [collpair->point_indexB[2]].goal >= SOFTGOALSNAP))) - VECSUB(cloth->current_x[collpair->point_indexB[2]], cloth->current_x[collpair->point_indexB[2]], temp); - - collisions = 1; - -} - -} - - search = collision_list; - while(search) - { - CollisionPair *coll_pair = search->link; - - MEM_freeN(coll_pair); - search = search->next; -} - BLI_linklist_free(collision_list,NULL); - - collision_list = NULL; -} - */ // Test on *simple* selfcollisions collisions = 1; count = 0; @@ -2409,5 +2363,5 @@ int cloth_bvh_objcollision(ClothModifierData * clmd, float step, float prevstep, */ ////////////////////////////////////////////// - return 0; + return ret; } diff --git a/source/blender/blenkernel/intern/kdop.c b/source/blender/blenkernel/intern/kdop.c index 234a6b75548..74b5b3d7b7f 100644 --- a/source/blender/blenkernel/intern/kdop.c +++ b/source/blender/blenkernel/intern/kdop.c @@ -915,6 +915,7 @@ int bvh_traverse(CollisionTree *tree1, CollisionTree *tree2, LinkNode **collisio // of list are horrible slow! BLI_linklist_prepend(&collision_list[0], collpair); } + return 1; } else diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c index 554613b3355..50160771054 100644 --- a/source/blender/blenkernel/intern/modifier.c +++ b/source/blender/blenkernel/intern/modifier.c @@ -5187,6 +5187,8 @@ static void collisionModifier_deformVerts( // recalc static bounding boxes bvh_update_from_mvert(collmd->tree, collmd->current_x, numverts, NULL, 0); + + printf("bvh_update_from_mvert\n"); } collmd->time = current_time; diff --git a/source/blender/makesdna/DNA_userdef_types.h b/source/blender/makesdna/DNA_userdef_types.h index c37b332929d..138040b13ca 100644 --- a/source/blender/makesdna/DNA_userdef_types.h +++ b/source/blender/makesdna/DNA_userdef_types.h @@ -259,6 +259,7 @@ extern UserDef U; /* from usiblender.c !!!! */ #define USER_KEYINSERTNEED (1 << 19) #define USER_ZOOM_TO_MOUSEPOS (1 << 20) #define USER_SHOW_FPS (1 << 21) +#define USER_UNDOSAVE (1 << 22) // flag to signal a write_undo() call after a save (save on exit needed then) /* transopts */ diff --git a/source/blender/src/blenderbuttons.c b/source/blender/src/blenderbuttons.c index c8fb9ec7a7a..84bb22afeac 100644 --- a/source/blender/src/blenderbuttons.c +++ b/source/blender/src/blenderbuttons.c @@ -1,2020 +1,2731 @@ /* DataToC output of file */ -int datatoc_blenderbuttons_size= 64418; +int datatoc_blenderbuttons_size= 87170; char datatoc_blenderbuttons[]= { 137, 80, 78, 71, 13, 10, 26, 10, 0, 0, 0, 13, 73, 72, 68, 82, 0, 0, 2, 0, 0, 0, 1, 0, 8, 6, 0, 0, 0,197,144,206,103, 0, - 0, 0, 1,115, 82, 71, 66, 0,174,206, 28,233, 0, 0, 0, 6, 98, 75, 71, 68, 0,255, 0,255, 0,255,160,189,167,147, 0, 0, - 0, 9,112, 72, 89,115, 0, 0, 11, 19, 0, 0, 11, 19, 1, 0,154,156, 24, 0, 0, 0, 7,116, 73, 77, 69, 7,215, 11, 26, 20, - 59, 43, 0,186, 29, 9, 0, 0, 32, 0, 73, 68, 65, 84,120,218,236,125,121, 92, 84, 85,255,255,251,220,217,217, 23, 1, 21,151, -193,125, 95,201, 37, 55, 40, 53,243,155,153, 6,148,154,100,101, 98,137,218,147,166, 61,101,143,250,211, 71,197,164, 50, 53,161, -167,210,172, 52, 5,115,201, 45, 81, 7,245, 81, 82,113, 47, 23, 20, 69, 4, 69,150, 97, 22,102,187,115,151,223, 31, 51, 67, 3, - 2,179,128, 91,207,188, 95,220,215,229,222,123,238,103,206, 61,219,103, 61,231,144, 30, 61,122,240,240,192, 3, 15, 60,240,192, - 3, 15,254,167, 64,121,138,192, 3, 15, 60,240,192, 3, 15,254,119,112,230,236, 1, 0, 0,241, 88, 0, 60,240,192, 3, 15, 60, -240,192, 99, 1,240,192, 3, 15, 60,240,192, 3, 15, 60, 2,128, 7, 30,120,224,129, 7, 30,120,224, 17, 0, 60,240,192, 3, 15, - 60,240,192,131,191, 5,132,246, 23,231,206,157, 35,238, 18,170, 41,150,192, 67,207, 67,175, 54,164,166,166,242,107,215,174,125, -100,249, 27, 55,110, 28,191,105,211, 38,226,169,143, 39,154, 30,234, 65, 15,158,242,243,208,251, 59,211,115, 89, 0,248, 31, 71, -245, 2, 36,143,115, 62, 83, 82, 82, 48,117,234, 84,226,169, 54,247,235,120,216,176, 97,149,215, 25, 25, 25,127,139,178, 28,253, - 82, 66,157, 3,193,142,237,169,127,235, 54, 35, 11,220, 6,169,177, 13, 34, 64,163, 2,123,145, 99,152,247, 56,183, 69, 79,255, -245,224,241,177, 0, 60,140,198, 58,122,244,232,168, 29, 59,118, 40,236,174,163,119,236,216,145,249, 88,244, 72,222, 50,118, 18, -242,216,246, 75, 62, 47, 47, 15, 0, 32,151,203,159,164, 65,196,105,233,116,220,184,113, 78,167,221,180,105,147, 43,130, 26,191, -101,203,150,202,139,109,219,182, 97,216,176, 97, 85,158, 63, 42, 33, 32, 59, 59,155, 7,128,200,200, 72,210, 16,233,118,108, 79, -125,160,245, 23, 30,209, 28, 0,112,207,104, 4, 99, 48, 89,110,170, 52, 0,128,216,216, 88,164,165,165,213,154,191,222,185,189, -249,182,119,219,186,244,227, 63, 15,252,217,137,122,145, 33,240,221,139, 48,238,216,134,242,242, 49, 40, 7,208, 75,246, 41,230, -201, 78,163,185, 20, 40, 49,230, 98,158, 33,206,165,223,141,141,141,141, 74, 75, 75, 83, 84,187, 23,157,150,150,150,249,152,245, -173, 6,105,183, 79,200,247, 54, 56,154, 4, 75,136,143,200,159,152,164, 98,222,164, 50, 80, 21, 6, 13,167, 51,153,255, 39,102, -199, 57, 20, 0,172, 12,219,118,174,111, 67,224,119,236,216,129,133, 91, 22,195,167,185, 63, 42,110,171, 49, 63,110,158,226, 49, -215,184, 31, 39, 16,185, 92,206,231,229,229, 33, 47, 47, 15,251,246,237,195,212,169, 83, 31, 87, 33,192,214,129, 72,106,106,170, - 40, 33, 33,193,188,124,249,242, 83, 0, 48,103,206,156,167,234,122,113,204,152, 49,149,255, 51, 12, 11,218,108, 2,109,162, 65, -211,150,131, 97, 24,204,153, 51,199,165,188,216, 51,255,154, 96, 21, 6,248, 71,105, 9,112, 69,248,121,100, 26,126,128, 31, 46, -220,248, 25, 50, 52, 3,139, 99, 40,254,230, 12,206,231,150, 97,236,178,117, 78,189,222,246,110, 91, 39, 25,186, 5,175,254,247, - 85,135,101, 34, 27, 57, 15, 65,163,223, 66,225,123,189, 0, 67,121,229,253, 51,134, 15,112, 6, 0, 12,192, 96, 89, 44, 14, 6, -158, 70, 0,128,222,229,189,157,106, 51,105,105,105,247,221,180, 99,144,228, 49,234, 99, 13, 49, 6, 60, 9,223,219,160, 24,208, -173, 7,121, 45, 60, 66,168,106,209, 72, 16,218, 49,156, 18,146, 80,162, 87,171, 57, 41,194, 88,170,103, 51,246,245, 81,195, 89, - 39, 73,221,113,225,103,155, 58,145,102,150, 11,244,146, 31,168, 0,176, 99,199, 14,197,150, 79, 62, 66,220,162, 37,138,122, 54, - 2,222,198,248, 1,160, 84, 95, 6, 4, 3,255, 60,184, 0,154, 27,229, 88,243,246,202,199,141,145,213, 54,240, 60,234, 60, 86, - 10, 1, 35, 70,140, 64, 94, 94, 30,228,114,249, 99, 87,118, 10,133,101,220,136,142,142,230, 1, 80,169,169,169,225, 9, 9, 9, -133,203,151, 47, 63,237, 44, 17,134, 97, 64,211,230, 74,198,111,207,252,179,179,179, 17, 25, 25,233, 82,166,226,226,226,236,153, - 45, 50, 50, 50,170, 11, 0, 13,209, 86, 92,174,135,200,200, 72, 50,110,220, 56,126,248,240,225,247, 61,219,191,127,191,205,210, - 97,179,122, 56, 77,191, 33,221, 1,225, 17,205, 81, 88,174,198, 47, 83, 95, 70, 48, 25,128,220,255,204, 70,171, 49,173,144,225, - 2,243,175, 44, 44,171,169,141, 52,128,169, 45,124,203, 49,232,111, 85,160, 48, 33,162,206,116, 23,165, 7,176,176,235, 61, 44, -189,248,113,125,235,179, 33,152,110, 67,210, 64, 3,211,122, 16,223,219, 32,136,143,143,247, 2,240, 52, 0, 31,187,219, 42, 0, - 23, 54,108,216,160,116,150,206, 23,107,191,160,232, 82,147,136, 54, 25,165,229, 48, 75, 69, 34,161, 80, 99,148, 82, 98,177,129, - 19,248,121, 51,180,204,108, 22, 22,221, 49,125,255,205,122,227,235,147, 39,177,206,124,183, 74,165,250,183,237,255,156,156,156, - 82,111,111,111, 74,167,211,113,246,105,250,244,233,243,121, 3, 51,246, 89,245, 45, 83,161, 35,237,255,242,229,203,104,235,227, -103,111, 13,112,199, 10, 80,201,252, 75,245,101, 88,250,236,130,202, 7,111,236,120, 23, 8, 5,198, 44,143,195,182, 57, 91, 92, -105,100,117, 13,110,245,110,168,183,111,223, 6, 0, 52,111,222,188,202,255,112,193,156,221,128,130, 8,169, 77, 8, 48,155, 25, - 91, 60, 64,131,104, 1, 13, 80,150,246,204, 31, 0, 72, 66, 66, 2, 0,220, 73, 77, 77, 13, 76, 72, 72, 40,119,154,249,155,205, -160,105, 19, 76, 52, 13,115, 53,230,207,115,174, 85, 67, 92, 92, 28,178,179,179,255,234, 93,201,201,136,137,137,169,188, 78, 79, - 79,175,183,176, 99, 39,240,212,187,253,217, 51,254,113,227,198,161,103,207,158, 54, 1,192, 85,139, 64,131, 52,194,130, 27,249, -208,109,251, 23,124,222, 92,137,240,136,230, 8, 11,150,225,198,182, 27, 22,230, 31,224,103,113, 1,136, 4,206, 73,176, 13,228, - 99,107,119,233, 58,110,207, 95, 12, 67,218,250,186, 45, 4, 50, 25,140, 70, 35,114,115,115, 81,108,188,138,118, 8,175, 53,173, -213, 12, 94, 87,219, 39,182,126, 98, 77,155,233, 70,255, 34,118,253,154,119,179,159,145, 58, 24,183,211,109,176,166,239,141,137, -137,225, 9, 33, 54, 87, 78,125,190,215,214,151,121,161, 80, 88,175, 58,143,143,143,247, 7, 48,230,224,193,131,255,226, 56,206, -100,215,150,132, 2,129,192, 59, 62, 62,126,242,134, 13, 27,246, 56,228,152,115,103, 9, 75,239,148, 72, 69, 34,137, 55, 37, 36, -126,188, 64,226,197, 9, 4, 66,142, 80,224,136,144,229, 5, 2,147,128, 35, 70,157,128,213,123,139, 69,228,155, 99,123,140,137, - 73,147, 56,228, 59,206, 99,121,121,185, 70,175,215, 51, 0,160,211,233,184,143, 62,250,168,146,225, 47, 89,178,228, 31,245,109, -239, 67,135, 14,157,106,251,255,192,129, 3, 41, 13,209,135, 40, 71,218,255,226, 87, 98, 96, 44, 41,193,236,206, 29, 96,239,187, -119, 90, 11, 25, 61, 58, 10, 64, 21,230, 63,122,244,232,104, 0,100,244,232,209,209,235, 70,127,101,177, 44,182,111, 84, 37,189, - 51,152,179, 38, 7,115,214,228, 96,218,138,203,120,125,209, 31, 24,251,207,115,245, 31,232, 10, 10,156, 18, 12, 30, 22,243,183, -250,252,249, 90, 44, 1, 48,211, 52,250,246,233,211, 16, 66, 6,191,101,203, 22,108,217,178, 5, 10,133,162,242,112, 81,224,225, - 21, 10, 5,162,163,163, 43,153,191,253,195,132,132, 4,149, 51, 3, 19,195,176, 22,205,223,100, 49,253, 87,103,254, 44,203, 66, -103,208,185,244,129, 54,139, 65,117,171, 65,122,122, 58,210,211,211,171, 8, 3, 46,125,111,102,213,241,208,122, 93, 47, 33,209, -198,252,199,141, 27,135,229,203,151, 87, 50,127,145, 80,228, 42,243,183, 13,224,181, 29, 78,195,128,124, 84,140,233, 11, 62,109, - 54, 10,110,228,131, 31,211,241,175, 66, 72,155, 13, 97,147, 16, 32, 32,224,161, 74,198,186,210, 92, 24,210,214,131,231,121, 92, -188,120, 17,131, 7, 15,134, 76, 38,171,194,248, 3, 3, 3, 97, 48, 24, 96, 48, 24, 80, 88, 88,136,241,134, 25,248, 38,240,189, - 90,105, 58,105,242, 38,213,210,186,202,184, 27, 74, 89, 33,181, 48,127,167,219, 96,245,239,141,137,137,225,211,211,211,145,150, -150,134,216,216, 88,190,190,223,107,101,254, 96, 24,198,237, 62, 17, 31, 31, 47, 5,240,246,129, 3, 7, 62, 90,180,104,209, 9, - 66,136,220,118, 0,104, 22, 28, 28,236,117,232,208,161,181,241,241,241,131,235,162,243, 85,202, 90,129,128,136, 36, 52,195,251, -153, 76,230, 80,150,227,154,177, 28, 23,193, 18,210, 2, 2, 65, 48, 33, 36, 0, 68,224,199,241, 8,226,105, 46, 64, 99, 48,123, -135,250, 49, 2,170,143,214,169, 58,210,235,245, 76,117,173,255,113, 7, 85, 23,227,110,215,174, 29,218,250,248, 65, 95,116, 23, -207,247,236,229, 50,131,182, 9, 17, 11,183, 44, 6,128, 74,230,111,179, 34,236,216,177, 35,211, 38, 4, 20,104,238,160,215,156, -126, 46, 9, 25, 58, 3, 11,157,129,197,221, 50, 19, 10, 75,140,184,125,207,232, 22,227,179,117, 22, 71,204,255, 81,161, 14, 33, - 0, 70,218, 4,163,209, 88, 31,242,188, 66,161,128,205, 71, 30, 18, 18, 98,175,205,194,133,193,164,138, 38, 92,135, 41,209,225, -160, 71,155, 77, 22,205,223, 68,131, 54, 87,101,254,102,179, 25, 58,157, 14, 90,141,246, 81, 87, 11,191,101, 75, 90,213, 79,178, -252,193,122,223,173, 1,207,158,249,219, 24, 63, 69, 81,144, 74,165,240,246,241,170, 87,134, 71,191,148,192,215,118, 56,122,119, -223, 63, 23, 32, 24, 3,192, 12,157, 14, 0,240,201,186,142,243,185,101,150, 65,126,232,116,152, 47, 46, 4, 74,203, 92, 43, 64, - 43,220,253, 30,111,148, 2, 0,214,175, 95,143, 29, 59,118,224,211, 79, 63,197,201,147, 39, 97, 50,153, 80, 92, 92,108,211,202, - 42,211,135,135,135,195, 0, 64,128,155,143,164,189,212,209,238, 73, 61,132, 70, 82,135, 5,207,101,154,246,150,176,154, 98, 2, -220, 97,254, 0,224,174, 16, 16, 31, 31,223,216,202,252,167,124,255,253,247,151,230,205,155,247,210,198,141, 27,209,174, 93, 59, - 0, 64,203,150, 45,161, 86,171, 37, 11, 23, 46, 60,125,232,208,161, 31,227,227,227,229,181,150, 18,199, 19,112,140,148,101,153, - 32,150, 97,155,153, 89,115, 27, 1, 69,154,138,133,148, 72, 42, 18, 24,132, 94, 98,149,183,175, 64, 35,144,242,140, 84, 32,240, - 22, 50,180,223,205, 51,103, 37, 19, 67,190,112,152,239,156,156,156, 82,157, 78,199,213,100,230,239,222,189,251, 85,154,166, 27, -172, 33,117,239,222,189,193,104, 9,235, 98,220,255,153,242,214, 95,204,182,224, 54,102,119,238,128, 21, 22, 6,237,146,212,106, -211,254,109, 76,191,218,239, 84, 94, 7,119,109,236, 82,230, 43, 12, 44,180,122, 6, 26, 29, 3,117, 5, 3,149,150,113,189, 87, -214, 16,249,111,175,229,219,255,127,227,198, 13,168, 84,170,135, 54, 98,164,164,164, 64, 46,151,195, 22,244, 87,205,215,207,167, -164,164,192,104, 48,212, 71, 0,224,215,173, 91,135,130,194, 66,136, 4, 2,132, 53,110, 92,133,249, 63,251,236,179, 56,120,240, -160,179,131, 19,137,142,142,174, 46, 4, 84,177,100, 56, 27,171, 64,155,104,208, 38, 19,204,102, 26, 12,195, 86, 50,127,147,201, - 4,189, 94,143,138,138, 10,104,181,174, 11, 0,246, 46, 0, 27,220,213,252,183,164,109, 1,120,160,212,202,104,172, 78,109, 16, -158,183, 8, 1,105,105,136,179,104, 80, 46,245,149,234,204, 95, 36, 18, 65, 34,145, 64, 42,149, 66, 42,149,214,187, 77,213,230, - 18,168,105, 94,188, 61,198,166,108, 5,255, 98, 4,238,245,239,133, 96, 12,128,236,229, 85, 96,238,150, 0, 1,126, 16,150,109, -194,174, 47, 78, 3, 2,129, 75,121,169,175, 43, 64, 39,176,140, 41, 75,151, 46, 69, 73, 73, 9,214,174, 93,139,238,221,187, 99, -209,162, 69,232,213,171, 23, 12, 6, 67,117, 13,205, 38, 82, 63,108,198,239, 44,131,118,215, 29, 80,155, 32,225, 50, 29,235, 44, -142,202,190,225,174,107,204,158,249, 87, 50, 27,171, 16,224,162, 59,192,247,194,133, 11, 95,190,243,206, 59, 71,186,118,237,234, - 7, 0, 11, 22, 44, 64, 78, 78, 14, 0,160, 95,191,126,248,229,151, 95, 48,112,224, 64,239,241,227,199,231,102,102,102, 30,120, -227,141, 55,198,159, 61,123,246,190,146, 13, 10, 14,226,110,220,200,101, 50, 21, 7,247,182,105,211, 54, 51,162,165,252,146,192, - 87, 86, 44, 32, 98, 29, 37, 17,233, 41,169,151,150, 22, 10,104,240,102, 1, 39, 53,251,106, 11,203,124, 78, 30, 58,215,167, 81, - 96,216, 47, 14,133, 81, 59,159,255,182,109,219, 94, 31, 51,102,204,247, 54,179,191, 70,163,161,196, 98,113,189, 27,146,205,236, -127,224,192,129, 7,107, 1,176,105,249,145,173,219,194, 88, 82, 2, 93,129,133, 9, 14,182,106,135,174, 90, 1,110,252,113,253, - 62,218, 53, 93,151, 93, 44,114, 41,243,245,101,254,246,140,159,231,121,155,143,191, 18,102,179,185,242, 80,169, 84,208,233,116, - 80, 42,149, 15,109,228,176,205,243,223,183,111, 95,117, 75, 0,159,146,146,130,110,221,186,193,104, 52, 84, 14,116, 41, 41, 41, - 46,153,235,215,124,181, 6,102,179, 25,205,194,195, 97,102,217,218,152,191, 43, 3, 9,169,193,244, 95, 57,117,177, 46, 75,198, -125, 2, 0,109,174,100,254,167, 78,158,130,222, 96,128, 86,171,133, 90,173,134, 74,165,170,162,217,185, 10,155, 27,160, 30,126, -127,148,149,150,161,172,172, 20,165,101, 74,148,150,149,161,172,172, 12,101,165, 22,141,180, 67,199,142, 80, 90,255,119, 85,251, - 7,128,158, 61,123,254,165,245,123,123,195,199,199, 23,190, 62,190,208,106,181,209,245,100,254,110,187, 3,114, 63,157, 2,209, -203,171, 16,140, 1, 16,102,173,130,121,235,116, 32,192, 15, 59,223,141,193,173,157, 55, 49,106,249, 6, 64,248,144,151, 21, 49, -222,130, 44, 92, 6,157, 78, 7,163,209, 8,189, 94,143,172,172, 44, 44, 91,182,172,198,228, 94, 94, 54, 11,202,117,119,152,183, -187, 90,181,125,249, 18, 39,175,235, 35,100,184,218,103,171,208, 73, 75, 75, 35,177,177,177, 54,230,239,182,101, 66, 40, 20, 18, -134, 97,170, 11, 5,112, 53, 22, 96,195,134, 13,215, 98, 99, 99,187,111,220,184,113,240,209,163, 71,125,135, 14, 29,122,210,198, -252,173, 10, 36, 36, 18, 9,127,235,214, 45,209,222,189,123,219, 7, 6, 6,158, 26, 48, 96, 64,110, 77,180, 94,125,229, 85,174, -109, 68, 59,109,191,126,253, 98, 46, 93,250,243, 25,141, 78,219,152,103,204, 12, 40,152, 25, 19,101, 50,153, 76, 6, 13,138, 52, -156,201,168, 45,204, 47, 98,118,237,222,147,212, 40, 56,164,152,166,245, 14,213,247,154,180,255,242,242,114, 33, 0,248,249,249, - 61,182,110, 1,170, 54,237,127,203, 39, 31, 89,164,230,162,187, 85,158,185, 26, 11, 48,122,244,232,232, 53,111,175, 4, 96, 9, -248,219,177, 99,135,194,198,244,109,107, 2, 12,251,225, 37, 0,192,153,229,191,219,226, 3, 30, 22, 42, 27, 99, 65, 65, 65,165, -182,111, 99,250,118,149, 11,173, 86, 11,163,209,104, 55,136, 60,188, 60, 78,157,106,137,253, 48, 51, 12, 46, 93,186,132,179,103, -206,160,123,183,238, 48, 26,141, 48, 24,140, 48, 26, 12,248,241,135, 31, 96, 75,231, 76, 71, 79, 78, 78, 70,167,142,157, 96, 54, -155,113,237,218, 53, 48,102, 26,133, 5,133, 13, 90,166,182,107,235,154, 5,182,181, 11, 28, 91, 0,204, 38, 48,172,197,236,127, -226,196,239,208, 25,116,168,208,106,160, 86,171, 81,174, 82,161,188, 92, 89, 47, 65,204,102, 9,112, 83,251, 7, 0, 28, 57,114, - 4, 90,173, 22, 90,173,198,122,214,162, 81,112, 48, 58,116,236,136, 43,151, 47,227,240,145, 35, 46,211,180,105,255, 66,161, 8, - 94, 94, 94,240,241,241,129,175,143, 15,124,124,188,160, 44, 87, 70, 39, 36, 36,100, 58,213,231,234, 97,234,175, 13,231,115,203, - 96,190,184, 16,101, 56, 6, 50,114, 5,200,128,127, 33,247,211, 41,120,113,249,247,144,138, 40, 64, 36,180, 28,238,112, 29, 55, - 93, 1,133, 47,124,133,160, 77, 47, 64,175,215, 35, 40, 40, 8,229,229,229, 40, 47, 47,199,241,227,199,113,247,238,221, 74, 51, -113,101,250,194, 66,188, 27, 40, 67, 35,175,146,186, 52,224,104,123,166, 26, 27, 27, 27,101,247, 44,170,218,179,104, 23,251, 5, - 95, 7, 3,111,136, 25, 5, 46,107,254, 53,125,111, 90, 90, 26, 73, 79, 79, 39,245,252,222, 42, 66,128, 59,204,223,134,143, 63, -254,248,194, 75, 47,189, 52,126,233,210,165,237,207,159, 63, 63, 64, 38,147, 9, 94,124,241, 69, 34,145, 72,192,113, 28, 25, 57, -114,228,133,153, 51,103,118,235,210,165,203,206,201,147, 39,191, 62,121,242,228, 90,125, 81, 9,211, 18,184, 63, 47, 95, 59,213, -165,107,183,215, 78,157, 60, 57,118,231,238, 95,151,100,159, 60,217,248, 82,206, 21,233,181,194, 92,254,199,149,155,101, 75,147, - 63,237,116, 96,247,238,228, 54,173,219,236,242, 9,243, 62,178, 97,195, 6,214,217, 18, 29, 58,116, 40, 78,157, 58,213, 35, 37, - 37,101,161,209,104, 20, 45, 90,180,232,179,157, 59,119,142, 43, 44, 44,124,232,140,195,169, 58,170,237, 65,240,205, 60, 40,129, - 74,237,223,134,193, 33, 33, 88,129, 43,206,107, 29, 86, 19,255,149,211,151, 16,208,190, 17,134,253,240, 18,118, 76,220,174,176, - 73,111, 54,230,111,211,254, 93,153,101,240,203,210, 30, 13,195, 97, 9,193,229,203,151, 97,107,172,213,205,203, 34,145, 8, 34, -145, 8, 37, 37, 37, 24, 57,114,228,163,168, 39, 34,151,203,249,148,148, 20,244,233,211, 7, 70,147, 9, 6,163, 1, 70,107,112, -147,193,104,113, 3,172, 94,189, 26,137,137,137,142, 6, 19,126,249,242,229, 96, 89, 22,167, 79,159,129, 72,104, 49,219,182,109, -219, 22, 55,243,242, 80, 88, 88,136, 77,155,126,198,184,113,175, 2, 0, 95,205, 18, 80,235, 0,148,154,154, 42, 6,192, 36, 36, - 36,112, 53,105, 64,174, 76, 85,180,105,254, 89, 89, 89,208, 85,232, 43, 5, 48,141, 86, 3,141, 70, 13,141,198, 61, 23,128,189, -246, 63,110,220,184, 74, 11,128,171,130,192,184,113,227,170, 92, 71,200,229,232,208,209, 18, 20,119,229,242,101,220,180, 90, 60, -198,141, 27,231,114,212,126,255,167,251, 67, 34,150, 64, 38,147, 65, 42,149, 66, 34,145,160,168,168,200,105,230,111,167,237, 55, -104, 3, 28,187,108, 29,126, 1, 48, 98,233,255,129, 79,155, 13, 18,151,140,243,185,101, 32, 65,129,184, 94,160,177,104,255, 46, -186, 0,236,250, 31,177, 9, 2,246,215, 14, 97, 48, 0, 2,139,178,247,151,121,223,194,232,205,102, 51,190,249,230, 27, 12, 30, -252, 87, 92,216,193, 73,225, 64,177, 30,237,247,148,163, 71, 72,203, 26, 73,214, 16,229,110,239,242, 84, 56, 72,235, 44,195, 38, -245,176, 40,212,101,141,112, 89,144,120,208,223,107, 21, 2,234, 61, 11, 96,233,210,165,155,102,204,152, 17,114,238,194,133, 56, -131,193,208, 77,161, 56, 36,147, 72, 37, 66,138, 80, 56,116,232,144,111,167, 78,157, 54,196,198,198,254,107,236,216,177, 14,181, -245,204, 67,251,185, 81, 47,141, 58,220,189,123,207, 57, 52, 99, 26,113, 61,231,218, 18, 46, 47,151, 1,192, 75, 65,153,187,182, -105,159, 22, 26, 26,178, 71, 32, 20,255,248,239,121, 73,244, 23,139, 62,119, 88, 75,125,250,244,249,124,232,208,161, 0,128,146, -146, 18, 28, 56,112,192,239,187,239,190, 91, 2, 0,167, 78,157,234,211,185,115,231,125, 79,132, 0, 96, 91,248,231,217, 31, 55, - 58,210,236, 93,153, 18, 72,182,205,217,194,247,154,211, 15,193, 93, 27, 87, 50,253, 74,115,234,197, 34,156, 89,254,187,171,102, -171,134,154,147, 74, 0,240, 29, 59,118,196,197,139, 23,171, 48, 22,149, 74,149, 11,160,181,139,210,252,131,180, 4,220,247,155, - 63,254,240, 35,140, 70, 35, 76,180, 9, 52, 77, 99,249,242,229,117, 45,146,195, 47, 95,190,188,242,130,227, 88, 72,101, 62, 48, - 24,140,184,124,233, 18,132, 34, 17,204, 52, 13, 47,111, 47,108,218,180, 9, 2,129, 0,113,113,113,120,246,217,103,249,178,178, -218, 3,188,150, 47, 95,190, 47, 33, 33,129, 78, 77, 77, 13,181,149, 77,181,117, 0, 92, 50,109,206,153, 51, 7,199,142, 29, 67, - 69, 69, 5, 42,116, 58,104, 53, 26, 43,243,215, 64,171,209,162, 66, 91, 1,157,221,128,239, 76,217, 69, 70, 70,242,217,217,217, -149,218,127, 77,211, 0,157, 93, 4,200, 58, 23,191, 74, 93,216,152,190,205,247,232,202, 42,133,182, 21,254, 0,192,199,203, 7, - 82,153, 20, 90,173, 54,218,230,218,113,131,249, 63,144,249,218, 54, 33, 96,204,210,239,192,111, 5, 26, 77, 74, 69,230,123, 49, - 24,152,244, 19, 32, 18,193, 91, 90, 63, 63,103,117, 65, 0, 0,198, 29, 27,231,224,173,123,232,186,207, 11, 69,191,234, 81,190, -248,175,187,102,179, 25,131, 6, 13, 2, 0,132, 7,202,240,223,212,230,248,116,217,109,124,117,198,224, 72, 35,182,159, 22,135, -218,254,183, 75,155,233,198,152,213, 80,115,235, 27,194,231,255, 32,191,183, 82, 8,104,136,246,247,229,151, 95,126,249,198,164, - 55,246, 62,213, 59,178,143, 86,163, 9, 98, 88,198, 20, 22, 22, 86, 18, 30, 30, 94,164,209,104,206,143, 29, 59,214,233, 65,225, -215,237,191,114, 0, 54,189, 54,225,173,172, 1, 3, 7,110,151,201,100,254, 4, 60, 71, 8, 1,199,241,106,131,174, 92,113,245, - 66,190,214, 91, 34,118,106,156,183, 49,127,192, 18, 72, 93, 61, 80,111,217,178,101,255,122, 34, 4, 0, 43, 83,119, 88, 97, 59, -118,236,112,185,177,158, 89,254, 59, 15, 0, 54, 65,192,142,241, 55, 36, 67,119,187, 35,117,237,218, 21,167, 78,157, 66, 73, 73, -165,137,176, 53, 0,216,152,223,196,137, 19, 31,117,125, 85, 41,163,148,148, 20,254,181,137,175, 97,245,234, 53, 86,159, 57,131, - 57,115,230,212, 57,125,201,197, 21,244, 44,154,211,193,131,142, 54,155,232,184,124,249,242,107, 9, 9, 9,197,169,169,169,130, -132,132,132,202,128, 64,235,180, 64,167, 7, 58,155,198, 60, 96,192,128, 6, 47,187,200,200, 72,222, 94,139,183,143, 1,112, 99, - 5, 64, 2,128,223,180,105,211,125, 90,190,213, 66,224,114,123,222,180,105, 19,113,213, 98,224, 12,234, 50,253,187, 42, 44,140, - 93,182, 14,176, 91,248,103,200, 71,127, 77, 71,214, 53, 84, 69,217, 89, 0, 28,173, 4, 88, 56,160, 16,133, 0,122,125, 26,136, -197,167,219, 33, 4, 64, 73,174, 14,109,218,180,177, 48,141,197,129,120,238,169, 16, 68, 60,151,227,172, 70,236,180,123,211,154, -150,184, 59,222, 52,208,152, 87, 47, 90, 15,233,123, 27, 12,235,214,175,187, 6,224, 90, 67,209,251,241,167,111,243,208, 0, 81, -161, 13, 25,152,103,197,172,135, 81,158, 15,123, 51, 32, 50,122,244,232,168, 29,203, 31,203,189, 0, 8, 0,254,169,167,158,194, -158, 61,123,140, 86,166,207, 1,240,122, 64,150,135,122,195, 22, 36,152,152, 56,141,183,106,254,143, 36,111,115,230,204,105, 89, -147, 89,210,110, 26,161, 43,218, 14,121,192,117, 92,153,159,250, 46,251, 91,219,170,124,174, 50,113, 71,107,251, 55, 4,234,227, - 18,152, 59,119, 46,110,220,184,209, 96,121,113,102,121, 95, 87,113,230,131,114,156,129, 37, 48,116,112,172, 12,191,157,104,135, - 48, 47, 31,252,153,125, 15,237,157,100,254, 78,180,191,199,117, 57, 92,242,128,222,245, 44,207,238, 28,154, 54, 48,189,228,135, -149,241,135,190, 27, 96,117, 11,131, 27,150,132, 7, 46, 4,140, 28, 57, 82,250,132, 53, 64,183, 52,251,134,250,237,212,212, 84, -219, 10, 53, 76, 66, 66, 66,125,167, 50,121,208,240,204,191, 94,117,145,148,148,212, 32,117,153,154,154, 42, 76, 24,152,240,192, -219,197,145, 52, 3,142,164,229, 60,246,125,214,211, 50, 61,120,228,141,208,221,125,132, 61,240,192, 3, 15, 60,240,192,131, 39, - 23,148,167, 8, 60,240,192, 3, 15, 60,240,192, 35, 0,120,224,129, 7, 30,120,224,129, 7, 30, 1,192, 3, 15, 60,240,192, 3, - 15, 60,240, 8, 0, 30,120,224,129, 7, 30,120,224, 1, 0,156, 4, 80, 98, 61, 63,145,168, 50, 11,224,220,185,115,110, 71,166, -214, 20, 76,232,161,231,161,231,161,231,161,231, 36,189, 58,167,137, 62, 6,244, 60,245,235,161, 87,133,249,159, 61,123,118, 24, - 96,217, 96,146, 16, 98,124,220,190,215, 99, 1,240,192, 3, 15,224,239,239, 79,249,251,251, 19,127,127,127, 17, 0,193,227,150, - 63,219,190,243,118,251,207,215, 23, 53,173,143,239,193, 99,132,255,251,191,255,139,122,194, 63,161, 15, 0,219,178,195,162, 39, -245, 35, 60, 2,192,223, 28,245,216,110,221,101, 12, 27, 54, 44,202, 58,232, 86, 30,214,123,127, 75,122,143, 57, 72,203,176, 48, - 2, 0,106,181,154, 83,171,213,188, 90,173, 54, 3, 96,221, 33,246,246,115, 93, 11,166,140,232, 58, 26, 0,166,140,232,250,195, -219,207,117, 93, 3, 0,115,198, 60, 69,230,188, 28, 41,122,123,120, 23,183,214, 20,177, 95,138, 54, 45, 45,173,202,230, 59,245, - 97,254,118,237,190, 33,215,218,175, 47,205,134,166,247,196, 50,255, 61,123,246, 40,254, 6,159,194,160,225, 86,116,172, 21, 77, -130, 37,164,109,227, 80,170,133,188, 25, 9, 11, 8, 22,120, 75, 68, 13,246,123,194,191, 73,155,162, 0,200, 96, 49,199,112,240, -160,138, 0,224,196,222, 42, 38, 0,146,250,254, 84, 70, 70, 6,146,147,147,171, 44,255, 55,107,214, 44, 91, 71, 39,238,208,227, - 54, 7, 86,173,232, 87, 50, 30, 23,122,143,125,213, 71,120,203,248,136, 86,114, 0, 64, 17,205, 76,104, 44, 22,254,100,123,120, - 69, 83, 33, 41, 42, 45,165,157, 33, 52,121,120,151, 28,150,229,195,159,238,223,200,175,125,251, 1,251, 37, 18,234,214,180,164, - 62,255,254, 15,185,136,123,106,253,255,137,132,228, 87,128, 92, 2,208,217,213, 76, 86, 95,138,182,158,203,205, 86, 97,254,118, -109,223,221, 65,154,184,120,255, 97,211,123, 98,153, 63,199,113, 32,132, 96,240,224,193,252,145, 35, 71,136,139,117, 44, 6, 96, -110,136,252, 4, 5, 5, 77, 81, 42,149, 95,187,249,186, 4,128,209,206, 18,208,160, 24,208,173, 7,121, 45, 60, 66,168,106,209, - 72, 16,218, 49,156, 18,146, 80,162, 87,171, 57, 41,194, 88,170,103, 51,246,245, 81,195,217,250,254,134,179, 2, 64, 8,128, 72, - 0,217,176, 4, 61, 60, 78,240, 3, 48, 20,192, 24, 0,219, 0, 28, 0,160,105, 0,186, 63, 3,120,181,129, 24,236,163,147,140, - 40,135, 70,158, 62,214, 14, 21, 10,160,216,221,129,119,230,204,153,104,209,162,197,125,219,133, 38, 39, 39, 71,231,231,231, 43, - 86,174, 92,233,202, 32,204,175,159,238,141,248,129,247,111, 46,195,109, 14,196,134,255,210,152,180, 74,247,200,232, 45, 95,190, - 60,234,195, 15, 63, 84,196,197,197,225,231,159,127, 38, 0,240,206, 59,239, 68,173, 93,187, 86,209,162, 69, 11,112, 28, 7,131, -193,128,168,168, 40,108,221,186,213, 33,205,117,203, 63,139,106,255,225, 22, 69, 70,175,102,209,243,179,211, 51, 1, 96,205,194, - 53, 81, 87,231, 51, 10,182,133, 31, 52,156, 55,202, 13,126, 40,246, 63, 21,125,242,198, 39,153,142,232,181,106, 22,214,184,133, - 88,118,119,250,180,137,166, 48,153, 88,172, 81, 26,200,242,239, 54,254,244,209,212,215, 16, 40,147,241, 70, 51,203,127,178,250, - 59, 83, 81,105, 41,105,220, 56, 88, 88, 84, 84, 86,107, 35, 57,179,237,229,182, 59,118,222, 14, 24,240,116, 72,114,207,222, 65, -162,245,235,175,203, 67, 26,201, 74, 63,127,239, 68,242,140,151,122,176, 79,247,111,148,149,115, 77,155, 63, 41,190,245,200,111, -246, 95,172, 15, 83,172,175, 38,197,215,100,241,170,167, 16, 80,219, 59,238,230,181,161,233, 61,177,204,127,214,172, 89, 24, 60, -120, 48,255,223,255,254,215, 29, 82, 52, 44,102,119,166, 1,178, 85, 20, 20, 20, 52, 70,169, 84,110,115,227, 93,127,171,210, 25, - 8,224,110,124,124,124, 0,128, 41,214,107, 27,238, 1,248,117,195,134, 13,185,206, 18,253, 98,237, 23, 20, 93,106, 18,209, 38, -163,180, 28,102,169, 72, 36, 20,106,140, 82, 74, 44, 54,112, 2, 63,111,134,150,153,205,194,162, 59,166,239,191, 89,111,124,125, -242, 36,182, 62,109,199, 25, 23, 64,115, 0, 63, 0,136,177,158,155, 63, 70,109, 42, 24,192, 38, 0,207, 3, 56, 14, 96,132,245, - 58,184, 1,104,191, 2, 39,252,165, 15,211,196,254,128,208, 15,192, 85, 0, 17,238,104, 35, 54, 19,186, 61,243,159, 53,107,150, -194, 78,243,175,124,230,140,185,221,150,198,158, 89, 83,175,148,131,122,165,188,242,218,246,236, 81,208, 3,128, 19, 39, 78, 40, -164, 82, 41,178,178,178,238, 19,182,242,243,243, 73, 65, 65, 1,233,215,175, 95,244,238,221,187,157, 42,195,198, 39, 46, 41,120, -169, 8,221, 74,196, 85,180, 97, 66,241, 88,147,255, 6,249,161, 32,142,200, 71, 92,140,102,238,188,224,208,108, 26,213, 74,206, -183, 16,203,238,190,255,238, 4, 83, 51, 31,177, 88,125,233, 24,241, 42,190,128, 25,131,218,162,105,128, 12,197,103,142,146,123, -167,143, 81,179,166, 76,164,163, 90,201,249, 14, 94,190,230,186, 52,152, 70,141,196, 67,196, 98, 74,122,252,248,221,153,167, 78, -222,233, 24,214,172,149, 57,160, 81, 51,226,235, 11,175, 86, 17, 94, 17, 65, 65,146, 54, 28,207,155,118,157, 44,214, 61,194, 54, -204,219, 51,123,219, 81, 67, 31,229,157,165, 85,237, 92,253,168, 41,221,195,162,247,196, 50,255,221,187,119, 43, 8, 33,160, 40, - 10,217,217,217, 56,122,244,168, 91,180, 88,150,189, 96,181, 0, 52, 68, 60,139, 76,169, 84,110, 11, 10, 10,122,217,141,119,205, -214,250, 50,197,199,199,135, 1, 88,113,240,224,193,127,103,100,100,188,111, 59, 14, 28, 56,176, 92,161, 80,228,196,199,199,207, -119,134,224,172,185,179,132,165,119, 74,188, 12,188, 41,128, 23,146, 80, 94, 34,105,204,137,196,141, 57, 66,133,114, 68, 24,194, - 8, 4, 65, 28, 71,252,117,132,245, 97,196,148,236,155, 99,123,132,210, 23, 67, 31,168, 0,240, 5,128,131, 0,102, 88,207, 95, -212,163,176, 3, 1, 44, 0,176,219, 90,112,187,173,215,129,110,210, 59, 2, 96, 15,128, 4, 0,107, 1,252,195, 74,243, 72, 61, - 27,133,191,245,236,221, 0, 26, 54,172, 26,246, 2,235,249,113,195, 83, 0,142, 1,104,108, 21,158, 94,115,229,229,140,140, 12, -133,189,217,127,214,172, 89,138,228,228,228,232,228,228,228,104,123, 33, 32, 57, 57, 57, 58, 35, 35, 67,225, 12, 61,123, 51, 61, -245, 74, 57,174,237,153,136,107,123, 38, 86, 97,218,220,230, 64,184, 75,207, 42,228, 16,119,232,165,164,164, 68, 29, 63,126, 28, - 19, 38, 76, 64,126,126, 62, 18, 18, 18,162,106, 74, 35,149, 74, 21, 77,154, 52,113, 88,126,169, 41, 41, 81, 77,142,255,129,130, - 9, 3, 32,206, 87,227,235, 5,159, 71, 85, 87,142, 83, 82, 82,163, 68,198, 22,138,160, 38, 6,135,204,127,202,228, 87,232, 79, -102, 78,228,197,183,206,136, 3,239, 93, 36, 23,239,106, 16, 30,226,141,167, 59,133,161,169,234, 42,110,104, 13, 16,114, 60, 2, -136, 64,244,207,183, 38,240,211,223,121,243,106, 84, 43,121,173, 76,167, 92,165, 13,234,211,199, 39,185,107,191,231,205,190, 65, -173, 37, 62, 1,161,156,204,199,219, 20,212, 40,216, 24, 18,222, 92, 88,174,212, 74, 52,106, 6,229,106,147,211,131,144,213,207, -239,144,113, 58, 25, 15,112,159,230, 95,147, 80,238,130, 16, 64,106, 56, 87, 63,106, 74,231, 20, 61,126, 75,224,125,135,139,244, -158, 56, 80, 20,197,239,221,187, 87,193,113, 28,222,123,239, 61, 16, 66,112,244,232, 81, 88,182,222,229,136, 27,244, 64,211,244, - 89,171, 5,160,190,110,108, 37, 0, 40,149,202,173, 65, 65, 65,209,238,240, 79,154,166,133, 0,190, 62,112,224, 64,252,162, 69, -139,238, 16, 66,196,182, 3,128, 40, 56, 56,152, 28, 58,116,104, 94,124,124,252,116, 71, 4, 5, 68, 36,161, 25,222,207,100, 50, -135,178, 28,215,140,229,184, 8,150,144, 22, 16, 8,130, 9, 33, 1, 32, 2, 63,142, 71, 16, 79,115, 1, 26,131,217, 59,212,143, - 17, 80,125,180, 15, 76, 0, 8,183,106,252,159,194,178,219,231,167,214,235,112, 55,126,107, 34,128,124,107, 3,159, 11, 32,200, -122, 38,214,251,174,238,181,251, 47, 0,215, 1,172,177,154,131, 36,214, 6,241,149,245,126,125,246, 95, 30, 12,139,171, 99, 72, - 3,245,129, 55, 1,204,183,158, 31, 55,116, 6,176, 29,192,179, 86, 75, 74,103,119, 9,217,152,191, 61,211,183, 23, 2, 92,110, -156, 86,230,111, 67,117, 33,192, 29,122,213, 6, 88,226, 42,189,195,135, 15,131,166,105,244,238,221, 59,186, 67,135, 14,200,203, -203,171,252, 62,142,227, 32,151,203,249,121,243,230, 41,142, 31, 63,142,145, 35, 71, 58, 28, 80,140, 89,167, 64,209, 12, 84,189, -229,209,166, 14,193,184,190,238,240, 95, 76,139,227, 49, 77,190,142, 63, 60, 47, 88,113,243,184, 63,134,189,113,205,241, 0, 69, - 9, 42, 74, 46,102,113, 69, 42, 35,202, 42,104, 62,166, 71, 11,222, 95, 38,198, 29,149, 14, 37,106, 3,226,122,182,224, 41, 66, -248,223,127,221, 7,245,145, 19,252,153,109,187,110,213, 69, 46,235,108,211,105, 33,161,126,173,155,182,136, 96,188,100, 92,235, -193,207,199,249,180,234,157,240, 66,227,118, 47, 14, 11,106, 26,217, 93, 89,209, 56,198, 76,155,205, 55,114,117,126, 78, 50,127, -222,217, 45,104,211,210,210, 20, 14,102, 6,212,248,204, 9,151,156,103,118,192, 67,212,252,121,158,135,217,252,151,203,126,224, -192,129,182,254,226, 46,227, 50,139, 68, 34, 51,199,113,199,173, 90,120,125,132,128,208, 74, 73, 64,169, 84, 4, 5, 5, 37,184, -240,110,185, 74,165,146, 28, 62,124,248,181, 3, 7, 14, 60,255,253,247,223,151,205,155, 55,175,197,198,141, 27,209,174, 93, 59, - 0, 64,203,150, 45,161, 86,171,201,194,133, 11,139, 15, 29, 58,244,121,124,124,252,192, 58, 41,114,140,148,101,153, 32,150, 97, -155,153, 89,115, 27, 1, 69,154,138,133,148, 72, 42, 18, 24,132, 94, 98,149,183,175, 64, 35,144,242,140, 84, 32,240, 22, 50,180, -223,205, 51,103, 37, 19, 67,190,112,187, 61, 59, 18, 0,158,179,106,135,246, 56,102,189,239, 10,198, 3,120, 15,128,220,202, 8, -255, 0, 80,110, 61,207,183,222,127,207,154,206, 25,120,193,226,107,137,183, 94,155,236, 14, 88,239, 79,193,253, 91,249, 58,139, - 87, 0,124,103, 61,215, 23,111, 0,152,102, 45,179,105,214,235,199, 5,109, 96, 9,154,220, 5, 32, 17,192, 84, 0, 81,158, 97, -171,118, 20, 22, 22, 42,250,246,237,139,169, 83,167,102,246,237,219, 23, 39, 78,156,192,218,181,107,163, 26, 55,110,172,160, 40, - 10,121,121,121,164,180,180,148, 76,159, 62, 61,250,200,145, 35,138,201,147, 39,215,217, 57,251,223,188,163, 40,234,219, 17, 9, - 83,167,102,254, 25,198, 70,119, 86, 7, 41, 82,215,166, 70, 89,164, 19, 96, 77,222, 27,100, 83,105, 12, 25, 60,189, 48,250,104, -154, 92, 17,253,244,167,181,214, 79, 1,205,172,248,250,235,141, 65, 91, 47, 20,222,222,120, 38, 95,181,238,248, 13,221,205, 34, - 35, 79,241, 20,140,122, 22, 37, 37, 52,178,243,203,217, 29,121,133,218,221,119,138, 84,191,220, 42,184,114,172,168,120,248,109, -147,249,179,218,104,250, 5,134, 55, 51, 84,148, 55,237, 20,249, 12, 69,147,150,131, 11,175,108, 55, 4, 6,121,203, 90,117,236, - 81,194, 51, 37, 23,136,192, 47,132,227, 56,193,189,123, 6,103,172,120,188, 45,226,223,142, 17, 87, 55,131,219, 95,195,154,158, -119, 66,195,174,212,244,109,135, 51,233, 61,120,176,168,168,168, 80, 0,128, 80, 40,196,236,217,179,145,157,157, 13, 55,253,254, -246, 48, 1, 48,153, 76, 38, 83, 97, 97, 97, 6,234, 23, 16,168,173, 98, 14, 80, 42, 83,131,130,130, 70, 57,249,174,212,104, 52, -134,207,153, 51, 39,249,157,119,222,209,119,237,218, 85, 2, 0, 11, 22, 44, 64, 78,142,101, 55,202,126,253,250,129,227, 56, 12, - 28, 56, 80, 50,126,252,120,237,149, 43, 87, 14,189,241,198, 27,125,188,188,106,102, 77, 28,199, 51,153, 7, 15,238,205,203,187, - 49,158, 53,179,141, 4, 34,153, 73, 64,164, 58, 74, 34,214, 83, 82, 47, 45, 45,242,170, 0, 37, 81,115, 82,214,172, 85,151,249, - 40,118,158, 27,197,158, 58,235,118, 0,183, 35, 1, 96, 56,128, 67,213,238, 29,178,222,119, 22, 2, 0, 31, 1,136, 3, 80, 86, - 75,154, 50,235,243,143,224,156, 95,103, 60,128,253, 0,212,181, 60, 87, 91,159,143,119,163, 76,158,129, 37,134, 96,153,245,252, - 76, 61, 26, 87,140,213,106,210,207,154,159,126,214,235, 24, 23,233, 4, 2, 8,112,226,112,213,149,210, 31,150, 85,172,108, 65, - 72,183,172,150, 30,183,226, 60,170,107,252,213, 45, 2,174,130,219, 28,136,182, 35,127,168,188,110, 59,242,135,251,162,248, 93, -165, 87,141,153,240,174,208, 91,189,122, 53,159,157,157,192,140, 1,163, 0, 0, 32, 0, 73, 68, 65, 84,141,211,167, 79,163, 89, -179,102,252,111,191,253, 6,141, 70,131,203,151, 47,223,167,209,126,244,209, 71,153,157, 58,117,138,222,178,101, 75,173,244,190, - 89,189,154,111,158,125, 17,161,167,115,160,104, 54,146,239,122,149, 81, 80, 26, 51,216,203, 21,247,165,125,255,163,183, 50, 91, - 68,158,142,190,245,199, 43,181,106,207,215, 11, 10, 62, 40,160,153, 21, 37,165, 6, 57,109, 96, 3,115,238,104,124,118, 95, 41, - 44, 51,181,236,142, 78,161, 65, 0,128,221,231,238, 9,115,139, 42,252, 0, 4, 22,209,198, 78,183, 77,230,216,220,194,194, 15, -106,163, 57,228,133, 56,170,195,224, 37, 93, 25,221, 31,249, 45, 58, 14,149,137, 68, 44,125,253,143, 12, 85, 97,254,229,123,197, -249,191,231,107,148,133, 0, 69, 17,165,150,246,159, 18,215,211, 81,187, 33,177,177,177,213,153,113,117,179,186,253, 53,172,233, - 31, 86, 52,190, 7, 13,136,193,131, 7,243,135, 15, 31, 6,183, 57, 0, 60,207,227,243,207, 63,199,145, 35, 71,108,130,154,219, -117, 80, 94, 94,110, 34,132, 12, 58,117,234,148, 49, 60, 60,124, 88, 61,173, 58, 1,128,101, 54,128,245, 60, 17, 0, 23, 20, 20, -228,140,162,102,108,220,184,177,122,223,190,125,111,110,220,184,209,255,232,209,163,226,161, 67,135,170,109,204, 31,176,108,119, - 47,145, 72,112,235,214, 45,106,239,222,189,126,129,129,129,119, 7, 12, 24,144,203,113, 53, 79, 86,107, 27,209, 78,219,175, 95, -191,152, 75,151,254,124, 70,163,211, 54,230, 25, 51, 3, 10,102,198, 68,153, 76, 38,147, 65,131, 34, 13,103, 50,106, 11,243,139, -152, 93,187,247, 36, 53, 10, 14, 41,166,105,189,219,179, 16,168, 26, 58, 6,101, 61,154,194,226, 23, 62,108,119,143,178, 94, 55, -182, 62,183,221,171,171,131,206,128, 37, 64,239,102, 53, 58,213,143,155,214,116, 51, 28,208,163, 0,140, 5,240,189, 3,122,223, - 91,211, 81, 78,208,179, 29,173, 96,137,115,248, 24,150,153, 4, 31, 91,175, 91, 85, 75,231, 12,189,241, 0,222,177, 50, 89,131, -245,158,193,122,253,142,245,185, 51,244,226, 97,137,115,112,246,136,119, 34,127,159, 1,248, 15,128, 81,214, 50,167, 0, 72, 1, -156,176, 90,101,250, 2, 72,178, 62,175, 43,127, 24, 54,108,216,125,190,126, 91, 16, 96,245,216,128, 97,195,134, 57, 20, 6,134, - 13, 27, 22, 93,221, 55,223,118,228, 15,247, 49,127,234,149,114,184, 75,207,166,101,186, 74,239,220,185,115,104,209,162, 5,238, -221,187, 71, 10, 10, 10,200,221,187,119, 73,255,254,253,239, 11, 6,172, 52, 83,121,121, 41,164, 82,105,173,244,228,231,206, 65, -213,162, 9,122,220, 59, 65,162, 11,246,144,151,238,110, 38,103,125,138,163,217, 44,117,141, 76, 62, 63,135,134, 68, 90,183,178, -115,189,160, 96, 78, 1,205,196, 20,208,204,138,219,180,249,243,115, 55, 75, 66,244, 12, 3,181,209, 98, 28,187, 84, 82,130,155, - 70,122,195,109,147,121,205,109,154,249, 34,183,176, 48, 29,117, 76,157,109, 42,239, 48, 39,160,105,191,208,210,252, 3, 90,134, - 49,149, 23, 22, 73,155, 93, 56,113,202,255,242,185,243,109,242,110,177, 61,111,223,188, 13,177, 72, 24,218, 57,204,123,188, 74, -107,110,227,168, 62,210,210,210, 72,108,108,172, 83, 66, 97,108,108,108,116, 90, 90,154,203,140,194, 62, 16,240,113,158,161,243, -119,198,144, 33,131,249,204,204,204,202, 24,135,253,243,124,193,243, 60, 6, 15, 30, 92, 31,211, 63,172, 76, 58, 26, 0,158,126, -250,105,125, 53,193,209, 45,121, 34, 40, 40,104,130,157,114,106, 82, 42,149,187,149, 74,229,186, 58,222,177,165,229, 0, 84,132, -133,133, 93,120,233,165,151, 86, 47, 93,186,212,235,252,249,243,254, 50,153, 12, 47,190,248, 34, 36, 18, 9, 56,142,195,200,145, - 35, 43,102,206,156, 25,208,165, 75,151, 43,147, 39, 79,238, 60,121,242,228, 50,163,177,230,133, 3, 19,166, 37,112,127, 94,190, -118,170, 75,215,110,175,157, 58,121,114,236,206,221,191, 46,201, 62,121,178,241,165,156, 43,210,107,133,185,252,143, 43, 55,203, -150, 38,127,218,233,192,238,221,201,109, 90,183,217,229, 19,230,125,100,195,134, 13,110, 79, 7, 20,214,160,173, 71, 2, 24, 0, - 96, 17,128,233,214,193,210,187,154,217,238, 7, 88,252,236,159,192,226, 18,200,174, 67,192,120,202,170,253, 58, 99,142, 63,110, -181, 46, 80,117,208, 11, 1,208, 18,192,105, 7, 52, 79, 91,211,133,162,246,169,139, 20, 44,129,121,129, 86,198,249, 18, 44, 83, -255,114,172,180,115,172,215, 27, 97,241,147,111,128,197,117, 65, 59,160,247, 10,128,111, 0,116, 0, 80, 84, 45,159,119, 97, 9, - 90,188, 98, 77,187,217, 1,189,247, 96,153,221,160,119,162,252,188, 0,236, 3,240,147,131,250,120, 25,192,191,173,231,179,118, -249, 19, 89,235, 50, 13,192, 42, 0,139,173,207,239,214,246,131, 25, 25, 25,153, 0,144,159,159,175,176, 69,251, 87,215,250,243, -243,243, 21,246,105,235,130, 45,205,134,255,210,149,209,249,213,181,244, 13,255,165,241, 40,232,101,101,101, 97,208,160, 65,184, -114,229,202, 95, 76, 92, 46,143,222,178,101,139,162, 85,171, 86,209, 28,199, 41, 90,182,108,201,219,166, 1,238,218,181, 11,145, -145,145,209,123,247,238,173,145, 94,251,172, 44,252, 28, 28, 90,165,172, 58, 38, 14,135,238,211,219,192,179,161,224, 57, 96, 90, -203,239,248, 10,206, 7, 74,131, 31,148, 57, 65,232, 62,104,103,244,229, 95,234, 54,179, 95, 47, 40,216, 10, 96,107,235, 22, 77, -219, 3,248,135,137,229,144,126, 33, 15,131,194, 44,238, 78,194,243, 90, 45,195, 44, 42, 46, 46,190,231, 4, 51,253,148,231,121, -239,156, 43,202,215, 84,167,183, 52, 42,190,171, 68,241, 61, 45,132,194, 50,239,138,114, 30, 42, 13,203,135,134,136, 3,132, 28, -198, 24, 76,236,207,139,222,123, 58,224,147, 47,142,171, 28, 8, 1,153, 78, 12,216,164,154,187,192, 53, 12,181, 90, 94, 14,196, -185,250,166,205, 26,230, 40, 42,223, 62, 29,113,150, 30,137, 43, 71, 61,233, 61, 9,224, 51,167, 93, 4,210, 45,147,177,246, 95, - 96,176, 78, 97,233, 99, 46,206,249,175,181,109, 8, 4,130, 16,161, 80, 88,124,252,248,241,111,159,126,250,233,250,148, 89, 11, -165, 82,185,198, 42, 88,188,162, 84, 42, 55,219,206,117,188,179, 9, 22,151, 41,111, 29,187, 43,150, 46, 93, 58,125,198,140, 25, - 77,207, 93,184, 48,212, 96, 48,248, 42, 20,135,136, 68, 42, 1, 69, 40, 28, 58,116, 72,212,169, 83,167,179,177,177,177, 35,199, -142, 29, 91,225, 40, 67,153,135,246,115,163, 94, 26,117,184,123,247,158,115,104,198, 52,226,122,206,181, 37, 92, 94, 46, 3,128, -151,130, 50,119,109,211, 62, 45, 52, 52,100,143, 64, 40,254,241,223,243,146,232, 47, 22,125,238,118, 65,214, 36, 0,252,195, 42, -225,188, 0,224, 50, 0,159, 26,222,219, 99,213,216, 99, 96,153, 71, 30, 95,135,249,191,173,181,192,156, 17, 0,202,172,233, 5, -117,208,139, 2,112,205, 73,122,215,172,233,127,169,131,222, 20, 0,147, 0, 92, 4, 48,211,250, 93,246,180, 21, 0,242, 96,241, -223,239, 6,176, 30,150, 25, 7,181,209,155,104, 45,143, 30, 86, 43, 66, 77,249,212, 88,159,167, 88,133,128,245,117,208,251,222, -218,208,188,156, 28,188,190,119, 80,126,159, 89, 45, 27,251,173, 66, 13,170,209,254, 13, 64, 39,107, 93,228, 88, 5, 41,135,166, - 93,235, 60,127, 69, 3, 45, 4, 68, 38,173,210,241,147, 86,233,106, 88,184,167, 28,143,138,222,159,127,254, 73,254,252,243,207, - 42,247,126,250,233,167, 76, 0,100,243,230,205, 0, 64,110,221,170, 26, 83, 87, 27,243, 7,128,230,127,254, 73,128,170,244,222, - 94, 50,203,194, 28,151, 89,243, 84, 61, 68,239, 23, 23, 70, 97,150,207,131, 16, 16, 84,160,146,249, 91,185,250, 61,169, 84,234, -148,217,144,231,121, 66, 8, 89, 48, 39,174,179, 87, 88,179,150,163, 56,120,181, 45,200, 47, 18,152,141, 42,190,113,168, 15,241, -241, 22, 17,198,204,161, 92, 69, 51, 68, 70,100,106, 45,211,166, 14,133,160,182, 54, 91,253,255, 71,201, 0,237,221, 17,206,204, -219, 39, 15,153,222, 99,207,252,185,205,129,216,127,193, 50, 69,127,189,130,198,207,199,105, 91, 76, 6,105,168,250, 97, 89,182, - 12, 0,122,245,234, 85,175, 5,129,108,204,223,138, 82,235,217, 81,223, 72,180, 27, 79,205, 0, 10, 0,224,203, 47,191,124,249, -141, 73,111, 12,123,170,119,228, 24,173, 70, 19,194,176,140, 49, 44, 44,172, 48, 60, 60, 60, 87,163,209,108, 27, 59,118,108,169, -179,249,250,117,251,175, 28,128, 77,175, 77,120, 43,107,192,192,129,219,101, 50,153, 63, 1,207, 89,102, 78,240,106,131,174, 92, -113,245, 66,190,214, 91, 34,174, 87, 64,107,117, 1,128,133, 37, 72,205, 25, 63,252, 41,235,193,162,246,229, 69, 89, 88, 34,234, -157,157,175,169,128,101, 33,159,186,232,237,128, 37,104,205, 25,188,230, 68,254,190, 6,240,173,163,177, 31,192,187,118,239,212, - 69,239, 7,171,197,192, 17,242,172,154,189, 51,249,115,101,190,235,215, 14,232, 61,235, 4, 61,155,181, 97,189,181,108,156, 49, - 49,145, 97,195,134, 69, 85,143,250, 31, 54,108, 88,180, 51,154,122,109,244,236, 86,234,123,220,232, 61,246,184, 81,120,215, 68, - 53,107,182,254,157, 79, 83, 38,217,238,209, 34,234, 39,163,158,219, 87,148,159,175,117,170,208, 8,225,255, 61,165, 31,249,248, -235,223,231,236, 90, 21,186,237,196,201,187, 83, 67,252,185, 23,169, 32,191, 0,158, 7, 8,225, 77, 38,134, 43,226,128, 82,218, -196, 5, 20,222, 53,184,228,143,180,154,249, 21,213,174, 31,151, 34,244,172, 4,232, 38,158, 91,172,125,208,223,200, 1,104, 34, -149, 74,239,246,234,213,235,217, 51,103,206,212,155,160, 82,169, 60, 24, 20, 20, 52, 73,169, 84,174,119,242, 21,129, 53, 31,149, -227,233,186,245,235, 50, 0,100, 52,212, 71,254,248,211,183,121, 86, 94,241, 64, 80,147, 0, 96,116,131, 14, 95, 71, 37,153, 60, -244,254,182,244,170,192,202, 72, 73,181,123,110, 55,206,199,157,222,147, 0,165, 94,255, 38,224,101, 6, 16,194,129, 47, 52, 26, -233,141, 69, 69, 37,231,225,194, 42,106, 31,127,253, 59,191,253,179, 17,228,133,233,251,178, 0,100,197,246,109,255,143,160, 32, -201, 92,161,128,240,119,203,140, 87,239,210,204, 6,153,136,146,202,132, 2,129,153,225,164,174,228, 47, 45, 45, 45, 51, 54, 54, -214,182, 15,128,205, 61,224, 58,103,173,238,235,183, 51,253,215, 35, 14,192,179, 18,160, 27,160, 94, 41, 7, 33, 4, 47,142,158, - 82,227, 24,178, 99,123,106, 67,125,107, 17, 0,210, 16,204,223, 78, 8, 88,239, 66,114,153,117, 76,165,159,212,186, 18,214,208, - 16, 27,114,142,172,135,222,223,155,158, 7,143,187, 0,160, 84,242, 74,165,114, 74,125,233,188,244,254, 62, 30, 0, 94, 27,220, -137,252,120,228,210,231, 6,126,218,170,233,227,142,119,162,117, 36, 34, 72, 36,108, 4, 66,244, 62, 50, 97, 73,151, 14,126, 57, -233,251, 93,163,109, 13,244,227,221, 9,248,123,192, 26,180,199, 2,224,198, 55,166,166,166,240, 9, 9, 83,201,142,237,169,127, -247,238,229,111, 21,164, 37,110, 42,206,143,190,178,220,221, 71,216, 3, 15, 60,120, 2, 37,126, 1,224, 37, 33,224, 56, 30, 32, - 4, 21, 6, 79,247,247,192,131,255,217,241,192, 83, 4, 30,120,240,191, 3,134, 5, 52,250,191,245,178,243, 30,120,224,129,147, -160, 60, 69,224,129, 7, 30,120,224,129, 7, 30, 1,192, 3, 15, 60,240,192, 3, 15, 60,240, 8, 0, 30,120,224,129, 7, 30,120, -224,193,223, 17, 85, 98, 0,206,157, 59,231,118, 52,106, 77,193,132, 53,209,123,225,153,200,168, 46,221,218, 40,154, 52, 11,143, -214, 26,116,138,195,138,172,232,140, 67,231, 51,221,165,215,181,239,240,168, 30,221,250, 42,238, 21, 22,194, 91,230,141,219, 5, -185,209,217, 39,246,184, 77,175,161,191, 55,113, 60, 21,213,175,111, 43,133,204, 91, 0,161,128, 2,145, 18,188, 56,238, 18,113, -151, 94,194,255,203,138,122,170,239, 83, 10,127, 31, 1, 32, 4, 98,251,214, 60,199,233, 81,125,175,135,222, 99, 75,175,206,169, -102,143,251,247,182,234,245, 50,239,199,229, 62,208,252,157,253,232,150,219, 3,105,207, 37, 45,239,187,247,121,163, 66,183,233, -253,163,244,254, 13, 87, 61,237,249,161,208, 19,162,134, 41,178, 79,226,247,186, 44, 0,212,134,149, 81,104, 11,203,122,248, 44, -128,220,153,153,184,233,236, 15, 12, 31,216, 42,138,128, 67, 72, 64, 16,178, 14,159, 81,124,152, 56, 17, 3,134, 14, 0,163,211, - 43, 58,117, 24, 12,142,131, 98,198, 91, 79, 71,247,236,217, 13,215,175,223,130, 90,165,195,234,245, 71, 50,107,163,215,123,208, -171, 81, 60, 8, 90,182,105,165, 72,120,127, 49,222,124,245, 57,252,240,159,175, 0, 72,177,231,124, 1, 40, 10,138,149, 11,230, - 33, 39,231, 42,228,242,150,144,200,132,184, 83,144, 19, 13,125,205, 89,158,251, 92,119, 94, 44, 22, 67, 38,147, 33, 55, 55, 23, - 77, 67,253,208, 72,232,131,166, 45, 2, 16, 40,243,135, 55, 97, 65, 81, 20,120,142,133, 94, 34,132,250,158, 26, 99,254,147,225, -176,162,150,207,233,198,251,202,212,240, 11, 16,195,199, 91, 8,177,140,130, 80, 0, 80, 98, 33, 50,119, 69,242,102, 94,128, 97, -163, 78, 56, 93,225, 93, 95, 90, 25, 21, 30, 30,142,102,173,155, 41, 12, 70, 19, 40,137, 12, 48, 3,211,146, 79, 69, 25,244, 58, -124,247, 73, 84,230, 35, 20, 36,255, 86,243,152,159,112,184, 90, 23, 78,167,143,253,112,174, 55,128,167, 26,203,188,254, 93, 88, - 88,216, 65, 36,149,128,243,242, 90, 6, 96,109,218,178,164,138,199,165, 0, 34, 58, 13,137,186,121,233,112, 77,251, 41,252, 45, -218,104,106,106, 42,249, 97,195,134, 43, 18,177, 88,198,113,156,191,183,143,143,207,168, 23, 95,244, 2, 64, 39, 36, 36,240,143, -105,158, 41, 0, 72, 72, 72,224, 26,128,156,159,191,191,255,172,246,237,219,143,149, 72, 36,205, 10, 10, 10, 10, 10, 11, 11, 79, -210, 52,189, 4, 64,174, 27,244, 2, 2, 3, 3, 23, 63,243,204, 51,207,135,133,133,201, 79,157, 58,117,239,226,197,139,199,141, - 70,227, 66, 88, 86,136,253,223,176, 0,212,194,252, 5,222, 18,225, 83, 19, 7,182, 94,193,241,188,241,232,213,123, 95,174,140, - 82,239,159,153,137, 75,142,222, 85,222, 61,200,155, 42,148, 48, 87,168, 32,100, 41,252,113,233, 42, 94,127,125,102,229,115,138, - 2,126,207, 90,143, 70, 45,194, 21, 92,133, 6, 52, 71,112,232, 80, 86,244,234,245, 71,106,161,216,146, 63,125,226, 18,136,151, - 31,206, 92,202,199,249, 75,111,224,187,159,127,171,124,202,113,192,136,254,253,129,138, 34, 0,190,200,189,120, 25,162, 70, 1, - 24,208,175,139, 66,165,175, 67,102, 33, 20, 64, 40,244,232,214, 11,141,189,197,104,218, 72, 10,191,224, 32, 4, 74,124, 17, 40, - 21, 64, 36, 16,192,204,178, 80, 49, 28, 78,149,158,118, 88,168, 11,223,109,206,203, 4,229,240,243,242, 66, 72,163, 96,248,249, -121,129,167, 88, 48, 92, 5, 88,176,240,241,241, 66,163,198,205,144,123,165, 29,223,186,195, 15,117, 14, 74, 61, 99, 86,241,254, -190,222,240, 15, 8, 68, 72,163, 96,232,116, 58,136, 37, 82,136,140,150,197,249, 34,228, 45, 21,202,114, 21,158,121,107,125,116, -126,193, 29,148, 23,221, 66,217,249, 84, 71,194,128,211,131,196,208, 73, 67,163, 15,172, 63,144,233, 4,173, 7, 42, 4,228,229, -229,241, 0, 32,151,203,201,227, 66, 47, 60, 60,252,117,154,166,215, 3,192,216,232,104, 42,117,203, 22,119, 6, 95,203, 26,169, -118,134, 28,158,231, 65, 8,169, 60,219,238,217,210, 57,216, 73,205,149,245,228, 93, 97,254,157,188,205,204, 86,223, 0,255, 14, - 0, 32,150, 73, 65, 27,140,224,116,250,229,199,143, 28, 94, 16,251,225,220,142,105,203,146,242, 29,209,249,242,163, 68,222,170, - 97, 49,176,184, 32, 57,235, 56, 84,227, 88,212,125,200,243, 24,242,220,255,185, 84, 71, 55, 47, 29, 86,180,233, 18, 21,125,253, -143, 76,215,133,226, 88,165, 75,201,227,226,226,176, 37,246, 64,157,105,162, 15, 84,221,138,164, 83,128,229, 83,139,141, 28, 12, -140,165, 94,117,214,115,106,223, 0,180,243, 21,213, 73,111,197,138, 21,153, 31,189, 55, 59,116,244,216, 49, 62, 70,163, 1, 43, - 63,255,140, 90,189,122,181, 49, 49, 49, 49, 28,192,157,134,238,123, 99,198,140, 25,186,109,219,182, 12, 87,133,168, 73,147, 38, -241,121,121,121, 40, 43, 43,195,210,165, 75,225,235,235,139,168,168, 40,200,229,114,172, 95,191,222,221,126, 55,184, 87,175, 94, - 27,222,127,255,253,235,237,219,183, 95,223,179,103,207,203,247,238,221,107,150,149,149,213,235,205, 55,223,220,173,209,104,150, -195,178,149,187,179,136, 30, 59,118,108, 90, 82, 82, 82,176,217,108,134, 76, 38,131,183,183,119, 19,157, 78,247,242,232,209,163, - 71, 93,184,112, 33, 17,150,141,211,158, 56,156, 59,119,174,186,149,192, 57, 1, 96,101, 20,154, 3,104, 13,203, 18,135,172,206, -196,220,206,186, 86,252, 69,255,182,161, 51,159,233,212,100, 65, 99,127, 89,211,149, 40,218, 4,224,234,204,204,218, 55,169, 49, - 85, 40,209,184,205,179, 88,252,193, 88,172,183,227, 73,135,143,167, 64,167, 55, 97,228,208,153,120,122,192, 36,188, 26,247, 12, -100, 50, 9,104,150,129, 86, 79, 43,106,111,100,183, 0, 26, 24, 59, 97, 45,222,126,127,106,229,221, 17, 79, 71, 65, 42,149, 96, -251,161,223,176,231, 88, 22, 54,172,251, 10, 70,131, 9, 98,129, 16, 62, 94, 98,232,202, 10,162, 85, 5,168,113,135, 53,158,231, - 1,158,179, 28, 20, 7,158,231, 97,162, 37,149,203, 59,240, 52, 11, 86, 0,176, 96,193,210, 28, 24,182,110, 1,118,206, 91,114, - 62,208,143,129,159,175, 55,194,155, 69,160, 67,215, 54,240,245,145, 65, 93, 81,130,162,146, 34,148,171,239,193,108, 36,240,242, -242, 66, 72,200, 0,148, 22,135,240,141, 66, 63,171,217,140, 63,120, 30,207, 24,244, 48, 8, 1,177, 84, 12,131, 94, 12, 90, 47, -134, 81, 42,129,144, 48,224, 33,128,209, 80, 1,131, 94,139,102,205,154, 42,196, 2, 33,148,208, 32,148,158,128,234,107,204, 87, -199,167, 27, 62,117,216,128, 62,136,255,160,238,177, 50, 54,182,202,254,238,177,177,177,189,131,130,130,114, 8, 33, 70,158,231, -133,129,129,129, 94,185,185,185,193,214,213,221,154,186,219,144, 19, 19, 19,199,217,253, 70,148,187,171,197,213,200, 45, 9,225, -167, 77,155, 22,189,122,245,106,151,104,134,135,135, 39,244,233,211,103,201,192, 30, 61, 96,150, 72,144,156,156,204, 77,125,229, -149, 97, 41,155, 55, 31,112,241,247,177, 98,193,130,202,235, 89,243,231, 35,121,225,194, 58,175,157, 33, 91,141,185,243,189,123, -247, 6, 0,126,232,208, 86,157, 1,220, 72, 74, 74, 51,184,200,252,179,186,118,238,236,103,235, 51,222, 82, 25,238,150, 20, 67, - 83,174, 66,175, 62,125,189,118,125,183,238, 64,236,135,115, 59,167, 45, 75,114,180, 54, 59, 51, 99,201,106,225,107, 47,143, 18, -182,149,203, 57,171, 16,128,249,201,171,170, 10,209,179,166, 3, 0, 62,122, 47,209,173,237,164,221, 98,254, 54,164, 5,185,144, -120,168, 75,164,189,133, 4,231, 23,190, 5,226,215, 8,236,141,243, 48,221,248, 19, 57, 74, 29, 34,247, 22, 59,245,126,207, 94, -189,142, 78, 25, 31,223, 50,126,242,155, 1,105, 63,253,204,201,229,114,106,113,210,114,248, 46, 88,140,237,219,183, 23,166,166, -166, 82, 13,101, 5, 24, 51,102,204,176,109,219,182,237,223,182,109,155,237,122,184,237,127, 7, 2, 74,212,254,253,251, 21,183, -110,221, 66,235,214,173, 49,104,208, 32,248,251,251, 67,165, 82,225,206,157, 59,184,121,243, 38,134, 15, 31,206, 15, 31, 62, 60, -122,246,236,217,174,212,211,152,103,158,121,102,229,138, 21, 43, 54,245,236,217,115, 37, 33,228,142,221, 56, 78, 98, 98, 98,124, - 0,100, 89, 15,167,232, 37, 38, 38,166, 79,155, 54,141, 58,125,250, 52, 8, 33, 8, 14, 14,174, 60,246,238,221, 43,238,215,175, -223, 87,183,111,223, 62,241,164, 51,127,219,189,234, 66,128,176, 6,230, 31, 28, 25, 17, 28,223,163,101,208, 4, 66,136,136,231, -121, 51,103, 57,104,214,108, 52,136, 41,174,105,215,198,210, 15, 26,249,181,110,179,237,212,205,159, 87, 70,113, 71,103,102,214, -190, 91, 28, 32, 70,167,142,237, 65, 81,153,200, 81,149, 1,184, 12,117,225, 53,136,164, 18,236,216,253, 37,244,165, 44, 38,188, -241, 15,112, 28,240,226,168,254, 96,133, 62, 14, 63, 46, 39,231, 50, 56, 14, 24,217,157, 88,249, 74, 75, 24, 77, 52, 98, 70, 12, -135, 52,128,194,134,141,251, 64, 81, 64,250,207,235, 81,120,227,207,232,189,155, 86,100,214, 36,253, 0, 0,199, 3, 28,199,129, -227, 56,176, 44, 11,147,136,135,153,152, 65,211, 52,244, 94, 70,128,147,130,226, 89,176, 98, 30, 21,180, 17, 58,141,186,206,188, -133,248,152, 32, 20,202, 16, 28, 28,140, 54,109,218, 32,172,113, 95, 64, 64,129,101, 79,131,226, 85, 48,234, 24,176,156, 14, 69, -119,148, 8, 9, 46, 69,112,192, 0, 44, 91,177, 43,234,231, 31,239,167, 37, 51, 50,224, 77,165,128, 81, 2,154, 50, 67, 39, 22, -162, 66, 38,130, 80, 36, 6, 56,111, 16, 1, 65,133, 78,143,242,162, 91,200, 61,125, 12,202,252,124,112, 28, 7,138, 23,184,213, -104,190, 91,251,151,224,252,230, 59,111, 58, 30, 39,171,174,217,110, 76, 75, 75,155,251,254,251,239, 79,205,207,207,167, 8, 33, - 33,169,169,169, 63,195,178,185,147,151,187, 13,121, 74,108,172,104,205,154, 53, 27,239,221,187,135,244,244,116, 68,182,111, 47, -104,136, 14, 34,151,203, 73, 92, 92, 92, 20,207,243,138,213,171, 87,187,188, 97, 17, 77,211, 41, 3,173,109, 74, 44, 22,163, 93, -187,118,216,122,232, 80, 70, 72, 72, 8, 74, 74, 74,156,166, 99,211,236, 31, 0, 72,239,222,189,249,211,167, 45, 22, 43,187,243, -159, 67,134, 12, 41,156, 59, 55,214, 63, 41,201,241,154,251,177, 31,206,245,246, 54, 51, 91,187,118,238,236, 39,160, 40,188,251, -218, 4, 24,140, 38, 36,127,251, 45,188,100, 50, 24,141, 70, 24, 13, 6,116,239,217,163,237,111, 63,253, 52, 13,192, 23,142,172, -142, 11,103, 77,231, 0, 80,215,242,242,168,234, 12,191,122,247,116,231,195,155,119, 24, 28,125,251,202, 17,126,216,139,111, 69, -103,236,252,214, 45, 65,192,126,215, 62,219,150,182,117,221,119,132, 78, 1, 66,220,170, 96,113,120, 88, 8, 68, 51, 83,161,153, - 16, 1, 97, 96,168, 75,204, 63, 46, 46,174,200,172,211,223,153,252,238,212,230, 31,254, 99, 14, 86,175, 75,185,212,167, 87,175, - 86, 41,171, 82,188,222,155, 51, 27, 63,245,239,139,141, 27, 55, 78,132,101,215,210,250, 48,254,168,109,219,182, 41,108,204, 62, - 53, 53, 53, 23,150,109,218, 15, 58, 35, 0,236,223,191, 95, 17, 18, 18,130,158, 61,123, 50, 20, 69, 9, 45,214, 89, 14, 34,145, - 8, 65, 65, 65,104,220,184, 49,110,222,188,137,253,251,247, 43, 92,232,115,177, 47,188,240,194,103, 43, 86,172, 88,213,190,125, -251,181,132, 16, 14,192, 87, 0,158, 3,112,132, 16,178, 16,150, 53,243,103, 3, 88,232, 12,189, 21,137,137,155, 7,198,198,146, -157, 59,119, 66, 40, 20, 66,161, 80,224,252,249,243,104,211,166, 13, 22, 45, 90,132, 46, 93,186, 96,234,212,169,194,143, 63,254, -120,197,147,200,252,167,204, 93, 86,121,239,235,164, 15,107, 20, 2,106,154, 5, 64, 9, 5,148,144,225,120,173,193,204,220, 33, -132, 72,124, 36,130,110,126, 98, 68,202, 58, 15,105,141,232,183,129, 14,131,208,196,155, 31, 51,113, 64,196,135, 65,126, 94,195, - 86, 70,193,191,246,236,112, 16, 8,108, 99,182, 31,128,102,240, 15,127, 1, 6,214,136,181,169,235,240,195,198,116, 12,143, 30, - 0, 0,208,235, 1,129,176,118, 82, 50,175,246, 0, 0,150,181,223,155,166, 8, 64, 22, 40,129, 4,241,175,191,133,152,184, 56, -236,218,109, 97,100, 94,222,128,174,226,110,157,133,101,134,160,146,249,155, 25, 22, 38,141, 25,122,149, 30, 42, 51, 13,165,158, - 70,185, 73, 11,149,182, 2,229,197, 90, 40, 85, 70, 40, 43,106, 95, 66,253,221, 87, 91,241,132, 16, 8, 4, 4,132,146,128,101, -121, 48,250,124,232, 84,215, 80, 88,164,134,178,188, 2,106, 45, 11,101,185, 17, 5, 5, 69,184,116,229, 28, 84,234,115,232,219, -171,183,162, 54,154, 2, 0,148,214, 8,195,245, 59, 40,251,227, 50,202,242,111, 65,163, 86, 66,163, 86,226,214,165,211, 56,158, -246, 29,178,182,108, 64,201,245,235, 96,105,206,210,155, 4, 15,205, 13,104,219,135,155,142,137,137,233,184,120,241,226,247,155, - 52,105,162, 75, 79, 79,239,150,150,150,246, 43,128,158,214, 74,119,123,193, 41,113, 88,216, 44, 0,232,215,165, 11,166, 77,155, - 86,124,234,202,149, 3, 79,117,232, 16,213, 16,153,223,178,101, 75, 38, 0,146,152,104,209, 50, 19, 19, 19, 93,162,107,150, 72, - 0, 0, 91,183,110, 69,104,104, 40, 62, 76, 76,196,172, 89,179, 16, 18, 18,242, 88,248, 97,109, 76, 63, 53, 53,181,242, 0,128, -195,135, 15,135, 3, 24,229, 36,153,167, 2, 2, 3, 59, 8, 40, 10,111,196,196, 64,165,214,160,224,238, 29,136, 68, 66, 8,133, -150, 67, 36, 18, 65, 34,243, 66,107,185,252,243,158, 67,135, 58,165,177, 95,203,203,195,143, 91,127,173, 60,108,152,159,188, 10, -243,147, 87, 97,143,226,176,203,223, 59, 52,246,227, 40, 0,184,125,229, 72,230, 80, 11,243, 87,224, 49, 89,237,232,194,247, 95, -160,248,237, 94, 24,146, 81,130, 78, 1, 66, 8,252,130,192,148, 23, 35,114,111, 49,188,133, 22, 30, 40,112, 48, 39,235,230,245, -235,101, 95,167,254,167,253,247,255,249, 30, 95,126,251,213,173,175, 86,124, 54,255,253,233, 51, 70, 45, 94,178, 24, 50, 95,111, - 12,234, 55, 0,167, 78,158,250,254,181,248,215,220,254,102, 27,243,183, 93,239,220,185, 19, 79, 61,245, 84,107, 0, 19,156, 53, -251,155,205,102,244,234,213,139, 99, 89, 86,168, 86,171, 97, 50,153, 96, 50,153,112,229,202, 21, 40, 20, 10, 28, 59,118, 12, 77, -154, 52,129,217,108,198,164, 73,147,156,201,235,184,184,184,184, 47,198,142, 29,235,183,118,237, 90, 63, 66,136, 24,192, 97, 0, -106, 0,189, 0,252,106, 39,120, 30, 4,208,197, 17,189,109,239,191,191,121, 84,247,238,228,167,152, 24, 20,158, 61,139,207, 62, -251,140,219,181,107,215,255,187,125,251,118,168, 66,161,120,123,238,220,185, 48,155,205, 24, 48, 96, 0,188,189,189,251,227, 9, -135,189, 48, 80,167, 5, 96,102, 38, 74, 86,162, 36,229,247,235, 37, 25,145, 17,193,209,189,229, 65,150,117,196, 95, 88,132,223, -125,134,227,224, 31,197,232,223, 57, 16,207,200,119,193,247,183, 37, 61, 71,244,144, 79,216,120,228,210, 31, 53, 17,111,210, 54, -150,240,124, 1, 63,250,245,153,152, 53,253, 43, 0, 74, 0,190, 0, 76,104,217,190, 23,164, 18, 33, 12, 58, 19, 64, 91, 4, 4, - 95, 95, 95, 20, 43,107,221, 47, 27, 6,253, 85, 2,128,191,244,251,183,160,168,213, 85,148, 4,206,240, 39,140, 38, 51,100, 62, - 82, 64,108, 17, 16,180, 26, 13,250,247,239,143, 35,191,254, 84,187, 58,194,209,224, 56, 33, 24,134,129,201,100, 66,133, 80, 0, - 33, 77, 1,119, 53, 96,188, 24,176, 98, 14,188, 72, 0,189, 64, 8, 70,167,135,202, 84,123,172,147,175,143, 14, 12, 67, 96,162, - 89,168,212, 26,228, 92,207, 71,193,221, 82, 24,104, 51, 52, 21, 74, 84,104, 85, 48,178, 52,136,144, 64,167, 87, 67,163,191,137, - 91,133,106,148,105,117,181,210,100,237,164, 52, 70,173, 67,193,185,203,184,119,249, 38, 52,218,235,208,170, 84,224, 33,132, 72, - 64,192, 19, 17, 40,202, 98,245,117,197,185,246, 65,252, 7, 78,185, 3, 28,224, 30,128,123,243,230,205, 51, 0,192,220,185,115, - 79, 37, 37, 37,121, 91,179,110, 4,144,239, 46,225, 53,107,214, 44,141,137,137, 1, 0, 68,132,132,132, 90,125,226,130,134,236, - 28, 54,243,191,213, 18,224,176,248,194,195,195,135,210, 52,141,228,228,100,188,252,242,203, 24, 59,124,248, 95, 3,253,133, 11, - 22, 75, 80, 72, 8,239,108, 92,192,172,249,243, 43,125,254, 0, 48,123,193,130, 42,150, 1, 39,205,254, 85, 96,211,254,109, 76, -223,134,212,212, 84, 36, 36, 36,224,192,129, 27, 63, 2,248,201, 17,157, 0,161,240,223, 70,218, 4,129, 64,128, 43, 55,114,193, -243, 60, 46,229, 92, 3, 77,155, 65,129, 64, 40, 20,130, 16, 2,142,101, 97,208,233,113,237,247,223, 15, 57, 81,134,148, 61,211, -127,237,229, 81,246, 26, 63, 5, 0, 39,206, 92, 64,219,136,150, 46, 77, 83, 62,144,246,239, 74,109,255,128, 69,243,183,185, 66, -248,231,199,188, 21,189,119,155,123,214,128, 6,129,242, 46,196, 45,218,161,120,154, 20,146,103,198,129,205,222, 7, 86, 99,137, - 55, 40,158,246, 52, 90,166,102,129,229,234,110, 42,237,219,182,111,234,229,229,237,245,229, 55,107,140,209, 67,134,136,251,246, -239,247,211,254, 61,191, 61,127,229,122, 14,192,241,144, 74, 36, 24,208,123, 0,118,239,220,141, 17, 35, 70,240,251,246,237,115, -122, 40,168,174,245,239,223,191, 31, 55,110,220,160, 1,136, 79,158, 60, 73, 79,157, 58,117,124,106,106,234,107,142,232,228,229, -229,161,117,235,214, 0, 64,229,229,229,225,252,249,243,104,217,178, 37, 34, 34, 34, 80, 94, 94,142,236,236,108,180,106,213, 10, -161,161,161,104,217,178, 37,242,242,242,234,110, 40, 20, 21, 31, 23, 23,183,100,240,224,193, 62,167, 78,157,242, 99, 24,102,178, - 76, 38, 27,109, 48, 24, 86,192,178,245, 57,172, 2,192, 42, 88,182, 86,167, 81,199,244,118,145, 72, 20,159, 54, 99,198,250,167, - 67, 66, 72,201,156, 57,232,207,113, 88,181,115, 39, 95,168,215,191,133,191,182,101, 95,127,233,210,165,181, 12,195, 8,125,124, -124, 16, 30, 30,238, 99, 54,155, 33, 18,137,240,119, 67, 77, 46,128, 48, 0,173,199, 68,182,120,183,121,176,247, 4,152, 13, 64, -251, 97, 56, 19, 50, 6,207, 36,126, 7, 67,169, 10, 2, 63, 95, 40, 86,198, 99, 80,167,223, 17,116, 33, 99, 48,128, 22,181,253, - 64, 27,191,102,248,227,194, 47,118, 6, 7, 29, 44, 91, 40,155, 1,179, 9, 66, 78, 0,202,202,196,183,109,119,188,139,200,190, -139, 60, 70,244,236, 82, 77, 9, 21, 2, 16, 1, 34, 41, 24,194,194,170, 7,227,149, 9, 51, 0, 64,145,244, 81, 98,173, 29,129, -229,120, 48, 28, 5,138, 97, 64,209, 38,232, 41, 75,219, 49, 8, 4,240,102, 12,208, 24,120, 16, 17, 1,203,178,208,179, 64,177, -174,246,141,159, 24,154,131, 81, 36, 0,167,103,192,112,106,104, 43,204, 16, 16, 17, 76,140, 25, 52, 79,131, 49,211,128,152, 3, - 69, 0, 34,225,160, 54,176, 40, 42,209, 67,103, 98,106, 84,146, 41,194, 86,238,195, 75,200, 95, 46, 93,179,209, 0,181, 82, 9, -138, 8, 32, 20,242, 0, 47,132,128,184,175,234, 92,189,117,149,110,223,178,189,216, 25,179,127,109,178, 25,236,118,196, 74, 74, - 74, 26, 5,224,246,220,185,115,123,250,251,251, 7,168,213,234, 91, 73, 73, 73, 46, 19, 77, 76, 76,124,115,205,154, 53,104,220, -184,177,253, 61,213,170, 85,171, 14, 60,213,161,195,208, 83, 87,174, 28,108,168,142,144,152,152, 24,109,231, 10,168,139,249, 71, -245,233,211, 39,124, 96,143, 30, 32,190,190, 72, 74, 74,194,156, 57,115, 32, 18,137, 96, 46, 47,135,191,191, 63, 62, 76, 76,172, -140, 11, 72,136,139,115, 40, 4, 84,247,241, 59,138, 9,168,203,163, 80, 93,251,119, 96, 29,112,216,100,202,149,202, 14, 62,190, -190, 40, 45, 47,135,226,196, 9, 8, 41, 1, 76,102, 51,244, 6, 3, 56,142,171, 20, 92, 24, 51, 13,218,100,114,198,165,193, 1, -160,172,110, 0,206,174,225, 27,173,247, 49, 63,121,149, 24, 0,218,202,229,197, 55,107,214, 45, 92,178, 82, 53,107, 29, 25,181, -119,219,183,174,152,155,107, 47, 96, 23,204,254, 85,204,178, 91,254,131, 30,175,255, 3,146,136,110,150,177,162,244, 46,114,148, - 22,193, 95,210,255, 5,228,179, 12,188, 86,215,237,106,214,104, 52, 1, 18,153, 20,109, 34, 34,164, 55, 11,110, 55, 41, 43, 41, -195, 43,175, 77, 80,236, 57,152,129,149,203,146,211,183,237,217, 25,211, 54,162, 45,226, 95,158,136,172, 51,199, 48, 98,248,112, -126,223,254,253, 14,191,217, 94,235,223,191,127, 63,134, 13, 27,102, 19, 22,197,119,238,220,193,212,169, 83,197, 0,224, 76,108, - 65, 89, 89, 25, 6, 13, 26, 4,150,101,145,151,151,135, 99,199,142,161, 83,167, 78,240,247,247, 71,243,230,205,209,163, 71, 15, - 80, 20, 5,138,162,208,164, 73, 19, 71,237,180, 83,151, 46, 93,190,232,223,191,191,224,194,133, 11,126, 44,203, 22,109,221,186, - 85, 99, 48, 24,146, 0,216, 59, 77,223,125,254,249,231,243,247,236,217, 19, 65, 8,185,139,218, 55,230,233,153, 48,112,224,250, -190, 66, 33, 41, 89,178, 4,188,217, 12,133, 64,192,101,233,245,147, 96,217,198,221,134,119,230,205,155, 39,164, 40, 10, 74,165, - 18, 55,110,220, 40,238,210,165, 75, 40,254,134, 16, 86, 99,254,109,195,252,101, 3,159,239, 30, 62,213, 79, 38,234,195,176, 92, -185,144,103,253, 16,208, 68,112, 87,101,132,161, 84, 13,136,133, 96, 85, 90, 20,148,211, 64,112, 11, 80, 28, 45,173,203,196,123, - 93,163, 65,187, 0, 63, 48, 38,224,122,230,143,104, 19,245, 92,165, 2,103,166,205, 16,129, 66,133,209,178, 67,237,136,168, 94, -144, 5,135, 99,197,250, 95,107,205,240,136,174, 4,123,206,243, 16, 73, 1,113,139,231, 64,231, 31,173,180, 2,136,196, 18,152, - 97,132,143,204,178, 35,233,206, 61,155,240,199,201,204, 58, 77,146, 28,199, 65, 76, 27, 96,134, 24, 20,197, 0, 70,203,192,102, - 54,155, 97, 50,138, 32, 16,138, 0, 35,192,115, 22, 23, 65, 75,121, 4,144, 85,243,140, 2,189,145,131, 64, 64, 96,102,204, 48, -154, 56,104,180,150,118,104,230,120,208, 38, 14, 16, 2, 2,145, 0, 66, 41, 64, 12, 44, 56,194,128,131, 1, 90, 3, 0, 56, 30, - 88, 88, 0, 20, 7,240, 4,160, 40, 14,132, 8,192,241, 4, 20,101, 85,156, 56, 10, 28, 69,129,112,206, 41,200,118, 65,126,226, -122,182, 35,111, 0, 33,115,231,206, 45, 78, 74, 74,138, 6,240,210,220,185,115,135, 39, 37, 37,233, 0,148,185,101,178,138,141, - 21,175, 89,179,230,219,152,152, 24,200, 27, 53,170,188, 47,111,212, 40,192,106, 5, 8,121, 20, 29,134,166,105,133,205,247,207, -107,181,248,228,147, 79, 96, 42, 43,131, 45,242,173,141, 85, 88, 17,153, 76, 24, 53,106, 84,113, 97,113,241,120,103, 52,237, 6, -116,201, 84,177, 0,212, 97, 33,192,233,211,167, 73, 77,194, 67, 21,161,214, 68, 67, 69, 43, 97, 52, 26, 17,224,239, 15,169, 88, - 2, 51,203,128,231,121,176, 44, 11,154,166, 97, 54,155,193, 49,172,179,241, 12,220,181,188, 60,170,173, 92,110,211, 8,184,107, -121,121,212,143, 91,127,149,218, 91, 4,218,202,229,170,134, 50,223, 23,228,102, 55,152,230,239,110, 12,192,144,140, 18, 20,203, -211, 33,110,209, 14, 36,162, 27, 90,174, 59,139, 82, 35, 7,111, 33, 1,253,223,237,184,122,227, 38, 28,237, 90,108, 96,104,156, -206, 58,137, 47, 86,124,142,167,163, 6, 98,222,255, 91,128,223,246,254,134,159, 54,252,128,254,131, 7,198, 52,151,183,128,208, - 75,132,131, 71, 15, 98,227,247, 63,224,151,237, 91, 33,150, 74,249,157, 59,119,214,185, 62,196,182,109,219,170, 48,126, 27, 84, - 42,149,203,229,163,213,106,225,239,239,127, 2, 64, 95,185, 92,142,222,189,123, 67, 32,176,184, 89, 91,182,108, 9,137, 68, 2, -181, 90, 13,185, 92, 14, 95, 95,223, 91, 90,173,182,101, 29,228, 46, 93,184,112, 97,233, 47,191,252, 50,178,109,219,182, 29,182, -110,221, 90, 81, 94, 94,190, 16,192, 70,123,249,101,200,144, 33,239,175, 91,183,110, 11,128, 98, 0,177, 0,126, 7,208,189, 6, -122,103, 87, 43, 20, 75, 3,178,179, 63,122,149, 97,240, 57,192,125, 91, 81, 49,177, 26,189,151,102,204,152,241,249,148, 41, 83, -112,243,230, 77,236,222,189, 27, 12,195, 28, 2,240,234,147,194,212,123,244,232,129,115,231,206, 85,250,253,235,180,176, 84,187, -110, 53, 38,178,197, 98, 63,153,168, 79,137,198,248,219,241,107, 37, 73, 16, 72,128,171, 71,241,172,156,199, 63,167,143, 66,239, -206,114,204, 72,120, 30, 47,182,166,129,139,251,193,139,100, 12,234, 12,214, 81, 33, 71,149, 15,161, 4, 24,241,226, 63,176,241, -203,101, 22,101, 81,111, 2,107, 0,182, 43,206,225,192, 41,203,140,194,102, 45, 34, 64, 9, 29, 51,175,145,221, 9,204, 70, 96, -231,238,125,136, 28, 62,221,162,253, 67, 4,129, 12,136,123, 33, 22, 35, 7,143,182,116,252, 91,185, 96,140,117,111,213,204,243, - 60, 24, 98, 97,240, 38,218, 18,252,103, 50, 26,160,215,235, 81, 81, 81, 1,173, 70, 13,173, 86, 11,141,202,162,101,189, 0, 0, - 32, 0, 73, 68, 65, 84,182, 2,198,138, 10, 24, 12,134,218, 27,127, 5,129,193,200,194, 96,100,161,211,155,161,173, 48,161, 92, -107,130, 74, 67, 67,173, 53, 67,165,178,156,149,101, 12,148,229, 12,148,106, 6,165, 74, 26,247, 74,107,207, 35,197,243, 96, 1, - 16,150,128, 80, 28,120,194, 3, 60, 15,158, 23,128,229,254,170, 62,206, 58,122,184,106, 27,239,216,191, 35,142,237, 57,134,223, - 14,253, 86, 41, 20, 92,189,117,213,213, 54, 23, 14,160,245,242,229,203,207, 3, 88,253,225,135, 31,190,215,170, 85, 43, 38, 53, - 53,149, 36, 39, 39,187,172,117, 77,137,141, 37,226,176,176,109, 0, 16, 22, 22,118,223,243,105,211,166, 49,217, 87,175,110,106, -168, 88, 0,155,249,223,217,125,227,109,190,127, 0,216,188,121, 51,174, 23, 21, 1, 0,118,101,102, 86,121,118,245,234,213,208, -144,144,144,242, 71, 49, 8, 12, 29,218,202, 54,239,186,202,125,219,181,237,185, 35,120,249,249, 94,225, 88, 22, 26,101, 57, 74, - 75, 75, 81,166, 42,135, 78,175,135, 78,175,135,182,162, 2, 58,181, 6, 90,149, 10, 70,131, 30,180,209, 8,142, 97, 29,142, 57, -109,229,114,219,152,193, 1,160,237,221, 1, 0,240,227,214, 95, 49, 63,121, 85, 0,128, 48,151, 27, 98,235,200,168,234,130, 67, - 68,167, 33, 81,143,122, 80,190,251,138, 28, 45,215,157, 5,137,232, 6,211,225,116,220,122,163, 39,188,133, 4, 71,135,133,128, - 81,151, 32,114, 95, 49,132, 14,154, 95, 70, 70, 6,121,123,230, 59,184,126,245, 42,178, 50,143,194,223,215, 31,227, 94, 25,135, -128,224, 32,156, 57,153, 13, 31,177, 20,222,222,222,104, 34,111,138, 77, 63,111,194,135, 31,127,132, 10, 55,152,184, 13,189,122, -245,114,249, 29, 95, 95, 95,168,213,234,190, 20, 69,209,205,155, 55, 71,159, 62,125,208,185,115,103, 52,106,212, 8, 82,169, 20, -114,185, 28,221,187,119, 71, 64, 64, 0,180, 90,109, 75, 95, 95, 95, 71, 36, 63, 61,124,248,112,198,134, 13, 27, 68,229,229,229, -243,170, 49,235,216, 65,131, 6,125,177,110,221,186,239,194,194,194,150, 16, 66,124, 0,124, 8,160, 46, 51,217,199,139,181,218, - 79,223, 98, 24,246, 91,131, 97,124, 53,122, 49,175, 38,252,235,151,233,239,205, 18, 92,189,122, 21, 39, 78,156,192,186,117,235, - 42, 0,252,243, 73,211,236,171, 7,189,215, 22, 4, 95,125, 16,144, 8, 40,226,155, 95,166,251,105, 83,214,205,127,158,187,165, - 60,105, 96,201,117,148,222,132,244,151,119,177,100,128, 22,217, 11,251, 96,101,116, 5,188,183, 79, 3,148, 5,168,224,165, 23, -173,146, 87, 45,248, 43,170,255,252,133, 95,241,175,127,109, 64, 27,191,174,248,243,248,121,236, 87, 92, 70,116,255,206, 24, 54, -200,210,208,120,129, 16, 52,235,252, 71,142,232,217, 1,139, 63, 93,134,125, 23, 53,240,145,119,194, 11, 47,140,194,111,135,182, - 97,247,111,155, 44, 31,199,154, 33, 17,213, 61,206,241, 28, 11,150,179,104, 51,176,106, 51, 52, 77,195,104, 52,194, 96, 48, 64, -167, 55,192,160,215,193,160,215, 65,111, 50,130, 54,213,190,237,115,153,193, 23,234, 10, 22, 26, 3, 7,141,129,179,252,175,229, - 80,161, 99, 80,161,103, 80,174,100, 81,166, 52,163,172,220,140,178, 50, 51, 74, 75,105,220, 43, 53,215, 41, 0,252,101,254,191, - 95, 85, 19, 10,120, 8, 8, 1, 95, 45,234,159, 39,142, 21,167, 15,226, 63, 64,199,254, 29, 43,175, 15,172, 63, 80,105, 17, 56, -182,231, 24,174,222,186,122,211,149, 6,151,158,158,254, 95,158,231,187,196,196,196,196, 71, 68, 68,132, 0,160, 56,142,147,152, -205,230,192,153, 51,103,250,213, 98, 10,174, 17,226,176,176,249,107,214,172, 25, 25, 19, 19,131,136,144, 16,167, 92, 87,245, 52, -255, 71, 1, 64,100,135, 14, 14, 3,216,218, 54,110, 28,157,156,156,140, 63,111,221,210,252,178,127, 63,174, 92,185, 82,169,245, -183,111,223, 30,214,103,244, 47,251,247,227,214,173, 91,184,154,157,109,112, 68,115,214,252,249,152,189, 96, 65,165,121,223,246, -191,237,218,246,191, 43,177, 0, 73, 73,105,252,144, 33, 67,222,181,103,250,182,115,239,222,189,145,148,148,230,148,118,125,237, - 74,110, 54,195, 48,160,105, 19,148,247,138, 81,114,183, 8,165, 69,247, 80, 90,116, 15,202,226, 18,168,202,202, 96,210,233, 44, -241, 51, 42, 21,156, 8, 2,100,230, 39,175, 18,206, 79, 94, 37, 4,160, 1,192,245,237,213,237,190, 68,118,113, 1, 78,163,105, -235,200,168,194,220,108, 69,247, 62,127,229,161,117,207, 23,163, 84, 37, 55, 20,245,105, 31, 36,174,188,138,230,239, 14,114,148, - 58,228, 79,126, 10,252,205, 11, 8,253,207, 25,120,175, 61,141,187,175,200,209,123, 95, 49,136, 72, 2, 33, 1,132,148, 99, 1, -244,194,197,139,228,147,101,139, 49, 99,246,251, 48,115, 44,174,228, 93,195,132,113,227, 33,150, 74,177, 99,251, 78,192,204,194, -100, 52,225,104,246,113, 24, 12, 21,152, 50,105,210,225,183,223,126,187,174,186, 38, 99,198,140,137, 30, 62,124, 56, 8, 33,200, -200,200,184,207,164,255,193, 7, 31, 56,253,157,193,193,193,184,115,231, 14, 0, 8, 83, 82, 82, 80, 82, 82,130,174, 93,187, 34, - 32, 32, 0, 20, 69,225,228,201,147,160, 40, 10,132, 16,220,185,115, 7,193,193,193,206,144, 93, 66,211,244, 96, 0,155,237,238, -141, 27, 52,104, 80,242,228,201,147, 3, 83, 82, 82,164,132, 16, 10,192, 54, 88,102, 1,220,115, 64,111,206, 9,179, 57,178, 58, -189, 87,231,254,178,229,229,241,211,200,200,119, 82,144,121,226, 18,146,147,147, 57,141, 70,243, 38, 44,179, 11,158, 56,244,232, -209,163,242,112,202, 5, 0, 32,119,211,241,155,137, 74,157,233, 52,128, 28, 0, 77,178,174,149,124, 61,184, 67,216,199,194,155, - 39,130,176,110, 34, 32,241, 6, 76, 58,128,231, 97, 22, 72,239, 29,253,243,238,183,168, 99,245,165,141, 63,125, 21, 61,126, 66, -188, 2, 0,116,156, 25,215, 85,249, 0, 88,180,241,139, 64,116,116, 55,132, 53,106,140, 50,181,198, 98, 43,160, 25,220, 85,233, -234,252,168,102, 45,250,163, 32,223, 58,205,147, 8, 49,162,187, 37, 6, 96,223, 69, 51,126,219,149,142,123,165,119, 16, 28, 96, -153, 73, 16, 32, 22,161, 91,100, 15, 40,182,215, 97,210,133, 16, 98,142, 1, 11, 1, 56, 66, 64,177, 28, 96,102,192,138,132, 0, -161, 96,235,147, 28, 15,203, 90, 1,117, 96,175,226, 38,121,126,160, 47,239, 37,230, 33, 20,217, 89, 24,204, 0,195, 3, 70, 26, - 96, 77, 44, 8, 33, 32, 98, 2,134, 5,116, 38,224,100,150,154,244,232,209,156,175,209,228,111,227,150, 20, 7, 98, 53,255, 91, -132, 2, 2,150,163, 64, 9,172, 51, 5, 0,240, 2, 30,224,157,179, 2,216, 51,255,154,174,143,237, 57, 22,225,108, 67,139,137, -137,233,156,158,158,254, 57,128, 30,233,233,233,251,210,211,211,143,198,196,196, 36,182,110,221,218, 76, 8, 9, 94,185,114,229, -254, 15, 63,252,112,194,178,101,203, 14,215, 33,124,218,180,127,225,236,217,179,231,207,158, 61, 27,251,246,237,131,238,222,253, -125, 57, 34, 36, 4, 55,111,222, 4, 0,133, 51, 11,249,212,182,232, 79, 98, 98, 98,212,154, 53,107, 20,171, 87,175, 70,100,251, -246,209,167, 46, 95,118,104, 42, 62,126,241, 98,230,128,255,207,222,151,199, 53,121,108,239, 63,147,141, 0, 42,130,187,104, 85, -172,168, 85,235,130, 21, 80, 43,137,162,181, 90,187,252,106,212,234,181,245,171, 45, 65,237,117,235,130,182,182,118,209,170,189, - 23,181,171,196, 46, 87,187, 88, 37, 88, 91,183,186,160, 9, 42, 34,136, 86,235, 10, 8, 42,130, 11, 74,194,150, 0,217,230,247, - 71,242,198, 16, 3,121, 19, 80,180,125,159,207, 39, 31,222, 45,135,201,204,188,243,156,115,230,204,153,190,125,159,186,112,236, - 88,103, 0, 62, 0, 62, 55,250,248, 64, 88, 93,141,110,237,218, 97,193,130, 5, 72, 77, 77, 93, 25, 26, 26,154,146,154,154,186, -191,160,160,192,141,114,119,119, 30,128,122,196, 0,212,208, 3, 83, 82, 82, 72, 92,156,236,216,209,163, 69,169,114,185, 92, 4, - 0,113,113,178,193, 43, 87, 42,211,192, 50, 9, 80,231,190,143,189, 83,121,253,198, 40,139,201,220, 67, 87, 90,138,210,219,183, - 64, 8, 15,148, 90, 80, 85, 85, 5, 74, 41, 40,165,184,116,238, 60,140,134,106,252,153,156,236,174, 14, 29,199,156,230, 0,120, - 99,164, 81,150, 49,210, 40, 56, 46, 11,180, 77, 17,176, 70,135,110,131, 36, 5, 57, 25, 42, 0,232,220,169, 19, 78,101, 88,245, -228,220, 63,183, 1, 0, 90, 61, 50, 64,122, 43,255, 68,163, 13,198, 3,255, 40, 66,230,211, 64,191,176,104, 20,205, 30,140,182, - 95, 31, 65,182, 70,135, 64, 17, 65,177, 70, 11, 1, 33,110, 61, 0,246,119, 51, 53,181,198,147, 93,187,118,165, 99,198, 62,141, - 29,219,118, 32, 49, 49, 17, 31,188,251, 30,246,170,247,131, 47,224, 35,184, 67,112, 84,105,105,221, 75,151,183,110,221,170,182, - 41, 2,146, 81,163, 70,213,136, 5,216,183,111, 31, 46, 94,188, 88,165, 80, 40,218, 57,123,147, 92,246,151,206,157,145,151,151, -135,199, 30,123,204, 52,111,222, 60,209,166, 77,155, 16, 16, 16,128, 11, 23, 46,220,229,121,205,203,203, 67,103,246,237,236,152, -120,110,234, 19, 79, 60,241,209, 75, 47,189, 20,144,153,153,217,180,170,170,234,255,124,125,125,159,177, 5, 6,254,206, 82,158, -227, 66,249,169,207,252,123,211,134,161, 35, 94, 32,159, 38, 3,164,253,179,248,100,205, 59, 84,147,115, 97, 58, 0, 37,254,198, -168,161, 0,204, 85,227,236,103,146,234,236,185,106,251,148,102,254,103,146,146, 63,202,171, 76,186,240, 71, 91,142, 9,242,227, - 63,193,175,174,242, 55, 81, 94,121,113,185,225,104,218,197, 27,123, 10, 53,250,148,185,106, 92,175, 77,201,152,242,175,197,234, -131, 71,210,164, 0, 84, 22, 62, 51,205,199,199,197,178,235,120,255,245,233,208,235,171, 81, 86,105,141, 1, 48,240,124,176,121, -107,221,105,118, 11,242,211,200, 11,207,254,219, 74,150,102,198,114, 54, 97,116, 31,130, 73,179, 86,193,207,207, 7,205,124,197, - 82, 0,170,156, 51, 39,164,235,191,216, 90,231,128, 36,160, 38, 24,136, 85, 9, 0, 33, 48, 83,106, 85, 4, 76,182,229,126,132, - 7,129,197, 2,147, 45, 56,208,157, 18, 80, 82,217, 28,149,213,197, 16, 9,120,246, 52,103, 38, 11, 96, 52, 82, 24, 77, 20, 21, -149, 22, 16, 62,129, 25, 4, 70,203, 29,215,189, 43,152, 45, 60,240,136, 25,196, 76, 64,121,212,238,254, 39,181, 24,207,140,164, -179, 23, 54, 17,119,185,161,207,167,157,175,111,223,177,187, 45,250,244,233,115, 61, 36, 36,228,133,203,151, 47,119, 75, 76, 76, -204, 0,240, 92, 82, 82,210,115,142, 15,175, 88,177, 66,189,112,225, 66,233,138, 21, 43,220, 17,132,189, 66, 98, 99, 99,107,125, -232,197, 87, 94,177,250, 0, 61, 75, 12, 68,157,220,254, 0,128, 65, 61,123, 74, 51, 88,144,191,125, 0, 62,117,202, 30,173, 58, -184, 79, 31, 75,124,124,252,151,227,198,141, 51,101,101,101, 9,174, 92,185,130,206, 45, 90,164,237,216,177,131, 85,128,226, 61, -202, 3,224, 72,238, 55, 83, 82, 82, 28, 99, 60, 78, 59,212,179, 91, 37, 64,185, 98,165, 78,182, 48,238,197, 11,251, 15,164, 53, -247,247,111, 86,166, 45,129,201,100, 2,181,189, 7,218,155, 69, 40,211,106, 65, 41, 69,255,232,104,233,159,201,110,243, 32,153, -112, 39,230,132,103, 91, 14,200, 11, 31,240, 56,198, 72,163,236,171, 0,114, 46, 95,102,173, 4, 68,143,125, 73,146,188,243, 23, -187,149,255,187,242, 59, 21, 0,180, 10, 25, 34,189,149,151,170, 6,128,198, 33,127,122,183, 18,128,111,208, 47,246,125,220,176, - 88,208,119,125, 6, 50, 70,183, 65,175, 29, 55, 33, 32, 64, 83,161,119,123,179,237,216,177,131, 76,124,105, 34, 29, 62,114, 4, -182,109,249, 13, 31,175, 92,129,184,210, 82, 80,139, 5,155, 55,111, 65, 97, 97,225, 51, 0,118,184,147,227, 74, 17, 0,128, 23, - 94,120,225, 36,128,114, 54,101, 89,191,126, 61, 25, 53,106, 20, 61,113,226,132,104,192,128, 1, 24, 49, 98, 4, 84, 42, 21, 30, -121,228, 17, 84, 87, 87, 35, 42, 42, 10,148, 82,203,137, 19, 39,120, 66,161,208,155,140,128,143, 5, 4, 4,172,158, 56,113,162, -240,220,185,115,205,170,171,171,107, 11, 12,100,139,254,193,253, 38,108,232, 55,108, 34,249, 46, 5, 40,171, 4, 12,151,118, 91, - 52, 57,170,105,168, 25, 24,248,208,128,201, 3,224,104,249,187,186,230,210,149,234, 64,254,204,249,249,207, 36, 21,249, 87,110, - 87,164, 1,104,103,123,121,171, 1, 20, 2,200,155,171,134, 91, 23,167,226,235,157,234,161, 67,251, 72,205,180,137,202,241,229, -168,208,149, 89,215,253,243,252,144, 91, 14,178,230,235,141,172,126,224,214,109, 95,144, 91,154, 60, 9,120,122,149, 35, 23, 54, -105, 18, 0,179, 81, 11, 80, 29, 70,247, 97, 55,161,107, 4, 31,160,212, 74,212,224, 67, 68,109,138,128,141,252,173, 57, 0, 1, -152,217,205, 77,164, 29,191, 74,194,122,183,163, 38,163, 6, 2,219,194, 94, 74, 41,204, 38,138, 42, 35, 80, 86,110,130, 17, 20, - 38,202,131, 64, 72,112,251,166,177,214,114, 30, 59,182,146, 0,192,224,200,183, 40, 49, 90,173,127, 10,128, 82, 2, 80,155,197, - 64,249, 32,124, 11, 44, 22, 1,178,115,182,176,250,205,175,126,252,170,244,114,238,229,186, 8, 88, 8,235, 82,141,186,216,201, - 94,243, 75,150, 44, 97,252,163,167,108, 86,241, 29,162,126,241, 69,201,150, 45, 91, 84, 54, 37, 64,229, 78, 9, 88,167, 84, 26, -255, 60,125, 90,214,185, 79, 31,243, 19, 61,122,232,108,125,180,218,230, 16,177, 67, 54,122,180,213,226,232,211,199,253,116,199, - 91,111, 73, 1, 96, 96,247,238,119,221,203,204,202, 82,103,156,247, 94, 25,234,211,179,231,215, 60, 30,207,124,225,216, 49,255, - 54,109,218,220, 78, 45, 40,216,224,206,234,191, 15,172,227,216, 15,116,182,128, 63,102,106,160,194,169,173,217, 40, 1,231,100, - 11,227,194,183,125,251,221,150,144, 46,157, 31,171,174,174,130,217,104,130,197, 98, 65,211,192, 64,148,106, 52, 12,249,179, 81, -162, 74, 62,124,227,223,173, 1, 24,114, 46, 95, 22, 49,243,255,233, 39,254,194, 24,105,148,101, 73,252, 23,238,146, 3,217, 49, -107, 78, 28,189,144,117, 65,234, 72,254, 0, 48,252,169,231,164, 7,246,252,174,190,149,151,234,125, 37,214, 18,224,231,250, 58, -123, 14, 27,248, 71, 17,240,199,235,246,243, 71,127,191, 97, 63, 46, 53,154,189, 46,239,230, 95, 54,147, 33, 67,134, 60, 61,106, -236,232, 93,175, 77,157,113,248,241,190,125,134,110,251,125, 59,210, 78, 30,199,241,227,199,119,214,229, 6,174, 67, 17,152,177, -117,235,214,111,183,110,221, 26,177,117,235, 86,214,133, 27, 53,106,212,240,189,123,247, 30,216,177, 99, 7, 66, 66, 66, 48,114, -228, 72, 4, 4, 4,100,151,150,150,134,158, 61,123, 22,121,121,121, 60,161, 80,136, 81,163, 70, 69,239,221,187,215,211,159,122, -174,180,180,116,229,246,237,219,235, 10, 12,244, 4,127, 22,158, 76, 92,254, 91,210,179,239, 84, 6, 79, 65,229,177,197,150,107, -135,150, 77,173,135,188, 7, 78, 17, 96,237, 1,168, 13,115,213,208, 1,248,203,246,241, 10,135, 15,159, 86,199,198, 46,148, 38, - 40, 62, 86, 5,119,234, 6,160, 26, 66, 31, 49, 10,174,151, 97,227,142, 84,226,185,188,157,234,105,175,206,199,250,239,127, 5, - 44, 87, 0, 8, 96,170,170, 68,112,187, 0,233,178,183,102,176,182,230, 96,182, 64,192,179,192, 72, 4, 16, 82,211, 29, 69, 0, - 38,128,154,193, 54, 48,204, 17,199,207, 92, 39, 0,208, 54,136, 71,133, 2,171,181,111,178, 88, 19, 24,149,148, 83,152, 77, 0, - 95, 96,129,217,196,110,228, 56,146,246, 31, 2, 0,225,131, 22, 80, 48, 57,225,121,128,133, 88,221,253, 89, 57,219, 61, 42,228, -183,239,125,171,110,128,254,197,202, 92, 97,200,223,193, 19,224,118, 57,214,177, 11, 23,146,142, 57,185, 12,235,120,214,237, 51, - 13,153, 58,248, 46,229,214,186,196, 47,193,106, 91,123,183,111, 72, 3,231, 1,112,174, 91,157,155,165, 86,172,250,142,114,197, -202, 11,178,133,113,189, 1,240, 47,164,164, 24,171,244,149,176,152,205,232, 25, 22, 38,109, 23,250, 24,142,253,177,157, 93, 29, - 83, 50,113,207, 31, 59,237,167,131, 31, 11,177, 31,239,249, 99,231, 93,231,117,133,198,127,253,185, 85, 65, 30,241,212,243,210, -115, 23,114,113,253,202,105, 21, 0, 28,216,243,187,170,205, 35,189,165, 55,243,207,120,220,238, 19, 38, 76,128,167,233,125,205, -196,167,206,251,249, 47,180,197, 31,215,170,238,249,128,159,154,154,250,135, 66,161,224,101,102,102, 90,246, 31, 77, 65,139,150, - 45,156, 87,122,120,132,173, 91,183,126,167, 80, 40,126,144,203,229, 70, 79,190,247,230,155,111,170, 0,144,105,211,166,209,220, -220, 92,100,100,100,160,188,188, 60,180,105,211,166,104,209,162,133,125, 47, 0, 47,200,159,193,127, 82, 82, 82,132,105,105,105, -125, 12, 6,195, 98,212,156,203,247, 6,239,158,217,252, 47, 97, 64,215, 31, 22,148,230,238,157,210, 0,242, 26, 21,204, 42, 0, - 87,215,189, 82, 0,220, 14,130, 10,133, 96,237,218,181,238, 93, 85,123,142,168, 59,116, 30, 65,110, 22,164,209,214,193, 29,161, - 41, 55, 97,227,182,195, 94,119,208,245,223,174,182,125,183, 13, 5,110, 34,176,169, 0,203, 22,189,230,209, 75,255,205,209,156, -123,182,129,205, 13,141,133, 0,128,216, 87, 72, 13,149, 70, 88, 0,248,249,249, 65,111,210, 19,179,201,115,121,233, 25,214, 61, - 3,194,159,152, 79, 45,148,143,203,151,118, 53,230,238,102,108,151, 14,114,187, 4,178,168, 31, 71,194,111,224,105, 1, 67, 92, -156,204, 7,128,121,229, 74,165,185, 62,130,148, 43, 86, 50, 27,249,216,219, 52,247,140,103,235,244,231, 44,255,194, 43,101,204, -121, 43, 96, 71,236,223,243,155,218,185,175,221,204,247, 46,127,128,187,141,125,156,117, 96, 19,241, 65, 37,175,238, 21,169,185, -229, 38,132, 54, 21,220,151, 87,197,182, 86,191,193,222, 57, 79,201,191,198,248,236,253,134, 63,108,240,137,193, 96,248, 13,112, -191, 41, 29, 75,188, 93,154,187,119, 35,106,198, 6, 60,212, 74, 0,171,193,199,219,125,132, 57,112,112, 68,183,110,221,144,147, -147,195, 85, 4, 7, 14, 28, 56, 60, 36,224,113, 85,192,161, 33,192,145, 63, 7, 14, 28, 56,112, 10, 0, 7, 14, 28, 56,112,224, -192,129, 83, 0, 56,112,224,192,129, 3, 7, 14,156, 2,192,129, 3, 7, 14, 28, 56,112,104,116,212, 8, 77, 61,121,242,164,215, - 81,155,174,130, 9, 57,121,156, 60, 78,222, 3, 35,175,206,232,112,174,254, 56,121,156,188,191,151, 60,143, 21, 0,135,129,194, - 83,184, 27,120, 26, 82, 30,135, 7, 19,148,107,183,135,178, 29, 88, 63,175, 80, 40,252, 1, 60,113,248,240,225,101,124, 62,127, -176,143,143, 15,244,122,253,145,161, 67,135,190, 11, 32, 67, 46,151,235, 31,132, 10,176,101,135, 84,253,147,199, 21, 74, 41, 61, -115,230, 12,250,244,233,195,189,147, 28, 60, 82, 0, 60, 90,135,204, 38, 81,142, 43,121,142,137, 79, 60,149,247, 15, 28,208, 89, -225,169,167,158,146,238,217,179, 71,205, 86,102,112,112,240, 93, 55, 10, 11, 11,157, 7, 83, 40,149, 74,194,178,140,247, 76, 9, -168, 45,159,127, 99,201, 91,181,106,213,136, 45, 91,182, 36,103,103,103, 3, 0, 66, 66, 66,158, 77, 79, 79,223,238,109,251, 58, -246,123, 74,169,253,253, 96,174, 51,239,138,237, 58,113,163, 60,179,109, 7, 79,200,255,177, 51,103,206,108, 41, 43, 43,235,209, -169, 83, 39,220,190,125, 27, 85, 85, 85, 0, 48,120,203,150, 45, 42,127,127,255, 11, 10,133,226,121,185, 92, 94,231, 86,146,103, -206,156,241,200, 32, 72, 77, 77,149,202,229,114,181, 39,223, 81, 42,149, 42,153, 76, 38,245, 38, 1, 20,245, 48, 9,195,132, 9, - 19, 60,121, 63, 0, 0,157, 58, 89,119,192, 45, 47, 47, 71,117,181, 53, 13,186, 78,167,243,228,125,171, 19,167, 79,159,166,131, - 7, 15, 70,207,158, 61,225,227,227, 83, 84, 93, 93,253, 8, 55,140,254,243,224,156, 12,232,158, 37, 2,226,172,216,123,139,223, - 19, 70,187,125,230,249,153,187, 61,146,169, 82,221, 49,144,178,179,179,225,239,239,111, 31,132, 24,176,217,252, 67, 38,147, 81, -165, 82,233,124, 78,106,121,198,171,186,141,138,186,179,157,171, 43,249,245, 1, 33,132, 14, 27, 54, 76,154,146,146,226, 17, 89, -108,217,178, 37,185,117,235,214,120,249,229,151,161,213,106, 45,241,241,241,219, 86,172, 88, 49,105,225,194,133,155, 61,252,255, -248,227,143, 63,236,231,163, 71,143,198,238,221,187,235, 60,103, 35,214,169, 47,211,176,176, 48, 0,160, 14,153,225, 60, 34,255, -210,210,210,180,174, 93,187, 54, 3, 0,177, 88, 12, 95, 95, 95, 20, 21, 21,161,164,164, 4, 1, 1, 1, 40, 42, 42,234,177,123, -247,238, 12,133, 66,209, 93, 46,151,223,168, 75, 94,239,222,189, 33,147,201, 16, 18,114, 39,235,223,202,149, 43,107, 60, 19, 23, - 23, 7, 0, 56,122,244,168,202,155,126, 83,159,236,143,107,214,172,169,237,150,125,175, 2,111,225,239,239,143,115,231,206, 65, - 40, 20,194, 96, 48, 96,247,238,221,200,201,201,193,162, 69,245,219,113, 54, 48, 48,144, 15, 32,250,224,193,131,187,163,162,162, -110, 62,255,252,243,109,146,147,147,193,231,243, 91, 53,111,222,156, 15, 14,255,104,242,103,174, 57, 43, 1,127,155, 32,192,240, -240,112,201,253,182,184, 27, 19,193, 3,151,218, 63,222, 66,171,213,218, 45,126,157, 78,135,117,235,214,217, 63, 30, 12,180, 46, -207,199,143, 31, 79,101, 50, 25, 5, 64,157,159,241, 20, 7, 15, 30, 84,189,245,214, 91,232,210,165, 75,131,213, 95,231,206,157, -201,219,111,191, 13, 74, 41, 82, 82, 82, 84,158,182,123,118,118, 54, 70,143, 30,109, 1, 0,145, 72,196, 11, 13, 13, 69,124,124, -252,166, 86,173, 90,209,240,240,240, 49, 30, 88,156,247,170,139,144,176,176, 48,202,252,174,227,199,143, 51,251, 1, 48,237,194, -218,237,175,213,106,183,136, 68,162,102, 0, 48,123,246,108, 76,153, 50, 5, 34,145, 8,190,190,190, 16,139,197, 32,132,128,207, -231,163,180,180,180, 25,128,120,133, 66, 81,167,236,184,184, 56,132,132,132, 32, 47, 47,207,254,137,139,139,171,241,169, 15,100, - 50,153,212,246, 59,189, 30, 19,230,207,159,111,255, 56,142,151, 78,215, 45,108,229,117,234,212, 9,254,254,254, 88,188,120, 49, -252,253,253,177,109,219, 54, 84, 86, 86, 54, 8,249,219,222,101,170,213,106,255,111,234,212,169,232,214,173, 91,155,221,187,119, -227,230,205,155,184,122,245, 42, 74, 74, 74, 12,247,115,108, 82, 40, 20,146,130,130, 2,170, 80, 40, 36,174,238,229,228,228,208, -139, 23, 47,114, 9,232,238, 3,249,199,196,173, 64, 76,220,138, 90, 21,131,251,162, 0, 16, 23,168,235,186, 55, 72, 79, 79, 87, - 53,132, 18, 48,101,202,148,135, 70, 9,168, 47,244,122,253, 93, 86,191, 55,205,203,144,201,248,241,227,237, 86,126, 82, 82, 18, -234, 75,252,142,214,191, 82,169, 36,195,134, 13,147, 42,149,202, 26, 30,129,250, 32, 49, 49,145, 0, 32, 81, 81, 81, 82,103, 79, - 3,203, 65,215,100,243, 6,160,117,235,214, 88,186,116,105,213, 27,111,188, 97,200,203,203,219,185, 98,197,138,145,141,221,190, - 14,123, 0, 16,199,118,242,176, 93,158,200,201,201,233, 1, 0, 51,102,204, 64,105,105, 41,174, 93,187, 6,161, 80, 8,129, 64, - 0,129, 64, 0,161, 80, 8, 95, 95, 95, 84, 86, 86, 34, 57, 57,121, 50,128, 64,119, 66,243,242,242,160, 84, 42,237, 31, 71, 79, -192,202,149, 43,145,156,156,236,245,239, 86, 42,149,106,219, 20,128,170,129,222,229,218, 18,119,179, 30, 63, 47, 95,190,140,157, - 59,119, 98,233,210,165,232,212,169, 19, 90,182,108,137,148,148, 20, 44, 90,180, 8,254,254,254, 0, 0, 62,191, 94,134,122,187, -233,211,167, 79,252,207,127,254,131,244,244,116, 92,187,118, 13, 38,147,233,229, 22, 45, 90, 4, 2, 48,222,239,190, 23, 28, 28, -140,152,152, 24, 85,110,110, 46,117, 36,255,152,152, 24,213,163,143, 62, 10,179,217, 12, 14,247, 22,142,196,239,120,220, 24, 30, - 0,234,226, 83,215,245, 70, 83, 2,198,140, 25,211, 16, 74, 0,245,224,195, 26, 47,190,190,167,193, 26, 36, 59, 59, 27, 58,157, -174, 86, 55,255,145, 35, 71, 26, 66, 49,168, 55, 14, 30, 60,168,178, 41, 22, 72, 73, 73, 81, 19, 66,208,186,117,107, 85, 67,118, - 78,198,253,111,243, 4,212,137, 85,171, 86,141, 25, 50,100, 8, 5,128,248,248,120,209,247,223,127,143,151, 95,126,153,113,205, -139,255,250,235, 47,145,237,222,222,240,240,240,231,216,252,255,209,163, 71,227,233,167,159,182,187,247,153, 99,230,156, 57,102, -233,254, 7, 0,216,172,127, 87,237, 64,156,238,215,137,221,187,119, 47,107,217,178, 37, 0,224,226,197,139,200,207,207,199,137, - 19, 39, 96, 48, 24, 64, 8,129, 64, 32, 0, 33, 4,102,179, 25,122,189, 30, 91,183,110, 5,128,190,158,120,142,100, 50,153, 75, -229, 37, 47, 47,175, 94, 74,128,195,111,175,151, 55, 0, 13, 48, 85,106, 52, 26, 49, 96,192, 0,168,213,106, 92,190,124, 25, 3, - 7, 14,180,223, 83,171,213, 8, 10, 10,178, 43, 2, 94,160,253,244,233,211, 11,190,251,238, 59, 68, 71, 91, 55, 50,106,223,190, - 61,204,102,243,143, 0, 74,238, 55,241,200,229,114, 53,163,124,134,132,132,224,216,177, 99,148, 33,127, 70,249,235,222,189, 59, -155,241, 97, 16,128, 31, 96,221,243,172, 46,140, 5, 16, 3,160, 21, 71,251,247,185, 99,179, 98,195,251, 24, 4,104, 83, 2,164, -233,233,233,106,111,101,116,238,220, 25, 83,166, 76,193,207, 63,255,236,109, 76, 0, 1, 64,127,254,249,103,151, 55,119,237,218, - 5,219, 61,143,101, 31,189,244, 24, 34,186,156, 67, 97,230,226,122,213,147,227,156,127,114,114, 50,162,163,163, 17, 19, 19, 99, - 39,255,142, 29, 59, 54,132,210, 87, 47, 69, 32, 42, 42, 74,114,240,224, 65,220,190,125, 91,202, 92,147, 72, 36, 82,165, 82,169, -138,138,138,146,120, 58,111,239,230,127, 73,217, 40, 0, 91,182,108,217,201,204,253,235,116, 58,172, 92,185, 18, 21, 21, 21, 16, - 10,133,240,241,241,193,165, 75,151,176,116,233, 82,104,181, 90,196,199,199,255,182, 98,197,138,225, 11, 23, 46, 84,185, 33,217, - 26,202,128,187,152, 0, 22,117, 14, 55, 59, 0,218,167, 3,220,253,222,160,160,160,193,213,213,213, 48,153, 76, 56,114,228, 8, -248,124, 62, 12, 6, 3, 42, 43, 43, 97,177, 88,236,239,177,209,104, 68,117,117, 53,243, 78,247,118, 39,183, 54, 55,127, 92, 92, -156, 61, 30, 32, 36, 36, 4, 69, 69, 69,245, 86, 68, 29, 86, 5,176,237,139, 26, 0, 65,174,110,172, 94,189,218,171, 66,196,199, -199,227,173,183,222, 66,255,254,253,237, 30, 16, 38,125,118,255,254,253,145,149,149,133,214,173, 91,123, 35,186,211,244,233,211, - 47,127,247,221,119,142,227,103,240,181,107,215,174, 53, 38,177, 12, 28, 56,144, 48,164, 63,112,224, 64, 12, 28, 56, 80, 5, 0, - 89, 89, 89,232,209,163, 7,219,118, 56, 9,192, 23,192, 38, 0,147,224,180, 37,184, 13,175, 3,248,194,118,252, 46,128, 30,128, -251, 45,234,255,206, 96,118, 3, 92,183,114,161,221,242, 95,183,114,161,253,222,125, 87, 0,238, 55, 30, 20, 37, 96,202,148, 41, -244,221,119,223,189,203, 21,232, 13,249, 55,164,245, 15,192,165,245,207, 88,253, 66,161, 16, 55,110,220,104, 84,242,119,180,254, - 29, 3,186, 84, 42,149,163, 23,224,190, 7,108,102,103,103,227,229,151, 95,214, 3,240,243,247,247,199,123,239,189, 7,161, 80, -104,191, 63,109,218, 52, 0, 64, 96, 96, 32,198,141, 27,135,195,135, 15, 31,184,143,229, 36,142, 30,128,186,148,128,176,176, 48, -231,173, 98, 93, 42, 3, 6,131, 1, 26,141, 6, 85, 85, 85, 8, 8, 8,128,143,143, 15, 76, 38, 19, 40,165, 48,155,205, 48, 24, - 12, 48, 26,141, 48,155,205,142, 10,253,237,186, 10,153,151,151, 87, 35, 0,144,153, 14,112,244, 8, 56,222,175, 47,188, 8, 8, - 20,215,118,195, 49, 38,192, 19,101, 96,233,210,165, 24, 59,118, 44, 58,119,238, 12, 63, 63, 63, 72, 36, 18,104, 52, 26,248,251, -251, 67,171,213, 98,253,250,245,224,241, 60,118,200,118,152, 62,125,250,229,121,243,230, 97,219,182,109,120,238,185,231, 0,160, - 45,128,155, 15,194, 56, 44,151,203,213, 1, 1, 1,210,137, 19, 39,170, 0, 96,243,230,205,210, 73,147, 38,121,210, 22, 6, 0, - 83, 0,252, 92,135, 18,224, 56,213,246, 8,128, 62, 0, 50, 56,219, 30, 53,136,191, 54,252, 45, 51, 1,214,151,252, 25,120,107, -165, 59, 14,200,203,150, 45,171, 55,249, 51, 24,208,191, 31,246, 31, 80, 97,227, 1, 63,187, 82,112,244,210, 99,245,250,141, 97, - 97, 97,200,203,203, 67, 82, 82, 18, 58,118,236,136, 13, 27, 54,120,108,117, 41, 20, 9, 18, 7, 15, 78,131,144, 63, 51, 31, 95, - 84, 84, 36,117,190, 55,108,216, 48,105, 82, 82, 82,131,197, 2, 0, 86,247, 63, 91,239,147, 86,171, 61, 15,235,188,176,101,243, -230,205, 88,191,126, 61, 0, 96,211,166, 77,208,106,181,204, 99,166,172,172, 44,180,106,213, 56, 94, 73,167,104,255,187,148, 51, -182,251,196,231,229,229, 29, 49,155,205,208,106,181,184,125,251, 54,180, 90, 45,244,122, 61,244,122, 61, 42, 42, 42, 80, 86, 86, -134,210,210, 82, 84, 86, 86,162,186,186,154,153,219, 77,171, 75,166, 51,185,187, 10, 36,117, 94, 21,192, 22, 54, 87, 63,117,113, -205, 19,248, 53,116,123,108,216,176, 1, 18,137, 4,126,126,126, 56,119,238, 28,212,106, 53,252,253,253,241,254,251,239,227,240, -225,195, 88,180,104,145,167, 10, 64,219,233,211,167, 95,157, 52,105, 18,126,253,245, 87,134,252,219, 63, 40,228,111, 29, 23, 20, - 18,134,252, 1, 96,226,196,137,170, 11, 23, 46,120, 58,181,202, 40, 1,176, 41, 1,206,211, 1, 23, 29,142,243, 1,156,230,104, -255, 14,156,131, 0, 27, 69, 1,184, 31, 65,128, 13, 77,254, 54,226,110, 8,203,141, 44, 91,182,172, 94,228,255,226,235,123, 48, -160,255, 29,215,205,150, 95,183,218, 61, 2,251, 15,168,188, 82, 2,228,114, 57,108, 75,195,160,215,235,177,111,223, 62, 44, 93, -106, 93, 81,112,250,244,105,152, 76, 38, 15,100,197,170, 1,107,224, 31,165,148, 9, 6,172, 23,249, 51,214,127, 93,110,254,134, -138, 5, 96, 20, 9,137, 68, 34,117,247,108, 72, 72,200,168,248,248,248,176,244,244,116,193, 15, 63,252,192,187,112,225, 2,166, - 77,155,102, 98,234, 49, 62, 62, 30,233,233,233,248,225,135, 31, 4, 87,174, 92, 65,120,120,184, 91,153,247, 34, 6,128,177,164, -157,148, 0,202, 40,125,108, 17, 26, 26,154,105, 50,153, 96, 48, 24,112,235,214, 45,220,184,113, 3, 55,111,222,196,205,155, 55, -113,235,214, 45,104, 52, 26,232,245,122, 84, 87, 87,163,180,180,148,249,159, 5,117,201,100, 2,253, 28,149,208, 58,202,238, 17, -249, 51, 57, 0,156,175,213,167,127,184, 88, 13, 96, 87,242,216,202,200,201,201, 65, 86, 86, 22,244,122, 61, 34, 35, 35,209,183, -111, 95,108,216,176, 1,239,188,243, 14, 68, 34, 17,248,124, 62, 4, 2,214, 14,217, 14,211,167, 79,191, 62,105,210, 36,100,100, -100,224,131, 15, 62, 96,172,223,235,120, 64,150, 49,103,102,102, 82,102,206,255,196,137, 19, 88,183,110,157, 20, 0,186,119,239, - 14,199,192,192,122, 42, 1,115, 97,157,255, 31, 15, 96, 22,128,112,252,195,221,255,192,157, 72,127, 87, 65,128,206,171, 0,238, -215, 20, 0,245,240,250,223,133,252,237, 74, 64, 61,166, 18,106,144,191,171,243,253, 7, 60, 31,223, 28, 7, 93, 63, 63, 63,244, -236,217,179,198,253,244,244,116,143,228,141, 31, 63, 30, 73, 73, 73, 96, 20, 1, 0,212,118,205,227,117,231, 27, 54,108, 80, 1, -192,238,221,187,165,174, 34,214, 83, 82, 82,212,151, 47, 95,118,105, 61,186, 66,109, 73,127, 24, 69, 35, 37, 37, 5, 81, 81, 81, - 82,149, 74,229,182,239,164,167,167,239, 91,190,124,249,136,212,212,212,253,161,161,161,200,206,206,134, 86,171, 21, 4, 6, 6, - 98,250,244,233,208,104, 52, 87, 82, 83, 83, 59,133,134,134, 34, 53, 53,149,196,198,198,186, 83,142,239,154,243,175, 71, 12, 64, -141,119,139,201,151, 96,203,157, 96,247,204, 56,204,255,187,109,143,136,136,136,119,212,106,245, 28,179,217,140,178,178, 50, 24, -141, 70,251,188,127, 85, 85, 21, 40,165,160,148, 34, 43, 43, 11, 6,131, 1,209,209,209, 47,201,229,114,147,171,164, 35,181, 33, - 58, 58, 26,209,209,209, 53,130,254, 60,157, 2,112, 36,122,155,203,159, 58,246, 15,219,170,128,134, 30,215, 88,143,159,204, 82, -191, 55,222,120, 3,106,181, 26, 82,169, 20, 57, 57, 57,104,210,164, 9,242,243,243,193,231,243,217,122, 0,200,244,233,211,175, - 78,157, 58, 21,135, 14, 29,194,251,239,191, 15, 0,193, 0,174,225, 78,254,135, 70,183,252,153,241, 37, 47, 47, 15, 97, 97, 97, - 76, 63,147,198,196,196,168, 66, 66, 66,144,149,149, 69, 89, 6, 2, 58, 42, 1,147,108, 10,192, 38, 0, 71, 0,200, 1, 72, 0, -220, 0,135,134,235,192, 13,157,141,207, 85,192,207,202,149, 43,107,189,222,152,228,111, 91, 1,112, 47,180,104,175,101, 94, 45, -112,223,191,125,125, 61,243, 90,186, 11, 18,243, 20,209,209,209,210,164,164, 36,245,132, 9, 19,104, 98, 98, 98, 13, 69,192, 73, -225, 99, 93, 15,177,177,177,110, 53, 27, 15, 19, 3, 81, 39, 69,194, 58, 42, 73,165,172,200,223, 97, 48,183,207,235,135,135,135, -255, 43, 62, 62,254,199,113,227,198, 33, 43, 43, 11, 87,174, 92,233,180,120,241, 98,105,108,108, 44, 43,121,247, 40, 15, 64,141, -122,174,133,248, 88,101, 12,148,203,229,186,132,132,132, 37,187,118,237,250,208,100, 50,161,164,164,196, 30, 3, 0, 0,183,110, -221, 66, 73, 73, 9, 40,165,140,213,238, 17,203, 50,243,255, 97, 97, 97,246, 8,118,230, 58, 91, 37,192,133,149,127,215, 52,212, - 61, 32,127,143,193, 40, 1, 11, 23, 46, 68, 74, 74, 10,198,141, 27,135,229,203,151,227,205, 55,223,132, 64, 32,128, 88, 44,118, - 59,134, 80, 74, 45, 51,102,204,192,143, 63,254,136,239,191,255, 30, 0, 58,218,200,191,193, 13,170,250,160,176,176, 16, 59,119, -238,172,145,197,209,118, 44, 29, 62,124,184,202,203, 37,143,102,155, 18,176,195,102,253, 71,112,228, 95, 59, 92, 5, 1,178, 82, - 0, 60, 73,196,225, 45, 97, 55, 52, 26,130,252,235, 75,212,247, 2,115,231,206,149, 94,184,112,161, 65,101,218, 92,164, 13,186, -148,142, 33, 60,219,218,122,198, 43, 64, 9, 33,176, 88, 44,216,178,101, 11,107, 37,224,173,183,222, 98,202,121, 87, 12, 0,143, -199,131,197, 98,193,219,111,191,173, 98, 75,158,117,201, 75, 73, 73, 81, 59,102, 69,244,162,223,253,180,124,249,242, 91,169,169, -169,187,217, 90,253,247,193,219, 70,156,189, 61,181, 40,124,172,148,128,216,216,216,143, 20, 10, 69,210,207, 63,255,124, 86, 36, - 18,129, 89, 21, 96,177, 88,208,188,121,115,104,181, 90,200,100, 50, 68, 71, 71,251,201,229,114,183, 11,188,153,241,197, 49,248, -239,248,241,227,136,142,142,174, 49,158,184, 27,135,226,226,226,104, 94, 94,158,212,217,197,239,109, 26, 96, 71,184, 8,240, 51, - 1, 48,173, 94,189, 90,108,179, 70,121, 14, 31,143,148, 0,199,196, 63,179,102,205,178, 31,151,149,149,185, 29,155, 8, 33,100, -250,244,233,244,135, 31,126,120, 30,192,239, 15, 34,241,216,136,158,120,122,143,141,210,238,132,235, 15,195, 24,126,191,193,172, - 2,112, 69,252,172, 86, 1, 52, 52,169,215, 38,239, 65, 81, 30, 30,228,142,243,217,103,159,169, 27, 90,166,211, 26,233,123, 6, - 39,247, 63,219,151,154,109, 46,116,226,193,239,189,167,191,117,209,162, 69,123,234, 83,159,163, 71,143,174,177, 44,246,233,167, -159,174,225, 25,240,112,238,159,120,232,237, 97, 85,110,185, 92,126, 78,161, 80, 52,217,187,119,239, 39,249,249,249,115, 42, 43, - 43, 97, 54,155,209,175, 95, 63, 12, 28, 56, 48, 62, 58, 58, 58,142, 13,249, 3,192,209,163, 71,237,199, 81, 81, 81, 53,174, 59, -159,187, 25, 87,136,163, 66,203, 40, 19,182, 56, 0,175,218,125,194,132, 9,181,221, 18, 56,140,151,162,123, 53,174,184,241, 84, - 88, 0,224,251,239,191,231, 54, 76,225,192, 90, 9,168,141,252,107, 83, 0, 26,186,115,113,157,149, 3,241, 80,179,255,199,213, -141, 35,225,223,131,105,129, 6,121, 7,229,114,185, 14, 86,215,235, 92,230,218,249,243,231,217, 16,151, 29,189,123,247,110,240, -241,192,149, 66,235,173,203,255, 94, 43,139, 28, 56,254,184,159, 74,128,219,202,245,118, 31, 97, 14, 28, 56,112,224,192,129,195, -195, 11, 30, 87, 5, 28, 56,112,224,192,129, 3,167, 0,112,224,192,129, 3, 7, 14, 28, 56, 5,128, 3, 7, 14, 28, 56, 60,132, - 48,193,131,237,138, 57,255,124,202,173, 0, 0, 32, 0, 73, 68, 65, 84,252, 51, 33,224,170,128, 3, 7, 14, 28,184,177,157,195, - 63,188,147,156, 60,121,210,235,136, 75, 87,193,132,110,228,213,185,254,216, 11,121, 13, 93, 62, 78, 30, 39,239, 31, 45,239,207, -119,174,120, 61,176,244,255,164, 19,238,181,188,227,139,188,151, 23,182,252,110,121, 76,253, 41, 20, 10,137,209,104,196,165, 75, -151, 84, 6,131, 1, 2,129, 0, 5, 5, 5,120, 41,160, 51,246,100,102,162,242,241,142,136,136,136,144,242,249,124,102, 93,123, -163,181,175, 66,161,120, 12, 64,235,179,103,207,238,108,223,190, 61, 79,163,209,136,219,183,111,191,212,215,215,119,173, 92, 46, -191, 6, 0, 9, 9, 9,188,132,132, 4,115,109,242, 18, 18, 18,154,218,188, 5,250,216,216, 88, 10, 0,139,255,253,228, 55,242, - 39,243,167,111,204, 12,189, 36,104, 61, 42,162, 73,211,102, 21, 0, 40,165, 84, 0, 32, 48, 33, 33,225, 42,247,190, 61,216,242, -238,181,150,200,118,211, 23, 79, 83,224,122,156, 50,119,101,228, 83, 18, 65, 80,128, 42, 55,251,162,244, 81,159, 38, 88,112,230, -160,250, 65,210,178,234,200, 71,206, 45,113,105,100,140, 29, 59, 86,178,107,215, 46, 85,252, 59,214,243,223, 14, 61,137,131, 7, - 15,178,106,151,127, 77,123, 69,194, 35, 68,149,117,225, 2,180, 90, 45, 58,117,234,132, 38, 77,155, 98,107,210, 22,214,237, 58, -126,252,248, 26, 47,110, 82, 82, 82,157,123, 41,216,178, 43,122,213,111,152,141,154, 40,165,245,235,119, 50, 77,205, 87, 85, 25, -228,189,172,176,213, 64,200, 43,214,227,188,245,192,241, 5,245,111,212,241,183,107,150, 47,169, 37,171,175, 41, 20, 10,170,211, -233,164, 91,183,110, 85,229,229,229, 65, 38,108,129,182, 29, 91,161, 74, 87, 9, 95,189, 9, 67,222,124, 13,195,198, 77,196,142, -239, 18,176,125,255,126,213,168, 81,163,164, 15, 64, 23,206, 54,155,205,237,242,242,242, 44,125,251,246, 21,133,134,134,226,196, -137, 19,239, 84, 85, 85,141, 85, 40, 20,209,114,185, 92, 19, 27, 27,107,169,107, 73, 88,108,108,108,185,227,249, 87, 95,125,197, -219,253, 83, 92,183, 14, 51,250,227,237, 65,189, 90, 29,221,251,223,196, 45,167, 37, 39,187,245, 30,190,156, 16,162,145,203,229, - 5,253,250,245,179,216,148, 6,206,211,240, 15,115, 19,121,170,105,176,202, 54,230, 13,249,127, 29,245,172, 36,178, 85, 7, 21, - 1, 69, 78, 69, 9,218,181,239,172, 50, 90,204, 88,212,103, 48,138, 58,181,146,126,183,227,119, 86,138, 64,204, 36,208, 30, 93, -153, 51, 62,182,238,181,224,208, 49,138,152, 73, 64,143,174,192,130,101,245, 35,110,102,131,146,250,102, 39,115,165, 76, 52,148, -220,250,128, 82, 74,177,132,128,124, 84,231, 51,192, 18,130, 9,231,101, 15,204, 90,235, 59,228, 79,109,228, 63, 12,135, 15, 31, -102,245,221,180,163, 47, 82,147,177, 7,148,202,235, 72, 79,179, 38,172,201,190,144, 5, 0,216,185,147,208,172,139,227,165, 11, -230,178,107,151,145, 35, 71, 90,246,237,219,199, 75, 74, 74,194,129, 3, 7,106, 36,195,113,134,151, 41, 84,237,205,228,162, 35, - 83,234,133, 66,193,164, 11,175,119,206,130,144, 87,236, 27,237,172, 94,189,186, 97, 20, 0,135,122,178,237, 78,200, 10,185,185, -185, 80, 39, 38,170, 62,138,158,128,126, 83,102, 65,212, 38, 16, 16,216,146,253, 89, 40, 96, 17,194, 82, 77, 49,230,149, 24,228, -127,190, 2, 71,142, 28, 81, 41, 20,138, 26,233,110, 27, 1,102, 30,143,215,186,101,203,150, 80,171,213,130,190,125,251, 98,208, -160, 65,188, 27, 55,110,244, 63,117,234,212, 25,133, 66, 49, 64, 46,151,223,176,145, 53,143,101,221, 53, 25, 49,124,100,200,242, - 85,219,120,113,211, 78, 55,139, 24, 61, 83, 26, 17,158,252,228,155, 95, 20, 60, 19,250,196,203, 97, 0,202, 97,141, 49,224,213, -198, 15,142,137,173,220,245,163,122, 43,164, 28,156, 61, 9,238,188, 5,246, 99, 79,130, 0, 41,211,184,253, 94,238, 3,133, 66, -193,243,128, 8,157, 55,169,160, 97, 97, 97, 8, 11, 11,243, 58, 79,188, 98,114,140,100,114,255, 72, 85,247,118,193,232,218, 46, - 24,143,183,106,143, 96,223, 38, 16, 91,128, 46, 62, 77, 16,144,115, 77, 53,253,153,231, 36,108,100,245,232, 10, 92,200,229,225, -252, 69, 63,156,201,109,134,231, 71,250, 99,213,187,124,244,232, 74, 26,204, 72,175, 47, 73, 51,219,156,134,132,132,168, 50, 51, - 51,145,153,153,137, 15,127, 58,133, 71,199,196,169, 0, 80, 15,183, 60,165,108, 63, 50,153,204,253, 91,188,196, 90, 71, 97, 97, - 97,144,201,100, 46, 63,204, 51,158, 98, 92,223, 15, 36,142,229, 25,219,103,137,164, 33,218, 99,236,216,177,146,157, 59,119,170, - 8, 33,120,227, 19,130,223, 14, 13,195,161, 67,135, 88,125, 55, 49,113,138, 36, 34, 60, 22, 67,135, 94,199,231,159,127, 94,227, -222,228,201,192,152, 49,192,252, 57, 73,170, 85,159,177,107, 19,134,252,213,106, 53,120, 60, 30, 38, 78,156, 8, 62,159, 95, 31, -178,191,203,242,119, 53, 32, 19,226, 29,249, 55, 24,194, 86, 1, 0,214,172, 89,131, 53,107,214, 88,175, 13,136,111,180,226, 28, - 56,112, 0, 95,189, 16,131,129,207,201, 32,104, 17, 4, 34,228,131, 39,228,131, 47, 22,129,231, 43, 6, 64, 65,205, 38, 80,131, - 1,175,189, 50, 11,101,251, 51,145,155,155,171, 82, 40, 20, 18, 52, 30, 72,102,102,102,100,199,142, 29, 69, 22,139, 5, 41, 41, - 41,216,182,109, 27, 2, 2, 2, 16, 25, 25,217,110,243,230,205, 31,219,158, 99, 21, 16,168, 80, 40,248,135,247,255,242,191, 71, -252, 10,218,232,202,249,152,188,164, 2, 95,254,247, 51,160,105,111,193,127,227, 90,119,201, 61,241,243,100, 7,238,224,213,162, - 24, 18, 7, 82, 39,214,203,196,126,236,120,253, 30,237,133,193,161,129, 61, 0,246, 86,218,184,251,231,146,174,143,118,109, 46, -255,232, 53,139,135,236, 72,194,194,194, 40,147,150,212, 33, 61, 41,245, 52,109,167,226,133, 87, 36, 79,117,124, 84, 37,170, 50, -193,247,191,111,193,164, 55, 64,252,198, 50, 4,136,196,168, 18, 86, 66, 87, 85, 9, 95, 16, 84, 95, 45, 82,125,250,233,167,210, -183,223,126,187, 78,242,189,144, 11,172,219,100, 1,160,183,125,128, 39,159,224,225,133, 81,164,198,123, 19, 51, 9, 88,183,201, - 43,242,150, 42,149, 74,234,173,181,206, 88,253,153,153,153,119,234,224,176, 17,149, 6, 29, 0, 96, 68,220, 62, 40, 87,142,244, -200,203,144,187, 34, 23, 66,146,115,167, 35,144, 66,144,150, 61, 28,206,139,208,234,255, 94, 96,215,176, 31,217,243,205,147,218, -210,206, 18,155,210,119,252, 56,187,118,150, 63,251,165,100,221,182,127,171,182,159,250, 0,203,231,253,134,112, 73, 40, 54,126, -125, 8,223,238,181,110, 16, 52,243, 95, 31, 72,215,254,244,129, 87, 74, 85,252, 59,160,192, 78, 40,127, 56, 11, 74, 41,154,182, -126, 28,135, 14, 29,130,109,223,130, 58,203,183,234, 51,153, 68, 38,107,161, 2,190, 2,240, 27,210,211,129,240,240, 59,247, 63, -254,248,206,241,252, 57, 73, 42, 95,191,197,210,153,175, 45,173,179,156, 12,249, 71, 69, 69,193, 98,177,224,203, 47,191,108, 80, - 7, 13, 0, 88, 44,150,187,201,159,214,253,254,242, 38,104,107,188,252,204, 16,110,145,185,120,206,238,231,179, 30,244,237,123, -247, 28, 59,111,162,182,134,154,111,177, 76,195,188,121,243,236,247,231,205,155,135, 53,107,214,128,215,109,198,157,255,106,123, -222,149, 60,193, 68,215,229,115,222,201, 90, 48,145, 93,249,170,170,170,208,182, 83,103,192, 98, 0,207, 7, 32, 2, 62, 76,229, -165,168,202,187,132, 91, 5,133,232, 48, 88, 2, 34,106, 14, 98, 52, 0,124, 30, 86,206,124, 19, 35,215,125,128, 5, 11, 22, 52, -244,184,204,138, 21, 21, 10, 5,161,148, 54,175,172,172, 28, 28, 20, 20,132,172,172, 44, 88, 44, 22, 92,186,116, 9,235,215,175, - 71,207,158, 61, 17, 28, 28,252, 50,128,215,156,200,186, 86,111, 0,165,180,101, 39, 94,186,164,221, 35,163, 69, 37, 41,167, 81, -170,245,193,143, 59, 76,216,117,244, 39,204,145,249, 10, 4,122, 75,152, 45,166,192,165, 2,192, 17,122,227,163,182,233, 30, 87, -158, 1, 30,139,142,200,204, 27, 66,178,104, 24,214,165, 40,154,231, 94,204,197,201, 31, 78, 67,161, 80,120,100, 61, 48,228,160, -215,255, 12,189,126, 35, 52,154,104,198, 58,246,232, 7, 14,242,105,166,106, 93,101,134,120,201, 44,152,111,107, 96,186,120, 25, - 2,145, 16,126,132, 15,127,194,135, 63, 95,128, 32,161, 24,180, 92,135,235, 7,142,184,221,233,197, 21,169, 31, 58,102,177,191, -135,171,222, 37,136, 95, 76,108, 30, 1,239,172,127, 27, 57,171,224, 69, 10, 92,103,242,135,128,143,188,235, 21,184, 94,108, 64, -250, 57,235, 6, 34,221,166,109,135, 39,251,158, 11, 73, 14, 4,164, 16, 62,188, 83,214,191,173, 9, 2, 39, 95, 67,192,164, 51, -240,121,126, 9, 16,236,239,153, 39,151,197,206,109,158,108,241,170,216,246,186, 42, 34,232, 93, 28, 63,120, 9,255,111,252, 56, - 4,183,236,142, 89,255,126, 21, 95, 44,222,139,136,192,197, 88,251,211,135, 94,239,224, 67, 8, 16,187,224,140,221, 98, 25, 58, -116,168,141,144, 44,110, 27,120,202, 36,161, 10, 56, 0,224, 55,148,220,108,130,110,143, 52,193, 55,223, 88, 45,255, 37, 75,128, -144, 16,171,136,146,155, 77, 80,114,179, 9,250,245, 57,175,114, 71,254, 7, 14, 28,128,197, 98,177,147,244,230,205,155, 97, 54, -155, 61,114, 95,215,225,225,185,139,252,173,239,179,123,229,157, 2,100,173, 66, 33,101, 44, 53, 11,165,176, 88,238,238,190,204, -117, 11,165, 88,155,144, 32, 77,176,126,199,229,255,164, 0,161, 20, 36, 33, 65, 33,165,148,226,179,207, 62,179,223,103,142, 19, - 18, 18,164,148, 90,159,163, 0,169, 77, 94,130, 66, 1,219, 61, 98, 54,155, 97, 50,155, 97, 50,221, 93,103,204,117,147,217,140, -175,215,174,149,174, 77, 72,168,165,124, 20,130,166, 77, 1, 33, 31,102,125, 5,206,110, 73,194,251,175,202,209,225,117, 57,250, -175,248, 8,151,254, 60, 1,190,175, 24,198,226,155, 56,125, 84,141,237,135,246,160,244,198, 13,156, 57,115,166,193, 54,214,138, -140,140,100,229, 77, 80, 40, 20, 1,148,210, 65,153,153,153,191,191,247,222,123,189,206,158, 61, 43, 50, 24, 12,224,243,249,104, -218,180, 41, 76, 38, 19, 50, 50, 50, 64, 8, 17,185, 27,235, 19, 18, 18,252, 21, 10,133,111, 66, 66, 66,112, 73, 65,234,159, 31, -254, 47, 63,232,175, 67, 59,160,209,241, 32, 18,240,208, 33, 80,140,210,219, 34,200, 63, 53,225,244,237,254,254,238,120,195, 22, -107, 66, 29,251,162, 77, 49,184,235, 58, 71,215,247, 7, 12,249, 59, 43, 7, 60,119, 90, 40,179,223,119, 13, 55,231,232, 41,158, -123,251,108,238,126,189,126, 35, 0,130,170,170,239, 33, 62,118, 25,250, 61,143,214,184,239, 14,111, 15,136,146, 4,104,202, 97, - 17, 9, 96, 56,126, 22,213,231,243, 80,181,247, 16, 80, 89, 13, 17,165,240, 3, 31, 2, 16, 84, 91, 76,208, 84, 87,225,235,125, - 59,220,202, 92,245,174,213,186,119,132,245,156, 49, 87, 40,178, 46, 82, 44, 88,230,125,127,117,202, 87,206,218,101, 47,147,201, -236,123,107, 51,120,105, 77, 1,246, 31,215, 34,255,102, 21, 0, 32,255,102, 21,114, 10, 42,129,232, 68,102, 99, 20,247,174, 31, - 82,104, 85, 4,202, 79,195,223,255, 34,124,196,229,176, 88, 52, 48, 26,143,131,207, 15,129, 65, 87,220,104,157,117,194,232,127, - 75, 0,130, 47,127,155,129, 38,188, 71, 0, 0,215,179, 40, 6,140,227,227,223, 75, 71, 98,232,200, 94, 0,168,237, 57,207, 16, - 21, 21, 69,223,248,132,160, 73,171, 62,160, 0, 70,191, 48,147,245,188,255,218,111, 22,211,214,173,255, 2,112, 6, 37, 55,155, -160,188,216,186, 5,115,223,190, 64,183,110,192,203, 47,223, 33,255,242, 98, 95,148, 23,251, 34,200,239,122,157, 50,199,143, 31, - 15,169, 84,138,225,195,135,215,112,253, 59,126,188,153, 18,112,245,222,122,131, 88,135,249,109, 66,136,253, 83,219,181, 88,185, - 92, 45,143,113, 63, 39, 30, 19, 19,163,114,101, 57,207,155, 55, 15, 49, 49, 49, 53, 8,181, 54,121,191, 41, 20, 56,115,230,140, -221, 5,239, 88,103, 12,156,175,205,140,141, 85,199,202, 93,111,213, 44,162, 20, 60, 63, 31, 24,111, 92,129, 98,241, 98,172,215, -149, 64, 27, 21, 97,191,255,221, 79,235,241,193,155,175, 34,116,193, 75,248,232,244, 1, 36,106, 47, 97,228,179,207, 34, 36, 36, -196,227, 96, 64, 27,209,211,240,240,240, 26,125,248,232,209,163,170,186,182, 99, 87, 40, 20, 66,133, 66, 49,240,244,233,211,249, - 41, 41, 41,234, 55,222,120, 35,226,203, 47,191, 20, 87, 84, 84,216,183,105,174,170,170, 66,147, 38, 77,114, 38, 76,152,208,125, -200,144, 33,143,184, 81, 36,120,132,144, 78,167,211,182, 20,101,239, 89,112,121,193,162,248,118,219,151,180,199,249, 66, 1, 74, - 43,248,176, 16,160,184,194, 0,218,162,107,213,252,119,150,245,122,230,249,127,189, 6, 55,241, 4, 54,247,127, 13, 87,191,155, - 99, 14,141, 64,254,181, 77, 1, 80,182,174, 28,185, 92,238,238, 33,234,108,253, 91, 93,109,223,215,230, 29,112,251, 79,123,181, -108,163,210, 80, 35, 68,197, 26,136,127, 59, 0, 34,224, 1, 85, 6,208,114, 29,136,201, 4, 33, 0, 51,181,160,202,108, 66,185, -201, 0, 88,220, 91, 81, 76,144,223,170,119,107,213,105, 97, 13, 18,108, 16,133,149, 56, 4,242,185,125, 1,238,178,254, 1,252, -242,122,187, 26,231, 3, 23,230, 65, 72,111,195, 72, 90, 66,169, 84, 30, 96,251, 98,137, 43, 84, 8,250,232, 39,220,122, 35, 22, -183, 53,190,104,111, 60, 11,179, 57, 15, 0,112,229,100,219, 70,235,176,137,187,191, 80,189, 58, 74, 81,131,252, 25, 68, 4, 46, -198,224, 94,227, 17, 25,116, 22,137,187,151,170, 60, 25, 68,134, 13, 27, 70, 83, 82, 82, 80, 92, 60, 2, 45, 90,236, 71,147,150, -189, 65, 41, 5,143,199, 99, 21,136,148,159, 15,228,229,157,177,157, 85, 0,226, 10,104,116,192,160, 65,214, 43, 57, 57,192, 87, - 95, 1,229,101,128,174, 2,168,208, 1,254,129,101,172,202, 86,155,181,159,155,155, 11, 0,248,228,147, 79, 0, 0,161,161,161, -247,194,205,204,170, 14,231,206,157, 91,195, 98,119, 38,110,214,222, 29, 27, 97,219,231,253, 29,240,217,103,159, 97,205,154, 53, - 80, 40, 20, 18,119,193,117, 51,130, 67,145,125,246, 28, 10, 3, 3, 85, 60, 30, 15,115,230,204,185, 43, 38,195,147,242, 61, 89, -221, 28,212, 82,129, 87, 63,121, 23,125,198,143,135,226,147, 79,192,227,221,225, 57, 69,206,153, 59, 30,194, 67,135,176,111,223, - 62, 92,186,116, 73, 42,151,203,213,108, 54, 94,113, 36,255,180,180, 52, 21, 0,100,100,100,168, 34, 35, 35,165,105,105,105,234, -240,240,112, 73,122,122, 58, 34, 35, 35,165,149,149,149,170, 90,198, 92,227,180,105,211,250, 76,153, 50,165, 89,151, 46, 93,176, -107,215, 46,125,105,105,169,160,178,178,210,234,237,176,205,127,108,221,186, 53,116,244,232,209,190,114,185,188,210,133, 24,158, - 3, 89,243,242,178, 78,174,249,224,237,233, 77, 90,116, 83,226, 79,229, 43,248,235, 42, 65,254, 77, 1, 64,121,168, 54, 24,161, -161, 45, 10,103,207,152, 21, 65, 8, 41,100,198,124, 79,126,175, 11, 15, 1, 55, 85,240,128,160, 86, 45, 46, 37, 37,229,174, 79, - 73,161, 22, 37,133, 90,143,218,154,249,220,177, 98,173, 13, 47, 62,118, 25, 62,103, 10, 33, 40,208, 50, 30,128, 26,207,215, 38, -240, 92, 65, 62,142,221,190,134,179,151,242,112,243,210,101,148, 93, 46, 64,249,213, 66,152,244,149, 48, 26, 77, 40, 55, 27,160, - 55,155, 80, 77,205, 48,131,130, 18,246, 74,166, 99,180,255,133, 92,235,249,130,101,140,229,207, 67,252,187, 13,179,226,197,211, - 56,128, 56,165, 22,113, 74,109, 13,194,103, 62,145,113, 25, 16,210,219, 16, 80, 45,126,153, 97, 54,177,158, 2,184,121, 12,102, - 93, 19, 0,192,127, 5, 1,168,190,121, 5,153,159,182, 67,246,207, 99,113,236,211,126,200,201,186,214,168, 29,179,239,160, 16, -232,180,128, 78, 11,232,125,207, 1, 0,126,253,208,136,183,231, 45, 1, 0, 12,137,238,229,177,229,255,194,176,131,208,104,162, - 17,120,116, 63, 86,191,107, 85,114,135, 13, 27,198,202,245, 15, 0,203, 63, 94, 74,186,118, 5, 28, 63, 23, 46, 88,221,255, 0, -208,173, 27,197,154, 53, 64,167,238, 21,120, 44,226, 22, 6,141,184,133,231, 95, 50,178, 46,163,163,197,207,156,135,134,134, 34, - 52, 52, 20,115,230,204,105,232, 42,118,251,174, 57, 98,221,186,117, 82, 87,132,109,247,162,173, 90,133,117,235,214,177,178,132, - 95,123,237, 53, 21, 19,249,239, 10,243,231,207,191,203, 11,224, 10, 7,207,229, 99,250,140,217, 56,190,113, 35, 22, 45, 90, 84, -171,114,194,148,111,255,254,253,168, 43, 96,111,216, 99,143,224,251,239,190, 66,216,228,201, 88,190,124, 57,234, 42,227,188,121, -243, 48, 98,196, 8,120,179, 2, 32, 45, 45, 77,229, 16, 44,135,163, 71,143,170, 0, 32, 61, 61, 93, 69, 8, 65, 90, 90, 90,157, - 50,245,122,125,243, 29, 59,118,224,220,185,115,200,201,201,241,211,233,116, 48, 26,173,253,204, 96, 48, 96,247,238,221,196,166, - 44, 84,178, 40,142,165,186,186, 90,116,124,203,100, 84,101,127,129, 61, 41,185,184,116,157,143, 50, 29, 15,102, 10, 20,234,124, - 49,123,193,187,145,177,177,177, 5, 44, 12, 62,187, 94,193, 44, 57,101, 57, 29,192,161, 17,172,255,218, 20, 0, 2,128, 72, 36, - 18, 72, 36, 18,156, 58,117,202,254,201, 59,118, 5,165,149,165,104, 49,200,243,117,191,199,143, 31, 39, 0,224,231, 55, 5,226, - 99,151, 33,188, 82, 12, 74, 8, 68, 51,138,107,220,119, 75, 92, 34, 62,204, 20, 40,208,149, 32,191, 84,131, 91,101, 90,148, 86, - 85, 65,107,168,196,173,234, 74, 92,175,210,163,176,170, 2, 26, 99, 53,180, 22, 35, 12, 22,247,193,175, 79, 62,225, 98,192,115, -136, 11,120,117, 98, 19, 80,136, 64, 61,222, 6,252, 78,244,190,139,107,172,145,127,179, 10,251,143,107, 49,112, 97, 94,205,186, -160,183,225, 99,185, 2, 31,203, 21,124,240,148, 0,249,249,249, 6,182, 50,183, 92,178,160, 85,124,130,253,252,146,206,140,130, -220, 66,100,165,158,197,141,203, 37,141,222,113, 55,126,157, 2, 0, 40, 43,162,240,171,124, 12,146, 25, 2,252,191, 37, 66,251, - 39, 62,113, 50, 8,123,227,159, 62, 55, 52, 5,175, 44,176,146, 63, 33, 4,191,167, 90,155,128,237,154,127, 6,161, 61,186,215, - 44,231, 70,224,203, 47,129,139, 23,173,158,128, 15, 63,164,118,247, 59,165, 20,129,129,129,238, 71, 96, 91, 31,101,230,253, 63, -249,228, 19,228,230,230, 34, 59, 59, 27,217,217,217, 72, 78, 78,198,155,111,190,137,252,252,252, 70,107, 15,134,232, 92, 89,210, -115,231,206, 5, 33,132, 53, 25, 18, 66, 80,151, 50, 81,215, 61, 71, 28,242, 41, 1,225, 53,193,183,239, 44, 67,147, 29,201,136, -137,137,193,100, 70, 27, 3, 32,239,214, 27,115,195, 6,195,207,207, 15,195,134, 13,195,123,239,189,135,228,228,100,213,242,229, -203, 93,190,127,223, 21,102,227,122,175,199, 16, 28, 28, 44,181, 88, 44,117, 42, 20,117,221, 99, 65,142,118,143, 83,100,100,164, -212,129, 40, 17, 17, 17, 33,117,227, 61, 25, 62,108,216,176,102,249,249,249, 56,116,232, 16, 30,125,244, 81, 8, 4, 2,251, 20, - 71,112,112, 48,219,233, 8,139,237,255,146,174, 61,250,199,173,219,219, 28,127,237, 90,130, 39, 35,123,194, 95,204,131,191,159, - 25,190, 62,213,120,250,185, 9, 22, 0, 26,199, 47, 38, 36, 36,184,155,139,178,175, 2, 96, 57, 29,192,225, 65,243, 0, 0, 32, - 10,133,162,233,220,185,115, 49,119,238, 92, 0, 48,124, 28,251, 49,140, 69, 38,248,250,138,225, 77,227,201,100,214,240, 97,191, -167, 46,130,242,121,120,239, 87,189,163,245,207, 10,126,193,193, 82, 83, 19, 63,104,169, 25,231,116, 90,156, 41, 45,198,217,178, -219, 56, 91,166,193, 57,157, 6, 23,245, 90, 20, 87, 87,161,194,100,194, 53,189,206,254, 63,235,194, 11,163, 8, 86,189,203,199, -170,119,249,160,224,131, 18, 30, 98, 38, 17,188, 54, 73,132, 25, 19, 91,161,107,215, 54,176, 64,232,241, 79,102, 92,253,142,243, -242,117, 36, 5,170, 77,134, 52,167,192,170,200,103,174,176, 6,209,237,121, 43, 0, 0, 32,160, 90,240,169, 14,213, 60,107, 68, -179, 70,163,241,147,201,100,209,158,148, 49, 44, 44, 12,201,201,201,216, 88,161, 67,165,129,135, 87, 54,125,139, 34,177, 47, 42, - 13,141,183, 77,196,184,190, 31, 72,211, 52,203,176,241,199, 68,251,181, 95, 63, 52, 34, 34,112,177,253, 60,230,153,175,164, 20, -172,214, 15,211,213,139,129,105, 11, 70,160,249,209,100, 72, 63,141, 2,111, 44,160, 86,171,189,234,195,157, 58,213,140, 30, 31, - 62, 28,104,222, 28, 8, 9, 1,194,251, 54,133, 88,196, 7,159,119, 71,172,216,215,215,237,128,204,227,241,236,150,127,110,110, -174,221,234,103, 62, 31,125,244, 17, 62,250,232, 35, 92,187,198,222, 43,227,106,190,190,230,125,207,173,175,117,235,214, 73, 87, -175, 94,237,146,176,217, 90,255, 14,174,231,187,226, 20,152,115,139,133, 93, 10,123, 3, 33,176,232,171, 33,108,219, 9,242,165, - 75, 49,205,191, 57,154,171,211,236,247,103,252,107, 26, 62,248,239,183,200, 89,245, 11,222,239, 51, 28, 19, 2,187, 96,223,182, -109,200,203,203,115,249,254, 61, 31, 43, 71,175,222,189,165, 22, 91,153, 24,133,204,113,122,198,213,181,218, 48,115,230, 76, 74, - 8,161, 76, 96, 31, 51,223,239, 72,242,105,105,105,234,136,136, 8, 41,165, 20,204, 84,128,155,122, 75, 17, 10,133,143, 62,255, -252,243,185,165,165,165,208,106,181,240,245,245, 69,171, 86,173,208,188,121,115, 52,111,222,220, 93,229, 89,156, 20, 59,179,143, -143,143,254,197,216,207,165,235,143, 13,196,229,171,101,104, 19,192, 71,100,119,130,199,187, 80,248, 55,107, 86, 2,192, 92, 7, -111,112,251, 13, 60,164,214, 63,224,102, 25,160, 92, 46,175, 80, 40, 20, 62, 0,252,229,114,185, 93, 11,236, 16,213,222, 43,205, -151, 89,234, 39,147,201,168,104,134, 61,242,159, 56,204,255,187, 29,144,223,217,153,168,254, 36,250, 57,232, 77,213, 40,211,233, -145,107, 52, 66,104,177,126,185,212, 88, 5, 11,165,160, 0,118,221,188, 4,157,201, 8, 0, 44, 6, 38,130, 5,203,106,246,113, -107, 60,128, 5,102, 84,227,252,197,114,124,191,185,204,163, 31,235, 72,244, 54,151, 63,181, 29,219,137,157,205,234, 7,235,119, -149, 16,142,248, 26, 64, 8,138,139,239, 4,231,137, 44,215, 97,224,181,195,236, 62,217,184,126,221,110, 57,237,103, 83,190,216, - 95,215,213, 80,188,148, 74, 37,152,210,108, 58,125, 4,209,209,209,141,214,113,183,159,178, 46,239, 75, 77, 62, 11, 0, 24,220, -203,154, 25,239,237,121, 75,112,228,108, 47,252, 55,113, 50, 20, 59,102,177,158,255,127,101, 65, 52,130,130,146,109,103,106,155, -178, 20, 13, 74,173,214, 24, 64, 17, 20,148,204, 74,214,190, 61,123,237, 57, 45, 38, 79, 6,164, 82,130,219, 87, 3,160,211,138, - 81, 89, 38,194,166, 13, 4,115,231, 82, 92, 41, 42, 71,120,100, 4, 82, 14,168, 88, 89,197,102,179,217, 62,223,159,156,108, 45, -171, 35,225, 23, 21, 21,161,168,168,136, 53,255, 59, 16, 6,229,241,120,119,145, 42,165, 32,158, 38, 1,146,203,229,234,215, 94, -123,173, 70, 44, 0,227, 17,240,196, 21, 78, 28,180, 18,139,211,178, 2, 66,216,207,217, 17, 66, 96, 42, 47,135,176,101, 16,248, -126, 77,208,235,197,241,248,104,212, 72,188,195, 44,219,235, 63, 0,230,202, 42, 8, 91,180, 65,159, 8, 9, 58,119,232,130,207, -207,167,161,119,239,222,210, 99,199,142,221,165, 4,196,202,229, 0,136, 10, 0,102,197,198,218,151, 14,154,156,200, 94, 32,224, - 3,244,206, 66,197,218, 10,188,118,237, 90, 2,128,218, 92,252, 36, 35, 35,195,165,139, 63, 45, 45, 77,205,134,252, 19, 18, 18, - 8, 33,100,113,243,230,205,123, 69, 68, 68,116,189,112,225, 2, 78,156, 56, 1,179,217, 12,127,127,127,232,245,250,162,160,160, -160,203,158, 24,125, 10,133,130,215,166, 77,155,125,207, 61,247, 92,155,163,135, 51,176, 70,185, 15,205,136, 8,221,219, 84,227, -226,109,127, 12,237,110,188, 4,192,121, 30,203, 92, 87,155, 56,102,156, 34,132, 56,158, 58,231,125,225,208,200, 16,176,120,233, - 13, 0, 12, 14,131, 10, 45, 72,241,120,126,184, 6,185,215, 66,124,172, 51, 6,150,105,180, 82,163,159, 88, 85,202,179,224, 70, - 85, 5, 96, 52,194,108, 91,215,116,190,162, 4,133,250, 50, 80, 74, 97,203, 47,160,102, 83,188,152, 73, 4,235, 54,221,233,147, - 23,114,129, 30, 93, 77,224, 67, 87, 47,242,119,234,236,238,234,160, 86, 47,128, 82, 57, 75, 5,100, 66,163,209, 24,242,243,243, - 5, 43, 71,130, 23,183,111, 24,230,245, 62, 98,183,194,216, 42, 21,174,188, 46,206,231, 12, 9,177,181,230,176,132, 96,160,109, - 37,135,171,229,126,137,137,137,214, 76,128, 50, 25,101,147,243, 33,118,220,215, 82,197,246,217,170,180, 68,138,200,160,179, 24, - 18,221, 11,135,247,157,197, 81,237, 82, 16, 16,200,199,125, 37, 77,216, 62,155, 85,249,130,130,146, 65, 8,193, 11, 47,188,128, -111,190, 41, 3, 67, 49,214,191,148, 81, 8,104, 77,203,254,118,173,242,162,134, 75,165, 41, 7, 84,170,225,195, 1,195,141,142, -184, 90,226, 3,139,109,182,181,157,174, 13,222,138, 41,199,190,163,221,209,180, 67,119, 41,147, 37,176, 46, 48,196, 95, 80, 80, - 0, 0,184,113,227,134,221, 51,112,243,230, 77,251,192,234, 37,136,131,219,217,249,165, 36,108,242, 1, 56,226,155,111,190,145, -174, 89,179, 70,197, 40, 0,171, 87,175,246,216,250,119, 38, 12,111, 33, 22,139,113,227,202,101,116,233,218, 13, 22, 83, 53,136, -201, 12, 65,211,102,104, 58, 96, 32,154,244,127, 2, 22,157, 9,102,125, 53,168,201, 12,152, 45,136, 91,251, 95, 76,156, 60, 17, - 98,177,216,165, 60,211,166, 64, 86,255,215,213,115, 97,203, 93, 63, 27, 25, 25, 41,181, 41, 0,148, 82,138, 33, 67,134, 72, 83, - 83, 83,239,122,206, 29,249,219,234,202, 2, 96,119,247,238,221,251,127,241,197, 23,134, 91,183,110, 85,141, 28, 57,242,185,204, -204,204,247,245,122,125,113,203,150, 45,229,159,127,254,185,134,109,253, 41, 20, 10, 33,128, 71, 34,194,195, 91,197,206,136,197, -165,130, 75,154,169, 51, 98,159, 76,223,183, 33,254,122,185,102,240,192,168,145,150, 54, 29, 66,255,159,179,149, 95, 87,106, 97, - 91, 31, 35, 14,250, 39,113,193, 1,206,199, 28, 30, 84, 5,160, 46,235,194, 27,242,103,200,166,150,132, 49,172,148,128, 21, 39, - 14,170, 1,144, 73, 3, 34, 41,124,197,208, 82, 19, 12, 38, 19, 44,212,130, 22, 1, 1, 40,208,149,194,147,228, 66,174,150,247, -221,137, 1,240,108, 45,182, 43, 23,127,125,211,245,218,242, 8,140, 27, 56,112,224,246,184,184, 56, 81, 80, 80,144,229,250,245, -235,152,215,251,186, 51,249,179,254, 31,181, 37,236,241, 10,182, 44,127, 46,146, 60,221,245, 12, 91, 36,108,159,165, 6, 64,198, -246, 89, 34,217,121,250, 67, 85, 90, 34, 64, 64, 48,174,239, 7,210,237,167, 62, 80,179, 37,127,166, 47, 21, 23,143,160, 64, 25, - 99,253,194, 21,239,172,143,223,207,244, 7, 82,215,230, 26, 54,171,158, 20,107,123, 75,204,229,229, 42,194, 7,244, 85,190, 32, -229, 38, 8,120, 2,232,121, 98,233,168, 9,175, 98,118, 76,172,219,246, 72, 74, 74, 34, 73, 73, 73,244, 30,190,127,160,148, 18, - 66, 8,117,140,104,119,244, 4,120, 34, 75, 46,151,171, 99, 98, 98, 48,111,222, 60,187, 66,209, 88,169,112,135, 15, 31,142,217, -137,235,240, 81,121, 9,250, 69, 13, 5,175, 77,160,181, 76, 70,106, 77,221, 11, 33, 8, 95, 0, 34,226,227,155,132, 85,104, 54, - 98, 32,186,118,237,234,113,212,126,125,224, 96,221,171,194,195,195,165,169,169,169,245,170,171,220,220,220,232,253,251,247, 95, -225,243,249,219,158,124,242,201,143,103,205,154,117,107,237,218,181, 41,128,117,202,193, 3, 81, 60, 0,201, 39, 78,156, 24,244, -195,250, 13, 60, 17,223,231,234,248,151,198,247,157, 61,123,182,246,235,175,191, 30, 11, 32,192, 70,252,229,204, 6, 65,108, 60, - 10, 28, 30, 12,176,113,255,123,171, 0,212, 91, 97,112, 67, 62,172, 7,164, 77, 39,210,136,108,188, 76, 98,201,202, 81,233,170, - 13, 48,153,205,232, 58,104, 0, 66, 77,225,158, 18,110,131, 5,163, 48, 73,127, 0,168, 24,107,220, 22, 7, 80,175, 28,248, 74, -165,114,135, 66,161, 16, 36, 39, 39, 47, 88,185,114,229,167, 14,202,197,112,199,255,197,214,163, 0,160,193,146,151, 76, 56,207, -196, 89,212,254,251, 38,156,151,121,165,233,239, 60,253,161,154,105, 31, 10,138,237,167, 62,240,170,140, 86,114, 39,120,101,193, -240, 59,102, 47,185,115,111,193, 50,207,243,145,199,189,117, 70, 29, 7,144,181,223, 44,150, 84,234,173,251, 0,220,201,255, 31, -235,241, 59, 98,179,200,204,114,185,188,193,231, 85, 25, 37,160, 33,100,217, 98, 1, 84,204,113, 3,148,205,171,239,117,237,218, - 21,109,231,204,145,174,217,187, 87,149,247,241,111,144, 9, 91,160,185,109,243,158, 74,189, 9,115,223, 92, 4,190, 95, 16,118, -109, 80,224, 84, 75,130, 81,131, 7,123,157,183,223,108, 54,121, 61, 76,176,117,241,179, 80,190,200,243,207, 63,127,139, 82, 26, -223,163, 71,143,255, 21, 23, 23,235,188, 32,126,199,122, 31,150,145,145, 1,139,137, 96,240,144,190, 31,204,158, 61, 91, 11, 0, -179,102,205,178, 0,208,214,167, 73, 29, 60, 78, 53,142, 93,120, 69, 57, 60,100, 30,128,123,162, 20,120, 77,140, 73, 53, 18,236, - 32, 35, 55,171,209, 43,213, 41,233, 15,115,173,222,114,229,114,185, 25,192,127,108, 31,175,229,186, 42, 95, 61,127, 47,105,136, -103,238, 37,172, 4, 79,177, 96, 89,114,131,203,118,151,234,215,131,246, 53,222,203, 58,104,168, 77, 87,228,114,185, 90, 46,151, - 55,136, 44, 82,143, 57, 0,166, 12, 10,133, 2,182,237,123,145,239,176,125,111,234,254,125,246,237,123, 71, 68,140,128, 77,233, -173,245,255,241, 39,106,137,121,115,224,221,196,196,114, 55, 65,119, 74, 64, 67,212,215, 19, 79, 60, 81,109, 50,153, 82, 0,232, -222,123,239,189,122,145,104,108,108, 44,121,239,189,247,168,193, 96, 0,128,189,181, 61,183, 98,197, 10,178,112,225, 66,251,255, -178,165, 2,174,115,108,119, 14,238,228,112,127,193,214,195, 69,188,221, 71,152, 3, 7, 14, 28, 56, 52, 10, 76, 0,170, 0,136, - 27,216,136,115,183, 99, 32,235, 29, 5, 57, 60, 28,224, 26,147, 3, 7, 14, 28, 30, 46, 8, 0, 52, 97, 65,254,122, 88, 3,184, - 27,138, 15, 44,224,150,253,253,237, 58, 18, 7, 14, 28, 56,112,248,251,193,143,227, 11, 14,156, 7,128, 3, 7, 14, 28, 56,112, -224,192, 41, 0, 28, 56,112,224,192,129,195, 63, 29, 53, 92, 58, 39, 79,158,244, 58, 34,215, 85, 48,225,131, 46, 47,100,128, 15, -124,125,110, 64, 40, 42,129,197, 98, 93, 22,198,231,243,192, 35,124,235, 95, 30, 1, 33, 60, 80, 34, 0, 33, 4, 60,152,176,125, -167, 16,148, 82, 4,241, 90,192,147,242,217, 50, 42,182,132, 53,128,167, 28,214, 4, 3, 70,102,201,215,195, 88,127,156, 60, 78, - 30, 39,143,147,199,201,123, 48,229,113, 30, 0, 55, 56,120,248, 34,180,165, 90, 24,141, 20,183,110, 19,236, 73,246,197,222,125, -254,224, 17, 33,246,169,218, 98,239,129,118,216,171,106,135, 67,199, 90, 65, 0, 1,120, 16, 99,104, 36, 15, 62, 34, 31,214,255, - 99,210, 43, 83,233,164, 87,166,210,195,169,170, 42, 35,143,164,158, 61,147,121, 80,117,228,176, 46, 57, 57,185, 10, 64, 83, 78, - 7,125,248, 49,242,169,161,146, 89,179,166, 82, 79, 55,121,122, 88,161, 80, 40, 36,212,134,186,118,215, 99, 11,234, 4,174, 71, -113,224,208, 8, 30, 0, 6,131,135, 12, 98,253, 18, 30, 73,205,112,171,181, 52,180,188,134, 68, 70,166, 16,163, 71,154,113,234, - 47, 95,136,132, 2, 8,248, 2, 8,133, 20, 62,124, 35, 32,104, 10, 1, 42, 49,168,151, 9, 98,145, 15, 40,128,118,109,128,103, -199, 88,176,127, 27, 59,242,191,120, 62, 27,143, 62,214, 21,237,131,155,163,224,202,133, 78, 1,109,187,160,101,123, 51,254,248, -253,119, 36, 39, 39,151,160,145,119,196,146,201,100, 99,148, 74,229, 78,135,243,103, 28,207, 57,212,142,217,179,100,212, 84,117, - 86, 58, 40, 44, 80,101,177, 20,163,180,125,165,170, 67,219, 17,168,168,110,135,111,214,253,244,183,221,233, 44, 38, 38, 70, 53, -111,222, 60, 16, 66,176,122,245,106, 85, 67,228, 4, 96,210, 1,112,252,127,255,225,145,210, 69, 41, 8,143, 87, 87,123, 83,199, -246,100,218,244, 78,242,173,154,237,236,184, 51, 34,135,134, 5,147, 13,208,193, 75,192, 78, 1,104, 44,240,238, 51, 23,142, 25, -101, 4, 5, 31, 2,190, 16,131,195, 9, 90,183,226, 65, 32,224,193, 71,200, 71,143, 80, 30,174, 92, 53, 97, 80, 24, 15, 45,130, -196,248,227, 64, 51, 0, 0,159, 86,130, 82, 11,220,165, 8,158,244,202, 84,250, 87,102, 38, 58,183,239,128,191,210,142, 34,221, - 96,132,246,182, 22, 34,159,166,232,217,127, 8,250, 14, 25, 5,213,118, 37,100, 44,115,227,223, 3,226, 31,174, 84, 42,247,135, -132,132, 32, 51, 51,147,233, 48, 37, 0,230, 40,149,202, 29, 50,153, 44, 90,169, 84,238,255,187,189, 20, 51, 99,101,212, 71,160, -129,128,103, 64, 85,149, 25,165, 58, 95,252,248,243,126,143,234,127,196,200, 33,146,102,190, 26, 12, 31, 34, 66,231, 78,207,170, -154, 53, 11,128,209,100,194,173, 91,183,209, 38,255, 42,114,114,243,240,202,203, 99,232,134, 31,118,121,213,174, 97,182, 61, 21, - 0,246,219,100,223, 79,235, 31,184,179, 29,238,234,213,171,161, 80, 40, 36,141,149, 14,248, 62,190, 47,116,203,150, 45,119,239, -167,208, 72,228,165, 80, 36, 72, 8, 8, 98, 26,160,222,105,254,175, 32,233,175, 58,114,188, 45, 75,166,125,223, 43, 59, 94, 77, -208,185, 85,228,254,248,227, 15,251,249,232,209,163,177,123,247,238, 58,207, 57,220,123,242,119,188,230,168, 8,212,169, 0,164, - 30, 78,199,144,161,225,247,173,208, 22,207,178, 67, 58, 62,236,213, 75,200, 19,240,161,213, 8,208,182,181, 16,109, 91,139, 80, - 81, 33,132, 88, 40,128, 89,224,131, 1,125, 8,250, 61,206, 7,143, 8, 65, 8,129,143, 80, 4, 33,175, 26, 68, 44,130, 73, 15, -152,160,171,147,252, 15, 31,216,143, 46,237, 90,225,204,169, 51,200, 47,186,126,167,124,229, 21, 16,159, 61, 70,121,124,130, 1, - 97, 3,240,199,110,207, 56,118,237,218,181,146,204,204, 76,213,197,139, 23,225,235,235, 11, 95, 95, 95,233,214,173, 91,213, 30, - 14,102, 82,165, 82,185,159, 33,126,135,206,209, 28,192,168,111,191,253,246,246,171,175,190,154, 44,147,201, 70, 42,149,202,228, - 7,177,131,135,135,135, 75,210,211,211, 89,255,110,201,240,193,146,222,161, 77, 85, 29,218, 21, 33,160,153, 15,120, 60, 63, 84, - 86,154, 80,172,169,196,100, 89, 79, 42,110, 54, 0,223,127,247, 51,171,126, 36,196, 13,188,240,204,227,170, 94,189,122,226,250, - 13, 45,142,255,121, 2, 21, 21, 58, 4, 4, 52, 69, 72, 72, 39,240,248, 66,152,205,249,136,157, 57,149, 38,172,253,241,111,101, -221,196,196,196,168,230,207,159,111, 63,159, 55,111, 94,131,121, 1, 30,100, 15,128, 82,169, 36, 50,153,140, 38, 37, 37,193,213, -198, 74,247,219,104,151,203, 99, 65, 8,193,186,117, 10,105, 76, 76,253,148, 0, 94,167, 23,237,228,157,177,188,137,203,193,180, -109,115, 30,130,131,120, 15,109,251,253, 83,225, 72,246,174,148, 2,183, 30,128,212,195,233, 0, 80,111, 69,224,240,156,156, 58, -239, 15,253,188,155,215,131,133, 67,142,115,143, 6,161,100,117,107, 8, 5, 66,116,108, 95,129,242,114, 33,142,159,233, 8, 62, -159, 15, 62,225, 67, 36, 52,161, 87, 55, 61,186,119,227,131,128, 7,145,208, 7, 34, 62, 65,216,227, 6, 4, 5, 90,176,241,127, -117,203,238,217,165, 13,174,228, 22,213, 36,127, 27,242,175, 93, 33,132, 39,160,237, 34, 31, 71, 96,243,166, 40,209,222,102, 85, -222, 53,107,214, 72, 86,172, 88,161,186,114,229,138,227,101,213,152, 49, 99,176,107, 23,123,107, 83,169, 84, 30,112, 36,127, 23, -104, 25, 31, 31, 95,242,198, 27,111,236, 67, 35, 79, 81,212, 65,254, 42, 79,202, 22, 26, 18,164, 10,110, 83,134,150, 45,252,209, - 33,184, 45,252,252,253,112,229, 74, 33,204,102, 11,130,219, 55,197,217,243,105,136, 28, 58, 72,146,118, 56,163,206,193,244,245, -215,167,210,199, 67,181,120,228,145, 14, 56,119,254, 10,142, 31, 63,143, 91,183,203, 65, 41, 16, 24,232, 11,189,190, 2,253,251, -247, 66, 73, 73, 41, 10,143,255,137, 33, 79,134, 75, 82, 15,177, 87, 84,107,134, 60,189, 0, 0, 32, 0, 73, 68, 65, 84, 30,100, - 48,214,191,109,219,105, 48,158,128, 53,107,214,120,236, 5, 96,166,251,157, 51, 1,187,216, 78,182,222,253,175, 67,135, 14,180, - 99,199,142,245,206,197,175, 84, 42,201,132, 9, 19,104, 98, 98, 34,152,141,149,234, 34, 60,219, 86,184,119,149, 63, 50, 50, 82, -194,108, 14, 84,139, 18, 75,221,200,180,255,111,185, 60, 86, 85,159,119,212, 89,222,160, 69, 21, 56,182,188, 73, 13,226,231,240, -112, 90,255,206, 46,255,122, 77, 1,212, 87, 17, 24,250,121,183, 90,149, 0,111,200,159, 65, 74, 74, 10, 10, 11, 11, 1, 0,193, -193,193,212,147,151,129, 79, 43, 33, 32,102,136,132, 66,252,121,166, 21,248, 2, 1,154, 10,117,214, 56,128, 38, 60, 20, 22, 54, -197,227,189, 44, 32,132, 64,246,172, 9,212,194, 3,136, 15, 8, 40,172,129,252,174,161, 47,185,138, 27,154, 10,100, 23, 22,214, - 90,150,146, 82, 13,180,183,110,216,100,177, 30,128,156,201, 31, 0,176,107,215, 46, 60,245,212, 83,146, 61,123,246,184, 29,224, -100, 50,217,240,188,188, 60,151, 29,166,180,180,212,241,114,243, 37, 75,150,224,220,185,115, 35, 30,164,169, 0, 7,242,103, 13, -201,240,193, 18,177,224, 58,124,125,155, 67,236, 35, 66,151, 46,157,209,177,115,103,148,149,169,161,209, 84, 64, 36,226, 35, 40, - 80, 12,129,111,115,183,131,169,128, 22,162,105,147, 22,208, 87,154,112,230, 76, 14,174,221, 40,197,245, 27, 21,168,172, 22,227, -145, 96, 19,196, 62,124,228,100,231,225,209,174, 93,113,237,122, 25, 42, 77,205, 88, 13,208,142,110,255,218,174,123, 58, 29, 80, -155, 76,111,100, 49,214,255,188,121,243,238,186, 62,127,254,124,175,188, 0,174,118, 39,116,158, 59,110, 40,175, 66, 90, 90,154, -170,190, 27,242, 76,152, 48,129, 42,149, 74,200,100, 50,184,154, 14, 96,227,169, 98,200, 31, 0, 50, 50, 50,238, 42,147,237,190, - 91,163,135,217, 97,176,161, 60, 46,137,243,253, 49, 97,181,206, 37,241, 7, 7,241,108,163, 20,187,230, 29, 61,122,116, 13, 47, -201,211, 79, 63, 93,163,174, 56,183,255,131, 3,143, 99, 0, 26,202, 35,208,144,200,201,177, 42, 22,133,133,133, 30, 41, 1, 2, -129, 0, 66,190, 16, 66, 33,193,176, 33,128, 94, 87,141, 75,185, 34, 8, 5, 66, 8,204, 2, 68,132, 83,136,132, 66,240,249, 60, -128, 18,104,180,192,177, 19, 2, 88, 44, 22, 0,183,106,149,123,226,207, 92, 84, 84,212,158,129,179, 75,219,182, 84,103, 34,168, -172, 44,133,217, 98, 98,253, 59, 79,156, 56, 81,187,210,161,215,179, 34, 26,103,215,191, 43,205,112,251,246,237,142,207, 39, 55, -134, 23,192,149,139,223,145,252,109, 3, 32, 59, 11, 48,184,141,138,199,187, 10,147,217, 2,131,209,132, 91,183, 53, 16,138,196, -168,174, 54,194,104, 50,195,100,178,192,100,166,172, 60, 49, 34,161, 14, 98,223, 14, 40, 46, 46, 69, 89,185, 30, 26,109, 37,154, -181,232,139,193,143, 63,142,140,212,221,104,111, 48,161,180,172, 20,221,187,119,133,143, 72, 0, 93,185,230,111, 49, 80,216, 34, -255,237,115,255, 78,158, 41,175, 98, 1,230,205,155, 87,195,155,224,124,143,173, 2,160,209, 68,219, 31,140,141, 13, 66, 98, 98, - 98,141,254,202, 24, 8,249,249,249, 94,239,202, 41,147,201,104, 98, 98,162,125,155,241,218, 98, 2,156,201,213,217, 83,149,150, -150,166, 98, 2,223, 40,165,244,232,209,163, 53,238, 31, 61,122, 84,229,206,233,193, 40, 13,140, 18,224,104,197,215,102,232,187, -249,109, 24, 31,153,140,205, 0, 38,174,214,225,137, 69, 21,245, 82,190,156,231,248,221,197, 4,112,184,247,222,128,218, 60, 0, -247,213,191,227,202,210,175,143,245,239,100,177, 34, 39, 39,135, 25, 80, 88,245, 94, 62, 95,128,136, 65, 22,240,121, 2, 28,203, - 20, 35, 43, 71,140,177, 79, 1,207, 60, 13,140, 27, 77,208,174,141, 8, 98,145, 15,196, 34, 31,248,138,125, 16,220,206, 7, 98, -145, 24, 98, 55,203, 0, 11,242,175,146, 18,205, 77, 82,219, 64,210,181, 75, 39, 4, 52,247,135,216, 98, 64,133,222,120,223, 59, -197,225,195,135,247, 31, 62,124,184, 6,225, 59,126, 0,160,184,184, 24,227,198,141,107, 52, 43,223,102, 29, 73,156,175,217,142, - 61,178,228,204,102, 64,167, 55, 66,167, 51,160,172,172, 26, 55,111,106,113,237,218,109,148,151, 87,163,162,194,136,138, 10, 3, -116, 58, 35, 74, 75, 74,221,202,170,174, 54,161,170,202, 12,163,209,128,166, 77, 69,232, 24,220, 12,126,254,254, 0,128,144,174, -157,209,161,125, 51, 4, 52, 19,131, 82, 51,140, 38, 11,170,171,117,127,139,129, 36, 38, 38, 70,181, 96,193,130, 58,201, 60, 38, - 38,134,181, 69,106,219, 82,184,214,251,171, 87,175,198, 55,223,124,227,241, 86,195, 14,219,206,218, 63, 12,161, 22, 22, 22, 50, -187,103,122,196,110, 19, 38, 76,160, 73, 73, 73,112, 84, 30,148, 74, 37, 25, 63,126,124,157,223,155, 57,115, 38, 8, 33, 96,250, -113,120,120,184, 4, 0, 34, 34, 34,164, 12,145, 51, 86, 63,115,159, 82,106,191,207,226,215,214,176,226, 93, 41, 14,108,102, 80, - 90,182,108, 9,226,160, 37,212, 87, 30,135, 7,143,252, 93,157,123,229, 1,120,144, 44,255, 59, 3,188, 25,124, 62,223,227,239, - 13, 25,100, 65,235, 86, 62, 40, 43, 19,192, 71, 96,130,143,136, 15,117,186, 8, 99,165, 66,136,132, 66,148,149, 9,145,154,233, -143,102, 98, 2, 30,143,135,209,209, 6, 60, 55,150,130,199,163, 88,122,210,243,114,202,100, 50,202,247, 19, 67, 35,108, 9, 63, - 99, 1, 46, 22, 82, 12,151, 12, 99,189,165,111,255,254,253,113,228,200, 17,151,247,252,252,252, 88, 15,150, 90,173,118, 4, 0, -172, 95,191, 30,211,166, 77,179, 95, 47, 46, 46,182, 31, 79,155, 54, 13, 69, 69, 69,141,210,158,233,233,233,106, 66, 8,152,121, - 82, 30,143, 7,198,221, 89,199,188,105,173,200,191,122, 77,218,170,153, 94,229, 35,226,195, 96,180,160,170,186, 0, 87, 11,138, -161,209,150, 65,163,209,163, 88, 83,137, 98, 77, 37,154, 7,117, 6,144, 91,167,172,155,183, 41,110,220,188,141,158, 61,187,162, - 68,171,133, 80,192, 67, 89,121, 1,116, 37, 22, 60,246,168, 14,109, 90,181,130,159,159, 31,124,124,124,113,253, 70, 57, 8, 63, -144, 85, 25, 29, 93,242, 13,181, 10,160,161, 87, 16,212,102,173, 3,119, 98, 1,216, 66, 46,151,171, 99, 98, 98, 48,119,238,220, -187,188, 10,204, 52,131,183, 43, 11, 38, 76,152, 80,195,130,101,222, 47, 66, 8, 94,124,241, 69, 36, 37, 37, 17,182, 74,128,179, -229,239,120,207,217,211,224,140,181,107,215, 18, 0,118, 43, 63, 35, 35, 67,101,235,215,106,155, 55,128,249,171, 2, 64,210,211, -211,237,247,235,218,206, 53, 45, 45, 77, 53,100,200, 96,233,145, 35,214,119, 98,230,204,153, 56,121,242, 79, 41, 67,225, 71,143, - 30, 85, 49,191, 63, 34, 34,194,173,167,108,237,218,181,248, 74, 26,136,137,107,244,214,223, 53,223,191,198,253,137,107,244,246, -250,156, 46, 21,226,187, 3, 6,112,120, 8,148,246,184, 21, 53,149,238,149, 11,113,242,228, 73,246,171, 0,238, 5,241, 59,198, - 2,212,199,250,175,105,201,215, 36,127,155,155,201,237, 84, 64,203,150,124,240, 8, 31,173, 90,242,209,173, 43,197,181,107, 2, -240,248, 4, 66,129, 0, 66,129, 16,127,157,246, 71,144,191, 16,124, 62, 31, 67,194,205,240,245,245,129,197, 66, 1,106,246,138, -252,155,180,233,136,155, 21, 20,186,139,106, 8, 8, 31, 23,175,229,147,139, 44,201,223, 54,176, 73,175, 94,189,170,186,122,245, -170,171,223,171,102, 89,142,145,197,197,197,251, 24,146, 7,128,113,227,198, 97,253,250,245,246,103,202,202,202, 80, 84, 84,132, - 29, 59,118, 48,203, 5,239,123,231,181, 13, 92,170,140,140, 12, 21, 19, 44,102,187,230, 49, 41,164, 30, 74, 87, 75, 37, 97,160, -133,101,208, 87, 26,161,245,169, 2,133, 22, 85, 85, 38,148,149, 85,163,232,182, 30,215,174, 87,224, 73,105, 39, 0,169,117,202, -170, 52,180, 68,222,165, 91, 8,233,242, 8,186,116,233,128,226,226,219, 8,108,110, 70,183,110, 1,104,221, 42, 4, 98, 95, 95, -148,148, 84,224,248,137, 11, 40, 40, 44, 67,219, 14,189, 30,218, 1, 36, 65,161,160,132, 64,202,112,169, 35,169,214,181,110, 63, - 65,161,144, 36,172, 93,203,202, 11,176,102,205, 26,149,179, 2,176,106,213, 42,172, 91,183, 78,234, 78, 94, 66, 66, 2,141,141, -141, 37,114,121,160, 67,153,168, 43, 98,166, 0, 48,126,252,120, 86,238,127,199, 41,133, 22, 45,146,224,237,180, 1, 99,229,219, - 20, 0, 74, 41,197,144, 33, 67,164,169,169,169,181,222,119, 71,216,204,220,122,106,234, 17, 21, 33, 4,132, 16,244,235,215, 87, -186,118,237, 90,245,221,207,222, 81, 50,220,201,227, 77,208,130,145, 39, 27,222,185,134,126, 52, 97,245, 57,187, 60, 54,224, 98, - 0, 30, 30,184, 85, 0, 30, 68,139,159,193,164, 73,147,234,245,125, 30,143, 7, 62,223,250,233, 25,202, 67,255, 62,102,248,136, -196, 86, 5, 64, 40,196,224,112,192,199, 7, 16,242,125,208,178,165, 24,124,190, 14,102,179, 5, 22,139,231,110,123,189,230, 6, -196, 29,122,224, 82,242, 79,104, 37,224,225,112,254, 21,143, 7,148,121,243,230,169,215,174, 93, 43,173,207, 50, 64,102, 89,223, -235,175,191,110,191,198, 88,250,101,101,101,208,235,245,152, 62,125, 58, 0,224,235,175,191, 6, 0, 85, 99,180,109, 90, 90,154, -218,102,237,171, 0, 96,208,160, 65,245, 10,224,234,208,169, 59, 50,143,238, 65,235,150,126,240,243,179,118,251,234,106, 51,202, -202, 13,208,104, 43,209,177, 75, 47,252,184, 97,163,219, 54,249,253,247,189,228,197,231, 35,232,209,140,179,120,114, 72, 95,116, -234,212, 9, 70, 67, 21,250,247,123, 28,254, 1, 1,184,146,151,143,194,107, 37, 72, 77, 59, 15,109,121, 0,118,175,223,248,208, -250, 76,103,198,202,109,237, 79, 48, 83, 46,183, 47, 11,183, 56,145, 62,143, 71, 0,106,167, 12, 58, 83, 46, 71, 95, 23, 22, 44, - 33,160,112, 80,203, 99, 99, 99,225,236, 5,152, 59,119, 46, 8, 33,136,141,149,171,108,124,142,153,177,114,244,237,123,183,188, -216,216, 88,187, 59,222, 29,201,177, 37,127,103,140, 31, 63, 30, 35, 70,140,144,122,171, 4, 59,206,213,135,135,135, 75, 83, 83, - 83,213,181,221,103, 19,164,104, 91, 85, 64, 25,229, 43, 50, 50, 82, 42,151,199,170,157,149, 14, 7,249,240, 68, 94,226,252, 38, -214, 83,113,155, 59,158,142,249,249,118,133, 96,207,169,186,199, 62, 87,121, 0,184, 24,128,135, 84, 1, 24, 60,100,208, 61,153, -243,105, 40,203,223,177, 35,121, 3,141,150,160, 93, 27, 30, 8,225,129,240,120,216,187,223, 58,191,239,227, 35,134,143,200, 7, -227,158, 38, 16,251,136,224, 43, 38,208, 20,243,145,113,188, 41,204, 22, 51, 58,118,240,108, 94, 87, 38,147,209,107, 5,151,160, -205,220,133,110, 29,133, 56, 83,232,253,188,240,204,153, 51,213,168,103, 80,158, 76, 38,147,126,249,229,151, 42,198,205, 95, 92, - 92, 60, 49, 60, 60,188, 98,223,190,125, 59,159,123,238,185, 81,197,197,197,100,234,212,169,123,108,249, 2, 26,173,115,166,167, -167,171,195,195,195,165,204,113,125,100,253,184, 97, 35,153,250,202,100,154,125,225, 28,174,229, 93, 1,143, 71, 96, 54, 83,136, -125,131, 16,218,179, 55,118,255,145,204,186, 78,175,221,178, 72, 53,197,215, 84, 85, 85, 38,244,233, 29,130,224,246, 45,145,127, -245, 38,180,167,115,145,149,157,143,253, 7,254,194,149, 66,138, 99,153,103,188,106,167, 7, 37,249,143,101,115,160,215,207,245, -255,132,165,188,220,255, 97,205,154, 53,118, 5, 96,205,154, 53, 64,222,250,187,158,117, 37,143, 45, 40,165,164, 62,253, 56, 54, - 54,182, 94,125,207,129,228,213,222,220,119,229, 85,112,252,174, 43,121, 30,181,243,149, 45, 72, 90,243,178,117,108, 24,254, 72, - 13,242, 7, 0,217,152, 39,172, 7,218,147,110, 21, 0, 46, 15,192,131,131,117, 43, 23,222, 53, 13,224,145, 2,240,128, 7,124, -212,187,112,153, 39,124, 32, 22,137, 48,110, 12, 1,143, 16, 12, 26,104,194,233, 51,190,224, 17,235,156,127, 73, 9, 15,237,219, -242,193, 35, 34,156, 58, 45,130,216, 7, 48, 24, 13,184,146,239,235, 17,249,231,102,255,137,240, 17,207, 64,208, 50, 28,185,217, - 25, 16,220, 72, 66, 64,179, 32, 90, 90,166,105,148, 10, 86, 42,149,106,153, 76, 38, 29, 56,112,160, 42, 46, 46, 14,189,123,247, - 46,210,106,181, 24, 56,112,160, 84,171,213, 98,206,156, 57, 42, 27,249,171, 27,187,145,235, 75,252,206, 74, 0, 0, 68, 14, 29, - 36,105,215,182,157,202,223,223, 31, 63,110,216, 72,206,156,205,245,108, 64, 79,205, 80, 3, 32,102,180,164,231,178,210,209,174, - 77, 19,136,197, 66, 84, 84, 24, 80,120,189, 12, 68,208, 17,199, 50, 83,185,104, 41, 54, 56,241, 6,208,245,255, 80, 99,121,225, -241, 5,141, 90,164,216,216, 32,135,180,181, 13, 67,104,238, 72,217, 19,210,174,111, 62, 3, 87,227,188, 44,210,199,250, 91, 43, -175, 91, 63, 28, 30, 90,244,235,215,207, 30,240,183,110,229,194,187,238,185, 85, 0, 26, 58, 31,255,253,206,239,239,153, 22, 65, -160,213, 18,248,181, 37,104, 17, 68, 48,112,128, 17, 98, 17, 31, 62, 34, 35, 90, 4,137,109,131, 0, 65,196, 64, 51, 50, 78, 8, -173,222, 2,150,138,145, 76, 38,163,189,186, 55,195, 27,115, 63, 66,165,168, 3,126, 77, 46, 68,215,208, 65, 0,128, 38,199,118, - 32, 59, 31,180,162,188,241,148, 0, 0, 36, 47, 47, 79,178,114,229, 74,149,163,119, 0, 0,105, 76,203,255, 94,195,150,236,167, -222,245,126,240,208, 9, 50,245,149,201,244, 86,241, 45, 84,222,208, 67, 44,110,129, 14, 93, 30,103, 53,149,240,176,195,154, 14, -187,129,126,102,222,122,216, 87, 4,228,109,104,244,223,230, 46,184,239,239,134, 81,207, 76,108, 80,203,157,139, 1,120,176,148, -128,218,200,223,173, 7,224,159, 0, 10,107, 84, 63,225, 81, 80, 80, 4, 53,167, 72, 57, 44,128, 88, 36,132,143, 72,128,103,199, - 80, 80,106, 65, 96, 11, 19, 76,102, 2,139,197,108, 27,252,220,227,241,206, 21, 24,251,162, 12, 21,130,110,104,221,196, 31,147, - 95, 8,194,198,173,167,237, 74,128,209,252, 43, 78, 95,104,220,117,226,140, 34,224,112,206,189, 61, 94,120, 21,254,142, 32, 19, -180,132, 38, 6,222,205, 12,202, 32,175,228,173,211,174, 64, 76,224,194,187,111, 28, 95,208,232, 86,255, 63, 25,251,254, 50, 54, -100, 31, 38, 86, 5,145, 58, 40,139,220,180, 64, 99, 41, 1,110, 27,203,219,125,132, 57,112,224,192,129, 3, 7, 14, 15, 47,184, - 68,207, 28, 56,112,224,192,129, 3,167, 0,112,224,192,129, 3, 7, 14, 28, 56, 5,128, 3, 7, 14, 28, 56,112,224,192, 41, 0, - 28, 56,112,224,192,129, 3,135,191, 7,106,172, 2, 56,121,242,164,215,209,160,174,130, 9, 27, 90,222,148,233,177,110,191,167, -211,220,176, 31,251, 7,181,181, 31,255,252,125,194, 93,207,182,146,190,234, 86,222,190,213,119, 50,230,141,156,255,165,253,248, -150,234, 91,120, 83,190,218,224,109,249,106,131,171,242, 61, 63, 85,238,246,123,153,170,157,232,220,185, 51, 46, 95,190,140,129, -210,177,246,235,191,253,168,184,231,245,231,174,191,196, 7, 7, 75,222, 40, 44,116,204, 76, 72,238,103,255,115,150, 55,118,236, - 88,201,174, 93,187,106,100, 74, 28, 51,102,140,116,231,206,157,234,198,120, 63, 30,100,121,245,145,245,119,174,191,168,168,168, -151,250,244,233,179,241,244,233,211, 47,166,164,164,252,218, 0,229,163, 15,202,251,193,201,107, 92,121, 30, 43, 0,206,248,234, -171,175, 36, 85, 85, 85, 32,124, 33, 8, 33, 48,155,140, 16, 9, 5,152, 51,103,142,186,190,154,199, 87, 95,125, 37, 1,128,217, -179,103,215, 75,150, 78,115, 3,254, 65,109,237,196,223,182, 99,103, 0,192,141,171,151,189,146,183,111,245,235, 24, 57,255, 75, - 59,113,125,181, 45, 3, 0, 48,251,217, 65,127, 75, 13, 48, 83,181, 19, 3,165, 99,145,169,218,105, 37,181,241, 83, 0, 0,151, - 47, 55,126,253,133, 2,146,108, 64, 21, 10, 72,179, 1,213, 27,133,133,200,136,123, 27, 0, 48,104,229,167,141, 90,111, 47,189, -244, 18,221,180,105, 19,170,170,170,106, 92, 23,139,197,170,151, 94,122, 9,191,252,242,203,131,186, 60,112,104,247, 46,193, 27, -168,217,172,207,206,191,177, 8,192, 14,206, 14,170, 29,159,127,254,249,240, 63,255,252,179,217,181,107,215,218, 6, 5, 5, 53, - 15, 11, 11, 43,124,243,205, 55,127,244, 86, 94, 84, 84,212,136,201,147, 39,167,108,220,184,241, 85, 0, 1,147,254, 47,118, 58, - 0,203,233,211,167, 95, 86, 40, 20,191,201,229,114,139,135, 34,153,228,202,180, 1,198, 43,103, 18,105,168, 62, 76,239,129, 76, - 14, 13,237, 1,112,196,127,254, 27, 47, 9,232,216, 71, 21,213,167, 7,252,124,132,160,148,194,108,166, 56,147,115, 5,241,171, - 63,147,250,250, 8, 49,107,214, 44,175,200,251,231, 13,139, 36,189,186, 29, 84,157,201, 14,145,122, 91,112,134,240,125, 3, 90, - 64,167,185, 97, 39,254,186, 60, 2,108, 44,213, 65, 83, 22, 98,223,234,215,237, 47, 82,109,207,213,181,198,210,249,127,138, 68, - 34,235, 91, 64, 41, 44, 22,235,251,109, 54,155,237,229,231,241,133,172,173,104, 0,104,215,218,154,170,211, 80, 86,130,106,147, - 9, 0, 80, 97,178,202,235, 50,106, 6, 30,237,213,159, 21,241, 3, 64,223,193, 35,144,169,218,105, 39,254,218,158,187,159,245, -199, 12, 26,217, 0,158,242,247,199, 30,157, 78,197, 16, 63, 0,100,237,221, 87,215,160, 85, 39, 62,253,105,153,228,248,237, 99, - 40,204, 63,133,110,157, 34,240,191,185,191,120,220,135,199,142, 29,251,220,230,205,155, 25,242, 55, 1,168, 2,224, 7,192, 82, - 85, 85, 37,240,245,245,197,216,177, 99, 37,174, 60, 1,141,140, 54, 79,244,235,243,199,158, 95, 18,154,232, 10,207, 99,168,108, -230,198, 43, 90,227,203, 0,126,123,208, 6, 38,153, 76, 70,189,221,128,199,137, 24,189,194,151, 95,126, 41,201,200,200, 80,109, -216,112, 39, 49,209,237,219,183,145,157,157,141,103,158,121,230, 7,137, 68, 34,125,243,205, 55, 89,181,175, 66,161,224,109,220, -184,241, 67, 0,255,159,189, 47,143,111,162,234,222,127, 38, 73,211,116,223,217,247,150,202, 78,161, 8,200,154, 0,165, 66, 1, -101, 41, 90,208, 87, 68,104, 64, 69, 1, 81,180,175,223,159,190, 46, 8,138, 20,101, 13,139,226,171,101, 43,136, 82, 40, 20, 10, - 41,101,211, 74, 41,101,183,180,165,116,163,116, 79,151,236,153,249,253,145, 76, 76, 67,210, 76,210,176,190,243,124, 62,243,105, -231,206,228,100,114,231,222,251,156,115,238,185,231, 62, 55, 34,242, 69,183,157, 59,119,182,126,249,245, 5, 94, 0,116, 0,218, - 26,110,123, 6, 0,103,244,232,209,163,128,251,183, 58,183, 70,170,131,103,127,136,140,132,149,148,181,254,102, 71,255,160,210, -207,103,128,203,229, 65,167,211, 66, 86,223,128, 89,211, 95,160,234,235,235, 91, 74,216,148, 51,223, 11, 11,219,176,180,237,175, -137,167,192,182, 2,176,102,237, 58,161,112,226, 12,105,199, 86, 62,112, 23,240, 64,146, 36,116, 36,192,227, 18,240,247,233,129, -222,221, 59, 73, 83, 83, 14,139, 54,110,220, 40,180, 87, 9, 88,183,110,157,176,103,240, 89,105,255, 30,183,193,229,232,164,235, -214,175, 23, 45,122,251,109,187,100, 52, 86,151,193,205, 39, 0, 62,222, 94, 0, 96,252,107,233,190, 54, 29,187,216,244, 6, 28, -143,127, 27,131,103,127,136,215, 94,154, 6, 0,198,191,150,238,219,112, 48,195, 46,237,154,203,229,162, 67,135, 14,224,114,185, - 80,171,213,104,108,108,132, 78,167, 67, 77, 77,141, 67, 47,215,147,199,197, 15,107, 15,192,213, 7,184, 87, 0,252,213, 80,130, -138,178, 92,252, 28,255,145, 93, 86,127,255, 97, 99,209,161,157,126,138,164,131, 5,242,239,210,165,139,113, 58, 0, 0,138,139, -139,157, 82,127, 12,147,171, 82,145, 30, 30,248,252,237,183, 0, 0,159,155, 16,255, 47, 57, 57, 77, 7, 19, 59,178,181,206,250, -104,164,176,102,112,170,244,195, 78,175, 64, 69,142,131, 43, 73, 33,226, 5, 29,126,252,102,175,232,248, 6, 48, 29,204,121, 11, - 22, 44,248, 77,161, 80, 96,199,142, 29,202, 57,115,230, 8, 0,120, 2, 32,119,236,216,161,158, 51,103, 14, 79,161, 80, 64, 32, - 16, 72, 91, 58,208, 69, 70, 70, 10,143, 29, 59, 38, 53,108,216,210, 98,120,242, 57,255,111,221,231, 31,184,249, 94,223, 5,183, -191, 79,226,211, 49,126, 94,239, 36, 85,124, 86,175,166, 30, 43, 5,128,222,130,183,166, 38,130,242,247, 79,181,251,183, 15, 25, - 50, 68,248,231,159,127, 58, 76, 54,107,214,172, 17,238,219,183, 79, 90, 95, 95,111,241,250,221,187,119,177,111,223, 62,233,235, -175,191, 46,250,241,199, 31,211,108,180, 23, 98,231,206,157, 63,143,136,124,113,102, 78,214, 57, 94,135,118,109,180, 47,191,190, -160,201,184,123,242,240,175,232,219,183,111,143,157, 59,119, 78,232,219,183,239, 65, 0, 56,115,230, 76,179,253,131, 73,127,211, -247, 15, 2,176,145,136,103,192,128, 1,212,145,148,227,200,186,122,221, 88,166, 84,170,240,245,186, 45, 13, 11,231,196,176,132, -253, 20,227,190, 32,192,213,171, 87, 11, 71,140,159, 42,237,209, 41, 0,174, 46, 28,144, 36,137,178,178, 50, 92,201,206,130, 90, - 75,130, 36, 41, 4,248,184, 99,252,132, 73, 82,133, 74,107,247, 23,186,186,148, 35,184, 83, 25,192, 37,208,171,123, 17, 92,121, -247,236,182,252, 77,201,223, 28,178,186,122,148, 21, 21,192,205, 39,192,170, 87,160, 57,242, 50,199, 79,123,126,197, 91, 83, 6, - 99,240,236, 15,209,140,150,125, 31,248,124, 62,184, 92, 46,188,189,189,145,159,159,143,154,154, 26,189, 34,229, 32,249,183,109, -213, 26,158, 60, 46,166, 46,250, 2, 19,102, 13,195,161,171, 37, 40, 83,160,197,228,111,142,226,210, 50, 92,187,112, 22, 65,126, -222,122,242,231,113,157, 82,127,207, 79,127, 13, 0,224,199,115,177,139,252, 1,224,255,214,111,192,255,173,223, 96, 36,255,148, -198, 70,188, 63,126,146,254, 98, 16,159,209,239, 30, 22,215, 85, 56,255,189,231,164,175,119,126, 19, 46, 28, 79,120,192, 29, 28, -112,209,190,245,112,188,253,249, 82,233,242,164, 30,140,212,136,180,180, 52, 13, 0,252,244,211, 79,114, 0, 2,122, 27,229, 29, - 59,118,144, 0,220, 77,183, 85,142,137,137,113,104, 94, 46, 62, 62, 94,104, 79, 57, 3,140, 24, 52,160,191, 60,241,215, 3,226, - 1,125, 66,185,141,215, 79,160,160,188, 30,119,107,229, 32, 41,202,161, 64, 96,138,162,168,234,234,113,212,168, 81,163,156,154, - 72,204,132,252,225,239,159,234,144,140,140,140, 12, 41, 0,130, 32, 8, 12, 25, 50,196,238, 58, 75, 77, 77,189,143,252, 47, 92, -184,128, 89,179,102, 25,207, 53, 26, 13,110,222,188, 41,141,143,143,111,214,139,185,115,231,206,183, 71, 68,190, 56,233,203,184, - 37,188,196,196, 68,108, 91,183,154,103,240, 24, 25,201, 63, 49, 49, 17,235,215,175, 71,223,190,125, 15,218,234,111,230,228,111, -173,191, 77, 24,110,240, 2,122,121,216,148,247,237,186, 77, 70,242, 47,175,172, 66,121,101, 21,100,245, 13,112,113,225,121,110, -218,177, 75, 9,103,109,136,192,226,161, 34, 44, 44,236,190,163, 89, 5, 96,227,198,141, 84, 64,151,126,232,210,198, 23, 74,141, - 14, 4, 1,164,164, 28,197,127,127,218,129,203,217,217,120,127,233, 98,112,185, 28,144, 58, 18,222,238,174,232,210,111,132,116, -237,218,181,140, 59,216,250,245,235,133,189,187,223,145,122,123,202,241,195, 79,229,224, 16, 20, 6,247,253, 91,186,126,253,122, -187, 58,169, 37,242,167,137, 95, 33,171,106,162, 32,200,234,234,109,202,179,212,153,232,142,148,145,176,178, 9,193,253,180,231, - 87, 70,207, 24, 28, 28,140,128,128, 0,212,213,213,129,207,231,131,195,225, 64,161, 80,160,166,166, 6, 92,174,190,147,219,179, -217,210,254,223, 14, 96,241,218, 99, 56,176,238, 99,180,109,213, 26,238, 30,254, 40,210,149,224,231,248,143,224,105, 24, 52,184, - 12,229, 89, 34,127,154,248,101,165,121,232,209,161, 21,234,229, 74,184,186,187, 2, 58,157,205,120, 0, 91,245,247,209,214, 67, -184,118,241, 60,250,116,235, 5,153,206,182,210, 72,147,255,223,199,142,227,255,214,111, 48,150,167, 52, 54, 34,165,177, 17,249, -226,255,224,216,245,203,232, 61,184, 27, 80,101,123,107,230,209,203,186, 9, 23,190, 51, 86, 26,228,209, 19, 10,170, 30, 80,149, -131,175,170,134, 74, 87, 15, 37,169, 0,201,247, 68,251,145,131, 16,177,176, 51,101,203,154,163,231,253,197, 98,177,187, 88, 44, - 6,244, 83, 0, 16,139,197, 48,156, 27, 44, 40, 37,118,239,222,109,119,167, 93,178,100,137,112,233,210,165,210, 94,189,122, 81, - 4, 65, 72, 1,224,149, 87, 94,161, 58,119,238, 76,125,252,241,199, 14,109,205,236,229,202,217,177,225,195,215,221, 34,219,171, -184,231,110,150,225, 80, 1, 7, 31, 30,185,167,250, 79, 90,131,172, 81,131,215, 28,145, 89, 83, 19,241, 32, 45,127,248,251,167, - 98,246,236,217,118, 79, 17,154, 18, 62, 69, 81, 4,189,157, 52, 83,188,246,218,107,194,123,247,152, 25, 37,106,181, 26, 87,174, - 92, 57,217, 92,123, 1, 32,236,208,174, 13, 63, 58, 58, 26, 0,144,153,153,137,147,135,127, 21, 20,151,150,145, 52,249, 27,126, -187,177,191, 93,185,114, 37,190, 37,253,237,235, 57,147,112, 53,175, 8,109,186,181, 5, 26,229,140,127,123,121,101, 21, 52, 26, -173, 65,193,209, 66,163,209,162,232, 78,129,160,133,175,149,176,113,206,226, 17,162,137, 43, 74,165, 82, 97, 64,143, 30, 82,119, - 55, 23,144, 36, 5, 29, 9,156, 61,125, 6,255,249,252, 11,144, 20,112, 43, 55, 23,151,179, 47,161, 79,159,254,224,114, 9, 60, -211,173, 3,242, 47, 50,247, 2,240,121,229, 8,237, 82, 10,240, 8, 20,221,213, 0, 60, 2,253,122,220, 65,198,149,114,135,127, -128,169,123,223,146,103, 64, 33,171,106,178, 26,192, 22, 76,221,251,150, 52,237,140,132,149,136, 88,178,222, 98, 20,187, 41,180, - 90, 45,220,221,221,193,225,112,224,231,231, 7,185, 92,142,198, 70,253, 54,192, 65, 65, 65,168,170,170,178, 43, 71,182,178, 6, - 24,236,230,134,247,215,157, 70, 68,127,224, 78, 22,240,151,225,218,251,235, 78,227,251, 37, 34,232, 72,157,221,245,119,237,194, - 89,227,255, 99,195,123,128,231,197, 65, 74,218,117, 12,232,209, 17,222,158,174,248,105, 95, 42, 6,137,162, 80,108, 97, 21,128, -173,250, 59,120,157, 2,238, 2, 83,198, 18,216,122, 40, 31, 1,126, 93, 49,109, 56,193,168,254,104,119,127, 74,227, 63, 91, 39, - 83,159,198, 3,237,101, 32,230,127, 2,234, 63,159, 3, 28, 5,136,140, 21,244,160, 98,181, 50,131,167,123, 74, 59,251,134,163, - 78,215, 0, 85, 77, 46,126, 46,220,137, 51, 83,106,208,107,158, 8,227, 23,121,194,205,239, 25, 8,120,126,224, 77,145, 97,158, -118, 30,181,109,235, 54,139,131,148, 88, 44,166,104,165,141,195,225,128,162, 40,181, 65,137, 86,114, 56, 28, 57, 69, 81,254, 0, - 72,180, 96,121,109,124,124,124, 90,100,100,164,168,170,170, 74,154,146,146,162, 87,124, 82, 82,208,179,103, 79,244,232,209, 67, - 68,151,217,131,122, 21,249,206,220,255,251, 62,233,155,168, 54, 28, 74, 41,195,252,132, 28,141, 86,163, 89,175,210, 97, 5, 0, -135, 54,163,120,241, 69,245, 3, 39,255,132,132,132, 52, 71,172,127,211, 41, 19,130, 32, 48,120,240, 96, 33,211, 93, 37,117, 58, -157, 93, 10,195,237,219,183, 33,145, 72,136, 77,155, 54, 89,186, 44, 0,208, 11, 0,111, 76,212,180,218,252,252,124,223,204,204, - 76, 36, 38, 38, 34, 60, 63,159,147,153,153, 9, 0, 8, 15, 15,199,243,163, 7,193,219,211, 21,235,127, 60, 80, 62,107,214,172, -184, 77,155, 54, 45,177,183,191,221,253,109, 37,188,122, 11,224,217,125, 49,246,174,156,135,254,125,218,224,153, 73, 95,216,236, - 31,178,186,122, 8, 4,174, 0, 0, 23, 23, 30,228,114,165,179,121,134, 37,253, 71, 0, 38,155, 1, 53, 25,168, 72,146,132,187, - 43, 31,106, 45, 5,146, 2, 56, 4,240,201,103, 95, 64, 71, 2, 13, 13, 13, 40, 43,187,139,214,173,219,128,162, 72,104,181, 58, - 8, 92,120,224,186, 48,115,193,110,216,176, 65,216,189, 75,177, 52,208,175, 78,223, 28, 12, 7, 65, 80, 24,216,251,150,148, 94, - 21, 96, 15,104,235,158,118,247,155,147, 63, 19,235,223, 92,139,166,137,127,195,193,140,251,200,159,169,245, 15,232, 3,134, 92, - 93, 93,225,227,227, 99,116, 25,210,129,127, 62, 62, 62,104,211,166, 13,180, 90,230,202,211,143,169,167,224,211, 5, 16,134,234, -207,115,180,122,247, 63,160, 47,251,248, 11, 41,106,213,246, 77,201, 20,151,234,131, 21, 59,181,242,135,151,143, 7,120,222, 92, - 40, 43, 21, 0,135,131,182,157, 59,224,108,118,129, 67,245,247,218,123, 95, 98,212,208, 49,224,149, 1, 13,173, 1,119, 14, 7, - 67,187,116,133,120, 74,107, 70,114,204,231,250,127,121,105, 30,166,190, 56, 18, 8, 81, 2,151,121,128, 39, 15,152, 28,142, 14, -155,183, 50,243,198,180,247,135, 90, 93, 13, 66, 85,133,159, 11,119,226,252, 28, 31,140,154, 58, 7, 35, 90, 61, 47,186,122, 76, - 11, 45,217, 8, 23,117, 35,180, 61, 72, 84,220, 99, 22, 52,106, 80,222,148,115,230,204,225, 0,168,161, 12, 59, 68, 25,206, 91, -132,148,148,148,180,158, 61,123,138,220,221,221, 17, 24, 24, 8,119,119,119,164,167,167, 19, 41, 41, 41,105, 14,136,107, 51,105, -210,164,173, 27,182,252,192,249, 36,173,129,220,119, 46, 23, 42,181,166, 81,169,195, 50,123,200,223,220,229,159,158,158, 78,208, -199,227, 66,254,150,220,253,246,122, 1, 26, 26, 26,140,255, 95,184,112,193,120, 0,192,210,165, 75,155,156,155,220,239,106, 69, - 92, 59, 0, 93, 12, 74,161,251,243,211, 95, 81,154,122, 2,104,203,255,185,225,195, 77,251,219, 33,177, 88,172,180,167,191,197, - 78, 30,133,126,225, 61,224,213,223, 11, 37, 39, 10, 1,129, 43,166, 47,250, 23, 6,191,250, 61,163,223,172,213,234, 80,114,247, -158,150,182,252,105, 20,221, 41,104,233,171,165,172, 28, 44, 30, 3,133, 0,150, 44, 21,202, 48,184,145, 20,160, 35,245, 74, 0, - 65, 0,191,238,223,135,169,211,102, 32, 48,168,149,113, 0,164,236,120,151, 92, 78, 57,122,135, 20, 25,207,251,245,113, 55,234, -134, 3,123,229,131,203,177,223, 11, 96,238,238,183,116,221, 30,235,223,220,221,111,233,186,233, 90,246,230, 80, 87, 87,135,250, -250,122,168, 84, 42,144, 36,137,138,138, 10,163,251, 95, 46,151,163,161,161,193,174, 41,128, 3,235, 62, 70,218, 85, 64, 86, 0, -104, 20,192,247,203, 69, 70,247,255,197, 44,224,210,221,179,224,218, 89,127,178,210, 60,248,251,120, 32,192,223, 3,207,132,246, - 68,254,237, 10,228,148, 84,161, 83,128, 15, 84,247,202,145,123, 43,183, 73, 46, 0, 38,245, 55, 76,248, 2, 70,136, 98,112, 32, -105, 47,164,233,123,177,115,205,123,152,254,222, 10, 92,214, 0, 21, 85,229,140,234,207,116,174,255,245, 97, 67, 48,187, 87,103, -236, 61,112, 18,151, 47, 23, 96,205,149, 76,236,142,248, 23,176,253, 28, 74, 74, 42, 24, 89, 23, 29,148,174,208,169, 43,161, 86, -235, 35,171, 91,183,239,136, 30, 61,123,138,234,220,244,177, 24, 10, 82, 14,142,170, 17,110,141, 92,220,187,219,188, 2, 64,191, - 51,165, 82, 9,165, 82, 41, 0,160, 6,224,165, 84, 42,189,205,151, 4,182,192, 11, 32, 76, 79, 79,151,246,236,217, 19,175,188, -242,138,168,178,178, 18,211,166, 77,179,103,224, 28,193,231,243, 27, 60, 61, 61,181, 17, 17, 17,119,151, 47, 95,222, 46, 46, 46, - 46,255,175,172,203, 19,119, 95, 83,221,212,144,176,123, 63,214, 7,225,242,119, 38,249,155, 91,255,180,194, 66,191, 51,166,177, - 0, 46, 46,255,196,168,172, 89,179,198,120, 88, 58, 7,140, 43,124,172,189, 27,190,225,224, 0,224,201, 74,243, 44,186,211,233, -254,150,117, 49,235,246,172, 89,179, 98,237,233,111, 35,159,125, 6,227,134,135,226,203,207, 86,227,219,181,201,248,127,191,156, -196,130, 49,131, 80,246,123, 50,100, 53,117, 76,250, 7, 17, 61,229,121,104, 52,218, 44,141, 70,171, 53, 85, 0, 0, 96,197, 39, - 31,181,196,130,103, 45,255, 71, 8, 75,115,255,230, 74, 64, 19, 5,128,195,225, 64,214, 32, 7,151, 67, 64,171,213,129,164, 40, -104, 73,125, 16,105,246,165, 44,140, 25, 27,169,119,147, 81, 20,184, 28, 46,234,229,106,104,213, 42,219,214,255,198,141,194,174, -237,239, 74,131,252,101, 70, 45, 99,216, 96, 79, 67,140, 46, 1,130,160, 48,160,103,174,116,195,198,141,140,189, 0,180,117,223, - 92, 48,160, 67,214,107, 51,193, 53,246,192,207,207, 15, 21, 21, 21,112,117,117, 69,125,125, 61,130,130,130,140, 65,129, 74,165, - 18,181,181,181,118, 41, 0,177, 95,238,198,247,203, 69,240,233, 2,164, 93, 5,222, 89, 37,133, 39,143,139,105,239,126,133, 98, -178, 12, 9,107, 62, 0,151,195, 92, 30,109,253,135,135,135, 34,168, 91, 23,180, 10, 10, 4,159, 67, 64, 75, 80,168,104, 84,160, -166, 94,233, 80,253,125,187,242, 55,188,216,179, 43,188,189, 3,224, 30,212, 14,154,234, 26,100, 29,218,133,218,234, 66,135, 26, -241, 15, 43,223, 6,150,140, 3, 79,171, 70,151, 70,160,156, 91,135,239,239,254, 5,240,189, 25,203,184,152,244,135,168,146,163, - 64, 33, 95,142, 65, 33, 34,244,250,151, 39,242,253,210,164, 65, 65, 89,210,142, 67,243, 33,227,212, 67, 69, 41, 32,255,133,132, -192,211,139,137,229,111, 58,192,211,171, 0,248,206,234,184, 71,143, 30, 5, 0,204,158, 61, 91, 20, 31, 31,159, 54,117,234, 84, -163,197,200,132,252,131,130,130,142,108,221,186,213, 67, 34,145,112,151, 44, 89,130,197,139, 23, 83,231,206,157, 27, 10, 32, 69, -161, 69, 79, 0,127,218,251, 76, 98,177,159, 85,183,191,163, 1,129,206, 36,127,115,130, 55, 85, 88, 40,138, 34, 12,129,129,182, -251, 69,113,241, 57,250,255,157, 59,119, 26, 15,243, 50, 26,254,254,254, 16,139,197,214, 6,193, 98, 0,181, 0, 56,197,165,101, - 56,127,254,188,113,206, 63, 60, 60, 28,128,126,251,237, 61, 7,147, 81, 83,175,148, 3, 88, 33, 22,139,117,246,244,183,223, 15, -124,138,200,229,139, 48,113,226, 88, 4,186,114, 81, 79, 80, 72,201, 41,194,249,171, 37,118, 17,245,194, 57, 49,207,230,231,230, -242,138,238, 20,128, 62, 12,228, 15,214,106,127, 50,137,223,188,204, 18,154,196, 0,184,186,186,226,214,245,203,162, 46,237,252, -165,110, 46, 60,232,116, 36, 8,130, 0, 65, 0,177,226,183, 64, 81, 36,116,134,124, 0,114,165, 18, 55,114,242,193,231,219,140, -234,134, 86, 83,141, 1,189,110,155,142, 24,120,115,201,109,236,255,165,187,177,105, 13,234,147,135, 63,178,123,218,109,253, 91, - 34,126,133,172, 10, 0, 28,178,254, 45,117,180,140,132,149, 0,192,216,250, 7,244,235,252,219,180,105, 3,149, 74,133,123,247, -238, 65,167,211, 33, 48, 48, 16, 85, 85, 85, 8, 12, 12, 52,212, 43,115,194,174, 40,203,197,199, 95, 72, 33, 43, 0,190,121,111, - 36, 26,180, 58, 44, 93,149,136,239,150, 71,227,189, 53,135,192, 35, 8,216,193,255,144,149,230,161,109,160, 47, 92,224, 2, 29, - 8,220,189,125, 13,119,202,101, 8, 14,242,199,239, 23,207,225,198,117,216,109,253, 79,159,187, 20, 46,254, 0,135, 11,236, 72, -190,141,253, 27,223,199,220,149, 18, 44,157,220, 31,111,141,237,108, 87,253,165, 52, 54,226,219, 41, 51,129, 90, 1, 64,184, 0, -223,174,198,140,191, 78,227,216,216,133, 32,190, 90, 4,226,143, 15, 24, 91, 24,151,238, 6, 96,136, 66,134, 6, 55, 46,228, 2, - 1,130,167,187, 64, 69, 41, 32,227,184, 64,139, 80, 80, 58, 57, 52,149,119,113,118,157, 12,179,103, 5, 35, 77, 42,125,232,157, - 54, 54, 54,150, 2,128, 45, 91,182,208,174,126, 98,201, 18,253, 52,240, 47,191,252,194,244,205, 14,111,215,174,221,209,175,190, -250,202,227,214,173, 91,112,113,113,129,183,183, 55, 46, 95,190,172, 1, 80,209,146,231,107,110, 77,190, 35,222, 1,103,146,191, -185,245,175, 39,230,251,151, 15, 26,150, 7,166,217,120,174, 91,123,246,236, 25,198,116,122, 78, 32, 16,204,181,174, 52,137,235, - 71,143, 30,125, 27, 64,120, 78,214, 57,152,206,249,191, 57,119, 38,142,118,235,134,196,196, 68,100,102,102,226, 72,183,110,238, -179,102,205,250,241,212,169, 83,140,251,219, 75,227,134,192,135,244,131, 28, 46,216, 31,191, 8, 27, 15, 93,194,251,207,143,192, -156, 53, 59, 49, 99,197,207,246, 90,224,196,138, 79, 62,178,148, 8,136, 50, 81, 2, 88,139,254, 41, 67, 19, 15,192,155,111,190, - 73,212,222,205, 69, 94, 81, 21,120, 46, 92,104,117, 36, 52, 90, 29, 46, 94,204,196,127,255,251, 35,212, 58, 10, 26, 29, 74,253, -203,119, 0, 0, 32, 0, 73, 68, 65, 84, 9, 62,143,131,242,154, 6,148,220, 56, 47, 90,188,120,113,179, 29,106,227,198,141,194, -158,193,119,254,177,254, 13,237,106,255, 47,161,250,246,196,161, 0, 14, 5, 14,135,196,208,254, 55,164, 27, 25,120, 1, 44, 89, -255,166,171, 0, 60,252,219,216, 69,254,150,172,127,211,168,218,136, 37,235,237, 34, 47,253,160, 88,131,134,134, 6,184,184,184, - 24,173,127,146, 36,141,127,237, 85, 0,126,142,255, 8, 23, 75, 78,193,179,141, 62,232,207,139,199, 69, 69, 89, 46,188, 93, 93, - 80, 91, 93, 12, 46,135, 0,143,195,108,250,153,182,254, 59,250,123,225,122,254,109,104,213,106,184,242,248,104,104, 80,226,119, -233, 57, 12, 18, 69,217, 69,254,116,253,189,240,246,231, 72,248,254, 59,200, 73,160, 99,112, 7, 92,189,246, 7,150, 78,238,239, - 80,253, 1,192,210,224, 65, 72,186,117, 18,144,105, 1, 65, 32,142,103, 92, 7,241,213, 34,122, 96, 98, 92,121,167, 86,231,167, -157, 61,158, 1,168,235,209, 64,212,163,134,211, 0, 25, 79, 3,141,174, 14,174, 74, 57, 4,165,183,177, 59,238, 22,186,132,133, -194, 90, 0,160, 57,220,220,220, 76, 73, 0, 2,129,192,226, 53,166,216,186,117, 43,182,110,221,218,162,206,236,229,229,245, 78, -110,110,174,135,183,183, 55,220,220,220,224,239,239,143,138,138, 10, 16, 4, 33,119,230,160, 65, 91,252,209,209,209, 20,160, 15, - 8,180, 39, 40,208,217,228, 63,100,200, 16,161,173,128, 90,166,177, 0, 30, 30, 30,177, 60, 30, 47,207,188,124,205,154, 53, 77, - 44,127, 0,232,220,185, 51,198,141, 27,183,195,150,253, 83, 92, 90,214, 36,218,255,227,255, 91, 2, 87, 30, 31,173, 91,183, 6, - 29, 19, 96,184,238, 97, 79,127,155, 39,236,135,197,171,191, 67,253,189,114, 4,121,183,194,181,235,133,152,179,102,167,221,253, -195,140,240, 9,179,207,155,202, 97, 61, 1, 79, 0, 46, 93,186,212,108, 50, 32,171, 30, 0, 0, 88,182,108, 89,218, 55,171, 9, - 17, 69, 77,145,118,105, 23, 0, 47,119, 87,244,234, 19,134, 94,189,251,131,199, 1, 26, 20, 58, 20,222,173, 70, 70,218, 97,145, -167,135,187,205, 47,104,148,203, 17,218,249, 46,148, 42,129, 33,107,139,190, 25,185, 9,148,160, 40,160,186,214, 21, 32, 0, 47, - 15, 45,250,134, 22,224,244, 5,219, 89,236, 76,173,127, 83,139,223,205, 39, 0, 46,148, 6,208,254, 51,222,233,120,182,159,209, -212,250, 55,181,248,233,178,220,107, 89,198,123,153,100,217, 51, 85, 2, 0,160, 77, 27,189, 50, 82, 93, 93, 13,111,111,111,163, -251,223, 30, 5,128, 86, 2,128,175,176, 48,122, 52,240,253,105,108,252,119, 20,102,188,247, 29,118,174,124, 11, 60,130, 0,223, -149,217,138, 29,218,250,191, 94, 88,142,144,142,129,216,190,109, 55,186,116,233, 2,159,118,193,232,223, 46, 24, 26,213, 63,238, -127, 23, 6, 50,105,235,255,139,185, 99,241,206, 39, 59,208,177, 27,209,162,250,163,173,255,241, 7,126,192,177,217, 49, 32, 58, - 12, 5,160,207, 10, 8, 0,183, 27, 27,141, 74, 98, 14,152, 37,240,217, 48, 39,143, 24,189,140, 18, 6, 79,171,151,118,233,222, - 7,117,110,192,109,220, 65,125, 65, 5, 42, 86,232,208, 80,211, 1, 55,207,230, 48,126, 33, 36, 73, 18,110,110,110,148, 66,161, -128,137,229, 73,185,185,185,129, 36, 73,226, 81, 12,150,245,245,245,223,188,245,214, 91, 83,182,110,221, 42,240,241,241,129, 84, - 42,197,218,181,107,235,212,106,245,243,206,252, 30,218,226,167,151,203,217, 27, 8,152,152,152, 72, 24,146,252,180,152,252, 1, -192,132,216,109,214,185,173, 12,131, 98,177, 88, 45,145, 72,134,238,221,187,247,114, 99, 99, 99, 91,141, 70,191,204,212,156,252, -123,245,234,133,161, 67,135, 78, 18,139,197,182,190,147, 39, 43,205,195,151,159,126,140, 95,147,142, 32,114,196, 64,156, 72,253, - 67,111,192,180, 11,134, 79,187, 96,132,231,231,227,249,233,175, 84, 22, 86,201,199, 3,216,199,212,250, 95,188, 37, 9,113,111, -140, 71,187, 54, 66,163,114, 97, 94, 15, 45,204,166,200,122, 2,158, 34,165,128,145, 2, 0, 0,239, 47,123, 47,237,155,111, 72, -209,237, 14,207,160, 91,247,158, 82,111, 15, 55,144, 20,160, 80,169,145,159,159,143,138,252, 75, 34, 47, 79, 15, 44, 92,184,208, -102,199,117, 19, 8,176,247,232,104, 17, 29, 1,223,172, 59,130,195,129,135, 7,115,235,137, 94, 2,232,225,223, 6,164, 78,163, - 39,127, 3, 52,132,139,205, 20,187,230,160,151,212, 68, 44, 89,223,132,180, 28, 33,127, 83, 37,192, 52,241, 79,117,117,181,237, - 23, 96, 67, 9,248,217,100,149,240,214, 21,111,254,115,162,105,128, 39, 67, 57, 29,253,189,176,247,194, 37, 92,189,249, 55, 6, -137,162,154,144,190, 61,228, 79,227,133,183, 63,199,254,129, 30,120,123,106, 15,167,212,223,210,224, 65,120,239,224, 94, 16, 95, -126,130, 35,173,135, 96,109,195,213, 38,215,167,249,248, 98,165,172,214, 46,226, 56,181, 58, 63,205,143, 23,129,226,154, 60, 84, - 84,221,197,189, 28, 79,112,117,222, 24,222,111, 36,118,159,221,253, 72, 7, 53, 39,101,251,187,240,227,143, 63, 70, 16, 4,113, -252,187,239,190, 19,188,248,226,139,117,114,185,124, 60, 28,152,243,111, 14,206, 88, 2, 40, 22,251, 57,133,252, 45, 88,169,182, -148, 15, 6,207, 38,174,148, 72, 36,193,245,245,245, 95,102,102,102, 46, 41, 41, 41, 65, 99, 99, 35,248,124, 62,218,182,109,139, -160,160,160, 23, 37, 18,201,239, 63,255,204,104, 75,128, 27, 0,194, 59,250,123,225,185,231,158,195,165, 91, 37, 8,236,218,187, - 73,127,123,126,250, 43,114, 0,235,190,140, 91,178,143,233,239,152, 39,236,135,136,212, 63, 49,251,147,255, 98,212,168, 81,104, -221,186,181, 69, 69,203,137,175,157,112,128,252,169,102,202, 89, 37,226, 17,144, 62,163, 84,192, 0,240,254,251,239,167,109,216, -176, 65,120, 49, 45, 71, 4,232, 35,105, 41,138,130,171,171, 43, 62,120,127, 25,227, 78,251,182,157,105,126,153,130,118,245,115, -181,114, 64, 43, 55, 70,192,211,196,111,239, 90, 44,218,213,159,123, 45, 11,185,215,178, 16, 20, 20,132,138,138, 10,135,136,223, - 39,168, 29,212, 12,130, 35,153, 98,246,231, 63,227,220,105,231, 85, 99, 65, 65,129,113,183, 63,141, 74,121, 31,249,219, 67,252, - 52,254, 53,208,195,105,245, 7, 0, 68,252, 7, 70,226,167,201,255,118, 99,163,104,154,143, 47, 82,128,180,149,178, 90,135,126, -251,111, 43,143,155, 12, 60, 10, 0,192,238,107,204, 19,246, 80, 20, 69,184,186,186, 26,189, 0,244,255, 0,224,234,234, 74, 88, -250,255, 33,227,204, 15, 63,252, 48,106,223,190,125, 75,235,234,234,226, 1,100, 56,251, 11,156,177,244,207,201,228,228,116,136, -197, 98, 5,128,165,134,163, 69,239,227,202,149, 43,195, 1,116, 13,236,218, 91,174, 81, 41,221, 13,253,173, 14,128, 12,192,141, - 78, 1,238, 47,137,197, 98,187, 26,116,196,199, 91, 31, 22,241, 59,164,104, 57,120, 63, 11, 39, 32, 44, 44,140, 17,249,219, 52, - 64, 91,186, 83,223,131, 0, 61,183, 79, 19, 63, 90, 72,252,244,220,180,172,188, 24,178,242, 98, 4, 5, 5,181,200,226, 7, 0, -173,142,180,219,251,208, 28,202,171,101, 14, 63,139, 57,232,185,125,103, 17,255, 3,168, 63, 2, 0, 34, 61, 60, 40, 83,171,127, - 0,207,165, 69,196,255, 63,134,191,234,234,234, 98,216,106,120,244, 56,117,234,148, 68, 34,145,252,183,176, 74, 46,215,168,148, -166,243,145,222,157, 2,220,253, 28,216,253,143, 0,244, 83, 25, 79,154, 82,197,226,225, 42, 1,140, 26,147,163,251, 8,179, 96, -193,130, 5, 11, 22, 44,158, 92,112,216, 42, 96,193,130, 5, 11, 22, 44, 88, 5,128, 5, 11, 22, 44, 88,176, 96,193, 42, 0, 44, - 88,176, 96,193,130, 5, 11, 86, 1, 96,193,130, 5, 11, 22, 44, 88, 60, 21,104,178, 10,224,210,165, 75, 14, 71,145, 90, 10, 38, -100,229,177,242,156, 37,207,176,183, 58, 7, 0,105, 41,249, 10, 91,127,214,229,133,133,133,209,117, 71,175,229,166, 46, 93,186, - 68,178,245,199,202, 99,229, 61,189,242,236, 86, 0,158, 18,180, 40,201, 68,116,116,180, 16,128,105,202, 80, 81, 98, 98, 98, 26, -171, 43, 62, 26,124,253,245,215,175, 94,185,114,165,255,249,243,231,223,115,117,117,133, 92, 46,255, 64, 34,145,172,102,144,129, -141,197, 63, 3, 11, 5, 64,199,214,196,227,141,168,168, 40,225,225,195,135,211, 28,252,172, 40, 57, 57,249,164,147, 18, 74, 33, - 42, 42,234,165,228,228,228,221,155, 55,111,246, 7, 80, 15, 64,199,246,185,167, 15, 79,213, 20,128,129,188, 91,244,249,189,123, -247,154,231, 11,151,182, 68,110,116,116,180,208,176,102,151,138,142,142,166,236,149, 69,217, 9, 75,235,131, 91, 40, 79,248, 40, -222,165, 68, 34, 33, 22, 45, 90,180,250,218,181,107,223,119,238,220,249, 61,129, 64, 0,149, 74, 5, 0, 95,239,223,191,159,156, - 58,117,170,232, 17,117, 25,202,254,227, 97,202,179,186, 7,187,233, 94,236, 14,237,207, 30, 29, 29, 45,164, 40,138,162,254,159, -101,217,244, 53, 91,109,208, 18, 10, 10, 10,168,130,130, 2,167, 17, 76,117,245,184, 38,251, 21, 56,155,168, 9,130,176, 75, 46, - 73, 82,148, 78, 71, 81, 36,105,249,136,138,138, 18, 38, 39, 39, 59,180, 11,213,150, 45, 91,198, 28, 57,114,228,228,232,209,163, - 65, 16, 4,181,107,215,174,113,246, 62,155,249,113,228,200,145,221, 47, 15,227, 67,188, 64, 92,157,231,153,191,111,254,252, 88, -146,190,102, 75, 94, 99, 99, 35,213,216,216,216,108, 59,164,239,121, 16,239,135,133, 85, 67,224,190, 4, 65, 60, 27, 29,222, 98, -222,108, 91,249,180, 31, 33, 90,180,141,219,222,189,123,165, 51,103,206, 4,160, 79,170, 97,210, 56,165,142,120, 21,104,133,130, -206,249,111, 72, 67, 42,141,142,142,182,207,171,144,232,111,199,183,218,238,251,141,147,223,100, 46,206,254,125,109,172,117,104, -198,245, 39,145, 72, 8,153, 76,182,167, 79,159, 62,211, 1,112, 40,138,130,155,155, 27,202,203,203, 81, 91, 91, 11, 31, 31, 31, -148,151,151,159,156, 58,117,170,232,192,129, 3,105,118,190, 19,138, 78, 7, 75, 16, 4,166, 79,159,142,113,227,198,137, 22, 44, - 88,192, 88,206,193,131,191, 25,255,159, 50,229, 69,155,231,182,160, 56,247,246, 63,213, 61,108,125,147,115,243, 50,183, 97,182, - 55, 85,162,183, 19, 54, 69,122,122, 58, 86,172, 88,113,223,187, 24, 57,114, 36,117,250,244,105, 70,109, 57, 49, 49, 81,138, 79, - 8,250,252,254,196, 51,159, 16, 45, 30,204, 31,227,177,165,137,165, 45,145, 72, 68,177,177,177, 24, 53,106, 20,117,230,204, 25, - 70,159, 61,103, 37, 39,227,129,196,247,144,156,156, 44,165, 55, 9, 27, 53,106, 20, 85, 87, 87,215, 28,225, 11, 99, 99, 99,141, -237,245,247,223,127,119, 39, 8, 2, 49, 49, 49,247, 0,180,158, 53,107,214,113,137, 68,194,177,199, 98, 95,125,124,181,241,255, -178,148,187, 32, 8, 2, 59,223,117, 7, 64,224,155, 87,190,126, 33, 48, 48, 16, 0,176,235,167,157,140,235, 42, 60, 60, 28,221, -186,117, 99,153,247, 49, 33,127,123, 61, 0, 84, 98, 98, 34,194,195,195, 41, 43, 3, 40,229, 64,231,118,170, 53,105, 46, 47, 49, - 49,209,116, 67, 12,187, 65, 16, 4,145,152,152, 72,208, 3,144,225,175,195,150, 38, 77,254,134,103, 34, 76,158,205,110, 69,133, -152, 89, 99, 60,152,148,219,130,231,161, 77,198,131, 73,185, 61,228, 79, 81, 20,232,221,217, 40,202,190,102, 34,145, 72, 56, 53, - 53, 53,255,245,241,241,153, 14,128, 51,119,238, 92,204,158, 61, 27,124, 62, 31,110,110,110, 16, 8, 4, 32, 8, 2, 92, 46, 23, - 50,153,140,113, 61, 70, 68, 68, 8, 1, 80,251,246,237, 3,253, 78, 40,138,194,254,253,251,177, 96,193, 2,169,225,250, 99, 7, - 75, 10,193,163,240,172, 37, 38, 38, 74, 1, 16, 47,221,156,137,153, 55, 44,246, 49,106,230,141,104, 17,241,153, 67,253,142,122, -255,253,247,209,181,107, 87,167, 60, 47, 65, 16,148, 88,236,135,128,128, 19, 78,173,135, 9, 19, 38,140, 77, 77, 77, 61, 73, 81, - 20, 17, 27, 27,155,102, 15,249, 91,195,129,196,247, 16, 31, 31, 15,146, 36,241,222,123,239, 49, 82, 40, 76,201, 31, 0,142, 28, - 57,146, 52,106,212, 40, 0,240,139,137,137,209,142, 30, 61, 26, 98,177,152, 52,196,205, 48,241, 50, 54, 57, 95,187,118, 45, 94, -122, 78,111, 27,238,124,215, 13, 47, 15,227,227,131,200,247, 25,255, 38, 15, 15, 15,140, 26, 53, 10,153,153,153,198,241,212,252, -160,239, 97,179, 23, 62, 58,242,111, 86, 1,160,201, 42, 51, 51,211,152,118,210,212,122,178,151,104, 77, 6, 17,103, 15, 74,230, -202,128, 83, 93,195, 22,166, 4,236,134,169, 66, 97,176,254,159,198,118, 70,153, 14, 38, 37, 37, 37,198, 11,197,197,197,140, 21, - 70,153, 76,246,149, 92, 46,127,133,195,225,112,102,205,154, 5,153, 76,134,210,210, 82,184,184,184,128,199,227,129,199,227,193, -197,197, 5,110,110,110, 80, 40, 20, 96,226, 66,220,188,121,179,240,248,241,227, 82,130, 32, 48, 99,198, 12, 80, 20, 69, 43,121, -196,140, 25, 51, 0, 0,169,169,169, 82,118,168,104,158,252, 13,239, 87,100,170, 36,211,239,222,212,171,229,200,160,158,152,152, - 72, 24,222, 11, 54,111,222,236, 20,101,236,163,143, 62,162,141,130, 22,123, 38, 34, 35, 35, 35, 46, 92,184,144,218,165, 75, 23, -132,132,132, 80,195,135, 15, 55,122, 78, 12,187, 63, 58, 68,254,107,214,172, 1, 65, 16,224,112, 56,184,112,225, 2,152,120, 99, -204, 60, 18, 47, 16, 4,129,151, 95,126, 89,107, 40, 82,199,196,196,212, 9,133, 66, 44, 88,176,128,156, 56,113,162,205,223,110, -186, 43,105, 89,202, 93,128, 0, 18,222,249, 39,107,241,206,119,221, 17, 51,220, 21,203,159,255,128,241,115, 49,177,252, 89,239, -192,195, 35,255,216,229, 43, 45, 94,231, 53,215, 33,195,195,195,169,204,204, 76,208,158, 0,154,184,194,195,195,237,234,228, 15, -154,252, 77,173,234,199, 61, 96,207,116, 74,224,169,211, 0, 40, 10, 37, 37, 37, 40, 43, 43, 51,150,153,159,219,176,254,185, 71, -143, 30,157, 24, 26, 26, 10, 46,151,139,220,220, 92, 80, 20,133,191,255,254, 27,106,181, 26, 4, 65,128,199,227,129, 32, 8,232, -116, 58,200,229,114, 28, 56,112,192,166,220, 19, 39, 78, 72, 1, 96,198,140, 25,247,181, 91,122,170,135, 38, 10, 38,237,218,220, -173,111,235,156,137,149, 79,195,218,116, 0, 19,215,191, 57,210,211,211, 97,176, 12, 91,166, 0,127, 66,128,248, 76,175,192,153, - 42,175, 20, 69, 1,159, 16,152,121, 35,218,225, 64, 89,130, 32, 40,195,123, 49,146,145,225,125, 17, 45,145,215,189,123,247,251, -200,205, 81,184,186,186, 82,215,174, 93, 67, 69, 69, 5, 81, 81, 81,129,176,176, 48,170,160,160, 0, 92, 46, 23, 90,173,214,161, - 47, 24, 61,156, 75, 43, 15, 88,182,108, 25,214,174, 93,139,211,167, 79,131, 32, 8, 76,158, 50, 31,119, 10,152,109,224,120,228, -200,145,223, 12,239, 88, 9,128, 52, 28,136,137,137,169, 5,224,155,156,156,140,168,168, 40,161,169, 66,222, 28,244,214,255,253, -251,152,232,167, 3,128, 93, 59,179,236,146,199,226,241, 37,255,102, 61, 0, 6,235,159, 48,245, 4,208,150,127,102,102,102, 75, -200,223, 86,128,146, 67,242, 76, 60, 19, 66, 56, 16,224,244, 0, 44, 39,202,100,240, 49, 62, 15, 93,230,172,224, 23,106,175,159, -241,112, 6, 26, 38, 45, 52, 30,118, 88,254, 20, 61,216,118,232,208, 1,131, 6, 13,194,160, 65,131, 0,192,120,110,126,175, 21, -248,250,251,251,247, 81,169, 84,168,174,174,198,185,115,231,144,145,145,129,138,138, 10, 40, 20, 10,208,115,164, 20, 69, 65,163, -209, 64,165, 82, 49,154, 98,160,219,134, 53,114, 79, 76, 76, 36, 8,130, 0, 83,207,204,193,131,191, 25, 15, 38,231,182,160, 56, -247,118, 19,162,167, 15,211,115,211,123,152, 98,212,168, 81, 72, 79, 79,111, 89,131, 48,153,243,135,126, 26, 75,100, 32,103,130, -190,134, 22,198,222,152,190, 23,218, 11,224, 44, 56,195, 11,208,190,125,123, 20, 23, 23, 19,230,202,174,163,228,127, 32,241, 61, - 99, 27,166, 49, 98,196, 8, 0,192,169,179,204, 23,107, 68, 69, 69, 69, 26,230,254,175, 3,144, 27,198,115,250, 48,106,221, 76, -131, 11,155,206,253, 91, 80,174,236,148,199,226,241, 7,143, 73,231,164, 61, 1,246, 90,254,203,151, 47,167, 86,173, 90,229,180, -135,181, 37,207, 48, 72, 57,173,113, 50,157, 67,107,142,116, 76,100, 53,136,197, 98, 79,107,215, 29,133,233,220,191, 51,148, 0, -211,185,127,166, 74,192,236,217,179,225,225,225, 1, 79, 79, 79,120,121,121,193,199,199,135,244,243,243,227, 36, 39, 39,227,213, - 87, 95, 53,222, 39, 16, 8, 48,126,252,120, 52,163, 4, 4,168,213,106, 84, 87, 87, 67,169, 84,194,199,199, 7,174,174,174,208, -106,181,160, 40, 10, 58,157, 14,106,181, 26, 26,141, 6, 58,157,206,174,248, 2, 67,208,154,213,235,166, 86,232,163,132,173,128, - 64,123,209, 82, 37,128,248,204,250,116,223,204, 27,209, 6,114,117, 80,182,153,245,111, 82,142, 25, 51,102,216, 29, 12,104,110, -253,155,202,115, 20,225,225,225,148, 78,167, 67, 88, 88, 24,117,233,210, 37, 34, 44, 44,140,210,104, 52,144,201,100, 14,203,164, -141, 41, 30,143,135, 37, 75,150,224,194,133, 11,248,103,222,159,121,155, 62,122,244,232,209,145, 35, 71, 2,128,151,129,244,229, - 0,176,123,247,238, 86,167, 78,157,242, 54,244, 15,194,240,215,166,224,181,223,173,197,203, 67,239,183,254,103,127, 47,199,238, -115, 26, 80, 20,133, 1,179, 6, 32,107,103, 22,241, 40,141, 43, 22,206,177,254,109,122, 0,104, 75,149,110,176,166,241, 0, 76, -176,106,213, 42,218, 98,112, 10, 24,200,115,120,126,221,176, 68,175,201,145,154,154, 74,210,171, 2, 90,106,177,199,198,198,122, - 62,205, 13,110,203,150, 45, 88,179,102, 77,147,118, 69,147,255,148, 41, 83, 48,101,202, 20,189,133,115,234, 84,115, 98,252,243, -243,243,149, 58,157, 14, 53, 53, 53,168,172,172, 68, 77, 77, 13,228,114, 57,228,114, 57, 26, 26, 26, 80, 87, 87, 7,153, 76, 6, -133, 66, 1,149, 74, 5,157,206,182,197, 68, 16, 4,246,237,219,103,151,194,246, 36, 35, 61, 61,189,201, 97,138, 37, 75,150, 8, - 77,207,153,204, 57, 91,152,243,111, 98,185,183, 36,144,203,210,103, 41,138, 34,246,237,219,231,212, 88,128,125,251,246,217,221, -135, 7, 14, 28, 72,233,116, 58, 99,130,150,176,176, 48,138, 36, 73,220,187,119, 15,141,141,141, 14,253,230,127, 47, 31,141, 83, -167, 78,129,220,227, 11,138,162, 16, 31, 31,111,124, 71,233,231, 72, 48,157,249,136,138,138,122, 17, 0, 98, 98, 98, 74, 12, 10, -128,106,215,174,132, 86, 11, 23, 46,108,117,234,212, 41, 76,152, 48, 33,194,158,156, 0,101, 41,119, 65,128, 64,130,137,245, 63, -235, 59, 57,184, 47,203,176,235,156, 26,139, 23, 47,198,170,163, 95,179,204,250, 20,145,191, 77, 15,128,249,188,191,105, 60, 0, -211,105,128,196,196,196, 52, 67,128,144,212,204,147,228,232,128,113,159, 60,122, 90,192, 48, 15,233,148, 9,246,113,227,198, 93, - 77, 77, 77,237,243, 56,190, 96,218,234,119,150,219,159,182,250,237,112,251, 55, 65, 66, 66,130,241,255,255,252,231, 63,248,241, -199, 31, 1, 64, 13,128, 79, 19, 63, 0,140, 31, 63,222,150, 2,160, 8, 13, 13,133, 92, 46,135, 90,173, 70, 69, 69, 5, 92, 93, - 93,193,227,241,140, 30,128,198,198, 70,200,229,114,168, 84, 42,200,100, 50, 76,159, 62, 93,180,127,255,254,102,159,143,182, 50, -109, 44,107,197,140, 25, 51,108, 42, 10,122,133,230,193,197, 0, 56,114,221, 28, 38,203,253,238, 67,124,124,188,116,201,146, 37, -162,248,248,248,180, 71,218,134,173, 88,255,166,176, 39, 22,192,154,245,239, 40, 6, 14, 28, 72, 93,188,120,145, 8, 11, 11,251, -148,110,218, 58,157,238, 19, 15, 15, 15, 84, 86, 86, 58, 52,198,124,252,225,104,164,165,165,129,216, 23, 0, 0, 56,246,177, 23, -198,127, 81,143, 81,163, 70,225,203, 85,167, 64, 81, 20, 99,111,197,145, 35, 71, 14,140, 30, 61, 26, 0, 42,118,239,222,217,254, -212,169,211,190, 20, 65, 97,226,132,137, 83, 14, 31, 62,156,116,248,240, 97, 70,114,104, 47,231,218,181,107,241,242, 48,151,166, - 22, 63, 40, 44, 89,188, 4,173,199,183,193,211, 26,183,244, 84, 27,101,171, 62,180,170, 32,132,133,133, 53,175, 0,152, 70,252, - 27,200,223, 24, 44, 69,123, 2,152,106,254, 22, 72,187, 69,176, 32,207,233,115, 82,177,177,177,125, 82, 83, 83,157, 57,224, 61, -173,237,140,128, 62, 10,220,104, 73,191,254,250,235, 0,192, 55,105, 75,198,107,134, 65,203, 26,174, 13, 29, 58,244,213,180,180, -180, 68,157, 78,135,186,186, 58,104, 52, 26,227,188,191, 82,169, 52, 46, 49,164, 3, 3,247,239,223,159,198,160,189, 16, 48, 44, - 1, 52,111,183,209,209,209, 20, 77,250,227,198,141, 19, 49, 81, 0, 30, 84, 30, 0,211,185,127, 83,242, 55,159, 22, 96,240, 62, -154, 3, 21, 31, 31, 47,125,233,165,151,176,103,207, 30, 71,189,101, 66, 83,207, 9,125, 78, 7, 12,206,188, 17, 77,221,186,117, -203,234,231,233,132, 63, 71,143, 30,181,234,177,187,125,251, 54, 99,207, 76,117,245, 56, 10, 0, 34, 34,242,145,159,159,111, 49, -186,188,170,106, 44,128, 26, 0,182,199,173, 94,189,122, 81, 23, 47, 94, 36, 12,131,229,167, 0,192,225,112, 62,185,115,231, 14, -106,106,106, 28,234,200, 28, 14,161, 87,216,105,242,191,172,197,143, 82, 53, 0,224,203, 85,167,236, 30, 35,232, 62,177,112,225, -194, 48,138,162, 16, 53, 41,106,250,161,164, 67,191, 50, 37,126, 83, 81, 47, 78,125,225, 58, 65, 16,189, 40, 10,224,190, 44, 3, - 69, 81, 88,178,116, 9,218,140,111,219,194,188,170,250,101,189,116,187, 99, 51, 9, 62,126,104,110, 21,128,113,240, 54, 91,198, - 70, 37, 38, 38,218,237, 50, 53, 33,109,167, 60,184,169, 60,122,253,255, 83,186,188,238,137,128, 89,221, 55, 89, 34,102,229,218, -125,131,129, 88, 44,214, 74, 36,146,253,163, 71,143, 94,148,156,156,188, 78,171,213,162,182,182,214, 24, 3, 0, 0, 21, 21, 21, -168,173,173, 5, 69, 81,176,167, 61, 69, 68, 68,136,142, 31, 63, 46, 77, 76, 76,108, 98,125,210,159,143,136,136,176, 43, 25,208, -131,128,226,220,219,142, 16,254,125, 4,111, 99,200, 38, 8,130,160, 28, 33,127,131,167, 45,205, 82, 95, 4, 0,147,160, 64, 70, - 88,176, 96,129,148,193,119, 50, 54, 52, 76,167, 42,239, 39, 34,102,201,241,186,118,237, 74, 93,191,126,157,118,249,127, 10,224, - 19,149, 74,133,188,188, 60,200,100, 50, 71,169,144, 34,247,248,225,216,101,253, 74,189, 29, 82, 53,118,159, 83,131,162, 40,156, - 62,239, 56, 39,166,167,167, 99,194,132, 9,162,195,135, 15,167, 29, 74, 58,228,168, 24, 14, 73,146, 46, 0,176,231,188, 6,139, - 23, 47, 70,155,200,182,204,213, 73, 11,104,108,108, 4, 0,228,231,231, 83, 91,182,108, 49, 42,100,166,177, 36, 59,118,236, 48, - 29, 31, 88,247,130, 19, 65, 91,247,150, 44,127,243,235,205, 77, 1, 16,134, 41,128,251,150, 77,217, 51, 5, 96,113,160,112, 30, -233,152,202,115,234,250,127,122,238,223, 81,216, 82, 72,236, 85, 88,172,185,251, 29,157, 6,176,230,238,119,112, 26,192, 52, 40, -136,176,227, 26, 44, 40, 1, 20,128,245, 18,137,100,115, 66, 66,130,134,207,231, 67,165, 82, 65,171,213,130, 36, 73,248,250,250, -162,166,166, 6,246,102, 83, 60,126,252,120, 26,244,235,254,169,125,251,246,193,160, 8, 24,151, 6, 30, 63,126,252,127, 98,112, -120,233,165,151,168,198,198, 70, 28, 58,116,200,222,246, 44,180, 81,223,212,204, 27,209, 34, 38,222,184,247,223,127,255, 62,227, -194, 28, 31,124,240, 1,197, 52,200, 83, 44,246,179, 41, 79, 44,246, 99, 36,204,205,205,141, 30, 36, 41,138,162, 32,151,203, 81, - 90, 90,234,240,156,191, 41, 34,191,168,111,114,222, 18,242,215,233,116, 4, 0, 56, 96,241,155,131, 60,248,123, 82,119,211, 76, -128,206, 66,115, 10,153,137, 2,192,226,113,244, 0, 24, 94, 28, 97, 79,249, 35,182, 64,211, 30,179,231, 33,236,176,152,109, 40, - 34,227,156,246, 92, 51,103,206, 20, 57,144,222,183, 89, 11,205,130, 5,218,156,117,202, 40,104, 76, 44, 22,107, 1, 16,211,167, - 79, 23, 22, 22, 22, 74, 21, 10, 5,116, 58, 29,122,245,234, 37, 26, 52,104,144,195,239,123,223,190,125,166, 75,206, 28,242, 26, - 61,232, 24, 0, 91,231, 76,244, 69, 67,116,120, 83,194, 57,125,218,110,183,191, 97,173, 63, 53,243,198,253, 10, 28, 69, 81, 20, -157, 35,192, 68, 33, 51, 6,204, 57,218, 55, 0, 96,239,222,189,132,179,250, 26,211,123, 0,160,186,186, 26, 93,187,118,165,234, -234,234,208,185,115,103,100,103,103, 59,101,172,227,188, 84, 3,130, 32, 48,229,133, 88,218, 13,131,213,171, 22, 24,255,183, 55, - 99,166,179, 32, 22,139,201,205,167, 54, 59, 85,230,156, 57,115, 12, 94, 23,137, 39, 0,173,225,160,196, 98, 49,105,114, 15, 59, - 29,240,184, 43, 0, 79, 16, 90,220, 73, 31, 87, 55,148,179,159,235, 1,120, 97, 30,104,189, 25,230,248,141,223,113,227,198,141, - 71,252, 70, 72,226,241,150,167,175, 43,123, 51,202, 89,197, 39, 77,246,177,160, 44, 93, 51, 88,222,105, 79,195, 64, 82, 86, 86, -102,124, 31,249,249,249, 78,123, 39, 18,201,102, 74, 44, 94, 64,252,254,155,132,209, 7, 28,221,222,213, 17, 24,150,245, 57,125, - 76,104, 78,185,102,221,254, 15, 31,150,166, 6,136,135,217,208, 88,176, 96,193,130, 5, 11, 22,143, 7, 56,108, 21,176, 96,193, -130, 5, 11, 22,172, 2,192,130, 5, 11, 22, 44, 88,176, 96, 21, 0, 22, 44, 88,176, 96,193,130, 5,171, 0,176, 96,193,130, 5, - 11, 22, 44,158, 10, 52, 89, 5, 64,231,188,118, 4,150,130, 9, 89,121,172, 60, 86,222,195,147, 23, 23, 23,215, 84,187,231,112, -140,217,229, 76,151,154,209,217, 20, 77,151,158, 89, 74, 31,236,233,233, 9,129, 64, 96,252, 60,135,195, 1,151,203,189, 79, 30, -189, 49, 19, 73,234, 87,121, 89,219, 44,135,125,191,214, 33,145,108, 17,114,121,174,160, 72, 45,230,207,127, 35,205, 17,121,155, - 55,111, 22,101,103,103,243,194,194,194, 82,205,179,238, 57, 40, 79,152,157,157,141, 77,155, 54,165,177,253,237,201,147,103,183, - 2,240,191,136,192,192, 55,154, 84, 92,101,229,118,226,177,146,247, 70, 32, 5, 0,149,219, 43, 9,211,255, 91, 32,178,133,201, - 61, 31,184,188,255, 89,108, 93,183, 70, 88,113,245, 28, 70,249, 85, 72,219,107,139,144, 67,117,197,133, 70,127,145,119,232, 16, - 44, 90,186, 44,205,214,231,207,156, 57,131, 17, 35, 70, 24,137,159, 38,108,130, 32,238, 35,108,146, 36,141,199,157, 59,119, 44, -202,187,120,241, 34,194,195,195,225,230,230, 6, 30,143, 7, 46,151,219, 68, 38, 77,250, 58,157,206,120,168, 84, 42,100,102,102, - 34, 36, 36,228,169,123, 63, 18,137,132, 16,139,197,212,230,205,155,133,127,255,253, 55,110,221,186, 37,245,245,245,197, 47,191, -252,210,162,246,191,101,203, 86,161,171,192, 31,190,126,207, 72, 27, 27, 74, 68, 91,182,108, 19,110,220,104, 95,238,135, 77,155, - 54, 9, 19, 19, 19, 79,230,228,228,224,208,161, 67, 8, 13, 13,197,123,239,189,199, 53, 93,123,239,128, 60,105,126, 94, 46, 66, -130,187,129,239,234,138,197,139,151,140,137,141,141,101,183, 2,126, 90, 61, 0, 79, 18, 34, 34, 34,108,106, 60,199,143, 31,183, -217, 49,105,130, 54, 39,110, 71,225,108,121, 15, 0,132,157,164,109, 51,181,172,147,229, 49,249,188,249,247, 63,217,196,178,121, -179,240,250,153, 99, 40,220,253,141, 84, 46, 87, 65, 51,132, 3,183, 14, 4,186, 23, 94,198,179, 94,148,180,166,226, 47,180,219, -252,255, 68,211, 23,124,214,172, 18,112,253,250,117,112,185, 92,140, 28, 57, 18, 60, 30,207,120,208, 10, 1,109,245,107,181, 90, -232,116, 58,104, 52, 26,220,185,115, 7, 39, 79,158,180, 40, 79, 46,151, 35, 43, 43, 11, 67,135, 14, 5,159,207,135,139,139, 75, - 19,153, 36, 73, 66,171,213, 66,171,213, 66,163,209, 64,161, 80, 32, 43, 43, 11, 13, 13, 13,143, 3, 89,115, 12,109,131, 3, 64, -219,146, 60,244, 18,137,132,136,139,139, 35,227,226,226, 16, 16, 16,128,127,255,251,223,152, 49, 99, 6,234,235,235, 17, 16, 16, -224, 80, 6,210,128,128, 0,227,243,124,244,209,135,248,121,103, 38,220,220, 90,129,203,229, 75, 27,234,139,236,150,153,145,145, -129,134,134, 6, 12, 29, 58,244,206,184,113,227,218, 86, 85, 85,225,216,177, 99,186,249,243,231, 99,235,214,173,205,246, 17, 85, - 65,238,125,117,115,229,230, 77,164,121,185, 99,105,252,103, 69, 3, 6,246,233,120,183,184, 28,199,146,211, 78,238,218,181,123, - 92, 76,204,203, 39, 88,234,124,252, 65,167,254, 53,243, 20, 48, 82, 0,204, 83,183,218, 58,127,232,228,255,230,155,111, 54,123, - 79, 77, 77, 13, 0, 80, 76,148, 0,154,172, 91,106,173, 63, 8,121,166,150,191, 19,172,127,123, 73,155, 41, 89, 59, 91,158,233, -189,166,127, 1, 0,213,213,250,204,136,254,254,169, 79, 69, 71, 45,248, 51, 21, 33, 69, 82,105,145,156,196,180, 16, 46,158, 9, -210,130,244,167,224,226,207, 69,125, 21, 31,110,245, 10,244,204, 94, 47,253, 57, 62, 78,244,234,146, 21, 86,149, 0,130, 32,112, -227,198, 13,240,249,124,140, 25, 51,198, 72,218, 46, 46, 46,224,112, 56,160, 40, 10, 26,141, 6, 90,173, 22, 42,149, 10, 69, 69, - 69,144, 74,165, 86,183, 84,230,112, 56,208,104, 52,200,206,206,198,200,145, 35,225,230,230, 6, 87, 87, 87,163, 60, 90, 1, 80, -169, 84,104,104,104,192,149, 43, 87,160, 84, 42,141,211, 4, 76, 16, 19, 19, 35,228,114,185,210,250,250,122,240,249,124,148,151, -151,191, 61,109,218,180,122,129, 64,240,179, 35,164, 29, 19, 19, 51,147,203,229,238, 73, 78, 78,166,229,229, 76,155, 54,237,111, -137, 68, 50, 67, 44, 22,171, 29,177,132,227,226,226,164, 43, 86,172, 40, 7,208, 10,208, 79,181, 92,191,126, 29,173, 90,181, 66, - 88, 88, 24,126,250,233, 39,187,201,255,135,185,115, 49,113,192, 0, 0, 64,155, 69,139,224,230,222, 26, 13,117,133,168,147,229, -137, 98, 99,231,165, 89,203,231,110, 13,253,250,245, 67,121,121, 57,206,156, 57,211,153,195,225,224,202,149, 43,240,247,247, 71, -122,122, 58, 94,123,237, 53, 42, 59, 59,187,217,207, 87,125,181,180,201,185,167, 90,131,118, 90, 37, 22,191,255, 73,199,248,213, -255,193, 55,171, 55,162, 61, 71,135,141,171,215,164,190,246,218,107,176, 37,143,197,227, 71,254,116, 57,211,189, 0,238,203,255, -109,235,252, 97,194,153, 59,245, 61, 9, 48, 85, 2, 30,146, 39,192, 94, 75,157,176, 97,157, 59, 34,207,210,223,167, 42,113,213, -119,171,190, 20,134,102,255, 32, 45,231,234, 16,226, 3,116,238, 68,129,219,143, 15, 94,183,110,224,171,148, 80,157, 45,130, 74, -198, 3,151,116,129, 50,245,103,233,214, 13,171, 69,243,223,178, 60, 29, 64,187,231,115,115,115,225,231,231, 7,145, 72, 4,129, - 64, 0, 62,159, 15, 30,143,103,180,250,149, 74, 37, 74, 75, 75,113,234,212, 41,112, 56, 28,112, 56, 28, 52, 39, 79,167,211,225, -218,181,107, 24, 49, 98, 4,188,189,189, 33, 16, 8,192,229,114,161,213,106,161, 86,171, 81, 87, 87,135,191,254,250, 11, 42,149, - 10, 60, 30,207, 24, 11, 96, 11, 35, 71,142, 20,222,188,121, 83,122,251,246,109,212,213,213,129,207,231,163, 77,155, 54,235, 79, -159, 62,141, 97,195,134,241, 36, 18,201,143,246, 40, 1, 35, 71,142,156,122,243,230,205, 61,102,242, 66, 79,159, 62, 29, 58,108, -216,176, 93, 6, 37,128,145,188, 77,155, 54, 9,213,106, 53,202,202,202,104,151,183,177,146, 86,172, 88, 81, 18, 23, 23,215,126, -198,140, 25, 99,222,125,247, 93,187,198,191,173,219,126, 20,126,184,124, 89,147,178,178,117,235,208,230,197, 14,248,230,155,239, - 68,115,231,190,226,208,120,122,230,204, 25,233,159,127,254,137, 15, 63,252,176,142,203,229,122, 11, 4, 2, 12, 27, 54, 12, 82, -169, 20,201,201,201,104,223,190,189, 29, 61,143,192, 47,185,119,177,255, 86, 9, 14,254,254, 19,184, 92, 2, 75, 23,189, 74,246, -111, 19,200,217,178,248, 19,108,181, 87, 30,139, 71, 66,254,230, 74,164, 37,165,192,225, 85, 0,143,122,123,219,110,221,186,137, -108, 29, 15,219, 90,127, 16,242,156,104,245, 51, 37,109, 71,200, 26,166,214, 57,109,161, 27,228, 80, 14,202,179, 58, 80,251,251, -167, 58,100,253,111,216,176, 65, 56,111,222, 60,202, 90,153,249, 53,107, 48,189,127,195,134, 13, 66,243,107,230,101,205,214,215, -181,139,210,210,146, 58,180,242,226,161,155, 23, 5, 94, 32, 9,222,115,207,195,163,255,207,112, 27,248, 45, 92,125,220,192,111, - 80, 64, 46,215,161, 19, 87,142,244, 4,235,169,100, 57, 28, 14,120, 60, 30, 92, 92, 92,112,235,214, 45, 92,185,114, 5,222,222, -222, 8, 8, 8, 64, 64, 64, 0, 2, 3, 3,225,235,235, 11,153, 76,134,244,244,116,112,185, 92,227,220,190, 37,208,215,249,124, - 62,116, 58, 29,114,114,114,224,238,238,142,192,192, 64,180,106,213, 10, 65, 65, 65,240,244,244, 68, 78, 78, 14, 52, 26,141,113, -138,192,154, 66, 97,110,249,223,187,119, 79,154,151,151,135,174, 93,187, 34, 50, 50, 18,131, 7, 15,134, 92, 46,199,201,147, 39, -145,157,157,189, 93,169, 84,190, 98,135,229, 47,186, 87, 94,241,107,254, 93, 25,188, 66,134, 34, 52,242, 13,180, 31, 60, 5, 53, - 42, 14,142,167,158, 64,118,118,246, 52,165, 82, 57,159, 41,249,215,213,213,225,242,229,203,210, 51,103,206,160, 95,191,126,136, -139,139, 11, 4, 64, 26, 60, 0,237, 1, 64, 32, 16, 48, 38,235,173,219,126, 20,254,146,144, 36,244, 15,232, 35, 77,216,125, 25, -115,127,248, 1,201, 89, 89, 72,206,202, 66,155, 69,139, 0, 0, 26, 77,227, 41, 71,250,220, 11, 47,188, 64, 29, 60,120, 16,211, -167, 79,191,227,229,229,197,113,119,119,207,204,200,200,192,153, 51,103, 80, 89, 89,137,208,208, 80,251,148,210,172, 91, 88,253, -199, 85,108, 93,253,209,101, 30, 87, 1,142,174, 30, 95,175,253,129,179, 39, 61, 19,165, 28, 30,158,121,230, 25,150,101,159, 18, -240, 28, 37,248, 71,181,121,197, 3,179,176,255,183, 21,129, 7, 50,175,222, 66, 87, 61, 97,163,220, 46,165, 98,245,234,213,194, - 19, 39, 78, 72,115,115,115,173,150,101,100,100, 48,146, 69,223,151,145,145,129,234,234,106,233,234,213,171, 69,203,150,233,173, -114, 75,101,205,193, 91, 89,133,228, 66, 37,218,215,112, 49,192,155, 64, 80, 5, 16,194,243, 1,135, 8, 0,165,188,135,198,123, - 4,174, 21,146, 40,107, 84,130,199,225,160,175,191,171,212,218,239, 54, 85, 0, 92, 93, 93,145,151,151,135,246,237,219, 35, 34, - 34, 2, 92, 46, 23, 36, 73,162,170,170, 10,103,206,156,129,139,139, 11,248,124, 62,212,106,181, 85, 5,128,246, 14,208, 74, 0, - 69, 81,200,207,207, 71, 72, 72, 8,124,124,124,208,208,208,128,172,172, 44,232,116, 58,184,186,186, 66,165, 82, 65,165, 82, 89, - 29, 59,232, 32, 58, 0,168,168,168,144, 22, 23, 23,163,127,255,254, 16, 10,133,232,208,161,131,168,177,177, 17, 65, 65, 65,210, -212,212, 84,156, 63,127, 30,190,190,190, 67, 37, 18,201, 78,177, 88,172,179, 85,143, 21, 21, 21, 39,239, 85,203,224, 31, 58, 20, -221, 70,190, 4,223, 14,161, 80, 53,214,162,240,207,195,184,117,226, 39, 90, 30,163,247,107,136,125,144,150,150,150,162,117,235, -214, 16, 8, 4,162,203,151, 47, 75,227,226,226, 56, 6, 15, 0, 0,220,140,139,139, 35,153,180,193,109,219,127, 18,250,250, 61, - 35,245,245,127, 6, 28,142, 11, 52,154, 70,108,255, 81,138,185,175,139,104,143, 2,230,207,159,143,160,160, 32,210,222,190,247, -234,171,175, 82, 9, 9, 9, 24, 57,114, 36, 6, 14, 28,216, 25,128,246,196,137, 19,225, 5, 5, 5,112,115,115,131,155,155, 27, -162,162,162,198,236,221,187,247, 36, 19,121, 59,255, 46,194,183,127,221,196,182,149,203,171, 59, 60,211,185, 95, 99, 67, 13,126, - 63,242, 23, 46, 95,249, 27,190, 20, 9,126,217, 61, 68,189, 61,123,220,158, 61,123,255,183, 92,176, 79, 16, 44, 77, 31, 89,243, - 10, 88, 83,213,137, 25, 51,102,152, 90,208, 68,116,116,116,115,231, 79, 44, 42, 43,183, 19,166,199,227, 38, 15,120, 32,238,255, -230,172,246, 22, 61,179,163,214,185, 61, 30, 0,123, 17, 19, 19, 35, 76, 74, 74,106, 66,254,150,202, 28, 65,110,110, 46,146,146, -146,164, 49, 49, 49,194,230,202,172, 18, 87,101, 17,206,221, 85, 64,174, 35,113,186,136, 68,153,150, 7,157, 42, 19, 53,215,223, -196, 79,139, 98,113,232,152, 12, 87,170, 40, 92,170,208,226, 90,149, 22, 85,165,101,205,122,229, 76,149, 0,129, 64,128, 59,119, -238,224,230,205,155, 0,244,113, 49,127,100,194, 62, 90, 0, 0, 32, 0, 73, 68, 65, 84,252,241, 71,147,185,252,230,230,235, 9, -130, 48,122, 1,104,121, 20, 69,161,168,168, 8,157, 58,117, 66,105,105, 41, 72,146,132, 64, 32, 48,202,106,110, 74,193, 20,133, -133,133, 80, 42,149, 8, 15, 15, 71,135, 14, 29, 68, 92, 46, 23,222,222,222, 24, 50,100,136,200,211,211, 19,133,133,133,168,171, -171,187,194,180, 29, 20, 22, 22,130,228,240,209, 62,108, 28,124, 59,132,130,195,117,129,155,119, 16, 58, 13,137, 2,223,195,143, -150, 87, 96, 75,206,230,205,155,133,181,181,181,210,146,146, 18,116,236,216, 17, 34,145, 72,244,243,207, 63,167, 85, 85, 85, 17, - 0, 48,116,232, 80,173,225,214, 80, 31, 31, 31, 72, 36, 18,155, 1, 15, 2, 65, 0, 2,130,250, 67,167, 85,161,252,110, 6,202, - 74,206,140,173,172,200,250,200, 32, 15, 0,112,175,172, 12, 6,121, 46, 76,219,158, 88, 44,158,145,144,144,128,217,179,103, 99, -214,172, 89, 0, 64, 30, 59,118,140,151,148,148,132,185,115,231,142,191,120,241, 34,113,246,236, 89, 34, 46, 46,142, 81,228,126, - 78,157, 28,203, 79, 93,194, 87,239,197, 98,228,164,113,254, 58, 74,139,189,191,158,194,247,235,127,198,145, 37,175, 97,107,255, - 78,232,228,195,195, 71, 31,197,177, 65,128, 79, 8, 46, 93,186,100,149,252,155,245, 0,152,207,237,219, 58,127, 26,241, 0,150, -224, 57,132, 47,158,253, 66,180, 96,193,130, 39,161,190,155, 76, 41, 60,224, 32, 61, 70,239, 33, 42, 42, 74,120,235,214, 45,169, - 90,173,110,182,172, 37,168,169,169, 65, 99, 99,163, 52, 42, 42, 74, 84, 84, 84,116, 95,217,225,195,135,173,190,187,236,106, 5, -100,106, 18,217, 21, 90,148,214,106,209,250, 15, 30,250,237,205,197,157,130,107,248,251, 79, 53,180, 60, 46,212, 36,160, 84, 83, -168,161, 72, 4, 53,179,173, 61,189,220,143,158,187,167, 35,246,239,221,187,135,206,157, 59,163,160,160,192,232,242,231,241,120, -198,251,237,157,206, 51,205, 33, 64,255,125, 64, 83,130,181,112,110,204,135, 77,178, 38, 73, 18,141,141,141,250,193,145,199, 19, -189,249,230,155, 77,222, 93,125,125, 61,239,224,193,131,152, 50,101, 10,103,249,242,229,247, 86,173, 90,165,181,213, 22, 9, 66, -175, 16, 41,228,247,208, 80, 95, 36,154, 55,239,181, 52,137, 68,146, 14,224,171,250,250,122, 28, 60,120,208,168, 56,134,132,132, -168,153,180,237,149, 43, 87, 78,249,230,155,111, 18,163,162,162, 48, 98,196, 8, 0, 32,207,158, 61,203,249,237,183,223, 32, 20, - 10, 39,109,216,176,225,184, 61, 21,115, 87,174,194,171,201,127, 96,241,204, 40,204,120,117, 58,228,202, 58, 28, 56,152,134,181, - 27,119,226,191,227,159, 69,183,242, 98,150, 77,159, 2,101,128,169, 7,192,217,160,204, 58,178,173,115, 22, 38,120,208,228,239, - 68,171,221,154, 71,193,209,249,255,230,218, 5,163,246,114,248,240,225,180,238,221,187,139,252,252,252,154, 45,107, 9,252,252, -252,208,189,123,247, 38, 68,111,169,204, 18, 20, 58,111,104, 8,224, 66,165, 10,229, 58, 29, 78,228, 43,177, 55, 81,137,147,197, - 65,200,229,251,160, 88,166, 65, 81, 61,137, 70, 45, 32,215, 82,112, 13,104, 99,147,152,233,245,253, 58,157, 14, 90,173, 22, 1, - 1, 1,240,244,244, 68,231,206,157,161,209,104,140,229,150, 18, 2,153,203,163,215,247,107,181, 90, 40, 20, 10, 80, 20,133,142, - 29, 59,162,164,164, 4,109,219,182, 5,143,199,131, 74,165,130, 90,173, 54,126, 47,147,233,193, 78,157, 58, 65, 32, 16, 32, 51, - 51, 19,197,197,197, 82,157, 78,135,186,186, 58,226,207, 63,255,148, 54, 52, 52,160, 83,167, 78,240,246,246,126,158,233, 24,213, -169, 83, 39,112, 72, 53, 74,178, 82, 81, 91,156, 3, 82,167,129,162,174, 2,133,127, 30,134,186,177,134,150,215,133,137,114, 67, - 35, 32, 32, 64,186,105,211, 38,163, 23,167,170,170,138,184,118,237, 26, 12,164, 77, 2,104,109, 41,225,145, 57,180, 90, 5,180, -154, 6,184,121,180,129,192,205, 31, 18,201, 22,161, 88, 44,214,174, 88,177, 34,192, 68, 30,182,110,221, 10,153, 76, 70, 47, 97, -188, 15, 43, 86,172,160,134, 15, 31, 78, 13, 28, 56,144,250,236,179,207,126,159, 50,101, 10, 38, 77,154, 4, 0,184,120,241, 98, - 93, 82, 82, 18,102,204,152, 49,229,196,137, 19,135,153,212,217,138, 21, 43,168, 17, 35, 70, 80, 47,191,249, 54,198,236, 59,133, -101,255,154,134,119, 62, 88, 8,165,186, 1,183,243,138, 32,145,236,197,111,147,135, 65,216,177,149,195,125, 99,194,132, 9,236, -184,254, 8, 17, 22, 22,214,132,244,205, 3, 1, 31,106, 42,224,232,232,104,161, 61,231, 15,205,210,183,178,102,223,220,218,103, -106,253, 91,147,247, 70, 96, 32,245, 70,224, 63,238,124,243,115, 91,158, 8,103,201,179, 98, 73, 59, 66,212, 15, 12,102, 74,132, -195, 30, 0, 0,216,181,107, 87,218,228,201,147, 69,166,201,105, 44,149, 57,130,144,144, 16, 76,158, 60, 89,180,107,215,174,180, -230,202,172,126,190,123, 8,186,123,112,225, 69, 0, 26,138,194,141, 26, 53, 18,114, 85,216,117,174, 20,127,229, 85,163, 84, 1, - 84, 41,117,200,107,160,112, 87, 69,161, 65,173, 17, 53, 71, 94,244,210, 60,181, 90, 13,133, 66,129,182,109,219,162, 79,159, 62, - 6, 69,207, 31,131, 7, 15, 54, 18, 54, 77,218,214, 8,155, 38,116,141, 70, 3,181, 90, 13,130, 32, 16, 28, 28,140,218,218, 90, - 20, 21, 21,161,186,186, 26, 93,186,116, 1,135,195,129, 90,173,134, 74,165, 50,126,198, 22,130,130,130, 68, 29, 58,116,192,181, -107,215,112,244,232, 81, 28, 58,116, 72,122,232,208,161,147,167, 79,159, 6,151,203,197,115,207, 61,135,110,221,186, 41, 96, 8, -188, 99, 32,111, 74,107,127, 31, 84,229, 95,194,223,199,127,196,181,195,155,112,227,176, 4,119,206,255, 6, 87, 14, 73,203, 43, -177, 37,231,173,183,222, 74,107,221,186,181,200,219,219, 27,217,217,217, 40, 46, 46,150,198,199,199, 11, 77, 21, 1,131, 39,128, -147,144,144,128,222,189,123,219,124, 54,181, 74, 6, 89,109, 46, 92, 92, 60,224,235,223, 67,234,225,217, 30, 63,252,240,139,144, - 32, 56, 67,233,123,188,106, 83, 33,253,239, 59,136,232,209, 96,181,109, 31, 62,124, 24,110,110,110,232,221,187, 55,186,116,233, - 66, 79, 31,104,107,106,106, 26,246,237,219,231, 27, 22, 22, 54,101,207,158, 61, 73, 76,219,110,114,242, 97,120,123,123, 98,212, -232, 33,242,176,129,253, 48,245,205,185,144, 19, 90, 84,148, 87, 99,193,162,207,177,106, 80, 8, 6,182,114, 92, 73,158, 48, 97, - 2,245,245,215, 95,179, 74,192, 99,162, 8, 88,194, 99,179, 23,192,163, 94, 85,224, 8, 1,219,139,237,149,122, 5,194,148,168, -233,178,199, 65,222,227,234, 81, 48,243, 4, 80,246,120, 0,104, 44, 91,182, 44,109,236,216,177,162,193,131, 7, 91, 45, 51,189, -214, 28, 76,239, 31, 59,118,108,147, 96, 63, 75,101,205, 90,135,174, 30,162,190,109, 3, 49, 60,192, 21,207,250,241,209, 78,192, -129, 43, 69, 65,160,210,162,147, 39, 15, 53, 20,133,171, 13, 90,228, 52,106,209,190, 85, 0,186, 60, 59,218,170, 44,218,234,167, -151,250,117,234,212, 9,253,251,247, 71, 77, 77, 13,106,107,107, 81, 91, 91, 11, 47, 47, 47, 12, 29, 58, 20,106,181,218,152, 19, -192, 26, 97,211,202,132, 70,163, 1, 65, 16, 8, 13, 13,133, 66,161, 64, 69, 69, 5,202,203,203, 81, 81, 81,129,198,198, 70,132, -134,134,130,199,227, 25,229, 89,203, 43, 96,174,148,181,110,221, 90, 20, 28, 28,140,219,183,111, 35, 37, 37, 5, 25, 25, 25,112, -119,119,199,152, 49, 99,208,191,127,255,195, 2,129, 96, 41,211,101,123,187,118,237, 74,106,221, 42,232,149,224,182,190,104,200, -251, 19, 57, 41,219, 81,146,241, 59,252, 92,117, 24, 55,118, 12,250,247,239, 63,231,221,119,223, 61,200, 68,150,183,183, 55, 6, - 14, 28, 8,138,162,112,238,220, 57,100,102,102, 74, 75, 74, 74,164, 95,125,245,149, 48, 46, 46, 78, 68,103, 78, 28, 52,104, 16, -210,211,211,109,202,155, 63,127,110,154,172, 38, 87, 84, 93,113, 5,174, 2,127,180,105,247,156, 52,168,205, 96,169,151,119,151, -195,223,172,254,126, 50, 45,111,215,187,238,216,125, 86, 5,107, 74, 79, 78, 78, 14, 2, 3, 3, 49, 98,196, 8,242,217,103,159, -133, 92, 46, 71, 99, 99, 35,214,175, 95,239,217,163, 71,143, 23,165, 82,105,146, 61,125,226,239,191,115,208,185, 83, 7,188,252, -242, 20,247,143,255,189, 24, 85,245, 50, 84, 86, 85, 34,246,157,207,241,249,212,177, 24,219,169,117,139,200,127,237,218,181,232, -211,167, 15,214,173, 91,199, 42, 1, 15, 17,166,243,254,182,240,208, 50, 1, 58,115, 85,129, 33,185,143, 83, 50, 1,218,130,121, - 34, 30,103, 40, 1,206, 36,107,103,203,115,198,171,134, 19,210, 3,155, 41, 16,132, 21,143,133, 93,120,235,173,183,210,204, 63, -103, 90,182,109,219, 54, 70, 50,233,251, 44,221,207, 84, 6,141, 29,187,246,164, 45,127,117, 38,180, 25,201, 40,144, 1,158,132, - 11, 58,123,114, 80,162, 35,192,117,229, 33,189, 92, 7, 37, 9, 4,185,114, 17, 60,104, 20,222, 93,189, 53,173, 57, 5, 64,163, -209,128,203,229,162,107,215,174, 24, 56,112, 32,234,234,234,160, 84, 42,141,235,243,213,106, 53,252,253,253, 49, 98,196, 8, 36, - 37, 37, 25,167, 4, 44, 65,167,211, 25,179, 8,246,236,217, 19, 6, 55, 61,148, 74,165,177, 63,211,158,132,158, 61,123,162,186, -186, 26, 13, 13, 13, 86,251,178, 57,153,159, 62,125, 58, 45, 38, 38,102, 76,239,222,189, 79,154, 36, 2,170, 29, 57,114,228, 73, -129, 64, 48, 91, 44, 22, 43,237,169,203,211,167, 79, 39,196,196,196,212,245,238,221,251,160,137,188,202,145, 35, 71,174,127,247, -221,119, 25,103,235, 89,184,112, 97,218,166, 77,155, 68,145,145,145,184,125,251,182,244,230,205,155, 40, 44, 44,132,151,151,151, -212,215,215, 23, 17, 17, 17,216,182,109, 27, 6, 13, 26,196,248,217,222,120,227,213,180,109,219,118,136,148,202,106,248,250,133, - 74, 61,189, 58,194,203,187, 19, 26,235, 75,146, 86,174,218,142,152,151,199, 97,215,187,238,198,122,178,100,177, 77,156, 56, 17, -201,201,201, 40, 46, 46,230, 84, 87, 87, 67,169, 84, 34, 61, 61,157,103, 80, 58,235,206,158, 61,107, 87,127,136,138,154,136, 3, - 7,146, 80, 87, 91,133,226,210,187,120,247,173,127,169,223,255,112, 5,127,234,152, 97, 24,161,170, 3, 92, 28,163,135, 9, 19, - 38, 80,159,126,250,169, 49, 29,116,112,112, 48,190,254,250,107, 0,160,142, 28, 57,194,166, 13,127, 68, 74,193,163, 84, 0,136, - 25, 51,102,152,186,208, 8, 51,119, 63, 97,175,251,223, 25,228,110, 36,249,202,237,176,149,109,207,158,224,191,202,202,237, 48, -117,197,155, 18,179,185,203,158, 9,105, 87,110,175,116,170,188, 39, 0,255, 83,131, 68,151, 97, 34,209,101,149, 86, 90,113,242, - 4, 92,180, 10, 92,174,167,144, 90,175, 5,159, 32, 16, 64, 81, 16,181,245,133, 95,155, 32, 81,135, 33, 66, 96,199, 30,155, 30, -128, 46, 93,186, 96,240,224,193, 80, 40, 20,208,104, 52,224,243,249, 70,194,166,173,244,160,160, 32, 12, 31, 62, 28, 41, 41, 41, -205,122, 0,120, 60, 30,250,247,239, 15,130, 32, 32,151,203,141,222, 5, 90,105,167,179, 11,146, 36,137,190,125,251,226,143, 63, -254,128, 61,193,149,187,118,237,146, 2, 32, 36, 18, 9, 1,192, 19,250,108,123,133, 98,177, 88,227, 72, 93,238,218,181, 43,201, - 32,207, 19,128, 63,128,106,177, 88,108,119,110,226,133, 11, 23,166, 1,192,134, 13, 27, 68, 46, 46, 46,200,207,207,135,191,191, -191, 20, 0, 74, 74, 74, 48, 97,194, 4,172, 89,179,198, 46,153,243,230,205, 73,147, 72,182, 8,213,106,153,200,173,174, 64,234, -237, 27, 12,119,207,118,112,247,108,135, 99, 39,238,129, 24,219,188,197,253,211, 79, 63, 17,243,231,207,167,170,171,171, 49,113, -226, 68,117, 64, 64, 0,159, 36, 73, 20, 22, 22,218,237, 17, 3,128, 29, 59,126, 34,196,226, 88,202,251,122, 38,222,122,235, 13, -116, 8,237,206,255,122,241, 27,228,142,141, 63,113,214,115,149, 14,181,229, 9, 19, 38, 80,203,151, 47,135,175,175, 47, 74, 75, - 75,225,230,230, 6,146, 36,225,225,225,129, 47,191,252,146, 85, 2, 30, 2,194,194,194,172,122, 1,152,166, 2,118, 58, 30,243, - 85, 5, 68,229,246, 74,139, 23, 28,180,254,137,237,149,247,203, 51,183,212,105,215, 61, 3,210,118,182, 60, 22,143, 17, 12,100, - 67,188, 20, 53, 65,232,163, 85, 73,185,119,242, 17,162,185, 11,175,128,214, 24,214,183, 7, 2,218, 7,138, 62,216,180, 51,109, -119,198, 66,155, 94,180,174, 93,187, 98,196,136, 17,198,249,120, 46,151, 11,149, 74,101, 76,221,107, 58, 77,208,177, 99, 71, 12, - 31, 62, 28,105,105,150,187,158,155,155, 27,194,194,194,192,227,241,160, 86,171,141,159, 51, 93, 58,104,186, 17, 16,135,195,193, -128, 1, 3,144,153,153,105,119, 29, 24,188, 3,245,134,163,197, 48,144,126,139, 55, 37, 48,120,136,140,253,112,211,166, 77, 66, -185, 92, 14,149, 74,133, 30, 61,122, 32, 62, 62, 94,106,223,115,197,166, 1,128, 68,178, 69,164, 80, 84,192,213,213, 15, 46,124, - 47, 41,135,195,195, 47, 9,135, 69,175,204,142,106, 86,222,214,173, 91, 9,137, 68, 66,124,251,237,183,164, 66,161, 0, 0,132, -134,134,218,149,126,217, 20, 18,201, 22, 98,219,182,173, 19,230,126,250,109,178, 94, 30,197, 9, 13,125, 6,161, 47,190,248,202, - 91,111,189,149,224,136,204, 85,171, 86,177,157,250, 49, 81, 2,154, 35,255,135,170, 0, 60,169,112,230,178, 63,115, 98,110, 41, - 81, 59, 81,158,179, 21, 6, 86, 1,113, 0,123, 14, 31, 73,107, 82,119,117,133, 56,125,187,144,241,231,163,163,163,225,231,231, -103,140,240, 39, 73,210,232,194,167, 61, 0,116,208, 31,189, 35, 96,112,112, 48, 8,130,192,238,221,187,239,147,183,118,237, 90, - 36, 38, 38, 26,239,213,233,116, 54,183, 3,230,243,249, 24, 52,104, 16,152, 68,199, 63,193,202, 90,139,219, 58,173, 8,232, 73, -125, 59,244,225, 88,164,148,137, 60,131,178, 68, 0,192,166, 77,155,168,133, 11, 23, 18, 39, 78, 56,190, 52,127,222,188,249, 71, - 12, 94, 19, 14, 73,146, 58, 14,135,227,102,239,244, 11, 13,214,186,127,188,148, 0,155, 3,181,163,251, 8,179, 96,193,130, 5, - 11, 22, 44,158, 92,112,216, 42, 96,193,130, 5, 11, 22, 44, 88, 5,128, 5, 11, 22, 44, 88,176, 96,193, 42, 0, 44, 88,176, 96, -193,130, 5, 11, 86, 1, 96,193,130, 5, 11, 22, 44, 88, 60, 21,104,178, 10,224,210,165, 75, 14, 71,112, 90, 10, 38,100,229,177, -242, 88,121, 79,165, 60,234,133, 23,197,248,253, 55, 9, 36, 18, 9,199, 82,182, 62,182,254, 88,121,157, 58,117, 50,222, 83, 88, - 88, 72,176,245,247,112,229,217,173, 0,208,157,187,153,251, 29,121,192, 39, 89,158, 35, 50, 31,247,223,219, 4, 18,137,132, 15, -192, 27,128,187,161, 61,144, 0, 42, 29, 73,158,242,128, 65, 57,235, 55, 91,169,211, 71,178,124,105,245,234,213,194,115,231,206, - 73, 79,157, 58, 5, 0, 24, 61,122, 52,134, 13, 27,198, 56,149,240,163,120, 15, 47,188, 40,198,196, 9, 3,181,128,152, 39, 22, -139, 73,176,203, 62, 89,152,161, 83,167, 78,212,228,201,193,198,243,164, 36, 80,182,148, 0, 22,143,216, 3, 96,236,225,123,239, -223, 0,130,152, 89,211,146,239, 33, 28, 32,222,135, 38,207,210,239,109,225,111,126,172,127, 47, 77,252,215, 46,159,254,113,239, -174,245, 99,219,180, 15,110, 45,147,105,224,227,227,130,178,146, 60,178,119,239,254,213, 18,137,100,176, 88, 44,190,109,143, 76, -241,156,254, 84,126, 94, 14,242, 10,148, 40,186, 75,161, 99, 91, 2,193, 93, 4,232, 22, 28, 10,201,142,236,199,165,243, 91, 82, - 36,232,189, 6, 30,250, 51, 94,185,114, 69, 26, 22,118, 20,155, 55,203,145,150, 6,124,242,201, 49, 20, 21, 21, 73, 39, 79,158, - 12,129, 64,128,210,210, 82,209,212,169, 83,225, 12,133,224,149, 87, 94,161,100, 50,153, 40, 34, 34, 2,239,188,243, 78,154, 3, -109,134, 35, 22,139, 49,113,194, 64, 50, 54, 54,150, 7,108,193,239,191, 1, 18,137,132, 96,154,179,159,197,255, 14,212,234,229, - 72, 73,137, 69,100,228, 22, 76,158,188, 10, 73, 73,250,190,199, 42, 2, 15, 7,108, 34, 32,123, 24,214,132,236, 9, 2, 32,247, -248, 61,181,191,117,253,186, 53,175, 30, 58,248, 67, 92, 72, 72,247, 30,211, 94, 28,141,142,237,189,225,235,227,138,154, 90, 37, - 74,238,118,228,220,202,175, 9, 60,116,240, 7,233,250,117,107,190,125,123,209,210,117,182,228,189,251,246, 44,225,237,156, 67, -210,242,210,108,188, 20, 5, 12, 15, 7,130, 59, 3,185, 5, 20,206, 92, 80, 32, 89,154,141, 41,227,189,169,174,161,147, 68,223, -173,223,233, 40,145, 57,211,242, 39, 44,200,126, 36, 74, 64,117,117, 53,222,121, 71,142,160, 32, 32, 58, 26, 88,185,178, 1, 89, - 89, 89,208,106,181, 16, 8, 4,104,213,170,149,244,208,161, 67,152, 63,127,190,104,235,214,173,118,213,221,194,133, 11,133, 87, -175, 94, 69,235,214,173,165,251,246,237, 35,126,249,229, 23, 0,144,166,166,166,226,141, 55,222,192,246,237,219,237,253,173,124, - 0, 72, 62,114,145, 3,108, 33,245,127,239,207,241,207,130,181,254, 1, 96,250,244,253, 72, 73,209,255,141,141,205, 3,237, 17, - 96,189, 1, 15,151,248, 77,203,205,149, 0, 54, 8,208,130, 23,224,105, 38,127,137, 68,194, 59,158,178,247, 99,209,168,129, 61, -166, 69,133,162,127,239, 86, 8,240,115, 3, 1, 2,222,158,174, 8, 13,246, 71,196,232, 46, 24, 61, 98, 64,231,227, 41,123, 63, -150, 72, 36,109,108,201,188,157,115, 72, 58, 50,188, 14,123,215, 3,115,163,129, 30, 6,207,159,135, 59,208, 51, 4,248,108, 9, - 48,180,127, 29,110,231, 28,146,182,228, 21,181,212,235, 97, 67,145,120, 36, 3,146,191,191, 63, 14, 29,114, 67, 69, 5,144,152, - 8,212,212,240, 16, 18, 18,130, 73,147, 38,209,219,189, 34, 45, 45, 13,153,153,153,210,213,171, 87, 11,153,202,141,140,140, 20, - 94,187,118, 77,202,231,243,165, 53, 53, 77, 61, 89, 10,133, 2,219,183,111,135, 72, 36,178,183, 62, 73, 0,248,253, 55, 9,146, -143, 92,228,252,254,155,164, 69,191,125,222,188,121, 20,125, 52, 87,198,176, 93, 80, 14,148, 53,139, 45,155, 55, 11,183, 44, 89, - 34,188, 52,127, 62, 85, 52,113, 34,117,126,206, 28,106,195, 59,239, 8,183,108,222, 44,108,201,111,110,105,155,177, 36,131,105, -217,131,150, 71,187,254, 39, 79, 14, 70,108,108, 74,147,191, 52, 38, 79, 14,110, 18, 31,192,226,193, 32, 44, 44,172,201, 97, 73, - 57, 96, 21,128,199,129, 5, 30, 34,174, 93, 62,189, 50, 36, 36, 36,116,240,192,182, 77, 27, 2,135, 0,159,207,133,155,128, 7, - 23, 23, 14,130,187,250, 33, 56, 56,164,213,181,203,167, 15, 73, 36, 18,171,158, 34,241,156,254, 20, 23,117, 88, 50, 23, 80,170, -128,219, 69, 64,141, 12,168,173, 3,118, 30, 4, 22,125, 10,196,173, 6,134, 13, 4, 56, 84, 29,196,115,250,179, 29,223, 4,125, -251,246, 21,253,254,123, 79,180,106, 5,204,154,197, 67,155, 54,207, 98,244,232,209,162, 67,135, 14, 17,147, 38, 77, 18, 69, 70, - 70,162,117,235,214,184,120,241, 34,246,236,217, 35,157, 62,125,186,240,251,239,191,111,150,128, 70,142, 28, 41, 84,169, 84, 82, - 23, 23,151,102,191, 91, 42,149, 98,236,216,177, 76,200,140,154, 61,123, 54, 37, 22,139,213,134,152, 17,152,144, 63, 1, 0,179, -103,207,182, 91, 65,203,200,200, 48, 30,205,149, 57,216,109,137,150,116,239, 45,155, 55, 11,187,221,188, 41,157,122,233,146,180, - 99, 78, 46,248,117,117,104,155,115, 19,194, 63,206, 75,131,178,179,165, 18, 7,149,128,140,140, 12,204,155, 55,143, 90,180,104, -145,195, 74, 4, 45,131, 73, 25, 83,121,230, 68,207,164,204, 22,104,210,167,255,170, 39,135,176, 29,254, 33, 18, 63, 19, 60,169, - 10, 0,101,225,112,154,224, 7,248,124,148,147, 31,147,178,183, 46,174, 93,207,158, 16, 26,236,111, 36,125, 75,219, 52, 11, 92, -121,208,106, 73,132, 6,251,227,218,245,236, 96, 0, 62,214,228,229,231,229, 32,106,140,254,255,163,233,192, 27, 31, 2,155,119, - 2,165,247,128,155,185, 64,214, 53, 10,169,103,129, 19,231,128,200,209,250,251, 91,160,155, 17, 15,240, 21, 63, 18,197,100,217, -178,101,105, 13, 13,250,120,203, 89,179,102,225,252,249,243,132, 68, 34, 73,163,175, 85, 87, 87,139,122,246,228, 97,254,124, 96, -192,128, 11,208,233,110, 74,139,139,139,173,122, 82, 22, 46, 92, 40, 36, 8, 66,202,116,115,152,242,242,114,155, 94,153,217,179, -103, 35, 33, 33, 1, 0,168,244,244,116,181,201,187, 32,104,226, 79, 72, 72,192,236,217,179, 31,229,120,224,104,153, 69,168,174, - 94, 69,215, 63,255, 52,108,130,164,134,150, 36, 65,106,116, 32, 53, 90, 4,157, 78, 71, 29,195,253,214,173, 17,238, 95,127,253, - 37,125,238,185,231, 30,184, 18,224,136,119,161,165,228,175,158, 28, 98,241, 72,137, 77, 97,217,249, 49,131, 69,203,174,153,224, - 55,202, 65,195,153,114,162, 60,226, 49, 24, 92,154,125, 6, 27, 65,133,148, 51,234,207,145,192, 69,137, 68,194, 75, 79, 63,210, -171, 93, 27, 79, 80, 20,112,250,124, 17,228, 10,253,174,171, 3,251,183, 65, 80,128, 27,138, 74,234,201,220,219, 53, 28, 30,143, -131,238,221,252,208,174, 93,136, 47,244, 91,180, 90, 68, 94,129, 18,195,195, 1,149, 6, 56,114, 10,144,158,167,208,174, 53,129, -110,157,128,177, 35,128, 30,193, 4,120, 92,253,214,226, 67,195,128,111, 36, 74,166,245, 77,216,249, 63, 83, 37,130,194,253,177, - 0,212, 35,106, 91, 0, 64,111,231,138,126,253,250,137,204,175,113,185, 92,105,175, 94,229,136,139,211, 63,230,138, 21, 57, 40, - 40,232,109, 85,150, 82,169,180,105,249,155,162,160,160,192,230, 61, 9, 9, 9, 70, 43,159, 86, 4, 76,174,209, 10, 2, 97,184, -246, 56, 56,237,136,150,142, 27,221, 43,171,164,106,141, 6, 28, 14, 7, 20,151, 11,146, 36,161, 33, 73,144, 58, 29,116, 58, 18, - 29,238,222,149,182,164,189,200,229,114, 0,144,206,155, 55, 15, 4, 65,216, 29,223, 97, 74,248,219,182,109, 35,154, 43,123,152, -228, 15, 0, 41,177, 41,136,220, 18,137,233,251,129,216, 20,253,255, 52,249,171, 39,135,128,159,148,203, 50,239, 67,132,169,219, -159,209,118,192,214, 86, 1,180, 96,117,128,181, 40,118, 71,162,219, 41, 27,131,187,195, 74,131, 21, 82, 37, 28,177, 34,154, 9, - 42,116, 68,158,213,207,208,223, 67, 0, 32,247,218,140, 93, 32,245,209,254,174, 0,128,162,210, 58, 40, 20, 90, 0, 64, 72, 55, - 63, 4, 5,184, 33,251, 90, 57,231,239, 91,213, 16, 8,184, 8,238,234,139, 26,153, 26, 0,172, 10, 46,186, 75, 33,184,179,254, -251,159, 31, 5,132,245, 34,224,202, 7,180, 90, 96,252, 72,192,215, 11,200, 47, 4, 34, 71, 1,157, 59,232,239,127,196, 32,204, -188, 39,143, 74,177,124, 32, 40, 47, 47,183,171, 31,214,215, 51,223,125, 55, 33, 33,129, 48, 81, 2, 76,189, 3,143,188,238,186, -117,235, 70,229,231,231, 19,142, 94, 55,135, 75, 94, 46, 84, 26, 53, 8, 46, 15, 58,138, 2, 1, 64,171, 35,161,209,146,160,116, - 58, 16,183,254,118,202,115, 95,189,122, 21,129,129,129,210,175,191,254, 90,244,193, 7, 31, 56,172, 4,152, 79,163,216, 75,220, -206, 34,255,194,194, 66,162, 83,167, 78,212,244,253, 77, 21, 2, 0,136,220, 18, 9,126, 82, 46,146,146,242,140, 43, 1,216, 88, -128, 71, 71,254, 86, 21,128, 39, 0,205,145,168,221, 4,219,194, 37,142,214,229, 62,224,213, 4,196,204, 26,123,191,131,240,241, -113, 65, 77,173, 18,129,254,238,136,158,210, 3, 90, 29, 9, 87, 87, 46,184, 28, 14, 40,138,194,164,241,193,136,138, 8, 6, 65, - 0, 85, 53, 10,248,248,184, 0, 64,181, 53,129, 29,219, 18,200,187, 67,161, 71, 48, 48,230, 57,125,101,223,204, 5,250,245, 0, -252,188,129, 9, 66,128, 36, 1, 30, 23,200,185,173,191, 63,191,136, 98,250,110,237,249,191,165, 3,201, 35, 89, 6,184,105,211, - 38,225,234,213,171,145,151,151,135,244,244,116,233, 55,223,124, 35,242,244,244, 52,110, 59,171,211,233, 68,215,175,183,146,254, -231, 63, 37, 32, 8, 2,229,229,161, 8, 13,237,130,156, 28,203, 83, 41, 36, 73, 90, 44, 31, 59,118,236,253, 94, 36,138,194,201, -147, 39,237,250,205,166, 74,192,227, 68,254,206, 80, 18, 76, 81,221,161, 61,248, 55,255, 6,229, 2,240, 73, 10, 4, 1,104,116, - 90,168, 41, 29,228, 90, 45, 20, 33, 61,128,235, 55, 91,252,236,125,250,244, 1, 65, 16, 14,145, 63, 0, 12, 30, 60, 24,219,182, -109, 35,250,245,235, 71, 53, 87,102, 11,219,182,109, 35,204, 9,223, 82,153, 61,136, 77,249,135,248, 1,220,103,249,211, 1,131, - 73, 73,121, 44, 83, 63, 2,242, 7,216, 32, 64, 83, 18, 49, 63, 90,108, 21, 82, 20,192,121,169,230,129, 61, 52,181,215, 79,255, - 29,204, 21, 24, 94, 89, 73, 94,101, 81,137,222,234, 91,179,233, 47, 92,186, 90, 14,141,134, 4, 73, 82, 6,165,133, 48,198, 6, - 20,149,212,163,172, 36,239, 54, 0,171,102,101,112, 23, 1,206,102,234,255, 15, 12, 7,178,174, 1,177, 49, 64, 72,103,189,219, -255,139,245, 0,223, 5,224,112,128,179,153,250,251, 91, 64,208,206,142,161, 48,127,223, 15,221, 26,185,126,253, 58, 4, 2,125, -157, 28, 62,124, 24, 9, 9, 9,210,180, 52, 61, 23,172, 94,189, 90,232,239,239, 47,189,113, 67,139,173, 91,129,172,172, 65,224, -114,123,136, 58,116,232, 32,178, 38,207,195,195,131,241,119,107,181,218, 39,190,227,154,146,127,183,110,221, 40,107,135,189,202, - 66, 94, 80, 43, 81,141, 90,133, 58,181, 26, 10,181, 6, 42,173, 22, 26, 74, 7,185, 70,131,122,181, 26,165,237,218,137, 90,242, -220,238,238,238,240,240,240, 16,109,219,182,141,112,196,253,111, 74,244,182,202,236, 81, 2, 6, 15, 30,108,179,140,137, 23,192, - 26,249,155, 90,255, 44, 30, 45,249,179, 10,192, 67,192,131, 94, 82, 72,237,245, 3, 5,198,138,134,182,119,239,254,165,185,183, -107, 64,146, 20, 62,124,119, 40,114,114,171,113, 35,167, 10, 4,129, 38, 1,129, 36, 73, 33,247,118, 13,122,247,238,127, 21,128, - 85, 63,113,183,224, 80, 28, 62, 9,232,116, 0,149, 15, 72,207, 3, 73, 39,128, 9,175, 3,162, 89, 64,218, 31,250,251,116, 58, -224,240, 73,253,253,143, 16,150,230,255,225, 12,101,207, 81, 84, 87, 87, 75,123,246,188,141,140, 12,224,252,121, 29, 58,116,184, -140,172,172, 44,233,228,201,147,169, 67,135, 14, 73, 83, 82, 82,112,239,222, 61, 12, 28, 56, 16, 47,189,244,146,104,255,254,253, -105,205, 37,241,161, 40, 74,100,205, 11, 96, 14, 90,241,176, 23,244, 20,192, 35,154,243,111, 2, 83,139, 62, 63, 63,159,176,118, - 88,186,191, 57,248, 13, 24,128,170,145,163, 80,173, 80,162, 70,163,130, 82,171, 69,131, 70, 7,153, 90,141,250, 49, 99, 17, 24, - 30,238,160, 87,144,192,224,193,131,209,183,111, 95,209,249,243,231,211, 90, 34,195,148,232, 45,149,181, 68, 9, 48, 29, 11, 44, -149, 49,129, 37,242,167, 45,127,243, 76,129, 44, 30, 62,249,179, 10,192,147,238,182,152, 89, 99,215, 52,128, 88, 44,214,245,238, - 55,114, 76, 94, 94,238,205, 63, 51, 75, 65,146, 20, 38,140,235,134,203,215,202,241,229,154,243,248,226,219,115, 70,242,255, 51, -179, 20,121,121,185,119,122,247, 27,249,182, 88, 44,214, 88,147, 41,217,145, 77,232,224,141,248, 31,244, 36,191,249, 11,224,191, -191, 2,162,161,192,128, 94, 64,218, 46,125,121,252, 15,128, 14,222, 45,201, 8,216,210, 85, 0,148, 13, 57,143,100, 46,178,177, -177, 17,125,251, 42,241,236,179,192,179,207, 2,131, 6, 81,200,207,207, 71, 82, 82, 18,254,248, 67,175, 61, 9,133, 66,132,135, -135, 51, 74, 15,188,127,255,254, 52, 38,196,174,213,106,225,229,229,101,183, 21,107,136,250, 55, 70,252,211,231,142, 90,176,244, -209, 92,153, 61, 74,128, 51,238, 3, 0,241,194,133,105,234, 33, 67, 68, 55,198, 71,136,202,158,121, 6,101, 46, 46, 40,235,209, - 3, 57,145,145, 34,221,115, 67, 69, 98,195, 20,141,189,120,246,217,103,209, 18,171,223, 84,134,173, 50,166,117,104,201,234,127, -246,217,103,109,150, 57, 2, 58, 71,192, 63, 73,129, 88,143,192,131, 2,147,165,128,108, 38,192, 7,104,153, 63,142,223, 33, 22, -139,171,214,175, 91,179, 54,229,232,158,247,139,239,214, 7,135,116,245, 67,212,248, 96,248,249, 10,240,255,219,187,246,248, 38, -170,109,253, 77,146,166,105,105,121, 83, 94, 90,105,121, 40,130,128,130, 88, 69,165, 81, 16, 99, 27, 64,218,136, 23,245,130,200, -105,229,120, 16,181, 66,208,123,188,162,247,120, 33, 28, 42, 92,185, 30, 72, 21,161,222,115, 84, 76, 11,150,242,176, 90, 78,234, -241, 40,120,160, 10,200, 67, 45, 45, 90,164, 64,161,208,119,210,100, 50,251,254,145, 76,153,166,121,204, 36, 83, 90,112,127,191, -223,252, 50,179,103,102,101,102,246,204,254,214, 90,123,237,181, 47,213,218,241,221,247,231,112,226,228, 37,148,151,159,248,122, -218,131,179,183, 2, 56, 21, 76,102,194,136, 84,237,151,165, 59,172, 95,151,214, 35,229, 62,224,157, 21,238, 76,128,229,191, 0, - 27, 63,118, 91,254, 46,116, 71,194,136, 84, 45, 62,251, 64, 14, 2,151,251,220, 78, 27, 5,112,230,204, 25,109,175, 94,125,173, - 7, 14,156, 7, 0,252,244, 83,119,220,126,251,205,232,211,167, 15, 52, 26, 13,206,156, 57,163, 77, 77, 77,149,148, 10,120,200, -144, 33,218, 31,127,252,209,234,207, 98, 99, 89, 22,195,134, 13,195,198,141, 27, 37,145,144,119,223,191, 96,155,132, 18, 11,224, -203, 90, 13,213,130, 13, 70,238, 82,200, 95,168, 4,180,121, 47, 14, 31, 14,187,190,195,181,208,165, 60, 55,177,255, 37,183,188, - 64,228, 47,132, 67, 63, 12,160,253,255, 87,196, 19,224, 79, 49,144, 52, 12, 48,140, 96, 57,185,199, 94,147, 16,247, 93,145,235, - 11,242,156,100,185,190,112, 2, 23,255,176,232, 5,179,217,108,254,232,232,225, 47,255,178,173,224,139,196, 1,131,135, 38, 9, -230, 2,216, 55,106,212,216,127,165, 78,159,255,114,102,102,102,147, 24,121,158,244,190, 76,230,188,177,100,203,206,159,240,223, -111,251,153, 11, 32,116,242,151,197, 97,210,213,200, 31, 0, 30,125,244, 81, 28, 58,116, 8, 79, 62,121, 0, 0, 48, 97,194, 4, - 60,242,200, 88,237,243,207, 63,223, 74,206, 95,125,245,149, 36,153,235,215,175, 47, 1,192,164,164,164, 36, 55, 52, 52, 88,149, - 74, 37, 20, 10, 5, 88,150,133, 90,173, 70, 76, 76,140, 54, 92,242, 7, 32,139, 18, 64,113,109,162,178,178,146, 41,202, 40, 34, -131, 22, 13,210, 98,136,239, 99,170, 50,138,172,212,250,239, 92,168, 36, 52,148,114, 55,188, 29, 33,143,233,226,215,215, 21,228, -241,158,128, 58,179,217,252,248,168, 49,247,240, 25, 99, 98, 0,244, 5,112, 6,128,205, 51,203,155, 36,120,187,247, 43, 78, 17, - 84,156,178, 1, 95, 30,234,236,231,208,149,242, 74,180,129,135,232, 91,175,225,200,145, 35,178,201,222,185,115,103,137, 92,247, - 39,232,247,103,188,202, 25,120, 18, 1, 81, 80,120, 43, 1,149, 75, 42,209, 85,191,189,107, 21, 98,179, 0, 2, 0, 19,234, 60, -194, 20, 20, 20, 20, 20, 20, 20, 87, 47,104, 16, 32, 5, 5, 5, 5, 5, 5, 85, 0, 40, 40, 40, 40, 40, 40, 40,168, 2, 64, 65, - 65, 65, 65, 65, 65, 65, 21, 0, 10, 10, 10, 10, 10, 10,138,107, 3,109, 70, 1, 28, 60,120, 48,228,168, 76, 95,193,132, 84, 94, -135,201, 11, 58,137, 77,103,202, 51, 24, 12,201, 0,172, 22,139, 69, 22,121,179,103,207, 78,230, 56, 78, 54,121,244,253,235, 28, -121, 11, 23, 46,156,157,153,153,249,113, 71, 94,159,217,108,142, 0,160,241,188,211,118, 0, 28, 0,146,153,153, 73,104,125, 80, -121,191, 37,121,114,121, 0,136,136, 69, 10,228,150,119,197, 64, 46,174, 34,164,113,173,232,235,243, 16,161,108,247, 43,144,135, -236,236,108,109,128,231, 41, 89,222,145,183,187, 35, 92,121, 60,102,222,190,203,154,208,189, 16, 0, 48,126,252,248,176,235,115, - 68,255, 45,184,161,223, 30, 68, 69, 69, 97,202,148, 41,157,253,126,144, 16,150,171, 89, 94,176,255,145,130,189, 29, 85, 41, 57, - 57, 57, 15,189,251,238,187, 47, 70, 68, 68,108, 83,171,213,165,106,181,250, 7, 0,102,165, 82,105, 97, 24,230, 47,102,179,185, -175,217,108,166,195,206, 40, 40,252,121, 0,124,125,228,132,248,255,198, 37,230,134, 38, 30,129,114,201,147,100,193,202,137,244, -244,116,114,226,196,137,160,228,106,177, 88,172, 70,163, 17,113,113,113, 62, 83,174,102,101,101, 89,165,144,181,197, 98,177,102, -103,103,107,179,178,178,172,251,246,237,179,122, 41, 2, 33,201,227,142,253, 39, 20, 55,191,142,247,255,238, 0, 0,112,199,254, -243,178,118,120,243,235,146,158,203,135,127,238, 70, 56, 2,124,244,169, 91,150,110,114, 4, 70, 13, 59, 10,192,173, 4,148,150, -150, 74,170,155, 85,111,107,147,107,127,174, 65,163,163,151,181,169,165, 27,116,211,106, 49,120, 0,131,132,132,185,164,190,222, -142, 45, 91,182,116, 86,131,206,132,248,110, 94, 17,121,129,190, 49, 25,191,185, 80,224, 16,190,127,121,121,121,214, 89,179,102, -105,243,243,243, 75,194, 17,250,238,187,239,234, 84, 42,213,189, 42,149,234, 81,165, 82,217, 75,161, 80,196,152, 76, 38,197,146, - 37, 75,230,187, 92, 46,176,110, 60,234,114,185,244,102,179,249, 43,143, 55,192,225,105,255, 58,188, 27,116,250,244,233, 68,236, -179, 47, 40, 40,144, 84, 33, 51,102,204, 32,225,156, 79,113,237,131,207, 8, 40,117, 58,224,160,228, 63,126,252,120,148,150,150, - 74,106,176, 2, 53, 56, 34,229,181,147,111, 52, 26, 81, 81, 81, 1,143,139, 88,182,105, 93, 73,213,120,130,168, 17, 96,122,125, -200, 0, 0,211,123, 41,147,158,158, 30,180,117, 21,146,117,117,117,181,213, 31,249, 27,141, 70,152, 76, 38, 73,228,239,217, 70, - 82, 82,146, 54, 41, 41, 41, 44,121, 60,217,243,191, 43,255, 11,109,200,127,105,154, 6,171,242,237,162,158,213, 71,107, 99,200, -232, 4, 5,154,108, 4, 47, 60,161,193,190,163, 44,108, 77, 4,205, 14, 64, 59,238, 40,142,254,228,194,248,241,227,137, 88, 37, -192,248,199,155, 72,249,119,245,136,237,174,198,128,129, 49,232,215,127, 24,126, 41,119, 96,200,205, 78, 68,104,170, 81,188,237, - 2, 30,124,240, 65,242,233,167,159,210, 6,239,234, 65,235,244,131, 22,139,197,170,215,235,145,159,159,111,245,245,189,238,223, -191,159,188,246,218,107,216,177, 99, 71,192,250,221,184,113,227,125,106,181,122,180, 90,173, 94,164, 86,171,163, 79,157, 58,133, -225,195,135, 67,169, 84, 34, 54, 54, 22, 39, 78,156, 64, 76, 76,140,106,255,254,253, 61,247,238,221,251,229, 51,207, 60, 51, 4, -192, 47, 0,212,112,119, 15,248,109,248,132,237,159,176,221,226,203, 25,134, 1, 35, 66,131,218,190,125,187, 95, 25,194,114, 41, -138,155,128,240,195, 58,191, 35,177,112,225,194,100, 79, 86, 74,138, 78, 34,253, 80, 61, 0,162,200, 95, 44,140, 70, 99,208, 99, -196, 16,151, 63,242, 95,185,114, 37,150, 45, 91,230,173,116,132, 68, 12,228,192,120,130, 62, 35,192, 36,124,200, 8, 45,254,188, -188, 60, 6, 0,248, 95,127,125, 46,222,100, 29,136,252, 61,158,129,160, 86,187,197, 98,177,122, 91,248,124,153,240, 25, 75,149, - 23,200,194, 95,154, 38,126,166,184,252,181,221,200,240, 27, 20,136,138,100,112,195, 32, 37, 46, 92,226,224,100,149,168,169, 37, -168,107, 36, 56,241, 43, 7, 40,128,190,209,135,249,231, 19,176, 81,120,249, 63,110, 76, 30, 49, 52, 17,123,207,158, 67, 66,124, - 63,140, 30,147, 8,101,100,111,220,144,112, 9,151,108,118, 84,159,117,225,215,115,118, 68,171, 42, 68,201,187, 2, 32, 50, 88, -246,178,203,243,199, 77,157, 72, 20,156,192,250,135, 70,163,209, 2,176,122,215,225,129, 3, 7, 68,145, 63, 0, 68, 68, 68,244, -212,104, 52,243, 46, 92,184, 16, 61, 98,196, 8,220,122,235,173, 80,169, 84,120,235,173,183,224,114,185,112,203, 45,183, 96,235, -214,173,216,191,127, 63, 14, 31, 62, 12,165, 82,249, 23,179,217, 60, 99,253,250,245,129,172,234,214,231, 39,135,199,210,108, 54, -107, 7, 12, 24, 96, 37,132, 4, 60,231,236,217,179,218,204,204, 76, 73, 15,148,151, 29,234,249, 60, 81, 31, 63,126, 60, 96,187, - 49,114,228, 72,173, 84, 50, 63,126,252,184,117,206,156, 57,232,209,163,135,150, 42, 2, 93, 19, 42,127,141, 79, 48, 75,189,171, -160,162,162, 2,203,150, 45, 11, 85,129,240,139,244,244,116,194, 12,202, 99,210,211, 19,136, 37,103, 34,176,249,110,194,196, 60, - 23,244,139,247, 69,214,222,164, 28,168, 91,192, 31,132, 10,197,190,125,251,172, 73, 73, 66,237, 17,236, 0, 0, 26,206, 73, 68, - 65, 84, 73,109, 92,255, 82,229,125,176, 36,198,111,227,246,216,234, 38,209,114,214,175, 95,159, 28,169, 92, 2,133, 2,136,142, - 2,106,235, 57,180, 16,130,110, 81, 12,236, 28, 96,107, 33,184,174,159, 2, 28, 11,148,157,114,161,162,162,194, 26,136,200, 22, - 63, 59, 53, 57,225,134,104,171, 90, 77,240,187,121,119,192,229, 34, 56, 91,237, 64,229,233, 90, 32,226, 20,162,122,181,224, 76, -245,207, 80,168,235,112,236, 88, 45,122,244, 10, 44,239, 10,130,241,241, 29,133,204,180,222, 19, 61,121,230,126,144, 44,239,226, -197, 41,109,182,123,247, 46, 14, 74,108, 18,149, 18, 34, 65, 73,113,241,223, 72,106,106, 42,120,210,183,217,108,173,117,200, 91, -254,133,133,133,162,234, 52, 50, 50,242,174,166,166,166,155, 70,142, 28, 9,173, 86,139,172,172, 44, 60,245,212, 83, 0, 0,167, -211,137,205,155, 55,163,180,180, 20,223,126,251, 45,182,108,217, 2,155,205, 54,140,227, 56, 93, 16,139, 93,214,247,105,231,206, -157,162,186,230, 24,134,145,252, 46, 11,101,135,114,190,231, 27, 46,153, 51,103, 14,170,170,170,124,238, 31, 52,104, 16, 66, 37, -240,170,170, 42, 84, 85, 85, 81, 69,224, 10, 67,232,238, 15,228, 13, 80, 73,181,216,229, 38,218,112,225,113,251,135,110,186,141, - 7,193, 64,128,217,225,254,112,152, 9,165, 76,122,122, 66,107,163,150,151,151,199, 32,103, 34,241,246, 4,136, 37,235,234,234, -234, 54,228, 28, 10, 89,139,133, 64,233,144,165,159, 88,224,254,247,121,240,134, 13, 27,200,249,163,207, 99,224, 8, 37,154,108, -151, 15,177,185, 8,236, 14,192,233, 41,115,178, 4, 68,225, 94,255,254,112, 41, 12, 6, 67,114, 89, 89,153,207,255,140,141,173, -179, 54,217, 20,232,219,187, 39,106, 47, 54,163,182,174, 22,251, 14,156,197,233,115, 4,234,110,205, 24, 60,172, 17,182,230, 11, - 24, 62,198,137, 33, 35, 91,176,229,157, 82, 60,252,240,195,201, 39, 79,158,164, 95,253, 85, 0,222,250,103, 24, 6,169,169,169, - 4, 0,118,236,216, 1,131,193,144,108, 52, 26,173, 82,200,223,108, 54, 71,214,214,214,206,117, 58,157,138,232,232,104,220,123, -239,189, 88,189,122, 53, 34, 34, 34,144,153,153,137,220,220, 92,148,150,150, 98,223,190,125,216,179,103, 15,190,255,254,123,244, -237,219,183, 47,203,178, 55,192,143,251, 95,232, 2, 13,214, 5,160, 80, 40, 68, 93,103, 71,118, 1,108,223,190, 93,150, 46,128, - 30, 61,122,104,171,170,170,172,254,246,133, 91,239, 84, 17,184,122, 60, 0, 87, 19, 24, 63,228, 36, 89, 11, 78, 79, 79, 39,150, -101, 39, 1,165, 26,232, 25, 1,244, 28, 2, 38,207, 35, 76,100,223,127, 7,128, 8,173,126, 0, 16, 90,254, 62, 26, 87, 36, 37, - 37,105, 3, 4, 3, 74,190,135,191,189,216,205,175, 71, 32,182, 62, 11, 63, 59, 8,206, 94,224, 0, 40, 16, 19,237,118,113, 58, - 89, 2,123, 11, 96,119, 0,246, 22,192,225, 4,236, 54,192,209,114,217, 75,226, 43, 32,229,111,111,119, 35,197,251, 26,112,125, - 66, 12, 72,132, 10, 23,108, 54, 88,191, 56,133, 99, 39, 78,227,226,197, 70,140, 26,239, 66,147,157,133,189,197, 5, 91, 51,135, -179,149,128,173, 9,216,182,109,155, 85,202, 4, 24, 20,178,121, 56,164,126,107,132,183,254, 53, 26,141,214, 98,177,148,240, 67, - 70,109, 54,155,117,194,132, 9, 82,100,177, 0,134, 1,224,198,141, 27,199,105, 52, 26, 69,110,110, 46,230,207,159,143, 21, 43, - 86,128, 16,130,111,190,249, 6, 95,124,241, 5, 14, 31, 62,140,186,186, 58, 12, 31, 62, 28,245,245,245,209, 10,133, 34, 46,152, -240,153, 51,103,250, 37, 84,169, 30,148,174,222, 5, 16,200, 11, 16,142,245, 79, 21, 1,170, 0,116, 8, 41, 26, 12, 6,173,160, -207,208, 91, 9, 96,132,214,134,199, 37, 31,146, 75,143, 39,253,188,188, 60,198,146, 51, 17, 80,171,193,228,229, 93,209,155,229, -163,254, 45, 22, 11, 99, 48, 24, 72, 48,111,136,119,108,128, 20, 66,247,133, 64,199,206,125,169, 9,131,250, 43, 48, 71,175,134, -189, 5,232, 17,203, 64,193,120,172,126, 16,216,155,129, 38, 7, 65,147,141,160,201, 78,192, 17, 64, 17, 32,230,122,238,226, 38, -220, 50,182, 2, 3,110,186,136,207,119, 87,227,226, 69, 59,198,221, 89,143, 49,189, 27,129,136, 22,216,155, 57, 84,159, 38,104, -106, 98,192,178, 12,122,247,101, 0,134,163, 95,241, 85,244,237, 10,222,213, 18,225, 47, 15,189, 94,223, 46,254,200, 71, 44, 0, - 95,233,195, 0, 28, 92,186,116,233, 93, 42,149, 42,230,253,247,223,199,166, 77,155,240,228,147, 79, 98,229,202,149, 96, 24, 6, - 63,255,252, 51,108, 54, 27,140, 70, 35, 88,150,197,211, 79, 63,205, 49, 12, 19,244, 3,144, 51,154,190,171,119, 1, 4,242, 2, -200, 97,253, 83, 80, 5, 64, 86,248,232, 71,102, 2, 28, 39,222,196,153,224,142, 80, 79, 79, 31, 76,128, 50, 88,222, 58, 9, 68, -141,104,245, 4,240, 74,129,152,110, 0,185,192, 91,243, 6,131,129, 8,173,127,222, 35, 32,220, 54, 24, 12, 16, 36,203, 33, 82, - 9,221, 27,130, 81, 0, 62,229,177, 46,160,169,153,160,197,225, 14,246,107,113, 16,168, 34, 47,239,179, 55, 3, 54, 39, 65,205, - 69,130,243,151, 8,190, 61,198,130,227, 0,131,193,160, 45, 43, 43,107, 87, 55, 44, 11, 84,157,114,224, 84,249, 37,252,115,239, - 37, 16,194,224,216, 15, 28, 82,231,176, 80,171, 8,206,159, 3,254,249, 25, 80, 95, 79, 64, 56,224,238,251, 24,104, 52,128, 78, - 55, 3,191,252,242,139,168,123,210,221, 9,178,123,111,135,196, 12,200,234, 33,242,244,249,135,141,222,189,139,187,156, 39, 97, -199,142, 29,237,202, 94,125,245, 85,178, 99,199, 14, 20, 22, 22,138,149,163, 0,112, 4,192,193,236,236,236,177, 61,123,246,140, - 1,220,110,240,247,222,123, 15,243,231,207,199,166, 77,155, 90, 45,245,236,236,108,212,214,214,162,190,190,190,177,185,185,185, -194,227, 65, 80, 7,250, 3,142,227,218,196, 67,241, 22, 60, 33, 68,180,251, 31,184, 58,186, 0,124,121, 1,228,182,254,121,153, -212,242,167, 10, 64, 88, 40, 45, 45, 13, 26,253,237,217, 47, 78, 96,100, 55, 88,134,252, 3,120, 59,129, 32,161, 27, 48,180, 5, -204,141,133, 12,222, 26,223,218,247, 31, 78, 55,128,247, 80, 64,127, 67, 3,125, 53,150,124,123,193,147,191,119, 0,160,199,138, -106, 45, 11,226, 1, 96,100, 38, 43,230,238,201,211,147, 79,159,217,109,229,250,113, 80,168,128, 8, 79,187,232,228, 8, 88, 22, -104,104, 32,112, 56, 1,214,233, 86, 10,102,204,116,123,111,252,184,236,153,164, 59,167, 39,183, 92,216,101, 29, 53,138,195,151, - 95,184,192, 40,128,243,103, 25,104,162,128, 47, 62, 5, 28, 54, 6, 12, 1,198,220, 22,129,170, 74, 14,147, 39,167,160,160,160, - 64,212,180,214,186, 59, 65, 86, 61,227,190,127,153,149, 0, 70,102, 5, 64, 22,121,193, 92,206,157, 65,254,190, 10,249,168,127, -225, 49,188,247, 46, 45, 45, 77,155,159,159,239, 79, 94, 35,128,147,223,125,247, 93,227, 61,247,220,211, 15,130, 49,253,239,189, -247, 94, 43, 33, 58,157, 78,184, 92, 46,148,149,149,161, 95,191,126, 23, 56,142, 19,165, 45,206,156, 57,211,159,165, 46,233,166, -175,134, 46, 0, 95, 94, 0, 57,173,127, 74,252,215,160, 2,224, 25,179,127, 69, 91, 24,222,202,181, 88, 44,188,197,203,248, 56, -134,240,228, 47,176,138, 37, 65, 56, 10,128, 47,147,106,249,123, 7, 0,122,208, 90,150,149,149,101,245,116,103,136,146, 39, 36, -127, 95, 49, 1, 82,229, 5,195,170,124, 59,130,201, 43, 40, 40, 40,233,211,147,193,253, 73, 17,224, 0, 56, 29, 28, 34,213,238, -199,212,208, 68,208,226, 36, 96, 93, 64,233, 17, 23, 92, 28, 65,176, 33,123, 5, 5, 5, 37,253,251, 49,152,156,172,196,195,143, - 41,209,216, 64,208, 80, 7, 52, 53, 48, 72, 24, 78,224,114, 50, 80, 41, 52,168,189,200,161,234, 87, 7,202,126, 16, 23, 48,166, -187, 19,100,237, 98, 96, 68, 60,176,238, 5, 96,209,155, 29,162, 4,200,233, 25,144, 69, 94, 7, 14,249, 11,229,217,113,190,200, -127,249,242,229,237,220,252,121,121,121,124,158,128, 18, 63,214, 63,224, 78,230,115,240,198, 27,111, 44,183,219,237,131,149, 74, -165, 38, 58, 58, 26, 0,144,159,159,143,180,180, 52,216,108, 54,216,237,118,180,180,180, 32, 38, 38,198,238,114,185, 10, 8, 33, -103, 69, 90,215,178,188, 31, 87, 75, 23,128,208, 11,192,175, 83,226,167, 10,192, 21, 35,127, 49, 50, 61,132, 79, 60,235, 0, 64, -132,195, 18, 75, 75, 75,219, 16,190, 47, 5,161, 29,148, 12,160, 86, 0, 81, 74, 32, 70, 5,180, 52,192,178, 34, 2, 88,251, 20, - 65, 84,111, 32,170,183,228,190,127, 63,228, 15, 31,100, 45,234,195,240, 38,127,239,152, 0,169,242, 36,144,127, 80,121, 53,181, -132,217, 89,226, 36, 26, 13,192,113,192, 45, 55, 42, 47,215,199,247, 46, 56, 93, 4, 46, 78,137, 89,179,102,137, 82, 78,206,157, - 39,204,238, 79, 93,132,101, 1,135,147,192,197, 2, 10, 6, 72, 78, 1, 26,106, 25,252,112,200, 6,155, 93,129,233,250, 89,216, -186,117,171, 40,242, 95,254, 20, 48,236, 58,247,246,208,193, 64, 7,121, 2, 40, 36, 32, 64,178, 31,146,146,146, 34,102, 52,128, -178,103,207,158, 7,109, 54,219, 95, 43, 42, 42,134,140, 29, 59, 54,145,101, 89, 85, 68, 68, 4, 10, 10, 10, 48,117,234, 84,216, -237,118, 52, 55, 55,163,172,172,172,190, 87,175, 94,127,183,217,108,239,115, 28,215, 4,145, 25, 0,133, 1, 9, 82, 93,255, 2, - 69,162,157,231,160, 43,118, 1, 8,189, 0,114,200, 9, 37,119, 0,197, 85,160, 0,116,134,229,239,195,250, 32, 94,215, 35,151, -149,226,215, 35, 32,214, 3, 32, 55,249,243,202,142,151,123,159, 8,203,164,202, 11, 22, 11, 32, 85, 94,147,157, 48, 77,118, 16, -133, 2,248,103,169,187,175,159, 15,248,115,247,251,207,146, 36,175,161,129, 48,140,194,147,147, 66,225,150,241,175,127, 0, 77, -141, 28, 8, 7, 76,159,158,130,173, 91,183, 6,173, 15,221,157, 32,198,199,129,158, 49, 64,213, 5, 32, 42, 18,224, 8,208, 77, - 3,188,145, 73,149, 0,137, 32, 34,190, 75,209,240, 69,254, 12,195,144,148,148, 20, 0, 64,106,106, 42, 97, 24, 38,144, 34, 16, -227,112, 56, 26, 21, 10, 69,241,160, 65,131,174,107,104,104,120,230,192,129, 3, 3,111,189,245, 86,142,101,217,230,186,186,186, -115,135, 14, 29,250, 57, 33, 33,161,188, 79,159, 62, 21, 54,155, 45,159,101,217,115, 25, 25, 25, 77,227,198,141, 19,165, 0,240, - 73,129,194,129,217,108, 22, 77,168,161,116, 1,132,115,190, 63, 47,128, 28, 47, 11, 37,255,171, 84, 1, 16, 49,214, 95,210,135, - 46, 33,119,128, 20,185,140, 32,202, 63,100,242, 98, 74,193,164, 39, 60, 72,240, 19,128,159,188,247,214,121, 22,105, 99,204, 61, -247,107,149,139, 92,189,158, 11,225,243, 12,120, 2, 4, 25,129, 55, 36, 36,121,127,123,177,155, 80, 41, 8, 69, 94,171,220,180, -180,203,117,194, 7,252, 89, 44,150,146, 80,228, 17,174,109, 29, 55,214, 3, 41, 41, 41,216,185,115, 39,195, 91, 85,162,234,227, -175, 87,156, 8, 59, 85, 94, 23,235,247,111, 99,177, 11, 55,188,201,159,143,219, 17, 6, 9,234,245,250, 64,242, 42, 29, 14, 71, - 36, 33,164,129,227, 56,179,195,225,248, 38, 62, 62,190,111,109,109, 45,243,202, 43,175,212,215,213,213,213, 12, 30, 60,184,161, -177,177,177,201,225,112,212, 59,157,206,150, 5, 11, 22,216, 36, 90,216, 97, 63,204,204,204,204, 14, 35,194,142,148, 77,241,219, - 84, 0,228,110, 61, 58,172, 53,242,144, 40,227,203, 90,150, 2,153,163,250,197,100, 11, 12,235, 15,164, 76,250, 35,135, 55, 32, -132, 58,241,187, 29,174,188,157, 59,119, 74,170,171, 14,176,238,127,107,242,228,148,205, 0, 64, 78, 78, 14, 81, 40, 20,224, 23, -161, 11, 91,167,211,129,227, 56,112, 28,135,140,140, 12, 38,200,168, 0,134,101,217,104, 66,136,139,227,184, 22,167,211,249, 15, -165, 82,201, 40, 20,138, 72, 0,145, 28,199,193,229,114, 41, 89,150, 85,179, 44, 59,112,193,130, 5,199, 5,231,118,248, 36, 64, - 20, 20, 93, 1,129,114,164, 48,161,206, 35, 76, 65, 65, 65,209, 5,208, 44, 32,116, 78, 96,216,168, 4,229,103, 0,244, 0,160, -161,196, 79, 65, 17,216, 3, 64, 65, 65, 65,113,181, 64,227, 81, 2, 56, 1,241, 43,112,121,230, 65, 21,128,129,158,117,154, 53, -138,130,130, 42, 0, 20, 20, 20,215, 8, 20, 0, 98, 4,219, 60,241,171, 5,164,207,121,142,163,214, 63, 5, 5, 85, 0, 40, 40, - 40,126, 35,109, 26, 37,125, 10,138, 0,218, 51, 5, 5, 5, 5, 5, 5,197,111, 89, 91, 62,120,240,160,112, 34, 29,226,149, 68, -135,160,237, 68, 59,149, 22,139, 37,158,223,246, 21, 76, 40,148, 39, 21,215,162, 60, 31,195, 22, 25,250,252,104,125, 92, 45,242, -226,227,227, 91,143,169,172,172,100,164,202, 91,184,112, 33, 50, 51, 51, 25,250,254,133, 38,147,126,191, 84,158, 20,121,146, 21, - 0,137,232, 39,242, 56, 98, 48, 24, 36,103,150,242, 55, 95, 60,218,143,153,246, 53, 27,160,175, 99,174, 56,120,130,241,140,133, -183, 90, 44,150,214,108, 93, 93,101,172,182, 94,175, 79, 46, 44, 44,108, 37,193,148,148, 20,237,206,157, 59, 75,174, 69,109,215, - 87,125, 28, 63,238, 30, 25, 54,114,228,200,206,190, 60, 50, 99,102, 38, 10, 62, 49,251,124,103,103,204,204, 36,158,125,126, 95, -156, 25, 51, 51, 3, 54, 2, 5,159,152, 67,126,233,226,227,227,137, 94, 63,180,117,187,176, 16, 36,152, 18, 16, 12,171,179, 87, - 39,111,255,108, 59, 18, 71, 37, 90,193, 0,199,191, 59,166,189,115,220, 93, 88,251,230, 90, 73,239,223,220,185,115,219,221,119, -110,110, 46, 77,238, 68, 65,209,129, 10,128, 90,236,129, 73, 73, 73,146,133, 7, 80, 0,124,146,168,247, 68, 27, 18,136, 54, 20, -205, 73, 76,227, 66, 44, 22, 11,140, 70, 35, 76, 38,147, 53, 64,154, 78, 49,255,223,230,152,193, 9,215, 3, 0,206,217,237, 96, -109, 45,238,194,218,122,158,228,196,165, 63,110,109,200, 11,219,228, 20,240,228, 22,151, 52,199,187,130,113,103,215,227,127,129, -160,235,157,209, 56,183,169, 15,158,248,195,168, 15, 57,239,129,204,152,153,137,135,116,183,217,129, 76,141,135,232, 67,250, 15, -129, 2, 33, 59, 28, 14, 35,138,138, 50, 48,109, 90, 14,244,122, 19, 10, 11,221,207, 42, 20, 69,224,137,103,159, 32,181,189, 47, - 98,141,121, 53,122, 69,247, 2,199,186, 96, 39, 45,214, 79,191,249,108,218,108,215, 35,228,174,196, 73,218,197,139, 23, 7, 85, - 4,230,206,157, 75, 22, 46, 92,232,243,153, 82, 37,128,226,183,140,131, 7, 15,122,123, 9,218, 29, 19, 78, 12,128,164,115,189, -167,175,149, 11, 27,204,230,228,176, 91, 95, 66, 68, 47, 98, 69, 26,141, 70, 16, 66,176,114,229,202, 64,231, 17,201,249,187,123, -118,199,225,138,143, 80, 86,241, 79, 92,170,250, 31,148,255, 57, 3, 91,159, 78,235,212, 23,237,240,247, 71, 90, 73,254,200, 17, -247, 58,112,121, 93, 88,206, 17,209,117, 34, 10, 82,234,227,248,241,227,152, 55,111, 30, 2,146,191, 8,133,241,254,251,119,135, -170, 56,250,197, 67,186,219,154, 51, 50, 50, 52, 15,233,110, 11,153,216, 61, 22,126,160, 37,100,235, 31, 0,210,210,220,179,242, -165,165,229,163,176,176, 28,122,253, 80,232,245, 67,219,116, 13, 4,253, 94, 55,108, 72,158,253,252, 35,228,119,127,152,143,151, -103, 46,197,109,241,183, 99, 72,247, 33, 24,210,107, 8, 70,197,221,130, 63, 76,249,125,209, 75, 47, 44,195,222,234,175,173,107, -214,172, 17,245,109, 95,184,112,161,205,114,199, 72, 27, 54, 47,254, 10,179,103,207, 38,194, 37,156,250,209,233,116,178,214,183, -220,242, 58, 18, 11, 23, 46, 76,150, 67,134, 12,114,250, 0, 24, 15,224, 37, 0,107, 1, 20, 1, 48, 1,248, 47,207,114, 19,165, -125,223,228,239,175,172,141, 7,192,104, 52,146,138,138, 10, 0, 64, 98, 98, 34,132,147,205, 88, 44,150, 54,219,222,251, 3, 89, -236,213,213,213, 86,139,197, 34,218, 19, 16, 76, 89, 16, 90,245, 79,123, 82, 97,122, 91,250, 82, 93,236, 57, 57, 57, 65,143, 41, - 46, 22, 53,183, 58, 49, 24, 12, 88,185,114,165,207,157,203,150, 45,131,201,100,130,209,104,244,123,140, 47, 12, 78,184, 30,167, - 47,213, 97,235,211,105,232,195, 76, 66,249, 59, 47, 34,241,225, 68,124, 94, 94,131, 89, 43, 55,117,234,203, 54,230,150,209,173, -235,163, 71,143,110, 83,206,123, 6,132,229,114, 91,246, 65,200,141, 24, 12, 6,204,155, 55,207,231,206,205,155, 55,195,100, 50, - 65, 55,233, 86,236,254,234, 59, 32,182, 27, 80,223,120,197,159,225,174,221,223, 70, 3, 57,216,181,251, 91, 89,228,157,251,115, -159,128, 4,211,127, 73,141,168, 15, 68,232,250,207,200, 40,130, 94, 63,180,245,151,135, 94, 63, 84,116,151,192, 59, 31,190,131, - 21,111,255, 9,247, 12, 79,134,171,165, 5,172,139, 5,163, 98, 0, 40, 65,192,225,220,249, 42,140,236,119, 19, 94,126,250,101, -252,105,213,159, 68,121,163,188, 27,182,148, 65,155, 1, 0, 91,182,108,105,115,238,236,217,179,137,119,153, 88,178,222,245,202, -110, 60, 4, 29,217,189,123,119,216, 94, 5,157, 78, 71, 86,173, 90, 5, 0,178,200,235, 72,226,175,171,171,227,189,101, 97, 93, -103, 93, 93, 29,223,166,135, 42, 39, 6,192,191, 1,248, 14,192,251, 0,166, 2,120, 16,192,239,225,158, 21, 18, 0, 46, 80,234, -111,139, 12,163,155, 99,114, 76,203,130, 91,241, 38,147,137,177, 88, 44,140,197, 98, 97, 42, 42, 42,192,175,243, 46,101,225,182, -175,253,254,192, 43, 21, 89, 89, 89,214,234,234,106,171, 47, 5, 65,184, 29, 36, 85,174, 47,171, 38,208,246, 21,255,192, 62,254, -248, 99,159,196,207, 48, 76, 59,242, 95,182,108,153, 40,153,191, 86, 84,162,241,189,197,152,181, 33, 31,131, 19,174, 71,255, 62, - 81,168,216, 86,225, 38,255,158,221,221, 7, 69, 40, 37, 95,171, 94,175,215, 6,218, 22, 3,142, 0,215, 69, 3,219, 51,129,184, - 72, 96, 84,175,203,110,255,248,110,192, 39, 25,151,203,165,130, 97, 24,159,139, 20,188,254,250,235, 62,137,127,228,200,145, 48, -153, 76, 88, 53, 47, 21, 71,202, 79, 97, 64,226, 64,160,169, 89,140,245, 15,145, 94, 0,209, 86, 94,193, 39,102,236,218,253,173, - 79, 75, 95,208,183, 47,233,198, 87,125, 64,252, 46,161,128, 39,125,254,215,161, 31, 38,233,252,102, 91, 51, 38,205,190,203,154, - 52,240, 14,180, 52, 53, 1, 74, 37, 84, 42, 21,148, 74, 37,148, 74, 21, 78,158, 60,137,173,219, 10, 78,219,157,205, 24, 18, 25, -143, 91, 39,143,155, 50,255,119,243, 37, 91,141,111,236,154,135, 7,140, 9,237,202,183,108,217,194, 72,245, 4,240,228,143, 33, -107,176,235,149,221, 97, 91,238, 58,157,142,172, 93,187, 22,163, 71,143,198,186,117,235,186,164, 39, 96,225,194,133,201,115,230, -204, 33,199,143, 31,183, 86, 85, 85,201, 34,175,170,170, 10, 85, 85, 85,225,120, 19,180, 0, 38, 3, 56, 4,224, 52,128, 1, 0, -126, 4,240, 11,128, 83,158,197, 6,138, 86,133,152, 39,127,225,186,183,178,124, 69,242, 0, 8,250, 94, 81, 81, 81,129,184,184, -184,118, 10, 2, 95,230, 75, 65, 16,217,184,134, 28,252,247,200, 35,143,116,216,189, 11,201,202,151,213,239,153, 56,136, 9, 70, - 22, 54, 84,162,241,225, 59, 64, 98, 95, 4,166,188,130, 70,124, 8,188,235,182, 22,137,229, 69, 68,252,251, 58,176,172,244, 68, -103,133,133,133, 37,194,231, 20, 36,247,186,111, 15,207,123,192,107, 27,128,235,175, 3,206,237, 80, 35,119,163, 3,243, 62,242, - 95, 46,201,188,151,121, 62,123, 97,176,223,153, 79, 86, 34,118,148, 6, 49,195,159,195,199, 43, 23, 96,236,232, 1,184, 49,245, - 79,162,234, 67,204,165,223,127,255,110,236,217,163, 19,211,151,207, 0, 32, 94,228,207,240,129,127,161,244,235,139,181,240,197, -192, 31,209, 23,121,121, 2,130,225, 76,245, 25, 60, 96,120, 0,177,221,123,193,197,176,248,242,139,127,160,161,177, 17,250,233, -211,113,190,186, 26,121,249, 91,241,212,147,243, 6, 71,106, 34,161, 32, 17,152,118,219,180,226, 31,173,235, 66,178, 26, 47, 93, -186, 20,246,125, 11,201, 31,128, 71, 9,120, 62,100, 79,128, 78,167, 35,203,151, 47,199,176, 97,238,231, 57,116,232, 80,116, 37, - 79,128,151,197, 47, 27, 4,214, 63,191, 30,202,189,222,236,249, 38, 35, 0, 68, 3, 24, 5,224, 24,128,193, 0,234, 1,212, 66, -254, 73,186,174,121, 92,177, 68, 64,113,113,113, 90,131,193,208,174, 43,192, 51,183, 61, 0,180,206,119, 47,149, 28, 66, 12,254, - 19,235,113, 8, 25,188,117,239,207,221, 47,214,250, 7,128, 79, 95, 90, 14,253,138, 55,193, 78,153, 4, 21,128,152,189, 39,240, -121,121, 13, 0,128,157,178, 8,206,239,251,130,233,247,123,201, 36, 21,128,144, 68,163,102,230,135, 88,244,228, 41,252,244,244, - 82, 52,237,113, 96, 64,223,192,229,161, 42, 80,225, 42, 7,155, 55,111,118,107,195,250,123,177,175,170, 26,177, 99, 99,113,186, -168, 28,208, 68, 34,109,209,191,163,247,117,169,157,249, 45,250,139,250, 15,169, 78, 2,120, 17,124,121, 31, 2,202, 46,202, 40, -194,180,156,105, 72,203, 7, 50,138,220,235, 69, 25, 69,173,202,129,186,240,132,168,107,104,180, 55,160,111, 84, 31,176,246,102, - 16, 5,193,237, 19, 39, 98,219,182,109,246,181,111,190,169,225, 8,193, 99,143, 63,134,222,125,122,163,185,177, 17,172,139, 69, -108, 68,119, 56, 21,206,144,238,183,182,182,182,205,232, 0,169, 1,129,237,200,159, 71,136, 74,128, 78,167, 35, 70,163, 17, 19, - 39, 78,108, 83, 62,122,244,104,188,241,198, 27,157,170, 4,116, 20,241,243,178,133,114,121, 47, 64, 8, 83, 5,127, 3,224,160, -135,236, 31, 4,240, 0,128, 50, 0, 99, 0, 20, 0,216, 4,192, 9,138,176, 20, 0,226, 69,138, 68,226,254,128, 72, 76, 76,108, - 37,253,164,164, 36, 45, 31, 27,192,123, 7, 18, 19, 19,173,124,119, 65,103, 53,188,114, 34, 88, 95,191,192,250, 15,138, 89, 27, -242, 65,166, 39,224,220,157,183,161, 15, 38, 33, 42,109, 29,216, 51,231,129,158,221,161,170,249, 16, 59,214,150, 2, 74,101, 40, -247, 30,182,214,124,232,133,127,195,132,113, 64,226,162, 35, 24, 21,243, 36,126,188,193, 0,252,239, 82,191,229,157,229, 1, 48, -153, 76,184,231,246, 27, 49,101,210, 8,232,111, 89,138,236,181,235,113,172,244, 52,158,190,111, 2,206, 22,236, 66,221,165,122, -185,222,135, 54, 93, 5, 30, 47, 64, 80,130, 22, 18,190,156,228,239, 71,166, 40, 84, 86, 86, 50,241,241,241,196, 19,255,215,170, - 16, 0,192,180,156,105, 80, 23,158, 64, 97, 97,121,235, 72,128,192, 1,129, 12, 56,142,131,139, 3, 8,199, 34, 50, 74,131,199, -159,120, 66,243,218,171,175,162,127,255,254,220,224, 1, 3, 20,246,166, 70,184, 8, 64, 56, 23, 56, 46,184, 71, 43, 55, 55,151, -153, 58,117, 42,169,169,169, 65,125,125,125, 27,197,209,107,116,128,232, 81, 1, 58,157,142,100, 47, 56, 10,104,134, 1,103,223, -110,127,128,102, 24,178, 23, 28, 5, 68, 42, 1, 58,157,142,204,152, 49, 67, 59,122,244,104,107, 77, 77, 77,187,253,241,241,241, -152, 49, 99,134, 22, 93, 60, 38, 32, 92,235, 63, 76, 47,128, 80, 97, 24, 8,119, 87,192,195, 0,154, 64, 33,155, 2, 32, 37, 17, -144,175,253, 62, 97, 48, 24,124,122, 1,120,178,143,139,139,211, 26,141, 70,171,135, 16, 97, 48, 24, 2, 6, 21, 6,178, 14, 67, - 24, 95,223, 33,195, 0,121,235, 62, 80, 48,160, 20,148,255, 57, 3, 17,105,235, 96,171,250, 9,170,189,235,224,204, 95, 4,230, -161,213,216,254,251,116,252,178,253, 36,244,171,222, 7, 84,157,147,217,121,169, 5, 40, 90,181, 13,163,126,153, 6, 92,104,194, -146,169, 75, 3,150,203,225, 1, 8,213,250, 47,216,182, 28,202,193, 55, 35, 6, 35, 80,249, 69, 14, 26, 24,130,127,253,116, 10, - 83,142,156, 22,117, 57,123,246,232,252,146, 61, 0,120,246,251, 60, 78, 44,249,251,121, 71,195, 34,134,112,114, 0,240,200, 40, -186, 76,252, 0,218, 89,254,124,192, 96, 97, 97,185,207,243, 99,163, 98, 81, 85, 87,133,137, 67,238,128,173,197, 14,216,236, 96, - 29, 78,188,108, 52,130, 81, 64,209,220,212, 8,142,115,129,117, 17, 68,170, 34,112,190,241, 60, 34, 92,193, 71, 27,127,254,249, -231,173,247, 54,119,238, 92,194,183, 55, 23, 46, 92,142, 9, 59,115,230,140,232,251,116,147,176, 91, 9, 24,153,208,254,255,143, -159,116, 32,235,221, 81, 16, 75,214,158,227,200,196,137, 19, 17, 31, 31,223,110,255,145, 35, 71, 80, 80, 80, 96,237, 44,242,247, - 88,227, 12,239, 9,144,163,223,223,151,245, 47,131, 23,128,199, 3, 30,133,160,133, 82,184,188, 10, 64,135,128,183,252, 1, 32, - 41, 41, 73,107,177, 88,172,188,235,223,143,114,160, 45, 43, 43, 11, 22, 11,192,200,101,205, 75, 33, 19,177, 10, 6,111,253,251, - 34,126, 94,209,145,114,189,135,202,107,224,252,254, 53,156,195, 87, 24,240,208,106,160,174, 30,229, 57, 47, 98,232,194, 53, 56, -187,233, 69, 32, 66, 5, 40, 58, 39,179,115,101, 19, 48, 50,238, 97,209,229,157,225, 1, 48,153, 76,141,179,167,220,113,166, 7, -215,235,250,102, 68,104,242,215, 44,194, 95,118, 28,196,146, 7,239,198,188, 55, 63, 64,250,127,255, 95,135,122,131, 2,221, 98, -193, 39,102,120,146, 0, 49,225, 42,167,225,184,250, 3,121, 1, 50,138,138,136, 47,242, 23, 90,255,193, 48, 40,110, 16, 62,253, -178, 8,119, 93,127, 23,162,187,197,128,227, 8, 20,132, 5,199, 48, 32,132,192, 69, 0,150, 35, 96, 89, 22,182,186, 38,236,220, -191, 19,106,151, 90,114, 80,170,119,160,211,127, 44,154,132,148, 65, 21, 96, 62, 19, 47,195,159, 18, 32,149,252,189,149,128, 85, -171, 86, 97,224,192,129,151, 21,251,242,114,152, 76, 38,116, 5,203, 95,110, 69,192,151,245, 31,166, 23, 0, 0,146, 1,220, 0, -224,143,184, 60,241, 19, 69, 87, 86, 0,226,226,226,180,222, 30, 1,190,223, 93,168, 28, 8,215,195,180,224, 37,191, 88, 50, 14, - 3,244,105,253,135, 74,252, 60,102,173,220,132,173, 0, 30, 92,145, 2, 98,121, 17,204, 35,217, 56, 84, 94, 3,166,119, 47,156, -248,181,222,109,253, 75,239, 2,144, 5, 71,142, 28,105, 29,242, 39,102, 93, 14, 15,128, 20,229, 96,243,230,205, 14, 0, 13, 11, -146,199,212, 63,183,250,127, 28, 47,189,108,180,247,235, 30, 87,115,244, 88,101,255,121,199, 62,136,233, 36,226, 23, 67,206,194, - 46, 26,209, 94,128,142, 74, 6,228,139,252,121,203, 31, 64,208,128,192,197,139, 23, 51,119,221,127,215,116,235,164,146, 2,195, - 45,233,168,183,215,131, 81, 0,238,193, 72, 28, 92, 46, 2,142,101,209, 45, 50, 22, 95,215,125,135,178,189, 39,144,103,206, 43, - 9,251,194,203,127, 7, 64,250, 48,192, 54, 74,192,192, 74, 28, 63, 19, 31, 18,249,123, 43, 1,235,214,173, 67,207,158, 61, 81, - 83, 83,131,229,203,151,163,171,185,253,229, 80, 4,252, 89,255, 33,122, 1,250,195, 29,245,175, 0,112, 43,128, 44, 0,229,148, -190,101, 86, 0, 58, 42, 15,128, 63,143, 64,118,118,182,214, 91, 81, 48, 24, 12,146, 19, 6, 9,137,160, 43,164,216, 21, 90,255, - 66,226, 55, 26,141,124,183,135,240,185,138,190, 96, 94, 9,120,120,197,123, 32,249, 64,223,121,102,148, 60,151,142,187, 77,127, - 3, 34, 34,208, 77,163,238,148,251, 21,142,241,247,181, 30, 98, 30, 0, 22,128,194, 83,183,138, 48,235,227,220,236, 41,119, 84, - 61,151, 83,152,240,242, 83, 15,116, 31, 52, 32,217, 1,224,176,193, 96,232, 1,247,248,226,144,234,131,127,229,246,236,209,241, - 17,255,161, 40,119, 76, 48, 11, 94, 10,161,203,225,234,151, 2,111,210,231, 61, 2,189,123,247,246,169,157,125,189,231,235,237, -241, 55, 93, 15,215,108,246,240,228,235, 39,143,233, 19,219, 7,118,167, 29,132, 16,168, 85,106,212,218,154,177,239,215, 61,216, -252,215, 92,104,111,214,106,243,144, 23,246, 53,190,177,107, 30,114,115,115, 81, 86, 38, 61, 7,192,101, 37, 0, 97,145,191, 80, -222,162, 69,139,200,170, 85,171,176,116,233, 82,116,229, 62,127,161, 34, 80, 82, 82, 18,210,185,129,142,145, 32,115, 6,220,227, -253,237, 0, 94, 0,176, 31,128,139,210,183,111,140, 27, 55, 14, 7, 15, 30, 68,142,105, 89,187, 60, 0,222,217, 0, 85, 94, 13, -101,192, 62,126,225,182,247,126, 41,147, 17, 4, 34,250, 16,189, 0, 97,161,163,134, 1,242,202,136,217,108, 70,113,113, 49, 87, - 81, 81, 33, 36, 50,173,197, 98,145,108,221,204, 90,185, 9, 16, 36,254,153,252,242,134,214,245, 78,138,134, 9,218,128,113, 36, -164,103,183, 22,192, 69,184,135,255, 60, 30,230, 53,158, 93,144, 60,166,101,106,241, 55,221, 31,123,245,125,152,205,102,117,113, -113,241, 64,180, 77,103, 29, 82,125,116,180, 39, 32, 88,126,255,160, 45,103, 7,116, 9,248, 35,127,135,126, 24, 80, 24,220, 48, -251,232,237, 45, 76, 55,101, 12,217, 27,191, 15,147,238,152,132,193,177,131, 1,142,224,188,189, 6, 95,127,251, 53,206, 30, 61, -139,251, 70,222,167,125,246,217,103, 59,189, 62,132, 74,128, 92,100,205,123, 2,174,150,128,191, 48,250,234,229, 66,142,103,161, -144,250,224, 76,203,196,123, 0, 58, 10, 89, 89, 89, 62,201,222,107, 38, 54, 33,172,190,242, 22, 7, 35,218, 80,209, 17,195, 0, - 77, 38, 19,204,102, 51, 91, 92, 92,172,242,116, 29,240,228,127, 95,128,251,246, 9,207,100, 74, 29,145, 74,153, 4, 40,239,148, -198,201,108, 54, 71,122,222,203, 87, 60, 69,174,204,204,204, 39,194, 20, 27, 57,245,143,239,148,154,205,230,123,139,139,139, 81, - 92, 92,108, 7,160,241, 44,114, 16, 63, 35,114,188,191,100,146,246,236,111, 83, 95, 82,137, 91,142, 46,129,202,202, 74,166, 40, -163,136, 12, 90, 52, 72,139, 33,190,143,169,202, 40,178,138,141, 7,216,248,214, 70,102,205,154, 53,201,155, 86,108, 66,252,176, - 27,172, 0,240,227,145, 31,180,169, 83,245, 88,187,126,109,201, 71,248, 40,164,235,204,205,205,101, 30,120,224,129,118,163, 2, -156,206,240, 70,136,201, 77,214,215, 90,180, 63, 69,215,244, 2,120,151,137, 86, 0,130, 89,226, 18, 44,245, 80, 95,116,210,193, -242,229, 58,223,167, 60,131,193, 64,138,139,139, 85,194,231, 37,244,176, 72, 84, 80, 74, 58,136,144,187, 98, 35, 20, 11,160, 17, - 32, 4,238,196,252, 81, 8,111,124, 47, 95, 31, 63, 23, 23, 23,243,227,202,234, 19, 19, 19,251,153, 76,166,200,174,240, 44, 59, -210,109, 47,167,236,202,202, 74,166,114, 73,165,108,207,224,249,231,159, 47,241, 62,239,235,191,239, 13,251, 58, 63,251,236, 51, - 74,174, 20, 84, 9, 16, 97, 68, 51,161,206, 35, 76, 65, 65, 65, 65, 65, 65,113,245, 66, 65, 31, 1, 5, 5, 5, 5, 5, 5, 85, - 0, 40, 40, 40, 40, 40, 40, 40,126, 3,248,127, 37, 93,196,116, 64, 61,103,188, 0, 0, 0, 0, 73, 69, 78, 68,174, 66, 96,130, + 0, 0, 4,115, 66, 73, 84, 8, 8, 8, 8,124, 8,100,136, 0, 0, 0, 9,112, 72, 89,115, 0, 0, 13,215, 0, 0, 13,215, 1, + 66, 40,155,120, 0, 0, 0, 25,116, 69, 88,116, 83,111,102,116,119, 97,114,101, 0,119,119,119, 46,105,110,107,115, 99, 97,112, +101, 46,111,114,103,155,238, 60, 26, 0, 0, 32, 0, 73, 68, 65, 84,120,156,236,157,119,120, 20, 85,247,199,191,103,218,206,182, +244, 78, 9,157,208, 91, 64,164, 35,210, 4, 81,169,130, 72,243,149, 87, 5, 20,105, 74, 81, 64,154,136,250,170,168, 40,160, 2, +210, 4, 11, 69, 68,154, 20, 81,106,232, 73, 40,161,132,150, 66, 72,219, 94,239,239,143,221,141, 1,147,236,110,192,246,115, 63, +207, 51,207,110,102,103,191,115,118,179, 51,231,220,115,207,189,151, 24, 99, 8, 16, 32, 64,128, 0, 1, 2,252,187,224,254,106, + 3, 2, 4, 8, 16, 32, 64,128, 0,127, 62,129, 0, 32, 64,128, 0, 1, 2, 4,248, 23, 18, 8, 0, 2, 4, 8, 16, 32, 64,128, +127, 33,129, 0, 32, 64,128, 0, 1, 2, 4,248, 23, 18, 8, 0, 2, 4, 8, 16,224, 79,134,136, 2,247,222, 0,127, 57, 62,253, + 8,137, 72, 8,147,233, 17, 34, 82,221,175, 19,255,157, 47, 0, 34,234, 70, 68,123,220, 91,183,191,218,158, 0,165, 67,110,254, +106, 59,254, 46, 72,178,156, 73, 68,172,180, 77,169, 84,102,254,213, 54,254,219, 17, 69,113, 65,215,174, 93,141,178, 44,191, 87, +158,247, 19, 81,227,136,136,136,205,193,193,193,153,106,181, 58, 63, 50, 50,114, 47, 17, 61, 94, 94,123,254,238,122, 1,254, 56, +200,151, 97,128, 81, 42,106,211, 52, 38, 44,225, 68, 86, 65,102,166,193,254,125,185, 79, 70,212, 90,146,184,110,156, 72,149,136, + 40,159,217,113,203,102, 99,103, 28, 14, 71, 18, 99,236,186,175, 58,178, 58,180,151,221, 98,244, 57, 24,225, 85, 33,102, 75, 97, +214, 6, 63,236,252,245,243,159,217,131, 78, 6,252,167, 29, 29, 96,140,181,242,245,189,127, 6, 68, 36, 72,146, 52, 69, 20,197, +103,236,118,123,168,197, 98,121,132, 49,182,255,175,182,203, 3, 17,213,141,142,142,126, 14, 0,178,178,178, 62, 97,140,165,252, + 65,231, 81,191,250,116, 66, 87,187, 3,214,183, 87,159,221,194,238,113, 76, 43, 17,201, 0, 98, 1, 92,103,140,217,124, 56, 62, + 52, 56, 56,120,110, 65, 65,193, 43,140,177,194,123, 57,247, 93,186, 97, 49, 49, 49, 13,156, 78,103, 69,158,231,175,101,100,100, +156, 97,140,229,250,248, 94,246,237,254,100, 40, 68, 30,146,192, 67, 18,133, 59,158,215,175, 18, 13,198,152, 79, 1,147, 44,203, +153, 22,139, 37,218, 31,219,149, 74,101,150,209,104,140, 41,197,182, 76, 0,126,233,113, 28,151,229,112, 56,254, 20,189, 18,244, + 9, 64, 71, 89,150,159,181,219,237,157, 4, 65,216,101, 54,155,151, 0,216, 93,222,223, 26, 17,133, 12, 30, 60, 56,111,197,138, + 21, 24, 52,104,144, 99,237,218,181, 97,254,252,118,180, 90,237,139, 60,207,207,155, 51,103,142,242,161,135, 30, 34,141, 70,131, + 3, 7, 14, 96,226,196,137,250,130,130,130, 77,249,249,249, 79,249, 99,207,223, 93, 47,192, 31,139,224,237, 0, 34, 10,171, 95, + 41,186,214,198,109, 63,112,221,186,116,138, 80, 17, 85, 54, 50,118,213,159,147, 16,145, 36,136,220,252,168, 10,218,218, 51,223, +152,172,123,236,209,254,194,165,244,115, 13,107, 86,171,183,114,213,202,117,150, 73,227,167, 36, 16, 81, 24,128, 51,140, 49,167, + 55, 61,139, 69,167, 58,127,249, 22, 85,140,144,189,158,251,108,186, 1, 77,235,199,120, 63,240, 78,226,212, 10, 96,127, 26, 0, +160,130,159,239,253, 67, 33, 34, 65,169, 84, 30,108,214,172, 89,163, 89,179,102, 9,223,126,251, 45,150, 46, 93,186, 28, 64,245, +191,216,174, 10, 97, 97, 97, 35, 20, 10,197,176,206,157, 59,107, 71,143, 30, 29, 1, 0, 31,126,248,225,147,113,113,113, 58,139, +197,178, 44, 55, 55,247,115,198,216, 13,111, 90,130, 32,100, 58, 28,142, 50,111,236, 9, 9, 9,223,188,241,159,250,235,166, 12, + 77, 24, 57,107,121,234, 10, 0, 81, 0,178,238, 62, 78, 20,197, 36,187,221, 30, 81,124,159, 36, 73, 57, 22,139,165,217, 93,246, +171,102, 61, 91,255,161,113,131,106,245, 84,119,252,246, 19, 34, 58, 85,214,111,145,136, 42,135,134,134,254,212,171, 87,175,248, +239,191,255, 62,145,136,250, 50,198,210,189,125,182, 50,244,228,200,200,200, 4, 81, 20,235,116,234,212, 73, 26, 61,122,180,162, + 75,151, 46,216,190,125,123,194, 7, 31,124, 80, 37, 38, 38,198,170,215,235,147, 13, 6,195,121,198,152,165, 52, 29, 81,161,200, +234,221,166, 94,169,223,157, 44,203,191,251,142, 74,195, 98,177, 68,239,223,191, 31, 68, 4,142,227, 32, 73, 18, 20, 10, 5, 68, + 81,132, 36, 73, 16, 69,241,142,231,130, 32, 64,150,229,178,254,111,209,239,188,243, 14,148, 74, 37, 76, 38, 19, 76, 38, 19,204, +102, 51,204,102, 51, 44, 22, 11, 44, 22, 11,172, 86,107,209,102, 54,155,241,253,247,223,151,169,183, 96,193,130,223,233, 89,173, + 86, 88, 44,150, 59,158, 91,173, 86,152, 76, 38,108,221,186,213,107,192, 64, 68,213,101, 89, 30, 33, 73,210, 48,181, 90,109,237, +220,185,243,225,168,168,168, 77,217,217,217,218, 29, 59,118,124,102, 48, 24, 36,165, 82,185,220,108, 54,127,198, 24,187,232,235, +247,233, 38,129,231,121, 92,189,122, 21, 60,207,243, 0,234, 2, 56,232,203, 27,137,168,169, 86,171,125, 51,245,224, 14,101,172, +100, 2,156, 25,128, 5,168,212, 44, 26,143, 30,220,161,121,176,123,255, 94,146, 36,253,215,106,181,126,234,143,222,233,211,167, +149,149, 42, 85, 42,218, 95,169, 82, 37,244,232,209, 67,211,186,117,235,191, 84, 47,192, 31,143,215, 0, 32, 70, 35, 61,188,124, +249, 42,161, 96,195, 34,188,211,189,137,212,115,197,129,246, 68,180,134, 49,102,247,245, 36,188,200,125,218,228,129,234,149,118, +108,221, 95,165,192,116,227,216,249,204,237,223,175,219,240,117,187, 49,195,199,237,125,249,197,177,226, 11,255,125, 49, 47, 50, + 50, 18, 58,157, 46, 30,192,101, 95, 52, 43, 70,200, 24,240,174,225,142,125,146, 4,104,100, 64,173,228,161, 22, 1,141,146,135, +196, 59,124, 53,179, 56,199,183,236, 57, 25,175, 80,133, 0,192,249,242, 8,252, 81, 72,146, 52,165,105,211,166, 13, 87,175, 94, + 45,124,254,249,231, 88,178,100,137,222,108, 54, 15,189, 87, 93, 34,234,160,209,104,254,203,243,124, 16, 17, 41,109, 54,219, 85, +131,193, 48,131, 49,118,197,135,247, 86, 36,162,244, 22, 45, 90,176, 21, 43, 86,240,145,145,145, 69,175,245,234,213, 43,242,214, +173, 91,145, 67,134, 12,153,190,109,219,182, 25, 68, 20,239, 45,219,227,112, 56,162,147,146,146,160,213,106, 97, 52, 26,209,184, +113, 99,164,166,166, 66,173, 86,195, 98,177,224,228,201,147, 87, 51,142,175,216,243,124, 55,105,228,194,175, 47,172,159,185, 52, +249, 2, 0, 67, 73, 90,118,187, 61, 34, 63, 63, 31,193,193,193, 0, 0,189, 94, 15,173, 86,123, 71, 64,224,113,254,147,135, 36, + 12,122, 99, 89,202, 94, 0, 34, 0, 5, 0, 83, 41,159,183, 97,100,100,228, 15,115,231,206,173,208,184,113, 99, 60,242,200, 35, +205,150, 44, 89,114,168, 78,157, 58,118,189, 94,111,118, 56, 28, 59, 50, 50, 50,222,103,140,157,245,246,221, 1, 64,173, 90,181, +218, 37, 36, 36, 84,125,238,185,231,164,199, 30,123, 76,120,241,197, 23,123,140, 30, 61,186, 69,118,118,118, 88, 84, 84, 84,110, +211,166, 77, 15, 31, 60,120,112,203, 55,223,124,243,192,226,197,139,155,196,199,199, 95, 74, 79, 79, 47, 49,227, 99, 53,155,139, + 90,183,181,234, 54,220,172, 84, 42,155,114, 4,112, 28,129,136, 64,196,225,129, 7, 91,223,224, 56,192,100, 52, 31, 59,113, 60, +233,209,178,108, 19, 69, 17, 75,151, 46,133, 40,138, 80,171,213, 80, 42,149, 80,169, 84, 80, 42,149, 80,171,213,144,101, 25, 26, +141, 6, 42,149, 10, 29, 58,116,240,250, 89, 53, 26, 13, 58,117,234, 4, 81, 20,209,178,101,203,162, 32,162,180,205, 27,106,181, + 26, 83,167, 78,133, 32, 8, 16, 4, 1,193,106, 21, 70, 53,111, 1,133,211,137,165,231,206,193,236,116, 22,189,230,139,158, 36, + 73, 73,162, 40,214, 76, 76, 76, 60, 60,114,228,200,207,159,126,234,169,235,128,131, 86,172,248,178,210,144, 33, 79, 31, 5,248, +159,190, 92,181,170,226,226,197,139, 31, 60,116,232,208,104, 73,146, 46, 88,173,214,102,222,116,221, 93,158, 51, 7, 13, 26, 52, +101,244,232,209,136,140,140,196, 75, 47,189, 4,198,216, 47, 68, 52, 23,192,116,111,141,159,224,224,224, 57,243,231,207,151, 99, + 69, 35,216,138, 1,128,206, 29,203,105,162, 97,127, 98, 41,230,207,159,175,233,219,183,239, 60, 0, 62, 57, 88,143, 94,113,103, + 13, 0,118,187, 29, 38,147,233,158,244,142, 28, 57, 2,139,197, 21,167, 10,130,128, 26, 53,106,248,173,247, 79,132,136, 4,142, +227, 50,156, 78,103,209, 61,134,231,249, 28,135,195, 17,235,143,207, 44,166,199, 1, 24, 8, 64, 93,108,183, 1,192, 26, 95, 26, +203,222, 40, 51, 0,208, 18,213,123,186,119,215,160, 90,200,133,238,250, 5,196,134,133,226,249,135, 26, 42, 22,237, 63,245, 32, +128,159,125, 57, 1, 17,245,138,140, 83, 55,216,182,101, 79,212,233,203,223,255,184,239,212,167,123, 32,209,173,155,217,217,198, + 77,123,231,157, 79,168,222, 67,167, 80, 64, 89, 88, 88,104, 34,162, 42, 68,164,100,140,149,120,227, 45, 11,165, 12,168, 37,151, +211, 87,203,128, 82,226,161, 86, 2, 74,240,254, 74, 1, 64,241,150,156,215, 22,235,159,137, 32, 8, 35,102,207,158, 45,174, 91, +183, 14,111,190,249,166,222,108, 54,119,103,140,237, 39,162, 54, 42,149,106,185,209,104, 28,234, 79,119, 0, 17, 85, 86,171,213, + 31,134,134,134,182, 31, 63,126,124, 65,116,116,180, 77,165, 82, 57, 15, 29, 58, 84, 99,241,226,197,125, 53, 26,205,231, 6,131, + 97,108, 89, 63, 54,198,216,117, 34,170,125,236,216,177,113,141, 26, 53,234,253,228,147, 79,170, 70,141, 26,165, 5,128,143, 62, +250, 72,183,118,237, 90,163,195,225,248,150, 49,246,174,175, 93, 61, 90,173, 22, 27, 54,108,128, 66,161, 0,224,186,209,239,223, +191, 31,130, 32, 92,205, 58,185,114,193,243,221,164,199, 63,249, 33,247,167,183,214,101,247, 5,176,138, 49,166, 47, 77, 43, 56, + 56, 24, 95,125,245, 21, 66, 67, 67, 17, 26, 26,122,247,231,191,195,249,191,241, 89,202,113, 0,151, 74,251, 13,138,162,216,185, + 66,133, 10, 95,190,245,214, 91,209, 53,107,214, 68,112,112, 48, 30,122,232, 33,122,248,225,135,163, 1,192, 96, 48, 96,211,166, + 77,213,231,204,153,243,184, 36, 73,143, 88,173,214,227,222, 62,107, 65, 65, 65,252,182,109,219,236,209,209,209, 5,173, 90,181, +250, 95,124,124,124,232, 55,223,124,163,175, 91,183,238,181,148,148, 20,113,202,148, 41,109, 58,116,232,208, 96,251,246,237, 99, +213,106,181,248,202, 43,175, 84, 5,224,245,127,172, 80, 40,154,207,253, 96,113,180, 36,242,144,120, 1, 10,145,131, 40, 10, 80, +240, 60, 36,145,199,176,167,158,244,122,113,136,162, 8, 34, 66,159, 62,125,138,246,237,218,181, 11,159,125,246, 25, 34, 35, 35, + 49, 97,194, 4, 40,149, 74, 56, 28,190, 5,218,102,179, 25,125,251,246, 5,207,243, 94,157,191, 47, 14,219,108, 54, 67, 16, 4, +212,175, 17,139,215, 30,173,135,214, 22, 6,125, 54, 15, 46,211,140, 17,118, 59,146,234,213,195,251,121,121, 72, 55, 24, 32, 8, + 94,219, 59,176,217,108, 77,227,227,227,143, 95,187,118, 45, 92,202, 62, 93, 17, 7, 63,137, 6,115, 80, 29,251,213, 32, 28,248, + 36, 10,196, 51, 49,243,146,120,233,210,165,240,144,144,144,180, 91,183,110, 53,245,233,131, 3, 51,151, 47, 95, 62,109,200,144, + 33, 0, 0,167,211,137,230,205,155, 99,213,170, 85, 92,215,174, 93,167, 13, 29, 58, 20, 0, 94, 43, 75,192,110,183,183,232,212, +169, 19,129, 93, 5,116, 89,160,119, 92,189, 16,108, 60,193,160, 47, 68, 88, 88, 77, 72,146,164, 36,162, 10,190,100,218,138,244, + 60, 56,237,176,231, 94,131,190, 32, 15,198,194, 66,196,169, 28, 8, 86,203,229,210,179, 88, 44,104,211,166, 13, 28, 14, 7,118, +236,216,129,188,188, 60,132,133,133,249,101, 95, 89,244,239,223,159, 7,128,117,235,214,149,171,133,247, 7, 18,195,243,188,178, +248,245, 32,203,178,210,221,237,228,115, 55,119, 49,148, 0, 24, 99, 44,201,179,131,136,106,187,247,151,216,232,241,135, 82,175, + 8, 34, 82, 86, 10, 81, 55,159,247,193, 39,156,238,157, 17,128,168, 2,175, 80,225,191, 15,181,224,214, 38, 93,174, 65, 68,103, + 24, 99,121,222, 78, 32, 42,248, 49,211,102,190,232,184, 85,120,225,198,190, 83,139, 47, 51,112, 65,204, 1, 61, 0,132,216,205, +102,247, 97,158,155,109,182,251,131,149, 25, 0,240,188,188, 88,165, 82,105, 75,123, 93,161, 14, 55,188,185,230,210,179, 26,153, +135, 88, 46,255,255,247,197,106,181, 86,168, 82,165, 10,142, 29, 59, 86,180,143,136,218,104,181,218,237, 19, 38, 76, 80,206,153, + 51,103, 11,128, 96, 95,180,136,168,141, 44,203, 91,158,121,230,153,130, 57,115,230, 92,212,104, 52, 78, 0, 40, 44, 44,228,154, + 53,107,102,234,216,177,163,121,220,184,113, 79, 95,191,126, 61, 13,192, 7, 37,105, 4, 7, 7, 39, 43, 20,138,116, 0, 51,179, +178,178, 94, 32,162,177, 31,125,244, 81,239,175,190,250,234, 21, 0,200,201,201,153,111,181, 90,191,101,140, 89,137,232,193,224, +224,224,143, 28, 14, 71,148, 94,175,111, 82,150,109, 70,163, 17, 10,133, 2,146, 36, 1,112,221, 80,238,118,254,215, 89,139, 49, + 25, 25, 63,197,148,229,252, 61,132,133,133,253, 46, 0, 40,197,249, 95,100,140,221, 46,229,251,170, 21, 25, 25,249,213, 7, 31, +124, 16, 90,177, 98, 69,132,132,132, 32, 36, 36, 4, 28,231,170,103,181,217,108,184,121,243, 38,194,195,195, 49,116,232,208,152, +221,187,119, 31,210,104, 52, 31,235,245,250,177,222,236,179, 88, 44,234,129, 3, 7,246,175, 92,185,114,200,238,221,187, 51,137, + 72, 0,192, 61,240,192, 3,230,111,190,249,198,216,187,119,239,168, 71, 31,125,244,153,126,253,250,109,130,151,235,163,152,230, +145, 41, 47,142,116,101, 0,136, 64,156, 43, 3,224,202, 8, 0, 38,147,249,152, 55, 13, 73,146,160, 86,171,225,116,254, 22,255, +189,247,222,123, 48, 26,141,184,112,225, 2, 14, 29, 58,132,246,237,219,195,102,243, 90, 50,225,177, 9,153,153,153,119,116, 33, +220, 75, 0, 96,177, 88, 16, 20,164,194,142, 55,131,113,243,114, 30,222,216,229,196,119, 73,215, 33, 8, 2,122,213,168,141, 1, +102,134,183,236, 2,158, 85, 42, 97,245,177,219,254,171,175,190,250,100,255,190,125, 49,103,143,172, 27,152,159,126,162,102,176, +104,231, 19, 1,176, 84, 32,223, 38, 56,146, 46,213,184,240, 64,243,230,107,234,214,175,159, 57,103,206,156, 50, 91,179, 68, 20, + 4,160,238,160, 65,131,166, 12, 25, 50, 4,169,169,169, 24, 54,108,152,238,232,209,163, 55, 19, 19, 19, 99,151, 45, 91, 22, 52, +100,200, 16,108,219,182,109, 10, 17,109, 1,112,150, 49,150, 95,146,150,221,110, 87,170,213,234, 18,111,251, 6,131, 17,183,245, +183, 33,138, 34,131,171, 91,193, 23,135,237,210,115,227, 72, 63, 2, 91,210, 26, 8,121, 55,160,177,217, 0,210,160, 85,245, 96, + 90,159,149, 83, 46, 61,167,211, 9,163,209, 8,163,209,136,252,252,124,220,190,237,159,125,119, 67, 68, 45,131,131,131, 39, 18, +209, 67, 38,147, 41,216,225,112, 32, 56, 56,184,128,136,126, 42, 40, 40, 88,192, 24,243,169, 43,229,126, 35, 8,194,215, 28,199, +213, 0, 0, 81, 20,101,181, 90,237, 28, 56,112, 32,100, 89,134, 66,161, 64, 80, 80,144,179,176,176,112,167, 74,165, 58, 99, 52, + 26,251,122,211, 35,162, 14, 0, 60,254, 77, 0,160, 7,144, 84,236,144, 10, 0,186, 16, 81, 30, 99,108,207, 61,217, 94,218, 11, +145, 10,161,253,123, 11,230, 75,182, 77, 31,226, 76,102,161,118,200,166,253, 83,230, 61,209,254,131,158,173, 42,102, 44, 26, 53, + 80, 28,252,206,231, 93, 0,124,229,237, 4,204,201, 26,246,120,164, 87,206,209,243, 95,157, 38, 32, 8, 96, 32, 7,172,140, 57, +217,200,145, 71,239,184,107, 48,198,140,190,140, 52,112, 88, 13,218,235,183,237,136, 10,230,224, 10, 95,139, 5,177,140, 65, 33, +114,106,141,204, 67,173,228, 32,149, 47, 3,240,183, 69,150,229,203, 87,174, 92,169, 89,191,126,125,204,153, 51, 71, 51,109,218, +180,173,130, 32,240,155, 54,109, 82,230,228,228, 64,150,101, 95,139,197, 90,132,133,133,173, 89,189,122,245,249,174, 93,187,234, + 60,187, 47, 93,186,164,184,116,233,146,188,118,237,218,208, 11, 23, 46,168,180, 90, 45, 47, 8,194, 36,148, 18, 0, 40, 20,138, +240, 55,223,124,179,238,146, 37, 75, 30,136,136,136,184, 45,203,242, 92,179,217,188,230,198,141, 27,107,221,231, 81,136,162,248, +148, 86,171,157,146,144,144, 16,218,173, 91,183,240,229,203,151, 95,243,102, 95,227,198,141,239,248,123,246,236,217,121,137, 21, +243,138,156,255, 53,103,243, 49,241,241,149,125, 42,230, 50, 24, 12, 8, 13, 13, 45, 10, 2,220,118,249,229,252,221, 92,178,219, +237,151, 15, 28, 56,160, 26, 58,116,168, 34, 36, 36, 4,174,110, 92, 87,218, 52, 61, 61,189,104,171, 86,173, 26, 6, 13, 26, 36, + 62,249,228,147,253, 0,120, 13, 0, 0,224,220,185,115, 15, 46, 95,190,220,100,179,217, 36,183,141,214,236,236,108,197,213,171, + 87,149,125,250,244,177,207,152, 49,227, 1, 0,155,124,209, 2,128,243, 41,167,138,210,251,178, 82,153,105, 49,155,239,238,255, +142,115,143, 12, 40,181,112, 79, 20, 69, 40,149, 74, 48,198,138,182,225,195,135, 99,231,206,157,168, 94,189, 58, 18, 19, 19, 97, +177, 88, 96,183,219,225, 75, 93,156,205,102, 43,114,238, 59,127,252, 30, 2,156,120,108,192,211,229, 14, 0,172, 86, 43,130,131, + 84,224, 35,205, 24, 50, 85,143,236, 92, 75, 81,202,127,251,205,107, 56, 21, 28,130,137, 17, 53,161, 53, 93, 67,129,181,212,210, +137,223,209,182,109,171,236,248,234, 5,251,131,127, 57,154,224,105,105, 3, 64,200,120,226,123,181,106,184,255,251,220, 10,217, +222, 52,100, 89,126,239,201, 39,159, 28, 45,203, 50, 63,122,244,104, 0,192,176, 97,195, 10, 15, 31, 62, 92,147, 49,150, 77, 68, + 81,195,134, 13, 75, 59,116,232,144,118,204,152, 49,156,209,104, 60,224,254,220,111,219,108,182,137,119,235,169,213,234, 51,199, +142, 29,107,222,163,142, 22,208, 68,131,141,119,221,247,242,249, 48, 76,121,255, 75,124,191,247, 40, 66, 66, 66,148, 97, 97, 97, + 27,100, 89,118, 50,198,102, 89,173,214,183, 75,203,222, 21,233,245,232, 1,155,205, 6, 83, 94, 22,180, 7, 22,194,212,236, 89, + 24,110,223, 70,165, 43,107, 16,169, 73, 80,148, 71, 79, 16, 4,108,219,182,173, 40, 0,152, 53,107, 22,118,237,218,229,151,125, + 30,136,136,215,104, 52,159,196,196,196, 60, 57,113,226, 68, 85,255,254,253, 57,158,231,241,238,187,239, 34, 61, 61, 61,164,101, +203,150,143, 47, 88,176,160,139, 86,171, 93,171,215,235,159, 99,140,249,155, 21,224, 0, 48,247,230, 55, 14,135,163,207,179,207, + 62,139,228,228,100,216,108, 54, 68, 69, 69, 65,146,164,162,173, 95,191,126, 90,157, 78, 87,251,203, 47,191,172,237,163,100, 45, + 0,223, 3, 8, 1,144,239,222, 64, 68,228, 46, 62,221,233,126,173, 39,128, 61,229,177,217, 67,137, 1, 0, 17, 85,232, 88, 55, + 62,174, 91,243, 6,200, 91,244, 37,166,236, 62, 63,164, 79,195,170,161,243,126, 60, 56,178,103,135, 86,111, 52, 74,168,192,186, +183, 76,212,198,106,181,245, 50,116,186,228,210,196,137, 72, 25, 17,167,188,204,152, 35,244,118, 97,186,147, 17, 69, 48, 64, 3, +222, 25, 18, 87, 61, 56,232,217,215,235,110,224,121, 78,224,120,136,238,138, 91,234, 49, 52, 62,157,136, 70,122,251, 81, 84, 8, +227, 49,242,227, 92, 40, 68,114,109, 18, 65, 22, 1,133,224,186, 40,212, 74, 14, 26,217,213,153,235, 15,110, 59,226,170,199,168, + 32,107,100, 0,136, 33, 34,190, 28, 63,170,251, 14, 17,117, 84,169, 84,149, 67, 66, 66, 80, 88, 88,136,102,205,154, 97,249,242, +229,154, 26, 53,106, 32, 44, 44, 12,211,166, 77, 51, 88,173,214,101, 62,232, 52,168, 92,185,242, 7, 75,151, 46, 61,216,185,115, +231, 92,184, 35,168,171, 87,175,202, 41, 41, 41, 65,243,230,205,171,125,230,204,153, 84,189, 94,191, 89,163,209,180,225,121, 62, +164, 44,189,196,196, 68, 36, 38, 38,134,101,100,100,132,173, 90,181,234,195, 77,155, 54, 77, 6, 80, 27, 0,148, 74,229,169,198, +141, 27, 87,104,219,182,173, 58, 50, 50,210,167,155, 58,128,162, 62,127,179,217,140, 57,115,230,228, 37, 86,204,123,253, 78,231, + 31, 31, 19, 18, 82,166, 89, 0, 92, 5,127, 26,141,230,142, 62,127,165, 82,121,123,202,224,234,254, 58,127, 48,198,236, 68,212, +102,217,178,101,175,124,245,213, 87, 61, 56,142, 11,209,104, 52,234,110,221,186,105,218,183,111,175, 53,155,205, 72, 79, 79, 71, +120,120, 56, 90,181,106,133,215, 95,127,221,145,146,146, 50,220,167, 15, 12, 32, 39, 39, 39,172,110,221,186, 69, 45,163,188,188, + 60,225,202,149, 43,210,245,235,215, 69,147,201,196,231,231,231,151,154,245,242,134,197,108,142, 62,115, 57,243,142, 81, 1, 10, + 81,128, 36,240,208,168, 20,165, 22,198,137,162, 8,149, 74, 5,167,211,137,107,215,174, 33, 42, 42, 10,143, 60,242, 8,186,119, +239, 14,167,211, 9,187,221, 14,171,213,234, 87, 6,192,227,220,255, 59,234, 69,240, 28,119,207, 25, 0,158,151,128,160,142,112, + 98, 15, 4,193, 81, 20, 0, 8,130, 0, 78,148,112,169,102, 99, 80,106, 38, 4,231,159,119, 9, 19, 17,215,181,107,215,231, 86, +175, 94,205,223,188,121, 19,161,161,161,112, 58,157, 56,122,244,104, 6, 99, 44, 27, 0, 24, 99,217, 60,207,223,116, 56, 28,181, + 19, 18, 18, 48,106,212, 40,212,169, 83, 7,133,133,133, 99,136,232,149,187,239,129, 5, 5, 5, 11,199,142, 29,187,168,227,222, + 45,106,219,227,139, 97,212,235,112, 59, 55, 15,143,191, 52, 31,109, 59, 84,197,141, 27, 27,225,190, 38, 84,105,105,105,120,242, +201, 39, 95, 79, 75, 75,107, 15,160, 71, 73, 54,122,244,218,183,111,175, 54, 26,141,112, 24, 12,208, 2, 80, 13, 90, 12, 21, 92, + 93, 11, 31,125,244, 17, 62,170,241,144,223,122,213,170, 85, 67,126,126, 62, 50, 50, 50, 48,108,216, 48,180,111,223, 30, 55,110, +220,240,203, 62, 15, 42,149,106,102,163, 70,141, 6,110,221,186, 85,125,234,212, 41, 24,141, 70, 28, 56,112, 0,111,191,253, 54, +250,246,237,139,196,196, 68,238,252,249,243,154,238,221,187, 15, 60,126,252,120, 22,128,105, 62,252,139, 56,184,178,205, 10,252, + 22, 0,216,102,206,156,233,156, 49, 99, 6, 1,224,221,251,172,190,116, 73,135,135,135,131,231,121,132,135,135,131, 49,134, 95, +127,253, 21,233,233,233,168, 94,189, 58, 58,117,234,132,154, 53,107,250, 96,210,111, 48,198,110, 18,145,231, 81, 67, 68,109, 0, + 84, 32,162, 12, 0,199, 61,175,223, 43, 37,142,197, 15, 85,160,105, 90,250,117,103,139, 78,143, 88, 18, 87, 30,175,174,141,140, + 77,120,123,233, 10,106, 26,165, 9,111, 60,241,157, 86, 15,141,159,111,219,127,250,188,211,198,177, 50,211,184, 0,204,121, 89, +230, 6, 57, 5, 87, 45, 60,137, 17, 96, 44,132,192, 98, 57,134,170,149,227,149, 66,149,132, 32,123,124, 77, 53,171, 84, 77, 35, + 84,168,170, 9,169, 80, 85, 45,109, 91,125,109, 16, 0,159,170,246, 57, 30,224,221,155,192, 1, 2, 71, 16,120,215,151, 18, 44, + 3, 65, 74, 30, 26,165,239, 25, 0, 34,170,165, 18,232,231,121,205,194,251,141,234, 81, 9,207,117,141, 64,207,103,234,118,149, +148,194, 97, 34,106,232,179,208, 31, 0, 17,181, 87,171,213, 63,108,216,176, 65, 97,181, 90,145,145,145,129,180,180, 52, 68, 69, + 69,225,242,229,203, 24, 54,108,152,225,196,137, 19,105,102,179,121,174, 23,157, 26, 9, 9, 9,147,151, 44, 89,178,187,115,231, +206,135, 1, 92, 4,144, 6,224, 98, 94, 94,222,181,139, 23, 47,230, 92,188,120, 49,187,176,176,176,135,195,225, 88, 88, 80, 80, + 48, 64,167,211,117,245,197,198,216,216, 88, 76,152, 48, 65,173, 80, 40,138, 28, 21,207,243,193, 93,187,118, 85,123,138,240,124, + 69,173, 86, 99,223,190,125, 56,118,236,216,213,226,206,255,170, 35,113, 76,229,202,149, 99,130,131,131,139,234, 3,202,194, 98, +177, 52, 99,140,197,123, 54, 0,117,166, 12,174,254,186,191,206,223, 3, 99,204,116,235,214,173, 25, 87,175, 94,109,126,229,202, +149,154,201,201,201, 53,223,121,231,157, 65,195,135, 15, 79, 63,124,248, 48, 34, 34, 34,208,182,109, 91, 76,159, 62,221,241,205, + 55,223,244,100,140,109,247,245, 51, 71, 68, 68,228,166,164,164,136, 0,160,211,233,184,171, 87,175,138,215,175, 95, 23,111,220, +184, 33, 22, 22, 22,114, 33, 33, 33, 94,187,220, 74, 67, 33,203, 89,245,171,198,160, 86,197, 8,196, 71,135, 34, 54, 60, 8, 97, + 65, 42,104, 84, 10, 40,149,202, 82, 71, 6, 72,146, 4,165, 82,137,169, 83,167,226,217,103,159,197,192,129, 3,145,158,158, 14, +187,221,142,220,220, 92,188,246,218,107,152, 61,123,118, 81,193,151, 55,138,103, 0,114,114,110, 35, 55, 47,255,158, 2, 0,171, +213, 10,226, 69, 28, 8,173, 0,230, 30,137, 80,188,232,143, 36, 5, 46, 85,174, 3, 78,144,124,170, 1,184, 95, 48,198,156,187, +118,237, 90, 56,100,200, 16, 76,158, 60, 25,201,201,201,224, 56, 14,137,137,137,113, 68, 20, 5, 0, 68, 20,149,152,152, 24,203, +243, 60, 82, 83, 83,241,254,251,239, 99,212,168, 81,142, 61,123,246,124, 82, 82, 3,200,110,183,127,121,235,214,173,189,237, 31, +123,202,112, 44, 95,139,107,138,154,120,109,217, 46,116,120,184, 43,190,120,127, 54, 66,114, 79, 1,105, 63, 1,105, 63,161, 6, +221,192,206,175,151,169, 35, 35, 35, 59, 8,130,240,116, 73, 54,122,244, 58,118,236,104, 72, 78, 78,134,209,104, 4, 0,220, 92, +212, 31,108,195,157, 73,171, 26, 53,106, 96,219,182,109,126,233,229,231,231,227,189,247,222, 67,167, 78,157,176,172, 28,246,121, + 32,162,255,142, 31, 63, 94,173,213,106,161, 84, 42,177,124,249,114, 60,255,252,243,144,101,151,155, 80,171,213,208,106,181, 24, + 63,126,188, 26,192, 72,111,255, 27, 34,234, 61,102,204,152, 24, 0, 65,112,181,164,195, 0,132, 29, 62,124, 56, 70,146,164,184, +166, 77,155, 70, 39, 38, 38, 70,175, 88,177,162,157, 36, 73, 61,189,233,185, 53, 65, 68,144, 36, 9,167, 79,159,198,135, 31,126, +136, 31,126,248, 1,141, 27, 55,198, 47,191,252, 82,212,149,233, 39, 30, 15,223,224,248,241,227,189,117, 58, 93, 68,108,108,172, + 1, 64,163,242,136,149, 68,137, 87, 68,158, 5, 63,228, 89, 28, 60, 12, 6, 69,180, 70,158,247,217,154,117, 82,193,186, 57,152, +217,185,129,226,161, 47,246, 63,122,236,202,205,201, 0,114, 0,148,217, 74,103,140, 49,165, 90, 76,217,188,249, 91, 85,221,196, +200, 10,185,250,116,145, 57,201,225,116,146,137,192, 28, 28,136, 7, 72,102, 96, 18, 8,202, 75,103, 10, 20,130,196, 93,182, 89, + 29, 70, 95,140,151, 69, 42,218, 60,153, 0, 89,242,100, 0, 92, 69,128,190,124,237,238,254,214, 9,237, 98,228,153, 75, 90, 71, + 73,181,130, 68,156,254,104, 60,142, 84,141, 64,163,142, 81,168, 82, 63,168,233,214, 47,206, 39, 17,209,155, 0,102, 49,198,172, +190,216,119,191, 32,162,118,106,181,250,199, 13, 27, 54,200, 65, 65, 65, 56,113,226, 4, 94,126,249,101, 35,207,243,153, 70,163, +177,178, 82,169,204,116, 56, 28, 43, 77, 38,211,244,178,198,175, 19, 81, 92,195,134, 13, 7,189,245,214, 91, 59,187,116,233,226, +105,249,123,126,100,164,213,106,149,162, 40,230,139,162,168,130, 43, 8,243,173, 89,247, 7,224, 46,238,186,122,235,244,234, 5, +197,157,191,167,229,175, 80, 40,124, 10, 0,138, 83, 66,218,223, 14, 32, 14,128,182, 88, 52,109,102,140,253,226,171, 38, 99,204, + 0,224,123, 34, 10, 51, 24, 12,203,218,182,109, 75, 83,166, 76,113,124,253,245,215, 61, 25, 99, 63,250, 99, 95,237,218,181, 15, +204,157, 59,183,125,211,166, 77,173, 87,174, 92, 17,175, 92,185,194, 93,187,118, 77, 50, 26,141,220,190,125,251, 16, 22, 22,118, +168,172,247, 75,178,156,105, 43, 97,220,190, 66,150,179,204, 38,147, 79,221, 37,119,227,233, 2,200,204,116,205, 31,100, 52, 26, +145,158,158,142,136,136, 8,236,223,191, 31,201,201,201,136,143,143,135,213,106,245,187, 11,192,179,173, 89,242, 30,120, 56,240, +236,132, 55,252, 14, 0,108, 54, 27, 32,114,216, 32, 95, 2,164, 59,157,191, 32, 8, 32, 73, 66,122, 68, 60, 72, 20, 32, 56,124, + 11, 0,172, 86, 43,119,242,248,241,240, 60,253,149,200,142,156,194, 36, 78,224, 37,155,131,241, 2, 7,135, 13,162,229,122, 78, +126,200,245, 12, 46, 56,190,106,213, 18,251,234,139,217, 54,145,136,230, 0, 72,112, 56, 28,191,172, 90,181,138, 91,182,108,153, +118,216,176, 97, 23,120,158,207,104,209,162, 69,220,178,101,203,180, 0,240,225,135, 31, 58,191,255,254,251,214, 0, 82,202,154, + 23,160,160,160,224,209, 83,167, 78, 77,232,222,189,251,107,193,193,193,124, 65, 65,129,242,250,245,235, 64, 78, 50,216,151,191, +141, 12, 96,154, 40, 56,122, 44,194,228,201,147, 85, 19, 39, 78, 28, 3,224, 75,111,122,143, 54,173, 32,118,137, 12, 85, 12,105, +200, 3,166, 60, 80,199, 73,128,164, 1,224, 26, 61, 99, 52, 26,253,210,187, 31,246, 1,128,193, 96, 24, 49, 98,196,136,181, 13, + 27, 54, 84, 53,108,216, 16, 31,127,252, 49,122,244,112, 37, 13,212,106, 53, 26, 53,106,132, 11, 23, 46, 96,248,240,225, 38,163, +209,248, 76, 89,255, 19, 55,103, 22, 47, 94,220,230,241,199, 31, 63,219,169, 83, 39, 17,128, 34, 59, 59,155,204,102, 51,139,141, +141,229,135, 13, 27,166,168, 89,179,102,196,144, 33, 67, 20, 0,202,188,230, 60,120, 2, 0, 65, 16,112,245,234, 85, 72,146, 4, +155,205,134,209,163, 71,163, 83,167, 78,247, 26, 0,196, 85,169, 82,229,140, 70,163, 57,156,145,145,113, 1,192, 99,229, 17, 43, +137, 18,175, 8,119,186,219, 17,174,224,231,140, 25,254, 84, 84,216,133, 95, 96,200,187,133,160,224,112,204,232,213, 42,120,230, +230,131, 75,174,229,235,203, 76,219,120, 48, 27,237, 11, 62,255,104,235, 7,111,127, 49,204, 46,112,178,195, 6,139, 14,140,113, + 4,198, 64, 0, 99, 80, 16,131,134, 17,147,182,174,185, 22,100, 51,219, 39,251,106,124,145,243,151, 8, 10,193,229,252,101,247, + 61, 67,173,116, 13, 9,244, 86, 3, 64, 68,221,100,158,190,124,167, 69,120,196,243, 9,193,176, 59, 25,222, 56,145,135,121, 43, + 22,237,181,243,156,169, 69,183, 10,221,218, 61, 81, 5, 79, 78,106, 40,156,218,151, 57,109,251,151,105, 99,137,104, 32, 99,172, +220, 19, 34,249, 3, 17,181, 85,171,213, 63,110,220,184, 81,214,106,181, 56,118,236, 24,198,143, 31,111, 48, 26,141, 3, 24, 99, + 91,252,208, 9,109,212,168, 81,203,233,211,167,239,232,218,181,107, 33,126,115,254, 69, 1, 64,181,106,213,184,102,205,154, 93, +105,218,180,169,213,106,181, 14, 36,162, 93,112, 5,122, 58, 63,135,156,220,211,132, 60, 0,112,236,216,177, 59,156,255, 21, 91, +211, 49, 85,170,252,214,242,151,101,185,168, 5,224, 11,165,244,249,199,185,135,234,121, 60,141,133,136, 42,149, 33, 83,154,118, +183,161, 67,135,126, 54, 97,194, 4,154, 60,121,178,115,253,250,245,126, 59,127, 0,120,253,245,215,127, 28, 58,116,104,163, 39, +158,120, 34,116,240,224,193, 54,189, 94, 79,249,249,249,180,119,239, 94, 74, 77, 77,205, 27, 52,104, 80,153,255,111,155,197, 18, +189,118,207, 73, 72,130, 0, 73,228,161, 16, 92,213,254,237, 27, 86,243,107,178,156,226,136,162, 8, 89,150, 49,107,214, 44,236, +221,187, 23, 49, 49, 49,104,210,164, 9, 44, 22, 11,234,212,169,131, 30, 61,122,160, 85,171, 86,229,202, 0,120,182,201,179,223, + 1,207,113, 88, 60,239, 21,216, 44, 38, 76,249,223,114,191, 50, 0, 78,135, 19,191,178, 61,168,248,113, 19,176,229, 74,100,238, + 77,129, 32, 8,136,123,176, 59,236,137,125,144,163, 8,129,154, 57,125,206, 0,204,157, 59,183, 93,197,138, 21,111,213,121,160, + 86, 90,110,141,151,111,243,112,210,132,119,151, 13, 31,214, 61,113,133,147, 4,103, 86,158,116, 59,235,214,173,176, 11, 23, 47, +214,240,166,229, 46,232, 59, 72, 68,115,187,118,237, 58,109,200,144, 33, 56,116,232, 80,144,195,225, 8,242,212,143,172, 88,177, + 2,171, 87,175,158,235, 75, 17,155,251, 58,124, 11,192, 91, 68,212, 57, 38, 38,102, 67, 68, 68,132, 10,249,142, 59, 70, 6, 96, + 60,193,168,215, 33, 34, 34, 2, 6,131,161,190, 47,122,213, 35,213, 61,179,116,145,235,159,125,116,174,235,194,226, 4, 32, 40, + 22, 58,157, 14,249,249,249,200,207,207,247, 75,239,126,216,231,214,220, 44, 73,210,184,230,205,155,191, 59,105,210, 36,197,128, + 1, 3,248,164,164, 36, 56,157, 78, 52,104,208, 0,111,188,241,134,253,127,255,251,159,205, 98,177,188,204, 24,219,236,195,119, +120,158,136,148,221,187,119,111,210,190,125,123,125,183,110,221,168,109,219,182,100, 50,153,232,204,153, 51,226, 47,191,252, 34, + 36, 37, 37,113, 54,155,237,136,175, 67,121, 61, 1,128, 66,161, 64,181,106,213,240,193, 7, 31,224,153,103,158,193,150, 45, 91, +208,160, 65,131,123, 13, 0,110, 54,110,220,248,102,122,122,250, 69,148,179,128,178, 52,202, 26, 5, 80, 51, 33, 54,252,191,227, + 38,188,194,231, 45, 24, 1, 82, 5,129, 83, 40,241,120,243, 10,220,151, 71, 46,180, 87,138, 98, 71,147,205,182,219,219, 9, 24, + 99,235, 84, 26,241,249,133,243,190,107,252,248, 51,213,110, 51,230, 84, 18, 72, 1, 34,157,147, 65,195, 1, 10, 16,184, 31, 86, +164, 71,230,102,153,207, 57, 28, 88,225,171,241, 37, 57,127,133,232,233, 2,112,101, 0,120,239,195,147, 94, 51, 45,159, 30, 1, +198,112,232,171,165, 24,249,235, 45,221,169, 92,235, 56, 0,159, 49,187,157, 17,209,224,243, 73,183, 23, 62, 50,162, 86,200,132, +209, 99, 48,238, 5,187,166, 99,227,151,166,194, 85,164,241,135, 35,138,226,182,205,155, 55, 43,213,106, 53,142, 30, 61,138, 9, + 19, 38, 24, 76, 38, 83,111,127, 82,203, 0, 16, 28, 28,204,130,131,131,183, 63,241,196, 19, 38, 20,115,250,197,158, 3, 0, 30, +120,224, 1,218,184,113,227,145,246,237,219, 71,219,237,246, 56,189, 94, 31,103,181, 90,175,163,148,249, 25,108, 54, 27, 46, 95, +190,140,170, 85,171, 22,237, 35,162, 82, 3,128,155, 55,111,122, 29, 50, 86,171, 86,173,111,110,157, 94,189,231, 78,231, 95, 37, + 38, 36, 36,164,200,241,251,147, 1, 40,173,224, 15,174, 74, 91, 17,192,233, 98,135,251, 21, 0, 16, 81,183,225,195,135,111,158, + 62,125,186, 48,118,236, 88,251,134, 13, 27, 30,245,215,249, 51,198,114, 38, 76,152, 16, 57,126,252,120,121,249,242,229,243,103, +204,152,209, 99,198,140, 25, 45,114,114,114, 66,181, 90,109, 94,104,104,232,225,126,253,250,109, 49,153, 76,142,109,219,182,153, +225, 10,202,126,135,168, 80,100, 61,217,161, 81,137, 25, 0,127,236, 41,142,167, 11, 64, 16, 4,244,236,217, 19, 54,155, 13, 22, +139, 5, 54,155, 13,106,181, 26,221,186,117, 43,218,231, 75, 6,192,110,183,255, 46, 0,200,203, 47,132, 40,138,152,243,209, 10, + 16,199,225,205,151,158, 66,197,112, 53,210,111,100, 97,233,210,165,101,234,217,108, 54, 56, 45, 78,168,135,197, 66,249, 92, 48, +232,185,154,168,223,243, 57,228,235,170,224,184, 89,141,122,134,179, 8,221,249, 33,172, 14,187, 79, 1, 0,199,113,105, 71,142, + 28,105,144,152,152,184, 81,211,160,235,213,171, 78, 39,129,156,180,234,200,130,225,202,122, 81,135,121, 73,102,130, 36, 49, 65, +208, 85, 78, 77, 77,109,201,113,220, 5, 31,191,202,233, 67,135, 14,197,182,109,219,166,140, 25, 51,134, 75, 72, 72, 64, 74, 74, + 10, 62,250,232, 35,231,234,213,171,231, 2,152,238,163, 78,113, 82, 12, 6, 67,169, 29,193, 6,131, 1,183,111, 59, 33,138,162, + 79,163, 70, 46,229, 24,143,223,178,228, 50,132,253,118, 45, 23,119,254,121,121,121,158, 74,126, 95,135,105,223, 55,251,172, 86, +235,167, 68,180,127,222,188,121,175,112, 28,215,222,104, 52, 70, 3,112,170,213,234,155,118,187,125,183, 94,175,127,151, 49,150, +234,163, 93, 96,140,157, 36,162,244, 3, 7, 14,196, 39, 37, 37, 85,212,235,245,145, 0, 32,138,226,109,163,209,120, 13,174,161, +192, 62,207,208,232,201, 32, 74,146,132,118,237,218,225,192,129, 3,232,219,183, 47,234,215,175,143,158, 61,123,222,107, 0,112, + 42, 61, 61,189, 49,128, 71, 1,220, 4,112,162, 60, 98, 37, 81,234, 21, 17,165, 18,215, 45,253,252, 11,173,110,245, 60,128, 23, + 65, 10, 37, 72, 82,130, 20, 74, 44,124,225, 41,117,143,153, 31,174,206,156,228,102, 0, 0, 32, 0, 73, 68, 65, 84,118, 79,234, +226, 53, 29,110, 50,216,123,156, 58,148,253,253,213,180,252,250,157,251, 85,202,171,222, 32, 56, 87, 20, 9, 78, 39, 44,105,103, + 10, 84,219,191,186, 22,150,151,109, 73, 54, 27, 29,221,125,109,105, 58, 25,220,133,127,238,212,191,219,249,123,186, 0, 28,214, + 60, 56,192, 3,240,106,158, 13, 54, 43,176,115, 57, 90,109,185,113,203,201,208,136, 49,150,225,121,145, 49,182,146,136,182,175, +152,125,252,244,240, 62,246,168, 83,151, 54,194, 23,209,251, 5, 99,140, 37, 39, 39,131,136, 48,105,210, 36,189,201,100,122,140, + 49,246,147,191, 58,249,249,249,101,166, 43,239,102,239,222,189, 87, 1,120,157,241, 49, 63, 63,255,241, 17, 35, 70, 44,109,221, +186,117,133,113,227,198,133,132,133,133,149, 24, 0, 20, 22, 22,226,199, 31,127,204,187,120,241,226, 53,189, 94, 95,106,154,142, +136,212,111,252,167,254,186,231,187, 73, 35,239,118,254, 30,167,239, 79, 6,160,172,106,255,123, 45,162, 33,162, 54, 35, 70,140, +216, 60,115,230, 76,225,197, 23, 95, 44,151,243, 7,128,236,236,236,173, 68, 84, 33, 37, 37,165,117,187,118,237, 84,211,166, 77, +219, 20, 28, 28,188,233,210,165, 75, 25, 59,119,238,140,117, 56, 28,248,249,231,159,173,233,233,233, 70,189, 94,255, 75,105, 99, +168,139, 79, 2,116, 55, 37,141, 2,144,101,101,150,201, 84,114,245,191, 7, 81, 20, 49, 96,192, 0,220,235,119,229,161,164, 0, +192,179,229,235,140, 16, 69, 17, 31,126,181, 3,193, 26, 37, 76, 86,239,243,166,216,237, 46,199,174,187, 84,136,139, 83,142, 67, +165,189,128,218, 93,130, 17,196,159, 71,237,159,191,131,221,110, 1,138,213, 5,120,195,233,116,214,189,125,251,246,200,121,243, +230,189,254,229,151, 95, 94,120,249,229,151,127,104,217,178,101,142,195,201, 96, 3,231,188,126,237, 90,196,175,191,254,250, 72, + 65, 65, 65, 77,167,211, 57, 19,192, 18, 95, 62,183,251,190,246, 26, 17,109, 49, 24, 12, 7,158,127,254,121, 44, 92,184, 16, 91, +182,108,105, 93,222,225,107,140,177, 27, 26,141,198,124,234,212, 41,101, 67,141, 0,166,137, 2,220, 35, 3,108,114, 24, 12, 38, + 51,174, 92,201, 98, 60,207, 31,246, 91,175, 97, 67, 20, 22, 22,162,160,160, 0,121,121,121,200,207,207, 71, 65, 65, 1,174, 92, +185, 82, 62,189,251, 99, 95, 50,128, 33,190, 28,235,163,158,167,194,254,228,189,106, 21,239, 2, 8, 15, 15,199,128, 1, 3,138, +238, 83,197,135, 51,251, 43,235,182,211, 0,192,231,110, 73,127, 40,241,138,208, 8, 52,236,177,166, 53,107, 53, 18, 13, 40, 72, + 79, 5, 23, 20, 6, 78,225,114,254,156,172, 66,124,100, 24,254,243, 88,151,136,207, 54,110,159, 11, 96,130,183,147, 48,198,140, + 0, 30, 18, 4,234,255,205, 39, 23,167,154,205,142, 38,130,200,217,236, 54,167,168,144,249, 52,139,201, 62,193,225,192,106,230, + 75, 19, 2, 0, 47,170, 10,120,142, 74,173, 42, 19, 36,141,174,126,237,202, 69,129,132, 66, 21, 81, 86, 77,193,155, 52,124, 46, +224,250,178,231, 21,119,254,197,236,207, 38,162,161, 29, 27,191,244,170,231, 61,190,216,121, 63,176,219,237, 93,199,141, 27,183, + 13, 0,108, 54, 91, 15,198,216,190, 63,235,220,190,224,190,121,213, 87, 40, 20,253,126,253,245,215,183,251,246,237, 27,238,112, + 56,184, 98,175,115, 59,118,236,208,159, 56,113,226,182,217,108, 30,107,183,219, 75, 93,147,129,136,104, 76,159,234, 15, 79, 25, +154, 48,114,225,215, 23,214,191,181, 46,187,111, 70,198, 79,101, 58,168,178,166,182, 37, 34,217,135,161,126,190,143, 13,251,253, +185,159,155, 58,117,170, 48,118,236, 88,251,119,223,125, 87, 46,231,239,193,237,212,215,201,178, 92,125,255,254,253, 15, 60,254, +248,227,138,198,141, 27,115, 73, 73, 73,182,180,180, 52,139,193, 96, 56,196,252,159,118,182,136, 59, 70, 1,184,187, 6, 98,195, +131,188,118, 13,120, 38, 2,186, 95, 24,141, 70,175, 99,255,117, 38, 11,204,118,167, 79, 93, 0, 70,163,241,142,126,127,102,119, + 32,109,251,218, 59,138, 1,253,153, 9,208, 93, 67,243, 17, 17, 45,187,118,237,218,184,241,227,199, 79, 72, 72, 72, 56, 10, 0, +155, 55,111,238,155,147,147,147, 72, 68,255,115, 58,157, 93,221, 55,102,127, 73, 33, 34, 71, 66, 66, 2,239,118, 10, 62,165,152, + 75,195,106,181, 78, 30, 50,100,200,219, 63,125,183, 66,227,124,228, 99, 24, 13, 58, 24, 12, 6, 24, 76, 22,100, 88,149, 88,184, +112,182,165,160,160, 96,170,191,122, 59,118,236,208,152, 76,166,162,150,127, 97, 97, 33,116, 58, 29, 22, 46, 92, 88, 46,189,251, +101,223,223, 17,158,231,179,102,204,152, 17, 13, 0, 59,119,238, 44,245, 56, 81, 20,125,205,196,233,137,104, 36, 0,111,215,158, +215,249, 79,188, 81,226, 98, 64, 81, 50,183, 9, 68, 15, 10, 60,199,136,120, 34,142,115,175,186,198, 17, 56,142,200, 29,238,216, +157,142,155, 55,110, 23,214,245,251,164, 68, 60, 92,213,151, 5,172, 28,211, 35, 6,248,123, 66, 68,130, 86,171,125, 81,150,229, + 54,217,217,217,189, 1, 64,163,209,108,118, 58,157,219, 77, 38,211,199,222,134, 82, 18, 17, 61,214,174, 66,247,218,149,180, 17, +111,173, 58,123, 1,192,105, 95, 38,249, 41, 67, 47,222,248, 83,239,241,111,174, 58,155, 92,146,243, 39,162,214,248,253,136, 19, +159,139, 0,137,168,137, 40,138, 47,217,108,182,229,140, 49,175,221, 97,126,216,205,105, 52,154,186,146, 36,213,214,235,245,231, +172, 86,107,138,159, 53, 24,191,163, 60, 25, 0,149, 74,149,105, 50,153,238,219, 98, 64, 60,207,103, 58,157, 78,191,244, 4, 65, +200,178,217,108,247, 77,143,231,249, 44,187,221,238,115, 65, 36, 17,133, 11,130,240,154,221,110, 31,195,113,220, 7, 78,167,115, +182,175, 35, 70, 74, 67,150,229,247, 58,116,232,240,220,174, 93,187, 22,150, 52,222,223, 95, 66, 66, 66, 86,133,134,134, 62, 54, +113,226, 68,117,116,116, 52,242,242,242,112,249,242,101,246,233,167,159,154, 45, 22,203,171, 58,157,174,196, 57, 60,254,169,122, + 1,238, 31, 62,173, 6, 24, 32,192,159,133,123, 30,134,104, 0,250,123,113,254,110, 45, 9, 64, 13,184,230,209,190,116,175, 55, +238, 0, 1,238, 23, 68,196,221,107, 80,119,151,222,227, 17, 17, 17, 47,155, 76,166, 70, 60,207,155, 69, 81, 60,114,251,246,237, +215, 24, 99,229,234, 47,254,187,235, 5,184, 63, 4, 2,128, 0,255,239, 33, 34,233,207, 30,186, 25, 32, 64,128, 0,127,119, 2, + 1, 64,128, 0, 1, 2, 4, 8,240, 47,164,196,153, 0, 3, 4, 8, 16, 32, 64,128, 0,255,191, 9, 4, 0, 1, 2, 4, 8, 16, + 32,192,191,144, 64, 0, 16, 32, 64,128, 0, 1, 2,252, 11, 9, 4, 0, 1, 2, 4,240, 27, 34,226,137,200,191, 37,206,202,214, + 11, 20, 35,253,203, 32,162,154, 60,207,123, 93, 82, 62,192, 31,199,159,183, 60, 86,128, 0,255, 15, 80,169, 84, 71, 45, 22, 75, +169,171,113,221, 61,113,135, 36, 73, 55,141, 70, 99,124,105,199,203,178,124,222,102,179, 85, 45,237,245,187,245,100, 89,190,172, +215,235,107,249,110,241,253,135,136, 36,142,227,126,108,210,164, 73, 19,158,231,175, 58,157,206, 86,229,156, 20,199,163,199, 24, + 99,158,199,251, 55,235, 80,128,191, 45, 68, 20, 78, 68, 63, 76,153, 50,229,250, 95,109,203,191,153, 64, 6, 32, 0,136,200,251, + 20,105,222, 53,136,136,158, 33,162,239,137, 40,147,136,110, 17,209, 86, 34, 26, 69, 68,126,255,206,136,136,147,120, 26, 19,174, +228,126, 81,138,156, 78, 45,113, 5,225, 42, 97,159, 32,208,127,168, 28, 83,211,253,166, 71,191, 40, 69,210,169, 69,174, 32, 92, +197,249,173,231,112, 56,106,158, 58,117, 74, 40, 44, 44, 20, 10, 11, 11, 5,157, 78, 39,232,245,122, 65,175,215, 11, 6,131,161, +104, 51, 26,141, 66,122,122,186, 96, 50,153, 42,151,165,103,179,217,170,158, 61,123,214, 39,189,180,180, 52,193,108, 54,151, 26, + 44,252,145, 16,145, 64, 68,245,220, 43,103, 70,180,108,217,178,241,215, 95,127, 29, 50,109,218,180,250, 0, 86,223,131,110,209, + 4,160,158, 32,224, 62,216,218, 70,161, 80, 92,116,175,161,238,183, 61,254,110,247,106,175,159,246, 69, 18, 81,172,143,199, 86, + 34,162, 42, 94,142, 9, 37,162, 56, 31,245, 98,136,168,186, 47,199,122,209, 81, 0,216, 48,124,248,112,219,172, 89,179,124,250, + 44, 1,254, 24, 2, 25,128,127, 57, 68,164, 6,144, 78, 68,227, 24, 99, 62, 47,196,116,151, 70, 4,128, 53,112,173,175, 61, 7, +174, 53,185, 29, 0,154, 1,152, 4, 96, 32, 17, 13, 40,109, 14,251, 18,244, 42,104, 36,108,238,255,240,131, 9, 83, 95, 24,164, +140,141,141,133,195, 88,128,243, 41,103,218,190,186,100, 75,211,131,103, 46, 14, 39,162,199, 24, 99, 37, 46,138, 83,154,222,128, +206, 15, 38,188, 58,226, 49,101,108,100, 24,236,133,217, 72, 73, 62,211,246,149,229, 63, 55, 61,145,150,233,151, 94,133, 10, 21, +112,252,248,113, 88,173,214,162,101,103, 69, 81,132, 36, 73, 69,207, 69, 81,132,103,181, 55,111,196,197,197, 33, 41, 41,233,142, +121,242, 5, 65,184, 67, 79,146, 36,216,237,190, 79,154, 73, 68, 53,227,227,227,215,214,168, 81,163,202,238,221,187,183, 59,157, +206,105, 28,199,205,110,221,186,117,231, 43, 87,174,164, 95,187,118,237, 73,198,152, 79, 11,217,184, 3,196, 83,205,154, 53,139, + 62,121,242,100,174,221,110,239,121,228,200,145,140,212,212,212,208, 23, 94,120,129, 59,114,228,200, 67, 68,244, 44, 99,204,167, +121,241,139,233,118,112, 63,122,156,127,209,126,198,216, 30,127,180,138,105,182,169, 92,185,242,143,139, 22, 45, 82, 63,241,196, + 19, 91,137,168, 59, 99,108,191, 63, 26,223,126,251, 45, 0,192,233,116,194,233,116,130, 49, 6,167,211, 53,103, 79,241, 96, 5, + 0,158,122,234,169,242,152,121, 47,136, 0,222, 38,162,247, 25, 99,165, 46, 85,235, 14,126, 30, 3, 48,223,139, 30, 15, 96, 30, + 17, 45, 41,235,123, 34,162,102, 0, 6,193,181,210, 95,185,113, 7,219,203,218,182,109, 27,181,116,233,210, 90,118,187,253,156, +175,171, 52, 2, 64,100,100,228,151, 57, 57, 57,115,124, 93,165,207, 7,123,186, 2, 56,228, 94, 23,224, 95,199, 63, 62, 3, 64, + 68, 79, 18,209, 38, 34,202,117, 63, 62,249, 87,219,244, 15, 35, 17, 64, 24,128,126,247,160,177, 24,192,121, 0,173, 25, 99,155, + 24, 99, 55, 25, 99, 89,140,177, 31, 0, 60, 4, 96, 31,128, 85,190,180,180,137,136,130, 36,108, 88, 57,247,165, 70, 75, 23, 76, + 83, 86,205,217, 7,121,207, 60,168,143, 46, 65, 19,225, 50,126,152,242,136,122,204,163, 45, 90, 4,171,132, 85,190, 24,230,209, + 91, 51,127, 92,163,197,179,199, 41,171,231,236,134,234,151,119, 16,148,188, 22, 45, 85, 55,176,107,108, 83,245,208, 86,113,205, +131,100,126,141,175, 31,150,136,224,112, 56, 96,183,219,225,112, 56,138,156,196,226,197,139,225,112, 56,238, 88, 24,196, 87, 61, +187,221,254, 59, 61, 83,163, 70, 69, 90,254,232, 1, 64,120,120,248,119,169,169,169,245,119,238,220, 25,246,221,119,223,117,232, +218,181,107,210,218,181,107, 59,108,220,184, 49,124,239,222,189,245, 67, 67, 67,191,243, 89, 12,104,216,188,121,243,184,117,235, +214,133,174, 94,189,186,122, 84, 84,212,110,155,205,182,110,244,232,209, 57,102,179, 25, 31,127,252,177, 38, 44, 44,236, 13,119, +203,206,215,207,220,129, 49,182,231,238,148, 63, 99,140, 24, 99,123, 60,193,129, 63,120,156,255,193,131, 7,213,146, 36,225,185, +231,158,211, 40, 20,138,173,254,102, 2,136, 8,167, 79,159,198,185,115,231,112,249,242,101, 92,191,126, 29, 89, 89, 89,184,125, +251, 54, 10, 11, 11, 97, 52, 26, 97,179,217,124, 90,253,240, 46, 93, 65,161, 80,188,174, 86,171, 47, 11,130, 96,211,104, 52,151, +149, 74,229,235,238,172,138, 79, 48,198,110, 2, 88, 6, 96, 19, 17,229, 20,203, 68, 20,205,168, 71, 68,221, 0,124, 13, 96,185, +183,160,214,253,250, 39, 0,214,151,246, 61,185,247,127, 15, 96, 37, 99,172,220, 43, 75,186,153, 93,181,106,213,150, 59,118,236, +168,165,211,233,112,246,172,127,126,156, 49,214, 35, 46, 46,110, 55, 17, 37,220,163, 29, 30, 66, 1,116, 34,162,144,251,164,247, +143,194,107, 0,224, 78,237, 46, 33,162, 60,247,227,223,166,143,142,136,166, 0,152, 10, 87, 10,178,161,251,113,170,123,255,189, +232, 10, 68,244, 57, 17, 69,222, 7, 51,255,238, 60, 8, 96, 11, 92,173,117,191, 33,162,222, 0,106, 2,120, 25, 0, 35,162, 23, +136,232, 20, 17,165, 18,209,203,112,101,153,166,193,213,210, 24,233, 77, 79,228,240,220, 19, 15,183,170,215,171,123,103,206,246, +237, 75,120,111,253,110,212,127,235, 12,234,191,121, 18, 11,183,158, 6,203, 76,197,235,189,106, 9, 17, 90,101,107,247,185,189, +234, 13,120,164, 67,189, 71, 58, 60,200,217,190, 29,139,255,125,123,192, 25,255,230, 69,125,245,249,231,116, 31,238,186,204, 96, + 42,192, 59,189,171,139,209, 65,138,150, 68, 52,192,199,207, 92,212, 42, 47,190,241, 60, 95,244,220,223, 21,192,138,191,199,179, +121,246,223,189,175, 12,187,234, 68, 71, 71,175, 15, 13, 13,205,235,217,179,103,221,148,148, 20, 41, 41, 41, 9, 81, 81, 81, 49, +235,215,175, 15, 14, 13, 13,141, 57,112,224, 0, 78,157, 58, 37,181,107,215,174,110, 72, 72, 72, 94,116,116,244,122, 34,170, 83, +134,166, 8,128, 59,118,236, 88,214,154, 53,107, 88,155, 54,109,176,109,219,182,152,250,245,235,143,189,116,233,210, 47,243,231, +207,183, 70, 71, 71, 99,192,128, 1,225, 0,158,240,241,251, 99, 0,188,173,157,176,219,159,244,122,113,231,159,146,146,130, 51, +103,206,160,110,221,186, 24, 63,126,188, 70,150,101,191,130, 0,198, 88,209, 2, 66,213,171, 87, 71,223,190,125,241,194, 11, 47, +160,119,239,222,168, 86,173,218, 29, 89, 26, 63,236, 19,100, 89, 62,208,175, 95,191, 87, 15, 29, 58, 84, 37, 63, 63, 95,216,185, +115,103,149,206,157, 59,191,162, 86,171, 15,248, 25, 4,108, 7,240, 2,128, 16,198, 24,110,222,188, 89, 8,160, 97,177, 46,137, +239, 0, 60,198, 24, 59,227,163,222, 1,184, 26, 0,191, 11, 2,220,127,175, 7,208,143, 49,118,220, 87, 27, 75,130,136, 70,132, +134,134,142, 56,122,244,104,149,188,188, 60,164,166,166, 34, 37, 37,197, 47, 13,133, 66, 97,221,181,107, 87,204,125, 12, 2,108, + 0,118,225, 95, 26, 4,248,146, 1,120, 30, 64, 29, 0, 77,220,143,207,151,247,100, 68,212,204,237, 88, 79, 18,145,201,253,248, +185, 59,189,228,175,214, 83, 0,254, 3,160, 51, 99,108, 45, 99,236, 58, 99,108, 45,128,206, 0,254,227,126,189,188, 36, 2, 24, + 14,160,245, 61,104, 20,225, 14,162, 90,221, 15,173, 63,128,150, 0, 86, 2,224,136,168, 26, 17, 13, 39,162, 51, 68, 20,229,227, +251,251, 0,248,208, 61,213,238, 16, 0,207, 0, 24, 3, 96,132,251,181, 81,238, 57,207, 23, 0,232,229, 77, 76, 43,209,160, 41, +255,233,173,196,161,207,177,228, 72, 1,174,134,183,193,158, 31, 55,225,155,183,198, 96,117,210,109, 44, 61,144, 9,137, 89, 48, +225,209, 6,234, 16,149,194,235,210,160, 90, 9,131, 38, 13,235,165,164, 3,159,226,163,195, 58,231,244,221,186,147,215, 10,236, + 93, 46,231,218,122, 78,217,122, 51,121,217, 9, 35, 19, 35,171, 97,106,207, 4, 77,136, 74, 26,232, 77,207,211, 26, 23, 69, 17, +171, 87,175,198,242,229,203,139,210,245, 60,207,255, 46, 48,240, 5,143, 94,135, 31, 51,208,122,243,213, 82, 3, 0,111,171,217, +197,197,197, 45, 93,176, 96, 65,223, 91,183,110,133,244,239,223,159,154, 52,105,130,196,196, 68,212,174, 93, 27, 6,131, 1, 53, +106,212, 64,143, 30, 61, 80,181,106, 85,180,110,221,154,118,237,218, 21, 50,109,218,180,190,113,113,113, 75, 75,177, 75, 4,112, +162,121,243,230,219,136, 72,158, 54,109, 90,218,164, 73,147, 44, 21, 43, 86,196,146, 37, 75, 66, 4, 65,104,188,126,253,250, 92, +142,227, 48, 96,192, 0, 17,192,139, 62,124,214,162, 62,255, 98, 14, 11, 86,171,245,119,251, 46, 94,188,232, 83, 77, 64,113,231, +159,156,156,140,211,167, 79, 23, 45, 23,221,176, 97, 67, 76,159, 62, 93,163, 84, 42,125, 14, 2,156, 78,215, 74,132, 53,106,212, + 64,207,158, 61, 97,181, 90,145,156,156, 12,171,213,138,166, 77,155,162, 66,133, 10, 62,175, 46,232, 65,146,164, 41,125,250,244, +169,247,217,103,159, 41,121,158, 71, 74, 74, 10,194,194,194,240,241,199, 31,171,154, 55,111, 94, 71,150,101,127, 27, 45,187, 0, + 24, 0, 88,140, 70,163, 5,112, 5, 46,185,185,185,133, 0, 44,101,117, 15,148,132, 59,253,223, 15,192,174, 98, 89,133, 12,252, +230,252,253,234, 70,185, 27, 34,122, 88,169, 84, 46, 56,120,240, 96,100, 94, 94, 30, 82, 82, 82,144,146,146,130, 27, 55,110,248, + 93, 67,145,144,144,128,251, 25, 4,184,211,255,255,202, 32,160,204, 0,192,221,218, 31, 11, 96, 34, 99,236, 10,128,137, 0,198, +250,155, 5,112,183,168,103, 1,216, 12, 32, 25,192,179, 0,162,220,143,201, 0, 54, 19,209, 44, 95,163, 96,247,249, 95, 7, 48, +156, 49,150, 89,252, 53,247,223,195, 1,188,126, 15,217,138, 78, 0,140, 0,252, 46, 34, 42,133,247, 0,236, 33,162, 63,109, 25, + 97, 63,104, 9,224, 87,184, 46,244,233,112,245, 25,102, 1, 24,234,227,251, 19, 1, 28,117, 63, 31, 9, 96, 26, 99,108,175,187, + 85, 49, 17,191,181,250, 79,185,143, 45, 19,147, 29,141, 98,162,194,129,188,116, 44, 58,164,195,171,163,134, 33,226,228, 18,212, + 54,159,194,236, 62,245,176,244,231,171,128,168, 68, 98,173, 10,112, 2, 45,124,209,139, 10, 11, 2,242,174,224,189,131, 70,163, +222,202, 70, 49,198, 14, 48,198,246,233, 45,206, 23,223,250,241,162, 1, 97, 85,208,176,106, 4,156,204,187, 30,240,155,195, 30, + 57,114, 36, 70,141, 26,133,101,203,150,129,231,121,240, 60,143, 69,139, 22,225,189,247,222, 3,199,113,126, 7, 0, 71,251,214, +196,201,129,117,209,104, 77, 74,209,123,111, 86,174,140,244,216, 88,159, 2, 10,155,205, 22,209,172, 89, 51,156, 60,121, 18,151, + 47, 95,134, 94,175, 71,118,118, 54, 12, 6, 3,244,122, 61, 12, 6, 3,146,146,146,160,215,235,113,233,210, 37,156, 56,113, 2, +181,107,215,134,205,102,139, 40, 69,178, 94,155, 54,109, 42,108,218,180, 41,244,155,111,190,169, 20, 21, 21,165, 89,185,114,229, +141, 79, 63,253,212,217,184,113, 99,188,248,226,139, 21,114,114,114,162,127,254,249,103,180,109,219, 22, 90,173,182,162,151,207, +121, 71,193, 31, 99, 12, 14,135, 3,102,179, 25, 22,139, 5,183,111,223, 70, 70, 70, 6,210,211,211,145,150,150, 6,139,197,130, + 19, 39, 78,148, 25, 4,148,229,252, 61, 91,211,166, 77,177, 96,193, 2,141, 74,165,242, 57, 8, 16, 69, 17,205,155, 55,199,245, +235,215,145,159,159, 15, 81, 20, 97,183,219, 97,179,217, 80,189,122,245,162, 44,128,175, 8,130, 48,252,213, 87, 95, 85, 94,188, +120, 17,185,185,185, 16, 4,161,168,187,103,220,184,113,106,133, 66, 49,220,103, 49, 23,102, 0, 70, 34, 82,212,168, 81, 35, 18, +128, 19, 46,199,111,246, 83,167, 8,183,147,151, 60,255, 27, 0, 49,184, 71,231, 63,127,254,252,224,225,195,135,143, 81, 40, 20, +223,110,220,184, 81,101, 54,155,249,148,148, 20, 36, 37, 37, 97,225,194,133,215, 95,125,245,213, 50, 87, 8, 45,141, 64, 16,112, +127,240,150, 1,232, 12,192,232,190,153,123, 82, 69, 70,247,126,127,152, 14, 87,107,186, 33, 99,236, 29,198,216, 97,198,152,206, +253,248, 14, 92,233,251,214,238,227,124,161, 51, 0, 3, 99,108,111, 73, 47,186,247, 27,202, 97, 39,136, 72, 3, 96, 20,128, 97, + 0,158,190,215, 31, 3, 17,189, 14, 87, 63,120, 29, 0, 61,136,104,252,189,232,221, 15,220, 1, 89, 5,114,141,227,182, 50,198, +174, 1, 88, 10,215,247, 53, 9,174, 66,190,193, 62,202,241,112, 21,252, 1,174,116,154,178,216,107, 74,247, 62,184,143,241, 90, + 21,199, 0,206,105,184, 13,240, 18, 64,132,172,227,219, 1,139, 30, 16,149,112,112, 18, 64, 28, 32, 42,193, 75, 50,152, 15, 25, + 44, 6,226,156,186,108,128, 19, 32,242,196,112,231,242,191,178, 70, 45, 19,212, 97,224, 69, 5, 24,152,207, 53, 49,162, 40, 98, +217,178,101, 88,178,100, 73,145, 3,231,121, 30, 19, 39, 78,196,180,105,211,240,254,251,239,131,227,124, 47,177, 17, 69, 17,137, + 95, 95, 64,163, 53,174,148,168,199,217,215,202,205, 69, 61,157, 14,201, 90,173,215, 0, 32, 47, 47,239,133,190,125,251, 22,232, +116, 58,244,234,213, 11, 7, 14, 28,128, 78,231, 90,127,189, 66,133, 10, 48, 24, 12, 40, 44, 44,196,129, 3, 7,240,192, 3, 15, +192,225,112, 96,212,168, 81, 5,121,121,121, 47,148, 34,121,246,224,193,131, 55, 86,174, 92,201,218,183,111,143, 61,123,246,196, +214,173, 91, 55,100,206,156, 57,186,130,130, 2, 60,243,204, 51, 2, 0,235,249,243,231,193,113, 28, 34, 34, 34, 68, 34,186,123, +121,229, 34, 24, 99, 69, 49,185, 39,147,194,243, 60,100, 89,134,213,106, 69,120,120, 56, 98, 99, 99, 17, 31, 31,143, 26, 53,106, +192,106,181,162,113,227,198, 40,109,104, 32, 17,181,169, 82,165,202,143,135, 14, 29, 82,199,198,198,150,232,252, 61, 91,243,230, +205,177,104,209, 34,159,130, 0, 79, 23, 64,108,108, 44, 12, 6, 3, 84, 42, 21,148, 74, 37,148, 74, 37, 68, 81, 68, 72, 72, 72, + 81, 23,129,175, 88, 44,150,138,149, 43, 87,134, 94,175, 47,210, 82, 42,149, 80, 40, 20,168, 95,191, 62, 12, 6, 67,153,193, 83, + 9, 54,154, 1, 84, 5,224,105, 0,241, 68,164, 8, 15, 15,143, 2,112,197, 31,173,146,204,117,111,184, 23,231, 63,117,234,212, +233, 6,131, 33, 43, 39, 39,103,174, 32, 8,154,180,180, 52, 62, 57, 57, 25, 75,151, 46,205,155, 50,101, 74,193,241,227,199, 55, + 88,173,214,118,229,213, 15, 4, 1,247,142,183, 95,240,235,248,125, 21,233,124,247,254,237,190,156,192,157,222,127, 22, 64,227, +210, 10, 82, 24, 99, 57, 68, 52, 8,192, 9, 34,218,192, 24, 75,242, 34,219, 15,192,167, 94,142,249,212,125,156, 79,118, 22, 99, + 38,128,157,140,177,245, 68,212, 9,192, 92,184,250,219,252,134,136, 70,193,213,146,110,195, 24,203, 32, 87,197,233,126, 34,186, +205, 24, 91, 86, 30,205,251,196,123,112,181,204,119,195,253,253, 48,198, 78, 2,136, 3, 92,147,188, 0,136, 35,162, 74,238,224, +160, 44,142,194,213,178, 63, 1, 96, 17,128,185, 68,228, 4, 96,133,235,187, 91,228, 62,174, 1,126,203, 20,148,138, 74,226, 78, + 93, 72, 77,121, 48, 81, 19,133,231,219, 85,196,136,121, 43,241,246,147,141,192,137,118, 76, 93,127, 26,255,233, 92, 31, 16, 85, + 56,122, 57, 29, 2,207,121,215, 19,113,234,194,217,148, 7, 19, 53,145, 24,223,222,160,121,245,135, 27, 31, 19,209,243, 0,148, + 90,153, 95, 56,115,248, 35, 42, 56, 28, 56,125,195, 0,129,243,174, 7,184,156,215,146, 37, 75,240,252,243,207, 67,169, 84,226, +147, 79, 62,249, 93, 13,128,175,206,223,227, 8, 27,174, 78,198,217, 97, 77, 32,138, 34,170, 47, 57,124, 71, 23,128,175, 45, 77, +155,205,182,139,136,250, 15, 26, 52,232,101,179,217,252, 0, 0,165, 36, 73,138, 45, 91,182,208,154, 53,107, 80,181,106, 85,244, +235,215,143, 89, 44, 22, 11,199,113, 38, 89,150, 15,101,103,103,255,143, 49,182,171, 36, 61,198,152,153,136, 90, 78,156, 56,113, +227,249,243,231, 31, 92,184,112,161,252,214, 91,111,133,245,236,217,211,178,127,255,126,244,238,221, 27,145,145,145,134,130,130, + 2, 5, 0, 4, 5, 5,241, 0, 34, 0,148, 58,182,219, 29, 4, 48,207,115,247,119,192, 44, 22, 11,238,222, 87,150,243, 7, 0, +133, 66,241,218,149, 43, 87,212, 53,107,214, 52,235,116, 58,121,198,140, 25,230,194,194, 66,121,224,192,129,214, 49, 99,198, 72, + 61,123,246, 52,231,230,230,202,131, 7, 15,182,206,154, 53, 75,234,217,179,167,217,104, 52,106, 52, 26,205,107, 0,186,150,245, + 93,138,162,136,140,140, 12, 4, 7, 7,195,233,116, 66,150,101, 40, 20, 10, 40, 20, 10,152, 76, 38,191,107, 0,100, 89,190,126, +230,204,153, 42,225,225,225,112, 58,157, 69, 1,128, 74,165,194,217,179,103,161,209,104,202, 51, 30, 94, 6,160,100,140, 33, 47, + 47,207, 18, 22, 22,102,102,140,221,171,227, 74, 39, 34,207,188, 21,233,229, 21,121,237,181,215, 94,201,207,207,159,148,147,147, +163, 8, 11, 11, 83, 84,172, 88, 17,227,198,141, 19, 36, 73,202, 53, 24, 12,199, 29, 14,199,139,140, 49,255, 10, 0,220,228,228, +228, 32, 35, 35, 3,199,143, 31,199,171,175,190,170,179, 90,173,138,136,136,136,169, 0,158, 46,143,158, 59,104, 85,194, 85, 16, +216, 12, 0,193,149, 93,244,215,119,252,227, 40,245, 23, 76, 68, 61,224, 90, 71,125,237, 93, 47,173, 5, 48,137,136,122, 48,198, +182,248,112,142, 81, 0, 22,220,157,170,191, 27,198, 88, 38, 17,189,237, 62,126,132, 23,205, 26,112, 85,194,150, 69, 50, 0,191, + 70, 4,144,171,120,176, 43,128, 14,238, 93,147,225,234, 19,155,197, 24,123,205, 79,173,129, 0,166, 0,104,199, 24,203, 0, 92, + 21,188,238, 32, 96, 15, 17,229, 50,198, 54,249,160,115, 5, 64,169, 19,201,148, 64, 58, 99,172, 74, 25,122, 60, 92, 65, 73,123, +184,254,151,191, 27,214,195, 24,115, 16,209, 22, 0, 61,241,155, 3, 47,141,205,112,117, 11, 45, 99,140,173, 33, 34, 11, 92, 1, +147, 8, 87,176,248,149,187,217,247, 50, 92,149,196,101,162, 51,179,245, 51,191,220,221,104,211,164,206,170,145, 29,173,128,164, +198,232,149,167, 64, 28,135, 81,143, 52,194,127,186, 53,131,157, 83,224,253, 13, 71, 12,121, 58,147,215,202,125,157,133,214,207, + 92,181,175,209,166, 81,205, 84, 35,219,218, 72, 27, 25,155,240,222, 79,215, 54, 43, 21, 10, 76, 27,214, 85,211,165, 83, 7, 56, + 46,254,130,249, 27, 79,234,243, 12,150,245,222,244, 60, 14,251,165,151, 94,194,135, 31,126, 8, 0, 69,142,159,231,121,188,251, +238,187,224, 56, 14, 83,167, 78,245,107, 20,192,197,103, 91,160,250,146,195, 69,251, 36, 73,130,157,227,112, 70,163, 1, 0,180, +112, 58, 97, 54,123,207,238,186, 11,196,138,110, 92,146, 36,237, 55, 24, 12,173, 43, 85,170, 4,189, 94,143,130,130,130, 95,109, + 54,155, 63, 5,113, 58, 0, 15, 17,209,169,158, 61,123, 54,232,213,171, 23,226,226,226,184,195,135, 15,163, 79,159, 62,104,208, +160,129,186,160,160, 0, 0, 16, 28, 28, 44,193, 75, 0,224,214, 36,186,171,202,223, 83, 3, 80,140,142,222,134, 2,154,205,230, +174,192,111,179, 8, 22, 22, 22,202,140, 49,154, 57,115, 38,139,140,140, 68,110,110,110,209,223, 65, 65, 65,184,117,235,150,236, +203, 68, 67,228, 30,113,145,154,154,234,201, 64, 20, 21,105,138,162,136,179,103,207,250,157, 1,112, 56, 28, 95,204,157, 59,247, +149, 69,139, 22,169, 24, 99,144,101, 25, 74,165, 18,178, 44, 99,198,140, 25, 6,171,213,250,133,207, 98,191,167,168,197,126,175, + 48,198,170,208, 61, 78,200, 52,126,252,248, 71,242,243,243,167, 55,109,218, 84, 89,177, 98, 69,108,222,188, 25,217,217,217, 80, + 40, 20,102,157, 78,183,192,225,112,220, 83, 87,232,240,225,195,245,113,113,113,154,183,223,126, 27, 99,198,140,185, 86, 80, 80, + 80,239, 94,244, 0,180, 2, 96, 7,112, 16, 64,125, 95,238,203,255, 95,248,221, 47,152,136, 84, 0,218,193,213,130, 30, 86,212, +105,231,134,185,174,222,137, 0,150, 17,209,127, 0,236, 99,140, 25,203, 56, 71, 51,184,134,153,248,194, 47,240, 45,138,171, 10, +224,170,151, 99,174,185,143,243, 10, 17, 85, 5,240, 33, 92, 45,224, 78,158, 76, 5, 99, 44,143,136, 30,134,171, 70,161, 29,128, +209,140,177,211, 62,232,117, 7,240, 62,128,135, 25, 99, 23,139,191,198, 24,187, 64, 68,143, 2,216, 74, 68,249,140,177,125, 94, +228,226,253,185, 24,125, 40,154,106, 10,224,138,187, 59,167,172,192, 98, 37,128, 37, 68,180,209, 61,244,168, 68, 24, 99,171,136, +232,105, 0,179,136,104, 10, 99,236, 91, 0,223,222,101,211, 43,112,205, 17,240,161, 55,251,109, 78,231, 7,251,146,175, 61,243, +222,166,163,117, 94,126,184, 26,247, 66,215,122,120,161,103, 51, 64, 84, 2,162, 18,140,151,241,234,138,189,142,107,183, 11,143, + 51,198,188, 14, 5,116,233, 93,127,230,221, 31,228, 58,227, 59,198,113,131,219,198, 97,112,175, 78, 26,104,162, 0,167, 3,236, +210, 47,152,186,250,128, 35, 61, 71,119, 26,128, 79,243, 32,120, 82,254, 47,191,252,242, 29, 5,122,175,189,246,154, 95, 78,161, + 56,162, 40,226,250,232,182, 69, 69,132,162, 40,162,133,217, 92,110, 61, 15, 54,155,205,162,211,233, 28, 61,123,246,228, 87,173, + 90,229,176,219,237,229,117, 20, 63,238,223,191,191, 65,175, 94,189, 80,189,122,117, 46, 55, 55, 23, 0,160,209,104, 4, 79, 0, + 16, 20, 20,164,128, 43, 0,240, 74,177,161,126,187, 1,192,147, 1,112,255,126,189, 58,255,146,232,223,191,191,117,230,204,153, +172, 75,151, 46, 78, 65, 16,238, 72,193,248,251, 61,138,162,136,156,156, 28,156, 62,125, 26, 53,107,214,132, 74,165,130,201,100, + 66,106,106,106, 81, 77,128, 63,154,102,179,121,238,158, 61,123, 30,125,234,169,167,234, 76,154, 52, 73, 93,191,126,125,156, 61, +123, 22,211,167, 79, 55, 36, 37, 37,165, 26,141,198,185,126, 25,232,150, 5, 96, 34,162, 96, 0, 10, 0, 39,203,161,113, 95,121, +230,153,103,106, 23, 22, 22,174,169, 92,185,178,210,100, 50, 97,217,178,101,216,178,101, 11, 24, 99,118,187,221,158,193, 24,187, + 39,231,175,211,233,148, 71,143, 30,253,197,104, 52, 86,124,251,237,183,235,245,239,223,191, 46, 17, 61,232,233,166, 46, 7, 74, + 0,121,112, 13,133,102, 0, 10,136, 40,146, 49,118,235, 94,236,252,167, 80,210, 47,248, 69,184,170,181,159,101,140,237, 44,233, + 77,140,177,157, 68,244, 44, 92, 93, 1, 50, 92, 78,165, 52, 8,174,244,176, 47,156, 0,176,206,135,227,150, 1, 40,213, 41,185, +185, 1, 87,191,182, 47,172,131,171, 53,252, 62, 99,236,142,217, 86, 24, 99,185,238, 62,195, 17, 0,214, 17, 81, 19, 31, 10,109, +102, 3,120,130, 49,118,170,164, 23, 25, 99,199,200, 53,228,108, 54, 92,193, 86, 89,164,250,244, 9,124, 63,254, 99,184, 42,242, +203,196,253, 63, 94, 6, 96, 3,188, 23,219, 13, 7,240, 21,128,157,238, 44,206, 17,184,250,252, 19, 1,188, 4, 32, 26,174, 98, + 34,175, 5, 63,238,236, 67,207,153,223,156,222,250,195,137,155,149, 38, 61,222, 68,157, 88,171, 34, 28,118,224, 72,202, 13,204, + 94,243,179, 62, 37, 61,251, 66,161,193,210,223,155, 86,113,189, 89, 91, 46,109,253, 49,229,118,165, 73,143, 88,213,137,213, 77, +112,112,151,112, 36,189, 16,179,191, 61,161, 79,185,118,251, 66,161,209,218,231,238, 96,183, 52,174, 92,185, 2,165, 82, 9,158, +231,139, 38,137,113, 58,157, 69, 99,249,253, 37, 35, 35,163,104, 34,156,178,244, 60, 78,210, 79, 46, 94,188,120,241,129,149, 43, + 87,170,175, 92,185, 98, 6,112,209,235, 59, 74,102,107, 90, 90,218, 40, 0, 42,173, 86,235,200,200,200,112, 2, 16,237,118,187, +227,198,141, 27, 78, 0, 34, 99,140,131,203, 17,249,132, 59, 8, 64,106,106, 42,172, 86, 43,142, 30, 61,138,196,196, 68,148,199, +249, 3,192,216,177, 99,165,200,200, 72, 8,130,192,229,231,223, 57,175,139,159, 67,246,138,106, 58, 10, 10, 10,112,226,196,137, +162, 22,191,167,250,223,223, 12, 0, 99,204, 78, 68, 15, 30, 57,114,100,202,224,193,131,135, 27, 12,134,138, 26,141,230,186,213, +106,253,194,104, 52,206,189,251,190,227,163,166,153, 92, 67, 56,175,220,135,212,255, 61,211,167, 79,159,150,249,249,249, 59,242, +242,242, 84, 23, 46, 92,192,181,107,215, 80, 88, 88,104,115, 7,157, 71,224, 61,179,235, 21,142,227, 86,101,102,102,190, 14,224, +201,213,171, 87, 47,252,239,127,255,139,165, 75,151,142, 4, 80,222, 0, 32, 11,174, 34,232, 26,238, 45, 21,174,122,173,127, 69, + 0, 64, 62,222,243, 2, 4, 40, 19,114, 77,247, 59, 10, 64, 95, 0,141,224, 42,208, 59, 5, 96, 19,128,119,253,189,193, 17,145, + 32, 75,194, 36,149,196, 15,212,155,237, 53,137,192,212,178,226,156,193,106, 91,102,177,216, 62, 96,174,161,133,229,208,227,220, +122,196,212, 10,233,156,193, 98, 95,102,177,249,174, 23, 20, 20,116,212,104, 52,150,186, 22,192,221, 40, 20,138,155, 6,131,161, +212, 76,139, 70,163, 57,239,207,244,190, 74,165,242,178, 78,167,243,121, 45, 0, 34,138, 81,169, 84, 75,162,163,163, 19, 51, 51, + 51,143,154, 76,166,103,189,117,199,149,162, 19, 77, 68,199, 58,118,236,168,248,233,167,159, 76, 68,132,182,109,219, 42,247,237, +219,103, 34, 34,180,107,215, 78,185,119,239, 94, 19,128,154,254, 86,162, 19, 17, 59,114,228, 8,154, 55,111, 94,102,159,127, 89, +239, 47, 44, 44,196,254,253,251,139, 82,235, 74,165,178,168,128,112,230,204,153,108,242,228,201, 80, 40, 20, 94,245,137,136,125, +251,237,183,176,219,237,119, 56,125,207,198,243,252, 29,127, 55,107,214,172, 92, 54,223, 47,220, 69,203, 27, 25, 99,157,238,163, +230, 33,198,216, 3,254,190,175, 89,179,102,155, 11, 11, 11,187, 20, 20, 20,152, 11, 11, 11, 77, 22,139,229, 28, 92,221, 81,187, + 25, 99,191,222, 47,251,220, 54,134, 52,110,220, 56,243,240,225,195,138,216,216,216,179, 57, 57, 57,165,206,101,225,163,158, 4, +160, 59, 92,247,171, 71,124,236,222,254,199, 19, 8, 0, 2,220,119, 60,165,222,190,182,168,255,233,122,255, 22,136, 40, 20,174, + 22,190,167,195, 94,186,251, 57, 99, 44,183,156,218,229,238,119,150, 36, 41,211,102,179, 69,223,189, 95,150,229, 44,147,201, 20, +147,152,152,152, 99,181, 90,195,211,210,210,178,140, 70, 99,140, 55, 59,252, 61,255, 95, 28, 0, 40, 0, 60,199, 24,123,255, 62, +106, 78,100,140,121,205, 18,254,213, 16, 81,239,160,160,160, 73,133,133,133,243, 25, 99,254,204,108, 89,154, 94, 45,184,186,141, + 47, 49, 31,167,201,254,167, 19, 8, 0, 2, 4, 8, 16,224, 31,138, 59,152,141,241, 20, 26,223, 39, 77,173,187,248, 51,192,255, +115, 2, 1, 64,128, 0, 1, 2, 4, 8,240, 47,228, 31,191, 24, 80,128, 0, 1, 2, 4, 8, 16,192,127, 2, 1, 64,128, 0, 1, + 2, 4, 8,240, 47, 36, 16, 0, 4, 8, 16, 32, 64,128, 0,255, 66, 2, 1, 64,128, 0, 1, 2, 4, 8,240, 47,228,222,166, 25, +243, 19,149, 74,149,105, 50,153,126, 55, 92,167, 56, 74,165,210,235, 80,157,251,137,123, 24,141,210,235,129,191, 97, 97,140,153, +254, 40,123,254,209,188,221, 85,128,202, 44,131,231, 21,112,130,192,129,193,225,176,192, 40,155, 49, 97,155,255, 51,228, 4, 8, +112, 15,184,231,166,168,200,113, 92,173, 26, 53,106, 84, 74, 75, 75, 59,239,112, 56,126,249,171,237, 10,240,247,133,136,132,242, + 76,202,244, 79,197,167, 81, 0,117,195,168,126,155,122,241, 35, 79, 95,202,222,119,240,166,233,155,242,142,159,166, 98,203,129, +150,113,204,159, 58,174, 86,150,229,243, 74,165, 50, 62, 40, 40,168,204,227,136, 8, 89, 89, 89,204,225,112,216,108, 54, 91,148, + 47, 65, 0, 17, 53,227, 56,238,225,144,144,144,135,156, 78,103, 13, 34, 58,157,151,151,247, 19,128,173,229, 29,103, 74, 68, 53, + 0, 60, 5,215, 66, 71,128,107, 25,223, 85,140,177,180,242,232,221, 51, 51, 59,114,136,132, 6,140,100,152, 10,148, 78, 99,182, +150, 51,235,131,156, 78,135,196,113,188,213, 41,107, 10, 57, 85,148, 14,202, 96, 19,136,153,161,130, 1,195,118,151,107, 9,208, +255,239,184,135,116,197, 73,146,148,224,112, 56,226,120,158,191, 97,181, 90,207,150, 53, 21,243,159,141,219,198, 96,158,231, 35, + 1, 48,135,195,145,195, 92,171,168,253,173, 32,162,232, 10, 21, 42,116,233,211,167,143,178,247, 19, 79, 32, 46, 46, 14,207, 61, +255, 60,126,250,233,167,207,203,186,193, 19, 17,215,164, 73,147,174,199,143, 31,175, 84,218, 49,178, 44,155, 76, 38,211,151,126, +218,195,213,171, 87,175, 75,211,166, 77, 43,127,249,101,233,111,149,101,217,108, 54,155, 87,250, 59,209, 85,177,243,200,112, 45, +227,155,233,235,132, 76,247, 58,247,255, 93, 90, 97,112,173,251,193, 1,120,199, 61,147,234,247, 0,122,184, 15,217,194, 24,235, +121,143,231, 8, 10, 14, 14, 30, 95,187,118,237,222, 10,133,162,226,245,235,215,175,223,184,113,227,176,213,106,157,123,247,212, +235, 62,234,133,132,134,134,206,126,232,161,135,186, 71, 71, 71, 87, 57,114,228, 72,214,233,211,167,127, 53,155,205, 51,125,153, +250,253,159,140, 79, 1,192,208, 86,149,222, 95, 54,241,137, 23,179,110,231,223,122,117,233,206,175,127, 62,159, 49, 55,110,166, +184, 0, 0, 32, 0, 73, 68, 65, 84,249, 98, 46, 43,240,251,100,238, 0,128,173, 30, 10, 88, 13,119,110, 22, 3,104,242,217, 63, + 61, 0,144, 36,169, 32, 43, 43, 43, 72,169,252, 45, 9, 64,197,150, 44, 45,254,120,238,220, 57, 36, 38, 38, 90, 44, 22, 75, 76, + 89, 55, 61, 34, 82,105,181,218,247, 37, 73, 26, 52,120,240, 96,177, 89,179,102, 98,213,170, 85,113,238,220, 57, 28, 62,124,216, +178,122,245,106,167,221,110,159, 99, 54,155,231,249,114,161, 19, 81, 52, 92, 11, 27, 13,170, 88,177, 98,139,129, 3, 7, 98,240, +224,193, 32, 34,172, 92,185, 18,171, 87,175,198,245,235,215, 15, 3, 88, 13, 96, 45, 99, 44,171, 44, 61,158,231,159,118, 58,157, + 62,101, 61, 4, 65, 48,217,108,182,146,239, 88,111,119, 21,160,182,134, 33,231,124, 12,204,186, 80,230,176,203,103,115,157,194, +103, 39, 29,170, 3, 55,156,242,131, 21, 56,243, 51,141,120, 99, 66, 24,103, 39, 94, 48, 59, 37, 85, 1, 23, 81,237, 22,148, 92, + 54, 70,236,183,149, 36, 73, 68, 45,241, 91, 70,198, 2, 32, 27,174, 41, 58,163,225,154,182, 51, 13, 64, 20,126,155,114,214,196, + 24, 59,232,203,103,113,235, 15, 2,160,113,255,169,103,140,173,246,245,189, 94,116, 43,132,134,134, 62,168,215,235, 67,180, 90, +109, 94, 65, 65,193, 49,187,221,126,217,199,247,134, 8,130, 80, 27, 64, 77,133, 66,225,236,210,165,203,205, 1, 3, 6,228,174, + 89,179, 38,108,231,206,157,113, 22,139,133, 3,112,222,110,183,159, 99,204,247,235,206,221, 2, 78,132,107,114, 19, 45,128, 66, + 0,151, 0, 28, 43,143,131,145, 36, 41, 65, 16,132,230,161,161,161,136,139,139,147,156, 78, 39, 50, 51, 51,173,121,121,121,176, +219,237, 71,172, 86,235, 89,111, 26, 10,133,162,175,211,233,244,124,255, 69,215,214, 93,118, 23, 61,231, 56, 78,111, 50,153,190, +246,199, 78, 34,226,226,227,227,159,250,113,235, 86,165, 66,161,192,175,191,254,138,111,191,251, 14, 27, 55,110, 76,182,219,237, +165,102, 0,136,136,107,216,176, 97,215,237,219,183, 87,140,137,137,161, 95,127,253,181,104,173, 7,207,250, 12,146, 36,161, 82, +165, 74, 96,140, 45,246,199,158,218,181,107,119,217,185,115,103,165, 47,190,248,130, 30,126,248, 97, 68, 69, 69, 33, 56, 56, 24, + 90,173, 22, 10,197,111,179, 39, 75,146,196,108, 54,219,231,190, 76,155,125,215, 57,148, 0,166, 7, 7, 7,255,183, 69,139, 22, + 33,167, 79,159, 46,204,204,204, 92, 12, 96, 6, 99,204, 80,198,251, 88,243,230,205,173,255,199,222,153,135, 53,117,109,125,248, +183, 79,230, 16,194, 60, 35, 40, 42,136, 32, 2,214,171, 84,173,162,173, 67,157,106, 29,107,181,218, 58, 92, 91,135, 42, 14,180, +106, 7,180,214,177,104,171,182,189,106,235, 80,253,234,112,109, 45,213,106,213,138, 56, 64,157, 16, 17, 21, 84, 4,100,146, 25, + 2, 33,211, 57,217,223, 31,129, 20, 21,146,128, 94,219,222,155,247,121,242,144,156,156,172,236, 29,206,217,107,237,181,215, 94, + 43, 37, 37,101,167, 78,167,155,209, 82,195,163,129,188,143, 39, 77,154,244,145,147,147, 19, 98, 99, 99, 83, 96, 40,180, 83, 91, + 93,109, 72, 43, 96,107,107, 11, 24,174,197, 33, 48, 76, 98,122, 3, 56, 5, 96, 42,165, 84, 97,129,252, 23,194,195,195,119, 69, + 69, 69,221, 13, 8, 8, 56, 26, 22, 22,118,171,168,168,200, 59, 41, 41, 41,252,173,183,222,234,163, 80, 40,214, 80, 74,191,109, + 70,123, 35, 95,125,245,213, 3,171, 87,175,118,210,233,116,144, 72, 36,176,177,177,129, 82,169,196,240,225,195,181,169,169,169, +179, 40,165, 91,155,255, 75,252, 61,104,212, 0,104,211,134,136, 37, 85,104, 71, 13,121,252, 65, 40,194, 22,191,214,115,209,248, + 23, 2, 2, 57, 86,171, 91,255,211,149, 11, 59,126,187, 57,243,102, 57, 77,107,214,151,213, 27, 0,187,198, 66, 50,197,112, 79, +171,214,116, 49, 26, 1,228,131,236,103,110, 0,136, 68,162, 42,133, 66, 33,255,249,231,159, 65, 41,125,168, 24, 75, 99,127,195, +194,194, 76, 26, 0,132, 16,185, 76, 38, 75, 29, 62,124,184,203,230,205,155,165,118,118,118,143,157,115,231,206, 29, 76,157, 58, +181, 38, 37, 37, 37, 85,161, 80,244, 50,117,211, 17, 66, 46,203,229,242,240,145, 35, 71,146, 9, 19, 38,160, 79,159, 62,143,149, +154,213,235,245, 56,125,250, 52,118,239,222,141,131, 7, 15, 82,133, 66,113,149, 82,218,197,132,204,233,123,247,238,133, 72, 36, +130, 70,163,129, 78,167,131, 78,167, 3,203,178,224, 56, 14, 44,203, 66,175,215,131,227, 56,204,159, 63, 31,122,189,190,241,193, +238,235,222,206,200, 79,107,123,175, 68,233,244,175, 20,206,230,183, 66,177,180, 85, 88, 63,209,224, 33, 67, 16, 17, 17,129,164, +164, 36, 28, 57,124, 24,185, 87,127,211, 68,122,168,107,167,135,242,148,237,221,108,139,225, 21,124, 23,211,227,155,250,253, 6, + 22, 20, 20,184,171,213,106,126,187,118,237,200,160, 65,131,200,176, 97,195,208,163, 71, 15,156, 63,127, 30,113,113,113, 56,122, +244, 40,189,123,247, 46, 21,139,197,172,167,167,231, 3, 74,233,177,166,250,218, 88,223,235,175,249, 58, 69,179,215,146,129,199, + 20, 66,161,176,131, 92, 46,127,126,251,246,237,252,174, 93,187,226,226,197,139,152, 52,105, 18, 91, 93, 93,125,146,101, 89,147, + 69,171, 4, 2,193, 8,134, 97,108,187,116,233, 82, 52, 99,198,140, 7, 42,149,138,196,199,199,203,203,203,203,133,142,142,142, +218,200,200, 72,133, 80, 40,164, 91,182,108,241, 72, 78, 78,118,211,235,245,149, 58,157,238, 39, 11,250,201, 0,120, 5,128,190, +119,239,222,133, 65, 65, 65,218,173, 91,183,106,117, 58,157, 31, 0, 30,128, 56, 75, 7,123, 66, 8, 35,145, 72, 94,238,208,161, +131,115,116,116,180, 48, 56, 56, 24, 2,129, 0, 55,110,220, 64,102,102, 38,174, 95,191,142,196,196, 68,109,126,126,126,169, 74, +165,250,197,204,245, 60,189,176,176, 16, 78, 78, 78,208,106,181, 80,171,213,208,104, 52,208,106,181,198, 71,253,181,120,233,210, + 37,204,156, 57,179, 89,202,182,238, 59, 28,167, 76,153, 50,106, 89, 76, 12,250, 15, 24, 64,111,220,184,113, 13,192,109,115,158, +138,206,157, 59, 15, 56,113,226, 68, 43, 87, 87, 87,134, 16,130,203,151, 47, 63,116,239,215, 63,119,119,119,111, 86,155, 2, 3, + 3,251,159, 56,113,194,199,219,219,155, 89,190,124, 57,164, 82, 41,156,157,157,225,232,232, 8,153, 76, 6,129, 64, 0,189, 94, +143,158, 61,123, 66, 44, 22, 55,203, 0,168,155,113,251, 19, 66, 86,143, 31, 63,254,133, 33, 67,134,192,217,217, 25, 14, 14, 14, +184,124,249, 50,102,207,158,125, 78,167,211, 13,108,204, 8, 32,132,208, 54,109,218,232, 46, 93,186, 36, 56,117,234, 20, 38, 76, +152,240,179, 86,171,125,229, 73,140, 0, 66,200,215,203,151, 47,255,231,210,165, 75, 49,121,242,100,236,220,185,115, 31,128,177, + 13, 13, 0,145, 72,164,138,140,140,148, 12, 29, 58, 20,125,250,244,193,252,249,243,113,236,216,177, 87,205,101,243, 35,132,140, +232,219,183,239,231,235,214,173,251, 62, 44, 44,236,115, 60, 92, 15,134,212,165, 69, 78,130,161,238,136,217, 26, 42,132,144, 17, +179,102,205,250,247,204,153, 51,153,107,215,174,129, 16, 2, 39, 39, 39,227,131,199,227,161,123,247,238,108,110,110,110,151,166, +234,186,252,221,105, 52, 6,160,111, 43,223, 13,239, 45,234, 61,152, 15,189, 30, 84, 15,232, 57, 64,207, 66,171,213,212,136, 24, + 42, 95, 56,180,211, 11,225,190,118, 63, 60,239, 37,122, 63, 49, 95,115,176,217,223,202,106,160, 97,245,198,231,198, 71, 11, 32, +132,248,193, 80,222,118,124,221,161,255, 3,176,147, 82,122,175, 25, 50,140,133, 61, 76, 41,127, 75,234,178,203,229,242,173, 19, + 38, 76,112,219,188,121,179,184,177,247,107,106,106, 96, 99, 99,131,173, 91,183,202,166, 79,159,222,249,194,133, 11,239, 3, 88, + 97, 66,100,151,109,219,182, 33, 52, 52, 20,237,219,183,111,244, 4,134, 97,208,183,111, 95,120,122,122,162, 99,199,142,100,225, +194,133,166,138, 51, 25,251,169, 82,169, 16, 20, 20,132,211,167, 79, 35, 53, 53,213, 88,242, 84, 36, 18, 25,159,155,244, 16,113, +124, 1,213,170,237,159,255, 78,235, 62,239,195,149,252, 19,211,167,195,193,193,193,248,118, 80, 80, 16,166, 78,157,138,138,138, + 10,209,202,149, 43, 69, 61, 55,175,179,125, 48,187,150, 37, 28,175,209,223,166, 30, 15, 15, 15, 33, 0,188,244,210, 75, 56,124, +248,143, 10,194, 65, 65, 65,152, 62,125, 58, 6, 14, 28, 72,218,180,105, 67, 96, 72, 63,219,108, 40,165,122,142,227, 8, 12, 6, +238,112, 66, 72, 25,128,196,230,186,178, 9, 33,158,124, 62,223, 71, 34,145,116,252,253,247,223,249,109,219,182, 5, 0, 12, 29, + 58, 20, 91,183,110,229,207,152, 49,163, 11,204, 84,173,100, 89,214,101,220,184,113,215, 53, 26, 13,245,246,246,214, 29, 56,112, +192, 94, 32, 16,208,193,131, 7,151, 95,184,112, 65,150,146,146, 34, 29, 57,114,100,165, 84, 42,173,242,243,243, 83,164,167,167, +119,180,176,121,207, 1,160, 85, 85, 85,182,132, 16,187,248,248,248,252,224,224,224,202,143, 62,250,232, 82, 73, 73, 73, 87, 0, +161, 0,146, 45, 17, 36, 18,137,186,247,237,219,215,109,221,186,117,188,246,237,219,131,199,227, 33, 63, 63, 31, 0,224,234,234, +138,208,208, 80, 8, 4, 2,225,213,171, 87, 93,111,220,184,209, 13,102, 10,179,184,185,185, 97,249,242,229,198,194, 58, 2,129, + 0,197,197,197,216,185,115, 39, 42, 43, 43,209,191,127,127,140, 25, 51, 6, 46, 46, 46, 22,118,245, 49,106,110,223,190,173,103, + 24,134,233,215,175, 31,185,113,227, 70,165, 37,255,219,212,212, 84, 95, 55, 55, 67,136,146,135,135,135,177,109,245,247,126,253, +243,230,210,179,103,207,214,187,119,239, 6, 0, 92,187,118, 13,115,231,206,133, 84, 42, 5, 0,232,116, 58,163, 17,222, 28, 8, + 33, 78, 0, 62,107,215,174,221,107,189,123,247, 22, 10, 4, 2,120,121,121,225,220,185,115, 72, 75, 75,195,168, 81,163, 48,102, +204, 24,232,245,250,158,239,188,243,206,135, 0,162, 31,149, 65, 41, 37, 60, 30,111,207,252,249,243,199,175, 90,181, 10,187,119, +239, 30, 58,126,252,120,174, 49,175,140, 72, 36, 42, 82,171,213,150,196,102,173,140,137,137, 25,213,171, 87, 47,167,175,191,254, + 26, 42,149,106,108,113,113, 49,134, 12, 25, 2,123,123,123,108,217,178, 5,253,251,247,151, 72,165, 82,148,151,151,227,216,177, + 99,184,122,245,170, 22,134,226,109,166,250, 59,122,200,144, 33,177,235,214,173,219, 24, 16, 16,240, 21, 33, 68, 15, 67, 97,179, + 1, 0,206, 0,136,161,148,102, 19, 66, 22, 0,136, 1, 96,178, 88, 24, 33,100,244,186, 89,179,246,245, 28, 61,154,196,197,197, +129,207,231, 35, 62, 62, 30,215,174, 93, 67,187,118,237,176,124,249,114, 4, 7, 7, 99,198,140, 25,252, 37, 75,150,172, 3,208, +223,130,190,255,237,104,212, 0,224, 1, 58, 78,167,213,243,121, 0, 15,148,215,202, 89,234, 5, 61, 11,112, 44,192,151, 2,170, + 10,244, 11,116,105,239,248,230,115,159, 5,187,145, 7,105, 69,212,100, 96, 77,157,101, 54,202,120,128,213,160, 54,182,135, 97, +230,207,170,192, 44,205,132,126,177,229,197,172,234,228,141, 6, 48,217,201,201,169, 87, 80, 80, 16,121,240,224, 1,246,239,223, +143, 29, 59,118,124,184,103,207,158, 15, 8, 33,103, 97,168, 26,120,128, 82, 90, 99, 78,166, 64, 32, 48, 86, 1,107, 74,249,215, +159, 99,162, 93, 3, 60, 61, 61,135,172, 93,187,182, 81, 5, 87, 93, 93,141,234,234,106,212,212,212, 64,161, 80, 96,222,188,121, + 54, 19, 39, 78, 92, 66, 8,217,111, 42, 38,192,215,215, 23,229,229,229,248,233,167,159,224,229,229,133,231,158,123,238,161,247, + 19, 19, 19,113,234,212, 41, 40,149, 74,139,140, 20, 0, 80,171,213, 8, 10, 10, 66, 72, 72, 8, 50, 50, 50,144,145,145,241,152, +242, 55, 59,216, 49, 20, 32, 20,142, 18,112,145,145,145,252,212,212, 84, 84, 84, 84, 32, 48, 48, 16, 1, 1, 1,184,121,243, 38, + 78,156, 56,129,130,130, 2,136, 68, 34, 56, 73,192, 1,148, 0,122, 83, 30, 30,173, 84, 42, 69,100,100, 36, 88,150, 69, 92, 92, + 28, 66, 67, 67,225,227,227,131,156,156, 28,252,242,203, 47,200,205,205, 69,120,120, 56,210,211,211,129, 63,114,209, 91, 74, 13, +195, 48,198, 37, 0, 24,170, 64,118, 4, 48,148, 16,242,163,185,107,133, 16, 66,132, 66, 97,168, 80, 40, 12,110,215,174, 29,127, +212,168, 81,188, 9, 19, 38, 48,245,202,191,158,206,157, 59, 67,173, 86, 63,238,254,105,132, 13, 27, 54,148,168,213,106, 12, 30, + 60,216,223,221,221,189,122,218,180,105, 21, 99,199,142, 85,239,217,179, 71, 27, 27, 27,235,176,127,255,254,214,125,251,246,189, +237,232,232,200,212,245,217, 18,218, 68, 68, 68,228, 18, 66,228, 42,149,138,102,100,100,168,243,242,242,212,117, 75, 93, 55, 96, +168,224,105,214, 0, 32,132, 56, 58, 57, 57,181, 91,184,112, 33,175,117,235,214,208,233,116, 72, 72, 72, 64, 85, 85,149,241,122, +214,104, 52,176,183,183, 71,199,142, 29,249, 89, 89, 89,237, 9, 33, 25,166,106, 2,104, 52, 26,176, 44,139,221,187,119, 35, 34, + 34, 2, 93,186,116,193,169, 83,167, 80, 80, 96,152,208,197,197,197, 97,204,152, 49, 45, 82,182, 0, 64, 41,213, 18, 66,210, 78, +158, 60, 25, 18, 53,111, 30, 82, 83, 83, 95, 32,132,168, 40,165,185,230, 62,123,254,252,249,135,220,254,129,129,129,184,127,255, +254, 67, 30,128,230,178,125,251,118,253,233,211,167,153,115,231,206, 97,238,220,185, 16,139, 13,195, 67, 84, 84, 20, 18, 18, 18, + 16, 30, 30,142,101,203,150, 89, 44,143, 16,226, 34,149, 74, 79,237,218,181, 43,248,213, 87, 95,173,239, 51,142, 31, 63,142,225, +195,135,215,104,181,218,233,231,206,157,155,109, 99, 99, 19, 49,109,218, 52,172, 92,185,242,159,132,144,143, 26,139, 9,208,235, +245, 19,119,237,218, 53,158, 97, 24,196,196,196,224,192,129, 3, 80, 40, 20,240,244,244,132, 86,171,133, 94,175,135, 72, 36, 66, +255,254,253,221,234,235, 36,212,215, 88,104,172,109,148,210, 28, 66,200,216,209,163, 71,255,122,229,202, 21,222,247,223,127,111, +172,106,201,178, 44, 42, 43, 43,113,248,240, 97, 28, 58,116, 8, 9, 9, 9, 42,173, 86,123, 20,134, 98, 97, 23, 77,244,247,181, + 49, 99,198,172, 27, 56,112,160,236,171,175,190,146,127,254,249,231, 66, 0,191, 2, 56, 1,195,117,220, 15,192, 6, 24, 60, 94, +191, 1,136, 53,243,251,189,246, 99, 84,212,158,142,129,129,100,211,168, 81, 32,253,250,225,224,217,179,250,252,252,252, 79, 0, +108,202,205,205, 29, 30, 29, 29,189,245,208,161, 67,232,209,163, 7,108,108,108, 34,136, 37, 1,108,127, 67, 26, 53, 0,182,158, +205,153,123,254,122,206,183, 62,110,242,185, 95,189,221,239, 37,112,124,168,108,219,212,168, 66, 39,192,201, 39, 64, 86,154,147, + 94, 35,189,188, 21, 97,222, 42,223,249,253,218,126,209,166, 13,233,145,149,213,120,192, 9, 33,100, 31,159,207, 31, 21, 30, 30, +206, 92,188, 88,247, 63,102,213, 16, 67, 11, 64, 11,176,117, 31,107,224, 1, 32,132, 28,161,148, 14,126, 92,218,195,242, 0, 32, + 57, 57, 25,103,206,156, 1, 96, 24,116,215,175, 95,143, 53,107,214,144, 95,126,249,229,133, 29, 59,118,188,112,228,200,145, 45, +132,144,227, 77,201,171,167,126,176,105,168,236, 31,125,152, 27,144,236,236,236,198,189,255,254,251,210,122,235,190, 33,245,138, +191,186,186, 26, 10,133, 2, 74,165, 18,132, 16, 12, 27, 54,140,191,103,207,158, 65, 0, 76, 6, 5, 18, 66,224,225,225, 1,189, + 94,143, 35, 71,142, 64, 42,149,162,166,166, 6,167, 79,159,134, 90,173,182, 76, 97, 55, 64,163,209, 32, 33, 33, 1, 25, 25, 25, +168,170,170,130, 88, 44,110,212, 3, 96, 9, 34, 62, 40, 0, 99, 21,182,170,170, 42,196,196,196, 32, 55, 55, 23, 18,137,196, 56, +224,213,159,103,134, 51, 42,149,170, 93, 84, 84,148,177, 13, 5, 5, 5,216,181,107,151,177, 12,111,255,254,253,193,231,243,113, +245,234, 85,192, 96,253, 91, 76, 19,107,254,105,132, 16, 62,128,238, 0, 26, 45,129,221, 0,159, 54,109,218,132,237,222,189,155, +223,165,203,227,171, 44,153,153,153,200,204,204,196,143, 63,254, 8,145, 72,100,113, 97, 28,177, 88,140,240,240,240,202,181,107, +215, 22,175, 94,189,218,254,227,143, 63,118,101, 24, 70,225,239,239, 95, 88, 81, 81,193, 49, 12,211,220, 89,162,173,159,159,159, +250,232,209,163,121,119,239,222,213,100,102,102, 86, 39, 38, 38, 42,238,223,191,175,133,161,142,188, 69,198,137, 68, 34,233, 48, +116,232, 80,177,139,139, 11, 68, 34, 17,146,147,147, 31, 82,254, 13,141, 0,134, 97, 16, 26, 26, 42, 78, 76, 76,244, 7,208,100, + 92,134, 90,173,134, 74,165,194,157, 59,119,224,236,236,140,136,136, 8,248,251,251,227,194,133, 11, 0,128,158, 61,123, 66, 42, +149, 54, 75,217, 18, 66, 92,229,114,121,119,141, 70, 83,169, 86,171,207, 0,184, 50,231,221,119, 91,237,219,187,215, 97,235,150, + 45,204,192, 65,131,250, 18, 66, 14, 80, 74,107, 77,201,105,168,232, 3, 3, 3,141,199,158,196, 3, 0, 24, 92,223,182,182,182, + 16, 8, 4,168,255, 95, 38, 38, 26, 10,228, 37, 39, 39,163,182,182, 22, 28,103,222,235, 79, 8,113,148, 74,165,167, 14, 30, 60, + 24, 60, 96,192, 0,163,215,164,109,219,182,232,212,169, 19,162,163,163,101,203,151, 47,239,205,113,220,234, 67,135, 14, 29,154, + 60,121, 50,254,241,143,127,216,229,230,230,186, 3,200,126, 84, 30,165, 84, 79, 8,193,240,225,195,177,120,241, 98,196,196,196, + 96,211,166, 77, 16, 8, 4,144, 72, 36,120,229,232, 8,156,157,112, 6,173, 91,183,198,145, 35, 71, 96, 99, 99,131,214,173, 91, +155,220,201, 69, 41,253,141, 16,242,118, 72, 72, 72,108, 72, 72,136,140, 82,138,224,224, 96, 44, 95,190, 28,227,199,143,199,249, +243,231,127, 5,176, 29,134,128, 64,147, 6, 55,143,199,123, 99,220,184,113,159,190,240,194, 11,178, 75,151, 46,201, 89,150,157, + 42,145, 72,134,171, 84,170,117,148,210,157,117,191,201,207, 0, 54, 18, 66,132,117,198, 31,211,148,194, 22, 10,133,111, 28,154, + 63,127,199,243, 46, 46,164,100,209, 34, 68,232,245,216, 24, 23, 71,243,107,107,167, 80, 74,119,212,201,219,113,243,230,205,175, + 88,150,229,203,100, 50,120,121,121,201,110,223,190,237, 6,160,217, 85, 52,255,234, 52,154, 7,160,157, 12,142,253,194,124,163, + 15, 68,191, 60,220,215, 73,236, 1, 78, 7, 85,232, 4,236, 76,202,151,121,189,186, 4,187,126, 47,144,169,158,155, 6,112, 58, + 68,250,219,187, 74, 42, 96,202, 45, 57,186,119,239,222, 76, 70, 70,198, 31, 71,116, 26, 48, 81,151, 16,115,188, 16, 96, 53,208, +191,103, 11,189, 78,141,163, 71,143,162, 79,159, 62, 32,132,188,108,137,188,139, 23, 47, 54, 90,127, 93, 32, 16, 96,232,208,161, +152, 62,125, 58,162,162,162,248,102,228, 25,151, 0, 30, 85,246,205, 93, 2, 96, 24,166,103, 88, 88,216, 99,199, 21, 10,133, 81, +241, 43, 20, 10,163, 7, 64,161, 80,160, 85,171, 86, 2, 7, 7,135,190, 38, 5, 63,130,139,139, 11,108,108,108,240,239,127,255, + 27, 10, 69,203,150,175,181, 90, 45,174, 95,191,142, 51,103,206, 32, 61, 61, 29, 66,161, 16,197,197,197,184,119,239, 30, 82, 82, + 82,192,178,172,197, 6, 64, 99, 52,246,127,177,132,250, 8,237,134,193, 81, 12,195, 64,163,249,195, 64,228,243,249, 70,163,226, + 41,110,217,185, 11,192,195,220, 73, 14, 14, 14, 97, 49, 49, 49,143, 41,127,189, 94,143,210,210, 82,100,101,101, 33, 53, 53, 21, +199,142, 29,211,151,151,151,103, 52, 33,230, 33, 22, 46, 92,232, 90, 91, 91,107,244,138, 68, 71, 71, 87, 58, 59, 59,215,180,110, +221,218,232,182,230, 56,142, 92,187,118,205,213,242,238,160,122,223,190,125,108,118,118,118,229,189,123,247,202,143, 31, 63, 94, +158,158,158, 94, 11,131,199,196, 6,128, 69,193,132,132, 16,247,128,128, 0, 84, 87, 87, 35, 33, 33, 1,247,239,223, 55, 94,207, +245,143,250,107,154, 82, 90,191,118,106,210, 85,172,209,104,224,225,225,129, 5, 11, 22, 96,204,152, 49, 16, 8, 4,120,241,197, + 23,241,217,103,159, 97,229,202,149,136,138,138, 50,222,135, 22,182,209,198,207,207,111,224,141,180, 52,247,119,222,121,167, 3, + 33,196,141, 82,170,171,168,168,248,249,173, 41, 83,148, 44,203, 98,125,108,172, 8,134, 50,213, 38, 17, 8, 4,184,122,245, 42, + 58,118,252, 99, 72,115,119,119,135,147,147,147, 81,129,183, 4,153, 76,102, 52,106,234, 99,110,186,118,237, 10, 0,232,212,169, + 83,115, 68,173,216,186,117,107,240,128, 1, 3,176, 98,197, 10,124,246,217,103, 40, 43, 43,195,210,165, 75,177,103,207, 30,132, +132,132,192,209,209,241, 53, 66,200,123, 35, 71,142, 4,203,178, 56,115,230, 76, 21,204, 40,175,182,109,219, 66,169, 84,226,157, +119,222,129, 88, 44,134, 86,171,133,171,171, 43,206,188,158, 0,177, 88,140,201,147, 39, 35, 57, 57, 25, 87,174, 92,177,168,145, +148,210,173,149,149,149,173,206,156, 57, 19,121,246,236,217,149,169,169,169,208,233,116,208,235,245, 0,176, 30,192, 79, 0,190, + 32,132,220, 37,132,124,220,152, 12, 66, 72,199,224,224,224, 13, 17, 17, 17,182,169,169,169,114,150,101, 31, 28, 60,120,176, 74, +165, 82,173,174, 87,254,117,188, 51,104,208,160,251,148,210, 54,132, 16, 57, 0,117, 99,202,159, 16, 18,246,207,158, 61,119,116, +227,243, 73,201,167,159,130,170,213,136,231, 56,125, 82,109,237,164,122,229, 95,199,219, 75,151, 46,229, 51, 12,131,242,242,114, +220,187,119,175,152,182,160,132,246,223,129,199, 60, 0, 29, 29, 73,240,236,161, 33, 95,191, 51, 40,248, 31,181, 42, 77,141,158, +128,101,132, 50,190,147, 79,128,236,179,185,187, 80, 80, 90,133,207,246,253,134,168,177, 43,100, 84, 40,133,167,173,210,153,242, +208, 6, 77,187, 19,201,201,147, 39,113,233,210, 37, 44, 91,182, 12,223,126,251, 45, 94, 83,169,160,255,212, 31,208, 42,161, 81, + 41,241,127,247,236,144,172,237, 4,230,232, 81,244,234,213, 11,167, 79,159, 54,213,230,135,228, 93,185,114, 5,133,133,134, 66, + 88,251,247,239,199,144, 33, 67,176,119,239, 94, 36, 39, 39,131, 97, 24,216,219,219,155, 92,199,174,119,233,215, 91,230,230,130, + 0, 77,161, 80, 40, 90, 7, 4, 4, 24, 95, 83, 74, 31,114,249,215,212,212, 24,159,215, 15,158, 82,169, 20,148,210,102,141, 0, + 79, 3,157, 78, 7,177, 88,108, 84,178,217,217,217,152, 54,109, 26, 2, 2, 2, 80, 94, 94,142,213,171, 87,163,123,247,238,207, +186, 89,127, 38, 66, 0,102,141, 9,141, 70, 99, 31, 28, 28,108,124, 93, 81, 81,129,188,188, 60, 72, 36, 18,180,109,219, 22,174, +174,174,240,244,244,132, 66,161,160, 0, 42, 44,249,226,105,211,166,149, 47, 92,184,208, 61, 55, 55, 87, 10,195,174, 7, 35, 28, +199,161,186,186,218,246,210,165, 75,188,128,128,128,178,123,247, 44, 14,109,201,100, 89,182,245,170, 85,171, 46,170,213,106,170, + 82,169,116, 64,189,219, 13,157, 96, 48,120,204,162,215,235,165,245,215,113, 67,101,255,232,223,250,217,107,221, 18,195,227, 46, +176, 6,104,181, 90, 8, 4, 2,180,109,219,246, 33,163,219,199,199,231, 49, 3,220, 28,132, 16,158,141,141, 77,255,253,251,246, +137,133, 66, 33,142, 28, 57,162, 5, 80, 94,231,209, 17,231,229,229,101, 31, 56,112, 32,104,210,164, 73, 0,224, 96, 90, 26, 90, +236,230, 55,135,173,173, 45,100, 50, 25, 94,127,253,117, 76,156, 56, 17,221,186,117,195, 7, 31,124, 0,157, 78, 7,181, 90,109, +145,119,135, 16, 98,227,238,238,254,198,152, 49, 99,240,239,127,255, 27, 31,124,240,193,175,114,185,252, 57,111,111,111,167,151, + 95,126, 25,167, 78,157,130, 88, 44,134,187,187,187,124,206,156, 57,221,199,142, 29,139,109,219,182,161,164,164,100,155,185, 45, +129,106,181, 26,222,222,222,112,113,113,129,171,171, 43,236,237,237,225,224,224,128,234,234,106,136,197, 98,108,219,182, 13,163, + 70,141, 66, 99,222,205,166,160,148, 86, 18, 66,138, 5, 2,193,140,119,222,121, 7, 58,157, 14,253,250,245,195,197,139, 23,247, +114, 28,151,241,210, 75, 47,117, 91,176, 96, 1,222,120,227,141, 15, 8, 33, 59, 40,165,217,143,124,254, 38, 33,100,229, 15, 63, +252,240,114,251,246,237, 59, 28, 60,120,176,166,162,162, 34,166,161, 23,143, 16, 50,162,119,239,222, 81,219,183,111,223, 15,195, +189, 51, 26, 77,120,159, 40,165, 87, 9, 33, 43,237, 47, 95, 94, 60,142,101,177, 30,208,127, 83, 83, 51,241, 17,121,175,204,153, + 51,103,253,244,233,211,145,149,149,133, 35, 71,142,128,101,217, 83, 22,119,250,111,198, 67, 6, 0, 33,132,124,254, 90,167,237, +179, 95, 14,126,238,110, 65, 89,193,236,109,231,127,252,118,198,243, 35, 60,228,106,207,210,156,244,154,249, 99,251,201, 62,219, +247, 27,230,143,237,135,210,236,155, 53, 78, 53, 37,178,178,234,218, 10,134, 32,207,220, 23,117,237,218, 21, 63,255,252, 51,238, +223,191,143,141,155, 47, 66, 94,114, 21,229,165, 90,220,210,180,131,208, 59, 4,118,118,118,205,114,175,213,203,203,201,201, 65, + 76, 76, 12, 46, 93,186,132,249,243,231, 35, 54, 54, 22, 65, 65, 65,205,150, 39, 20, 10, 65, 8,121,162, 32, 64,153, 76, 86,152, +149,149,213,202,217,217, 25,148, 82,163,203,191,161, 17,208,112,224,172,174,174,198,131, 7, 15,192, 48,204, 51,223,195,207,113, + 28,248,124, 62, 52, 26, 13, 8, 33, 88,189,122, 53,212,106, 53,202,203,203,161,209,104, 48,107,214, 44,172, 93,251,151, 47, 9, +254, 52,233, 8, 32,199,220, 73,148,210, 91,155, 55,111,238,180,121,243,102,166,162,162, 2, 23, 46, 92, 64, 69, 69, 5,124,124, +124,208,174, 93, 59,132,132,132,160, 85,171, 86, 24, 61,122, 52,179,123,247,110,127, 60,162,208, 27,195,223,223,159,221,188,121, +115,225,212,169, 83,189,222,126,251,109,207,206,157, 59,215, 0, 64, 86, 86,150,188,186,186,218, 70, 36, 18,169,187,119,239, 94, +168,211,233,154,147,185, 51, 25,128,119, 69, 69,197,115, 0,210, 96,216, 82, 41, 7, 16, 2, 64, 0,192,162,168,102,134, 97,148, + 89, 89, 89,210, 14, 29, 58,152, 85,254, 0, 80, 91, 91, 11, 0, 77,110, 59, 3, 12, 6, 64, 94, 94, 30, 46, 95,190,140, 54,109, +218,160,119,239,222, 15,221, 99,124, 62, 31, 89, 89, 89,240,247,247,183,164,137,221,254,245,175,127,185,132,133,133, 33,102,217, + 50,216,218,218,242,195,194,194, 38,218,217,217,241,189,188,188,208, 33, 32, 0, 83,166, 76,193,157, 59,119, 0,195, 54, 72,147, + 8, 4, 2,244,236,217, 19,133,133,133,240,240, 48, 56,132,212,106,181,217,248, 31,115,200,100, 50,240,120, 60,164,167,167,227, +246,237,219, 8, 15, 15,127, 72,249, 91,184,188,227,210,173, 91, 55, 41,143,199,195,145, 35, 71, 0,224,107,133, 66,209,235,246, +237,219, 81,131, 7, 15, 70,199,142, 29,145,155,155,139,153, 51,103, 98,194,132, 9, 56,112,224, 0,230,204,153,115, 17,134,160, + 56,147,104, 52, 26,216,218,218, 66, 46,151,195,206,206, 14,114,185, 28,182,182,182,198,137, 66, 94, 94, 30, 54,108,216, 0,192, +144,172,205,146,198, 18, 66, 60, 9, 33,199, 98, 99, 99, 29,122,246,236,137, 51,103,206, 96,226,196,137,232,220,185,179,253,207, + 63,255,220,109,214,172, 89, 72, 73, 73, 65, 89, 89, 89, 41,208,184, 14,161,148,174, 37,132, 8,146,146,146, 58,105,181,218,165, +148,210,125, 13,228,143,238,213,171,215,186,237,219,183,127,235,230,230,246, 69, 93,108,216,123, 0,122, 54,213, 38, 74,233, 18, + 66,136,224,132, 64, 16,117, 65,167,123,253, 17,121,163,198,253,243,195,253,179,231, 78, 33, 25, 25, 25,184,122,245, 42,182,111, +223, 94, 3,224,125, 75,250,251,119,228, 33, 3, 32, 8, 16, 20, 87,212, 40,190, 59,117,227,250, 23, 71,211,162,107, 88,238,220, +111,215,114, 35, 38, 60,223,202, 83,122,241, 75, 58,169,219,219, 53, 81, 99, 87,200, 74,179,111,214, 72,207,127, 70,193,105, 17, +127,171,188,152, 35,184,105,233, 23,250,248,248, 96,209,234,175, 81, 94, 94,142,153, 51,103, 66,230, 38,123, 34, 87,179,175,175, + 47,190,253,246,219, 63,228,201, 90, 38,143,207,231,131,199,227, 61, 22,244,247,232,195, 20, 12,195,252,158,146,146,210,170, 75, +151, 46, 15, 41,255,134,179,167,134,179,168,186,227, 92,101,101,229, 51,183, 48, 53, 26, 13,108,108,108,208,183,111, 95, 4, 5, + 5, 25, 7,114,189, 94, 15,189, 94, 15,150,101,241,214, 91,111,225,135, 31,126, 48, 33,133,114,148,240,116,237, 29, 24,221,182, +109,219,196,175,189,246, 26,108,108,108, 30, 59, 75,171,213,226,226,197,139,104,239,192,232, 0,162, 55,189,181, 0, 0, 80,115, +242,228, 73, 89,191,126,253, 80, 94, 94,142,175,190,250, 10,217,217,217,208,104, 52,245, 91,165,112,243,230, 77,192, 16,196,103, + 17, 77,237,255, 39,132,184,194,224, 26,182, 1,112,220,156, 28,149, 74,149,182, 99,199,142,192,244,244,116,210,171, 87, 47, 1, +165,180,126,214,101, 60,167,206,165, 77,246,236,217,227, 99,105,251, 0,192,193,193, 65,183,118,237,218,226,125,251,246,217,100, +103,103,187, 57, 59, 59,231,183,107,215,174, 48, 45, 45,173, 57,174,127, 0,198,181,221, 19, 35, 71,142, 28,213,169, 83,167,254, + 37, 37, 37,216,188,121, 51,120, 60, 94, 45,199,113, 63, 90,186,213,139, 82, 90,120,231,206, 29,151,128,128, 0,136,197,226, 38, +149, 63,143,199, 3,199,113, 40, 43, 43,131, 94,175, 55, 89,155,190,188,188, 28,155, 54,109,170, 55, 22,192,178, 44, 94,125,245, + 85,227, 61,246,201, 39,159, 32, 33, 33, 1,209,209,143, 5,174, 63, 70, 80, 80,144,223,235,175,191, 14, 0,248,240,131, 15,176, +116,201, 18, 70,175,215, 51,245,215,178, 90,173,198,193,131, 7,241,193,135, 31, 42, 96, 65,208, 99,195,123, 95,161, 80, 64, 46, +151, 63,177,242,175,135, 97, 24,180,109,219, 22,222,222,222, 70,229,255,254,251,239, 67,167,211, 97,201,146, 37,150,136,200, 63, +119,238, 92,137, 74,165,114,121,227,141, 55,176,111,223,190, 79,212,106,245,166, 47,190,248,162,230,185,231,158,147,245,238,221, + 27, 98,177, 24, 54, 54, 54,216,185,115, 39,222,125,247,221,139, 44,203,246,167,148, 86,155, 19, 92, 91, 91,139,240,240,112,227, +246, 68, 59, 59, 59, 72,165, 82,212,214,214, 54, 92,110,107,238,143, 48,101,206,156, 57,173,134, 14, 29,138,213,171, 87,227,203, + 47,191,212, 68, 70, 70,138,150, 44, 89,130, 57,115,230,224,202,149, 43,152, 59,119,174,134,101,217, 73,166,150,242, 40,165,159, + 18, 66, 14, 81, 74,141,122,134, 16,242, 90,175, 94,189, 86, 79,157, 58,213,254,235,175,191, 22,175, 89,179,134, 1,240, 35,128, + 5,230,242,160, 80, 74, 23, 17, 66,254,143, 82,154,210, 80,222,184,232, 31,246,140,124,185, 7,121,249,237, 13,248,231,176, 64, +108,219,248,153, 94,161, 80,188,245,168,103,226,191,137,135, 12,128, 52, 67, 0,197,139,237, 0,225, 29, 74, 53, 0,208,197,131, +191,248, 31,190, 54, 91,253,117, 41,173, 36, 63, 77, 1, 21,201,224,164, 44,149, 65,207, 33,179, 68, 89,176,238,116,241,210,244, + 18,147, 23,152,190,170,170,138,121,116, 63,188,163,163, 99,163, 51,244,186,181, 94, 83,131,211,211,150,103,116, 73,214, 27, 0, + 77,197, 1,212,111, 21,108,138,138,138,138, 67,155, 54,109,122,121,212,168, 81, 54, 74,165,242,161,160,191,134,127,235, 7,208, +202,202, 74,156, 60,121, 82,171,215,235, 77, 5,158,177, 74,165,146,223,152, 98,173,167,225,224, 84,215, 95,179,174,236,119,223, +125, 23, 42,149, 10, 42,149, 10,106,181,218,168,248, 27, 26, 1,102, 61, 40,122,166, 22, 18,251,226,221, 67, 57,225,198, 43, 59, + 52,111,191,190,223, 62,114,248,107,252,177, 99,199, 26, 26,206,178,184,124,249, 50,138,238, 94, 99,103,135,176,149, 51,135, 10, +107,169,141, 91, 30, 1, 76, 6, 98, 1, 56,190,100,201,146,136,237,219,183,123, 12, 27, 54, 12, 51,103,206,196,243,207, 63,143, +184,184, 56,108,217,178, 5,183,110,221, 66, 73, 73, 73, 33,204,108, 55,123, 4, 89,131,253,255, 50, 66,200, 64, 0, 78, 48,184, +196,239, 1,248,205, 18,165, 72, 41, 85, 18, 66,190,139,143,143,247,187,114,229, 74,168, 90,173,182,123,225,133, 23,200,139, 47, +190, 72, 88,150, 69, 78, 78, 14,114,114,114, 80, 88, 88, 8,181, 90,109, 54,217, 18,159,207, 47, 11, 12, 12, 12,159, 49, 99,134, +209,183, 63,118,236, 88,229,129, 3, 7,202,228,114,185,241,119, 74, 79, 79,183, 75, 79, 79,247, 35,132,148, 54,163,207, 62,126, +126,126,130, 37, 75,150,160,176,176, 16, 29, 58,116,192,178,101,203, 68, 37, 37, 37, 62, 0,204,238,147, 6, 0,149, 74,149,126, +245,234, 85,255,214,173, 91,139,125,125,125,161,211,233, 30, 83,254,182,182,182,112,115,115,195,237,219,183,145,156,156,172, 86, +171,213,183, 77,201,100, 24,230,161,107, 86,165, 82, 25,239,185,154,154, 26, 36, 36, 36, 0, 0,156,157,157,205,182,239,214,173, + 91,121,113,113,113,254,195,134, 13,195,154, 53,107,112, 62, 49, 17,132, 16, 20, 23, 23,235,243,243,243,149, 5, 5, 5,213,148, +210,124, 0,169,150,236,173,127,116,207, 63,199,113, 79, 69,249,215,179,105,211,166,135,102,254, 26,141, 6, 28,199, 65,173, 54, +159,180,143, 82,170, 35,132,124,177,106,213,170,229, 49, 49, 49, 56,116,232, 80,208,151, 95,126,249, 85, 88, 88, 24,110,223,190, +141,189,123,247, 66,175,215,227,214,173, 91, 21,153,153,153, 91, 0,124, 98,225, 14,168,162,254,253,251,155, 12,236, 19,139,197, + 22,205,250, 31, 33, 36, 40, 40, 8,217,217,217,248,242,203, 47, 43, 0,116,140,143,143,159,125,229,202,149,232,231,158,123,142, +151,148,148,164, 81,169, 84,175, 88,146,199,227, 17,229, 63,177,107,215,174,203, 94,123,237, 53,187,203,151, 47,219,170,213,234, + 55, 37, 18,201,144,186,192, 64,179, 57, 50,234,228, 53, 84,254, 19,135,204,222,187,179,103,191, 17,100,205, 73,128,120, 14,195, +167, 27, 22,211,242, 59,233,111, 81, 74, 15,180,160,223,127, 27, 30,211,104,117,193, 19,198,136,171, 43,133,236,175, 93, 60,248, +211,222,237,227,253,233,139, 1,114, 15,103, 73,173, 99, 89,181,170, 60,254,118, 85,241,186,132,210,165,201, 69,236,225, 71,101, + 60,194,134,224,224,224,119,151, 47, 95,206, 27, 49, 98, 4, 26, 75,140, 3, 24, 20, 87,113,113, 49,126,253,245, 87, 14,192,231, +207, 80, 30,206,156, 57, 3,119,119,247,250, 36, 68,208,235, 13,147, 84,142,227,140, 51, 27, 66,136, 37,129,109,223,103,103,103, +207,220,180,105,211, 63, 70,143, 30,205,111,204,229,223,240,121,126,126,190,182,166,166,102, 15,165,212, 84,100,205, 7,175,190, +250,234, 39,111,190,249, 38,111,228,200,145, 77,122, 33, 56,142,195,229,203,151,145,148,148,196, 1,248,192, 92, 67,181, 90,173, + 49,225,207,163,138,191,225,107,147, 8,170,106, 25, 39,255, 7, 66, 73,129,122, 94,247, 7,110,179,187,104,106, 55, 94,249, 70, + 58,117,252, 62, 7,103, 31,127, 94,254,237,107,220,252,112,174, 98,214,155,252, 90, 70, 96, 83,205,216,187, 23,193,214,189, 28, + 51,226, 77,186, 98, 41,165,165, 0,126, 38,132,120,197,198,198,118,239,218,181,171, 83, 93, 6, 49,156, 57,115,166, 12,192,239, +117,131,122,179,160,148,234,235,250,196, 0,184, 9,160,194,146,217, 81, 35,114, 56, 24,118,109,220, 33,132,216,156, 59,119,110, +116, 82, 82,146,144,101, 89,100,103,103, 35, 39, 39, 7,167, 78,157, 2,195, 48,102,119, 1,176, 44,251, 67, 69, 69, 69,192,154, + 53,107,158,179,179,179,211,118,239,222,189,102,228,200,145, 70,197, 95, 80, 80, 32,205,207,207,247,214,233,116, 2, 74,233, 37, +152,217, 45,242, 8, 69,105,105,105,204,138, 21, 43, 80, 86, 86,134,141, 27, 55, 2,134, 36, 64, 22, 15,230,148,210, 74,137, 68, +114,243,194,133, 11, 33,122,189,158, 95,159, 60,170,222,152,114,118,118,134,135,135, 7,178,179,179,145,156,156,204,106,181,218, +155,230,246,220,243,249,124,188,255,254,251,136,143,143,135,135,135, 7, 94,121,229, 21,163,226,117,113,113, 65,175, 94,189,224, +227,227,131, 1, 3, 6, 96,225,194,133, 38,219,167,215,235,207,189,249,230,155,174, 73, 73, 73,246,111,190,245, 22, 54,109,222, +172, 42, 40, 40,248,161,177,196, 55,150,240,168,247,239,105, 42,127, 30,143,103,116,247,215, 63, 62,250,232,163,230,230, 1, 88, +189,124,249,242,240,170,170,170, 17,139, 23, 47,198,146, 37, 75,112,243,230, 77,124,247,221,119, 56,117,234,212, 65, 0,115, 1, + 20, 83, 74, 45,222, 30,171,213,106,240, 82,227,167, 0, 0, 32, 0, 73, 68, 65, 84,255, 83,181, 87,178,238,221,187,135,110,221, +186,129, 97, 24,137, 94,175, 47,170,115,193,239, 58,117,234, 84, 87, 24, 50, 82, 90,236, 61, 6, 12,129,129,118,118,118,235,199, +142, 29, 43,184,121,243,166, 92,163,209, 60, 56,120,240,160,162, 46, 48,112,119,115, 27, 72, 8, 9,243, 10, 29,179, 51,244,133, +177,228,155, 4, 64,161, 2,180, 89,199,244,229,119,226, 39, 83, 74,155,149,238,249,239,136, 69,169,128, 1,160,131, 11,177,229, + 81,116,212, 83,120, 51, 4,121, 28,193, 77, 51, 51,255, 63,190,196,144,191,126,105,171, 86,173, 38, 44, 91,182,204,168,184, 39, + 77,154, 4, 66, 8,106,107,107, 17, 31, 31,207,149,150,150,238,134,193,106, 53,185, 38,254, 52,229,201,229,242,203,181,181,181, +102,163,131,235, 17, 10,133,165, 42,149,170, 77, 83, 65, 53,132, 16,111,169, 84,122, 61, 42, 42,202,246,133, 23, 94,224, 53,182, + 20, 80, 85, 85,133,162,162, 34,246,216,177, 99,249, 53, 53, 53, 29,205,109, 77, 34,132,116, 0,240,169,167,167,231,136, 25, 51, +102,160,127,255,254, 32,132, 96,243,230,205, 16, 10,133,200,201,201,193,197,139, 23, 81, 85, 85,117, 8,192, 98,115, 89,176, 4, + 2,193, 68,150,101, 45, 74, 5, 44, 18,137, 84,106,181,218,244,141,176,237, 69, 9,180,144,161, 58,223, 78,175,120,224,198,234, + 52,182,123,111,178,226,241, 29,249,106, 70, 32,170,102,228,238, 69,176,245,170,130, 16, 53,152,122,178, 89,133,148, 8, 33,182, + 78, 78, 78, 47,137, 68, 34,185, 70,163, 81,148,149,149,157,104,137,210,110,106, 9,224,105, 64, 8,113, 19,137, 68,131, 71,142, + 28,201,151, 72, 36,184,126,253, 58,174, 92,185,194,114, 28,247,139,165,209,195,132, 16, 30,195, 48,193,132,144,208,246,237,219, +151, 50, 12,163,188,127,255,190, 84,169, 84, 58,215,205, 86,110, 88,154, 29,174,129,204,192,249,243,231,247, 88,181,106, 21,243, +224,193, 3,252,244,211, 79,136,137,137,225, 74, 74, 74, 18, 45,201,148,214, 64, 14,145, 72, 36, 47, 57, 59, 59,123, 60,255,252, +243,162,134,158,161,250,132, 82,103,207,158,213,148,150,150, 22,170, 84,170, 19,166,246, 75,147,186, 44,148,245,187,110, 76, 45, +183, 9, 4, 2,248,251,251,155,205,186, 71, 8,177, 11, 14, 14,126, 53, 41, 41, 73,176,114,229, 74,124,250,233,167,135, 40,165, +102, 99, 47, 30, 69, 34,145, 76,180,196,107, 35,145, 72, 84,181,181,181, 22, 43, 7, 62,159, 63, 85,161, 80, 48,150, 4,208, 89, +146, 10,152, 16,194, 3, 48,215,217,217,121,118,219,182,109,125,211,211,211,179,171,170,170, 62, 7,176,177,185,215,200,127, 18, + 66,200,180, 49, 99,198,108, 89,188,120, 49, 6, 13, 26,132,194,194, 66, 31, 75,114, 49, 88, 32,119, 97,239,222,189, 27, 6, 6, +126,244, 36,247, 51, 33,100, 69,240,216,221,139, 85, 94,175, 67,117,105,169,190,224,236,138,137, 79,115,124,248, 43, 99,177, 1, +240, 84,190,236, 17,197,253,227,143, 63,226,252,249,243, 92, 89, 89,153, 69,138,255, 63, 45,239,105, 65, 8,241,150,203,229,251, +218,180,105, 19, 58,124,248,112,105,253,210, 65,101,101, 37,148, 74, 37,126,253,245, 87,117,121,121,249, 79, 10,133, 98, 58,109, + 70, 26, 90, 98,200,147,191, 42, 32, 32,160,247,172, 89,179, 16, 23, 23,135,228,228,100,148,149,149,157, 3, 16, 77, 41, 77,252, + 15,117,201, 50,234, 13, 1,101,161, 45, 88, 13, 31,124, 17, 11, 27,143,234,150, 40,254,134, 16, 66, 4, 48,204,218,245,148,210, +230,165, 76,123, 70, 16, 66,188, 68, 34, 81,152, 78,167,115, 37,132, 84,112, 28,151, 66, 41,181,168, 22,192, 35,114,132, 12,195, +132, 2, 8,212,235,245,183, 0,164, 52,103, 54,247,136, 44,137,157,157,221,203, 85, 85, 85, 78,245,199, 4, 2, 65,153, 78,167, +251,133,182,160,162, 37,159,207,111, 45, 16, 8,122,200,100, 50,198,205,205,141, 15, 0, 69, 69, 69,108, 77, 77,141, 94,167,211, +157,103, 89, 54,219,156, 12,161, 80, 56, 81,167,211, 89, 92,125,211,210,194, 59,132, 16, 79,111,111,239,158,101,101,101,149, 42, +149,234,164,165, 49, 14,207, 2,153, 76, 54, 94,169, 84,202,204,159,217,188, 98, 64,196,224,158, 16,193, 80,161,244, 47,151,164, +134, 16,210,171, 83,167, 78,103,190,253,246, 91,140, 31, 63, 30,119,238,220, 9,165,148, 94,123, 74,178, 23, 11,133,194, 40,173, + 86, 59,179, 97, 32,223, 19,200, 91, 99,215,182,127, 84, 85,230,241,215,159,134,188,191, 11,207,212, 0, 48,126,169, 65,113,111, +135,193, 29,249,198,147, 42,234,167, 45,239,105, 80,119,115,190,230,224,224,240, 10,199,113,221,149, 74,165,135, 92, 46,207,214, +235,245,231,170,170,170,246, 82, 74,127,125, 2,217, 47,195,208, 95, 1,128, 73,148,210,159,159, 86,187,159, 10,223,246, 20,128, +202, 24,104,149,192,219,103, 91,150,227,217,202, 83,131, 16,210, 5, 64, 23, 0, 87,204, 44, 55, 89, 42, 79, 10,192, 25, 0, 5, + 80,218, 18, 99,194,202,255, 6,132,144,120, 15, 15,143, 62,133,133,133,191, 0,120,149,214,197,150, 61, 37,217, 29,155,187,132, + 96, 70, 94,104,195,216,128,255, 5,254, 20, 3,192,138, 21, 43, 86,172,252,247, 67, 12, 69,169,220, 0,148, 60,197,164, 93, 86, +158, 18, 86, 3,192,138, 21, 43, 86,172, 88,249, 31,164, 57,137, 69,172, 88,177, 98,197,138, 21, 43,255, 37, 88, 13, 0, 43, 86, +172, 88,177, 98,229,127, 16,171, 1, 96,197,138, 21, 43, 86,172,252, 15, 98, 58,181,157, 21, 43,205, 97,221, 0, 27, 72,213,142, +224,241, 28,161, 7, 31, 12, 88,112, 92, 57,106,197,229, 88,240,107,139, 18,179, 88,177,210, 82,234, 10, 2, 13,100, 24,230,141, +118,237,218, 13,188,123,247,238, 78,142,227,102,255,201,109, 18, 1, 48,149, 93,136,181, 6,203, 89,121, 86, 60, 22, 4, 40, 20, + 10, 31,232,116, 58,147,105, 33, 27, 34, 18,137,138,212,106,117,147,153,164, 4, 2,193, 3,150,101, 31,147,199,231,243,245, 44, +203, 62,230,129, 48, 39,207,202,147, 83, 55, 48, 90,106,252,153, 30,144, 98, 34,249,112, 65,107, 80,226,196,169,170, 92,121,181, +197,126, 80,215,248,233, 41,103,207, 16, 94, 37,196,178,123,156,212,245, 30, 79, 98, 87, 12, 66,203, 32, 69, 30, 38,199,155,207, +123,250, 55,131, 16,242,162,131,131, 67,108, 77, 77, 77,128,173,173,237,173,170,170,170,101, 44,203,154, 42,164,208,152, 12, 6, + 64, 95,161, 80, 56,133,227,184, 72, 30,143,119, 82,171,213,126, 3,224,116, 75,246,121,215,253,159,151, 1, 24, 9,160, 53,128, + 44, 0,251, 1, 44,107,137,146, 33,132,136,248,124,254,187, 34,145,104, 0,165,212, 31, 0, 37,132,220,209,104, 52,199, 88,150, +253,226,105,110,241,122, 82, 8, 33,207,123,121,121,253, 48,114,228, 72,183, 87, 71,140,128,167,167, 39,102,188,253, 54, 78,157, + 58, 37,253, 51,182, 45, 18, 66,132, 33, 33, 33,191,132,135,135,247,251,238,187,239,184, 71,222, 51, 62,231,243,249, 10,181, 90, +237,250, 36, 70, 0, 33,164,171,141,141,205, 78,177, 88,236, 94, 86, 86,182,152, 82,250,245, 19, 52,221,202,127, 49,143, 25, 0, +132, 16, 90, 93, 93, 13,153,204,124,222,138,178,178, 50,212, 85,190,107,210,162, 37,132, 80,133, 66,129,250, 84,174, 0, 80, 92, + 92, 12, 55, 55, 55, 52,117,188, 5, 69, 39,254,171, 97,120,252, 7, 84,207, 89,100,148, 49, 60,126, 17,199,234, 76, 26, 80, 60, + 30,175,152, 82,234,216,212,251, 13, 7, 36,134, 97,202,117, 58, 93,227,197,104,214, 13,176,129, 72,219, 9,229,183,123, 66, 93, + 29, 8,202,186,164,151,235, 37,219,174,113,158,191,231,235,157,186,123, 49,101, 83, 59,243, 10, 58, 56, 50, 42, 16,126, 9,196, +210, 59,112,240,187, 4, 25,115, 17,111,157,107, 52,155, 31, 33,100, 29, 12,219,134, 0,160, 28,134,210,158,175, 3,136,128, 33, +247,255, 30, 0,221, 1,212,183,191,136, 82,186,192, 84,127, 31,145,159, 13,192,183,238,101, 14,165,180,181,165,159,109, 10,161, + 80, 56, 69, 46,151,127,190,125,251,118,155,174, 93,187,226,226,197,139,152, 52,105, 82,109,117,117,245, 24,150,101,143, 88,208, +166, 14,124, 62,255, 77, 0,111,136, 68, 34,109,255,254,253, 79,143, 29, 59,246,218,247,223,127,223,249,228,201,147,145, 26,141, +134, 7, 96, 39,203,178,219, 41,165, 22,165, 2,174, 75,158,244, 59, 0,109,239,222,189,207, 6, 5, 5, 85,109,221,186,181, 82, +167,211,141,129, 33,121, 76,175,230, 36, 85, 34,132,116,145, 72, 36,251,123,245,234,229, 21, 17, 17, 33,114,119,119, 71,113,113, + 49,110,221,186,133,187,119,239,170,111,220,184, 81,160, 82,169,198,152,203, 51, 32, 18,137,174,235,245,122,159, 6,114, 27,251, + 46,227,115,134, 97,238,171, 84,170,102,149,203, 38,132,240,125,125,125,243,143, 29, 61,234, 42, 18,137,144,152,152,136, 31,126, +252, 17, 63,253,244,211, 38,150,101,159,185, 7,128, 16, 34,236,212,169,211, 47, 39, 78,156,232,179,101,203, 22, 94,191,126,253, +224,236,236, 12, 59, 59, 59,216,217,217, 25,211,123, 51, 12, 3,161, 80,200,177, 44, 43,107, 42,211,168, 5,223,213,118,248,176, + 97,215, 59,118,236, 40, 57,122,244, 40, 82,174, 93, 83, 1,112,108,169, 60, 43,255,221, 52,106, 0, 80, 74,113,240,224,193, 70, + 75,226, 62,122,204,207,207,207,172, 1, 64, 41,197,177, 99,199, 96,103,103, 7,123,123,123,216,217,217,193,203,203, 11, 38,142, +255, 41, 6,128, 80, 40,252, 77,167,211,173,160,148,254,165,234, 63, 19, 66,232,142, 31, 78, 66,192, 99,160, 84,105, 80,171, 82, + 63,244, 87,173,209, 66,195,234,161,213,177,248,191,207, 22, 64,175,215,155,252,253, 8, 33,116,239,222,189,168,207,235,222, 48, + 55,121,125, 37,192,250,122, 0,243,231,207,111, 90,222,215,189,195,244,249,105,175,229,148,212,118,254, 87, 10,231,117,170, 80, +228,233, 25,214,207, 97,200,144, 33,136,136,136, 64, 82, 82, 18, 14, 31, 62,140,130,171,191, 85,244,241,208, 20, 78, 15,229,229, +183,115,147,253, 14,175,224,255,195,244,248,244, 38,218,246,115, 65, 65,193, 11,106,181, 90,220,174, 93, 59,222,160, 65,131,120, +195,134, 13, 67,143, 30, 61,112,254,252,121,196,197,197,225,232,209,163,220,221,187,119, 57,177, 88,172,246,244,244, 60, 67, 41, + 29,218,156,223,178, 65, 81, 32, 0,104,223,146,196, 81,117,137,158, 34,249,124,254, 96,137, 68,242,118,114,114,178,164,109,219, +182,198,247, 15, 30, 60,136, 25, 51,102, 92, 46, 45, 45,237,106, 74,142, 64, 32,184,200, 48,140, 95,151, 46, 93, 18,103,204,152, +113, 86,165, 82,241,227,227,227,219,150,151,151,203, 29, 29, 29, 21,145,145,145,153, 66,161,144,219,178,101, 75,175,228,228,228, + 30,122,189,254,150, 78,167,235, 97, 65,251, 86, 2,120,177,170,170,170, 21, 33, 68, 24, 31, 31,127, 50, 63, 63, 63,227,163,143, + 62, 58, 94, 82, 82,178, 28,134,226, 71,203, 45,236,107, 23, 59, 59,187, 95, 87,172, 88,225, 52,114,228, 72, 56, 58, 58, 66,169, + 84, 34, 41, 41, 9,149,149,149,184,126,253, 58,110,223,190,141,147, 39, 79,150, 41, 20,138, 1,166,140, 0, 66, 8, 45, 44, 44, +132,147,147, 19,180, 90, 45,212,106, 53, 52, 26, 13,180, 90,173,241,161,211,233,192,178, 44, 46, 93,186,132,153, 51,103, 54,123, + 60, 32,132,116,154, 50,101, 74,234,178,152, 24,244, 31, 48, 64,127,227,198,141,181, 0,118, 90,146,254,152, 16,194, 15, 11, 11, +139,235,220,185,243,160, 29, 59,118, 52,122,142, 88, 44, 46, 82,169, 84, 22,123, 41, 67, 66, 66,142,158, 56,113,226, 69, 55, 55, + 55,254,242,229,203, 33,149, 74,225,226,226, 2,123,123,123,200,100, 50, 8, 4, 2, 80, 74,209,163, 71, 15,136,197,226,102, 27, + 0,132, 16, 49,128, 40, 0,255, 14, 14, 14, 62, 49,228,229,151, 91,157, 57,123,150, 36, 38, 37, 1,192, 3, 0,173,158,213,178, + 2, 33,196, 1,192, 98, 24,234,201,124, 73, 41, 45,104,240,158, 55, 12,165,117,171, 0,172,178, 36, 11,170,155,155,219, 21, 62, +159,239,165,211,233,114,139,139,139, 77,222, 75, 86,154, 79,147,110,224, 71,115,114, 55,149,179,219, 82, 28, 29, 29, 97,111,111, +111, 84,244,230,142,255, 25,232,116,186,190, 66,161,176, 27, 33,100,216, 95,205, 8,224, 49, 4,133,197, 21, 8, 13,242,195,190, +195,103,112, 57,205, 48, 17,228,243,249, 16, 10,235,140, 51,129,208,130, 74,187, 6,234,115,184, 7, 5, 5,225,244,233,211, 72, + 77, 77,133, 80, 40,132, 72, 36,130, 72, 36, 50, 62, 55, 41,143,227,219, 18,173, 58, 32,226, 59, 77,175,121, 31,174,148,252, 58, +125, 58, 28, 28, 28,140,111, 7, 5, 5, 97,234,212,169,168,168,168,112, 88,185,114,165, 67,143,205,235,218, 20,205,102,106,192, +241, 92, 0, 52,106, 0, 0,128,135,135,135, 28, 0, 94,122,233, 37, 28, 62,124,248, 33,121,211,167, 79,199,192,129, 3,121,109, +218,180,225, 1, 48, 83,174,176,113, 40,165, 90,142,227,120, 48,100,142, 60, 71, 8, 73, 1, 48,207, 66, 5,193, 8,133,194,247, +101, 50,217, 28,119,119,119,201,168, 81,163,196, 19, 38, 76, 16, 52, 84,254, 0, 16, 18, 18, 2,149, 74,213,222,156, 60,150,101, +187,142, 27, 55,110,189, 70,163,161,222,222,222, 53, 7, 14, 28, 8, 16, 8, 4,220,224,193,131, 83, 47, 92,184,224,147,146,146, +226, 54,114,228,200, 12,169, 84,122,199,207,207, 47, 43, 61, 61,253,159, 22,118,115,100, 68, 68,196, 47,132,144,137, 42,149,138, +205,200,200, 40,205,203,203, 43,149, 72, 36, 20,192, 38, 0, 31, 2, 48,107, 0, 16, 66, 4, 98,177,120,223,178,101,203,156,198, +141, 27, 7, 71, 71, 71,148,150,150,226,198,141, 27, 80, 40, 20, 80, 42,149,112,113,113, 65, 77, 77, 13,250,246,237,235,116,236, +216,177,189,117, 25,218,154,244, 46,184,185,185, 97,249,242,229,198,122, 0, 2,129, 0,197,197,197,216,185,115, 39, 42, 43, 43, +209,191,127,127,140, 25, 51, 6, 46, 46, 46, 22,118,245, 49,114,111,223,190,205, 50, 12,195,239,215,175, 31,115,227,198,141,116, + 75,149,127, 72, 72, 72,220,209,163, 71,251,127,253,245,215, 72, 76, 76, 52, 78,122, 26, 78,124, 90,181,106,101,241, 18, 41, 0, +116,233,210,101,192,150, 45, 91, 8,165, 20,215,175, 95,199,187,239,190, 11,169, 84, 10, 74, 41,148, 74, 37, 56,142,179,164,208, +152, 41,166, 0, 88, 1, 96, 25, 1,216, 31, 15, 29, 34, 25,183,111,115, 48, 84,221, 28,251,140, 99, 10, 22, 77,155, 54,109,129, +163,163, 35, 86,175, 94, 61,129, 16,210,135, 82,154, 77, 8,105, 13,224,244,226,197,139,125, 75, 74, 74,176,117,235, 86, 30, 0, +179,245,158,165, 82,169,123, 86, 86,150,155,135,135,135, 35, 33,228, 23, 0, 5,141, 60, 10, 1, 60,112,113,113,249, 93, 32, 16, +180, 98, 89, 54,191,168,168,168,203,127,172,135,255, 69, 88,108, 0, 52,245,176,132,122,139,191, 94,201,243,120, 60,147,199, 91, +130,131,131,195,201,202,202,202, 53,148, 82,179, 53,221, 77,177,115,231, 78,155,201,147, 39,199,253,213,140,128,106,165, 10,161, + 65,126,232, 23, 17,138,223, 18, 13,217, 42, 5, 2, 62,132,130,250, 1, 74, 0,129,185,242,189, 13, 80,171,213, 8, 10, 10, 66, + 72, 72, 8, 50, 50, 50,144,145,145,241,152,242, 55, 91, 14,152,161,132, 16, 74, 28, 37,208, 68, 70, 70, 74, 82, 83, 83, 81, 81, + 81,129,192,192, 64, 4, 4, 4,224,230,205,155, 56,113,226, 4, 10, 10, 10, 32, 18,137,224, 44,129, 26,160,124, 64,111,106,247, + 73,149, 84, 42, 69,100,100, 36, 88,150, 69, 92, 92, 28, 66, 67, 67,225,227,227,131,156,156, 28,252,242,203, 47,200,205,205, 69, +120,120, 56,210,211,211, 1,195,108,162, 57,228, 48, 12, 99, 92, 2, 0,208, 30,192, 59, 0, 78, 19, 66,186, 82, 74,239,155,249, +252,224, 54,109,218,188,191,123,247,110,155, 46, 93, 30, 31, 99, 50, 51, 51,145,153,153,137, 31,126,248, 1, 34,145, 40,205,146, + 6,109,216,176,225,146, 90,173,102, 6, 15, 30, 60,201,221,221,253,222,180,105,211,210,198,142, 29, 91,186,103,207,158,170,216, +216,216,160,253,251,247,143,232,219,183,239, 78, 71, 71, 71, 94, 51, 12, 0, 95, 63, 63,191,242,163, 71,143, 30,191,123,247,110, +121,102,102,102,118, 98, 98, 98,230,253,251,247, 21, 0,202,234,250,109, 22,129, 64, 48,229, 31,255,248,135,247, 75, 47,189, 4, +123,123,123,228,230,230,226,250,245,235,143, 21,184, 18, 10,133,144,203,229, 8, 8, 8,240, 72, 75, 75,155, 4, 96, 91, 83, 50, + 53, 26, 13, 88,150,197,238,221,187, 17, 17, 17,129, 46, 93,186,224,212,169, 83, 40, 40, 48, 76, 22,227,226,226, 48,102,204, 24, +243,215, 95, 19, 80, 74, 43, 9, 33,159,159, 60,121,114,126,212,188,121, 72, 77, 77,221, 74, 8, 41,162,148, 30, 53,245,185,144, +144,144, 31, 78,156, 56,241,146,171,171, 43, 15,192, 67,138,191,225, 36,168,185,236,218,181,139, 75, 72, 72,224,159, 63,127, 30, +239,190,251, 46, 36, 18, 67, 41,132, 57,115,230, 32, 49, 49, 17,193,193,193, 88,189,122,117, 75,186, 90,207,110,134, 97,150,233, +245,122,199,235,105,105, 60, 24, 20,127, 1,128,129,148,210,204, 39, 17,220, 2,228, 46, 46, 46, 88,177, 98, 5,220,221,221,125, +231,205,155,119,154, 16, 50, 25,192,142,245,235,215,251,206,157, 59, 23,239,189,247, 30, 0, 88,180,252,164, 84, 42,203,189,188, +188,236,125,124,124,164,201,201,201,131, 42, 43, 43, 81, 86, 86,134,226,226, 98, 20, 20, 20, 32, 39, 39, 7,153,153,153,184,117, +235,150,190,170,170, 10,249,249,249, 76,155, 54,109,254, 50, 5,145,254,234,252,199, 13, 0, 62,159,175,247,241,241, 97,234, 11, +226, 0,134, 58,241,124, 62, 31, 62, 62, 62,120,244,184, 72, 36,106, 81, 17,143,192,192,192,126, 66,161,176,251,147, 42,238,113, +227,198, 33, 55, 55,215,230,195, 15, 63,108,177, 17, 32, 22,139,127,213,104, 52,253,205,157, 39,151,203,143, 87, 85, 85, 13,176, + 68,102,181, 82,133,125,135,207,224,183,196, 20,148,150, 43, 32, 20, 24, 20,190,113,246, 47, 20, 64, 40,176,124,192,212,104, 52, + 72, 72, 72, 64, 70, 70, 6,170,170,170, 32, 22,139, 27,245, 0, 88,130,136, 15, 14, 0, 36, 18, 9, 36, 18, 9,170,170,170, 16, + 19, 19,131,220,220, 92, 72, 36, 18,136,197, 98, 0,128,144, 15, 75,254,183,211, 84, 42,213,235, 81, 81, 81,198, 54, 20, 20, 20, + 96,215,174, 93,200,206,206,134, 68, 34, 65,255,254,253,193,231,243,113,245,234, 85, 0,152,102,113,167, 1, 52,177,230,255,121, + 93,126,251,207, 0,140, 54,245,121, 7, 7,135,197, 49, 49, 49,143, 41,127,189, 94,143,242,242,114,100,101,101, 33, 53, 53, 21, +199,142, 29,211, 86, 84, 84,124, 99,105,187,196, 98,177, 62, 60, 60, 60,125,237,218,181, 73,171, 87,175,238,248,241,199, 31,119, + 99, 24, 38,211,223,223, 63,161,162,162, 66,203, 48,140, 94,167,211, 53,199, 66,206,222,183,111, 95, 77, 72, 72, 72,250,189,123, +247, 74,142, 31, 63,158,149,151,151, 87, 12,131,193,212, 14,192,109, 75,132, 8, 4,130,151,187,117,235, 38, 82,171,213, 80, 40, + 20,200,200,200,120, 76,249,215,151,185,166,148,194,219,219,219,230,206,157, 59,131, 96,194, 0, 80,171,213, 80,169, 84,184,115, +231, 14,156,157,157, 17, 17, 17, 1,127,127,127, 92,184,112, 1, 0,208,179,103, 79, 72,165,210,102, 41, 91, 66,200, 63,228,114, +121,172, 70,163,185,165,209,104,166, 3,136,153,243,238,187, 3,247,237,221, 27,180,117,203, 22,254,192, 65,131,246, 16, 66,130, + 40,165,133, 77,201, 8, 15, 15, 31,250,213, 87, 95, 1, 0,174, 95,191,142, 17, 35, 70, 60,230,253,108,137, 81, 66, 8,129, 76, + 38,131,141,141, 13,132, 66, 33, 24,134,129, 86,171,197,165, 75,151, 0, 0,105,105,105, 80, 42,149, 22,123,239, 30,197,209,201, + 37,230,243, 47,191,178, 89, 48,247, 93, 20, 21,230, 3,134, 24,143,193,127,130,242, 7,128, 79, 62,253,244,211, 1, 46, 46, 46, +109,231,206,157, 11, 0,190, 81, 81, 81,241,177,177,177,152, 59,119, 46, 54,108,216,128,213,171, 87,231, 0,248,210, 18, 97,197, +197,197,157, 8, 33,246, 44,203,102,156, 61,123,214,213,221,221, 29,114,185, 28,238,238,238,136,136,136,128, 88, 44,134, 72, 36, +130, 64, 32, 96,186,116,233, 2, 79, 79,207, 90,142,227, 44,170,192,105,229, 25, 24, 0, 44,203, 50,213,213,213,104, 88, 10,179, +164,164, 4,238,238,238,104,226,120,139,114, 19, 72, 36, 18, 12, 30, 60,216, 70, 38,147,253, 68, 8, 25, 76, 41, 61,211, 18, 57, + 0,208,189,123,119,108,218,180,201,102,246,236,217, 45, 50, 2, 52, 26,205,114,161, 80,216,227,155,111,190,177,153, 48, 97,194, + 99,239, 95,186,116, 9,145,145,145, 74,133, 66, 97,209, 26, 44, 96, 48, 0,234,221,254,245, 10,159,212,230, 67,172,173, 65,181, + 82, 15, 81,155,231, 32, 18, 89, 84,112, 12, 0,160,213,106,141,107,183,245, 10,191,184,184, 24, 58,157, 14, 90,173, 22, 97, 97, + 97,144,203,229, 22,203,123,148,150,186, 52, 41,165, 42, 66,200, 67,193,161, 12,195, 64,163,249, 35,192,156,207,231, 27,141,138, +167, 24,209,189, 7,192,187,230, 78,210,104, 52, 29,131,131,131,141,175, 43, 42, 42,144,151,151, 7,137, 68,130,182,109,219,194, +213,213, 21,158,158,158, 80, 40, 20,122, 0, 55, 44,249,226,133, 11, 23, 70,196,196,196, 92,172,127, 29, 29, 29,125,243,210,165, + 75, 2,185, 92,110, 92, 38,225, 56,142,119,237,218,181,110, 48,189,133,172, 33,251, 89,150, 29,177,106,213,170,247,213,106, 53, +167, 82,169,106, 0, 40, 0, 84, 0,152, 7, 96,175, 37, 66,244,122,125,103, 15, 15, 15, 84, 87, 87, 35, 49, 49,177, 81,229, 95, + 93, 93, 13,149,202,240,111,176,183,183, 7,165, 52,212,148, 76,141, 70, 3, 15, 15, 15, 44, 88,176, 0, 94, 94, 94, 16, 8, 4, +120,241,197, 23, 17, 26, 26, 10,173, 86,139,192,192,192,102,121, 24, 9, 33, 94,126,126,126, 71, 18, 78,159,118,142, 93,191,190, +199,250,245,235,191,165,148, 38, 17, 66, 34,223,154, 50, 37,249,196,241,227,222,235, 99, 99, 29,134, 13, 31,190,168,174,239,141, +178, 99,199, 14,156, 63,127, 30, 66,161, 16, 35, 70,140,128, 80, 40, 68, 96, 96, 32,238,223,191,255,144, 55,160, 37,200,229,114, +216,216,216, 24,149,191, 86,171, 53,198,181,132,132,132,180, 88,249,187,184,120,172,217,190,115,215,140, 82, 21, 35,178,117,112, + 41, 43,126, 80,160,166,148,122,193,176,243, 99,101,139,132, 62, 1,148,210, 66, 66, 72,228,188,121,243, 18, 0,180,153, 59,119, + 46,250,244,233,131,208,208, 80,108,216,176, 1,243,230,205,203, 1,208,167, 97,108,128, 5, 50, 43, 9, 33, 51,182,110,221,250, +195,188,121,243,160,211,233,160, 84, 42,141,202, 95, 44, 22, 35, 46, 46, 14,215,175, 95, 79, 0, 48,224,175,180, 27,229,175, 78, +147,202,246,105, 46, 1,200,100, 50, 28, 63,126, 28, 23, 46, 92, 64, 70, 70, 6, 56,142, 51,121,188, 37,136,197, 98, 56, 56, 56, + 96,194,132, 9,178,240,240,240,237, 45, 22, 4,192,214,214, 22,189,122,245, 66,116,116,180,141,173,173,237,214,230,126,158, 82, +122, 78,171,213, 14,156, 58,117,170,114,229,202,149, 56,123,246, 44, 82, 82, 82,140,174,225,200,200, 72,165, 82,169, 28, 72, 41, + 61,103,169,204,234,154, 90, 16, 66, 32, 18, 9, 33,228, 1,114, 77, 6,162,254,217, 15, 31, 44, 27,137, 37, 75, 7, 67, 95,116, + 30,132,179, 92, 23,234,116, 58,136,197, 98,136,197, 98, 48, 12,131,156,156, 28, 76,152, 48, 1, 43, 87,174,196,135, 31,126,136, +212,212, 84,212,214,214, 54,183,235,127,103,236, 96,112,157,154,132, 82,250,245,230,205,155,181,128, 65,249, 95,184,112, 1,105, +105,105, 40, 42, 42, 2, 33, 4, 33, 33, 33, 24, 52,104, 16, 70,143, 30, 45,144, 72, 36,147, 45,249,226,105,211,166,165, 46, 92, +184,176, 87, 70, 70, 70,235, 71,223,227, 56, 14,213,213,213,190,151, 46, 93,234,213,182,109,219,235, 48, 84,224,179,132, 24, 0, +252,138,138,138,101,117, 1,107, 90, 0,126, 0,254, 15,128, 45,128,181,150, 8, 33,132,232,139,138,138,154, 84,252, 13,149, 63, +128,122, 69,102,242, 70,214,106,181, 16, 8, 4,104,219,182, 45,108,109,109,141, 99,137,143,143,143, 81,249,215, 43, 92, 11,218, + 39,178,177,177, 57,180,127,223, 62,103,161, 80,136, 35, 71,142, 84, 1,184, 78, 8,145, 0,112,204,203,203,251,233,192,129, 3, +232,220,185, 51, 0, 4,154,147,215, 80,209, 7, 6, 6, 26,143, 61,137, 7, 0,128,209, 3,240,218,107,175,225,248,241,227,208, +106,181, 88,180,104, 17, 14, 28, 56,128,247,222,123,175, 69, 6,179,187,187,231, 39, 59,118,237,156,195, 9,229,162,207, 87,199, +148, 22,229,223,143,166,148, 6, 1,152, 5, 32,182, 69, 13,125, 10, 80, 74,115, 1,188, 25, 21, 21,133,148,148, 20,132,134,134, + 34, 37, 37, 5, 81, 81, 81, 0, 48,153, 82,154,221, 2,153, 63,254,246,219,111, 63,220,184,113, 3, 2,129, 0,124, 62,223, 24, + 67,114,250,244,105, 68, 71, 71,167, 1, 24,110, 85,254,205,227,153, 24, 0,128, 33,216,207,201,201,201,248, 48,119,188,185, 72, + 36, 18,216,219,219,227,212,169, 83,181,201,201,201,150,174,147, 54,138,173,173, 45,110,220,184,129,117,235,214,213, 84, 87, 87, + 79,106,137, 12, 74,233, 57,141, 70, 51,112,217,178,101,202, 27, 55,110, 64, 42,149, 34, 57, 57, 25,111,188,241, 70,179,149, 63, + 0,212,170,213, 16,242,121,112, 17, 41,208,193,177, 28,139, 63, 30, 11,149, 40, 5,233, 89,231,144, 93,124, 17,195, 38,116,192, +253,235,113, 22,203,227, 56, 14, 2,129,192, 24,132,180,106,213, 42,120,121,121,161,188,188, 28,181,181,181,152, 53,107, 22,226, +227,227,155,221,239,191, 49,111, 3, 48, 91, 86, 89,165, 82,125,177, 99,199, 14, 85,191,126,253,170, 63,255,252,115, 36, 37, 37, + 33, 59, 59, 27, 90,173,214,120,142, 64, 32,192, 75, 47,189,196, 99, 24,230,101, 75,190,216,223,223, 95,185,121,243,230,211,174, +174,174,165,111,191,253,118,223,175,191,254,186, 61, 0,100,101,101,181,187,122,245,106, 31,145, 72, 84,214,189,123,247,211, 50, +153,204, 98,139,172, 46,240,107,212,200,145, 35, 59,127,252,241,199, 63,204,156, 57, 51, 29,192, 41, 30,143, 23, 14, 96,188,165, +129, 97,132,144,171, 25, 25, 25, 40, 47, 47, 55,171,252, 1,160,178,178, 18, 12,195, 92, 53, 37, 83,171,213, 34, 47, 47, 15, 7, + 14, 28, 64, 82, 82, 18, 8, 33,143,237, 50,202,202,202,178,180,171,171,255,245,175,127, 61, 23, 22, 22,134,205, 95,126, 9, 91, + 91, 91,155,176,176,176, 7,125,250,244,169,125,253,245,215,211,151, 47, 91, 54,115,234,212,169,200,206,206, 6, 0,179, 46,113, +129, 64,128,171, 87,175,162, 99,199,142,198, 99,238,238,238,112,114,114, 50, 26, 43, 45,193,214,214, 22, 12,195,224,238,221,187, +184,123,247,238, 67, 59,111,234, 61, 2,205,193,203,171,213, 71,219,119,238, 92, 96,227,232, 46, 90, 29,179,180, 44, 39,243,246, + 7,138,202,178,111, 40,165, 85,148,210,205,127,166, 34,172, 11,248,219,185, 97,195, 6,132,134,134,226,234,213,171, 8, 13, 13, + 69,108,108, 44, 0,236,168,123,191,217, 80, 74,103,125,241,197, 23,213,245, 99, 87,253, 50,224,236,217,179,115, 89,150, 29, 64, + 41,109,110, 60,208,255, 60,102, 13,128,166,162,255, 5, 2, 1, 24,198, 50,111,125,126,126,190, 81,193, 59, 58, 58, 26,173,232, +166,142,183, 4,177, 88,140, 19, 39, 78,212,110,221,186,245, 85, 74,233,201, 22, 11,130, 97,253,111,226,196,137,202,154,154,154, + 65,205, 85,212, 13,161,148,158, 83,171,213, 3,163,162,162,148, 59,118,236,192,228,201,147, 91,164,252, 1,192, 91, 90,142, 30, +237,244,120,115, 92, 4,198, 77,235,132,236,162, 68,168,213, 26,104,181, 44,180, 26, 22, 85,213,165,232, 55,196,211, 98,121, 90, +173, 22, 54, 54, 54, 24, 61,122, 52, 22, 45, 90, 4,150,101,193,113, 28,244,122,189,113, 11,224,180,105,230,150,215,169, 70, 79, +120, 10,127, 7,166,122,219,182,109, 80, 42, 27, 79,246,167,213,106,113,230,204, 25,248, 59, 48,213, 0,209,130, 82,115,174,158, +220,147, 39, 79,130, 82,138,178,178, 50,124,242,201, 39,248,233,167,159,112,246,236, 89,163, 87,226,230,205,155, 0,144,107,105, +127, 9, 33,217,132, 16, 90,247,200,174, 59, 70, 8, 33,255, 32,132,252, 27, 64, 56, 44,112,153, 82, 74,243, 85, 42,149, 91,124, +124,252,204, 13, 27, 54,220, 88,189,122,181, 46, 62, 62,158,147,201,100, 96, 89, 22,153,153,153,184,120,241, 34, 10, 11, 11,161, + 86,171,155, 21, 45,238,224,224, 80,243,213, 87, 95,157,114,112,112, 80,103,103,103,135,136, 68, 34, 85, 88, 88,216,105,161, 80, + 88,211, 28, 57, 13, 24,236,231,231, 39, 91,178,100, 9,162,163,163,177,113,227, 70, 56, 58, 58, 58, 0, 24,108,169, 0,141, 70, +243,243,157, 59,119,106,175, 93,187,214,164,242,231,243,249,112,117, 53,164,138,200,201,201,169, 81,171,213, 38,115, 31,148,151, +151, 99,211,166, 77, 56,117,234, 20,190,249,230, 27,252,246,219,111, 15,141, 51, 43, 86,172,192,244,233,211,113,244,168,201,152, + 61, 0, 64, 80, 80,208,232,215, 95,127, 29, 12,143,135, 15, 63,248, 0, 73,137,137,252,164,196, 68,155, 35,135, 15,227,235,175, +190,194,140, 25, 51, 16, 23, 23,135, 81,163, 71,223,133, 5,187, 30,158,196,205,111, 14, 30,143, 7,127,127,127,180,110,221,218, +168,244,163,162,162,176, 96,193,130,135,150,184,204,225,229,229,179,224,139, 77, 27,163, 61,125,218,138,150, 45, 93, 84,118, 59, + 61,237,227,202,242,146,191, 68,178, 31, 66,136, 39, 33,228,244,166, 77,155,124,231,204,153,131,216,216, 88,132,135,135, 99,195, +134, 13,152, 59,119, 46,214,175, 95,239, 11, 67,192,173,119,115,101, 83, 74, 11,243,242,242,162,182,111,223, 14, 62,159,143,204, +204, 76,252,243,159,255,172, 84,171,213, 47, 53,103, 73,193,202, 31, 52, 26, 3,240,224,193, 3,179, 51,127, 75,149,191, 80, 40, +212,123,123,123, 55,150,241, 15,222,222,143, 95, 3, 98,177,184, 69, 65,128, 23, 46, 92, 72,188,123,247,238,167,148,210, 95, 91, +242,249,122, 46, 93,186,132, 9, 19, 38,180, 88, 81, 63, 10,165,244, 28, 33,100,224,166, 77,155,118,214,214,214, 78,106,169,204, + 17,175, 7,161,168,252, 14, 20, 53,105, 40, 42,211, 25, 21,191, 86,203, 25,159,235,137,229, 75, 40,115,230,204,129, 74,165,130, + 74,165,130, 70,163,121, 72,241,215, 63, 55,107,144,233,153, 66, 70, 98,127, 97,207, 80,206,238,139, 43, 59, 42,222,153,176, 63, +160,207,176,215,164, 99,199,142, 5, 96,136, 3,184,124,249, 50,138,238, 94,171,157, 29,194,166,207, 30, 42, 44,128,141,219,113, + 24,246, 38,155,226,149, 37, 75,150,172,223,190,125,251, 11,195,134, 13,195,204,153, 51,241,252,243,207, 35, 46, 46, 14, 91,182, +108,193,173, 91,183, 80, 82, 82,114, 6, 38,214,115, 27,193,183,193,254,127, 95, 66,200, 97, 0,161, 0, 42, 1, 28,128, 97, 86, +108,209, 52,172,110,118,245, 29,128,239, 8, 33,222,231,207,159,191,145,152,152, 40,103, 89, 22,217,217,217,200,201,201,193,169, + 83,167,192, 48,140,217, 93, 0,124, 62,255, 90, 96, 96,224, 71, 51,102,204,216, 87,127,108,236,216,177,185, 7, 14, 28, 72,149, +203,229,249,245,199,210,211,211, 3,210,211,211, 71,215,109, 89,180,148,223,211,210,210,132, 43, 86,172, 64, 89, 89, 25, 54,110, +220, 8, 0, 98, 24, 18, 4, 89, 4,199,113,187, 50, 51, 51, 23,221,186,117,171,131, 74,165,130, 72, 36,130, 82,169, 52, 42,127, +145, 72, 4, 79, 79, 79,104,181, 90,148,149,149, 33, 51, 51, 51,151,227,184, 61,166,100, 50, 12,243, 80,178, 31,149, 74,101, 28, + 87,106,106,106,144,144,144, 0, 0,112,118,118, 54,219,190, 91,183,110, 29,143,139,139,155, 60,108,216, 48,172, 89,179, 6,231, + 19, 19, 65, 8, 65,113,113,177, 54, 63, 63,191,160,160,160, 32,139, 82,250, 27,128,207, 44,217, 91, 47, 16, 8,208,179,103, 79, + 20, 22, 22,194,195,195, 3,128, 33,104, 81, 32, 16, 52,154,180,168, 57, 48, 12,131,207, 63,255,252,161,124, 7,245, 65,208, 90, +173,214,162, 56, 0, 66, 72, 80,239, 62,145, 11,130, 58,119,145, 44,152, 59,167,236,122, 74,202, 39,229,165,197,155,158,168, 97, + 79,151,153, 75,150, 44,241,157, 57,115, 38,214,174, 93,139, 69,139, 22,221, 5, 48,113,222,188,121,123, 0,248,205,157, 59, 23, + 37, 37, 37,190,159,126,250,233,251, 0,102,154, 19, 70, 8, 25, 6,192, 6,134,229,185, 56, 74,233, 54,103,103,231,216,223,127, +255,221,182,170,170, 74,175, 80, 40, 6, 82, 74, 51,154, 56,215, 90,235,222, 12,143, 25, 0, 12,195, 24, 47,124, 75, 48,103, 8, +104,181, 90,134, 30,142,198, 79,108,132,113,224,200,207,207,199, 71, 31,125,132, 38,142,183, 40, 8,240,206,157, 59,102,147,163, + 88, 66, 75,214,231,205, 81, 39,171,173,217, 19, 77,144, 95,154, 10,101,173,178, 78,233,179,198,191,154, 58, 35, 64, 83,119,204, + 82,180, 90,173, 49,225,207,163,138,191,225,107,147, 8,170, 10,224,228,127,158, 47, 44, 40,141,234,254,160,199,156, 46,154,252, + 47,174,124,227, 53,117,252,190, 64,103, 31,127,113,193,157,107,234,249, 97,220,205, 89,111,242, 11,120, 2,155, 28,216,186,159, +135,189,251,117,204, 56,109,210, 21, 75, 41, 77, 6,208,155, 16,210, 47, 54, 54,118, 93,215,174, 93, 67,235,131, 2,207,156, 57, +147, 2, 96, 65,221,160,222, 44, 40,165, 90,189, 94,207,192,112,221,127, 9,224, 22,165,212, 98, 95,115, 19, 50,243, 8, 33, 3, +223,123,239,189,223, 70,142, 28, 41,145, 72, 36,184,126,253, 58,174, 92,185, 82,203,113, 92,148,185,207,179, 44,219,165,162,162, + 98,242,154, 53,107,150,219,217,217, 85,117,239,222,253,254,200,145, 35,141,138,191,160,160,192, 43, 63, 63,255, 69,157, 78, 39, +167,148, 46,129,193,240,176,148,136,142, 29, 59,106,151, 44, 89, 34,124,240,224, 1, 2, 2, 2, 16, 19, 19,163, 46, 41, 41,137, + 0,144,106, 97,255, 56, 66,200,168,132,132,132, 4, 30,143,231,228,224,224,240,144,162,178,181,181,133, 90,173,198,237,219,183, +145,144,144, 80,166, 86,171, 71, 83, 51, 30, 30, 62,159,143,247,223,127, 31,241,241,241,240,240,240,192, 43,175,188, 98,244, 54, +186,184,184,160, 87,175, 94,240,241,241,193,128, 1, 3,176,112,225, 66,147,237,211,235,245,179,222,124,243,205,110, 73, 73, 73, +129,111,190,245, 22, 54,109,222, 92, 84, 80, 80,208, 5, 64, 65, 75, 20, 64, 67, 79,132, 66,161,128, 92, 46,127, 42,202, 31, 48, +120, 0, 56,142,123,232,177,116,233, 82,163, 65, 96,238, 59, 8, 33,164,181,159,223,190,101,203, 63,113,155, 54,105, 66,209,157, +204, 59,171, 74, 74, 30,108,120,226,134, 61,101,242,242,242,176,104,209, 34,172, 93,187,246, 46,128,200,186,123, 36,114,222,188, +121, 9, 15, 30, 60,104, 93, 94, 94, 14, 88,190,125,215,134, 82,250, 61, 33,100, 28,128,113,132, 16,120,120,120,224,246,237,219, +240,245,245,173, 5,224, 71, 8,241,171, 63,185,238,220,177, 48,120,183,173,219, 1,205,208,120, 38,192,195,209, 88,146,200, 3, + 33, 4, 12,195, 24, 31, 13, 95,215, 63,143,142,142, 54,155, 9,112,227,198,141,200,202,202,122,104,157,239,131, 15, 62, 64, 83, +199,255,172, 76,128,118,118,118,191, 42, 20,138,229, 79, 83,249, 63, 13,120,124,193, 3, 61,247,120, 61,133,198,224, 11, 68, 69, + 58,173,233, 90, 10,130, 38,234, 51, 52,134,249,218, 12,132, 96, 91, 63, 87,104,225,131,234,252,246, 80, 60,120,158,213,105,124, +191, 79,103, 93,198,119,224,151,240, 4,162, 28,200,221, 19, 97,235,117, 7, 66,220,199,212,223,138, 1,203, 7,102, 66, 72,107, + 39, 39,167,131, 34,145,200, 79,163,209,100,150,149,149,141,106, 73, 16,209,127, 34, 5,240, 35,242, 95, 20,137, 68,239,235,116, +186, 8, 66, 72, 26,199,113,171, 40,165, 22,215, 2, 32,132,136, 25,134,153, 77, 8,121,175,125,251,246,201, 12,195,228,221,191, +127,223, 75,169, 84,134, 81, 74, 87, 1,216,212,220,117, 93, 66,136,155,157,157,221,175, 85, 85, 85, 33, 48,236, 30,160, 2,129, + 32, 85,167,211, 13,160,148, 22, 53, 83, 86,128, 88, 44,254,161, 93,187,118,190,173, 90,181,178,169, 79,248, 84, 81, 81,129,220, +220, 92,229,221,187,119,115,212,106,245,171,245,179, 49, 19,114,232,222,189,123,141, 1, 92,166,150, 24, 5, 2, 1,252,253,253, +205,142, 7,132,144,246,193,193,193, 87,146,146,146,108, 87,174, 92,137, 79, 63,253,180, 59,165,244, 66,115,250, 87,223,182,130, +130,130,199, 18,255, 60,170,152, 25,134,105,214, 24,197,231,243,117,165,165,165,124, 75,182,213,202,229,114,147,153, 0,125,125, +125, 47,240,249,124,233,189,123,247,198, 81, 74, 45,218,101,242, 44, 33,132,200, 0,141,246,174,216, 0, 0, 32, 0, 73, 68, 65, + 84, 44,132, 33, 85,247, 10, 74,233,131, 6,239,121,194,144,115, 67, 80,247,158,217, 76,128, 13,102,245, 58, 0,135, 40,165,172, +171,171,235,165, 71, 19,254,212, 5,125, 14,174,147,109,245, 0, 88, 72, 99,197,128, 56,157, 78,103,241, 44, 92, 40, 20,234,235, +114,149, 55, 74, 83,202,166,169, 98, 64, 2,129,160, 72,171,213, 90,139, 1,253,237,104, 96, 8, 40, 11, 91,131,213, 72,193, 23, +213,194,198, 35,187, 37,138,255, 97,201,196, 22,134, 89, 59, 75, 41,109,180,134,192,127, 11,132, 16, 59,134, 97,222, 7, 48, 77, +175,215,255, 11, 22,166, 76, 53, 35,243, 99, 0, 31, 1,136,161,148,126,252, 4,114,120, 60, 30,239, 13,145, 72,244, 50,165, 52, +172, 46,158,226,170, 90,173,254,133,227,184,239,204,205,252,129,230, 23, 27,179, 52,237, 46, 33, 36,210,219,219,251,171,178,178, +178,116,149, 74, 53,170, 37,217,239, 8, 33,180,180,180,244, 33,195,164, 49, 15,103,115, 13, 0, 91, 91,219,219, 42,149,170,141, + 37,231,138, 68,162,162,218,218, 90, 95, 83,191, 37,105,152,207,250,127, 0, 98, 40,106,213, 13,134,221, 43,231, 40,165, 53,143, +188,223, 30, 64, 39, 0,119, 0,220,160,148,182,104, 25,249,127,145,199, 12, 0, 43, 86,158, 12, 66,240,109, 15, 25,168, 76, 0, +173,146,226,237,115,149, 45, 85,252, 86,172, 60, 75, 36, 18,201, 3, 75, 2, 55, 37, 18, 73, 81,109,109,173,117,146,242,140, 33, +132, 4, 0,168,223,158, 33, 6,160, 6, 80, 3,195,214,216, 75,214, 93, 0,205,199,106, 0, 88,177, 98,197,138,149,191, 5,132, + 16, 23, 0, 47, 54,136, 11, 72,166,148, 90,148,213,210,202,227,180, 40,224,206,138, 21, 43, 86,172, 88,121,214, 80, 74, 75, 0, + 40, 9, 33,175, 1, 80,193,224,246,183,210, 66,172, 30, 0, 43, 86,172, 88,177, 98,229,127, 16,171, 7,192,138, 21, 43, 86,172, + 88,249, 31,164,201, 98, 64,255, 81,142,182, 23, 65,168,176, 7,129, 12, 20, 53,208,202, 43, 49,232,142, 53,135,179, 21, 43, 86, +172, 52,131,186, 8,121, 87, 0,229,150, 36, 58,178, 64,158, 11,128, 14, 0,210,235,220,237, 86,254,139,121,182, 6,192,129, 96, + 33,236,203, 67,192,231, 90,113, 26,165, 61, 15,172, 45, 7,126, 53, 79,128, 74,156,240,204, 69,165, 99, 42, 70,167, 53, 47, 41, +246,223,140,186, 27,118, 32,195, 48,111,184,184,184, 12, 44, 41, 41,217,201,113,220,236, 63,187, 93, 86, 12, 16, 66,150,201,229, +114,125, 85, 85,213,199,127, 98, 27, 14,227,143,116,189, 71, 40,165, 67,254,172,182, 88,249,107, 66, 8,113, 2, 16,232,226,226, +210,254,185,231,158, 19,100,102,102,130, 16,242, 0,192,233,150,108, 27,173, 75,166,179,179, 99,199,142, 61,219,181,107,135,244, +244,116, 16, 66,206, 1,152, 68, 41,189,247,180,219,255, 36, 16, 66, 28, 0,136, 26,230, 24,176,210, 50,158, 93, 12,192,105, 87, + 25,116,130,231,149,181, 21, 65, 31,252,159,221,140, 31,207,215,186,230, 23, 41,109,189,221,100, 53,175,244,148, 22,175,120,189, +242, 75,137,216,225, 38, 4,186, 68,244, 41,182, 40,247, 57, 33,132, 39, 21, 11, 38,185,136, 5, 67, 53, 28, 23, 70, 1, 8, 9, + 82,202, 84,236,225, 90, 29,183,221,146,125,201, 0, 96, 35, 36, 57, 26, 22,127, 36,210,127,108,135,239,195, 7, 68, 2,166, 64, +169,102,125, 31, 61,203,130,246,190,224,226,226,114,160,123,247,238,174,245,229,118,191,249,230, 27,220,186,117, 75,106, 73, 89, + 91, 66, 8, 95, 32, 16, 79, 22,203,100,195, 56,142,237, 12, 16,202,240,120, 87, 53,170,154,159,117,106,245, 46, 75,247, 62,135, +184,144,222, 66, 6,111,114, 20,251,175, 22,211, 95,120, 60, 94,180, 94,175, 95,245,232,121,124, 62,127,129, 78,167,251,172, 73, + 65, 81,196, 11, 20,173, 65,234, 12, 73, 6, 28,244,200, 66, 44,205, 39,132, 8, 41,165, 90, 68, 17, 47, 24,170,208,137,234,206, +209, 66,143, 76,196,210,252, 38,229, 62,220,231, 46, 98,177,120, 33, 33,164,155, 70,163,241, 22,139,197,121,148,210, 11, 42,149, +106, 45,165,244,138, 37, 50, 44,133, 16,242,150, 76, 38,251, 40, 45, 45,109,167,175,175,239,135, 22,156, 47,227, 51,204, 28,123, + 57,243,146, 90, 75, 59, 3,128, 88,200,191, 86, 89,163, 59,193,178,250,207, 41,165,141, 23, 71,120, 92,142, 59,128,175, 1, 8, + 1,204, 6,112, 55, 43, 43, 11, 44,203,162,125,251,246, 0,208, 14,192, 70, 7, 7, 7, 90, 81, 81, 49,197, 58,240, 61, 91, 54, +255,152, 56, 14, 60, 18, 5, 16, 59, 0, 26, 66,233,230,119,134, 71,252,235,207,106, 15, 33, 68, 36, 22,139,199,239,223,191, 95, +208,175, 95, 63,212,214,214,162,166,166, 6,113,113,113, 88,186,116,169,174,186,186,250, 96,115,140, 0, 66,136,159,189,189,253, +181, 29, 59,118,200,134, 15, 31,142,154,154, 26, 84, 87, 87,227,208,161, 67,136,142,142,174,169,174,174,238,252, 87, 50, 2, 8, + 33,135,218,182,109, 59, 52, 51, 51,243,123, 0,107, 41,165,215,254,236, 54,253, 93,121, 70, 30, 0, 66,192,122,134,170,149,165, +207,247,136,182,153,173, 35,226,178, 21, 49,139,142,245,232,209, 21,231,207,196, 99,221,198,157,207,247, 88,168,253, 40,113, 85, +241, 6,177,204,181, 22, 32,231,205,237, 29, 39,132, 4,120,200,197, 63,190,221,167, 99,235,225,221,131, 37, 1, 94, 78,160,101, +121,184,118,227,150,239,207,105, 15, 94,250, 54,173, 50,138, 16, 50,194, 92,102, 50, 0,168,213,193,135, 43,188, 1, 34,117, 0, + 52, 53,134,135,214,240,151,173,173, 4,163, 85,129, 97, 13,175,213,119,147, 32,125,251,176, 79,243,127, 1,194,119,115,115, 59, +176, 98,197, 10, 87,134, 97,112,245,234, 85, 28, 57,114, 4, 25, 25, 25, 27, 45, 84,254,157, 37,182,118,251, 59,246,248,127,246, +206, 59, 60,138,234,235,227,223, 59,179,187, 51,219,201,166, 16, 2, 33,161,165,208, 67,145,132, 14, 82, 84,164,189, 32,168, 88, + 64, 64, 17, 21, 80,192, 14, 82, 68,252,129, 32,160, 8, 8, 10, 2, 74,137, 40,160, 64, 0,105, 82,162,212, 16, 32, 1, 82, 32, + 33, 1, 66,250,246, 50,187,247,253, 99,179,107, 2, 41,155,208, 44,251,121,158,121,118, 51, 59,115,246,220,201,236,156,115,207, +189,247,156,190,245,106,251, 23,200, 24, 82, 8,223, 58,237,225, 16, 69,132, 36,157, 60,218, 39, 41,254,183,169,132,144,167, 40, +165, 85,230,159,151, 48, 24,126,120, 56, 94,236,249, 35, 68, 0,118,138, 68,162,103, 86,173, 90,133,231,159,127,222,125,204, 79, + 63,253,132,231,159,127,126, 20,128,138, 29, 0, 6, 13,224,192,123,148,194, 7, 0,244,102,152, 30,219,130, 11,199, 62, 39, 29, + 1,180, 37,132,156,234, 24,132, 99,113,131,209, 92,193,137, 36, 0, 64,168,160, 3,197,199, 0, 42,117, 0, 8, 33, 34,137, 68, + 50,167, 94,189,122, 19,150, 47, 95,206, 71, 68, 68, 64,161, 80, 32, 59, 59, 59,244,212,169, 83, 33,211,166, 77, 27, 32,147,201, +190, 48,153, 76, 31,212, 36,233, 75, 57,223,215,139,227,184,185,137,137,137,138,144,144,144, 42, 19,137, 16, 66,122, 40,229,236, +134, 69,159, 76,244,233, 55, 96,176, 68, 19,208, 0,118,107, 17, 50, 83, 19,186,255,248,243,238,152, 79, 23,111,158, 64, 8,121, +134, 82,234, 73, 73,197,229, 91,182,108, 25,168, 84, 42, 49,116,232,208,139,205,155, 55,135, 92, 46,199,198,141, 27, 17, 20, 20, + 4,157, 78,119,113,205,154, 53, 34,171,213,138,215, 94,123,237, 27, 84,163,152, 79,137,174,143,170, 84,170,183,139,139,139,251, + 2, 0,190,232, 81, 15, 34,212,131,128, 44,188,113, 32,203, 83, 57, 95,109,139,127,133, 18,242, 26, 0, 14,160,197,176,211,133, +175, 13,238,184,177, 58,186,220,111,120,158,191,105,177, 88, 42, 92,203,239,105, 98, 33, 94, 68,110, 90,236,168,221,174, 71, 63, +116,234, 55, 12,163,250,119, 67,171,176, 16,156,189,156,129,213,191, 28, 90, 30,221,119,222,242, 63,247,108, 5,199,146, 28,179, +224,120,208, 57, 1, 90, 45, 92,184, 80,220,191,127,127,196,197,197, 97,251,246,237,232,208,161, 3,122,244,232,129, 81,163, 70, +137,151, 44, 89, 18, 14,224, 68, 53,228,189,244,225,135, 31, 42, 6, 14, 28,232,150,215,185,115,103,244,234,213, 11, 99,198,140, + 81,124,254,249,231, 47, 1,248,240, 62,181,165, 38,212,122,246,217,103,153,252,252,252, 17,199,142, 29, 27, 33, 18,137,246,149, +100,222,188,171, 34,112,255, 69, 30, 76, 4, 32,174, 78, 40,136,174,203, 91,223, 42,166,239, 73,224,113,254, 98,154, 15, 64, 57, +152,115,146, 32, 20,235, 97,201,185,249, 72,239, 87,122,116,141, 52,153, 62,123,177,112, 6,168,242, 48, 30,187,113,181, 66,165, + 9,105,222,192, 87,190,255,192,220, 87,253, 67,186, 13, 6,124,130, 0, 85, 0,232,145,245,192,173, 52, 32,249,119, 36, 37, 39, +163,127,156, 54,247,138,158,246,172,202, 40, 18, 66,168,163, 40, 27,248,164, 49, 32,226, 1,177, 20, 16, 75,113,252, 38,240,204, + 15, 89,200, 44,178, 98, 92,215,122,248,226,249, 54,128,136, 7,243,226,166,106,167, 43, 38,132,180, 24, 48, 96, 64,226,168, 81, +163, 48,113,226, 68, 71,102,102,230,124, 0,223, 81, 74,147, 61, 57, 87,169, 9,216, 63,240,165,225,126,207, 62, 53, 6,188, 88, +132,236, 27,215, 32, 85, 4,192,108,103,144,152,120, 12,191,255, 22,139,243, 71, 19, 11,244,133,249,221, 42,107, 47,203,178, 25, + 82,214, 81,223, 95, 10, 20,152, 1,173, 21,144, 72, 36,150, 17, 35, 70,112,114,185, 28, 28,199,129,227, 56,176, 44,139,133, 11, + 23, 90, 12, 6, 3, 39, 18,137,114, 5, 65, 8,186,195,208,190, 69,186, 81,138,185,228,115, 26, 3, 0,123,134,243,216,172,124, + 14, 3, 6, 12, 64,167, 78,157,112,244,232, 81,108,223,190, 29,195,116,235,209,103,147,115,120,146,190, 73,226, 9,193,123, 88, + 72, 15, 85,214,102,142,227,254, 55,104,208,160,137,223,124,243, 13,119,249,242,101,228,228,228, 96,255,254,253,168, 83,167, 14, +234,213,171,135, 22, 45, 90,224,233,167,159, 54,165,164,164,124, 97, 52, 26,223,241,224, 95, 80,217,245,109, 38, 18,137, 14, 28, + 58,116, 72,212,177, 99, 71,159,188,188,188,153,126,126,126, 51, 42, 57,190,103, 68, 88,253, 95,143,236,219, 44,149,242, 18,172, +254,230, 43,124,255,227,239,112, 56, 28, 24,208,183, 13, 70, 62,219, 23, 57,183, 10,241,196, 51,115,140, 55,111, 21,246,167,148, +238,175,226,251,119,126,244,209, 71,143,199,196,196,160, 65,131, 6, 96, 89, 22,233,233,233,200,204,204,132, 84, 42, 69, 72, 72, + 8,212,106, 53,126,248,225, 7,204,157, 59,119, 23,165,212,163, 50,195, 37,178,123,203,100,178,173, 70,163, 81,230,190,103, 87, +244,138,161, 41,135,214, 56,252, 26,207, 96,253, 67,118, 99,116, 92, 65, 69,231,243, 34,230,166,197, 78,107,119,232, 51, 8,209, +125, 6,223,110, 8,113,116,199,102,156, 60,176,163, 90,134,240, 94, 25,233,242, 32,132,208,196,196, 68,176, 44, 91,238, 86,175, + 94, 61,143,126,187,132, 16,106,202,205,196,247, 39,110,224,209,168,198, 8, 13,212,184, 63,187,114, 61, 23, 91,118,237,195, 0, +243, 14,132,191,190,254,129,167, 46, 39,132,116,239,214,173, 91,216,203, 47,191,140, 23, 94,120, 65,111,183,219, 19, 0,180,220, +181,107,151, 10, 0, 6, 14, 28,104,180, 90,173,223,123,146, 45,144, 16,194, 74, 36,146,204,107,215,174, 5,233,116, 58, 52,105, +210, 36,149, 82, 58,147, 16,242,209,222,189,123, 27, 3,192, 99,143, 61,118, 93, 16,132,250,158, 70, 84,239, 37,132,144, 79, 1, +116, 3,240,129,235,119, 68, 8, 57,248,238,187,239,118,115,101,108,212,235,245,136,143,143,199,137, 19, 39,206,153, 76,166,151, + 41,165, 30, 23,187,250,175,227,113, 4,160, 93,187, 87,196, 39, 79,174,176,213,232, 91,196,240,135,201,210,244,231,163,172,223, +220,217,239,238, 5,165, 79,192, 94, 40,135,246,240, 35,176, 21, 2,108,208,111,211,222, 28,150,246,214,135, 95,181,254,236, 89, + 75, 83, 72,149, 23, 1, 92, 45, 79, 20, 33, 68,228,175,144,196,238,159, 61,198, 63,164,215,211, 64,112,115,224,218,121,208,115, +123,156,198, 95,151, 15,168, 3,208,212,239, 42,126,234, 92,236,223,231, 0,126, 36,132, 52,175,178,151,104,209,193, 0, 30,125, +215, 25,240, 74, 7, 9,158,127, 68,134,101,127,222,192,149, 2,231,220,196, 21,191,103,225,179, 23, 98,192, 73,100, 53,186, 4, + 0, 50, 51, 51, 51,173, 50,153, 76, 18, 29, 29,205,100,102,102,166,121,104,252,197, 82,149,250,231,222, 67, 59,248,153,180,199, +145,150,210, 2,141,194,186,129, 87,214,133,222,108,197,153,211,113, 56,245,231, 54, 20,229, 95,131,127,136, 92, 99, 23,108,191, + 16, 66,154, 84,212, 94, 74,105,208,172, 79, 23,224,194,133, 11, 56,127,254, 60, 34, 34, 34,192, 57,113, 27,127,158,231,193,113, + 28,230,204,153,195,113, 28,135,215, 94,123, 77, 3,128, 5, 80,233, 53,236,209,163, 7,250,140, 91,229,254,123,192,128, 1, 24, + 48, 96, 0,172,203, 60,238,100,186,218,220,182, 94,189,122, 19, 86,174, 92,201, 29, 60,120, 16, 6,131, 1,114,185, 28, 26,141, + 6,147, 39, 79,118,181, 3,107,215,174,149,118,233,210,229, 13, 66,200,230,154, 14, 7, 16, 66, 2, 89,150,221,185,110,221, 58, + 71,199,142, 29,125, 50, 51, 51,113,245,234, 85,116,237,218,181,162,227, 85, 10, 25,187,241,216,254, 88,169,143, 56, 29, 69,151, +215,227,227,207,246,225,102,158,211,193,201,184,118, 3,227,135,213, 71, 84,120, 19,252,188,102,146,172,215,208, 79, 54, 18, 66, + 26, 87, 17,146,125, 99,246,236,217, 23,151, 45, 91, 38, 58,123,246, 44,164, 82, 41,100, 50,153,251,213,104, 52,226,214,173, 91, +152, 63,127,190, 0,231, 16, 65,133,104, 52,154, 57, 90,173,246,109, 66, 8,196, 98,113,172, 76, 38, 27, 24, 23, 23, 39,235,218, +181, 43,240,117,215, 58, 16,152,122, 96, 24,134, 74,228, 7,152,252,180,169, 80,214,190,138,216, 97,199,241,212,230,114, 31,238, + 22, 59,173,109,202,203,196,215,191,103, 96, 64, 76, 83,183, 33,108, 21, 22,130,137,207, 60,142, 38, 62, 12, 54, 12,213,160,201, +107,235, 60, 78,239,107,177, 88,106, 95,186,116, 9, 12,195,148,107,164, 3, 2, 2,170, 85, 70,249,118, 74,215, 47,185,125,171, + 14, 44, 47,131,228,183,143,176, 42,241, 49,216, 88, 41, 0,231, 96, 32,235,176,160,105,225, 65, 56,124,238,122,206, 93,141,160, +148, 30, 36,132,156, 59,116,232, 80, 59, 0,169,148,210, 52, 66,136,104,235,214,173,209,163, 70,141, 66,171, 86,173,100, 39, 78, +156,240, 7,112,203, 3,113,237,187,119,239, 30, 20, 16, 16,128, 37, 75,150,128, 82,186,156, 82,186,158, 16, 82,123,203,150, 45, +159,141, 29, 59, 22, 81, 81, 81, 65, 39, 78,156,104,143,106, 84,145,188,135,140,249,249,231,159,125,191,254,250,235,125, 12,195, +100, 80, 74, 63, 4, 64,172,214,191,166,138, 41, 20, 10, 60,241,196, 19,232,219,183,111,139, 15, 62,248, 96, 22,128, 62, 15, 65, +207,127, 36,149, 58, 0,132,144,158, 62, 62, 62, 83, 65,152,142,218,226, 98,149, 88,178,154,202,100,242, 2,234,176,239,212,233, +116,159, 81, 74, 61,170, 40, 6, 48,106, 7, 21,234,102,231, 24,148,157, 98,218,179,176,220, 74,133,254, 88, 43, 16,191,243, 96, + 40,129,144, 31,208,174,105, 29, 75,230, 77,173,204, 65,237,117, 25, 48,234,138, 36,137, 89,246,185,113, 49, 13,131, 67, 59,244, + 4, 52,245,128, 75, 71, 65, 83,254, 0,244,249,128, 46, 23, 40,206, 5,213,230,194,204,240, 8,150, 19, 12,171, 79,131,191, 73, +199, 11, 0,190,173, 84, 69,139, 14,185, 86, 14,199,174, 21,162,101, 93, 27,158,239, 36, 69,159,102,254,248,238, 68, 30, 0, 96, +116,183, 70,224,164, 10, 64,204,123,214,228,219,160,148, 22, 19, 66, 22,157, 56,113,226,237,145, 35, 71, 34, 53, 53,117, 57, 33, +228, 58,165,180,210,218,233, 98, 49,247,114, 88,139,144, 80,130, 91,224, 36,106,112,242,218, 40, 50,152, 97, 48, 91, 97, 48, 91, +113,250,207, 95, 32,230,124,161,244,229,160,187,122, 30, 10, 95,117,125,193,108, 29, 9, 96, 85,101,114, 93,184,140,126, 97, 97, + 33,206,157, 59,135,212,212, 84, 68, 70, 70,162,107,215,174, 8, 11, 11, 67,169, 2, 38,119,246, 38, 40, 4, 66, 80,248,203, 32, +130,206,157, 59,195, 42, 86, 35,126,235, 86,132,135,135, 35, 50, 50, 18,231,207,159,199,238,221,187,209,245,250,117, 40,167,134, + 33, 37, 37, 5,253, 27,162, 16, 76,229, 85,186,120,158,159,186,116,233, 82,254,242,229,203,110,227, 47,147,201, 80,187,118, 89, +187,208,176, 97, 67, 76,155, 54,141,159, 51,103,206, 84, 0, 79,123,210,222,210, 16, 66,100, 34,145,104,231,244,233,211,217, 1, + 3, 6,212, 78, 78, 78, 70,102,102, 38, 50, 50, 50, 42,116, 0,120, 9, 51,105,241,167, 19,125,124,212, 60,112, 37, 22,181,212, + 42, 44,122, 63, 6, 79,191,229,140,244, 47,154,214, 23,181,124, 52,128,195,136,232,214, 33, 24,242, 68, 59,213,230,237, 39, 38, + 1,152, 85,129, 14,191, 2,232,215,161, 67, 7,244,236,217, 19,187,118,237,194,132, 9, 19,220,159, 63,254,248,227,152, 55,111, + 30,172, 86, 43, 66, 66, 66, 68,105,105,105,169,132,144, 10, 39, 6,106,181,218,183, 79,156, 56, 33, 18, 4, 1, 99,198,140, 25, +176,116,233, 82, 89,235,214,173,157, 31, 10,226, 6,142,172,211,207, 48,117,194,226,152,250, 81, 27,145,118,164, 43,110,158,239, + 7,182, 85, 38, 42, 25,146, 97, 57, 57,212,241, 11,176, 50,165, 7,236,140,235,254, 39,144, 80, 19, 90, 21,236,133, 67, 83,253, +212,235, 46,227,127,183, 70,154, 16, 82, 4,160,204,243, 98,218,180,105, 96, 89, 22, 34,145, 8, 81, 81, 81,120,230,153,103, 60, +150, 77, 8, 49, 2,144, 2, 64,143, 71,251,194,148,149, 8, 17,217, 15, 17, 11,136, 24, 2, 63, 25,139,247,186,169,193, 16, 64, + 64, 64,181,116,189,151, 80, 74,243, 1,148, 46,125,158,151,153,153, 9,192,105, 16,225,121,231,142,215,104,156, 78, 93, 90, 90, + 26, 0,184, 28,233, 83, 46,121, 42,149, 10,112,166,222,125, 40,180,108,217, 18, 43, 87,174, 68,102,102,102,200,138, 21, 43,214, +109,220,184, 81,208,106,181, 80,171,157,255,118, 87,177,166,146,242,229, 85,212, 48,247, 82,154,114,111, 18, 66,136, 68,165, 82, +173,171, 91,183,110,191, 9,147,222,148,189,244,210, 24, 82, 88,172,195,178,181, 91,201,205, 91,121,190, 17,181,217,103, 22, 46, + 92, 48, 68, 46,151,127,110, 48, 24, 60, 24, 27,162, 34, 0, 92,112,160,194,112,236,232,126, 58, 60,120,184, 25, 54, 45, 0,155, + 4,150, 91, 42, 0, 72, 74,201, 48,135, 4,169,205, 64, 1, 87,114,124,185, 4,200,217,199,135, 69,135,201, 97,210, 3,183,210, + 65,211,254, 4,138,111, 0,218, 60, 64,123, 11, 86,109, 33,204,186, 34,152,181, 69, 48,218, 40,186, 5, 64,246, 99, 22,158,132, + 7, 14, 64,168,191, 18,231, 39,171,208, 48, 80, 13,136,101,120, 38, 70,131, 46, 45, 66, 96,176,139, 16, 94, 63, 0, 16, 57,135, + 6, 60,133, 16,242,136, 82,169, 92, 96,181, 90, 47, 90, 44,150,151, 1,124, 60,111,222,188,126,139, 22, 45,106,246,241,199, 31, + 51,175,188,242,202, 58, 66, 72, 51, 74,233,141,138,100, 40,124,148, 79,107,252,236,108,131,134, 29,241, 72,204, 72,152,172,118, + 20,233, 77, 48, 90,108,208,155,173,104,223,103, 42,114,114, 50, 33,146, 40,160, 43,254, 10, 86,222,193,152,138, 77, 79,194, 67, + 7,128,231,121, 20, 20, 20, 96,251,246,237,152, 49, 99, 6, 66, 67, 67,177, 99,199, 14,172, 94,189, 26,175,191,254, 58, 34, 35, + 35,129,146, 74,114,119, 54, 16, 87,193, 96,238,128,109,120,226,207,247,157, 83, 5,130, 0,232,116, 58,204,152, 49, 3, 89, 89, + 89,144, 74,165,184,201,247, 5,207,243,248,120,219,199,160,147,240, 9, 28,229, 71,119, 74, 93,183, 14,141, 26, 53, 66,102,102, + 38,228,114,185,219, 1,232,220,185,115,153, 82,180, 50,153, 12, 29, 59,118, 36,132,144, 14,158,180,245,182,239, 96, 88,150,221, + 56,108,216, 48,191,113,227,198,213, 77, 74, 74, 66,102,102, 38,210,210,210, 80, 92, 92, 92,161, 69, 83,200,216,222, 79, 60, 57, + 72,132,252, 29, 0, 43, 5, 24, 41,134,247,107,142,238, 29,155, 2,140, 20,181, 3,252,220,251, 65, 88, 12,126,178, 19,183,115, +255,185,222,168,192, 1, 0,208, 47, 61, 61, 29,114,185, 28, 9, 9, 9,144,201,220, 17, 38, 49, 0,145, 68, 34, 49,185,140,215, +206,157, 59, 33,147,201, 16, 28, 28, 92,225, 28, 0,187,221, 46,170, 93,187, 54, 8, 33,120,231,157,119,228, 17, 17, 17, 48,155, + 75,122,170, 44, 53, 16,193,220,212,113,243,178,157, 9,110,243, 3,120,245, 79,176,232, 59,194, 78, 55,160, 18, 7,192,146,127, + 13, 97, 69,199, 16, 81, 28,143,121, 71,116,200, 55, 57, 96,119, 80,216, 29,192,110, 10, 56, 24,177,235,154, 82, 0, 38, 74,105, +149, 97, 50, 87,155, 88,150, 69,108,108, 44,206,156, 57, 3,135,195,225,254,255,150,200,114, 81, 76, 41,173, 85,129, 40,245,177, + 99,199,192,243, 60,164, 82,169,251,213,245,126,228,200,145, 24, 49, 98, 68,117,156, 11,105,101,242, 30, 13, 83,129,101, 8, 24, + 66, 64, 13,121,158,200,187,167, 72,165,210,231,205,102,115,149, 15, 33,177, 88,220, 11,192,218,170,142,227,121, 62,246,182, 93, + 7,202, 43, 75, 44, 22,139, 99, 1,248,123,170,231,189,196,106,181, 98,201,146, 37, 96, 89, 22, 11, 22, 44,192,244,233,211, 69, +171, 86,173,194,185,115,231, 16, 30, 30,254, 48, 84,250,215, 80,174,161, 85, 42,149, 43,186,119,239,222,127,227,198,141,210, 35, +167, 46,161,176, 88,135,109, 91, 54, 98,249,252, 89,232, 55,242, 3, 12, 30,254,180,232,213, 87,199,137,122,244,232, 49,145,101, +217, 44,187,221,190,188,242,175, 97,138, 25,194,100, 13,238,162,202,155,191,100,109,135,225, 3, 59,158,130, 45, 15,160, 42, 2, +123,113, 32, 8,167,251,228,203, 29,234, 65,157, 21,121, 12, 41,202, 2,152,138,139, 58, 56,104,155, 48,127, 5,160,189, 5,154, +157,228, 12,249,107,111, 65,208, 21,194,162, 43,132, 89, 91, 8,147,182, 8, 70, 93, 49,204, 14,160,142, 20,176, 58,208,166,202, + 43, 97,214, 1, 18, 25,154, 6,243,127, 25,122,177, 20,245, 2,254,154, 19,224,220, 60,115,132, 9, 33,117, 27, 53,106,180, 99, +255,254,253,126,243,231,207,239,252,229,151, 95,126, 75, 41,141, 39,132,244,120,247,221,119, 79,175, 95,191,190,222,123,239,189, +231, 51,126,252,248,183, 1,188, 89,145, 28,155,213,218,180, 78,131, 86,104,211,225, 5,104, 77, 86, 24,204, 54, 24, 75,122,255, +251,183,126,138,155,215,146, 96, 49,219, 96,179, 3,109, 31, 29,139,128,160, 8,108,158, 59,177,210,246,150,254,129,115, 28,135, +115,231,206, 97,226,196,137,152, 48, 97, 2,142, 31, 63,142,231,158,123, 14, 1, 1, 1, 56,124,248, 48, 90,183,110,237,122, 40, +223,233, 0, 56,103,242,103, 99,193,157, 15, 12,187,189,130, 78,254,231,244,104,101,186, 1,128,197, 98,169, 39,151,203,193, 48, + 12,120,158,119, 59, 0, 35, 71,142, 52,196,199,199,203,111, 63, 94, 38,147,121, 60,145,229,139, 47,190,224, 10, 11, 11,251,180, +107,215,238, 3, 74,105,227,217,179,103,251, 38, 39, 39, 35, 35, 35, 3,187,119,239, 46,142,141,141, 21, 4, 65, 40,254,248,227, +143,203, 61,223, 96,114,180,210,248,214, 1,110,222, 4, 88, 57,192,240, 0, 35, 69, 96,244,255, 0, 0,244,218, 18,167,241,103, +164, 0, 43, 69,235,150,145, 48, 24, 45,173, 42,211, 73, 16, 4,108,218,180, 9, 50,153,204,237, 0,240, 60,127, 93, 16, 4,205, +206,157, 59, 17, 23, 23, 87,230,248,170,202,202,234,116, 58, 16, 66,112,244,232, 81,180,105,211, 6, 90,109,201,232,131, 85,184, + 78, 20,126, 91, 81,124,227, 45, 80,250,179, 93,234,119,145, 53, 22,190, 2, 17,163,170, 76,158,181, 32, 11, 44,195,128, 33,192, + 45,131, 29,243, 54, 28,168,208, 64,114, 28,231,145,135, 92,186,199,127,250,244,105,140, 31, 63,222, 45,107,206,156, 57,183,203, +172, 48, 34,232,186, 30,109,218,220,121,203, 83, 74, 33, 8,130,123,104,193,211,232, 66,101,242,108, 14,184, 29, 0,230, 33, 20, + 45, 55,155,205,210,242,134,246,141, 70, 35,140, 70, 35, 44, 22, 11, 86,172, 88,129,176,176, 48,143, 30, 84,102,179,217,239,135, + 31,126, 0,165, 20, 63,252,240, 3,126,248,225, 7,215,126,152, 76, 38,152,205,102,172, 88,177, 2,141, 27, 55,246,187,183, 45, +241, 28,171,213,138,197,139, 23, 3, 0,166, 76,153,130, 90,181,106,225,131, 15, 62, 64,247,238,221,209,176, 97, 67, 0,101,159, +105, 94, 60,231, 14, 7,128, 56,107,126,142,120,247,221,119,197, 82,169, 20, 18,177, 8, 95,173,221,142, 21,243,103, 65,194, 59, +159,189, 50, 41, 7,127,127,127, 76,158, 60, 89, 49,105,210,164, 55,224, 92,194, 84, 49,118, 90,232, 96,196,233,115,134, 93,191, +216,241,125, 77,167,232, 62,175, 70, 47,120,175, 19, 26, 53,108,105, 75, 75,207,196, 71,139, 15,139,117,186, 98,251,236, 33,183, + 18, 29,140, 36,157,177,211,194,138,133, 57, 8,114,210, 64,253,130, 1, 93, 46, 28,186, 2, 88,180,133,176,232,139, 96,210, 22, +194, 84, 92, 8,163, 94, 7,179, 3, 48,219, 1,131, 13,229,153,174, 59,177,232,176,239,138, 21, 27,206,220, 66,139,250, 62, 24, +219, 51, 12, 50,137,212,237, 12,216, 24, 9,142, 36,229, 32,186, 69,227, 42, 69, 17, 66, 56,185, 92,254,243,143, 63,254,232,167, + 84, 42,177,107,215,174, 66, 0,137,132, 16, 57, 0,191, 91,183,110,253,242,219,111,191,189, 58,104,208, 32,192,153,116,163,226, +214,218, 97,118, 64,130,171,153,151,145,153,113, 1,188, 50, 24,156, 42, 24, 6,179, 21, 22,171, 13,102,179, 13, 86,171, 0,171, + 69,192,181,148, 51,168,219,160,181, 7,141,253, 11,142,227,144,154,154,138,198,141, 27,227,204,153, 51,208,235,245,208,104, 52, + 24, 58,116, 40,190,250,234, 43,240, 60, 15,148,179, 48,242,126,194,243,124, 86,122,122,122,168, 74,165, 2,203,178,144,201,100, +144,203,229, 24, 61,122,180, 44, 49, 49,241,134,193, 96,104, 70,105,101,247, 72,249,204,156, 57, 51,200,102,179, 29,207,205,205, + 85,154,205,102,229,181,107,215,240,231,159,127,210,115,231,206, 57, 86,173, 90,117, 51, 47, 47,175,144, 82,250, 6,165,244, 96, +101,114, 4, 75, 17,186, 60,189, 19,199,207,164, 2, 0, 46,236,249,107, 88, 62, 41,173, 24,205,186, 59, 67,248, 13, 67,234, 96, +223,246, 69, 85,169,181, 35, 44, 44,172, 95, 80, 80, 16, 62,251,236, 51,200,100, 50,244,233,211, 7,123,246,236,241,175,104, 14, + 87, 85, 15,187, 67,135, 14,185, 13,107,124,124,252,157,199, 19, 16,128,113,128,101,173, 20, 84, 76,236,149, 79, 98,179, 21, 94, + 7,203, 16, 16, 2,216, 28,149, 27, 72, 79, 41,237, 0,216,108,182,187,146,201,243, 60,210,210,210,202, 56, 36, 37,247, 45,236, +118,123,153,104,131, 39, 84, 38,207,102,167, 15,213, 1,248, 47, 98,179,217,144,152,152, 8,142,227, 96,181, 90, 65, 8, 1, 33, + 4, 22,139, 5,165,231, 2,120,169, 62,119, 56, 0,148, 82, 42,145, 72,198, 15, 25, 50,100,113, 66, 66,130,172,125,203, 38,248, + 54,118, 47,250,141,252, 0, 0, 80,219,175, 22, 26,213, 15, 68, 66, 66, 2,222,120,227, 13,131,193, 96,120,185,202,111,241,189, +158,198, 20, 5, 5,115,142,155, 97, 27, 38, 21,112,179, 14,116,234,246,235,233, 64, 20,252,118,177,233,215, 95,127,131, 58,190, + 60,115,240, 19,203, 17, 78, 76,210,192,249, 94, 70,173,235,105, 21,137, 98,224, 56,123,225,194,133, 70,173, 2, 27,193,106,212, +195,170, 43,114,246,250,117,133, 48,106,139, 96,212,235, 97,182, 3,150, 18, 7, 32,169, 24, 96, 8,170, 92, 39, 90,152,151,131, + 33,223,166, 64,107, 22,128,248, 27, 48,131,195, 59,255,215,206,217,227, 23, 75, 49,228,227,173,248,245,207,203, 88, 52,225,255, +170,108, 46,128, 79, 87,172, 88,209,190,117,235,214,152, 53,107, 22,252,253,253,213,254,254,254,133,181,106,213, 18, 7, 6, 6, +162,113,227,198, 24, 58,116, 40, 46, 93,186, 4, 0, 21,182, 21, 0, 8, 43, 62, 13,174, 69,208,201, 63,182, 34, 35,229, 56,172, + 86, 1,173,122,189, 13, 69,173,186,104,213,253, 21,136,226,183, 32,249,212, 30, 88,172, 2, 26,183,232,134,188,172, 43, 96,197, +226,211,158, 40, 9, 56, 31,230,145,145,145,136,139,139,131, 82,169,132,143,143, 15,124,125,125, 17, 27, 27,139, 14, 29, 58, 84, + 62, 7,224, 62, 65, 8,249,243,244,233,211, 33,125,250,244, 33,165, 29,128,225,195,135,147,139, 23, 47,106,190,254,250,235,109, +132,144,238,213,169,251, 61,115,230, 76, 63,189, 94,255,231,181,107,215, 2, 3, 2, 2,216,150, 45, 91,226,250,245,235,120,233, +165,151, 28, 86,171,181,200,225,112,204, 2,176,170, 42,153,114,153,248,236,149,212,196,206, 3,250, 68,185, 29,128, 21, 27,206, +160, 48,233, 51,128,225,241,209,103,191,186,143,237,221,179, 61, 18,206,103, 66,174,144, 85,120,255, 81, 74,159, 36,132, 52,210, +233,116, 23,131,131,131, 69,102,179, 25, 11, 22, 44, 64,139, 22, 45, 0, 0,159,126,250, 41,222,123,239, 61, 0,192, 71, 31,125, +132, 25, 51,102, 84,217,214, 27, 55,110,128, 97, 24, 92,190,124,217,253, 30, 0, 32, 17, 5, 81,125,222, 32, 34, 81,110,131, 96, +181, 16,125, 94, 56, 24,113, 18, 28,130,174, 50,121,182,130,172, 18, 7,128,192,106,167,149, 26, 72, 79, 41,221, 43,183,219,237, +119, 37,147,227, 56, 52,106,212,232,142,253,174, 8, 64,117,231, 23, 84, 38,207,106, 47, 29, 1,240,122, 0, 15, 2,171,213,138, +118,237,218, 97,245,234,213,232,220,185, 51, 66, 67, 67,113,243,230, 77,156, 63,127, 94,176, 90,173,162, 54,109,218,192,223,223, +223, 27, 5,168, 1,229,254, 34,172, 86,235, 42,157, 78,183,176, 69,139, 22,134, 47,191, 88,236,120,246,241,182,104, 25, 22,140, +152, 86,141, 48,184,123, 83,124,240,193, 7,150,206,157, 59, 27, 12, 6,195,115,148, 86, 29,210, 69, 91,106, 3,132, 68, 72,252, + 14, 44,223,229,176, 7,135, 52,102,103,205,154,133,233,211,167, 99,201,146, 37, 32, 98,133,104,249, 46, 56, 32,241, 59, 0, 8, +137,206,227,203,231,166,137,238,218,146,162, 55,234, 46, 28,133,161,168, 0,186,162, 2, 20, 23, 21,160,168,160, 0, 69, 90, 61, +180, 54, 64, 15, 9, 4,191, 6,208,218,128, 35,121, 48,235,109,216, 89,149,138, 50, 98, 1, 39,254,235,114, 88, 28, 76, 73,200, + 95,134, 28,189, 3,191,254,233,172, 56, 25,232, 95,117, 36,172, 89,179,102,195, 71,140, 24, 1, 0,152, 62,125, 58,226,227,227, +153,248,248,120,241,174, 93,187,176,108,217, 50,140, 29, 59, 22,251,246,237,195,232,209,163, 47,162,226,177, 97, 0,128,213,160, +143, 75, 73,248,195,232, 27, 28, 3,139,213, 6,155, 64, 32, 87, 59,115, 22, 73,120, 5,154,119, 26, 6,171,213, 14,177, 68,129, +218,245, 35,145,121,225,148,201,162,215,255, 90,153,204,210,112, 28,135,174, 93,187, 98,199,142, 29,248,245,215, 95, 97, 52, 26, +241,253,247,223,227,127,255,251, 31, 6, 12, 24,224,169, 3,112,121,211,166, 77,176, 90,173, 80,229,156, 64,147,223, 39, 99,132, +121, 19,222,144,237, 69, 56,147, 5,187,221,142, 19, 39, 78, 0,128, 71,101, 59, 13, 6,195,252, 25, 51,102,152, 11, 10, 10,202, +204, 1,144,203,229,248,244,211, 79,185, 54,109,218,180, 81, 42,149,243, 61,109, 35, 33,132,100,101,101,109,209,233,116,181, 39, + 78,156,200, 54,108,216, 16,153,153,153, 48, 24, 12, 32,132,232, 28, 14, 71, 35, 74,233,215,158, 56, 20,122,131,176,119,203,214, +189,214,126,143,117,114, 63,112, 58,182, 15, 71,173, 90,126,168,229,227,143,142, 29, 90,184,190, 19,131, 7,244,193,207,191, 30, +182,232,245,134,189, 85,136,253, 98,213,170, 85,162, 90,181,106, 65,175,215,151,233,213,188,251,238,187,160,148,130, 82,234,145, +241, 39,132, 8,233,233,233, 72, 73, 73,129, 94,175,183,159, 62,125, 26, 55,110,148, 76, 49, 33,224,169,136, 79, 66,157,176, 61, + 96,196, 60, 49, 23, 14,162,156, 34, 30, 18, 73,165,117,212,133,162,108,176, 12, 1,203, 16,216,236,127, 25,200,160,160, 32,104, + 52, 26, 72,165,210,106, 63,124, 75,247,202, 5, 65,184, 43,153, 28,199, 33, 47, 47, 15,122,189, 30,118,187,221,125,189, 0, 96, +251,246,237,240,247,247,135, 70,163,129, 90,173,134, 84, 42,205,185, 27,121,174, 8,128,107,243,114,255,177, 90,173, 88,186,116, + 41, 26, 54,108,232,254,109,216,108, 54, 80, 74,139, 47, 93,186,212,105,195,134, 13, 91,127,249,229, 23,234,154,180,232,197,115, + 42,156,108,167,211,233,166, 17, 66,118,125,242,201, 39,147, 9, 33, 29, 12, 6,131, 63,203,178,130, 76, 38,203,178, 88, 44,187, + 12, 6,195, 98, 74,233, 21,143,191,233,209,156, 28,236,171,119,184, 78,128,202,239, 64,226,133, 62,159,124,242, 9,242,243,243, +241,197, 23, 95, 0, 0, 83, 39, 64, 29, 11, 86,124, 24,143,102,229, 87, 38,198,102,199,119, 43, 82,241, 78,183,128,140,198, 13, +106,235, 96,101, 57, 24,180, 69, 48, 26, 77, 48,219, 1, 43,195,129, 11,110, 10,179, 85,192, 69, 45,176, 63, 7,217, 22, 71, 21, + 19, 0, 1,112, 14, 19,246,191,219, 29, 43,127,207, 68,131, 58, 26,140,237, 27,229, 30,247, 15,240,231,241, 92,159,246,168, 95, +199, 31, 67,250,118, 2,166,125, 93,169,172,228,228,228,221,219,183,111, 31, 57, 96,192, 0,204,154, 53, 11,241,241,241,160,148, +162,184,184,216,150,157,157,157,157,149,149,117,165, 36,105,197, 2, 74,105,165, 53, 16,108, 54,203,215, 73,199,246, 76,108,220, +182,107,147,134, 81, 79, 35,249,207, 88, 8, 86, 35,196,156,115, 56, 70, 44,145,162,110,163, 40,248, 6, 54, 68,193,141, 12, 36, +255,177, 47,211,102, 51,175,169, 72,222,237, 15, 85,158,231, 17, 22, 22,134,201,147, 39,227,224,193,131,120,246,217,103, 17, 19, + 19,131, 57,115,230,160, 89,179,102,224, 56,206,181,206,185, 50, 7,160,223,194,133, 11,231,172, 95,191,254,169,197, 35,163, 73, +175, 94,195, 16,209,251, 13,156, 90, 53, 5,133, 59,119, 98,213,111,251,168, 78,167,139, 5,240, 65,165, 23,174, 4, 74,233, 41, +153, 76,246,197,196,137, 19,223, 88,191,126,189,212,223,223,223, 61, 54,206, 48, 12,126,250,233, 39,121,243,230,205, 95, 17,137, + 68,199, 4, 65,216, 82,149,188, 97,195,134, 45,200,201,201,105,251,200, 35,143,136,215,173, 91,135,253,251,247, 35, 53, 53, 21, +118,187,221, 8,231,250,226, 74, 13, 96,105,204, 86, 97,209,188, 47,183,188,254,100,159, 54,254, 91, 86, 77,196,180,255,109,198, + 83, 3,187, 0,172, 12, 96,164,120,106,112, 31,204, 94,240, 35,222,157, 60, 26, 98,137, 28, 91,182,255,166, 53,155,173, 85,141, + 3, 88,247,237,219,135,147, 39, 79,226,243,207, 63, 23, 66, 66, 66,220,191,203,234, 70, 0,196, 98,241,188,117,235,214,189, 13, + 0, 12,195,196,110,221,186,117, 96,183,110,221, 74, 38,229, 9,153, 76,189, 86,107, 65, 68,188,227,218,169, 97,132, 66,204,212, +107,245, 19, 80, 88,225, 36, 84, 0,176, 23,102,187, 35, 0, 54, 59,117, 27, 72, 87, 79,189,186, 51,247,121,158,207, 9, 10, 10, + 42,179,164,227,139, 47,190,168,177, 76,158,231,225,231,119,167, 99,238, 50,218,213, 93,167, 95,153, 60,171, 29, 96, 9, 3,134, +193,223, 46, 2,224,233, 16,199, 63,140, 77, 19, 39, 78, 28,255,210, 75, 47,185,135, 0,214,172, 89,227,118, 4, 40,165,199, 0, + 12, 38,132,132, 93,185,114,229, 13, 0,103, 30,170,182,255, 48, 30,120, 57, 96,137,132,140,155, 48, 97,242,146,185,115,231,138, +115,114,114,176,117,235, 86,204,154, 53,203, 82, 84,148, 59,201,106,165, 85, 76, 38,116, 66, 8,105, 91, 87,134,221, 95,181,133, +175, 15, 79, 96, 22, 40,204,118,103,200, 95, 28,212, 24,118,177, 12,201, 23, 47,226,243,243,214,130, 2, 43,250, 84,181, 70,156, + 16, 66, 11,190, 26,228, 12,247,139,164,128,152, 43,245,190,212,190,146,191, 53,157, 95,168,244,161, 66, 8,145,107, 52,154,227, +241,241,241, 77, 21, 10, 5,218,183,111,127,227,250,245,235, 45,224, 44,216, 81,237, 11,238, 74, 4,244,196,184,105,126,140,200, + 1,131, 54, 31, 65, 13,203,142,151, 22,221,202,198,142,165, 51,243,116,133,183,122, 84,145, 8,200,182, 96,193, 2,209,185,115, +231,112,254,252,121,184,126, 88,149,109, 37, 19, 1,171,124,218,189,208,156,244,173,167,192,162, 78, 79,142,136,232,247,225,122, +108,155,241, 52,254,140,219,116, 49, 75,143, 73,107,207,211,221, 85,157,127, 91,155, 69, 82,169,116,142, 72, 36,122, 99,250,244, +233,124,116,116, 52,137,136,136, 64, 70, 70, 6,126,255,253,119, 58,115,230, 76, 51, 33,228,131,194,194,194,207, 43,146,241,202, + 43, 67,249,255, 56, 0, 0, 32, 0, 73, 68, 65, 84,175,136, 51, 50, 50,190, 47, 46, 46, 30, 92, 92, 92, 44, 42, 42, 42, 66, 65, + 65,129,205, 98,177, 24, 1, 56, 0, 76,164,148,174,171,142, 94, 37,186,245, 12, 12,168,181, 61,118,229, 4,121,235,230, 33, 80, + 40,212,127,205,252,103,164,208,155, 41,142,159, 78,193, 83, 35, 38, 26, 10, 10,139, 6,120,144, 8,232,142, 84,192, 64,197,227, +223,132, 16,143,141, 26, 33,164, 55,203,178, 91,237,118,251, 95,137,128,150,246,236, 64,175,252,254, 61,241,107, 50, 13,202,186, +123,240,218,111, 21, 58,221,132, 16,122,233,253,230,112,152,138,193, 16,130,199, 86,223,192,241,203,215,225,239,127,231,132,112, + 74,105,181,116, 43,253, 29,185,185,185, 53,146, 73, 8,161, 90,173, 22, 82,169, 20, 34,209,157,253,153,234,234,227,137,188,210, +240, 34,146, 99,178, 61,184, 76,128,132,144,151, 43,154, 4,104,177, 88,220,147, 1,195,194,194, 64, 41,173,188,167,130,146, 36, +104,142, 59, 3, 95,165, 39, 1,154, 76, 38, 52,110,220,248,129, 39, 60,114, 65, 8,105, 11, 96,101, 84, 84, 84,212, 43,175,188, +130,232,232,104,215,208,101, 62,165,244,161, 77, 78,252, 55,240,192, 29, 0, 66, 72,109,181, 90,189,187,184,184,184, 37, 74,150, +151, 73, 36,146, 68,171,213,218,151, 82, 90,101,120,174,148,156,182, 62, 18,108, 26, 92, 15,117, 91,249,128,215, 72,156, 14, 64, +166, 17, 56, 83, 8,243,161, 91,200,214,217, 48,220,147, 4, 49, 74, 94,114,217,102,183, 7, 3,228,182,233,110,229,220,239,132, + 64, 44, 22, 93,211,233,141, 97, 85,232,215,176,121,243,230,103,226,227,227, 85,115,231,206,197, 39,159,124, 18, 77, 41,253,211, +211,246,149, 35,207,153, 10,184, 99,159,122,161, 45,163,101,190, 65, 33,160, 14, 7,242,175, 95, 69,198,249, 19,198,164,248,223, + 50, 77,218,194, 42, 83, 1,115, 28,151, 97,181, 90,171,149,202,216,227,204,108, 19, 72, 61, 72,240,212, 77, 29, 70,167, 22,161, +110,152, 15,178, 2, 20,248, 22, 20, 63, 98, 1,189, 86,157,239,116, 65, 8,105,171, 86,171,167, 18, 66, 58,232,116,186,122,114, +185,252, 22,195, 48, 39,139,138,138,166, 87,149, 3,188, 99,199,142,210,162,162,162,147,197,197,197, 98,173, 86,107,210,235,245, +121, 0, 14,192,153,208,228, 24,165,212, 88, 19,157, 74,244,234, 41,151,241, 27,135,244,235,160, 26,220,191, 43,215,186,101, 83, +128,229,145,112,254, 42,126,222,126,200,178,101,251, 30,173,193, 96,124,186, 42,227, 95,129,236, 95, 1,244,163,148,150, 27, 1, +168,129, 81,123,148,101,217,183, 5, 65,112,166, 2, 94,254,104, 93, 56, 72, 16, 24,123, 46,198, 29,184, 90,217,185, 82, 17,115, +211,108,167,101,122,235,247,210,224,150,156, 83, 99, 35, 78, 8, 49, 0,168,108,217,161,142, 82, 90,233, 42,135,219,228,217, 80, +249, 26,122, 43,165,180,242,101, 24,247,145,106, 44, 3, 52, 89,173,214, 42,157, 91,153, 76,118,211,100, 50, 85,153,120,137,227, +184, 28,179,217,252,160, 83, 30,151,129, 16, 18, 13,224,219,182,109,219, 70,190,246,218,107,120,233,165,151,188, 14,192, 93,242, +192, 29, 0,247, 23, 19, 50, 3,192, 71, 0,102, 82, 74,103,212, 80, 6, 39, 23, 97, 2,199,226, 49, 7, 69, 19, 10, 16, 80, 92, + 54,217,177,219,234,192,226,170,194,235,247, 27, 66, 72,231,224,224,224,175,243,242,242, 46,155, 76,166,161,119,155,179,158,148, + 20, 3,226, 20,138, 39,237,118,161, 53,113, 22, 3, 74,168,110, 49,160,251,198, 76, 34,130, 14,173,224,128,194,189,143,162, 24, +118, 36, 99,201,195,253, 95,220, 15, 8, 33, 42, 94, 34,153,164, 80,240,189, 93, 75,253,228, 10,217, 89,189,222,176,215,108,182, + 46,170, 34,251, 95, 85,178, 43, 12, 22,213,196,200,222, 43, 8, 33, 22, 84,158,108, 69,160,148,138,171, 41, 83, 11, 64, 89,201, + 33, 70, 74,233, 29,203, 63,189,252, 55, 33,132,116, 7,176, 12,192, 33, 74,233,184,135,172,206, 63,154,135,230, 0,120,241,226, +165, 98, 56,142, 43,146, 74,165,229, 26, 90,147,201,100,181, 88, 44, 21, 37,198,241,226,197,139, 23,143,240, 58, 0, 94,188,252, + 13, 33,132, 40, 1, 84,212,235, 53, 80, 74, 43, 93,186,231,197,139, 23, 47, 85,225,117, 0,188,120,241,226,197,139,151,255, 32, +213, 91,191,227,197,139, 23, 47, 94,188,120,249, 87,224,117, 0,188,120,241,226,197,139,151,255, 32, 94, 7,192,139, 23, 47, 94, +188,120,249, 15,226,117, 0,188,120,241,226,197,139,151,255, 32,149, 37,188,240,242, 47,135, 16, 34, 18,137, 68, 35,229,114,249, + 0, 65, 16, 90, 1,160, 44,203,158, 49, 26,141,191, 8,130,240,240,243, 10,252,141,233,219,183,175,220, 98,177,188, 38, 8, 66, + 71,187,221,222, 94, 16, 4, 8,130,112,194,102,179, 29, 99, 89,118,233,217,179,103, 13, 15, 91,199,251,193, 87,219,226, 95,161, +132,188, 6,128, 3,104, 49,236,116,225,107,131, 59,110,124,216,122,121,241,226,165,250,120, 87, 1, 60, 0, 8, 33,245, 1,140, + 84, 40, 20,109,245,122,253, 41, 0,107, 40,165, 15,181,114, 5, 33,164,149, 92, 46,223,220,186,117,235,122, 17, 17, 17, 50, 87, +253,117,157, 78,135,196,196, 68,227,217,179,103, 51, 13, 6, 67,149,153, 5,255,139,244,234,213,171,139, 32, 8,107, 4, 65,104, + 88, 98,248,203,108, 50,153,236,170,175,175,239,203,123,247,238,173,170, 8,208, 63, 2, 78, 68,110, 90,237,168,221,161,207, 32, + 68,247, 25,140,145,253,187,161,117, 88, 8, 18, 46,103, 96,205, 47,135,112,116,199,102,156, 60,176, 3, 18, 22, 57, 22,129, 86, +153, 45,142,231,249,155, 22,139,165,194,236,115, 30,103,158,244,242,159,130, 16,194,116,235,214,237, 25, 65, 16,166, 21, 23, 23, +135,168, 84,170, 43, 90,173,246,131,243,231,207,111,173, 73,138,117, 47, 94, 7,224,190, 67, 8,169,223,187,119,239,243,243,231, +207, 87,182,108,217, 18,241,241,241,120,243,205, 55,181,199,143, 31,111,241,176,156, 0, 66, 72, 11,181, 90,189,127,228,200,145, +126,253,251,247,135, 68, 34, 65,110,110, 46, 68, 34, 17,172, 86, 43,146,147,147,113,236,216, 49, 28, 59,118,172, 64,171,213,118, +243, 58, 1,127,209,171, 87,175, 46, 54,155,237,160, 32, 8,140,203,224,219,237,246, 50, 14,128, 82,169, 68,104,104,168, 67,165, + 82,253,223,119,223,125,183,173,186,223, 33, 18,137,110,218,237,246,218, 0, 32, 22,139,115,172, 86,235,195, 78,193, 74, 77,185, +153,248,250,240, 85,244,143,105,134, 6,129, 26,247,103, 87,178,111, 97,199,238,221,120,204,188, 7, 77, 94, 91,239, 81,134, 66, + 66, 8, 77, 74, 74,114,151, 3,118,149, 6,118,253, 29, 20, 20,244,208, 50, 29,254, 27, 32,132,180, 6, 16, 2, 32,155, 82,122, +242, 46,101, 49, 0, 62,143,140,140,252,191,228,228,228, 79, 41,165, 75,239,137,146,213,160,107,215,174,205,164, 82,233,220,236, +236,236,158,189,123,247,150,191,248,226,139,136,136,136, 64,114,114, 50, 86,175, 94, 77,247,237,219,103, 82, 42,149, 59,147,146, +146,222,209,106,181,233, 15, 90,191,127, 50,149, 58, 0,132, 16, 51, 0, 14,128,148, 82,106,190,171, 47,114,202,114, 35, 22,139, +221,149,191,164, 82, 41,174, 94,189,250, 19,128,103, 61,149, 39, 18,137,210, 25,134,161, 0,142,216,108,182,131, 0, 54,220,173, +142,247, 3,145, 72,180, 32, 45, 45,237,173, 95,126,249, 5,107,214,172,193, 11, 47,188,128, 6, 13, 26, 96,192,128, 1, 11, 40, +165, 83, 30,180, 62,132, 16,177, 92, 46, 79,126,241,197, 23, 27,201,100, 50,180,104,209, 2,117,235,214,117, 23, 17,185,112,225, + 2,206,158, 61,139,220,220, 92,104,181, 90, 92,185,114,229,170,209,104,108,242,111, 25, 14, 32,132, 4,137,197,226,197, 74,165, +178,167,195,225,128, 78,167, 59, 96,183,219, 39, 81, 74,179,170, 58,183,111,223,190,114,147,201,148,104,183,219,221, 61,127, 0, + 8, 15, 15,135, 78,167,195,197,139, 23, 97,181, 90, 97,183,219,209,176, 97, 67,180,111,223, 62,151,231,249,200, 57,115,230, 84, + 90,225,178, 28, 29,105, 81, 81, 17, 28, 14, 7, 52, 26,205, 67, 55,134,132, 16,106,213,230,225,135, 89,163,113,201,175, 39,236, + 44,239,220, 15, 64,226, 48,163, 85,193, 30,180,240,165, 8,127,123,167,199, 14,192,197,139, 23,203, 24,253,210,239, 3, 3, 3, + 31,122,155,255,169, 16, 66, 30, 1, 0, 74,233,113, 66,200, 64, 0,191, 82, 74,237, 53,148,197, 0, 88, 53,111,222,188, 81,111, + 78,154,132,136,200,200,162,180,180, 52,205,131,236,109,199,196,196,236,243,245,245,237, 54,122,244,104,246,241,199, 31,135, 72, + 36,130, 32, 8,176,217,108, 46, 29, 65, 41, 69, 92, 92, 28, 86,173, 90,101,191,126,253,250,222,115,231,206, 61,254,160,244,251, +167,227,233, 28, 0,147, 88, 44,134, 32, 8,119,227, 8,184, 11,104,136, 68,162, 50,198,159,231,249,106, 11,179,219,237, 13,118, +236,216,129,249,243,231, 55, 76, 79, 79, 31,114,253,250,245,217,132,144,231, 40,165, 7,107,168,223,125,197,225,112,192,110,183, +195,104, 52, 66,167,123,120, 73,220, 68, 34,209,203, 81, 81, 81,161,174,107,206,178, 44,180, 90, 45, 76, 38, 19,140, 70, 35, 18, + 18, 18,192, 48, 12,120,158, 71,126,126, 62,106,213,170, 85,223,106,181,142, 4,176,234,161, 41, 93, 10, 66, 72, 61, 0, 63, 3, +184, 74, 41,125,170,154,231, 6,105, 52,154,164,208,208, 80,181,195,225,128,197, 98,129, 90,173, 30, 98,183,219,251,198,196,196, + 68,197,199,199,167, 86,118,190,201,100,122,173,116,216,191, 67,135, 14,232,210,165, 11,110,221,186,149,115,227,198, 13,129,227, +184,186,137,137,137, 40, 46, 46, 70, 82, 82, 18,218,183,111,239, 47, 22,139, 63, 3, 48,170,186,237, 84,171,213,136,141,141,173, +238,105,247, 13, 75, 65, 22,194,138,227, 17,161,253, 3,255, 59,162, 69,190,209, 1, 7, 5, 4, 7, 16,231,160,160,140, 51,253, + 63, 33,132, 2, 48, 81, 74, 43, 43,208, 3,134, 97,220,219,143, 63,254,136,196,196, 68, 56, 28, 14,184, 42,211,149,200,113, 81, + 76, 41,245,166, 62,174,130,210,198,191,100,215, 5, 0,157, 1, 28,170,129, 44, 6,192,170,185,115,231,142,122,115,210, 36,104, +181, 90, 60,251,204, 51,181,102,127,252,241, 60, 0, 83,239,153,210, 85,144,159,159,223,228,216,177, 99,172,203,217, 54,153, 76, +176,217,108,112, 56, 28, 32,132,184,203, 70,235,116, 58,100,101,101,177, 55,110,220,104,245,160,116,251, 55,224,145, 3,192,178, +172,203, 96,155, 66, 66, 66,144,145,145, 81, 19,239, 92, 10,192, 36, 18,137,202, 24,126,158,231,113,225,194,133,205,168, 70,239, +223, 69,223,190,125,145,144,144, 0,149, 74, 37, 79, 73, 73,145,127,251,237,183, 59,100, 50,217, 60,163,209, 56,179, 6,250,221, + 23,236,118,251,226,177, 99,199,142,157, 53,107,150,242,197, 23, 95,196,217,179,103,241,234,171,175,234, 1, 44,169,169, 76, 66, + 72,103, 0, 95, 1, 48, 1,152, 76, 41, 61,226,233,185, 62, 62, 62, 79,215,173, 91,151, 13, 8, 8, 64,211,166, 77, 97, 54,155, +161,211,233,220, 17,128,168,168, 40,228,229,229, 33, 52, 52, 20,133,133,133, 32,132, 48,122,189,254, 73,252, 13, 28, 0, 66, 72, + 19, 0,123,225, 12,111, 86,187,146,159, 88, 44, 94, 28, 28, 28,172,182,217,108,176, 88, 44,238,173, 89,179,102,138,134, 13, 27, +174, 5,208,177,178,243, 5, 65,232,104,179,217, 32, 8, 2, 24,134, 65,207,158, 61,145,147,147,243,246,164, 73,147, 62, 3,128, +199, 30,123,108,184,217,108,222,224,114, 16, 50, 50, 50,208,171, 87,175,104, 79,116, 43, 29,246, 87,169, 84,102, 74, 41,175,209, +104,224,235,235,107,118, 25, 67, 79,199,198, 75, 38,119, 94, 23, 4,225,206,250,186,165,144,201,100,153, 6,131, 33,196, 19,253, + 44,249, 89, 96, 25, 6, 12, 1,114,245, 14,204,219,120,192,237,196,223,238,204,115, 28, 87,101,181,186,210, 14, 64, 66, 66, 2, +198,143, 31,239,150, 51,103,206,156,219,229,169, 61,209,241,191,204,109, 61,127, 5,128, 8, 0,137,168,129, 3,224, 50,254,159, +126,250,233,168,183,222,124, 19, 71,143, 30,197,190,125,251, 48,112,192, 0, 44, 94,178,164,210,223,200,253,192,106,181, 2, 0, +244,122, 61,204,230,191,250,159, 54,155, 13,191,253,246, 27, 54,109,218, 4, 95, 95, 95,140, 31, 63, 30, 51,103,206,252,219, 69, +129, 31, 6, 23,134,145,114,163, 52,205, 54,151,141,172, 85,233, 0,176, 44,235,254, 49,186,182,168,168, 40, 42,149, 74,113,236, +216,177, 13,240,208,112, 83, 74,205, 98,177,184,140,225,119,189,103, 89,182, 70, 33, 42, 0,208,104, 52, 80, 42,149,232,213,171, + 23, 30,125,244, 81,217, 51,207, 60, 51,149, 16, 18,119, 55,165,119,239, 37,148,210, 76, 66, 72,243,189,123,247,110, 75, 73, 73, +105,109, 52, 26,145,148,148,116, 24,192,205,187, 16,187, 0, 64,139,146,247, 95, 1,104,233,233,137, 86,171,181,105, 96, 96, 32, +194,195,195, 97, 48, 24,220,134,223,104, 52, 98,223,190,125,200,206,206,134,201,100,130,213,106, 69, 76, 76, 12, 2, 3, 3,241, +205, 55,223,180,185, 11, 93,171, 77,201, 3,108, 56,128,109,148,210,188,146,125,145,112,150,242,173, 13,224, 79, 0,255, 87, 93, +185, 50,153,172,231,237,198,223, 98,177, 32, 47, 47, 15,163, 71,143,174,178,141, 54,155,205, 53,219, 31, 81, 81, 81, 40, 40, 40, +200,125,253,245,215, 63, 3, 64, 1, 32, 46, 46,110,163, 70,163,153, 46, 8, 66,164, 32, 8,184,113,227, 6, 26, 53,106, 20,234, +137,110,118,187,189,118,113,113, 49, 84, 42, 21, 28, 14, 7, 95, 92, 92, 12,141, 70,131,227,199,143,243,106,181, 26,106,181, 26, + 98,177,184,202,178,173, 37,136, 8, 33, 26,189, 94, 15,185, 92,238,126,112,186,194,166,174,146,187,117,234,212, 9,242, 80, 30, +108,133,217, 96, 25, 2, 66, 0,155,131,130,227, 56,180,105,115,231, 37,243, 52, 58, 92,218, 1, 16, 4,225,174,229,253,151,185, +205,248,251, 82, 74,243, 9, 33, 44,128,103, 0, 36, 84, 83, 22, 3, 96,213,252,249,243, 71, 77,156, 48, 1,199,142, 29, 67,253, +250,245,145,158,158,142,110, 61,122,164, 25, 12,134,217,247,161, 9, 21, 66, 41,133,217,108,134,221,110,135, 94,175,135,197, 98, +129,217,108, 70, 90, 90, 26,226,226,226,224,235,235,139,151, 94,122, 9, 34,145, 8, 22,139,197,123,191,148,112,187,161,175,136, + 74, 29, 0, 87, 40,184,162,173,186, 8,130, 32,229,121,222, 84,218, 9, 56,117,234, 84,141,122,255, 46,124,124,124,160, 82,169, +220,219,130, 5, 11,100,147, 38, 77,138, 37,132, 52,121,216,229,128, 93,148, 56, 1, 51,190,253,246,219,173, 31,126,248, 33,150, + 46, 93,250,248,228,201,147,143, 16, 66, 94,160,148, 94,172,129,200,210, 61, 44, 83,117, 78, 20, 4,193,108,179,217,144,149,149, +133,107,215,174,185,255, 15, 46, 39,192, 96, 48,192,108, 54,195,100, 50, 33, 53, 53, 21,245,235,215,175,129,122,119,205,112, 56, + 35, 14, 83, 8, 33, 61, 0,220, 2,240, 29,156,198, 63, 14,192, 80, 74,105,181,151,217,185,134, 96,110,119, 0,148, 74, 37,218, +180,105, 83,165, 51,236,234,253, 11,130, 0,163,209,136,220,220,220, 59, 28, 87,215, 49,118,187, 29, 44,203,194,223,223,159,245, + 84,191,180,180, 52,100,101,101, 65,173, 86,163, 86,173, 90,208,104, 52,112, 25,255,234,226,112, 56,144,154,154,138,140,140, 12, + 40,149, 74, 40,149, 74, 40, 20, 10, 40,149, 74,112, 28, 7,177,184, 90, 21,123, 75, 57, 0, 4, 86, 59,192,243, 60,210,210,210, +202, 68, 0,170,243, 76,184,221, 1,184, 91,121,255, 37, 8, 33, 26, 0, 29, 0,119,217,237,140, 18,227,223, 24, 64, 27, 66, 72, + 33,156,207,136, 67,148,210,171, 30,200,235,193, 48,204,228,230,205,155, 71, 49, 12, 83, 52,127,254,252,166,175,191,246, 26,230, +205,155,135,105,211,167,167, 62,243,244,211,141, 83, 83, 83,109, 6,131,161, 31,165,244,210,125,107, 88, 57, 80, 74, 97, 50,153, +220,134,223,181,241, 60,143,254,253,251,195, 53,148,231,218,239,117, 0,202,226,138, 4, 84,228, 16, 84,250,208,171,200,240,199, +199,199,111, 40, 57,100, 75,117,148,161,148,154,235,215,175, 95, 38,100,120, 55,189,127,224, 78, 7,224,217,103,159, 37, 95,125, +245,149, 42, 33, 33,161, 39,128, 93,119, 35,251, 94, 66, 41,221, 70, 8, 89, 99, 50,153, 70,190,251,238,187,104,217,178,101,251, +241,227,199,159, 32,132,180,166,148,166, 85, 83,220,120, 56,163, 0, 82, 0,147,171,115, 34,195, 48,167,109, 54, 91,208,153, 51, +103,144,158,158, 14,179,217,140,182,109,219, 66,165, 82,161,125,251,246, 96, 24, 6,103,206,156,129,217,108, 70,211,166, 77,113, +235,214, 45,136, 68,162,211,213,212,239,110,217, 10, 96, 34,156, 81,142, 3, 0,214, 3,104, 15, 32, 11,192,176,154, 24,127, 0, + 48, 26,141,251,101, 50,217,208,162,162, 34,183,241,119, 56, 28,152, 60,121, 50,178,178,178,110,132,135,135, 87,122,190, 32, 8, + 39, 4, 65, 24, 40, 8, 2,206,156, 57, 3, 63, 63,191,192, 17, 35, 70, 60,255,253,247,223,175, 5, 0,181, 90,221,207,213,251, + 23, 4, 1,109,218,180, 65,113,113,113,158, 39,186,137,197,226,156, 54,109,218,212, 6, 0, 95, 95, 95,115, 66, 66, 2,175, 86, +171,209,164, 73, 19,115, 78, 78, 14, 15, 56,135, 0, 60,108,170,192, 48, 76, 65,235,214,173,171, 26, 2,184,238,161, 60, 8,133, + 89,110, 7,192, 21, 1,104,212,168,209, 29,199,221, 77, 4,224,110,228,253, 87, 32,132,248, 1,232, 4,103, 20, 44, 7,128,154, + 82, 90, 84, 98,252, 27, 2,248, 17, 78, 71,153, 80, 74,171,252,255, 18, 66,122, 60,246,216, 99,123,151, 45, 91,198,134,134,134, + 34, 47, 47, 47, 72,165, 84, 98,254,252,249,248,112,218,180,213, 0,198,252,176, 97, 67, 27, 0,186, 7,109,252,129,191, 34, 0, +174,205,101,236, 25,134,129,213,106,117,255,237,122,245,222, 47,127,113, 97, 24,161, 46,195, 95,250,125,105, 42,205, 4, 88,186, +167,206,243, 60, 78,159, 62,189,249,143, 63,254,112,133,253,159, 69, 53, 29, 0, 0,200,204,204, 36, 46,185, 37,142, 68,141,123, +255,128,211, 1, 40,189,201,100, 50,244,235,215, 79, 33,145, 72,122,221,141,220,187,133, 16,210,149, 16,178,138, 16,226, 30, 51, +163,148,142, 90,180,104,209,148, 65,131, 6,217, 68, 34, 17,102,204,152,161, 64, 13, 38,212, 80, 74,143, 80, 74, 59, 80, 74, 91, + 86,103,252, 31, 0, 76, 38, 83,220,133, 11, 23,140, 26,141, 6, 70,163, 17,102,179, 25, 74,165, 18,128,211,225,107,223,190, 61, +140, 70, 35, 68, 34, 17,130,131,131,145,154,154,106, 50, 26,141,191, 86, 87,199,187,129, 82,154, 15,224, 81, 0,231,224, 28,203, +156, 85,242,209,107,119, 83, 6, 55, 60, 60,124,114,139, 22, 45,140,131, 6, 13, 66,203,150, 45,209,179,103, 79,236,220,185, 19, +221,187,119,167,103,206,156,169,114, 66,161, 32, 8,199,108, 54, 27,108, 54, 27,204,102, 51,142, 29, 59,134,228,228,228,239,252, +252,252,146, 21, 10, 69,146,197, 98,249,213, 21, 1, 16,137, 68, 24, 62,124, 56,242,243,243, 61, 90, 66,105,181, 90, 3, 41,165, +132, 82, 74,242,243,243,121, 31, 31, 31, 40, 20, 10,228,228,228,240,174,253,158,174,141,167,148, 10, 86,171, 53,192,117, 94, 69, +155,167,227,255, 0, 96, 47,114, 70, 0, 88,198, 25, 1,224, 56, 14,121,121,121,208,235,245,176,219,237,160,148,122,252,240,229, +121, 62,167,126,253,250,168, 91,183, 46, 2, 3, 3,177,117,235,214,187,146,247, 31,163, 13,128,147, 0, 44, 0,122, 0,144, 17, + 66, 36,112, 70, 4,126,163,148, 58, 40,165, 55, 60, 49,254, 0,192, 48,204,228,101,203,150,177, 70,163, 17, 47,191,252, 50,178, +174, 93,195,213,171, 87,241,209,140, 25, 73, 0,198,148,200, 59,249, 48,140, 63,224,140,100,153, 76, 38,183, 3, 96, 50,153,238, +248,219,229,200,155, 76, 38,239, 61, 83, 77, 42,117, 0, 56,142, 3,207,243, 72, 74, 74,218,156,152,152,184,129,101,217,225,184, + 75,131, 13,192, 29, 1,184, 91,204,102, 51, 52, 26, 13, 52, 26, 13,124,124,124,192,113,206,133, 6, 93,187,118,101,101, 50,217, + 67, 93, 10, 18, 26, 26,186,241,210,165, 75,163,195,194,194,126, 37,132,184, 87, 64, 80, 74, 23,252,241,199, 31,253,191,252,242, + 75, 68, 68, 68,160, 97,195,134, 3, 31,164, 94,130, 32,124,157,144,144,144, 93, 92, 92,140, 38, 77,154,192, 98,177,184, 39,217, + 0,128, 68, 34, 65,195,134, 13,209,182,109, 91,228,230,230, 34, 49, 49, 49, 83, 16,132, 53, 15, 82, 71, 0,160,148,230,194,233, + 4,100,193,121,159,158,166,148,110,191, 27,153, 73, 73, 73,153, 26,141,166, 93,187,118,237, 46,124,251,237,183,246,141, 27, 55, + 82,137, 68,146,181,122,245,234,142, 83,166, 76,249,163,170,243,139,138,138,150,114, 28,119, 69,161, 80, 64, 16, 4,100,103,103, + 35, 45, 45, 13, 38,147, 41,194,102,179, 69,186, 66,255, 0, 48,101,202, 20,132,134,134, 10, 57, 57, 57, 47,214, 68, 87,153,172, +210, 73,244, 15, 28,123, 97, 54, 24,183, 3, 64,193,243, 60,252,252,252,160, 80, 40,192,178, 44, 8,113, 70, 7, 60,193,100, 50, + 5,150,118, 68, 0,220,149,188,255, 24,114, 74,105, 54,128,166, 0, 26, 3,136,162,148, 90,225,236,161, 59,170, 43,172,121,243, +230, 81,161,161,161, 88,188,120, 49, 86,174, 92,153,191, 96,193, 2,176, 44,139, 70, 13, 27,170,107, 34,239, 94,227,138, 0,148, +103,248, 93, 61,127,192, 57, 81,208, 27, 1,168, 62, 85, 37, 2,250,161,228,245,174,141,126, 5,114,183,160, 6, 81, 4,160,234, +108, 98,114,185, 60, 93,175,215,223, 25, 83,124, 64,248,251,251, 95, 74, 74, 74, 10, 91,190,124, 57,166, 79,159,190, 10,192,247, +112, 78,200,105, 13, 96,196,148, 41, 83,198, 60,253,244,211,232,213,171,215,165,194,194,194,136, 7,169,155, 43, 17,208,176, 97, +195,252, 8, 33,208,106,181,104,208,160, 65,153, 99,242,243,243,177,113,227,198, 60,173, 86,219,227, 97, 38, 2, 34,132, 4, 2, +152, 9, 96, 6,165,244,198,195,210,195, 69,167, 78,157,122,171, 84,170,184,130,130, 2,230,210,165, 75,101,230, 5, 56, 28, 14, +136, 68, 34, 76,153, 50, 5,179,103,207,198,186,117,235,166,142, 26, 53,234,179,234,126,135, 84, 42,189,105, 54,155,107, 3,127, +143,172,120,188,136,220,180,216, 81,230,183,166,213,106, 33,149, 74,221, 19, 10, 75, 83,178, 54,219, 99,235, 77, 8,161,247, 82, +222,191, 25, 66, 72, 31, 56,151,247, 25, 1, 68, 1,184, 8,160, 0,192,227,148,210,159,171, 43,143,101,217, 95,211,210,210,250, + 21, 21, 22, 98,225,194,133, 24, 49, 98, 4, 4,155, 13, 3, 6, 13,218, 97,183,219,159,188,183,218, 87, 31,165, 82,185,189, 75, +151, 46, 77,198,141, 27, 23, 33, 22,139,239, 24, 10, 16,137, 68, 48, 26,141,184,126,253,186, 99,235,214,173, 23,211,211,211, 83, +173, 86,235, 3,237, 84,253, 93,241,100, 37,128, 55, 19,224,125,130, 16,242,209,151, 95,126, 57,163,127,255,254,248,253,247,223, +113,228,200, 17, 92,184,112, 1,225,225,225,104,215,174, 29,218,182,109,139, 93,187,118,225,163,143, 62,154, 65, 41,125,224,203, + 22, 93,169,128, 91,181,106, 85, 47, 44, 44, 76, 22, 16, 16, 0, 74, 41,114,114,114,144,154,154,234, 77, 5, 92, 9,195,135, 15, + 31,224,239,239,191,146, 16, 18,144,153,153,137,155, 55,111,186,103,177, 15, 27, 54, 12, 13, 26, 52, 16,226,226,226,222,171,137, +241,255, 39, 64, 8,177, 0,144, 84,114,136, 64, 41,245,120,150, 33, 33, 68, 11, 64, 89,201, 33, 70, 74,169,220, 83,121,255,102, + 74,230, 0,116, 4, 16, 79, 41,205, 37,132,168, 0, 60, 2, 32,213,147, 9,127,229,200,235,209,167, 79,159,189,159,204,153,195, +170,213,106, 92,186,120, 17,179, 62,254,216,126,252,248,241,222,148,210, 3,247, 88,253, 26, 65, 8, 25, 40,151,203,103,245,235, +215, 79,241,228,147, 79, 54, 20, 4,193,237, 4,232,245,122,236,222,189,251,242,241,227,199,205, 86,171,117,218,221, 70, 9,255, +107,120, 29,128,251, 4, 33,132, 19,139,197, 91,222,120,227,141,126, 61,122,244, 64, 72, 72, 8,236,118, 59,108, 54, 27, 82, 82, + 82,112,232,208, 33,172, 94,189,122,135,205,102, 27,242,176, 86, 43,184,138, 1,201,100,178, 39, 5, 65,104, 77, 8,161, 44,203, + 38,120,139, 1, 85,205,216,177, 99, 53,254,254,254,159,213,169, 83, 39, 58, 44, 44,172,129,159,159, 31,163,211,233,242, 10, 10, + 10, 46,228,228,228,188,248,234,171,175, 62,244,104,133,151,127, 39,132,144, 0, 56,141,190, 4,206, 37,168,103, 41,165, 53, 78, +129,235, 90, 5,208,184, 81,163,214, 41,169,169,103, 40,165, 11,255, 46,198,223, 5, 33, 68, 4,224,101,165, 82,249,198,255,253, +223,255,169, 91,182,108, 89,231,232,209,163,215,118,237,218,165, 55,153, 76, 75, 0,172,242, 62,175, 42,167,188,137,128, 94, 7, +224, 62, 82,178,166,118, 16,128,199,125,125,125,123,135,134,134,134, 92,185,114, 37,163,160,160, 96, 47,156, 43, 20,182,254, 29, +198,217,188,120,241,226,229,159, 0, 33, 68,201, 48,204,251, 28,199, 61,105, 50,153,126, 6, 48,143, 82,170,127,216,122,253, 83, +241, 58, 0, 15, 16, 66,136,164,100,194,142, 23, 47, 94,188,120,241,114,223,168,104,233, 95,105,188, 14,128, 23, 47, 94,188,120, +241,242, 47,194,211, 84,192, 94, 7,192,139, 23, 47, 94,188,120,249,151,225,141, 0,120,241,226,197,139, 23, 47, 94,202,197,211, +114,192, 94,188,120,241,226,197,139,151,127, 16, 23,134, 17,119,117,196,102,155,233, 29,197, 53,254, 49, 17,128,215, 95,127,189, +140,162, 5, 5, 5, 80,171,213, 72, 79,191,115,245, 11, 33, 4,141, 27, 55,190, 99,255,151, 95,126,233, 14,135,148,150,231,112, + 56,112,250,244,105, 68, 70, 70, 98,205,154, 53,119,156,199,178, 44,198,141, 27,231,177,188,154,242, 32,229,253,221,174,223,109, +223, 47,138,140,140, 60,216,161, 67,135, 78,229,201, 99, 24,198,110,183,219, 31,138,243, 74, 8, 97,194,194,194,134,117,236,216, + 81, 85,158,110, 18,137,132, 90, 44,150,149,213,148, 41, 10, 11, 11, 75,238,216,177, 99,227,242,100, 2,176, 83, 74,189,206,186, +151,127, 20, 37,171,160,194, 0,180, 45,217,117, 10,192,101,239,202,167, 7,195,133, 97,196, 44,151,163,150,235,111,131, 1, 69, +183, 59, 1, 21, 62, 84, 8, 33,117, 20, 74,213, 68,137, 68,210, 77,161, 80, 4, 27, 12,250,235,118,193,254,123, 81, 81,225, 23, +148,210,140,187, 85,142, 16,162,208,168,196,171, 10,180,182, 23,170, 59, 51,190,160,160, 0,157, 58,117,194,149, 43, 87,208,173, + 91, 55,176, 44, 11,134, 97,220,175,187,118,121, 94, 3,200,225,112,224,212,169, 83,216,188,121, 51,214,172, 89,131, 29, 59,118, +184, 83, 32,115, 28, 7,142,227,208,178,165,199,213,118,203, 80, 84, 84, 4,185, 92,142,171, 87,175, 86,120,140, 88, 44, 70,104, +104,168, 71,122, 38, 39, 39, 35, 48, 48, 16, 27, 55,110,172,240, 56, 31, 31, 31, 60,251,108,229,137, 27,255,206,215,175,196,248, + 31,222,181,107, 87,116, 37,242, 60,174,176,119, 47, 41, 49,254, 67,246,238,221,171, 90,189,122, 53,214,175, 95,127, 71,161,172, +206,157, 59, 87, 43, 99, 93,137,241, 79,216,179,103, 79,227, 53,107,214, 96,247,238,221,119,200, 12, 15, 15,191,167,237, 37,132, +116, 14,111, 80,247, 59,106,183, 27, 47,103,222,124,143, 82, 90,173, 90, 15, 37,213,232, 90, 3,104, 4, 32, 29, 64, 66, 73,253, +134,154,234,163, 6,208, 10, 64, 56,128, 12, 0,103, 74, 82, 65,215, 84,158, 79,137,126,141,239, 70, 63, 66, 72, 59,158,231,167, + 18, 66, 58, 88, 44,150,186, 60,207,103, 81, 74,255, 48,153, 76,255,163,148, 86,171,204,238,189, 64, 44, 22,223, 20, 4,193,211, +146,208,110, 56,142,203, 49,155,205, 30,103,147, 44,249,127,140,133, 51,215, 0, 0, 28, 7,176,146, 82, 90,236,169, 12,134, 97, + 70,114, 28,247,101,235,214,173,153, 94,189,122,193,102,179, 97,239,222,189, 72, 78, 78,118,176, 44,251,186,221,110, 95, 83,173, + 70,120,169, 17,161,171,169, 59, 2,112, 97,216,157,143,166,114, 29, 0,158,231,199,180,127,228,145, 79,191,250,106,185,111, 72, + 72, 8, 88,150,129, 78,111,168,123,241,226,197,246,211, 62,252,224, 69,149, 74,245,137, 78,167, 91, 68,239, 34,124, 80,187,150, +120, 86,144,159,108, 48, 33,166, 41, 0, 62,241,244, 60,151,241,146,203,157,137,193, 88,150,189,195,128, 17, 66,144,146,146, 82, + 97, 79,182, 52,167, 79,159,198,230,205,155, 17, 18, 18,226,106,123, 25, 99,195,113, 28, 68, 34, 17,150, 46, 93, 90, 97, 79,182, + 60,138,138,138, 16, 19, 19,131, 43, 87,174,160,119,239,222,224, 56, 14, 18,137, 4, 98,177, 24, 12,243, 87, 9,134,141, 27, 55, +130, 82, 90,105,222,115,135,195,129, 11, 23, 46, 96,227,198,141, 88,178,100, 9, 78,158, 60,233, 46, 19,171, 82,169, 32,145,252, +149,148,173,180,236,242,184,253,250, 89,173, 86, 56, 28, 14, 56, 28, 14, 80, 74, 17, 24, 24,120, 87,215, 47, 63, 63, 31,130, 32, +192, 85, 52,167, 79,159, 62,213,186,126,145,145,145, 7,119,237,218, 21,237,146,247,248,213,207, 0,171, 17,176, 25, 1,155, 9, +169, 79,237,132, 72, 36, 2, 33,132, 62,232, 72, 64, 68, 68,196,192,184,184, 56, 31, 87,137,228,123, 81, 34, 59, 34, 34,226, 88, + 92, 92, 92,179,219,239,191,187,145, 89, 25,132,144,218,237, 91,183,216,181,123,195,114,133, 33, 59, 25,157,159,122,245,135,146, +178,212, 91,203, 59, 94,169, 84, 94, 54,153, 76, 13, 0, 64, 34,145,228,153, 76,166,247, 20, 10, 5, 29, 56,112, 96, 86,147, 38, + 77,178, 83, 82, 82,176,109,219,182,254,196,121, 3, 39, 2, 56,239, 73, 98,171,146,196, 46,145, 0, 90,201,100, 50,201, 19, 79, + 60,145,213,172, 89,179,236,204,204, 76, 33, 54, 54,246,113, 66,136, 24,192,217, 18,121,230,202,165, 57,151,216, 2,104, 6,160, + 21,207,243,244,177,199, 30,203,108,221,186,117, 86,118,118, 54, 27, 27, 27,219,159, 97, 24,134, 82,234,146, 87,169,126,132, 16, +177, 68, 34,249, 95,253,250,245,199, 45, 95,190, 92, 26, 30, 30, 14,149, 74,133,236,236,236,208, 83,167, 78,133,188,243,206, 59, + 3,121,158, 95,100,177, 88,166, 63,200,228, 51,130, 32,212,214,106,181,238,226, 93, 0,112,241,226, 69,108,218,180, 9,111,191, +253,118,185,245, 85, 10, 10, 10,224,235,235,235,177,211, 64, 8,137, 81,171,213,171,134, 12, 25, 98, 14, 14, 14, 14, 85, 42,149, + 48,153, 76,141,150, 45, 91, 54,138, 16, 50,134, 82, 26, 95,197,249, 50,158,231,183, 15, 28, 56,176,227,202,149, 43,165,118,187, + 29,122,189,115,153,254,184,113,227, 80, 92, 92,140, 73,147, 38, 45, 85, 40, 20, 35, 12, 6,195, 64, 74,169,177, 42,157,196, 98, +241, 41, 65, 16,252, 74,239,147, 72, 36,121, 22,139,165,109, 69,231,120,241,140, 59,172, 5,207,243, 99,198,191,254,198,162,131, + 7, 14,250, 10, 96,176,231,192, 97,236,218,123, 8,167,206,158,131,175,127, 32,126,216,184,201,239,153, 17,207,205, 86,171,213, +239,213,244, 75, 9, 33,117, 2, 3,124,159, 63,188,184,143, 68,206, 75, 38, 18, 66,106, 85,125,150, 19,181, 90,141, 43, 87,174, +224,252,249,243, 40, 44, 44,116, 59, 0,165,157, 0,181, 90,141,199, 31,127,220,163,194, 16,174,176,245,204,153, 51,113,246,236, +217, 59, 42, 32, 74,165, 82, 52,107,214, 12,137,137,137,238, 66, 47, 85,225, 50,254, 46, 35,155,151,151,135,220,220, 92,247,107, +110,110, 46,110,221,186,229,113,225,138,164,164, 36,108,216,176, 1,117,234,212, 1, 0, 28, 57,114, 4, 71,142, 28, 65,124,124, + 60,142, 30, 61,138,163, 71,143,226,240,225,195, 30,201,186,253,250,185, 12, 63,165, 20, 14,135,227,174,174,223,233,211,167,221, +121,241, 93, 91,117,175,159, 43,236, 63,115,230, 76, 36,157, 58, 10,216,204,128, 96,118,190,218, 76,101,228, 57, 28,142, 7, 26, + 9,136,142,142,246,119,233,150,144,144,224, 50,206,204,148, 41, 83,102,175, 90,181,106, 69,187,118,237, 86, 0, 88, 65, 8,161, +174,141,227,184, 74, 13, 68,116,116,116,251,210,247, 95,233, 82,217,165, 74,102,163,180, 76,134, 97,106,108,116, 20, 18,102,250, + 23,179,223,150,214, 74,218, 0,191,227, 11, 49,163,167,143, 82, 41, 33,179, 42, 58,222,100, 50, 53,200,207,207, 23,233,245,122, +145,201,100, 10,140,143,143, 79,209,233,116,151,215,175, 95,111, 12, 15, 15,183,175, 95,191,222,168,211,233, 46,197,199,199, 95, +142,137,137,169, 35, 22,139, 95, 34,132,116,171, 72,158, 92, 46,207, 32,132, 80,158,231, 11,162,162,162, 26,237,222,189, 59,195, + 96, 48, 36,199,198,198,234, 34, 34, 34,236,223,126,251,173, 73,167,211,165,156, 56,113, 34, 57, 38, 38,166,182, 88, 44, 30, 89, +153, 60, 0, 80,169, 84, 7, 88,150,221,222,160, 65,131,166, 7, 14, 28,184,104, 50,153, 46,255,252,243,207,230,136,136, 8,251, +215, 95,127,173, 43, 44, 44,188,116,226,196,137,212,110,221,186,213,229, 56,238, 37,150,101, 43,149, 39,145, 72,230, 13, 29, 58, +116,252,133, 11, 23,164,117,234,212,193,229,203,151,177,117,235, 86, 20, 21, 21,161, 93,187,118,228,192,129, 3,210,152,152,152, + 55,121,158,175,240,186,221, 47,148, 74, 37, 8, 33,136,141,141,197,214,173, 91,221, 67,120, 82,169, 20,107,215,174,197,143, 63, +254,136,184,184, 56, 28, 62,124, 24,167, 79,159, 70,110,174,231,129, 20, 66,136,186, 86,173, 90,171, 94,127,253,245,218,239,191, +255,126,209, 59,239,188,243,205,115,207, 61, 55,178,105,211,166,155, 86,174, 92, 25, 16, 28, 28,188,170, 36, 58, 80, 33, 18,137, +228,243,169, 83,167,118, 89,187,118,173, 52, 33, 33, 1, 73, 73, 73, 72, 76, 76,196,217,179,103,145,159,159, 15,155,205,134, 85, +171, 86,201,134, 14, 29,218, 89, 42,149,126,238,137, 94,130, 32,248, 21, 21, 21,185,159, 83,122,189, 30, 86,171,213,175,234, 51, +255,219,200,229,168,117, 97, 24, 49,187,182,210,195, 1, 46,202,244,158, 8, 33,117, 90, 71,181,249,116,230,140, 25,242,189,135, +226,113,237, 90, 38,222,120,101,148,251,243, 93,123,246,129,147, 72, 48,101,234,219,242, 35,135,127,127,139, 16,178,165, 38,101, + 34,131, 52,146,197,219,190, 95,234, 43,215,216,241,241,203,249,154,183,151,253, 49, 23,192,171,158,156,155,158,158,142, 30, 61, +122,128, 97, 24, 4, 6, 6,150, 49,252,174,247, 34,145,200, 93, 81,172,170,158,172, 43,236,202,113, 28,250,246,237,235,238,245, +151,142, 2,200,100, 50,240, 60,239,113, 79, 86,165, 82, 33, 35,195, 57, 74, 82, 84, 84,132,240,240,112,119,145, 19,187,221,238, +238,113,123, 74,100,100, 36,214,173, 91, 7,192,233,241,247,239,223, 31, 28,199,129, 16, 2,171,213,234,222,170,115,253,204,102, + 51,100, 50, 25, 40,165, 56,126,252, 56, 0, 32, 42, 42, 10, 44,203,214,232,250,229,230,230, 34, 36, 36, 4, 54,155, 13, 47,191, +252, 50, 0,224,179,207, 62, 3,207,243,213,186,126, 46,121,189,211,231, 3,189,156,189,126,102,234, 89, 0,128,227, 3,223, 59, +228, 61,200, 72,192,154, 53,107,220, 97,255,118,237,218, 1, 0, 51,125,250,244,105,219,182,109, 11,168,100, 72,160, 82, 39,197, +213, 94,169, 84,138, 39,158,120,162,220, 8, 64,120,120, 56, 22, 47, 94,236,190, 47, 31,121,228,145,106, 59, 62,132,144,206,237, +162, 90,237,137,253,233,103, 73, 84,179, 64,214,176,254, 19,100,229,235,113,163,200, 8, 7,165, 30, 85, 5, 5,128,232,232,104, +247,141,235,231,231,231,118, 68,162,163,163, 29, 71,142, 28,185,113,252,248,241, 43, 93,186,116,233, 14,224, 80,121,178, 44, 22, + 75,144,201,100,130, 84, 42, 85,158, 60,121,242, 26,195, 48,146,242,228,181,107,215,142, 30, 57,114,228,230,241,227,199,175, 86, + 38, 15, 0,116, 58, 93,247,110,221,186, 89,142, 30, 61,250,232,216,177, 99,247,189,248,226,139,235, 62,252,240,195,116, 63, 63, + 63,183,199,217,182,109, 91,219,193,131, 7,111, 94,190,124, 57,173,101,203,150, 61, 43,146, 71, 8,121, 36, 56, 56,120,220,242, +229,203,185,195,135, 15, 67,167,211,225,218,181,107,152, 50,101, 10, 86,174, 92,137,200,200, 72, 40, 20, 10,124,254,249,231,124, +247,238,221, 39, 17, 66, 54,123, 50, 28, 64, 8,249, 25,128, 31,128,167, 40,165, 55, 75,237,247, 7,240, 51,128, 28, 74,233,144, +170,228, 0, 64,108,108, 44,196, 98, 49, 36, 18, 73,153,232,223,171,175,190,234,254,237,138,197, 98,136, 68, 34, 28, 61,122,212, + 19,145, 46,198, 14, 25, 50,196,252,252,243,207, 39, 52,106,212,232, 81, 0, 89, 82,169, 84, 18, 28, 28,188, 33, 47, 47, 79,190, +100,201,146,254,131, 7, 15, 30, 11,160,220, 26, 23,132,144, 46, 77,154, 52,121,126,234,212,169,146,223,126,251, 13, 86,171, 21, + 17, 17, 17, 88,182,108, 25,242,242,242,176,122,245,249, 75,248,232, 0, 0, 32, 0, 73, 68, 65, 84,106,220,184,113, 3, 6,131, + 1,111,191,253, 54,191,107,215,174,231, 8, 33,235, 41,165, 85,246, 94,212,106, 53, 54,109,218,228, 46,251,238,165,106, 74,194, +255,149,134, 16,203,252,240, 21, 74,213,164, 37, 95, 46,245, 77,186,148,134,130,130, 2,188,241,202, 40,172,254,126, 51,182,237, +216,139, 29,187,127,195,227,125, 30,133, 68, 68, 64, 8,131, 79,231,205,243, 13, 8, 8,152, 86, 93,165, 8, 33,145, 29,218, 54, +235, 21, 16,214,153, 4, 71,143,194,208, 71,195, 69,106,165,108, 8, 33,164,190,167, 50, 74, 27,252,242, 34, 0,174,205,211,158, +236,237, 15,220,219,163, 0, 50,153,172, 90, 61,217,244,244,116,248,251,251, 3, 0,194,195,195,193,178,206,231,245,233,211,167, +177,119,239, 94,156, 62,125,186, 90, 14,192,242,229,203,209,163, 71, 15,216,237,118, 76,153, 50, 5, 18,137, 4,132, 16,140, 31, + 63, 30, 49, 49, 49,152, 60,121, 50,108, 54,155,199,242, 24,134, 41,211,235,119,225,138, 0,212,228,250,149,238,245,187, 16, 4, +161, 70,215,143,231,249,178, 61,127,183, 64,115,185,242, 30,100, 36,160,244,125, 49,123,246,236,119,126,250,233,167,160,187, 29, + 18, 40,125,191,181,108,217, 18, 60,207,163,126,253,250,238,125, 74,165,210, 29, 13,168,233,144,128,146, 99,214, 44,125,119,148, +180,111, 93, 11,123,236,226, 77,252,122,149,193,187,187,114, 44, 51, 15,234,139, 13, 54, 84, 88,178,152,227,184,235, 82,169, 20, +132, 16, 40, 20,138,130,171, 87,175,234,236,118,187, 9, 0, 2, 2, 2,236, 0, 96, 54,155, 77, 91,182,108,209,189,255,254,251, +146, 95,126,249, 69, 5,103,126,250, 42, 57,121,242,164,228, 94,201,219,184,113, 35,151,156,156, 44,234,213,171, 87,207,217,179, +103,175, 9, 14, 14,254,234,155,111,190,105, 14, 0, 14,135,195,250,251,239,191,107,223,127,255,125,242,221,119,223,169, 42,187, +159,121,158,127,127,197,138, 21,124, 90, 90, 26,116, 58, 29, 56,142,115,223,175, 44,203,130,227, 56, 48, 12, 3,181, 90,141,169, + 83,167,242, 10,133,226, 29, 79,218, 10,160, 14,128,206, 0,246, 19, 66,106, 3,110,227,191, 31, 64, 39, 0, 1, 30,202,193,152, + 49, 99, 48,102,204, 24,140, 30, 61,186,140, 3,240,253,247,223,227,199, 31,127,196,175,191,254,138, 61,123,246,224,208,161, 67, +238, 18,233, 30,242, 72,131, 6, 13, 66,131,131,131,143,195, 89,189,116,103,106,106,106,250, 35,143, 60, 98,222,176, 97,195,206, + 22, 45, 90, 52,192, 95,243, 2,238,128,231,249, 87, 23, 45, 90, 36, 77, 73, 73,129,213,106,133, 68, 34,193,173, 91,183,176,104, +209, 34,172, 93,187, 22,133,133,133,238, 33, 85,169, 84,138,201,147, 39,203,148, 74,165, 71, 29, 63,192, 57,191,201, 85,254, 29, + 0, 8, 33,115, 9, 33,115,165, 82,233, 7,213,105,228,127,141, 11,195, 8,117,109,183,127, 86,166,215, 36, 22,139,123, 52, 8, + 9, 65, 98,114, 10, 52, 26, 13, 98,183,237,128,175,198, 23, 10,153, 12, 22,139, 9, 0, 32,149,242,160, 96,208,178, 69, 43, 16, + 66,218, 87, 87,153, 32, 31,241,202, 85, 95,252,207,199,146,254, 11,178,114, 13,176, 16, 21,150,190,255,132,223, 11,239,111,253, + 10,128, 71,229, 39,203, 27,247, 47,253,234,242,130, 93,175, 85,225,234,237,223, 62,246,239,218,228,114,121,153,158,167, 39,136, + 68, 34,136, 68, 34,247,156, 4,135,195,129,188,188, 60, 0, 64, 97, 97, 97, 25, 67,233, 9, 74,165, 18, 10,133, 2, 18,137, 4, + 44,203,194,106,181,226,207, 63,255, 4, 0,156, 60,121,210,227, 8, 0,224,188,126,165, 67,255,109,218,180,113, 71, 37,106,122, +253, 74, 59, 0, 11, 23, 46,116,207, 1,224,121,190,218,215,207,233, 0,152,220, 78,128, 99, 90,128,115, 14,128,213, 84, 35,121, +247,146,210,198, 61, 50, 50, 50,212, 53,107, 63, 33, 33, 1,237,218,181,171,145, 3, 80,250,248, 77,155, 54,161,126,253,250,216, +185,115,167, 59,252,175, 82,169,202,220,155, 53, 65,103,113, 76,120,105,218,146, 95,230,247, 11,100,168,185, 24, 99,191,191,108, + 19,108,182, 47, 45,118,124, 66, 41, 45,168,232, 60,131,193, 16, 34,145, 72,198, 31, 61,122,244, 12, 0,228,230,230, 42,115,115, +115,161, 86,171,141, 18,137, 68,191,120,241, 98,230,226,197,139,178,154,232, 70, 8,185,167,242, 26, 55,110,140,101,203,150,137, +231,204,153,131,165, 75,151,182,156, 49, 99,198,194,166, 77,155, 70,103,103,103,139,197, 98,177, 68, 34,145,120, 34,179,125,120, +120, 56, 82, 82, 82,144,157,157, 13,155,205,134,107,215,174, 1, 0, 50, 50, 50,224,239,239, 15, 63, 63, 63,212,173, 91, 23, 81, + 81, 81,132, 97,152,104, 15,213, 27, 4,224, 0,156,243, 30, 14, 16, 66,158, 2,176, 9,206,121, 11,201, 0,158,242,180,157,155, + 54,109, 42, 55, 2, 48,126,252,120,136,197, 98,247, 38,145, 72,112,240,224, 65, 79,197, 2,112, 70, 47,139,139,139, 15,201,100, + 50,101,114,114,114,122,211,166, 77,179, 1,168,116, 58,157, 66,165, 82, 85,122, 46,195, 48,209,141, 27, 55, 70, 70, 70,134,123, +206,147,175,175, 47,142, 28, 57, 2,135,195,129,182,109,219,194,102,179,185,159, 97,173, 90,181,130,167,215,175,184,184,216,109, +252, 93, 17, 0, 74, 41, 12, 6, 3, 20, 10,133,162, 90,141,252, 15, 81, 85, 50,160, 50, 14,128, 93, 16, 66,101, 50, 25,236,118, + 59, 56, 78, 2,149, 82, 1,169,148,131,197,100, 64,151,206, 49,184,124, 57, 5, 82,169, 12,118,135, 3,156, 68, 12,177, 88, 92, + 89, 9,207, 59, 16,139, 73,183, 55, 70, 60,218, 92, 19,218, 14, 69,191,173,118,238,172,213, 28,143,198, 40, 73,195,250,254, 29, + 8, 33,173, 61, 9,167, 85,230, 0, 16, 66,220,134,203,181, 85,133, 84, 42,189,195,232,187, 30,184,132, 16,183,161,113,245, 60, + 61,107,171,216,237, 0,184,140,171, 70,163, 65, 94, 94, 30,106,213,242,120,202,131, 27,149, 74, 5,165, 82, 9,145, 72,228, 14, +249,183,107,215, 14, 39, 79,158, 68, 84, 84, 84,181, 29, 0, 74, 41, 78,156, 56,129, 54,109,218, 64,171,213, 66,167,211,161,118, +237,218, 53,190,126,130, 32,224,213, 87, 95,197,194,133, 11,113,233,210, 37,164,164,164,160, 71,143, 30, 96, 89,182,218,215, 79, + 42,149, 2,130, 25,204,187, 73,112, 76, 15,196,193, 52, 61, 14, 94, 49, 97, 70, 52,173,145,188,123,137,235,222,224,121,254,142, + 33,129,154, 70, 0, 92, 81,167, 38, 77,154,184,247, 61,241,196, 19, 0,156, 81, 25,165, 82, 89,198, 73,173, 46,132,144,192, 39, +159,124,114,229,148, 41, 83,152,169,111, 78,112, 52,119,164, 50, 22,171,205, 96,181,211, 41,213, 22, 86, 66,113,113,177,236,242, +229,203,218,196,196, 68, 69,105, 35,244,119,144,167,209,104, 48,117,234, 84,102,250,244,233, 56,118,236, 88,173,224,224, 96,143, +138,197, 16, 66, 88, 0,117, 84, 42, 21,174, 93,187,134,183,222,122,171,204,231, 51,103,254, 85,181, 59, 57, 57, 25, 97, 97, 97, + 48, 24, 12,245, 60,145, 77, 41,189, 73, 8,233,129,191,156,128, 83, 0, 56, 56,141,127, 15, 74,105,142, 71,141,195, 95,134, 94, + 34,145, 96,237,218,181,238,253,235,215,175,135, 92, 46,135, 66,161,128, 92, 46,135, 92, 46,175,174, 19,117,220, 96, 48, 52, 58, +126,252,120, 20,203,178, 63, 60,253,244,211, 86, 0, 42, 0,202, 9, 19, 38, 12,185,121,243,230, 85, 56, 87, 4,148,139,217,108, + 14, 86,171,213,176, 90,173,110, 7,192,199,199, 7,171, 87,175, 70, 81, 81, 17,126,249,229, 23, 20, 21, 21,185, 63,139,140,140, +132, 94,175, 15,174, 74, 41,137, 68,146, 87,171, 86,173, 50, 99,254, 26,141,198,188,103,207, 30,239,112,192, 93, 82,198, 1, 16, +137, 68,153,185,121,121,254, 74,133,115,242, 26, 39,145, 64,204, 50, 24,253,242, 24,164,166,166, 65,165,174,229, 52,254,156, 4, +212,225,128, 32, 8,186,234,124,153,255,255,179,119,222,241, 77,214,219, 31,255,156, 39, 79,118,147, 14, 40, 29,236, 33,148, 77, + 89,178,151, 23,244,178, 20, 65, 20, 20, 80,188, 23,245,199, 85, 25, 87,171, 8,130,138, 32,130,162,112,189,128,122,149,161,168, + 12, 69, 68,246, 16, 25, 34,101, 86, 86,129, 66,129,210, 65, 71,246,124,146,231,251,251, 35, 73, 77, 75,211, 38,109, 1,149,188, + 95,175,188,218, 60,121,242,233,247, 73,154,156,243, 61,223,243, 61, 71, 35, 93,250,246,236,183, 35,113,105, 45, 34, 20, 28,158, + 24,220, 1,234,132, 54, 64, 65, 54,150,188, 61,186,230,128,113,139, 63, 1, 80, 97, 84, 33,144, 3, 80,250,241, 80, 35, 0,165, +163, 0, 62,124, 6,199, 55,243, 12, 6, 95, 4,224,224,193,131,104,208,160, 1,106,214,172,137, 86,173, 90, 21, 59, 3,161, 44, + 1, 0, 40, 14, 3, 63,250,232,163,248,231, 63,255,137,246,237,219,227,205, 55,223,132,211,233,132, 32, 8,149,114, 0, 0,143, +129, 49,153, 76,200,203,203, 67, 92, 92, 92,241,227,149,137, 0, 0,158,176,255,133, 11, 23,176,123,247,110,244,237,219, 23, 64, +232,175, 95,241, 18, 0, 0, 8, 54,252,116,217,142, 55,127, 97,152,229,157, 43, 84,230,253,168, 46, 74, 27,226,178,140,126,101, +151, 0,242,243,243,145,154,154,138,129, 3, 7, 98,247,238,221,232,211,167, 15,128,223,223,251, 80,102,197, 68,212, 67, 38,147, +109,149,201,100,138,254,253,251, 75, 82, 82, 82,144,146,146,114, 41,245,120,218,255,157,226,241,129, 32,226,201,202, 92, 63, 0, + 56,157, 78,210,235,245, 18,163,209, 40,113,185, 92, 36,149, 74,129, 32,195,254,183, 67,207, 31,183,219,205,185, 92, 46,146,203, +229, 21,234, 49,198,220, 74,165, 50,239,250,245,235,241, 77,155, 54,197,167,159,126, 10,158,231,145,153,153,137, 89,179,102, 97, +193,130, 5,232,208,161, 3,180, 90, 45,234,213,171,135, 67,135, 14, 33, 34, 34,226,122,176, 99,241, 58, 1, 35, 1,164,194, 99, +252, 29,240,228, 4, 4,109,252, 1, 96,213,170, 85,101, 70, 0, 94,120,225,133,226,227, 62, 35,187,109,219,182,160, 52,189,187, + 46, 14,111,216,176, 97,118,203,150, 45, 91,243, 60,175, 24, 50,100,200,118,135,195,161,158, 56,113,226,131,221,186,117,123,180, +109,219,182,185, 0, 2,214,184, 80, 40, 20,121,121,121,121,181, 35, 34, 34,224,114,185,138,195,253,190, 72,163,111, 9,197, 55, +190,140,140, 12, 68, 68, 68, 84,120,237,254,217,254, 68, 52,151, 49,134,237,219,183,163, 70,141, 26,136,140,140,244, 29,247, 69, + 18, 28,140,177,227, 65, 93,244, 95, 24,255,112,191,255,239,165,163, 1, 37, 28, 0, 81, 20,127, 58,115,230,108,251,134,141, 27, +147,205,230,128, 92, 46, 67, 76, 84, 36,118,238,218, 5,181, 90, 13,155,221, 14,133, 92, 6,185, 76,134,195,135, 15,131,136,142, + 6, 59,160, 8, 21, 63,122,206,139, 15,215, 85,198,212, 3,210, 23,130,151,171,145, 50,117, 18,164, 48, 3, 18, 30,173,146,234, +163,103,151,230,141,164, 82,233,253,130, 32,148,251, 95, 91, 86,226, 95,137,139,242, 36,135, 85,122, 9,160,244, 12, 68,165, 82, +149,152,121, 6,131, 84, 42, 5, 17, 21,207,174, 99, 98, 98, 74, 24,255, 96,119, 20,248,208,104, 52, 16, 69, 17, 23, 46, 92,192, +249,243,231,209,186,117,235,226, 48,123, 40, 73,128,192,239, 75, 0,201,201,201, 16, 69, 17,113,113,113,197,198, 31,168,220,235, +231,114,185, 48,127,254,124, 8,130,128,190,125,251, 22, 27,127, 32,244,215, 79,161, 80,120, 66,255,211,162, 1,193,138, 89, 93, +196, 98,227, 95, 25,189,234,196,103,216,125,134,184, 58, 28, 0,133, 66,129,186,117,235,194,100, 50, 97,224,192,129, 16, 69,177, + 56,114, 4,160, 68, 4, 32, 24, 7,128,136,122,196,198,198,110, 89,176, 96,129,154,231,121, 68, 71, 71, 99,210,164, 73,236,232, +209,163, 93,188,251,235,155, 7,123,189, 26,141,230,188, 40,138,141,187,118,237,202, 34, 34, 34, 10,102,204,152, 49,198,225,112, +112,141, 26, 53,178,243, 60,207, 4, 65,224, 12, 6,131, 76, 38,147,161, 86,173, 90, 66,100,100,100,208,107, 91,185,185,185,124, +122,122,186,194,233,116, 86,139, 94, 89,184, 92, 46,202,207,207, 87, 20, 21, 21, 81,108,108,172, 16, 27, 27, 91,110,178,140, 68, + 34, 57,146,150,150, 54,184, 93,187,118,104,209,162, 5,228,114,121,113, 62, 79,135, 14, 29,208,188,121,243,226,200,224,137, 19, + 39,192, 24,251, 53,216,177,120,215,254,191,193,239,198, 95, 14,224, 27, 34,234, 27, 74,221, 3,159,225,247, 25,123, 31, 43, 86, +172, 40,158,249,251,110, 21,109, 11,246,142,171, 65,114,114,242,207, 79, 63,253,116,221,188,188, 60, 76,155, 54,205,254,206, 59, +239, 12,157, 55,111,222,139, 26,141, 6, 89, 89, 89,153,109,219,182,205, 77, 79, 79,255, 71,121,181, 0,136,232,200,153, 51,103, +106, 39, 37, 37,193,108, 54, 67, 38,147, 21, 39, 63, 3, 40,225, 0,200,100, 50,156, 56,113, 2, 28,199, 29, 9,246,186,125, 24, + 12, 6,212,168, 81,163, 68, 66, 96, 97, 97, 33,120,158, 71,100,100,100,229,214,200,254, 98, 84,212, 3,192, 71, 9, 7, 64,175, +215,125,240,234, 43, 47,143,221,184,233,199, 88, 34, 2, 47,225, 65, 16,145,152, 16,143,188, 27, 55, 32,151, 41, 32,151, 75,193, + 17,225,185,231,158, 45,200,201,201,153, 29,204, 31, 33, 34,105, 98,180,116,238,255, 77,157,169,198,133, 47, 0, 34,216, 85, 45, +208,189,207,255, 33,239,234,111, 80,112, 82,128,227,177,240,173,167, 99,246, 31, 58,255, 31, 34,106, 86, 94,181,168,210,179,255, +178, 30,247,253, 12,117, 9,192, 59,251, 40,129, 74,165, 42,254, 25,170,193,137,136,136,128, 74,165, 42, 54,252, 39, 78,156,128, + 40,138,104,217,178,101, 72, 58,128,231,131, 95,191,126,125,212,169, 83, 7, 78,167, 19, 54,155, 13, 41, 41, 41,224, 56, 14,175, +190, 26,252,174, 76,137, 68,130, 70,141, 26, 85,235,235, 55,126,252,248,106,123,253,148, 74, 37,204, 83,206,222,146,247,163,170, +148, 54,238,254, 75, 2, 85,113, 0,204,102, 51,228,114,121,177,209,247,143, 16,133,226, 0, 16, 81,247,196,196,196,173,115,231, +206, 85, 95,184,112, 1, 82,169, 20, 90,173, 22,105,105,105, 66,101,138,235,120,183, 1,114,114,185, 28, 74,165, 50,142,231,121, +214,177, 99, 71,179, 74,165, 18,207,159, 63, 47, 42,149, 74,183, 90,173,182, 27,141, 70,249,153, 51,103, 34,189,245, 0,130, 74, +202, 92,183,110, 93,205,246,237,219,155, 58,117,234, 20, 80,207,235, 8, 85,168, 23,200,161,150,203,229,238,216,216, 88,187,197, + 98,145,101,100,100,104,206,157, 59,199, 51,198, 2,234, 89, 44,150,185, 41, 41, 41,253,118,237,218,165, 82,171,213,144, 72, 36, +197, 14, 64, 68, 68, 4, 20, 10, 5,100, 50, 25,140, 70, 35,102,207,158,109, 53, 26,141,243,131,185, 86, 34,138,135, 39,225,175, + 57,128,211, 0, 30, 3,176, 22,158, 28,128,221, 68,212, 47,216,247,199,103, 64,125, 78,128,143,241,227,199, 23, 31,247,125,118, +182,110,221, 90,209,184, 26, 36, 39, 39, 31,252,249,231,159, 19,206,159, 63,143,151, 94,122, 9,167, 78,157, 26, 50,120,240,224, +118, 8,177, 16,144,197, 98,249,252,221,119,223,253,219,218,181,107,213,110,183,251,166, 9,132,191, 3, 64, 68, 88,184,112,161, + 89,167,211,125, 30,204, 53,251, 80, 40, 20,230,168,168,168,136,210,199, 14, 29, 58,196, 34, 35, 35, 67, 42,194, 21,166,148, 3, +192, 24,203,210,104, 52,211, 95,159,254,218,130,183,102,191,173,225,165, 82,168, 84, 42,172, 92,185, 18, 74,165, 18, 82, 94, 10, +142, 35, 60,243,204, 51,230,130,130,130, 69,140,177, 51,193,252,145, 26, 26,110,202,212,135,234,213,228,117, 39,128,220, 3,128, + 66, 3,133,140,144,123,249, 56, 20,230,227, 0,199, 3, 18, 30,137,137, 53, 48,250,177,254,181,150,125,182,241, 41, 0,255, 43, + 75,139,227, 56,124,251,237,183,144, 72, 36, 72, 72, 72, 40,115, 7,128,111, 93,216, 55,147, 45, 15,159,135,175, 80, 40,240,192, + 3, 15,148,185, 35, 32, 49, 49, 17,192,239, 51,207, 96, 33, 34,116,236,216,177,196,204,223,255, 22,106, 29, 37,169, 84,138,255, +254,247,191,112,185, 92,112, 58,157,197, 63, 57,142, 11, 58, 2,240, 71,127,253,100, 50,153, 59, 54, 54, 86,114, 43,222,143,170, +162, 84, 42, 89,235,214,173, 75,188, 32,254,209,163,202, 56, 0, 28,199,185, 99, 99, 99,139, 47, 66,161, 80, 96,224,192,129,208, +104, 52,208,104, 52,208,106,181,168, 93,187,118,177,147, 90,209,251,161,209,104, 94,184,120,241,162,218,183,181, 80,171,213, 34, + 39, 39, 7, 68, 84, 97,193,149, 64,248, 47,121,116,235,214,205, 82,250,113,158,231, 89, 66, 66,130, 93,169, 84,178,205,155, 55, + 55, 98,140,233, 3,105, 17, 17,166, 77,155, 38, 2,224,146,147,147, 77, 21,233,253,248,227,143,141,136, 40,160, 30, 0,168,213, +234, 75, 29, 58,116,168,251,222,123,239, 73, 71,143, 30,125,211,107,196,243, 60,171, 85,171,150, 67, 34,145,208,142, 29, 59,154, + 16, 81, 65, 32, 45,198,216, 65,149, 74,181, 98,242,228,201,227,223,127,255,125,185, 90,173, 70, 98, 98, 34,206,157, 59,135,122, +245,234,129,136,160,215,235,241,240,195, 15,219,156, 78,231, 50,198, 88,176, 51,216,181,240, 24,255, 83, 0,250, 49,198,242,253, +114, 2, 90, 1,216, 0,207,110,128,114,201,203,203, 43, 81, 84,204, 23, 1,112, 58,157, 88,183,110, 93,113, 14, 64, 48,159, 13, +127,227,127,249,242,101,124,249,229,151, 56,120,240, 96, 58, 99,108, 39,128,157, 65, 94, 87, 49,140,177,239,213,106,245, 79,159, +127,254,121,255,241,227,199,203,124, 73,193,143, 63,254, 56,204,102, 51,136,168,216, 65,121,229,149, 87, 28, 55,110,220,216,203, + 24,251, 62,148,191, 97,179,217,222,246, 27,127,151,194,194, 66,248,140,191,127, 20, 51, 76,249,161,127, 31, 55,237,157, 54,153, + 76, 31, 71, 68,104,228,169,135, 15,207,120,243,173,217, 53, 59,116,236, 72, 67, 31, 28, 6,147,201,132, 19,199,143, 99,202,148, + 41, 55,110,220,184,241,129, 78,167,123, 39,216,129,240, 28,247,183,249,223, 93, 53,191,183,241,105, 19,192, 1, 68, 0,125, 7, + 96,150,247,119,239,164,129, 8,110, 81,228,212,106,229, 3, 8,224, 0, 52,110,220, 24, 0,112,225,194, 5,116,238,220, 57,168, + 72, 64,121,252,227, 31,255, 0, 0,124,244,209, 71,248,228,147, 79,130,138, 4, 4,139, 47,251,223,255,230,159, 7, 16, 42, 68, + 4,183,219, 93, 28,250,119,185, 92,120,227,141, 55, 66, 90, 2,248,163,191,126, 14,135,131, 7, 0, 34, 98,213,253,126, 84, 21, +171,213, 90, 98,253,147,136,150,249, 47, 9,248, 27,126,223,118,177,138, 40, 93,191,128,136,216, 59,239,188, 83,110, 78, 74,121, +152, 76,166,249, 19, 39, 78, 28,250,201, 39,159, 40, 34, 35, 35,177,103,207, 30,124,240,193, 7, 70,167,211,249, 64, 40,215,234, +195,187, 13,176, 30, 0, 40, 20, 10,227,196,137, 19, 27,204,152, 49, 35, 43, 62, 62,190, 56, 52,111, 50,153,248, 77,155, 54,213, +201,203,203,139, 20, 4, 97, 55, 99,236,124, 32, 61,151,203, 53,106,225,194,133, 77, 0,152,167, 77,155,214,168, 81,163, 70,142, +233,211,167,103, 54,110,220,184,248, 31,216,106,181,242,155, 55,111,174,157,147,147, 19,237,213, 43,183,214,136,197, 98,105, 98, +177, 88,254, 53, 97,194,132,217,111,191,253,182, 98,209,162, 69,178, 30, 61,122, 20, 63,110, 52, 26,165,251,247,239,111,144,159, +159,175,116,187,221, 59, 5, 65,200, 40, 79,207,102,179, 77,222,183,111, 31,122,245,234, 53,110,250,244,233,170,182,109,219,162, +105,211,166, 56,126,252, 56, 82, 83, 83, 49,115,230, 76,155,203,229, 90,102,177, 88,130,221, 2, 8, 0, 55, 0, 28, 0, 48,204, + 55,211,247, 75, 12, 92, 11, 64, 87,145, 0,207,243, 98,124,124,124,153,255, 84,179,102,205, 42,247,121,101, 29, 79, 76, 76, 92, +236, 51,254, 43, 86,172,192,210,165, 75,179,236,118,123,165,254, 79,124, 88,173,214,241, 11, 23, 46,252,229,220,185,115, 9,179, +102,205, 82, 18, 17,134, 12, 25, 82, 92, 1,213, 96, 48, 96,194,132, 9,214,221,187,119,231,154,205,230,241, 85,249, 91, 0,124, + 97,127,138,139,139, 43, 81, 33,241,110,199, 63,251,223,231, 8,148,181, 35,160,204,226, 41,102,179,105, 49, 17,125,255,194,243, + 19, 39,203,229,242, 30, 0,226, 0, 20,186, 92,174,253,249,249,249, 31, 50,198, 46,134, 50,152, 92,189,208,191,114,151, 17,152, + 80,102,178,193, 16,204, 76,214, 87,137, 47, 88,106,215,174, 29,234,101,149,203,144, 33, 67,170, 77,235,143,254,250, 5, 19, 9, + 8,245,253,184, 21,148, 54,250,190,159, 85,137, 76, 84,148,147, 82, 30,140,177, 35, 68,212,159,136,118,124,248,225,135,138,135, + 30,122,200,104,181, 90, 7,132,178, 86,237,143,197, 98,169,239,251,157,136,232,216,177, 99,237, 70,142, 28,217,189,103,207,158, +121, 15, 60,240,192,133, 61,123,246,212,201,202,202,138, 19, 69,241,128,219,237, 62, 81, 81,121,112,198,216, 58,255,251, 60,207, +183,124,234,169,167,250,116,236,216,177,232,193, 7, 31, 60,187,119,239,222,196,171, 87,175, 38,184,221,238, 95, 68, 81, 60, 22, + 76,185,113,239, 57,139,137,104,217,185,115,231,222, 28, 60,120,240,164, 78,157, 58,113, 0,164, 39, 79,158,172, 95, 80, 80, 32, +151, 72, 36, 63,219,237,246,223,130,185,102,111,169,224,255, 35,162, 47,102,205,154,245,170,219,237,238,104, 54,155,227, 52, 26, + 77, 14,199,113,169, 6,131, 97, 14, 99, 44, 96, 54,124, 0,205, 50,139,252,120,139, 2,245, 12, 70,195,229,114,113,214,141,211, +176, 86,215, 12, 28,199, 21,239,122,242,253, 94,214,141,136, 48,104,208,160, 50,157,134,232,232,232,228, 83,167, 78, 97,253,250, +245, 88,178,100, 73,150,213,106,237,201, 24,203, 12,229,186,202,184,158, 27, 68,212,124,203,150, 45,243,182,108,217,242,108,187, +118,237,156,157, 58,117, 82,115, 28,135,195,135, 15, 91,142, 31, 63, 46, 35,162,101, 22,139,229,149, 80,123,192,148,129,163,140, + 53,255, 10,203, 80,223, 77,148,181,247,223,159,128,213,211, 24, 99, 87, 1, 76,174,246, 17, 85, 19,161,204,100,131, 33,148,153, +108, 69,200,100, 50,172, 89,179, 38,168,115,125,201,130,229, 17, 29, 29, 29,244,117, 5,187, 45,230,143,252,250, 1,161, 69, 2, +238, 20, 74,165,210,221,186,117,235,114, 45,189,127, 53,186, 96,144, 74,165,238,122,245,234,149,171,169,209,104,202,213,100,140, +237, 39,162, 94,235,214,173,155, 98, 52, 26, 23,134,106,172,202,209,101, 0,142, 19,209,111,123,246,236,233,186,119,239,222,123, + 93, 46,215, 25, 81, 20,191,171,108, 77,124,151,203,117,154,136,206,254,250,235,175,157, 15, 31, 62,124,175,203,229, 74, 23, 69, +113, 35, 99, 44,248,202, 86,191,143,207, 9,224, 21, 34,154,119,248,240,225, 15,213,106,117,207,130,130,130,116,167,211,121,160, + 50, 29,232, 24, 99, 7, 1, 12, 1, 60, 91, 4,141, 70, 99,104,153,187,213,140, 92, 46,207, 83, 13,157, 19,114,156, 91,161, 80, +148,153,105,127,250,244,233,127,253,253,239,127,159, 99,177, 88,138, 4, 65,120,162,170,198,223,135,247,125,152, 76, 68,115, 14, + 30, 60,120,239,225,195,135,239, 5, 0,151,203,245, 43,128, 95,171,210,232,169,212,223,185,235,179,253, 43,162,162,100,192, 63, +125,139, 81,223, 76,182, 60, 66, 49, 26,254, 89,191,129,240,109, 61, 9,132,175, 50, 92,117, 81, 81,119,191,170,240, 71,124,253, +252,241, 69, 2,202, 59, 71,171,213,222,145, 47,102,171,213, 90,237,159, 31,167,211, 89, 45,154,140,177, 84, 0,163,170, 67,171, + 12,109, 23,128,125,222, 91,117,232,137, 0, 14,121,111,213,161,167, 3, 48,182, 58,180,252, 52,239,168,241, 7,128, 80, 58,250, + 5,131,183, 1, 84,153, 77,160,170, 73, 63, 31,192, 38,239, 45,204,109,164,229, 26, 70,165,103,255,101, 57, 3, 84,133,134,126, + 97,194,132, 9, 19, 38, 76,152, 63, 41,149,139,247,134, 9, 19, 38, 76,152, 48, 97,254,212,132, 29,128, 48, 97,194,132, 9, 19, +230, 47, 70,233, 37,128,178, 18, 2,195, 14, 64,152, 48, 97,194,132, 9,243, 23,164,162, 93, 0, 97, 7, 32, 76,152, 48, 97,194, +132,249, 11, 82, 86, 50,160, 63, 97, 7, 32, 0, 68,196, 19, 81, 34, 17, 85, 75,173, 89, 34,138, 37,162,158,222, 30,224, 97,194, +132, 9, 19, 38,204, 45,167, 60, 39,224,182,108, 3,148,201,100,185,130, 32, 4,189,127, 85,161, 80,228,217,108,182,106,221,242, + 18, 44, 68, 84, 3, 64,243,216,216,216,123, 58,118,236, 40,205,200,200, 0, 17,229, 2,248,137, 49,102,172,132, 94, 35, 0, 43, + 90,180,104,209,163, 73,147, 38, 56,119,238, 28,136,104, 63,128,113,140,177, 75,213, 61,254,191, 10, 68,196, 75,165,210, 39,165, + 82,233, 96, 81, 20,219, 17, 17, 36, 18,201,113,135,195,241,131, 32, 8, 43, 43,187,239,156,168,236, 15, 2, 99,193, 53,207, 8, + 83, 5, 94, 34, 53, 92,208,130,188, 19, 15, 6, 17, 60,140,152,207, 44, 68,196, 49,198,196,242,206,185, 73,111, 50, 53, 0, 33, + 9,228,253, 30, 19,225, 6,112, 22, 11, 89, 38, 17,201, 24, 99,206,242,206,185,245, 23,124,251, 32, 34, 25,128,186, 0,106,193, + 83,117,240, 90,101, 11,237, 16, 81, 83, 0,111, 1,232, 6,224, 32,128, 25,229, 85,119, 12,160,161, 1,240, 32, 60, 91, 81,187, +192,179,197,243, 43, 0,223, 51,198, 66,234, 34, 27,166,234, 4,114, 2,110,203, 54, 64, 34, 98, 38,147, 9, 17, 17, 17, 21,158, +107,179,217,160, 82,169,238,200, 23, 50, 17,201, 21, 10,197,232, 53,107,214, 72,239,187,239, 62, 88,173, 86,152,205,102,108,220, +184, 17,211,167, 79, 23, 76, 38,211,250, 80,156, 0, 34,106, 20, 21, 21,117,114,249,242,229, 17, 15, 62,248, 32,204,102, 51, 76, + 38, 19, 54,108,216,128,148,148, 20,179,201,100,106, 27,172, 19, 64, 68,124,114,114,242,198,182,109,219,254,125,249,242,229,101, +158, 19,138,227,228,253,128,142, 4, 96, 1,208, 49,192,105, 58,198,216,219, 1, 30,187,101, 16, 81, 43,133, 66,177, 54, 57, 57, +185,126,215,174, 93,149,117,234,212,193,141, 27, 55,112,246,236, 89, 92,186,116,201,122,225,194,133,171,118,187,253, 17,198,216, +169, 74,104,135, 29,128, 59,197,100, 74, 0,135, 36,151, 27, 50, 0,112,184,224,122,112, 35,140,187,174, 33, 6, 64, 12,128,162, +126,117,160,219,248, 32, 52,114,222, 99,176,121, 9,156, 16,113, 14, 11, 89, 78, 25,122,127, 7,135,201, 76, 68, 20, 0,152, 5, +216,134,253,128,115,187,174,162, 3,128, 14, 0,142,254,173, 30,142,125, 59, 4,205, 34,164, 80, 2, 0,113,208,131,225,125,188, +207,202,236,146,163, 82,169,134,217,108, 54, 5, 0, 40,149, 74,187,213,106,253,174,188, 75, 34,162, 24,137, 68,210,197,229,114, +109, 14,116,142, 74,165,202,181,217,108,113, 94,205, 60,171,213, 90,238,103,148,136, 58,241, 60,255,137, 32, 8,237, 42, 56, 79, + 2,160, 54,207,243,245,251,245,235, 87,123,204,152, 49,212,191,127,127,236,216,177, 3,171, 86,173, 98,187,119,239,206,118,185, + 92,153, 0,174, 87, 84,199,128,136, 98, 0,204,226, 56,238,177,251,238,187, 47,118,204,152, 49, 24, 48, 96, 0,182,111,223,142, + 85,171, 86, 97,215,174, 93, 55, 68, 81,252, 6,192, 44,198, 88, 81, 57, 58, 99, 1, 60,173, 82,169, 58,245,239,223, 95, 57,120, +240, 96,116,237,218, 21,191,252,242, 11, 54,109,218,132, 29, 59,118,216,172, 86,235, 17, 0,159, 51,198, 66,106, 4, 20,224,239, +101, 2,240, 85,171,188,194, 24,107, 80, 85,205,187,137,219,230, 0, 48,198,176,126,253,250,226, 38, 22,133,133,133,168, 95,191, +126,113, 67, 11,255,159,141, 26, 53,186, 83, 14, 64,231,255,254,247,191,237,158,123,238, 57,108,221,186, 21, 27, 55,110,196,189, +247,222,139,246,237,219,227,211, 79, 63,197,162, 69,139,142,123, 11,172, 4,171, 55,123,193,130, 5,175, 77,157, 58,181, 88,175, + 71,143, 30,232,212,169, 19,150, 44, 89,130,133, 11, 23,190,205, 24,155, 30,132, 14,223,166, 77,155,141,219,183,111, 31,176,116, +233, 82,201,128, 1, 3,110,234, 8, 38,147,201, 80,183,110,221,160, 94, 55,175,241,127, 20,192,183, 0, 58, 50,198,182, 7, 56, +111, 1, 99,236,223, 65,232, 53,209,104, 52,243, 25, 99, 29, 44, 22, 75,109, 34,130, 70,163,201, 18, 69,113,157,201,100,154,206, + 24,179, 85,164,225,167,213, 42, 34, 34, 98,207,140, 25, 51,106, 14, 31, 62, 28,145,145,145, 48, 24, 12, 72, 79, 79,135, 78,167, +195,201,147, 39,145,158,158,142,221,187,119, 23,152,205,230,190,193, 58, 1, 62,195, 31,168, 7,131,175, 2, 98,216, 17,184,133, + 76,161,218, 46, 17,173,248, 15, 88, 12, 0,236,120, 84,142, 53,218,177, 24, 58,116,104,177,145,216,184,113, 35, 70, 26, 87,162, +255, 55,158,138,174,174, 73, 84,196,115, 56,133,247,217,245,155,244,166,210, 96, 38,226,117, 90,200, 58, 1,192,246, 71, 21, 88, +163,121, 2, 67,135, 14, 69,247,238,221,113,224,192, 1,143,158,233, 11, 12,248,198, 14, 0, 96,147, 41,149, 56,188,137,247, 88, +153,197,105,136,104,148,239, 59,209, 91,161, 83, 4, 96, 0, 80,228,189, 21,122, 11, 13,129,136,212, 18,137,164,255,170, 85,171, + 44,163, 70,141,218, 17,232,178,125,223,127,126,154, 2,128,223, 0, 28, 5,144, 10,224,136,175,170, 29, 17,213,231, 56,238,151, +149, 43, 87, 94,121,252,241,199,187,150,163,217,101,232,208,161, 13,134, 12, 25, 66, 3, 7, 14, 44,110,144,229, 79,118,118, 54, +190,250,234, 43,172, 92,185,146,165,165,165,101, 50,198,202, 44,180,212,178,101,203,235, 35, 70,140, 72,108,218,180, 41,250,246, +237, 27, 80,107,245,234,213, 88,181,106, 21,210,210,210, 46, 51,198, 26, 5, 24,151,123,222,188,121,220,132, 9, 19, 16, 21, 21, +117,211,227,122,189, 30,115,231,206,197,187,239,190,235,102,140, 85, 57, 2, 93,250,181, 13,127,126, 75, 82, 81, 67,160,128,111, + 0, 17,109, 4, 16, 13,224, 17,111,189,106,223,241,120,120,170, 71, 93, 15, 84,223, 58, 16, 82,169, 20, 82,169, 20,155, 55,111, +198,226,197,139,241,237,183,223, 22, 59, 1,254,183, 59,136,234,155,111,190, 65,100,100, 36,198,142, 29,107,118,187,221, 39,150, + 44, 89,210,102,203,150, 45,218,191,255,253,239, 88,186,116,105, 51, 34, 58, 18, 76,125,114, 34,146,200,100,178,167,198,140, 25, +131,140,140, 12, 12, 28, 56,240, 34, 99,236,141,165, 75,151,206,220,177, 99, 71,147, 65,131, 6, 97,241,226,197, 79, 17,209,204, +138,188,243, 54,109,218,124,187, 99,199,142,254,181,106,213,146, 0, 37,251,129,251, 59, 78, 33,240, 8,128,111, 25, 99, 69, 21, +149, 33,174, 8, 34,106,173, 82,169,246,111,218,180, 73,211,161, 67, 7,146,201,100,112,185, 92, 56,121,242,100,189,119,222,121, +231,185,157, 59,119, 14, 34,162,214,193,148,118, 37, 34, 94,161, 80,172,157, 49, 99, 70,205,199, 31,127, 28,113,113,113,200,202, +202,194,149, 43, 87, 96, 50,153, 96,179,217,144,144,144, 0,171,213,138,126,253,250,213,220,190,125,251, 26, 34,106, 83,217,229, +128, 48,119,150,222,253,250,161,255, 51,191,247, 87, 26, 50,100, 8,134, 12, 25, 2,231,178,172, 74,233,245,237,219, 23, 3,158, +253,180,248,254,208,161, 67, 49,116,232, 80, 8, 75, 43,167,231,101, 45, 0, 6, 20,151, 66, 6,224,105,113, 46,145, 72,250,188, +253,246,219,238, 81,163, 70, 5,223,172,193,131, 26, 30,199,130,121,101,153, 87, 83,203,113,220,150, 57,115,230,216, 31,127,252, +241,138,106,122,215,156,211,217, 70,104,164, 69, 98,128, 46,120,113,113,113,104,211,166, 13, 70,141, 26, 69,105,105,105, 53, 3, + 9,217,237,246, 90,227, 26, 20, 1, 77,107, 5,236,175, 17, 31, 31,143,118,237,218, 65, 16, 4,164,165,165,213, 41,103, 92, 92, +159, 62,125,112,242,228, 73,232,116, 58,180,105,211, 6,141, 26, 53,194,133, 11, 23,176,117,235, 86,100,101,101,249,122, 91,132, +212, 44, 35, 60,211, 15,157,210,205,127,130,110, 6,228,165, 6, 60,107, 64,187,137,168, 47, 99, 44,207,107,252,247, 0, 72, 2, +176, 63,212, 1, 73,165, 82, 92,189,122, 21,203,150, 45,195,184,113,227,208,190,125,123, 24,141,198, 63,140, 3,192, 24,251,137, +136,126,219,187,119,111, 71, 0, 23, 25, 99, 25, 68,196,111,216,176,161,203, 83, 79, 61,133,182,109,219,170, 82, 83, 83, 99,225, + 89, 99,171,136, 78,125,250,244, 73,172, 85,171, 22, 22, 45, 90, 4,198,216, 82,198,216, 23, 68, 20,183,126,253,250, 5,255,252, +231, 63,145,156,156,156,152,154,154,218, 9, 21,148, 64,109,223,190,253,144, 37, 75,150, 0, 0,126,251,237, 55, 12, 27, 54,172, +132,225,247,111, 11, 26, 36, 86, 0, 29,189,198, 63, 38,148, 39,150, 70,173, 86, 79, 93,187,118,173,182, 99,199,142,200,207,207, + 7, 99, 12, 28,199,161,110,221,186, 88,186,116,169,114,232,208,161,117, 78,158, 60,249, 10, 60,107,138,229, 34,149, 74,199, 37, + 39, 39, 55, 24, 52,104, 16,180, 90, 45, 46, 94,188,136, 75,151, 46,193,100, 50,149,184, 41, 20, 10, 68, 69, 69,161, 73,147, 38, +245,206,158, 61,251, 4,128,229,129, 52, 43,154,249,139,162, 8,147,201, 84,236,100,120,207,119, 48,198,170, 37,249, 51,140, 31, + 12, 34, 47,129,243,135, 97,132, 30, 61,122,192, 41,211,226,151, 13, 27,144,148,148,132,164,164, 36,156, 62,125, 26, 91,183,110, + 69,207,156,108,104,255,221, 20, 23, 50, 46, 96, 72, 35, 56, 33,162,236, 55,143,193, 69, 28,244, 63, 60,228,209,115,200, 34,113, +104,195, 6, 52,107,214, 12,205,155, 55,199,169, 83,167,176,109,219, 54,143,222, 75, 77,113,225,194, 5, 12,105, 12,189, 55, 15, +160, 76,148, 74,165,221,151,248,235, 93, 2,184,233,111,147,231,131,211, 99,244,232,209, 92, 74, 74, 74,132,209,104, 52,106,181, +218,128,151,173, 84, 42,243,136,200,127, 9,224, 38,103,216,155,116,188,126,212,168, 81,242,148,148,148,134, 58,157, 46,189,130, +190, 30,182,150,178, 60, 13, 78,127,128,107,231, 54, 0, 93,159, 65, 98,155, 30,144, 72, 36,176,217,108,216,188,121, 51, 78,159, + 62, 93,226,252, 64, 66, 6,131,193,218, 80,184,168,197, 47,179,112,253,232,114,184, 58,141, 71,189,118,189,193, 73,248, 98,173, + 51,103,206,248,127,134,110,206,199,184,249,154,161, 84, 42, 81, 80, 80,128, 47,191,252, 18, 87,174, 92,129, 82,169, 44,209, 34, +155,136, 26,133,144, 7, 85,223,111,166, 95,223,239,248, 21,191,251, 87,130,212, 10,227,165, 60, 7,224, 33, 0,187,225,233, 85, +189,135,136, 30, 5,176, 6, 30,227,127, 22,158, 89,100, 72, 72,165, 82,204,153, 51, 7, 78,167, 19,169,169,169, 24, 62,124,120, +113,199, 42,141, 70,131,255,252,231, 63,168, 85,171, 86,101,174,163,218, 96,140, 21, 2,216,230,119,168,224,234,213,171, 0,224, +203, 97, 8, 54,108,165,136,137,241,216,214,140,140, 12,192, 19,238, 3,128,163, 62, 61,239,151, 70,133,134,102,249,242,229, 56, +112,224, 0,100, 50, 25,134, 13, 27, 6,153, 76,134,230,205,155,227,234,213,171, 37,162, 1, 33,208,177,116,104, 63,216,112,127, + 25, 12,234,212,169, 19,244,122, 61, 24, 99,197,157, 4, 37, 18, 9,120,158,199,146, 37, 75,212, 61,122,244,120, 93,169, 84,190, + 44,151,203,245, 14,135,227, 75,187,221,254, 78, 89, 61,227,165, 82,233,224, 46, 93,186, 40, 4, 65,128, 78,167, 43, 54,202,165, +111,102,179, 25,140, 49,212,174, 93, 91,125,249,242,229,129, 40,199, 1, 40, 15, 65, 16, 96, 52, 26, 97, 50,153, 96, 52, 26, 97, + 52,134,156,227, 25, 38, 20,120, 24,225,194,185,161, 27, 16,255,235,171,239, 1, 0, 18, 1, 24,141, 70,204,156, 57, 19,217,217, +217, 80, 42,149,200,145,245,135, 66,161,192,219, 27,222, 6,155,132,115,224, 81,246, 27,195,112, 14, 12, 11,135,126,143,254,191, + 78,251, 93,207,100, 50, 97,214,172, 89,200,202,202,130, 82,169, 68,174,226,126, 40, 20, 10,204,254,126, 54,216,100,188, 15,224, + 92,160, 33, 90,173,214,239,136,232, 17, 0,223, 90,173,214, 64,142, 66,167,142, 29, 59,106, 62,255,252,115,245,181,107,215,144, +153,153,137,158, 61, 3, 55,244,179, 90,173,241, 68,100, 6, 80,203,106,181, 90, 3,156,246,223, 78,157, 58,221,179,114,229,202, +250, 89, 89, 89,200,200,200, 64,239,222,189, 3,106, 2, 0,156,102,208,203,105, 0,126, 1,251, 68, 7,227,133,150,208,142, 92, +128,249,243,231,151,255,188, 82, 20, 22, 22,138, 48,223, 0, 55,245, 24,128,131, 16, 63,214,193,144,254, 45,232,254,153,248,240, +163,165,168,234, 50,113,233, 86,229, 62, 61,158,231,143, 16,209,223, 24, 99,199, 42,171, 29,142, 4, 84,141,242,186, 1,230, 19, + 81, 63,120,102,252, 45,225, 89,171,146,195, 99,252,251, 50,198,202,236, 48, 85,238, 31,227,249,226, 55, 63, 34, 34, 2,201,201, +201, 32, 34, 16, 17,172, 86,235, 29,141, 0, 40,149,202, 49,118,187,189,194,254,183, 82,169,244,111,221,225,215, 23, 0, 0, 32, + 0, 73, 68, 65, 84, 0, 86, 86,116,158, 66,161, 88, 91,234,208,158,178,194,237, 82,169,116, 45,128, 10,183, 6,250, 27,250,230, +205,155, 23, 31,171,100, 4,160, 4, 68,180,160,178,207,117, 56, 28, 90,153, 76, 6,167,211, 9,158,231,193,243,124, 9, 39,160, + 89,179,102, 40, 40, 40,224,141, 70, 99,196,181,107,215, 34,102,205,154, 53,105,255,254,253,241, 0,158, 44,173, 37,138, 98,135, + 58,117,234,192,100, 50, 33, 59, 59, 27, 70,163,177, 56,113,210,103,164,205,102, 51,124,223,161, 49, 49, 49, 16, 69, 49, 80, 2, + 99,185,216,108,182, 18,134,223,247,123,152, 91,136, 39,147,223,130, 15,110,254, 28,184,221, 1,108,109, 89,201,127,191, 63,150, + 9, 32, 51, 36,189, 0,201,127,165,208,195, 27,246, 47, 13, 17, 53, 79, 76, 76, 76,220,190,125,187,242,194,133, 11,200,204,204, +196,229,203,151,203,117, 0,188,164, 1, 40,115,169,138,136, 94,174, 93,187,246,224, 45, 91,182, 36,156, 63,127, 30,151, 47, 95, +198,229,203,151,131,112, 0, 44,120,189, 95, 52, 32, 81, 2, 78, 27,180,198,243,112, 59,131, 78,183, 41,137, 41, 23, 51,251,197, + 0,188, 28,112, 90, 17, 73, 87,145, 83,152, 93,101,227, 95, 26,198, 24, 54,109,218,132, 49, 99,198, 96,222,188,121,209,245,235, +215,223, 73, 68, 29,131,136, 4,132,103,250, 33, 82, 58,243, 63,164, 28, 0,160,216, 9,120, 12,192, 17,120,140,191, 3,158,156, +128,144,141, 63,224, 49, 88,115,231,206,197, 83, 79, 61,133,132,132, 4,204,152, 49, 3, 60,207, 23,183,196,245,253,126, 39,176, +219,237,202,178,254,217,173, 86, 43,172, 86, 43, 28, 14, 7,150, 45, 91,134,166, 77,155, 6, 21, 26,182,219,237, 53, 87,175, 94, + 13,198, 24, 86,175, 94,141,213,171, 87,251,142,195,102,179,193,110,183, 99,217,178,101,104,210,164, 73,192,181, 57,127,164, 82, + 41,142, 31, 63,142, 39,159,124,178,248, 88,124,252,239,201,196,129, 66,220,229, 65, 68,141, 1, 60,231,119,191,216, 17, 8, 54, + 26,224,114,185,164,190, 54,194,254,134,223, 63, 10, 32,145, 72, 16, 31, 31,143,248,248,120, 44, 93,186, 84,158,148,148, 52, 28, +101, 56, 0, 0,112,227,198,141, 18,198,190,244,207,192, 19,168,224,241,233,149,158,253,155, 76,225,221, 73, 97, 0,120,146,253, +110,250, 50,136,142,142,110, 16, 17, 17,209, 98,251,246,237,178,140,140, 12, 92,185,114, 5,169,169,169,108,219,182,109,206,231, +158,123,174, 12,153, 18, 28, 5,110, 94,122,136,140,140, 28, 19, 17, 17,241,202,182,109,219,162,125,134,255,240,225,195,226,246, +237,219, 11,255,239,255,254,175,124, 69,167, 13,111,244,136, 0,148, 90,192,105, 1, 32,129,197,168, 11,250, 34, 75, 96, 55, 97, +102, 79, 13, 32,215,120,180,136,131,165,168, 82, 95,243, 1, 97,140, 97,219,182,109, 72, 78, 78,198,162, 69,139, 32,145, 72, 80, + 88, 88, 24,173,213,106, 51, 0,148,155,140, 20,104,166, 31,206, 13, 40,159,138,218, 1,151, 91, 8,200,187,230,191, 22,191, 27, +127, 57,128,111, 42, 91,204, 70, 42,149,162,101,203,150, 72, 73, 73,193,247,223,127,143,243,231,207, 67, 20,197,226,208,241,157, +206, 1,248, 35, 83,137, 48,255,237,130,174, 92,185,130,201,147, 39, 99,210,164, 73,184,118,237, 90,137,124,142, 43, 87,174, 96, +252,248,241, 24, 55,110, 28, 50, 50, 50,144,152,152, 8,187,221,174, 46, 75,136,227,184,163,103,206,156, 65, 81, 81,209, 77, 78, +128,201,100,186,201,248, 23, 21, 21,129,227,184, 35,193, 14, 84, 20, 69,232,245,122,232,116,186,128,183, 48, 97, 0, 20,249, 39, +252, 77,155, 54,173,233,180,105,211,134,198,198,198,118, 29, 59,118, 44, 95, 80, 80,128,195,135, 15, 99,206,156, 57,246, 5, 11, + 22, 8, 39, 78,156,184, 28,132,230, 17,224,247, 92,134,215, 95,127,253,133,105,211,166,101,198,197,197,173, 24, 55,110,156,170, +176,176, 16,191,254,250, 43,222,121,231,157,220,247,222,123,207,112,242,228,201,229, 21, 42, 10, 22,204,220, 93, 0, 56, 45,160, +201, 71, 48,243,135,115,176, 85,214, 1,112, 90,240,198,174, 66,192,105, 1, 55,229, 8,222,216,120, 30,230,194,192,193,151,114, + 56,187,114,229, 74,216,108, 37, 35, 17,140, 49,236,222,189,187,216,248,191,240,194, 11, 0,138,151, 65,171, 66,125,198,152, 47, + 82, 81,191,162,147,239, 54, 42, 42, 5, 92,222, 46, 0,255,132,191,211,240,108, 27, 91, 11,207,114,192,110, 34,234,231,237,247, + 28, 52, 62,163, 48,118,236, 88,220,127,255,253,104,212,168,209, 77, 9,128,190,237, 88, 97, 74, 34,149, 74,209,163, 71, 15,228, +228,228, 20,103,234,218,237,246,226,232, 73,101, 96,140,101, 0,248,183,111,230, 95,201, 28, 0, 12, 24, 48, 0,251,246,237,131, + 40,138,232,218,181, 43,242,243,127,255,183,168, 93,187,118, 89,143,149, 57, 96, 65, 16, 54,101,102,102,222,159,150,150,166,140, +143,143, 47,177,238,239,251, 66,145, 72, 36,136,137,137, 65,126,126, 62,174, 95,191,110,177,219,237, 1,247, 95,251,227,116, 58, +203, 12,249,251,255, 30,142, 0,220, 54, 76,107,214,172,209, 60,244,208, 67,168,169, 75, 67,220,249,175,240,132, 61, 15, 78,165, + 29,123,209, 1,151,220, 13,112,244,232, 81, 0, 8,246, 13, 57,255,205, 55,223, 52, 29, 54,108, 24,106,234, 78, 34, 46,253,107, + 60,110,207,131, 67,229,192,207,104,143,203,238,134, 72, 77, 77, 5,128, 96,139,217, 20,239,115,127,253,245,215, 91,235,245,250, +164,244,244,116, 62, 58, 58, 26,159,126,250, 41,151,158,158, 46,236,219,183, 15, 78,167, 51, 11, 64, 26, 99,204, 17,132,102,241, +238,161,233,211,167,191,149,159,159, 63,249,210,165, 75,106,175,166,236,204,153, 51,230,125,251,246, 49,151,203,245, 45,128,215, +189,185, 72,229,227,118,227,205,253,110,188,209,219, 92,124,223,102, 40, 8,242, 18, 75,193, 68,188,177,223,129,153,189,189,249, +125,110, 1,150,194,236,202, 40, 13,249,232,163,143,222, 90,189,122,245,163, 99,198,140,225, 70,140, 24,129,217,179,103, 3, 0, +198,140, 25, 83,108,252, 87,173, 90,181,110,213,170, 85, 35,128,224,182,222, 18,209, 80,120,118, 79, 0,128,133, 49,182,177, 50, +131,187,155, 40, 43,235,191, 52,229, 89,219,181,240, 24,255, 83,240,172,249,159, 6,208, 23,158, 28,128, 86,240,108, 5, 12, 9, +127, 67,223,176, 97,195,176,241, 15, 1,255,245,126,223, 90,117, 85,140,191, 63,149, 53,252,222,231, 18, 17, 89, 0,224,244,233, +211,112,185, 92, 22,198, 24,249,110,129, 30, 43, 75, 75, 16,132, 21, 23, 46, 92,184,146,158,158,142,140,140,140, 98,163,236, 51, +254,190, 90, 7,114,185, 28, 6,131, 1, 23, 47, 94,188,234,118,187,191,168,104,124,140, 49, 82, 40, 20,136,141,141, 45,158,233, + 23, 21, 21,149,152,249,191,244,210, 75,120,243,205, 55,125,231,135,119, 0,220, 90,246,190,247,222,123, 87, 71,140, 24,129,227, +251,182,194,221,102, 36,146, 22,156,135,179,205, 72, 24,175,157,195,103,159,125,134,173, 91,183, 94, 5,176, 55, 72,189, 65,239, +191,255,254,154,225,195,135,179, 19,251,183, 67,108, 59, 18, 73,243,207,195,213,250, 17, 24,178,210,241,233,167,159,178,109,219, +182,173, 1, 48, 40, 24, 49,198,152, 1, 0,166, 79,159, 94, 63, 59, 59, 59,169,113,227,198,252,200,145, 35, 17, 23, 23, 7,169, + 84,138,125,251,246,185,157, 78,231, 46,198, 88,106,144,198, 31,222,239, 79,188,242,202, 43,163,115,115,115, 39, 55,109,218, 84, + 61,124,248,112,212,170, 85, 11, 60,207,211,129, 3, 7, 76, 46,151,171, 59, 99,108, 98, 80,198, 31,200,188,127, 3,216,177, 39, +224,201, 5,232,173, 68,239, 58, 18,216,117, 37,195,246,217,217,217, 88,185,114, 37, 3,144, 89,142,214,198,251,191, 5, 60, 90, + 86,204,236,165, 66,239,122, 18, 88, 10, 74, 70, 0,114,115,115,177,106,213, 42, 0, 8,104,124, 25, 99, 25,140,177,209, 58,157, +174,197,162, 69,139, 86,245,234,213,171,216,209,254,232,163,143,124,198,255,115, 0,143,150,247, 93, 80, 6,106,198, 88, 26, 99, + 44, 13,191, 59, 2,128, 39, 55,192,247, 61, 24,206, 13, 8,145,242,114, 0,110, 0, 56, 0, 96,152,111,166,239,221, 10,216, 15, + 30,231, 32,104, 87,211,151,233, 31, 44, 18, 73, 72, 91, 68,111, 57,127,132,241,248, 18,253,124,142,128,219,237,174, 22,227,239, +163, 42, 78, 64, 78, 78,206,196,174, 93,187,126,228,116, 58,161,211,233, 38, 6,251, 88, 25, 99,112, 17,209, 35,187,119,239,222, +211,175, 95,191,154, 81, 81, 81, 37,146,144,180, 90, 45, 28, 14, 7, 46, 92,184,128,221,187,119, 23,216,237,246,145,161,214, 0, +240, 95, 94, 8,103,255,223, 25,152,167, 20,236,129,231,218, 81,230,153,189, 63, 36, 71, 70, 70,106, 6,246, 7,178,174, 93,131, + 61,251,156,105,116, 67, 28, 95,114,162,140,194, 63,129,245, 46, 2,120,244,185,118,180,234,212,222,141,239,105, 53,154,166, 3, +251, 63,143,172,235, 89,176,103,159, 61,255,120, 35, 76, 93,114,162,236,194, 63,129,120,230,153,103, 34, 13, 6, 67,231,214,173, + 91,243, 74,165, 18, 27, 55,110,196,182,109,219, 0,192,229,118,187, 83,125,197,128, 66, 97,194,132, 9, 45,245,122,253,178,182, +109,219,170, 85, 42, 21, 54,109,218,132,173, 91,183, 2,128,197,237,118,255,147, 49,246, 91,176, 90,222, 45,202,121,219, 51,209, +246,137, 36,103,189,183,250, 41,209, 32, 81,134,227, 70,207,215,178, 78,167,195,238,221,187,145,150,150,118, 5,158, 40,133,185, + 28,173,113, 68,180,124,231, 21, 44,127,162,185,163,222,155,189, 21,168, 31,235,198,119,133,215, 0, 89, 77,232,245,122,236,217, +179, 7,105,105,105, 87, 24, 99,227, 24, 99, 21, 58,102,140,177,116, 0, 99,137,104, 12,224,249,236, 26,141, 70,159, 3,241, 15, +198, 88,232, 73, 75,101,255,157, 6,213,161,243, 87,165,244, 18, 64,233,136,192,237,171, 4,184, 41, 5,175, 29,148,128,136,192, +113, 92,241,173,172,251, 41, 41, 41,183,189,162, 19, 17, 77, 8,148, 4,232,112, 56,138,147, 1,155, 54,109, 10,198,216,199, 65, +232,177,178, 18,243,252,147, 0,109, 54, 27,154, 52,105, 82,225,181, 18, 17, 43, 40, 40, 40,177,247,191,172,104, 9,199,113,193, +134,211,130,173,240, 87,217,173,129, 85,194, 87, 10,248,158,123,238,169, 87,167, 78, 29,149,111, 63,180, 78,167, 67, 86, 86, 86, +184, 20,240, 95,133,137, 20, 1, 57,234,231, 90,208,224,146, 17,202, 70, 90,216,226,213,200,132, 3, 87,240, 81, 96,131, 21,144, +151,168, 33, 68,140,206,179,224,137, 12, 61, 18,238,137, 70,118,172, 10, 95, 58, 4,124, 45, 95,196, 50,130,149, 25, 61,122,116, +205,130,130,130,190, 6,131,129, 23, 69,209, 23,141,114,187,221,110, 6, 32,221, 59, 11, 13,137,145, 35, 71,118,213,233,116, 59, + 76, 38,147,202,229,114,209,165, 75,151,152,209,104,180,185,221,110, 2,176, 0,192,204, 96, 10,140,149, 5, 17,197, 40,120,180, +159,249, 96, 82,108,187,126,195,241,230, 23,187,145,154,154,122,195,229,114, 29, 11,213, 81, 33,162, 49, 74, 9, 22, 79,236, 32, +141,172,115, 79, 75,172,185,172, 66,106,106,170, 94, 16,132,137,140,177,213,149, 24, 27,243,119,176,181, 90,109,165, 62,107,225, + 37,128, 91,195,109,113, 0,100, 50,153, 91, 16,132,160,227,251, 82,169, 84,116, 58,157,183,117,218, 29,194, 54, 64,155,211,233, + 92, 85,209,121,254,245,191,203, 67, 46,151,231,217,237,246,114,107,131, 43,149,202, 92,187,221, 94,161, 86, 48,117,198, 1,128, +136, 94,131,167,202, 99, 69,220,145, 94, 0,192, 45,109, 6,100, 47,235,120, 56,236,127, 7,120,131, 56,228,162, 38,148,248, 61, +187,149,131, 3, 87,161,195,154,242,171, 99,150,201, 51, 36,133, 18, 93, 33, 65,113,102,153,203,133, 34, 62, 6,199, 48,147,149, +249,190,151, 69,199,142, 29,251, 26, 12,134, 26,122,189,222,166,215,235,205, 46,151,203, 8, 79, 62, 66, 14, 99,101, 52, 37, 10, + 78,115,187,193, 96,184, 87,167,211,101, 27, 12,134, 75, 46,151,235, 12,128, 12, 0, 91, 24, 99,213, 18,186, 38,162,186,113,113, +113,109,243,242,242,142, 51, 22,124, 4, 37,128,214,187, 0, 94, 4, 48,159, 5, 81,174,188, 2,173, 98, 35, 19,118,180,111, 63, +190, 40, 64, 89,249, 0,183,197, 1, 8, 19, 38, 76,152,187, 25,242, 47, 90, 31, 38,204,109,194, 63, 17,176,172,164,192,112,214, + 93,152, 48, 97,194,220, 98,194,198, 63,204, 31,145,176, 3, 16, 38, 76,152, 48, 97,194,220,133, 84,185, 29, 99,152, 48, 97,194, +132, 9, 19,230,143,131,127,246,127,121,197,128,194, 57, 0, 97,194,132, 9, 19, 38,204, 93, 72, 56, 2, 16, 38, 76,152, 48, 97, +194,252, 5,169,168, 14, 64,216, 1, 8, 19, 38, 76,152, 48, 97,254, 98, 4, 83, 10, 56,236, 0,220,165, 16,209, 89,198, 88,243, +202, 62,238,119, 94, 52, 0, 37, 99,172,194,194,225,222,254, 18,106,111, 15,130, 48,183, 0, 37, 79, 6,187, 27, 1, 59,172, 72, + 57,184,228, 60, 9,114,158, 51,200,164,188, 69, 34,145,200, 5, 55,203,205, 51,216,238, 45,171, 58, 27, 17, 21, 0,136, 4, 96, + 4, 96,129,231, 59,195, 9, 79,105, 89, 51, 60,173,172,157,240,180,187, 53,192,211,144,165, 8,192,228,202,214,106,184,147,168, +120, 26,102,115, 67, 1, 0, 28,129, 69,202, 32, 68, 43,224,138,150,195,169,149,195,174,149,193,170,149,195, 90, 67, 6, 75, 93, + 45,140, 83, 90,195,132,255, 4, 46, 7,172,228, 41,215,238, 70, 28, 0,112,128, 24, 41,135, 49, 90, 1, 99,180, 28, 58,141, 12, +121, 90, 25,178, 35,229,184, 26, 45,199,229,122, 90,156,159,210, 30,233, 0,138,104, 97,104,107,179, 68,196,171,213,234,133, 46, +151,107,188, 82,169,204,210,235,245,163, 24, 99,199, 66,189,254,152,152,152,183, 21, 10,197, 84,155,205,182, 76,167,211,189, 24, +234,243,195,252,177,248, 75, 70, 0, 56,142,115, 49,198, 42, 44, 20, 68, 68,110, 81, 20,203,189, 70, 34, 58, 11, 79,207, 3, 31, + 27, 24, 99,195, 42, 59,182, 91,160,151, 10,207,151,233,126, 34,234, 1, 96, 33, 99,172, 83,101,245,252, 72,170,226,227, 62, 36, + 0,230, 18,209, 39,140,177,253,129, 78, 34,162, 14, 0, 70, 3,120, 55, 72,221, 50,241, 47,176, 20,108,225,163,187, 9,187, 27, + 90,177,240, 50,160, 77, 0, 76,121,128,249,134,231,167,233, 6,224, 48, 57,109, 86,139,219,229,180,219, 35,228,146, 34, 18, 93, +133,191,165,103, 40, 30,123,127,187, 50,207, 96,227,224,215,173,206,143,200,156,156,156,235,113,113,113, 60, 17, 89,114,115,115, + 21, 14,135,195, 81,183,110, 93, 19,199,113,198, 99,199,142,169,172, 86,171,189,115,231,206, 69, 50,153,204,240,218,107,175, 21, +206,153, 51, 39, 17, 21,180,119,253,163, 98,115, 67,193,126, 94, 12, 70, 4,178, 20, 16, 51,231,203, 96,211, 73,140, 70,147,184, +245,116,129, 50,202, 85, 40,220, 31,149,237,128,211,108,131, 4, 78,104, 32, 16,145,138,227,184,251, 68, 81,220,202, 24, 19,252, +245,236,110,196,249,233,113,204,156, 31,197,172, 58,185,201,104,116,111, 61, 93,192, 71,185,138,204,247, 71, 95, 47,100, 78, 75, + 30, 60,142,147,137,251, 0,117,184, 69,146, 61,162, 40, 38,123,203, 38, 87, 8,207,243,255,108,209,162,197,248,117,235,214,169, +182,108,217,210,244,229,151, 95, 94, 3,160, 73,168,215,159,156,156,252,210,146, 37, 75,164,201,201,201,227,136,104,106, 89, 78, + 28, 17, 37,200,100,178, 55,190,251,238,187,231, 7, 14, 28, 24, 84, 47,132,170, 32,147,201,114, 5, 65,168,176, 16,154,143, 96, +138,171,221, 45, 84, 42, 2,224,171,220,228,171,218, 84,209,253,219, 13, 99, 76,242,202, 43,175,148, 40, 33,236,235, 73,239,127, + 75, 73, 73,169,208, 73,240,205,114,189,198,117, 45,128,247,170, 56,182,106,213, 3, 48, 25,192, 90, 34,154, 7, 32, 5,192, 35, + 85, 17,243,119, 80, 2,149,197,245, 59,151, 1, 56, 87, 94, 36,128, 49, 86, 64, 68, 75, 1,124, 75, 68, 80, 40, 20,241, 0, 96, +183,219,139,123,115,251,189, 22, 3, 25, 99, 65, 53, 25,247,214, 77, 33,255,159,126,127,211,119, 78,208, 95, 10,165,180,137,227, +184, 20,137, 68,242, 79, 65, 16,154,249,190,228, 36, 18,201, 20,137, 68,242,188, 32, 8, 45, 24, 99,182,114,158,175,148, 72, 36, +103, 24, 99,139,221,110,247,251,222, 99,188, 68, 34, 73,103,140,125, 34,138,226,188, 59,186,239, 91,155, 8,188, 44, 47,113,200, + 41,139,180,111,186,170,112,253,120,201,237,168, 25,169, 53,247,110, 83, 95, 82,167,118,162,188, 77,139,230, 71, 34, 34, 14, 68, +149,211,218, 67, 31, 31, 31,239,140,137,137,153,171,211,233, 24,128,255, 49,198,220, 68,244,180,247,241,229,222,251, 15,193,227, + 64,108, 2,240, 48,128,208, 43,249,253, 81, 96, 34, 6, 60,241, 34,186, 39, 2, 51,187,192, 5,192,156,178, 11,156,213, 5, 65, +193, 67, 84, 54,131,179, 87, 2,172,136,130,133,102, 65, 66, 68,125,222,122,235, 45, 54,109,218, 52, 33,144, 94,255,199, 95, 68, +143,218,192,204, 46, 48, 19,112, 41,101, 23,228, 54, 23, 12,114, 9, 28,138, 36, 20,246,170,131, 43, 0, 50,185, 15,160, 32,162, + 45,111,190,249, 38,123,237,181,215,130,110, 79,169,213,106, 71, 61,247,220,115,170,248,248,120, 60,244,208, 67,248,215,191,254, + 85,143,136, 34,202,235, 1, 80, 26, 34,138,141,139,139, 19,101, 50, 25,122,245,234, 37,221,187,119,111, 65,100,100,228, 10,131, +193,240,162,223, 57, 17, 0, 54, 79,152, 48, 65, 61,112,224, 64, 37, 60,109,226,111, 41,130, 32,196,153,205,102, 40,149,129, 11, +181,250,250,162, 88, 44, 22,104, 52,154, 74,125, 47,252, 21,169, 82, 4,128,136, 58, 48,198,142, 6,123,255,118,242,206, 59,239, + 84,155,150,159,129,122,164,188, 89,236,157,208,243,206,252, 31, 1,176, 15, 64,207,106,208,243, 57, 40, 44,123,127,209, 14,183, + 93,116,186,172,162,195,101,115, 59, 92, 86,183,211,101,118, 59,236, 58,193,218,233,245, 38,147,130,117,240, 24, 99,191,248,198, +232,235,220, 71, 68,245,253,140,182, 19,192,125,140,177,227, 33,140,147, 0,188,204, 24,123, 26,192, 80,198, 88,119, 0,217, 68, + 20, 76,239,245,128, 16, 81,140, 84, 42, 93, 23, 25, 25,121,111, 97, 97,161, 2, 0, 79, 68, 26,185, 92,254,117,116,116,116, 15, +157, 78, 39, 7, 32, 7, 16,208, 1, 0, 32,103,140,213,141,140,140,124, 75, 46,151,223,239,116, 58, 31, 3, 96, 19, 69,177, 65, +141, 26, 53,102,152, 76,166, 1, 68, 52,130, 49, 86, 84,142,198,173,195,236,105,199,252,233,111, 0,207, 1, 79,118,138, 49, 20, +184, 34,197,245,233, 70, 89,164, 70,109, 21,121,133,245, 72,150,141,143,174,163,182, 66, 93, 83, 47,149,202, 0, 32,144,195, 98, + 6,160,119,187,111,178,231,110,148, 52,242,130,223,253, 80,140, 78, 3, 0,115, 1,220, 15,192, 10,207,255,249, 12,111,131,159, +144, 33,162, 6,188, 84, 58,223,237,118, 15,224,136,179, 17, 71,251, 92,130,240,106, 40,122,204,148,135,218, 17, 64,140, 18, 34, + 0,139, 91,132, 37, 66, 10, 94,201,195, 42,229, 96,138,150,193, 8, 7,204, 52, 11,140,136,122,142, 30, 61,154,155, 54,109,154, +166, 34,189,104,185,103,233,196, 45,226,138, 90, 10,181,146, 71, 22,207,225, 66,180, 2,231,224, 49,254,110, 0,223,142, 26, 53, + 74,246,218,107,175,133, 52,123, 47, 42, 42,250, 98,249,242,229,237,134, 13, 27,166,145,201,100,120,228,145, 71,220,235,214,173, + 43,208,106,181,215, 76, 38,211,163, 21, 45, 7, 16, 81,108, 76, 76,204,175,123,246,236,145,170,213,106,188,242,202, 43,170,209, +163, 71,227,233,167,159,158, 0, 79, 73, 96, 16,145, 4,192, 55, 15, 60,240, 64,196,226,197,139, 67,142, 46, 84, 5,181, 90,141, +253,251,247, 23,119, 68,229,121, 30, 29, 59,118,196,153, 51,103,138,239,251,126,134,241, 80,209,236, 31,248,147, 46, 1, 0,192, +233,180,180, 47, 73, 34, 97,162,203,101, 19, 1,139, 75, 16,108,240,124,129,216,192,113, 86,165, 82,233,110,222,188,249,178,138, +116,254,200,198,223,135,215, 9, 64,117,233,249,112,219, 69,231,249,149, 57,169,213,161,229, 27, 35,126,159, 17,200,253,102,234, +178, 80,199,238,157,249, 79, 0,240,153,255,113,165, 82,153,231,155,249, 43,149,202,160,162, 9,126,154, 93,165, 82,233,198,185, +115,231, 70,245,233,211,135,239,220,185,179,155, 49,118,175, 84, 42, 93, 51,123,246,236,152,191,253,237,111,124,231,206,157, 29, +101, 53,113, 42,141, 92, 46,119,109,217,178, 69,245,175,127,253,171,247,201,147, 39,207, 9,130, 48, 82, 42,149,178,109,219,182, +169, 38, 77,154,212,237,240,225,195,233, 68, 52,148, 49,246, 75, 40, 99,172, 22, 44,249, 16, 25,240,197, 89, 64, 37,151,186,135, +116,138,118,169,162, 99,178,227,107,144,198, 73, 50,153,200, 43, 21,109,146, 26, 31,237,218,169,195,249, 13, 7,211,147,204,118, +161,188, 62, 8,252,229,203,151, 35,254,247,191,255,173, 28, 49, 98,132,141,136,158,246, 58,118, 43,188, 51,255,161,222,251, 91, +188,221, 28,123, 0,168, 7, 79,145,177,114, 95, 72, 34,106, 2, 79,203,223,197, 0,166, 2,144, 1,120, 2,192, 94, 34,234,206, + 24,203, 12,229,178,137,168,137, 68, 34, 57,144,220,171,247,254,225,207, 78,124,219,106,177,209,250,165, 75,186,156, 77, 61,120, +128,136,238, 13, 70, 47, 82, 6, 1,166, 92,233,103,253,225, 38, 14,102, 0,102,142,131,229, 95,237, 96, 59, 93, 4, 71,125, 13, +116,173, 52, 48,226, 35,230,198,199,116,111,167, 78,157,212, 43, 87,174,140, 48,155,205,136,136,136,184, 73, 79, 43,131, 17,166, + 92,237,103, 3, 96,231, 8,151, 0,100, 74, 56,100,254,171, 29,178, 79, 23, 34,191,190, 6, 39, 91,213, 68, 58, 45,100, 86,124, + 64,159,117,238,220,185,225,170, 85,171, 26, 5,210, 11,112,221,245, 84, 42,213, 91,243,230,205,139, 96,140,193,106,181, 98,222, +188,121,138,151, 95,126, 25, 91,182,108,105, 50,119,238,220,175, 0, 52, 43,235,185, 90,173,246,109,167,211,249, 60,207,243,138, +159,126,250, 73, 18, 31, 31,207,165,164,164, 56,151, 47, 95, 46, 50,198, 72,169, 84,126,224,119,250,226, 86,173, 90,181,248,225, +135, 31, 26, 88, 44, 22, 92,184,112, 1,237,218,181, 11,106,140,213,129, 68, 34, 41,190, 61,251,236,179, 0,128,167,158,122, 10, + 95,125,245, 21,120,158, 47,118, 2,194,252, 78, 69, 17,128, 63,115, 37, 64,118,224,224,193,125, 39, 79,157, 58,146,113,233,210, +217,252,194,194, 76,147,197,114,195,205,152, 73, 46,151,187, 21,138,160,123,187, 76, 5, 16, 15, 96, 31, 17, 49,111,136,188, 42, + 84,183,158,143,115,213,164, 83,140,219, 33,150, 29,178,172, 60, 87,136, 72, 78, 68,190,248,179, 3,149, 12, 17,122, 35, 0, 55, +205,160,173, 86,107,188, 47, 50, 17,236,250, 63, 17,145, 84, 42, 77,169, 85,171,214,174,195,135, 15,215, 28, 63,126, 60,159,159, +159, 15, 34, 66,108,108,236,182,212,212,212, 90, 19, 38, 76,224, 13, 6, 67,208, 45,150,121,158, 71,167, 78,157, 48,117,234, 84, +249,179,207, 62, 27, 43,147,201,182, 73,165, 82,180,107,215, 14, 83,166, 76,145, 79,154, 52,169,166, 66,161,216, 37,149, 74, 83, +168, 58,251, 54, 7,131, 57, 31, 28,199,137, 83,186,107, 77, 79,117,137, 53,187,149, 49,214,168,154, 9, 69, 19, 7,181, 79, 79, +110, 90,191,160,109, 82,163,188, 65,125,123,164,147, 50, 82,167,183,187,173,140, 56, 43, 2, 71, 0, 28, 86,171,213,106,177, 88, +124,143,187,224,153,237,251,112,122,111,254,247, 77,229,232,249,243, 22,128, 37,140,177,119, 24, 99,217,140,177, 76,198,216,108, +120, 28,130,144,155, 80,241, 82,233,220,182, 61,123, 29,124,101,201,255,182,197, 55, 74,210,215,168,215, 76,247,232,180,121, 91, + 26,182,233,188,159,227,249,160,114, 79, 34,229,112,193, 82, 32, 18, 96,129, 8, 11, 99,176,114,128,165, 65, 36,140,131, 26,161, +176, 85, 20, 76,248,136,185,136,168,101,221,186,117,227,127,250,233,167,136, 27, 55,110,224,212,169,178, 27, 83, 70,201, 97, 98, +150,124,129, 35,100,194,147, 56,121, 5, 64,102, 3, 45,210, 7, 53,196,145, 86, 53,113,158, 22, 50, 51, 17, 77,175, 91,183,110, +255,159,126,250,169, 81,121,122,165, 33,162,186, 42,149,234,215,157, 59,119,198,182,107,215,142,114,115,115,177,125,251,118,152, +205,102, 40, 20, 10,116,233,210, 5,118,187,189, 78,160,231, 11,130, 48,245,220,185,115,154, 67,135, 14, 73, 35, 34, 34,184, 41, + 83,166, 56,191,248,226,139, 44, 65, 16,234, 9,130,160, 48, 26,141,175,122,255,206,191,227,226,226, 30, 60,120,240, 96,131,162, +162, 34,156, 58,117, 10, 39, 78,156, 8,106,140,213,133, 84, 42,197, 11, 47,188, 0,169, 84,138,143, 63,254, 24,105,105,105, 88, +177, 98, 5,164, 82, 41, 70,141, 26, 21,142, 0,148,194,127, 23, 64,160,104, 64,153,175,150,119,205,181, 67,176,247,239, 4,162, + 40, 90, 84, 42, 21, 20, 10, 69,241, 77, 46,151,151,184, 5, 67, 85, 18,244,110,135,158,159,110,133, 25,249,161,226,182,139,206, +138,207, 10, 30,198, 88, 3, 34,202,132, 39, 19, 28,126,142, 64,200,221,206,188, 17,128,126,213, 49, 46,141, 70,179, 38, 38, 38, +102,224,177, 99,199,148, 14,135, 3,103,207,158,133, 86,171,197,191,255,253,111,164,164,164,200, 93, 46, 23, 50, 50, 50, 16, 25, + 25, 25,180, 3,224, 59, 47, 49, 49, 17,143, 60,242, 8,117,235,214, 77,158,150,150,230,246, 29, 27, 62,124, 56,186,117,235,166, +156, 52,105,210,235, 5, 5, 5, 29, 81,197,220,141,144,176, 22, 48,187,188,134,173,119,139,104, 71,100, 76,220, 53,168,107, 24, +210,245,146,104,171, 68,109, 27,255, 80,167,159,160,174, 97, 88,191,239,116,115,163, 67,180,141,127,236,161,141,107,118, 29, 86, +253,150,126, 41,144, 90, 70,203,150, 45,175,118,233,210,101,236,147, 79, 62,233,194,239, 51,255, 7,137,200, 13, 96, 51, 99, 76, + 36,162,238, 68,228, 2,144, 10,160, 16, 21,204,254,189,244, 4,240, 82, 25,199, 87, 2, 8,217,186, 48,145,245, 28,250,143,103, + 22, 22, 21,153, 97, 48, 88, 97, 48,219, 97, 48, 88,209,188,247,131,191, 94, 58,241,107, 74, 48, 26, 49, 74, 56, 97, 41,100, 38, + 1,214,115, 58, 56,239,137,132, 53, 90, 14, 11, 56, 88, 32,194,138, 69, 76, 32,162, 6, 90,173,182,217,161, 67,135,228,217,217, +217,184,124,249, 50, 46, 95,190,140, 46, 93,186,220,164, 23,173,128, 1,150, 66,183,201,137,107,103,138,160,107, 26,133,172,104, +133,199, 9, 0,112,133, 22, 50, 35, 17, 61,174,209,104, 94, 60,116,232, 80,205,138,244,136,136,231, 56,110, 66, 68, 68,196, 19, + 70,163,113,149, 74,165,154,177, 99,199,142, 90,109,218,180,161,139, 23, 47,194,225,112,224,216,177, 99,226,138, 21, 43,108,189, +123,247, 86,127,253,245,215, 22,158,231, 63, 15,116,189, 18,137,228,251, 22, 45, 90, 60,248,208, 67, 15,161, 79,159, 62,242, 47, +190,248,194,237,114,185,186, 48,198,242,253,254,230,136,136,136,136,148,163, 71,143,214,200,207,207,199,229,203,151,145,153,153, + 9,147, 41,232, 20,133,106,161, 91,183,110, 16, 4,161,120,166,239,191, 28,176,103,207, 30,212,172, 89, 19, 22, 75,165,154, 53, +222,181, 4,116,151, 74,175,237, 87,116,255,118,227, 18, 4,155, 84, 42, 45, 97,240, 85, 42, 21,252,157,130, 96,160,250,195, 94, +208, 38,182,126,213,148,115,102,182,152,185,238,163,170,142,171,186,245,146,123,198,190, 80,187,145,250,213,236, 76,203,236, 99, +123,243,171,172,231,143,203, 86,189, 14,128,151,250,126,161,255,170, 38,138, 6,220, 90, 24,138,174, 40,138,215,204,102, 51, 14, + 28, 56,128,164,164, 36,196,197,197,129,227, 56,232,245,122,225,224,193,131,146,118,237,218, 33, 62, 62, 30, 28,199,133,228, 0, + 16, 17, 18, 19, 19, 65, 68,200,201,201,129,201,100, 18,136, 72,226, 59,150,151,151,231,251,146,188, 22,236, 88,171, 10, 1, 34, + 4,135,195, 46,175, 97, 45, 20, 53,118,185, 60,218,168, 80,215,212, 89, 76,130,204, 10,149, 13, 17, 53,245, 36,215, 24, 12,118, +209,170,183, 58,109,144, 71,232,165, 50,185, 13,129,103,236, 38, 0,122, 81, 20, 93, 40, 57,211,247, 95,243,135,247, 49,183, 87, +199, 20,100, 18,164, 12,101, 59, 10, 92,169,191, 21, 20, 12, 76,106, 54, 9,172,160,192, 4,131,217, 10,131,193, 1,179,201, 10, +157,206, 74, 40, 25,181, 8,136,150,135, 83, 52, 23, 58,190,191, 4,183,148,131,211,226,132,179,111,109, 88, 96,131, 5,255,101, +206, 90,181,106, 37,202,100,178, 14,219,183,111,151,250,140,225,137, 19, 39,240,227,143, 63,154, 38, 76,152, 32, 97,172,100, 27, + 99,173, 20,133,204, 92, 88,240,125, 6,236, 60,135, 66,171,128,162,190,117, 61,209, 0, 90,200,244, 53,107,214, 28, 40,147,201, +254,179, 99,199, 14, 77, 41,189,243, 19, 38, 76, 80, 49,198,172,254,122,106,181,122,193,179,207, 62,251,236,132, 9, 19,228,235, +214,173,107, 39, 8,130,180, 89,179,102,220,153, 51,103,224,118,187,241,249,231,159,187, 86,174, 92,121,195,229,114, 45, 57,118, +236, 88, 7,147,201,180, 30,192, 87,129,174,215,108, 54, 63, 74, 68,201,223,125,247,221,193,132,132, 4, 48,198, 56,127,227, 95, +171, 86,173,254,114,185,252,227, 29, 59,118,104, 11, 11, 11, 41, 51, 51, 19,105,105,105,248,237,183,223,142,180,104,209,194, 26, + 72,247, 86,112,232,208, 33, 60,245,212, 83,197, 70,223, 63,236,223,169, 83, 39,236,218,181, 11, 18,201,109,237, 34,255,167,231, +182,196, 75,110,197,174, 2,167,203,101, 45,109,240, 21, 10, 5,252,157,130, 96,136,170,223,105, 65,179, 1,211,164,233, 91,103, +207, 3, 80,101, 3, 91,221,122, 13,146, 52, 11, 6, 62, 94, 79,250,227,170, 43,213,162,231,143,203,234,190, 21, 14, 0,224,151, + 7, 80,153, 39,171, 84,170, 92, 0, 32,162,115,129,182,250,249,118, 7, 4,163,103, 54,155,167, 16,209,129, 71, 31,125,116,249, +107,175,189,166,156, 52,105,146, 68, 34,145,224,127,255,251,159,116,197,138, 21,230,105,211,166, 41, 94,123,237, 53, 62,148, 72, +189,207, 1,136,143,143,199,252,249,243, 93,239,190,251,174,157,231,121,229,226,197,139, 17, 31, 31,143,133, 11, 23,186,103,206, +156,105,179,217,108, 79, 50,198,214, 7, 45, 92, 69, 20, 60, 4,187,205, 42,238,185, 46,209,239,185, 84, 36,225,229,182,198,237, +146,196,200,177,131,251,120,102,254, 63,255,150,164,183,185, 28,195, 6,246,223, 82,163, 86, 66,193,132, 87,231,245,251,237,236, + 69, 0,248, 49,128,100,194,230,205,155,185,119,222,121,103,250,243,207, 63,239, 40, 99,230,223,197,251,249, 61,226,141, 12, 52, + 5, 32, 37,162,252, 32,156,128, 29, 0,198, 2, 40,157,209,251, 36, 60,201,128, 33, 65, 28,183,235,135,207,150,221, 59,248,133, + 89,219,204, 6, 59, 12, 38, 43, 12, 6, 43,206,252,180,190, 11,136,130,210,211,200, 97, 19, 11,175, 10,137, 42, 8, 9, 26, 24, + 90, 68, 65, 15, 23, 44, 51, 99, 95,175,235,124,245,213,230,241,241,241,154,158, 61,123,138,110,183,155,142, 29, 59,134, 85,171, + 86, 57,126,254,249,103,206,237,118, 95, 41,109,252, 1, 64, 35, 67,174, 88,120,213, 24,175,134, 62, 65,141,211, 45,107,224, 20, +128,204,153,154, 25, 15, 11,175,190,154,146,144,144,208,164, 87,175, 94, 78,183,219, 45,241,234, 21,236,221,187, 87, 46,138,226, + 55, 40, 35, 17, 85,169, 84, 62, 53,111,222, 60,121, 70, 70, 6,166, 76,153,162, 60,123,246, 44,142, 29,243,228,247,125,253,245, +215,174,213,171, 87,231,217,237,246,206,193,212,229,240,193, 24, 59,174, 82,169,214,127,252,241,199,237,228,114,249,122, 0,152, + 57,115,230, 83, 78,167,243,229,218,181,107, 55,235,222,189,187,192, 24,147, 28, 63,126, 28, 95,126,249,101,225,238,221,187,165, +110,183,251, 7,198, 88,185,223, 31, 68,116,191, 76, 38,251,196,233,116, 62,206, 24, 11,249,253, 44,141, 90,173,198,119,223,125, + 7,158,231,241,196, 19, 79,224,208,161, 67,232,222,189, 59, 54,109,218,132, 3, 7, 14,132,195,255,165,240, 15,255, 7, 42, 10, +116, 91, 95,177,106,222, 85, 96, 41,109,240, 75, 71, 1,130,129,147,200,165, 0,192, 73,149,234, 50,198, 27,242, 30,252,242,244, + 42,163,201, 75, 73, 10, 0, 82, 57, 87, 45,122,254, 56,138,132, 91,225,193, 95, 33,162,250,190,223, 43, 35, 96,179,217,226, 42, +218,234, 23,106,100,129, 49,182,158,136,142,205,155, 55,111,211,222,189,123, 27,124,245,213, 87, 42, 0,176,219,237,237, 23, 44, + 88,176,102,199,142, 29, 77,215,173, 91,167, 10, 86, 79, 16, 4,152, 76, 38, 12, 26, 52,200,122,242,228,201,243,118,187,125,164, + 92, 46, 63,107,177, 88, 48,108,216, 48,235,161, 67,135, 50,109, 54,219, 96,198, 88,149,118, 45,132,138,156,231,156, 86,187,221, +185,231,178, 67,162, 80, 69,152, 93, 18,153,242, 92,174,149, 4,121,180, 81, 38,215,232,244, 54,183,181,192,104,119,170, 34,107, + 20, 64, 30,161,187,126,163,208,106,182,217, 93,229, 24,107,171,213,106, 53, 21, 21, 21,249, 30, 23,224,201, 3,128,223,125,255, + 89,188, 19,158,100,220, 96,120, 13,192, 1, 34,226, 1, 44,247,234,140, 5,240, 28,128,222, 65,106, 20,227, 22,132,151,207, 31, +253,229,215,111,230,164,112, 13, 59, 63,112,216,230,132, 59,227,224,198,123,117, 87,207,118, 3, 19,187, 7,163,161,149,193, 38, +101, 86, 71,207,122, 48,203, 24,204, 16, 97,153, 17, 61,189,177,174,176,176,229,185,115,231,120,141, 70,131, 31,127,252,145,211, +233,116,174, 67,135, 14,137,118,187,253, 6, 99,236, 56, 99,172,204,216,179, 86,134,235,188,104,203,239, 85, 27,151,101, 18, 79, + 18,224,235, 17,211,255, 81, 84, 88, 56, 35, 61, 61, 93,173,209,104,176,121,243,102,153, 78,167,179, 28, 58,116, 72,112, 56, 28, +123, 25, 99, 83, 25, 99,101,126,118,236,118,251,165,237,219,183,183, 51,155,205,184,114,229, 10, 92, 46, 23,210,211,211,113,234, +212, 41,113,245,234,213,185, 94,227,159, 19,234,107,103,181, 90,159,240,253,254,250,235,175, 79, 46, 42, 42,122,235,220,185,115, +106,149, 74,133,173, 91,183, 74,117, 58,157,245,240,225,195, 14,187,221,126,128, 49, 54,153, 49, 22,112,205, 8, 0,136,168,127, + 84, 84,212,250,119,223,125, 87,253,252,243,207,111, 33,162,129,140,177,159, 67, 29,151, 63,254, 97,255,175,190,250, 10, 13, 27, + 54,196,183,223,126, 27, 94,251, 15,130,144,114, 0,254, 12, 56,157, 78, 75, 89, 97,127,159, 83,192,113,213,146,223, 88,173,123, +240,111,145,102, 72,122,228, 87, 7,160,253, 43,141,254, 85,193,185, 21,214, 1, 40,141, 55, 15, 32,232,217,121, 48,248, 71,136, +168, 84,125,128, 80,116, 24, 99,151,137, 40,249,192,129, 3, 11,155, 55,111,254,164, 40,138, 74, 0,215,140, 70, 99,167, 99,199, +142,189,219,188,121,243,103, 4, 65, 8, 42,106, 97,183,219,249, 6, 13, 26, 88, 29, 14,199, 50,139,197,242, 50, 0, 94, 16, 4, +174, 97,195,134, 86,139,197,178,220,106,181, 78,174,104,134,116, 43,144,203,248,194, 24,141,202, 16, 95, 51, 70, 83,104,135,178, +118, 66,252,217,250,117,235, 94, 95,191,239,183,102, 70,187,219,246,204,152,145,223, 67,166, 54, 60,245,210,236,251,114, 11,138, +108, 91, 54,126,183,116,220, 51,207,151,183,109,239,200,136, 17, 35, 78,143, 29, 59,118,224,172, 89,179, 4,120,178,253, 69, 34, +234,230, 93,243, 63,226,189,127,143,247,126,102,176, 53, 16, 24, 99,153, 68,212, 27,158,100,192, 67, 0, 84, 0,182, 1, 8,121, + 7,128,159, 94,247,236,243, 39,231, 94, 63,119,252, 69, 6,166, 36,146,108, 7, 19,131,218, 1, 0, 0, 81,114, 88, 0,216,101, +158,170,135,150, 87,213,175,196, 22,228,230,182,106,210,164,137,164, 93,187,118,216,178,101, 11, 56,142,195,254,253,251,153, 32, + 8,251, 24, 99, 55, 42,208,187, 2,224,134, 76,226, 9,251, 79, 83,188,210, 35, 63, 39,231,245,123,238,185, 71,149,156,156,236, +211,163, 3, 7, 14,184, 5, 65,120,176, 34, 35,105, 54,155, 31, 31, 49, 98,196, 26,167,211,217,168,123,247,238,152, 56,113,162, + 50, 33, 33, 1, 43, 87,174, 52,219,237,246, 57,149, 49,254,254,188,250,234,171, 67, 10, 10, 10,102, 55,110,220, 88,149,156,156, +140,173, 91,183,226,216,177, 99,116,240,224, 65, 38, 8,194, 8,198,216,238,138, 52,136,232,111,145,145,145,223, 29, 61,122, 84, + 45,147,201, 48,127,254,124,117, 74, 74,202,102, 34, 26,204, 24,251,169, 50,227,210,235,245, 37, 66,255, 82,169, 20, 57, 57, 57, + 80,171,213, 97,227, 95, 5,254,148,175, 28,199,113, 89, 61,123,247,254,160,162,243, 36, 18, 73, 86, 69,231,104, 20, 58,220, 83, +235, 8,234,117, 73,197, 35,255,215,152, 1,128, 75, 96, 66,230, 57,211,191, 25, 99,139, 40,196, 61,248,113, 98, 30,250,186,246, +225, 65,126, 51,222,118,101,174, 41, 0, 0, 32, 0, 73, 68, 65, 84,107, 61,157, 1,128,195,205,132,212, 2,199,191,191,187,193, + 22,121,103,234,243, 0, 44,132,119,230, 94,158,158,202,236, 64,131, 92,194, 3,121,102,188,215, 90, 89,101, 61,230, 87, 7,160, + 60, 3, 90, 69, 35,126,184,146,207, 3,112,243, 86, 63,255, 37, 0,223,152, 42, 59, 54,175, 81,158, 72, 68,219,181, 90,237, 51, + 70,163, 81,240,134,110,167, 16,209, 14,173, 86,251,162,209,104, 44,175, 6, 0, 0,216,212,106,245,206,162,162,162, 15, 25, 99, + 91, 0,207,235, 21, 17, 17,177, 53, 63, 63,127, 25, 99,236,251,202,140,173, 58,144, 75,121, 51,152, 88,208,167, 83, 11,211,249, +124, 7,107,215,170,197,185,102,247, 52,206, 94,185,249,151,182, 58,139,103,205, 31, 50,181, 33,251, 70,161, 53, 43, 39,207, 6, +121,132,126,197,202, 85,229,149,236, 53, 1, 48,184, 61,133, 0,252,207,115,122,239,251, 71, 6, 66,222, 85,194, 60,251,243, 71, +133,250,188, 10,244, 42,237, 84,199,169, 96,134, 27, 14,112,176, 76,176,254, 83,106,200,185,212,181,121,243,230,146,168,168, 40, +108,218,180, 9, 63,252,240, 3, 36, 18,137, 91, 16,132,227, 21, 25,127, 0,168,165,194, 37,120,170, 44,101, 62,103,123, 38, 82, +151,125,105,101, 82, 82,146,202, 95,143,227, 56,171,203,229,250,119, 48, 51,100,198,216, 25, 0,173,136, 72,113,224,192,129,162, + 97,195,134, 33, 42, 42, 10, 29, 59,118,212,166,167,167,143, 1,176,164,178,215,254,236,179,207, 54,213,233,116,171,147,146,146, + 84, 49, 49, 49,248,241,199, 31,177, 97,195, 6, 72, 36, 18,171,203,229,154, 30,164,241,239, 23, 25, 25,185,225,232,209,163,106, +185, 92,142,140,140, 12,116,235,214, 13,203,150, 45, 83, 63,251,236,179,155,136,104, 8, 99,108, 79, 40,227,226, 56, 14,177,177, +177, 65,159, 31,206, 3, 8,158,219,226, 0, 84,247,174, 2,183,219, 93,183,186,198,214, 62,233, 26,251,239,216, 58,244,237, 17, + 51,156,174, 98, 89,233,247,159,103,190, 10,192,103, 96,131,222,131, 63, 68,117,150,205,157,248, 2, 33,235, 58, 16, 27, 93,172, +247,250,209,194, 87, 1, 44,242,134,233, 83,224,153,185,167, 16,209,145,242,180,219, 57,229,172,255,125,171, 8, 59,255, 6,180, +150, 84, 89,207,143,138,182, 21, 86,101,219,225,186, 42, 60, 55,232,237,125, 85,193,107,164,191, 47,117,108, 11,128, 45, 65, 60, +215, 1,224,129, 82,199,220, 0, 6, 86,231, 24, 43, 3,199, 73,148,135,143, 28,151,117,235,216,254,151,238,170,104,195,234,157, + 71, 91, 29,186,112, 35,246,185,113,143,110,128, 44,194,240,228,212, 55,250,102,223, 40,116, 46,249,207,162, 79, 26, 39,181, 42, + 34, 9,255, 52, 0, 48,198, 62, 14, 32,217,224,225,135, 31,206,121,240,193, 7, 87,174, 89,179,198, 77, 68, 93,189, 57, 0,190, +153,127, 99,239,253,171,222,251, 81, 68, 36, 4, 10,137,255,209,233, 88, 3, 38, 72, 32,140,202,121, 76, 85, 80,112,185,159,201, +100,146, 92,186,116, 9,151, 47, 95,134, 94,175,119,139,162, 8, 81, 20, 47, 2, 40, 55, 4, 94,172, 23,135, 11, 0,140,143,101, +143,172, 87, 84,148,177,211,100, 50,169, 50, 50, 50,144,153,153,201,244,122,189, 93, 20, 69, 18, 69,241, 19, 0, 1, 51,245,203, +130, 49,102, 87,169, 84,151, 14, 31, 62,220, 34, 57, 57,153,118,236,216, 97,177,217,108,159, 85,252,204,178,121,244,209, 71,239, + 45, 42, 42,218,105, 50,153, 84,151, 46, 93, 66,102,102, 38,116, 58,157,141, 49, 6,151,203,181, 10, 65, 58, 22, 18,137,100,211, +138, 21, 43,148,114,185, 28, 23, 46, 92,128, 90,173,134, 82,169, 68,175, 94,189,240,205, 55,223,168, 31,126,248,225, 31,225,137, +244, 4,141, 40,138,112,108,120, 9,211,246,137, 32,162,226, 74,175,190, 60, 28,255,234,175, 68,132, 25, 51,102, 84,230, 37,184, + 43,161, 32,163,117,127, 89, 26,180,111,181,182,199,128,164,225, 14,227,241,226, 25,165,224, 16, 45, 87, 47,154, 83,124, 89,247, + 20,100, 99, 28, 0,232,152, 88,127,237,136, 54,245,135, 75,175,167, 22,235,217,220,204,114,162,208,145,178, 46,143,125, 20,234, +154,253,128, 38,138,181,195, 90,199, 15,183, 94,204,171, 22,189,219, 1, 17, 37, 84, 53, 20, 25,166,114,196,199, 68,236,141,138, + 80,171, 53, 17,234,227, 82,169, 76,111,176,218,155, 48,144,165,110, 98,194,247,188, 92, 94,116,242,244,185, 30, 86,155,195,154, + 16, 31,255,225,233, 51,103,156, 68, 52, 1, 8,236, 0, 16,209, 28,120,214,230, 15,193, 19, 13,168,231,253,121,204,251, 51, 6, +128, 29, 64,182,119,109, 70, 5, 64, 96,165,106,226,255,105,120,129, 56, 44, 98, 98,199,142, 29,251, 26, 12,134, 26,122,189,222, +166,215,235, 45, 46,151,203, 0, 79,133,195, 92, 22,100,125,126, 0, 96,147, 73, 78, 11,153,163, 67,135, 14,219, 12, 6, 67, 87, +189, 94,159,173,215,235, 47,185,221,238,179, 0, 46, 2,216,201, 24,187, 80,153,161, 18, 81, 11,181, 90,253,165, 32, 8, 13, 57, +142, 91,110,183,219,167,150,149,136, 24, 12,254,227, 51, 24, 12,151, 93, 46,151,111,124,187, 25, 99, 65, 79, 6, 42,170,219,175, + 80, 40,242,108, 54, 91, 72, 14,190, 76, 38,115,243, 28, 56,135, 16,220,165, 73, 36, 18,209,233,116,134,195, 0, 65,112,215, 59, + 0, 97,194,132, 9,115,171,137,141,141,165,252,252,252, 63,236,151,237, 31,121,124, 68,164, 0, 16,116,101, 55, 0,118,198,152, +253, 86,141,231,175, 68,216, 1, 8, 19, 38, 76,152, 48, 97,238, 66,254,204,165,128,195,132, 9, 19, 38, 76,152, 48,149, 36,236, + 0,132, 9, 19, 38, 76,152, 48,119, 33, 97, 7, 32, 76,152, 48, 97,194,132,185, 11, 9, 59, 0, 97,194,132, 9, 19, 38,204, 93, +200,159,178, 16, 80,152,187, 27,242, 22,237, 15,182,226,220, 31, 17,171,213,154, 80,149,231,171, 84,170, 59,182,205,146,136, 54, + 1, 24,228,189,187,153, 49, 54,168,188,243,195,220,221, 16, 17, 7,160,150,247,110,126,101,183, 42,134, 9, 13, 34, 74, 2, 48, + 2,158,109,188, 12, 30,123, 63,199,255,245, 15, 71, 0,238, 50,136, 40,134,136,222, 34,162,183,137, 40,198,123,108, 19, 17, 49, +239,109,211,157,212,171,224,111, 53, 32,162,245, 26,141,198, 16, 29, 29,109, 34,162, 31,136,168, 89,117,233,223, 41,148, 41,177, + 39, 85,147,213,217,170,201,234,108,101, 74,236,201, 59, 61,158, 32, 24,148,158,158,142,244,244,116, 0, 24,232,253,130, 15, 83, + 14, 50,153, 44, 67, 46,151, 47, 35,162,200, 59, 61,150, 59,192, 47,181,106,213,202, 73, 72, 72,200, 1,112,224, 78, 15,230, 46, +226, 49,198,216,108, 0, 17, 0,230,195, 99,239, 75, 84, 80, 13, 71, 0,238, 62, 94, 24, 55,110,220,244, 26, 53,106,224,253,247, +223, 31, 72, 68,221, 0, 12,242,245,246,214,104, 52,131,136, 40, 2,192, 96,120, 74,170,246, 6,176, 27,192, 63, 24, 99,198,178, +244,198, 62,252,192,244, 26,145, 17, 88,248,249,186, 98, 61,241,215,207, 0,155, 30, 92,159, 41,161,234,149, 9, 17,213,213,104, + 52, 39, 7, 14, 28,104,237,222,189,187,132,227, 56,183, 78,167,107,255,201, 39,159,156, 32,162,118,140,177,244, 42,188, 38,119, + 20,114, 90, 99,177,204,219,252,232, 25,138,253,199, 63,254,241, 53, 99, 12,105,105,105, 39, 85, 42,213,254, 45, 91,182,236, 87, +169, 84, 65, 69, 59, 84, 42, 85, 42,199,113,117,125, 85,210,124, 29, 14,189,213, 44,175, 25, 12,134,144,138, 68, 17, 81, 67, 0, +245, 43, 56,173,159,183, 15, 0,224,153,225,157,174, 72, 87, 42,149,230,186, 92,174, 56,239,239,121, 78,167, 51,190,188,227, 55, +177,244, 62, 5,128,246,240, 20, 34,242,225,132,231, 11,206,255,152,205,123,243, 63,166, 7,176, 11,207,238,186,109,189, 26, 4, + 65,104,212,185,115,231,177,199,143, 31,127,148,136, 38, 1, 88,241,103,142, 96,149, 7, 17, 53,145, 72, 36, 95, 2,144,187,221, +238,231, 1,116, 62,122,244, 40, 12, 6, 3, 90,181,106,117, 47, 17,245, 36,162, 69,241,241,241, 44, 39, 39,103,164,183,124,115, +152,234,199, 87,210,220, 12, 79, 4,192,129, 82,109,191,195, 14,192,221, 71,124,147, 38, 77, 48,125,250,116, 20, 22, 22,182, 91, +177, 98,197, 77, 37, 72,229,114,249,141,190,125,251, 42,135, 12, 25,130, 62,125,250, 96,234,212,169,143,108,221,186,245, 43, 0, +223,149,169, 87, 55, 30,211,159,121, 4,133,133,133,237, 86,110,220,227,209,179, 22, 1, 54,189, 71, 79, 42,185,209,191,195, 61, +202, 71,122, 36,225,239,201,245, 49, 97,241,143,143,108, 56,116,177, 76,189, 17, 77, 61,141,127,214,189,216,211,115,255, 67, 79, + 23,209, 39, 58,213,130,226,158,238,152,251,225,127, 12,209,209,209,187, 93, 46,215,218,221,187,119, 55,171, 91,183,238, 83, 79, + 62,249,228, 2, 0, 67,170,227,197,249, 35,176,114,229,202, 94,130, 32,192,233,116,246,218,186,117,235,136,222,189,123,111,156, + 56,113,226,194, 39,159,124,178, 66,135,137,227,184,186, 63,253,244, 83,156, 86,171, 5,199,113,144, 72, 36,224, 56, 14,118,187, + 29, 93,186,116, 9,105, 28, 68,244, 70,131, 6, 13,166, 55,104,208,160,196, 12, 95, 16, 4,140, 28, 57, 18,118,187, 29,173, 91, +183, 70,100,100,228, 14,192, 83,178,245,250,245,235, 32,162,215, 24, 99,115,202,211,118,185, 92,113, 70,163, 17,162, 40, 34, 42, + 42, 42,174,162,227,101, 80, 27, 57,191, 61,194,204,249,147,138,199, 27,211, 96, 37,220, 2,207, 12,215, 71,255,126,172,209,215, +112, 59,193, 12, 89,143, 21, 31,211,196, 47, 69,124,139, 75, 0, 42,116, 26,137,168, 79, 13, 41,102, 89, 69,180, 7, 0, 21,135, + 99,133, 2,102, 85,166,169,205,250,245,235, 21, 95,127,253,181,226,195, 15, 63, 92, 92, 88, 88, 56,153,136,198, 49,198, 78,132, +162, 65, 68, 60,207,243,135, 69, 81,252,216,237,118, 47,245, 29,151,201,100, 71,221,110,247, 10,183,219,189,200,119,204,231, 76, +241, 60,159, 39, 8, 66,192,234,123, 60,207,231,186,221,238, 56,137, 68,146,231,114,185,138,207,147, 72, 36, 47,242, 60,255,152, +195,225,232,234,119,236, 5,158,231,199, 57, 28,142,242, 74,183, 47,222,185,115,103,103,181, 90,141, 17, 35, 70,252,220,185,115, +103,200,229,114,236,217,179, 7, 73, 73, 73, 48, 24, 12, 63,127,241,197, 23, 48, 26,141, 24, 63,126,252, 82, 0,127, 11,229, 53, + 8, 19, 52,190, 46,157, 28,128, 88,120,122,119,148,136, 0,132, 11, 1,221,101, 16, 81,125,158,231,143,238,220,185,179,198,189, +247,222,139,113,227,198,225,198,141, 27, 96,140, 33, 42, 42, 10,131, 6, 13,194,128, 1, 3,160, 82,169, 80, 84, 84,132,173, 91, +183, 98,238,220,185,206,188,188,188,158,140,177,155,154,252, 16, 81,125, 94, 34, 57,186,227,147, 89, 53,238,109, 94, 31,227,102, +252, 7, 55,138, 12, 0, 19, 17,163, 81,226,161,110,205, 49,244,222,123, 16,169,224, 96, 48, 24,177,241,151,179,120,117,213,126, +103,118,145,165, 76,189, 17, 77,137,173, 59,127,115,163,159,136,136,136, 43,111,190,249,102,236, 11, 47,188,176,153,231,249,157, + 25, 25, 25,191, 14, 25, 50,164, 96,237,218,181,191, 13, 30, 60,152,207,204,204,212,252,153,102, 84,254, 57, 0,226,148,216,139, + 17,204,234,105, 79,172,172,233,254, 63,227,144, 84, 81, 20,209,173, 91,183,196,193,131, 7,215,205,201,201,177, 63,254,248,227, +159, 29, 59,118,236,109,223,115, 2,229, 0,104, 52,154,220,163, 71,143,198,173, 95,191, 30, 74,165,178, 68,151,204,137, 19, 39, +230, 21, 22, 22, 6, 93,134,149,136, 46,101,101,101, 53,172, 93,187,246, 77,143, 93,185,114, 5,122,189, 30, 17, 17, 17,136,138, +138,130, 32, 8, 16, 4, 1, 89, 89, 89,232,214,173,219,101,198, 88,163, 10,180, 25, 99, 12,235,215,175,199,136, 17, 35,138,155, + 59, 5, 58,126, 19, 75,239,107, 42, 94, 59, 58, 11,247,220,215,154,123,114,125, 43,113,249,240, 83,184,250,235, 53,184, 28, 18, + 52,234, 85,151,123,114,125,115,113,249,240,179,184,122,248, 58, 92,118,160, 81,175,218,197,199, 46,238, 62,195,213,105,255, 6, +158,221,245, 91,121, 99,140,146,211,156,134,117,234,190,184, 97,201,124, 85, 66,147,230,112, 23, 92,199,233,159,183,225,177,249, + 43,172, 5,122,227,135,122,135,123, 90, 8,175, 37, 43, 40, 40,192,193,131, 7, 97, 50,153,176,111,223, 62,182, 98,197, 10, 59, + 99,108,181,221,110,255, 55, 99, 76, 31,164,142,130,136, 44, 90,173,214,102,179,217,118, 56,255,159,189,235, 14,143,170,232,222, +239,236,173,219,211, 19,144, 18,138, 16,233, 82, 62, 58, 4, 16, 20, 2,210, 81, 65, 84, 68,253, 68, 5, 62, 16, 81,176, 16, 20, + 41, 98,143, 88, 64,233, 32, 63, 44,128, 8, 9,157,132, 30,164, 35, 16, 32, 64, 8, 33, 9, 1,210,118,147,173,247,252,254, 72, +118, 77, 66,178,217, 32,138,101,223,231,153,103,247,206,206,125,239,185,101,239, 57,115,102,230, 28,155,237, 9, 34,202,103,140, +145,159,159, 95, 65, 97, 97, 97,188,213,106,125,140,136,114, 25, 99,180, 97,195, 6, 68, 69, 69,121, 76,158,197, 24,163,181,107, +215, 98,192,128, 1,174,188, 44, 70, 73,146, 86,233,116,186,174,217,217,217,130,211,233, 20, 24, 99, 70, 89,150, 87, 26, 12,134, +174,215,174, 93,211, 86,194,183,230,185,231,158, 27,208,171, 87, 47, 24,141, 70, 4, 5, 5, 33, 53, 53, 21,215,174, 93,131, 70, +163, 65,189,122,245, 32,138, 34, 22, 44, 88,128,207, 63,255,124, 45, 17, 13,244,246, 58,250, 80,117, 48,198,238, 65, 81,194,173, +239,168, 76,154,105,159, 7,224, 95, 6, 34, 74, 97,140, 61, 50,116,232,208, 77,135, 14, 29,226,190,253,246, 91, 56, 28, 14,119, +201,201,201,193,207, 63,255,140,181,107,215, 34, 62, 62,190,208,102,179,197, 2,248,176, 60,101, 93,146,111,216,203,239,109,250, +101,105, 52,247,127,239, 60, 3, 56,108,128,179,168,228,231,229, 99,221,158, 19, 88,157,112, 18, 91, 14, 95, 42,180, 58,156, 30, +249, 92, 61,255,114,224, 84,171,213, 84, 80, 80,176, 54, 61, 61,253, 84, 68, 68, 68,102, 68, 68, 68, 88, 64, 64,128, 74, 81, 20, +165,162,157,254,234,120,224,129, 7,218,189,242,202,242,236,126,253,250,169, 71,143, 30,189, 59, 45, 57,109,230,170, 85,239, 29, + 7,128, 71, 31,125,180,217,214,173, 91,167,206,156, 57,179,211,184,113,227, 6, 60,240,192, 3,219,182,110,221,186,223, 19,159, + 43, 57,138, 44,203,248,244,211, 79,179,179,179,179,109, 64, 81, 70, 53,167,211,153, 90, 69,241,190,238,218,181,235,187, 53,107, +150,206,189,213,180,105, 83,204,154, 53, 11,115,230,204,193,241,227,199,161, 40, 10,136, 8, 68,132, 43, 87,174, 40, 0,150,121, + 67,110,177, 88,160,209,220,154, 23,166,162,250, 63, 19,140,177,200,230,117,106,140, 63,148,184, 95,195, 86,207, 0, 86, 78,132, +224,116,160, 85,173, 70, 56, 62,253, 73, 77,195,215, 23,142, 99,140,109,174,138, 39,192,117, 95, 20, 69, 65,223,190,125, 89,143, + 30, 61,212, 11, 23, 46, 28,177,125,251,246,161, 28,199, 77, 80, 20,101,145, 55, 70, 44, 99,140,126,252,241, 71,237,132, 9, 19, + 30, 58,115,230,204,105,198, 88, 20, 0,172, 95,191, 94, 51,113,226,196,110,199,142, 29, 59,195, 24,123, 24, 0,170, 85,243,110, +174,169,203,200, 99,140,181,145, 36,105,253,172, 89,179, 2,219,182,109,203,119,238,220,217,193, 24,107, 45,203,242,250, 57,115, +230, 4,117,236,216,145,111,221,186,181, 39,217, 84, 0,166,207,159, 63,191,111,231,206,157,249,228,228,100, 56,157, 78,183, 49, +106,179,217,144,155,155, 11,147,201,132, 47,191,252,210, 1, 96, 58, 99,140,243, 77, 12,188,243, 96,140, 73, 0,234, 20,111,254, + 12, 64,205, 92, 22,182, 11,174, 63,174,175,252,187, 10,128,103,253,252,252,242,187,116,233, 66,157, 59,119,166, 49, 99,198,208, +245,235,215,169, 99,199,142, 4, 32, 14,192, 35, 0,116, 85,226,211,107,242,187,182,168, 79, 93,155,215,163,241,131, 58,146, 18, + 55,157, 34,155,213,174, 26,223,103,157,169, 28,110, 9,192,186,241,227,199,155,151, 45, 91,246,243, 19, 79, 60,209,172,103,207, +158, 29, 18, 19, 19, 87,237,216,177, 35, 3,192, 15,119,251,122, 86,181,152,205,230,106,102,179,185, 90,195,134, 13,231,216,237, +118,101,229,202,149,151,187,117,235,214,199, 85,239, 42,221,186,117,235, 83, 48, 54,208, 65,207,129,232, 57,144,242,162,246,154, +217,108,174, 86, 17,175, 94,175,207, 72, 78, 78,166,121,243,230,145,159,159, 95,198, 29,120, 78, 26, 3,136, 44, 81,222,138,140, +140,164, 27, 55,110, 80,231,206,157, 9,192, 91,101,126,175,227, 37, 47,101,103,103, 83,124,124, 60,161,120, 65,135,167,250, 91, +202, 23,221,235,208, 91,193, 31, 41, 19, 65,215,198,128,250, 53,144,169, 77,221,128,204,179,227, 66,215, 40, 19, 65,174,114, 98, +236, 61,235,218,133, 27, 50,135, 55,145, 41,253,191, 69,117, 52, 45,236, 11,250,162,123,132, 39,249, 2, 5,236,188, 24,187,146, +148,121,255, 37,165, 31,138,202,195,140,148, 81, 53, 73,153, 53,152,126,120,161, 47, 5,234,228,157, 85,184,142,148,147,147, 67, + 9, 9, 9,180,105,211, 38,218,190,125, 59,237,218,181,139,246,239,223, 79, 75,151, 46,165,250,245,235,155,180, 90,237, 9, 0, + 45, 43,225,145, 85, 42,149,131,136,232,179,207, 62,163, 81,163, 70, 41,162, 40, 22, 20, 95, 43, 90,190,124, 57,141, 25, 51, 70, + 17, 69,177, 16, 0,157, 57,115,198,243,117, 44,150,237,212,169, 83, 4,128, 66, 66, 66, 10,142, 30, 61, 74,185,185,185,180,101, +203, 22, 2,160,132,134,134, 22, 28, 63,126,156,242,243,243,105,255,254,253, 30,249, 0, 28, 8, 14, 14,166,193,131, 7,211,153, + 51,103, 40, 38, 38,134, 80, 52,238,124, 13, 64, 86,207,158, 61,105,243,230,205,244,243,207, 63, 83,139, 22, 45, 40, 32, 32,128, + 80,148, 89,242,174,255, 39,255,105, 5,192, 8, 20, 37,241, 34, 0, 7, 80, 52, 36, 32,151,108,227,243, 0,252, 75, 65, 68, 11, + 24, 99,223, 37, 36, 36,180, 0,208, 75, 81,148, 41,118,187, 29,197,157,233,143, 0,196, 3,248,156, 49,214, 5,192,114, 34,138, +246,134, 47,254,232,249, 22, 0,122,129, 28, 83,224,176,128, 20,103,149,248,134,124,178, 11,223,191,248,219, 54, 99,172,102,120, +120,248,206, 17, 35, 70,212,205,203,203, 67, 74, 74, 74,183,215, 95,127,125,159,191,191, 63, 59,186,119,155,250,249,137,175,231, + 1,120,249,119, 94,142,187,134,166, 77,155, 54, 35, 34,150,144,144,144,181,100,201,146, 91, 86, 0, 44, 89,178,228,152,122, 70, + 45,174,228, 36, 65, 79,124, 46, 15,128, 36, 73,238, 58,215, 24,111,121,237, 61, 78,180, 3, 64, 37, 38,244, 21, 47,191,124,239, +137, 39,158,128,213,106,197,240,225,195,177,107,215,174,190, 0,222,161,226, 55, 78, 85, 96,179,217,202,237,233, 87, 84, 95, 6, + 87, 80,173,233,154, 66,155,115, 71,219, 89,199,102,252, 24,187,163,233,133, 11, 23, 66,158,158,252,180,101,215,164,238,238, 57, + 0,255,251,228, 72,151, 49,211, 99, 66,218,182,109,139,174, 61, 59,159, 59, 56,225,190,183, 13,106, 62, 29,192,101, 79,228, 5, + 10, 90, 86,175,215, 16, 88, 49,190,168,130, 23,128,192, 26, 64,224, 61,128, 32,161,117,131, 48, 20,216,156, 45,171,114,190, 46, + 15, 0, 99, 12,130, 32, 64, 16, 4,240, 60,143,214,173, 91, 99,195,134, 13,218, 31,126,248,161,241,204,153, 51,119,251,251,251, +199,100,103,103,191, 90, 25, 95, 80, 80, 16,250,244,233,195, 90,182,108,169, 62,124,248,176, 3, 0, 31, 24, 24,136, 65,131, 6, +177,182,109,219,202, 7, 14, 28,112,104, 52, 26,175,222,241, 90,173, 22, 47,190,248,162, 99,226,196,137,106,157, 78,135,179,103, +207,194,104, 52, 98,220,184,113,206,137, 19, 39,170,245,122, 61, 82, 82, 82,160,215,235, 43,163,250,207,161, 67,135,160, 40, 10, + 78,158, 60,233,190,143,130, 32,168,141, 70, 35,142, 31, 63,142,209,163, 71,187, 27,235,116, 58,228,231,231,123,157, 10,222,135, + 42,225, 27, 34,146, 25, 99,132,162,201,215,183, 12, 51,249, 12,128,127, 49,136, 40,135, 49,118, 77, 16,132,231, 95,120,225, 5, +216,237,118,244,232,209, 3,137,137,137,171,156, 78,103, 82,207,158, 61,219, 78,154, 52, 9, 79, 60,241,196,155,140,177,197, 68, +116,201, 43, 62, 78,245,252,171,131,218, 2, 14, 43, 30,110, 29,142, 61,167,210, 86, 57, 20, 74, 26,220,166,102,219, 79, 30,107, +134,246,239,108,243,138,143, 49, 86,187, 94,189,122, 9,137,137,137,181, 82, 83, 83,241,226,139, 47, 98,207,158, 61, 91,223,123, +239,189, 38, 60,207,115,125,234,241,181, 47, 92,184,214,132,136,170,234,218,254,203,128,136, 80,194,240,250,221, 96,140,193, 98, +177, 64,150,101,168, 84, 69,115,247,156, 78,103,232,254,253,251, 97, 52, 26,193,113,156,187, 88, 44, 22, 68, 68, 68,120,154,104, + 87, 22,163, 58,116,232,208,166, 87,175, 94, 72, 74, 74, 66,247,238,221,209,166, 77,155, 54, 7, 15, 30, 28, 5,160,202,185,232, +157, 78, 39,180, 90,173,215,245,165,240,252, 54, 59,128, 4, 45, 99,115,150, 47, 95,222,180,105,211,166,120,229,149, 87,104,119, +114,238,167,120,126,219, 62, 87,179,109, 99,216, 5,251, 55,223, 60, 55,124,248,112,213,156, 79,231,223,235, 55,104,208,127, 20, + 69, 25,231,141,124,142,107,151, 33, 40, 78, 64, 84, 23, 41,126,151, 1, 16, 88, 3,138, 83, 6, 88,133,195,224,229,130, 49, 6, + 89,150,193,113,156, 91,249,187, 12, 1,142,227, 32,138,162,215, 60, 0, 16, 24, 24, 8,158,231, 97, 54,155,193,243, 60, 1, 69, + 70, 1,199,113, 48,155,205,208,106,181, 94, 15,165,104, 52, 26,104,181, 90,164,164,164,160,118,237,218, 8, 10, 10, 2, 0,240, + 60, 79, 41, 41, 41,104,208,160, 1,130,130,130,220,207,148, 39,100,102,102, 98,199,142, 29, 8, 12, 12,116, 31,223,110,183,235, +178,178,178, 96, 54,155,225, 90,113,164,211,233,160,211,233,220,231,227,195, 93,192,221,118, 83,248,202, 93,117, 17, 85,103,140, + 93,142,137,137,161,148,148, 20, 90,190,124, 57, 37, 37, 37,209,119,223,125, 71, 79, 60,241, 4, 37, 38, 38,210,252,249,243,137, +231,249, 76, 0,188, 87,124,192,229,101, 47, 71,145,178,230,127,180,117,218,195,164,252,223, 51,244,203,140, 40,154,216,187, 33, +217, 22, 12,160,132,201, 29, 72,224, 88,197,124, 37,134, 0,234,212,169,115,250,230,205,155,116,233,210, 37,122,254,249,231, 73, + 16,132, 95, 75,182, 29,124, 47,168,170,231,252, 87, 41, 46, 23,127,131, 6, 13,230,220,184,113, 67,249,250,235,175, 43, 28, 2, + 48,191, 20,224,245, 16,128,193, 96, 56,232,231,231,151, 17, 16, 16,144, 97, 52, 26, 15, 22,223, 23, 58,125,250, 52,189,253,246, +219, 52,119,238, 92,154, 55,111, 30, 45, 90,180,136, 86,173, 90, 85,169,123,184,196,189, 21, 24, 99,233,155, 54,109,162,157, 59, +119,146,209,104,164,184,184, 56, 90,181,106, 21, 49,198,210, 1, 8, 85,124,246, 40, 45, 45,141, 46, 93,186,116,203, 16, 64,121, +245, 21,112,244, 30, 55,110, 28, 17, 17,125,251,237,183,212,174, 93, 59,106,223,190,189,173,125,251,246,182,135, 31,126,216,230, +250,222,174, 93, 59,199,146, 37, 75,136,136,232,213, 87, 95, 37, 0, 67, 43,147, 47, 80,192,206, 3, 51,199,144,242,198, 3,164, +140,137, 32,229,141, 30,164,124,244, 4, 41, 75,167,146,178, 97, 30, 45,155, 62,129, 2,253,140, 59,171,114,190,102,179,153,206, +158, 61, 75,167, 79,159,166,243,231,207,211,165, 75,151, 40, 45, 45,141, 54,111,222, 76,247,221,119,159, 73,175,215,123, 53, 4, +192,113,156,131,136,232,200,145, 35,244,214, 91,111, 41,178, 44,155,139,175, 21, 93,188,120,145, 62,254,248, 99, 69,173, 86, 23, +184,142,233,197,117,164,130,130, 2, 2, 64, 90,173,214,188,120,241, 98,197,108, 54, 83,118,118, 54, 1, 80, 52, 26, 77,193,162, + 69,139, 20, 69, 81, 72, 81,148,202,134, 0,190, 6,144, 17, 20, 20, 68, 43, 87,174,164,117,235,214,209,168, 81,163, 92,251, 80, + 76, 76, 12,133,134,134, 82,104,104, 40,205,157, 59,151,168,104, 39,175,158, 65, 95,169, 90, 1,176,185,248, 51, 17, 64, 47, 20, + 13, 7,136,165,218,220,109, 33,125,229,174, 62, 32,111,142, 31, 63,158, 46, 93,186, 68, 47,188,240, 2, 1,176,116,235,214,141, +182,110,221, 74,191,252,242, 11,125,245,213, 87,164, 86,171, 45, 0, 30,242,150,239,245, 97,237, 72, 89, 51,158,166, 14,106, 73, + 0, 44,253, 90,214,160,171,159, 60, 76,202,194,129,148,240, 74,123,210, 73,156,103,190, 98, 3, 0, 64,189, 49, 99,198,208,153, + 51,103,232,197, 23, 95, 36, 81, 20, 47, 1,168, 89,178,237, 63,193, 0,104,223,190,253,192, 37, 75,150, 92, 73, 77, 77, 85,134, + 14, 29,154,208,163, 71,143,135,178,178,178,170,103,101,101, 85,239,209,163,199, 67,125,251,246, 77, 72, 72, 72, 80,102,204,152, +113,165,125,251,246, 3, 93,251, 85,241, 62, 83, 82, 82, 18,205,157, 59,151, 62,251,236, 51, 90,184,112, 33,125,251,237,183,180, +110,221,186,170, 24, 0, 81,173, 91,183,166,179,103,207, 82,255,254,253, 9,192,185,190,125,251,210,222,189,123,169,105,211,166, + 4,160,111, 85,101, 74, 79, 79,167,226, 28,244, 84, 89,125, 5, 28,243,179,179,179,169, 42,176, 90,173,196,243,252,114, 47,228, +139,172, 27,226,103, 54, 47,152, 68,202,135, 35, 73,137,121,134,148,229,111,145, 18,251, 21,101,111,255, 63, 10, 14,244, 55, 1, +136,172,202,249, 22, 22, 22,210,229,203,151, 41, 37, 37,133,210,210,210, 40, 41, 41,137, 70,142, 28, 89,168, 86,171,115, 57,142, +123, 26,197,171,178, 42,225,145, 57,142,115, 92,187,118,141,162,162,162, 10,180, 90,237, 69, 0,141, 0, 80,126,126, 62, 61,242, +200, 35,133, 90,173, 54, 21, 64,115,151,210,245,198, 0,112,181, 3,208, 92,167,211, 93,121,250,233,167, 11,111,222,188, 73, 28, +199,217, 1, 52,211,233,116,169,195,135, 15, 47, 52,153, 76,222,240,221, 31, 18, 18, 98, 79, 76, 76,164, 45, 91,182,208,209,163, + 71,221, 6,128,201,100,162,244,244,116, 74, 79, 79,167,252,252,124,175,228,243,149,223, 87, 0,212, 64,209, 60,172, 91,230,189, +220,117,225,124,229,238, 21, 0,223,205,159, 63,159,118,238,220, 73, 0,110, 2, 8, 3,240,174,193, 96,112,116,239,222,189, 74, +202,223,197,183,230,181, 40,186, 56,111,120, 41,190, 0,173,224, 24,220, 50,172,114,229, 79,165,149,186, 90,173,142,191,255,254, +251, 73, 20,197,243, 0,106,223,210,190,156, 9,131,127,151, 82,178,151,159,255,156,198,236,234,225,155,199, 6, 58, 6, 15, 30, +188,111,208,160, 65,251,222,126,251,237,148,248,248,120,229,251,239,191, 47,168, 95,191,254,103, 37,247,169,226,125,166,243,231, +207, 83, 76, 76, 12,125,243,205, 55,180,114,229, 74, 90,187,118, 45,109,222,188,185, 42, 6,192,183,209,209,209,244,203, 47,191, +144, 70,163,113, 2,104,173, 86,171,157,113,113,113, 52,110,220, 56, 2,240,109, 85,101,202,202,202,186,165,135, 90, 81,125, 5, + 28,131,167, 76,153, 66, 68, 68,107,214,172,161,135, 30,122,200, 93,158,121,230,153, 82,219, 43, 86,172, 32, 34,162,119,222,121, +135, 0, 12,241, 70, 70,163,200,207,172, 25,228,103,250,126,220, 16,186,244,249, 36,186,184,108, 14, 45,155, 49,153,130, 3, 3, + 76, 70,189,126,102, 85,207,215,106,181,210,181,107,215, 40, 51, 51,147, 62,249,228, 19, 69,175,215, 23,232,116,186,175, 1,248, + 85,129, 71, 86,169, 84,202, 61,247,220, 99,214,233,116, 43, 1,104, 92,252,225,225,225, 38,189, 94,255, 35,138, 39,219, 2,168, +180,199, 94, 94, 59, 0, 58,163,209,184,166, 78,157, 58,102,142,227,236,174, 58,189, 94,255, 67,120,120,184,201, 11,190,173,235, +214,173,163,163, 71,143,210,146, 37, 75,232,192,129, 3, 62, 15,192, 93, 40, 0,186,160, 40, 10, 96,100,137,162, 42,213,230,110, + 11,233, 43,119,245, 1,121,239,181,215, 94,163, 99,199,142,145, 74,165, 42,196,111,113, 33, 26, 2,120, 28, 64,163,170,242,205, + 29,217,142, 44, 75, 71,146,138,225,182,248,202,246,234,139,173,215,242,221,203,255, 16, 3,128,158, 3,185,241, 28,232,208,161, + 67,180,127,255,126, 74, 72, 72,160, 89,179,102, 93,189,247,222,123,191,156, 55,111, 94,195,223, 99, 0, 92,188,120,145,190,254, +250,107, 90,185,114, 37,173, 89,179,134, 54,109,218, 68,187,118,237,242,234,229, 11, 64, 39, 8,130, 57, 33, 33,129,102,206,156, + 73, 0,182, 20,215,111,153, 50,101, 10,173, 88,177,130,120,158, 55,163,106,171, 70, 40, 63, 63,255, 22, 5, 85, 81,189, 7,158, + 79,190,255,254,123,178,219,237,212,181,107, 87,103,241, 75, 78, 46, 81, 90,182,111,223,222,102,181, 90, 41, 54, 54,150, 56,142, +251,170,138,215, 46, 50, 80,175,221,169,150,196, 60,181, 36,230, 5,250,251,237, 68, 21,122,254, 37,207,203,100, 50,209,158, 61, +123,168, 73,147, 38,249, 6,131,225, 24,128, 22,183,193,195, 27, 12,134,125, 28,199, 61, 89,178,222, 96, 48,236,225, 56,238,217, +146,117,106,181, 58, 3, 0,169,213,106,143,171, 65, 42,106, 39, 8,194,115, 70,163,113, 71,201, 58,142,227,158, 53, 24, 12,123, + 42,145,113,213,192,129, 3,233,233,167,159, 38,198, 88, 78, 96, 96,160,207, 3,112, 23, 10,128,205, 0,234, 3,216, 89,162,248, +134, 0,124,197,253,128, 60, 59,108,216, 48, 58,122,244, 40, 85,171, 86,141, 80,198,197,126, 59,124,207,117,191,151,148,165,143, + 82,173, 64,245,237,241, 85, 65,169,255, 19,134, 0,202, 51, 0, 30,122,232,161,248, 94,189,122,197,223,123,239,189,159,182,110, +221,122, 88, 86, 86, 86,245,178,115, 3,170,120, 95,232,212,169, 83,180, 98,197, 10,250,241,199, 31, 41, 46, 46,142, 18, 18, 18, +232,224,193,131,222, 42,217,208,186,117,235, 82, 98, 98, 34,117,232,208,129, 0, 60, 81, 92,255, 68,203,150, 45,233,187,239,190, +163,123,238,185,135, 0, 52,247, 86, 38, 89,150, 51, 80,228,114, 38, 89,150, 51, 42,171,247, 32, 27,111, 52, 26,247,156, 60,121, +146,126,250,233, 39, 2, 16, 93,230,247, 9, 75,150, 44,161, 11, 23, 46, 80,112,112,240, 47,101, 95,128,127, 86, 1, 64, 79, 61, +245, 84,161, 70,163,201, 97,140, 61, 5, 47,220,253,127,215, 2,192, 8,224, 75, 20, 77, 12, 13,113,221, 79, 34,159, 7,224,175, + 86,124,145, 0,255,197, 96,140,117,110,218,180,105,194,194,133, 11, 49,124,248,112,156, 59,119,174, 5, 17,221,118, 50, 26,198, + 88,231,255,212, 13, 72,216,255, 70, 87,180,120,107, 43,142, 95,201,175, 58,223,188, 46, 4,252, 22, 2,184,108, 72,224, 91,182, +203,137, 26,248,119, 64,201, 72,128,234,201, 33,199,152,221, 28, 12, 0, 36,104,179, 10,223,187,214,188,178,253,171,146, 13, 80, + 20,197, 12,187,221, 94,238,108,127, 89,150, 51, 11, 11, 11, 61, 70, 7, 44, 94,254, 23, 23, 22, 22,214, 43, 35, 35,227, 23, 0, +157,137,200, 82, 28,104,100, 93, 72, 72,200,131,215,174, 93,219, 6,160, 39,221,133, 23, 10, 99, 44, 84,171,213,206,151, 36,169, +250,205,155, 55,159, 36,162, 83, 37,126, 11, 11, 8, 8,248, 9,128,253,230,205,155,195,136, 40,237,207,150, 15, 0,180, 90,109, +178, 74,165,218,106, 50,153, 38, 19, 81,238,221,144,225,110,129, 49,246, 53,128,209, 21, 61, 26,197,121, 42,254,150,255,227,191, + 50, 24, 99, 77, 1,236, 42, 83, 29, 74, 68, 86,119, 27,159, 1,240,239, 6, 99,108, 71,181,106,213, 34,211,211,211, 55, 2, 24, + 84,242,225,184, 93,190,218,129,234,200,148, 27,133,119,132,239,159,138,191, 91, 58,224, 98, 35,160, 38, 17, 93, 46, 83, 47, 0, +240, 7,112,147,136, 28,229,238,236,195,191, 30,106,181, 58,195, 98,177,220,182, 17,234, 67,213,193, 24,203, 5, 80,234,154, 19, +145,165, 84, 27,159, 1,240,239, 70,113,232,206, 80, 20,101,113,251,221, 47,240, 59,205,231,131, 15, 62,248,224, 67,213,193, 24, +179, 16,145,236,169,141, 47,143,247,191, 28, 68,164, 16, 81,250,157, 82,214,119,154,207, 7, 31,124,240,193,135,219, 66, 23,198, +216, 1, 79, 13,124, 30, 0, 31,124,240,193, 7, 31,124,248,135,129, 49,102, 65, 81, 30,149,146, 80,151, 28, 6,240, 25, 0, 62, +248,224,131, 15, 62,248,240, 47,132,111, 8,192, 7, 31,124,240,193, 7, 31,254, 97, 96,140,229, 48,198, 44, 37,202,127,202,182, +241, 25, 0, 94,130, 49, 22,201, 24,139, 46, 46,145,119, 91, 30, 31,124,184, 91, 96,140, 25, 25, 99,147, 24, 99,171,139,203, 36, +198,152,209,203,125,249,134, 13, 27,158, 27, 53,106, 20, 49,198,110, 41,130, 32, 84,121,238, 8, 99,140,191,239,190,251, 42,228, +148, 36,201,107,206,202,228, 19, 69,209, 55,183,197,135,191, 11, 66, 1,248,149, 40, 91,139,151,238,186, 81,105, 54, 64,198, 24, + 7,160,151, 36, 73,207, 58, 28,142, 30, 60,207,111,183, 90,173, 11, 0,108, 34, 34,167,183,146, 48,198, 66,121,158,111, 28, 20, + 20,212,154, 49,214,220,110,183,215, 22, 4, 33,133,136,142, 93,191,126,253, 23,135,195,241, 43, 17,101, 86,237,252,254, 84, 68, + 42,118,203, 52,112,162, 43, 35,214,206,202,118, 40,190,118, 15,138,162,248,172,195,225,232,206,243,252,118,155,205, 86,229,107, + 87,130, 47, 28,192, 11, 0, 30, 68, 81,132,167,203, 40,138,241,252, 37, 17, 37,221, 6, 95, 43,163,209,248, 10, 99,172,173,201, +100,170,161,211,233,174, 16,209,129,220,220,220,185, 68,116,232, 54,248,218,202,178,252, 18,128,142, 54,155,173,134, 40,138, 41, + 0,118, 91, 44,150,143,111, 39,190, 0, 99,172,163,191,140,151,136,208,222,100, 71,117,131,136, 75,138,130, 61, 57, 54,124, 64, + 68, 39,171,202,231,195,239, 7, 99,172,189,159,159,223,215,131, 6, 13,178,212,170, 85, 43, 92,175,215,163,176,176,176,222,231, +159,127, 62,138, 49,246, 12, 17,237,243,176, 47, 31, 17, 17,113,116,211,166, 77,245, 23, 45, 90,132, 77,155, 54, 65,150,229, 82, +165, 97,195,134, 92, 21,229, 41,197,169, 40, 10, 28, 14, 7,114,115,115,145,147,147,131,220,220, 92,180,110,221,218, 43,206, 63, + 66, 62,192,115, 28,134,178,240,102, 73,220,157,230,243,225,159, 9,215, 18,236,226,116,192, 0,208,190,236,178,236, 10, 13, 0, +198, 88, 35, 73,146,158, 17, 4, 97,164,191,191,127,206,195, 15, 63,124,108,228,200,145,159, 45, 91,182,172,225, 79, 63,253,244, + 73,118,118,182,159, 44,203, 75,173, 86,235, 55, 37, 3,111,148,133, 78,167,139,149, 36,169, 78,131, 6, 13, 76, 13, 26, 52,184, +209,184,113,227,107,237,219,183,191,218,161, 67,135, 19,123,247,238, 13,220,183,111, 95,211, 95,127,253,181,199,217,179,103, 3, + 3, 2, 2,116,133,133,133, 23, 11, 11, 11,123,123, 58, 49,198, 24,253,209,129, 35,138,123,249,145,197,155, 59, 1, 0, 54, 51, + 32, 86,126, 88,198, 88, 35, 81, 20,159,225,121,254,113, 63, 63,191,236, 62,125,250, 28, 12, 12, 12, 92,117,253,250,117,109,108, +108,236, 71, 57, 57, 57,254,146, 36, 45,183,217,108, 95,123,186,118,101, 56,159, 1,240,110,157, 58,117,182, 50,198,110,206,152, + 49,227,149,233,211,167,247,183, 90,173,126,151, 46, 93,218,201, 24,123, 31,192,135,222, 4, 98, 97,140,241, 90,173,246, 93,163, +209, 56,246,141, 55,222,144,219,183,111,207, 26, 54,108,136,164,164,164,240,125,251,246,213,158, 49, 99,198,195, 58,157, 46,198, +108, 54,191,238,205,108,126,198,152, 40, 8,194,251,146, 36,141, 30, 61,122,180,166,113,227,198,144, 36, 9,103,206,156,169,127, +232,208,161,122,187,119,239, 30, 38, 8,194, 7, 14,135, 99,186, 55,134, 15, 99, 76,214, 8,248, 40, 64,198, 19,239, 15, 12,215, +116,104,217, 20,213,131,140, 56,127,254,236,189, 9,135,207,212,159,182, 45,111,168, 90, 96,239, 91, 28,120,155,136,238, 76, 30, + 93, 31, 42, 5, 99,204,232,239,239,255,245, 11, 47,188, 16, 58,106,212,168, 99,213,171, 87,255, 38, 47, 47,111,215,158, 61,123, +238, 91,176, 96,193, 43, 99,198,140,249,154, 49,214,161,162, 64, 55, 17, 17, 17,123,227,226,226, 26,215,170, 85, 11, 0,110, 81, +174,178,236,113,197, 82,185,136,136,136,216,187,105,211, 38, 55,167,221,110, 47,165,252,115,115,189,143,185,243, 71,200, 87, 44, + 83,168,201,100,170, 52,197,113,118,118, 54, 2, 2, 2, 42, 85,236,229,241, 93,188,120, 17, 75,151, 46,197,164, 73,147,220,245, +233,233,233,168, 94,189,122, 85,210, 61,251,240, 15,132, 75, 87, 22, 15, 3,248,149,156, 4, 88,174, 1, 32, 73,210, 94,181, 90, +221,160, 75,151, 46,199,198,142, 29,187, 48, 42, 42,234,154,235,183, 46, 93,186,236, 91,176, 96,193,190, 13, 27, 54,132,196,196, +196,180, 78, 72, 72, 72, 16, 69, 49,201,102,179,117, 44,143,203,108, 54, 63,180, 99,199,142, 73,178, 44, 91, 67, 67, 67,109, 70, +163, 81,148, 36, 73, 2,128,254,253,251,103,116,234,212,233,242,209,232, 94,155,111, 0, 0, 32, 0, 73, 68, 65, 84,163, 71,149, + 67,135, 14,105,114,115,115, 53, 51,103,206,140,246,116, 50,140, 49,106,211,166,141, 77, 20,197,249,118,187,253,249, 59,169, 0, +130,131,131, 35, 29, 14, 71,164,205,102, 3,199,113,145,246, 19, 63,117,133,168,131,170,126, 87, 0,216,169,210, 6,186,154,238, +172,136, 67, 16,132, 95, 69, 81,188,167, 99,199,142,251,198,142, 29,251,217,192,129, 3, 51, 0, 96,233,210,165, 53,159,120,226, +137, 84, 0, 9,107,214,172, 9,139,137,137,105,183,103,207,158,189, 60,207, 95,117, 56, 28,141, 60,201,197, 24,123,158,231,249, +177,203,151, 47,159,177, 99,199,142,250,109,218,180, 57,254,216, 99,143,101, 7, 5, 5,173,255,250,235,175, 91,124,245,213, 87, +111,244,237,219,247, 57,187,221, 46, 0,152, 93,217,121,106,181,218,119, 27, 53,106, 52,118,221,186,117,234,106,213,126,139, 71, + 19, 20, 20,132,142, 29, 59,178, 17, 35, 70,168,251,247,239, 63,246,212,169, 83, 0,240,106,101,124,146, 36,125,212,172, 89,179, + 81,243,230,205, 83,135,135,135, 67,163,209, 32, 53, 53, 21,181,106,213, 66,211,166, 77, 89,203,150, 45, 53, 43, 86,172,152,144, +149,149, 5, 0,111, 85,198,167, 23,241,101,183, 58,226,208, 85,115, 39,105,212,247, 15, 6, 76,153, 64, 94, 58, 26,132, 54,196, + 21,125, 11, 54,219,184, 77,187, 96, 71,242,203,167,110,192, 1, 96, 70,101,124, 62,220, 49, 60, 59,120,240, 96,203,200,145, 35, +143,214,171, 87,175, 7,128, 43,106,181, 90,172, 89,179,230,183,215,175, 95,215,126,250,233,167,253, 6, 12, 24,240, 44,128,247, +203,219,185, 93,187,118,109, 22, 47, 94, 12, 0, 56,118,236, 24,122,247,238, 13,181, 90,125,139,146, 45,209, 99, 1, 0,168, 84, + 42,167,211,233, 44,247, 93,213,174, 93,187, 54,139, 22, 45, 2, 0,156, 58,117, 10, 57, 57, 57,165,148,127, 85, 12, 0,111,228, +187, 93,104,181, 90,172, 91,183, 14,162, 40,186,139, 36, 73,165,182, 69, 81,252, 93,124,174,250,173, 91,183,194,223,223, 31,126, +126,126,183, 45,239,157,132, 44,203,155,172, 86,235, 59, 68,180,251,110,203,242,111, 66, 57,171, 0,218,123, 21, 8,136, 49, 70, +137,137,137,255, 11, 15, 15, 47, 12, 12, 12,212,170,138,125,222, 37, 97,179,217,148,163, 71,143, 90,183,108,217,226,247,198, 27, +111,188, 91, 81,143,188,152,107, 82,201, 58, 89,150,173,249,249,249,214, 13, 27, 54,248, 93,191,126, 93, 35,203,178,251, 33,158, + 57,115,102,180, 39,174, 58,117,234,216, 15, 30, 60, 40,108,223,190, 29,143, 63,254,248,122,155,205, 54,224, 78, 25, 1,245,234, +213,139, 62,191,224,191,211, 32,106, 17,248,240,155,184,177, 99, 62, 32,106,161,106,212, 39, 30,197,201, 20,136,104,167, 39, 14, +198, 24,133,135,135,239, 55,153, 76,134,145, 35, 71,238,152, 51,103,206, 9, 65, 16, 40, 54, 54, 54,184,119,239,222, 89,118,187, +157,189,250,234,171, 77,151, 44, 89,210,141,227,184,188,172,172,172,118,158,188, 25,197,110,255, 95, 22, 45, 90, 52,253,169,167, +158,186,254,208, 67, 15,245, 95,180,104, 81,108,181,106,213,108, 0,208,173, 91,183, 33, 63,255,252,243,247,235,214,173,211,143, + 24, 49,226, 29, 0,221,137,232, 87, 15,124,173,140, 70,227,174,211,167, 79,151, 82,254, 37, 97, 50,153,112,238,220, 57,116,239, +222,189, 48, 39, 39,167,179,167,225, 0,198, 88, 39,181, 90,189, 41, 62, 62, 94,211,184,113, 99, 40,138,130,180,180, 52, 92,185, +114, 5, 38,147, 9,102,179, 25, 55,110,220, 64,114,114, 50,190,248,226,139, 2,155,205,214,193,211,112, 0, 99,236,161, 48, 13, +190, 79, 89, 51, 67, 43, 52,238,139,244,140,116, 4,217,211, 33,154,174, 98,198,150,116, 28, 57,159,142,171, 87,175,226, 49,255, + 83,120,115, 91, 94, 65,158, 13,237,137,232,120, 69,124, 62,220, 57, 48,198, 86,207,152, 49,163,199,132, 9, 19,190,210,104, 52, +181, 0,172, 63,127,254,252,217,123,239,189,247,202,200,145, 35,235, 70, 71, 71,199,213,171, 87,111, 11, 17, 13,171, 96,127,218, +180,105, 83,185, 74,223, 85,158,124,242, 73,188,240,194, 11,144, 36, 9,178, 44, 67,146, 36, 52,111,222,188,194, 80,177,140, 49, + 82, 20, 5, 86,171,181, 84,207,255,218,181,107, 56,114,228, 8,146,147,147,177,100,201, 18,160, 40, 46,253, 91,158, 66, 1,123, + 35,159,193, 96,168,114,216,218, 98,143, 37, 24, 99, 80,169, 84, 16, 4, 1,162, 40, 66, 16, 4, 8,130,224, 54, 4,118,237,218, +133,106,213,170, 85,202, 95,146,143,231,121,240, 60,143,248,248,120,196,198,198, 98,218,180,105,240,243,243,131, 32, 8, 56,122, +244, 40,106,212,168,113,215,195,236, 22,207,195, 48, 89,173,214,222, 62, 35,224,207, 67,241,120,127,201,123,111, 45,235, 33,246, + 52, 7,128,191,116,233,146,254,242,229,203,206,106,213,170,229, 7, 7, 7,203,130, 32, 8,102,179,217,177,125,251,118,231,174, + 93,187,140, 68,100,168,138,213,234,130,197, 98,145,142, 29, 59, 70, 87,175, 94,213, 84,101,127, 34, 98, 28,199,173,120,249,229, +151,135,207,158, 61, 27,203,151, 47,239, 55,124,248,112,103, 81,148,210,210,144, 36, 41,211, 98,177,120, 28,251,170, 83,167, 78, +164, 40,138,145,162, 40,130,231,249,157, 6,131,161,200,205, 15,192, 96, 48,196,135,245,122,113,167,217,108,142, 84, 78,109,236, + 10, 81,219,213,229, 9,168, 76,206, 85,171, 86, 45, 58,120,240, 96,224, 87, 95,125,213,125,225,194,133,189,163,162,162,118, 14, + 31, 62,252,226,136, 17, 35,218,174, 95,191, 62, 82,175,215, 95,232,222,189,251,242,134, 13, 27,222,120,247,221,119,219, 85, 66, + 55,186,110,221,186,235,134, 12, 25,146,125,237,218, 53,193,108, 54,171, 11, 10, 10, 84, 73, 73, 73, 26,158,231, 21,171,213,202, +159, 58,117, 74, 8, 9, 9, 41,168, 93,187,246,234,148,148,148,241, 0,158,171,136,204,104, 52,190,242,198, 27,111,200,158,148, +255,141, 27, 55, 0, 0, 47,189,244,146, 28, 19, 19,243, 10,128, 71, 43,226,147,101,249,141,241,227,199,107,106,212,168, 1,198, + 24, 78,158, 60,233, 86,252,102,179, 25, 38,147, 9,118,187, 29, 70,163, 17,157, 58,117, 82,239,222,189,123, 50,128, 17, 21,241, + 5,170,241,230,146,209,205,181, 98,147,190,184,113, 45, 3,155, 79,100,160,153,148,142,251,229, 12,164, 93,205, 64,122,122, 58, + 50, 50, 50, 80,171,186, 5, 83,219, 66, 61,243, 0, 38, 0, 24, 85,201, 53,244,225, 14,193, 96, 48, 32, 55, 55, 55, 94,163,209, +232, 79,159, 62,125,161, 81,163, 70,105, 0, 12,249,249,249, 58,131,193, 80,233,254,101,149,107,131, 6, 13, 0, 0,121,121,121, +144,101, 25,122,189, 30,106,181, 26,146, 36,185, 75,101,176, 88, 44,238,222,126, 78, 78, 14,126,254,249,103, 68, 70, 70, 98,252, +248,241,208,235,245,152, 49, 99, 6, 18, 18, 18,250,141, 26, 53,106, 8, 99,236, 49, 34,218,232,173,124,119, 98, 8,192,133,109, +219,182,121,236,253, 87,245, 93, 90,150,207,133, 45, 91,182,192,207,207,207,171,107,247,103, 97,241,226,197,186, 81,163, 70,197, + 50,198,124, 70,192,159,135,251, 0, 28, 41,177,221, 30,192,254,146, 13, 42,157, 4,168, 40, 10,151,150,150,166, 47, 78,225,152, +183,110,221,186,106, 42,149,138,185,122,237,127, 54, 20, 69, 25,185,116,233,210,225, 42,149, 10,211,167, 79,199,119,223,125,135, +188,188, 60, 84,175, 94, 29, 54,155, 13,138,162, 64,146, 36,244,234,213, 43,212,229, 74,172,104, 34,140, 74,165,138, 60, 51, 49, +124, 26, 68, 29,186, 44,188, 22,169, 82,169,208,229,221,237,176, 90,173,208,235,245, 16, 4, 97,167, 74,165, 2,108,230,174, 85, +149,179, 77,155, 54, 55,218,180,105,243,221,165, 75,151,180,159,126,250,105,151, 65,131, 6, 61, 28, 26, 26,186,167,119,239,222, +159,133,133,133,153, 5, 65,240,150,170, 93, 68, 68,196,185, 53,107,214,132,133,133,133, 89, 20, 69, 97, 26,141, 70,241,243,243, +179,153,205,102,178,219,237,202,175,191,254, 42, 95,188,120, 81, 14, 13, 13, 53,167,164,164,120,148,149, 49,214,182,125,251,246, +229,246, 8, 92,202,255,198,141, 27,184,121,243, 38, 66, 66, 66, 24, 99,172,173, 39, 62, 34,106,217,164, 73, 19, 20, 22, 22,194, +100, 50,185, 75, 65, 65,129,251,187,217,108,134,162, 40,168, 81,163, 6, 83,169, 84, 30, 13, 30,179, 29,205,255,211,166, 13,144, +159, 9,131, 45, 3,247,114,233,168,175,202, 0,242, 50,240,106, 68, 58, 98,173, 25,168, 89, 35, 29, 81, 53,109,216, 45,128,113, + 42,116,170,252, 18,250,112,135,144, 88, 80, 80, 80, 47, 49, 49,241,126,142,227, 86, 62,250,232,163, 54, 0, 6, 0,250,113,227, +198, 13,206,200,200,184, 4, 32,209, 19, 65, 89,133,154,149,149,229, 86,252,138,162, 64,167,211,185,123,254,222, 26, 0,174, 94, +127, 78, 78, 14,214,173, 91,135, 9, 19, 38,192,110,183,227,232,209,163, 88,184,112, 33, 94,124,241, 69,180,111,223, 62,248,151, + 95,126, 73,111,213,170,213, 42,198, 88, 99, 34, 74,245, 70,190,146, 6, 1,199, 85,121,254, 95, 41,244,237,219,215,221,243, 47, +105, 0,184,206,115,199,142, 29, 85,226, 27, 58,116, 40,120,158,135, 40,138,216,188,121,179,187,254,145, 71, 30,129, 40,138, 56, +120,240, 96,165, 28,197,238,249, 94,149,181, 51, 24, 12,155,115,115,115, 31,172,146,128, 37,240,232,163,143, 34, 53, 53, 85, 55, +109,218, 52,159, 17,240,231, 97,127, 73,239, 79,121,115, 0,188, 94, 6,168, 40, 10,187,114,229,138,232,112, 56,238,170, 59,169, + 56,212, 44,250,247,239,143,169, 83,167,162, 89,179,102, 56,122,244, 40,178,178,178, 96,179,217,208,119,125, 63,200,178,140,240, +240,112,252,250,235,175,184,116,233, 18, 42, 74, 66, 81,172,220, 1,155, 25,106,181,186,235,206,255,214,238,154, 48,190, 9, 14, +188,209, 5,199,231, 14,238,170,209,104, 34,117, 58,221,206,208,158, 47,196,107, 90, 14, 2,128,200,170, 46, 1, 12, 15, 15, 55, +127,248,225,135,177, 60,207,231,245,236,217,115,163,191,191,191,185,138,167,220,188,109,219,182, 87, 70,142, 28,153,214,179,103, +207, 27,146, 36,217,170, 85,171,102,179, 88, 44, 74,118,118, 54, 41,138,226,244,243,243,203,175, 89,179,102, 86,189,122,245, 82, + 0, 68,120, 34, 51,153, 76, 53, 26, 54,108,120, 75,125,126,126, 62,174, 95,191,142,235,215,175,187,141, 0,198, 24, 76, 38, 83, +141,138,184, 24, 99,178,205,102, 11, 84,171,213,200,204,204, 68, 74, 74,138, 91,225,151, 84,254, 54,155, 13, 64,209, 28, 3,155, +205, 86,203, 3, 95,136, 66, 16,141,254, 1, 64,126, 6, 4, 83, 58, 58,232, 51,160,183,102, 0,249,233,168,205, 50,240,124,157, +116, 68,213, 44,154,200, 26, 17, 0,228,219, 80,219,187,203,232,195,239, 65,113,210,159,196,181,107,215, 54,230, 56,238,109,158, +231,159,238,215,175, 95,221,129, 3, 7,214,217,186,117,235,232,142, 29, 59, 62, 50,116,232, 80, 17,192, 2, 79, 60, 46,165,234, + 42,193,193,193,208,235,245,238,223,245,122,125, 41,229,171, 86,171, 43,149, 45, 39, 39, 7,217,217,217,184,124,249, 50,122,246, +236, 9,135,195,129, 35, 71,142,192,102,179, 97,217,178,101, 80, 20, 5, 38,147, 9, 6,131,161, 90,116,116,116, 38,128,143,189, +149,175,172,242,215,233,116,184,221, 37,134,241,241,241,136,143,143,199,174, 93,187,144,144,144,224, 46,241,241,241,216,185,115, +103,149,123,236,113,113,113,216,188,121, 51,182,108,217, 82,106,223,216,216, 88, 36, 36, 36,120,197,103,181, 90,223,145, 36,201, +244,237,183,223,150,155, 46,246,240,225,195,208,235,245,166,188,188,188,119,170, 36, 92, 57,104,215,174, 29, 98, 98, 98,116, 26, +141, 38,150, 49,230, 51,220,255, 2,168,212, 3,240, 87, 69,189,122,245, 96, 54,155,241,194, 11, 47,160,101,203,150,176,217,108, +168, 93,187, 54, 18, 70,196, 67, 45,203,120,234,169,167,112,248,240, 97,104, 52,154, 10, 57, 20, 69, 41,118,249, 51,112,156, 14, +176,150,212,205, 12, 26,141, 38, 82, 81, 20,216,237,118,100,110,120, 31,144,180, 93, 85,205,135, 68,194,139, 97, 0, 23,178,178, +178,164,220,220, 92, 1, 0,179,217,108,124,177,135,162, 42,107,137,207, 45, 92,184,176, 79,163, 70,141,126, 24, 50,100, 72, 6, + 80, 52, 91,248,250,245,235,200,204,204,132,205,102, 99,153,153,153,216,179,103, 79,112,108,108,108,127, 20, 45, 13,172, 16, 58, +157,238, 74, 82, 82, 82,120, 80, 80,144,187, 46, 63, 63,223,221,235,191,121,243,102, 41, 47,128, 78,167,187, 82, 17, 23, 17, 89, + 68, 81,204, 61,127,254,188,191,193, 96,184,197,245, 95, 82,249,187,228, 22, 4,225,170, 7,241,178, 24, 96,207,185,146, 36,248, +107, 2,144,153,153,129, 95,206,102,160, 33,151,142,122,170, 12, 32, 47, 29,112, 20, 25,175, 38, 59,240,235, 13, 64, 39,160, 66, +249,124,184, 51, 96,140,133,183,108,217, 50, 97,244,232,209, 53, 51, 50, 50, 48,117,234, 84,203,236,217,179, 31,158, 51,103,206, +120,189, 94,143,180,180,180, 75,205,155, 55,207, 56,115,230,204, 51,149,165,186, 45,169, 84,131,131,131, 97,183,219,193,113,156, +107,105, 45,230,204,153,131, 57,115,230,184,219,231,229,229, 85, 42, 95,118,118, 54,114,115,115,241,203, 47,191, 96,234,212,169, + 56,121,242,164,251, 24, 42,149, 10,146, 36, 65,173, 86, 67,165, 82, 97,216,176, 97,120,253,245,215, 59,123, 35, 95,121, 61,255, +167,159,126, 26,227,199,143,119,247,218,131,131,131,189,118, 11,244,235,215,207,221,243, 47,249,233, 58,206,198,141, 21,142, 76, +148,139,199, 31,127,220,237, 69, 88,183,110, 93,169,122, 89,150,145,144,144, 80, 41, 7, 17,237,102,140,245, 30, 53,106, 84,108, +106,106,170,174, 93,187,118,208,235,245,208,235,245, 56,117,234, 20, 70,140, 24, 97,202,207,207,191, 35, 61,118,189, 94,143,206, +157, 59, 99,242,228,201,186, 15, 62,248, 96, 9,128,122,191,151,211, 7,143,176, 50,198, 74,142, 91,217, 0,120, 61, 7,224, 47, + 13,139,197,130, 26, 53,106, 32, 56, 56, 24, 33, 33, 33,240,243,243,131,191,191, 63,242,243,243, 33,203, 50,190,254,250,107, 12, + 25, 50,196,163, 1,224,112, 56, 0, 91, 1, 0, 6,167, 83,141, 33, 63, 3,122,189, 10,118,123, 30,242,243,211,176,119, 74,167, +174,144,180, 93, 27,188,180,194, 61, 55,192, 75,217, 84,135, 14, 29, 10, 74, 75, 75,211,235,116, 58, 91,227,198,141,111, 48,198, +200,233,116,178,156,156, 28, 67, 70, 70,134,100, 52, 26, 11,195,195,195,189,153,162, 28, 47, 8, 66,216,218,181,107, 35,230,205, +155,215,233,244,233,211,141,122,247,238, 13,187,221, 14,155,205,134,212,212,212,251,222,123,239,189, 65,130, 32,220, 80, 20,229, + 87, 0, 41,158,200,136,232,192,190,125,251,106,119,236,216,145, 1, 69, 47,216,146, 74,223, 85,172, 86, 43,242,242,242,136,136, + 60, 38,147,224, 56,238,232,129, 3, 7,186,213,170, 85, 11, 78,167,179, 92,229, 31, 24, 24, 8,171,213,138,171, 87,175, 2, 30, + 92,196, 68, 68,193, 26,118,242,224,225, 99,255,233, 20, 92, 7, 83, 55,102,224, 92, 74, 58, 50,210, 51,240,115,143,116,220,171, + 45, 4, 0, 36,243,245, 48,244, 39, 11,114,179,210, 0,134, 61, 94, 92, 67, 0, 0, 99,172,155, 94,196,130,124, 27, 70, 84,118, + 94, 62, 20,129, 49, 22,222,170, 85,171,189, 59,119,238,172,118,238,220, 57, 76,154, 52, 9, 39, 78,156,232, 23, 21, 21,213, 2, +128, 43,178, 88, 34,128, 5,222,228,185, 47,169, 88,237,118, 59,202, 14,133,125,252,241,199, 24, 58,116, 40, 36, 73, 66, 80, 80, +144, 87,227,238,174, 33,128,228,228,100,136,162, 8,167,211,137,103,158,121, 6, 41, 41, 41, 48, 26,141,165,148,186,191,191,127, + 24, 0, 45, 99, 76, 42, 47, 85,181, 39,229, 15,252,102, 32,120, 59, 60, 81, 18,174, 94,126,121, 99,255,229,204,179,174, 20,235, +214,173, 43,197,231,194,250,245,235,171,180, 2,192,101, 4, 76,155, 54, 45, 54, 38, 38, 70,215,185,115,103,156, 60,121, 18,143, + 63,254,184,201,100, 50,221, 49,119,189, 94,175,199,201,147, 39,241,254,251,239,155, 76, 38,211,147,119,130,211, 7,143,232, 10, +160,176,196,182,247,113, 0,238, 20, 84, 42, 85,238, 59,239,188,211,254,245,215, 95,223,175, 82,169, 60,173, 81,103,113,113,113, +173,138,115, 24, 87, 10,215, 56,189,193, 96,128,209,104,132,193, 96,128, 94,175,135,221,110,135, 44,203,184,114,229, 10, 62,254, +184,200,211,167, 86,171,203, 13, 48,100,177, 88, 0, 91,209,178,244, 77, 15, 2, 16, 11, 1,169, 0, 16,181,120,248, 7, 42, 82, +250, 12,224,121, 62,190,214,163, 51,119, 22,247, 70,118, 86, 38,219,204,153, 51,187,134,135,135,103,182,107,215,238, 74,163, 70, +141, 92, 93, 24, 69,173, 86,219, 13, 6,195, 13,179,217,172, 77, 79, 79, 15, 77, 78, 78,174,239,197,169, 46, 57,127,254,252,158, +217,179,103, 71,119,237,218,245, 70,255,254,253, 7,188,242,202, 43, 27,156, 78,167,253,250,245,235,152, 61,123,182, 42, 42, 42, +234,199,211,167, 79,139, 73, 73, 73,179, 1,244,245, 68,150,155,155, 59,119,198,140, 25, 15,143, 24, 49, 66,173,213,106,221, 61, +253,235,215,175,187, 13, 1,171,213, 10, 34,194,162, 69,139,172,185,185,185,115, 61,241, 89, 44,150,247, 55,111,222,220,182, 73, +147, 38,154,208,208, 80, 88, 44,150, 82,202, 95,173, 86,195,223,223, 31,103,206,156, 65,124,124,124,129,213,106,253,196, 19,223, +245, 66,188,247,220,255, 93, 90,114,184,254,126,237,149,171, 34, 50, 50, 50,144,158,145,129,180,155, 5,184, 87, 11, 64,237,135, +237, 57,245,112, 46,125, 15,172,133,112, 58, 20,196,120,113, 13,193, 24,139, 12,210,139, 63, 45,125,117,168,110,216,244,149, 91, + 24, 99, 15,122, 10, 90,227, 67,105,229,127,241,226, 69, 44, 95,190, 28,123,247,238, 77, 34,162,173, 0,182,222, 14,167,203,197, + 46, 73, 18, 56,142, 43,242,194,149,128,107, 14, 64, 96, 96,160,219, 59, 80, 25, 92, 6,128, 70,163, 65,122,122, 58,244,122, 61, +126,248,225, 7,183, 18, 47,217,203,182, 90,173,233, 0, 2,202, 83,254,229,201, 87, 22, 26,141,230,182, 12,128, 27, 55,110,220, + 81,229, 95, 30, 31, 80,228, 13,185, 29,227,196,101, 4,140, 27, 55, 46,118,242,228,201,186, 98, 37,125, 71,199,234, 79,157, 58, +117,199,141, 10, 31, 60,226, 24, 0,137,136,108,140, 49, 17,128,189,108,131,114, 13, 0,158,231,143,247,233,211,231,217,255,254, +247,191,155,251,247,239,127, 75,143,210,245,192,254,250,235,175, 53,119,239,222,221, 69,165, 82,157,168, 72, 2, 69, 81, 90,197, +197,197, 45, 77, 76, 76, 28, 61,109,218,180, 53,173, 91,183,190, 81,150, 43, 61, 61,221,127,211,166, 77,189, 11, 10, 10,110, 16, + 81, 43,111,206,172,160,160, 0, 45, 91,182, 68, 80, 80, 16, 2, 2, 2, 96, 52, 26,161,209,104, 80, 80, 80,224,238, 53, 84,182, +252,165,160,160, 0,176,149,185, 4,197, 43, 10, 44, 22, 7,186,126,122, 18,133,133,110, 3,106,103,110,110,238,206,202,228,226, +121,254,232,254,253,251,255, 19, 17, 17,241, 99, 9,229,239,134, 74,165, 66, 64, 64,128, 57, 53, 53,149, 59,121,242,100, 55,149, + 74,117,164, 60, 30, 23,136, 40,137, 49, 54,235,209, 71, 31,125,234,171,175,190,250, 34, 32, 32, 32,115,219,182,109,161,247,221, +119,223,149, 35, 71,142, 24, 25, 99,249, 73, 73, 73,234,109,219,182, 61, 14,224,235,202, 34,248, 17,209, 33,157, 78, 23,211,191, +127,255,177, 95,124,241,133,154,136, 74,245,252,109, 54, 27,108, 54, 27,214,174, 93,107,177, 90,173,159,122,193,183, 81,150,229, +141,171, 87,175,126,120,192,128, 1,162, 36, 73,112, 58,139,140, 42,163,209,136,192,192, 64, 92,185,114, 5,171, 87,175, 46,116, + 58,157, 75, 43,251,227, 19,209, 15, 70,153,141, 28,191,244,224, 67,111,117, 8,150,190, 47, 52,163, 69, 61, 19, 34,107, 2, 48, + 84, 7, 66,239, 67,245,171,103, 32, 57,205, 78, 39,135, 37,118, 39,121,156,116, 6, 0,140,177, 46, 65,122,113,253,217, 29,223, +233,252,145,143,159, 46,108,215,247, 95,158,185,185,216, 8,216, 91,217,254,255, 86,220,115,207, 61, 49,241,241,241,213, 46, 94, +188,136, 37, 75,150,224,203, 47,191,188, 98,177, 88, 30,186, 93, 62, 89,150,157,101, 93,230, 70,163, 17,175,189,246, 26,180, 90, + 45,116, 58, 29, 66, 66, 66, 16, 24, 24, 8,167,211,137,242, 86,247,148,199, 57, 98,196, 8, 55,103, 68, 68, 4, 30,123,236, 49, + 20, 22, 22,222,210,155,151, 36, 9,223,124,243,141, 19, 40,223,107, 36,138,226, 45,242,185, 96, 48, 24, 48, 97,194, 4,132,133, +133,185, 13, 4,111,228, 3, 0,142,227,148,160,160, 32,175,180, 60,207,243,149, 46,105,246,196, 23, 29, 29, 93,101, 62, 23, 92, + 70,192, 7, 31,124,176,196,100, 50, 61,121, 39,149,244,145, 35, 71, 48, 98,196, 8,159,242,255,115,209, 6, 64, 12,128,182, 0, +126, 70, 81,204,148, 82,227, 66, 21,197, 1,224, 0, 60,197,113,220, 59,247,220,115, 79,250,132, 9, 19,182,118,236,216,241,218, +161, 67,135, 44, 7, 14, 28, 8,202,202,202, 10,218,183,111, 95,151,156,156,156, 16, 69, 81, 94, 7,176,196, 83,132, 55,198, 24, + 83,169, 84, 99, 85, 42, 85,244,131, 15, 62,184,227,205, 55,223,220,119,248,240,225,194,196,196,196,224, 3, 7, 14,180, 78, 74, + 74,234, 0, 32, 90, 81,148, 24,111, 34,217,121, 19, 10,211,155, 16,152, 28,199, 69, 59, 38,112,211, 32,105, 1,209, 85,116, 40, +189,173, 5, 36, 29,106,253,239,167,233,169,169,169,209,149,201,198, 24, 83, 1, 24,206,113,220,172,144,144,144,204,151, 94,122, +105,125,143, 30, 61,210, 31,120,224,129, 73,195,134, 13,123,255,202,149, 43,213,246,239,223,223,207,100, 50,133, 42,138, 50, 5, +192,138,202,206,153, 21,189,105, 94, 6,240, 74,104,104,232, 26,198, 88,173,126,253,250,173,254,254,251,239,135,216,237,246, 52, +147,201, 20, 5, 96, 17,128,233, 94, 70,238,227,181, 90,237,187,162, 40,142,125,225,133, 23,228,160,160, 32,166, 82,169, 92, 65, + 84,104,241,226,197, 22,155,205, 86,149, 72,128, 6, 73,146, 22, 11,130,240, 96,207,158, 61, 53, 53,107,214,132,193, 96, 64, 94, + 94, 30,210,210,210, 16, 23, 23,103,182,219,237,171,109, 54,219, 11,101, 3, 81, 84,196,103, 20,241,141, 70, 64,159,217,157,161, +233, 80, 29,168, 99, 4,146,178,129, 61, 87, 25,166, 36,144,217,234,196, 34,147, 29, 19,137,232, 22,171,182, 12, 87,231, 64,157, +184,241,236,206,239,116, 1,156, 5,244,243, 20, 64,109, 68,194, 85, 21,250,125,126, 44, 63,223,226,232, 77, 68, 94, 15, 35,252, +155,208,180,105,211, 43, 11, 22, 44,184,231,135, 31,126,192,231,159,127,126,165,160,160,160, 51, 17, 93,186,147,199, 96,140, 81, + 74, 74,138,187,151, 94,214,117,173, 40, 10, 84, 42,149, 87,107,217, 25, 99,213, 56,142, 59,189,111,223,190,220,144,144,144, 90, + 60,207,151, 50, 0, 50, 51, 51, 79,215,174, 93,187,134,195,225,104, 65, 68, 23,170, 42,103, 78, 78,206, 45,189,107,111,100, 83, + 75, 2,165,127,251, 50,230, 30, 42,154,235,224, 42,174,184, 0, 37,203,171,175,190,250,167,243,253,209, 96,140,145, 94,175,191, + 99,115, 9,124,240, 14,140, 49, 11, 17,201, 37,183, 1,148, 90, 5, 80,238,204, 79, 87, 1, 32,171, 84,170, 87, 56,142,187,209, +168, 81,163,221, 79, 62,249,228,236,144,144,144,253,140,177,155,140,177, 87, 0,200,158,246, 47,135,175,158, 32, 8,123,130,131, +131, 79, 15, 30, 60,248, 19,157, 78,119,150,227,184,189, 0,234, 85,133,231, 78, 21, 0,209,202, 4,144, 50, 73, 32,101,170, 31, + 41,209, 53, 72,153,217,144,148, 15, 90,146, 18,211,153,148,175,122,147,178,104, 8, 41, 43,159,164,144,144,144,232, 42,114,139, + 42,149,106, 34,199,113,215, 27, 52,104,176, 67,173, 86,167, 4, 4, 4,236, 96,140, 93,103,140, 77, 0, 32,222,134,188,141, 1, +204, 7,112, 1, 69,238,156, 43, 40, 82,252,173,110,243,252, 91, 25,141,198, 85,126,126,126, 23,121,158,183,251,249,249, 93, 52, + 26,141,171,126, 7, 95, 63,181, 90,189,135,231,249, 60,142,227,108,130, 32,228,200,178, 28, 15,160,199,109,242, 69,249,203,216, +161,229,145,205, 49, 56,117, 2,174,249,203,136, 3,208,206, 91, 14,145,131,249,236,151, 79, 19, 29, 90, 73,202,219,225,164,204, +109, 78,202,188,110,164, 44, 26, 76,241,211,251,145,200,115,230,187,241,236,253, 29, 10,128, 1,254,254,254,167, 4, 65,216, 13, + 32,252, 15, 58, 6,101,102,102, 82,110,110, 46, 89, 44, 22, 82, 20,229,150, 82,244,154,242,154,175, 15,199,113,121,111,189,245, + 86,242,249,243,231,147, 77, 38,147, 41, 43, 43,235,252,135, 31,126,152,196,243,124, 62,128, 71,110, 87,206,242,228,243, 70, 54, + 65, 16, 50, 80, 52,249,170,210, 34, 8, 66,198,159,205,247, 71, 23,131,193,176, 9, 64,167,187, 45,199,191,173, 0,176,148,221, + 46,171,179,203,245, 0,148, 99, 73, 24, 57,142,155, 66, 68, 79, 19,209, 66, 34,154, 69, 94, 76,248,169,128,139,169, 84,170,177, +140,177,201, 68,244,158,183,189,254, 63, 2, 37,227,253,203,178, 12,141, 70,131,226,160, 64,238, 97, 14, 87,114, 17,139,197,178, + 51, 59, 59,123,231,109, 28,195,192,113,220, 20, 69, 81, 94, 4,240, 25, 17,205, 38,162,202,167, 54,255,205,193, 24, 51,222,238, + 51, 82, 1,159, 76, 94,120, 15,202, 66,195,179,140, 66, 39, 42,244, 22,169, 37, 62,179,192, 98,247, 37, 75,185, 75,144,101,217, + 97,181, 90, 61, 14,244, 27, 12, 6,103,110,110,174,215,243,149, 24, 99, 53, 81, 20,142,184, 43,128, 16, 0,215, 1,236, 5, 48, +137,136,206,223,142,156,106,181,218, 97,177, 88,110,145, 83,175,215, 59,243,242,242,254,182,147,169,125,248,231,162,120, 62, 93, +201,119,223, 53, 0,193, 84, 98,254,139, 87, 6,128, 15, 62,248,224,195,223, 17, 21,205,246,247,193,135,127, 58, 24, 99,205, 80, +122,213, 85, 23,162,210,115,166,124, 6,128, 15, 62,248,224,131, 15, 62,252, 11,225,115, 93,249,224,131, 15, 62,248,224,195, 63, + 12,140,177, 8, 0,107,203, 84, 55, 35, 34,119,116, 54,159, 7,192, 7, 31,124,240,193, 7, 31,254, 97, 96,140,101, 1,184, 23, + 64, 54,128, 48, 20, 5,137,187,189, 92, 0, 62,248,224,131, 15, 62,248,224,195,223, 6,122, 34,202, 41,254, 94,238,132,108,159, + 1,224,131, 15, 62,248,224,131, 15,255, 66,252,237,230, 0, 20, 39, 55,144, 81,180,198,177,202,203,194,254,104, 48,198,196,136, +136,136, 61,233,233,233,173,115,115,111, 53,186, 84, 42,149,211,233,116,254,237,174,251,159,137,216, 3,231, 13, 38,107, 65,164, + 10,202,105, 5,170,251, 42,250,228,121,236, 31,216,161,217, 53, 79, 92,174,251,209,174, 93,187,214,139, 23, 47,190,229,119,223, +253,248,123,131, 49, 22,202, 24,155, 13,224, 49, 34,146, 84, 42,149, 35, 44, 44,108,119,126,126,254,211,121,121,121, 23,239,182, +124, 62,248,112, 23, 97, 44,254,108, 14, 32, 7, 64,175,178, 58,211,227,139,175, 56,126,112, 31, 0, 35, 0,116, 64,209, 90,218, + 21, 0, 54,150,156, 72,224, 9,222, 68,237, 43, 11, 73,146, 50, 45, 22, 75,185,107,179, 37, 73,186,234, 39, 65,147, 99, 69, 1, +128,128,170,240,254,209, 96,140,137, 13, 27, 54,220, 27, 23, 23,215, 42, 60, 60, 28, 27, 54,108,112, 71, 56,115, 69, 16,107,214, +172, 89,149,146,138, 75,146,148, 97,179,217,170,116,253,188,137,130, 88, 44,175, 31,207,243,147, 69, 81,236,238,112, 56,154, 0, + 32, 81, 20, 79, 88, 44,150,109, 14,135, 99,174, 55,241, 10, 24, 99,181,136,232, 50, 99, 44, 28, 69,217,166, 42,130,158,138,194, + 26,223, 71, 68,167, 61,113,102,228,230,126, 13,162,186,149, 29,155, 24,142, 2,120,198,131,108,238,251,177,120,241,226, 59,114, + 63, 60, 28,235, 29, 0,143, 1,200, 2, 48,159,136, 22,221, 9,222,170, 64,148,164, 12,187,135,103,197,211,255,170, 42, 96,140, +253, 12, 32,170,120,115, 3, 17,121,204, 63,225,129,199,143,231,249,201,146, 36,117,183,219,237, 77, 0,144, 36, 73, 39, 10, 11, + 11,189,126,254, 0, 76,235,214,173, 91,255, 37, 75,150, 72, 28,199, 33,245,215, 68,254,163,143, 62,142, 76, 75,187,178,139, 38, +178, 71, 1, 92,100, 31, 82,218,237,200,231,131, 15,127,115, 52,100,140, 37, 2, 80, 3,240, 3,112,203,114,216, 91, 12,128,226, +176,179,157, 0,140, 80,169, 84,195,122,244,232,225, 63,114,228, 72,244,234,213, 11,155, 55,111, 30,178,108,217,178, 33,219,182, +109,203,102,140,173, 70,145, 49,176,219, 83, 32, 31,187,221, 30,106, 50,153,160,213,106,189,146, 56, 43, 43, 11, 33, 33, 33, 21, +190,196,172, 86,171,255,213, 9, 6,112,179,243,170,150,237,226, 79, 64, 68, 68,196,238,184,184,184, 86,181,107, 23,165,168,119, +197, 12, 47, 89,120,158, 7, 99,140,188,237,121,218,108,182,208,195,135, 15, 67,230, 1, 81, 5,136,146, 12, 65,148, 32,202, 50, + 36, 73,118,111,131,169,220,121, 12, 24, 99,149, 26, 12,140,177, 7, 53, 26,205,138,247,222,123,207, 24, 25, 25,201,135,134,134, +194,102,179,225,220,185,115,237,183,110,221,218,234,195, 15, 63,252, 47, 99,236, 81, 34,218, 94, 9, 85,231,226,103,134, 1, 40, + 55,233, 82, 49,106, 51,198,186, 22,183,243,104, 0,100,155, 10,235, 62,214,189,121,171,111,183, 31, 59, 84,201,167, 71,193,202, +222,143,222,151,222, 47,202,254,104, 47, 0,236,133, 56, 63,116, 99,149,239, 71,121, 96,140, 53, 10, 14, 14,126,125,205,154, 53, +204,106,181,214,123,237,181,215,218, 49,198, 90, 3,120,233,247, 4,185,170,170,162,181,219,108,161,171,118, 30,131,200,243,144, + 4, 14, 34,207, 65, 20,126,251,222,242,222,123,170,100, 72,150,144, 35, 12,192,151, 0, 68, 0, 99, 1, 68,101,103,103,195,233, +116, 34, 40, 40, 40,138, 49, 86, 15, 64,140,159,159, 31,229,228,228,140, 38,162, 12, 47, 56, 31,212,106,181, 43,222,127,255,125, + 99,215,174, 93,221,207, 95,114,114,114,251,205,155, 55,183,250,224,131, 15,188,125,254,134,204,159, 63,223,127,215,174, 93,208, +104, 52,168,233,184,140, 37, 45, 78, 66,104,120,253, 30,226,229,159,152,195,210, 15,128,207, 0,240,225,223,136, 68,250, 45, 20, +112,185,222,242, 91, 86, 1, 48,198, 50,154, 53,107, 22, 58,114,228, 72, 12, 31, 62, 28,213,171, 87,191,101,167,171, 87,175, 98, +229,202,149, 88,182,108, 25,142, 31, 63,158, 73, 68, 21,246, 42, 24, 99, 68, 68, 88,179,102, 13,120,158, 7,207,243, 16, 4,161, +212,103,217,239, 13, 27, 54, 4, 85, 16,191, 90,175,215,159, 53,153, 76,247,234,116,186,115,249,249,249, 13,138,143,225, 26, 22, + 40, 11, 43, 17, 21,150, 83, 95, 82,190,234,178, 44,191,103,183,219,135, 56,157,206, 10,141, 10,158,231,109,178, 44,255, 96, 50, +153, 38, 19, 81,185, 57,232,253,252,252,200,229,246,175, 86,173, 26,126,248,225,135, 82,202, 95,150,101,244,237,219, 23,203,150, + 45, 67,179,102,205, 42, 60,199, 50,242,209,175,191,254,138,134, 75,219,130, 41,118,128, 20,128,168,184, 40, 69, 9, 73,168, 56, +223, 7, 47,131,205,202, 5,227, 37,143,220,140,177,222,141, 26, 53,250, 62, 46, 46, 78,163, 40, 10, 46, 94,188,136,154, 53,107, +130,227, 56,164,167,167, 35, 32, 32, 0,105,105,105,120,252,241,199, 11,210,211,211,251,121,122, 9,215,173, 91,119,237,133, 11, + 23,222,171, 91,183,238,107,161,161,161,151, 42,106,151,150,150,214,224,242,229,203,111,215,172, 89,115, 90,106,106,234,131, 21, +181,147, 36, 41,227,177, 73,179, 66, 35, 26, 55,196,133,228,203,168, 91,175, 86,133,159,231,146, 46, 96,197,156, 87, 42,236,213, +142, 26, 53,138,194,195,195, 1, 0,167, 14,237,193,170, 30,166, 34,229, 95,108, 4,164,141,222, 95,229,251, 81, 30, 24, 99,145, +145,145,145, 59,118,236,216, 1,139,197, 2,187,221,142,126,253,250, 33, 62, 62,254, 24,128,119,137,232,187, 42,112, 5, 1,104, + 82,188,185,195,245,255,100,140, 85, 42, 95,101, 30, 0,163, 86,202,205,126,206, 58,166, 68,149,147, 1,199,240, 33, 37, 85, 34, +211,218,203,151, 47,247, 55,153, 76,232,208,161,131,163, 69,139, 22,252,142, 29, 59,240,217,103,159, 97,214,172, 89, 40, 44, 44, +116,108,220,184,145,191,124,249, 50,198,140, 25,179,241,198,141, 27, 81,149,240,245,110,220,184,241,247, 91,182,108,209, 40,138, +130, 11, 23, 46,192, 98,177, 64, 16, 4,232,245,122, 4, 4, 4, 32, 53, 53, 21,143, 61,246, 88,193,213,171, 87, 61, 62,127,140, +177,156,179,103,207, 26,143, 30, 61, 10,131,193,128,123, 44,231,209, 56,254, 37,176, 15, 9, 52,145, 65,245,145,187,233, 73, 0, + 31,162, 40,111,137,215, 9,114,138,143,209,210, 32, 98, 89,158, 13,255,165, 59, 16,203,158, 49,214, 73,150,229,175, 44, 22,203, + 72, 34, 58,252,123,249,254, 40, 48,198, 58,105, 52,154, 55,205,102,115,133,255, 87, 31,254,186, 40,155, 11,160, 60,148,215,227, + 9,157, 49, 99, 6,252,252,252, 16, 22, 86,190, 94, 15, 11, 11, 67,243,230,205, 97,179,217,112,252,248,113,175,122, 21, 60,207, + 67,237,200, 71,224,134,183, 96, 17,141,112, 14,154, 91,161, 65,224, 9,249,249,249, 13, 24, 99,100, 50,153,254,195, 24,243, 3, + 0, 73,146, 46,248,249,249,105,202,182,205,206,206,182, 48,198,130,200, 67, 66, 27, 89,150,223,255,248,227,143, 31, 25, 53,106, +148,170,228,177,157, 14, 7, 44,133,133,176,217,237,176,219,108,200,207,207, 23, 63,249,244,211, 97, 75,150, 46, 85, 3, 24, 88, + 30, 87,110,110, 46, 54,109,218,116, 75,175,191,164,203,217,149, 78,180, 42, 61, 79, 73,146,160,178,153, 96,237,250, 26, 84, 78, + 27, 84,138, 21,203,183,159, 64, 76,236, 73,212,240,151,176,244,201, 38, 48,112, 54,224, 66,124, 81, 4,112, 15, 96,140, 5,168, +213,234,229, 27, 55,110,212,100,102,102,226,236,217,179,104,218,180, 41, 94,126,249,101,112, 28,135,217,179,103,227,218,181,107, + 8, 11, 11,195,130, 5, 11, 52,195,134, 13, 91,197, 24,171, 95,145, 59,214,110,183,119,175, 89,179,102, 15, 34,194,229,203,151, +129, 98,163,178, 88,113,185,191, 19, 17, 66, 66, 66,182, 86,214, 33,182,217,108,161, 61,218, 52, 70,154,137,112,127,163,250, 48, +217,128, 54,205, 34,144,103, 81,208,238,254,198,200, 45,116,162, 83,155,230,200, 41,112,224,209, 62,145, 88,248,182,181,194,231, +111,241,226,197,216,180,105, 19,122, 94,152, 11, 60, 80,212,235, 87,189, 82,228, 53, 80, 94, 15,116,135,127,174,234,253,240,132, +231,158,123, 14,111,190,249, 38,182,109,219,134,132,132,132,230,253,251,247, 95,194, 24,139, 37, 34, 83,101,251, 50,198, 94, 15, + 12, 12,124,171,105,211,166, 34, 0, 84,118,173,202,194,102,181,134,209, 68, 54,116, 77,146,188,128,115, 88,140, 50, 7,168, 57, + 64,230, 0,153, 7,100,206,106, 76,205,192, 74,153, 47,170,151,100, 57, 87, 80, 91,158, 97,128, 71, 3, 0,128,120,244,232, 81, +248,251,251, 99,195,134, 13,124,253,250,245,177,103,207, 30,168,213,106,204,157, 59, 23,205,154, 53,227,181, 90, 45,214,173, 91, +135,155, 55,111,122, 52, 82, 24, 99, 1, 26,141,102,249,230,205,155, 53,179,102,205,194,253,247,223,143, 26, 53,106, 64,165, 82, +129,227, 56,216,237,118,100,103,103,163,122,245,234, 88,180,104,145,102,224,192,129, 30,159, 63, 0,214, 11, 23, 46, 56,212,106, + 53, 47,203, 50, 4, 82,195,161, 9, 6, 63,145,129,120, 57, 91,153, 96,121,152,125, 72,187, 25, 99, 29, 1,204, 67,145, 7,106, +161,183,215,148, 49,214, 50, 80, 47,237, 88,240,191,135, 13, 79,205,249, 62,150, 49,246,187, 18,218, 48,198, 58, 5, 4, 4,196, +206,152, 49, 67, 55, 97,194,132, 29,140,177,110,127, 69, 35,160,216, 72,137, 45, 40, 40,208,221,109, 89,124,184,125, 20, 39, 0, + 42, 9, 99,201,200,152,229,190,232, 66, 67,139,222,169, 91,182,108, 1, 0,116,233,210, 5,106,181, 26,133,133,133, 88,191,126, + 61, 14, 29, 42,202, 16, 91,149,156,211,130, 32, 32,232,232,106, 16, 47,130,153,174, 3,123, 23, 65,120,104, 66,185, 30, 0, 47, +113,201,245,197,106,181, 26,211,211,211,203, 59, 38, 95,124,142, 21, 26, 0, 14,135, 99,224,232,209,163, 85,177,177,177,112, 58, +157, 16, 4, 1,130, 32, 64, 20,197, 82,223, 37, 73,194,243,207, 63,207,125,241,229,151,253, 60, 9, 85, 82,217,151,252,238, 42, + 90,173, 22,106,181, 26,141, 27, 55,118,245, 60, 43, 29,131,118, 93,103,149,195, 2,149, 98, 5, 28, 86,188,240,205, 30, 20,218, +156, 56,124, 9,216,214,210,136,129,247,185,236, 31,207,157, 27, 65, 16, 94,153, 53,107,150, 81,165, 82,225,220,185,115,144, 36, + 9,249,249,249, 24, 60,120, 48,236,118, 59, 20, 69,129, 36, 73,112, 56, 28,104,220,184, 49,134, 14, 29,106,252,246, 30,213,179, + 88, 0, 0, 19,135, 73, 68, 65, 84,219,111,255, 7,224,237,242,248,174, 92,185,162, 39, 34,119,106,212, 62,125,250, 32, 58, 58, + 26, 17, 17, 17, 56,115,230, 12,162,163,163,177,113,227, 70, 0, 69, 10,205,155, 20,170,181, 3,212,168, 23,194,187,159, 7,142, +227,220,223,203,150,202, 32,203, 50, 96,183, 0, 14, 75,209,167, 11, 14, 11,100, 89,190,173,251,225, 9,169,169,169,232,216,177, + 35, 94,124,241, 69,180,104,209,194, 37,163, 30,128, 71, 3,128, 49, 22, 29, 17, 17, 49,109,199,142, 29, 8, 11, 11,131,195,225, +128,221,110, 71,126,126, 62, 30,125,244, 81, 0, 72, 46,206, 93,113,142,200,227,152, 54,111,183, 88,140,131,182, 85,110, 60,216, +159, 97, 70,168, 33,120,113, 90, 47, 13, 24, 48, 32,105,209,162, 69,252,181,107,215,112,248,240, 97,168,213,106,119, 73, 75, 75, +131,201,100,194,251,239,191,239, 64,209, 16, 65,133, 16, 69,241,149, 57,115,230, 24, 85, 42, 21,194,195,195,241,252,243,207, 99, +245,234,213, 8, 8, 8, 40,186, 31,201,113,224,117, 1,112,106, 31, 64,163, 70,141, 48,108,216, 48,227,202,149, 43, 43,124,254, + 0,124, 63,117,234,212,168, 41, 83,166,212, 14, 10, 10, 66,182, 45, 0,163,127,109,129,171,105,105, 87,182,116, 58,245, 40,138, +223, 19, 68,180,135, 49, 54, 25,192, 71,240,210, 0,112, 41,255,163,107, 62, 55,212,240,147, 16,148,244,157, 46,106, 13,110,219, + 8,112, 41,255,131, 7, 15,234, 52, 26, 13, 50, 51, 51, 13,115,230,204,249,203, 25, 1,140,177, 78, 58,157, 46,118,197,138, 21, +186,254,253,251,223, 17, 62, 73,146,150, 88,173,214, 39,239,132, 7,197, 7,175, 97, 68,145,193,235, 70,217,176,216, 30,223,160, +254,254,254, 0,128,253,251,247,227,212,169, 83, 56,113,226, 4, 84, 42,149, 91, 33, 86, 5,130,138, 65,119,105, 23,110,118, 28, + 7,166, 40, 80,118,206, 7,223,247,149, 82,202,159, 99, 69,134,130, 55, 32, 34,119,222, 80,173, 86,155, 34,138, 98, 53,160,200, +101,206, 24, 8, 96, 36,203,114,186,217,108,246,152, 46, 86, 81, 20,158,231,121, 88,173, 86,136,162,232,238,137,112, 28,135, 78, +157, 58,225,208,161, 67,238,228, 64,106,189, 30,138,162,120, 84, 16, 46,165, 95, 86,249,203,178, 12, 81, 20,221, 61, 78,215,167, + 55,248,205, 0, 40,128,202,105, 5,179, 23, 98,214,160,251,176,114,127, 42, 90,215, 80,227,193,186, 2, 96,241, 46,191,144, 40, +138, 61,187,118,237,202, 37, 37, 37, 65, 20, 69,136,162, 8,187,221,142,158, 61,123,130, 49,134,244,244,116, 72,146, 4, 81, 20, + 1, 0, 61,123,246, 20,215,175, 95,223, 19, 21,191,128, 75, 41,255, 13, 27, 54,184,235,136, 8, 27, 54,108, 64, 84, 84, 20, 54, +110,220,232,117,254,116, 65, 16,176,104,209,162,114,211,155,150, 44, 83,166, 76,169,148,171,200, 0, 40,116, 27, 1,202,155, 33, +197,195, 0,133,165,238, 67, 85,238, 71,101,200,202,202, 26, 27, 29, 29, 93, 11, 64, 48,128,159,137,232, 86,235,180, 4, 24, 99, + 3, 93,202,159,136,208,183,111, 95,140, 27, 55, 14,237,218,181, 67, 94, 94, 30, 94,126,249,101,100,103,103,215, 35,162, 29,103, +206,156, 81, 24, 99,145, 68,180,171, 2, 58,187, 32,201,185,235, 30,100, 70,217,213,251,231, 0, 53,255,219,119,183, 71, 64,150, +115, 1,139,199,116,207,174,121, 8,157, 59,119, 70,223,190,125,177,114,229, 74,140, 29,251,155,142, 31, 59,118, 44, 94,122,233, + 37,228,228,228,160,118,237,218,124,114,114,242,121,198, 88,133,243, 21, 92,207,223,133, 11, 23,208,186,117,107,140, 25, 51, 6, +163, 70,141,194, 79, 63,253, 4, 67,230, 47, 56,255,127,111, 33,124,208, 84,104, 68, 17,140, 49,244,234,213, 75,252,233,167,159, + 60, 61,127,111, 31, 57,114, 68,243,200, 35,143, 60,166, 40,138,196,113,156,163, 86,173, 90,187,243,243,243,159,102,137, 84,106, + 21, 0, 17,109,102,140, 53,242,116,190, 37,206,251, 55,229,239,175, 6,173,126, 6,157,106, 75,216, 48,210,160,139, 90,113,163, +202, 70, 64, 73,229,175,213,106,241,203, 47,191,160, 99,199,142,152, 49, 99,134,225,173,183,222,250,203, 24, 1, 46,229,127,224, +192, 1, 93, 96, 96,224, 29,227,155, 61,123,182,110,210,164, 73,191,219,131,226,131,119, 96,140,181, 0,112,164,120,179, 61, 17, +237, 47,175,157, 87,221,109,173, 86,139,140,140, 12,216,237,246, 42, 43,126, 23,252,175,236, 1,115,218, 65, 13, 34, 33,168,128, +194,245, 51,225,188,122, 26,234,122, 45,193,243, 60, 46,254,252, 5,142,172,124, 31,126, 17,237,161,246, 66, 42,154,200, 56, 0, + 28,128, 6, 55,159,198, 84, 43, 65, 46, 25,212,128, 3,160,226,109, 54, 81,133,251, 80, 52,254,231, 17,174, 30,101,159, 62,125, +176,115,231, 78,119,239,146,231,121, 52,109,218, 20,201,201,201,224,184,202, 59,135,229, 77,252,115, 25, 3,140, 49,183,162,113, +245, 60,189,129, 75, 25,171, 28,133, 56,155,154,133, 90,122,134,113,157,130, 48,238, 63, 26,192, 86, 8,216,204,128,173, 82, 15, + 51, 24, 99,140,231,249, 70, 97, 97, 97, 72, 77, 77,117, 43,250,154, 53,107,226,217,103,159, 5,199,113,248,252,243,207, 97, 50, +153,220,198, 65,163, 70,141, 80, 80, 80,208,220, 19,175,171,103, 31, 29, 29,237, 58, 78,169,223, 93, 94, 0,111, 61, 0,130, 32, + 96,204,152, 49, 21,246,250, 75,122, 6, 42,131, 90,173, 6, 28, 22,168, 94, 59, 5,229,173, 48,236, 76, 54, 97,231,197, 66, 68, +183, 35,112, 28,119, 91,247,195, 11,156, 36,162,207,170,208,126,208,212,169, 83,161, 40, 10,186,119,239,142,145, 35, 71,162,109, +219,182,136,137,137,193,238,221,187,177, 96,193, 2,172, 88,177, 2, 14,135, 3,107,215,174, 85, 77,158, 60,121, 20,128,114, 13, + 0, 70, 56, 62, 48,194,242, 44,202,252,183,253,191,146,190,200, 45,176, 26, 75,183,182, 24, 1,172,150,191, 80,123, 90, 53, 18, +149,157,157, 13, 63, 63, 63,236,217,179, 7, 26, 77,145,167,201, 53, 31, 97,250,244,233,164,213,106, 97,181, 90, 17, 23, 23, 7, +181, 90,141, 26, 53,106,148, 59, 7,160,228,243,151,149,149, 5, 0,120,242,201, 39,113,249,242,101, 60,254,216, 35,152,117,255, + 13,132, 55,237, 2,125,231,103,160,226,139,188,111,141, 27, 55,246,248,252, 17, 81, 38,128, 81,197,229,142,160, 60,229, 15, 0, +208,135,162, 83, 88, 16, 54,140,173,163,139,250,236,176,215,202,172, 60,229, 47,138, 34,212,106, 53, 34, 35, 35,241,209, 71, 31, + 25, 38, 78,156,120,215,141, 0,151,178,222,191,127,191,206, 53, 15,227, 78,241, 25,141, 70, 56,157, 78,221,148, 41, 83,124, 70, +192,159,131,253, 0,212, 68,100, 41,234, 20, 51,117,121,203,230,255,240,245,207, 65, 50,224, 60,189, 3, 33,135,190, 65, 78,211, + 1, 16, 52,122,240, 60, 15,241,222,246, 40, 60,185, 21,126, 13,255, 3,107,230, 5, 36,125,247, 1,186, 76,250, 18,135,127,252, + 10, 15,220, 58,239,240, 22,228, 20,226, 73,142, 21,185, 55,246,164, 74,159,240, 28, 19,121, 6,240,170,162,217,242,188, 10,224, + 64,182,230,247, 88, 71,193, 11, 3, 64, 16, 4, 12, 24, 48,160,104,204,184,103, 79,236,221,187, 23, 0,208,188,121,115,156, 63, +127,222,237,169,168, 12, 21, 13, 1,184,240,123, 60, 0,125,102,111,198,166,147,153, 48,200, 60,246,141,107,136,251,252, 21,220, +204,201,199,144, 85,153,144, 84, 78,196, 14,240,138, 14,118,187, 29, 98,113, 15, 75,146, 36, 8,130,128,252,252,124,247,177,108, + 54,155,219, 56,112, 25, 31, 21,161, 85,171, 86,185,173, 91,183, 70,171, 86,173,208,184,113, 99, 3,138,199,253, 75, 42,250,198, +141, 27, 83,171, 86,173,242, 92,237, 42, 3,207,243,152, 63,127,190,199,222,191, 74,165,194,155,111,190, 89, 41,151,123, 8, 0, + 0,236,133,216,121,209,130,183,247, 17,162,219, 21, 85,253, 17, 30,128,170,128, 49, 86, 23, 64,236,132, 9, 19,134, 19,145,170, +119,239,222,120,241,197, 23,145,145,145,129,175,190,250, 10,169,169,169,232,209,163, 7,252,252,252, 64, 68, 56,115,230,140, 25, +192, 15, 21, 18,126, 68,103, 25,112,182,108,117,238, 71,108,229,201,139, 25,165, 86, 5, 72, 2, 15,145,231,160,211, 72, 30,231, +241, 56,157, 78,204,155, 55,207,237,242, 47, 11,158,231,161,209,104, 42,252,189, 44,236,118, 59, 4, 65, 0, 99, 12,118,187, 29, + 51,102,204,192, 99, 81,145,216,114, 85,194,244, 15,230, 65, 37,136,165,134,225, 42, 3, 99,172,150, 36, 73, 31,219,237,246,126, +138,162,240, 0,160, 82,169, 28,106,181,122,189,217,108,254, 31, 17, 93, 46,110,231,149, 11,202, 32, 98,217, 55, 19, 7,254,166, +252, 25, 15,104, 3, 1,109, 16,160, 13, 66,167, 22, 65,152,243,148, 78, 55,121,201,158, 85, 0,106, 84,198, 39, 73,210,170,152, +152, 24,157, 86,171,197,193,131, 7, 33, 73, 82,169, 33,148,158, 61,123, 98,252,248,241,134,152,152,152,101, 0, 26,123, 35,227, + 31, 1, 73,146,150,204,156, 57, 83,231,231,231,135,228,228,100,252, 30, 15, 64, 73, 79, 66, 64, 64, 0,146,147,147, 17, 25, 25, +137,197,139, 23,235,158,126,250,105,159, 17,240, 23,193, 31,107, 0, 76,103,252,185, 71,128,130,185, 15,160,176, 65,127,216, 58, + 62,231, 86,164,154, 22,189,145, 21,247, 5,132, 71,167, 33, 57,110, 1,170,183,233,133, 6, 15, 60,130,106,141,219, 98,195,131, + 45, 42,165,222,116, 22, 49, 60, 3, 4, 14,224,152, 85,243,192,170,236, 82,131, 29, 12,192,241,145,254, 2,188, 56, 71, 75, 97, + 33, 4, 65,192,166, 77,155,208,189,123,119, 36, 38, 38,186, 61, 0,231,206,157, 67,253,250,245,113,245,234,213, 42, 25, 0,174, +207,178, 10, 84,163,209,148,234,121,122, 3, 73,146, 64, 0, 46, 92, 43, 82,210,121, 22, 7, 78,167,101,227, 62,141, 10, 63, 30, +191,137,157, 41,118,180, 12,169,156,135,136,200, 96, 48,156, 78, 78, 78,110,105, 48, 24,220,138,190,228, 88, 58,199,113,110,185, + 37, 73,194,233,211,167,161,213,106,143, 87,196,121,232,208, 33,163, 75,225,159, 56,113, 2,109,219,182,189,165,205,137, 19, 39, + 88,201,118,149, 65, 16, 4,140, 31, 63,190,220, 30,255,109,205, 1,112, 88,160, 76,245, 7,236, 5,136,110,167,184,149, 63,112, +123,247,163, 36, 88, 81,202, 77,247, 64,169,211,225,209,163, 94,118,223,237, 77,154, 52,233,118,243,230, 77, 92,189,122,213,214, +174, 93, 59,241,131, 15, 62, 64, 98, 98, 34,194,195,195,177,105,211, 38, 68, 71, 71, 99,245,234,213, 55, 1, 12, 46,222,237, 24, + 17,101, 87, 85, 78, 81,146, 50,155,212, 9, 43, 87,209,203,178,236,105,249,230,134,160,160,160,168,234,213,171,227,253,247,223, +135, 44,203, 24, 51,102, 12,166, 79,159, 78, 0, 16, 25, 25, 9, 65, 16,160, 86,171,209,189,123,119, 36, 37, 37, 1,192,134,242, +136,136,136,140, 70,227,233, 11, 23, 46,180,212,233,116,110, 67,128,136,176, 54,110, 59, 84, 12, 80,105,252, 75, 41,255, 83,167, + 78,121,124,254, 0, 64,146,164, 79,251,247,239,255,112, 76, 76, 12, 19, 4, 1, 38,147, 9,215,206, 31,227, 63,250,232,163, 1, + 7,246,237, 13,166,137,108, 42,128,139, 0,154,194,139,206, 64,158, 13,255,125, 98,214,255,197,254,124,122,149,174, 83,125,255, + 98,197,255,155, 1,112, 56,195,137, 41, 75,247,152, 77,133,214, 10, 99, 80,148,132,213,106,125,230,217,103,159,253,254,157,119, +222,209, 54,105,210,164,148,242, 87,171,213, 56,113,226, 4, 62,253,244, 83,147,201,100,250,175, 55,124,127, 20,172, 86,235,147, +147, 39, 79,142, 37, 34, 93,100,100, 36, 12, 6,195,109,241,184, 38, 16, 46, 95,190, 92, 23, 24, 24,136,212,212, 84, 4, 6, 6, +194, 96, 48,160,110,221,186,216,184,113,163, 46, 42, 42,202,103, 4,252, 5,240,199, 26, 0,211,200, 81, 67, 96,200, 55,231, 35, +255,228,153, 82, 19,253,196,251, 31, 66,250,234,183,145,242,109, 52,210,119,255,136,182,209,107, 32, 8, 2, 66,234,222,135,245, +151, 43,167,126,164, 57, 30, 71,145,167,159,223,122, 73,251,209,142,199,194, 2, 5, 6,112, 42, 64, 40,246, 0,200,106,237, 13, +192,243, 28, 0,149, 74,229,200,205,205,229,213,106, 53, 24, 99, 56,112,224,128,219, 72, 57,123,246, 44,120,158, 71, 90, 90, 26, + 92, 47, 22,142,227,156,158,248, 74, 14, 1,148,103, 48,184,226, 33, 84, 69,225,184,148,230,230,231, 35,176,234, 96, 58,234, 25, + 9,131,234, 41, 64, 97, 62, 30,188,199,138, 55,219, 2,207, 54,245,138, 10, 86,171,117,235,214,173, 91,155, 61,249,228,147,252, +141, 27, 55, 32,138, 98, 41, 87,122, 73, 3, 64, 20, 69,108,220,184,209,106, 50,153,182,122, 35, 95,116,116, 52, 98, 99, 99,221, +219,174,121, 0, 21, 13, 13, 84, 4, 65, 16, 48,111,222,188, 74, 61, 0,211,167, 79,175,148, 75,173, 86,195, 52,241,244, 29,189, + 31,197,231,226, 15, 96, 86,189,122,245,158,157, 49, 99,134,170, 73,147, 38,200,205,201,129,197, 98, 1,128, 74,205, 49,198, 88, +221,186,117,235,118, 59,124,248, 48,236,118, 59,174, 95,191, 46, 18, 17, 78,159, 62,141,193,131, 7, 59, 12, 6, 3, 63,123,246, +108, 76,159, 62, 29, 7, 14, 28, 8, 72, 73, 73,185, 76, 68, 23, 60,113, 86,180, 12, 80,148,164, 76,235,109, 6, 0, 34,162,190, +140,177,186,133,133,133, 73, 77,155, 54,229,175, 94,189,138,137, 19, 39, 66,173, 86,187,255,207,118,187, 29, 57, 57, 57,184,112, +225,130, 3, 64, 4, 17, 37, 87,196,103,181, 90,183,110,217,178,165,217, 83, 79, 61,197,231,230,230,186,149, 61, 19, 4,240, 37, + 20,191,235,115,195,134, 13,149, 62,127, 54,155,173,239,103,159,125,198,182,111,223, 14,181, 90, 13,157, 78,135,176,194,171, 88, +216,244, 4, 19,234, 91, 58, 17, 47,175,123,122,131,101, 6,128,167, 1,124,224,197, 57,239,102,140,245,142, 90,203, 98, 55,140, + 50,232, 58,133,133,186,141,128,195, 25, 78,244,120,227, 59,115,110,129,117, 8, 17,197,121,121, 13,227, 24, 99, 67,222,124,243, +205,239, 63,253,244, 83,109,139, 22, 45, 74, 41,255, 17, 35, 70,152, 76, 38,211, 93, 87,134,174,243,158, 50,101, 74,236,226,197, +139,117,117,235, 86, 26,139,171, 92,104, 52,154, 55, 11, 10, 10,116, 3, 6,120,116, 73,234, 12, 6,195,155, 0,124, 75, 12,255, + 56, 20,150,120,231,186,190,151, 26, 10, 40,207, 0, 88, 59,118,236,216, 1, 99,199,142, 69,131, 6, 13, 42,100,190,118,237, 26, + 18, 18, 18,128, 91,211, 13,150,130,217, 1, 48, 81,115,235,154,127,117, 48,234,190,184, 0,167, 63,127, 9,247, 14, 26,143, 26, + 45,187, 85,105, 21, 0,251,144,214, 0, 0, 77,100,117, 27, 7,155,199,221, 44,196, 45,203, 0, 3,212, 86, 51, 0,143, 99,106, +146, 36,173,157, 63,127,254, 35,195,134, 13, 99, 2,207,195,233,116, 66, 65,145,178,114,201, 42, 8, 2,114,115,115,241,238,187, +239, 42, 58,157,110,125, 69, 92,162, 40, 58,131,131,131, 57, 89,150,241,208, 67, 15, 65,150,229, 82, 69,173, 86,187,151, 86,186, +122,158, 94,131,151, 80, 59,255, 48, 94,141, 40,222, 46,114, 6,160,166, 30,152,222,193,123, 26,155,205, 54,231,195, 15, 63,124, +182, 71,143, 30,254,213,170, 85,131,211, 89,100,207,132,132,132,192,225,112,128,227, 56,247,208,192,190,125,251,176,122,245,234, +124,171,213,250,161, 39, 78, 87,207, 62, 46, 46, 14, 81, 81, 81, 72, 76, 76,116,175, 2,136,138,138, 66, 92, 92, 92,169,118,149, + 65, 16, 4, 76,154, 52,201,227, 10, 0,149,170,242, 52, 22,127,232,253, 0,222,158, 57,115,230,127, 39, 79,158, 12,149, 74,133, +252,255,111,239,108, 99,154,186,194, 56,254,127,122,251,118, 95,138, 3,149,136, 2, 93, 16,113,113, 56,151,248,201,132,184,201, + 32, 33, 89,140, 49, 27,201,220, 75,194,136,108,132,152, 96, 92,220,194, 38, 34,209,205, 48,183,133,234,190, 44, 91, 6,206, 56, + 93,226, 50, 17, 39, 99, 38, 11,198, 37,211, 72,182,100,153,213,205,134,160, 32,111,101,131,218,222,218, 94,104,207, 62,148,219, + 32,218,246, 82, 96, 48,189,191, 79,165,156, 62,247,158,156,211, 62,207,115,238, 57,255,199,235,197,141, 27, 55,176, 98,197, 10, + 92,233,236, 76,172, 98,200, 88, 23, 17,253, 92, 88, 88, 88,176,118,237, 90,172, 90,181, 10,130, 32,224,192,129, 3,240,249,124, +175,251,124,190,252,246,246,246,119,214,173, 91, 7,191,223, 15, 0,113,245, 44,128,123,133,128,204, 38, 14, 22, 35, 7,179,137, +195, 51, 79,229, 36, 37, 0, 52,137, 79,207,158, 61,107,148, 36, 9, 62,159, 15, 35, 35, 35, 8, 4, 2, 81, 39, 54, 58, 58,138, +156,156, 28, 56, 28, 14, 99, 85, 85,213, 17, 68,212, 67, 31, 72, 48, 24,108, 56,116,232, 80, 69,113,113,113,106, 70, 70, 6,194, +225,240, 61, 14,127,242,233,155,105,204, 63, 78, 81, 20,152, 76,166,232,216,154,199, 56,152,238,186, 65,159, 48, 96, 23,165,126, +231,194,155, 0, 62, 0,112, 76, 75,135,163, 65, 64,115,111,219,247,111, 61, 46, 21, 60,157,142, 95, 7,198,241,220,123, 39,101, +143, 63,160,217,249, 79,178,247, 3, 17,189, 88, 93, 93,125,170,185,185, 89, 92,191,126,253,130,114,254, 42,106,191,203,203,203, +219,206,157, 59,151,212, 17, 64, 93, 55, 96,254, 73,116,254, 95,229, 65, 66, 64, 28,128,114, 34,218, 87, 82, 82,178,188,178,178, + 18,203,150, 45, 67,107,107, 43,250,250,250,160, 40, 10, 58, 59, 59,113,253,250,245, 62, 0,251, 0,124,201, 24,139,153, 21,171, + 66, 64,215,174, 93,139, 41,252, 51,249,181,186,243, 59,129,144, 13, 3,144,170,254, 29, 75, 7, 96,116,116,212, 31, 8, 4,226, +202, 5, 19, 81,166, 32, 8,142, 96, 48,184, 57, 20, 10,197, 92,227,231, 56,110, 92,146,164, 86,143,199, 19,125,166, 24,239,254, +220,110,119,220,149,128,154,154, 26, 28, 60,120, 80, 83, 95,167,123, 30, 60,145,104, 12, 17,109,206,204,204, 60,209,212,212, 36, +230,229,229,193, 96, 48, 64,146, 34,223,117,245, 71,248,242,229,203,216,186,117,171,111,120,120,248, 5,198,216,143,177,108,217, +237,118, 15, 0, 10,135,195,247,157,253,143,245,122,104,104, 40,166, 44, 36, 17,177,158,158, 30, 52, 54, 54,198,204,252,213, 32, +162,174,174, 78,147, 64,206,108,142,199,132, 61, 11,128, 62, 69, 81,210,140, 70, 35,134,135,135,225,114,185,208,219,219,139,109, +219,182,141,133, 66,161, 84,198,152, 28,207,198,132, 29, 35,128,141,136, 8,255, 60,137,200,147,171, 99,140,177,139, 68,244, 89, +109,109,237, 27,133,133,133,216,180,105,211, 8, 99, 44,161,236,245, 92,172, 0, 76,220,231,233,170,170,170, 45, 60,207,195,225, +112,140,219,237,118, 99,123,123,123,116,217,191,171,171,107,220,225,112, 24, 7, 7, 7, 81, 95, 95,223,194, 24,139,155,250, 17, +209,230,172,172,172, 19, 71,143, 30, 21, 87,175, 94, 13, 34,138, 58,125,117,254, 93,186,116, 73,211,252, 3, 0,142,227,198, 58, + 58, 58,140,178, 44, 67, 16, 4, 72,146,132,197,222, 63,177,252,252, 78, 24,253, 67, 96, 70,235, 8,141, 71,244, 0,146,232,123, +129,205,106,106,107,216, 94, 44,213, 52,253, 36,123,228,233, 59,255, 41,246, 74,108, 54,219,169, 61,123,246,136,251,247,239, 95, + 80,206,127, 50, 68, 84, 96,179,217,218,188, 94,175,148,172, 64,150,206,194,231,190, 0, 32,250, 15, 34, 1,192, 78,179,217,252, +118,105,105,233,162,180,180, 52,116,116,116,192,233,116,122, 66,161,208,135, 0, 26, 25, 99,254,132, 23, 32, 98, 67, 67, 67,240, +120, 60,113,149, 0, 85,231, 15, 64,139, 83, 60, 13,224,217, 73,111, 45, 10,135,239, 63,255,174,229,199,124, 46,176, 88, 44,227, +138,162,196,205, 60,211,211,211, 81, 93, 93, 61, 47, 1,192, 68,155, 45, 86,171,181,185,172,172,140, 47, 42, 42,178,228,231,231, + 71,159,185,158, 57,115, 38,120,252,248,113,217,239,247,191,202, 24,107,139,103, 39, 55, 55,247, 91,151,203,245,209,202,149, 43, +119,103,100,100,116,199,106,215,211,211,147,119,243,230,205,247,179,179,179,107,111,221,186, 21, 51, 67, 36, 34,214,223,223,175, +249,220,191,150,190,206,230,120, 76, 92,243, 9,131,193,240,203,133, 11, 23, 30,179,219,237,232,238,238,198,213,171, 87,177,119, +239,222,144,219,237,222,197, 24, 59, 28,239,243, 90, 32,162,175, 26, 26, 26, 94, 19, 69, 17, 59,118,236,184,200, 24,219, 56, 19, +123, 22,171,117, 64, 9,222, 43,154,100,177, 90, 7, 3,218,106, 70, 76,149, 2,118,221,190,125, 27, 60,207, 35, 45, 45, 13, 0, +114, 1, 28, 65,164, 22, 68, 37,211, 38, 5,188,133,231,249,230,178,178, 50,190,184,184,216,146,159,159, 15,163,209, 8,167,211, +137,150,150, 22,205,243, 15, 0,120,158, 63,177, 97,195,134,210,138,138, 10, 46, 61, 61, 29,162, 40, 98,108,164, 23,141,142,195, + 33,231,111, 87, 58,156,175, 4,234, 0,116, 39, 91, 19,128,136, 10, 36,222,114,210,119, 55,184,125, 38,206,127,146,189, 18, 81, + 20,191,144,101,249,165,133,232,252, 85,136,168, 32, 37, 37,165,214,227,241,232, 25,253, 67, 74,204, 0, 32,218,128,104, 49, 34, + 95,238, 23, 16, 89,238,175, 98,140,253,173,245, 2, 86,171,117, 32, 24,140,173,214, 22,227, 51,154,138,217,168,216,108,182,191, + 20, 69,201,154,250,190,217,108,238, 81,229,130,231, 3, 45,153,103, 34,135,195,243,252, 64, 32, 16,152,171, 98, 64, 75,204,102, +243,110, 65, 16,138,100, 89, 94, 67, 68, 76, 20,197, 63,100, 89, 62,175, 40,202,199,140,177,127, 52,216, 40, 69, 36,115, 37, 0, +241, 42,243,101,171,237, 88,156, 66, 57,211,157, 47,211,153, 43,179, 49, 30,147,108,101, 2,248, 28,145, 64,180, 31,192,239, 0, +222,101,140, 57,181,222,123, 2,251,207, 75,146,244,141,193, 96,192,157, 59,119,202, 24, 99,167,102,104,143, 69, 79, 1, 76, 60, + 26,200, 88,156,146, 84,128, 76,179, 87, 12,104,137,217,108,222, 45,138, 98,145, 44,203,107, 0, 76,123,254, 77,216, 89, 42, 8, + 66, 93, 56, 28,126, 57, 20, 10,241, 0, 96, 50,153,238,114, 28,247,181,215,235,173,103,140,185,147,185, 63, 29,157,135,157,132, + 1,128, 78,242,168,153,103,188, 54, 41, 41, 41, 33,143,199, 51,239,229,104,213, 35, 82,211, 93,110, 32,162,165,140, 49, 55, 69, + 10, 16,197,147, 33, 20, 25, 99,221, 68,148,147,104, 51,219, 92,241,127, 26, 15, 32,186,209, 16,201,236,250,159,202, 76, 86, 0, +254, 11,146,157,127, 58, 58, 58,201,163, 7, 0, 58, 58, 58, 58, 58, 58,143, 32,137,183, 82,235,232,232,232,232,232,232, 60,116, +232, 1,128,142,142,142,142,142,206, 35,200,191, 46, 96, 71,216,137,209,203,202, 0, 0, 0, 0, 73, 69, 78, 68,174, 66, 96,130, }; diff --git a/source/blender/src/header_info.c b/source/blender/src/header_info.c index bf4beacaa58..97607b69446 100644 --- a/source/blender/src/header_info.c +++ b/source/blender/src/header_info.c @@ -78,7 +78,6 @@ #include "BIF_usiblender.h" #include "BIF_writeimage.h" #include "BIF_drawscene.h" - #ifdef WITH_VERSE #include "BIF_verse.h" #endif @@ -830,6 +829,8 @@ static void do_info_filemenu(void *arg, int event) if (untitled(dir)) { activate_fileselect(FILE_BLENDER, "Save As", dir, BIF_write_file); } else { + /* do NOT ask everytime for overwriting... */ + G.save_over = 1; BIF_write_file(dir); free_filesel_spec(dir); } diff --git a/source/blender/src/toets.c b/source/blender/src/toets.c index 27a39537988..14b8eca4135 100644 --- a/source/blender/src/toets.c +++ b/source/blender/src/toets.c @@ -831,6 +831,8 @@ int blenderqread(unsigned short event, short val) if (untitled(dir)) { activate_fileselect(FILE_BLENDER, "Save File", dir, BIF_write_file); } else { + /* do NOT ask everytime for overwriting... */ + G.save_over = 1; BIF_write_file(dir); free_filesel_spec(dir); } @@ -931,6 +933,8 @@ int blenderqread(unsigned short event, short val) if (untitled(dir)) { activate_fileselect(FILE_BLENDER, "Save File", dir, BIF_write_file); } else { + /* do NOT ask everytime for overwriting... */ + G.save_over = 1; BIF_write_file(dir); free_filesel_spec(dir); } diff --git a/source/blender/src/toolbox.c b/source/blender/src/toolbox.c index 969b9d4657b..97794148895 100644 --- a/source/blender/src/toolbox.c +++ b/source/blender/src/toolbox.c @@ -169,6 +169,28 @@ void asciitoraw(int ch, unsigned short *event, unsigned short *qual) /* this va_ stuff allows printf() style codes in these menus */ +static int vconfirm_choice(char *title, char *itemfmt, va_list ap) +{ + char *s, buf[512]; + + s= buf; + if (title) s+= sprintf(s, "%s%%t|", title); + vsprintf(s, itemfmt, ap); + + return (pupmenu(buf)); +} +int confirm_choice(char *title, char *itemfmt, ...) +{ + va_list ap; + int ret; + + va_start(ap, itemfmt); + ret= vconfirm_choice(title, itemfmt, ap); + va_end(ap); + + return ret; +} + static int vconfirm(char *title, char *itemfmt, va_list ap) { char *s, buf[512]; diff --git a/source/blender/src/usiblender.c b/source/blender/src/usiblender.c index 2bf2d5d9ae9..f3801342b3a 100644 --- a/source/blender/src/usiblender.c +++ b/source/blender/src/usiblender.c @@ -110,6 +110,7 @@ #include "BIF_resources.h" #include "BIF_screen.h" #include "BIF_space.h" +#include "BIF_toets.h" #include "BIF_toolbox.h" #include "BIF_cursors.h" @@ -793,7 +794,7 @@ void BIF_write_file(char *target) strcpy(di, target); } - if (BLI_exists(di)) { + if (BLI_exists(di) && !G.save_over) { if(!saveover(di)) return; } @@ -824,9 +825,13 @@ void BIF_write_file(char *target) G.save_over = 1; writeBlog(); + } else { error("%s", err); } + + /* CLEARS signal: "file needs save" on exit */ + U.uiflag &= ~USER_UNDOSAVE; waitcursor(0); } @@ -927,6 +932,41 @@ void BIF_init(void) BLI_strncpy(G.lib, G.sce, FILE_MAX); } +int exit_save_question(void) +{ + char dir[FILE_MAXDIR]; + int ret = 0; + + /* just go on if no undo there */ + /* better check necessary --> some flag */ + if(!(U.uiflag & USER_UNDOSAVE)) + return 1; + + /* do sweet question here */ + ret = confirm_choice("Warning: Unsaved changes", "Do you want to save your changes before exit?"); + + if(ret==1) + { + /* copyied from header_info.c */ + strcpy(dir, G.sce); + if (untitled(dir)) { + activate_fileselect(FILE_BLENDER, "Save As", dir, BIF_write_file); + } else { + /* do NOT ask everytime for overwriting... */ + G.save_over = 1; + BIF_write_file(dir); + free_filesel_spec(dir); + } + return 1; + } + else + { + /* cancel, ok, continue button available */ + } + + return 1; +} + /***/ extern ListBase editNurb; @@ -934,7 +974,15 @@ extern ListBase editelems; void exit_usiblender(void) { - struct TmpFont *tf; + struct TmpFont *tf; + + /* ask for save before exit */ + if(!exit_save_question()) + { + /* user pressed 'cancel' */ + return; + } + tf= G.ttfdata.first; while(tf) { From 9e96ac11bbe0212d031e59df461d3ae887e07d03 Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Fri, 21 Dec 2007 01:24:09 +0000 Subject: [PATCH 068/246] WIP commit, just to have a nice return from holidays :) --- source/blender/blenkernel/BKE_blender.h | 1 - source/blender/blenkernel/BKE_cloth.h | 6 + source/blender/blenkernel/intern/cloth.c | 336 +++------------------- source/blender/src/drawobject.c | 340 +++++++++++++++++++++++ 4 files changed, 382 insertions(+), 301 deletions(-) diff --git a/source/blender/blenkernel/BKE_blender.h b/source/blender/blenkernel/BKE_blender.h index 84ebd3102b3..243425db139 100644 --- a/source/blender/blenkernel/BKE_blender.h +++ b/source/blender/blenkernel/BKE_blender.h @@ -70,7 +70,6 @@ extern void BKE_reset_undo(void); extern char *BKE_undo_menu_string(void); extern void BKE_undo_number(int nr); extern void BKE_undo_save_quit(void); -extern int BKE_undo_there(void); #ifdef __cplusplus } diff --git a/source/blender/blenkernel/BKE_cloth.h b/source/blender/blenkernel/BKE_cloth.h index d888ba28ebe..b122347998d 100644 --- a/source/blender/blenkernel/BKE_cloth.h +++ b/source/blender/blenkernel/BKE_cloth.h @@ -67,6 +67,12 @@ typedef struct fc float *u, *u0; // velocity in x direction float *v, *v0; // velocity in y direction float *w, *w0; // velocity in z direction + unsigned char* _texture_data; + float _light_dir[3]; + int _ray_templ[4096][3]; + FILE* _fp; + int _cur_frame; + int _nframes; } fc; fc *f_init(void); void f_free(fc *m_fc); diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c index 95d487b2ec7..318d6eac410 100644 --- a/source/blender/blenkernel/intern/cloth.c +++ b/source/blender/blenkernel/intern/cloth.c @@ -498,308 +498,33 @@ static int cloth_read_cache(Object *ob, ClothModifierData *clmd, float framenr) return ret; } -#define AMBIENT 50 -#define DECAY 0.04f -#define ALMOST_EQUAL(a, b) ((fabs(a-b)<0.00001f)?1:0) - - // cube vertices -GLfloat cv[][3] = { - {1.0f, 1.0f, 1.0f}, {-1.0f, 1.0f, 1.0f}, {-1.0f, -1.0f, 1.0f}, {1.0f, -1.0f, 1.0f}, - {1.0f, 1.0f, -1.0f}, {-1.0f, 1.0f, -1.0f}, {-1.0f, -1.0f, -1.0f}, {1.0f, -1.0f, -1.0f} -}; - - // edges have the form edges[n][0][xyz] + t*edges[n][1][xyz] -float edges[12][2][3] = { - {{1.0f, 1.0f, -1.0f}, {0.0f, 0.0f, 1.0f}}, - {{-1.0f, 1.0f, -1.0f}, {0.0f, 0.0f, 1.0f}}, - {{-1.0f, -1.0f, -1.0f}, {0.0f, 0.0f, 1.0f}}, - {{1.0f, -1.0f, -1.0f}, {0.0f, 0.0f, 1.0f}}, - - {{1.0f, -1.0f, 1.0f}, {0.0f, 1.0f, 0.0f}}, - {{-1.0f, -1.0f, 1.0f}, {0.0f, 1.0f, 0.0f}}, - {{-1.0f, -1.0f, -1.0f}, {0.0f, 1.0f, 0.0f}}, - {{1.0f, -1.0f, -1.0f}, {0.0f, 1.0f, 0.0f}}, - - {{-1.0f, 1.0f, 1.0f}, {1.0f, 0.0f, 0.0f}}, - {{-1.0f, -1.0f, 1.0f}, {1.0f, 0.0f, 0.0f}}, - {{-1.0f, -1.0f, -1.0f}, {1.0f, 0.0f, 0.0f}}, - {{-1.0f, 1.0f, -1.0f}, {1.0f, 0.0f, 0.0f}} -}; - -void light_ray(unsigned char* _texture_data, int _ray_templ[4096][3], int x, int y, int z, int n, float decay) +int m_fc_open(ClothModifierData *clmd) { - int xx = x, yy = y, zz = z, i = 0; - int offset; - - int l = 255; - float d; - - do { - offset = ((((zz*n) + yy)*n + xx) << 2); - if (_texture_data[offset + 2] > 0) - _texture_data[offset + 2] = (unsigned char) ((_texture_data[offset + 2] + l)*0.5f); - else - _texture_data[offset + 2] = (unsigned char) l; - d = _texture_data[offset+1]; - if (l > AMBIENT) { - l -= d*decay; - if (l < AMBIENT) - l = AMBIENT; - } - - i++; - xx = x + _ray_templ[i][0]; - yy = y + _ray_templ[i][1]; - zz = z + _ray_templ[i][2]; - - } while ((xx>=0)&&(xx=0)&&(yy=0)&&(zz0) ? 0 : n-1; - int sy = (_light_dir[1]>0) ? 0 : n-1; - int sz = (_light_dir[2]>0) ? 0 : n-1; - - float decay = 1.0f/(n*DECAY); - - for (i=0; i 0) ? 1 : -1; - int yinc = (ly > 0) ? 1 : -1; - int zinc = (lz > 0) ? 1 : -1; - float tx, ty, tz; - int i = 1; - int len = 0; - int maxlen = 3*edgelen*edgelen; - _ray_templ[0][0] = _ray_templ[0][2] = _ray_templ[0][2] = 0; + Cloth *cloth = clmd->clothObject; + int _N; + fc *m_fc = NULL; - while (len <= maxlen) - { - // fx + t*lx = (x+1) -> t = (x+1-fx)/lx - tx = (x+xinc-fx)/lx; - ty = (y+yinc-fy)/ly; - tz = (z+zinc-fz)/lz; + if(!cloth) + return 0; + + m_fc = cloth->m_fc; - if ((tx<=ty)&&(tx<=tz)) { - _ray_templ[i][0] = _ray_templ[i-1][0] + xinc; - x =+ xinc; - fx = x; + m_fc->_fp = fopen("/home/daniel/Desktop/f32rand.dat", "rb"); + if (!m_fc->_fp) + return 0; - if (ALMOST_EQUAL(ty,tx)) { - _ray_templ[i][1] = _ray_templ[i-1][1] + yinc; - y += yinc; - fy = y; - } else { - _ray_templ[i][1] = _ray_templ[i-1][1]; - fy += tx*ly; - } - - if (ALMOST_EQUAL(tz,tx)) { - _ray_templ[i][2] = _ray_templ[i-1][2] + zinc; - z += zinc; - fz = z; - } else { - _ray_templ[i][2] = _ray_templ[i-1][2]; - fz += tx*lz; - } - } else if ((ty0)&&(t<2)) { - ret[num][0] = edges[i][0][0] + edges[i][1][0]*t; - ret[num][1] = edges[i][0][1] + edges[i][1][1]*t; - ret[num][2] = edges[i][0][2] + edges[i][1][2]*t; - num++; - } - } - - return num; -} - -void draw_slices(float m[][4]) -{ - int i; - - Vec3 viewdir(m[0][2], m[1][2], m[2][2]); - viewdir.Normalize(); - // find cube vertex that is closest to the viewer - for (i=0; i<8; i++) { - float x = cv[i][0] + viewdir[0]; - float y = cv[i][1] + viewdir[1]; - float z = cv[i][2] + viewdir[2]; - if ((x>=-1.0f)&&(x<=1.0f) - &&(y>=-1.0f)&&(y<=1.0f) - &&(z>=-1.0f)&&(z<=1.0f)) - { - break; - } - } - if(i != 8) return; - - glBlendFunc(GL_SRC_ALPHA, GL_ONE); - glDisable(GL_DEPTH_TEST); - // our slices are defined by the plane equation a*x + b*y +c*z + d = 0 - // (a,b,c), the plane normal, are given by viewdir - // d is the parameter along the view direction. the first d is given by - // inserting previously found vertex into the plane equation - float d0 = -(viewdir[0]*cv[i][0] + viewdir[1]*cv[i][1] + viewdir[2]*cv[i][2]); - float dd = 2*d0/64.0f; - int n = 0; - for (float d = -d0; d < d0; d += dd) { - // intersect_edges returns the intersection points of all cube edges with - // the given plane that lie within the cube - float pt[12][3]; - int num = intersect_edges(pt, viewdir[0], viewdir[1], viewdir[2], d); - - if (num > 2) { - // sort points to get a convex polygon - // std::sort(pt.begin()+1, pt.end(), Convexcomp(pt[0], viewdir)); - int shuffled = 1; - - while(shuffled) - { - int j; - shuffled = 0; - - for(j = 0; j < num-1; j++) - { - // Vec3 va = a-p0, vb = b-p0; - // return dot(up, cross(va, vb)) >= 0; - float va[3], vb[3], vc[3]; - - VECSUB(va, pt[j], pt[0]); - VECSUB(vb, pt[j+1], pt[0]); - Crossf(vc, va, vb); - - if(INPR(viewdir, vc)>= 0) - { - float temp[3]; - - VECCOPY(temp, pt[j]); - VECCOPY(pt[j], pt[j+1]); - VECCOPY(pt[j+1], temp); - - shuffled = 1; - } - } - } - - glEnable(GL_TEXTURE_3D); - glEnable(GL_FRAGMENT_PROGRAM_ARB); - glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, _prog[0]); - glActiveTextureARB(GL_TEXTURE0_ARB); - glBindTexture(GL_TEXTURE_3D, _txt[0]); - glBegin(GL_POLYGON); - for (i=0; i_fp); + fread(&_N, sizeof(int), 1, m_fc->_fp); + printf("Resolution: %dx%dx%d\n", _N, _N, _N); + + fread(&m_fc->_nframes, sizeof(int), 1, m_fc->_fp); + printf("Number of frames: %d\n", m_fc->_nframes); + m_fc->_cur_frame = 0; + + return 1; } -void draw(void) -{ - int i; - - glClearColor(0, 0, 0, 0); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); - gluLookAt(0, 0, -_dist, 0, 0, 0, 0, 1, 0); - - float m[4][4]; - build_rotmatrix(m, _quat); - - glMultMatrixf(&m[0][0]); - - if (_draw_cube) - draw_cube(); - draw_slices(m, _draw_slice_outline); - - if (_dispstring != NULL) { - glMatrixMode(GL_PROJECTION); - glLoadMatrixd(_ortho_m); - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); - - glDisable(GL_TEXTURE_3D); - glDisable(GL_FRAGMENT_PROGRAM_ARB); - glColor4f(1.0, 1.0, 1.0, 1.0); - glRasterPos2i(-_sx/2 + 10, _sy/2 - 15); - - print_string(_dispstring); - - glMatrixMode(GL_PROJECTION); - glLoadMatrixd(_persp_m); - glMatrixMode(GL_MODELVIEW); - } -}*/ /************************************************ * clothModifier_do - main simulation function @@ -819,9 +544,6 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd,Object *ob, DerivedMesh *d float current_time = bsystem_time(ob, (float)G.scene->r.cfra, 0.0); ListBase *effectors = NULL; float deltaTime = current_time - clmd->sim_parms->sim_time; - unsigned char* _texture_data=NULL; - float _light_dir[3]; - int _ray_templ[4096][3]; clmd->sim_parms->dt = 1.0f / (clmd->sim_parms->stepsPerFrame * G.scene->r.frs_sec); @@ -1216,6 +938,9 @@ static int cloth_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *d cloth->m_fc = f_init(); + // open file + m_fc_open(clmd); + switch (ob->type) { case OB_MESH: @@ -1895,8 +1620,7 @@ fc *f_init(void) int i; int size; - fc *m_fc = MEM_callocN(sizeof(fc), - "f_c"); + fc *m_fc = MEM_callocN(sizeof(fc), "f_c"); for (i=0; i<10; i++) clear_buffer(buffers[i]); @@ -1913,12 +1637,24 @@ fc *f_init(void) for (i=0; iv[i] = -0.5f; + m_fc->_texture_data = (unsigned char*) MEM_callocN((30+2)*(30+2)*(30+2)*4, "fc_texture_data"); + + m_fc->_fp = 0; + return m_fc; } void f_free(fc *m_fc) { if(m_fc) + { + if(m_fc->_texture_data) + MEM_freeN(m_fc->_texture_data); + + if(m_fc->_fp) + fclose(m_fc->_fp); + MEM_freeN(m_fc); + } } diff --git a/source/blender/src/drawobject.c b/source/blender/src/drawobject.c index db2225f4823..a6fced7124a 100644 --- a/source/blender/src/drawobject.c +++ b/source/blender/src/drawobject.c @@ -78,6 +78,7 @@ #include "BLI_rand.h" #include "BKE_utildefines.h" +#include "BKE_cloth.h" #include "BKE_curve.h" #include "BKE_constraint.h" // for the get_constraint_target function #include "BKE_DerivedMesh.h" @@ -2174,6 +2175,345 @@ static void draw_em_fancy(Object *ob, EditMesh *em, DerivedMesh *cageDM, Derived /* Mesh drawing routines */ + + +#define AMBIENT 50 +#define DECAY 0.04f +#define ALMOST_EQUAL(a, b) ((fabs(a-b)<0.00001f)?1:0) + + // cube vertices +GLfloat cv[][3] = { + {1.0f, 1.0f, 1.0f}, {-1.0f, 1.0f, 1.0f}, {-1.0f, -1.0f, 1.0f}, {1.0f, -1.0f, 1.0f}, + {1.0f, 1.0f, -1.0f}, {-1.0f, 1.0f, -1.0f}, {-1.0f, -1.0f, -1.0f}, {1.0f, -1.0f, -1.0f} +}; + + // edges have the form edges[n][0][xyz] + t*edges[n][1][xyz] +float edges[12][2][3] = { + {{1.0f, 1.0f, -1.0f}, {0.0f, 0.0f, 1.0f}}, + {{-1.0f, 1.0f, -1.0f}, {0.0f, 0.0f, 1.0f}}, + {{-1.0f, -1.0f, -1.0f}, {0.0f, 0.0f, 1.0f}}, + {{1.0f, -1.0f, -1.0f}, {0.0f, 0.0f, 1.0f}}, + + {{1.0f, -1.0f, 1.0f}, {0.0f, 1.0f, 0.0f}}, + {{-1.0f, -1.0f, 1.0f}, {0.0f, 1.0f, 0.0f}}, + {{-1.0f, -1.0f, -1.0f}, {0.0f, 1.0f, 0.0f}}, + {{1.0f, -1.0f, -1.0f}, {0.0f, 1.0f, 0.0f}}, + + {{-1.0f, 1.0f, 1.0f}, {1.0f, 0.0f, 0.0f}}, + {{-1.0f, -1.0f, 1.0f}, {1.0f, 0.0f, 0.0f}}, + {{-1.0f, -1.0f, -1.0f}, {1.0f, 0.0f, 0.0f}}, + {{-1.0f, 1.0f, -1.0f}, {1.0f, 0.0f, 0.0f}} +}; + +void light_ray(unsigned char* _texture_data, int _ray_templ[4096][3], int x, int y, int z, int n, float decay) +{ + int xx = x, yy = y, zz = z, i = 0; + int offset; + + int l = 255; + float d; + + do { + offset = ((((zz*n) + yy)*n + xx) << 2); + if (_texture_data[offset + 2] > 0) + _texture_data[offset + 2] = (unsigned char) ((_texture_data[offset + 2] + l)*0.5f); + else + _texture_data[offset + 2] = (unsigned char) l; + d = _texture_data[offset+1]; + if (l > AMBIENT) { + l -= d*decay; + if (l < AMBIENT) + l = AMBIENT; + } + + i++; + xx = x + _ray_templ[i][0]; + yy = y + _ray_templ[i][1]; + zz = z + _ray_templ[i][2]; + + } while ((xx>=0)&&(xx=0)&&(yy=0)&&(zz0) ? 0 : n-1; + int sy = (_light_dir[1]>0) ? 0 : n-1; + int sz = (_light_dir[2]>0) ? 0 : n-1; + + float decay = 1.0f/(n*DECAY); + + for (i=0; i 0) ? 1 : -1; + int yinc = (ly > 0) ? 1 : -1; + int zinc = (lz > 0) ? 1 : -1; + float tx, ty, tz; + int i = 1; + int len = 0; + int maxlen = 3*edgelen*edgelen; + _ray_templ[0][0] = _ray_templ[0][2] = _ray_templ[0][2] = 0; + + while (len <= maxlen) + { + // fx + t*lx = (x+1) -> t = (x+1-fx)/lx + tx = (x+xinc-fx)/lx; + ty = (y+yinc-fy)/ly; + tz = (z+zinc-fz)/lz; + + if ((tx<=ty)&&(tx<=tz)) { + _ray_templ[i][0] = _ray_templ[i-1][0] + xinc; + x =+ xinc; + fx = x; + + if (ALMOST_EQUAL(ty,tx)) { + _ray_templ[i][1] = _ray_templ[i-1][1] + yinc; + y += yinc; + fy = y; + } else { + _ray_templ[i][1] = _ray_templ[i-1][1]; + fy += tx*ly; + } + + if (ALMOST_EQUAL(tz,tx)) { + _ray_templ[i][2] = _ray_templ[i-1][2] + zinc; + z += zinc; + fz = z; + } else { + _ray_templ[i][2] = _ray_templ[i-1][2]; + fz += tx*lz; + } + } else if ((ty0)&&(t<2)) { + ret[num][0] = edges[i][0][0] + edges[i][1][0]*t; + ret[num][1] = edges[i][0][1] + edges[i][1][1]*t; + ret[num][2] = edges[i][0][2] + edges[i][1][2]*t; + num++; + } + } + + return num; +} + +void draw_slices ( float m[][4] ) +{ + int i; + + float viewdir[3]; + float d0; + float dd; + int n; + float d; + + viewdir[0] = m[0][2]; + viewdir[1] = m[1][2]; + viewdir[2] = m[2][2]; + Normalize(viewdir); + + // find cube vertex that is closest to the viewer + for ( i=0; i<8; i++ ) + { + float x = cv[i][0] + viewdir[0]; + float y = cv[i][1] + viewdir[1]; + float z = cv[i][2] + viewdir[2]; + if ( ( x>=-1.0f ) && ( x<=1.0f ) + && ( y>=-1.0f ) && ( y<=1.0f ) + && ( z>=-1.0f ) && ( z<=1.0f ) ) + { + break; + } + } + if ( i != 8 ) return; + + glBlendFunc ( GL_SRC_ALPHA, GL_ONE ); + glDisable ( GL_DEPTH_TEST ); + // our slices are defined by the plane equation a*x + b*y +c*z + d = 0 + // (a,b,c), the plane normal, are given by viewdir + // d is the parameter along the view direction. the first d is given by + // inserting previously found vertex into the plane equation + d0 = - ( viewdir[0]*cv[i][0] + viewdir[1]*cv[i][1] + viewdir[2]*cv[i][2] ); + dd = 2*d0/64.0f; + n = 0; + + for ( d = -d0; d < d0; d += dd ) + { + // intersect_edges returns the intersection points of all cube edges with + // the given plane that lie within the cube + float pt[12][3]; + int num = intersect_edges ( pt, viewdir[0], viewdir[1], viewdir[2], d ); + + if ( num > 2 ) + { + // sort points to get a convex polygon + // std::sort(pt.begin()+1, pt.end(), Convexcomp(pt[0], viewdir)); + int shuffled = 1; + + while ( shuffled ) + { + int j; + shuffled = 0; + + for ( j = 0; j < num-1; j++ ) + { + // Vec3 va = a-p0, vb = b-p0; + // return dot(up, cross(va, vb)) >= 0; + float va[3], vb[3], vc[3]; + + VECSUB ( va, pt[j], pt[0] ); + VECSUB ( vb, pt[j+1], pt[0] ); + Crossf ( vc, va, vb ); + + if ( INPR ( viewdir, vc ) >= 0 ) + { + float temp[3]; + + VECCOPY ( temp, pt[j] ); + VECCOPY ( pt[j], pt[j+1] ); + VECCOPY ( pt[j+1], temp ); + + shuffled = 1; + } + } + } +/* + glEnable ( GL_TEXTURE_3D ); + glEnable ( GL_FRAGMENT_PROGRAM_ARB ); + glBindProgramARB ( GL_FRAGMENT_PROGRAM_ARB, _prog[0] ); + glActiveTextureARB ( GL_TEXTURE0_ARB ); + glBindTexture ( GL_TEXTURE_3D, _txt[0] ); + glBegin ( GL_POLYGON ); + for ( i=0; iclothObject; + fc *m_fc = NULL; + + if(!cloth) + return; + + m_fc = cloth->m_fc; + + glClearColor(0, 0, 0, 0); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + // gluLookAt(0, 0, -_dist, 0, 0, 0, 0, 1, 0); + + // build_rotmatrix(m, _quat); + + glMultMatrixf(&m[0][0]); + + // ---------------------------------------- + // from ligth constructor + m_fc->_light_dir[0] = -1.0f; + m_fc->_light_dir[1] = 0.5f; + m_fc->_light_dir[2] = 0.0f; + + gen_ray_templ(m_fc->_ray_templ, m_fc->_light_dir, 30 + 2); + + cast_light(m_fc->_texture_data, m_fc->_ray_templ, m_fc->_light_dir, 30+2); + + glActiveTextureARB(GL_TEXTURE0_ARB); + glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA, 30+2, 30+2, 30+2, 0, GL_RGBA, GL_UNSIGNED_BYTE, m_fc->_texture_data); + // ---------------------------------------- + + draw_slices(m); +/* + if (_dispstring != NULL) { + glMatrixMode(GL_PROJECTION); + glLoadMatrixd(_ortho_m); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + + glDisable(GL_TEXTURE_3D); + glDisable(GL_FRAGMENT_PROGRAM_ARB); + glColor4f(1.0, 1.0, 1.0, 1.0); + glRasterPos2i(-_sx/2 + 10, _sy/2 - 15); + + print_string(_dispstring); + + glMatrixMode(GL_PROJECTION); + glLoadMatrixd(_persp_m); + glMatrixMode(GL_MODELVIEW); + } +*/ +} + static void draw_mesh_object_outline(Object *ob, DerivedMesh *dm) { From 5b9a06e041240301d6ee527eaceea29704783346 Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Wed, 2 Jan 2008 13:51:44 +0000 Subject: [PATCH 069/246] Pre merge commit, only added debug output so far --- source/blender/blenkernel/intern/implicit.c | 6 ++- source/blender/src/drawobject.c | 48 ++++++++++++++++++++- 2 files changed, 51 insertions(+), 3 deletions(-) diff --git a/source/blender/blenkernel/intern/implicit.c b/source/blender/blenkernel/intern/implicit.c index 9e4428c1055..a1d60b34125 100644 --- a/source/blender/blenkernel/intern/implicit.c +++ b/source/blender/blenkernel/intern/implicit.c @@ -1687,8 +1687,7 @@ int collisions_collision_response_static ( ClothModifierData *clmd, CollisionMod // If v_n_mag < 0 the edges are approaching each other. if ( magrelVel < -ALMOST_ZERO ) { - printf("magrelVel < -ALMOST_ZERO\n"); - + // Calculate Impulse magnitude to stop all motion in normal direction. // const double I_mag = v_n_mag / (1/m1 + 1/m2); float magnitude_i = magrelVel / 2.0f; // TODO implement masses @@ -1697,6 +1696,8 @@ int collisions_collision_response_static ( ClothModifierData *clmd, CollisionMod float vrel_t[3]; double impulse; float overlap = ( epsilon + ALMOST_ZERO-collpair->distance ); + + printf("magrelVel < -ALMOST_ZERO\n"); // calculateFrictionImpulse(tangential, relativeVelocity, collpair->normal, magrelVel, clmd->coll_parms.friction*0.01, magrelVel); @@ -1737,6 +1738,7 @@ int collisions_collision_response_static ( ClothModifierData *clmd, CollisionMod collmd->verts[collpair->point_indexB[2]].impulse_count++; */ + result = 1; // printf("magnitude_i: %f\n", magnitude_i); // negative before collision in my case diff --git a/source/blender/src/drawobject.c b/source/blender/src/drawobject.c index a6fced7124a..111f0789ee9 100644 --- a/source/blender/src/drawobject.c +++ b/source/blender/src/drawobject.c @@ -2483,7 +2483,7 @@ void draw_fl(ClothModifierData *clmd) m_fc->_light_dir[0] = -1.0f; m_fc->_light_dir[1] = 0.5f; m_fc->_light_dir[2] = 0.0f; - + gen_ray_templ(m_fc->_ray_templ, m_fc->_light_dir, 30 + 2); cast_light(m_fc->_texture_data, m_fc->_ray_templ, m_fc->_light_dir, 30+2); @@ -2514,6 +2514,52 @@ void draw_fl(ClothModifierData *clmd) */ } +void fc_load_frame(ClothModifierData *clmd) +{ + float* tmp = (float*) MEM_callocN(30*30*30*sizeof(float), "fc_tmp"); + float tmin=9999999, tmax=-99999999; + Cloth *cloth = clmd->clothObject; + fc *m_fc = NULL; + int i = 0; + + if(!cloth) + return; + + m_fc = cloth->m_fc; + + if (++m_fc->_cur_frame == m_fc->_nframes) { + fseek(m_fc->_fp, 12, SEEK_SET); + m_fc->_cur_frame = 0; + } + + fread(tmp, sizeof(float), 30*30*30, m_fc->_fp); + + for (i=0; i<30*30*30; i++) + { + m_fc->_texture_data[(i<<2)+1] = (unsigned char) (tmp[i]*255.0f); + } + + fread(tmp, sizeof(float), 30*30*30, m_fc->_fp); + + for (i=0; i<30*30*30; i++) + { + m_fc->_texture_data[(i<<2)] = (unsigned char) (tmp[i]*255.0f); + if (tmp[i]tmax) + tmax = tmp[i]; + m_fc->_texture_data[(i<<2)+2] = 0; + m_fc->_texture_data[(i<<2)+3] = 255; + } + + MEM_freeN(tmp); + + // cast_light(_N); DG NOT NEEDED + + glActiveTextureARB(GL_TEXTURE0_ARB); + glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA, 30, 30, 30, 0, GL_RGBA, GL_UNSIGNED_BYTE, m_fc->_texture_data); +} + static void draw_mesh_object_outline(Object *ob, DerivedMesh *dm) { From 8d6bbf763504af934a859573ba45880159bc1828 Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Mon, 7 Jan 2008 03:20:43 +0000 Subject: [PATCH 070/246] Merged back with last version where collisions worked at least a bit (rev 12296). Also merged fixes (hopefully). --- CMakeLists.txt | 23 +- source/blender/blenkernel/BKE_cloth.h | 188 +- source/blender/blenkernel/BKE_modifier.h | 2 +- source/blender/blenkernel/intern/cloth.c | 1667 +++++++----------- source/blender/blenkernel/intern/collision.c | 900 +++++++++- source/blender/blenkernel/intern/implicit.c | 1200 ++----------- source/blender/blenkernel/intern/modifier.c | 221 +-- source/blender/blenloader/intern/readfile.c | 5 +- source/blender/blenloader/intern/writefile.c | 2 + source/blender/makesdna/DNA_cloth_types.h | 102 +- source/blender/makesdna/DNA_modifier_types.h | 6 +- source/blender/src/buttons_object.c | 193 +- source/blender/src/drawobject.c | 106 -- source/blender/src/vpaint.c | 7 +- 14 files changed, 2043 insertions(+), 2579 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index d79c2220104..4eb5e9c659d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -65,8 +65,9 @@ OPTION(WITH_ELBEEM "Enable Elbeem (Fluid Simulation)" ON) OPTION(WITH_QUICKTIME "Enable Quicktime Support" OFF) OPTION(WITH_OPENEXR "Enable OpenEXR Support (http://www.openexr.com)" OFF) OPTION(WITH_FFMPEG "Enable FFMPeg Support (http://ffmpeg.mplayerhq.hu/)" OFF) -OPTION(WITH_OPENAL "Enable OpenAL Support (http://www.openal.org)" ON) -OPTION(YESIAMSTUPID "Enable execution on 64-bit platforms" OFF) +OPTION(WITH_OPENAL "Enable OpenAL Support (http://www.openal.org)" ON) +OPTION(YESIAMSTUPID "Enable execution on 64-bit platforms" OFF) +OPTION(WITH_OPENMP "Enable OpenMP (has to be supported by the compiler)" OFF) IF(NOT WITH_GAMEENGINE AND WITH_PLAYER) MESSAGE("WARNING: WITH_PLAYER needs WITH_GAMEENGINE") @@ -184,6 +185,13 @@ IF(UNIX) SET(LLIBS "-lXi -lutil -lc -lm -lpthread -lstdc++") + IF(WITH_OPENMP) + SET(LLIBS "${LLIBS} -lgomp ") + SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fopenmp ") + SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fopenmp ") + ENDIF(WITH_OPENMP) + + SET(PLATFORM_CFLAGS "-pipe -fPIC -funsigned-char -fno-strict-aliasing -DXP_UNIX -Wno-char-subscripts") SET(PLATFORM_LINKFLAGS "-pthread") @@ -270,6 +278,11 @@ IF(WIN32) SET(CMAKE_C_FLAGS_MINSIZEREL "/D_CRT_NONSTDC_NO_DEPRECATE /D_CRT_SECURE_NO_DEPRECATE /D_SCL_SECURE_NO_DEPRECATE /wd4800 /wd4244 /wd4305 /O1 /Ob1 /DNDEBUG /EHsc /MT /W3 /nologo /J" CACHE STRING "MSVC MT flags " FORCE) SET(CMAKE_C_FLAGS_RELWITHDEBINFO "/D_CRT_NONSTDC_NO_DEPRECATE /D_CRT_SECURE_NO_DEPRECATE /D_SCL_SECURE_NO_DEPRECATE /wd4800 /wd4244 /wd4305 /O2 /Ob1 /DNDEBUG /EHsc /MT /W3 /nologo /Zi /J" CACHE STRING "MSVC MT flags " FORCE) + IF(WITH_OPENMP) + SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /openmp ") + SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /openmp ") + ENDIF(WITH_OPENMP) + SET(SDL ${LIBDIR}/sdl) SET(SDL_INC ${SDL}/include) SET(SDL_LIB SDL) @@ -347,6 +360,12 @@ IF(APPLE) SET(PLATFORM_CFLAGS "-pipe -fPIC -funsigned-char -fno-strict-aliasing") SET(PLATFORM_LINKFLAGS "-fexceptions -framework CoreServices -framework Foundation -framework IOKit -framework AppKit -framework Carbon -framework AGL -framework AudioUnit -framework AudioToolbox -framework CoreAudio -framework QuickTime") + IF(WITH_OPENMP) + SET(LLIBS "${LLIBS} -lgomp ") + SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fopenmp ") + SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fopenmp ") + ENDIF(WITH_OPENMP) + SET(SDL ${LIBDIR}/sdl) SET(SDL_INC ${SDL}/include) SET(SDL_LIB SDL) diff --git a/source/blender/blenkernel/BKE_cloth.h b/source/blender/blenkernel/BKE_cloth.h index b122347998d..eb1f33ae600 100644 --- a/source/blender/blenkernel/BKE_cloth.h +++ b/source/blender/blenkernel/BKE_cloth.h @@ -34,14 +34,14 @@ #ifndef BKE_CLOTH_H #define BKE_CLOTH_H -#include "BKE_customdata.h" #include "BLI_linklist.h" +#include "BKE_customdata.h" #include "BKE_DerivedMesh.h" -#include "BKE_object.h" - #include "DNA_cloth_types.h" #include "DNA_customdata_types.h" #include "DNA_meshdata_types.h" +#include "DNA_modifier_types.h" +#include "DNA_object_types.h" struct Object; struct Cloth; @@ -49,8 +49,8 @@ struct MFace; struct DerivedMesh; struct ClothModifierData; -// this is needed for inlining behaviour +// this is needed for inlining behaviour #ifndef _WIN32 #define LINUX #define DO_INLINE inline @@ -60,71 +60,6 @@ struct ClothModifierData; #define CLOTH_MAX_THREAD 2 -typedef struct fc -{ - float *d, *d0; // density - float *T, *T0; // temperature - float *u, *u0; // velocity in x direction - float *v, *v0; // velocity in y direction - float *w, *w0; // velocity in z direction - unsigned char* _texture_data; - float _light_dir[3]; - int _ray_templ[4096][3]; - FILE* _fp; - int _cur_frame; - int _nframes; -} fc; -fc *f_init(void); -void f_free(fc *m_fc); -void step(fc *m_fc, float dt); - - -typedef struct ClothVertex { - int flags; /* General flags per vertex. */ - float mass; /* mass / weight of the vertex */ - float goal; /* goal, from SB */ - float impulse[3]; /* used in collision.c */ - unsigned int impulse_count; /* same as above */ - float collball; - char octantflag; - float weight; -} ClothVertex; - -typedef struct ClothSpring { - unsigned int ij; /* Pij from the paper, one end of the spring. */ - unsigned int kl; /* Pkl from the paper, one end of the spring. */ - float restlen; /* The original length of the spring. */ - unsigned int matrix_index; /* needed for implicit solver (fast lookup) */ - int type; /* types defined in BKE_cloth.h ("springType") */ - int flags; /* defined in BKE_cloth.h, e.g. deactivated due to tearing */ - float dfdx[3][3]; - float dfdv[3][3]; - float f[3]; -} ClothSpring; - -typedef struct Cloth { - struct ClothVertex *verts; /* The vertices that represent this cloth. */ - struct LinkNode *springs; /* The springs connecting the mesh. */ - struct BVH *tree; /* collision tree for this cloth object */ - struct BVH *selftree; /* self collision tree for this cloth object */ - struct MFace *mfaces; - struct Implicit_Data *implicit; /* our implicit solver connects to this pointer */ - struct EdgeHash *edgehash; /* used for fast checking adjacent points */ - unsigned int numverts; /* The number of verts == m * n. */ - unsigned int numsprings; /* The count of springs. */ - unsigned int numfaces; - unsigned int numothersprings; - unsigned int numspringssave; - unsigned int old_solver_type; - float (*x)[3]; /* The current position of all vertices.*/ - float (*xold)[3]; /* The previous position of all vertices.*/ - float (*current_x)[3]; /* The TEMPORARY current position of all vertices.*/ - float (*current_xold)[3]; /* The TEMPORARY previous position of all vertices.*/ - float (*v)[4]; /* the current velocity of all vertices */ - float (*current_v)[3]; - float (*xconst)[3]; - struct fc *m_fc; -} Cloth; /* goal defines */ #define SOFTGOALSNAP 0.999f @@ -155,9 +90,7 @@ typedef enum CLOTH_SIMSETTINGS_FLAG_COLLOBJ = ( 1 << 2 ), // object is only collision object, no cloth simulation is done CLOTH_SIMSETTINGS_FLAG_GOAL = ( 1 << 3 ), // we have goals enabled CLOTH_SIMSETTINGS_FLAG_TEARING = ( 1 << 4 ), // true if tearing is enabled - CLOTH_SIMSETTINGS_FLAG_CCACHE_PROTECT = ( 1 << 5 ), - CLOTH_SIMSETTINGS_FLAG_BIG_FORCE = ( 1 << 6 ), // true if we have big spring force for bending - CLOTH_SIMSETTINGS_FLAG_SLEEP = ( 1 << 7 ), // true if we let the cloth go to sleep + CLOTH_SIMSETTINGS_FLAG_CCACHE_PROTECT = ( 1 << 5 ), // true if tearing is enabled } CLOTH_SIMSETTINGS_FLAGS; /* SPRING FLAGS */ @@ -172,7 +105,6 @@ typedef enum CLOTH_SPRING_TYPE_STRUCTURAL = 0, CLOTH_SPRING_TYPE_SHEAR, CLOTH_SPRING_TYPE_BENDING, - CLOTH_SPRING_TYPE_COLLISION, } CLOTH_SPRING_TYPES; /* SPRING FLAGS */ @@ -188,32 +120,91 @@ typedef enum // needed for buttons_object.c -void cloth_clear_cache(struct Object *ob, struct ClothModifierData *clmd, float framenr); -void cloth_free_modifier ( struct ClothModifierData *clmd ); +void cloth_clear_cache(Object *ob, ClothModifierData *clmd, float framenr); // needed for cloth.c -void implicit_set_positions ( struct ClothModifierData *clmd ); +void implicit_set_positions ( ClothModifierData *clmd ); // from cloth.c, needed for modifier.c -DerivedMesh *clothModifier_do(struct ClothModifierData *clmd, struct Object *ob, struct DerivedMesh *dm, int useRenderParams, int isFinalCalc); +void clothModifier_do ( ClothModifierData *clmd, Object *ob, DerivedMesh *dm, float ( *vertexCos ) [3], int numverts ); -// needed in implicit.c -int cloth_bvh_objcollision(struct ClothModifierData *clmd, float step, float prevstep, float dt); +// used in collision.c +typedef struct Tree +{ + struct Tree *nodes[4]; // 4 children --> quad-tree + struct Tree *parent; + struct Tree *nextLeaf; + struct Tree *prevLeaf; + float bv[26]; // Bounding volume of all nodes / we have 7 axes on a 14-DOP + unsigned int tri_index; // this saves the index of the face + int count_nodes; // how many nodes are used + int traversed; // how many nodes already traversed until this level? + int isleaf; +} +Tree; + +typedef struct Tree TreeNode; + +typedef struct BVH +{ + unsigned int numfaces; + unsigned int numverts; + ClothVertex *verts; // just a pointer to the original datastructure + MFace *mfaces; // just a pointer to the original datastructure + struct LinkNode *tree; + TreeNode *root; // TODO: saving the root --> is this really needed? YES! + TreeNode *leaf_tree; /* Tail of the leaf linked list. */ + TreeNode *leaf_root; /* Head of the leaf linked list. */ + float epsilon; /* epslion is used for inflation of the k-dop */ + int flags; /* bvhFlags */ +} +BVH; + +typedef void ( *CM_COLLISION_RESPONSE ) ( ClothModifierData *clmd, ClothModifierData *coll_clmd, Tree * tree1, Tree * tree2 ); + + +///////////////////////////////////////////////// +// collision.c +//////////////////////////////////////////////// + +// needed for implicit.c +void bvh_collision_response ( ClothModifierData *clmd, ClothModifierData *coll_clmd, Tree * tree1, Tree * tree2 ); +int cloth_bvh_objcollision ( ClothModifierData * clmd, float step, float dt ); //////////////////////////////////////////////// +///////////////////////////////////////////////// +// kdop.c +//////////////////////////////////////////////// + +// needed for cloth.c +void bvh_free ( BVH * bvh ); +BVH *bvh_build ( ClothModifierData *clmd, float epsilon ); +LinkNode *BLI_linklist_append_fast ( LinkNode **listp, void *ptr ); + +// needed for collision.c +int bvh_traverse ( ClothModifierData * clmd, ClothModifierData * coll_clmd, Tree * tree1, Tree * tree2, float step, CM_COLLISION_RESPONSE collision_response ); +void bvh_update ( ClothModifierData * clmd, BVH * bvh, int moving ); + +//////////////////////////////////////////////// + + + ///////////////////////////////////////////////// // cloth.c //////////////////////////////////////////////// -void cloth_free_modifier ( struct ClothModifierData *clmd ); -void cloth_init ( struct ClothModifierData *clmd ); +void cloth_free_modifier ( ClothModifierData *clmd ); +void cloth_init ( ClothModifierData *clmd ); +void cloth_deform_verts ( struct Object *ob, float framenr, float ( *vertexCos ) [3], int numVerts, void *derivedData, ClothModifierData *clmd ); +void cloth_update_normals ( ClothVertex *verts, int nVerts, MFace *face, int totface ); + //////////////////////////////////////////////// /* Typedefs for function pointers we need for solvers and collision detection. */ -typedef void ( *CM_COLLISION_SELF ) ( struct ClothModifierData *clmd, int step ); -// typedef void ( *CM_COLLISION_OBJ ) ( ClothModifierData *clmd, int step, CM_COLLISION_RESPONSE collision_response ); +typedef void ( *CM_COLLISION_SELF ) ( ClothModifierData *clmd, int step ); +typedef void ( *CM_COLLISION_OBJ ) ( ClothModifierData *clmd, int step, CM_COLLISION_RESPONSE collision_response ); /* This enum provides the IDs for our solvers. */ @@ -229,26 +220,29 @@ typedef struct { char *name; CM_SOLVER_ID id; - int ( *init ) ( struct Object *ob, struct ClothModifierData *clmd ); - int ( *solver ) ( struct Object *ob, float framenr, struct ClothModifierData *clmd, struct ListBase *effectors ); - int ( *free ) ( struct ClothModifierData *clmd ); + int ( *init ) ( Object *ob, ClothModifierData *clmd ); + int ( *solver ) ( Object *ob, float framenr, ClothModifierData *clmd, ListBase *effectors ); + int ( *free ) ( ClothModifierData *clmd ); } CM_SOLVER_DEF; /* new C implicit simulator */ -int implicit_init ( struct Object *ob, struct ClothModifierData *clmd ); -int implicit_free ( struct ClothModifierData *clmd ); -int implicit_solver ( struct Object *ob, float frame, struct ClothModifierData *clmd, struct ListBase *effectors ); - -/* explicit verlet simulator */ -int verlet_init ( struct Object *ob, struct ClothModifierData *clmd ); -int verlet_free ( struct ClothModifierData *clmd ); -int verlet_solver ( struct Object *ob, float frame, struct ClothModifierData *clmd, struct ListBase *effectors ); +int implicit_init ( Object *ob, ClothModifierData *clmd ); +int implicit_free ( ClothModifierData *clmd ); +int implicit_solver ( Object *ob, float frame, ClothModifierData *clmd, ListBase *effectors ); +/* used for caching in implicit.c */ +typedef struct Frame +{ + ClothVertex *verts; + ClothSpring *springs; + unsigned int numverts, numsprings; + float time; /* we need float since we want to support sub-frames */ +} +Frame; /* used for collisions in collision.c */ -/* typedef struct CollPair { unsigned int face1; // cloth face @@ -263,7 +257,6 @@ typedef struct CollPair unsigned int pointsb[4]; } CollPair; -*/ /* used for collisions in collision.c */ typedef struct EdgeCollPair @@ -289,8 +282,5 @@ typedef struct FaceCollPair } FaceCollPair; -// function definitions from implicit.c -DO_INLINE void mul_fvector_S(float to[3], float from[3], float scalar); - #endif diff --git a/source/blender/blenkernel/BKE_modifier.h b/source/blender/blenkernel/BKE_modifier.h index 8927584de1b..682eb1a00dd 100644 --- a/source/blender/blenkernel/BKE_modifier.h +++ b/source/blender/blenkernel/BKE_modifier.h @@ -287,7 +287,7 @@ int modifiers_getCageIndex(struct Object *ob, int *lastPossibleCageIndex_r); int modifiers_isSoftbodyEnabled(struct Object *ob); -struct ClothModifierData *modifiers_isClothEnabled(Object *ob); +ModifierData * modifiers_isClothEnabled(Object *ob); int modifiers_isParticleEnabled(struct Object *ob); struct Object *modifiers_isDeformedByArmature(struct Object *ob); diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c index 318d6eac410..fef932174a1 100644 --- a/source/blender/blenkernel/intern/cloth.c +++ b/source/blender/blenkernel/intern/cloth.c @@ -39,15 +39,15 @@ /* types */ #include "DNA_curve_types.h" -#include "DNA_cloth_types.h" #include "DNA_object_types.h" #include "DNA_object_force.h" +#include "DNA_cloth_types.h" #include "DNA_key_types.h" -#include "DNA_lattice_types.h" #include "DNA_mesh_types.h" #include "DNA_meshdata_types.h" -#include "DNA_modifier_types.h" +#include "DNA_lattice_types.h" #include "DNA_scene_types.h" +#include "DNA_modifier_types.h" #include "BLI_blenlib.h" #include "BLI_arithb.h" @@ -55,8 +55,6 @@ #include "BLI_linklist.h" #include "BKE_curve.h" -#include "BKE_cloth.h" -#include "BKE_collisions.h" #include "BKE_deform.h" #include "BKE_DerivedMesh.h" #include "BKE_cdderivedmesh.h" @@ -65,11 +63,11 @@ #include "BKE_global.h" #include "BKE_key.h" #include "BKE_mesh.h" -#include "BKE_modifier.h" #include "BKE_object.h" -#include "BKE_pointcache.h" +#include "BKE_cloth.h" +#include "BKE_modifier.h" #include "BKE_utildefines.h" - +#include "BKE_DerivedMesh.h" #include "BIF_editdeform.h" #include "BIF_editkey.h" #include "DNA_screen_types.h" @@ -78,21 +76,7 @@ #include "BIF_space.h" #include "mydevice.h" -#ifdef WIN32 -#include -#endif // WIN32 -#ifdef __APPLE__ -#define GL_GLEXT_LEGACY 1 -#include -#include -#else -#include -#if defined(__sun__) && !defined(__sparc__) -#include -#else -#include -#endif -#endif +#include "BKE_pointcache.h" #ifdef _WIN32 void tstart ( void ) @@ -106,9 +90,9 @@ double tval() } #else #include - static struct timeval _tstart, _tend; - static struct timezone tz; - void tstart ( void ) +static struct timeval _tstart, _tend; +static struct timezone tz; +void tstart ( void ) { gettimeofday ( &_tstart, &tz ); } @@ -128,82 +112,88 @@ double tval() /* Our available solvers. */ // 255 is the magic reserved number, so NEVER try to put 255 solvers in here! // 254 = MAX! -static CM_SOLVER_DEF solvers [] = -{ - { "Implicit", CM_IMPLICIT, implicit_init, implicit_solver, implicit_free }, -}; +static CM_SOLVER_DEF solvers [] = + { + { "Implicit", CM_IMPLICIT, implicit_init, implicit_solver, implicit_free }, + // { "Implicit C++", CM_IMPLICITCPP, implicitcpp_init, implicitcpp_solver, implicitcpp_free }, + }; /* ********** cloth engine ******* */ /* Prototypes for internal functions. */ -static void cloth_to_object (Object *ob, DerivedMesh *dm, ClothModifierData *clmd); -static void cloth_from_mesh (Object *ob, ClothModifierData *clmd, DerivedMesh *dm, float framenr); -static int cloth_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *dm, DerivedMesh *olddm, float framenr); +static void cloth_to_object ( Object *ob, ClothModifierData *clmd, float ( *vertexCos ) [3], unsigned int numverts ); +static void cloth_from_mesh ( Object *ob, ClothModifierData *clmd, DerivedMesh *dm ); +static int cloth_from_object ( Object *ob, ClothModifierData *clmd, DerivedMesh *dm, float ( *vertexCos ) [3], unsigned int numverts, float framenr ); +static int collobj_from_object ( Object *ob, ClothModifierData *clmd, DerivedMesh *dm, float ( *vertexCos ) [3], unsigned int numverts ); +int cloth_build_springs ( Cloth *cloth, DerivedMesh *dm ); +static void cloth_apply_vgroup ( ClothModifierData *clmd, DerivedMesh *dm, short vgroup ); + -int cloth_build_springs ( ClothModifierData *clmd, DerivedMesh *dm ); -static void cloth_apply_vgroup(ClothModifierData *clmd, DerivedMesh *dm, short vgroup); /****************************************************************************** * * External interface called by modifier.c clothModifier functions. * ******************************************************************************/ /** - * cloth_init - creates a new cloth simulation. - * - * 1. create object - * 2. fill object with standard values or with the GUI settings if given - */ -void cloth_init (ClothModifierData *clmd) +* cloth_init - creates a new cloth simulation. +* +* 1. create object +* 2. fill object with standard values or with the GUI settings if given +*/ +void cloth_init ( ClothModifierData *clmd ) { /* Initialize our new data structure to reasonable values. */ - clmd->sim_parms->gravity [0] = 0.0; - clmd->sim_parms->gravity [1] = 0.0; - clmd->sim_parms->gravity [2] = -9.81; - clmd->sim_parms->structural = 100.0; - clmd->sim_parms->shear = 100.0; - clmd->sim_parms->bending = 1.0; - clmd->sim_parms->Cdis = 5.0; - clmd->sim_parms->Cvi = 1.0; - clmd->sim_parms->mass = 1.0f; - clmd->sim_parms->stepsPerFrame = 5; - clmd->sim_parms->sim_time = 1.0; - clmd->sim_parms->flags = CLOTH_SIMSETTINGS_FLAG_RESET; - clmd->sim_parms->solver_type = 0; - clmd->sim_parms->preroll = 0; - clmd->sim_parms->maxspringlen = 10; - clmd->coll_parms->self_friction = 5.0; - clmd->coll_parms->friction = 10.0; - clmd->coll_parms->loop_count = 1; - clmd->coll_parms->epsilon = 0.01; - clmd->coll_parms->selfepsilon = 0.49; - + clmd->sim_parms.gravity [0] = 0.0; + clmd->sim_parms.gravity [1] = 0.0; + clmd->sim_parms.gravity [2] = -9.81; + clmd->sim_parms.structural = 100.0; + clmd->sim_parms.shear = 100.0; + clmd->sim_parms.bending = 1.0; + clmd->sim_parms.Cdis = 5.0; + clmd->sim_parms.Cvi = 1.0; + clmd->sim_parms.mass = 1.0f; + clmd->sim_parms.stepsPerFrame = 5; + clmd->sim_parms.sim_time = 1.0; + clmd->sim_parms.flags = CLOTH_SIMSETTINGS_FLAG_RESET; + clmd->sim_parms.solver_type = 0; + clmd->sim_parms.preroll = 0; + clmd->sim_parms.maxspringlen = 10; + clmd->sim_parms.firstframe = 1; + clmd->sim_parms.lastframe = 250; + clmd->coll_parms.self_friction = 5.0; + clmd->coll_parms.friction = 10.0; + clmd->coll_parms.loop_count = 1; + clmd->coll_parms.epsilon = 0.01f; + clmd->coll_parms.flags = 0; + /* These defaults are copied from softbody.c's * softbody_calc_forces() function. */ - clmd->sim_parms->eff_force_scale = 1000.0; - clmd->sim_parms->eff_wind_scale = 250.0; + clmd->sim_parms.eff_force_scale = 1000.0; + clmd->sim_parms.eff_wind_scale = 250.0; // also from softbodies - clmd->sim_parms->maxgoal = 1.0; - clmd->sim_parms->mingoal = 0.0; - clmd->sim_parms->defgoal = 0.0; - clmd->sim_parms->goalspring = 100.0; - clmd->sim_parms->goalfrict = 0.0; + clmd->sim_parms.maxgoal = 1.0f; + clmd->sim_parms.mingoal = 0.0f; + clmd->sim_parms.defgoal = 0.7f; + clmd->sim_parms.goalspring = 100.0f; + clmd->sim_parms.goalfrict = 0.0f; + + clmd->sim_parms.cache = NULL; } // unused in the moment, cloth needs quads from mesh -DerivedMesh *CDDM_convert_to_triangle(DerivedMesh *dm) +DerivedMesh *CDDM_convert_to_triangle ( DerivedMesh *dm ) { - /* DerivedMesh *result = NULL; int i; - int numverts = dm->getNumVerts(dm); - int numedges = dm->getNumEdges(dm); - int numfaces = dm->getNumFaces(dm); + int numverts = dm->getNumVerts ( dm ); + int numedges = dm->getNumEdges ( dm ); + int numfaces = dm->getNumFaces ( dm ); - MVert *mvert = CDDM_get_verts(dm); - MEdge *medge = CDDM_get_edges(dm); - MFace *mface = CDDM_get_faces(dm); + MVert *mvert = CDDM_get_verts ( dm ); + MEdge *medge = CDDM_get_edges ( dm ); + MFace *mface = CDDM_get_faces ( dm ); MVert *mvert2; MFace *mface2; @@ -215,121 +205,118 @@ DerivedMesh *CDDM_convert_to_triangle(DerivedMesh *dm) float vec1[3], vec2[3], vec3[3], vec4[3], vec5[3]; float mag1=0, mag2=0; - for(i = 0; i < numfaces; i++) + for ( i = 0; i < numfaces; i++ ) { - if(mface[i].v4) - numquads++; - else - numtris++; -} + if ( mface[i].v4 ) + numquads++; + else + numtris++; + } - result = CDDM_from_template(dm, numverts, 0, numtris + 2*numquads); + result = CDDM_from_template ( dm, numverts, 0, numtris + 2*numquads ); - if(!result) - return NULL; + if ( !result ) + return NULL; // do verts - mvert2 = CDDM_get_verts(result); - for(a=0; av1 = mface[a].v2; - mf->v2 = mface[a].v3; - mf->v3 = mface[a].v4; -} - else - { - mf->v1 = mface[a].v1; - mf->v2 = mface[a].v2; - mf->v3 = mface[a].v3; -} + if ( mface[a].v4 && random==1 ) + { + mf->v1 = mface[a].v2; + mf->v2 = mface[a].v3; + mf->v3 = mface[a].v4; + } + else + { + mf->v1 = mface[a].v1; + mf->v2 = mface[a].v2; + mf->v3 = mface[a].v3; + } - mf->v4 = 0; - mf->flag |= ME_SMOOTH; + mf->v4 = 0; + mf->flag |= ME_SMOOTH; - test_index_face(mf, NULL, 0, 3); + test_index_face ( mf, NULL, 0, 3 ); - if(mface[a].v4) - { - MFace *mf2; + if ( mface[a].v4 ) + { + MFace *mf2; - i++; + i++; - mf2 = &mface2[i]; - - // DM_copy_face_data(dm, result, a, i, 1); + mf2 = &mface2[i]; + /* + DM_copy_face_data(dm, result, a, i, 1); - // *mf2 = *inMF; - + *mf2 = *inMF; + */ - if(random==1) - { - mf2->v1 = mface[a].v1; - mf2->v2 = mface[a].v2; - mf2->v3 = mface[a].v4; -} - else - { - mf2->v1 = mface[a].v4; - mf2->v2 = mface[a].v1; - mf2->v3 = mface[a].v3; -} - mf2->v4 = 0; - mf2->flag |= ME_SMOOTH; + if ( random==1 ) + { + mf2->v1 = mface[a].v1; + mf2->v2 = mface[a].v2; + mf2->v3 = mface[a].v4; + } + else + { + mf2->v1 = mface[a].v4; + mf2->v2 = mface[a].v1; + mf2->v3 = mface[a].v3; + } + mf2->v4 = 0; + mf2->flag |= ME_SMOOTH; - test_index_face(mf2, NULL, 0, 3); -} + test_index_face ( mf2, NULL, 0, 3 ); + } - i++; -} + i++; + } - CDDM_calc_edges(result); - CDDM_calc_normals(result); + CDDM_calc_edges ( result ); + CDDM_calc_normals ( result ); return result; - */ - - return NULL; + } -DerivedMesh *CDDM_create_tearing(ClothModifierData *clmd, DerivedMesh *dm) +DerivedMesh *CDDM_create_tearing ( ClothModifierData *clmd, DerivedMesh *dm ) { - /* DerivedMesh *result = NULL; unsigned int i = 0, a = 0, j=0; - int numverts = dm->getNumVerts(dm); - int numedges = dm->getNumEdges(dm); - int numfaces = dm->getNumFaces(dm); + int numverts = dm->getNumVerts ( dm ); + int numedges = dm->getNumEdges ( dm ); + int numfaces = dm->getNumFaces ( dm ); - MVert *mvert = CDDM_get_verts(dm); - MEdge *medge = CDDM_get_edges(dm); - MFace *mface = CDDM_get_faces(dm); + MVert *mvert = CDDM_get_verts ( dm ); + MEdge *medge = CDDM_get_edges ( dm ); + MFace *mface = CDDM_get_faces ( dm ); MVert *mvert2; MFace *mface2; @@ -339,91 +326,90 @@ DerivedMesh *CDDM_create_tearing(ClothModifierData *clmd, DerivedMesh *dm) Cloth *cloth = clmd->clothObject; ClothSpring *springs = cloth->springs; unsigned int numsprings = cloth->numsprings; - + // create spring tearing hash edgehash = BLI_edgehash_new(); - - for(i = 0; i < numsprings; i++) - { - if((springs[i].flags & CSPRING_FLAG_DEACTIVATE) - &&(!BLI_edgehash_haskey(edgehash, springs[i].ij, springs[i].kl))) - { - BLI_edgehash_insert(edgehash, springs[i].ij, springs[i].kl, NULL); - BLI_edgehash_insert(edgehash, springs[i].kl, springs[i].ij, NULL); - j++; -} -} - - // printf("found %d tears\n", j); - - result = CDDM_from_template(dm, numverts, 0, numfaces); - if(!result) - return NULL; + for ( i = 0; i < numsprings; i++ ) + { + if ( ( springs[i].flags & CLOTH_SPRING_FLAG_DEACTIVATE ) + && ( !BLI_edgehash_haskey ( edgehash, springs[i].ij, springs[i].kl ) ) ) + { + BLI_edgehash_insert ( edgehash, springs[i].ij, springs[i].kl, NULL ); + BLI_edgehash_insert ( edgehash, springs[i].kl, springs[i].ij, NULL ); + j++; + } + } + + // printf("found %d tears\n", j); + + result = CDDM_from_template ( dm, numverts, 0, numfaces ); + + if ( !result ) + return NULL; // do verts - mvert2 = CDDM_get_verts(result); - for(a=0; av1 = mface[a].v1; - mf->v2 = mface[a].v2; - mf->v3 = mface[a].v3; - mf->v4 = mface[a].v4; - - test_index_face(mf, NULL, 0, 4); - - i++; -} -} + *mf = *inMF; + */ - CDDM_lower_num_faces(result, i); - CDDM_calc_edges(result); - CDDM_calc_normals(result); - - BLI_edgehash_free(edgehash, NULL); + if ( ( !BLI_edgehash_haskey ( edgehash, mface[a].v1, mface[a].v2 ) ) + && ( !BLI_edgehash_haskey ( edgehash, mface[a].v2, mface[a].v3 ) ) + && ( !BLI_edgehash_haskey ( edgehash, mface[a].v3, mface[a].v4 ) ) + && ( !BLI_edgehash_haskey ( edgehash, mface[a].v4, mface[a].v1 ) ) ) + { + mf->v1 = mface[a].v1; + mf->v2 = mface[a].v2; + mf->v3 = mface[a].v3; + mf->v4 = mface[a].v4; + + test_index_face ( mf, NULL, 0, 4 ); + + i++; + } + } + + CDDM_lower_num_faces ( result, i ); + CDDM_calc_edges ( result ); + CDDM_calc_normals ( result ); + + BLI_edgehash_free ( edgehash, NULL ); return result; - */ - - return NULL; } + + int modifiers_indexInObject(Object *ob, ModifierData *md_seek); void cloth_clear_cache(Object *ob, ClothModifierData *clmd, float framenr) { int stack_index = -1; - if(!(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_CCACHE_PROTECT)) + if(!(clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_CCACHE_PROTECT)) { stack_index = modifiers_indexInObject(ob, (ModifierData *)clmd); @@ -447,9 +433,9 @@ static void cloth_write_cache(Object *ob, ClothModifierData *clmd, float framenr for(a = 0; a < cloth->numverts; a++) { - fwrite(&cloth->x[a], sizeof(float),4,fp); - fwrite(&cloth->xconst[a], sizeof(float),4,fp); - fwrite(&cloth->v[a], sizeof(float),4,fp); + fwrite(&cloth->verts[a].x, sizeof(float),4,fp); + fwrite(&cloth->verts[a].xconst, sizeof(float),4,fp); + fwrite(&cloth->verts[a].v, sizeof(float),4,fp); } fclose(fp); @@ -472,17 +458,17 @@ static int cloth_read_cache(Object *ob, ClothModifierData *clmd, float framenr) else { for(a = 0; a < cloth->numverts; a++) { - if(fread(&cloth->x[a], sizeof(float), 4, fp) != 4) + if(fread(&cloth->verts[a].x, sizeof(float), 4, fp) != 4) { ret = 0; break; } - if(fread(&cloth->xconst[a], sizeof(float), 4, fp) != 4) + if(fread(&cloth->verts[a].xconst, sizeof(float), 4, fp) != 4) { ret = 0; break; } - if(fread(&cloth->v[a], sizeof(float), 4, fp) != 4) + if(fread(&cloth->verts[a].v, sizeof(float), 4, fp) != 4) { ret = 0; break; @@ -492,182 +478,200 @@ static int cloth_read_cache(Object *ob, ClothModifierData *clmd, float framenr) fclose(fp); } - if(clmd->sim_parms->solver_type == 0) + if(clmd->sim_parms.solver_type == 0) implicit_set_positions(clmd); return ret; } -int m_fc_open(ClothModifierData *clmd) -{ - Cloth *cloth = clmd->clothObject; - int _N; - fc *m_fc = NULL; - - if(!cloth) - return 0; - - m_fc = cloth->m_fc; - m_fc->_fp = fopen("/home/daniel/Desktop/f32rand.dat", "rb"); - if (!m_fc->_fp) - return 0; - - fread(&_N, sizeof(int), 1, m_fc->_fp); - fread(&_N, sizeof(int), 1, m_fc->_fp); - printf("Resolution: %dx%dx%d\n", _N, _N, _N); - - fread(&m_fc->_nframes, sizeof(int), 1, m_fc->_fp); - printf("Number of frames: %d\n", m_fc->_nframes); - m_fc->_cur_frame = 0; - - return 1; -} - - - -/************************************************ - * clothModifier_do - main simulation function -************************************************/ -DerivedMesh *clothModifier_do(ClothModifierData *clmd,Object *ob, DerivedMesh *dm, int useRenderParams, int isFinalCalc) +/** +* cloth_deform_verts - simulates one step, framenr is in frames. +* +**/ +void clothModifier_do ( ClothModifierData *clmd, Object *ob, DerivedMesh *dm, + float ( *vertexCos ) [3], int numverts ) { unsigned int i; - unsigned int numverts = -1; unsigned int numedges = -1; unsigned int numfaces = -1; MVert *mvert = NULL; MEdge *medge = NULL; MFace *mface = NULL; - DerivedMesh *result = NULL; + DerivedMesh *result = NULL, *result2 = NULL; Cloth *cloth = clmd->clothObject; - unsigned int framenr = (float)G.scene->r.cfra; - float current_time = bsystem_time(ob, (float)G.scene->r.cfra, 0.0); - ListBase *effectors = NULL; - float deltaTime = current_time - clmd->sim_parms->sim_time; + unsigned int framenr = ( float ) G.scene->r.cfra; + float current_time = bsystem_time ( ob, ( float ) G.scene->r.cfra, 0.0 ); + ListBase *effectors = NULL; + ClothVertex *newframe= NULL, *verts; + Frame *frame = NULL; + LinkNode *search = NULL; + float deltaTime = current_time - clmd->sim_parms.sim_time; + + clmd->sim_parms.ob = ob; - clmd->sim_parms->dt = 1.0f / (clmd->sim_parms->stepsPerFrame * G.scene->r.frs_sec); - result = CDDM_copy(dm); - - if(!result) - { - return dm; - } - - numverts = result->getNumVerts(result); - numedges = result->getNumEdges(result); - numfaces = result->getNumFaces(result); - mvert = CDDM_get_verts(result); - medge = CDDM_get_edges(result); - mface = CDDM_get_faces(result); - - clmd->sim_parms->sim_time = current_time; - - if ( current_time < clmd->sim_parms->firstframe ) - return result; - // only be active during a specific period: // that's "first frame" and "last frame" on GUI /* - if ( clmd->clothObject ) + if ( ! ( clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_COLLOBJ ) ) { - if ( clmd->sim_parms->cache ) - { - if ( current_time < clmd->sim_parms->firstframe ) - { - int frametime = cloth_cache_first_frame ( clmd ); - if ( cloth_cache_search_frame ( clmd, frametime ) ) - { - cloth_cache_get_frame ( clmd, frametime ); - cloth_to_object ( ob, result, clmd ); -} - return result; -} - else if ( current_time > clmd->sim_parms->lastframe ) - { - int frametime = cloth_cache_last_frame ( clmd ); - if ( cloth_cache_search_frame ( clmd, frametime ) ) - { - cloth_cache_get_frame ( clmd, frametime ); - cloth_to_object ( ob, result, clmd ); -} - return result; -} - else if ( ABS ( deltaTime ) >= 2.0f ) // no timewarps allowed - { - if ( cloth_cache_search_frame ( clmd, framenr ) ) - { - cloth_cache_get_frame ( clmd, framenr ); - cloth_to_object ( ob, result, clmd ); -} - clmd->sim_parms->sim_time = current_time; - return result; -} -} -} - */ - - if(deltaTime == 1.0f) - { - if ((clmd->clothObject == NULL) || (numverts != clmd->clothObject->numverts) ) + if ( clmd->clothObject ) { - cloth_clear_cache(ob, clmd, 0); - - if(!cloth_from_object (ob, clmd, result, dm, framenr)) - return result; + if ( clmd->sim_parms.cache ) + { + if ( current_time < clmd->sim_parms.firstframe ) + { + int frametime = cloth_cache_first_frame ( clmd ); + if ( cloth_cache_search_frame ( clmd, frametime ) ) + { + cloth_cache_get_frame ( clmd, frametime ); + cloth_to_object ( ob, clmd, vertexCos, numverts ); + } + return; + } + else if ( current_time > clmd->sim_parms.lastframe ) + { + int frametime = cloth_cache_last_frame ( clmd ); + if ( cloth_cache_search_frame ( clmd, frametime ) ) + { + cloth_cache_get_frame ( clmd, frametime ); + cloth_to_object ( ob, clmd, vertexCos, numverts ); + } + return; + } + else if ( ABS ( deltaTime ) >= 2.0f ) // no timewarps allowed + { + if ( cloth_cache_search_frame ( clmd, framenr ) ) + { + cloth_cache_get_frame ( clmd, framenr ); + cloth_to_object ( ob, clmd, vertexCos, numverts ); + } + clmd->sim_parms.sim_time = current_time; + return; + } + } - if(clmd->clothObject == NULL) - return result; + } + } + */ + + // unused in the moment, calculated seperately in implicit.c + clmd->sim_parms.dt = 1.0f / clmd->sim_parms.stepsPerFrame; + + clmd->sim_parms.sim_time = current_time; + + // check if cloth object was some collision object before and needs freeing now + if ( ! ( clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_COLLOBJ ) && ( clmd->clothObject != NULL ) && ( clmd->clothObject->old_solver_type == 255 ) ) + { + // temporary set CSIMSETT_FLAG_COLLOBJ flag for proper freeing + clmd->sim_parms.flags |= CLOTH_SIMSETTINGS_FLAG_COLLOBJ; + cloth_free_modifier ( clmd ); + clmd->sim_parms.flags &= ~CLOTH_SIMSETTINGS_FLAG_COLLOBJ; + } + + // This is for collisions objects: check special case CSIMSETT_FLAG_COLLOBJ + if ( clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_COLLOBJ ) + { + // save next position + time + if ( ( clmd->clothObject == NULL ) || ( numverts != clmd->clothObject->numverts ) ) + { + if ( !collobj_from_object ( ob, clmd, dm, vertexCos, framenr ) ) + { + clmd->sim_parms.flags |= CLOTH_SIMSETTINGS_FLAG_COLLOBJ; + cloth_free_modifier ( clmd ); + return; + } + + if ( clmd->clothObject == NULL ) + return; cloth = clmd->clothObject; } - /* - deltaTime = 0; - while( deltaTime < 1.0) + + // Save old position + clmd->sim_parms.sim_time_old = clmd->sim_parms.sim_time; + clmd->sim_parms.sim_time = current_time; + + verts = cloth->verts; + + for ( i = 0; i < clmd->clothObject->numverts; i++, verts++ ) { - step(cloth->m_fc, 0.1); - deltaTime+=0.1; + // Save the previous position. + VECCOPY ( verts->xold, verts->x ); + VECCOPY ( verts->txold, verts->x ); + + // Get the current position. + VECCOPY ( verts->x, vertexCos[i] ); + Mat4MulVecfl ( ob->obmat, verts->x ); + + // Compute the vertices "velocity". + // (no dt correction here because of float error) + VECSUB ( verts->v, verts->x, verts->xold ); } - */ - clmd->clothObject->old_solver_type = clmd->sim_parms->solver_type; + + return; + } + + if ( deltaTime == 1.0f ) + { + if ( ( clmd->clothObject == NULL ) || ( numverts != clmd->clothObject->numverts ) ) + { + cloth_clear_cache(ob, clmd, 0); + + if ( !cloth_from_object ( ob, clmd, dm, vertexCos, numverts, framenr ) ) + return; + + if ( clmd->clothObject == NULL ) + return; + + cloth = clmd->clothObject; + } + + clmd->clothObject->old_solver_type = clmd->sim_parms.solver_type; // Insure we have a clmd->clothObject, in case allocation failed. - if (clmd->clothObject != NULL) + if ( clmd->clothObject != NULL ) { if(!cloth_read_cache(ob, clmd, framenr)) { + verts = cloth->verts; + // Force any pinned verts to their constrained location. - // has to be commented for verlet - for ( i = 0; i < clmd->clothObject->numverts; i++ ) + for ( i = 0; i < clmd->clothObject->numverts; i++, verts++ ) { // Save the previous position. - VECCOPY ( cloth->xold[i], cloth->xconst[i] ); - VECCOPY ( cloth->current_xold[i], cloth->x[i] ); + VECCOPY ( verts->xold, verts->xconst ); + VECCOPY ( verts->txold, verts->x ); + // Get the current position. - VECCOPY ( cloth->xconst[i], mvert[i].co ); - Mat4MulVecfl ( ob->obmat, cloth->xconst[i] ); + VECCOPY ( verts->xconst, vertexCos[i] ); + Mat4MulVecfl ( ob->obmat, verts->xconst ); } - + tstart(); - - /* Call the solver. */ - - if (solvers [clmd->sim_parms->solver_type].solver) - solvers [clmd->sim_parms->solver_type].solver (ob, framenr, clmd, effectors); - + + // Call the solver. + if ( solvers [clmd->sim_parms.solver_type].solver ) + solvers [clmd->sim_parms.solver_type].solver ( ob, framenr, clmd, effectors ); + tend(); - - printf("Cloth simulation time: %f\n", tval()); - + printf ( "Cloth simulation time: %f\n", ( float ) tval() ); + cloth_write_cache(ob, clmd, framenr); + + } + else // just retrieve the cached frame + { + cloth_read_cache(ob, clmd, framenr); } // Copy the result back to the object. - cloth_to_object (ob, result, clmd); - + cloth_to_object ( ob, clmd, vertexCos, numverts ); + // bvh_free(clmd->clothObject->tree); - // clmd->clothObject->tree = bvh_build(clmd, clmd->coll_parms->epsilon); - } + // clmd->clothObject->tree = bvh_build(clmd, clmd->coll_parms.epsilon); + } } else if ( ( deltaTime <= 0.0f ) || ( deltaTime > 1.0f ) ) @@ -675,147 +679,85 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd,Object *ob, DerivedMesh *d if ( clmd->clothObject != NULL ) { if(cloth_read_cache(ob, clmd, framenr)) - cloth_to_object (ob, result, clmd); + cloth_to_object ( ob, clmd, vertexCos, numverts ); } else { cloth_clear_cache(ob, clmd, 0); } } - - cloth = clmd->clothObject; - /* - if(cloth) - { - if (_texture_data == NULL) - _texture_data = (unsigned char*) malloc((30+2)*(30+2)*(30+2)*4); - - for (i=0; i<(30+2)*(30+2)*(30+2); i++) { - _texture_data[(i<<2)] = (unsigned char) (cloth->m_fc->T[i] * 255.0f); - _texture_data[(i<<2)+1] = (unsigned char) (cloth->m_fc->d[i] * 255.0f); - _texture_data[(i<<2)+2] = 0; - _texture_data[(i<<2)+3] = 255; - } - - // from ligth constructor - _light_dir[0] = -1.0f; - _light_dir[1] = 0.5f; - _light_dir[2] = 0.0f; - - gen_ray_templ(_ray_templ, _light_dir, 30 + 2); - - cast_light(_texture_data, _ray_templ, _light_dir, 30+2); - - glActiveTextureARB(GL_TEXTURE0_ARB); - glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA, 30+2, 30+2, 30+2, 0, GL_RGBA, GL_UNSIGNED_BYTE, _texture_data); - free(_texture_data); - } - */ - return result; + } /* frees all */ -void cloth_free_modifier (ClothModifierData *clmd) +void cloth_free_modifier ( ClothModifierData *clmd ) { Cloth *cloth = NULL; - - if(!clmd) + Object *ob = clmd->sim_parms.ob; + + if ( !clmd ) return; cloth = clmd->clothObject; - // free our frame cache - // cloth_clear_cache(ob, clmd, 0); - - /* Calls the solver and collision frees first as they - * might depend on data in clmd->clothObject. */ - - if (cloth) - { - f_free(cloth->m_fc); - - // If our solver provides a free function, call it - if (cloth->old_solver_type < 255 && solvers [cloth->old_solver_type].free) - { - solvers [cloth->old_solver_type].free (clmd); - } - - // Free the verts. - if (cloth->verts != NULL) - MEM_freeN (cloth->verts); - - // Free the faces. - if ( cloth->mfaces != NULL ) - MEM_freeN ( cloth->mfaces ); - - // Free the verts. - if ( cloth->x != NULL ) - MEM_freeN ( cloth->x ); - - // Free the verts. - if ( cloth->xold != NULL ) - MEM_freeN ( cloth->xold ); - - // Free the verts. - if ( cloth->v != NULL ) - MEM_freeN ( cloth->v ); - - // Free the verts. - if ( cloth->current_x != NULL ) - MEM_freeN ( cloth->current_x ); - - // Free the verts. - if ( cloth->current_xold != NULL ) - MEM_freeN ( cloth->current_xold ); - - // Free the verts. - if ( cloth->current_v != NULL ) - MEM_freeN ( cloth->current_v ); - - // Free the verts. - if ( cloth->xconst != NULL ) - MEM_freeN ( cloth->xconst ); - - cloth->verts = NULL; - cloth->numverts = -1; - - // Free the springs. - if ( cloth->springs != NULL ) + if ( ! ( clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_CCACHE_PROTECT ) ) + { + if ( cloth ) { - LinkNode *search = cloth->springs; - while(search) + // free our frame cache, TODO: but get to first position before + if(ob) + cloth_clear_cache ( ob, clmd, 0 ); + + // If our solver provides a free function, call it + if ( cloth->old_solver_type < 255 && solvers [cloth->old_solver_type].free ) { - ClothSpring *spring = search->link; - - MEM_freeN ( spring ); - search = search->next; + solvers [cloth->old_solver_type].free ( clmd ); } - BLI_linklist_free(cloth->springs, NULL); - + + // Free the verts. + if ( cloth->verts != NULL ) + MEM_freeN ( cloth->verts ); + + cloth->verts = NULL; + cloth->numverts = 0; + + // Free the springs. + if ( cloth->springs != NULL ) + { + LinkNode *search = cloth->springs; + while(search) + { + ClothSpring *spring = search->link; + + MEM_freeN ( spring ); + search = search->next; + } + BLI_linklist_free(cloth->springs, NULL); + + cloth->springs = NULL; + } + cloth->springs = NULL; + cloth->numsprings = 0; + + // free BVH collision tree + if ( cloth->tree ) + bvh_free ( ( BVH * ) cloth->tree ); + + // we save our faces for collision objects + if ( cloth->mfaces ) + MEM_freeN ( cloth->mfaces ); + /* + if(clmd->clothObject->facemarks) + MEM_freeN(clmd->clothObject->facemarks); + */ + MEM_freeN ( cloth ); + clmd->clothObject = NULL; } - - cloth->numsprings = -1; - - // free BVH collision tree - if(cloth->tree) - bvh_free((BVH *)cloth->tree); - - // free BVH self collision tree - if(cloth->selftree) - bvh_free((BVH *)cloth->selftree); - - if(cloth->edgehash) - BLI_edgehash_free ( cloth->edgehash, NULL ); - - MEM_freeN (cloth); - clmd->clothObject = NULL; } - } - /****************************************************************************** * * Internal functions. @@ -823,44 +765,42 @@ void cloth_free_modifier (ClothModifierData *clmd) ******************************************************************************/ /** - * cloth_to_object - copies the deformed vertices to the object. - * - * This function is a modified version of the softbody.c:softbody_to_object() function. - **/ -static void cloth_to_object (Object *ob, DerivedMesh *dm, ClothModifierData *clmd) +* cloth_to_object - copies the deformed vertices to the object. +* +* This function is a modified version of the softbody.c:softbody_to_object() function. +**/ +static void cloth_to_object ( Object *ob, ClothModifierData *clmd, float ( *vertexCos ) [3], unsigned int numverts ) { + ClothVertex *verts = NULL; unsigned int i = 0; - MVert *mvert = NULL; - unsigned int numverts; - Cloth *cloth = clmd->clothObject; - if (clmd->clothObject) { + if ( clmd->clothObject ) + { + verts = clmd->clothObject->verts; + /* inverse matrix is not uptodate... */ - Mat4Invert (ob->imat, ob->obmat); + Mat4Invert ( ob->imat, ob->obmat ); - mvert = CDDM_get_verts(dm); - numverts = dm->getNumVerts(dm); - - for (i = 0; i < numverts; i++) + for ( i = 0; i < numverts; i++, verts++ ) { - VECCOPY (mvert[i].co, cloth->x[i]); - Mat4MulVecfl (ob->imat, mvert[i].co); /* cloth is in global coords */ + VECCOPY ( vertexCos[i], verts->x ); + Mat4MulVecfl ( ob->imat, vertexCos[i] ); /* softbody is in global coords */ } } } /** - * cloth_apply_vgroup - applies a vertex group as specified by type - * - **/ -static void cloth_apply_vgroup(ClothModifierData *clmd, DerivedMesh *dm, short vgroup) +* cloth_apply_vgroup - applies a vertex group as specified by type +* +**/ +static void cloth_apply_vgroup ( ClothModifierData *clmd, DerivedMesh *dm, short vgroup ) { unsigned int i = 0; unsigned int j = 0; - MDeformVert *dvert = NULL; + MDeformVert *dvert = NULL; Cloth *clothObj = NULL; - unsigned int numverts = 0; + unsigned int numverts = dm->getNumVerts ( dm ); float goalfac = 0; ClothVertex *verts = NULL; @@ -869,7 +809,7 @@ static void cloth_apply_vgroup(ClothModifierData *clmd, DerivedMesh *dm, short v if ( !dm ) return; - numverts = dm->getNumVerts(dm); + numverts = dm->getNumVerts ( dm ); /* vgroup is 1 based, decrement so we can match the right group. */ --vgroup; @@ -879,7 +819,7 @@ static void cloth_apply_vgroup(ClothModifierData *clmd, DerivedMesh *dm, short v for ( i = 0; i < numverts; i++, verts++ ) { // LATER ON, support also mass painting here - if ( clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL ) + if ( clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_GOAL ) { dvert = dm->getVertData ( dm, i, CD_MDEFORMVERT ); if ( dvert ) @@ -890,7 +830,7 @@ static void cloth_apply_vgroup(ClothModifierData *clmd, DerivedMesh *dm, short v { verts->goal = dvert->dw [j].weight; - goalfac= ABS ( clmd->sim_parms->maxgoal - clmd->sim_parms->mingoal ); + goalfac= ABS ( clmd->sim_parms.maxgoal - clmd->sim_parms.mingoal ); verts->goal = ( float ) pow ( verts->goal , 4.0f ); if ( dvert->dw [j].weight >=SOFTGOALSNAP ) @@ -907,194 +847,226 @@ static void cloth_apply_vgroup(ClothModifierData *clmd, DerivedMesh *dm, short v } } } - + // only meshes supported at the moment -static int cloth_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *dm, DerivedMesh *olddm, float framenr) +/* collision objects */ +static int collobj_from_object ( Object *ob, ClothModifierData *clmd, DerivedMesh *dm, float ( *vertexCos ) [3], unsigned int numverts ) { unsigned int i; - unsigned int numverts = dm->getNumVerts(dm); - MVert *mvert = CDDM_get_verts(dm); + MVert *mvert = NULL; + ClothVertex *verts = NULL; float tnull[3] = {0,0,0}; - Cloth *cloth = NULL; - + /* If we have a clothObject, free it. */ - if (clmd->clothObject != NULL) - cloth_free_modifier (clmd); + if ( clmd->clothObject != NULL ) + cloth_free_modifier ( clmd ); /* Allocate a new cloth object. */ - clmd->clothObject = MEM_callocN (sizeof(Cloth), "cloth"); - if (clmd->clothObject) + clmd->clothObject = MEM_callocN ( sizeof ( Cloth ), "cloth" ); + if ( clmd->clothObject ) { clmd->clothObject->old_solver_type = 255; - clmd->clothObject->edgehash = NULL; + // clmd->clothObject->old_collision_type = 255; } - else if (clmd->clothObject == NULL) + else if ( clmd->clothObject == NULL ) { - modifier_setError (&(clmd->modifier), "Out of memory on allocating clmd->clothObject."); + modifier_setError ( & ( clmd->modifier ), "Out of memory on allocating clmd->clothObject." ); return 0; } - - cloth = clmd->clothObject; - - cloth->m_fc = f_init(); - // open file - m_fc_open(clmd); - - switch (ob->type) + switch ( ob->type ) { case OB_MESH: - + // mesh input objects need DerivedMesh if ( !dm ) return 0; - cloth_from_mesh (ob, clmd, dm, framenr); + cloth_from_mesh ( ob, clmd, dm ); + + if ( clmd->clothObject != NULL ) + { + if ( !dm ) return 0; + if ( !dm->getNumVerts ( dm ) || !dm->getNumFaces ( dm ) ) return 0; + + mvert = dm->getVertArray ( dm ); + verts = clmd->clothObject->verts; + numverts = clmd->clothObject->numverts = dm->getNumVerts ( dm ); + + for ( i = 0; i < numverts; i++, verts++ ) + { + VECCOPY ( verts->x, mvert[i].co ); + Mat4MulVecfl ( ob->obmat, verts->x ); + verts->flags = 0; + VECCOPY ( verts->xold, verts->x ); + VECCOPY ( verts->txold, verts->x ); + VECCOPY ( verts->tx, verts->x ); + VecMulf ( verts->v, 0.0f ); + verts->impulse_count = 0; + VECCOPY ( verts->impulse, tnull ); + } + clmd->clothObject->tree = bvh_build ( clmd,clmd->coll_parms.epsilon ); + + } + + return 1; + default: return 0; // TODO - we do not support changing meshes + } +} + +/* +helper function to get proper spring length +when object is rescaled +*/ +float cloth_globallen ( float *v1,float *v2,Object *ob ) +{ + float p1[3],p2[3]; + VECCOPY ( p1,v1 ); + Mat4MulVecfl ( ob->obmat, p1 ); + VECCOPY ( p2,v2 ); + Mat4MulVecfl ( ob->obmat, p2 ); + return VecLenf ( p1,p2 ); +} + +// only meshes supported at the moment +static int cloth_from_object ( Object *ob, ClothModifierData *clmd, DerivedMesh *dm, float ( *vertexCos ) [3], unsigned int numverts, float framenr ) +{ + unsigned int i = 0; + // dm->getNumVerts(dm); + MVert *mvert = NULL; // CDDM_get_verts(dm); + ClothVertex *verts = NULL; + float tnull[3] = {0,0,0}; + + /* If we have a clothObject, free it. */ + if ( clmd->clothObject != NULL ) + cloth_free_modifier ( clmd ); + + /* Allocate a new cloth object. */ + clmd->clothObject = MEM_callocN ( sizeof ( Cloth ), "cloth" ); + if ( clmd->clothObject ) + { + clmd->clothObject->old_solver_type = 255; + // clmd->clothObject->old_collision_type = 255; + } + else if ( !clmd->clothObject ) + { + modifier_setError ( & ( clmd->modifier ), "Out of memory on allocating clmd->clothObject." ); + return 0; + } + + clmd->sim_parms.ob = ob; + + switch ( ob->type ) + { + case OB_MESH: + + // mesh input objects need DerivedMesh + if ( !dm ) + return 0; + + cloth_from_mesh ( ob, clmd, dm ); if ( clmd->clothObject != NULL ) { /* create springs */ clmd->clothObject->springs = NULL; clmd->clothObject->numsprings = -1; - + + mvert = CDDM_get_verts ( dm ); + verts = clmd->clothObject->verts; + /* set initial values */ - for (i = 0; i < numverts; ++i) + for ( i = 0; i < numverts; i++, verts++ ) { - VECCOPY (clmd->clothObject->x[i], mvert[i].co); - Mat4MulVecfl(ob->obmat, clmd->clothObject->x[i]); - - clmd->clothObject->verts [i].mass = clmd->sim_parms->mass; - if ( clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL ) - clmd->clothObject->verts [i].goal= clmd->sim_parms->defgoal; + VECCOPY ( verts->x, mvert[i].co ); + Mat4MulVecfl ( ob->obmat, verts->x ); + + verts->mass = clmd->sim_parms.mass; + + if ( clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_GOAL ) + verts->goal= clmd->sim_parms.defgoal; else - clmd->clothObject->verts [i].goal= 0.0; - clmd->clothObject->verts [i].flags = 0; - VECCOPY(clmd->clothObject->xold[i], clmd->clothObject->x[i]); - VECCOPY(clmd->clothObject->xconst[i], clmd->clothObject->x[i]); - VECCOPY(clmd->clothObject->current_xold[i], clmd->clothObject->x[i]); - VecMulf(clmd->clothObject->v[i], 0.0); - - clmd->clothObject->verts [i].impulse_count = 0; - VECCOPY ( clmd->clothObject->verts [i].impulse, tnull ); + verts->goal= 0.0f; + + verts->flags = 0; + VECCOPY ( verts->xold, verts->x ); + VECCOPY ( verts->xconst, verts->x ); + VECCOPY ( verts->txold, verts->x ); + VecMulf ( verts->v, 0.0f ); + + verts->impulse_count = 0; + VECCOPY ( verts->impulse, tnull ); } - if (!cloth_build_springs (clmd, dm) ) + if ( !cloth_build_springs ( clmd->clothObject, dm ) ) { - modifier_setError (&(clmd->modifier), "Can't build springs."); + modifier_setError ( & ( clmd->modifier ), "Can't build springs." ); return 0; - } - - /* apply / set vertex groups */ - if (clmd->sim_parms->vgroup_mass > 0) - cloth_apply_vgroup (clmd, olddm, clmd->sim_parms->vgroup_mass); - - /* init our solver */ - if (solvers [clmd->sim_parms->solver_type].init) - solvers [clmd->sim_parms->solver_type].init (ob, clmd); - - clmd->clothObject->tree = bvh_build_from_float3(CDDM_get_faces(dm), dm->getNumFaces(dm), clmd->clothObject->x, numverts, clmd->coll_parms->epsilon); - - clmd->clothObject->selftree = bvh_build_from_float3(NULL, 0, clmd->clothObject->x, numverts, clmd->coll_parms->selfepsilon); - - // save initial state + } + + // apply / set vertex groups + if ( clmd->sim_parms.vgroup_mass > 0 ) + cloth_apply_vgroup ( clmd, dm, clmd->sim_parms.vgroup_mass ); + + // init our solver + if ( solvers [clmd->sim_parms.solver_type].init ) + solvers [clmd->sim_parms.solver_type].init ( ob, clmd ); + + clmd->clothObject->tree = bvh_build ( clmd, clmd->coll_parms.epsilon ); + cloth_write_cache(ob, clmd, framenr-1); } + return 1; - default: return 0; // TODO - we do not support changing meshes + case OB_LATTICE: + printf ( "Not supported: OB_LATTICE\n" ); + // lattice_to_softbody(ob); + return 1; + case OB_CURVE: + case OB_SURF: + printf ( "Not supported: OB_SURF| OB_CURVE\n" ); + return 1; + default: return 0; // TODO - we do not support changing meshes } - + return 0; } -static void cloth_from_mesh (Object *ob, ClothModifierData *clmd, DerivedMesh *dm, float framenr) +static void cloth_from_mesh ( Object *ob, ClothModifierData *clmd, DerivedMesh *dm ) { - unsigned int numverts = dm->getNumVerts(dm); - unsigned int numfaces = dm->getNumFaces(dm); - MFace *mface = CDDM_get_faces(dm); + unsigned int numverts = dm->getNumVerts ( dm ); + unsigned int numfaces = dm->getNumFaces ( dm ); + MFace *mface = dm->getFaceArray ( dm ); + unsigned int i = 0; /* Allocate our vertices. */ clmd->clothObject->numverts = numverts; - clmd->clothObject->verts = MEM_callocN (sizeof (ClothVertex) * clmd->clothObject->numverts, "clothVertex"); - if (clmd->clothObject->verts == NULL) - { - cloth_free_modifier (clmd); - modifier_setError (&(clmd->modifier), "Out of memory on allocating clmd->clothObject->verts."); - return; - } - - clmd->clothObject->x = MEM_callocN ( sizeof ( float ) * clmd->clothObject->numverts * 4, "Cloth MVert_x" ); - if ( clmd->clothObject->x == NULL ) + clmd->clothObject->verts = MEM_callocN ( sizeof ( ClothVertex ) * clmd->clothObject->numverts, "clothVertex" ); + if ( clmd->clothObject->verts == NULL ) { cloth_free_modifier ( clmd ); - modifier_setError ( & ( clmd->modifier ), "Out of memory on allocating clmd->clothObject->x." ); - return; - } - - clmd->clothObject->xold = MEM_callocN ( sizeof ( float ) * clmd->clothObject->numverts * 4, "Cloth MVert_xold" ); - if ( clmd->clothObject->xold == NULL ) - { - cloth_free_modifier ( clmd ); - modifier_setError ( & ( clmd->modifier ), "Out of memory on allocating clmd->clothObject->xold." ); - return; - } - - clmd->clothObject->v = MEM_callocN ( sizeof ( float ) * clmd->clothObject->numverts * 4, "Cloth MVert_v" ); - if ( clmd->clothObject->v == NULL ) - { - cloth_free_modifier ( clmd ); - modifier_setError ( & ( clmd->modifier ), "Out of memory on allocating clmd->clothObject->v." ); - return; - } - - clmd->clothObject->current_x = MEM_callocN ( sizeof ( float ) * clmd->clothObject->numverts * 4, "Cloth MVert_current_x" ); - if ( clmd->clothObject->current_x == NULL ) - { - cloth_free_modifier ( clmd ); - modifier_setError ( & ( clmd->modifier ), "Out of memory on allocating clmd->clothObject->current_x." ); - return; - } - - clmd->clothObject->current_xold = MEM_callocN ( sizeof ( float ) * clmd->clothObject->numverts * 4, "Cloth MVert_current_xold" ); - if ( clmd->clothObject->current_xold == NULL ) - { - cloth_free_modifier ( clmd ); - modifier_setError ( & ( clmd->modifier ), "Out of memory on allocating clmd->clothObject->current_xold." ); - return; - } - - clmd->clothObject->current_v = MEM_callocN ( sizeof ( float ) * clmd->clothObject->numverts * 4, "Cloth MVert_current_v" ); - if ( clmd->clothObject->current_v == NULL ) - { - cloth_free_modifier ( clmd ); - modifier_setError ( & ( clmd->modifier ), "Out of memory on allocating clmd->clothObject->current_v." ); - return; - } - - clmd->clothObject->xconst = MEM_callocN ( sizeof ( float ) * clmd->clothObject->numverts * 4, "Cloth MVert_xconst" ); - if ( clmd->clothObject->xconst == NULL ) - { - cloth_free_modifier ( clmd ); - modifier_setError ( & ( clmd->modifier ), "Out of memory on allocating clmd->clothObject->xconst." ); + modifier_setError ( & ( clmd->modifier ), "Out of memory on allocating clmd->clothObject->verts." ); return; } // save face information clmd->clothObject->numfaces = numfaces; - clmd->clothObject->mfaces = MEM_callocN (sizeof (MFace) * clmd->clothObject->numfaces, "clothMFaces"); - if (clmd->clothObject->mfaces == NULL) + clmd->clothObject->mfaces = MEM_callocN ( sizeof ( MFace ) * clmd->clothObject->numfaces, "clothMFaces" ); + if ( clmd->clothObject->mfaces == NULL ) { - cloth_free_modifier (clmd); - modifier_setError (&(clmd->modifier), "Out of memory on allocating clmd->clothObject->mfaces."); + cloth_free_modifier ( clmd ); + modifier_setError ( & ( clmd->modifier ), "Out of memory on allocating clmd->clothObject->mfaces." ); return; } - memcpy(clmd->clothObject->mfaces, mface, sizeof(MFace)*numfaces); + for ( i = 0; i < numfaces; i++ ) + memcpy ( &clmd->clothObject->mfaces[i], &mface[i], sizeof ( MFace ) ); /* Free the springs since they can't be correct if the vertices * changed. */ - if (clmd->clothObject->springs != NULL) - MEM_freeN (clmd->clothObject->springs); + if ( clmd->clothObject->springs != NULL ) + MEM_freeN ( clmd->clothObject->springs ); } @@ -1103,7 +1075,6 @@ static void cloth_from_mesh (Object *ob, ClothModifierData *clmd, DerivedMesh *d ***************************************************************************************/ // be carefull: implicit solver has to be resettet when using this one! -// --> only for implicit handling of this spring! int cloth_add_spring ( ClothModifierData *clmd, unsigned int indexA, unsigned int indexB, float restlength, int spring_type) { Cloth *cloth = clmd->clothObject; @@ -1130,12 +1101,11 @@ int cloth_add_spring ( ClothModifierData *clmd, unsigned int indexA, unsigned in return 0; } -int cloth_build_springs ( ClothModifierData *clmd, DerivedMesh *dm ) +int cloth_build_springs ( Cloth *cloth, DerivedMesh *dm ) { - Cloth *cloth = clmd->clothObject; ClothSpring *spring = NULL, *tspring = NULL, *tspring2 = NULL; unsigned int struct_springs = 0, shear_springs=0, bend_springs = 0; - unsigned int i = 0, j = 0, akku_count; + unsigned int i = 0; unsigned int numverts = dm->getNumVerts ( dm ); unsigned int numedges = dm->getNumEdges ( dm ); unsigned int numfaces = dm->getNumFaces ( dm ); @@ -1145,9 +1115,9 @@ int cloth_build_springs ( ClothModifierData *clmd, DerivedMesh *dm ) LinkNode **edgelist = NULL; EdgeHash *edgehash = NULL; LinkNode *search = NULL, *search2 = NULL; - float temp[3], akku, min, max; - LinkNode *node = NULL, *node2 = NULL; - + float temp[3]; + ClothVertex *verts = NULL; + // error handling if ( numedges==0 ) return 0; @@ -1162,6 +1132,8 @@ int cloth_build_springs ( ClothModifierData *clmd, DerivedMesh *dm ) if ( cloth->springs ) MEM_freeN ( cloth->springs ); + + verts = cloth->verts; // create spring network hash edgehash = BLI_edgehash_new(); @@ -1175,54 +1147,16 @@ int cloth_build_springs ( ClothModifierData *clmd, DerivedMesh *dm ) { spring->ij = medge[i].v1; spring->kl = medge[i].v2; - VECSUB ( temp, cloth->x[spring->kl], cloth->x[spring->ij] ); + VECSUB ( temp, verts[spring->kl].x, verts[spring->ij].x ); spring->restlen = sqrt ( INPR ( temp, temp ) ); spring->type = CLOTH_SPRING_TYPE_STRUCTURAL; spring->flags = 0; struct_springs++; - - if(!i) - node2 = BLI_linklist_append_fast ( &cloth->springs, spring ); - else - node2 = BLI_linklist_append_fast ( &node->next, spring ); - node = node2; - } - } - - // calc collision balls *slow* - // better: use precalculated list with O(1) index access to all springs of a vertex - // missing for structural since it's not needed for building bending springs - for ( i = 0; i < numverts; i++ ) - { - akku_count = 0; - akku = 0.0; - cloth->verts[i].collball=0; - min = 1e22f; - max = -1e22f; - - search = cloth->springs; - for ( j = 0; j < struct_springs; j++ ) - { - if ( !search ) - break; - tspring = search->link; - - if((tspring->ij == i) || (tspring->kl == i)) - { - akku += spring->restlen; - akku_count++; - min = MIN2(spring->restlen,min); - max = MAX2(spring->restlen,max); - } + BLI_linklist_append ( &cloth->springs, spring ); } - - if (akku_count > 0) { - cloth->verts[i].collball = akku/(float)akku_count*clmd->coll_parms->selfepsilon; - } - else cloth->verts[i].collball=0; } - + // shear springs for ( i = 0; i < numfaces; i++ ) { @@ -1230,7 +1164,7 @@ int cloth_build_springs ( ClothModifierData *clmd, DerivedMesh *dm ) spring->ij = mface[i].v1; spring->kl = mface[i].v3; - VECSUB ( temp, cloth->x[spring->kl], cloth->x[spring->ij] ); + VECSUB ( temp, verts[spring->kl].x, verts[spring->ij].x ); spring->restlen = sqrt ( INPR ( temp, temp ) ); spring->type = CLOTH_SPRING_TYPE_SHEAR; @@ -1238,8 +1172,7 @@ int cloth_build_springs ( ClothModifierData *clmd, DerivedMesh *dm ) BLI_linklist_append ( &edgelist[spring->kl], spring ); shear_springs++; - node2 = BLI_linklist_append_fast ( &node->next, spring ); - node = node2; + BLI_linklist_append ( &cloth->springs, spring ); if ( mface[i].v4 ) { @@ -1247,19 +1180,18 @@ int cloth_build_springs ( ClothModifierData *clmd, DerivedMesh *dm ) spring->ij = mface[i].v2; spring->kl = mface[i].v4; - VECSUB ( temp, cloth->x[spring->kl], cloth->x[spring->ij] ); - spring->restlen = sqrt ( INPR ( temp, temp ) ); - spring->type = CLOTH_SPRING_TYPE_SHEAR; + VECSUB ( temp, verts[spring->kl].x, verts[spring->ij].x ); + spring->restlen = sqrt ( INPR ( temp, temp ) ); + spring->type = CLOTH_SPRING_TYPE_SHEAR; - BLI_linklist_append ( &edgelist[spring->ij], spring ); - BLI_linklist_append ( &edgelist[spring->kl], spring ); - shear_springs++; + BLI_linklist_append ( &edgelist[spring->ij], spring ); + BLI_linklist_append ( &edgelist[spring->kl], spring ); + shear_springs++; - node2 = BLI_linklist_append_fast ( &node->next, spring ); - node = node2; + BLI_linklist_append ( &cloth->springs, spring ); } } - + // bending springs search2 = cloth->springs; for ( i = struct_springs; i < struct_springs+shear_springs; i++ ) @@ -1277,38 +1209,36 @@ int cloth_build_springs ( ClothModifierData *clmd, DerivedMesh *dm ) // check for existing spring // check also if startpoint is equal to endpoint if ( !BLI_edgehash_haskey ( edgehash, index2, tspring2->ij ) - && !BLI_edgehash_haskey ( edgehash, tspring2->ij, index2 ) - && ( index2!=tspring2->ij ) ) + && !BLI_edgehash_haskey ( edgehash, tspring2->ij, index2 ) + && ( index2!=tspring2->ij ) ) { spring = ( ClothSpring * ) MEM_callocN ( sizeof ( ClothSpring ), "cloth spring" ); spring->ij = tspring2->ij; spring->kl = index2; - VECSUB ( temp, cloth->x[index2], cloth->x[tspring2->ij] ); + VECSUB ( temp, verts[index2].x, verts[tspring2->ij].x ); spring->restlen = sqrt ( INPR ( temp, temp ) ); spring->type = CLOTH_SPRING_TYPE_BENDING; BLI_edgehash_insert ( edgehash, spring->ij, index2, NULL ); bend_springs++; - node2 = BLI_linklist_append_fast ( &node->next, spring ); - node = node2; + BLI_linklist_append ( &cloth->springs, spring ); } search = search->next; } search2 = search2->next; } - - cloth->numspringssave = cloth->numsprings = struct_springs + shear_springs + bend_springs; - cloth->numothersprings = struct_springs + shear_springs; - + + cloth->numsprings = struct_springs + shear_springs + bend_springs; + for ( i = 0; i < numverts; i++ ) { BLI_linklist_free ( edgelist[i],NULL ); } if ( edgelist ) MEM_freeN ( edgelist ); - - cloth->edgehash = edgehash; + + BLI_edgehash_free ( edgehash, NULL ); return 1; @@ -1317,344 +1247,3 @@ int cloth_build_springs ( ClothModifierData *clmd, DerivedMesh *dm ) * SPRING NETWORK BUILDING IMPLEMENTATION END ***************************************************************************************/ -#define F_ITER 20 -#define m_diffusion 0.00001f -#define m_viscosity 0.000f -#define m_buoyancy 1.5f -#define m_cooling 1.0f -#define m_vc_eps 4.0f - -#define GRID_SIZE 30 -#define SIZE ((GRID_SIZE+2)*(GRID_SIZE+2)*(GRID_SIZE+2)) -#define _I(x,y,z) (((z)<<10)+((y)<<5)+x) - -#define SWAPFPTR(x,y) {float *t=x;x=y;y=t;} - -float buffers[10][SIZE]; -float sd[SIZE], su[SIZE], sv[SIZE], sw[SIZE], sT[SIZE]; - - -// nothing to do in this mode -// add code for 2nd mode -void set_bnd(int b, float* x, int N) -{ -} - -void lin_solve(int b, float *x, float *x0, float a, float c, int N) -{ - float cRecip = 1.0 / c; - int i, j, k, l; - for (l=0; lN+0.5) xx=N+0.5f; i0=(int)xx; i1=i0+1; - if (yy<0.5) yy=0.5f; if (yy>N+0.5) yy=N+0.5f; j0=(int)yy; j1=j0+1; - if (zz<0.5) zz=0.5f; if (zz>N+0.5) zz=N+0.5f; k0=(int)zz; k1=k0+1; - sx1 = xx-i0; sx0 = 1-sx1; - sy1 = yy-j0; sy0 = 1-sy1; - sz1 = zz-k0; sz0 = 1-sz1; - v0 = sx0*(sy0*x0[_I(i0,j0,k0)]+sy1*x0[_I(i0,j1,k0)])+sx1*(sy0*x0[_I(i1,j0,k0)]+sy1*x0[_I(i1,j1,k0)]); - v1 = sx0*(sy0*x0[_I(i0,j0,k1)]+sy1*x0[_I(i0,j1,k1)])+sx1*(sy0*x0[_I(i1,j0,k1)]+sy1*x0[_I(i1,j1,k1)]); - x[_I(i,j,k)] = sz0*v0 + sz1*v1; - } - } - } - set_bnd(b,x, N); -} - -void advect_cool(int b, float* x0, float* x, float* y0, float* y, float* uu, float* vv, float* ww, float dt, float cooling, int N) -{ - int i, j, k, i0, j0, k0, i1, j1, k1; - float sx0, sx1, sy0, sy1, sz0, sz1, v0, v1; - float xx, yy, zz, dt0, c0; - dt0 = dt*N; - c0 = 1.0f - cooling*dt; - for (k=1; k<=N; k++) - { - for (j=1; j<=N; j++) - { - for (i=1; i<=N; i++) - { - xx = i-dt0*uu[_I(i,j,k)]; - yy = j-dt0*vv[_I(i,j,k)]; - zz = k-dt0*ww[_I(i,j,k)]; - if (xx<0.5) xx=0.5f; if (xx>N+0.5) xx=N+0.5f; i0=(int)xx; i1=i0+1; - if (yy<0.5) yy=0.5f; if (yy>N+0.5) yy=N+0.5f; j0=(int)yy; j1=j0+1; - if (zz<0.5) zz=0.5f; if (zz>N+0.5) zz=N+0.5f; k0=(int)zz; k1=k0+1; - sx1 = xx-i0; sx0 = 1-sx1; - sy1 = yy-j0; sy0 = 1-sy1; - sz1 = zz-k0; sz0 = 1-sz1; - v0 = sx0*(sy0*x0[_I(i0,j0,k0)]+sy1*x0[_I(i0,j1,k0)])+sx1*(sy0*x0[_I(i1,j0,k0)]+sy1*x0[_I(i1,j1,k0)]); - v1 = sx0*(sy0*x0[_I(i0,j0,k1)]+sy1*x0[_I(i0,j1,k1)])+sx1*(sy0*x0[_I(i1,j0,k1)]+sy1*x0[_I(i1,j1,k1)]); - x[_I(i,j,k)] = sz0*v0 + sz1*v1; - v0 = sx0*(sy0*y0[_I(i0,j0,k0)]+sy1*y0[_I(i0,j1,k0)])+sx1*(sy0*y0[_I(i1,j0,k0)]+sy1*y0[_I(i1,j1,k0)]); - v1 = sx0*(sy0*y0[_I(i0,j0,k1)]+sy1*y0[_I(i0,j1,k1)])+sx1*(sy0*y0[_I(i1,j0,k1)]+sy1*y0[_I(i1,j1,k1)]); - y[_I(i,j,k)] = (sz0*v0 + sz1*v1)*c0; - } - } - } - set_bnd(b,x, N); - set_bnd(b,y, N); -} - -void fproject(float* u, float* u0, float* v, float* v0, float* w, float* w0, int N) -{ - float* p = u0; float* div = v0; // temporary buffers, use old velocity buffers - int i, j, k; - float h; - h = 1.0f/N; - for (k=1; k<=N; k++) { - for (j=1; j<=N; j++) { - for (i=1; i<=N; i++) { - div[_I(i,j,k)] = -h*( - u[_I(i+1,j,k)]-u[_I(i-1,j,k)]+ - v[_I(i,j+1,k)]-v[_I(i,j-1,k)]+ - w[_I(i,j,k+1)]-w[_I(i,j,k-1)])*0.5; - p[_I(i,j,k)] = 0; - } - } - } - set_bnd(0, div, N); - set_bnd(0, p, N); - lin_solve(0, p, div, 1, 6, N); - - for (k=1; k<=N; k++) { - for (j=1; j<=N; j++) { - for (i=1; i<=N; i++) { - u[_I(i,j,k)] -= (p[_I(i+1,j,k)]-p[_I(i-1,j,k)])*0.5*N; - v[_I(i,j,k)] -= (p[_I(i,j+1,k)]-p[_I(i,j-1,k)])*0.5*N; - w[_I(i,j,k)] -= (p[_I(i,j,k+1)]-p[_I(i,j,k-1)])*0.5*N; - } - } - } - set_bnd(1, u, N); - set_bnd(2, v, N); - set_bnd(3, w, N); -} - -void vorticity_confinement(float *T0, float* u, float* u0, float* v, float* v0, float* w, float* w0, float dt, float vc_eps, int N) -{ - int i,j,k,ijk; - float *curlx = u0, *curly = v0, *curlz=w0, *curl=T0; // temp buffers - float dt0 = dt * vc_eps; - float x,y,z; - - - for (k=1; ku, m_fc->u0, m_fc->v, m_fc->v0, m_fc->w, m_fc->w0, m_fc->T, m_fc->T0, dt, GRID_SIZE); - dens_temp_step(sd, sT, m_fc->T, m_fc->T0, m_fc->d, m_fc->d0, m_fc->u, m_fc->v, m_fc->w, dt, GRID_SIZE); -} - - - -void clear_buffer(float* x) -{ - int i; - for (i=0; id=buffers[i++]; m_fc->d0=buffers[i++]; - m_fc->T=buffers[i++]; m_fc->T0=buffers[i++]; - m_fc->u=buffers[i++]; m_fc->u0=buffers[i++]; - m_fc->v=buffers[i++]; m_fc->v0=buffers[i++]; - m_fc->w=buffers[i++]; m_fc->w0=buffers[i++]; - - clear_sources(sd, su, sv); - - size=(GRID_SIZE+2)*(GRID_SIZE+2)*(GRID_SIZE+2); - for (i=0; iv[i] = -0.5f; - - m_fc->_texture_data = (unsigned char*) MEM_callocN((30+2)*(30+2)*(30+2)*4, "fc_texture_data"); - - m_fc->_fp = 0; - - return m_fc; -} - -void f_free(fc *m_fc) -{ - if(m_fc) - { - if(m_fc->_texture_data) - MEM_freeN(m_fc->_texture_data); - - if(m_fc->_fp) - fclose(m_fc->_fp); - - MEM_freeN(m_fc); - } -} - diff --git a/source/blender/blenkernel/intern/collision.c b/source/blender/blenkernel/intern/collision.c index 4bc1efc1e70..4a03f579fe8 100644 --- a/source/blender/blenkernel/intern/collision.c +++ b/source/blender/blenkernel/intern/collision.c @@ -49,7 +49,6 @@ #include "BLI_arithb.h" #include "BLI_edgehash.h" #include "BLI_linklist.h" -#include "BKE_collisions.h" #include "BKE_curve.h" #include "BKE_deform.h" #include "BKE_DerivedMesh.h" @@ -71,20 +70,6 @@ #include "Bullet-C-Api.h" -// step is limited from 0 (frame start position) to 1 (frame end position) -void collision_move_object(CollisionModifierData *collmd, float step, float prevstep) -{ - float tv[3] = {0,0,0}; - unsigned int i = 0; - - for ( i = 0; i < collmd->numverts; i++ ) - { - VECSUB(tv, collmd->xnew[i].co, collmd->x[i].co); - VECADDS(collmd->current_x[i].co, collmd->x[i].co, tv, prevstep); - VECADDS(collmd->current_xnew[i].co, collmd->x[i].co, tv, step); - VECSUB(collmd->current_v[i].co, collmd->current_xnew[i].co, collmd->current_x[i].co); - } -} /** @@ -232,7 +217,7 @@ int gsl_poly_solve_quadratic (float a, float b, float c, float *x0, float *x1) * page 4, left column */ -int collisions_get_collision_time(float a[3], float b[3], float c[3], float d[3], float e[3], float f[3], float solution[3]) +int cloth_get_collision_time(float a[3], float b[3], float c[3], float d[3], float e[3], float f[3], float solution[3]) { int num_sols = 0; @@ -333,7 +318,7 @@ int collisions_get_collision_time(float a[3], float b[3], float c[3], float d[3] } // w3 is not perfect -void collisions_compute_barycentric (float pv[3], float p1[3], float p2[3], float p3[3], float *w1, float *w2, float *w3) +void cloth_compute_barycentric (float pv[3], float p1[3], float p2[3], float p3[3], float *w1, float *w2, float *w3) { double tempV1[3], tempV2[3], tempV4[3]; double a,b,c,d,e,f; @@ -376,3 +361,884 @@ DO_INLINE void interpolateOnTriangle(float to[3], float v1[3], float v2[3], floa VECADDMUL(to, v3, w3); } +// unused in the moment, has some bug in +DO_INLINE void calculateFrictionImpulse(float to[3], float vrel[3], float normal[3], double normalVelocity, + double frictionConstant, double delta_V_n) +{ + float vrel_t_pre[3]; + float vrel_t[3]; + VECSUBS(vrel_t_pre, vrel, normal, normalVelocity); + VECCOPY(to, vrel_t_pre); + VecMulf(to, MAX2(1.0f - frictionConstant * delta_V_n / INPR(vrel_t_pre,vrel_t_pre), 0.0f)); +} + +int cloth_collision_response_static(ClothModifierData *clmd, ClothModifierData *coll_clmd) +{ + unsigned int i = 0; + int result = 0; + LinkNode *search = NULL; + CollPair *collpair = NULL; + Cloth *cloth1, *cloth2; + float w1, w2, w3, u1, u2, u3; + float v1[3], v2[3], relativeVelocity[3]; + float magrelVel; + + cloth1 = clmd->clothObject; + cloth2 = coll_clmd->clothObject; + + search = clmd->coll_parms.collision_list; + + while(search) + { + collpair = search->link; + + // compute barycentric coordinates for both collision points + cloth_compute_barycentric(collpair->pa, + cloth1->verts[collpair->ap1].txold, + cloth1->verts[collpair->ap2].txold, + cloth1->verts[collpair->ap3].txold, + &w1, &w2, &w3); + + cloth_compute_barycentric(collpair->pb, + cloth2->verts[collpair->bp1].txold, + cloth2->verts[collpair->bp2].txold, + cloth2->verts[collpair->bp3].txold, + &u1, &u2, &u3); + + // Calculate relative "velocity". + interpolateOnTriangle(v1, cloth1->verts[collpair->ap1].tv, cloth1->verts[collpair->ap2].tv, cloth1->verts[collpair->ap3].tv, w1, w2, w3); + + interpolateOnTriangle(v2, cloth2->verts[collpair->bp1].tv, cloth2->verts[collpair->bp2].tv, cloth2->verts[collpair->bp3].tv, u1, u2, u3); + + VECSUB(relativeVelocity, v1, v2); + + // Calculate the normal component of the relative velocity (actually only the magnitude - the direction is stored in 'normal'). + magrelVel = INPR(relativeVelocity, collpair->normal); + + // printf("magrelVel: %f\n", magrelVel); + + // Calculate masses of points. + + // If v_n_mag < 0 the edges are approaching each other. + if(magrelVel < -ALMOST_ZERO) + { + // Calculate Impulse magnitude to stop all motion in normal direction. + // const double I_mag = v_n_mag / (1/m1 + 1/m2); + float magnitude_i = magrelVel / 2.0f; // TODO implement masses + float tangential[3], magtangent, magnormal, collvel[3]; + float vrel_t_pre[3]; + float vrel_t[3]; + double impulse; + float epsilon = clmd->coll_parms.epsilon; + float overlap = (epsilon + ALMOST_ZERO-collpair->distance); + + // calculateFrictionImpulse(tangential, relativeVelocity, collpair->normal, magrelVel, clmd->coll_parms.friction*0.01, magrelVel); + + // magtangent = INPR(tangential, tangential); + + // Apply friction impulse. + if (magtangent < -ALMOST_ZERO) + { + + // printf("friction applied: %f\n", magtangent); + // TODO check original code + /* + VECSUB(cloth1->verts[face1->v1].tv, cloth1->verts[face1->v1].tv,tangential); + VECSUB(cloth1->verts[face1->v1].tv, cloth1->verts[face1->v2].tv,tangential); + VECSUB(cloth1->verts[face1->v1].tv, cloth1->verts[face1->v3].tv,tangential); + VECSUB(cloth1->verts[face1->v1].tv, cloth1->verts[face1->v4].tv,tangential); + */ + } + + + impulse = -2.0f * magrelVel / ( 1.0 + w1*w1 + w2*w2 + w3*w3); + + // printf("impulse: %f\n", impulse); + + VECADDMUL(cloth1->verts[collpair->ap1].impulse, collpair->normal, w1 * impulse); + cloth1->verts[collpair->ap1].impulse_count++; + + VECADDMUL(cloth1->verts[collpair->ap2].impulse, collpair->normal, w2 * impulse); + cloth1->verts[collpair->ap2].impulse_count++; + + VECADDMUL(cloth1->verts[collpair->ap3].impulse, collpair->normal, w3 * impulse); + cloth1->verts[collpair->ap3].impulse_count++; + + result = 1; + + /* + if (overlap > ALMOST_ZERO) { + double I_mag = overlap * 0.1; + + impulse = -I_mag / ( 1.0 + w1*w1 + w2*w2 + w3*w3); + + VECADDMUL(cloth1->verts[collpair->ap1].impulse, collpair->normal, w1 * impulse); + cloth1->verts[collpair->ap1].impulse_count++; + + VECADDMUL(cloth1->verts[collpair->ap2].impulse, collpair->normal, w2 * impulse); + cloth1->verts[collpair->ap2].impulse_count++; + + VECADDMUL(cloth1->verts[collpair->ap3].impulse, collpair->normal, w3 * impulse); + cloth1->verts[collpair->ap3].impulse_count++; + } + */ + + // printf("magnitude_i: %f\n", magnitude_i); // negative before collision in my case + + // Apply the impulse and increase impulse counters. + + /* + // calculateFrictionImpulse(tangential, collvel, collpair->normal, magtangent, clmd->coll_parms.friction*0.01, magtangent); + VECSUBS(vrel_t_pre, collvel, collpair->normal, magnormal); + // VecMulf(vrel_t_pre, clmd->coll_parms.friction*0.01f/INPR(vrel_t_pre,vrel_t_pre)); + magtangent = Normalize(vrel_t_pre); + VecMulf(vrel_t_pre, MIN2(clmd->coll_parms.friction*0.01f*magnormal,magtangent)); + + VECSUB(cloth1->verts[face1->v1].tv, cloth1->verts[face1->v1].tv,vrel_t_pre); + */ + + + + } + + search = search->next; + } + + + return result; +} + +int cloth_collision_response_moving_tris(ClothModifierData *clmd, ClothModifierData *coll_clmd) +{ + +} + + +int cloth_collision_response_moving_edges(ClothModifierData *clmd, ClothModifierData *coll_clmd) +{ + +} + +void cloth_collision_static(ClothModifierData *clmd, ClothModifierData *coll_clmd, Tree *tree1, Tree *tree2) +{ + CollPair *collpair = NULL; + Cloth *cloth1=NULL, *cloth2=NULL; + MFace *face1=NULL, *face2=NULL; + ClothVertex *verts1=NULL, *verts2=NULL; + double distance = 0; + float epsilon = clmd->coll_parms.epsilon; + unsigned int i = 0; + + for(i = 0; i < 4; i++) + { + collpair = (CollPair *)MEM_callocN(sizeof(CollPair), "cloth coll pair"); + + cloth1 = clmd->clothObject; + cloth2 = coll_clmd->clothObject; + + verts1 = cloth1->verts; + verts2 = cloth2->verts; + + face1 = &(cloth1->mfaces[tree1->tri_index]); + face2 = &(cloth2->mfaces[tree2->tri_index]); + + // check all possible pairs of triangles + if(i == 0) + { + collpair->ap1 = face1->v1; + collpair->ap2 = face1->v2; + collpair->ap3 = face1->v3; + + collpair->bp1 = face2->v1; + collpair->bp2 = face2->v2; + collpair->bp3 = face2->v3; + + } + + if(i == 1) + { + if(face1->v4) + { + collpair->ap1 = face1->v3; + collpair->ap2 = face1->v4; + collpair->ap3 = face1->v1; + + collpair->bp1 = face2->v1; + collpair->bp2 = face2->v2; + collpair->bp3 = face2->v3; + } + else + i++; + } + + if(i == 2) + { + if(face2->v4) + { + collpair->ap1 = face1->v1; + collpair->ap2 = face1->v2; + collpair->ap3 = face1->v3; + + collpair->bp1 = face2->v3; + collpair->bp2 = face2->v4; + collpair->bp3 = face2->v1; + } + else + i+=2; + } + + if(i == 3) + { + if((face1->v4)&&(face2->v4)) + { + collpair->ap1 = face1->v3; + collpair->ap2 = face1->v4; + collpair->ap3 = face1->v1; + + collpair->bp1 = face2->v3; + collpair->bp2 = face2->v4; + collpair->bp3 = face2->v1; + } + else + i++; + } + + // calc SIPcode (?) + + if(i < 4) + { + // calc distance + normal + distance = plNearestPoints( + verts1[collpair->ap1].txold, verts1[collpair->ap2].txold, verts1[collpair->ap3].txold, verts2[collpair->bp1].txold, verts2[collpair->bp2].txold, verts2[collpair->bp3].txold, collpair->pa,collpair->pb,collpair->vector); + + if (distance <= (epsilon + ALMOST_ZERO)) + { + // printf("dist: %f\n", (float)distance); + + // collpair->face1 = tree1->tri_index; + // collpair->face2 = tree2->tri_index; + + VECCOPY(collpair->normal, collpair->vector); + Normalize(collpair->normal); + + collpair->distance = distance; + BLI_linklist_append(&clmd->coll_parms.collision_list, collpair); + } + else + { + MEM_freeN(collpair); + } + } + else + { + MEM_freeN(collpair); + } + } +} + +int cloth_are_edges_adjacent(ClothModifierData *clmd, ClothModifierData *coll_clmd, EdgeCollPair *edgecollpair) +{ + Cloth *cloth1, *cloth2; + ClothVertex *verts1, *verts2; + float temp[3]; + + cloth1 = clmd->clothObject; + cloth2 = coll_clmd->clothObject; + + verts1 = cloth1->verts; + verts2 = cloth2->verts; + + VECSUB(temp, verts1[edgecollpair->p11].xold, verts2[edgecollpair->p21].xold); + if(ABS(INPR(temp, temp)) < ALMOST_ZERO) + return 1; + + VECSUB(temp, verts1[edgecollpair->p11].xold, verts2[edgecollpair->p22].xold); + if(ABS(INPR(temp, temp)) < ALMOST_ZERO) + return 1; + + VECSUB(temp, verts1[edgecollpair->p12].xold, verts2[edgecollpair->p21].xold); + if(ABS(INPR(temp, temp)) < ALMOST_ZERO) + return 1; + + VECSUB(temp, verts1[edgecollpair->p12].xold, verts2[edgecollpair->p22].xold); + if(ABS(INPR(temp, temp)) < ALMOST_ZERO) + return 1; + + return 0; +} + +void cloth_collision_moving_edges(ClothModifierData *clmd, ClothModifierData *coll_clmd, Tree *tree1, Tree *tree2) +{ + EdgeCollPair edgecollpair; + Cloth *cloth1=NULL, *cloth2=NULL; + MFace *face1=NULL, *face2=NULL; + ClothVertex *verts1=NULL, *verts2=NULL; + double distance = 0; + float epsilon = clmd->coll_parms.epsilon; + unsigned int i = 0, j = 0, k = 0; + int numsolutions = 0; + float a[3], b[3], c[3], d[3], e[3], f[3], solution[3]; + + cloth1 = clmd->clothObject; + cloth2 = coll_clmd->clothObject; + + verts1 = cloth1->verts; + verts2 = cloth2->verts; + + face1 = &(cloth1->mfaces[tree1->tri_index]); + face2 = &(cloth2->mfaces[tree2->tri_index]); + + for( i = 0; i < 5; i++) + { + if(i == 0) + { + edgecollpair.p11 = face1->v1; + edgecollpair.p12 = face1->v2; + } + else if(i == 1) + { + edgecollpair.p11 = face1->v2; + edgecollpair.p12 = face1->v3; + } + else if(i == 2) + { + if(face1->v4) + { + edgecollpair.p11 = face1->v3; + edgecollpair.p12 = face1->v4; + } + else + { + edgecollpair.p11 = face1->v3; + edgecollpair.p12 = face1->v1; + i+=5; // get out of here after this edge pair is handled + } + } + else if(i == 3) + { + if(face1->v4) + { + edgecollpair.p11 = face1->v4; + edgecollpair.p12 = face1->v1; + } + else + continue; + } + else + { + edgecollpair.p11 = face1->v3; + edgecollpair.p12 = face1->v1; + } + + + for( j = 0; j < 5; j++) + { + if(j == 0) + { + edgecollpair.p21 = face2->v1; + edgecollpair.p22 = face2->v2; + } + else if(j == 1) + { + edgecollpair.p21 = face2->v2; + edgecollpair.p22 = face2->v3; + } + else if(j == 2) + { + if(face2->v4) + { + edgecollpair.p21 = face2->v3; + edgecollpair.p22 = face2->v4; + } + else + { + edgecollpair.p21 = face2->v3; + edgecollpair.p22 = face2->v1; + } + } + else if(j == 3) + { + if(face2->v4) + { + edgecollpair.p21 = face2->v4; + edgecollpair.p22 = face2->v1; + } + else + continue; + } + else + { + edgecollpair.p21 = face2->v3; + edgecollpair.p22 = face2->v1; + } + + + if(!cloth_are_edges_adjacent(clmd, coll_clmd, &edgecollpair)) + { + VECSUB(a, verts1[edgecollpair.p12].xold, verts1[edgecollpair.p11].xold); + VECSUB(b, verts1[edgecollpair.p12].v, verts1[edgecollpair.p11].v); + VECSUB(c, verts1[edgecollpair.p21].xold, verts1[edgecollpair.p11].xold); + VECSUB(d, verts1[edgecollpair.p21].v, verts1[edgecollpair.p11].v); + VECSUB(e, verts2[edgecollpair.p22].xold, verts1[edgecollpair.p11].xold); + VECSUB(f, verts2[edgecollpair.p22].v, verts1[edgecollpair.p11].v); + + numsolutions = cloth_get_collision_time(a, b, c, d, e, f, solution); + + for (k = 0; k < numsolutions; k++) + { + if ((solution[k] >= 0.0) && (solution[k] <= 1.0)) + { + float out_collisionTime = solution[k]; + + // TODO: check for collisions + + // TODO: put into (edge) collision list + + // printf("Moving edge found!\n"); + } + } + } + } + } +} + +void cloth_collision_moving_tris(ClothModifierData *clmd, ClothModifierData *coll_clmd, Tree *tree1, Tree *tree2) +{ + CollPair collpair; + Cloth *cloth1=NULL, *cloth2=NULL; + MFace *face1=NULL, *face2=NULL; + ClothVertex *verts1=NULL, *verts2=NULL; + double distance = 0; + float epsilon = clmd->coll_parms.epsilon; + unsigned int i = 0, j = 0, k = 0; + int numsolutions = 0; + float a[3], b[3], c[3], d[3], e[3], f[3], solution[3]; + + for(i = 0; i < 2; i++) + { + cloth1 = clmd->clothObject; + cloth2 = coll_clmd->clothObject; + + verts1 = cloth1->verts; + verts2 = cloth2->verts; + + face1 = &(cloth1->mfaces[tree1->tri_index]); + face2 = &(cloth2->mfaces[tree2->tri_index]); + + // check all possible pairs of triangles + if(i == 0) + { + collpair.ap1 = face1->v1; + collpair.ap2 = face1->v2; + collpair.ap3 = face1->v3; + + collpair.pointsb[0] = face2->v1; + collpair.pointsb[1] = face2->v2; + collpair.pointsb[2] = face2->v3; + collpair.pointsb[3] = face2->v4; + } + + if(i == 1) + { + if(face1->v4) + { + collpair.ap1 = face1->v3; + collpair.ap2 = face1->v4; + collpair.ap3 = face1->v1; + + collpair.pointsb[0] = face2->v1; + collpair.pointsb[1] = face2->v2; + collpair.pointsb[2] = face2->v3; + collpair.pointsb[3] = face2->v4; + } + else + i++; + } + + // calc SIPcode (?) + + if(i < 2) + { + VECSUB(a, verts1[collpair.ap2].xold, verts1[collpair.ap1].xold); + VECSUB(b, verts1[collpair.ap2].v, verts1[collpair.ap1].v); + VECSUB(c, verts1[collpair.ap3].xold, verts1[collpair.ap1].xold); + VECSUB(d, verts1[collpair.ap3].v, verts1[collpair.ap1].v); + + for(j = 0; j < 4; j++) + { + if((j==3) && !(face2->v4)) + break; + + VECSUB(e, verts2[collpair.pointsb[j]].xold, verts1[collpair.ap1].xold); + VECSUB(f, verts2[collpair.pointsb[j]].v, verts1[collpair.ap1].v); + + numsolutions = cloth_get_collision_time(a, b, c, d, e, f, solution); + + for (k = 0; k < numsolutions; k++) + { + if ((solution[k] >= 0.0) && (solution[k] <= 1.0)) + { + float out_collisionTime = solution[k]; + + // TODO: check for collisions + + // TODO: put into (point-face) collision list + + // printf("Moving found!\n"); + + } + } + + // TODO: check borders for collisions + } + + } + } +} + +void cloth_collision_moving(ClothModifierData *clmd, ClothModifierData *coll_clmd, Tree *tree1, Tree *tree2) +{ + // TODO: check for adjacent + cloth_collision_moving_edges(clmd, coll_clmd, tree1, tree2); + + cloth_collision_moving_tris(clmd, coll_clmd, tree1, tree2); + cloth_collision_moving_tris(coll_clmd, clmd, tree2, tree1); +} + +// move collision objects forward in time and update static bounding boxes +void cloth_update_collision_objects(float step) +{ + Base *base=NULL; + ClothModifierData *coll_clmd=NULL; + Object *coll_ob=NULL; + unsigned int i=0; + + // search all objects for collision object + for (base = G.scene->base.first; base; base = base->next) + { + + coll_ob = base->object; + coll_clmd = (ClothModifierData *) modifiers_findByType (coll_ob, eModifierType_Cloth); + if (!coll_clmd) + continue; + + // if collision object go on + if (coll_clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_COLLOBJ) + { + if (coll_clmd->clothObject && coll_clmd->clothObject->tree) + { + Cloth *coll_cloth = coll_clmd->clothObject; + BVH *coll_bvh = coll_clmd->clothObject->tree; + unsigned int coll_numverts = coll_cloth->numverts; + + // update position of collision object + for(i = 0; i < coll_numverts; i++) + { + VECCOPY(coll_cloth->verts[i].txold, coll_cloth->verts[i].tx); + + VECADDS(coll_cloth->verts[i].tx, coll_cloth->verts[i].xold, coll_cloth->verts[i].v, step); + + // no dt here because of float rounding errors + VECSUB(coll_cloth->verts[i].tv, coll_cloth->verts[i].tx, coll_cloth->verts[i].txold); + } + + // update BVH of collision object + bvh_update(coll_clmd, coll_bvh, 0); // 0 means STATIC, 1 means MOVING + } + else + printf ("cloth_bvh_objcollision: found a collision object with clothObject or collData NULL.\n"); + } + } +} + +// CLOTH_MAX_THRESHOLD defines how much collision rounds/loops should be taken +#define CLOTH_MAX_THRESHOLD 10 + +// cloth - object collisions +int cloth_bvh_objcollision(ClothModifierData * clmd, float step, float dt) +{ + Base *base=NULL; + ClothModifierData *coll_clmd=NULL; + Cloth *cloth=NULL; + Object *coll_ob=NULL; + BVH *cloth_bvh=NULL; + unsigned int i=0, j = 0, numfaces = 0, numverts = 0; + unsigned int result = 0, ic = 0, rounds = 0; // result counts applied collisions; ic is for debug output; + ClothVertex *verts = NULL; + float tnull[3] = {0,0,0}; + int ret = 0; + + if ((clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_COLLOBJ) || !(((Cloth *)clmd->clothObject)->tree)) + { + return 0; + } + cloth = clmd->clothObject; + verts = cloth->verts; + cloth_bvh = (BVH *) cloth->tree; + numfaces = clmd->clothObject->numfaces; + numverts = clmd->clothObject->numverts; + + //////////////////////////////////////////////////////////// + // static collisions + //////////////////////////////////////////////////////////// + + // update cloth bvh + bvh_update(clmd, cloth_bvh, 0); // 0 means STATIC, 1 means MOVING (see later in this function) + + // update collision objects + cloth_update_collision_objects(step); + + do + { + result = 0; + ic = 0; + clmd->coll_parms.collision_list = NULL; + + // check all collision objects + for (base = G.scene->base.first; base; base = base->next) + { + coll_ob = base->object; + coll_clmd = (ClothModifierData *) modifiers_findByType (coll_ob, eModifierType_Cloth); + + if (!coll_clmd) + continue; + + // if collision object go on + if (coll_clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_COLLOBJ) + { + if (coll_clmd->clothObject && coll_clmd->clothObject->tree) + { + BVH *coll_bvh = coll_clmd->clothObject->tree; + + bvh_traverse(clmd, coll_clmd, cloth_bvh->root, coll_bvh->root, step, cloth_collision_static); + } + else + printf ("cloth_bvh_objcollision: found a collision object with clothObject or collData NULL.\n"); + } + } + + // process all collisions (calculate impulses, TODO: also repulses if distance too short) + result = 1; + for(j = 0; j < 10; j++) // 10 is just a value that ensures convergence + { + result = 0; + + // handle all collision objects + for (base = G.scene->base.first; base; base = base->next) + { + + coll_ob = base->object; + coll_clmd = (ClothModifierData *) modifiers_findByType (coll_ob, eModifierType_Cloth); + if (!coll_clmd) + continue; + + // if collision object go on + if (coll_clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_COLLOBJ) + { + if (coll_clmd->clothObject) + result += cloth_collision_response_static(clmd, coll_clmd); + else + printf ("cloth_bvh_objcollision: found a collision object with clothObject or collData NULL.\n"); + } + } + + // apply impulses in parallel + ic=0; + for(i = 0; i < numverts; i++) + { + // calculate "velocities" (just xnew = xold + v; no dt in v) + if(verts[i].impulse_count) + { + VECADDMUL(verts[i].tv, verts[i].impulse, 1.0f / verts[i].impulse_count); + VECCOPY(verts[i].impulse, tnull); + verts[i].impulse_count = 0; + + ic++; + ret++; + } + } + } + + // free collision list + if(clmd->coll_parms.collision_list) + { + LinkNode *search = clmd->coll_parms.collision_list; + while(search) + { + CollPair *coll_pair = search->link; + + MEM_freeN(coll_pair); + search = search->next; + } + BLI_linklist_free(clmd->coll_parms.collision_list,NULL); + + clmd->coll_parms.collision_list = NULL; + } + + printf("ic: %d\n", ic); + rounds++; + } + while(result && (CLOTH_MAX_THRESHOLD>rounds)); + + printf("\n"); + + //////////////////////////////////////////////////////////// + // update positions + // this is needed for bvh_calc_DOP_hull_moving() [kdop.c] + //////////////////////////////////////////////////////////// + + // verts come from clmd + for(i = 0; i < numverts; i++) + { + VECADD(verts[i].tx, verts[i].txold, verts[i].tv); + } + //////////////////////////////////////////////////////////// + + //////////////////////////////////////////////////////////// + // moving collisions + //////////////////////////////////////////////////////////// + + + // update cloth bvh + bvh_update(clmd, cloth_bvh, 1); // 0 means STATIC, 1 means MOVING + + // update moving bvh for collision object once + for (base = G.scene->base.first; base; base = base->next) + { + + coll_ob = base->object; + coll_clmd = (ClothModifierData *) modifiers_findByType (coll_ob, eModifierType_Cloth); + if (!coll_clmd) + continue; + + if(!coll_clmd->clothObject) + continue; + + // if collision object go on + if (coll_clmd->clothObject && coll_clmd->clothObject->tree) + { + BVH *coll_bvh = coll_clmd->clothObject->tree; + + bvh_update(coll_clmd, coll_bvh, 1); // 0 means STATIC, 1 means MOVING + } + } + + + do + { + result = 0; + ic = 0; + clmd->coll_parms.collision_list = NULL; + + // check all collision objects + for (base = G.scene->base.first; base; base = base->next) + { + coll_ob = base->object; + coll_clmd = (ClothModifierData *) modifiers_findByType (coll_ob, eModifierType_Cloth); + + if (!coll_clmd) + continue; + + // if collision object go on + if (coll_clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_COLLOBJ) + { + if (coll_clmd->clothObject && coll_clmd->clothObject->tree) + { + BVH *coll_bvh = coll_clmd->clothObject->tree; + + bvh_traverse(clmd, coll_clmd, cloth_bvh->root, coll_bvh->root, step, cloth_collision_moving); + } + else + printf ("cloth_bvh_objcollision: found a collision object with clothObject or collData NULL.\n"); + } + } + + // process all collisions (calculate impulses, TODO: also repulses if distance too short) + result = 1; + for(j = 0; j < 10; j++) // 10 is just a value that ensures convergence + { + result = 0; + + // handle all collision objects + for (base = G.scene->base.first; base; base = base->next) + { + + coll_ob = base->object; + coll_clmd = (ClothModifierData *) modifiers_findByType (coll_ob, eModifierType_Cloth); + + if (!coll_clmd) + continue; + + // if collision object go on + if (coll_clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_COLLOBJ) + { + if (coll_clmd->clothObject) + result += cloth_collision_response_moving_tris(clmd, coll_clmd); + else + printf ("cloth_bvh_objcollision: found a collision object with clothObject or collData NULL.\n"); + } + } + + // apply impulses in parallel + ic=0; + for(i = 0; i < numverts; i++) + { + // calculate "velocities" (just xnew = xold + v; no dt in v) + if(verts[i].impulse_count) + { + VECADDMUL(verts[i].tv, verts[i].impulse, 1.0f / verts[i].impulse_count); + VECCOPY(verts[i].impulse, tnull); + verts[i].impulse_count = 0; + + ic++; + ret++; + } + } + } + + + // verts come from clmd + for(i = 0; i < numverts; i++) + { + VECADD(verts[i].tx, verts[i].txold, verts[i].tv); + } + + // update cloth bvh + bvh_update(clmd, cloth_bvh, 1); // 0 means STATIC, 1 means MOVING + + + // free collision list + if(clmd->coll_parms.collision_list) + { + LinkNode *search = clmd->coll_parms.collision_list; + while(search) + { + CollPair *coll_pair = search->link; + + MEM_freeN(coll_pair); + search = search->next; + } + BLI_linklist_free(clmd->coll_parms.collision_list,NULL); + + clmd->coll_parms.collision_list = NULL; + } + + printf("ic: %d\n", ic); + rounds++; + } + while(result && (CLOTH_MAX_THRESHOLD>rounds)); + + + //////////////////////////////////////////////////////////// + // update positions + velocities + //////////////////////////////////////////////////////////// + + // verts come from clmd + for(i = 0; i < numverts; i++) + { + VECADD(verts[i].tx, verts[i].txold, verts[i].tv); + } + //////////////////////////////////////////////////////////// + + return MIN2(ret, 1); +} diff --git a/source/blender/blenkernel/intern/implicit.c b/source/blender/blenkernel/intern/implicit.c index a1d60b34125..b154cb0e755 100644 --- a/source/blender/blenkernel/intern/implicit.c +++ b/source/blender/blenkernel/intern/implicit.c @@ -46,11 +46,9 @@ #include "DNA_lattice_types.h" #include "DNA_scene_types.h" #include "DNA_modifier_types.h" -#include "BLI_arithb.h" #include "BLI_blenlib.h" -#include "BLI_edgehash.h" +#include "BLI_arithb.h" #include "BLI_threads.h" -#include "BKE_collisions.h" #include "BKE_curve.h" #include "BKE_displist.h" #include "BKE_effect.h" @@ -63,7 +61,6 @@ #include "BKE_global.h" #include "BIF_editdeform.h" -#include "Bullet-C-Api.h" #ifdef _WIN32 #include @@ -85,14 +82,18 @@ void itend(void) double itval() { return ((double)_itend.QuadPart - - (double)_itstart.QuadPart)/((double)ifreq.QuadPart); + (double)_itstart.QuadPart)/((double)ifreq.QuadPart); } #else #include +// intrinsics need better compile flag checking +// #include +// #include +// #include - static struct timeval _itstart, _itend; - static struct timezone itz; - void itstart(void) +static struct timeval _itstart, _itend; +static struct timezone itz; +void itstart(void) { gettimeofday(&_itstart, &itz); } @@ -108,7 +109,14 @@ double itval() return t2-t1; } #endif - +/* +#define C99 +#ifdef C99 +#defineDO_INLINE inline +#else +#defineDO_INLINE static +#endif +*/ struct Cloth; ////////////////////////////////////////// @@ -172,7 +180,7 @@ void print_fvector(float m3[3]) // long float vector float (*)[3] /////////////////////////// /* print long vector on console: for debug output */ -DO_INLINE void print_lfvector(lfVector *fLongVector, unsigned int verts) +DO_INLINE void print_lfvector(float (*fLongVector)[3], unsigned int verts) { unsigned int i = 0; for(i = 0; i < verts; i++) @@ -188,7 +196,7 @@ DO_INLINE lfVector *create_lfvector(unsigned int verts) // return (lfVector *)cloth_aligned_malloc(&MEMORY_BASE, verts * sizeof(lfVector)); } /* delete long vector */ -DO_INLINE void del_lfvector(lfVector *fLongVector) +DO_INLINE void del_lfvector(float (*fLongVector)[3]) { if (fLongVector != NULL) { @@ -202,7 +210,7 @@ DO_INLINE void cp_lfvector(float (*to)[3], float (*from)[3], unsigned int verts) memcpy(to, from, verts * sizeof(lfVector)); } /* init long vector with float[3] */ -DO_INLINE void init_lfvector(lfVector *fLongVector, float vector[3], unsigned int verts) +DO_INLINE void init_lfvector(float (*fLongVector)[3], float vector[3], unsigned int verts) { unsigned int i = 0; for(i = 0; i < verts; i++) @@ -216,7 +224,7 @@ DO_INLINE void zero_lfvector(float (*to)[3], unsigned int verts) memset(to, 0.0f, verts * sizeof(lfVector)); } /* multiply long vector with scalar*/ -DO_INLINE void mul_lfvectorS(float (*to)[3], lfVector *fLongVector, float scalar, unsigned int verts) +DO_INLINE void mul_lfvectorS(float (*to)[3], float (*fLongVector)[3], float scalar, unsigned int verts) { unsigned int i = 0; @@ -227,7 +235,7 @@ DO_INLINE void mul_lfvectorS(float (*to)[3], lfVector *fLongVector, float scalar } /* multiply long vector with scalar*/ /* A -= B * float */ -DO_INLINE void submul_lfvectorS(float (*to)[3], lfVector *fLongVector, float scalar, unsigned int verts) +DO_INLINE void submul_lfvectorS(float (*to)[3], float (*fLongVector)[3], float scalar, unsigned int verts) { unsigned int i = 0; for(i = 0; i < verts; i++) @@ -236,12 +244,12 @@ DO_INLINE void submul_lfvectorS(float (*to)[3], lfVector *fLongVector, float sca } } /* dot product for big vector */ -DO_INLINE float dot_lfvector(lfVector *fLongVectorA, lfVector *fLongVectorB, unsigned int verts) +DO_INLINE float dot_lfvector(float (*fLongVectorA)[3], float (*fLongVectorB)[3], unsigned int verts) { unsigned int i = 0; float temp = 0.0; // schedule(guided, 2) -#pragma omp parallel for reduction(+: temp) private(i) +#pragma omp parallel for reduction(+: temp) for(i = 0; i < verts; i++) { temp += INPR(fLongVectorA[i], fLongVectorB[i]); @@ -249,7 +257,7 @@ DO_INLINE float dot_lfvector(lfVector *fLongVectorA, lfVector *fLongVectorB, uns return temp; } /* A = B + C --> for big vector */ -DO_INLINE void add_lfvector_lfvector(float (*to)[3], lfVector *fLongVectorA, lfVector *fLongVectorB, unsigned int verts) +DO_INLINE void add_lfvector_lfvector(float (*to)[3], float (*fLongVectorA)[3], float (*fLongVectorB)[3], unsigned int verts) { unsigned int i = 0; @@ -260,7 +268,7 @@ DO_INLINE void add_lfvector_lfvector(float (*to)[3], lfVector *fLongVectorA, lfV } /* A = B + C * float --> for big vector */ -DO_INLINE void add_lfvector_lfvectorS(float (*to)[3], lfVector *fLongVectorA, lfVector *fLongVectorB, float bS, unsigned int verts) +DO_INLINE void add_lfvector_lfvectorS(float (*to)[3], float (*fLongVectorA)[3], float (*fLongVectorB)[3], float bS, unsigned int verts) { unsigned int i = 0; @@ -271,7 +279,7 @@ DO_INLINE void add_lfvector_lfvectorS(float (*to)[3], lfVector *fLongVectorA, lf } } /* A = B * float + C * float --> for big vector */ -DO_INLINE void add_lfvectorS_lfvectorS(float (*to)[3], lfVector *fLongVectorA, float aS, lfVector *fLongVectorB, float bS, unsigned int verts) +DO_INLINE void add_lfvectorS_lfvectorS(float (*to)[3], float (*fLongVectorA)[3], float aS, float (*fLongVectorB)[3], float bS, unsigned int verts) { unsigned int i = 0; @@ -281,7 +289,7 @@ DO_INLINE void add_lfvectorS_lfvectorS(float (*to)[3], lfVector *fLongVectorA, f } } /* A = B - C * float --> for big vector */ -DO_INLINE void sub_lfvector_lfvectorS(float (*to)[3], lfVector *fLongVectorA, lfVector *fLongVectorB, float bS, unsigned int verts) +DO_INLINE void sub_lfvector_lfvectorS(float (*to)[3], float (*fLongVectorA)[3], float (*fLongVectorB)[3], float bS, unsigned int verts) { unsigned int i = 0; for(i = 0; i < verts; i++) @@ -291,7 +299,7 @@ DO_INLINE void sub_lfvector_lfvectorS(float (*to)[3], lfVector *fLongVectorA, lf } /* A = B - C --> for big vector */ -DO_INLINE void sub_lfvector_lfvector(float (*to)[3], lfVector *fLongVectorA, lfVector *fLongVectorB, unsigned int verts) +DO_INLINE void sub_lfvector_lfvector(float (*to)[3], float (*fLongVectorA)[3], float (*fLongVectorB)[3], unsigned int verts) { unsigned int i = 0; @@ -323,7 +331,7 @@ DO_INLINE void cp_fmatrix(float to[3][3], float from[3][3]) DO_INLINE float det_fmatrix(float m[3][3]) { return m[0][0]*m[1][1]*m[2][2] + m[1][0]*m[2][1]*m[0][2] + m[0][1]*m[1][2]*m[2][0] - -m[0][0]*m[1][2]*m[2][1] - m[0][1]*m[1][0]*m[2][2] - m[2][0]*m[1][1]*m[0][2]; + -m[0][0]*m[1][2]*m[2][1] - m[0][1]*m[1][0]*m[2][2] - m[2][0]*m[1][1]*m[0][2]; } DO_INLINE void inverse_fmatrix(float to[3][3], float from[3][3]) { @@ -561,37 +569,34 @@ DO_INLINE void mul_bfmatrix_S(fmatrix3x3 *matrix, float scalar) /* SPARSE SYMMETRIC multiply big matrix with long vector*/ /* STATUS: verified */ -DO_INLINE void mul_bfmatrix_lfvector( float (*to)[3], fmatrix3x3 *from, lfVector *fLongVector) +DO_INLINE void mul_bfmatrix_lfvector( float (*to)[3], fmatrix3x3 *from, float (*fLongVector)[3]) { unsigned int i = 0; - lfVector *temp = create_lfvector(from[0].vcount); - zero_lfvector(to, from[0].vcount); - -#pragma omp parallel sections private(i) + /* process diagonal elements */ + for(i = 0; i < from[0].vcount; i++) { -#pragma omp section - { - for(i = from[0].vcount; i < from[0].vcount+from[0].scount; i++) - { - muladd_fmatrix_fvector(to[from[i].c], from[i].m, fLongVector[from[i].r]); - } - } -#pragma omp section - { - for(i = 0; i < from[0].vcount+from[0].scount; i++) - { - muladd_fmatrix_fvector(temp[from[i].r], from[i].m, fLongVector[from[i].c]); - } - } + muladd_fmatrix_fvector(to[from[i].r], from[i].m, fLongVector[from[i].c]); } - add_lfvector_lfvector(to, to, temp, from[0].vcount); - - del_lfvector(temp); - - -} + /* process off-diagonal entries (every off-diagonal entry needs to be symmetric) */ + // TODO: pragma below is wrong, correct it! + // #pragma omp parallel for shared(to,from, fLongVector) private(i) + for(i = from[0].vcount; i < from[0].vcount+from[0].scount; i++) + { + // muladd_fmatrix_fvector(to[from[i].c], from[i].m, fLongVector[from[i].r]); + + to[from[i].c][0] += INPR(from[i].m[0],fLongVector[from[i].r]); + to[from[i].c][1] += INPR(from[i].m[1],fLongVector[from[i].r]); + to[from[i].c][2] += INPR(from[i].m[2],fLongVector[from[i].r]); + + // muladd_fmatrix_fvector(to[from[i].r], from[i].m, fLongVector[from[i].c]); + + to[from[i].r][0] += INPR(from[i].m[0],fLongVector[from[i].c]); + to[from[i].r][1] += INPR(from[i].m[1],fLongVector[from[i].c]); + to[from[i].r][2] += INPR(from[i].m[2],fLongVector[from[i].c]); + } +} /* SPARSE SYMMETRIC multiply big matrix with long vector (for diagonal preconditioner) */ /* STATUS: verified */ @@ -699,7 +704,7 @@ static float I[3][3] = {{1,0,0},{0,1,0},{0,0,1}}; static float ZERO[3][3] = {{0,0,0}, {0,0,0}, {0,0,0}}; typedef struct Implicit_Data { - lfVector *X, *V, *Xnew, *Vnew, *F, *B, *dV, *z; + lfVector *X, *V, *Xnew, *Vnew, *olddV, *F, *B, *dV, *z; fmatrix3x3 *A, *dFdV, *dFdX, *S, *P, *Pinv, *bigI; } Implicit_Data; @@ -735,6 +740,8 @@ int implicit_init (Object *ob, ClothModifierData *clmd) id->Xnew = create_lfvector(cloth->numverts); id->V = create_lfvector(cloth->numverts); id->Vnew = create_lfvector(cloth->numverts); + id->olddV = create_lfvector(cloth->numverts); + zero_lfvector(id->olddV, cloth->numverts); id->F = create_lfvector(cloth->numverts); id->B = create_lfvector(cloth->numverts); id->dV = create_lfvector(cloth->numverts); @@ -767,7 +774,7 @@ int implicit_init (Object *ob, ClothModifierData *clmd) // dFdV_start[i].c = big_I[i].c = big_zero[i].c = id->A[i+cloth->numverts].c = id->dFdV[i+cloth->numverts].c = id->dFdX[i+cloth->numverts].c = - id->P[i+cloth->numverts].c = id->Pinv[i+cloth->numverts].c = id->bigI[i+cloth->numverts].c = spring->kl; + id->P[i+cloth->numverts].c = id->Pinv[i+cloth->numverts].c = id->bigI[i+cloth->numverts].c = spring->kl; spring->matrix_index = i + cloth->numverts; @@ -776,7 +783,7 @@ int implicit_init (Object *ob, ClothModifierData *clmd) for(i = 0; i < cloth->numverts; i++) { - VECCOPY(id->X[i], cloth->x[i]); + VECCOPY(id->X[i], verts[i].x); } return 1; @@ -805,6 +812,7 @@ int implicit_free (ClothModifierData *clmd) del_lfvector(id->Xnew); del_lfvector(id->V); del_lfvector(id->Vnew); + del_lfvector(id->olddV); del_lfvector(id->F); del_lfvector(id->B); del_lfvector(id->dV); @@ -817,31 +825,6 @@ int implicit_free (ClothModifierData *clmd) return 1; } -void cloth_bending_mode(ClothModifierData *clmd, int enabled) -{ - Cloth *cloth = clmd->clothObject; - Implicit_Data *id; - - if(cloth) - { - id = cloth->implicit; - - if(id) - { - if(enabled) - { - cloth->numsprings = cloth->numspringssave; - } - else - { - cloth->numsprings = cloth->numothersprings; - } - - id->A[0].scount = id->dFdV[0].scount = id->dFdX[0].scount = id->P[0].scount = id->Pinv[0].scount = id->bigI[0].scount = cloth->numsprings; - } - } -} - DO_INLINE float fb(float length, float L) { float x = length/L; @@ -892,7 +875,7 @@ DO_INLINE void filter(lfVector *V, fmatrix3x3 *S) } } -int cg_filtered(lfVector *dv, fmatrix3x3 *lA, lfVector *lB, lfVector *z, fmatrix3x3 *S) +int cg_filtered(lfVector *ldV, fmatrix3x3 *lA, lfVector *lB, lfVector *z, fmatrix3x3 *S) { // Solves for unknown X in equation AX=B unsigned int conjgrad_loopcount=0, conjgrad_looplimit=100; @@ -905,14 +888,14 @@ int cg_filtered(lfVector *dv, fmatrix3x3 *lA, lfVector *lB, lfVector *z, fmatrix tmp = create_lfvector(numverts); r = create_lfvector(numverts); - // zero_lfvector(dv, CLOTHPARTICLES); - filter(dv, S); + // zero_lfvector(ldV, CLOTHPARTICLES); + filter(ldV, S); - add_lfvector_lfvector(dv, dv, z, numverts); + add_lfvector_lfvector(ldV, ldV, z, numverts); // r = B - Mul(tmp,A,X); // just use B if X known to be zero cp_lfvector(r, lB, numverts); - mul_bfmatrix_lfvector(tmp, lA, dv); + mul_bfmatrix_lfvector(tmp, lA, ldV); sub_lfvector_lfvector(r, r, tmp, numverts); filter(r,S); @@ -932,7 +915,7 @@ int cg_filtered(lfVector *dv, fmatrix3x3 *lA, lfVector *lB, lfVector *z, fmatrix a = s/dot_lfvector(d, q, numverts); // X = X + d*a; - add_lfvector_lfvectorS(dv, dv, d, a, numverts); + add_lfvector_lfvectorS(ldV, ldV, d, a, numverts); // r = r - q*a; sub_lfvector_lfvectorS(r, r, q, a, numverts); @@ -947,16 +930,12 @@ int cg_filtered(lfVector *dv, fmatrix3x3 *lA, lfVector *lB, lfVector *z, fmatrix conjgrad_loopcount++; } - // itend(); - // printf("cg_filtered time: %f\n", (float)itval()); - conjgrad_lasterror = s; del_lfvector(q); del_lfvector(d); del_lfvector(tmp); del_lfvector(r); - // printf("W/O conjgrad_loopcount: %d\n", conjgrad_loopcount); return conjgrad_loopcountrestlen; - float cb = clmd->sim_parms->structural; + float cb = clmd->sim_parms.structural; float nullf[3] = {0,0,0}; float stretch_force[3] = {0,0,0}; float bending_force[3] = {0,0,0}; float damping_force[3] = {0,0,0}; float nulldfdx[3][3]={ {0,0,0}, {0,0,0}, {0,0,0}}; + Cloth *cloth = clmd->clothObject; + ClothVertex *verts = cloth->verts; VECCOPY(s->f, nullf); cp_fmatrix(s->dfdx, nulldfdx); @@ -1125,13 +1106,13 @@ DO_INLINE void cloth_calc_spring_force(ClothModifierData *clmd, ClothSpring *s, /* if(length>L) { - if((clmd->sim_parms->flags & CSIMSETT_FLAG_TEARING_ENABLED) - && ((((length-L)*100.0f/L) > clmd->sim_parms->maxspringlen))) // cut spring! - { - s->flags |= CSPRING_FLAG_DEACTIVATE; - return; - } - } + if((clmd->sim_parms.flags & CSIMSETT_FLAG_TEARING_ENABLED) + && ((((length-L)*100.0f/L) > clmd->sim_parms.maxspringlen))) // cut spring! + { + s->flags |= CSPRING_FLAG_DEACTIVATE; + return; + } + } */ mul_fvector_S(dir, extent, 1.0f/length); } @@ -1141,19 +1122,6 @@ DO_INLINE void cloth_calc_spring_force(ClothModifierData *clmd, ClothSpring *s, } - /* - if(s->type == CLOTH_SPRING_TYPE_COLLISION) - { - if(length < L) - { - mul_fvector_S(stretch_force, dir, (100.0*(length-L))); - - VECADD(s->f, s->f, stretch_force); - } - return; - } - */ - // calculate force of structural + shear springs if(s->type != CLOTH_SPRING_TYPE_BENDING) { @@ -1161,72 +1129,56 @@ DO_INLINE void cloth_calc_spring_force(ClothModifierData *clmd, ClothSpring *s, { s->flags |= CLOTH_SPRING_FLAG_NEEDED; - k = clmd->sim_parms->structural; + k = clmd->sim_parms.structural; mul_fvector_S(stretch_force, dir, (k*(length-L))); VECADD(s->f, s->f, stretch_force); // Ascher & Boxman, p.21: Damping only during elonglation - mul_fvector_S(damping_force, extent, clmd->sim_parms->Cdis * 0.01 * ((INPR(vel,extent)/length))); + mul_fvector_S(damping_force, extent, clmd->sim_parms.Cdis * ((INPR(vel,extent)/length))); VECADD(s->f, s->f, damping_force); dfdx_spring_type1(s->dfdx, dir,length,L,k); - dfdv_damp(s->dfdv, dir,clmd->sim_parms->Cdis); + dfdv_damp(s->dfdv, dir,clmd->sim_parms.Cdis); } } else // calculate force of bending springs { if(length < L) { - // clmd->sim_parms->flags |= CLOTH_SIMSETTINGS_FLAG_BIG_FORCE; - s->flags |= CLOTH_SPRING_FLAG_NEEDED; - k = clmd->sim_parms->bending; + k = clmd->sim_parms.bending; mul_fvector_S(bending_force, dir, fbstar(length, L, k, cb)); VECADD(s->f, s->f, bending_force); - - // if(INPR(bending_force,bending_force) > 0.13*0.13) - { - clmd->sim_parms->flags |= CLOTH_SIMSETTINGS_FLAG_BIG_FORCE; - } - - + dfdx_spring_type2(s->dfdx, dir,length,L,k, cb); - /* - if(s->ij == 300 || s->kl == 300) - printf("id->F[0]: %f, id->F[1]: %f, id->F[2]: %f\n", s->f[0], s->f[1], s->f[2]); - */ } } } -DO_INLINE int cloth_apply_spring_force(ClothModifierData *clmd, ClothSpring *s, lfVector *lF, lfVector *X, lfVector *V, fmatrix3x3 *dFdV, fmatrix3x3 *dFdX) +DO_INLINE void cloth_apply_spring_force(ClothModifierData *clmd, ClothSpring *s, lfVector *lF, lfVector *X, lfVector *V, fmatrix3x3 *dFdV, fmatrix3x3 *dFdX) { if(s->flags & CLOTH_SPRING_FLAG_NEEDED) { - VECADD(lF[s->ij], lF[s->ij], s->f); - VECSUB(lF[s->kl], lF[s->kl], s->f); - if(s->type != CLOTH_SPRING_TYPE_BENDING) { sub_fmatrix_fmatrix(dFdV[s->ij].m, dFdV[s->ij].m, s->dfdv); sub_fmatrix_fmatrix(dFdV[s->kl].m, dFdV[s->kl].m, s->dfdv); - add_fmatrix_fmatrix(dFdV[s->matrix_index].m, dFdV[s->matrix_index].m, s->dfdv); + add_fmatrix_fmatrix(dFdV[s->matrix_index].m, dFdV[s->matrix_index].m, s->dfdv); } - else if(!(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_BIG_FORCE)) - return 0; - + + VECADD(lF[s->ij], lF[s->ij], s->f); + VECSUB(lF[s->kl], lF[s->kl], s->f); + sub_fmatrix_fmatrix(dFdX[s->ij].m, dFdX[s->ij].m, s->dfdx); sub_fmatrix_fmatrix(dFdX[s->kl].m, dFdX[s->kl].m, s->dfdx); add_fmatrix_fmatrix(dFdX[s->matrix_index].m, dFdX[s->matrix_index].m, s->dfdx); - } - - return 1; + } } DO_INLINE void calculateTriangleNormal(float to[3], lfVector *X, MFace mface) @@ -1275,7 +1227,7 @@ void cloth_calc_force(ClothModifierData *clmd, lfVector *lF, lfVector *lX, lfVec /* Collect forces and derivatives: F,dFdX,dFdV */ Cloth *cloth = clmd->clothObject; unsigned int i = 0; - float spring_air = clmd->sim_parms->Cvi * 0.01f; /* viscosity of air scaled in percent */ + float spring_air = clmd->sim_parms.Cvi * 0.01f; /* viscosity of air scaled in percent */ float gravity[3]; float tm2[3][3] = {{-spring_air,0,0}, {0,-spring_air,0},{0,0,-spring_air}}; ClothVertex *verts = cloth->verts; @@ -1286,7 +1238,8 @@ void cloth_calc_force(ClothModifierData *clmd, lfVector *lF, lfVector *lX, lfVec float kd, ks; LinkNode *search = cloth->springs; - VECCOPY(gravity, clmd->sim_parms->gravity); + + VECCOPY(gravity, clmd->sim_parms.gravity); mul_fvector_S(gravity, gravity, 0.001f); /* scale gravity force */ /* set dFdX jacobi matrix to zero */ @@ -1299,24 +1252,24 @@ void cloth_calc_force(ClothModifierData *clmd, lfVector *lF, lfVector *lX, lfVec submul_lfvectorS(lF, lV, spring_air, numverts); /* do goal stuff */ - if(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL) + if(clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_GOAL) { for(i = 0; i < numverts; i++) { if(verts [i].goal < SOFTGOALSNAP) { // current_position = xold + t * (newposition - xold) - VECSUB(tvect, cloth->xconst[i], cloth->xold[i]); + VECSUB(tvect, verts[i].xconst, verts[i].xold); mul_fvector_S(tvect, tvect, time); - VECADD(tvect, tvect, cloth->xold[i]); + VECADD(tvect, tvect, verts[i].xold); VECSUB(auxvect, tvect, lX[i]); - ks = 1.0f/(1.0f- verts [i].goal*clmd->sim_parms->goalspring)-1.0f ; + ks = 1.0f/(1.0f- verts [i].goal*clmd->sim_parms.goalspring)-1.0f ; VECADDS(lF[i], lF[i], auxvect, -ks); // calulate damping forces generated by goals - VECSUB(velgoal, cloth->xold[i], cloth->xconst[i]); - kd = clmd->sim_parms->goalfrict * 0.01f; // friction force scale taken from SB + VECSUB(velgoal,verts[i].xold, verts[i].xconst); + kd = clmd->sim_parms.goalfrict * 0.01f; // friction force scale taken from SB VECSUBADDSS(lF[i], velgoal, kd, lV[i], kd); } @@ -1329,7 +1282,7 @@ void cloth_calc_force(ClothModifierData *clmd, lfVector *lF, lfVector *lX, lfVec float speed[3] = {0.0f, 0.0f,0.0f}; float force[3]= {0.0f, 0.0f, 0.0f}; -// #pragma omp parallel for private (i) shared(lF) + #pragma omp parallel for private (i) shared(lF) for(i = 0; i < cloth->numverts; i++) { float vertexnormal[3]={0,0,0}; @@ -1353,42 +1306,24 @@ void cloth_calc_force(ClothModifierData *clmd, lfVector *lF, lfVector *lX, lfVec while(search) { // only handle active springs - // if(((clmd->sim_parms->flags & CSIMSETT_FLAG_TEARING_ENABLED) && !(springs[i].flags & CSPRING_FLAG_DEACTIVATE))|| !(clmd->sim_parms->flags & CSIMSETT_FLAG_TEARING_ENABLED)){} + // if(((clmd->sim_parms.flags & CSIMSETT_FLAG_TEARING_ENABLED) && !(springs[i].flags & CSPRING_FLAG_DEACTIVATE))|| !(clmd->sim_parms.flags & CSIMSETT_FLAG_TEARING_ENABLED)){} cloth_calc_spring_force(clmd, search->link, lF, lX, lV, dFdV, dFdX); search = search->next; } - if(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_BIG_FORCE) - { - if(cloth->numspringssave != cloth->numsprings) - { - cloth_bending_mode(clmd, 1); - } - } - else - { - if(cloth->numspringssave == cloth->numsprings) - { - cloth_bending_mode(clmd, 0); - } - } - // apply spring forces search = cloth->springs; while(search) { // only handle active springs - // if(((clmd->sim_parms->flags & CSIMSETT_FLAG_TEARING_ENABLED) && !(springs[i].flags & CSPRING_FLAG_DEACTIVATE))|| !(clmd->sim_parms->flags & CSIMSETT_FLAG_TEARING_ENABLED)) - if(!cloth_apply_spring_force(clmd, search->link, lF, lX, lV, dFdV, dFdX)) - break; + // if(((clmd->sim_parms.flags & CSIMSETT_FLAG_TEARING_ENABLED) && !(springs[i].flags & CSPRING_FLAG_DEACTIVATE))|| !(clmd->sim_parms.flags & CSIMSETT_FLAG_TEARING_ENABLED)) + cloth_apply_spring_force(clmd, search->link, lF, lX, lV, dFdV, dFdX); search = search->next; } - - clmd->sim_parms->flags &= ~CLOTH_SIMSETTINGS_FLAG_BIG_FORCE; } -void simulate_implicit_euler(lfVector *Vnew, lfVector *lX, lfVector *lV, lfVector *lF, fmatrix3x3 *dFdV, fmatrix3x3 *dFdX, float dt, fmatrix3x3 *A, lfVector *B, lfVector *dV, fmatrix3x3 *S, lfVector *z, fmatrix3x3 *P, fmatrix3x3 *Pinv) +void simulate_implicit_euler(lfVector *Vnew, lfVector *lX, lfVector *lV, lfVector *lF, fmatrix3x3 *dFdV, fmatrix3x3 *dFdX, float dt, fmatrix3x3 *A, lfVector *B, lfVector *dV, fmatrix3x3 *S, lfVector *z, lfVector *olddV, fmatrix3x3 *P, fmatrix3x3 *Pinv) { unsigned int numverts = dFdV[0].vcount; @@ -1396,46 +1331,48 @@ void simulate_implicit_euler(lfVector *Vnew, lfVector *lX, lfVector *lV, lfVecto initdiag_bfmatrix(A, I); zero_lfvector(dV, numverts); - subadd_bfmatrixS_bfmatrixS(A, dFdV, dt, dFdX, (dt*dt)); + subadd_bfmatrixS_bfmatrixS(A, dFdV, dt, dFdX, (dt*dt)); + mul_bfmatrix_lfvector(dFdXmV, dFdX, lV); + add_lfvectorS_lfvectorS(B, lF, dt, dFdXmV, (dt*dt), numverts); - // TODO: unstable with quality=5 + stiffness=7000 + no zero_lfvector() + itstart(); + cg_filtered(dV, A, B, z, S); /* conjugate gradient algorithm to solve Ax=b */ + // cg_filtered_pre(dV, A, B, z, olddV, P, Pinv, dt); - // TODO: unstable with quality=5 + stiffness=7000 - // cg_filtered_pre(dV, A, B, z, S, P, Pinv); + itend(); + // printf("cg_filtered calc time: %f\n", (float)itval()); + cp_lfvector(olddV, dV, numverts); + // advance velocities add_lfvector_lfvector(Vnew, lV, dV, numverts); + del_lfvector(dFdXmV); } int implicit_solver (Object *ob, float frame, ClothModifierData *clmd, ListBase *effectors) -{ - unsigned int i=0; +{ + unsigned int i=0, j; float step=0.0f, tf=1.0f; Cloth *cloth = clmd->clothObject; ClothVertex *verts = cloth->verts; unsigned int numverts = cloth->numverts; - float dt = 1.0f / clmd->sim_parms->stepsPerFrame; + float dt = 1.0f / clmd->sim_parms.stepsPerFrame; Implicit_Data *id = cloth->implicit; int result = 0; - float force = 0, lastforce = 0; - // lfVector *dx; - if(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL) /* do goal stuff */ + if(clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_GOAL) /* do goal stuff */ { for(i = 0; i < numverts; i++) { // update velocities with constrained velocities from pinned verts if(verts [i].goal >= SOFTGOALSNAP) { - float temp[3]; - VECSUB(temp, cloth->xconst[i], cloth->xold[i]); - VECSUB(id->z[i], temp, id->V[i]); - + VECSUB(id->V[i], verts[i].xconst, verts[i].xold); // VecMulf(id->V[i], 1.0 / dt); } } @@ -1445,43 +1382,13 @@ int implicit_solver (Object *ob, float frame, ClothModifierData *clmd, ListBase { effectors= pdInitEffectors(ob,NULL); - // clear constraint matrix from collisions - if(clmd->coll_parms->flags & CLOTH_COLLISIONSETTINGS_FLAG_ENABLED) - { - for(i = 0; i < id->S[0].vcount; i++) - { - if(!(verts [id->S[i].r].goal >= SOFTGOALSNAP)) - { - id->S[0].vcount = i-1; - break; - } - } - } - // calculate - cloth_calc_force(clmd, id->F, id->X, id->V, id->dFdV, id->dFdX, effectors, step ); + cloth_calc_force(clmd, id->F, id->X, id->V, id->dFdV, id->dFdX, effectors, step ); + simulate_implicit_euler(id->Vnew, id->X, id->V, id->F, id->dFdV, id->dFdX, dt, id->A, id->B, id->dV, id->S, id->z, id->olddV, id->P, id->Pinv); - // check for sleeping - // if(!(clmd->coll_parms->flags & CLOTH_SIMSETTINGS_FLAG_SLEEP)) - { - simulate_implicit_euler(id->Vnew, id->X, id->V, id->F, id->dFdV, id->dFdX, dt, id->A, id->B, id->dV, id->S, id->z, id->P, id->Pinv); + add_lfvector_lfvectorS(id->Xnew, id->X, id->Vnew, dt, numverts); - add_lfvector_lfvectorS(id->Xnew, id->X, id->Vnew, dt, numverts); - } - /* - dx = create_lfvector(numverts); - sub_lfvector_lfvector(dx, id->Xnew, id->X, numverts); - force = dot_lfvector(dx, dx, numverts); - del_lfvector(dx); - - if((force < 0.00001) && (lastforce >= force)) - clmd->coll_parms->flags |= CLOTH_SIMSETTINGS_FLAG_SLEEP; - else if((lastforce*2 < force)) - clmd->coll_parms->flags &= ~CLOTH_SIMSETTINGS_FLAG_SLEEP; - */ - lastforce = force; - - if(clmd->coll_parms->flags & CLOTH_COLLISIONSETTINGS_FLAG_ENABLED) + if(clmd->coll_parms.flags & CLOTH_COLLISIONSETTINGS_FLAG_ENABLED) { // collisions // itstart(); @@ -1489,42 +1396,46 @@ int implicit_solver (Object *ob, float frame, ClothModifierData *clmd, ListBase // update verts to current positions for(i = 0; i < numverts; i++) { - if(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL) /* do goal stuff */ + if(clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_GOAL) /* do goal stuff */ { if(verts [i].goal >= SOFTGOALSNAP) { float tvect[3] = {.0,.0,.0}; // VECSUB(tvect, id->Xnew[i], verts[i].xold); mul_fvector_S(tvect, id->V[i], step+dt); - VECADD(tvect, tvect, cloth->xold[i]); + VECADD(tvect, tvect, verts[i].xold); VECCOPY(id->Xnew[i], tvect); } } - VECCOPY(cloth->current_x[i], id->Xnew[i]); - VECSUB(cloth->current_v[i], cloth->current_x[i], cloth->current_xold[i]); - VECCOPY(cloth->v[i], cloth->current_v[i]); - } - - // call collision function - result = cloth_bvh_objcollision(clmd, step + dt, step, dt); - - // copy corrected positions back to simulation - if(result) - { - memcpy(cloth->current_xold, cloth->current_x, sizeof(lfVector) * numverts); - memcpy(id->Xnew, cloth->current_x, sizeof(lfVector) * numverts); + VECCOPY(verts[i].tx, id->Xnew[i]); - for(i = 0; i < numverts; i++) - { - VECCOPY(id->Vnew[i], cloth->current_v[i]); + VECSUB(verts[i].tv, verts[i].tx, verts[i].txold); + VECCOPY(verts[i].v, verts[i].tv); + } + + // call collision function + result = cloth_bvh_objcollision(clmd, step + dt, dt); + + // copy corrected positions back to simulation + for(i = 0; i < numverts; i++) + { + if(result) + { + // VECADD(verts[i].tx, verts[i].txold, verts[i].tv); + + VECCOPY(verts[i].txold, verts[i].tx); + + VECCOPY(id->Xnew[i], verts[i].tx); + + VECCOPY(id->Vnew[i], verts[i].tv); VecMulf(id->Vnew[i], 1.0f / dt); } - } - else - { - memcpy(cloth->current_xold, id->Xnew, sizeof(lfVector) * numverts); + else + { + VECCOPY(verts[i].txold, id->Xnew[i]); + } } // X = Xnew; @@ -1538,9 +1449,8 @@ int implicit_solver (Object *ob, float frame, ClothModifierData *clmd, ListBase // calculate cloth_calc_force(clmd, id->F, id->X, id->V, id->dFdV, id->dFdX, effectors, step); - simulate_implicit_euler(id->Vnew, id->X, id->V, id->F, id->dFdV, id->dFdX, dt / 2.0f, id->A, id->B, id->dV, id->S, id->z, id->P, id->Pinv); + simulate_implicit_euler(id->Vnew, id->X, id->V, id->F, id->dFdV, id->dFdX, dt / 2.0f, id->A, id->B, id->dV, id->S, id->z, id->olddV, id->P, id->Pinv); } - } else { @@ -1553,817 +1463,49 @@ int implicit_solver (Object *ob, float frame, ClothModifierData *clmd, ListBase // V = Vnew; cp_lfvector(id->V, id->Vnew, numverts); - + step += dt; if(effectors) pdEndEffectors(effectors); } - - if(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL) - { - for(i = 0; i < numverts; i++) + + for(i = 0; i < numverts; i++) + { + if(clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_GOAL) { if(verts [i].goal < SOFTGOALSNAP) { - VECCOPY(cloth->current_xold[i], id->X[i]); - VECCOPY(cloth->x[i], id->X[i]); + VECCOPY(verts[i].txold, id->X[i]); + VECCOPY(verts[i].x, id->X[i]); + VECCOPY(verts[i].v, id->V[i]); } else { - VECCOPY(cloth->current_xold[i], cloth->xconst[i]); - VECCOPY(cloth->x[i], cloth->xconst[i]); + VECCOPY(verts[i].txold, verts[i].xconst); + VECCOPY(verts[i].x, verts[i].xconst); + VECCOPY(verts[i].v, id->V[i]); } } + else + { + VECCOPY(verts[i].txold, id->X[i]); + VECCOPY(verts[i].x, id->X[i]); + VECCOPY(verts[i].v, id->V[i]); + } } - else - { - memcpy(cloth->current_xold, id->X, sizeof(lfVector) * numverts); - memcpy(cloth->x, id->X, sizeof(lfVector) * numverts); - } - - memcpy(cloth->v, id->V, sizeof(lfVector) * numverts); - return 1; } void implicit_set_positions (ClothModifierData *clmd) { Cloth *cloth = clmd->clothObject; - unsigned int numverts = cloth->numverts; + ClothVertex *verts = cloth->verts; + unsigned int numverts = cloth->numverts, i; Implicit_Data *id = cloth->implicit; - memcpy(id->X, cloth->x, sizeof(lfVector) * numverts); - memcpy(id->V, cloth->v, sizeof(lfVector) * numverts); -} - -unsigned int implicit_getcreate_S_index(ClothModifierData *clmd, unsigned int index) -{ - Cloth *cloth = clmd->clothObject; - Implicit_Data *id = cloth->implicit; - unsigned int i = 0, pinned = 0; - - pinned = id->S[0].vcount; - - for(i = 0; i < pinned; i++) - { - if(id->S[i].r == index) - { - return index; - } - } - - // create new PINNED entry in constraint matrix - id->S[0].vcount++; - id->S[pinned].c = id->S[pinned].r = index; - return pinned; -} - -int collisions_collision_response_static ( ClothModifierData *clmd, CollisionModifierData *collmd, CollisionPair *collpair ) -{ - - unsigned int i = 0; - int result = 0; - LinkNode *search = NULL; - Cloth *cloth1 = NULL; - float w1, w2, w3, u1, u2, u3; - float v1[3], v2[3], relativeVelocity[3]; - float magrelVel = 0.0; - float epsilon = clmd->coll_parms->epsilon; - - - cloth1 = clmd->clothObject; - - if(!collpair) - { - return 0; - } - - // TODO: check distance & calc normal - // calc distance + normal - collpair->distance = plNearestPoints( - cloth1->current_xold[collpair->point_indexA[0]], - cloth1->current_xold[collpair->point_indexA[1]], - cloth1->current_xold[collpair->point_indexA[2]], - collmd->current_x[collpair->point_indexB[0]].co, - collmd->current_x[collpair->point_indexB[1]].co, - collmd->current_x[collpair->point_indexB[2]].co, - collpair->pa,collpair->pb,collpair->vector); - - if (collpair->distance > (epsilon + ALMOST_ZERO)) - { - printf("collpair->distance > (epsilon + ALMOST_ZERO)\n"); - return 0; - } - - printf("IN1\n"); - - // compute barycentric coordinates for both collision points - collisions_compute_barycentric (collpair->pa, - cloth1->current_xold[collpair->point_indexA[0]], - cloth1->current_xold[collpair->point_indexA[1]], - cloth1->current_xold[collpair->point_indexA[2]], - &w1, &w2, &w3 ); - - collisions_compute_barycentric (collpair->pb, - collmd->current_x[collpair->point_indexB[0]].co, - collmd->current_x[collpair->point_indexB[1]].co, - collmd->current_x[collpair->point_indexB[2]].co, - &u1, &u2, &u3 ); - - // Calculate relative "velocity". - interpolateOnTriangle ( v1, cloth1->current_v[collpair->point_indexA[0]], cloth1->current_v[collpair->point_indexA[1]], cloth1->current_v[collpair->point_indexA[2]], w1, w2, w3 ); - - interpolateOnTriangle ( v2, collmd->current_v[collpair->point_indexB[0]].co, collmd->current_v[collpair->point_indexB[1]].co, collmd->current_v[collpair->point_indexB[2]].co, u1, u2, u3 ); - - VECSUB ( relativeVelocity, v1, v2 ); - - // Calculate the normal component of the relative velocity (actually only the magnitude - the direction is stored in 'normal'). - magrelVel = INPR ( relativeVelocity, collpair->normal ); - - // printf("magrelVel: %f\n", magrelVel); - - // Calculate masses of points. - - // If v_n_mag < 0 the edges are approaching each other. - if ( magrelVel < -ALMOST_ZERO ) - { - - // Calculate Impulse magnitude to stop all motion in normal direction. - // const double I_mag = v_n_mag / (1/m1 + 1/m2); - float magnitude_i = magrelVel / 2.0f; // TODO implement masses - float tangential[3], magtangent, magnormal, collvel[3]; - float vrel_t_pre[3]; - float vrel_t[3]; - double impulse; - float overlap = ( epsilon + ALMOST_ZERO-collpair->distance ); - - printf("magrelVel < -ALMOST_ZERO\n"); - - // calculateFrictionImpulse(tangential, relativeVelocity, collpair->normal, magrelVel, clmd->coll_parms.friction*0.01, magrelVel); - - // magtangent = INPR(tangential, tangential); - - // Apply friction impulse. - if ( magtangent < -ALMOST_ZERO ) - { - - // printf("friction applied: %f\n", magtangent); - // TODO check original code - } - - - impulse = -2.0f * magrelVel / ( 1.0 + w1*w1 + w2*w2 + w3*w3 ); - - // printf("impulse: %f\n", impulse); - - // face A - VECADDMUL ( cloth1->verts[collpair->point_indexA[0]].impulse, collpair->normal, w1 * impulse ); - cloth1->verts[collpair->point_indexA[0]].impulse_count++; - - VECADDMUL ( cloth1->verts[collpair->point_indexA[1]].impulse, collpair->normal, w2 * impulse ); - cloth1->verts[collpair->point_indexA[1]].impulse_count++; - - VECADDMUL ( cloth1->verts[collpair->point_indexA[2]].impulse, collpair->normal, w3 * impulse ); - cloth1->verts[collpair->point_indexA[2]].impulse_count++; - - // face B - /* - VECADDMUL ( collmd->verts[collpair->point_indexB[0]].impulse, collpair->normal, u1 * impulse ); - collmd->verts[collpair->point_indexB[0]].impulse_count++; - - VECADDMUL ( collmd->verts[collpair->point_indexB[1]].impulse, collpair->normal, u2 * impulse ); - collmd->verts[collpair->point_indexB[1]].impulse_count++; - - VECADDMUL ( collmd->verts[collpair->point_indexB[2]].impulse, collpair->normal, u3 * impulse ); - collmd->verts[collpair->point_indexB[2]].impulse_count++; - */ - - - result = 1; - - // printf("magnitude_i: %f\n", magnitude_i); // negative before collision in my case - - // Apply the impulse and increase impulse counters. - - } - - return result; -} - - -int collisions_collision_response_moving_tris(ClothModifierData *clmd, ClothModifierData *coll_clmd) -{ - return 0; -} - - -int collisions_collision_response_moving_edges(ClothModifierData *clmd, ClothModifierData *coll_clmd) -{ - return 0; -} - -void cloth_collision_static(ClothModifierData *clmd, LinkNode *collision_list) -{ - /* - CollPair *collpair = NULL; - Cloth *cloth1=NULL, *cloth2=NULL; - MFace *face1=NULL, *face2=NULL; - ClothVertex *verts1=NULL, *verts2=NULL; - double distance = 0; - float epsilon = clmd->coll_parms->epsilon; - unsigned int i = 0; - - for(i = 0; i < 4; i++) - { - collpair = (CollPair *)MEM_callocN(sizeof(CollPair), "cloth coll pair"); - - cloth1 = clmd->clothObject; - cloth2 = coll_clmd->clothObject; - - verts1 = cloth1->verts; - verts2 = cloth2->verts; - - face1 = &(cloth1->mfaces[tree1->tri_index]); - face2 = &(cloth2->mfaces[tree2->tri_index]); - - // check all possible pairs of triangles - if(i == 0) - { - collpair->ap1 = face1->v1; - collpair->ap2 = face1->v2; - collpair->ap3 = face1->v3; - - collpair->bp1 = face2->v1; - collpair->bp2 = face2->v2; - collpair->bp3 = face2->v3; - -} - - if(i == 1) - { - if(face1->v4) - { - collpair->ap1 = face1->v3; - collpair->ap2 = face1->v4; - collpair->ap3 = face1->v1; - - collpair->bp1 = face2->v1; - collpair->bp2 = face2->v2; - collpair->bp3 = face2->v3; -} - else - i++; -} - - if(i == 2) - { - if(face2->v4) - { - collpair->ap1 = face1->v1; - collpair->ap2 = face1->v2; - collpair->ap3 = face1->v3; - - collpair->bp1 = face2->v3; - collpair->bp2 = face2->v4; - collpair->bp3 = face2->v1; -} - else - i+=2; -} - - if(i == 3) - { - if((face1->v4)&&(face2->v4)) - { - collpair->ap1 = face1->v3; - collpair->ap2 = face1->v4; - collpair->ap3 = face1->v1; - - collpair->bp1 = face2->v3; - collpair->bp2 = face2->v4; - collpair->bp3 = face2->v1; -} - else - i++; -} - - - if(i < 4) - { - // calc distance + normal - distance = plNearestPoints( - verts1[collpair->ap1].txold, verts1[collpair->ap2].txold, verts1[collpair->ap3].txold, verts2[collpair->bp1].txold, verts2[collpair->bp2].txold, verts2[collpair->bp3].txold, collpair->pa,collpair->pb,collpair->vector); - - if (distance <= (epsilon + ALMOST_ZERO)) - { - // printf("dist: %f\n", (float)distance); - - // collpair->face1 = tree1->tri_index; - // collpair->face2 = tree2->tri_index; - - // VECCOPY(collpair->normal, collpair->vector); - // Normalize(collpair->normal); - - // collpair->distance = distance; - -} - else - { - MEM_freeN(collpair); -} -} - else - { - MEM_freeN(collpair); -} -} - */ -} - -int collisions_are_edges_adjacent(ClothModifierData *clmd, ClothModifierData *coll_clmd, EdgeCollPair *edgecollpair) -{ - Cloth *cloth1, *cloth2; - ClothVertex *verts1, *verts2; - float temp[3]; - /* - cloth1 = clmd->clothObject; - cloth2 = coll_clmd->clothObject; - - verts1 = cloth1->verts; - verts2 = cloth2->verts; - - VECSUB(temp, verts1[edgecollpair->p11].xold, verts2[edgecollpair->p21].xold); - if(ABS(INPR(temp, temp)) < ALMOST_ZERO) - return 1; - - VECSUB(temp, verts1[edgecollpair->p11].xold, verts2[edgecollpair->p22].xold); - if(ABS(INPR(temp, temp)) < ALMOST_ZERO) - return 1; - - VECSUB(temp, verts1[edgecollpair->p12].xold, verts2[edgecollpair->p21].xold); - if(ABS(INPR(temp, temp)) < ALMOST_ZERO) - return 1; - - VECSUB(temp, verts1[edgecollpair->p12].xold, verts2[edgecollpair->p22].xold); - if(ABS(INPR(temp, temp)) < ALMOST_ZERO) - return 1; - */ - return 0; -} - - -void collisions_collision_moving_edges(ClothModifierData *clmd, ClothModifierData *coll_clmd, CollisionTree *tree1, CollisionTree *tree2) -{ - /* - EdgeCollPair edgecollpair; - Cloth *cloth1=NULL, *cloth2=NULL; - MFace *face1=NULL, *face2=NULL; - ClothVertex *verts1=NULL, *verts2=NULL; - double distance = 0; - float epsilon = clmd->coll_parms->epsilon; - unsigned int i = 0, j = 0, k = 0; - int numsolutions = 0; - float a[3], b[3], c[3], d[3], e[3], f[3], solution[3]; - - cloth1 = clmd->clothObject; - cloth2 = coll_clmd->clothObject; - - verts1 = cloth1->verts; - verts2 = cloth2->verts; - - face1 = &(cloth1->mfaces[tree1->tri_index]); - face2 = &(cloth2->mfaces[tree2->tri_index]); - - for( i = 0; i < 5; i++) - { - if(i == 0) - { - edgecollpair.p11 = face1->v1; - edgecollpair.p12 = face1->v2; -} - else if(i == 1) - { - edgecollpair.p11 = face1->v2; - edgecollpair.p12 = face1->v3; -} - else if(i == 2) - { - if(face1->v4) - { - edgecollpair.p11 = face1->v3; - edgecollpair.p12 = face1->v4; -} - else - { - edgecollpair.p11 = face1->v3; - edgecollpair.p12 = face1->v1; - i+=5; // get out of here after this edge pair is handled -} -} - else if(i == 3) - { - if(face1->v4) - { - edgecollpair.p11 = face1->v4; - edgecollpair.p12 = face1->v1; -} - else - continue; -} - else - { - edgecollpair.p11 = face1->v3; - edgecollpair.p12 = face1->v1; -} - - - for( j = 0; j < 5; j++) - { - if(j == 0) - { - edgecollpair.p21 = face2->v1; - edgecollpair.p22 = face2->v2; -} - else if(j == 1) - { - edgecollpair.p21 = face2->v2; - edgecollpair.p22 = face2->v3; -} - else if(j == 2) - { - if(face2->v4) - { - edgecollpair.p21 = face2->v3; - edgecollpair.p22 = face2->v4; -} - else - { - edgecollpair.p21 = face2->v3; - edgecollpair.p22 = face2->v1; -} -} - else if(j == 3) - { - if(face2->v4) - { - edgecollpair.p21 = face2->v4; - edgecollpair.p22 = face2->v1; -} - else - continue; -} - else - { - edgecollpair.p21 = face2->v3; - edgecollpair.p22 = face2->v1; -} - - - if(!collisions_are_edges_adjacent(clmd, coll_clmd, &edgecollpair)) - { - VECSUB(a, verts1[edgecollpair.p12].xold, verts1[edgecollpair.p11].xold); - VECSUB(b, verts1[edgecollpair.p12].v, verts1[edgecollpair.p11].v); - VECSUB(c, verts1[edgecollpair.p21].xold, verts1[edgecollpair.p11].xold); - VECSUB(d, verts1[edgecollpair.p21].v, verts1[edgecollpair.p11].v); - VECSUB(e, verts2[edgecollpair.p22].xold, verts1[edgecollpair.p11].xold); - VECSUB(f, verts2[edgecollpair.p22].v, verts1[edgecollpair.p11].v); - - numsolutions = collisions_get_collision_time(a, b, c, d, e, f, solution); - - for (k = 0; k < numsolutions; k++) - { - if ((solution[k] >= 0.0) && (solution[k] <= 1.0)) - { - float out_collisionTime = solution[k]; - - // TODO: check for collisions - - // TODO: put into (edge) collision list - - printf("Moving edge found!\n"); -} -} -} -} -} - */ -} - -void collisions_collision_moving_tris(ClothModifierData *clmd, ClothModifierData *coll_clmd, CollisionTree *tree1, CollisionTree *tree2) -{ - /* - CollPair collpair; - Cloth *cloth1=NULL, *cloth2=NULL; - MFace *face1=NULL, *face2=NULL; - ClothVertex *verts1=NULL, *verts2=NULL; - double distance = 0; - float epsilon = clmd->coll_parms->epsilon; - unsigned int i = 0, j = 0, k = 0; - int numsolutions = 0; - float a[3], b[3], c[3], d[3], e[3], f[3], solution[3]; - - for(i = 0; i < 2; i++) - { - cloth1 = clmd->clothObject; - cloth2 = coll_clmd->clothObject; - - verts1 = cloth1->verts; - verts2 = cloth2->verts; - - face1 = &(cloth1->mfaces[tree1->tri_index]); - face2 = &(cloth2->mfaces[tree2->tri_index]); - - // check all possible pairs of triangles - if(i == 0) - { - collpair.ap1 = face1->v1; - collpair.ap2 = face1->v2; - collpair.ap3 = face1->v3; - - collpair.pointsb[0] = face2->v1; - collpair.pointsb[1] = face2->v2; - collpair.pointsb[2] = face2->v3; - collpair.pointsb[3] = face2->v4; -} - - if(i == 1) - { - if(face1->v4) - { - collpair.ap1 = face1->v3; - collpair.ap2 = face1->v4; - collpair.ap3 = face1->v1; - - collpair.pointsb[0] = face2->v1; - collpair.pointsb[1] = face2->v2; - collpair.pointsb[2] = face2->v3; - collpair.pointsb[3] = face2->v4; -} - else - i++; -} - - // calc SIPcode (?) - - if(i < 2) - { - VECSUB(a, verts1[collpair.ap2].xold, verts1[collpair.ap1].xold); - VECSUB(b, verts1[collpair.ap2].v, verts1[collpair.ap1].v); - VECSUB(c, verts1[collpair.ap3].xold, verts1[collpair.ap1].xold); - VECSUB(d, verts1[collpair.ap3].v, verts1[collpair.ap1].v); - - for(j = 0; j < 4; j++) - { - if((j==3) && !(face2->v4)) - break; - - VECSUB(e, verts2[collpair.pointsb[j]].xold, verts1[collpair.ap1].xold); - VECSUB(f, verts2[collpair.pointsb[j]].v, verts1[collpair.ap1].v); - - numsolutions = collisions_get_collision_time(a, b, c, d, e, f, solution); - - for (k = 0; k < numsolutions; k++) - { - if ((solution[k] >= 0.0) && (solution[k] <= 1.0)) - { - float out_collisionTime = solution[k]; - - // TODO: check for collisions - - // TODO: put into (point-face) collision list - - printf("Moving found!\n"); - -} -} - - // TODO: check borders for collisions -} - -} -} - */ -} - -void collisions_collision_moving(ClothModifierData *clmd, ClothModifierData *coll_clmd, CollisionTree *tree1, CollisionTree *tree2) -{ - /* - // TODO: check for adjacent - collisions_collision_moving_edges(clmd, coll_clmd, tree1, tree2); - - collisions_collision_moving_tris(clmd, coll_clmd, tree1, tree2); - collisions_collision_moving_tris(coll_clmd, clmd, tree2, tree1); - */ -} - -// cloth - object collisions -int cloth_bvh_objcollision(ClothModifierData * clmd, float step, float prevstep, float dt) -{ - - Base *base = NULL; - CollisionModifierData *collmd = NULL; - Cloth *cloth = NULL; - Object *ob2 = NULL; - BVH *bvh1 = NULL, *bvh2 = NULL, *self_bvh; - LinkNode *collision_list = NULL; - unsigned int i = 0, j = 0, index; - int collisions = 0, count = 0; - float (*current_x)[3]; - Implicit_Data *id = NULL; - int ret = 0; - - if (!(((Cloth *)clmd->clothObject)->tree)) - { - printf("No BVH found\n"); - return 0; - } - - cloth = clmd->clothObject; - bvh1 = cloth->tree; - self_bvh = cloth->selftree; - id = cloth->implicit; - - //////////////////////////////////////////////////////////// - // static collisions - //////////////////////////////////////////////////////////// - - // update cloth bvh - bvh_update_from_float3 ( bvh1, cloth->current_xold, cloth->numverts, cloth->current_x, 0 ); // 0 means STATIC, 1 means MOVING (see later in this function) - - // check all collision objects - for ( base = G.scene->base.first; base; base = base->next ) - { - ob2 = base->object; - collmd = ( CollisionModifierData * ) modifiers_findByType ( ob2, eModifierType_Collision ); - - if ( !collmd ) - continue; - - // check if there is a bounding volume hierarchy - if ( collmd->tree ) - { - bvh2 = collmd->tree; - - // update position + bvh of collision object - collision_move_object ( collmd, step, prevstep ); - bvh_update_from_mvert ( collmd->tree, collmd->current_x, collmd->numverts, NULL, 0 ); - - // fill collision list - collisions += bvh_traverse ( bvh1->root, bvh2->root, &collision_list ); - - // call static collision response - if ( collision_list ) - { - LinkNode *search = collision_list; - - while ( search ) - { - collisions_collision_response_static(clmd, collmd, (CollisionPair *)search->link); - - search = search->next; - } - } - - // free collision list - if ( collision_list ) - { - LinkNode *search = collision_list; - - while ( search ) - { - CollisionPair *coll_pair = search->link; - - MEM_freeN ( coll_pair ); - search = search->next; - } - BLI_linklist_free ( collision_list,NULL ); - - collision_list = NULL; - } - } - } - - // vertex weight = 2 - - for(i = 0; i < cloth->numverts; i++) - if ((cloth->verts[i].impulse_count > 0) && !(cloth->verts[i].flags & CVERT_FLAG_PINNED)) - { - printf("applying impulse\n"); - - VECADDS(cloth->current_v[i], cloth->current_v[i], cloth->verts[i].impulse, 1.0 / (cloth->verts[i].impulse_count * 2.0)); - - // reset - cloth->verts[i].impulse_count = 0; - cloth->verts[i].impulse[0] = 0.0; - cloth->verts[i].impulse[1] = 0.0; - cloth->verts[i].impulse[2] = 0.0; - - ret = 1; - } - - ////////////////////////////////////////////// - // update velocities + positions - ////////////////////////////////////////////// - for(i = 0; i < cloth->numverts; i++) - { - VECADD(cloth->current_x[i], cloth->current_xold[i], cloth->current_v[i]); - } - ////////////////////////////////////////////// - - - // Test on *simple* selfcollisions - collisions = 1; - count = 0; - current_x = cloth->current_x; // needed for openMP - /* - // #pragma omp parallel for private(i,j, collisions) shared(current_x) - // for ( count = 0; count < 6; count++ ) - { - collisions = 0; - - for ( i = 0; i < cloth->numverts; i++ ) - { - float mindistance1 = cloth->verts[i].collball; - - for ( j = i + 1; j < cloth->numverts; j++ ) - { - float temp[3]; - float length = 0; - - float mindistance2 = cloth->verts[j].collball; - - if ( clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL ) - { - if ( ( cloth->verts [i].goal >= SOFTGOALSNAP ) - && ( cloth->verts [j].goal >= SOFTGOALSNAP ) ) - { - continue; - } - } - - // check for adjacent points - if ( BLI_edgehash_haskey ( cloth->edgehash, i, j ) ) - { - continue; - } - - VECSUB ( temp, current_x[i], current_x[j] ); - - length = Normalize ( temp ); - - if ( length < ((mindistance1 + mindistance2)) ) - { - float correction = ((mindistance1 + mindistance2)) - length; - - if ( ( clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL ) && ( cloth->verts [i].goal >= SOFTGOALSNAP ) ) - { - VecMulf ( temp, -correction ); - VECADD ( current_x[j], current_x[j], temp ); - } - else if ( ( clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL ) && ( cloth->verts [j].goal >= SOFTGOALSNAP ) ) - { - VecMulf ( temp, correction ); - VECADD ( current_x[i], current_x[i], temp ); - } - else - { - unsigned int pinned = id->S[0].vcount; - - printf("correction: %f\n", correction); - - VecMulf ( temp, -correction*0.5 ); - VECADD ( current_x[j], current_x[j], temp ); - VECSUB ( cloth->current_v[j], cloth->current_x[j], cloth->current_xold[j] ); - - index = implicit_getcreate_S_index(clmd, j); - id->S[index].pinned = 1; - - VECSUB ( current_x[i], current_x[i], temp ); - VECSUB ( cloth->current_v[i], cloth->current_x[i], cloth->current_xold[i] ); - - index = implicit_getcreate_S_index(clmd, i); - id->S[index].pinned = 1; - - cloth_add_spring (clmd, i, j, mindistance1 + mindistance2, CLOTH_SPRING_TYPE_COLLISION); - } - - collisions = 1; - } - } - } - } - */ - - ////////////////////////////////////////////// - // SELFCOLLISIONS: update velocities - ////////////////////////////////////////////// - /* - for ( i = 0; i < cloth->numverts; i++ ) - { - VECSUB ( cloth->current_v[i], cloth->current_x[i], cloth->current_xold[i] ); - } - */ - ////////////////////////////////////////////// - - return ret; + for(i = 0; i < numverts; i++) + { + VECCOPY(id->X[i], verts[i].x); + VECCOPY(id->V[i], verts[i].v); + } } diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c index e7ce752424d..3b69f47b1f4 100644 --- a/source/blender/blenkernel/intern/modifier.c +++ b/source/blender/blenkernel/intern/modifier.c @@ -75,7 +75,6 @@ #include "BKE_main.h" #include "BKE_anim.h" #include "BKE_bad_level_calls.h" -#include "BKE_collisions.h" #include "BKE_curve.h" #include "BKE_customdata.h" #include "BKE_global.h" @@ -2727,7 +2726,7 @@ static void displaceModifier_foreachIDLink(ModifierData *md, Object *ob, { DisplaceModifierData *dmd = (DisplaceModifierData*) md; - walk(userData, ob, (ID **)&dmd->texture); + walk(userData, ob, &dmd->texture); displaceModifier_foreachObjectLink(md, ob, (ObjectWalkFunc) walk, userData); } @@ -4947,15 +4946,9 @@ static void softbodyModifier_deformVerts( static void clothModifier_initData(ModifierData *md) { ClothModifierData *clmd = (ClothModifierData*) md; - - clmd->sim_parms = MEM_callocN(sizeof(SimulationSettings), - "cloth sim parms"); - clmd->coll_parms = MEM_callocN(sizeof(CollisionSettings), - "cloth coll parms"); - cloth_init (clmd); } -/* + static void clothModifier_deformVerts( ModifierData *md, Object *ob, DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts) @@ -4978,23 +4971,6 @@ static void clothModifier_deformVerts( if(dm) dm->release(dm); } -*/ - -static DerivedMesh *clothModifier_applyModifier( - ModifierData *md, Object *ob, DerivedMesh *derivedData, - int useRenderParams, int isFinalCalc) -{ - ClothModifierData *clmd = (ClothModifierData*) md; - DerivedMesh *result=NULL; - - result = clothModifier_do(clmd, ob, derivedData, useRenderParams, isFinalCalc); - - if(result) - { - return result; - } - return derivedData; -} static void clothModifier_updateDepgraph( ModifierData *md, DagForest *forest, Object *ob, @@ -5011,13 +4987,14 @@ static void clothModifier_updateDepgraph( Object *ob1= base->object; if(ob1 != ob) { - CollisionModifierData *collmd = (CollisionModifierData *)modifiers_findByType(ob1, eModifierType_Collision); - if(collmd) - { - DagNode *curNode = dag_get_node(forest, ob1); - - dag_add_relation(forest, curNode, obNode, DAG_RL_DATA_DATA|DAG_RL_OB_DATA); - + ClothModifierData *coll_clmd = (ClothModifierData *)modifiers_findByType(ob1, eModifierType_Cloth); + if(coll_clmd) + { + if (coll_clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_COLLOBJ) + { + DagNode *curNode = dag_get_node(forest, ob1); + dag_add_relation(forest, curNode, obNode, DAG_RL_DATA_DATA|DAG_RL_OB_DATA); + } } } } @@ -5026,12 +5003,12 @@ static void clothModifier_updateDepgraph( CustomDataMask clothModifier_requiredDataMask(ModifierData *md) { - ClothModifierData *clmd = (ClothModifierData *)md; + ClothModifierData *clmd = (HookModifierData *)md; CustomDataMask dataMask = 0; /* ask for vertexgroups if we need them */ - if(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL) - if (clmd->sim_parms->vgroup_mass > 0) + if(clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_GOAL) + if (clmd->sim_parms.vgroup_mass > 0) dataMask |= (1 << CD_MDEFORMVERT); return dataMask; @@ -5049,156 +5026,11 @@ static void clothModifier_freeData(ModifierData *md) if (clmd) { - - clmd->sim_parms->flags &= ~CLOTH_SIMSETTINGS_FLAG_CCACHE_PROTECT; + clmd->sim_parms.flags &= ~CLOTH_SIMSETTINGS_FLAG_CCACHE_PROTECT; cloth_free_modifier (clmd); - - MEM_freeN(clmd->sim_parms); - MEM_freeN(clmd->coll_parms); } } -/* Collision */ - -static void collisionModifier_initData(ModifierData *md) -{ - CollisionModifierData *collmd = (CollisionModifierData*) md; - - collmd->x = NULL; - collmd->xnew = NULL; - collmd->current_x = NULL; - collmd->current_xnew = NULL; - collmd->current_v = NULL; - collmd->time = -1; - collmd->numverts = 0; - collmd->tree = NULL; -} - -static void collisionModifier_freeData(ModifierData *md) -{ - CollisionModifierData *collmd = (CollisionModifierData*) md; - - if (collmd) - { - if(collmd->tree) - bvh_free(collmd->tree); - if(collmd->x) - MEM_freeN(collmd->x); - if(collmd->xnew) - MEM_freeN(collmd->xnew); - if(collmd->current_x) - MEM_freeN(collmd->current_x); - if(collmd->current_xnew) - MEM_freeN(collmd->current_xnew); - if(collmd->current_v) - MEM_freeN(collmd->current_v); - - collmd->x = NULL; - collmd->xnew = NULL; - collmd->current_x = NULL; - collmd->current_xnew = NULL; - collmd->current_v = NULL; - collmd->time = -1; - collmd->numverts = 0; - collmd->tree = NULL; - } -} - -static int collisionModifier_dependsOnTime(ModifierData *md) -{ - return 1; -} - -static void collisionModifier_deformVerts( - ModifierData *md, Object *ob, DerivedMesh *derivedData, - float (*vertexCos)[3], int numVerts) -{ - CollisionModifierData *collmd = (CollisionModifierData*) md; - DerivedMesh *dm = NULL; - float current_time = 0; - unsigned int numverts = 0, i = 0; - MVert *tempVert = NULL; - - // if possible use/create DerivedMesh - - if(derivedData) dm = CDDM_copy(derivedData); - else if(ob->type==OB_MESH) dm = CDDM_from_mesh(ob->data, ob); - - if(!ob->pd) - { - printf("collisionModifier_deformVerts: Should not happen!\n"); - return; - } - - if(dm) - { - CDDM_apply_vert_coords(dm, vertexCos); - CDDM_calc_normals(dm); - - - current_time = bsystem_time ( ob, ( float ) G.scene->r.cfra, 0.0 ); - - if(current_time > collmd->time) - { - numverts = dm->getNumVerts ( dm ); - - // check if mesh has changed - if(collmd->x && (numverts != collmd->numverts)) - collisionModifier_freeData((ModifierData *)collmd); - - if(collmd->time == -1) // first time - { - collmd->x = dm->dupVertArray(dm); // frame start position - - for ( i = 0; i < numverts; i++ ) - { - // we save global positions - Mat4MulVecfl ( ob->obmat, collmd->x[i].co ); - } - - collmd->xnew = MEM_dupallocN(collmd->x); // frame end position - collmd->current_x = MEM_dupallocN(collmd->x); // inter-frame - collmd->current_xnew = MEM_dupallocN(collmd->x); // inter-frame - collmd->current_v = MEM_dupallocN(collmd->x); // inter-frame - - collmd->numverts = numverts; - - // TODO: epsilon - // create bounding box hierarchy - collmd->tree = bvh_build_from_mvert(dm->getFaceArray(dm), dm->getNumFaces(dm), collmd->current_x, numverts, ob->pd->pdef_sbift); - } - else if(numverts == collmd->numverts) - { - // put positions to old positions - tempVert = collmd->x; - collmd->x = collmd->xnew; - collmd->xnew = tempVert; - - memcpy(collmd->xnew, dm->getVertArray(dm), numverts*sizeof(MVert)); - - for ( i = 0; i < numverts; i++ ) - { - // we save global positions - Mat4MulVecfl ( ob->obmat, collmd->xnew[i].co ); - } - - memcpy(collmd->current_xnew, dm->getVertArray(dm), numverts*sizeof(MVert)); - memcpy(collmd->current_x, dm->getVertArray(dm), numverts*sizeof(MVert)); - - // recalc static bounding boxes - bvh_update_from_mvert(collmd->tree, collmd->current_x, numverts, NULL, 0); - - printf("bvh_update_from_mvert\n"); - } - - collmd->time = current_time; - } - } - - if(dm) - dm->release(dm); -} - /* Boolean */ static void booleanModifier_copyData(ModifierData *md, ModifierData *target) @@ -7010,10 +6842,10 @@ ModifierTypeInfo *modifierType_getInfo(ModifierType type) mti->deformVerts = softbodyModifier_deformVerts; mti = INIT_TYPE(Cloth); - mti->type = eModifierTypeType_Nonconstructive; + mti->type = eModifierTypeType_OnlyDeform; mti->initData = clothModifier_initData; - mti->flags = eModifierTypeFlag_AcceptsMesh - | eModifierTypeFlag_RequiresOriginalData; + mti->flags = eModifierTypeFlag_AcceptsCVs; + // | eModifierTypeFlag_RequiresOriginalData; // | eModifierTypeFlag_SupportsMapping // | eModifierTypeFlag_SupportsEditmode // | eModifierTypeFlag_EnableInEditmode; @@ -7021,19 +6853,8 @@ ModifierTypeInfo *modifierType_getInfo(ModifierType type) mti->freeData = clothModifier_freeData; mti->requiredDataMask = clothModifier_requiredDataMask; // mti->copyData = clothModifier_copyData; - // mti->deformVerts = clothModifier_deformVerts; - mti->applyModifier = clothModifier_applyModifier; + mti->deformVerts = clothModifier_deformVerts; mti->updateDepgraph = clothModifier_updateDepgraph; - - mti = INIT_TYPE(Collision); - mti->type = eModifierTypeType_OnlyDeform; - mti->initData = collisionModifier_initData; - mti->flags = eModifierTypeFlag_AcceptsMesh - | eModifierTypeFlag_RequiresOriginalData; - mti->dependsOnTime = collisionModifier_dependsOnTime; - mti->freeData = collisionModifier_freeData; - mti->deformVerts = collisionModifier_deformVerts; - // mti->copyData = collisionModifier_copyData; mti = INIT_TYPE(Boolean); mti->type = eModifierTypeType_Nonconstructive; @@ -7293,11 +7114,11 @@ int modifiers_isSoftbodyEnabled(Object *ob) return (md && md->mode & (eModifierMode_Realtime | eModifierMode_Render)); } -ClothModifierData *modifiers_isClothEnabled(Object *ob) +ModifierData * modifiers_isClothEnabled(Object *ob) { - ClothModifierData *clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth); + ModifierData *md = modifiers_findByType(ob, eModifierType_Cloth); - return clmd; + return md; } int modifiers_isParticleEnabled(Object *ob) diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index d215bdf67cd..37d15b65de5 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -2986,12 +2986,14 @@ static void direct_link_modifiers(FileData *fd, ListBase *lb) ClothModifierData *clmd = (ClothModifierData*) md; clmd->clothObject = NULL; - + /* clmd->sim_parms= newdataadr(fd, clmd->sim_parms); clmd->coll_parms= newdataadr(fd, clmd->coll_parms); + */ } else if (md->type==eModifierType_Collision) { + /* CollisionModifierData *collmd = (CollisionModifierData*) md; collmd->x = NULL; @@ -3001,6 +3003,7 @@ static void direct_link_modifiers(FileData *fd, ListBase *lb) collmd->time = -1; collmd->numverts = 0; collmd->tree = NULL; + */ } else if (md->type==eModifierType_Hook) { HookModifierData *hmd = (HookModifierData*) md; diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c index 275e3b18c4c..3326d38c56f 100644 --- a/source/blender/blenloader/intern/writefile.c +++ b/source/blender/blenloader/intern/writefile.c @@ -827,8 +827,10 @@ static void write_modifiers(WriteData *wd, ListBase *modbase) } else if(md->type==eModifierType_Cloth) { ClothModifierData *clmd = (ClothModifierData*) md; + /* writestruct(wd, DATA, "SimulationSettings", 1, clmd->sim_parms); writestruct(wd, DATA, "CollisionSettings", 1, clmd->coll_parms); + */ } else if (md->type==eModifierType_MeshDeform) { MeshDeformModifierData *mmd = (MeshDeformModifierData*) md; diff --git a/source/blender/makesdna/DNA_cloth_types.h b/source/blender/makesdna/DNA_cloth_types.h index 4d8fbf1a6fc..2bbe328d170 100644 --- a/source/blender/makesdna/DNA_cloth_types.h +++ b/source/blender/makesdna/DNA_cloth_types.h @@ -32,7 +32,64 @@ #ifndef DNA_CLOTH_TYPES_H #define DNA_CLOTH_TYPES_H -typedef struct SimulationSettings { +#include "DNA_listBase.h" + + +/** +* Pin and unpin frames are the frames on which the vertices stop moving. +* They will assume the position they had prior to pinFrame until unpinFrame +* is reached. +*/ +typedef struct ClothVertex +{ + int flags; /* General flags per vertex. */ + float v [3]; /* The velocity of the point. */ + float xconst [3]; /* constrained position */ + float x [3]; /* The current position of this vertex. */ + float xold [3]; /* The previous position of this vertex.*/ + float tx [3]; /* temporary position */ + float txold [3]; /* temporary old position */ + float tv[3]; /* temporary "velocity", mostly used as tv = tx-txold */ + float mass; /* mass / weight of the vertex */ + float goal; /* goal, from SB */ + float impulse[3]; /* used in collision.c */ + unsigned int impulse_count; /* same as above */ +} +ClothVertex; + + +/** +* The definition of a spring. +*/ +typedef struct ClothSpring +{ + int ij; /* Pij from the paper, one end of the spring. */ + int kl; /* Pkl from the paper, one end of the spring. */ + float restlen; /* The original length of the spring. */ + int matrix_index; /* needed for implicit solver (fast lookup) */ + int type; /* types defined in BKE_cloth.h ("springType") */ + int flags; /* defined in BKE_cloth.h, e.g. deactivated due to tearing */ + float dfdx[3][3]; + float dfdv[3][3]; + float f[3]; +} +ClothSpring; + + + +/** +* This struct contains all the global data required to run a simulation. +* At the time of this writing, this structure contains data appropriate +* to run a simulation as described in Deformation Constraints in a +* Mass-Spring Model to Describe Rigid Cloth Behavior by Xavier Provot. +* +* I've tried to keep similar, if not exact names for the variables as +* are presented in the paper. Where I've changed the concept slightly, +* as in stepsPerFrame comapred to the time step in the paper, I've used +* variables with different names to minimize confusion. +**/ +typedef struct SimulationSettings +{ short vgroup_mass; /* optional vertexgroup name for assigning weight. */ short pad; float mingoal; /* see SB */ @@ -55,23 +112,56 @@ typedef struct SimulationSettings { float eff_force_scale;/* Scaling of effector forces (see softbody_calc_forces).*/ float eff_wind_scale; /* Scaling of effector wind (see softbody_calc_forces). */ float sim_time_old; + struct LinkNode *cache; float defgoal; - float goalfrict; + int goalfrict; float goalspring; int maxspringlen; /* in percent!; if tearing enabled, a spring will get cut */ int lastframe; /* frame on which simulation stops */ int firstframe; /* frame on which simulation starts */ -} SimulationSettings; + struct Object *ob; +} +SimulationSettings; -typedef struct CollisionSettings { + +typedef struct CollisionSettings +{ float epsilon; /* The radius of a particle in the cloth. */ float self_friction; /* Fiction/damping with self contact. */ float friction; /* Friction/damping applied on contact with other object.*/ short collision_type; /* which collision system is used. */ short loop_count; /* How many iterations for the collision loop. */ + struct LinkNode *collision_list; /* e.g. pointer to temp memory for collisions */ int flags; /* collision flags defined in BKE_cloth.h */ - float selfepsilon; -} CollisionSettings; + int pad; +} +CollisionSettings; +/** +* This structure describes a cloth object against which the +* simulation can run. +* +* The m and n members of this structure represent the assumed +* rectangular ordered grid for which the original paper is written. +* At some point they need to disappear and we need to determine out +* own connectivity of the mesh based on the actual edges in the mesh. +* +**/ +typedef struct Cloth +{ + struct ClothVertex *verts; /* The vertices that represent this cloth. */ + struct LinkNode *springs; /* The springs connecting the mesh. */ + unsigned int numverts; /* The number of verts == m * n. */ + unsigned int numsprings; /* The count of springs. */ + unsigned int numfaces; + unsigned char old_solver_type; + unsigned char pad2; + short pad3; + void *tree; /* collision tree for this cloth object */ + struct MFace *mfaces; + void *implicit; /* our implicit solver connects to this pointer */ +} +Cloth; + #endif diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h index 384ac37484d..f8b6f4202a5 100644 --- a/source/blender/makesdna/DNA_modifier_types.h +++ b/source/blender/makesdna/DNA_modifier_types.h @@ -7,6 +7,8 @@ #define MODSTACK_DEBUG 1 +#include "DNA_cloth_types.h" + /* WARNING ALERT! TYPEDEF VALUES ARE WRITTEN IN FILES! SO DO NOT CHANGE! */ typedef enum ModifierType { @@ -347,8 +349,8 @@ typedef struct ClothModifierData { ModifierData modifier; struct Cloth *clothObject; /* The internal data structure for cloth. */ - struct SimulationSettings *sim_parms; /* definition is in DNA_cloth_types.h */ - struct CollisionSettings *coll_parms; /* definition is in DNA_cloth_types.h */ + struct SimulationSettings sim_parms; /* definition is in DNA_cloth_types.h */ + struct CollisionSettings coll_parms; /* definition is in DNA_cloth_types.h */ } ClothModifierData; typedef struct CollisionModifierData { diff --git a/source/blender/src/buttons_object.c b/source/blender/src/buttons_object.c index f71f6adb051..662e0df093b 100644 --- a/source/blender/src/buttons_object.c +++ b/source/blender/src/buttons_object.c @@ -48,7 +48,6 @@ #include "BKE_action.h" #include "BKE_cloth.h" -#include "BKE_collisions.h" #include "BKE_global.h" #include "BKE_main.h" #include "BKE_library.h" @@ -2989,29 +2988,66 @@ void do_effects_panels(unsigned short event) allqueue(REDRAWVIEW3D, 0); break; case B_CLOTH_CLEARCACHEALL: + { + ClothModifierData *clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth); + if(clmd) { - ClothModifierData *clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth); - if(clmd) + CFRA= 1; + update_for_newframe_muted(); + DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA); + cloth_clear_cache(ob, clmd, 2); + allqueue(REDRAWBUTSOBJECT, 0); + allqueue(REDRAWVIEW3D, 0); + } + } + break; + case B_CLOTH_CLEARCACHEFRAME: + { + ClothModifierData *clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth); + if(clmd) + { + cloth_clear_cache(ob, clmd, MAX2(2.0,G.scene->r.cfra + 1.0)); + allqueue(REDRAWBUTSOBJECT, 0); + } + } + break; + case B_CLOTH_CHANGEPREROLL: + { + ClothModifierData *clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth); + if(clmd) + { + if(clmd->sim_parms.cache) { CFRA= 1; update_for_newframe_muted(); DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA); - cloth_clear_cache(ob, clmd, 2); allqueue(REDRAWBUTSOBJECT, 0); allqueue(REDRAWVIEW3D, 0); - } - } - break; - case B_CLOTH_RENEW: - { - ClothModifierData *clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth); - if(clmd) - { - do_object_panels(B_CLOTH_CLEARCACHEALL); - cloth_free_modifier (clmd); } } - break; + } + break; + case B_CLOTH_DEL_VG: + { + ClothModifierData *clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth); + if(clmd) + { + clmd->sim_parms.vgroup_mass = 0; + do_object_panels(B_CLOTH_RENEW); + } + allqueue(REDRAWBUTSOBJECT, 0); + } + break; + case B_CLOTH_RENEW: + { + ClothModifierData *clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth); + if(clmd) + { + do_object_panels(B_CLOTH_CLEARCACHEALL); + cloth_free_modifier (clmd); + } + } + break; default: if(event>=B_SELEFFECT && eventsim_parms->flags, 0, 0, 0, 0, "Sets object to become a cloth collision object"); + but = uiDefButBitI(block, TOG, CLOTH_SIMSETTINGS_FLAG_COLLOBJ, B_EFFECT_DEP, "Collision Object", 170,200,130,20, &clmd->sim_parms.flags, 0, 0, 0, 0, "Sets object to become a cloth collision object"); - if (!(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_COLLOBJ)) + if (!(clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_COLLOBJ)) { Cloth *cloth = clmd->clothObject; int defCount; @@ -4798,18 +4834,18 @@ static void object_panel_cloth(Object *ob) val2=0; - // uiDefButBitI(block, TOG, CSIMSETT_FLAG_ADVANCED, REDRAWBUTSOBJECT, "Advanced", 180,200,130,20, &clmd->sim_parms->flags, 0, 0, 0, 0, "Enable advanced mode"); + // uiDefButBitI(block, TOG, CSIMSETT_FLAG_ADVANCED, REDRAWBUTSOBJECT, "Advanced", 180,200,130,20, &clmd->sim_parms.flags, 0, 0, 0, 0, "Enable advanced mode"); /* GENERAL STUFF */ uiClearButLock(); uiBlockBeginAlign(block); - uiDefButF(block, NUM, B_CLOTH_RENEW, "StructStiff:", 10,170,150,20, &clmd->sim_parms->structural, 1.0, 10000.0, 100, 0, "Overall stiffness of structure"); - uiDefButF(block, NUM, B_CLOTH_RENEW, "BendStiff:", 160,170,150,20, &clmd->sim_parms->bending, 0.0, 10000.0, 1000, 0, "Wrinkle possibility"); - uiDefButI(block, NUM, B_CLOTH_RENEW, "Quality:", 10,150,150,20, &clmd->sim_parms->stepsPerFrame, 3.0, 10.0, 5, 0, "Quality of the simulation (higher=>better=>slower)"); + uiDefButF(block, NUM, B_CLOTH_RENEW, "StructStiff:", 10,170,150,20, &clmd->sim_parms.structural, 1.0, 10000.0, 100, 0, "Overall stiffness of structure"); + uiDefButF(block, NUM, B_CLOTH_RENEW, "BendStiff:", 160,170,150,20, &clmd->sim_parms.bending, 0.0, 10000.0, 1000, 0, "Wrinkle possibility"); + uiDefButI(block, NUM, B_CLOTH_RENEW, "Steps per Frame:", 10,150,150,20, &clmd->sim_parms.stepsPerFrame, 1.0, 100.0, 5, 0, "Quality of the simulation (higher=better=slower)"); uiBlockEndAlign(block); uiBlockBeginAlign(block); - uiDefButF(block, NUM, B_CLOTH_RENEW, "Spring Damp:", 160,150,150,20, &clmd->sim_parms->Cdis, 0.0, 10.0, 10, 0, "Spring damping"); - uiDefButF(block, NUM, B_DIFF, "Air Damp:", 10,130,150,20, &clmd->sim_parms->Cvi, 0.0, 10.0, 10, 0, "Apply gravitation to point movement"); + uiDefButF(block, NUM, B_CLOTH_RENEW, "Spring Damp:", 160,150,150,20, &clmd->sim_parms.Cdis, 0.0, 10.0, 10, 0, "Spring damping"); + uiDefButF(block, NUM, B_DIFF, "Air Damp:", 10,130,150,20, &clmd->sim_parms.Cvi, 0.0, 10.0, 10, 0, "Apply gravitation to point movement"); uiBlockEndAlign(block); uiClearButLock(); @@ -4818,15 +4854,15 @@ static void object_panel_cloth(Object *ob) uiDefBut(block, LABEL, 0, "Gravity:", 10,100,60,20, NULL, 0.0, 0, 0, 0, ""); // uiClearButLock(); - uiDefButF(block, NUM, B_CLOTH_RENEW, "X:", 70,100,80,20, &clmd->sim_parms->gravity[0], -100.0, 100.0, 10, 0, "Apply gravitation to point movement"); - uiDefButF(block, NUM, B_CLOTH_RENEW, "Y:", 150,100,80,20, &clmd->sim_parms->gravity[1], -100.0, 100.0, 10, 0, "Apply gravitation to point movement"); - uiDefButF(block, NUM, B_CLOTH_RENEW, "Z:", 230,100,80,20, &clmd->sim_parms->gravity[2], -100.0, 100.0, 10, 0, "Apply gravitation to point movement"); + uiDefButF(block, NUM, B_CLOTH_RENEW, "X:", 70,100,80,20, &clmd->sim_parms.gravity[0], -100.0, 100.0, 10, 0, "Apply gravitation to point movement"); + uiDefButF(block, NUM, B_CLOTH_RENEW, "Y:", 150,100,80,20, &clmd->sim_parms.gravity[1], -100.0, 100.0, 10, 0, "Apply gravitation to point movement"); + uiDefButF(block, NUM, B_CLOTH_RENEW, "Z:", 230,100,80,20, &clmd->sim_parms.gravity[2], -100.0, 100.0, 10, 0, "Apply gravitation to point movement"); uiBlockEndAlign(block); /* GOAL STUFF */ uiBlockBeginAlign(block); - uiDefButBitI(block, TOG, CLOTH_SIMSETTINGS_FLAG_GOAL, REDRAWVIEW3D, "Use Goal", 10,70,130,20, &clmd->sim_parms->flags, 0, 0, 0, 0, "Define forces for vertices to stick to animated position"); - if (clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL) + uiDefButBitI(block, TOG, CLOTH_SIMSETTINGS_FLAG_GOAL, REDRAWVIEW3D, "Use Goal", 10,70,130,20, &clmd->sim_parms.flags, 0, 0, 0, 0, "Define forces for vertices to stick to animated position"); + if (clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_GOAL) { if(ob->type==OB_MESH) { @@ -4841,17 +4877,17 @@ static void object_panel_cloth(Object *ob) defCount = BLI_countlist (&ob->defbase); if (defCount == 0) { - clmd->sim_parms->vgroup_mass = 0; + clmd->sim_parms.vgroup_mass = 0; } sprintf (clvg2, "%s%s", clmvg, clvg1); - uiDefButS(block, MENU, B_CLOTH_RENEW, clvg2, 140,70,20,20, &clmd->sim_parms->vgroup_mass, 0, defCount, 0, 0, "Browses available vertex groups"); + uiDefButS(block, MENU, B_CLOTH_RENEW, clvg2, 140,70,20,20, &clmd->sim_parms.vgroup_mass, 0, defCount, 0, 0, "Browses available vertex groups"); MEM_freeN (clvg1); MEM_freeN (clvg2); - if(clmd->sim_parms->vgroup_mass) + if(clmd->sim_parms.vgroup_mass) { - bDeformGroup *defGroup = BLI_findlink(&ob->defbase, clmd->sim_parms->vgroup_mass-1); + bDeformGroup *defGroup = BLI_findlink(&ob->defbase, clmd->sim_parms.vgroup_mass-1); if(defGroup) uiDefBut(block, BUT, B_DIFF, defGroup->name, 160,70,130,20, NULL, 0.0, 0.0, 0, 0, "Name of current vertex group"); else @@ -4861,31 +4897,31 @@ static void object_panel_cloth(Object *ob) } else - uiDefButF(block, NUM, B_CLOTH_RENEW, "Goal:", 160,70,150,20, &clmd->sim_parms->defgoal, 0.0, 1.0, 10, 0, "Default Goal (vertex target position) value, when no Vertex Group used"); + uiDefButF(block, NUM, B_CLOTH_RENEW, "Goal:", 160,70,150,20, &clmd->sim_parms.defgoal, 0.0, 1.0, 10, 0, "Default Goal (vertex target position) value, when no Vertex Group used"); } else { - uiDefButS(block, TOG, B_CLOTH_RENEW, "W", 140,70,20,20, &clmd->sim_parms->vgroup_mass, 0, 1, 0, 0, "Use control point weight values"); - uiDefButF(block, NUM, B_CLOTH_RENEW, "Goal:", 160,70,150,20, &clmd->sim_parms->defgoal, 0.0, 1.0, 10, 0, "Default Goal (vertex target position) value, when no Vertex Group used"); + uiDefButS(block, TOG, B_CLOTH_RENEW, "W", 140,70,20,20, &clmd->sim_parms.vgroup_mass, 0, 1, 0, 0, "Use control point weight values"); + uiDefButF(block, NUM, B_CLOTH_RENEW, "Goal:", 160,70,150,20, &clmd->sim_parms.defgoal, 0.0, 1.0, 10, 0, "Default Goal (vertex target position) value, when no Vertex Group used"); } - uiDefButF(block, NUM, B_CLOTH_RENEW, "G Stiff:", 10,50,150,20, &clmd->sim_parms->goalspring, 0.0, 500.0, 10, 0, "Goal (vertex target position) spring stiffness"); - uiDefButF(block, NUM, B_CLOTH_RENEW, "G Damp:", 160,50,150,20, &clmd->sim_parms->goalfrict, 0.0, 50.0, 10, 0, "Goal (vertex target position) friction"); - uiDefButF(block, NUM, B_CLOTH_RENEW, "G Min:", 10,30,150,20, &clmd->sim_parms->mingoal, 0.0, 1.0, 10, 0, "Goal minimum, vertex group weights are scaled to match this range"); - uiDefButF(block, NUM, B_CLOTH_RENEW, "G Max:", 160,30,150,20, &clmd->sim_parms->maxgoal, 0.0, 1.0, 10, 0, "Goal maximum, vertex group weights are scaled to match this range"); + uiDefButF(block, NUM, B_CLOTH_RENEW, "G Stiff:", 10,50,150,20, &clmd->sim_parms.goalspring, 0.0, 500.0, 10, 0, "Goal (vertex target position) spring stiffness"); + uiDefButF(block, NUM, B_CLOTH_RENEW, "G Damp:", 160,50,150,20, &clmd->sim_parms.goalfrict , 0.0, 50.0, 10, 0, "Goal (vertex target position) friction"); + uiDefButF(block, NUM, B_CLOTH_RENEW, "G Min:", 10,30,150,20, &clmd->sim_parms.mingoal, 0.0, 1.0, 10, 0, "Goal minimum, vertex group weights are scaled to match this range"); + uiDefButF(block, NUM, B_CLOTH_RENEW, "G Max:", 160,30,150,20, &clmd->sim_parms.maxgoal, 0.0, 1.0, 10, 0, "Goal maximum, vertex group weights are scaled to match this range"); } uiBlockEndAlign(block); /* // no tearing supported anymore since modifier stack restrictions uiBlockBeginAlign(block); - uiDefButBitI(block, TOG, CSIMSETT_FLAG_TEARING_ENABLED, B_EFFECT_DEP, "Tearing", 10,0,150,20, &clmd->sim_parms->flags, 0, 0, 0, 0, "Sets object to become a cloth collision object"); + uiDefButBitI(block, TOG, CSIMSETT_FLAG_TEARING_ENABLED, B_EFFECT_DEP, "Tearing", 10,0,150,20, &clmd->sim_parms.flags, 0, 0, 0, 0, "Sets object to become a cloth collision object"); - if (clmd->sim_parms->flags & CSIMSETT_FLAG_TEARING_ENABLED) + if (clmd->sim_parms.flags & CSIMSETT_FLAG_TEARING_ENABLED) { - uiDefButI(block, NUM, B_DIFF, "Max extent:", 160,0,150,20, &clmd->sim_parms->maxspringlen, 1.0, 1000.0, 10, 0, "Maximum extension before spring gets cut"); - } + uiDefButI(block, NUM, B_DIFF, "Max extent:", 160,0,150,20, &clmd->sim_parms.maxspringlen, 1.0, 1000.0, 10, 0, "Maximum extension before spring gets cut"); + } uiBlockEndAlign(block); */ @@ -4904,7 +4940,7 @@ static void object_panel_cloth_II(Object *ob) clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth); if(clmd) { - if (!(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_COLLOBJ)) + if (!(clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_COLLOBJ)) { Cloth *cloth = clmd->clothObject; char str[128]; @@ -4915,18 +4951,18 @@ static void object_panel_cloth_II(Object *ob) uiSetButLock(object_data_is_libdata(ob), ERROR_LIBDATA_MESSAGE); - uiDefButI(block, NUM, B_DIFF, "First Frame:", 10,160,150,20, &clmd->sim_parms->firstframe, 0, MAXFRAME, 1, 0, "Frame on which the simulation starts"); - uiDefButI(block, NUM, B_DIFF, "Last Frame:", 160,160,150,20, &clmd->sim_parms->lastframe, 0, MAXFRAME, 10, 0, "Frame on which the simulation stops"); - /* - if(clmd->sim_parms->cache) + uiDefButI(block, NUM, B_DIFF, "First Frame:", 10,160,150,20, &clmd->sim_parms.firstframe, 0, MAXFRAME, 1, 0, "Frame on which the simulation starts"); + uiDefButI(block, NUM, B_DIFF, "Last Frame:", 160,160,150,20, &clmd->sim_parms.lastframe, 0, MAXFRAME, 10, 0, "Frame on which the simulation stops"); + + if(clmd->sim_parms.cache) { - int length = BLI_linklist_length(clmd->sim_parms->cache); + int length = BLI_linklist_length(clmd->sim_parms.cache); - // correct spelling if only 1 frame cacheed --> only gimmick - if(length-clmd->sim_parms->preroll>1) - sprintf (str, "Frame 1 - %d cached. [%d in preroll, %d in total]", length-clmd->sim_parms->preroll, clmd->sim_parms->preroll, length); + /* correct spelling if only 1 frame cacheed --> only gimmick */ + if(length-clmd->sim_parms.preroll>1) + sprintf (str, "Frame 1 - %d cached. [%d in preroll, %d in total]", length-clmd->sim_parms.preroll, clmd->sim_parms.preroll, length); else - sprintf (str, "Frame %d cached. [%d in preroll, %d in total]", length-clmd->sim_parms->preroll, clmd->sim_parms->preroll, length); + sprintf (str, "Frame %d cached. [%d in preroll, %d in total]", length-clmd->sim_parms.preroll, clmd->sim_parms.preroll, length); uiDefBut(block, LABEL, 0, str, 10,140,290,20, NULL, 0.0, 0, 0, 0, ""); uiDefBut(block, LABEL, 0, "Clear cache:", 10,120,290,20, NULL, 0.0, 0, 0, 0, ""); @@ -4934,15 +4970,15 @@ static void object_panel_cloth_II(Object *ob) uiDefBut(block, BUT, B_CLOTH_CLEARCACHEALL, "All", 10, 100,145,20, NULL, 0.0, 0.0, 0, 0, "Free cloth cache without preroll"); uiDefBut(block, BUT, B_CLOTH_CLEARCACHEFRAME, "From next frame", 155, 100,145,20, NULL, 0.0, 0.0, 0, 0, "Free cloth cache"); if(length>1) // B_CLOTH_CHANGEPREROLL - uiDefButI(block, NUM, B_CLOTH_CHANGEPREROLL, "Preroll:", 10,80,145,20, &clmd->sim_parms->preroll, 0, length-1, 1, 0, "Simulation starts on this frame"); + uiDefButI(block, NUM, B_CLOTH_CHANGEPREROLL, "Preroll:", 10,80,145,20, &clmd->sim_parms.preroll, 0, length-1, 1, 0, "Simulation starts on this frame"); else uiDefBut(block, LABEL, 0, " ", 10,80,145,20, NULL, 0.0, 0, 0, 0, ""); } - else + else { uiDefBut(block, LABEL, 0, "No frames cached.", 10,120,290,20, NULL, 0.0, 0, 0, 0, ""); - }*/ - uiDefButBitI(block, TOG, CLOTH_SIMSETTINGS_FLAG_CCACHE_PROTECT, REDRAWVIEW3D, "Protect Cache", 10,50,145,20, &clmd->sim_parms->flags, 0, 0, 0, 0, "Protect cache from automatic freeing when scene changed"); + } + uiDefButBitI(block, TOG, CLOTH_SIMSETTINGS_FLAG_CCACHE_PROTECT, REDRAWVIEW3D, "Protect Cache", 10,50,145,20, &clmd->sim_parms.flags, 0, 0, 0, 0, "Protect cache from automatic freeing when scene changed"); uiBlockEndAlign(block); } } @@ -4952,32 +4988,41 @@ static void object_panel_cloth_II(Object *ob) static void object_panel_cloth_III(Object *ob) { uiBlock *block; + static int val; + uiBut *but; ClothModifierData *clmd = NULL; clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth); if(clmd) - { - block= uiNewBlock(&curarea->uiblocks, "object_panel_cloth_III", UI_EMBOSS, UI_HELV, curarea->win); - uiNewPanelTabbed("Cloth", "Physics"); - if(uiNewPanel(curarea, block, "Cloth Collisions", "Physics", 651, 0, 318, 204)==0) return; - - uiSetButLock(object_data_is_libdata(ob), ERROR_LIBDATA_MESSAGE); - - uiBlockBeginAlign(block); - uiDefButBitI(block, TOG, CLOTH_COLLISIONSETTINGS_FLAG_ENABLED, REDRAWVIEW3D, "Enable collisions", 10,160,130,20, &clmd->coll_parms->flags, 0, 0, 0, 0, "Enable collisions with this object"); - if (clmd->coll_parms->flags & CLOTH_COLLISIONSETTINGS_FLAG_ENABLED) + { + if (!(clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_COLLOBJ)) { - // uiDefBut(block, LABEL, 0, "",10,10,300,20, NULL, 0.0, 0, 0, 0, ""); /* tell UI we go to 10,10*/ - uiDefButF(block, NUM, B_CLOTH_RENEW, "Min Distance:", 10,140,150,20, &clmd->coll_parms->epsilon, 0.001f, 1.0, 0.01f, 0, "Minimum distance between collision objects before collision response takes in"); - uiDefBut(block, LABEL, 0, "",160,140,150,20, NULL, 0.0, 0, 0, 0, ""); - uiDefButF(block, NUM, B_CLOTH_RENEW, "Selfcoll balls:", 10,120,150,20, &clmd->coll_parms->selfepsilon, 0.001f, 1.0, 0.49f, 0, "Minimum distance between two selfcollision points"); + Cloth *cloth = clmd->clothObject; + char str[128]; + + block= uiNewBlock(&curarea->uiblocks, "object_panel_cloth_III", UI_EMBOSS, UI_HELV, curarea->win); + uiNewPanelTabbed("Cloth", "Physics"); + if(uiNewPanel(curarea, block, "Cloth Collisions", "Physics", 651, 0, 318, 204)==0) return; + + uiSetButLock(object_data_is_libdata(ob), ERROR_LIBDATA_MESSAGE); + + uiBlockBeginAlign(block); + uiDefButBitI(block, TOG, CLOTH_COLLISIONSETTINGS_FLAG_ENABLED, REDRAWVIEW3D, "Enable collisions", 10,70,130,20, &clmd->coll_parms.flags, 0, 0, 0, 0, "Enable collisions with this object"); + if (clmd->coll_parms.flags & CLOTH_COLLISIONSETTINGS_FLAG_ENABLED) + { + // uiDefBut(block, LABEL, 0, "",10,10,300,20, NULL, 0.0, 0, 0, 0, ""); /* tell UI we go to 10,10*/ + uiDefButF(block, NUM, B_CLOTH_RENEW, "Min Distance:", 10,30,150,20, &clmd->coll_parms.epsilon, 0.001f, 1.0, 0.01f, 0, "Minimum distance between collision objects before collision response takes in"); + uiDefBut(block, LABEL, 0, "",160,30,150,20, NULL, 0.0, 0, 0, 0, ""); + } + else + uiDefBut(block, LABEL, 0, "",140,10,170,20, NULL, 0.0, 0, 0, 0, ""); + uiBlockEndAlign(block); } - else - uiDefBut(block, LABEL, 0, "",140,10,170,20, NULL, 0.0, 0, 0, 0, ""); - uiBlockEndAlign(block); } + // uiBlockEndAlign(block); } + void object_panels() { Object *ob; diff --git a/source/blender/src/drawobject.c b/source/blender/src/drawobject.c index 111f0789ee9..61e4c6d5660 100644 --- a/source/blender/src/drawobject.c +++ b/source/blender/src/drawobject.c @@ -2454,112 +2454,6 @@ void draw_slices ( float m[][4] ) } } - -void draw_fl(ClothModifierData *clmd) -{ - int i; - float m[4][4]; - Cloth *cloth = clmd->clothObject; - fc *m_fc = NULL; - - if(!cloth) - return; - - m_fc = cloth->m_fc; - - glClearColor(0, 0, 0, 0); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); - // gluLookAt(0, 0, -_dist, 0, 0, 0, 0, 1, 0); - - // build_rotmatrix(m, _quat); - - glMultMatrixf(&m[0][0]); - - // ---------------------------------------- - // from ligth constructor - m_fc->_light_dir[0] = -1.0f; - m_fc->_light_dir[1] = 0.5f; - m_fc->_light_dir[2] = 0.0f; - - gen_ray_templ(m_fc->_ray_templ, m_fc->_light_dir, 30 + 2); - - cast_light(m_fc->_texture_data, m_fc->_ray_templ, m_fc->_light_dir, 30+2); - - glActiveTextureARB(GL_TEXTURE0_ARB); - glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA, 30+2, 30+2, 30+2, 0, GL_RGBA, GL_UNSIGNED_BYTE, m_fc->_texture_data); - // ---------------------------------------- - - draw_slices(m); -/* - if (_dispstring != NULL) { - glMatrixMode(GL_PROJECTION); - glLoadMatrixd(_ortho_m); - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); - - glDisable(GL_TEXTURE_3D); - glDisable(GL_FRAGMENT_PROGRAM_ARB); - glColor4f(1.0, 1.0, 1.0, 1.0); - glRasterPos2i(-_sx/2 + 10, _sy/2 - 15); - - print_string(_dispstring); - - glMatrixMode(GL_PROJECTION); - glLoadMatrixd(_persp_m); - glMatrixMode(GL_MODELVIEW); - } -*/ -} - -void fc_load_frame(ClothModifierData *clmd) -{ - float* tmp = (float*) MEM_callocN(30*30*30*sizeof(float), "fc_tmp"); - float tmin=9999999, tmax=-99999999; - Cloth *cloth = clmd->clothObject; - fc *m_fc = NULL; - int i = 0; - - if(!cloth) - return; - - m_fc = cloth->m_fc; - - if (++m_fc->_cur_frame == m_fc->_nframes) { - fseek(m_fc->_fp, 12, SEEK_SET); - m_fc->_cur_frame = 0; - } - - fread(tmp, sizeof(float), 30*30*30, m_fc->_fp); - - for (i=0; i<30*30*30; i++) - { - m_fc->_texture_data[(i<<2)+1] = (unsigned char) (tmp[i]*255.0f); - } - - fread(tmp, sizeof(float), 30*30*30, m_fc->_fp); - - for (i=0; i<30*30*30; i++) - { - m_fc->_texture_data[(i<<2)] = (unsigned char) (tmp[i]*255.0f); - if (tmp[i]tmax) - tmax = tmp[i]; - m_fc->_texture_data[(i<<2)+2] = 0; - m_fc->_texture_data[(i<<2)+3] = 255; - } - - MEM_freeN(tmp); - - // cast_light(_N); DG NOT NEEDED - - glActiveTextureARB(GL_TEXTURE0_ARB); - glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA, 30, 30, 30, 0, GL_RGBA, GL_UNSIGNED_BYTE, m_fc->_texture_data); -} - static void draw_mesh_object_outline(Object *ob, DerivedMesh *dm) { diff --git a/source/blender/src/vpaint.c b/source/blender/src/vpaint.c index 615a9566b97..2e4ecd95709 100644 --- a/source/blender/src/vpaint.c +++ b/source/blender/src/vpaint.c @@ -51,6 +51,7 @@ #include "DNA_action_types.h" #include "DNA_armature_types.h" #include "DNA_brush_types.h" +#include "DNA_cloth_types.h" #include "DNA_mesh_types.h" #include "DNA_meshdata_types.h" #include "DNA_modifier_types.h" @@ -747,7 +748,7 @@ static int sample_backbuf_area(VPaint *vp, int *indexar, int totface, int x, int struct ImBuf *ibuf; int x1, y1, x2, y2, a, tot=0, index; - if(totface>=MAXINDEX) return 0; + if(totface+4>=MAXINDEX) return 0; if(size>64.0) size= 64.0; @@ -777,7 +778,7 @@ static int sample_backbuf_area(VPaint *vp, int *indexar, int totface, int x, int size= (y2-y1)*(x2-x1); if(size<=0) return 0; - memset(indexar, 0, sizeof(int)*totface+2); /* plus 2! first element is total */ + memset(indexar, 0, sizeof(int)*totface+4); /* plus 2! first element is total, +2 was giving valgrind errors, +4 seems ok */ while(size--) { @@ -1350,7 +1351,7 @@ void weight_paint(void) // same goes for cloth if(modifiers_isClothEnabled(ob)) { - cloth_free_modifier(modifiers_isClothEnabled(ob)); + cloth_free_modifier((ClothModifierData *)modifiers_isClothEnabled(ob)); } BIF_undo_push("Weight Paint"); From 530039a4297d93998202391caedfbbbc2558499d Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Mon, 21 Jan 2008 02:23:03 +0000 Subject: [PATCH 071/246] Restructured many collision things again, GUI cleanup --- source/blender/blenkernel/BKE_cloth.h | 45 +- source/blender/blenkernel/BKE_collisions.h | 1 + source/blender/blenkernel/intern/cloth.c | 107 +++- source/blender/blenkernel/intern/collision.c | 90 +++- source/blender/blenkernel/intern/kdop.c | 533 +++++-------------- source/blender/blenkernel/intern/modifier.c | 150 ++++++ source/blender/makesdna/DNA_cloth_types.h | 2 +- source/blender/src/buttons_object.c | 38 +- 8 files changed, 488 insertions(+), 478 deletions(-) diff --git a/source/blender/blenkernel/BKE_cloth.h b/source/blender/blenkernel/BKE_cloth.h index eb1f33ae600..592c34ad28e 100644 --- a/source/blender/blenkernel/BKE_cloth.h +++ b/source/blender/blenkernel/BKE_cloth.h @@ -129,38 +129,39 @@ void implicit_set_positions ( ClothModifierData *clmd ); void clothModifier_do ( ClothModifierData *clmd, Object *ob, DerivedMesh *dm, float ( *vertexCos ) [3], int numverts ); // used in collision.c -typedef struct Tree +typedef struct CollisionTree { - struct Tree *nodes[4]; // 4 children --> quad-tree - struct Tree *parent; - struct Tree *nextLeaf; - struct Tree *prevLeaf; + struct CollisionTree *nodes[4]; // 4 children --> quad-tree + struct CollisionTree *parent; + struct CollisionTree *nextLeaf; + struct CollisionTree *prevLeaf; float bv[26]; // Bounding volume of all nodes / we have 7 axes on a 14-DOP unsigned int tri_index; // this saves the index of the face + // int point_index[4]; // supports up to 4 points in a leaf int count_nodes; // how many nodes are used int traversed; // how many nodes already traversed until this level? int isleaf; } -Tree; - -typedef struct Tree TreeNode; +CollisionTree; typedef struct BVH { unsigned int numfaces; unsigned int numverts; - ClothVertex *verts; // just a pointer to the original datastructure + // ClothVertex *verts; // just a pointer to the original datastructure + MVert *current_x; // e.g. txold in clothvertex + MVert *current_xold; // e.g. tx in clothvertex MFace *mfaces; // just a pointer to the original datastructure struct LinkNode *tree; - TreeNode *root; // TODO: saving the root --> is this really needed? YES! - TreeNode *leaf_tree; /* Tail of the leaf linked list. */ - TreeNode *leaf_root; /* Head of the leaf linked list. */ + CollisionTree *root; // TODO: saving the root --> is this really needed? YES! + CollisionTree *leaf_tree; /* Tail of the leaf linked list. */ + CollisionTree *leaf_root; /* Head of the leaf linked list. */ float epsilon; /* epslion is used for inflation of the k-dop */ int flags; /* bvhFlags */ } BVH; -typedef void ( *CM_COLLISION_RESPONSE ) ( ClothModifierData *clmd, ClothModifierData *coll_clmd, Tree * tree1, Tree * tree2 ); +typedef void ( *CM_COLLISION_RESPONSE ) ( ClothModifierData *clmd, ClothModifierData *coll_clmd, CollisionTree * tree1, CollisionTree * tree2 ); ///////////////////////////////////////////////// @@ -168,9 +169,15 @@ typedef void ( *CM_COLLISION_RESPONSE ) ( ClothModifierData *clmd, ClothModifier //////////////////////////////////////////////// // needed for implicit.c -void bvh_collision_response ( ClothModifierData *clmd, ClothModifierData *coll_clmd, Tree * tree1, Tree * tree2 ); +void bvh_collision_response ( ClothModifierData *clmd, ClothModifierData *coll_clmd, CollisionTree * tree1, CollisionTree * tree2 ); int cloth_bvh_objcollision ( ClothModifierData * clmd, float step, float dt ); +// needed for modifier.c +BVH *bvh_build_from_mvert (MFace *mfaces, unsigned int numfaces, MVert *x, unsigned int numverts, float epsilon); + +// needed for collision.c +void bvh_update_from_mvert(BVH * bvh, MVert *x, unsigned int numverts, MVert *xnew, int moving); + //////////////////////////////////////////////// @@ -180,13 +187,12 @@ int cloth_bvh_objcollision ( ClothModifierData * clmd, float step, float dt ); // needed for cloth.c void bvh_free ( BVH * bvh ); -BVH *bvh_build ( ClothModifierData *clmd, float epsilon ); +void bvh_build (BVH *bvh); LinkNode *BLI_linklist_append_fast ( LinkNode **listp, void *ptr ); // needed for collision.c -int bvh_traverse ( ClothModifierData * clmd, ClothModifierData * coll_clmd, Tree * tree1, Tree * tree2, float step, CM_COLLISION_RESPONSE collision_response ); -void bvh_update ( ClothModifierData * clmd, BVH * bvh, int moving ); - +int bvh_traverse ( ClothModifierData * clmd, ClothModifierData * coll_clmd, CollisionTree * tree1, CollisionTree * tree2, float step, CM_COLLISION_RESPONSE collision_response ); +void bvh_update(BVH * bvh, int moving); //////////////////////////////////////////////// @@ -199,6 +205,9 @@ void cloth_init ( ClothModifierData *clmd ); void cloth_deform_verts ( struct Object *ob, float framenr, float ( *vertexCos ) [3], int numVerts, void *derivedData, ClothModifierData *clmd ); void cloth_update_normals ( ClothVertex *verts, int nVerts, MFace *face, int totface ); +// needed for collision.c +void bvh_update_from_cloth(ClothModifierData *clmd, int moving); + //////////////////////////////////////////////// diff --git a/source/blender/blenkernel/BKE_collisions.h b/source/blender/blenkernel/BKE_collisions.h index e38662fdf95..f0f6212d3f5 100644 --- a/source/blender/blenkernel/BKE_collisions.h +++ b/source/blender/blenkernel/BKE_collisions.h @@ -79,6 +79,7 @@ typedef struct BVH } BVH; + /* used for collisions in kdop.c and also collision.c*/ typedef struct CollisionPair { diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c index fef932174a1..c68fb983fc9 100644 --- a/source/blender/blenkernel/intern/cloth.c +++ b/source/blender/blenkernel/intern/cloth.c @@ -160,6 +160,7 @@ void cloth_init ( ClothModifierData *clmd ) clmd->sim_parms.maxspringlen = 10; clmd->sim_parms.firstframe = 1; clmd->sim_parms.lastframe = 250; + clmd->sim_parms.vgroup_mass = 0; clmd->coll_parms.self_friction = 5.0; clmd->coll_parms.friction = 10.0; clmd->coll_parms.loop_count = 1; @@ -175,13 +176,91 @@ void cloth_init ( ClothModifierData *clmd ) // also from softbodies clmd->sim_parms.maxgoal = 1.0f; clmd->sim_parms.mingoal = 0.0f; - clmd->sim_parms.defgoal = 0.7f; + clmd->sim_parms.defgoal = 0.0f; clmd->sim_parms.goalspring = 100.0f; clmd->sim_parms.goalfrict = 0.0f; clmd->sim_parms.cache = NULL; } + +BVH *bvh_build_from_cloth (ClothModifierData *clmd, float epsilon) +{ + unsigned int i = 0; + BVH *bvh=NULL; + Cloth *cloth = clmd->clothObject; + ClothVertex *verts = NULL; + + if(!clmd) + return NULL; + + cloth = clmd->clothObject; + + if(!cloth) + return NULL; + + verts = cloth->verts; + + bvh = MEM_callocN(sizeof(BVH), "BVH"); + if (bvh == NULL) + { + printf("bvh: Out of memory.\n"); + return NULL; + } + + // springs = cloth->springs; + // numsprings = cloth->numsprings; + + bvh->flags = 0; + bvh->leaf_tree = NULL; + bvh->leaf_root = NULL; + bvh->tree = NULL; + + bvh->epsilon = epsilon; + bvh->numfaces = cloth->numfaces; + bvh->mfaces = cloth->mfaces; + + bvh->numverts = cloth->numverts; + + bvh->current_x = MEM_callocN ( sizeof ( MVert ) * bvh->numverts, "bvh->current_x" ); + bvh->current_xold = MEM_callocN ( sizeof ( MVert ) * bvh->numverts, "bvh->current_xold" ); + + for(i = 0; i < bvh->numverts; i++) + { + VECCOPY(bvh->current_x[i].co, verts[i].tx); + VECCOPY(bvh->current_xold[i].co, verts[i].txold); + } + + bvh_build (bvh); + + return bvh; +} + +void bvh_update_from_cloth(ClothModifierData *clmd, int moving) +{ + unsigned int i = 0; + Cloth *cloth = clmd->clothObject; + BVH *bvh = cloth->tree; + ClothVertex *verts = cloth->verts; + + if(!bvh) + return; + + if(cloth->numverts!=bvh->numverts) + return; + + if(cloth->verts) + { + for(i = 0; i < bvh->numverts; i++) + { + VECCOPY(bvh->current_x[i].co, verts[i].tx); + VECCOPY(bvh->current_xold[i].co, verts[i].txold); + } + } + + bvh_update(bvh, moving); +} + // unused in the moment, cloth needs quads from mesh DerivedMesh *CDDM_convert_to_triangle ( DerivedMesh *dm ) { @@ -433,9 +512,9 @@ static void cloth_write_cache(Object *ob, ClothModifierData *clmd, float framenr for(a = 0; a < cloth->numverts; a++) { - fwrite(&cloth->verts[a].x, sizeof(float),4,fp); - fwrite(&cloth->verts[a].xconst, sizeof(float),4,fp); - fwrite(&cloth->verts[a].v, sizeof(float),4,fp); + fwrite(&cloth->verts[a].x, sizeof(float),3,fp); + fwrite(&cloth->verts[a].xconst, sizeof(float),3,fp); + fwrite(&cloth->verts[a].v, sizeof(float),3,fp); } fclose(fp); @@ -458,17 +537,17 @@ static int cloth_read_cache(Object *ob, ClothModifierData *clmd, float framenr) else { for(a = 0; a < cloth->numverts; a++) { - if(fread(&cloth->verts[a].x, sizeof(float), 4, fp) != 4) + if(fread(&cloth->verts[a].x, sizeof(float), 3, fp) != 3) { ret = 0; break; } - if(fread(&cloth->verts[a].xconst, sizeof(float), 4, fp) != 4) + if(fread(&cloth->verts[a].xconst, sizeof(float), 3, fp) != 3) { ret = 0; break; } - if(fread(&cloth->verts[a].v, sizeof(float), 4, fp) != 4) + if(fread(&cloth->verts[a].v, sizeof(float), 3, fp) != 3) { ret = 0; break; @@ -656,7 +735,7 @@ void clothModifier_do ( ClothModifierData *clmd, Object *ob, DerivedMesh *dm, solvers [clmd->sim_parms.solver_type].solver ( ob, framenr, clmd, effectors ); tend(); - printf ( "Cloth simulation time: %f\n", ( float ) tval() ); + // printf ( "Cloth simulation time: %f\n", ( float ) tval() ); cloth_write_cache(ob, clmd, framenr); @@ -830,7 +909,13 @@ static void cloth_apply_vgroup ( ClothModifierData *clmd, DerivedMesh *dm, short { verts->goal = dvert->dw [j].weight; - goalfac= ABS ( clmd->sim_parms.maxgoal - clmd->sim_parms.mingoal ); + goalfac= 1.0f; + + /* + // Kicking goal factor to simplify things...who uses that anyway? + // ABS ( clmd->sim_parms.maxgoal - clmd->sim_parms.mingoal ); + */ + verts->goal = ( float ) pow ( verts->goal , 4.0f ); if ( dvert->dw [j].weight >=SOFTGOALSNAP ) @@ -905,7 +990,7 @@ static int collobj_from_object ( Object *ob, ClothModifierData *clmd, DerivedMes verts->impulse_count = 0; VECCOPY ( verts->impulse, tnull ); } - clmd->clothObject->tree = bvh_build ( clmd,clmd->coll_parms.epsilon ); + clmd->clothObject->tree = bvh_build_from_cloth ( clmd,clmd->coll_parms.epsilon ); } @@ -1012,7 +1097,7 @@ static int cloth_from_object ( Object *ob, ClothModifierData *clmd, DerivedMesh if ( solvers [clmd->sim_parms.solver_type].init ) solvers [clmd->sim_parms.solver_type].init ( ob, clmd ); - clmd->clothObject->tree = bvh_build ( clmd, clmd->coll_parms.epsilon ); + clmd->clothObject->tree = bvh_build_from_cloth ( clmd, clmd->coll_parms.epsilon ); cloth_write_cache(ob, clmd, framenr-1); } diff --git a/source/blender/blenkernel/intern/collision.c b/source/blender/blenkernel/intern/collision.c index 4a03f579fe8..4ab436b2936 100644 --- a/source/blender/blenkernel/intern/collision.c +++ b/source/blender/blenkernel/intern/collision.c @@ -70,7 +70,72 @@ #include "Bullet-C-Api.h" +// step is limited from 0 (frame start position) to 1 (frame end position) +void collision_move_object(CollisionModifierData *collmd, float step, float prevstep) +{ + float tv[3] = {0,0,0}; + unsigned int i = 0; + + for ( i = 0; i < collmd->numverts; i++ ) + { + VECSUB(tv, collmd->xnew[i].co, collmd->x[i].co); + VECADDS(collmd->current_x[i].co, collmd->x[i].co, tv, prevstep); + VECADDS(collmd->current_xnew[i].co, collmd->x[i].co, tv, step); + VECSUB(collmd->current_v[i].co, collmd->current_xnew[i].co, collmd->current_x[i].co); + } +} +BVH *bvh_build_from_mvert (MFace *mfaces, unsigned int numfaces, MVert *x, unsigned int numverts, float epsilon) +{ + BVH *bvh=NULL; + + bvh = MEM_callocN(sizeof(BVH), "BVH"); + if (bvh == NULL) + { + printf("bvh: Out of memory.\n"); + return NULL; + } + + bvh->flags = 0; + bvh->leaf_tree = NULL; + bvh->leaf_root = NULL; + bvh->tree = NULL; + + bvh->epsilon = epsilon; + bvh->numfaces = numfaces; + bvh->mfaces = mfaces; + + // we have no faces, we save seperate points + if(!mfaces) + { + bvh->numfaces = numverts; + } + + bvh->numverts = numverts; + bvh->current_x = MEM_dupallocN(x); + bvh->current_xold = MEM_dupallocN(x); + + bvh_build(bvh); + + return bvh; +} + +void bvh_update_from_mvert(BVH * bvh, MVert *x, unsigned int numverts, MVert *xnew, int moving) +{ + if(!bvh) + return; + + if(numverts!=bvh->numverts) + return; + + if(x) + memcpy(bvh->current_xold, x, sizeof(MVert) * numverts); + + if(xnew) + memcpy(bvh->current_x, xnew, sizeof(MVert) * numverts); + + bvh_update(bvh, moving); +} /** * gsl_poly_solve_cubic - @@ -519,7 +584,7 @@ int cloth_collision_response_moving_edges(ClothModifierData *clmd, ClothModifier } -void cloth_collision_static(ClothModifierData *clmd, ClothModifierData *coll_clmd, Tree *tree1, Tree *tree2) +void cloth_collision_static(ClothModifierData *clmd, ClothModifierData *coll_clmd, CollisionTree *tree1, CollisionTree *tree2) { CollPair *collpair = NULL; Cloth *cloth1=NULL, *cloth2=NULL; @@ -667,7 +732,7 @@ int cloth_are_edges_adjacent(ClothModifierData *clmd, ClothModifierData *coll_cl return 0; } -void cloth_collision_moving_edges(ClothModifierData *clmd, ClothModifierData *coll_clmd, Tree *tree1, Tree *tree2) +void cloth_collision_moving_edges(ClothModifierData *clmd, ClothModifierData *coll_clmd, CollisionTree *tree1, CollisionTree *tree2) { EdgeCollPair edgecollpair; Cloth *cloth1=NULL, *cloth2=NULL; @@ -802,7 +867,7 @@ void cloth_collision_moving_edges(ClothModifierData *clmd, ClothModifierData *co } } -void cloth_collision_moving_tris(ClothModifierData *clmd, ClothModifierData *coll_clmd, Tree *tree1, Tree *tree2) +void cloth_collision_moving_tris(ClothModifierData *clmd, ClothModifierData *coll_clmd, CollisionTree *tree1, CollisionTree *tree2) { CollPair collpair; Cloth *cloth1=NULL, *cloth2=NULL; @@ -896,7 +961,7 @@ void cloth_collision_moving_tris(ClothModifierData *clmd, ClothModifierData *col } } -void cloth_collision_moving(ClothModifierData *clmd, ClothModifierData *coll_clmd, Tree *tree1, Tree *tree2) +void cloth_collision_moving(ClothModifierData *clmd, ClothModifierData *coll_clmd, CollisionTree *tree1, CollisionTree *tree2) { // TODO: check for adjacent cloth_collision_moving_edges(clmd, coll_clmd, tree1, tree2); @@ -943,7 +1008,7 @@ void cloth_update_collision_objects(float step) } // update BVH of collision object - bvh_update(coll_clmd, coll_bvh, 0); // 0 means STATIC, 1 means MOVING + bvh_update_from_cloth(coll_clmd, 0); // 0 means STATIC, 1 means MOVING } else printf ("cloth_bvh_objcollision: found a collision object with clothObject or collData NULL.\n"); @@ -972,6 +1037,7 @@ int cloth_bvh_objcollision(ClothModifierData * clmd, float step, float dt) { return 0; } + cloth = clmd->clothObject; verts = cloth->verts; cloth_bvh = (BVH *) cloth->tree; @@ -983,7 +1049,7 @@ int cloth_bvh_objcollision(ClothModifierData * clmd, float step, float dt) //////////////////////////////////////////////////////////// // update cloth bvh - bvh_update(clmd, cloth_bvh, 0); // 0 means STATIC, 1 means MOVING (see later in this function) + bvh_update_from_cloth(clmd, 0); // 0 means STATIC, 1 means MOVING (see later in this function) // update collision objects cloth_update_collision_objects(step); @@ -1075,12 +1141,12 @@ int cloth_bvh_objcollision(ClothModifierData * clmd, float step, float dt) clmd->coll_parms.collision_list = NULL; } - printf("ic: %d\n", ic); + // printf("ic: %d\n", ic); rounds++; } while(result && (CLOTH_MAX_THRESHOLD>rounds)); - printf("\n"); + // printf("\n"); //////////////////////////////////////////////////////////// // update positions @@ -1100,7 +1166,7 @@ int cloth_bvh_objcollision(ClothModifierData * clmd, float step, float dt) // update cloth bvh - bvh_update(clmd, cloth_bvh, 1); // 0 means STATIC, 1 means MOVING + bvh_update_from_cloth(clmd, 1); // 0 means STATIC, 1 means MOVING // update moving bvh for collision object once for (base = G.scene->base.first; base; base = base->next) @@ -1119,7 +1185,7 @@ int cloth_bvh_objcollision(ClothModifierData * clmd, float step, float dt) { BVH *coll_bvh = coll_clmd->clothObject->tree; - bvh_update(coll_clmd, coll_bvh, 1); // 0 means STATIC, 1 means MOVING + bvh_update_from_cloth(coll_clmd, 1); // 0 means STATIC, 1 means MOVING } } @@ -1204,7 +1270,7 @@ int cloth_bvh_objcollision(ClothModifierData * clmd, float step, float dt) } // update cloth bvh - bvh_update(clmd, cloth_bvh, 1); // 0 means STATIC, 1 means MOVING + bvh_update_from_cloth(clmd, 1); // 0 means STATIC, 1 means MOVING // free collision list @@ -1223,7 +1289,7 @@ int cloth_bvh_objcollision(ClothModifierData * clmd, float step, float dt) clmd->coll_parms.collision_list = NULL; } - printf("ic: %d\n", ic); + // printf("ic: %d\n", ic); rounds++; } while(result && (CLOTH_MAX_THRESHOLD>rounds)); diff --git a/source/blender/blenkernel/intern/kdop.c b/source/blender/blenkernel/intern/kdop.c index 74b5b3d7b7f..ed1da4d19f9 100644 --- a/source/blender/blenkernel/intern/kdop.c +++ b/source/blender/blenkernel/intern/kdop.c @@ -1,4 +1,4 @@ -/* collision.c +/* kdop.c * * * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** @@ -38,6 +38,7 @@ #include "DNA_curve_types.h" #include "DNA_object_types.h" #include "DNA_object_force.h" +#include "DNA_cloth_types.h" #include "DNA_key_types.h" #include "DNA_mesh_types.h" #include "DNA_meshdata_types.h" @@ -58,7 +59,7 @@ #include "BKE_key.h" #include "BKE_mesh.h" #include "BKE_object.h" -#include "BKE_collisions.h" +#include "BKE_cloth.h" #include "BKE_modifier.h" #include "BKE_utildefines.h" #include "BKE_DerivedMesh.h" @@ -164,13 +165,13 @@ static int size_threshold = 16; /* * Common methods for all algorithms */ -void bvh_exchange(CollisionTree **a, int i, int j) +DO_INLINE void bvh_exchange(CollisionTree **a, int i, int j) { CollisionTree *t=a[i]; a[i]=a[j]; a[j]=t; } -int floor_lg(int a) +DO_INLINE int floor_lg(int a) { return (int)(floor(log(a)/log(2))); } @@ -195,7 +196,7 @@ static void bvh_insertionsort(CollisionTree **a, int lo, int hi, int axis) } } -static int bvh_partition(CollisionTree **a, int lo, int hi, CollisionTree *x, int axis) +static int bvh_partition(CollisionTree **a, int lo, int hi, CollisionTree * x, int axis) { int i=lo, j=hi; while (1) @@ -215,7 +216,7 @@ static int bvh_partition(CollisionTree **a, int lo, int hi, CollisionTree *x, in */ static void bvh_downheap(CollisionTree **a, int i, int n, int lo, int axis) { - CollisionTree *d = a[lo+i-1]; + CollisionTree * d = a[lo+i-1]; int child; while (i<=n/2) { @@ -293,7 +294,7 @@ static void bvh_introsort_loop (CollisionTree **a, int lo, int hi, int depth_lim } } -void bvh_sort(CollisionTree **a0, int begin, int end, int axis) +DO_INLINE void bvh_sort(CollisionTree **a0, int begin, int end, int axis) { if (begin < end) { @@ -302,7 +303,7 @@ void bvh_sort(CollisionTree **a0, int begin, int end, int axis) bvh_insertionsort(a, begin, end, axis); } } -void bvh_sort_along_axis(CollisionTree **face_list, int start, int end, int axis) +DO_INLINE void bvh_sort_along_axis(CollisionTree **face_list, int start, int end, int axis) { bvh_sort(face_list, start, end, axis); } @@ -330,11 +331,11 @@ void bvh_free(BVH * bvh) BLI_linklist_free(bvh->tree,NULL); bvh->tree = NULL; - if(bvh->x) - MEM_freeN(bvh->x); - if(bvh->xnew) - MEM_freeN(bvh->xnew); - + if(bvh->current_x) + MEM_freeN(bvh->current_x); + if(bvh->current_xold) + MEM_freeN(bvh->current_xold); + MEM_freeN(bvh); bvh = NULL; } @@ -342,7 +343,7 @@ void bvh_free(BVH * bvh) // only supports x,y,z axis in the moment // but we should use a plain and simple function here for speed sake -int bvh_largest_axis(float *bv) +DO_INLINE int bvh_largest_axis(float *bv) { float middle_point[3]; @@ -366,7 +367,7 @@ int bvh_largest_axis(float *bv) } // depends on the fact that the BVH's for each face is already build -void bvh_calc_DOP_hull_from_faces(BVH * bvh, CollisionTree **tri, int numfaces, float *bv) +DO_INLINE void bvh_calc_DOP_hull_from_faces(BVH * bvh, CollisionTree **tri, int numfaces, float *bv) { float newmin,newmax; int i, j; @@ -390,62 +391,35 @@ void bvh_calc_DOP_hull_from_faces(BVH * bvh, CollisionTree **tri, int numfaces, } } -void bvh_calc_DOP_hull_static(BVH * bvh, CollisionTree **tri, int numfaces, float *bv) +DO_INLINE void bvh_calc_DOP_hull_static(BVH * bvh, CollisionTree **tri, int numfaces, float *bv) { - MVert *tempMVert = bvh->x; - float *tempBV = bv; - float newminmax; - int i, j, k; - for (j = 0; j < numfaces; j++) - { - // 1 up to 4 vertices per leaf. - for (k = 0; k < 4; k++) - { - int temp = tri[j]->point_index[k]; - - if(temp < 0) - continue; - - // for all Axes. - for (i = KDOP_START; i < KDOP_END; i++) - { - newminmax = INPR(tempMVert[temp].co, KDOP_AXES[i]); - if ((newminmax < tempBV[(2 * i)]) || (k == 0 && j == 0)) - tempBV[(2 * i)] = newminmax; - if ((newminmax > tempBV[(2 * i) + 1])|| (k == 0 && j == 0)) - tempBV[(2 * i) + 1] = newminmax; - } - } - } -} - -void bvh_calc_DOP_hull_moving(BVH * bvh, CollisionTree **tri, int numfaces, float *bv) -{ - MVert *tempMVert = bvh->x; - MVert *tempMVert2 = bvh->xnew; + MFace *tempMFace = bvh->mfaces; float *tempBV = bv; float newminmax; int i, j, k; for (j = 0; j < numfaces; j++) { + tempMFace = bvh->mfaces + (tri [j])->tri_index; // 3 or 4 vertices per face. for (k = 0; k < 4; k++) { - int temp = tri[j]->point_index[k]; - - if(temp < 0) + int temp = 0; + // If this is a triangle. + if (k == 3 && !tempMFace->v4) continue; - + // TODO: other name for "temp" this gets all vertices of a face + if (k == 0) + temp = tempMFace->v1; + else if (k == 1) + temp = tempMFace->v2; + else if (k == 2) + temp = tempMFace->v3; + else if (k == 3) + temp = tempMFace->v4; // for all Axes. for (i = KDOP_START; i < KDOP_END; i++) { - newminmax = INPR(tempMVert[temp].co, KDOP_AXES[i]); - if ((newminmax < tempBV[(2 * i)]) || (k == 0 && j == 0)) - tempBV[(2 * i)] = newminmax; - if ((newminmax > tempBV[(2 * i) + 1])|| (k == 0 && j == 0)) - tempBV[(2 * i) + 1] = newminmax; - - newminmax = INPR(tempMVert2[temp].co, KDOP_AXES[i]); + newminmax = INPR(bvh->current_xold[temp].co, KDOP_AXES[i]); if ((newminmax < tempBV[(2 * i)]) || (k == 0 && j == 0)) tempBV[(2 * i)] = newminmax; if ((newminmax > tempBV[(2 * i) + 1])|| (k == 0 && j == 0)) @@ -455,7 +429,51 @@ void bvh_calc_DOP_hull_moving(BVH * bvh, CollisionTree **tri, int numfaces, floa } } -static void bvh_div_env_node(BVH * bvh, TreeNode *tree, CollisionTree **face_list, unsigned int start, unsigned int end, int lastaxis, LinkNode *nlink) +DO_INLINE void bvh_calc_DOP_hull_moving(BVH * bvh, CollisionTree **tri, int numfaces, float *bv) +{ + MFace *tempMFace = bvh->mfaces; + float *tempBV = bv; + float newminmax; + int i, j, k; + for (j = 0; j < numfaces; j++) + { + tempMFace = bvh->mfaces + (tri [j])->tri_index; + // 3 or 4 vertices per face. + for (k = 0; k < 4; k++) + { + int temp = 0; + // If this is a triangle. + if (k == 3 && !tempMFace->v4) + continue; + // TODO: other name for "temp" this gets all vertices of a face + if (k == 0) + temp = tempMFace->v1; + else if (k == 1) + temp = tempMFace->v2; + else if (k == 2) + temp = tempMFace->v3; + else if (k == 3) + temp = tempMFace->v4; + // for all Axes. + for (i = KDOP_START; i < KDOP_END; i++) + { + newminmax = INPR(bvh->current_xold[temp].co, KDOP_AXES[i]); + if ((newminmax < tempBV[(2 * i)]) || (k == 0 && j == 0)) + tempBV[(2 * i)] = newminmax; + if ((newminmax > tempBV[(2 * i) + 1])|| (k == 0 && j == 0)) + tempBV[(2 * i) + 1] = newminmax; + + newminmax = INPR(bvh->current_x[temp].co, KDOP_AXES[i]); + if ((newminmax < tempBV[(2 * i)]) || (k == 0 && j == 0)) + tempBV[(2 * i)] = newminmax; + if ((newminmax > tempBV[(2 * i) + 1])|| (k == 0 && j == 0)) + tempBV[(2 * i) + 1] = newminmax; + } + } + } +} + +static void bvh_div_env_node(BVH *bvh, CollisionTree *tree, CollisionTree **face_list, unsigned int start, unsigned int end, int lastaxis, LinkNode *nlink) { int i = 0; CollisionTree *newtree = NULL; @@ -523,17 +541,26 @@ static void bvh_div_env_node(BVH * bvh, TreeNode *tree, CollisionTree **face_lis return; } -// mfaces is allowed to be null -// just vertexes are used if mfaces=NULL -BVH *bvh_build (BVH *bvh, MFace *mfaces, unsigned int numfaces) +/* function cannot be directly called - needs alloced bvh */ +void bvh_build (BVH *bvh) { - unsigned int i = 0, j = 0; + unsigned int i = 0, j = 0, k = 0; CollisionTree **face_list=NULL; CollisionTree *tree=NULL; LinkNode *nlink = NULL; + tree = (CollisionTree *)MEM_callocN(sizeof(CollisionTree), "CollisionTree"); + // TODO: check succesfull alloc + BLI_linklist_append(&bvh->tree, tree); + nlink = bvh->tree; + if (tree == NULL) + { + printf("bvh_build: Out of memory for nodes.\n"); + bvh_free(bvh); + return; + } bvh->root = bvh->tree->link; bvh->root->isleaf = 0; bvh->root->parent = NULL; @@ -541,25 +568,7 @@ BVH *bvh_build (BVH *bvh, MFace *mfaces, unsigned int numfaces) if(bvh->numfaces<=1) { - // Why that? --> only one face there - if(bvh->mfaces) - { - bvh->root->point_index[0] = mfaces[0].v1; - bvh->root->point_index[1] = mfaces[0].v2; - bvh->root->point_index[2] = mfaces[0].v3; - if(mfaces[0].v4) - bvh->root->point_index[3] = mfaces[0].v4; - else - bvh->root->point_index[3] = -1; - } - else - { - bvh->root->point_index[0] = 0; - bvh->root->point_index[1] = -1; - bvh->root->point_index[2] = -1; - bvh->root->point_index[3] = -1; - } - + bvh->root->tri_index = 0; // Why that? --> only one face there bvh->root->isleaf = 1; bvh->root->traversed = 0; bvh->root->count_nodes = 0; @@ -569,46 +578,28 @@ BVH *bvh_build (BVH *bvh, MFace *mfaces, unsigned int numfaces) bvh->root->prevLeaf = NULL; } else - { + { // create face boxes face_list = MEM_callocN (bvh->numfaces * sizeof (CollisionTree *), "CollisionTree"); if (face_list == NULL) { printf("bvh_build: Out of memory for face_list.\n"); bvh_free(bvh); - return NULL; + return; } // create face boxes - for(i = 0; i < bvh->numfaces; i++) + for(i = 0, k = 0; i < bvh->numfaces; i++) { - LinkNode *tnlink = NULL; - + LinkNode *tnlink; + tree = (CollisionTree *)MEM_callocN(sizeof(CollisionTree), "CollisionTree"); // TODO: check succesfull alloc tnlink = BLI_linklist_append_fast(&nlink->next, tree); face_list[i] = tree; - - if(bvh->mfaces) - { - tree->point_index[0] = mfaces[i].v1; - tree->point_index[1] = mfaces[i].v2; - tree->point_index[2] = mfaces[i].v3; - if(mfaces[i].v4) - tree->point_index[3] = mfaces[i].v4; - else - tree->point_index[3] = -1; - } - else - { - tree->point_index[0] = i; - tree->point_index[1] = -1; - tree->point_index[2] = -1; - tree->point_index[3] = -1; - } - + tree->tri_index = i; tree->isleaf = 1; tree->nextLeaf = NULL; tree->prevLeaf = bvh->leaf_tree; @@ -641,170 +632,18 @@ BVH *bvh_build (BVH *bvh, MFace *mfaces, unsigned int numfaces) // build root bvh bvh_calc_DOP_hull_from_faces(bvh, face_list, bvh->numfaces, bvh->root->bv); - + // This is the traversal function. bvh_div_env_node(bvh, bvh->root, face_list, 0, bvh->numfaces-1, 0, nlink); if (face_list) MEM_freeN(face_list); - // BLI_edgehash_free(edgehash, NULL); } - - return bvh; -} - -BVH *bvh_build_from_mvert (MFace *mfaces, unsigned int numfaces, MVert *x, unsigned int numverts, float epsilon) -{ - BVH *bvh=NULL; - CollisionTree *tree=NULL; - - bvh = MEM_callocN(sizeof(BVH), "BVH"); - if (bvh == NULL) - { - printf("bvh: Out of memory.\n"); - return NULL; - } - - bvh->flags = 0; - bvh->leaf_tree = NULL; - bvh->leaf_root = NULL; - bvh->tree = NULL; - - bvh->epsilon = epsilon; - bvh->numfaces = numfaces; - bvh->mfaces = mfaces; - - // we have no faces, we save seperate points - if(!mfaces) - { - bvh->numfaces = numverts; - } - - bvh->numverts = numverts; - bvh->xnew = MEM_dupallocN(x); - bvh->x = MEM_dupallocN(x); - tree = (CollisionTree *)MEM_callocN(sizeof(CollisionTree), "CollisionTree"); - - if (tree == NULL) - { - printf("bvh_build: Out of memory for nodes.\n"); - bvh_free(bvh); - return NULL; - } - - BLI_linklist_append(&bvh->tree, tree); - - return bvh_build(bvh, mfaces, numfaces); -} - - -BVH *bvh_build_from_float3 (MFace *mfaces, unsigned int numfaces, float (*x)[3], unsigned int numverts, float epsilon) -{ - BVH *bvh=NULL; - CollisionTree *tree=NULL; - unsigned int i = 0; - - bvh = MEM_callocN(sizeof(BVH), "BVH"); - if (bvh == NULL) - { - printf("bvh: Out of memory.\n"); - return NULL; - } - - bvh->flags = 0; - bvh->leaf_tree = NULL; - bvh->leaf_root = NULL; - bvh->tree = NULL; - - bvh->epsilon = epsilon; - bvh->numfaces = numfaces; - bvh->mfaces = mfaces; - - // we have no faces, we save seperate points - if(!mfaces) - { - bvh->numfaces = numverts; - } - - bvh->numverts = numverts; - bvh->xnew = (MVert *)MEM_callocN(sizeof(MVert)*numverts, "BVH MVert"); - - for(i = 0; i < numverts; i++) - { - VECCOPY(bvh->xnew[i].co, x[i]); - } - - bvh->x = MEM_dupallocN(bvh->xnew); - - tree = (CollisionTree *)MEM_callocN(sizeof(CollisionTree), "CollisionTree"); - - if (tree == NULL) - { - printf("bvh_build: Out of memory for nodes.\n"); - bvh_free(bvh); - return NULL; - } - - BLI_linklist_append(&bvh->tree, tree); - - return bvh_build(bvh, mfaces, numfaces); -} - -BVH *bvh_build_from_float4 (MFace *mfaces, unsigned int numfaces, float (*x)[4], unsigned int numverts, float epsilon) -{ - BVH *bvh=NULL; - CollisionTree *tree=NULL; - unsigned int i = 0; - - bvh = MEM_callocN(sizeof(BVH), "BVH"); - if (bvh == NULL) - { - printf("bvh: Out of memory.\n"); - return NULL; - } - - bvh->flags = 0; - bvh->leaf_tree = NULL; - bvh->leaf_root = NULL; - bvh->tree = NULL; - - bvh->epsilon = epsilon; - bvh->numfaces = numfaces; - bvh->mfaces = mfaces; - - // we have no faces, we save seperate points - if(!mfaces) - { - bvh->numfaces = numverts; - } - - bvh->numverts = numverts; - bvh->xnew = (MVert *)MEM_callocN(sizeof(MVert)*numverts, "BVH MVert"); - - for(i = 0; i < numverts; i++) - { - VECCOPY(bvh->xnew[i].co, x[i]); - } - - bvh->x = MEM_dupallocN(bvh->xnew); - - tree = (CollisionTree *)MEM_callocN(sizeof(CollisionTree), "CollisionTree"); - - if (tree == NULL) - { - printf("bvh_build: Out of memory for nodes.\n"); - bvh_free(bvh); - return NULL; - } - - BLI_linklist_append(&bvh->tree, tree); - - return bvh_build(bvh, mfaces, numfaces); } // bvh_overlap - is it possbile for 2 bv's to collide ? -int bvh_overlap(float *bv1, float *bv2) +DO_INLINE int bvh_overlap(float *bv1, float *bv2) { int i = 0; for (i = KDOP_START; i < KDOP_END; i++) @@ -823,6 +662,7 @@ int bvh_overlap(float *bv1, float *bv2) return 1; } + /** * bvh_traverse - traverse two bvh trees looking for potential collisions. * @@ -830,9 +670,18 @@ int bvh_overlap(float *bv1, float *bv2) * every other triangle that doesn't require any realloc, but uses * much memory */ -int bvh_traverse(CollisionTree *tree1, CollisionTree *tree2, LinkNode **collision_list) +int bvh_traverse(ClothModifierData * clmd, ClothModifierData * coll_clmd, CollisionTree * tree1, CollisionTree * tree2, float step, CM_COLLISION_RESPONSE collision_response) { - int i = 0, ret = 0; + int i = 0, ret=0; + + /* + // Shouldn't be possible + if(!tree1 || !tree2) + { + printf("Error: no tree there\n"); + return 0; + } + */ if (bvh_overlap(tree1->bv, tree2->bv)) { // Check if this node in the first tree is a leaf @@ -841,85 +690,11 @@ int bvh_traverse(CollisionTree *tree1, CollisionTree *tree2, LinkNode **collisio // Check if this node in the second tree a leaf if (tree2->isleaf) { - ////////////////////////////////// - // TODO: check for 3rd point if zero (triangle)!!! - ////////////////////////////////// + // Provide the collision response. - CollisionPair *collpair = NULL; - - if(tree1 != tree2) // do not collide same points - { - //////////////////////////////////////// - // FIRST FACE - //////////////////////////////////////// - - // save potential colliding triangles - collpair = (CollisionPair *)MEM_callocN(sizeof(CollisionPair), "CollisionPair"); - - VECCOPY(collpair->point_indexA, tree1->point_index); - VECCOPY(collpair->point_indexB, tree2->point_index); - - // we use prepend because lots of insertions at end - // of list are horrible slow! - BLI_linklist_prepend(&collision_list[0], collpair); - - //////////////////////////////////////// - // SECOND FACE - //////////////////////////////////////// - if(tree1->point_index[3]) // check for quad face - { - // save potential colliding triangles - collpair = (CollisionPair *)MEM_callocN(sizeof(CollisionPair), "CollisionPair"); - - VECCOPY(collpair->point_indexA, tree1->point_index); - collpair->point_indexA[2] = tree1->point_index[3]; - - VECCOPY(collpair->point_indexB, tree2->point_index); - - // we use prepend because lots of insertions at end - // of list are horrible slow! - BLI_linklist_prepend(&collision_list[0], collpair); - } - //////////////////////////////////////// - // THIRD FACE - //////////////////////////////////////// - if(tree2->point_index[3]) // check for quad face - { - // save potential colliding triangles - collpair = (CollisionPair *)MEM_callocN(sizeof(CollisionPair), "CollisionPair"); - - VECCOPY(collpair->point_indexA, tree1->point_index); - - VECCOPY(collpair->point_indexB, tree2->point_index); - collpair->point_indexB[2] = tree2->point_index[3]; - - // we use prepend because lots of insertions at end - // of list are horrible slow! - BLI_linklist_prepend(&collision_list[0], collpair); - } - //////////////////////////////////////// - // FOURTH FACE - //////////////////////////////////////// - if(tree1->point_index[3] && tree1->point_index[3]) // check for quad face - { - // save potential colliding triangles - collpair = (CollisionPair *)MEM_callocN(sizeof(CollisionPair), "CollisionPair"); - - VECCOPY(collpair->point_indexA, tree1->point_index); - collpair->point_indexA[2] = tree1->point_index[3]; - - VECCOPY(collpair->point_indexB, tree2->point_index); - collpair->point_indexB[2] = tree2->point_index[3]; - - // we use prepend because lots of insertions at end - // of list are horrible slow! - BLI_linklist_prepend(&collision_list[0], collpair); - } - - return 1; - } - else - return 0; + if(collision_response) + collision_response (clmd, coll_clmd, tree1, tree2); + return 1; } else { @@ -927,7 +702,7 @@ int bvh_traverse(CollisionTree *tree1, CollisionTree *tree2, LinkNode **collisio for (i = 0; i < 4; i++) { // Only traverse nodes that exist. - if (tree2->nodes[i] && (bvh_traverse (tree1, tree2->nodes[i], collision_list))) + if (tree2->nodes[i] && bvh_traverse (clmd, coll_clmd, tree1, tree2->nodes[i], step, collision_response)) ret = 1; } } @@ -938,7 +713,7 @@ int bvh_traverse(CollisionTree *tree1, CollisionTree *tree2, LinkNode **collisio for (i = 0; i < 4; i++) { // Only traverse nodes that exist. - if (tree1->nodes [i] && (bvh_traverse (tree1->nodes[i], tree2, collision_list))) + if (tree1->nodes [i] && bvh_traverse (clmd, coll_clmd, tree1->nodes[i], tree2, step, collision_response)) ret = 1; } } @@ -949,7 +724,7 @@ int bvh_traverse(CollisionTree *tree1, CollisionTree *tree2, LinkNode **collisio // bottom up update of bvh tree: // join the 4 children here -void bvh_join(CollisionTree *tree) +void bvh_join(CollisionTree * tree) { int i = 0, j = 0; if (!tree) @@ -979,10 +754,10 @@ void bvh_join(CollisionTree *tree) } // update static bvh -// needs new positions in bvh->x, bvh->xnew +/* you have to update the bvh position before calling this function */ void bvh_update(BVH * bvh, int moving) { - TreeNode *leaf, *parent; + CollisionTree *leaf, *parent; int traversecheck = 1; // if this is zero we don't go further unsigned int j = 0; @@ -993,7 +768,6 @@ void bvh_update(BVH * bvh, int moving) { leaf->parent->traversed = 0; } - if(!moving) bvh_calc_DOP_hull_static(bvh, &leaf, 1, leaf->bv); else @@ -1034,70 +808,3 @@ void bvh_update(BVH * bvh, int moving) } } -void bvh_update_from_mvert(BVH * bvh, MVert *x, unsigned int numverts, MVert *xnew, int moving) -{ - if(!bvh) - return; - - if(numverts!=bvh->numverts) - return; - - if(x) - memcpy(bvh->x, x, sizeof(MVert) * numverts); - - if(xnew) - memcpy(bvh->xnew, xnew, sizeof(MVert) * numverts); - - bvh_update(bvh, moving); -} - -void bvh_update_from_float3(BVH * bvh, float (*x)[3], unsigned int numverts, float (*xnew)[3], int moving) -{ - unsigned int i = 0; - - if(!bvh) - return; - - if(numverts!=bvh->numverts) - return; - - if(x) - { - for(i = 0; i < numverts; i++) - VECCOPY(bvh->x[i].co, x[i]); - } - - if(xnew) - { - for(i = 0; i < numverts; i++) - VECCOPY(bvh->xnew[i].co, xnew[i]); - } - - bvh_update(bvh, moving); -} - -void bvh_update_from_float4(BVH * bvh, float (*x)[4], unsigned int numverts, float (*xnew)[4], int moving) -{ - unsigned int i = 0; - - if(!bvh) - return; - - if(numverts!=bvh->numverts) - return; - - if(x) - { - for(i = 0; i < numverts; i++) - VECCOPY(bvh->x[i].co, x[i]); - } - - if(xnew) - { - for(i = 0; i < numverts; i++) - VECCOPY(bvh->xnew[i].co, xnew[i]); - } - - bvh_update(bvh, moving); -} - diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c index 3b69f47b1f4..8fdfbb71dc9 100644 --- a/source/blender/blenkernel/intern/modifier.c +++ b/source/blender/blenkernel/intern/modifier.c @@ -75,6 +75,7 @@ #include "BKE_main.h" #include "BKE_anim.h" #include "BKE_bad_level_calls.h" +#include "BKE_cloth.h" #include "BKE_curve.h" #include "BKE_customdata.h" #include "BKE_global.h" @@ -5031,6 +5032,145 @@ static void clothModifier_freeData(ModifierData *md) } } +/* Collision */ + +static void collisionModifier_initData(ModifierData *md) +{ + CollisionModifierData *collmd = (CollisionModifierData*) md; + + collmd->x = NULL; + collmd->xnew = NULL; + collmd->current_x = NULL; + collmd->current_xnew = NULL; + collmd->current_v = NULL; + collmd->time = -1; + collmd->numverts = 0; + collmd->tree = NULL; +} + +static void collisionModifier_freeData(ModifierData *md) +{ + CollisionModifierData *collmd = (CollisionModifierData*) md; + + if (collmd) + { + if(collmd->tree) + bvh_free(collmd->tree); + if(collmd->x) + MEM_freeN(collmd->x); + if(collmd->xnew) + MEM_freeN(collmd->xnew); + if(collmd->current_x) + MEM_freeN(collmd->current_x); + if(collmd->current_xnew) + MEM_freeN(collmd->current_xnew); + if(collmd->current_v) + MEM_freeN(collmd->current_v); + + collmd->x = NULL; + collmd->xnew = NULL; + collmd->current_x = NULL; + collmd->current_xnew = NULL; + collmd->current_v = NULL; + collmd->time = -1; + collmd->numverts = 0; + collmd->tree = NULL; + } +} + +static int collisionModifier_dependsOnTime(ModifierData *md) +{ + return 1; +} + +static void collisionModifier_deformVerts( + ModifierData *md, Object *ob, DerivedMesh *derivedData, + float (*vertexCos)[3], int numVerts) +{ + CollisionModifierData *collmd = (CollisionModifierData*) md; + DerivedMesh *dm = NULL; + float current_time = 0; + unsigned int numverts = 0, i = 0; + MVert *tempVert = NULL; + + // if possible use/create DerivedMesh + + if(derivedData) dm = CDDM_copy(derivedData); + else if(ob->type==OB_MESH) dm = CDDM_from_mesh(ob->data, ob); + + if(!ob->pd) + { + printf("collisionModifier_deformVerts: Should not happen!\n"); + return; + } + + if(dm) + { + CDDM_apply_vert_coords(dm, vertexCos); + CDDM_calc_normals(dm); + + + current_time = bsystem_time ( ob, ( float ) G.scene->r.cfra, 0.0 ); + + if(current_time > collmd->time) + { + numverts = dm->getNumVerts ( dm ); + + // check if mesh has changed + if(collmd->x && (numverts != collmd->numverts)) + collisionModifier_freeData((ModifierData *)collmd); + + if(collmd->time == -1) // first time + { + collmd->x = dm->dupVertArray(dm); // frame start position + + for ( i = 0; i < numverts; i++ ) + { + // we save global positions + Mat4MulVecfl ( ob->obmat, collmd->x[i].co ); + } + + collmd->xnew = MEM_dupallocN(collmd->x); // frame end position + collmd->current_x = MEM_dupallocN(collmd->x); // inter-frame + collmd->current_xnew = MEM_dupallocN(collmd->x); // inter-frame + collmd->current_v = MEM_dupallocN(collmd->x); // inter-frame + + collmd->numverts = numverts; + + // TODO: epsilon + // create bounding box hierarchy + collmd->tree = bvh_build_from_mvert(dm->getFaceArray(dm), dm->getNumFaces(dm), collmd->current_x, numverts, ob->pd->pdef_sbift); + } + else if(numverts == collmd->numverts) + { + // put positions to old positions + tempVert = collmd->x; + collmd->x = collmd->xnew; + collmd->xnew = tempVert; + + memcpy(collmd->xnew, dm->getVertArray(dm), numverts*sizeof(MVert)); + + for ( i = 0; i < numverts; i++ ) + { + // we save global positions + Mat4MulVecfl ( ob->obmat, collmd->xnew[i].co ); + } + + memcpy(collmd->current_xnew, dm->getVertArray(dm), numverts*sizeof(MVert)); + memcpy(collmd->current_x, dm->getVertArray(dm), numverts*sizeof(MVert)); + + // recalc static bounding boxes + bvh_update_from_mvert(collmd->tree, collmd->current_x, numverts, NULL, 0); + } + + collmd->time = current_time; + } + } + + if(dm) + dm->release(dm); +} + /* Boolean */ static void booleanModifier_copyData(ModifierData *md, ModifierData *target) @@ -6855,6 +6995,16 @@ ModifierTypeInfo *modifierType_getInfo(ModifierType type) // mti->copyData = clothModifier_copyData; mti->deformVerts = clothModifier_deformVerts; mti->updateDepgraph = clothModifier_updateDepgraph; + + mti = INIT_TYPE(Collision); + mti->type = eModifierTypeType_OnlyDeform; + mti->initData = collisionModifier_initData; + mti->flags = eModifierTypeFlag_AcceptsMesh + | eModifierTypeFlag_RequiresOriginalData; + mti->dependsOnTime = collisionModifier_dependsOnTime; + mti->freeData = collisionModifier_freeData; + mti->deformVerts = collisionModifier_deformVerts; + // mti->copyData = collisionModifier_copyData; mti = INIT_TYPE(Boolean); mti->type = eModifierTypeType_Nonconstructive; diff --git a/source/blender/makesdna/DNA_cloth_types.h b/source/blender/makesdna/DNA_cloth_types.h index 2bbe328d170..ce942f5bbb0 100644 --- a/source/blender/makesdna/DNA_cloth_types.h +++ b/source/blender/makesdna/DNA_cloth_types.h @@ -106,7 +106,7 @@ typedef struct SimulationSettings float bending; /* Flexion spring stiffness. */ float sim_time; int flags; /* flags, see CSIMSETT_FLAGS enum above. */ - short solver_type; /* which solver should be used? */ + short solver_type; /* which solver should be used? txold */ short pad2; float maxgoal; /* see SB */ float eff_force_scale;/* Scaling of effector forces (see softbody_calc_forces).*/ diff --git a/source/blender/src/buttons_object.c b/source/blender/src/buttons_object.c index 581ff63a987..abc45e70183 100644 --- a/source/blender/src/buttons_object.c +++ b/source/blender/src/buttons_object.c @@ -3184,7 +3184,7 @@ static void object_panel_deflection(Object *ob) PartDeflect *pd= ob->pd; but = uiDefButBitS(block, TOG, 1, B_REDR, "Deflection",160,160,150,20, &pd->deflect, 0, 0, 0, 0, "Deflects particles based on collision"); - // uiButSetFunc(but, object_collision__enabletoggle, ob, NULL); + uiButSetFunc(but, object_collision__enabletoggle, ob, NULL); if(pd->deflect) { uiDefBut(block, LABEL, 0, "Particles", 160,140,75,20, NULL, 0.0, 0, 0, 0, ""); @@ -4928,7 +4928,7 @@ static void object_panel_cloth(Object *ob) Cloth *cloth = clmd->clothObject; int defCount; char *clvg1, *clvg2; - char clmvg [] = "Mass Vertex Group%t|None%x0|"; + char clmvg [] = "Weight Paint Groups%t|"; val2=0; @@ -4938,12 +4938,12 @@ static void object_panel_cloth(Object *ob) uiClearButLock(); uiBlockBeginAlign(block); uiDefButF(block, NUM, B_CLOTH_RENEW, "StructStiff:", 10,170,150,20, &clmd->sim_parms.structural, 1.0, 10000.0, 100, 0, "Overall stiffness of structure"); - uiDefButF(block, NUM, B_CLOTH_RENEW, "BendStiff:", 160,170,150,20, &clmd->sim_parms.bending, 0.0, 10000.0, 1000, 0, "Wrinkle possibility"); - uiDefButI(block, NUM, B_CLOTH_RENEW, "Steps per Frame:", 10,150,150,20, &clmd->sim_parms.stepsPerFrame, 1.0, 100.0, 5, 0, "Quality of the simulation (higher=better=slower)"); + uiDefButF(block, NUM, B_CLOTH_RENEW, "BendStiff:", 160,170,150,20, &clmd->sim_parms.bending, 0.0, 10000.0, 1000, 0, "Wrinkle coefficient (higher = less smaller but more big wrinkles)"); + uiDefButI(block, NUM, B_CLOTH_RENEW, "Quality:", 10,150,150,20, &clmd->sim_parms.stepsPerFrame, 1.0, 100.0, 5, 0, "Quality of the simulation (higher=better=slower)"); uiBlockEndAlign(block); uiBlockBeginAlign(block); uiDefButF(block, NUM, B_CLOTH_RENEW, "Spring Damp:", 160,150,150,20, &clmd->sim_parms.Cdis, 0.0, 10.0, 10, 0, "Spring damping"); - uiDefButF(block, NUM, B_DIFF, "Air Damp:", 10,130,150,20, &clmd->sim_parms.Cvi, 0.0, 10.0, 10, 0, "Apply gravitation to point movement"); + uiDefButF(block, NUM, B_DIFF, "Air Damp:", 10,130,150,20, &clmd->sim_parms.Cvi, 0.0, 10.0, 10, 0, "Air has normaly some thickness which slows falling things down"); uiBlockEndAlign(block); uiClearButLock(); @@ -4959,7 +4959,7 @@ static void object_panel_cloth(Object *ob) /* GOAL STUFF */ uiBlockBeginAlign(block); - uiDefButBitI(block, TOG, CLOTH_SIMSETTINGS_FLAG_GOAL, REDRAWVIEW3D, "Use Goal", 10,70,130,20, &clmd->sim_parms.flags, 0, 0, 0, 0, "Define forces for vertices to stick to animated position"); + uiDefButBitI(block, TOG, CLOTH_SIMSETTINGS_FLAG_GOAL, REDRAWVIEW3D, "Pinning of cloth", 10,70,150,20, &clmd->sim_parms.flags, 0, 0, 0, 0, "Define forces for vertices to stick to animated position"); if (clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_GOAL) { if(ob->type==OB_MESH) @@ -4977,26 +4977,15 @@ static void object_panel_cloth(Object *ob) { clmd->sim_parms.vgroup_mass = 0; } + else + if(!clmd->sim_parms.vgroup_mass) + clmd->sim_parms.vgroup_mass = 1; + sprintf (clvg2, "%s%s", clmvg, clvg1); - uiDefButS(block, MENU, B_CLOTH_RENEW, clvg2, 140,70,20,20, &clmd->sim_parms.vgroup_mass, 0, defCount, 0, 0, "Browses available vertex groups"); + uiDefButS(block, MENU, B_CLOTH_RENEW, clvg2, 160,70,150,20, &clmd->sim_parms.vgroup_mass, 0, defCount, 0, 0, "Browses available vertex groups"); MEM_freeN (clvg1); MEM_freeN (clvg2); - - if(clmd->sim_parms.vgroup_mass) - { - bDeformGroup *defGroup = BLI_findlink(&ob->defbase, clmd->sim_parms.vgroup_mass-1); - if(defGroup) - uiDefBut(block, BUT, B_DIFF, defGroup->name, 160,70,130,20, NULL, 0.0, 0.0, 0, 0, "Name of current vertex group"); - else - uiDefBut(block, BUT, B_DIFF, "(no group)", 160,70,130,20, NULL, 0.0, 0.0, 0, 0, "Vertex Group doesn't exist anymore"); - - uiDefIconBut(block, BUT, B_CLOTH_DEL_VG, ICON_X, 290,70,20,20, 0, 0, 0, 0, 0, "Disable use of vertex group"); - - } - else - uiDefButF(block, NUM, B_CLOTH_RENEW, "Goal:", 160,70,150,20, &clmd->sim_parms.defgoal, 0.0, 1.0, 10, 0, "Default Goal (vertex target position) value, when no Vertex Group used"); - } else { @@ -5004,10 +4993,13 @@ static void object_panel_cloth(Object *ob) uiDefButF(block, NUM, B_CLOTH_RENEW, "Goal:", 160,70,150,20, &clmd->sim_parms.defgoal, 0.0, 1.0, 10, 0, "Default Goal (vertex target position) value, when no Vertex Group used"); } - uiDefButF(block, NUM, B_CLOTH_RENEW, "G Stiff:", 10,50,150,20, &clmd->sim_parms.goalspring, 0.0, 500.0, 10, 0, "Goal (vertex target position) spring stiffness"); + uiDefButF(block, NUM, B_CLOTH_RENEW, "Pin Stiff:", 10,50,150,20, &clmd->sim_parms.goalspring, 0.0, 500.0, 10, 0, "Pin (vertex target position) spring stiffness"); + /* + // nobody is changing these ones anyway uiDefButF(block, NUM, B_CLOTH_RENEW, "G Damp:", 160,50,150,20, &clmd->sim_parms.goalfrict , 0.0, 50.0, 10, 0, "Goal (vertex target position) friction"); uiDefButF(block, NUM, B_CLOTH_RENEW, "G Min:", 10,30,150,20, &clmd->sim_parms.mingoal, 0.0, 1.0, 10, 0, "Goal minimum, vertex group weights are scaled to match this range"); uiDefButF(block, NUM, B_CLOTH_RENEW, "G Max:", 160,30,150,20, &clmd->sim_parms.maxgoal, 0.0, 1.0, 10, 0, "Goal maximum, vertex group weights are scaled to match this range"); + */ } uiBlockEndAlign(block); From 3759c772fdafa008965e702098edeb8a2cae373b Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Mon, 21 Jan 2008 10:55:46 +0000 Subject: [PATCH 072/246] Speedup spring creation again, was lost during merge --- source/blender/blenkernel/intern/cloth.c | 60 +++++++++++++----------- 1 file changed, 33 insertions(+), 27 deletions(-) diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c index c68fb983fc9..3fa99279435 100644 --- a/source/blender/blenkernel/intern/cloth.c +++ b/source/blender/blenkernel/intern/cloth.c @@ -1160,6 +1160,7 @@ static void cloth_from_mesh ( Object *ob, ClothModifierData *clmd, DerivedMesh * ***************************************************************************************/ // be carefull: implicit solver has to be resettet when using this one! +// --> only for implicit handling of this spring! int cloth_add_spring ( ClothModifierData *clmd, unsigned int indexA, unsigned int indexB, float restlength, int spring_type) { Cloth *cloth = clmd->clothObject; @@ -1190,7 +1191,7 @@ int cloth_build_springs ( Cloth *cloth, DerivedMesh *dm ) { ClothSpring *spring = NULL, *tspring = NULL, *tspring2 = NULL; unsigned int struct_springs = 0, shear_springs=0, bend_springs = 0; - unsigned int i = 0; + unsigned int i = 0, j = 0, akku_count; unsigned int numverts = dm->getNumVerts ( dm ); unsigned int numedges = dm->getNumEdges ( dm ); unsigned int numfaces = dm->getNumFaces ( dm ); @@ -1200,9 +1201,9 @@ int cloth_build_springs ( Cloth *cloth, DerivedMesh *dm ) LinkNode **edgelist = NULL; EdgeHash *edgehash = NULL; LinkNode *search = NULL, *search2 = NULL; - float temp[3]; - ClothVertex *verts = NULL; - + float temp[3], akku, min, max; + LinkNode *node = NULL, *node2 = NULL; + // error handling if ( numedges==0 ) return 0; @@ -1217,8 +1218,6 @@ int cloth_build_springs ( Cloth *cloth, DerivedMesh *dm ) if ( cloth->springs ) MEM_freeN ( cloth->springs ); - - verts = cloth->verts; // create spring network hash edgehash = BLI_edgehash_new(); @@ -1232,16 +1231,20 @@ int cloth_build_springs ( Cloth *cloth, DerivedMesh *dm ) { spring->ij = medge[i].v1; spring->kl = medge[i].v2; - VECSUB ( temp, verts[spring->kl].x, verts[spring->ij].x ); + VECSUB ( temp, cloth->verts[spring->kl].x, cloth->verts[spring->ij].x ); spring->restlen = sqrt ( INPR ( temp, temp ) ); spring->type = CLOTH_SPRING_TYPE_STRUCTURAL; spring->flags = 0; struct_springs++; - - BLI_linklist_append ( &cloth->springs, spring ); + + if(!i) + node2 = BLI_linklist_append_fast ( &cloth->springs, spring ); + else + node2 = BLI_linklist_append_fast ( &node->next, spring ); + node = node2; } } - + // shear springs for ( i = 0; i < numfaces; i++ ) { @@ -1249,7 +1252,7 @@ int cloth_build_springs ( Cloth *cloth, DerivedMesh *dm ) spring->ij = mface[i].v1; spring->kl = mface[i].v3; - VECSUB ( temp, verts[spring->kl].x, verts[spring->ij].x ); + VECSUB ( temp, cloth->verts[spring->kl].x, cloth->verts[spring->ij].x ); spring->restlen = sqrt ( INPR ( temp, temp ) ); spring->type = CLOTH_SPRING_TYPE_SHEAR; @@ -1257,7 +1260,8 @@ int cloth_build_springs ( Cloth *cloth, DerivedMesh *dm ) BLI_linklist_append ( &edgelist[spring->kl], spring ); shear_springs++; - BLI_linklist_append ( &cloth->springs, spring ); + node2 = BLI_linklist_append_fast ( &node->next, spring ); + node = node2; if ( mface[i].v4 ) { @@ -1265,18 +1269,19 @@ int cloth_build_springs ( Cloth *cloth, DerivedMesh *dm ) spring->ij = mface[i].v2; spring->kl = mface[i].v4; - VECSUB ( temp, verts[spring->kl].x, verts[spring->ij].x ); - spring->restlen = sqrt ( INPR ( temp, temp ) ); - spring->type = CLOTH_SPRING_TYPE_SHEAR; + VECSUB ( temp, cloth->verts[spring->kl].x, cloth->verts[spring->ij].x ); + spring->restlen = sqrt ( INPR ( temp, temp ) ); + spring->type = CLOTH_SPRING_TYPE_SHEAR; - BLI_linklist_append ( &edgelist[spring->ij], spring ); - BLI_linklist_append ( &edgelist[spring->kl], spring ); - shear_springs++; + BLI_linklist_append ( &edgelist[spring->ij], spring ); + BLI_linklist_append ( &edgelist[spring->kl], spring ); + shear_springs++; - BLI_linklist_append ( &cloth->springs, spring ); + node2 = BLI_linklist_append_fast ( &node->next, spring ); + node = node2; } } - + // bending springs search2 = cloth->springs; for ( i = struct_springs; i < struct_springs+shear_springs; i++ ) @@ -1294,35 +1299,36 @@ int cloth_build_springs ( Cloth *cloth, DerivedMesh *dm ) // check for existing spring // check also if startpoint is equal to endpoint if ( !BLI_edgehash_haskey ( edgehash, index2, tspring2->ij ) - && !BLI_edgehash_haskey ( edgehash, tspring2->ij, index2 ) - && ( index2!=tspring2->ij ) ) + && !BLI_edgehash_haskey ( edgehash, tspring2->ij, index2 ) + && ( index2!=tspring2->ij ) ) { spring = ( ClothSpring * ) MEM_callocN ( sizeof ( ClothSpring ), "cloth spring" ); spring->ij = tspring2->ij; spring->kl = index2; - VECSUB ( temp, verts[index2].x, verts[tspring2->ij].x ); + VECSUB ( temp, cloth->verts[index2].x, cloth->verts[tspring2->ij].x ); spring->restlen = sqrt ( INPR ( temp, temp ) ); spring->type = CLOTH_SPRING_TYPE_BENDING; BLI_edgehash_insert ( edgehash, spring->ij, index2, NULL ); bend_springs++; - BLI_linklist_append ( &cloth->springs, spring ); + node2 = BLI_linklist_append_fast ( &node->next, spring ); + node = node2; } search = search->next; } search2 = search2->next; } - + cloth->numsprings = struct_springs + shear_springs + bend_springs; - + for ( i = 0; i < numverts; i++ ) { BLI_linklist_free ( edgelist[i],NULL ); } if ( edgelist ) MEM_freeN ( edgelist ); - + BLI_edgehash_free ( edgehash, NULL ); return 1; From 3db5a4e8dc81fcc6663db267f24bc982dd201a18 Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Tue, 22 Jan 2008 00:34:28 +0000 Subject: [PATCH 073/246] First successfull use of collision modifier. Means: Collision with cloth are enabled using the 'Deflection' panel from now on --- source/blender/blenkernel/BKE_cloth.h | 45 ++++- source/blender/blenkernel/intern/collision.c | 95 ++++++----- source/blender/blenkernel/intern/implicit.c | 3 +- source/blender/blenkernel/intern/kdop.c | 8 +- source/blender/blenkernel/intern/modifier.c | 15 +- source/blender/makesdna/DNA_cloth_types.h | 42 ----- source/blender/makesdna/DNA_modifier_types.h | 7 +- source/blender/src/buttons_object.c | 165 +++++++++---------- 8 files changed, 191 insertions(+), 189 deletions(-) diff --git a/source/blender/blenkernel/BKE_cloth.h b/source/blender/blenkernel/BKE_cloth.h index 592c34ad28e..6ad9893d072 100644 --- a/source/blender/blenkernel/BKE_cloth.h +++ b/source/blender/blenkernel/BKE_cloth.h @@ -61,6 +61,47 @@ struct ClothModifierData; #define CLOTH_MAX_THREAD 2 +/** + * Pin and unpin frames are the frames on which the vertices stop moving. + * They will assume the position they had prior to pinFrame until unpinFrame + * is reached. + */ +typedef struct ClothVertex +{ + int flags; /* General flags per vertex. */ + float v [3]; /* The velocity of the point. */ + float xconst [3]; /* constrained position */ + float x [3]; /* The current position of this vertex. */ + float xold [3]; /* The previous position of this vertex.*/ + float tx [3]; /* temporary position */ + float txold [3]; /* temporary old position */ + float tv[3]; /* temporary "velocity", mostly used as tv = tx-txold */ + float mass; /* mass / weight of the vertex */ + float goal; /* goal, from SB */ + float impulse[3]; /* used in collision.c */ + unsigned int impulse_count; /* same as above */ +} +ClothVertex; + + +/** + * The definition of a spring. + */ +typedef struct ClothSpring +{ + int ij; /* Pij from the paper, one end of the spring. */ + int kl; /* Pkl from the paper, one end of the spring. */ + float restlen; /* The original length of the spring. */ + int matrix_index; /* needed for implicit solver (fast lookup) */ + int type; /* types defined in BKE_cloth.h ("springType") */ + int flags; /* defined in BKE_cloth.h, e.g. deactivated due to tearing */ + float dfdx[3][3]; + float dfdv[3][3]; + float f[3]; +} +ClothSpring; + + /* goal defines */ #define SOFTGOALSNAP 0.999f @@ -161,7 +202,7 @@ typedef struct BVH } BVH; -typedef void ( *CM_COLLISION_RESPONSE ) ( ClothModifierData *clmd, ClothModifierData *coll_clmd, CollisionTree * tree1, CollisionTree * tree2 ); +typedef void ( *CM_COLLISION_RESPONSE ) ( ClothModifierData *clmd, CollisionModifierData *collmd, CollisionTree * tree1, CollisionTree * tree2 ); ///////////////////////////////////////////////// @@ -191,7 +232,7 @@ void bvh_build (BVH *bvh); LinkNode *BLI_linklist_append_fast ( LinkNode **listp, void *ptr ); // needed for collision.c -int bvh_traverse ( ClothModifierData * clmd, ClothModifierData * coll_clmd, CollisionTree * tree1, CollisionTree * tree2, float step, CM_COLLISION_RESPONSE collision_response ); +int bvh_traverse ( ClothModifierData * clmd, CollisionModifierData * collmd, CollisionTree * tree1, CollisionTree * tree2, float step, CM_COLLISION_RESPONSE collision_response ); void bvh_update(BVH * bvh, int moving); //////////////////////////////////////////////// diff --git a/source/blender/blenkernel/intern/collision.c b/source/blender/blenkernel/intern/collision.c index 4ab436b2936..c5e6c119e10 100644 --- a/source/blender/blenkernel/intern/collision.c +++ b/source/blender/blenkernel/intern/collision.c @@ -70,7 +70,11 @@ #include "Bullet-C-Api.h" -// step is limited from 0 (frame start position) to 1 (frame end position) +/*********************************** +Collision modifier code start +***********************************/ + +/* step is limited from 0 (frame start position) to 1 (frame end position) */ void collision_move_object(CollisionModifierData *collmd, float step, float prevstep) { float tv[3] = {0,0,0}; @@ -85,6 +89,7 @@ void collision_move_object(CollisionModifierData *collmd, float step, float prev } } +/* build bounding volume hierarchy from mverts (see kdop.c for whole BVH code) */ BVH *bvh_build_from_mvert (MFace *mfaces, unsigned int numfaces, MVert *x, unsigned int numverts, float epsilon) { BVH *bvh=NULL; @@ -137,6 +142,10 @@ void bvh_update_from_mvert(BVH * bvh, MVert *x, unsigned int numverts, MVert *xn bvh_update(bvh, moving); } +/*********************************** +Collision modifier code end +***********************************/ + /** * gsl_poly_solve_cubic - * @@ -437,19 +446,18 @@ DO_INLINE void calculateFrictionImpulse(float to[3], float vrel[3], float normal VecMulf(to, MAX2(1.0f - frictionConstant * delta_V_n / INPR(vrel_t_pre,vrel_t_pre), 0.0f)); } -int cloth_collision_response_static(ClothModifierData *clmd, ClothModifierData *coll_clmd) +int cloth_collision_response_static(ClothModifierData *clmd, CollisionModifierData *collmd) { unsigned int i = 0; int result = 0; LinkNode *search = NULL; CollPair *collpair = NULL; - Cloth *cloth1, *cloth2; + Cloth *cloth1; float w1, w2, w3, u1, u2, u3; float v1[3], v2[3], relativeVelocity[3]; float magrelVel; cloth1 = clmd->clothObject; - cloth2 = coll_clmd->clothObject; search = clmd->coll_parms.collision_list; @@ -463,17 +471,18 @@ int cloth_collision_response_static(ClothModifierData *clmd, ClothModifierData * cloth1->verts[collpair->ap2].txold, cloth1->verts[collpair->ap3].txold, &w1, &w2, &w3); - + + // was: txold cloth_compute_barycentric(collpair->pb, - cloth2->verts[collpair->bp1].txold, - cloth2->verts[collpair->bp2].txold, - cloth2->verts[collpair->bp3].txold, + collmd->current_x[collpair->bp1].co, + collmd->current_x[collpair->bp2].co, + collmd->current_x[collpair->bp3].co, &u1, &u2, &u3); // Calculate relative "velocity". interpolateOnTriangle(v1, cloth1->verts[collpair->ap1].tv, cloth1->verts[collpair->ap2].tv, cloth1->verts[collpair->ap3].tv, w1, w2, w3); - interpolateOnTriangle(v2, cloth2->verts[collpair->bp1].tv, cloth2->verts[collpair->bp2].tv, cloth2->verts[collpair->bp3].tv, u1, u2, u3); + interpolateOnTriangle(v2, collmd->current_v[collpair->bp1].co, collmd->current_v[collpair->bp2].co, collmd->current_v[collpair->bp3].co, u1, u2, u3); VECSUB(relativeVelocity, v1, v2); @@ -575,21 +584,21 @@ int cloth_collision_response_static(ClothModifierData *clmd, ClothModifierData * int cloth_collision_response_moving_tris(ClothModifierData *clmd, ClothModifierData *coll_clmd) { - + return 1; } int cloth_collision_response_moving_edges(ClothModifierData *clmd, ClothModifierData *coll_clmd) { - + return 1; } -void cloth_collision_static(ClothModifierData *clmd, ClothModifierData *coll_clmd, CollisionTree *tree1, CollisionTree *tree2) +void cloth_collision_static(ClothModifierData *clmd, CollisionModifierData *collmd, CollisionTree *tree1, CollisionTree *tree2) { CollPair *collpair = NULL; - Cloth *cloth1=NULL, *cloth2=NULL; + Cloth *cloth1=NULL; MFace *face1=NULL, *face2=NULL; - ClothVertex *verts1=NULL, *verts2=NULL; + ClothVertex *verts1=NULL; double distance = 0; float epsilon = clmd->coll_parms.epsilon; unsigned int i = 0; @@ -599,13 +608,11 @@ void cloth_collision_static(ClothModifierData *clmd, ClothModifierData *coll_clm collpair = (CollPair *)MEM_callocN(sizeof(CollPair), "cloth coll pair"); cloth1 = clmd->clothObject; - cloth2 = coll_clmd->clothObject; verts1 = cloth1->verts; - verts2 = cloth2->verts; face1 = &(cloth1->mfaces[tree1->tri_index]); - face2 = &(cloth2->mfaces[tree2->tri_index]); + face2 = &(collmd->mfaces[tree2->tri_index]); // check all possible pairs of triangles if(i == 0) @@ -674,7 +681,7 @@ void cloth_collision_static(ClothModifierData *clmd, ClothModifierData *coll_clm { // calc distance + normal distance = plNearestPoints( - verts1[collpair->ap1].txold, verts1[collpair->ap2].txold, verts1[collpair->ap3].txold, verts2[collpair->bp1].txold, verts2[collpair->bp2].txold, verts2[collpair->bp3].txold, collpair->pa,collpair->pb,collpair->vector); + verts1[collpair->ap1].txold, verts1[collpair->ap2].txold, verts1[collpair->ap3].txold, collmd->current_x[collpair->bp1].co, collmd->current_x[collpair->bp2].co, collmd->current_x[collpair->bp3].co, collpair->pa,collpair->pb,collpair->vector); if (distance <= (epsilon + ALMOST_ZERO)) { @@ -688,6 +695,7 @@ void cloth_collision_static(ClothModifierData *clmd, ClothModifierData *coll_clm collpair->distance = distance; BLI_linklist_append(&clmd->coll_parms.collision_list, collpair); + } else { @@ -703,8 +711,8 @@ void cloth_collision_static(ClothModifierData *clmd, ClothModifierData *coll_clm int cloth_are_edges_adjacent(ClothModifierData *clmd, ClothModifierData *coll_clmd, EdgeCollPair *edgecollpair) { - Cloth *cloth1, *cloth2; - ClothVertex *verts1, *verts2; + Cloth *cloth1 = NULL, *cloth2 = NULL; + ClothVertex *verts1 = NULL, *verts2 = NULL; float temp[3]; cloth1 = clmd->clothObject; @@ -1023,7 +1031,7 @@ void cloth_update_collision_objects(float step) int cloth_bvh_objcollision(ClothModifierData * clmd, float step, float dt) { Base *base=NULL; - ClothModifierData *coll_clmd=NULL; + CollisionModifierData *collmd=NULL; Cloth *cloth=NULL; Object *coll_ob=NULL; BVH *cloth_bvh=NULL; @@ -1064,23 +1072,21 @@ int cloth_bvh_objcollision(ClothModifierData * clmd, float step, float dt) for (base = G.scene->base.first; base; base = base->next) { coll_ob = base->object; - coll_clmd = (ClothModifierData *) modifiers_findByType (coll_ob, eModifierType_Cloth); + collmd = (CollisionModifierData *) modifiers_findByType (coll_ob, eModifierType_Collision); - if (!coll_clmd) + if (!collmd) continue; - // if collision object go on - if (coll_clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_COLLOBJ) + if (collmd->tree) { - if (coll_clmd->clothObject && coll_clmd->clothObject->tree) - { - BVH *coll_bvh = coll_clmd->clothObject->tree; + BVH *coll_bvh = collmd->tree; + + collision_move_object(collmd, step + dt, step); - bvh_traverse(clmd, coll_clmd, cloth_bvh->root, coll_bvh->root, step, cloth_collision_static); - } - else - printf ("cloth_bvh_objcollision: found a collision object with clothObject or collData NULL.\n"); + bvh_traverse(clmd, collmd, cloth_bvh->root, coll_bvh->root, step, cloth_collision_static); } + else + printf ("cloth_bvh_objcollision: found a collision object with clothObject or collData NULL.\n"); } // process all collisions (calculate impulses, TODO: also repulses if distance too short) @@ -1094,18 +1100,11 @@ int cloth_bvh_objcollision(ClothModifierData * clmd, float step, float dt) { coll_ob = base->object; - coll_clmd = (ClothModifierData *) modifiers_findByType (coll_ob, eModifierType_Cloth); - if (!coll_clmd) + collmd = (CollisionModifierData *) modifiers_findByType (coll_ob, eModifierType_Collision); + if (!collmd) continue; - // if collision object go on - if (coll_clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_COLLOBJ) - { - if (coll_clmd->clothObject) - result += cloth_collision_response_static(clmd, coll_clmd); - else - printf ("cloth_bvh_objcollision: found a collision object with clothObject or collData NULL.\n"); - } + result += cloth_collision_response_static(clmd, collmd); } // apply impulses in parallel @@ -1140,14 +1139,10 @@ int cloth_bvh_objcollision(ClothModifierData * clmd, float step, float dt) clmd->coll_parms.collision_list = NULL; } - - // printf("ic: %d\n", ic); rounds++; } while(result && (CLOTH_MAX_THRESHOLD>rounds)); - // printf("\n"); - //////////////////////////////////////////////////////////// // update positions // this is needed for bvh_calc_DOP_hull_moving() [kdop.c] @@ -1162,9 +1157,11 @@ int cloth_bvh_objcollision(ClothModifierData * clmd, float step, float dt) //////////////////////////////////////////////////////////// // moving collisions + // + // response code is just missing itm //////////////////////////////////////////////////////////// - + /* // update cloth bvh bvh_update_from_cloth(clmd, 1); // 0 means STATIC, 1 means MOVING @@ -1294,7 +1291,6 @@ int cloth_bvh_objcollision(ClothModifierData * clmd, float step, float dt) } while(result && (CLOTH_MAX_THRESHOLD>rounds)); - //////////////////////////////////////////////////////////// // update positions + velocities //////////////////////////////////////////////////////////// @@ -1305,6 +1301,7 @@ int cloth_bvh_objcollision(ClothModifierData * clmd, float step, float dt) VECADD(verts[i].tx, verts[i].txold, verts[i].tv); } //////////////////////////////////////////////////////////// - + */ + return MIN2(ret, 1); } diff --git a/source/blender/blenkernel/intern/implicit.c b/source/blender/blenkernel/intern/implicit.c index b154cb0e755..4985b3efa3f 100644 --- a/source/blender/blenkernel/intern/implicit.c +++ b/source/blender/blenkernel/intern/implicit.c @@ -850,6 +850,7 @@ DO_INLINE float fbstar(float length, float L, float kb, float cb) return tempfb; } +// function to calculae bending spring force (taken from Choi & Co) DO_INLINE float fbstar_jacobi(float length, float L, float kb, float cb) { float tempfb = kb * fb(length, L); @@ -1331,7 +1332,7 @@ void simulate_implicit_euler(lfVector *Vnew, lfVector *lX, lfVector *lV, lfVecto initdiag_bfmatrix(A, I); zero_lfvector(dV, numverts); - subadd_bfmatrixS_bfmatrixS(A, dFdV, dt, dFdX, (dt*dt)); + subadd_bfmatrixS_bfmatrixS(A, dFdV, dt, dFdX, (dt*dt)); mul_bfmatrix_lfvector(dFdXmV, dFdX, lV); diff --git a/source/blender/blenkernel/intern/kdop.c b/source/blender/blenkernel/intern/kdop.c index ed1da4d19f9..736ffcf0965 100644 --- a/source/blender/blenkernel/intern/kdop.c +++ b/source/blender/blenkernel/intern/kdop.c @@ -670,7 +670,7 @@ DO_INLINE int bvh_overlap(float *bv1, float *bv2) * every other triangle that doesn't require any realloc, but uses * much memory */ -int bvh_traverse(ClothModifierData * clmd, ClothModifierData * coll_clmd, CollisionTree * tree1, CollisionTree * tree2, float step, CM_COLLISION_RESPONSE collision_response) +int bvh_traverse ( ClothModifierData * clmd, CollisionModifierData * collmd, CollisionTree * tree1, CollisionTree * tree2, float step, CM_COLLISION_RESPONSE collision_response) { int i = 0, ret=0; @@ -693,7 +693,7 @@ int bvh_traverse(ClothModifierData * clmd, ClothModifierData * coll_clmd, Collis // Provide the collision response. if(collision_response) - collision_response (clmd, coll_clmd, tree1, tree2); + collision_response (clmd, collmd, tree1, tree2); return 1; } else @@ -702,7 +702,7 @@ int bvh_traverse(ClothModifierData * clmd, ClothModifierData * coll_clmd, Collis for (i = 0; i < 4; i++) { // Only traverse nodes that exist. - if (tree2->nodes[i] && bvh_traverse (clmd, coll_clmd, tree1, tree2->nodes[i], step, collision_response)) + if (tree2->nodes[i] && bvh_traverse (clmd, collmd, tree1, tree2->nodes[i], step, collision_response)) ret = 1; } } @@ -713,7 +713,7 @@ int bvh_traverse(ClothModifierData * clmd, ClothModifierData * coll_clmd, Collis for (i = 0; i < 4; i++) { // Only traverse nodes that exist. - if (tree1->nodes [i] && bvh_traverse (clmd, coll_clmd, tree1->nodes[i], tree2, step, collision_response)) + if (tree1->nodes [i] && bvh_traverse (clmd, collmd, tree1->nodes[i], tree2, step, collision_response)) ret = 1; } } diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c index ed86e1ae17f..da31929442d 100644 --- a/source/blender/blenkernel/intern/modifier.c +++ b/source/blender/blenkernel/intern/modifier.c @@ -5004,7 +5004,7 @@ static void clothModifier_updateDepgraph( CustomDataMask clothModifier_requiredDataMask(ModifierData *md) { - ClothModifierData *clmd = (HookModifierData *)md; + ClothModifierData *clmd = (ClothModifierData *)md; CustomDataMask dataMask = 0; /* ask for vertexgroups if we need them */ @@ -5067,6 +5067,9 @@ static void collisionModifier_freeData(ModifierData *md) if(collmd->current_v) MEM_freeN(collmd->current_v); + if(collmd->mfaces) + MEM_freeN(collmd->mfaces); + collmd->x = NULL; collmd->xnew = NULL; collmd->current_x = NULL; @@ -5075,6 +5078,7 @@ static void collisionModifier_freeData(ModifierData *md) collmd->time = -1; collmd->numverts = 0; collmd->tree = NULL; + collmd->mfaces = NULL; } } @@ -5139,7 +5143,10 @@ static void collisionModifier_deformVerts( // TODO: epsilon // create bounding box hierarchy - collmd->tree = bvh_build_from_mvert(dm->getFaceArray(dm), dm->getNumFaces(dm), collmd->current_x, numverts, ob->pd->pdef_sbift); + collmd->tree = bvh_build_from_mvert(dm->getFaceArray(dm), dm->getNumFaces(dm), collmd->x, numverts, ob->pd->pdef_sbift); + + collmd->mfaces = dm->dupFaceArray(dm); + collmd->numfaces = dm->getNumFaces(dm); } else if(numverts == collmd->numverts) { @@ -5156,8 +5163,8 @@ static void collisionModifier_deformVerts( Mat4MulVecfl ( ob->obmat, collmd->xnew[i].co ); } - memcpy(collmd->current_xnew, dm->getVertArray(dm), numverts*sizeof(MVert)); - memcpy(collmd->current_x, dm->getVertArray(dm), numverts*sizeof(MVert)); + memcpy(collmd->current_xnew, collmd->x, numverts*sizeof(MVert)); + memcpy(collmd->current_x, collmd->x, numverts*sizeof(MVert)); // recalc static bounding boxes bvh_update_from_mvert(collmd->tree, collmd->current_x, numverts, NULL, 0); diff --git a/source/blender/makesdna/DNA_cloth_types.h b/source/blender/makesdna/DNA_cloth_types.h index ce942f5bbb0..3cb76c7a845 100644 --- a/source/blender/makesdna/DNA_cloth_types.h +++ b/source/blender/makesdna/DNA_cloth_types.h @@ -35,48 +35,6 @@ #include "DNA_listBase.h" -/** -* Pin and unpin frames are the frames on which the vertices stop moving. -* They will assume the position they had prior to pinFrame until unpinFrame -* is reached. -*/ -typedef struct ClothVertex -{ - int flags; /* General flags per vertex. */ - float v [3]; /* The velocity of the point. */ - float xconst [3]; /* constrained position */ - float x [3]; /* The current position of this vertex. */ - float xold [3]; /* The previous position of this vertex.*/ - float tx [3]; /* temporary position */ - float txold [3]; /* temporary old position */ - float tv[3]; /* temporary "velocity", mostly used as tv = tx-txold */ - float mass; /* mass / weight of the vertex */ - float goal; /* goal, from SB */ - float impulse[3]; /* used in collision.c */ - unsigned int impulse_count; /* same as above */ -} -ClothVertex; - - -/** -* The definition of a spring. -*/ -typedef struct ClothSpring -{ - int ij; /* Pij from the paper, one end of the spring. */ - int kl; /* Pkl from the paper, one end of the spring. */ - float restlen; /* The original length of the spring. */ - int matrix_index; /* needed for implicit solver (fast lookup) */ - int type; /* types defined in BKE_cloth.h ("springType") */ - int flags; /* defined in BKE_cloth.h, e.g. deactivated due to tearing */ - float dfdx[3][3]; - float dfdv[3][3]; - float f[3]; -} -ClothSpring; - - - /** * This struct contains all the global data required to run a simulation. * At the time of this writing, this structure contains data appropriate diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h index f8b6f4202a5..9ea0a9c2c9a 100644 --- a/source/blender/makesdna/DNA_modifier_types.h +++ b/source/blender/makesdna/DNA_modifier_types.h @@ -354,15 +354,20 @@ typedef struct ClothModifierData { } ClothModifierData; typedef struct CollisionModifierData { - ModifierData modifier; + ModifierData modifier; struct MVert *x; /* position at the beginning of the frame */ struct MVert *xnew; /* position at the end of the frame */ + struct MVert *xold; /* unsued atm, but was discussed during sprint */ struct MVert *current_xnew; /* new position at the actual inter-frame step */ struct MVert *current_x; /* position at the actual inter-frame step */ struct MVert *current_v; /* position at the actual inter-frame step */ + struct MFace *mfaces; /* object face data */ + unsigned int numverts; + unsigned int numfaces; + int pad; float time; struct BVH *tree; /* collision tree for this cloth object */ } CollisionModifierData; diff --git a/source/blender/src/buttons_object.c b/source/blender/src/buttons_object.c index 384b88be1eb..6b5083c5e26 100644 --- a/source/blender/src/buttons_object.c +++ b/source/blender/src/buttons_object.c @@ -4941,101 +4941,94 @@ static void object_panel_cloth(Object *ob) if(clmd) { - but = uiDefButBitI(block, TOG, CLOTH_SIMSETTINGS_FLAG_COLLOBJ, B_EFFECT_DEP, "Collision Object", 170,200,130,20, &clmd->sim_parms.flags, 0, 0, 0, 0, "Sets object to become a cloth collision object"); + Cloth *cloth = clmd->clothObject; + int defCount; + char *clvg1, *clvg2; + char clmvg [] = "Weight Paint Groups%t|"; - if (!(clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_COLLOBJ)) + val2=0; + + /* GENERAL STUFF */ + uiClearButLock(); + uiBlockBeginAlign(block); + uiDefButF(block, NUM, B_CLOTH_RENEW, "StructStiff:", 10,170,150,20, &clmd->sim_parms.structural, 1.0, 10000.0, 100, 0, "Overall stiffness of structure"); + uiDefButF(block, NUM, B_CLOTH_RENEW, "BendStiff:", 160,170,150,20, &clmd->sim_parms.bending, 0.0, 10000.0, 1000, 0, "Wrinkle coefficient (higher = less smaller but more big wrinkles)"); + uiDefButI(block, NUM, B_CLOTH_RENEW, "Quality:", 10,150,150,20, &clmd->sim_parms.stepsPerFrame, 1.0, 100.0, 5, 0, "Quality of the simulation (higher=better=slower)"); + uiBlockEndAlign(block); + uiBlockBeginAlign(block); + uiDefButF(block, NUM, B_CLOTH_RENEW, "Spring Damp:", 160,150,150,20, &clmd->sim_parms.Cdis, 0.0, 10.0, 10, 0, "Spring damping"); + uiDefButF(block, NUM, B_DIFF, "Air Damp:", 10,130,150,20, &clmd->sim_parms.Cvi, 0.0, 10.0, 10, 0, "Air has normaly some thickness which slows falling things down"); + uiBlockEndAlign(block); + + uiClearButLock(); + + uiBlockBeginAlign(block); + uiDefBut(block, LABEL, 0, "Gravity:", 10,100,60,20, NULL, 0.0, 0, 0, 0, ""); + // uiClearButLock(); + + uiDefButF(block, NUM, B_CLOTH_RENEW, "X:", 70,100,80,20, &clmd->sim_parms.gravity[0], -100.0, 100.0, 10, 0, "Apply gravitation to point movement"); + uiDefButF(block, NUM, B_CLOTH_RENEW, "Y:", 150,100,80,20, &clmd->sim_parms.gravity[1], -100.0, 100.0, 10, 0, "Apply gravitation to point movement"); + uiDefButF(block, NUM, B_CLOTH_RENEW, "Z:", 230,100,80,20, &clmd->sim_parms.gravity[2], -100.0, 100.0, 10, 0, "Apply gravitation to point movement"); + uiBlockEndAlign(block); + + /* GOAL STUFF */ + uiBlockBeginAlign(block); + uiDefButBitI(block, TOG, CLOTH_SIMSETTINGS_FLAG_GOAL, REDRAWVIEW3D, "Pinning of cloth", 10,70,150,20, &clmd->sim_parms.flags, 0, 0, 0, 0, "Define forces for vertices to stick to animated position"); + if (clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_GOAL) { - Cloth *cloth = clmd->clothObject; - int defCount; - char *clvg1, *clvg2; - char clmvg [] = "Weight Paint Groups%t|"; - - val2=0; - - // uiDefButBitI(block, TOG, CSIMSETT_FLAG_ADVANCED, REDRAWBUTSOBJECT, "Advanced", 180,200,130,20, &clmd->sim_parms.flags, 0, 0, 0, 0, "Enable advanced mode"); - - /* GENERAL STUFF */ - uiClearButLock(); - uiBlockBeginAlign(block); - uiDefButF(block, NUM, B_CLOTH_RENEW, "StructStiff:", 10,170,150,20, &clmd->sim_parms.structural, 1.0, 10000.0, 100, 0, "Overall stiffness of structure"); - uiDefButF(block, NUM, B_CLOTH_RENEW, "BendStiff:", 160,170,150,20, &clmd->sim_parms.bending, 0.0, 10000.0, 1000, 0, "Wrinkle coefficient (higher = less smaller but more big wrinkles)"); - uiDefButI(block, NUM, B_CLOTH_RENEW, "Quality:", 10,150,150,20, &clmd->sim_parms.stepsPerFrame, 1.0, 100.0, 5, 0, "Quality of the simulation (higher=better=slower)"); - uiBlockEndAlign(block); - uiBlockBeginAlign(block); - uiDefButF(block, NUM, B_CLOTH_RENEW, "Spring Damp:", 160,150,150,20, &clmd->sim_parms.Cdis, 0.0, 10.0, 10, 0, "Spring damping"); - uiDefButF(block, NUM, B_DIFF, "Air Damp:", 10,130,150,20, &clmd->sim_parms.Cvi, 0.0, 10.0, 10, 0, "Air has normaly some thickness which slows falling things down"); - uiBlockEndAlign(block); - - uiClearButLock(); - - uiBlockBeginAlign(block); - uiDefBut(block, LABEL, 0, "Gravity:", 10,100,60,20, NULL, 0.0, 0, 0, 0, ""); - // uiClearButLock(); - - uiDefButF(block, NUM, B_CLOTH_RENEW, "X:", 70,100,80,20, &clmd->sim_parms.gravity[0], -100.0, 100.0, 10, 0, "Apply gravitation to point movement"); - uiDefButF(block, NUM, B_CLOTH_RENEW, "Y:", 150,100,80,20, &clmd->sim_parms.gravity[1], -100.0, 100.0, 10, 0, "Apply gravitation to point movement"); - uiDefButF(block, NUM, B_CLOTH_RENEW, "Z:", 230,100,80,20, &clmd->sim_parms.gravity[2], -100.0, 100.0, 10, 0, "Apply gravitation to point movement"); - uiBlockEndAlign(block); - - /* GOAL STUFF */ - uiBlockBeginAlign(block); - uiDefButBitI(block, TOG, CLOTH_SIMSETTINGS_FLAG_GOAL, REDRAWVIEW3D, "Pinning of cloth", 10,70,150,20, &clmd->sim_parms.flags, 0, 0, 0, 0, "Define forces for vertices to stick to animated position"); - if (clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_GOAL) + if(ob->type==OB_MESH) { - if(ob->type==OB_MESH) - { - - defCount = sizeof (clmvg); - clvg1 = get_vertexgroup_menustr (ob); - clvg2 = MEM_callocN (strlen (clvg1) + 1 + defCount, "clothVgMS"); - if (! clvg2) { - printf ("draw_modifier: error allocating memory for cloth vertex group menu string.\n"); - return; - } - defCount = BLI_countlist (&ob->defbase); - if (defCount == 0) - { - clmd->sim_parms.vgroup_mass = 0; - } - else - if(!clmd->sim_parms.vgroup_mass) - clmd->sim_parms.vgroup_mass = 1; - - sprintf (clvg2, "%s%s", clmvg, clvg1); - - uiDefButS(block, MENU, B_CLOTH_RENEW, clvg2, 160,70,150,20, &clmd->sim_parms.vgroup_mass, 0, defCount, 0, 0, "Browses available vertex groups"); - MEM_freeN (clvg1); - MEM_freeN (clvg2); - } - else - { - uiDefButS(block, TOG, B_CLOTH_RENEW, "W", 140,70,20,20, &clmd->sim_parms.vgroup_mass, 0, 1, 0, 0, "Use control point weight values"); - uiDefButF(block, NUM, B_CLOTH_RENEW, "Goal:", 160,70,150,20, &clmd->sim_parms.defgoal, 0.0, 1.0, 10, 0, "Default Goal (vertex target position) value, when no Vertex Group used"); - } - uiDefButF(block, NUM, B_CLOTH_RENEW, "Pin Stiff:", 10,50,150,20, &clmd->sim_parms.goalspring, 0.0, 500.0, 10, 0, "Pin (vertex target position) spring stiffness"); - /* - // nobody is changing these ones anyway - uiDefButF(block, NUM, B_CLOTH_RENEW, "G Damp:", 160,50,150,20, &clmd->sim_parms.goalfrict , 0.0, 50.0, 10, 0, "Goal (vertex target position) friction"); - uiDefButF(block, NUM, B_CLOTH_RENEW, "G Min:", 10,30,150,20, &clmd->sim_parms.mingoal, 0.0, 1.0, 10, 0, "Goal minimum, vertex group weights are scaled to match this range"); - uiDefButF(block, NUM, B_CLOTH_RENEW, "G Max:", 160,30,150,20, &clmd->sim_parms.maxgoal, 0.0, 1.0, 10, 0, "Goal maximum, vertex group weights are scaled to match this range"); - */ + defCount = sizeof (clmvg); + clvg1 = get_vertexgroup_menustr (ob); + clvg2 = MEM_callocN (strlen (clvg1) + 1 + defCount, "clothVgMS"); + if (! clvg2) { + printf ("draw_modifier: error allocating memory for cloth vertex group menu string.\n"); + return; + } + defCount = BLI_countlist (&ob->defbase); + if (defCount == 0) + { + clmd->sim_parms.vgroup_mass = 0; + } + else + if(!clmd->sim_parms.vgroup_mass) + clmd->sim_parms.vgroup_mass = 1; + + sprintf (clvg2, "%s%s", clmvg, clvg1); + + uiDefButS(block, MENU, B_CLOTH_RENEW, clvg2, 160,70,150,20, &clmd->sim_parms.vgroup_mass, 0, defCount, 0, 0, "Browses available vertex groups"); + MEM_freeN (clvg1); + MEM_freeN (clvg2); } - uiBlockEndAlign(block); - - /* - // no tearing supported anymore since modifier stack restrictions - uiBlockBeginAlign(block); - uiDefButBitI(block, TOG, CSIMSETT_FLAG_TEARING_ENABLED, B_EFFECT_DEP, "Tearing", 10,0,150,20, &clmd->sim_parms.flags, 0, 0, 0, 0, "Sets object to become a cloth collision object"); - - if (clmd->sim_parms.flags & CSIMSETT_FLAG_TEARING_ENABLED) + else { - uiDefButI(block, NUM, B_DIFF, "Max extent:", 160,0,150,20, &clmd->sim_parms.maxspringlen, 1.0, 1000.0, 10, 0, "Maximum extension before spring gets cut"); - } + uiDefButS(block, TOG, B_CLOTH_RENEW, "W", 140,70,20,20, &clmd->sim_parms.vgroup_mass, 0, 1, 0, 0, "Use control point weight values"); + uiDefButF(block, NUM, B_CLOTH_RENEW, "Goal:", 160,70,150,20, &clmd->sim_parms.defgoal, 0.0, 1.0, 10, 0, "Default Goal (vertex target position) value, when no Vertex Group used"); + } - uiBlockEndAlign(block); + uiDefButF(block, NUM, B_CLOTH_RENEW, "Pin Stiff:", 10,50,150,20, &clmd->sim_parms.goalspring, 0.0, 500.0, 10, 0, "Pin (vertex target position) spring stiffness"); + /* + // nobody is changing these ones anyway + uiDefButF(block, NUM, B_CLOTH_RENEW, "G Damp:", 160,50,150,20, &clmd->sim_parms.goalfrict , 0.0, 50.0, 10, 0, "Goal (vertex target position) friction"); + uiDefButF(block, NUM, B_CLOTH_RENEW, "G Min:", 10,30,150,20, &clmd->sim_parms.mingoal, 0.0, 1.0, 10, 0, "Goal minimum, vertex group weights are scaled to match this range"); + uiDefButF(block, NUM, B_CLOTH_RENEW, "G Max:", 160,30,150,20, &clmd->sim_parms.maxgoal, 0.0, 1.0, 10, 0, "Goal maximum, vertex group weights are scaled to match this range"); */ } + uiBlockEndAlign(block); + + /* + // no tearing supported anymore since modifier stack restrictions + uiBlockBeginAlign(block); + uiDefButBitI(block, TOG, CSIMSETT_FLAG_TEARING_ENABLED, B_EFFECT_DEP, "Tearing", 10,0,150,20, &clmd->sim_parms.flags, 0, 0, 0, 0, "Sets object to become a cloth collision object"); + + if (clmd->sim_parms.flags & CSIMSETT_FLAG_TEARING_ENABLED) + { + uiDefButI(block, NUM, B_DIFF, "Max extent:", 160,0,150,20, &clmd->sim_parms.maxspringlen, 1.0, 1000.0, 10, 0, "Maximum extension before spring gets cut"); + } + + uiBlockEndAlign(block); + */ } } From 35c93b07bd18590b4b80acc8c8a6adf1d6f122c1 Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Tue, 22 Jan 2008 20:28:12 +0000 Subject: [PATCH 074/246] GUI cloth panel refactor, also made many code rearrangements, cleared DNA up --- source/blender/blenkernel/BKE_cloth.h | 115 ++-------- source/blender/blenkernel/BKE_modifier.h | 2 +- source/blender/blenkernel/intern/cloth.c | 136 ++++++------ source/blender/blenkernel/intern/collision.c | 95 ++------- source/blender/blenkernel/intern/implicit.c | 43 ++-- source/blender/blenkernel/intern/modifier.c | 55 +++-- source/blender/blenloader/intern/readfile.c | 36 ++-- source/blender/blenloader/intern/writefile.c | 15 +- source/blender/makesdna/DNA_cloth_types.h | 5 +- source/blender/makesdna/DNA_modifier_types.h | 6 +- source/blender/src/buttons_object.c | 208 +++++++++---------- 11 files changed, 297 insertions(+), 419 deletions(-) diff --git a/source/blender/blenkernel/BKE_cloth.h b/source/blender/blenkernel/BKE_cloth.h index 6ad9893d072..cb52e2f3ca0 100644 --- a/source/blender/blenkernel/BKE_cloth.h +++ b/source/blender/blenkernel/BKE_cloth.h @@ -35,6 +35,7 @@ #define BKE_CLOTH_H #include "BLI_linklist.h" +#include "BKE_collision.h" #include "BKE_customdata.h" #include "BKE_DerivedMesh.h" #include "DNA_cloth_types.h" @@ -48,7 +49,7 @@ struct Cloth; struct MFace; struct DerivedMesh; struct ClothModifierData; - +struct CollisionTree; // this is needed for inlining behaviour #ifndef _WIN32 @@ -60,7 +61,6 @@ struct ClothModifierData; #define CLOTH_MAX_THREAD 2 - /** * Pin and unpin frames are the frames on which the vertices stop moving. * They will assume the position they had prior to pinFrame until unpinFrame @@ -169,40 +169,7 @@ void implicit_set_positions ( ClothModifierData *clmd ); // from cloth.c, needed for modifier.c void clothModifier_do ( ClothModifierData *clmd, Object *ob, DerivedMesh *dm, float ( *vertexCos ) [3], int numverts ); -// used in collision.c -typedef struct CollisionTree -{ - struct CollisionTree *nodes[4]; // 4 children --> quad-tree - struct CollisionTree *parent; - struct CollisionTree *nextLeaf; - struct CollisionTree *prevLeaf; - float bv[26]; // Bounding volume of all nodes / we have 7 axes on a 14-DOP - unsigned int tri_index; // this saves the index of the face - // int point_index[4]; // supports up to 4 points in a leaf - int count_nodes; // how many nodes are used - int traversed; // how many nodes already traversed until this level? - int isleaf; -} -CollisionTree; - -typedef struct BVH -{ - unsigned int numfaces; - unsigned int numverts; - // ClothVertex *verts; // just a pointer to the original datastructure - MVert *current_x; // e.g. txold in clothvertex - MVert *current_xold; // e.g. tx in clothvertex - MFace *mfaces; // just a pointer to the original datastructure - struct LinkNode *tree; - CollisionTree *root; // TODO: saving the root --> is this really needed? YES! - CollisionTree *leaf_tree; /* Tail of the leaf linked list. */ - CollisionTree *leaf_root; /* Head of the leaf linked list. */ - float epsilon; /* epslion is used for inflation of the k-dop */ - int flags; /* bvhFlags */ -} -BVH; - -typedef void ( *CM_COLLISION_RESPONSE ) ( ClothModifierData *clmd, CollisionModifierData *collmd, CollisionTree * tree1, CollisionTree * tree2 ); +typedef void ( *CM_COLLISION_RESPONSE ) ( ClothModifierData *clmd, CollisionModifierData *collmd, CollisionTree *tree1, CollisionTree *tree2 ); ///////////////////////////////////////////////// @@ -213,30 +180,20 @@ typedef void ( *CM_COLLISION_RESPONSE ) ( ClothModifierData *clmd, CollisionModi void bvh_collision_response ( ClothModifierData *clmd, ClothModifierData *coll_clmd, CollisionTree * tree1, CollisionTree * tree2 ); int cloth_bvh_objcollision ( ClothModifierData * clmd, float step, float dt ); -// needed for modifier.c -BVH *bvh_build_from_mvert (MFace *mfaces, unsigned int numfaces, MVert *x, unsigned int numverts, float epsilon); - -// needed for collision.c -void bvh_update_from_mvert(BVH * bvh, MVert *x, unsigned int numverts, MVert *xnew, int moving); - -//////////////////////////////////////////////// - - -///////////////////////////////////////////////// -// kdop.c -//////////////////////////////////////////////// - -// needed for cloth.c -void bvh_free ( BVH * bvh ); -void bvh_build (BVH *bvh); -LinkNode *BLI_linklist_append_fast ( LinkNode **listp, void *ptr ); - -// needed for collision.c int bvh_traverse ( ClothModifierData * clmd, CollisionModifierData * collmd, CollisionTree * tree1, CollisionTree * tree2, float step, CM_COLLISION_RESPONSE collision_response ); -void bvh_update(BVH * bvh, int moving); //////////////////////////////////////////////// +//////////////////////////////////////////////// +// implicit.c +//////////////////////////////////////////////// + +// needed for cloth.c +int implicit_init ( Object *ob, ClothModifierData *clmd ); +int implicit_free ( ClothModifierData *clmd ); +int implicit_solver ( Object *ob, float frame, ClothModifierData *clmd, ListBase *effectors ); +//////////////////////////////////////////////// + ///////////////////////////////////////////////// // cloth.c @@ -276,12 +233,6 @@ typedef struct } CM_SOLVER_DEF; - -/* new C implicit simulator */ -int implicit_init ( Object *ob, ClothModifierData *clmd ); -int implicit_free ( ClothModifierData *clmd ); -int implicit_solver ( Object *ob, float frame, ClothModifierData *clmd, ListBase *effectors ); - /* used for caching in implicit.c */ typedef struct Frame { @@ -292,45 +243,5 @@ typedef struct Frame } Frame; -/* used for collisions in collision.c */ -typedef struct CollPair -{ - unsigned int face1; // cloth face - unsigned int face2; // object face - double distance; // magnitude of vector - float normal[3]; - float vector[3]; // unnormalized collision vector: p2-p1 - float pa[3], pb[3]; // collision point p1 on face1, p2 on face2 - int lastsign; // indicates if the distance sign has changed, unused itm - float time; // collision time, from 0 up to 1 - unsigned int ap1, ap2, ap3, bp1, bp2, bp3, bp4; - unsigned int pointsb[4]; -} -CollPair; - -/* used for collisions in collision.c */ -typedef struct EdgeCollPair -{ - unsigned int p11, p12, p21, p22; - float normal[3]; - float vector[3]; - float time; - int lastsign; - float pa[3], pb[3]; // collision point p1 on face1, p2 on face2 -} -EdgeCollPair; - -/* used for collisions in collision.c */ -typedef struct FaceCollPair -{ - unsigned int p11, p12, p13, p21; - float normal[3]; - float vector[3]; - float time; - int lastsign; - float pa[3], pb[3]; // collision point p1 on face1, p2 on face2 -} -FaceCollPair; - #endif diff --git a/source/blender/blenkernel/BKE_modifier.h b/source/blender/blenkernel/BKE_modifier.h index 682eb1a00dd..068190cb6fa 100644 --- a/source/blender/blenkernel/BKE_modifier.h +++ b/source/blender/blenkernel/BKE_modifier.h @@ -287,7 +287,7 @@ int modifiers_getCageIndex(struct Object *ob, int *lastPossibleCageIndex_r); int modifiers_isSoftbodyEnabled(struct Object *ob); -ModifierData * modifiers_isClothEnabled(Object *ob); +ClothModifierData * modifiers_isClothEnabled(Object *ob); int modifiers_isParticleEnabled(struct Object *ob); struct Object *modifiers_isDeformedByArmature(struct Object *ob); diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c index 3fa99279435..1b284d0d35a 100644 --- a/source/blender/blenkernel/intern/cloth.c +++ b/source/blender/blenkernel/intern/cloth.c @@ -141,46 +141,46 @@ static void cloth_apply_vgroup ( ClothModifierData *clmd, DerivedMesh *dm, short * 2. fill object with standard values or with the GUI settings if given */ void cloth_init ( ClothModifierData *clmd ) -{ +{ /* Initialize our new data structure to reasonable values. */ - clmd->sim_parms.gravity [0] = 0.0; - clmd->sim_parms.gravity [1] = 0.0; - clmd->sim_parms.gravity [2] = -9.81; - clmd->sim_parms.structural = 100.0; - clmd->sim_parms.shear = 100.0; - clmd->sim_parms.bending = 1.0; - clmd->sim_parms.Cdis = 5.0; - clmd->sim_parms.Cvi = 1.0; - clmd->sim_parms.mass = 1.0f; - clmd->sim_parms.stepsPerFrame = 5; - clmd->sim_parms.sim_time = 1.0; - clmd->sim_parms.flags = CLOTH_SIMSETTINGS_FLAG_RESET; - clmd->sim_parms.solver_type = 0; - clmd->sim_parms.preroll = 0; - clmd->sim_parms.maxspringlen = 10; - clmd->sim_parms.firstframe = 1; - clmd->sim_parms.lastframe = 250; - clmd->sim_parms.vgroup_mass = 0; - clmd->coll_parms.self_friction = 5.0; - clmd->coll_parms.friction = 10.0; - clmd->coll_parms.loop_count = 1; - clmd->coll_parms.epsilon = 0.01f; - clmd->coll_parms.flags = 0; + clmd->sim_parms->gravity [0] = 0.0; + clmd->sim_parms->gravity [1] = 0.0; + clmd->sim_parms->gravity [2] = -9.81; + clmd->sim_parms->structural = 100.0; + clmd->sim_parms->shear = 100.0; + clmd->sim_parms->bending = 1.0; + clmd->sim_parms->Cdis = 5.0; + clmd->sim_parms->Cvi = 1.0; + clmd->sim_parms->mass = 1.0f; + clmd->sim_parms->stepsPerFrame = 5; + clmd->sim_parms->sim_time = 1.0; + clmd->sim_parms->flags = CLOTH_SIMSETTINGS_FLAG_RESET; + clmd->sim_parms->solver_type = 0; + clmd->sim_parms->preroll = 0; + clmd->sim_parms->maxspringlen = 10; + clmd->sim_parms->firstframe = 1; + clmd->sim_parms->lastframe = 250; + clmd->sim_parms->vgroup_mass = 0; + clmd->coll_parms->self_friction = 5.0; + clmd->coll_parms->friction = 10.0; + clmd->coll_parms->loop_count = 1; + clmd->coll_parms->epsilon = 0.01f; + clmd->coll_parms->flags = 0; /* These defaults are copied from softbody.c's * softbody_calc_forces() function. */ - clmd->sim_parms.eff_force_scale = 1000.0; - clmd->sim_parms.eff_wind_scale = 250.0; + clmd->sim_parms->eff_force_scale = 1000.0; + clmd->sim_parms->eff_wind_scale = 250.0; // also from softbodies - clmd->sim_parms.maxgoal = 1.0f; - clmd->sim_parms.mingoal = 0.0f; - clmd->sim_parms.defgoal = 0.0f; - clmd->sim_parms.goalspring = 100.0f; - clmd->sim_parms.goalfrict = 0.0f; + clmd->sim_parms->maxgoal = 1.0f; + clmd->sim_parms->mingoal = 0.0f; + clmd->sim_parms->defgoal = 0.0f; + clmd->sim_parms->goalspring = 100.0f; + clmd->sim_parms->goalfrict = 0.0f; - clmd->sim_parms.cache = NULL; + clmd->sim_parms->cache = NULL; } @@ -488,7 +488,7 @@ void cloth_clear_cache(Object *ob, ClothModifierData *clmd, float framenr) { int stack_index = -1; - if(!(clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_CCACHE_PROTECT)) + if(!(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_CCACHE_PROTECT)) { stack_index = modifiers_indexInObject(ob, (ModifierData *)clmd); @@ -557,7 +557,7 @@ static int cloth_read_cache(Object *ob, ClothModifierData *clmd, float framenr) fclose(fp); } - if(clmd->sim_parms.solver_type == 0) + if(clmd->sim_parms->solver_type == 0) implicit_set_positions(clmd); return ret; @@ -585,21 +585,21 @@ void clothModifier_do ( ClothModifierData *clmd, Object *ob, DerivedMesh *dm, ClothVertex *newframe= NULL, *verts; Frame *frame = NULL; LinkNode *search = NULL; - float deltaTime = current_time - clmd->sim_parms.sim_time; + float deltaTime = current_time - clmd->sim_parms->sim_time; - clmd->sim_parms.ob = ob; + clmd->sim_parms->ob = ob; // only be active during a specific period: // that's "first frame" and "last frame" on GUI /* - if ( ! ( clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_COLLOBJ ) ) + if ( ! ( clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_COLLOBJ ) ) { if ( clmd->clothObject ) { - if ( clmd->sim_parms.cache ) + if ( clmd->sim_parms->cache ) { - if ( current_time < clmd->sim_parms.firstframe ) + if ( current_time < clmd->sim_parms->firstframe ) { int frametime = cloth_cache_first_frame ( clmd ); if ( cloth_cache_search_frame ( clmd, frametime ) ) @@ -609,7 +609,7 @@ void clothModifier_do ( ClothModifierData *clmd, Object *ob, DerivedMesh *dm, } return; } - else if ( current_time > clmd->sim_parms.lastframe ) + else if ( current_time > clmd->sim_parms->lastframe ) { int frametime = cloth_cache_last_frame ( clmd ); if ( cloth_cache_search_frame ( clmd, frametime ) ) @@ -626,7 +626,7 @@ void clothModifier_do ( ClothModifierData *clmd, Object *ob, DerivedMesh *dm, cloth_cache_get_frame ( clmd, framenr ); cloth_to_object ( ob, clmd, vertexCos, numverts ); } - clmd->sim_parms.sim_time = current_time; + clmd->sim_parms->sim_time = current_time; return; } } @@ -636,28 +636,28 @@ void clothModifier_do ( ClothModifierData *clmd, Object *ob, DerivedMesh *dm, */ // unused in the moment, calculated seperately in implicit.c - clmd->sim_parms.dt = 1.0f / clmd->sim_parms.stepsPerFrame; + clmd->sim_parms->dt = 1.0f / clmd->sim_parms->stepsPerFrame; - clmd->sim_parms.sim_time = current_time; + clmd->sim_parms->sim_time = current_time; // check if cloth object was some collision object before and needs freeing now - if ( ! ( clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_COLLOBJ ) && ( clmd->clothObject != NULL ) && ( clmd->clothObject->old_solver_type == 255 ) ) + if ( ! ( clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_COLLOBJ ) && ( clmd->clothObject != NULL ) && ( clmd->clothObject->old_solver_type == 255 ) ) { // temporary set CSIMSETT_FLAG_COLLOBJ flag for proper freeing - clmd->sim_parms.flags |= CLOTH_SIMSETTINGS_FLAG_COLLOBJ; + clmd->sim_parms->flags |= CLOTH_SIMSETTINGS_FLAG_COLLOBJ; cloth_free_modifier ( clmd ); - clmd->sim_parms.flags &= ~CLOTH_SIMSETTINGS_FLAG_COLLOBJ; + clmd->sim_parms->flags &= ~CLOTH_SIMSETTINGS_FLAG_COLLOBJ; } // This is for collisions objects: check special case CSIMSETT_FLAG_COLLOBJ - if ( clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_COLLOBJ ) + if ( clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_COLLOBJ ) { // save next position + time if ( ( clmd->clothObject == NULL ) || ( numverts != clmd->clothObject->numverts ) ) { if ( !collobj_from_object ( ob, clmd, dm, vertexCos, framenr ) ) { - clmd->sim_parms.flags |= CLOTH_SIMSETTINGS_FLAG_COLLOBJ; + clmd->sim_parms->flags |= CLOTH_SIMSETTINGS_FLAG_COLLOBJ; cloth_free_modifier ( clmd ); return; } @@ -669,8 +669,8 @@ void clothModifier_do ( ClothModifierData *clmd, Object *ob, DerivedMesh *dm, } // Save old position - clmd->sim_parms.sim_time_old = clmd->sim_parms.sim_time; - clmd->sim_parms.sim_time = current_time; + clmd->sim_parms->sim_time_old = clmd->sim_parms->sim_time; + clmd->sim_parms->sim_time = current_time; verts = cloth->verts; @@ -707,7 +707,7 @@ void clothModifier_do ( ClothModifierData *clmd, Object *ob, DerivedMesh *dm, cloth = clmd->clothObject; } - clmd->clothObject->old_solver_type = clmd->sim_parms.solver_type; + clmd->clothObject->old_solver_type = clmd->sim_parms->solver_type; // Insure we have a clmd->clothObject, in case allocation failed. if ( clmd->clothObject != NULL ) @@ -731,8 +731,8 @@ void clothModifier_do ( ClothModifierData *clmd, Object *ob, DerivedMesh *dm, tstart(); // Call the solver. - if ( solvers [clmd->sim_parms.solver_type].solver ) - solvers [clmd->sim_parms.solver_type].solver ( ob, framenr, clmd, effectors ); + if ( solvers [clmd->sim_parms->solver_type].solver ) + solvers [clmd->sim_parms->solver_type].solver ( ob, framenr, clmd, effectors ); tend(); // printf ( "Cloth simulation time: %f\n", ( float ) tval() ); @@ -749,7 +749,7 @@ void clothModifier_do ( ClothModifierData *clmd, Object *ob, DerivedMesh *dm, cloth_to_object ( ob, clmd, vertexCos, numverts ); // bvh_free(clmd->clothObject->tree); - // clmd->clothObject->tree = bvh_build(clmd, clmd->coll_parms.epsilon); + // clmd->clothObject->tree = bvh_build(clmd, clmd->coll_parms->epsilon); } } @@ -772,14 +772,14 @@ void clothModifier_do ( ClothModifierData *clmd, Object *ob, DerivedMesh *dm, void cloth_free_modifier ( ClothModifierData *clmd ) { Cloth *cloth = NULL; - Object *ob = clmd->sim_parms.ob; + Object *ob = clmd->sim_parms->ob; if ( !clmd ) return; cloth = clmd->clothObject; - if ( ! ( clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_CCACHE_PROTECT ) ) + if ( ! ( clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_CCACHE_PROTECT ) ) { if ( cloth ) { @@ -898,7 +898,7 @@ static void cloth_apply_vgroup ( ClothModifierData *clmd, DerivedMesh *dm, short for ( i = 0; i < numverts; i++, verts++ ) { // LATER ON, support also mass painting here - if ( clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_GOAL ) + if ( clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL ) { dvert = dm->getVertData ( dm, i, CD_MDEFORMVERT ); if ( dvert ) @@ -913,7 +913,7 @@ static void cloth_apply_vgroup ( ClothModifierData *clmd, DerivedMesh *dm, short /* // Kicking goal factor to simplify things...who uses that anyway? - // ABS ( clmd->sim_parms.maxgoal - clmd->sim_parms.mingoal ); + // ABS ( clmd->sim_parms->maxgoal - clmd->sim_parms->mingoal ); */ verts->goal = ( float ) pow ( verts->goal , 4.0f ); @@ -990,7 +990,7 @@ static int collobj_from_object ( Object *ob, ClothModifierData *clmd, DerivedMes verts->impulse_count = 0; VECCOPY ( verts->impulse, tnull ); } - clmd->clothObject->tree = bvh_build_from_cloth ( clmd,clmd->coll_parms.epsilon ); + clmd->clothObject->tree = bvh_build_from_cloth ( clmd,clmd->coll_parms->epsilon ); } @@ -1039,7 +1039,7 @@ static int cloth_from_object ( Object *ob, ClothModifierData *clmd, DerivedMesh return 0; } - clmd->sim_parms.ob = ob; + clmd->sim_parms->ob = ob; switch ( ob->type ) { @@ -1066,10 +1066,10 @@ static int cloth_from_object ( Object *ob, ClothModifierData *clmd, DerivedMesh VECCOPY ( verts->x, mvert[i].co ); Mat4MulVecfl ( ob->obmat, verts->x ); - verts->mass = clmd->sim_parms.mass; + verts->mass = clmd->sim_parms->mass; - if ( clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_GOAL ) - verts->goal= clmd->sim_parms.defgoal; + if ( clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL ) + verts->goal= clmd->sim_parms->defgoal; else verts->goal= 0.0f; @@ -1090,14 +1090,14 @@ static int cloth_from_object ( Object *ob, ClothModifierData *clmd, DerivedMesh } // apply / set vertex groups - if ( clmd->sim_parms.vgroup_mass > 0 ) - cloth_apply_vgroup ( clmd, dm, clmd->sim_parms.vgroup_mass ); + if ( clmd->sim_parms->vgroup_mass > 0 ) + cloth_apply_vgroup ( clmd, dm, clmd->sim_parms->vgroup_mass ); // init our solver - if ( solvers [clmd->sim_parms.solver_type].init ) - solvers [clmd->sim_parms.solver_type].init ( ob, clmd ); + if ( solvers [clmd->sim_parms->solver_type].init ) + solvers [clmd->sim_parms->solver_type].init ( ob, clmd ); - clmd->clothObject->tree = bvh_build_from_cloth ( clmd, clmd->coll_parms.epsilon ); + clmd->clothObject->tree = bvh_build_from_cloth ( clmd, clmd->coll_parms->epsilon ); cloth_write_cache(ob, clmd, framenr-1); } diff --git a/source/blender/blenkernel/intern/collision.c b/source/blender/blenkernel/intern/collision.c index c5e6c119e10..75201bbcea3 100644 --- a/source/blender/blenkernel/intern/collision.c +++ b/source/blender/blenkernel/intern/collision.c @@ -459,7 +459,7 @@ int cloth_collision_response_static(ClothModifierData *clmd, CollisionModifierDa cloth1 = clmd->clothObject; - search = clmd->coll_parms.collision_list; + search = clmd->coll_parms->collision_list; while(search) { @@ -503,10 +503,10 @@ int cloth_collision_response_static(ClothModifierData *clmd, CollisionModifierDa float vrel_t_pre[3]; float vrel_t[3]; double impulse; - float epsilon = clmd->coll_parms.epsilon; + float epsilon = clmd->coll_parms->epsilon; float overlap = (epsilon + ALMOST_ZERO-collpair->distance); - // calculateFrictionImpulse(tangential, relativeVelocity, collpair->normal, magrelVel, clmd->coll_parms.friction*0.01, magrelVel); + // calculateFrictionImpulse(tangential, relativeVelocity, collpair->normal, magrelVel, clmd->coll_parms->friction*0.01, magrelVel); // magtangent = INPR(tangential, tangential); @@ -562,11 +562,11 @@ int cloth_collision_response_static(ClothModifierData *clmd, CollisionModifierDa // Apply the impulse and increase impulse counters. /* - // calculateFrictionImpulse(tangential, collvel, collpair->normal, magtangent, clmd->coll_parms.friction*0.01, magtangent); + // calculateFrictionImpulse(tangential, collvel, collpair->normal, magtangent, clmd->coll_parms->friction*0.01, magtangent); VECSUBS(vrel_t_pre, collvel, collpair->normal, magnormal); - // VecMulf(vrel_t_pre, clmd->coll_parms.friction*0.01f/INPR(vrel_t_pre,vrel_t_pre)); + // VecMulf(vrel_t_pre, clmd->coll_parms->friction*0.01f/INPR(vrel_t_pre,vrel_t_pre)); magtangent = Normalize(vrel_t_pre); - VecMulf(vrel_t_pre, MIN2(clmd->coll_parms.friction*0.01f*magnormal,magtangent)); + VecMulf(vrel_t_pre, MIN2(clmd->coll_parms->friction*0.01f*magnormal,magtangent)); VECSUB(cloth1->verts[face1->v1].tv, cloth1->verts[face1->v1].tv,vrel_t_pre); */ @@ -600,7 +600,7 @@ void cloth_collision_static(ClothModifierData *clmd, CollisionModifierData *coll MFace *face1=NULL, *face2=NULL; ClothVertex *verts1=NULL; double distance = 0; - float epsilon = clmd->coll_parms.epsilon; + float epsilon = clmd->coll_parms->epsilon; unsigned int i = 0; for(i = 0; i < 4; i++) @@ -694,7 +694,7 @@ void cloth_collision_static(ClothModifierData *clmd, CollisionModifierData *coll Normalize(collpair->normal); collpair->distance = distance; - BLI_linklist_append(&clmd->coll_parms.collision_list, collpair); + BLI_linklist_append(&clmd->coll_parms->collision_list, collpair); } else @@ -747,7 +747,7 @@ void cloth_collision_moving_edges(ClothModifierData *clmd, ClothModifierData *co MFace *face1=NULL, *face2=NULL; ClothVertex *verts1=NULL, *verts2=NULL; double distance = 0; - float epsilon = clmd->coll_parms.epsilon; + float epsilon = clmd->coll_parms->epsilon; unsigned int i = 0, j = 0, k = 0; int numsolutions = 0; float a[3], b[3], c[3], d[3], e[3], f[3], solution[3]; @@ -882,7 +882,7 @@ void cloth_collision_moving_tris(ClothModifierData *clmd, ClothModifierData *col MFace *face1=NULL, *face2=NULL; ClothVertex *verts1=NULL, *verts2=NULL; double distance = 0; - float epsilon = clmd->coll_parms.epsilon; + float epsilon = clmd->coll_parms->epsilon; unsigned int i = 0, j = 0, k = 0; int numsolutions = 0; float a[3], b[3], c[3], d[3], e[3], f[3], solution[3]; @@ -978,52 +978,6 @@ void cloth_collision_moving(ClothModifierData *clmd, ClothModifierData *coll_clm cloth_collision_moving_tris(coll_clmd, clmd, tree2, tree1); } -// move collision objects forward in time and update static bounding boxes -void cloth_update_collision_objects(float step) -{ - Base *base=NULL; - ClothModifierData *coll_clmd=NULL; - Object *coll_ob=NULL; - unsigned int i=0; - - // search all objects for collision object - for (base = G.scene->base.first; base; base = base->next) - { - - coll_ob = base->object; - coll_clmd = (ClothModifierData *) modifiers_findByType (coll_ob, eModifierType_Cloth); - if (!coll_clmd) - continue; - - // if collision object go on - if (coll_clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_COLLOBJ) - { - if (coll_clmd->clothObject && coll_clmd->clothObject->tree) - { - Cloth *coll_cloth = coll_clmd->clothObject; - BVH *coll_bvh = coll_clmd->clothObject->tree; - unsigned int coll_numverts = coll_cloth->numverts; - - // update position of collision object - for(i = 0; i < coll_numverts; i++) - { - VECCOPY(coll_cloth->verts[i].txold, coll_cloth->verts[i].tx); - - VECADDS(coll_cloth->verts[i].tx, coll_cloth->verts[i].xold, coll_cloth->verts[i].v, step); - - // no dt here because of float rounding errors - VECSUB(coll_cloth->verts[i].tv, coll_cloth->verts[i].tx, coll_cloth->verts[i].txold); - } - - // update BVH of collision object - bvh_update_from_cloth(coll_clmd, 0); // 0 means STATIC, 1 means MOVING - } - else - printf ("cloth_bvh_objcollision: found a collision object with clothObject or collData NULL.\n"); - } - } -} - // CLOTH_MAX_THRESHOLD defines how much collision rounds/loops should be taken #define CLOTH_MAX_THRESHOLD 10 @@ -1041,7 +995,7 @@ int cloth_bvh_objcollision(ClothModifierData * clmd, float step, float dt) float tnull[3] = {0,0,0}; int ret = 0; - if ((clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_COLLOBJ) || !(((Cloth *)clmd->clothObject)->tree)) + if ((clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_COLLOBJ) || !(((Cloth *)clmd->clothObject)->tree)) { return 0; } @@ -1059,14 +1013,11 @@ int cloth_bvh_objcollision(ClothModifierData * clmd, float step, float dt) // update cloth bvh bvh_update_from_cloth(clmd, 0); // 0 means STATIC, 1 means MOVING (see later in this function) - // update collision objects - cloth_update_collision_objects(step); - do { result = 0; ic = 0; - clmd->coll_parms.collision_list = NULL; + clmd->coll_parms->collision_list = NULL; // check all collision objects for (base = G.scene->base.first; base; base = base->next) @@ -1125,9 +1076,9 @@ int cloth_bvh_objcollision(ClothModifierData * clmd, float step, float dt) } // free collision list - if(clmd->coll_parms.collision_list) + if(clmd->coll_parms->collision_list) { - LinkNode *search = clmd->coll_parms.collision_list; + LinkNode *search = clmd->coll_parms->collision_list; while(search) { CollPair *coll_pair = search->link; @@ -1135,9 +1086,9 @@ int cloth_bvh_objcollision(ClothModifierData * clmd, float step, float dt) MEM_freeN(coll_pair); search = search->next; } - BLI_linklist_free(clmd->coll_parms.collision_list,NULL); + BLI_linklist_free(clmd->coll_parms->collision_list,NULL); - clmd->coll_parms.collision_list = NULL; + clmd->coll_parms->collision_list = NULL; } rounds++; } @@ -1191,7 +1142,7 @@ int cloth_bvh_objcollision(ClothModifierData * clmd, float step, float dt) { result = 0; ic = 0; - clmd->coll_parms.collision_list = NULL; + clmd->coll_parms->collision_list = NULL; // check all collision objects for (base = G.scene->base.first; base; base = base->next) @@ -1203,7 +1154,7 @@ int cloth_bvh_objcollision(ClothModifierData * clmd, float step, float dt) continue; // if collision object go on - if (coll_clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_COLLOBJ) + if (coll_clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_COLLOBJ) { if (coll_clmd->clothObject && coll_clmd->clothObject->tree) { @@ -1233,7 +1184,7 @@ int cloth_bvh_objcollision(ClothModifierData * clmd, float step, float dt) continue; // if collision object go on - if (coll_clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_COLLOBJ) + if (coll_clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_COLLOBJ) { if (coll_clmd->clothObject) result += cloth_collision_response_moving_tris(clmd, coll_clmd); @@ -1271,9 +1222,9 @@ int cloth_bvh_objcollision(ClothModifierData * clmd, float step, float dt) // free collision list - if(clmd->coll_parms.collision_list) + if(clmd->coll_parms->collision_list) { - LinkNode *search = clmd->coll_parms.collision_list; + LinkNode *search = clmd->coll_parms->collision_list; while(search) { CollPair *coll_pair = search->link; @@ -1281,9 +1232,9 @@ int cloth_bvh_objcollision(ClothModifierData * clmd, float step, float dt) MEM_freeN(coll_pair); search = search->next; } - BLI_linklist_free(clmd->coll_parms.collision_list,NULL); + BLI_linklist_free(clmd->coll_parms->collision_list,NULL); - clmd->coll_parms.collision_list = NULL; + clmd->coll_parms->collision_list = NULL; } // printf("ic: %d\n", ic); diff --git a/source/blender/blenkernel/intern/implicit.c b/source/blender/blenkernel/intern/implicit.c index 4985b3efa3f..3f21bf2bfc5 100644 --- a/source/blender/blenkernel/intern/implicit.c +++ b/source/blender/blenkernel/intern/implicit.c @@ -1081,7 +1081,7 @@ DO_INLINE void cloth_calc_spring_force(ClothModifierData *clmd, ClothSpring *s, float vel[3]; float k = 0.0f; float L = s->restlen; - float cb = clmd->sim_parms.structural; + float cb = clmd->sim_parms->structural; float nullf[3] = {0,0,0}; float stretch_force[3] = {0,0,0}; @@ -1089,7 +1089,6 @@ DO_INLINE void cloth_calc_spring_force(ClothModifierData *clmd, ClothSpring *s, float damping_force[3] = {0,0,0}; float nulldfdx[3][3]={ {0,0,0}, {0,0,0}, {0,0,0}}; Cloth *cloth = clmd->clothObject; - ClothVertex *verts = cloth->verts; VECCOPY(s->f, nullf); cp_fmatrix(s->dfdx, nulldfdx); @@ -1107,8 +1106,8 @@ DO_INLINE void cloth_calc_spring_force(ClothModifierData *clmd, ClothSpring *s, /* if(length>L) { - if((clmd->sim_parms.flags & CSIMSETT_FLAG_TEARING_ENABLED) - && ((((length-L)*100.0f/L) > clmd->sim_parms.maxspringlen))) // cut spring! + if((clmd->sim_parms->flags & CSIMSETT_FLAG_TEARING_ENABLED) + && ((((length-L)*100.0f/L) > clmd->sim_parms->maxspringlen))) // cut spring! { s->flags |= CSPRING_FLAG_DEACTIVATE; return; @@ -1130,19 +1129,19 @@ DO_INLINE void cloth_calc_spring_force(ClothModifierData *clmd, ClothSpring *s, { s->flags |= CLOTH_SPRING_FLAG_NEEDED; - k = clmd->sim_parms.structural; + k = clmd->sim_parms->structural; mul_fvector_S(stretch_force, dir, (k*(length-L))); VECADD(s->f, s->f, stretch_force); // Ascher & Boxman, p.21: Damping only during elonglation - mul_fvector_S(damping_force, extent, clmd->sim_parms.Cdis * ((INPR(vel,extent)/length))); + mul_fvector_S(damping_force, extent, clmd->sim_parms->Cdis * ((INPR(vel,extent)/length))); VECADD(s->f, s->f, damping_force); dfdx_spring_type1(s->dfdx, dir,length,L,k); - dfdv_damp(s->dfdv, dir,clmd->sim_parms.Cdis); + dfdv_damp(s->dfdv, dir,clmd->sim_parms->Cdis); } } else // calculate force of bending springs @@ -1151,7 +1150,7 @@ DO_INLINE void cloth_calc_spring_force(ClothModifierData *clmd, ClothSpring *s, { s->flags |= CLOTH_SPRING_FLAG_NEEDED; - k = clmd->sim_parms.bending; + k = clmd->sim_parms->bending; mul_fvector_S(bending_force, dir, fbstar(length, L, k, cb)); VECADD(s->f, s->f, bending_force); @@ -1228,7 +1227,7 @@ void cloth_calc_force(ClothModifierData *clmd, lfVector *lF, lfVector *lX, lfVec /* Collect forces and derivatives: F,dFdX,dFdV */ Cloth *cloth = clmd->clothObject; unsigned int i = 0; - float spring_air = clmd->sim_parms.Cvi * 0.01f; /* viscosity of air scaled in percent */ + float spring_air = clmd->sim_parms->Cvi * 0.01f; /* viscosity of air scaled in percent */ float gravity[3]; float tm2[3][3] = {{-spring_air,0,0}, {0,-spring_air,0},{0,0,-spring_air}}; ClothVertex *verts = cloth->verts; @@ -1240,7 +1239,7 @@ void cloth_calc_force(ClothModifierData *clmd, lfVector *lF, lfVector *lX, lfVec LinkNode *search = cloth->springs; - VECCOPY(gravity, clmd->sim_parms.gravity); + VECCOPY(gravity, clmd->sim_parms->gravity); mul_fvector_S(gravity, gravity, 0.001f); /* scale gravity force */ /* set dFdX jacobi matrix to zero */ @@ -1253,7 +1252,7 @@ void cloth_calc_force(ClothModifierData *clmd, lfVector *lF, lfVector *lX, lfVec submul_lfvectorS(lF, lV, spring_air, numverts); /* do goal stuff */ - if(clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_GOAL) + if(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL) { for(i = 0; i < numverts; i++) { @@ -1265,12 +1264,12 @@ void cloth_calc_force(ClothModifierData *clmd, lfVector *lF, lfVector *lX, lfVec VECADD(tvect, tvect, verts[i].xold); VECSUB(auxvect, tvect, lX[i]); - ks = 1.0f/(1.0f- verts [i].goal*clmd->sim_parms.goalspring)-1.0f ; + ks = 1.0f/(1.0f- verts [i].goal*clmd->sim_parms->goalspring)-1.0f ; VECADDS(lF[i], lF[i], auxvect, -ks); // calulate damping forces generated by goals VECSUB(velgoal,verts[i].xold, verts[i].xconst); - kd = clmd->sim_parms.goalfrict * 0.01f; // friction force scale taken from SB + kd = clmd->sim_parms->goalfrict * 0.01f; // friction force scale taken from SB VECSUBADDSS(lF[i], velgoal, kd, lV[i], kd); } @@ -1287,7 +1286,7 @@ void cloth_calc_force(ClothModifierData *clmd, lfVector *lF, lfVector *lX, lfVec for(i = 0; i < cloth->numverts; i++) { float vertexnormal[3]={0,0,0}; - float fieldfactor = 1000.0f, windfactor = 250.0f; // from sb + float fieldfactor = 1000.0f; // windfactor = 250.0f; // from sb pdDoEffectors(effectors, lX[i], force, speed, (float)G.scene->r.cfra, 0.0f, PE_WIND_AS_SPEED); @@ -1307,7 +1306,7 @@ void cloth_calc_force(ClothModifierData *clmd, lfVector *lF, lfVector *lX, lfVec while(search) { // only handle active springs - // if(((clmd->sim_parms.flags & CSIMSETT_FLAG_TEARING_ENABLED) && !(springs[i].flags & CSPRING_FLAG_DEACTIVATE))|| !(clmd->sim_parms.flags & CSIMSETT_FLAG_TEARING_ENABLED)){} + // if(((clmd->sim_parms->flags & CSIMSETT_FLAG_TEARING_ENABLED) && !(springs[i].flags & CSPRING_FLAG_DEACTIVATE))|| !(clmd->sim_parms->flags & CSIMSETT_FLAG_TEARING_ENABLED)){} cloth_calc_spring_force(clmd, search->link, lF, lX, lV, dFdV, dFdX); search = search->next; @@ -1318,7 +1317,7 @@ void cloth_calc_force(ClothModifierData *clmd, lfVector *lF, lfVector *lX, lfVec while(search) { // only handle active springs - // if(((clmd->sim_parms.flags & CSIMSETT_FLAG_TEARING_ENABLED) && !(springs[i].flags & CSPRING_FLAG_DEACTIVATE))|| !(clmd->sim_parms.flags & CSIMSETT_FLAG_TEARING_ENABLED)) + // if(((clmd->sim_parms->flags & CSIMSETT_FLAG_TEARING_ENABLED) && !(springs[i].flags & CSPRING_FLAG_DEACTIVATE))|| !(clmd->sim_parms->flags & CSIMSETT_FLAG_TEARING_ENABLED)) cloth_apply_spring_force(clmd, search->link, lF, lX, lV, dFdV, dFdX); search = search->next; } @@ -1357,16 +1356,16 @@ void simulate_implicit_euler(lfVector *Vnew, lfVector *lX, lfVector *lV, lfVecto int implicit_solver (Object *ob, float frame, ClothModifierData *clmd, ListBase *effectors) { - unsigned int i=0, j; + unsigned int i=0; float step=0.0f, tf=1.0f; Cloth *cloth = clmd->clothObject; ClothVertex *verts = cloth->verts; unsigned int numverts = cloth->numverts; - float dt = 1.0f / clmd->sim_parms.stepsPerFrame; + float dt = 1.0f / clmd->sim_parms->stepsPerFrame; Implicit_Data *id = cloth->implicit; int result = 0; - if(clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_GOAL) /* do goal stuff */ + if(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL) /* do goal stuff */ { for(i = 0; i < numverts; i++) { @@ -1389,7 +1388,7 @@ int implicit_solver (Object *ob, float frame, ClothModifierData *clmd, ListBase add_lfvector_lfvectorS(id->Xnew, id->X, id->Vnew, dt, numverts); - if(clmd->coll_parms.flags & CLOTH_COLLISIONSETTINGS_FLAG_ENABLED) + if(clmd->coll_parms->flags & CLOTH_COLLISIONSETTINGS_FLAG_ENABLED) { // collisions // itstart(); @@ -1397,7 +1396,7 @@ int implicit_solver (Object *ob, float frame, ClothModifierData *clmd, ListBase // update verts to current positions for(i = 0; i < numverts; i++) { - if(clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_GOAL) /* do goal stuff */ + if(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL) /* do goal stuff */ { if(verts [i].goal >= SOFTGOALSNAP) { @@ -1472,7 +1471,7 @@ int implicit_solver (Object *ob, float frame, ClothModifierData *clmd, ListBase for(i = 0; i < numverts; i++) { - if(clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_GOAL) + if(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL) { if(verts [i].goal < SOFTGOALSNAP) { diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c index da31929442d..9273b6bf9ab 100644 --- a/source/blender/blenkernel/intern/modifier.c +++ b/source/blender/blenkernel/intern/modifier.c @@ -4947,6 +4947,14 @@ static void softbodyModifier_deformVerts( static void clothModifier_initData(ModifierData *md) { ClothModifierData *clmd = (ClothModifierData*) md; + + clmd->sim_parms = MEM_callocN(sizeof(SimulationSettings), "cloth sim parms"); + clmd->coll_parms = MEM_callocN(sizeof(CollisionSettings), "cloth coll parms"); + + /* check for alloc failing */ + if(!clmd->sim_parms || !clmd->coll_parms) + return; + cloth_init (clmd); } @@ -4956,7 +4964,7 @@ static void clothModifier_deformVerts( { DerivedMesh *dm = NULL; - // if possible use/create DerivedMesh + /* if possible use/create DerivedMesh */ if(derivedData) dm = CDDM_copy(derivedData); else if(ob->type==OB_MESH) dm = CDDM_from_mesh(ob->data, ob); @@ -4967,6 +4975,8 @@ static void clothModifier_deformVerts( CDDM_calc_normals(dm); } + /* TODO: check for sim_parms / coll_parms NOT NULL */ + clothModifier_do((ClothModifierData *)md, ob, dm, vertexCos, numVerts); if(dm) @@ -4991,7 +5001,7 @@ static void clothModifier_updateDepgraph( ClothModifierData *coll_clmd = (ClothModifierData *)modifiers_findByType(ob1, eModifierType_Cloth); if(coll_clmd) { - if (coll_clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_COLLOBJ) + if (coll_clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_COLLOBJ) { DagNode *curNode = dag_get_node(forest, ob1); dag_add_relation(forest, curNode, obNode, DAG_RL_DATA_DATA|DAG_RL_OB_DATA); @@ -5008,8 +5018,8 @@ CustomDataMask clothModifier_requiredDataMask(ModifierData *md) CustomDataMask dataMask = 0; /* ask for vertexgroups if we need them */ - if(clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_GOAL) - if (clmd->sim_parms.vgroup_mass > 0) + if(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL) + if (clmd->sim_parms->vgroup_mass > 0) dataMask |= (1 << CD_MDEFORMVERT); return dataMask; @@ -5027,8 +5037,11 @@ static void clothModifier_freeData(ModifierData *md) if (clmd) { - clmd->sim_parms.flags &= ~CLOTH_SIMSETTINGS_FLAG_CCACHE_PROTECT; + clmd->sim_parms->flags &= ~CLOTH_SIMSETTINGS_FLAG_CCACHE_PROTECT; cloth_free_modifier (clmd); + + MEM_freeN(clmd->sim_parms); + MEM_freeN(clmd->coll_parms); } } @@ -5096,9 +5109,8 @@ static void collisionModifier_deformVerts( float current_time = 0; unsigned int numverts = 0, i = 0; MVert *tempVert = NULL; - - // if possible use/create DerivedMesh + /* if possible use/create DerivedMesh */ if(derivedData) dm = CDDM_copy(derivedData); else if(ob->type==OB_MESH) dm = CDDM_from_mesh(ob->data, ob); @@ -5112,12 +5124,11 @@ static void collisionModifier_deformVerts( { CDDM_apply_vert_coords(dm, vertexCos); CDDM_calc_normals(dm); - - + current_time = bsystem_time ( ob, ( float ) G.scene->r.cfra, 0.0 ); if(current_time > collmd->time) - { + { numverts = dm->getNumVerts ( dm ); // check if mesh has changed @@ -5141,12 +5152,12 @@ static void collisionModifier_deformVerts( collmd->numverts = numverts; - // TODO: epsilon - // create bounding box hierarchy - collmd->tree = bvh_build_from_mvert(dm->getFaceArray(dm), dm->getNumFaces(dm), collmd->x, numverts, ob->pd->pdef_sbift); - collmd->mfaces = dm->dupFaceArray(dm); collmd->numfaces = dm->getNumFaces(dm); + + // TODO: epsilon + // create bounding box hierarchy + collmd->tree = bvh_build_from_mvert(collmd->mfaces, collmd->numfaces, collmd->x, numverts, ob->pd->pdef_sbift); } else if(numverts == collmd->numverts) { @@ -5166,8 +5177,16 @@ static void collisionModifier_deformVerts( memcpy(collmd->current_xnew, collmd->x, numverts*sizeof(MVert)); memcpy(collmd->current_x, collmd->x, numverts*sizeof(MVert)); - // recalc static bounding boxes - bvh_update_from_mvert(collmd->tree, collmd->current_x, numverts, NULL, 0); + /* happens on file load (ONLY when i decomment changes in readfile.c */ + if(!collmd->tree) + { + collmd->tree = bvh_build_from_mvert(collmd->mfaces, collmd->numfaces, collmd->current_x, numverts, ob->pd->pdef_sbift); + } + else + { + // recalc static bounding boxes + bvh_update_from_mvert(collmd->tree, collmd->current_x, numverts, NULL, 0); + } } collmd->time = current_time; @@ -7271,11 +7290,11 @@ int modifiers_isSoftbodyEnabled(Object *ob) return (md && md->mode & (eModifierMode_Realtime | eModifierMode_Render)); } -ModifierData * modifiers_isClothEnabled(Object *ob) +ClothModifierData * modifiers_isClothEnabled(Object *ob) { ModifierData *md = modifiers_findByType(ob, eModifierType_Cloth); - return md; + return (ClothModifierData *)md; } int modifiers_isParticleEnabled(Object *ob) diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index af75e9490d5..c725b3d63ac 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -2998,29 +2998,41 @@ static void direct_link_modifiers(FileData *fd, ListBase *lb) SubsurfModifierData *smd = (SubsurfModifierData*) md; smd->emCache = smd->mCache = 0; - } + } else if (md->type==eModifierType_Cloth) { - ClothModifierData *clmd = (ClothModifierData*) md; - - clmd->clothObject = NULL; - /* - clmd->sim_parms= newdataadr(fd, clmd->sim_parms); - clmd->coll_parms= newdataadr(fd, clmd->coll_parms); - */ - - } + ClothModifierData *clmd = (ClothModifierData*) md; + + clmd->clothObject = NULL; + + clmd->sim_parms= newdataadr(fd, clmd->sim_parms); + clmd->coll_parms= newdataadr(fd, clmd->coll_parms); + + } else if (md->type==eModifierType_Collision) { - /* + CollisionModifierData *collmd = (CollisionModifierData*) md; + /* + // TODO: CollisionModifier should use pointcache + // + have proper reset events before enabling this + collmd->x = newdataadr(fd, collmd->x); + collmd->xnew = newdataadr(fd, collmd->xnew); + collmd->mfaces = newdataadr(fd, collmd->mfaces); + + collmd->current_x = MEM_callocN(sizeof(MVert)*collmd->numverts,"current_x"); + collmd->current_xnew = MEM_callocN(sizeof(MVert)*collmd->numverts,"current_xnew"); + collmd->current_v = MEM_callocN(sizeof(MVert)*collmd->numverts,"current_v"); + */ collmd->x = NULL; collmd->xnew = NULL; collmd->current_x = NULL; collmd->current_xnew = NULL; + collmd->current_v = NULL; collmd->time = -1; collmd->numverts = 0; collmd->tree = NULL; - */ + collmd->mfaces = NULL; + } else if (md->type==eModifierType_Hook) { HookModifierData *hmd = (HookModifierData*) md; diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c index 3ac4160b105..8bcc2497dbd 100644 --- a/source/blender/blenloader/intern/writefile.c +++ b/source/blender/blenloader/intern/writefile.c @@ -839,11 +839,22 @@ static void write_modifiers(WriteData *wd, ListBase *modbase) } else if(md->type==eModifierType_Cloth) { ClothModifierData *clmd = (ClothModifierData*) md; - /* + writestruct(wd, DATA, "SimulationSettings", 1, clmd->sim_parms); writestruct(wd, DATA, "CollisionSettings", 1, clmd->coll_parms); - */ + } + else if (md->type==eModifierType_Collision) { + + CollisionModifierData *collmd = (CollisionModifierData*) md; + /* + // TODO: CollisionModifier should use pointcache + // + have proper reset events before enabling this + writestruct(wd, DATA, "MVert", collmd->numverts, collmd->x); + writestruct(wd, DATA, "MVert", collmd->numverts, collmd->xnew); + writestruct(wd, DATA, "MFace", collmd->numfaces, collmd->mfaces); + */ + } else if (md->type==eModifierType_MeshDeform) { MeshDeformModifierData *mmd = (MeshDeformModifierData*) md; int size = mmd->dyngridsize; diff --git a/source/blender/makesdna/DNA_cloth_types.h b/source/blender/makesdna/DNA_cloth_types.h index 3cb76c7a845..ee4a0130dbf 100644 --- a/source/blender/makesdna/DNA_cloth_types.h +++ b/source/blender/makesdna/DNA_cloth_types.h @@ -34,7 +34,6 @@ #include "DNA_listBase.h" - /** * This struct contains all the global data required to run a simulation. * At the time of this writing, this structure contains data appropriate @@ -116,9 +115,9 @@ typedef struct Cloth unsigned char old_solver_type; unsigned char pad2; short pad3; - void *tree; /* collision tree for this cloth object */ + struct BVH *tree; /* collision tree for this cloth object */ struct MFace *mfaces; - void *implicit; /* our implicit solver connects to this pointer */ + struct Implicit_Data *implicit; /* our implicit solver connects to this pointer */ } Cloth; diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h index 9ea0a9c2c9a..e5c3b46d875 100644 --- a/source/blender/makesdna/DNA_modifier_types.h +++ b/source/blender/makesdna/DNA_modifier_types.h @@ -7,8 +7,6 @@ #define MODSTACK_DEBUG 1 -#include "DNA_cloth_types.h" - /* WARNING ALERT! TYPEDEF VALUES ARE WRITTEN IN FILES! SO DO NOT CHANGE! */ typedef enum ModifierType { @@ -349,8 +347,8 @@ typedef struct ClothModifierData { ModifierData modifier; struct Cloth *clothObject; /* The internal data structure for cloth. */ - struct SimulationSettings sim_parms; /* definition is in DNA_cloth_types.h */ - struct CollisionSettings coll_parms; /* definition is in DNA_cloth_types.h */ + struct SimulationSettings *sim_parms; /* definition is in DNA_cloth_types.h */ + struct CollisionSettings *coll_parms; /* definition is in DNA_cloth_types.h */ } ClothModifierData; typedef struct CollisionModifierData { diff --git a/source/blender/src/buttons_object.c b/source/blender/src/buttons_object.c index 6b5083c5e26..90f7dab0a58 100644 --- a/source/blender/src/buttons_object.c +++ b/source/blender/src/buttons_object.c @@ -3083,7 +3083,7 @@ void do_effects_panels(unsigned short event) ClothModifierData *clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth); if(clmd) { - if(clmd->sim_parms.cache) + if(clmd->sim_parms->cache) { CFRA= 1; update_for_newframe_muted(); @@ -3099,7 +3099,7 @@ void do_effects_panels(unsigned short event) ClothModifierData *clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth); if(clmd) { - clmd->sim_parms.vgroup_mass = 0; + clmd->sim_parms->vgroup_mass = 0; do_object_panels(B_CLOTH_RENEW); } allqueue(REDRAWBUTSOBJECT, 0); @@ -4923,25 +4923,25 @@ static void object_cloth__enabletoggle(void *ob_v, void *arg2) allqueue(REDRAWBUTSEDIT, 0); } + static void object_panel_cloth(Object *ob) { uiBlock *block; - static int val, val2; uiBut *but; + static int val, val2; ClothModifierData *clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth); - block= uiNewBlock(&curarea->uiblocks, "object_panel_cloth", UI_EMBOSS, UI_HELV, curarea->win); - if(uiNewPanel(curarea, block, "Cloth", "Physics", 640, 0, 318, 204)==0) return; + + block= uiNewBlock(&curarea->uiblocks, "object_cloth", UI_EMBOSS, UI_HELV, curarea->win); + if(uiNewPanel(curarea, block, "Cloth ", "Physics", 640, 0, 318, 204)==0) return; + uiSetButLock(object_data_is_libdata(ob), ERROR_LIBDATA_MESSAGE); - if(ob->id.lib) uiSetButLock(1, "Can't edit library data"); - val = ((clmd)?(1):(0)); + but = uiDefButI(block, TOG, REDRAWBUTSOBJECT, "Cloth", 10,200,130,20, &val, 0, 0, 0, 0, "Sets object to become cloth"); - but = uiDefButI(block, TOG, REDRAWBUTSOBJECT, "Cloth Object", 10,200,130,20, &val, 0, 0, 0, 0, "Sets object to become cloth"); uiButSetFunc(but, object_cloth__enabletoggle, ob, NULL); uiDefBut(block, LABEL, 0, "",10,10,300,0, NULL, 0.0, 0, 0, 0, ""); /* tell UI we go to 10,10*/ if(clmd) { - Cloth *cloth = clmd->clothObject; int defCount; char *clvg1, *clvg2; char clmvg [] = "Weight Paint Groups%t|"; @@ -4951,13 +4951,13 @@ static void object_panel_cloth(Object *ob) /* GENERAL STUFF */ uiClearButLock(); uiBlockBeginAlign(block); - uiDefButF(block, NUM, B_CLOTH_RENEW, "StructStiff:", 10,170,150,20, &clmd->sim_parms.structural, 1.0, 10000.0, 100, 0, "Overall stiffness of structure"); - uiDefButF(block, NUM, B_CLOTH_RENEW, "BendStiff:", 160,170,150,20, &clmd->sim_parms.bending, 0.0, 10000.0, 1000, 0, "Wrinkle coefficient (higher = less smaller but more big wrinkles)"); - uiDefButI(block, NUM, B_CLOTH_RENEW, "Quality:", 10,150,150,20, &clmd->sim_parms.stepsPerFrame, 1.0, 100.0, 5, 0, "Quality of the simulation (higher=better=slower)"); + uiDefButF(block, NUM, B_CLOTH_RENEW, "StructStiff:", 10,170,150,20, &clmd->sim_parms->structural, 1.0, 10000.0, 100, 0, "Overall stiffness of structure"); + uiDefButF(block, NUM, B_CLOTH_RENEW, "BendStiff:", 160,170,150,20, &clmd->sim_parms->bending, 0.0, 10000.0, 1000, 0, "Wrinkle coefficient (higher = less smaller but more big wrinkles)"); + uiDefButI(block, NUM, B_CLOTH_RENEW, "Quality:", 10,150,150,20, &clmd->sim_parms->stepsPerFrame, 1.0, 100.0, 5, 0, "Quality of the simulation (higher=better=slower)"); uiBlockEndAlign(block); uiBlockBeginAlign(block); - uiDefButF(block, NUM, B_CLOTH_RENEW, "Spring Damp:", 160,150,150,20, &clmd->sim_parms.Cdis, 0.0, 10.0, 10, 0, "Spring damping"); - uiDefButF(block, NUM, B_DIFF, "Air Damp:", 10,130,150,20, &clmd->sim_parms.Cvi, 0.0, 10.0, 10, 0, "Air has normaly some thickness which slows falling things down"); + uiDefButF(block, NUM, B_CLOTH_RENEW, "Spring Damp:", 160,150,150,20, &clmd->sim_parms->Cdis, 0.0, 10.0, 10, 0, "Spring damping"); + uiDefButF(block, NUM, B_DIFF, "Air Damp:", 10,130,150,20, &clmd->sim_parms->Cvi, 0.0, 10.0, 10, 0, "Air has normaly some thickness which slows falling things down"); uiBlockEndAlign(block); uiClearButLock(); @@ -4966,15 +4966,20 @@ static void object_panel_cloth(Object *ob) uiDefBut(block, LABEL, 0, "Gravity:", 10,100,60,20, NULL, 0.0, 0, 0, 0, ""); // uiClearButLock(); - uiDefButF(block, NUM, B_CLOTH_RENEW, "X:", 70,100,80,20, &clmd->sim_parms.gravity[0], -100.0, 100.0, 10, 0, "Apply gravitation to point movement"); - uiDefButF(block, NUM, B_CLOTH_RENEW, "Y:", 150,100,80,20, &clmd->sim_parms.gravity[1], -100.0, 100.0, 10, 0, "Apply gravitation to point movement"); - uiDefButF(block, NUM, B_CLOTH_RENEW, "Z:", 230,100,80,20, &clmd->sim_parms.gravity[2], -100.0, 100.0, 10, 0, "Apply gravitation to point movement"); + uiDefButF(block, NUM, B_CLOTH_RENEW, "X:", 70,100,80,20, &clmd->sim_parms->gravity[0], -100.0, 100.0, 10, 0, "Apply gravitation to point movement"); + uiDefButF(block, NUM, B_CLOTH_RENEW, "Y:", 150,100,80,20, &clmd->sim_parms->gravity[1], -100.0, 100.0, 10, 0, "Apply gravitation to point movement"); + uiDefButF(block, NUM, B_CLOTH_RENEW, "Z:", 230,100,80,20, &clmd->sim_parms->gravity[2], -100.0, 100.0, 10, 0, "Apply gravitation to point movement"); uiBlockEndAlign(block); /* GOAL STUFF */ uiBlockBeginAlign(block); - uiDefButBitI(block, TOG, CLOTH_SIMSETTINGS_FLAG_GOAL, REDRAWVIEW3D, "Pinning of cloth", 10,70,150,20, &clmd->sim_parms.flags, 0, 0, 0, 0, "Define forces for vertices to stick to animated position"); - if (clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_GOAL) + + if(BLI_countlist (&ob->defbase) > 0) + { + uiDefButBitI(block, TOG, CLOTH_SIMSETTINGS_FLAG_GOAL, REDRAWVIEW3D, "Pinning of cloth", 10,70,150,20, &clmd->sim_parms->flags, 0, 0, 0, 0, "Define forces for vertices to stick to animated position"); + } + + if (clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL) { if(ob->type==OB_MESH) { @@ -4989,30 +4994,30 @@ static void object_panel_cloth(Object *ob) defCount = BLI_countlist (&ob->defbase); if (defCount == 0) { - clmd->sim_parms.vgroup_mass = 0; + clmd->sim_parms->vgroup_mass = 0; } else - if(!clmd->sim_parms.vgroup_mass) - clmd->sim_parms.vgroup_mass = 1; + if(!clmd->sim_parms->vgroup_mass) + clmd->sim_parms->vgroup_mass = 1; sprintf (clvg2, "%s%s", clmvg, clvg1); - uiDefButS(block, MENU, B_CLOTH_RENEW, clvg2, 160,70,150,20, &clmd->sim_parms.vgroup_mass, 0, defCount, 0, 0, "Browses available vertex groups"); + uiDefButS(block, MENU, B_CLOTH_RENEW, clvg2, 160,70,150,20, &clmd->sim_parms->vgroup_mass, 0, defCount, 0, 0, "Browses available vertex groups"); MEM_freeN (clvg1); MEM_freeN (clvg2); } else { - uiDefButS(block, TOG, B_CLOTH_RENEW, "W", 140,70,20,20, &clmd->sim_parms.vgroup_mass, 0, 1, 0, 0, "Use control point weight values"); - uiDefButF(block, NUM, B_CLOTH_RENEW, "Goal:", 160,70,150,20, &clmd->sim_parms.defgoal, 0.0, 1.0, 10, 0, "Default Goal (vertex target position) value, when no Vertex Group used"); + uiDefButS(block, TOG, B_CLOTH_RENEW, "W", 140,70,20,20, &clmd->sim_parms->vgroup_mass, 0, 1, 0, 0, "Use control point weight values"); + uiDefButF(block, NUM, B_CLOTH_RENEW, "Goal:", 160,70,150,20, &clmd->sim_parms->defgoal, 0.0, 1.0, 10, 0, "Default Goal (vertex target position) value, when no Vertex Group used"); } - uiDefButF(block, NUM, B_CLOTH_RENEW, "Pin Stiff:", 10,50,150,20, &clmd->sim_parms.goalspring, 0.0, 500.0, 10, 0, "Pin (vertex target position) spring stiffness"); + uiDefButF(block, NUM, B_CLOTH_RENEW, "Pin Stiff:", 10,50,150,20, &clmd->sim_parms->goalspring, 0.0, 500.0, 10, 0, "Pin (vertex target position) spring stiffness"); /* // nobody is changing these ones anyway - uiDefButF(block, NUM, B_CLOTH_RENEW, "G Damp:", 160,50,150,20, &clmd->sim_parms.goalfrict , 0.0, 50.0, 10, 0, "Goal (vertex target position) friction"); - uiDefButF(block, NUM, B_CLOTH_RENEW, "G Min:", 10,30,150,20, &clmd->sim_parms.mingoal, 0.0, 1.0, 10, 0, "Goal minimum, vertex group weights are scaled to match this range"); - uiDefButF(block, NUM, B_CLOTH_RENEW, "G Max:", 160,30,150,20, &clmd->sim_parms.maxgoal, 0.0, 1.0, 10, 0, "Goal maximum, vertex group weights are scaled to match this range"); + uiDefButF(block, NUM, B_CLOTH_RENEW, "G Damp:", 160,50,150,20, &clmd->sim_parms->goalfrict , 0.0, 50.0, 10, 0, "Goal (vertex target position) friction"); + uiDefButF(block, NUM, B_CLOTH_RENEW, "G Min:", 10,30,150,20, &clmd->sim_parms->mingoal, 0.0, 1.0, 10, 0, "Goal minimum, vertex group weights are scaled to match this range"); + uiDefButF(block, NUM, B_CLOTH_RENEW, "G Max:", 160,30,150,20, &clmd->sim_parms->maxgoal, 0.0, 1.0, 10, 0, "Goal maximum, vertex group weights are scaled to match this range"); */ } uiBlockEndAlign(block); @@ -5020,111 +5025,85 @@ static void object_panel_cloth(Object *ob) /* // no tearing supported anymore since modifier stack restrictions uiBlockBeginAlign(block); - uiDefButBitI(block, TOG, CSIMSETT_FLAG_TEARING_ENABLED, B_EFFECT_DEP, "Tearing", 10,0,150,20, &clmd->sim_parms.flags, 0, 0, 0, 0, "Sets object to become a cloth collision object"); + uiDefButBitI(block, TOG, CSIMSETT_FLAG_TEARING_ENABLED, B_EFFECT_DEP, "Tearing", 10,0,150,20, &clmd->sim_parms->flags, 0, 0, 0, 0, "Sets object to become a cloth collision object"); - if (clmd->sim_parms.flags & CSIMSETT_FLAG_TEARING_ENABLED) + if (clmd->sim_parms->flags & CSIMSETT_FLAG_TEARING_ENABLED) { - uiDefButI(block, NUM, B_DIFF, "Max extent:", 160,0,150,20, &clmd->sim_parms.maxspringlen, 1.0, 1000.0, 10, 0, "Maximum extension before spring gets cut"); - } + uiDefButI(block, NUM, B_DIFF, "Max extent:", 160,0,150,20, &clmd->sim_parms->maxspringlen, 1.0, 1000.0, 10, 0, "Maximum extension before spring gets cut"); + } uiBlockEndAlign(block); */ } + + uiBlockEndAlign(block); + + uiBlockEndAlign(block); } - static void object_panel_cloth_II(Object *ob) { uiBlock *block; - static int val; - uiBut *but; ClothModifierData *clmd = NULL; + + block= uiNewBlock(&curarea->uiblocks, "object_cloth_II", UI_EMBOSS, UI_HELV, curarea->win); + uiNewPanelTabbed("Cloth ", "Physics"); + if(uiNewPanel(curarea, block, "Cloth Cache/Collisions", "Physics", 651, 0, 318, 204)==0) return; + + uiSetButLock(object_data_is_libdata(ob), ERROR_LIBDATA_MESSAGE); clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth); - if(clmd) - { - if (!(clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_COLLOBJ)) - { - Cloth *cloth = clmd->clothObject; - char str[128]; - - block= uiNewBlock(&curarea->uiblocks, "object_panel_cloth_II", UI_EMBOSS, UI_HELV, curarea->win); - uiNewPanelTabbed("Cloth", "Physics"); - if(uiNewPanel(curarea, block, "Cloth Cache", "Physics", 651, 0, 318, 204)==0) return; - - uiSetButLock(object_data_is_libdata(ob), ERROR_LIBDATA_MESSAGE); - - uiDefButI(block, NUM, B_DIFF, "First Frame:", 10,160,150,20, &clmd->sim_parms.firstframe, 0, MAXFRAME, 1, 0, "Frame on which the simulation starts"); - uiDefButI(block, NUM, B_DIFF, "Last Frame:", 160,160,150,20, &clmd->sim_parms.lastframe, 0, MAXFRAME, 10, 0, "Frame on which the simulation stops"); - - if(clmd->sim_parms.cache) - { - int length = BLI_linklist_length(clmd->sim_parms.cache); - - /* correct spelling if only 1 frame cacheed --> only gimmick */ - if(length-clmd->sim_parms.preroll>1) - sprintf (str, "Frame 1 - %d cached. [%d in preroll, %d in total]", length-clmd->sim_parms.preroll, clmd->sim_parms.preroll, length); - else - sprintf (str, "Frame %d cached. [%d in preroll, %d in total]", length-clmd->sim_parms.preroll, clmd->sim_parms.preroll, length); - - uiDefBut(block, LABEL, 0, str, 10,140,290,20, NULL, 0.0, 0, 0, 0, ""); - uiDefBut(block, LABEL, 0, "Clear cache:", 10,120,290,20, NULL, 0.0, 0, 0, 0, ""); - uiBlockBeginAlign (block); - uiDefBut(block, BUT, B_CLOTH_CLEARCACHEALL, "All", 10, 100,145,20, NULL, 0.0, 0.0, 0, 0, "Free cloth cache without preroll"); - uiDefBut(block, BUT, B_CLOTH_CLEARCACHEFRAME, "From next frame", 155, 100,145,20, NULL, 0.0, 0.0, 0, 0, "Free cloth cache"); - if(length>1) // B_CLOTH_CHANGEPREROLL - uiDefButI(block, NUM, B_CLOTH_CHANGEPREROLL, "Preroll:", 10,80,145,20, &clmd->sim_parms.preroll, 0, length-1, 1, 0, "Simulation starts on this frame"); - else - uiDefBut(block, LABEL, 0, " ", 10,80,145,20, NULL, 0.0, 0, 0, 0, ""); - } - else - { - uiDefBut(block, LABEL, 0, "No frames cached.", 10,120,290,20, NULL, 0.0, 0, 0, 0, ""); - } - uiDefButBitI(block, TOG, CLOTH_SIMSETTINGS_FLAG_CCACHE_PROTECT, REDRAWVIEW3D, "Protect Cache", 10,50,145,20, &clmd->sim_parms.flags, 0, 0, 0, 0, "Protect cache from automatic freeing when scene changed"); - uiBlockEndAlign(block); - } - } - // uiBlockEndAlign(block); -} - -static void object_panel_cloth_III(Object *ob) -{ - uiBlock *block; - static int val; - uiBut *but; - ClothModifierData *clmd = NULL; - clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth); if(clmd) { - if (!(clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_COLLOBJ)) - { - Cloth *cloth = clmd->clothObject; - char str[128]; - - block= uiNewBlock(&curarea->uiblocks, "object_panel_cloth_III", UI_EMBOSS, UI_HELV, curarea->win); - uiNewPanelTabbed("Cloth", "Physics"); - if(uiNewPanel(curarea, block, "Cloth Collisions", "Physics", 651, 0, 318, 204)==0) return; + // char str[128]; - uiSetButLock(object_data_is_libdata(ob), ERROR_LIBDATA_MESSAGE); - - uiBlockBeginAlign(block); - uiDefButBitI(block, TOG, CLOTH_COLLISIONSETTINGS_FLAG_ENABLED, REDRAWVIEW3D, "Enable collisions", 10,70,130,20, &clmd->coll_parms.flags, 0, 0, 0, 0, "Enable collisions with this object"); - if (clmd->coll_parms.flags & CLOTH_COLLISIONSETTINGS_FLAG_ENABLED) - { - // uiDefBut(block, LABEL, 0, "",10,10,300,20, NULL, 0.0, 0, 0, 0, ""); /* tell UI we go to 10,10*/ - uiDefButF(block, NUM, B_CLOTH_RENEW, "Min Distance:", 10,30,150,20, &clmd->coll_parms.epsilon, 0.001f, 1.0, 0.01f, 0, "Minimum distance between collision objects before collision response takes in"); - uiDefBut(block, LABEL, 0, "",160,30,150,20, NULL, 0.0, 0, 0, 0, ""); - } - else - uiDefBut(block, LABEL, 0, "",140,10,170,20, NULL, 0.0, 0, 0, 0, ""); - uiBlockEndAlign(block); + uiDefButI(block, NUM, B_DIFF, "First Frame:", 10,160,150,20, &clmd->sim_parms->firstframe, 0, MAXFRAME, 1, 0, "Frame on which the simulation starts"); + uiDefButI(block, NUM, B_DIFF, "Last Frame:", 160,160,150,20, &clmd->sim_parms->lastframe, 0, MAXFRAME, 10, 0, "Frame on which the simulation stops"); + + uiDefBut(block, LABEL, 0, "",10,140,300,20, NULL, 0.0, 0, 0, 0, ""); + + /* correct spelling if only 1 frame cacheed --> only gimmick */ + /* + if(length-clmd->sim_parms->preroll>1) + sprintf (str, "Frame 1 - %d cached. [%d in preroll, %d in total]", length-clmd->sim_parms->preroll, clmd->sim_parms->preroll, length); + else + sprintf (str, "Frame %d cached. [%d in preroll, %d in total]", length-clmd->sim_parms->preroll, clmd->sim_parms->preroll, length); + */ + + uiDefButBitI(block, TOG, CLOTH_SIMSETTINGS_FLAG_CCACHE_PROTECT, REDRAWVIEW3D, "Protect Cache", 10,120,300,20, &clmd->sim_parms->flags, 0, 0, 0, 0, "Protect cache from automatic freeing when scene changed"); + + if(!(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_CCACHE_PROTECT)) + { + uiDefBut(block, LABEL, 0, "Clear cache:", 10,100,90,20, NULL, 0.0, 0, 0, 0, ""); + uiDefBut(block, BUT, B_CLOTH_CLEARCACHEALL, "All", 100, 100,100,20, NULL, 0.0, 0.0, 0, 0, "Free ALL cloth cache without preroll"); + uiDefBut(block, BUT, B_CLOTH_CLEARCACHEFRAME, "From next frame", 200, 100,110,20, NULL, 0.0, 0.0, 0, 0, "Free cloth cache starting from next frame"); + uiDefBut(block, LABEL, 0, " ", 10,80,300,20, NULL, 0.0, 0, 0, 0, ""); + } + else + { + uiDefBut(block, LABEL, 0, " ", 10,100,300,40, NULL, 0.0, 0, 0, 0, ""); } - } - // uiBlockEndAlign(block); -} + /* + if(length>1) // B_CLOTH_CHANGEPREROLL + uiDefButI(block, NUM, B_CLOTH_CHANGEPREROLL, "Preroll:", 10,80,145,20, &clmd->sim_parms->preroll, 0, length-1, 1, 0, "Simulation starts on this frame"); + else + uiDefBut(block, LABEL, 0, " ", 10,80,145,20, NULL, 0.0, 0, 0, 0, ""); + */ + + uiDefButBitI(block, TOG, CLOTH_COLLISIONSETTINGS_FLAG_ENABLED, REDRAWVIEW3D, "Enable collisions", 10,60,150,20, &clmd->coll_parms->flags, 0, 0, 0, 0, "Enable collisions with this object"); + if (clmd->coll_parms->flags & CLOTH_COLLISIONSETTINGS_FLAG_ENABLED) + { + uiDefButF(block, NUM, B_CLOTH_RENEW, "Min Distance:", 160,60,150,20, &clmd->coll_parms->epsilon, 0.001f, 1.0, 0.01f, 0, "Minimum distance between collision objects before collision response takes in"); + } + else + uiDefBut(block, LABEL, 0, "",160,60,150,20, NULL, 0.0, 0, 0, 0, ""); + } + + uiBlockEndAlign(block); + +} void object_panels() { @@ -5156,7 +5135,6 @@ void physics_panels() object_softbodies_II(ob); object_panel_cloth(ob); object_panel_cloth_II(ob); - object_panel_cloth_III(ob); object_panel_fluidsim(ob); } } From ab7b4bb892d4bd9926dbc381634d97a556dab3e4 Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Tue, 22 Jan 2008 23:17:10 +0000 Subject: [PATCH 075/246] (hopefully) fixed huge problem with cache/cloth reset. --- source/blender/blenkernel/BKE_cloth.h | 12 +- source/blender/blenkernel/BKE_modifier.h | 2 +- source/blender/blenkernel/intern/cloth.c | 218 +++++++------------- source/blender/blenkernel/intern/modifier.c | 11 +- source/blender/include/butspace.h | 3 +- source/blender/makesdna/DNA_cloth_types.h | 1 - source/blender/src/buttons_object.c | 115 +++++------ source/blender/src/editmesh.c | 3 +- source/blender/src/editobject.c | 3 +- source/blender/src/transform_conversions.c | 3 +- source/blender/src/transform_generics.c | 16 +- source/blender/src/vpaint.c | 3 +- 12 files changed, 163 insertions(+), 227 deletions(-) diff --git a/source/blender/blenkernel/BKE_cloth.h b/source/blender/blenkernel/BKE_cloth.h index cb52e2f3ca0..11de3092e7c 100644 --- a/source/blender/blenkernel/BKE_cloth.h +++ b/source/blender/blenkernel/BKE_cloth.h @@ -198,10 +198,14 @@ int implicit_solver ( Object *ob, float frame, ClothModifierData *clmd, ListBase ///////////////////////////////////////////////// // cloth.c //////////////////////////////////////////////// -void cloth_free_modifier ( ClothModifierData *clmd ); -void cloth_init ( ClothModifierData *clmd ); -void cloth_deform_verts ( struct Object *ob, float framenr, float ( *vertexCos ) [3], int numVerts, void *derivedData, ClothModifierData *clmd ); -void cloth_update_normals ( ClothVertex *verts, int nVerts, MFace *face, int totface ); + +// needed for modifier.c +void cloth_free_modifier_extern (ClothModifierData *clmd); +void cloth_free_modifier (Object *ob, ClothModifierData *clmd); +void cloth_init (ClothModifierData *clmd); +void cloth_deform_verts (struct Object *ob, float framenr, float ( *vertexCos ) [3], int numVerts, void *derivedData, ClothModifierData *clmd); + +void cloth_update_normals (ClothVertex *verts, int nVerts, MFace *face, int totface); // needed for collision.c void bvh_update_from_cloth(ClothModifierData *clmd, int moving); diff --git a/source/blender/blenkernel/BKE_modifier.h b/source/blender/blenkernel/BKE_modifier.h index 068190cb6fa..fba30264fea 100644 --- a/source/blender/blenkernel/BKE_modifier.h +++ b/source/blender/blenkernel/BKE_modifier.h @@ -287,7 +287,7 @@ int modifiers_getCageIndex(struct Object *ob, int *lastPossibleCageIndex_r); int modifiers_isSoftbodyEnabled(struct Object *ob); -ClothModifierData * modifiers_isClothEnabled(Object *ob); +int modifiers_isClothEnabled(struct Object *ob); int modifiers_isParticleEnabled(struct Object *ob); struct Object *modifiers_isDeformedByArmature(struct Object *ob); diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c index 1b284d0d35a..2b5937985ae 100644 --- a/source/blender/blenkernel/intern/cloth.c +++ b/source/blender/blenkernel/intern/cloth.c @@ -124,7 +124,6 @@ static CM_SOLVER_DEF solvers [] = static void cloth_to_object ( Object *ob, ClothModifierData *clmd, float ( *vertexCos ) [3], unsigned int numverts ); static void cloth_from_mesh ( Object *ob, ClothModifierData *clmd, DerivedMesh *dm ); static int cloth_from_object ( Object *ob, ClothModifierData *clmd, DerivedMesh *dm, float ( *vertexCos ) [3], unsigned int numverts, float framenr ); -static int collobj_from_object ( Object *ob, ClothModifierData *clmd, DerivedMesh *dm, float ( *vertexCos ) [3], unsigned int numverts ); int cloth_build_springs ( Cloth *cloth, DerivedMesh *dm ); static void cloth_apply_vgroup ( ClothModifierData *clmd, DerivedMesh *dm, short vgroup ); @@ -165,7 +164,7 @@ void cloth_init ( ClothModifierData *clmd ) clmd->coll_parms->friction = 10.0; clmd->coll_parms->loop_count = 1; clmd->coll_parms->epsilon = 0.01f; - clmd->coll_parms->flags = 0; + clmd->coll_parms->flags = CLOTH_COLLISIONSETTINGS_FLAG_ENABLED; /* These defaults are copied from softbody.c's * softbody_calc_forces() function. @@ -572,24 +571,13 @@ void clothModifier_do ( ClothModifierData *clmd, Object *ob, DerivedMesh *dm, float ( *vertexCos ) [3], int numverts ) { unsigned int i; - unsigned int numedges = -1; - unsigned int numfaces = -1; - MVert *mvert = NULL; - MEdge *medge = NULL; - MFace *mface = NULL; - DerivedMesh *result = NULL, *result2 = NULL; Cloth *cloth = clmd->clothObject; unsigned int framenr = ( float ) G.scene->r.cfra; float current_time = bsystem_time ( ob, ( float ) G.scene->r.cfra, 0.0 ); ListBase *effectors = NULL; - ClothVertex *newframe= NULL, *verts; - Frame *frame = NULL; - LinkNode *search = NULL; + ClothVertex *verts = NULL; float deltaTime = current_time - clmd->sim_parms->sim_time; - clmd->sim_parms->ob = ob; - - // only be active during a specific period: // that's "first frame" and "last frame" on GUI /* @@ -640,56 +628,9 @@ void clothModifier_do ( ClothModifierData *clmd, Object *ob, DerivedMesh *dm, clmd->sim_parms->sim_time = current_time; - // check if cloth object was some collision object before and needs freeing now - if ( ! ( clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_COLLOBJ ) && ( clmd->clothObject != NULL ) && ( clmd->clothObject->old_solver_type == 255 ) ) - { - // temporary set CSIMSETT_FLAG_COLLOBJ flag for proper freeing - clmd->sim_parms->flags |= CLOTH_SIMSETTINGS_FLAG_COLLOBJ; - cloth_free_modifier ( clmd ); - clmd->sim_parms->flags &= ~CLOTH_SIMSETTINGS_FLAG_COLLOBJ; - } - - // This is for collisions objects: check special case CSIMSETT_FLAG_COLLOBJ - if ( clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_COLLOBJ ) - { - // save next position + time - if ( ( clmd->clothObject == NULL ) || ( numverts != clmd->clothObject->numverts ) ) - { - if ( !collobj_from_object ( ob, clmd, dm, vertexCos, framenr ) ) - { - clmd->sim_parms->flags |= CLOTH_SIMSETTINGS_FLAG_COLLOBJ; - cloth_free_modifier ( clmd ); - return; - } - - if ( clmd->clothObject == NULL ) - return; - - cloth = clmd->clothObject; - } - - // Save old position - clmd->sim_parms->sim_time_old = clmd->sim_parms->sim_time; - clmd->sim_parms->sim_time = current_time; - - verts = cloth->verts; - - for ( i = 0; i < clmd->clothObject->numverts; i++, verts++ ) - { - // Save the previous position. - VECCOPY ( verts->xold, verts->x ); - VECCOPY ( verts->txold, verts->x ); - - // Get the current position. - VECCOPY ( verts->x, vertexCos[i] ); - Mat4MulVecfl ( ob->obmat, verts->x ); - - // Compute the vertices "velocity". - // (no dt correction here because of float error) - VECSUB ( verts->v, verts->x, verts->xold ); - } - - return; + if(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_RESET) + { + cloth_free_modifier (ob, clmd); } if ( deltaTime == 1.0f ) @@ -769,10 +710,9 @@ void clothModifier_do ( ClothModifierData *clmd, Object *ob, DerivedMesh *dm, } /* frees all */ -void cloth_free_modifier ( ClothModifierData *clmd ) +void cloth_free_modifier ( Object *ob, ClothModifierData *clmd ) { Cloth *cloth = NULL; - Object *ob = clmd->sim_parms->ob; if ( !clmd ) return; @@ -784,8 +724,7 @@ void cloth_free_modifier ( ClothModifierData *clmd ) if ( cloth ) { // free our frame cache, TODO: but get to first position before - if(ob) - cloth_clear_cache ( ob, clmd, 0 ); + cloth_clear_cache ( ob, clmd, 0 ); // If our solver provides a free function, call it if ( cloth->old_solver_type < 255 && solvers [cloth->old_solver_type].free ) @@ -834,8 +773,72 @@ void cloth_free_modifier ( ClothModifierData *clmd ) clmd->clothObject = NULL; } } + clmd->sim_parms->flags &= ~CLOTH_SIMSETTINGS_FLAG_RESET; } +/* frees all */ +void cloth_free_modifier_extern ( ClothModifierData *clmd ) +{ + Cloth *cloth = NULL; + + if ( !clmd ) + return; + + cloth = clmd->clothObject; + + if ( ! ( clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_CCACHE_PROTECT ) ) + { + if ( cloth ) + { + // If our solver provides a free function, call it + if ( cloth->old_solver_type < 255 && solvers [cloth->old_solver_type].free ) + { + solvers [cloth->old_solver_type].free ( clmd ); + } + + // Free the verts. + if ( cloth->verts != NULL ) + MEM_freeN ( cloth->verts ); + + cloth->verts = NULL; + cloth->numverts = 0; + + // Free the springs. + if ( cloth->springs != NULL ) + { + LinkNode *search = cloth->springs; + while(search) + { + ClothSpring *spring = search->link; + + MEM_freeN ( spring ); + search = search->next; + } + BLI_linklist_free(cloth->springs, NULL); + + cloth->springs = NULL; + } + + cloth->springs = NULL; + cloth->numsprings = 0; + + // free BVH collision tree + if ( cloth->tree ) + bvh_free ( ( BVH * ) cloth->tree ); + + // we save our faces for collision objects + if ( cloth->mfaces ) + MEM_freeN ( cloth->mfaces ); + /* + if(clmd->clothObject->facemarks) + MEM_freeN(clmd->clothObject->facemarks); + */ + MEM_freeN ( cloth ); + clmd->clothObject = NULL; + } + } + clmd->sim_parms->flags &= ~CLOTH_SIMSETTINGS_FLAG_RESET; +} /****************************************************************************** * @@ -933,72 +936,6 @@ static void cloth_apply_vgroup ( ClothModifierData *clmd, DerivedMesh *dm, short } } -// only meshes supported at the moment -/* collision objects */ -static int collobj_from_object ( Object *ob, ClothModifierData *clmd, DerivedMesh *dm, float ( *vertexCos ) [3], unsigned int numverts ) -{ - unsigned int i; - MVert *mvert = NULL; - ClothVertex *verts = NULL; - float tnull[3] = {0,0,0}; - - /* If we have a clothObject, free it. */ - if ( clmd->clothObject != NULL ) - cloth_free_modifier ( clmd ); - - /* Allocate a new cloth object. */ - clmd->clothObject = MEM_callocN ( sizeof ( Cloth ), "cloth" ); - if ( clmd->clothObject ) - { - clmd->clothObject->old_solver_type = 255; - // clmd->clothObject->old_collision_type = 255; - } - else if ( clmd->clothObject == NULL ) - { - modifier_setError ( & ( clmd->modifier ), "Out of memory on allocating clmd->clothObject." ); - return 0; - } - - switch ( ob->type ) - { - case OB_MESH: - - // mesh input objects need DerivedMesh - if ( !dm ) - return 0; - - cloth_from_mesh ( ob, clmd, dm ); - - if ( clmd->clothObject != NULL ) - { - if ( !dm ) return 0; - if ( !dm->getNumVerts ( dm ) || !dm->getNumFaces ( dm ) ) return 0; - - mvert = dm->getVertArray ( dm ); - verts = clmd->clothObject->verts; - numverts = clmd->clothObject->numverts = dm->getNumVerts ( dm ); - - for ( i = 0; i < numverts; i++, verts++ ) - { - VECCOPY ( verts->x, mvert[i].co ); - Mat4MulVecfl ( ob->obmat, verts->x ); - verts->flags = 0; - VECCOPY ( verts->xold, verts->x ); - VECCOPY ( verts->txold, verts->x ); - VECCOPY ( verts->tx, verts->x ); - VecMulf ( verts->v, 0.0f ); - verts->impulse_count = 0; - VECCOPY ( verts->impulse, tnull ); - } - clmd->clothObject->tree = bvh_build_from_cloth ( clmd,clmd->coll_parms->epsilon ); - - } - - return 1; - default: return 0; // TODO - we do not support changing meshes - } -} - /* helper function to get proper spring length when object is rescaled @@ -1024,7 +961,7 @@ static int cloth_from_object ( Object *ob, ClothModifierData *clmd, DerivedMesh /* If we have a clothObject, free it. */ if ( clmd->clothObject != NULL ) - cloth_free_modifier ( clmd ); + cloth_free_modifier ( ob, clmd ); /* Allocate a new cloth object. */ clmd->clothObject = MEM_callocN ( sizeof ( Cloth ), "cloth" ); @@ -1038,8 +975,6 @@ static int cloth_from_object ( Object *ob, ClothModifierData *clmd, DerivedMesh modifier_setError ( & ( clmd->modifier ), "Out of memory on allocating clmd->clothObject." ); return 0; } - - clmd->sim_parms->ob = ob; switch ( ob->type ) { @@ -1085,6 +1020,7 @@ static int cloth_from_object ( Object *ob, ClothModifierData *clmd, DerivedMesh if ( !cloth_build_springs ( clmd->clothObject, dm ) ) { + cloth_free_modifier ( ob, clmd ); modifier_setError ( & ( clmd->modifier ), "Can't build springs." ); return 0; } @@ -1130,7 +1066,7 @@ static void cloth_from_mesh ( Object *ob, ClothModifierData *clmd, DerivedMesh * clmd->clothObject->verts = MEM_callocN ( sizeof ( ClothVertex ) * clmd->clothObject->numverts, "clothVertex" ); if ( clmd->clothObject->verts == NULL ) { - cloth_free_modifier ( clmd ); + cloth_free_modifier ( ob, clmd ); modifier_setError ( & ( clmd->modifier ), "Out of memory on allocating clmd->clothObject->verts." ); return; } @@ -1140,7 +1076,7 @@ static void cloth_from_mesh ( Object *ob, ClothModifierData *clmd, DerivedMesh * clmd->clothObject->mfaces = MEM_callocN ( sizeof ( MFace ) * clmd->clothObject->numfaces, "clothMFaces" ); if ( clmd->clothObject->mfaces == NULL ) { - cloth_free_modifier ( clmd ); + cloth_free_modifier ( ob, clmd ); modifier_setError ( & ( clmd->modifier ), "Out of memory on allocating clmd->clothObject->mfaces." ); return; } @@ -1191,7 +1127,7 @@ int cloth_build_springs ( Cloth *cloth, DerivedMesh *dm ) { ClothSpring *spring = NULL, *tspring = NULL, *tspring2 = NULL; unsigned int struct_springs = 0, shear_springs=0, bend_springs = 0; - unsigned int i = 0, j = 0, akku_count; + unsigned int i = 0; unsigned int numverts = dm->getNumVerts ( dm ); unsigned int numedges = dm->getNumEdges ( dm ); unsigned int numfaces = dm->getNumFaces ( dm ); @@ -1201,7 +1137,7 @@ int cloth_build_springs ( Cloth *cloth, DerivedMesh *dm ) LinkNode **edgelist = NULL; EdgeHash *edgehash = NULL; LinkNode *search = NULL, *search2 = NULL; - float temp[3], akku, min, max; + float temp[3]; LinkNode *node = NULL, *node2 = NULL; // error handling diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c index 9273b6bf9ab..40b01fa3322 100644 --- a/source/blender/blenkernel/intern/modifier.c +++ b/source/blender/blenkernel/intern/modifier.c @@ -4991,6 +4991,7 @@ static void clothModifier_updateDepgraph( Base *base; + /* TODO: this belongs to collision modifier */ if(clmd) { for(base = G.scene->base.first; base; base= base->next) @@ -5034,11 +5035,13 @@ static int clothModifier_dependsOnTime(ModifierData *md) static void clothModifier_freeData(ModifierData *md) { ClothModifierData *clmd = (ClothModifierData*) md; + Object *ob = NULL; + ClothModifierData *clmd2 = NULL; if (clmd) { - clmd->sim_parms->flags &= ~CLOTH_SIMSETTINGS_FLAG_CCACHE_PROTECT; - cloth_free_modifier (clmd); + + cloth_free_modifier_extern (clmd); MEM_freeN(clmd->sim_parms); MEM_freeN(clmd->coll_parms); @@ -7290,11 +7293,11 @@ int modifiers_isSoftbodyEnabled(Object *ob) return (md && md->mode & (eModifierMode_Realtime | eModifierMode_Render)); } -ClothModifierData * modifiers_isClothEnabled(Object *ob) +int modifiers_isClothEnabled(Object *ob) { ModifierData *md = modifiers_findByType(ob, eModifierType_Cloth); - return (ClothModifierData *)md; + return (md && md->mode & (eModifierMode_Realtime | eModifierMode_Render)); } int modifiers_isParticleEnabled(Object *ob) diff --git a/source/blender/include/butspace.h b/source/blender/include/butspace.h index c925a0689ef..a7759f799ba 100644 --- a/source/blender/include/butspace.h +++ b/source/blender/include/butspace.h @@ -295,8 +295,7 @@ void curvemap_buttons(struct uiBlock *block, struct CurveMapping *cumap, char la #define B_CLOTH_CLEARCACHEALL 1480 #define B_CLOTH_CLEARCACHEFRAME 1481 #define B_CLOTH_CHANGEPREROLL 1482 -#define B_CLOTH_DEL_VG 1483 -#define B_CLOTH_RENEW 1484 +#define B_CLOTH_RENEW 1483 /* *********************** */ #define B_WORLDBUTS 1600 diff --git a/source/blender/makesdna/DNA_cloth_types.h b/source/blender/makesdna/DNA_cloth_types.h index ee4a0130dbf..65b8f4169ff 100644 --- a/source/blender/makesdna/DNA_cloth_types.h +++ b/source/blender/makesdna/DNA_cloth_types.h @@ -76,7 +76,6 @@ typedef struct SimulationSettings int maxspringlen; /* in percent!; if tearing enabled, a spring will get cut */ int lastframe; /* frame on which simulation stops */ int firstframe; /* frame on which simulation starts */ - struct Object *ob; } SimulationSettings; diff --git a/source/blender/src/buttons_object.c b/source/blender/src/buttons_object.c index 7f62c5b3308..4ac49a93119 100644 --- a/source/blender/src/buttons_object.c +++ b/source/blender/src/buttons_object.c @@ -2287,6 +2287,56 @@ void do_object_panels(unsigned short event) if(ob->ipo) ob->ipo->showkey= (ob->ipoflag & OB_DRAWKEY)?1:0; allqueue(REDRAWVIEW3D, 0); break; + case B_CLOTH_CLEARCACHEALL: + { + ClothModifierData *clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth); + if(clmd) + { + CFRA= 1; + update_for_newframe_muted(); + DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA); + cloth_clear_cache(ob, clmd, 2); + allqueue(REDRAWBUTSOBJECT, 0); + allqueue(REDRAWVIEW3D, 0); + } + } + break; + case B_CLOTH_CLEARCACHEFRAME: + { + ClothModifierData *clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth); + if(clmd) + { + cloth_clear_cache(ob, clmd, MAX2(2.0,G.scene->r.cfra + 1.0)); + allqueue(REDRAWBUTSOBJECT, 0); + } + } + break; + case B_CLOTH_CHANGEPREROLL: + { + ClothModifierData *clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth); + if(clmd) + { + if(clmd->sim_parms->cache) + { + CFRA= 1; + update_for_newframe_muted(); + DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA); + allqueue(REDRAWBUTSOBJECT, 0); + allqueue(REDRAWVIEW3D, 0); + } + } + } + break; + case B_CLOTH_RENEW: + { + ClothModifierData *clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth); + + if(clmd) + { + clmd->sim_parms->flags |= CLOTH_SIMSETTINGS_FLAG_RESET; + } + } + break; default: if(event>=B_SELEFFECT && eventr.cfra + 1.0)); - allqueue(REDRAWBUTSOBJECT, 0); - } - } - break; - case B_CLOTH_CHANGEPREROLL: - { - ClothModifierData *clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth); - if(clmd) - { - if(clmd->sim_parms->cache) - { - CFRA= 1; - update_for_newframe_muted(); - DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA); - allqueue(REDRAWBUTSOBJECT, 0); - allqueue(REDRAWVIEW3D, 0); - } - } - } - break; - case B_CLOTH_DEL_VG: - { - ClothModifierData *clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth); - if(clmd) - { - clmd->sim_parms->vgroup_mass = 0; - do_object_panels(B_CLOTH_RENEW); - } - allqueue(REDRAWBUTSOBJECT, 0); - } - break; - case B_CLOTH_RENEW: - { - ClothModifierData *clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth); - if(clmd) - { - do_object_panels(B_CLOTH_CLEARCACHEALL); - cloth_free_modifier (clmd); - } - } - break; default: if(event>=B_SELEFFECT && eventsim_parms->vgroup_mass = 0; } else + { if(!clmd->sim_parms->vgroup_mass) clmd->sim_parms->vgroup_mass = 1; + else if(clmd->sim_parms->vgroup_mass > defCount) + clmd->sim_parms->vgroup_mass = defCount; + } sprintf (clvg2, "%s%s", clmvg, clvg1); diff --git a/source/blender/src/editmesh.c b/source/blender/src/editmesh.c index dc16caa1f59..8bd397b0da4 100644 --- a/source/blender/src/editmesh.c +++ b/source/blender/src/editmesh.c @@ -1329,7 +1329,8 @@ void load_editMesh(void) for(base= G.scene->base.first; base; base= base->next) { if(base->object->data==me) { if(modifiers_isClothEnabled(base->object)) { - cloth_free_modifier(modifiers_isClothEnabled(base->object)); + ClothModifierData *clmd = (ClothModifierData *)modifiers_findByType(base->object, eModifierType_Cloth); + clmd->sim_parms->flags |= CLOTH_SIMSETTINGS_FLAG_RESET; } base->object->softflag |= OB_SB_REDO; diff --git a/source/blender/src/editobject.c b/source/blender/src/editobject.c index 7b3a1a24188..cb1ed4c3e5a 100644 --- a/source/blender/src/editobject.c +++ b/source/blender/src/editobject.c @@ -1761,7 +1761,8 @@ void exit_editmode(int flag) /* freedata==0 at render, 1= freedata, 2= do undo b } if(modifiers_isClothEnabled(ob)) { - cloth_free_modifier(modifiers_isClothEnabled(ob)); + ClothModifierData *clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth); + clmd->sim_parms->flags |= CLOTH_SIMSETTINGS_FLAG_RESET; } if(ob->type==OB_MESH && get_mesh(ob)->mr) diff --git a/source/blender/src/transform_conversions.c b/source/blender/src/transform_conversions.c index 9160bf2f563..882a16bb9ce 100644 --- a/source/blender/src/transform_conversions.c +++ b/source/blender/src/transform_conversions.c @@ -3405,7 +3405,8 @@ void special_aftertrans_update(TransInfo *t) if (modifiers_isSoftbodyEnabled(ob)) ob->softflag |= OB_SB_REDO; else if(modifiers_isClothEnabled(ob)) { - cloth_free_modifier(modifiers_isClothEnabled(ob)); + ClothModifierData *clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth); + clmd->sim_parms->flags |= CLOTH_SIMSETTINGS_FLAG_RESET; } /* Set autokey if necessary */ diff --git a/source/blender/src/transform_generics.c b/source/blender/src/transform_generics.c index a79b1d4c4ea..1f6d8ecf7af 100644 --- a/source/blender/src/transform_generics.c +++ b/source/blender/src/transform_generics.c @@ -468,14 +468,13 @@ void recalcData(TransInfo *t) /* bah, softbody exception... recalcdata doesnt reset */ for(base= FIRSTBASE; base; base= base->next) { if(base->object->recalc & OB_RECALC_DATA) - { - ClothModifierData *clmd = NULL; - + { if(modifiers_isSoftbodyEnabled(base->object)) { base->object->softflag |= OB_SB_REDO; } - else if((clmd = (ClothModifierData *)modifiers_isClothEnabled(ob))) { - cloth_free_modifier(clmd); + else if(modifiers_isClothEnabled(base->object)) { + ClothModifierData *clmd = (ClothModifierData *) modifiers_findByType(base->object, eModifierType_Cloth); + clmd->sim_parms->flags |= CLOTH_SIMSETTINGS_FLAG_RESET; } } @@ -516,13 +515,12 @@ void recalcData(TransInfo *t) /* softbody & cloth exception */ if(ob->recalc & OB_RECALC_DATA) { - ClothModifierData *clmd = NULL; - if(modifiers_isSoftbodyEnabled(ob)) { ob->softflag |= OB_SB_REDO; } - else if((clmd = (ClothModifierData *)modifiers_isClothEnabled(ob))) { - cloth_free_modifier(clmd); + else if(modifiers_isClothEnabled(ob)) { + ClothModifierData *clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth); + clmd->sim_parms->flags |= CLOTH_SIMSETTINGS_FLAG_RESET; } } diff --git a/source/blender/src/vpaint.c b/source/blender/src/vpaint.c index 2e4ecd95709..dec15f96b8a 100644 --- a/source/blender/src/vpaint.c +++ b/source/blender/src/vpaint.c @@ -1351,7 +1351,8 @@ void weight_paint(void) // same goes for cloth if(modifiers_isClothEnabled(ob)) { - cloth_free_modifier((ClothModifierData *)modifiers_isClothEnabled(ob)); + ClothModifierData *clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth); + clmd->sim_parms->flags |= CLOTH_SIMSETTINGS_FLAG_RESET; } BIF_undo_push("Weight Paint"); From 6490b2b29add882065637ea8701946940bc02d2d Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Wed, 23 Jan 2008 13:24:44 +0000 Subject: [PATCH 076/246] Made GUI even more intuitive with explanations why something is not available etc., fixed some uninitialized variable. NEW: show pinned verts as big red balls in 3dview - please tell me how to improve that visual feedback :) --- source/blender/blenkernel/BKE_cloth.h | 5 ++- source/blender/blenkernel/intern/cloth.c | 45 ++++++++++++-------- source/blender/makesdna/DNA_cloth_types.h | 2 +- source/blender/src/buttons_object.c | 46 ++++++++++++-------- source/blender/src/drawobject.c | 51 +++++++++++++++++++++++ 5 files changed, 110 insertions(+), 39 deletions(-) diff --git a/source/blender/blenkernel/BKE_cloth.h b/source/blender/blenkernel/BKE_cloth.h index 11de3092e7c..4e704098ebd 100644 --- a/source/blender/blenkernel/BKE_cloth.h +++ b/source/blender/blenkernel/BKE_cloth.h @@ -80,6 +80,7 @@ typedef struct ClothVertex float goal; /* goal, from SB */ float impulse[3]; /* used in collision.c */ unsigned int impulse_count; /* same as above */ + float avg_spring_len; /* average length of connected springs, UNUSED ATM */ } ClothVertex; @@ -156,8 +157,8 @@ typedef enum } CLOTH_SPRINGS_FLAGS; /* Bits to or into the ClothVertex.flags. */ -#define CVERT_FLAG_PINNED 1 -#define CVERT_FLAG_COLLISION 2 +#define CLOTH_VERT_FLAG_PINNED 1 +#define CLOTH_VERT_FLAG_COLLISION 2 // needed for buttons_object.c diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c index 2b5937985ae..fb3617e16f0 100644 --- a/source/blender/blenkernel/intern/cloth.c +++ b/source/blender/blenkernel/intern/cloth.c @@ -124,7 +124,7 @@ static CM_SOLVER_DEF solvers [] = static void cloth_to_object ( Object *ob, ClothModifierData *clmd, float ( *vertexCos ) [3], unsigned int numverts ); static void cloth_from_mesh ( Object *ob, ClothModifierData *clmd, DerivedMesh *dm ); static int cloth_from_object ( Object *ob, ClothModifierData *clmd, DerivedMesh *dm, float ( *vertexCos ) [3], unsigned int numverts, float framenr ); -int cloth_build_springs ( Cloth *cloth, DerivedMesh *dm ); +int cloth_build_springs ( ClothModifierData *clmd, DerivedMesh *dm ); static void cloth_apply_vgroup ( ClothModifierData *clmd, DerivedMesh *dm, short vgroup ); @@ -502,12 +502,17 @@ static void cloth_write_cache(Object *ob, ClothModifierData *clmd, float framenr Cloth *cloth = clmd->clothObject; if(!cloth) + { return; + } stack_index = modifiers_indexInObject(ob, (ModifierData *)clmd); fp = BKE_ptcache_id_fopen((ID *)ob, 'w', framenr, stack_index); - if(!fp) return; + if(!fp) + { + return; + } for(a = 0; a < cloth->numverts; a++) { @@ -554,10 +559,10 @@ static int cloth_read_cache(Object *ob, ClothModifierData *clmd, float framenr) } fclose(fp); + + if(clmd->sim_parms->solver_type == 0) + implicit_set_positions(clmd); } - - if(clmd->sim_parms->solver_type == 0) - implicit_set_positions(clmd); return ret; } @@ -622,6 +627,8 @@ void clothModifier_do ( ClothModifierData *clmd, Object *ob, DerivedMesh *dm, } } */ + + // printf("ct: %f, st: %f, r.cfra: %f, dt: %f\n", current_time, clmd->sim_parms->sim_time, ( float ) G.scene->r.cfra, deltaTime); // unused in the moment, calculated seperately in implicit.c clmd->sim_parms->dt = 1.0f / clmd->sim_parms->stepsPerFrame; @@ -681,11 +688,7 @@ void clothModifier_do ( ClothModifierData *clmd, Object *ob, DerivedMesh *dm, cloth_write_cache(ob, clmd, framenr); } - else // just retrieve the cached frame - { - cloth_read_cache(ob, clmd, framenr); - } - + // Copy the result back to the object. cloth_to_object ( ob, clmd, vertexCos, numverts ); @@ -694,12 +697,14 @@ void clothModifier_do ( ClothModifierData *clmd, Object *ob, DerivedMesh *dm, } } - else if ( ( deltaTime <= 0.0f ) || ( deltaTime > 1.0f ) ) + else { if ( clmd->clothObject != NULL ) { if(cloth_read_cache(ob, clmd, framenr)) + { cloth_to_object ( ob, clmd, vertexCos, numverts ); + } } else { @@ -866,7 +871,7 @@ static void cloth_to_object ( Object *ob, ClothModifierData *clmd, float ( *vert for ( i = 0; i < numverts; i++, verts++ ) { VECCOPY ( vertexCos[i], verts->x ); - Mat4MulVecfl ( ob->imat, vertexCos[i] ); /* softbody is in global coords */ + Mat4MulVecfl ( ob->imat, vertexCos[i] ); /* cloth is in global coords */ } } } @@ -921,9 +926,9 @@ static void cloth_apply_vgroup ( ClothModifierData *clmd, DerivedMesh *dm, short verts->goal = ( float ) pow ( verts->goal , 4.0f ); - if ( dvert->dw [j].weight >=SOFTGOALSNAP ) + if ( verts->goal >=SOFTGOALSNAP ) { - verts->flags |= CVERT_FLAG_PINNED; + verts->flags |= CLOTH_VERT_FLAG_PINNED; } // TODO enable mass painting here, for the moment i let "goals" go first @@ -1018,7 +1023,7 @@ static int cloth_from_object ( Object *ob, ClothModifierData *clmd, DerivedMesh VECCOPY ( verts->impulse, tnull ); } - if ( !cloth_build_springs ( clmd->clothObject, dm ) ) + if ( !cloth_build_springs ( clmd, dm ) ) { cloth_free_modifier ( ob, clmd ); modifier_setError ( & ( clmd->modifier ), "Can't build springs." ); @@ -1042,11 +1047,11 @@ static int cloth_from_object ( Object *ob, ClothModifierData *clmd, DerivedMesh case OB_LATTICE: printf ( "Not supported: OB_LATTICE\n" ); // lattice_to_softbody(ob); - return 1; + return 0; case OB_CURVE: case OB_SURF: printf ( "Not supported: OB_SURF| OB_CURVE\n" ); - return 1; + return 0; default: return 0; // TODO - we do not support changing meshes } @@ -1123,8 +1128,9 @@ int cloth_add_spring ( ClothModifierData *clmd, unsigned int indexA, unsigned in return 0; } -int cloth_build_springs ( Cloth *cloth, DerivedMesh *dm ) +int cloth_build_springs ( ClothModifierData *clmd, DerivedMesh *dm ) { + Cloth *cloth = clmd->clothObject; ClothSpring *spring = NULL, *tspring = NULL, *tspring2 = NULL; unsigned int struct_springs = 0, shear_springs=0, bend_springs = 0; unsigned int i = 0; @@ -1169,6 +1175,7 @@ int cloth_build_springs ( Cloth *cloth, DerivedMesh *dm ) spring->kl = medge[i].v2; VECSUB ( temp, cloth->verts[spring->kl].x, cloth->verts[spring->ij].x ); spring->restlen = sqrt ( INPR ( temp, temp ) ); + clmd->coll_parms->avg_spring_len += spring->restlen; spring->type = CLOTH_SPRING_TYPE_STRUCTURAL; spring->flags = 0; struct_springs++; @@ -1181,6 +1188,8 @@ int cloth_build_springs ( Cloth *cloth, DerivedMesh *dm ) } } + clmd->coll_parms->avg_spring_len /= struct_springs; + // shear springs for ( i = 0; i < numfaces; i++ ) { diff --git a/source/blender/makesdna/DNA_cloth_types.h b/source/blender/makesdna/DNA_cloth_types.h index 65b8f4169ff..9c5e3a1b9f2 100644 --- a/source/blender/makesdna/DNA_cloth_types.h +++ b/source/blender/makesdna/DNA_cloth_types.h @@ -89,7 +89,7 @@ typedef struct CollisionSettings short loop_count; /* How many iterations for the collision loop. */ struct LinkNode *collision_list; /* e.g. pointer to temp memory for collisions */ int flags; /* collision flags defined in BKE_cloth.h */ - int pad; + float avg_spring_len; /* for selfcollision */ } CollisionSettings; diff --git a/source/blender/src/buttons_object.c b/source/blender/src/buttons_object.c index 4ac49a93119..8e691c30f94 100644 --- a/source/blender/src/buttons_object.c +++ b/source/blender/src/buttons_object.c @@ -4937,6 +4937,8 @@ static void object_panel_cloth(Object *ob) block= uiNewBlock(&curarea->uiblocks, "object_cloth", UI_EMBOSS, UI_HELV, curarea->win); if(uiNewPanel(curarea, block, "Cloth ", "Physics", 640, 0, 318, 204)==0) return; uiSetButLock(object_data_is_libdata(ob), ERROR_LIBDATA_MESSAGE); + + val = (clmd ? 1:0); but = uiDefButI(block, TOG, REDRAWBUTSOBJECT, "Cloth", 10,200,130,20, &val, 0, 0, 0, 0, "Sets object to become cloth"); @@ -4977,12 +4979,10 @@ static void object_panel_cloth(Object *ob) /* GOAL STUFF */ uiBlockBeginAlign(block); - if(BLI_countlist (&ob->defbase) > 0) - { - uiDefButBitI(block, TOG, CLOTH_SIMSETTINGS_FLAG_GOAL, REDRAWVIEW3D, "Pinning of cloth", 10,70,150,20, &clmd->sim_parms->flags, 0, 0, 0, 0, "Define forces for vertices to stick to animated position"); - } - if (clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL) + uiDefButBitI(block, TOG, CLOTH_SIMSETTINGS_FLAG_GOAL, REDRAWVIEW3D, "Pinning of cloth", 10,70,150,20, &clmd->sim_parms->flags, 0, 0, 0, 0, "Define forces for vertices to stick to animated position"); + + if ((clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL) && (BLI_countlist (&ob->defbase) > 0)) { if(ob->type==OB_MESH) { @@ -5013,13 +5013,9 @@ static void object_panel_cloth(Object *ob) MEM_freeN (clvg1); MEM_freeN (clvg2); } - else - { - uiDefButS(block, TOG, B_CLOTH_RENEW, "W", 140,70,20,20, &clmd->sim_parms->vgroup_mass, 0, 1, 0, 0, "Use control point weight values"); - uiDefButF(block, NUM, B_CLOTH_RENEW, "Goal:", 160,70,150,20, &clmd->sim_parms->defgoal, 0.0, 1.0, 10, 0, "Default Goal (vertex target position) value, when no Vertex Group used"); - } uiDefButF(block, NUM, B_CLOTH_RENEW, "Pin Stiff:", 10,50,150,20, &clmd->sim_parms->goalspring, 0.0, 500.0, 10, 0, "Pin (vertex target position) spring stiffness"); + uiDefBut(block, LABEL, 0, " ", 160,50,150,20, NULL, 0.0, 0, 0, 0, ""); /* // nobody is changing these ones anyway uiDefButF(block, NUM, B_CLOTH_RENEW, "G Damp:", 160,50,150,20, &clmd->sim_parms->goalfrict , 0.0, 50.0, 10, 0, "Goal (vertex target position) friction"); @@ -5027,6 +5023,12 @@ static void object_panel_cloth(Object *ob) uiDefButF(block, NUM, B_CLOTH_RENEW, "G Max:", 160,30,150,20, &clmd->sim_parms->maxgoal, 0.0, 1.0, 10, 0, "Goal maximum, vertex group weights are scaled to match this range"); */ } + else if (clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL) + { + uiDefBut(block, LABEL, 0, " ", 160,70,150,20, NULL, 0.0, 0, 0, 0, ""); + uiDefBut(block, LABEL, 0, "No vertex group for pinning available.", 10,50,300,20, NULL, 0.0, 0, 0, 0, ""); + } + uiBlockEndAlign(block); /* @@ -5078,18 +5080,26 @@ static void object_panel_cloth_II(Object *ob) sprintf (str, "Frame %d cached. [%d in preroll, %d in total]", length-clmd->sim_parms->preroll, clmd->sim_parms->preroll, length); */ - uiDefButBitI(block, TOG, CLOTH_SIMSETTINGS_FLAG_CCACHE_PROTECT, REDRAWVIEW3D, "Protect Cache", 10,120,300,20, &clmd->sim_parms->flags, 0, 0, 0, 0, "Protect cache from automatic freeing when scene changed"); - - if(!(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_CCACHE_PROTECT)) + if (!G.relbase_valid) { - uiDefBut(block, LABEL, 0, "Clear cache:", 10,100,90,20, NULL, 0.0, 0, 0, 0, ""); - uiDefBut(block, BUT, B_CLOTH_CLEARCACHEALL, "All", 100, 100,100,20, NULL, 0.0, 0.0, 0, 0, "Free ALL cloth cache without preroll"); - uiDefBut(block, BUT, B_CLOTH_CLEARCACHEFRAME, "From next frame", 200, 100,110,20, NULL, 0.0, 0.0, 0, 0, "Free cloth cache starting from next frame"); - uiDefBut(block, LABEL, 0, " ", 10,80,300,20, NULL, 0.0, 0, 0, 0, ""); + uiDefBut(block, LABEL, 0, "Cache deactivated until file is saved.", 10,120,300,20, NULL, 0.0, 0, 0, 0, ""); + uiDefBut(block, LABEL, 0, " ", 10,100,300,40, NULL, 0.0, 0, 0, 0, ""); } else { - uiDefBut(block, LABEL, 0, " ", 10,100,300,40, NULL, 0.0, 0, 0, 0, ""); + uiDefButBitI(block, TOG, CLOTH_SIMSETTINGS_FLAG_CCACHE_PROTECT, REDRAWVIEW3D, "Protect Cache", 10,120,300,20, &clmd->sim_parms->flags, 0, 0, 0, 0, "Protect cache from automatic freeing when scene changed"); + + if(!(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_CCACHE_PROTECT)) + { + uiDefBut(block, LABEL, 0, "Clear cache:", 10,100,90,20, NULL, 0.0, 0, 0, 0, ""); + uiDefBut(block, BUT, B_CLOTH_CLEARCACHEALL, "All", 100, 100,100,20, NULL, 0.0, 0.0, 10, 0, "Free ALL cloth cache without preroll"); + uiDefBut(block, BUT, B_CLOTH_CLEARCACHEFRAME, "From next frame", 200, 100,110,20, NULL, 0.0, 0.0, 10, 0, "Free cloth cache starting from next frame"); + uiDefBut(block, LABEL, 0, " ", 10,80,300,20, NULL, 0.0, 0, 0, 0, ""); + } + else + { + uiDefBut(block, LABEL, 0, " ", 10,100,300,40, NULL, 0.0, 0, 0, 0, ""); + } } /* diff --git a/source/blender/src/drawobject.c b/source/blender/src/drawobject.c index c8d2e3dad90..0069ac0f15e 100644 --- a/source/blender/src/drawobject.c +++ b/source/blender/src/drawobject.c @@ -5399,6 +5399,57 @@ void draw_object(Base *base, int flag) if(col) cpack(col); glDepthMask(GL_TRUE); } + + /* code for drawing pinned cloth verts */ + if(modifiers_isClothEnabled(ob)) + { + ClothModifierData *clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth); + Cloth *cloth = clmd->clothObject; + ClothVertex *verts; + float col[3], point[3]; + col[0] = 0.53; + col[1] = 0.04; + col[2] = 0.0; + glColor3fv(col); + + /* inverse matrix is not uptodate... */ + Mat4Invert ( ob->imat, ob->obmat ); + + if(cloth) + { + verts = cloth->verts; + + for(i = 0; i < cloth->numverts; i++) + { + if(verts[i].flags & CLOTH_VERT_FLAG_PINNED) + { + float size[3], cent[3]; + GLUquadricObj *qobj = gluNewQuadric(); + + gluQuadricDrawStyle(qobj, GLU_FILL); + + size[0]= clmd->coll_parms->avg_spring_len / 3.0; + size[1]= clmd->coll_parms->avg_spring_len / 3.0; + size[2]= clmd->coll_parms->avg_spring_len / 3.0; + + VECCOPY ( point, verts[i].x ); + Mat4MulVecfl ( ob->imat, point ); + + cent[0]= point[0]; + cent[1]= point[1]; + cent[2]= point[2]; + + glPushMatrix(); + glTranslatef(cent[0], cent[1], cent[2]); + glScalef(size[0], size[1], size[2]); + gluSphere(qobj, 1.0, 8, 5); + glPopMatrix(); + + gluDeleteQuadric(qobj); + } + } + } + } { bConstraint *con; From 4b1b749130258edd5a1bf0489d07e6e4138f3a9c Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Wed, 23 Jan 2008 15:30:23 +0000 Subject: [PATCH 077/246] Enabled first + last simulation frame, hopefully fixed some cache problems, changed 3d view ball to a pushpin layout -feel free to enhance in drawobject.c line 5440 --- source/blender/blenkernel/intern/cloth.c | 147 ++++++++++------------ source/blender/makesdna/DNA_cloth_types.h | 2 + source/blender/src/buttons_object.c | 4 +- source/blender/src/drawobject.c | 75 ++++++----- 4 files changed, 117 insertions(+), 111 deletions(-) diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c index fb3617e16f0..4a0252b7fd7 100644 --- a/source/blender/blenkernel/intern/cloth.c +++ b/source/blender/blenkernel/intern/cloth.c @@ -160,6 +160,8 @@ void cloth_init ( ClothModifierData *clmd ) clmd->sim_parms->firstframe = 1; clmd->sim_parms->lastframe = 250; clmd->sim_parms->vgroup_mass = 0; + clmd->sim_parms->lastcachedframe = 0; + clmd->coll_parms->self_friction = 5.0; clmd->coll_parms->friction = 10.0; clmd->coll_parms->loop_count = 1; @@ -483,46 +485,6 @@ DerivedMesh *CDDM_create_tearing ( ClothModifierData *clmd, DerivedMesh *dm ) int modifiers_indexInObject(Object *ob, ModifierData *md_seek); -void cloth_clear_cache(Object *ob, ClothModifierData *clmd, float framenr) -{ - int stack_index = -1; - - if(!(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_CCACHE_PROTECT)) - { - stack_index = modifiers_indexInObject(ob, (ModifierData *)clmd); - - BKE_ptcache_id_clear((ID *)ob, PTCACHE_CLEAR_AFTER, framenr, stack_index); - } -} -static void cloth_write_cache(Object *ob, ClothModifierData *clmd, float framenr) -{ - FILE *fp = NULL; - int stack_index = -1; - unsigned int a; - Cloth *cloth = clmd->clothObject; - - if(!cloth) - { - return; - } - - stack_index = modifiers_indexInObject(ob, (ModifierData *)clmd); - - fp = BKE_ptcache_id_fopen((ID *)ob, 'w', framenr, stack_index); - if(!fp) - { - return; - } - - for(a = 0; a < cloth->numverts; a++) - { - fwrite(&cloth->verts[a].x, sizeof(float),3,fp); - fwrite(&cloth->verts[a].xconst, sizeof(float),3,fp); - fwrite(&cloth->verts[a].v, sizeof(float),3,fp); - } - - fclose(fp); -} static int cloth_read_cache(Object *ob, ClothModifierData *clmd, float framenr) { FILE *fp = NULL; @@ -567,6 +529,55 @@ static int cloth_read_cache(Object *ob, ClothModifierData *clmd, float framenr) return ret; } +void cloth_clear_cache(Object *ob, ClothModifierData *clmd, float framenr) +{ + int stack_index = -1; + + if(!(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_CCACHE_PROTECT)) + { + stack_index = modifiers_indexInObject(ob, (ModifierData *)clmd); + + BKE_ptcache_id_clear((ID *)ob, PTCACHE_CLEAR_AFTER, framenr, stack_index); + } + + if(framenr>0) + { + cloth_read_cache(ob, clmd, framenr); + } +} +static void cloth_write_cache(Object *ob, ClothModifierData *clmd, float framenr) +{ + FILE *fp = NULL; + int stack_index = -1; + unsigned int a; + Cloth *cloth = clmd->clothObject; + + if(!cloth) + { + return; + } + + stack_index = modifiers_indexInObject(ob, (ModifierData *)clmd); + + fp = BKE_ptcache_id_fopen((ID *)ob, 'w', framenr, stack_index); + if(!fp) + { + return; + } + + for(a = 0; a < cloth->numverts; a++) + { + fwrite(&cloth->verts[a].x, sizeof(float),3,fp); + fwrite(&cloth->verts[a].xconst, sizeof(float),3,fp); + fwrite(&cloth->verts[a].v, sizeof(float),3,fp); + } + + clmd->sim_parms->lastcachedframe = MAX2(clmd->sim_parms->lastcachedframe, framenr); + + fclose(fp); +} + + /** * cloth_deform_verts - simulates one step, framenr is in frames. @@ -585,48 +596,24 @@ void clothModifier_do ( ClothModifierData *clmd, Object *ob, DerivedMesh *dm, // only be active during a specific period: // that's "first frame" and "last frame" on GUI - /* - if ( ! ( clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_COLLOBJ ) ) + if ( current_time < clmd->sim_parms->firstframe ) { - if ( clmd->clothObject ) - { - if ( clmd->sim_parms->cache ) - { - if ( current_time < clmd->sim_parms->firstframe ) - { - int frametime = cloth_cache_first_frame ( clmd ); - if ( cloth_cache_search_frame ( clmd, frametime ) ) - { - cloth_cache_get_frame ( clmd, frametime ); - cloth_to_object ( ob, clmd, vertexCos, numverts ); - } - return; - } - else if ( current_time > clmd->sim_parms->lastframe ) - { - int frametime = cloth_cache_last_frame ( clmd ); - if ( cloth_cache_search_frame ( clmd, frametime ) ) - { - cloth_cache_get_frame ( clmd, frametime ); - cloth_to_object ( ob, clmd, vertexCos, numverts ); - } - return; - } - else if ( ABS ( deltaTime ) >= 2.0f ) // no timewarps allowed - { - if ( cloth_cache_search_frame ( clmd, framenr ) ) - { - cloth_cache_get_frame ( clmd, framenr ); - cloth_to_object ( ob, clmd, vertexCos, numverts ); - } - clmd->sim_parms->sim_time = current_time; - return; - } - } - - } + return; + } + else if ( current_time > clmd->sim_parms->lastframe ) + { + int stack_index = modifiers_indexInObject(ob, (ModifierData *)clmd); + + if(BKE_ptcache_id_exist((ID *)ob, clmd->sim_parms->lastcachedframe, stack_index)) + { + if(cloth_read_cache(ob, clmd, framenr)) + { + // Copy the result back to the object. + cloth_to_object ( ob, clmd, vertexCos, numverts ); + } + } + return; } - */ // printf("ct: %f, st: %f, r.cfra: %f, dt: %f\n", current_time, clmd->sim_parms->sim_time, ( float ) G.scene->r.cfra, deltaTime); diff --git a/source/blender/makesdna/DNA_cloth_types.h b/source/blender/makesdna/DNA_cloth_types.h index 9c5e3a1b9f2..661ad9547d5 100644 --- a/source/blender/makesdna/DNA_cloth_types.h +++ b/source/blender/makesdna/DNA_cloth_types.h @@ -76,6 +76,8 @@ typedef struct SimulationSettings int maxspringlen; /* in percent!; if tearing enabled, a spring will get cut */ int lastframe; /* frame on which simulation stops */ int firstframe; /* frame on which simulation starts */ + int lastcachedframe; + int pad3; } SimulationSettings; diff --git a/source/blender/src/buttons_object.c b/source/blender/src/buttons_object.c index 8e691c30f94..1d7a1972d36 100644 --- a/source/blender/src/buttons_object.c +++ b/source/blender/src/buttons_object.c @@ -2295,7 +2295,7 @@ void do_object_panels(unsigned short event) CFRA= 1; update_for_newframe_muted(); DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA); - cloth_clear_cache(ob, clmd, 2); + cloth_clear_cache(ob, clmd, 1); allqueue(REDRAWBUTSOBJECT, 0); allqueue(REDRAWVIEW3D, 0); } @@ -2306,7 +2306,7 @@ void do_object_panels(unsigned short event) ClothModifierData *clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth); if(clmd) { - cloth_clear_cache(ob, clmd, MAX2(2.0,G.scene->r.cfra + 1.0)); + cloth_clear_cache(ob, clmd, MAX2(1.0,G.scene->r.cfra + 1.0)); allqueue(REDRAWBUTSOBJECT, 0); } } diff --git a/source/blender/src/drawobject.c b/source/blender/src/drawobject.c index 0069ac0f15e..a23ee559570 100644 --- a/source/blender/src/drawobject.c +++ b/source/blender/src/drawobject.c @@ -5406,7 +5406,7 @@ void draw_object(Base *base, int flag) ClothModifierData *clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth); Cloth *cloth = clmd->clothObject; ClothVertex *verts; - float col[3], point[3]; + float col[3]; col[0] = 0.53; col[1] = 0.04; col[2] = 0.0; @@ -5417,35 +5417,52 @@ void draw_object(Base *base, int flag) if(cloth) { - verts = cloth->verts; - - for(i = 0; i < cloth->numverts; i++) - { - if(verts[i].flags & CLOTH_VERT_FLAG_PINNED) + /* don't paint anything if cloth has RESET status */ + if(!(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_RESET)) + { + verts = cloth->verts; + + for(i = 0; i < cloth->numverts; i++) { - float size[3], cent[3]; - GLUquadricObj *qobj = gluNewQuadric(); - - gluQuadricDrawStyle(qobj, GLU_FILL); - - size[0]= clmd->coll_parms->avg_spring_len / 3.0; - size[1]= clmd->coll_parms->avg_spring_len / 3.0; - size[2]= clmd->coll_parms->avg_spring_len / 3.0; - - VECCOPY ( point, verts[i].x ); - Mat4MulVecfl ( ob->imat, point ); - - cent[0]= point[0]; - cent[1]= point[1]; - cent[2]= point[2]; - - glPushMatrix(); - glTranslatef(cent[0], cent[1], cent[2]); - glScalef(size[0], size[1], size[2]); - gluSphere(qobj, 1.0, 8, 5); - glPopMatrix(); - - gluDeleteQuadric(qobj); + if(verts[i].flags & CLOTH_VERT_FLAG_PINNED) + { + float size[3], cent[3]; + GLUquadricObj *qobj = gluNewQuadric(); + + gluQuadricDrawStyle(qobj, GLU_FILL); + + size[0]= clmd->coll_parms->avg_spring_len / 3.0; + size[1]= clmd->coll_parms->avg_spring_len / 3.0; + size[2]= clmd->coll_parms->avg_spring_len / 3.0; + + VECCOPY ( cent, verts[i].x ); + Mat4MulVecfl ( ob->imat, cent ); + + glPushMatrix(); + glTranslatef(cent[0], cent[1], cent[2]); + glScalef(size[0], size[1], size[2]); + + // gluSphere(qobj, 1.0, 8, 5); + glTranslatef(0, 0, 1.0); + gluDisk(qobj, 0, 0.4, 8, 5); + gluCylinder(qobj, 0.4, 0.4, 1.0, 8, 5); + + glTranslatef(0, 0, 1.0); + gluDisk(qobj, 0, 0.4, 8, 5); + + glTranslatef(0, 0, -2.0); + /* + col[0] = 0.53; + col[1] = 0.54; + col[2] = 0.0; + glColor3fv(col); + */ + gluCylinder(qobj, 0.0, 0.2, 1.0, 8, 5); + + glPopMatrix(); + + gluDeleteQuadric(qobj); + } } } } From 576a7f623c99a1df71bf4135dd44930c99d63150 Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Wed, 23 Jan 2008 17:58:09 +0000 Subject: [PATCH 078/246] fix for collision modifier not reseted after first run + made the pushpin more like one --- source/blender/blenkernel/intern/cloth.c | 6 +++ source/blender/blenkernel/intern/modifier.c | 6 +++ source/blender/src/drawobject.c | 42 +++++++++++++++++---- 3 files changed, 47 insertions(+), 7 deletions(-) diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c index 4a0252b7fd7..df57440996a 100644 --- a/source/blender/blenkernel/intern/cloth.c +++ b/source/blender/blenkernel/intern/cloth.c @@ -621,6 +621,12 @@ void clothModifier_do ( ClothModifierData *clmd, Object *ob, DerivedMesh *dm, clmd->sim_parms->dt = 1.0f / clmd->sim_parms->stepsPerFrame; clmd->sim_parms->sim_time = current_time; + + /* check if cache is active / if file is already saved */ + if ((!G.relbase_valid) && ( deltaTime != 1.0f )) + { + clmd->sim_parms->flags |= CLOTH_SIMSETTINGS_FLAG_RESET; + } if(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_RESET) { diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c index 40b01fa3322..3ea4d4fb584 100644 --- a/source/blender/blenkernel/intern/modifier.c +++ b/source/blender/blenkernel/intern/modifier.c @@ -5130,6 +5130,8 @@ static void collisionModifier_deformVerts( current_time = bsystem_time ( ob, ( float ) G.scene->r.cfra, 0.0 ); + // printf("current_time %f, collmd->time %f\n", current_time, collmd->time); + if(current_time > collmd->time) { numverts = dm->getNumVerts ( dm ); @@ -5194,6 +5196,10 @@ static void collisionModifier_deformVerts( collmd->time = current_time; } + else + { + collmd->time = current_time; + } } if(dm) diff --git a/source/blender/src/drawobject.c b/source/blender/src/drawobject.c index a23ee559570..6696fd3cfe3 100644 --- a/source/blender/src/drawobject.c +++ b/source/blender/src/drawobject.c @@ -5421,7 +5421,13 @@ void draw_object(Base *base, int flag) if(!(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_RESET)) { verts = cloth->verts; - + /* + // this makes the screen pink + glEnable(GL_LIGHTING); + glEnable(GL_COLOR_MATERIAL); + glShadeModel(GL_SMOOTH); + */ + for(i = 0; i < cloth->numverts; i++) { if(verts[i].flags & CLOTH_VERT_FLAG_PINNED) @@ -5443,27 +5449,49 @@ void draw_object(Base *base, int flag) glScalef(size[0], size[1], size[2]); // gluSphere(qobj, 1.0, 8, 5); - glTranslatef(0, 0, 1.0); - gluDisk(qobj, 0, 0.4, 8, 5); - gluCylinder(qobj, 0.4, 0.4, 1.0, 8, 5); glTranslatef(0, 0, 1.0); - gluDisk(qobj, 0, 0.4, 8, 5); + gluDisk(qobj, 0, 0.25, 8, 5); - glTranslatef(0, 0, -2.0); + glTranslatef(0, 0, -1.0); + + glTranslatef(0, 0, 0.875); + gluCylinder(qobj, 0.15, 0.25, 0.125, 8, 5); + + glTranslatef(0, 0, -0.25); + gluCylinder(qobj, 0.15, 0.15, 0.25, 8, 5); + + glTranslatef(0, 0, -0.125); + gluCylinder(qobj, 0.25, 0.15, 0.125, 8, 5); + + // gluDisk(qobj, 0, 0.5, 8, 5); + + /* + glTranslatef(0, 0, 1.0); + gluDisk(qobj, 0, 0.4, 8, 5); + */ /* col[0] = 0.53; col[1] = 0.54; col[2] = 0.0; glColor3fv(col); */ - gluCylinder(qobj, 0.0, 0.2, 1.0, 8, 5); + glTranslatef(0, 0, -0.5); + gluCylinder(qobj, 0.0, 0.05, 0.5, 8, 5); + + glTranslatef(0, 0, 0.5); + gluDisk(qobj, 0, 0.25, 8, 5); glPopMatrix(); gluDeleteQuadric(qobj); } } + /* + glShadeModel(GL_FLAT); + glDisable(GL_COLOR_MATERIAL); + glDisable(GL_LIGHTING); + */ } } } From c5dc7c7b024b0136e385aabf846c086428daf4c0 Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Thu, 24 Jan 2008 10:43:12 +0000 Subject: [PATCH 079/246] New: Editable cache. Fixed: Don't clear cache on e.g. lamp moving. Changed: Switched to another modifier type to be more flexible (allows tearing later) --- source/blender/blenkernel/BKE_cloth.h | 16 +- source/blender/blenkernel/intern/cloth.c | 315 ++++++++++---------- source/blender/blenkernel/intern/implicit.c | 45 +-- source/blender/blenkernel/intern/modifier.c | 43 ++- source/blender/src/buttons_object.c | 2 +- source/blender/src/editmesh.c | 105 ++++++- source/blender/src/transform_conversions.c | 2 +- source/blender/src/vpaint.c | 1 + 8 files changed, 305 insertions(+), 224 deletions(-) diff --git a/source/blender/blenkernel/BKE_cloth.h b/source/blender/blenkernel/BKE_cloth.h index 4e704098ebd..e3fdb9e0f25 100644 --- a/source/blender/blenkernel/BKE_cloth.h +++ b/source/blender/blenkernel/BKE_cloth.h @@ -160,16 +160,6 @@ typedef enum #define CLOTH_VERT_FLAG_PINNED 1 #define CLOTH_VERT_FLAG_COLLISION 2 - -// needed for buttons_object.c -void cloth_clear_cache(Object *ob, ClothModifierData *clmd, float framenr); - -// needed for cloth.c -void implicit_set_positions ( ClothModifierData *clmd ); - -// from cloth.c, needed for modifier.c -void clothModifier_do ( ClothModifierData *clmd, Object *ob, DerivedMesh *dm, float ( *vertexCos ) [3], int numverts ); - typedef void ( *CM_COLLISION_RESPONSE ) ( ClothModifierData *clmd, CollisionModifierData *collmd, CollisionTree *tree1, CollisionTree *tree2 ); @@ -193,6 +183,7 @@ int bvh_traverse ( ClothModifierData * clmd, CollisionModifierData * collmd, Col int implicit_init ( Object *ob, ClothModifierData *clmd ); int implicit_free ( ClothModifierData *clmd ); int implicit_solver ( Object *ob, float frame, ClothModifierData *clmd, ListBase *effectors ); +void implicit_set_positions ( ClothModifierData *clmd ); //////////////////////////////////////////////// @@ -204,13 +195,16 @@ int implicit_solver ( Object *ob, float frame, ClothModifierData *clmd, ListBase void cloth_free_modifier_extern (ClothModifierData *clmd); void cloth_free_modifier (Object *ob, ClothModifierData *clmd); void cloth_init (ClothModifierData *clmd); -void cloth_deform_verts (struct Object *ob, float framenr, float ( *vertexCos ) [3], int numVerts, void *derivedData, ClothModifierData *clmd); +DerivedMesh *clothModifier_do(ClothModifierData *clmd,Object *ob, DerivedMesh *dm, int useRenderParams, int isFinalCalc); void cloth_update_normals (ClothVertex *verts, int nVerts, MFace *face, int totface); // needed for collision.c void bvh_update_from_cloth(ClothModifierData *clmd, int moving); +// needed for editmesh.c +void cloth_write_cache(Object *ob, ClothModifierData *clmd, float framenr); + //////////////////////////////////////////////// diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c index df57440996a..f22fd28d96e 100644 --- a/source/blender/blenkernel/intern/cloth.c +++ b/source/blender/blenkernel/intern/cloth.c @@ -121,9 +121,9 @@ static CM_SOLVER_DEF solvers [] = /* ********** cloth engine ******* */ /* Prototypes for internal functions. */ -static void cloth_to_object ( Object *ob, ClothModifierData *clmd, float ( *vertexCos ) [3], unsigned int numverts ); +static void cloth_to_object (Object *ob, ClothModifierData *clmd, DerivedMesh *dm); static void cloth_from_mesh ( Object *ob, ClothModifierData *clmd, DerivedMesh *dm ); -static int cloth_from_object ( Object *ob, ClothModifierData *clmd, DerivedMesh *dm, float ( *vertexCos ) [3], unsigned int numverts, float framenr ); +static int cloth_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *dm, float framenr); int cloth_build_springs ( ClothModifierData *clmd, DerivedMesh *dm ); static void cloth_apply_vgroup ( ClothModifierData *clmd, DerivedMesh *dm, short vgroup ); @@ -545,7 +545,7 @@ void cloth_clear_cache(Object *ob, ClothModifierData *clmd, float framenr) cloth_read_cache(ob, clmd, framenr); } } -static void cloth_write_cache(Object *ob, ClothModifierData *clmd, float framenr) +void cloth_write_cache(Object *ob, ClothModifierData *clmd, float framenr) { FILE *fp = NULL; int stack_index = -1; @@ -579,26 +579,46 @@ static void cloth_write_cache(Object *ob, ClothModifierData *clmd, float framenr -/** -* cloth_deform_verts - simulates one step, framenr is in frames. -* -**/ -void clothModifier_do ( ClothModifierData *clmd, Object *ob, DerivedMesh *dm, - float ( *vertexCos ) [3], int numverts ) +/************************************************ + * clothModifier_do - main simulation function +************************************************/ +DerivedMesh *clothModifier_do(ClothModifierData *clmd,Object *ob, DerivedMesh *dm, int useRenderParams, int isFinalCalc) + { unsigned int i; Cloth *cloth = clmd->clothObject; unsigned int framenr = ( float ) G.scene->r.cfra; float current_time = bsystem_time ( ob, ( float ) G.scene->r.cfra, 0.0 ); - ListBase *effectors = NULL; + ListBase *effectors = NULL; ClothVertex *verts = NULL; float deltaTime = current_time - clmd->sim_parms->sim_time; + unsigned int numverts = -1; + unsigned int numedges = -1; + unsigned int numfaces = -1; + MVert *mvert = NULL; + MEdge *medge = NULL; + MFace *mface = NULL; + DerivedMesh *result = NULL; + + result = CDDM_copy(dm); + + if(!result) + { + return dm; + } + + numverts = result->getNumVerts(result); + numedges = result->getNumEdges(result); + numfaces = result->getNumFaces(result); + mvert = CDDM_get_verts(result); + medge = CDDM_get_edges(result); + mface = CDDM_get_faces(result); // only be active during a specific period: // that's "first frame" and "last frame" on GUI if ( current_time < clmd->sim_parms->firstframe ) { - return; + return result; } else if ( current_time > clmd->sim_parms->lastframe ) { @@ -609,10 +629,10 @@ void clothModifier_do ( ClothModifierData *clmd, Object *ob, DerivedMesh *dm, if(cloth_read_cache(ob, clmd, framenr)) { // Copy the result back to the object. - cloth_to_object ( ob, clmd, vertexCos, numverts ); + cloth_to_object (ob, clmd, result); } } - return; + return result; } // printf("ct: %f, st: %f, r.cfra: %f, dt: %f\n", current_time, clmd->sim_parms->sim_time, ( float ) G.scene->r.cfra, deltaTime); @@ -639,11 +659,11 @@ void clothModifier_do ( ClothModifierData *clmd, Object *ob, DerivedMesh *dm, { cloth_clear_cache(ob, clmd, 0); - if ( !cloth_from_object ( ob, clmd, dm, vertexCos, numverts, framenr ) ) - return; + if ( !cloth_from_object ( ob, clmd, result, framenr ) ) + return result; if ( clmd->clothObject == NULL ) - return; + return result; cloth = clmd->clothObject; } @@ -665,7 +685,7 @@ void clothModifier_do ( ClothModifierData *clmd, Object *ob, DerivedMesh *dm, VECCOPY ( verts->txold, verts->x ); // Get the current position. - VECCOPY ( verts->xconst, vertexCos[i] ); + VECCOPY ( verts->xconst, mvert[i].co ); Mat4MulVecfl ( ob->obmat, verts->xconst ); } @@ -679,14 +699,10 @@ void clothModifier_do ( ClothModifierData *clmd, Object *ob, DerivedMesh *dm, // printf ( "Cloth simulation time: %f\n", ( float ) tval() ); cloth_write_cache(ob, clmd, framenr); - } // Copy the result back to the object. - cloth_to_object ( ob, clmd, vertexCos, numverts ); - - // bvh_free(clmd->clothObject->tree); - // clmd->clothObject->tree = bvh_build(clmd, clmd->coll_parms->epsilon); + cloth_to_object (ob, clmd, result); } } @@ -696,7 +712,7 @@ void clothModifier_do ( ClothModifierData *clmd, Object *ob, DerivedMesh *dm, { if(cloth_read_cache(ob, clmd, framenr)) { - cloth_to_object ( ob, clmd, vertexCos, numverts ); + cloth_to_object (ob, clmd, result); } } else @@ -704,6 +720,8 @@ void clothModifier_do ( ClothModifierData *clmd, Object *ob, DerivedMesh *dm, cloth_clear_cache(ob, clmd, 0); } } + + return result; } @@ -783,59 +801,55 @@ void cloth_free_modifier_extern ( ClothModifierData *clmd ) return; cloth = clmd->clothObject; - - if ( ! ( clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_CCACHE_PROTECT ) ) - { - if ( cloth ) - { - // If our solver provides a free function, call it - if ( cloth->old_solver_type < 255 && solvers [cloth->old_solver_type].free ) - { - solvers [cloth->old_solver_type].free ( clmd ); - } - - // Free the verts. - if ( cloth->verts != NULL ) - MEM_freeN ( cloth->verts ); - - cloth->verts = NULL; - cloth->numverts = 0; - - // Free the springs. - if ( cloth->springs != NULL ) - { - LinkNode *search = cloth->springs; - while(search) - { - ClothSpring *spring = search->link; - - MEM_freeN ( spring ); - search = search->next; - } - BLI_linklist_free(cloth->springs, NULL); - - cloth->springs = NULL; - } - - cloth->springs = NULL; - cloth->numsprings = 0; - - // free BVH collision tree - if ( cloth->tree ) - bvh_free ( ( BVH * ) cloth->tree ); - - // we save our faces for collision objects - if ( cloth->mfaces ) - MEM_freeN ( cloth->mfaces ); - /* - if(clmd->clothObject->facemarks) - MEM_freeN(clmd->clothObject->facemarks); - */ - MEM_freeN ( cloth ); - clmd->clothObject = NULL; + + if ( cloth ) + { + // If our solver provides a free function, call it + if ( cloth->old_solver_type < 255 && solvers [cloth->old_solver_type].free ) + { + solvers [cloth->old_solver_type].free ( clmd ); } + + // Free the verts. + if ( cloth->verts != NULL ) + MEM_freeN ( cloth->verts ); + + cloth->verts = NULL; + cloth->numverts = 0; + + // Free the springs. + if ( cloth->springs != NULL ) + { + LinkNode *search = cloth->springs; + while(search) + { + ClothSpring *spring = search->link; + + MEM_freeN ( spring ); + search = search->next; + } + BLI_linklist_free(cloth->springs, NULL); + + cloth->springs = NULL; + } + + cloth->springs = NULL; + cloth->numsprings = 0; + + // free BVH collision tree + if ( cloth->tree ) + bvh_free ( ( BVH * ) cloth->tree ); + + // we save our faces for collision objects + if ( cloth->mfaces ) + MEM_freeN ( cloth->mfaces ); + /* + if(clmd->clothObject->facemarks) + MEM_freeN(clmd->clothObject->facemarks); + */ + MEM_freeN ( cloth ); + clmd->clothObject = NULL; } - clmd->sim_parms->flags &= ~CLOTH_SIMSETTINGS_FLAG_RESET; } /****************************************************************************** @@ -847,24 +861,25 @@ void cloth_free_modifier_extern ( ClothModifierData *clmd ) /** * cloth_to_object - copies the deformed vertices to the object. * -* This function is a modified version of the softbody.c:softbody_to_object() function. **/ -static void cloth_to_object ( Object *ob, ClothModifierData *clmd, float ( *vertexCos ) [3], unsigned int numverts ) +static void cloth_to_object (Object *ob, ClothModifierData *clmd, DerivedMesh *dm) { - ClothVertex *verts = NULL; unsigned int i = 0; + MVert *mvert = NULL; + unsigned int numverts; + Cloth *cloth = clmd->clothObject; - if ( clmd->clothObject ) - { - verts = clmd->clothObject->verts; - + if (clmd->clothObject) { /* inverse matrix is not uptodate... */ - Mat4Invert ( ob->imat, ob->obmat ); + Mat4Invert (ob->imat, ob->obmat); - for ( i = 0; i < numverts; i++, verts++ ) + mvert = CDDM_get_verts(dm); + numverts = dm->getNumVerts(dm); + + for (i = 0; i < numverts; i++) { - VECCOPY ( vertexCos[i], verts->x ); - Mat4MulVecfl ( ob->imat, vertexCos[i] ); /* cloth is in global coords */ + VECCOPY (mvert[i].co, cloth->verts[i].x); + Mat4MulVecfl (ob->imat, mvert[i].co); /* cloth is in global coords */ } } } @@ -948,20 +963,18 @@ float cloth_globallen ( float *v1,float *v2,Object *ob ) return VecLenf ( p1,p2 ); } -// only meshes supported at the moment -static int cloth_from_object ( Object *ob, ClothModifierData *clmd, DerivedMesh *dm, float ( *vertexCos ) [3], unsigned int numverts, float framenr ) +static int cloth_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *dm, float framenr) { unsigned int i = 0; - // dm->getNumVerts(dm); - MVert *mvert = NULL; // CDDM_get_verts(dm); + MVert *mvert = NULL; ClothVertex *verts = NULL; float tnull[3] = {0,0,0}; - /* If we have a clothObject, free it. */ + // If we have a clothObject, free it. if ( clmd->clothObject != NULL ) cloth_free_modifier ( ob, clmd ); - /* Allocate a new cloth object. */ + // Allocate a new cloth object. clmd->clothObject = MEM_callocN ( sizeof ( Cloth ), "cloth" ); if ( clmd->clothObject ) { @@ -974,88 +987,74 @@ static int cloth_from_object ( Object *ob, ClothModifierData *clmd, DerivedMesh return 0; } - switch ( ob->type ) + // mesh input objects need DerivedMesh + if ( !dm ) + return 0; + + cloth_from_mesh ( ob, clmd, dm ); + + if ( clmd->clothObject != NULL ) { - case OB_MESH: + // create springs + clmd->clothObject->springs = NULL; + clmd->clothObject->numsprings = -1; + + mvert = CDDM_get_verts ( dm ); + verts = clmd->clothObject->verts; - // mesh input objects need DerivedMesh - if ( !dm ) - return 0; + // set initial values + for ( i = 0; i < dm->getNumVerts(dm); i++, verts++ ) + { + VECCOPY ( verts->x, mvert[i].co ); + Mat4MulVecfl ( ob->obmat, verts->x ); - cloth_from_mesh ( ob, clmd, dm ); + verts->mass = clmd->sim_parms->mass; - if ( clmd->clothObject != NULL ) - { - /* create springs */ - clmd->clothObject->springs = NULL; - clmd->clothObject->numsprings = -1; - - mvert = CDDM_get_verts ( dm ); - verts = clmd->clothObject->verts; + if ( clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL ) + verts->goal= clmd->sim_parms->defgoal; + else + verts->goal= 0.0f; - /* set initial values */ - for ( i = 0; i < numverts; i++, verts++ ) - { - VECCOPY ( verts->x, mvert[i].co ); - Mat4MulVecfl ( ob->obmat, verts->x ); + verts->flags = 0; + VECCOPY ( verts->xold, verts->x ); + VECCOPY ( verts->xconst, verts->x ); + VECCOPY ( verts->txold, verts->x ); + VecMulf ( verts->v, 0.0f ); - verts->mass = clmd->sim_parms->mass; - - if ( clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL ) - verts->goal= clmd->sim_parms->defgoal; - else - verts->goal= 0.0f; - - verts->flags = 0; - VECCOPY ( verts->xold, verts->x ); - VECCOPY ( verts->xconst, verts->x ); - VECCOPY ( verts->txold, verts->x ); - VecMulf ( verts->v, 0.0f ); - - verts->impulse_count = 0; - VECCOPY ( verts->impulse, tnull ); - } - - if ( !cloth_build_springs ( clmd, dm ) ) - { - cloth_free_modifier ( ob, clmd ); - modifier_setError ( & ( clmd->modifier ), "Can't build springs." ); - return 0; - } - - // apply / set vertex groups - if ( clmd->sim_parms->vgroup_mass > 0 ) - cloth_apply_vgroup ( clmd, dm, clmd->sim_parms->vgroup_mass ); - - // init our solver - if ( solvers [clmd->sim_parms->solver_type].init ) - solvers [clmd->sim_parms->solver_type].init ( ob, clmd ); - - clmd->clothObject->tree = bvh_build_from_cloth ( clmd, clmd->coll_parms->epsilon ); - - cloth_write_cache(ob, clmd, framenr-1); - } - - return 1; - case OB_LATTICE: - printf ( "Not supported: OB_LATTICE\n" ); - // lattice_to_softbody(ob); + verts->impulse_count = 0; + VECCOPY ( verts->impulse, tnull ); + } + + if ( !cloth_build_springs ( clmd, dm ) ) + { + cloth_free_modifier ( ob, clmd ); + modifier_setError ( & ( clmd->modifier ), "Can't build springs." ); return 0; - case OB_CURVE: - case OB_SURF: - printf ( "Not supported: OB_SURF| OB_CURVE\n" ); - return 0; - default: return 0; // TODO - we do not support changing meshes + } + + // apply / set vertex groups + if ( clmd->sim_parms->vgroup_mass > 0 ) + cloth_apply_vgroup ( clmd, dm, clmd->sim_parms->vgroup_mass ); + + // init our solver + if ( solvers [clmd->sim_parms->solver_type].init ) + solvers [clmd->sim_parms->solver_type].init ( ob, clmd ); + + clmd->clothObject->tree = bvh_build_from_cloth ( clmd, clmd->coll_parms->epsilon ); + + cloth_write_cache(ob, clmd, framenr-1); + + return 1; } - return 0; } + static void cloth_from_mesh ( Object *ob, ClothModifierData *clmd, DerivedMesh *dm ) { unsigned int numverts = dm->getNumVerts ( dm ); unsigned int numfaces = dm->getNumFaces ( dm ); - MFace *mface = dm->getFaceArray ( dm ); + MFace *mface = CDDM_get_faces(dm); unsigned int i = 0; /* Allocate our vertices. diff --git a/source/blender/blenkernel/intern/implicit.c b/source/blender/blenkernel/intern/implicit.c index 3f21bf2bfc5..69cc3b165c2 100644 --- a/source/blender/blenkernel/intern/implicit.c +++ b/source/blender/blenkernel/intern/implicit.c @@ -569,33 +569,35 @@ DO_INLINE void mul_bfmatrix_S(fmatrix3x3 *matrix, float scalar) /* SPARSE SYMMETRIC multiply big matrix with long vector*/ /* STATUS: verified */ -DO_INLINE void mul_bfmatrix_lfvector( float (*to)[3], fmatrix3x3 *from, float (*fLongVector)[3]) +DO_INLINE void mul_bfmatrix_lfvector( float (*to)[3], fmatrix3x3 *from, lfVector *fLongVector) { unsigned int i = 0; + lfVector *temp = create_lfvector(from[0].vcount); + zero_lfvector(to, from[0].vcount); - /* process diagonal elements */ - for(i = 0; i < from[0].vcount; i++) - { - muladd_fmatrix_fvector(to[from[i].r], from[i].m, fLongVector[from[i].c]); - } - /* process off-diagonal entries (every off-diagonal entry needs to be symmetric) */ - // TODO: pragma below is wrong, correct it! - // #pragma omp parallel for shared(to,from, fLongVector) private(i) - for(i = from[0].vcount; i < from[0].vcount+from[0].scount; i++) +#pragma omp parallel sections private(i) { - // muladd_fmatrix_fvector(to[from[i].c], from[i].m, fLongVector[from[i].r]); - - to[from[i].c][0] += INPR(from[i].m[0],fLongVector[from[i].r]); - to[from[i].c][1] += INPR(from[i].m[1],fLongVector[from[i].r]); - to[from[i].c][2] += INPR(from[i].m[2],fLongVector[from[i].r]); - - // muladd_fmatrix_fvector(to[from[i].r], from[i].m, fLongVector[from[i].c]); - - to[from[i].r][0] += INPR(from[i].m[0],fLongVector[from[i].c]); - to[from[i].r][1] += INPR(from[i].m[1],fLongVector[from[i].c]); - to[from[i].r][2] += INPR(from[i].m[2],fLongVector[from[i].c]); +#pragma omp section + { + for(i = from[0].vcount; i < from[0].vcount+from[0].scount; i++) + { + muladd_fmatrix_fvector(to[from[i].c], from[i].m, fLongVector[from[i].r]); + } + } +#pragma omp section + { + for(i = 0; i < from[0].vcount+from[0].scount; i++) + { + muladd_fmatrix_fvector(temp[from[i].r], from[i].m, fLongVector[from[i].c]); + } + } } + add_lfvector_lfvector(to, to, temp, from[0].vcount); + + del_lfvector(temp); + + } /* SPARSE SYMMETRIC multiply big matrix with long vector (for diagonal preconditioner) */ @@ -1088,7 +1090,6 @@ DO_INLINE void cloth_calc_spring_force(ClothModifierData *clmd, ClothSpring *s, float bending_force[3] = {0,0,0}; float damping_force[3] = {0,0,0}; float nulldfdx[3][3]={ {0,0,0}, {0,0,0}, {0,0,0}}; - Cloth *cloth = clmd->clothObject; VECCOPY(s->f, nullf); cp_fmatrix(s->dfdx, nulldfdx); diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c index 3ea4d4fb584..428c136a7fe 100644 --- a/source/blender/blenkernel/intern/modifier.c +++ b/source/blender/blenkernel/intern/modifier.c @@ -4958,29 +4958,23 @@ static void clothModifier_initData(ModifierData *md) cloth_init (clmd); } -static void clothModifier_deformVerts( - ModifierData *md, Object *ob, DerivedMesh *derivedData, - float (*vertexCos)[3], int numVerts) +static DerivedMesh *clothModifier_applyModifier(ModifierData *md, Object *ob, + DerivedMesh *derivedData, int useRenderParams, int isFinalCalc) { - DerivedMesh *dm = NULL; + ClothModifierData *clmd = (ClothModifierData*) md; + DerivedMesh *result=NULL; + + /* check for alloc failing */ + if(!clmd->sim_parms || !clmd->coll_parms) + return derivedData; - /* if possible use/create DerivedMesh */ - - if(derivedData) dm = CDDM_copy(derivedData); - else if(ob->type==OB_MESH) dm = CDDM_from_mesh(ob->data, ob); - - if(dm) + result = clothModifier_do(clmd, ob, derivedData, useRenderParams, isFinalCalc); + + if(result) { - CDDM_apply_vert_coords(dm, vertexCos); - CDDM_calc_normals(dm); + return result; } - - /* TODO: check for sim_parms / coll_parms NOT NULL */ - - clothModifier_do((ClothModifierData *)md, ob, dm, vertexCos, numVerts); - - if(dm) - dm->release(dm); + return derivedData; } static void clothModifier_updateDepgraph( @@ -5035,8 +5029,6 @@ static int clothModifier_dependsOnTime(ModifierData *md) static void clothModifier_freeData(ModifierData *md) { ClothModifierData *clmd = (ClothModifierData*) md; - Object *ob = NULL; - ClothModifierData *clmd2 = NULL; if (clmd) { @@ -7017,10 +7009,10 @@ ModifierTypeInfo *modifierType_getInfo(ModifierType type) mti->deformVerts = softbodyModifier_deformVerts; mti = INIT_TYPE(Cloth); - mti->type = eModifierTypeType_OnlyDeform; + mti->type = eModifierTypeType_Nonconstructive; mti->initData = clothModifier_initData; - mti->flags = eModifierTypeFlag_AcceptsCVs; - // | eModifierTypeFlag_RequiresOriginalData; + mti->flags = eModifierTypeFlag_AcceptsMesh + | eModifierTypeFlag_RequiresOriginalData; // | eModifierTypeFlag_SupportsMapping // | eModifierTypeFlag_SupportsEditmode // | eModifierTypeFlag_EnableInEditmode; @@ -7028,7 +7020,8 @@ ModifierTypeInfo *modifierType_getInfo(ModifierType type) mti->freeData = clothModifier_freeData; mti->requiredDataMask = clothModifier_requiredDataMask; // mti->copyData = clothModifier_copyData; - mti->deformVerts = clothModifier_deformVerts; + // mti->deformVerts = clothModifier_deformVerts; + mti->applyModifier = clothModifier_applyModifier; mti->updateDepgraph = clothModifier_updateDepgraph; mti = INIT_TYPE(Collision); diff --git a/source/blender/src/buttons_object.c b/source/blender/src/buttons_object.c index 1d7a1972d36..a064e266d6d 100644 --- a/source/blender/src/buttons_object.c +++ b/source/blender/src/buttons_object.c @@ -5087,7 +5087,7 @@ static void object_panel_cloth_II(Object *ob) } else { - uiDefButBitI(block, TOG, CLOTH_SIMSETTINGS_FLAG_CCACHE_PROTECT, REDRAWVIEW3D, "Protect Cache", 10,120,300,20, &clmd->sim_parms->flags, 0, 0, 0, 0, "Protect cache from automatic freeing when scene changed"); + uiDefButBitI(block, TOG, CLOTH_SIMSETTINGS_FLAG_CCACHE_PROTECT, REDRAWVIEW3D, "Protect Cache & Enable Cache Editing", 10,120,300,20, &clmd->sim_parms->flags, 0, 0, 0, 0, "Protect cache from automatic freeing when scene changed. This also enabled the cache beeing edited in editmode."); if(!(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_CCACHE_PROTECT)) { diff --git a/source/blender/src/editmesh.c b/source/blender/src/editmesh.c index 8bd397b0da4..7b51d50ae7b 100644 --- a/source/blender/src/editmesh.c +++ b/source/blender/src/editmesh.c @@ -76,6 +76,7 @@ #include "BKE_modifier.h" #include "BKE_multires.h" #include "BKE_object.h" +#include "BKE_pointcache.h" #include "BKE_texture.h" #include "BKE_utildefines.h" @@ -804,7 +805,10 @@ void make_editMesh() EditFace *efa; EditEdge *eed; EditSelection *ese; - int tot, a, eekadoodle= 0; + int tot, a, eekadoodle= 0, cloth_enabled = 0; + ClothModifierData *clmd = NULL; + Cloth *cloth = NULL; + float temp[3]; #ifdef WITH_VERSE if(me->vnode){ @@ -839,10 +843,43 @@ void make_editMesh() /* make editverts */ CustomData_copy(&me->vdata, &em->vdata, CD_MASK_EDITMESH, CD_CALLOC, 0); mvert= me->mvert; + + /* lots of checks to be sure if we have nice cloth object */ + if(modifiers_isClothEnabled(G.obedit)) + { + clmd = (ClothModifierData *) modifiers_findByType(G.obedit, eModifierType_Cloth); + cloth = clmd->clothObject; + + /* just to be sure also check vertcount */ + /* also check if we have a protected cache */ + if(cloth && (tot == cloth->numverts) && (clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_CCACHE_PROTECT)) + { + /* check if we have cache for this frame */ + int stack_index = modifiers_indexInObject(G.obedit, (ModifierData *)clmd); + + if(BKE_ptcache_id_exist((ID *)G.obedit, (float) G.scene->r.cfra, stack_index)) + { + cloth_enabled = 1; + + /* inverse matrix is not uptodate... */ + Mat4Invert ( G.obedit->imat, G.obedit->obmat ); + } + } + } evlist= (EditVert **)MEM_mallocN(tot*sizeof(void *),"evlist"); for(a=0; aco, NULL); + + if(cloth_enabled) + { + VECCOPY(temp, cloth->verts[a].x); + Mat4MulVecfl ( G.obedit->imat, temp ); + eve= addvertlist(temp, NULL); + + /* TODO: what about normals? */ + } + else + eve= addvertlist(mvert->co, NULL); evlist[a]= eve; // face select sets selection in next loop @@ -971,7 +1008,10 @@ void load_editMesh(void) EditEdge *eed; EditSelection *ese; float *fp, *newkey, *oldkey, nor[3]; - int i, a, ototvert, totedge=0; + int i, a, ototvert, totedge=0, cloth_enabled = 0; + ClothModifierData *clmd = NULL; + Cloth *cloth = NULL; + float temp[3], dt = 0.0; #ifdef WITH_VERSE if(em->vnode) { @@ -1038,9 +1078,52 @@ void load_editMesh(void) /* the vertices, use ->tmp.l as counter */ eve= em->verts.first; a= 0; - + + /* lots of checks to be sure if we have nice cloth object */ + if(modifiers_isClothEnabled(G.obedit)) + { + clmd = (ClothModifierData *) modifiers_findByType(G.obedit, eModifierType_Cloth); + cloth = clmd->clothObject; + + /* just to be sure also check vertcount */ + /* also check if we have a protected cache */ + if(cloth && (G.totvert == cloth->numverts) && (clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_CCACHE_PROTECT)) + { + /* check if we have cache for this frame */ + int stack_index = modifiers_indexInObject(G.obedit, (ModifierData *)clmd); + + if(BKE_ptcache_id_exist((ID *)G.obedit, (float) G.scene->r.cfra, stack_index)) + { + cloth_enabled = 1; + + /* inverse matrix is not uptodate... */ + Mat4Invert ( G.obedit->imat, G.obedit->obmat ); + dt = 1.0f / clmd->sim_parms->stepsPerFrame; + } + } + } + + i=0; while(eve) { - VECCOPY(mvert->co, eve->co); + + if(cloth_enabled) + { + VECCOPY(temp, cloth->verts[i].x); + VECCOPY(cloth->verts[i].x, eve->co); + Mat4MulVecfl ( G.obedit->obmat, cloth->verts[i].x ); + /* + // not physical correct but gives nicer results when commented + VECSUB(temp, cloth->verts[i].x, temp); + VecMulf(temp, 1.0f / dt); + VECADD(cloth->verts[i].v, cloth->verts[i].v, temp); + */ + if(oldverts) { + VECCOPY(mvert->co, oldverts[i].co); + } + i++; + } + else + VECCOPY(mvert->co, eve->co); mvert->mat_nr= 255; /* what was this for, halos? */ /* vertex normal */ @@ -1068,6 +1151,10 @@ void load_editMesh(void) eve= eve->next; mvert++; } + + /* burn changes to cache */ + if(cloth_enabled) + cloth_write_cache(G.obedit, clmd, (float) G.scene->r.cfra); /* the edges */ a= 0; @@ -1330,7 +1417,13 @@ void load_editMesh(void) if(base->object->data==me) { if(modifiers_isClothEnabled(base->object)) { ClothModifierData *clmd = (ClothModifierData *)modifiers_findByType(base->object, eModifierType_Cloth); - clmd->sim_parms->flags |= CLOTH_SIMSETTINGS_FLAG_RESET; + + /* only reset cloth when no cache was used */ + if(!cloth_enabled) + { + clmd->sim_parms->flags |= CLOTH_SIMSETTINGS_FLAG_RESET; + } + } base->object->softflag |= OB_SB_REDO; diff --git a/source/blender/src/transform_conversions.c b/source/blender/src/transform_conversions.c index 882a16bb9ce..5d2e7cd7410 100644 --- a/source/blender/src/transform_conversions.c +++ b/source/blender/src/transform_conversions.c @@ -3404,7 +3404,7 @@ void special_aftertrans_update(TransInfo *t) ob= base->object; if (modifiers_isSoftbodyEnabled(ob)) ob->softflag |= OB_SB_REDO; - else if(modifiers_isClothEnabled(ob)) { + else if((ob == OBACT) && modifiers_isClothEnabled(ob)) { ClothModifierData *clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth); clmd->sim_parms->flags |= CLOTH_SIMSETTINGS_FLAG_RESET; } diff --git a/source/blender/src/vpaint.c b/source/blender/src/vpaint.c index dec15f96b8a..163b93468fe 100644 --- a/source/blender/src/vpaint.c +++ b/source/blender/src/vpaint.c @@ -1353,6 +1353,7 @@ void weight_paint(void) if(modifiers_isClothEnabled(ob)) { ClothModifierData *clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth); clmd->sim_parms->flags |= CLOTH_SIMSETTINGS_FLAG_RESET; + printf("vpaint.c\n"); } BIF_undo_push("Weight Paint"); From e7f5d077810004467066d627f34d433a61e68fb2 Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Fri, 25 Jan 2008 08:55:27 +0000 Subject: [PATCH 080/246] New: load cached data on file load; Fixed: Don't destroy cache on fileload, calculate normals correctly, don't reset all data when pressing partial free, making also cache free buttons available when cache is protected, duplicating cloth with shift-d should work properly now --- source/blender/blenkernel/BKE_cloth.h | 17 +++++++---- source/blender/blenkernel/intern/cloth.c | 29 ++++++++++++------- source/blender/blenkernel/intern/implicit.c | 2 +- source/blender/blenkernel/intern/modifier.c | 26 ++++++++++++++--- source/blender/makesdna/DNA_cloth_types.h | 4 +-- source/blender/src/buttons_object.c | 32 +++++++-------------- 6 files changed, 64 insertions(+), 46 deletions(-) diff --git a/source/blender/blenkernel/BKE_cloth.h b/source/blender/blenkernel/BKE_cloth.h index e3fdb9e0f25..4c017cfaf06 100644 --- a/source/blender/blenkernel/BKE_cloth.h +++ b/source/blender/blenkernel/BKE_cloth.h @@ -128,17 +128,19 @@ ClothSpring; /* These are the bits used in SimSettings.flags. */ typedef enum { - CLOTH_SIMSETTINGS_FLAG_RESET = ( 1 << 1 ), // The CM object requires a reinitializaiton. - CLOTH_SIMSETTINGS_FLAG_COLLOBJ = ( 1 << 2 ), // object is only collision object, no cloth simulation is done - CLOTH_SIMSETTINGS_FLAG_GOAL = ( 1 << 3 ), // we have goals enabled - CLOTH_SIMSETTINGS_FLAG_TEARING = ( 1 << 4 ), // true if tearing is enabled + CLOTH_SIMSETTINGS_FLAG_RESET = ( 1 << 1 ), // The CM object requires a reinitializaiton. + CLOTH_SIMSETTINGS_FLAG_COLLOBJ = ( 1 << 2 ),// object is only collision object, no cloth simulation is done + CLOTH_SIMSETTINGS_FLAG_GOAL = ( 1 << 3 ), // we have goals enabled + CLOTH_SIMSETTINGS_FLAG_TEARING = ( 1 << 4 ),// true if tearing is enabled CLOTH_SIMSETTINGS_FLAG_CCACHE_PROTECT = ( 1 << 5 ), // true if tearing is enabled + CLOTH_SIMSETTINGS_FLAG_NEW = ( 1 << 6 ), // unsued, true if cloth was just enabled } CLOTH_SIMSETTINGS_FLAGS; -/* SPRING FLAGS */ +/* COLLISION FLAGS */ typedef enum { - CLOTH_COLLISIONSETTINGS_FLAG_ENABLED = ( 1 << 1 ), + CLOTH_COLLSETTINGS_FLAG_ENABLED = ( 1 << 1 ), /* enables cloth - object collisions */ + CLOTH_COLLSETTINGS_FLAG_SELF = ( 1 << 2 ), /* unused */ } CLOTH_COLLISIONSETTINGS_FLAGS; /* Spring types as defined in the paper.*/ @@ -205,6 +207,9 @@ void bvh_update_from_cloth(ClothModifierData *clmd, int moving); // needed for editmesh.c void cloth_write_cache(Object *ob, ClothModifierData *clmd, float framenr); +// needed for button_object.c +void cloth_clear_cache(Object *ob, ClothModifierData *clmd, float framenr); + //////////////////////////////////////////////// diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c index f22fd28d96e..70c6857f14b 100644 --- a/source/blender/blenkernel/intern/cloth.c +++ b/source/blender/blenkernel/intern/cloth.c @@ -153,7 +153,7 @@ void cloth_init ( ClothModifierData *clmd ) clmd->sim_parms->mass = 1.0f; clmd->sim_parms->stepsPerFrame = 5; clmd->sim_parms->sim_time = 1.0; - clmd->sim_parms->flags = CLOTH_SIMSETTINGS_FLAG_RESET; + clmd->sim_parms->flags = CLOTH_SIMSETTINGS_FLAG_NEW; clmd->sim_parms->solver_type = 0; clmd->sim_parms->preroll = 0; clmd->sim_parms->maxspringlen = 10; @@ -166,7 +166,7 @@ void cloth_init ( ClothModifierData *clmd ) clmd->coll_parms->friction = 10.0; clmd->coll_parms->loop_count = 1; clmd->coll_parms->epsilon = 0.01f; - clmd->coll_parms->flags = CLOTH_COLLISIONSETTINGS_FLAG_ENABLED; + clmd->coll_parms->flags = CLOTH_COLLSETTINGS_FLAG_ENABLED; /* These defaults are copied from softbody.c's * softbody_calc_forces() function. @@ -533,7 +533,8 @@ void cloth_clear_cache(Object *ob, ClothModifierData *clmd, float framenr) { int stack_index = -1; - if(!(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_CCACHE_PROTECT)) + /* clear cache if specific frame cleaning requested or cache is not protected */ + if((!(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_CCACHE_PROTECT)) || (framenr > 1.0)) { stack_index = modifiers_indexInObject(ob, (ModifierData *)clmd); @@ -635,8 +636,6 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd,Object *ob, DerivedMesh *d return result; } - // printf("ct: %f, st: %f, r.cfra: %f, dt: %f\n", current_time, clmd->sim_parms->sim_time, ( float ) G.scene->r.cfra, deltaTime); - // unused in the moment, calculated seperately in implicit.c clmd->sim_parms->dt = 1.0f / clmd->sim_parms->stepsPerFrame; @@ -659,6 +658,8 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd,Object *ob, DerivedMesh *d { cloth_clear_cache(ob, clmd, 0); + // printf("v1: %d, v2: %d\n", numverts, clmd->clothObject->numverts); + if ( !cloth_from_object ( ob, clmd, result, framenr ) ) return result; @@ -718,6 +719,9 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd,Object *ob, DerivedMesh *d else { cloth_clear_cache(ob, clmd, 0); + + if ( !cloth_from_object ( ob, clmd, result, framenr ) ) + return result; } } @@ -743,9 +747,9 @@ void cloth_free_modifier ( Object *ob, ClothModifierData *clmd ) cloth_clear_cache ( ob, clmd, 0 ); // If our solver provides a free function, call it - if ( cloth->old_solver_type < 255 && solvers [cloth->old_solver_type].free ) + if ( solvers [clmd->sim_parms->solver_type].free ) { - solvers [cloth->old_solver_type].free ( clmd ); + solvers [clmd->sim_parms->solver_type].free ( clmd ); } // Free the verts. @@ -805,9 +809,9 @@ void cloth_free_modifier_extern ( ClothModifierData *clmd ) if ( cloth ) { // If our solver provides a free function, call it - if ( cloth->old_solver_type < 255 && solvers [cloth->old_solver_type].free ) + if ( solvers [clmd->sim_parms->solver_type].free ) { - solvers [cloth->old_solver_type].free ( clmd ); + solvers [clmd->sim_parms->solver_type].free ( clmd ); } // Free the verts. @@ -972,7 +976,9 @@ static int cloth_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *d // If we have a clothObject, free it. if ( clmd->clothObject != NULL ) + { cloth_free_modifier ( ob, clmd ); + } // Allocate a new cloth object. clmd->clothObject = MEM_callocN ( sizeof ( Cloth ), "cloth" ); @@ -1041,8 +1047,9 @@ static int cloth_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *d solvers [clmd->sim_parms->solver_type].init ( ob, clmd ); clmd->clothObject->tree = bvh_build_from_cloth ( clmd, clmd->coll_parms->epsilon ); - - cloth_write_cache(ob, clmd, framenr-1); + + if(!cloth_read_cache(ob, clmd, framenr)) + cloth_write_cache(ob, clmd, framenr); return 1; } diff --git a/source/blender/blenkernel/intern/implicit.c b/source/blender/blenkernel/intern/implicit.c index 69cc3b165c2..557a664b5ea 100644 --- a/source/blender/blenkernel/intern/implicit.c +++ b/source/blender/blenkernel/intern/implicit.c @@ -1389,7 +1389,7 @@ int implicit_solver (Object *ob, float frame, ClothModifierData *clmd, ListBase add_lfvector_lfvectorS(id->Xnew, id->X, id->Vnew, dt, numverts); - if(clmd->coll_parms->flags & CLOTH_COLLISIONSETTINGS_FLAG_ENABLED) + if(clmd->coll_parms->flags & CLOTH_COLLSETTINGS_FLAG_ENABLED) { // collisions // itstart(); diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c index d18d5ae3fd0..a10210cbf3a 100644 --- a/source/blender/blenkernel/intern/modifier.c +++ b/source/blender/blenkernel/intern/modifier.c @@ -4972,6 +4972,7 @@ static DerivedMesh *clothModifier_applyModifier(ModifierData *md, Object *ob, if(result) { + CDDM_calc_normals(result); return result; } return derivedData; @@ -5020,6 +5021,22 @@ CustomDataMask clothModifier_requiredDataMask(ModifierData *md) return dataMask; } +static void clothModifier_copyData(ModifierData *md, ModifierData *target) +{ + ClothModifierData *clmd = (ClothModifierData*) md; + ClothModifierData *tclmd = (ClothModifierData*) target; + + if(tclmd->sim_parms) + MEM_freeN(tclmd->sim_parms); + if(tclmd->coll_parms) + MEM_freeN(tclmd->coll_parms); + + tclmd->sim_parms = MEM_dupallocN(clmd->sim_parms); + tclmd->coll_parms = MEM_dupallocN(clmd->coll_parms); + + tclmd->sim_parms->lastcachedframe = 0; +} + static int clothModifier_dependsOnTime(ModifierData *md) { @@ -5035,8 +5052,10 @@ static void clothModifier_freeData(ModifierData *md) cloth_free_modifier_extern (clmd); - MEM_freeN(clmd->sim_parms); - MEM_freeN(clmd->coll_parms); + if(clmd->sim_parms) + MEM_freeN(clmd->sim_parms); + if(clmd->coll_parms) + MEM_freeN(clmd->coll_parms); } } @@ -7033,8 +7052,7 @@ ModifierTypeInfo *modifierType_getInfo(ModifierType type) mti->dependsOnTime = clothModifier_dependsOnTime; mti->freeData = clothModifier_freeData; mti->requiredDataMask = clothModifier_requiredDataMask; - // mti->copyData = clothModifier_copyData; - // mti->deformVerts = clothModifier_deformVerts; + mti->copyData = clothModifier_copyData; mti->applyModifier = clothModifier_applyModifier; mti->updateDepgraph = clothModifier_updateDepgraph; diff --git a/source/blender/makesdna/DNA_cloth_types.h b/source/blender/makesdna/DNA_cloth_types.h index 661ad9547d5..d24ee2f0eb8 100644 --- a/source/blender/makesdna/DNA_cloth_types.h +++ b/source/blender/makesdna/DNA_cloth_types.h @@ -69,7 +69,7 @@ typedef struct SimulationSettings float eff_force_scale;/* Scaling of effector forces (see softbody_calc_forces).*/ float eff_wind_scale; /* Scaling of effector wind (see softbody_calc_forces). */ float sim_time_old; - struct LinkNode *cache; + struct LinkNode *cache; /* UNUSED atm */ float defgoal; int goalfrict; float goalspring; @@ -113,7 +113,7 @@ typedef struct Cloth unsigned int numverts; /* The number of verts == m * n. */ unsigned int numsprings; /* The count of springs. */ unsigned int numfaces; - unsigned char old_solver_type; + unsigned char old_solver_type; /* unused, only 1 solver here */ unsigned char pad2; short pad3; struct BVH *tree; /* collision tree for this cloth object */ diff --git a/source/blender/src/buttons_object.c b/source/blender/src/buttons_object.c index 0b30f0b3cba..79dc890c462 100644 --- a/source/blender/src/buttons_object.c +++ b/source/blender/src/buttons_object.c @@ -2320,7 +2320,8 @@ void do_object_panels(unsigned short event) ClothModifierData *clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth); if(clmd) { - cloth_clear_cache(ob, clmd, MAX2(1.0,G.scene->r.cfra + 1.0)); + cloth_clear_cache(ob, clmd, MAX2(1.0,G.scene->r.cfra)); + // MAX2(1.0,G.scene->r.cfra + 1.0) allqueue(REDRAWBUTSOBJECT, 0); } } @@ -5071,18 +5072,12 @@ static void object_panel_cloth(Object *ob) uiBlockBeginAlign(block); uiDefButF(block, NUM, B_CLOTH_RENEW, "StructStiff:", 10,170,150,20, &clmd->sim_parms->structural, 1.0, 10000.0, 100, 0, "Overall stiffness of structure"); uiDefButF(block, NUM, B_CLOTH_RENEW, "BendStiff:", 160,170,150,20, &clmd->sim_parms->bending, 0.0, 10000.0, 1000, 0, "Wrinkle coefficient (higher = less smaller but more big wrinkles)"); - uiDefButI(block, NUM, B_CLOTH_RENEW, "Quality:", 10,150,150,20, &clmd->sim_parms->stepsPerFrame, 1.0, 100.0, 5, 0, "Quality of the simulation (higher=better=slower)"); - uiBlockEndAlign(block); - uiBlockBeginAlign(block); + uiDefButI(block, NUM, B_CLOTH_RENEW, "Quality:", 10,150,150,20, &clmd->sim_parms->stepsPerFrame, 4.0, 100.0, 5, 0, "Quality of the simulation (higher=better=slower)"); + uiDefButF(block, NUM, B_CLOTH_RENEW, "Spring Damp:", 160,150,150,20, &clmd->sim_parms->Cdis, 0.0, 10.0, 10, 0, "Spring damping"); uiDefButF(block, NUM, B_DIFF, "Air Damp:", 10,130,150,20, &clmd->sim_parms->Cvi, 0.0, 10.0, 10, 0, "Air has normaly some thickness which slows falling things down"); - uiBlockEndAlign(block); - uiClearButLock(); - - uiBlockBeginAlign(block); uiDefBut(block, LABEL, 0, "Gravity:", 10,100,60,20, NULL, 0.0, 0, 0, 0, ""); - // uiClearButLock(); uiDefButF(block, NUM, B_CLOTH_RENEW, "X:", 70,100,80,20, &clmd->sim_parms->gravity[0], -100.0, 100.0, 10, 0, "Apply gravitation to point movement"); uiDefButF(block, NUM, B_CLOTH_RENEW, "Y:", 150,100,80,20, &clmd->sim_parms->gravity[1], -100.0, 100.0, 10, 0, "Apply gravitation to point movement"); @@ -5202,17 +5197,10 @@ static void object_panel_cloth_II(Object *ob) { uiDefButBitI(block, TOG, CLOTH_SIMSETTINGS_FLAG_CCACHE_PROTECT, REDRAWVIEW3D, "Protect Cache & Enable Cache Editing", 10,120,300,20, &clmd->sim_parms->flags, 0, 0, 0, 0, "Protect cache from automatic freeing when scene changed. This also enabled the cache beeing edited in editmode."); - if(!(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_CCACHE_PROTECT)) - { - uiDefBut(block, LABEL, 0, "Clear cache:", 10,100,90,20, NULL, 0.0, 0, 0, 0, ""); - uiDefBut(block, BUT, B_CLOTH_CLEARCACHEALL, "All", 100, 100,100,20, NULL, 0.0, 0.0, 10, 0, "Free ALL cloth cache without preroll"); - uiDefBut(block, BUT, B_CLOTH_CLEARCACHEFRAME, "From next frame", 200, 100,110,20, NULL, 0.0, 0.0, 10, 0, "Free cloth cache starting from next frame"); - uiDefBut(block, LABEL, 0, " ", 10,80,300,20, NULL, 0.0, 0, 0, 0, ""); - } - else - { - uiDefBut(block, LABEL, 0, " ", 10,100,300,40, NULL, 0.0, 0, 0, 0, ""); - } + uiDefBut(block, LABEL, 0, "Clear cache:", 10,100,90,20, NULL, 0.0, 0, 0, 0, ""); + uiDefBut(block, BUT, B_CLOTH_CLEARCACHEALL, "All", 100, 100,100,20, NULL, 0.0, 0.0, 10, 0, "Free ALL cloth cache without preroll"); + uiDefBut(block, BUT, B_CLOTH_CLEARCACHEFRAME, "From next frame", 200, 100,110,20, NULL, 0.0, 0.0, 10, 0, "Free cloth cache starting from next frame"); + uiDefBut(block, LABEL, 0, " ", 10,80,300,20, NULL, 0.0, 0, 0, 0, ""); } /* @@ -5222,8 +5210,8 @@ static void object_panel_cloth_II(Object *ob) uiDefBut(block, LABEL, 0, " ", 10,80,145,20, NULL, 0.0, 0, 0, 0, ""); */ - uiDefButBitI(block, TOG, CLOTH_COLLISIONSETTINGS_FLAG_ENABLED, REDRAWVIEW3D, "Enable collisions", 10,60,150,20, &clmd->coll_parms->flags, 0, 0, 0, 0, "Enable collisions with this object"); - if (clmd->coll_parms->flags & CLOTH_COLLISIONSETTINGS_FLAG_ENABLED) + uiDefButBitI(block, TOG, CLOTH_COLLSETTINGS_FLAG_ENABLED, REDRAWVIEW3D, "Enable collisions", 10,60,150,20, &clmd->coll_parms->flags, 0, 0, 0, 0, "Enable collisions with this object"); + if (clmd->coll_parms->flags & CLOTH_COLLSETTINGS_FLAG_ENABLED) { uiDefButF(block, NUM, B_CLOTH_RENEW, "Min Distance:", 160,60,150,20, &clmd->coll_parms->epsilon, 0.001f, 1.0, 0.01f, 0, "Minimum distance between collision objects before collision response takes in"); } From 589870100dc6734a20c99f572baeb2c401e6509f Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Fri, 25 Jan 2008 10:33:19 +0000 Subject: [PATCH 081/246] Fix: clear cache button works again even with protected cache, edited cache doesn't get saved to wrong frame anymore when moving frames forward in editmode --- source/blender/blenkernel/BKE_cloth.h | 2 ++ source/blender/blenkernel/intern/cloth.c | 14 +++++++++----- source/blender/blenkernel/intern/collision.c | 2 +- source/blender/makesdna/DNA_cloth_types.h | 2 +- source/blender/src/buttons_object.c | 5 +++++ source/blender/src/editmesh.c | 16 ++++++++++++++-- 6 files changed, 32 insertions(+), 9 deletions(-) diff --git a/source/blender/blenkernel/BKE_cloth.h b/source/blender/blenkernel/BKE_cloth.h index 4c017cfaf06..3a3d6612a23 100644 --- a/source/blender/blenkernel/BKE_cloth.h +++ b/source/blender/blenkernel/BKE_cloth.h @@ -134,6 +134,7 @@ typedef enum CLOTH_SIMSETTINGS_FLAG_TEARING = ( 1 << 4 ),// true if tearing is enabled CLOTH_SIMSETTINGS_FLAG_CCACHE_PROTECT = ( 1 << 5 ), // true if tearing is enabled CLOTH_SIMSETTINGS_FLAG_NEW = ( 1 << 6 ), // unsued, true if cloth was just enabled + CLOTH_SIMSETTINGS_FLAG_CCACHE_FFREE = (1 << 7), /* force cache freeing */ } CLOTH_SIMSETTINGS_FLAGS; /* COLLISION FLAGS */ @@ -206,6 +207,7 @@ void bvh_update_from_cloth(ClothModifierData *clmd, int moving); // needed for editmesh.c void cloth_write_cache(Object *ob, ClothModifierData *clmd, float framenr); +int cloth_read_cache(Object *ob, ClothModifierData *clmd, float framenr); // needed for button_object.c void cloth_clear_cache(Object *ob, ClothModifierData *clmd, float framenr); diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c index 70c6857f14b..e1b97362e08 100644 --- a/source/blender/blenkernel/intern/cloth.c +++ b/source/blender/blenkernel/intern/cloth.c @@ -145,9 +145,9 @@ void cloth_init ( ClothModifierData *clmd ) clmd->sim_parms->gravity [0] = 0.0; clmd->sim_parms->gravity [1] = 0.0; clmd->sim_parms->gravity [2] = -9.81; - clmd->sim_parms->structural = 100.0; - clmd->sim_parms->shear = 100.0; - clmd->sim_parms->bending = 1.0; + clmd->sim_parms->structural = 200.0; + clmd->sim_parms->shear = 200.0; + clmd->sim_parms->bending = 0.1; clmd->sim_parms->Cdis = 5.0; clmd->sim_parms->Cvi = 1.0; clmd->sim_parms->mass = 1.0f; @@ -161,6 +161,7 @@ void cloth_init ( ClothModifierData *clmd ) clmd->sim_parms->lastframe = 250; clmd->sim_parms->vgroup_mass = 0; clmd->sim_parms->lastcachedframe = 0; + clmd->sim_parms->editedframe = 0; clmd->coll_parms->self_friction = 5.0; clmd->coll_parms->friction = 10.0; @@ -485,7 +486,7 @@ DerivedMesh *CDDM_create_tearing ( ClothModifierData *clmd, DerivedMesh *dm ) int modifiers_indexInObject(Object *ob, ModifierData *md_seek); -static int cloth_read_cache(Object *ob, ClothModifierData *clmd, float framenr) +int cloth_read_cache(Object *ob, ClothModifierData *clmd, float framenr) { FILE *fp = NULL; int stack_index = -1; @@ -534,7 +535,7 @@ void cloth_clear_cache(Object *ob, ClothModifierData *clmd, float framenr) int stack_index = -1; /* clear cache if specific frame cleaning requested or cache is not protected */ - if((!(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_CCACHE_PROTECT)) || (framenr > 1.0)) + if((!(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_CCACHE_PROTECT)) || (clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_CCACHE_FFREE)) { stack_index = modifiers_indexInObject(ob, (ModifierData *)clmd); @@ -545,6 +546,9 @@ void cloth_clear_cache(Object *ob, ClothModifierData *clmd, float framenr) { cloth_read_cache(ob, clmd, framenr); } + + /* delete cache free request */ + clmd->sim_parms->flags &= ~CLOTH_SIMSETTINGS_FLAG_CCACHE_FFREE; } void cloth_write_cache(Object *ob, ClothModifierData *clmd, float framenr) { diff --git a/source/blender/blenkernel/intern/collision.c b/source/blender/blenkernel/intern/collision.c index 75201bbcea3..3d967655f70 100644 --- a/source/blender/blenkernel/intern/collision.c +++ b/source/blender/blenkernel/intern/collision.c @@ -694,7 +694,7 @@ void cloth_collision_static(ClothModifierData *clmd, CollisionModifierData *coll Normalize(collpair->normal); collpair->distance = distance; - BLI_linklist_append(&clmd->coll_parms->collision_list, collpair); + BLI_linklist_prepend(&clmd->coll_parms->collision_list, collpair); } else diff --git a/source/blender/makesdna/DNA_cloth_types.h b/source/blender/makesdna/DNA_cloth_types.h index d24ee2f0eb8..ab47d00d1b5 100644 --- a/source/blender/makesdna/DNA_cloth_types.h +++ b/source/blender/makesdna/DNA_cloth_types.h @@ -77,7 +77,7 @@ typedef struct SimulationSettings int lastframe; /* frame on which simulation stops */ int firstframe; /* frame on which simulation starts */ int lastcachedframe; - int pad3; + int editedframe; /* which frame is in buffer */ } SimulationSettings; diff --git a/source/blender/src/buttons_object.c b/source/blender/src/buttons_object.c index 79dc890c462..5ec89c6534e 100644 --- a/source/blender/src/buttons_object.c +++ b/source/blender/src/buttons_object.c @@ -2306,6 +2306,9 @@ void do_object_panels(unsigned short event) ClothModifierData *clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth); if(clmd) { + /* force freeing because user wants */ + clmd->sim_parms->flags |= CLOTH_SIMSETTINGS_FLAG_CCACHE_FFREE; + CFRA= 1; update_for_newframe_muted(); DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA); @@ -2320,6 +2323,8 @@ void do_object_panels(unsigned short event) ClothModifierData *clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth); if(clmd) { + /* force freeing because user wants */ + clmd->sim_parms->flags |= CLOTH_SIMSETTINGS_FLAG_CCACHE_FFREE; cloth_clear_cache(ob, clmd, MAX2(1.0,G.scene->r.cfra)); // MAX2(1.0,G.scene->r.cfra + 1.0) allqueue(REDRAWBUTSOBJECT, 0); diff --git a/source/blender/src/editmesh.c b/source/blender/src/editmesh.c index 7b51d50ae7b..9c00d8b71bc 100644 --- a/source/blender/src/editmesh.c +++ b/source/blender/src/editmesh.c @@ -861,6 +861,8 @@ void make_editMesh() { cloth_enabled = 1; + clmd->sim_parms->editedframe = (float) G.scene->r.cfra; + /* inverse matrix is not uptodate... */ Mat4Invert ( G.obedit->imat, G.obedit->obmat ); } @@ -1092,7 +1094,7 @@ void load_editMesh(void) /* check if we have cache for this frame */ int stack_index = modifiers_indexInObject(G.obedit, (ModifierData *)clmd); - if(BKE_ptcache_id_exist((ID *)G.obedit, (float) G.scene->r.cfra, stack_index)) + if(BKE_ptcache_id_exist((ID *)G.obedit, clmd->sim_parms->editedframe, stack_index)) { cloth_enabled = 1; @@ -1108,9 +1110,11 @@ void load_editMesh(void) if(cloth_enabled) { + VECCOPY(temp, cloth->verts[i].x); VECCOPY(cloth->verts[i].x, eve->co); Mat4MulVecfl ( G.obedit->obmat, cloth->verts[i].x ); + /* // not physical correct but gives nicer results when commented VECSUB(temp, cloth->verts[i].x, temp); @@ -1154,7 +1158,15 @@ void load_editMesh(void) /* burn changes to cache */ if(cloth_enabled) - cloth_write_cache(G.obedit, clmd, (float) G.scene->r.cfra); + { + cloth_write_cache(G.obedit, clmd, clmd->sim_parms->editedframe); + + /* in this case we have to get the data for the requested frame */ + if(clmd->sim_parms->editedframe != (float) G.scene->r.cfra) + { + cloth_read_cache(G.obedit, clmd, (float) G.scene->r.cfra); + } + } /* the edges */ a= 0; From a01a606b1fdc2f855d84f855033116cc2ff5191d Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Fri, 25 Jan 2008 16:14:54 +0000 Subject: [PATCH 082/246] Weekend commit -> New: 3rd tab for advanced users mit many things to play with. Fixed: Free modifier correctly when deactivating cloth on panel, be carefull: could eventually put weird values on the GUI due to changed DNA --- source/blender/blenkernel/BKE_cloth.h | 7 +- source/blender/blenkernel/intern/cloth.c | 90 ++++++++---- source/blender/blenkernel/intern/collision.c | 5 +- source/blender/blenkernel/intern/implicit.c | 13 +- source/blender/makesdna/DNA_cloth_types.h | 20 +-- source/blender/src/buttons_object.c | 140 ++++++++++++++++--- source/blender/src/vpaint.c | 1 - 7 files changed, 216 insertions(+), 60 deletions(-) diff --git a/source/blender/blenkernel/BKE_cloth.h b/source/blender/blenkernel/BKE_cloth.h index 3a3d6612a23..5bcd40c5905 100644 --- a/source/blender/blenkernel/BKE_cloth.h +++ b/source/blender/blenkernel/BKE_cloth.h @@ -80,7 +80,10 @@ typedef struct ClothVertex float goal; /* goal, from SB */ float impulse[3]; /* used in collision.c */ unsigned int impulse_count; /* same as above */ - float avg_spring_len; /* average length of connected springs, UNUSED ATM */ + float avg_spring_len; /* average length of connected springs, UNUSED ATM */ + float struct_stiff; + float bend_stiff; + float shear_stiff; } ClothVertex; @@ -99,6 +102,7 @@ typedef struct ClothSpring float dfdx[3][3]; float dfdv[3][3]; float f[3]; + float stiffness; /* stiffness factor from the vertex groups */ } ClothSpring; @@ -135,6 +139,7 @@ typedef enum CLOTH_SIMSETTINGS_FLAG_CCACHE_PROTECT = ( 1 << 5 ), // true if tearing is enabled CLOTH_SIMSETTINGS_FLAG_NEW = ( 1 << 6 ), // unsued, true if cloth was just enabled CLOTH_SIMSETTINGS_FLAG_CCACHE_FFREE = (1 << 7), /* force cache freeing */ + CLOTH_SIMSETTINGS_FLAG_SCALING = (1 << 8), /* is advanced scaling active? */ } CLOTH_SIMSETTINGS_FLAGS; /* COLLISION FLAGS */ diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c index e1b97362e08..8ffb7ef2d19 100644 --- a/source/blender/blenkernel/intern/cloth.c +++ b/source/blender/blenkernel/intern/cloth.c @@ -125,7 +125,7 @@ static void cloth_to_object (Object *ob, ClothModifierData *clmd, DerivedMesh * static void cloth_from_mesh ( Object *ob, ClothModifierData *clmd, DerivedMesh *dm ); static int cloth_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *dm, float framenr); int cloth_build_springs ( ClothModifierData *clmd, DerivedMesh *dm ); -static void cloth_apply_vgroup ( ClothModifierData *clmd, DerivedMesh *dm, short vgroup ); +static void cloth_apply_vgroup ( ClothModifierData *clmd, DerivedMesh *dm, short vgroup, int mode ); /****************************************************************************** @@ -162,10 +162,11 @@ void cloth_init ( ClothModifierData *clmd ) clmd->sim_parms->vgroup_mass = 0; clmd->sim_parms->lastcachedframe = 0; clmd->sim_parms->editedframe = 0; + clmd->sim_parms->autoprotect = 10; clmd->coll_parms->self_friction = 5.0; clmd->coll_parms->friction = 10.0; - clmd->coll_parms->loop_count = 1; + clmd->coll_parms->loop_count = 5; clmd->coll_parms->epsilon = 0.01f; clmd->coll_parms->flags = CLOTH_COLLSETTINGS_FLAG_ENABLED; @@ -482,8 +483,6 @@ DerivedMesh *CDDM_create_tearing ( ClothModifierData *clmd, DerivedMesh *dm ) return result; } - - int modifiers_indexInObject(Object *ob, ModifierData *md_seek); int cloth_read_cache(Object *ob, ClothModifierData *clmd, float framenr) @@ -522,10 +521,10 @@ int cloth_read_cache(Object *ob, ClothModifierData *clmd, float framenr) } fclose(fp); - - if(clmd->sim_parms->solver_type == 0) - implicit_set_positions(clmd); } + + if(clmd->sim_parms->solver_type == 0) + implicit_set_positions(clmd); return ret; } @@ -655,6 +654,14 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd,Object *ob, DerivedMesh *d { cloth_free_modifier (ob, clmd); } + + // sanity check for correctness of GUI values + if(clmd->sim_parms->max_structsim_parms->structural) + clmd->sim_parms->max_struct=clmd->sim_parms->structural; + if(clmd->sim_parms->max_bendsim_parms->bending) + clmd->sim_parms->max_struct=clmd->sim_parms->bending; + if(clmd->sim_parms->max_shearsim_parms->shear) + clmd->sim_parms->max_shear=clmd->sim_parms->shear; if ( deltaTime == 1.0f ) { @@ -693,7 +700,7 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd,Object *ob, DerivedMesh *d VECCOPY ( verts->xconst, mvert[i].co ); Mat4MulVecfl ( ob->obmat, verts->xconst ); } - + tstart(); // Call the solver. @@ -704,6 +711,10 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd,Object *ob, DerivedMesh *d // printf ( "Cloth simulation time: %f\n", ( float ) tval() ); cloth_write_cache(ob, clmd, framenr); + + // check for autoprotection + if(framenr >= clmd->sim_parms->autoprotect) + clmd->sim_parms->flags |= CLOTH_SIMSETTINGS_FLAG_CCACHE_PROTECT; } // Copy the result back to the object. @@ -897,7 +908,8 @@ static void cloth_to_object (Object *ob, ClothModifierData *clmd, DerivedMesh * * cloth_apply_vgroup - applies a vertex group as specified by type * **/ -static void cloth_apply_vgroup ( ClothModifierData *clmd, DerivedMesh *dm, short vgroup ) +/* can be optimized to do all groups in one loop */ +static void cloth_apply_vgroup ( ClothModifierData *clmd, DerivedMesh *dm, short vgroup, int mode ) { unsigned int i = 0; unsigned int j = 0; @@ -922,7 +934,7 @@ static void cloth_apply_vgroup ( ClothModifierData *clmd, DerivedMesh *dm, short for ( i = 0; i < numverts; i++, verts++ ) { // LATER ON, support also mass painting here - if ( clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL ) + if ((clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL )||(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_SCALING)) { dvert = dm->getVertData ( dm, i, CD_MDEFORMVERT ); if ( dvert ) @@ -931,25 +943,37 @@ static void cloth_apply_vgroup ( ClothModifierData *clmd, DerivedMesh *dm, short { if ( dvert->dw[j].def_nr == vgroup ) { - verts->goal = dvert->dw [j].weight; - - goalfac= 1.0f; - - /* - // Kicking goal factor to simplify things...who uses that anyway? - // ABS ( clmd->sim_parms->maxgoal - clmd->sim_parms->mingoal ); - */ - - verts->goal = ( float ) pow ( verts->goal , 4.0f ); - - if ( verts->goal >=SOFTGOALSNAP ) + if (clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL ) { - verts->flags |= CLOTH_VERT_FLAG_PINNED; + verts->goal = dvert->dw [j].weight; + goalfac= 1.0f; + + /* + // Kicking goal factor to simplify things...who uses that anyway? + // ABS ( clmd->sim_parms->maxgoal - clmd->sim_parms->mingoal ); + */ + + verts->goal = ( float ) pow ( verts->goal , 4.0f ); + if ( verts->goal >=SOFTGOALSNAP ) + verts->flags |= CLOTH_VERT_FLAG_PINNED; + + break; + } + + if (clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_SCALING ) + { + if(mode==2) + { + verts->struct_stiff = dvert->dw [j].weight; + verts->shear_stiff = dvert->dw [j].weight; + } + else if(mode==1) + { + verts->bend_stiff = dvert->dw [j].weight; + } + break; } - // TODO enable mass painting here, for the moment i let "goals" go first - - break; } } } @@ -1044,7 +1068,15 @@ static int cloth_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *d // apply / set vertex groups if ( clmd->sim_parms->vgroup_mass > 0 ) - cloth_apply_vgroup ( clmd, dm, clmd->sim_parms->vgroup_mass ); + cloth_apply_vgroup ( clmd, dm, clmd->sim_parms->vgroup_mass, 0 ); + + // apply / set vertex groups + if ( clmd->sim_parms->vgroup_bend > 0 ) + cloth_apply_vgroup ( clmd, dm, clmd->sim_parms->vgroup_bend, 1 ); + + // apply / set vertex groups + if ( clmd->sim_parms->vgroup_struct > 0 ) + cloth_apply_vgroup ( clmd, dm, clmd->sim_parms->vgroup_struct, 2 ); // init our solver if ( solvers [clmd->sim_parms->solver_type].init ) @@ -1181,6 +1213,7 @@ int cloth_build_springs ( ClothModifierData *clmd, DerivedMesh *dm ) clmd->coll_parms->avg_spring_len += spring->restlen; spring->type = CLOTH_SPRING_TYPE_STRUCTURAL; spring->flags = 0; + spring->stiffness = (cloth->verts[spring->kl].struct_stiff + cloth->verts[spring->ij].struct_stiff) / 2.0; struct_springs++; if(!i) @@ -1203,6 +1236,7 @@ int cloth_build_springs ( ClothModifierData *clmd, DerivedMesh *dm ) VECSUB ( temp, cloth->verts[spring->kl].x, cloth->verts[spring->ij].x ); spring->restlen = sqrt ( INPR ( temp, temp ) ); spring->type = CLOTH_SPRING_TYPE_SHEAR; + spring->stiffness = (cloth->verts[spring->kl].shear_stiff + cloth->verts[spring->ij].shear_stiff) / 2.0; BLI_linklist_append ( &edgelist[spring->ij], spring ); BLI_linklist_append ( &edgelist[spring->kl], spring ); @@ -1220,6 +1254,7 @@ int cloth_build_springs ( ClothModifierData *clmd, DerivedMesh *dm ) VECSUB ( temp, cloth->verts[spring->kl].x, cloth->verts[spring->ij].x ); spring->restlen = sqrt ( INPR ( temp, temp ) ); spring->type = CLOTH_SPRING_TYPE_SHEAR; + spring->stiffness = (cloth->verts[spring->kl].shear_stiff + cloth->verts[spring->ij].shear_stiff) / 2.0; BLI_linklist_append ( &edgelist[spring->ij], spring ); BLI_linklist_append ( &edgelist[spring->kl], spring ); @@ -1257,6 +1292,7 @@ int cloth_build_springs ( ClothModifierData *clmd, DerivedMesh *dm ) VECSUB ( temp, cloth->verts[index2].x, cloth->verts[tspring2->ij].x ); spring->restlen = sqrt ( INPR ( temp, temp ) ); spring->type = CLOTH_SPRING_TYPE_BENDING; + spring->stiffness = (cloth->verts[spring->kl].bend_stiff + cloth->verts[spring->ij].bend_stiff) / 2.0; BLI_edgehash_insert ( edgehash, spring->ij, index2, NULL ); bend_springs++; diff --git a/source/blender/blenkernel/intern/collision.c b/source/blender/blenkernel/intern/collision.c index 3d967655f70..1ce19e878fa 100644 --- a/source/blender/blenkernel/intern/collision.c +++ b/source/blender/blenkernel/intern/collision.c @@ -978,9 +978,6 @@ void cloth_collision_moving(ClothModifierData *clmd, ClothModifierData *coll_clm cloth_collision_moving_tris(coll_clmd, clmd, tree2, tree1); } -// CLOTH_MAX_THRESHOLD defines how much collision rounds/loops should be taken -#define CLOTH_MAX_THRESHOLD 10 - // cloth - object collisions int cloth_bvh_objcollision(ClothModifierData * clmd, float step, float dt) { @@ -1092,7 +1089,7 @@ int cloth_bvh_objcollision(ClothModifierData * clmd, float step, float dt) } rounds++; } - while(result && (CLOTH_MAX_THRESHOLD>rounds)); + while(result && (clmd->coll_parms->loop_count>rounds)); //////////////////////////////////////////////////////////// // update positions diff --git a/source/blender/blenkernel/intern/implicit.c b/source/blender/blenkernel/intern/implicit.c index 557a664b5ea..7ea48d6629b 100644 --- a/source/blender/blenkernel/intern/implicit.c +++ b/source/blender/blenkernel/intern/implicit.c @@ -1091,6 +1091,8 @@ DO_INLINE void cloth_calc_spring_force(ClothModifierData *clmd, ClothSpring *s, float damping_force[3] = {0,0,0}; float nulldfdx[3][3]={ {0,0,0}, {0,0,0}, {0,0,0}}; + float scaling = 0.0; + VECCOPY(s->f, nullf); cp_fmatrix(s->dfdx, nulldfdx); cp_fmatrix(s->dfdv, nulldfdx); @@ -1122,15 +1124,17 @@ DO_INLINE void cloth_calc_spring_force(ClothModifierData *clmd, ClothSpring *s, mul_fvector_S(dir, extent, 0.0f); } - // calculate force of structural + shear springs if(s->type != CLOTH_SPRING_TYPE_BENDING) { if(length > L) // only on elonglation { s->flags |= CLOTH_SPRING_FLAG_NEEDED; - - k = clmd->sim_parms->structural; + + k = clmd->sim_parms->structural; + + scaling = k + s->stiffness * (clmd->sim_parms->max_struct-k); + k = scaling; mul_fvector_S(stretch_force, dir, (k*(length-L))); @@ -1152,6 +1156,9 @@ DO_INLINE void cloth_calc_spring_force(ClothModifierData *clmd, ClothSpring *s, s->flags |= CLOTH_SPRING_FLAG_NEEDED; k = clmd->sim_parms->bending; + + scaling = k + s->stiffness * (clmd->sim_parms->max_bend-k); + cb = k = scaling; mul_fvector_S(bending_force, dir, fbstar(length, L, k, cb)); VECADD(s->f, s->f, bending_force); diff --git a/source/blender/makesdna/DNA_cloth_types.h b/source/blender/makesdna/DNA_cloth_types.h index ab47d00d1b5..93aa09db349 100644 --- a/source/blender/makesdna/DNA_cloth_types.h +++ b/source/blender/makesdna/DNA_cloth_types.h @@ -47,24 +47,24 @@ **/ typedef struct SimulationSettings { - short vgroup_mass; /* optional vertexgroup name for assigning weight. */ - short pad; + short vgroup_mass; /* optional vertexgroup name for assigning weight.*/ + short vgroup_struct; /* vertex group for scaling structural stiffness */ float mingoal; /* see SB */ int preroll; /* How many frames of simulation to do before we start. */ float Cdis; /* Mechanical damping of springs. */ float Cvi; /* Viscous/fluid damping. */ - int stepsPerFrame; /* Number of time steps per frame. */ - float gravity [3]; /* Gravity/external force vector. */ + int stepsPerFrame; /* Number of time steps per frame. */ + float gravity [3]; /* Gravity/external force vector. */ float ufluid [3]; /* Velocity vector of the fluid. */ - float dt; /* This is the duration of our time step, computed. */ + float dt; /* This is the duration of our time step, computed. */ float mass; /* The mass of the entire cloth. */ float structural; /* Structural spring stiffness. */ float shear; /* Shear spring stiffness. */ float bending; /* Flexion spring stiffness. */ float sim_time; int flags; /* flags, see CSIMSETT_FLAGS enum above. */ - short solver_type; /* which solver should be used? txold */ - short pad2; + short solver_type; /* which solver should be used? txold */ + short vgroup_bend; /* vertex group for scaling bending stiffness */ float maxgoal; /* see SB */ float eff_force_scale;/* Scaling of effector forces (see softbody_calc_forces).*/ float eff_wind_scale; /* Scaling of effector wind (see softbody_calc_forces). */ @@ -77,7 +77,11 @@ typedef struct SimulationSettings int lastframe; /* frame on which simulation stops */ int firstframe; /* frame on which simulation starts */ int lastcachedframe; - int editedframe; /* which frame is in buffer */ + int editedframe; /* which frame is in buffer */ + int autoprotect; /* starting from this frame, cache gets protected */ + float max_bend; /* max bending scaling value, min is "bending" */ + float max_struct; /* max structural scaling value, min is "structural" */ + float max_shear; /* max shear scaling value, UNUSED */ } SimulationSettings; diff --git a/source/blender/src/buttons_object.c b/source/blender/src/buttons_object.c index 5ec89c6534e..7b87dd2108c 100644 --- a/source/blender/src/buttons_object.c +++ b/source/blender/src/buttons_object.c @@ -2325,6 +2325,7 @@ void do_object_panels(unsigned short event) { /* force freeing because user wants */ clmd->sim_parms->flags |= CLOTH_SIMSETTINGS_FLAG_CCACHE_FFREE; + cloth_clear_cache(ob, clmd, MAX2(1.0,G.scene->r.cfra)); // MAX2(1.0,G.scene->r.cfra + 1.0) allqueue(REDRAWBUTSOBJECT, 0); @@ -5036,13 +5037,31 @@ static void object_cloth__enabletoggle(void *ob_v, void *arg2) if (!md) { md = modifier_new(eModifierType_Cloth); BLI_addhead(&ob->modifiers, md); + + allqueue(REDRAWBUTSEDIT, 0); } else { - BLI_remlink(&ob->modifiers, md); - modifier_free(md); - } + Object *ob = ob_v; + ModifierData *md = modifiers_findByType(ob, eModifierType_Cloth); + + if (!md) + return; - allqueue(REDRAWBUTSEDIT, 0); + BLI_remlink(&ob->modifiers, md); + + modifier_free(md); + + BIF_undo_push("Del modifier"); + + ob->softflag |= OB_SB_RESET; + allqueue(REDRAWBUTSEDIT, 0); + allqueue(REDRAWVIEW3D, 0); + allqueue(REDRAWIMAGE, 0); + allqueue(REDRAWOOPS, 0); + DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA); + object_handle_update(ob); + countall(); + } } @@ -5068,7 +5087,7 @@ static void object_panel_cloth(Object *ob) { int defCount; char *clvg1, *clvg2; - char clmvg [] = "Weight Paint Groups%t|"; + char clmvg [] = "Vertex Groups%t|"; val2=0; @@ -5177,22 +5196,12 @@ static void object_panel_cloth_II(Object *ob) clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth); if(clmd) - { - // char str[128]; - + { uiDefButI(block, NUM, B_DIFF, "First Frame:", 10,160,150,20, &clmd->sim_parms->firstframe, 0, MAXFRAME, 1, 0, "Frame on which the simulation starts"); uiDefButI(block, NUM, B_DIFF, "Last Frame:", 160,160,150,20, &clmd->sim_parms->lastframe, 0, MAXFRAME, 10, 0, "Frame on which the simulation stops"); uiDefBut(block, LABEL, 0, "",10,140,300,20, NULL, 0.0, 0, 0, 0, ""); - /* correct spelling if only 1 frame cacheed --> only gimmick */ - /* - if(length-clmd->sim_parms->preroll>1) - sprintf (str, "Frame 1 - %d cached. [%d in preroll, %d in total]", length-clmd->sim_parms->preroll, clmd->sim_parms->preroll, length); - else - sprintf (str, "Frame %d cached. [%d in preroll, %d in total]", length-clmd->sim_parms->preroll, clmd->sim_parms->preroll, length); - */ - if (!G.relbase_valid) { uiDefBut(block, LABEL, 0, "Cache deactivated until file is saved.", 10,120,300,20, NULL, 0.0, 0, 0, 0, ""); @@ -5209,6 +5218,7 @@ static void object_panel_cloth_II(Object *ob) } /* + TODO: implement this again in cloth! if(length>1) // B_CLOTH_CHANGEPREROLL uiDefButI(block, NUM, B_CLOTH_CHANGEPREROLL, "Preroll:", 10,80,145,20, &clmd->sim_parms->preroll, 0, length-1, 1, 0, "Simulation starts on this frame"); else @@ -5219,6 +5229,7 @@ static void object_panel_cloth_II(Object *ob) if (clmd->coll_parms->flags & CLOTH_COLLSETTINGS_FLAG_ENABLED) { uiDefButF(block, NUM, B_CLOTH_RENEW, "Min Distance:", 160,60,150,20, &clmd->coll_parms->epsilon, 0.001f, 1.0, 0.01f, 0, "Minimum distance between collision objects before collision response takes in"); + uiDefButS(block, NUM, REDRAWBUTSOBJECT, "Collision Quality:", 10,40,300,20, &clmd->coll_parms->loop_count, 1.0, 100.0, 1.0, 0, "How many collision iterations should be done. (higher = better = slower), je be changed for each frame"); } else uiDefBut(block, LABEL, 0, "",160,60,150,20, NULL, 0.0, 0, 0, 0, ""); @@ -5228,6 +5239,102 @@ static void object_panel_cloth_II(Object *ob) } +static void object_panel_cloth_III(Object *ob) +{ + uiBlock *block; + ClothModifierData *clmd = NULL; + + block= uiNewBlock(&curarea->uiblocks, "object_cloth_III", UI_EMBOSS, UI_HELV, curarea->win); + uiNewPanelTabbed("Cloth ", "Physics"); + if(uiNewPanel(curarea, block, "Cloth Advanced", "Physics", 651, 0, 318, 204)==0) return; + + uiSetButLock(object_data_is_libdata(ob), ERROR_LIBDATA_MESSAGE); + + clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth); + + if(clmd) + { + int defCount; + char *clvg1, *clvg2; + char clmvg [] = "Vertex Groups%t|None%x0|"; + char clmvg2 [] = "Vertex Groups%t|None%x0|"; + + uiDefButI(block, NUM, B_DIFF, "Autoprotect Cache From:",10,160,300,20, &clmd->sim_parms->autoprotect, 0, MAXFRAME, 1, 0, "Frame on which the simulation gets cache protection enabled automatically (To prevent accidently cleaning it)."); + + uiDefButBitI(block, TOG, CLOTH_SIMSETTINGS_FLAG_SCALING, REDRAWVIEW3D, "Enable stiffness scaling",10,130,300,20, &clmd->sim_parms->flags, 0, 0, 0, 0, "If enabled, stiffness can be scaled along a weight painted vertex group."); + + if ((clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_SCALING)&& (BLI_countlist (&ob->defbase) > 0)) + { + uiDefBut(block, LABEL, 0, "StructStiff VGroup:",10,110,150,20, NULL, 0.0, 0, 0, 0, ""); + uiDefBut(block, LABEL, 0, "BendStiff VGroup:",160,110,150,20, NULL, 0.0, 0, 0, 0, ""); + + defCount = sizeof (clmvg); + clvg1 = get_vertexgroup_menustr (ob); + clvg2 = MEM_callocN (strlen (clvg1) + 1 + defCount, "clothVgST"); + if (! clvg2) { + printf ("draw_modifier: error allocating memory for cloth vertex group menu string.\n"); + return; + } + defCount = BLI_countlist (&ob->defbase); + if (defCount == 0) + { + clmd->sim_parms->vgroup_struct = 0; + } + else + { + if(clmd->sim_parms->vgroup_struct > defCount) + clmd->sim_parms->vgroup_struct = 0; + } + + sprintf (clvg2, "%s%s", clmvg, clvg1); + + uiDefButS(block, MENU, B_CLOTH_RENEW, clvg2, 10,90,150,20, &clmd->sim_parms->vgroup_struct, 0, defCount, 0, 0, "Browses available vertex groups"); + MEM_freeN (clvg1); + MEM_freeN (clvg2); + + defCount = sizeof (clmvg); + clvg1 = get_vertexgroup_menustr (ob); + clvg2 = MEM_callocN (strlen (clvg1) + 1 + defCount, "clothVgBD"); + if (! clvg2) { + printf ("draw_modifier: error allocating memory for cloth vertex group menu string.\n"); + return; + } + defCount = BLI_countlist (&ob->defbase); + if (defCount == 0) + { + clmd->sim_parms->vgroup_bend = 0; + } + else + { + if(clmd->sim_parms->vgroup_bend > defCount) + clmd->sim_parms->vgroup_bend = 0; + } + + sprintf (clvg2, "%s%s", clmvg2, clvg1); + + uiDefButS(block, MENU, B_CLOTH_RENEW, clvg2, 160,90,150,20, &clmd->sim_parms->vgroup_bend, 0, defCount, 0, 0, "Browses available vertex groups"); + MEM_freeN (clvg1); + MEM_freeN (clvg2); + + uiDefButF(block, NUM, B_CLOTH_RENEW, "StructStiff Max:",10,70,150,20, &clmd->sim_parms->max_struct, clmd->sim_parms->structural, 1000.0, 0.01f, 0, "Maximum structural stiffness value"); + + uiDefButF(block, NUM, B_CLOTH_RENEW, "BendStiff Max:",160,70,150,20, &clmd->sim_parms->max_bend, clmd->sim_parms->bending, 1000.0, 0.01f, 0, "Maximum bending stiffness value"); + + } + else if (clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_SCALING) + { + uiDefBut(block, LABEL, 0, " ", 10,110,300,20, NULL, 0.0, 0, 0, 0, ""); + uiDefBut(block, LABEL, 0, "No vertex group for pinning available.", 10,90,300,20, NULL, 0.0, 0, 0, 0, ""); + } + + + + } + + uiBlockEndAlign(block); + +} + void object_panels() { Object *ob; @@ -5259,6 +5366,7 @@ void physics_panels() object_softbodies_solver(ob); object_panel_cloth(ob); object_panel_cloth_II(ob); + object_panel_cloth_III(ob); object_panel_fluidsim(ob); } } diff --git a/source/blender/src/vpaint.c b/source/blender/src/vpaint.c index 163b93468fe..dec15f96b8a 100644 --- a/source/blender/src/vpaint.c +++ b/source/blender/src/vpaint.c @@ -1353,7 +1353,6 @@ void weight_paint(void) if(modifiers_isClothEnabled(ob)) { ClothModifierData *clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth); clmd->sim_parms->flags |= CLOTH_SIMSETTINGS_FLAG_RESET; - printf("vpaint.c\n"); } BIF_undo_push("Weight Paint"); From a1a9e011b8d1f545a5db3144b22b48a7a4df2786 Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Fri, 25 Jan 2008 21:47:43 +0000 Subject: [PATCH 083/246] untested fixes for vgroups --- source/blender/blenkernel/intern/cloth.c | 32 +++++++++++++----------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c index 8ffb7ef2d19..b5bd1c68dda 100644 --- a/source/blender/blenkernel/intern/cloth.c +++ b/source/blender/blenkernel/intern/cloth.c @@ -945,19 +945,22 @@ static void cloth_apply_vgroup ( ClothModifierData *clmd, DerivedMesh *dm, short { if (clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL ) { - verts->goal = dvert->dw [j].weight; - goalfac= 1.0f; - - /* - // Kicking goal factor to simplify things...who uses that anyway? - // ABS ( clmd->sim_parms->maxgoal - clmd->sim_parms->mingoal ); - */ - - verts->goal = ( float ) pow ( verts->goal , 4.0f ); - if ( verts->goal >=SOFTGOALSNAP ) - verts->flags |= CLOTH_VERT_FLAG_PINNED; - - break; + if(mode==0) + { + verts->goal = dvert->dw [j].weight; + goalfac= 1.0f; + + /* + // Kicking goal factor to simplify things...who uses that anyway? + // ABS ( clmd->sim_parms->maxgoal - clmd->sim_parms->mingoal ); + */ + + verts->goal = ( float ) pow ( verts->goal , 4.0f ); + if ( verts->goal >=SOFTGOALSNAP ) + verts->flags |= CLOTH_VERT_FLAG_PINNED; + + break; + } } if (clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_SCALING ) @@ -966,12 +969,13 @@ static void cloth_apply_vgroup ( ClothModifierData *clmd, DerivedMesh *dm, short { verts->struct_stiff = dvert->dw [j].weight; verts->shear_stiff = dvert->dw [j].weight; + break; } else if(mode==1) { verts->bend_stiff = dvert->dw [j].weight; + break; } - break; } } From 9c1fa1ff4d5d5d21170d7a56c00abc6476b85dda Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Tue, 29 Jan 2008 02:24:37 +0000 Subject: [PATCH 084/246] WIP commit, many debug outputs, extensive log comes after bug is killed --- source/blender/blenkernel/BKE_cloth.h | 6 +- source/blender/blenkernel/CMakeLists.txt | 2 +- source/blender/blenkernel/intern/cloth.c | 522 +++++++++++-------- source/blender/blenkernel/intern/collision.c | 88 ++-- source/blender/blenkernel/intern/modifier.c | 3 + source/blender/src/buttons_editing.c | 2 +- source/blender/src/buttons_object.c | 39 +- source/blender/src/editmesh.c | 38 +- 8 files changed, 391 insertions(+), 309 deletions(-) diff --git a/source/blender/blenkernel/BKE_cloth.h b/source/blender/blenkernel/BKE_cloth.h index 5bcd40c5905..1a3feed0a0c 100644 --- a/source/blender/blenkernel/BKE_cloth.h +++ b/source/blender/blenkernel/BKE_cloth.h @@ -62,9 +62,7 @@ struct CollisionTree; #define CLOTH_MAX_THREAD 2 /** - * Pin and unpin frames are the frames on which the vertices stop moving. - * They will assume the position they had prior to pinFrame until unpinFrame - * is reached. + * The definition of a cloth vertex. */ typedef struct ClothVertex { @@ -87,7 +85,6 @@ typedef struct ClothVertex } ClothVertex; - /** * The definition of a spring. */ @@ -106,7 +103,6 @@ typedef struct ClothSpring } ClothSpring; - /* goal defines */ #define SOFTGOALSNAP 0.999f diff --git a/source/blender/blenkernel/CMakeLists.txt b/source/blender/blenkernel/CMakeLists.txt index 0b87f0c1d98..30f21ef83cc 100644 --- a/source/blender/blenkernel/CMakeLists.txt +++ b/source/blender/blenkernel/CMakeLists.txt @@ -34,7 +34,7 @@ SET(INC ../python ../render/extern/include ../../../intern/decimation/extern ../imbuf ../avi ../../../intern/elbeem/extern ../../../intern/opennl/extern ../../../intern/iksolver/extern ../blenloader ../quicktime - ../../../intern/bmfont + ../../../intern/bmfont ../../../extern/bullet2/src ../nodes ${SDL_INC} ${ZLIB_INC} diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c index b5bd1c68dda..0870bf2efa3 100644 --- a/source/blender/blenkernel/intern/cloth.c +++ b/source/blender/blenkernel/intern/cloth.c @@ -125,7 +125,7 @@ static void cloth_to_object (Object *ob, ClothModifierData *clmd, DerivedMesh * static void cloth_from_mesh ( Object *ob, ClothModifierData *clmd, DerivedMesh *dm ); static int cloth_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *dm, float framenr); int cloth_build_springs ( ClothModifierData *clmd, DerivedMesh *dm ); -static void cloth_apply_vgroup ( ClothModifierData *clmd, DerivedMesh *dm, short vgroup, int mode ); +static void cloth_apply_vgroup ( ClothModifierData *clmd, DerivedMesh *dm ); /****************************************************************************** @@ -162,12 +162,12 @@ void cloth_init ( ClothModifierData *clmd ) clmd->sim_parms->vgroup_mass = 0; clmd->sim_parms->lastcachedframe = 0; clmd->sim_parms->editedframe = 0; - clmd->sim_parms->autoprotect = 10; + clmd->sim_parms->autoprotect = 25; clmd->coll_parms->self_friction = 5.0; clmd->coll_parms->friction = 10.0; - clmd->coll_parms->loop_count = 5; - clmd->coll_parms->epsilon = 0.01f; + clmd->coll_parms->loop_count = 3; + clmd->coll_parms->epsilon = 0.015f; clmd->coll_parms->flags = CLOTH_COLLSETTINGS_FLAG_ENABLED; /* These defaults are copied from softbody.c's @@ -182,8 +182,6 @@ void cloth_init ( ClothModifierData *clmd ) clmd->sim_parms->defgoal = 0.0f; clmd->sim_parms->goalspring = 100.0f; clmd->sim_parms->goalfrict = 0.0f; - - clmd->sim_parms->cache = NULL; } @@ -521,17 +519,38 @@ int cloth_read_cache(Object *ob, ClothModifierData *clmd, float framenr) } fclose(fp); + + /* + // belongs to another location ?!? + if((clmd->sim_parms->solver_type == 0) && (ret!=0)) + { + implicit_set_positions(clmd); + } + */ + + if(clmd->sim_parms->lastcachedframe < framenr) + { + printf("cloth_read_cache problem: lnex - f#: %f, lastCF: %d\n", framenr, clmd->sim_parms->lastcachedframe); + } } - if(clmd->sim_parms->solver_type == 0) - implicit_set_positions(clmd); - + printf("cloth_read_cache: %f\n", framenr); + return ret; } void cloth_clear_cache(Object *ob, ClothModifierData *clmd, float framenr) { int stack_index = -1; + printf("cloth_clear_cache: %f\n", framenr); + + /* + // belongs to another location ?!? + if(framenr>0) + { + cloth_read_cache(ob, clmd, framenr); + } + */ /* clear cache if specific frame cleaning requested or cache is not protected */ if((!(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_CCACHE_PROTECT)) || (clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_CCACHE_FFREE)) @@ -541,13 +560,13 @@ void cloth_clear_cache(Object *ob, ClothModifierData *clmd, float framenr) BKE_ptcache_id_clear((ID *)ob, PTCACHE_CLEAR_AFTER, framenr, stack_index); } - if(framenr>0) - { - cloth_read_cache(ob, clmd, framenr); - } + /* update last cached frame # */ + clmd->sim_parms->lastcachedframe = framenr; /* delete cache free request */ clmd->sim_parms->flags &= ~CLOTH_SIMSETTINGS_FLAG_CCACHE_FFREE; + + } void cloth_write_cache(Object *ob, ClothModifierData *clmd, float framenr) { @@ -556,8 +575,11 @@ void cloth_write_cache(Object *ob, ClothModifierData *clmd, float framenr) unsigned int a; Cloth *cloth = clmd->clothObject; + printf("cloth_write_cache: %f\n", framenr); + if(!cloth) { + printf("cloth_write_cache: no cloth\n"); return; } @@ -566,6 +588,7 @@ void cloth_write_cache(Object *ob, ClothModifierData *clmd, float framenr) fp = BKE_ptcache_id_fopen((ID *)ob, 'w', framenr, stack_index); if(!fp) { + printf("cloth_write_cache: no fp\n"); return; } @@ -578,6 +601,8 @@ void cloth_write_cache(Object *ob, ClothModifierData *clmd, float framenr) clmd->sim_parms->lastcachedframe = MAX2(clmd->sim_parms->lastcachedframe, framenr); + printf("lcf: %d, framenr: %f\n", clmd->sim_parms->lastcachedframe, framenr); + fclose(fp); } @@ -591,7 +616,7 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd,Object *ob, DerivedMesh *d { unsigned int i; Cloth *cloth = clmd->clothObject; - unsigned int framenr = ( float ) G.scene->r.cfra; + float framenr = G.scene->r.cfra; float current_time = bsystem_time ( ob, ( float ) G.scene->r.cfra, 0.0 ); ListBase *effectors = NULL; ClothVertex *verts = NULL; @@ -604,6 +629,8 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd,Object *ob, DerivedMesh *d MFace *mface = NULL; DerivedMesh *result = NULL; + printf("clothModifier_do start\n"); + result = CDDM_copy(dm); if(!result) @@ -614,134 +641,182 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd,Object *ob, DerivedMesh *d numverts = result->getNumVerts(result); numedges = result->getNumEdges(result); numfaces = result->getNumFaces(result); - mvert = CDDM_get_verts(result); - medge = CDDM_get_edges(result); - mface = CDDM_get_faces(result); - - // only be active during a specific period: - // that's "first frame" and "last frame" on GUI - if ( current_time < clmd->sim_parms->firstframe ) - { - return result; - } - else if ( current_time > clmd->sim_parms->lastframe ) - { - int stack_index = modifiers_indexInObject(ob, (ModifierData *)clmd); - - if(BKE_ptcache_id_exist((ID *)ob, clmd->sim_parms->lastcachedframe, stack_index)) - { - if(cloth_read_cache(ob, clmd, framenr)) - { - // Copy the result back to the object. - cloth_to_object (ob, clmd, result); - } - } - return result; - } - - // unused in the moment, calculated seperately in implicit.c - clmd->sim_parms->dt = 1.0f / clmd->sim_parms->stepsPerFrame; - - clmd->sim_parms->sim_time = current_time; + mvert = dm->getVertArray(result); + medge = dm->getEdgeArray(result); + mface = dm->getFaceArray(result); /* check if cache is active / if file is already saved */ + /* if ((!G.relbase_valid) && ( deltaTime != 1.0f )) { clmd->sim_parms->flags |= CLOTH_SIMSETTINGS_FLAG_RESET; } - + */ + if(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_RESET) { cloth_free_modifier (ob, clmd); + printf("clothModifier_do CLOTH_SIMSETTINGS_FLAG_RESET\n"); } - // sanity check for correctness of GUI values - if(clmd->sim_parms->max_structsim_parms->structural) - clmd->sim_parms->max_struct=clmd->sim_parms->structural; - if(clmd->sim_parms->max_bendsim_parms->bending) - clmd->sim_parms->max_struct=clmd->sim_parms->bending; - if(clmd->sim_parms->max_shearsim_parms->shear) - clmd->sim_parms->max_shear=clmd->sim_parms->shear; - - if ( deltaTime == 1.0f ) + // unused in the moment, calculated seperately in implicit.c + clmd->sim_parms->dt = 1.0f / clmd->sim_parms->stepsPerFrame; + + if ( ( clmd->clothObject == NULL ) || (clmd->clothObject && (numverts != clmd->clothObject->numverts )) ) { - if ( ( clmd->clothObject == NULL ) || ( numverts != clmd->clothObject->numverts ) ) + /* only force free the cache if we have a different number of verts */ + if(clmd->clothObject && (numverts != clmd->clothObject->numverts )) { - cloth_clear_cache(ob, clmd, 0); - - // printf("v1: %d, v2: %d\n", numverts, clmd->clothObject->numverts); - - if ( !cloth_from_object ( ob, clmd, result, framenr ) ) - return result; - - if ( clmd->clothObject == NULL ) - return result; - - cloth = clmd->clothObject; + clmd->sim_parms->flags |= CLOTH_SIMSETTINGS_FLAG_CCACHE_FFREE; + cloth_free_modifier ( ob, clmd ); } - - clmd->clothObject->old_solver_type = clmd->sim_parms->solver_type; - - // Insure we have a clmd->clothObject, in case allocation failed. - if ( clmd->clothObject != NULL ) - { - if(!cloth_read_cache(ob, clmd, framenr)) - { - verts = cloth->verts; - - // Force any pinned verts to their constrained location. - for ( i = 0; i < clmd->clothObject->numverts; i++, verts++ ) - { - // Save the previous position. - VECCOPY ( verts->xold, verts->xconst ); - VECCOPY ( verts->txold, verts->x ); - - // Get the current position. - VECCOPY ( verts->xconst, mvert[i].co ); - Mat4MulVecfl ( ob->obmat, verts->xconst ); - } + + cloth_clear_cache(ob, clmd, 0); - tstart(); - - // Call the solver. - if ( solvers [clmd->sim_parms->solver_type].solver ) - solvers [clmd->sim_parms->solver_type].solver ( ob, framenr, clmd, effectors ); - - tend(); - // printf ( "Cloth simulation time: %f\n", ( float ) tval() ); - - cloth_write_cache(ob, clmd, framenr); - - // check for autoprotection - if(framenr >= clmd->sim_parms->autoprotect) - clmd->sim_parms->flags |= CLOTH_SIMSETTINGS_FLAG_CCACHE_PROTECT; - } - - // Copy the result back to the object. - cloth_to_object (ob, clmd, result); - } - - } - else - { - if ( clmd->clothObject != NULL ) + if ( !cloth_from_object ( ob, clmd, result, framenr ) ) + return result; + + if ( clmd->clothObject == NULL ) + return result; + + cloth = clmd->clothObject; + + if(!cloth_read_cache(ob, clmd, framenr)) { - if(cloth_read_cache(ob, clmd, framenr)) - { - cloth_to_object (ob, clmd, result); - } + /* save first frame in case we have a reseted object + and we move one frame forward. + In that case we would only start with the SECOND frame + if we don't save the current state before + TODO PROBLEM: IMHO we can't track external movement from the + first frame in this case! */ + /* + if ( deltaTime == 1.0f ) + cloth_write_cache(ob, clmd, framenr-1.0); + */ + printf("cloth_from_object NO cloth_read_cache cloth_write_cache\n"); } else { + printf("cloth_from_object cloth_read_cache\n"); + + implicit_set_positions(clmd); + } + + clmd->sim_parms->sim_time = current_time; + } + + // only be active during a specific period: + // that's "first frame" and "last frame" on GUI + /* + // TODO: enable later again after refactoring + if ( current_time < clmd->sim_parms->firstframe ) + { + return result; +} + else if ( current_time > clmd->sim_parms->lastframe ) + { + int stack_index = modifiers_indexInObject(ob, (ModifierData *)clmd); + + if(BKE_ptcache_id_exist((ID *)ob, clmd->sim_parms->lastcachedframe, stack_index)) + { + if(cloth_read_cache(ob, clmd, framenr)) + { + // Copy the result back to the object. + cloth_to_object (ob, clmd, result); +} +} + return result; +} + */ + + /* nice moving one frame forward */ + if ( deltaTime == 1.0f ) + { + clmd->sim_parms->sim_time = current_time; + + printf("clothModifier_do deltaTime=1\n"); + + if(!cloth_read_cache(ob, clmd, framenr)) + { + verts = cloth->verts; + + // Force any pinned verts to their constrained location. + for ( i = 0; i < clmd->clothObject->numverts; i++, verts++ ) + { + // Save the previous position. + VECCOPY ( verts->xold, verts->xconst ); + VECCOPY ( verts->txold, verts->x ); + + // Get the current position. + VECCOPY ( verts->xconst, mvert[i].co ); + Mat4MulVecfl ( ob->obmat, verts->xconst ); + } + + tstart(); + + // Call the solver. + if ( solvers [clmd->sim_parms->solver_type].solver ) + solvers [clmd->sim_parms->solver_type].solver ( ob, framenr, clmd, effectors ); + + tend(); + // printf ( "Cloth simulation time: %f\n", ( float ) tval() ); + + cloth_write_cache(ob, clmd, framenr); + + // check for autoprotection + if(framenr >= clmd->sim_parms->autoprotect) + { + printf("fr#: %f, auto: %d\n", framenr, clmd->sim_parms->autoprotect); + clmd->sim_parms->flags |= CLOTH_SIMSETTINGS_FLAG_CCACHE_PROTECT; + } + + printf("clothModifier_do deltaTime=1 cachewrite\n"); + } + else + { + printf("clothModifier_do deltaTime=1 cacheread\n"); + implicit_set_positions(clmd); + } + + // Copy the result back to the object. + cloth_to_object (ob, clmd, result); + } + else if(deltaTime == 0.0f) + { + printf("clothModifier_do deltaTime!=1 clmd->clothObject != NULL\n"); + if(cloth_read_cache(ob, clmd, framenr)) + { + cloth_to_object (ob, clmd, result); + implicit_set_positions(clmd); + } + else /* same cache parts are missing */ + { + /* + clmd->sim_parms->flags |= CLOTH_SIMSETTINGS_FLAG_RESET; + */ + clmd->sim_parms->flags |= CLOTH_SIMSETTINGS_FLAG_CCACHE_FFREE; cloth_clear_cache(ob, clmd, 0); - if ( !cloth_from_object ( ob, clmd, result, framenr ) ) - return result; + cloth_write_cache(ob, clmd, framenr); + } + } + else + { + printf("clothModifier_do deltaTime!=1 clmd->clothObject != NULL\n"); + if(cloth_read_cache(ob, clmd, framenr)) + { + cloth_to_object (ob, clmd, result); + implicit_set_positions(clmd); + clmd->sim_parms->sim_time = current_time; + } + else + { + /* jump to a non-existing frame makes sim reset */ + clmd->sim_parms->flags |= CLOTH_SIMSETTINGS_FLAG_RESET; } } return result; - } /* frees all */ @@ -754,59 +829,54 @@ void cloth_free_modifier ( Object *ob, ClothModifierData *clmd ) cloth = clmd->clothObject; - if ( ! ( clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_CCACHE_PROTECT ) ) - { - if ( cloth ) + + if ( cloth ) + { + // If our solver provides a free function, call it + if ( solvers [clmd->sim_parms->solver_type].free ) { - // free our frame cache, TODO: but get to first position before - cloth_clear_cache ( ob, clmd, 0 ); - - // If our solver provides a free function, call it - if ( solvers [clmd->sim_parms->solver_type].free ) - { - solvers [clmd->sim_parms->solver_type].free ( clmd ); - } - - // Free the verts. - if ( cloth->verts != NULL ) - MEM_freeN ( cloth->verts ); - - cloth->verts = NULL; - cloth->numverts = 0; - - // Free the springs. - if ( cloth->springs != NULL ) - { - LinkNode *search = cloth->springs; - while(search) - { - ClothSpring *spring = search->link; - - MEM_freeN ( spring ); - search = search->next; - } - BLI_linklist_free(cloth->springs, NULL); - - cloth->springs = NULL; - } - - cloth->springs = NULL; - cloth->numsprings = 0; - - // free BVH collision tree - if ( cloth->tree ) - bvh_free ( ( BVH * ) cloth->tree ); - - // we save our faces for collision objects - if ( cloth->mfaces ) - MEM_freeN ( cloth->mfaces ); - /* - if(clmd->clothObject->facemarks) - MEM_freeN(clmd->clothObject->facemarks); - */ - MEM_freeN ( cloth ); - clmd->clothObject = NULL; + solvers [clmd->sim_parms->solver_type].free ( clmd ); } + + // Free the verts. + if ( cloth->verts != NULL ) + MEM_freeN ( cloth->verts ); + + cloth->verts = NULL; + cloth->numverts = 0; + + // Free the springs. + if ( cloth->springs != NULL ) + { + LinkNode *search = cloth->springs; + while(search) + { + ClothSpring *spring = search->link; + + MEM_freeN ( spring ); + search = search->next; + } + BLI_linklist_free(cloth->springs, NULL); + + cloth->springs = NULL; + } + + cloth->springs = NULL; + cloth->numsprings = 0; + + // free BVH collision tree + if ( cloth->tree ) + bvh_free ( ( BVH * ) cloth->tree ); + + // we save our faces for collision objects + if ( cloth->mfaces ) + MEM_freeN ( cloth->mfaces ); + /* + if(clmd->clothObject->facemarks) + MEM_freeN(clmd->clothObject->facemarks); + */ + MEM_freeN ( cloth ); + clmd->clothObject = NULL; } clmd->sim_parms->flags &= ~CLOTH_SIMSETTINGS_FLAG_RESET; } @@ -816,6 +886,8 @@ void cloth_free_modifier_extern ( ClothModifierData *clmd ) { Cloth *cloth = NULL; + printf("cloth_free_modifier_extern\n"); + if ( !clmd ) return; @@ -823,6 +895,8 @@ void cloth_free_modifier_extern ( ClothModifierData *clmd ) if ( cloth ) { + printf("cloth_free_modifier_extern in\n"); + // If our solver provides a free function, call it if ( solvers [clmd->sim_parms->solver_type].free ) { @@ -909,7 +983,7 @@ static void cloth_to_object (Object *ob, ClothModifierData *clmd, DerivedMesh * * **/ /* can be optimized to do all groups in one loop */ -static void cloth_apply_vgroup ( ClothModifierData *clmd, DerivedMesh *dm, short vgroup, int mode ) +static void cloth_apply_vgroup ( ClothModifierData *clmd, DerivedMesh *dm ) { unsigned int i = 0; unsigned int j = 0; @@ -918,66 +992,57 @@ static void cloth_apply_vgroup ( ClothModifierData *clmd, DerivedMesh *dm, short unsigned int numverts = dm->getNumVerts ( dm ); float goalfac = 0; ClothVertex *verts = NULL; + // clmd->sim_parms->vgroup_mass clothObj = clmd->clothObject; if ( !dm ) return; - + numverts = dm->getNumVerts ( dm ); - /* vgroup is 1 based, decrement so we can match the right group. */ - --vgroup; - verts = clothObj->verts; - - for ( i = 0; i < numverts; i++, verts++ ) + + if (((clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_SCALING ) || + (clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL )) && + ((clmd->sim_parms->vgroup_mass>0) || + (clmd->sim_parms->vgroup_struct>0)|| + (clmd->sim_parms->vgroup_bend>0))) { - // LATER ON, support also mass painting here - if ((clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL )||(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_SCALING)) + for ( i = 0; i < numverts; i++, verts++ ) { dvert = dm->getVertData ( dm, i, CD_MDEFORMVERT ); if ( dvert ) { for ( j = 0; j < dvert->totweight; j++ ) { - if ( dvert->dw[j].def_nr == vgroup ) + if (( dvert->dw[j].def_nr == (clmd->sim_parms->vgroup_mass-1)) && (clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL )) { - if (clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL ) + verts->goal = dvert->dw [j].weight; + goalfac= 1.0f; + + /* + // Kicking goal factor to simplify things...who uses that anyway? + // ABS ( clmd->sim_parms->maxgoal - clmd->sim_parms->mingoal ); + */ + + verts->goal = ( float ) pow ( verts->goal , 4.0f ); + if ( verts->goal >=SOFTGOALSNAP ) + verts->flags |= CLOTH_VERT_FLAG_PINNED; + } + + if (clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_SCALING ) + { + if( dvert->dw[j].def_nr == (clmd->sim_parms->vgroup_struct-1)) { - if(mode==0) - { - verts->goal = dvert->dw [j].weight; - goalfac= 1.0f; - - /* - // Kicking goal factor to simplify things...who uses that anyway? - // ABS ( clmd->sim_parms->maxgoal - clmd->sim_parms->mingoal ); - */ - - verts->goal = ( float ) pow ( verts->goal , 4.0f ); - if ( verts->goal >=SOFTGOALSNAP ) - verts->flags |= CLOTH_VERT_FLAG_PINNED; - - break; - } + verts->struct_stiff = dvert->dw [j].weight; + verts->shear_stiff = dvert->dw [j].weight; } - if (clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_SCALING ) + if( dvert->dw[j].def_nr == (clmd->sim_parms->vgroup_bend-1)) { - if(mode==2) - { - verts->struct_stiff = dvert->dw [j].weight; - verts->shear_stiff = dvert->dw [j].weight; - break; - } - else if(mode==1) - { - verts->bend_stiff = dvert->dw [j].weight; - break; - } + verts->bend_stiff = dvert->dw [j].weight; } - } } } @@ -1010,6 +1075,8 @@ static int cloth_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *d if ( clmd->clothObject != NULL ) { cloth_free_modifier ( ob, clmd ); + + printf("cloth_free_modifier cloth_from_object\n"); } // Allocate a new cloth object. @@ -1037,14 +1104,21 @@ static int cloth_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *d clmd->clothObject->springs = NULL; clmd->clothObject->numsprings = -1; - mvert = CDDM_get_verts ( dm ); + mvert = dm->getVertArray ( dm ); verts = clmd->clothObject->verts; // set initial values for ( i = 0; i < dm->getNumVerts(dm); i++, verts++ ) { VECCOPY ( verts->x, mvert[i].co ); + + if(i<5) + printf("i: %d, verts->x[0]: %f\n", i, verts->x[0]); + Mat4MulVecfl ( ob->obmat, verts->x ); + + if(i<5) + printf("i: %d, verts->x[0]: %f\n\n", i, verts->x[0]); verts->mass = clmd->sim_parms->mass; @@ -1063,34 +1137,24 @@ static int cloth_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *d VECCOPY ( verts->impulse, tnull ); } + // apply / set vertex groups + // has to be happen before springs are build! + cloth_apply_vgroup (clmd, dm); + if ( !cloth_build_springs ( clmd, dm ) ) { cloth_free_modifier ( ob, clmd ); modifier_setError ( & ( clmd->modifier ), "Can't build springs." ); + printf("cloth_free_modifier cloth_build_springs\n"); return 0; } - - // apply / set vertex groups - if ( clmd->sim_parms->vgroup_mass > 0 ) - cloth_apply_vgroup ( clmd, dm, clmd->sim_parms->vgroup_mass, 0 ); - // apply / set vertex groups - if ( clmd->sim_parms->vgroup_bend > 0 ) - cloth_apply_vgroup ( clmd, dm, clmd->sim_parms->vgroup_bend, 1 ); - - // apply / set vertex groups - if ( clmd->sim_parms->vgroup_struct > 0 ) - cloth_apply_vgroup ( clmd, dm, clmd->sim_parms->vgroup_struct, 2 ); - // init our solver if ( solvers [clmd->sim_parms->solver_type].init ) solvers [clmd->sim_parms->solver_type].init ( ob, clmd ); clmd->clothObject->tree = bvh_build_from_cloth ( clmd, clmd->coll_parms->epsilon ); - if(!cloth_read_cache(ob, clmd, framenr)) - cloth_write_cache(ob, clmd, framenr); - return 1; } return 0; @@ -1112,6 +1176,7 @@ static void cloth_from_mesh ( Object *ob, ClothModifierData *clmd, DerivedMesh * { cloth_free_modifier ( ob, clmd ); modifier_setError ( & ( clmd->modifier ), "Out of memory on allocating clmd->clothObject->verts." ); + printf("cloth_free_modifier clmd->clothObject->verts\n"); return; } @@ -1122,6 +1187,7 @@ static void cloth_from_mesh ( Object *ob, ClothModifierData *clmd, DerivedMesh * { cloth_free_modifier ( ob, clmd ); modifier_setError ( & ( clmd->modifier ), "Out of memory on allocating clmd->clothObject->mfaces." ); + printf("cloth_free_modifier clmd->clothObject->mfaces\n"); return; } for ( i = 0; i < numfaces; i++ ) @@ -1214,6 +1280,14 @@ int cloth_build_springs ( ClothModifierData *clmd, DerivedMesh *dm ) spring->kl = medge[i].v2; VECSUB ( temp, cloth->verts[spring->kl].x, cloth->verts[spring->ij].x ); spring->restlen = sqrt ( INPR ( temp, temp ) ); + /* + if(spring->restlen > 1.0) + { + printf("i: %d, L: %f\n", i, spring->restlen); + printf("%d, x: %f, y: %f, z: %f\n", cloth->verts[spring->ij].x[0], cloth->verts[spring->ij].x[1], spring->ij, cloth->verts[spring->ij].x[2]); + printf("%d, x: %f, y: %f, z: %f\n\n",spring->kl, cloth->verts[spring->kl].x[0], cloth->verts[spring->kl].x[1], cloth->verts[spring->kl].x[2]); + } + */ clmd->coll_parms->avg_spring_len += spring->restlen; spring->type = CLOTH_SPRING_TYPE_STRUCTURAL; spring->flags = 0; diff --git a/source/blender/blenkernel/intern/collision.c b/source/blender/blenkernel/intern/collision.c index 1ce19e878fa..083ae5a2b46 100644 --- a/source/blender/blenkernel/intern/collision.c +++ b/source/blender/blenkernel/intern/collision.c @@ -991,6 +991,7 @@ int cloth_bvh_objcollision(ClothModifierData * clmd, float step, float dt) ClothVertex *verts = NULL; float tnull[3] = {0,0,0}; int ret = 0; + ClothModifierData *tclmd; if ((clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_COLLOBJ) || !(((Cloth *)clmd->clothObject)->tree)) { @@ -1025,6 +1026,10 @@ int cloth_bvh_objcollision(ClothModifierData * clmd, float step, float dt) if (!collmd) continue; + tclmd = (ClothModifierData *) modifiers_findByType (coll_ob, eModifierType_Cloth); + if(tclmd == clmd) + continue; + if (collmd->tree) { BVH *coll_bvh = collmd->tree; @@ -1035,57 +1040,50 @@ int cloth_bvh_objcollision(ClothModifierData * clmd, float step, float dt) } else printf ("cloth_bvh_objcollision: found a collision object with clothObject or collData NULL.\n"); - } - // process all collisions (calculate impulses, TODO: also repulses if distance too short) - result = 1; - for(j = 0; j < 10; j++) // 10 is just a value that ensures convergence - { - result = 0; - - // handle all collision objects - for (base = G.scene->base.first; base; base = base->next) + + // process all collisions (calculate impulses, TODO: also repulses if distance too short) + result = 1; + for(j = 0; j < 10; j++) // 10 is just a value that ensures convergence { - - coll_ob = base->object; - collmd = (CollisionModifierData *) modifiers_findByType (coll_ob, eModifierType_Collision); - if (!collmd) - continue; - - result += cloth_collision_response_static(clmd, collmd); - } - - // apply impulses in parallel - ic=0; - for(i = 0; i < numverts; i++) - { - // calculate "velocities" (just xnew = xold + v; no dt in v) - if(verts[i].impulse_count) - { - VECADDMUL(verts[i].tv, verts[i].impulse, 1.0f / verts[i].impulse_count); - VECCOPY(verts[i].impulse, tnull); - verts[i].impulse_count = 0; + result = 0; - ic++; - ret++; + if (collmd->tree) + result += cloth_collision_response_static(clmd, collmd); + + + // apply impulses in parallel + ic=0; + for(i = 0; i < numverts; i++) + { + // calculate "velocities" (just xnew = xold + v; no dt in v) + if(verts[i].impulse_count) + { + VECADDMUL(verts[i].tv, verts[i].impulse, 1.0f / verts[i].impulse_count); + VECCOPY(verts[i].impulse, tnull); + verts[i].impulse_count = 0; + + ic++; + ret++; + } } } - } - - // free collision list - if(clmd->coll_parms->collision_list) - { - LinkNode *search = clmd->coll_parms->collision_list; - while(search) - { - CollPair *coll_pair = search->link; - - MEM_freeN(coll_pair); - search = search->next; - } - BLI_linklist_free(clmd->coll_parms->collision_list,NULL); - clmd->coll_parms->collision_list = NULL; + // free collision list + if(clmd->coll_parms->collision_list) + { + LinkNode *search = clmd->coll_parms->collision_list; + while(search) + { + CollPair *coll_pair = search->link; + + MEM_freeN(coll_pair); + search = search->next; + } + BLI_linklist_free(clmd->coll_parms->collision_list,NULL); + + clmd->coll_parms->collision_list = NULL; + } } rounds++; } diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c index a10210cbf3a..475009c8fa6 100644 --- a/source/blender/blenkernel/intern/modifier.c +++ b/source/blender/blenkernel/intern/modifier.c @@ -4956,6 +4956,7 @@ static void clothModifier_initData(ModifierData *md) return; cloth_init (clmd); + printf("clothModifier_initData\n"); } static DerivedMesh *clothModifier_applyModifier(ModifierData *md, Object *ob, @@ -5050,6 +5051,8 @@ static void clothModifier_freeData(ModifierData *md) if (clmd) { + printf("clothModifier_freeData\n"); + cloth_free_modifier_extern (clmd); if(clmd->sim_parms) diff --git a/source/blender/src/buttons_editing.c b/source/blender/src/buttons_editing.c index d3a474a57a5..3ea7788f87c 100644 --- a/source/blender/src/buttons_editing.c +++ b/source/blender/src/buttons_editing.c @@ -1788,7 +1788,7 @@ static void draw_modifier(uiBlock *block, Object *ob, ModifierData *md, int *xco } else if (md->type==eModifierType_Softbody) { height = 31; } else if (md->type==eModifierType_Cloth) { - height = 26; + height = 31; } else if (md->type==eModifierType_Collision) { height = 19; } else if (md->type==eModifierType_Boolean) { diff --git a/source/blender/src/buttons_object.c b/source/blender/src/buttons_object.c index eb81c256289..4f23d60cd67 100644 --- a/source/blender/src/buttons_object.c +++ b/source/blender/src/buttons_object.c @@ -2355,10 +2355,13 @@ void do_object_panels(unsigned short event) /* force freeing because user wants */ clmd->sim_parms->flags |= CLOTH_SIMSETTINGS_FLAG_CCACHE_FFREE; + /*user wants to free all, so free whole cloth, this helps to start sim at later frame */ + clmd->sim_parms->flags |= CLOTH_SIMSETTINGS_FLAG_RESET; + CFRA= 1; update_for_newframe_muted(); DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA); - cloth_clear_cache(ob, clmd, 1); + cloth_clear_cache(ob, clmd, 0); allqueue(REDRAWBUTSOBJECT, 0); allqueue(REDRAWVIEW3D, 0); } @@ -2372,7 +2375,7 @@ void do_object_panels(unsigned short event) /* force freeing because user wants */ clmd->sim_parms->flags |= CLOTH_SIMSETTINGS_FLAG_CCACHE_FFREE; - cloth_clear_cache(ob, clmd, MAX2(1.0,G.scene->r.cfra)); + cloth_clear_cache(ob, clmd, MAX2(0.0,G.scene->r.cfra)); // MAX2(1.0,G.scene->r.cfra + 1.0) allqueue(REDRAWBUTSOBJECT, 0); } @@ -2383,14 +2386,11 @@ void do_object_panels(unsigned short event) ClothModifierData *clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth); if(clmd) { - if(clmd->sim_parms->cache) - { - CFRA= 1; - update_for_newframe_muted(); - DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA); - allqueue(REDRAWBUTSOBJECT, 0); - allqueue(REDRAWVIEW3D, 0); - } + CFRA= 1; + update_for_newframe_muted(); + DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA); + allqueue(REDRAWBUTSOBJECT, 0); + allqueue(REDRAWVIEW3D, 0); } } break; @@ -2401,6 +2401,9 @@ void do_object_panels(unsigned short event) if(clmd) { clmd->sim_parms->flags |= CLOTH_SIMSETTINGS_FLAG_RESET; + DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA); + allqueue(REDRAWBUTSOBJECT, 0); + allqueue(REDRAWVIEW3D, 0); } } break; @@ -5047,7 +5050,9 @@ static void object_cloth__enabletoggle(void *ob_v, void *arg2) md = modifier_new(eModifierType_Cloth); BLI_addhead(&ob->modifiers, md); + DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA); allqueue(REDRAWBUTSEDIT, 0); + allqueue(REDRAWVIEW3D, 0); } else { Object *ob = ob_v; @@ -5121,7 +5126,7 @@ static void object_panel_cloth(Object *ob) uiBlockBeginAlign(block); - uiDefButBitI(block, TOG, CLOTH_SIMSETTINGS_FLAG_GOAL, REDRAWVIEW3D, "Pinning of cloth", 10,70,150,20, &clmd->sim_parms->flags, 0, 0, 0, 0, "Define forces for vertices to stick to animated position"); + uiDefButBitI(block, TOG, CLOTH_SIMSETTINGS_FLAG_GOAL, B_CLOTH_RENEW, "Pinning of cloth", 10,70,150,20, &clmd->sim_parms->flags, 0, 0, 0, 0, "Define forces for vertices to stick to animated position"); if ((clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL) && (BLI_countlist (&ob->defbase) > 0)) { @@ -5207,7 +5212,7 @@ static void object_panel_cloth_II(Object *ob) if(clmd) { uiDefButI(block, NUM, B_DIFF, "First Frame:", 10,160,150,20, &clmd->sim_parms->firstframe, 0, MAXFRAME, 1, 0, "Frame on which the simulation starts"); - uiDefButI(block, NUM, B_DIFF, "Last Frame:", 160,160,150,20, &clmd->sim_parms->lastframe, 0, MAXFRAME, 10, 0, "Frame on which the simulation stops"); + uiDefButI(block, NUM, B_DIFF, "Last Frame:", 160,160,150,20, &clmd->sim_parms->lastframe, 0, MAXFRAME, 1, 0, "Frame on which the simulation stops"); uiDefBut(block, LABEL, 0, "",10,140,300,20, NULL, 0.0, 0, 0, 0, ""); @@ -5234,11 +5239,11 @@ static void object_panel_cloth_II(Object *ob) uiDefBut(block, LABEL, 0, " ", 10,80,145,20, NULL, 0.0, 0, 0, 0, ""); */ - uiDefButBitI(block, TOG, CLOTH_COLLSETTINGS_FLAG_ENABLED, REDRAWVIEW3D, "Enable collisions", 10,60,150,20, &clmd->coll_parms->flags, 0, 0, 0, 0, "Enable collisions with this object"); + uiDefButBitI(block, TOG, CLOTH_COLLSETTINGS_FLAG_ENABLED, B_CLOTH_RENEW, "Enable collisions", 10,60,150,20, &clmd->coll_parms->flags, 0, 0, 0, 0, "Enable collisions with this object"); if (clmd->coll_parms->flags & CLOTH_COLLSETTINGS_FLAG_ENABLED) { - uiDefButF(block, NUM, B_CLOTH_RENEW, "Min Distance:", 160,60,150,20, &clmd->coll_parms->epsilon, 0.001f, 1.0, 0.01f, 0, "Minimum distance between collision objects before collision response takes in"); - uiDefButS(block, NUM, REDRAWBUTSOBJECT, "Collision Quality:", 10,40,300,20, &clmd->coll_parms->loop_count, 1.0, 100.0, 1.0, 0, "How many collision iterations should be done. (higher = better = slower), je be changed for each frame"); + uiDefButF(block, NUM, REDRAWBUTSOBJECT, "Min Distance:", 160,60,150,20, &clmd->coll_parms->epsilon, 0.001f, 1.0, 0.01f, 0, "Minimum distance between collision objects before collision response takes in, can be changed for each frame"); + uiDefButS(block, NUM, REDRAWBUTSOBJECT, "Collision Quality:", 10,40,300,20, &clmd->coll_parms->loop_count, 1.0, 100.0, 1.0, 0, "How many collision iterations should be done. (higher = better = slower), can be changed for each frame"); } else uiDefBut(block, LABEL, 0, "",160,60,150,20, NULL, 0.0, 0, 0, 0, ""); @@ -5268,9 +5273,9 @@ static void object_panel_cloth_III(Object *ob) char clmvg [] = "Vertex Groups%t|None%x0|"; char clmvg2 [] = "Vertex Groups%t|None%x0|"; - uiDefButI(block, NUM, B_DIFF, "Autoprotect Cache From:",10,160,300,20, &clmd->sim_parms->autoprotect, 0, MAXFRAME, 1, 0, "Frame on which the simulation gets cache protection enabled automatically (To prevent accidently cleaning it)."); + uiDefButI(block, NUM, B_DIFF, "Autoprotect Cache From:",10,160,300,20, &clmd->sim_parms->autoprotect, 0.0, MAXFRAME + 1, 1, 0, "Frame on which the simulation gets cache protection enabled automatically (To prevent accidently cleaning it)."); - uiDefButBitI(block, TOG, CLOTH_SIMSETTINGS_FLAG_SCALING, REDRAWVIEW3D, "Enable stiffness scaling",10,130,300,20, &clmd->sim_parms->flags, 0, 0, 0, 0, "If enabled, stiffness can be scaled along a weight painted vertex group."); + uiDefButBitI(block, TOG, CLOTH_SIMSETTINGS_FLAG_SCALING, B_CLOTH_RENEW, "Enable stiffness scaling",10,130,300,20, &clmd->sim_parms->flags, 0, 0, 0, 0, "If enabled, stiffness can be scaled along a weight painted vertex group."); if ((clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_SCALING)&& (BLI_countlist (&ob->defbase) > 0)) { diff --git a/source/blender/src/editmesh.c b/source/blender/src/editmesh.c index 9c00d8b71bc..712c9ddc4a9 100644 --- a/source/blender/src/editmesh.c +++ b/source/blender/src/editmesh.c @@ -857,14 +857,16 @@ void make_editMesh() /* check if we have cache for this frame */ int stack_index = modifiers_indexInObject(G.obedit, (ModifierData *)clmd); - if(BKE_ptcache_id_exist((ID *)G.obedit, (float) G.scene->r.cfra, stack_index)) + if(BKE_ptcache_id_exist((ID *)G.obedit, G.scene->r.cfra, stack_index)) { cloth_enabled = 1; - clmd->sim_parms->editedframe = (float) G.scene->r.cfra; + clmd->sim_parms->editedframe = G.scene->r.cfra; /* inverse matrix is not uptodate... */ Mat4Invert ( G.obedit->imat, G.obedit->obmat ); + + printf("make_editmesh --> cloth_enabled\n"); } } } @@ -1014,6 +1016,8 @@ void load_editMesh(void) ClothModifierData *clmd = NULL; Cloth *cloth = NULL; float temp[3], dt = 0.0; + + printf("loadmesh\n"); #ifdef WITH_VERSE if(em->vnode) { @@ -1102,6 +1106,7 @@ void load_editMesh(void) Mat4Invert ( G.obedit->imat, G.obedit->obmat ); dt = 1.0f / clmd->sim_parms->stepsPerFrame; } + printf("loadmesh --> tot: %d, num: %d\n", G.totvert, cloth->numverts); } } @@ -1110,6 +1115,7 @@ void load_editMesh(void) if(cloth_enabled) { + printf("loadmesh --> cloth_enabled\n"); VECCOPY(temp, cloth->verts[i].x); VECCOPY(cloth->verts[i].x, eve->co); @@ -1123,6 +1129,7 @@ void load_editMesh(void) */ if(oldverts) { VECCOPY(mvert->co, oldverts[i].co); + printf("loadmesh --> cloth_enabled oldverts\n"); } i++; } @@ -1159,12 +1166,22 @@ void load_editMesh(void) /* burn changes to cache */ if(cloth_enabled) { + printf("loadmesh --> cloth_enabled cloth_write_cache\n"); cloth_write_cache(G.obedit, clmd, clmd->sim_parms->editedframe); /* in this case we have to get the data for the requested frame */ - if(clmd->sim_parms->editedframe != (float) G.scene->r.cfra) + if(clmd->sim_parms->editedframe != G.scene->r.cfra) { - cloth_read_cache(G.obedit, clmd, (float) G.scene->r.cfra); + cloth_read_cache(G.obedit, clmd, G.scene->r.cfra); + } + } + else + { + if(modifiers_isClothEnabled(G.obedit)) { + ClothModifierData *clmd = (ClothModifierData *)modifiers_findByType(G.obedit, eModifierType_Cloth); + printf("loadmesh --> CLOTH_SIMSETTINGS_FLAG_RESET\n"); + /* only reset cloth when no cache was used */ + clmd->sim_parms->flags |= CLOTH_SIMSETTINGS_FLAG_RESET; } } @@ -1426,18 +1443,7 @@ void load_editMesh(void) if(me->id.us>1) { Base *base; for(base= G.scene->base.first; base; base= base->next) { - if(base->object->data==me) { - if(modifiers_isClothEnabled(base->object)) { - ClothModifierData *clmd = (ClothModifierData *)modifiers_findByType(base->object, eModifierType_Cloth); - - /* only reset cloth when no cache was used */ - if(!cloth_enabled) - { - clmd->sim_parms->flags |= CLOTH_SIMSETTINGS_FLAG_RESET; - } - - } - + if(base->object->data==me) { base->object->softflag |= OB_SB_REDO; base->object->recalc |= OB_RECALC_DATA; } From 5da7f4df472f41997a1f424315f94d0d04b3dd30 Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Tue, 29 Jan 2008 16:32:42 +0000 Subject: [PATCH 085/246] -= Cloth cleanup =- Fixes: - Cloth event refactor to solve 2 unknown cache bugs - Cloth vgroup refactor (faster + scalable stinnes now working) - Cloth + Collision modifier on one object crash - Editmode + faceextrude on baked cloth crash - Stiffness groups would get pinned - Correct scaled stiffness calculation - Fixes freeing error under some circumstances - Deactivating reset/cache freeing when in editmode - Autobaking setting doesn't get screwed up anymore - More than 1 collision object in a scene could explode - Pinning + not protected cache didn't reset cloth - Start simulation on first frame and not on 2nd - Maximum structstiff now correct (copy-paste error) - Loading file with baked cloth calculate the spring length correctly - Loading file behaviour improved with cache - Collision object is evaluated first (untested) - Debug output activated with rt>0 Be carefull: Files with some cloth cache or something should be regenerated. --- source/blender/blenkernel/BKE_cloth.h | 3 +- source/blender/blenkernel/intern/cloth.c | 213 +++++++++++-------- source/blender/blenkernel/intern/collision.c | 10 +- source/blender/blenkernel/intern/implicit.c | 95 ++++++--- source/blender/blenkernel/intern/modifier.c | 13 +- source/blender/blenloader/intern/readfile.c | 3 + source/blender/makesdna/DNA_cloth_types.h | 2 + source/blender/src/buttons_object.c | 21 +- source/blender/src/editmesh.c | 12 +- 9 files changed, 244 insertions(+), 128 deletions(-) diff --git a/source/blender/blenkernel/BKE_cloth.h b/source/blender/blenkernel/BKE_cloth.h index 1a3feed0a0c..80d09cde342 100644 --- a/source/blender/blenkernel/BKE_cloth.h +++ b/source/blender/blenkernel/BKE_cloth.h @@ -133,9 +133,10 @@ typedef enum CLOTH_SIMSETTINGS_FLAG_GOAL = ( 1 << 3 ), // we have goals enabled CLOTH_SIMSETTINGS_FLAG_TEARING = ( 1 << 4 ),// true if tearing is enabled CLOTH_SIMSETTINGS_FLAG_CCACHE_PROTECT = ( 1 << 5 ), // true if tearing is enabled - CLOTH_SIMSETTINGS_FLAG_NEW = ( 1 << 6 ), // unsued, true if cloth was just enabled + CLOTH_SIMSETTINGS_FLAG_EDITMODE = ( 1 << 6 ), // are we in editmode? -several things disabled CLOTH_SIMSETTINGS_FLAG_CCACHE_FFREE = (1 << 7), /* force cache freeing */ CLOTH_SIMSETTINGS_FLAG_SCALING = (1 << 8), /* is advanced scaling active? */ + CLOTH_SIMSETTINGS_FLAG_LOADED = (1 << 9), /* did we just got load? */ } CLOTH_SIMSETTINGS_FLAGS; /* COLLISION FLAGS */ diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c index 0870bf2efa3..a99ac705c0b 100644 --- a/source/blender/blenkernel/intern/cloth.c +++ b/source/blender/blenkernel/intern/cloth.c @@ -153,7 +153,7 @@ void cloth_init ( ClothModifierData *clmd ) clmd->sim_parms->mass = 1.0f; clmd->sim_parms->stepsPerFrame = 5; clmd->sim_parms->sim_time = 1.0; - clmd->sim_parms->flags = CLOTH_SIMSETTINGS_FLAG_NEW; + clmd->sim_parms->flags = 0; clmd->sim_parms->solver_type = 0; clmd->sim_parms->preroll = 0; clmd->sim_parms->maxspringlen = 10; @@ -163,6 +163,7 @@ void cloth_init ( ClothModifierData *clmd ) clmd->sim_parms->lastcachedframe = 0; clmd->sim_parms->editedframe = 0; clmd->sim_parms->autoprotect = 25; + clmd->sim_parms->firstcachedframe = -1.0; clmd->coll_parms->self_friction = 5.0; clmd->coll_parms->friction = 10.0; @@ -520,20 +521,14 @@ int cloth_read_cache(Object *ob, ClothModifierData *clmd, float framenr) fclose(fp); - /* - // belongs to another location ?!? - if((clmd->sim_parms->solver_type == 0) && (ret!=0)) - { - implicit_set_positions(clmd); - } - */ - if(clmd->sim_parms->lastcachedframe < framenr) { + if(G.rt > 0) printf("cloth_read_cache problem: lnex - f#: %f, lastCF: %d\n", framenr, clmd->sim_parms->lastcachedframe); } } + if(G.rt > 0) printf("cloth_read_cache: %f\n", framenr); return ret; @@ -542,15 +537,15 @@ int cloth_read_cache(Object *ob, ClothModifierData *clmd, float framenr) void cloth_clear_cache(Object *ob, ClothModifierData *clmd, float framenr) { int stack_index = -1; - printf("cloth_clear_cache: %f\n", framenr); - /* - // belongs to another location ?!? - if(framenr>0) + // don't do anything as long as we're in editmode! + if(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_EDITMODE) { - cloth_read_cache(ob, clmd, framenr); + /* delete cache free request */ + clmd->sim_parms->flags &= ~CLOTH_SIMSETTINGS_FLAG_CCACHE_FFREE; + + return; } - */ /* clear cache if specific frame cleaning requested or cache is not protected */ if((!(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_CCACHE_PROTECT)) || (clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_CCACHE_FFREE)) @@ -558,11 +553,18 @@ void cloth_clear_cache(Object *ob, ClothModifierData *clmd, float framenr) stack_index = modifiers_indexInObject(ob, (ModifierData *)clmd); BKE_ptcache_id_clear((ID *)ob, PTCACHE_CLEAR_AFTER, framenr, stack_index); + + /* update last cached frame # */ + clmd->sim_parms->lastcachedframe = framenr; + + /* update first cached frame # */ + if((framenr < clmd->sim_parms->firstcachedframe) && (clmd->sim_parms->firstcachedframe >=0.0)) + clmd->sim_parms->firstcachedframe = -1.0; + + if(G.rt > 0) + printf("cloth_clear_cache: %f\n", framenr); } - /* update last cached frame # */ - clmd->sim_parms->lastcachedframe = framenr; - /* delete cache free request */ clmd->sim_parms->flags &= ~CLOTH_SIMSETTINGS_FLAG_CCACHE_FFREE; @@ -575,10 +577,12 @@ void cloth_write_cache(Object *ob, ClothModifierData *clmd, float framenr) unsigned int a; Cloth *cloth = clmd->clothObject; + if(G.rt > 0) printf("cloth_write_cache: %f\n", framenr); if(!cloth) { + if(G.rt > 0) printf("cloth_write_cache: no cloth\n"); return; } @@ -588,6 +592,7 @@ void cloth_write_cache(Object *ob, ClothModifierData *clmd, float framenr) fp = BKE_ptcache_id_fopen((ID *)ob, 'w', framenr, stack_index); if(!fp) { + if(G.rt > 0) printf("cloth_write_cache: no fp\n"); return; } @@ -599,8 +604,14 @@ void cloth_write_cache(Object *ob, ClothModifierData *clmd, float framenr) fwrite(&cloth->verts[a].v, sizeof(float),3,fp); } + /* update last cached frame # */ clmd->sim_parms->lastcachedframe = MAX2(clmd->sim_parms->lastcachedframe, framenr); + /* update first cached frame # */ + if((clmd->sim_parms->firstcachedframe < 0.0) || ((framenr < clmd->sim_parms->firstcachedframe) && (clmd->sim_parms->firstcachedframe > 0.0))) + clmd->sim_parms->firstcachedframe = framenr; + + if(G.rt > 0) printf("lcf: %d, framenr: %f\n", clmd->sim_parms->lastcachedframe, framenr); fclose(fp); @@ -629,8 +640,18 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd,Object *ob, DerivedMesh *d MFace *mface = NULL; DerivedMesh *result = NULL; + if(G.rt > 0) printf("clothModifier_do start\n"); + /* we're getting called two times during file load, + resulting in a not valid G.relbase on the first time (cache makes problems) + --> just return back */ + if((clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_LOADED)&& (!G.relbase_valid)) + { + clmd->sim_parms->flags &= ~CLOTH_SIMSETTINGS_FLAG_LOADED; + return dm; + } + result = CDDM_copy(dm); if(!result) @@ -656,6 +677,7 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd,Object *ob, DerivedMesh *d if(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_RESET) { cloth_free_modifier (ob, clmd); + if(G.rt > 0) printf("clothModifier_do CLOTH_SIMSETTINGS_FLAG_RESET\n"); } @@ -693,10 +715,12 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd,Object *ob, DerivedMesh *d if ( deltaTime == 1.0f ) cloth_write_cache(ob, clmd, framenr-1.0); */ + if(G.rt > 0) printf("cloth_from_object NO cloth_read_cache cloth_write_cache\n"); } else { + if(G.rt > 0) printf("cloth_from_object cloth_read_cache\n"); implicit_set_positions(clmd); @@ -707,33 +731,35 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd,Object *ob, DerivedMesh *d // only be active during a specific period: // that's "first frame" and "last frame" on GUI - /* + // TODO: enable later again after refactoring if ( current_time < clmd->sim_parms->firstframe ) { - return result; -} + return result; + } else if ( current_time > clmd->sim_parms->lastframe ) { - int stack_index = modifiers_indexInObject(ob, (ModifierData *)clmd); - - if(BKE_ptcache_id_exist((ID *)ob, clmd->sim_parms->lastcachedframe, stack_index)) - { - if(cloth_read_cache(ob, clmd, framenr)) - { + int stack_index = modifiers_indexInObject(ob, (ModifierData *)clmd); + + if(BKE_ptcache_id_exist((ID *)ob, clmd->sim_parms->lastcachedframe, stack_index)) + { + if(cloth_read_cache(ob, clmd, clmd->sim_parms->lastcachedframe)) + { + implicit_set_positions(clmd); + // Copy the result back to the object. - cloth_to_object (ob, clmd, result); -} -} - return result; -} - */ + cloth_to_object (ob, clmd, result); + } + } + return result; + } /* nice moving one frame forward */ if ( deltaTime == 1.0f ) { clmd->sim_parms->sim_time = current_time; + if(G.rt > 0) printf("clothModifier_do deltaTime=1\n"); if(!cloth_read_cache(ob, clmd, framenr)) @@ -766,14 +792,16 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd,Object *ob, DerivedMesh *d // check for autoprotection if(framenr >= clmd->sim_parms->autoprotect) { + if(G.rt > 0) printf("fr#: %f, auto: %d\n", framenr, clmd->sim_parms->autoprotect); clmd->sim_parms->flags |= CLOTH_SIMSETTINGS_FLAG_CCACHE_PROTECT; } - + if(G.rt > 0) printf("clothModifier_do deltaTime=1 cachewrite\n"); } else { + if(G.rt > 0) printf("clothModifier_do deltaTime=1 cacheread\n"); implicit_set_positions(clmd); } @@ -783,6 +811,7 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd,Object *ob, DerivedMesh *d } else if(deltaTime == 0.0f) { + if(G.rt > 0) printf("clothModifier_do deltaTime!=1 clmd->clothObject != NULL\n"); if(cloth_read_cache(ob, clmd, framenr)) { @@ -802,6 +831,7 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd,Object *ob, DerivedMesh *d } else { + if(G.rt > 0) printf("clothModifier_do deltaTime!=1 clmd->clothObject != NULL\n"); if(cloth_read_cache(ob, clmd, framenr)) { @@ -885,7 +915,7 @@ void cloth_free_modifier ( Object *ob, ClothModifierData *clmd ) void cloth_free_modifier_extern ( ClothModifierData *clmd ) { Cloth *cloth = NULL; - + if(G.rt > 0) printf("cloth_free_modifier_extern\n"); if ( !clmd ) @@ -895,6 +925,7 @@ void cloth_free_modifier_extern ( ClothModifierData *clmd ) if ( cloth ) { + if(G.rt > 0) printf("cloth_free_modifier_extern in\n"); // If our solver provides a free function, call it @@ -1070,12 +1101,13 @@ static int cloth_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *d MVert *mvert = NULL; ClothVertex *verts = NULL; float tnull[3] = {0,0,0}; + int cache_there = 0; // If we have a clothObject, free it. if ( clmd->clothObject != NULL ) { cloth_free_modifier ( ob, clmd ); - + if(G.rt > 0) printf("cloth_free_modifier cloth_from_object\n"); } @@ -1098,66 +1130,73 @@ static int cloth_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *d cloth_from_mesh ( ob, clmd, dm ); - if ( clmd->clothObject != NULL ) + if((clmd->sim_parms->firstcachedframe < 0.0) || ((clmd->sim_parms->firstcachedframe >= 0.0) && (!cloth_read_cache(ob, clmd, clmd->sim_parms->firstcachedframe)))) { - // create springs - clmd->clothObject->springs = NULL; - clmd->clothObject->numsprings = -1; - - mvert = dm->getVertArray ( dm ); - verts = clmd->clothObject->verts; + // no cache there + cache_there = 0; + if(G.rt > 0) + printf("cache_there = 0\n"); + } + else + { + // we have a cache + cache_there = 1; + if(G.rt > 0) + printf("cache_there = 1, fcf: %d\n", clmd->sim_parms->firstcachedframe); + } + + // create springs + clmd->clothObject->springs = NULL; + clmd->clothObject->numsprings = -1; + + mvert = dm->getVertArray ( dm ); + verts = clmd->clothObject->verts; - // set initial values - for ( i = 0; i < dm->getNumVerts(dm); i++, verts++ ) + // set initial values + for ( i = 0; i < dm->getNumVerts(dm); i++, verts++ ) + { + if(!cache_there) { VECCOPY ( verts->x, mvert[i].co ); - - if(i<5) - printf("i: %d, verts->x[0]: %f\n", i, verts->x[0]); - Mat4MulVecfl ( ob->obmat, verts->x ); - - if(i<5) - printf("i: %d, verts->x[0]: %f\n\n", i, verts->x[0]); - - verts->mass = clmd->sim_parms->mass; - - if ( clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL ) - verts->goal= clmd->sim_parms->defgoal; - else - verts->goal= 0.0f; - - verts->flags = 0; - VECCOPY ( verts->xold, verts->x ); - VECCOPY ( verts->xconst, verts->x ); - VECCOPY ( verts->txold, verts->x ); - VecMulf ( verts->v, 0.0f ); - - verts->impulse_count = 0; - VECCOPY ( verts->impulse, tnull ); } - // apply / set vertex groups - // has to be happen before springs are build! - cloth_apply_vgroup (clmd, dm); - - if ( !cloth_build_springs ( clmd, dm ) ) - { - cloth_free_modifier ( ob, clmd ); - modifier_setError ( & ( clmd->modifier ), "Can't build springs." ); - printf("cloth_free_modifier cloth_build_springs\n"); - return 0; - } - - // init our solver - if ( solvers [clmd->sim_parms->solver_type].init ) - solvers [clmd->sim_parms->solver_type].init ( ob, clmd ); + verts->mass = clmd->sim_parms->mass; - clmd->clothObject->tree = bvh_build_from_cloth ( clmd, clmd->coll_parms->epsilon ); - - return 1; + if ( clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL ) + verts->goal= clmd->sim_parms->defgoal; + else + verts->goal= 0.0f; + + verts->flags = 0; + VECCOPY ( verts->xold, verts->x ); + VECCOPY ( verts->xconst, verts->x ); + VECCOPY ( verts->txold, verts->x ); + VecMulf ( verts->v, 0.0f ); + + verts->impulse_count = 0; + VECCOPY ( verts->impulse, tnull ); } - return 0; + + // apply / set vertex groups + // has to be happen before springs are build! + cloth_apply_vgroup (clmd, dm); + + if ( !cloth_build_springs ( clmd, dm ) ) + { + cloth_free_modifier ( ob, clmd ); + modifier_setError ( & ( clmd->modifier ), "Can't build springs." ); + printf("cloth_free_modifier cloth_build_springs\n"); + return 0; + } + + // init our solver + if ( solvers [clmd->sim_parms->solver_type].init ) + solvers [clmd->sim_parms->solver_type].init ( ob, clmd ); + + clmd->clothObject->tree = bvh_build_from_cloth ( clmd, clmd->coll_parms->epsilon ); + + return 1; } diff --git a/source/blender/blenkernel/intern/collision.c b/source/blender/blenkernel/intern/collision.c index 083ae5a2b46..0689b8b6dd2 100644 --- a/source/blender/blenkernel/intern/collision.c +++ b/source/blender/blenkernel/intern/collision.c @@ -561,7 +561,7 @@ int cloth_collision_response_static(ClothModifierData *clmd, CollisionModifierDa // Apply the impulse and increase impulse counters. - /* + /* // calculateFrictionImpulse(tangential, collvel, collpair->normal, magtangent, clmd->coll_parms->friction*0.01, magtangent); VECSUBS(vrel_t_pre, collvel, collpair->normal, magnormal); // VecMulf(vrel_t_pre, clmd->coll_parms->friction*0.01f/INPR(vrel_t_pre,vrel_t_pre)); @@ -1097,6 +1097,14 @@ int cloth_bvh_objcollision(ClothModifierData * clmd, float step, float dt) // verts come from clmd for(i = 0; i < numverts; i++) { + if(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL) + { + if(verts [i].goal >= SOFTGOALSNAP) + { + continue; + } + } + VECADD(verts[i].tx, verts[i].txold, verts[i].tv); } //////////////////////////////////////////////////////////// diff --git a/source/blender/blenkernel/intern/implicit.c b/source/blender/blenkernel/intern/implicit.c index 7ea48d6629b..cda56f5b601 100644 --- a/source/blender/blenkernel/intern/implicit.c +++ b/source/blender/blenkernel/intern/implicit.c @@ -82,7 +82,7 @@ void itend(void) double itval() { return ((double)_itend.QuadPart - - (double)_itstart.QuadPart)/((double)ifreq.QuadPart); + (double)_itstart.QuadPart)/((double)ifreq.QuadPart); } #else #include @@ -91,9 +91,9 @@ double itval() // #include // #include -static struct timeval _itstart, _itend; -static struct timezone itz; -void itstart(void) + static struct timeval _itstart, _itend; + static struct timezone itz; + void itstart(void) { gettimeofday(&_itstart, &itz); } @@ -331,7 +331,7 @@ DO_INLINE void cp_fmatrix(float to[3][3], float from[3][3]) DO_INLINE float det_fmatrix(float m[3][3]) { return m[0][0]*m[1][1]*m[2][2] + m[1][0]*m[2][1]*m[0][2] + m[0][1]*m[1][2]*m[2][0] - -m[0][0]*m[1][2]*m[2][1] - m[0][1]*m[1][0]*m[2][2] - m[2][0]*m[1][1]*m[0][2]; + -m[0][0]*m[1][2]*m[2][1] - m[0][1]*m[1][0]*m[2][2] - m[2][0]*m[1][1]*m[0][2]; } DO_INLINE void inverse_fmatrix(float to[3][3], float from[3][3]) { @@ -719,6 +719,9 @@ int implicit_init (Object *ob, ClothModifierData *clmd) ClothSpring *spring = NULL; Implicit_Data *id = NULL; LinkNode *search = NULL; + + if(G.rt > 0) + printf("implicit_init\n"); // init memory guard // MEMORY_BASE.first = MEMORY_BASE.last = NULL; @@ -776,7 +779,7 @@ int implicit_init (Object *ob, ClothModifierData *clmd) // dFdV_start[i].c = big_I[i].c = big_zero[i].c = id->A[i+cloth->numverts].c = id->dFdV[i+cloth->numverts].c = id->dFdX[i+cloth->numverts].c = - id->P[i+cloth->numverts].c = id->Pinv[i+cloth->numverts].c = id->bigI[i+cloth->numverts].c = spring->kl; + id->P[i+cloth->numverts].c = id->Pinv[i+cloth->numverts].c = id->bigI[i+cloth->numverts].c = spring->kl; spring->matrix_index = i + cloth->numverts; @@ -1023,7 +1026,7 @@ int cg_filtered_pre(lfVector *dv, fmatrix3x3 *lA, lfVector *lB, lfVector *z, fma del_lfvector(p); del_lfvector(r); - // printf("iterations: %d\n", iterations); + printf("iterations: %d\n", iterations); return iterationsL) { - if((clmd->sim_parms->flags & CSIMSETT_FLAG_TEARING_ENABLED) - && ((((length-L)*100.0f/L) > clmd->sim_parms->maxspringlen))) // cut spring! - { - s->flags |= CSPRING_FLAG_DEACTIVATE; - return; - } - } + if((clmd->sim_parms->flags & CSIMSETT_FLAG_TEARING_ENABLED) + && ((((length-L)*100.0f/L) > clmd->sim_parms->maxspringlen))) // cut spring! + { + s->flags |= CSPRING_FLAG_DEACTIVATE; + return; + } + } */ mul_fvector_S(dir, extent, 1.0f/length); } @@ -1133,8 +1136,18 @@ DO_INLINE void cloth_calc_spring_force(ClothModifierData *clmd, ClothSpring *s, k = clmd->sim_parms->structural; - scaling = k + s->stiffness * (clmd->sim_parms->max_struct-k); + scaling = k + s->stiffness * ABS(clmd->sim_parms->max_struct-k); k = scaling; + + // printf("scaling: %f, stiffness: %f\n", k, s->stiffness); + /* + if((s->ij == 109) || (s->kl == 109)) + { + printf("length-L: %f, f: %f, len: %f, L: %f\n", length-L, (k*(length-L)), length, L); + printf("kl X-x: %f, f-y: %f, f-z: %f\n", X[s->kl][0], X[s->kl][1], X[s->kl][2]); + printf("ij X-x: %f, f-y: %f, f-z: %f\n\n", X[s->ij][0], X[s->ij][1], X[s->ij][2]); + } + */ mul_fvector_S(stretch_force, dir, (k*(length-L))); @@ -1157,7 +1170,7 @@ DO_INLINE void cloth_calc_spring_force(ClothModifierData *clmd, ClothSpring *s, k = clmd->sim_parms->bending; - scaling = k + s->stiffness * (clmd->sim_parms->max_bend-k); + scaling = k + s->stiffness * ABS(clmd->sim_parms->max_bend-k); cb = k = scaling; mul_fvector_S(bending_force, dir, fbstar(length, L, k, cb)); @@ -1166,6 +1179,12 @@ DO_INLINE void cloth_calc_spring_force(ClothModifierData *clmd, ClothSpring *s, dfdx_spring_type2(s->dfdx, dir,length,L,k, cb); } } + /* + if((s->ij == 109) || (s->kl == 109)) + { + printf("type: %d, f-x: %f, f-y: %f, f-z: %f\n", s->type, s->f[0], s->f[1], s->f[2]); +} + */ } DO_INLINE void cloth_apply_spring_force(ClothModifierData *clmd, ClothSpring *s, lfVector *lF, lfVector *X, lfVector *V, fmatrix3x3 *dFdV, fmatrix3x3 *dFdX) @@ -1258,7 +1277,7 @@ void cloth_calc_force(ClothModifierData *clmd, lfVector *lF, lfVector *lX, lfVec init_lfvector(lF, gravity, numverts); submul_lfvectorS(lF, lV, spring_air, numverts); - + /* do goal stuff */ if(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL) { @@ -1275,22 +1294,24 @@ void cloth_calc_force(ClothModifierData *clmd, lfVector *lF, lfVector *lX, lfVec ks = 1.0f/(1.0f- verts [i].goal*clmd->sim_parms->goalspring)-1.0f ; VECADDS(lF[i], lF[i], auxvect, -ks); - // calulate damping forces generated by goals + // calulate damping forces generated by goals + VECSUB(velgoal,verts[i].xold, verts[i].xconst); kd = clmd->sim_parms->goalfrict * 0.01f; // friction force scale taken from SB VECSUBADDSS(lF[i], velgoal, kd, lV[i], kd); + } } } - + /* handle external forces like wind */ if(effectors) { float speed[3] = {0.0f, 0.0f,0.0f}; float force[3]= {0.0f, 0.0f, 0.0f}; - #pragma omp parallel for private (i) shared(lF) +#pragma omp parallel for private (i) shared(lF) for(i = 0; i < cloth->numverts; i++) { float vertexnormal[3]={0,0,0}; @@ -1308,7 +1329,7 @@ void cloth_calc_force(ClothModifierData *clmd, lfVector *lF, lfVector *lX, lfVec VECADDS(lF[i], lF[i], wind_normalized, -calculateVertexWindForce(speed, vertexnormal)); } } - + // calculate spring forces search = cloth->springs; while(search) @@ -1329,6 +1350,7 @@ void cloth_calc_force(ClothModifierData *clmd, lfVector *lF, lfVector *lX, lfVec cloth_apply_spring_force(clmd, search->link, lF, lX, lV, dFdV, dFdX); search = search->next; } + // printf("\n"); } void simulate_implicit_euler(lfVector *Vnew, lfVector *lX, lfVector *lV, lfVector *lF, fmatrix3x3 *dFdV, fmatrix3x3 *dFdX, float dt, fmatrix3x3 *A, lfVector *B, lfVector *dV, fmatrix3x3 *S, lfVector *z, lfVector *olddV, fmatrix3x3 *P, fmatrix3x3 *Pinv) @@ -1391,11 +1413,23 @@ int implicit_solver (Object *ob, float frame, ClothModifierData *clmd, ListBase effectors= pdInitEffectors(ob,NULL); // calculate - cloth_calc_force(clmd, id->F, id->X, id->V, id->dFdV, id->dFdX, effectors, step ); + cloth_calc_force(clmd, id->F, id->X, id->V, id->dFdV, id->dFdX, effectors, step ); + + // printf("F -> x: %f, y: %f; z: %f\n\n", id->F[109][0], id->F[109][1], id->F[109][2]); + simulate_implicit_euler(id->Vnew, id->X, id->V, id->F, id->dFdV, id->dFdX, dt, id->A, id->B, id->dV, id->S, id->z, id->olddV, id->P, id->Pinv); add_lfvector_lfvectorS(id->Xnew, id->X, id->Vnew, dt, numverts); + /* + printf("dt: %f\n", dt); + printf("Xnew -> x: %f, y: %f; z: %f\n", id->Xnew[109][0], id->Xnew[109][1], id->Xnew[109][2]); + printf("X -> x: %f, y: %f; z: %f\n", id->X[109][0], id->X[109][1], id->X[109][2]); + printf("Vnew -> x: %f, y: %f; z: %f\n\n", id->Vnew[109][0], id->Vnew[109][1], id->Vnew[109][2]); + */ + + // clmd->coll_parms->flags &= ~CLOTH_COLLSETTINGS_FLAG_ENABLED; + if(clmd->coll_parms->flags & CLOTH_COLLSETTINGS_FLAG_ENABLED) { // collisions @@ -1404,7 +1438,8 @@ int implicit_solver (Object *ob, float frame, ClothModifierData *clmd, ListBase // update verts to current positions for(i = 0; i < numverts; i++) { - if(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL) /* do goal stuff */ + + if(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL) { if(verts [i].goal >= SOFTGOALSNAP) { @@ -1431,6 +1466,16 @@ int implicit_solver (Object *ob, float frame, ClothModifierData *clmd, ListBase { if(result) { + + if(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL) + { + if(verts [i].goal >= SOFTGOALSNAP) + { + continue; + } + } + + // VECADD(verts[i].tx, verts[i].txold, verts[i].tv); VECCOPY(verts[i].txold, verts[i].tx); @@ -1515,5 +1560,7 @@ void implicit_set_positions (ClothModifierData *clmd) { VECCOPY(id->X[i], verts[i].x); VECCOPY(id->V[i], verts[i].v); - } + } + if(G.rt > 0) + printf("implicit_set_positions\n"); } diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c index 475009c8fa6..7f378f136b6 100644 --- a/source/blender/blenkernel/intern/modifier.c +++ b/source/blender/blenkernel/intern/modifier.c @@ -4987,7 +4987,6 @@ static void clothModifier_updateDepgraph( Base *base; - /* TODO: this belongs to collision modifier */ if(clmd) { for(base = G.scene->base.first; base; base= base->next) @@ -4995,14 +4994,11 @@ static void clothModifier_updateDepgraph( Object *ob1= base->object; if(ob1 != ob) { - ClothModifierData *coll_clmd = (ClothModifierData *)modifiers_findByType(ob1, eModifierType_Cloth); + CollisionModifierData *coll_clmd = (CollisionModifierData *)modifiers_findByType(ob1, eModifierType_Collision); if(coll_clmd) - { - if (coll_clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_COLLOBJ) - { - DagNode *curNode = dag_get_node(forest, ob1); - dag_add_relation(forest, curNode, obNode, DAG_RL_DATA_DATA|DAG_RL_OB_DATA); - } + { + DagNode *curNode = dag_get_node(forest, ob1); + dag_add_relation(forest, curNode, obNode, DAG_RL_DATA_DATA|DAG_RL_OB_DATA); } } } @@ -5220,6 +5216,7 @@ static void collisionModifier_deformVerts( dm->release(dm); } + /* Boolean */ static void booleanModifier_copyData(ModifierData *md, ModifierData *target) diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index a9d2e7d05a1..4feb8c00659 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -3015,6 +3015,9 @@ static void direct_link_modifiers(FileData *fd, ListBase *lb) clmd->sim_parms= newdataadr(fd, clmd->sim_parms); clmd->coll_parms= newdataadr(fd, clmd->coll_parms); + clmd->sim_parms->flags |= CLOTH_SIMSETTINGS_FLAG_LOADED; + clmd->sim_parms->flags &= ~CLOTH_SIMSETTINGS_FLAG_EDITMODE; + } else if (md->type==eModifierType_Collision) { diff --git a/source/blender/makesdna/DNA_cloth_types.h b/source/blender/makesdna/DNA_cloth_types.h index 93aa09db349..7d2ec9b96b4 100644 --- a/source/blender/makesdna/DNA_cloth_types.h +++ b/source/blender/makesdna/DNA_cloth_types.h @@ -82,6 +82,8 @@ typedef struct SimulationSettings float max_bend; /* max bending scaling value, min is "bending" */ float max_struct; /* max structural scaling value, min is "structural" */ float max_shear; /* max shear scaling value, UNUSED */ + int firstcachedframe; + int pad; } SimulationSettings; diff --git a/source/blender/src/buttons_object.c b/source/blender/src/buttons_object.c index 4f23d60cd67..e6046203c4f 100644 --- a/source/blender/src/buttons_object.c +++ b/source/blender/src/buttons_object.c @@ -2352,6 +2352,10 @@ void do_object_panels(unsigned short event) ClothModifierData *clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth); if(clmd) { + // do nothing in editmode + if(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_EDITMODE) + break; + /* force freeing because user wants */ clmd->sim_parms->flags |= CLOTH_SIMSETTINGS_FLAG_CCACHE_FFREE; @@ -2372,6 +2376,10 @@ void do_object_panels(unsigned short event) ClothModifierData *clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth); if(clmd) { + // do nothing in editmode + if(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_EDITMODE) + break; + /* force freeing because user wants */ clmd->sim_parms->flags |= CLOTH_SIMSETTINGS_FLAG_CCACHE_FFREE; @@ -2386,6 +2394,10 @@ void do_object_panels(unsigned short event) ClothModifierData *clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth); if(clmd) { + // do nothing in editmode + if(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_EDITMODE) + break; + CFRA= 1; update_for_newframe_muted(); DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA); @@ -5211,8 +5223,8 @@ static void object_panel_cloth_II(Object *ob) if(clmd) { - uiDefButI(block, NUM, B_DIFF, "First Frame:", 10,160,150,20, &clmd->sim_parms->firstframe, 0, MAXFRAME, 1, 0, "Frame on which the simulation starts"); - uiDefButI(block, NUM, B_DIFF, "Last Frame:", 160,160,150,20, &clmd->sim_parms->lastframe, 0, MAXFRAME, 1, 0, "Frame on which the simulation stops"); + uiDefButI(block, NUM, B_CLOTH_RENEW, "First Frame:",10,160,150,20, &clmd->sim_parms->firstframe, 0, MAXFRAME, 1, 0, "Frame on which the simulation starts"); + uiDefButI(block, NUM, B_CLOTH_RENEW, "Last Frame:",160,160,150,20, &clmd->sim_parms->lastframe, 0, MAXFRAME, 1, 0, "Frame on which the simulation stops"); uiDefBut(block, LABEL, 0, "",10,140,300,20, NULL, 0.0, 0, 0, 0, ""); @@ -5244,6 +5256,7 @@ static void object_panel_cloth_II(Object *ob) { uiDefButF(block, NUM, REDRAWBUTSOBJECT, "Min Distance:", 160,60,150,20, &clmd->coll_parms->epsilon, 0.001f, 1.0, 0.01f, 0, "Minimum distance between collision objects before collision response takes in, can be changed for each frame"); uiDefButS(block, NUM, REDRAWBUTSOBJECT, "Collision Quality:", 10,40,300,20, &clmd->coll_parms->loop_count, 1.0, 100.0, 1.0, 0, "How many collision iterations should be done. (higher = better = slower), can be changed for each frame"); + uiDefButS(block, NUM, REDRAWBUTSOBJECT, "Friction:", 10,40,300,20, &clmd->coll_parms->friction, 1.0, 100.0, 1.0, 0, "Friction force if a collision happened"); } else uiDefBut(block, LABEL, 0, "",160,60,150,20, NULL, 0.0, 0, 0, 0, ""); @@ -5330,9 +5343,9 @@ static void object_panel_cloth_III(Object *ob) MEM_freeN (clvg1); MEM_freeN (clvg2); - uiDefButF(block, NUM, B_CLOTH_RENEW, "StructStiff Max:",10,70,150,20, &clmd->sim_parms->max_struct, clmd->sim_parms->structural, 1000.0, 0.01f, 0, "Maximum structural stiffness value"); + uiDefButF(block, NUM, B_CLOTH_RENEW, "StructStiff Max:",10,70,150,20, &clmd->sim_parms->max_struct, clmd->sim_parms->structural, 10000.0, 0.01f, 0, "Maximum structural stiffness value"); - uiDefButF(block, NUM, B_CLOTH_RENEW, "BendStiff Max:",160,70,150,20, &clmd->sim_parms->max_bend, clmd->sim_parms->bending, 1000.0, 0.01f, 0, "Maximum bending stiffness value"); + uiDefButF(block, NUM, B_CLOTH_RENEW, "BendStiff Max:",160,70,150,20, &clmd->sim_parms->max_bend, clmd->sim_parms->bending, 10000.0, 0.01f, 0, "Maximum bending stiffness value"); } else if (clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_SCALING) diff --git a/source/blender/src/editmesh.c b/source/blender/src/editmesh.c index 712c9ddc4a9..94ac17ebd6c 100644 --- a/source/blender/src/editmesh.c +++ b/source/blender/src/editmesh.c @@ -862,10 +862,11 @@ void make_editMesh() cloth_enabled = 1; clmd->sim_parms->editedframe = G.scene->r.cfra; + clmd->sim_parms->flags |= CLOTH_SIMSETTINGS_FLAG_EDITMODE; /* inverse matrix is not uptodate... */ Mat4Invert ( G.obedit->imat, G.obedit->obmat ); - + if(G.rt > 0) printf("make_editmesh --> cloth_enabled\n"); } } @@ -1017,8 +1018,6 @@ void load_editMesh(void) Cloth *cloth = NULL; float temp[3], dt = 0.0; - printf("loadmesh\n"); - #ifdef WITH_VERSE if(em->vnode) { struct VNode *vnode = (VNode*)em->vnode; @@ -1106,6 +1105,7 @@ void load_editMesh(void) Mat4Invert ( G.obedit->imat, G.obedit->obmat ); dt = 1.0f / clmd->sim_parms->stepsPerFrame; } + if(G.rt > 0) printf("loadmesh --> tot: %d, num: %d\n", G.totvert, cloth->numverts); } } @@ -1115,6 +1115,7 @@ void load_editMesh(void) if(cloth_enabled) { + if(G.rt > 0) printf("loadmesh --> cloth_enabled\n"); VECCOPY(temp, cloth->verts[i].x); @@ -1129,6 +1130,7 @@ void load_editMesh(void) */ if(oldverts) { VECCOPY(mvert->co, oldverts[i].co); + if(G.rt > 0) printf("loadmesh --> cloth_enabled oldverts\n"); } i++; @@ -1166,6 +1168,7 @@ void load_editMesh(void) /* burn changes to cache */ if(cloth_enabled) { + if(G.rt > 0) printf("loadmesh --> cloth_enabled cloth_write_cache\n"); cloth_write_cache(G.obedit, clmd, clmd->sim_parms->editedframe); @@ -1174,14 +1177,17 @@ void load_editMesh(void) { cloth_read_cache(G.obedit, clmd, G.scene->r.cfra); } + clmd->sim_parms->flags &= ~CLOTH_SIMSETTINGS_FLAG_EDITMODE; } else { if(modifiers_isClothEnabled(G.obedit)) { ClothModifierData *clmd = (ClothModifierData *)modifiers_findByType(G.obedit, eModifierType_Cloth); + if(G.rt > 0) printf("loadmesh --> CLOTH_SIMSETTINGS_FLAG_RESET\n"); /* only reset cloth when no cache was used */ clmd->sim_parms->flags |= CLOTH_SIMSETTINGS_FLAG_RESET; + clmd->sim_parms->flags &= ~CLOTH_SIMSETTINGS_FLAG_EDITMODE; } } From 3a36304bd908f15a5a5605e6939698e73b41e8b7 Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Wed, 7 May 2008 20:06:28 +0000 Subject: [PATCH 086/246] Resolved other bad files in branch, had to kick old bullet, will have to copy from trunk --- extern/bullet2/CMakeLists.txt | 46 - extern/bullet2/Makefile | 64 - .../bullet2/make/msvc_7_0/Bullet_vc7.vcproj | 921 ------------ extern/bullet2/readme.txt | 12 - extern/bullet2/src/Bullet-C-Api.h | 37 - .../BroadphaseCollision/btAxisSweep3.cpp | 38 - .../BroadphaseCollision/btAxisSweep3.h | 880 ------------ .../btBroadphaseInterface.h | 46 - .../BroadphaseCollision/btBroadphaseProxy.cpp | 17 - .../BroadphaseCollision/btBroadphaseProxy.h | 232 --- .../btCollisionAlgorithm.cpp | 23 - .../btCollisionAlgorithm.h | 77 - .../BroadphaseCollision/btDispatcher.cpp | 22 - .../BroadphaseCollision/btDispatcher.h | 99 -- .../btMultiSapBroadphase.cpp | 204 --- .../btMultiSapBroadphase.h | 119 -- .../btOverlappingPairCache.cpp | 474 ------ .../btOverlappingPairCache.h | 323 ----- .../btOverlappingPairCallback.h | 37 - .../btSimpleBroadphase.cpp | 312 ---- .../BroadphaseCollision/btSimpleBroadphase.h | 147 -- .../src/BulletCollision/CMakeLists.txt | 68 - .../SphereTriangleDetector.cpp | 200 --- .../SphereTriangleDetector.h | 49 - .../btCollisionConfiguration.h | 47 - .../CollisionDispatch/btCollisionCreateFunc.h | 46 - .../btCollisionDispatcher.cpp | 287 ---- .../CollisionDispatch/btCollisionDispatcher.h | 145 -- .../CollisionDispatch/btCollisionObject.cpp | 62 - .../CollisionDispatch/btCollisionObject.h | 349 ----- .../CollisionDispatch/btCollisionWorld.cpp | 370 ----- .../CollisionDispatch/btCollisionWorld.h | 259 ---- .../btCompoundCollisionAlgorithm.cpp | 142 -- .../btCompoundCollisionAlgorithm.h | 67 - .../btConvexConcaveCollisionAlgorithm.cpp | 314 ---- .../btConvexConcaveCollisionAlgorithm.h | 113 -- .../btConvexConvexAlgorithm.cpp | 249 ---- .../btConvexConvexAlgorithm.h | 77 - .../btDefaultCollisionConfiguration.cpp | 237 --- .../btDefaultCollisionConfiguration.h | 87 -- .../btEmptyCollisionAlgorithm.cpp | 34 - .../btEmptyCollisionAlgorithm.h | 50 - .../CollisionDispatch/btManifoldResult.cpp | 114 -- .../CollisionDispatch/btManifoldResult.h | 102 -- .../btSimulationIslandManager.cpp | 359 ----- .../btSimulationIslandManager.h | 69 - .../btSphereBoxCollisionAlgorithm.cpp | 260 ---- .../btSphereBoxCollisionAlgorithm.h | 67 - .../btSphereSphereCollisionAlgorithm.cpp | 93 -- .../btSphereSphereCollisionAlgorithm.h | 59 - .../btSphereTriangleCollisionAlgorithm.cpp | 82 -- .../btSphereTriangleCollisionAlgorithm.h | 62 - .../CollisionDispatch/btUnionFind.cpp | 84 -- .../CollisionDispatch/btUnionFind.h | 124 -- .../CollisionShapes/btBoxShape.cpp | 54 - .../CollisionShapes/btBoxShape.h | 323 ----- .../btBvhTriangleMeshShape.cpp | 200 --- .../CollisionShapes/btBvhTriangleMeshShape.h | 90 -- .../CollisionShapes/btCapsuleShape.cpp | 146 -- .../CollisionShapes/btCapsuleShape.h | 60 - .../CollisionShapes/btCollisionMargin.h | 26 - .../CollisionShapes/btCollisionShape.cpp | 85 -- .../CollisionShapes/btCollisionShape.h | 94 -- .../CollisionShapes/btCompoundShape.cpp | 107 -- .../CollisionShapes/btCompoundShape.h | 136 -- .../CollisionShapes/btConcaveShape.cpp | 28 - .../CollisionShapes/btConcaveShape.h | 50 - .../CollisionShapes/btConeShape.cpp | 133 -- .../CollisionShapes/btConeShape.h | 103 -- .../CollisionShapes/btConvexHullShape.cpp | 179 --- .../CollisionShapes/btConvexHullShape.h | 77 - .../CollisionShapes/btConvexInternalShape.cpp | 78 - .../CollisionShapes/btConvexInternalShape.h | 99 -- .../CollisionShapes/btConvexShape.cpp | 18 - .../CollisionShapes/btConvexShape.h | 77 - .../btConvexTriangleMeshShape.cpp | 205 --- .../btConvexTriangleMeshShape.h | 55 - .../CollisionShapes/btCylinderShape.cpp | 206 --- .../CollisionShapes/btCylinderShape.h | 138 -- .../CollisionShapes/btEmptyShape.cpp | 49 - .../CollisionShapes/btEmptyShape.h | 70 - .../btHeightfieldTerrainShape.cpp | 339 ----- .../btHeightfieldTerrainShape.h | 88 -- .../CollisionShapes/btMinkowskiSumShape.cpp | 57 - .../CollisionShapes/btMinkowskiSumShape.h | 62 - .../CollisionShapes/btMultiSphereShape.cpp | 148 -- .../CollisionShapes/btMultiSphereShape.h | 74 - .../CollisionShapes/btOptimizedBvh.cpp | 1181 --------------- .../CollisionShapes/btOptimizedBvh.h | 393 ----- .../btPolyhedralConvexShape.cpp | 148 -- .../CollisionShapes/btPolyhedralConvexShape.h | 93 -- .../CollisionShapes/btSphereShape.cpp | 77 - .../CollisionShapes/btSphereShape.h | 65 - .../CollisionShapes/btStaticPlaneShape.cpp | 105 -- .../CollisionShapes/btStaticPlaneShape.h | 61 - .../btStridingMeshInterface.cpp | 124 -- .../CollisionShapes/btStridingMeshInterface.h | 89 -- .../CollisionShapes/btTetrahedronShape.cpp | 195 --- .../CollisionShapes/btTetrahedronShape.h | 75 - .../CollisionShapes/btTriangleBuffer.cpp | 42 - .../CollisionShapes/btTriangleBuffer.h | 61 - .../CollisionShapes/btTriangleCallback.cpp | 28 - .../CollisionShapes/btTriangleCallback.h | 40 - .../btTriangleIndexVertexArray.cpp | 78 - .../btTriangleIndexVertexArray.h | 105 -- .../CollisionShapes/btTriangleMesh.cpp | 60 - .../CollisionShapes/btTriangleMesh.h | 75 - .../CollisionShapes/btTriangleMeshShape.cpp | 202 --- .../CollisionShapes/btTriangleMeshShape.h | 80 -- .../CollisionShapes/btTriangleShape.h | 179 --- .../CollisionShapes/btUniformScalingShape.cpp | 114 -- .../CollisionShapes/btUniformScalingShape.h | 86 -- extern/bullet2/src/BulletCollision/Doxyfile | 746 ---------- .../btContinuousConvexCollision.cpp | 210 --- .../btContinuousConvexCollision.h | 52 - .../NarrowPhaseCollision/btConvexCast.cpp | 20 - .../NarrowPhaseCollision/btConvexCast.h | 71 - .../btConvexPenetrationDepthSolver.h | 43 - .../btDiscreteCollisionDetectorInterface.h | 88 -- .../NarrowPhaseCollision/btGjkConvexCast.cpp | 174 --- .../NarrowPhaseCollision/btGjkConvexCast.h | 50 - .../NarrowPhaseCollision/btGjkEpa.cpp | 628 -------- .../NarrowPhaseCollision/btGjkEpa.h | 53 - .../btGjkEpaPenetrationDepthSolver.cpp | 50 - .../btGjkEpaPenetrationDepthSolver.h | 39 - .../btGjkPairDetector.cpp | 299 ---- .../NarrowPhaseCollision/btGjkPairDetector.h | 85 -- .../NarrowPhaseCollision/btManifoldPoint.h | 99 -- .../btMinkowskiPenetrationDepthSolver.cpp | 333 ----- .../btMinkowskiPenetrationDepthSolver.h | 37 - .../btPersistentManifold.cpp | 248 ---- .../btPersistentManifold.h | 179 --- .../NarrowPhaseCollision/btPointCollector.h | 61 - .../btRaycastCallback.cpp | 101 -- .../NarrowPhaseCollision/btRaycastCallback.h | 42 - .../btSimplexSolverInterface.h | 64 - .../btSubSimplexConvexCast.cpp | 139 -- .../btSubSimplexConvexCast.h | 50 - .../btVoronoiSimplexSolver.cpp | 607 -------- .../btVoronoiSimplexSolver.h | 157 -- .../src/BulletCollision/ibmsdk/Makefile | 95 -- .../bullet2/src/BulletDynamics/CMakeLists.txt | 22 - .../btConeTwistConstraint.cpp | 286 ---- .../ConstraintSolver/btConeTwistConstraint.h | 126 -- .../ConstraintSolver/btConstraintSolver.h | 52 - .../ConstraintSolver/btContactConstraint.cpp | 417 ------ .../ConstraintSolver/btContactConstraint.h | 122 -- .../ConstraintSolver/btContactSolverInfo.h | 51 - .../btGeneric6DofConstraint.cpp | 497 ------- .../btGeneric6DofConstraint.h | 433 ------ .../ConstraintSolver/btHingeConstraint.cpp | 400 ------ .../ConstraintSolver/btHingeConstraint.h | 130 -- .../ConstraintSolver/btJacobianEntry.h | 156 -- .../btPoint2PointConstraint.cpp | 117 -- .../btPoint2PointConstraint.h | 89 -- .../btSequentialImpulseConstraintSolver.cpp | 1266 ----------------- .../btSequentialImpulseConstraintSolver.h | 126 -- .../btSolve2LinearConstraint.cpp | 255 ---- .../btSolve2LinearConstraint.h | 107 -- .../ConstraintSolver/btSolverBody.h | 76 - .../ConstraintSolver/btSolverConstraint.h | 69 - .../ConstraintSolver/btTypedConstraint.cpp | 56 - .../ConstraintSolver/btTypedConstraint.h | 112 -- .../BulletDynamics/Dynamics/Bullet-C-API.cpp | 120 -- .../BulletDynamics/Dynamics/Bullet-C-Api.cpp | 91 -- .../Dynamics/btContinuousDynamicsWorld.cpp | 194 --- .../Dynamics/btContinuousDynamicsWorld.h | 46 - .../Dynamics/btDiscreteDynamicsWorld.cpp | 1004 ------------- .../Dynamics/btDiscreteDynamicsWorld.h | 164 --- .../BulletDynamics/Dynamics/btDynamicsWorld.h | 89 -- .../BulletDynamics/Dynamics/btRigidBody.cpp | 350 ----- .../src/BulletDynamics/Dynamics/btRigidBody.h | 385 ----- .../Dynamics/btSimpleDynamicsWorld.cpp | 217 --- .../Dynamics/btSimpleDynamicsWorld.h | 86 -- .../Vehicle/btRaycastVehicle.cpp | 738 ---------- .../BulletDynamics/Vehicle/btRaycastVehicle.h | 201 --- .../Vehicle/btVehicleRaycaster.h | 35 - .../BulletDynamics/Vehicle/btWheelInfo.cpp | 56 - .../src/BulletDynamics/Vehicle/btWheelInfo.h | 116 -- .../src/BulletDynamics/ibmsdk/Makefile | 45 - extern/bullet2/src/CMakeLists.txt | 1 - extern/bullet2/src/LinearMath/CMakeLists.txt | 11 - extern/bullet2/src/LinearMath/btAabbUtil2.h | 125 -- .../src/LinearMath/btAlignedAllocator.cpp | 155 -- .../src/LinearMath/btAlignedAllocator.h | 94 -- .../src/LinearMath/btAlignedObjectArray.h | 386 ----- .../src/LinearMath/btDefaultMotionState.h | 38 - .../bullet2/src/LinearMath/btGeometryUtil.cpp | 178 --- .../bullet2/src/LinearMath/btGeometryUtil.h | 41 - extern/bullet2/src/LinearMath/btIDebugDraw.h | 102 -- extern/bullet2/src/LinearMath/btList.h | 73 - extern/bullet2/src/LinearMath/btMatrix3x3.h | 410 ------ extern/bullet2/src/LinearMath/btMinMax.h | 69 - extern/bullet2/src/LinearMath/btMotionState.h | 40 - extern/bullet2/src/LinearMath/btPoint3.h | 24 - .../bullet2/src/LinearMath/btPoolAllocator.h | 94 -- extern/bullet2/src/LinearMath/btQuadWord.h | 135 -- extern/bullet2/src/LinearMath/btQuaternion.h | 321 ----- extern/bullet2/src/LinearMath/btQuickprof.cpp | 38 - extern/bullet2/src/LinearMath/btQuickprof.h | 712 --------- extern/bullet2/src/LinearMath/btRandom.h | 42 - extern/bullet2/src/LinearMath/btScalar.h | 394 ----- extern/bullet2/src/LinearMath/btSimdMinMax.h | 41 - extern/bullet2/src/LinearMath/btStackAlloc.h | 115 -- extern/bullet2/src/LinearMath/btTransform.h | 200 --- .../bullet2/src/LinearMath/btTransformUtil.h | 142 -- extern/bullet2/src/LinearMath/btVector3.h | 452 ------ extern/bullet2/src/LinearMath/ibmsdk/Makefile | 30 - extern/bullet2/src/Makefile | 71 - extern/bullet2/src/SConscript | 98 -- extern/bullet2/src/btBulletCollisionCommon.h | 63 - extern/bullet2/src/btBulletDynamicsCommon.h | 44 - extern/bullet2/src/ibmsdk/Makefile | 10 - source/blender/include/BIF_imasel.h | 1 + source/blender/include/BSE_drawview.h | 2 +- source/blender/include/BSE_filesel.h | 1 + source/blender/makesdna/DNA_userdef_types.h | 5 +- 217 files changed, 6 insertions(+), 34741 deletions(-) delete mode 100644 extern/bullet2/CMakeLists.txt delete mode 100644 extern/bullet2/Makefile delete mode 100644 extern/bullet2/make/msvc_7_0/Bullet_vc7.vcproj delete mode 100644 extern/bullet2/readme.txt delete mode 100644 extern/bullet2/src/Bullet-C-Api.h delete mode 100644 extern/bullet2/src/BulletCollision/BroadphaseCollision/btAxisSweep3.cpp delete mode 100644 extern/bullet2/src/BulletCollision/BroadphaseCollision/btAxisSweep3.h delete mode 100644 extern/bullet2/src/BulletCollision/BroadphaseCollision/btBroadphaseInterface.h delete mode 100644 extern/bullet2/src/BulletCollision/BroadphaseCollision/btBroadphaseProxy.cpp delete mode 100644 extern/bullet2/src/BulletCollision/BroadphaseCollision/btBroadphaseProxy.h delete mode 100644 extern/bullet2/src/BulletCollision/BroadphaseCollision/btCollisionAlgorithm.cpp delete mode 100644 extern/bullet2/src/BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h delete mode 100644 extern/bullet2/src/BulletCollision/BroadphaseCollision/btDispatcher.cpp delete mode 100644 extern/bullet2/src/BulletCollision/BroadphaseCollision/btDispatcher.h delete mode 100644 extern/bullet2/src/BulletCollision/BroadphaseCollision/btMultiSapBroadphase.cpp delete mode 100644 extern/bullet2/src/BulletCollision/BroadphaseCollision/btMultiSapBroadphase.h delete mode 100644 extern/bullet2/src/BulletCollision/BroadphaseCollision/btOverlappingPairCache.cpp delete mode 100644 extern/bullet2/src/BulletCollision/BroadphaseCollision/btOverlappingPairCache.h delete mode 100644 extern/bullet2/src/BulletCollision/BroadphaseCollision/btOverlappingPairCallback.h delete mode 100644 extern/bullet2/src/BulletCollision/BroadphaseCollision/btSimpleBroadphase.cpp delete mode 100644 extern/bullet2/src/BulletCollision/BroadphaseCollision/btSimpleBroadphase.h delete mode 100644 extern/bullet2/src/BulletCollision/CMakeLists.txt delete mode 100644 extern/bullet2/src/BulletCollision/CollisionDispatch/SphereTriangleDetector.cpp delete mode 100644 extern/bullet2/src/BulletCollision/CollisionDispatch/SphereTriangleDetector.h delete mode 100644 extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionConfiguration.h delete mode 100644 extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionCreateFunc.h delete mode 100644 extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionDispatcher.cpp delete mode 100644 extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionDispatcher.h delete mode 100644 extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionObject.cpp delete mode 100644 extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionObject.h delete mode 100644 extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionWorld.cpp delete mode 100644 extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionWorld.h delete mode 100644 extern/bullet2/src/BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.cpp delete mode 100644 extern/bullet2/src/BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.h delete mode 100644 extern/bullet2/src/BulletCollision/CollisionDispatch/btConvexConcaveCollisionAlgorithm.cpp delete mode 100644 extern/bullet2/src/BulletCollision/CollisionDispatch/btConvexConcaveCollisionAlgorithm.h delete mode 100644 extern/bullet2/src/BulletCollision/CollisionDispatch/btConvexConvexAlgorithm.cpp delete mode 100644 extern/bullet2/src/BulletCollision/CollisionDispatch/btConvexConvexAlgorithm.h delete mode 100644 extern/bullet2/src/BulletCollision/CollisionDispatch/btDefaultCollisionConfiguration.cpp delete mode 100644 extern/bullet2/src/BulletCollision/CollisionDispatch/btDefaultCollisionConfiguration.h delete mode 100644 extern/bullet2/src/BulletCollision/CollisionDispatch/btEmptyCollisionAlgorithm.cpp delete mode 100644 extern/bullet2/src/BulletCollision/CollisionDispatch/btEmptyCollisionAlgorithm.h delete mode 100644 extern/bullet2/src/BulletCollision/CollisionDispatch/btManifoldResult.cpp delete mode 100644 extern/bullet2/src/BulletCollision/CollisionDispatch/btManifoldResult.h delete mode 100644 extern/bullet2/src/BulletCollision/CollisionDispatch/btSimulationIslandManager.cpp delete mode 100644 extern/bullet2/src/BulletCollision/CollisionDispatch/btSimulationIslandManager.h delete mode 100644 extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereBoxCollisionAlgorithm.cpp delete mode 100644 extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereBoxCollisionAlgorithm.h delete mode 100644 extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereSphereCollisionAlgorithm.cpp delete mode 100644 extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereSphereCollisionAlgorithm.h delete mode 100644 extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereTriangleCollisionAlgorithm.cpp delete mode 100644 extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereTriangleCollisionAlgorithm.h delete mode 100644 extern/bullet2/src/BulletCollision/CollisionDispatch/btUnionFind.cpp delete mode 100644 extern/bullet2/src/BulletCollision/CollisionDispatch/btUnionFind.h delete mode 100644 extern/bullet2/src/BulletCollision/CollisionShapes/btBoxShape.cpp delete mode 100644 extern/bullet2/src/BulletCollision/CollisionShapes/btBoxShape.h delete mode 100644 extern/bullet2/src/BulletCollision/CollisionShapes/btBvhTriangleMeshShape.cpp delete mode 100644 extern/bullet2/src/BulletCollision/CollisionShapes/btBvhTriangleMeshShape.h delete mode 100644 extern/bullet2/src/BulletCollision/CollisionShapes/btCapsuleShape.cpp delete mode 100644 extern/bullet2/src/BulletCollision/CollisionShapes/btCapsuleShape.h delete mode 100644 extern/bullet2/src/BulletCollision/CollisionShapes/btCollisionMargin.h delete mode 100644 extern/bullet2/src/BulletCollision/CollisionShapes/btCollisionShape.cpp delete mode 100644 extern/bullet2/src/BulletCollision/CollisionShapes/btCollisionShape.h delete mode 100644 extern/bullet2/src/BulletCollision/CollisionShapes/btCompoundShape.cpp delete mode 100644 extern/bullet2/src/BulletCollision/CollisionShapes/btCompoundShape.h delete mode 100644 extern/bullet2/src/BulletCollision/CollisionShapes/btConcaveShape.cpp delete mode 100644 extern/bullet2/src/BulletCollision/CollisionShapes/btConcaveShape.h delete mode 100644 extern/bullet2/src/BulletCollision/CollisionShapes/btConeShape.cpp delete mode 100644 extern/bullet2/src/BulletCollision/CollisionShapes/btConeShape.h delete mode 100644 extern/bullet2/src/BulletCollision/CollisionShapes/btConvexHullShape.cpp delete mode 100644 extern/bullet2/src/BulletCollision/CollisionShapes/btConvexHullShape.h delete mode 100644 extern/bullet2/src/BulletCollision/CollisionShapes/btConvexInternalShape.cpp delete mode 100644 extern/bullet2/src/BulletCollision/CollisionShapes/btConvexInternalShape.h delete mode 100644 extern/bullet2/src/BulletCollision/CollisionShapes/btConvexShape.cpp delete mode 100644 extern/bullet2/src/BulletCollision/CollisionShapes/btConvexShape.h delete mode 100644 extern/bullet2/src/BulletCollision/CollisionShapes/btConvexTriangleMeshShape.cpp delete mode 100644 extern/bullet2/src/BulletCollision/CollisionShapes/btConvexTriangleMeshShape.h delete mode 100644 extern/bullet2/src/BulletCollision/CollisionShapes/btCylinderShape.cpp delete mode 100644 extern/bullet2/src/BulletCollision/CollisionShapes/btCylinderShape.h delete mode 100644 extern/bullet2/src/BulletCollision/CollisionShapes/btEmptyShape.cpp delete mode 100644 extern/bullet2/src/BulletCollision/CollisionShapes/btEmptyShape.h delete mode 100644 extern/bullet2/src/BulletCollision/CollisionShapes/btHeightfieldTerrainShape.cpp delete mode 100644 extern/bullet2/src/BulletCollision/CollisionShapes/btHeightfieldTerrainShape.h delete mode 100644 extern/bullet2/src/BulletCollision/CollisionShapes/btMinkowskiSumShape.cpp delete mode 100644 extern/bullet2/src/BulletCollision/CollisionShapes/btMinkowskiSumShape.h delete mode 100644 extern/bullet2/src/BulletCollision/CollisionShapes/btMultiSphereShape.cpp delete mode 100644 extern/bullet2/src/BulletCollision/CollisionShapes/btMultiSphereShape.h delete mode 100644 extern/bullet2/src/BulletCollision/CollisionShapes/btOptimizedBvh.cpp delete mode 100644 extern/bullet2/src/BulletCollision/CollisionShapes/btOptimizedBvh.h delete mode 100644 extern/bullet2/src/BulletCollision/CollisionShapes/btPolyhedralConvexShape.cpp delete mode 100644 extern/bullet2/src/BulletCollision/CollisionShapes/btPolyhedralConvexShape.h delete mode 100644 extern/bullet2/src/BulletCollision/CollisionShapes/btSphereShape.cpp delete mode 100644 extern/bullet2/src/BulletCollision/CollisionShapes/btSphereShape.h delete mode 100644 extern/bullet2/src/BulletCollision/CollisionShapes/btStaticPlaneShape.cpp delete mode 100644 extern/bullet2/src/BulletCollision/CollisionShapes/btStaticPlaneShape.h delete mode 100644 extern/bullet2/src/BulletCollision/CollisionShapes/btStridingMeshInterface.cpp delete mode 100644 extern/bullet2/src/BulletCollision/CollisionShapes/btStridingMeshInterface.h delete mode 100644 extern/bullet2/src/BulletCollision/CollisionShapes/btTetrahedronShape.cpp delete mode 100644 extern/bullet2/src/BulletCollision/CollisionShapes/btTetrahedronShape.h delete mode 100644 extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleBuffer.cpp delete mode 100644 extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleBuffer.h delete mode 100644 extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleCallback.cpp delete mode 100644 extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleCallback.h delete mode 100644 extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleIndexVertexArray.cpp delete mode 100644 extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleIndexVertexArray.h delete mode 100644 extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleMesh.cpp delete mode 100644 extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleMesh.h delete mode 100644 extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleMeshShape.cpp delete mode 100644 extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleMeshShape.h delete mode 100644 extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleShape.h delete mode 100644 extern/bullet2/src/BulletCollision/CollisionShapes/btUniformScalingShape.cpp delete mode 100644 extern/bullet2/src/BulletCollision/CollisionShapes/btUniformScalingShape.h delete mode 100644 extern/bullet2/src/BulletCollision/Doxyfile delete mode 100644 extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btContinuousConvexCollision.cpp delete mode 100644 extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btContinuousConvexCollision.h delete mode 100644 extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btConvexCast.cpp delete mode 100644 extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btConvexCast.h delete mode 100644 extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btConvexPenetrationDepthSolver.h delete mode 100644 extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btDiscreteCollisionDetectorInterface.h delete mode 100644 extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkConvexCast.cpp delete mode 100644 extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkConvexCast.h delete mode 100644 extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkEpa.cpp delete mode 100644 extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkEpa.h delete mode 100644 extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.cpp delete mode 100644 extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.h delete mode 100644 extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkPairDetector.cpp delete mode 100644 extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkPairDetector.h delete mode 100644 extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btManifoldPoint.h delete mode 100644 extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.cpp delete mode 100644 extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.h delete mode 100644 extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btPersistentManifold.cpp delete mode 100644 extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btPersistentManifold.h delete mode 100644 extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btPointCollector.h delete mode 100644 extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btRaycastCallback.cpp delete mode 100644 extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btRaycastCallback.h delete mode 100644 extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btSimplexSolverInterface.h delete mode 100644 extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btSubSimplexConvexCast.cpp delete mode 100644 extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btSubSimplexConvexCast.h delete mode 100644 extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.cpp delete mode 100644 extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.h delete mode 100644 extern/bullet2/src/BulletCollision/ibmsdk/Makefile delete mode 100644 extern/bullet2/src/BulletDynamics/CMakeLists.txt delete mode 100644 extern/bullet2/src/BulletDynamics/ConstraintSolver/btConeTwistConstraint.cpp delete mode 100644 extern/bullet2/src/BulletDynamics/ConstraintSolver/btConeTwistConstraint.h delete mode 100644 extern/bullet2/src/BulletDynamics/ConstraintSolver/btConstraintSolver.h delete mode 100644 extern/bullet2/src/BulletDynamics/ConstraintSolver/btContactConstraint.cpp delete mode 100644 extern/bullet2/src/BulletDynamics/ConstraintSolver/btContactConstraint.h delete mode 100644 extern/bullet2/src/BulletDynamics/ConstraintSolver/btContactSolverInfo.h delete mode 100644 extern/bullet2/src/BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.cpp delete mode 100644 extern/bullet2/src/BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.h delete mode 100644 extern/bullet2/src/BulletDynamics/ConstraintSolver/btHingeConstraint.cpp delete mode 100644 extern/bullet2/src/BulletDynamics/ConstraintSolver/btHingeConstraint.h delete mode 100644 extern/bullet2/src/BulletDynamics/ConstraintSolver/btJacobianEntry.h delete mode 100644 extern/bullet2/src/BulletDynamics/ConstraintSolver/btPoint2PointConstraint.cpp delete mode 100644 extern/bullet2/src/BulletDynamics/ConstraintSolver/btPoint2PointConstraint.h delete mode 100644 extern/bullet2/src/BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.cpp delete mode 100644 extern/bullet2/src/BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.h delete mode 100644 extern/bullet2/src/BulletDynamics/ConstraintSolver/btSolve2LinearConstraint.cpp delete mode 100644 extern/bullet2/src/BulletDynamics/ConstraintSolver/btSolve2LinearConstraint.h delete mode 100644 extern/bullet2/src/BulletDynamics/ConstraintSolver/btSolverBody.h delete mode 100644 extern/bullet2/src/BulletDynamics/ConstraintSolver/btSolverConstraint.h delete mode 100644 extern/bullet2/src/BulletDynamics/ConstraintSolver/btTypedConstraint.cpp delete mode 100644 extern/bullet2/src/BulletDynamics/ConstraintSolver/btTypedConstraint.h delete mode 100644 extern/bullet2/src/BulletDynamics/Dynamics/Bullet-C-API.cpp delete mode 100644 extern/bullet2/src/BulletDynamics/Dynamics/Bullet-C-Api.cpp delete mode 100644 extern/bullet2/src/BulletDynamics/Dynamics/btContinuousDynamicsWorld.cpp delete mode 100644 extern/bullet2/src/BulletDynamics/Dynamics/btContinuousDynamicsWorld.h delete mode 100644 extern/bullet2/src/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.cpp delete mode 100644 extern/bullet2/src/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.h delete mode 100644 extern/bullet2/src/BulletDynamics/Dynamics/btDynamicsWorld.h delete mode 100644 extern/bullet2/src/BulletDynamics/Dynamics/btRigidBody.cpp delete mode 100644 extern/bullet2/src/BulletDynamics/Dynamics/btRigidBody.h delete mode 100644 extern/bullet2/src/BulletDynamics/Dynamics/btSimpleDynamicsWorld.cpp delete mode 100644 extern/bullet2/src/BulletDynamics/Dynamics/btSimpleDynamicsWorld.h delete mode 100644 extern/bullet2/src/BulletDynamics/Vehicle/btRaycastVehicle.cpp delete mode 100644 extern/bullet2/src/BulletDynamics/Vehicle/btRaycastVehicle.h delete mode 100644 extern/bullet2/src/BulletDynamics/Vehicle/btVehicleRaycaster.h delete mode 100644 extern/bullet2/src/BulletDynamics/Vehicle/btWheelInfo.cpp delete mode 100644 extern/bullet2/src/BulletDynamics/Vehicle/btWheelInfo.h delete mode 100644 extern/bullet2/src/BulletDynamics/ibmsdk/Makefile delete mode 100644 extern/bullet2/src/CMakeLists.txt delete mode 100644 extern/bullet2/src/LinearMath/CMakeLists.txt delete mode 100644 extern/bullet2/src/LinearMath/btAabbUtil2.h delete mode 100644 extern/bullet2/src/LinearMath/btAlignedAllocator.cpp delete mode 100644 extern/bullet2/src/LinearMath/btAlignedAllocator.h delete mode 100644 extern/bullet2/src/LinearMath/btAlignedObjectArray.h delete mode 100644 extern/bullet2/src/LinearMath/btDefaultMotionState.h delete mode 100644 extern/bullet2/src/LinearMath/btGeometryUtil.cpp delete mode 100644 extern/bullet2/src/LinearMath/btGeometryUtil.h delete mode 100644 extern/bullet2/src/LinearMath/btIDebugDraw.h delete mode 100644 extern/bullet2/src/LinearMath/btList.h delete mode 100644 extern/bullet2/src/LinearMath/btMatrix3x3.h delete mode 100644 extern/bullet2/src/LinearMath/btMinMax.h delete mode 100644 extern/bullet2/src/LinearMath/btMotionState.h delete mode 100644 extern/bullet2/src/LinearMath/btPoint3.h delete mode 100755 extern/bullet2/src/LinearMath/btPoolAllocator.h delete mode 100644 extern/bullet2/src/LinearMath/btQuadWord.h delete mode 100644 extern/bullet2/src/LinearMath/btQuaternion.h delete mode 100644 extern/bullet2/src/LinearMath/btQuickprof.cpp delete mode 100644 extern/bullet2/src/LinearMath/btQuickprof.h delete mode 100644 extern/bullet2/src/LinearMath/btRandom.h delete mode 100644 extern/bullet2/src/LinearMath/btScalar.h delete mode 100644 extern/bullet2/src/LinearMath/btSimdMinMax.h delete mode 100644 extern/bullet2/src/LinearMath/btStackAlloc.h delete mode 100644 extern/bullet2/src/LinearMath/btTransform.h delete mode 100644 extern/bullet2/src/LinearMath/btTransformUtil.h delete mode 100644 extern/bullet2/src/LinearMath/btVector3.h delete mode 100644 extern/bullet2/src/LinearMath/ibmsdk/Makefile delete mode 100644 extern/bullet2/src/Makefile delete mode 100644 extern/bullet2/src/SConscript delete mode 100644 extern/bullet2/src/btBulletCollisionCommon.h delete mode 100644 extern/bullet2/src/btBulletDynamicsCommon.h delete mode 100644 extern/bullet2/src/ibmsdk/Makefile diff --git a/extern/bullet2/CMakeLists.txt b/extern/bullet2/CMakeLists.txt deleted file mode 100644 index 19dc6e2ba77..00000000000 --- a/extern/bullet2/CMakeLists.txt +++ /dev/null @@ -1,46 +0,0 @@ -# $Id$ -# ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. The Blender -# Foundation also sells licenses for use in proprietary software under -# the Blender License. See http://www.blender.org/BL/ for information -# about this. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software Foundation, -# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -# -# The Original Code is Copyright (C) 2006, Blender Foundation -# All rights reserved. -# -# The Original Code is: all of this file. -# -# Contributor(s): Jacques Beaurai, Erwin Coumans -# -# ***** END GPL/BL DUAL LICENSE BLOCK ***** - -SET(INC . src) - -FILE(GLOB SRC - src/LinearMath/*.cpp - src/BulletCollision/BroadphaseCollision/*.cpp - src/BulletCollision/CollisionShapes/*.cpp - src/BulletCollision/NarrowPhaseCollision/*.cpp - src/BulletCollision//CollisionDispatch/*.cpp - src/BulletDynamics/ConstraintSolver/*.cpp - src/BulletDynamics/Vehicle/*.cpp - src/BulletDynamics/Dynamics/*.cpp -) - -ADD_DEFINITIONS(-D_LIB) - -BLENDERLIB(extern_bullet "${SRC}" "${INC}") -#, libtype=['game2', 'player'], priority=[20, 170], compileflags=cflags ) diff --git a/extern/bullet2/Makefile b/extern/bullet2/Makefile deleted file mode 100644 index be242c290ff..00000000000 --- a/extern/bullet2/Makefile +++ /dev/null @@ -1,64 +0,0 @@ -# -# $Id$ -# -# ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. The Blender -# Foundation also sells licenses for use in proprietary software under -# the Blender License. See http://www.blender.org/BL/ for information -# about this. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software Foundation, -# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -# -# The Original Code is Copyright (C) 2002 by Hans Lambermont -# All rights reserved. -# -# The Original Code is: all of this file. -# -# Contributor(s): -# -# ***** END GPL/BL DUAL LICENSE BLOCK ***** -LIBNAME = bullet2 -include nan_definitions.mk -SOURCEDIR = extern/$(LIBNAME) -DIR = $(OCGDIR)/extern/$(LIBNAME) -DIRS = src -DISTDIR = src - -BULLETDIRS = \ -LinearMath \ -BulletCollision/BroadphaseCollision \ -BulletCollision/CollisionShapes \ -BulletCollision/NarrowPhaseCollision \ -BulletCollision//CollisionDispatch \ -BulletDynamics/ConstraintSolver \ -BulletDynamics/Vehicle \ -BulletDynamics/Dynamics - -include nan_subdirs.mk - -CP = $(NANBLENDERHOME)/intern/tools/cpifdiff.sh - -install: all debug - @[ -d $(NAN_BULLET2) ] || mkdir -p $(NAN_BULLET2) - @[ -d $(NAN_BULLET2)/include ] || mkdir -p $(NAN_BULLET2)/include - @for i in $(BULLETDIRS); do \ - [ -d $(NAN_BULLET2)/include/$$i ] || mkdir -p $(NAN_BULLET2)/include/$$i; \ - $(CP) $(DISTDIR)/$$i/*.h $(NAN_BULLET2)/include/$$i; \ - done - @[ -d $(NAN_BULLET2)/lib ] || mkdir -p $(NAN_BULLET2)/lib - @$(CP) $(DISTDIR)/*.h $(NAN_BULLET2)/include - @$(CP) $(OCGDIR)/extern/bullet2/libbullet2.a $(NAN_BULLET2)/lib -ifeq ($(OS),darwin) - ranlib $(NAN_BULLET2)/lib/libbullet2.a -endif diff --git a/extern/bullet2/make/msvc_7_0/Bullet_vc7.vcproj b/extern/bullet2/make/msvc_7_0/Bullet_vc7.vcproj deleted file mode 100644 index 87a1e4546d1..00000000000 --- a/extern/bullet2/make/msvc_7_0/Bullet_vc7.vcproj +++ /dev/null @@ -1,921 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/extern/bullet2/readme.txt b/extern/bullet2/readme.txt deleted file mode 100644 index 4d1a4c11706..00000000000 --- a/extern/bullet2/readme.txt +++ /dev/null @@ -1,12 +0,0 @@ - -*** These files in extern/bullet2 are NOT part of the Blender build yet *** - -This is the new refactored version of Bullet physics library version 2.x - -Soon this will replace the old Bullet version in extern/bullet. -First the integration in Blender Game Engine needs to be updated. -Once that is done all build systems can be updated to use/build extern/bullet2 files. - -Questions? mail blender at erwincoumans.com, or check the bf-blender mailing list. -Thanks, -Erwin diff --git a/extern/bullet2/src/Bullet-C-Api.h b/extern/bullet2/src/Bullet-C-Api.h deleted file mode 100644 index 078dcae63bb..00000000000 --- a/extern/bullet2/src/Bullet-C-Api.h +++ /dev/null @@ -1,37 +0,0 @@ -/* -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. -*/ - -/* - Draft high-level generic physics C-API. For low-level access, use the physics SDK native API's. - Work in progress, functionality will be added on demand. - - If possible, use the richer Bullet C++ API, by including "btBulletDynamicsCommon.h" -*/ - -#ifndef BULLET_C_API_H -#define BULLET_C_API_H - -#ifdef __cplusplus -extern "C" { -#endif - -double plNearestPoints(float p1[3], float p2[3], float p3[3], float q1[3], float q2[3], float q3[3], float *pa, float *pb, float normal[3]); - -#ifdef __cplusplus -} -#endif - -#endif //BULLET_C_API_H - diff --git a/extern/bullet2/src/BulletCollision/BroadphaseCollision/btAxisSweep3.cpp b/extern/bullet2/src/BulletCollision/BroadphaseCollision/btAxisSweep3.cpp deleted file mode 100644 index d7eea33ea41..00000000000 --- a/extern/bullet2/src/BulletCollision/BroadphaseCollision/btAxisSweep3.cpp +++ /dev/null @@ -1,38 +0,0 @@ - -//Bullet Continuous Collision Detection and Physics Library -//Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ - - -// -// btAxisSweep3 -// -// Copyright (c) 2006 Simon Hobbs -// -// 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 "btAxisSweep3.h" - -#include - -btAxisSweep3::btAxisSweep3(const btPoint3& worldAabbMin,const btPoint3& worldAabbMax, unsigned short int maxHandles, btOverlappingPairCache* pairCache) -:btAxisSweep3Internal(worldAabbMin,worldAabbMax,0xfffe,0xffff,maxHandles,pairCache) -{ - // 1 handle is reserved as sentinel - btAssert(maxHandles > 1 && maxHandles < 32767); - -} - - -bt32BitAxisSweep3::bt32BitAxisSweep3(const btPoint3& worldAabbMin,const btPoint3& worldAabbMax, unsigned int maxHandles , btOverlappingPairCache* pairCache ) -:btAxisSweep3Internal(worldAabbMin,worldAabbMax,0xfffffffe,0x7fffffff,maxHandles,pairCache) -{ - // 1 handle is reserved as sentinel - btAssert(maxHandles > 1 && maxHandles < 2147483647); -} diff --git a/extern/bullet2/src/BulletCollision/BroadphaseCollision/btAxisSweep3.h b/extern/bullet2/src/BulletCollision/BroadphaseCollision/btAxisSweep3.h deleted file mode 100644 index d36df6e6621..00000000000 --- a/extern/bullet2/src/BulletCollision/BroadphaseCollision/btAxisSweep3.h +++ /dev/null @@ -1,880 +0,0 @@ -//Bullet Continuous Collision Detection and Physics Library -//Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ - -// -// btAxisSweep3.h -// -// Copyright (c) 2006 Simon Hobbs -// -// 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 AXIS_SWEEP_3_H -#define AXIS_SWEEP_3_H - -#include "LinearMath/btPoint3.h" -#include "LinearMath/btVector3.h" -#include "btOverlappingPairCache.h" -#include "btBroadphaseInterface.h" -#include "btBroadphaseProxy.h" -#include "btOverlappingPairCallback.h" - -//#define DEBUG_BROADPHASE 1 - -/// btAxisSweep3Internal is an internal template class that implements sweep and prune. -/// Dont use this class directly, use btAxisSweep3 or bt32BitAxisSweep3 instead. -template -class btAxisSweep3Internal : public btBroadphaseInterface -{ -protected: - - BP_FP_INT_TYPE m_bpHandleMask; - BP_FP_INT_TYPE m_handleSentinel; - -public: - - - class Edge - { - public: - BP_FP_INT_TYPE m_pos; // low bit is min/max - BP_FP_INT_TYPE m_handle; - - BP_FP_INT_TYPE IsMax() const {return m_pos & 1;} - }; - -public: - ATTRIBUTE_ALIGNED16(class) Handle : public btBroadphaseProxy - { - public: - BT_DECLARE_ALIGNED_ALLOCATOR(); - - // indexes into the edge arrays - BP_FP_INT_TYPE m_minEdges[3], m_maxEdges[3]; // 6 * 2 = 12 -// BP_FP_INT_TYPE m_uniqueId; - BP_FP_INT_TYPE m_pad; - - //void* m_pOwner; this is now in btBroadphaseProxy.m_clientObject - - SIMD_FORCE_INLINE void SetNextFree(BP_FP_INT_TYPE next) {m_minEdges[0] = next;} - SIMD_FORCE_INLINE BP_FP_INT_TYPE GetNextFree() const {return m_minEdges[0];} - }; // 24 bytes + 24 for Edge structures = 44 bytes total per entry - - -protected: - btPoint3 m_worldAabbMin; // overall system bounds - btPoint3 m_worldAabbMax; // overall system bounds - - btVector3 m_quantize; // scaling factor for quantization - - BP_FP_INT_TYPE m_numHandles; // number of active handles - BP_FP_INT_TYPE m_maxHandles; // max number of handles - Handle* m_pHandles; // handles pool - BP_FP_INT_TYPE m_firstFreeHandle; // free handles list - - Edge* m_pEdges[3]; // edge arrays for the 3 axes (each array has m_maxHandles * 2 + 2 sentinel entries) - - btOverlappingPairCache* m_pairCache; - - ///btOverlappingPairCallback is an additional optional user callback for adding/removing overlapping pairs, similar interface to btOverlappingPairCache. - btOverlappingPairCallback* m_userPairCallback; - - bool m_ownsPairCache; - - int m_invalidPair; - - // allocation/deallocation - BP_FP_INT_TYPE allocHandle(); - void freeHandle(BP_FP_INT_TYPE handle); - - - bool testOverlap(int ignoreAxis,const Handle* pHandleA, const Handle* pHandleB); - -#ifdef DEBUG_BROADPHASE - void debugPrintAxis(int axis,bool checkCardinality=true); -#endif //DEBUG_BROADPHASE - - //Overlap* AddOverlap(BP_FP_INT_TYPE handleA, BP_FP_INT_TYPE handleB); - //void RemoveOverlap(BP_FP_INT_TYPE handleA, BP_FP_INT_TYPE handleB); - - void quantize(BP_FP_INT_TYPE* out, const btPoint3& point, int isMax) const; - - void sortMinDown(int axis, BP_FP_INT_TYPE edge, btDispatcher* dispatcher, bool updateOverlaps ); - void sortMinUp(int axis, BP_FP_INT_TYPE edge, btDispatcher* dispatcher, bool updateOverlaps ); - void sortMaxDown(int axis, BP_FP_INT_TYPE edge, btDispatcher* dispatcher, bool updateOverlaps ); - void sortMaxUp(int axis, BP_FP_INT_TYPE edge, btDispatcher* dispatcher, bool updateOverlaps ); - -public: - - btAxisSweep3Internal(const btPoint3& worldAabbMin,const btPoint3& worldAabbMax, BP_FP_INT_TYPE handleMask, BP_FP_INT_TYPE handleSentinel, BP_FP_INT_TYPE maxHandles = 16384, btOverlappingPairCache* pairCache=0); - - virtual ~btAxisSweep3Internal(); - - - virtual void calculateOverlappingPairs(btDispatcher* dispatcher); - - BP_FP_INT_TYPE addHandle(const btPoint3& aabbMin,const btPoint3& aabbMax, void* pOwner,short int collisionFilterGroup,short int collisionFilterMask,btDispatcher* dispatcher); - void removeHandle(BP_FP_INT_TYPE handle,btDispatcher* dispatcher); - void updateHandle(BP_FP_INT_TYPE handle, const btPoint3& aabbMin,const btPoint3& aabbMax,btDispatcher* dispatcher); - SIMD_FORCE_INLINE Handle* getHandle(BP_FP_INT_TYPE index) const {return m_pHandles + index;} - - void processAllOverlappingPairs(btOverlapCallback* callback); - - //Broadphase Interface - virtual btBroadphaseProxy* createProxy( const btVector3& aabbMin, const btVector3& aabbMax,int shapeType,void* userPtr ,short int collisionFilterGroup,short int collisionFilterMask,btDispatcher* dispatcher); - virtual void destroyProxy(btBroadphaseProxy* proxy,btDispatcher* dispatcher); - virtual void setAabb(btBroadphaseProxy* proxy,const btVector3& aabbMin,const btVector3& aabbMax,btDispatcher* dispatcher); - - bool testAabbOverlap(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1); - - btOverlappingPairCache* getOverlappingPairCache() - { - return m_pairCache; - } - const btOverlappingPairCache* getOverlappingPairCache() const - { - return m_pairCache; - } - - void setOverlappingPairUserCallback(btOverlappingPairCallback* pairCallback) - { - m_userPairCallback = pairCallback; - } - const btOverlappingPairCallback* getOverlappingPairUserCallback() const - { - return m_userPairCallback; - } -}; - -//////////////////////////////////////////////////////////////////// - - - - -#ifdef DEBUG_BROADPHASE -#include - -template -void btAxisSweep3::debugPrintAxis(int axis, bool checkCardinality) -{ - int numEdges = m_pHandles[0].m_maxEdges[axis]; - printf("SAP Axis %d, numEdges=%d\n",axis,numEdges); - - int i; - for (i=0;im_handle); - int handleIndex = pEdge->IsMax()? pHandlePrev->m_maxEdges[axis] : pHandlePrev->m_minEdges[axis]; - char beginOrEnd; - beginOrEnd=pEdge->IsMax()?'E':'B'; - printf(" [%c,h=%d,p=%x,i=%d]\n",beginOrEnd,pEdge->m_handle,pEdge->m_pos,handleIndex); - } - - if (checkCardinality) - assert(numEdges == m_numHandles*2+1); -} -#endif //DEBUG_BROADPHASE - -template -btBroadphaseProxy* btAxisSweep3Internal::createProxy( const btVector3& aabbMin, const btVector3& aabbMax,int shapeType,void* userPtr,short int collisionFilterGroup,short int collisionFilterMask,btDispatcher* dispatcher) -{ - (void)shapeType; - BP_FP_INT_TYPE handleId = addHandle(aabbMin,aabbMax, userPtr,collisionFilterGroup,collisionFilterMask,dispatcher); - - Handle* handle = getHandle(handleId); - - return handle; -} - - - -template -void btAxisSweep3Internal::destroyProxy(btBroadphaseProxy* proxy,btDispatcher* dispatcher) -{ - Handle* handle = static_cast(proxy); - removeHandle(handle->m_uniqueId,dispatcher); -} - -template -void btAxisSweep3Internal::setAabb(btBroadphaseProxy* proxy,const btVector3& aabbMin,const btVector3& aabbMax,btDispatcher* dispatcher) -{ - Handle* handle = static_cast(proxy); - updateHandle(handle->m_uniqueId,aabbMin,aabbMax,dispatcher); - -} - - - - - -template -btAxisSweep3Internal::btAxisSweep3Internal(const btPoint3& worldAabbMin,const btPoint3& worldAabbMax, BP_FP_INT_TYPE handleMask, BP_FP_INT_TYPE handleSentinel,BP_FP_INT_TYPE maxHandles, btOverlappingPairCache* pairCache ) -:m_bpHandleMask(handleMask), -m_handleSentinel(handleSentinel), -m_pairCache(pairCache), -m_userPairCallback(0), -m_ownsPairCache(false), -m_invalidPair(0) -{ - if (!m_pairCache) - { - void* ptr = btAlignedAlloc(sizeof(btOverlappingPairCache),16); - m_pairCache = new(ptr) btOverlappingPairCache(); - m_ownsPairCache = true; - } - - //assert(bounds.HasVolume()); - - // init bounds - m_worldAabbMin = worldAabbMin; - m_worldAabbMax = worldAabbMax; - - btVector3 aabbSize = m_worldAabbMax - m_worldAabbMin; - - BP_FP_INT_TYPE maxInt = m_handleSentinel; - - m_quantize = btVector3(btScalar(maxInt),btScalar(maxInt),btScalar(maxInt)) / aabbSize; - - // allocate handles buffer and put all handles on free list - void* ptr = btAlignedAlloc(sizeof(Handle)*maxHandles,16); - m_pHandles = new(ptr) Handle[maxHandles]; - m_maxHandles = maxHandles; - m_numHandles = 0; - - // handle 0 is reserved as the null index, and is also used as the sentinel - m_firstFreeHandle = 1; - { - for (BP_FP_INT_TYPE i = m_firstFreeHandle; i < maxHandles; i++) - m_pHandles[i].SetNextFree(i + 1); - m_pHandles[maxHandles - 1].SetNextFree(0); - } - - { - // allocate edge buffers - for (int i = 0; i < 3; i++) - { - void* ptr = btAlignedAlloc(sizeof(Edge)*maxHandles*2,16); - m_pEdges[i] = new(ptr) Edge[maxHandles * 2]; - } - } - //removed overlap management - - // make boundary sentinels - - m_pHandles[0].m_clientObject = 0; - - for (int axis = 0; axis < 3; axis++) - { - m_pHandles[0].m_minEdges[axis] = 0; - m_pHandles[0].m_maxEdges[axis] = 1; - - m_pEdges[axis][0].m_pos = 0; - m_pEdges[axis][0].m_handle = 0; - m_pEdges[axis][1].m_pos = m_handleSentinel; - m_pEdges[axis][1].m_handle = 0; -#ifdef DEBUG_BROADPHASE - debugPrintAxis(axis); -#endif //DEBUG_BROADPHASE - - } - -} - -template -btAxisSweep3Internal::~btAxisSweep3Internal() -{ - - for (int i = 2; i >= 0; i--) - { - btAlignedFree(m_pEdges[i]); - } - btAlignedFree(m_pHandles); - - if (m_ownsPairCache) - { - m_pairCache->~btOverlappingPairCache(); - btAlignedFree(m_pairCache); - } -} - -template -void btAxisSweep3Internal::quantize(BP_FP_INT_TYPE* out, const btPoint3& point, int isMax) const -{ - btPoint3 clampedPoint(point); - - - - clampedPoint.setMax(m_worldAabbMin); - clampedPoint.setMin(m_worldAabbMax); - - btVector3 v = (clampedPoint - m_worldAabbMin) * m_quantize; - out[0] = (BP_FP_INT_TYPE)(((BP_FP_INT_TYPE)v.getX() & m_bpHandleMask) | isMax); - out[1] = (BP_FP_INT_TYPE)(((BP_FP_INT_TYPE)v.getY() & m_bpHandleMask) | isMax); - out[2] = (BP_FP_INT_TYPE)(((BP_FP_INT_TYPE)v.getZ() & m_bpHandleMask) | isMax); - -} - - -template -BP_FP_INT_TYPE btAxisSweep3Internal::allocHandle() -{ - assert(m_firstFreeHandle); - - BP_FP_INT_TYPE handle = m_firstFreeHandle; - m_firstFreeHandle = getHandle(handle)->GetNextFree(); - m_numHandles++; - - return handle; -} - -template -void btAxisSweep3Internal::freeHandle(BP_FP_INT_TYPE handle) -{ - assert(handle > 0 && handle < m_maxHandles); - - getHandle(handle)->SetNextFree(m_firstFreeHandle); - m_firstFreeHandle = handle; - - m_numHandles--; -} - - -template -BP_FP_INT_TYPE btAxisSweep3Internal::addHandle(const btPoint3& aabbMin,const btPoint3& aabbMax, void* pOwner,short int collisionFilterGroup,short int collisionFilterMask,btDispatcher* dispatcher) -{ - // quantize the bounds - BP_FP_INT_TYPE min[3], max[3]; - quantize(min, aabbMin, 0); - quantize(max, aabbMax, 1); - - // allocate a handle - BP_FP_INT_TYPE handle = allocHandle(); - - - Handle* pHandle = getHandle(handle); - - pHandle->m_uniqueId = handle; - //pHandle->m_pOverlaps = 0; - pHandle->m_clientObject = pOwner; - pHandle->m_collisionFilterGroup = collisionFilterGroup; - pHandle->m_collisionFilterMask = collisionFilterMask; - - // compute current limit of edge arrays - BP_FP_INT_TYPE limit = m_numHandles * 2; - - - // insert new edges just inside the max boundary edge - for (BP_FP_INT_TYPE axis = 0; axis < 3; axis++) - { - - m_pHandles[0].m_maxEdges[axis] += 2; - - m_pEdges[axis][limit + 1] = m_pEdges[axis][limit - 1]; - - m_pEdges[axis][limit - 1].m_pos = min[axis]; - m_pEdges[axis][limit - 1].m_handle = handle; - - m_pEdges[axis][limit].m_pos = max[axis]; - m_pEdges[axis][limit].m_handle = handle; - - pHandle->m_minEdges[axis] = limit - 1; - pHandle->m_maxEdges[axis] = limit; - } - - // now sort the new edges to their correct position - sortMinDown(0, pHandle->m_minEdges[0], dispatcher,false); - sortMaxDown(0, pHandle->m_maxEdges[0], dispatcher,false); - sortMinDown(1, pHandle->m_minEdges[1], dispatcher,false); - sortMaxDown(1, pHandle->m_maxEdges[1], dispatcher,false); - sortMinDown(2, pHandle->m_minEdges[2], dispatcher,true); - sortMaxDown(2, pHandle->m_maxEdges[2], dispatcher,true); - - - return handle; -} - - -template -void btAxisSweep3Internal::removeHandle(BP_FP_INT_TYPE handle,btDispatcher* dispatcher) -{ - - Handle* pHandle = getHandle(handle); - - //explicitly remove the pairs containing the proxy - //we could do it also in the sortMinUp (passing true) - //todo: compare performance - m_pairCache->removeOverlappingPairsContainingProxy(pHandle,dispatcher); - - - // compute current limit of edge arrays - int limit = m_numHandles * 2; - - int axis; - - for (axis = 0;axis<3;axis++) - { - m_pHandles[0].m_maxEdges[axis] -= 2; - } - - // remove the edges by sorting them up to the end of the list - for ( axis = 0; axis < 3; axis++) - { - Edge* pEdges = m_pEdges[axis]; - BP_FP_INT_TYPE max = pHandle->m_maxEdges[axis]; - pEdges[max].m_pos = m_handleSentinel; - - sortMaxUp(axis,max,dispatcher,false); - - - BP_FP_INT_TYPE i = pHandle->m_minEdges[axis]; - pEdges[i].m_pos = m_handleSentinel; - - - sortMinUp(axis,i,dispatcher,false); - - pEdges[limit-1].m_handle = 0; - pEdges[limit-1].m_pos = m_handleSentinel; - -#ifdef DEBUG_BROADPHASE - debugPrintAxis(axis,false); -#endif //DEBUG_BROADPHASE - - - } - - - // free the handle - freeHandle(handle); - - -} - -extern int gOverlappingPairs; -#include - -template -void btAxisSweep3Internal::calculateOverlappingPairs(btDispatcher* dispatcher) -{ -#ifdef USE_LAZY_REMOVAL - - if (m_ownsPairCache) - { - - btBroadphasePairArray& overlappingPairArray = m_pairCache->getOverlappingPairArray(); - - //perform a sort, to find duplicates and to sort 'invalid' pairs to the end - overlappingPairArray.heapSort(btBroadphasePairSortPredicate()); - - overlappingPairArray.resize(overlappingPairArray.size() - m_invalidPair); - m_invalidPair = 0; - - - int i; - - btBroadphasePair previousPair; - previousPair.m_pProxy0 = 0; - previousPair.m_pProxy1 = 0; - previousPair.m_algorithm = 0; - - - for (i=0;iprocessOverlap(pair); - } else - { - needsRemoval = true; - } - } else - { - //remove duplicate - needsRemoval = true; - //should have no algorithm - btAssert(!pair.m_algorithm); - } - - if (needsRemoval) - { - m_pairCache->cleanOverlappingPair(pair,dispatcher); - - // m_overlappingPairArray.swap(i,m_overlappingPairArray.size()-1); - // m_overlappingPairArray.pop_back(); - pair.m_pProxy0 = 0; - pair.m_pProxy1 = 0; - m_invalidPair++; - gOverlappingPairs--; - } - - } - - ///if you don't like to skip the invalid pairs in the array, execute following code: - #define CLEAN_INVALID_PAIRS 1 - #ifdef CLEAN_INVALID_PAIRS - - //perform a sort, to sort 'invalid' pairs to the end - overlappingPairArray.heapSort(btBroadphasePairSortPredicate()); - - overlappingPairArray.resize(overlappingPairArray.size() - m_invalidPair); - m_invalidPair = 0; - #endif//CLEAN_INVALID_PAIRS - - //printf("overlappingPairArray.size()=%d\n",overlappingPairArray.size()); - } -#endif //USE_LAZY_REMOVAL - - - - -} - - -template -bool btAxisSweep3Internal::testAabbOverlap(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1) -{ - const Handle* pHandleA = static_cast(proxy0); - const Handle* pHandleB = static_cast(proxy1); - - //optimization 1: check the array index (memory address), instead of the m_pos - - for (int axis = 0; axis < 3; axis++) - { - if (pHandleA->m_maxEdges[axis] < pHandleB->m_minEdges[axis] || - pHandleB->m_maxEdges[axis] < pHandleA->m_minEdges[axis]) - { - return false; - } - } - return true; -} - -template -bool btAxisSweep3Internal::testOverlap(int ignoreAxis,const Handle* pHandleA, const Handle* pHandleB) -{ - //optimization 1: check the array index (memory address), instead of the m_pos - - for (int axis = 0; axis < 3; axis++) - { - if (axis != ignoreAxis) - { - if (pHandleA->m_maxEdges[axis] < pHandleB->m_minEdges[axis] || - pHandleB->m_maxEdges[axis] < pHandleA->m_minEdges[axis]) - { - return false; - } - } - } - - //optimization 2: only 2 axis need to be tested (conflicts with 'delayed removal' optimization) - - /*for (int axis = 0; axis < 3; axis++) - { - if (m_pEdges[axis][pHandleA->m_maxEdges[axis]].m_pos < m_pEdges[axis][pHandleB->m_minEdges[axis]].m_pos || - m_pEdges[axis][pHandleB->m_maxEdges[axis]].m_pos < m_pEdges[axis][pHandleA->m_minEdges[axis]].m_pos) - { - return false; - } - } - */ - - return true; -} - -template -void btAxisSweep3Internal::updateHandle(BP_FP_INT_TYPE handle, const btPoint3& aabbMin,const btPoint3& aabbMax,btDispatcher* dispatcher) -{ -// assert(bounds.IsFinite()); - //assert(bounds.HasVolume()); - - Handle* pHandle = getHandle(handle); - - // quantize the new bounds - BP_FP_INT_TYPE min[3], max[3]; - quantize(min, aabbMin, 0); - quantize(max, aabbMax, 1); - - // update changed edges - for (int axis = 0; axis < 3; axis++) - { - BP_FP_INT_TYPE emin = pHandle->m_minEdges[axis]; - BP_FP_INT_TYPE emax = pHandle->m_maxEdges[axis]; - - int dmin = (int)min[axis] - (int)m_pEdges[axis][emin].m_pos; - int dmax = (int)max[axis] - (int)m_pEdges[axis][emax].m_pos; - - m_pEdges[axis][emin].m_pos = min[axis]; - m_pEdges[axis][emax].m_pos = max[axis]; - - // expand (only adds overlaps) - if (dmin < 0) - sortMinDown(axis, emin,dispatcher,true); - - if (dmax > 0) - sortMaxUp(axis, emax,dispatcher,true); - - // shrink (only removes overlaps) - if (dmin > 0) - sortMinUp(axis, emin,dispatcher,true); - - if (dmax < 0) - sortMaxDown(axis, emax,dispatcher,true); - -#ifdef DEBUG_BROADPHASE - debugPrintAxis(axis); -#endif //DEBUG_BROADPHASE - } - - -} - - - - -// sorting a min edge downwards can only ever *add* overlaps -template -void btAxisSweep3Internal::sortMinDown(int axis, BP_FP_INT_TYPE edge, btDispatcher* dispatcher, bool updateOverlaps) -{ - - Edge* pEdge = m_pEdges[axis] + edge; - Edge* pPrev = pEdge - 1; - Handle* pHandleEdge = getHandle(pEdge->m_handle); - - while (pEdge->m_pos < pPrev->m_pos) - { - Handle* pHandlePrev = getHandle(pPrev->m_handle); - - if (pPrev->IsMax()) - { - // if previous edge is a maximum check the bounds and add an overlap if necessary - if (updateOverlaps && testOverlap(axis,pHandleEdge, pHandlePrev)) - { - m_pairCache->addOverlappingPair(pHandleEdge,pHandlePrev); - if (m_userPairCallback) - m_userPairCallback->addOverlappingPair(pHandleEdge,pHandlePrev); - - //AddOverlap(pEdge->m_handle, pPrev->m_handle); - - } - - // update edge reference in other handle - pHandlePrev->m_maxEdges[axis]++; - } - else - pHandlePrev->m_minEdges[axis]++; - - pHandleEdge->m_minEdges[axis]--; - - // swap the edges - Edge swap = *pEdge; - *pEdge = *pPrev; - *pPrev = swap; - - // decrement - pEdge--; - pPrev--; - } - -#ifdef DEBUG_BROADPHASE - debugPrintAxis(axis); -#endif //DEBUG_BROADPHASE - -} - -// sorting a min edge upwards can only ever *remove* overlaps -template -void btAxisSweep3Internal::sortMinUp(int axis, BP_FP_INT_TYPE edge, btDispatcher* dispatcher, bool updateOverlaps) -{ - Edge* pEdge = m_pEdges[axis] + edge; - Edge* pNext = pEdge + 1; - Handle* pHandleEdge = getHandle(pEdge->m_handle); - - while (pNext->m_handle && (pEdge->m_pos >= pNext->m_pos)) - { - Handle* pHandleNext = getHandle(pNext->m_handle); - - if (pNext->IsMax()) - { -#ifndef USE_LAZY_REMOVAL - // if next edge is maximum remove any overlap between the two handles - if (updateOverlaps) - { - Handle* handle0 = getHandle(pEdge->m_handle); - Handle* handle1 = getHandle(pNext->m_handle); - - m_pairCache->removeOverlappingPair(handle0,handle1,dispatcher); - if (m_userPairCallback) - m_userPairCallback->removeOverlappingPair(handle0,handle1); - - } -#endif //USE_LAZY_REMOVAL - - // update edge reference in other handle - pHandleNext->m_maxEdges[axis]--; - } - else - pHandleNext->m_minEdges[axis]--; - - pHandleEdge->m_minEdges[axis]++; - - // swap the edges - Edge swap = *pEdge; - *pEdge = *pNext; - *pNext = swap; - - // increment - pEdge++; - pNext++; - } - - -} - -// sorting a max edge downwards can only ever *remove* overlaps -template -void btAxisSweep3Internal::sortMaxDown(int axis, BP_FP_INT_TYPE edge, btDispatcher* dispatcher, bool updateOverlaps) -{ - - Edge* pEdge = m_pEdges[axis] + edge; - Edge* pPrev = pEdge - 1; - Handle* pHandleEdge = getHandle(pEdge->m_handle); - - while (pEdge->m_pos < pPrev->m_pos) - { - Handle* pHandlePrev = getHandle(pPrev->m_handle); - - if (!pPrev->IsMax()) - { - // if previous edge was a minimum remove any overlap between the two handles - if (updateOverlaps) - { - //this is done during the overlappingpairarray iteration/narrowphase collision -#ifndef USE_LAZY_REMOVAL - Handle* handle0 = getHandle(pEdge->m_handle); - Handle* handle1 = getHandle(pPrev->m_handle); - m_pairCache->removeOverlappingPair(handle0,handle1,dispatcher); - if (m_userPairCallback) - m_userPairCallback->removeOverlappingPair(handle0,handle1); - -#endif //USE_LAZY_REMOVAL - - } - - // update edge reference in other handle - pHandlePrev->m_minEdges[axis]++;; - } - else - pHandlePrev->m_maxEdges[axis]++; - - pHandleEdge->m_maxEdges[axis]--; - - // swap the edges - Edge swap = *pEdge; - *pEdge = *pPrev; - *pPrev = swap; - - // decrement - pEdge--; - pPrev--; - } - - -#ifdef DEBUG_BROADPHASE - debugPrintAxis(axis); -#endif //DEBUG_BROADPHASE - -} - -// sorting a max edge upwards can only ever *add* overlaps -template -void btAxisSweep3Internal::sortMaxUp(int axis, BP_FP_INT_TYPE edge, btDispatcher* dispatcher, bool updateOverlaps) -{ - Edge* pEdge = m_pEdges[axis] + edge; - Edge* pNext = pEdge + 1; - Handle* pHandleEdge = getHandle(pEdge->m_handle); - - while (pNext->m_handle && (pEdge->m_pos >= pNext->m_pos)) - { - Handle* pHandleNext = getHandle(pNext->m_handle); - - if (!pNext->IsMax()) - { - // if next edge is a minimum check the bounds and add an overlap if necessary - if (updateOverlaps && testOverlap(axis, pHandleEdge, pHandleNext)) - { - Handle* handle0 = getHandle(pEdge->m_handle); - Handle* handle1 = getHandle(pNext->m_handle); - m_pairCache->addOverlappingPair(handle0,handle1); - if (m_userPairCallback) - m_userPairCallback->addOverlappingPair(handle0,handle1); - } - - // update edge reference in other handle - pHandleNext->m_minEdges[axis]--; - } - else - pHandleNext->m_maxEdges[axis]--; - - pHandleEdge->m_maxEdges[axis]++; - - // swap the edges - Edge swap = *pEdge; - *pEdge = *pNext; - *pNext = swap; - - // increment - pEdge++; - pNext++; - } - -} - - - -//////////////////////////////////////////////////////////////////// - - -/// btAxisSweep3 is an efficient implementation of the 3d axis sweep and prune broadphase. -/// It uses arrays rather then lists for storage of the 3 axis. Also it operates using 16 bit integer coordinates instead of floats. -/// For large worlds and many objects, use bt32BitAxisSweep3 instead. bt32BitAxisSweep3 has higher precision and allows more then 16384 objects at the cost of more memory and bit of performance. -class btAxisSweep3 : public btAxisSweep3Internal -{ -public: - - btAxisSweep3(const btPoint3& worldAabbMin,const btPoint3& worldAabbMax, unsigned short int maxHandles = 16384, btOverlappingPairCache* pairCache = 0); - -}; - -/// bt32BitAxisSweep3 allows higher precision quantization and more objects compared to the btAxisSweep3 sweep and prune. -/// This comes at the cost of more memory per handle, and a bit slower performance. -/// It uses arrays rather then lists for storage of the 3 axis. -class bt32BitAxisSweep3 : public btAxisSweep3Internal -{ -public: - - bt32BitAxisSweep3(const btPoint3& worldAabbMin,const btPoint3& worldAabbMax, unsigned int maxHandles = 1500000, btOverlappingPairCache* pairCache = 0); - -}; - -#endif - diff --git a/extern/bullet2/src/BulletCollision/BroadphaseCollision/btBroadphaseInterface.h b/extern/bullet2/src/BulletCollision/BroadphaseCollision/btBroadphaseInterface.h deleted file mode 100644 index 97ba20743d2..00000000000 --- a/extern/bullet2/src/BulletCollision/BroadphaseCollision/btBroadphaseInterface.h +++ /dev/null @@ -1,46 +0,0 @@ -/* -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 BROADPHASE_INTERFACE_H -#define BROADPHASE_INTERFACE_H - - - -struct btDispatcherInfo; -class btDispatcher; -#include "btBroadphaseProxy.h" -class btOverlappingPairCache; - -#include "LinearMath/btVector3.h" - -///BroadphaseInterface for aabb-overlapping object pairs -class btBroadphaseInterface -{ -public: - virtual ~btBroadphaseInterface() {} - - virtual btBroadphaseProxy* createProxy( const btVector3& aabbMin, const btVector3& aabbMax,int shapeType,void* userPtr, short int collisionFilterGroup,short int collisionFilterMask, btDispatcher* dispatcher) =0; - virtual void destroyProxy(btBroadphaseProxy* proxy,btDispatcher* dispatcher)=0; - virtual void setAabb(btBroadphaseProxy* proxy,const btVector3& aabbMin,const btVector3& aabbMax, btDispatcher* dispatcher)=0; - - ///calculateOverlappingPairs is optional: incremental algorithms (sweep and prune) might do it during the set aabb - virtual void calculateOverlappingPairs(btDispatcher* dispatcher)=0; - - virtual btOverlappingPairCache* getOverlappingPairCache()=0; - virtual const btOverlappingPairCache* getOverlappingPairCache() const =0; - -}; - -#endif //BROADPHASE_INTERFACE_H diff --git a/extern/bullet2/src/BulletCollision/BroadphaseCollision/btBroadphaseProxy.cpp b/extern/bullet2/src/BulletCollision/BroadphaseCollision/btBroadphaseProxy.cpp deleted file mode 100644 index f4d7341f8dd..00000000000 --- a/extern/bullet2/src/BulletCollision/BroadphaseCollision/btBroadphaseProxy.cpp +++ /dev/null @@ -1,17 +0,0 @@ -/* -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 "btBroadphaseProxy.h" - diff --git a/extern/bullet2/src/BulletCollision/BroadphaseCollision/btBroadphaseProxy.h b/extern/bullet2/src/BulletCollision/BroadphaseCollision/btBroadphaseProxy.h deleted file mode 100644 index f0a462cce02..00000000000 --- a/extern/bullet2/src/BulletCollision/BroadphaseCollision/btBroadphaseProxy.h +++ /dev/null @@ -1,232 +0,0 @@ -/* -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 BROADPHASE_PROXY_H -#define BROADPHASE_PROXY_H - -#include "LinearMath/btScalar.h" //for SIMD_FORCE_INLINE -#include "LinearMath/btAlignedAllocator.h" - - -/// btDispatcher uses these types -/// IMPORTANT NOTE:The types are ordered polyhedral, implicit convex and concave -/// to facilitate type checking -enum BroadphaseNativeTypes -{ -// polyhedral convex shapes - BOX_SHAPE_PROXYTYPE, - TRIANGLE_SHAPE_PROXYTYPE, - TETRAHEDRAL_SHAPE_PROXYTYPE, - CONVEX_TRIANGLEMESH_SHAPE_PROXYTYPE, - CONVEX_HULL_SHAPE_PROXYTYPE, -//implicit convex shapes -IMPLICIT_CONVEX_SHAPES_START_HERE, - SPHERE_SHAPE_PROXYTYPE, - MULTI_SPHERE_SHAPE_PROXYTYPE, - CAPSULE_SHAPE_PROXYTYPE, - CONE_SHAPE_PROXYTYPE, - CONVEX_SHAPE_PROXYTYPE, - CYLINDER_SHAPE_PROXYTYPE, - UNIFORM_SCALING_SHAPE_PROXYTYPE, - MINKOWSKI_SUM_SHAPE_PROXYTYPE, - MINKOWSKI_DIFFERENCE_SHAPE_PROXYTYPE, -//concave shapes -CONCAVE_SHAPES_START_HERE, - //keep all the convex shapetype below here, for the check IsConvexShape in broadphase proxy! - TRIANGLE_MESH_SHAPE_PROXYTYPE, - ///used for demo integration FAST/Swift collision library and Bullet - FAST_CONCAVE_MESH_PROXYTYPE, - //terrain - TERRAIN_SHAPE_PROXYTYPE, -///Used for GIMPACT Trimesh integration - GIMPACT_SHAPE_PROXYTYPE, - - EMPTY_SHAPE_PROXYTYPE, - STATIC_PLANE_PROXYTYPE, -CONCAVE_SHAPES_END_HERE, - - COMPOUND_SHAPE_PROXYTYPE, - - MAX_BROADPHASE_COLLISION_TYPES -}; - - -///btBroadphaseProxy -ATTRIBUTE_ALIGNED16(struct) btBroadphaseProxy -{ - -BT_DECLARE_ALIGNED_ALLOCATOR(); - - ///optional filtering to cull potential collisions - enum CollisionFilterGroups - { - DefaultFilter = 1, - StaticFilter = 2, - KinematicFilter = 4, - DebrisFilter = 8, - SensorTrigger = 16, - AllFilter = DefaultFilter | StaticFilter | KinematicFilter | DebrisFilter | SensorTrigger - }; - - //Usually the client btCollisionObject or Rigidbody class - void* m_clientObject; - - ///in the case of btMultiSapBroadphase, we store the collifionFilterGroup/Mask in the m_multiSapParentProxy - union - { - struct - { - short int m_collisionFilterGroup; - short int m_collisionFilterMask; - }; - - void* m_multiSapParentProxy; - - }; - - int m_uniqueId;//m_uniqueId is introduced for paircache. could get rid of this, by calculating the address offset etc. - int m_unusedPadding; //making the structure 16 bytes, better for alignment etc. - - SIMD_FORCE_INLINE int getUid() - { - return m_uniqueId;//(int)this; - } - - //used for memory pools - btBroadphaseProxy() :m_clientObject(0){} - - btBroadphaseProxy(void* userPtr,short int collisionFilterGroup, short int collisionFilterMask) - :m_clientObject(userPtr), - m_collisionFilterGroup(collisionFilterGroup), - m_collisionFilterMask(collisionFilterMask) - { - } - - - - static SIMD_FORCE_INLINE bool isPolyhedral(int proxyType) - { - return (proxyType < IMPLICIT_CONVEX_SHAPES_START_HERE); - } - - static SIMD_FORCE_INLINE bool isConvex(int proxyType) - { - return (proxyType < CONCAVE_SHAPES_START_HERE); - } - - static SIMD_FORCE_INLINE bool isConcave(int proxyType) - { - return ((proxyType > CONCAVE_SHAPES_START_HERE) && - (proxyType < CONCAVE_SHAPES_END_HERE)); - } - static SIMD_FORCE_INLINE bool isCompound(int proxyType) - { - return (proxyType == COMPOUND_SHAPE_PROXYTYPE); - } - static SIMD_FORCE_INLINE bool isInfinite(int proxyType) - { - return (proxyType == STATIC_PLANE_PROXYTYPE); - } - -} -; - -class btCollisionAlgorithm; - -struct btBroadphaseProxy; - - - -/// contains a pair of aabb-overlapping objects -ATTRIBUTE_ALIGNED16(struct) btBroadphasePair -{ - btBroadphasePair () - : - m_pProxy0(0), - m_pProxy1(0), - m_algorithm(0), - m_userInfo(0) - { - } - -BT_DECLARE_ALIGNED_ALLOCATOR(); - - btBroadphasePair(const btBroadphasePair& other) - : m_pProxy0(other.m_pProxy0), - m_pProxy1(other.m_pProxy1), - m_algorithm(other.m_algorithm), - m_userInfo(other.m_userInfo) - { - } - btBroadphasePair(btBroadphaseProxy& proxy0,btBroadphaseProxy& proxy1) - { - - //keep them sorted, so the std::set operations work - if (&proxy0 < &proxy1) - { - m_pProxy0 = &proxy0; - m_pProxy1 = &proxy1; - } - else - { - m_pProxy0 = &proxy1; - m_pProxy1 = &proxy0; - } - - m_algorithm = 0; - m_userInfo = 0; - - } - - btBroadphaseProxy* m_pProxy0; - btBroadphaseProxy* m_pProxy1; - - mutable btCollisionAlgorithm* m_algorithm; - mutable void* m_userInfo; - -}; - -/* -//comparison for set operation, see Solid DT_Encounter -SIMD_FORCE_INLINE bool operator<(const btBroadphasePair& a, const btBroadphasePair& b) -{ - return a.m_pProxy0 < b.m_pProxy0 || - (a.m_pProxy0 == b.m_pProxy0 && a.m_pProxy1 < b.m_pProxy1); -} -*/ - - - -class btBroadphasePairSortPredicate -{ - public: - - bool operator() ( const btBroadphasePair& a, const btBroadphasePair& b ) - { - return a.m_pProxy0 > b.m_pProxy0 || - (a.m_pProxy0 == b.m_pProxy0 && a.m_pProxy1 > b.m_pProxy1) || - (a.m_pProxy0 == b.m_pProxy0 && a.m_pProxy1 == b.m_pProxy1 && a.m_algorithm > b.m_algorithm); - } -}; - - -SIMD_FORCE_INLINE bool operator==(const btBroadphasePair& a, const btBroadphasePair& b) -{ - return (a.m_pProxy0 == b.m_pProxy0) && (a.m_pProxy1 == b.m_pProxy1); -} - - -#endif //BROADPHASE_PROXY_H - diff --git a/extern/bullet2/src/BulletCollision/BroadphaseCollision/btCollisionAlgorithm.cpp b/extern/bullet2/src/BulletCollision/BroadphaseCollision/btCollisionAlgorithm.cpp deleted file mode 100644 index c95d1be0f2c..00000000000 --- a/extern/bullet2/src/BulletCollision/BroadphaseCollision/btCollisionAlgorithm.cpp +++ /dev/null @@ -1,23 +0,0 @@ -/* -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 "btCollisionAlgorithm.h" -#include "btDispatcher.h" - -btCollisionAlgorithm::btCollisionAlgorithm(const btCollisionAlgorithmConstructionInfo& ci) -{ - m_dispatcher = ci.m_dispatcher1; -} - diff --git a/extern/bullet2/src/BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h b/extern/bullet2/src/BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h deleted file mode 100644 index 610eab4ce5e..00000000000 --- a/extern/bullet2/src/BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h +++ /dev/null @@ -1,77 +0,0 @@ -/* -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 COLLISION_ALGORITHM_H -#define COLLISION_ALGORITHM_H - -#include "LinearMath/btScalar.h" - -struct btBroadphaseProxy; -class btDispatcher; -class btManifoldResult; -class btCollisionObject; -struct btDispatcherInfo; -class btPersistentManifold; - - -struct btCollisionAlgorithmConstructionInfo -{ - btCollisionAlgorithmConstructionInfo() - :m_dispatcher1(0), - m_manifold(0) - { - } - btCollisionAlgorithmConstructionInfo(btDispatcher* dispatcher,int temp) - :m_dispatcher1(dispatcher) - { - (void)temp; - } - - btDispatcher* m_dispatcher1; - btPersistentManifold* m_manifold; - - int getDispatcherId(); - -}; - - -///btCollisionAlgorithm is an collision interface that is compatible with the Broadphase and btDispatcher. -///It is persistent over frames -class btCollisionAlgorithm -{ - -protected: - - btDispatcher* m_dispatcher; - -protected: - int getDispatcherId(); - -public: - - btCollisionAlgorithm() {}; - - btCollisionAlgorithm(const btCollisionAlgorithmConstructionInfo& ci); - - virtual ~btCollisionAlgorithm() {}; - - virtual void processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut) = 0; - - virtual btScalar calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut) = 0; - -}; - - -#endif //COLLISION_ALGORITHM_H diff --git a/extern/bullet2/src/BulletCollision/BroadphaseCollision/btDispatcher.cpp b/extern/bullet2/src/BulletCollision/BroadphaseCollision/btDispatcher.cpp deleted file mode 100644 index 20768225b3a..00000000000 --- a/extern/bullet2/src/BulletCollision/BroadphaseCollision/btDispatcher.cpp +++ /dev/null @@ -1,22 +0,0 @@ -/* -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 "btDispatcher.h" - -btDispatcher::~btDispatcher() -{ - -} - diff --git a/extern/bullet2/src/BulletCollision/BroadphaseCollision/btDispatcher.h b/extern/bullet2/src/BulletCollision/BroadphaseCollision/btDispatcher.h deleted file mode 100644 index daea11f7788..00000000000 --- a/extern/bullet2/src/BulletCollision/BroadphaseCollision/btDispatcher.h +++ /dev/null @@ -1,99 +0,0 @@ -/* -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 _DISPATCHER_H -#define _DISPATCHER_H - -#include "LinearMath/btScalar.h" - -class btCollisionAlgorithm; -struct btBroadphaseProxy; -class btRigidBody; -class btCollisionObject; -class btOverlappingPairCache; - - -class btPersistentManifold; -class btStackAlloc; - -struct btDispatcherInfo -{ - enum DispatchFunc - { - DISPATCH_DISCRETE = 1, - DISPATCH_CONTINUOUS - }; - btDispatcherInfo() - :m_timeStep(btScalar(0.)), - m_stepCount(0), - m_dispatchFunc(DISPATCH_DISCRETE), - m_timeOfImpact(btScalar(1.)), - m_useContinuous(false), - m_debugDraw(0), - m_enableSatConvex(false), - m_enableSPU(false), - m_stackAllocator(0) - { - - } - btScalar m_timeStep; - int m_stepCount; - int m_dispatchFunc; - btScalar m_timeOfImpact; - bool m_useContinuous; - class btIDebugDraw* m_debugDraw; - bool m_enableSatConvex; - bool m_enableSPU; - btStackAlloc* m_stackAllocator; - -}; - -/// btDispatcher can be used in combination with broadphase to dispatch overlapping pairs. -/// For example for pairwise collision detection or user callbacks (game logic). -class btDispatcher -{ - - -public: - virtual ~btDispatcher() ; - - virtual btCollisionAlgorithm* findAlgorithm(btCollisionObject* body0,btCollisionObject* body1,btPersistentManifold* sharedManifold=0) = 0; - - virtual btPersistentManifold* getNewManifold(void* body0,void* body1)=0; - - virtual void releaseManifold(btPersistentManifold* manifold)=0; - - virtual void clearManifold(btPersistentManifold* manifold)=0; - - virtual bool needsCollision(btCollisionObject* body0,btCollisionObject* body1) = 0; - - virtual bool needsResponse(btCollisionObject* body0,btCollisionObject* body1)=0; - - virtual void dispatchAllCollisionPairs(btOverlappingPairCache* pairCache,btDispatcherInfo& dispatchInfo,btDispatcher* dispatcher)=0; - - virtual int getNumManifolds() const = 0; - - virtual btPersistentManifold* getManifoldByIndexInternal(int index) = 0; - - virtual btPersistentManifold** getInternalManifoldPointer() = 0; - - virtual void* allocateCollisionAlgorithm(int size) = 0; - - virtual void freeCollisionAlgorithm(void* ptr) = 0; - -}; - - -#endif //_DISPATCHER_H diff --git a/extern/bullet2/src/BulletCollision/BroadphaseCollision/btMultiSapBroadphase.cpp b/extern/bullet2/src/BulletCollision/BroadphaseCollision/btMultiSapBroadphase.cpp deleted file mode 100644 index 41406ff49f9..00000000000 --- a/extern/bullet2/src/BulletCollision/BroadphaseCollision/btMultiSapBroadphase.cpp +++ /dev/null @@ -1,204 +0,0 @@ -/* -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 "btMultiSapBroadphase.h" - -#include "btSimpleBroadphase.h" -#include "LinearMath/btAabbUtil2.h" - -/// btSapBroadphaseArray m_sapBroadphases; - -/// btOverlappingPairCache* m_overlappingPairs; -extern int gOverlappingPairs; - -btMultiSapBroadphase::btMultiSapBroadphase(int maxProxies,btOverlappingPairCache* pairCache) -:m_overlappingPairs(pairCache), -m_ownsPairCache(false), -m_invalidPair(0) -{ - if (!m_overlappingPairs) - { - m_ownsPairCache = true; - void* mem = btAlignedAlloc(sizeof(btOverlappingPairCache),16); - m_overlappingPairs = new (mem)btOverlappingPairCache(); - } - - struct btMultiSapOverlapFilterCallback : public btOverlapFilterCallback - { - virtual ~btMultiSapOverlapFilterCallback() - {} - // return true when pairs need collision - virtual bool needBroadphaseCollision(btBroadphaseProxy* childProxy0,btBroadphaseProxy* childProxy1) const - { - btMultiSapBroadphase::btMultiSapProxy* multiSapProxy0 = (btMultiSapBroadphase::btMultiSapProxy*)childProxy0->m_multiSapParentProxy; - btMultiSapBroadphase::btMultiSapProxy* multiSapProxy1 = (btMultiSapBroadphase::btMultiSapProxy*)childProxy1->m_multiSapParentProxy; - - bool collides = (multiSapProxy0->m_collisionFilterGroup & multiSapProxy1->m_collisionFilterMask) != 0; - collides = collides && (multiSapProxy1->m_collisionFilterGroup & multiSapProxy0->m_collisionFilterMask); - - return collides; - } - }; - - void* mem = btAlignedAlloc(sizeof(btMultiSapOverlapFilterCallback),16); - m_filterCallback = new (mem)btMultiSapOverlapFilterCallback(); - - m_overlappingPairs->setOverlapFilterCallback(m_filterCallback); - mem = btAlignedAlloc(sizeof(btSimpleBroadphase),16); - m_simpleBroadphase = new (mem) btSimpleBroadphase(maxProxies,m_overlappingPairs); -} - -btMultiSapBroadphase::~btMultiSapBroadphase() -{ - if (m_ownsPairCache) - { - btAlignedFree(m_overlappingPairs); - } -} - -btBroadphaseProxy* btMultiSapBroadphase::createProxy( const btVector3& aabbMin, const btVector3& aabbMax,int shapeType,void* userPtr, short int collisionFilterGroup,short int collisionFilterMask, btDispatcher* dispatcher) -{ - void* mem = btAlignedAlloc(sizeof(btMultiSapProxy),16); - btMultiSapProxy* proxy = new (mem)btMultiSapProxy(aabbMin, aabbMax,shapeType,userPtr, collisionFilterGroup,collisionFilterMask); - m_multiSapProxies.push_back(proxy); - - ///we don't pass the userPtr but our multisap proxy. We need to patch this, before processing an actual collision - ///this is needed to be able to calculate the aabb overlap - btBroadphaseProxy* simpleProxy = m_simpleBroadphase->createProxy(aabbMin,aabbMax,shapeType,userPtr,collisionFilterGroup,collisionFilterMask, dispatcher); - simpleProxy->m_multiSapParentProxy = proxy; - - mem = btAlignedAlloc(sizeof(btChildProxy),16); - btChildProxy* childProxyRef = new btChildProxy(); - childProxyRef->m_proxy = simpleProxy; - childProxyRef->m_childBroadphase = m_simpleBroadphase; - proxy->m_childProxies.push_back(childProxyRef); - - ///this should deal with inserting/removal into child broadphases - setAabb(proxy,aabbMin,aabbMax,dispatcher); - return proxy; -} - -void btMultiSapBroadphase::destroyProxy(btBroadphaseProxy* proxy,btDispatcher* dispatcher) -{ - ///not yet - btAssert(0); - -} -void btMultiSapBroadphase::setAabb(btBroadphaseProxy* proxy,const btVector3& aabbMin,const btVector3& aabbMax, btDispatcher* dispatcher) -{ - btMultiSapProxy* multiProxy = static_cast(proxy); - multiProxy->m_aabbMin = aabbMin; - multiProxy->m_aabbMax = aabbMax; - - for (int i=0;im_childProxies.size();i++) - { - btChildProxy* childProxyRef = multiProxy->m_childProxies[i]; - childProxyRef->m_childBroadphase->setAabb(childProxyRef->m_proxy,aabbMin,aabbMax,dispatcher); - } - -} - - ///calculateOverlappingPairs is optional: incremental algorithms (sweep and prune) might do it during the set aabb -void btMultiSapBroadphase::calculateOverlappingPairs(btDispatcher* dispatcher) -{ - m_simpleBroadphase->calculateOverlappingPairs(dispatcher); - -#ifndef USE_HASH_PAIRCACHE - - btBroadphasePairArray& overlappingPairArray = m_overlappingPairs->getOverlappingPairArray(); - - //perform a sort, to find duplicates and to sort 'invalid' pairs to the end - overlappingPairArray.heapSort(btBroadphasePairSortPredicate()); - - overlappingPairArray.resize(overlappingPairArray.size() - m_invalidPair); - m_invalidPair = 0; - - - btBroadphasePair previousPair; - previousPair.m_pProxy0 = 0; - previousPair.m_pProxy1 = 0; - previousPair.m_algorithm = 0; - - int i; - - for (i=0;iprocessOverlap(pair); - } else - { - needsRemoval = true; - } - } else - { - //remove duplicate - needsRemoval = true; - //should have no algorithm - btAssert(!pair.m_algorithm); - } - - if (needsRemoval) - { - m_overlappingPairs->cleanOverlappingPair(pair,dispatcher); - - // m_overlappingPairArray.swap(i,m_overlappingPairArray.size()-1); - // m_overlappingPairArray.pop_back(); - pair.m_pProxy0 = 0; - pair.m_pProxy1 = 0; - m_invalidPair++; - gOverlappingPairs--; - } - - } - -///if you don't like to skip the invalid pairs in the array, execute following code: -#define CLEAN_INVALID_PAIRS 1 -#ifdef CLEAN_INVALID_PAIRS - - //perform a sort, to sort 'invalid' pairs to the end - overlappingPairArray.heapSort(btBroadphasePairSortPredicate()); - - overlappingPairArray.resize(overlappingPairArray.size() - m_invalidPair); - m_invalidPair = 0; -#endif//CLEAN_INVALID_PAIRS - -#endif //USE_HASH_PAIRCACHE - -} - - -bool btMultiSapBroadphase::testAabbOverlap(btBroadphaseProxy* childProxy0,btBroadphaseProxy* childProxy1) -{ - btMultiSapProxy* multiSapProxy0 = (btMultiSapProxy*)childProxy0->m_multiSapParentProxy; - btMultiSapProxy* multiSapProxy1 = (btMultiSapProxy*)childProxy1->m_multiSapParentProxy; - - return TestAabbAgainstAabb2(multiSapProxy0->m_aabbMin,multiSapProxy0->m_aabbMax, - multiSapProxy1->m_aabbMin,multiSapProxy1->m_aabbMax); - -} diff --git a/extern/bullet2/src/BulletCollision/BroadphaseCollision/btMultiSapBroadphase.h b/extern/bullet2/src/BulletCollision/BroadphaseCollision/btMultiSapBroadphase.h deleted file mode 100644 index 1ee609b8d1f..00000000000 --- a/extern/bullet2/src/BulletCollision/BroadphaseCollision/btMultiSapBroadphase.h +++ /dev/null @@ -1,119 +0,0 @@ -/* -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 BT_MULTI_SAP_BROADPHASE -#define BT_MULTI_SAP_BROADPHASE - -#include "btBroadphaseInterface.h" -#include "LinearMath/btAlignedObjectArray.h" -#include "btOverlappingPairCache.h" - -class btAxisSweep3; -class btSimpleBroadphase; - - -typedef btAlignedObjectArray btSapBroadphaseArray; - -///multi SAP broadphase -///See http://www.continuousphysics.com/Bullet/phpBB2/viewtopic.php?t=328 -///and http://www.continuousphysics.com/Bullet/phpBB2/viewtopic.php?t=1329 -class btMultiSapBroadphase :public btBroadphaseInterface -{ - btSapBroadphaseArray m_sapBroadphases; - - btSimpleBroadphase* m_simpleBroadphase; - - btOverlappingPairCache* m_overlappingPairs; - - bool m_ownsPairCache; - - btOverlapFilterCallback* m_filterCallback; - - int m_invalidPair; - - struct btChildProxy - { - btBroadphaseProxy* m_proxy; - btBroadphaseInterface* m_childBroadphase; - }; - -public: - - struct btMultiSapProxy : public btBroadphaseProxy - { - - ///array with all the entries that this proxy belongs to - btAlignedObjectArray m_childProxies; - btVector3 m_aabbMin; - btVector3 m_aabbMax; - - int m_shapeType; - void* m_userPtr; - short int m_collisionFilterGroup; - short int m_collisionFilterMask; - - btMultiSapProxy(const btVector3& aabbMin, const btVector3& aabbMax,int shapeType,void* userPtr, short int collisionFilterGroup,short int collisionFilterMask) - :m_aabbMin(aabbMin), - m_aabbMax(aabbMax), - m_shapeType(shapeType), - m_userPtr(userPtr), - m_collisionFilterGroup(collisionFilterGroup), - m_collisionFilterMask(collisionFilterMask) - { - - } - - - }; - -protected: - - btAlignedObjectArray m_multiSapProxies; - -public: - - btMultiSapBroadphase(int maxProxies = 16384,btOverlappingPairCache* pairCache=0); - - btSapBroadphaseArray getBroadphaseArray() - { - return m_sapBroadphases; - } - - const btSapBroadphaseArray getBroadphaseArray() const - { - return m_sapBroadphases; - } - - virtual ~btMultiSapBroadphase(); - - virtual btBroadphaseProxy* createProxy( const btVector3& aabbMin, const btVector3& aabbMax,int shapeType,void* userPtr, short int collisionFilterGroup,short int collisionFilterMask, btDispatcher* dispatcher); - virtual void destroyProxy(btBroadphaseProxy* proxy,btDispatcher* dispatcher); - virtual void setAabb(btBroadphaseProxy* proxy,const btVector3& aabbMin,const btVector3& aabbMax, btDispatcher* dispatcher); - - ///calculateOverlappingPairs is optional: incremental algorithms (sweep and prune) might do it during the set aabb - virtual void calculateOverlappingPairs(btDispatcher* dispatcher); - - bool testAabbOverlap(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1); - - virtual btOverlappingPairCache* getOverlappingPairCache() - { - return m_overlappingPairs; - } - virtual const btOverlappingPairCache* getOverlappingPairCache() const - { - return m_overlappingPairs; - } -}; - -#endif //BT_MULTI_SAP_BROADPHASE diff --git a/extern/bullet2/src/BulletCollision/BroadphaseCollision/btOverlappingPairCache.cpp b/extern/bullet2/src/BulletCollision/BroadphaseCollision/btOverlappingPairCache.cpp deleted file mode 100644 index e4ef043f064..00000000000 --- a/extern/bullet2/src/BulletCollision/BroadphaseCollision/btOverlappingPairCache.cpp +++ /dev/null @@ -1,474 +0,0 @@ - -/* -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 "btOverlappingPairCache.h" - -#include "btDispatcher.h" -#include "btCollisionAlgorithm.h" - -int gOverlappingPairs = 0; - -int gRemovePairs =0; -int gAddedPairs =0; -int gFindPairs =0; - -btOverlappingPairCache::btOverlappingPairCache(): - m_overlapFilterCallback(0), - m_blockedForChanges(false) -{ - int initialAllocatedSize= 2; - m_overlappingPairArray.reserve(initialAllocatedSize); -#ifdef USE_HASH_PAIRCACHE - growTables(); -#endif //USE_HASH_PAIRCACHE -} - - -btOverlappingPairCache::~btOverlappingPairCache() -{ - //todo/test: show we erase/delete data, or is it automatic -} - -void btOverlappingPairCache::cleanOverlappingPair(btBroadphasePair& pair,btDispatcher* dispatcher) -{ - if (pair.m_algorithm) - { - { - pair.m_algorithm->~btCollisionAlgorithm(); - dispatcher->freeCollisionAlgorithm(pair.m_algorithm); - pair.m_algorithm=0; - } - } -} - - -void btOverlappingPairCache::cleanProxyFromPairs(btBroadphaseProxy* proxy,btDispatcher* dispatcher) -{ - - class CleanPairCallback : public btOverlapCallback - { - btBroadphaseProxy* m_cleanProxy; - btOverlappingPairCache* m_pairCache; - btDispatcher* m_dispatcher; - - public: - CleanPairCallback(btBroadphaseProxy* cleanProxy,btOverlappingPairCache* pairCache,btDispatcher* dispatcher) - :m_cleanProxy(cleanProxy), - m_pairCache(pairCache), - m_dispatcher(dispatcher) - { - } - virtual bool processOverlap(btBroadphasePair& pair) - { - if ((pair.m_pProxy0 == m_cleanProxy) || - (pair.m_pProxy1 == m_cleanProxy)) - { - m_pairCache->cleanOverlappingPair(pair,m_dispatcher); - } - return false; - } - - }; - - CleanPairCallback cleanPairs(proxy,this,dispatcher); - - processAllOverlappingPairs(&cleanPairs,dispatcher); - -} - -void btOverlappingPairCache::removeOverlappingPairsContainingProxy(btBroadphaseProxy* proxy,btDispatcher* dispatcher) -{ - - class RemovePairCallback : public btOverlapCallback - { - btBroadphaseProxy* m_obsoleteProxy; - - public: - RemovePairCallback(btBroadphaseProxy* obsoleteProxy) - :m_obsoleteProxy(obsoleteProxy) - { - } - virtual bool processOverlap(btBroadphasePair& pair) - { - return ((pair.m_pProxy0 == m_obsoleteProxy) || - (pair.m_pProxy1 == m_obsoleteProxy)); - } - - }; - - - RemovePairCallback removeCallback(proxy); - - processAllOverlappingPairs(&removeCallback,dispatcher); -} - - -#ifdef USE_HASH_PAIRCACHE - - - - - - - -btBroadphasePair* btOverlappingPairCache::findPair(btBroadphaseProxy* proxy0, btBroadphaseProxy* proxy1) -{ - gFindPairs++; - - int proxyId1 = proxy0->getUid(); - int proxyId2 = proxy1->getUid(); - - if (proxyId1 > proxyId2) - btSwap(proxyId1, proxyId2); - - int hash = getHash(proxyId1, proxyId2) & (m_overlappingPairArray.capacity()-1); - - int index = m_hashTable[hash]; - while (index != BT_NULL_PAIR && equalsPair(m_overlappingPairArray[index], proxyId1, proxyId2) == false) - { - index = m_next[index]; - } - - if (index == BT_NULL_PAIR) - { - return NULL; - } - - btAssert(index < m_overlappingPairArray.size()); - - return &m_overlappingPairArray[index]; -} - -#include - -void btOverlappingPairCache::growTables() -{ - - int newCapacity = m_overlappingPairArray.capacity(); - - if (m_hashTable.size() < newCapacity) - { - //grow hashtable and next table - int curHashtableSize = m_hashTable.size(); - - m_hashTable.resize(newCapacity); - m_next.resize(newCapacity); - - - int i; - - for (i= 0; i < newCapacity; ++i) - { - m_hashTable[i] = BT_NULL_PAIR; - } - for (i = 0; i < newCapacity; ++i) - { - m_next[i] = BT_NULL_PAIR; - } - - for(i=0;igetUid(); - int proxyId2 = pair.m_pProxy1->getUid(); - if (proxyId1 > proxyId2) - btSwap(proxyId1, proxyId2); - int hashValue = getHash(proxyId1,proxyId2) & (m_overlappingPairArray.capacity()-1); // New hash value with new mask - m_next[i] = m_hashTable[hashValue]; - m_hashTable[hashValue] = i; - } - - - } -} - -btBroadphasePair* btOverlappingPairCache::internalAddPair(btBroadphaseProxy* proxy0, btBroadphaseProxy* proxy1) -{ - int proxyId1 = proxy0->getUid(); - int proxyId2 = proxy1->getUid(); - - if (proxyId1 > proxyId2) - btSwap(proxyId1, proxyId2); - - int hash = getHash(proxyId1, proxyId2) & (m_overlappingPairArray.capacity()-1); - - - - btBroadphasePair* pair = internalFindPair(proxy0, proxy1, hash); - if (pair != NULL) - { - return pair; - } - - int count = m_overlappingPairArray.size(); - int oldCapacity = m_overlappingPairArray.capacity(); - void* mem = &m_overlappingPairArray.expand(); - int newCapacity = m_overlappingPairArray.capacity(); - - if (oldCapacity < newCapacity) - { - growTables(); - //hash with new capacity - hash = getHash(proxyId1, proxyId2) & (m_overlappingPairArray.capacity()-1); - } - - pair = new (mem) btBroadphasePair(*proxy0,*proxy1); -// pair->m_pProxy0 = proxy0; -// pair->m_pProxy1 = proxy1; - pair->m_algorithm = 0; - pair->m_userInfo = 0; - - - m_next[count] = m_hashTable[hash]; - m_hashTable[hash] = count; - - return pair; -} - - - -void* btOverlappingPairCache::removeOverlappingPair(btBroadphaseProxy* proxy0, btBroadphaseProxy* proxy1,btDispatcher* dispatcher) -{ - gRemovePairs++; - - int proxyId1 = proxy0->getUid(); - int proxyId2 = proxy1->getUid(); - - if (proxyId1 > proxyId2) - btSwap(proxyId1, proxyId2); - - int hash = getHash(proxyId1, proxyId2) & (m_overlappingPairArray.capacity()-1); - - btBroadphasePair* pair = internalFindPair(proxy0, proxy1, hash); - if (pair == NULL) - { - return 0; - } - - cleanOverlappingPair(*pair,dispatcher); - - void* userData = pair->m_userInfo; - - btAssert(pair->m_pProxy0->getUid() == proxyId1); - btAssert(pair->m_pProxy1->getUid() == proxyId2); - - int pairIndex = int(pair - &m_overlappingPairArray[0]); - btAssert(pairIndex < m_overlappingPairArray.size()); - - // Remove the pair from the hash table. - int index = m_hashTable[hash]; - btAssert(index != BT_NULL_PAIR); - - int previous = BT_NULL_PAIR; - while (index != pairIndex) - { - previous = index; - index = m_next[index]; - } - - if (previous != BT_NULL_PAIR) - { - btAssert(m_next[previous] == pairIndex); - m_next[previous] = m_next[pairIndex]; - } - else - { - m_hashTable[hash] = m_next[pairIndex]; - } - - // We now move the last pair into spot of the - // pair being removed. We need to fix the hash - // table indices to support the move. - - int lastPairIndex = m_overlappingPairArray.size() - 1; - - // If the removed pair is the last pair, we are done. - if (lastPairIndex == pairIndex) - { - m_overlappingPairArray.pop_back(); - return userData; - } - - // Remove the last pair from the hash table. - const btBroadphasePair* last = &m_overlappingPairArray[lastPairIndex]; - int lastHash = getHash(last->m_pProxy0->getUid(), last->m_pProxy1->getUid()) & (m_overlappingPairArray.capacity()-1); - - index = m_hashTable[lastHash]; - btAssert(index != BT_NULL_PAIR); - - previous = BT_NULL_PAIR; - while (index != lastPairIndex) - { - previous = index; - index = m_next[index]; - } - - if (previous != BT_NULL_PAIR) - { - btAssert(m_next[previous] == lastPairIndex); - m_next[previous] = m_next[lastPairIndex]; - } - else - { - m_hashTable[lastHash] = m_next[lastPairIndex]; - } - - // Copy the last pair into the remove pair's spot. - m_overlappingPairArray[pairIndex] = m_overlappingPairArray[lastPairIndex]; - - // Insert the last pair into the hash table - m_next[pairIndex] = m_hashTable[lastHash]; - m_hashTable[lastHash] = pairIndex; - - m_overlappingPairArray.pop_back(); - - return userData; -} -#include - -void btOverlappingPairCache::processAllOverlappingPairs(btOverlapCallback* callback,btDispatcher* dispatcher) -{ - - int i; - -// printf("m_overlappingPairArray.size()=%d\n",m_overlappingPairArray.size()); - for (i=0;iprocessOverlap(*pair)) - { - removeOverlappingPair(pair->m_pProxy0,pair->m_pProxy1,dispatcher); - - gOverlappingPairs--; - } else - { - i++; - } - } -} - -#else - - - - -void* btOverlappingPairCache::removeOverlappingPair(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1, btDispatcher* dispatcher ) -{ -#ifndef USE_LAZY_REMOVAL - - btBroadphasePair findPair(*proxy0,*proxy1); - - int findIndex = m_overlappingPairArray.findLinearSearch(findPair); - if (findIndex < m_overlappingPairArray.size()) - { - gOverlappingPairs--; - btBroadphasePair& pair = m_overlappingPairArray[findIndex]; - void* userData = pair.m_userInfo; - cleanOverlappingPair(pair,dispatcher); - - m_overlappingPairArray.swap(findIndex,m_overlappingPairArray.capacity()-1); - m_overlappingPairArray.pop_back(); - return userData; - } -#endif //USE_LAZY_REMOVAL - - return 0; -} - - - - - - - - -btBroadphasePair* btOverlappingPairCache::addOverlappingPair(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1) -{ - //don't add overlap with own - assert(proxy0 != proxy1); - - if (!needsBroadphaseCollision(proxy0,proxy1)) - return 0; - - void* mem = &m_overlappingPairArray.expand(); - btBroadphasePair* pair = new (mem) btBroadphasePair(*proxy0,*proxy1); - gOverlappingPairs++; - return pair; - -} - -///this findPair becomes really slow. Either sort the list to speedup the query, or -///use a different solution. It is mainly used for Removing overlapping pairs. Removal could be delayed. -///we could keep a linked list in each proxy, and store pair in one of the proxies (with lowest memory address) -///Also we can use a 2D bitmap, which can be useful for a future GPU implementation - btBroadphasePair* btOverlappingPairCache::findPair(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1) -{ - if (!needsBroadphaseCollision(proxy0,proxy1)) - return 0; - - btBroadphasePair tmpPair(*proxy0,*proxy1); - int findIndex = m_overlappingPairArray.findLinearSearch(tmpPair); - - if (findIndex < m_overlappingPairArray.size()) - { - //assert(it != m_overlappingPairSet.end()); - btBroadphasePair* pair = &m_overlappingPairArray[findIndex]; - return pair; - } - return 0; -} - - - - - - - - - - -#include - -void btOverlappingPairCache::processAllOverlappingPairs(btOverlapCallback* callback,btDispatcher* dispatcher) -{ - - int i; - - for (i=0;iprocessOverlap(*pair)) - { - cleanOverlappingPair(*pair,dispatcher); - - m_overlappingPairArray.swap(i,m_overlappingPairArray.capacity()-1); - m_overlappingPairArray.pop_back(); - gOverlappingPairs--; - } else - { - i++; - } - } -} - - - -#endif //USE_HASH_PAIRCACHE diff --git a/extern/bullet2/src/BulletCollision/BroadphaseCollision/btOverlappingPairCache.h b/extern/bullet2/src/BulletCollision/BroadphaseCollision/btOverlappingPairCache.h deleted file mode 100644 index a387505d1be..00000000000 --- a/extern/bullet2/src/BulletCollision/BroadphaseCollision/btOverlappingPairCache.h +++ /dev/null @@ -1,323 +0,0 @@ - -/* -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 OVERLAPPING_PAIR_CACHE_H -#define OVERLAPPING_PAIR_CACHE_H - - -#include "btBroadphaseInterface.h" -#include "btBroadphaseProxy.h" -#include "LinearMath/btPoint3.h" -#include "LinearMath/btAlignedObjectArray.h" -class btDispatcher; - -///disable the USE_HASH_PAIRCACHE define to use a pair manager that sorts the pairs to find duplicates/non-overlap -#define USE_HASH_PAIRCACHE 1 - - -struct btOverlapCallback -{ - virtual ~btOverlapCallback() - {} - //return true for deletion of the pair - virtual bool processOverlap(btBroadphasePair& pair) = 0; -}; - -struct btOverlapFilterCallback -{ - virtual ~btOverlapFilterCallback() - {} - // return true when pairs need collision - virtual bool needBroadphaseCollision(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1) const = 0; -}; - -typedef btAlignedObjectArray btBroadphasePairArray; - -#ifdef USE_HASH_PAIRCACHE - - -/// Hash-space based Pair Cache, thanks to Erin Catto, Box2D, http://www.box2d.org, and Pierre Terdiman, Codercorner, http://codercorner.com - -extern int gRemovePairs; -extern int gAddedPairs; -extern int gFindPairs; - -const int BT_NULL_PAIR=0xffffffff; - -class btOverlappingPairCache -{ - btBroadphasePairArray m_overlappingPairArray; - btOverlapFilterCallback* m_overlapFilterCallback; - bool m_blockedForChanges; - - -public: - btOverlappingPairCache(); - virtual ~btOverlappingPairCache(); - - - void removeOverlappingPairsContainingProxy(btBroadphaseProxy* proxy,btDispatcher* dispatcher); - - void* removeOverlappingPair(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1,btDispatcher* dispatcher); - - SIMD_FORCE_INLINE bool needsBroadphaseCollision(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1) const - { - if (m_overlapFilterCallback) - return m_overlapFilterCallback->needBroadphaseCollision(proxy0,proxy1); - - bool collides = (proxy0->m_collisionFilterGroup & proxy1->m_collisionFilterMask) != 0; - collides = collides && (proxy1->m_collisionFilterGroup & proxy0->m_collisionFilterMask); - - return collides; - } - - // Add a pair and return the new pair. If the pair already exists, - // no new pair is created and the old one is returned. - SIMD_FORCE_INLINE btBroadphasePair* addOverlappingPair(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1) - { - gAddedPairs++; - - if (!needsBroadphaseCollision(proxy0,proxy1)) - return 0; - - return internalAddPair(proxy0,proxy1); - } - - - - void cleanProxyFromPairs(btBroadphaseProxy* proxy,btDispatcher* dispatcher); - - - virtual void processAllOverlappingPairs(btOverlapCallback*,btDispatcher* dispatcher); - - btBroadphasePair* getOverlappingPairArrayPtr() - { - return &m_overlappingPairArray[0]; - } - - const btBroadphasePair* getOverlappingPairArrayPtr() const - { - return &m_overlappingPairArray[0]; - } - - btBroadphasePairArray& getOverlappingPairArray() - { - return m_overlappingPairArray; - } - - const btBroadphasePairArray& getOverlappingPairArray() const - { - return m_overlappingPairArray; - } - - void cleanOverlappingPair(btBroadphasePair& pair,btDispatcher* dispatcher); - - - - btBroadphasePair* findPair(btBroadphaseProxy* proxy0, btBroadphaseProxy* proxy1); - - int GetCount() const { return m_overlappingPairArray.size(); } -// btBroadphasePair* GetPairs() { return m_pairs; } - - btOverlapFilterCallback* getOverlapFilterCallback() - { - return m_overlapFilterCallback; - } - - void setOverlapFilterCallback(btOverlapFilterCallback* callback) - { - m_overlapFilterCallback = callback; - } - - int getNumOverlappingPairs() const - { - return m_overlappingPairArray.size(); - } -private: - - btBroadphasePair* internalAddPair(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1); - - void growTables(); - - SIMD_FORCE_INLINE bool equalsPair(const btBroadphasePair& pair, int proxyId1, int proxyId2) - { - return pair.m_pProxy0->getUid() == proxyId1 && pair.m_pProxy1->getUid() == proxyId2; - } - - /* - // Thomas Wang's hash, see: http://www.concentric.net/~Ttwang/tech/inthash.htm - // This assumes proxyId1 and proxyId2 are 16-bit. - SIMD_FORCE_INLINE int getHash(int proxyId1, int proxyId2) - { - int key = (proxyId2 << 16) | proxyId1; - key = ~key + (key << 15); - key = key ^ (key >> 12); - key = key + (key << 2); - key = key ^ (key >> 4); - key = key * 2057; - key = key ^ (key >> 16); - return key; - } - */ - - - - SIMD_FORCE_INLINE unsigned int getHash(unsigned int proxyId1, unsigned int proxyId2) - { - int key = ((unsigned int)proxyId1) | (((unsigned int)proxyId1) <<16); - // Thomas Wang's hash - - key += ~(key << 15); - key ^= (key >> 10); - key += (key << 3); - key ^= (key >> 6); - key += ~(key << 11); - key ^= (key >> 16); - return key; - } - - - - - - SIMD_FORCE_INLINE btBroadphasePair* internalFindPair(btBroadphaseProxy* proxy0, btBroadphaseProxy* proxy1, int hash) - { - int proxyId1 = proxy0->getUid(); - int proxyId2 = proxy1->getUid(); - if (proxyId1 > proxyId2) - btSwap(proxyId1, proxyId2); - - int index = m_hashTable[hash]; - - while( index != BT_NULL_PAIR && equalsPair(m_overlappingPairArray[index], proxyId1, proxyId2) == false) - { - index = m_next[index]; - } - - if ( index == BT_NULL_PAIR ) - { - return NULL; - } - - btAssert(index < m_overlappingPairArray.size()); - - return &m_overlappingPairArray[index]; - } - - -public: - - btAlignedObjectArray m_hashTable; - btAlignedObjectArray m_next; - -}; - - - -#else//USE_HASH_PAIRCACHE - -#define USE_LAZY_REMOVAL 1 - -///btOverlappingPairCache maintains the objects with overlapping AABB -///Typically managed by the Broadphase, Axis3Sweep or btSimpleBroadphase -class btOverlappingPairCache -{ - protected: - //avoid brute-force finding all the time - btBroadphasePairArray m_overlappingPairArray; - - //during the dispatch, check that user doesn't destroy/create proxy - bool m_blockedForChanges; - - //if set, use the callback instead of the built in filter in needBroadphaseCollision - btOverlapFilterCallback* m_overlapFilterCallback; - - public: - - btOverlappingPairCache(); - virtual ~btOverlappingPairCache(); - - virtual void processAllOverlappingPairs(btOverlapCallback*,btDispatcher* dispatcher); - - void* removeOverlappingPair(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1,btDispatcher* dispatcher); - - void cleanOverlappingPair(btBroadphasePair& pair,btDispatcher* dispatcher); - - btBroadphasePair* addOverlappingPair(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1); - - btBroadphasePair* findPair(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1); - - - void cleanProxyFromPairs(btBroadphaseProxy* proxy,btDispatcher* dispatcher); - - void removeOverlappingPairsContainingProxy(btBroadphaseProxy* proxy,btDispatcher* dispatcher); - - - inline bool needsBroadphaseCollision(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1) const - { - if (m_overlapFilterCallback) - return m_overlapFilterCallback->needBroadphaseCollision(proxy0,proxy1); - - bool collides = (proxy0->m_collisionFilterGroup & proxy1->m_collisionFilterMask) != 0; - collides = collides && (proxy1->m_collisionFilterGroup & proxy0->m_collisionFilterMask); - - return collides; - } - - btBroadphasePairArray& getOverlappingPairArray() - { - return m_overlappingPairArray; - } - - const btBroadphasePairArray& getOverlappingPairArray() const - { - return m_overlappingPairArray; - } - - - - - btBroadphasePair* getOverlappingPairArrayPtr() - { - return &m_overlappingPairArray[0]; - } - - const btBroadphasePair* getOverlappingPairArrayPtr() const - { - return &m_overlappingPairArray[0]; - } - - int getNumOverlappingPairs() const - { - return m_overlappingPairArray.size(); - } - - btOverlapFilterCallback* getOverlapFilterCallback() - { - return m_overlapFilterCallback; - } - - void setOverlapFilterCallback(btOverlapFilterCallback* callback) - { - m_overlapFilterCallback = callback; - } - -}; -#endif //USE_HASH_PAIRCACHE - -#endif //OVERLAPPING_PAIR_CACHE_H - - diff --git a/extern/bullet2/src/BulletCollision/BroadphaseCollision/btOverlappingPairCallback.h b/extern/bullet2/src/BulletCollision/BroadphaseCollision/btOverlappingPairCallback.h deleted file mode 100644 index b8d967dc4b2..00000000000 --- a/extern/bullet2/src/BulletCollision/BroadphaseCollision/btOverlappingPairCallback.h +++ /dev/null @@ -1,37 +0,0 @@ - -/* -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 OVERLAPPING_PAIR_CALLBACK_H -#define OVERLAPPING_PAIR_CALLBACK_H - -///btOverlappingPairCallback provides user callback to keep track of overlap between objects, like a collision sensor -class btOverlappingPairCallback -{ -public: - virtual ~btOverlappingPairCallback() - { - - } - - virtual void addOverlappingPair(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1) = 0; - - virtual void removeOverlappingPair(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1) = 0; - - virtual void removeOverlappingPairsContainingProxy(btBroadphaseProxy* proxy0) = 0; - -}; - -#endif //OVERLAPPING_PAIR_CALLBACK_H \ No newline at end of file diff --git a/extern/bullet2/src/BulletCollision/BroadphaseCollision/btSimpleBroadphase.cpp b/extern/bullet2/src/BulletCollision/BroadphaseCollision/btSimpleBroadphase.cpp deleted file mode 100644 index e0bb0992933..00000000000 --- a/extern/bullet2/src/BulletCollision/BroadphaseCollision/btSimpleBroadphase.cpp +++ /dev/null @@ -1,312 +0,0 @@ -/* -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 "btSimpleBroadphase.h" -#include -#include - -#include "LinearMath/btVector3.h" -#include "LinearMath/btTransform.h" -#include "LinearMath/btMatrix3x3.h" -#include - -extern int gOverlappingPairs; - -void btSimpleBroadphase::validate() -{ - for (int i=0;i~btOverlappingPairCache(); - btAlignedFree(m_pairCache); - } -} - - -btBroadphaseProxy* btSimpleBroadphase::createProxy( const btVector3& aabbMin, const btVector3& aabbMax,int shapeType,void* userPtr ,short int collisionFilterGroup,short int collisionFilterMask, btDispatcher* dispatcher) -{ - if (m_numHandles >= m_maxHandles) - { - btAssert(0); - return 0; //should never happen, but don't let the game crash ;-) - } - assert(aabbMin[0]<= aabbMax[0] && aabbMin[1]<= aabbMax[1] && aabbMin[2]<= aabbMax[2]); - - int newHandleIndex = allocHandle(); - btSimpleBroadphaseProxy* proxy = new (&m_pHandles[newHandleIndex])btSimpleBroadphaseProxy(aabbMin,aabbMax,shapeType,userPtr,collisionFilterGroup,collisionFilterMask); - - return proxy; -} - -class RemovingOverlapCallback : public btOverlapCallback -{ -protected: - virtual bool processOverlap(btBroadphasePair& pair) - { - (void)pair; - btAssert(0); - return false; - } -}; - -class RemovePairContainingProxy -{ - - btBroadphaseProxy* m_targetProxy; - public: - virtual ~RemovePairContainingProxy() - { - } -protected: - virtual bool processOverlap(btBroadphasePair& pair) - { - btSimpleBroadphaseProxy* proxy0 = static_cast(pair.m_pProxy0); - btSimpleBroadphaseProxy* proxy1 = static_cast(pair.m_pProxy1); - - return ((m_targetProxy == proxy0 || m_targetProxy == proxy1)); - }; -}; - -void btSimpleBroadphase::destroyProxy(btBroadphaseProxy* proxyOrg,btDispatcher* dispatcher) -{ - - btSimpleBroadphaseProxy* proxy0 = static_cast(proxyOrg); - freeHandle(proxy0); - - m_pairCache->removeOverlappingPairsContainingProxy(proxyOrg,dispatcher); - - //validate(); - -} - -void btSimpleBroadphase::setAabb(btBroadphaseProxy* proxy,const btVector3& aabbMin,const btVector3& aabbMax, btDispatcher* dispatcher) -{ - btSimpleBroadphaseProxy* sbp = getSimpleProxyFromProxy(proxy); - sbp->m_min = aabbMin; - sbp->m_max = aabbMax; -} - - - - - - - - - -bool btSimpleBroadphase::aabbOverlap(btSimpleBroadphaseProxy* proxy0,btSimpleBroadphaseProxy* proxy1) -{ - return proxy0->m_min[0] <= proxy1->m_max[0] && proxy1->m_min[0] <= proxy0->m_max[0] && - proxy0->m_min[1] <= proxy1->m_max[1] && proxy1->m_min[1] <= proxy0->m_max[1] && - proxy0->m_min[2] <= proxy1->m_max[2] && proxy1->m_min[2] <= proxy0->m_max[2]; - -} - - - -//then remove non-overlapping ones -class CheckOverlapCallback : public btOverlapCallback -{ -public: - virtual bool processOverlap(btBroadphasePair& pair) - { - return (!btSimpleBroadphase::aabbOverlap(static_cast(pair.m_pProxy0),static_cast(pair.m_pProxy1))); - } -}; - -void btSimpleBroadphase::calculateOverlappingPairs(btDispatcher* dispatcher) -{ - //first check for new overlapping pairs - int i,j; - - if (m_firstAllocatedHandle >= 0) - { - - btSimpleBroadphaseProxy* proxy0 = &m_pHandles[m_firstAllocatedHandle]; - - for (i=0;ifindPair(proxy0,proxy1)) - { - m_pairCache->addOverlappingPair(proxy0,proxy1); - } - } else - { - #ifdef USE_HASH_PAIRCACHE - if ( m_pairCache->findPair(proxy0,proxy1)) - { - m_pairCache->removeOverlappingPair(proxy0,proxy1,dispatcher); - } - #endif //USE_HASH_PAIRCACHE - - } - } - proxy1 = &m_pHandles[proxy1->GetNextAllocated()]; - - } - proxy0 = &m_pHandles[proxy0->GetNextAllocated()]; - - } - - #ifndef USE_HASH_PAIRCACHE - - if (m_ownsPairCache) - { - - btBroadphasePairArray& overlappingPairArray = m_pairCache->getOverlappingPairArray(); - - //perform a sort, to find duplicates and to sort 'invalid' pairs to the end - overlappingPairArray.heapSort(btBroadphasePairSortPredicate()); - - overlappingPairArray.resize(overlappingPairArray.size() - m_invalidPair); - m_invalidPair = 0; - - - btBroadphasePair previousPair; - previousPair.m_pProxy0 = 0; - previousPair.m_pProxy1 = 0; - previousPair.m_algorithm = 0; - - - for (i=0;iprocessOverlap(pair); - } else - { - needsRemoval = true; - } - } else - { - //remove duplicate - needsRemoval = true; - //should have no algorithm - btAssert(!pair.m_algorithm); - } - - if (needsRemoval) - { - m_pairCache->cleanOverlappingPair(pair,dispatcher); - - // m_overlappingPairArray.swap(i,m_overlappingPairArray.size()-1); - // m_overlappingPairArray.pop_back(); - pair.m_pProxy0 = 0; - pair.m_pProxy1 = 0; - m_invalidPair++; - gOverlappingPairs--; - } - - } - - ///if you don't like to skip the invalid pairs in the array, execute following code: - #define CLEAN_INVALID_PAIRS 1 - #ifdef CLEAN_INVALID_PAIRS - - //perform a sort, to sort 'invalid' pairs to the end - overlappingPairArray.heapSort(btBroadphasePairSortPredicate()); - - overlappingPairArray.resize(overlappingPairArray.size() - m_invalidPair); - m_invalidPair = 0; - #endif//CLEAN_INVALID_PAIRS - - } - #endif //USE_HASH_PAIRCACHE - } -} - - -bool btSimpleBroadphase::testAabbOverlap(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1) -{ - btSimpleBroadphaseProxy* p0 = getSimpleProxyFromProxy(proxy0); - btSimpleBroadphaseProxy* p1 = getSimpleProxyFromProxy(proxy1); - return aabbOverlap(p0,p1); -} - - - diff --git a/extern/bullet2/src/BulletCollision/BroadphaseCollision/btSimpleBroadphase.h b/extern/bullet2/src/BulletCollision/BroadphaseCollision/btSimpleBroadphase.h deleted file mode 100644 index 09367a79d2b..00000000000 --- a/extern/bullet2/src/BulletCollision/BroadphaseCollision/btSimpleBroadphase.h +++ /dev/null @@ -1,147 +0,0 @@ -/* -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 SIMPLE_BROADPHASE_H -#define SIMPLE_BROADPHASE_H - - -#include "btOverlappingPairCache.h" - - -struct btSimpleBroadphaseProxy : public btBroadphaseProxy -{ - btVector3 m_min; - btVector3 m_max; - int m_nextFree; - int m_nextAllocated; -// int m_handleId; - - - btSimpleBroadphaseProxy() {}; - - btSimpleBroadphaseProxy(const btPoint3& minpt,const btPoint3& maxpt,int shapeType,void* userPtr,short int collisionFilterGroup,short int collisionFilterMask) - :btBroadphaseProxy(userPtr,collisionFilterGroup,collisionFilterMask), - m_min(minpt),m_max(maxpt) - { - (void)shapeType; - } - - - SIMD_FORCE_INLINE void SetNextFree(int next) {m_nextFree = next;} - SIMD_FORCE_INLINE int GetNextFree() const {return m_nextFree;} - - SIMD_FORCE_INLINE void SetNextAllocated(int next) {m_nextAllocated = next;} - SIMD_FORCE_INLINE int GetNextAllocated() const {return m_nextAllocated;} - - -}; - -///SimpleBroadphase is a brute force aabb culling broadphase based on O(n^2) aabb checks -///btSimpleBroadphase is just a unit-test implementation to verify and test other broadphases. -///So please don't use this class, but use bt32BitAxisSweep3 or btAxisSweep3 instead! -class btSimpleBroadphase : public btBroadphaseInterface -{ - -protected: - - int m_numHandles; // number of active handles - int m_maxHandles; // max number of handles - btSimpleBroadphaseProxy* m_pHandles; // handles pool - int m_firstFreeHandle; // free handles list - int m_firstAllocatedHandle; - - int allocHandle() - { - - int freeHandle = m_firstFreeHandle; - m_firstFreeHandle = m_pHandles[freeHandle].GetNextFree(); - - m_pHandles[freeHandle].SetNextAllocated(m_firstAllocatedHandle); - m_firstAllocatedHandle = freeHandle; - - m_numHandles++; - - return freeHandle; - } - - void freeHandle(btSimpleBroadphaseProxy* proxy) - { - int handle = int(proxy-m_pHandles); - btAssert(handle >= 0 && handle < m_maxHandles); - - proxy->SetNextFree(m_firstFreeHandle); - m_firstFreeHandle = handle; - - m_firstAllocatedHandle = proxy->GetNextAllocated(); - proxy->SetNextAllocated(-1); - - m_numHandles--; - } - - - btOverlappingPairCache* m_pairCache; - bool m_ownsPairCache; - - int m_invalidPair; - - - - inline btSimpleBroadphaseProxy* getSimpleProxyFromProxy(btBroadphaseProxy* proxy) - { - btSimpleBroadphaseProxy* proxy0 = static_cast(proxy); - return proxy0; - } - - - void validate(); - -protected: - - - - -public: - btSimpleBroadphase(int maxProxies=16384,btOverlappingPairCache* overlappingPairCache=0); - virtual ~btSimpleBroadphase(); - - - static bool aabbOverlap(btSimpleBroadphaseProxy* proxy0,btSimpleBroadphaseProxy* proxy1); - - - virtual btBroadphaseProxy* createProxy( const btVector3& aabbMin, const btVector3& aabbMax,int shapeType,void* userPtr ,short int collisionFilterGroup,short int collisionFilterMask, btDispatcher* dispatcher); - - virtual void calculateOverlappingPairs(btDispatcher* dispatcher); - - virtual void destroyProxy(btBroadphaseProxy* proxy,btDispatcher* dispatcher); - virtual void setAabb(btBroadphaseProxy* proxy,const btVector3& aabbMin,const btVector3& aabbMax, btDispatcher* dispatcher); - - btOverlappingPairCache* getOverlappingPairCache() - { - return m_pairCache; - } - const btOverlappingPairCache* getOverlappingPairCache() const - { - return m_pairCache; - } - - bool testAabbOverlap(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1); - - -}; - - - -#endif //SIMPLE_BROADPHASE_H - diff --git a/extern/bullet2/src/BulletCollision/CMakeLists.txt b/extern/bullet2/src/BulletCollision/CMakeLists.txt deleted file mode 100644 index d2d3dc6fabf..00000000000 --- a/extern/bullet2/src/BulletCollision/CMakeLists.txt +++ /dev/null @@ -1,68 +0,0 @@ - -INCLUDE_DIRECTORIES( -${BULLET_PHYSICS_SOURCE_DIR}/src } -) - -ADD_LIBRARY(LibBulletCollision - BroadphaseCollision/btAxisSweep3.cpp - BroadphaseCollision/btBroadphaseProxy.cpp - BroadphaseCollision/btCollisionAlgorithm.cpp - BroadphaseCollision/btDispatcher.cpp - BroadphaseCollision/btMultiSapBroadphase.cpp - BroadphaseCollision/btOverlappingPairCache.cpp - BroadphaseCollision/btSimpleBroadphase.cpp - CollisionDispatch/btCollisionDispatcher.cpp - CollisionDispatch/btCollisionObject.cpp - CollisionDispatch/btCollisionWorld.cpp - CollisionDispatch/btCompoundCollisionAlgorithm.cpp - CollisionDispatch/btConvexConcaveCollisionAlgorithm.cpp - CollisionDispatch/btDefaultCollisionConfiguration.cpp - CollisionDispatch/btSphereSphereCollisionAlgorithm.cpp - CollisionDispatch/btSphereBoxCollisionAlgorithm.cpp - CollisionDispatch/btSphereTriangleCollisionAlgorithm.cpp - CollisionDispatch/btConvexConvexAlgorithm.cpp - CollisionDispatch/btEmptyCollisionAlgorithm.cpp - CollisionDispatch/btManifoldResult.cpp - CollisionDispatch/btSimulationIslandManager.cpp - CollisionDispatch/btUnionFind.cpp - CollisionDispatch/SphereTriangleDetector.cpp - CollisionShapes/btBoxShape.cpp - CollisionShapes/btBvhTriangleMeshShape.cpp - CollisionShapes/btCapsuleShape.cpp - CollisionShapes/btCollisionShape.cpp - CollisionShapes/btCompoundShape.cpp - CollisionShapes/btConcaveShape.cpp - CollisionShapes/btConeShape.cpp - CollisionShapes/btConvexHullShape.cpp - CollisionShapes/btConvexShape.cpp - CollisionShapes/btConvexInternalShape.cpp - CollisionShapes/btConvexTriangleMeshShape.cpp - CollisionShapes/btCylinderShape.cpp - CollisionShapes/btEmptyShape.cpp - CollisionShapes/btHeightfieldTerrainShape.cpp - CollisionShapes/btMinkowskiSumShape.cpp - CollisionShapes/btMultiSphereShape.cpp - CollisionShapes/btOptimizedBvh.cpp - CollisionShapes/btPolyhedralConvexShape.cpp - CollisionShapes/btTetrahedronShape.cpp - CollisionShapes/btSphereShape.cpp - CollisionShapes/btStaticPlaneShape.cpp - CollisionShapes/btStridingMeshInterface.cpp - CollisionShapes/btTriangleCallback.cpp - CollisionShapes/btTriangleBuffer.cpp - CollisionShapes/btTriangleIndexVertexArray.cpp - CollisionShapes/btTriangleMesh.cpp - CollisionShapes/btTriangleMeshShape.cpp - CollisionShapes/btUniformScalingShape.cpp - NarrowPhaseCollision/btContinuousConvexCollision.cpp - NarrowPhaseCollision/btGjkEpa.cpp - NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.cpp - NarrowPhaseCollision/btConvexCast.cpp - NarrowPhaseCollision/btGjkConvexCast.cpp - NarrowPhaseCollision/btGjkPairDetector.cpp - NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.cpp - NarrowPhaseCollision/btPersistentManifold.cpp - NarrowPhaseCollision/btRaycastCallback.cpp - NarrowPhaseCollision/btSubSimplexConvexCast.cpp - NarrowPhaseCollision/btVoronoiSimplexSolver.cpp -) diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/SphereTriangleDetector.cpp b/extern/bullet2/src/BulletCollision/CollisionDispatch/SphereTriangleDetector.cpp deleted file mode 100644 index 81133670f0c..00000000000 --- a/extern/bullet2/src/BulletCollision/CollisionDispatch/SphereTriangleDetector.cpp +++ /dev/null @@ -1,200 +0,0 @@ -/* -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 "LinearMath/btScalar.h" -#include "SphereTriangleDetector.h" -#include "BulletCollision/CollisionShapes/btTriangleShape.h" -#include "BulletCollision/CollisionShapes/btSphereShape.h" - - -SphereTriangleDetector::SphereTriangleDetector(btSphereShape* sphere,btTriangleShape* triangle) -:m_sphere(sphere), -m_triangle(triangle) -{ - -} - -void SphereTriangleDetector::getClosestPoints(const ClosestPointInput& input,Result& output,class btIDebugDraw* debugDraw) -{ - - (void)debugDraw; - const btTransform& transformA = input.m_transformA; - const btTransform& transformB = input.m_transformB; - - btVector3 point,normal; - btScalar timeOfImpact = btScalar(1.); - btScalar depth = btScalar(0.); -// output.m_distance = btScalar(1e30); - //move sphere into triangle space - btTransform sphereInTr = transformB.inverseTimes(transformA); - - if (collide(sphereInTr.getOrigin(),point,normal,depth,timeOfImpact)) - { - output.addContactPoint(transformB.getBasis()*normal,transformB*point,depth); - } - -} - -#define MAX_OVERLAP btScalar(0.) - - - -// See also geometrictools.com -// Basic idea: D = |p - (lo + t0*lv)| where t0 = lv . (p - lo) / lv . lv -btScalar SegmentSqrDistance(const btVector3& from, const btVector3& to,const btVector3 &p, btVector3 &nearest) { - btVector3 diff = p - from; - btVector3 v = to - from; - btScalar t = v.dot(diff); - - if (t > 0) { - btScalar dotVV = v.dot(v); - if (t < dotVV) { - t /= dotVV; - diff -= t*v; - } else { - t = 1; - diff -= v; - } - } else - t = 0; - - nearest = from + t*v; - return diff.dot(diff); -} - -bool SphereTriangleDetector::facecontains(const btVector3 &p,const btVector3* vertices,btVector3& normal) { - btVector3 lp(p); - btVector3 lnormal(normal); - - return pointInTriangle(vertices, lnormal, &lp); -} - -///combined discrete/continuous sphere-triangle -bool SphereTriangleDetector::collide(const btVector3& sphereCenter,btVector3 &point, btVector3& resultNormal, btScalar& depth, btScalar &timeOfImpact) -{ - - const btVector3* vertices = &m_triangle->getVertexPtr(0); - const btVector3& c = sphereCenter; - btScalar r = m_sphere->getRadius(); - - btVector3 delta (0,0,0); - - btVector3 normal = (vertices[1]-vertices[0]).cross(vertices[2]-vertices[0]); - normal.normalize(); - btVector3 p1ToCentre = c - vertices[0]; - btScalar distanceFromPlane = p1ToCentre.dot(normal); - - if (distanceFromPlane < btScalar(0.)) - { - //triangle facing the other way - - distanceFromPlane *= btScalar(-1.); - normal *= btScalar(-1.); - } - - ///todo: move this gContactBreakingThreshold into a proper structure - extern btScalar gContactBreakingThreshold; - - btScalar contactMargin = gContactBreakingThreshold; - bool isInsideContactPlane = distanceFromPlane < r + contactMargin; - bool isInsideShellPlane = distanceFromPlane < r; - - btScalar deltaDotNormal = delta.dot(normal); - if (!isInsideShellPlane && deltaDotNormal >= btScalar(0.0)) - return false; - - // Check for contact / intersection - bool hasContact = false; - btVector3 contactPoint; - if (isInsideContactPlane) { - if (facecontains(c,vertices,normal)) { - // Inside the contact wedge - touches a point on the shell plane - hasContact = true; - contactPoint = c - normal*distanceFromPlane; - } else { - // Could be inside one of the contact capsules - btScalar contactCapsuleRadiusSqr = (r + contactMargin) * (r + contactMargin); - btVector3 nearestOnEdge; - for (int i = 0; i < m_triangle->getNumEdges(); i++) { - - btPoint3 pa; - btPoint3 pb; - - m_triangle->getEdge(i,pa,pb); - - btScalar distanceSqr = SegmentSqrDistance(pa,pb,c, nearestOnEdge); - if (distanceSqr < contactCapsuleRadiusSqr) { - // Yep, we're inside a capsule - hasContact = true; - contactPoint = nearestOnEdge; - } - - } - } - } - - if (hasContact) { - btVector3 contactToCentre = c - contactPoint; - btScalar distanceSqr = contactToCentre.length2(); - if (distanceSqr < (r - MAX_OVERLAP)*(r - MAX_OVERLAP)) { - btScalar distance = btSqrt(distanceSqr); - resultNormal = contactToCentre; - resultNormal.normalize(); - point = contactPoint; - depth = -(r-distance); - return true; - } - - if (delta.dot(contactToCentre) >= btScalar(0.0)) - return false; - - // Moving towards the contact point -> collision - point = contactPoint; - timeOfImpact = btScalar(0.0); - return true; - } - - return false; -} - - -bool SphereTriangleDetector::pointInTriangle(const btVector3 vertices[], const btVector3 &normal, btVector3 *p ) -{ - const btVector3* p1 = &vertices[0]; - const btVector3* p2 = &vertices[1]; - const btVector3* p3 = &vertices[2]; - - btVector3 edge1( *p2 - *p1 ); - btVector3 edge2( *p3 - *p2 ); - btVector3 edge3( *p1 - *p3 ); - - btVector3 p1_to_p( *p - *p1 ); - btVector3 p2_to_p( *p - *p2 ); - btVector3 p3_to_p( *p - *p3 ); - - btVector3 edge1_normal( edge1.cross(normal)); - btVector3 edge2_normal( edge2.cross(normal)); - btVector3 edge3_normal( edge3.cross(normal)); - - btScalar r1, r2, r3; - r1 = edge1_normal.dot( p1_to_p ); - r2 = edge2_normal.dot( p2_to_p ); - r3 = edge3_normal.dot( p3_to_p ); - if ( ( r1 > 0 && r2 > 0 && r3 > 0 ) || - ( r1 <= 0 && r2 <= 0 && r3 <= 0 ) ) - return true; - return false; - -} diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/SphereTriangleDetector.h b/extern/bullet2/src/BulletCollision/CollisionDispatch/SphereTriangleDetector.h deleted file mode 100644 index 0c817b221c8..00000000000 --- a/extern/bullet2/src/BulletCollision/CollisionDispatch/SphereTriangleDetector.h +++ /dev/null @@ -1,49 +0,0 @@ -/* -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 SPHERE_TRIANGLE_DETECTOR_H -#define SPHERE_TRIANGLE_DETECTOR_H - -#include "BulletCollision/NarrowPhaseCollision/btDiscreteCollisionDetectorInterface.h" -#include "LinearMath/btPoint3.h" - - -class btSphereShape; -class btTriangleShape; - - - -/// sphere-triangle to match the btDiscreteCollisionDetectorInterface -struct SphereTriangleDetector : public btDiscreteCollisionDetectorInterface -{ - virtual void getClosestPoints(const ClosestPointInput& input,Result& output,class btIDebugDraw* debugDraw); - - SphereTriangleDetector(btSphereShape* sphere,btTriangleShape* triangle); - - virtual ~SphereTriangleDetector() {}; - -private: - - bool collide(const btVector3& sphereCenter,btVector3 &point, btVector3& resultNormal, btScalar& depth, btScalar &timeOfImpact); - bool pointInTriangle(const btVector3 vertices[], const btVector3 &normal, btVector3 *p ); - bool facecontains(const btVector3 &p,const btVector3* vertices,btVector3& normal); - - btSphereShape* m_sphere; - btTriangleShape* m_triangle; - - -}; -#endif //SPHERE_TRIANGLE_DETECTOR_H - diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionConfiguration.h b/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionConfiguration.h deleted file mode 100644 index fad770ac26d..00000000000 --- a/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionConfiguration.h +++ /dev/null @@ -1,47 +0,0 @@ -/* -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 BT_COLLISION_CONFIGURATION -#define BT_COLLISION_CONFIGURATION -struct btCollisionAlgorithmCreateFunc; - -class btStackAlloc; -class btPoolAllocator; - -///btCollisionConfiguration allows to configure Bullet collision detection -///stack allocator size, default collision algorithms and persistent manifold pool size -///todo: describe the meaning -class btCollisionConfiguration -{ - -public: - - virtual ~btCollisionConfiguration() - { - } - - ///memory pools - virtual btPoolAllocator* getPersistentManifoldPool() = 0; - - virtual btPoolAllocator* getCollisionAlgorithmPool() = 0; - - virtual btStackAlloc* getStackAllocator() = 0; - - virtual btCollisionAlgorithmCreateFunc* getCollisionAlgorithmCreateFunc(int proxyType0,int proxyType1) =0; - -}; - -#endif //BT_COLLISION_CONFIGURATION - diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionCreateFunc.h b/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionCreateFunc.h deleted file mode 100644 index c6728918d16..00000000000 --- a/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionCreateFunc.h +++ /dev/null @@ -1,46 +0,0 @@ -/* -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 COLLISION_CREATE_FUNC -#define COLLISION_CREATE_FUNC - -#include "LinearMath/btAlignedObjectArray.h" -typedef btAlignedObjectArray btCollisionObjectArray; -class btCollisionAlgorithm; -class btCollisionObject; - -struct btCollisionAlgorithmConstructionInfo; - -///Used by the btCollisionDispatcher to register and create instances for btCollisionAlgorithm -struct btCollisionAlgorithmCreateFunc -{ - bool m_swapped; - - btCollisionAlgorithmCreateFunc() - :m_swapped(false) - { - } - virtual ~btCollisionAlgorithmCreateFunc(){}; - - virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& , btCollisionObject* body0,btCollisionObject* body1) - { - - (void)body0; - (void)body1; - return 0; - } -}; -#endif //COLLISION_CREATE_FUNC - diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionDispatcher.cpp b/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionDispatcher.cpp deleted file mode 100644 index 644caf2677b..00000000000 --- a/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionDispatcher.cpp +++ /dev/null @@ -1,287 +0,0 @@ -/* -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 "btCollisionDispatcher.h" - - -#include "BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h" - -#include "BulletCollision/CollisionShapes/btCollisionShape.h" -#include "BulletCollision/CollisionDispatch/btCollisionObject.h" -#include "BulletCollision/BroadphaseCollision/btOverlappingPairCache.h" -#include "LinearMath/btPoolAllocator.h" -#include "BulletCollision/CollisionDispatch/btCollisionConfiguration.h" - -int gNumManifold = 0; - -#include - - - -btCollisionDispatcher::btCollisionDispatcher (btCollisionConfiguration* collisionConfiguration): - m_count(0), - m_useIslands(true), - m_collisionConfiguration(collisionConfiguration) -{ - int i; - - setNearCallback(defaultNearCallback); - - m_collisionAlgorithmPoolAllocator = collisionConfiguration->getCollisionAlgorithmPool(); - - m_persistentManifoldPoolAllocator = collisionConfiguration->getPersistentManifoldPool(); - - for (i=0;igetCollisionAlgorithmCreateFunc(i,j); - assert(m_doubleDispatch[i][j]); - } - } - - -}; - - -void btCollisionDispatcher::registerCollisionCreateFunc(int proxyType0, int proxyType1, btCollisionAlgorithmCreateFunc *createFunc) -{ - m_doubleDispatch[proxyType0][proxyType1] = createFunc; -} - -btCollisionDispatcher::~btCollisionDispatcher() -{ -} - -btPersistentManifold* btCollisionDispatcher::getNewManifold(void* b0,void* b1) -{ - gNumManifold++; - - //btAssert(gNumManifold < 65535); - - - btCollisionObject* body0 = (btCollisionObject*)b0; - btCollisionObject* body1 = (btCollisionObject*)b1; - - void* mem = 0; - - if (m_persistentManifoldPoolAllocator->getFreeCount()) - { - mem = m_persistentManifoldPoolAllocator->allocate(sizeof(btPersistentManifold)); - } else - { - mem = btAlignedAlloc(sizeof(btPersistentManifold),16); - - } - btPersistentManifold* manifold = new(mem) btPersistentManifold (body0,body1,0); - manifold->m_index1a = m_manifoldsPtr.size(); - m_manifoldsPtr.push_back(manifold); - - return manifold; -} - -void btCollisionDispatcher::clearManifold(btPersistentManifold* manifold) -{ - manifold->clearManifold(); -} - - -void btCollisionDispatcher::releaseManifold(btPersistentManifold* manifold) -{ - - gNumManifold--; - - //printf("releaseManifold: gNumManifold %d\n",gNumManifold); - clearManifold(manifold); - - int findIndex = manifold->m_index1a; - btAssert(findIndex < m_manifoldsPtr.size()); - m_manifoldsPtr.swap(findIndex,m_manifoldsPtr.size()-1); - m_manifoldsPtr[findIndex]->m_index1a = findIndex; - m_manifoldsPtr.pop_back(); - - manifold->~btPersistentManifold(); - if (m_persistentManifoldPoolAllocator->validPtr(manifold)) - { - m_persistentManifoldPoolAllocator->free(manifold); - } else - { - btAlignedFree(manifold); - } - -} - - - -btCollisionAlgorithm* btCollisionDispatcher::findAlgorithm(btCollisionObject* body0,btCollisionObject* body1,btPersistentManifold* sharedManifold) -{ - - btCollisionAlgorithmConstructionInfo ci; - - ci.m_dispatcher1 = this; - ci.m_manifold = sharedManifold; - btCollisionAlgorithm* algo = m_doubleDispatch[body0->getCollisionShape()->getShapeType()][body1->getCollisionShape()->getShapeType()]->CreateCollisionAlgorithm(ci,body0,body1); - - return algo; -} - - - - - -bool btCollisionDispatcher::needsResponse(btCollisionObject* body0,btCollisionObject* body1) -{ - //here you can do filtering - bool hasResponse = - (body0->hasContactResponse() && body1->hasContactResponse()); - //no response between two static/kinematic bodies: - hasResponse = hasResponse && - ((!body0->isStaticOrKinematicObject()) ||(! body1->isStaticOrKinematicObject())); - return hasResponse; -} - -bool btCollisionDispatcher::needsCollision(btCollisionObject* body0,btCollisionObject* body1) -{ - assert(body0); - assert(body1); - - bool needsCollision = true; - - //broadphase filtering already deals with this - if ((body0->isStaticObject() || body0->isKinematicObject()) && - (body1->isStaticObject() || body1->isKinematicObject())) - { - printf("warning btCollisionDispatcher::needsCollision: static-static collision!\n"); - } - - if ((!body0->isActive()) && (!body1->isActive())) - needsCollision = false; - else if (!body0->checkCollideWith(body1)) - needsCollision = false; - - return needsCollision ; - -} - - - -///interface for iterating all overlapping collision pairs, no matter how those pairs are stored (array, set, map etc) -///this is useful for the collision dispatcher. -class btCollisionPairCallback : public btOverlapCallback -{ - btDispatcherInfo& m_dispatchInfo; - btCollisionDispatcher* m_dispatcher; - -public: - - btCollisionPairCallback(btDispatcherInfo& dispatchInfo,btCollisionDispatcher* dispatcher) - :m_dispatchInfo(dispatchInfo), - m_dispatcher(dispatcher) - { - } - - btCollisionPairCallback& operator=(btCollisionPairCallback& other) - { - m_dispatchInfo = other.m_dispatchInfo; - m_dispatcher = other.m_dispatcher; - return *this; - } - - virtual ~btCollisionPairCallback() {} - - - virtual bool processOverlap(btBroadphasePair& pair) - { - (*m_dispatcher->getNearCallback())(pair,*m_dispatcher,m_dispatchInfo); - - return false; - } -}; - - -void btCollisionDispatcher::dispatchAllCollisionPairs(btOverlappingPairCache* pairCache,btDispatcherInfo& dispatchInfo,btDispatcher* dispatcher) -{ - //m_blockedForChanges = true; - - btCollisionPairCallback collisionCallback(dispatchInfo,this); - - pairCache->processAllOverlappingPairs(&collisionCallback,dispatcher); - - //m_blockedForChanges = false; - -} - - - - -//by default, Bullet will use this near callback -void btCollisionDispatcher::defaultNearCallback(btBroadphasePair& collisionPair, btCollisionDispatcher& dispatcher, btDispatcherInfo& dispatchInfo) -{ - btCollisionObject* colObj0 = (btCollisionObject*)collisionPair.m_pProxy0->m_clientObject; - btCollisionObject* colObj1 = (btCollisionObject*)collisionPair.m_pProxy1->m_clientObject; - - if (dispatcher.needsCollision(colObj0,colObj1)) - { - //dispatcher will keep algorithms persistent in the collision pair - if (!collisionPair.m_algorithm) - { - collisionPair.m_algorithm = dispatcher.findAlgorithm(colObj0,colObj1); - } - - if (collisionPair.m_algorithm) - { - btManifoldResult contactPointResult(colObj0,colObj1); - - if (dispatchInfo.m_dispatchFunc == btDispatcherInfo::DISPATCH_DISCRETE) - { - //discrete collision detection query - collisionPair.m_algorithm->processCollision(colObj0,colObj1,dispatchInfo,&contactPointResult); - } else - { - //continuous collision detection query, time of impact (toi) - btScalar toi = collisionPair.m_algorithm->calculateTimeOfImpact(colObj0,colObj1,dispatchInfo,&contactPointResult); - if (dispatchInfo.m_timeOfImpact > toi) - dispatchInfo.m_timeOfImpact = toi; - - } - } - } - -} - - -void* btCollisionDispatcher::allocateCollisionAlgorithm(int size) -{ - if (m_collisionAlgorithmPoolAllocator->getFreeCount()) - { - return m_collisionAlgorithmPoolAllocator->allocate(size); - } - - //warn user for overflow? - return btAlignedAlloc(size,16); -} - -void btCollisionDispatcher::freeCollisionAlgorithm(void* ptr) -{ - if (m_collisionAlgorithmPoolAllocator->validPtr(ptr)) - { - m_collisionAlgorithmPoolAllocator->free(ptr); - } else - { - btAlignedFree(ptr); - } -} diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionDispatcher.h b/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionDispatcher.h deleted file mode 100644 index 45aaa1bd90d..00000000000 --- a/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionDispatcher.h +++ /dev/null @@ -1,145 +0,0 @@ -/* -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 COLLISION__DISPATCHER_H -#define COLLISION__DISPATCHER_H - -#include "BulletCollision/BroadphaseCollision/btDispatcher.h" -#include "BulletCollision/NarrowPhaseCollision/btPersistentManifold.h" - -#include "BulletCollision/CollisionDispatch/btManifoldResult.h" - -#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" -#include "LinearMath/btAlignedObjectArray.h" - -class btIDebugDraw; -class btOverlappingPairCache; -class btPoolAllocator; -class btCollisionConfiguration; - -#include "btCollisionCreateFunc.h" - -#define USE_DISPATCH_REGISTRY_ARRAY 1 - -class btCollisionDispatcher; -///user can override this nearcallback for collision filtering and more finegrained control over collision detection -typedef void (*btNearCallback)(btBroadphasePair& collisionPair, btCollisionDispatcher& dispatcher, btDispatcherInfo& dispatchInfo); - - -///btCollisionDispatcher supports algorithms that handle ConvexConvex and ConvexConcave collision pairs. -///Time of Impact, Closest Points and Penetration Depth. -class btCollisionDispatcher : public btDispatcher -{ - int m_count; - - btAlignedObjectArray m_manifoldsPtr; - - bool m_useIslands; - - btManifoldResult m_defaultManifoldResult; - - btNearCallback m_nearCallback; - - btPoolAllocator* m_collisionAlgorithmPoolAllocator; - - btPoolAllocator* m_persistentManifoldPoolAllocator; - - btCollisionAlgorithmCreateFunc* m_doubleDispatch[MAX_BROADPHASE_COLLISION_TYPES][MAX_BROADPHASE_COLLISION_TYPES]; - - - btCollisionConfiguration* m_collisionConfiguration; - - -public: - - ///registerCollisionCreateFunc allows registration of custom/alternative collision create functions - void registerCollisionCreateFunc(int proxyType0,int proxyType1, btCollisionAlgorithmCreateFunc* createFunc); - - int getNumManifolds() const - { - return int( m_manifoldsPtr.size()); - } - - btPersistentManifold** getInternalManifoldPointer() - { - return &m_manifoldsPtr[0]; - } - - btPersistentManifold* getManifoldByIndexInternal(int index) - { - return m_manifoldsPtr[index]; - } - - const btPersistentManifold* getManifoldByIndexInternal(int index) const - { - return m_manifoldsPtr[index]; - } - - btCollisionDispatcher (btCollisionConfiguration* collisionConfiguration); - - virtual ~btCollisionDispatcher(); - - virtual btPersistentManifold* getNewManifold(void* b0,void* b1); - - virtual void releaseManifold(btPersistentManifold* manifold); - - - virtual void clearManifold(btPersistentManifold* manifold); - - - btCollisionAlgorithm* findAlgorithm(btCollisionObject* body0,btCollisionObject* body1,btPersistentManifold* sharedManifold = 0); - - virtual bool needsCollision(btCollisionObject* body0,btCollisionObject* body1); - - virtual bool needsResponse(btCollisionObject* body0,btCollisionObject* body1); - - virtual void dispatchAllCollisionPairs(btOverlappingPairCache* pairCache,btDispatcherInfo& dispatchInfo,btDispatcher* dispatcher); - - void setNearCallback(btNearCallback nearCallback) - { - m_nearCallback = nearCallback; - } - - btNearCallback getNearCallback() const - { - return m_nearCallback; - } - - //by default, Bullet will use this near callback - static void defaultNearCallback(btBroadphasePair& collisionPair, btCollisionDispatcher& dispatcher, btDispatcherInfo& dispatchInfo); - - virtual void* allocateCollisionAlgorithm(int size); - - virtual void freeCollisionAlgorithm(void* ptr); - - btCollisionConfiguration* getCollisionConfiguration() - { - return m_collisionConfiguration; - } - - const btCollisionConfiguration* getCollisionConfiguration() const - { - return m_collisionConfiguration; - } - - void setCollisionConfiguration(btCollisionConfiguration* config) - { - m_collisionConfiguration = config; - } - -}; - -#endif //COLLISION__DISPATCHER_H - diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionObject.cpp b/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionObject.cpp deleted file mode 100644 index 6b72a131c4f..00000000000 --- a/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionObject.cpp +++ /dev/null @@ -1,62 +0,0 @@ -/* -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 "btCollisionObject.h" - -btCollisionObject::btCollisionObject() - : m_broadphaseHandle(0), - m_collisionShape(0), - m_collisionFlags(0), - m_islandTag1(-1), - m_companionId(-1), - m_activationState1(1), - m_deactivationTime(btScalar(0.)), - m_userObjectPointer(0), - m_internalOwner(0), - m_hitFraction(btScalar(1.)), - m_ccdSweptSphereRadius(btScalar(0.)), - m_ccdSquareMotionThreshold(btScalar(0.)), - m_checkCollideWith(false) -{ - -} - -btCollisionObject::~btCollisionObject() -{ -} - -void btCollisionObject::setActivationState(int newState) -{ - if ( (m_activationState1 != DISABLE_DEACTIVATION) && (m_activationState1 != DISABLE_SIMULATION)) - m_activationState1 = newState; -} - -void btCollisionObject::forceActivationState(int newState) -{ - m_activationState1 = newState; -} - -void btCollisionObject::activate(bool forceActivation) -{ - if (forceActivation || !(m_collisionFlags & (CF_STATIC_OBJECT|CF_KINEMATIC_OBJECT))) - { - setActivationState(ACTIVE_TAG); - m_deactivationTime = btScalar(0.); - } -} - - - diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionObject.h b/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionObject.h deleted file mode 100644 index 7c1ddbf1e2d..00000000000 --- a/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionObject.h +++ /dev/null @@ -1,349 +0,0 @@ -/* -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 COLLISION_OBJECT_H -#define COLLISION_OBJECT_H - -#include "LinearMath/btTransform.h" - -//island management, m_activationState1 -#define ACTIVE_TAG 1 -#define ISLAND_SLEEPING 2 -#define WANTS_DEACTIVATION 3 -#define DISABLE_DEACTIVATION 4 -#define DISABLE_SIMULATION 5 - -struct btBroadphaseProxy; -class btCollisionShape; -#include "LinearMath/btMotionState.h" -#include "LinearMath/btAlignedAllocator.h" - - - -/// btCollisionObject can be used to manage collision detection objects. -/// btCollisionObject maintains all information that is needed for a collision detection: Shape, Transform and AABB proxy. -/// They can be added to the btCollisionWorld. -ATTRIBUTE_ALIGNED16(class) btCollisionObject -{ - -protected: - - btTransform m_worldTransform; - - ///m_interpolationWorldTransform is used for CCD and interpolation - ///it can be either previous or future (predicted) transform - btTransform m_interpolationWorldTransform; - //those two are experimental: just added for bullet time effect, so you can still apply impulses (directly modifying velocities) - //without destroying the continuous interpolated motion (which uses this interpolation velocities) - btVector3 m_interpolationLinearVelocity; - btVector3 m_interpolationAngularVelocity; - btBroadphaseProxy* m_broadphaseHandle; - btCollisionShape* m_collisionShape; - - int m_collisionFlags; - - int m_islandTag1; - int m_companionId; - - int m_activationState1; - btScalar m_deactivationTime; - - btScalar m_friction; - btScalar m_restitution; - - ///users can point to their objects, m_userPointer is not used by Bullet, see setUserPointer/getUserPointer - void* m_userObjectPointer; - - ///m_internalOwner is reserved to point to Bullet's btRigidBody. Don't use this, use m_userObjectPointer instead. - void* m_internalOwner; - - ///time of impact calculation - btScalar m_hitFraction; - - ///Swept sphere radius (0.0 by default), see btConvexConvexAlgorithm:: - btScalar m_ccdSweptSphereRadius; - - /// Don't do continuous collision detection if square motion (in one step) is less then m_ccdSquareMotionThreshold - btScalar m_ccdSquareMotionThreshold; - - /// If some object should have elaborate collision filtering by sub-classes - bool m_checkCollideWith; - - char m_pad[7]; - - virtual bool checkCollideWithOverride(btCollisionObject* co) - { - return true; - } - -public: - - BT_DECLARE_ALIGNED_ALLOCATOR(); - - enum CollisionFlags - { - CF_STATIC_OBJECT= 1, - CF_KINEMATIC_OBJECT= 2, - CF_NO_CONTACT_RESPONSE = 4, - CF_CUSTOM_MATERIAL_CALLBACK = 8//this allows per-triangle material (friction/restitution) - }; - - - SIMD_FORCE_INLINE bool mergesSimulationIslands() const - { - ///static objects, kinematic and object without contact response don't merge islands - return ((m_collisionFlags & (CF_STATIC_OBJECT | CF_KINEMATIC_OBJECT | CF_NO_CONTACT_RESPONSE) )==0); - } - - - SIMD_FORCE_INLINE bool isStaticObject() const { - return (m_collisionFlags & CF_STATIC_OBJECT) != 0; - } - - SIMD_FORCE_INLINE bool isKinematicObject() const - { - return (m_collisionFlags & CF_KINEMATIC_OBJECT) != 0; - } - - SIMD_FORCE_INLINE bool isStaticOrKinematicObject() const - { - return (m_collisionFlags & (CF_KINEMATIC_OBJECT | CF_STATIC_OBJECT)) != 0 ; - } - - SIMD_FORCE_INLINE bool hasContactResponse() const { - return (m_collisionFlags & CF_NO_CONTACT_RESPONSE)==0; - } - - - btCollisionObject(); - - virtual ~btCollisionObject(); - - void setCollisionShape(btCollisionShape* collisionShape) - { - m_collisionShape = collisionShape; - } - - SIMD_FORCE_INLINE const btCollisionShape* getCollisionShape() const - { - return m_collisionShape; - } - - SIMD_FORCE_INLINE btCollisionShape* getCollisionShape() - { - return m_collisionShape; - } - - - - - int getActivationState() const { return m_activationState1;} - - void setActivationState(int newState); - - void setDeactivationTime(btScalar time) - { - m_deactivationTime = time; - } - btScalar getDeactivationTime() const - { - return m_deactivationTime; - } - - void forceActivationState(int newState); - - void activate(bool forceActivation = false); - - inline bool isActive() const - { - return ((getActivationState() != ISLAND_SLEEPING) && (getActivationState() != DISABLE_SIMULATION)); - } - - void setRestitution(btScalar rest) - { - m_restitution = rest; - } - btScalar getRestitution() const - { - return m_restitution; - } - void setFriction(btScalar frict) - { - m_friction = frict; - } - btScalar getFriction() const - { - return m_friction; - } - - ///reserved for Bullet internal usage - void* getInternalOwner() - { - return m_internalOwner; - } - - const void* getInternalOwner() const - { - return m_internalOwner; - } - - btTransform& getWorldTransform() - { - return m_worldTransform; - } - - const btTransform& getWorldTransform() const - { - return m_worldTransform; - } - - void setWorldTransform(const btTransform& worldTrans) - { - m_worldTransform = worldTrans; - } - - - btBroadphaseProxy* getBroadphaseHandle() - { - return m_broadphaseHandle; - } - - const btBroadphaseProxy* getBroadphaseHandle() const - { - return m_broadphaseHandle; - } - - void setBroadphaseHandle(btBroadphaseProxy* handle) - { - m_broadphaseHandle = handle; - } - - - const btTransform& getInterpolationWorldTransform() const - { - return m_interpolationWorldTransform; - } - - btTransform& getInterpolationWorldTransform() - { - return m_interpolationWorldTransform; - } - - void setInterpolationWorldTransform(const btTransform& trans) - { - m_interpolationWorldTransform = trans; - } - - - const btVector3& getInterpolationLinearVelocity() const - { - return m_interpolationLinearVelocity; - } - - const btVector3& getInterpolationAngularVelocity() const - { - return m_interpolationAngularVelocity; - } - - const int getIslandTag() const - { - return m_islandTag1; - } - - void setIslandTag(int tag) - { - m_islandTag1 = tag; - } - - const int getCompanionId() const - { - return m_companionId; - } - - void setCompanionId(int id) - { - m_companionId = id; - } - - const btScalar getHitFraction() const - { - return m_hitFraction; - } - - void setHitFraction(btScalar hitFraction) - { - m_hitFraction = hitFraction; - } - - - const int getCollisionFlags() const - { - return m_collisionFlags; - } - - void setCollisionFlags(int flags) - { - m_collisionFlags = flags; - } - - ///Swept sphere radius (0.0 by default), see btConvexConvexAlgorithm:: - btScalar getCcdSweptSphereRadius() const - { - return m_ccdSweptSphereRadius; - } - - ///Swept sphere radius (0.0 by default), see btConvexConvexAlgorithm:: - void setCcdSweptSphereRadius(btScalar radius) - { - m_ccdSweptSphereRadius = radius; - } - - btScalar getCcdSquareMotionThreshold() const - { - return m_ccdSquareMotionThreshold; - } - - - /// Don't do continuous collision detection if square motion (in one step) is less then m_ccdSquareMotionThreshold - void setCcdSquareMotionThreshold(btScalar ccdSquareMotionThreshold) - { - m_ccdSquareMotionThreshold = ccdSquareMotionThreshold; - } - - ///users can point to their objects, userPointer is not used by Bullet - void* getUserPointer() const - { - return m_userObjectPointer; - } - - ///users can point to their objects, userPointer is not used by Bullet - void setUserPointer(void* userPointer) - { - m_userObjectPointer = userPointer; - } - - inline bool checkCollideWith(btCollisionObject* co) - { - if (m_checkCollideWith) - return checkCollideWithOverride(co); - - return true; - } - - -} -; - -#endif //COLLISION_OBJECT_H diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionWorld.cpp b/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionWorld.cpp deleted file mode 100644 index b4828508bcb..00000000000 --- a/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionWorld.cpp +++ /dev/null @@ -1,370 +0,0 @@ -/* -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 "btCollisionWorld.h" -#include "btCollisionDispatcher.h" -#include "BulletCollision/CollisionDispatch/btCollisionObject.h" -#include "BulletCollision/CollisionShapes/btCollisionShape.h" -#include "BulletCollision/CollisionShapes/btConvexShape.h" - -#include "BulletCollision/CollisionShapes/btSphereShape.h" //for raycasting -#include "BulletCollision/CollisionShapes/btTriangleMeshShape.h" //for raycasting -#include "BulletCollision/NarrowPhaseCollision/btRaycastCallback.h" -#include "BulletCollision/CollisionShapes/btCompoundShape.h" -#include "BulletCollision/NarrowPhaseCollision/btSubSimplexConvexCast.h" -#include "BulletCollision/NarrowPhaseCollision/btGjkConvexCast.h" -#include "BulletCollision/NarrowPhaseCollision/btContinuousConvexCollision.h" - -#include "BulletCollision/BroadphaseCollision/btBroadphaseInterface.h" -#include "LinearMath/btAabbUtil2.h" -#include "LinearMath/btQuickprof.h" -#include "LinearMath/btStackAlloc.h" - -//When the user doesn't provide dispatcher or broadphase, create basic versions (and delete them in destructor) -#include "BulletCollision/CollisionDispatch/btCollisionDispatcher.h" -#include "BulletCollision/BroadphaseCollision/btSimpleBroadphase.h" -#include "BulletCollision/CollisionDispatch/btCollisionConfiguration.h" - - -btCollisionWorld::btCollisionWorld(btDispatcher* dispatcher,btBroadphaseInterface* pairCache, btCollisionConfiguration* collisionConfiguration) -:m_dispatcher1(dispatcher), -m_broadphasePairCache(pairCache) -{ - m_stackAlloc = collisionConfiguration->getStackAllocator(); - m_dispatchInfo.m_stackAllocator = m_stackAlloc; -} - - -btCollisionWorld::~btCollisionWorld() -{ - - //clean up remaining objects - int i; - for (i=0;igetBroadphaseHandle(); - if (bp) - { - // - // only clear the cached algorithms - // - getBroadphase()->getOverlappingPairCache()->cleanProxyFromPairs(bp,m_dispatcher1); - getBroadphase()->destroyProxy(bp,m_dispatcher1); - } - } - - -} - - - - - - - - - - -void btCollisionWorld::addCollisionObject(btCollisionObject* collisionObject,short int collisionFilterGroup,short int collisionFilterMask) -{ - - //check that the object isn't already added - btAssert( m_collisionObjects.findLinearSearch(collisionObject) == m_collisionObjects.size()); - - m_collisionObjects.push_back(collisionObject); - - //calculate new AABB - btTransform trans = collisionObject->getWorldTransform(); - - btVector3 minAabb; - btVector3 maxAabb; - collisionObject->getCollisionShape()->getAabb(trans,minAabb,maxAabb); - - int type = collisionObject->getCollisionShape()->getShapeType(); - collisionObject->setBroadphaseHandle( getBroadphase()->createProxy( - minAabb, - maxAabb, - type, - collisionObject, - collisionFilterGroup, - collisionFilterMask, - m_dispatcher1 - )) ; - - - - - -} - - - - -void btCollisionWorld::performDiscreteCollisionDetection() -{ - btDispatcherInfo& dispatchInfo = getDispatchInfo(); - - BEGIN_PROFILE("perform Broadphase Collision Detection"); - - - //update aabb (of all moved objects) - - btVector3 aabbMin,aabbMax; - for (int i=0;igetCollisionShape()->getAabb(m_collisionObjects[i]->getWorldTransform(),aabbMin,aabbMax); - m_broadphasePairCache->setAabb(m_collisionObjects[i]->getBroadphaseHandle(),aabbMin,aabbMax,m_dispatcher1); - } - - m_broadphasePairCache->calculateOverlappingPairs(m_dispatcher1); - - END_PROFILE("perform Broadphase Collision Detection"); - - BEGIN_PROFILE("performDiscreteCollisionDetection"); - - btDispatcher* dispatcher = getDispatcher(); - if (dispatcher) - dispatcher->dispatchAllCollisionPairs(m_broadphasePairCache->getOverlappingPairCache(),dispatchInfo,m_dispatcher1); - - END_PROFILE("performDiscreteCollisionDetection"); - -} - - - -void btCollisionWorld::removeCollisionObject(btCollisionObject* collisionObject) -{ - - - //bool removeFromBroadphase = false; - - { - - btBroadphaseProxy* bp = collisionObject->getBroadphaseHandle(); - if (bp) - { - // - // only clear the cached algorithms - // - getBroadphase()->getOverlappingPairCache()->cleanProxyFromPairs(bp,m_dispatcher1); - getBroadphase()->destroyProxy(bp,m_dispatcher1); - collisionObject->setBroadphaseHandle(0); - } - } - - - //swapremove - m_collisionObjects.remove(collisionObject); - -} - - - -void btCollisionWorld::rayTestSingle(const btTransform& rayFromTrans,const btTransform& rayToTrans, - btCollisionObject* collisionObject, - const btCollisionShape* collisionShape, - const btTransform& colObjWorldTransform, - RayResultCallback& resultCallback,short int collisionFilterMask) -{ - - btSphereShape pointShape(btScalar(0.0)); - pointShape.setMargin(0.f); - - objectQuerySingle(&pointShape,rayFromTrans,rayToTrans, - collisionObject, - collisionShape, - colObjWorldTransform, - resultCallback,collisionFilterMask); -} - -void btCollisionWorld::objectQuerySingle(const btConvexShape* castShape,const btTransform& rayFromTrans,const btTransform& rayToTrans, - btCollisionObject* collisionObject, - const btCollisionShape* collisionShape, - const btTransform& colObjWorldTransform, - RayResultCallback& resultCallback,short int collisionFilterMask) -{ - - - if (collisionShape->isConvex()) - { - btConvexCast::CastResult castResult; - castResult.m_fraction = btScalar(1.);//?? - - btConvexShape* convexShape = (btConvexShape*) collisionShape; - btVoronoiSimplexSolver simplexSolver; -#define USE_SUBSIMPLEX_CONVEX_CAST 1 -#ifdef USE_SUBSIMPLEX_CONVEX_CAST - btSubsimplexConvexCast convexCaster(castShape,convexShape,&simplexSolver); -#else - //btGjkConvexCast convexCaster(castShape,convexShape,&simplexSolver); - //btContinuousConvexCollision convexCaster(castShape,convexShape,&simplexSolver,0); -#endif //#USE_SUBSIMPLEX_CONVEX_CAST - - if (convexCaster.calcTimeOfImpact(rayFromTrans,rayToTrans,colObjWorldTransform,colObjWorldTransform,castResult)) - { - //add hit - if (castResult.m_normal.length2() > btScalar(0.0001)) - { - - if (castResult.m_fraction < resultCallback.m_closestHitFraction) - { -#ifdef USE_SUBSIMPLEX_CONVEX_CAST - //rotate normal into worldspace - castResult.m_normal = rayFromTrans.getBasis() * castResult.m_normal; -#endif //USE_SUBSIMPLEX_CONVEX_CAST - - castResult.m_normal.normalize(); - btCollisionWorld::LocalRayResult localRayResult - ( - collisionObject, - 0, - castResult.m_normal, - castResult.m_fraction - ); - - bool normalInWorldSpace = true; - resultCallback.AddSingleResult(localRayResult, normalInWorldSpace); - - } - } - } - } - else - { - - if (collisionShape->isConcave()) - { - - btTriangleMeshShape* triangleMesh = (btTriangleMeshShape*)collisionShape; - - btTransform worldTocollisionObject = colObjWorldTransform.inverse(); - - btVector3 rayFromLocal = worldTocollisionObject * rayFromTrans.getOrigin(); - btVector3 rayToLocal = worldTocollisionObject * rayToTrans.getOrigin(); - - //ConvexCast::CastResult - - struct BridgeTriangleRaycastCallback : public btTriangleRaycastCallback - { - btCollisionWorld::RayResultCallback* m_resultCallback; - btCollisionObject* m_collisionObject; - btTriangleMeshShape* m_triangleMesh; - - BridgeTriangleRaycastCallback( const btVector3& from,const btVector3& to, - btCollisionWorld::RayResultCallback* resultCallback, btCollisionObject* collisionObject,btTriangleMeshShape* triangleMesh): - btTriangleRaycastCallback(from,to), - m_resultCallback(resultCallback), - m_collisionObject(collisionObject), - m_triangleMesh(triangleMesh) - { - } - - - virtual btScalar reportHit(const btVector3& hitNormalLocal, btScalar hitFraction, int partId, int triangleIndex ) - { - btCollisionWorld::LocalShapeInfo shapeInfo; - shapeInfo.m_shapePart = partId; - shapeInfo.m_triangleIndex = triangleIndex; - - btCollisionWorld::LocalRayResult rayResult - (m_collisionObject, - &shapeInfo, - hitNormalLocal, - hitFraction); - - bool normalInWorldSpace = false; - return m_resultCallback->AddSingleResult(rayResult,normalInWorldSpace); - - - } - - }; - - - BridgeTriangleRaycastCallback rcb(rayFromLocal,rayToLocal,&resultCallback,collisionObject,triangleMesh); - rcb.m_hitFraction = resultCallback.m_closestHitFraction; - - btVector3 rayAabbMinLocal = rayFromLocal; - rayAabbMinLocal.setMin(rayToLocal); - btVector3 rayAabbMaxLocal = rayFromLocal; - rayAabbMaxLocal.setMax(rayToLocal); - - triangleMesh->processAllTriangles(&rcb,rayAabbMinLocal,rayAabbMaxLocal); - - } else - { - //todo: use AABB tree or other BVH acceleration structure! - if (collisionShape->isCompound()) - { - const btCompoundShape* compoundShape = static_cast(collisionShape); - int i=0; - for (i=0;igetNumChildShapes();i++) - { - btTransform childTrans = compoundShape->getChildTransform(i); - const btCollisionShape* childCollisionShape = compoundShape->getChildShape(i); - btTransform childWorldTrans = colObjWorldTransform * childTrans; - objectQuerySingle(castShape, rayFromTrans,rayToTrans, - collisionObject, - childCollisionShape, - childWorldTrans, - resultCallback, collisionFilterMask); - - } - - - } - } - } -} - -void btCollisionWorld::rayTest(const btVector3& rayFromWorld, const btVector3& rayToWorld, RayResultCallback& resultCallback,short int collisionFilterMask) -{ - - - btTransform rayFromTrans,rayToTrans; - rayFromTrans.setIdentity(); - rayFromTrans.setOrigin(rayFromWorld); - rayToTrans.setIdentity(); - - rayToTrans.setOrigin(rayToWorld); - - /// go over all objects, and if the ray intersects their aabb, do a ray-shape query using convexCaster (CCD) - - int i; - for (i=0;igetBroadphaseHandle()->m_collisionFilterGroup & collisionFilterMask) { - //RigidcollisionObject* collisionObject = ctrl->GetRigidcollisionObject(); - btVector3 collisionObjectAabbMin,collisionObjectAabbMax; - collisionObject->getCollisionShape()->getAabb(collisionObject->getWorldTransform(),collisionObjectAabbMin,collisionObjectAabbMax); - - btScalar hitLambda = btScalar(1.); //could use resultCallback.m_closestHitFraction, but needs testing - btVector3 hitNormal; - if (btRayAabb(rayFromWorld,rayToWorld,collisionObjectAabbMin,collisionObjectAabbMax,hitLambda,hitNormal)) - { - rayTestSingle(rayFromTrans,rayToTrans, - collisionObject, - collisionObject->getCollisionShape(), - collisionObject->getWorldTransform(), - resultCallback); - } - } - } - -} diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionWorld.h b/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionWorld.h deleted file mode 100644 index bda03ccedeb..00000000000 --- a/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionWorld.h +++ /dev/null @@ -1,259 +0,0 @@ -/* -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. -*/ - - -/** - * @mainpage Bullet Documentation - * - * @section intro_sec Introduction - * Bullet Collision Detection & Physics SDK - * - * Bullet is a Collision Detection and Rigid Body Dynamics Library. The Library is Open Source and free for commercial use, under the ZLib license ( http://opensource.org/licenses/zlib-license.php ). - * - * There is the Physics Forum for Feedback and bteral Collision Detection and Physics discussions. - * Please visit http://www.continuousphysics.com/Bullet/phpBB2/index.php - * - * @section install_sec Installation - * - * @subsection step1 Step 1: Download - * You can download the Bullet Physics Library from our website: http://www.continuousphysics.com/Bullet/ - * @subsection step2 Step 2: Building - * Bullet comes with autogenerated Project Files for Microsoft Visual Studio 6, 7, 7.1 and 8. - * The main Workspace/Solution is located in Bullet/msvc/8/wksbullet.sln (replace 8 with your version). - * - * Under other platforms, like Linux or Mac OS-X, Bullet can be build using either using cmake, http://www.cmake.org, or jam, http://www.perforce.com/jam/jam.html . cmake can autogenerate Xcode, KDevelop, MSVC and other build systems. just run cmake . in the root of Bullet. - * Jam is a build system that can build the library, demos and also autogenerate the MSVC Project Files. - * So if you are not using MSVC, you can run configure and jam . - * If you don't have jam installed, you can make jam from the included jam-2.5 sources, or download jam from ftp://ftp.perforce.com/pub/jam/ - * - * @subsection step3 Step 3: Testing demos - * Try to run and experiment with CcdPhysicsDemo executable as a starting point. - * Bullet can be used in several ways, as Full Rigid Body simulation, as Collision Detector Library or Low Level / Snippets like the GJK Closest Point calculation. - * The Dependencies can be seen in this documentation under Directories - * - * @subsection step4 Step 4: Integrating in your application, Full Rigid Body Simulation - * Check out CcdPhysicsDemo how to create a btDynamicsWorld, btRigidBody and btCollisionShape, Stepping the simulation and synchronizing your graphics object transform. - * PLEASE NOTE THE CcdPhysicsEnvironment and CcdPhysicsController is obsolete and will be removed. It has been replaced by classes derived frmo btDynamicsWorld and btRididBody - * @subsection step5 Step 5 : Integrate the Collision Detection Library (without Dynamics and other Extras) - * Bullet Collision Detection can also be used without the Dynamics/Extras. - * Check out btCollisionWorld and btCollisionObject, and the CollisionInterfaceDemo. Also in Extras/test_BulletOde.cpp there is a sample Collision Detection integration with Open Dynamics Engine, ODE, http://www.ode.org - * @subsection step6 Step 6 : Use Snippets like the GJK Closest Point calculation. - * Bullet has been designed in a modular way keeping dependencies to a minimum. The ConvexHullDistance demo demonstrates direct use of btGjkPairDetector. - * - * @section copyright Copyright - * Copyright (C) 2005-2007 Erwin Coumans, some contributions Copyright Gino van den Bergen, Christer Ericson, Simon Hobbs, Ricardo Padrela, F Richter(res), Stephane Redon - * Special thanks to all visitors of the Bullet Physics forum, and in particular above contributors, Dave Eberle, Dirk Gregorius, Erin Catto, Dave Eberle, Adam Moravanszky, - * Pierre Terdiman, Kenny Erleben, Russell Smith, Oliver Strunk, Jan Paul van Waveren, Marten Svanfeldt. - * - */ - - - -#ifndef COLLISION_WORLD_H -#define COLLISION_WORLD_H - -class btStackAlloc; -class btCollisionShape; -class btConvexShape; -class btBroadphaseInterface; -#include "LinearMath/btVector3.h" -#include "LinearMath/btTransform.h" -#include "btCollisionObject.h" -#include "btCollisionDispatcher.h" //for definition of btCollisionObjectArray -#include "BulletCollision/BroadphaseCollision/btOverlappingPairCache.h" -#include "LinearMath/btAlignedObjectArray.h" - -///CollisionWorld is interface and container for the collision detection -class btCollisionWorld -{ - - -protected: - - btAlignedObjectArray m_collisionObjects; - - btDispatcher* m_dispatcher1; - - btDispatcherInfo m_dispatchInfo; - - btStackAlloc* m_stackAlloc; - - btBroadphaseInterface* m_broadphasePairCache; - -public: - - //this constructor doesn't own the dispatcher and paircache/broadphase - btCollisionWorld(btDispatcher* dispatcher,btBroadphaseInterface* broadphasePairCache, btCollisionConfiguration* collisionConfiguration); - - virtual ~btCollisionWorld(); - - - btBroadphaseInterface* getBroadphase() - { - return m_broadphasePairCache; - } - - btOverlappingPairCache* getPairCache() - { - return m_broadphasePairCache->getOverlappingPairCache(); - } - - - btDispatcher* getDispatcher() - { - return m_dispatcher1; - } - - ///LocalShapeInfo gives extra information for complex shapes - ///Currently, only btTriangleMeshShape is available, so it just contains triangleIndex and subpart - struct LocalShapeInfo - { - int m_shapePart; - int m_triangleIndex; - - //const btCollisionShape* m_shapeTemp; - //const btTransform* m_shapeLocalTransform; - }; - - struct LocalRayResult - { - LocalRayResult(btCollisionObject* collisionObject, - LocalShapeInfo* localShapeInfo, - const btVector3& hitNormalLocal, - btScalar hitFraction) - :m_collisionObject(collisionObject), - m_localShapeInfo(localShapeInfo), - m_hitNormalLocal(hitNormalLocal), - m_hitFraction(hitFraction) - { - } - - btCollisionObject* m_collisionObject; - LocalShapeInfo* m_localShapeInfo; - btVector3 m_hitNormalLocal; - btScalar m_hitFraction; - - }; - - ///RayResultCallback is used to report new raycast results - struct RayResultCallback - { - virtual ~RayResultCallback() - { - } - btScalar m_closestHitFraction; - bool HasHit() - { - return (m_closestHitFraction < btScalar(1.)); - } - - RayResultCallback() - :m_closestHitFraction(btScalar(1.)) - { - } - virtual btScalar AddSingleResult(LocalRayResult& rayResult,bool normalInWorldSpace) = 0; - }; - - struct ClosestRayResultCallback : public RayResultCallback - { - ClosestRayResultCallback(const btVector3& rayFromWorld,const btVector3& rayToWorld) - :m_rayFromWorld(rayFromWorld), - m_rayToWorld(rayToWorld), - m_collisionObject(0) - { - } - - btVector3 m_rayFromWorld;//used to calculate hitPointWorld from hitFraction - btVector3 m_rayToWorld; - - btVector3 m_hitNormalWorld; - btVector3 m_hitPointWorld; - btCollisionObject* m_collisionObject; - - virtual btScalar AddSingleResult(LocalRayResult& rayResult,bool normalInWorldSpace) - { - -//caller already does the filter on the m_closestHitFraction - assert(rayResult.m_hitFraction <= m_closestHitFraction); - - m_closestHitFraction = rayResult.m_hitFraction; - m_collisionObject = rayResult.m_collisionObject; - if (normalInWorldSpace) - { - m_hitNormalWorld = rayResult.m_hitNormalLocal; - } else - { - ///need to transform normal into worldspace - m_hitNormalWorld = m_collisionObject->getWorldTransform().getBasis()*rayResult.m_hitNormalLocal; - } - m_hitPointWorld.setInterpolate3(m_rayFromWorld,m_rayToWorld,rayResult.m_hitFraction); - return rayResult.m_hitFraction; - } - }; - - - - - int getNumCollisionObjects() const - { - return int(m_collisionObjects.size()); - } - - /// rayTest performs a raycast on all objects in the btCollisionWorld, and calls the resultCallback - /// This allows for several queries: first hit, all hits, any hit, dependent on the value returned by the callback. - void rayTest(const btVector3& rayFromWorld, const btVector3& rayToWorld, RayResultCallback& resultCallback, short int collisionFilterMask=-1); - - /// rayTestSingle performs a raycast call and calls the resultCallback. It is used internally by rayTest. - /// In a future implementation, we consider moving the ray test as a virtual method in btCollisionShape. - /// This allows more customization. - static void rayTestSingle(const btTransform& rayFromTrans,const btTransform& rayToTrans, - btCollisionObject* collisionObject, - const btCollisionShape* collisionShape, - const btTransform& colObjWorldTransform, - RayResultCallback& resultCallback, short int collisionFilterMask=-1); - - /// objectQuerySingle performs a collision detection query and calls the resultCallback. It is used internally by rayTest. - static void objectQuerySingle(const btConvexShape* castShape, const btTransform& rayFromTrans,const btTransform& rayToTrans, - btCollisionObject* collisionObject, - const btCollisionShape* collisionShape, - const btTransform& colObjWorldTransform, - RayResultCallback& resultCallback, short int collisionFilterMask=-1); - - void addCollisionObject(btCollisionObject* collisionObject,short int collisionFilterGroup=1,short int collisionFilterMask=1); - - btCollisionObjectArray& getCollisionObjectArray() - { - return m_collisionObjects; - } - - const btCollisionObjectArray& getCollisionObjectArray() const - { - return m_collisionObjects; - } - - - void removeCollisionObject(btCollisionObject* collisionObject); - - virtual void performDiscreteCollisionDetection(); - - btDispatcherInfo& getDispatchInfo() - { - return m_dispatchInfo; - } - -}; - - -#endif //COLLISION_WORLD_H diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.cpp b/extern/bullet2/src/BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.cpp deleted file mode 100644 index 7c0c7a3b0a9..00000000000 --- a/extern/bullet2/src/BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.cpp +++ /dev/null @@ -1,142 +0,0 @@ -/* -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 "BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.h" -#include "BulletCollision/CollisionDispatch/btCollisionObject.h" -#include "BulletCollision/CollisionShapes/btCompoundShape.h" - - -btCompoundCollisionAlgorithm::btCompoundCollisionAlgorithm( const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* body0,btCollisionObject* body1,bool isSwapped) -:btCollisionAlgorithm(ci), -m_isSwapped(isSwapped) -{ - btCollisionObject* colObj = m_isSwapped? body1 : body0; - btCollisionObject* otherObj = m_isSwapped? body0 : body1; - assert (colObj->getCollisionShape()->isCompound()); - - btCompoundShape* compoundShape = static_cast(colObj->getCollisionShape()); - int numChildren = compoundShape->getNumChildShapes(); - int i; - - m_childCollisionAlgorithms.resize(numChildren); - for (i=0;igetChildShape(i); - btCollisionShape* orgShape = colObj->getCollisionShape(); - colObj->setCollisionShape( childShape ); - m_childCollisionAlgorithms[i] = ci.m_dispatcher1->findAlgorithm(colObj,otherObj); - colObj->setCollisionShape( orgShape ); - } -} - - -btCompoundCollisionAlgorithm::~btCompoundCollisionAlgorithm() -{ - int numChildren = m_childCollisionAlgorithms.size(); - int i; - for (i=0;i~btCollisionAlgorithm(); - m_dispatcher->freeCollisionAlgorithm(m_childCollisionAlgorithms[i]); - } -} - -void btCompoundCollisionAlgorithm::processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut) -{ - btCollisionObject* colObj = m_isSwapped? body1 : body0; - btCollisionObject* otherObj = m_isSwapped? body0 : body1; - - assert (colObj->getCollisionShape()->isCompound()); - btCompoundShape* compoundShape = static_cast(colObj->getCollisionShape()); - - //We will use the OptimizedBVH, AABB tree to cull potential child-overlaps - //If both proxies are Compound, we will deal with that directly, by performing sequential/parallel tree traversals - //given Proxy0 and Proxy1, if both have a tree, Tree0 and Tree1, this means: - //determine overlapping nodes of Proxy1 using Proxy0 AABB against Tree1 - //then use each overlapping node AABB against Tree0 - //and vise versa. - - int numChildren = m_childCollisionAlgorithms.size(); - int i; - for (i=0;igetChildShape(i); - - //backup - btTransform orgTrans = colObj->getWorldTransform(); - btCollisionShape* orgShape = colObj->getCollisionShape(); - - const btTransform& childTrans = compoundShape->getChildTransform(i); - //btTransform newChildWorldTrans = orgTrans*childTrans ; - colObj->setWorldTransform( orgTrans*childTrans ); - //the contactpoint is still projected back using the original inverted worldtrans - colObj->setCollisionShape( childShape ); - m_childCollisionAlgorithms[i]->processCollision(colObj,otherObj,dispatchInfo,resultOut); - //revert back - colObj->setCollisionShape( orgShape); - colObj->setWorldTransform( orgTrans ); - } -} - -btScalar btCompoundCollisionAlgorithm::calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut) -{ - - btCollisionObject* colObj = m_isSwapped? body1 : body0; - btCollisionObject* otherObj = m_isSwapped? body0 : body1; - - assert (colObj->getCollisionShape()->isCompound()); - - btCompoundShape* compoundShape = static_cast(colObj->getCollisionShape()); - - //We will use the OptimizedBVH, AABB tree to cull potential child-overlaps - //If both proxies are Compound, we will deal with that directly, by performing sequential/parallel tree traversals - //given Proxy0 and Proxy1, if both have a tree, Tree0 and Tree1, this means: - //determine overlapping nodes of Proxy1 using Proxy0 AABB against Tree1 - //then use each overlapping node AABB against Tree0 - //and vise versa. - - btScalar hitFraction = btScalar(1.); - - int numChildren = m_childCollisionAlgorithms.size(); - int i; - for (i=0;igetChildShape(i); - - //backup - btTransform orgTrans = colObj->getWorldTransform(); - btCollisionShape* orgShape = colObj->getCollisionShape(); - - const btTransform& childTrans = compoundShape->getChildTransform(i); - //btTransform newChildWorldTrans = orgTrans*childTrans ; - colObj->setWorldTransform( orgTrans*childTrans ); - - colObj->setCollisionShape( childShape ); - btScalar frac = m_childCollisionAlgorithms[i]->calculateTimeOfImpact(colObj,otherObj,dispatchInfo,resultOut); - if (fracsetCollisionShape( orgShape); - colObj->setWorldTransform( orgTrans); - } - return hitFraction; - -} - - diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.h b/extern/bullet2/src/BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.h deleted file mode 100644 index a381d8b3c3f..00000000000 --- a/extern/bullet2/src/BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.h +++ /dev/null @@ -1,67 +0,0 @@ -/* -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 COMPOUND_COLLISION_ALGORITHM_H -#define COMPOUND_COLLISION_ALGORITHM_H - -#include "BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h" -#include "BulletCollision/BroadphaseCollision/btDispatcher.h" -#include "BulletCollision/BroadphaseCollision/btBroadphaseInterface.h" - -#include "BulletCollision/NarrowPhaseCollision/btPersistentManifold.h" -class btDispatcher; -#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" -#include "btCollisionCreateFunc.h" -#include "LinearMath/btAlignedObjectArray.h" -class btDispatcher; - -/// btCompoundCollisionAlgorithm supports collision between CompoundCollisionShapes and other collision shapes -/// Place holder, not fully implemented yet -class btCompoundCollisionAlgorithm : public btCollisionAlgorithm -{ - btAlignedObjectArray m_childCollisionAlgorithms; - bool m_isSwapped; - -public: - - btCompoundCollisionAlgorithm( const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* body0,btCollisionObject* body1,bool isSwapped); - - virtual ~btCompoundCollisionAlgorithm(); - - virtual void processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut); - - btScalar calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut); - - struct CreateFunc :public btCollisionAlgorithmCreateFunc - { - virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, btCollisionObject* body0,btCollisionObject* body1) - { - void* mem = ci.m_dispatcher1->allocateCollisionAlgorithm(sizeof(btCompoundCollisionAlgorithm)); - return new(mem) btCompoundCollisionAlgorithm(ci,body0,body1,false); - } - }; - - struct SwappedCreateFunc :public btCollisionAlgorithmCreateFunc - { - virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, btCollisionObject* body0,btCollisionObject* body1) - { - void* mem = ci.m_dispatcher1->allocateCollisionAlgorithm(sizeof(btCompoundCollisionAlgorithm)); - return new(mem) btCompoundCollisionAlgorithm(ci,body0,body1,true); - } - }; - -}; - -#endif //COMPOUND_COLLISION_ALGORITHM_H diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btConvexConcaveCollisionAlgorithm.cpp b/extern/bullet2/src/BulletCollision/CollisionDispatch/btConvexConcaveCollisionAlgorithm.cpp deleted file mode 100644 index 559b633feb9..00000000000 --- a/extern/bullet2/src/BulletCollision/CollisionDispatch/btConvexConcaveCollisionAlgorithm.cpp +++ /dev/null @@ -1,314 +0,0 @@ -/* -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 "btConvexConcaveCollisionAlgorithm.h" -#include "BulletCollision/CollisionDispatch/btCollisionObject.h" -#include "BulletCollision/CollisionShapes/btMultiSphereShape.h" -#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" -#include "BulletCollision/CollisionShapes/btConcaveShape.h" -#include "BulletCollision/CollisionDispatch/btManifoldResult.h" -#include "BulletCollision/NarrowPhaseCollision/btRaycastCallback.h" -#include "BulletCollision/CollisionShapes/btTriangleShape.h" -#include "BulletCollision/CollisionShapes/btSphereShape.h" -#include "LinearMath/btIDebugDraw.h" -#include "BulletCollision/NarrowPhaseCollision/btSubSimplexConvexCast.h" - -btConvexConcaveCollisionAlgorithm::btConvexConcaveCollisionAlgorithm( const btCollisionAlgorithmConstructionInfo& ci, btCollisionObject* body0,btCollisionObject* body1,bool isSwapped) -: btCollisionAlgorithm(ci), -m_isSwapped(isSwapped), -m_btConvexTriangleCallback(ci.m_dispatcher1,body0,body1,isSwapped) -{ -} - -btConvexConcaveCollisionAlgorithm::~btConvexConcaveCollisionAlgorithm() -{ -} - - - -btConvexTriangleCallback::btConvexTriangleCallback(btDispatcher* dispatcher,btCollisionObject* body0,btCollisionObject* body1,bool isSwapped): - m_dispatcher(dispatcher), - m_dispatchInfoPtr(0) -{ - m_convexBody = isSwapped? body1:body0; - m_triBody = isSwapped? body0:body1; - - // - // create the manifold from the dispatcher 'manifold pool' - // - m_manifoldPtr = m_dispatcher->getNewManifold(m_convexBody,m_triBody); - - clearCache(); -} - -btConvexTriangleCallback::~btConvexTriangleCallback() -{ - clearCache(); - m_dispatcher->releaseManifold( m_manifoldPtr ); - -} - - -void btConvexTriangleCallback::clearCache() -{ - m_dispatcher->clearManifold(m_manifoldPtr); -}; - - - -void btConvexTriangleCallback::processTriangle(btVector3* triangle,int partId, int triangleIndex) -{ - - //just for debugging purposes - //printf("triangle %d",m_triangleCount++); - - - //aabb filter is already applied! - - btCollisionAlgorithmConstructionInfo ci; - ci.m_dispatcher1 = m_dispatcher; - - btCollisionObject* ob = static_cast(m_triBody); - - - - ///debug drawing of the overlapping triangles - if (m_dispatchInfoPtr && m_dispatchInfoPtr->m_debugDraw && m_dispatchInfoPtr->m_debugDraw->getDebugMode() > 0) - { - btVector3 color(255,255,0); - btTransform& tr = ob->getWorldTransform(); - m_dispatchInfoPtr->m_debugDraw->drawLine(tr(triangle[0]),tr(triangle[1]),color); - m_dispatchInfoPtr->m_debugDraw->drawLine(tr(triangle[1]),tr(triangle[2]),color); - m_dispatchInfoPtr->m_debugDraw->drawLine(tr(triangle[2]),tr(triangle[0]),color); - - //btVector3 center = triangle[0] + triangle[1]+triangle[2]; - //center *= btScalar(0.333333); - //m_dispatchInfoPtr->m_debugDraw->drawLine(tr(triangle[0]),tr(center),color); - //m_dispatchInfoPtr->m_debugDraw->drawLine(tr(triangle[1]),tr(center),color); - //m_dispatchInfoPtr->m_debugDraw->drawLine(tr(triangle[2]),tr(center),color); - - } - - - //btCollisionObject* colObj = static_cast(m_convexProxy->m_clientObject); - - if (m_convexBody->getCollisionShape()->isConvex()) - { - btTriangleShape tm(triangle[0],triangle[1],triangle[2]); - tm.setMargin(m_collisionMarginTriangle); - - - btCollisionShape* tmpShape = ob->getCollisionShape(); - ob->setCollisionShape( &tm ); - - - btCollisionAlgorithm* colAlgo = ci.m_dispatcher1->findAlgorithm(m_convexBody,m_triBody,m_manifoldPtr); - ///this should use the btDispatcher, so the actual registered algorithm is used - // btConvexConvexAlgorithm cvxcvxalgo(m_manifoldPtr,ci,m_convexBody,m_triBody); - - m_resultOut->setShapeIdentifiers(-1,-1,partId,triangleIndex); - // cvxcvxalgo.setShapeIdentifiers(-1,-1,partId,triangleIndex); -// cvxcvxalgo.processCollision(m_convexBody,m_triBody,*m_dispatchInfoPtr,m_resultOut); - colAlgo->processCollision(m_convexBody,m_triBody,*m_dispatchInfoPtr,m_resultOut); - colAlgo->~btCollisionAlgorithm(); - ci.m_dispatcher1->freeCollisionAlgorithm(colAlgo); - ob->setCollisionShape( tmpShape ); - - } - - - -} - - - -void btConvexTriangleCallback::setTimeStepAndCounters(btScalar collisionMarginTriangle,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut) -{ - m_dispatchInfoPtr = &dispatchInfo; - m_collisionMarginTriangle = collisionMarginTriangle; - m_resultOut = resultOut; - - //recalc aabbs - btTransform convexInTriangleSpace; - convexInTriangleSpace = m_triBody->getWorldTransform().inverse() * m_convexBody->getWorldTransform(); - btCollisionShape* convexShape = static_cast(m_convexBody->getCollisionShape()); - //CollisionShape* triangleShape = static_cast(triBody->m_collisionShape); - convexShape->getAabb(convexInTriangleSpace,m_aabbMin,m_aabbMax); - btScalar extraMargin = collisionMarginTriangle; - btVector3 extra(extraMargin,extraMargin,extraMargin); - - m_aabbMax += extra; - m_aabbMin -= extra; - -} - -void btConvexConcaveCollisionAlgorithm::clearCache() -{ - m_btConvexTriangleCallback.clearCache(); - -} - -void btConvexConcaveCollisionAlgorithm::processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut) -{ - - - btCollisionObject* convexBody = m_isSwapped ? body1 : body0; - btCollisionObject* triBody = m_isSwapped ? body0 : body1; - - if (triBody->getCollisionShape()->isConcave()) - { - - - btCollisionObject* triOb = triBody; - btConcaveShape* concaveShape = static_cast( triOb->getCollisionShape()); - - if (convexBody->getCollisionShape()->isConvex()) - { - btScalar collisionMarginTriangle = concaveShape->getMargin(); - - resultOut->setPersistentManifold(m_btConvexTriangleCallback.m_manifoldPtr); - m_btConvexTriangleCallback.setTimeStepAndCounters(collisionMarginTriangle,dispatchInfo,resultOut); - - //Disable persistency. previously, some older algorithm calculated all contacts in one go, so you can clear it here. - //m_dispatcher->clearManifold(m_btConvexTriangleCallback.m_manifoldPtr); - - m_btConvexTriangleCallback.m_manifoldPtr->setBodies(convexBody,triBody); - - concaveShape->processAllTriangles( &m_btConvexTriangleCallback,m_btConvexTriangleCallback.getAabbMin(),m_btConvexTriangleCallback.getAabbMax()); - - resultOut->refreshContactPoints(); - - } - - } - -} - - -btScalar btConvexConcaveCollisionAlgorithm::calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut) -{ - (void)resultOut; - (void)dispatchInfo; - btCollisionObject* convexbody = m_isSwapped ? body1 : body0; - btCollisionObject* triBody = m_isSwapped ? body0 : body1; - - - //quick approximation using raycast, todo: hook up to the continuous collision detection (one of the btConvexCast) - - //only perform CCD above a certain threshold, this prevents blocking on the long run - //because object in a blocked ccd state (hitfraction<1) get their linear velocity halved each frame... - btScalar squareMot0 = (convexbody->getInterpolationWorldTransform().getOrigin() - convexbody->getWorldTransform().getOrigin()).length2(); - if (squareMot0 < convexbody->getCcdSquareMotionThreshold()) - { - return btScalar(1.); - } - - //const btVector3& from = convexbody->m_worldTransform.getOrigin(); - //btVector3 to = convexbody->m_interpolationWorldTransform.getOrigin(); - //todo: only do if the motion exceeds the 'radius' - - btTransform triInv = triBody->getWorldTransform().inverse(); - btTransform convexFromLocal = triInv * convexbody->getWorldTransform(); - btTransform convexToLocal = triInv * convexbody->getInterpolationWorldTransform(); - - struct LocalTriangleSphereCastCallback : public btTriangleCallback - { - btTransform m_ccdSphereFromTrans; - btTransform m_ccdSphereToTrans; - btTransform m_meshTransform; - - btScalar m_ccdSphereRadius; - btScalar m_hitFraction; - - - LocalTriangleSphereCastCallback(const btTransform& from,const btTransform& to,btScalar ccdSphereRadius,btScalar hitFraction) - :m_ccdSphereFromTrans(from), - m_ccdSphereToTrans(to), - m_ccdSphereRadius(ccdSphereRadius), - m_hitFraction(hitFraction) - { - } - - - virtual void processTriangle(btVector3* triangle, int partId, int triangleIndex) - { - (void)partId; - (void)triangleIndex; - //do a swept sphere for now - btTransform ident; - ident.setIdentity(); - btConvexCast::CastResult castResult; - castResult.m_fraction = m_hitFraction; - btSphereShape pointShape(m_ccdSphereRadius); - btTriangleShape triShape(triangle[0],triangle[1],triangle[2]); - btVoronoiSimplexSolver simplexSolver; - btSubsimplexConvexCast convexCaster(&pointShape,&triShape,&simplexSolver); - //GjkConvexCast convexCaster(&pointShape,convexShape,&simplexSolver); - //ContinuousConvexCollision convexCaster(&pointShape,convexShape,&simplexSolver,0); - //local space? - - if (convexCaster.calcTimeOfImpact(m_ccdSphereFromTrans,m_ccdSphereToTrans, - ident,ident,castResult)) - { - if (m_hitFraction > castResult.m_fraction) - m_hitFraction = castResult.m_fraction; - } - - } - - }; - - - - - - if (triBody->getCollisionShape()->isConcave()) - { - btVector3 rayAabbMin = convexFromLocal.getOrigin(); - rayAabbMin.setMin(convexToLocal.getOrigin()); - btVector3 rayAabbMax = convexFromLocal.getOrigin(); - rayAabbMax.setMax(convexToLocal.getOrigin()); - btScalar ccdRadius0 = convexbody->getCcdSweptSphereRadius(); - rayAabbMin -= btVector3(ccdRadius0,ccdRadius0,ccdRadius0); - rayAabbMax += btVector3(ccdRadius0,ccdRadius0,ccdRadius0); - - btScalar curHitFraction = btScalar(1.); //is this available? - LocalTriangleSphereCastCallback raycastCallback(convexFromLocal,convexToLocal, - convexbody->getCcdSweptSphereRadius(),curHitFraction); - - raycastCallback.m_hitFraction = convexbody->getHitFraction(); - - btCollisionObject* concavebody = triBody; - - btConcaveShape* triangleMesh = (btConcaveShape*) concavebody->getCollisionShape(); - - if (triangleMesh) - { - triangleMesh->processAllTriangles(&raycastCallback,rayAabbMin,rayAabbMax); - } - - - - if (raycastCallback.m_hitFraction < convexbody->getHitFraction()) - { - convexbody->setHitFraction( raycastCallback.m_hitFraction); - return raycastCallback.m_hitFraction; - } - } - - return btScalar(1.); - -} diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btConvexConcaveCollisionAlgorithm.h b/extern/bullet2/src/BulletCollision/CollisionDispatch/btConvexConcaveCollisionAlgorithm.h deleted file mode 100644 index da33e988991..00000000000 --- a/extern/bullet2/src/BulletCollision/CollisionDispatch/btConvexConcaveCollisionAlgorithm.h +++ /dev/null @@ -1,113 +0,0 @@ -/* -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 CONVEX_CONCAVE_COLLISION_ALGORITHM_H -#define CONVEX_CONCAVE_COLLISION_ALGORITHM_H - -#include "BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h" -#include "BulletCollision/BroadphaseCollision/btDispatcher.h" -#include "BulletCollision/BroadphaseCollision/btBroadphaseInterface.h" -#include "BulletCollision/CollisionShapes/btTriangleCallback.h" -#include "BulletCollision/NarrowPhaseCollision/btPersistentManifold.h" -class btDispatcher; -#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" -#include "btCollisionCreateFunc.h" - -///For each triangle in the concave mesh that overlaps with the AABB of a convex (m_convexProxy), processTriangle is called. -class btConvexTriangleCallback : public btTriangleCallback -{ - btCollisionObject* m_convexBody; - btCollisionObject* m_triBody; - - btVector3 m_aabbMin; - btVector3 m_aabbMax ; - - btManifoldResult* m_resultOut; - - btDispatcher* m_dispatcher; - const btDispatcherInfo* m_dispatchInfoPtr; - btScalar m_collisionMarginTriangle; - -public: -int m_triangleCount; - - btPersistentManifold* m_manifoldPtr; - - btConvexTriangleCallback(btDispatcher* dispatcher,btCollisionObject* body0,btCollisionObject* body1,bool isSwapped); - - void setTimeStepAndCounters(btScalar collisionMarginTriangle,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut); - - virtual ~btConvexTriangleCallback(); - - virtual void processTriangle(btVector3* triangle, int partId, int triangleIndex); - - void clearCache(); - - SIMD_FORCE_INLINE const btVector3& getAabbMin() const - { - return m_aabbMin; - } - SIMD_FORCE_INLINE const btVector3& getAabbMax() const - { - return m_aabbMax; - } - -}; - - - - -/// btConvexConcaveCollisionAlgorithm supports collision between convex shapes and (concave) trianges meshes. -class btConvexConcaveCollisionAlgorithm : public btCollisionAlgorithm -{ - - bool m_isSwapped; - - btConvexTriangleCallback m_btConvexTriangleCallback; - - -public: - - btConvexConcaveCollisionAlgorithm( const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* body0,btCollisionObject* body1,bool isSwapped); - - virtual ~btConvexConcaveCollisionAlgorithm(); - - virtual void processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut); - - btScalar calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut); - - void clearCache(); - - struct CreateFunc :public btCollisionAlgorithmCreateFunc - { - virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, btCollisionObject* body0,btCollisionObject* body1) - { - void* mem = ci.m_dispatcher1->allocateCollisionAlgorithm(sizeof(btConvexConcaveCollisionAlgorithm)); - return new(mem) btConvexConcaveCollisionAlgorithm(ci,body0,body1,false); - } - }; - - struct SwappedCreateFunc :public btCollisionAlgorithmCreateFunc - { - virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, btCollisionObject* body0,btCollisionObject* body1) - { - void* mem = ci.m_dispatcher1->allocateCollisionAlgorithm(sizeof(btConvexConcaveCollisionAlgorithm)); - return new(mem) btConvexConcaveCollisionAlgorithm(ci,body0,body1,true); - } - }; - -}; - -#endif //CONVEX_CONCAVE_COLLISION_ALGORITHM_H diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btConvexConvexAlgorithm.cpp b/extern/bullet2/src/BulletCollision/CollisionDispatch/btConvexConvexAlgorithm.cpp deleted file mode 100644 index d1692cdac69..00000000000 --- a/extern/bullet2/src/BulletCollision/CollisionDispatch/btConvexConvexAlgorithm.cpp +++ /dev/null @@ -1,249 +0,0 @@ -/* -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 "btConvexConvexAlgorithm.h" - -#include -#include "BulletCollision/NarrowPhaseCollision/btDiscreteCollisionDetectorInterface.h" -#include "BulletCollision/BroadphaseCollision/btBroadphaseInterface.h" -#include "BulletCollision/CollisionDispatch/btCollisionObject.h" -#include "BulletCollision/CollisionShapes/btConvexShape.h" -#include "BulletCollision/NarrowPhaseCollision/btGjkPairDetector.h" -#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" -#include "BulletCollision/CollisionDispatch/btCollisionDispatcher.h" -#include "BulletCollision/CollisionShapes/btBoxShape.h" -#include "BulletCollision/CollisionDispatch/btManifoldResult.h" - -#include "BulletCollision/NarrowPhaseCollision/btConvexPenetrationDepthSolver.h" -#include "BulletCollision/NarrowPhaseCollision/btContinuousConvexCollision.h" -#include "BulletCollision/NarrowPhaseCollision/btSubSimplexConvexCast.h" -#include "BulletCollision/NarrowPhaseCollision/btGjkConvexCast.h" - - - -#include "BulletCollision/CollisionShapes/btMinkowskiSumShape.h" -#include "BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.h" -#include "BulletCollision/CollisionShapes/btSphereShape.h" - -#include "BulletCollision/NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.h" - -#include "BulletCollision/NarrowPhaseCollision/btGjkEpa.h" -#include "BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.h" - - - - - - - - - -btConvexConvexAlgorithm::CreateFunc::CreateFunc(btSimplexSolverInterface* simplexSolver, btConvexPenetrationDepthSolver* pdSolver) -{ - m_simplexSolver = simplexSolver; - m_pdSolver = pdSolver; -} - -btConvexConvexAlgorithm::CreateFunc::~CreateFunc() -{ -} - -btConvexConvexAlgorithm::btConvexConvexAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* body0,btCollisionObject* body1,btSimplexSolverInterface* simplexSolver, btConvexPenetrationDepthSolver* pdSolver) -: btCollisionAlgorithm(ci), -m_gjkPairDetector(0,0,simplexSolver,pdSolver), -m_ownManifold (false), -m_manifoldPtr(mf), -m_lowLevelOfDetail(false) -{ - (void)body0; - (void)body1; - - -} - - - - -btConvexConvexAlgorithm::~btConvexConvexAlgorithm() -{ - if (m_ownManifold) - { - if (m_manifoldPtr) - m_dispatcher->releaseManifold(m_manifoldPtr); - } -} - -void btConvexConvexAlgorithm ::setLowLevelOfDetail(bool useLowLevel) -{ - m_lowLevelOfDetail = useLowLevel; -} - - - - - -// -// Convex-Convex collision algorithm -// -void btConvexConvexAlgorithm ::processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut) -{ - - if (!m_manifoldPtr) - { - //swapped? - m_manifoldPtr = m_dispatcher->getNewManifold(body0,body1); - m_ownManifold = true; - } - resultOut->setPersistentManifold(m_manifoldPtr); - -#ifdef USE_BT_GJKEPA - btConvexShape* shape0(static_cast(body0->getCollisionShape())); - btConvexShape* shape1(static_cast(body1->getCollisionShape())); - const btScalar radialmargin(0/*shape0->getMargin()+shape1->getMargin()*/); - btGjkEpaSolver::sResults results; - if(btGjkEpaSolver::Collide( shape0,body0->getWorldTransform(), - shape1,body1->getWorldTransform(), - radialmargin,results)) - { - dispatchInfo.m_debugDraw->drawLine(results.witnesses[1],results.witnesses[1]+results.normal,btVector3(255,0,0)); - resultOut->addContactPoint(results.normal,results.witnesses[1],-results.depth); - } -#else - - btConvexShape* min0 = static_cast(body0->getCollisionShape()); - btConvexShape* min1 = static_cast(body1->getCollisionShape()); - - btGjkPairDetector::ClosestPointInput input; - - //TODO: if (dispatchInfo.m_useContinuous) - m_gjkPairDetector.setMinkowskiA(min0); - m_gjkPairDetector.setMinkowskiB(min1); - input.m_maximumDistanceSquared = min0->getMargin() + min1->getMargin() + m_manifoldPtr->getContactBreakingThreshold(); - input.m_maximumDistanceSquared*= input.m_maximumDistanceSquared; - input.m_stackAlloc = dispatchInfo.m_stackAllocator; - -// input.m_maximumDistanceSquared = btScalar(1e30); - - input.m_transformA = body0->getWorldTransform(); - input.m_transformB = body1->getWorldTransform(); - - m_gjkPairDetector.getClosestPoints(input,*resultOut,dispatchInfo.m_debugDraw); -#endif - - if (m_ownManifold) - { - resultOut->refreshContactPoints(); - } - -} - - - -bool disableCcd = false; -btScalar btConvexConvexAlgorithm::calculateTimeOfImpact(btCollisionObject* col0,btCollisionObject* col1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut) -{ - (void)resultOut; - (void)dispatchInfo; - ///Rather then checking ALL pairs, only calculate TOI when motion exceeds threshold - - ///Linear motion for one of objects needs to exceed m_ccdSquareMotionThreshold - ///col0->m_worldTransform, - btScalar resultFraction = btScalar(1.); - - - btScalar squareMot0 = (col0->getInterpolationWorldTransform().getOrigin() - col0->getWorldTransform().getOrigin()).length2(); - btScalar squareMot1 = (col1->getInterpolationWorldTransform().getOrigin() - col1->getWorldTransform().getOrigin()).length2(); - - if (squareMot0 < col0->getCcdSquareMotionThreshold() && - squareMot1 < col1->getCcdSquareMotionThreshold()) - return resultFraction; - - if (disableCcd) - return btScalar(1.); - - - //An adhoc way of testing the Continuous Collision Detection algorithms - //One object is approximated as a sphere, to simplify things - //Starting in penetration should report no time of impact - //For proper CCD, better accuracy and handling of 'allowed' penetration should be added - //also the mainloop of the physics should have a kind of toi queue (something like Brian Mirtich's application of Timewarp for Rigidbodies) - - - /// Convex0 against sphere for Convex1 - { - btConvexShape* convex0 = static_cast(col0->getCollisionShape()); - - btSphereShape sphere1(col1->getCcdSweptSphereRadius()); //todo: allow non-zero sphere sizes, for better approximation - btConvexCast::CastResult result; - btVoronoiSimplexSolver voronoiSimplex; - //SubsimplexConvexCast ccd0(&sphere,min0,&voronoiSimplex); - ///Simplification, one object is simplified as a sphere - btGjkConvexCast ccd1( convex0 ,&sphere1,&voronoiSimplex); - //ContinuousConvexCollision ccd(min0,min1,&voronoiSimplex,0); - if (ccd1.calcTimeOfImpact(col0->getWorldTransform(),col0->getInterpolationWorldTransform(), - col1->getWorldTransform(),col1->getInterpolationWorldTransform(),result)) - { - - //store result.m_fraction in both bodies - - if (col0->getHitFraction()> result.m_fraction) - col0->setHitFraction( result.m_fraction ); - - if (col1->getHitFraction() > result.m_fraction) - col1->setHitFraction( result.m_fraction); - - if (resultFraction > result.m_fraction) - resultFraction = result.m_fraction; - - } - - - - - } - - /// Sphere (for convex0) against Convex1 - { - btConvexShape* convex1 = static_cast(col1->getCollisionShape()); - - btSphereShape sphere0(col0->getCcdSweptSphereRadius()); //todo: allow non-zero sphere sizes, for better approximation - btConvexCast::CastResult result; - btVoronoiSimplexSolver voronoiSimplex; - //SubsimplexConvexCast ccd0(&sphere,min0,&voronoiSimplex); - ///Simplification, one object is simplified as a sphere - btGjkConvexCast ccd1(&sphere0,convex1,&voronoiSimplex); - //ContinuousConvexCollision ccd(min0,min1,&voronoiSimplex,0); - if (ccd1.calcTimeOfImpact(col0->getWorldTransform(),col0->getInterpolationWorldTransform(), - col1->getWorldTransform(),col1->getInterpolationWorldTransform(),result)) - { - - //store result.m_fraction in both bodies - - if (col0->getHitFraction() > result.m_fraction) - col0->setHitFraction( result.m_fraction); - - if (col1->getHitFraction() > result.m_fraction) - col1->setHitFraction( result.m_fraction); - - if (resultFraction > result.m_fraction) - resultFraction = result.m_fraction; - - } - } - - return resultFraction; - -} - diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btConvexConvexAlgorithm.h b/extern/bullet2/src/BulletCollision/CollisionDispatch/btConvexConvexAlgorithm.h deleted file mode 100644 index ca58bce25f1..00000000000 --- a/extern/bullet2/src/BulletCollision/CollisionDispatch/btConvexConvexAlgorithm.h +++ /dev/null @@ -1,77 +0,0 @@ -/* -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 CONVEX_CONVEX_ALGORITHM_H -#define CONVEX_CONVEX_ALGORITHM_H - -#include "BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h" -#include "BulletCollision/NarrowPhaseCollision/btGjkPairDetector.h" -#include "BulletCollision/NarrowPhaseCollision/btPersistentManifold.h" -#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" -#include "BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.h" -#include "btCollisionCreateFunc.h" -#include "btCollisionDispatcher.h" - -class btConvexPenetrationDepthSolver; - -///ConvexConvexAlgorithm collision algorithm implements time of impact, convex closest points and penetration depth calculations. -class btConvexConvexAlgorithm : public btCollisionAlgorithm -{ - btGjkPairDetector m_gjkPairDetector; -public: - - bool m_ownManifold; - btPersistentManifold* m_manifoldPtr; - bool m_lowLevelOfDetail; - - -public: - - btConvexConvexAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* body0,btCollisionObject* body1, btSimplexSolverInterface* simplexSolver, btConvexPenetrationDepthSolver* pdSolver); - - virtual ~btConvexConvexAlgorithm(); - - virtual void processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut); - - virtual btScalar calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut); - - void setLowLevelOfDetail(bool useLowLevel); - - - const btPersistentManifold* getManifold() - { - return m_manifoldPtr; - } - - struct CreateFunc :public btCollisionAlgorithmCreateFunc - { - btConvexPenetrationDepthSolver* m_pdSolver; - btSimplexSolverInterface* m_simplexSolver; - - CreateFunc(btSimplexSolverInterface* simplexSolver, btConvexPenetrationDepthSolver* pdSolver); - - virtual ~CreateFunc(); - - virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, btCollisionObject* body0,btCollisionObject* body1) - { - void* mem = ci.m_dispatcher1->allocateCollisionAlgorithm(sizeof(btConvexConvexAlgorithm)); - return new(mem) btConvexConvexAlgorithm(ci.m_manifold,ci,body0,body1,m_simplexSolver,m_pdSolver); - } - }; - - -}; - -#endif //CONVEX_CONVEX_ALGORITHM_H diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btDefaultCollisionConfiguration.cpp b/extern/bullet2/src/BulletCollision/CollisionDispatch/btDefaultCollisionConfiguration.cpp deleted file mode 100644 index 661270b9bcb..00000000000 --- a/extern/bullet2/src/BulletCollision/CollisionDispatch/btDefaultCollisionConfiguration.cpp +++ /dev/null @@ -1,237 +0,0 @@ - -/* -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 "btDefaultCollisionConfiguration.h" - -#include "BulletCollision/CollisionDispatch/btConvexConvexAlgorithm.h" -#include "BulletCollision/CollisionDispatch/btEmptyCollisionAlgorithm.h" -#include "BulletCollision/CollisionDispatch/btConvexConcaveCollisionAlgorithm.h" -#include "BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.h" -#include "BulletCollision/CollisionDispatch/btSphereSphereCollisionAlgorithm.h" -#include "BulletCollision/CollisionDispatch/btSphereBoxCollisionAlgorithm.h" -#include "BulletCollision/CollisionDispatch/btSphereTriangleCollisionAlgorithm.h" -#include "BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.h" -#include "BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.h" - - - -#include "LinearMath/btStackAlloc.h" -#include "LinearMath/btPoolAllocator.h" - - - -#define DEFAULT_MAX_OVERLAPPING_PAIRS 65535 -#define DEFAULT_STACK_ALLOCATOR_SIZE (5*1024*1024) - - -btDefaultCollisionConfiguration::btDefaultCollisionConfiguration(btStackAlloc* stackAlloc,btPoolAllocator* persistentManifoldPool,btPoolAllocator* collisionAlgorithmPool) -{ - - void* mem = btAlignedAlloc(sizeof(btVoronoiSimplexSolver),16); - m_simplexSolver = new (mem)btVoronoiSimplexSolver(); - mem = btAlignedAlloc(sizeof(btGjkEpaPenetrationDepthSolver),16); - m_pdSolver = new (mem)btGjkEpaPenetrationDepthSolver; - - //default CreationFunctions, filling the m_doubleDispatch table - mem = btAlignedAlloc(sizeof(btConvexConvexAlgorithm::CreateFunc),16); - m_convexConvexCreateFunc = new(mem) btConvexConvexAlgorithm::CreateFunc(m_simplexSolver,m_pdSolver); - mem = btAlignedAlloc(sizeof(btConvexConcaveCollisionAlgorithm::CreateFunc),16); - m_convexConcaveCreateFunc = new (mem)btConvexConcaveCollisionAlgorithm::CreateFunc; - mem = btAlignedAlloc(sizeof(btConvexConcaveCollisionAlgorithm::CreateFunc),16); - m_swappedConvexConcaveCreateFunc = new (mem)btConvexConcaveCollisionAlgorithm::SwappedCreateFunc; - mem = btAlignedAlloc(sizeof(btCompoundCollisionAlgorithm::CreateFunc),16); - m_compoundCreateFunc = new (mem)btCompoundCollisionAlgorithm::CreateFunc; - mem = btAlignedAlloc(sizeof(btCompoundCollisionAlgorithm::SwappedCreateFunc),16); - m_swappedCompoundCreateFunc = new (mem)btCompoundCollisionAlgorithm::SwappedCreateFunc; - mem = btAlignedAlloc(sizeof(btEmptyAlgorithm::CreateFunc),16); - m_emptyCreateFunc = new(mem) btEmptyAlgorithm::CreateFunc; - - mem = btAlignedAlloc(sizeof(btSphereSphereCollisionAlgorithm::CreateFunc),16); - m_sphereSphereCF = new(mem) btSphereSphereCollisionAlgorithm::CreateFunc; - mem = btAlignedAlloc(sizeof(btSphereBoxCollisionAlgorithm::CreateFunc),16); - m_sphereBoxCF = new(mem) btSphereBoxCollisionAlgorithm::CreateFunc; - mem = btAlignedAlloc(sizeof(btSphereBoxCollisionAlgorithm::CreateFunc),16); - m_boxSphereCF = new (mem)btSphereBoxCollisionAlgorithm::CreateFunc; - m_boxSphereCF->m_swapped = true; - mem = btAlignedAlloc(sizeof(btSphereTriangleCollisionAlgorithm::CreateFunc),16); - m_sphereTriangleCF = new (mem)btSphereTriangleCollisionAlgorithm::CreateFunc; - mem = btAlignedAlloc(sizeof(btSphereTriangleCollisionAlgorithm::CreateFunc),16); - m_triangleSphereCF = new (mem)btSphereTriangleCollisionAlgorithm::CreateFunc; - m_triangleSphereCF->m_swapped = true; - - - ///calculate maximum element size, big enough to fit any collision algorithm in the memory pool - int maxSize = sizeof(btConvexConvexAlgorithm); - int maxSize2 = sizeof(btConvexConcaveCollisionAlgorithm); - int maxSize3 = sizeof(btCompoundCollisionAlgorithm); - int maxSize4 = sizeof(btEmptyAlgorithm); - - int collisionAlgorithmMaxElementSize = btMax(maxSize,maxSize2); - collisionAlgorithmMaxElementSize = btMax(collisionAlgorithmMaxElementSize,maxSize3); - collisionAlgorithmMaxElementSize = btMax(collisionAlgorithmMaxElementSize,maxSize4); - - if (stackAlloc) - { - m_ownsStackAllocator = false; - this->m_stackAlloc = stackAlloc; - } else - { - m_ownsStackAllocator = true; - void* mem = btAlignedAlloc(sizeof(btStackAlloc),16); - m_stackAlloc = new(mem)btStackAlloc(DEFAULT_STACK_ALLOCATOR_SIZE); - } - - if (persistentManifoldPool) - { - m_ownsPersistentManifoldPool = false; - m_persistentManifoldPool = persistentManifoldPool; - } else - { - m_ownsPersistentManifoldPool = true; - void* mem = btAlignedAlloc(sizeof(btPoolAllocator),16); - m_persistentManifoldPool = new (mem) btPoolAllocator(sizeof(btPersistentManifold),DEFAULT_MAX_OVERLAPPING_PAIRS); - } - - if (collisionAlgorithmPool) - { - m_ownsCollisionAlgorithmPool = false; - m_collisionAlgorithmPool = collisionAlgorithmPool; - } else - { - m_ownsCollisionAlgorithmPool = true; - void* mem = btAlignedAlloc(sizeof(btPoolAllocator),16); - m_collisionAlgorithmPool = new(mem) btPoolAllocator(collisionAlgorithmMaxElementSize,DEFAULT_MAX_OVERLAPPING_PAIRS); - } - - -} - -btDefaultCollisionConfiguration::~btDefaultCollisionConfiguration() -{ - if (m_ownsStackAllocator) - { - m_stackAlloc->destroy(); - m_stackAlloc->~btStackAlloc(); - btAlignedFree(m_stackAlloc); - } - if (m_ownsCollisionAlgorithmPool) - { - m_collisionAlgorithmPool->~btPoolAllocator(); - btAlignedFree(m_collisionAlgorithmPool); - } - if (m_ownsPersistentManifoldPool) - { - m_persistentManifoldPool->~btPoolAllocator(); - btAlignedFree(m_persistentManifoldPool); - } - - m_convexConvexCreateFunc->~btCollisionAlgorithmCreateFunc(); - btAlignedFree( m_convexConvexCreateFunc); - - m_convexConcaveCreateFunc->~btCollisionAlgorithmCreateFunc(); - btAlignedFree( m_convexConcaveCreateFunc); - m_swappedConvexConcaveCreateFunc->~btCollisionAlgorithmCreateFunc(); - btAlignedFree( m_swappedConvexConcaveCreateFunc); - - m_compoundCreateFunc->~btCollisionAlgorithmCreateFunc(); - btAlignedFree( m_compoundCreateFunc); - - m_swappedCompoundCreateFunc->~btCollisionAlgorithmCreateFunc(); - btAlignedFree( m_swappedCompoundCreateFunc); - - m_emptyCreateFunc->~btCollisionAlgorithmCreateFunc(); - btAlignedFree( m_emptyCreateFunc); - - m_sphereSphereCF->~btCollisionAlgorithmCreateFunc(); - btAlignedFree( m_sphereSphereCF); - - m_sphereBoxCF->~btCollisionAlgorithmCreateFunc(); - btAlignedFree( m_sphereBoxCF); - m_boxSphereCF->~btCollisionAlgorithmCreateFunc(); - btAlignedFree( m_boxSphereCF); - m_sphereTriangleCF->~btCollisionAlgorithmCreateFunc(); - btAlignedFree( m_sphereTriangleCF); - m_triangleSphereCF->~btCollisionAlgorithmCreateFunc(); - btAlignedFree( m_triangleSphereCF); - - m_simplexSolver->~btVoronoiSimplexSolver(); - btAlignedFree(m_simplexSolver); - m_pdSolver->~btGjkEpaPenetrationDepthSolver(); - btAlignedFree(m_pdSolver); - - -} - - -btCollisionAlgorithmCreateFunc* btDefaultCollisionConfiguration::getCollisionAlgorithmCreateFunc(int proxyType0,int proxyType1) -{ - - - if ((proxyType0 == SPHERE_SHAPE_PROXYTYPE) && (proxyType1==SPHERE_SHAPE_PROXYTYPE)) - { - return m_sphereSphereCF; - } - - if ((proxyType0 == SPHERE_SHAPE_PROXYTYPE) && (proxyType1==BOX_SHAPE_PROXYTYPE)) - { - return m_sphereBoxCF; - } - - if ((proxyType0 == BOX_SHAPE_PROXYTYPE ) && (proxyType1==SPHERE_SHAPE_PROXYTYPE)) - { - return m_boxSphereCF; - } - - if ((proxyType0 == SPHERE_SHAPE_PROXYTYPE ) && (proxyType1==TRIANGLE_SHAPE_PROXYTYPE)) - { - return m_sphereTriangleCF; - } - - if ((proxyType0 == TRIANGLE_SHAPE_PROXYTYPE ) && (proxyType1==SPHERE_SHAPE_PROXYTYPE)) - { - return m_triangleSphereCF; - } - - - if (btBroadphaseProxy::isConvex(proxyType0) && btBroadphaseProxy::isConvex(proxyType1)) - { - return m_convexConvexCreateFunc; - } - - if (btBroadphaseProxy::isConvex(proxyType0) && btBroadphaseProxy::isConcave(proxyType1)) - { - return m_convexConcaveCreateFunc; - } - - if (btBroadphaseProxy::isConvex(proxyType1) && btBroadphaseProxy::isConcave(proxyType0)) - { - return m_swappedConvexConcaveCreateFunc; - } - - if (btBroadphaseProxy::isCompound(proxyType0)) - { - return m_compoundCreateFunc; - } else - { - if (btBroadphaseProxy::isCompound(proxyType1)) - { - return m_swappedCompoundCreateFunc; - } - } - - //failed to find an algorithm - return m_emptyCreateFunc; -} diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btDefaultCollisionConfiguration.h b/extern/bullet2/src/BulletCollision/CollisionDispatch/btDefaultCollisionConfiguration.h deleted file mode 100644 index 2e99f1db18f..00000000000 --- a/extern/bullet2/src/BulletCollision/CollisionDispatch/btDefaultCollisionConfiguration.h +++ /dev/null @@ -1,87 +0,0 @@ -/* -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 BT_DEFAULT_COLLISION_CONFIGURATION -#define BT_DEFAULT_COLLISION_CONFIGURATION - -#include "btCollisionConfiguration.h" -class btVoronoiSimplexSolver; -class btGjkEpaPenetrationDepthSolver; - - -///btCollisionConfiguration allows to configure Bullet collision detection -///stack allocator, pool memory allocators -///todo: describe the meaning -class btDefaultCollisionConfiguration : public btCollisionConfiguration -{ - - int m_persistentManifoldPoolSize; - - btStackAlloc* m_stackAlloc; - bool m_ownsStackAllocator; - - btPoolAllocator* m_persistentManifoldPool; - bool m_ownsPersistentManifoldPool; - - btPoolAllocator* m_collisionAlgorithmPool; - bool m_ownsCollisionAlgorithmPool; - - //default simplex/penetration depth solvers - btVoronoiSimplexSolver* m_simplexSolver; - btGjkEpaPenetrationDepthSolver* m_pdSolver; - - //default CreationFunctions, filling the m_doubleDispatch table - btCollisionAlgorithmCreateFunc* m_convexConvexCreateFunc; - btCollisionAlgorithmCreateFunc* m_convexConcaveCreateFunc; - btCollisionAlgorithmCreateFunc* m_swappedConvexConcaveCreateFunc; - btCollisionAlgorithmCreateFunc* m_compoundCreateFunc; - btCollisionAlgorithmCreateFunc* m_swappedCompoundCreateFunc; - btCollisionAlgorithmCreateFunc* m_emptyCreateFunc; - btCollisionAlgorithmCreateFunc* m_sphereSphereCF; - btCollisionAlgorithmCreateFunc* m_sphereBoxCF; - btCollisionAlgorithmCreateFunc* m_boxSphereCF; - btCollisionAlgorithmCreateFunc* m_sphereTriangleCF; - btCollisionAlgorithmCreateFunc* m_triangleSphereCF; - -public: - - btDefaultCollisionConfiguration(btStackAlloc* stackAlloc=0,btPoolAllocator* persistentManifoldPool=0,btPoolAllocator* collisionAlgorithmPool=0); - - virtual ~btDefaultCollisionConfiguration(); - - ///memory pools - virtual btPoolAllocator* getPersistentManifoldPool() - { - return m_persistentManifoldPool; - } - - virtual btPoolAllocator* getCollisionAlgorithmPool() - { - return m_collisionAlgorithmPool; - } - - virtual btStackAlloc* getStackAllocator() - { - return m_stackAlloc; - } - - - btCollisionAlgorithmCreateFunc* getCollisionAlgorithmCreateFunc(int proxyType0,int proxyType1); - - -}; - -#endif //BT_DEFAULT_COLLISION_CONFIGURATION - diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btEmptyCollisionAlgorithm.cpp b/extern/bullet2/src/BulletCollision/CollisionDispatch/btEmptyCollisionAlgorithm.cpp deleted file mode 100644 index 936054387c4..00000000000 --- a/extern/bullet2/src/BulletCollision/CollisionDispatch/btEmptyCollisionAlgorithm.cpp +++ /dev/null @@ -1,34 +0,0 @@ -/* -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 "btEmptyCollisionAlgorithm.h" - - - -btEmptyAlgorithm::btEmptyAlgorithm(const btCollisionAlgorithmConstructionInfo& ci) - : btCollisionAlgorithm(ci) -{ -} - -void btEmptyAlgorithm::processCollision (btCollisionObject* ,btCollisionObject* ,const btDispatcherInfo& ,btManifoldResult* ) -{ -} - -btScalar btEmptyAlgorithm::calculateTimeOfImpact(btCollisionObject* ,btCollisionObject* ,const btDispatcherInfo& ,btManifoldResult* ) -{ - return btScalar(1.); -} - - diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btEmptyCollisionAlgorithm.h b/extern/bullet2/src/BulletCollision/CollisionDispatch/btEmptyCollisionAlgorithm.h deleted file mode 100644 index 89e7080780c..00000000000 --- a/extern/bullet2/src/BulletCollision/CollisionDispatch/btEmptyCollisionAlgorithm.h +++ /dev/null @@ -1,50 +0,0 @@ -/* -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 EMPTY_ALGORITH -#define EMPTY_ALGORITH -#include "BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h" -#include "btCollisionCreateFunc.h" -#include "btCollisionDispatcher.h" - -#define ATTRIBUTE_ALIGNED(a) - -///EmptyAlgorithm is a stub for unsupported collision pairs. -///The dispatcher can dispatch a persistent btEmptyAlgorithm to avoid a search every frame. -class btEmptyAlgorithm : public btCollisionAlgorithm -{ - -public: - - btEmptyAlgorithm(const btCollisionAlgorithmConstructionInfo& ci); - - virtual void processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut); - - virtual btScalar calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut); - - struct CreateFunc :public btCollisionAlgorithmCreateFunc - { - virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, btCollisionObject* body0,btCollisionObject* body1) - { - (void)body0; - (void)body1; - void* mem = ci.m_dispatcher1->allocateCollisionAlgorithm(sizeof(btEmptyAlgorithm)); - return new(mem) btEmptyAlgorithm(ci); - } - }; - -} ATTRIBUTE_ALIGNED(16); - -#endif //EMPTY_ALGORITH diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btManifoldResult.cpp b/extern/bullet2/src/BulletCollision/CollisionDispatch/btManifoldResult.cpp deleted file mode 100644 index 61c4c231da4..00000000000 --- a/extern/bullet2/src/BulletCollision/CollisionDispatch/btManifoldResult.cpp +++ /dev/null @@ -1,114 +0,0 @@ -/* -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 "btManifoldResult.h" -#include "BulletCollision/NarrowPhaseCollision/btPersistentManifold.h" -#include "BulletCollision/CollisionDispatch/btCollisionObject.h" - - -///This is to allow MaterialCombiner/Custom Friction/Restitution values -ContactAddedCallback gContactAddedCallback=0; - -///User can override this material combiner by implementing gContactAddedCallback and setting body0->m_collisionFlags |= btCollisionObject::customMaterialCallback; -inline btScalar calculateCombinedFriction(const btCollisionObject* body0,const btCollisionObject* body1) -{ - btScalar friction = body0->getFriction() * body1->getFriction(); - - const btScalar MAX_FRICTION = btScalar(10.); - if (friction < -MAX_FRICTION) - friction = -MAX_FRICTION; - if (friction > MAX_FRICTION) - friction = MAX_FRICTION; - return friction; - -} - -inline btScalar calculateCombinedRestitution(const btCollisionObject* body0,const btCollisionObject* body1) -{ - return body0->getRestitution() * body1->getRestitution(); -} - - - -btManifoldResult::btManifoldResult(btCollisionObject* body0,btCollisionObject* body1) - :m_manifoldPtr(0), - m_body0(body0), - m_body1(body1) -{ - m_rootTransA = body0->getWorldTransform(); - m_rootTransB = body1->getWorldTransform(); -} - - -void btManifoldResult::addContactPoint(const btVector3& normalOnBInWorld,const btVector3& pointInWorld,btScalar depth) -{ - assert(m_manifoldPtr); - //order in manifold needs to match - - if (depth > m_manifoldPtr->getContactBreakingThreshold()) - return; - - bool isSwapped = m_manifoldPtr->getBody0() != m_body0; - - btVector3 pointA = pointInWorld + normalOnBInWorld * depth; - - btVector3 localA; - btVector3 localB; - - if (isSwapped) - { - localA = m_rootTransB.invXform(pointA ); - localB = m_rootTransA.invXform(pointInWorld); - } else - { - localA = m_rootTransA.invXform(pointA ); - localB = m_rootTransB.invXform(pointInWorld); - } - - btManifoldPoint newPt(localA,localB,normalOnBInWorld,depth); - newPt.m_positionWorldOnA = pointA; - newPt.m_positionWorldOnB = pointInWorld; - - int insertIndex = m_manifoldPtr->getCacheEntry(newPt); - - newPt.m_combinedFriction = calculateCombinedFriction(m_body0,m_body1); - newPt.m_combinedRestitution = calculateCombinedRestitution(m_body0,m_body1); - - - ///todo, check this for any side effects - if (insertIndex >= 0) - { - //const btManifoldPoint& oldPoint = m_manifoldPtr->getContactPoint(insertIndex); - m_manifoldPtr->replaceContactPoint(newPt,insertIndex); - } else - { - m_manifoldPtr->AddManifoldPoint(newPt); - } - - //User can override friction and/or restitution - if (gContactAddedCallback && - //and if either of the two bodies requires custom material - ((m_body0->getCollisionFlags() & btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK) || - (m_body1->getCollisionFlags() & btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK))) - { - //experimental feature info, for per-triangle material etc. - btCollisionObject* obj0 = isSwapped? m_body1 : m_body0; - btCollisionObject* obj1 = isSwapped? m_body0 : m_body1; - (*gContactAddedCallback)(newPt,obj0,m_partId0,m_index0,obj1,m_partId1,m_index1); - } - -} - diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btManifoldResult.h b/extern/bullet2/src/BulletCollision/CollisionDispatch/btManifoldResult.h deleted file mode 100644 index 5aac9a46f6a..00000000000 --- a/extern/bullet2/src/BulletCollision/CollisionDispatch/btManifoldResult.h +++ /dev/null @@ -1,102 +0,0 @@ -/* -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 MANIFOLD_RESULT_H -#define MANIFOLD_RESULT_H - -class btCollisionObject; -#include "BulletCollision/NarrowPhaseCollision/btPersistentManifold.h" -class btManifoldPoint; - -#include "BulletCollision/NarrowPhaseCollision/btDiscreteCollisionDetectorInterface.h" - -#include "LinearMath/btTransform.h" - -typedef bool (*ContactAddedCallback)(btManifoldPoint& cp, const btCollisionObject* colObj0,int partId0,int index0,const btCollisionObject* colObj1,int partId1,int index1); -extern ContactAddedCallback gContactAddedCallback; - - - -///btManifoldResult is a helper class to manage contact results. -class btManifoldResult : public btDiscreteCollisionDetectorInterface::Result -{ - btPersistentManifold* m_manifoldPtr; - - //we need this for compounds - btTransform m_rootTransA; - btTransform m_rootTransB; - - btCollisionObject* m_body0; - btCollisionObject* m_body1; - int m_partId0; - int m_partId1; - int m_index0; - int m_index1; -public: - - btManifoldResult() - { - } - - btManifoldResult(btCollisionObject* body0,btCollisionObject* body1); - - virtual ~btManifoldResult() {}; - - void setPersistentManifold(btPersistentManifold* manifoldPtr) - { - m_manifoldPtr = manifoldPtr; - } - - const btPersistentManifold* getPersistentManifold() const - { - return m_manifoldPtr; - } - btPersistentManifold* getPersistentManifold() - { - return m_manifoldPtr; - } - - virtual void setShapeIdentifiers(int partId0,int index0, int partId1,int index1) - { - m_partId0=partId0; - m_partId1=partId1; - m_index0=index0; - m_index1=index1; - } - - virtual void addContactPoint(const btVector3& normalOnBInWorld,const btVector3& pointInWorld,btScalar depth); - - SIMD_FORCE_INLINE void refreshContactPoints() - { - btAssert(m_manifoldPtr); - if (!m_manifoldPtr->getNumContacts()) - return; - - bool isSwapped = m_manifoldPtr->getBody0() != m_body0; - - if (isSwapped) - { - m_manifoldPtr->refreshContactPoints(m_rootTransB,m_rootTransA); - } else - { - m_manifoldPtr->refreshContactPoints(m_rootTransA,m_rootTransB); - } - } - - -}; - -#endif //MANIFOLD_RESULT_H diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btSimulationIslandManager.cpp b/extern/bullet2/src/BulletCollision/CollisionDispatch/btSimulationIslandManager.cpp deleted file mode 100644 index 6c42d1706ff..00000000000 --- a/extern/bullet2/src/BulletCollision/CollisionDispatch/btSimulationIslandManager.cpp +++ /dev/null @@ -1,359 +0,0 @@ - - -#include "LinearMath/btScalar.h" -#include "btSimulationIslandManager.h" -#include "BulletCollision/BroadphaseCollision/btDispatcher.h" -#include "BulletCollision/NarrowPhaseCollision/btPersistentManifold.h" -#include "BulletCollision/CollisionDispatch/btCollisionObject.h" -#include "BulletCollision/CollisionDispatch/btCollisionWorld.h" - -#include -#include "LinearMath/btQuickprof.h" - -btSimulationIslandManager::btSimulationIslandManager() -{ -} - -btSimulationIslandManager::~btSimulationIslandManager() -{ -} - - -void btSimulationIslandManager::initUnionFind(int n) -{ - m_unionFind.reset(n); -} - - -void btSimulationIslandManager::findUnions(btDispatcher* dispatcher,btCollisionWorld* colWorld) -{ - - { - btBroadphasePair* pairPtr = colWorld->getPairCache()->getOverlappingPairArrayPtr(); - - for (int i=0;igetPairCache()->getNumOverlappingPairs();i++) - { - const btBroadphasePair& collisionPair = pairPtr[i]; - btCollisionObject* colObj0 = (btCollisionObject*)collisionPair.m_pProxy0->m_clientObject; - btCollisionObject* colObj1 = (btCollisionObject*)collisionPair.m_pProxy1->m_clientObject; - - if (((colObj0) && ((colObj0)->mergesSimulationIslands())) && - ((colObj1) && ((colObj1)->mergesSimulationIslands()))) - { - - m_unionFind.unite((colObj0)->getIslandTag(), - (colObj1)->getIslandTag()); - } - } - } -} - - -void btSimulationIslandManager::updateActivationState(btCollisionWorld* colWorld,btDispatcher* dispatcher) -{ - - initUnionFind( int (colWorld->getCollisionObjectArray().size())); - - // put the index into m_controllers into m_tag - { - - int index = 0; - int i; - for (i=0;igetCollisionObjectArray().size(); i++) - { - btCollisionObject* collisionObject= colWorld->getCollisionObjectArray()[i]; - collisionObject->setIslandTag(index); - collisionObject->setCompanionId(-1); - collisionObject->setHitFraction(btScalar(1.)); - index++; - - } - } - // do the union find - - findUnions(dispatcher,colWorld); - - - -} - - - - -void btSimulationIslandManager::storeIslandActivationState(btCollisionWorld* colWorld) -{ - // put the islandId ('find' value) into m_tag - { - - - int index = 0; - int i; - for (i=0;igetCollisionObjectArray().size();i++) - { - btCollisionObject* collisionObject= colWorld->getCollisionObjectArray()[i]; - if (collisionObject->mergesSimulationIslands()) - { - collisionObject->setIslandTag( m_unionFind.find(index) ); - collisionObject->setCompanionId(-1); - } else - { - collisionObject->setIslandTag(-1); - collisionObject->setCompanionId(-2); - } - index++; - } - } -} - -inline int getIslandId(const btPersistentManifold* lhs) -{ - int islandId; - const btCollisionObject* rcolObj0 = static_cast(lhs->getBody0()); - const btCollisionObject* rcolObj1 = static_cast(lhs->getBody1()); - islandId= rcolObj0->getIslandTag()>=0?rcolObj0->getIslandTag():rcolObj1->getIslandTag(); - return islandId; - -} - - - -/// function object that routes calls to operator< -class btPersistentManifoldSortPredicate -{ - public: - - SIMD_FORCE_INLINE bool operator() ( const btPersistentManifold* lhs, const btPersistentManifold* rhs ) - { - return getIslandId(lhs) < getIslandId(rhs); - } -}; - - - - - -// -// todo: this is random access, it can be walked 'cache friendly'! -// -void btSimulationIslandManager::buildAndProcessIslands(btDispatcher* dispatcher,btCollisionObjectArray& collisionObjects, IslandCallback* callback) -{ - - BEGIN_PROFILE("islandUnionFindAndHeapSort"); - - //we are going to sort the unionfind array, and store the element id in the size - //afterwards, we clean unionfind, to make sure no-one uses it anymore - - getUnionFind().sortIslands(); - int numElem = getUnionFind().getNumElements(); - - int endIslandIndex=1; - int startIslandIndex; - - - //update the sleeping state for bodies, if all are sleeping - for ( startIslandIndex=0;startIslandIndexgetIslandTag() != islandId) && (colObj0->getIslandTag() != -1)) - { - printf("error in island management\n"); - } - - assert((colObj0->getIslandTag() == islandId) || (colObj0->getIslandTag() == -1)); - if (colObj0->getIslandTag() == islandId) - { - if (colObj0->getActivationState()== ACTIVE_TAG) - { - allSleeping = false; - } - if (colObj0->getActivationState()== DISABLE_DEACTIVATION) - { - allSleeping = false; - } - } - } - - - if (allSleeping) - { - int idx; - for (idx=startIslandIndex;idxgetIslandTag() != islandId) && (colObj0->getIslandTag() != -1)) - { - printf("error in island management\n"); - } - - assert((colObj0->getIslandTag() == islandId) || (colObj0->getIslandTag() == -1)); - - if (colObj0->getIslandTag() == islandId) - { - colObj0->setActivationState( ISLAND_SLEEPING ); - } - } - } else - { - - int idx; - for (idx=startIslandIndex;idxgetIslandTag() != islandId) && (colObj0->getIslandTag() != -1)) - { - printf("error in island management\n"); - } - - assert((colObj0->getIslandTag() == islandId) || (colObj0->getIslandTag() == -1)); - - if (colObj0->getIslandTag() == islandId) - { - if ( colObj0->getActivationState() == ISLAND_SLEEPING) - { - colObj0->setActivationState( WANTS_DEACTIVATION); - } - } - } - } - } - - - int i; - int maxNumManifolds = dispatcher->getNumManifolds(); - -#define SPLIT_ISLANDS 1 -#ifdef SPLIT_ISLANDS - - -#endif //SPLIT_ISLANDS - - - for (i=0;igetManifoldByIndexInternal(i); - - btCollisionObject* colObj0 = static_cast(manifold->getBody0()); - btCollisionObject* colObj1 = static_cast(manifold->getBody1()); - - //todo: check sleeping conditions! - if (((colObj0) && colObj0->getActivationState() != ISLAND_SLEEPING) || - ((colObj1) && colObj1->getActivationState() != ISLAND_SLEEPING)) - { - - //kinematic objects don't merge islands, but wake up all connected objects - if (colObj0->isKinematicObject() && colObj0->getActivationState() != ISLAND_SLEEPING) - { - colObj1->activate(); - } - if (colObj1->isKinematicObject() && colObj1->getActivationState() != ISLAND_SLEEPING) - { - colObj0->activate(); - } -#ifdef SPLIT_ISLANDS - // //filtering for response - if (dispatcher->needsResponse(colObj0,colObj1)) - m_islandmanifold.push_back(manifold); -#endif //SPLIT_ISLANDS - } - } - -#ifndef SPLIT_ISLANDS - btPersistentManifold** manifold = dispatcher->getInternalManifoldPointer(); - - callback->ProcessIsland(&collisionObjects[0],collisionObjects.size(),manifold,maxNumManifolds, -1); -#else - // Sort manifolds, based on islands - // Sort the vector using predicate and std::sort - //std::sort(islandmanifold.begin(), islandmanifold.end(), btPersistentManifoldSortPredicate); - - int numManifolds = int (m_islandmanifold.size()); - - //we should do radix sort, it it much faster (O(n) instead of O (n log2(n)) - m_islandmanifold.heapSort(btPersistentManifoldSortPredicate()); - - //now process all active islands (sets of manifolds for now) - - int startManifoldIndex = 0; - int endManifoldIndex = 1; - - //int islandId; - - END_PROFILE("islandUnionFindAndHeapSort"); - - - -// printf("Start Islands\n"); - - //traverse the simulation islands, and call the solver, unless all objects are sleeping/deactivated - for ( startIslandIndex=0;startIslandIndexisActive()) - islandSleeping = true; - } - - - //find the accompanying contact manifold for this islandId - int numIslandManifolds = 0; - btPersistentManifold** startManifold = 0; - - if (startManifoldIndexProcessIsland(&m_islandBodies[0],m_islandBodies.size(),startManifold,numIslandManifolds, islandId); -// printf("Island callback of size:%d bodies, %d manifolds\n",islandBodies.size(),numIslandManifolds); - } - - if (numIslandManifolds) - { - startManifoldIndex = endManifoldIndex; - } - - m_islandBodies.resize(0); - } -#endif //SPLIT_ISLANDS - - m_islandmanifold.resize(0); -} diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btSimulationIslandManager.h b/extern/bullet2/src/BulletCollision/CollisionDispatch/btSimulationIslandManager.h deleted file mode 100644 index 01a059b5fbe..00000000000 --- a/extern/bullet2/src/BulletCollision/CollisionDispatch/btSimulationIslandManager.h +++ /dev/null @@ -1,69 +0,0 @@ -/* -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 SIMULATION_ISLAND_MANAGER_H -#define SIMULATION_ISLAND_MANAGER_H - -#include "BulletCollision/CollisionDispatch/btUnionFind.h" -#include "btCollisionCreateFunc.h" -#include "LinearMath/btAlignedObjectArray.h" - - -class btCollisionObject; -class btCollisionWorld; -class btDispatcher; -class btPersistentManifold; - - -///SimulationIslandManager creates and handles simulation islands, using btUnionFind -class btSimulationIslandManager -{ - btUnionFind m_unionFind; - - btAlignedObjectArray m_islandmanifold; - btAlignedObjectArray m_islandBodies; - - -public: - btSimulationIslandManager(); - virtual ~btSimulationIslandManager(); - - - void initUnionFind(int n); - - - btUnionFind& getUnionFind() { return m_unionFind;} - - virtual void updateActivationState(btCollisionWorld* colWorld,btDispatcher* dispatcher); - virtual void storeIslandActivationState(btCollisionWorld* world); - - - void findUnions(btDispatcher* dispatcher,btCollisionWorld* colWorld); - - - - struct IslandCallback - { - virtual ~IslandCallback() {}; - - virtual void ProcessIsland(btCollisionObject** bodies,int numBodies,class btPersistentManifold** manifolds,int numManifolds, int islandId) = 0; - }; - - void buildAndProcessIslands(btDispatcher* dispatcher,btCollisionObjectArray& collisionObjects, IslandCallback* callback); - -}; - -#endif //SIMULATION_ISLAND_MANAGER_H - diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereBoxCollisionAlgorithm.cpp b/extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereBoxCollisionAlgorithm.cpp deleted file mode 100644 index 1e4bbce451d..00000000000 --- a/extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereBoxCollisionAlgorithm.cpp +++ /dev/null @@ -1,260 +0,0 @@ -/* -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 "btSphereBoxCollisionAlgorithm.h" -#include "BulletCollision/CollisionDispatch/btCollisionDispatcher.h" -#include "BulletCollision/CollisionShapes/btSphereShape.h" -#include "BulletCollision/CollisionShapes/btBoxShape.h" -#include "BulletCollision/CollisionDispatch/btCollisionObject.h" -//#include - -btSphereBoxCollisionAlgorithm::btSphereBoxCollisionAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* col0,btCollisionObject* col1, bool isSwapped) -: btCollisionAlgorithm(ci), -m_ownManifold(false), -m_manifoldPtr(mf), -m_isSwapped(isSwapped) -{ - btCollisionObject* sphereObj = m_isSwapped? col1 : col0; - btCollisionObject* boxObj = m_isSwapped? col0 : col1; - - if (!m_manifoldPtr && m_dispatcher->needsCollision(sphereObj,boxObj)) - { - m_manifoldPtr = m_dispatcher->getNewManifold(sphereObj,boxObj); - m_ownManifold = true; - } -} - - -btSphereBoxCollisionAlgorithm::~btSphereBoxCollisionAlgorithm() -{ - if (m_ownManifold) - { - if (m_manifoldPtr) - m_dispatcher->releaseManifold(m_manifoldPtr); - } -} - - - -void btSphereBoxCollisionAlgorithm::processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut) -{ - (void)dispatchInfo; - (void)resultOut; - if (!m_manifoldPtr) - return; - - btCollisionObject* sphereObj = m_isSwapped? body1 : body0; - btCollisionObject* boxObj = m_isSwapped? body0 : body1; - - - btSphereShape* sphere0 = (btSphereShape*)sphereObj->getCollisionShape(); - - btVector3 normalOnSurfaceB; - btVector3 pOnBox,pOnSphere; - btVector3 sphereCenter = sphereObj->getWorldTransform().getOrigin(); - btScalar radius = sphere0->getRadius(); - - btScalar dist = getSphereDistance(boxObj,pOnBox,pOnSphere,sphereCenter,radius); - - resultOut->setPersistentManifold(m_manifoldPtr); - - if (dist < SIMD_EPSILON) - { - btVector3 normalOnSurfaceB = (pOnBox- pOnSphere).normalize(); - - /// report a contact. internally this will be kept persistent, and contact reduction is done - - resultOut->addContactPoint(normalOnSurfaceB,pOnBox,dist); - - } - - if (m_ownManifold) - { - if (m_manifoldPtr->getNumContacts()) - { - resultOut->refreshContactPoints(); - } - } - -} - -btScalar btSphereBoxCollisionAlgorithm::calculateTimeOfImpact(btCollisionObject* col0,btCollisionObject* col1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut) -{ - (void)resultOut; - (void)dispatchInfo; - (void)col0; - (void)col1; - - //not yet - return btScalar(1.); -} - - -btScalar btSphereBoxCollisionAlgorithm::getSphereDistance(btCollisionObject* boxObj, btVector3& pointOnBox, btVector3& v3PointOnSphere, const btVector3& sphereCenter, btScalar fRadius ) -{ - - btScalar margins; - btVector3 bounds[2]; - btBoxShape* boxShape= (btBoxShape*)boxObj->getCollisionShape(); - - bounds[0] = -boxShape->getHalfExtentsWithoutMargin(); - bounds[1] = boxShape->getHalfExtentsWithoutMargin(); - - margins = boxShape->getMargin();//also add sphereShape margin? - - const btTransform& m44T = boxObj->getWorldTransform(); - - btVector3 boundsVec[2]; - btScalar fPenetration; - - boundsVec[0] = bounds[0]; - boundsVec[1] = bounds[1]; - - btVector3 marginsVec( margins, margins, margins ); - - // add margins - bounds[0] += marginsVec; - bounds[1] -= marginsVec; - - ///////////////////////////////////////////////// - - btVector3 tmp, prel, n[6], normal, v3P; - btScalar fSep = btScalar(10000000.0), fSepThis; - - n[0].setValue( btScalar(-1.0), btScalar(0.0), btScalar(0.0) ); - n[1].setValue( btScalar(0.0), btScalar(-1.0), btScalar(0.0) ); - n[2].setValue( btScalar(0.0), btScalar(0.0), btScalar(-1.0) ); - n[3].setValue( btScalar(1.0), btScalar(0.0), btScalar(0.0) ); - n[4].setValue( btScalar(0.0), btScalar(1.0), btScalar(0.0) ); - n[5].setValue( btScalar(0.0), btScalar(0.0), btScalar(1.0) ); - - // convert point in local space - prel = m44T.invXform( sphereCenter); - - bool bFound = false; - - v3P = prel; - - for (int i=0;i<6;i++) - { - int j = i<3? 0:1; - if ( (fSepThis = ((v3P-bounds[j]) .dot(n[i]))) > btScalar(0.0) ) - { - v3P = v3P - n[i]*fSepThis; - bFound = true; - } - } - - // - - if ( bFound ) - { - bounds[0] = boundsVec[0]; - bounds[1] = boundsVec[1]; - - normal = (prel - v3P).normalize(); - pointOnBox = v3P + normal*margins; - v3PointOnSphere = prel - normal*fRadius; - - if ( ((v3PointOnSphere - pointOnBox) .dot (normal)) > btScalar(0.0) ) - { - return btScalar(1.0); - } - - // transform back in world space - tmp = m44T( pointOnBox); - pointOnBox = tmp; - tmp = m44T( v3PointOnSphere); - v3PointOnSphere = tmp; - btScalar fSeps2 = (pointOnBox-v3PointOnSphere).length2(); - - //if this fails, fallback into deeper penetration case, below - if (fSeps2 > SIMD_EPSILON) - { - fSep = - btSqrt(fSeps2); - normal = (pointOnBox-v3PointOnSphere); - normal *= btScalar(1.)/fSep; - } - - return fSep; - } - - ////////////////////////////////////////////////// - // Deep penetration case - - fPenetration = getSpherePenetration( boxObj,pointOnBox, v3PointOnSphere, sphereCenter, fRadius,bounds[0],bounds[1] ); - - bounds[0] = boundsVec[0]; - bounds[1] = boundsVec[1]; - - if ( fPenetration <= btScalar(0.0) ) - return (fPenetration-margins); - else - return btScalar(1.0); -} - -btScalar btSphereBoxCollisionAlgorithm::getSpherePenetration( btCollisionObject* boxObj,btVector3& pointOnBox, btVector3& v3PointOnSphere, const btVector3& sphereCenter, btScalar fRadius, const btVector3& aabbMin, const btVector3& aabbMax) -{ - - btVector3 bounds[2]; - - bounds[0] = aabbMin; - bounds[1] = aabbMax; - - btVector3 p0, tmp, prel, n[6], normal; - btScalar fSep = btScalar(-10000000.0), fSepThis; - - // set p0 and normal to a default value to shup up GCC - p0.setValue(btScalar(0.), btScalar(0.), btScalar(0.)); - normal.setValue(btScalar(0.), btScalar(0.), btScalar(0.)); - - n[0].setValue( btScalar(-1.0), btScalar(0.0), btScalar(0.0) ); - n[1].setValue( btScalar(0.0), btScalar(-1.0), btScalar(0.0) ); - n[2].setValue( btScalar(0.0), btScalar(0.0), btScalar(-1.0) ); - n[3].setValue( btScalar(1.0), btScalar(0.0), btScalar(0.0) ); - n[4].setValue( btScalar(0.0), btScalar(1.0), btScalar(0.0) ); - n[5].setValue( btScalar(0.0), btScalar(0.0), btScalar(1.0) ); - - const btTransform& m44T = boxObj->getWorldTransform(); - - // convert point in local space - prel = m44T.invXform( sphereCenter); - - /////////// - - for (int i=0;i<6;i++) - { - int j = i<3 ? 0:1; - if ( (fSepThis = ((prel-bounds[j]) .dot( n[i]))-fRadius) > btScalar(0.0) ) return btScalar(1.0); - if ( fSepThis > fSep ) - { - p0 = bounds[j]; normal = (btVector3&)n[i]; - fSep = fSepThis; - } - } - - pointOnBox = prel - normal*(normal.dot((prel-p0))); - v3PointOnSphere = pointOnBox + normal*fSep; - - // transform back in world space - tmp = m44T( pointOnBox); - pointOnBox = tmp; - tmp = m44T( v3PointOnSphere); v3PointOnSphere = tmp; - normal = (pointOnBox-v3PointOnSphere).normalize(); - - return fSep; - -} - diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereBoxCollisionAlgorithm.h b/extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereBoxCollisionAlgorithm.h deleted file mode 100644 index b839dc4adb1..00000000000 --- a/extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereBoxCollisionAlgorithm.h +++ /dev/null @@ -1,67 +0,0 @@ -/* -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 SPHERE_BOX_COLLISION_ALGORITHM_H -#define SPHERE_BOX_COLLISION_ALGORITHM_H - -#include "BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h" -#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" -#include "BulletCollision/CollisionDispatch/btCollisionCreateFunc.h" -class btPersistentManifold; -#include "btCollisionDispatcher.h" - -#include "LinearMath/btVector3.h" - -/// btSphereBoxCollisionAlgorithm provides sphere-box collision detection. -/// Other features are frame-coherency (persistent data) and collision response. -class btSphereBoxCollisionAlgorithm : public btCollisionAlgorithm -{ - bool m_ownManifold; - btPersistentManifold* m_manifoldPtr; - bool m_isSwapped; - -public: - - btSphereBoxCollisionAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* col0,btCollisionObject* col1, bool isSwapped); - - virtual ~btSphereBoxCollisionAlgorithm(); - - virtual void processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut); - - virtual btScalar calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut); - - btScalar getSphereDistance( btCollisionObject* boxObj,btVector3& v3PointOnBox, btVector3& v3PointOnSphere, const btVector3& v3SphereCenter, btScalar fRadius ); - - btScalar getSpherePenetration( btCollisionObject* boxObj, btVector3& v3PointOnBox, btVector3& v3PointOnSphere, const btVector3& v3SphereCenter, btScalar fRadius, const btVector3& aabbMin, const btVector3& aabbMax); - - struct CreateFunc :public btCollisionAlgorithmCreateFunc - { - virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, btCollisionObject* body0,btCollisionObject* body1) - { - void* mem = ci.m_dispatcher1->allocateCollisionAlgorithm(sizeof(btSphereBoxCollisionAlgorithm)); - if (!m_swapped) - { - return new(mem) btSphereBoxCollisionAlgorithm(0,ci,body0,body1,false); - } else - { - return new(mem) btSphereBoxCollisionAlgorithm(0,ci,body0,body1,true); - } - } - }; - -}; - -#endif //SPHERE_BOX_COLLISION_ALGORITHM_H - diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereSphereCollisionAlgorithm.cpp b/extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereSphereCollisionAlgorithm.cpp deleted file mode 100644 index e7f42647e61..00000000000 --- a/extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereSphereCollisionAlgorithm.cpp +++ /dev/null @@ -1,93 +0,0 @@ -/* -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 "btSphereSphereCollisionAlgorithm.h" -#include "BulletCollision/CollisionDispatch/btCollisionDispatcher.h" -#include "BulletCollision/CollisionShapes/btSphereShape.h" -#include "BulletCollision/CollisionDispatch/btCollisionObject.h" - -btSphereSphereCollisionAlgorithm::btSphereSphereCollisionAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* col0,btCollisionObject* col1) -: btCollisionAlgorithm(ci), -m_ownManifold(false), -m_manifoldPtr(mf) -{ - if (!m_manifoldPtr) - { - m_manifoldPtr = m_dispatcher->getNewManifold(col0,col1); - m_ownManifold = true; - } -} - -btSphereSphereCollisionAlgorithm::~btSphereSphereCollisionAlgorithm() -{ - if (m_ownManifold) - { - if (m_manifoldPtr) - m_dispatcher->releaseManifold(m_manifoldPtr); - } -} - -void btSphereSphereCollisionAlgorithm::processCollision (btCollisionObject* col0,btCollisionObject* col1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut) -{ - (void)dispatchInfo; - - if (!m_manifoldPtr) - return; - - resultOut->setPersistentManifold(m_manifoldPtr); - - btSphereShape* sphere0 = (btSphereShape*)col0->getCollisionShape(); - btSphereShape* sphere1 = (btSphereShape*)col1->getCollisionShape(); - - btVector3 diff = col0->getWorldTransform().getOrigin()- col1->getWorldTransform().getOrigin(); - btScalar len = diff.length(); - btScalar radius0 = sphere0->getRadius(); - btScalar radius1 = sphere1->getRadius(); - - m_manifoldPtr->clearManifold(); - - ///iff distance positive, don't generate a new contact - if ( len > (radius0+radius1)) - { - return; - } - ///distance (negative means penetration) - btScalar dist = len - (radius0+radius1); - - btVector3 normalOnSurfaceB = diff / len; - ///point on A (worldspace) - btVector3 pos0 = col0->getWorldTransform().getOrigin() - radius0 * normalOnSurfaceB; - ///point on B (worldspace) - btVector3 pos1 = col1->getWorldTransform().getOrigin() + radius1* normalOnSurfaceB; - - /// report a contact. internally this will be kept persistent, and contact reduction is done - - - resultOut->addContactPoint(normalOnSurfaceB,pos1,dist); - - //no resultOut->refreshContactPoints(); needed, because of clearManifold (all points are new) - -} - -btScalar btSphereSphereCollisionAlgorithm::calculateTimeOfImpact(btCollisionObject* col0,btCollisionObject* col1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut) -{ - (void)col0; - (void)col1; - (void)dispatchInfo; - (void)resultOut; - - //not yet - return btScalar(1.); -} diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereSphereCollisionAlgorithm.h b/extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereSphereCollisionAlgorithm.h deleted file mode 100644 index bcaa0d303a9..00000000000 --- a/extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereSphereCollisionAlgorithm.h +++ /dev/null @@ -1,59 +0,0 @@ -/* -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 SPHERE_SPHERE_COLLISION_ALGORITHM_H -#define SPHERE_SPHERE_COLLISION_ALGORITHM_H - -#include "BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h" -#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" -#include "BulletCollision/CollisionDispatch/btCollisionCreateFunc.h" -#include "btCollisionDispatcher.h" - -class btPersistentManifold; - -/// btSphereSphereCollisionAlgorithm provides sphere-sphere collision detection. -/// Other features are frame-coherency (persistent data) and collision response. -/// Also provides the most basic sample for custom/user btCollisionAlgorithm -class btSphereSphereCollisionAlgorithm : public btCollisionAlgorithm -{ - bool m_ownManifold; - btPersistentManifold* m_manifoldPtr; - -public: - btSphereSphereCollisionAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* body0,btCollisionObject* body1); - - btSphereSphereCollisionAlgorithm(const btCollisionAlgorithmConstructionInfo& ci) - : btCollisionAlgorithm(ci) {} - - virtual void processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut); - - virtual btScalar calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut); - - - virtual ~btSphereSphereCollisionAlgorithm(); - - struct CreateFunc :public btCollisionAlgorithmCreateFunc - { - virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, btCollisionObject* body0,btCollisionObject* body1) - { - void* mem = ci.m_dispatcher1->allocateCollisionAlgorithm(sizeof(btSphereSphereCollisionAlgorithm)); - return new(mem) btSphereSphereCollisionAlgorithm(0,ci,body0,body1); - } - }; - -}; - -#endif //SPHERE_SPHERE_COLLISION_ALGORITHM_H - diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereTriangleCollisionAlgorithm.cpp b/extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereTriangleCollisionAlgorithm.cpp deleted file mode 100644 index 5d50bfed7a1..00000000000 --- a/extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereTriangleCollisionAlgorithm.cpp +++ /dev/null @@ -1,82 +0,0 @@ -/* -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 "btSphereTriangleCollisionAlgorithm.h" -#include "BulletCollision/CollisionDispatch/btCollisionDispatcher.h" -#include "BulletCollision/CollisionShapes/btSphereShape.h" -#include "BulletCollision/CollisionDispatch/btCollisionObject.h" -#include "SphereTriangleDetector.h" - - -btSphereTriangleCollisionAlgorithm::btSphereTriangleCollisionAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* col0,btCollisionObject* col1,bool swapped) -: btCollisionAlgorithm(ci), -m_ownManifold(false), -m_manifoldPtr(mf), -m_swapped(swapped) -{ - if (!m_manifoldPtr) - { - m_manifoldPtr = m_dispatcher->getNewManifold(col0,col1); - m_ownManifold = true; - } -} - -btSphereTriangleCollisionAlgorithm::~btSphereTriangleCollisionAlgorithm() -{ - if (m_ownManifold) - { - if (m_manifoldPtr) - m_dispatcher->releaseManifold(m_manifoldPtr); - } -} - -void btSphereTriangleCollisionAlgorithm::processCollision (btCollisionObject* col0,btCollisionObject* col1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut) -{ - if (!m_manifoldPtr) - return; - - btCollisionObject* sphereObj = m_swapped? col1 : col0; - btCollisionObject* triObj = m_swapped? col0 : col1; - - btSphereShape* sphere = (btSphereShape*)sphereObj->getCollisionShape(); - btTriangleShape* triangle = (btTriangleShape*)triObj->getCollisionShape(); - - /// report a contact. internally this will be kept persistent, and contact reduction is done - resultOut->setPersistentManifold(m_manifoldPtr); - SphereTriangleDetector detector(sphere,triangle); - - btDiscreteCollisionDetectorInterface::ClosestPointInput input; - input.m_maximumDistanceSquared = btScalar(1e30);//todo: tighter bounds - input.m_transformA = col0->getWorldTransform(); - input.m_transformB = col1->getWorldTransform(); - - detector.getClosestPoints(input,*resultOut,dispatchInfo.m_debugDraw); - - if (m_ownManifold) - resultOut->refreshContactPoints(); - -} - -btScalar btSphereTriangleCollisionAlgorithm::calculateTimeOfImpact(btCollisionObject* col0,btCollisionObject* col1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut) -{ - (void)resultOut; - (void)dispatchInfo; - (void)col0; - (void)col1; - - //not yet - return btScalar(1.); -} diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereTriangleCollisionAlgorithm.h b/extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereTriangleCollisionAlgorithm.h deleted file mode 100644 index 4aefc0c43a5..00000000000 --- a/extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereTriangleCollisionAlgorithm.h +++ /dev/null @@ -1,62 +0,0 @@ -/* -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 SPHERE_TRIANGLE_COLLISION_ALGORITHM_H -#define SPHERE_TRIANGLE_COLLISION_ALGORITHM_H - -#include "BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h" -#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" -#include "BulletCollision/CollisionDispatch/btCollisionCreateFunc.h" -class btPersistentManifold; -#include "btCollisionDispatcher.h" - -/// btSphereSphereCollisionAlgorithm provides sphere-sphere collision detection. -/// Other features are frame-coherency (persistent data) and collision response. -/// Also provides the most basic sample for custom/user btCollisionAlgorithm -class btSphereTriangleCollisionAlgorithm : public btCollisionAlgorithm -{ - bool m_ownManifold; - btPersistentManifold* m_manifoldPtr; - bool m_swapped; - -public: - btSphereTriangleCollisionAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* body0,btCollisionObject* body1,bool swapped); - - btSphereTriangleCollisionAlgorithm(const btCollisionAlgorithmConstructionInfo& ci) - : btCollisionAlgorithm(ci) {} - - virtual void processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut); - - virtual btScalar calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut); - - - virtual ~btSphereTriangleCollisionAlgorithm(); - - struct CreateFunc :public btCollisionAlgorithmCreateFunc - { - - virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, btCollisionObject* body0,btCollisionObject* body1) - { - - void* mem = ci.m_dispatcher1->allocateCollisionAlgorithm(sizeof(btSphereTriangleCollisionAlgorithm)); - - return new(mem) btSphereTriangleCollisionAlgorithm(ci.m_manifold,ci,body0,body1,m_swapped); - } - }; - -}; - -#endif //SPHERE_TRIANGLE_COLLISION_ALGORITHM_H - diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btUnionFind.cpp b/extern/bullet2/src/BulletCollision/CollisionDispatch/btUnionFind.cpp deleted file mode 100644 index c81be8aa75c..00000000000 --- a/extern/bullet2/src/BulletCollision/CollisionDispatch/btUnionFind.cpp +++ /dev/null @@ -1,84 +0,0 @@ -/* -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 "btUnionFind.h" -#include - - - - -btUnionFind::~btUnionFind() -{ - Free(); - -} - -btUnionFind::btUnionFind() -{ - -} - -void btUnionFind::allocate(int N) -{ - m_elements.resize(N); -} -void btUnionFind::Free() -{ - m_elements.clear(); -} - - -void btUnionFind::reset(int N) -{ - allocate(N); - - for (int i = 0; i < N; i++) - { - m_elements[i].m_id = i; m_elements[i].m_sz = 1; - } -} - - -class btUnionFindElementSortPredicate -{ - public: - - bool operator() ( const btElement& lhs, const btElement& rhs ) - { - return lhs.m_id < rhs.m_id; - } -}; - -///this is a special operation, destroying the content of btUnionFind. -///it sorts the elements, based on island id, in order to make it easy to iterate over islands -void btUnionFind::sortIslands() -{ - - //first store the original body index, and islandId - int numElements = m_elements.size(); - - for (int i=0;i m_elements; - - public: - - btUnionFind(); - ~btUnionFind(); - - - //this is a special operation, destroying the content of btUnionFind. - //it sorts the elements, based on island id, in order to make it easy to iterate over islands - void sortIslands(); - - void reset(int N); - - SIMD_FORCE_INLINE int getNumElements() const - { - return int(m_elements.size()); - } - SIMD_FORCE_INLINE bool isRoot(int x) const - { - return (x == m_elements[x].m_id); - } - - btElement& getElement(int index) - { - return m_elements[index]; - } - const btElement& getElement(int index) const - { - return m_elements[index]; - } - - void allocate(int N); - void Free(); - - - - - int find(int p, int q) - { - return (find(p) == find(q)); - } - - void unite(int p, int q) - { - int i = find(p), j = find(q); - if (i == j) - return; - -#ifndef USE_PATH_COMPRESSION - //weighted quick union, this keeps the 'trees' balanced, and keeps performance of unite O( log(n) ) - if (m_elements[i].m_sz < m_elements[j].m_sz) - { - m_elements[i].m_id = j; m_elements[j].m_sz += m_elements[i].m_sz; - } - else - { - m_elements[j].m_id = i; m_elements[i].m_sz += m_elements[j].m_sz; - } -#else - m_elements[i].m_id = j; m_elements[j].m_sz += m_elements[i].m_sz; -#endif //USE_PATH_COMPRESSION - } - - int find(int x) - { - //assert(x < m_N); - //assert(x >= 0); - - while (x != m_elements[x].m_id) - { - //not really a reason not to use path compression, and it flattens the trees/improves find performance dramatically - - #ifdef USE_PATH_COMPRESSION - // - m_elements[x].m_id = m_elements[m_elements[x].m_id].m_id; - #endif // - x = m_elements[x].m_id; - //assert(x < m_N); - //assert(x >= 0); - - } - return x; - } - - - }; - - -#endif //UNION_FIND_H diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btBoxShape.cpp b/extern/bullet2/src/BulletCollision/CollisionShapes/btBoxShape.cpp deleted file mode 100644 index adac455bbcb..00000000000 --- a/extern/bullet2/src/BulletCollision/CollisionShapes/btBoxShape.cpp +++ /dev/null @@ -1,54 +0,0 @@ -/* -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 "btBoxShape.h" - - -//{ - - -void btBoxShape::getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const -{ - const btVector3& halfExtents = getHalfExtentsWithoutMargin(); - - btMatrix3x3 abs_b = t.getBasis().absolute(); - btPoint3 center = t.getOrigin(); - btVector3 extent = btVector3(abs_b[0].dot(halfExtents), - abs_b[1].dot(halfExtents), - abs_b[2].dot(halfExtents)); - extent += btVector3(getMargin(),getMargin(),getMargin()); - - aabbMin = center - extent; - aabbMax = center + extent; - - -} - - -void btBoxShape::calculateLocalInertia(btScalar mass,btVector3& inertia) const -{ - //btScalar margin = btScalar(0.); - btVector3 halfExtents = getHalfExtentsWithMargin(); - - btScalar lx=btScalar(2.)*(halfExtents.x()); - btScalar ly=btScalar(2.)*(halfExtents.y()); - btScalar lz=btScalar(2.)*(halfExtents.z()); - - inertia.setValue(mass/(btScalar(12.0)) * (ly*ly + lz*lz), - mass/(btScalar(12.0)) * (lx*lx + lz*lz), - mass/(btScalar(12.0)) * (lx*lx + ly*ly)); - -} - diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btBoxShape.h b/extern/bullet2/src/BulletCollision/CollisionShapes/btBoxShape.h deleted file mode 100644 index 98f1bd34b09..00000000000 --- a/extern/bullet2/src/BulletCollision/CollisionShapes/btBoxShape.h +++ /dev/null @@ -1,323 +0,0 @@ -/* -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 OBB_BOX_MINKOWSKI_H -#define OBB_BOX_MINKOWSKI_H - -#include "btPolyhedralConvexShape.h" -#include "btCollisionMargin.h" -#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" -#include "LinearMath/btPoint3.h" -#include "LinearMath/btMinMax.h" - -///btBoxShape implements both a feature based (vertex/edge/plane) and implicit (getSupportingVertex) Box -class btBoxShape: public btPolyhedralConvexShape -{ - - //btVector3 m_boxHalfExtents1; //use m_implicitShapeDimensions instead - - -public: - - btVector3 getHalfExtentsWithMargin() const - { - btVector3 halfExtents = getHalfExtentsWithoutMargin(); - btVector3 margin(getMargin(),getMargin(),getMargin()); - halfExtents += margin; - return halfExtents; - } - - const btVector3& getHalfExtentsWithoutMargin() const - { - return m_implicitShapeDimensions;//changed in Bullet 2.63: assume the scaling and margin are included - } - - - virtual int getShapeType() const { return BOX_SHAPE_PROXYTYPE;} - - virtual btVector3 localGetSupportingVertex(const btVector3& vec) const - { - btVector3 halfExtents = getHalfExtentsWithoutMargin(); - btVector3 margin(getMargin(),getMargin(),getMargin()); - halfExtents += margin; - - return btVector3(btFsels(vec.x(), halfExtents.x(), -halfExtents.x()), - btFsels(vec.y(), halfExtents.y(), -halfExtents.y()), - btFsels(vec.z(), halfExtents.z(), -halfExtents.z())); - } - - SIMD_FORCE_INLINE btVector3 localGetSupportingVertexWithoutMargin(const btVector3& vec)const - { - const btVector3& halfExtents = getHalfExtentsWithoutMargin(); - - return btVector3(btFsels(vec.x(), halfExtents.x(), -halfExtents.x()), - btFsels(vec.y(), halfExtents.y(), -halfExtents.y()), - btFsels(vec.z(), halfExtents.z(), -halfExtents.z())); - } - - virtual void batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const - { - const btVector3& halfExtents = getHalfExtentsWithoutMargin(); - - for (int i=0;i>1)) - halfExtents.y() * ((i&2)>>1), - halfExtents.z() * (1-((i&4)>>2)) - halfExtents.z() * ((i&4)>>2)); - } - - - virtual void getPlaneEquation(btVector4& plane,int i) const - { - btVector3 halfExtents = getHalfExtentsWithoutMargin(); - - switch (i) - { - case 0: - plane.setValue(btScalar(1.),btScalar(0.),btScalar(0.)); - plane[3] = -halfExtents.x(); - break; - case 1: - plane.setValue(btScalar(-1.),btScalar(0.),btScalar(0.)); - plane[3] = -halfExtents.x(); - break; - case 2: - plane.setValue(btScalar(0.),btScalar(1.),btScalar(0.)); - plane[3] = -halfExtents.y(); - break; - case 3: - plane.setValue(btScalar(0.),btScalar(-1.),btScalar(0.)); - plane[3] = -halfExtents.y(); - break; - case 4: - plane.setValue(btScalar(0.),btScalar(0.),btScalar(1.)); - plane[3] = -halfExtents.z(); - break; - case 5: - plane.setValue(btScalar(0.),btScalar(0.),btScalar(-1.)); - plane[3] = -halfExtents.z(); - break; - default: - assert(0); - } - } - - - virtual void getEdge(int i,btPoint3& pa,btPoint3& pb) const - //virtual void getEdge(int i,Edge& edge) const - { - int edgeVert0 = 0; - int edgeVert1 = 0; - - switch (i) - { - case 0: - edgeVert0 = 0; - edgeVert1 = 1; - break; - case 1: - edgeVert0 = 0; - edgeVert1 = 2; - break; - case 2: - edgeVert0 = 1; - edgeVert1 = 3; - - break; - case 3: - edgeVert0 = 2; - edgeVert1 = 3; - break; - case 4: - edgeVert0 = 0; - edgeVert1 = 4; - break; - case 5: - edgeVert0 = 1; - edgeVert1 = 5; - - break; - case 6: - edgeVert0 = 2; - edgeVert1 = 6; - break; - case 7: - edgeVert0 = 3; - edgeVert1 = 7; - break; - case 8: - edgeVert0 = 4; - edgeVert1 = 5; - break; - case 9: - edgeVert0 = 4; - edgeVert1 = 6; - break; - case 10: - edgeVert0 = 5; - edgeVert1 = 7; - break; - case 11: - edgeVert0 = 6; - edgeVert1 = 7; - break; - default: - btAssert(0); - - } - - getVertex(edgeVert0,pa ); - getVertex(edgeVert1,pb ); - } - - - - - - virtual bool isInside(const btPoint3& pt,btScalar tolerance) const - { - btVector3 halfExtents = getHalfExtentsWithoutMargin(); - - //btScalar minDist = 2*tolerance; - - bool result = (pt.x() <= (halfExtents.x()+tolerance)) && - (pt.x() >= (-halfExtents.x()-tolerance)) && - (pt.y() <= (halfExtents.y()+tolerance)) && - (pt.y() >= (-halfExtents.y()-tolerance)) && - (pt.z() <= (halfExtents.z()+tolerance)) && - (pt.z() >= (-halfExtents.z()-tolerance)); - - return result; - } - - - //debugging - virtual const char* getName()const - { - return "Box"; - } - - virtual int getNumPreferredPenetrationDirections() const - { - return 6; - } - - virtual void getPreferredPenetrationDirection(int index, btVector3& penetrationVector) const - { - switch (index) - { - case 0: - penetrationVector.setValue(btScalar(1.),btScalar(0.),btScalar(0.)); - break; - case 1: - penetrationVector.setValue(btScalar(-1.),btScalar(0.),btScalar(0.)); - break; - case 2: - penetrationVector.setValue(btScalar(0.),btScalar(1.),btScalar(0.)); - break; - case 3: - penetrationVector.setValue(btScalar(0.),btScalar(-1.),btScalar(0.)); - break; - case 4: - penetrationVector.setValue(btScalar(0.),btScalar(0.),btScalar(1.)); - break; - case 5: - penetrationVector.setValue(btScalar(0.),btScalar(0.),btScalar(-1.)); - break; - default: - assert(0); - } - } - -}; - -#endif //OBB_BOX_MINKOWSKI_H - - diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btBvhTriangleMeshShape.cpp b/extern/bullet2/src/BulletCollision/CollisionShapes/btBvhTriangleMeshShape.cpp deleted file mode 100644 index eea263fe5b4..00000000000 --- a/extern/bullet2/src/BulletCollision/CollisionShapes/btBvhTriangleMeshShape.cpp +++ /dev/null @@ -1,200 +0,0 @@ -/* -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 "BulletCollision/CollisionShapes/btBvhTriangleMeshShape.h" -#include "BulletCollision/CollisionShapes/btOptimizedBvh.h" - - -///Bvh Concave triangle mesh is a static-triangle mesh shape with Bounding Volume Hierarchy optimization. -///Uses an interface to access the triangles to allow for sharing graphics/physics triangles. -btBvhTriangleMeshShape::btBvhTriangleMeshShape(btStridingMeshInterface* meshInterface, bool useQuantizedAabbCompression, bool buildBvh) -:btTriangleMeshShape(meshInterface), -m_bvh(0), -m_useQuantizedAabbCompression(useQuantizedAabbCompression), -m_ownsBvh(false) -{ - //construct bvh from meshInterface -#ifndef DISABLE_BVH - - btVector3 bvhAabbMin,bvhAabbMax; - meshInterface->calculateAabbBruteForce(bvhAabbMin,bvhAabbMax); - - if (buildBvh) - { - void* mem = btAlignedAlloc(sizeof(btOptimizedBvh),16); - m_bvh = new (mem) btOptimizedBvh(); - m_bvh->build(meshInterface,m_useQuantizedAabbCompression,bvhAabbMin,bvhAabbMax); - m_ownsBvh = true; - } - -#endif //DISABLE_BVH - -} - -btBvhTriangleMeshShape::btBvhTriangleMeshShape(btStridingMeshInterface* meshInterface, bool useQuantizedAabbCompression,const btVector3& bvhAabbMin,const btVector3& bvhAabbMax,bool buildBvh) -:btTriangleMeshShape(meshInterface), -m_bvh(0), -m_useQuantizedAabbCompression(useQuantizedAabbCompression), -m_ownsBvh(false) -{ - //construct bvh from meshInterface -#ifndef DISABLE_BVH - - if (buildBvh) - { - void* mem = btAlignedAlloc(sizeof(btOptimizedBvh),16); - m_bvh = new (mem) btOptimizedBvh(); - - m_bvh->build(meshInterface,m_useQuantizedAabbCompression,bvhAabbMin,bvhAabbMax); - m_ownsBvh = true; - } - -#endif //DISABLE_BVH - -} - -void btBvhTriangleMeshShape::partialRefitTree(const btVector3& aabbMin,const btVector3& aabbMax) -{ - m_bvh->refitPartial( m_meshInterface,aabbMin,aabbMax ); - - m_localAabbMin.setMin(aabbMin); - m_localAabbMax.setMax(aabbMax); -} - - -void btBvhTriangleMeshShape::refitTree() -{ - m_bvh->refit( m_meshInterface ); - - recalcLocalAabb(); -} - -btBvhTriangleMeshShape::~btBvhTriangleMeshShape() -{ - if (m_ownsBvh) - { - m_bvh->~btOptimizedBvh(); - btAlignedFree(m_bvh); - } -} - -//perform bvh tree traversal and report overlapping triangles to 'callback' -void btBvhTriangleMeshShape::processAllTriangles(btTriangleCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const -{ - -#ifdef DISABLE_BVH - //brute force traverse all triangles - btTriangleMeshShape::processAllTriangles(callback,aabbMin,aabbMax); -#else - - //first get all the nodes - - - struct MyNodeOverlapCallback : public btNodeOverlapCallback - { - btStridingMeshInterface* m_meshInterface; - btTriangleCallback* m_callback; - btVector3 m_triangle[3]; - - - MyNodeOverlapCallback(btTriangleCallback* callback,btStridingMeshInterface* meshInterface) - :m_meshInterface(meshInterface), - m_callback(callback) - { - } - - virtual void processNode(int nodeSubPart, int nodeTriangleIndex) - { - const unsigned char *vertexbase; - int numverts; - PHY_ScalarType type; - int stride; - const unsigned char *indexbase; - int indexstride; - int numfaces; - PHY_ScalarType indicestype; - - - m_meshInterface->getLockedReadOnlyVertexIndexBase( - &vertexbase, - numverts, - type, - stride, - &indexbase, - indexstride, - numfaces, - indicestype, - nodeSubPart); - - int* gfxbase = (int*)(indexbase+nodeTriangleIndex*indexstride); - - const btVector3& meshScaling = m_meshInterface->getScaling(); - for (int j=2;j>=0;j--) - { - - int graphicsindex = gfxbase[j]; - - -#ifdef DEBUG_TRIANGLE_MESH - printf("%d ,",graphicsindex); -#endif //DEBUG_TRIANGLE_MESH - btScalar* graphicsbase = (btScalar*)(vertexbase+graphicsindex*stride); - - m_triangle[j] = btVector3( - graphicsbase[0]*meshScaling.getX(), - graphicsbase[1]*meshScaling.getY(), - graphicsbase[2]*meshScaling.getZ()); -#ifdef DEBUG_TRIANGLE_MESH - printf("triangle vertices:%f,%f,%f\n",triangle[j].x(),triangle[j].y(),triangle[j].z()); -#endif //DEBUG_TRIANGLE_MESH - } - - m_callback->processTriangle(m_triangle,nodeSubPart,nodeTriangleIndex); - m_meshInterface->unLockReadOnlyVertexBase(nodeSubPart); - } - - }; - - MyNodeOverlapCallback myNodeCallback(callback,m_meshInterface); - - m_bvh->reportAabbOverlappingNodex(&myNodeCallback,aabbMin,aabbMax); - - -#endif//DISABLE_BVH - - -} - - -void btBvhTriangleMeshShape::setLocalScaling(const btVector3& scaling) -{ - if ((getLocalScaling() -scaling).length2() > SIMD_EPSILON) - { - btTriangleMeshShape::setLocalScaling(scaling); - if (m_ownsBvh) - { - m_bvh->~btOptimizedBvh(); - btAlignedFree(m_bvh); - } - ///m_localAabbMin/m_localAabbMax is already re-calculated in btTriangleMeshShape. We could just scale aabb, but this needs some more work - void* mem = btAlignedAlloc(sizeof(btOptimizedBvh),16); - m_bvh = new(mem) btOptimizedBvh(); - //rebuild the bvh... - m_bvh->build(m_meshInterface,m_useQuantizedAabbCompression,m_localAabbMin,m_localAabbMax); - - } -} diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btBvhTriangleMeshShape.h b/extern/bullet2/src/BulletCollision/CollisionShapes/btBvhTriangleMeshShape.h deleted file mode 100644 index 95c73b2441f..00000000000 --- a/extern/bullet2/src/BulletCollision/CollisionShapes/btBvhTriangleMeshShape.h +++ /dev/null @@ -1,90 +0,0 @@ -/* -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_TRIANGLE_MESH_SHAPE_H -#define BVH_TRIANGLE_MESH_SHAPE_H - -#include "btTriangleMeshShape.h" -#include "btOptimizedBvh.h" -#include "LinearMath/btAlignedAllocator.h" - -///Bvh Concave triangle mesh is a static-triangle mesh shape with Bounding Volume Hierarchy optimization. -///Uses an interface to access the triangles to allow for sharing graphics/physics triangles. -ATTRIBUTE_ALIGNED16(class) btBvhTriangleMeshShape : public btTriangleMeshShape -{ - - btOptimizedBvh* m_bvh; - bool m_useQuantizedAabbCompression; - bool m_ownsBvh; - bool m_pad[11];////need padding due to alignment - -public: - - BT_DECLARE_ALIGNED_ALLOCATOR(); - - btBvhTriangleMeshShape() :btTriangleMeshShape(0),m_bvh(0),m_ownsBvh(false) {}; - btBvhTriangleMeshShape(btStridingMeshInterface* meshInterface, bool useQuantizedAabbCompression, bool buildBvh = true); - - ///optionally pass in a larger bvh aabb, used for quantization. This allows for deformations within this aabb - btBvhTriangleMeshShape(btStridingMeshInterface* meshInterface, bool useQuantizedAabbCompression,const btVector3& bvhAabbMin,const btVector3& bvhAabbMax, bool buildBvh = true); - - virtual ~btBvhTriangleMeshShape(); - - - /* - virtual int getShapeType() const - { - return TRIANGLE_MESH_SHAPE_PROXYTYPE; - } - */ - - - - virtual void processAllTriangles(btTriangleCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const; - - void refitTree(); - - ///for a fast incremental refit of parts of the tree. Note: the entire AABB of the tree will become more conservative, it never shrinks - void partialRefitTree(const btVector3& aabbMin,const btVector3& aabbMax); - - //debugging - virtual const char* getName()const {return "BVHTRIANGLEMESH";} - - - virtual void setLocalScaling(const btVector3& scaling); - - btOptimizedBvh* getOptimizedBvh() - { - return m_bvh; - } - - - void setOptimizedBvh(btOptimizedBvh* bvh) - { - btAssert(!m_bvh); - btAssert(!m_ownsBvh); - - m_bvh = bvh; - m_ownsBvh = false; - } - - bool usesQuantizedAabbCompression() const - { - return m_useQuantizedAabbCompression; - } -} -; - -#endif //BVH_TRIANGLE_MESH_SHAPE_H diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btCapsuleShape.cpp b/extern/bullet2/src/BulletCollision/CollisionShapes/btCapsuleShape.cpp deleted file mode 100644 index b4f21f38b3d..00000000000 --- a/extern/bullet2/src/BulletCollision/CollisionShapes/btCapsuleShape.cpp +++ /dev/null @@ -1,146 +0,0 @@ -/* -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 "btCapsuleShape.h" - -#include "BulletCollision/CollisionShapes/btCollisionMargin.h" -#include "LinearMath/btQuaternion.h" - -btCapsuleShape::btCapsuleShape(btScalar radius, btScalar height) -{ - m_implicitShapeDimensions.setValue(radius,0.5f*height,radius); -} - - - btVector3 btCapsuleShape::localGetSupportingVertexWithoutMargin(const btVector3& vec0)const -{ - - btVector3 supVec(0,0,0); - - btScalar maxDot(btScalar(-1e30)); - - btVector3 vec = vec0; - btScalar lenSqr = vec.length2(); - if (lenSqr < btScalar(0.0001)) - { - vec.setValue(1,0,0); - } else - { - btScalar rlen = btScalar(1.) / btSqrt(lenSqr ); - vec *= rlen; - } - - btVector3 vtx; - btScalar newDot; - - btScalar radius = getRadius(); - - - { - btVector3 pos(0,getHalfHeight(),0); - vtx = pos +vec*m_localScaling*(radius) - vec * getMargin(); - newDot = vec.dot(vtx); - if (newDot > maxDot) - { - maxDot = newDot; - supVec = vtx; - } - } - { - btVector3 pos(0,-getHalfHeight(),0); - vtx = pos +vec*m_localScaling*(radius) - vec * getMargin(); - newDot = vec.dot(vtx); - if (newDot > maxDot) - { - maxDot = newDot; - supVec = vtx; - } - } - - return supVec; - -} - - void btCapsuleShape::batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const -{ - - - btScalar radius = getRadius(); - - for (int j=0;j maxDot) - { - maxDot = newDot; - supportVerticesOut[j] = vtx; - } - } - { - btVector3 pos(0,-getHalfHeight(),0); - vtx = pos +vec*m_localScaling*(radius) - vec * getMargin(); - newDot = vec.dot(vtx); - if (newDot > maxDot) - { - maxDot = newDot; - supportVerticesOut[j] = vtx; - } - } - - } -} - - -void btCapsuleShape::calculateLocalInertia(btScalar mass,btVector3& inertia) const -{ - //as an approximation, take the inertia of the box that bounds the spheres - - btTransform ident; - ident.setIdentity(); - - - btScalar radius = getRadius(); - - btVector3 halfExtents(radius,radius+getHalfHeight(),radius); - - btScalar margin = CONVEX_DISTANCE_MARGIN; - - btScalar lx=btScalar(2.)*(halfExtents[0]+margin); - btScalar ly=btScalar(2.)*(halfExtents[1]+margin); - btScalar lz=btScalar(2.)*(halfExtents[2]+margin); - const btScalar x2 = lx*lx; - const btScalar y2 = ly*ly; - const btScalar z2 = lz*lz; - const btScalar scaledmass = mass * btScalar(.08333333); - - inertia[0] = scaledmass * (y2+z2); - inertia[1] = scaledmass * (x2+z2); - inertia[2] = scaledmass * (x2+y2); - -} - - - - - diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btCapsuleShape.h b/extern/bullet2/src/BulletCollision/CollisionShapes/btCapsuleShape.h deleted file mode 100644 index 0b566450fef..00000000000 --- a/extern/bullet2/src/BulletCollision/CollisionShapes/btCapsuleShape.h +++ /dev/null @@ -1,60 +0,0 @@ -/* -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 BT_CAPSULE_SHAPE_H -#define BT_CAPSULE_SHAPE_H - -#include "btConvexInternalShape.h" -#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" // for the types - - -///btCapsuleShape represents a capsule around the Y axis -///A more general solution that can represent capsules is the btMultiSphereShape -class btCapsuleShape : public btConvexInternalShape -{ - -public: - btCapsuleShape(btScalar radius,btScalar height); - - ///CollisionShape Interface - virtual void calculateLocalInertia(btScalar mass,btVector3& inertia) const; - - /// btConvexShape Interface - virtual btVector3 localGetSupportingVertexWithoutMargin(const btVector3& vec)const; - - virtual void batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const; - - virtual int getShapeType() const { return CAPSULE_SHAPE_PROXYTYPE; } - - virtual const char* getName()const - { - return "CapsuleShape"; - } - - btScalar getRadius() const - { - return m_implicitShapeDimensions.getX(); - } - - btScalar getHalfHeight() const - { - return m_implicitShapeDimensions.getY(); - } - -}; - - - -#endif //BT_CAPSULE_SHAPE_H diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btCollisionMargin.h b/extern/bullet2/src/BulletCollision/CollisionShapes/btCollisionMargin.h deleted file mode 100644 index 4730264d3df..00000000000 --- a/extern/bullet2/src/BulletCollision/CollisionShapes/btCollisionMargin.h +++ /dev/null @@ -1,26 +0,0 @@ -/* -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 COLLISION_MARGIN_H -#define COLLISION_MARGIN_H - -//used by Gjk and some other algorithms - -#define CONVEX_DISTANCE_MARGIN btScalar(0.04)// btScalar(0.1)//;//btScalar(0.01) - - - -#endif //COLLISION_MARGIN_H - diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btCollisionShape.cpp b/extern/bullet2/src/BulletCollision/CollisionShapes/btCollisionShape.cpp deleted file mode 100644 index 81d82428f4c..00000000000 --- a/extern/bullet2/src/BulletCollision/CollisionShapes/btCollisionShape.cpp +++ /dev/null @@ -1,85 +0,0 @@ -/* -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 "BulletCollision/CollisionShapes/btCollisionShape.h" - - -/* - Make sure this dummy function never changes so that it - can be used by probes that are checking whether the - library is actually installed. -*/ -extern "C" void btBulletCollisionProbe () {} - - - -void btCollisionShape::getBoundingSphere(btVector3& center,btScalar& radius) const -{ - btTransform tr; - tr.setIdentity(); - btVector3 aabbMin,aabbMax; - - getAabb(tr,aabbMin,aabbMax); - - radius = (aabbMax-aabbMin).length()*btScalar(0.5); - center = (aabbMin+aabbMax)*btScalar(0.5); -} - -btScalar btCollisionShape::getAngularMotionDisc() const -{ - btVector3 center; - btScalar disc; - getBoundingSphere(center,disc); - disc += (center).length(); - return disc; -} - -void btCollisionShape::calculateTemporalAabb(const btTransform& curTrans,const btVector3& linvel,const btVector3& angvel,btScalar timeStep, btVector3& temporalAabbMin,btVector3& temporalAabbMax) -{ - //start with static aabb - getAabb(curTrans,temporalAabbMin,temporalAabbMax); - - btScalar temporalAabbMaxx = temporalAabbMax.getX(); - btScalar temporalAabbMaxy = temporalAabbMax.getY(); - btScalar temporalAabbMaxz = temporalAabbMax.getZ(); - btScalar temporalAabbMinx = temporalAabbMin.getX(); - btScalar temporalAabbMiny = temporalAabbMin.getY(); - btScalar temporalAabbMinz = temporalAabbMin.getZ(); - - // add linear motion - btVector3 linMotion = linvel*timeStep; - //todo: simd would have a vector max/min operation, instead of per-element access - if (linMotion.x() > btScalar(0.)) - temporalAabbMaxx += linMotion.x(); - else - temporalAabbMinx += linMotion.x(); - if (linMotion.y() > btScalar(0.)) - temporalAabbMaxy += linMotion.y(); - else - temporalAabbMiny += linMotion.y(); - if (linMotion.z() > btScalar(0.)) - temporalAabbMaxz += linMotion.z(); - else - temporalAabbMinz += linMotion.z(); - - //add conservative angular motion - btScalar angularMotion = angvel.length() * getAngularMotionDisc() * timeStep; - btVector3 angularMotion3d(angularMotion,angularMotion,angularMotion); - temporalAabbMin = btVector3(temporalAabbMinx,temporalAabbMiny,temporalAabbMinz); - temporalAabbMax = btVector3(temporalAabbMaxx,temporalAabbMaxy,temporalAabbMaxz); - - temporalAabbMin -= angularMotion3d; - temporalAabbMax += angularMotion3d; -} diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btCollisionShape.h b/extern/bullet2/src/BulletCollision/CollisionShapes/btCollisionShape.h deleted file mode 100644 index 53fb12e33a1..00000000000 --- a/extern/bullet2/src/BulletCollision/CollisionShapes/btCollisionShape.h +++ /dev/null @@ -1,94 +0,0 @@ -/* -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 COLLISION_SHAPE_H -#define COLLISION_SHAPE_H - -#include "LinearMath/btTransform.h" -#include "LinearMath/btVector3.h" -#include "LinearMath/btMatrix3x3.h" -#include "LinearMath/btPoint3.h" -#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" //for the shape types - -///btCollisionShape provides interface for collision shapes that can be shared among btCollisionObjects. -class btCollisionShape -{ -public: - - btCollisionShape() - { - } - virtual ~btCollisionShape() - { - } - - ///getAabb returns the axis aligned bounding box in the coordinate frame of the given transform t. - virtual void getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const =0; - - virtual void getBoundingSphere(btVector3& center,btScalar& radius) const; - - ///getAngularMotionDisc returns the maximus radius needed for Conservative Advancement to handle time-of-impact with rotations. - virtual btScalar getAngularMotionDisc() const; - - - ///calculateTemporalAabb calculates the enclosing aabb for the moving object over interval [0..timeStep) - ///result is conservative - void calculateTemporalAabb(const btTransform& curTrans,const btVector3& linvel,const btVector3& angvel,btScalar timeStep, btVector3& temporalAabbMin,btVector3& temporalAabbMax); - -#ifndef __SPU__ - - SIMD_FORCE_INLINE bool isPolyhedral() const - { - return btBroadphaseProxy::isPolyhedral(getShapeType()); - } - - SIMD_FORCE_INLINE bool isConvex() const - { - return btBroadphaseProxy::isConvex(getShapeType()); - } - SIMD_FORCE_INLINE bool isConcave() const - { - return btBroadphaseProxy::isConcave(getShapeType()); - } - SIMD_FORCE_INLINE bool isCompound() const - { - return btBroadphaseProxy::isCompound(getShapeType()); - } - - ///isInfinite is used to catch simulation error (aabb check) - SIMD_FORCE_INLINE bool isInfinite() const - { - return btBroadphaseProxy::isInfinite(getShapeType()); - } - - virtual int getShapeType() const=0; - virtual void setLocalScaling(const btVector3& scaling) =0; - virtual const btVector3& getLocalScaling() const =0; - virtual void calculateLocalInertia(btScalar mass,btVector3& inertia) const = 0; - - -//debugging support - virtual const char* getName()const =0 ; -#endif //__SPU__ - - - - virtual void setMargin(btScalar margin) = 0; - virtual btScalar getMargin() const = 0; - -}; - -#endif //COLLISION_SHAPE_H - diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btCompoundShape.cpp b/extern/bullet2/src/BulletCollision/CollisionShapes/btCompoundShape.cpp deleted file mode 100644 index 114a1f4c1fc..00000000000 --- a/extern/bullet2/src/BulletCollision/CollisionShapes/btCompoundShape.cpp +++ /dev/null @@ -1,107 +0,0 @@ -/* -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 "btCompoundShape.h" - - -#include "btCollisionShape.h" - - -btCompoundShape::btCompoundShape() -:m_localAabbMin(btScalar(1e30),btScalar(1e30),btScalar(1e30)), -m_localAabbMax(btScalar(-1e30),btScalar(-1e30),btScalar(-1e30)), -m_aabbTree(0), -m_collisionMargin(btScalar(0.)), -m_localScaling(btScalar(1.),btScalar(1.),btScalar(1.)) -{ -} - - -btCompoundShape::~btCompoundShape() -{ -} - -void btCompoundShape::addChildShape(const btTransform& localTransform,btCollisionShape* shape) -{ - //m_childTransforms.push_back(localTransform); - //m_childShapes.push_back(shape); - btCompoundShapeChild child; - child.m_transform = localTransform; - child.m_childShape = shape; - child.m_childShapeType = shape->getShapeType(); - child.m_childMargin = shape->getMargin(); - - m_children.push_back(child); - - //extend the local aabbMin/aabbMax - btVector3 localAabbMin,localAabbMax; - shape->getAabb(localTransform,localAabbMin,localAabbMax); - for (int i=0;i<3;i++) - { - if (m_localAabbMin[i] > localAabbMin[i]) - { - m_localAabbMin[i] = localAabbMin[i]; - } - if (m_localAabbMax[i] < localAabbMax[i]) - { - m_localAabbMax[i] = localAabbMax[i]; - } - - } -} - - - - ///getAabb's default implementation is brute force, expected derived classes to implement a fast dedicated version -void btCompoundShape::getAabb(const btTransform& trans,btVector3& aabbMin,btVector3& aabbMax) const -{ - btVector3 localHalfExtents = btScalar(0.5)*(m_localAabbMax-m_localAabbMin); - btVector3 localCenter = btScalar(0.5)*(m_localAabbMax+m_localAabbMin); - - btMatrix3x3 abs_b = trans.getBasis().absolute(); - - btPoint3 center = trans(localCenter); - - btVector3 extent = btVector3(abs_b[0].dot(localHalfExtents), - abs_b[1].dot(localHalfExtents), - abs_b[2].dot(localHalfExtents)); - extent += btVector3(getMargin(),getMargin(),getMargin()); - - aabbMin = center - extent; - aabbMax = center + extent; -} - -void btCompoundShape::calculateLocalInertia(btScalar mass,btVector3& inertia) const -{ - //approximation: take the inertia from the aabb for now - btTransform ident; - ident.setIdentity(); - btVector3 aabbMin,aabbMax; - getAabb(ident,aabbMin,aabbMax); - - btVector3 halfExtents = (aabbMax-aabbMin)*btScalar(0.5); - - btScalar lx=btScalar(2.)*(halfExtents.x()); - btScalar ly=btScalar(2.)*(halfExtents.y()); - btScalar lz=btScalar(2.)*(halfExtents.z()); - - inertia[0] = mass/(btScalar(12.0)) * (ly*ly + lz*lz); - inertia[1] = mass/(btScalar(12.0)) * (lx*lx + lz*lz); - inertia[2] = mass/(btScalar(12.0)) * (lx*lx + ly*ly); - -} - - - diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btCompoundShape.h b/extern/bullet2/src/BulletCollision/CollisionShapes/btCompoundShape.h deleted file mode 100644 index d23bd65b5e8..00000000000 --- a/extern/bullet2/src/BulletCollision/CollisionShapes/btCompoundShape.h +++ /dev/null @@ -1,136 +0,0 @@ -/* -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 COMPOUND_SHAPE_H -#define COMPOUND_SHAPE_H - -#include "btCollisionShape.h" - -#include "LinearMath/btVector3.h" -#include "LinearMath/btTransform.h" -#include "LinearMath/btMatrix3x3.h" -#include "btCollisionMargin.h" -#include "LinearMath/btAlignedObjectArray.h" - -class btOptimizedBvh; - -ATTRIBUTE_ALIGNED16(struct) btCompoundShapeChild -{ - BT_DECLARE_ALIGNED_ALLOCATOR(); - - btTransform m_transform; - btCollisionShape* m_childShape; - int m_childShapeType; - btScalar m_childMargin; -}; - -/// btCompoundShape allows to store multiple other btCollisionShapes -/// This allows for concave collision objects. This is more general then the Static Concave btTriangleMeshShape. -ATTRIBUTE_ALIGNED16(class) btCompoundShape : public btCollisionShape -{ - //btAlignedObjectArray m_childTransforms; - //btAlignedObjectArray m_childShapes; - btAlignedObjectArray m_children; - btVector3 m_localAabbMin; - btVector3 m_localAabbMax; - - btOptimizedBvh* m_aabbTree; - -public: - BT_DECLARE_ALIGNED_ALLOCATOR(); - - btCompoundShape(); - - virtual ~btCompoundShape(); - - void addChildShape(const btTransform& localTransform,btCollisionShape* shape); - - int getNumChildShapes() const - { - return int (m_children.size()); - } - - btCollisionShape* getChildShape(int index) - { - return m_children[index].m_childShape; - } - const btCollisionShape* getChildShape(int index) const - { - return m_children[index].m_childShape; - } - - btTransform getChildTransform(int index) - { - return m_children[index].m_transform; - } - const btTransform getChildTransform(int index) const - { - return m_children[index].m_transform; - } - - - btCompoundShapeChild* getChildList() - { - return &m_children[0]; - } - - ///getAabb's default implementation is brute force, expected derived classes to implement a fast dedicated version - void getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const; - - - virtual void setLocalScaling(const btVector3& scaling) - { - m_localScaling = scaling; - } - virtual const btVector3& getLocalScaling() const - { - return m_localScaling; - } - - virtual void calculateLocalInertia(btScalar mass,btVector3& inertia) const; - - virtual int getShapeType() const { return COMPOUND_SHAPE_PROXYTYPE;} - - virtual void setMargin(btScalar margin) - { - m_collisionMargin = margin; - } - virtual btScalar getMargin() const - { - return m_collisionMargin; - } - virtual const char* getName()const - { - return "Compound"; - } - - //this is optional, but should make collision queries faster, by culling non-overlapping nodes - void createAabbTreeFromChildren(); - - const btOptimizedBvh* getAabbTree() const - { - return m_aabbTree; - } - -private: - btScalar m_collisionMargin; -protected: - btVector3 m_localScaling; - -}; - - - -#endif //COMPOUND_SHAPE_H diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btConcaveShape.cpp b/extern/bullet2/src/BulletCollision/CollisionShapes/btConcaveShape.cpp deleted file mode 100644 index 5103500a012..00000000000 --- a/extern/bullet2/src/BulletCollision/CollisionShapes/btConcaveShape.cpp +++ /dev/null @@ -1,28 +0,0 @@ - -/* -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 "btConcaveShape.h" - -btConcaveShape::btConcaveShape() : m_collisionMargin(btScalar(0.)) -{ - -} - -btConcaveShape::~btConcaveShape() -{ - -} diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btConcaveShape.h b/extern/bullet2/src/BulletCollision/CollisionShapes/btConcaveShape.h deleted file mode 100644 index 4db4e6513dd..00000000000 --- a/extern/bullet2/src/BulletCollision/CollisionShapes/btConcaveShape.h +++ /dev/null @@ -1,50 +0,0 @@ -/* -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_SHAPE_H -#define CONCAVE_SHAPE_H - -#include "btCollisionShape.h" -#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" // for the types -#include "btTriangleCallback.h" - - -///Concave shape proves an interface concave shapes that can produce triangles that overlapping a given AABB. -///Static triangle mesh, infinite plane, height field/landscapes are example that implement this interface. -class btConcaveShape : public btCollisionShape -{ -protected: - btScalar m_collisionMargin; - -public: - btConcaveShape(); - - virtual ~btConcaveShape(); - - virtual void processAllTriangles(btTriangleCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const = 0; - - virtual btScalar getMargin() const { - return m_collisionMargin; - } - virtual void setMargin(btScalar collisionMargin) - { - m_collisionMargin = collisionMargin; - } - - - -}; - -#endif //CONCAVE_SHAPE_H diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btConeShape.cpp b/extern/bullet2/src/BulletCollision/CollisionShapes/btConeShape.cpp deleted file mode 100644 index 207b3024bc3..00000000000 --- a/extern/bullet2/src/BulletCollision/CollisionShapes/btConeShape.cpp +++ /dev/null @@ -1,133 +0,0 @@ -/* -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 "btConeShape.h" -#include "LinearMath/btPoint3.h" - - - -btConeShape::btConeShape (btScalar radius,btScalar height): -m_radius (radius), -m_height(height) -{ - setConeUpIndex(1); - btVector3 halfExtents; - m_sinAngle = (m_radius / btSqrt(m_radius * m_radius + m_height * m_height)); -} - -btConeShapeZ::btConeShapeZ (btScalar radius,btScalar height): -btConeShape(radius,height) -{ - setConeUpIndex(2); -} - -btConeShapeX::btConeShapeX (btScalar radius,btScalar height): -btConeShape(radius,height) -{ - setConeUpIndex(0); -} - -///choose upAxis index -void btConeShape::setConeUpIndex(int upIndex) -{ - switch (upIndex) - { - case 0: - m_coneIndices[0] = 1; - m_coneIndices[1] = 0; - m_coneIndices[2] = 2; - break; - case 1: - m_coneIndices[0] = 0; - m_coneIndices[1] = 1; - m_coneIndices[2] = 2; - break; - case 2: - m_coneIndices[0] = 0; - m_coneIndices[1] = 2; - m_coneIndices[2] = 1; - break; - default: - assert(0); - }; -} - -btVector3 btConeShape::coneLocalSupport(const btVector3& v) const -{ - - btScalar halfHeight = m_height * btScalar(0.5); - - if (v[m_coneIndices[1]] > v.length() * m_sinAngle) - { - btVector3 tmp; - - tmp[m_coneIndices[0]] = btScalar(0.); - tmp[m_coneIndices[1]] = halfHeight; - tmp[m_coneIndices[2]] = btScalar(0.); - return tmp; - } - else { - btScalar s = btSqrt(v[m_coneIndices[0]] * v[m_coneIndices[0]] + v[m_coneIndices[2]] * v[m_coneIndices[2]]); - if (s > SIMD_EPSILON) { - btScalar d = m_radius / s; - btVector3 tmp; - tmp[m_coneIndices[0]] = v[m_coneIndices[0]] * d; - tmp[m_coneIndices[1]] = -halfHeight; - tmp[m_coneIndices[2]] = v[m_coneIndices[2]] * d; - return tmp; - } - else { - btVector3 tmp; - tmp[m_coneIndices[0]] = btScalar(0.); - tmp[m_coneIndices[1]] = -halfHeight; - tmp[m_coneIndices[2]] = btScalar(0.); - return tmp; - } - } - -} - -btVector3 btConeShape::localGetSupportingVertexWithoutMargin(const btVector3& vec) const -{ - return coneLocalSupport(vec); -} - -void btConeShape::batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const -{ - for (int i=0;i maxDot) - { - maxDot = newDot; - supVec = vtx; - } - } - return supVec; -} - -void btConvexHullShape::batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const -{ - btScalar newDot; - //use 'w' component of supportVerticesOut? - { - for (int i=0;i supportVerticesOut[j][3]) - { - //WARNING: don't swap next lines, the w component would get overwritten! - supportVerticesOut[j] = vtx; - supportVerticesOut[j][3] = newDot; - } - } - } - - - -} - - - -btVector3 btConvexHullShape::localGetSupportingVertex(const btVector3& vec)const -{ - btVector3 supVertex = localGetSupportingVertexWithoutMargin(vec); - - if ( getMargin()!=btScalar(0.) ) - { - btVector3 vecnorm = vec; - if (vecnorm .length2() < (SIMD_EPSILON*SIMD_EPSILON)) - { - vecnorm.setValue(btScalar(-1.),btScalar(-1.),btScalar(-1.)); - } - vecnorm.normalize(); - supVertex+= getMargin() * vecnorm; - } - return supVertex; -} - - - - - - - - - -//currently just for debugging (drawing), perhaps future support for algebraic continuous collision detection -//Please note that you can debug-draw btConvexHullShape with the Raytracer Demo -int btConvexHullShape::getNumVertices() const -{ - return m_points.size(); -} - -int btConvexHullShape::getNumEdges() const -{ - return m_points.size(); -} - -void btConvexHullShape::getEdge(int i,btPoint3& pa,btPoint3& pb) const -{ - - int index0 = i%m_points.size(); - int index1 = (i+1)%m_points.size(); - pa = m_points[index0]*m_localScaling; - pb = m_points[index1]*m_localScaling; -} - -void btConvexHullShape::getVertex(int i,btPoint3& vtx) const -{ - vtx = m_points[i]*m_localScaling; -} - -int btConvexHullShape::getNumPlanes() const -{ - return 0; -} - -void btConvexHullShape::getPlane(btVector3& ,btPoint3& ,int ) const -{ - - btAssert(0); -} - -//not yet -bool btConvexHullShape::isInside(const btPoint3& ,btScalar ) const -{ - assert(0); - return false; -} - diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btConvexHullShape.h b/extern/bullet2/src/BulletCollision/CollisionShapes/btConvexHullShape.h deleted file mode 100644 index 0928d68b8fc..00000000000 --- a/extern/bullet2/src/BulletCollision/CollisionShapes/btConvexHullShape.h +++ /dev/null @@ -1,77 +0,0 @@ -/* -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 CONVEX_HULL_SHAPE_H -#define CONVEX_HULL_SHAPE_H - -#include "btPolyhedralConvexShape.h" -#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" // for the types -#include "LinearMath/btAlignedObjectArray.h" - -///ConvexHullShape implements an implicit (getSupportingVertex) Convex Hull of a Point Cloud (vertices) -///No connectivity is needed. localGetSupportingVertex iterates linearly though all vertices. -///on modern hardware, due to cache coherency this isn't that bad. Complex algorithms tend to trash the cash. -///(memory is much slower then the cpu) -ATTRIBUTE_ALIGNED16(class) btConvexHullShape : public btPolyhedralConvexShape -{ - btAlignedObjectArray m_points; - -public: - BT_DECLARE_ALIGNED_ALLOCATOR(); - - - ///this constructor optionally takes in a pointer to points. Each point is assumed to be 3 consecutive btScalar (x,y,z), the striding defines the number of bytes between each point, in memory. - ///It is easier to not pass any points in the constructor, and just add one point at a time, using addPoint. - ///btConvexHullShape make an internal copy of the points. - btConvexHullShape(const btScalar* points=0,int numPoints=0, int stride=sizeof(btPoint3)); - - void addPoint(const btPoint3& point); - - btPoint3* getPoints() - { - return &m_points[0]; - } - - int getNumPoints() - { - return m_points.size(); - } - - virtual btVector3 localGetSupportingVertex(const btVector3& vec)const; - virtual btVector3 localGetSupportingVertexWithoutMargin(const btVector3& vec)const; - virtual void batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const; - - - virtual int getShapeType()const { return CONVEX_HULL_SHAPE_PROXYTYPE; } - - //debugging - virtual const char* getName()const {return "Convex";} - - - virtual int getNumVertices() const; - virtual int getNumEdges() const; - virtual void getEdge(int i,btPoint3& pa,btPoint3& pb) const; - virtual void getVertex(int i,btPoint3& vtx) const; - virtual int getNumPlanes() const; - virtual void getPlane(btVector3& planeNormal,btPoint3& planeSupport,int i ) const; - virtual bool isInside(const btPoint3& pt,btScalar tolerance) const; - - - -}; - - -#endif //CONVEX_HULL_SHAPE_H - diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btConvexInternalShape.cpp b/extern/bullet2/src/BulletCollision/CollisionShapes/btConvexInternalShape.cpp deleted file mode 100644 index f828d28e18c..00000000000 --- a/extern/bullet2/src/BulletCollision/CollisionShapes/btConvexInternalShape.cpp +++ /dev/null @@ -1,78 +0,0 @@ -/* -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 "btConvexInternalShape.h" - - -btConvexInternalShape::btConvexInternalShape() -: m_localScaling(btScalar(1.),btScalar(1.),btScalar(1.)), -m_collisionMargin(CONVEX_DISTANCE_MARGIN) -{ -} - - -void btConvexInternalShape::setLocalScaling(const btVector3& scaling) -{ - m_localScaling = scaling; -} - - - -void btConvexInternalShape::getAabbSlow(const btTransform& trans,btVector3&minAabb,btVector3&maxAabb) const -{ - - btScalar margin = getMargin(); - for (int i=0;i<3;i++) - { - btVector3 vec(btScalar(0.),btScalar(0.),btScalar(0.)); - vec[i] = btScalar(1.); - - btVector3 sv = localGetSupportingVertex(vec*trans.getBasis()); - - btVector3 tmp = trans(sv); - maxAabb[i] = tmp[i]+margin; - vec[i] = btScalar(-1.); - tmp = trans(localGetSupportingVertex(vec*trans.getBasis())); - minAabb[i] = tmp[i]-margin; - } -}; - - -btVector3 btConvexInternalShape::localGetSupportingVertex(const btVector3& vec)const -{ -#ifndef __SPU__ - - btVector3 supVertex = localGetSupportingVertexWithoutMargin(vec); - - if ( getMargin()!=btScalar(0.) ) - { - btVector3 vecnorm = vec; - if (vecnorm .length2() < (SIMD_EPSILON*SIMD_EPSILON)) - { - vecnorm.setValue(btScalar(-1.),btScalar(-1.),btScalar(-1.)); - } - vecnorm.normalize(); - supVertex+= getMargin() * vecnorm; - } - return supVertex; - -#else - return btVector3(0,0,0); -#endif //__SPU__ - - } - - diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btConvexInternalShape.h b/extern/bullet2/src/BulletCollision/CollisionShapes/btConvexInternalShape.h deleted file mode 100644 index a03af873bd3..00000000000 --- a/extern/bullet2/src/BulletCollision/CollisionShapes/btConvexInternalShape.h +++ /dev/null @@ -1,99 +0,0 @@ - -#ifndef BT_CONVEX_INTERNAL_SHAPE_H -#define BT_CONVEX_INTERNAL_SHAPE_H - -#include "btConvexShape.h" - -///btConvexInternalShape carries some additional data, shared by most implementations -class btConvexInternalShape : public btConvexShape -{ - - protected: - - //local scaling. collisionMargin is not scaled ! - btVector3 m_localScaling; - - btVector3 m_implicitShapeDimensions; - - btScalar m_collisionMargin; - - btScalar m_padding[2]; - - - - -public: - - btConvexInternalShape(); - - virtual ~btConvexInternalShape() - { - - } - - - virtual btVector3 localGetSupportingVertex(const btVector3& vec)const; -#ifndef __SPU__ - virtual btVector3 localGetSupportingVertexWithoutMargin(const btVector3& vec) const= 0; - - //notice that the vectors should be unit length - virtual void batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const= 0; -#endif //#ifndef __SPU__ - - const btVector3& getImplicitShapeDimensions() const - { - return m_implicitShapeDimensions; - } - - ///getAabb's default implementation is brute force, expected derived classes to implement a fast dedicated version - void getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const - { - getAabbSlow(t,aabbMin,aabbMax); - } - - - - virtual void getAabbSlow(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const; - - - virtual void setLocalScaling(const btVector3& scaling); - virtual const btVector3& getLocalScaling() const - { - return m_localScaling; - } - - const btVector3& getLocalScalingNV() const - { - return m_localScaling; - } - - virtual void setMargin(btScalar margin) - { - m_collisionMargin = margin; - } - virtual btScalar getMargin() const - { - return m_collisionMargin; - } - - btScalar getMarginNV() const - { - return m_collisionMargin; - } - - virtual int getNumPreferredPenetrationDirections() const - { - return 0; - } - - virtual void getPreferredPenetrationDirection(int index, btVector3& penetrationVector) const - { - (void)penetrationVector; - (void)index; - btAssert(0); - } - -}; - - -#endif //BT_CONVEX_INTERNAL_SHAPE_H diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btConvexShape.cpp b/extern/bullet2/src/BulletCollision/CollisionShapes/btConvexShape.cpp deleted file mode 100644 index 7afcccf8b03..00000000000 --- a/extern/bullet2/src/BulletCollision/CollisionShapes/btConvexShape.cpp +++ /dev/null @@ -1,18 +0,0 @@ -/* -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 "btConvexShape.h" - - diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btConvexShape.h b/extern/bullet2/src/BulletCollision/CollisionShapes/btConvexShape.h deleted file mode 100644 index 6dfd288e05b..00000000000 --- a/extern/bullet2/src/BulletCollision/CollisionShapes/btConvexShape.h +++ /dev/null @@ -1,77 +0,0 @@ -/* -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 CONVEX_SHAPE_INTERFACE1 -#define CONVEX_SHAPE_INTERFACE1 - -#include "btCollisionShape.h" - -#include "LinearMath/btVector3.h" -#include "LinearMath/btTransform.h" -#include "LinearMath/btMatrix3x3.h" -#include "btCollisionMargin.h" -#include "LinearMath/btAlignedAllocator.h" - -//todo: get rid of this btConvexCastResult thing! -struct btConvexCastResult; -#define MAX_PREFERRED_PENETRATION_DIRECTIONS 10 - -/// btConvexShape is an abstract shape interface. -/// It describes general convex shapes using the localGetSupportingVertex interface -/// used in combination with GJK or btConvexCast -ATTRIBUTE_ALIGNED16(class) btConvexShape : public btCollisionShape -{ - - -public: - - BT_DECLARE_ALIGNED_ALLOCATOR(); - - virtual ~btConvexShape() - { - - } - - - virtual btVector3 localGetSupportingVertex(const btVector3& vec)const =0; -#ifndef __SPU__ - virtual btVector3 localGetSupportingVertexWithoutMargin(const btVector3& vec) const= 0; - - //notice that the vectors should be unit length - virtual void batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const= 0; -#endif //#ifndef __SPU__ - - - ///getAabb's default implementation is brute force, expected derived classes to implement a fast dedicated version - void getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const =0; - - virtual void getAabbSlow(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const =0; - - virtual void setLocalScaling(const btVector3& scaling) =0; - virtual const btVector3& getLocalScaling() const =0; - - virtual void setMargin(btScalar margin)=0; - - virtual btScalar getMargin() const=0; - - virtual int getNumPreferredPenetrationDirections() const=0; - - virtual void getPreferredPenetrationDirection(int index, btVector3& penetrationVector) const=0; - -}; - - - -#endif //CONVEX_SHAPE_INTERFACE1 diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btConvexTriangleMeshShape.cpp b/extern/bullet2/src/BulletCollision/CollisionShapes/btConvexTriangleMeshShape.cpp deleted file mode 100644 index 6941030b15f..00000000000 --- a/extern/bullet2/src/BulletCollision/CollisionShapes/btConvexTriangleMeshShape.cpp +++ /dev/null @@ -1,205 +0,0 @@ -/* -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 "btConvexTriangleMeshShape.h" -#include "BulletCollision/CollisionShapes/btCollisionMargin.h" - -#include "LinearMath/btQuaternion.h" -#include "BulletCollision/CollisionShapes/btStridingMeshInterface.h" - - -btConvexTriangleMeshShape ::btConvexTriangleMeshShape (btStridingMeshInterface* meshInterface) -:m_stridingMesh(meshInterface) -{ - recalcLocalAabb(); -} - - - - -///It's not nice to have all this virtual function overhead, so perhaps we can also gather the points once -///but then we are duplicating -class LocalSupportVertexCallback: public btInternalTriangleIndexCallback -{ - - btVector3 m_supportVertexLocal; -public: - - btScalar m_maxDot; - btVector3 m_supportVecLocal; - - LocalSupportVertexCallback(const btVector3& supportVecLocal) - : m_supportVertexLocal(btScalar(0.),btScalar(0.),btScalar(0.)), - m_maxDot(btScalar(-1e30)), - m_supportVecLocal(supportVecLocal) - { - } - - virtual void internalProcessTriangleIndex(btVector3* triangle,int partId,int triangleIndex) - { - (void)triangleIndex; - (void)partId; - - for (int i=0;i<3;i++) - { - btScalar dot = m_supportVecLocal.dot(triangle[i]); - if (dot > m_maxDot) - { - m_maxDot = dot; - m_supportVertexLocal = triangle[i]; - } - } - } - - btVector3 GetSupportVertexLocal() - { - return m_supportVertexLocal; - } - -}; - - - - - -btVector3 btConvexTriangleMeshShape::localGetSupportingVertexWithoutMargin(const btVector3& vec0)const -{ - btVector3 supVec(btScalar(0.),btScalar(0.),btScalar(0.)); - - btVector3 vec = vec0; - btScalar lenSqr = vec.length2(); - if (lenSqr < btScalar(0.0001)) - { - vec.setValue(1,0,0); - } else - { - btScalar rlen = btScalar(1.) / btSqrt(lenSqr ); - vec *= rlen; - } - - LocalSupportVertexCallback supportCallback(vec); - btVector3 aabbMax(btScalar(1e30),btScalar(1e30),btScalar(1e30)); - m_stridingMesh->InternalProcessAllTriangles(&supportCallback,-aabbMax,aabbMax); - supVec = supportCallback.GetSupportVertexLocal(); - - return supVec; -} - -void btConvexTriangleMeshShape::batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const -{ - //use 'w' component of supportVerticesOut? - { - for (int i=0;iInternalProcessAllTriangles(&supportCallback,-aabbMax,aabbMax); - supportVerticesOut[j] = supportCallback.GetSupportVertexLocal(); - } - -} - - - -btVector3 btConvexTriangleMeshShape::localGetSupportingVertex(const btVector3& vec)const -{ - btVector3 supVertex = localGetSupportingVertexWithoutMargin(vec); - - if ( getMargin()!=btScalar(0.) ) - { - btVector3 vecnorm = vec; - if (vecnorm .length2() < (SIMD_EPSILON*SIMD_EPSILON)) - { - vecnorm.setValue(btScalar(-1.),btScalar(-1.),btScalar(-1.)); - } - vecnorm.normalize(); - supVertex+= getMargin() * vecnorm; - } - return supVertex; -} - - - - - - - - - -//currently just for debugging (drawing), perhaps future support for algebraic continuous collision detection -//Please note that you can debug-draw btConvexTriangleMeshShape with the Raytracer Demo -int btConvexTriangleMeshShape::getNumVertices() const -{ - //cache this? - return 0; - -} - -int btConvexTriangleMeshShape::getNumEdges() const -{ - return 0; -} - -void btConvexTriangleMeshShape::getEdge(int ,btPoint3& ,btPoint3& ) const -{ - btAssert(0); -} - -void btConvexTriangleMeshShape::getVertex(int ,btPoint3& ) const -{ - btAssert(0); -} - -int btConvexTriangleMeshShape::getNumPlanes() const -{ - return 0; -} - -void btConvexTriangleMeshShape::getPlane(btVector3& ,btPoint3& ,int ) const -{ - btAssert(0); -} - -//not yet -bool btConvexTriangleMeshShape::isInside(const btPoint3& ,btScalar ) const -{ - btAssert(0); - return false; -} - - - -void btConvexTriangleMeshShape::setLocalScaling(const btVector3& scaling) -{ - m_stridingMesh->setScaling(scaling); - - recalcLocalAabb(); - -} - - -const btVector3& btConvexTriangleMeshShape::getLocalScaling() const -{ - return m_stridingMesh->getScaling(); -} diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btConvexTriangleMeshShape.h b/extern/bullet2/src/BulletCollision/CollisionShapes/btConvexTriangleMeshShape.h deleted file mode 100644 index f3daa58368f..00000000000 --- a/extern/bullet2/src/BulletCollision/CollisionShapes/btConvexTriangleMeshShape.h +++ /dev/null @@ -1,55 +0,0 @@ -#ifndef CONVEX_TRIANGLEMESH_SHAPE_H -#define CONVEX_TRIANGLEMESH_SHAPE_H - - -#include "btPolyhedralConvexShape.h" -#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" // for the types - - -/// btConvexTriangleMeshShape is a convex hull of a triangle mesh. If you just have a point cloud, you can use btConvexHullShape instead. -/// It uses the btStridingMeshInterface instead of a point cloud. This can avoid the duplication of the triangle mesh data. -class btConvexTriangleMeshShape : public btPolyhedralConvexShape -{ - - class btStridingMeshInterface* m_stridingMesh; - -public: - btConvexTriangleMeshShape(btStridingMeshInterface* meshInterface); - - class btStridingMeshInterface* getMeshInterface() - { - return m_stridingMesh; - } - const class btStridingMeshInterface* getMeshInterface() const - { - return m_stridingMesh; - } - - virtual btVector3 localGetSupportingVertex(const btVector3& vec)const; - virtual btVector3 localGetSupportingVertexWithoutMargin(const btVector3& vec)const; - virtual void batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const; - - virtual int getShapeType()const { return CONVEX_TRIANGLEMESH_SHAPE_PROXYTYPE; } - - //debugging - virtual const char* getName()const {return "ConvexTrimesh";} - - virtual int getNumVertices() const; - virtual int getNumEdges() const; - virtual void getEdge(int i,btPoint3& pa,btPoint3& pb) const; - virtual void getVertex(int i,btPoint3& vtx) const; - virtual int getNumPlanes() const; - virtual void getPlane(btVector3& planeNormal,btPoint3& planeSupport,int i ) const; - virtual bool isInside(const btPoint3& pt,btScalar tolerance) const; - - - virtual void setLocalScaling(const btVector3& scaling); - virtual const btVector3& getLocalScaling() const; - -}; - - - -#endif //CONVEX_TRIANGLEMESH_SHAPE_H - - diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btCylinderShape.cpp b/extern/bullet2/src/BulletCollision/CollisionShapes/btCylinderShape.cpp deleted file mode 100644 index 3afef1c7550..00000000000 --- a/extern/bullet2/src/BulletCollision/CollisionShapes/btCylinderShape.cpp +++ /dev/null @@ -1,206 +0,0 @@ -/* -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 "btCylinderShape.h" -#include "LinearMath/btPoint3.h" - -btCylinderShape::btCylinderShape (const btVector3& halfExtents) -:btBoxShape(halfExtents), -m_upAxis(1) -{ - recalcLocalAabb(); -} - - -btCylinderShapeX::btCylinderShapeX (const btVector3& halfExtents) -:btCylinderShape(halfExtents) -{ - m_upAxis = 0; - recalcLocalAabb(); -} - - -btCylinderShapeZ::btCylinderShapeZ (const btVector3& halfExtents) -:btCylinderShape(halfExtents) -{ - m_upAxis = 2; - recalcLocalAabb(); -} - -void btCylinderShape::getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const -{ - //skip the box 'getAabb' - btPolyhedralConvexShape::getAabb(t,aabbMin,aabbMax); -} - - -SIMD_FORCE_INLINE btVector3 CylinderLocalSupportX(const btVector3& halfExtents,const btVector3& v) -{ -const int cylinderUpAxis = 0; -const int XX = 1; -const int YY = 0; -const int ZZ = 2; - - //mapping depends on how cylinder local orientation is - // extents of the cylinder is: X,Y is for radius, and Z for height - - - btScalar radius = halfExtents[XX]; - btScalar halfHeight = halfExtents[cylinderUpAxis]; - - - btVector3 tmp; - btScalar d ; - - btScalar s = btSqrt(v[XX] * v[XX] + v[ZZ] * v[ZZ]); - if (s != btScalar(0.0)) - { - d = radius / s; - tmp[XX] = v[XX] * d; - tmp[YY] = v[YY] < 0.0 ? -halfHeight : halfHeight; - tmp[ZZ] = v[ZZ] * d; - return tmp; - } - else - { - tmp[XX] = radius; - tmp[YY] = v[YY] < 0.0 ? -halfHeight : halfHeight; - tmp[ZZ] = btScalar(0.0); - return tmp; - } - - -} - - - - - - -inline btVector3 CylinderLocalSupportY(const btVector3& halfExtents,const btVector3& v) -{ - -const int cylinderUpAxis = 1; -const int XX = 0; -const int YY = 1; -const int ZZ = 2; - - - btScalar radius = halfExtents[XX]; - btScalar halfHeight = halfExtents[cylinderUpAxis]; - - - btVector3 tmp; - btScalar d ; - - btScalar s = btSqrt(v[XX] * v[XX] + v[ZZ] * v[ZZ]); - if (s != btScalar(0.0)) - { - d = radius / s; - tmp[XX] = v[XX] * d; - tmp[YY] = v[YY] < 0.0 ? -halfHeight : halfHeight; - tmp[ZZ] = v[ZZ] * d; - return tmp; - } - else - { - tmp[XX] = radius; - tmp[YY] = v[YY] < 0.0 ? -halfHeight : halfHeight; - tmp[ZZ] = btScalar(0.0); - return tmp; - } - -} - -inline btVector3 CylinderLocalSupportZ(const btVector3& halfExtents,const btVector3& v) -{ -const int cylinderUpAxis = 2; -const int XX = 0; -const int YY = 2; -const int ZZ = 1; - - //mapping depends on how cylinder local orientation is - // extents of the cylinder is: X,Y is for radius, and Z for height - - - btScalar radius = halfExtents[XX]; - btScalar halfHeight = halfExtents[cylinderUpAxis]; - - - btVector3 tmp; - btScalar d ; - - btScalar s = btSqrt(v[XX] * v[XX] + v[ZZ] * v[ZZ]); - if (s != btScalar(0.0)) - { - d = radius / s; - tmp[XX] = v[XX] * d; - tmp[YY] = v[YY] < 0.0 ? -halfHeight : halfHeight; - tmp[ZZ] = v[ZZ] * d; - return tmp; - } - else - { - tmp[XX] = radius; - tmp[YY] = v[YY] < 0.0 ? -halfHeight : halfHeight; - tmp[ZZ] = btScalar(0.0); - return tmp; - } - - -} - -btVector3 btCylinderShapeX::localGetSupportingVertexWithoutMargin(const btVector3& vec)const -{ - return CylinderLocalSupportX(getHalfExtentsWithoutMargin(),vec); -} - - -btVector3 btCylinderShapeZ::localGetSupportingVertexWithoutMargin(const btVector3& vec)const -{ - return CylinderLocalSupportZ(getHalfExtentsWithoutMargin(),vec); -} -btVector3 btCylinderShape::localGetSupportingVertexWithoutMargin(const btVector3& vec)const -{ - return CylinderLocalSupportY(getHalfExtentsWithoutMargin(),vec); -} - -void btCylinderShape::batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const -{ - for (int i=0;i=0); - btAssert(y>=0); - btAssert(xstartX) - startX = quantizedAabbMin[1]; - if (quantizedAabbMax[1]startJ) - startJ = quantizedAabbMin[2]; - if (quantizedAabbMax[2]startX) - startX = quantizedAabbMin[0]; - if (quantizedAabbMax[0]startJ) - startJ = quantizedAabbMin[2]; - if (quantizedAabbMax[2]startX) - startX = quantizedAabbMin[0]; - if (quantizedAabbMax[0]startJ) - startJ = quantizedAabbMin[1]; - if (quantizedAabbMax[1]processTriangle(vertices,x,j); - //second triangle - getVertex(x,j,vertices[0]); - getVertex(x+1,j+1,vertices[1]); - getVertex(x,j+1,vertices[2]); - callback->processTriangle(vertices,x,j); - } else - { - //first triangle - getVertex(x,j,vertices[0]); - getVertex(x,j+1,vertices[1]); - getVertex(x+1,j,vertices[2]); - callback->processTriangle(vertices,x,j); - //second triangle - getVertex(x+1,j,vertices[0]); - getVertex(x,j+1,vertices[1]); - getVertex(x+1,j+1,vertices[2]); - callback->processTriangle(vertices,x,j); - } - } - } - - - -} - -void btHeightfieldTerrainShape::calculateLocalInertia(btScalar ,btVector3& inertia) const -{ - //moving concave objects not supported - - inertia.setValue(btScalar(0.),btScalar(0.),btScalar(0.)); -} - -void btHeightfieldTerrainShape::setLocalScaling(const btVector3& scaling) -{ - m_localScaling = scaling; -} -const btVector3& btHeightfieldTerrainShape::getLocalScaling() const -{ - return m_localScaling; -} diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btHeightfieldTerrainShape.h b/extern/bullet2/src/BulletCollision/CollisionShapes/btHeightfieldTerrainShape.h deleted file mode 100644 index 8dba7b3d5fe..00000000000 --- a/extern/bullet2/src/BulletCollision/CollisionShapes/btHeightfieldTerrainShape.h +++ /dev/null @@ -1,88 +0,0 @@ -/* -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 HEIGHTFIELD_TERRAIN_SHAPE_H -#define HEIGHTFIELD_TERRAIN_SHAPE_H - -#include "btConcaveShape.h" - -///btHeightfieldTerrainShape simulates a 2D heightfield terrain -class btHeightfieldTerrainShape : public btConcaveShape -{ -protected: - btVector3 m_localAabbMin; - btVector3 m_localAabbMax; - - ///terrain data - int m_width; - int m_length; - btScalar m_maxHeight; - union - { - unsigned char* m_heightfieldDataUnsignedChar; - btScalar* m_heightfieldDataFloat; - void* m_heightfieldDataUnknown; - }; - - bool m_useFloatData; - bool m_flipQuadEdges; - bool m_useDiamondSubdivision; - - int m_upAxis; - - btVector3 m_localScaling; - - virtual btScalar getHeightFieldValue(int x,int y) const; - void quantizeWithClamp(int* out, const btVector3& point) const; - void getVertex(int x,int y,btVector3& vertex) const; - - inline bool testQuantizedAabbAgainstQuantizedAabb(int* aabbMin1, int* aabbMax1,const int* aabbMin2,const int* aabbMax2) const - { - bool overlap = true; - overlap = (aabbMin1[0] > aabbMax2[0] || aabbMax1[0] < aabbMin2[0]) ? false : overlap; - overlap = (aabbMin1[2] > aabbMax2[2] || aabbMax1[2] < aabbMin2[2]) ? false : overlap; - overlap = (aabbMin1[1] > aabbMax2[1] || aabbMax1[1] < aabbMin2[1]) ? false : overlap; - return overlap; - } - -public: - btHeightfieldTerrainShape(int width,int height,void* heightfieldData, btScalar maxHeight,int upAxis,bool useFloatData,bool flipQuadEdges); - - virtual ~btHeightfieldTerrainShape(); - - - void setUseDiamondSubdivision(bool useDiamondSubdivision=true) { m_useDiamondSubdivision = useDiamondSubdivision;} - - virtual int getShapeType() const - { - return TERRAIN_SHAPE_PROXYTYPE; - } - - virtual void getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const; - - virtual void processAllTriangles(btTriangleCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const; - - virtual void calculateLocalInertia(btScalar mass,btVector3& inertia) const; - - virtual void setLocalScaling(const btVector3& scaling); - - virtual const btVector3& getLocalScaling() const; - - //debugging - virtual const char* getName()const {return "HEIGHTFIELD";} - -}; - -#endif //HEIGHTFIELD_TERRAIN_SHAPE_H diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btMinkowskiSumShape.cpp b/extern/bullet2/src/BulletCollision/CollisionShapes/btMinkowskiSumShape.cpp deleted file mode 100644 index 7f7f2822189..00000000000 --- a/extern/bullet2/src/BulletCollision/CollisionShapes/btMinkowskiSumShape.cpp +++ /dev/null @@ -1,57 +0,0 @@ -/* -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 "btMinkowskiSumShape.h" - - -btMinkowskiSumShape::btMinkowskiSumShape(const btConvexShape* shapeA,const btConvexShape* shapeB) -:m_shapeA(shapeA), -m_shapeB(shapeB) -{ - m_transA.setIdentity(); - m_transB.setIdentity(); -} - -btVector3 btMinkowskiSumShape::localGetSupportingVertexWithoutMargin(const btVector3& vec)const -{ - btVector3 supVertexA = m_transA(m_shapeA->localGetSupportingVertexWithoutMargin(vec*m_transA.getBasis())); - btVector3 supVertexB = m_transB(m_shapeB->localGetSupportingVertexWithoutMargin(vec*m_transB.getBasis())); - return supVertexA + supVertexB; -} - -void btMinkowskiSumShape::batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const -{ - //todo: could make recursive use of batching. probably this shape is not used frequently. - for (int i=0;igetMargin() + m_shapeB->getMargin(); -} - - -void btMinkowskiSumShape::calculateLocalInertia(btScalar mass,btVector3& inertia) const -{ - (void)mass; - btAssert(0); - inertia.setValue(0,0,0); -} diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btMinkowskiSumShape.h b/extern/bullet2/src/BulletCollision/CollisionShapes/btMinkowskiSumShape.h deleted file mode 100644 index 484e317e6fc..00000000000 --- a/extern/bullet2/src/BulletCollision/CollisionShapes/btMinkowskiSumShape.h +++ /dev/null @@ -1,62 +0,0 @@ -/* -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 MINKOWSKI_SUM_SHAPE_H -#define MINKOWSKI_SUM_SHAPE_H - -#include "btConvexInternalShape.h" -#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" // for the types - -/// btMinkowskiSumShape represents implicit (getSupportingVertex) based minkowski sum of two convex implicit shapes. -class btMinkowskiSumShape : public btConvexInternalShape -{ - - btTransform m_transA; - btTransform m_transB; - const btConvexShape* m_shapeA; - const btConvexShape* m_shapeB; - -public: - - btMinkowskiSumShape(const btConvexShape* shapeA,const btConvexShape* shapeB); - - virtual btVector3 localGetSupportingVertexWithoutMargin(const btVector3& vec)const; - - virtual void batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const; - - - virtual void calculateLocalInertia(btScalar mass,btVector3& inertia) const; - - void setTransformA(const btTransform& transA) { m_transA = transA;} - void setTransformB(const btTransform& transB) { m_transB = transB;} - - const btTransform& getTransformA()const { return m_transA;} - const btTransform& GetTransformB()const { return m_transB;} - - - virtual int getShapeType() const { return MINKOWSKI_SUM_SHAPE_PROXYTYPE; } - - virtual btScalar getMargin() const; - - const btConvexShape* getShapeA() const { return m_shapeA;} - const btConvexShape* getShapeB() const { return m_shapeB;} - - virtual const char* getName()const - { - return "MinkowskiSum"; - } -}; - -#endif //MINKOWSKI_SUM_SHAPE_H diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btMultiSphereShape.cpp b/extern/bullet2/src/BulletCollision/CollisionShapes/btMultiSphereShape.cpp deleted file mode 100644 index a8ce8622f9f..00000000000 --- a/extern/bullet2/src/BulletCollision/CollisionShapes/btMultiSphereShape.cpp +++ /dev/null @@ -1,148 +0,0 @@ -/* -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 "btMultiSphereShape.h" -#include "BulletCollision/CollisionShapes/btCollisionMargin.h" -#include "LinearMath/btQuaternion.h" - -btMultiSphereShape::btMultiSphereShape (const btVector3& inertiaHalfExtents,const btVector3* positions,const btScalar* radi,int numSpheres) -:m_inertiaHalfExtents(inertiaHalfExtents) -{ - btScalar startMargin = btScalar(1e30); - - m_numSpheres = numSpheres; - for (int i=0;i maxDot) - { - maxDot = newDot; - supVec = vtx; - } - } - - return supVec; - -} - - void btMultiSphereShape::batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const -{ - - for (int j=0;j maxDot) - { - maxDot = newDot; - supportVerticesOut[j] = vtx; - } - } - } -} - - - - - - - - -void btMultiSphereShape::calculateLocalInertia(btScalar mass,btVector3& inertia) const -{ - //as an approximation, take the inertia of the box that bounds the spheres - - btTransform ident; - ident.setIdentity(); -// btVector3 aabbMin,aabbMax; - -// getAabb(ident,aabbMin,aabbMax); - - btVector3 halfExtents = m_inertiaHalfExtents;//(aabbMax - aabbMin)* btScalar(0.5); - - btScalar margin = CONVEX_DISTANCE_MARGIN; - - btScalar lx=btScalar(2.)*(halfExtents[0]+margin); - btScalar ly=btScalar(2.)*(halfExtents[1]+margin); - btScalar lz=btScalar(2.)*(halfExtents[2]+margin); - const btScalar x2 = lx*lx; - const btScalar y2 = ly*ly; - const btScalar z2 = lz*lz; - const btScalar scaledmass = mass * btScalar(.08333333); - - inertia[0] = scaledmass * (y2+z2); - inertia[1] = scaledmass * (x2+z2); - inertia[2] = scaledmass * (x2+y2); - -} - - - diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btMultiSphereShape.h b/extern/bullet2/src/BulletCollision/CollisionShapes/btMultiSphereShape.h deleted file mode 100644 index 7db54e7a23c..00000000000 --- a/extern/bullet2/src/BulletCollision/CollisionShapes/btMultiSphereShape.h +++ /dev/null @@ -1,74 +0,0 @@ -/* -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 MULTI_SPHERE_MINKOWSKI_H -#define MULTI_SPHERE_MINKOWSKI_H - -#include "btConvexInternalShape.h" -#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" // for the types - -#define MAX_NUM_SPHERES 5 - -///btMultiSphereShape represents implicit convex hull of a collection of spheres (using getSupportingVertex) -class btMultiSphereShape : public btConvexInternalShape - -{ - - btVector3 m_localPositions[MAX_NUM_SPHERES]; - btScalar m_radi[MAX_NUM_SPHERES]; - btVector3 m_inertiaHalfExtents; - - int m_numSpheres; - - - - -public: - btMultiSphereShape (const btVector3& inertiaHalfExtents,const btVector3* positions,const btScalar* radi,int numSpheres); - - ///CollisionShape Interface - virtual void calculateLocalInertia(btScalar mass,btVector3& inertia) const; - - /// btConvexShape Interface - virtual btVector3 localGetSupportingVertexWithoutMargin(const btVector3& vec)const; - - virtual void batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const; - - int getSphereCount() const - { - return m_numSpheres; - } - - const btVector3& getSpherePosition(int index) const - { - return m_localPositions[index]; - } - - btScalar getSphereRadius(int index) const - { - return m_radi[index]; - } - - virtual int getShapeType() const { return MULTI_SPHERE_SHAPE_PROXYTYPE; } - - virtual const char* getName()const - { - return "MultiSphere"; - } - -}; - - -#endif //MULTI_SPHERE_MINKOWSKI_H diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btOptimizedBvh.cpp b/extern/bullet2/src/BulletCollision/CollisionShapes/btOptimizedBvh.cpp deleted file mode 100644 index e80469f45cf..00000000000 --- a/extern/bullet2/src/BulletCollision/CollisionShapes/btOptimizedBvh.cpp +++ /dev/null @@ -1,1181 +0,0 @@ -/* -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 "btOptimizedBvh.h" -#include "btStridingMeshInterface.h" -#include "LinearMath/btAabbUtil2.h" -#include "LinearMath/btIDebugDraw.h" - - -btOptimizedBvh::btOptimizedBvh() : m_useQuantization(false), - //m_traversalMode(TRAVERSAL_STACKLESS_CACHE_FRIENDLY) - m_traversalMode(TRAVERSAL_STACKLESS) - //m_traversalMode(TRAVERSAL_RECURSIVE) - ,m_subtreeHeaderCount(0) //PCK: add this line -{ - -} - - -void btOptimizedBvh::build(btStridingMeshInterface* triangles, bool useQuantizedAabbCompression, const btVector3& bvhAabbMin, const btVector3& bvhAabbMax) -{ - m_useQuantization = useQuantizedAabbCompression; - - - // NodeArray triangleNodes; - - struct NodeTriangleCallback : public btInternalTriangleIndexCallback - { - - NodeArray& m_triangleNodes; - - NodeTriangleCallback& operator=(NodeTriangleCallback& other) - { - m_triangleNodes = other.m_triangleNodes; - return *this; - } - - NodeTriangleCallback(NodeArray& triangleNodes) - :m_triangleNodes(triangleNodes) - { - } - - virtual void internalProcessTriangleIndex(btVector3* triangle,int partId,int triangleIndex) - { - btOptimizedBvhNode node; - btVector3 aabbMin,aabbMax; - aabbMin.setValue(btScalar(1e30),btScalar(1e30),btScalar(1e30)); - aabbMax.setValue(btScalar(-1e30),btScalar(-1e30),btScalar(-1e30)); - aabbMin.setMin(triangle[0]); - aabbMax.setMax(triangle[0]); - aabbMin.setMin(triangle[1]); - aabbMax.setMax(triangle[1]); - aabbMin.setMin(triangle[2]); - aabbMax.setMax(triangle[2]); - - //with quantization? - node.m_aabbMinOrg = aabbMin; - node.m_aabbMaxOrg = aabbMax; - - node.m_escapeIndex = -1; - - //for child nodes - node.m_subPart = partId; - node.m_triangleIndex = triangleIndex; - m_triangleNodes.push_back(node); - } - }; - struct QuantizedNodeTriangleCallback : public btInternalTriangleIndexCallback - { - QuantizedNodeArray& m_triangleNodes; - const btOptimizedBvh* m_optimizedTree; // for quantization - - QuantizedNodeTriangleCallback& operator=(QuantizedNodeTriangleCallback& other) - { - m_triangleNodes = other.m_triangleNodes; - m_optimizedTree = other.m_optimizedTree; - return *this; - } - - QuantizedNodeTriangleCallback(QuantizedNodeArray& triangleNodes,const btOptimizedBvh* tree) - :m_triangleNodes(triangleNodes),m_optimizedTree(tree) - { - } - - virtual void internalProcessTriangleIndex(btVector3* triangle,int partId,int triangleIndex) - { - btAssert(partId==0); - //negative indices are reserved for escapeIndex - btAssert(triangleIndex>=0); - - btQuantizedBvhNode node; - btVector3 aabbMin,aabbMax; - aabbMin.setValue(btScalar(1e30),btScalar(1e30),btScalar(1e30)); - aabbMax.setValue(btScalar(-1e30),btScalar(-1e30),btScalar(-1e30)); - aabbMin.setMin(triangle[0]); - aabbMax.setMax(triangle[0]); - aabbMin.setMin(triangle[1]); - aabbMax.setMax(triangle[1]); - aabbMin.setMin(triangle[2]); - aabbMax.setMax(triangle[2]); - - //PCK: add these checks for zero dimensions of aabb - const btScalar MIN_AABB_DIMENSION = btScalar(0.002); - const btScalar MIN_AABB_HALF_DIMENSION = btScalar(0.001); - if (aabbMax.x() - aabbMin.x() < MIN_AABB_DIMENSION) - { - aabbMax.setX(aabbMax.x() + MIN_AABB_HALF_DIMENSION); - aabbMin.setX(aabbMin.x() - MIN_AABB_HALF_DIMENSION); - } - if (aabbMax.y() - aabbMin.y() < MIN_AABB_DIMENSION) - { - aabbMax.setY(aabbMax.y() + MIN_AABB_HALF_DIMENSION); - aabbMin.setY(aabbMin.y() - MIN_AABB_HALF_DIMENSION); - } - if (aabbMax.z() - aabbMin.z() < MIN_AABB_DIMENSION) - { - aabbMax.setZ(aabbMax.z() + MIN_AABB_HALF_DIMENSION); - aabbMin.setZ(aabbMin.z() - MIN_AABB_HALF_DIMENSION); - } - - m_optimizedTree->quantizeWithClamp(&node.m_quantizedAabbMin[0],aabbMin); - m_optimizedTree->quantizeWithClamp(&node.m_quantizedAabbMax[0],aabbMax); - - node.m_escapeIndexOrTriangleIndex = triangleIndex; - - m_triangleNodes.push_back(node); - } - }; - - - - int numLeafNodes = 0; - - - if (m_useQuantization) - { - - //initialize quantization values - setQuantizationValues(bvhAabbMin,bvhAabbMax); - - QuantizedNodeTriangleCallback callback(m_quantizedLeafNodes,this); - - - triangles->InternalProcessAllTriangles(&callback,m_bvhAabbMin,m_bvhAabbMax); - - //now we have an array of leafnodes in m_leafNodes - numLeafNodes = m_quantizedLeafNodes.size(); - - - m_quantizedContiguousNodes.resize(2*numLeafNodes); - - - } else - { - NodeTriangleCallback callback(m_leafNodes); - - btVector3 aabbMin(btScalar(-1e30),btScalar(-1e30),btScalar(-1e30)); - btVector3 aabbMax(btScalar(1e30),btScalar(1e30),btScalar(1e30)); - - triangles->InternalProcessAllTriangles(&callback,aabbMin,aabbMax); - - //now we have an array of leafnodes in m_leafNodes - numLeafNodes = m_leafNodes.size(); - - m_contiguousNodes.resize(2*numLeafNodes); - } - - m_curNodeIndex = 0; - - buildTree(0,numLeafNodes); - - ///if the entire tree is small then subtree size, we need to create a header info for the tree - if(m_useQuantization && !m_SubtreeHeaders.size()) - { - btBvhSubtreeInfo& subtree = m_SubtreeHeaders.expand(); - subtree.setAabbFromQuantizeNode(m_quantizedContiguousNodes[0]); - subtree.m_rootNodeIndex = 0; - subtree.m_subtreeSize = m_quantizedContiguousNodes[0].isLeafNode() ? 1 : m_quantizedContiguousNodes[0].getEscapeIndex(); - } - - //PCK: update the copy of the size - m_subtreeHeaderCount = m_SubtreeHeaders.size(); - - //PCK: clear m_quantizedLeafNodes and m_leafNodes, they are temporary - m_quantizedLeafNodes.clear(); - m_leafNodes.clear(); -} - - - -void btOptimizedBvh::refitPartial(btStridingMeshInterface* meshInterface,const btVector3& aabbMin,const btVector3& aabbMax) -{ - //incrementally initialize quantization values - btAssert(m_useQuantization); - - btAssert(aabbMin.getX() > m_bvhAabbMin.getX()); - btAssert(aabbMin.getY() > m_bvhAabbMin.getY()); - btAssert(aabbMin.getZ() > m_bvhAabbMin.getZ()); - - btAssert(aabbMax.getX() < m_bvhAabbMax.getX()); - btAssert(aabbMax.getY() < m_bvhAabbMax.getY()); - btAssert(aabbMax.getZ() < m_bvhAabbMax.getZ()); - - ///we should update all quantization values, using updateBvhNodes(meshInterface); - ///but we only update chunks that overlap the given aabb - - unsigned short quantizedQueryAabbMin[3]; - unsigned short quantizedQueryAabbMax[3]; - - quantizeWithClamp(&quantizedQueryAabbMin[0],aabbMin); - quantizeWithClamp(&quantizedQueryAabbMax[0],aabbMax); - - int i; - for (i=0;im_SubtreeHeaders.size();i++) - { - btBvhSubtreeInfo& subtree = m_SubtreeHeaders[i]; - - //PCK: unsigned instead of bool - unsigned overlap = testQuantizedAabbAgainstQuantizedAabb(quantizedQueryAabbMin,quantizedQueryAabbMax,subtree.m_quantizedAabbMin,subtree.m_quantizedAabbMax); - if (overlap != 0) - { - updateBvhNodes(meshInterface,subtree.m_rootNodeIndex,subtree.m_rootNodeIndex+subtree.m_subtreeSize,i); - - subtree.setAabbFromQuantizeNode(m_quantizedContiguousNodes[subtree.m_rootNodeIndex]); - } - } - -} - -///just for debugging, to visualize the individual patches/subtrees -#ifdef DEBUG_PATCH_COLORS -btVector3 color[4]= -{ - btVector3(255,0,0), - btVector3(0,255,0), - btVector3(0,0,255), - btVector3(0,255,255) -}; -#endif //DEBUG_PATCH_COLORS - - -void btOptimizedBvh::updateBvhNodes(btStridingMeshInterface* meshInterface,int firstNode,int endNode,int index) -{ - (void)index; - - btAssert(m_useQuantization); - - int nodeSubPart=0; - - //get access info to trianglemesh data - const unsigned char *vertexbase; - int numverts; - PHY_ScalarType type; - int stride; - const unsigned char *indexbase; - int indexstride; - int numfaces; - PHY_ScalarType indicestype; - meshInterface->getLockedReadOnlyVertexIndexBase(&vertexbase,numverts, type,stride,&indexbase,indexstride,numfaces,indicestype,nodeSubPart); - - btVector3 triangleVerts[3]; - btVector3 aabbMin,aabbMax; - const btVector3& meshScaling = meshInterface->getScaling(); - - int i; - for (i=endNode-1;i>=firstNode;i--) - { - - - btQuantizedBvhNode& curNode = m_quantizedContiguousNodes[i]; - if (curNode.isLeafNode()) - { - //recalc aabb from triangle data - int nodeTriangleIndex = curNode.getTriangleIndex(); - //triangles->getLockedReadOnlyVertexIndexBase(vertexBase,numVerts, - - int* gfxbase = (int*)(indexbase+nodeTriangleIndex*indexstride); - - - for (int j=2;j>=0;j--) - { - - int graphicsindex = gfxbase[j]; - btScalar* graphicsbase = (btScalar*)(vertexbase+graphicsindex*stride); -#ifdef DEBUG_PATCH_COLORS - btVector3 mycolor = color[index&3]; - graphicsbase[8] = mycolor.getX(); - graphicsbase[9] = mycolor.getY(); - graphicsbase[10] = mycolor.getZ(); -#endif //DEBUG_PATCH_COLORS - - - triangleVerts[j] = btVector3( - graphicsbase[0]*meshScaling.getX(), - graphicsbase[1]*meshScaling.getY(), - graphicsbase[2]*meshScaling.getZ()); - } - - - - aabbMin.setValue(btScalar(1e30),btScalar(1e30),btScalar(1e30)); - aabbMax.setValue(btScalar(-1e30),btScalar(-1e30),btScalar(-1e30)); - aabbMin.setMin(triangleVerts[0]); - aabbMax.setMax(triangleVerts[0]); - aabbMin.setMin(triangleVerts[1]); - aabbMax.setMax(triangleVerts[1]); - aabbMin.setMin(triangleVerts[2]); - aabbMax.setMax(triangleVerts[2]); - - quantizeWithClamp(&curNode.m_quantizedAabbMin[0],aabbMin); - quantizeWithClamp(&curNode.m_quantizedAabbMax[0],aabbMax); - - } else - { - //combine aabb from both children - - btQuantizedBvhNode* leftChildNode = &m_quantizedContiguousNodes[i+1]; - - btQuantizedBvhNode* rightChildNode = leftChildNode->isLeafNode() ? &m_quantizedContiguousNodes[i+2] : - &m_quantizedContiguousNodes[i+1+leftChildNode->getEscapeIndex()]; - - - { - for (int i=0;i<3;i++) - { - curNode.m_quantizedAabbMin[i] = leftChildNode->m_quantizedAabbMin[i]; - if (curNode.m_quantizedAabbMin[i]>rightChildNode->m_quantizedAabbMin[i]) - curNode.m_quantizedAabbMin[i]=rightChildNode->m_quantizedAabbMin[i]; - - curNode.m_quantizedAabbMax[i] = leftChildNode->m_quantizedAabbMax[i]; - if (curNode.m_quantizedAabbMax[i] < rightChildNode->m_quantizedAabbMax[i]) - curNode.m_quantizedAabbMax[i] = rightChildNode->m_quantizedAabbMax[i]; - } - } - } - - } - - meshInterface->unLockReadOnlyVertexBase(nodeSubPart); - - -} - -void btOptimizedBvh::setQuantizationValues(const btVector3& bvhAabbMin,const btVector3& bvhAabbMax,btScalar quantizationMargin) -{ - //enlarge the AABB to avoid division by zero when initializing the quantization values - btVector3 clampValue(quantizationMargin,quantizationMargin,quantizationMargin); - m_bvhAabbMin = bvhAabbMin - clampValue; - m_bvhAabbMax = bvhAabbMax + clampValue; - btVector3 aabbSize = m_bvhAabbMax - m_bvhAabbMin; - m_bvhQuantization = btVector3(btScalar(65535.0),btScalar(65535.0),btScalar(65535.0)) / aabbSize; -} - - -void btOptimizedBvh::refit(btStridingMeshInterface* meshInterface) -{ - if (m_useQuantization) - { - //calculate new aabb - btVector3 aabbMin,aabbMax; - meshInterface->calculateAabbBruteForce(aabbMin,aabbMax); - - setQuantizationValues(aabbMin,aabbMax); - - updateBvhNodes(meshInterface,0,m_curNodeIndex,0); - - ///now update all subtree headers - - int i; - for (i=0;i gMaxStackDepth) - gMaxStackDepth = gStackDepth; -#endif //DEBUG_TREE_BUILDING - - - int splitAxis, splitIndex, i; - int numIndices =endIndex-startIndex; - int curIndex = m_curNodeIndex; - - assert(numIndices>0); - - if (numIndices==1) - { -#ifdef DEBUG_TREE_BUILDING - gStackDepth--; -#endif //DEBUG_TREE_BUILDING - - assignInternalNodeFromLeafNode(m_curNodeIndex,startIndex); - - m_curNodeIndex++; - return; - } - //calculate Best Splitting Axis and where to split it. Sort the incoming 'leafNodes' array within range 'startIndex/endIndex'. - - splitAxis = calcSplittingAxis(startIndex,endIndex); - - splitIndex = sortAndCalcSplittingIndex(startIndex,endIndex,splitAxis); - - int internalNodeIndex = m_curNodeIndex; - - setInternalNodeAabbMax(m_curNodeIndex,btVector3(btScalar(-1e30),btScalar(-1e30),btScalar(-1e30))); - setInternalNodeAabbMin(m_curNodeIndex,btVector3(btScalar(1e30),btScalar(1e30),btScalar(1e30))); - - for (i=startIndex;im_escapeIndex; - - int leftChildNodexIndex = m_curNodeIndex; - - //build left child tree - buildTree(startIndex,splitIndex); - - int rightChildNodexIndex = m_curNodeIndex; - //build right child tree - buildTree(splitIndex,endIndex); - -#ifdef DEBUG_TREE_BUILDING - gStackDepth--; -#endif //DEBUG_TREE_BUILDING - - int escapeIndex = m_curNodeIndex - curIndex; - - if (m_useQuantization) - { - //escapeIndex is the number of nodes of this subtree - const int sizeQuantizedNode =sizeof(btQuantizedBvhNode); - const int treeSizeInBytes = escapeIndex * sizeQuantizedNode; - if (treeSizeInBytes > MAX_SUBTREE_SIZE_IN_BYTES) - { - updateSubtreeHeaders(leftChildNodexIndex,rightChildNodexIndex); - } - } - - setInternalNodeEscapeIndex(internalNodeIndex,escapeIndex); - -} - -void btOptimizedBvh::updateSubtreeHeaders(int leftChildNodexIndex,int rightChildNodexIndex) -{ - btAssert(m_useQuantization); - - btQuantizedBvhNode& leftChildNode = m_quantizedContiguousNodes[leftChildNodexIndex]; - int leftSubTreeSize = leftChildNode.isLeafNode() ? 1 : leftChildNode.getEscapeIndex(); - int leftSubTreeSizeInBytes = leftSubTreeSize * sizeof(btQuantizedBvhNode); - - btQuantizedBvhNode& rightChildNode = m_quantizedContiguousNodes[rightChildNodexIndex]; - int rightSubTreeSize = rightChildNode.isLeafNode() ? 1 : rightChildNode.getEscapeIndex(); - int rightSubTreeSizeInBytes = rightSubTreeSize * sizeof(btQuantizedBvhNode); - - if(leftSubTreeSizeInBytes <= MAX_SUBTREE_SIZE_IN_BYTES) - { - btBvhSubtreeInfo& subtree = m_SubtreeHeaders.expand(); - subtree.setAabbFromQuantizeNode(leftChildNode); - subtree.m_rootNodeIndex = leftChildNodexIndex; - subtree.m_subtreeSize = leftSubTreeSize; - } - - if(rightSubTreeSizeInBytes <= MAX_SUBTREE_SIZE_IN_BYTES) - { - btBvhSubtreeInfo& subtree = m_SubtreeHeaders.expand(); - subtree.setAabbFromQuantizeNode(rightChildNode); - subtree.m_rootNodeIndex = rightChildNodexIndex; - subtree.m_subtreeSize = rightSubTreeSize; - } - - //PCK: update the copy of the size - m_subtreeHeaderCount = m_SubtreeHeaders.size(); -} - - -int btOptimizedBvh::sortAndCalcSplittingIndex(int startIndex,int endIndex,int splitAxis) -{ - int i; - int splitIndex =startIndex; - int numIndices = endIndex - startIndex; - btScalar splitValue; - - btVector3 means(btScalar(0.),btScalar(0.),btScalar(0.)); - for (i=startIndex;i splitValue) - { - //swap - swapLeafNodes(i,splitIndex); - splitIndex++; - } - } - - //if the splitIndex causes unbalanced trees, fix this by using the center in between startIndex and endIndex - //otherwise the tree-building might fail due to stack-overflows in certain cases. - //unbalanced1 is unsafe: it can cause stack overflows - //bool unbalanced1 = ((splitIndex==startIndex) || (splitIndex == (endIndex-1))); - - //unbalanced2 should work too: always use center (perfect balanced trees) - //bool unbalanced2 = true; - - //this should be safe too: - int rangeBalancedIndices = numIndices/3; - bool unbalanced = ((splitIndex<=(startIndex+rangeBalancedIndices)) || (splitIndex >=(endIndex-1-rangeBalancedIndices))); - - if (unbalanced) - { - splitIndex = startIndex+ (numIndices>>1); - } - - bool unbal = (splitIndex==startIndex) || (splitIndex == (endIndex)); - btAssert(!unbal); - - return splitIndex; -} - - -int btOptimizedBvh::calcSplittingAxis(int startIndex,int endIndex) -{ - int i; - - btVector3 means(btScalar(0.),btScalar(0.),btScalar(0.)); - btVector3 variance(btScalar(0.),btScalar(0.),btScalar(0.)); - int numIndices = endIndex-startIndex; - - for (i=startIndex;im_aabbMinOrg,rootNode->m_aabbMaxOrg); - isLeafNode = rootNode->m_escapeIndex == -1; - - //PCK: unsigned instead of bool - if (isLeafNode && (aabbOverlap != 0)) - { - nodeCallback->processNode(rootNode->m_subPart,rootNode->m_triangleIndex); - } - - //PCK: unsigned instead of bool - if ((aabbOverlap != 0) || isLeafNode) - { - rootNode++; - curIndex++; - } else - { - escapeIndex = rootNode->m_escapeIndex; - rootNode += escapeIndex; - curIndex += escapeIndex; - } - } - if (maxIterations < walkIterations) - maxIterations = walkIterations; - -} - -/* -///this was the original recursive traversal, before we optimized towards stackless traversal -void btOptimizedBvh::walkTree(btOptimizedBvhNode* rootNode,btNodeOverlapCallback* nodeCallback,const btVector3& aabbMin,const btVector3& aabbMax) const -{ - bool isLeafNode, aabbOverlap = TestAabbAgainstAabb2(aabbMin,aabbMax,rootNode->m_aabbMin,rootNode->m_aabbMax); - if (aabbOverlap) - { - isLeafNode = (!rootNode->m_leftChild && !rootNode->m_rightChild); - if (isLeafNode) - { - nodeCallback->processNode(rootNode); - } else - { - walkTree(rootNode->m_leftChild,nodeCallback,aabbMin,aabbMax); - walkTree(rootNode->m_rightChild,nodeCallback,aabbMin,aabbMax); - } - } - -} -*/ - -void btOptimizedBvh::walkRecursiveQuantizedTreeAgainstQueryAabb(const btQuantizedBvhNode* currentNode,btNodeOverlapCallback* nodeCallback,unsigned short int* quantizedQueryAabbMin,unsigned short int* quantizedQueryAabbMax) const -{ - btAssert(m_useQuantization); - - bool isLeafNode; - //PCK: unsigned instead of bool - unsigned aabbOverlap; - - //PCK: unsigned instead of bool - aabbOverlap = testQuantizedAabbAgainstQuantizedAabb(quantizedQueryAabbMin,quantizedQueryAabbMax,currentNode->m_quantizedAabbMin,currentNode->m_quantizedAabbMax); - isLeafNode = currentNode->isLeafNode(); - - //PCK: unsigned instead of bool - if (aabbOverlap != 0) - { - if (isLeafNode) - { - nodeCallback->processNode(0,currentNode->getTriangleIndex()); - } else - { - //process left and right children - const btQuantizedBvhNode* leftChildNode = currentNode+1; - walkRecursiveQuantizedTreeAgainstQueryAabb(leftChildNode,nodeCallback,quantizedQueryAabbMin,quantizedQueryAabbMax); - - const btQuantizedBvhNode* rightChildNode = leftChildNode->isLeafNode() ? leftChildNode+1:leftChildNode+leftChildNode->getEscapeIndex(); - walkRecursiveQuantizedTreeAgainstQueryAabb(rightChildNode,nodeCallback,quantizedQueryAabbMin,quantizedQueryAabbMax); - } - } -} - - - - - - - -void btOptimizedBvh::walkStacklessQuantizedTree(btNodeOverlapCallback* nodeCallback,unsigned short int* quantizedQueryAabbMin,unsigned short int* quantizedQueryAabbMax,int startNodeIndex,int endNodeIndex) const -{ - btAssert(m_useQuantization); - - int curIndex = startNodeIndex; - int walkIterations = 0; - int subTreeSize = endNodeIndex - startNodeIndex; - - const btQuantizedBvhNode* rootNode = &m_quantizedContiguousNodes[startNodeIndex]; - int escapeIndex; - - bool isLeafNode; - //PCK: unsigned instead of bool - unsigned aabbOverlap; - - while (curIndex < endNodeIndex) - { - -//#define VISUALLY_ANALYZE_BVH 1 -#ifdef VISUALLY_ANALYZE_BVH - //some code snippet to debugDraw aabb, to visually analyze bvh structure - static int drawPatch = 0; - //need some global access to a debugDrawer - extern btIDebugDraw* debugDrawerPtr; - if (curIndex==drawPatch) - { - btVector3 aabbMin,aabbMax; - aabbMin = unQuantize(rootNode->m_quantizedAabbMin); - aabbMax = unQuantize(rootNode->m_quantizedAabbMax); - btVector3 color(1,0,0); - debugDrawerPtr->drawAabb(aabbMin,aabbMax,color); - } -#endif//VISUALLY_ANALYZE_BVH - - //catch bugs in tree data - assert (walkIterations < subTreeSize); - - walkIterations++; - //PCK: unsigned instead of bool - aabbOverlap = testQuantizedAabbAgainstQuantizedAabb(quantizedQueryAabbMin,quantizedQueryAabbMax,rootNode->m_quantizedAabbMin,rootNode->m_quantizedAabbMax); - isLeafNode = rootNode->isLeafNode(); - - if (isLeafNode && aabbOverlap) - { - nodeCallback->processNode(0,rootNode->getTriangleIndex()); - } - - //PCK: unsigned instead of bool - if ((aabbOverlap != 0) || isLeafNode) - { - rootNode++; - curIndex++; - } else - { - escapeIndex = rootNode->getEscapeIndex(); - rootNode += escapeIndex; - curIndex += escapeIndex; - } - } - if (maxIterations < walkIterations) - maxIterations = walkIterations; - -} - -//This traversal can be called from Playstation 3 SPU -void btOptimizedBvh::walkStacklessQuantizedTreeCacheFriendly(btNodeOverlapCallback* nodeCallback,unsigned short int* quantizedQueryAabbMin,unsigned short int* quantizedQueryAabbMax) const -{ - btAssert(m_useQuantization); - - int i; - - - for (i=0;im_SubtreeHeaders.size();i++) - { - const btBvhSubtreeInfo& subtree = m_SubtreeHeaders[i]; - - //PCK: unsigned instead of bool - unsigned overlap = testQuantizedAabbAgainstQuantizedAabb(quantizedQueryAabbMin,quantizedQueryAabbMax,subtree.m_quantizedAabbMin,subtree.m_quantizedAabbMax); - if (overlap != 0) - { - walkStacklessQuantizedTree(nodeCallback,quantizedQueryAabbMin,quantizedQueryAabbMax, - subtree.m_rootNodeIndex, - subtree.m_rootNodeIndex+subtree.m_subtreeSize); - } - } -} - - - - -void btOptimizedBvh::reportSphereOverlappingNodex(btNodeOverlapCallback* nodeCallback,const btVector3& aabbMin,const btVector3& aabbMax) const -{ - (void)nodeCallback; - (void)aabbMin; - (void)aabbMax; - //not yet, please use aabb - btAssert(0); -} - - - - -btVector3 btOptimizedBvh::unQuantize(const unsigned short* vecIn) const -{ - btVector3 vecOut; - vecOut.setValue( - (btScalar)(vecIn[0]) / (m_bvhQuantization.getX()), - (btScalar)(vecIn[1]) / (m_bvhQuantization.getY()), - (btScalar)(vecIn[2]) / (m_bvhQuantization.getZ())); - vecOut += m_bvhAabbMin; - return vecOut; -} - - -void btOptimizedBvh::swapLeafNodes(int i,int splitIndex) -{ - if (m_useQuantization) - { - btQuantizedBvhNode tmp = m_quantizedLeafNodes[i]; - m_quantizedLeafNodes[i] = m_quantizedLeafNodes[splitIndex]; - m_quantizedLeafNodes[splitIndex] = tmp; - } else - { - btOptimizedBvhNode tmp = m_leafNodes[i]; - m_leafNodes[i] = m_leafNodes[splitIndex]; - m_leafNodes[splitIndex] = tmp; - } -} - -void btOptimizedBvh::assignInternalNodeFromLeafNode(int internalNode,int leafNodeIndex) -{ - if (m_useQuantization) - { - m_quantizedContiguousNodes[internalNode] = m_quantizedLeafNodes[leafNodeIndex]; - } else - { - m_contiguousNodes[internalNode] = m_leafNodes[leafNodeIndex]; - } -} - -//PCK: include -#include - -//PCK: consts -static const unsigned BVH_ALIGNMENT = 16; -static const unsigned BVH_ALIGNMENT_MASK = BVH_ALIGNMENT-1; - -static const unsigned BVH_ALIGNMENT_BLOCKS = 2; - - - -unsigned int btOptimizedBvh::getAlignmentSerializationPadding() -{ - return BVH_ALIGNMENT_BLOCKS * BVH_ALIGNMENT; -} - -unsigned btOptimizedBvh::calculateSerializeBufferSize() -{ - unsigned baseSize = sizeof(btOptimizedBvh) + getAlignmentSerializationPadding(); - baseSize += sizeof(btBvhSubtreeInfo) * m_subtreeHeaderCount; - if (m_useQuantization) - { - return baseSize + m_curNodeIndex * sizeof(btQuantizedBvhNode); - } - return baseSize + m_curNodeIndex * sizeof(btOptimizedBvhNode); -} - -bool btOptimizedBvh::serialize(void *o_alignedDataBuffer, unsigned i_dataBufferSize, bool i_swapEndian) -{ - assert(m_subtreeHeaderCount == m_SubtreeHeaders.size()); - m_subtreeHeaderCount = m_SubtreeHeaders.size(); - -/* if (i_dataBufferSize < calculateSerializeBufferSize() || o_alignedDataBuffer == NULL || (((unsigned)o_alignedDataBuffer & BVH_ALIGNMENT_MASK) != 0)) - { - ///check alignedment for buffer? - btAssert(0); - return false; - } -*/ - - btOptimizedBvh *targetBvh = (btOptimizedBvh *)o_alignedDataBuffer; - - // construct the class so the virtual function table, etc will be set up - // Also, m_leafNodes and m_quantizedLeafNodes will be initialized to default values by the constructor - new (targetBvh) btOptimizedBvh; - - if (i_swapEndian) - { - targetBvh->m_curNodeIndex = btSwapEndian(m_curNodeIndex); - - - btSwapVector3Endian(m_bvhAabbMin,targetBvh->m_bvhAabbMin); - btSwapVector3Endian(m_bvhAabbMax,targetBvh->m_bvhAabbMax); - btSwapVector3Endian(m_bvhQuantization,targetBvh->m_bvhQuantization); - - targetBvh->m_traversalMode = (btTraversalMode)btSwapEndian(m_traversalMode); - targetBvh->m_subtreeHeaderCount = btSwapEndian(m_subtreeHeaderCount); - } - else - { - targetBvh->m_curNodeIndex = m_curNodeIndex; - targetBvh->m_bvhAabbMin = m_bvhAabbMin; - targetBvh->m_bvhAabbMax = m_bvhAabbMax; - targetBvh->m_bvhQuantization = m_bvhQuantization; - targetBvh->m_traversalMode = m_traversalMode; - targetBvh->m_subtreeHeaderCount = m_subtreeHeaderCount; - } - - targetBvh->m_useQuantization = m_useQuantization; - - unsigned char *nodeData = (unsigned char *)targetBvh; - nodeData += sizeof(btOptimizedBvh); - - unsigned sizeToAdd = 0;//(BVH_ALIGNMENT-((unsigned)nodeData & BVH_ALIGNMENT_MASK))&BVH_ALIGNMENT_MASK; - nodeData += sizeToAdd; - - int nodeCount = m_curNodeIndex; - - if (m_useQuantization) - { - targetBvh->m_quantizedContiguousNodes.initializeFromBuffer(nodeData, nodeCount, nodeCount); - - if (i_swapEndian) - { - for (int nodeIndex = 0; nodeIndex < nodeCount; nodeIndex++) - { - targetBvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[0] = btSwapEndian(m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[0]); - targetBvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[1] = btSwapEndian(m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[1]); - targetBvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[2] = btSwapEndian(m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[2]); - - targetBvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[0] = btSwapEndian(m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[0]); - targetBvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[1] = btSwapEndian(m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[1]); - targetBvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[2] = btSwapEndian(m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[2]); - - targetBvh->m_quantizedContiguousNodes[nodeIndex].m_escapeIndexOrTriangleIndex = btSwapEndian(m_quantizedContiguousNodes[nodeIndex].m_escapeIndexOrTriangleIndex); - } - } - else - { - for (int nodeIndex = 0; nodeIndex < nodeCount; nodeIndex++) - { - - targetBvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[0] = m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[0]; - targetBvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[1] = m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[1]; - targetBvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[2] = m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[2]; - - targetBvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[0] = m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[0]; - targetBvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[1] = m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[1]; - targetBvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[2] = m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[2]; - - targetBvh->m_quantizedContiguousNodes[nodeIndex].m_escapeIndexOrTriangleIndex = m_quantizedContiguousNodes[nodeIndex].m_escapeIndexOrTriangleIndex; - - - } - } - nodeData += sizeof(btQuantizedBvhNode) * nodeCount; - } - else - { - targetBvh->m_contiguousNodes.initializeFromBuffer(nodeData, nodeCount, nodeCount); - - if (i_swapEndian) - { - for (int nodeIndex = 0; nodeIndex < nodeCount; nodeIndex++) - { - btSwapVector3Endian(m_contiguousNodes[nodeIndex].m_aabbMinOrg, targetBvh->m_contiguousNodes[nodeIndex].m_aabbMinOrg); - btSwapVector3Endian(m_contiguousNodes[nodeIndex].m_aabbMaxOrg, targetBvh->m_contiguousNodes[nodeIndex].m_aabbMaxOrg); - - targetBvh->m_contiguousNodes[nodeIndex].m_escapeIndex = btSwapEndian(m_contiguousNodes[nodeIndex].m_escapeIndex); - targetBvh->m_contiguousNodes[nodeIndex].m_subPart = btSwapEndian(m_contiguousNodes[nodeIndex].m_subPart); - targetBvh->m_contiguousNodes[nodeIndex].m_triangleIndex = btSwapEndian(m_contiguousNodes[nodeIndex].m_triangleIndex); - } - } - else - { - for (int nodeIndex = 0; nodeIndex < nodeCount; nodeIndex++) - { - targetBvh->m_contiguousNodes[nodeIndex].m_aabbMinOrg = m_contiguousNodes[nodeIndex].m_aabbMinOrg; - targetBvh->m_contiguousNodes[nodeIndex].m_aabbMaxOrg = m_contiguousNodes[nodeIndex].m_aabbMaxOrg; - - targetBvh->m_contiguousNodes[nodeIndex].m_escapeIndex = m_contiguousNodes[nodeIndex].m_escapeIndex; - targetBvh->m_contiguousNodes[nodeIndex].m_subPart = m_contiguousNodes[nodeIndex].m_subPart; - targetBvh->m_contiguousNodes[nodeIndex].m_triangleIndex = m_contiguousNodes[nodeIndex].m_triangleIndex; - } - } - nodeData += sizeof(btOptimizedBvhNode) * nodeCount; - } - - sizeToAdd = 0;//(BVH_ALIGNMENT-((unsigned)nodeData & BVH_ALIGNMENT_MASK))&BVH_ALIGNMENT_MASK; - nodeData += sizeToAdd; - - // Now serialize the subtree headers - targetBvh->m_SubtreeHeaders.initializeFromBuffer(nodeData, m_subtreeHeaderCount, m_subtreeHeaderCount); - if (i_swapEndian) - { - for (int i = 0; i < m_subtreeHeaderCount; i++) - { - targetBvh->m_SubtreeHeaders[i].m_quantizedAabbMin[0] = btSwapEndian(m_SubtreeHeaders[i].m_quantizedAabbMin[0]); - targetBvh->m_SubtreeHeaders[i].m_quantizedAabbMin[1] = btSwapEndian(m_SubtreeHeaders[i].m_quantizedAabbMin[1]); - targetBvh->m_SubtreeHeaders[i].m_quantizedAabbMin[2] = btSwapEndian(m_SubtreeHeaders[i].m_quantizedAabbMin[2]); - - targetBvh->m_SubtreeHeaders[i].m_quantizedAabbMax[0] = btSwapEndian(m_SubtreeHeaders[i].m_quantizedAabbMax[0]); - targetBvh->m_SubtreeHeaders[i].m_quantizedAabbMax[1] = btSwapEndian(m_SubtreeHeaders[i].m_quantizedAabbMax[1]); - targetBvh->m_SubtreeHeaders[i].m_quantizedAabbMax[2] = btSwapEndian(m_SubtreeHeaders[i].m_quantizedAabbMax[2]); - - targetBvh->m_SubtreeHeaders[i].m_rootNodeIndex = btSwapEndian(m_SubtreeHeaders[i].m_rootNodeIndex); - targetBvh->m_SubtreeHeaders[i].m_subtreeSize = btSwapEndian(m_SubtreeHeaders[i].m_subtreeSize); - } - } - else - { - for (int i = 0; i < m_subtreeHeaderCount; i++) - { - targetBvh->m_SubtreeHeaders[i].m_quantizedAabbMin[0] = (m_SubtreeHeaders[i].m_quantizedAabbMin[0]); - targetBvh->m_SubtreeHeaders[i].m_quantizedAabbMin[1] = (m_SubtreeHeaders[i].m_quantizedAabbMin[1]); - targetBvh->m_SubtreeHeaders[i].m_quantizedAabbMin[2] = (m_SubtreeHeaders[i].m_quantizedAabbMin[2]); - - targetBvh->m_SubtreeHeaders[i].m_quantizedAabbMax[0] = (m_SubtreeHeaders[i].m_quantizedAabbMax[0]); - targetBvh->m_SubtreeHeaders[i].m_quantizedAabbMax[1] = (m_SubtreeHeaders[i].m_quantizedAabbMax[1]); - targetBvh->m_SubtreeHeaders[i].m_quantizedAabbMax[2] = (m_SubtreeHeaders[i].m_quantizedAabbMax[2]); - - targetBvh->m_SubtreeHeaders[i].m_rootNodeIndex = (m_SubtreeHeaders[i].m_rootNodeIndex); - targetBvh->m_SubtreeHeaders[i].m_subtreeSize = (m_SubtreeHeaders[i].m_subtreeSize); - targetBvh->m_SubtreeHeaders[i] = m_SubtreeHeaders[i]; - } - } - - nodeData += sizeof(btBvhSubtreeInfo) * m_subtreeHeaderCount; - - return true; -} - -btOptimizedBvh *btOptimizedBvh::deSerializeInPlace(void *i_alignedDataBuffer, unsigned i_dataBufferSize, bool i_swapEndian) -{ - - if (i_alignedDataBuffer == NULL)// || (((unsigned)i_alignedDataBuffer & BVH_ALIGNMENT_MASK) != 0)) - { - return NULL; - } - btOptimizedBvh *bvh = (btOptimizedBvh *)i_alignedDataBuffer; - - if (i_swapEndian) - { - bvh->m_curNodeIndex = btSwapEndian(bvh->m_curNodeIndex); - - btUnSwapVector3Endian(bvh->m_bvhAabbMin); - btUnSwapVector3Endian(bvh->m_bvhAabbMax); - btUnSwapVector3Endian(bvh->m_bvhQuantization); - - bvh->m_traversalMode = (btTraversalMode)btSwapEndian(bvh->m_traversalMode); - bvh->m_subtreeHeaderCount = btSwapEndian(bvh->m_subtreeHeaderCount); - } - - int calculatedBufSize = bvh->calculateSerializeBufferSize(); - btAssert(calculatedBufSize <= i_dataBufferSize); - - if (calculatedBufSize > i_dataBufferSize) - { - return NULL; - } - - unsigned char *nodeData = (unsigned char *)bvh; - nodeData += sizeof(btOptimizedBvh); - - unsigned sizeToAdd = 0;//(BVH_ALIGNMENT-((unsigned)nodeData & BVH_ALIGNMENT_MASK))&BVH_ALIGNMENT_MASK; - nodeData += sizeToAdd; - - int nodeCount = bvh->m_curNodeIndex; - - // Must call placement new to fill in virtual function table, etc, but we don't want to overwrite most data, so call a special version of the constructor - // Also, m_leafNodes and m_quantizedLeafNodes will be initialized to default values by the constructor - new (bvh) btOptimizedBvh(*bvh, false); - - if (bvh->m_useQuantization) - { - bvh->m_quantizedContiguousNodes.initializeFromBuffer(nodeData, nodeCount, nodeCount); - - if (i_swapEndian) - { - for (int nodeIndex = 0; nodeIndex < nodeCount; nodeIndex++) - { - bvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[0] = btSwapEndian(bvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[0]); - bvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[1] = btSwapEndian(bvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[1]); - bvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[2] = btSwapEndian(bvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[2]); - - bvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[0] = btSwapEndian(bvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[0]); - bvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[1] = btSwapEndian(bvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[1]); - bvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[2] = btSwapEndian(bvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[2]); - - bvh->m_quantizedContiguousNodes[nodeIndex].m_escapeIndexOrTriangleIndex = btSwapEndian(bvh->m_quantizedContiguousNodes[nodeIndex].m_escapeIndexOrTriangleIndex); - } - } - nodeData += sizeof(btQuantizedBvhNode) * nodeCount; - } - else - { - bvh->m_contiguousNodes.initializeFromBuffer(nodeData, nodeCount, nodeCount); - - if (i_swapEndian) - { - for (int nodeIndex = 0; nodeIndex < nodeCount; nodeIndex++) - { - btUnSwapVector3Endian(bvh->m_contiguousNodes[nodeIndex].m_aabbMinOrg); - btUnSwapVector3Endian(bvh->m_contiguousNodes[nodeIndex].m_aabbMaxOrg); - - bvh->m_contiguousNodes[nodeIndex].m_escapeIndex = btSwapEndian(bvh->m_contiguousNodes[nodeIndex].m_escapeIndex); - bvh->m_contiguousNodes[nodeIndex].m_subPart = btSwapEndian(bvh->m_contiguousNodes[nodeIndex].m_subPart); - bvh->m_contiguousNodes[nodeIndex].m_triangleIndex = btSwapEndian(bvh->m_contiguousNodes[nodeIndex].m_triangleIndex); - } - } - nodeData += sizeof(btOptimizedBvhNode) * nodeCount; - } - - sizeToAdd = 0;//(BVH_ALIGNMENT-((unsigned)nodeData & BVH_ALIGNMENT_MASK))&BVH_ALIGNMENT_MASK; - nodeData += sizeToAdd; - - // Now serialize the subtree headers - bvh->m_SubtreeHeaders.initializeFromBuffer(nodeData, bvh->m_subtreeHeaderCount, bvh->m_subtreeHeaderCount); - if (i_swapEndian) - { - for (int i = 0; i < bvh->m_subtreeHeaderCount; i++) - { - bvh->m_SubtreeHeaders[i].m_quantizedAabbMin[0] = btSwapEndian(bvh->m_SubtreeHeaders[i].m_quantizedAabbMin[0]); - bvh->m_SubtreeHeaders[i].m_quantizedAabbMin[1] = btSwapEndian(bvh->m_SubtreeHeaders[i].m_quantizedAabbMin[1]); - bvh->m_SubtreeHeaders[i].m_quantizedAabbMin[2] = btSwapEndian(bvh->m_SubtreeHeaders[i].m_quantizedAabbMin[2]); - - bvh->m_SubtreeHeaders[i].m_quantizedAabbMax[0] = btSwapEndian(bvh->m_SubtreeHeaders[i].m_quantizedAabbMax[0]); - bvh->m_SubtreeHeaders[i].m_quantizedAabbMax[1] = btSwapEndian(bvh->m_SubtreeHeaders[i].m_quantizedAabbMax[1]); - bvh->m_SubtreeHeaders[i].m_quantizedAabbMax[2] = btSwapEndian(bvh->m_SubtreeHeaders[i].m_quantizedAabbMax[2]); - - bvh->m_SubtreeHeaders[i].m_rootNodeIndex = btSwapEndian(bvh->m_SubtreeHeaders[i].m_rootNodeIndex); - bvh->m_SubtreeHeaders[i].m_subtreeSize = btSwapEndian(bvh->m_SubtreeHeaders[i].m_subtreeSize); - } - } - - return bvh; -} - -// Constructor that prevents btVector3's default constructor from being called -btOptimizedBvh::btOptimizedBvh(btOptimizedBvh &self, bool ownsMemory) : -m_bvhAabbMin(self.m_bvhAabbMin), -m_bvhAabbMax(self.m_bvhAabbMax), -m_bvhQuantization(self.m_bvhQuantization) -{ - -} - diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btOptimizedBvh.h b/extern/bullet2/src/BulletCollision/CollisionShapes/btOptimizedBvh.h deleted file mode 100644 index bcacdbe582b..00000000000 --- a/extern/bullet2/src/BulletCollision/CollisionShapes/btOptimizedBvh.h +++ /dev/null @@ -1,393 +0,0 @@ -/* -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 OPTIMIZED_BVH_H -#define OPTIMIZED_BVH_H - - - -#include "LinearMath/btVector3.h" -#include "LinearMath/btAlignedAllocator.h" - - -//http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vclang/html/vclrf__m128.asp - - - -class btStridingMeshInterface; - -//Note: currently we have 16 bytes per quantized node -#define MAX_SUBTREE_SIZE_IN_BYTES 2048 - - -///btQuantizedBvhNode is a compressed aabb node, 16 bytes. -///Node can be used for leafnode or internal node. Leafnodes can point to 32-bit triangle index (non-negative range). -ATTRIBUTE_ALIGNED16 (struct) btQuantizedBvhNode -{ - BT_DECLARE_ALIGNED_ALLOCATOR(); - - //12 bytes - unsigned short int m_quantizedAabbMin[3]; - unsigned short int m_quantizedAabbMax[3]; - //4 bytes - int m_escapeIndexOrTriangleIndex; - - bool isLeafNode() const - { - //skipindex is negative (internal node), triangleindex >=0 (leafnode) - return (m_escapeIndexOrTriangleIndex >= 0); - } - int getEscapeIndex() const - { - btAssert(!isLeafNode()); - return -m_escapeIndexOrTriangleIndex; - } - int getTriangleIndex() const - { - btAssert(isLeafNode()); - return m_escapeIndexOrTriangleIndex; - } -} -; - -/// btOptimizedBvhNode contains both internal and leaf node information. -/// Total node size is 44 bytes / node. You can use the compressed version of 16 bytes. -ATTRIBUTE_ALIGNED16 (struct) btOptimizedBvhNode -{ - BT_DECLARE_ALIGNED_ALLOCATOR(); - - //32 bytes - btVector3 m_aabbMinOrg; - btVector3 m_aabbMaxOrg; - - //4 - int m_escapeIndex; - - //8 - //for child nodes - int m_subPart; - int m_triangleIndex; - int m_padding[5];//bad, due to alignment - - -}; - - -///btBvhSubtreeInfo provides info to gather a subtree of limited size -ATTRIBUTE_ALIGNED16(class) btBvhSubtreeInfo -{ -public: - BT_DECLARE_ALIGNED_ALLOCATOR(); - - //12 bytes - unsigned short int m_quantizedAabbMin[3]; - unsigned short int m_quantizedAabbMax[3]; - //4 bytes, points to the root of the subtree - int m_rootNodeIndex; - //4 bytes - int m_subtreeSize; - int m_padding[3]; - - btBvhSubtreeInfo() - { - //memset(&m_padding[0], 0, sizeof(m_padding)); - } - - - void setAabbFromQuantizeNode(const btQuantizedBvhNode& quantizedNode) - { - m_quantizedAabbMin[0] = quantizedNode.m_quantizedAabbMin[0]; - m_quantizedAabbMin[1] = quantizedNode.m_quantizedAabbMin[1]; - m_quantizedAabbMin[2] = quantizedNode.m_quantizedAabbMin[2]; - m_quantizedAabbMax[0] = quantizedNode.m_quantizedAabbMax[0]; - m_quantizedAabbMax[1] = quantizedNode.m_quantizedAabbMax[1]; - m_quantizedAabbMax[2] = quantizedNode.m_quantizedAabbMax[2]; - } -} -; - - -class btNodeOverlapCallback -{ -public: - virtual ~btNodeOverlapCallback() {}; - - virtual void processNode(int subPart, int triangleIndex) = 0; -}; - -#include "LinearMath/btAlignedAllocator.h" -#include "LinearMath/btAlignedObjectArray.h" - - - -///for code readability: -typedef btAlignedObjectArray NodeArray; -typedef btAlignedObjectArray QuantizedNodeArray; -typedef btAlignedObjectArray BvhSubtreeInfoArray; - - -///OptimizedBvh store an AABB tree that can be quickly traversed on CPU (and SPU,GPU in future) -ATTRIBUTE_ALIGNED16(class) btOptimizedBvh -{ - NodeArray m_leafNodes; - NodeArray m_contiguousNodes; - - QuantizedNodeArray m_quantizedLeafNodes; - - QuantizedNodeArray m_quantizedContiguousNodes; - - int m_curNodeIndex; - - - //quantization data - bool m_useQuantization; - btVector3 m_bvhAabbMin; - btVector3 m_bvhAabbMax; - btVector3 m_bvhQuantization; -public: - BT_DECLARE_ALIGNED_ALLOCATOR(); - - enum btTraversalMode - { - TRAVERSAL_STACKLESS = 0, - TRAVERSAL_STACKLESS_CACHE_FRIENDLY, - TRAVERSAL_RECURSIVE - }; -protected: - - btTraversalMode m_traversalMode; - - BvhSubtreeInfoArray m_SubtreeHeaders; - - //This is only used for serialization so we don't have to add serialization directly to btAlignedObjectArray - int m_subtreeHeaderCount; - - - ///two versions, one for quantized and normal nodes. This allows code-reuse while maintaining readability (no template/macro!) - ///this might be refactored into a virtual, it is usually not calculated at run-time - void setInternalNodeAabbMin(int nodeIndex, const btVector3& aabbMin) - { - if (m_useQuantization) - { - quantizeWithClamp(&m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[0] ,aabbMin); - } else - { - m_contiguousNodes[nodeIndex].m_aabbMinOrg = aabbMin; - - } - } - void setInternalNodeAabbMax(int nodeIndex,const btVector3& aabbMax) - { - if (m_useQuantization) - { - quantizeWithClamp(&m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[0],aabbMax); - } else - { - m_contiguousNodes[nodeIndex].m_aabbMaxOrg = aabbMax; - } - } - - btVector3 getAabbMin(int nodeIndex) const - { - if (m_useQuantization) - { - return unQuantize(&m_quantizedLeafNodes[nodeIndex].m_quantizedAabbMin[0]); - } - //non-quantized - return m_leafNodes[nodeIndex].m_aabbMinOrg; - - } - btVector3 getAabbMax(int nodeIndex) const - { - if (m_useQuantization) - { - return unQuantize(&m_quantizedLeafNodes[nodeIndex].m_quantizedAabbMax[0]); - } - //non-quantized - return m_leafNodes[nodeIndex].m_aabbMaxOrg; - - } - - void setQuantizationValues(const btVector3& bvhAabbMin,const btVector3& bvhAabbMax,btScalar quantizationMargin=btScalar(1.0)); - - void setInternalNodeEscapeIndex(int nodeIndex, int escapeIndex) - { - if (m_useQuantization) - { - m_quantizedContiguousNodes[nodeIndex].m_escapeIndexOrTriangleIndex = -escapeIndex; - } - else - { - m_contiguousNodes[nodeIndex].m_escapeIndex = escapeIndex; - } - - } - - void mergeInternalNodeAabb(int nodeIndex,const btVector3& newAabbMin,const btVector3& newAabbMax) - { - if (m_useQuantization) - { - unsigned short int quantizedAabbMin[3]; - unsigned short int quantizedAabbMax[3]; - quantizeWithClamp(quantizedAabbMin,newAabbMin); - quantizeWithClamp(quantizedAabbMax,newAabbMax); - for (int i=0;i<3;i++) - { - if (m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[i] > quantizedAabbMin[i]) - m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[i] = quantizedAabbMin[i]; - - if (m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[i] < quantizedAabbMax[i]) - m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[i] = quantizedAabbMax[i]; - - } - } else - { - //non-quantized - m_contiguousNodes[nodeIndex].m_aabbMinOrg.setMin(newAabbMin); - m_contiguousNodes[nodeIndex].m_aabbMaxOrg.setMax(newAabbMax); - } - } - - void swapLeafNodes(int firstIndex,int secondIndex); - - void assignInternalNodeFromLeafNode(int internalNode,int leafNodeIndex); - -protected: - - - - void buildTree (int startIndex,int endIndex); - - int calcSplittingAxis(int startIndex,int endIndex); - - int sortAndCalcSplittingIndex(int startIndex,int endIndex,int splitAxis); - - void walkStacklessTree(btNodeOverlapCallback* nodeCallback,const btVector3& aabbMin,const btVector3& aabbMax) const; - - void walkStacklessQuantizedTree(btNodeOverlapCallback* nodeCallback,unsigned short int* quantizedQueryAabbMin,unsigned short int* quantizedQueryAabbMax,int startNodeIndex,int endNodeIndex) const; - - ///tree traversal designed for small-memory processors like PS3 SPU - void walkStacklessQuantizedTreeCacheFriendly(btNodeOverlapCallback* nodeCallback,unsigned short int* quantizedQueryAabbMin,unsigned short int* quantizedQueryAabbMax) const; - - ///use the 16-byte stackless 'skipindex' node tree to do a recursive traversal - void walkRecursiveQuantizedTreeAgainstQueryAabb(const btQuantizedBvhNode* currentNode,btNodeOverlapCallback* nodeCallback,unsigned short int* quantizedQueryAabbMin,unsigned short int* quantizedQueryAabbMax) const; - - ///use the 16-byte stackless 'skipindex' node tree to do a recursive traversal - void walkRecursiveQuantizedTreeAgainstQuantizedTree(const btQuantizedBvhNode* treeNodeA,const btQuantizedBvhNode* treeNodeB,btNodeOverlapCallback* nodeCallback) const; - - -#define USE_BANCHLESS 1 -#ifdef USE_BANCHLESS - //This block replaces the block below and uses no branches, and replaces the 8 bit return with a 32 bit return for improved performance (~3x on XBox 360) - SIMD_FORCE_INLINE unsigned testQuantizedAabbAgainstQuantizedAabb(unsigned short int* aabbMin1,unsigned short int* aabbMax1,const unsigned short int* aabbMin2,const unsigned short int* aabbMax2) const - { - return btSelect((unsigned)((aabbMin1[0] <= aabbMax2[0]) & (aabbMax1[0] >= aabbMin2[0]) - & (aabbMin1[2] <= aabbMax2[2]) & (aabbMax1[2] >= aabbMin2[2]) - & (aabbMin1[1] <= aabbMax2[1]) & (aabbMax1[1] >= aabbMin2[1])), - 1, 0); - } -#else - SIMD_FORCE_INLINE bool testQuantizedAabbAgainstQuantizedAabb(unsigned short int* aabbMin1,unsigned short int* aabbMax1,const unsigned short int* aabbMin2,const unsigned short int* aabbMax2) const - { - bool overlap = true; - overlap = (aabbMin1[0] > aabbMax2[0] || aabbMax1[0] < aabbMin2[0]) ? false : overlap; - overlap = (aabbMin1[2] > aabbMax2[2] || aabbMax1[2] < aabbMin2[2]) ? false : overlap; - overlap = (aabbMin1[1] > aabbMax2[1] || aabbMax1[1] < aabbMin2[1]) ? false : overlap; - return overlap; - } -#endif //USE_BANCHLESS - - void updateSubtreeHeaders(int leftChildNodexIndex,int rightChildNodexIndex); - -public: - btOptimizedBvh(); - - virtual ~btOptimizedBvh(); - - void build(btStridingMeshInterface* triangles,bool useQuantizedAabbCompression, const btVector3& bvhAabbMin, const btVector3& bvhAabbMax); - - void reportAabbOverlappingNodex(btNodeOverlapCallback* nodeCallback,const btVector3& aabbMin,const btVector3& aabbMax) const; - - void reportSphereOverlappingNodex(btNodeOverlapCallback* nodeCallback,const btVector3& aabbMin,const btVector3& aabbMax) const; - - SIMD_FORCE_INLINE void quantizeWithClamp(unsigned short* out, const btVector3& point) const - { - - btAssert(m_useQuantization); - - btVector3 clampedPoint(point); - clampedPoint.setMax(m_bvhAabbMin); - clampedPoint.setMin(m_bvhAabbMax); - - btVector3 v = (clampedPoint - m_bvhAabbMin) * m_bvhQuantization; - out[0] = (unsigned short)(v.getX()+0.5f); - out[1] = (unsigned short)(v.getY()+0.5f); - out[2] = (unsigned short)(v.getZ()+0.5f); - } - - - btVector3 unQuantize(const unsigned short* vecIn) const; - - ///setTraversalMode let's you choose between stackless, recursive or stackless cache friendly tree traversal. Note this is only implemented for quantized trees. - void setTraversalMode(btTraversalMode traversalMode) - { - m_traversalMode = traversalMode; - } - - void refit(btStridingMeshInterface* triangles); - - void refitPartial(btStridingMeshInterface* triangles,const btVector3& aabbMin, const btVector3& aabbMax); - - void updateBvhNodes(btStridingMeshInterface* meshInterface,int firstNode,int endNode,int index); - - - SIMD_FORCE_INLINE QuantizedNodeArray& getQuantizedNodeArray() - { - return m_quantizedContiguousNodes; - } - - SIMD_FORCE_INLINE BvhSubtreeInfoArray& getSubtreeInfoArray() - { - return m_SubtreeHeaders; - } - - /////Calculate space needed to store BVH for serialization - unsigned calculateSerializeBufferSize(); - - /// Data buffer MUST be 16 byte aligned - bool serialize(void *o_alignedDataBuffer, unsigned i_dataBufferSize, bool i_swapEndian); - - ///deSerializeInPlace loads and initializes a BVH from a buffer in memory 'in place' - static btOptimizedBvh *deSerializeInPlace(void *i_alignedDataBuffer, unsigned i_dataBufferSize, bool i_swapEndian); - - static unsigned int getAlignmentSerializationPadding(); - - SIMD_FORCE_INLINE bool isQuantized() - { - return m_useQuantization; - } - -private: - // Special "copy" constructor that allows for in-place deserialization - // Prevents btVector3's default constructor from being called, but doesn't inialize much else - // ownsMemory should most likely be false if deserializing, and if you are not, don't call this (it also changes the function signature, which we need) - btOptimizedBvh(btOptimizedBvh &other, bool ownsMemory); - -} -; - - -#endif //OPTIMIZED_BVH_H - diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btPolyhedralConvexShape.cpp b/extern/bullet2/src/BulletCollision/CollisionShapes/btPolyhedralConvexShape.cpp deleted file mode 100644 index 30323deb3b5..00000000000 --- a/extern/bullet2/src/BulletCollision/CollisionShapes/btPolyhedralConvexShape.cpp +++ /dev/null @@ -1,148 +0,0 @@ -/* -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 - -btPolyhedralConvexShape::btPolyhedralConvexShape() -:m_localAabbMin(1,1,1), -m_localAabbMax(-1,-1,-1), -m_isLocalAabbValid(false), -m_optionalHull(0) -{ - -} - - - -btVector3 btPolyhedralConvexShape::localGetSupportingVertexWithoutMargin(const btVector3& vec0)const -{ - int i; - btVector3 supVec(0,0,0); - - btScalar maxDot(btScalar(-1e30)); - - btVector3 vec = vec0; - btScalar lenSqr = vec.length2(); - if (lenSqr < btScalar(0.0001)) - { - vec.setValue(1,0,0); - } else - { - btScalar rlen = btScalar(1.) / btSqrt(lenSqr ); - vec *= rlen; - } - - btVector3 vtx; - btScalar newDot; - - for (i=0;i maxDot) - { - maxDot = newDot; - supVec = vtx; - } - } - - return supVec; - -} - -void btPolyhedralConvexShape::batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const -{ - int i; - - btVector3 vtx; - btScalar newDot; - - for (i=0;i supportVerticesOut[j][3]) - { - //WARNING: don't swap next lines, the w component would get overwritten! - supportVerticesOut[j] = vtx; - supportVerticesOut[j][3] = newDot; - } - } - } -} - - - -void btPolyhedralConvexShape::calculateLocalInertia(btScalar mass,btVector3& inertia) const -{ - //not yet, return box inertia - - btScalar margin = getMargin(); - - btTransform ident; - ident.setIdentity(); - btVector3 aabbMin,aabbMax; - getAabb(ident,aabbMin,aabbMax); - btVector3 halfExtents = (aabbMax-aabbMin)*btScalar(0.5); - - btScalar lx=btScalar(2.)*(halfExtents.x()+margin); - btScalar ly=btScalar(2.)*(halfExtents.y()+margin); - btScalar lz=btScalar(2.)*(halfExtents.z()+margin); - const btScalar x2 = lx*lx; - const btScalar y2 = ly*ly; - const btScalar z2 = lz*lz; - const btScalar scaledmass = mass * btScalar(0.08333333); - - inertia = scaledmass * (btVector3(y2+z2,x2+z2,x2+y2)); - -} - - - -void btPolyhedralConvexShape::getAabb(const btTransform& trans,btVector3& aabbMin,btVector3& aabbMax) const -{ - getNonvirtualAabb(trans,aabbMin,aabbMax,getMargin()); -} - - - - -void btPolyhedralConvexShape::recalcLocalAabb() -{ - m_isLocalAabbValid = true; - - for (int i=0;i<3;i++) - { - btVector3 vec(btScalar(0.),btScalar(0.),btScalar(0.)); - vec[i] = btScalar(1.); - btVector3 tmp = localGetSupportingVertex(vec); - m_localAabbMax[i] = tmp[i]+m_collisionMargin; - vec[i] = btScalar(-1.); - tmp = localGetSupportingVertex(vec); - m_localAabbMin[i] = tmp[i]-m_collisionMargin; - } -} - - diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btPolyhedralConvexShape.h b/extern/bullet2/src/BulletCollision/CollisionShapes/btPolyhedralConvexShape.h deleted file mode 100644 index 9d46b991e10..00000000000 --- a/extern/bullet2/src/BulletCollision/CollisionShapes/btPolyhedralConvexShape.h +++ /dev/null @@ -1,93 +0,0 @@ -/* -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 BU_SHAPE -#define BU_SHAPE - -#include "LinearMath/btPoint3.h" -#include "LinearMath/btMatrix3x3.h" -#include "btConvexInternalShape.h" - - -///PolyhedralConvexShape is an interface class for feature based (vertex/edge/face) convex shapes. -class btPolyhedralConvexShape : public btConvexInternalShape -{ - -protected: - btVector3 m_localAabbMin; - btVector3 m_localAabbMax; - bool m_isLocalAabbValid; - -public: - - btPolyhedralConvexShape(); - - //brute force implementations - virtual btVector3 localGetSupportingVertexWithoutMargin(const btVector3& vec)const; - virtual void batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const; - - virtual void calculateLocalInertia(btScalar mass,btVector3& inertia) const; - - - inline void getNonvirtualAabb(const btTransform& trans,btVector3& aabbMin,btVector3& aabbMax, btScalar margin) const - { - - //lazy evaluation of local aabb - btAssert(m_isLocalAabbValid); - - btAssert(m_localAabbMin.getX() <= m_localAabbMax.getX()); - btAssert(m_localAabbMin.getY() <= m_localAabbMax.getY()); - btAssert(m_localAabbMin.getZ() <= m_localAabbMax.getZ()); - - - btVector3 localHalfExtents = btScalar(0.5)*(m_localAabbMax-m_localAabbMin); - btVector3 localCenter = btScalar(0.5)*(m_localAabbMax+m_localAabbMin); - - btMatrix3x3 abs_b = trans.getBasis().absolute(); - - btPoint3 center = trans(localCenter); - - btVector3 extent = btVector3(abs_b[0].dot(localHalfExtents), - abs_b[1].dot(localHalfExtents), - abs_b[2].dot(localHalfExtents)); - extent += btVector3(margin,margin,margin); - - aabbMin = center - extent; - aabbMax = center + extent; - - - } - - - virtual void getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const; - - void recalcLocalAabb(); - - virtual int getNumVertices() const = 0 ; - virtual int getNumEdges() const = 0; - virtual void getEdge(int i,btPoint3& pa,btPoint3& pb) const = 0; - virtual void getVertex(int i,btPoint3& vtx) const = 0; - virtual int getNumPlanes() const = 0; - virtual void getPlane(btVector3& planeNormal,btPoint3& planeSupport,int i ) const = 0; -// virtual int getIndex(int i) const = 0 ; - - virtual bool isInside(const btPoint3& pt,btScalar tolerance) const = 0; - - /// optional Hull is for optional Separating Axis Test Hull collision detection, see Hull.cpp - class Hull* m_optionalHull; - -}; - -#endif //BU_SHAPE diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btSphereShape.cpp b/extern/bullet2/src/BulletCollision/CollisionShapes/btSphereShape.cpp deleted file mode 100644 index 15cfe432e27..00000000000 --- a/extern/bullet2/src/BulletCollision/CollisionShapes/btSphereShape.cpp +++ /dev/null @@ -1,77 +0,0 @@ -/* -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 "btSphereShape.h" -#include "BulletCollision/CollisionShapes/btCollisionMargin.h" - -#include "LinearMath/btQuaternion.h" - - -btSphereShape ::btSphereShape (btScalar radius) -{ - m_implicitShapeDimensions.setX(radius); -} - -btVector3 btSphereShape::localGetSupportingVertexWithoutMargin(const btVector3& vec)const -{ - (void)vec; - return btVector3(btScalar(0.),btScalar(0.),btScalar(0.)); -} - -void btSphereShape::batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const -{ - (void)vectors; - - for (int i=0;iprocessTriangle(triangle,0,0); - - triangle[0] = projectedCenter - tangentDir0*radius - tangentDir1*radius; - triangle[1] = projectedCenter - tangentDir0*radius + tangentDir1*radius; - triangle[2] = projectedCenter + tangentDir0*radius + tangentDir1*radius; - - callback->processTriangle(triangle,0,1); - -} - -void btStaticPlaneShape::calculateLocalInertia(btScalar mass,btVector3& inertia) const -{ - (void)mass; - - //moving concave objects not supported - - inertia.setValue(btScalar(0.),btScalar(0.),btScalar(0.)); -} - -void btStaticPlaneShape::setLocalScaling(const btVector3& scaling) -{ - m_localScaling = scaling; -} -const btVector3& btStaticPlaneShape::getLocalScaling() const -{ - return m_localScaling; -} diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btStaticPlaneShape.h b/extern/bullet2/src/BulletCollision/CollisionShapes/btStaticPlaneShape.h deleted file mode 100644 index 0cbce3abd93..00000000000 --- a/extern/bullet2/src/BulletCollision/CollisionShapes/btStaticPlaneShape.h +++ /dev/null @@ -1,61 +0,0 @@ -/* -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 STATIC_PLANE_SHAPE_H -#define STATIC_PLANE_SHAPE_H - -#include "btConcaveShape.h" - - -///StaticPlaneShape simulates an 'infinite' plane by dynamically reporting triangles approximated by intersection of the plane with the AABB. -///Assumed is that the other objects is not also infinite, so a reasonable sized AABB. -class btStaticPlaneShape : public btConcaveShape -{ -protected: - btVector3 m_localAabbMin; - btVector3 m_localAabbMax; - - btVector3 m_planeNormal; - btScalar m_planeConstant; - btVector3 m_localScaling; - -public: - btStaticPlaneShape(const btVector3& planeNormal,btScalar planeConstant); - - virtual ~btStaticPlaneShape(); - - - virtual int getShapeType() const - { - return STATIC_PLANE_PROXYTYPE; - } - - virtual void getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const; - - virtual void processAllTriangles(btTriangleCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const; - - virtual void calculateLocalInertia(btScalar mass,btVector3& inertia) const; - - virtual void setLocalScaling(const btVector3& scaling); - virtual const btVector3& getLocalScaling() const; - - - //debugging - virtual const char* getName()const {return "STATICPLANE";} - - -}; - -#endif //STATIC_PLANE_SHAPE_H diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btStridingMeshInterface.cpp b/extern/bullet2/src/BulletCollision/CollisionShapes/btStridingMeshInterface.cpp deleted file mode 100644 index 3129b7c83ce..00000000000 --- a/extern/bullet2/src/BulletCollision/CollisionShapes/btStridingMeshInterface.cpp +++ /dev/null @@ -1,124 +0,0 @@ -/* -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 "btStridingMeshInterface.h" - -btStridingMeshInterface::~btStridingMeshInterface() -{ - -} - - -void btStridingMeshInterface::InternalProcessAllTriangles(btInternalTriangleIndexCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const -{ - (void)aabbMin; - (void)aabbMax; - int numtotalphysicsverts = 0; - int part,graphicssubparts = getNumSubParts(); - const unsigned char * vertexbase; - const unsigned char * indexbase; - int indexstride; - PHY_ScalarType type; - PHY_ScalarType gfxindextype; - int stride,numverts,numtriangles; - int gfxindex; - btVector3 triangle[3]; - btScalar* graphicsbase; - - btVector3 meshScaling = getScaling(); - - ///if the number of parts is big, the performance might drop due to the innerloop switch on indextype - for (part=0;partinternalProcessTriangleIndex(triangle,part,gfxindex); - } - break; - } - case PHY_SHORT: - { - for (gfxindex=0;gfxindexinternalProcessTriangleIndex(triangle,part,gfxindex); - } - break; - } - default: - btAssert((gfxindextype == PHY_INTEGER) || (gfxindextype == PHY_SHORT)); - } - - unLockReadOnlyVertexBase(part); - } -} - -void btStridingMeshInterface::calculateAabbBruteForce(btVector3& aabbMin,btVector3& aabbMax) -{ - - struct AabbCalculationCallback : public btInternalTriangleIndexCallback - { - btVector3 m_aabbMin; - btVector3 m_aabbMax; - - AabbCalculationCallback() - { - m_aabbMin.setValue(btScalar(1e30),btScalar(1e30),btScalar(1e30)); - m_aabbMax.setValue(btScalar(-1e30),btScalar(-1e30),btScalar(-1e30)); - } - - virtual void internalProcessTriangleIndex(btVector3* triangle,int partId,int triangleIndex) - { - (void)partId; - (void)triangleIndex; - - m_aabbMin.setMin(triangle[0]); - m_aabbMax.setMax(triangle[0]); - m_aabbMin.setMin(triangle[1]); - m_aabbMax.setMax(triangle[1]); - m_aabbMin.setMin(triangle[2]); - m_aabbMax.setMax(triangle[2]); - } - }; - - //first calculate the total aabb for all triangles - AabbCalculationCallback aabbCallback; - aabbMin.setValue(btScalar(-1e30),btScalar(-1e30),btScalar(-1e30)); - aabbMax.setValue(btScalar(1e30),btScalar(1e30),btScalar(1e30)); - InternalProcessAllTriangles(&aabbCallback,aabbMin,aabbMax); - - aabbMin = aabbCallback.m_aabbMin; - aabbMax = aabbCallback.m_aabbMax; -} diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btStridingMeshInterface.h b/extern/bullet2/src/BulletCollision/CollisionShapes/btStridingMeshInterface.h deleted file mode 100644 index 4ce0bd2e2f9..00000000000 --- a/extern/bullet2/src/BulletCollision/CollisionShapes/btStridingMeshInterface.h +++ /dev/null @@ -1,89 +0,0 @@ -/* -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 STRIDING_MESHINTERFACE_H -#define STRIDING_MESHINTERFACE_H - -#include "LinearMath/btVector3.h" -#include "btTriangleCallback.h" - -/// PHY_ScalarType enumerates possible scalar types. -/// See the btStridingMeshInterface for its use -typedef enum PHY_ScalarType { - PHY_FLOAT, - PHY_DOUBLE, - PHY_INTEGER, - PHY_SHORT, - PHY_FIXEDPOINT88 -} PHY_ScalarType; - -/// btStridingMeshInterface is the interface class for high performance access to triangle meshes -/// It allows for sharing graphics and collision meshes. Also it provides locking/unlocking of graphics meshes that are in gpu memory. -class btStridingMeshInterface -{ - protected: - - btVector3 m_scaling; - - public: - btStridingMeshInterface() :m_scaling(btScalar(1.),btScalar(1.),btScalar(1.)) - { - - } - - virtual ~btStridingMeshInterface(); - - - - void InternalProcessAllTriangles(btInternalTriangleIndexCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const; - - ///brute force method to calculate aabb - void calculateAabbBruteForce(btVector3& aabbMin,btVector3& aabbMax); - - /// get read and write access to a subpart of a triangle mesh - /// this subpart has a continuous array of vertices and indices - /// in this way the mesh can be handled as chunks of memory with striding - /// very similar to OpenGL vertexarray support - /// make a call to unLockVertexBase when the read and write access is finished - virtual void getLockedVertexIndexBase(unsigned char **vertexbase, int& numverts,PHY_ScalarType& type, int& stride,unsigned char **indexbase,int & indexstride,int& numfaces,PHY_ScalarType& indicestype,int subpart=0)=0; - - virtual void getLockedReadOnlyVertexIndexBase(const unsigned char **vertexbase, int& numverts,PHY_ScalarType& type, int& stride,const unsigned char **indexbase,int & indexstride,int& numfaces,PHY_ScalarType& indicestype,int subpart=0) const=0; - - /// unLockVertexBase finishes the access to a subpart of the triangle mesh - /// make a call to unLockVertexBase when the read and write access (using getLockedVertexIndexBase) is finished - virtual void unLockVertexBase(int subpart)=0; - - virtual void unLockReadOnlyVertexBase(int subpart) const=0; - - - /// getNumSubParts returns the number of seperate subparts - /// each subpart has a continuous array of vertices and indices - virtual int getNumSubParts() const=0; - - virtual void preallocateVertices(int numverts)=0; - virtual void preallocateIndices(int numindices)=0; - - const btVector3& getScaling() const { - return m_scaling; - } - void setScaling(const btVector3& scaling) - { - m_scaling = scaling; - } - - -}; - -#endif //STRIDING_MESHINTERFACE_H diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btTetrahedronShape.cpp b/extern/bullet2/src/BulletCollision/CollisionShapes/btTetrahedronShape.cpp deleted file mode 100644 index 3aa1eda9964..00000000000 --- a/extern/bullet2/src/BulletCollision/CollisionShapes/btTetrahedronShape.cpp +++ /dev/null @@ -1,195 +0,0 @@ - -/* -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 "btTetrahedronShape.h" -#include "LinearMath/btMatrix3x3.h" - -btBU_Simplex1to4::btBU_Simplex1to4() -:m_numVertices(0) -{ -} - -btBU_Simplex1to4::btBU_Simplex1to4(const btPoint3& pt0) -:m_numVertices(0) -{ - addVertex(pt0); -} - -btBU_Simplex1to4::btBU_Simplex1to4(const btPoint3& pt0,const btPoint3& pt1) -:m_numVertices(0) -{ - addVertex(pt0); - addVertex(pt1); -} - -btBU_Simplex1to4::btBU_Simplex1to4(const btPoint3& pt0,const btPoint3& pt1,const btPoint3& pt2) -:m_numVertices(0) -{ - addVertex(pt0); - addVertex(pt1); - addVertex(pt2); -} - -btBU_Simplex1to4::btBU_Simplex1to4(const btPoint3& pt0,const btPoint3& pt1,const btPoint3& pt2,const btPoint3& pt3) -:m_numVertices(0) -{ - addVertex(pt0); - addVertex(pt1); - addVertex(pt2); - addVertex(pt3); -} - - - - - -void btBU_Simplex1to4::addVertex(const btPoint3& pt) -{ - m_vertices[m_numVertices++] = pt; - - recalcLocalAabb(); -} - - -int btBU_Simplex1to4::getNumVertices() const -{ - return m_numVertices; -} - -int btBU_Simplex1to4::getNumEdges() const -{ - //euler formula, F-E+V = 2, so E = F+V-2 - - switch (m_numVertices) - { - case 0: - return 0; - case 1: return 0; - case 2: return 1; - case 3: return 3; - case 4: return 6; - - - } - - return 0; -} - -void btBU_Simplex1to4::getEdge(int i,btPoint3& pa,btPoint3& pb) const -{ - - switch (m_numVertices) - { - - case 2: - pa = m_vertices[0]; - pb = m_vertices[1]; - break; - case 3: - switch (i) - { - case 0: - pa = m_vertices[0]; - pb = m_vertices[1]; - break; - case 1: - pa = m_vertices[1]; - pb = m_vertices[2]; - break; - case 2: - pa = m_vertices[2]; - pb = m_vertices[0]; - break; - - } - break; - case 4: - switch (i) - { - case 0: - pa = m_vertices[0]; - pb = m_vertices[1]; - break; - case 1: - pa = m_vertices[1]; - pb = m_vertices[2]; - break; - case 2: - pa = m_vertices[2]; - pb = m_vertices[0]; - break; - case 3: - pa = m_vertices[0]; - pb = m_vertices[3]; - break; - case 4: - pa = m_vertices[1]; - pb = m_vertices[3]; - break; - case 5: - pa = m_vertices[2]; - pb = m_vertices[3]; - break; - } - - } - - - - -} - -void btBU_Simplex1to4::getVertex(int i,btPoint3& vtx) const -{ - vtx = m_vertices[i]; -} - -int btBU_Simplex1to4::getNumPlanes() const -{ - switch (m_numVertices) - { - case 0: - return 0; - case 1: - return 0; - case 2: - return 0; - case 3: - return 2; - case 4: - return 4; - default: - { - } - } - return 0; -} - - -void btBU_Simplex1to4::getPlane(btVector3&, btPoint3& ,int ) const -{ - -} - -int btBU_Simplex1to4::getIndex(int ) const -{ - return 0; -} - -bool btBU_Simplex1to4::isInside(const btPoint3& ,btScalar ) const -{ - return false; -} - diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btTetrahedronShape.h b/extern/bullet2/src/BulletCollision/CollisionShapes/btTetrahedronShape.h deleted file mode 100644 index ca1b4b42a6f..00000000000 --- a/extern/bullet2/src/BulletCollision/CollisionShapes/btTetrahedronShape.h +++ /dev/null @@ -1,75 +0,0 @@ -/* -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 BU_SIMPLEX_1TO4_SHAPE -#define BU_SIMPLEX_1TO4_SHAPE - - -#include "btPolyhedralConvexShape.h" -#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" - - -///BU_Simplex1to4 implements feature based and implicit simplex of up to 4 vertices (tetrahedron, triangle, line, vertex). -class btBU_Simplex1to4 : public btPolyhedralConvexShape -{ -protected: - - int m_numVertices; - btPoint3 m_vertices[4]; - -public: - btBU_Simplex1to4(); - - btBU_Simplex1to4(const btPoint3& pt0); - btBU_Simplex1to4(const btPoint3& pt0,const btPoint3& pt1); - btBU_Simplex1to4(const btPoint3& pt0,const btPoint3& pt1,const btPoint3& pt2); - btBU_Simplex1to4(const btPoint3& pt0,const btPoint3& pt1,const btPoint3& pt2,const btPoint3& pt3); - - - void reset() - { - m_numVertices = 0; - } - - - virtual int getShapeType() const{ return TETRAHEDRAL_SHAPE_PROXYTYPE; } - - void addVertex(const btPoint3& pt); - - //PolyhedralConvexShape interface - - virtual int getNumVertices() const; - - virtual int getNumEdges() const; - - virtual void getEdge(int i,btPoint3& pa,btPoint3& pb) const; - - virtual void getVertex(int i,btPoint3& vtx) const; - - virtual int getNumPlanes() const; - - virtual void getPlane(btVector3& planeNormal,btPoint3& planeSupport,int i) const; - - virtual int getIndex(int i) const; - - virtual bool isInside(const btPoint3& pt,btScalar tolerance) const; - - - ///getName is for debugging - virtual const char* getName()const { return "btBU_Simplex1to4";} - -}; - -#endif //BU_SIMPLEX_1TO4_SHAPE diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleBuffer.cpp b/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleBuffer.cpp deleted file mode 100644 index 54864c32f3a..00000000000 --- a/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleBuffer.cpp +++ /dev/null @@ -1,42 +0,0 @@ -/* -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 "btTriangleBuffer.h" - - -///example usage of this class: -// btTriangleBuffer triBuf; -// concaveShape->processAllTriangles(&triBuf,aabbMin, aabbMax); -// for (int i=0;i m_triangleBuffer; - -public: - - - virtual void processTriangle(btVector3* triangle, int partId, int triangleIndex); - - int getNumTriangles() const - { - return int(m_triangleBuffer.size()); - } - - const btTriangle& getTriangle(int index) const - { - return m_triangleBuffer[index]; - } - - void clearBuffer() - { - m_triangleBuffer.clear(); - } - -}; - - -#endif //BT_TRIANGLE_BUFFER_H - diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleCallback.cpp b/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleCallback.cpp deleted file mode 100644 index a020746db5f..00000000000 --- a/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleCallback.cpp +++ /dev/null @@ -1,28 +0,0 @@ -/* -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 "btTriangleCallback.h" - -btTriangleCallback::~btTriangleCallback() -{ - -} - - -btInternalTriangleIndexCallback::~btInternalTriangleIndexCallback() -{ - -} - diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleCallback.h b/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleCallback.h deleted file mode 100644 index 7b2337498ec..00000000000 --- a/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleCallback.h +++ /dev/null @@ -1,40 +0,0 @@ -/* -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 TRIANGLE_CALLBACK_H -#define TRIANGLE_CALLBACK_H - -#include "LinearMath/btVector3.h" - - -class btTriangleCallback -{ -public: - - virtual ~btTriangleCallback(); - virtual void processTriangle(btVector3* triangle, int partId, int triangleIndex) = 0; -}; - -class btInternalTriangleIndexCallback -{ -public: - - virtual ~btInternalTriangleIndexCallback(); - virtual void internalProcessTriangleIndex(btVector3* triangle,int partId,int triangleIndex) = 0; -}; - - - -#endif //TRIANGLE_CALLBACK_H diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleIndexVertexArray.cpp b/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleIndexVertexArray.cpp deleted file mode 100644 index 554915a7058..00000000000 --- a/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleIndexVertexArray.cpp +++ /dev/null @@ -1,78 +0,0 @@ -/* -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 "btTriangleIndexVertexArray.h" - -btTriangleIndexVertexArray::btTriangleIndexVertexArray(int numTriangles,int* triangleIndexBase,int triangleIndexStride,int numVertices,btScalar* vertexBase,int vertexStride) -{ - btIndexedMesh mesh; - - mesh.m_numTriangles = numTriangles; - mesh.m_triangleIndexBase = (const unsigned char *)triangleIndexBase; - mesh.m_triangleIndexStride = triangleIndexStride; - mesh.m_numVertices = numVertices; - mesh.m_vertexBase = (const unsigned char *)vertexBase; - mesh.m_vertexStride = vertexStride; - - addIndexedMesh(mesh); - -} - -btTriangleIndexVertexArray::~btTriangleIndexVertexArray() -{ - -} - -void btTriangleIndexVertexArray::getLockedVertexIndexBase(unsigned char **vertexbase, int& numverts,PHY_ScalarType& type, int& vertexStride,unsigned char **indexbase,int & indexstride,int& numfaces,PHY_ScalarType& indicestype,int subpart) -{ - btAssert(subpart< getNumSubParts() ); - - btIndexedMesh& mesh = m_indexedMeshes[subpart]; - - numverts = mesh.m_numVertices; - (*vertexbase) = (unsigned char *) mesh.m_vertexBase; - #ifdef BT_USE_DOUBLE_PRECISION - type = PHY_DOUBLE; - #else - type = PHY_FLOAT; - #endif - vertexStride = mesh.m_vertexStride; - - numfaces = mesh.m_numTriangles; - - (*indexbase) = (unsigned char *)mesh.m_triangleIndexBase; - indexstride = mesh.m_triangleIndexStride; - indicestype = PHY_INTEGER; -} - -void btTriangleIndexVertexArray::getLockedReadOnlyVertexIndexBase(const unsigned char **vertexbase, int& numverts,PHY_ScalarType& type, int& vertexStride,const unsigned char **indexbase,int & indexstride,int& numfaces,PHY_ScalarType& indicestype,int subpart) const -{ - const btIndexedMesh& mesh = m_indexedMeshes[subpart]; - - numverts = mesh.m_numVertices; - (*vertexbase) = (const unsigned char *)mesh.m_vertexBase; - #ifdef BT_USE_DOUBLE_PRECISION - type = PHY_DOUBLE; - #else - type = PHY_FLOAT; - #endif - vertexStride = mesh.m_vertexStride; - - numfaces = mesh.m_numTriangles; - (*indexbase) = (const unsigned char *)mesh.m_triangleIndexBase; - indexstride = mesh.m_triangleIndexStride; - indicestype = PHY_INTEGER; -} - diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleIndexVertexArray.h b/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleIndexVertexArray.h deleted file mode 100644 index 3441a8325e2..00000000000 --- a/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleIndexVertexArray.h +++ /dev/null @@ -1,105 +0,0 @@ -/* -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 BT_TRIANGLE_INDEX_VERTEX_ARRAY_H -#define BT_TRIANGLE_INDEX_VERTEX_ARRAY_H - -#include "btStridingMeshInterface.h" -#include "LinearMath/btAlignedObjectArray.h" -#include "LinearMath/btScalar.h" - - -///IndexedMesh indexes into existing vertex and index arrays, in a similar way OpenGL glDrawElements -///instead of the number of indices, we pass the number of triangles -///todo: explain with pictures -ATTRIBUTE_ALIGNED16( struct) btIndexedMesh -{ - BT_DECLARE_ALIGNED_ALLOCATOR(); - - int m_numTriangles; - const unsigned char * m_triangleIndexBase; - int m_triangleIndexStride; - int m_numVertices; - const unsigned char * m_vertexBase; - int m_vertexStride; - int pad[2]; -} -; - - -typedef btAlignedObjectArray IndexedMeshArray; - -///TriangleIndexVertexArray allows to use multiple meshes, by indexing into existing triangle/index arrays. -///Additional meshes can be added using addIndexedMesh -///No duplcate is made of the vertex/index data, it only indexes into external vertex/index arrays. -///So keep those arrays around during the lifetime of this btTriangleIndexVertexArray. -ATTRIBUTE_ALIGNED16( class) btTriangleIndexVertexArray : public btStridingMeshInterface -{ - IndexedMeshArray m_indexedMeshes; - int m_pad[3]; - - -public: - - BT_DECLARE_ALIGNED_ALLOCATOR(); - - btTriangleIndexVertexArray() - { - } - - virtual ~btTriangleIndexVertexArray(); - - //just to be backwards compatible - btTriangleIndexVertexArray(int numTriangleIndices,int* triangleIndexBase,int triangleIndexStride,int numVertices,btScalar* vertexBase,int vertexStride); - - void addIndexedMesh(const btIndexedMesh& mesh) - { - m_indexedMeshes.push_back(mesh); - } - - - virtual void getLockedVertexIndexBase(unsigned char **vertexbase, int& numverts,PHY_ScalarType& type, int& vertexStride,unsigned char **indexbase,int & indexstride,int& numfaces,PHY_ScalarType& indicestype,int subpart=0); - - virtual void getLockedReadOnlyVertexIndexBase(const unsigned char **vertexbase, int& numverts,PHY_ScalarType& type, int& vertexStride,const unsigned char **indexbase,int & indexstride,int& numfaces,PHY_ScalarType& indicestype,int subpart=0) const; - - /// unLockVertexBase finishes the access to a subpart of the triangle mesh - /// make a call to unLockVertexBase when the read and write access (using getLockedVertexIndexBase) is finished - virtual void unLockVertexBase(int subpart) {(void)subpart;} - - virtual void unLockReadOnlyVertexBase(int subpart) const {(void)subpart;} - - /// getNumSubParts returns the number of seperate subparts - /// each subpart has a continuous array of vertices and indices - virtual int getNumSubParts() const { - return (int)m_indexedMeshes.size(); - } - - IndexedMeshArray& getIndexedMeshArray() - { - return m_indexedMeshes; - } - - const IndexedMeshArray& getIndexedMeshArray() const - { - return m_indexedMeshes; - } - - virtual void preallocateVertices(int numverts){(void) numverts;} - virtual void preallocateIndices(int numindices){(void) numindices;} - -} -; - -#endif //BT_TRIANGLE_INDEX_VERTEX_ARRAY_H diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleMesh.cpp b/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleMesh.cpp deleted file mode 100644 index 98c54ef45f8..00000000000 --- a/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleMesh.cpp +++ /dev/null @@ -1,60 +0,0 @@ -/* -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 "btTriangleMesh.h" -#include - - -btTriangleMesh::btTriangleMesh () -{ - -} - -void btTriangleMesh::getLockedVertexIndexBase(unsigned char **vertexbase, int& numverts,PHY_ScalarType& type, int& stride,unsigned char **indexbase,int & indexstride,int& numfaces,PHY_ScalarType& indicestype,int subpart) -{ - (void)subpart; - numverts = m_vertices.size(); - *vertexbase = (unsigned char*)&m_vertices[0]; - type = PHY_FLOAT; - stride = sizeof(btVector3); - - numfaces = m_indices.size()/3; - *indexbase = (unsigned char*) &m_indices[0]; - indicestype = PHY_INTEGER; - indexstride = 3*sizeof(int); - -} - -void btTriangleMesh::getLockedReadOnlyVertexIndexBase(const unsigned char **vertexbase, int& numverts,PHY_ScalarType& type, int& stride,const unsigned char **indexbase,int & indexstride,int& numfaces,PHY_ScalarType& indicestype,int subpart) const -{ - (void)subpart; - numverts = m_vertices.size(); - *vertexbase = (unsigned char*)&m_vertices[0]; - type = PHY_FLOAT; - stride = sizeof(btVector3); - - numfaces = m_indices.size()/3; - *indexbase = (unsigned char*) &m_indices[0]; - indicestype = PHY_INTEGER; - indexstride = 3*sizeof(int); - -} - - - -int btTriangleMesh::getNumSubParts() const -{ - return 1; -} diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleMesh.h b/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleMesh.h deleted file mode 100644 index 83e5a56d16a..00000000000 --- a/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleMesh.h +++ /dev/null @@ -1,75 +0,0 @@ -/* -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 TRIANGLE_MESH_H -#define TRIANGLE_MESH_H - -#include "btStridingMeshInterface.h" -#include "LinearMath/btVector3.h" -#include "LinearMath/btAlignedObjectArray.h" - -///TriangleMesh provides storage for a concave triangle mesh. It can be used as data for the btTriangleMeshShape. -class btTriangleMesh : public btStridingMeshInterface -{ - btAlignedObjectArray m_vertices; - btAlignedObjectArray m_indices; - - public: - btTriangleMesh (); - - void addTriangle(const btVector3& vertex0,const btVector3& vertex1,const btVector3& vertex2) - { - int curIndex = m_indices.size(); - m_vertices.push_back(vertex0); - m_vertices.push_back(vertex1); - m_vertices.push_back(vertex2); - - m_indices.push_back(curIndex++); - m_indices.push_back(curIndex++); - m_indices.push_back(curIndex++); - } - - int getNumTriangles() const - { - return m_indices.size() / 3; - } - - - -//StridingMeshInterface interface implementation - - virtual void getLockedVertexIndexBase(unsigned char **vertexbase, int& numverts,PHY_ScalarType& type, int& stride,unsigned char **indexbase,int & indexstride,int& numfaces,PHY_ScalarType& indicestype,int subpart=0); - - virtual void getLockedReadOnlyVertexIndexBase(const unsigned char **vertexbase, int& numverts,PHY_ScalarType& type, int& stride,const unsigned char **indexbase,int & indexstride,int& numfaces,PHY_ScalarType& indicestype,int subpart=0) const; - - /// unLockVertexBase finishes the access to a subpart of the triangle mesh - /// make a call to unLockVertexBase when the read and write access (using getLockedVertexIndexBase) is finished - virtual void unLockVertexBase(int subpart) {(void) subpart;} - - virtual void unLockReadOnlyVertexBase(int subpart) const { (void) subpart;} - - /// getNumSubParts returns the number of seperate subparts - /// each subpart has a continuous array of vertices and indices - virtual int getNumSubParts() const; - - virtual void preallocateVertices(int numverts){(void) numverts;} - virtual void preallocateIndices(int numindices){(void) numindices;} - - -}; - -#endif //TRIANGLE_MESH_H - diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleMeshShape.cpp b/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleMeshShape.cpp deleted file mode 100644 index 0d390c88b68..00000000000 --- a/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleMeshShape.cpp +++ /dev/null @@ -1,202 +0,0 @@ -/* -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 "btTriangleMeshShape.h" -#include "LinearMath/btVector3.h" -#include "LinearMath/btQuaternion.h" -#include "btStridingMeshInterface.h" -#include "LinearMath/btAabbUtil2.h" -#include "BulletCollision/CollisionShapes/btCollisionMargin.h" - - -btTriangleMeshShape::btTriangleMeshShape(btStridingMeshInterface* meshInterface) -: m_meshInterface(meshInterface) -{ - recalcLocalAabb(); -} - - -btTriangleMeshShape::~btTriangleMeshShape() -{ - -} - - - - -void btTriangleMeshShape::getAabb(const btTransform& trans,btVector3& aabbMin,btVector3& aabbMax) const -{ - - btVector3 localHalfExtents = btScalar(0.5)*(m_localAabbMax-m_localAabbMin); - btVector3 localCenter = btScalar(0.5)*(m_localAabbMax+m_localAabbMin); - - btMatrix3x3 abs_b = trans.getBasis().absolute(); - - btPoint3 center = trans(localCenter); - - btVector3 extent = btVector3(abs_b[0].dot(localHalfExtents), - abs_b[1].dot(localHalfExtents), - abs_b[2].dot(localHalfExtents)); - extent += btVector3(getMargin(),getMargin(),getMargin()); - - aabbMin = center - extent; - aabbMax = center + extent; - - -} - -void btTriangleMeshShape::recalcLocalAabb() -{ - for (int i=0;i<3;i++) - { - btVector3 vec(btScalar(0.),btScalar(0.),btScalar(0.)); - vec[i] = btScalar(1.); - btVector3 tmp = localGetSupportingVertex(vec); - m_localAabbMax[i] = tmp[i]+m_collisionMargin; - vec[i] = btScalar(-1.); - tmp = localGetSupportingVertex(vec); - m_localAabbMin[i] = tmp[i]-m_collisionMargin; - } -} - - - -class SupportVertexCallback : public btTriangleCallback -{ - - btVector3 m_supportVertexLocal; -public: - - btTransform m_worldTrans; - btScalar m_maxDot; - btVector3 m_supportVecLocal; - - SupportVertexCallback(const btVector3& supportVecWorld,const btTransform& trans) - : m_supportVertexLocal(btScalar(0.),btScalar(0.),btScalar(0.)), m_worldTrans(trans) ,m_maxDot(btScalar(-1e30)) - - { - m_supportVecLocal = supportVecWorld * m_worldTrans.getBasis(); - } - - virtual void processTriangle( btVector3* triangle,int partId, int triangleIndex) - { - (void)partId; - (void)triangleIndex; - for (int i=0;i<3;i++) - { - btScalar dot = m_supportVecLocal.dot(triangle[i]); - if (dot > m_maxDot) - { - m_maxDot = dot; - m_supportVertexLocal = triangle[i]; - } - } - } - - btVector3 GetSupportVertexWorldSpace() - { - return m_worldTrans(m_supportVertexLocal); - } - - btVector3 GetSupportVertexLocal() - { - return m_supportVertexLocal; - } - -}; - - -void btTriangleMeshShape::setLocalScaling(const btVector3& scaling) -{ - m_meshInterface->setScaling(scaling); - recalcLocalAabb(); -} - -const btVector3& btTriangleMeshShape::getLocalScaling() const -{ - return m_meshInterface->getScaling(); -} - - - - - - -//#define DEBUG_TRIANGLE_MESH - - - -void btTriangleMeshShape::processAllTriangles(btTriangleCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const -{ - struct FilteredCallback : public btInternalTriangleIndexCallback - { - btTriangleCallback* m_callback; - btVector3 m_aabbMin; - btVector3 m_aabbMax; - - FilteredCallback(btTriangleCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) - :m_callback(callback), - m_aabbMin(aabbMin), - m_aabbMax(aabbMax) - { - } - - virtual void internalProcessTriangleIndex(btVector3* triangle,int partId,int triangleIndex) - { - if (TestTriangleAgainstAabb2(&triangle[0],m_aabbMin,m_aabbMax)) - { - //check aabb in triangle-space, before doing this - m_callback->processTriangle(triangle,partId,triangleIndex); - } - - } - - }; - - FilteredCallback filterCallback(callback,aabbMin,aabbMax); - - m_meshInterface->InternalProcessAllTriangles(&filterCallback,aabbMin,aabbMax); -} - - - - - -void btTriangleMeshShape::calculateLocalInertia(btScalar mass,btVector3& inertia) const -{ - (void)mass; - //moving concave objects not supported - btAssert(0); - inertia.setValue(btScalar(0.),btScalar(0.),btScalar(0.)); -} - - -btVector3 btTriangleMeshShape::localGetSupportingVertex(const btVector3& vec) const -{ - btVector3 supportVertex; - - btTransform ident; - ident.setIdentity(); - - SupportVertexCallback supportCallback(vec,ident); - - btVector3 aabbMax(btScalar(1e30),btScalar(1e30),btScalar(1e30)); - - processAllTriangles(&supportCallback,-aabbMax,aabbMax); - - supportVertex = supportCallback.GetSupportVertexLocal(); - - return supportVertex; -} diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleMeshShape.h b/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleMeshShape.h deleted file mode 100644 index 6657fc09147..00000000000 --- a/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleMeshShape.h +++ /dev/null @@ -1,80 +0,0 @@ -/* -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 TRIANGLE_MESH_SHAPE_H -#define TRIANGLE_MESH_SHAPE_H - -#include "btConcaveShape.h" -#include "btStridingMeshInterface.h" - - -///Concave triangle mesh interface. Don't use this class directly, use btBvhTriangleMeshShape instead. -class btTriangleMeshShape : public btConcaveShape -{ -protected: - btVector3 m_localAabbMin; - btVector3 m_localAabbMax; - btStridingMeshInterface* m_meshInterface; - - ///btTriangleMeshShape constructor has been disabled/protected, so that users will not mistakenly use this class. - ///Don't use btTriangleMeshShape but use btBvhTriangleMeshShape instead! - btTriangleMeshShape(btStridingMeshInterface* meshInterface); - -public: - - virtual ~btTriangleMeshShape(); - - virtual btVector3 localGetSupportingVertex(const btVector3& vec) const; - - virtual btVector3 localGetSupportingVertexWithoutMargin(const btVector3& vec)const - { - assert(0); - return localGetSupportingVertex(vec); - } - - void recalcLocalAabb(); - - virtual int getShapeType() const - { - return TRIANGLE_MESH_SHAPE_PROXYTYPE; - } - - virtual void getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const; - - virtual void processAllTriangles(btTriangleCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const; - - virtual void calculateLocalInertia(btScalar mass,btVector3& inertia) const; - - virtual void setLocalScaling(const btVector3& scaling); - virtual const btVector3& getLocalScaling() const; - - btStridingMeshInterface* getMeshInterface() - { - return m_meshInterface; - } - - const btStridingMeshInterface* getMeshInterface() const - { - return m_meshInterface; - } - - - //debugging - virtual const char* getName()const {return "TRIANGLEMESH";} - - -}; - -#endif //TRIANGLE_MESH_SHAPE_H diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleShape.h b/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleShape.h deleted file mode 100644 index 064c64fa6ab..00000000000 --- a/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleShape.h +++ /dev/null @@ -1,179 +0,0 @@ -/* -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 OBB_TRIANGLE_MINKOWSKI_H -#define OBB_TRIANGLE_MINKOWSKI_H - -#include "btConvexShape.h" -#include "btBoxShape.h" - -class btTriangleShape : public btPolyhedralConvexShape -{ - - -public: - - btVector3 m_vertices1[3]; - - - virtual int getNumVertices() const - { - return 3; - } - - const btVector3& getVertexPtr(int index) const - { - return m_vertices1[index]; - } - virtual void getVertex(int index,btVector3& vert) const - { - vert = m_vertices1[index]; - } - virtual int getShapeType() const - { - return TRIANGLE_SHAPE_PROXYTYPE; - } - - virtual int getNumEdges() const - { - return 3; - } - - virtual void getEdge(int i,btPoint3& pa,btPoint3& pb) const - { - getVertex(i,pa); - getVertex((i+1)%3,pb); - } - - - virtual void getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax)const - { -// btAssert(0); - getAabbSlow(t,aabbMin,aabbMax); - } - - btVector3 localGetSupportingVertexWithoutMargin(const btVector3& dir)const - { - btVector3 dots(dir.dot(m_vertices1[0]), dir.dot(m_vertices1[1]), dir.dot(m_vertices1[2])); - return m_vertices1[dots.maxAxis()]; - - } - - virtual void batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const - { - for (int i=0;i= -tolerance && dist <= tolerance) - { - //inside check on edge-planes - int i; - for (i=0;i<3;i++) - { - btPoint3 pa,pb; - getEdge(i,pa,pb); - btVector3 edge = pb-pa; - btVector3 edgeNormal = edge.cross(normal); - edgeNormal.normalize(); - btScalar dist = pt.dot( edgeNormal); - btScalar edgeConst = pa.dot(edgeNormal); - dist -= edgeConst; - if (dist < -tolerance) - return false; - } - - return true; - } - - return false; - } - //debugging - virtual const char* getName()const - { - return "Triangle"; - } - - virtual int getNumPreferredPenetrationDirections() const - { - return 2; - } - - virtual void getPreferredPenetrationDirection(int index, btVector3& penetrationVector) const - { - calcNormal(penetrationVector); - if (index) - penetrationVector *= btScalar(-1.); - } - - -}; - -#endif //OBB_TRIANGLE_MINKOWSKI_H - diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btUniformScalingShape.cpp b/extern/bullet2/src/BulletCollision/CollisionShapes/btUniformScalingShape.cpp deleted file mode 100644 index ef340286cb0..00000000000 --- a/extern/bullet2/src/BulletCollision/CollisionShapes/btUniformScalingShape.cpp +++ /dev/null @@ -1,114 +0,0 @@ -/* -Bullet Continuous Collision Detection and Physics Library -Copyright (c) 2003-2007 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 "btUniformScalingShape.h" - -btUniformScalingShape::btUniformScalingShape( btConvexShape* convexChildShape,btScalar uniformScalingFactor): -m_childConvexShape(convexChildShape), -m_uniformScalingFactor(uniformScalingFactor) -{ -} - -btUniformScalingShape::~btUniformScalingShape() -{ -} - - -btVector3 btUniformScalingShape::localGetSupportingVertexWithoutMargin(const btVector3& vec)const -{ - btVector3 tmpVertex; - tmpVertex = m_childConvexShape->localGetSupportingVertexWithoutMargin(vec); - return tmpVertex*m_uniformScalingFactor; -} - -void btUniformScalingShape::batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const -{ - m_childConvexShape->batchedUnitVectorGetSupportingVertexWithoutMargin(vectors,supportVerticesOut,numVectors); - int i; - for (i=0;ilocalGetSupportingVertex(vec); - return tmpVertex*m_uniformScalingFactor; -} - - -void btUniformScalingShape::calculateLocalInertia(btScalar mass,btVector3& inertia) const -{ - - ///this linear upscaling is not realistic, but we don't deal with large mass ratios... - btVector3 tmpInertia; - m_childConvexShape->calculateLocalInertia(mass,tmpInertia); - inertia = tmpInertia * m_uniformScalingFactor; -} - - - ///getAabb's default implementation is brute force, expected derived classes to implement a fast dedicated version -void btUniformScalingShape::getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const -{ - m_childConvexShape->getAabb(t,aabbMin,aabbMax); - btVector3 aabbCenter = (aabbMax+aabbMin)*btScalar(0.5); - btVector3 scaledAabbHalfExtends = (aabbMax-aabbMin)*btScalar(0.5)*m_uniformScalingFactor; - - aabbMin = aabbCenter - scaledAabbHalfExtends; - aabbMax = aabbCenter + scaledAabbHalfExtends; - -} - -void btUniformScalingShape::getAabbSlow(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const -{ - m_childConvexShape->getAabbSlow(t,aabbMin,aabbMax); - btVector3 aabbCenter = (aabbMax+aabbMin)*btScalar(0.5); - btVector3 scaledAabbHalfExtends = (aabbMax-aabbMin)*btScalar(0.5)*m_uniformScalingFactor; - - aabbMin = aabbCenter - scaledAabbHalfExtends; - aabbMax = aabbCenter + scaledAabbHalfExtends; -} - -void btUniformScalingShape::setLocalScaling(const btVector3& scaling) -{ - m_childConvexShape->setLocalScaling(scaling); -} - -const btVector3& btUniformScalingShape::getLocalScaling() const -{ - return m_childConvexShape->getLocalScaling(); -} - -void btUniformScalingShape::setMargin(btScalar margin) -{ - m_childConvexShape->setMargin(margin); -} -btScalar btUniformScalingShape::getMargin() const -{ - return m_childConvexShape->getMargin() * m_uniformScalingFactor; -} - -int btUniformScalingShape::getNumPreferredPenetrationDirections() const -{ - return m_childConvexShape->getNumPreferredPenetrationDirections(); -} - -void btUniformScalingShape::getPreferredPenetrationDirection(int index, btVector3& penetrationVector) const -{ - m_childConvexShape->getPreferredPenetrationDirection(index,penetrationVector); -} diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btUniformScalingShape.h b/extern/bullet2/src/BulletCollision/CollisionShapes/btUniformScalingShape.h deleted file mode 100644 index 3a0ecf021d3..00000000000 --- a/extern/bullet2/src/BulletCollision/CollisionShapes/btUniformScalingShape.h +++ /dev/null @@ -1,86 +0,0 @@ -/* -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 BT_UNIFORM_SCALING_SHAPE_H -#define BT_UNIFORM_SCALING_SHAPE_H - -#include "btConvexShape.h" -#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" // for the types - -class btUniformScalingShape : public btConvexShape -{ - btConvexShape* m_childConvexShape; - - btScalar m_uniformScalingFactor; - - public: - - btUniformScalingShape( btConvexShape* convexChildShape, btScalar uniformScalingFactor); - - virtual ~btUniformScalingShape(); - - virtual btVector3 localGetSupportingVertexWithoutMargin(const btVector3& vec)const; - - virtual btVector3 localGetSupportingVertex(const btVector3& vec)const; - - virtual void batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const; - - virtual void calculateLocalInertia(btScalar mass,btVector3& inertia) const; - - btScalar getUniformScalingFactor() const - { - return m_uniformScalingFactor; - } - - btConvexShape* getChildShape() - { - return m_childConvexShape; - } - - const btConvexShape* getChildShape() const - { - return m_childConvexShape; - } - - virtual const char* getName()const - { - return "UniformScalingShape"; - } - - virtual int getShapeType() const { return UNIFORM_SCALING_SHAPE_PROXYTYPE; } - - - /////////////////////////// - - - ///getAabb's default implementation is brute force, expected derived classes to implement a fast dedicated version - void getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const; - - virtual void getAabbSlow(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const; - - virtual void setLocalScaling(const btVector3& scaling) ; - virtual const btVector3& getLocalScaling() const ; - - virtual void setMargin(btScalar margin); - virtual btScalar getMargin() const; - - virtual int getNumPreferredPenetrationDirections() const; - - virtual void getPreferredPenetrationDirection(int index, btVector3& penetrationVector) const; - - -}; - -#endif //BT_UNIFORM_SCALING_SHAPE_H diff --git a/extern/bullet2/src/BulletCollision/Doxyfile b/extern/bullet2/src/BulletCollision/Doxyfile deleted file mode 100644 index 4ecb6acb62f..00000000000 --- a/extern/bullet2/src/BulletCollision/Doxyfile +++ /dev/null @@ -1,746 +0,0 @@ -# Doxyfile 1.2.4 - -# This file describes the settings to be used by doxygen for a project -# -# All text after a hash (#) is considered a comment and will be ignored -# The format is: -# TAG = value [value, ...] -# For lists items can also be appended using: -# TAG += value [value, ...] -# Values that contain spaces should be placed between quotes (" ") - -#--------------------------------------------------------------------------- -# General configuration options -#--------------------------------------------------------------------------- - -# The PROJECT_NAME tag is a single word (or a sequence of words surrounded -# by quotes) that should identify the project. -PROJECT_NAME = "Bullet Continuous Collision Detection Library" - -# The PROJECT_NUMBER tag can be used to enter a project or revision number. -# This could be handy for archiving the generated documentation or -# if some version control system is used. - -PROJECT_NUMBER = - -# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) -# base path where the generated documentation will be put. -# If a relative path is entered, it will be relative to the location -# where doxygen was started. If left blank the current directory will be used. - -OUTPUT_DIRECTORY = - -# The OUTPUT_LANGUAGE tag is used to specify the language in which all -# documentation generated by doxygen is written. Doxygen will use this -# information to generate all constant output in the proper language. -# The default language is English, other supported languages are: -# Dutch, French, Italian, Czech, Swedish, German, Finnish, Japanese, -# Korean, Hungarian, Norwegian, Spanish, Romanian, Russian, Croatian, -# Polish, Portuguese and Slovene. - -OUTPUT_LANGUAGE = English - -# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in -# documentation are documented, even if no documentation was available. -# Private class members and static file members will be hidden unless -# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES - -EXTRACT_ALL = YES - -# If the EXTRACT_PRIVATE tag is set to YES all private members of a class -# will be included in the documentation. - -EXTRACT_PRIVATE = YES - -# If the EXTRACT_STATIC tag is set to YES all static members of a file -# will be included in the documentation. - -EXTRACT_STATIC = YES - -# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all -# undocumented members of documented classes, files or namespaces. -# If set to NO (the default) these members will be included in the -# various overviews, but no documentation section is generated. -# This option has no effect if EXTRACT_ALL is enabled. - -HIDE_UNDOC_MEMBERS = NO - -# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all -# undocumented classes that are normally visible in the class hierarchy. -# If set to NO (the default) these class will be included in the various -# overviews. This option has no effect if EXTRACT_ALL is enabled. - -HIDE_UNDOC_CLASSES = NO - -# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will -# include brief member descriptions after the members that are listed in -# the file and class documentation (similar to JavaDoc). -# Set to NO to disable this. - -BRIEF_MEMBER_DESC = YES - -# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend -# the brief description of a member or function before the detailed description. -# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the -# brief descriptions will be completely suppressed. - -REPEAT_BRIEF = YES - -# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then -# Doxygen will generate a detailed section even if there is only a brief -# description. - -ALWAYS_DETAILED_SEC = NO - -# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full -# path before files name in the file list and in the header files. If set -# to NO the shortest path that makes the file name unique will be used. - -FULL_PATH_NAMES = NO - -# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag -# can be used to strip a user defined part of the path. Stripping is -# only done if one of the specified strings matches the left-hand part of -# the path. It is allowed to use relative paths in the argument list. - -STRIP_FROM_PATH = - -# The INTERNAL_DOCS tag determines if documentation -# that is typed after a \internal command is included. If the tag is set -# to NO (the default) then the documentation will be excluded. -# Set it to YES to include the internal documentation. - -INTERNAL_DOCS = NO - -# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will -# generate a class diagram (in Html and LaTeX) for classes with base or -# super classes. Setting the tag to NO turns the diagrams off. - -CLASS_DIAGRAMS = YES - -# If the SOURCE_BROWSER tag is set to YES then a list of source files will -# be generated. Documented entities will be cross-referenced with these sources. - -SOURCE_BROWSER = YES - -# Setting the INLINE_SOURCES tag to YES will include the body -# of functions and classes directly in the documentation. - -INLINE_SOURCES = NO - -# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct -# doxygen to hide any special comment blocks from generated source code -# fragments. Normal C and C++ comments will always remain visible. - -STRIP_CODE_COMMENTS = YES - -# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate -# file names in lower case letters. If set to YES upper case letters are also -# allowed. This is useful if you have classes or files whose names only differ -# in case and if your file system supports case sensitive file names. Windows -# users are adviced to set this option to NO. - -CASE_SENSE_NAMES = YES - -# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen -# will show members with their full class and namespace scopes in the -# documentation. If set to YES the scope will be hidden. - -HIDE_SCOPE_NAMES = NO - -# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen -# will generate a verbatim copy of the header file for each class for -# which an include is specified. Set to NO to disable this. - -VERBATIM_HEADERS = YES - -# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen -# will put list of the files that are included by a file in the documentation -# of that file. - -SHOW_INCLUDE_FILES = YES - -# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen -# will interpret the first line (until the first dot) of a JavaDoc-style -# comment as the brief description. If set to NO, the JavaDoc -# comments will behave just like the Qt-style comments (thus requiring an -# explict @brief command for a brief description. - -JAVADOC_AUTOBRIEF = YES - -# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented -# member inherits the documentation from any documented member that it -# reimplements. - -INHERIT_DOCS = YES - -# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] -# is inserted in the documentation for inline members. - -INLINE_INFO = YES - -# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen -# will sort the (detailed) documentation of file and class members -# alphabetically by member name. If set to NO the members will appear in -# declaration order. - -SORT_MEMBER_DOCS = YES - -# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC -# tag is set to YES, then doxygen will reuse the documentation of the first -# member in the group (if any) for the other members of the group. By default -# all members of a group must be documented explicitly. - -DISTRIBUTE_GROUP_DOC = NO - -# The TAB_SIZE tag can be used to set the number of spaces in a tab. -# Doxygen uses this value to replace tabs by spaces in code fragments. - -TAB_SIZE = 8 - -# The ENABLE_SECTIONS tag can be used to enable conditional -# documentation sections, marked by \if sectionname ... \endif. - -ENABLED_SECTIONS = - -# The GENERATE_TODOLIST tag can be used to enable (YES) or -# disable (NO) the todo list. This list is created by putting \todo -# commands in the documentation. - -GENERATE_TODOLIST = YES - -# The GENERATE_TESTLIST tag can be used to enable (YES) or -# disable (NO) the test list. This list is created by putting \test -# commands in the documentation. - -GENERATE_TESTLIST = YES - -# This tag can be used to specify a number of aliases that acts -# as commands in the documentation. An alias has the form "name=value". -# For example adding "sideeffect=\par Side Effects:\n" will allow you to -# put the command \sideeffect (or @sideeffect) in the documentation, which -# will result in a user defined paragraph with heading "Side Effects:". -# You can put \n's in the value part of an alias to insert newlines. - -ALIASES = - -#--------------------------------------------------------------------------- -# configuration options related to warning and progress messages -#--------------------------------------------------------------------------- - -# The QUIET tag can be used to turn on/off the messages that are generated -# by doxygen. Possible values are YES and NO. If left blank NO is used. - -QUIET = NO - -# The WARNINGS tag can be used to turn on/off the warning messages that are -# generated by doxygen. Possible values are YES and NO. If left blank -# NO is used. - -WARNINGS = YES - -# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings -# for undocumented members. If EXTRACT_ALL is set to YES then this flag will -# automatically be disabled. - -WARN_IF_UNDOCUMENTED = YES - -# The WARN_FORMAT tag determines the format of the warning messages that -# doxygen can produce. The string should contain the $file, $line, and $text -# tags, which will be replaced by the file and line number from which the -# warning originated and the warning text. - -WARN_FORMAT = "$file:$line: $text" - -# The WARN_LOGFILE tag can be used to specify a file to which warning -# and error messages should be written. If left blank the output is written -# to stderr. - -WARN_LOGFILE = - -#--------------------------------------------------------------------------- -# configuration options related to the input files -#--------------------------------------------------------------------------- - -# The INPUT tag can be used to specify the files and/or directories that contain -# documented source files. You may enter file names like "myfile.cpp" or -# directories like "/usr/src/myproject". Separate the files or directories -# with spaces. - -INPUT = . - - -# If the value of the INPUT tag contains directories, you can use the -# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp -# and *.h) to filter out the source-files in the directories. If left -# blank all files are included. - -FILE_PATTERNS = *.h *.cpp *.c - -# The RECURSIVE tag can be used to turn specify whether or not subdirectories -# should be searched for input files as well. Possible values are YES and NO. -# If left blank NO is used. - -RECURSIVE = YES - -# The EXCLUDE tag can be used to specify files and/or directories that should -# excluded from the INPUT source files. This way you can easily exclude a -# subdirectory from a directory tree whose root is specified with the INPUT tag. - -EXCLUDE = - -# If the value of the INPUT tag contains directories, you can use the -# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude -# certain files from those directories. - -EXCLUDE_PATTERNS = - -# The EXAMPLE_PATH tag can be used to specify one or more files or -# directories that contain example code fragments that are included (see -# the \include command). - -EXAMPLE_PATH = - -# If the value of the EXAMPLE_PATH tag contains directories, you can use the -# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp -# and *.h) to filter out the source-files in the directories. If left -# blank all files are included. - -EXAMPLE_PATTERNS = - -# The IMAGE_PATH tag can be used to specify one or more files or -# directories that contain image that are included in the documentation (see -# the \image command). - -IMAGE_PATH = - -# The INPUT_FILTER tag can be used to specify a program that doxygen should -# invoke to filter for each input file. Doxygen will invoke the filter program -# by executing (via popen()) the command , where -# is the value of the INPUT_FILTER tag, and is the name of an -# input file. Doxygen will then use the output that the filter program writes -# to standard output. - -INPUT_FILTER = - -# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using -# INPUT_FILTER) will be used to filter the input files when producing source -# files to browse. - -FILTER_SOURCE_FILES = NO - -#--------------------------------------------------------------------------- -# configuration options related to the alphabetical class index -#--------------------------------------------------------------------------- - -# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index -# of all compounds will be generated. Enable this if the project -# contains a lot of classes, structs, unions or interfaces. - -ALPHABETICAL_INDEX = NO - -# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then -# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns -# in which this list will be split (can be a number in the range [1..20]) - -COLS_IN_ALPHA_INDEX = 5 - -# In case all classes in a project start with a common prefix, all -# classes will be put under the same header in the alphabetical index. -# The IGNORE_PREFIX tag can be used to specify one or more prefixes that -# should be ignored while generating the index headers. - -IGNORE_PREFIX = - -#--------------------------------------------------------------------------- -# configuration options related to the HTML output -#--------------------------------------------------------------------------- - -# If the GENERATE_HTML tag is set to YES (the default) Doxygen will -# generate HTML output. - -GENERATE_HTML = YES - -# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `html' will be used as the default path. - -HTML_OUTPUT = html - -# The HTML_HEADER tag can be used to specify a personal HTML header for -# each generated HTML page. If it is left blank doxygen will generate a -# standard header. - -HTML_HEADER = - -# The HTML_FOOTER tag can be used to specify a personal HTML footer for -# each generated HTML page. If it is left blank doxygen will generate a -# standard footer. - -HTML_FOOTER = - -# The HTML_STYLESHEET tag can be used to specify a user defined cascading -# style sheet that is used by each HTML page. It can be used to -# fine-tune the look of the HTML output. If the tag is left blank doxygen -# will generate a default style sheet - -HTML_STYLESHEET = - -# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, -# files or namespaces will be aligned in HTML using tables. If set to -# NO a bullet list will be used. - -HTML_ALIGN_MEMBERS = YES - -# If the GENERATE_HTMLHELP tag is set to YES, additional index files -# will be generated that can be used as input for tools like the -# Microsoft HTML help workshop to generate a compressed HTML help file (.chm) -# of the generated HTML documentation. - -GENERATE_HTMLHELP = NO - -# The DISABLE_INDEX tag can be used to turn on/off the condensed index at -# top of each HTML page. The value NO (the default) enables the index and -# the value YES disables it. - -DISABLE_INDEX = NO - -# This tag can be used to set the number of enum values (range [1..20]) -# that doxygen will group on one line in the generated HTML documentation. - -ENUM_VALUES_PER_LINE = 4 - -# If the GENERATE_TREEVIEW tag is set to YES, a side pannel will be -# generated containing a tree-like index structure (just like the one that -# is generated for HTML Help). For this to work a browser that supports -# JavaScript and frames is required (for instance Netscape 4.0+ -# or Internet explorer 4.0+). - -GENERATE_TREEVIEW = NO - -# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be -# used to set the initial width (in pixels) of the frame in which the tree -# is shown. - -TREEVIEW_WIDTH = 250 - -#--------------------------------------------------------------------------- -# configuration options related to the LaTeX output -#--------------------------------------------------------------------------- - -# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will -# generate Latex output. - -GENERATE_LATEX = NO - -# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `latex' will be used as the default path. - -LATEX_OUTPUT = latex - -# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact -# LaTeX documents. This may be useful for small projects and may help to -# save some trees in general. - -COMPACT_LATEX = NO - -# The PAPER_TYPE tag can be used to set the paper type that is used -# by the printer. Possible values are: a4, a4wide, letter, legal and -# executive. If left blank a4wide will be used. - -PAPER_TYPE = a4wide - -# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX -# packages that should be included in the LaTeX output. - -EXTRA_PACKAGES = - -# The LATEX_HEADER tag can be used to specify a personal LaTeX header for -# the generated latex document. The header should contain everything until -# the first chapter. If it is left blank doxygen will generate a -# standard header. Notice: only use this tag if you know what you are doing! - -LATEX_HEADER = - -# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated -# is prepared for conversion to pdf (using ps2pdf). The pdf file will -# contain links (just like the HTML output) instead of page references -# This makes the output suitable for online browsing using a pdf viewer. - -PDF_HYPERLINKS = NO - -# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of -# plain latex in the generated Makefile. Set this option to YES to get a -# higher quality PDF documentation. - -USE_PDFLATEX = NO - -# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. -# command to the generated LaTeX files. This will instruct LaTeX to keep -# running if errors occur, instead of asking the user for help. -# This option is also used when generating formulas in HTML. - -LATEX_BATCHMODE = NO - -#--------------------------------------------------------------------------- -# configuration options related to the RTF output -#--------------------------------------------------------------------------- - -# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output -# The RTF output is optimised for Word 97 and may not look very pretty with -# other RTF readers or editors. - -GENERATE_RTF = NO - -# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `rtf' will be used as the default path. - -RTF_OUTPUT = rtf - -# If the COMPACT_RTF tag is set to YES Doxygen generates more compact -# RTF documents. This may be useful for small projects and may help to -# save some trees in general. - -COMPACT_RTF = NO - -# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated -# will contain hyperlink fields. The RTF file will -# contain links (just like the HTML output) instead of page references. -# This makes the output suitable for online browsing using a WORD or other. -# programs which support those fields. -# Note: wordpad (write) and others do not support links. - -RTF_HYPERLINKS = NO - -# Load stylesheet definitions from file. Syntax is similar to doxygen's -# config file, i.e. a series of assigments. You only have to provide -# replacements, missing definitions are set to their default value. - -RTF_STYLESHEET_FILE = - -#--------------------------------------------------------------------------- -# configuration options related to the man page output -#--------------------------------------------------------------------------- - -# If the GENERATE_MAN tag is set to YES (the default) Doxygen will -# generate man pages - -GENERATE_MAN = NO - -# The MAN_OUTPUT tag is used to specify where the man pages will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `man' will be used as the default path. - -MAN_OUTPUT = man - -# The MAN_EXTENSION tag determines the extension that is added to -# the generated man pages (default is the subroutine's section .3) - -MAN_EXTENSION = .3 - -#--------------------------------------------------------------------------- -# configuration options related to the XML output -#--------------------------------------------------------------------------- - -# If the GENERATE_XML tag is set to YES Doxygen will -# generate an XML file that captures the structure of -# the code including all documentation. Warning: This feature -# is still experimental and very incomplete. - -GENERATE_XML = NO - -#--------------------------------------------------------------------------- -# Configuration options related to the preprocessor -#--------------------------------------------------------------------------- - -# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will -# evaluate all C-preprocessor directives found in the sources and include -# files. - -ENABLE_PREPROCESSING = YES - -# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro -# names in the source code. If set to NO (the default) only conditional -# compilation will be performed. Macro expansion can be done in a controlled -# way by setting EXPAND_ONLY_PREDEF to YES. - -MACRO_EXPANSION = NO - -# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES -# then the macro expansion is limited to the macros specified with the -# PREDEFINED and EXPAND_AS_PREDEFINED tags. - -EXPAND_ONLY_PREDEF = NO - -# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files -# in the INCLUDE_PATH (see below) will be search if a #include is found. - -SEARCH_INCLUDES = YES - -# The INCLUDE_PATH tag can be used to specify one or more directories that -# contain include files that are not input files but should be processed by -# the preprocessor. - -INCLUDE_PATH = ../../generic/extern - -# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard -# patterns (like *.h and *.hpp) to filter out the header-files in the -# directories. If left blank, the patterns specified with FILE_PATTERNS will -# be used. - -INCLUDE_FILE_PATTERNS = - -# The PREDEFINED tag can be used to specify one or more macro names that -# are defined before the preprocessor is started (similar to the -D option of -# gcc). The argument of the tag is a list of macros of the form: name -# or name=definition (no spaces). If the definition and the = are -# omitted =1 is assumed. - -PREDEFINED = - -# If the MACRO_EXPANSION and EXPAND_PREDEF_ONLY tags are set to YES then -# this tag can be used to specify a list of macro names that should be expanded. -# The macro definition that is found in the sources will be used. -# Use the PREDEFINED tag if you want to use a different macro definition. - -EXPAND_AS_DEFINED = - -#--------------------------------------------------------------------------- -# Configuration::addtions related to external references -#--------------------------------------------------------------------------- - -# The TAGFILES tag can be used to specify one or more tagfiles. - -TAGFILES = - -# When a file name is specified after GENERATE_TAGFILE, doxygen will create -# a tag file that is based on the input files it reads. - -GENERATE_TAGFILE = - -# If the ALLEXTERNALS tag is set to YES all external classes will be listed -# in the class index. If set to NO only the inherited external classes -# will be listed. - -ALLEXTERNALS = NO - -# The PERL_PATH should be the absolute path and name of the perl script -# interpreter (i.e. the result of `which perl'). - -PERL_PATH = /usr/bin/perl - -#--------------------------------------------------------------------------- -# Configuration options related to the dot tool -#--------------------------------------------------------------------------- - -# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is -# available from the path. This tool is part of Graphviz, a graph visualization -# toolkit from AT&T and Lucent Bell Labs. The other options in this section -# have no effect if this option is set to NO (the default) - -HAVE_DOT = YES - -# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen -# will generate a graph for each documented class showing the direct and -# indirect inheritance relations. Setting this tag to YES will force the -# the CLASS_DIAGRAMS tag to NO. - -CLASS_GRAPH = YES - -# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen -# will generate a graph for each documented class showing the direct and -# indirect implementation dependencies (inheritance, containment, and -# class references variables) of the class with other documented classes. - -COLLABORATION_GRAPH = YES - -# If the ENABLE_PREPROCESSING, INCLUDE_GRAPH, and HAVE_DOT tags are set to -# YES then doxygen will generate a graph for each documented file showing -# the direct and indirect include dependencies of the file with other -# documented files. - -INCLUDE_GRAPH = YES - -# If the ENABLE_PREPROCESSING, INCLUDED_BY_GRAPH, and HAVE_DOT tags are set to -# YES then doxygen will generate a graph for each documented header file showing -# the documented files that directly or indirectly include this file - -INCLUDED_BY_GRAPH = YES - -# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen -# will graphical hierarchy of all classes instead of a textual one. - -GRAPHICAL_HIERARCHY = YES - -# The tag DOT_PATH can be used to specify the path where the dot tool can be -# found. If left blank, it is assumed the dot tool can be found on the path. - -DOT_PATH = - -# The MAX_DOT_GRAPH_WIDTH tag can be used to set the maximum allowed width -# (in pixels) of the graphs generated by dot. If a graph becomes larger than -# this value, doxygen will try to truncate the graph, so that it fits within -# the specified constraint. Beware that most browsers cannot cope with very -# large images. - -MAX_DOT_GRAPH_WIDTH = 1024 - -# The MAX_DOT_GRAPH_HEIGHT tag can be used to set the maximum allows height -# (in pixels) of the graphs generated by dot. If a graph becomes larger than -# this value, doxygen will try to truncate the graph, so that it fits within -# the specified constraint. Beware that most browsers cannot cope with very -# large images. - -MAX_DOT_GRAPH_HEIGHT = 1024 - -# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will -# generate a legend page explaining the meaning of the various boxes and -# arrows in the dot generated graphs. - -GENERATE_LEGEND = YES - -#--------------------------------------------------------------------------- -# Configuration::addtions related to the search engine -#--------------------------------------------------------------------------- - -# The SEARCHENGINE tag specifies whether or not a search engine should be -# used. If set to NO the values of all tags below this one will be ignored. - -SEARCHENGINE = NO - -# The CGI_NAME tag should be the name of the CGI script that -# starts the search engine (doxysearch) with the correct parameters. -# A script with this name will be generated by doxygen. - -CGI_NAME = search.cgi - -# The CGI_URL tag should be the absolute URL to the directory where the -# cgi binaries are located. See the documentation of your http daemon for -# details. - -CGI_URL = - -# The DOC_URL tag should be the absolute URL to the directory where the -# documentation is located. If left blank the absolute path to the -# documentation, with file:// prepended to it, will be used. - -DOC_URL = - -# The DOC_ABSPATH tag should be the absolute path to the directory where the -# documentation is located. If left blank the directory on the local machine -# will be used. - -DOC_ABSPATH = - -# The BIN_ABSPATH tag must point to the directory where the doxysearch binary -# is installed. - -BIN_ABSPATH = c:\program files\doxygen\bin - -# The EXT_DOC_PATHS tag can be used to specify one or more paths to -# documentation generated for other projects. This allows doxysearch to search -# the documentation for these projects as well. - -EXT_DOC_PATHS = diff --git a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btContinuousConvexCollision.cpp b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btContinuousConvexCollision.cpp deleted file mode 100644 index c6a2b396d78..00000000000 --- a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btContinuousConvexCollision.cpp +++ /dev/null @@ -1,210 +0,0 @@ -/* -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 "btContinuousConvexCollision.h" -#include "BulletCollision/CollisionShapes/btConvexShape.h" -#include "BulletCollision/CollisionShapes/btMinkowskiSumShape.h" -#include "BulletCollision/NarrowPhaseCollision/btSimplexSolverInterface.h" -#include "LinearMath/btTransformUtil.h" -#include "BulletCollision/CollisionShapes/btSphereShape.h" - -#include "btGjkPairDetector.h" -#include "btPointCollector.h" - - - -btContinuousConvexCollision::btContinuousConvexCollision ( const btConvexShape* convexA,const btConvexShape* convexB,btSimplexSolverInterface* simplexSolver, btConvexPenetrationDepthSolver* penetrationDepthSolver) -:m_simplexSolver(simplexSolver), -m_penetrationDepthSolver(penetrationDepthSolver), -m_convexA(convexA),m_convexB(convexB) -{ -} - -/// This maximum should not be necessary. It allows for untested/degenerate cases in production code. -/// You don't want your game ever to lock-up. -#define MAX_ITERATIONS 1000 - -bool btContinuousConvexCollision::calcTimeOfImpact( - const btTransform& fromA, - const btTransform& toA, - const btTransform& fromB, - const btTransform& toB, - CastResult& result) -{ - - m_simplexSolver->reset(); - - /// compute linear and angular velocity for this interval, to interpolate - btVector3 linVelA,angVelA,linVelB,angVelB; - btTransformUtil::calculateVelocity(fromA,toA,btScalar(1.),linVelA,angVelA); - btTransformUtil::calculateVelocity(fromB,toB,btScalar(1.),linVelB,angVelB); - - btScalar boundingRadiusA = m_convexA->getAngularMotionDisc(); - btScalar boundingRadiusB = m_convexB->getAngularMotionDisc(); - - btScalar maxAngularProjectedVelocity = angVelA.length() * boundingRadiusA + angVelB.length() * boundingRadiusB; - - btScalar radius = btScalar(0.001); - - btScalar lambda = btScalar(0.); - btVector3 v(1,0,0); - - int maxIter = MAX_ITERATIONS; - - btVector3 n; - n.setValue(btScalar(0.),btScalar(0.),btScalar(0.)); - bool hasResult = false; - btVector3 c; - - btScalar lastLambda = lambda; - //btScalar epsilon = btScalar(0.001); - - int numIter = 0; - //first solution, using GJK - - - btTransform identityTrans; - identityTrans.setIdentity(); - - btSphereShape raySphere(btScalar(0.0)); - raySphere.setMargin(btScalar(0.)); - - -// result.drawCoordSystem(sphereTr); - - btPointCollector pointCollector1; - - { - - btGjkPairDetector gjk(m_convexA,m_convexB,m_simplexSolver,m_penetrationDepthSolver); - btGjkPairDetector::ClosestPointInput input; - - //we don't use margins during CCD - // gjk.setIgnoreMargin(true); - - input.m_transformA = fromA; - input.m_transformB = fromB; - gjk.getClosestPoints(input,pointCollector1,0); - - hasResult = pointCollector1.m_hasResult; - c = pointCollector1.m_pointInWorld; - } - - if (hasResult) - { - btScalar dist; - dist = pointCollector1.m_distance; - n = pointCollector1.m_normalOnBInWorld; - - - - //not close enough - while (dist > radius) - { - numIter++; - if (numIter > maxIter) - { - return false; //todo: report a failure - } - btScalar dLambda = btScalar(0.); - - btScalar projectedLinearVelocity = (linVelB-linVelA).dot(n); - - //calculate safe moving fraction from distance / (linear+rotational velocity) - - //btScalar clippedDist = GEN_min(angularConservativeRadius,dist); - //btScalar clippedDist = dist; - - - dLambda = dist / (projectedLinearVelocity+ maxAngularProjectedVelocity); - - lambda = lambda + dLambda; - - if (lambda > btScalar(1.)) - return false; - - if (lambda < btScalar(0.)) - return false; - - - //todo: next check with relative epsilon - if (lambda <= lastLambda) - { - return false; - //n.setValue(0,0,0); - break; - } - lastLambda = lambda; - - - - //interpolate to next lambda - btTransform interpolatedTransA,interpolatedTransB,relativeTrans; - - btTransformUtil::integrateTransform(fromA,linVelA,angVelA,lambda,interpolatedTransA); - btTransformUtil::integrateTransform(fromB,linVelB,angVelB,lambda,interpolatedTransB); - relativeTrans = interpolatedTransB.inverseTimes(interpolatedTransA); - - result.DebugDraw( lambda ); - - btPointCollector pointCollector; - btGjkPairDetector gjk(m_convexA,m_convexB,m_simplexSolver,m_penetrationDepthSolver); - btGjkPairDetector::ClosestPointInput input; - input.m_transformA = interpolatedTransA; - input.m_transformB = interpolatedTransB; - gjk.getClosestPoints(input,pointCollector,0); - if (pointCollector.m_hasResult) - { - if (pointCollector.m_distance < btScalar(0.)) - { - //degenerate ?! - result.m_fraction = lastLambda; - n = pointCollector.m_normalOnBInWorld; - result.m_normal=n;//.setValue(1,1,1);// = n; - return true; - } - c = pointCollector.m_pointInWorld; - n = pointCollector.m_normalOnBInWorld; - dist = pointCollector.m_distance; - } else - { - //?? - return false; - } - - } - - result.m_fraction = lambda; - result.m_normal = n; - return true; - } - - return false; - -/* -//todo: - //if movement away from normal, discard result - btVector3 move = transBLocalTo.getOrigin() - transBLocalFrom.getOrigin(); - if (result.m_fraction < btScalar(1.)) - { - if (move.dot(result.m_normal) <= btScalar(0.)) - { - } - } -*/ - -} - diff --git a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btContinuousConvexCollision.h b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btContinuousConvexCollision.h deleted file mode 100644 index 28c2b4d6156..00000000000 --- a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btContinuousConvexCollision.h +++ /dev/null @@ -1,52 +0,0 @@ -/* -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 CONTINUOUS_COLLISION_CONVEX_CAST_H -#define CONTINUOUS_COLLISION_CONVEX_CAST_H - -#include "btConvexCast.h" -#include "btSimplexSolverInterface.h" -class btConvexPenetrationDepthSolver; -class btConvexShape; - -/// btContinuousConvexCollision implements angular and linear time of impact for convex objects. -/// Based on Brian Mirtich's Conservative Advancement idea (PhD thesis). -/// Algorithm operates in worldspace, in order to keep inbetween motion globally consistent. -/// It uses GJK at the moment. Future improvement would use minkowski sum / supporting vertex, merging innerloops -class btContinuousConvexCollision : public btConvexCast -{ - btSimplexSolverInterface* m_simplexSolver; - btConvexPenetrationDepthSolver* m_penetrationDepthSolver; - const btConvexShape* m_convexA; - const btConvexShape* m_convexB; - - -public: - - btContinuousConvexCollision (const btConvexShape* shapeA,const btConvexShape* shapeB ,btSimplexSolverInterface* simplexSolver,btConvexPenetrationDepthSolver* penetrationDepthSolver); - - virtual bool calcTimeOfImpact( - const btTransform& fromA, - const btTransform& toA, - const btTransform& fromB, - const btTransform& toB, - CastResult& result); - - -}; - -#endif //CONTINUOUS_COLLISION_CONVEX_CAST_H - diff --git a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btConvexCast.cpp b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btConvexCast.cpp deleted file mode 100644 index d2a1310b232..00000000000 --- a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btConvexCast.cpp +++ /dev/null @@ -1,20 +0,0 @@ -/* -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 "btConvexCast.h" - -btConvexCast::~btConvexCast() -{ -} diff --git a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btConvexCast.h b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btConvexCast.h deleted file mode 100644 index cc80f0aa8da..00000000000 --- a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btConvexCast.h +++ /dev/null @@ -1,71 +0,0 @@ -/* -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 CONVEX_CAST_H -#define CONVEX_CAST_H - -#include "LinearMath/btTransform.h" -#include "LinearMath/btVector3.h" -#include "LinearMath/btScalar.h" -class btMinkowskiSumShape; -#include "LinearMath/btIDebugDraw.h" - -/// btConvexCast is an interface for Casting -class btConvexCast -{ -public: - - - virtual ~btConvexCast(); - - ///RayResult stores the closest result - /// alternatively, add a callback method to decide about closest/all results - struct CastResult - { - //virtual bool addRayResult(const btVector3& normal,btScalar fraction) = 0; - - virtual void DebugDraw(btScalar fraction) {(void)fraction;} - virtual void drawCoordSystem(const btTransform& trans) {(void)trans;} - - CastResult() - :m_fraction(btScalar(1e30)), - m_debugDrawer(0) - { - } - - - virtual ~CastResult() {}; - - btVector3 m_normal; - btScalar m_fraction; - btTransform m_hitTransformA; - btTransform m_hitTransformB; - - btIDebugDraw* m_debugDrawer; - - }; - - - /// cast a convex against another convex object - virtual bool calcTimeOfImpact( - const btTransform& fromA, - const btTransform& toA, - const btTransform& fromB, - const btTransform& toB, - CastResult& result) = 0; -}; - -#endif //CONVEX_CAST_H diff --git a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btConvexPenetrationDepthSolver.h b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btConvexPenetrationDepthSolver.h deleted file mode 100644 index 99690921317..00000000000 --- a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btConvexPenetrationDepthSolver.h +++ /dev/null @@ -1,43 +0,0 @@ -/* -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 CONVEX_PENETRATION_DEPTH_H -#define CONVEX_PENETRATION_DEPTH_H - -class btStackAlloc; -class btVector3; -#include "btSimplexSolverInterface.h" -class btConvexShape; -#include "LinearMath/btPoint3.h" -class btTransform; - -///ConvexPenetrationDepthSolver provides an interface for penetration depth calculation. -class btConvexPenetrationDepthSolver -{ -public: - - virtual ~btConvexPenetrationDepthSolver() {}; - virtual bool calcPenDepth( btSimplexSolverInterface& simplexSolver, - const btConvexShape* convexA,const btConvexShape* convexB, - const btTransform& transA,const btTransform& transB, - btVector3& v, btPoint3& pa, btPoint3& pb, - class btIDebugDraw* debugDraw,btStackAlloc* stackAlloc - ) = 0; - - -}; -#endif //CONVEX_PENETRATION_DEPTH_H - diff --git a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btDiscreteCollisionDetectorInterface.h b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btDiscreteCollisionDetectorInterface.h deleted file mode 100644 index f11c8bd1290..00000000000 --- a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btDiscreteCollisionDetectorInterface.h +++ /dev/null @@ -1,88 +0,0 @@ -/* -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 DISCRETE_COLLISION_DETECTOR1_INTERFACE_H -#define DISCRETE_COLLISION_DETECTOR1_INTERFACE_H -#include "LinearMath/btTransform.h" -#include "LinearMath/btVector3.h" -class btStackAlloc; - -/// This interface is made to be used by an iterative approach to do TimeOfImpact calculations -/// This interface allows to query for closest points and penetration depth between two (convex) objects -/// the closest point is on the second object (B), and the normal points from the surface on B towards A. -/// distance is between closest points on B and closest point on A. So you can calculate closest point on A -/// by taking closestPointInA = closestPointInB + m_distance * m_normalOnSurfaceB -struct btDiscreteCollisionDetectorInterface -{ - - struct Result - { - - virtual ~Result(){} - - ///setShapeIdentifiers provides experimental support for per-triangle material / custom material combiner - virtual void setShapeIdentifiers(int partId0,int index0, int partId1,int index1)=0; - virtual void addContactPoint(const btVector3& normalOnBInWorld,const btVector3& pointInWorld,btScalar depth)=0; - }; - - struct ClosestPointInput - { - ClosestPointInput() - :m_maximumDistanceSquared(btScalar(1e30)), - m_stackAlloc(0) - { - } - - btTransform m_transformA; - btTransform m_transformB; - btScalar m_maximumDistanceSquared; - btStackAlloc* m_stackAlloc; - }; - - virtual ~btDiscreteCollisionDetectorInterface() {}; - - // - // give either closest points (distance > 0) or penetration (distance) - // the normal always points from B towards A - // - virtual void getClosestPoints(const ClosestPointInput& input,Result& output,class btIDebugDraw* debugDraw) = 0; - -}; - -struct btStorageResult : public btDiscreteCollisionDetectorInterface::Result -{ - btVector3 m_normalOnSurfaceB; - btVector3 m_closestPointInB; - btScalar m_distance; //negative means penetration ! - - btStorageResult() : m_distance(btScalar(1e30)) - { - - } - virtual ~btStorageResult() {}; - - virtual void addContactPoint(const btVector3& normalOnBInWorld,const btVector3& pointInWorld,btScalar depth) - { - if (depth < m_distance) - { - m_normalOnSurfaceB = normalOnBInWorld; - m_closestPointInB = pointInWorld; - m_distance = depth; - } - } -}; - -#endif //DISCRETE_COLLISION_DETECTOR_INTERFACE1_H diff --git a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkConvexCast.cpp b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkConvexCast.cpp deleted file mode 100644 index da2a02b9839..00000000000 --- a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkConvexCast.cpp +++ /dev/null @@ -1,174 +0,0 @@ -/* -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 "btGjkConvexCast.h" -#include "BulletCollision/CollisionShapes/btSphereShape.h" -#include "BulletCollision/CollisionShapes/btMinkowskiSumShape.h" -#include "btGjkPairDetector.h" -#include "btPointCollector.h" - - -btGjkConvexCast::btGjkConvexCast(const btConvexShape* convexA,const btConvexShape* convexB,btSimplexSolverInterface* simplexSolver) -:m_simplexSolver(simplexSolver), -m_convexA(convexA), -m_convexB(convexB) -{ -} - -bool btGjkConvexCast::calcTimeOfImpact( - const btTransform& fromA, - const btTransform& toA, - const btTransform& fromB, - const btTransform& toB, - CastResult& result) -{ - - - btMinkowskiSumShape combi(m_convexA,m_convexB); - btMinkowskiSumShape* convex = &combi; - - btTransform rayFromLocalA; - btTransform rayToLocalA; - - rayFromLocalA = fromA.inverse()* fromB; - rayToLocalA = toA.inverse()* toB; - - - btTransform trA,trB; - trA = btTransform(fromA); - trB = btTransform(fromB); - trA.setOrigin(btPoint3(0,0,0)); - trB.setOrigin(btPoint3(0,0,0)); - - convex->setTransformA(trA); - convex->setTransformB(trB); - - - - - btScalar radius = btScalar(0.01); - - btScalar lambda = btScalar(0.); - btVector3 s = rayFromLocalA.getOrigin(); - btVector3 r = rayToLocalA.getOrigin()-rayFromLocalA.getOrigin(); - btVector3 x = s; - btVector3 n; - n.setValue(0,0,0); - bool hasResult = false; - btVector3 c; - - btScalar lastLambda = lambda; - - //first solution, using GJK - - //no penetration support for now, perhaps pass a pointer when we really want it - btConvexPenetrationDepthSolver* penSolverPtr = 0; - - btTransform identityTrans; - identityTrans.setIdentity(); - - btSphereShape raySphere(btScalar(0.0)); - raySphere.setMargin(btScalar(0.)); - - btTransform sphereTr; - sphereTr.setIdentity(); - sphereTr.setOrigin( rayFromLocalA.getOrigin()); - - result.drawCoordSystem(sphereTr); - { - btPointCollector pointCollector1; - btGjkPairDetector gjk(&raySphere,convex,m_simplexSolver,penSolverPtr); - - btGjkPairDetector::ClosestPointInput input; - input.m_transformA = sphereTr; - input.m_transformB = identityTrans; - gjk.getClosestPoints(input,pointCollector1,0); - - hasResult = pointCollector1.m_hasResult; - c = pointCollector1.m_pointInWorld; - n = pointCollector1.m_normalOnBInWorld; - } - - - - if (hasResult) - { - btScalar dist; - dist = (c-x).length(); - if (dist < radius) - { - //penetration - lastLambda = btScalar(1.); - } - - //not close enough - while (dist > radius) - { - - n = x - c; - btScalar nDotr = n.dot(r); - - if (nDotr >= -(SIMD_EPSILON*SIMD_EPSILON)) - return false; - - lambda = lambda - n.dot(n) / nDotr; - if (lambda <= lastLambda) - break; - - lastLambda = lambda; - - x = s + lambda * r; - - sphereTr.setOrigin( x ); - result.drawCoordSystem(sphereTr); - btPointCollector pointCollector; - btGjkPairDetector gjk(&raySphere,convex,m_simplexSolver,penSolverPtr); - btGjkPairDetector::ClosestPointInput input; - input.m_transformA = sphereTr; - input.m_transformB = identityTrans; - gjk.getClosestPoints(input,pointCollector,0); - if (pointCollector.m_hasResult) - { - if (pointCollector.m_distance < btScalar(0.)) - { - //degeneracy, report a hit - result.m_fraction = lastLambda; - result.m_normal = n; - return true; - } - c = pointCollector.m_pointInWorld; - dist = (c-x).length(); - } else - { - //?? - return false; - } - - } - - if (lastLambda < btScalar(1.)) - { - - result.m_fraction = lastLambda; - result.m_normal = n; - return true; - } - } - - return false; -} - diff --git a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkConvexCast.h b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkConvexCast.h deleted file mode 100644 index a977c9e83f7..00000000000 --- a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkConvexCast.h +++ /dev/null @@ -1,50 +0,0 @@ -/* -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 GJK_CONVEX_CAST_H -#define GJK_CONVEX_CAST_H - -#include "BulletCollision/CollisionShapes/btCollisionMargin.h" - -#include "LinearMath/btVector3.h" -#include "btConvexCast.h" -class btConvexShape; -class btMinkowskiSumShape; -#include "btSimplexSolverInterface.h" - -///GjkConvexCast performs a raycast on a convex object using support mapping. -class btGjkConvexCast : public btConvexCast -{ - btSimplexSolverInterface* m_simplexSolver; - const btConvexShape* m_convexA; - const btConvexShape* m_convexB; - -public: - - btGjkConvexCast(const btConvexShape* convexA,const btConvexShape* convexB,btSimplexSolverInterface* simplexSolver); - - /// cast a convex against another convex object - virtual bool calcTimeOfImpact( - const btTransform& fromA, - const btTransform& toA, - const btTransform& fromB, - const btTransform& toB, - CastResult& result); - -}; - -#endif //GJK_CONVEX_CAST_H diff --git a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkEpa.cpp b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkEpa.cpp deleted file mode 100644 index f57868be044..00000000000 --- a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkEpa.cpp +++ /dev/null @@ -1,628 +0,0 @@ -/* -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. -*/ - -/* -GJK-EPA collision solver by Nathanael Presson -Nov.2006 -*/ - -#include "btGjkEpa.h" -#include //for memset -#include - -#if defined(DEBUG) || defined (_DEBUG) -#include //for debug printf -#ifdef __SPU__ -#include -#define printf spu_printf -#endif //__SPU__ -#endif - -namespace gjkepa_impl -{ - -// -// Port. typedefs -// - -typedef btScalar F; -typedef bool Z; -typedef int I; -typedef unsigned int U; -typedef unsigned char U1; -typedef unsigned short U2; - -typedef btVector3 Vector3; -typedef btMatrix3x3 Rotation; - -// -// Config -// - -#if 0 -#define BTLOCALSUPPORT localGetSupportingVertexWithoutMargin -#else -#define BTLOCALSUPPORT localGetSupportingVertex -#endif - -// -// Const -// - - -#define cstInf SIMD_INFINITY -#define cstPi SIMD_PI -#define cst2Pi SIMD_2_PI -#define GJK_maxiterations (128) -#define GJK_hashsize (1<<6) -#define GJK_hashmask (GJK_hashsize-1) -#define GJK_insimplex_eps F(0.0001) -#define GJK_sqinsimplex_eps (GJK_insimplex_eps*GJK_insimplex_eps) -#define EPA_maxiterations 256 -#define EPA_inface_eps F(0.01) -#define EPA_accuracy F(0.001) - -// -// Utils -// - -static inline F Abs(F v) { return(v<0?-v:v); } -static inline F Sign(F v) { return(F(v<0?-1:1)); } -template static inline void Swap(T& a,T& b) { T -t(a);a=b;b=t; } -template static inline T Min(const T& a,const T& b) { -return(a static inline T Max(const T& a,const T& b) { -return(a>b?a:b); } -static inline void ClearMemory(void* p,U sz) { memset(p,0,(size_t)sz); -} -#if 0 -template static inline void Raise(const T& object) { -throw(object); } -#else -template static inline void Raise(const T&) {} -#endif - - - -// -// GJK -// -struct GJK - { - struct Mkv - { - Vector3 w; /* Minkowski vertice */ - Vector3 r; /* Ray */ - }; - struct He - { - Vector3 v; - He* n; - }; - btStackAlloc* sa; - btBlock* sablock; - He* table[GJK_hashsize]; - Rotation wrotations[2]; - Vector3 positions[2]; - const btConvexShape* shapes[2]; - Mkv simplex[5]; - Vector3 ray; - U order; - U iterations; - F margin; - Z failed; - // - GJK(btStackAlloc* psa, - const Rotation& wrot0,const Vector3& pos0,const btConvexShape* shape0, - const Rotation& wrot1,const Vector3& pos1,const btConvexShape* shape1, - F pmargin=0) - { - wrotations[0]=wrot0;positions[0]=pos0;shapes[0]=shape0; - wrotations[1]=wrot1;positions[1]=pos1;shapes[1]=shape1; - sa =psa; - sablock =sa->beginBlock(); - margin =pmargin; - failed =false; - } - // - ~GJK() - { - sa->endBlock(sablock); - } - // vdh : very dumm hash - static inline U Hash(const Vector3& v) - { - //this doesn't compile under GCC 3.3.5, so add the ()... - //const U h(U(v[0]*15461)^U(v[1]*83003)^U(v[2]*15473)); - //return(((*((const U*)&h))*169639)&GJK_hashmask); - const U h((U)(v[0]*15461)^(U)(v[1]*83003)^(U)(v[2]*15473)); - return(((*((const U*)&h))*169639)&GJK_hashmask); - } - // - inline Vector3 LocalSupport(const Vector3& d,U i) const - { - return(wrotations[i]*shapes[i]->BTLOCALSUPPORT(d*wrotations[i])+positions[i]); - } - // - inline void Support(const Vector3& d,Mkv& v) const - { - v.r = d; - v.w = LocalSupport(d,0)-LocalSupport(-d,1)+d*margin; - } - #define SPX(_i_) simplex[_i_] - #define SPXW(_i_) simplex[_i_].w - // - inline Z FetchSupport() - { - const U h(Hash(ray)); - He* e = (He*)(table[h]); - while(e) { if(e->v==ray) { --order;return(false); } else e=e->n; } - e=(He*)sa->allocate(sizeof(He));e->v=ray;e->n=table[h];table[h]=e; - Support(ray,simplex[++order]); - return(ray.dot(SPXW(order))>0); - } - // - inline Z SolveSimplex2(const Vector3& ao,const Vector3& ab) - { - if(ab.dot(ao)>=0) - { - const Vector3 cabo(cross(ab,ao)); - if(cabo.length2()>GJK_sqinsimplex_eps) - { ray=cross(cabo,ab); } - else - { return(true); } - } - else - { order=0;SPX(0)=SPX(1);ray=ao; } - return(false); - } - // - inline Z SolveSimplex3(const Vector3& ao,const Vector3& ab,const Vector3& -ac) - { - return(SolveSimplex3a(ao,ab,ac,cross(ab,ac))); - } - // - inline Z SolveSimplex3a(const Vector3& ao,const Vector3& ab,const Vector3& -ac,const Vector3& cabc) - { - if((cross(cabc,ab)).dot(ao)<-GJK_insimplex_eps) - { order=1;SPX(0)=SPX(1);SPX(1)=SPX(2);return(SolveSimplex2(ao,ab)); } - else if((cross(cabc,ac)).dot(ao)>+GJK_insimplex_eps) - { order=1;SPX(1)=SPX(2);return(SolveSimplex2(ao,ac)); } - else - { - const F d(cabc.dot(ao)); - if(Abs(d)>GJK_insimplex_eps) - { - if(d>0) - { ray=cabc; } - else - { ray=-cabc;Swap(SPX(0),SPX(1)); } - return(false); - } else return(true); - } - } - // - inline Z SolveSimplex4(const Vector3& ao,const Vector3& ab,const Vector3& -ac,const Vector3& ad) - { - Vector3 crs; - if((crs=cross(ab,ac)).dot(ao)>GJK_insimplex_eps) - { -order=2;SPX(0)=SPX(1);SPX(1)=SPX(2);SPX(2)=SPX(3);return(SolveSimplex3a(ao,ab,ac,crs)); -} - else if((crs=cross(ac,ad)).dot(ao)>GJK_insimplex_eps) - { order=2;SPX(2)=SPX(3);return(SolveSimplex3a(ao,ac,ad,crs)); } - else if((crs=cross(ad,ab)).dot(ao)>GJK_insimplex_eps) - { -order=2;SPX(1)=SPX(0);SPX(0)=SPX(2);SPX(2)=SPX(3);return(SolveSimplex3a(ao,ad,ab,crs)); -} - else return(true); - } - // - inline Z SearchOrigin(const Vector3& initray=Vector3(1,0,0)) - { - iterations = 0; - order = (U)-1; - failed = false; - ray = initray.normalized(); - ClearMemory(table,sizeof(void*)*GJK_hashsize); - FetchSupport(); - ray = -SPXW(0); - for(;iterations0?rl:1; - if(FetchSupport()) - { - Z found(false); - switch(order) - { - case 1: found=SolveSimplex2(-SPXW(1),SPXW(0)-SPXW(1));break; - case 2: found=SolveSimplex3(-SPXW(2),SPXW(1)-SPXW(2),SPXW(0)-SPXW(2));break; - case 3: found=SolveSimplex4(-SPXW(3),SPXW(2)-SPXW(3),SPXW(1)-SPXW(3),SPXW(0)-SPXW(3));break; - } - if(found) return(true); - } else return(false); - } - failed=true; - return(false); - } - // - inline Z EncloseOrigin() - { - switch(order) - { - /* Point */ - case 0: break; - /* Line */ - case 1: - { - const Vector3 ab(SPXW(1)-SPXW(0)); - const Vector3 b[]={ cross(ab,Vector3(1,0,0)), - cross(ab,Vector3(0,1,0)), - cross(ab,Vector3(0,0,1))}; - const F m[]={b[0].length2(),b[1].length2(),b[2].length2()}; - const Rotation r(btQuaternion(ab.normalized(),cst2Pi/3)); - Vector3 w(b[m[0]>m[1]?m[0]>m[2]?0:2:m[1]>m[2]?1:2]); - Support(w.normalized(),simplex[4]);w=r*w; - Support(w.normalized(),simplex[2]);w=r*w; - Support(w.normalized(),simplex[3]);w=r*w; - order=4; - return(true); - } - break; - /* Triangle */ - case 2: - { - const -Vector3 n(cross((SPXW(1)-SPXW(0)),(SPXW(2)-SPXW(0))).normalized()); - Support( n,simplex[3]); - Support(-n,simplex[4]); - order=4; - return(true); - } - break; - /* Tetrahedron */ - case 3: return(true); - /* Hexahedron */ - case 4: return(true); - } - return(false); - } - #undef SPX - #undef SPXW - }; - -// -// EPA -// -struct EPA - { - // - struct Face - { - const GJK::Mkv* v[3]; - Face* f[3]; - U e[3]; - Vector3 n; - F d; - U mark; - Face* prev; - Face* next; - Face() {} - }; - // - GJK* gjk; - btStackAlloc* sa; - Face* root; - U nfaces; - U iterations; - Vector3 features[2][3]; - Vector3 nearest[2]; - Vector3 normal; - F depth; - Z failed; - // - EPA(GJK* pgjk) - { - gjk = pgjk; - sa = pgjk->sa; - } - // - ~EPA() - { - } - // - inline Vector3 GetCoordinates(const Face* face) const - { - const Vector3 o(face->n*-face->d); - const F a[]={ cross(face->v[0]->w-o,face->v[1]->w-o).length(), - cross(face->v[1]->w-o,face->v[2]->w-o).length(), - cross(face->v[2]->w-o,face->v[0]->w-o).length()}; - const F sm(a[0]+a[1]+a[2]); - return(Vector3(a[1],a[2],a[0])/(sm>0?sm:1)); - } - // - inline Face* FindBest() const - { - Face* bf = 0; - if(root) - { - Face* cf = root; - F bd(cstInf); - do { - if(cf->dd;bf=cf; } - } while(0!=(cf=cf->next)); - } - return(bf); - } - // - inline Z Set(Face* f,const GJK::Mkv* a,const GJK::Mkv* b,const GJK::Mkv* -c) const - { - const Vector3 nrm(cross(b->w-a->w,c->w-a->w)); - const F len(nrm.length()); - const Z valid( (cross(a->w,b->w).dot(nrm)>=-EPA_inface_eps)&& - (cross(b->w,c->w).dot(nrm)>=-EPA_inface_eps)&& - (cross(c->w,a->w).dot(nrm)>=-EPA_inface_eps)); - f->v[0] = a; - f->v[1] = b; - f->v[2] = c; - f->mark = 0; - f->n = nrm/(len>0?len:cstInf); - f->d = Max(0,-f->n.dot(a->w)); - return(valid); - } - // - inline Face* NewFace(const GJK::Mkv* a,const GJK::Mkv* b,const GJK::Mkv* c) - { - Face* pf = (Face*)sa->allocate(sizeof(Face)); - if(Set(pf,a,b,c)) - { - if(root) root->prev=pf; - pf->prev=0; - pf->next=root; - root =pf; - ++nfaces; - } - else - { - pf->prev=pf->next=0; - } - return(pf); - } - // - inline void Detach(Face* face) - { - if(face->prev||face->next) - { - --nfaces; - if(face==root) - { root=face->next;root->prev=0; } - else - { - if(face->next==0) - { face->prev->next=0; } - else - { face->prev->next=face->next;face->next->prev=face->prev; } - } - face->prev=face->next=0; - } - } - // - inline void Link(Face* f0,U e0,Face* f1,U e1) const - { - f0->f[e0]=f1;f1->e[e1]=e0; - f1->f[e1]=f0;f0->e[e0]=e1; - } - // - GJK::Mkv* Support(const Vector3& w) const - { - GJK::Mkv* v =(GJK::Mkv*)sa->allocate(sizeof(GJK::Mkv)); - gjk->Support(w,*v); - return(v); - } - // - U BuildHorizon(U markid,const GJK::Mkv* w,Face& f,U e,Face*& cf,Face*& -ff) - { - static const U mod3[]={0,1,2,0,1}; - U ne(0); - if(f.mark!=markid) - { - const U e1(mod3[e+1]); - if((f.n.dot(w->w)+f.d)>0) - { - Face* nf = NewFace(f.v[e1],f.v[e],w); - Link(nf,0,&f,e); - if(cf) Link(cf,1,nf,2); else ff=nf; - cf=nf;ne=1; - } - else - { - const U e2(mod3[e+2]); - Detach(&f); - f.mark = markid; - ne += BuildHorizon(markid,w,*f.f[e1],f.e[e1],cf,ff); - ne += BuildHorizon(markid,w,*f.f[e2],f.e[e2],cf,ff); - } - } - return(ne); - } - // - inline F EvaluatePD(F accuracy=EPA_accuracy) - { - btBlock* sablock = sa->beginBlock(); - Face* bestface = 0; - U markid(1); - depth = -cstInf; - normal = Vector3(0,0,0); - root = 0; - nfaces = 0; - iterations = 0; - failed = false; - /* Prepare hull */ - if(gjk->EncloseOrigin()) - { - const U* pfidx = 0; - U nfidx= 0; - const U* peidx = 0; - U neidx = 0; - GJK::Mkv* basemkv[5]; - Face* basefaces[6]; - switch(gjk->order) - { - /* Tetrahedron */ - case 3: { - static const U fidx[4][3]={{2,1,0},{3,0,1},{3,1,2},{3,2,0}}; - static const -U eidx[6][4]={{0,0,2,1},{0,1,1,1},{0,2,3,1},{1,0,3,2},{2,0,1,2},{3,0,2,2}}; - pfidx=(const U*)fidx;nfidx=4;peidx=(const U*)eidx;neidx=6; - } break; - /* Hexahedron */ - case 4: { - static const -U fidx[6][3]={{2,0,4},{4,1,2},{1,4,0},{0,3,1},{0,2,3},{1,3,2}}; - static const -U eidx[9][4]={{0,0,4,0},{0,1,2,1},{0,2,1,2},{1,1,5,2},{1,0,2,0},{2,2,3,2},{3,1,5,0},{3,0,4,2},{5,1,4,1}}; - pfidx=(const U*)fidx;nfidx=6;peidx=(const U*)eidx;neidx=9; - } break; - } - U i; - - for( i=0;i<=gjk->order;++i) { -basemkv[i]=(GJK::Mkv*)sa->allocate(sizeof(GJK::Mkv));*basemkv[i]=gjk->simplex[i]; -} - for( i=0;iendBlock(sablock); - return(depth); - } - /* Expand hull */ - for(;iterationsn); - const F d(bf->n.dot(w->w)+bf->d); - bestface = bf; - if(d<-accuracy) - { - Face* cf =0; - Face* ff =0; - U nf = 0; - Detach(bf); - bf->mark=++markid; - for(U i=0;i<3;++i) { -nf+=BuildHorizon(markid,w,*bf->f[i],bf->e[i],cf,ff); } - if(nf<=2) { break; } - Link(cf,1,ff,2); - } else break; - } else break; - } - /* Extract contact */ - if(bestface) - { - const Vector3 b(GetCoordinates(bestface)); - normal = bestface->n; - depth = Max(0,bestface->d); - for(U i=0;i<2;++i) - { - const F s(F(i?-1:1)); - for(U j=0;j<3;++j) - { - features[i][j]=gjk->LocalSupport(s*bestface->v[j]->r,i); - } - } - nearest[0] = features[0][0]*b.x()+features[0][1]*b.y()+features[0][2]*b.z(); - nearest[1] = features[1][0]*b.x()+features[1][1]*b.y()+features[1][2]*b.z(); - } else failed=true; - sa->endBlock(sablock); - return(depth); - } - }; -} - -// -// Api -// - -using namespace gjkepa_impl; - - - -// -bool btGjkEpaSolver::Collide(const btConvexShape *shape0,const btTransform &wtrs0, - const btConvexShape *shape1,const btTransform &wtrs1, - btScalar radialmargin, - btStackAlloc* stackAlloc, - sResults& results) -{ - - -/* Initialize */ -results.witnesses[0] = -results.witnesses[1] = -results.normal = Vector3(0,0,0); -results.depth = 0; -results.status = sResults::Separated; -results.epa_iterations = 0; -results.gjk_iterations = 0; -/* Use GJK to locate origin */ -GJK gjk(stackAlloc, - wtrs0.getBasis(),wtrs0.getOrigin(),shape0, - wtrs1.getBasis(),wtrs1.getOrigin(),shape1, - radialmargin+EPA_accuracy); -const Z collide(gjk.SearchOrigin()); -results.gjk_iterations = gjk.iterations+1; -if(collide) - { - /* Then EPA for penetration depth */ - EPA epa(&gjk); - const F pd(epa.EvaluatePD()); - results.epa_iterations = epa.iterations+1; - if(pd>0) - { - results.status = sResults::Penetrating; - results.normal = epa.normal; - results.depth = pd; - results.witnesses[0] = epa.nearest[0]; - results.witnesses[1] = epa.nearest[1]; - return(true); - } else { if(epa.failed) results.status=sResults::EPA_Failed; } - } else { if(gjk.failed) results.status=sResults::GJK_Failed; } -return(false); -} - - - - - diff --git a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkEpa.h b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkEpa.h deleted file mode 100644 index 1338e2714a8..00000000000 --- a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkEpa.h +++ /dev/null @@ -1,53 +0,0 @@ -/* -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. -*/ - -/* -GJK-EPA collision solver by Nathanael Presson -Nov.2006 -*/ - - -#ifndef _05E48D53_04E0_49ad_BB0A_D74FE62E7366_ -#define _05E48D53_04E0_49ad_BB0A_D74FE62E7366_ -#include "BulletCollision/CollisionShapes/btConvexShape.h" - -class btStackAlloc; - -///btGjkEpaSolver contributed under zlib by Nathanael Presson -struct btGjkEpaSolver -{ -struct sResults - { - enum eStatus - { - Separated, /* Shapes doesnt penetrate */ - Penetrating, /* Shapes are penetrating */ - GJK_Failed, /* GJK phase fail, no big issue, shapes are probably just 'touching' */ - EPA_Failed, /* EPA phase fail, bigger problem, need to save parameters, and debug */ - } status; - btVector3 witnesses[2]; - btVector3 normal; - btScalar depth; - int epa_iterations; - int gjk_iterations; - }; -static bool Collide(const btConvexShape* shape0,const btTransform& wtrs0, - const btConvexShape* shape1,const btTransform& wtrs1, - btScalar radialmargin, - btStackAlloc* stackAlloc, - sResults& results); -}; - -#endif diff --git a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.cpp b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.cpp deleted file mode 100644 index 9e600652333..00000000000 --- a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.cpp +++ /dev/null @@ -1,50 +0,0 @@ -/* -Bullet Continuous Collision Detection and Physics Library -Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ - -EPA Copyright (c) Ricardo Padrela 2006 - -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 "BulletCollision/CollisionShapes/btConvexShape.h" -#include "btGjkEpaPenetrationDepthSolver.h" -#include "BulletCollision/NarrowPhaseCollision/btGjkEpa.h" - -bool btGjkEpaPenetrationDepthSolver::calcPenDepth( btSimplexSolverInterface& simplexSolver, - const btConvexShape* pConvexA, const btConvexShape* pConvexB, - const btTransform& transformA, const btTransform& transformB, - btVector3& v, btPoint3& wWitnessOnA, btPoint3& wWitnessOnB, - class btIDebugDraw* debugDraw, btStackAlloc* stackAlloc ) -{ - - (void)debugDraw; - (void)v; - (void)simplexSolver; - - const btScalar radialmargin(btScalar(0.)); - - btGjkEpaSolver::sResults results; - if(btGjkEpaSolver::Collide( pConvexA,transformA, - pConvexB,transformB, - radialmargin,stackAlloc,results)) - { - // debugDraw->drawLine(results.witnesses[1],results.witnesses[1]+results.normal,btVector3(255,0,0)); - //resultOut->addContactPoint(results.normal,results.witnesses[1],-results.depth); - wWitnessOnA = results.witnesses[0]; - wWitnessOnB = results.witnesses[1]; - return true; - } - - return false; -} - - diff --git a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.h b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.h deleted file mode 100644 index 2dc069ce5cf..00000000000 --- a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.h +++ /dev/null @@ -1,39 +0,0 @@ -/* -Bullet Continuous Collision Detection and Physics Library -Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ - -EPA Copyright (c) Ricardo Padrela 2006 - -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 BT_GJP_EPA_PENETRATION_DEPTH_H -#define BT_GJP_EPA_PENETRATION_DEPTH_H - -#include "btConvexPenetrationDepthSolver.h" - -///EpaPenetrationDepthSolver uses the Expanding Polytope Algorithm to -///calculate the penetration depth between two convex shapes. -class btGjkEpaPenetrationDepthSolver : public btConvexPenetrationDepthSolver -{ - public : - - bool calcPenDepth( btSimplexSolverInterface& simplexSolver, - const btConvexShape* pConvexA, const btConvexShape* pConvexB, - const btTransform& transformA, const btTransform& transformB, - btVector3& v, btPoint3& wWitnessOnA, btPoint3& wWitnessOnB, - class btIDebugDraw* debugDraw,btStackAlloc* stackAlloc ); - - private : - -}; - -#endif // BT_GJP_EPA_PENETRATION_DEPTH_H - diff --git a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkPairDetector.cpp b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkPairDetector.cpp deleted file mode 100644 index c5f50d4dd1a..00000000000 --- a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkPairDetector.cpp +++ /dev/null @@ -1,299 +0,0 @@ -/* -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 "btGjkPairDetector.h" -#include "BulletCollision/CollisionShapes/btConvexShape.h" -#include "BulletCollision/NarrowPhaseCollision/btSimplexSolverInterface.h" -#include "BulletCollision/NarrowPhaseCollision/btConvexPenetrationDepthSolver.h" - -#if defined(DEBUG) || defined (_DEBUG) -#include //for debug printf -#ifdef __SPU__ -#include -#define printf spu_printf -#endif //__SPU__ -#endif - -//must be above the machine epsilon -#define REL_ERROR2 btScalar(1.0e-6) - -//temp globals, to improve GJK/EPA/penetration calculations -int gNumDeepPenetrationChecks = 0; -int gNumGjkChecks = 0; - - - -btGjkPairDetector::btGjkPairDetector(const btConvexShape* objectA,const btConvexShape* objectB,btSimplexSolverInterface* simplexSolver,btConvexPenetrationDepthSolver* penetrationDepthSolver) -:m_cachedSeparatingAxis(btScalar(0.),btScalar(0.),btScalar(1.)), -m_penetrationDepthSolver(penetrationDepthSolver), -m_simplexSolver(simplexSolver), -m_minkowskiA(objectA), -m_minkowskiB(objectB), -m_ignoreMargin(false), -m_lastUsedMethod(-1), -m_catchDegeneracies(1) -{ -} - -void btGjkPairDetector::getClosestPoints(const ClosestPointInput& input,Result& output,class btIDebugDraw* debugDraw) -{ - btScalar distance=btScalar(0.); - btVector3 normalInB(btScalar(0.),btScalar(0.),btScalar(0.)); - btVector3 pointOnA,pointOnB; - btTransform localTransA = input.m_transformA; - btTransform localTransB = input.m_transformB; - btVector3 positionOffset = (localTransA.getOrigin() + localTransB.getOrigin()) * btScalar(0.5); - localTransA.getOrigin() -= positionOffset; - localTransB.getOrigin() -= positionOffset; - - btScalar marginA = m_minkowskiA->getMargin(); - btScalar marginB = m_minkowskiB->getMargin(); - - gNumGjkChecks++; - - //for CCD we don't use margins - if (m_ignoreMargin) - { - marginA = btScalar(0.); - marginB = btScalar(0.); - } - - m_curIter = 0; - int gGjkMaxIter = 1000;//this is to catch invalid input, perhaps check for #NaN? - m_cachedSeparatingAxis.setValue(0,1,0); - - bool isValid = false; - bool checkSimplex = false; - bool checkPenetration = true; - m_degenerateSimplex = 0; - - m_lastUsedMethod = -1; - - { - btScalar squaredDistance = SIMD_INFINITY; - btScalar delta = btScalar(0.); - - btScalar margin = marginA + marginB; - - - - m_simplexSolver->reset(); - - for ( ; ; ) - //while (true) - { - - btVector3 seperatingAxisInA = (-m_cachedSeparatingAxis)* input.m_transformA.getBasis(); - btVector3 seperatingAxisInB = m_cachedSeparatingAxis* input.m_transformB.getBasis(); - - btVector3 pInA = m_minkowskiA->localGetSupportingVertexWithoutMargin(seperatingAxisInA); - btVector3 qInB = m_minkowskiB->localGetSupportingVertexWithoutMargin(seperatingAxisInB); - btPoint3 pWorld = localTransA(pInA); - btPoint3 qWorld = localTransB(qInB); - - btVector3 w = pWorld - qWorld; - delta = m_cachedSeparatingAxis.dot(w); - - // potential exit, they don't overlap - if ((delta > btScalar(0.0)) && (delta * delta > squaredDistance * input.m_maximumDistanceSquared)) - { - checkPenetration = false; - break; - } - - //exit 0: the new point is already in the simplex, or we didn't come any closer - if (m_simplexSolver->inSimplex(w)) - { - m_degenerateSimplex = 1; - checkSimplex = true; - break; - } - // are we getting any closer ? - btScalar f0 = squaredDistance - delta; - btScalar f1 = squaredDistance * REL_ERROR2; - - if (f0 <= f1) - { - if (f0 <= btScalar(0.)) - { - m_degenerateSimplex = 2; - } - checkSimplex = true; - break; - } - //add current vertex to simplex - m_simplexSolver->addVertex(w, pWorld, qWorld); - - //calculate the closest point to the origin (update vector v) - if (!m_simplexSolver->closest(m_cachedSeparatingAxis)) - { - m_degenerateSimplex = 3; - checkSimplex = true; - break; - } - - btScalar previousSquaredDistance = squaredDistance; - squaredDistance = m_cachedSeparatingAxis.length2(); - - //redundant m_simplexSolver->compute_points(pointOnA, pointOnB); - - //are we getting any closer ? - if (previousSquaredDistance - squaredDistance <= SIMD_EPSILON * previousSquaredDistance) - { - m_simplexSolver->backup_closest(m_cachedSeparatingAxis); - checkSimplex = true; - break; - } - - //degeneracy, this is typically due to invalid/uninitialized worldtransforms for a btCollisionObject - if (m_curIter++ > gGjkMaxIter) - { - #if defined(DEBUG) || defined (_DEBUG) - - printf("btGjkPairDetector maxIter exceeded:%i\n",m_curIter); - printf("sepAxis=(%f,%f,%f), squaredDistance = %f, shapeTypeA=%i,shapeTypeB=%i\n", - m_cachedSeparatingAxis.getX(), - m_cachedSeparatingAxis.getY(), - m_cachedSeparatingAxis.getZ(), - squaredDistance, - m_minkowskiA->getShapeType(), - m_minkowskiB->getShapeType()); - - #endif - break; - - } - - - bool check = (!m_simplexSolver->fullSimplex()); - //bool check = (!m_simplexSolver->fullSimplex() && squaredDistance > SIMD_EPSILON * m_simplexSolver->maxVertex()); - - if (!check) - { - //do we need this backup_closest here ? - m_simplexSolver->backup_closest(m_cachedSeparatingAxis); - break; - } - } - - if (checkSimplex) - { - m_simplexSolver->compute_points(pointOnA, pointOnB); - normalInB = pointOnA-pointOnB; - btScalar lenSqr = m_cachedSeparatingAxis.length2(); - //valid normal - if (lenSqr < 0.0001) - { - m_degenerateSimplex = 5; - } - if (lenSqr > SIMD_EPSILON*SIMD_EPSILON) - { - btScalar rlen = btScalar(1.) / btSqrt(lenSqr ); - normalInB *= rlen; //normalize - btScalar s = btSqrt(squaredDistance); - - btAssert(s > btScalar(0.0)); - pointOnA -= m_cachedSeparatingAxis * (marginA / s); - pointOnB += m_cachedSeparatingAxis * (marginB / s); - distance = ((btScalar(1.)/rlen) - margin); - isValid = true; - - m_lastUsedMethod = 1; - } else - { - m_lastUsedMethod = 2; - } - } - - bool catchDegeneratePenetrationCase = - (m_catchDegeneracies && m_penetrationDepthSolver && m_degenerateSimplex && ((distance+margin) < 0.01)); - - //if (checkPenetration && !isValid) - if (checkPenetration && (!isValid || catchDegeneratePenetrationCase )) - { - //penetration case - - //if there is no way to handle penetrations, bail out - if (m_penetrationDepthSolver) - { - // Penetration depth case. - btVector3 tmpPointOnA,tmpPointOnB; - - gNumDeepPenetrationChecks++; - - bool isValid2 = m_penetrationDepthSolver->calcPenDepth( - *m_simplexSolver, - m_minkowskiA,m_minkowskiB, - localTransA,localTransB, - m_cachedSeparatingAxis, tmpPointOnA, tmpPointOnB, - debugDraw,input.m_stackAlloc - ); - - if (isValid2) - { - btVector3 tmpNormalInB = tmpPointOnB-tmpPointOnA; - btScalar lenSqr = tmpNormalInB.length2(); - if (lenSqr > (SIMD_EPSILON*SIMD_EPSILON)) - { - tmpNormalInB /= btSqrt(lenSqr); - btScalar distance2 = -(tmpPointOnA-tmpPointOnB).length(); - //only replace valid penetrations when the result is deeper (check) - if (!isValid || (distance2 < distance)) - { - distance = distance2; - pointOnA = tmpPointOnA; - pointOnB = tmpPointOnB; - normalInB = tmpNormalInB; - isValid = true; - m_lastUsedMethod = 3; - } else - { - - } - } else - { - //isValid = false; - m_lastUsedMethod = 4; - } - } else - { - m_lastUsedMethod = 5; - } - - } - } - } - - if (isValid) - { -#ifdef __SPU__ - //spu_printf("distance\n"); -#endif //__CELLOS_LV2__ - - - output.addContactPoint( - normalInB, - pointOnB+positionOffset, - distance); - //printf("gjk add:%f",distance); - } - - -} - - - - - diff --git a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkPairDetector.h b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkPairDetector.h deleted file mode 100644 index 1ec51f74069..00000000000 --- a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkPairDetector.h +++ /dev/null @@ -1,85 +0,0 @@ -/* -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 GJK_PAIR_DETECTOR_H -#define GJK_PAIR_DETECTOR_H - -#include "btDiscreteCollisionDetectorInterface.h" -#include "LinearMath/btPoint3.h" -#include "BulletCollision/CollisionShapes/btCollisionMargin.h" - -class btConvexShape; -#include "btSimplexSolverInterface.h" -class btConvexPenetrationDepthSolver; - -/// btGjkPairDetector uses GJK to implement the btDiscreteCollisionDetectorInterface -class btGjkPairDetector : public btDiscreteCollisionDetectorInterface -{ - - - btVector3 m_cachedSeparatingAxis; - btConvexPenetrationDepthSolver* m_penetrationDepthSolver; - btSimplexSolverInterface* m_simplexSolver; - const btConvexShape* m_minkowskiA; - const btConvexShape* m_minkowskiB; - bool m_ignoreMargin; - - -public: - - //some debugging to fix degeneracy problems - int m_lastUsedMethod; - int m_curIter; - int m_degenerateSimplex; - int m_catchDegeneracies; - - - btGjkPairDetector(const btConvexShape* objectA,const btConvexShape* objectB,btSimplexSolverInterface* simplexSolver,btConvexPenetrationDepthSolver* penetrationDepthSolver); - virtual ~btGjkPairDetector() {}; - - virtual void getClosestPoints(const ClosestPointInput& input,Result& output,class btIDebugDraw* debugDraw); - - void setMinkowskiA(btConvexShape* minkA) - { - m_minkowskiA = minkA; - } - - void setMinkowskiB(btConvexShape* minkB) - { - m_minkowskiB = minkB; - } - void setCachedSeperatingAxis(const btVector3& seperatingAxis) - { - m_cachedSeparatingAxis = seperatingAxis; - } - - void setPenetrationDepthSolver(btConvexPenetrationDepthSolver* penetrationDepthSolver) - { - m_penetrationDepthSolver = penetrationDepthSolver; - } - - ///don't use setIgnoreMargin, it's for Bullet's internal use - void setIgnoreMargin(bool ignoreMargin) - { - m_ignoreMargin = ignoreMargin; - } - - -}; - -#endif //GJK_PAIR_DETECTOR_H diff --git a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btManifoldPoint.h b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btManifoldPoint.h deleted file mode 100644 index 1933d378f4f..00000000000 --- a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btManifoldPoint.h +++ /dev/null @@ -1,99 +0,0 @@ -/* -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 MANIFOLD_CONTACT_POINT_H -#define MANIFOLD_CONTACT_POINT_H - -#include "LinearMath/btVector3.h" -#include "LinearMath/btTransformUtil.h" - - - - - -/// ManifoldContactPoint collects and maintains persistent contactpoints. -/// used to improve stability and performance of rigidbody dynamics response. -class btManifoldPoint - { - public: - btManifoldPoint() - :m_userPersistentData(0), - m_lifeTime(0) - { - } - - btManifoldPoint( const btVector3 &pointA, const btVector3 &pointB, - const btVector3 &normal, - btScalar distance ) : - m_localPointA( pointA ), - m_localPointB( pointB ), - m_normalWorldOnB( normal ), - m_distance1( distance ), - m_combinedFriction(btScalar(0.)), - m_combinedRestitution(btScalar(0.)), - m_userPersistentData(0), - m_lifeTime(0) - { - - - } - - - - btVector3 m_localPointA; - btVector3 m_localPointB; - btVector3 m_positionWorldOnB; - ///m_positionWorldOnA is redundant information, see getPositionWorldOnA(), but for clarity - btVector3 m_positionWorldOnA; - btVector3 m_normalWorldOnB; - - btScalar m_distance1; - btScalar m_combinedFriction; - btScalar m_combinedRestitution; - - - mutable void* m_userPersistentData; - - int m_lifeTime;//lifetime of the contactpoint in frames - - btScalar getDistance() const - { - return m_distance1; - } - int getLifeTime() const - { - return m_lifeTime; - } - - const btVector3& getPositionWorldOnA() const { - return m_positionWorldOnA; -// return m_positionWorldOnB + m_normalWorldOnB * m_distance1; - } - - const btVector3& getPositionWorldOnB() const - { - return m_positionWorldOnB; - } - - void setDistance(btScalar dist) - { - m_distance1 = dist; - } - - - - }; - -#endif //MANIFOLD_CONTACT_POINT_H diff --git a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.cpp b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.cpp deleted file mode 100644 index 100bc240764..00000000000 --- a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.cpp +++ /dev/null @@ -1,333 +0,0 @@ -/* -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 "btMinkowskiPenetrationDepthSolver.h" -#include "BulletCollision/CollisionShapes/btMinkowskiSumShape.h" -#include "BulletCollision/NarrowPhaseCollision/btSubSimplexConvexCast.h" -#include "BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.h" -#include "BulletCollision/NarrowPhaseCollision/btGjkPairDetector.h" - - - - -#define NUM_UNITSPHERE_POINTS 42 -static btVector3 sPenetrationDirections[NUM_UNITSPHERE_POINTS+MAX_PREFERRED_PENETRATION_DIRECTIONS*2] = -{ -btVector3(btScalar(0.000000) , btScalar(-0.000000),btScalar(-1.000000)), -btVector3(btScalar(0.723608) , btScalar(-0.525725),btScalar(-0.447219)), -btVector3(btScalar(-0.276388) , btScalar(-0.850649),btScalar(-0.447219)), -btVector3(btScalar(-0.894426) , btScalar(-0.000000),btScalar(-0.447216)), -btVector3(btScalar(-0.276388) , btScalar(0.850649),btScalar(-0.447220)), -btVector3(btScalar(0.723608) , btScalar(0.525725),btScalar(-0.447219)), -btVector3(btScalar(0.276388) , btScalar(-0.850649),btScalar(0.447220)), -btVector3(btScalar(-0.723608) , btScalar(-0.525725),btScalar(0.447219)), -btVector3(btScalar(-0.723608) , btScalar(0.525725),btScalar(0.447219)), -btVector3(btScalar(0.276388) , btScalar(0.850649),btScalar(0.447219)), -btVector3(btScalar(0.894426) , btScalar(0.000000),btScalar(0.447216)), -btVector3(btScalar(-0.000000) , btScalar(0.000000),btScalar(1.000000)), -btVector3(btScalar(0.425323) , btScalar(-0.309011),btScalar(-0.850654)), -btVector3(btScalar(-0.162456) , btScalar(-0.499995),btScalar(-0.850654)), -btVector3(btScalar(0.262869) , btScalar(-0.809012),btScalar(-0.525738)), -btVector3(btScalar(0.425323) , btScalar(0.309011),btScalar(-0.850654)), -btVector3(btScalar(0.850648) , btScalar(-0.000000),btScalar(-0.525736)), -btVector3(btScalar(-0.525730) , btScalar(-0.000000),btScalar(-0.850652)), -btVector3(btScalar(-0.688190) , btScalar(-0.499997),btScalar(-0.525736)), -btVector3(btScalar(-0.162456) , btScalar(0.499995),btScalar(-0.850654)), -btVector3(btScalar(-0.688190) , btScalar(0.499997),btScalar(-0.525736)), -btVector3(btScalar(0.262869) , btScalar(0.809012),btScalar(-0.525738)), -btVector3(btScalar(0.951058) , btScalar(0.309013),btScalar(0.000000)), -btVector3(btScalar(0.951058) , btScalar(-0.309013),btScalar(0.000000)), -btVector3(btScalar(0.587786) , btScalar(-0.809017),btScalar(0.000000)), -btVector3(btScalar(0.000000) , btScalar(-1.000000),btScalar(0.000000)), -btVector3(btScalar(-0.587786) , btScalar(-0.809017),btScalar(0.000000)), -btVector3(btScalar(-0.951058) , btScalar(-0.309013),btScalar(-0.000000)), -btVector3(btScalar(-0.951058) , btScalar(0.309013),btScalar(-0.000000)), -btVector3(btScalar(-0.587786) , btScalar(0.809017),btScalar(-0.000000)), -btVector3(btScalar(-0.000000) , btScalar(1.000000),btScalar(-0.000000)), -btVector3(btScalar(0.587786) , btScalar(0.809017),btScalar(-0.000000)), -btVector3(btScalar(0.688190) , btScalar(-0.499997),btScalar(0.525736)), -btVector3(btScalar(-0.262869) , btScalar(-0.809012),btScalar(0.525738)), -btVector3(btScalar(-0.850648) , btScalar(0.000000),btScalar(0.525736)), -btVector3(btScalar(-0.262869) , btScalar(0.809012),btScalar(0.525738)), -btVector3(btScalar(0.688190) , btScalar(0.499997),btScalar(0.525736)), -btVector3(btScalar(0.525730) , btScalar(0.000000),btScalar(0.850652)), -btVector3(btScalar(0.162456) , btScalar(-0.499995),btScalar(0.850654)), -btVector3(btScalar(-0.425323) , btScalar(-0.309011),btScalar(0.850654)), -btVector3(btScalar(-0.425323) , btScalar(0.309011),btScalar(0.850654)), -btVector3(btScalar(0.162456) , btScalar(0.499995),btScalar(0.850654)) -}; - - -bool btMinkowskiPenetrationDepthSolver::calcPenDepth(btSimplexSolverInterface& simplexSolver, - const btConvexShape* convexA,const btConvexShape* convexB, - const btTransform& transA,const btTransform& transB, - btVector3& v, btPoint3& pa, btPoint3& pb, - class btIDebugDraw* debugDraw,btStackAlloc* stackAlloc - ) -{ - - (void)stackAlloc; - (void)v; - - - struct btIntermediateResult : public btDiscreteCollisionDetectorInterface::Result - { - - btIntermediateResult():m_hasResult(false) - { - } - - btVector3 m_normalOnBInWorld; - btVector3 m_pointInWorld; - btScalar m_depth; - bool m_hasResult; - - virtual void setShapeIdentifiers(int partId0,int index0, int partId1,int index1) - { - (void)partId0; - (void)index0; - (void)partId1; - (void)index1; - } - void addContactPoint(const btVector3& normalOnBInWorld,const btVector3& pointInWorld,btScalar depth) - { - m_normalOnBInWorld = normalOnBInWorld; - m_pointInWorld = pointInWorld; - m_depth = depth; - m_hasResult = true; - } - }; - - //just take fixed number of orientation, and sample the penetration depth in that direction - btScalar minProj = btScalar(1e30); - btVector3 minNorm(btScalar(0.), btScalar(0.), btScalar(0.)); - btVector3 minA,minB; - btVector3 seperatingAxisInA,seperatingAxisInB; - btVector3 pInA,qInB,pWorld,qWorld,w; - -#define USE_BATCHED_SUPPORT 1 -#ifdef USE_BATCHED_SUPPORT - - btVector3 supportVerticesABatch[NUM_UNITSPHERE_POINTS+MAX_PREFERRED_PENETRATION_DIRECTIONS*2]; - btVector3 supportVerticesBBatch[NUM_UNITSPHERE_POINTS+MAX_PREFERRED_PENETRATION_DIRECTIONS*2]; - btVector3 seperatingAxisInABatch[NUM_UNITSPHERE_POINTS+MAX_PREFERRED_PENETRATION_DIRECTIONS*2]; - btVector3 seperatingAxisInBBatch[NUM_UNITSPHERE_POINTS+MAX_PREFERRED_PENETRATION_DIRECTIONS*2]; - int i; - - int numSampleDirections = NUM_UNITSPHERE_POINTS; - - for (i=0;igetNumPreferredPenetrationDirections(); - if (numPDA) - { - for (int i=0;igetPreferredPenetrationDirection(i,norm); - norm = transA.getBasis() * norm; - sPenetrationDirections[numSampleDirections] = norm; - seperatingAxisInABatch[numSampleDirections] = (-norm) * transA.getBasis(); - seperatingAxisInBBatch[numSampleDirections] = norm * transB.getBasis(); - numSampleDirections++; - } - } - } - - { - int numPDB = convexB->getNumPreferredPenetrationDirections(); - if (numPDB) - { - for (int i=0;igetPreferredPenetrationDirection(i,norm); - norm = transB.getBasis() * norm; - sPenetrationDirections[numSampleDirections] = norm; - seperatingAxisInABatch[numSampleDirections] = (-norm) * transA.getBasis(); - seperatingAxisInBBatch[numSampleDirections] = norm * transB.getBasis(); - numSampleDirections++; - } - } - } - - - - convexA->batchedUnitVectorGetSupportingVertexWithoutMargin(seperatingAxisInABatch,supportVerticesABatch,numSampleDirections); - convexB->batchedUnitVectorGetSupportingVertexWithoutMargin(seperatingAxisInBBatch,supportVerticesBBatch,numSampleDirections); - - for (i=0;igetNumPreferredPenetrationDirections(); - if (numPDA) - { - for (int i=0;igetPreferredPenetrationDirection(i,norm); - norm = transA.getBasis() * norm; - sPenetrationDirections[numSampleDirections] = norm; - numSampleDirections++; - } - } - } - - { - int numPDB = convexB->getNumPreferredPenetrationDirections(); - if (numPDB) - { - for (int i=0;igetPreferredPenetrationDirection(i,norm); - norm = transB.getBasis() * norm; - sPenetrationDirections[numSampleDirections] = norm; - numSampleDirections++; - } - } - } - - for (int i=0;ilocalGetSupportingVertexWithoutMargin(seperatingAxisInA); - qInB = convexB->localGetSupportingVertexWithoutMargin(seperatingAxisInB); - pWorld = transA(pInA); - qWorld = transB(qInB); - w = qWorld - pWorld; - btScalar delta = norm.dot(w); - //find smallest delta - if (delta < minProj) - { - minProj = delta; - minNorm = norm; - minA = pWorld; - minB = qWorld; - } - } -#endif //USE_BATCHED_SUPPORT - - //add the margins - - minA += minNorm*convexA->getMargin(); - minB -= minNorm*convexB->getMargin(); - //no penetration - if (minProj < btScalar(0.)) - return false; - - minProj += (convexA->getMargin() + convexB->getMargin()); - - - - - -//#define DEBUG_DRAW 1 -#ifdef DEBUG_DRAW - if (debugDraw) - { - btVector3 color(0,1,0); - debugDraw->drawLine(minA,minB,color); - color = btVector3 (1,1,1); - btVector3 vec = minB-minA; - btScalar prj2 = minNorm.dot(vec); - debugDraw->drawLine(minA,minA+(minNorm*minProj),color); - - } -#endif //DEBUG_DRAW - - - - btGjkPairDetector gjkdet(convexA,convexB,&simplexSolver,0); - - btScalar offsetDist = minProj; - btVector3 offset = minNorm * offsetDist; - - - - btGjkPairDetector::ClosestPointInput input; - - btVector3 newOrg = transA.getOrigin() + offset; - - btTransform displacedTrans = transA; - displacedTrans.setOrigin(newOrg); - - input.m_transformA = displacedTrans; - input.m_transformB = transB; - input.m_maximumDistanceSquared = btScalar(1e30);//minProj; - - btIntermediateResult res; - gjkdet.getClosestPoints(input,res,debugDraw); - - btScalar correctedMinNorm = minProj - res.m_depth; - - - //the penetration depth is over-estimated, relax it - btScalar penetration_relaxation= btScalar(1.); - minNorm*=penetration_relaxation; - - if (res.m_hasResult) - { - - pa = res.m_pointInWorld - minNorm * correctedMinNorm; - pb = res.m_pointInWorld; - -#ifdef DEBUG_DRAW - if (debugDraw) - { - btVector3 color(1,0,0); - debugDraw->drawLine(pa,pb,color); - } -#endif//DEBUG_DRAW - - - } - return res.m_hasResult; -} - - - diff --git a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.h b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.h deleted file mode 100644 index 27b42c2b47e..00000000000 --- a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.h +++ /dev/null @@ -1,37 +0,0 @@ -/* -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 MINKOWSKI_PENETRATION_DEPTH_SOLVER_H -#define MINKOWSKI_PENETRATION_DEPTH_SOLVER_H - -#include "btConvexPenetrationDepthSolver.h" - -///MinkowskiPenetrationDepthSolver implements bruteforce penetration depth estimation. -///Implementation is based on sampling the depth using support mapping, and using GJK step to get the witness points. -class btMinkowskiPenetrationDepthSolver : public btConvexPenetrationDepthSolver -{ -public: - - virtual bool calcPenDepth( btSimplexSolverInterface& simplexSolver, - const btConvexShape* convexA,const btConvexShape* convexB, - const btTransform& transA,const btTransform& transB, - btVector3& v, btPoint3& pa, btPoint3& pb, - class btIDebugDraw* debugDraw,btStackAlloc* stackAlloc - ); - -}; - -#endif //MINKOWSKI_PENETRATION_DEPTH_SOLVER_H - diff --git a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btPersistentManifold.cpp b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btPersistentManifold.cpp deleted file mode 100644 index ee94ee01149..00000000000 --- a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btPersistentManifold.cpp +++ /dev/null @@ -1,248 +0,0 @@ -/* -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 "btPersistentManifold.h" -#include "LinearMath/btTransform.h" -#include - -btScalar gContactBreakingThreshold = btScalar(0.02); -ContactDestroyedCallback gContactDestroyedCallback = 0; - - - -btPersistentManifold::btPersistentManifold() -:m_body0(0), -m_body1(0), -m_cachedPoints (0), -m_index1a(0) -{ -} - - - - -#ifdef DEBUG_PERSISTENCY -#include -void btPersistentManifold::DebugPersistency() -{ - int i; - printf("DebugPersistency : numPoints %d\n",m_cachedPoints); - for (i=0;i1) - printf("error in clearUserCache\n"); - } - } - assert(occurance<=0); -#endif //DEBUG_PERSISTENCY - - if (pt.m_userPersistentData && gContactDestroyedCallback) - { - (*gContactDestroyedCallback)(pt.m_userPersistentData); - pt.m_userPersistentData = 0; - } - -#ifdef DEBUG_PERSISTENCY - DebugPersistency(); -#endif - } - - -} - - -int btPersistentManifold::sortCachedPoints(const btManifoldPoint& pt) -{ - - //calculate 4 possible cases areas, and take biggest area - //also need to keep 'deepest' - - int maxPenetrationIndex = -1; -#define KEEP_DEEPEST_POINT 1 -#ifdef KEEP_DEEPEST_POINT - btScalar maxPenetration = pt.getDistance(); - for (int i=0;i<4;i++) - { - if (m_pointCache[i].getDistance() < maxPenetration) - { - maxPenetrationIndex = i; - maxPenetration = m_pointCache[i].getDistance(); - } - } -#endif //KEEP_DEEPEST_POINT - - btScalar res0(btScalar(0.)),res1(btScalar(0.)),res2(btScalar(0.)),res3(btScalar(0.)); - if (maxPenetrationIndex != 0) - { - btVector3 a0 = pt.m_localPointA-m_pointCache[1].m_localPointA; - btVector3 b0 = m_pointCache[3].m_localPointA-m_pointCache[2].m_localPointA; - btVector3 cross = a0.cross(b0); - res0 = cross.length2(); - } - if (maxPenetrationIndex != 1) - { - btVector3 a1 = pt.m_localPointA-m_pointCache[0].m_localPointA; - btVector3 b1 = m_pointCache[3].m_localPointA-m_pointCache[2].m_localPointA; - btVector3 cross = a1.cross(b1); - res1 = cross.length2(); - } - - if (maxPenetrationIndex != 2) - { - btVector3 a2 = pt.m_localPointA-m_pointCache[0].m_localPointA; - btVector3 b2 = m_pointCache[3].m_localPointA-m_pointCache[1].m_localPointA; - btVector3 cross = a2.cross(b2); - res2 = cross.length2(); - } - - if (maxPenetrationIndex != 3) - { - btVector3 a3 = pt.m_localPointA-m_pointCache[0].m_localPointA; - btVector3 b3 = m_pointCache[2].m_localPointA-m_pointCache[1].m_localPointA; - btVector3 cross = a3.cross(b3); - res3 = cross.length2(); - } - - btVector4 maxvec(res0,res1,res2,res3); - int biggestarea = maxvec.closestAxis4(); - return biggestarea; -} - - -int btPersistentManifold::getCacheEntry(const btManifoldPoint& newPoint) const -{ - btScalar shortestDist = getContactBreakingThreshold() * getContactBreakingThreshold(); - int size = getNumContacts(); - int nearestPoint = -1; - for( int i = 0; i < size; i++ ) - { - const btManifoldPoint &mp = m_pointCache[i]; - - btVector3 diffA = mp.m_localPointA- newPoint.m_localPointA; - const btScalar distToManiPoint = diffA.dot(diffA); - if( distToManiPoint < shortestDist ) - { - shortestDist = distToManiPoint; - nearestPoint = i; - } - } - return nearestPoint; -} - -void btPersistentManifold::AddManifoldPoint(const btManifoldPoint& newPoint) -{ - assert(validContactDistance(newPoint)); - - int insertIndex = getNumContacts(); - if (insertIndex == MANIFOLD_CACHE_SIZE) - { -#if MANIFOLD_CACHE_SIZE >= 4 - //sort cache so best points come first, based on area - insertIndex = sortCachedPoints(newPoint); -#else - insertIndex = 0; -#endif - - - } else - { - m_cachedPoints++; - - - } - replaceContactPoint(newPoint,insertIndex); -} - -btScalar btPersistentManifold::getContactBreakingThreshold() const -{ - return gContactBreakingThreshold; -} - - - -void btPersistentManifold::refreshContactPoints(const btTransform& trA,const btTransform& trB) -{ - int i; -#ifdef DEBUG_PERSISTENCY - printf("refreshContactPoints posA = (%f,%f,%f) posB = (%f,%f,%f)\n", - trA.getOrigin().getX(), - trA.getOrigin().getY(), - trA.getOrigin().getZ(), - trB.getOrigin().getX(), - trB.getOrigin().getY(), - trB.getOrigin().getZ()); -#endif //DEBUG_PERSISTENCY - /// first refresh worldspace positions and distance - for (i=getNumContacts()-1;i>=0;i--) - { - btManifoldPoint &manifoldPoint = m_pointCache[i]; - manifoldPoint.m_positionWorldOnA = trA( manifoldPoint.m_localPointA ); - manifoldPoint.m_positionWorldOnB = trB( manifoldPoint.m_localPointB ); - manifoldPoint.m_distance1 = (manifoldPoint.m_positionWorldOnA - manifoldPoint.m_positionWorldOnB).dot(manifoldPoint.m_normalWorldOnB); - manifoldPoint.m_lifeTime++; - } - - /// then - btScalar distance2d; - btVector3 projectedDifference,projectedPoint; - for (i=getNumContacts()-1;i>=0;i--) - { - - btManifoldPoint &manifoldPoint = m_pointCache[i]; - //contact becomes invalid when signed distance exceeds margin (projected on contactnormal direction) - if (!validContactDistance(manifoldPoint)) - { - removeContactPoint(i); - } else - { - //contact also becomes invalid when relative movement orthogonal to normal exceeds margin - projectedPoint = manifoldPoint.m_positionWorldOnA - manifoldPoint.m_normalWorldOnB * manifoldPoint.m_distance1; - projectedDifference = manifoldPoint.m_positionWorldOnB - projectedPoint; - distance2d = projectedDifference.dot(projectedDifference); - if (distance2d > getContactBreakingThreshold()*getContactBreakingThreshold() ) - { - removeContactPoint(i); - } - } - } -#ifdef DEBUG_PERSISTENCY - DebugPersistency(); -#endif // -} - - - - - diff --git a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btPersistentManifold.h b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btPersistentManifold.h deleted file mode 100644 index f0b1ce58db7..00000000000 --- a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btPersistentManifold.h +++ /dev/null @@ -1,179 +0,0 @@ -/* -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 PERSISTENT_MANIFOLD_H -#define PERSISTENT_MANIFOLD_H - - -#include "LinearMath/btVector3.h" -#include "LinearMath/btTransform.h" -#include "btManifoldPoint.h" -#include "LinearMath/btAlignedAllocator.h" - -struct btCollisionResult; - -///contact breaking and merging threshold -extern btScalar gContactBreakingThreshold; - -typedef bool (*ContactDestroyedCallback)(void* userPersistentData); -extern ContactDestroyedCallback gContactDestroyedCallback; - - - - -#define MANIFOLD_CACHE_SIZE 4 - -///btPersistentManifold is a contact point cache, it stays persistent as long as objects are overlapping in the broadphase. -///Those contact points are created by the collision narrow phase. -///The cache can be empty, or hold 1,2,3 or 4 points. Some collision algorithms (GJK) might only add one point at a time. -///updates/refreshes old contact points, and throw them away if necessary (distance becomes too large) -///reduces the cache to 4 points, when more then 4 points are added, using following rules: -///the contact point with deepest penetration is always kept, and it tries to maximuze the area covered by the points -///note that some pairs of objects might have more then one contact manifold. -ATTRIBUTE_ALIGNED16( class) btPersistentManifold -{ - - btManifoldPoint m_pointCache[MANIFOLD_CACHE_SIZE]; - - /// this two body pointers can point to the physics rigidbody class. - /// void* will allow any rigidbody class - void* m_body0; - void* m_body1; - int m_cachedPoints; - - - /// sort cached points so most isolated points come first - int sortCachedPoints(const btManifoldPoint& pt); - - int findContactPoint(const btManifoldPoint* unUsed, int numUnused,const btManifoldPoint& pt); - -public: - - BT_DECLARE_ALIGNED_ALLOCATOR(); - - int m_index1a; - - btPersistentManifold(); - - btPersistentManifold(void* body0,void* body1,int bla) - : m_body0(body0),m_body1(body1),m_cachedPoints(0) - { - } - - SIMD_FORCE_INLINE void* getBody0() { return m_body0;} - SIMD_FORCE_INLINE void* getBody1() { return m_body1;} - - SIMD_FORCE_INLINE const void* getBody0() const { return m_body0;} - SIMD_FORCE_INLINE const void* getBody1() const { return m_body1;} - - void setBodies(void* body0,void* body1) - { - m_body0 = body0; - m_body1 = body1; - } - - void clearUserCache(btManifoldPoint& pt); - -#ifdef DEBUG_PERSISTENCY - void DebugPersistency(); -#endif // - - SIMD_FORCE_INLINE int getNumContacts() const { return m_cachedPoints;} - - SIMD_FORCE_INLINE const btManifoldPoint& getContactPoint(int index) const - { - btAssert(index < m_cachedPoints); - return m_pointCache[index]; - } - - SIMD_FORCE_INLINE btManifoldPoint& getContactPoint(int index) - { - btAssert(index < m_cachedPoints); - return m_pointCache[index]; - } - - /// todo: get this margin from the current physics / collision environment - btScalar getContactBreakingThreshold() const; - - int getCacheEntry(const btManifoldPoint& newPoint) const; - - void AddManifoldPoint( const btManifoldPoint& newPoint); - - void removeContactPoint (int index) - { - clearUserCache(m_pointCache[index]); - - int lastUsedIndex = getNumContacts() - 1; -// m_pointCache[index] = m_pointCache[lastUsedIndex]; - if(index != lastUsedIndex) - { - m_pointCache[index] = m_pointCache[lastUsedIndex]; - //get rid of duplicated userPersistentData pointer - m_pointCache[lastUsedIndex].m_userPersistentData = 0; - m_pointCache[lastUsedIndex].m_lifeTime = 0; - } - - btAssert(m_pointCache[lastUsedIndex].m_userPersistentData==0); - m_cachedPoints--; - } - void replaceContactPoint(const btManifoldPoint& newPoint,int insertIndex) - { - btAssert(validContactDistance(newPoint)); - -#define MAINTAIN_PERSISTENCY 1 -#ifdef MAINTAIN_PERSISTENCY - int lifeTime = m_pointCache[insertIndex].getLifeTime(); - btAssert(lifeTime>=0); - void* cache = m_pointCache[insertIndex].m_userPersistentData; - - m_pointCache[insertIndex] = newPoint; - - m_pointCache[insertIndex].m_userPersistentData = cache; - m_pointCache[insertIndex].m_lifeTime = lifeTime; -#else - clearUserCache(m_pointCache[insertIndex]); - m_pointCache[insertIndex] = newPoint; - -#endif - } - - bool validContactDistance(const btManifoldPoint& pt) const - { - return pt.m_distance1 <= getContactBreakingThreshold(); - } - /// calculated new worldspace coordinates and depth, and reject points that exceed the collision margin - void refreshContactPoints( const btTransform& trA,const btTransform& trB); - - - SIMD_FORCE_INLINE void clearManifold() - { - int i; - for (i=0;i= btScalar(0.0) ) - { - return ; // same sign - } - - const btScalar proj_length=dist_a-dist_b; - const btScalar distance = (dist_a)/(proj_length); - // Now we have the intersection point on the plane, we'll see if it's inside the triangle - // Add an epsilon as a tolerance for the raycast, - // in case the ray hits exacly on the edge of the triangle. - // It must be scaled for the triangle size. - - if(distance < m_hitFraction) - { - - - btScalar edge_tolerance =triangleNormal.length2(); - edge_tolerance *= btScalar(-0.0001); - btVector3 point; point.setInterpolate3( m_from, m_to, distance); - { - btVector3 v0p; v0p = vert0 - point; - btVector3 v1p; v1p = vert1 - point; - btVector3 cp0; cp0 = v0p.cross( v1p ); - - if ( (btScalar)(cp0.dot(triangleNormal)) >=edge_tolerance) - { - - - btVector3 v2p; v2p = vert2 - point; - btVector3 cp1; - cp1 = v1p.cross( v2p); - if ( (btScalar)(cp1.dot(triangleNormal)) >=edge_tolerance) - { - btVector3 cp2; - cp2 = v2p.cross(v0p); - - if ( (btScalar)(cp2.dot(triangleNormal)) >=edge_tolerance) - { - - if ( dist_a > 0 ) - { - m_hitFraction = reportHit(triangleNormal,distance,partId,triangleIndex); - } - else - { - m_hitFraction = reportHit(-triangleNormal,distance,partId,triangleIndex); - } - } - } - } - } - } -} diff --git a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btRaycastCallback.h b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btRaycastCallback.h deleted file mode 100644 index 87490a345a2..00000000000 --- a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btRaycastCallback.h +++ /dev/null @@ -1,42 +0,0 @@ -/* -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 RAYCAST_TRI_CALLBACK_H -#define RAYCAST_TRI_CALLBACK_H - -#include "BulletCollision/CollisionShapes/btTriangleCallback.h" -struct btBroadphaseProxy; - - -class btTriangleRaycastCallback: public btTriangleCallback -{ -public: - - //input - btVector3 m_from; - btVector3 m_to; - - btScalar m_hitFraction; - - btTriangleRaycastCallback(const btVector3& from,const btVector3& to); - - virtual void processTriangle(btVector3* triangle, int partId, int triangleIndex); - - virtual btScalar reportHit(const btVector3& hitNormalLocal, btScalar hitFraction, int partId, int triangleIndex ) = 0; - -}; - -#endif //RAYCAST_TRI_CALLBACK_H - diff --git a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btSimplexSolverInterface.h b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btSimplexSolverInterface.h deleted file mode 100644 index cf65f46505b..00000000000 --- a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btSimplexSolverInterface.h +++ /dev/null @@ -1,64 +0,0 @@ -/* -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 SIMPLEX_SOLVER_INTERFACE_H -#define SIMPLEX_SOLVER_INTERFACE_H - -#include "LinearMath/btVector3.h" -#include "LinearMath/btPoint3.h" - -#define NO_VIRTUAL_INTERFACE 1 -#ifdef NO_VIRTUAL_INTERFACE -#include "btVoronoiSimplexSolver.h" -#define btSimplexSolverInterface btVoronoiSimplexSolver -#else - -/// btSimplexSolverInterface can incrementally calculate distance between origin and up to 4 vertices -/// Used by GJK or Linear Casting. Can be implemented by the Johnson-algorithm or alternative approaches based on -/// voronoi regions or barycentric coordinates -class btSimplexSolverInterface -{ - public: - virtual ~btSimplexSolverInterface() {}; - - virtual void reset() = 0; - - virtual void addVertex(const btVector3& w, const btPoint3& p, const btPoint3& q) = 0; - - virtual bool closest(btVector3& v) = 0; - - virtual btScalar maxVertex() = 0; - - virtual bool fullSimplex() const = 0; - - virtual int getSimplex(btPoint3 *pBuf, btPoint3 *qBuf, btVector3 *yBuf) const = 0; - - virtual bool inSimplex(const btVector3& w) = 0; - - virtual void backup_closest(btVector3& v) = 0; - - virtual bool emptySimplex() const = 0; - - virtual void compute_points(btPoint3& p1, btPoint3& p2) = 0; - - virtual int numVertices() const =0; - - -}; -#endif -#endif //SIMPLEX_SOLVER_INTERFACE_H - diff --git a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btSubSimplexConvexCast.cpp b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btSubSimplexConvexCast.cpp deleted file mode 100644 index 687738b7fa9..00000000000 --- a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btSubSimplexConvexCast.cpp +++ /dev/null @@ -1,139 +0,0 @@ -/* -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 "btSubSimplexConvexCast.h" -#include "BulletCollision/CollisionShapes/btConvexShape.h" -#include "BulletCollision/CollisionShapes/btMinkowskiSumShape.h" -#include "BulletCollision/NarrowPhaseCollision/btSimplexSolverInterface.h" - - -btSubsimplexConvexCast::btSubsimplexConvexCast (const btConvexShape* convexA,const btConvexShape* convexB,btSimplexSolverInterface* simplexSolver) -:m_simplexSolver(simplexSolver), -m_convexA(convexA),m_convexB(convexB) -{ -} - -///Typically the conservative advancement reaches solution in a few iterations, clip it to 32 for degenerate cases. -///See discussion about this here http://continuousphysics.com/Bullet/phpBB2/viewtopic.php?t=565 -#ifdef BT_USE_DOUBLE_PRECISION -#define MAX_ITERATIONS 64 -#else -#define MAX_ITERATIONS 32 -#endif -bool btSubsimplexConvexCast::calcTimeOfImpact( - const btTransform& fromA, - const btTransform& toA, - const btTransform& fromB, - const btTransform& toB, - CastResult& result) -{ - - btMinkowskiSumShape combi(m_convexA,m_convexB); - btMinkowskiSumShape* convex = &combi; - - btTransform rayFromLocalA; - btTransform rayToLocalA; - - rayFromLocalA = fromA.inverse()* fromB; - rayToLocalA = toA.inverse()* toB; - - - m_simplexSolver->reset(); - - convex->setTransformB(btTransform(rayFromLocalA.getBasis())); - - //btScalar radius = btScalar(0.01); - - btScalar lambda = btScalar(0.); - //todo: need to verify this: - //because of minkowski difference, we need the inverse direction - - btVector3 s = -rayFromLocalA.getOrigin(); - btVector3 r = -(rayToLocalA.getOrigin()-rayFromLocalA.getOrigin()); - btVector3 x = s; - btVector3 v; - btVector3 arbitraryPoint = convex->localGetSupportingVertex(r); - - v = x - arbitraryPoint; - - int maxIter = MAX_ITERATIONS; - - btVector3 n; - n.setValue(btScalar(0.),btScalar(0.),btScalar(0.)); - bool hasResult = false; - btVector3 c; - - btScalar lastLambda = lambda; - - - btScalar dist2 = v.length2(); -#ifdef BT_USE_DOUBLE_PRECISION - btScalar epsilon = btScalar(0.0001); -#else - btScalar epsilon = btScalar(0.0001); -#endif //BT_USE_DOUBLE_PRECISION - btVector3 w,p; - btScalar VdotR; - - while ( (dist2 > epsilon) && maxIter--) - { - p = convex->localGetSupportingVertex( v); - w = x - p; - - btScalar VdotW = v.dot(w); - - if ( VdotW > btScalar(0.)) - { - VdotR = v.dot(r); - - if (VdotR >= -(SIMD_EPSILON*SIMD_EPSILON)) - return false; - else - { - lambda = lambda - VdotW / VdotR; - x = s + lambda * r; - m_simplexSolver->reset(); - //check next line - w = x-p; - lastLambda = lambda; - n = v; - hasResult = true; - } - } - m_simplexSolver->addVertex( w, x , p); - if (m_simplexSolver->closest(v)) - { - dist2 = v.length2(); - hasResult = true; - //printf("V=%f , %f, %f\n",v[0],v[1],v[2]); - //printf("DIST2=%f\n",dist2); - //printf("numverts = %i\n",m_simplexSolver->numVertices()); - } else - { - dist2 = btScalar(0.); - } - } - - //int numiter = MAX_ITERATIONS - maxIter; -// printf("number of iterations: %d", numiter); - result.m_fraction = lambda; - result.m_normal = n; - - return true; -} - - - diff --git a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btSubSimplexConvexCast.h b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btSubSimplexConvexCast.h deleted file mode 100644 index 05662db5d23..00000000000 --- a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btSubSimplexConvexCast.h +++ /dev/null @@ -1,50 +0,0 @@ -/* -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 SUBSIMPLEX_CONVEX_CAST_H -#define SUBSIMPLEX_CONVEX_CAST_H - -#include "btConvexCast.h" -#include "btSimplexSolverInterface.h" -class btConvexShape; - -/// btSubsimplexConvexCast implements Gino van den Bergens' paper -///"Ray Casting against bteral Convex Objects with Application to Continuous Collision Detection" -/// GJK based Ray Cast, optimized version -/// Objects should not start in overlap, otherwise results are not defined. -class btSubsimplexConvexCast : public btConvexCast -{ - btSimplexSolverInterface* m_simplexSolver; - const btConvexShape* m_convexA; - const btConvexShape* m_convexB; - -public: - - btSubsimplexConvexCast (const btConvexShape* shapeA,const btConvexShape* shapeB,btSimplexSolverInterface* simplexSolver); - - //virtual ~btSubsimplexConvexCast(); - ///SimsimplexConvexCast calculateTimeOfImpact calculates the time of impact+normal for the linear cast (sweep) between two moving objects. - ///Precondition is that objects should not penetration/overlap at the start from the interval. Overlap can be tested using btGjkPairDetector. - virtual bool calcTimeOfImpact( - const btTransform& fromA, - const btTransform& toA, - const btTransform& fromB, - const btTransform& toB, - CastResult& result); - -}; - -#endif //SUBSIMPLEX_CONVEX_CAST_H diff --git a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.cpp b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.cpp deleted file mode 100644 index 105b7eccefa..00000000000 --- a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.cpp +++ /dev/null @@ -1,607 +0,0 @@ - -/* -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. - - Elsevier CDROM license agreements grants nonexclusive license to use the software - for any purpose, commercial or non-commercial as long as the following credit is included - identifying the original source of the software: - - Parts of the source are "from the book Real-Time Collision Detection by - Christer Ericson, published by Morgan Kaufmann Publishers, - (c) 2005 Elsevier Inc." - -*/ - - -#include "btVoronoiSimplexSolver.h" -#include -#include - -#define VERTA 0 -#define VERTB 1 -#define VERTC 2 -#define VERTD 3 - -#define CATCH_DEGENERATE_TETRAHEDRON 1 -void btVoronoiSimplexSolver::removeVertex(int index) -{ - - assert(m_numVertices>0); - m_numVertices--; - m_simplexVectorW[index] = m_simplexVectorW[m_numVertices]; - m_simplexPointsP[index] = m_simplexPointsP[m_numVertices]; - m_simplexPointsQ[index] = m_simplexPointsQ[m_numVertices]; -} - -void btVoronoiSimplexSolver::reduceVertices (const btUsageBitfield& usedVerts) -{ - if ((numVertices() >= 4) && (!usedVerts.usedVertexD)) - removeVertex(3); - - if ((numVertices() >= 3) && (!usedVerts.usedVertexC)) - removeVertex(2); - - if ((numVertices() >= 2) && (!usedVerts.usedVertexB)) - removeVertex(1); - - if ((numVertices() >= 1) && (!usedVerts.usedVertexA)) - removeVertex(0); - -} - - - - - -//clear the simplex, remove all the vertices -void btVoronoiSimplexSolver::reset() -{ - m_cachedValidClosest = false; - m_numVertices = 0; - m_needsUpdate = true; - m_lastW = btVector3(btScalar(1e30),btScalar(1e30),btScalar(1e30)); - m_cachedBC.reset(); -} - - - - //add a vertex -void btVoronoiSimplexSolver::addVertex(const btVector3& w, const btPoint3& p, const btPoint3& q) -{ - m_lastW = w; - m_needsUpdate = true; - - m_simplexVectorW[m_numVertices] = w; - m_simplexPointsP[m_numVertices] = p; - m_simplexPointsQ[m_numVertices] = q; - - m_numVertices++; -} - -bool btVoronoiSimplexSolver::updateClosestVectorAndPoints() -{ - - if (m_needsUpdate) - { - m_cachedBC.reset(); - - m_needsUpdate = false; - - switch (numVertices()) - { - case 0: - m_cachedValidClosest = false; - break; - case 1: - { - m_cachedP1 = m_simplexPointsP[0]; - m_cachedP2 = m_simplexPointsQ[0]; - m_cachedV = m_cachedP1-m_cachedP2; //== m_simplexVectorW[0] - m_cachedBC.reset(); - m_cachedBC.setBarycentricCoordinates(btScalar(1.),btScalar(0.),btScalar(0.),btScalar(0.)); - m_cachedValidClosest = m_cachedBC.isValid(); - break; - }; - case 2: - { - //closest point origin from line segment - const btVector3& from = m_simplexVectorW[0]; - const btVector3& to = m_simplexVectorW[1]; - btVector3 nearest; - - btVector3 p (btScalar(0.),btScalar(0.),btScalar(0.)); - btVector3 diff = p - from; - btVector3 v = to - from; - btScalar t = v.dot(diff); - - if (t > 0) { - btScalar dotVV = v.dot(v); - if (t < dotVV) { - t /= dotVV; - diff -= t*v; - m_cachedBC.m_usedVertices.usedVertexA = true; - m_cachedBC.m_usedVertices.usedVertexB = true; - } else { - t = 1; - diff -= v; - //reduce to 1 point - m_cachedBC.m_usedVertices.usedVertexB = true; - } - } else - { - t = 0; - //reduce to 1 point - m_cachedBC.m_usedVertices.usedVertexA = true; - } - m_cachedBC.setBarycentricCoordinates(1-t,t); - nearest = from + t*v; - - m_cachedP1 = m_simplexPointsP[0] + t * (m_simplexPointsP[1] - m_simplexPointsP[0]); - m_cachedP2 = m_simplexPointsQ[0] + t * (m_simplexPointsQ[1] - m_simplexPointsQ[0]); - m_cachedV = m_cachedP1 - m_cachedP2; - - reduceVertices(m_cachedBC.m_usedVertices); - - m_cachedValidClosest = m_cachedBC.isValid(); - break; - } - case 3: - { - //closest point origin from triangle - btVector3 p (btScalar(0.),btScalar(0.),btScalar(0.)); - - const btVector3& a = m_simplexVectorW[0]; - const btVector3& b = m_simplexVectorW[1]; - const btVector3& c = m_simplexVectorW[2]; - - closestPtPointTriangle(p,a,b,c,m_cachedBC); - m_cachedP1 = m_simplexPointsP[0] * m_cachedBC.m_barycentricCoords[0] + - m_simplexPointsP[1] * m_cachedBC.m_barycentricCoords[1] + - m_simplexPointsP[2] * m_cachedBC.m_barycentricCoords[2]; - - m_cachedP2 = m_simplexPointsQ[0] * m_cachedBC.m_barycentricCoords[0] + - m_simplexPointsQ[1] * m_cachedBC.m_barycentricCoords[1] + - m_simplexPointsQ[2] * m_cachedBC.m_barycentricCoords[2]; - - m_cachedV = m_cachedP1-m_cachedP2; - - reduceVertices (m_cachedBC.m_usedVertices); - m_cachedValidClosest = m_cachedBC.isValid(); - - break; - } - case 4: - { - - - btVector3 p (btScalar(0.),btScalar(0.),btScalar(0.)); - - const btVector3& a = m_simplexVectorW[0]; - const btVector3& b = m_simplexVectorW[1]; - const btVector3& c = m_simplexVectorW[2]; - const btVector3& d = m_simplexVectorW[3]; - - bool hasSeperation = closestPtPointTetrahedron(p,a,b,c,d,m_cachedBC); - - if (hasSeperation) - { - - m_cachedP1 = m_simplexPointsP[0] * m_cachedBC.m_barycentricCoords[0] + - m_simplexPointsP[1] * m_cachedBC.m_barycentricCoords[1] + - m_simplexPointsP[2] * m_cachedBC.m_barycentricCoords[2] + - m_simplexPointsP[3] * m_cachedBC.m_barycentricCoords[3]; - - m_cachedP2 = m_simplexPointsQ[0] * m_cachedBC.m_barycentricCoords[0] + - m_simplexPointsQ[1] * m_cachedBC.m_barycentricCoords[1] + - m_simplexPointsQ[2] * m_cachedBC.m_barycentricCoords[2] + - m_simplexPointsQ[3] * m_cachedBC.m_barycentricCoords[3]; - - m_cachedV = m_cachedP1-m_cachedP2; - reduceVertices (m_cachedBC.m_usedVertices); - } else - { -// printf("sub distance got penetration\n"); - - if (m_cachedBC.m_degenerate) - { - m_cachedValidClosest = false; - } else - { - m_cachedValidClosest = true; - //degenerate case == false, penetration = true + zero - m_cachedV.setValue(btScalar(0.),btScalar(0.),btScalar(0.)); - } - break; - } - - m_cachedValidClosest = m_cachedBC.isValid(); - - //closest point origin from tetrahedron - break; - } - default: - { - m_cachedValidClosest = false; - } - }; - } - - return m_cachedValidClosest; - -} - -//return/calculate the closest vertex -bool btVoronoiSimplexSolver::closest(btVector3& v) -{ - bool succes = updateClosestVectorAndPoints(); - v = m_cachedV; - return succes; -} - - - -btScalar btVoronoiSimplexSolver::maxVertex() -{ - int i, numverts = numVertices(); - btScalar maxV = btScalar(0.); - for (i=0;i= btScalar(0.0) && d4 <= d3) - { - result.m_closestPointOnSimplex = b; - result.m_usedVertices.usedVertexB = true; - result.setBarycentricCoordinates(0,1,0); - - return true; // b; // barycentric coordinates (0,1,0) - } - // Check if P in edge region of AB, if so return projection of P onto AB - btScalar vc = d1*d4 - d3*d2; - if (vc <= btScalar(0.0) && d1 >= btScalar(0.0) && d3 <= btScalar(0.0)) { - btScalar v = d1 / (d1 - d3); - result.m_closestPointOnSimplex = a + v * ab; - result.m_usedVertices.usedVertexA = true; - result.m_usedVertices.usedVertexB = true; - result.setBarycentricCoordinates(1-v,v,0); - return true; - //return a + v * ab; // barycentric coordinates (1-v,v,0) - } - - // Check if P in vertex region outside C - btVector3 cp = p - c; - btScalar d5 = ab.dot(cp); - btScalar d6 = ac.dot(cp); - if (d6 >= btScalar(0.0) && d5 <= d6) - { - result.m_closestPointOnSimplex = c; - result.m_usedVertices.usedVertexC = true; - result.setBarycentricCoordinates(0,0,1); - return true;//c; // barycentric coordinates (0,0,1) - } - - // Check if P in edge region of AC, if so return projection of P onto AC - btScalar vb = d5*d2 - d1*d6; - if (vb <= btScalar(0.0) && d2 >= btScalar(0.0) && d6 <= btScalar(0.0)) { - btScalar w = d2 / (d2 - d6); - result.m_closestPointOnSimplex = a + w * ac; - result.m_usedVertices.usedVertexA = true; - result.m_usedVertices.usedVertexC = true; - result.setBarycentricCoordinates(1-w,0,w); - return true; - //return a + w * ac; // barycentric coordinates (1-w,0,w) - } - - // Check if P in edge region of BC, if so return projection of P onto BC - btScalar va = d3*d6 - d5*d4; - if (va <= btScalar(0.0) && (d4 - d3) >= btScalar(0.0) && (d5 - d6) >= btScalar(0.0)) { - btScalar w = (d4 - d3) / ((d4 - d3) + (d5 - d6)); - - result.m_closestPointOnSimplex = b + w * (c - b); - result.m_usedVertices.usedVertexB = true; - result.m_usedVertices.usedVertexC = true; - result.setBarycentricCoordinates(0,1-w,w); - return true; - // return b + w * (c - b); // barycentric coordinates (0,1-w,w) - } - - // P inside face region. Compute Q through its barycentric coordinates (u,v,w) - btScalar denom = btScalar(1.0) / (va + vb + vc); - btScalar v = vb * denom; - btScalar w = vc * denom; - - result.m_closestPointOnSimplex = a + ab * v + ac * w; - result.m_usedVertices.usedVertexA = true; - result.m_usedVertices.usedVertexB = true; - result.m_usedVertices.usedVertexC = true; - result.setBarycentricCoordinates(1-v-w,v,w); - - return true; -// return a + ab * v + ac * w; // = u*a + v*b + w*c, u = va * denom = btScalar(1.0) - v - w - -} - - - - - -/// Test if point p and d lie on opposite sides of plane through abc -int btVoronoiSimplexSolver::pointOutsideOfPlane(const btPoint3& p, const btPoint3& a, const btPoint3& b, const btPoint3& c, const btPoint3& d) -{ - btVector3 normal = (b-a).cross(c-a); - - btScalar signp = (p - a).dot(normal); // [AP AB AC] - btScalar signd = (d - a).dot( normal); // [AD AB AC] - -#ifdef CATCH_DEGENERATE_TETRAHEDRON -#ifdef BT_USE_DOUBLE_PRECISION -if (signd * signd < (btScalar(1e-8) * btScalar(1e-8))) - { - return -1; - } -#else - if (signd * signd < (btScalar(1e-4) * btScalar(1e-4))) - { -// printf("affine dependent/degenerate\n");// - return -1; - } -#endif - -#endif - // Points on opposite sides if expression signs are opposite - return signp * signd < btScalar(0.); -} - - -bool btVoronoiSimplexSolver::closestPtPointTetrahedron(const btPoint3& p, const btPoint3& a, const btPoint3& b, const btPoint3& c, const btPoint3& d, btSubSimplexClosestResult& finalResult) -{ - btSubSimplexClosestResult tempResult; - - // Start out assuming point inside all halfspaces, so closest to itself - finalResult.m_closestPointOnSimplex = p; - finalResult.m_usedVertices.reset(); - finalResult.m_usedVertices.usedVertexA = true; - finalResult.m_usedVertices.usedVertexB = true; - finalResult.m_usedVertices.usedVertexC = true; - finalResult.m_usedVertices.usedVertexD = true; - - int pointOutsideABC = pointOutsideOfPlane(p, a, b, c, d); - int pointOutsideACD = pointOutsideOfPlane(p, a, c, d, b); - int pointOutsideADB = pointOutsideOfPlane(p, a, d, b, c); - int pointOutsideBDC = pointOutsideOfPlane(p, b, d, c, a); - - if (pointOutsideABC < 0 || pointOutsideACD < 0 || pointOutsideADB < 0 || pointOutsideBDC < 0) - { - finalResult.m_degenerate = true; - return false; - } - - if (!pointOutsideABC && !pointOutsideACD && !pointOutsideADB && !pointOutsideBDC) - { - return false; - } - - - btScalar bestSqDist = FLT_MAX; - // If point outside face abc then compute closest point on abc - if (pointOutsideABC) - { - closestPtPointTriangle(p, a, b, c,tempResult); - btPoint3 q = tempResult.m_closestPointOnSimplex; - - btScalar sqDist = (q - p).dot( q - p); - // Update best closest point if (squared) distance is less than current best - if (sqDist < bestSqDist) { - bestSqDist = sqDist; - finalResult.m_closestPointOnSimplex = q; - //convert result bitmask! - finalResult.m_usedVertices.reset(); - finalResult.m_usedVertices.usedVertexA = tempResult.m_usedVertices.usedVertexA; - finalResult.m_usedVertices.usedVertexB = tempResult.m_usedVertices.usedVertexB; - finalResult.m_usedVertices.usedVertexC = tempResult.m_usedVertices.usedVertexC; - finalResult.setBarycentricCoordinates( - tempResult.m_barycentricCoords[VERTA], - tempResult.m_barycentricCoords[VERTB], - tempResult.m_barycentricCoords[VERTC], - 0 - ); - - } - } - - - // Repeat test for face acd - if (pointOutsideACD) - { - closestPtPointTriangle(p, a, c, d,tempResult); - btPoint3 q = tempResult.m_closestPointOnSimplex; - //convert result bitmask! - - btScalar sqDist = (q - p).dot( q - p); - if (sqDist < bestSqDist) - { - bestSqDist = sqDist; - finalResult.m_closestPointOnSimplex = q; - finalResult.m_usedVertices.reset(); - finalResult.m_usedVertices.usedVertexA = tempResult.m_usedVertices.usedVertexA; - - finalResult.m_usedVertices.usedVertexC = tempResult.m_usedVertices.usedVertexB; - finalResult.m_usedVertices.usedVertexD = tempResult.m_usedVertices.usedVertexC; - finalResult.setBarycentricCoordinates( - tempResult.m_barycentricCoords[VERTA], - 0, - tempResult.m_barycentricCoords[VERTB], - tempResult.m_barycentricCoords[VERTC] - ); - - } - } - // Repeat test for face adb - - - if (pointOutsideADB) - { - closestPtPointTriangle(p, a, d, b,tempResult); - btPoint3 q = tempResult.m_closestPointOnSimplex; - //convert result bitmask! - - btScalar sqDist = (q - p).dot( q - p); - if (sqDist < bestSqDist) - { - bestSqDist = sqDist; - finalResult.m_closestPointOnSimplex = q; - finalResult.m_usedVertices.reset(); - finalResult.m_usedVertices.usedVertexA = tempResult.m_usedVertices.usedVertexA; - finalResult.m_usedVertices.usedVertexB = tempResult.m_usedVertices.usedVertexC; - - finalResult.m_usedVertices.usedVertexD = tempResult.m_usedVertices.usedVertexB; - finalResult.setBarycentricCoordinates( - tempResult.m_barycentricCoords[VERTA], - tempResult.m_barycentricCoords[VERTC], - 0, - tempResult.m_barycentricCoords[VERTB] - ); - - } - } - // Repeat test for face bdc - - - if (pointOutsideBDC) - { - closestPtPointTriangle(p, b, d, c,tempResult); - btPoint3 q = tempResult.m_closestPointOnSimplex; - //convert result bitmask! - btScalar sqDist = (q - p).dot( q - p); - if (sqDist < bestSqDist) - { - bestSqDist = sqDist; - finalResult.m_closestPointOnSimplex = q; - finalResult.m_usedVertices.reset(); - // - finalResult.m_usedVertices.usedVertexB = tempResult.m_usedVertices.usedVertexA; - finalResult.m_usedVertices.usedVertexC = tempResult.m_usedVertices.usedVertexC; - finalResult.m_usedVertices.usedVertexD = tempResult.m_usedVertices.usedVertexB; - - finalResult.setBarycentricCoordinates( - 0, - tempResult.m_barycentricCoords[VERTA], - tempResult.m_barycentricCoords[VERTC], - tempResult.m_barycentricCoords[VERTB] - ); - - } - } - - //help! we ended up full ! - - if (finalResult.m_usedVertices.usedVertexA && - finalResult.m_usedVertices.usedVertexB && - finalResult.m_usedVertices.usedVertexC && - finalResult.m_usedVertices.usedVertexD) - { - return true; - } - - return true; -} - diff --git a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.h b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.h deleted file mode 100644 index 356d335bc93..00000000000 --- a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.h +++ /dev/null @@ -1,157 +0,0 @@ -/* -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 btVoronoiSimplexSolver_H -#define btVoronoiSimplexSolver_H - -#include "btSimplexSolverInterface.h" - - - -#define VORONOI_SIMPLEX_MAX_VERTS 5 - -struct btUsageBitfield{ - btUsageBitfield() - { - reset(); - } - - void reset() - { - usedVertexA = false; - usedVertexB = false; - usedVertexC = false; - usedVertexD = false; - } - unsigned short usedVertexA : 1; - unsigned short usedVertexB : 1; - unsigned short usedVertexC : 1; - unsigned short usedVertexD : 1; - unsigned short unused1 : 1; - unsigned short unused2 : 1; - unsigned short unused3 : 1; - unsigned short unused4 : 1; -}; - - -struct btSubSimplexClosestResult -{ - btPoint3 m_closestPointOnSimplex; - //MASK for m_usedVertices - //stores the simplex vertex-usage, using the MASK, - // if m_usedVertices & MASK then the related vertex is used - btUsageBitfield m_usedVertices; - btScalar m_barycentricCoords[4]; - bool m_degenerate; - - void reset() - { - m_degenerate = false; - setBarycentricCoordinates(); - m_usedVertices.reset(); - } - bool isValid() - { - bool valid = (m_barycentricCoords[0] >= btScalar(0.)) && - (m_barycentricCoords[1] >= btScalar(0.)) && - (m_barycentricCoords[2] >= btScalar(0.)) && - (m_barycentricCoords[3] >= btScalar(0.)); - - - return valid; - } - void setBarycentricCoordinates(btScalar a=btScalar(0.),btScalar b=btScalar(0.),btScalar c=btScalar(0.),btScalar d=btScalar(0.)) - { - m_barycentricCoords[0] = a; - m_barycentricCoords[1] = b; - m_barycentricCoords[2] = c; - m_barycentricCoords[3] = d; - } - -}; - -/// btVoronoiSimplexSolver is an implementation of the closest point distance algorithm from a 1-4 points simplex to the origin. -/// Can be used with GJK, as an alternative to Johnson distance algorithm. -#ifdef NO_VIRTUAL_INTERFACE -class btVoronoiSimplexSolver -#else -class btVoronoiSimplexSolver : public btSimplexSolverInterface -#endif -{ -public: - - int m_numVertices; - - btVector3 m_simplexVectorW[VORONOI_SIMPLEX_MAX_VERTS]; - btPoint3 m_simplexPointsP[VORONOI_SIMPLEX_MAX_VERTS]; - btPoint3 m_simplexPointsQ[VORONOI_SIMPLEX_MAX_VERTS]; - - - - btPoint3 m_cachedP1; - btPoint3 m_cachedP2; - btVector3 m_cachedV; - btVector3 m_lastW; - bool m_cachedValidClosest; - - btSubSimplexClosestResult m_cachedBC; - - bool m_needsUpdate; - - void removeVertex(int index); - void reduceVertices (const btUsageBitfield& usedVerts); - bool updateClosestVectorAndPoints(); - - bool closestPtPointTetrahedron(const btPoint3& p, const btPoint3& a, const btPoint3& b, const btPoint3& c, const btPoint3& d, btSubSimplexClosestResult& finalResult); - int pointOutsideOfPlane(const btPoint3& p, const btPoint3& a, const btPoint3& b, const btPoint3& c, const btPoint3& d); - bool closestPtPointTriangle(const btPoint3& p, const btPoint3& a, const btPoint3& b, const btPoint3& c,btSubSimplexClosestResult& result); - -public: - - void reset(); - - void addVertex(const btVector3& w, const btPoint3& p, const btPoint3& q); - - - bool closest(btVector3& v); - - btScalar maxVertex(); - - bool fullSimplex() const - { - return (m_numVertices == 4); - } - - int getSimplex(btPoint3 *pBuf, btPoint3 *qBuf, btVector3 *yBuf) const; - - bool inSimplex(const btVector3& w); - - void backup_closest(btVector3& v) ; - - bool emptySimplex() const ; - - void compute_points(btPoint3& p1, btPoint3& p2) ; - - int numVertices() const - { - return m_numVertices; - } - - -}; - -#endif //VoronoiSimplexSolver diff --git a/extern/bullet2/src/BulletCollision/ibmsdk/Makefile b/extern/bullet2/src/BulletCollision/ibmsdk/Makefile deleted file mode 100644 index ad04ef1d295..00000000000 --- a/extern/bullet2/src/BulletCollision/ibmsdk/Makefile +++ /dev/null @@ -1,95 +0,0 @@ -#### Source code Dirs -VPATH = \ -../BroadphaseCollision \ -../CollisionDispatch \ -../NarrowPhaseCollision \ -../CollisionShapes - -ROOT = ../../.. - -#### Library -LIBRARY_ppu = bulletcollision.a - -#### Compiler flags -CPPFLAGS = \ --DUSE_LIBSPE2 \ --I../BroadphaseCollision \ --I../CollisionDispath \ --I../NarrowPhaseCollision \ --I../CollisionShapes \ --I$(ROOT)/src/ \ --I$(SDKINC) - -#### Optimization level flags -#CC_OPT_LEVEL = $(CC_OPT_LEVEL_DEBUG) -CC_OPT_LEVEL = -O3 - -##### Objects to be archived in lib - -OBJS = \ -btAxisSweep3.o \ -btBroadphaseProxy.o \ -btCollisionAlgorithm.o \ -btDispatcher.o \ -btOverlappingPairCache.o \ -btSimpleBroadphase.o \ -btContinuousConvexCollision.o \ -btConvexCast.o \ -btGjkConvexCast.o \ -btGjkEpa.o \ -btGjkEpaPenetrationDepthSolver.o \ -btGjkPairDetector.o \ -btDefaultCollisionConfiguration.o \ -btMinkowskiPenetrationDepthSolver.o \ -btPersistentManifold.o \ -btRaycastCallback.o \ -btSubSimplexConvexCast.o \ -btVoronoiSimplexSolver.o \ -btCollisionDispatcher.o \ -btCollisionObject.o \ -btCollisionWorld.o \ -btCompoundCollisionAlgorithm.o \ -btConvexConcaveCollisionAlgorithm.o \ -btConvexConvexAlgorithm.o \ -btEmptyCollisionAlgorithm.o \ -btManifoldResult.o \ -btSimulationIslandManager.o \ -btSphereBoxCollisionAlgorithm.o \ -btSphereSphereCollisionAlgorithm.o \ -btSphereTriangleCollisionAlgorithm.o \ -btUnionFind.o \ -SphereTriangleDetector.o \ -btBoxShape.o \ -btBvhTriangleMeshShape.o \ -btCapsuleShape.o \ -btCollisionShape.o \ -btCompoundShape.o \ -btConcaveShape.o \ -btConeShape.o \ -btConvexHullShape.o \ -btConvexShape.o \ -btConvexInternalShape.o \ -btConvexTriangleMeshShape.o \ -btCylinderShape.o \ -btEmptyShape.o \ -btHeightfieldTerrainShape.o \ -btMinkowskiSumShape.o \ -btMultiSphereShape.o \ -btOptimizedBvh.o \ -btPolyhedralConvexShape.o \ -btSphereShape.o \ -btStaticPlaneShape.o \ -btStridingMeshInterface.o \ -btTetrahedronShape.o \ -btTriangleBuffer.o \ -btTriangleCallback.o \ -btTriangleIndexVertexArray.o \ -btTriangleMesh.o \ -btTriangleMeshShape.o \ -btUniformScalingShape.o - -#### Install directories -INSTALL_DIR = $(ROOT)/lib/ibmsdk -INSTALL_FILES = $(LIBRARY_ppu) -CELL_TOP ?= /opt/ibm/cell-sdk/prototype -include $(CELL_TOP)/make.footer diff --git a/extern/bullet2/src/BulletDynamics/CMakeLists.txt b/extern/bullet2/src/BulletDynamics/CMakeLists.txt deleted file mode 100644 index 97ccd7ed08a..00000000000 --- a/extern/bullet2/src/BulletDynamics/CMakeLists.txt +++ /dev/null @@ -1,22 +0,0 @@ -INCLUDE_DIRECTORIES( -${BULLET_PHYSICS_SOURCE_DIR}/src } -) - -ADD_LIBRARY(LibBulletDynamics - - ConstraintSolver/btContactConstraint.cpp - ConstraintSolver/btConeTwistConstraint.cpp - ConstraintSolver/btGeneric6DofConstraint.cpp - ConstraintSolver/btHingeConstraint.cpp - ConstraintSolver/btPoint2PointConstraint.cpp - ConstraintSolver/btSequentialImpulseConstraintSolver.cpp - ConstraintSolver/btSolve2LinearConstraint.cpp - ConstraintSolver/btTypedConstraint.cpp - Dynamics/Bullet-C-API.cpp - Dynamics/btDiscreteDynamicsWorld.cpp - Dynamics/btSimpleDynamicsWorld.cpp - Dynamics/Bullet-C-API.cpp - Dynamics/btRigidBody.cpp - Vehicle/btRaycastVehicle.cpp - Vehicle/btWheelInfo.cpp -) diff --git a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btConeTwistConstraint.cpp b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btConeTwistConstraint.cpp deleted file mode 100644 index a8a2c4f6763..00000000000 --- a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btConeTwistConstraint.cpp +++ /dev/null @@ -1,286 +0,0 @@ -/* -Bullet Continuous Collision Detection and Physics Library -btConeTwistConstraint is Copyright (c) 2007 Starbreeze Studios - -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. - -Written by: Marcus Hennix -*/ - - -#include "btConeTwistConstraint.h" -#include "BulletDynamics/Dynamics/btRigidBody.h" -#include "LinearMath/btTransformUtil.h" -#include "LinearMath/btMinMax.h" -#include - -btConeTwistConstraint::btConeTwistConstraint() -:btTypedConstraint(CONETWIST_CONSTRAINT_TYPE) -{ -} - - -btConeTwistConstraint::btConeTwistConstraint(btRigidBody& rbA,btRigidBody& rbB, - const btTransform& rbAFrame,const btTransform& rbBFrame) - :btTypedConstraint(CONETWIST_CONSTRAINT_TYPE, rbA,rbB),m_rbAFrame(rbAFrame),m_rbBFrame(rbBFrame), - m_angularOnly(false) -{ - // flip axis for correct angles - m_rbBFrame.getBasis()[1][0] *= btScalar(-1.); - m_rbBFrame.getBasis()[1][1] *= btScalar(-1.); - m_rbBFrame.getBasis()[1][2] *= btScalar(-1.); - - m_swingSpan1 = btScalar(1e30); - m_swingSpan2 = btScalar(1e30); - m_twistSpan = btScalar(1e30); - m_biasFactor = 0.3f; - m_relaxationFactor = 1.0f; - - m_solveTwistLimit = false; - m_solveSwingLimit = false; - -} - -btConeTwistConstraint::btConeTwistConstraint(btRigidBody& rbA,const btTransform& rbAFrame) - :btTypedConstraint(CONETWIST_CONSTRAINT_TYPE,rbA),m_rbAFrame(rbAFrame), - m_angularOnly(false) -{ - m_rbBFrame = m_rbAFrame; - - // flip axis for correct angles - m_rbBFrame.getBasis()[1][0] *= btScalar(-1.); - m_rbBFrame.getBasis()[1][1] *= btScalar(-1.); - m_rbBFrame.getBasis()[1][2] *= btScalar(-1.); - - m_rbBFrame.getBasis()[2][0] *= btScalar(-1.); - m_rbBFrame.getBasis()[2][1] *= btScalar(-1.); - m_rbBFrame.getBasis()[2][2] *= btScalar(-1.); - - m_swingSpan1 = btScalar(1e30); - m_swingSpan2 = btScalar(1e30); - m_twistSpan = btScalar(1e30); - m_biasFactor = 0.3f; - m_relaxationFactor = 1.0f; - - m_solveTwistLimit = false; - m_solveSwingLimit = false; - -} - -void btConeTwistConstraint::buildJacobian() -{ - m_appliedImpulse = btScalar(0.); - - //set bias, sign, clear accumulator - m_swingCorrection = btScalar(0.); - m_twistLimitSign = btScalar(0.); - m_solveTwistLimit = false; - m_solveSwingLimit = false; - m_accTwistLimitImpulse = btScalar(0.); - m_accSwingLimitImpulse = btScalar(0.); - - if (!m_angularOnly) - { - btVector3 pivotAInW = m_rbA.getCenterOfMassTransform()*m_rbAFrame.getOrigin(); - btVector3 pivotBInW = m_rbB.getCenterOfMassTransform()*m_rbBFrame.getOrigin(); - btVector3 relPos = pivotBInW - pivotAInW; - - btVector3 normal[3]; - if (relPos.length2() > SIMD_EPSILON) - { - normal[0] = relPos.normalized(); - } - else - { - normal[0].setValue(btScalar(1.0),0,0); - } - - btPlaneSpace1(normal[0], normal[1], normal[2]); - - for (int i=0;i<3;i++) - { - new (&m_jac[i]) btJacobianEntry( - m_rbA.getCenterOfMassTransform().getBasis().transpose(), - m_rbB.getCenterOfMassTransform().getBasis().transpose(), - pivotAInW - m_rbA.getCenterOfMassPosition(), - pivotBInW - m_rbB.getCenterOfMassPosition(), - normal[i], - m_rbA.getInvInertiaDiagLocal(), - m_rbA.getInvMass(), - m_rbB.getInvInertiaDiagLocal(), - m_rbB.getInvMass()); - } - } - - btVector3 b1Axis1,b1Axis2,b1Axis3; - btVector3 b2Axis1,b2Axis2; - - b1Axis1 = getRigidBodyA().getCenterOfMassTransform().getBasis() * this->m_rbAFrame.getBasis().getColumn(0); - b2Axis1 = getRigidBodyB().getCenterOfMassTransform().getBasis() * this->m_rbBFrame.getBasis().getColumn(0); - - btScalar swing1=btScalar(0.),swing2 = btScalar(0.); - - // Get Frame into world space - if (m_swingSpan1 >= btScalar(0.05f)) - { - b1Axis2 = getRigidBodyA().getCenterOfMassTransform().getBasis() * this->m_rbAFrame.getBasis().getColumn(1); - swing1 = btAtan2Fast( b2Axis1.dot(b1Axis2),b2Axis1.dot(b1Axis1) ); - } - - if (m_swingSpan2 >= btScalar(0.05f)) - { - b1Axis3 = getRigidBodyA().getCenterOfMassTransform().getBasis() * this->m_rbAFrame.getBasis().getColumn(2); - swing2 = btAtan2Fast( b2Axis1.dot(b1Axis3),b2Axis1.dot(b1Axis1) ); - } - - btScalar RMaxAngle1Sq = 1.0f / (m_swingSpan1*m_swingSpan1); - btScalar RMaxAngle2Sq = 1.0f / (m_swingSpan2*m_swingSpan2); - btScalar EllipseAngle = btFabs(swing1)* RMaxAngle1Sq + btFabs(swing2) * RMaxAngle2Sq; - - if (EllipseAngle > 1.0f) - { - m_swingCorrection = EllipseAngle-1.0f; - m_solveSwingLimit = true; - - // Calculate necessary axis & factors - m_swingAxis = b2Axis1.cross(b1Axis2* b2Axis1.dot(b1Axis2) + b1Axis3* b2Axis1.dot(b1Axis3)); - m_swingAxis.normalize(); - - btScalar swingAxisSign = (b2Axis1.dot(b1Axis1) >= 0.0f) ? 1.0f : -1.0f; - m_swingAxis *= swingAxisSign; - - m_kSwing = btScalar(1.) / (getRigidBodyA().computeAngularImpulseDenominator(m_swingAxis) + - getRigidBodyB().computeAngularImpulseDenominator(m_swingAxis)); - - } - - // Twist limits - if (m_twistSpan >= btScalar(0.)) - { - btVector3 b2Axis2 = getRigidBodyB().getCenterOfMassTransform().getBasis() * this->m_rbBFrame.getBasis().getColumn(1); - btQuaternion rotationArc = shortestArcQuat(b2Axis1,b1Axis1); - btVector3 TwistRef = quatRotate(rotationArc,b2Axis2); - btScalar twist = btAtan2Fast( TwistRef.dot(b1Axis3), TwistRef.dot(b1Axis2) ); - - btScalar lockedFreeFactor = (m_twistSpan > btScalar(0.05f)) ? m_limitSoftness : btScalar(0.); - if (twist <= -m_twistSpan*lockedFreeFactor) - { - m_twistCorrection = -(twist + m_twistSpan); - m_solveTwistLimit = true; - - m_twistAxis = (b2Axis1 + b1Axis1) * 0.5f; - m_twistAxis.normalize(); - m_twistAxis *= -1.0f; - - m_kTwist = btScalar(1.) / (getRigidBodyA().computeAngularImpulseDenominator(m_twistAxis) + - getRigidBodyB().computeAngularImpulseDenominator(m_twistAxis)); - - } else - if (twist > m_twistSpan*lockedFreeFactor) - { - m_twistCorrection = (twist - m_twistSpan); - m_solveTwistLimit = true; - - m_twistAxis = (b2Axis1 + b1Axis1) * 0.5f; - m_twistAxis.normalize(); - - m_kTwist = btScalar(1.) / (getRigidBodyA().computeAngularImpulseDenominator(m_twistAxis) + - getRigidBodyB().computeAngularImpulseDenominator(m_twistAxis)); - - } - } -} - -void btConeTwistConstraint::solveConstraint(btScalar timeStep) -{ - - btVector3 pivotAInW = m_rbA.getCenterOfMassTransform()*m_rbAFrame.getOrigin(); - btVector3 pivotBInW = m_rbB.getCenterOfMassTransform()*m_rbBFrame.getOrigin(); - - btScalar tau = btScalar(0.3); - - //linear part - if (!m_angularOnly) - { - btVector3 rel_pos1 = pivotAInW - m_rbA.getCenterOfMassPosition(); - btVector3 rel_pos2 = pivotBInW - m_rbB.getCenterOfMassPosition(); - - btVector3 vel1 = m_rbA.getVelocityInLocalPoint(rel_pos1); - btVector3 vel2 = m_rbB.getVelocityInLocalPoint(rel_pos2); - btVector3 vel = vel1 - vel2; - - for (int i=0;i<3;i++) - { - const btVector3& normal = m_jac[i].m_linearJointAxis; - btScalar jacDiagABInv = btScalar(1.) / m_jac[i].getDiagonal(); - - btScalar rel_vel; - rel_vel = normal.dot(vel); - //positional error (zeroth order error) - btScalar depth = -(pivotAInW - pivotBInW).dot(normal); //this is the error projected on the normal - btScalar impulse = depth*tau/timeStep * jacDiagABInv - rel_vel * jacDiagABInv; - m_appliedImpulse += impulse; - btVector3 impulse_vector = normal * impulse; - m_rbA.applyImpulse(impulse_vector, pivotAInW - m_rbA.getCenterOfMassPosition()); - m_rbB.applyImpulse(-impulse_vector, pivotBInW - m_rbB.getCenterOfMassPosition()); - } - } - - { - ///solve angular part - const btVector3& angVelA = getRigidBodyA().getAngularVelocity(); - const btVector3& angVelB = getRigidBodyB().getAngularVelocity(); - - // solve swing limit - if (m_solveSwingLimit) - { - btScalar amplitude = ((angVelB - angVelA).dot( m_swingAxis )*m_relaxationFactor*m_relaxationFactor + m_swingCorrection*(btScalar(1.)/timeStep)*m_biasFactor); - btScalar impulseMag = amplitude * m_kSwing; - - // Clamp the accumulated impulse - btScalar temp = m_accSwingLimitImpulse; - m_accSwingLimitImpulse = btMax(m_accSwingLimitImpulse + impulseMag, btScalar(0.0) ); - impulseMag = m_accSwingLimitImpulse - temp; - - btVector3 impulse = m_swingAxis * impulseMag; - - m_rbA.applyTorqueImpulse(impulse); - m_rbB.applyTorqueImpulse(-impulse); - - } - - // solve twist limit - if (m_solveTwistLimit) - { - btScalar amplitude = ((angVelB - angVelA).dot( m_twistAxis )*m_relaxationFactor*m_relaxationFactor + m_twistCorrection*(btScalar(1.)/timeStep)*m_biasFactor ); - btScalar impulseMag = amplitude * m_kTwist; - - // Clamp the accumulated impulse - btScalar temp = m_accTwistLimitImpulse; - m_accTwistLimitImpulse = btMax(m_accTwistLimitImpulse + impulseMag, btScalar(0.0) ); - impulseMag = m_accTwistLimitImpulse - temp; - - btVector3 impulse = m_twistAxis * impulseMag; - - m_rbA.applyTorqueImpulse(impulse); - m_rbB.applyTorqueImpulse(-impulse); - - } - - } - -} - -void btConeTwistConstraint::updateRHS(btScalar timeStep) -{ - (void)timeStep; - -} diff --git a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btConeTwistConstraint.h b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btConeTwistConstraint.h deleted file mode 100644 index f121919c8f9..00000000000 --- a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btConeTwistConstraint.h +++ /dev/null @@ -1,126 +0,0 @@ -/* -Bullet Continuous Collision Detection and Physics Library -btConeTwistConstraint is Copyright (c) 2007 Starbreeze Studios - -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. - -Written by: Marcus Hennix -*/ - - - -#ifndef CONETWISTCONSTRAINT_H -#define CONETWISTCONSTRAINT_H - -#include "../../LinearMath/btVector3.h" -#include "btJacobianEntry.h" -#include "btTypedConstraint.h" - -class btRigidBody; - - -///btConeTwistConstraint can be used to simulate ragdoll joints (upper arm, leg etc) -class btConeTwistConstraint : public btTypedConstraint -{ -#ifdef IN_PARALLELL_SOLVER -public: -#endif - btJacobianEntry m_jac[3]; //3 orthogonal linear constraints - - btTransform m_rbAFrame; - btTransform m_rbBFrame; - - btScalar m_limitSoftness; - btScalar m_biasFactor; - btScalar m_relaxationFactor; - - btScalar m_swingSpan1; - btScalar m_swingSpan2; - btScalar m_twistSpan; - - btVector3 m_swingAxis; - btVector3 m_twistAxis; - - btScalar m_kSwing; - btScalar m_kTwist; - - btScalar m_twistLimitSign; - btScalar m_swingCorrection; - btScalar m_twistCorrection; - - btScalar m_accSwingLimitImpulse; - btScalar m_accTwistLimitImpulse; - - bool m_angularOnly; - bool m_solveTwistLimit; - bool m_solveSwingLimit; - - -public: - - btConeTwistConstraint(btRigidBody& rbA,btRigidBody& rbB,const btTransform& rbAFrame, const btTransform& rbBFrame); - - btConeTwistConstraint(btRigidBody& rbA,const btTransform& rbAFrame); - - btConeTwistConstraint(); - - virtual void buildJacobian(); - - virtual void solveConstraint(btScalar timeStep); - - void updateRHS(btScalar timeStep); - - const btRigidBody& getRigidBodyA() const - { - return m_rbA; - } - const btRigidBody& getRigidBodyB() const - { - return m_rbB; - } - - void setAngularOnly(bool angularOnly) - { - m_angularOnly = angularOnly; - } - - void setLimit(btScalar _swingSpan1,btScalar _swingSpan2,btScalar _twistSpan, btScalar _softness = 0.8f, btScalar _biasFactor = 0.3f, btScalar _relaxationFactor = 1.0f) - { - m_swingSpan1 = _swingSpan1; - m_swingSpan2 = _swingSpan2; - m_twistSpan = _twistSpan; - - m_limitSoftness = _softness; - m_biasFactor = _biasFactor; - m_relaxationFactor = _relaxationFactor; - } - - const btTransform& getAFrame() { return m_rbAFrame; }; - const btTransform& getBFrame() { return m_rbBFrame; }; - - inline int getSolveTwistLimit() - { - return m_solveTwistLimit; - } - - inline int getSolveSwingLimit() - { - return m_solveTwistLimit; - } - - inline btScalar getTwistLimitSign() - { - return m_twistLimitSign; - } - -}; - -#endif //CONETWISTCONSTRAINT_H diff --git a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btConstraintSolver.h b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btConstraintSolver.h deleted file mode 100644 index addfb67a839..00000000000 --- a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btConstraintSolver.h +++ /dev/null @@ -1,52 +0,0 @@ -/* -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 CONSTRAINT_SOLVER_H -#define CONSTRAINT_SOLVER_H - -#include "LinearMath/btScalar.h" - -class btPersistentManifold; -class btRigidBody; -class btCollisionObject; -class btTypedConstraint; -struct btContactSolverInfo; -struct btBroadphaseProxy; -class btIDebugDraw; -class btStackAlloc; -class btDispatcher; -/// btConstraintSolver provides solver interface -class btConstraintSolver -{ - -public: - - virtual ~btConstraintSolver() {} - - virtual void prepareSolve (int numBodies, int numManifolds) {;} - - ///solve a group of constraints - virtual btScalar solveGroup(btCollisionObject** bodies,int numBodies,btPersistentManifold** manifold,int numManifolds,btTypedConstraint** constraints,int numConstraints, const btContactSolverInfo& info,class btIDebugDraw* debugDrawer, btStackAlloc* stackAlloc,btDispatcher* dispatcher) = 0; - - virtual void allSolved (const btContactSolverInfo& info,class btIDebugDraw* debugDrawer, btStackAlloc* stackAlloc) {;} - - ///clear internal cached data and reset random seed - virtual void reset() = 0; -}; - - - - -#endif //CONSTRAINT_SOLVER_H diff --git a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btContactConstraint.cpp b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btContactConstraint.cpp deleted file mode 100644 index 1588428503a..00000000000 --- a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btContactConstraint.cpp +++ /dev/null @@ -1,417 +0,0 @@ -/* -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 "btContactConstraint.h" -#include "BulletDynamics/Dynamics/btRigidBody.h" -#include "LinearMath/btVector3.h" -#include "btJacobianEntry.h" -#include "btContactSolverInfo.h" -#include "LinearMath/btMinMax.h" -#include "BulletCollision/NarrowPhaseCollision/btManifoldPoint.h" - -#define ASSERT2 assert - -#define USE_INTERNAL_APPLY_IMPULSE 1 - - -//bilateral constraint between two dynamic objects -void resolveSingleBilateral(btRigidBody& body1, const btVector3& pos1, - btRigidBody& body2, const btVector3& pos2, - btScalar distance, const btVector3& normal,btScalar& impulse ,btScalar timeStep) -{ - (void)timeStep; - (void)distance; - - - btScalar normalLenSqr = normal.length2(); - ASSERT2(btFabs(normalLenSqr) < btScalar(1.1)); - if (normalLenSqr > btScalar(1.1)) - { - impulse = btScalar(0.); - return; - } - btVector3 rel_pos1 = pos1 - body1.getCenterOfMassPosition(); - btVector3 rel_pos2 = pos2 - body2.getCenterOfMassPosition(); - //this jacobian entry could be re-used for all iterations - - btVector3 vel1 = body1.getVelocityInLocalPoint(rel_pos1); - btVector3 vel2 = body2.getVelocityInLocalPoint(rel_pos2); - btVector3 vel = vel1 - vel2; - - - btJacobianEntry jac(body1.getCenterOfMassTransform().getBasis().transpose(), - body2.getCenterOfMassTransform().getBasis().transpose(), - rel_pos1,rel_pos2,normal,body1.getInvInertiaDiagLocal(),body1.getInvMass(), - body2.getInvInertiaDiagLocal(),body2.getInvMass()); - - btScalar jacDiagAB = jac.getDiagonal(); - btScalar jacDiagABInv = btScalar(1.) / jacDiagAB; - - btScalar rel_vel = jac.getRelativeVelocity( - body1.getLinearVelocity(), - body1.getCenterOfMassTransform().getBasis().transpose() * body1.getAngularVelocity(), - body2.getLinearVelocity(), - body2.getCenterOfMassTransform().getBasis().transpose() * body2.getAngularVelocity()); - btScalar a; - a=jacDiagABInv; - - - rel_vel = normal.dot(vel); - - //todo: move this into proper structure - btScalar contactDamping = btScalar(0.2); - -#ifdef ONLY_USE_LINEAR_MASS - btScalar massTerm = btScalar(1.) / (body1.getInvMass() + body2.getInvMass()); - impulse = - contactDamping * rel_vel * massTerm; -#else - btScalar velocityImpulse = -contactDamping * rel_vel * jacDiagABInv; - impulse = velocityImpulse; -#endif -} - - - -//response between two dynamic objects with friction -btScalar resolveSingleCollision( - btRigidBody& body1, - btRigidBody& body2, - btManifoldPoint& contactPoint, - const btContactSolverInfo& solverInfo) -{ - - const btVector3& pos1_ = contactPoint.getPositionWorldOnA(); - const btVector3& pos2_ = contactPoint.getPositionWorldOnB(); - const btVector3& normal = contactPoint.m_normalWorldOnB; - - //constant over all iterations - btVector3 rel_pos1 = pos1_ - body1.getCenterOfMassPosition(); - btVector3 rel_pos2 = pos2_ - body2.getCenterOfMassPosition(); - - btVector3 vel1 = body1.getVelocityInLocalPoint(rel_pos1); - btVector3 vel2 = body2.getVelocityInLocalPoint(rel_pos2); - btVector3 vel = vel1 - vel2; - btScalar rel_vel; - rel_vel = normal.dot(vel); - - btScalar Kfps = btScalar(1.) / solverInfo.m_timeStep ; - - // btScalar damping = solverInfo.m_damping ; - btScalar Kerp = solverInfo.m_erp; - btScalar Kcor = Kerp *Kfps; - - btConstraintPersistentData* cpd = (btConstraintPersistentData*) contactPoint.m_userPersistentData; - assert(cpd); - btScalar distance = cpd->m_penetration; - btScalar positionalError = Kcor *-distance; - btScalar velocityError = cpd->m_restitution - rel_vel;// * damping; - - btScalar penetrationImpulse = positionalError * cpd->m_jacDiagABInv; - - btScalar velocityImpulse = velocityError * cpd->m_jacDiagABInv; - - btScalar normalImpulse = penetrationImpulse+velocityImpulse; - - // See Erin Catto's GDC 2006 paper: Clamp the accumulated impulse - btScalar oldNormalImpulse = cpd->m_appliedImpulse; - btScalar sum = oldNormalImpulse + normalImpulse; - cpd->m_appliedImpulse = btScalar(0.) > sum ? btScalar(0.): sum; - - normalImpulse = cpd->m_appliedImpulse - oldNormalImpulse; - -#ifdef USE_INTERNAL_APPLY_IMPULSE - if (body1.getInvMass()) - { - body1.internalApplyImpulse(contactPoint.m_normalWorldOnB*body1.getInvMass(),cpd->m_angularComponentA,normalImpulse); - } - if (body2.getInvMass()) - { - body2.internalApplyImpulse(contactPoint.m_normalWorldOnB*body2.getInvMass(),cpd->m_angularComponentB,-normalImpulse); - } -#else //USE_INTERNAL_APPLY_IMPULSE - body1.applyImpulse(normal*(normalImpulse), rel_pos1); - body2.applyImpulse(-normal*(normalImpulse), rel_pos2); -#endif //USE_INTERNAL_APPLY_IMPULSE - - return normalImpulse; -} - - -btScalar resolveSingleFriction( - btRigidBody& body1, - btRigidBody& body2, - btManifoldPoint& contactPoint, - const btContactSolverInfo& solverInfo) -{ - - (void)solverInfo; - - const btVector3& pos1 = contactPoint.getPositionWorldOnA(); - const btVector3& pos2 = contactPoint.getPositionWorldOnB(); - - btVector3 rel_pos1 = pos1 - body1.getCenterOfMassPosition(); - btVector3 rel_pos2 = pos2 - body2.getCenterOfMassPosition(); - - btConstraintPersistentData* cpd = (btConstraintPersistentData*) contactPoint.m_userPersistentData; - assert(cpd); - - btScalar combinedFriction = cpd->m_friction; - - btScalar limit = cpd->m_appliedImpulse * combinedFriction; - - if (cpd->m_appliedImpulse>btScalar(0.)) - //friction - { - //apply friction in the 2 tangential directions - - // 1st tangent - btVector3 vel1 = body1.getVelocityInLocalPoint(rel_pos1); - btVector3 vel2 = body2.getVelocityInLocalPoint(rel_pos2); - btVector3 vel = vel1 - vel2; - - btScalar j1,j2; - - { - - btScalar vrel = cpd->m_frictionWorldTangential0.dot(vel); - - // calculate j that moves us to zero relative velocity - j1 = -vrel * cpd->m_jacDiagABInvTangent0; - btScalar oldTangentImpulse = cpd->m_accumulatedTangentImpulse0; - cpd->m_accumulatedTangentImpulse0 = oldTangentImpulse + j1; - btSetMin(cpd->m_accumulatedTangentImpulse0, limit); - btSetMax(cpd->m_accumulatedTangentImpulse0, -limit); - j1 = cpd->m_accumulatedTangentImpulse0 - oldTangentImpulse; - - } - { - // 2nd tangent - - btScalar vrel = cpd->m_frictionWorldTangential1.dot(vel); - - // calculate j that moves us to zero relative velocity - j2 = -vrel * cpd->m_jacDiagABInvTangent1; - btScalar oldTangentImpulse = cpd->m_accumulatedTangentImpulse1; - cpd->m_accumulatedTangentImpulse1 = oldTangentImpulse + j2; - btSetMin(cpd->m_accumulatedTangentImpulse1, limit); - btSetMax(cpd->m_accumulatedTangentImpulse1, -limit); - j2 = cpd->m_accumulatedTangentImpulse1 - oldTangentImpulse; - } - -#ifdef USE_INTERNAL_APPLY_IMPULSE - if (body1.getInvMass()) - { - body1.internalApplyImpulse(cpd->m_frictionWorldTangential0*body1.getInvMass(),cpd->m_frictionAngularComponent0A,j1); - body1.internalApplyImpulse(cpd->m_frictionWorldTangential1*body1.getInvMass(),cpd->m_frictionAngularComponent1A,j2); - } - if (body2.getInvMass()) - { - body2.internalApplyImpulse(cpd->m_frictionWorldTangential0*body2.getInvMass(),cpd->m_frictionAngularComponent0B,-j1); - body2.internalApplyImpulse(cpd->m_frictionWorldTangential1*body2.getInvMass(),cpd->m_frictionAngularComponent1B,-j2); - } -#else //USE_INTERNAL_APPLY_IMPULSE - body1.applyImpulse((j1 * cpd->m_frictionWorldTangential0)+(j2 * cpd->m_frictionWorldTangential1), rel_pos1); - body2.applyImpulse((j1 * -cpd->m_frictionWorldTangential0)+(j2 * -cpd->m_frictionWorldTangential1), rel_pos2); -#endif //USE_INTERNAL_APPLY_IMPULSE - - - } - return cpd->m_appliedImpulse; -} - - -btScalar resolveSingleFrictionOriginal( - btRigidBody& body1, - btRigidBody& body2, - btManifoldPoint& contactPoint, - const btContactSolverInfo& solverInfo) -{ - - (void)solverInfo; - - const btVector3& pos1 = contactPoint.getPositionWorldOnA(); - const btVector3& pos2 = contactPoint.getPositionWorldOnB(); - - btVector3 rel_pos1 = pos1 - body1.getCenterOfMassPosition(); - btVector3 rel_pos2 = pos2 - body2.getCenterOfMassPosition(); - - btConstraintPersistentData* cpd = (btConstraintPersistentData*) contactPoint.m_userPersistentData; - assert(cpd); - - btScalar combinedFriction = cpd->m_friction; - - btScalar limit = cpd->m_appliedImpulse * combinedFriction; - //if (contactPoint.m_appliedImpulse>btScalar(0.)) - //friction - { - //apply friction in the 2 tangential directions - - { - // 1st tangent - btVector3 vel1 = body1.getVelocityInLocalPoint(rel_pos1); - btVector3 vel2 = body2.getVelocityInLocalPoint(rel_pos2); - btVector3 vel = vel1 - vel2; - - btScalar vrel = cpd->m_frictionWorldTangential0.dot(vel); - - // calculate j that moves us to zero relative velocity - btScalar j = -vrel * cpd->m_jacDiagABInvTangent0; - btScalar total = cpd->m_accumulatedTangentImpulse0 + j; - btSetMin(total, limit); - btSetMax(total, -limit); - j = total - cpd->m_accumulatedTangentImpulse0; - cpd->m_accumulatedTangentImpulse0 = total; - body1.applyImpulse(j * cpd->m_frictionWorldTangential0, rel_pos1); - body2.applyImpulse(j * -cpd->m_frictionWorldTangential0, rel_pos2); - } - - - { - // 2nd tangent - btVector3 vel1 = body1.getVelocityInLocalPoint(rel_pos1); - btVector3 vel2 = body2.getVelocityInLocalPoint(rel_pos2); - btVector3 vel = vel1 - vel2; - - btScalar vrel = cpd->m_frictionWorldTangential1.dot(vel); - - // calculate j that moves us to zero relative velocity - btScalar j = -vrel * cpd->m_jacDiagABInvTangent1; - btScalar total = cpd->m_accumulatedTangentImpulse1 + j; - btSetMin(total, limit); - btSetMax(total, -limit); - j = total - cpd->m_accumulatedTangentImpulse1; - cpd->m_accumulatedTangentImpulse1 = total; - body1.applyImpulse(j * cpd->m_frictionWorldTangential1, rel_pos1); - body2.applyImpulse(j * -cpd->m_frictionWorldTangential1, rel_pos2); - } - } - return cpd->m_appliedImpulse; -} - - -//velocity + friction -//response between two dynamic objects with friction -btScalar resolveSingleCollisionCombined( - btRigidBody& body1, - btRigidBody& body2, - btManifoldPoint& contactPoint, - const btContactSolverInfo& solverInfo) -{ - - const btVector3& pos1 = contactPoint.getPositionWorldOnA(); - const btVector3& pos2 = contactPoint.getPositionWorldOnB(); - const btVector3& normal = contactPoint.m_normalWorldOnB; - - btVector3 rel_pos1 = pos1 - body1.getCenterOfMassPosition(); - btVector3 rel_pos2 = pos2 - body2.getCenterOfMassPosition(); - - btVector3 vel1 = body1.getVelocityInLocalPoint(rel_pos1); - btVector3 vel2 = body2.getVelocityInLocalPoint(rel_pos2); - btVector3 vel = vel1 - vel2; - btScalar rel_vel; - rel_vel = normal.dot(vel); - - btScalar Kfps = btScalar(1.) / solverInfo.m_timeStep ; - - //btScalar damping = solverInfo.m_damping ; - btScalar Kerp = solverInfo.m_erp; - btScalar Kcor = Kerp *Kfps; - - btConstraintPersistentData* cpd = (btConstraintPersistentData*) contactPoint.m_userPersistentData; - assert(cpd); - btScalar distance = cpd->m_penetration; - btScalar positionalError = Kcor *-distance; - btScalar velocityError = cpd->m_restitution - rel_vel;// * damping; - - btScalar penetrationImpulse = positionalError * cpd->m_jacDiagABInv; - - btScalar velocityImpulse = velocityError * cpd->m_jacDiagABInv; - - btScalar normalImpulse = penetrationImpulse+velocityImpulse; - - // See Erin Catto's GDC 2006 paper: Clamp the accumulated impulse - btScalar oldNormalImpulse = cpd->m_appliedImpulse; - btScalar sum = oldNormalImpulse + normalImpulse; - cpd->m_appliedImpulse = btScalar(0.) > sum ? btScalar(0.): sum; - - normalImpulse = cpd->m_appliedImpulse - oldNormalImpulse; - - -#ifdef USE_INTERNAL_APPLY_IMPULSE - if (body1.getInvMass()) - { - body1.internalApplyImpulse(contactPoint.m_normalWorldOnB*body1.getInvMass(),cpd->m_angularComponentA,normalImpulse); - } - if (body2.getInvMass()) - { - body2.internalApplyImpulse(contactPoint.m_normalWorldOnB*body2.getInvMass(),cpd->m_angularComponentB,-normalImpulse); - } -#else //USE_INTERNAL_APPLY_IMPULSE - body1.applyImpulse(normal*(normalImpulse), rel_pos1); - body2.applyImpulse(-normal*(normalImpulse), rel_pos2); -#endif //USE_INTERNAL_APPLY_IMPULSE - - { - //friction - btVector3 vel1 = body1.getVelocityInLocalPoint(rel_pos1); - btVector3 vel2 = body2.getVelocityInLocalPoint(rel_pos2); - btVector3 vel = vel1 - vel2; - - rel_vel = normal.dot(vel); - - - btVector3 lat_vel = vel - normal * rel_vel; - btScalar lat_rel_vel = lat_vel.length(); - - btScalar combinedFriction = cpd->m_friction; - - if (cpd->m_appliedImpulse > 0) - if (lat_rel_vel > SIMD_EPSILON) - { - lat_vel /= lat_rel_vel; - btVector3 temp1 = body1.getInvInertiaTensorWorld() * rel_pos1.cross(lat_vel); - btVector3 temp2 = body2.getInvInertiaTensorWorld() * rel_pos2.cross(lat_vel); - btScalar friction_impulse = lat_rel_vel / - (body1.getInvMass() + body2.getInvMass() + lat_vel.dot(temp1.cross(rel_pos1) + temp2.cross(rel_pos2))); - btScalar normal_impulse = cpd->m_appliedImpulse * combinedFriction; - - btSetMin(friction_impulse, normal_impulse); - btSetMax(friction_impulse, -normal_impulse); - body1.applyImpulse(lat_vel * -friction_impulse, rel_pos1); - body2.applyImpulse(lat_vel * friction_impulse, rel_pos2); - } - } - - - - return normalImpulse; -} - -btScalar resolveSingleFrictionEmpty( - btRigidBody& body1, - btRigidBody& body2, - btManifoldPoint& contactPoint, - const btContactSolverInfo& solverInfo) -{ - (void)contactPoint; - (void)body1; - (void)body2; - (void)solverInfo; - - - return btScalar(0.); -}; - diff --git a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btContactConstraint.h b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btContactConstraint.h deleted file mode 100644 index 826e79f78bd..00000000000 --- a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btContactConstraint.h +++ /dev/null @@ -1,122 +0,0 @@ -/* -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 CONTACT_CONSTRAINT_H -#define CONTACT_CONSTRAINT_H - -//todo: make into a proper class working with the iterative constraint solver - -class btRigidBody; -#include "LinearMath/btVector3.h" -#include "LinearMath/btScalar.h" -struct btContactSolverInfo; -class btManifoldPoint; - -enum { - DEFAULT_CONTACT_SOLVER_TYPE=0, - CONTACT_SOLVER_TYPE1, - CONTACT_SOLVER_TYPE2, - USER_CONTACT_SOLVER_TYPE1, - MAX_CONTACT_SOLVER_TYPES -}; - - -typedef btScalar (*ContactSolverFunc)(btRigidBody& body1, - btRigidBody& body2, - class btManifoldPoint& contactPoint, - const btContactSolverInfo& info); - -///stores some extra information to each contact point. It is not in the contact point, because that want to keep the collision detection independent from the constraint solver. -struct btConstraintPersistentData -{ - inline btConstraintPersistentData() - :m_appliedImpulse(btScalar(0.)), - m_prevAppliedImpulse(btScalar(0.)), - m_accumulatedTangentImpulse0(btScalar(0.)), - m_accumulatedTangentImpulse1(btScalar(0.)), - m_jacDiagABInv(btScalar(0.)), - m_persistentLifeTime(0), - m_restitution(btScalar(0.)), - m_friction(btScalar(0.)), - m_penetration(btScalar(0.)), - m_contactSolverFunc(0), - m_frictionSolverFunc(0) - { - } - - - /// total applied impulse during most recent frame - btScalar m_appliedImpulse; - btScalar m_prevAppliedImpulse; - btScalar m_accumulatedTangentImpulse0; - btScalar m_accumulatedTangentImpulse1; - - btScalar m_jacDiagABInv; - btScalar m_jacDiagABInvTangent0; - btScalar m_jacDiagABInvTangent1; - int m_persistentLifeTime; - btScalar m_restitution; - btScalar m_friction; - btScalar m_penetration; - btVector3 m_frictionWorldTangential0; - btVector3 m_frictionWorldTangential1; - - btVector3 m_frictionAngularComponent0A; - btVector3 m_frictionAngularComponent0B; - btVector3 m_frictionAngularComponent1A; - btVector3 m_frictionAngularComponent1B; - - //some data doesn't need to be persistent over frames: todo: clean/reuse this - btVector3 m_angularComponentA; - btVector3 m_angularComponentB; - - ContactSolverFunc m_contactSolverFunc; - ContactSolverFunc m_frictionSolverFunc; - -}; - -///bilateral constraint between two dynamic objects -///positive distance = separation, negative distance = penetration -void resolveSingleBilateral(btRigidBody& body1, const btVector3& pos1, - btRigidBody& body2, const btVector3& pos2, - btScalar distance, const btVector3& normal,btScalar& impulse ,btScalar timeStep); - - -///contact constraint resolution: -///calculate and apply impulse to satisfy non-penetration and non-negative relative velocity constraint -///positive distance = separation, negative distance = penetration -btScalar resolveSingleCollision( - btRigidBody& body1, - btRigidBody& body2, - btManifoldPoint& contactPoint, - const btContactSolverInfo& info); - -btScalar resolveSingleFriction( - btRigidBody& body1, - btRigidBody& body2, - btManifoldPoint& contactPoint, - const btContactSolverInfo& solverInfo - ); - - - -btScalar resolveSingleCollisionCombined( - btRigidBody& body1, - btRigidBody& body2, - btManifoldPoint& contactPoint, - const btContactSolverInfo& solverInfo - ); - -#endif //CONTACT_CONSTRAINT_H diff --git a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btContactSolverInfo.h b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btContactSolverInfo.h deleted file mode 100644 index ad2c40e2107..00000000000 --- a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btContactSolverInfo.h +++ /dev/null @@ -1,51 +0,0 @@ -/* -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 CONTACT_SOLVER_INFO -#define CONTACT_SOLVER_INFO - -struct btContactSolverInfoData -{ - btScalar m_tau; - btScalar m_damping; - btScalar m_friction; - btScalar m_timeStep; - btScalar m_restitution; - int m_numIterations; - btScalar m_maxErrorReduction; - btScalar m_sor; - btScalar m_erp; - -}; - -struct btContactSolverInfo : public btContactSolverInfoData -{ - - inline btContactSolverInfo() - { - m_tau = btScalar(0.6); - m_damping = btScalar(1.0); - m_friction = btScalar(0.3); - m_restitution = btScalar(0.); - m_maxErrorReduction = btScalar(20.); - m_numIterations = 10; - m_erp = btScalar(0.4); - m_sor = btScalar(1.3); - } - - -}; - -#endif //CONTACT_SOLVER_INFO diff --git a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.cpp b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.cpp deleted file mode 100644 index 96d48f9f7dd..00000000000 --- a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.cpp +++ /dev/null @@ -1,497 +0,0 @@ -/* -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. -*/ -/* -2007-09-09 -Refactored by Francisco León -email: projectileman@yahoo.com -http://gimpact.sf.net -*/ - - -#include "btGeneric6DofConstraint.h" -#include "BulletDynamics/Dynamics/btRigidBody.h" -#include "LinearMath/btTransformUtil.h" -#include - - -static const btScalar kSign[] = { btScalar(1.0), btScalar(-1.0), btScalar(1.0) }; -static const int kAxisA[] = { 1, 0, 0 }; -static const int kAxisB[] = { 2, 2, 1 }; -#define GENERIC_D6_DISABLE_WARMSTARTING 1 - -btScalar btGetMatrixElem(const btMatrix3x3& mat, int index) -{ - int i = index%3; - int j = index/3; - return mat[i][j]; -} - -///MatrixToEulerXYZ from http://www.geometrictools.com/LibFoundation/Mathematics/Wm4Matrix3.inl.html -bool matrixToEulerXYZ(const btMatrix3x3& mat,btVector3& xyz) -{ -// // rot = cy*cz -cy*sz sy -// // cz*sx*sy+cx*sz cx*cz-sx*sy*sz -cy*sx -// // -cx*cz*sy+sx*sz cz*sx+cx*sy*sz cx*cy -// - - if (btGetMatrixElem(mat,2) < btScalar(1.0)) - { - if (btGetMatrixElem(mat,2) > btScalar(-1.0)) - { - xyz[0] = btAtan2(-btGetMatrixElem(mat,5),btGetMatrixElem(mat,8)); - xyz[1] = btAsin(btGetMatrixElem(mat,2)); - xyz[2] = btAtan2(-btGetMatrixElem(mat,1),btGetMatrixElem(mat,0)); - return true; - } - else - { - // WARNING. Not unique. XA - ZA = -atan2(r10,r11) - xyz[0] = -btAtan2(btGetMatrixElem(mat,3),btGetMatrixElem(mat,4)); - xyz[1] = -SIMD_HALF_PI; - xyz[2] = btScalar(0.0); - return false; - } - } - else - { - // WARNING. Not unique. XAngle + ZAngle = atan2(r10,r11) - xyz[0] = btAtan2(btGetMatrixElem(mat,3),btGetMatrixElem(mat,4)); - xyz[1] = SIMD_HALF_PI; - xyz[2] = 0.0; - - } - - - return false; -} - - - -//////////////////////////// btRotationalLimitMotor //////////////////////////////////// - - -int btRotationalLimitMotor::testLimitValue(btScalar test_value) -{ - if(m_loLimit>m_hiLimit) - { - m_currentLimit = 0;//Free from violation - return 0; - } - - if (test_value < m_loLimit) - { - m_currentLimit = 1;//low limit violation - m_currentLimitError = test_value - m_loLimit; - return 1; - } - else if (test_value> m_hiLimit) - { - m_currentLimit = 2;//High limit violation - m_currentLimitError = test_value - m_hiLimit; - return 2; - } - else - { - m_currentLimit = 0;//Free from violation - return 0; - } - return 0; -} - - -btScalar btRotationalLimitMotor::solveAngularLimits( - btScalar timeStep,btVector3& axis,btScalar jacDiagABInv, - btRigidBody * body0, btRigidBody * body1) -{ - if (needApplyTorques()==false) return 0.0f; - - btScalar target_velocity = m_targetVelocity; - btScalar maxMotorForce = m_maxMotorForce; - - //current error correction - if (m_currentLimit!=0) - { - target_velocity = -m_ERP*m_currentLimitError/(timeStep); - maxMotorForce = m_maxLimitForce; - } - - maxMotorForce *= timeStep; - - // current velocity difference - btVector3 vel_diff = body0->getAngularVelocity(); - if (body1) - { - vel_diff -= body1->getAngularVelocity(); - } - - - - btScalar rel_vel = axis.dot(vel_diff); - - // correction velocity - btScalar motor_relvel = m_limitSoftness*(target_velocity - m_damping*rel_vel); - - - if ( motor_relvel < SIMD_EPSILON && motor_relvel > -SIMD_EPSILON ) - { - return 0.0f;//no need for applying force - } - - - // correction impulse - btScalar unclippedMotorImpulse = (1+m_bounce)*motor_relvel*jacDiagABInv; - - // clip correction impulse - btScalar clippedMotorImpulse; - - //todo: should clip against accumulated impulse - if (unclippedMotorImpulse>0.0f) - { - clippedMotorImpulse = unclippedMotorImpulse > maxMotorForce? maxMotorForce: unclippedMotorImpulse; - } - else - { - clippedMotorImpulse = unclippedMotorImpulse < -maxMotorForce ? -maxMotorForce: unclippedMotorImpulse; - } - - - // sort with accumulated impulses - btScalar lo = btScalar(-1e30); - btScalar hi = btScalar(1e30); - - btScalar oldaccumImpulse = m_accumulatedImpulse; - btScalar sum = oldaccumImpulse + clippedMotorImpulse; - m_accumulatedImpulse = sum > hi ? btScalar(0.) : sum < lo ? btScalar(0.) : sum; - - clippedMotorImpulse = m_accumulatedImpulse - oldaccumImpulse; - - - - btVector3 motorImp = clippedMotorImpulse * axis; - - - body0->applyTorqueImpulse(motorImp); - if (body1) body1->applyTorqueImpulse(-motorImp); - - return clippedMotorImpulse; - - -} - -//////////////////////////// End btRotationalLimitMotor //////////////////////////////////// - -//////////////////////////// btTranslationalLimitMotor //////////////////////////////////// -btScalar btTranslationalLimitMotor::solveLinearAxis( - btScalar timeStep, - btScalar jacDiagABInv, - btRigidBody& body1,const btVector3 &pointInA, - btRigidBody& body2,const btVector3 &pointInB, - int limit_index, - const btVector3 & axis_normal_on_a) -{ - -///find relative velocity - btVector3 rel_pos1 = pointInA - body1.getCenterOfMassPosition(); - btVector3 rel_pos2 = pointInB - body2.getCenterOfMassPosition(); - - btVector3 vel1 = body1.getVelocityInLocalPoint(rel_pos1); - btVector3 vel2 = body2.getVelocityInLocalPoint(rel_pos2); - btVector3 vel = vel1 - vel2; - - btScalar rel_vel = axis_normal_on_a.dot(vel); - - - -/// apply displacement correction - -//positional error (zeroth order error) - btScalar depth = -(pointInA - pointInB).dot(axis_normal_on_a); - btScalar lo = btScalar(-1e30); - btScalar hi = btScalar(1e30); - - btScalar minLimit = m_lowerLimit[limit_index]; - btScalar maxLimit = m_upperLimit[limit_index]; - - //handle the limits - if (minLimit < maxLimit) - { - { - if (depth > maxLimit) - { - depth -= maxLimit; - lo = btScalar(0.); - - } - else - { - if (depth < minLimit) - { - depth -= minLimit; - hi = btScalar(0.); - } - else - { - return 0.0f; - } - } - } - } - - btScalar normalImpulse= m_limitSoftness*(m_restitution*depth/timeStep - m_damping*rel_vel) * jacDiagABInv; - - - - - btScalar oldNormalImpulse = m_accumulatedImpulse[limit_index]; - btScalar sum = oldNormalImpulse + normalImpulse; - m_accumulatedImpulse[limit_index] = sum > hi ? btScalar(0.) : sum < lo ? btScalar(0.) : sum; - normalImpulse = m_accumulatedImpulse[limit_index] - oldNormalImpulse; - - btVector3 impulse_vector = axis_normal_on_a * normalImpulse; - body1.applyImpulse( impulse_vector, rel_pos1); - body2.applyImpulse(-impulse_vector, rel_pos2); - return normalImpulse; -} - -//////////////////////////// btTranslationalLimitMotor //////////////////////////////////// - - -btGeneric6DofConstraint::btGeneric6DofConstraint() - :btTypedConstraint(D6_CONSTRAINT_TYPE), - m_useLinearReferenceFrameA(true) -{ -} - -btGeneric6DofConstraint::btGeneric6DofConstraint(btRigidBody& rbA, btRigidBody& rbB, const btTransform& frameInA, const btTransform& frameInB, bool useLinearReferenceFrameA) - : btTypedConstraint(D6_CONSTRAINT_TYPE, rbA, rbB) - , m_frameInA(frameInA) - , m_frameInB(frameInB), - m_useLinearReferenceFrameA(useLinearReferenceFrameA) -{ - -} - - - - - -void btGeneric6DofConstraint::calculateAngleInfo() -{ - btMatrix3x3 relative_frame = m_calculatedTransformA.getBasis().inverse()*m_calculatedTransformB.getBasis(); - - matrixToEulerXYZ(relative_frame,m_calculatedAxisAngleDiff); - - - - // in euler angle mode we do not actually constrain the angular velocity - // along the axes axis[0] and axis[2] (although we do use axis[1]) : - // - // to get constrain w2-w1 along ...not - // ------ --------------------- ------ - // d(angle[0])/dt = 0 ax[1] x ax[2] ax[0] - // d(angle[1])/dt = 0 ax[1] - // d(angle[2])/dt = 0 ax[0] x ax[1] ax[2] - // - // constraining w2-w1 along an axis 'a' means that a'*(w2-w1)=0. - // to prove the result for angle[0], write the expression for angle[0] from - // GetInfo1 then take the derivative. to prove this for angle[2] it is - // easier to take the euler rate expression for d(angle[2])/dt with respect - // to the components of w and set that to 0. - - btVector3 axis0 = m_calculatedTransformB.getBasis().getColumn(0); - btVector3 axis2 = m_calculatedTransformA.getBasis().getColumn(2); - - m_calculatedAxis[1] = axis2.cross(axis0); - m_calculatedAxis[0] = m_calculatedAxis[1].cross(axis2); - m_calculatedAxis[2] = axis0.cross(m_calculatedAxis[1]); - - -// if(m_debugDrawer) -// { -// -// char buff[300]; -// sprintf(buff,"\n X: %.2f ; Y: %.2f ; Z: %.2f ", -// m_calculatedAxisAngleDiff[0], -// m_calculatedAxisAngleDiff[1], -// m_calculatedAxisAngleDiff[2]); -// m_debugDrawer->reportErrorWarning(buff); -// } - -} - -void btGeneric6DofConstraint::calculateTransforms() -{ - m_calculatedTransformA = m_rbA.getCenterOfMassTransform() * m_frameInA; - m_calculatedTransformB = m_rbB.getCenterOfMassTransform() * m_frameInB; - - calculateAngleInfo(); -} - - -void btGeneric6DofConstraint::buildLinearJacobian( - btJacobianEntry & jacLinear,const btVector3 & normalWorld, - const btVector3 & pivotAInW,const btVector3 & pivotBInW) -{ - new (&jacLinear) btJacobianEntry( - m_rbA.getCenterOfMassTransform().getBasis().transpose(), - m_rbB.getCenterOfMassTransform().getBasis().transpose(), - pivotAInW - m_rbA.getCenterOfMassPosition(), - pivotBInW - m_rbB.getCenterOfMassPosition(), - normalWorld, - m_rbA.getInvInertiaDiagLocal(), - m_rbA.getInvMass(), - m_rbB.getInvInertiaDiagLocal(), - m_rbB.getInvMass()); - -} - -void btGeneric6DofConstraint::buildAngularJacobian( - btJacobianEntry & jacAngular,const btVector3 & jointAxisW) -{ - new (&jacAngular) btJacobianEntry(jointAxisW, - m_rbA.getCenterOfMassTransform().getBasis().transpose(), - m_rbB.getCenterOfMassTransform().getBasis().transpose(), - m_rbA.getInvInertiaDiagLocal(), - m_rbB.getInvInertiaDiagLocal()); - -} - -bool btGeneric6DofConstraint::testAngularLimitMotor(int axis_index) -{ - btScalar angle = m_calculatedAxisAngleDiff[axis_index]; - - //test limits - m_angularLimits[axis_index].testLimitValue(angle); - return m_angularLimits[axis_index].needApplyTorques(); -} - -void btGeneric6DofConstraint::buildJacobian() -{ - //calculates transform - calculateTransforms(); - - const btVector3& pivotAInW = m_calculatedTransformA.getOrigin(); - const btVector3& pivotBInW = m_calculatedTransformB.getOrigin(); - - - btVector3 rel_pos1 = pivotAInW - m_rbA.getCenterOfMassPosition(); - btVector3 rel_pos2 = pivotBInW - m_rbB.getCenterOfMassPosition(); - - btVector3 normalWorld; - int i; - //linear part - for (i=0;i<3;i++) - { - if (m_linearLimits.isLimited(i)) - { - if (m_useLinearReferenceFrameA) - normalWorld = m_calculatedTransformA.getBasis().getColumn(i); - else - normalWorld = m_calculatedTransformB.getBasis().getColumn(i); - - buildLinearJacobian( - m_jacLinear[i],normalWorld , - pivotAInW,pivotBInW); - - } - } - - // angular part - for (i=0;i<3;i++) - { - //calculates error angle - if (testAngularLimitMotor(i)) - { - normalWorld = this->getAxis(i); - // Create angular atom - buildAngularJacobian(m_jacAng[i],normalWorld); - } - } - - -} - - -void btGeneric6DofConstraint::solveConstraint(btScalar timeStep) -{ - m_timeStep = timeStep; - - //calculateTransforms(); - - int i; - - // linear - - btVector3 pointInA = m_calculatedTransformA.getOrigin(); - btVector3 pointInB = m_calculatedTransformB.getOrigin(); - - btScalar jacDiagABInv; - btVector3 linear_axis; - for (i=0;i<3;i++) - { - if (m_linearLimits.isLimited(i)) - { - jacDiagABInv = btScalar(1.) / m_jacLinear[i].getDiagonal(); - - if (m_useLinearReferenceFrameA) - linear_axis = m_calculatedTransformA.getBasis().getColumn(i); - else - linear_axis = m_calculatedTransformB.getBasis().getColumn(i); - - m_linearLimits.solveLinearAxis( - m_timeStep, - jacDiagABInv, - m_rbA,pointInA, - m_rbB,pointInB, - i,linear_axis); - - } - } - - // angular - btVector3 angular_axis; - btScalar angularJacDiagABInv; - for (i=0;i<3;i++) - { - if (m_angularLimits[i].needApplyTorques()) - { - - // get axis - angular_axis = getAxis(i); - - angularJacDiagABInv = btScalar(1.) / m_jacAng[i].getDiagonal(); - - m_angularLimits[i].solveAngularLimits(m_timeStep,angular_axis,angularJacDiagABInv, &m_rbA,&m_rbB); - } - } -} - -void btGeneric6DofConstraint::updateRHS(btScalar timeStep) -{ - (void)timeStep; - -} - -btVector3 btGeneric6DofConstraint::getAxis(int axis_index) const -{ - return m_calculatedAxis[axis_index]; -} - -btScalar btGeneric6DofConstraint::getAngle(int axis_index) const -{ - return m_calculatedAxisAngleDiff[axis_index]; -} - - diff --git a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.h b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.h deleted file mode 100644 index e4683b91b9e..00000000000 --- a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.h +++ /dev/null @@ -1,433 +0,0 @@ -/* -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. -*/ -/* -2007-09-09 -btGeneric6DofConstraint Refactored by Francisco León -email: projectileman@yahoo.com -http://gimpact.sf.net -*/ - - -#ifndef GENERIC_6DOF_CONSTRAINT_H -#define GENERIC_6DOF_CONSTRAINT_H - -#include "LinearMath/btVector3.h" -#include "btJacobianEntry.h" -#include "btTypedConstraint.h" - -class btRigidBody; - - -//! Rotation Limit structure for generic joints -class btRotationalLimitMotor -{ -public: - //! limit_parameters - //!@{ - btScalar m_loLimit;//!< joint limit - btScalar m_hiLimit;//!< joint limit - btScalar m_targetVelocity;//!< target motor velocity - btScalar m_maxMotorForce;//!< max force on motor - btScalar m_maxLimitForce;//!< max force on limit - btScalar m_damping;//!< Damping. - btScalar m_limitSoftness;//! Relaxation factor - btScalar m_ERP;//!< Error tolerance factor when joint is at limit - btScalar m_bounce;//!< restitution factor - bool m_enableMotor; - - //!@} - - //! temp_variables - //!@{ - btScalar m_currentLimitError;//! How much is violated this limit - int m_currentLimit;//!< 0=free, 1=at lo limit, 2=at hi limit - btScalar m_accumulatedImpulse; - //!@} - - btRotationalLimitMotor() - { - m_accumulatedImpulse = 0.f; - m_targetVelocity = 0; - m_maxMotorForce = 0.1f; - m_maxLimitForce = 300.0f; - m_loLimit = -SIMD_INFINITY; - m_hiLimit = SIMD_INFINITY; - m_ERP = 0.5f; - m_bounce = 0.0f; - m_damping = 1.0f; - m_limitSoftness = 0.5f; - m_currentLimit = 0; - m_currentLimitError = 0; - m_enableMotor = false; - } - - btRotationalLimitMotor(const btRotationalLimitMotor & limot) - { - m_targetVelocity = limot.m_targetVelocity; - m_maxMotorForce = limot.m_maxMotorForce; - m_limitSoftness = limot.m_limitSoftness; - m_loLimit = limot.m_loLimit; - m_hiLimit = limot.m_hiLimit; - m_ERP = limot.m_ERP; - m_bounce = limot.m_bounce; - m_currentLimit = limot.m_currentLimit; - m_currentLimitError = limot.m_currentLimitError; - m_enableMotor = limot.m_enableMotor; - } - - - - //! Is limited - bool isLimited() - { - if(m_loLimit>=m_hiLimit) return false; - return true; - } - - //! Need apply correction - bool needApplyTorques() - { - if(m_currentLimit == 0 && m_enableMotor == false) return false; - return true; - } - - //! calculates error - /*! - calculates m_currentLimit and m_currentLimitError. - */ - int testLimitValue(btScalar test_value); - - //! apply the correction impulses for two bodies - btScalar solveAngularLimits(btScalar timeStep,btVector3& axis, btScalar jacDiagABInv,btRigidBody * body0, btRigidBody * body1); - - -}; - - - -class btTranslationalLimitMotor -{ -public: - btVector3 m_lowerLimit;//!< the constraint lower limits - btVector3 m_upperLimit;//!< the constraint upper limits - btVector3 m_accumulatedImpulse; - //! Linear_Limit_parameters - //!@{ - btScalar m_limitSoftness;//!< Softness for linear limit - btScalar m_damping;//!< Damping for linear limit - btScalar m_restitution;//! Bounce parameter for linear limit - //!@} - - btTranslationalLimitMotor() - { - m_lowerLimit.setValue(0.f,0.f,0.f); - m_upperLimit.setValue(0.f,0.f,0.f); - m_accumulatedImpulse.setValue(0.f,0.f,0.f); - - m_limitSoftness = 0.7f; - m_damping = btScalar(1.0f); - m_restitution = btScalar(0.5f); - } - - btTranslationalLimitMotor(const btTranslationalLimitMotor & other ) - { - m_lowerLimit = other.m_lowerLimit; - m_upperLimit = other.m_upperLimit; - m_accumulatedImpulse = other.m_accumulatedImpulse; - - m_limitSoftness = other.m_limitSoftness ; - m_damping = other.m_damping; - m_restitution = other.m_restitution; - } - - //! Test limit - /*! - - free means upper < lower, - - locked means upper == lower - - limited means upper > lower - - limitIndex: first 3 are linear, next 3 are angular - */ - inline bool isLimited(int limitIndex) - { - return (m_upperLimit[limitIndex] >= m_lowerLimit[limitIndex]); - } - - - btScalar solveLinearAxis( - btScalar timeStep, - btScalar jacDiagABInv, - btRigidBody& body1,const btVector3 &pointInA, - btRigidBody& body2,const btVector3 &pointInB, - int limit_index, - const btVector3 & axis_normal_on_a); - - -}; - -/// btGeneric6DofConstraint between two rigidbodies each with a pivotpoint that descibes the axis location in local space -/*! -btGeneric6DofConstraint can leave any of the 6 degree of freedom 'free' or 'locked'. -currently this limit supports rotational motors
-
    -
  • For Linear limits, use btGeneric6DofConstraint.setLinearUpperLimit, btGeneric6DofConstraint.setLinearLowerLimit. You can set the parameters with the btTranslationalLimitMotor structure accsesible through the btGeneric6DofConstraint.getTranslationalLimitMotor method. -At this moment translational motors are not supported. May be in the future.
  • - -
  • For Angular limits, use the btRotationalLimitMotor structure for configuring the limit. -This is accessible through btGeneric6DofConstraint.getLimitMotor method, -This brings support for limit parameters and motors.
  • - -
  • Angulars limits have these possible ranges: - -AXIS - - - - - - - - - - - - -
    MIN ANGLEMAX ANGLEX-PIPIY-PI/2PI/2Z-PI/2PI/2
    -
  • -
- -*/ -class btGeneric6DofConstraint : public btTypedConstraint -{ -protected: - - //! relative_frames - //!@{ - btTransform m_frameInA;//!< the constraint space w.r.t body A - btTransform m_frameInB;//!< the constraint space w.r.t body B - //!@} - - //! Jacobians - //!@{ - btJacobianEntry m_jacLinear[3];//!< 3 orthogonal linear constraints - btJacobianEntry m_jacAng[3];//!< 3 orthogonal angular constraints - //!@} - - //! Linear_Limit_parameters - //!@{ - btTranslationalLimitMotor m_linearLimits; - //!@} - - - //! hinge_parameters - //!@{ - btRotationalLimitMotor m_angularLimits[3]; - //!@} - - -protected: - //! temporal variables - //!@{ - btScalar m_timeStep; - btTransform m_calculatedTransformA; - btTransform m_calculatedTransformB; - btVector3 m_calculatedAxisAngleDiff; - btVector3 m_calculatedAxis[3]; - - bool m_useLinearReferenceFrameA; - - //!@} - - btGeneric6DofConstraint& operator=(btGeneric6DofConstraint& other) - { - btAssert(0); - (void) other; - return *this; - } - - - - void buildLinearJacobian( - btJacobianEntry & jacLinear,const btVector3 & normalWorld, - const btVector3 & pivotAInW,const btVector3 & pivotBInW); - - void buildAngularJacobian(btJacobianEntry & jacAngular,const btVector3 & jointAxisW); - - - //! calcs the euler angles between the two bodies. - void calculateAngleInfo(); - - - -public: - btGeneric6DofConstraint(btRigidBody& rbA, btRigidBody& rbB, const btTransform& frameInA, const btTransform& frameInB ,bool useLinearReferenceFrameA); - - btGeneric6DofConstraint(); - - //! Calcs global transform of the offsets - /*! - Calcs the global transform for the joint offset for body A an B, and also calcs the agle differences between the bodies. - \sa btGeneric6DofConstraint.getCalculatedTransformA , btGeneric6DofConstraint.getCalculatedTransformB, btGeneric6DofConstraint.calculateAngleInfo - */ - void calculateTransforms(); - - //! Gets the global transform of the offset for body A - /*! - \sa btGeneric6DofConstraint.getFrameOffsetA, btGeneric6DofConstraint.getFrameOffsetB, btGeneric6DofConstraint.calculateAngleInfo. - */ - const btTransform & getCalculatedTransformA() const - { - return m_calculatedTransformA; - } - - //! Gets the global transform of the offset for body B - /*! - \sa btGeneric6DofConstraint.getFrameOffsetA, btGeneric6DofConstraint.getFrameOffsetB, btGeneric6DofConstraint.calculateAngleInfo. - */ - const btTransform & getCalculatedTransformB() const - { - return m_calculatedTransformB; - } - - const btTransform & getFrameOffsetA() const - { - return m_frameInA; - } - - const btTransform & getFrameOffsetB() const - { - return m_frameInB; - } - - - btTransform & getFrameOffsetA() - { - return m_frameInA; - } - - btTransform & getFrameOffsetB() - { - return m_frameInB; - } - - - //! performs Jacobian calculation, and also calculates angle differences and axis - virtual void buildJacobian(); - - virtual void solveConstraint(btScalar timeStep); - - void updateRHS(btScalar timeStep); - - //! Get the rotation axis in global coordinates - /*! - \pre btGeneric6DofConstraint.buildJacobian must be called previously. - */ - btVector3 getAxis(int axis_index) const; - - //! Get the relative Euler angle - /*! - \pre btGeneric6DofConstraint.buildJacobian must be called previously. - */ - btScalar getAngle(int axis_index) const; - - //! Test angular limit. - /*! - Calculates angular correction and returns true if limit needs to be corrected. - \pre btGeneric6DofConstraint.buildJacobian must be called previously. - */ - bool testAngularLimitMotor(int axis_index); - - void setLinearLowerLimit(const btVector3& linearLower) - { - m_linearLimits.m_lowerLimit = linearLower; - } - - void setLinearUpperLimit(const btVector3& linearUpper) - { - m_linearLimits.m_upperLimit = linearUpper; - } - - void setAngularLowerLimit(const btVector3& angularLower) - { - m_angularLimits[0].m_loLimit = angularLower.getX(); - m_angularLimits[1].m_loLimit = angularLower.getY(); - m_angularLimits[2].m_loLimit = angularLower.getZ(); - } - - void setAngularUpperLimit(const btVector3& angularUpper) - { - m_angularLimits[0].m_hiLimit = angularUpper.getX(); - m_angularLimits[1].m_hiLimit = angularUpper.getY(); - m_angularLimits[2].m_hiLimit = angularUpper.getZ(); - } - - //! Retrieves the angular limit informacion - btRotationalLimitMotor * getRotationalLimitMotor(int index) - { - return &m_angularLimits[index]; - } - - //! Retrieves the limit informacion - btTranslationalLimitMotor * getTranslationalLimitMotor() - { - return &m_linearLimits; - } - - //first 3 are linear, next 3 are angular - void setLimit(int axis, btScalar lo, btScalar hi) - { - if(axis<3) - { - m_linearLimits.m_lowerLimit[axis] = lo; - m_linearLimits.m_upperLimit[axis] = hi; - } - else - { - m_angularLimits[axis-3].m_loLimit = lo; - m_angularLimits[axis-3].m_hiLimit = hi; - } - } - - //! Test limit - /*! - - free means upper < lower, - - locked means upper == lower - - limited means upper > lower - - limitIndex: first 3 are linear, next 3 are angular - */ - bool isLimited(int limitIndex) - { - if(limitIndex<3) - { - return m_linearLimits.isLimited(limitIndex); - - } - return m_angularLimits[limitIndex-3].isLimited(); - } - - const btRigidBody& getRigidBodyA() const - { - return m_rbA; - } - const btRigidBody& getRigidBodyB() const - { - return m_rbB; - } - - -}; - -#endif //GENERIC_6DOF_CONSTRAINT_H diff --git a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btHingeConstraint.cpp b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btHingeConstraint.cpp deleted file mode 100644 index f71698fa6ee..00000000000 --- a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btHingeConstraint.cpp +++ /dev/null @@ -1,400 +0,0 @@ -/* -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 "btHingeConstraint.h" -#include "BulletDynamics/Dynamics/btRigidBody.h" -#include "LinearMath/btTransformUtil.h" -#include "LinearMath/btMinMax.h" -#include - - -btHingeConstraint::btHingeConstraint() -: btTypedConstraint (HINGE_CONSTRAINT_TYPE), -m_enableAngularMotor(false) -{ -} - -btHingeConstraint::btHingeConstraint(btRigidBody& rbA,btRigidBody& rbB, const btVector3& pivotInA,const btVector3& pivotInB, - btVector3& axisInA,btVector3& axisInB) - :btTypedConstraint(HINGE_CONSTRAINT_TYPE, rbA,rbB), - m_angularOnly(false), - m_enableAngularMotor(false) -{ - m_rbAFrame.getOrigin() = pivotInA; - - // since no frame is given, assume this to be zero angle and just pick rb transform axis - btVector3 rbAxisA1 = rbA.getCenterOfMassTransform().getBasis().getColumn(0); - btScalar projection = rbAxisA1.dot(axisInA); - if (projection > SIMD_EPSILON) - rbAxisA1 = rbAxisA1*projection - axisInA; - else - rbAxisA1 = rbA.getCenterOfMassTransform().getBasis().getColumn(1); - - btVector3 rbAxisA2 = rbAxisA1.cross(axisInA); - - m_rbAFrame.getBasis().setValue( rbAxisA1.getX(),rbAxisA2.getX(),axisInA.getX(), - rbAxisA1.getY(),rbAxisA2.getY(),axisInA.getY(), - rbAxisA1.getZ(),rbAxisA2.getZ(),axisInA.getZ() ); - - btQuaternion rotationArc = shortestArcQuat(axisInA,axisInB); - btVector3 rbAxisB1 = quatRotate(rotationArc,rbAxisA1); - btVector3 rbAxisB2 = rbAxisB1.cross(axisInB); - - - m_rbBFrame.getOrigin() = pivotInB; - m_rbBFrame.getBasis().setValue( rbAxisB1.getX(),rbAxisB2.getX(),-axisInB.getX(), - rbAxisB1.getY(),rbAxisB2.getY(),-axisInB.getY(), - rbAxisB1.getZ(),rbAxisB2.getZ(),-axisInB.getZ() ); - - //start with free - m_lowerLimit = btScalar(1e30); - m_upperLimit = btScalar(-1e30); - m_biasFactor = 0.3f; - m_relaxationFactor = 1.0f; - m_limitSoftness = 0.9f; - m_solveLimit = false; - -} - - -btHingeConstraint::btHingeConstraint(btRigidBody& rbA,const btVector3& pivotInA,btVector3& axisInA) -:btTypedConstraint(HINGE_CONSTRAINT_TYPE, rbA), m_angularOnly(false), m_enableAngularMotor(false) -{ - - // since no frame is given, assume this to be zero angle and just pick rb transform axis - // fixed axis in worldspace - btVector3 rbAxisA1 = rbA.getCenterOfMassTransform().getBasis().getColumn(0); - btScalar projection = rbAxisA1.dot(axisInA); - if (projection > SIMD_EPSILON) - rbAxisA1 = rbAxisA1*projection - axisInA; - else - rbAxisA1 = rbA.getCenterOfMassTransform().getBasis().getColumn(1); - - btVector3 rbAxisA2 = axisInA.cross(rbAxisA1); - - m_rbAFrame.getOrigin() = pivotInA; - m_rbAFrame.getBasis().setValue( rbAxisA1.getX(),rbAxisA2.getX(),axisInA.getX(), - rbAxisA1.getY(),rbAxisA2.getY(),axisInA.getY(), - rbAxisA1.getZ(),rbAxisA2.getZ(),axisInA.getZ() ); - - - btVector3 axisInB = rbA.getCenterOfMassTransform().getBasis() * -axisInA; - - btQuaternion rotationArc = shortestArcQuat(axisInA,axisInB); - btVector3 rbAxisB1 = quatRotate(rotationArc,rbAxisA1); - btVector3 rbAxisB2 = axisInB.cross(rbAxisB1); - - - m_rbBFrame.getOrigin() = rbA.getCenterOfMassTransform()(pivotInA); - m_rbBFrame.getBasis().setValue( rbAxisB1.getX(),rbAxisB2.getX(),axisInB.getX(), - rbAxisB1.getY(),rbAxisB2.getY(),axisInB.getY(), - rbAxisB1.getZ(),rbAxisB2.getZ(),axisInB.getZ() ); - - //start with free - m_lowerLimit = btScalar(1e30); - m_upperLimit = btScalar(-1e30); - m_biasFactor = 0.3f; - m_relaxationFactor = 1.0f; - m_limitSoftness = 0.9f; - m_solveLimit = false; -} - -btHingeConstraint::btHingeConstraint(btRigidBody& rbA,btRigidBody& rbB, - const btTransform& rbAFrame, const btTransform& rbBFrame) -:btTypedConstraint(HINGE_CONSTRAINT_TYPE, rbA,rbB),m_rbAFrame(rbAFrame),m_rbBFrame(rbBFrame), -m_angularOnly(false), -m_enableAngularMotor(false) -{ - // flip axis - m_rbBFrame.getBasis()[0][2] *= btScalar(-1.); - m_rbBFrame.getBasis()[1][2] *= btScalar(-1.); - m_rbBFrame.getBasis()[2][2] *= btScalar(-1.); - - //start with free - m_lowerLimit = btScalar(1e30); - m_upperLimit = btScalar(-1e30); - m_biasFactor = 0.3f; - m_relaxationFactor = 1.0f; - m_limitSoftness = 0.9f; - m_solveLimit = false; -} - - - -btHingeConstraint::btHingeConstraint(btRigidBody& rbA, const btTransform& rbAFrame) -:btTypedConstraint(HINGE_CONSTRAINT_TYPE, rbA),m_rbAFrame(rbAFrame),m_rbBFrame(rbAFrame), -m_angularOnly(false), -m_enableAngularMotor(false) -{ - ///not providing rigidbody B means implicitly using worldspace for body B - - // flip axis - m_rbBFrame.getBasis()[0][2] *= btScalar(-1.); - m_rbBFrame.getBasis()[1][2] *= btScalar(-1.); - m_rbBFrame.getBasis()[2][2] *= btScalar(-1.); - - m_rbBFrame.getOrigin() = m_rbA.getCenterOfMassTransform()(m_rbAFrame.getOrigin()); - - //start with free - m_lowerLimit = btScalar(1e30); - m_upperLimit = btScalar(-1e30); - m_biasFactor = 0.3f; - m_relaxationFactor = 1.0f; - m_limitSoftness = 0.9f; - m_solveLimit = false; -} - -void btHingeConstraint::buildJacobian() -{ - m_appliedImpulse = btScalar(0.); - - if (!m_angularOnly) - { - btVector3 pivotAInW = m_rbA.getCenterOfMassTransform()*m_rbAFrame.getOrigin(); - btVector3 pivotBInW = m_rbB.getCenterOfMassTransform()*m_rbBFrame.getOrigin(); - btVector3 relPos = pivotBInW - pivotAInW; - - btVector3 normal[3]; - if (relPos.length2() > SIMD_EPSILON) - { - normal[0] = relPos.normalized(); - } - else - { - normal[0].setValue(btScalar(1.0),0,0); - } - - btPlaneSpace1(normal[0], normal[1], normal[2]); - - for (int i=0;i<3;i++) - { - new (&m_jac[i]) btJacobianEntry( - m_rbA.getCenterOfMassTransform().getBasis().transpose(), - m_rbB.getCenterOfMassTransform().getBasis().transpose(), - pivotAInW - m_rbA.getCenterOfMassPosition(), - pivotBInW - m_rbB.getCenterOfMassPosition(), - normal[i], - m_rbA.getInvInertiaDiagLocal(), - m_rbA.getInvMass(), - m_rbB.getInvInertiaDiagLocal(), - m_rbB.getInvMass()); - } - } - - //calculate two perpendicular jointAxis, orthogonal to hingeAxis - //these two jointAxis require equal angular velocities for both bodies - - //this is unused for now, it's a todo - btVector3 jointAxis0local; - btVector3 jointAxis1local; - - btPlaneSpace1(m_rbAFrame.getBasis().getColumn(2),jointAxis0local,jointAxis1local); - - getRigidBodyA().getCenterOfMassTransform().getBasis() * m_rbAFrame.getBasis().getColumn(2); - btVector3 jointAxis0 = getRigidBodyA().getCenterOfMassTransform().getBasis() * jointAxis0local; - btVector3 jointAxis1 = getRigidBodyA().getCenterOfMassTransform().getBasis() * jointAxis1local; - btVector3 hingeAxisWorld = getRigidBodyA().getCenterOfMassTransform().getBasis() * m_rbAFrame.getBasis().getColumn(2); - - new (&m_jacAng[0]) btJacobianEntry(jointAxis0, - m_rbA.getCenterOfMassTransform().getBasis().transpose(), - m_rbB.getCenterOfMassTransform().getBasis().transpose(), - m_rbA.getInvInertiaDiagLocal(), - m_rbB.getInvInertiaDiagLocal()); - - new (&m_jacAng[1]) btJacobianEntry(jointAxis1, - m_rbA.getCenterOfMassTransform().getBasis().transpose(), - m_rbB.getCenterOfMassTransform().getBasis().transpose(), - m_rbA.getInvInertiaDiagLocal(), - m_rbB.getInvInertiaDiagLocal()); - - new (&m_jacAng[2]) btJacobianEntry(hingeAxisWorld, - m_rbA.getCenterOfMassTransform().getBasis().transpose(), - m_rbB.getCenterOfMassTransform().getBasis().transpose(), - m_rbA.getInvInertiaDiagLocal(), - m_rbB.getInvInertiaDiagLocal()); - - - // Compute limit information - btScalar hingeAngle = getHingeAngle(); - - //set bias, sign, clear accumulator - m_correction = btScalar(0.); - m_limitSign = btScalar(0.); - m_solveLimit = false; - m_accLimitImpulse = btScalar(0.); - - if (m_lowerLimit < m_upperLimit) - { - if (hingeAngle <= m_lowerLimit*m_limitSoftness) - { - m_correction = (m_lowerLimit - hingeAngle); - m_limitSign = 1.0f; - m_solveLimit = true; - } - else if (hingeAngle >= m_upperLimit*m_limitSoftness) - { - m_correction = m_upperLimit - hingeAngle; - m_limitSign = -1.0f; - m_solveLimit = true; - } - } - - //Compute K = J*W*J' for hinge axis - btVector3 axisA = getRigidBodyA().getCenterOfMassTransform().getBasis() * m_rbAFrame.getBasis().getColumn(2); - m_kHinge = 1.0f / (getRigidBodyA().computeAngularImpulseDenominator(axisA) + - getRigidBodyB().computeAngularImpulseDenominator(axisA)); - -} - -void btHingeConstraint::solveConstraint(btScalar timeStep) -{ - - btVector3 pivotAInW = m_rbA.getCenterOfMassTransform()*m_rbAFrame.getOrigin(); - btVector3 pivotBInW = m_rbB.getCenterOfMassTransform()*m_rbBFrame.getOrigin(); - - btScalar tau = btScalar(0.3); - - //linear part - if (!m_angularOnly) - { - btVector3 rel_pos1 = pivotAInW - m_rbA.getCenterOfMassPosition(); - btVector3 rel_pos2 = pivotBInW - m_rbB.getCenterOfMassPosition(); - - btVector3 vel1 = m_rbA.getVelocityInLocalPoint(rel_pos1); - btVector3 vel2 = m_rbB.getVelocityInLocalPoint(rel_pos2); - btVector3 vel = vel1 - vel2; - - for (int i=0;i<3;i++) - { - const btVector3& normal = m_jac[i].m_linearJointAxis; - btScalar jacDiagABInv = btScalar(1.) / m_jac[i].getDiagonal(); - - btScalar rel_vel; - rel_vel = normal.dot(vel); - //positional error (zeroth order error) - btScalar depth = -(pivotAInW - pivotBInW).dot(normal); //this is the error projected on the normal - btScalar impulse = depth*tau/timeStep * jacDiagABInv - rel_vel * jacDiagABInv; - m_appliedImpulse += impulse; - btVector3 impulse_vector = normal * impulse; - m_rbA.applyImpulse(impulse_vector, pivotAInW - m_rbA.getCenterOfMassPosition()); - m_rbB.applyImpulse(-impulse_vector, pivotBInW - m_rbB.getCenterOfMassPosition()); - } - } - - - { - ///solve angular part - - // get axes in world space - btVector3 axisA = getRigidBodyA().getCenterOfMassTransform().getBasis() * m_rbAFrame.getBasis().getColumn(2); - btVector3 axisB = getRigidBodyB().getCenterOfMassTransform().getBasis() * m_rbBFrame.getBasis().getColumn(2); - - const btVector3& angVelA = getRigidBodyA().getAngularVelocity(); - const btVector3& angVelB = getRigidBodyB().getAngularVelocity(); - - btVector3 angVelAroundHingeAxisA = axisA * axisA.dot(angVelA); - btVector3 angVelAroundHingeAxisB = axisB * axisB.dot(angVelB); - - btVector3 angAorthog = angVelA - angVelAroundHingeAxisA; - btVector3 angBorthog = angVelB - angVelAroundHingeAxisB; - btVector3 velrelOrthog = angAorthog-angBorthog; - { - //solve orthogonal angular velocity correction - btScalar relaxation = btScalar(1.); - btScalar len = velrelOrthog.length(); - if (len > btScalar(0.00001)) - { - btVector3 normal = velrelOrthog.normalized(); - btScalar denom = getRigidBodyA().computeAngularImpulseDenominator(normal) + - getRigidBodyB().computeAngularImpulseDenominator(normal); - // scale for mass and relaxation - //todo: expose this 0.9 factor to developer - velrelOrthog *= (btScalar(1.)/denom) * m_relaxationFactor; - } - - //solve angular positional correction - btVector3 angularError = -axisA.cross(axisB) *(btScalar(1.)/timeStep); - btScalar len2 = angularError.length(); - if (len2>btScalar(0.00001)) - { - btVector3 normal2 = angularError.normalized(); - btScalar denom2 = getRigidBodyA().computeAngularImpulseDenominator(normal2) + - getRigidBodyB().computeAngularImpulseDenominator(normal2); - angularError *= (btScalar(1.)/denom2) * relaxation; - } - - m_rbA.applyTorqueImpulse(-velrelOrthog+angularError); - m_rbB.applyTorqueImpulse(velrelOrthog-angularError); - - // solve limit - if (m_solveLimit) - { - btScalar amplitude = ( (angVelB - angVelA).dot( axisA )*m_relaxationFactor + m_correction* (btScalar(1.)/timeStep)*m_biasFactor ) * m_limitSign; - - btScalar impulseMag = amplitude * m_kHinge; - - // Clamp the accumulated impulse - btScalar temp = m_accLimitImpulse; - m_accLimitImpulse = btMax(m_accLimitImpulse + impulseMag, btScalar(0) ); - impulseMag = m_accLimitImpulse - temp; - - - btVector3 impulse = axisA * impulseMag * m_limitSign; - m_rbA.applyTorqueImpulse(impulse); - m_rbB.applyTorqueImpulse(-impulse); - } - } - - //apply motor - if (m_enableAngularMotor) - { - //todo: add limits too - btVector3 angularLimit(0,0,0); - - btVector3 velrel = angVelAroundHingeAxisA - angVelAroundHingeAxisB; - btScalar projRelVel = velrel.dot(axisA); - - btScalar desiredMotorVel = m_motorTargetVelocity; - btScalar motor_relvel = desiredMotorVel - projRelVel; - - btScalar unclippedMotorImpulse = m_kHinge * motor_relvel;; - //todo: should clip against accumulated impulse - btScalar clippedMotorImpulse = unclippedMotorImpulse > m_maxMotorImpulse ? m_maxMotorImpulse : unclippedMotorImpulse; - clippedMotorImpulse = clippedMotorImpulse < -m_maxMotorImpulse ? -m_maxMotorImpulse : clippedMotorImpulse; - btVector3 motorImp = clippedMotorImpulse * axisA; - - m_rbA.applyTorqueImpulse(motorImp+angularLimit); - m_rbB.applyTorqueImpulse(-motorImp-angularLimit); - - } - } - -} - -void btHingeConstraint::updateRHS(btScalar timeStep) -{ - (void)timeStep; - -} - -btScalar btHingeConstraint::getHingeAngle() -{ - const btVector3 refAxis0 = getRigidBodyA().getCenterOfMassTransform().getBasis() * m_rbAFrame.getBasis().getColumn(0); - const btVector3 refAxis1 = getRigidBodyA().getCenterOfMassTransform().getBasis() * m_rbAFrame.getBasis().getColumn(1); - const btVector3 swingAxis = getRigidBodyB().getCenterOfMassTransform().getBasis() * m_rbBFrame.getBasis().getColumn(1); - - return btAtan2Fast( swingAxis.dot(refAxis0), swingAxis.dot(refAxis1) ); -} diff --git a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btHingeConstraint.h b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btHingeConstraint.h deleted file mode 100644 index 8d8adfe9250..00000000000 --- a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btHingeConstraint.h +++ /dev/null @@ -1,130 +0,0 @@ -/* -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. -*/ - -/* Hinge Constraint by Dirk Gregorius. Limits added by Marcus Hennix at Starbreeze Studios */ - -#ifndef HINGECONSTRAINT_H -#define HINGECONSTRAINT_H - -#include "LinearMath/btVector3.h" -#include "btJacobianEntry.h" -#include "btTypedConstraint.h" - -class btRigidBody; - -/// hinge constraint between two rigidbodies each with a pivotpoint that descibes the axis location in local space -/// axis defines the orientation of the hinge axis -class btHingeConstraint : public btTypedConstraint -{ -#ifdef IN_PARALLELL_SOLVER -public: -#endif - btJacobianEntry m_jac[3]; //3 orthogonal linear constraints - btJacobianEntry m_jacAng[3]; //2 orthogonal angular constraints+ 1 for limit/motor - - btTransform m_rbAFrame; // constraint axii. Assumes z is hinge axis. - btTransform m_rbBFrame; - - btScalar m_motorTargetVelocity; - btScalar m_maxMotorImpulse; - - btScalar m_limitSoftness; - btScalar m_biasFactor; - btScalar m_relaxationFactor; - - btScalar m_lowerLimit; - btScalar m_upperLimit; - - btScalar m_kHinge; - - btScalar m_limitSign; - btScalar m_correction; - - btScalar m_accLimitImpulse; - - bool m_angularOnly; - bool m_enableAngularMotor; - bool m_solveLimit; - - -public: - - btHingeConstraint(btRigidBody& rbA,btRigidBody& rbB, const btVector3& pivotInA,const btVector3& pivotInB, btVector3& axisInA,btVector3& axisInB); - - btHingeConstraint(btRigidBody& rbA,const btVector3& pivotInA,btVector3& axisInA); - - btHingeConstraint(btRigidBody& rbA,btRigidBody& rbB, const btTransform& rbAFrame, const btTransform& rbBFrame); - - btHingeConstraint(btRigidBody& rbA,const btTransform& rbAFrame); - - btHingeConstraint(); - - virtual void buildJacobian(); - - virtual void solveConstraint(btScalar timeStep); - - void updateRHS(btScalar timeStep); - - const btRigidBody& getRigidBodyA() const - { - return m_rbA; - } - const btRigidBody& getRigidBodyB() const - { - return m_rbB; - } - - void setAngularOnly(bool angularOnly) - { - m_angularOnly = angularOnly; - } - - void enableAngularMotor(bool enableMotor,btScalar targetVelocity,btScalar maxMotorImpulse) - { - m_enableAngularMotor = enableMotor; - m_motorTargetVelocity = targetVelocity; - m_maxMotorImpulse = maxMotorImpulse; - } - - void setLimit(btScalar low,btScalar high,btScalar _softness = 0.9f, btScalar _biasFactor = 0.3f, btScalar _relaxationFactor = 1.0f) - { - m_lowerLimit = low; - m_upperLimit = high; - - m_limitSoftness = _softness; - m_biasFactor = _biasFactor; - m_relaxationFactor = _relaxationFactor; - - } - - btScalar getHingeAngle(); - - - const btTransform& getAFrame() { return m_rbAFrame; }; - const btTransform& getBFrame() { return m_rbBFrame; }; - - inline int getSolveLimit() - { - return m_solveLimit; - } - - inline btScalar getLimitSign() - { - return m_limitSign; - } - -}; - -#endif //HINGECONSTRAINT_H diff --git a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btJacobianEntry.h b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btJacobianEntry.h deleted file mode 100644 index bfeb24c2dfb..00000000000 --- a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btJacobianEntry.h +++ /dev/null @@ -1,156 +0,0 @@ -/* -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 JACOBIAN_ENTRY_H -#define JACOBIAN_ENTRY_H - -#include "LinearMath/btVector3.h" -#include "BulletDynamics/Dynamics/btRigidBody.h" - - -//notes: -// Another memory optimization would be to store m_1MinvJt in the remaining 3 w components -// which makes the btJacobianEntry memory layout 16 bytes -// if you only are interested in angular part, just feed massInvA and massInvB zero - -/// Jacobian entry is an abstraction that allows to describe constraints -/// it can be used in combination with a constraint solver -/// Can be used to relate the effect of an impulse to the constraint error -class btJacobianEntry -{ -public: - btJacobianEntry() {}; - //constraint between two different rigidbodies - btJacobianEntry( - const btMatrix3x3& world2A, - const btMatrix3x3& world2B, - const btVector3& rel_pos1,const btVector3& rel_pos2, - const btVector3& jointAxis, - const btVector3& inertiaInvA, - const btScalar massInvA, - const btVector3& inertiaInvB, - const btScalar massInvB) - :m_linearJointAxis(jointAxis) - { - m_aJ = world2A*(rel_pos1.cross(m_linearJointAxis)); - m_bJ = world2B*(rel_pos2.cross(-m_linearJointAxis)); - m_0MinvJt = inertiaInvA * m_aJ; - m_1MinvJt = inertiaInvB * m_bJ; - m_Adiag = massInvA + m_0MinvJt.dot(m_aJ) + massInvB + m_1MinvJt.dot(m_bJ); - - btAssert(m_Adiag > btScalar(0.0)); - } - - //angular constraint between two different rigidbodies - btJacobianEntry(const btVector3& jointAxis, - const btMatrix3x3& world2A, - const btMatrix3x3& world2B, - const btVector3& inertiaInvA, - const btVector3& inertiaInvB) - :m_linearJointAxis(btVector3(btScalar(0.),btScalar(0.),btScalar(0.))) - { - m_aJ= world2A*jointAxis; - m_bJ = world2B*-jointAxis; - m_0MinvJt = inertiaInvA * m_aJ; - m_1MinvJt = inertiaInvB * m_bJ; - m_Adiag = m_0MinvJt.dot(m_aJ) + m_1MinvJt.dot(m_bJ); - - btAssert(m_Adiag > btScalar(0.0)); - } - - //angular constraint between two different rigidbodies - btJacobianEntry(const btVector3& axisInA, - const btVector3& axisInB, - const btVector3& inertiaInvA, - const btVector3& inertiaInvB) - : m_linearJointAxis(btVector3(btScalar(0.),btScalar(0.),btScalar(0.))) - , m_aJ(axisInA) - , m_bJ(-axisInB) - { - m_0MinvJt = inertiaInvA * m_aJ; - m_1MinvJt = inertiaInvB * m_bJ; - m_Adiag = m_0MinvJt.dot(m_aJ) + m_1MinvJt.dot(m_bJ); - - btAssert(m_Adiag > btScalar(0.0)); - } - - //constraint on one rigidbody - btJacobianEntry( - const btMatrix3x3& world2A, - const btVector3& rel_pos1,const btVector3& rel_pos2, - const btVector3& jointAxis, - const btVector3& inertiaInvA, - const btScalar massInvA) - :m_linearJointAxis(jointAxis) - { - m_aJ= world2A*(rel_pos1.cross(jointAxis)); - m_bJ = world2A*(rel_pos2.cross(-jointAxis)); - m_0MinvJt = inertiaInvA * m_aJ; - m_1MinvJt = btVector3(btScalar(0.),btScalar(0.),btScalar(0.)); - m_Adiag = massInvA + m_0MinvJt.dot(m_aJ); - - btAssert(m_Adiag > btScalar(0.0)); - } - - btScalar getDiagonal() const { return m_Adiag; } - - // for two constraints on the same rigidbody (for example vehicle friction) - btScalar getNonDiagonal(const btJacobianEntry& jacB, const btScalar massInvA) const - { - const btJacobianEntry& jacA = *this; - btScalar lin = massInvA * jacA.m_linearJointAxis.dot(jacB.m_linearJointAxis); - btScalar ang = jacA.m_0MinvJt.dot(jacB.m_aJ); - return lin + ang; - } - - - - // for two constraints on sharing two same rigidbodies (for example two contact points between two rigidbodies) - btScalar getNonDiagonal(const btJacobianEntry& jacB,const btScalar massInvA,const btScalar massInvB) const - { - const btJacobianEntry& jacA = *this; - btVector3 lin = jacA.m_linearJointAxis * jacB.m_linearJointAxis; - btVector3 ang0 = jacA.m_0MinvJt * jacB.m_aJ; - btVector3 ang1 = jacA.m_1MinvJt * jacB.m_bJ; - btVector3 lin0 = massInvA * lin ; - btVector3 lin1 = massInvB * lin; - btVector3 sum = ang0+ang1+lin0+lin1; - return sum[0]+sum[1]+sum[2]; - } - - btScalar getRelativeVelocity(const btVector3& linvelA,const btVector3& angvelA,const btVector3& linvelB,const btVector3& angvelB) - { - btVector3 linrel = linvelA - linvelB; - btVector3 angvela = angvelA * m_aJ; - btVector3 angvelb = angvelB * m_bJ; - linrel *= m_linearJointAxis; - angvela += angvelb; - angvela += linrel; - btScalar rel_vel2 = angvela[0]+angvela[1]+angvela[2]; - return rel_vel2 + SIMD_EPSILON; - } -//private: - - btVector3 m_linearJointAxis; - btVector3 m_aJ; - btVector3 m_bJ; - btVector3 m_0MinvJt; - btVector3 m_1MinvJt; - //Optimization: can be stored in the w/last component of one of the vectors - btScalar m_Adiag; - -}; - -#endif //JACOBIAN_ENTRY_H diff --git a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btPoint2PointConstraint.cpp b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btPoint2PointConstraint.cpp deleted file mode 100644 index ff918ea5625..00000000000 --- a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btPoint2PointConstraint.cpp +++ /dev/null @@ -1,117 +0,0 @@ -/* -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 "btPoint2PointConstraint.h" -#include "BulletDynamics/Dynamics/btRigidBody.h" -#include - - - -btPoint2PointConstraint::btPoint2PointConstraint() -:btTypedConstraint(POINT2POINT_CONSTRAINT_TYPE) -{ -} - -btPoint2PointConstraint::btPoint2PointConstraint(btRigidBody& rbA,btRigidBody& rbB, const btVector3& pivotInA,const btVector3& pivotInB) -:btTypedConstraint(POINT2POINT_CONSTRAINT_TYPE,rbA,rbB),m_pivotInA(pivotInA),m_pivotInB(pivotInB) -{ - -} - - -btPoint2PointConstraint::btPoint2PointConstraint(btRigidBody& rbA,const btVector3& pivotInA) -:btTypedConstraint(POINT2POINT_CONSTRAINT_TYPE,rbA),m_pivotInA(pivotInA),m_pivotInB(rbA.getCenterOfMassTransform()(pivotInA)) -{ - -} - -void btPoint2PointConstraint::buildJacobian() -{ - m_appliedImpulse = btScalar(0.); - - btVector3 normal(0,0,0); - - for (int i=0;i<3;i++) - { - normal[i] = 1; - new (&m_jac[i]) btJacobianEntry( - m_rbA.getCenterOfMassTransform().getBasis().transpose(), - m_rbB.getCenterOfMassTransform().getBasis().transpose(), - m_rbA.getCenterOfMassTransform()*m_pivotInA - m_rbA.getCenterOfMassPosition(), - m_rbB.getCenterOfMassTransform()*m_pivotInB - m_rbB.getCenterOfMassPosition(), - normal, - m_rbA.getInvInertiaDiagLocal(), - m_rbA.getInvMass(), - m_rbB.getInvInertiaDiagLocal(), - m_rbB.getInvMass()); - normal[i] = 0; - } - -} - -void btPoint2PointConstraint::solveConstraint(btScalar timeStep) -{ - btVector3 pivotAInW = m_rbA.getCenterOfMassTransform()*m_pivotInA; - btVector3 pivotBInW = m_rbB.getCenterOfMassTransform()*m_pivotInB; - - - btVector3 normal(0,0,0); - - -// btVector3 angvelA = m_rbA.getCenterOfMassTransform().getBasis().transpose() * m_rbA.getAngularVelocity(); -// btVector3 angvelB = m_rbB.getCenterOfMassTransform().getBasis().transpose() * m_rbB.getAngularVelocity(); - - for (int i=0;i<3;i++) - { - normal[i] = 1; - btScalar jacDiagABInv = btScalar(1.) / m_jac[i].getDiagonal(); - - btVector3 rel_pos1 = pivotAInW - m_rbA.getCenterOfMassPosition(); - btVector3 rel_pos2 = pivotBInW - m_rbB.getCenterOfMassPosition(); - //this jacobian entry could be re-used for all iterations - - btVector3 vel1 = m_rbA.getVelocityInLocalPoint(rel_pos1); - btVector3 vel2 = m_rbB.getVelocityInLocalPoint(rel_pos2); - btVector3 vel = vel1 - vel2; - - btScalar rel_vel; - rel_vel = normal.dot(vel); - - /* - //velocity error (first order error) - btScalar rel_vel = m_jac[i].getRelativeVelocity(m_rbA.getLinearVelocity(),angvelA, - m_rbB.getLinearVelocity(),angvelB); - */ - - //positional error (zeroth order error) - btScalar depth = -(pivotAInW - pivotBInW).dot(normal); //this is the error projected on the normal - - btScalar impulse = depth*m_setting.m_tau/timeStep * jacDiagABInv - m_setting.m_damping * rel_vel * jacDiagABInv; - m_appliedImpulse+=impulse; - btVector3 impulse_vector = normal * impulse; - m_rbA.applyImpulse(impulse_vector, pivotAInW - m_rbA.getCenterOfMassPosition()); - m_rbB.applyImpulse(-impulse_vector, pivotBInW - m_rbB.getCenterOfMassPosition()); - - normal[i] = 0; - } -} - -void btPoint2PointConstraint::updateRHS(btScalar timeStep) -{ - (void)timeStep; - -} - diff --git a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btPoint2PointConstraint.h b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btPoint2PointConstraint.h deleted file mode 100644 index 27872b9c8aa..00000000000 --- a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btPoint2PointConstraint.h +++ /dev/null @@ -1,89 +0,0 @@ -/* -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 POINT2POINTCONSTRAINT_H -#define POINT2POINTCONSTRAINT_H - -#include "LinearMath/btVector3.h" -#include "btJacobianEntry.h" -#include "btTypedConstraint.h" - -class btRigidBody; - -struct btConstraintSetting -{ - btConstraintSetting() : - m_tau(btScalar(0.3)), - m_damping(btScalar(1.)) - { - } - btScalar m_tau; - btScalar m_damping; -}; - -/// point to point constraint between two rigidbodies each with a pivotpoint that descibes the 'ballsocket' location in local space -class btPoint2PointConstraint : public btTypedConstraint -{ -#ifdef IN_PARALLELL_SOLVER -public: -#endif - btJacobianEntry m_jac[3]; //3 orthogonal linear constraints - - btVector3 m_pivotInA; - btVector3 m_pivotInB; - - - -public: - - btConstraintSetting m_setting; - - btPoint2PointConstraint(btRigidBody& rbA,btRigidBody& rbB, const btVector3& pivotInA,const btVector3& pivotInB); - - btPoint2PointConstraint(btRigidBody& rbA,const btVector3& pivotInA); - - btPoint2PointConstraint(); - - virtual void buildJacobian(); - - - virtual void solveConstraint(btScalar timeStep); - - void updateRHS(btScalar timeStep); - - void setPivotA(const btVector3& pivotA) - { - m_pivotInA = pivotA; - } - - void setPivotB(const btVector3& pivotB) - { - m_pivotInB = pivotB; - } - - const btVector3& getPivotInA() const - { - return m_pivotInA; - } - - const btVector3& getPivotInB() const - { - return m_pivotInB; - } - - -}; - -#endif //POINT2POINTCONSTRAINT_H diff --git a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.cpp b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.cpp deleted file mode 100644 index 7d4ed7856c3..00000000000 --- a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.cpp +++ /dev/null @@ -1,1266 +0,0 @@ -/* -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 COMPUTE_IMPULSE_DENOM 1 -//It is not necessary (redundant) to refresh contact manifolds, this refresh has been moved to the collision algorithms. -//#define FORCE_REFESH_CONTACT_MANIFOLDS 1 - -#include "btSequentialImpulseConstraintSolver.h" -#include "BulletCollision/NarrowPhaseCollision/btPersistentManifold.h" -#include "BulletDynamics/Dynamics/btRigidBody.h" -#include "btContactConstraint.h" -#include "btSolve2LinearConstraint.h" -#include "btContactSolverInfo.h" -#include "LinearMath/btIDebugDraw.h" -#include "btJacobianEntry.h" -#include "LinearMath/btMinMax.h" -#include "BulletDynamics/ConstraintSolver/btTypedConstraint.h" -#include -#include "LinearMath/btStackAlloc.h" -#include "LinearMath/btQuickprof.h" -#include "btSolverBody.h" -#include "btSolverConstraint.h" - -#include "LinearMath/btAlignedObjectArray.h" - -#ifdef USE_PROFILE -#include "LinearMath/btQuickprof.h" -#endif //USE_PROFILE - -int totalCpd = 0; - -int gTotalContactPoints = 0; - -struct btOrderIndex -{ - int m_manifoldIndex; - int m_pointIndex; -}; - - - -#define SEQUENTIAL_IMPULSE_MAX_SOLVER_POINTS 16384 -static btOrderIndex gOrder[SEQUENTIAL_IMPULSE_MAX_SOLVER_POINTS]; - - -unsigned long btSequentialImpulseConstraintSolver::btRand2() -{ - m_btSeed2 = (1664525L*m_btSeed2 + 1013904223L) & 0xffffffff; - return m_btSeed2; -} - - - -//See ODE: adam's all-int straightforward(?) dRandInt (0..n-1) -int btSequentialImpulseConstraintSolver::btRandInt2 (int n) -{ - // seems good; xor-fold and modulus - const unsigned long un = n; - unsigned long r = btRand2(); - - // note: probably more aggressive than it needs to be -- might be - // able to get away without one or two of the innermost branches. - if (un <= 0x00010000UL) { - r ^= (r >> 16); - if (un <= 0x00000100UL) { - r ^= (r >> 8); - if (un <= 0x00000010UL) { - r ^= (r >> 4); - if (un <= 0x00000004UL) { - r ^= (r >> 2); - if (un <= 0x00000002UL) { - r ^= (r >> 1); - } - } - } - } - } - - return (int) (r % un); -} - - - - - -bool MyContactDestroyedCallback(void* userPersistentData) -{ - assert (userPersistentData); - btConstraintPersistentData* cpd = (btConstraintPersistentData*)userPersistentData; - btAlignedFree(cpd); - totalCpd--; - //printf("totalCpd = %i. DELETED Ptr %x\n",totalCpd,userPersistentData); - return true; -} - - - -btSequentialImpulseConstraintSolver::btSequentialImpulseConstraintSolver() -:m_solverMode(SOLVER_RANDMIZE_ORDER | SOLVER_CACHE_FRIENDLY), //not using SOLVER_USE_WARMSTARTING, -m_btSeed2(0) -{ - gContactDestroyedCallback = &MyContactDestroyedCallback; - - //initialize default friction/contact funcs - int i,j; - for (i=0;im_angularVelocity = rigidbody->getAngularVelocity(); - solverBody->m_centerOfMassPosition = rigidbody->getCenterOfMassPosition(); - solverBody->m_friction = rigidbody->getFriction(); -// solverBody->m_invInertiaWorld = rigidbody->getInvInertiaTensorWorld(); - solverBody->m_invMass = rigidbody->getInvMass(); - solverBody->m_linearVelocity = rigidbody->getLinearVelocity(); - solverBody->m_originalBody = rigidbody; - solverBody->m_angularFactor = rigidbody->getAngularFactor(); -} - -btScalar penetrationResolveFactor = btScalar(0.9); -btScalar restitutionCurve(btScalar rel_vel, btScalar restitution) -{ - btScalar rest = restitution * -rel_vel; - return rest; -} - - - - - - -//velocity + friction -//response between two dynamic objects with friction -//SIMD_FORCE_INLINE -btScalar resolveSingleCollisionCombinedCacheFriendly( - btSolverBody& body1, - btSolverBody& body2, - const btSolverConstraint& contactConstraint, - const btContactSolverInfo& solverInfo) -{ - (void)solverInfo; - - btScalar normalImpulse; - - // Optimized version of projected relative velocity, use precomputed cross products with normal - // body1.getVelocityInLocalPoint(contactConstraint.m_rel_posA,vel1); - // body2.getVelocityInLocalPoint(contactConstraint.m_rel_posB,vel2); - // btVector3 vel = vel1 - vel2; - // btScalar rel_vel = contactConstraint.m_contactNormal.dot(vel); - - btScalar rel_vel; - btScalar vel1Dotn = contactConstraint.m_contactNormal.dot(body1.m_linearVelocity) - + contactConstraint.m_relpos1CrossNormal.dot(body1.m_angularVelocity); - btScalar vel2Dotn = contactConstraint.m_contactNormal.dot(body2.m_linearVelocity) - + contactConstraint.m_relpos2CrossNormal.dot(body2.m_angularVelocity); - - rel_vel = vel1Dotn-vel2Dotn; - - - btScalar positionalError = contactConstraint.m_penetration; - btScalar velocityError = contactConstraint.m_restitution - rel_vel;// * damping; - - btScalar penetrationImpulse = positionalError * contactConstraint.m_jacDiagABInv; - btScalar velocityImpulse = velocityError * contactConstraint.m_jacDiagABInv; - normalImpulse = penetrationImpulse+velocityImpulse; - - // See Erin Catto's GDC 2006 paper: Clamp the accumulated impulse - btScalar oldNormalImpulse = contactConstraint.m_appliedImpulse; - btScalar sum = oldNormalImpulse + normalImpulse; - contactConstraint.m_appliedImpulse = btScalar(0.) > sum ? btScalar(0.): sum; - - btScalar oldVelocityImpulse = contactConstraint.m_appliedVelocityImpulse; - btScalar velocitySum = oldVelocityImpulse + velocityImpulse; - contactConstraint.m_appliedVelocityImpulse = btScalar(0.) > velocitySum ? btScalar(0.): velocitySum; - - normalImpulse = contactConstraint.m_appliedImpulse - oldNormalImpulse; - - if (body1.m_invMass) - { - body1.internalApplyImpulse(contactConstraint.m_contactNormal*body1.m_invMass, - contactConstraint.m_angularComponentA,normalImpulse); - } - if (body2.m_invMass) - { - body2.internalApplyImpulse(contactConstraint.m_contactNormal*body2.m_invMass, - contactConstraint.m_angularComponentB,-normalImpulse); - } - - - - - - return normalImpulse; -} - - -#ifndef NO_FRICTION_TANGENTIALS - -//SIMD_FORCE_INLINE -btScalar resolveSingleFrictionCacheFriendly( - btSolverBody& body1, - btSolverBody& body2, - const btSolverConstraint& contactConstraint, - const btContactSolverInfo& solverInfo, - btScalar appliedNormalImpulse) -{ - (void)solverInfo; - - - const btScalar combinedFriction = contactConstraint.m_friction; - - const btScalar limit = appliedNormalImpulse * combinedFriction; - - if (appliedNormalImpulse>btScalar(0.)) - //friction - { - - btScalar j1; - { - - btScalar rel_vel; - const btScalar vel1Dotn = contactConstraint.m_contactNormal.dot(body1.m_linearVelocity) - + contactConstraint.m_relpos1CrossNormal.dot(body1.m_angularVelocity); - const btScalar vel2Dotn = contactConstraint.m_contactNormal.dot(body2.m_linearVelocity) - + contactConstraint.m_relpos2CrossNormal.dot(body2.m_angularVelocity); - rel_vel = vel1Dotn-vel2Dotn; - - // calculate j that moves us to zero relative velocity - j1 = -rel_vel * contactConstraint.m_jacDiagABInv; -#define CLAMP_ACCUMULATED_FRICTION_IMPULSE 1 -#ifdef CLAMP_ACCUMULATED_FRICTION_IMPULSE - btScalar oldTangentImpulse = contactConstraint.m_appliedImpulse; - contactConstraint.m_appliedImpulse = oldTangentImpulse + j1; - - if (limit < contactConstraint.m_appliedImpulse) - { - contactConstraint.m_appliedImpulse = limit; - } else - { - if (contactConstraint.m_appliedImpulse < -limit) - contactConstraint.m_appliedImpulse = -limit; - } - j1 = contactConstraint.m_appliedImpulse - oldTangentImpulse; -#else - if (limit < j1) - { - j1 = limit; - } else - { - if (j1 < -limit) - j1 = -limit; - } - -#endif //CLAMP_ACCUMULATED_FRICTION_IMPULSE - - //GEN_set_min(contactConstraint.m_appliedImpulse, limit); - //GEN_set_max(contactConstraint.m_appliedImpulse, -limit); - - - - } - - if (body1.m_invMass) - { - body1.internalApplyImpulse(contactConstraint.m_contactNormal*body1.m_invMass,contactConstraint.m_angularComponentA,j1); - } - if (body2.m_invMass) - { - body2.internalApplyImpulse(contactConstraint.m_contactNormal*body2.m_invMass,contactConstraint.m_angularComponentB,-j1); - } - - } - return 0.f; -} - - -#else - -//velocity + friction -//response between two dynamic objects with friction -btScalar resolveSingleFrictionCacheFriendly( - btSolverBody& body1, - btSolverBody& body2, - btSolverConstraint& contactConstraint, - const btContactSolverInfo& solverInfo) -{ - - btVector3 vel1; - btVector3 vel2; - btScalar normalImpulse(0.f); - - { - const btVector3& normal = contactConstraint.m_contactNormal; - if (contactConstraint.m_penetration < 0.f) - return 0.f; - - - body1.getVelocityInLocalPoint(contactConstraint.m_rel_posA,vel1); - body2.getVelocityInLocalPoint(contactConstraint.m_rel_posB,vel2); - btVector3 vel = vel1 - vel2; - btScalar rel_vel; - rel_vel = normal.dot(vel); - - btVector3 lat_vel = vel - normal * rel_vel; - btScalar lat_rel_vel = lat_vel.length2(); - - btScalar combinedFriction = contactConstraint.m_friction; - const btVector3& rel_pos1 = contactConstraint.m_rel_posA; - const btVector3& rel_pos2 = contactConstraint.m_rel_posB; - - - //if (contactConstraint.m_appliedVelocityImpulse > 0.f) - if (lat_rel_vel > SIMD_EPSILON*SIMD_EPSILON) - { - lat_rel_vel = btSqrt(lat_rel_vel); - - lat_vel /= lat_rel_vel; - btVector3 temp1 = body1.m_invInertiaWorld * rel_pos1.cross(lat_vel); - btVector3 temp2 = body2.m_invInertiaWorld * rel_pos2.cross(lat_vel); - btScalar friction_impulse = lat_rel_vel / - (body1.m_invMass + body2.m_invMass + lat_vel.dot(temp1.cross(rel_pos1) + temp2.cross(rel_pos2))); - btScalar normal_impulse = contactConstraint.m_appliedVelocityImpulse * combinedFriction; - - GEN_set_min(friction_impulse, normal_impulse); - GEN_set_max(friction_impulse, -normal_impulse); - body1.applyImpulse(lat_vel * -friction_impulse, rel_pos1); - body2.applyImpulse(lat_vel * friction_impulse, rel_pos2); - } - } - - return normalImpulse; -} - -#endif //NO_FRICTION_TANGENTIALS - - - - - -void btSequentialImpulseConstraintSolver::addFrictionConstraint(const btVector3& normalAxis,int solverBodyIdA,int solverBodyIdB,int frictionIndex,btManifoldPoint& cp,const btVector3& rel_pos1,const btVector3& rel_pos2,btRigidBody* rb0,btRigidBody* rb1, btScalar relaxation) -{ - - btSolverConstraint& solverConstraint = m_tmpSolverFrictionConstraintPool.expand(); - solverConstraint.m_contactNormal = normalAxis; - - solverConstraint.m_solverBodyIdA = solverBodyIdA; - solverConstraint.m_solverBodyIdB = solverBodyIdB; - solverConstraint.m_constraintType = btSolverConstraint::BT_SOLVER_FRICTION_1D; - solverConstraint.m_frictionIndex = frictionIndex; - - solverConstraint.m_friction = cp.m_combinedFriction; - - solverConstraint.m_appliedImpulse = btScalar(0.); - solverConstraint.m_appliedVelocityImpulse = 0.f; - solverConstraint.m_penetration = 0.f; - { - btVector3 ftorqueAxis1 = rel_pos1.cross(solverConstraint.m_contactNormal); - solverConstraint.m_relpos1CrossNormal = ftorqueAxis1; - solverConstraint.m_angularComponentA = rb0->getInvInertiaTensorWorld()*ftorqueAxis1; - } - { - btVector3 ftorqueAxis1 = rel_pos2.cross(solverConstraint.m_contactNormal); - solverConstraint.m_relpos2CrossNormal = ftorqueAxis1; - solverConstraint.m_angularComponentB = rb1->getInvInertiaTensorWorld()*ftorqueAxis1; - } - -#ifdef COMPUTE_IMPULSE_DENOM - btScalar denom0 = rb0->computeImpulseDenominator(pos1,solverConstraint.m_contactNormal); - btScalar denom1 = rb1->computeImpulseDenominator(pos2,solverConstraint.m_contactNormal); -#else - btVector3 vec; - vec = ( solverConstraint.m_angularComponentA).cross(rel_pos1); - btScalar denom0 = rb0->getInvMass() + normalAxis.dot(vec); - vec = ( solverConstraint.m_angularComponentB).cross(rel_pos2); - btScalar denom1 = rb1->getInvMass() + normalAxis.dot(vec); - - -#endif //COMPUTE_IMPULSE_DENOM - btScalar denom = relaxation/(denom0+denom1); - solverConstraint.m_jacDiagABInv = denom; - -} - - -btScalar btSequentialImpulseConstraintSolver::solveGroupCacheFriendlySetup(btCollisionObject** bodies,int numBodies,btPersistentManifold** manifoldPtr, int numManifolds,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& infoGlobal,btIDebugDraw* debugDrawer,btStackAlloc* stackAlloc) -{ - (void)stackAlloc; - (void)debugDrawer; - - if (!(numConstraints + numManifolds)) - { -// printf("empty\n"); - return 0.f; - } - btPersistentManifold* manifold = 0; - btRigidBody* rb0=0,*rb1=0; - -#ifdef FORCE_REFESH_CONTACT_MANIFOLDS - - BEGIN_PROFILE("refreshManifolds"); - - int i; - - - - for (i=0;igetBody1(); - rb0 = (btRigidBody*)manifold->getBody0(); - - manifold->refreshContactPoints(rb0->getCenterOfMassTransform(),rb1->getCenterOfMassTransform()); - - } - - END_PROFILE("refreshManifolds"); -#endif //FORCE_REFESH_CONTACT_MANIFOLDS - - btVector3 color(0,1,0); - - - BEGIN_PROFILE("gatherSolverData"); - - //int sizeofSB = sizeof(btSolverBody); - //int sizeofSC = sizeof(btSolverConstraint); - - - //if (1) - { - //if m_stackAlloc, try to pack bodies/constraints to speed up solving -// btBlock* sablock; -// sablock = stackAlloc->beginBlock(); - - // int memsize = 16; -// unsigned char* stackMemory = stackAlloc->allocate(memsize); - - - //todo: use stack allocator for this temp memory - int minReservation = numManifolds*2; - - //m_tmpSolverBodyPool.reserve(minReservation); - - //don't convert all bodies, only the one we need so solver the constraints -/* - { - for (int i=0;igetIslandTag() >= 0)) - { - btAssert(rb->getCompanionId() < 0); - int solverBodyId = m_tmpSolverBodyPool.size(); - btSolverBody& solverBody = m_tmpSolverBodyPool.expand(); - initSolverBody(&solverBody,rb); - rb->setCompanionId(solverBodyId); - } - } - } -*/ - - //m_tmpSolverConstraintPool.reserve(minReservation); - //m_tmpSolverFrictionConstraintPool.reserve(minReservation); - - { - int i; - - for (i=0;igetBody1(); - - rb0 = (btRigidBody*)manifold->getBody0(); - - - int solverBodyIdA=-1; - int solverBodyIdB=-1; - - if (manifold->getNumContacts()) - { - - - - if (rb0->getIslandTag() >= 0) - { - if (rb0->getCompanionId() >= 0) - { - //body has already been converted - solverBodyIdA = rb0->getCompanionId(); - } else - { - solverBodyIdA = m_tmpSolverBodyPool.size(); - btSolverBody& solverBody = m_tmpSolverBodyPool.expand(); - initSolverBody(&solverBody,rb0); - rb0->setCompanionId(solverBodyIdA); - } - } else - { - //create a static body - solverBodyIdA = m_tmpSolverBodyPool.size(); - btSolverBody& solverBody = m_tmpSolverBodyPool.expand(); - initSolverBody(&solverBody,rb0); - } - - if (rb1->getIslandTag() >= 0) - { - if (rb1->getCompanionId() >= 0) - { - solverBodyIdB = rb1->getCompanionId(); - } else - { - solverBodyIdB = m_tmpSolverBodyPool.size(); - btSolverBody& solverBody = m_tmpSolverBodyPool.expand(); - initSolverBody(&solverBody,rb1); - rb1->setCompanionId(solverBodyIdB); - } - } else - { - //create a static body - solverBodyIdB = m_tmpSolverBodyPool.size(); - btSolverBody& solverBody = m_tmpSolverBodyPool.expand(); - initSolverBody(&solverBody,rb1); - } - } - - btVector3 rel_pos1; - btVector3 rel_pos2; - btScalar relaxation; - - for (int j=0;jgetNumContacts();j++) - { - - btManifoldPoint& cp = manifold->getContactPoint(j); - - if (debugDrawer) - debugDrawer->drawContactPoint(cp.m_positionWorldOnB,cp.m_normalWorldOnB,cp.getDistance(),cp.getLifeTime(),color); - - - if (cp.getDistance() <= btScalar(0.)) - { - - const btVector3& pos1 = cp.getPositionWorldOnA(); - const btVector3& pos2 = cp.getPositionWorldOnB(); - - rel_pos1 = pos1 - rb0->getCenterOfMassPosition(); - rel_pos2 = pos2 - rb1->getCenterOfMassPosition(); - - - relaxation = 1.f; - btScalar rel_vel; - btVector3 vel; - - int frictionIndex = m_tmpSolverConstraintPool.size(); - - { - btSolverConstraint& solverConstraint = m_tmpSolverConstraintPool.expand(); - - solverConstraint.m_solverBodyIdA = solverBodyIdA; - solverConstraint.m_solverBodyIdB = solverBodyIdB; - solverConstraint.m_constraintType = btSolverConstraint::BT_SOLVER_CONTACT_1D; - - btVector3 torqueAxis0 = rel_pos1.cross(cp.m_normalWorldOnB); - solverConstraint.m_angularComponentA = rb0->getInvInertiaTensorWorld()*torqueAxis0; - btVector3 torqueAxis1 = rel_pos2.cross(cp.m_normalWorldOnB); - solverConstraint.m_angularComponentB = rb1->getInvInertiaTensorWorld()*torqueAxis1; - { -#ifdef COMPUTE_IMPULSE_DENOM - btScalar denom0 = rb0->computeImpulseDenominator(pos1,cp.m_normalWorldOnB); - btScalar denom1 = rb1->computeImpulseDenominator(pos2,cp.m_normalWorldOnB); -#else - btVector3 vec; - vec = ( solverConstraint.m_angularComponentA).cross(rel_pos1); - btScalar denom0 = rb0->getInvMass() + cp.m_normalWorldOnB.dot(vec); - vec = ( solverConstraint.m_angularComponentB).cross(rel_pos2); - btScalar denom1 = rb1->getInvMass() + cp.m_normalWorldOnB.dot(vec); -#endif //COMPUTE_IMPULSE_DENOM - - btScalar denom = relaxation/(denom0+denom1); - solverConstraint.m_jacDiagABInv = denom; - } - - solverConstraint.m_contactNormal = cp.m_normalWorldOnB; - solverConstraint.m_relpos1CrossNormal = rel_pos1.cross(cp.m_normalWorldOnB); - solverConstraint.m_relpos2CrossNormal = rel_pos2.cross(cp.m_normalWorldOnB); - - - btVector3 vel1 = rb0->getVelocityInLocalPoint(rel_pos1); - btVector3 vel2 = rb1->getVelocityInLocalPoint(rel_pos2); - - vel = vel1 - vel2; - - rel_vel = cp.m_normalWorldOnB.dot(vel); - - - solverConstraint.m_penetration = cp.getDistance();///btScalar(infoGlobal.m_numIterations); - solverConstraint.m_friction = cp.m_combinedFriction; - solverConstraint.m_restitution = restitutionCurve(rel_vel, cp.m_combinedRestitution); - if (solverConstraint.m_restitution <= btScalar(0.)) - { - solverConstraint.m_restitution = 0.f; - }; - - btScalar penVel = -solverConstraint.m_penetration/infoGlobal.m_timeStep; - solverConstraint.m_penetration *= -(infoGlobal.m_erp/infoGlobal.m_timeStep); - - if (solverConstraint.m_restitution > penVel) - { - solverConstraint.m_penetration = btScalar(0.); - } - - - - solverConstraint.m_appliedImpulse = 0.f; - solverConstraint.m_appliedVelocityImpulse = 0.f; - - - - } - - - { - btVector3 frictionDir1 = vel - cp.m_normalWorldOnB * rel_vel; - btScalar lat_rel_vel = frictionDir1.length2(); - if (lat_rel_vel > SIMD_EPSILON)//0.0f) - { - frictionDir1 /= btSqrt(lat_rel_vel); - addFrictionConstraint(frictionDir1,solverBodyIdA,solverBodyIdB,frictionIndex,cp,rel_pos1,rel_pos2,rb0,rb1, relaxation); - btVector3 frictionDir2 = frictionDir1.cross(cp.m_normalWorldOnB); - frictionDir2.normalize();//?? - addFrictionConstraint(frictionDir2,solverBodyIdA,solverBodyIdB,frictionIndex,cp,rel_pos1,rel_pos2,rb0,rb1, relaxation); - } else - { - //re-calculate friction direction every frame, todo: check if this is really needed - btVector3 frictionDir1,frictionDir2; - btPlaneSpace1(cp.m_normalWorldOnB,frictionDir1,frictionDir2); - addFrictionConstraint(frictionDir1,solverBodyIdA,solverBodyIdB,frictionIndex,cp,rel_pos1,rel_pos2,rb0,rb1, relaxation); - addFrictionConstraint(frictionDir2,solverBodyIdA,solverBodyIdB,frictionIndex,cp,rel_pos1,rel_pos2,rb0,rb1, relaxation); - } - - } - } - } - } - } - } - END_PROFILE("gatherSolverData"); - - BEGIN_PROFILE("prepareConstraints"); - - btContactSolverInfo info = infoGlobal; - - { - int j; - for (j=0;jbuildJacobian(); - } - } - - - - int numConstraintPool = m_tmpSolverConstraintPool.size(); - int numFrictionPool = m_tmpSolverFrictionConstraintPool.size(); - - ///todo: use stack allocator for such temporarily memory, same for solver bodies/constraints - m_orderTmpConstraintPool.resize(numConstraintPool); - m_orderFrictionConstraintPool.resize(numFrictionPool); - { - int i; - for (i=0;igetRigidBodyA().getIslandTag() >= 0) && (constraint->getRigidBodyA().getCompanionId() >= 0)) - { - m_tmpSolverBodyPool[constraint->getRigidBodyA().getCompanionId()].writebackVelocity(); - } - if ((constraint->getRigidBodyB().getIslandTag() >= 0) && (constraint->getRigidBodyB().getCompanionId() >= 0)) - { - m_tmpSolverBodyPool[constraint->getRigidBodyB().getCompanionId()].writebackVelocity(); - } - - constraint->solveConstraint(infoGlobal.m_timeStep); - - if ((constraint->getRigidBodyA().getIslandTag() >= 0) && (constraint->getRigidBodyA().getCompanionId() >= 0)) - { - m_tmpSolverBodyPool[constraint->getRigidBodyA().getCompanionId()].readVelocity(); - } - if ((constraint->getRigidBodyB().getIslandTag() >= 0) && (constraint->getRigidBodyB().getCompanionId() >= 0)) - { - m_tmpSolverBodyPool[constraint->getRigidBodyB().getCompanionId()].readVelocity(); - } - - } - - { - int numPoolConstraints = m_tmpSolverConstraintPool.size(); - for (j=0;jgetNumContacts();p++) - { - gOrder[totalPoints].m_manifoldIndex = j; - gOrder[totalPoints].m_pointIndex = p; - totalPoints++; - } - } - } - - { - int j; - for (j=0;jbuildJacobian(); - } - } - - END_PROFILE("prepareConstraints"); - - - BEGIN_PROFILE("solveConstraints"); - - //should traverse the contacts random order... - int iteration; - - { - for ( iteration = 0;iterationsolveConstraint(info.m_timeStep); - } - - for (j=0;jgetBody0(), - (btRigidBody*)manifold->getBody1() - ,manifold->getContactPoint(gOrder[j].m_pointIndex),info,iteration,debugDrawer); - } - - for (j=0;jgetBody0(), - (btRigidBody*)manifold->getBody1(),manifold->getContactPoint(gOrder[j].m_pointIndex),info,iteration,debugDrawer); - } - - } - } - - END_PROFILE("solveConstraints"); - - -#ifdef USE_PROFILE - btProfiler::endBlock("solve"); -#endif //USE_PROFILE - - - - - return btScalar(0.); -} - - - - - - - -void btSequentialImpulseConstraintSolver::prepareConstraints(btPersistentManifold* manifoldPtr, const btContactSolverInfo& info,btIDebugDraw* debugDrawer) -{ - - (void)debugDrawer; - - btRigidBody* body0 = (btRigidBody*)manifoldPtr->getBody0(); - btRigidBody* body1 = (btRigidBody*)manifoldPtr->getBody1(); - - - //only necessary to refresh the manifold once (first iteration). The integration is done outside the loop - { -#ifdef FORCE_REFESH_CONTACT_MANIFOLDS - manifoldPtr->refreshContactPoints(body0->getCenterOfMassTransform(),body1->getCenterOfMassTransform()); -#endif //FORCE_REFESH_CONTACT_MANIFOLDS - int numpoints = manifoldPtr->getNumContacts(); - - gTotalContactPoints += numpoints; - - btVector3 color(0,1,0); - for (int i=0;igetContactPoint(i); - if (cp.getDistance() <= btScalar(0.)) - { - const btVector3& pos1 = cp.getPositionWorldOnA(); - const btVector3& pos2 = cp.getPositionWorldOnB(); - - btVector3 rel_pos1 = pos1 - body0->getCenterOfMassPosition(); - btVector3 rel_pos2 = pos2 - body1->getCenterOfMassPosition(); - - - //this jacobian entry is re-used for all iterations - btJacobianEntry jac(body0->getCenterOfMassTransform().getBasis().transpose(), - body1->getCenterOfMassTransform().getBasis().transpose(), - rel_pos1,rel_pos2,cp.m_normalWorldOnB,body0->getInvInertiaDiagLocal(),body0->getInvMass(), - body1->getInvInertiaDiagLocal(),body1->getInvMass()); - - - btScalar jacDiagAB = jac.getDiagonal(); - - btConstraintPersistentData* cpd = (btConstraintPersistentData*) cp.m_userPersistentData; - if (cpd) - { - //might be invalid - cpd->m_persistentLifeTime++; - if (cpd->m_persistentLifeTime != cp.getLifeTime()) - { - //printf("Invalid: cpd->m_persistentLifeTime = %i cp.getLifeTime() = %i\n",cpd->m_persistentLifeTime,cp.getLifeTime()); - new (cpd) btConstraintPersistentData; - cpd->m_persistentLifeTime = cp.getLifeTime(); - - } else - { - //printf("Persistent: cpd->m_persistentLifeTime = %i cp.getLifeTime() = %i\n",cpd->m_persistentLifeTime,cp.getLifeTime()); - - } - } else - { - - //todo: should this be in a pool? - void* mem = btAlignedAlloc(sizeof(btConstraintPersistentData),16); - cpd = new (mem)btConstraintPersistentData; - assert(cpd); - - totalCpd ++; - //printf("totalCpd = %i Created Ptr %x\n",totalCpd,cpd); - cp.m_userPersistentData = cpd; - cpd->m_persistentLifeTime = cp.getLifeTime(); - //printf("CREATED: %x . cpd->m_persistentLifeTime = %i cp.getLifeTime() = %i\n",cpd,cpd->m_persistentLifeTime,cp.getLifeTime()); - - } - assert(cpd); - - cpd->m_jacDiagABInv = btScalar(1.) / jacDiagAB; - - //Dependent on Rigidbody A and B types, fetch the contact/friction response func - //perhaps do a similar thing for friction/restutution combiner funcs... - - cpd->m_frictionSolverFunc = m_frictionDispatch[body0->m_frictionSolverType][body1->m_frictionSolverType]; - cpd->m_contactSolverFunc = m_contactDispatch[body0->m_contactSolverType][body1->m_contactSolverType]; - - btVector3 vel1 = body0->getVelocityInLocalPoint(rel_pos1); - btVector3 vel2 = body1->getVelocityInLocalPoint(rel_pos2); - btVector3 vel = vel1 - vel2; - btScalar rel_vel; - rel_vel = cp.m_normalWorldOnB.dot(vel); - - btScalar combinedRestitution = cp.m_combinedRestitution; - - cpd->m_penetration = cp.getDistance();///btScalar(info.m_numIterations); - cpd->m_friction = cp.m_combinedFriction; - cpd->m_restitution = restitutionCurve(rel_vel, combinedRestitution); - if (cpd->m_restitution <= btScalar(0.)) - { - cpd->m_restitution = btScalar(0.0); - - }; - - //restitution and penetration work in same direction so - //rel_vel - - btScalar penVel = -cpd->m_penetration/info.m_timeStep; - - if (cpd->m_restitution > penVel) - { - cpd->m_penetration = btScalar(0.); - } - - - btScalar relaxation = info.m_damping; - if (m_solverMode & SOLVER_USE_WARMSTARTING) - { - cpd->m_appliedImpulse *= relaxation; - } else - { - cpd->m_appliedImpulse =btScalar(0.); - } - - //for friction - cpd->m_prevAppliedImpulse = cpd->m_appliedImpulse; - - //re-calculate friction direction every frame, todo: check if this is really needed - btPlaneSpace1(cp.m_normalWorldOnB,cpd->m_frictionWorldTangential0,cpd->m_frictionWorldTangential1); - - -#define NO_FRICTION_WARMSTART 1 - - #ifdef NO_FRICTION_WARMSTART - cpd->m_accumulatedTangentImpulse0 = btScalar(0.); - cpd->m_accumulatedTangentImpulse1 = btScalar(0.); - #endif //NO_FRICTION_WARMSTART - btScalar denom0 = body0->computeImpulseDenominator(pos1,cpd->m_frictionWorldTangential0); - btScalar denom1 = body1->computeImpulseDenominator(pos2,cpd->m_frictionWorldTangential0); - btScalar denom = relaxation/(denom0+denom1); - cpd->m_jacDiagABInvTangent0 = denom; - - - denom0 = body0->computeImpulseDenominator(pos1,cpd->m_frictionWorldTangential1); - denom1 = body1->computeImpulseDenominator(pos2,cpd->m_frictionWorldTangential1); - denom = relaxation/(denom0+denom1); - cpd->m_jacDiagABInvTangent1 = denom; - - btVector3 totalImpulse = - #ifndef NO_FRICTION_WARMSTART - cpd->m_frictionWorldTangential0*cpd->m_accumulatedTangentImpulse0+ - cpd->m_frictionWorldTangential1*cpd->m_accumulatedTangentImpulse1+ - #endif //NO_FRICTION_WARMSTART - cp.m_normalWorldOnB*cpd->m_appliedImpulse; - - - - /// - { - btVector3 torqueAxis0 = rel_pos1.cross(cp.m_normalWorldOnB); - cpd->m_angularComponentA = body0->getInvInertiaTensorWorld()*torqueAxis0; - btVector3 torqueAxis1 = rel_pos2.cross(cp.m_normalWorldOnB); - cpd->m_angularComponentB = body1->getInvInertiaTensorWorld()*torqueAxis1; - } - { - btVector3 ftorqueAxis0 = rel_pos1.cross(cpd->m_frictionWorldTangential0); - cpd->m_frictionAngularComponent0A = body0->getInvInertiaTensorWorld()*ftorqueAxis0; - } - { - btVector3 ftorqueAxis1 = rel_pos1.cross(cpd->m_frictionWorldTangential1); - cpd->m_frictionAngularComponent1A = body0->getInvInertiaTensorWorld()*ftorqueAxis1; - } - { - btVector3 ftorqueAxis0 = rel_pos2.cross(cpd->m_frictionWorldTangential0); - cpd->m_frictionAngularComponent0B = body1->getInvInertiaTensorWorld()*ftorqueAxis0; - } - { - btVector3 ftorqueAxis1 = rel_pos2.cross(cpd->m_frictionWorldTangential1); - cpd->m_frictionAngularComponent1B = body1->getInvInertiaTensorWorld()*ftorqueAxis1; - } - - /// - - - - //apply previous frames impulse on both bodies - body0->applyImpulse(totalImpulse, rel_pos1); - body1->applyImpulse(-totalImpulse, rel_pos2); - } - - } - } -} - - -btScalar btSequentialImpulseConstraintSolver::solveCombinedContactFriction(btRigidBody* body0,btRigidBody* body1, btManifoldPoint& cp, const btContactSolverInfo& info,int iter,btIDebugDraw* debugDrawer) -{ - btScalar maxImpulse = btScalar(0.); - - { - - btVector3 color(0,1,0); - { - if (cp.getDistance() <= btScalar(0.)) - { - - if (iter == 0) - { - if (debugDrawer) - debugDrawer->drawContactPoint(cp.m_positionWorldOnB,cp.m_normalWorldOnB,cp.getDistance(),cp.getLifeTime(),color); - } - - { - - //btConstraintPersistentData* cpd = (btConstraintPersistentData*) cp.m_userPersistentData; - btScalar impulse = resolveSingleCollisionCombined( - *body0,*body1, - cp, - info); - - if (maxImpulse < impulse) - maxImpulse = impulse; - - } - } - } - } - return maxImpulse; -} - - - -btScalar btSequentialImpulseConstraintSolver::solve(btRigidBody* body0,btRigidBody* body1, btManifoldPoint& cp, const btContactSolverInfo& info,int iter,btIDebugDraw* debugDrawer) -{ - - btScalar maxImpulse = btScalar(0.); - - { - - btVector3 color(0,1,0); - { - if (cp.getDistance() <= btScalar(0.)) - { - - if (iter == 0) - { - if (debugDrawer) - debugDrawer->drawContactPoint(cp.m_positionWorldOnB,cp.m_normalWorldOnB,cp.getDistance(),cp.getLifeTime(),color); - } - - { - - btConstraintPersistentData* cpd = (btConstraintPersistentData*) cp.m_userPersistentData; - btScalar impulse = cpd->m_contactSolverFunc( - *body0,*body1, - cp, - info); - - if (maxImpulse < impulse) - maxImpulse = impulse; - - } - } - } - } - return maxImpulse; -} - -btScalar btSequentialImpulseConstraintSolver::solveFriction(btRigidBody* body0,btRigidBody* body1, btManifoldPoint& cp, const btContactSolverInfo& info,int iter,btIDebugDraw* debugDrawer) -{ - - (void)debugDrawer; - (void)iter; - - - { - - btVector3 color(0,1,0); - { - - if (cp.getDistance() <= btScalar(0.)) - { - - btConstraintPersistentData* cpd = (btConstraintPersistentData*) cp.m_userPersistentData; - cpd->m_frictionSolverFunc( - *body0,*body1, - cp, - info); - - - } - } - - - } - return btScalar(0.); -} - - -void btSequentialImpulseConstraintSolver::reset() -{ - m_btSeed2 = 0; -} - diff --git a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.h b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.h deleted file mode 100644 index 83a96d4dc44..00000000000 --- a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.h +++ /dev/null @@ -1,126 +0,0 @@ -/* -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 SEQUENTIAL_IMPULSE_CONSTRAINT_SOLVER_H -#define SEQUENTIAL_IMPULSE_CONSTRAINT_SOLVER_H - -#include "btConstraintSolver.h" -class btIDebugDraw; -#include "btContactConstraint.h" -#include "btSolverBody.h" -#include "btSolverConstraint.h" - - -/// btSequentialImpulseConstraintSolver uses a Propagation Method and Sequentially applies impulses -/// The approach is the 3D version of Erin Catto's GDC 2006 tutorial. See http://www.gphysics.com -/// Although Sequential Impulse is more intuitive, it is mathematically equivalent to Projected Successive Overrelaxation (iterative LCP) -/// Applies impulses for combined restitution and penetration recovery and to simulate friction -class btSequentialImpulseConstraintSolver : public btConstraintSolver -{ - - btAlignedObjectArray m_tmpSolverBodyPool; - btAlignedObjectArray m_tmpSolverConstraintPool; - btAlignedObjectArray m_tmpSolverFrictionConstraintPool; - btAlignedObjectArray m_orderTmpConstraintPool; - btAlignedObjectArray m_orderFrictionConstraintPool; - - -protected: - btScalar solve(btRigidBody* body0,btRigidBody* body1, btManifoldPoint& cp, const btContactSolverInfo& info,int iter,btIDebugDraw* debugDrawer); - btScalar solveFriction(btRigidBody* body0,btRigidBody* body1, btManifoldPoint& cp, const btContactSolverInfo& info,int iter,btIDebugDraw* debugDrawer); - void prepareConstraints(btPersistentManifold* manifoldPtr, const btContactSolverInfo& info,btIDebugDraw* debugDrawer); - void addFrictionConstraint(const btVector3& normalAxis,int solverBodyIdA,int solverBodyIdB,int frictionIndex,btManifoldPoint& cp,const btVector3& rel_pos1,const btVector3& rel_pos2,btRigidBody* rb0,btRigidBody* rb1, btScalar relaxation); - - ContactSolverFunc m_contactDispatch[MAX_CONTACT_SOLVER_TYPES][MAX_CONTACT_SOLVER_TYPES]; - ContactSolverFunc m_frictionDispatch[MAX_CONTACT_SOLVER_TYPES][MAX_CONTACT_SOLVER_TYPES]; - - //choose between several modes, different friction model etc. - int m_solverMode; - ///m_btSeed2 is used for re-arranging the constraint rows. improves convergence/quality of friction - unsigned long m_btSeed2; - -public: - - enum eSolverMode - { - SOLVER_RANDMIZE_ORDER = 1, - SOLVER_FRICTION_SEPARATE = 2, - SOLVER_USE_WARMSTARTING = 4, - SOLVER_CACHE_FRIENDLY = 8 - }; - - btSequentialImpulseConstraintSolver(); - - ///Advanced: Override the default contact solving function for contacts, for certain types of rigidbody - ///See btRigidBody::m_contactSolverType and btRigidBody::m_frictionSolverType - void setContactSolverFunc(ContactSolverFunc func,int type0,int type1) - { - m_contactDispatch[type0][type1] = func; - } - - ///Advanced: Override the default friction solving function for contacts, for certain types of rigidbody - ///See btRigidBody::m_contactSolverType and btRigidBody::m_frictionSolverType - void SetFrictionSolverFunc(ContactSolverFunc func,int type0,int type1) - { - m_frictionDispatch[type0][type1] = func; - } - - virtual ~btSequentialImpulseConstraintSolver(); - - virtual btScalar solveGroup(btCollisionObject** bodies,int numBodies,btPersistentManifold** manifold,int numManifolds,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& info, btIDebugDraw* debugDrawer, btStackAlloc* stackAlloc,btDispatcher* dispatcher); - - virtual btScalar solveGroupCacheFriendly(btCollisionObject** bodies,int numBodies,btPersistentManifold** manifoldPtr, int numManifolds,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& infoGlobal,btIDebugDraw* debugDrawer,btStackAlloc* stackAlloc); - btScalar solveGroupCacheFriendlyIterations(btCollisionObject** bodies,int numBodies,btPersistentManifold** manifoldPtr, int numManifolds,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& infoGlobal,btIDebugDraw* debugDrawer,btStackAlloc* stackAlloc); - btScalar solveGroupCacheFriendlySetup(btCollisionObject** bodies,int numBodies,btPersistentManifold** manifoldPtr, int numManifolds,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& infoGlobal,btIDebugDraw* debugDrawer,btStackAlloc* stackAlloc); - - - ///clear internal cached data and reset random seed - virtual void reset(); - - btScalar solveCombinedContactFriction(btRigidBody* body0,btRigidBody* body1, btManifoldPoint& cp, const btContactSolverInfo& info,int iter,btIDebugDraw* debugDrawer); - - - void setSolverMode(int mode) - { - m_solverMode = mode; - } - - int getSolverMode() const - { - return m_solverMode; - } - - unsigned long btRand2(); - - int btRandInt2 (int n); - - void setRandSeed(unsigned long seed) - { - m_btSeed2 = seed; - } - unsigned long getRandSeed() const - { - return m_btSeed2; - } - -}; - -#ifndef BT_PREFER_SIMD -typedef btSequentialImpulseConstraintSolver btSequentialImpulseConstraintSolverPrefered; -#endif - - -#endif //SEQUENTIAL_IMPULSE_CONSTRAINT_SOLVER_H - diff --git a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSolve2LinearConstraint.cpp b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSolve2LinearConstraint.cpp deleted file mode 100644 index 0c7dbd668bb..00000000000 --- a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSolve2LinearConstraint.cpp +++ /dev/null @@ -1,255 +0,0 @@ -/* -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 "btSolve2LinearConstraint.h" - -#include "BulletDynamics/Dynamics/btRigidBody.h" -#include "LinearMath/btVector3.h" -#include "btJacobianEntry.h" - - -void btSolve2LinearConstraint::resolveUnilateralPairConstraint( - btRigidBody* body1, - btRigidBody* body2, - - const btMatrix3x3& world2A, - const btMatrix3x3& world2B, - - const btVector3& invInertiaADiag, - const btScalar invMassA, - const btVector3& linvelA,const btVector3& angvelA, - const btVector3& rel_posA1, - const btVector3& invInertiaBDiag, - const btScalar invMassB, - const btVector3& linvelB,const btVector3& angvelB, - const btVector3& rel_posA2, - - btScalar depthA, const btVector3& normalA, - const btVector3& rel_posB1,const btVector3& rel_posB2, - btScalar depthB, const btVector3& normalB, - btScalar& imp0,btScalar& imp1) -{ - (void)linvelA; - (void)linvelB; - (void)angvelB; - (void)angvelA; - - - - imp0 = btScalar(0.); - imp1 = btScalar(0.); - - btScalar len = btFabs(normalA.length()) - btScalar(1.); - if (btFabs(len) >= SIMD_EPSILON) - return; - - btAssert(len < SIMD_EPSILON); - - - //this jacobian entry could be re-used for all iterations - btJacobianEntry jacA(world2A,world2B,rel_posA1,rel_posA2,normalA,invInertiaADiag,invMassA, - invInertiaBDiag,invMassB); - btJacobianEntry jacB(world2A,world2B,rel_posB1,rel_posB2,normalB,invInertiaADiag,invMassA, - invInertiaBDiag,invMassB); - - //const btScalar vel0 = jacA.getRelativeVelocity(linvelA,angvelA,linvelB,angvelB); - //const btScalar vel1 = jacB.getRelativeVelocity(linvelA,angvelA,linvelB,angvelB); - - const btScalar vel0 = normalA.dot(body1->getVelocityInLocalPoint(rel_posA1)-body2->getVelocityInLocalPoint(rel_posA1)); - const btScalar vel1 = normalB.dot(body1->getVelocityInLocalPoint(rel_posB1)-body2->getVelocityInLocalPoint(rel_posB1)); - -// btScalar penetrationImpulse = (depth*contactTau*timeCorrection) * massTerm;//jacDiagABInv - btScalar massTerm = btScalar(1.) / (invMassA + invMassB); - - - // calculate rhs (or error) terms - const btScalar dv0 = depthA * m_tau * massTerm - vel0 * m_damping; - const btScalar dv1 = depthB * m_tau * massTerm - vel1 * m_damping; - - - // dC/dv * dv = -C - - // jacobian * impulse = -error - // - - //impulse = jacobianInverse * -error - - // inverting 2x2 symmetric system (offdiagonal are equal!) - // - - - btScalar nonDiag = jacA.getNonDiagonal(jacB,invMassA,invMassB); - btScalar invDet = btScalar(1.0) / (jacA.getDiagonal() * jacB.getDiagonal() - nonDiag * nonDiag ); - - //imp0 = dv0 * jacA.getDiagonal() * invDet + dv1 * -nonDiag * invDet; - //imp1 = dv1 * jacB.getDiagonal() * invDet + dv0 * - nonDiag * invDet; - - imp0 = dv0 * jacA.getDiagonal() * invDet + dv1 * -nonDiag * invDet; - imp1 = dv1 * jacB.getDiagonal() * invDet + dv0 * - nonDiag * invDet; - - //[a b] [d -c] - //[c d] inverse = (1 / determinant) * [-b a] where determinant is (ad - bc) - - //[jA nD] * [imp0] = [dv0] - //[nD jB] [imp1] [dv1] - -} - - - -void btSolve2LinearConstraint::resolveBilateralPairConstraint( - btRigidBody* body1, - btRigidBody* body2, - const btMatrix3x3& world2A, - const btMatrix3x3& world2B, - - const btVector3& invInertiaADiag, - const btScalar invMassA, - const btVector3& linvelA,const btVector3& angvelA, - const btVector3& rel_posA1, - const btVector3& invInertiaBDiag, - const btScalar invMassB, - const btVector3& linvelB,const btVector3& angvelB, - const btVector3& rel_posA2, - - btScalar depthA, const btVector3& normalA, - const btVector3& rel_posB1,const btVector3& rel_posB2, - btScalar depthB, const btVector3& normalB, - btScalar& imp0,btScalar& imp1) -{ - - (void)linvelA; - (void)linvelB; - (void)angvelA; - (void)angvelB; - - - - imp0 = btScalar(0.); - imp1 = btScalar(0.); - - btScalar len = btFabs(normalA.length()) - btScalar(1.); - if (btFabs(len) >= SIMD_EPSILON) - return; - - btAssert(len < SIMD_EPSILON); - - - //this jacobian entry could be re-used for all iterations - btJacobianEntry jacA(world2A,world2B,rel_posA1,rel_posA2,normalA,invInertiaADiag,invMassA, - invInertiaBDiag,invMassB); - btJacobianEntry jacB(world2A,world2B,rel_posB1,rel_posB2,normalB,invInertiaADiag,invMassA, - invInertiaBDiag,invMassB); - - //const btScalar vel0 = jacA.getRelativeVelocity(linvelA,angvelA,linvelB,angvelB); - //const btScalar vel1 = jacB.getRelativeVelocity(linvelA,angvelA,linvelB,angvelB); - - const btScalar vel0 = normalA.dot(body1->getVelocityInLocalPoint(rel_posA1)-body2->getVelocityInLocalPoint(rel_posA1)); - const btScalar vel1 = normalB.dot(body1->getVelocityInLocalPoint(rel_posB1)-body2->getVelocityInLocalPoint(rel_posB1)); - - // calculate rhs (or error) terms - const btScalar dv0 = depthA * m_tau - vel0 * m_damping; - const btScalar dv1 = depthB * m_tau - vel1 * m_damping; - - // dC/dv * dv = -C - - // jacobian * impulse = -error - // - - //impulse = jacobianInverse * -error - - // inverting 2x2 symmetric system (offdiagonal are equal!) - // - - - btScalar nonDiag = jacA.getNonDiagonal(jacB,invMassA,invMassB); - btScalar invDet = btScalar(1.0) / (jacA.getDiagonal() * jacB.getDiagonal() - nonDiag * nonDiag ); - - //imp0 = dv0 * jacA.getDiagonal() * invDet + dv1 * -nonDiag * invDet; - //imp1 = dv1 * jacB.getDiagonal() * invDet + dv0 * - nonDiag * invDet; - - imp0 = dv0 * jacA.getDiagonal() * invDet + dv1 * -nonDiag * invDet; - imp1 = dv1 * jacB.getDiagonal() * invDet + dv0 * - nonDiag * invDet; - - //[a b] [d -c] - //[c d] inverse = (1 / determinant) * [-b a] where determinant is (ad - bc) - - //[jA nD] * [imp0] = [dv0] - //[nD jB] [imp1] [dv1] - - if ( imp0 > btScalar(0.0)) - { - if ( imp1 > btScalar(0.0) ) - { - //both positive - } - else - { - imp1 = btScalar(0.); - - // now imp0>0 imp1<0 - imp0 = dv0 / jacA.getDiagonal(); - if ( imp0 > btScalar(0.0) ) - { - } else - { - imp0 = btScalar(0.); - } - } - } - else - { - imp0 = btScalar(0.); - - imp1 = dv1 / jacB.getDiagonal(); - if ( imp1 <= btScalar(0.0) ) - { - imp1 = btScalar(0.); - // now imp0>0 imp1<0 - imp0 = dv0 / jacA.getDiagonal(); - if ( imp0 > btScalar(0.0) ) - { - } else - { - imp0 = btScalar(0.); - } - } else - { - } - } -} - - -/* -void btSolve2LinearConstraint::resolveAngularConstraint( const btMatrix3x3& invInertiaAWS, - const btScalar invMassA, - const btVector3& linvelA,const btVector3& angvelA, - const btVector3& rel_posA1, - const btMatrix3x3& invInertiaBWS, - const btScalar invMassB, - const btVector3& linvelB,const btVector3& angvelB, - const btVector3& rel_posA2, - - btScalar depthA, const btVector3& normalA, - const btVector3& rel_posB1,const btVector3& rel_posB2, - btScalar depthB, const btVector3& normalB, - btScalar& imp0,btScalar& imp1) -{ - -} -*/ - diff --git a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSolve2LinearConstraint.h b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSolve2LinearConstraint.h deleted file mode 100644 index 057d3fac827..00000000000 --- a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSolve2LinearConstraint.h +++ /dev/null @@ -1,107 +0,0 @@ -/* -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 SOLVE_2LINEAR_CONSTRAINT_H -#define SOLVE_2LINEAR_CONSTRAINT_H - -#include "LinearMath/btMatrix3x3.h" -#include "LinearMath/btVector3.h" - - -class btRigidBody; - - - -/// constraint class used for lateral tyre friction. -class btSolve2LinearConstraint -{ - btScalar m_tau; - btScalar m_damping; - -public: - - btSolve2LinearConstraint(btScalar tau,btScalar damping) - { - m_tau = tau; - m_damping = damping; - } - // - // solve unilateral constraint (equality, direct method) - // - void resolveUnilateralPairConstraint( - btRigidBody* body0, - btRigidBody* body1, - - const btMatrix3x3& world2A, - const btMatrix3x3& world2B, - - const btVector3& invInertiaADiag, - const btScalar invMassA, - const btVector3& linvelA,const btVector3& angvelA, - const btVector3& rel_posA1, - const btVector3& invInertiaBDiag, - const btScalar invMassB, - const btVector3& linvelB,const btVector3& angvelB, - const btVector3& rel_posA2, - - btScalar depthA, const btVector3& normalA, - const btVector3& rel_posB1,const btVector3& rel_posB2, - btScalar depthB, const btVector3& normalB, - btScalar& imp0,btScalar& imp1); - - - // - // solving 2x2 lcp problem (inequality, direct solution ) - // - void resolveBilateralPairConstraint( - btRigidBody* body0, - btRigidBody* body1, - const btMatrix3x3& world2A, - const btMatrix3x3& world2B, - - const btVector3& invInertiaADiag, - const btScalar invMassA, - const btVector3& linvelA,const btVector3& angvelA, - const btVector3& rel_posA1, - const btVector3& invInertiaBDiag, - const btScalar invMassB, - const btVector3& linvelB,const btVector3& angvelB, - const btVector3& rel_posA2, - - btScalar depthA, const btVector3& normalA, - const btVector3& rel_posB1,const btVector3& rel_posB2, - btScalar depthB, const btVector3& normalB, - btScalar& imp0,btScalar& imp1); - -/* - void resolveAngularConstraint( const btMatrix3x3& invInertiaAWS, - const btScalar invMassA, - const btVector3& linvelA,const btVector3& angvelA, - const btVector3& rel_posA1, - const btMatrix3x3& invInertiaBWS, - const btScalar invMassB, - const btVector3& linvelB,const btVector3& angvelB, - const btVector3& rel_posA2, - - btScalar depthA, const btVector3& normalA, - const btVector3& rel_posB1,const btVector3& rel_posB2, - btScalar depthB, const btVector3& normalB, - btScalar& imp0,btScalar& imp1); - -*/ - -}; - -#endif //SOLVE_2LINEAR_CONSTRAINT_H diff --git a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSolverBody.h b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSolverBody.h deleted file mode 100644 index 21305b3164e..00000000000 --- a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSolverBody.h +++ /dev/null @@ -1,76 +0,0 @@ -/* -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 BT_SOLVER_BODY_H -#define BT_SOLVER_BODY_H - -class btRigidBody; -#include "LinearMath/btVector3.h" -#include "LinearMath/btMatrix3x3.h" -#include "BulletDynamics/Dynamics/btRigidBody.h" -#include "LinearMath/btAlignedAllocator.h" - - -///btSolverBody is an internal datastructure for the constraint solver. Only necessary data is packed to increase cache coherence/performance. -ATTRIBUTE_ALIGNED16 (struct) btSolverBody -{ - BT_DECLARE_ALIGNED_ALLOCATOR(); - - btVector3 m_angularVelocity; - float m_angularFactor; - float m_invMass; - float m_friction; - btRigidBody* m_originalBody; - btVector3 m_linearVelocity; - btVector3 m_centerOfMassPosition; - - SIMD_FORCE_INLINE void getVelocityInLocalPoint(const btVector3& rel_pos, btVector3& velocity ) const - { - velocity = m_linearVelocity + m_angularVelocity.cross(rel_pos); - } - - //Optimization for the iterative solver: avoid calculating constant terms involving inertia, normal, relative position - SIMD_FORCE_INLINE void internalApplyImpulse(const btVector3& linearComponent, const btVector3& angularComponent,btScalar impulseMagnitude) - { - m_linearVelocity += linearComponent*impulseMagnitude; - m_angularVelocity += angularComponent*(impulseMagnitude*m_angularFactor); - } - - void writebackVelocity() - { - if (m_invMass) - { - m_originalBody->setLinearVelocity(m_linearVelocity); - m_originalBody->setAngularVelocity(m_angularVelocity); - //m_originalBody->setCompanionId(-1); - } - } - - void readVelocity() - { - if (m_invMass) - { - m_linearVelocity = m_originalBody->getLinearVelocity(); - m_angularVelocity = m_originalBody->getAngularVelocity(); - } - } - - - - -}; - -#endif //BT_SOLVER_BODY_H - diff --git a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSolverConstraint.h b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSolverConstraint.h deleted file mode 100644 index a750560d33c..00000000000 --- a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSolverConstraint.h +++ /dev/null @@ -1,69 +0,0 @@ - - -/* -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 BT_SOLVER_CONSTRAINT_H -#define BT_SOLVER_CONSTRAINT_H - -class btRigidBody; -#include "LinearMath/btVector3.h" -#include "LinearMath/btMatrix3x3.h" - -//#define NO_FRICTION_TANGENTIALS 1 - -///1D constraint along a normal axis between bodyA and bodyB. It can be combined to solve contact and friction constraints. -ATTRIBUTE_ALIGNED16 (struct) btSolverConstraint -{ - BT_DECLARE_ALIGNED_ALLOCATOR(); - - btVector3 m_relpos1CrossNormal; - btVector3 m_contactNormal; - - btVector3 m_relpos2CrossNormal; - btVector3 m_angularComponentA; - - btVector3 m_angularComponentB; - mutable btScalar m_appliedVelocityImpulse; - mutable btScalar m_appliedImpulse; - int m_solverBodyIdA; - int m_solverBodyIdB; - - btScalar m_friction; - btScalar m_restitution; - btScalar m_jacDiagABInv; - btScalar m_penetration; - - - - int m_constraintType; - int m_frictionIndex; - int m_unusedPadding[2]; - - enum btSolverConstraintType - { - BT_SOLVER_CONTACT_1D = 0, - BT_SOLVER_FRICTION_1D - }; -}; - - - - - - -#endif //BT_SOLVER_CONSTRAINT_H - - diff --git a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btTypedConstraint.cpp b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btTypedConstraint.cpp deleted file mode 100644 index 6e8b552dbbc..00000000000 --- a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btTypedConstraint.cpp +++ /dev/null @@ -1,56 +0,0 @@ -/* -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 "btTypedConstraint.h" -#include "BulletDynamics/Dynamics/btRigidBody.h" - -static btRigidBody s_fixed(0, 0,0); - -btTypedConstraint::btTypedConstraint(btTypedConstraintType type) -:m_userConstraintType(-1), -m_userConstraintId(-1), -m_constraintType (type), -m_rbA(s_fixed), -m_rbB(s_fixed), -m_appliedImpulse(btScalar(0.)) -{ - s_fixed.setMassProps(btScalar(0.),btVector3(btScalar(0.),btScalar(0.),btScalar(0.))); -} -btTypedConstraint::btTypedConstraint(btTypedConstraintType type, btRigidBody& rbA) -:m_userConstraintType(-1), -m_userConstraintId(-1), -m_constraintType (type), -m_rbA(rbA), -m_rbB(s_fixed), -m_appliedImpulse(btScalar(0.)) -{ - s_fixed.setMassProps(btScalar(0.),btVector3(btScalar(0.),btScalar(0.),btScalar(0.))); - -} - - -btTypedConstraint::btTypedConstraint(btTypedConstraintType type, btRigidBody& rbA,btRigidBody& rbB) -:m_userConstraintType(-1), -m_userConstraintId(-1), -m_constraintType (type), -m_rbA(rbA), -m_rbB(rbB), -m_appliedImpulse(btScalar(0.)) -{ - s_fixed.setMassProps(btScalar(0.),btVector3(btScalar(0.),btScalar(0.),btScalar(0.))); - -} - diff --git a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btTypedConstraint.h b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btTypedConstraint.h deleted file mode 100644 index 745d0afde6d..00000000000 --- a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btTypedConstraint.h +++ /dev/null @@ -1,112 +0,0 @@ -/* -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 TYPED_CONSTRAINT_H -#define TYPED_CONSTRAINT_H - -class btRigidBody; -#include "LinearMath/btScalar.h" - -enum btTypedConstraintType -{ - POINT2POINT_CONSTRAINT_TYPE, - HINGE_CONSTRAINT_TYPE, - CONETWIST_CONSTRAINT_TYPE, - D6_CONSTRAINT_TYPE, - VEHICLE_CONSTRAINT_TYPE -}; - -///TypedConstraint is the baseclass for Bullet constraints and vehicles -class btTypedConstraint -{ - int m_userConstraintType; - int m_userConstraintId; - - btTypedConstraintType m_constraintType; - - btTypedConstraint& operator=(btTypedConstraint& other) - { - btAssert(0); - (void) other; - return *this; - } - -protected: - btRigidBody& m_rbA; - btRigidBody& m_rbB; - btScalar m_appliedImpulse; - - -public: - - btTypedConstraint(btTypedConstraintType type); - virtual ~btTypedConstraint() {}; - btTypedConstraint(btTypedConstraintType type, btRigidBody& rbA); - - btTypedConstraint(btTypedConstraintType type, btRigidBody& rbA,btRigidBody& rbB); - - virtual void buildJacobian() = 0; - - virtual void solveConstraint(btScalar timeStep) = 0; - - const btRigidBody& getRigidBodyA() const - { - return m_rbA; - } - const btRigidBody& getRigidBodyB() const - { - return m_rbB; - } - - btRigidBody& getRigidBodyA() - { - return m_rbA; - } - btRigidBody& getRigidBodyB() - { - return m_rbB; - } - - int getUserConstraintType() const - { - return m_userConstraintType ; - } - - void setUserConstraintType(int userConstraintType) - { - m_userConstraintType = userConstraintType; - }; - - void setUserConstraintId(int uid) - { - m_userConstraintId = uid; - } - - int getUserConstraintId() const - { - return m_userConstraintId; - } - btScalar getAppliedImpulse() const - { - return m_appliedImpulse; - } - - btTypedConstraintType getConstraintType () const - { - return m_constraintType; - } -}; - -#endif //TYPED_CONSTRAINT_H diff --git a/extern/bullet2/src/BulletDynamics/Dynamics/Bullet-C-API.cpp b/extern/bullet2/src/BulletDynamics/Dynamics/Bullet-C-API.cpp deleted file mode 100644 index 248c582dcd8..00000000000 --- a/extern/bullet2/src/BulletDynamics/Dynamics/Bullet-C-API.cpp +++ /dev/null @@ -1,120 +0,0 @@ -/* -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. -*/ - -/* - Draft high-level generic physics C-API. For low-level access, use the physics SDK native API's. - Work in progress, functionality will be added on demand. - - If possible, use the richer Bullet C++ API, by including -*/ - -#include "Bullet-C-Api.h" -#include "btBulletDynamicsCommon.h" -#include "LinearMath/btAlignedAllocator.h" - - -#include "LinearMath/btVector3.h" -#include "LinearMath/btScalar.h" -#include "LinearMath/btMatrix3x3.h" -#include "LinearMath/btTransform.h" -#include "BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.h" -#include "BulletCollision/CollisionShapes/btTriangleShape.h" - -#include "BulletCollision/NarrowPhaseCollision/btGjkPairDetector.h" -#include "BulletCollision/NarrowPhaseCollision/btPointCollector.h" -#include "BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.h" -#include "BulletCollision/NarrowPhaseCollision/btSubSimplexConvexCast.h" -#include "BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.h" -#include "BulletCollision/NarrowPhaseCollision/btGjkEpa.h" -#include "BulletCollision/CollisionShapes/btMinkowskiSumShape.h" -#include "BulletCollision/NarrowPhaseCollision/btSubSimplexConvexCast.h" -#include "BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.h" -#include "BulletCollision/NarrowPhaseCollision/btGjkPairDetector.h" - -#include "BulletCollision/NarrowPhaseCollision/btDiscreteCollisionDetectorInterface.h" -#include "BulletCollision/NarrowPhaseCollision/btSimplexSolverInterface.h" -#include "BulletCollision/NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.h" -#include "BulletCollision/NarrowPhaseCollision/btGjkPairDetector.h" -#include "BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.h" -#include "LinearMath/btStackAlloc.h" - -extern "C" -double plNearestPoints(float p1[3], float p2[3], float p3[3], float q1[3], float q2[3], float q3[3], float *pa, float *pb, float normal[3]) -{ - btVector3 vp(p1[0], p1[1], p1[2]); - btTriangleShape trishapeA(vp, - btVector3(p2[0], p2[1], p2[2]), - btVector3(p3[0], p3[1], p3[2])); - trishapeA.setMargin(0.000001f); - btVector3 vq(q1[0], q1[1], q1[2]); - btTriangleShape trishapeB(vq, - btVector3(q2[0], q2[1], q2[2]), - btVector3(q3[0], q3[1], q3[2])); - trishapeB.setMargin(0.000001f); - - // btVoronoiSimplexSolver sGjkSimplexSolver; - // btGjkEpaPenetrationDepthSolver penSolverPtr; - - static btSimplexSolverInterface sGjkSimplexSolver; - sGjkSimplexSolver.reset(); - - static btGjkEpaPenetrationDepthSolver Solver0; - static btMinkowskiPenetrationDepthSolver Solver1; - - btConvexPenetrationDepthSolver* Solver = NULL; - - Solver = &Solver1; - - btGjkPairDetector convexConvex(&trishapeA ,&trishapeB,&sGjkSimplexSolver,Solver); - - convexConvex.m_catchDegeneracies = 1; - - // btGjkPairDetector convexConvex(&trishapeA ,&trishapeB,&sGjkSimplexSolver,0); - - btPointCollector gjkOutput; - btGjkPairDetector::ClosestPointInput input; - - btStackAlloc gStackAlloc(1024*1024*2); - - input.m_stackAlloc = &gStackAlloc; - - btTransform tr; - tr.setIdentity(); - - input.m_transformA = tr; - input.m_transformB = tr; - - convexConvex.getClosestPoints(input, gjkOutput, 0); - - - if (gjkOutput.m_hasResult) - { - - pb[0] = pa[0] = gjkOutput.m_pointInWorld[0]; - pb[1] = pa[1] = gjkOutput.m_pointInWorld[1]; - pb[2] = pa[2] = gjkOutput.m_pointInWorld[2]; - - pb[0]+= gjkOutput.m_normalOnBInWorld[0] * gjkOutput.m_distance; - pb[1]+= gjkOutput.m_normalOnBInWorld[1] * gjkOutput.m_distance; - pb[2]+= gjkOutput.m_normalOnBInWorld[2] * gjkOutput.m_distance; - - normal[0] = gjkOutput.m_normalOnBInWorld[0]; - normal[1] = gjkOutput.m_normalOnBInWorld[1]; - normal[2] = gjkOutput.m_normalOnBInWorld[2]; - - return gjkOutput.m_distance; - } - return -1.0f; -} diff --git a/extern/bullet2/src/BulletDynamics/Dynamics/Bullet-C-Api.cpp b/extern/bullet2/src/BulletDynamics/Dynamics/Bullet-C-Api.cpp deleted file mode 100644 index 4051d3f3e1f..00000000000 --- a/extern/bullet2/src/BulletDynamics/Dynamics/Bullet-C-Api.cpp +++ /dev/null @@ -1,91 +0,0 @@ -#include "LinearMath/btVector3.h" -#include "LinearMath/btScalar.h" -#include "LinearMath/btMatrix3x3.h" -#include "LinearMath/btTransform.h" -#include "BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.h" -#include "BulletCollision/CollisionShapes/btTriangleShape.h" - -#include "BulletCollision/NarrowPhaseCollision/btGjkPairDetector.h" -#include "BulletCollision/NarrowPhaseCollision/btPointCollector.h" -#include "BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.h" -#include "BulletCollision/NarrowPhaseCollision/btSubSimplexConvexCast.h" -#include "BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.h" -#include "BulletCollision/NarrowPhaseCollision/btGjkEpa.h" -#include "BulletCollision/CollisionShapes/btMinkowskiSumShape.h" -#include "BulletCollision/NarrowPhaseCollision/btSubSimplexConvexCast.h" -#include "BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.h" -#include "BulletCollision/NarrowPhaseCollision/btGjkPairDetector.h" - -#include "BulletCollision/NarrowPhaseCollision/btDiscreteCollisionDetectorInterface.h" -#include "BulletCollision/NarrowPhaseCollision/btSimplexSolverInterface.h" -#include "BulletCollision/NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.h" -#include "BulletCollision/NarrowPhaseCollision/btGjkPairDetector.h" -#include "BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.h" -#include "LinearMath/btStackAlloc.h" - - -extern "C" -double plNearestPoints(float p1[3], float p2[3], float p3[3], float q1[3], float q2[3], float q3[3], float *pa, float *pb, float normal[3]) -{ - btTriangleShape trishapeA(btVector3(p1[0], p1[1], p1[2]), btVector3(p2[0], p2[1], p2[2]), btVector3(p3[0], p3[1], p3[2])); - trishapeA.setMargin(0.000001f); - - btTriangleShape trishapeB(btVector3(q1[0], q1[1], q1[2]), btVector3(q2[0], q2[1], q2[2]), btVector3(q3[0], q3[1], q3[2])); - trishapeB.setMargin(0.000001f); - - // btVoronoiSimplexSolver sGjkSimplexSolver; - // btGjkEpaPenetrationDepthSolver penSolverPtr; - - static btSimplexSolverInterface sGjkSimplexSolver; - sGjkSimplexSolver.reset(); - - static btGjkEpaPenetrationDepthSolver Solver0; - static btMinkowskiPenetrationDepthSolver Solver1; - - btConvexPenetrationDepthSolver* Solver = NULL; - - Solver = &Solver1; - - btGjkPairDetector convexConvex(&trishapeA ,&trishapeB,&sGjkSimplexSolver,Solver); - - convexConvex.m_catchDegeneracies = 1; - - // btGjkPairDetector convexConvex(&trishapeA ,&trishapeB,&sGjkSimplexSolver,0); - - btPointCollector gjkOutput; - btGjkPairDetector::ClosestPointInput input; - - btStackAlloc gStackAlloc(1024*1024*2); - - input.m_stackAlloc = &gStackAlloc; - - btTransform tr; - tr.setIdentity(); - - input.m_transformA = tr; - input.m_transformB = tr; - - convexConvex.getClosestPoints(input, gjkOutput, 0); - - - if (gjkOutput.m_hasResult) - { - - pb[0] = pa[0] = gjkOutput.m_pointInWorld[0]; - pb[1] = pa[1] = gjkOutput.m_pointInWorld[1]; - pb[2] = pa[2] = gjkOutput.m_pointInWorld[2]; - - pb[0]+= gjkOutput.m_normalOnBInWorld[0] * gjkOutput.m_distance; - pb[1]+= gjkOutput.m_normalOnBInWorld[1] * gjkOutput.m_distance; - pb[2]+= gjkOutput.m_normalOnBInWorld[2] * gjkOutput.m_distance; - - normal[0] = gjkOutput.m_normalOnBInWorld[0]; - normal[1] = gjkOutput.m_normalOnBInWorld[1]; - normal[2] = gjkOutput.m_normalOnBInWorld[2]; - - return gjkOutput.m_distance; - } - return -1.0f; -} - - diff --git a/extern/bullet2/src/BulletDynamics/Dynamics/btContinuousDynamicsWorld.cpp b/extern/bullet2/src/BulletDynamics/Dynamics/btContinuousDynamicsWorld.cpp deleted file mode 100644 index 5e330cb64f2..00000000000 --- a/extern/bullet2/src/BulletDynamics/Dynamics/btContinuousDynamicsWorld.cpp +++ /dev/null @@ -1,194 +0,0 @@ -/* -Bullet Continuous Collision Detection and Physics Library -Copyright (c) 2003-2007 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 "btContinuousDynamicsWorld.h" -#include "LinearMath/btQuickprof.h" - -//collision detection -#include "BulletCollision/CollisionDispatch/btCollisionDispatcher.h" -#include "BulletCollision/BroadphaseCollision/btSimpleBroadphase.h" -#include "BulletCollision/CollisionShapes/btCollisionShape.h" -#include "BulletCollision/CollisionDispatch/btSimulationIslandManager.h" - -//rigidbody & constraints -#include "BulletDynamics/Dynamics/btRigidBody.h" -#include "BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.h" -#include "BulletDynamics/ConstraintSolver/btContactSolverInfo.h" -#include "BulletDynamics/ConstraintSolver/btTypedConstraint.h" - - - -#include - -btContinuousDynamicsWorld::btContinuousDynamicsWorld(btDispatcher* dispatcher,btBroadphaseInterface* pairCache,btConstraintSolver* constraintSolver,btCollisionConfiguration* collisionConfiguration) -:btDiscreteDynamicsWorld(dispatcher,pairCache,constraintSolver,collisionConfiguration) -{ -} - -btContinuousDynamicsWorld::~btContinuousDynamicsWorld() -{ -} - - -void btContinuousDynamicsWorld::internalSingleStepSimulation( btScalar timeStep) -{ - - startProfiling(timeStep); - - ///update aabbs information - updateAabbs(); - //static int frame=0; -// printf("frame %d\n",frame++); - - ///apply gravity, predict motion - predictUnconstraintMotion(timeStep); - - btDispatcherInfo& dispatchInfo = getDispatchInfo(); - - dispatchInfo.m_timeStep = timeStep; - dispatchInfo.m_stepCount = 0; - dispatchInfo.m_debugDraw = getDebugDrawer(); - - ///perform collision detection - performDiscreteCollisionDetection(); - - calculateSimulationIslands(); - - - getSolverInfo().m_timeStep = timeStep; - - - - ///solve contact and other joint constraints - solveConstraints(getSolverInfo()); - - ///CallbackTriggers(); - - calculateTimeOfImpacts(timeStep); - - btScalar toi = dispatchInfo.m_timeOfImpact; -// if (toi < 1.f) -// printf("toi = %f\n",toi); - if (toi < 0.f) - printf("toi = %f\n",toi); - - - ///integrate transforms - integrateTransforms(timeStep * toi); - - ///update vehicle simulation - updateVehicles(timeStep); - - - updateActivationState( timeStep ); - -} - -void btContinuousDynamicsWorld::calculateTimeOfImpacts(btScalar timeStep) -{ - ///these should be 'temporal' aabbs! - updateTemporalAabbs(timeStep); - - ///'toi' is the global smallest time of impact. However, we just calculate the time of impact for each object individually. - ///so we handle the case moving versus static properly, and we cheat for moving versus moving - float toi = 1.f; - - - btDispatcherInfo& dispatchInfo = getDispatchInfo(); - dispatchInfo.m_timeStep = timeStep; - dispatchInfo.m_timeOfImpact = 1.f; - dispatchInfo.m_stepCount = 0; - dispatchInfo.m_dispatchFunc = btDispatcherInfo::DISPATCH_CONTINUOUS; - - ///calculate time of impact for overlapping pairs - - BEGIN_PROFILE("performContinuousCollisionDetection"); - - btDispatcher* dispatcher = getDispatcher(); - if (dispatcher) - dispatcher->dispatchAllCollisionPairs(m_broadphasePairCache->getOverlappingPairCache(),dispatchInfo,m_dispatcher1); - - END_PROFILE("performContinuousCollisionDetection"); - - toi = dispatchInfo.m_timeOfImpact; - - dispatchInfo.m_dispatchFunc = btDispatcherInfo::DISPATCH_DISCRETE; - -} - -void btContinuousDynamicsWorld::updateTemporalAabbs(btScalar timeStep) -{ - BEGIN_PROFILE("perform Temporal Broadphase Collision Detection"); - - btVector3 temporalAabbMin,temporalAabbMax; - - for ( int i=0;igetCollisionShape()->getAabb(m_collisionObjects[i]->getWorldTransform(),temporalAabbMin,temporalAabbMax); - const btVector3& linvel = body->getLinearVelocity(); - - //make the AABB temporal - float temporalAabbMaxx = temporalAabbMax.getX(); - float temporalAabbMaxy = temporalAabbMax.getY(); - float temporalAabbMaxz = temporalAabbMax.getZ(); - float temporalAabbMinx = temporalAabbMin.getX(); - float temporalAabbMiny = temporalAabbMin.getY(); - float temporalAabbMinz = temporalAabbMin.getZ(); - - // add linear motion - btVector3 linMotion = linvel*timeStep; - - if (linMotion.x() > 0.f) - temporalAabbMaxx += linMotion.x(); - else - temporalAabbMinx += linMotion.x(); - if (linMotion.y() > 0.f) - temporalAabbMaxy += linMotion.y(); - else - temporalAabbMiny += linMotion.y(); - if (linMotion.z() > 0.f) - temporalAabbMaxz += linMotion.z(); - else - temporalAabbMinz += linMotion.z(); - - //add conservative angular motion - btScalar angularMotion(0);// = angvel.length() * GetAngularMotionDisc() * timeStep; - btVector3 angularMotion3d(angularMotion,angularMotion,angularMotion); - temporalAabbMin = btVector3(temporalAabbMinx,temporalAabbMiny,temporalAabbMinz); - temporalAabbMax = btVector3(temporalAabbMaxx,temporalAabbMaxy,temporalAabbMaxz); - - temporalAabbMin -= angularMotion3d; - temporalAabbMax += angularMotion3d; - - m_broadphasePairCache->setAabb(body->getBroadphaseHandle(),temporalAabbMin,temporalAabbMax,m_dispatcher1); - } - } - - //update aabb (of all moved objects) - - m_broadphasePairCache->calculateOverlappingPairs(m_dispatcher1); - - END_PROFILE("perform Temporal Broadphase Collision Detection"); - - -} - - diff --git a/extern/bullet2/src/BulletDynamics/Dynamics/btContinuousDynamicsWorld.h b/extern/bullet2/src/BulletDynamics/Dynamics/btContinuousDynamicsWorld.h deleted file mode 100644 index 61c8dea03eb..00000000000 --- a/extern/bullet2/src/BulletDynamics/Dynamics/btContinuousDynamicsWorld.h +++ /dev/null @@ -1,46 +0,0 @@ -/* -Bullet Continuous Collision Detection and Physics Library -Copyright (c) 2003-2007 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 BT_CONTINUOUS_DYNAMICS_WORLD_H -#define BT_CONTINUOUS_DYNAMICS_WORLD_H - -#include "btDiscreteDynamicsWorld.h" - -///btContinuousDynamicsWorld adds optional (per object) continuous collision detection for fast moving objects to the btDiscreteDynamicsWorld. -///This copes with fast moving objects that otherwise would tunnel/miss collisions. -///Under construction, don't use yet! Please use btDiscreteDynamicsWorld instead. -class btContinuousDynamicsWorld : public btDiscreteDynamicsWorld -{ - - void updateTemporalAabbs(btScalar timeStep); - - public: - - btContinuousDynamicsWorld(btDispatcher* dispatcher,btBroadphaseInterface* pairCache,btConstraintSolver* constraintSolver,btCollisionConfiguration* collisionConfiguration); - virtual ~btContinuousDynamicsWorld(); - - ///time stepping with calculation of time of impact for selected fast moving objects - virtual void internalSingleStepSimulation( btScalar timeStep); - - virtual void calculateTimeOfImpacts(btScalar timeStep); - - virtual btDynamicsWorldType getWorldType() const - { - return BT_CONTINUOUS_DYNAMICS_WORLD; - } - -}; - -#endif //BT_CONTINUOUS_DYNAMICS_WORLD_H diff --git a/extern/bullet2/src/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.cpp b/extern/bullet2/src/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.cpp deleted file mode 100644 index 88b11c878c5..00000000000 --- a/extern/bullet2/src/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.cpp +++ /dev/null @@ -1,1004 +0,0 @@ -/* -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 "btDiscreteDynamicsWorld.h" - -//collision detection -#include "BulletCollision/CollisionDispatch/btCollisionDispatcher.h" -#include "BulletCollision/BroadphaseCollision/btSimpleBroadphase.h" -#include "BulletCollision/CollisionShapes/btCollisionShape.h" -#include "BulletCollision/CollisionDispatch/btSimulationIslandManager.h" -#include - -//rigidbody & constraints -#include "BulletDynamics/Dynamics/btRigidBody.h" -#include "BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.h" -#include "BulletDynamics/ConstraintSolver/btContactSolverInfo.h" -#include "BulletDynamics/ConstraintSolver/btTypedConstraint.h" - -//for debug rendering -#include "BulletCollision/CollisionShapes/btBoxShape.h" -#include "BulletCollision/CollisionShapes/btCapsuleShape.h" -#include "BulletCollision/CollisionShapes/btCompoundShape.h" -#include "BulletCollision/CollisionShapes/btConeShape.h" -#include "BulletCollision/CollisionShapes/btConvexTriangleMeshShape.h" -#include "BulletCollision/CollisionShapes/btCylinderShape.h" -#include "BulletCollision/CollisionShapes/btMultiSphereShape.h" -#include "BulletCollision/CollisionShapes/btPolyhedralConvexShape.h" -#include "BulletCollision/CollisionShapes/btSphereShape.h" -#include "BulletCollision/CollisionShapes/btTriangleCallback.h" -#include "BulletCollision/CollisionShapes/btTriangleMeshShape.h" -#include "LinearMath/btIDebugDraw.h" - - - -//vehicle -#include "BulletDynamics/Vehicle/btRaycastVehicle.h" -#include "BulletDynamics/Vehicle/btVehicleRaycaster.h" -#include "BulletDynamics/Vehicle/btWheelInfo.h" -#include "LinearMath/btIDebugDraw.h" -#include "LinearMath/btQuickprof.h" -#include "LinearMath/btMotionState.h" - - - - - -btDiscreteDynamicsWorld::btDiscreteDynamicsWorld(btDispatcher* dispatcher,btBroadphaseInterface* pairCache,btConstraintSolver* constraintSolver, btCollisionConfiguration* collisionConfiguration) -:btDynamicsWorld(dispatcher,pairCache,collisionConfiguration), -m_constraintSolver(constraintSolver), -m_debugDrawer(0), -m_gravity(0,-10,0), -m_localTime(btScalar(1.)/btScalar(60.)), -m_profileTimings(0) -{ - if (!m_constraintSolver) - { - void* mem = btAlignedAlloc(sizeof(btSequentialImpulseConstraintSolver),16); - m_constraintSolver = new (mem) btSequentialImpulseConstraintSolver; - m_ownsConstraintSolver = true; - } else - { - m_ownsConstraintSolver = false; - } - - { - void* mem = btAlignedAlloc(sizeof(btSimulationIslandManager),16); - m_islandManager = new (mem) btSimulationIslandManager(); - } - - m_ownsIslandManager = true; -} - - -btDiscreteDynamicsWorld::~btDiscreteDynamicsWorld() -{ - //only delete it when we created it - if (m_ownsIslandManager) - { - m_islandManager->~btSimulationIslandManager(); - btAlignedFree( m_islandManager); - } - if (m_ownsConstraintSolver) - { - - m_constraintSolver->~btConstraintSolver(); - btAlignedFree(m_constraintSolver); - } -} - -void btDiscreteDynamicsWorld::saveKinematicState(btScalar timeStep) -{ - - for (int i=0;igetActivationState() != ISLAND_SLEEPING) - { - if (body->isKinematicObject()) - { - //to calculate velocities next frame - body->saveKinematicState(timeStep); - } - } - } - } -} - -void btDiscreteDynamicsWorld::synchronizeMotionStates() -{ - //debug vehicle wheels - - - { - //todo: iterate over awake simulation islands! - for ( int i=0;igetDebugMode() & btIDebugDraw::DBG_DrawWireframe) - { - btVector3 color(btScalar(255.),btScalar(255.),btScalar(255.)); - switch(colObj->getActivationState()) - { - case ACTIVE_TAG: - color = btVector3(btScalar(255.),btScalar(255.),btScalar(255.)); break; - case ISLAND_SLEEPING: - color = btVector3(btScalar(0.),btScalar(255.),btScalar(0.));break; - case WANTS_DEACTIVATION: - color = btVector3(btScalar(0.),btScalar(255.),btScalar(255.));break; - case DISABLE_DEACTIVATION: - color = btVector3(btScalar(255.),btScalar(0.),btScalar(0.));break; - case DISABLE_SIMULATION: - color = btVector3(btScalar(255.),btScalar(255.),btScalar(0.));break; - default: - { - color = btVector3(btScalar(255.),btScalar(0.),btScalar(0.)); - } - }; - - debugDrawObject(colObj->getWorldTransform(),colObj->getCollisionShape(),color); - } - btRigidBody* body = btRigidBody::upcast(colObj); - if (body && body->getMotionState() && !body->isStaticOrKinematicObject()) - { - //we need to call the update at least once, even for sleeping objects - //otherwise the 'graphics' transform never updates properly - //so todo: add 'dirty' flag - //if (body->getActivationState() != ISLAND_SLEEPING) - { - btTransform interpolatedTransform; - btTransformUtil::integrateTransform(body->getInterpolationWorldTransform(), - body->getInterpolationLinearVelocity(),body->getInterpolationAngularVelocity(),m_localTime,interpolatedTransform); - body->getMotionState()->setWorldTransform(interpolatedTransform); - } - } - } - } - - if (getDebugDrawer() && getDebugDrawer()->getDebugMode() & btIDebugDraw::DBG_DrawWireframe) - { - for ( int i=0;im_vehicles.size();i++) - { - for (int v=0;vgetNumWheels();v++) - { - btVector3 wheelColor(0,255,255); - if (m_vehicles[i]->getWheelInfo(v).m_raycastInfo.m_isInContact) - { - wheelColor.setValue(0,0,255); - } else - { - wheelColor.setValue(255,0,255); - } - - //synchronize the wheels with the (interpolated) chassis worldtransform - m_vehicles[i]->updateWheelTransform(v,true); - - btVector3 wheelPosWS = m_vehicles[i]->getWheelInfo(v).m_worldTransform.getOrigin(); - - btVector3 axle = btVector3( - m_vehicles[i]->getWheelInfo(v).m_worldTransform.getBasis()[0][m_vehicles[i]->getRightAxis()], - m_vehicles[i]->getWheelInfo(v).m_worldTransform.getBasis()[1][m_vehicles[i]->getRightAxis()], - m_vehicles[i]->getWheelInfo(v).m_worldTransform.getBasis()[2][m_vehicles[i]->getRightAxis()]); - - - //m_vehicles[i]->getWheelInfo(v).m_raycastInfo.m_wheelAxleWS - //debug wheels (cylinders) - m_debugDrawer->drawLine(wheelPosWS,wheelPosWS+axle,wheelColor); - m_debugDrawer->drawLine(wheelPosWS,m_vehicles[i]->getWheelInfo(v).m_raycastInfo.m_contactPointWS,wheelColor); - - } - } - } - -} - - -int btDiscreteDynamicsWorld::stepSimulation( btScalar timeStep,int maxSubSteps, btScalar fixedTimeStep) -{ - int numSimulationSubSteps = 0; - - if (maxSubSteps) - { - //fixed timestep with interpolation - m_localTime += timeStep; - if (m_localTime >= fixedTimeStep) - { - numSimulationSubSteps = int( m_localTime / fixedTimeStep); - m_localTime -= numSimulationSubSteps * fixedTimeStep; - } - } else - { - //variable timestep - fixedTimeStep = timeStep; - m_localTime = timeStep; - if (btFuzzyZero(timeStep)) - { - numSimulationSubSteps = 0; - maxSubSteps = 0; - } else - { - numSimulationSubSteps = 1; - maxSubSteps = 1; - } - } - - //process some debugging flags - if (getDebugDrawer()) - { - gDisableDeactivation = (getDebugDrawer()->getDebugMode() & btIDebugDraw::DBG_NoDeactivation) != 0; - } - if (numSimulationSubSteps) - { - - saveKinematicState(fixedTimeStep); - - //clamp the number of substeps, to prevent simulation grinding spiralling down to a halt - int clampedSimulationSteps = (numSimulationSubSteps > maxSubSteps)? maxSubSteps : numSimulationSubSteps; - - for (int i=0;isetGravity(gravity); - } - } -} - - -void btDiscreteDynamicsWorld::removeRigidBody(btRigidBody* body) -{ - removeCollisionObject(body); -} - -void btDiscreteDynamicsWorld::addRigidBody(btRigidBody* body) -{ - if (!body->isStaticOrKinematicObject()) - { - body->setGravity(m_gravity); - } - - if (body->getCollisionShape()) - { - bool isDynamic = !(body->isStaticObject() || body->isKinematicObject()); - short collisionFilterGroup = isDynamic? short(btBroadphaseProxy::DefaultFilter) : short(btBroadphaseProxy::StaticFilter); - short collisionFilterMask = isDynamic? short(btBroadphaseProxy::AllFilter) : short(btBroadphaseProxy::AllFilter ^ btBroadphaseProxy::StaticFilter); - - addCollisionObject(body,collisionFilterGroup,collisionFilterMask); - } -} - -void btDiscreteDynamicsWorld::addRigidBody(btRigidBody* body, short group, short mask) -{ - if (!body->isStaticOrKinematicObject()) - { - body->setGravity(m_gravity); - } - - if (body->getCollisionShape()) - { - addCollisionObject(body,group,mask); - } -} - - -void btDiscreteDynamicsWorld::updateVehicles(btScalar timeStep) -{ - BEGIN_PROFILE("updateVehicles"); - - for ( int i=0;iupdateVehicle( timeStep); - } - END_PROFILE("updateVehicles"); -} - -void btDiscreteDynamicsWorld::updateActivationState(btScalar timeStep) -{ - BEGIN_PROFILE("updateActivationState"); - - for ( int i=0;iupdateDeactivation(timeStep); - - if (body->wantsSleeping()) - { - if (body->isStaticOrKinematicObject()) - { - body->setActivationState(ISLAND_SLEEPING); - } else - { - if (body->getActivationState() == ACTIVE_TAG) - body->setActivationState( WANTS_DEACTIVATION ); - } - } else - { - if (body->getActivationState() != DISABLE_DEACTIVATION) - body->setActivationState( ACTIVE_TAG ); - } - } - } - END_PROFILE("updateActivationState"); -} - -void btDiscreteDynamicsWorld::addConstraint(btTypedConstraint* constraint,bool disableCollisionsBetweenLinkedBodies) -{ - m_constraints.push_back(constraint); - if (disableCollisionsBetweenLinkedBodies) - { - constraint->getRigidBodyA().addConstraintRef(constraint); - constraint->getRigidBodyB().addConstraintRef(constraint); - } -} - -void btDiscreteDynamicsWorld::removeConstraint(btTypedConstraint* constraint) -{ - m_constraints.remove(constraint); - constraint->getRigidBodyA().removeConstraintRef(constraint); - constraint->getRigidBodyB().removeConstraintRef(constraint); -} - -void btDiscreteDynamicsWorld::addVehicle(btRaycastVehicle* vehicle) -{ - m_vehicles.push_back(vehicle); -} - -void btDiscreteDynamicsWorld::removeVehicle(btRaycastVehicle* vehicle) -{ - m_vehicles.remove(vehicle); -} - -SIMD_FORCE_INLINE int btGetConstraintIslandId(const btTypedConstraint* lhs) -{ - int islandId; - - const btCollisionObject& rcolObj0 = lhs->getRigidBodyA(); - const btCollisionObject& rcolObj1 = lhs->getRigidBodyB(); - islandId= rcolObj0.getIslandTag()>=0?rcolObj0.getIslandTag():rcolObj1.getIslandTag(); - return islandId; - -} - - -class btSortConstraintOnIslandPredicate -{ - public: - - bool operator() ( const btTypedConstraint* lhs, const btTypedConstraint* rhs ) - { - int rIslandId0,lIslandId0; - rIslandId0 = btGetConstraintIslandId(rhs); - lIslandId0 = btGetConstraintIslandId(lhs); - return lIslandId0 < rIslandId0; - } -}; - - - - -void btDiscreteDynamicsWorld::solveConstraints(btContactSolverInfo& solverInfo) -{ - - struct InplaceSolverIslandCallback : public btSimulationIslandManager::IslandCallback - { - - btContactSolverInfo& m_solverInfo; - btConstraintSolver* m_solver; - btTypedConstraint** m_sortedConstraints; - int m_numConstraints; - btIDebugDraw* m_debugDrawer; - btStackAlloc* m_stackAlloc; - btDispatcher* m_dispatcher; - - InplaceSolverIslandCallback( - btContactSolverInfo& solverInfo, - btConstraintSolver* solver, - btTypedConstraint** sortedConstraints, - int numConstraints, - btIDebugDraw* debugDrawer, - btStackAlloc* stackAlloc, - btDispatcher* dispatcher) - :m_solverInfo(solverInfo), - m_solver(solver), - m_sortedConstraints(sortedConstraints), - m_numConstraints(numConstraints), - m_debugDrawer(debugDrawer), - m_stackAlloc(stackAlloc), - m_dispatcher(dispatcher) - { - - } - - InplaceSolverIslandCallback& operator=(InplaceSolverIslandCallback& other) - { - btAssert(0); - (void)other; - return *this; - } - virtual void ProcessIsland(btCollisionObject** bodies,int numBodies,btPersistentManifold** manifolds,int numManifolds, int islandId) - { - if (islandId<0) - { - ///we don't split islands, so all constraints/contact manifolds/bodies are passed into the solver regardless the island id - m_solver->solveGroup( bodies,numBodies,manifolds, numManifolds,&m_sortedConstraints[0],m_numConstraints,m_solverInfo,m_debugDrawer,m_stackAlloc,m_dispatcher); - } else - { - //also add all non-contact constraints/joints for this island - btTypedConstraint** startConstraint = 0; - int numCurConstraints = 0; - int i; - - //find the first constraint for this island - for (i=0;isolveGroup( bodies,numBodies,manifolds, numManifolds,startConstraint,numCurConstraints,m_solverInfo,m_debugDrawer,m_stackAlloc,m_dispatcher); - - } - } - - }; - - //sorted version of all btTypedConstraint, based on islandId - btAlignedObjectArray sortedConstraints; - sortedConstraints.resize( m_constraints.size()); - int i; - for (i=0;iprepareSolve(getCollisionWorld()->getNumCollisionObjects(), getCollisionWorld()->getDispatcher()->getNumManifolds()); - - /// solve all the constraints for this island - m_islandManager->buildAndProcessIslands(getCollisionWorld()->getDispatcher(),getCollisionWorld()->getCollisionObjectArray(),&solverCallback); - - m_constraintSolver->allSolved(solverInfo, m_debugDrawer, m_stackAlloc); -} - - - - -void btDiscreteDynamicsWorld::calculateSimulationIslands() -{ - BEGIN_PROFILE("calculateSimulationIslands"); - - getSimulationIslandManager()->updateActivationState(getCollisionWorld(),getCollisionWorld()->getDispatcher()); - - { - int i; - int numConstraints = int(m_constraints.size()); - for (i=0;i< numConstraints ; i++ ) - { - btTypedConstraint* constraint = m_constraints[i]; - - const btRigidBody* colObj0 = &constraint->getRigidBodyA(); - const btRigidBody* colObj1 = &constraint->getRigidBodyB(); - - if (((colObj0) && ((colObj0)->mergesSimulationIslands())) && - ((colObj1) && ((colObj1)->mergesSimulationIslands()))) - { - if (colObj0->isActive() || colObj1->isActive()) - { - - getSimulationIslandManager()->getUnionFind().unite((colObj0)->getIslandTag(), - (colObj1)->getIslandTag()); - } - } - } - } - - //Store the island id in each body - getSimulationIslandManager()->storeIslandActivationState(getCollisionWorld()); - - END_PROFILE("calculateSimulationIslands"); - -} - - -void btDiscreteDynamicsWorld::updateAabbs() -{ - BEGIN_PROFILE("updateAabbs"); - - btVector3 colorvec(1,0,0); - btTransform predictedTrans; - for ( int i=0;iIsActive() && (!body->IsStatic())) - { - btPoint3 minAabb,maxAabb; - colObj->getCollisionShape()->getAabb(colObj->getWorldTransform(), minAabb,maxAabb); - btBroadphaseInterface* bp = (btBroadphaseInterface*)m_broadphasePairCache; - - //moving objects should be moderately sized, probably something wrong if not - if ( colObj->isStaticObject() || ((maxAabb-minAabb).length2() < btScalar(1e12))) - { - bp->setAabb(body->getBroadphaseHandle(),minAabb,maxAabb, m_dispatcher1); - } else - { - //something went wrong, investigate - //this assert is unwanted in 3D modelers (danger of loosing work) - body->setActivationState(DISABLE_SIMULATION); - - static bool reportMe = true; - if (reportMe && m_debugDrawer) - { - reportMe = false; - m_debugDrawer->reportErrorWarning("Overflow in AABB, object removed from simulation"); - m_debugDrawer->reportErrorWarning("If you can reproduce this, please email bugs@continuousphysics.com\n"); - m_debugDrawer->reportErrorWarning("Please include above information, your Platform, version of OS.\n"); - m_debugDrawer->reportErrorWarning("Thanks.\n"); - } - - - } - if (m_debugDrawer && (m_debugDrawer->getDebugMode() & btIDebugDraw::DBG_DrawAabb)) - { - m_debugDrawer->drawAabb(minAabb,maxAabb,colorvec); - } - } - } - } - - END_PROFILE("updateAabbs"); -} - -void btDiscreteDynamicsWorld::integrateTransforms(btScalar timeStep) -{ - BEGIN_PROFILE("integrateTransforms"); - btTransform predictedTrans; - for ( int i=0;iisActive() && (!body->isStaticOrKinematicObject())) - { - body->predictIntegratedTransform(timeStep, predictedTrans); - body->proceedToTransform( predictedTrans); - } - } - } - END_PROFILE("integrateTransforms"); -} - - - -void btDiscreteDynamicsWorld::predictUnconstraintMotion(btScalar timeStep) -{ - BEGIN_PROFILE("predictUnconstraintMotion"); - for ( int i=0;iisStaticOrKinematicObject()) - { - if (body->isActive()) - { - body->applyForces( timeStep); - body->integrateVelocities( timeStep); - body->predictIntegratedTransform(timeStep,body->getInterpolationWorldTransform()); - } - } - } - } - END_PROFILE("predictUnconstraintMotion"); -} - - -void btDiscreteDynamicsWorld::startProfiling(btScalar timeStep) -{ - (void)timeStep; - #ifdef USE_QUICKPROF - - - //toggle btProfiler - if ( m_debugDrawer && m_debugDrawer->getDebugMode() & btIDebugDraw::DBG_ProfileTimings) - { - if (!m_profileTimings) - { - m_profileTimings = 1; - // To disable profiling, simply comment out the following line. - static int counter = 0; - - char filename[128]; - sprintf(filename,"quickprof_bullet_timings%i.csv",counter++); - btProfiler::init(filename, btProfiler::BLOCK_CYCLE_SECONDS);//BLOCK_TOTAL_MICROSECONDS - } else - { - btProfiler::endProfilingCycle(); - } - - } else - { - if (m_profileTimings) - { - btProfiler::endProfilingCycle(); - - m_profileTimings = 0; - btProfiler::destroy(); - } - } -#endif //USE_QUICKPROF -} - - - - - - -class DebugDrawcallback : public btTriangleCallback, public btInternalTriangleIndexCallback -{ - btIDebugDraw* m_debugDrawer; - btVector3 m_color; - btTransform m_worldTrans; - -public: - - DebugDrawcallback(btIDebugDraw* debugDrawer,const btTransform& worldTrans,const btVector3& color) : - m_debugDrawer(debugDrawer), - m_color(color), - m_worldTrans(worldTrans) - { - } - - virtual void internalProcessTriangleIndex(btVector3* triangle,int partId,int triangleIndex) - { - processTriangle(triangle,partId,triangleIndex); - } - - virtual void processTriangle(btVector3* triangle,int partId, int triangleIndex) - { - (void)partId; - (void)triangleIndex; - - btVector3 wv0,wv1,wv2; - wv0 = m_worldTrans*triangle[0]; - wv1 = m_worldTrans*triangle[1]; - wv2 = m_worldTrans*triangle[2]; - m_debugDrawer->drawLine(wv0,wv1,m_color); - m_debugDrawer->drawLine(wv1,wv2,m_color); - m_debugDrawer->drawLine(wv2,wv0,m_color); - } -}; - -void btDiscreteDynamicsWorld::debugDrawSphere(btScalar radius, const btTransform& transform, const btVector3& color) -{ - btVector3 start = transform.getOrigin(); - - const btVector3 xoffs = transform.getBasis() * btVector3(radius,0,0); - const btVector3 yoffs = transform.getBasis() * btVector3(0,radius,0); - const btVector3 zoffs = transform.getBasis() * btVector3(0,0,radius); - - // XY - getDebugDrawer()->drawLine(start-xoffs, start+yoffs, color); - getDebugDrawer()->drawLine(start+yoffs, start+xoffs, color); - getDebugDrawer()->drawLine(start+xoffs, start-yoffs, color); - getDebugDrawer()->drawLine(start-yoffs, start-xoffs, color); - - // XZ - getDebugDrawer()->drawLine(start-xoffs, start+zoffs, color); - getDebugDrawer()->drawLine(start+zoffs, start+xoffs, color); - getDebugDrawer()->drawLine(start+xoffs, start-zoffs, color); - getDebugDrawer()->drawLine(start-zoffs, start-xoffs, color); - - // YZ - getDebugDrawer()->drawLine(start-yoffs, start+zoffs, color); - getDebugDrawer()->drawLine(start+zoffs, start+yoffs, color); - getDebugDrawer()->drawLine(start+yoffs, start-zoffs, color); - getDebugDrawer()->drawLine(start-zoffs, start-yoffs, color); -} - -void btDiscreteDynamicsWorld::debugDrawObject(const btTransform& worldTransform, const btCollisionShape* shape, const btVector3& color) -{ - // Draw a small simplex at the center of the object - { - btVector3 start = worldTransform.getOrigin(); - getDebugDrawer()->drawLine(start, start+worldTransform.getBasis() * btVector3(1,0,0), btVector3(1,0,0)); - getDebugDrawer()->drawLine(start, start+worldTransform.getBasis() * btVector3(0,1,0), btVector3(0,1,0)); - getDebugDrawer()->drawLine(start, start+worldTransform.getBasis() * btVector3(0,0,1), btVector3(0,0,1)); - } - - if (shape->getShapeType() == COMPOUND_SHAPE_PROXYTYPE) - { - const btCompoundShape* compoundShape = static_cast(shape); - for (int i=compoundShape->getNumChildShapes()-1;i>=0;i--) - { - btTransform childTrans = compoundShape->getChildTransform(i); - const btCollisionShape* colShape = compoundShape->getChildShape(i); - debugDrawObject(worldTransform*childTrans,colShape,color); - } - - } else - { - switch (shape->getShapeType()) - { - - case SPHERE_SHAPE_PROXYTYPE: - { - const btSphereShape* sphereShape = static_cast(shape); - btScalar radius = sphereShape->getMargin();//radius doesn't include the margin, so draw with margin - - debugDrawSphere(radius, worldTransform, color); - break; - } - case MULTI_SPHERE_SHAPE_PROXYTYPE: - { - const btMultiSphereShape* multiSphereShape = static_cast(shape); - - for (int i = multiSphereShape->getSphereCount()-1; i>=0;i--) - { - btTransform childTransform = worldTransform; - childTransform.getOrigin() += multiSphereShape->getSpherePosition(i); - debugDrawSphere(multiSphereShape->getSphereRadius(i), childTransform, color); - } - - break; - } - case CAPSULE_SHAPE_PROXYTYPE: - { - const btCapsuleShape* capsuleShape = static_cast(shape); - - btScalar radius = capsuleShape->getRadius(); - btScalar halfHeight = capsuleShape->getHalfHeight(); - - // Draw the ends - { - btTransform childTransform = worldTransform; - childTransform.getOrigin() = worldTransform * btVector3(0,halfHeight,0); - debugDrawSphere(radius, childTransform, color); - } - - { - btTransform childTransform = worldTransform; - childTransform.getOrigin() = worldTransform * btVector3(0,-halfHeight,0); - debugDrawSphere(radius, childTransform, color); - } - - // Draw some additional lines - btVector3 start = worldTransform.getOrigin(); - getDebugDrawer()->drawLine(start+worldTransform.getBasis() * btVector3(-radius,halfHeight,0),start+worldTransform.getBasis() * btVector3(-radius,-halfHeight,0), color); - getDebugDrawer()->drawLine(start+worldTransform.getBasis() * btVector3(radius,halfHeight,0),start+worldTransform.getBasis() * btVector3(radius,-halfHeight,0), color); - getDebugDrawer()->drawLine(start+worldTransform.getBasis() * btVector3(0,halfHeight,-radius),start+worldTransform.getBasis() * btVector3(0,-halfHeight,-radius), color); - getDebugDrawer()->drawLine(start+worldTransform.getBasis() * btVector3(0,halfHeight,radius),start+worldTransform.getBasis() * btVector3(0,-halfHeight,radius), color); - - break; - } - case CONE_SHAPE_PROXYTYPE: - { - const btConeShape* coneShape = static_cast(shape); - btScalar radius = coneShape->getRadius();//+coneShape->getMargin(); - btScalar height = coneShape->getHeight();//+coneShape->getMargin(); - btVector3 start = worldTransform.getOrigin(); - - int upAxis= coneShape->getConeUpIndex(); - - - btVector3 offsetHeight(0,0,0); - offsetHeight[upAxis] = height * btScalar(0.5); - btVector3 offsetRadius(0,0,0); - offsetRadius[(upAxis+1)%3] = radius; - btVector3 offset2Radius(0,0,0); - offset2Radius[(upAxis+2)%3] = radius; - - getDebugDrawer()->drawLine(start+worldTransform.getBasis() * (offsetHeight),start+worldTransform.getBasis() * (-offsetHeight+offsetRadius),color); - getDebugDrawer()->drawLine(start+worldTransform.getBasis() * (offsetHeight),start+worldTransform.getBasis() * (-offsetHeight-offsetRadius),color); - getDebugDrawer()->drawLine(start+worldTransform.getBasis() * (offsetHeight),start+worldTransform.getBasis() * (-offsetHeight+offset2Radius),color); - getDebugDrawer()->drawLine(start+worldTransform.getBasis() * (offsetHeight),start+worldTransform.getBasis() * (-offsetHeight-offset2Radius),color); - - - - break; - - } - case CYLINDER_SHAPE_PROXYTYPE: - { - const btCylinderShape* cylinder = static_cast(shape); - int upAxis = cylinder->getUpAxis(); - btScalar radius = cylinder->getRadius(); - btScalar halfHeight = cylinder->getHalfExtentsWithMargin()[upAxis]; - btVector3 start = worldTransform.getOrigin(); - btVector3 offsetHeight(0,0,0); - offsetHeight[upAxis] = halfHeight; - btVector3 offsetRadius(0,0,0); - offsetRadius[(upAxis+1)%3] = radius; - getDebugDrawer()->drawLine(start+worldTransform.getBasis() * (offsetHeight+offsetRadius),start+worldTransform.getBasis() * (-offsetHeight+offsetRadius),color); - getDebugDrawer()->drawLine(start+worldTransform.getBasis() * (offsetHeight-offsetRadius),start+worldTransform.getBasis() * (-offsetHeight-offsetRadius),color); - break; - } - default: - { - - if (shape->isConcave()) - { - btConcaveShape* concaveMesh = (btConcaveShape*) shape; - - //todo pass camera, for some culling - btVector3 aabbMax(btScalar(1e30),btScalar(1e30),btScalar(1e30)); - btVector3 aabbMin(btScalar(-1e30),btScalar(-1e30),btScalar(-1e30)); - - DebugDrawcallback drawCallback(getDebugDrawer(),worldTransform,color); - concaveMesh->processAllTriangles(&drawCallback,aabbMin,aabbMax); - - } - - if (shape->getShapeType() == CONVEX_TRIANGLEMESH_SHAPE_PROXYTYPE) - { - btConvexTriangleMeshShape* convexMesh = (btConvexTriangleMeshShape*) shape; - //todo: pass camera for some culling - btVector3 aabbMax(btScalar(1e30),btScalar(1e30),btScalar(1e30)); - btVector3 aabbMin(btScalar(-1e30),btScalar(-1e30),btScalar(-1e30)); - //DebugDrawcallback drawCallback; - DebugDrawcallback drawCallback(getDebugDrawer(),worldTransform,color); - convexMesh->getMeshInterface()->InternalProcessAllTriangles(&drawCallback,aabbMin,aabbMax); - } - - - /// for polyhedral shapes - if (shape->isPolyhedral()) - { - btPolyhedralConvexShape* polyshape = (btPolyhedralConvexShape*) shape; - - int i; - for (i=0;igetNumEdges();i++) - { - btPoint3 a,b; - polyshape->getEdge(i,a,b); - btVector3 wa = worldTransform * a; - btVector3 wb = worldTransform * b; - getDebugDrawer()->drawLine(wa,wb,color); - - } - - - } - } - } - } -} - - -void btDiscreteDynamicsWorld::setConstraintSolver(btConstraintSolver* solver) -{ - if (m_ownsConstraintSolver) - { - btAlignedFree( m_constraintSolver); - } - m_ownsConstraintSolver = false; - m_constraintSolver = solver; -} - -btConstraintSolver* btDiscreteDynamicsWorld::getConstraintSolver() -{ - return m_constraintSolver; -} - - -int btDiscreteDynamicsWorld::getNumConstraints() const -{ - return int(m_constraints.size()); -} -btTypedConstraint* btDiscreteDynamicsWorld::getConstraint(int index) -{ - return m_constraints[index]; -} -const btTypedConstraint* btDiscreteDynamicsWorld::getConstraint(int index) const -{ - return m_constraints[index]; -} diff --git a/extern/bullet2/src/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.h b/extern/bullet2/src/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.h deleted file mode 100644 index 7364c4cd6b9..00000000000 --- a/extern/bullet2/src/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.h +++ /dev/null @@ -1,164 +0,0 @@ -/* -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 BT_DISCRETE_DYNAMICS_WORLD_H -#define BT_DISCRETE_DYNAMICS_WORLD_H - -#include "btDynamicsWorld.h" - -class btDispatcher; -class btOverlappingPairCache; -class btConstraintSolver; -class btSimulationIslandManager; -class btTypedConstraint; -#include "BulletDynamics/ConstraintSolver/btContactSolverInfo.h" - -class btRaycastVehicle; -class btIDebugDraw; -#include "LinearMath/btAlignedObjectArray.h" - - -///btDiscreteDynamicsWorld provides discrete rigid body simulation -///those classes replace the obsolete CcdPhysicsEnvironment/CcdPhysicsController -class btDiscreteDynamicsWorld : public btDynamicsWorld -{ -protected: - - btConstraintSolver* m_constraintSolver; - - btSimulationIslandManager* m_islandManager; - - btAlignedObjectArray m_constraints; - - btIDebugDraw* m_debugDrawer; - - btVector3 m_gravity; - - //for variable timesteps - btScalar m_localTime; - //for variable timesteps - - bool m_ownsIslandManager; - bool m_ownsConstraintSolver; - - btContactSolverInfo m_solverInfo; - - - btAlignedObjectArray m_vehicles; - - int m_profileTimings; - - void predictUnconstraintMotion(btScalar timeStep); - - void integrateTransforms(btScalar timeStep); - - void calculateSimulationIslands(); - - void solveConstraints(btContactSolverInfo& solverInfo); - - void updateActivationState(btScalar timeStep); - - void updateVehicles(btScalar timeStep); - - void startProfiling(btScalar timeStep); - - virtual void internalSingleStepSimulation( btScalar timeStep); - - void synchronizeMotionStates(); - - void saveKinematicState(btScalar timeStep); - - void debugDrawSphere(btScalar radius, const btTransform& transform, const btVector3& color); - -public: - - - ///this btDiscreteDynamicsWorld constructor gets created objects from the user, and will not delete those - btDiscreteDynamicsWorld(btDispatcher* dispatcher,btBroadphaseInterface* pairCache,btConstraintSolver* constraintSolver,btCollisionConfiguration* collisionConfiguration); - - virtual ~btDiscreteDynamicsWorld(); - - ///if maxSubSteps > 0, it will interpolate motion between fixedTimeStep's - virtual int stepSimulation( btScalar timeStep,int maxSubSteps=1, btScalar fixedTimeStep=btScalar(1.)/btScalar(60.)); - - virtual void updateAabbs(); - - void addConstraint(btTypedConstraint* constraint, bool disableCollisionsBetweenLinkedBodies=false); - - void removeConstraint(btTypedConstraint* constraint); - - void addVehicle(btRaycastVehicle* vehicle); - - void removeVehicle(btRaycastVehicle* vehicle); - - btSimulationIslandManager* getSimulationIslandManager() - { - return m_islandManager; - } - - const btSimulationIslandManager* getSimulationIslandManager() const - { - return m_islandManager; - } - - btCollisionWorld* getCollisionWorld() - { - return this; - } - - virtual void setDebugDrawer(btIDebugDraw* debugDrawer) - { - m_debugDrawer = debugDrawer; - } - - virtual btIDebugDraw* getDebugDrawer() - { - return m_debugDrawer; - } - - virtual void setGravity(const btVector3& gravity); - - virtual void addRigidBody(btRigidBody* body); - - virtual void addRigidBody(btRigidBody* body, short group, short mask); - - virtual void removeRigidBody(btRigidBody* body); - - void debugDrawObject(const btTransform& worldTransform, const btCollisionShape* shape, const btVector3& color); - - virtual void setConstraintSolver(btConstraintSolver* solver); - - virtual btConstraintSolver* getConstraintSolver(); - - virtual int getNumConstraints() const; - - virtual btTypedConstraint* getConstraint(int index) ; - - virtual const btTypedConstraint* getConstraint(int index) const; - - btContactSolverInfo& getSolverInfo() - { - return m_solverInfo; - } - - virtual btDynamicsWorldType getWorldType() const - { - return BT_DISCRETE_DYNAMICS_WORLD; - } - - -}; - -#endif //BT_DISCRETE_DYNAMICS_WORLD_H diff --git a/extern/bullet2/src/BulletDynamics/Dynamics/btDynamicsWorld.h b/extern/bullet2/src/BulletDynamics/Dynamics/btDynamicsWorld.h deleted file mode 100644 index a4c8bf3c559..00000000000 --- a/extern/bullet2/src/BulletDynamics/Dynamics/btDynamicsWorld.h +++ /dev/null @@ -1,89 +0,0 @@ -/* -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 BT_DYNAMICS_WORLD_H -#define BT_DYNAMICS_WORLD_H - -#include "BulletCollision/CollisionDispatch/btCollisionWorld.h" -class btTypedConstraint; -class btRaycastVehicle; -class btConstraintSolver; - - -enum btDynamicsWorldType -{ - BT_SIMPLE_DYNAMICS_WORLD=1, - BT_DISCRETE_DYNAMICS_WORLD=2, - BT_CONTINUOUS_DYNAMICS_WORLD=3 -}; - -///btDynamicsWorld is the baseclass for several dynamics implementation, basic, discrete, parallel, and continuous -class btDynamicsWorld : public btCollisionWorld -{ - public: - - - btDynamicsWorld(btDispatcher* dispatcher,btBroadphaseInterface* broadphase,btCollisionConfiguration* collisionConfiguration) - :btCollisionWorld(dispatcher,broadphase,collisionConfiguration) - { - } - - virtual ~btDynamicsWorld() - { - } - - ///stepSimulation proceeds the simulation over timeStep units - ///if maxSubSteps > 0, it will interpolate time steps - virtual int stepSimulation( btScalar timeStep,int maxSubSteps=1, btScalar fixedTimeStep=btScalar(1.)/btScalar(60.))=0; - - virtual void updateAabbs() = 0; - - virtual void addConstraint(btTypedConstraint* constraint, bool disableCollisionsBetweenLinkedBodies=false) { (void)constraint;}; - - virtual void removeConstraint(btTypedConstraint* constraint) {(void)constraint;}; - - virtual void addVehicle(btRaycastVehicle* vehicle) {(void)vehicle;}; - - virtual void removeVehicle(btRaycastVehicle* vehicle) {(void)vehicle;}; - - - virtual void setDebugDrawer(btIDebugDraw* debugDrawer) = 0; - - virtual btIDebugDraw* getDebugDrawer() = 0; - - //once a rigidbody is added to the dynamics world, it will get this gravity assigned - //existing rigidbodies in the world get gravity assigned too, during this method - virtual void setGravity(const btVector3& gravity) = 0; - - virtual void addRigidBody(btRigidBody* body) = 0; - - virtual void removeRigidBody(btRigidBody* body) = 0; - - virtual void setConstraintSolver(btConstraintSolver* solver) = 0; - - virtual btConstraintSolver* getConstraintSolver() = 0; - - virtual int getNumConstraints() const { return 0; } - - virtual btTypedConstraint* getConstraint(int index) { (void)index; return 0; } - - virtual const btTypedConstraint* getConstraint(int index) const { (void)index; return 0; } - - virtual btDynamicsWorldType getWorldType() const=0; - -}; - -#endif //BT_DYNAMICS_WORLD_H - diff --git a/extern/bullet2/src/BulletDynamics/Dynamics/btRigidBody.cpp b/extern/bullet2/src/BulletDynamics/Dynamics/btRigidBody.cpp deleted file mode 100644 index 03e60acdb19..00000000000 --- a/extern/bullet2/src/BulletDynamics/Dynamics/btRigidBody.cpp +++ /dev/null @@ -1,350 +0,0 @@ -/* -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 "btRigidBody.h" -#include "BulletCollision/CollisionShapes/btConvexShape.h" -#include "LinearMath/btMinMax.h" -#include "LinearMath/btTransformUtil.h" -#include "LinearMath/btMotionState.h" -#include "BulletDynamics/ConstraintSolver/btTypedConstraint.h" - -btScalar gLinearAirDamping = btScalar(1.); -//'temporarily' global variables -btScalar gDeactivationTime = btScalar(2.); -bool gDisableDeactivation = false; - -btScalar gLinearSleepingThreshold = btScalar(0.8); -btScalar gAngularSleepingThreshold = btScalar(1.0); -static int uniqueId = 0; - -btRigidBody::btRigidBody(btScalar mass, btMotionState* motionState, btCollisionShape* collisionShape, const btVector3& localInertia,btScalar linearDamping,btScalar angularDamping,btScalar friction,btScalar restitution) -: - m_linearVelocity(btScalar(0.0), btScalar(0.0), btScalar(0.0)), - m_angularVelocity(btScalar(0.),btScalar(0.),btScalar(0.)), - m_angularFactor(btScalar(1.)), - m_gravity(btScalar(0.0), btScalar(0.0), btScalar(0.0)), - m_totalForce(btScalar(0.0), btScalar(0.0), btScalar(0.0)), - m_totalTorque(btScalar(0.0), btScalar(0.0), btScalar(0.0)), - m_linearDamping(btScalar(0.)), - m_angularDamping(btScalar(0.5)), - m_linearSleepingThreshold(gLinearSleepingThreshold), - m_angularSleepingThreshold(gAngularSleepingThreshold), - m_optionalMotionState(motionState), - m_contactSolverType(0), - m_frictionSolverType(0) -{ - - if (motionState) - { - motionState->getWorldTransform(m_worldTransform); - } else - { - m_worldTransform = btTransform::getIdentity(); - } - - m_interpolationWorldTransform = m_worldTransform; - m_interpolationLinearVelocity.setValue(0,0,0); - m_interpolationAngularVelocity.setValue(0,0,0); - - //moved to btCollisionObject - m_friction = friction; - m_restitution = restitution; - - m_collisionShape = collisionShape; - m_debugBodyId = uniqueId++; - - //m_internalOwner is to allow upcasting from collision object to rigid body - m_internalOwner = this; - - setMassProps(mass, localInertia); - setDamping(linearDamping, angularDamping); - updateInertiaTensor(); - -} - -#ifdef OBSOLETE_MOTIONSTATE_LESS -btRigidBody::btRigidBody( btScalar mass,const btTransform& worldTransform,btCollisionShape* collisionShape,const btVector3& localInertia,btScalar linearDamping,btScalar angularDamping,btScalar friction,btScalar restitution) -: - m_gravity(btScalar(0.0), btScalar(0.0), btScalar(0.0)), - m_totalForce(btScalar(0.0), btScalar(0.0), btScalar(0.0)), - m_totalTorque(btScalar(0.0), btScalar(0.0), btScalar(0.0)), - m_linearVelocity(btScalar(0.0), btScalar(0.0), btScalar(0.0)), - m_angularVelocity(btScalar(0.),btScalar(0.),btScalar(0.)), - m_linearSleepingThreshold(gLinearSleepingThreshold), - m_angularSleepingThreshold(gAngularSleepingThreshold), - m_linearDamping(btScalar(0.)), - m_angularDamping(btScalar(0.5)), - m_optionalMotionState(0), - m_contactSolverType(0), - m_frictionSolverType(0) - -{ - - m_worldTransform = worldTransform; - m_interpolationWorldTransform = m_worldTransform; - m_interpolationLinearVelocity.setValue(0,0,0); - m_interpolationAngularVelocity.setValue(0,0,0); - - //moved to btCollisionObject - m_friction = friction; - m_restitution = restitution; - - m_collisionShape = collisionShape; - m_debugBodyId = uniqueId++; - - //m_internalOwner is to allow upcasting from collision object to rigid body - m_internalOwner = this; - - setMassProps(mass, localInertia); - setDamping(linearDamping, angularDamping); - updateInertiaTensor(); - -} - -#endif //OBSOLETE_MOTIONSTATE_LESS - - - - -#define EXPERIMENTAL_JITTER_REMOVAL 1 -#ifdef EXPERIMENTAL_JITTER_REMOVAL -//Bullet 2.20b has experimental damping code to reduce jitter just before objects fall asleep/deactivate -//doesn't work very well yet (value 0 disabled this damping) -//note there this influences deactivation thresholds! -btScalar gClippedAngvelThresholdSqr = btScalar(0.01); -btScalar gClippedLinearThresholdSqr = btScalar(0.01); -#endif //EXPERIMENTAL_JITTER_REMOVAL - -btScalar gJitterVelocityDampingFactor = btScalar(0.7); - -void btRigidBody::predictIntegratedTransform(btScalar timeStep,btTransform& predictedTransform) -{ - -#ifdef EXPERIMENTAL_JITTER_REMOVAL - //if (wantsSleeping()) - { - //clip to avoid jitter - if ((m_angularVelocity.length2() < gClippedAngvelThresholdSqr) && - (m_linearVelocity.length2() < gClippedLinearThresholdSqr)) - { - m_angularVelocity *= gJitterVelocityDampingFactor; - m_linearVelocity *= gJitterVelocityDampingFactor; - } - } - -#endif //EXPERIMENTAL_JITTER_REMOVAL - - btTransformUtil::integrateTransform(m_worldTransform,m_linearVelocity,m_angularVelocity,timeStep,predictedTransform); -} - -void btRigidBody::saveKinematicState(btScalar timeStep) -{ - //todo: clamp to some (user definable) safe minimum timestep, to limit maximum angular/linear velocities - if (timeStep != btScalar(0.)) - { - //if we use motionstate to synchronize world transforms, get the new kinematic/animated world transform - if (getMotionState()) - getMotionState()->getWorldTransform(m_worldTransform); - btVector3 linVel,angVel; - - btTransformUtil::calculateVelocity(m_interpolationWorldTransform,m_worldTransform,timeStep,m_linearVelocity,m_angularVelocity); - m_interpolationLinearVelocity = m_linearVelocity; - m_interpolationAngularVelocity = m_angularVelocity; - m_interpolationWorldTransform = m_worldTransform; - //printf("angular = %f %f %f\n",m_angularVelocity.getX(),m_angularVelocity.getY(),m_angularVelocity.getZ()); - } -} - -void btRigidBody::getAabb(btVector3& aabbMin,btVector3& aabbMax) const -{ - getCollisionShape()->getAabb(m_worldTransform,aabbMin,aabbMax); -} - - - - -void btRigidBody::setGravity(const btVector3& acceleration) -{ - if (m_inverseMass != btScalar(0.0)) - { - m_gravity = acceleration * (btScalar(1.0) / m_inverseMass); - } -} - - - - - - -void btRigidBody::setDamping(btScalar lin_damping, btScalar ang_damping) -{ - m_linearDamping = GEN_clamped(lin_damping, (btScalar)btScalar(0.0), (btScalar)btScalar(1.0)); - m_angularDamping = GEN_clamped(ang_damping, (btScalar)btScalar(0.0), (btScalar)btScalar(1.0)); -} - - - -#include - - -void btRigidBody::applyForces(btScalar step) -{ - if (isStaticOrKinematicObject()) - return; - - applyCentralForce(m_gravity); - - m_linearVelocity *= GEN_clamped((btScalar(1.) - step * gLinearAirDamping * m_linearDamping), (btScalar)btScalar(0.0), (btScalar)btScalar(1.0)); - m_angularVelocity *= GEN_clamped((btScalar(1.) - step * m_angularDamping), (btScalar)btScalar(0.0), (btScalar)btScalar(1.0)); - -#define FORCE_VELOCITY_DAMPING 1 -#ifdef FORCE_VELOCITY_DAMPING - btScalar speed = m_linearVelocity.length(); - if (speed < m_linearDamping) - { - btScalar dampVel = btScalar(0.005); - if (speed > dampVel) - { - btVector3 dir = m_linearVelocity.normalized(); - m_linearVelocity -= dir * dampVel; - } else - { - m_linearVelocity.setValue(btScalar(0.),btScalar(0.),btScalar(0.)); - } - } - - btScalar angSpeed = m_angularVelocity.length(); - if (angSpeed < m_angularDamping) - { - btScalar angDampVel = btScalar(0.005); - if (angSpeed > angDampVel) - { - btVector3 dir = m_angularVelocity.normalized(); - m_angularVelocity -= dir * angDampVel; - } else - { - m_angularVelocity.setValue(btScalar(0.),btScalar(0.),btScalar(0.)); - } - } -#endif //FORCE_VELOCITY_DAMPING - -} - -void btRigidBody::proceedToTransform(const btTransform& newTrans) -{ - setCenterOfMassTransform( newTrans ); -} - - -void btRigidBody::setMassProps(btScalar mass, const btVector3& inertia) -{ - if (mass == btScalar(0.)) - { - m_collisionFlags |= btCollisionObject::CF_STATIC_OBJECT; - m_inverseMass = btScalar(0.); - } else - { - m_collisionFlags &= (~btCollisionObject::CF_STATIC_OBJECT); - m_inverseMass = btScalar(1.0) / mass; - } - - m_invInertiaLocal.setValue(inertia.x() != btScalar(0.0) ? btScalar(1.0) / inertia.x(): btScalar(0.0), - inertia.y() != btScalar(0.0) ? btScalar(1.0) / inertia.y(): btScalar(0.0), - inertia.z() != btScalar(0.0) ? btScalar(1.0) / inertia.z(): btScalar(0.0)); - -} - - - -void btRigidBody::updateInertiaTensor() -{ - m_invInertiaTensorWorld = m_worldTransform.getBasis().scaled(m_invInertiaLocal) * m_worldTransform.getBasis().transpose(); -} - - -void btRigidBody::integrateVelocities(btScalar step) -{ - if (isStaticOrKinematicObject()) - return; - - m_linearVelocity += m_totalForce * (m_inverseMass * step); - m_angularVelocity += m_invInertiaTensorWorld * m_totalTorque * step; - -#define MAX_ANGVEL SIMD_HALF_PI - /// clamp angular velocity. collision calculations will fail on higher angular velocities - btScalar angvel = m_angularVelocity.length(); - if (angvel*step > MAX_ANGVEL) - { - m_angularVelocity *= (MAX_ANGVEL/step) /angvel; - } - - clearForces(); -} - -btQuaternion btRigidBody::getOrientation() const -{ - btQuaternion orn; - m_worldTransform.getBasis().getRotation(orn); - return orn; -} - - -void btRigidBody::setCenterOfMassTransform(const btTransform& xform) -{ - - if (isStaticOrKinematicObject()) - { - m_interpolationWorldTransform = m_worldTransform; - } else - { - m_interpolationWorldTransform = xform; - } - m_interpolationLinearVelocity = getLinearVelocity(); - m_interpolationAngularVelocity = getAngularVelocity(); - m_worldTransform = xform; - updateInertiaTensor(); -} - - -bool btRigidBody::checkCollideWithOverride(btCollisionObject* co) -{ - btRigidBody* otherRb = btRigidBody::upcast(co); - if (!otherRb) - return true; - - for (int i = 0; i < m_constraintRefs.size(); ++i) - { - btTypedConstraint* c = m_constraintRefs[i]; - if (&c->getRigidBodyA() == otherRb || &c->getRigidBodyB() == otherRb) - return false; - } - - return true; -} - -void btRigidBody::addConstraintRef(btTypedConstraint* c) -{ - int index = m_constraintRefs.findLinearSearch(c); - if (index == m_constraintRefs.size()) - m_constraintRefs.push_back(c); - - m_checkCollideWith = true; -} - -void btRigidBody::removeConstraintRef(btTypedConstraint* c) -{ - m_constraintRefs.remove(c); - m_checkCollideWith = m_constraintRefs.size() > 0; -} diff --git a/extern/bullet2/src/BulletDynamics/Dynamics/btRigidBody.h b/extern/bullet2/src/BulletDynamics/Dynamics/btRigidBody.h deleted file mode 100644 index b11f9f76d7d..00000000000 --- a/extern/bullet2/src/BulletDynamics/Dynamics/btRigidBody.h +++ /dev/null @@ -1,385 +0,0 @@ -/* -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 RIGIDBODY_H -#define RIGIDBODY_H - -#include "LinearMath/btAlignedObjectArray.h" -#include "LinearMath/btPoint3.h" -#include "LinearMath/btTransform.h" -#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" -#include "BulletCollision/CollisionDispatch/btCollisionObject.h" - -class btCollisionShape; -class btMotionState; -class btTypedConstraint; - - -extern btScalar gLinearAirDamping; - -extern btScalar gDeactivationTime; -extern bool gDisableDeactivation; -extern btScalar gLinearSleepingThreshold; -extern btScalar gAngularSleepingThreshold; - - -/// btRigidBody class for btRigidBody Dynamics -/// -class btRigidBody : public btCollisionObject -{ - - btMatrix3x3 m_invInertiaTensorWorld; - btVector3 m_linearVelocity; - btVector3 m_angularVelocity; - btScalar m_inverseMass; - btScalar m_angularFactor; - - btVector3 m_gravity; - btVector3 m_invInertiaLocal; - btVector3 m_totalForce; - btVector3 m_totalTorque; - - btScalar m_linearDamping; - btScalar m_angularDamping; - - btScalar m_linearSleepingThreshold; - btScalar m_angularSleepingThreshold; - - - //m_optionalMotionState allows to automatic synchronize the world transform for active objects - btMotionState* m_optionalMotionState; - - //keep track of typed constraints referencing this rigid body - btAlignedObjectArray m_constraintRefs; - -public: - -#ifdef OBSOLETE_MOTIONSTATE_LESS - //not supported, please use btMotionState - btRigidBody(btScalar mass, const btTransform& worldTransform, btCollisionShape* collisionShape, const btVector3& localInertia=btVector3(0,0,0),btScalar linearDamping=btScalar(0.),btScalar angularDamping=btScalar(0.),btScalar friction=btScalar(0.5),btScalar restitution=btScalar(0.)); -#endif //OBSOLETE_MOTIONSTATE_LESS - - btRigidBody(btScalar mass, btMotionState* motionState, btCollisionShape* collisionShape, const btVector3& localInertia=btVector3(0,0,0),btScalar linearDamping=btScalar(0.),btScalar angularDamping=btScalar(0.),btScalar friction=btScalar(0.5),btScalar restitution=btScalar(0.)); - - virtual ~btRigidBody() - { - //No constraints should point to this rigidbody - //Remove constraints from the dynamics world before you delete the related rigidbodies. - btAssert(m_constraintRefs.size()==0); - } - - - void proceedToTransform(const btTransform& newTrans); - - ///to keep collision detection and dynamics separate we don't store a rigidbody pointer - ///but a rigidbody is derived from btCollisionObject, so we can safely perform an upcast - static const btRigidBody* upcast(const btCollisionObject* colObj) - { - return (const btRigidBody*)colObj->getInternalOwner(); - } - static btRigidBody* upcast(btCollisionObject* colObj) - { - return (btRigidBody*)colObj->getInternalOwner(); - } - - /// continuous collision detection needs prediction - void predictIntegratedTransform(btScalar step, btTransform& predictedTransform) ; - - void saveKinematicState(btScalar step); - - - void applyForces(btScalar step); - - void setGravity(const btVector3& acceleration); - - const btVector3& getGravity() const - { - return m_gravity; - } - - void setDamping(btScalar lin_damping, btScalar ang_damping); - - SIMD_FORCE_INLINE const btCollisionShape* getCollisionShape() const { - return m_collisionShape; - } - - SIMD_FORCE_INLINE btCollisionShape* getCollisionShape() { - return m_collisionShape; - } - - void setMassProps(btScalar mass, const btVector3& inertia); - - btScalar getInvMass() const { return m_inverseMass; } - const btMatrix3x3& getInvInertiaTensorWorld() const { - return m_invInertiaTensorWorld; - } - - void integrateVelocities(btScalar step); - - void setCenterOfMassTransform(const btTransform& xform); - - void applyCentralForce(const btVector3& force) - { - m_totalForce += force; - } - - const btVector3& getInvInertiaDiagLocal() - { - return m_invInertiaLocal; - }; - - void setInvInertiaDiagLocal(const btVector3& diagInvInertia) - { - m_invInertiaLocal = diagInvInertia; - } - - void setSleepingThresholds(btScalar linear,btScalar angular) - { - m_linearSleepingThreshold = linear; - m_angularSleepingThreshold = angular; - } - - void applyTorque(const btVector3& torque) - { - m_totalTorque += torque; - } - - void applyForce(const btVector3& force, const btVector3& rel_pos) - { - applyCentralForce(force); - applyTorque(rel_pos.cross(force)); - } - - void applyCentralImpulse(const btVector3& impulse) - { - m_linearVelocity += impulse * m_inverseMass; - } - - void applyTorqueImpulse(const btVector3& torque) - { - m_angularVelocity += m_invInertiaTensorWorld * torque; - } - - void applyImpulse(const btVector3& impulse, const btVector3& rel_pos) - { - if (m_inverseMass != btScalar(0.)) - { - applyCentralImpulse(impulse); - if (m_angularFactor) - { - applyTorqueImpulse(rel_pos.cross(impulse)*m_angularFactor); - } - } - } - - //Optimization for the iterative solver: avoid calculating constant terms involving inertia, normal, relative position - SIMD_FORCE_INLINE void internalApplyImpulse(const btVector3& linearComponent, const btVector3& angularComponent,btScalar impulseMagnitude) - { - if (m_inverseMass != btScalar(0.)) - { - m_linearVelocity += linearComponent*impulseMagnitude; - if (m_angularFactor) - { - m_angularVelocity += angularComponent*impulseMagnitude*m_angularFactor; - } - } - } - - void clearForces() - { - m_totalForce.setValue(btScalar(0.0), btScalar(0.0), btScalar(0.0)); - m_totalTorque.setValue(btScalar(0.0), btScalar(0.0), btScalar(0.0)); - } - - void updateInertiaTensor(); - - const btPoint3& getCenterOfMassPosition() const { - return m_worldTransform.getOrigin(); - } - btQuaternion getOrientation() const; - - const btTransform& getCenterOfMassTransform() const { - return m_worldTransform; - } - const btVector3& getLinearVelocity() const { - return m_linearVelocity; - } - const btVector3& getAngularVelocity() const { - return m_angularVelocity; - } - - - inline void setLinearVelocity(const btVector3& lin_vel) - { - assert (m_collisionFlags != btCollisionObject::CF_STATIC_OBJECT); - m_linearVelocity = lin_vel; - } - - inline void setAngularVelocity(const btVector3& ang_vel) { - assert (m_collisionFlags != btCollisionObject::CF_STATIC_OBJECT); - { - m_angularVelocity = ang_vel; - } - } - - btVector3 getVelocityInLocalPoint(const btVector3& rel_pos) const - { - //we also calculate lin/ang velocity for kinematic objects - return m_linearVelocity + m_angularVelocity.cross(rel_pos); - - //for kinematic objects, we could also use use: - // return (m_worldTransform(rel_pos) - m_interpolationWorldTransform(rel_pos)) / m_kinematicTimeStep; - } - - void translate(const btVector3& v) - { - m_worldTransform.getOrigin() += v; - } - - - void getAabb(btVector3& aabbMin,btVector3& aabbMax) const; - - - - - - SIMD_FORCE_INLINE btScalar computeImpulseDenominator(const btPoint3& pos, const btVector3& normal) const - { - btVector3 r0 = pos - getCenterOfMassPosition(); - - btVector3 c0 = (r0).cross(normal); - - btVector3 vec = (c0 * getInvInertiaTensorWorld()).cross(r0); - - return m_inverseMass + normal.dot(vec); - - } - - SIMD_FORCE_INLINE btScalar computeAngularImpulseDenominator(const btVector3& axis) const - { - btVector3 vec = axis * getInvInertiaTensorWorld(); - return axis.dot(vec); - } - - SIMD_FORCE_INLINE void updateDeactivation(btScalar timeStep) - { - if ( (getActivationState() == ISLAND_SLEEPING) || (getActivationState() == DISABLE_DEACTIVATION)) - return; - - if ((getLinearVelocity().length2() < m_linearSleepingThreshold*m_linearSleepingThreshold) && - (getAngularVelocity().length2() < m_angularSleepingThreshold*m_angularSleepingThreshold)) - { - m_deactivationTime += timeStep; - } else - { - m_deactivationTime=btScalar(0.); - setActivationState(0); - } - - } - - SIMD_FORCE_INLINE bool wantsSleeping() - { - - if (getActivationState() == DISABLE_DEACTIVATION) - return false; - - //disable deactivation - if (gDisableDeactivation || (gDeactivationTime == btScalar(0.))) - return false; - - if ( (getActivationState() == ISLAND_SLEEPING) || (getActivationState() == WANTS_DEACTIVATION)) - return true; - - if (m_deactivationTime> gDeactivationTime) - { - return true; - } - return false; - } - - - - const btBroadphaseProxy* getBroadphaseProxy() const - { - return m_broadphaseHandle; - } - btBroadphaseProxy* getBroadphaseProxy() - { - return m_broadphaseHandle; - } - void setNewBroadphaseProxy(btBroadphaseProxy* broadphaseProxy) - { - m_broadphaseHandle = broadphaseProxy; - } - - //btMotionState allows to automatic synchronize the world transform for active objects - btMotionState* getMotionState() - { - return m_optionalMotionState; - } - const btMotionState* getMotionState() const - { - return m_optionalMotionState; - } - void setMotionState(btMotionState* motionState) - { - m_optionalMotionState = motionState; - if (m_optionalMotionState) - motionState->getWorldTransform(m_worldTransform); - } - - //for experimental overriding of friction/contact solver func - int m_contactSolverType; - int m_frictionSolverType; - - void setAngularFactor(btScalar angFac) - { - m_angularFactor = angFac; - } - btScalar getAngularFactor() const - { - return m_angularFactor; - } - - //is this rigidbody added to a btCollisionWorld/btDynamicsWorld/btBroadphase? - bool isInWorld() const - { - return (getBroadphaseProxy() != 0); - } - - virtual bool checkCollideWithOverride(btCollisionObject* co); - - void addConstraintRef(btTypedConstraint* c); - void removeConstraintRef(btTypedConstraint* c); - - btTypedConstraint* getConstraintRef(int index) - { - return m_constraintRefs[index]; - } - - int getNumConstraintRefs() - { - return m_constraintRefs.size(); - } - - - int m_debugBodyId; -}; - - - -#endif - diff --git a/extern/bullet2/src/BulletDynamics/Dynamics/btSimpleDynamicsWorld.cpp b/extern/bullet2/src/BulletDynamics/Dynamics/btSimpleDynamicsWorld.cpp deleted file mode 100644 index 3a78ec54f1c..00000000000 --- a/extern/bullet2/src/BulletDynamics/Dynamics/btSimpleDynamicsWorld.cpp +++ /dev/null @@ -1,217 +0,0 @@ -/* -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 "btSimpleDynamicsWorld.h" -#include "BulletCollision/CollisionDispatch/btCollisionDispatcher.h" -#include "BulletCollision/BroadphaseCollision/btSimpleBroadphase.h" -#include "BulletCollision/CollisionShapes/btCollisionShape.h" -#include "BulletDynamics/Dynamics/btRigidBody.h" -#include "BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.h" -#include "BulletDynamics/ConstraintSolver/btContactSolverInfo.h" - - -/* - Make sure this dummy function never changes so that it - can be used by probes that are checking whether the - library is actually installed. -*/ -extern "C" void btBulletDynamicsProbe () {} - - - - -btSimpleDynamicsWorld::btSimpleDynamicsWorld(btDispatcher* dispatcher,btBroadphaseInterface* pairCache,btConstraintSolver* constraintSolver,btCollisionConfiguration* collisionConfiguration) -:btDynamicsWorld(dispatcher,pairCache,collisionConfiguration), -m_constraintSolver(constraintSolver), -m_ownsConstraintSolver(false), -m_debugDrawer(0), -m_gravity(0,0,-10) -{ - -} - - -btSimpleDynamicsWorld::~btSimpleDynamicsWorld() -{ - if (m_ownsConstraintSolver) - btAlignedFree( m_constraintSolver); -} - -int btSimpleDynamicsWorld::stepSimulation( btScalar timeStep,int maxSubSteps, btScalar fixedTimeStep) -{ - (void)fixedTimeStep; - (void)maxSubSteps; - - - ///apply gravity, predict motion - predictUnconstraintMotion(timeStep); - - btDispatcherInfo& dispatchInfo = getDispatchInfo(); - dispatchInfo.m_timeStep = timeStep; - dispatchInfo.m_stepCount = 0; - dispatchInfo.m_debugDraw = getDebugDrawer(); - - ///perform collision detection - performDiscreteCollisionDetection(); - - ///solve contact constraints - int numManifolds = m_dispatcher1->getNumManifolds(); - if (numManifolds) - { - btPersistentManifold** manifoldPtr = ((btCollisionDispatcher*)m_dispatcher1)->getInternalManifoldPointer(); - - btContactSolverInfo infoGlobal; - infoGlobal.m_timeStep = timeStep; - m_constraintSolver->prepareSolve(0,numManifolds); - m_constraintSolver->solveGroup(0,0,manifoldPtr, numManifolds,0,0,infoGlobal,m_debugDrawer, m_stackAlloc,m_dispatcher1); - m_constraintSolver->allSolved(infoGlobal,m_debugDrawer, m_stackAlloc); - } - - ///integrate transforms - integrateTransforms(timeStep); - - updateAabbs(); - - synchronizeMotionStates(); - - return 1; - -} - - -void btSimpleDynamicsWorld::setGravity(const btVector3& gravity) -{ - m_gravity = gravity; - for ( int i=0;isetGravity(gravity); - } - } -} - -void btSimpleDynamicsWorld::removeRigidBody(btRigidBody* body) -{ - removeCollisionObject(body); -} - -void btSimpleDynamicsWorld::addRigidBody(btRigidBody* body) -{ - body->setGravity(m_gravity); - - if (body->getCollisionShape()) - { - addCollisionObject(body); - } -} - -void btSimpleDynamicsWorld::updateAabbs() -{ - btTransform predictedTrans; - for ( int i=0;iisActive() && (!body->isStaticObject())) - { - btPoint3 minAabb,maxAabb; - colObj->getCollisionShape()->getAabb(colObj->getWorldTransform(), minAabb,maxAabb); - btBroadphaseInterface* bp = getBroadphase(); - bp->setAabb(body->getBroadphaseHandle(),minAabb,maxAabb, m_dispatcher1); - } - } - } -} - -void btSimpleDynamicsWorld::integrateTransforms(btScalar timeStep) -{ - btTransform predictedTrans; - for ( int i=0;iisActive() && (!body->isStaticObject())) - { - body->predictIntegratedTransform(timeStep, predictedTrans); - body->proceedToTransform( predictedTrans); - } - } - } -} - - - -void btSimpleDynamicsWorld::predictUnconstraintMotion(btScalar timeStep) -{ - for ( int i=0;iisStaticObject()) - { - if (body->isActive()) - { - body->applyForces( timeStep); - body->integrateVelocities( timeStep); - body->predictIntegratedTransform(timeStep,body->getInterpolationWorldTransform()); - } - } - } - } -} - - -void btSimpleDynamicsWorld::synchronizeMotionStates() -{ - //todo: iterate over awake simulation islands! - for ( int i=0;igetMotionState()) - { - if (body->getActivationState() != ISLAND_SLEEPING) - { - body->getMotionState()->setWorldTransform(body->getWorldTransform()); - } - } - } - -} - - -void btSimpleDynamicsWorld::setConstraintSolver(btConstraintSolver* solver) -{ - if (m_ownsConstraintSolver) - { - btAlignedFree(m_constraintSolver); - } - m_ownsConstraintSolver = false; - m_constraintSolver = solver; -} - -btConstraintSolver* btSimpleDynamicsWorld::getConstraintSolver() -{ - return m_constraintSolver; -} diff --git a/extern/bullet2/src/BulletDynamics/Dynamics/btSimpleDynamicsWorld.h b/extern/bullet2/src/BulletDynamics/Dynamics/btSimpleDynamicsWorld.h deleted file mode 100644 index 4e38f74a731..00000000000 --- a/extern/bullet2/src/BulletDynamics/Dynamics/btSimpleDynamicsWorld.h +++ /dev/null @@ -1,86 +0,0 @@ -/* -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 BT_SIMPLE_DYNAMICS_WORLD_H -#define BT_SIMPLE_DYNAMICS_WORLD_H - -#include "btDynamicsWorld.h" - -class btDispatcher; -class btOverlappingPairCache; -class btConstraintSolver; - -///btSimpleDynamicsWorld serves as unit-test and to verify more complicated and optimized dynamics worlds. -///Please use btDiscreteDynamicsWorld instead (or btContinuousDynamicsWorld once it is finished). -class btSimpleDynamicsWorld : public btDynamicsWorld -{ -protected: - - btConstraintSolver* m_constraintSolver; - - bool m_ownsConstraintSolver; - - btIDebugDraw* m_debugDrawer; - - void predictUnconstraintMotion(btScalar timeStep); - - void integrateTransforms(btScalar timeStep); - - btVector3 m_gravity; - -public: - - - - ///this btSimpleDynamicsWorld constructor creates dispatcher, broadphase pairCache and constraintSolver - btSimpleDynamicsWorld(btDispatcher* dispatcher,btBroadphaseInterface* pairCache,btConstraintSolver* constraintSolver,btCollisionConfiguration* collisionConfiguration); - - virtual ~btSimpleDynamicsWorld(); - - ///maxSubSteps/fixedTimeStep for interpolation is currently ignored for btSimpleDynamicsWorld, use btDiscreteDynamicsWorld instead - virtual int stepSimulation( btScalar timeStep,int maxSubSteps=1, btScalar fixedTimeStep=btScalar(1.)/btScalar(60.)); - - virtual void setDebugDrawer(btIDebugDraw* debugDrawer) - { - m_debugDrawer = debugDrawer; - }; - - virtual btIDebugDraw* getDebugDrawer() - { - return m_debugDrawer; - } - - virtual void setGravity(const btVector3& gravity); - - virtual void addRigidBody(btRigidBody* body); - - virtual void removeRigidBody(btRigidBody* body); - - virtual void updateAabbs(); - - void synchronizeMotionStates(); - - virtual void setConstraintSolver(btConstraintSolver* solver); - - virtual btConstraintSolver* getConstraintSolver(); - - virtual btDynamicsWorldType getWorldType() const - { - return BT_SIMPLE_DYNAMICS_WORLD; - } - -}; - -#endif //BT_SIMPLE_DYNAMICS_WORLD_H diff --git a/extern/bullet2/src/BulletDynamics/Vehicle/btRaycastVehicle.cpp b/extern/bullet2/src/BulletDynamics/Vehicle/btRaycastVehicle.cpp deleted file mode 100644 index 8dcd6d895e4..00000000000 --- a/extern/bullet2/src/BulletDynamics/Vehicle/btRaycastVehicle.cpp +++ /dev/null @@ -1,738 +0,0 @@ -/* - * Copyright (c) 2005 Erwin Coumans http://continuousphysics.com/Bullet/ - * - * Permission to use, copy, modify, distribute and sell this software - * and its documentation for any purpose is hereby granted without fee, - * provided that the above copyright notice appear in all copies. - * Erwin Coumans makes no representations about the suitability - * of this software for any purpose. - * It is provided "as is" without express or implied warranty. -*/ - -#include "LinearMath/btVector3.h" -#include "btRaycastVehicle.h" - -#include "BulletDynamics/ConstraintSolver/btSolve2LinearConstraint.h" -#include "BulletDynamics/ConstraintSolver/btJacobianEntry.h" -#include "LinearMath/btQuaternion.h" -#include "BulletDynamics/Dynamics/btDynamicsWorld.h" -#include "btVehicleRaycaster.h" -#include "btWheelInfo.h" -#include "LinearMath/btMinMax.h" - - -#include "BulletDynamics/ConstraintSolver/btContactConstraint.h" - - - -static btRigidBody s_fixedObject( 0,0,0); - -btRaycastVehicle::btRaycastVehicle(const btVehicleTuning& tuning,btRigidBody* chassis, btVehicleRaycaster* raycaster ) -: btTypedConstraint(VEHICLE_CONSTRAINT_TYPE), -m_vehicleRaycaster(raycaster), -m_pitchControl(btScalar(0.)) -{ - m_chassisBody = chassis; - m_indexRightAxis = 0; - m_indexUpAxis = 2; - m_indexForwardAxis = 1; - defaultInit(tuning); -} - - -void btRaycastVehicle::defaultInit(const btVehicleTuning& tuning) -{ - (void)tuning; - m_currentVehicleSpeedKmHour = btScalar(0.); - m_steeringValue = btScalar(0.); - -} - - - -btRaycastVehicle::~btRaycastVehicle() -{ -} - - -// -// basically most of the code is general for 2 or 4 wheel vehicles, but some of it needs to be reviewed -// -btWheelInfo& btRaycastVehicle::addWheel( const btVector3& connectionPointCS, const btVector3& wheelDirectionCS0,const btVector3& wheelAxleCS, btScalar suspensionRestLength, btScalar wheelRadius,const btVehicleTuning& tuning, bool isFrontWheel) -{ - - btWheelInfoConstructionInfo ci; - - ci.m_chassisConnectionCS = connectionPointCS; - ci.m_wheelDirectionCS = wheelDirectionCS0; - ci.m_wheelAxleCS = wheelAxleCS; - ci.m_suspensionRestLength = suspensionRestLength; - ci.m_wheelRadius = wheelRadius; - ci.m_suspensionStiffness = tuning.m_suspensionStiffness; - ci.m_wheelsDampingCompression = tuning.m_suspensionCompression; - ci.m_wheelsDampingRelaxation = tuning.m_suspensionDamping; - ci.m_frictionSlip = tuning.m_frictionSlip; - ci.m_bIsFrontWheel = isFrontWheel; - ci.m_maxSuspensionTravelCm = tuning.m_maxSuspensionTravelCm; - - m_wheelInfo.push_back( btWheelInfo(ci)); - - btWheelInfo& wheel = m_wheelInfo[getNumWheels()-1]; - - updateWheelTransformsWS( wheel , false ); - updateWheelTransform(getNumWheels()-1,false); - return wheel; -} - - - - -const btTransform& btRaycastVehicle::getWheelTransformWS( int wheelIndex ) const -{ - assert(wheelIndex < getNumWheels()); - const btWheelInfo& wheel = m_wheelInfo[wheelIndex]; - return wheel.m_worldTransform; - -} - -void btRaycastVehicle::updateWheelTransform( int wheelIndex , bool interpolatedTransform) -{ - - btWheelInfo& wheel = m_wheelInfo[ wheelIndex ]; - updateWheelTransformsWS(wheel,interpolatedTransform); - btVector3 up = -wheel.m_raycastInfo.m_wheelDirectionWS; - const btVector3& right = wheel.m_raycastInfo.m_wheelAxleWS; - btVector3 fwd = up.cross(right); - fwd = fwd.normalize(); -// up = right.cross(fwd); -// up.normalize(); - - //rotate around steering over de wheelAxleWS - btScalar steering = wheel.m_steering; - - btQuaternion steeringOrn(up,steering);//wheel.m_steering); - btMatrix3x3 steeringMat(steeringOrn); - - btQuaternion rotatingOrn(right,-wheel.m_rotation); - btMatrix3x3 rotatingMat(rotatingOrn); - - btMatrix3x3 basis2( - right[0],fwd[0],up[0], - right[1],fwd[1],up[1], - right[2],fwd[2],up[2] - ); - - wheel.m_worldTransform.setBasis(steeringMat * rotatingMat * basis2); - wheel.m_worldTransform.setOrigin( - wheel.m_raycastInfo.m_hardPointWS + wheel.m_raycastInfo.m_wheelDirectionWS * wheel.m_raycastInfo.m_suspensionLength - ); -} - -void btRaycastVehicle::resetSuspension() -{ - - int i; - for (i=0;igetMotionState())) - { - getRigidBody()->getMotionState()->getWorldTransform(chassisTrans); - } - - wheel.m_raycastInfo.m_hardPointWS = chassisTrans( wheel.m_chassisConnectionPointCS ); - wheel.m_raycastInfo.m_wheelDirectionWS = chassisTrans.getBasis() * wheel.m_wheelDirectionCS ; - wheel.m_raycastInfo.m_wheelAxleWS = chassisTrans.getBasis() * wheel.m_wheelAxleCS; -} - -btScalar btRaycastVehicle::rayCast(btWheelInfo& wheel) -{ - updateWheelTransformsWS( wheel,false); - - - btScalar depth = -1; - - btScalar raylen = wheel.getSuspensionRestLength()+wheel.m_wheelsRadius; - - btVector3 rayvector = wheel.m_raycastInfo.m_wheelDirectionWS * (raylen); - const btVector3& source = wheel.m_raycastInfo.m_hardPointWS; - wheel.m_raycastInfo.m_contactPointWS = source + rayvector; - const btVector3& target = wheel.m_raycastInfo.m_contactPointWS; - - btScalar param = btScalar(0.); - - btVehicleRaycaster::btVehicleRaycasterResult rayResults; - - assert(m_vehicleRaycaster); - - void* object = m_vehicleRaycaster->castRay(source,target,rayResults); - - wheel.m_raycastInfo.m_groundObject = 0; - - if (object) - { - param = rayResults.m_distFraction; - depth = raylen * rayResults.m_distFraction; - wheel.m_raycastInfo.m_contactNormalWS = rayResults.m_hitNormalInWorld; - wheel.m_raycastInfo.m_isInContact = true; - - wheel.m_raycastInfo.m_groundObject = &s_fixedObject;//todo for driving on dynamic/movable objects!; - //wheel.m_raycastInfo.m_groundObject = object; - - - btScalar hitDistance = param*raylen; - wheel.m_raycastInfo.m_suspensionLength = hitDistance - wheel.m_wheelsRadius; - //clamp on max suspension travel - - btScalar minSuspensionLength = wheel.getSuspensionRestLength() - wheel.m_maxSuspensionTravelCm*btScalar(0.01); - btScalar maxSuspensionLength = wheel.getSuspensionRestLength()+ wheel.m_maxSuspensionTravelCm*btScalar(0.01); - if (wheel.m_raycastInfo.m_suspensionLength < minSuspensionLength) - { - wheel.m_raycastInfo.m_suspensionLength = minSuspensionLength; - } - if (wheel.m_raycastInfo.m_suspensionLength > maxSuspensionLength) - { - wheel.m_raycastInfo.m_suspensionLength = maxSuspensionLength; - } - - wheel.m_raycastInfo.m_contactPointWS = rayResults.m_hitPointInWorld; - - btScalar denominator= wheel.m_raycastInfo.m_contactNormalWS.dot( wheel.m_raycastInfo.m_wheelDirectionWS ); - - btVector3 chassis_velocity_at_contactPoint; - btVector3 relpos = wheel.m_raycastInfo.m_contactPointWS-getRigidBody()->getCenterOfMassPosition(); - - chassis_velocity_at_contactPoint = getRigidBody()->getVelocityInLocalPoint(relpos); - - btScalar projVel = wheel.m_raycastInfo.m_contactNormalWS.dot( chassis_velocity_at_contactPoint ); - - if ( denominator >= btScalar(-0.1)) - { - wheel.m_suspensionRelativeVelocity = btScalar(0.0); - wheel.m_clippedInvContactDotSuspension = btScalar(1.0) / btScalar(0.1); - } - else - { - btScalar inv = btScalar(-1.) / denominator; - wheel.m_suspensionRelativeVelocity = projVel * inv; - wheel.m_clippedInvContactDotSuspension = inv; - } - - } else - { - //put wheel info as in rest position - wheel.m_raycastInfo.m_suspensionLength = wheel.getSuspensionRestLength(); - wheel.m_suspensionRelativeVelocity = btScalar(0.0); - wheel.m_raycastInfo.m_contactNormalWS = - wheel.m_raycastInfo.m_wheelDirectionWS; - wheel.m_clippedInvContactDotSuspension = btScalar(1.0); - } - - return depth; -} - - -const btTransform& btRaycastVehicle::getChassisWorldTransform() const -{ - /*if (getRigidBody()->getMotionState()) - { - btTransform chassisWorldTrans; - getRigidBody()->getMotionState()->getWorldTransform(chassisWorldTrans); - return chassisWorldTrans; - } - */ - - - return getRigidBody()->getCenterOfMassTransform(); -} - - -void btRaycastVehicle::updateVehicle( btScalar step ) -{ - { - for (int i=0;igetLinearVelocity().length(); - - const btTransform& chassisTrans = getChassisWorldTransform(); - - btVector3 forwardW ( - chassisTrans.getBasis()[0][m_indexForwardAxis], - chassisTrans.getBasis()[1][m_indexForwardAxis], - chassisTrans.getBasis()[2][m_indexForwardAxis]); - - if (forwardW.dot(getRigidBody()->getLinearVelocity()) < btScalar(0.)) - { - m_currentVehicleSpeedKmHour *= btScalar(-1.); - } - - // - // simulate suspension - // - - int i=0; - for (i=0;i gMaxSuspensionForce) - { - suspensionForce = gMaxSuspensionForce; - } - btVector3 impulse = wheel.m_raycastInfo.m_contactNormalWS * suspensionForce * step; - btVector3 relpos = wheel.m_raycastInfo.m_contactPointWS - getRigidBody()->getCenterOfMassPosition(); - - getRigidBody()->applyImpulse(impulse, relpos); - - } - - - - updateFriction( step); - - - for (i=0;igetCenterOfMassPosition(); - btVector3 vel = getRigidBody()->getVelocityInLocalPoint( relpos ); - - if (wheel.m_raycastInfo.m_isInContact) - { - const btTransform& chassisWorldTransform = getChassisWorldTransform(); - - btVector3 fwd ( - chassisWorldTransform.getBasis()[0][m_indexForwardAxis], - chassisWorldTransform.getBasis()[1][m_indexForwardAxis], - chassisWorldTransform.getBasis()[2][m_indexForwardAxis]); - - btScalar proj = fwd.dot(wheel.m_raycastInfo.m_contactNormalWS); - fwd -= wheel.m_raycastInfo.m_contactNormalWS * proj; - - btScalar proj2 = fwd.dot(vel); - - wheel.m_deltaRotation = (proj2 * step) / (wheel.m_wheelsRadius); - wheel.m_rotation += wheel.m_deltaRotation; - - } else - { - wheel.m_rotation += wheel.m_deltaRotation; - } - - wheel.m_deltaRotation *= btScalar(0.99);//damping of rotation when not in contact - - } - - - -} - - -void btRaycastVehicle::setSteeringValue(btScalar steering,int wheel) -{ - assert(wheel>=0 && wheel < getNumWheels()); - - btWheelInfo& wheelInfo = getWheelInfo(wheel); - wheelInfo.m_steering = steering; -} - - - -btScalar btRaycastVehicle::getSteeringValue(int wheel) const -{ - return getWheelInfo(wheel).m_steering; -} - - -void btRaycastVehicle::applyEngineForce(btScalar force, int wheel) -{ - assert(wheel>=0 && wheel < getNumWheels()); - btWheelInfo& wheelInfo = getWheelInfo(wheel); - wheelInfo.m_engineForce = force; -} - - -const btWheelInfo& btRaycastVehicle::getWheelInfo(int index) const -{ - btAssert((index >= 0) && (index < getNumWheels())); - - return m_wheelInfo[index]; -} - -btWheelInfo& btRaycastVehicle::getWheelInfo(int index) -{ - btAssert((index >= 0) && (index < getNumWheels())); - - return m_wheelInfo[index]; -} - -void btRaycastVehicle::setBrake(btScalar brake,int wheelIndex) -{ - btAssert((wheelIndex >= 0) && (wheelIndex < getNumWheels())); - getWheelInfo(wheelIndex).m_brake = brake; -} - - -void btRaycastVehicle::updateSuspension(btScalar deltaTime) -{ - (void)deltaTime; - - btScalar chassisMass = btScalar(1.) / m_chassisBody->getInvMass(); - - for (int w_it=0; w_itcomputeImpulseDenominator(frictionPosWorld,frictionDirectionWorld); - btScalar denom1 = body1->computeImpulseDenominator(frictionPosWorld,frictionDirectionWorld); - btScalar relaxation = 1.f; - m_jacDiagABInv = relaxation/(denom0+denom1); - } - - - -}; - -btScalar calcRollingFriction(btWheelContactPoint& contactPoint) -{ - - btScalar j1=0.f; - - const btVector3& contactPosWorld = contactPoint.m_frictionPositionWorld; - - btVector3 rel_pos1 = contactPosWorld - contactPoint.m_body0->getCenterOfMassPosition(); - btVector3 rel_pos2 = contactPosWorld - contactPoint.m_body1->getCenterOfMassPosition(); - - btScalar maxImpulse = contactPoint.m_maxImpulse; - - btVector3 vel1 = contactPoint.m_body0->getVelocityInLocalPoint(rel_pos1); - btVector3 vel2 = contactPoint.m_body1->getVelocityInLocalPoint(rel_pos2); - btVector3 vel = vel1 - vel2; - - btScalar vrel = contactPoint.m_frictionDirectionWorld.dot(vel); - - // calculate j that moves us to zero relative velocity - j1 = -vrel * contactPoint.m_jacDiagABInv; - btSetMin(j1, maxImpulse); - btSetMax(j1, -maxImpulse); - - return j1; -} - - - - -btScalar sideFrictionStiffness2 = btScalar(1.0); -void btRaycastVehicle::updateFriction(btScalar timeStep) -{ - - //calculate the impulse, so that the wheels don't move sidewards - int numWheel = getNumWheels(); - if (!numWheel) - return; - - - void* mem = btAlignedAlloc(numWheel*sizeof(btVector3),16); - btVector3* forwardWS = new (mem)btVector3[numWheel]; - mem = btAlignedAlloc(numWheel*sizeof(btVector3),16); - btVector3* axle = new (mem)btVector3[numWheel]; - mem = btAlignedAlloc(numWheel*sizeof(btScalar),16); - btScalar* forwardImpulse = new (mem)btScalar[numWheel]; - mem = btAlignedAlloc(numWheel*sizeof(btScalar),16); - btScalar* sideImpulse = new(mem) btScalar[numWheel]; - - int numWheelsOnGround = 0; - - - //collapse all those loops into one! - for (int i=0;i maximpSquared) - { - sliding = true; - - btScalar factor = maximp / btSqrt(impulseSquared); - - m_wheelInfo[wheel].m_skidInfo *= factor; - } - } - - } - } - - - - - if (sliding) - { - for (int wheel = 0;wheel < getNumWheels(); wheel++) - { - if (sideImpulse[wheel] != btScalar(0.)) - { - if (m_wheelInfo[wheel].m_skidInfo< btScalar(1.)) - { - forwardImpulse[wheel] *= m_wheelInfo[wheel].m_skidInfo; - sideImpulse[wheel] *= m_wheelInfo[wheel].m_skidInfo; - } - } - } - } - - // apply the impulses - { - for (int wheel = 0;wheelgetCenterOfMassPosition(); - - if (forwardImpulse[wheel] != btScalar(0.)) - { - m_chassisBody->applyImpulse(forwardWS[wheel]*(forwardImpulse[wheel]),rel_pos); - } - if (sideImpulse[wheel] != btScalar(0.)) - { - class btRigidBody* groundObject = (class btRigidBody*) m_wheelInfo[wheel].m_raycastInfo.m_groundObject; - - btVector3 rel_pos2 = wheelInfo.m_raycastInfo.m_contactPointWS - - groundObject->getCenterOfMassPosition(); - - - btVector3 sideImp = axle[wheel] * sideImpulse[wheel]; - - rel_pos[2] *= wheelInfo.m_rollInfluence; - m_chassisBody->applyImpulse(sideImp,rel_pos); - - //apply friction impulse on the ground - groundObject->applyImpulse(-sideImp,rel_pos2); - } - } - } - - btAlignedFree(forwardWS); - btAlignedFree(axle); - btAlignedFree(forwardImpulse); - btAlignedFree(sideImpulse); -} - - -void* btDefaultVehicleRaycaster::castRay(const btVector3& from,const btVector3& to, btVehicleRaycasterResult& result) -{ -// RayResultCallback& resultCallback; - - btCollisionWorld::ClosestRayResultCallback rayCallback(from,to); - - m_dynamicsWorld->rayTest(from, to, rayCallback); - - if (rayCallback.HasHit()) - { - - btRigidBody* body = btRigidBody::upcast(rayCallback.m_collisionObject); - if (body) - { - result.m_hitPointInWorld = rayCallback.m_hitPointWorld; - result.m_hitNormalInWorld = rayCallback.m_hitNormalWorld; - result.m_hitNormalInWorld.normalize(); - result.m_distFraction = rayCallback.m_closestHitFraction; - return body; - } - } - return 0; -} diff --git a/extern/bullet2/src/BulletDynamics/Vehicle/btRaycastVehicle.h b/extern/bullet2/src/BulletDynamics/Vehicle/btRaycastVehicle.h deleted file mode 100644 index a84b185e947..00000000000 --- a/extern/bullet2/src/BulletDynamics/Vehicle/btRaycastVehicle.h +++ /dev/null @@ -1,201 +0,0 @@ -/* - * Copyright (c) 2005 Erwin Coumans http://continuousphysics.com/Bullet/ - * - * Permission to use, copy, modify, distribute and sell this software - * and its documentation for any purpose is hereby granted without fee, - * provided that the above copyright notice appear in all copies. - * Erwin Coumans makes no representations about the suitability - * of this software for any purpose. - * It is provided "as is" without express or implied warranty. -*/ -#ifndef RAYCASTVEHICLE_H -#define RAYCASTVEHICLE_H - -#include "BulletDynamics/Dynamics/btRigidBody.h" -#include "BulletDynamics/ConstraintSolver/btTypedConstraint.h" -#include "btVehicleRaycaster.h" -class btDynamicsWorld; -#include "LinearMath/btAlignedObjectArray.h" -#include "btWheelInfo.h" - -class btVehicleTuning; - -///rayCast vehicle, very special constraint that turn a rigidbody into a vehicle. -class btRaycastVehicle : public btTypedConstraint -{ -public: - class btVehicleTuning - { - public: - - btVehicleTuning() - :m_suspensionStiffness(btScalar(5.88)), - m_suspensionCompression(btScalar(0.83)), - m_suspensionDamping(btScalar(0.88)), - m_maxSuspensionTravelCm(btScalar(500.)), - m_frictionSlip(btScalar(10.5)) - { - } - btScalar m_suspensionStiffness; - btScalar m_suspensionCompression; - btScalar m_suspensionDamping; - btScalar m_maxSuspensionTravelCm; - btScalar m_frictionSlip; - - }; -private: - - btScalar m_tau; - btScalar m_damping; - btVehicleRaycaster* m_vehicleRaycaster; - btScalar m_pitchControl; - btScalar m_steeringValue; - btScalar m_currentVehicleSpeedKmHour; - - btRigidBody* m_chassisBody; - - int m_indexRightAxis; - int m_indexUpAxis; - int m_indexForwardAxis; - - void defaultInit(const btVehicleTuning& tuning); - -public: - - //constructor to create a car from an existing rigidbody - btRaycastVehicle(const btVehicleTuning& tuning,btRigidBody* chassis, btVehicleRaycaster* raycaster ); - - virtual ~btRaycastVehicle() ; - - - const btTransform& getChassisWorldTransform() const; - - btScalar rayCast(btWheelInfo& wheel); - - virtual void updateVehicle(btScalar step); - - void resetSuspension(); - - btScalar getSteeringValue(int wheel) const; - - void setSteeringValue(btScalar steering,int wheel); - - - void applyEngineForce(btScalar force, int wheel); - - const btTransform& getWheelTransformWS( int wheelIndex ) const; - - void updateWheelTransform( int wheelIndex, bool interpolatedTransform = true ); - - void setRaycastWheelInfo( int wheelIndex , bool isInContact, const btVector3& hitPoint, const btVector3& hitNormal,btScalar depth); - - btWheelInfo& addWheel( const btVector3& connectionPointCS0, const btVector3& wheelDirectionCS0,const btVector3& wheelAxleCS,btScalar suspensionRestLength,btScalar wheelRadius,const btVehicleTuning& tuning, bool isFrontWheel); - - inline int getNumWheels() const { - return int (m_wheelInfo.size()); - } - - btAlignedObjectArray m_wheelInfo; - - - const btWheelInfo& getWheelInfo(int index) const; - - btWheelInfo& getWheelInfo(int index); - - void updateWheelTransformsWS(btWheelInfo& wheel , bool interpolatedTransform = true); - - - void setBrake(btScalar brake,int wheelIndex); - - void setPitchControl(btScalar pitch) - { - m_pitchControl = pitch; - } - - void updateSuspension(btScalar deltaTime); - - void updateFriction(btScalar timeStep); - - - - inline btRigidBody* getRigidBody() - { - return m_chassisBody; - } - - const btRigidBody* getRigidBody() const - { - return m_chassisBody; - } - - inline int getRightAxis() const - { - return m_indexRightAxis; - } - inline int getUpAxis() const - { - return m_indexUpAxis; - } - - inline int getForwardAxis() const - { - return m_indexForwardAxis; - } - - - ///Worldspace forward vector - btVector3 getForwardVector() const - { - const btTransform& chassisTrans = getChassisWorldTransform(); - - btVector3 forwardW ( - chassisTrans.getBasis()[0][m_indexForwardAxis], - chassisTrans.getBasis()[1][m_indexForwardAxis], - chassisTrans.getBasis()[2][m_indexForwardAxis]); - - return forwardW; - } - - ///Velocity of vehicle (positive if velocity vector has same direction as foward vector) - btScalar getCurrentSpeedKmHour() const - { - return m_currentVehicleSpeedKmHour; - } - - virtual void setCoordinateSystem(int rightIndex,int upIndex,int forwardIndex) - { - m_indexRightAxis = rightIndex; - m_indexUpAxis = upIndex; - m_indexForwardAxis = forwardIndex; - } - - virtual void buildJacobian() - { - //not yet - } - - virtual void solveConstraint(btScalar timeStep) - { - (void)timeStep; - //not yet - } - - -}; - -class btDefaultVehicleRaycaster : public btVehicleRaycaster -{ - btDynamicsWorld* m_dynamicsWorld; -public: - btDefaultVehicleRaycaster(btDynamicsWorld* world) - :m_dynamicsWorld(world) - { - } - - virtual void* castRay(const btVector3& from,const btVector3& to, btVehicleRaycasterResult& result); - -}; - - -#endif //RAYCASTVEHICLE_H - diff --git a/extern/bullet2/src/BulletDynamics/Vehicle/btVehicleRaycaster.h b/extern/bullet2/src/BulletDynamics/Vehicle/btVehicleRaycaster.h deleted file mode 100644 index 5112ce6d420..00000000000 --- a/extern/bullet2/src/BulletDynamics/Vehicle/btVehicleRaycaster.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (c) 2005 Erwin Coumans http://continuousphysics.com/Bullet/ - * - * Permission to use, copy, modify, distribute and sell this software - * and its documentation for any purpose is hereby granted without fee, - * provided that the above copyright notice appear in all copies. - * Erwin Coumans makes no representations about the suitability - * of this software for any purpose. - * It is provided "as is" without express or implied warranty. -*/ -#ifndef VEHICLE_RAYCASTER_H -#define VEHICLE_RAYCASTER_H - -#include "LinearMath/btVector3.h" - -/// btVehicleRaycaster is provides interface for between vehicle simulation and raycasting -struct btVehicleRaycaster -{ -virtual ~btVehicleRaycaster() -{ -} - struct btVehicleRaycasterResult - { - btVehicleRaycasterResult() :m_distFraction(btScalar(-1.)){}; - btVector3 m_hitPointInWorld; - btVector3 m_hitNormalInWorld; - btScalar m_distFraction; - }; - - virtual void* castRay(const btVector3& from,const btVector3& to, btVehicleRaycasterResult& result) = 0; - -}; - -#endif //VEHICLE_RAYCASTER_H - diff --git a/extern/bullet2/src/BulletDynamics/Vehicle/btWheelInfo.cpp b/extern/bullet2/src/BulletDynamics/Vehicle/btWheelInfo.cpp deleted file mode 100644 index ef93c16fffc..00000000000 --- a/extern/bullet2/src/BulletDynamics/Vehicle/btWheelInfo.cpp +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (c) 2005 Erwin Coumans http://continuousphysics.com/Bullet/ - * - * Permission to use, copy, modify, distribute and sell this software - * and its documentation for any purpose is hereby granted without fee, - * provided that the above copyright notice appear in all copies. - * Erwin Coumans makes no representations about the suitability - * of this software for any purpose. - * It is provided "as is" without express or implied warranty. -*/ -#include "btWheelInfo.h" -#include "BulletDynamics/Dynamics/btRigidBody.h" // for pointvelocity - - -btScalar btWheelInfo::getSuspensionRestLength() const -{ - - return m_suspensionRestLength1; - -} - -void btWheelInfo::updateWheel(const btRigidBody& chassis,RaycastInfo& raycastInfo) -{ - (void)raycastInfo; - - - if (m_raycastInfo.m_isInContact) - - { - btScalar project= m_raycastInfo.m_contactNormalWS.dot( m_raycastInfo.m_wheelDirectionWS ); - btVector3 chassis_velocity_at_contactPoint; - btVector3 relpos = m_raycastInfo.m_contactPointWS - chassis.getCenterOfMassPosition(); - chassis_velocity_at_contactPoint = chassis.getVelocityInLocalPoint( relpos ); - btScalar projVel = m_raycastInfo.m_contactNormalWS.dot( chassis_velocity_at_contactPoint ); - if ( project >= btScalar(-0.1)) - { - m_suspensionRelativeVelocity = btScalar(0.0); - m_clippedInvContactDotSuspension = btScalar(1.0) / btScalar(0.1); - } - else - { - btScalar inv = btScalar(-1.) / project; - m_suspensionRelativeVelocity = projVel * inv; - m_clippedInvContactDotSuspension = inv; - } - - } - - else // Not in contact : position wheel in a nice (rest length) position - { - m_raycastInfo.m_suspensionLength = this->getSuspensionRestLength(); - m_suspensionRelativeVelocity = btScalar(0.0); - m_raycastInfo.m_contactNormalWS = -m_raycastInfo.m_wheelDirectionWS; - m_clippedInvContactDotSuspension = btScalar(1.0); - } -} diff --git a/extern/bullet2/src/BulletDynamics/Vehicle/btWheelInfo.h b/extern/bullet2/src/BulletDynamics/Vehicle/btWheelInfo.h deleted file mode 100644 index ac2729f4fd7..00000000000 --- a/extern/bullet2/src/BulletDynamics/Vehicle/btWheelInfo.h +++ /dev/null @@ -1,116 +0,0 @@ -/* - * Copyright (c) 2005 Erwin Coumans http://continuousphysics.com/Bullet/ - * - * Permission to use, copy, modify, distribute and sell this software - * and its documentation for any purpose is hereby granted without fee, - * provided that the above copyright notice appear in all copies. - * Erwin Coumans makes no representations about the suitability - * of this software for any purpose. - * It is provided "as is" without express or implied warranty. -*/ -#ifndef WHEEL_INFO_H -#define WHEEL_INFO_H - -#include "LinearMath/btVector3.h" -#include "LinearMath/btTransform.h" - -class btRigidBody; - -struct btWheelInfoConstructionInfo -{ - btVector3 m_chassisConnectionCS; - btVector3 m_wheelDirectionCS; - btVector3 m_wheelAxleCS; - btScalar m_suspensionRestLength; - btScalar m_maxSuspensionTravelCm; - btScalar m_wheelRadius; - - btScalar m_suspensionStiffness; - btScalar m_wheelsDampingCompression; - btScalar m_wheelsDampingRelaxation; - btScalar m_frictionSlip; - bool m_bIsFrontWheel; - -}; - -/// btWheelInfo contains information per wheel about friction and suspension. -struct btWheelInfo -{ - struct RaycastInfo - { - //set by raycaster - btVector3 m_contactNormalWS;//contactnormal - btVector3 m_contactPointWS;//raycast hitpoint - btScalar m_suspensionLength; - btVector3 m_hardPointWS;//raycast starting point - btVector3 m_wheelDirectionWS; //direction in worldspace - btVector3 m_wheelAxleWS; // axle in worldspace - bool m_isInContact; - void* m_groundObject; //could be general void* ptr - }; - - RaycastInfo m_raycastInfo; - - btTransform m_worldTransform; - - btVector3 m_chassisConnectionPointCS; //const - btVector3 m_wheelDirectionCS;//const - btVector3 m_wheelAxleCS; // const or modified by steering - btScalar m_suspensionRestLength1;//const - btScalar m_maxSuspensionTravelCm; - btScalar getSuspensionRestLength() const; - btScalar m_wheelsRadius;//const - btScalar m_suspensionStiffness;//const - btScalar m_wheelsDampingCompression;//const - btScalar m_wheelsDampingRelaxation;//const - btScalar m_frictionSlip; - btScalar m_steering; - btScalar m_rotation; - btScalar m_deltaRotation; - btScalar m_rollInfluence; - - btScalar m_engineForce; - - btScalar m_brake; - - bool m_bIsFrontWheel; - - void* m_clientInfo;//can be used to store pointer to sync transforms... - - btWheelInfo(btWheelInfoConstructionInfo& ci) - - { - - m_suspensionRestLength1 = ci.m_suspensionRestLength; - m_maxSuspensionTravelCm = ci.m_maxSuspensionTravelCm; - - m_wheelsRadius = ci.m_wheelRadius; - m_suspensionStiffness = ci.m_suspensionStiffness; - m_wheelsDampingCompression = ci.m_wheelsDampingCompression; - m_wheelsDampingRelaxation = ci.m_wheelsDampingRelaxation; - m_chassisConnectionPointCS = ci.m_chassisConnectionCS; - m_wheelDirectionCS = ci.m_wheelDirectionCS; - m_wheelAxleCS = ci.m_wheelAxleCS; - m_frictionSlip = ci.m_frictionSlip; - m_steering = btScalar(0.); - m_engineForce = btScalar(0.); - m_rotation = btScalar(0.); - m_deltaRotation = btScalar(0.); - m_brake = btScalar(0.); - m_rollInfluence = btScalar(0.1); - m_bIsFrontWheel = ci.m_bIsFrontWheel; - - } - - void updateWheel(const btRigidBody& chassis,RaycastInfo& raycastInfo); - - btScalar m_clippedInvContactDotSuspension; - btScalar m_suspensionRelativeVelocity; - //calculated by suspension - btScalar m_wheelsSuspensionForce; - btScalar m_skidInfo; - -}; - -#endif //WHEEL_INFO_H - diff --git a/extern/bullet2/src/BulletDynamics/ibmsdk/Makefile b/extern/bullet2/src/BulletDynamics/ibmsdk/Makefile deleted file mode 100644 index b599a0fd9a1..00000000000 --- a/extern/bullet2/src/BulletDynamics/ibmsdk/Makefile +++ /dev/null @@ -1,45 +0,0 @@ -#### Source code Dirs -VPATH = \ -../ConstraintSolver \ -../Dynamics \ -../Vehicle - -ROOT = ../../.. - -#### Library -LIBRARY_ppu = bulletdynamics.a - -#### Compiler flags -CPPFLAGS = \ --DUSE_LIBSPE2 \ --I../ConstraintSolver \ --I../Dynamics \ --I../Vehicle \ --I$(ROOT)/src \ --I$(SDKINC) - -#### Optimization level flags -#CC_OPT_LEVEL = $(CC_OPT_LEVEL_DEBUG) -CC_OPT_LEVEL = -O3 - -##### Objects to be archived in lib - -OBJS = \ -btContactConstraint.o \ -btGeneric6DofConstraint.o \ -btHingeConstraint.o \ -btPoint2PointConstraint.o \ -btSequentialImpulseConstraintSolver.o \ -btSolve2LinearConstraint.o \ -btTypedConstraint.o \ -btDiscreteDynamicsWorld.o \ -btRigidBody.o \ -btSimpleDynamicsWorld.o \ -btRaycastVehicle.o \ -btWheelInfo.o -#### Install directories -INSTALL_DIR = $(ROOT)/lib/ibmsdk -INSTALL_FILES = $(LIBRARY_ppu) -CELL_TOP ?= /opt/ibm/cell-sdk/prototype - -include $(CELL_TOP)/make.footer diff --git a/extern/bullet2/src/CMakeLists.txt b/extern/bullet2/src/CMakeLists.txt deleted file mode 100644 index 0ae1a7ab6ab..00000000000 --- a/extern/bullet2/src/CMakeLists.txt +++ /dev/null @@ -1 +0,0 @@ -SUBDIRS( BulletCollision BulletDynamics LinearMath ) diff --git a/extern/bullet2/src/LinearMath/CMakeLists.txt b/extern/bullet2/src/LinearMath/CMakeLists.txt deleted file mode 100644 index 82393547bfb..00000000000 --- a/extern/bullet2/src/LinearMath/CMakeLists.txt +++ /dev/null @@ -1,11 +0,0 @@ - -INCLUDE_DIRECTORIES( -${BULLET_PHYSICS_SOURCE_DIR}/src } -) - -ADD_LIBRARY(LibLinearMath -btQuickprof.cpp -btGeometryUtil.cpp -btAlignedAllocator.cpp -) - diff --git a/extern/bullet2/src/LinearMath/btAabbUtil2.h b/extern/bullet2/src/LinearMath/btAabbUtil2.h deleted file mode 100644 index 9b320961ba1..00000000000 --- a/extern/bullet2/src/LinearMath/btAabbUtil2.h +++ /dev/null @@ -1,125 +0,0 @@ -/* -Copyright (c) 2003-2006 Gino van den Bergen / 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 AABB_UTIL2 -#define AABB_UTIL2 - -#include "btVector3.h" -#include "btMinMax.h" - - - - -/// conservative test for overlap between two aabbs -SIMD_FORCE_INLINE bool TestAabbAgainstAabb2(const btVector3 &aabbMin1, const btVector3 &aabbMax1, - const btVector3 &aabbMin2, const btVector3 &aabbMax2) -{ - bool overlap = true; - overlap = (aabbMin1[0] > aabbMax2[0] || aabbMax1[0] < aabbMin2[0]) ? false : overlap; - overlap = (aabbMin1[2] > aabbMax2[2] || aabbMax1[2] < aabbMin2[2]) ? false : overlap; - overlap = (aabbMin1[1] > aabbMax2[1] || aabbMax1[1] < aabbMin2[1]) ? false : overlap; - return overlap; -} - -/// conservative test for overlap between triangle and aabb -SIMD_FORCE_INLINE bool TestTriangleAgainstAabb2(const btVector3 *vertices, - const btVector3 &aabbMin, const btVector3 &aabbMax) -{ - const btVector3 &p1 = vertices[0]; - const btVector3 &p2 = vertices[1]; - const btVector3 &p3 = vertices[2]; - - if (btMin(btMin(p1[0], p2[0]), p3[0]) > aabbMax[0]) return false; - if (btMax(btMax(p1[0], p2[0]), p3[0]) < aabbMin[0]) return false; - - if (btMin(btMin(p1[2], p2[2]), p3[2]) > aabbMax[2]) return false; - if (btMax(btMax(p1[2], p2[2]), p3[2]) < aabbMin[2]) return false; - - if (btMin(btMin(p1[1], p2[1]), p3[1]) > aabbMax[1]) return false; - if (btMax(btMax(p1[1], p2[1]), p3[1]) < aabbMin[1]) return false; - return true; -} - - -SIMD_FORCE_INLINE int btOutcode(const btVector3& p,const btVector3& halfExtent) -{ - return (p.getX() < -halfExtent.getX() ? 0x01 : 0x0) | - (p.getX() > halfExtent.getX() ? 0x08 : 0x0) | - (p.getY() < -halfExtent.getY() ? 0x02 : 0x0) | - (p.getY() > halfExtent.getY() ? 0x10 : 0x0) | - (p.getZ() < -halfExtent.getZ() ? 0x4 : 0x0) | - (p.getZ() > halfExtent.getZ() ? 0x20 : 0x0); -} - - -SIMD_FORCE_INLINE bool btRayAabb(const btVector3& rayFrom, - const btVector3& rayTo, - const btVector3& aabbMin, - const btVector3& aabbMax, - btScalar& param, btVector3& normal) -{ - btVector3 aabbHalfExtent = (aabbMax-aabbMin)* btScalar(0.5); - btVector3 aabbCenter = (aabbMax+aabbMin)* btScalar(0.5); - btVector3 source = rayFrom - aabbCenter; - btVector3 target = rayTo - aabbCenter; - int sourceOutcode = btOutcode(source,aabbHalfExtent); - int targetOutcode = btOutcode(target,aabbHalfExtent); - if ((sourceOutcode & targetOutcode) == 0x0) - { - btScalar lambda_enter = btScalar(0.0); - btScalar lambda_exit = param; - btVector3 r = target - source; - int i; - btScalar normSign = 1; - btVector3 hitNormal(0,0,0); - int bit=1; - - for (int j=0;j<2;j++) - { - for (i = 0; i != 3; ++i) - { - if (sourceOutcode & bit) - { - btScalar lambda = (-source[i] - aabbHalfExtent[i]*normSign) / r[i]; - if (lambda_enter <= lambda) - { - lambda_enter = lambda; - hitNormal.setValue(0,0,0); - hitNormal[i] = normSign; - } - } - else if (targetOutcode & bit) - { - btScalar lambda = (-source[i] - aabbHalfExtent[i]*normSign) / r[i]; - btSetMin(lambda_exit, lambda); - } - bit<<=1; - } - normSign = btScalar(-1.); - } - if (lambda_enter <= lambda_exit) - { - param = lambda_enter; - normal = hitNormal; - return true; - } - } - return false; -} - - -#endif - diff --git a/extern/bullet2/src/LinearMath/btAlignedAllocator.cpp b/extern/bullet2/src/LinearMath/btAlignedAllocator.cpp deleted file mode 100644 index 6b33ddbb8cf..00000000000 --- a/extern/bullet2/src/LinearMath/btAlignedAllocator.cpp +++ /dev/null @@ -1,155 +0,0 @@ -/* -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 "btAlignedAllocator.h" - -int gNumAlignedAllocs = 0; -int gNumAlignedFree = 0; -int gTotalBytesAlignedAllocs = 0;//detect memory leaks - -#ifdef BT_DEBUG_MEMORY_ALLOCATIONS -//this generic allocator provides the total allocated number of bytes -#include - -void* btAlignedAllocInternal (size_t size, int alignment,int line,char* filename) -{ - void *ret; - char *real; - unsigned long offset; - - gTotalBytesAlignedAllocs += size; - gNumAlignedAllocs++; - - printf("allocation#%d from %s,line %d, size %d\n",gNumAlignedAllocs,filename,line,size); - real = (char *)malloc(size + 2*sizeof(void *) + (alignment-1)); - if (real) { - offset = (alignment - (unsigned long)(real + 2*sizeof(void *))) & -(alignment-1); - ret = (void *)((real + 2*sizeof(void *)) + offset); - *((void **)(ret)-1) = (void *)(real); - *((int*)(ret)-2) = size; - - } else { - ret = (void *)(real);//?? - } - int* ptr = (int*)ret; - *ptr = 12; - return (ret); -} -#include -void btAlignedFreeInternal (void* ptr,int line,char* filename) -{ - - void* real; - gNumAlignedFree++; - - if (ptr) { - real = *((void **)(ptr)-1); - int size = *((int*)(ptr)-2); - gTotalBytesAlignedAllocs -= size; - - printf("free #%d from %s,line %d, size %d\n",gNumAlignedFree,filename,line,size); - - free(real); - } else - { - printf("NULL ptr\n"); - } -} - -#else //BT_DEBUG_MEMORY_ALLOCATIONS - - -#if defined (BT_HAS_ALIGNED_ALLOCATOR) - - - - - -#include -void* btAlignedAllocInternal (size_t size, int alignment) -{ - gNumAlignedAllocs++; - - void* ptr = _aligned_malloc(size,alignment); -// printf("btAlignedAllocInternal %d, %x\n",size,ptr); - return ptr; -} - -void btAlignedFreeInternal (void* ptr) -{ - gNumAlignedFree++; -// printf("btAlignedFreeInternal %x\n",ptr); - _aligned_free(ptr); -} - -#else - -#ifdef __CELLOS_LV2__ - -#include - - - -void* btAlignedAllocInternal (size_t size, int alignment) -{ - gNumAlignedAllocs++; - return memalign(alignment, size); -} - -void btAlignedFreeInternal (void* ptr) -{ - gNumAlignedFree++; - free(ptr); -} - -#else - -void* btAlignedAllocInternal (size_t size, int alignment) -{ - void *ret; - char *real; - unsigned long offset; - - gNumAlignedAllocs++; - - real = (char *)malloc(size + sizeof(void *) + (alignment-1)); - if (real) { - offset = (alignment - (unsigned long)(real + sizeof(void *))) & (alignment-1); - ret = (void *)((real + sizeof(void *)) + offset); - *((void **)(ret)-1) = (void *)(real); - } else { - ret = (void *)(real); - } - return (ret); -} - -void btAlignedFreeInternal (void* ptr) -{ - - void* real; - gNumAlignedFree++; - - if (ptr) { - real = *((void **)(ptr)-1); - free(real); - } -} -#endif // - -#endif - -#endif //BT_DEBUG_MEMORY_ALLOCATIONS - diff --git a/extern/bullet2/src/LinearMath/btAlignedAllocator.h b/extern/bullet2/src/LinearMath/btAlignedAllocator.h deleted file mode 100644 index 2b48e79e497..00000000000 --- a/extern/bullet2/src/LinearMath/btAlignedAllocator.h +++ /dev/null @@ -1,94 +0,0 @@ -/* -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 BT_ALIGNED_ALLOCATOR -#define BT_ALIGNED_ALLOCATOR - -///we probably replace this with our own aligned memory allocator -///so we replace _aligned_malloc and _aligned_free with our own -///that is better portable and more predictable - -#include "btScalar.h" -//#define BT_DEBUG_MEMORY_ALLOCATIONS 1 -#ifdef BT_DEBUG_MEMORY_ALLOCATIONS - -#define btAlignedAlloc(a,b) \ - btAlignedAllocInternal(a,b,__LINE__,__FILE__) - -#define btAlignedFree(ptr) \ - btAlignedFreeInternal(ptr,__LINE__,__FILE__) - -void* btAlignedAllocInternal (size_t size, int alignment,int line,char* filename); - -void btAlignedFreeInternal (void* ptr,int line,char* filename); - -#else - void* btAlignedAllocInternal (size_t size, int alignment); - void btAlignedFreeInternal (void* ptr); - - #define btAlignedAlloc(a,b) btAlignedAllocInternal(a,b) - #define btAlignedFree(ptr) btAlignedFreeInternal(ptr) -#endif -typedef int size_type; - - -template < typename T , unsigned Alignment > -class btAlignedAllocator { - - typedef btAlignedAllocator< T , Alignment > self_type; - -public: - - //just going down a list: - btAlignedAllocator() {} - /* - btAlignedAllocator( const self_type & ) {} - */ - - template < typename Other > - btAlignedAllocator( const btAlignedAllocator< Other , Alignment > & ) {} - - typedef const T* const_pointer; - typedef const T& const_reference; - typedef T* pointer; - typedef T& reference; - typedef T value_type; - - pointer address ( reference ref ) const { return &ref; } - const_pointer address ( const_reference ref ) const { return &ref; } - pointer allocate ( size_type n , const_pointer * hint = 0 ) { - (void)hint; - return reinterpret_cast< pointer >(btAlignedAlloc( sizeof(value_type) * n , Alignment )); - } - void construct ( pointer ptr , const value_type & value ) { new (ptr) value_type( value ); } - void deallocate( pointer ptr ) { - btAlignedFree( reinterpret_cast< void * >( ptr ) ); - } - void destroy ( pointer ptr ) { ptr->~value_type(); } - - - template < typename O > struct rebind { - typedef btAlignedAllocator< O , Alignment > other; - }; - template < typename O > - self_type & operator=( const btAlignedAllocator< O , Alignment > & ) { return *this; } - - friend bool operator==( const self_type & , const self_type & ) { return true; } -}; - - - -#endif //BT_ALIGNED_ALLOCATOR - diff --git a/extern/bullet2/src/LinearMath/btAlignedObjectArray.h b/extern/bullet2/src/LinearMath/btAlignedObjectArray.h deleted file mode 100644 index 66911316fbb..00000000000 --- a/extern/bullet2/src/LinearMath/btAlignedObjectArray.h +++ /dev/null @@ -1,386 +0,0 @@ -/* -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 BT_OBJECT_ARRAY__ -#define BT_OBJECT_ARRAY__ - -#include "btScalar.h" // has definitions like SIMD_FORCE_INLINE -#include "btAlignedAllocator.h" - -///If the platform doesn't support placement new, you can disable BT_USE_PLACEMENT_NEW -///then the btAlignedObjectArray doesn't support objects with virtual methods, and non-trivial constructors/destructors -///You can enable BT_USE_MEMCPY, then swapping elements in the array will use memcpy instead of operator= -///see discussion here: http://continuousphysics.com/Bullet/phpBB2/viewtopic.php?t=1231 and -///http://www.continuousphysics.com/Bullet/phpBB2/viewtopic.php?t=1240 - -#define BT_USE_PLACEMENT_NEW 1 -//#define BT_USE_MEMCPY 1 //disable, because it is cumbersome to find out for each platform where memcpy is defined. It can be in or or otherwise... - -#ifdef BT_USE_MEMCPY -#include -#include -#endif //BT_USE_MEMCPY - -#ifdef BT_USE_PLACEMENT_NEW -#include //for placement new -#endif //BT_USE_PLACEMENT_NEW - - -///btAlignedObjectArray uses a subset of the stl::vector interface for its methods -///It is developed to replace stl::vector to avoid STL alignment issues to add SIMD/SSE data -template -//template -class btAlignedObjectArray -{ - btAlignedAllocator m_allocator; - - int m_size; - int m_capacity; - T* m_data; - //PCK: added this line - bool m_ownsMemory; - - protected: - SIMD_FORCE_INLINE int allocSize(int size) - { - return (size ? size*2 : 1); - } - SIMD_FORCE_INLINE void copy(int start,int end, T* dest) - { - int i; - for (i=start;i size()) - { - reserve(newsize); - } -#ifdef BT_USE_PLACEMENT_NEW - for (int i=curSize;i - void downHeap(T *pArr, int k, int n,L CompareFunc) - { - /* PRE: a[k+1..N] is a heap */ - /* POST: a[k..N] is a heap */ - - T temp = pArr[k - 1]; - /* k has child(s) */ - while (k <= n/2) - { - int child = 2*k; - - if ((child < n) && CompareFunc(pArr[child - 1] , pArr[child])) - { - child++; - } - /* pick larger child */ - if (CompareFunc(temp , pArr[child - 1])) - { - /* move child up */ - pArr[k - 1] = pArr[child - 1]; - k = child; - } - else - { - break; - } - } - pArr[k - 1] = temp; - } /*downHeap*/ - - void swap(int index0,int index1) - { -#ifdef BT_USE_MEMCPY - char temp[sizeof(T)]; - memcpy(temp,&m_data[index0],sizeof(T)); - memcpy(&m_data[index0],&m_data[index1],sizeof(T)); - memcpy(&m_data[index1],temp,sizeof(T)); -#else - T temp = m_data[index0]; - m_data[index0] = m_data[index1]; - m_data[index1] = temp; -#endif //BT_USE_PLACEMENT_NEW - - } - - template - void heapSort(L CompareFunc) - { - /* sort a[0..N-1], N.B. 0 to N-1 */ - int k; - int n = m_size; - for (k = n/2; k > 0; k--) - { - downHeap(m_data, k, n, CompareFunc); - } - - /* a[1..N] is now a heap */ - while ( n>=1 ) - { - swap(0,n-1); /* largest of a[0..n-1] */ - - - n = n - 1; - /* restore a[1..i-1] heap */ - downHeap(m_data, 1, n, CompareFunc); - } - } - - ///non-recursive binary search, assumes sorted array - int findBinarySearch(const T& key) const - { - int first = 0; - int last = size(); - - //assume sorted array - while (first <= last) { - int mid = (first + last) / 2; // compute mid point. - if (key > m_data[mid]) - first = mid + 1; // repeat search in top half. - else if (key < m_data[mid]) - last = mid - 1; // repeat search in bottom half. - else - return mid; // found it. return position ///// - } - return size(); // failed to find key - } - - - int findLinearSearch(const T& key) const - { - int index=size(); - int i; - - for (i=0;i& planeEquations, const btVector3& point, btScalar margin) -{ - int numbrushes = planeEquations.size(); - for (int i=0;ibtScalar(0.)) - { - return false; - } - } - return true; - -} - - -bool btGeometryUtil::areVerticesBehindPlane(const btVector3& planeNormal, const btAlignedObjectArray& vertices, btScalar margin) -{ - int numvertices = vertices.size(); - for (int i=0;ibtScalar(0.)) - { - return false; - } - } - return true; -} - -bool notExist(const btVector3& planeEquation,const btAlignedObjectArray& planeEquations) -{ - int numbrushes = planeEquations.size(); - for (int i=0;i btScalar(0.999)) - { - return false; - } - } - return true; -} - -void btGeometryUtil::getPlaneEquationsFromVertices(btAlignedObjectArray& vertices, btAlignedObjectArray& planeEquationsOut ) -{ - const int numvertices = vertices.size(); - // brute force: - for (int i=0;i btScalar(0.0001)) - { - planeEquation.normalize(); - if (notExist(planeEquation,planeEquationsOut)) - { - planeEquation[3] = -planeEquation.dot(N1); - - //check if inside, and replace supportingVertexOut if needed - if (areVerticesBehindPlane(planeEquation,vertices,btScalar(0.01))) - { - planeEquationsOut.push_back(planeEquation); - } - } - } - normalSign = btScalar(-1.); - } - - } - } - } - -} - -void btGeometryUtil::getVerticesFromPlaneEquations(const btAlignedObjectArray& planeEquations , btAlignedObjectArray& verticesOut ) -{ - const int numbrushes = planeEquations.size(); - // brute force: - for (int i=0;i btScalar(0.0001) ) && - ( n3n1.length2() > btScalar(0.0001) ) && - ( n1n2.length2() > btScalar(0.0001) ) ) - { - //point P out of 3 plane equations: - - // d1 ( N2 * N3 ) + d2 ( N3 * N1 ) + d3 ( N1 * N2 ) - //P = ------------------------------------------------------------------------- - // N1 . ( N2 * N3 ) - - - btScalar quotient = (N1.dot(n2n3)); - if (btFabs(quotient) > btScalar(0.000001)) - { - quotient = btScalar(-1.) / quotient; - n2n3 *= N1[3]; - n3n1 *= N2[3]; - n1n2 *= N3[3]; - btVector3 potentialVertex = n2n3; - potentialVertex += n3n1; - potentialVertex += n1n2; - potentialVertex *= quotient; - - //check if inside, and replace supportingVertexOut if needed - if (isPointInsidePlanes(planeEquations,potentialVertex,btScalar(0.01))) - { - verticesOut.push_back(potentialVertex); - } - } - } - } - } - } -} - diff --git a/extern/bullet2/src/LinearMath/btGeometryUtil.h b/extern/bullet2/src/LinearMath/btGeometryUtil.h deleted file mode 100644 index 766cd75c383..00000000000 --- a/extern/bullet2/src/LinearMath/btGeometryUtil.h +++ /dev/null @@ -1,41 +0,0 @@ -/* -Copyright (c) 2003-2006 Gino van den Bergen / 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 BT_GEOMETRY_UTIL_H -#define BT_GEOMETRY_UTIL_H - -#include "btVector3.h" -#include "btAlignedObjectArray.h" - -class btGeometryUtil -{ - public: - - - static void getPlaneEquationsFromVertices(btAlignedObjectArray& vertices, btAlignedObjectArray& planeEquationsOut ); - - static void getVerticesFromPlaneEquations(const btAlignedObjectArray& planeEquations , btAlignedObjectArray& verticesOut ); - - static bool isInside(const btAlignedObjectArray& vertices, const btVector3& planeNormal, btScalar margin); - - static bool isPointInsidePlanes(const btAlignedObjectArray& planeEquations, const btVector3& point, btScalar margin); - - static bool areVerticesBehindPlane(const btVector3& planeNormal, const btAlignedObjectArray& vertices, btScalar margin); - -}; - - -#endif //BT_GEOMETRY_UTIL_H - diff --git a/extern/bullet2/src/LinearMath/btIDebugDraw.h b/extern/bullet2/src/LinearMath/btIDebugDraw.h deleted file mode 100644 index 2d96cff5055..00000000000 --- a/extern/bullet2/src/LinearMath/btIDebugDraw.h +++ /dev/null @@ -1,102 +0,0 @@ -/* -Copyright (c) 2005 Gino van den Bergen / Erwin Coumans http://continuousphysics.com - -Permission is hereby granted, free of charge, to any person or organization -obtaining a copy of the software and accompanying documentation covered by -this license (the "Software") to use, reproduce, display, distribute, -execute, and transmit the Software, and to prepare derivative works of the -Software, and to permit third-parties to whom the Software is furnished to -do so, all subject to the following: - -The copyright notices in the Software and this entire statement, including -the above license grant, this restriction and the following disclaimer, -must be included in all copies of the Software, in whole or in part, and -all derivative works of the Software, unless such copies or derivative -works are solely in the form of machine-executable object code generated by -a source language processor. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT -SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE -FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -DEALINGS IN THE SOFTWARE. -*/ - - -#ifndef IDEBUG_DRAW__H -#define IDEBUG_DRAW__H - -#include "btVector3.h" - - -class btIDebugDraw -{ - public: - - enum DebugDrawModes - { - DBG_NoDebug=0, - DBG_DrawWireframe = 1, - DBG_DrawAabb=2, - DBG_DrawFeaturesText=4, - DBG_DrawContactPoints=8, - DBG_NoDeactivation=16, - DBG_NoHelpText = 32, - DBG_DrawText=64, - DBG_ProfileTimings = 128, - DBG_EnableSatComparison = 256, - DBG_DisableBulletLCP = 512, - DBG_EnableCCD = 1024, - DBG_MAX_DEBUG_DRAW_MODE - }; - - virtual ~btIDebugDraw() {}; - - virtual void drawLine(const btVector3& from,const btVector3& to,const btVector3& color)=0; - - virtual void drawContactPoint(const btVector3& PointOnB,const btVector3& normalOnB,btScalar distance,int lifeTime,const btVector3& color)=0; - - virtual void reportErrorWarning(const char* warningString) = 0; - - virtual void draw3dText(const btVector3& location,const char* textString) = 0; - - virtual void setDebugMode(int debugMode) =0; - - virtual int getDebugMode() const = 0; - - inline void drawAabb(const btVector3& from,const btVector3& to,const btVector3& color) - { - - btVector3 halfExtents = (to-from)* 0.5f; - btVector3 center = (to+from) *0.5f; - int i,j; - - btVector3 edgecoord(1.f,1.f,1.f),pa,pb; - for (i=0;i<4;i++) - { - for (j=0;j<3;j++) - { - pa = btVector3(edgecoord[0]*halfExtents[0], edgecoord[1]*halfExtents[1], - edgecoord[2]*halfExtents[2]); - pa+=center; - - int othercoord = j%3; - edgecoord[othercoord]*=-1.f; - pb = btVector3(edgecoord[0]*halfExtents[0], edgecoord[1]*halfExtents[1], - edgecoord[2]*halfExtents[2]); - pb+=center; - - drawLine(pa,pb,color); - } - edgecoord = btVector3(-1.f,-1.f,-1.f); - if (i<3) - edgecoord[i]*=-1.f; - } - } -}; - - -#endif //IDEBUG_DRAW__H - diff --git a/extern/bullet2/src/LinearMath/btList.h b/extern/bullet2/src/LinearMath/btList.h deleted file mode 100644 index c87b47faf2b..00000000000 --- a/extern/bullet2/src/LinearMath/btList.h +++ /dev/null @@ -1,73 +0,0 @@ -/* -Copyright (c) 2003-2006 Gino van den Bergen / 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 GEN_LIST_H -#define GEN_LIST_H - -class btGEN_Link { -public: - btGEN_Link() : m_next(0), m_prev(0) {} - btGEN_Link(btGEN_Link *next, btGEN_Link *prev) : m_next(next), m_prev(prev) {} - - btGEN_Link *getNext() const { return m_next; } - btGEN_Link *getPrev() const { return m_prev; } - - bool isHead() const { return m_prev == 0; } - bool isTail() const { return m_next == 0; } - - void insertBefore(btGEN_Link *link) { - m_next = link; - m_prev = link->m_prev; - m_next->m_prev = this; - m_prev->m_next = this; - } - - void insertAfter(btGEN_Link *link) { - m_next = link->m_next; - m_prev = link; - m_next->m_prev = this; - m_prev->m_next = this; - } - - void remove() { - m_next->m_prev = m_prev; - m_prev->m_next = m_next; - } - -private: - btGEN_Link *m_next; - btGEN_Link *m_prev; -}; - -class btGEN_List { -public: - btGEN_List() : m_head(&m_tail, 0), m_tail(0, &m_head) {} - - btGEN_Link *getHead() const { return m_head.getNext(); } - btGEN_Link *getTail() const { return m_tail.getPrev(); } - - void addHead(btGEN_Link *link) { link->insertAfter(&m_head); } - void addTail(btGEN_Link *link) { link->insertBefore(&m_tail); } - -private: - btGEN_Link m_head; - btGEN_Link m_tail; -}; - -#endif - - - diff --git a/extern/bullet2/src/LinearMath/btMatrix3x3.h b/extern/bullet2/src/LinearMath/btMatrix3x3.h deleted file mode 100644 index 59680ff460d..00000000000 --- a/extern/bullet2/src/LinearMath/btMatrix3x3.h +++ /dev/null @@ -1,410 +0,0 @@ -/* -Copyright (c) 2003-2006 Gino van den Bergen / 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 btMatrix3x3_H -#define btMatrix3x3_H - -#include "btScalar.h" - -#include "btVector3.h" -#include "btQuaternion.h" - - -class btMatrix3x3 { - public: - btMatrix3x3 () {} - -// explicit btMatrix3x3(const btScalar *m) { setFromOpenGLSubMatrix(m); } - - explicit btMatrix3x3(const btQuaternion& q) { setRotation(q); } - /* - template - Matrix3x3(const btScalar& yaw, const btScalar& pitch, const btScalar& roll) - { - setEulerYPR(yaw, pitch, roll); - } - */ - btMatrix3x3(const btScalar& xx, const btScalar& xy, const btScalar& xz, - const btScalar& yx, const btScalar& yy, const btScalar& yz, - const btScalar& zx, const btScalar& zy, const btScalar& zz) - { - setValue(xx, xy, xz, - yx, yy, yz, - zx, zy, zz); - } - - SIMD_FORCE_INLINE btMatrix3x3 (const btMatrix3x3& other) - { - m_el[0] = other.m_el[0]; - m_el[1] = other.m_el[1]; - m_el[2] = other.m_el[2]; - } - - SIMD_FORCE_INLINE btMatrix3x3& operator=(const btMatrix3x3& other) - { - m_el[0] = other.m_el[0]; - m_el[1] = other.m_el[1]; - m_el[2] = other.m_el[2]; - return *this; - } - - SIMD_FORCE_INLINE btVector3 getColumn(int i) const - { - return btVector3(m_el[0][i],m_el[1][i],m_el[2][i]); - } - - - - SIMD_FORCE_INLINE const btVector3& getRow(int i) const - { - return m_el[i]; - } - - - SIMD_FORCE_INLINE btVector3& operator[](int i) - { - btFullAssert(0 <= i && i < 3); - return m_el[i]; - } - - SIMD_FORCE_INLINE const btVector3& operator[](int i) const - { - btFullAssert(0 <= i && i < 3); - return m_el[i]; - } - - btMatrix3x3& operator*=(const btMatrix3x3& m); - - - void setFromOpenGLSubMatrix(const btScalar *m) - { - m_el[0].setValue(m[0],m[4],m[8]); - m_el[1].setValue(m[1],m[5],m[9]); - m_el[2].setValue(m[2],m[6],m[10]); - - } - - void setValue(const btScalar& xx, const btScalar& xy, const btScalar& xz, - const btScalar& yx, const btScalar& yy, const btScalar& yz, - const btScalar& zx, const btScalar& zy, const btScalar& zz) - { - m_el[0].setValue(xx,xy,xz); - m_el[1].setValue(yx,yy,yz); - m_el[2].setValue(zx,zy,zz); - } - - void setRotation(const btQuaternion& q) - { - btScalar d = q.length2(); - btFullAssert(d != btScalar(0.0)); - btScalar s = btScalar(2.0) / d; - btScalar xs = q.x() * s, ys = q.y() * s, zs = q.z() * s; - btScalar wx = q.w() * xs, wy = q.w() * ys, wz = q.w() * zs; - btScalar xx = q.x() * xs, xy = q.x() * ys, xz = q.x() * zs; - btScalar yy = q.y() * ys, yz = q.y() * zs, zz = q.z() * zs; - setValue(btScalar(1.0) - (yy + zz), xy - wz, xz + wy, - xy + wz, btScalar(1.0) - (xx + zz), yz - wx, - xz - wy, yz + wx, btScalar(1.0) - (xx + yy)); - } - - - - void setEulerYPR(const btScalar& yaw, const btScalar& pitch, const btScalar& roll) - { - - btScalar cy(btCos(yaw)); - btScalar sy(btSin(yaw)); - btScalar cp(btCos(pitch)); - btScalar sp(btSin(pitch)); - btScalar cr(btCos(roll)); - btScalar sr(btSin(roll)); - btScalar cc = cy * cr; - btScalar cs = cy * sr; - btScalar sc = sy * cr; - btScalar ss = sy * sr; - setValue(cc - sp * ss, -cs - sp * sc, -sy * cp, - cp * sr, cp * cr, -sp, - sc + sp * cs, -ss + sp * cc, cy * cp); - - } - - /** - * setEulerZYX - * @param euler a const reference to a btVector3 of euler angles - * These angles are used to produce a rotation matrix. The euler - * angles are applied in ZYX order. I.e a vector is first rotated - * about X then Y and then Z - **/ - - void setEulerZYX(btScalar eulerX,btScalar eulerY,btScalar eulerZ) { - btScalar ci ( btCos(eulerX)); - btScalar cj ( btCos(eulerY)); - btScalar ch ( btCos(eulerZ)); - btScalar si ( btSin(eulerX)); - btScalar sj ( btSin(eulerY)); - btScalar sh ( btSin(eulerZ)); - btScalar cc = ci * ch; - btScalar cs = ci * sh; - btScalar sc = si * ch; - btScalar ss = si * sh; - - setValue(cj * ch, sj * sc - cs, sj * cc + ss, - cj * sh, sj * ss + cc, sj * cs - sc, - -sj, cj * si, cj * ci); - } - - void setIdentity() - { - setValue(btScalar(1.0), btScalar(0.0), btScalar(0.0), - btScalar(0.0), btScalar(1.0), btScalar(0.0), - btScalar(0.0), btScalar(0.0), btScalar(1.0)); - } - - void getOpenGLSubMatrix(btScalar *m) const - { - m[0] = btScalar(m_el[0].x()); - m[1] = btScalar(m_el[1].x()); - m[2] = btScalar(m_el[2].x()); - m[3] = btScalar(0.0); - m[4] = btScalar(m_el[0].y()); - m[5] = btScalar(m_el[1].y()); - m[6] = btScalar(m_el[2].y()); - m[7] = btScalar(0.0); - m[8] = btScalar(m_el[0].z()); - m[9] = btScalar(m_el[1].z()); - m[10] = btScalar(m_el[2].z()); - m[11] = btScalar(0.0); - } - - void getRotation(btQuaternion& q) const - { - btScalar trace = m_el[0].x() + m_el[1].y() + m_el[2].z(); - btScalar temp[4]; - - if (trace > btScalar(0.0)) - { - btScalar s = btSqrt(trace + btScalar(1.0)); - temp[3]=(s * btScalar(0.5)); - s = btScalar(0.5) / s; - - temp[0]=((m_el[2].y() - m_el[1].z()) * s); - temp[1]=((m_el[0].z() - m_el[2].x()) * s); - temp[2]=((m_el[1].x() - m_el[0].y()) * s); - } - else - { - int i = m_el[0].x() < m_el[1].y() ? - (m_el[1].y() < m_el[2].z() ? 2 : 1) : - (m_el[0].x() < m_el[2].z() ? 2 : 0); - int j = (i + 1) % 3; - int k = (i + 2) % 3; - - btScalar s = btSqrt(m_el[i][i] - m_el[j][j] - m_el[k][k] + btScalar(1.0)); - temp[i] = s * btScalar(0.5); - s = btScalar(0.5) / s; - - temp[3] = (m_el[k][j] - m_el[j][k]) * s; - temp[j] = (m_el[j][i] + m_el[i][j]) * s; - temp[k] = (m_el[k][i] + m_el[i][k]) * s; - } - q.setValue(temp[0],temp[1],temp[2],temp[3]); - } - - void getEuler(btScalar& yaw, btScalar& pitch, btScalar& roll) const - { - - if (btScalar(m_el[1].z()) < btScalar(1)) - { - if (btScalar(m_el[1].z()) > -btScalar(1)) - { - yaw = btScalar(btAtan2(m_el[1].x(), m_el[0].x())); - pitch = btScalar(btAsin(-m_el[1].y())); - roll = btScalar(btAtan2(m_el[2].y(), m_el[2].z())); - } - else - { - yaw = btScalar(-btAtan2(-m_el[0].y(), m_el[0].z())); - pitch = SIMD_HALF_PI; - roll = btScalar(0.0); - } - } - else - { - yaw = btScalar(btAtan2(-m_el[0].y(), m_el[0].z())); - pitch = -SIMD_HALF_PI; - roll = btScalar(0.0); - } - } - - - - - btMatrix3x3 scaled(const btVector3& s) const - { - return btMatrix3x3(m_el[0].x() * s.x(), m_el[0].y() * s.y(), m_el[0].z() * s.z(), - m_el[1].x() * s.x(), m_el[1].y() * s.y(), m_el[1].z() * s.z(), - m_el[2].x() * s.x(), m_el[2].y() * s.y(), m_el[2].z() * s.z()); - } - - btScalar determinant() const; - btMatrix3x3 adjoint() const; - btMatrix3x3 absolute() const; - btMatrix3x3 transpose() const; - btMatrix3x3 inverse() const; - - btMatrix3x3 transposeTimes(const btMatrix3x3& m) const; - btMatrix3x3 timesTranspose(const btMatrix3x3& m) const; - - SIMD_FORCE_INLINE btScalar tdotx(const btVector3& v) const - { - return m_el[0].x() * v.x() + m_el[1].x() * v.y() + m_el[2].x() * v.z(); - } - SIMD_FORCE_INLINE btScalar tdoty(const btVector3& v) const - { - return m_el[0].y() * v.x() + m_el[1].y() * v.y() + m_el[2].y() * v.z(); - } - SIMD_FORCE_INLINE btScalar tdotz(const btVector3& v) const - { - return m_el[0].z() * v.x() + m_el[1].z() * v.y() + m_el[2].z() * v.z(); - } - - - - protected: - btScalar cofac(int r1, int c1, int r2, int c2) const - { - return m_el[r1][c1] * m_el[r2][c2] - m_el[r1][c2] * m_el[r2][c1]; - } - - btVector3 m_el[3]; - }; - - SIMD_FORCE_INLINE btMatrix3x3& - btMatrix3x3::operator*=(const btMatrix3x3& m) - { - setValue(m.tdotx(m_el[0]), m.tdoty(m_el[0]), m.tdotz(m_el[0]), - m.tdotx(m_el[1]), m.tdoty(m_el[1]), m.tdotz(m_el[1]), - m.tdotx(m_el[2]), m.tdoty(m_el[2]), m.tdotz(m_el[2])); - return *this; - } - - SIMD_FORCE_INLINE btScalar - btMatrix3x3::determinant() const - { - return triple((*this)[0], (*this)[1], (*this)[2]); - } - - - SIMD_FORCE_INLINE btMatrix3x3 - btMatrix3x3::absolute() const - { - return btMatrix3x3( - btFabs(m_el[0].x()), btFabs(m_el[0].y()), btFabs(m_el[0].z()), - btFabs(m_el[1].x()), btFabs(m_el[1].y()), btFabs(m_el[1].z()), - btFabs(m_el[2].x()), btFabs(m_el[2].y()), btFabs(m_el[2].z())); - } - - SIMD_FORCE_INLINE btMatrix3x3 - btMatrix3x3::transpose() const - { - return btMatrix3x3(m_el[0].x(), m_el[1].x(), m_el[2].x(), - m_el[0].y(), m_el[1].y(), m_el[2].y(), - m_el[0].z(), m_el[1].z(), m_el[2].z()); - } - - SIMD_FORCE_INLINE btMatrix3x3 - btMatrix3x3::adjoint() const - { - return btMatrix3x3(cofac(1, 1, 2, 2), cofac(0, 2, 2, 1), cofac(0, 1, 1, 2), - cofac(1, 2, 2, 0), cofac(0, 0, 2, 2), cofac(0, 2, 1, 0), - cofac(1, 0, 2, 1), cofac(0, 1, 2, 0), cofac(0, 0, 1, 1)); - } - - SIMD_FORCE_INLINE btMatrix3x3 - btMatrix3x3::inverse() const - { - btVector3 co(cofac(1, 1, 2, 2), cofac(1, 2, 2, 0), cofac(1, 0, 2, 1)); - btScalar det = (*this)[0].dot(co); - btFullAssert(det != btScalar(0.0)); - btScalar s = btScalar(1.0) / det; - return btMatrix3x3(co.x() * s, cofac(0, 2, 2, 1) * s, cofac(0, 1, 1, 2) * s, - co.y() * s, cofac(0, 0, 2, 2) * s, cofac(0, 2, 1, 0) * s, - co.z() * s, cofac(0, 1, 2, 0) * s, cofac(0, 0, 1, 1) * s); - } - - SIMD_FORCE_INLINE btMatrix3x3 - btMatrix3x3::transposeTimes(const btMatrix3x3& m) const - { - return btMatrix3x3( - m_el[0].x() * m[0].x() + m_el[1].x() * m[1].x() + m_el[2].x() * m[2].x(), - m_el[0].x() * m[0].y() + m_el[1].x() * m[1].y() + m_el[2].x() * m[2].y(), - m_el[0].x() * m[0].z() + m_el[1].x() * m[1].z() + m_el[2].x() * m[2].z(), - m_el[0].y() * m[0].x() + m_el[1].y() * m[1].x() + m_el[2].y() * m[2].x(), - m_el[0].y() * m[0].y() + m_el[1].y() * m[1].y() + m_el[2].y() * m[2].y(), - m_el[0].y() * m[0].z() + m_el[1].y() * m[1].z() + m_el[2].y() * m[2].z(), - m_el[0].z() * m[0].x() + m_el[1].z() * m[1].x() + m_el[2].z() * m[2].x(), - m_el[0].z() * m[0].y() + m_el[1].z() * m[1].y() + m_el[2].z() * m[2].y(), - m_el[0].z() * m[0].z() + m_el[1].z() * m[1].z() + m_el[2].z() * m[2].z()); - } - - SIMD_FORCE_INLINE btMatrix3x3 - btMatrix3x3::timesTranspose(const btMatrix3x3& m) const - { - return btMatrix3x3( - m_el[0].dot(m[0]), m_el[0].dot(m[1]), m_el[0].dot(m[2]), - m_el[1].dot(m[0]), m_el[1].dot(m[1]), m_el[1].dot(m[2]), - m_el[2].dot(m[0]), m_el[2].dot(m[1]), m_el[2].dot(m[2])); - - } - - SIMD_FORCE_INLINE btVector3 - operator*(const btMatrix3x3& m, const btVector3& v) - { - return btVector3(m[0].dot(v), m[1].dot(v), m[2].dot(v)); - } - - - SIMD_FORCE_INLINE btVector3 - operator*(const btVector3& v, const btMatrix3x3& m) - { - return btVector3(m.tdotx(v), m.tdoty(v), m.tdotz(v)); - } - - SIMD_FORCE_INLINE btMatrix3x3 - operator*(const btMatrix3x3& m1, const btMatrix3x3& m2) - { - return btMatrix3x3( - m2.tdotx( m1[0]), m2.tdoty( m1[0]), m2.tdotz( m1[0]), - m2.tdotx( m1[1]), m2.tdoty( m1[1]), m2.tdotz( m1[1]), - m2.tdotx( m1[2]), m2.tdoty( m1[2]), m2.tdotz( m1[2])); - } - -/* - SIMD_FORCE_INLINE btMatrix3x3 btMultTransposeLeft(const btMatrix3x3& m1, const btMatrix3x3& m2) { - return btMatrix3x3( - m1[0][0] * m2[0][0] + m1[1][0] * m2[1][0] + m1[2][0] * m2[2][0], - m1[0][0] * m2[0][1] + m1[1][0] * m2[1][1] + m1[2][0] * m2[2][1], - m1[0][0] * m2[0][2] + m1[1][0] * m2[1][2] + m1[2][0] * m2[2][2], - m1[0][1] * m2[0][0] + m1[1][1] * m2[1][0] + m1[2][1] * m2[2][0], - m1[0][1] * m2[0][1] + m1[1][1] * m2[1][1] + m1[2][1] * m2[2][1], - m1[0][1] * m2[0][2] + m1[1][1] * m2[1][2] + m1[2][1] * m2[2][2], - m1[0][2] * m2[0][0] + m1[1][2] * m2[1][0] + m1[2][2] * m2[2][0], - m1[0][2] * m2[0][1] + m1[1][2] * m2[1][1] + m1[2][2] * m2[2][1], - m1[0][2] * m2[0][2] + m1[1][2] * m2[1][2] + m1[2][2] * m2[2][2]); -} -*/ - - -#endif diff --git a/extern/bullet2/src/LinearMath/btMinMax.h b/extern/bullet2/src/LinearMath/btMinMax.h deleted file mode 100644 index 5e27d62a4a4..00000000000 --- a/extern/bullet2/src/LinearMath/btMinMax.h +++ /dev/null @@ -1,69 +0,0 @@ -/* -Copyright (c) 2003-2006 Gino van den Bergen / 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 GEN_MINMAX_H -#define GEN_MINMAX_H - -template -SIMD_FORCE_INLINE const T& btMin(const T& a, const T& b) -{ - return a < b ? a : b ; -} - -template -SIMD_FORCE_INLINE const T& btMax(const T& a, const T& b) -{ - return a > b ? a : b; -} - -template -SIMD_FORCE_INLINE const T& GEN_clamped(const T& a, const T& lb, const T& ub) -{ - return a < lb ? lb : (ub < a ? ub : a); -} - -template -SIMD_FORCE_INLINE void btSetMin(T& a, const T& b) -{ - if (b < a) - { - a = b; - } -} - -template -SIMD_FORCE_INLINE void btSetMax(T& a, const T& b) -{ - if (a < b) - { - a = b; - } -} - -template -SIMD_FORCE_INLINE void GEN_clamp(T& a, const T& lb, const T& ub) -{ - if (a < lb) - { - a = lb; - } - else if (ub < a) - { - a = ub; - } -} - -#endif diff --git a/extern/bullet2/src/LinearMath/btMotionState.h b/extern/bullet2/src/LinearMath/btMotionState.h deleted file mode 100644 index 1975e5ff900..00000000000 --- a/extern/bullet2/src/LinearMath/btMotionState.h +++ /dev/null @@ -1,40 +0,0 @@ -/* -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 BT_MOTIONSTATE_H -#define BT_MOTIONSTATE_H - -#include "btTransform.h" - -///btMotionState allows the dynamics world to synchronize the updated world transforms with graphics -///For optimizations, potentially only moving objects get synchronized (using setWorldPosition/setWorldOrientation) -class btMotionState -{ - public: - - virtual ~btMotionState() - { - - } - - virtual void getWorldTransform(btTransform& worldTrans ) const =0; - - //Bullet only calls the update of worldtransform for active objects - virtual void setWorldTransform(const btTransform& worldTrans)=0; - - -}; - -#endif //BT_MOTIONSTATE_H diff --git a/extern/bullet2/src/LinearMath/btPoint3.h b/extern/bullet2/src/LinearMath/btPoint3.h deleted file mode 100644 index a2020e26d12..00000000000 --- a/extern/bullet2/src/LinearMath/btPoint3.h +++ /dev/null @@ -1,24 +0,0 @@ -/* -Copyright (c) 2003-2006 Gino van den Bergen / 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 btPoint3_H -#define btPoint3_H - -#include "btVector3.h" - -typedef btVector3 btPoint3; - -#endif diff --git a/extern/bullet2/src/LinearMath/btPoolAllocator.h b/extern/bullet2/src/LinearMath/btPoolAllocator.h deleted file mode 100755 index ad772ae123f..00000000000 --- a/extern/bullet2/src/LinearMath/btPoolAllocator.h +++ /dev/null @@ -1,94 +0,0 @@ -/* -Copyright (c) 2003-2006 Gino van den Bergen / 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 _BT_POOL_ALLOCATOR_H -#define _BT_POOL_ALLOCATOR_H - -#include "btScalar.h" -#include "btAlignedAllocator.h" - -class btPoolAllocator -{ - int m_elemSize; - int m_maxElements; - int m_freeCount; - void* m_firstFree; - unsigned char* m_pool; - -public: - - btPoolAllocator(int elemSize, int maxElements) - :m_elemSize(elemSize), - m_maxElements(maxElements) - { - m_pool = (unsigned char*) btAlignedAlloc(m_elemSize*m_maxElements,16); - - unsigned char* p = m_pool; - m_firstFree = p; - m_freeCount = m_maxElements; - int count = m_maxElements; - while (--count) { - *(void**)p = (p + m_elemSize); - p += m_elemSize; - } - *(void**)p = 0; - } - - ~btPoolAllocator() - { - btAlignedFree( m_pool); - } - - int getFreeCount() const - { - return m_freeCount; - } - - void* allocate(int size) - { - btAssert(!size || size<=m_elemSize); - btAssert(m_freeCount>0); - void* result = m_firstFree; - m_firstFree = *(void**)m_firstFree; - --m_freeCount; - return result; - } - - bool validPtr(void* ptr) - { - if (ptr) { - if (((unsigned char*)ptr >= m_pool && (unsigned char*)ptr < m_pool + m_maxElements * m_elemSize)) - { - return true; - } - } - return false; - } - - void free(void* ptr) - { - if (ptr) { - btAssert((unsigned char*)ptr >= m_pool && (unsigned char*)ptr < m_pool + m_maxElements * m_elemSize); - - *(void**)ptr = m_firstFree; - m_firstFree = ptr; - ++m_freeCount; - } - } - - -}; - -#endif //_BT_POOL_ALLOCATOR_H diff --git a/extern/bullet2/src/LinearMath/btQuadWord.h b/extern/bullet2/src/LinearMath/btQuadWord.h deleted file mode 100644 index 2e5950ebd5d..00000000000 --- a/extern/bullet2/src/LinearMath/btQuadWord.h +++ /dev/null @@ -1,135 +0,0 @@ -/* -Copyright (c) 2003-2006 Gino van den Bergen / 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 SIMD_QUADWORD_H -#define SIMD_QUADWORD_H - -#include "btScalar.h" -#include "btMinMax.h" - -//ATTRIBUTE_ALIGNED16(class) btQuadWordStorage -//some issues under PS3 Linux with IBM 2.1 SDK, gcc compiler prevent from using aligned quadword. todo: look into this - -class btQuadWordStorage -{ -protected: - btScalar m_x; - btScalar m_y; - btScalar m_z; - btScalar m_unusedW; -}; - - -///btQuadWord is base-class for vectors, points -class btQuadWord : public btQuadWordStorage -{ - public: - -// SIMD_FORCE_INLINE btScalar& operator[](int i) { return (&m_x)[i]; } -// SIMD_FORCE_INLINE const btScalar& operator[](int i) const { return (&m_x)[i]; } - - SIMD_FORCE_INLINE const btScalar& getX() const { return m_x; } - - SIMD_FORCE_INLINE const btScalar& getY() const { return m_y; } - - SIMD_FORCE_INLINE const btScalar& getZ() const { return m_z; } - - SIMD_FORCE_INLINE void setX(btScalar x) { m_x = x;}; - - SIMD_FORCE_INLINE void setY(btScalar y) { m_y = y;}; - - SIMD_FORCE_INLINE void setZ(btScalar z) { m_z = z;}; - - SIMD_FORCE_INLINE void setW(btScalar w) { m_unusedW = w;}; - - SIMD_FORCE_INLINE const btScalar& x() const { return m_x; } - - SIMD_FORCE_INLINE const btScalar& y() const { return m_y; } - - SIMD_FORCE_INLINE const btScalar& z() const { return m_z; } - - SIMD_FORCE_INLINE const btScalar& w() const { return m_unusedW; } - - - SIMD_FORCE_INLINE operator btScalar *() { return &m_x; } - SIMD_FORCE_INLINE operator const btScalar *() const { return &m_x; } - - - - SIMD_FORCE_INLINE void setValue(const btScalar& x, const btScalar& y, const btScalar& z) - { - m_x=x; - m_y=y; - m_z=z; - m_unusedW = 0.f; - } - -/* void getValue(btScalar *m) const - { - m[0] = m_x; - m[1] = m_y; - m[2] = m_z; - } -*/ - SIMD_FORCE_INLINE void setValue(const btScalar& x, const btScalar& y, const btScalar& z,const btScalar& w) - { - m_x=x; - m_y=y; - m_z=z; - m_unusedW=w; - } - - SIMD_FORCE_INLINE btQuadWord() - // :m_x(btScalar(0.)),m_y(btScalar(0.)),m_z(btScalar(0.)),m_unusedW(btScalar(0.)) - { - } - - SIMD_FORCE_INLINE btQuadWord(const btQuadWordStorage& q) - { - *((btQuadWordStorage*)this) = q; - } - - SIMD_FORCE_INLINE btQuadWord(const btScalar& x, const btScalar& y, const btScalar& z) - { - m_x = x, m_y = y, m_z = z, m_unusedW = 0.0f; - } - - SIMD_FORCE_INLINE btQuadWord(const btScalar& x, const btScalar& y, const btScalar& z,const btScalar& w) - { - m_x = x, m_y = y, m_z = z, m_unusedW = w; - } - - - SIMD_FORCE_INLINE void setMax(const btQuadWord& other) - { - btSetMax(m_x, other.m_x); - btSetMax(m_y, other.m_y); - btSetMax(m_z, other.m_z); - btSetMax(m_unusedW, other.m_unusedW); - } - - SIMD_FORCE_INLINE void setMin(const btQuadWord& other) - { - btSetMin(m_x, other.m_x); - btSetMin(m_y, other.m_y); - btSetMin(m_z, other.m_z); - btSetMin(m_unusedW, other.m_unusedW); - } - - - -}; - -#endif //SIMD_QUADWORD_H diff --git a/extern/bullet2/src/LinearMath/btQuaternion.h b/extern/bullet2/src/LinearMath/btQuaternion.h deleted file mode 100644 index 27ab1fcd2c3..00000000000 --- a/extern/bullet2/src/LinearMath/btQuaternion.h +++ /dev/null @@ -1,321 +0,0 @@ -/* -Copyright (c) 2003-2006 Gino van den Bergen / 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 SIMD__QUATERNION_H_ -#define SIMD__QUATERNION_H_ - -#include "btVector3.h" - -class btQuaternion : public btQuadWord { -public: - btQuaternion() {} - - // template - // explicit Quaternion(const btScalar *v) : Tuple4(v) {} - - btQuaternion(const btScalar& x, const btScalar& y, const btScalar& z, const btScalar& w) - : btQuadWord(x, y, z, w) - {} - - btQuaternion(const btVector3& axis, const btScalar& angle) - { - setRotation(axis, angle); - } - - btQuaternion(const btScalar& yaw, const btScalar& pitch, const btScalar& roll) - { - setEuler(yaw, pitch, roll); - } - - void setRotation(const btVector3& axis, const btScalar& angle) - { - btScalar d = axis.length(); - assert(d != btScalar(0.0)); - btScalar s = btSin(angle * btScalar(0.5)) / d; - setValue(axis.x() * s, axis.y() * s, axis.z() * s, - btCos(angle * btScalar(0.5))); - } - - void setEuler(const btScalar& yaw, const btScalar& pitch, const btScalar& roll) - { - btScalar halfYaw = btScalar(yaw) * btScalar(0.5); - btScalar halfPitch = btScalar(pitch) * btScalar(0.5); - btScalar halfRoll = btScalar(roll) * btScalar(0.5); - btScalar cosYaw = btCos(halfYaw); - btScalar sinYaw = btSin(halfYaw); - btScalar cosPitch = btCos(halfPitch); - btScalar sinPitch = btSin(halfPitch); - btScalar cosRoll = btCos(halfRoll); - btScalar sinRoll = btSin(halfRoll); - setValue(cosRoll * sinPitch * cosYaw + sinRoll * cosPitch * sinYaw, - cosRoll * cosPitch * sinYaw - sinRoll * sinPitch * cosYaw, - sinRoll * cosPitch * cosYaw - cosRoll * sinPitch * sinYaw, - cosRoll * cosPitch * cosYaw + sinRoll * sinPitch * sinYaw); - } - - btQuaternion& operator+=(const btQuaternion& q) - { - m_x += q.x(); m_y += q.y(); m_z += q.z(); m_unusedW += q.m_unusedW; - return *this; - } - - btQuaternion& operator-=(const btQuaternion& q) - { - m_x -= q.x(); m_y -= q.y(); m_z -= q.z(); m_unusedW -= q.m_unusedW; - return *this; - } - - btQuaternion& operator*=(const btScalar& s) - { - m_x *= s; m_y *= s; m_z *= s; m_unusedW *= s; - return *this; - } - - - btQuaternion& operator*=(const btQuaternion& q) - { - setValue(m_unusedW * q.x() + m_x * q.m_unusedW + m_y * q.z() - m_z * q.y(), - m_unusedW * q.y() + m_y * q.m_unusedW + m_z * q.x() - m_x * q.z(), - m_unusedW * q.z() + m_z * q.m_unusedW + m_x * q.y() - m_y * q.x(), - m_unusedW * q.m_unusedW - m_x * q.x() - m_y * q.y() - m_z * q.z()); - return *this; - } - - btScalar dot(const btQuaternion& q) const - { - return m_x * q.x() + m_y * q.y() + m_z * q.z() + m_unusedW * q.m_unusedW; - } - - btScalar length2() const - { - return dot(*this); - } - - btScalar length() const - { - return btSqrt(length2()); - } - - btQuaternion& normalize() - { - return *this /= length(); - } - - SIMD_FORCE_INLINE btQuaternion - operator*(const btScalar& s) const - { - return btQuaternion(x() * s, y() * s, z() * s, m_unusedW * s); - } - - - - btQuaternion operator/(const btScalar& s) const - { - assert(s != btScalar(0.0)); - return *this * (btScalar(1.0) / s); - } - - - btQuaternion& operator/=(const btScalar& s) - { - assert(s != btScalar(0.0)); - return *this *= btScalar(1.0) / s; - } - - - btQuaternion normalized() const - { - return *this / length(); - } - - btScalar angle(const btQuaternion& q) const - { - btScalar s = btSqrt(length2() * q.length2()); - assert(s != btScalar(0.0)); - return btAcos(dot(q) / s); - } - - btScalar getAngle() const - { - btScalar s = btScalar(2.) * btAcos(m_unusedW); - return s; - } - - - - btQuaternion inverse() const - { - return btQuaternion(m_x, m_y, m_z, -m_unusedW); - } - - SIMD_FORCE_INLINE btQuaternion - operator+(const btQuaternion& q2) const - { - const btQuaternion& q1 = *this; - return btQuaternion(q1.x() + q2.x(), q1.y() + q2.y(), q1.z() + q2.z(), q1.m_unusedW + q2.m_unusedW); - } - - SIMD_FORCE_INLINE btQuaternion - operator-(const btQuaternion& q2) const - { - const btQuaternion& q1 = *this; - return btQuaternion(q1.x() - q2.x(), q1.y() - q2.y(), q1.z() - q2.z(), q1.m_unusedW - q2.m_unusedW); - } - - SIMD_FORCE_INLINE btQuaternion operator-() const - { - const btQuaternion& q2 = *this; - return btQuaternion( - q2.x(), - q2.y(), - q2.z(), - q2.m_unusedW); - } - - SIMD_FORCE_INLINE btQuaternion farthest( const btQuaternion& qd) const - { - btQuaternion diff,sum; - diff = *this - qd; - sum = *this + qd; - if( diff.dot(diff) > sum.dot(sum) ) - return qd; - return (-qd); - } - - btQuaternion slerp(const btQuaternion& q, const btScalar& t) const - { - btScalar theta = angle(q); - if (theta != btScalar(0.0)) - { - btScalar d = btScalar(1.0) / btSin(theta); - btScalar s0 = btSin((btScalar(1.0) - t) * theta); - btScalar s1 = btSin(t * theta); - return btQuaternion((m_x * s0 + q.x() * s1) * d, - (m_y * s0 + q.y() * s1) * d, - (m_z * s0 + q.z() * s1) * d, - (m_unusedW * s0 + q.m_unusedW * s1) * d); - } - else - { - return *this; - } - } - - SIMD_FORCE_INLINE const btScalar& getW() const { return m_unusedW; } - - -}; - - - -SIMD_FORCE_INLINE btQuaternion -operator-(const btQuaternion& q) -{ - return btQuaternion(-q.x(), -q.y(), -q.z(), -q.w()); -} - - - - -SIMD_FORCE_INLINE btQuaternion -operator*(const btQuaternion& q1, const btQuaternion& q2) { - return btQuaternion(q1.w() * q2.x() + q1.x() * q2.w() + q1.y() * q2.z() - q1.z() * q2.y(), - q1.w() * q2.y() + q1.y() * q2.w() + q1.z() * q2.x() - q1.x() * q2.z(), - q1.w() * q2.z() + q1.z() * q2.w() + q1.x() * q2.y() - q1.y() * q2.x(), - q1.w() * q2.w() - q1.x() * q2.x() - q1.y() * q2.y() - q1.z() * q2.z()); -} - -SIMD_FORCE_INLINE btQuaternion -operator*(const btQuaternion& q, const btVector3& w) -{ - return btQuaternion( q.w() * w.x() + q.y() * w.z() - q.z() * w.y(), - q.w() * w.y() + q.z() * w.x() - q.x() * w.z(), - q.w() * w.z() + q.x() * w.y() - q.y() * w.x(), - -q.x() * w.x() - q.y() * w.y() - q.z() * w.z()); -} - -SIMD_FORCE_INLINE btQuaternion -operator*(const btVector3& w, const btQuaternion& q) -{ - return btQuaternion( w.x() * q.w() + w.y() * q.z() - w.z() * q.y(), - w.y() * q.w() + w.z() * q.x() - w.x() * q.z(), - w.z() * q.w() + w.x() * q.y() - w.y() * q.x(), - -w.x() * q.x() - w.y() * q.y() - w.z() * q.z()); -} - -SIMD_FORCE_INLINE btScalar -dot(const btQuaternion& q1, const btQuaternion& q2) -{ - return q1.dot(q2); -} - - -SIMD_FORCE_INLINE btScalar -length(const btQuaternion& q) -{ - return q.length(); -} - -SIMD_FORCE_INLINE btScalar -angle(const btQuaternion& q1, const btQuaternion& q2) -{ - return q1.angle(q2); -} - - -SIMD_FORCE_INLINE btQuaternion -inverse(const btQuaternion& q) -{ - return q.inverse(); -} - -SIMD_FORCE_INLINE btQuaternion -slerp(const btQuaternion& q1, const btQuaternion& q2, const btScalar& t) -{ - return q1.slerp(q2, t); -} - -SIMD_FORCE_INLINE btVector3 -quatRotate(const btQuaternion& rotation, const btVector3& v) -{ - btQuaternion q = rotation * v; - q *= rotation.inverse(); - return btVector3(q.getX(),q.getY(),q.getZ()); -} - -SIMD_FORCE_INLINE btQuaternion -shortestArcQuat(const btVector3& v0, const btVector3& v1) // Game Programming Gems 2.10. make sure v0,v1 are normalized -{ - btVector3 c = v0.cross(v1); - btScalar d = v0.dot(v1); - - if (d < -1.0 + SIMD_EPSILON) - return btQuaternion(0.0f,1.0f,0.0f,0.0f); // just pick any vector - - btScalar s = btSqrt((1.0f + d) * 2.0f); - btScalar rs = 1.0f / s; - - return btQuaternion(c.getX()*rs,c.getY()*rs,c.getZ()*rs,s * 0.5f); -} - -SIMD_FORCE_INLINE btQuaternion -shortestArcQuatNormalize2(btVector3& v0,btVector3& v1) -{ - v0.normalize(); - v1.normalize(); - return shortestArcQuat(v0,v1); -} - -#endif - - - diff --git a/extern/bullet2/src/LinearMath/btQuickprof.cpp b/extern/bullet2/src/LinearMath/btQuickprof.cpp deleted file mode 100644 index 37a0c8c3be5..00000000000 --- a/extern/bullet2/src/LinearMath/btQuickprof.cpp +++ /dev/null @@ -1,38 +0,0 @@ -/* -Copyright (c) 2006 Tyler Streeter - -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. - -*/ - - -// Please visit the project website (http://quickprof.sourceforge.net) -// for usage instructions. - -// Credits: The Clock class was inspired by the Timer classes in -// Ogre (www.ogre3d.org). - -#include "LinearMath/btQuickprof.h" - -#ifdef USE_QUICKPROF - -// Note: We must declare these private static variables again here to -// avoid link errors. -bool btProfiler::mEnabled = false; -btClock btProfiler::mClock; -unsigned long int btProfiler::mCurrentCycleStartMicroseconds = 0; -unsigned long int btProfiler::mLastCycleDurationMicroseconds = 0; -std::map btProfiler::mProfileBlocks; -std::ofstream btProfiler::mOutputFile; -bool btProfiler::mFirstFileOutput = true; -btProfiler::BlockTimingMethod btProfiler::mFileOutputMethod; -unsigned long int btProfiler::mCycleNumber = 0; -#endif //USE_QUICKPROF diff --git a/extern/bullet2/src/LinearMath/btQuickprof.h b/extern/bullet2/src/LinearMath/btQuickprof.h deleted file mode 100644 index a885967c5fa..00000000000 --- a/extern/bullet2/src/LinearMath/btQuickprof.h +++ /dev/null @@ -1,712 +0,0 @@ -/* -Copyright (c) 2006 Tyler Streeter - -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. - -*/ - -// Please visit the project website (http://quickprof.sourceforge.net) -// for usage instructions. - -// Credits: The Clock class was inspired by the Timer classes in -// Ogre (www.ogre3d.org). - -#ifndef QUICK_PROF_H -#define QUICK_PROF_H - -#include "btScalar.h" - -//#define USE_QUICKPROF 1 -//Don't use quickprof for now, because it contains STL. TODO: replace STL by Bullet container classes. - - -//if you don't need btClock, you can comment next line -#define USE_BT_CLOCK 1 - -#ifdef USE_BT_CLOCK -#ifdef __CELLOS_LV2__ -#include -#include -typedef uint64_t __int64; -#endif - -#if defined (SUNOS) || defined (__SUNOS__) - #include -#endif - -#if defined(WIN32) || defined(_WIN32) - - #define USE_WINDOWS_TIMERS - #define WIN32_LEAN_AND_MEAN - #define NOWINRES - #define NOMCX - #define NOIME -#ifdef _XBOX - #include -#else - #include -#endif - #include - -#else - #include -#endif - -#define mymin(a,b) (a > b ? a : b) - -/// basic clock -class btClock - { - public: - btClock() - { -#ifdef USE_WINDOWS_TIMERS - QueryPerformanceFrequency(&mClockFrequency); -#endif - reset(); - } - - ~btClock() - { - } - - /// Resets the initial reference time. - void reset() - { -#ifdef USE_WINDOWS_TIMERS - QueryPerformanceCounter(&mStartTime); - mStartTick = GetTickCount(); - mPrevElapsedTime = 0; -#else -#ifdef __CELLOS_LV2__ - - typedef uint64_t __int64; - typedef __int64 ClockSize; - ClockSize newTime; - __asm __volatile__( "mftb %0" : "=r" (newTime) : : "memory"); - mStartTime = newTime; -#else - gettimeofday(&mStartTime, 0); -#endif - -#endif - } - - /// Returns the time in ms since the last call to reset or since - /// the btClock was created. - unsigned long int getTimeMilliseconds() - { -#ifdef USE_WINDOWS_TIMERS - LARGE_INTEGER currentTime; - QueryPerformanceCounter(¤tTime); - LONGLONG elapsedTime = currentTime.QuadPart - - mStartTime.QuadPart; - - // Compute the number of millisecond ticks elapsed. - unsigned long msecTicks = (unsigned long)(1000 * elapsedTime / - mClockFrequency.QuadPart); - - // Check for unexpected leaps in the Win32 performance counter. - // (This is caused by unexpected data across the PCI to ISA - // bridge, aka south bridge. See Microsoft KB274323.) - unsigned long elapsedTicks = GetTickCount() - mStartTick; - signed long msecOff = (signed long)(msecTicks - elapsedTicks); - if (msecOff < -100 || msecOff > 100) - { - // Adjust the starting time forwards. - LONGLONG msecAdjustment = mymin(msecOff * - mClockFrequency.QuadPart / 1000, elapsedTime - - mPrevElapsedTime); - mStartTime.QuadPart += msecAdjustment; - elapsedTime -= msecAdjustment; - - // Recompute the number of millisecond ticks elapsed. - msecTicks = (unsigned long)(1000 * elapsedTime / - mClockFrequency.QuadPart); - } - - // Store the current elapsed time for adjustments next time. - mPrevElapsedTime = elapsedTime; - - return msecTicks; -#else - -#ifdef __CELLOS_LV2__ - __int64 freq=sys_time_get_timebase_frequency(); - double dFreq=((double) freq) / 1000.0; - typedef uint64_t __int64; - typedef __int64 ClockSize; - ClockSize newTime; - __asm __volatile__( "mftb %0" : "=r" (newTime) : : "memory"); - - return (newTime-mStartTime) / dFreq; -#else - - struct timeval currentTime; - gettimeofday(¤tTime, 0); - return (currentTime.tv_sec - mStartTime.tv_sec) * 1000 + - (currentTime.tv_usec - mStartTime.tv_usec) / 1000; -#endif //__CELLOS_LV2__ -#endif - } - - /// Returns the time in us since the last call to reset or since - /// the Clock was created. - unsigned long int getTimeMicroseconds() - { -#ifdef USE_WINDOWS_TIMERS - LARGE_INTEGER currentTime; - QueryPerformanceCounter(¤tTime); - LONGLONG elapsedTime = currentTime.QuadPart - - mStartTime.QuadPart; - - // Compute the number of millisecond ticks elapsed. - unsigned long msecTicks = (unsigned long)(1000 * elapsedTime / - mClockFrequency.QuadPart); - - // Check for unexpected leaps in the Win32 performance counter. - // (This is caused by unexpected data across the PCI to ISA - // bridge, aka south bridge. See Microsoft KB274323.) - unsigned long elapsedTicks = GetTickCount() - mStartTick; - signed long msecOff = (signed long)(msecTicks - elapsedTicks); - if (msecOff < -100 || msecOff > 100) - { - // Adjust the starting time forwards. - LONGLONG msecAdjustment = mymin(msecOff * - mClockFrequency.QuadPart / 1000, elapsedTime - - mPrevElapsedTime); - mStartTime.QuadPart += msecAdjustment; - elapsedTime -= msecAdjustment; - } - - // Store the current elapsed time for adjustments next time. - mPrevElapsedTime = elapsedTime; - - // Convert to microseconds. - unsigned long usecTicks = (unsigned long)(1000000 * elapsedTime / - mClockFrequency.QuadPart); - - return usecTicks; -#else - -#ifdef __CELLOS_LV2__ - __int64 freq=sys_time_get_timebase_frequency(); - double dFreq=((double) freq)/ 1000000.0; - typedef uint64_t __int64; - typedef __int64 ClockSize; - ClockSize newTime; - __asm __volatile__( "mftb %0" : "=r" (newTime) : : "memory"); - - return (newTime-mStartTime) / dFreq; -#else - - struct timeval currentTime; - gettimeofday(¤tTime, 0); - return (currentTime.tv_sec - mStartTime.tv_sec) * 1000000 + - (currentTime.tv_usec - mStartTime.tv_usec); -#endif//__CELLOS_LV2__ -#endif - } - - private: -#ifdef USE_WINDOWS_TIMERS - LARGE_INTEGER mClockFrequency; - DWORD mStartTick; - LONGLONG mPrevElapsedTime; - LARGE_INTEGER mStartTime; -#else -#ifdef __CELLOS_LV2__ - uint64_t mStartTime; -#else - struct timeval mStartTime; -#endif -#endif //__CELLOS_LV2__ - - }; - -#endif //USE_BT_CLOCK - - -#ifdef USE_QUICKPROF - - -#include -#include -#include -#include - - - - -namespace hidden -{ - /// A simple data structure representing a single timed block - /// of code. - struct ProfileBlock - { - ProfileBlock() - { - currentBlockStartMicroseconds = 0; - currentCycleTotalMicroseconds = 0; - lastCycleTotalMicroseconds = 0; - totalMicroseconds = 0; - } - - /// The starting time (in us) of the current block update. - unsigned long int currentBlockStartMicroseconds; - - /// The accumulated time (in us) spent in this block during the - /// current profiling cycle. - unsigned long int currentCycleTotalMicroseconds; - - /// The accumulated time (in us) spent in this block during the - /// past profiling cycle. - unsigned long int lastCycleTotalMicroseconds; - - /// The total accumulated time (in us) spent in this block. - unsigned long int totalMicroseconds; - }; - -}; - -/// A static class that manages timing for a set of profiling blocks. -class btProfiler -{ -public: - /// A set of ways to retrieve block timing data. - enum BlockTimingMethod - { - /// The total time spent in the block (in seconds) since the - /// profiler was initialized. - BLOCK_TOTAL_SECONDS, - - /// The total time spent in the block (in ms) since the - /// profiler was initialized. - BLOCK_TOTAL_MILLISECONDS, - - /// The total time spent in the block (in us) since the - /// profiler was initialized. - BLOCK_TOTAL_MICROSECONDS, - - /// The total time spent in the block, as a % of the total - /// elapsed time since the profiler was initialized. - BLOCK_TOTAL_PERCENT, - - /// The time spent in the block (in seconds) in the most recent - /// profiling cycle. - BLOCK_CYCLE_SECONDS, - - /// The time spent in the block (in ms) in the most recent - /// profiling cycle. - BLOCK_CYCLE_MILLISECONDS, - - /// The time spent in the block (in us) in the most recent - /// profiling cycle. - BLOCK_CYCLE_MICROSECONDS, - - /// The time spent in the block (in seconds) in the most recent - /// profiling cycle, as a % of the total cycle time. - BLOCK_CYCLE_PERCENT - }; - - /// Initializes the profiler. This must be called first. If this is - /// never called, the profiler is effectively disabled; all other - /// functions will return immediately. The first parameter - /// is the name of an output data file; if this string is not empty, - /// data will be saved on every profiling cycle; if this string is - /// empty, no data will be saved to a file. The second parameter - /// determines which timing method is used when printing data to the - /// output file. - inline static void init(const std::string outputFilename="", - BlockTimingMethod outputMethod=BLOCK_CYCLE_MILLISECONDS); - - /// Cleans up allocated memory. - inline static void destroy(); - - /// Begins timing the named block of code. - inline static void beginBlock(const std::string& name); - - /// Updates the accumulated time spent in the named block by adding - /// the elapsed time since the last call to startBlock for this block - /// name. - inline static void endBlock(const std::string& name); - - /// Returns the time spent in the named block according to the - /// given timing method. See comments on BlockTimingMethod for details. - inline static double getBlockTime(const std::string& name, - BlockTimingMethod method=BLOCK_CYCLE_MILLISECONDS); - - /// Defines the end of a profiling cycle. Use this regularly if you - /// want to generate detailed timing information. This must not be - /// called within a timing block. - inline static void endProfilingCycle(); - - /// A helper function that creates a string of statistics for - /// each timing block. This is mainly for printing an overall - /// summary to the command line. - inline static std::string createStatsString( - BlockTimingMethod method=BLOCK_TOTAL_PERCENT); - -//private: - inline btProfiler(); - - inline ~btProfiler(); - - /// Prints an error message to standard output. - inline static void printError(const std::string& msg) - { - //btAssert(0); - std::cout << "[QuickProf error] " << msg << std::endl; - } - - /// Determines whether the profiler is enabled. - static bool mEnabled; - - /// The clock used to time profile blocks. - static btClock mClock; - - /// The starting time (in us) of the current profiling cycle. - static unsigned long int mCurrentCycleStartMicroseconds; - - /// The duration (in us) of the most recent profiling cycle. - static unsigned long int mLastCycleDurationMicroseconds; - - /// Internal map of named profile blocks. - static std::map mProfileBlocks; - - /// The data file used if this feature is enabled in 'init.' - static std::ofstream mOutputFile; - - /// Tracks whether we have begun print data to the output file. - static bool mFirstFileOutput; - - /// The method used when printing timing data to an output file. - static BlockTimingMethod mFileOutputMethod; - - /// The number of the current profiling cycle. - static unsigned long int mCycleNumber; -}; - - -btProfiler::btProfiler() -{ - // This never gets called because a btProfiler instance is never - // created. -} - -btProfiler::~btProfiler() -{ - // This never gets called because a btProfiler instance is never - // created. -} - -void btProfiler::init(const std::string outputFilename, - BlockTimingMethod outputMethod) -{ - mEnabled = true; - - if (!outputFilename.empty()) - { - mOutputFile.open(outputFilename.c_str()); - } - - mFileOutputMethod = outputMethod; - - mClock.reset(); - - // Set the start time for the first cycle. - mCurrentCycleStartMicroseconds = mClock.getTimeMicroseconds(); -} - -void btProfiler::destroy() -{ - if (!mEnabled) - { - return; - } - - if (mOutputFile.is_open()) - { - mOutputFile.close(); - } - - // Destroy all ProfileBlocks. - while (!mProfileBlocks.empty()) - { - delete (*mProfileBlocks.begin()).second; - mProfileBlocks.erase(mProfileBlocks.begin()); - } -} - -void btProfiler::beginBlock(const std::string& name) -{ - if (!mEnabled) - { - return; - } - - if (name.empty()) - { - printError("Cannot allow unnamed profile blocks."); - return; - } - - hidden::ProfileBlock* block = mProfileBlocks[name]; - - if (!block) - { - // Create a new ProfileBlock. - mProfileBlocks[name] = new hidden::ProfileBlock(); - block = mProfileBlocks[name]; - } - - // We do this at the end to get more accurate results. - block->currentBlockStartMicroseconds = mClock.getTimeMicroseconds(); -} - -void btProfiler::endBlock(const std::string& name) -{ - if (!mEnabled) - { - return; - } - - // We do this at the beginning to get more accurate results. - unsigned long int endTick = mClock.getTimeMicroseconds(); - - hidden::ProfileBlock* block = mProfileBlocks[name]; - - if (!block) - { - // The named block does not exist. Print an error. - printError("The profile block named '" + name + - "' does not exist."); - return; - } - - unsigned long int blockDuration = endTick - - block->currentBlockStartMicroseconds; - block->currentCycleTotalMicroseconds += blockDuration; - block->totalMicroseconds += blockDuration; -} - -double btProfiler::getBlockTime(const std::string& name, - BlockTimingMethod method) -{ - if (!mEnabled) - { - return 0; - } - - hidden::ProfileBlock* block = mProfileBlocks[name]; - - if (!block) - { - // The named block does not exist. Print an error. - printError("The profile block named '" + name + - "' does not exist."); - return 0; - } - - double result = 0; - - switch(method) - { - case BLOCK_TOTAL_SECONDS: - result = (double)block->totalMicroseconds * (double)0.000001; - break; - case BLOCK_TOTAL_MILLISECONDS: - result = (double)block->totalMicroseconds * (double)0.001; - break; - case BLOCK_TOTAL_MICROSECONDS: - result = (double)block->totalMicroseconds; - break; - case BLOCK_TOTAL_PERCENT: - { - double timeSinceInit = (double)mClock.getTimeMicroseconds(); - if (timeSinceInit <= 0) - { - result = 0; - } - else - { - result = 100.0 * (double)block->totalMicroseconds / - timeSinceInit; - } - break; - } - case BLOCK_CYCLE_SECONDS: - result = (double)block->lastCycleTotalMicroseconds * - (double)0.000001; - break; - case BLOCK_CYCLE_MILLISECONDS: - result = (double)block->lastCycleTotalMicroseconds * - (double)0.001; - break; - case BLOCK_CYCLE_MICROSECONDS: - result = (double)block->lastCycleTotalMicroseconds; - break; - case BLOCK_CYCLE_PERCENT: - { - if (0 == mLastCycleDurationMicroseconds) - { - // We have not yet finished a cycle, so just return zero - // percent to avoid a divide by zero error. - result = 0; - } - else - { - result = 100.0 * (double)block->lastCycleTotalMicroseconds / - mLastCycleDurationMicroseconds; - } - break; - } - default: - break; - } - - return result; -} - -void btProfiler::endProfilingCycle() -{ - if (!mEnabled) - { - return; - } - - // Store the duration of the cycle that just finished. - mLastCycleDurationMicroseconds = mClock.getTimeMicroseconds() - - mCurrentCycleStartMicroseconds; - - // For each block, update data for the cycle that just finished. - std::map::iterator iter; - for (iter = mProfileBlocks.begin(); iter != mProfileBlocks.end(); ++iter) - { - hidden::ProfileBlock* block = (*iter).second; - block->lastCycleTotalMicroseconds = - block->currentCycleTotalMicroseconds; - block->currentCycleTotalMicroseconds = 0; - } - - if (mOutputFile.is_open()) - { - // Print data to the output file. - if (mFirstFileOutput) - { - // On the first iteration, print a header line that shows the - // names of each profiling block. - mOutputFile << "#cycle, "; - - for (iter = mProfileBlocks.begin(); iter != mProfileBlocks.end(); - ++iter) - { - mOutputFile << (*iter).first << ", "; - } - - mOutputFile << std::endl; - mFirstFileOutput = false; - } - - mOutputFile << mCycleNumber << ", "; - - for (iter = mProfileBlocks.begin(); iter != mProfileBlocks.end(); - ++iter) - { - mOutputFile << getBlockTime((*iter).first, mFileOutputMethod) - << ", "; - } - - mOutputFile << std::endl; - } - - ++mCycleNumber; - mCurrentCycleStartMicroseconds = mClock.getTimeMicroseconds(); -} - -std::string btProfiler::createStatsString(BlockTimingMethod method) -{ - if (!mEnabled) - { - return ""; - } - - std::string s; - std::string suffix; - - switch(method) - { - case BLOCK_TOTAL_SECONDS: - suffix = "s"; - break; - case BLOCK_TOTAL_MILLISECONDS: - suffix = "ms"; - break; - case BLOCK_TOTAL_MICROSECONDS: - suffix = "us"; - break; - case BLOCK_TOTAL_PERCENT: - { - suffix = "%"; - break; - } - case BLOCK_CYCLE_SECONDS: - suffix = "s"; - break; - case BLOCK_CYCLE_MILLISECONDS: - suffix = "ms"; - break; - case BLOCK_CYCLE_MICROSECONDS: - suffix = "us"; - break; - case BLOCK_CYCLE_PERCENT: - { - suffix = "%"; - break; - } - default: - break; - } - - std::map::iterator iter; - for (iter = mProfileBlocks.begin(); iter != mProfileBlocks.end(); ++iter) - { - if (iter != mProfileBlocks.begin()) - { - s += "\n"; - } - - char blockTime[64]; - sprintf(blockTime, "%lf", getBlockTime((*iter).first, method)); - - s += (*iter).first; - s += ": "; - s += blockTime; - s += " "; - s += suffix; - } - - return s; -} - - -#define BEGIN_PROFILE(a) btProfiler::beginBlock(a) -#define END_PROFILE(a) btProfiler::endBlock(a) - -#else //USE_QUICKPROF -#define BEGIN_PROFILE(a) -#define END_PROFILE(a) - -#endif //USE_QUICKPROF - -#endif //QUICK_PROF_H - - diff --git a/extern/bullet2/src/LinearMath/btRandom.h b/extern/bullet2/src/LinearMath/btRandom.h deleted file mode 100644 index fdf65e01caf..00000000000 --- a/extern/bullet2/src/LinearMath/btRandom.h +++ /dev/null @@ -1,42 +0,0 @@ -/* -Copyright (c) 2003-2006 Gino van den Bergen / 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 GEN_RANDOM_H -#define GEN_RANDOM_H - -#ifdef MT19937 - -#include -#include - -#define GEN_RAND_MAX UINT_MAX - -SIMD_FORCE_INLINE void GEN_srand(unsigned int seed) { init_genrand(seed); } -SIMD_FORCE_INLINE unsigned int GEN_rand() { return genrand_int32(); } - -#else - -#include - -#define GEN_RAND_MAX RAND_MAX - -SIMD_FORCE_INLINE void GEN_srand(unsigned int seed) { srand(seed); } -SIMD_FORCE_INLINE unsigned int GEN_rand() { return rand(); } - -#endif - -#endif - diff --git a/extern/bullet2/src/LinearMath/btScalar.h b/extern/bullet2/src/LinearMath/btScalar.h deleted file mode 100644 index 85dfaf3eb83..00000000000 --- a/extern/bullet2/src/LinearMath/btScalar.h +++ /dev/null @@ -1,394 +0,0 @@ -/* -Copyright (c) 2003-2006 Gino van den Bergen / 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 SIMD___SCALAR_H -#define SIMD___SCALAR_H - -#include - -#include -#include -#include - - -inline int btGetVersion() -{ - return 264; -} - -#ifdef WIN32 - - #if defined(__MINGW32__) || defined(__CYGWIN__) || (defined (_MSC_VER) && _MSC_VER < 1300) - - #define SIMD_FORCE_INLINE inline - #define ATTRIBUTE_ALIGNED16(a) a - #define ATTRIBUTE_ALIGNED128(a) a - #else - #define BT_HAS_ALIGNED_ALLOCATOR - #pragma warning(disable:4530) - #pragma warning(disable:4996) - #pragma warning(disable:4786) - #define SIMD_FORCE_INLINE __forceinline - #define ATTRIBUTE_ALIGNED16(a) __declspec(align(16)) a - #define ATTRIBUTE_ALIGNED128(a) __declspec (align(128)) a - #ifdef _XBOX - #define BT_USE_VMX128 - - #include - #define BT_HAVE_NATIVE_FSEL - #define btFsel(a,b,c) __fsel((a),(b),(c)) - #else - #define BT_USE_SSE - #endif - #endif //__MINGW32__ - - #include - #define btAssert assert - //btFullAssert is optional, slows down a lot - #define btFullAssert(x) - - #define btLikely(_c) _c - #define btUnlikely(_c) _c - -#else - -#if defined (__CELLOS_LV2__) - #define SIMD_FORCE_INLINE inline - #define ATTRIBUTE_ALIGNED16(a) a __attribute__ ((aligned (16))) - #define ATTRIBUTE_ALIGNED128(a) a __attribute__ ((aligned (128))) - #ifndef assert - #include - #endif - #define btAssert assert - //btFullAssert is optional, slows down a lot - #define btFullAssert(x) - - #define btLikely(_c) _c - #define btUnlikely(_c) _c - -#else - -#ifdef USE_LIBSPE2 - - #define SIMD_FORCE_INLINE __inline - #define ATTRIBUTE_ALIGNED16(a) a __attribute__ ((aligned (16))) - #define ATTRIBUTE_ALIGNED128(a) a __attribute__ ((aligned (128))) - #ifndef assert - #include - #endif - #define btAssert assert - //btFullAssert is optional, slows down a lot - #define btFullAssert(x) - - - #define btLikely(_c) __builtin_expect((_c), 1) - #define btUnlikely(_c) __builtin_expect((_c), 0) - - -#else - //non-windows systems - - #define SIMD_FORCE_INLINE inline - #define ATTRIBUTE_ALIGNED16(a) a - #define ATTRIBUTE_ALIGNED128(a) a - #ifndef assert - #include - #endif - #define btAssert assert - //btFullAssert is optional, slows down a lot - #define btFullAssert(x) - - -#endif // LIBSPE2 - -#endif //__CELLOS_LV2__ -#endif - -/// older compilers (gcc 3.x) and Sun needs double version of sqrt etc. -/// exclude Apple Intel (i's assumed to be a Macbook or new Intel Dual Core Processor) -#if defined (__sun) || defined (__sun__) || defined (__sparc) || (defined (__APPLE__) && ! defined (__i386__)) -//use slow double float precision operation on those platforms -#ifndef BT_USE_DOUBLE_PRECISION -#define BT_FORCE_DOUBLE_FUNCTIONS -#endif -#endif - -#if defined(BT_USE_DOUBLE_PRECISION) -typedef double btScalar; -#else -typedef float btScalar; -#endif - - -#define BT_DECLARE_ALIGNED_ALLOCATOR() \ - SIMD_FORCE_INLINE void* operator new(size_t sizeInBytes) { return btAlignedAlloc(sizeInBytes,16); } \ - SIMD_FORCE_INLINE void operator delete(void* ptr) { btAlignedFree(ptr); } \ - SIMD_FORCE_INLINE void* operator new(size_t, void* ptr) { return ptr; } \ - SIMD_FORCE_INLINE void operator delete(void*, void*) { } \ - - - -#if defined(BT_USE_DOUBLE_PRECISION) || defined(BT_FORCE_DOUBLE_FUNCTIONS) - -SIMD_FORCE_INLINE btScalar btSqrt(btScalar x) { return sqrt(x); } -SIMD_FORCE_INLINE btScalar btFabs(btScalar x) { return fabs(x); } -SIMD_FORCE_INLINE btScalar btCos(btScalar x) { return cos(x); } -SIMD_FORCE_INLINE btScalar btSin(btScalar x) { return sin(x); } -SIMD_FORCE_INLINE btScalar btTan(btScalar x) { return tan(x); } -SIMD_FORCE_INLINE btScalar btAcos(btScalar x) { return acos(x); } -SIMD_FORCE_INLINE btScalar btAsin(btScalar x) { return asin(x); } -SIMD_FORCE_INLINE btScalar btAtan(btScalar x) { return atan(x); } -SIMD_FORCE_INLINE btScalar btAtan2(btScalar x, btScalar y) { return atan2(x, y); } -SIMD_FORCE_INLINE btScalar btExp(btScalar x) { return exp(x); } -SIMD_FORCE_INLINE btScalar btLog(btScalar x) { return log(x); } -SIMD_FORCE_INLINE btScalar btPow(btScalar x,btScalar y) { return pow(x,y); } - -#else - -SIMD_FORCE_INLINE btScalar btSqrt(btScalar y) -{ -#ifdef USE_APPROXIMATION - double x, z, tempf; - unsigned long *tfptr = ((unsigned long *)&tempf) + 1; - - tempf = y; - *tfptr = (0xbfcdd90a - *tfptr)>>1; /* estimate of 1/sqrt(y) */ - x = tempf; - z = y*btScalar(0.5); /* hoist out the “/2” */ - x = (btScalar(1.5)*x)-(x*x)*(x*z); /* iteration formula */ - x = (btScalar(1.5)*x)-(x*x)*(x*z); - x = (btScalar(1.5)*x)-(x*x)*(x*z); - x = (btScalar(1.5)*x)-(x*x)*(x*z); - x = (btScalar(1.5)*x)-(x*x)*(x*z); - return x*y; -#else - return sqrtf(y); -#endif -} -SIMD_FORCE_INLINE btScalar btFabs(btScalar x) { return fabsf(x); } -SIMD_FORCE_INLINE btScalar btCos(btScalar x) { return cosf(x); } -SIMD_FORCE_INLINE btScalar btSin(btScalar x) { return sinf(x); } -SIMD_FORCE_INLINE btScalar btTan(btScalar x) { return tanf(x); } -SIMD_FORCE_INLINE btScalar btAcos(btScalar x) { - btAssert(x <= btScalar(1.)); - return acosf(x); -} -SIMD_FORCE_INLINE btScalar btAsin(btScalar x) { return asinf(x); } -SIMD_FORCE_INLINE btScalar btAtan(btScalar x) { return atanf(x); } -SIMD_FORCE_INLINE btScalar btAtan2(btScalar x, btScalar y) { return atan2f(x, y); } -SIMD_FORCE_INLINE btScalar btExp(btScalar x) { return expf(x); } -SIMD_FORCE_INLINE btScalar btLog(btScalar x) { return logf(x); } -SIMD_FORCE_INLINE btScalar btPow(btScalar x,btScalar y) { return powf(x,y); } - -#endif - -#define SIMD_2_PI btScalar(6.283185307179586232) -#define SIMD_PI (SIMD_2_PI * btScalar(0.5)) -#define SIMD_HALF_PI (SIMD_2_PI * btScalar(0.25)) -#define SIMD_RADS_PER_DEG (SIMD_2_PI / btScalar(360.0)) -#define SIMD_DEGS_PER_RAD (btScalar(360.0) / SIMD_2_PI) - -#ifdef BT_USE_DOUBLE_PRECISION -#define SIMD_EPSILON DBL_EPSILON -#define SIMD_INFINITY DBL_MAX -#else -#define SIMD_EPSILON FLT_EPSILON -#define SIMD_INFINITY FLT_MAX -#endif - -SIMD_FORCE_INLINE btScalar btAtan2Fast(btScalar y, btScalar x) -{ - btScalar coeff_1 = SIMD_PI / 4.0f; - btScalar coeff_2 = 3.0f * coeff_1; - btScalar abs_y = btFabs(y); - btScalar angle; - if (x >= 0.0f) { - btScalar r = (x - abs_y) / (x + abs_y); - angle = coeff_1 - coeff_1 * r; - } else { - btScalar r = (x + abs_y) / (abs_y - x); - angle = coeff_2 - coeff_1 * r; - } - return (y < 0.0f) ? -angle : angle; -} - -SIMD_FORCE_INLINE bool btFuzzyZero(btScalar x) { return btFabs(x) < SIMD_EPSILON; } - -SIMD_FORCE_INLINE bool btEqual(btScalar a, btScalar eps) { - return (((a) <= eps) && !((a) < -eps)); -} -SIMD_FORCE_INLINE bool btGreaterEqual (btScalar a, btScalar eps) { - return (!((a) <= eps)); -} - - -SIMD_FORCE_INLINE int btIsNegative(btScalar x) { - return x < btScalar(0.0) ? 1 : 0; -} - -SIMD_FORCE_INLINE btScalar btRadians(btScalar x) { return x * SIMD_RADS_PER_DEG; } -SIMD_FORCE_INLINE btScalar btDegrees(btScalar x) { return x * SIMD_DEGS_PER_RAD; } - -#define BT_DECLARE_HANDLE(name) typedef struct name##__ { int unused; } *name - -#ifndef btFsel -SIMD_FORCE_INLINE btScalar btFsel(btScalar a, btScalar b, btScalar c) -{ - return a >= 0 ? b : c; -} -#endif -#define btFsels(a,b,c) (btScalar)btFsel(a,b,c) - - -SIMD_FORCE_INLINE bool btMachineIsLittleEndian() -{ - long int i = 1; - const char *p = (const char *) &i; - if (p[0] == 1) // Lowest address contains the least significant byte - return true; - else - return false; -} - - - -///btSelect avoids branches, which makes performance much better for consoles like Playstation 3 and XBox 360 -///Thanks Phil Knight. See also http://www.cellperformance.com/articles/2006/04/more_techniques_for_eliminatin_1.html -SIMD_FORCE_INLINE unsigned btSelect(unsigned condition, unsigned valueIfConditionNonZero, unsigned valueIfConditionZero) -{ - // Set testNz to 0xFFFFFFFF if condition is nonzero, 0x00000000 if condition is zero - // Rely on positive value or'ed with its negative having sign bit on - // and zero value or'ed with its negative (which is still zero) having sign bit off - // Use arithmetic shift right, shifting the sign bit through all 32 bits - unsigned testNz = (unsigned)(((int)condition | -(int)condition) >> 31); - unsigned testEqz = ~testNz; - return ((valueIfConditionNonZero & testNz) | (valueIfConditionZero & testEqz)); -} -SIMD_FORCE_INLINE int btSelect(unsigned condition, int valueIfConditionNonZero, int valueIfConditionZero) -{ - unsigned testNz = (unsigned)(((int)condition | -(int)condition) >> 31); - unsigned testEqz = ~testNz; - return ((valueIfConditionNonZero & testNz) | (valueIfConditionZero & testEqz)); -} -SIMD_FORCE_INLINE float btSelect(unsigned condition, float valueIfConditionNonZero, float valueIfConditionZero) -{ -#ifdef BT_HAVE_NATIVE_FSEL - return (float)btFsel((btScalar)condition - btScalar(1.0f), valueIfConditionNonZero, valueIfConditionZero); -#else - return (condition != 0) ? valueIfConditionNonZero : valueIfConditionZero; -#endif -} - -template SIMD_FORCE_INLINE void btSwap(T& a, T& b) -{ - T tmp = a; - a = b; - b = tmp; -} - - -//PCK: endian swapping functions -SIMD_FORCE_INLINE unsigned btSwapEndian(unsigned val) -{ - return (((val & 0xff000000) >> 24) | ((val & 0x00ff0000) >> 8) | ((val & 0x0000ff00) << 8) | ((val & 0x000000ff) << 24)); -} - -SIMD_FORCE_INLINE unsigned short btSwapEndian(unsigned short val) -{ - return (((val & 0xff00) >> 8) | ((val & 0x00ff) << 8)); -} - -SIMD_FORCE_INLINE unsigned btSwapEndian(int val) -{ - return btSwapEndian((unsigned)val); -} - -SIMD_FORCE_INLINE unsigned short btSwapEndian(short val) -{ - return btSwapEndian((unsigned short) val); -} - -///btSwapFloat uses using char pointers to swap the endianness -////btSwapFloat/btSwapDouble will NOT return a float, because the machine might 'correct' invalid floating point values -///Not all values of sign/exponent/mantissa are valid floating point numbers according to IEEE 754. -///When a floating point unit is faced with an invalid value, it may actually change the value, or worse, throw an exception. -///In most systems, running user mode code, you wouldn't get an exception, but instead the hardware/os/runtime will 'fix' the number for you. -///so instead of returning a float/double, we return integer/long long integer -SIMD_FORCE_INLINE unsigned int btSwapEndianFloat(float d) -{ - unsigned int a; - unsigned char *dst = (unsigned char *)&a; - unsigned char *src = (unsigned char *)&d; - - dst[0] = src[3]; - dst[1] = src[2]; - dst[2] = src[1]; - dst[3] = src[0]; - return a; -} - -// unswap using char pointers -SIMD_FORCE_INLINE float btUnswapEndianFloat(unsigned int a) -{ - float d; - unsigned char *src = (unsigned char *)&a; - unsigned char *dst = (unsigned char *)&d; - - dst[0] = src[3]; - dst[1] = src[2]; - dst[2] = src[1]; - dst[3] = src[0]; - - return d; -} - - -// swap using char pointers -SIMD_FORCE_INLINE void btSwapEndianDouble(double d, unsigned char* dst) -{ - unsigned char *src = (unsigned char *)&d; - - dst[0] = src[7]; - dst[1] = src[6]; - dst[2] = src[5]; - dst[3] = src[4]; - dst[4] = src[3]; - dst[5] = src[2]; - dst[6] = src[1]; - dst[7] = src[0]; - -} - -// unswap using char pointers -SIMD_FORCE_INLINE double btUnswapEndianDouble(const unsigned char *src) -{ - double d; - unsigned char *dst = (unsigned char *)&d; - - dst[0] = src[7]; - dst[1] = src[6]; - dst[2] = src[5]; - dst[3] = src[4]; - dst[4] = src[3]; - dst[5] = src[2]; - dst[6] = src[1]; - dst[7] = src[0]; - - return d; -} - - -#endif //SIMD___SCALAR_H diff --git a/extern/bullet2/src/LinearMath/btSimdMinMax.h b/extern/bullet2/src/LinearMath/btSimdMinMax.h deleted file mode 100644 index 75e83f3c53f..00000000000 --- a/extern/bullet2/src/LinearMath/btSimdMinMax.h +++ /dev/null @@ -1,41 +0,0 @@ -/* -Copyright (c) 2003-2006 Gino van den Bergen / 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 SIMD_MINMAX_H -#define SIMD_MINMAX_H -#include "btScalar.h" - -template -SIMD_FORCE_INLINE const T& btMin(const T& a, const T& b) { - return b < a ? b : a; -} - -template -SIMD_FORCE_INLINE const T& btMax(const T& a, const T& b) { - return a < b ? b : a; -} - -template -SIMD_FORCE_INLINE void btSetMin(T& a, const T& b) { - if (a > b) a = b; -} - -template -SIMD_FORCE_INLINE void btSetMax(T& a, const T& b) { - if (a < b) a = b; -} - -#endif diff --git a/extern/bullet2/src/LinearMath/btStackAlloc.h b/extern/bullet2/src/LinearMath/btStackAlloc.h deleted file mode 100644 index ac940cd2edd..00000000000 --- a/extern/bullet2/src/LinearMath/btStackAlloc.h +++ /dev/null @@ -1,115 +0,0 @@ -/* -Copyright (c) 2003-2006 Gino van den Bergen / 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. -*/ - -/* -StackAlloc extracted from GJK-EPA collision solver by Nathanael Presson -Nov.2006 -*/ - -#ifndef BT_STACK_ALLOC -#define BT_STACK_ALLOC - -#include "btScalar.h" //for btAssert -#include "btAlignedAllocator.h" - -struct btBlock -{ - btBlock* previous; - unsigned char* address; -}; - -///StackAlloc provides some fast stack-based memory allocator (LIFO last-in first-out) -class btStackAlloc -{ -public: - - btStackAlloc(unsigned int size) { ctor();create(size); } - ~btStackAlloc() { destroy(); } - - inline void create(unsigned int size) - { - destroy(); - data = (unsigned char*) btAlignedAlloc(size,16); - totalsize = size; - } - inline void destroy() - { - btAssert(usedsize==0); - //Raise(L"StackAlloc is still in use"); - - if(usedsize==0) - { - if(!ischild && data) - btAlignedFree(data); - - data = 0; - usedsize = 0; - } - - } - - int getAvailableMemory() const - { - return totalsize - usedsize; - } - - unsigned char* allocate(unsigned int size) - { - const unsigned int nus(usedsize+size); - if(nusprevious = current; - pb->address = data+usedsize; - current = pb; - return(pb); - } - SIMD_FORCE_INLINE void endBlock(btBlock* block) - { - btAssert(block==current); - //Raise(L"Unmatched blocks"); - if(block==current) - { - current = block->previous; - usedsize = (unsigned int)((block->address-data)-sizeof(btBlock)); - } - } - -private: - void ctor() - { - data = 0; - totalsize = 0; - usedsize = 0; - current = 0; - ischild = false; - } - unsigned char* data; - unsigned int totalsize; - unsigned int usedsize; - btBlock* current; - bool ischild; -}; - -#endif //BT_STACK_ALLOC diff --git a/extern/bullet2/src/LinearMath/btTransform.h b/extern/bullet2/src/LinearMath/btTransform.h deleted file mode 100644 index 883b3a5d2b7..00000000000 --- a/extern/bullet2/src/LinearMath/btTransform.h +++ /dev/null @@ -1,200 +0,0 @@ -/* -Copyright (c) 2003-2006 Gino van den Bergen / 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 btTransform_H -#define btTransform_H - -#include "btVector3.h" -#include "btMatrix3x3.h" - - -///btTransform supports rigid transforms (only translation and rotation, no scaling/shear) -class btTransform { - - -public: - - - btTransform() {} - - explicit SIMD_FORCE_INLINE btTransform(const btQuaternion& q, - const btVector3& c = btVector3(btScalar(0), btScalar(0), btScalar(0))) - : m_basis(q), - m_origin(c) - {} - - explicit SIMD_FORCE_INLINE btTransform(const btMatrix3x3& b, - const btVector3& c = btVector3(btScalar(0), btScalar(0), btScalar(0))) - : m_basis(b), - m_origin(c) - {} - - SIMD_FORCE_INLINE btTransform (const btTransform& other) - : m_basis(other.m_basis), - m_origin(other.m_origin) - { - } - - SIMD_FORCE_INLINE btTransform& operator=(const btTransform& other) - { - m_basis = other.m_basis; - m_origin = other.m_origin; - return *this; - } - - - SIMD_FORCE_INLINE void mult(const btTransform& t1, const btTransform& t2) { - m_basis = t1.m_basis * t2.m_basis; - m_origin = t1(t2.m_origin); - } - -/* void multInverseLeft(const btTransform& t1, const btTransform& t2) { - btVector3 v = t2.m_origin - t1.m_origin; - m_basis = btMultTransposeLeft(t1.m_basis, t2.m_basis); - m_origin = v * t1.m_basis; - } - */ - - - SIMD_FORCE_INLINE btVector3 operator()(const btVector3& x) const - { - return btVector3(m_basis[0].dot(x) + m_origin.x(), - m_basis[1].dot(x) + m_origin.y(), - m_basis[2].dot(x) + m_origin.z()); - } - - SIMD_FORCE_INLINE btVector3 operator*(const btVector3& x) const - { - return (*this)(x); - } - - SIMD_FORCE_INLINE btMatrix3x3& getBasis() { return m_basis; } - SIMD_FORCE_INLINE const btMatrix3x3& getBasis() const { return m_basis; } - - SIMD_FORCE_INLINE btVector3& getOrigin() { return m_origin; } - SIMD_FORCE_INLINE const btVector3& getOrigin() const { return m_origin; } - - btQuaternion getRotation() const { - btQuaternion q; - m_basis.getRotation(q); - return q; - } - - - void setFromOpenGLMatrix(const btScalar *m) - { - m_basis.setFromOpenGLSubMatrix(m); - m_origin.setValue(m[12],m[13],m[14]); - } - - void getOpenGLMatrix(btScalar *m) const - { - m_basis.getOpenGLSubMatrix(m); - m[12] = m_origin.x(); - m[13] = m_origin.y(); - m[14] = m_origin.z(); - m[15] = btScalar(1.0); - } - - SIMD_FORCE_INLINE void setOrigin(const btVector3& origin) - { - m_origin = origin; - } - - SIMD_FORCE_INLINE btVector3 invXform(const btVector3& inVec) const; - - - - SIMD_FORCE_INLINE void setBasis(const btMatrix3x3& basis) - { - m_basis = basis; - } - - SIMD_FORCE_INLINE void setRotation(const btQuaternion& q) - { - m_basis.setRotation(q); - } - - - - void setIdentity() - { - m_basis.setIdentity(); - m_origin.setValue(btScalar(0.0), btScalar(0.0), btScalar(0.0)); - } - - - btTransform& operator*=(const btTransform& t) - { - m_origin += m_basis * t.m_origin; - m_basis *= t.m_basis; - return *this; - } - - btTransform inverse() const - { - btMatrix3x3 inv = m_basis.transpose(); - return btTransform(inv, inv * -m_origin); - } - - btTransform inverseTimes(const btTransform& t) const; - - btTransform operator*(const btTransform& t) const; - - static btTransform getIdentity() - { - btTransform tr; - tr.setIdentity(); - return tr; - } - -private: - - btMatrix3x3 m_basis; - btVector3 m_origin; -}; - - -SIMD_FORCE_INLINE btVector3 -btTransform::invXform(const btVector3& inVec) const -{ - btVector3 v = inVec - m_origin; - return (m_basis.transpose() * v); -} - -SIMD_FORCE_INLINE btTransform -btTransform::inverseTimes(const btTransform& t) const -{ - btVector3 v = t.getOrigin() - m_origin; - return btTransform(m_basis.transposeTimes(t.m_basis), - v * m_basis); -} - -SIMD_FORCE_INLINE btTransform -btTransform::operator*(const btTransform& t) const -{ - return btTransform(m_basis * t.m_basis, - (*this)(t.m_origin)); -} - - - -#endif - - - - - diff --git a/extern/bullet2/src/LinearMath/btTransformUtil.h b/extern/bullet2/src/LinearMath/btTransformUtil.h deleted file mode 100644 index d39e2e10074..00000000000 --- a/extern/bullet2/src/LinearMath/btTransformUtil.h +++ /dev/null @@ -1,142 +0,0 @@ -/* -Copyright (c) 2003-2006 Gino van den Bergen / 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 SIMD_TRANSFORM_UTIL_H -#define SIMD_TRANSFORM_UTIL_H - -#include "btTransform.h" -#define ANGULAR_MOTION_THRESHOLD btScalar(0.5)*SIMD_HALF_PI - - - -#define SIMDSQRT12 btScalar(0.7071067811865475244008443621048490) - -#define btRecipSqrt(x) ((btScalar)(btScalar(1.0)/btSqrt(btScalar(x)))) /* reciprocal square root */ - -SIMD_FORCE_INLINE btVector3 btAabbSupport(const btVector3& halfExtents,const btVector3& supportDir) -{ - return btVector3(supportDir.x() < btScalar(0.0) ? -halfExtents.x() : halfExtents.x(), - supportDir.y() < btScalar(0.0) ? -halfExtents.y() : halfExtents.y(), - supportDir.z() < btScalar(0.0) ? -halfExtents.z() : halfExtents.z()); -} - - -SIMD_FORCE_INLINE void btPlaneSpace1 (const btVector3& n, btVector3& p, btVector3& q) -{ - if (btFabs(n.z()) > SIMDSQRT12) { - // choose p in y-z plane - btScalar a = n[1]*n[1] + n[2]*n[2]; - btScalar k = btRecipSqrt (a); - p.setValue(0,-n[2]*k,n[1]*k); - // set q = n x p - q.setValue(a*k,-n[0]*p[2],n[0]*p[1]); - } - else { - // choose p in x-y plane - btScalar a = n.x()*n.x() + n.y()*n.y(); - btScalar k = btRecipSqrt (a); - p.setValue(-n.y()*k,n.x()*k,0); - // set q = n x p - q.setValue(-n.z()*p.y(),n.z()*p.x(),a*k); - } -} - - - -/// Utils related to temporal transforms -class btTransformUtil -{ - -public: - - static void integrateTransform(const btTransform& curTrans,const btVector3& linvel,const btVector3& angvel,btScalar timeStep,btTransform& predictedTransform) - { - predictedTransform.setOrigin(curTrans.getOrigin() + linvel * timeStep); -// #define QUATERNION_DERIVATIVE - #ifdef QUATERNION_DERIVATIVE - btQuaternion predictedOrn = curTrans.getRotation(); - predictedOrn += (angvel * predictedOrn) * (timeStep * btScalar(0.5)); - predictedOrn.normalize(); - #else - //exponential map - btVector3 axis; - btScalar fAngle = angvel.length(); - //limit the angular motion - if (fAngle*timeStep > ANGULAR_MOTION_THRESHOLD) - { - fAngle = ANGULAR_MOTION_THRESHOLD / timeStep; - } - - if ( fAngle < btScalar(0.001) ) - { - // use Taylor's expansions of sync function - axis = angvel*( btScalar(0.5)*timeStep-(timeStep*timeStep*timeStep)*(btScalar(0.020833333333))*fAngle*fAngle ); - } - else - { - // sync(fAngle) = sin(c*fAngle)/t - axis = angvel*( btSin(btScalar(0.5)*fAngle*timeStep)/fAngle ); - } - btQuaternion dorn (axis.x(),axis.y(),axis.z(),btCos( fAngle*timeStep*btScalar(0.5) )); - btQuaternion orn0 = curTrans.getRotation(); - - btQuaternion predictedOrn = dorn * orn0; - predictedOrn.normalize(); - #endif - predictedTransform.setRotation(predictedOrn); - } - - static void calculateVelocity(const btTransform& transform0,const btTransform& transform1,btScalar timeStep,btVector3& linVel,btVector3& angVel) - { - linVel = (transform1.getOrigin() - transform0.getOrigin()) / timeStep; - btVector3 axis; - btScalar angle; - calculateDiffAxisAngle(transform0,transform1,axis,angle); - angVel = axis * angle / timeStep; - } - - static void calculateDiffAxisAngle(const btTransform& transform0,const btTransform& transform1,btVector3& axis,btScalar& angle) - { - - #ifdef USE_QUATERNION_DIFF - btQuaternion orn0 = transform0.getRotation(); - btQuaternion orn1a = transform1.getRotation(); - btQuaternion orn1 = orn0.farthest(orn1a); - btQuaternion dorn = orn1 * orn0.inverse(); -#else - btMatrix3x3 dmat = transform1.getBasis() * transform0.getBasis().inverse(); - btQuaternion dorn; - dmat.getRotation(dorn); -#endif//USE_QUATERNION_DIFF - - ///floating point inaccuracy can lead to w component > 1..., which breaks - - dorn.normalize(); - - angle = dorn.getAngle(); - axis = btVector3(dorn.x(),dorn.y(),dorn.z()); - axis[3] = btScalar(0.); - //check for axis length - btScalar len = axis.length2(); - if (len < SIMD_EPSILON*SIMD_EPSILON) - axis = btVector3(btScalar(1.),btScalar(0.),btScalar(0.)); - else - axis /= btSqrt(len); - } - -}; - -#endif //SIMD_TRANSFORM_UTIL_H - diff --git a/extern/bullet2/src/LinearMath/btVector3.h b/extern/bullet2/src/LinearMath/btVector3.h deleted file mode 100644 index 1e331272dd8..00000000000 --- a/extern/bullet2/src/LinearMath/btVector3.h +++ /dev/null @@ -1,452 +0,0 @@ -/* -Copyright (c) 2003-2006 Gino van den Bergen / 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 SIMD__VECTOR3_H -#define SIMD__VECTOR3_H - -#include "btQuadWord.h" - -///btVector3 can be used to represent 3D points and vectors. -///It has an un-used w component to suit 16-byte alignment when btVector3 is stored in containers. This extra component can be used by derived classes (Quaternion?) or by user -///Ideally, this class should be replaced by a platform optimized SIMD version that keeps the data in registers -class btVector3 : public btQuadWord { - -public: - SIMD_FORCE_INLINE btVector3() {} - - SIMD_FORCE_INLINE btVector3(const btQuadWordStorage& q) - : btQuadWord(q) - { - } - - - SIMD_FORCE_INLINE btVector3(const btScalar& x, const btScalar& y, const btScalar& z) - :btQuadWord(x,y,z,btScalar(0.)) - { - } - -// SIMD_FORCE_INLINE btVector3(const btScalar& x, const btScalar& y, const btScalar& z,const btScalar& w) -// : btQuadWord(x,y,z,w) -// { -// } - - - - SIMD_FORCE_INLINE btVector3& operator+=(const btVector3& v) - { - m_x += v.x(); m_y += v.y(); m_z += v.z(); - return *this; - } - - - - SIMD_FORCE_INLINE btVector3& operator-=(const btVector3& v) - { - m_x -= v.x(); m_y -= v.y(); m_z -= v.z(); - return *this; - } - - SIMD_FORCE_INLINE btVector3& operator*=(const btScalar& s) - { - m_x *= s; m_y *= s; m_z *= s; - return *this; - } - - SIMD_FORCE_INLINE btVector3& operator/=(const btScalar& s) - { - btFullAssert(s != btScalar(0.0)); - return *this *= btScalar(1.0) / s; - } - - SIMD_FORCE_INLINE btScalar dot(const btVector3& v) const - { - return m_x * v.x() + m_y * v.y() + m_z * v.z(); - } - - SIMD_FORCE_INLINE btScalar length2() const - { - return dot(*this); - } - - SIMD_FORCE_INLINE btScalar length() const - { - return btSqrt(length2()); - } - - SIMD_FORCE_INLINE btScalar distance2(const btVector3& v) const; - - SIMD_FORCE_INLINE btScalar distance(const btVector3& v) const; - - SIMD_FORCE_INLINE btVector3& normalize() - { - return *this /= length(); - } - - SIMD_FORCE_INLINE btVector3 normalized() const; - - SIMD_FORCE_INLINE btVector3 rotate( const btVector3& wAxis, const btScalar angle ); - - SIMD_FORCE_INLINE btScalar angle(const btVector3& v) const - { - btScalar s = btSqrt(length2() * v.length2()); - btFullAssert(s != btScalar(0.0)); - return btAcos(dot(v) / s); - } - - SIMD_FORCE_INLINE btVector3 absolute() const - { - return btVector3( - btFabs(m_x), - btFabs(m_y), - btFabs(m_z)); - } - - SIMD_FORCE_INLINE btVector3 cross(const btVector3& v) const - { - return btVector3( - m_y * v.z() - m_z * v.y(), - m_z * v.x() - m_x * v.z(), - m_x * v.y() - m_y * v.x()); - } - - SIMD_FORCE_INLINE btScalar triple(const btVector3& v1, const btVector3& v2) const - { - return m_x * (v1.y() * v2.z() - v1.z() * v2.y()) + - m_y * (v1.z() * v2.x() - v1.x() * v2.z()) + - m_z * (v1.x() * v2.y() - v1.y() * v2.x()); - } - - SIMD_FORCE_INLINE int minAxis() const - { - return m_x < m_y ? (m_x < m_z ? 0 : 2) : (m_y < m_z ? 1 : 2); - } - - SIMD_FORCE_INLINE int maxAxis() const - { - return m_x < m_y ? (m_y < m_z ? 2 : 1) : (m_x < m_z ? 2 : 0); - } - - SIMD_FORCE_INLINE int furthestAxis() const - { - return absolute().minAxis(); - } - - SIMD_FORCE_INLINE int closestAxis() const - { - return absolute().maxAxis(); - } - - SIMD_FORCE_INLINE void setInterpolate3(const btVector3& v0, const btVector3& v1, btScalar rt) - { - btScalar s = btScalar(1.0) - rt; - m_x = s * v0.x() + rt * v1.x(); - m_y = s * v0.y() + rt * v1.y(); - m_z = s * v0.z() + rt * v1.z(); - //don't do the unused w component - // m_co[3] = s * v0[3] + rt * v1[3]; - } - - SIMD_FORCE_INLINE btVector3 lerp(const btVector3& v, const btScalar& t) const - { - return btVector3(m_x + (v.x() - m_x) * t, - m_y + (v.y() - m_y) * t, - m_z + (v.z() - m_z) * t); - } - - - SIMD_FORCE_INLINE btVector3& operator*=(const btVector3& v) - { - m_x *= v.x(); m_y *= v.y(); m_z *= v.z(); - return *this; - } - - - -}; - -SIMD_FORCE_INLINE btVector3 -operator+(const btVector3& v1, const btVector3& v2) -{ - return btVector3(v1.x() + v2.x(), v1.y() + v2.y(), v1.z() + v2.z()); -} - -SIMD_FORCE_INLINE btVector3 -operator*(const btVector3& v1, const btVector3& v2) -{ - return btVector3(v1.x() * v2.x(), v1.y() * v2.y(), v1.z() * v2.z()); -} - -SIMD_FORCE_INLINE btVector3 -operator-(const btVector3& v1, const btVector3& v2) -{ - return btVector3(v1.x() - v2.x(), v1.y() - v2.y(), v1.z() - v2.z()); -} - -SIMD_FORCE_INLINE btVector3 -operator-(const btVector3& v) -{ - return btVector3(-v.x(), -v.y(), -v.z()); -} - -SIMD_FORCE_INLINE btVector3 -operator*(const btVector3& v, const btScalar& s) -{ - return btVector3(v.x() * s, v.y() * s, v.z() * s); -} - -SIMD_FORCE_INLINE btVector3 -operator*(const btScalar& s, const btVector3& v) -{ - return v * s; -} - -SIMD_FORCE_INLINE btVector3 -operator/(const btVector3& v, const btScalar& s) -{ - btFullAssert(s != btScalar(0.0)); - return v * (btScalar(1.0) / s); -} - -SIMD_FORCE_INLINE btVector3 -operator/(const btVector3& v1, const btVector3& v2) -{ - return btVector3(v1.x() / v2.x(),v1.y() / v2.y(),v1.z() / v2.z()); -} - -SIMD_FORCE_INLINE btScalar -dot(const btVector3& v1, const btVector3& v2) -{ - return v1.dot(v2); -} - - - -SIMD_FORCE_INLINE btScalar -distance2(const btVector3& v1, const btVector3& v2) -{ - return v1.distance2(v2); -} - - -SIMD_FORCE_INLINE btScalar -distance(const btVector3& v1, const btVector3& v2) -{ - return v1.distance(v2); -} - -SIMD_FORCE_INLINE btScalar -angle(const btVector3& v1, const btVector3& v2) -{ - return v1.angle(v2); -} - -SIMD_FORCE_INLINE btVector3 -cross(const btVector3& v1, const btVector3& v2) -{ - return v1.cross(v2); -} - -SIMD_FORCE_INLINE btScalar -triple(const btVector3& v1, const btVector3& v2, const btVector3& v3) -{ - return v1.triple(v2, v3); -} - -SIMD_FORCE_INLINE btVector3 -lerp(const btVector3& v1, const btVector3& v2, const btScalar& t) -{ - return v1.lerp(v2, t); -} - - -SIMD_FORCE_INLINE bool operator==(const btVector3& p1, const btVector3& p2) -{ - return p1.x() == p2.x() && p1.y() == p2.y() && p1.z() == p2.z(); -} - -SIMD_FORCE_INLINE btScalar btVector3::distance2(const btVector3& v) const -{ - return (v - *this).length2(); -} - -SIMD_FORCE_INLINE btScalar btVector3::distance(const btVector3& v) const -{ - return (v - *this).length(); -} - -SIMD_FORCE_INLINE btVector3 btVector3::normalized() const -{ - return *this / length(); -} - -SIMD_FORCE_INLINE btVector3 btVector3::rotate( const btVector3& wAxis, const btScalar angle ) -{ - // wAxis must be a unit lenght vector - - btVector3 o = wAxis * wAxis.dot( *this ); - btVector3 x = *this - o; - btVector3 y; - - y = wAxis.cross( *this ); - - return ( o + x * btCos( angle ) + y * btSin( angle ) ); -} - -class btVector4 : public btVector3 -{ -public: - - SIMD_FORCE_INLINE btVector4() {} - - - SIMD_FORCE_INLINE btVector4(const btScalar& x, const btScalar& y, const btScalar& z,const btScalar& w) - : btVector3(x,y,z) - { - m_unusedW = w; - } - - - SIMD_FORCE_INLINE btVector4 absolute4() const - { - return btVector4( - btFabs(m_x), - btFabs(m_y), - btFabs(m_z), - btFabs(m_unusedW)); - } - - - - btScalar getW() const { return m_unusedW;} - - - SIMD_FORCE_INLINE int maxAxis4() const - { - int maxIndex = -1; - btScalar maxVal = btScalar(-1e30); - if (m_x > maxVal) - { - maxIndex = 0; - maxVal = m_x; - } - if (m_y > maxVal) - { - maxIndex = 1; - maxVal = m_y; - } - if (m_z > maxVal) - { - maxIndex = 2; - maxVal = m_z; - } - if (m_unusedW > maxVal) - { - maxIndex = 3; - maxVal = m_unusedW; - } - - - - - return maxIndex; - - } - - - SIMD_FORCE_INLINE int minAxis4() const - { - int minIndex = -1; - btScalar minVal = btScalar(1e30); - if (m_x < minVal) - { - minIndex = 0; - minVal = m_x; - } - if (m_y < minVal) - { - minIndex = 1; - minVal = m_y; - } - if (m_z < minVal) - { - minIndex = 2; - minVal = m_z; - } - if (m_unusedW < minVal) - { - minIndex = 3; - minVal = m_unusedW; - } - - return minIndex; - - } - - - SIMD_FORCE_INLINE int closestAxis4() const - { - return absolute4().maxAxis4(); - } - -}; - - -///btSwapVector3Endian swaps vector endianness, useful for network and cross-platform serialization -SIMD_FORCE_INLINE void btSwapScalarEndian(const btScalar& sourceVal, btScalar& destVal) -{ - #ifdef BT_USE_DOUBLE_PRECISION - unsigned char* dest = (unsigned char*) &destVal; - unsigned char* src = (unsigned char*) &sourceVal; - dest[0] = src[7]; - dest[1] = src[6]; - dest[2] = src[5]; - dest[3] = src[4]; - dest[4] = src[3]; - dest[5] = src[2]; - dest[6] = src[1]; - dest[7] = src[0]; -#else - unsigned char* dest = (unsigned char*) &destVal; - unsigned char* src = (unsigned char*) &sourceVal; - dest[0] = src[3]; - dest[1] = src[2]; - dest[2] = src[1]; - dest[3] = src[0]; -#endif //BT_USE_DOUBLE_PRECISION -} -///btSwapVector3Endian swaps vector endianness, useful for network and cross-platform serialization -SIMD_FORCE_INLINE void btSwapVector3Endian(const btVector3& sourceVec, btVector3& destVec) -{ - for (int i=0;i<4;i++) - { - btSwapScalarEndian(sourceVec[i],destVec[i]); - } - -} - -///btUnSwapVector3Endian swaps vector endianness, useful for network and cross-platform serialization -SIMD_FORCE_INLINE void btUnSwapVector3Endian(btVector3& vector) -{ - - btVector3 swappedVec; - for (int i=0;i<4;i++) - { - btSwapScalarEndian(vector[i],swappedVec[i]); - } - vector = swappedVec; -} - -#endif //SIMD__VECTOR3_H diff --git a/extern/bullet2/src/LinearMath/ibmsdk/Makefile b/extern/bullet2/src/LinearMath/ibmsdk/Makefile deleted file mode 100644 index 2ad26576241..00000000000 --- a/extern/bullet2/src/LinearMath/ibmsdk/Makefile +++ /dev/null @@ -1,30 +0,0 @@ -#### Source code Dirs -VPATH = ../ - -ROOT = ../../.. - -#### Library -LIBRARY_ppu = bulletmath.a - -#### Compiler flags -CPPFLAGS = \ --DUSE_LIBSPE2 \ --I$(ROOT)/src \ --I$(SDKINC) - -#### Optimization level flags -#CC_OPT_LEVEL = $(CC_OPT_LEVEL_DEBUG) -CC_OPT_LEVEL = -O3 - -##### Objects to be archived in lib - -OBJS = \ -btAlignedAllocator.o \ -btGeometryUtil.o \ -btQuickprof.o - -#### Install directories -INSTALL_DIR = $(ROOT)/lib/ibmsdk -INSTALL_FILES = $(LIBRARY_ppu) -CELL_TOP ?= /opt/ibm/cell-sdk/prototype -include $(CELL_TOP)/make.footer diff --git a/extern/bullet2/src/Makefile b/extern/bullet2/src/Makefile deleted file mode 100644 index 567811bae28..00000000000 --- a/extern/bullet2/src/Makefile +++ /dev/null @@ -1,71 +0,0 @@ -# -# $Id$ -# -# ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. The Blender -# Foundation also sells licenses for use in proprietary software under -# the Blender License. See http://www.blender.org/BL/ for information -# about this. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software Foundation, -# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -# -# The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. -# All rights reserved. -# -# The Original Code is: all of this file. -# -# Contributor(s): none yet. -# -# ***** END GPL/BL DUAL LICENSE BLOCK ***** -# - -LIBNAME = bullet2 -DIR = $(OCGDIR)/extern/$(LIBNAME) - -BULLETDIRS = \ -LinearMath \ -BulletCollision/BroadphaseCollision \ -BulletCollision/CollisionShapes \ -BulletCollision/NarrowPhaseCollision \ -BulletCollision/CollisionDispatch \ -BulletDynamics/ConstraintSolver \ -BulletDynamics/Vehicle \ -BulletDynamics/Dynamics - -CCSRCS = $(wildcard \ -LinearMath/*.cpp \ -BulletCollision/BroadphaseCollision/*.cpp \ -BulletCollision/CollisionShapes/*.cpp \ -BulletCollision/NarrowPhaseCollision/*.cpp \ -BulletCollision/CollisionDispatch/*.cpp \ -BulletDynamics/ConstraintSolver/*.cpp \ -BulletDynamics/Vehicle/*.cpp \ -BulletDynamics/Dynamics/*.cpp) - -CPPFLAGS += -D_LIB -I. -IBulletCollision -IBulletDynamics -ILinearMath - -all debug:: objdirs - -include nan_compile.mk - -.PHONY: objdirs clean -objdirs: - @for i in $(BULLETDIRS); do \ - [ -d $(DIR)/$(DEBUG_DIR)$$i ] || mkdir -p $(DIR)/$(DEBUG_DIR)$$i; \ - done - -clean:: - rm -rf $(DIR) - rm -rf $(NAN_BULLET2)/lib/libbullet2.a - rm -rf $(NAN_BULLET2)/include diff --git a/extern/bullet2/src/SConscript b/extern/bullet2/src/SConscript deleted file mode 100644 index 19702782b0d..00000000000 --- a/extern/bullet2/src/SConscript +++ /dev/null @@ -1,98 +0,0 @@ -#!/usr/bin/python -import sys -import os - -Import('env') - -defs = 'USE_DOUBLES QHULL _LIB' -cflags = [] - -if env['OURPLATFORM']=='win32-vc': - defs += ' WIN32 NDEBUG _WINDOWS _LIB' - #cflags += ['/MT', '/W3', '/GX', '/O2', '/Op'] - cflags += ['/MT', '/W3', '/GX', '/Og', '/Ot', '/Ob1', '/Op', '/G6'] -elif env['OURPLATFORM']=='win32-mingw': - defs += ' NDEBUG' - cflags += ['-O2'] -elif sys.platform=='linux2' or sys.platform=='linux-i386' or sys.platform=='freebsd4' or sys.platform=='freebsd5': - defs += ' NDEBUG' - cflags += ['-O2'] -elif sys.platform=='darwin': - defs += ' NDEBUG' - cflags += ['-O2','-pipe', '-fPIC', '-funsigned-char', '-ffast-math'] - -linearmath_src = env.Glob("LinearMath/*.cpp") -bulletdyn_src = ["BulletDynamics/ConstraintSolver/btContactConstraint.cpp", - "BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.cpp", - "BulletDynamics/ConstraintSolver/btHingeConstraint.cpp", - "BulletDynamics/ConstraintSolver/btPoint2PointConstraint.cpp", - "BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.cpp", - "BulletDynamics/ConstraintSolver/btSolve2LinearConstraint.cpp", - "BulletDynamics/ConstraintSolver/btTypedConstraint.cpp", - "BulletDynamics/ConstraintSolver/btConeTwistConstraint.cpp", - "BulletDynamics/Dynamics/btDiscreteDynamicsWorld.cpp", - "BulletDynamics/Dynamics/btSimpleDynamicsWorld.cpp", - "BulletDynamics/Dynamics/btRigidBody.cpp", - "BulletDynamics/Vehicle/btRaycastVehicle.cpp", - "BulletDynamics/Dynamics/Bullet-C-API.cpp", - "BulletDynamics/Vehicle/btWheelInfo.cpp"] -collision_src = ["BulletCollision/BroadphaseCollision/btAxisSweep3.cpp", - "BulletCollision/BroadphaseCollision/btBroadphaseProxy.cpp", - "BulletCollision/BroadphaseCollision/btCollisionAlgorithm.cpp", - "BulletCollision/BroadphaseCollision/btDispatcher.cpp", - "BulletCollision/BroadphaseCollision/btOverlappingPairCache.cpp", - "BulletCollision/BroadphaseCollision/btSimpleBroadphase.cpp", - "BulletCollision/CollisionDispatch/btCollisionDispatcher.cpp", - "BulletCollision/CollisionDispatch/btCollisionObject.cpp", - "BulletCollision/CollisionDispatch/btCollisionWorld.cpp", - "BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.cpp", - "BulletCollision/CollisionDispatch/btConvexConcaveCollisionAlgorithm.cpp", - "BulletCollision/CollisionDispatch/btSphereSphereCollisionAlgorithm.cpp", - "BulletCollision/CollisionDispatch/btSphereBoxCollisionAlgorithm.cpp", - "BulletCollision/CollisionDispatch/btConvexConvexAlgorithm.cpp", - "BulletCollision/CollisionDispatch/btEmptyCollisionAlgorithm.cpp", - "BulletCollision/CollisionDispatch/btManifoldResult.cpp", - "BulletCollision/CollisionDispatch/btSimulationIslandManager.cpp", - "BulletCollision/CollisionDispatch/btUnionFind.cpp", - "BulletCollision/CollisionShapes/btBoxShape.cpp", - "BulletCollision/CollisionShapes/btBvhTriangleMeshShape.cpp", - "BulletCollision/CollisionShapes/btCollisionShape.cpp", - "BulletCollision/CollisionShapes/btCompoundShape.cpp", - "BulletCollision/CollisionShapes/btConcaveShape.cpp", - "BulletCollision/CollisionShapes/btConeShape.cpp", - "BulletCollision/CollisionShapes/btConvexHullShape.cpp", - "BulletCollision/CollisionShapes/btConvexShape.cpp", - "BulletCollision/CollisionShapes/btConvexTriangleMeshShape.cpp", - "BulletCollision/CollisionShapes/btCylinderShape.cpp", - "BulletCollision/CollisionShapes/btEmptyShape.cpp", - "BulletCollision/CollisionShapes/btMinkowskiSumShape.cpp", - "BulletCollision/CollisionShapes/btMultiSphereShape.cpp", - "BulletCollision/CollisionShapes/btOptimizedBvh.cpp", - "BulletCollision/CollisionShapes/btPolyhedralConvexShape.cpp", - "BulletCollision/CollisionShapes/btTetrahedronShape.cpp", - "BulletCollision/CollisionShapes/btSphereShape.cpp", - "BulletCollision/CollisionShapes/btStaticPlaneShape.cpp", - "BulletCollision/CollisionShapes/btStridingMeshInterface.cpp", - "BulletCollision/CollisionShapes/btTriangleCallback.cpp", - "BulletCollision/CollisionShapes/btTriangleBuffer.cpp", - "BulletCollision/CollisionShapes/btTriangleIndexVertexArray.cpp", - "BulletCollision/CollisionShapes/btTriangleMesh.cpp", - "BulletCollision/CollisionShapes/btTriangleMeshShape.cpp", - "BulletCollision/CollisionShapes/btHeightfieldTerrainShape.cpp", - "BulletCollision/NarrowPhaseCollision/btContinuousConvexCollision.cpp", - "BulletCollision/NarrowPhaseCollision/btGjkEpa.cpp", - "BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.cpp", - "BulletCollision/NarrowPhaseCollision/btConvexCast.cpp", - "BulletCollision/NarrowPhaseCollision/btGjkConvexCast.cpp", - "BulletCollision/NarrowPhaseCollision/btGjkPairDetector.cpp", - "BulletCollision/NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.cpp", - "BulletCollision/NarrowPhaseCollision/btPersistentManifold.cpp", - "BulletCollision/NarrowPhaseCollision/btRaycastCallback.cpp", - "BulletCollision/NarrowPhaseCollision/btSubSimplexConvexCast.cpp", - "BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.cpp"] - -incs = '. BulletCollision BulletDynamics LinearMath' - -env.BlenderLib ( libname = 'extern_bullet2linmath', sources=linearmath_src, includes=Split(incs), defines=Split(defs), libtype=['game2', 'player'], priority=[20, 170], compileflags=cflags ) -env.BlenderLib ( libname = 'extern_bullet2dynamics', sources=bulletdyn_src, includes=Split(incs), defines=Split(defs), libtype=['game2', 'player'], priority=[19, 169], compileflags=cflags ) -env.BlenderLib ( libname = 'extern_bullet2collision', sources=collision_src, includes=Split(incs), defines=Split(defs), libtype=['game2', 'player'], priority=[20, 170], compileflags=cflags ) diff --git a/extern/bullet2/src/btBulletCollisionCommon.h b/extern/bullet2/src/btBulletCollisionCommon.h deleted file mode 100644 index a309f7d76d2..00000000000 --- a/extern/bullet2/src/btBulletCollisionCommon.h +++ /dev/null @@ -1,63 +0,0 @@ -/* -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 BULLET_COLLISION_COMMON_H -#define BULLET_COLLISION_COMMON_H - -///Common headerfile includes for Bullet Collision Detection - -///Bullet's btCollisionWorld and btCollisionObject definitions -#include "BulletCollision/CollisionDispatch/btCollisionWorld.h" -#include "BulletCollision/CollisionDispatch/btCollisionObject.h" - -///Collision Shapes -#include "BulletCollision/CollisionShapes/btBoxShape.h" -#include "BulletCollision/CollisionShapes/btSphereShape.h" -#include "BulletCollision/CollisionShapes/btCapsuleShape.h" -#include "BulletCollision/CollisionShapes/btCylinderShape.h" -#include "BulletCollision/CollisionShapes/btConeShape.h" -#include "BulletCollision/CollisionShapes/btStaticPlaneShape.h" -#include "BulletCollision/CollisionShapes/btConvexHullShape.h" -#include "BulletCollision/CollisionShapes/btTriangleMesh.h" -#include "BulletCollision/CollisionShapes/btConvexTriangleMeshShape.h" -#include "BulletCollision/CollisionShapes/btBvhTriangleMeshShape.h" -#include "BulletCollision/CollisionShapes/btTriangleMeshShape.h" -#include "BulletCollision/CollisionShapes/btTriangleIndexVertexArray.h" -#include "BulletCollision/CollisionShapes/btCompoundShape.h" -#include "BulletCollision/CollisionShapes/btTetrahedronShape.h" -#include "BulletCollision/CollisionShapes/btEmptyShape.h" -#include "BulletCollision/CollisionShapes/btMultiSphereShape.h" -#include "BulletCollision/CollisionShapes/btUniformScalingShape.h" - -///Narrowphase Collision Detector -#include "BulletCollision/CollisionDispatch/btSphereSphereCollisionAlgorithm.h" -#include "BulletCollision/CollisionDispatch/btSphereBoxCollisionAlgorithm.h" -#include "BulletCollision/CollisionDispatch/btDefaultCollisionConfiguration.h" - -///Dispatching and generation of collision pairs (broadphase) -#include "BulletCollision/CollisionDispatch/btCollisionDispatcher.h" -#include "BulletCollision/BroadphaseCollision/btSimpleBroadphase.h" -#include "BulletCollision/BroadphaseCollision/btAxisSweep3.h" - - -///Math library & Utils -#include "LinearMath/btQuaternion.h" -#include "LinearMath/btTransform.h" -#include "LinearMath/btDefaultMotionState.h" -#include "LinearMath/btQuickprof.h" -#include "LinearMath/btIDebugDraw.h" - -#endif //BULLET_COLLISION_COMMON_H - diff --git a/extern/bullet2/src/btBulletDynamicsCommon.h b/extern/bullet2/src/btBulletDynamicsCommon.h deleted file mode 100644 index 5d08dac0c0d..00000000000 --- a/extern/bullet2/src/btBulletDynamicsCommon.h +++ /dev/null @@ -1,44 +0,0 @@ -/* -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 BULLET_DYNAMICS_COMMON_H -#define BULLET_DYNAMICS_COMMON_H - -///Common headerfile includes for Bullet Dynamics, including Collision Detection -#include "btBulletCollisionCommon.h" - -#include "BulletDynamics/Dynamics/btDiscreteDynamicsWorld.h" -#include "BulletDynamics/Dynamics/btContinuousDynamicsWorld.h" - -#include "BulletDynamics/Dynamics/btSimpleDynamicsWorld.h" -#include "BulletDynamics/Dynamics/btRigidBody.h" - -#include "BulletDynamics/ConstraintSolver/btPoint2PointConstraint.h" -#include "BulletDynamics/ConstraintSolver/btHingeConstraint.h" -#include "BulletDynamics/ConstraintSolver/btConeTwistConstraint.h" -#include "BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.h" - - -#include "BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.h" -///Vehicle simulation, with wheel contact simulated by raycasts -#include "BulletDynamics/Vehicle/btRaycastVehicle.h" - - - - - - -#endif //BULLET_DYNAMICS_COMMON_H - diff --git a/extern/bullet2/src/ibmsdk/Makefile b/extern/bullet2/src/ibmsdk/Makefile deleted file mode 100644 index 768fffd35a4..00000000000 --- a/extern/bullet2/src/ibmsdk/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -#### Visit Bullet library ibmsdk dirs and build code -CELL_TOP ?= /opt/ibm/cell-sdk/prototype - -DIRS := \ -../BulletCollision/ibmsdk \ -../BulletDynamics/ibmsdk \ -../LinearMath/ibmsdk - - -include $(CELL_TOP)/make.footer diff --git a/source/blender/include/BIF_imasel.h b/source/blender/include/BIF_imasel.h index a3a3b7531d6..cbd547602e1 100644 --- a/source/blender/include/BIF_imasel.h +++ b/source/blender/include/BIF_imasel.h @@ -34,6 +34,7 @@ struct ScrArea; struct ID; void free_imasel(struct SpaceImaSel *simasel); +void reset_imaselspace(struct ScrArea *sa); void clever_numbuts_imasel(void); diff --git a/source/blender/include/BSE_drawview.h b/source/blender/include/BSE_drawview.h index 09ce87015d9..be1f5581be7 100644 --- a/source/blender/include/BSE_drawview.h +++ b/source/blender/include/BSE_drawview.h @@ -46,7 +46,7 @@ void do_viewbuts(unsigned short event); /* View3DAfter->type */ #define V3D_XRAY 1 #define V3D_TRANSP 2 -void add_view3d_after(struct View3D *v3d, struct Base *base, int type); +void add_view3d_after(struct View3D *v3d, struct Base *base, int type, int flag); void backdrawview3d(int test); void check_backbuf(void); diff --git a/source/blender/include/BSE_filesel.h b/source/blender/include/BSE_filesel.h index 13e38d50c47..b46b2328ea4 100644 --- a/source/blender/include/BSE_filesel.h +++ b/source/blender/include/BSE_filesel.h @@ -54,6 +54,7 @@ void activate_databrowse(struct ID *id, int idcode, int fromcode, int retval, sh void activate_databrowse_args(struct ID *id, int idcode, int fromcode, short *menup, void (*func)(char *, void *, void *), void *arg1, void *arg2); void filesel_prevspace(void); +void reset_filespace(struct ScrArea *sa); void free_filesel_spec(char *dir); void winqreadfilespace(struct ScrArea *sa, void *spacedata, struct BWinEvent *evt); void main_to_filelist(struct SpaceFile *sfile); diff --git a/source/blender/makesdna/DNA_userdef_types.h b/source/blender/makesdna/DNA_userdef_types.h index c45571cb583..acc1651e9fa 100644 --- a/source/blender/makesdna/DNA_userdef_types.h +++ b/source/blender/makesdna/DNA_userdef_types.h @@ -224,7 +224,7 @@ extern UserDef U; /* from usiblender.c !!!! */ #define USER_DUPLILINK (1 << 6) #define USER_FSCOLLUM (1 << 7) #define USER_MAT_ON_OB (1 << 8) -#define USER_NO_CAPSLOCK (1 << 9) +/*#define USER_NO_CAPSLOCK (1 << 9)*/ /* not used anywhere */ #define USER_VIEWMOVE (1 << 10) #define USER_TOOLTIPS (1 << 11) #define USER_TWOBUTTONMOUSE (1 << 12) @@ -236,7 +236,8 @@ extern UserDef U; /* from usiblender.c !!!! */ #define USER_ADD_EDITMODE (1 << 18) #define USER_ADD_VIEWALIGNED (1 << 19) #define USER_RELPATHS (1 << 20) -#define USER_DRAGIMMEDIATE (1 << 21) +#define USER_DRAGIMMEDIATE (1 << 21) +#define USER_DONT_DOSCRIPTLINKS (1 << 22) /* viewzom */ #define USER_ZOOM_CONT 0 From 96408da81a8c8cd5cb737ed4236fc1386ce70c6e Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Wed, 7 May 2008 20:22:28 +0000 Subject: [PATCH 087/246] Added bullet back to branch, compiling works again --- extern/bullet2/CMakeLists.txt | 43 + extern/bullet2/Makefile | 61 + .../bullet2/make/msvc_7_0/Bullet_vc7.vcproj | 927 +++++++++++++ extern/bullet2/readme.txt | 12 + extern/bullet2/src/Bullet-C-Api.h | 37 + .../BroadphaseCollision/btAxisSweep3.cpp | 660 ++++++++++ .../BroadphaseCollision/btAxisSweep3.h | 138 ++ .../btBroadphaseInterface.h | 40 + .../BroadphaseCollision/btBroadphaseProxy.cpp | 17 + .../BroadphaseCollision/btBroadphaseProxy.h | 204 +++ .../btCollisionAlgorithm.cpp | 23 + .../btCollisionAlgorithm.h | 77 ++ .../BroadphaseCollision/btDispatcher.cpp | 22 + .../BroadphaseCollision/btDispatcher.h | 93 ++ .../btOverlappingPairCache.cpp | 196 +++ .../btOverlappingPairCache.h | 120 ++ .../btSimpleBroadphase.cpp | 222 ++++ .../BroadphaseCollision/btSimpleBroadphase.h | 95 ++ .../src/BulletCollision/CMakeLists.txt | 60 + .../SphereTriangleDetector.cpp | 200 +++ .../SphereTriangleDetector.h | 49 + .../CollisionDispatch/btCollisionCreateFunc.h | 46 + .../btCollisionDispatcher.cpp | 367 ++++++ .../CollisionDispatch/btCollisionDispatcher.h | 135 ++ .../CollisionDispatch/btCollisionObject.cpp | 57 + .../CollisionDispatch/btCollisionObject.h | 346 +++++ .../CollisionDispatch/btCollisionWorld.cpp | 362 ++++++ .../CollisionDispatch/btCollisionWorld.h | 255 ++++ .../btCompoundCollisionAlgorithm.cpp | 140 ++ .../btCompoundCollisionAlgorithm.h | 64 + .../btConvexConcaveCollisionAlgorithm.cpp | 312 +++++ .../btConvexConcaveCollisionAlgorithm.h | 111 ++ .../btConvexConvexAlgorithm.cpp | 254 ++++ .../btConvexConvexAlgorithm.h | 76 ++ .../btEmptyCollisionAlgorithm.cpp | 34 + .../btEmptyCollisionAlgorithm.h | 48 + .../CollisionDispatch/btManifoldResult.cpp | 109 ++ .../CollisionDispatch/btManifoldResult.h | 77 ++ .../btSimulationIslandManager.cpp | 357 +++++ .../btSimulationIslandManager.h | 61 + .../btSphereBoxCollisionAlgorithm.cpp | 249 ++++ .../btSphereBoxCollisionAlgorithm.h | 64 + .../btSphereSphereCollisionAlgorithm.cpp | 85 ++ .../btSphereSphereCollisionAlgorithm.h | 56 + .../btSphereTriangleCollisionAlgorithm.cpp | 76 ++ .../btSphereTriangleCollisionAlgorithm.h | 59 + .../CollisionDispatch/btUnionFind.cpp | 83 ++ .../CollisionDispatch/btUnionFind.h | 124 ++ .../CollisionShapes/btBoxShape.cpp | 57 + .../CollisionShapes/btBoxShape.h | 293 +++++ .../btBvhTriangleMeshShape.cpp | 173 +++ .../CollisionShapes/btBvhTriangleMeshShape.h | 75 ++ .../CollisionShapes/btCapsuleShape.cpp | 146 +++ .../CollisionShapes/btCapsuleShape.h | 60 + .../CollisionShapes/btCollisionMargin.h | 26 + .../CollisionShapes/btCollisionShape.cpp | 85 ++ .../CollisionShapes/btCollisionShape.h | 94 ++ .../CollisionShapes/btCompoundShape.cpp | 100 ++ .../CollisionShapes/btCompoundShape.h | 117 ++ .../CollisionShapes/btConcaveShape.cpp | 28 + .../CollisionShapes/btConcaveShape.h | 50 + .../CollisionShapes/btConeShape.cpp | 133 ++ .../CollisionShapes/btConeShape.h | 103 ++ .../CollisionShapes/btConvexHullShape.cpp | 179 +++ .../CollisionShapes/btConvexHullShape.h | 76 ++ .../CollisionShapes/btConvexShape.cpp | 77 ++ .../CollisionShapes/btConvexShape.h | 127 ++ .../btConvexTriangleMeshShape.cpp | 205 +++ .../btConvexTriangleMeshShape.h | 51 + .../CollisionShapes/btCylinderShape.cpp | 206 +++ .../CollisionShapes/btCylinderShape.h | 138 ++ .../CollisionShapes/btEmptyShape.cpp | 49 + .../CollisionShapes/btEmptyShape.h | 70 + .../btHeightfieldTerrainShape.cpp | 339 +++++ .../btHeightfieldTerrainShape.h | 88 ++ .../CollisionShapes/btMinkowskiSumShape.cpp | 57 + .../CollisionShapes/btMinkowskiSumShape.h | 62 + .../CollisionShapes/btMultiSphereShape.cpp | 148 +++ .../CollisionShapes/btMultiSphereShape.h | 74 ++ .../CollisionShapes/btOptimizedBvh.cpp | 845 ++++++++++++ .../CollisionShapes/btOptimizedBvh.h | 330 +++++ .../btPolyhedralConvexShape.cpp | 148 +++ .../CollisionShapes/btPolyhedralConvexShape.h | 93 ++ .../CollisionShapes/btSphereShape.cpp | 77 ++ .../CollisionShapes/btSphereShape.h | 63 + .../CollisionShapes/btStaticPlaneShape.cpp | 105 ++ .../CollisionShapes/btStaticPlaneShape.h | 61 + .../btStridingMeshInterface.cpp | 124 ++ .../CollisionShapes/btStridingMeshInterface.h | 89 ++ .../CollisionShapes/btTetrahedronShape.cpp | 195 +++ .../CollisionShapes/btTetrahedronShape.h | 75 ++ .../CollisionShapes/btTriangleBuffer.cpp | 42 + .../CollisionShapes/btTriangleBuffer.h | 61 + .../CollisionShapes/btTriangleCallback.cpp | 28 + .../CollisionShapes/btTriangleCallback.h | 40 + .../btTriangleIndexVertexArray.cpp | 65 + .../btTriangleIndexVertexArray.h | 97 ++ .../CollisionShapes/btTriangleMesh.cpp | 60 + .../CollisionShapes/btTriangleMesh.h | 75 ++ .../CollisionShapes/btTriangleMeshShape.cpp | 203 +++ .../CollisionShapes/btTriangleMeshShape.h | 78 ++ .../CollisionShapes/btTriangleShape.h | 179 +++ extern/bullet2/src/BulletCollision/Doxyfile | 746 +++++++++++ .../btContinuousConvexCollision.cpp | 200 +++ .../btContinuousConvexCollision.h | 52 + .../NarrowPhaseCollision/btConvexCast.cpp | 20 + .../NarrowPhaseCollision/btConvexCast.h | 71 + .../btConvexPenetrationDepthSolver.h | 43 + .../btDiscreteCollisionDetectorInterface.h | 88 ++ .../NarrowPhaseCollision/btGjkConvexCast.cpp | 174 +++ .../NarrowPhaseCollision/btGjkConvexCast.h | 50 + .../NarrowPhaseCollision/btGjkEpa.cpp | 628 +++++++++ .../NarrowPhaseCollision/btGjkEpa.h | 53 + .../btGjkEpaPenetrationDepthSolver.cpp | 50 + .../btGjkEpaPenetrationDepthSolver.h | 39 + .../btGjkPairDetector.cpp | 299 +++++ .../NarrowPhaseCollision/btGjkPairDetector.h | 85 ++ .../NarrowPhaseCollision/btManifoldPoint.h | 99 ++ .../btMinkowskiPenetrationDepthSolver.cpp | 334 +++++ .../btMinkowskiPenetrationDepthSolver.h | 37 + .../btPersistentManifold.cpp | 246 ++++ .../btPersistentManifold.h | 161 +++ .../NarrowPhaseCollision/btPointCollector.h | 61 + .../btRaycastCallback.cpp | 101 ++ .../NarrowPhaseCollision/btRaycastCallback.h | 42 + .../btSimplexSolverInterface.h | 64 + .../btSubSimplexConvexCast.cpp | 139 ++ .../btSubSimplexConvexCast.h | 50 + .../btVoronoiSimplexSolver.cpp | 607 +++++++++ .../btVoronoiSimplexSolver.h | 157 +++ .../bullet2/src/BulletDynamics/CMakeLists.txt | 20 + .../btConeTwistConstraint.cpp | 285 ++++ .../ConstraintSolver/btConeTwistConstraint.h | 123 ++ .../ConstraintSolver/btConstraintSolver.h | 45 + .../ConstraintSolver/btContactConstraint.cpp | 417 ++++++ .../ConstraintSolver/btContactConstraint.h | 122 ++ .../ConstraintSolver/btContactSolverInfo.h | 47 + .../btGeneric6DofConstraint.cpp | 389 ++++++ .../btGeneric6DofConstraint.h | 120 ++ .../ConstraintSolver/btHingeConstraint.cpp | 229 ++++ .../ConstraintSolver/btHingeConstraint.h | 81 ++ .../ConstraintSolver/btJacobianEntry.h | 156 +++ .../btPoint2PointConstraint.cpp | 116 ++ .../btPoint2PointConstraint.h | 77 ++ .../btSequentialImpulseConstraintSolver.cpp | 1158 +++++++++++++++++ .../btSequentialImpulseConstraintSolver.h | 109 ++ .../btSolve2LinearConstraint.cpp | 255 ++++ .../btSolve2LinearConstraint.h | 107 ++ .../ConstraintSolver/btSolverBody.h | 71 + .../ConstraintSolver/btSolverConstraint.h | 63 + .../ConstraintSolver/btTypedConstraint.cpp | 53 + .../ConstraintSolver/btTypedConstraint.h | 96 ++ .../BulletDynamics/Dynamics/Bullet-C-API.cpp | 120 ++ .../Dynamics/btDiscreteDynamicsWorld.cpp | 954 ++++++++++++++ .../Dynamics/btDiscreteDynamicsWorld.h | 157 +++ .../BulletDynamics/Dynamics/btDynamicsWorld.h | 78 ++ .../BulletDynamics/Dynamics/btRigidBody.cpp | 345 +++++ .../src/BulletDynamics/Dynamics/btRigidBody.h | 357 +++++ .../Dynamics/btSimpleDynamicsWorld.cpp | 211 +++ .../Dynamics/btSimpleDynamicsWorld.h | 82 ++ .../Vehicle/btRaycastVehicle.cpp | 733 +++++++++++ .../BulletDynamics/Vehicle/btRaycastVehicle.h | 201 +++ .../Vehicle/btVehicleRaycaster.h | 35 + .../BulletDynamics/Vehicle/btWheelInfo.cpp | 56 + .../src/BulletDynamics/Vehicle/btWheelInfo.h | 116 ++ extern/bullet2/src/CMakeLists.txt | 1 + extern/bullet2/src/LinearMath/CMakeLists.txt | 10 + extern/bullet2/src/LinearMath/btAabbUtil2.h | 127 ++ .../src/LinearMath/btAlignedAllocator.cpp | 70 + .../src/LinearMath/btAlignedAllocator.h | 80 ++ .../src/LinearMath/btAlignedObjectArray.h | 367 ++++++ .../src/LinearMath/btDefaultMotionState.h | 38 + .../bullet2/src/LinearMath/btGeometryUtil.cpp | 178 +++ .../bullet2/src/LinearMath/btGeometryUtil.h | 41 + extern/bullet2/src/LinearMath/btIDebugDraw.h | 100 ++ extern/bullet2/src/LinearMath/btList.h | 73 ++ extern/bullet2/src/LinearMath/btMatrix3x3.h | 410 ++++++ extern/bullet2/src/LinearMath/btMinMax.h | 69 + extern/bullet2/src/LinearMath/btMotionState.h | 40 + extern/bullet2/src/LinearMath/btPoint3.h | 24 + extern/bullet2/src/LinearMath/btQuadWord.h | 139 ++ extern/bullet2/src/LinearMath/btQuaternion.h | 321 +++++ extern/bullet2/src/LinearMath/btQuickprof.cpp | 38 + extern/bullet2/src/LinearMath/btQuickprof.h | 712 ++++++++++ extern/bullet2/src/LinearMath/btRandom.h | 42 + extern/bullet2/src/LinearMath/btScalar.h | 181 +++ extern/bullet2/src/LinearMath/btSimdMinMax.h | 41 + extern/bullet2/src/LinearMath/btStackAlloc.h | 106 ++ extern/bullet2/src/LinearMath/btTransform.h | 206 +++ .../bullet2/src/LinearMath/btTransformUtil.h | 138 ++ extern/bullet2/src/LinearMath/btVector3.h | 402 ++++++ extern/bullet2/src/Makefile | 68 + extern/bullet2/src/SConscript | 98 ++ extern/bullet2/src/btBulletCollisionCommon.h | 61 + extern/bullet2/src/btBulletDynamicsCommon.h | 42 + 195 files changed, 30425 insertions(+) create mode 100644 extern/bullet2/CMakeLists.txt create mode 100644 extern/bullet2/Makefile create mode 100644 extern/bullet2/make/msvc_7_0/Bullet_vc7.vcproj create mode 100644 extern/bullet2/readme.txt create mode 100644 extern/bullet2/src/Bullet-C-Api.h create mode 100644 extern/bullet2/src/BulletCollision/BroadphaseCollision/btAxisSweep3.cpp create mode 100644 extern/bullet2/src/BulletCollision/BroadphaseCollision/btAxisSweep3.h create mode 100644 extern/bullet2/src/BulletCollision/BroadphaseCollision/btBroadphaseInterface.h create mode 100644 extern/bullet2/src/BulletCollision/BroadphaseCollision/btBroadphaseProxy.cpp create mode 100644 extern/bullet2/src/BulletCollision/BroadphaseCollision/btBroadphaseProxy.h create mode 100644 extern/bullet2/src/BulletCollision/BroadphaseCollision/btCollisionAlgorithm.cpp create mode 100644 extern/bullet2/src/BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h create mode 100644 extern/bullet2/src/BulletCollision/BroadphaseCollision/btDispatcher.cpp create mode 100644 extern/bullet2/src/BulletCollision/BroadphaseCollision/btDispatcher.h create mode 100644 extern/bullet2/src/BulletCollision/BroadphaseCollision/btOverlappingPairCache.cpp create mode 100644 extern/bullet2/src/BulletCollision/BroadphaseCollision/btOverlappingPairCache.h create mode 100644 extern/bullet2/src/BulletCollision/BroadphaseCollision/btSimpleBroadphase.cpp create mode 100644 extern/bullet2/src/BulletCollision/BroadphaseCollision/btSimpleBroadphase.h create mode 100644 extern/bullet2/src/BulletCollision/CMakeLists.txt create mode 100644 extern/bullet2/src/BulletCollision/CollisionDispatch/SphereTriangleDetector.cpp create mode 100644 extern/bullet2/src/BulletCollision/CollisionDispatch/SphereTriangleDetector.h create mode 100644 extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionCreateFunc.h create mode 100644 extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionDispatcher.cpp create mode 100644 extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionDispatcher.h create mode 100644 extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionObject.cpp create mode 100644 extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionObject.h create mode 100644 extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionWorld.cpp create mode 100644 extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionWorld.h create mode 100644 extern/bullet2/src/BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.cpp create mode 100644 extern/bullet2/src/BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.h create mode 100644 extern/bullet2/src/BulletCollision/CollisionDispatch/btConvexConcaveCollisionAlgorithm.cpp create mode 100644 extern/bullet2/src/BulletCollision/CollisionDispatch/btConvexConcaveCollisionAlgorithm.h create mode 100644 extern/bullet2/src/BulletCollision/CollisionDispatch/btConvexConvexAlgorithm.cpp create mode 100644 extern/bullet2/src/BulletCollision/CollisionDispatch/btConvexConvexAlgorithm.h create mode 100644 extern/bullet2/src/BulletCollision/CollisionDispatch/btEmptyCollisionAlgorithm.cpp create mode 100644 extern/bullet2/src/BulletCollision/CollisionDispatch/btEmptyCollisionAlgorithm.h create mode 100644 extern/bullet2/src/BulletCollision/CollisionDispatch/btManifoldResult.cpp create mode 100644 extern/bullet2/src/BulletCollision/CollisionDispatch/btManifoldResult.h create mode 100644 extern/bullet2/src/BulletCollision/CollisionDispatch/btSimulationIslandManager.cpp create mode 100644 extern/bullet2/src/BulletCollision/CollisionDispatch/btSimulationIslandManager.h create mode 100644 extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereBoxCollisionAlgorithm.cpp create mode 100644 extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereBoxCollisionAlgorithm.h create mode 100644 extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereSphereCollisionAlgorithm.cpp create mode 100644 extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereSphereCollisionAlgorithm.h create mode 100644 extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereTriangleCollisionAlgorithm.cpp create mode 100644 extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereTriangleCollisionAlgorithm.h create mode 100644 extern/bullet2/src/BulletCollision/CollisionDispatch/btUnionFind.cpp create mode 100644 extern/bullet2/src/BulletCollision/CollisionDispatch/btUnionFind.h create mode 100644 extern/bullet2/src/BulletCollision/CollisionShapes/btBoxShape.cpp create mode 100644 extern/bullet2/src/BulletCollision/CollisionShapes/btBoxShape.h create mode 100644 extern/bullet2/src/BulletCollision/CollisionShapes/btBvhTriangleMeshShape.cpp create mode 100644 extern/bullet2/src/BulletCollision/CollisionShapes/btBvhTriangleMeshShape.h create mode 100644 extern/bullet2/src/BulletCollision/CollisionShapes/btCapsuleShape.cpp create mode 100644 extern/bullet2/src/BulletCollision/CollisionShapes/btCapsuleShape.h create mode 100644 extern/bullet2/src/BulletCollision/CollisionShapes/btCollisionMargin.h create mode 100644 extern/bullet2/src/BulletCollision/CollisionShapes/btCollisionShape.cpp create mode 100644 extern/bullet2/src/BulletCollision/CollisionShapes/btCollisionShape.h create mode 100644 extern/bullet2/src/BulletCollision/CollisionShapes/btCompoundShape.cpp create mode 100644 extern/bullet2/src/BulletCollision/CollisionShapes/btCompoundShape.h create mode 100644 extern/bullet2/src/BulletCollision/CollisionShapes/btConcaveShape.cpp create mode 100644 extern/bullet2/src/BulletCollision/CollisionShapes/btConcaveShape.h create mode 100644 extern/bullet2/src/BulletCollision/CollisionShapes/btConeShape.cpp create mode 100644 extern/bullet2/src/BulletCollision/CollisionShapes/btConeShape.h create mode 100644 extern/bullet2/src/BulletCollision/CollisionShapes/btConvexHullShape.cpp create mode 100644 extern/bullet2/src/BulletCollision/CollisionShapes/btConvexHullShape.h create mode 100644 extern/bullet2/src/BulletCollision/CollisionShapes/btConvexShape.cpp create mode 100644 extern/bullet2/src/BulletCollision/CollisionShapes/btConvexShape.h create mode 100644 extern/bullet2/src/BulletCollision/CollisionShapes/btConvexTriangleMeshShape.cpp create mode 100644 extern/bullet2/src/BulletCollision/CollisionShapes/btConvexTriangleMeshShape.h create mode 100644 extern/bullet2/src/BulletCollision/CollisionShapes/btCylinderShape.cpp create mode 100644 extern/bullet2/src/BulletCollision/CollisionShapes/btCylinderShape.h create mode 100644 extern/bullet2/src/BulletCollision/CollisionShapes/btEmptyShape.cpp create mode 100644 extern/bullet2/src/BulletCollision/CollisionShapes/btEmptyShape.h create mode 100644 extern/bullet2/src/BulletCollision/CollisionShapes/btHeightfieldTerrainShape.cpp create mode 100644 extern/bullet2/src/BulletCollision/CollisionShapes/btHeightfieldTerrainShape.h create mode 100644 extern/bullet2/src/BulletCollision/CollisionShapes/btMinkowskiSumShape.cpp create mode 100644 extern/bullet2/src/BulletCollision/CollisionShapes/btMinkowskiSumShape.h create mode 100644 extern/bullet2/src/BulletCollision/CollisionShapes/btMultiSphereShape.cpp create mode 100644 extern/bullet2/src/BulletCollision/CollisionShapes/btMultiSphereShape.h create mode 100644 extern/bullet2/src/BulletCollision/CollisionShapes/btOptimizedBvh.cpp create mode 100644 extern/bullet2/src/BulletCollision/CollisionShapes/btOptimizedBvh.h create mode 100644 extern/bullet2/src/BulletCollision/CollisionShapes/btPolyhedralConvexShape.cpp create mode 100644 extern/bullet2/src/BulletCollision/CollisionShapes/btPolyhedralConvexShape.h create mode 100644 extern/bullet2/src/BulletCollision/CollisionShapes/btSphereShape.cpp create mode 100644 extern/bullet2/src/BulletCollision/CollisionShapes/btSphereShape.h create mode 100644 extern/bullet2/src/BulletCollision/CollisionShapes/btStaticPlaneShape.cpp create mode 100644 extern/bullet2/src/BulletCollision/CollisionShapes/btStaticPlaneShape.h create mode 100644 extern/bullet2/src/BulletCollision/CollisionShapes/btStridingMeshInterface.cpp create mode 100644 extern/bullet2/src/BulletCollision/CollisionShapes/btStridingMeshInterface.h create mode 100644 extern/bullet2/src/BulletCollision/CollisionShapes/btTetrahedronShape.cpp create mode 100644 extern/bullet2/src/BulletCollision/CollisionShapes/btTetrahedronShape.h create mode 100644 extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleBuffer.cpp create mode 100644 extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleBuffer.h create mode 100644 extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleCallback.cpp create mode 100644 extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleCallback.h create mode 100644 extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleIndexVertexArray.cpp create mode 100644 extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleIndexVertexArray.h create mode 100644 extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleMesh.cpp create mode 100644 extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleMesh.h create mode 100644 extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleMeshShape.cpp create mode 100644 extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleMeshShape.h create mode 100644 extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleShape.h create mode 100644 extern/bullet2/src/BulletCollision/Doxyfile create mode 100644 extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btContinuousConvexCollision.cpp create mode 100644 extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btContinuousConvexCollision.h create mode 100644 extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btConvexCast.cpp create mode 100644 extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btConvexCast.h create mode 100644 extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btConvexPenetrationDepthSolver.h create mode 100644 extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btDiscreteCollisionDetectorInterface.h create mode 100644 extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkConvexCast.cpp create mode 100644 extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkConvexCast.h create mode 100644 extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkEpa.cpp create mode 100644 extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkEpa.h create mode 100644 extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.cpp create mode 100644 extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.h create mode 100644 extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkPairDetector.cpp create mode 100644 extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkPairDetector.h create mode 100644 extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btManifoldPoint.h create mode 100644 extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.cpp create mode 100644 extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.h create mode 100644 extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btPersistentManifold.cpp create mode 100644 extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btPersistentManifold.h create mode 100644 extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btPointCollector.h create mode 100644 extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btRaycastCallback.cpp create mode 100644 extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btRaycastCallback.h create mode 100644 extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btSimplexSolverInterface.h create mode 100644 extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btSubSimplexConvexCast.cpp create mode 100644 extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btSubSimplexConvexCast.h create mode 100644 extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.cpp create mode 100644 extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.h create mode 100644 extern/bullet2/src/BulletDynamics/CMakeLists.txt create mode 100644 extern/bullet2/src/BulletDynamics/ConstraintSolver/btConeTwistConstraint.cpp create mode 100644 extern/bullet2/src/BulletDynamics/ConstraintSolver/btConeTwistConstraint.h create mode 100644 extern/bullet2/src/BulletDynamics/ConstraintSolver/btConstraintSolver.h create mode 100644 extern/bullet2/src/BulletDynamics/ConstraintSolver/btContactConstraint.cpp create mode 100644 extern/bullet2/src/BulletDynamics/ConstraintSolver/btContactConstraint.h create mode 100644 extern/bullet2/src/BulletDynamics/ConstraintSolver/btContactSolverInfo.h create mode 100644 extern/bullet2/src/BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.cpp create mode 100644 extern/bullet2/src/BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.h create mode 100644 extern/bullet2/src/BulletDynamics/ConstraintSolver/btHingeConstraint.cpp create mode 100644 extern/bullet2/src/BulletDynamics/ConstraintSolver/btHingeConstraint.h create mode 100644 extern/bullet2/src/BulletDynamics/ConstraintSolver/btJacobianEntry.h create mode 100644 extern/bullet2/src/BulletDynamics/ConstraintSolver/btPoint2PointConstraint.cpp create mode 100644 extern/bullet2/src/BulletDynamics/ConstraintSolver/btPoint2PointConstraint.h create mode 100644 extern/bullet2/src/BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.cpp create mode 100644 extern/bullet2/src/BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.h create mode 100644 extern/bullet2/src/BulletDynamics/ConstraintSolver/btSolve2LinearConstraint.cpp create mode 100644 extern/bullet2/src/BulletDynamics/ConstraintSolver/btSolve2LinearConstraint.h create mode 100644 extern/bullet2/src/BulletDynamics/ConstraintSolver/btSolverBody.h create mode 100644 extern/bullet2/src/BulletDynamics/ConstraintSolver/btSolverConstraint.h create mode 100644 extern/bullet2/src/BulletDynamics/ConstraintSolver/btTypedConstraint.cpp create mode 100644 extern/bullet2/src/BulletDynamics/ConstraintSolver/btTypedConstraint.h create mode 100644 extern/bullet2/src/BulletDynamics/Dynamics/Bullet-C-API.cpp create mode 100644 extern/bullet2/src/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.cpp create mode 100644 extern/bullet2/src/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.h create mode 100644 extern/bullet2/src/BulletDynamics/Dynamics/btDynamicsWorld.h create mode 100644 extern/bullet2/src/BulletDynamics/Dynamics/btRigidBody.cpp create mode 100644 extern/bullet2/src/BulletDynamics/Dynamics/btRigidBody.h create mode 100644 extern/bullet2/src/BulletDynamics/Dynamics/btSimpleDynamicsWorld.cpp create mode 100644 extern/bullet2/src/BulletDynamics/Dynamics/btSimpleDynamicsWorld.h create mode 100644 extern/bullet2/src/BulletDynamics/Vehicle/btRaycastVehicle.cpp create mode 100644 extern/bullet2/src/BulletDynamics/Vehicle/btRaycastVehicle.h create mode 100644 extern/bullet2/src/BulletDynamics/Vehicle/btVehicleRaycaster.h create mode 100644 extern/bullet2/src/BulletDynamics/Vehicle/btWheelInfo.cpp create mode 100644 extern/bullet2/src/BulletDynamics/Vehicle/btWheelInfo.h create mode 100644 extern/bullet2/src/CMakeLists.txt create mode 100644 extern/bullet2/src/LinearMath/CMakeLists.txt create mode 100644 extern/bullet2/src/LinearMath/btAabbUtil2.h create mode 100644 extern/bullet2/src/LinearMath/btAlignedAllocator.cpp create mode 100644 extern/bullet2/src/LinearMath/btAlignedAllocator.h create mode 100644 extern/bullet2/src/LinearMath/btAlignedObjectArray.h create mode 100644 extern/bullet2/src/LinearMath/btDefaultMotionState.h create mode 100644 extern/bullet2/src/LinearMath/btGeometryUtil.cpp create mode 100644 extern/bullet2/src/LinearMath/btGeometryUtil.h create mode 100644 extern/bullet2/src/LinearMath/btIDebugDraw.h create mode 100644 extern/bullet2/src/LinearMath/btList.h create mode 100644 extern/bullet2/src/LinearMath/btMatrix3x3.h create mode 100644 extern/bullet2/src/LinearMath/btMinMax.h create mode 100644 extern/bullet2/src/LinearMath/btMotionState.h create mode 100644 extern/bullet2/src/LinearMath/btPoint3.h create mode 100644 extern/bullet2/src/LinearMath/btQuadWord.h create mode 100644 extern/bullet2/src/LinearMath/btQuaternion.h create mode 100644 extern/bullet2/src/LinearMath/btQuickprof.cpp create mode 100644 extern/bullet2/src/LinearMath/btQuickprof.h create mode 100644 extern/bullet2/src/LinearMath/btRandom.h create mode 100644 extern/bullet2/src/LinearMath/btScalar.h create mode 100644 extern/bullet2/src/LinearMath/btSimdMinMax.h create mode 100644 extern/bullet2/src/LinearMath/btStackAlloc.h create mode 100644 extern/bullet2/src/LinearMath/btTransform.h create mode 100644 extern/bullet2/src/LinearMath/btTransformUtil.h create mode 100644 extern/bullet2/src/LinearMath/btVector3.h create mode 100644 extern/bullet2/src/Makefile create mode 100644 extern/bullet2/src/SConscript create mode 100644 extern/bullet2/src/btBulletCollisionCommon.h create mode 100644 extern/bullet2/src/btBulletDynamicsCommon.h diff --git a/extern/bullet2/CMakeLists.txt b/extern/bullet2/CMakeLists.txt new file mode 100644 index 00000000000..b5ae20253cc --- /dev/null +++ b/extern/bullet2/CMakeLists.txt @@ -0,0 +1,43 @@ +# $Id: CMakeLists.txt 14444 2008-04-16 22:40:48Z hos $ +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# The Original Code is Copyright (C) 2006, Blender Foundation +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): Jacques Beaurai, Erwin Coumans +# +# ***** END GPL LICENSE BLOCK ***** + +SET(INC . src) + +FILE(GLOB SRC + src/LinearMath/*.cpp + src/BulletCollision/BroadphaseCollision/*.cpp + src/BulletCollision/CollisionShapes/*.cpp + src/BulletCollision/NarrowPhaseCollision/*.cpp + src/BulletCollision//CollisionDispatch/*.cpp + src/BulletDynamics/ConstraintSolver/*.cpp + src/BulletDynamics/Vehicle/*.cpp + src/BulletDynamics/Dynamics/*.cpp +) + +ADD_DEFINITIONS(-D_LIB) + +BLENDERLIB(extern_bullet "${SRC}" "${INC}") +#, libtype=['game2', 'player'], priority=[20, 170], compileflags=cflags ) diff --git a/extern/bullet2/Makefile b/extern/bullet2/Makefile new file mode 100644 index 00000000000..2da1a5bcf85 --- /dev/null +++ b/extern/bullet2/Makefile @@ -0,0 +1,61 @@ +# +# $Id: Makefile 14444 2008-04-16 22:40:48Z hos $ +# +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# The Original Code is Copyright (C) 2002 by Hans Lambermont +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): +# +# ***** END GPL LICENSE BLOCK ***** +LIBNAME = bullet2 +include nan_definitions.mk +SOURCEDIR = extern/$(LIBNAME) +DIR = $(OCGDIR)/extern/$(LIBNAME) +DIRS = src +DISTDIR = src + +BULLETDIRS = \ +LinearMath \ +BulletCollision/BroadphaseCollision \ +BulletCollision/CollisionShapes \ +BulletCollision/NarrowPhaseCollision \ +BulletCollision//CollisionDispatch \ +BulletDynamics/ConstraintSolver \ +BulletDynamics/Vehicle \ +BulletDynamics/Dynamics + +include nan_subdirs.mk + +CP = $(NANBLENDERHOME)/intern/tools/cpifdiff.sh + +install: all debug + @[ -d $(NAN_BULLET2) ] || mkdir -p $(NAN_BULLET2) + @[ -d $(NAN_BULLET2)/include ] || mkdir -p $(NAN_BULLET2)/include + @for i in $(BULLETDIRS); do \ + [ -d $(NAN_BULLET2)/include/$$i ] || mkdir -p $(NAN_BULLET2)/include/$$i; \ + $(CP) $(DISTDIR)/$$i/*.h $(NAN_BULLET2)/include/$$i; \ + done + @[ -d $(NAN_BULLET2)/lib ] || mkdir -p $(NAN_BULLET2)/lib + @$(CP) $(DISTDIR)/*.h $(NAN_BULLET2)/include + @$(CP) $(OCGDIR)/extern/bullet2/libbullet2.a $(NAN_BULLET2)/lib +ifeq ($(OS),darwin) + ranlib $(NAN_BULLET2)/lib/libbullet2.a +endif diff --git a/extern/bullet2/make/msvc_7_0/Bullet_vc7.vcproj b/extern/bullet2/make/msvc_7_0/Bullet_vc7.vcproj new file mode 100644 index 00000000000..6de2fd3a2bd --- /dev/null +++ b/extern/bullet2/make/msvc_7_0/Bullet_vc7.vcproj @@ -0,0 +1,927 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/extern/bullet2/readme.txt b/extern/bullet2/readme.txt new file mode 100644 index 00000000000..4d1a4c11706 --- /dev/null +++ b/extern/bullet2/readme.txt @@ -0,0 +1,12 @@ + +*** These files in extern/bullet2 are NOT part of the Blender build yet *** + +This is the new refactored version of Bullet physics library version 2.x + +Soon this will replace the old Bullet version in extern/bullet. +First the integration in Blender Game Engine needs to be updated. +Once that is done all build systems can be updated to use/build extern/bullet2 files. + +Questions? mail blender at erwincoumans.com, or check the bf-blender mailing list. +Thanks, +Erwin diff --git a/extern/bullet2/src/Bullet-C-Api.h b/extern/bullet2/src/Bullet-C-Api.h new file mode 100644 index 00000000000..078dcae63bb --- /dev/null +++ b/extern/bullet2/src/Bullet-C-Api.h @@ -0,0 +1,37 @@ +/* +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. +*/ + +/* + Draft high-level generic physics C-API. For low-level access, use the physics SDK native API's. + Work in progress, functionality will be added on demand. + + If possible, use the richer Bullet C++ API, by including "btBulletDynamicsCommon.h" +*/ + +#ifndef BULLET_C_API_H +#define BULLET_C_API_H + +#ifdef __cplusplus +extern "C" { +#endif + +double plNearestPoints(float p1[3], float p2[3], float p3[3], float q1[3], float q2[3], float q3[3], float *pa, float *pb, float normal[3]); + +#ifdef __cplusplus +} +#endif + +#endif //BULLET_C_API_H + diff --git a/extern/bullet2/src/BulletCollision/BroadphaseCollision/btAxisSweep3.cpp b/extern/bullet2/src/BulletCollision/BroadphaseCollision/btAxisSweep3.cpp new file mode 100644 index 00000000000..be4a11506df --- /dev/null +++ b/extern/bullet2/src/BulletCollision/BroadphaseCollision/btAxisSweep3.cpp @@ -0,0 +1,660 @@ + +//Bullet Continuous Collision Detection and Physics Library +//Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + + +// +// btAxisSweep3 +// +// Copyright (c) 2006 Simon Hobbs +// +// 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 "btAxisSweep3.h" + +#include + +#ifdef DEBUG_BROADPHASE +#include +void btAxisSweep3::debugPrintAxis(int axis, bool checkCardinality) +{ + int numEdges = m_pHandles[0].m_maxEdges[axis]; + printf("SAP Axis %d, numEdges=%d\n",axis,numEdges); + + int i; + for (i=0;im_handle); + int handleIndex = pEdge->IsMax()? pHandlePrev->m_maxEdges[axis] : pHandlePrev->m_minEdges[axis]; + char beginOrEnd; + beginOrEnd=pEdge->IsMax()?'E':'B'; + printf(" [%c,h=%d,p=%x,i=%d]\n",beginOrEnd,pEdge->m_handle,pEdge->m_pos,handleIndex); + } + + if (checkCardinality) + assert(numEdges == m_numHandles*2+1); +} +#endif //DEBUG_BROADPHASE + + +btBroadphaseProxy* btAxisSweep3::createProxy( const btVector3& min, const btVector3& max,int shapeType,void* userPtr,short int collisionFilterGroup,short int collisionFilterMask) +{ + (void)shapeType; + BP_FP_INT_TYPE handleId = addHandle(min,max, userPtr,collisionFilterGroup,collisionFilterMask); + + Handle* handle = getHandle(handleId); + + return handle; +} + +void btAxisSweep3::destroyProxy(btBroadphaseProxy* proxy) +{ + Handle* handle = static_cast(proxy); + removeHandle(handle->m_handleId); +} + +void btAxisSweep3::setAabb(btBroadphaseProxy* proxy,const btVector3& aabbMin,const btVector3& aabbMax) +{ + Handle* handle = static_cast(proxy); + updateHandle(handle->m_handleId,aabbMin,aabbMax); + +} + + + + + + +btAxisSweep3::btAxisSweep3(const btPoint3& worldAabbMin,const btPoint3& worldAabbMax, int maxHandles) +:btOverlappingPairCache() +{ + m_invalidPair = 0; + //assert(bounds.HasVolume()); + + // 1 handle is reserved as sentinel + btAssert(maxHandles > 1 && maxHandles < BP_MAX_HANDLES); + + // init bounds + m_worldAabbMin = worldAabbMin; + m_worldAabbMax = worldAabbMax; + + btVector3 aabbSize = m_worldAabbMax - m_worldAabbMin; + + BP_FP_INT_TYPE maxInt = BP_HANDLE_SENTINEL; + + m_quantize = btVector3(btScalar(maxInt),btScalar(maxInt),btScalar(maxInt)) / aabbSize; + + // allocate handles buffer and put all handles on free list + m_pHandles = new Handle[maxHandles]; + m_maxHandles = maxHandles; + m_numHandles = 0; + + // handle 0 is reserved as the null index, and is also used as the sentinel + m_firstFreeHandle = 1; + { + for (BP_FP_INT_TYPE i = m_firstFreeHandle; i < maxHandles; i++) + m_pHandles[i].SetNextFree(i + 1); + m_pHandles[maxHandles - 1].SetNextFree(0); + } + + { + // allocate edge buffers + for (int i = 0; i < 3; i++) + m_pEdges[i] = new Edge[maxHandles * 2]; + } + //removed overlap management + + // make boundary sentinels + + m_pHandles[0].m_clientObject = 0; + + for (int axis = 0; axis < 3; axis++) + { + m_pHandles[0].m_minEdges[axis] = 0; + m_pHandles[0].m_maxEdges[axis] = 1; + + m_pEdges[axis][0].m_pos = 0; + m_pEdges[axis][0].m_handle = 0; + m_pEdges[axis][1].m_pos = BP_HANDLE_SENTINEL; + m_pEdges[axis][1].m_handle = 0; +#ifdef DEBUG_BROADPHASE + debugPrintAxis(axis); +#endif //DEBUG_BROADPHASE + + } + +} + +btAxisSweep3::~btAxisSweep3() +{ + + for (int i = 2; i >= 0; i--) + delete[] m_pEdges[i]; + delete[] m_pHandles; +} + +void btAxisSweep3::quantize(BP_FP_INT_TYPE* out, const btPoint3& point, int isMax) const +{ + btPoint3 clampedPoint(point); + + + + clampedPoint.setMax(m_worldAabbMin); + clampedPoint.setMin(m_worldAabbMax); + + btVector3 v = (clampedPoint - m_worldAabbMin) * m_quantize; + out[0] = (BP_FP_INT_TYPE)(((BP_FP_INT_TYPE)v.getX() & BP_HANDLE_MASK) | isMax); + out[1] = (BP_FP_INT_TYPE)(((BP_FP_INT_TYPE)v.getY() & BP_HANDLE_MASK) | isMax); + out[2] = (BP_FP_INT_TYPE)(((BP_FP_INT_TYPE)v.getZ() & BP_HANDLE_MASK) | isMax); + +} + + + +BP_FP_INT_TYPE btAxisSweep3::allocHandle() +{ + assert(m_firstFreeHandle); + + BP_FP_INT_TYPE handle = m_firstFreeHandle; + m_firstFreeHandle = getHandle(handle)->GetNextFree(); + m_numHandles++; + + return handle; +} + +void btAxisSweep3::freeHandle(BP_FP_INT_TYPE handle) +{ + assert(handle > 0 && handle < m_maxHandles); + + getHandle(handle)->SetNextFree(m_firstFreeHandle); + m_firstFreeHandle = handle; + + m_numHandles--; +} + + + +BP_FP_INT_TYPE btAxisSweep3::addHandle(const btPoint3& aabbMin,const btPoint3& aabbMax, void* pOwner,short int collisionFilterGroup,short int collisionFilterMask) +{ + // quantize the bounds + BP_FP_INT_TYPE min[3], max[3]; + quantize(min, aabbMin, 0); + quantize(max, aabbMax, 1); + + // allocate a handle + BP_FP_INT_TYPE handle = allocHandle(); + assert(handle!= 0xcdcd); + + Handle* pHandle = getHandle(handle); + + pHandle->m_handleId = handle; + //pHandle->m_pOverlaps = 0; + pHandle->m_clientObject = pOwner; + pHandle->m_collisionFilterGroup = collisionFilterGroup; + pHandle->m_collisionFilterMask = collisionFilterMask; + + // compute current limit of edge arrays + BP_FP_INT_TYPE limit = m_numHandles * 2; + + + // insert new edges just inside the max boundary edge + for (BP_FP_INT_TYPE axis = 0; axis < 3; axis++) + { + + m_pHandles[0].m_maxEdges[axis] += 2; + + m_pEdges[axis][limit + 1] = m_pEdges[axis][limit - 1]; + + m_pEdges[axis][limit - 1].m_pos = min[axis]; + m_pEdges[axis][limit - 1].m_handle = handle; + + m_pEdges[axis][limit].m_pos = max[axis]; + m_pEdges[axis][limit].m_handle = handle; + + pHandle->m_minEdges[axis] = limit - 1; + pHandle->m_maxEdges[axis] = limit; + } + + // now sort the new edges to their correct position + sortMinDown(0, pHandle->m_minEdges[0], false); + sortMaxDown(0, pHandle->m_maxEdges[0], false); + sortMinDown(1, pHandle->m_minEdges[1], false); + sortMaxDown(1, pHandle->m_maxEdges[1], false); + sortMinDown(2, pHandle->m_minEdges[2], true); + sortMaxDown(2, pHandle->m_maxEdges[2], true); + + + return handle; +} + + +void btAxisSweep3::removeHandle(BP_FP_INT_TYPE handle) +{ + + Handle* pHandle = getHandle(handle); + + //explicitly remove the pairs containing the proxy + //we could do it also in the sortMinUp (passing true) + //todo: compare performance + removeOverlappingPairsContainingProxy(pHandle); + + + // compute current limit of edge arrays + int limit = m_numHandles * 2; + + int axis; + + for (axis = 0;axis<3;axis++) + { + m_pHandles[0].m_maxEdges[axis] -= 2; + } + + // remove the edges by sorting them up to the end of the list + for ( axis = 0; axis < 3; axis++) + { + Edge* pEdges = m_pEdges[axis]; + BP_FP_INT_TYPE max = pHandle->m_maxEdges[axis]; + pEdges[max].m_pos = BP_HANDLE_SENTINEL; + + sortMaxUp(axis,max,false); + + + BP_FP_INT_TYPE i = pHandle->m_minEdges[axis]; + pEdges[i].m_pos = BP_HANDLE_SENTINEL; + + + sortMinUp(axis,i,false); + + pEdges[limit-1].m_handle = 0; + pEdges[limit-1].m_pos = BP_HANDLE_SENTINEL; + +#ifdef DEBUG_BROADPHASE + debugPrintAxis(axis,false); +#endif //DEBUG_BROADPHASE + + + } + + + // free the handle + freeHandle(handle); + + +} + +extern int gOverlappingPairs; + + +void btAxisSweep3::refreshOverlappingPairs() +{ + +} +void btAxisSweep3::processAllOverlappingPairs(btOverlapCallback* callback) +{ + + //perform a sort, to find duplicates and to sort 'invalid' pairs to the end + m_overlappingPairArray.heapSort(btBroadphasePairSortPredicate()); + + //remove the 'invalid' ones +#ifdef USE_POPBACK_REMOVAL + while (m_invalidPair>0) + { + m_invalidPair--; + m_overlappingPairArray.pop_back(); + } +#else + m_overlappingPairArray.resize(m_overlappingPairArray.size() - m_invalidPair); + m_invalidPair = 0; +#endif + + + int i; + + btBroadphasePair previousPair; + previousPair.m_pProxy0 = 0; + previousPair.m_pProxy1 = 0; + previousPair.m_algorithm = 0; + + + for (i=0;iprocessOverlap(pair); + } else + { + needsRemoval = true; + } + } else + { + //remove duplicate + needsRemoval = true; + //should have no algorithm + btAssert(!pair.m_algorithm); + } + + if (needsRemoval) + { + cleanOverlappingPair(pair); + + // m_overlappingPairArray.swap(i,m_overlappingPairArray.size()-1); + // m_overlappingPairArray.pop_back(); + pair.m_pProxy0 = 0; + pair.m_pProxy1 = 0; + m_invalidPair++; + gOverlappingPairs--; + } + + } +} + + +bool btAxisSweep3::testOverlap(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1) +{ + const Handle* pHandleA = static_cast(proxy0); + const Handle* pHandleB = static_cast(proxy1); + + //optimization 1: check the array index (memory address), instead of the m_pos + + for (int axis = 0; axis < 3; axis++) + { + if (pHandleA->m_maxEdges[axis] < pHandleB->m_minEdges[axis] || + pHandleB->m_maxEdges[axis] < pHandleA->m_minEdges[axis]) + { + return false; + } + } + return true; +} + +bool btAxisSweep3::testOverlap(int ignoreAxis,const Handle* pHandleA, const Handle* pHandleB) +{ + //optimization 1: check the array index (memory address), instead of the m_pos + + for (int axis = 0; axis < 3; axis++) + { + if (axis != ignoreAxis) + { + if (pHandleA->m_maxEdges[axis] < pHandleB->m_minEdges[axis] || + pHandleB->m_maxEdges[axis] < pHandleA->m_minEdges[axis]) + { + return false; + } + } + } + + //optimization 2: only 2 axis need to be tested (conflicts with 'delayed removal' optimization) + + /*for (int axis = 0; axis < 3; axis++) + { + if (m_pEdges[axis][pHandleA->m_maxEdges[axis]].m_pos < m_pEdges[axis][pHandleB->m_minEdges[axis]].m_pos || + m_pEdges[axis][pHandleB->m_maxEdges[axis]].m_pos < m_pEdges[axis][pHandleA->m_minEdges[axis]].m_pos) + { + return false; + } + } + */ + + return true; +} + +void btAxisSweep3::updateHandle(BP_FP_INT_TYPE handle, const btPoint3& aabbMin,const btPoint3& aabbMax) +{ +// assert(bounds.IsFinite()); + //assert(bounds.HasVolume()); + + Handle* pHandle = getHandle(handle); + + // quantize the new bounds + BP_FP_INT_TYPE min[3], max[3]; + quantize(min, aabbMin, 0); + quantize(max, aabbMax, 1); + + // update changed edges + for (int axis = 0; axis < 3; axis++) + { + BP_FP_INT_TYPE emin = pHandle->m_minEdges[axis]; + BP_FP_INT_TYPE emax = pHandle->m_maxEdges[axis]; + + int dmin = (int)min[axis] - (int)m_pEdges[axis][emin].m_pos; + int dmax = (int)max[axis] - (int)m_pEdges[axis][emax].m_pos; + + m_pEdges[axis][emin].m_pos = min[axis]; + m_pEdges[axis][emax].m_pos = max[axis]; + + // expand (only adds overlaps) + if (dmin < 0) + sortMinDown(axis, emin); + + if (dmax > 0) + sortMaxUp(axis, emax); + + // shrink (only removes overlaps) + if (dmin > 0) + sortMinUp(axis, emin); + + if (dmax < 0) + sortMaxDown(axis, emax); + +#ifdef DEBUG_BROADPHASE + debugPrintAxis(axis); +#endif //DEBUG_BROADPHASE + } + + +} + + + + +// sorting a min edge downwards can only ever *add* overlaps +void btAxisSweep3::sortMinDown(int axis, BP_FP_INT_TYPE edge, bool updateOverlaps) +{ + + Edge* pEdge = m_pEdges[axis] + edge; + Edge* pPrev = pEdge - 1; + Handle* pHandleEdge = getHandle(pEdge->m_handle); + + while (pEdge->m_pos < pPrev->m_pos) + { + Handle* pHandlePrev = getHandle(pPrev->m_handle); + + if (pPrev->IsMax()) + { + // if previous edge is a maximum check the bounds and add an overlap if necessary + if (updateOverlaps && testOverlap(axis,pHandleEdge, pHandlePrev)) + { + addOverlappingPair(pHandleEdge,pHandlePrev); + + //AddOverlap(pEdge->m_handle, pPrev->m_handle); + + } + + // update edge reference in other handle + pHandlePrev->m_maxEdges[axis]++; + } + else + pHandlePrev->m_minEdges[axis]++; + + pHandleEdge->m_minEdges[axis]--; + + // swap the edges + Edge swap = *pEdge; + *pEdge = *pPrev; + *pPrev = swap; + + // decrement + pEdge--; + pPrev--; + } + +#ifdef DEBUG_BROADPHASE + debugPrintAxis(axis); +#endif //DEBUG_BROADPHASE + +} + +// sorting a min edge upwards can only ever *remove* overlaps +void btAxisSweep3::sortMinUp(int axis, BP_FP_INT_TYPE edge, bool updateOverlaps) +{ + Edge* pEdge = m_pEdges[axis] + edge; + Edge* pNext = pEdge + 1; + Handle* pHandleEdge = getHandle(pEdge->m_handle); + + while (pNext->m_handle && (pEdge->m_pos >= pNext->m_pos)) + { + Handle* pHandleNext = getHandle(pNext->m_handle); + + if (pNext->IsMax()) + { + // if next edge is maximum remove any overlap between the two handles + if (updateOverlaps) + { + /* + Handle* handle0 = getHandle(pEdge->m_handle); + Handle* handle1 = getHandle(pNext->m_handle); + btBroadphasePair tmpPair(*handle0,*handle1); + removeOverlappingPair(tmpPair); + */ + + } + + // update edge reference in other handle + pHandleNext->m_maxEdges[axis]--; + } + else + pHandleNext->m_minEdges[axis]--; + + pHandleEdge->m_minEdges[axis]++; + + // swap the edges + Edge swap = *pEdge; + *pEdge = *pNext; + *pNext = swap; + + // increment + pEdge++; + pNext++; + } + + +} + +// sorting a max edge downwards can only ever *remove* overlaps +void btAxisSweep3::sortMaxDown(int axis, BP_FP_INT_TYPE edge, bool updateOverlaps) +{ + + Edge* pEdge = m_pEdges[axis] + edge; + Edge* pPrev = pEdge - 1; + Handle* pHandleEdge = getHandle(pEdge->m_handle); + + while (pEdge->m_pos < pPrev->m_pos) + { + Handle* pHandlePrev = getHandle(pPrev->m_handle); + + if (!pPrev->IsMax()) + { + // if previous edge was a minimum remove any overlap between the two handles + if (updateOverlaps) + { + //this is done during the overlappingpairarray iteration/narrowphase collision + /* + Handle* handle0 = getHandle(pEdge->m_handle); + Handle* handle1 = getHandle(pPrev->m_handle); + btBroadphasePair* pair = findPair(handle0,handle1); + //assert(pair); + + if (pair) + { + removeOverlappingPair(*pair); + } + */ + + } + + // update edge reference in other handle + pHandlePrev->m_minEdges[axis]++;; + } + else + pHandlePrev->m_maxEdges[axis]++; + + pHandleEdge->m_maxEdges[axis]--; + + // swap the edges + Edge swap = *pEdge; + *pEdge = *pPrev; + *pPrev = swap; + + // decrement + pEdge--; + pPrev--; + } + + +#ifdef DEBUG_BROADPHASE + debugPrintAxis(axis); +#endif //DEBUG_BROADPHASE + +} + +// sorting a max edge upwards can only ever *add* overlaps +void btAxisSweep3::sortMaxUp(int axis, BP_FP_INT_TYPE edge, bool updateOverlaps) +{ + Edge* pEdge = m_pEdges[axis] + edge; + Edge* pNext = pEdge + 1; + Handle* pHandleEdge = getHandle(pEdge->m_handle); + + while (pNext->m_handle && (pEdge->m_pos >= pNext->m_pos)) + { + Handle* pHandleNext = getHandle(pNext->m_handle); + + if (!pNext->IsMax()) + { + // if next edge is a minimum check the bounds and add an overlap if necessary + if (updateOverlaps && testOverlap(axis, pHandleEdge, pHandleNext)) + { + Handle* handle0 = getHandle(pEdge->m_handle); + Handle* handle1 = getHandle(pNext->m_handle); + addOverlappingPair(handle0,handle1); + } + + // update edge reference in other handle + pHandleNext->m_minEdges[axis]--; + } + else + pHandleNext->m_maxEdges[axis]--; + + pHandleEdge->m_maxEdges[axis]++; + + // swap the edges + Edge swap = *pEdge; + *pEdge = *pNext; + *pNext = swap; + + // increment + pEdge++; + pNext++; + } + +} diff --git a/extern/bullet2/src/BulletCollision/BroadphaseCollision/btAxisSweep3.h b/extern/bullet2/src/BulletCollision/BroadphaseCollision/btAxisSweep3.h new file mode 100644 index 00000000000..57bbb368672 --- /dev/null +++ b/extern/bullet2/src/BulletCollision/BroadphaseCollision/btAxisSweep3.h @@ -0,0 +1,138 @@ +//Bullet Continuous Collision Detection and Physics Library +//Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +// +// btAxisSweep3.h +// +// Copyright (c) 2006 Simon Hobbs +// +// 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 AXIS_SWEEP_3_H +#define AXIS_SWEEP_3_H + +#include "../../LinearMath/btPoint3.h" +#include "../../LinearMath/btVector3.h" +#include "btOverlappingPairCache.h" +#include "btBroadphaseProxy.h" + + +//Enable BP_USE_FIXEDPOINT_INT_32 if you need more then 32767 objects +//#define BP_USE_FIXEDPOINT_INT_32 1 + +#ifdef BP_USE_FIXEDPOINT_INT_32 + #define BP_FP_INT_TYPE unsigned int + #define BP_MAX_HANDLES 1500000 //arbitrary maximum number of handles + #define BP_HANDLE_SENTINEL 0x7fffffff + #define BP_HANDLE_MASK 0xfffffffe +#else + #define BP_FP_INT_TYPE unsigned short int + #define BP_MAX_HANDLES 32767 + #define BP_HANDLE_SENTINEL 0xffff + #define BP_HANDLE_MASK 0xfffe +#endif //BP_USE_FIXEDPOINT_INT_32 + +//#define DEBUG_BROADPHASE 1 + +/// btAxisSweep3 is an efficient implementation of the 3d axis sweep and prune broadphase. +/// It uses arrays rather then lists for storage of the 3 axis. Also it operates using integer coordinates instead of floats. +/// The testOverlap check is optimized to check the array index, rather then the actual AABB coordinates/pos +class btAxisSweep3 : public btOverlappingPairCache +{ + +public: + + + class Edge + { + public: + BP_FP_INT_TYPE m_pos; // low bit is min/max + BP_FP_INT_TYPE m_handle; + + BP_FP_INT_TYPE IsMax() const {return m_pos & 1;} + }; + +public: + class Handle : public btBroadphaseProxy + { + public: + + // indexes into the edge arrays + BP_FP_INT_TYPE m_minEdges[3], m_maxEdges[3]; // 6 * 2 = 12 + BP_FP_INT_TYPE m_handleId; + BP_FP_INT_TYPE m_pad; + + //void* m_pOwner; this is now in btBroadphaseProxy.m_clientObject + + inline void SetNextFree(BP_FP_INT_TYPE next) {m_minEdges[0] = next;} + inline BP_FP_INT_TYPE GetNextFree() const {return m_minEdges[0];} + }; // 24 bytes + 24 for Edge structures = 44 bytes total per entry + + +private: + btPoint3 m_worldAabbMin; // overall system bounds + btPoint3 m_worldAabbMax; // overall system bounds + + btVector3 m_quantize; // scaling factor for quantization + + BP_FP_INT_TYPE m_numHandles; // number of active handles + int m_maxHandles; // max number of handles + Handle* m_pHandles; // handles pool + BP_FP_INT_TYPE m_firstFreeHandle; // free handles list + + Edge* m_pEdges[3]; // edge arrays for the 3 axes (each array has m_maxHandles * 2 + 2 sentinel entries) + + int m_invalidPair; + + // allocation/deallocation + BP_FP_INT_TYPE allocHandle(); + void freeHandle(BP_FP_INT_TYPE handle); + + + bool testOverlap(int ignoreAxis,const Handle* pHandleA, const Handle* pHandleB); + +#ifdef DEBUG_BROADPHASE + void debugPrintAxis(int axis,bool checkCardinality=true); +#endif //DEBUG_BROADPHASE + + //Overlap* AddOverlap(BP_FP_INT_TYPE handleA, BP_FP_INT_TYPE handleB); + //void RemoveOverlap(BP_FP_INT_TYPE handleA, BP_FP_INT_TYPE handleB); + + void quantize(BP_FP_INT_TYPE* out, const btPoint3& point, int isMax) const; + + void sortMinDown(int axis, BP_FP_INT_TYPE edge, bool updateOverlaps = true); + void sortMinUp(int axis, BP_FP_INT_TYPE edge, bool updateOverlaps = true); + void sortMaxDown(int axis, BP_FP_INT_TYPE edge, bool updateOverlaps = true); + void sortMaxUp(int axis, BP_FP_INT_TYPE edge, bool updateOverlaps = true); + +public: + btAxisSweep3(const btPoint3& worldAabbMin,const btPoint3& worldAabbMax, int maxHandles = 16384); + virtual ~btAxisSweep3(); + + virtual void refreshOverlappingPairs(); + + BP_FP_INT_TYPE addHandle(const btPoint3& aabbMin,const btPoint3& aabbMax, void* pOwner,short int collisionFilterGroup,short int collisionFilterMask); + void removeHandle(BP_FP_INT_TYPE handle); + void updateHandle(BP_FP_INT_TYPE handle, const btPoint3& aabbMin,const btPoint3& aabbMax); + inline Handle* getHandle(BP_FP_INT_TYPE index) const {return m_pHandles + index;} + + void processAllOverlappingPairs(btOverlapCallback* callback); + + //Broadphase Interface + virtual btBroadphaseProxy* createProxy( const btVector3& min, const btVector3& max,int shapeType,void* userPtr ,short int collisionFilterGroup,short int collisionFilterMask); + virtual void destroyProxy(btBroadphaseProxy* proxy); + virtual void setAabb(btBroadphaseProxy* proxy,const btVector3& aabbMin,const btVector3& aabbMax); + bool testOverlap(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1); + +}; + +#endif + diff --git a/extern/bullet2/src/BulletCollision/BroadphaseCollision/btBroadphaseInterface.h b/extern/bullet2/src/BulletCollision/BroadphaseCollision/btBroadphaseInterface.h new file mode 100644 index 00000000000..b6ace03c07a --- /dev/null +++ b/extern/bullet2/src/BulletCollision/BroadphaseCollision/btBroadphaseInterface.h @@ -0,0 +1,40 @@ +/* +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 BROADPHASE_INTERFACE_H +#define BROADPHASE_INTERFACE_H + + + +struct btDispatcherInfo; +class btDispatcher; +struct btBroadphaseProxy; +#include "../../LinearMath/btVector3.h" + +///BroadphaseInterface for aabb-overlapping object pairs +class btBroadphaseInterface +{ +public: + virtual ~btBroadphaseInterface() {} + + virtual btBroadphaseProxy* createProxy( const btVector3& min, const btVector3& max,int shapeType,void* userPtr, short int collisionFilterGroup,short int collisionFilterMask) =0; + virtual void destroyProxy(btBroadphaseProxy* proxy)=0; + virtual void setAabb(btBroadphaseProxy* proxy,const btVector3& aabbMin,const btVector3& aabbMax)=0; + virtual void cleanProxyFromPairs(btBroadphaseProxy* proxy)=0; + + +}; + +#endif //BROADPHASE_INTERFACE_H diff --git a/extern/bullet2/src/BulletCollision/BroadphaseCollision/btBroadphaseProxy.cpp b/extern/bullet2/src/BulletCollision/BroadphaseCollision/btBroadphaseProxy.cpp new file mode 100644 index 00000000000..f4d7341f8dd --- /dev/null +++ b/extern/bullet2/src/BulletCollision/BroadphaseCollision/btBroadphaseProxy.cpp @@ -0,0 +1,17 @@ +/* +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 "btBroadphaseProxy.h" + diff --git a/extern/bullet2/src/BulletCollision/BroadphaseCollision/btBroadphaseProxy.h b/extern/bullet2/src/BulletCollision/BroadphaseCollision/btBroadphaseProxy.h new file mode 100644 index 00000000000..40d9748ffa9 --- /dev/null +++ b/extern/bullet2/src/BulletCollision/BroadphaseCollision/btBroadphaseProxy.h @@ -0,0 +1,204 @@ +/* +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 BROADPHASE_PROXY_H +#define BROADPHASE_PROXY_H + +#include "../../LinearMath/btScalar.h" //for SIMD_FORCE_INLINE + + +/// btDispatcher uses these types +/// IMPORTANT NOTE:The types are ordered polyhedral, implicit convex and concave +/// to facilitate type checking +enum BroadphaseNativeTypes +{ +// polyhedral convex shapes + BOX_SHAPE_PROXYTYPE, + TRIANGLE_SHAPE_PROXYTYPE, + TETRAHEDRAL_SHAPE_PROXYTYPE, + CONVEX_TRIANGLEMESH_SHAPE_PROXYTYPE, + CONVEX_HULL_SHAPE_PROXYTYPE, +//implicit convex shapes +IMPLICIT_CONVEX_SHAPES_START_HERE, + SPHERE_SHAPE_PROXYTYPE, + MULTI_SPHERE_SHAPE_PROXYTYPE, + CAPSULE_SHAPE_PROXYTYPE, + CONE_SHAPE_PROXYTYPE, + CONVEX_SHAPE_PROXYTYPE, + CYLINDER_SHAPE_PROXYTYPE, + MINKOWSKI_SUM_SHAPE_PROXYTYPE, + MINKOWSKI_DIFFERENCE_SHAPE_PROXYTYPE, +//concave shapes +CONCAVE_SHAPES_START_HERE, + //keep all the convex shapetype below here, for the check IsConvexShape in broadphase proxy! + TRIANGLE_MESH_SHAPE_PROXYTYPE, + ///used for demo integration FAST/Swift collision library and Bullet + FAST_CONCAVE_MESH_PROXYTYPE, + //terrain + TERRAIN_SHAPE_PROXYTYPE, +///Used for GIMPACT Trimesh integration + GIMPACT_SHAPE_PROXYTYPE, + + EMPTY_SHAPE_PROXYTYPE, + STATIC_PLANE_PROXYTYPE, +CONCAVE_SHAPES_END_HERE, + + COMPOUND_SHAPE_PROXYTYPE, + + MAX_BROADPHASE_COLLISION_TYPES +}; + + +///btBroadphaseProxy +struct btBroadphaseProxy +{ + + ///optional filtering to cull potential collisions + enum CollisionFilterGroups + { + DefaultFilter = 1, + StaticFilter = 2, + KinematicFilter = 4, + DebrisFilter = 8, + SensorTrigger = 16, + AllFilter = DefaultFilter | StaticFilter | KinematicFilter | DebrisFilter | SensorTrigger + }; + + //Usually the client btCollisionObject or Rigidbody class + void* m_clientObject; + short int m_collisionFilterGroup; + short int m_collisionFilterMask; + + //used for memory pools + btBroadphaseProxy() :m_clientObject(0){} + + btBroadphaseProxy(void* userPtr,short int collisionFilterGroup, short int collisionFilterMask) + :m_clientObject(userPtr), + m_collisionFilterGroup(collisionFilterGroup), + m_collisionFilterMask(collisionFilterMask) + { + } + + static inline bool isPolyhedral(int proxyType) + { + return (proxyType < IMPLICIT_CONVEX_SHAPES_START_HERE); + } + + static inline bool isConvex(int proxyType) + { + return (proxyType < CONCAVE_SHAPES_START_HERE); + } + + static inline bool isConcave(int proxyType) + { + return ((proxyType > CONCAVE_SHAPES_START_HERE) && + (proxyType < CONCAVE_SHAPES_END_HERE)); + } + static inline bool isCompound(int proxyType) + { + return (proxyType == COMPOUND_SHAPE_PROXYTYPE); + } + static inline bool isInfinite(int proxyType) + { + return (proxyType == STATIC_PLANE_PROXYTYPE); + } + +} +; + +class btCollisionAlgorithm; + +struct btBroadphaseProxy; + + + +/// contains a pair of aabb-overlapping objects +struct btBroadphasePair +{ + btBroadphasePair () + : + m_pProxy0(0), + m_pProxy1(0), + m_algorithm(0), + m_userInfo(0) + { + } + + btBroadphasePair(const btBroadphasePair& other) + : m_pProxy0(other.m_pProxy0), + m_pProxy1(other.m_pProxy1), + m_algorithm(other.m_algorithm), + m_userInfo(other.m_userInfo) + { + } + btBroadphasePair(btBroadphaseProxy& proxy0,btBroadphaseProxy& proxy1) + { + + //keep them sorted, so the std::set operations work + if (&proxy0 < &proxy1) + { + m_pProxy0 = &proxy0; + m_pProxy1 = &proxy1; + } + else + { + m_pProxy0 = &proxy1; + m_pProxy1 = &proxy0; + } + + m_algorithm = 0; + m_userInfo = 0; + + } + + btBroadphaseProxy* m_pProxy0; + btBroadphaseProxy* m_pProxy1; + + mutable btCollisionAlgorithm* m_algorithm; + mutable void* m_userInfo; + +}; + +/* +//comparison for set operation, see Solid DT_Encounter +SIMD_FORCE_INLINE bool operator<(const btBroadphasePair& a, const btBroadphasePair& b) +{ + return a.m_pProxy0 < b.m_pProxy0 || + (a.m_pProxy0 == b.m_pProxy0 && a.m_pProxy1 < b.m_pProxy1); +} +*/ + + +class btBroadphasePairSortPredicate +{ + public: + + bool operator() ( const btBroadphasePair& a, const btBroadphasePair& b ) + { + return a.m_pProxy0 > b.m_pProxy0 || + (a.m_pProxy0 == b.m_pProxy0 && a.m_pProxy1 > b.m_pProxy1) || + (a.m_pProxy0 == b.m_pProxy0 && a.m_pProxy1 == b.m_pProxy1 && a.m_algorithm > b.m_algorithm); + } +}; + + +SIMD_FORCE_INLINE bool operator==(const btBroadphasePair& a, const btBroadphasePair& b) +{ + return (a.m_pProxy0 == b.m_pProxy0) && (a.m_pProxy1 == b.m_pProxy1); +} + + +#endif //BROADPHASE_PROXY_H + diff --git a/extern/bullet2/src/BulletCollision/BroadphaseCollision/btCollisionAlgorithm.cpp b/extern/bullet2/src/BulletCollision/BroadphaseCollision/btCollisionAlgorithm.cpp new file mode 100644 index 00000000000..2ad0c86d8a2 --- /dev/null +++ b/extern/bullet2/src/BulletCollision/BroadphaseCollision/btCollisionAlgorithm.cpp @@ -0,0 +1,23 @@ +/* +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 "btCollisionAlgorithm.h" +#include "btDispatcher.h" + +btCollisionAlgorithm::btCollisionAlgorithm(const btCollisionAlgorithmConstructionInfo& ci) +{ + m_dispatcher = ci.m_dispatcher; +} + diff --git a/extern/bullet2/src/BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h b/extern/bullet2/src/BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h new file mode 100644 index 00000000000..55cec386a7b --- /dev/null +++ b/extern/bullet2/src/BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h @@ -0,0 +1,77 @@ +/* +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 COLLISION_ALGORITHM_H +#define COLLISION_ALGORITHM_H + +#include "../../LinearMath/btScalar.h" + +struct btBroadphaseProxy; +class btDispatcher; +class btManifoldResult; +class btCollisionObject; +struct btDispatcherInfo; +class btPersistentManifold; + + +struct btCollisionAlgorithmConstructionInfo +{ + btCollisionAlgorithmConstructionInfo() + :m_dispatcher(0), + m_manifold(0) + { + } + btCollisionAlgorithmConstructionInfo(btDispatcher* dispatcher,int temp) + :m_dispatcher(dispatcher) + { + (void)temp; + } + + btDispatcher* m_dispatcher; + btPersistentManifold* m_manifold; + + int getDispatcherId(); + +}; + + +///btCollisionAlgorithm is an collision interface that is compatible with the Broadphase and btDispatcher. +///It is persistent over frames +class btCollisionAlgorithm +{ + +protected: + + btDispatcher* m_dispatcher; + +protected: + int getDispatcherId(); + +public: + + btCollisionAlgorithm() {}; + + btCollisionAlgorithm(const btCollisionAlgorithmConstructionInfo& ci); + + virtual ~btCollisionAlgorithm() {}; + + virtual void processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut) = 0; + + virtual btScalar calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut) = 0; + +}; + + +#endif //COLLISION_ALGORITHM_H diff --git a/extern/bullet2/src/BulletCollision/BroadphaseCollision/btDispatcher.cpp b/extern/bullet2/src/BulletCollision/BroadphaseCollision/btDispatcher.cpp new file mode 100644 index 00000000000..20768225b3a --- /dev/null +++ b/extern/bullet2/src/BulletCollision/BroadphaseCollision/btDispatcher.cpp @@ -0,0 +1,22 @@ +/* +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 "btDispatcher.h" + +btDispatcher::~btDispatcher() +{ + +} + diff --git a/extern/bullet2/src/BulletCollision/BroadphaseCollision/btDispatcher.h b/extern/bullet2/src/BulletCollision/BroadphaseCollision/btDispatcher.h new file mode 100644 index 00000000000..3d958cc8fef --- /dev/null +++ b/extern/bullet2/src/BulletCollision/BroadphaseCollision/btDispatcher.h @@ -0,0 +1,93 @@ +/* +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 _DISPATCHER_H +#define _DISPATCHER_H + +#include "../../LinearMath/btScalar.h" + +class btCollisionAlgorithm; +struct btBroadphaseProxy; +class btRigidBody; +class btCollisionObject; +class btOverlappingPairCache; + + +class btPersistentManifold; +class btStackAlloc; + +struct btDispatcherInfo +{ + enum DispatchFunc + { + DISPATCH_DISCRETE = 1, + DISPATCH_CONTINUOUS + }; + btDispatcherInfo() + :m_timeStep(btScalar(0.)), + m_stepCount(0), + m_dispatchFunc(DISPATCH_DISCRETE), + m_timeOfImpact(btScalar(1.)), + m_useContinuous(false), + m_debugDraw(0), + m_enableSatConvex(false), + m_enableSPU(false), + m_stackAllocator(0) + { + + } + btScalar m_timeStep; + int m_stepCount; + int m_dispatchFunc; + btScalar m_timeOfImpact; + bool m_useContinuous; + class btIDebugDraw* m_debugDraw; + bool m_enableSatConvex; + bool m_enableSPU; + btStackAlloc* m_stackAllocator; + +}; + +/// btDispatcher can be used in combination with broadphase to dispatch overlapping pairs. +/// For example for pairwise collision detection or user callbacks (game logic). +class btDispatcher +{ + + +public: + virtual ~btDispatcher() ; + + virtual btCollisionAlgorithm* findAlgorithm(btCollisionObject* body0,btCollisionObject* body1,btPersistentManifold* sharedManifold=0) = 0; + + virtual btPersistentManifold* getNewManifold(void* body0,void* body1)=0; + + virtual void releaseManifold(btPersistentManifold* manifold)=0; + + virtual void clearManifold(btPersistentManifold* manifold)=0; + + virtual bool needsCollision(btCollisionObject* body0,btCollisionObject* body1) = 0; + + virtual bool needsResponse(btCollisionObject* body0,btCollisionObject* body1)=0; + + virtual void dispatchAllCollisionPairs(btOverlappingPairCache* pairCache,btDispatcherInfo& dispatchInfo)=0; + + virtual int getNumManifolds() const = 0; + + virtual btPersistentManifold* getManifoldByIndexInternal(int index) = 0; + +}; + + +#endif //_DISPATCHER_H diff --git a/extern/bullet2/src/BulletCollision/BroadphaseCollision/btOverlappingPairCache.cpp b/extern/bullet2/src/BulletCollision/BroadphaseCollision/btOverlappingPairCache.cpp new file mode 100644 index 00000000000..60f0a41a9d7 --- /dev/null +++ b/extern/bullet2/src/BulletCollision/BroadphaseCollision/btOverlappingPairCache.cpp @@ -0,0 +1,196 @@ + +/* +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 "btOverlappingPairCache.h" + +#include "btDispatcher.h" +#include "btCollisionAlgorithm.h" + +int gOverlappingPairs = 0; + +btOverlappingPairCache::btOverlappingPairCache(): +m_blockedForChanges(false), +m_overlapFilterCallback(0) +//m_NumOverlapBroadphasePair(0) +{ +} + + +btOverlappingPairCache::~btOverlappingPairCache() +{ + //todo/test: show we erase/delete data, or is it automatic +} + + +void btOverlappingPairCache::removeOverlappingPair(btBroadphasePair& findPair) +{ + + int findIndex = m_overlappingPairArray.findLinearSearch(findPair); + if (findIndex < m_overlappingPairArray.size()) + { + gOverlappingPairs--; + btBroadphasePair& pair = m_overlappingPairArray[findIndex]; + cleanOverlappingPair(pair); + + m_overlappingPairArray.swap(findIndex,m_overlappingPairArray.size()-1); + m_overlappingPairArray.pop_back(); + } +} + + +void btOverlappingPairCache::cleanOverlappingPair(btBroadphasePair& pair) +{ + if (pair.m_algorithm) + { + { + delete pair.m_algorithm;; + pair.m_algorithm=0; + } + } +} + + + + + +void btOverlappingPairCache::addOverlappingPair(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1) +{ + //don't add overlap with own + assert(proxy0 != proxy1); + + if (!needsBroadphaseCollision(proxy0,proxy1)) + return; + + + btBroadphasePair pair(*proxy0,*proxy1); + + m_overlappingPairArray.push_back(pair); + gOverlappingPairs++; + +} + +///this findPair becomes really slow. Either sort the list to speedup the query, or +///use a different solution. It is mainly used for Removing overlapping pairs. Removal could be delayed. +///we could keep a linked list in each proxy, and store pair in one of the proxies (with lowest memory address) +///Also we can use a 2D bitmap, which can be useful for a future GPU implementation + btBroadphasePair* btOverlappingPairCache::findPair(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1) +{ + if (!needsBroadphaseCollision(proxy0,proxy1)) + return 0; + + btBroadphasePair tmpPair(*proxy0,*proxy1); + int findIndex = m_overlappingPairArray.findLinearSearch(tmpPair); + + if (findIndex < m_overlappingPairArray.size()) + { + //assert(it != m_overlappingPairSet.end()); + btBroadphasePair* pair = &m_overlappingPairArray[findIndex]; + return pair; + } + return 0; +} + + + + + +void btOverlappingPairCache::cleanProxyFromPairs(btBroadphaseProxy* proxy) +{ + + class CleanPairCallback : public btOverlapCallback + { + btBroadphaseProxy* m_cleanProxy; + btOverlappingPairCache* m_pairCache; + + public: + CleanPairCallback(btBroadphaseProxy* cleanProxy,btOverlappingPairCache* pairCache) + :m_cleanProxy(cleanProxy), + m_pairCache(pairCache) + { + } + virtual bool processOverlap(btBroadphasePair& pair) + { + if ((pair.m_pProxy0 == m_cleanProxy) || + (pair.m_pProxy1 == m_cleanProxy)) + { + m_pairCache->cleanOverlappingPair(pair); + } + return false; + } + + }; + + CleanPairCallback cleanPairs(proxy,this); + + processAllOverlappingPairs(&cleanPairs); + +} + + + +void btOverlappingPairCache::removeOverlappingPairsContainingProxy(btBroadphaseProxy* proxy) +{ + + class RemovePairCallback : public btOverlapCallback + { + btBroadphaseProxy* m_obsoleteProxy; + + public: + RemovePairCallback(btBroadphaseProxy* obsoleteProxy) + :m_obsoleteProxy(obsoleteProxy) + { + } + virtual bool processOverlap(btBroadphasePair& pair) + { + return ((pair.m_pProxy0 == m_obsoleteProxy) || + (pair.m_pProxy1 == m_obsoleteProxy)); + } + + }; + + + RemovePairCallback removeCallback(proxy); + + processAllOverlappingPairs(&removeCallback); +} + + + +void btOverlappingPairCache::processAllOverlappingPairs(btOverlapCallback* callback) +{ + + int i; + + for (i=0;iprocessOverlap(*pair)) + { + cleanOverlappingPair(*pair); + + m_overlappingPairArray.swap(i,m_overlappingPairArray.size()-1); + m_overlappingPairArray.pop_back(); + gOverlappingPairs--; + } else + { + i++; + } + } +} + diff --git a/extern/bullet2/src/BulletCollision/BroadphaseCollision/btOverlappingPairCache.h b/extern/bullet2/src/BulletCollision/BroadphaseCollision/btOverlappingPairCache.h new file mode 100644 index 00000000000..a81fe3264df --- /dev/null +++ b/extern/bullet2/src/BulletCollision/BroadphaseCollision/btOverlappingPairCache.h @@ -0,0 +1,120 @@ + +/* +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 OVERLAPPING_PAIR_CACHE_H +#define OVERLAPPING_PAIR_CACHE_H + + +#include "btBroadphaseInterface.h" +#include "btBroadphaseProxy.h" +#include "../../LinearMath/btPoint3.h" +#include "../../LinearMath/btAlignedObjectArray.h" + + +struct btOverlapCallback +{ + virtual ~btOverlapCallback() + {} + //return true for deletion of the pair + virtual bool processOverlap(btBroadphasePair& pair) = 0; +}; + +struct btOverlapFilterCallback +{ + virtual ~btOverlapFilterCallback() + {} + // return true when pairs need collision + virtual bool needBroadphaseCollision(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1) const = 0; +}; + +///btOverlappingPairCache maintains the objects with overlapping AABB +///Typically managed by the Broadphase, Axis3Sweep or btSimpleBroadphase +class btOverlappingPairCache : public btBroadphaseInterface +{ + protected: + //avoid brute-force finding all the time + btAlignedObjectArray m_overlappingPairArray; + + //during the dispatch, check that user doesn't destroy/create proxy + bool m_blockedForChanges; + + //if set, use the callback instead of the built in filter in needBroadphaseCollision + btOverlapFilterCallback* m_overlapFilterCallback; + public: + + btOverlappingPairCache(); + virtual ~btOverlappingPairCache(); + + virtual void processAllOverlappingPairs(btOverlapCallback*); + + void removeOverlappingPair(btBroadphasePair& pair); + + void cleanOverlappingPair(btBroadphasePair& pair); + + void addOverlappingPair(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1); + + btBroadphasePair* findPair(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1); + + + void cleanProxyFromPairs(btBroadphaseProxy* proxy); + + void removeOverlappingPairsContainingProxy(btBroadphaseProxy* proxy); + + + inline bool needsBroadphaseCollision(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1) const + { + if (m_overlapFilterCallback) + return m_overlapFilterCallback->needBroadphaseCollision(proxy0,proxy1); + + bool collides = (proxy0->m_collisionFilterGroup & proxy1->m_collisionFilterMask) != 0; + collides = collides && (proxy1->m_collisionFilterGroup & proxy0->m_collisionFilterMask); + + return collides; + } + + + + virtual void refreshOverlappingPairs() =0; + + btBroadphasePair* getOverlappingPairArrayPtr() + { + return &m_overlappingPairArray[0]; + } + + const btBroadphasePair* getOverlappingPairArrayPtr() const + { + return &m_overlappingPairArray[0]; + } + + int getNumOverlappingPairs() const + { + return m_overlappingPairArray.size(); + } + + btOverlapFilterCallback* getOverlapFilterCallback() + { + return m_overlapFilterCallback; + } + + void setOverlapFilterCallback(btOverlapFilterCallback* callback) + { + m_overlapFilterCallback = callback; + } + +}; +#endif //OVERLAPPING_PAIR_CACHE_H + + diff --git a/extern/bullet2/src/BulletCollision/BroadphaseCollision/btSimpleBroadphase.cpp b/extern/bullet2/src/BulletCollision/BroadphaseCollision/btSimpleBroadphase.cpp new file mode 100644 index 00000000000..30bcbe0c5f1 --- /dev/null +++ b/extern/bullet2/src/BulletCollision/BroadphaseCollision/btSimpleBroadphase.cpp @@ -0,0 +1,222 @@ +/* +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 "btSimpleBroadphase.h" +#include +#include + +#include "LinearMath/btVector3.h" +#include "LinearMath/btTransform.h" +#include "LinearMath/btMatrix3x3.h" +#include + + +void btSimpleBroadphase::validate() +{ + for (int i=0;i=0;i--) + { + BP_Proxy* proxy = m_pProxies[i]; + destroyProxy(proxy); + } + */ +} + + +btBroadphaseProxy* btSimpleBroadphase::createProxy( const btVector3& min, const btVector3& max,int shapeType,void* userPtr ,short int collisionFilterGroup,short int collisionFilterMask) +{ + if (m_numProxies >= m_maxProxies) + { + assert(0); + return 0; //should never happen, but don't let the game crash ;-) + } + assert(min[0]<= max[0] && min[1]<= max[1] && min[2]<= max[2]); + + int freeIndex= m_freeProxies[m_firstFreeProxy]; + btSimpleBroadphaseProxy* proxy = new (&m_proxies[freeIndex])btSimpleBroadphaseProxy(min,max,shapeType,userPtr,collisionFilterGroup,collisionFilterMask); + m_firstFreeProxy++; + + btSimpleBroadphaseProxy* proxy1 = &m_proxies[0]; + + int index = int(proxy - proxy1); + btAssert(index == freeIndex); + + m_pProxies[m_numProxies] = proxy; + m_numProxies++; + //validate(); + + return proxy; +} + +class RemovingOverlapCallback : public btOverlapCallback +{ +protected: + virtual bool processOverlap(btBroadphasePair& pair) + { + (void)pair; + btAssert(0); + return false; + } +}; + +class RemovePairContainingProxy +{ + + btBroadphaseProxy* m_targetProxy; + public: + virtual ~RemovePairContainingProxy() + { + } +protected: + virtual bool processOverlap(btBroadphasePair& pair) + { + btSimpleBroadphaseProxy* proxy0 = static_cast(pair.m_pProxy0); + btSimpleBroadphaseProxy* proxy1 = static_cast(pair.m_pProxy1); + + return ((m_targetProxy == proxy0 || m_targetProxy == proxy1)); + }; +}; + +void btSimpleBroadphase::destroyProxy(btBroadphaseProxy* proxyOrg) +{ + + int i; + + btSimpleBroadphaseProxy* proxy0 = static_cast(proxyOrg); + btSimpleBroadphaseProxy* proxy1 = &m_proxies[0]; + + int index = int(proxy0 - proxy1); + btAssert (index < m_maxProxies); + m_freeProxies[--m_firstFreeProxy] = index; + + removeOverlappingPairsContainingProxy(proxyOrg); + + for (i=0;im_min = aabbMin; + sbp->m_max = aabbMax; +} + + + + + + + + + +bool btSimpleBroadphase::aabbOverlap(btSimpleBroadphaseProxy* proxy0,btSimpleBroadphaseProxy* proxy1) +{ + return proxy0->m_min[0] <= proxy1->m_max[0] && proxy1->m_min[0] <= proxy0->m_max[0] && + proxy0->m_min[1] <= proxy1->m_max[1] && proxy1->m_min[1] <= proxy0->m_max[1] && + proxy0->m_min[2] <= proxy1->m_max[2] && proxy1->m_min[2] <= proxy0->m_max[2]; + +} + + + +//then remove non-overlapping ones +class CheckOverlapCallback : public btOverlapCallback +{ +public: + virtual bool processOverlap(btBroadphasePair& pair) + { + return (!btSimpleBroadphase::aabbOverlap(static_cast(pair.m_pProxy0),static_cast(pair.m_pProxy1))); + } +}; + +void btSimpleBroadphase::refreshOverlappingPairs() +{ + //first check for new overlapping pairs + int i,j; + + for (i=0;i(proxy); + return proxy0; + } + + + void validate(); + +protected: + + + virtual void refreshOverlappingPairs(); +public: + btSimpleBroadphase(int maxProxies=16384); + virtual ~btSimpleBroadphase(); + + + static bool aabbOverlap(btSimpleBroadphaseProxy* proxy0,btSimpleBroadphaseProxy* proxy1); + + + virtual btBroadphaseProxy* createProxy( const btVector3& min, const btVector3& max,int shapeType,void* userPtr ,short int collisionFilterGroup,short int collisionFilterMask); + + + virtual void destroyProxy(btBroadphaseProxy* proxy); + virtual void setAabb(btBroadphaseProxy* proxy,const btVector3& aabbMin,const btVector3& aabbMax); + + + + + + +}; + + + +#endif //SIMPLE_BROADPHASE_H + diff --git a/extern/bullet2/src/BulletCollision/CMakeLists.txt b/extern/bullet2/src/BulletCollision/CMakeLists.txt new file mode 100644 index 00000000000..e565bf7edea --- /dev/null +++ b/extern/bullet2/src/BulletCollision/CMakeLists.txt @@ -0,0 +1,60 @@ + +INCLUDE_DIRECTORIES( +${BULLET_PHYSICS_SOURCE_DIR}/src } +) + +ADD_LIBRARY(LibBulletCollision + BroadphaseCollision/btAxisSweep3.cpp + BroadphaseCollision/btBroadphaseProxy.cpp + BroadphaseCollision/btCollisionAlgorithm.cpp + BroadphaseCollision/btDispatcher.cpp + BroadphaseCollision/btOverlappingPairCache.cpp + BroadphaseCollision/btSimpleBroadphase.cpp + CollisionDispatch/btCollisionDispatcher.cpp + CollisionDispatch/btCollisionObject.cpp + CollisionDispatch/btCollisionWorld.cpp + CollisionDispatch/btCompoundCollisionAlgorithm.cpp + CollisionDispatch/btConvexConcaveCollisionAlgorithm.cpp + CollisionDispatch/btSphereSphereCollisionAlgorithm.cpp + CollisionDispatch/btSphereBoxCollisionAlgorithm.cpp + CollisionDispatch/btConvexConvexAlgorithm.cpp + CollisionDispatch/btEmptyCollisionAlgorithm.cpp + CollisionDispatch/btManifoldResult.cpp + CollisionDispatch/btSimulationIslandManager.cpp + CollisionDispatch/btUnionFind.cpp + CollisionShapes/btBoxShape.cpp + CollisionShapes/btBvhTriangleMeshShape.cpp + CollisionShapes/btCollisionShape.cpp + CollisionShapes/btCompoundShape.cpp + CollisionShapes/btConcaveShape.cpp + CollisionShapes/btConeShape.cpp + CollisionShapes/btConvexHullShape.cpp + CollisionShapes/btConvexShape.cpp + CollisionShapes/btConvexTriangleMeshShape.cpp + CollisionShapes/btCylinderShape.cpp + CollisionShapes/btEmptyShape.cpp + CollisionShapes/btMinkowskiSumShape.cpp + CollisionShapes/btMultiSphereShape.cpp + CollisionShapes/btOptimizedBvh.cpp + CollisionShapes/btPolyhedralConvexShape.cpp + CollisionShapes/btTetrahedronShape.cpp + CollisionShapes/btSphereShape.cpp + CollisionShapes/btStaticPlaneShape.cpp + CollisionShapes/btStridingMeshInterface.cpp + CollisionShapes/btTriangleCallback.cpp + CollisionShapes/btTriangleBuffer.cpp + CollisionShapes/btTriangleIndexVertexArray.cpp + CollisionShapes/btTriangleMesh.cpp + CollisionShapes/btTriangleMeshShape.cpp + NarrowPhaseCollision/btContinuousConvexCollision.cpp + NarrowPhaseCollision/btGjkEpa.cpp + NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.cpp + NarrowPhaseCollision/btConvexCast.cpp + NarrowPhaseCollision/btGjkConvexCast.cpp + NarrowPhaseCollision/btGjkPairDetector.cpp + NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.cpp + NarrowPhaseCollision/btPersistentManifold.cpp + NarrowPhaseCollision/btRaycastCallback.cpp + NarrowPhaseCollision/btSubSimplexConvexCast.cpp + NarrowPhaseCollision/btVoronoiSimplexSolver.cpp +) diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/SphereTriangleDetector.cpp b/extern/bullet2/src/BulletCollision/CollisionDispatch/SphereTriangleDetector.cpp new file mode 100644 index 00000000000..81133670f0c --- /dev/null +++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/SphereTriangleDetector.cpp @@ -0,0 +1,200 @@ +/* +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 "LinearMath/btScalar.h" +#include "SphereTriangleDetector.h" +#include "BulletCollision/CollisionShapes/btTriangleShape.h" +#include "BulletCollision/CollisionShapes/btSphereShape.h" + + +SphereTriangleDetector::SphereTriangleDetector(btSphereShape* sphere,btTriangleShape* triangle) +:m_sphere(sphere), +m_triangle(triangle) +{ + +} + +void SphereTriangleDetector::getClosestPoints(const ClosestPointInput& input,Result& output,class btIDebugDraw* debugDraw) +{ + + (void)debugDraw; + const btTransform& transformA = input.m_transformA; + const btTransform& transformB = input.m_transformB; + + btVector3 point,normal; + btScalar timeOfImpact = btScalar(1.); + btScalar depth = btScalar(0.); +// output.m_distance = btScalar(1e30); + //move sphere into triangle space + btTransform sphereInTr = transformB.inverseTimes(transformA); + + if (collide(sphereInTr.getOrigin(),point,normal,depth,timeOfImpact)) + { + output.addContactPoint(transformB.getBasis()*normal,transformB*point,depth); + } + +} + +#define MAX_OVERLAP btScalar(0.) + + + +// See also geometrictools.com +// Basic idea: D = |p - (lo + t0*lv)| where t0 = lv . (p - lo) / lv . lv +btScalar SegmentSqrDistance(const btVector3& from, const btVector3& to,const btVector3 &p, btVector3 &nearest) { + btVector3 diff = p - from; + btVector3 v = to - from; + btScalar t = v.dot(diff); + + if (t > 0) { + btScalar dotVV = v.dot(v); + if (t < dotVV) { + t /= dotVV; + diff -= t*v; + } else { + t = 1; + diff -= v; + } + } else + t = 0; + + nearest = from + t*v; + return diff.dot(diff); +} + +bool SphereTriangleDetector::facecontains(const btVector3 &p,const btVector3* vertices,btVector3& normal) { + btVector3 lp(p); + btVector3 lnormal(normal); + + return pointInTriangle(vertices, lnormal, &lp); +} + +///combined discrete/continuous sphere-triangle +bool SphereTriangleDetector::collide(const btVector3& sphereCenter,btVector3 &point, btVector3& resultNormal, btScalar& depth, btScalar &timeOfImpact) +{ + + const btVector3* vertices = &m_triangle->getVertexPtr(0); + const btVector3& c = sphereCenter; + btScalar r = m_sphere->getRadius(); + + btVector3 delta (0,0,0); + + btVector3 normal = (vertices[1]-vertices[0]).cross(vertices[2]-vertices[0]); + normal.normalize(); + btVector3 p1ToCentre = c - vertices[0]; + btScalar distanceFromPlane = p1ToCentre.dot(normal); + + if (distanceFromPlane < btScalar(0.)) + { + //triangle facing the other way + + distanceFromPlane *= btScalar(-1.); + normal *= btScalar(-1.); + } + + ///todo: move this gContactBreakingThreshold into a proper structure + extern btScalar gContactBreakingThreshold; + + btScalar contactMargin = gContactBreakingThreshold; + bool isInsideContactPlane = distanceFromPlane < r + contactMargin; + bool isInsideShellPlane = distanceFromPlane < r; + + btScalar deltaDotNormal = delta.dot(normal); + if (!isInsideShellPlane && deltaDotNormal >= btScalar(0.0)) + return false; + + // Check for contact / intersection + bool hasContact = false; + btVector3 contactPoint; + if (isInsideContactPlane) { + if (facecontains(c,vertices,normal)) { + // Inside the contact wedge - touches a point on the shell plane + hasContact = true; + contactPoint = c - normal*distanceFromPlane; + } else { + // Could be inside one of the contact capsules + btScalar contactCapsuleRadiusSqr = (r + contactMargin) * (r + contactMargin); + btVector3 nearestOnEdge; + for (int i = 0; i < m_triangle->getNumEdges(); i++) { + + btPoint3 pa; + btPoint3 pb; + + m_triangle->getEdge(i,pa,pb); + + btScalar distanceSqr = SegmentSqrDistance(pa,pb,c, nearestOnEdge); + if (distanceSqr < contactCapsuleRadiusSqr) { + // Yep, we're inside a capsule + hasContact = true; + contactPoint = nearestOnEdge; + } + + } + } + } + + if (hasContact) { + btVector3 contactToCentre = c - contactPoint; + btScalar distanceSqr = contactToCentre.length2(); + if (distanceSqr < (r - MAX_OVERLAP)*(r - MAX_OVERLAP)) { + btScalar distance = btSqrt(distanceSqr); + resultNormal = contactToCentre; + resultNormal.normalize(); + point = contactPoint; + depth = -(r-distance); + return true; + } + + if (delta.dot(contactToCentre) >= btScalar(0.0)) + return false; + + // Moving towards the contact point -> collision + point = contactPoint; + timeOfImpact = btScalar(0.0); + return true; + } + + return false; +} + + +bool SphereTriangleDetector::pointInTriangle(const btVector3 vertices[], const btVector3 &normal, btVector3 *p ) +{ + const btVector3* p1 = &vertices[0]; + const btVector3* p2 = &vertices[1]; + const btVector3* p3 = &vertices[2]; + + btVector3 edge1( *p2 - *p1 ); + btVector3 edge2( *p3 - *p2 ); + btVector3 edge3( *p1 - *p3 ); + + btVector3 p1_to_p( *p - *p1 ); + btVector3 p2_to_p( *p - *p2 ); + btVector3 p3_to_p( *p - *p3 ); + + btVector3 edge1_normal( edge1.cross(normal)); + btVector3 edge2_normal( edge2.cross(normal)); + btVector3 edge3_normal( edge3.cross(normal)); + + btScalar r1, r2, r3; + r1 = edge1_normal.dot( p1_to_p ); + r2 = edge2_normal.dot( p2_to_p ); + r3 = edge3_normal.dot( p3_to_p ); + if ( ( r1 > 0 && r2 > 0 && r3 > 0 ) || + ( r1 <= 0 && r2 <= 0 && r3 <= 0 ) ) + return true; + return false; + +} diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/SphereTriangleDetector.h b/extern/bullet2/src/BulletCollision/CollisionDispatch/SphereTriangleDetector.h new file mode 100644 index 00000000000..b32806a6846 --- /dev/null +++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/SphereTriangleDetector.h @@ -0,0 +1,49 @@ +/* +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 SPHERE_TRIANGLE_DETECTOR_H +#define SPHERE_TRIANGLE_DETECTOR_H + +#include "../NarrowPhaseCollision/btDiscreteCollisionDetectorInterface.h" +#include "../../LinearMath/btPoint3.h" + + +class btSphereShape; +class btTriangleShape; + + + +/// sphere-triangle to match the btDiscreteCollisionDetectorInterface +struct SphereTriangleDetector : public btDiscreteCollisionDetectorInterface +{ + virtual void getClosestPoints(const ClosestPointInput& input,Result& output,class btIDebugDraw* debugDraw); + + SphereTriangleDetector(btSphereShape* sphere,btTriangleShape* triangle); + + virtual ~SphereTriangleDetector() {}; + +private: + + bool collide(const btVector3& sphereCenter,btVector3 &point, btVector3& resultNormal, btScalar& depth, btScalar &timeOfImpact); + bool pointInTriangle(const btVector3 vertices[], const btVector3 &normal, btVector3 *p ); + bool facecontains(const btVector3 &p,const btVector3* vertices,btVector3& normal); + + btSphereShape* m_sphere; + btTriangleShape* m_triangle; + + +}; +#endif //SPHERE_TRIANGLE_DETECTOR_H + diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionCreateFunc.h b/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionCreateFunc.h new file mode 100644 index 00000000000..d51a59af7f0 --- /dev/null +++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionCreateFunc.h @@ -0,0 +1,46 @@ +/* +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 COLLISION_CREATE_FUNC +#define COLLISION_CREATE_FUNC + +#include "../../LinearMath/btAlignedObjectArray.h" +typedef btAlignedObjectArray btCollisionObjectArray; +class btCollisionAlgorithm; +class btCollisionObject; + +struct btCollisionAlgorithmConstructionInfo; + +///Used by the btCollisionDispatcher to register and create instances for btCollisionAlgorithm +struct btCollisionAlgorithmCreateFunc +{ + bool m_swapped; + + btCollisionAlgorithmCreateFunc() + :m_swapped(false) + { + } + virtual ~btCollisionAlgorithmCreateFunc(){}; + + virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& , btCollisionObject* body0,btCollisionObject* body1) + { + + (void)body0; + (void)body1; + return 0; + } +}; +#endif //COLLISION_CREATE_FUNC + diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionDispatcher.cpp b/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionDispatcher.cpp new file mode 100644 index 00000000000..b535fac6563 --- /dev/null +++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionDispatcher.cpp @@ -0,0 +1,367 @@ +/* +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 "btCollisionDispatcher.h" + + +#include "BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h" +#include "BulletCollision/CollisionDispatch/btConvexConvexAlgorithm.h" +#include "BulletCollision/CollisionDispatch/btEmptyCollisionAlgorithm.h" +#include "BulletCollision/CollisionDispatch/btConvexConcaveCollisionAlgorithm.h" +#include "BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.h" +#include "BulletCollision/CollisionShapes/btCollisionShape.h" +#include "BulletCollision/CollisionDispatch/btCollisionObject.h" +#include "BulletCollision/BroadphaseCollision/btOverlappingPairCache.h" + +int gNumManifold = 0; + +#include + + +btCollisionDispatcher::btCollisionDispatcher(bool noDefaultAlgorithms): +m_count(0), +m_useIslands(true), +m_convexConvexCreateFunc(0), +m_convexConcaveCreateFunc(0), +m_swappedConvexConcaveCreateFunc(0), +m_compoundCreateFunc(0), +m_swappedCompoundCreateFunc(0), +m_emptyCreateFunc(0) +{ + (void)noDefaultAlgorithms; + int i; + + setNearCallback(defaultNearCallback); + + m_emptyCreateFunc = new btEmptyAlgorithm::CreateFunc; + for (i=0;iclearManifold(); +} + + +void btCollisionDispatcher::releaseManifold(btPersistentManifold* manifold) +{ + + gNumManifold--; + + //printf("releaseManifold: gNumManifold %d\n",gNumManifold); + clearManifold(manifold); + + ///todo: this can be improved a lot, linear search might be slow part! + int findIndex = m_manifoldsPtr.findLinearSearch(manifold); + if (findIndex < m_manifoldsPtr.size()) + { + m_manifoldsPtr.swap(findIndex,m_manifoldsPtr.size()-1); + m_manifoldsPtr.pop_back(); + delete manifold; + } + +} + + + +btCollisionAlgorithm* btCollisionDispatcher::findAlgorithm(btCollisionObject* body0,btCollisionObject* body1,btPersistentManifold* sharedManifold) +{ + +#ifdef USE_DISPATCH_REGISTRY_ARRAY + + btCollisionAlgorithmConstructionInfo ci; + ci.m_dispatcher = this; + ci.m_manifold = sharedManifold; + btCollisionAlgorithm* algo = m_doubleDispatch[body0->getCollisionShape()->getShapeType()][body1->getCollisionShape()->getShapeType()] + ->CreateCollisionAlgorithm(ci,body0,body1); +#else + btCollisionAlgorithm* algo = internalFindAlgorithm(body0,body1); +#endif //USE_DISPATCH_REGISTRY_ARRAY + return algo; +} + + +#ifndef BT_EXCLUDE_DEFAULT_COLLISIONALGORITHM_REGISTRATION + +btCollisionAlgorithmCreateFunc* btCollisionDispatcher::internalFindCreateFunc(int proxyType0,int proxyType1) +{ + + if (btBroadphaseProxy::isConvex(proxyType0) && btBroadphaseProxy::isConvex(proxyType1)) + { + return m_convexConvexCreateFunc; + } + + if (btBroadphaseProxy::isConvex(proxyType0) && btBroadphaseProxy::isConcave(proxyType1)) + { + return m_convexConcaveCreateFunc; + } + + if (btBroadphaseProxy::isConvex(proxyType1) && btBroadphaseProxy::isConcave(proxyType0)) + { + return m_swappedConvexConcaveCreateFunc; + } + + if (btBroadphaseProxy::isCompound(proxyType0)) + { + return m_compoundCreateFunc; + } else + { + if (btBroadphaseProxy::isCompound(proxyType1)) + { + return m_swappedCompoundCreateFunc; + } + } + + //failed to find an algorithm + return m_emptyCreateFunc; +} + +#endif //BT_EXCLUDE_DEFAULT_COLLISIONALGORITHM_REGISTRATION + + +#ifndef USE_DISPATCH_REGISTRY_ARRAY + +btCollisionAlgorithm* btCollisionDispatcher::internalFindAlgorithm(btCollisionObject* body0,btCollisionObject* body1,btPersistentManifold* sharedManifold) +{ + m_count++; + + btCollisionAlgorithmConstructionInfo ci; + ci.m_dispatcher = this; + + if (body0->getCollisionShape()->isConvex() && body1->getCollisionShape()->isConvex() ) + { + return new btConvexConvexAlgorithm(sharedManifold,ci,body0,body1); + } + + if (body0->getCollisionShape()->isConvex() && body1->getCollisionShape()->isConcave()) + { + return new btConvexConcaveCollisionAlgorithm(ci,body0,body1,false); + } + + if (body1->getCollisionShape()->isConvex() && body0->getCollisionShape()->isConcave()) + { + return new btConvexConcaveCollisionAlgorithm(ci,body0,body1,true); + } + + if (body0->getCollisionShape()->isCompound()) + { + return new btCompoundCollisionAlgorithm(ci,body0,body1,false); + } else + { + if (body1->getCollisionShape()->isCompound()) + { + return new btCompoundCollisionAlgorithm(ci,body0,body1,true); + } + } + + //failed to find an algorithm + return new btEmptyAlgorithm(ci); + +} +#endif //USE_DISPATCH_REGISTRY_ARRAY + +bool btCollisionDispatcher::needsResponse(btCollisionObject* body0,btCollisionObject* body1) +{ + //here you can do filtering + bool hasResponse = + (body0->hasContactResponse() && body1->hasContactResponse()); + //no response between two static/kinematic bodies: + hasResponse = hasResponse && + ((!body0->isStaticOrKinematicObject()) ||(! body1->isStaticOrKinematicObject())); + return hasResponse; +} + +bool btCollisionDispatcher::needsCollision(btCollisionObject* body0,btCollisionObject* body1) +{ + assert(body0); + assert(body1); + + bool needsCollision = true; + + //broadphase filtering already deals with this + if ((body0->isStaticObject() || body0->isKinematicObject()) && + (body1->isStaticObject() || body1->isKinematicObject())) + { + printf("warning btCollisionDispatcher::needsCollision: static-static collision!\n"); + } + + if ((!body0->isActive()) && (!body1->isActive())) + needsCollision = false; + else if (!body0->checkCollideWith(body1)) + needsCollision = false; + + return needsCollision ; + +} + + + +///interface for iterating all overlapping collision pairs, no matter how those pairs are stored (array, set, map etc) +///this is useful for the collision dispatcher. +class btCollisionPairCallback : public btOverlapCallback +{ + btDispatcherInfo& m_dispatchInfo; + btCollisionDispatcher* m_dispatcher; + +public: + + btCollisionPairCallback(btDispatcherInfo& dispatchInfo,btCollisionDispatcher* dispatcher) + :m_dispatchInfo(dispatchInfo), + m_dispatcher(dispatcher) + { + } + + btCollisionPairCallback& operator=(btCollisionPairCallback& other) + { + m_dispatchInfo = other.m_dispatchInfo; + m_dispatcher = other.m_dispatcher; + return *this; + } + + virtual ~btCollisionPairCallback() {} + + + virtual bool processOverlap(btBroadphasePair& pair) + { + (*m_dispatcher->getNearCallback())(pair,*m_dispatcher,m_dispatchInfo); + + return false; + } +}; + + +void btCollisionDispatcher::dispatchAllCollisionPairs(btOverlappingPairCache* pairCache,btDispatcherInfo& dispatchInfo) +{ + //m_blockedForChanges = true; + + btCollisionPairCallback collisionCallback(dispatchInfo,this); + + pairCache->processAllOverlappingPairs(&collisionCallback); + + //m_blockedForChanges = false; + +} + + + + +//by default, Bullet will use this near callback +void btCollisionDispatcher::defaultNearCallback(btBroadphasePair& collisionPair, btCollisionDispatcher& dispatcher, btDispatcherInfo& dispatchInfo) +{ + btCollisionObject* colObj0 = (btCollisionObject*)collisionPair.m_pProxy0->m_clientObject; + btCollisionObject* colObj1 = (btCollisionObject*)collisionPair.m_pProxy1->m_clientObject; + + if (dispatcher.needsCollision(colObj0,colObj1)) + { + //dispatcher will keep algorithms persistent in the collision pair + if (!collisionPair.m_algorithm) + { + collisionPair.m_algorithm = dispatcher.findAlgorithm(colObj0,colObj1); + } + + if (collisionPair.m_algorithm) + { + btManifoldResult contactPointResult(colObj0,colObj1); + + if (dispatchInfo.m_dispatchFunc == btDispatcherInfo::DISPATCH_DISCRETE) + { + //discrete collision detection query + collisionPair.m_algorithm->processCollision(colObj0,colObj1,dispatchInfo,&contactPointResult); + } else + { + //continuous collision detection query, time of impact (toi) + btScalar toi = collisionPair.m_algorithm->calculateTimeOfImpact(colObj0,colObj1,dispatchInfo,&contactPointResult); + if (dispatchInfo.m_timeOfImpact > toi) + dispatchInfo.m_timeOfImpact = toi; + + } + } + } + +} diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionDispatcher.h b/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionDispatcher.h new file mode 100644 index 00000000000..ca5aba8f01c --- /dev/null +++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionDispatcher.h @@ -0,0 +1,135 @@ +/* +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 COLLISION__DISPATCHER_H +#define COLLISION__DISPATCHER_H + +#include "../BroadphaseCollision/btDispatcher.h" +#include "../NarrowPhaseCollision/btPersistentManifold.h" + +#include "../CollisionDispatch/btManifoldResult.h" + +#include "../BroadphaseCollision/btBroadphaseProxy.h" +#include "../../LinearMath/btAlignedObjectArray.h" + +class btIDebugDraw; +class btOverlappingPairCache; + + +#include "btCollisionCreateFunc.h" + +#define USE_DISPATCH_REGISTRY_ARRAY 1 + +class btCollisionDispatcher; +///user can override this nearcallback for collision filtering and more finegrained control over collision detection +typedef void (*btNearCallback)(btBroadphasePair& collisionPair, btCollisionDispatcher& dispatcher, btDispatcherInfo& dispatchInfo); + + +///btCollisionDispatcher supports algorithms that handle ConvexConvex and ConvexConcave collision pairs. +///Time of Impact, Closest Points and Penetration Depth. +class btCollisionDispatcher : public btDispatcher +{ + int m_count; + + btAlignedObjectArray m_manifoldsPtr; + + bool m_useIslands; + + btManifoldResult m_defaultManifoldResult; + + btNearCallback m_nearCallback; + + btCollisionAlgorithmCreateFunc* m_doubleDispatch[MAX_BROADPHASE_COLLISION_TYPES][MAX_BROADPHASE_COLLISION_TYPES]; + + btCollisionAlgorithmCreateFunc* internalFindCreateFunc(int proxyType0,int proxyType1); + + //default CreationFunctions, filling the m_doubleDispatch table + btCollisionAlgorithmCreateFunc* m_convexConvexCreateFunc; + btCollisionAlgorithmCreateFunc* m_convexConcaveCreateFunc; + btCollisionAlgorithmCreateFunc* m_swappedConvexConcaveCreateFunc; + btCollisionAlgorithmCreateFunc* m_compoundCreateFunc; + btCollisionAlgorithmCreateFunc* m_swappedCompoundCreateFunc; + btCollisionAlgorithmCreateFunc* m_emptyCreateFunc; + +#ifndef USE_DISPATCH_REGISTRY_ARRAY + btCollisionAlgorithm* internalFindAlgorithm(btCollisionObject* body0,btCollisionObject* body1,btPersistentManifold* sharedManifold = 0); +#endif //USE_DISPATCH_REGISTRY_ARRAY + +public: + + ///registerCollisionCreateFunc allows registration of custom/alternative collision create functions + void registerCollisionCreateFunc(int proxyType0,int proxyType1, btCollisionAlgorithmCreateFunc* createFunc); + + int getNumManifolds() const + { + return int( m_manifoldsPtr.size()); + } + + btPersistentManifold** getInternalManifoldPointer() + { + return &m_manifoldsPtr[0]; + } + + btPersistentManifold* getManifoldByIndexInternal(int index) + { + return m_manifoldsPtr[index]; + } + + const btPersistentManifold* getManifoldByIndexInternal(int index) const + { + return m_manifoldsPtr[index]; + } + + ///the default constructor creates/register default collision algorithms, for convex, compound and concave shape support + btCollisionDispatcher (); + + ///a special constructor that doesn't create/register the default collision algorithms + btCollisionDispatcher(bool noDefaultAlgorithms); + + virtual ~btCollisionDispatcher(); + + virtual btPersistentManifold* getNewManifold(void* b0,void* b1); + + virtual void releaseManifold(btPersistentManifold* manifold); + + + virtual void clearManifold(btPersistentManifold* manifold); + + + btCollisionAlgorithm* findAlgorithm(btCollisionObject* body0,btCollisionObject* body1,btPersistentManifold* sharedManifold = 0); + + virtual bool needsCollision(btCollisionObject* body0,btCollisionObject* body1); + + virtual bool needsResponse(btCollisionObject* body0,btCollisionObject* body1); + + virtual void dispatchAllCollisionPairs(btOverlappingPairCache* pairCache,btDispatcherInfo& dispatchInfo); + + void setNearCallback(btNearCallback nearCallback) + { + m_nearCallback = nearCallback; + } + + btNearCallback getNearCallback() const + { + return m_nearCallback; + } + + //by default, Bullet will use this near callback + static void defaultNearCallback(btBroadphasePair& collisionPair, btCollisionDispatcher& dispatcher, btDispatcherInfo& dispatchInfo); + +}; + +#endif //COLLISION__DISPATCHER_H + diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionObject.cpp b/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionObject.cpp new file mode 100644 index 00000000000..d4c0a4e8cb3 --- /dev/null +++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionObject.cpp @@ -0,0 +1,57 @@ +/* +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 "btCollisionObject.h" + +btCollisionObject::btCollisionObject() + : m_broadphaseHandle(0), + m_collisionShape(0), + m_collisionFlags(0), + m_activationState1(1), + m_deactivationTime(btScalar(0.)), + m_userObjectPointer(0), + m_hitFraction(btScalar(1.)), + m_ccdSweptSphereRadius(btScalar(0.)), + m_ccdSquareMotionThreshold(btScalar(0.)), + m_checkCollideWith(false) +{ + +} + +btCollisionObject::~btCollisionObject() +{ +} + +void btCollisionObject::setActivationState(int newState) +{ + if ( (m_activationState1 != DISABLE_DEACTIVATION) && (m_activationState1 != DISABLE_SIMULATION)) + m_activationState1 = newState; +} + +void btCollisionObject::forceActivationState(int newState) +{ + m_activationState1 = newState; +} + +void btCollisionObject::activate(bool forceActivation) +{ + if (forceActivation || !(m_collisionFlags & (CF_STATIC_OBJECT|CF_KINEMATIC_OBJECT))) + { + setActivationState(ACTIVE_TAG); + m_deactivationTime = btScalar(0.); + } +} + + diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionObject.h b/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionObject.h new file mode 100644 index 00000000000..9fb6a67c4a3 --- /dev/null +++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionObject.h @@ -0,0 +1,346 @@ +/* +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 COLLISION_OBJECT_H +#define COLLISION_OBJECT_H + +#include "../../LinearMath/btTransform.h" + +//island management, m_activationState1 +#define ACTIVE_TAG 1 +#define ISLAND_SLEEPING 2 +#define WANTS_DEACTIVATION 3 +#define DISABLE_DEACTIVATION 4 +#define DISABLE_SIMULATION 5 + +struct btBroadphaseProxy; +class btCollisionShape; +#include "../../LinearMath/btMotionState.h" + + + +/// btCollisionObject can be used to manage collision detection objects. +/// btCollisionObject maintains all information that is needed for a collision detection: Shape, Transform and AABB proxy. +/// They can be added to the btCollisionWorld. +ATTRIBUTE_ALIGNED16(class) btCollisionObject +{ + +protected: + + btTransform m_worldTransform; + + ///m_interpolationWorldTransform is used for CCD and interpolation + ///it can be either previous or future (predicted) transform + btTransform m_interpolationWorldTransform; + //those two are experimental: just added for bullet time effect, so you can still apply impulses (directly modifying velocities) + //without destroying the continuous interpolated motion (which uses this interpolation velocities) + btVector3 m_interpolationLinearVelocity; + btVector3 m_interpolationAngularVelocity; + btBroadphaseProxy* m_broadphaseHandle; + btCollisionShape* m_collisionShape; + + int m_collisionFlags; + + int m_islandTag1; + int m_companionId; + + int m_activationState1; + btScalar m_deactivationTime; + + btScalar m_friction; + btScalar m_restitution; + + ///users can point to their objects, m_userPointer is not used by Bullet, see setUserPointer/getUserPointer + void* m_userObjectPointer; + + ///m_internalOwner is reserved to point to Bullet's btRigidBody. Don't use this, use m_userObjectPointer instead. + void* m_internalOwner; + + ///time of impact calculation + btScalar m_hitFraction; + + ///Swept sphere radius (0.0 by default), see btConvexConvexAlgorithm:: + btScalar m_ccdSweptSphereRadius; + + /// Don't do continuous collision detection if square motion (in one step) is less then m_ccdSquareMotionThreshold + btScalar m_ccdSquareMotionThreshold; + + /// If some object should have elaborate collision filtering by sub-classes + bool m_checkCollideWith; + + char m_pad[7]; + + virtual bool checkCollideWithOverride(btCollisionObject* co) + { + return true; + } + +public: + + enum CollisionFlags + { + CF_STATIC_OBJECT= 1, + CF_KINEMATIC_OBJECT= 2, + CF_NO_CONTACT_RESPONSE = 4, + CF_CUSTOM_MATERIAL_CALLBACK = 8//this allows per-triangle material (friction/restitution) + }; + + + inline bool mergesSimulationIslands() const + { + ///static objects, kinematic and object without contact response don't merge islands + return ((m_collisionFlags & (CF_STATIC_OBJECT | CF_KINEMATIC_OBJECT | CF_NO_CONTACT_RESPONSE) )==0); + } + + + inline bool isStaticObject() const { + return (m_collisionFlags & CF_STATIC_OBJECT) != 0; + } + + inline bool isKinematicObject() const + { + return (m_collisionFlags & CF_KINEMATIC_OBJECT) != 0; + } + + inline bool isStaticOrKinematicObject() const + { + return (m_collisionFlags & (CF_KINEMATIC_OBJECT | CF_STATIC_OBJECT)) != 0 ; + } + + inline bool hasContactResponse() const { + return (m_collisionFlags & CF_NO_CONTACT_RESPONSE)==0; + } + + + btCollisionObject(); + + virtual ~btCollisionObject(); + + void setCollisionShape(btCollisionShape* collisionShape) + { + m_collisionShape = collisionShape; + } + + const btCollisionShape* getCollisionShape() const + { + return m_collisionShape; + } + + btCollisionShape* getCollisionShape() + { + return m_collisionShape; + } + + + + + int getActivationState() const { return m_activationState1;} + + void setActivationState(int newState); + + void setDeactivationTime(btScalar time) + { + m_deactivationTime = time; + } + btScalar getDeactivationTime() const + { + return m_deactivationTime; + } + + void forceActivationState(int newState); + + void activate(bool forceActivation = false); + + inline bool isActive() const + { + return ((getActivationState() != ISLAND_SLEEPING) && (getActivationState() != DISABLE_SIMULATION)); + } + + void setRestitution(btScalar rest) + { + m_restitution = rest; + } + btScalar getRestitution() const + { + return m_restitution; + } + void setFriction(btScalar frict) + { + m_friction = frict; + } + btScalar getFriction() const + { + return m_friction; + } + + ///reserved for Bullet internal usage + void* getInternalOwner() + { + return m_internalOwner; + } + + const void* getInternalOwner() const + { + return m_internalOwner; + } + + btTransform& getWorldTransform() + { + return m_worldTransform; + } + + const btTransform& getWorldTransform() const + { + return m_worldTransform; + } + + void setWorldTransform(const btTransform& worldTrans) + { + m_worldTransform = worldTrans; + } + + + btBroadphaseProxy* getBroadphaseHandle() + { + return m_broadphaseHandle; + } + + const btBroadphaseProxy* getBroadphaseHandle() const + { + return m_broadphaseHandle; + } + + void setBroadphaseHandle(btBroadphaseProxy* handle) + { + m_broadphaseHandle = handle; + } + + + const btTransform& getInterpolationWorldTransform() const + { + return m_interpolationWorldTransform; + } + + btTransform& getInterpolationWorldTransform() + { + return m_interpolationWorldTransform; + } + + void setInterpolationWorldTransform(const btTransform& trans) + { + m_interpolationWorldTransform = trans; + } + + + const btVector3& getInterpolationLinearVelocity() const + { + return m_interpolationLinearVelocity; + } + + const btVector3& getInterpolationAngularVelocity() const + { + return m_interpolationAngularVelocity; + } + + const int getIslandTag() const + { + return m_islandTag1; + } + + void setIslandTag(int tag) + { + m_islandTag1 = tag; + } + + const int getCompanionId() const + { + return m_companionId; + } + + void setCompanionId(int id) + { + m_companionId = id; + } + + const btScalar getHitFraction() const + { + return m_hitFraction; + } + + void setHitFraction(btScalar hitFraction) + { + m_hitFraction = hitFraction; + } + + + const int getCollisionFlags() const + { + return m_collisionFlags; + } + + void setCollisionFlags(int flags) + { + m_collisionFlags = flags; + } + + ///Swept sphere radius (0.0 by default), see btConvexConvexAlgorithm:: + btScalar getCcdSweptSphereRadius() const + { + return m_ccdSweptSphereRadius; + } + + ///Swept sphere radius (0.0 by default), see btConvexConvexAlgorithm:: + void setCcdSweptSphereRadius(btScalar radius) + { + m_ccdSweptSphereRadius = radius; + } + + btScalar getCcdSquareMotionThreshold() const + { + return m_ccdSquareMotionThreshold; + } + + + /// Don't do continuous collision detection if square motion (in one step) is less then m_ccdSquareMotionThreshold + void setCcdSquareMotionThreshold(btScalar ccdSquareMotionThreshold) + { + m_ccdSquareMotionThreshold = ccdSquareMotionThreshold; + } + + ///users can point to their objects, userPointer is not used by Bullet + void* getUserPointer() const + { + return m_userObjectPointer; + } + + ///users can point to their objects, userPointer is not used by Bullet + void setUserPointer(void* userPointer) + { + m_userObjectPointer = userPointer; + } + + inline bool checkCollideWith(btCollisionObject* co) + { + if (m_checkCollideWith) + return checkCollideWithOverride(co); + + return true; + } + + +} +; + +#endif //COLLISION_OBJECT_H diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionWorld.cpp b/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionWorld.cpp new file mode 100644 index 00000000000..b49036a5b50 --- /dev/null +++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionWorld.cpp @@ -0,0 +1,362 @@ +/* +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 "btCollisionWorld.h" +#include "btCollisionDispatcher.h" +#include "BulletCollision/CollisionDispatch/btCollisionObject.h" +#include "BulletCollision/CollisionShapes/btCollisionShape.h" +#include "BulletCollision/CollisionShapes/btConvexShape.h" + +#include "BulletCollision/CollisionShapes/btSphereShape.h" //for raycasting +#include "BulletCollision/CollisionShapes/btTriangleMeshShape.h" //for raycasting +#include "BulletCollision/NarrowPhaseCollision/btRaycastCallback.h" +#include "BulletCollision/CollisionShapes/btCompoundShape.h" +#include "BulletCollision/NarrowPhaseCollision/btSubSimplexConvexCast.h" +#include "BulletCollision/BroadphaseCollision/btBroadphaseInterface.h" +#include "LinearMath/btAabbUtil2.h" +#include "LinearMath/btQuickprof.h" +#include "LinearMath/btStackAlloc.h" + +//When the user doesn't provide dispatcher or broadphase, create basic versions (and delete them in destructor) +#include "BulletCollision/CollisionDispatch/btCollisionDispatcher.h" +#include "BulletCollision/BroadphaseCollision/btSimpleBroadphase.h" + + +btCollisionWorld::btCollisionWorld(btDispatcher* dispatcher,btOverlappingPairCache* pairCache, int stackSize) +:m_dispatcher1(dispatcher), +m_broadphasePairCache(pairCache), +m_ownsDispatcher(false), +m_ownsBroadphasePairCache(false) +{ + m_stackAlloc = new btStackAlloc(stackSize); + m_dispatchInfo.m_stackAllocator = m_stackAlloc; +} + + +btCollisionWorld::~btCollisionWorld() +{ + m_stackAlloc->destroy(); + delete m_stackAlloc; + + //clean up remaining objects + int i; + for (i=0;igetBroadphaseHandle(); + if (bp) + { + // + // only clear the cached algorithms + // + getBroadphase()->cleanProxyFromPairs(bp); + getBroadphase()->destroyProxy(bp); + } + } + + if (m_ownsDispatcher) + delete m_dispatcher1; + if (m_ownsBroadphasePairCache) + delete m_broadphasePairCache; + +} + + + + + + + + + + +void btCollisionWorld::addCollisionObject(btCollisionObject* collisionObject,short int collisionFilterGroup,short int collisionFilterMask) +{ + + //check that the object isn't already added + btAssert( m_collisionObjects.findLinearSearch(collisionObject) == m_collisionObjects.size()); + + m_collisionObjects.push_back(collisionObject); + + //calculate new AABB + btTransform trans = collisionObject->getWorldTransform(); + + btVector3 minAabb; + btVector3 maxAabb; + collisionObject->getCollisionShape()->getAabb(trans,minAabb,maxAabb); + + int type = collisionObject->getCollisionShape()->getShapeType(); + collisionObject->setBroadphaseHandle( getBroadphase()->createProxy( + minAabb, + maxAabb, + type, + collisionObject, + collisionFilterGroup, + collisionFilterMask + )) ; + + + + + +} + + + + +void btCollisionWorld::performDiscreteCollisionDetection() +{ + btDispatcherInfo& dispatchInfo = getDispatchInfo(); + + BEGIN_PROFILE("perform Broadphase Collision Detection"); + + + //update aabb (of all moved objects) + + btVector3 aabbMin,aabbMax; + for (int i=0;igetCollisionShape()->getAabb(m_collisionObjects[i]->getWorldTransform(),aabbMin,aabbMax); + m_broadphasePairCache->setAabb(m_collisionObjects[i]->getBroadphaseHandle(),aabbMin,aabbMax); + } + + m_broadphasePairCache->refreshOverlappingPairs(); + + + END_PROFILE("perform Broadphase Collision Detection"); + + BEGIN_PROFILE("performDiscreteCollisionDetection"); + + btDispatcher* dispatcher = getDispatcher(); + if (dispatcher) + dispatcher->dispatchAllCollisionPairs(m_broadphasePairCache,dispatchInfo); + + END_PROFILE("performDiscreteCollisionDetection"); + +} + + +void btCollisionWorld::removeCollisionObject(btCollisionObject* collisionObject) +{ + + + //bool removeFromBroadphase = false; + + { + + btBroadphaseProxy* bp = collisionObject->getBroadphaseHandle(); + if (bp) + { + // + // only clear the cached algorithms + // + getBroadphase()->cleanProxyFromPairs(bp); + getBroadphase()->destroyProxy(bp); + collisionObject->setBroadphaseHandle(0); + } + } + + + //swapremove + m_collisionObjects.remove(collisionObject); + +} + + + +void btCollisionWorld::rayTestSingle(const btTransform& rayFromTrans,const btTransform& rayToTrans, + btCollisionObject* collisionObject, + const btCollisionShape* collisionShape, + const btTransform& colObjWorldTransform, + RayResultCallback& resultCallback,short int collisionFilterMask) +{ + + btSphereShape pointShape(btScalar(0.0)); + pointShape.setMargin(0.f); + + objectQuerySingle(&pointShape,rayFromTrans,rayToTrans, + collisionObject, + collisionShape, + colObjWorldTransform, + resultCallback,collisionFilterMask); +} + +void btCollisionWorld::objectQuerySingle(const btConvexShape* castShape,const btTransform& rayFromTrans,const btTransform& rayToTrans, + btCollisionObject* collisionObject, + const btCollisionShape* collisionShape, + const btTransform& colObjWorldTransform, + RayResultCallback& resultCallback,short int collisionFilterMask) +{ + + + if (collisionShape->isConvex()) + { + btConvexCast::CastResult castResult; + castResult.m_fraction = btScalar(1.);//?? + + btConvexShape* convexShape = (btConvexShape*) collisionShape; + btVoronoiSimplexSolver simplexSolver; + btSubsimplexConvexCast convexCaster(castShape,convexShape,&simplexSolver); + //GjkConvexCast convexCaster(castShape,convexShape,&simplexSolver); + //ContinuousConvexCollision convexCaster(castShape,convexShape,&simplexSolver,0); + + if (convexCaster.calcTimeOfImpact(rayFromTrans,rayToTrans,colObjWorldTransform,colObjWorldTransform,castResult)) + { + //add hit + if (castResult.m_normal.length2() > btScalar(0.0001)) + { + castResult.m_normal.normalize(); + if (castResult.m_fraction < resultCallback.m_closestHitFraction) + { + + btCollisionWorld::LocalRayResult localRayResult + ( + collisionObject, + 0, + castResult.m_normal, + castResult.m_fraction + ); + + resultCallback.AddSingleResult(localRayResult); + + } + } + } + } + else + { + + if (collisionShape->isConcave()) + { + + btTriangleMeshShape* triangleMesh = (btTriangleMeshShape*)collisionShape; + + btTransform worldTocollisionObject = colObjWorldTransform.inverse(); + + btVector3 rayFromLocal = worldTocollisionObject * rayFromTrans.getOrigin(); + btVector3 rayToLocal = worldTocollisionObject * rayToTrans.getOrigin(); + + //ConvexCast::CastResult + + struct BridgeTriangleRaycastCallback : public btTriangleRaycastCallback + { + btCollisionWorld::RayResultCallback* m_resultCallback; + btCollisionObject* m_collisionObject; + btTriangleMeshShape* m_triangleMesh; + + BridgeTriangleRaycastCallback( const btVector3& from,const btVector3& to, + btCollisionWorld::RayResultCallback* resultCallback, btCollisionObject* collisionObject,btTriangleMeshShape* triangleMesh): + btTriangleRaycastCallback(from,to), + m_resultCallback(resultCallback), + m_collisionObject(collisionObject), + m_triangleMesh(triangleMesh) + { + } + + + virtual btScalar reportHit(const btVector3& hitNormalLocal, btScalar hitFraction, int partId, int triangleIndex ) + { + btCollisionWorld::LocalShapeInfo shapeInfo; + shapeInfo.m_shapePart = partId; + shapeInfo.m_triangleIndex = triangleIndex; + + btCollisionWorld::LocalRayResult rayResult + (m_collisionObject, + &shapeInfo, + hitNormalLocal, + hitFraction); + + return m_resultCallback->AddSingleResult(rayResult); + + + } + + }; + + + BridgeTriangleRaycastCallback rcb(rayFromLocal,rayToLocal,&resultCallback,collisionObject,triangleMesh); + rcb.m_hitFraction = resultCallback.m_closestHitFraction; + + btVector3 rayAabbMinLocal = rayFromLocal; + rayAabbMinLocal.setMin(rayToLocal); + btVector3 rayAabbMaxLocal = rayFromLocal; + rayAabbMaxLocal.setMax(rayToLocal); + + triangleMesh->processAllTriangles(&rcb,rayAabbMinLocal,rayAabbMaxLocal); + + } else + { + //todo: use AABB tree or other BVH acceleration structure! + if (collisionShape->isCompound()) + { + const btCompoundShape* compoundShape = static_cast(collisionShape); + int i=0; + for (i=0;igetNumChildShapes();i++) + { + btTransform childTrans = compoundShape->getChildTransform(i); + const btCollisionShape* childCollisionShape = compoundShape->getChildShape(i); + btTransform childWorldTrans = colObjWorldTransform * childTrans; + objectQuerySingle(castShape, rayFromTrans,rayToTrans, + collisionObject, + childCollisionShape, + childWorldTrans, + resultCallback, collisionFilterMask); + + } + + + } + } + } +} + +void btCollisionWorld::rayTest(const btVector3& rayFromWorld, const btVector3& rayToWorld, RayResultCallback& resultCallback,short int collisionFilterMask) +{ + + + btTransform rayFromTrans,rayToTrans; + rayFromTrans.setIdentity(); + rayFromTrans.setOrigin(rayFromWorld); + rayToTrans.setIdentity(); + + rayToTrans.setOrigin(rayToWorld); + + /// go over all objects, and if the ray intersects their aabb, do a ray-shape query using convexCaster (CCD) + + int i; + for (i=0;igetBroadphaseHandle()->m_collisionFilterGroup & collisionFilterMask) { + //RigidcollisionObject* collisionObject = ctrl->GetRigidcollisionObject(); + btVector3 collisionObjectAabbMin,collisionObjectAabbMax; + collisionObject->getCollisionShape()->getAabb(collisionObject->getWorldTransform(),collisionObjectAabbMin,collisionObjectAabbMax); + + btScalar hitLambda = btScalar(1.); //could use resultCallback.m_closestHitFraction, but needs testing + btVector3 hitNormal; + if (btRayAabb(rayFromWorld,rayToWorld,collisionObjectAabbMin,collisionObjectAabbMax,hitLambda,hitNormal)) + { + rayTestSingle(rayFromTrans,rayToTrans, + collisionObject, + collisionObject->getCollisionShape(), + collisionObject->getWorldTransform(), + resultCallback); + } + } + } + +} diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionWorld.h b/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionWorld.h new file mode 100644 index 00000000000..b6d80233ab7 --- /dev/null +++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionWorld.h @@ -0,0 +1,255 @@ +/* +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. +*/ + + +/** + * @mainpage Bullet Documentation + * + * @section intro_sec Introduction + * Bullet Collision Detection & Physics SDK + * + * Bullet is a Collision Detection and Rigid Body Dynamics Library. The Library is Open Source and free for commercial use, under the ZLib license ( http://opensource.org/licenses/zlib-license.php ). + * + * There is the Physics Forum for Feedback and bteral Collision Detection and Physics discussions. + * Please visit http://www.continuousphysics.com/Bullet/phpBB2/index.php + * + * @section install_sec Installation + * + * @subsection step1 Step 1: Download + * You can download the Bullet Physics Library from our website: http://www.continuousphysics.com/Bullet/ + * @subsection step2 Step 2: Building + * Bullet comes with autogenerated Project Files for Microsoft Visual Studio 6, 7, 7.1 and 8. + * The main Workspace/Solution is located in Bullet/msvc/8/wksbullet.sln (replace 8 with your version). + * + * Under other platforms, like Linux or Mac OS-X, Bullet can be build using either using cmake, http://www.cmake.org, or jam, http://www.perforce.com/jam/jam.html . cmake can autogenerate Xcode, KDevelop, MSVC and other build systems. just run cmake . in the root of Bullet. + * Jam is a build system that can build the library, demos and also autogenerate the MSVC Project Files. + * So if you are not using MSVC, you can run configure and jam . + * If you don't have jam installed, you can make jam from the included jam-2.5 sources, or download jam from ftp://ftp.perforce.com/pub/jam/ + * + * @subsection step3 Step 3: Testing demos + * Try to run and experiment with CcdPhysicsDemo executable as a starting point. + * Bullet can be used in several ways, as Full Rigid Body simulation, as Collision Detector Library or Low Level / Snippets like the GJK Closest Point calculation. + * The Dependencies can be seen in this documentation under Directories + * + * @subsection step4 Step 4: Integrating in your application, Full Rigid Body Simulation + * Check out CcdPhysicsDemo how to create a btDynamicsWorld, btRigidBody and btCollisionShape, Stepping the simulation and synchronizing your graphics object transform. + * PLEASE NOTE THE CcdPhysicsEnvironment and CcdPhysicsController is obsolete and will be removed. It has been replaced by classes derived frmo btDynamicsWorld and btRididBody + * @subsection step5 Step 5 : Integrate the Collision Detection Library (without Dynamics and other Extras) + * Bullet Collision Detection can also be used without the Dynamics/Extras. + * Check out btCollisionWorld and btCollisionObject, and the CollisionInterfaceDemo. Also in Extras/test_BulletOde.cpp there is a sample Collision Detection integration with Open Dynamics Engine, ODE, http://www.ode.org + * @subsection step6 Step 6 : Use Snippets like the GJK Closest Point calculation. + * Bullet has been designed in a modular way keeping dependencies to a minimum. The ConvexHullDistance demo demonstrates direct use of btGjkPairDetector. + * + * @section copyright Copyright + * Copyright (C) 2005-2007 Erwin Coumans, some contributions Copyright Gino van den Bergen, Christer Ericson, Simon Hobbs, Ricardo Padrela, F Richter(res), Stephane Redon + * Special thanks to all visitors of the Bullet Physics forum, and in particular above contributors, Dave Eberle, Dirk Gregorius, Erin Catto, Dave Eberle, Adam Moravanszky, + * Pierre Terdiman, Kenny Erleben, Russell Smith, Oliver Strunk, Jan Paul van Waveren, Marten Svanfeldt. + * + */ + + + +#ifndef COLLISION_WORLD_H +#define COLLISION_WORLD_H + +class btStackAlloc; +class btCollisionShape; +class btConvexShape; +class btBroadphaseInterface; +#include "../../LinearMath/btVector3.h" +#include "../../LinearMath/btTransform.h" +#include "btCollisionObject.h" +#include "btCollisionDispatcher.h" //for definition of btCollisionObjectArray +#include "../BroadphaseCollision/btOverlappingPairCache.h" +#include "../../LinearMath/btAlignedObjectArray.h" + +///CollisionWorld is interface and container for the collision detection +class btCollisionWorld +{ + + +protected: + + btAlignedObjectArray m_collisionObjects; + + btDispatcher* m_dispatcher1; + + btDispatcherInfo m_dispatchInfo; + + btStackAlloc* m_stackAlloc; + + btOverlappingPairCache* m_broadphasePairCache; + + bool m_ownsDispatcher; + bool m_ownsBroadphasePairCache; + +public: + + //this constructor doesn't own the dispatcher and paircache/broadphase + btCollisionWorld(btDispatcher* dispatcher,btOverlappingPairCache* pairCache, int stackSize = 2*1024*1024); + + virtual ~btCollisionWorld(); + + + btBroadphaseInterface* getBroadphase() + { + return m_broadphasePairCache; + } + + btOverlappingPairCache* getPairCache() + { + return m_broadphasePairCache; + } + + + btDispatcher* getDispatcher() + { + return m_dispatcher1; + } + + ///LocalShapeInfo gives extra information for complex shapes + ///Currently, only btTriangleMeshShape is available, so it just contains triangleIndex and subpart + struct LocalShapeInfo + { + int m_shapePart; + int m_triangleIndex; + + //const btCollisionShape* m_shapeTemp; + //const btTransform* m_shapeLocalTransform; + }; + + struct LocalRayResult + { + LocalRayResult(btCollisionObject* collisionObject, + LocalShapeInfo* localShapeInfo, + const btVector3& hitNormalLocal, + btScalar hitFraction) + :m_collisionObject(collisionObject), + m_localShapeInfo(localShapeInfo), + m_hitNormalLocal(hitNormalLocal), + m_hitFraction(hitFraction) + { + } + + btCollisionObject* m_collisionObject; + LocalShapeInfo* m_localShapeInfo; + btVector3 m_hitNormalLocal; + btScalar m_hitFraction; + + }; + + ///RayResultCallback is used to report new raycast results + struct RayResultCallback + { + virtual ~RayResultCallback() + { + } + btScalar m_closestHitFraction; + bool HasHit() + { + return (m_closestHitFraction < btScalar(1.)); + } + + RayResultCallback() + :m_closestHitFraction(btScalar(1.)) + { + } + virtual btScalar AddSingleResult(LocalRayResult& rayResult) = 0; + }; + + struct ClosestRayResultCallback : public RayResultCallback + { + ClosestRayResultCallback(const btVector3& rayFromWorld,const btVector3& rayToWorld) + :m_rayFromWorld(rayFromWorld), + m_rayToWorld(rayToWorld), + m_collisionObject(0) + { + } + + btVector3 m_rayFromWorld;//used to calculate hitPointWorld from hitFraction + btVector3 m_rayToWorld; + + btVector3 m_hitNormalWorld; + btVector3 m_hitPointWorld; + btCollisionObject* m_collisionObject; + + virtual btScalar AddSingleResult(LocalRayResult& rayResult) + { + +//caller already does the filter on the m_closestHitFraction + assert(rayResult.m_hitFraction <= m_closestHitFraction); + + m_closestHitFraction = rayResult.m_hitFraction; + m_collisionObject = rayResult.m_collisionObject; + m_hitNormalWorld = m_collisionObject->getWorldTransform().getBasis()*rayResult.m_hitNormalLocal; + m_hitPointWorld.setInterpolate3(m_rayFromWorld,m_rayToWorld,rayResult.m_hitFraction); + return rayResult.m_hitFraction; + } + }; + + + + + int getNumCollisionObjects() const + { + return int(m_collisionObjects.size()); + } + + /// rayTest performs a raycast on all objects in the btCollisionWorld, and calls the resultCallback + /// This allows for several queries: first hit, all hits, any hit, dependent on the value returned by the callback. + void rayTest(const btVector3& rayFromWorld, const btVector3& rayToWorld, RayResultCallback& resultCallback, short int collisionFilterMask=-1); + + /// rayTestSingle performs a raycast call and calls the resultCallback. It is used internally by rayTest. + /// In a future implementation, we consider moving the ray test as a virtual method in btCollisionShape. + /// This allows more customization. + static void rayTestSingle(const btTransform& rayFromTrans,const btTransform& rayToTrans, + btCollisionObject* collisionObject, + const btCollisionShape* collisionShape, + const btTransform& colObjWorldTransform, + RayResultCallback& resultCallback, short int collisionFilterMask=-1); + + /// objectQuerySingle performs a collision detection query and calls the resultCallback. It is used internally by rayTest. + static void objectQuerySingle(const btConvexShape* castShape, const btTransform& rayFromTrans,const btTransform& rayToTrans, + btCollisionObject* collisionObject, + const btCollisionShape* collisionShape, + const btTransform& colObjWorldTransform, + RayResultCallback& resultCallback, short int collisionFilterMask=-1); + + void addCollisionObject(btCollisionObject* collisionObject,short int collisionFilterGroup=1,short int collisionFilterMask=1); + + btCollisionObjectArray& getCollisionObjectArray() + { + return m_collisionObjects; + } + + const btCollisionObjectArray& getCollisionObjectArray() const + { + return m_collisionObjects; + } + + + void removeCollisionObject(btCollisionObject* collisionObject); + + virtual void performDiscreteCollisionDetection(); + + btDispatcherInfo& getDispatchInfo() + { + return m_dispatchInfo; + } + +}; + + +#endif //COLLISION_WORLD_H diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.cpp b/extern/bullet2/src/BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.cpp new file mode 100644 index 00000000000..92f4c8b28a6 --- /dev/null +++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.cpp @@ -0,0 +1,140 @@ +/* +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 "BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.h" +#include "BulletCollision/CollisionDispatch/btCollisionObject.h" +#include "BulletCollision/CollisionShapes/btCompoundShape.h" + + +btCompoundCollisionAlgorithm::btCompoundCollisionAlgorithm( const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* body0,btCollisionObject* body1,bool isSwapped) +:m_isSwapped(isSwapped) +{ + btCollisionObject* colObj = m_isSwapped? body1 : body0; + btCollisionObject* otherObj = m_isSwapped? body0 : body1; + assert (colObj->getCollisionShape()->isCompound()); + + btCompoundShape* compoundShape = static_cast(colObj->getCollisionShape()); + int numChildren = compoundShape->getNumChildShapes(); + int i; + + m_childCollisionAlgorithms.resize(numChildren); + for (i=0;igetChildShape(i); + btCollisionShape* orgShape = colObj->getCollisionShape(); + colObj->setCollisionShape( childShape ); + m_childCollisionAlgorithms[i] = ci.m_dispatcher->findAlgorithm(colObj,otherObj); + colObj->setCollisionShape( orgShape ); + } +} + + +btCompoundCollisionAlgorithm::~btCompoundCollisionAlgorithm() +{ + int numChildren = m_childCollisionAlgorithms.size(); + int i; + for (i=0;igetCollisionShape()->isCompound()); + btCompoundShape* compoundShape = static_cast(colObj->getCollisionShape()); + + //We will use the OptimizedBVH, AABB tree to cull potential child-overlaps + //If both proxies are Compound, we will deal with that directly, by performing sequential/parallel tree traversals + //given Proxy0 and Proxy1, if both have a tree, Tree0 and Tree1, this means: + //determine overlapping nodes of Proxy1 using Proxy0 AABB against Tree1 + //then use each overlapping node AABB against Tree0 + //and vise versa. + + int numChildren = m_childCollisionAlgorithms.size(); + int i; + for (i=0;igetChildShape(i); + + //backup + btTransform orgTrans = colObj->getWorldTransform(); + btCollisionShape* orgShape = colObj->getCollisionShape(); + + const btTransform& childTrans = compoundShape->getChildTransform(i); + //btTransform newChildWorldTrans = orgTrans*childTrans ; + colObj->setWorldTransform( orgTrans*childTrans ); + //the contactpoint is still projected back using the original inverted worldtrans + colObj->setCollisionShape( childShape ); + m_childCollisionAlgorithms[i]->processCollision(colObj,otherObj,dispatchInfo,resultOut); + //revert back + colObj->setCollisionShape( orgShape); + colObj->setWorldTransform( orgTrans ); + } +} + +btScalar btCompoundCollisionAlgorithm::calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut) +{ + + btCollisionObject* colObj = m_isSwapped? body1 : body0; + btCollisionObject* otherObj = m_isSwapped? body0 : body1; + + assert (colObj->getCollisionShape()->isCompound()); + + btCompoundShape* compoundShape = static_cast(colObj->getCollisionShape()); + + //We will use the OptimizedBVH, AABB tree to cull potential child-overlaps + //If both proxies are Compound, we will deal with that directly, by performing sequential/parallel tree traversals + //given Proxy0 and Proxy1, if both have a tree, Tree0 and Tree1, this means: + //determine overlapping nodes of Proxy1 using Proxy0 AABB against Tree1 + //then use each overlapping node AABB against Tree0 + //and vise versa. + + btScalar hitFraction = btScalar(1.); + + int numChildren = m_childCollisionAlgorithms.size(); + int i; + for (i=0;igetChildShape(i); + + //backup + btTransform orgTrans = colObj->getWorldTransform(); + btCollisionShape* orgShape = colObj->getCollisionShape(); + + const btTransform& childTrans = compoundShape->getChildTransform(i); + //btTransform newChildWorldTrans = orgTrans*childTrans ; + colObj->setWorldTransform( orgTrans*childTrans ); + + colObj->setCollisionShape( childShape ); + btScalar frac = m_childCollisionAlgorithms[i]->calculateTimeOfImpact(colObj,otherObj,dispatchInfo,resultOut); + if (fracsetCollisionShape( orgShape); + colObj->setWorldTransform( orgTrans); + } + return hitFraction; + +} + + diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.h b/extern/bullet2/src/BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.h new file mode 100644 index 00000000000..7091b233b46 --- /dev/null +++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.h @@ -0,0 +1,64 @@ +/* +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 COMPOUND_COLLISION_ALGORITHM_H +#define COMPOUND_COLLISION_ALGORITHM_H + +#include "../BroadphaseCollision/btCollisionAlgorithm.h" +#include "../BroadphaseCollision/btDispatcher.h" +#include "../BroadphaseCollision/btBroadphaseInterface.h" + +#include "../NarrowPhaseCollision/btPersistentManifold.h" +class btDispatcher; +#include "../BroadphaseCollision/btBroadphaseProxy.h" +#include "btCollisionCreateFunc.h" +#include "../../LinearMath/btAlignedObjectArray.h" + +/// btCompoundCollisionAlgorithm supports collision between CompoundCollisionShapes and other collision shapes +/// Place holder, not fully implemented yet +class btCompoundCollisionAlgorithm : public btCollisionAlgorithm +{ + btAlignedObjectArray m_childCollisionAlgorithms; + bool m_isSwapped; + +public: + + btCompoundCollisionAlgorithm( const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* body0,btCollisionObject* body1,bool isSwapped); + + virtual ~btCompoundCollisionAlgorithm(); + + virtual void processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut); + + btScalar calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut); + + struct CreateFunc :public btCollisionAlgorithmCreateFunc + { + virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, btCollisionObject* body0,btCollisionObject* body1) + { + return new btCompoundCollisionAlgorithm(ci,body0,body1,false); + } + }; + + struct SwappedCreateFunc :public btCollisionAlgorithmCreateFunc + { + virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, btCollisionObject* body0,btCollisionObject* body1) + { + return new btCompoundCollisionAlgorithm(ci,body0,body1,true); + } + }; + +}; + +#endif //COMPOUND_COLLISION_ALGORITHM_H diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btConvexConcaveCollisionAlgorithm.cpp b/extern/bullet2/src/BulletCollision/CollisionDispatch/btConvexConcaveCollisionAlgorithm.cpp new file mode 100644 index 00000000000..24ceacfd40d --- /dev/null +++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btConvexConcaveCollisionAlgorithm.cpp @@ -0,0 +1,312 @@ +/* +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 "btConvexConcaveCollisionAlgorithm.h" +#include "BulletCollision/CollisionDispatch/btCollisionObject.h" +#include "BulletCollision/CollisionShapes/btMultiSphereShape.h" +#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" +#include "BulletCollision/CollisionShapes/btConcaveShape.h" +#include "BulletCollision/CollisionDispatch/btManifoldResult.h" +#include "BulletCollision/NarrowPhaseCollision/btRaycastCallback.h" +#include "BulletCollision/CollisionShapes/btTriangleShape.h" +#include "BulletCollision/CollisionShapes/btSphereShape.h" +#include "LinearMath/btIDebugDraw.h" +#include "BulletCollision/NarrowPhaseCollision/btSubSimplexConvexCast.h" + +btConvexConcaveCollisionAlgorithm::btConvexConcaveCollisionAlgorithm( const btCollisionAlgorithmConstructionInfo& ci, btCollisionObject* body0,btCollisionObject* body1,bool isSwapped) +: btCollisionAlgorithm(ci), +m_isSwapped(isSwapped), +m_btConvexTriangleCallback(ci.m_dispatcher,body0,body1,isSwapped) +{ +} + +btConvexConcaveCollisionAlgorithm::~btConvexConcaveCollisionAlgorithm() +{ +} + + + +btConvexTriangleCallback::btConvexTriangleCallback(btDispatcher* dispatcher,btCollisionObject* body0,btCollisionObject* body1,bool isSwapped): + m_dispatcher(dispatcher), + m_dispatchInfoPtr(0) +{ + m_convexBody = isSwapped? body1:body0; + m_triBody = isSwapped? body0:body1; + + // + // create the manifold from the dispatcher 'manifold pool' + // + m_manifoldPtr = m_dispatcher->getNewManifold(m_convexBody,m_triBody); + + clearCache(); +} + +btConvexTriangleCallback::~btConvexTriangleCallback() +{ + clearCache(); + m_dispatcher->releaseManifold( m_manifoldPtr ); + +} + + +void btConvexTriangleCallback::clearCache() +{ + m_dispatcher->clearManifold(m_manifoldPtr); +}; + + + +void btConvexTriangleCallback::processTriangle(btVector3* triangle,int partId, int triangleIndex) +{ + + //just for debugging purposes + //printf("triangle %d",m_triangleCount++); + + + //aabb filter is already applied! + + btCollisionAlgorithmConstructionInfo ci; + ci.m_dispatcher = m_dispatcher; + + btCollisionObject* ob = static_cast(m_triBody); + + + + ///debug drawing of the overlapping triangles + if (m_dispatchInfoPtr && m_dispatchInfoPtr->m_debugDraw && m_dispatchInfoPtr->m_debugDraw->getDebugMode() > 0) + { + btVector3 color(255,255,0); + btTransform& tr = ob->getWorldTransform(); + m_dispatchInfoPtr->m_debugDraw->drawLine(tr(triangle[0]),tr(triangle[1]),color); + m_dispatchInfoPtr->m_debugDraw->drawLine(tr(triangle[1]),tr(triangle[2]),color); + m_dispatchInfoPtr->m_debugDraw->drawLine(tr(triangle[2]),tr(triangle[0]),color); + + //btVector3 center = triangle[0] + triangle[1]+triangle[2]; + //center *= btScalar(0.333333); + //m_dispatchInfoPtr->m_debugDraw->drawLine(tr(triangle[0]),tr(center),color); + //m_dispatchInfoPtr->m_debugDraw->drawLine(tr(triangle[1]),tr(center),color); + //m_dispatchInfoPtr->m_debugDraw->drawLine(tr(triangle[2]),tr(center),color); + + } + + + //btCollisionObject* colObj = static_cast(m_convexProxy->m_clientObject); + + if (m_convexBody->getCollisionShape()->isConvex()) + { + btTriangleShape tm(triangle[0],triangle[1],triangle[2]); + tm.setMargin(m_collisionMarginTriangle); + + + btCollisionShape* tmpShape = ob->getCollisionShape(); + ob->setCollisionShape( &tm ); + + + btCollisionAlgorithm* colAlgo = ci.m_dispatcher->findAlgorithm(m_convexBody,m_triBody,m_manifoldPtr); + ///this should use the btDispatcher, so the actual registered algorithm is used + // btConvexConvexAlgorithm cvxcvxalgo(m_manifoldPtr,ci,m_convexBody,m_triBody); + + m_resultOut->setShapeIdentifiers(-1,-1,partId,triangleIndex); + // cvxcvxalgo.setShapeIdentifiers(-1,-1,partId,triangleIndex); +// cvxcvxalgo.processCollision(m_convexBody,m_triBody,*m_dispatchInfoPtr,m_resultOut); + colAlgo->processCollision(m_convexBody,m_triBody,*m_dispatchInfoPtr,m_resultOut); + delete colAlgo; + ob->setCollisionShape( tmpShape ); + + } + + + +} + + + +void btConvexTriangleCallback::setTimeStepAndCounters(btScalar collisionMarginTriangle,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut) +{ + m_dispatchInfoPtr = &dispatchInfo; + m_collisionMarginTriangle = collisionMarginTriangle; + m_resultOut = resultOut; + + //recalc aabbs + btTransform convexInTriangleSpace; + convexInTriangleSpace = m_triBody->getWorldTransform().inverse() * m_convexBody->getWorldTransform(); + btCollisionShape* convexShape = static_cast(m_convexBody->getCollisionShape()); + //CollisionShape* triangleShape = static_cast(triBody->m_collisionShape); + convexShape->getAabb(convexInTriangleSpace,m_aabbMin,m_aabbMax); + btScalar extraMargin = collisionMarginTriangle; + btVector3 extra(extraMargin,extraMargin,extraMargin); + + m_aabbMax += extra; + m_aabbMin -= extra; + +} + +void btConvexConcaveCollisionAlgorithm::clearCache() +{ + m_btConvexTriangleCallback.clearCache(); + +} + +void btConvexConcaveCollisionAlgorithm::processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut) +{ + + + btCollisionObject* convexBody = m_isSwapped ? body1 : body0; + btCollisionObject* triBody = m_isSwapped ? body0 : body1; + + if (triBody->getCollisionShape()->isConcave()) + { + + + btCollisionObject* triOb = triBody; + btConcaveShape* concaveShape = static_cast( triOb->getCollisionShape()); + + if (convexBody->getCollisionShape()->isConvex()) + { + btScalar collisionMarginTriangle = concaveShape->getMargin(); + + resultOut->setPersistentManifold(m_btConvexTriangleCallback.m_manifoldPtr); + m_btConvexTriangleCallback.setTimeStepAndCounters(collisionMarginTriangle,dispatchInfo,resultOut); + + //Disable persistency. previously, some older algorithm calculated all contacts in one go, so you can clear it here. + //m_dispatcher->clearManifold(m_btConvexTriangleCallback.m_manifoldPtr); + + m_btConvexTriangleCallback.m_manifoldPtr->setBodies(convexBody,triBody); + + concaveShape->processAllTriangles( &m_btConvexTriangleCallback,m_btConvexTriangleCallback.getAabbMin(),m_btConvexTriangleCallback.getAabbMax()); + + + } + + } + +} + + +btScalar btConvexConcaveCollisionAlgorithm::calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut) +{ + (void)resultOut; + (void)dispatchInfo; + btCollisionObject* convexbody = m_isSwapped ? body1 : body0; + btCollisionObject* triBody = m_isSwapped ? body0 : body1; + + + //quick approximation using raycast, todo: hook up to the continuous collision detection (one of the btConvexCast) + + //only perform CCD above a certain threshold, this prevents blocking on the long run + //because object in a blocked ccd state (hitfraction<1) get their linear velocity halved each frame... + btScalar squareMot0 = (convexbody->getInterpolationWorldTransform().getOrigin() - convexbody->getWorldTransform().getOrigin()).length2(); + if (squareMot0 < convexbody->getCcdSquareMotionThreshold()) + { + return btScalar(1.); + } + + //const btVector3& from = convexbody->m_worldTransform.getOrigin(); + //btVector3 to = convexbody->m_interpolationWorldTransform.getOrigin(); + //todo: only do if the motion exceeds the 'radius' + + btTransform triInv = triBody->getWorldTransform().inverse(); + btTransform convexFromLocal = triInv * convexbody->getWorldTransform(); + btTransform convexToLocal = triInv * convexbody->getInterpolationWorldTransform(); + + struct LocalTriangleSphereCastCallback : public btTriangleCallback + { + btTransform m_ccdSphereFromTrans; + btTransform m_ccdSphereToTrans; + btTransform m_meshTransform; + + btScalar m_ccdSphereRadius; + btScalar m_hitFraction; + + + LocalTriangleSphereCastCallback(const btTransform& from,const btTransform& to,btScalar ccdSphereRadius,btScalar hitFraction) + :m_ccdSphereFromTrans(from), + m_ccdSphereToTrans(to), + m_ccdSphereRadius(ccdSphereRadius), + m_hitFraction(hitFraction) + { + } + + + virtual void processTriangle(btVector3* triangle, int partId, int triangleIndex) + { + (void)partId; + (void)triangleIndex; + //do a swept sphere for now + btTransform ident; + ident.setIdentity(); + btConvexCast::CastResult castResult; + castResult.m_fraction = m_hitFraction; + btSphereShape pointShape(m_ccdSphereRadius); + btTriangleShape triShape(triangle[0],triangle[1],triangle[2]); + btVoronoiSimplexSolver simplexSolver; + btSubsimplexConvexCast convexCaster(&pointShape,&triShape,&simplexSolver); + //GjkConvexCast convexCaster(&pointShape,convexShape,&simplexSolver); + //ContinuousConvexCollision convexCaster(&pointShape,convexShape,&simplexSolver,0); + //local space? + + if (convexCaster.calcTimeOfImpact(m_ccdSphereFromTrans,m_ccdSphereToTrans, + ident,ident,castResult)) + { + if (m_hitFraction > castResult.m_fraction) + m_hitFraction = castResult.m_fraction; + } + + } + + }; + + + + + + if (triBody->getCollisionShape()->isConcave()) + { + btVector3 rayAabbMin = convexFromLocal.getOrigin(); + rayAabbMin.setMin(convexToLocal.getOrigin()); + btVector3 rayAabbMax = convexFromLocal.getOrigin(); + rayAabbMax.setMax(convexToLocal.getOrigin()); + btScalar ccdRadius0 = convexbody->getCcdSweptSphereRadius(); + rayAabbMin -= btVector3(ccdRadius0,ccdRadius0,ccdRadius0); + rayAabbMax += btVector3(ccdRadius0,ccdRadius0,ccdRadius0); + + btScalar curHitFraction = btScalar(1.); //is this available? + LocalTriangleSphereCastCallback raycastCallback(convexFromLocal,convexToLocal, + convexbody->getCcdSweptSphereRadius(),curHitFraction); + + raycastCallback.m_hitFraction = convexbody->getHitFraction(); + + btCollisionObject* concavebody = triBody; + + btConcaveShape* triangleMesh = (btConcaveShape*) concavebody->getCollisionShape(); + + if (triangleMesh) + { + triangleMesh->processAllTriangles(&raycastCallback,rayAabbMin,rayAabbMax); + } + + + + if (raycastCallback.m_hitFraction < convexbody->getHitFraction()) + { + convexbody->setHitFraction( raycastCallback.m_hitFraction); + return raycastCallback.m_hitFraction; + } + } + + return btScalar(1.); + +} diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btConvexConcaveCollisionAlgorithm.h b/extern/bullet2/src/BulletCollision/CollisionDispatch/btConvexConcaveCollisionAlgorithm.h new file mode 100644 index 00000000000..4915b6c20c8 --- /dev/null +++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btConvexConcaveCollisionAlgorithm.h @@ -0,0 +1,111 @@ +/* +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 CONVEX_CONCAVE_COLLISION_ALGORITHM_H +#define CONVEX_CONCAVE_COLLISION_ALGORITHM_H + +#include "../BroadphaseCollision/btCollisionAlgorithm.h" +#include "../BroadphaseCollision/btDispatcher.h" +#include "../BroadphaseCollision/btBroadphaseInterface.h" +#include "../CollisionShapes/btTriangleCallback.h" +#include "../NarrowPhaseCollision/btPersistentManifold.h" +class btDispatcher; +#include "../BroadphaseCollision/btBroadphaseProxy.h" +#include "btCollisionCreateFunc.h" + +///For each triangle in the concave mesh that overlaps with the AABB of a convex (m_convexProxy), processTriangle is called. +class btConvexTriangleCallback : public btTriangleCallback +{ + btCollisionObject* m_convexBody; + btCollisionObject* m_triBody; + + btVector3 m_aabbMin; + btVector3 m_aabbMax ; + + btManifoldResult* m_resultOut; + + btDispatcher* m_dispatcher; + const btDispatcherInfo* m_dispatchInfoPtr; + btScalar m_collisionMarginTriangle; + +public: +int m_triangleCount; + + btPersistentManifold* m_manifoldPtr; + + btConvexTriangleCallback(btDispatcher* dispatcher,btCollisionObject* body0,btCollisionObject* body1,bool isSwapped); + + void setTimeStepAndCounters(btScalar collisionMarginTriangle,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut); + + virtual ~btConvexTriangleCallback(); + + virtual void processTriangle(btVector3* triangle, int partId, int triangleIndex); + + void clearCache(); + + inline const btVector3& getAabbMin() const + { + return m_aabbMin; + } + inline const btVector3& getAabbMax() const + { + return m_aabbMax; + } + +}; + + + + +/// btConvexConcaveCollisionAlgorithm supports collision between convex shapes and (concave) trianges meshes. +class btConvexConcaveCollisionAlgorithm : public btCollisionAlgorithm +{ + + bool m_isSwapped; + + btConvexTriangleCallback m_btConvexTriangleCallback; + + +public: + + btConvexConcaveCollisionAlgorithm( const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* body0,btCollisionObject* body1,bool isSwapped); + + virtual ~btConvexConcaveCollisionAlgorithm(); + + virtual void processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut); + + btScalar calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut); + + void clearCache(); + + struct CreateFunc :public btCollisionAlgorithmCreateFunc + { + virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, btCollisionObject* body0,btCollisionObject* body1) + { + return new btConvexConcaveCollisionAlgorithm(ci,body0,body1,false); + } + }; + + struct SwappedCreateFunc :public btCollisionAlgorithmCreateFunc + { + virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, btCollisionObject* body0,btCollisionObject* body1) + { + return new btConvexConcaveCollisionAlgorithm(ci,body0,body1,true); + } + }; + +}; + +#endif //CONVEX_CONCAVE_COLLISION_ALGORITHM_H diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btConvexConvexAlgorithm.cpp b/extern/bullet2/src/BulletCollision/CollisionDispatch/btConvexConvexAlgorithm.cpp new file mode 100644 index 00000000000..9105fe20b49 --- /dev/null +++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btConvexConvexAlgorithm.cpp @@ -0,0 +1,254 @@ +/* +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 "btConvexConvexAlgorithm.h" + +#include +#include "BulletCollision/NarrowPhaseCollision/btDiscreteCollisionDetectorInterface.h" +#include "BulletCollision/BroadphaseCollision/btBroadphaseInterface.h" +#include "BulletCollision/CollisionDispatch/btCollisionObject.h" +#include "BulletCollision/CollisionShapes/btConvexShape.h" +#include "BulletCollision/NarrowPhaseCollision/btGjkPairDetector.h" +#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" +#include "BulletCollision/CollisionDispatch/btCollisionDispatcher.h" +#include "BulletCollision/CollisionShapes/btBoxShape.h" +#include "BulletCollision/CollisionDispatch/btManifoldResult.h" + +#include "BulletCollision/NarrowPhaseCollision/btConvexPenetrationDepthSolver.h" +#include "BulletCollision/NarrowPhaseCollision/btContinuousConvexCollision.h" +#include "BulletCollision/NarrowPhaseCollision/btSubSimplexConvexCast.h" +#include "BulletCollision/NarrowPhaseCollision/btGjkConvexCast.h" + + + +#include "BulletCollision/CollisionShapes/btMinkowskiSumShape.h" +#include "BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.h" +#include "BulletCollision/CollisionShapes/btSphereShape.h" + +#include "BulletCollision/NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.h" + +#include "BulletCollision/NarrowPhaseCollision/btGjkEpa.h" +#include "BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.h" + + + + + + + +btConvexConvexAlgorithm::CreateFunc::CreateFunc() +{ + m_ownsSolvers = true; + m_simplexSolver = new btVoronoiSimplexSolver(); + m_pdSolver = new btGjkEpaPenetrationDepthSolver; +} + +btConvexConvexAlgorithm::CreateFunc::CreateFunc(btSimplexSolverInterface* simplexSolver, btConvexPenetrationDepthSolver* pdSolver) +{ + m_ownsSolvers = false; + m_simplexSolver = simplexSolver; + m_pdSolver = pdSolver; +} + +btConvexConvexAlgorithm::CreateFunc::~CreateFunc() +{ + if (m_ownsSolvers){ + delete m_simplexSolver; + delete m_pdSolver; + } +} + +btConvexConvexAlgorithm::btConvexConvexAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* body0,btCollisionObject* body1,btSimplexSolverInterface* simplexSolver, btConvexPenetrationDepthSolver* pdSolver) +: btCollisionAlgorithm(ci), +m_gjkPairDetector(0,0,simplexSolver,pdSolver), +m_ownManifold (false), +m_manifoldPtr(mf), +m_lowLevelOfDetail(false) +{ + (void)body0; + (void)body1; + + +} + + + + +btConvexConvexAlgorithm::~btConvexConvexAlgorithm() +{ + if (m_ownManifold) + { + if (m_manifoldPtr) + m_dispatcher->releaseManifold(m_manifoldPtr); + } +} + +void btConvexConvexAlgorithm ::setLowLevelOfDetail(bool useLowLevel) +{ + m_lowLevelOfDetail = useLowLevel; +} + + + + + +// +// Convex-Convex collision algorithm +// +void btConvexConvexAlgorithm ::processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut) +{ + + if (!m_manifoldPtr) + { + //swapped? + m_manifoldPtr = m_dispatcher->getNewManifold(body0,body1); + m_ownManifold = true; + } + resultOut->setPersistentManifold(m_manifoldPtr); + +#ifdef USE_BT_GJKEPA + btConvexShape* shape0(static_cast(body0->getCollisionShape())); + btConvexShape* shape1(static_cast(body1->getCollisionShape())); + const btScalar radialmargin(0/*shape0->getMargin()+shape1->getMargin()*/); + btGjkEpaSolver::sResults results; + if(btGjkEpaSolver::Collide( shape0,body0->getWorldTransform(), + shape1,body1->getWorldTransform(), + radialmargin,results)) + { + dispatchInfo.m_debugDraw->drawLine(results.witnesses[1],results.witnesses[1]+results.normal,btVector3(255,0,0)); + resultOut->addContactPoint(results.normal,results.witnesses[1],-results.depth); + } +#else + + btConvexShape* min0 = static_cast(body0->getCollisionShape()); + btConvexShape* min1 = static_cast(body1->getCollisionShape()); + + btGjkPairDetector::ClosestPointInput input; + + //TODO: if (dispatchInfo.m_useContinuous) + m_gjkPairDetector.setMinkowskiA(min0); + m_gjkPairDetector.setMinkowskiB(min1); + input.m_maximumDistanceSquared = min0->getMargin() + min1->getMargin() + m_manifoldPtr->getContactBreakingThreshold(); + input.m_maximumDistanceSquared*= input.m_maximumDistanceSquared; + input.m_stackAlloc = dispatchInfo.m_stackAllocator; + +// input.m_maximumDistanceSquared = btScalar(1e30); + + input.m_transformA = body0->getWorldTransform(); + input.m_transformB = body1->getWorldTransform(); + + m_gjkPairDetector.getClosestPoints(input,*resultOut,dispatchInfo.m_debugDraw); +#endif + +} + + + +bool disableCcd = false; +btScalar btConvexConvexAlgorithm::calculateTimeOfImpact(btCollisionObject* col0,btCollisionObject* col1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut) +{ + (void)resultOut; + (void)dispatchInfo; + ///Rather then checking ALL pairs, only calculate TOI when motion exceeds threshold + + ///Linear motion for one of objects needs to exceed m_ccdSquareMotionThreshold + ///col0->m_worldTransform, + btScalar resultFraction = btScalar(1.); + + + btScalar squareMot0 = (col0->getInterpolationWorldTransform().getOrigin() - col0->getWorldTransform().getOrigin()).length2(); + btScalar squareMot1 = (col1->getInterpolationWorldTransform().getOrigin() - col1->getWorldTransform().getOrigin()).length2(); + + if (squareMot0 < col0->getCcdSquareMotionThreshold() && + squareMot1 < col1->getCcdSquareMotionThreshold()) + return resultFraction; + + if (disableCcd) + return btScalar(1.); + + + //An adhoc way of testing the Continuous Collision Detection algorithms + //One object is approximated as a sphere, to simplify things + //Starting in penetration should report no time of impact + //For proper CCD, better accuracy and handling of 'allowed' penetration should be added + //also the mainloop of the physics should have a kind of toi queue (something like Brian Mirtich's application of Timewarp for Rigidbodies) + + + /// Convex0 against sphere for Convex1 + { + btConvexShape* convex0 = static_cast(col0->getCollisionShape()); + + btSphereShape sphere1(col1->getCcdSweptSphereRadius()); //todo: allow non-zero sphere sizes, for better approximation + btConvexCast::CastResult result; + btVoronoiSimplexSolver voronoiSimplex; + //SubsimplexConvexCast ccd0(&sphere,min0,&voronoiSimplex); + ///Simplification, one object is simplified as a sphere + btGjkConvexCast ccd1( convex0 ,&sphere1,&voronoiSimplex); + //ContinuousConvexCollision ccd(min0,min1,&voronoiSimplex,0); + if (ccd1.calcTimeOfImpact(col0->getWorldTransform(),col0->getInterpolationWorldTransform(), + col1->getWorldTransform(),col1->getInterpolationWorldTransform(),result)) + { + + //store result.m_fraction in both bodies + + if (col0->getHitFraction()> result.m_fraction) + col0->setHitFraction( result.m_fraction ); + + if (col1->getHitFraction() > result.m_fraction) + col1->setHitFraction( result.m_fraction); + + if (resultFraction > result.m_fraction) + resultFraction = result.m_fraction; + + } + + + + + } + + /// Sphere (for convex0) against Convex1 + { + btConvexShape* convex1 = static_cast(col1->getCollisionShape()); + + btSphereShape sphere0(col0->getCcdSweptSphereRadius()); //todo: allow non-zero sphere sizes, for better approximation + btConvexCast::CastResult result; + btVoronoiSimplexSolver voronoiSimplex; + //SubsimplexConvexCast ccd0(&sphere,min0,&voronoiSimplex); + ///Simplification, one object is simplified as a sphere + btGjkConvexCast ccd1(&sphere0,convex1,&voronoiSimplex); + //ContinuousConvexCollision ccd(min0,min1,&voronoiSimplex,0); + if (ccd1.calcTimeOfImpact(col0->getWorldTransform(),col0->getInterpolationWorldTransform(), + col1->getWorldTransform(),col1->getInterpolationWorldTransform(),result)) + { + + //store result.m_fraction in both bodies + + if (col0->getHitFraction() > result.m_fraction) + col0->setHitFraction( result.m_fraction); + + if (col1->getHitFraction() > result.m_fraction) + col1->setHitFraction( result.m_fraction); + + if (resultFraction > result.m_fraction) + resultFraction = result.m_fraction; + + } + } + + return resultFraction; + +} + diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btConvexConvexAlgorithm.h b/extern/bullet2/src/BulletCollision/CollisionDispatch/btConvexConvexAlgorithm.h new file mode 100644 index 00000000000..cbea9a92b75 --- /dev/null +++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btConvexConvexAlgorithm.h @@ -0,0 +1,76 @@ +/* +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 CONVEX_CONVEX_ALGORITHM_H +#define CONVEX_CONVEX_ALGORITHM_H + +#include "../BroadphaseCollision/btCollisionAlgorithm.h" +#include "../NarrowPhaseCollision/btGjkPairDetector.h" +#include "../NarrowPhaseCollision/btPersistentManifold.h" +#include "../BroadphaseCollision/btBroadphaseProxy.h" +#include "../NarrowPhaseCollision/btVoronoiSimplexSolver.h" +#include "btCollisionCreateFunc.h" + +class btConvexPenetrationDepthSolver; + +///ConvexConvexAlgorithm collision algorithm implements time of impact, convex closest points and penetration depth calculations. +class btConvexConvexAlgorithm : public btCollisionAlgorithm +{ + btGjkPairDetector m_gjkPairDetector; +public: + + bool m_ownManifold; + btPersistentManifold* m_manifoldPtr; + bool m_lowLevelOfDetail; + + +public: + + btConvexConvexAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* body0,btCollisionObject* body1, btSimplexSolverInterface* simplexSolver, btConvexPenetrationDepthSolver* pdSolver); + + virtual ~btConvexConvexAlgorithm(); + + virtual void processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut); + + virtual btScalar calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut); + + void setLowLevelOfDetail(bool useLowLevel); + + + const btPersistentManifold* getManifold() + { + return m_manifoldPtr; + } + + struct CreateFunc :public btCollisionAlgorithmCreateFunc + { + btConvexPenetrationDepthSolver* m_pdSolver; + btSimplexSolverInterface* m_simplexSolver; + bool m_ownsSolvers; + + CreateFunc(btSimplexSolverInterface* simplexSolver, btConvexPenetrationDepthSolver* pdSolver); + CreateFunc(); + virtual ~CreateFunc(); + + virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, btCollisionObject* body0,btCollisionObject* body1) + { + return new btConvexConvexAlgorithm(ci.m_manifold,ci,body0,body1,m_simplexSolver,m_pdSolver); + } + }; + + +}; + +#endif //CONVEX_CONVEX_ALGORITHM_H diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btEmptyCollisionAlgorithm.cpp b/extern/bullet2/src/BulletCollision/CollisionDispatch/btEmptyCollisionAlgorithm.cpp new file mode 100644 index 00000000000..936054387c4 --- /dev/null +++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btEmptyCollisionAlgorithm.cpp @@ -0,0 +1,34 @@ +/* +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 "btEmptyCollisionAlgorithm.h" + + + +btEmptyAlgorithm::btEmptyAlgorithm(const btCollisionAlgorithmConstructionInfo& ci) + : btCollisionAlgorithm(ci) +{ +} + +void btEmptyAlgorithm::processCollision (btCollisionObject* ,btCollisionObject* ,const btDispatcherInfo& ,btManifoldResult* ) +{ +} + +btScalar btEmptyAlgorithm::calculateTimeOfImpact(btCollisionObject* ,btCollisionObject* ,const btDispatcherInfo& ,btManifoldResult* ) +{ + return btScalar(1.); +} + + diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btEmptyCollisionAlgorithm.h b/extern/bullet2/src/BulletCollision/CollisionDispatch/btEmptyCollisionAlgorithm.h new file mode 100644 index 00000000000..b1a193d2cfd --- /dev/null +++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btEmptyCollisionAlgorithm.h @@ -0,0 +1,48 @@ +/* +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 EMPTY_ALGORITH +#define EMPTY_ALGORITH +#include "../BroadphaseCollision/btCollisionAlgorithm.h" +#include "btCollisionCreateFunc.h" + +#define ATTRIBUTE_ALIGNED(a) + +///EmptyAlgorithm is a stub for unsupported collision pairs. +///The dispatcher can dispatch a persistent btEmptyAlgorithm to avoid a search every frame. +class btEmptyAlgorithm : public btCollisionAlgorithm +{ + +public: + + btEmptyAlgorithm(const btCollisionAlgorithmConstructionInfo& ci); + + virtual void processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut); + + virtual btScalar calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut); + + struct CreateFunc :public btCollisionAlgorithmCreateFunc + { + virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, btCollisionObject* body0,btCollisionObject* body1) + { + (void)body0; + (void)body1; + return new btEmptyAlgorithm(ci); + } + }; + +} ATTRIBUTE_ALIGNED(16); + +#endif //EMPTY_ALGORITH diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btManifoldResult.cpp b/extern/bullet2/src/BulletCollision/CollisionDispatch/btManifoldResult.cpp new file mode 100644 index 00000000000..490acc0b611 --- /dev/null +++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btManifoldResult.cpp @@ -0,0 +1,109 @@ +/* +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 "btManifoldResult.h" +#include "BulletCollision/NarrowPhaseCollision/btPersistentManifold.h" +#include "BulletCollision/CollisionDispatch/btCollisionObject.h" + + +///This is to allow MaterialCombiner/Custom Friction/Restitution values +ContactAddedCallback gContactAddedCallback=0; + +///User can override this material combiner by implementing gContactAddedCallback and setting body0->m_collisionFlags |= btCollisionObject::customMaterialCallback; +inline btScalar calculateCombinedFriction(const btCollisionObject* body0,const btCollisionObject* body1) +{ + btScalar friction = body0->getFriction() * body1->getFriction(); + + const btScalar MAX_FRICTION = btScalar(10.); + if (friction < -MAX_FRICTION) + friction = -MAX_FRICTION; + if (friction > MAX_FRICTION) + friction = MAX_FRICTION; + return friction; + +} + +inline btScalar calculateCombinedRestitution(const btCollisionObject* body0,const btCollisionObject* body1) +{ + return body0->getRestitution() * body1->getRestitution(); +} + + + +btManifoldResult::btManifoldResult(btCollisionObject* body0,btCollisionObject* body1) + :m_manifoldPtr(0), + m_body0(body0), + m_body1(body1) +{ + m_rootTransA = body0->getWorldTransform(); + m_rootTransB = body1->getWorldTransform(); +} + + +void btManifoldResult::addContactPoint(const btVector3& normalOnBInWorld,const btVector3& pointInWorld,btScalar depth) +{ + assert(m_manifoldPtr); + //order in manifold needs to match + + if (depth > m_manifoldPtr->getContactBreakingThreshold()) + return; + + bool isSwapped = m_manifoldPtr->getBody0() != m_body0; + + btVector3 pointA = pointInWorld + normalOnBInWorld * depth; + + btVector3 localA; + btVector3 localB; + + if (isSwapped) + { + localA = m_rootTransB.invXform(pointA ); + localB = m_rootTransA.invXform(pointInWorld); + } else + { + localA = m_rootTransA.invXform(pointA ); + localB = m_rootTransB.invXform(pointInWorld); + } + + btManifoldPoint newPt(localA,localB,normalOnBInWorld,depth); + + int insertIndex = m_manifoldPtr->getCacheEntry(newPt); + + newPt.m_combinedFriction = calculateCombinedFriction(m_body0,m_body1); + newPt.m_combinedRestitution = calculateCombinedRestitution(m_body0,m_body1); + + //User can override friction and/or restitution + if (gContactAddedCallback && + //and if either of the two bodies requires custom material + ((m_body0->getCollisionFlags() & btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK) || + (m_body1->getCollisionFlags() & btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK))) + { + //experimental feature info, for per-triangle material etc. + btCollisionObject* obj0 = isSwapped? m_body1 : m_body0; + btCollisionObject* obj1 = isSwapped? m_body0 : m_body1; + (*gContactAddedCallback)(newPt,obj0,m_partId0,m_index0,obj1,m_partId1,m_index1); + } + + if (insertIndex >= 0) + { + //const btManifoldPoint& oldPoint = m_manifoldPtr->getContactPoint(insertIndex); + m_manifoldPtr->replaceContactPoint(newPt,insertIndex); + } else + { + m_manifoldPtr->AddManifoldPoint(newPt); + } +} + diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btManifoldResult.h b/extern/bullet2/src/BulletCollision/CollisionDispatch/btManifoldResult.h new file mode 100644 index 00000000000..77192625513 --- /dev/null +++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btManifoldResult.h @@ -0,0 +1,77 @@ +/* +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 MANIFOLD_RESULT_H +#define MANIFOLD_RESULT_H + +class btCollisionObject; +class btPersistentManifold; +class btManifoldPoint; + +#include "BulletCollision/NarrowPhaseCollision/btDiscreteCollisionDetectorInterface.h" + +#include "../../LinearMath/btTransform.h" + +typedef bool (*ContactAddedCallback)(btManifoldPoint& cp, const btCollisionObject* colObj0,int partId0,int index0,const btCollisionObject* colObj1,int partId1,int index1); +extern ContactAddedCallback gContactAddedCallback; + + + +///btManifoldResult is a helper class to manage contact results. +class btManifoldResult : public btDiscreteCollisionDetectorInterface::Result +{ + btPersistentManifold* m_manifoldPtr; + + //we need this for compounds + btTransform m_rootTransA; + btTransform m_rootTransB; + + btCollisionObject* m_body0; + btCollisionObject* m_body1; + int m_partId0; + int m_partId1; + int m_index0; + int m_index1; +public: + + btManifoldResult() + { + } + + btManifoldResult(btCollisionObject* body0,btCollisionObject* body1); + + virtual ~btManifoldResult() {}; + + void setPersistentManifold(btPersistentManifold* manifoldPtr) + { + m_manifoldPtr = manifoldPtr; + } + + virtual void setShapeIdentifiers(int partId0,int index0, int partId1,int index1) + { + m_partId0=partId0; + m_partId1=partId1; + m_index0=index0; + m_index1=index1; + } + + virtual void addContactPoint(const btVector3& normalOnBInWorld,const btVector3& pointInWorld,btScalar depth); + + + +}; + +#endif //MANIFOLD_RESULT_H diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btSimulationIslandManager.cpp b/extern/bullet2/src/BulletCollision/CollisionDispatch/btSimulationIslandManager.cpp new file mode 100644 index 00000000000..ac2e8554c3a --- /dev/null +++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btSimulationIslandManager.cpp @@ -0,0 +1,357 @@ + + +#include "LinearMath/btScalar.h" +#include "btSimulationIslandManager.h" +#include "BulletCollision/BroadphaseCollision/btDispatcher.h" +#include "BulletCollision/NarrowPhaseCollision/btPersistentManifold.h" +#include "BulletCollision/CollisionDispatch/btCollisionObject.h" +#include "BulletCollision/CollisionDispatch/btCollisionWorld.h" + +#include +#include "LinearMath/btQuickprof.h" + +btSimulationIslandManager::btSimulationIslandManager() +{ +} + +btSimulationIslandManager::~btSimulationIslandManager() +{ +} + + +void btSimulationIslandManager::initUnionFind(int n) +{ + m_unionFind.reset(n); +} + + +void btSimulationIslandManager::findUnions(btDispatcher* dispatcher) +{ + + { + for (int i=0;igetNumManifolds();i++) + { + const btPersistentManifold* manifold = dispatcher->getManifoldByIndexInternal(i); + //static objects (invmass btScalar(0.)) don't merge ! + + const btCollisionObject* colObj0 = static_cast(manifold->getBody0()); + const btCollisionObject* colObj1 = static_cast(manifold->getBody1()); + + if (((colObj0) && ((colObj0)->mergesSimulationIslands())) && + ((colObj1) && ((colObj1)->mergesSimulationIslands()))) + { + + m_unionFind.unite((colObj0)->getIslandTag(), + (colObj1)->getIslandTag()); + } + } + } +} + + +void btSimulationIslandManager::updateActivationState(btCollisionWorld* colWorld,btDispatcher* dispatcher) +{ + + initUnionFind( int (colWorld->getCollisionObjectArray().size())); + + // put the index into m_controllers into m_tag + { + + int index = 0; + int i; + for (i=0;igetCollisionObjectArray().size(); i++) + { + btCollisionObject* collisionObject= colWorld->getCollisionObjectArray()[i]; + collisionObject->setIslandTag(index); + collisionObject->setCompanionId(-1); + collisionObject->setHitFraction(btScalar(1.)); + index++; + + } + } + // do the union find + + findUnions(dispatcher); + + + +} + + + + +void btSimulationIslandManager::storeIslandActivationState(btCollisionWorld* colWorld) +{ + // put the islandId ('find' value) into m_tag + { + + + int index = 0; + int i; + for (i=0;igetCollisionObjectArray().size();i++) + { + btCollisionObject* collisionObject= colWorld->getCollisionObjectArray()[i]; + if (collisionObject->mergesSimulationIslands()) + { + collisionObject->setIslandTag( m_unionFind.find(index) ); + collisionObject->setCompanionId(-1); + } else + { + collisionObject->setIslandTag(-1); + collisionObject->setCompanionId(-2); + } + index++; + } + } +} + +inline int getIslandId(const btPersistentManifold* lhs) +{ + int islandId; + const btCollisionObject* rcolObj0 = static_cast(lhs->getBody0()); + const btCollisionObject* rcolObj1 = static_cast(lhs->getBody1()); + islandId= rcolObj0->getIslandTag()>=0?rcolObj0->getIslandTag():rcolObj1->getIslandTag(); + return islandId; + +} + + + +/// function object that routes calls to operator< +class btPersistentManifoldSortPredicate +{ + public: + + SIMD_FORCE_INLINE bool operator() ( const btPersistentManifold* lhs, const btPersistentManifold* rhs ) + { + return getIslandId(lhs) < getIslandId(rhs); + } +}; + + + + + +// +// todo: this is random access, it can be walked 'cache friendly'! +// +void btSimulationIslandManager::buildAndProcessIslands(btDispatcher* dispatcher,btCollisionObjectArray& collisionObjects, IslandCallback* callback) +{ + + + + /*if (0) + { + int maxNumManifolds = dispatcher->getNumManifolds(); + btCollisionDispatcher* colDis = (btCollisionDispatcher*)dispatcher; + btPersistentManifold** manifold = colDis->getInternalManifoldPointer(); + callback->ProcessIsland(&collisionObjects[0],collisionObjects.size(),manifold,maxNumManifolds, 0); + return; + } + */ + + + BEGIN_PROFILE("islandUnionFindAndHeapSort"); + + //we are going to sort the unionfind array, and store the element id in the size + //afterwards, we clean unionfind, to make sure no-one uses it anymore + + getUnionFind().sortIslands(); + int numElem = getUnionFind().getNumElements(); + + int endIslandIndex=1; + int startIslandIndex; + + + //update the sleeping state for bodies, if all are sleeping + for ( startIslandIndex=0;startIslandIndexgetIslandTag() != islandId) && (colObj0->getIslandTag() != -1)) + { + printf("error in island management\n"); + } + + assert((colObj0->getIslandTag() == islandId) || (colObj0->getIslandTag() == -1)); + if (colObj0->getIslandTag() == islandId) + { + if (colObj0->getActivationState()== ACTIVE_TAG) + { + allSleeping = false; + } + if (colObj0->getActivationState()== DISABLE_DEACTIVATION) + { + allSleeping = false; + } + } + } + + + if (allSleeping) + { + int idx; + for (idx=startIslandIndex;idxgetIslandTag() != islandId) && (colObj0->getIslandTag() != -1)) + { + printf("error in island management\n"); + } + + assert((colObj0->getIslandTag() == islandId) || (colObj0->getIslandTag() == -1)); + + if (colObj0->getIslandTag() == islandId) + { + colObj0->setActivationState( ISLAND_SLEEPING ); + } + } + } else + { + + int idx; + for (idx=startIslandIndex;idxgetIslandTag() != islandId) && (colObj0->getIslandTag() != -1)) + { + printf("error in island management\n"); + } + + assert((colObj0->getIslandTag() == islandId) || (colObj0->getIslandTag() == -1)); + + if (colObj0->getIslandTag() == islandId) + { + if ( colObj0->getActivationState() == ISLAND_SLEEPING) + { + colObj0->setActivationState( WANTS_DEACTIVATION); + } + } + } + } + } + + btAlignedObjectArray islandmanifold; + int i; + int maxNumManifolds = dispatcher->getNumManifolds(); + islandmanifold.reserve(maxNumManifolds); + + for (i=0;igetManifoldByIndexInternal(i); + + btCollisionObject* colObj0 = static_cast(manifold->getBody0()); + btCollisionObject* colObj1 = static_cast(manifold->getBody1()); + + //todo: check sleeping conditions! + if (((colObj0) && colObj0->getActivationState() != ISLAND_SLEEPING) || + ((colObj1) && colObj1->getActivationState() != ISLAND_SLEEPING)) + { + + //kinematic objects don't merge islands, but wake up all connected objects + if (colObj0->isStaticOrKinematicObject() && colObj0->getActivationState() != ISLAND_SLEEPING) + { + colObj1->activate(); + } + if (colObj1->isStaticOrKinematicObject() && colObj1->getActivationState() != ISLAND_SLEEPING) + { + colObj0->activate(); + } + + //filtering for response + if (dispatcher->needsResponse(colObj0,colObj1)) + islandmanifold.push_back(manifold); + } + } + + int numManifolds = int (islandmanifold.size()); + + // Sort manifolds, based on islands + // Sort the vector using predicate and std::sort + //std::sort(islandmanifold.begin(), islandmanifold.end(), btPersistentManifoldSortPredicate); + + //we should do radix sort, it it much faster (O(n) instead of O (n log2(n)) + islandmanifold.heapSort(btPersistentManifoldSortPredicate()); + + //now process all active islands (sets of manifolds for now) + + int startManifoldIndex = 0; + int endManifoldIndex = 1; + + //int islandId; + + END_PROFILE("islandUnionFindAndHeapSort"); + + btAlignedObjectArray islandBodies; + + + //traverse the simulation islands, and call the solver, unless all objects are sleeping/deactivated + for ( startIslandIndex=0;startIslandIndexisActive()) + islandSleeping = true; + } + + + //find the accompanying contact manifold for this islandId + int numIslandManifolds = 0; + btPersistentManifold** startManifold = 0; + + if (startManifoldIndexProcessIsland(&islandBodies[0],islandBodies.size(),startManifold,numIslandManifolds, islandId); + } + + if (numIslandManifolds) + { + startManifoldIndex = endManifoldIndex; + } + + islandBodies.resize(0); + } + + +} diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btSimulationIslandManager.h b/extern/bullet2/src/BulletCollision/CollisionDispatch/btSimulationIslandManager.h new file mode 100644 index 00000000000..d91ed1c20eb --- /dev/null +++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btSimulationIslandManager.h @@ -0,0 +1,61 @@ +/* +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 SIMULATION_ISLAND_MANAGER_H +#define SIMULATION_ISLAND_MANAGER_H + +#include "../CollisionDispatch/btUnionFind.h" +#include "btCollisionCreateFunc.h" + +class btCollisionObject; +class btCollisionWorld; +class btDispatcher; + +///SimulationIslandManager creates and handles simulation islands, using btUnionFind +class btSimulationIslandManager +{ + btUnionFind m_unionFind; + +public: + btSimulationIslandManager(); + virtual ~btSimulationIslandManager(); + + + void initUnionFind(int n); + + + btUnionFind& getUnionFind() { return m_unionFind;} + + virtual void updateActivationState(btCollisionWorld* colWorld,btDispatcher* dispatcher); + virtual void storeIslandActivationState(btCollisionWorld* world); + + + void findUnions(btDispatcher* dispatcher); + + + + struct IslandCallback + { + virtual ~IslandCallback() {}; + + virtual void ProcessIsland(btCollisionObject** bodies,int numBodies,class btPersistentManifold** manifolds,int numManifolds, int islandId) = 0; + }; + + void buildAndProcessIslands(btDispatcher* dispatcher,btCollisionObjectArray& collisionObjects, IslandCallback* callback); + +}; + +#endif //SIMULATION_ISLAND_MANAGER_H + diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereBoxCollisionAlgorithm.cpp b/extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereBoxCollisionAlgorithm.cpp new file mode 100644 index 00000000000..05556bd34e2 --- /dev/null +++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereBoxCollisionAlgorithm.cpp @@ -0,0 +1,249 @@ +/* +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 "btSphereBoxCollisionAlgorithm.h" +#include "BulletCollision/CollisionDispatch/btCollisionDispatcher.h" +#include "BulletCollision/CollisionShapes/btSphereShape.h" +#include "BulletCollision/CollisionShapes/btBoxShape.h" +#include "BulletCollision/CollisionDispatch/btCollisionObject.h" +//#include + +btSphereBoxCollisionAlgorithm::btSphereBoxCollisionAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* col0,btCollisionObject* col1, bool isSwapped) +: btCollisionAlgorithm(ci), +m_ownManifold(false), +m_manifoldPtr(mf), +m_isSwapped(isSwapped) +{ + btCollisionObject* sphereObj = m_isSwapped? col1 : col0; + btCollisionObject* boxObj = m_isSwapped? col0 : col1; + + if (!m_manifoldPtr && m_dispatcher->needsCollision(sphereObj,boxObj)) + { + m_manifoldPtr = m_dispatcher->getNewManifold(sphereObj,boxObj); + m_ownManifold = true; + } +} + + +btSphereBoxCollisionAlgorithm::~btSphereBoxCollisionAlgorithm() +{ + if (m_ownManifold) + { + if (m_manifoldPtr) + m_dispatcher->releaseManifold(m_manifoldPtr); + } +} + + + +void btSphereBoxCollisionAlgorithm::processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut) +{ + (void)dispatchInfo; + (void)resultOut; + if (!m_manifoldPtr) + return; + + btCollisionObject* sphereObj = m_isSwapped? body1 : body0; + btCollisionObject* boxObj = m_isSwapped? body0 : body1; + + + btSphereShape* sphere0 = (btSphereShape*)sphereObj->getCollisionShape(); + + btVector3 normalOnSurfaceB; + btVector3 pOnBox,pOnSphere; + btVector3 sphereCenter = sphereObj->getWorldTransform().getOrigin(); + btScalar radius = sphere0->getRadius(); + + btScalar dist = getSphereDistance(boxObj,pOnBox,pOnSphere,sphereCenter,radius); + + if (dist < SIMD_EPSILON) + { + btVector3 normalOnSurfaceB = (pOnBox- pOnSphere).normalize(); + + /// report a contact. internally this will be kept persistent, and contact reduction is done + + resultOut->setPersistentManifold(m_manifoldPtr); + resultOut->addContactPoint(normalOnSurfaceB,pOnBox,dist); + + } + + + +} + +btScalar btSphereBoxCollisionAlgorithm::calculateTimeOfImpact(btCollisionObject* col0,btCollisionObject* col1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut) +{ + (void)resultOut; + (void)dispatchInfo; + (void)col0; + (void)col1; + + //not yet + return btScalar(1.); +} + + +btScalar btSphereBoxCollisionAlgorithm::getSphereDistance(btCollisionObject* boxObj, btVector3& pointOnBox, btVector3& v3PointOnSphere, const btVector3& sphereCenter, btScalar fRadius ) +{ + + btScalar margins; + btVector3 bounds[2]; + btBoxShape* boxShape= (btBoxShape*)boxObj->getCollisionShape(); + + bounds[0] = -boxShape->getHalfExtents(); + bounds[1] = boxShape->getHalfExtents(); + + margins = boxShape->getMargin();//also add sphereShape margin? + + const btTransform& m44T = boxObj->getWorldTransform(); + + btVector3 boundsVec[2]; + btScalar fPenetration; + + boundsVec[0] = bounds[0]; + boundsVec[1] = bounds[1]; + + btVector3 marginsVec( margins, margins, margins ); + + // add margins + bounds[0] += marginsVec; + bounds[1] -= marginsVec; + + ///////////////////////////////////////////////// + + btVector3 tmp, prel, n[6], normal, v3P; + btScalar fSep = btScalar(10000000.0), fSepThis; + + n[0].setValue( btScalar(-1.0), btScalar(0.0), btScalar(0.0) ); + n[1].setValue( btScalar(0.0), btScalar(-1.0), btScalar(0.0) ); + n[2].setValue( btScalar(0.0), btScalar(0.0), btScalar(-1.0) ); + n[3].setValue( btScalar(1.0), btScalar(0.0), btScalar(0.0) ); + n[4].setValue( btScalar(0.0), btScalar(1.0), btScalar(0.0) ); + n[5].setValue( btScalar(0.0), btScalar(0.0), btScalar(1.0) ); + + // convert point in local space + prel = m44T.invXform( sphereCenter); + + bool bFound = false; + + v3P = prel; + + for (int i=0;i<6;i++) + { + int j = i<3? 0:1; + if ( (fSepThis = ((v3P-bounds[j]) .dot(n[i]))) > btScalar(0.0) ) + { + v3P = v3P - n[i]*fSepThis; + bFound = true; + } + } + + // + + if ( bFound ) + { + bounds[0] = boundsVec[0]; + bounds[1] = boundsVec[1]; + + normal = (prel - v3P).normalize(); + pointOnBox = v3P + normal*margins; + v3PointOnSphere = prel - normal*fRadius; + + if ( ((v3PointOnSphere - pointOnBox) .dot (normal)) > btScalar(0.0) ) + { + return btScalar(1.0); + } + + // transform back in world space + tmp = m44T( pointOnBox); + pointOnBox = tmp; + tmp = m44T( v3PointOnSphere); + v3PointOnSphere = tmp; + btScalar fSeps2 = (pointOnBox-v3PointOnSphere).length2(); + + //if this fails, fallback into deeper penetration case, below + if (fSeps2 > SIMD_EPSILON) + { + fSep = - btSqrt(fSeps2); + normal = (pointOnBox-v3PointOnSphere); + normal *= btScalar(1.)/fSep; + } + + return fSep; + } + + ////////////////////////////////////////////////// + // Deep penetration case + + fPenetration = getSpherePenetration( boxObj,pointOnBox, v3PointOnSphere, sphereCenter, fRadius,bounds[0],bounds[1] ); + + bounds[0] = boundsVec[0]; + bounds[1] = boundsVec[1]; + + if ( fPenetration <= btScalar(0.0) ) + return (fPenetration-margins); + else + return btScalar(1.0); +} + +btScalar btSphereBoxCollisionAlgorithm::getSpherePenetration( btCollisionObject* boxObj,btVector3& pointOnBox, btVector3& v3PointOnSphere, const btVector3& sphereCenter, btScalar fRadius, const btVector3& aabbMin, const btVector3& aabbMax) +{ + + btVector3 bounds[2]; + + bounds[0] = aabbMin; + bounds[1] = aabbMax; + + btVector3 p0, tmp, prel, n[6], normal; + btScalar fSep = btScalar(-10000000.0), fSepThis; + + n[0].setValue( btScalar(-1.0), btScalar(0.0), btScalar(0.0) ); + n[1].setValue( btScalar(0.0), btScalar(-1.0), btScalar(0.0) ); + n[2].setValue( btScalar(0.0), btScalar(0.0), btScalar(-1.0) ); + n[3].setValue( btScalar(1.0), btScalar(0.0), btScalar(0.0) ); + n[4].setValue( btScalar(0.0), btScalar(1.0), btScalar(0.0) ); + n[5].setValue( btScalar(0.0), btScalar(0.0), btScalar(1.0) ); + + const btTransform& m44T = boxObj->getWorldTransform(); + + // convert point in local space + prel = m44T.invXform( sphereCenter); + + /////////// + + for (int i=0;i<6;i++) + { + int j = i<3 ? 0:1; + if ( (fSepThis = ((prel-bounds[j]) .dot( n[i]))-fRadius) > btScalar(0.0) ) return btScalar(1.0); + if ( fSepThis > fSep ) + { + p0 = bounds[j]; normal = (btVector3&)n[i]; + fSep = fSepThis; + } + } + + pointOnBox = prel - normal*(normal.dot((prel-p0))); + v3PointOnSphere = pointOnBox + normal*fSep; + + // transform back in world space + tmp = m44T( pointOnBox); + pointOnBox = tmp; + tmp = m44T( v3PointOnSphere); v3PointOnSphere = tmp; + normal = (pointOnBox-v3PointOnSphere).normalize(); + + return fSep; + +} + diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereBoxCollisionAlgorithm.h b/extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereBoxCollisionAlgorithm.h new file mode 100644 index 00000000000..07592909200 --- /dev/null +++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereBoxCollisionAlgorithm.h @@ -0,0 +1,64 @@ +/* +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 SPHERE_BOX_COLLISION_ALGORITHM_H +#define SPHERE_BOX_COLLISION_ALGORITHM_H + +#include "../BroadphaseCollision/btCollisionAlgorithm.h" +#include "../BroadphaseCollision/btBroadphaseProxy.h" +#include "../CollisionDispatch/btCollisionCreateFunc.h" +class btPersistentManifold; +#include "../../LinearMath/btVector3.h" + +/// btSphereBoxCollisionAlgorithm provides sphere-box collision detection. +/// Other features are frame-coherency (persistent data) and collision response. +class btSphereBoxCollisionAlgorithm : public btCollisionAlgorithm +{ + bool m_ownManifold; + btPersistentManifold* m_manifoldPtr; + bool m_isSwapped; + +public: + + btSphereBoxCollisionAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* col0,btCollisionObject* col1, bool isSwapped); + + virtual ~btSphereBoxCollisionAlgorithm(); + + virtual void processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut); + + virtual btScalar calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut); + + btScalar getSphereDistance( btCollisionObject* boxObj,btVector3& v3PointOnBox, btVector3& v3PointOnSphere, const btVector3& v3SphereCenter, btScalar fRadius ); + + btScalar getSpherePenetration( btCollisionObject* boxObj, btVector3& v3PointOnBox, btVector3& v3PointOnSphere, const btVector3& v3SphereCenter, btScalar fRadius, const btVector3& aabbMin, const btVector3& aabbMax); + + struct CreateFunc :public btCollisionAlgorithmCreateFunc + { + virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, btCollisionObject* body0,btCollisionObject* body1) + { + if (!m_swapped) + { + return new btSphereBoxCollisionAlgorithm(0,ci,body0,body1,false); + } else + { + return new btSphereBoxCollisionAlgorithm(0,ci,body0,body1,true); + } + } + }; + +}; + +#endif //SPHERE_BOX_COLLISION_ALGORITHM_H + diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereSphereCollisionAlgorithm.cpp b/extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereSphereCollisionAlgorithm.cpp new file mode 100644 index 00000000000..424ff432f84 --- /dev/null +++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereSphereCollisionAlgorithm.cpp @@ -0,0 +1,85 @@ +/* +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 "btSphereSphereCollisionAlgorithm.h" +#include "BulletCollision/CollisionDispatch/btCollisionDispatcher.h" +#include "BulletCollision/CollisionShapes/btSphereShape.h" +#include "BulletCollision/CollisionDispatch/btCollisionObject.h" + +btSphereSphereCollisionAlgorithm::btSphereSphereCollisionAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* col0,btCollisionObject* col1) +: btCollisionAlgorithm(ci), +m_ownManifold(false), +m_manifoldPtr(mf) +{ + if (!m_manifoldPtr) + { + m_manifoldPtr = m_dispatcher->getNewManifold(col0,col1); + m_ownManifold = true; + } +} + +btSphereSphereCollisionAlgorithm::~btSphereSphereCollisionAlgorithm() +{ + if (m_ownManifold) + { + if (m_manifoldPtr) + m_dispatcher->releaseManifold(m_manifoldPtr); + } +} + +void btSphereSphereCollisionAlgorithm::processCollision (btCollisionObject* col0,btCollisionObject* col1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut) +{ + (void)dispatchInfo; + + if (!m_manifoldPtr) + return; + + btSphereShape* sphere0 = (btSphereShape*)col0->getCollisionShape(); + btSphereShape* sphere1 = (btSphereShape*)col1->getCollisionShape(); + + btVector3 diff = col0->getWorldTransform().getOrigin()- col1->getWorldTransform().getOrigin(); + btScalar len = diff.length(); + btScalar radius0 = sphere0->getRadius(); + btScalar radius1 = sphere1->getRadius(); + + ///iff distance positive, don't generate a new contact + if ( len > (radius0+radius1)) + return; + + ///distance (negative means penetration) + btScalar dist = len - (radius0+radius1); + + btVector3 normalOnSurfaceB = diff / len; + ///point on A (worldspace) + btVector3 pos0 = col0->getWorldTransform().getOrigin() - radius0 * normalOnSurfaceB; + ///point on B (worldspace) + btVector3 pos1 = col1->getWorldTransform().getOrigin() + radius1* normalOnSurfaceB; + + /// report a contact. internally this will be kept persistent, and contact reduction is done + resultOut->setPersistentManifold(m_manifoldPtr); + resultOut->addContactPoint(normalOnSurfaceB,pos1,dist); + +} + +btScalar btSphereSphereCollisionAlgorithm::calculateTimeOfImpact(btCollisionObject* col0,btCollisionObject* col1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut) +{ + (void)col0; + (void)col1; + (void)dispatchInfo; + (void)resultOut; + + //not yet + return btScalar(1.); +} diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereSphereCollisionAlgorithm.h b/extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereSphereCollisionAlgorithm.h new file mode 100644 index 00000000000..7a19ff31edf --- /dev/null +++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereSphereCollisionAlgorithm.h @@ -0,0 +1,56 @@ +/* +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 SPHERE_SPHERE_COLLISION_ALGORITHM_H +#define SPHERE_SPHERE_COLLISION_ALGORITHM_H + +#include "../BroadphaseCollision/btCollisionAlgorithm.h" +#include "../BroadphaseCollision/btBroadphaseProxy.h" +#include "../CollisionDispatch/btCollisionCreateFunc.h" +class btPersistentManifold; + +/// btSphereSphereCollisionAlgorithm provides sphere-sphere collision detection. +/// Other features are frame-coherency (persistent data) and collision response. +/// Also provides the most basic sample for custom/user btCollisionAlgorithm +class btSphereSphereCollisionAlgorithm : public btCollisionAlgorithm +{ + bool m_ownManifold; + btPersistentManifold* m_manifoldPtr; + +public: + btSphereSphereCollisionAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* body0,btCollisionObject* body1); + + btSphereSphereCollisionAlgorithm(const btCollisionAlgorithmConstructionInfo& ci) + : btCollisionAlgorithm(ci) {} + + virtual void processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut); + + virtual btScalar calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut); + + + virtual ~btSphereSphereCollisionAlgorithm(); + + struct CreateFunc :public btCollisionAlgorithmCreateFunc + { + virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, btCollisionObject* body0,btCollisionObject* body1) + { + return new btSphereSphereCollisionAlgorithm(0,ci,body0,body1); + } + }; + +}; + +#endif //SPHERE_SPHERE_COLLISION_ALGORITHM_H + diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereTriangleCollisionAlgorithm.cpp b/extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereTriangleCollisionAlgorithm.cpp new file mode 100644 index 00000000000..b011b707e3f --- /dev/null +++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereTriangleCollisionAlgorithm.cpp @@ -0,0 +1,76 @@ +/* +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 "btSphereTriangleCollisionAlgorithm.h" +#include "BulletCollision/CollisionDispatch/btCollisionDispatcher.h" +#include "BulletCollision/CollisionShapes/btSphereShape.h" +#include "BulletCollision/CollisionDispatch/btCollisionObject.h" +#include "SphereTriangleDetector.h" + + +btSphereTriangleCollisionAlgorithm::btSphereTriangleCollisionAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* col0,btCollisionObject* col1,bool swapped) +: btCollisionAlgorithm(ci), +m_ownManifold(false), +m_manifoldPtr(mf), +m_swapped(swapped) +{ + if (!m_manifoldPtr) + { + m_manifoldPtr = m_dispatcher->getNewManifold(col0,col1); + m_ownManifold = true; + } +} + +btSphereTriangleCollisionAlgorithm::~btSphereTriangleCollisionAlgorithm() +{ + if (m_ownManifold) + { + if (m_manifoldPtr) + m_dispatcher->releaseManifold(m_manifoldPtr); + } +} + +void btSphereTriangleCollisionAlgorithm::processCollision (btCollisionObject* col0,btCollisionObject* col1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut) +{ + if (!m_manifoldPtr) + return; + + btSphereShape* sphere = (btSphereShape*)col0->getCollisionShape(); + btTriangleShape* triangle = (btTriangleShape*)col1->getCollisionShape(); + + /// report a contact. internally this will be kept persistent, and contact reduction is done + resultOut->setPersistentManifold(m_manifoldPtr); + SphereTriangleDetector detector(sphere,triangle); + + btDiscreteCollisionDetectorInterface::ClosestPointInput input; + input.m_maximumDistanceSquared = btScalar(1e30);//todo: tighter bounds + input.m_transformA = col0->getWorldTransform(); + input.m_transformB = col1->getWorldTransform(); + + detector.getClosestPoints(input,*resultOut,dispatchInfo.m_debugDraw); + +} + +btScalar btSphereTriangleCollisionAlgorithm::calculateTimeOfImpact(btCollisionObject* col0,btCollisionObject* col1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut) +{ + (void)resultOut; + (void)dispatchInfo; + (void)col0; + (void)col1; + + //not yet + return btScalar(1.); +} diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereTriangleCollisionAlgorithm.h b/extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereTriangleCollisionAlgorithm.h new file mode 100644 index 00000000000..57c6e6af619 --- /dev/null +++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereTriangleCollisionAlgorithm.h @@ -0,0 +1,59 @@ +/* +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 SPHERE_TRIANGLE_COLLISION_ALGORITHM_H +#define SPHERE_TRIANGLE_COLLISION_ALGORITHM_H + +#include "../BroadphaseCollision/btCollisionAlgorithm.h" +#include "../BroadphaseCollision/btBroadphaseProxy.h" +#include "../CollisionDispatch/btCollisionCreateFunc.h" +class btPersistentManifold; + +/// btSphereSphereCollisionAlgorithm provides sphere-sphere collision detection. +/// Other features are frame-coherency (persistent data) and collision response. +/// Also provides the most basic sample for custom/user btCollisionAlgorithm +class btSphereTriangleCollisionAlgorithm : public btCollisionAlgorithm +{ + bool m_ownManifold; + btPersistentManifold* m_manifoldPtr; + bool m_swapped; + +public: + btSphereTriangleCollisionAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* body0,btCollisionObject* body1,bool swapped); + + btSphereTriangleCollisionAlgorithm(const btCollisionAlgorithmConstructionInfo& ci) + : btCollisionAlgorithm(ci) {} + + virtual void processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut); + + virtual btScalar calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut); + + + virtual ~btSphereTriangleCollisionAlgorithm(); + + struct CreateFunc :public btCollisionAlgorithmCreateFunc + { + + virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, btCollisionObject* body0,btCollisionObject* body1) + { + + return new btSphereTriangleCollisionAlgorithm(ci.m_manifold,ci,body0,body1,m_swapped); + } + }; + +}; + +#endif //SPHERE_TRIANGLE_COLLISION_ALGORITHM_H + diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btUnionFind.cpp b/extern/bullet2/src/BulletCollision/CollisionDispatch/btUnionFind.cpp new file mode 100644 index 00000000000..62254335796 --- /dev/null +++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btUnionFind.cpp @@ -0,0 +1,83 @@ +/* +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 "btUnionFind.h" +#include + + + +btUnionFind::~btUnionFind() +{ + Free(); + +} + +btUnionFind::btUnionFind() +{ + +} + +void btUnionFind::allocate(int N) +{ + m_elements.resize(N); +} +void btUnionFind::Free() +{ + m_elements.clear(); +} + + +void btUnionFind::reset(int N) +{ + allocate(N); + + for (int i = 0; i < N; i++) + { + m_elements[i].m_id = i; m_elements[i].m_sz = 1; + } +} + + +class btUnionFindElementSortPredicate +{ + public: + + bool operator() ( const btElement& lhs, const btElement& rhs ) + { + return lhs.m_id < rhs.m_id; + } +}; + +///this is a special operation, destroying the content of btUnionFind. +///it sorts the elements, based on island id, in order to make it easy to iterate over islands +void btUnionFind::sortIslands() +{ + + //first store the original body index, and islandId + int numElements = m_elements.size(); + + for (int i=0;i m_elements; + + public: + + btUnionFind(); + ~btUnionFind(); + + + //this is a special operation, destroying the content of btUnionFind. + //it sorts the elements, based on island id, in order to make it easy to iterate over islands + void sortIslands(); + + void reset(int N); + + inline int getNumElements() const + { + return int(m_elements.size()); + } + inline bool isRoot(int x) const + { + return (x == m_elements[x].m_id); + } + + btElement& getElement(int index) + { + return m_elements[index]; + } + const btElement& getElement(int index) const + { + return m_elements[index]; + } + + void allocate(int N); + void Free(); + + + + + int find(int p, int q) + { + return (find(p) == find(q)); + } + + void unite(int p, int q) + { + int i = find(p), j = find(q); + if (i == j) + return; + +#ifndef USE_PATH_COMPRESSION + //weighted quick union, this keeps the 'trees' balanced, and keeps performance of unite O( log(n) ) + if (m_elements[i].m_sz < m_elements[j].m_sz) + { + m_elements[i].m_id = j; m_elements[j].m_sz += m_elements[i].m_sz; + } + else + { + m_elements[j].m_id = i; m_elements[i].m_sz += m_elements[j].m_sz; + } +#else + m_elements[i].m_id = j; m_elements[j].m_sz += m_elements[i].m_sz; +#endif //USE_PATH_COMPRESSION + } + + int find(int x) + { + //assert(x < m_N); + //assert(x >= 0); + + while (x != m_elements[x].m_id) + { + //not really a reason not to use path compression, and it flattens the trees/improves find performance dramatically + + #ifdef USE_PATH_COMPRESSION + // + m_elements[x].m_id = m_elements[m_elements[x].m_id].m_id; + #endif // + x = m_elements[x].m_id; + //assert(x < m_N); + //assert(x >= 0); + + } + return x; + } + + + }; + + +#endif //UNION_FIND_H diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btBoxShape.cpp b/extern/bullet2/src/BulletCollision/CollisionShapes/btBoxShape.cpp new file mode 100644 index 00000000000..636b0046c13 --- /dev/null +++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btBoxShape.cpp @@ -0,0 +1,57 @@ +/* +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 "btBoxShape.h" + +btVector3 btBoxShape::getHalfExtents() const +{ + return m_implicitShapeDimensions * m_localScaling; +} +//{ + + +void btBoxShape::getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const +{ + btVector3 halfExtents = getHalfExtents(); + + btMatrix3x3 abs_b = t.getBasis().absolute(); + btPoint3 center = t.getOrigin(); + btVector3 extent = btVector3(abs_b[0].dot(halfExtents), + abs_b[1].dot(halfExtents), + abs_b[2].dot(halfExtents)); + extent += btVector3(getMargin(),getMargin(),getMargin()); + + aabbMin = center - extent; + aabbMax = center + extent; + + +} + + +void btBoxShape::calculateLocalInertia(btScalar mass,btVector3& inertia) +{ + //btScalar margin = btScalar(0.); + btVector3 halfExtents = getHalfExtents(); + + btScalar lx=btScalar(2.)*(halfExtents.x()); + btScalar ly=btScalar(2.)*(halfExtents.y()); + btScalar lz=btScalar(2.)*(halfExtents.z()); + + inertia.setValue(mass/(btScalar(12.0)) * (ly*ly + lz*lz), + mass/(btScalar(12.0)) * (lx*lx + lz*lz), + mass/(btScalar(12.0)) * (lx*lx + ly*ly)); + +} + diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btBoxShape.h b/extern/bullet2/src/BulletCollision/CollisionShapes/btBoxShape.h new file mode 100644 index 00000000000..bc42f146c7c --- /dev/null +++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btBoxShape.h @@ -0,0 +1,293 @@ +/* +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 OBB_BOX_MINKOWSKI_H +#define OBB_BOX_MINKOWSKI_H + +#include "btPolyhedralConvexShape.h" +#include "btCollisionMargin.h" +#include "../BroadphaseCollision/btBroadphaseProxy.h" +#include "../../LinearMath/btPoint3.h" +#include "../../LinearMath/btSimdMinMax.h" + +///btBoxShape implements both a feature based (vertex/edge/plane) and implicit (getSupportingVertex) Box +class btBoxShape: public btPolyhedralConvexShape +{ + + //btVector3 m_boxHalfExtents1; //use m_implicitShapeDimensions instead + + +public: + + btVector3 getHalfExtents() const; + + virtual int getShapeType() const { return BOX_SHAPE_PROXYTYPE;} + + virtual btVector3 localGetSupportingVertex(const btVector3& vec) const + { + + btVector3 halfExtents = getHalfExtents(); + + btVector3 supVertex; + supVertex = btPoint3(vec.x() < btScalar(0.0) ? -halfExtents.x() : halfExtents.x(), + vec.y() < btScalar(0.0) ? -halfExtents.y() : halfExtents.y(), + vec.z() < btScalar(0.0) ? -halfExtents.z() : halfExtents.z()); + + return supVertex; + } + + virtual inline btVector3 localGetSupportingVertexWithoutMargin(const btVector3& vec)const + { + btVector3 halfExtents = getHalfExtents(); + btVector3 margin(getMargin(),getMargin(),getMargin()); + halfExtents -= margin; + + return btVector3(vec.x() < btScalar(0.0) ? -halfExtents.x() : halfExtents.x(), + vec.y() < btScalar(0.0) ? -halfExtents.y() : halfExtents.y(), + vec.z() < btScalar(0.0) ? -halfExtents.z() : halfExtents.z()); + } + + virtual void batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const + { + btVector3 halfExtents = getHalfExtents(); + btVector3 margin(getMargin(),getMargin(),getMargin()); + halfExtents -= margin; + + + for (int i=0;i>1)) - halfExtents.y() * ((i&2)>>1), + halfExtents.z() * (1-((i&4)>>2)) - halfExtents.z() * ((i&4)>>2)); + } + + + virtual void getPlaneEquation(btVector4& plane,int i) const + { + btVector3 halfExtents = getHalfExtents(); + + switch (i) + { + case 0: + plane.setValue(btScalar(1.),btScalar(0.),btScalar(0.)); + plane[3] = -halfExtents.x(); + break; + case 1: + plane.setValue(btScalar(-1.),btScalar(0.),btScalar(0.)); + plane[3] = -halfExtents.x(); + break; + case 2: + plane.setValue(btScalar(0.),btScalar(1.),btScalar(0.)); + plane[3] = -halfExtents.y(); + break; + case 3: + plane.setValue(btScalar(0.),btScalar(-1.),btScalar(0.)); + plane[3] = -halfExtents.y(); + break; + case 4: + plane.setValue(btScalar(0.),btScalar(0.),btScalar(1.)); + plane[3] = -halfExtents.z(); + break; + case 5: + plane.setValue(btScalar(0.),btScalar(0.),btScalar(-1.)); + plane[3] = -halfExtents.z(); + break; + default: + assert(0); + } + } + + + virtual void getEdge(int i,btPoint3& pa,btPoint3& pb) const + //virtual void getEdge(int i,Edge& edge) const + { + int edgeVert0 = 0; + int edgeVert1 = 0; + + switch (i) + { + case 0: + edgeVert0 = 0; + edgeVert1 = 1; + break; + case 1: + edgeVert0 = 0; + edgeVert1 = 2; + break; + case 2: + edgeVert0 = 1; + edgeVert1 = 3; + + break; + case 3: + edgeVert0 = 2; + edgeVert1 = 3; + break; + case 4: + edgeVert0 = 0; + edgeVert1 = 4; + break; + case 5: + edgeVert0 = 1; + edgeVert1 = 5; + + break; + case 6: + edgeVert0 = 2; + edgeVert1 = 6; + break; + case 7: + edgeVert0 = 3; + edgeVert1 = 7; + break; + case 8: + edgeVert0 = 4; + edgeVert1 = 5; + break; + case 9: + edgeVert0 = 4; + edgeVert1 = 6; + break; + case 10: + edgeVert0 = 5; + edgeVert1 = 7; + break; + case 11: + edgeVert0 = 6; + edgeVert1 = 7; + break; + default: + btAssert(0); + + } + + getVertex(edgeVert0,pa ); + getVertex(edgeVert1,pb ); + } + + + + + + virtual bool isInside(const btPoint3& pt,btScalar tolerance) const + { + btVector3 halfExtents = getHalfExtents(); + + //btScalar minDist = 2*tolerance; + + bool result = (pt.x() <= (halfExtents.x()+tolerance)) && + (pt.x() >= (-halfExtents.x()-tolerance)) && + (pt.y() <= (halfExtents.y()+tolerance)) && + (pt.y() >= (-halfExtents.y()-tolerance)) && + (pt.z() <= (halfExtents.z()+tolerance)) && + (pt.z() >= (-halfExtents.z()-tolerance)); + + return result; + } + + + //debugging + virtual char* getName()const + { + return "Box"; + } + + virtual int getNumPreferredPenetrationDirections() const + { + return 6; + } + + virtual void getPreferredPenetrationDirection(int index, btVector3& penetrationVector) const + { + switch (index) + { + case 0: + penetrationVector.setValue(btScalar(1.),btScalar(0.),btScalar(0.)); + break; + case 1: + penetrationVector.setValue(btScalar(-1.),btScalar(0.),btScalar(0.)); + break; + case 2: + penetrationVector.setValue(btScalar(0.),btScalar(1.),btScalar(0.)); + break; + case 3: + penetrationVector.setValue(btScalar(0.),btScalar(-1.),btScalar(0.)); + break; + case 4: + penetrationVector.setValue(btScalar(0.),btScalar(0.),btScalar(1.)); + break; + case 5: + penetrationVector.setValue(btScalar(0.),btScalar(0.),btScalar(-1.)); + break; + default: + assert(0); + } + } + +}; + +#endif //OBB_BOX_MINKOWSKI_H + diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btBvhTriangleMeshShape.cpp b/extern/bullet2/src/BulletCollision/CollisionShapes/btBvhTriangleMeshShape.cpp new file mode 100644 index 00000000000..8da554ef14d --- /dev/null +++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btBvhTriangleMeshShape.cpp @@ -0,0 +1,173 @@ +/* +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 "BulletCollision/CollisionShapes/btBvhTriangleMeshShape.h" +#include "BulletCollision/CollisionShapes/btOptimizedBvh.h" + + +///Bvh Concave triangle mesh is a static-triangle mesh shape with Bounding Volume Hierarchy optimization. +///Uses an interface to access the triangles to allow for sharing graphics/physics triangles. +btBvhTriangleMeshShape::btBvhTriangleMeshShape(btStridingMeshInterface* meshInterface, bool useQuantizedAabbCompression) +:btTriangleMeshShape(meshInterface),m_useQuantizedAabbCompression(useQuantizedAabbCompression) +{ + //construct bvh from meshInterface +#ifndef DISABLE_BVH + + m_bvh = new btOptimizedBvh(); + btVector3 bvhAabbMin,bvhAabbMax; + meshInterface->calculateAabbBruteForce(bvhAabbMin,bvhAabbMax); + m_bvh->build(meshInterface,m_useQuantizedAabbCompression,bvhAabbMin,bvhAabbMax); + +#endif //DISABLE_BVH + +} + +btBvhTriangleMeshShape::btBvhTriangleMeshShape(btStridingMeshInterface* meshInterface, bool useQuantizedAabbCompression,const btVector3& bvhAabbMin,const btVector3& bvhAabbMax) +:btTriangleMeshShape(meshInterface),m_useQuantizedAabbCompression(useQuantizedAabbCompression) +{ + //construct bvh from meshInterface +#ifndef DISABLE_BVH + + m_bvh = new btOptimizedBvh(); + m_bvh->build(meshInterface,m_useQuantizedAabbCompression,bvhAabbMin,bvhAabbMax); + +#endif //DISABLE_BVH + +} + +void btBvhTriangleMeshShape::partialRefitTree(const btVector3& aabbMin,const btVector3& aabbMax) +{ + m_bvh->refitPartial( m_meshInterface,aabbMin,aabbMax ); + + m_localAabbMin.setMin(aabbMin); + m_localAabbMax.setMax(aabbMax); +} + + +void btBvhTriangleMeshShape::refitTree() +{ + m_bvh->refit( m_meshInterface ); + + recalcLocalAabb(); +} + +btBvhTriangleMeshShape::~btBvhTriangleMeshShape() +{ + delete m_bvh; +} + +//perform bvh tree traversal and report overlapping triangles to 'callback' +void btBvhTriangleMeshShape::processAllTriangles(btTriangleCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const +{ + +#ifdef DISABLE_BVH + //brute force traverse all triangles + btTriangleMeshShape::processAllTriangles(callback,aabbMin,aabbMax); +#else + + //first get all the nodes + + + struct MyNodeOverlapCallback : public btNodeOverlapCallback + { + btStridingMeshInterface* m_meshInterface; + btTriangleCallback* m_callback; + btVector3 m_triangle[3]; + + + MyNodeOverlapCallback(btTriangleCallback* callback,btStridingMeshInterface* meshInterface) + :m_meshInterface(meshInterface), + m_callback(callback) + { + } + + virtual void processNode(int nodeSubPart, int nodeTriangleIndex) + { + const unsigned char *vertexbase; + int numverts; + PHY_ScalarType type; + int stride; + const unsigned char *indexbase; + int indexstride; + int numfaces; + PHY_ScalarType indicestype; + + + m_meshInterface->getLockedReadOnlyVertexIndexBase( + &vertexbase, + numverts, + type, + stride, + &indexbase, + indexstride, + numfaces, + indicestype, + nodeSubPart); + + int* gfxbase = (int*)(indexbase+nodeTriangleIndex*indexstride); + + const btVector3& meshScaling = m_meshInterface->getScaling(); + for (int j=2;j>=0;j--) + { + + int graphicsindex = gfxbase[j]; + + +#ifdef DEBUG_TRIANGLE_MESH + printf("%d ,",graphicsindex); +#endif //DEBUG_TRIANGLE_MESH + btScalar* graphicsbase = (btScalar*)(vertexbase+graphicsindex*stride); + + m_triangle[j] = btVector3( + graphicsbase[0]*meshScaling.getX(), + graphicsbase[1]*meshScaling.getY(), + graphicsbase[2]*meshScaling.getZ()); +#ifdef DEBUG_TRIANGLE_MESH + printf("triangle vertices:%f,%f,%f\n",triangle[j].x(),triangle[j].y(),triangle[j].z()); +#endif //DEBUG_TRIANGLE_MESH + } + + m_callback->processTriangle(m_triangle,nodeSubPart,nodeTriangleIndex); + m_meshInterface->unLockReadOnlyVertexBase(nodeSubPart); + } + + }; + + MyNodeOverlapCallback myNodeCallback(callback,m_meshInterface); + + m_bvh->reportAabbOverlappingNodex(&myNodeCallback,aabbMin,aabbMax); + + +#endif//DISABLE_BVH + + +} + + +void btBvhTriangleMeshShape::setLocalScaling(const btVector3& scaling) +{ + if ((getLocalScaling() -scaling).length2() > SIMD_EPSILON) + { + btTriangleMeshShape::setLocalScaling(scaling); + delete m_bvh; + ///m_localAabbMin/m_localAabbMax is already re-calculated in btTriangleMeshShape. We could just scale aabb, but this needs some more work + m_bvh = new btOptimizedBvh(); + //rebuild the bvh... + m_bvh->build(m_meshInterface,m_useQuantizedAabbCompression,m_localAabbMin,m_localAabbMax); + + } +} diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btBvhTriangleMeshShape.h b/extern/bullet2/src/BulletCollision/CollisionShapes/btBvhTriangleMeshShape.h new file mode 100644 index 00000000000..4914d9f959c --- /dev/null +++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btBvhTriangleMeshShape.h @@ -0,0 +1,75 @@ +/* +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_TRIANGLE_MESH_SHAPE_H +#define BVH_TRIANGLE_MESH_SHAPE_H + +#include "btTriangleMeshShape.h" +#include "btOptimizedBvh.h" + +///Bvh Concave triangle mesh is a static-triangle mesh shape with Bounding Volume Hierarchy optimization. +///Uses an interface to access the triangles to allow for sharing graphics/physics triangles. +ATTRIBUTE_ALIGNED16(class) btBvhTriangleMeshShape : public btTriangleMeshShape +{ + + btOptimizedBvh* m_bvh; + bool m_useQuantizedAabbCompression; + bool m_pad[12];////need padding due to alignment + +public: + + btBvhTriangleMeshShape() :btTriangleMeshShape(0) {}; + btBvhTriangleMeshShape(btStridingMeshInterface* meshInterface, bool useQuantizedAabbCompression); + + ///optionally pass in a larger bvh aabb, used for quantization. This allows for deformations within this aabb + btBvhTriangleMeshShape(btStridingMeshInterface* meshInterface, bool useQuantizedAabbCompression,const btVector3& bvhAabbMin,const btVector3& bvhAabbMax); + + virtual ~btBvhTriangleMeshShape(); + + + /* + virtual int getShapeType() const + { + return TRIANGLE_MESH_SHAPE_PROXYTYPE; + } + */ + + + + virtual void processAllTriangles(btTriangleCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const; + + void refitTree(); + + ///for a fast incremental refit of parts of the tree. Note: the entire AABB of the tree will become more conservative, it never shrinks + void partialRefitTree(const btVector3& aabbMin,const btVector3& aabbMax); + + //debugging + virtual char* getName()const {return "BVHTRIANGLEMESH";} + + + virtual void setLocalScaling(const btVector3& scaling); + + btOptimizedBvh* getOptimizedBvh() + { + return m_bvh; + } + bool usesQuantizedAabbCompression() const + { + return m_useQuantizedAabbCompression; + } +} +; + +#endif //BVH_TRIANGLE_MESH_SHAPE_H diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btCapsuleShape.cpp b/extern/bullet2/src/BulletCollision/CollisionShapes/btCapsuleShape.cpp new file mode 100644 index 00000000000..b7e15172da2 --- /dev/null +++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btCapsuleShape.cpp @@ -0,0 +1,146 @@ +/* +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 "btCapsuleShape.h" + +#include "BulletCollision/CollisionShapes/btCollisionMargin.h" +#include "LinearMath/btQuaternion.h" + +btCapsuleShape::btCapsuleShape(btScalar radius, btScalar height) +{ + m_implicitShapeDimensions.setValue(radius,0.5f*height,radius); +} + + + btVector3 btCapsuleShape::localGetSupportingVertexWithoutMargin(const btVector3& vec0)const +{ + + btVector3 supVec(0,0,0); + + btScalar maxDot(btScalar(-1e30)); + + btVector3 vec = vec0; + btScalar lenSqr = vec.length2(); + if (lenSqr < btScalar(0.0001)) + { + vec.setValue(1,0,0); + } else + { + btScalar rlen = btScalar(1.) / btSqrt(lenSqr ); + vec *= rlen; + } + + btVector3 vtx; + btScalar newDot; + + btScalar radius = getRadius(); + + + { + btVector3 pos(0,getHalfHeight(),0); + vtx = pos +vec*m_localScaling*(radius) - vec * getMargin(); + newDot = vec.dot(vtx); + if (newDot > maxDot) + { + maxDot = newDot; + supVec = vtx; + } + } + { + btVector3 pos(0,-getHalfHeight(),0); + vtx = pos +vec*m_localScaling*(radius) - vec * getMargin(); + newDot = vec.dot(vtx); + if (newDot > maxDot) + { + maxDot = newDot; + supVec = vtx; + } + } + + return supVec; + +} + + void btCapsuleShape::batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const +{ + + + btScalar radius = getRadius(); + + for (int j=0;j maxDot) + { + maxDot = newDot; + supportVerticesOut[j] = vtx; + } + } + { + btVector3 pos(0,-getHalfHeight(),0); + vtx = pos +vec*m_localScaling*(radius) - vec * getMargin(); + newDot = vec.dot(vtx); + if (newDot > maxDot) + { + maxDot = newDot; + supportVerticesOut[j] = vtx; + } + } + + } +} + + +void btCapsuleShape::calculateLocalInertia(btScalar mass,btVector3& inertia) +{ + //as an approximation, take the inertia of the box that bounds the spheres + + btTransform ident; + ident.setIdentity(); + + + btScalar radius = getRadius(); + + btVector3 halfExtents(radius,radius+getHalfHeight(),radius); + + btScalar margin = CONVEX_DISTANCE_MARGIN; + + btScalar lx=btScalar(2.)*(halfExtents[0]+margin); + btScalar ly=btScalar(2.)*(halfExtents[1]+margin); + btScalar lz=btScalar(2.)*(halfExtents[2]+margin); + const btScalar x2 = lx*lx; + const btScalar y2 = ly*ly; + const btScalar z2 = lz*lz; + const btScalar scaledmass = mass * btScalar(.08333333); + + inertia[0] = scaledmass * (y2+z2); + inertia[1] = scaledmass * (x2+z2); + inertia[2] = scaledmass * (x2+y2); + +} + + + + + diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btCapsuleShape.h b/extern/bullet2/src/BulletCollision/CollisionShapes/btCapsuleShape.h new file mode 100644 index 00000000000..27da8adefa5 --- /dev/null +++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btCapsuleShape.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 BT_CAPSULE_SHAPE_H +#define BT_CAPSULE_SHAPE_H + +#include "btConvexShape.h" +#include "../BroadphaseCollision/btBroadphaseProxy.h" // for the types + + +///btCapsuleShape represents a capsule around the Y axis +///A more general solution that can represent capsules is the btMultiSphereShape +class btCapsuleShape : public btConvexShape +{ + +public: + btCapsuleShape(btScalar radius,btScalar height); + + ///CollisionShape Interface + virtual void calculateLocalInertia(btScalar mass,btVector3& inertia); + + /// btConvexShape Interface + virtual btVector3 localGetSupportingVertexWithoutMargin(const btVector3& vec)const; + + virtual void batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const; + + virtual int getShapeType() const { return CAPSULE_SHAPE_PROXYTYPE; } + + virtual char* getName()const + { + return "CapsuleShape"; + } + + btScalar getRadius() const + { + return m_implicitShapeDimensions.getX(); + } + + btScalar getHalfHeight() const + { + return m_implicitShapeDimensions.getY(); + } + +}; + + + +#endif //BT_CAPSULE_SHAPE_H diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btCollisionMargin.h b/extern/bullet2/src/BulletCollision/CollisionShapes/btCollisionMargin.h new file mode 100644 index 00000000000..4730264d3df --- /dev/null +++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btCollisionMargin.h @@ -0,0 +1,26 @@ +/* +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 COLLISION_MARGIN_H +#define COLLISION_MARGIN_H + +//used by Gjk and some other algorithms + +#define CONVEX_DISTANCE_MARGIN btScalar(0.04)// btScalar(0.1)//;//btScalar(0.01) + + + +#endif //COLLISION_MARGIN_H + diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btCollisionShape.cpp b/extern/bullet2/src/BulletCollision/CollisionShapes/btCollisionShape.cpp new file mode 100644 index 00000000000..81d82428f4c --- /dev/null +++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btCollisionShape.cpp @@ -0,0 +1,85 @@ +/* +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 "BulletCollision/CollisionShapes/btCollisionShape.h" + + +/* + Make sure this dummy function never changes so that it + can be used by probes that are checking whether the + library is actually installed. +*/ +extern "C" void btBulletCollisionProbe () {} + + + +void btCollisionShape::getBoundingSphere(btVector3& center,btScalar& radius) const +{ + btTransform tr; + tr.setIdentity(); + btVector3 aabbMin,aabbMax; + + getAabb(tr,aabbMin,aabbMax); + + radius = (aabbMax-aabbMin).length()*btScalar(0.5); + center = (aabbMin+aabbMax)*btScalar(0.5); +} + +btScalar btCollisionShape::getAngularMotionDisc() const +{ + btVector3 center; + btScalar disc; + getBoundingSphere(center,disc); + disc += (center).length(); + return disc; +} + +void btCollisionShape::calculateTemporalAabb(const btTransform& curTrans,const btVector3& linvel,const btVector3& angvel,btScalar timeStep, btVector3& temporalAabbMin,btVector3& temporalAabbMax) +{ + //start with static aabb + getAabb(curTrans,temporalAabbMin,temporalAabbMax); + + btScalar temporalAabbMaxx = temporalAabbMax.getX(); + btScalar temporalAabbMaxy = temporalAabbMax.getY(); + btScalar temporalAabbMaxz = temporalAabbMax.getZ(); + btScalar temporalAabbMinx = temporalAabbMin.getX(); + btScalar temporalAabbMiny = temporalAabbMin.getY(); + btScalar temporalAabbMinz = temporalAabbMin.getZ(); + + // add linear motion + btVector3 linMotion = linvel*timeStep; + //todo: simd would have a vector max/min operation, instead of per-element access + if (linMotion.x() > btScalar(0.)) + temporalAabbMaxx += linMotion.x(); + else + temporalAabbMinx += linMotion.x(); + if (linMotion.y() > btScalar(0.)) + temporalAabbMaxy += linMotion.y(); + else + temporalAabbMiny += linMotion.y(); + if (linMotion.z() > btScalar(0.)) + temporalAabbMaxz += linMotion.z(); + else + temporalAabbMinz += linMotion.z(); + + //add conservative angular motion + btScalar angularMotion = angvel.length() * getAngularMotionDisc() * timeStep; + btVector3 angularMotion3d(angularMotion,angularMotion,angularMotion); + temporalAabbMin = btVector3(temporalAabbMinx,temporalAabbMiny,temporalAabbMinz); + temporalAabbMax = btVector3(temporalAabbMaxx,temporalAabbMaxy,temporalAabbMaxz); + + temporalAabbMin -= angularMotion3d; + temporalAabbMax += angularMotion3d; +} diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btCollisionShape.h b/extern/bullet2/src/BulletCollision/CollisionShapes/btCollisionShape.h new file mode 100644 index 00000000000..96268734a83 --- /dev/null +++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btCollisionShape.h @@ -0,0 +1,94 @@ +/* +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 COLLISION_SHAPE_H +#define COLLISION_SHAPE_H + +#include "../../LinearMath/btTransform.h" +#include "../../LinearMath/btVector3.h" +#include "../../LinearMath/btMatrix3x3.h" +#include "../../LinearMath/btPoint3.h" +#include "../BroadphaseCollision/btBroadphaseProxy.h" //for the shape types + +///btCollisionShape provides interface for collision shapes that can be shared among btCollisionObjects. +class btCollisionShape +{ +public: + + btCollisionShape() + { + } + virtual ~btCollisionShape() + { + } + + ///getAabb returns the axis aligned bounding box in the coordinate frame of the given transform t. + virtual void getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const =0; + + virtual void getBoundingSphere(btVector3& center,btScalar& radius) const; + + ///getAngularMotionDisc returns the maximus radius needed for Conservative Advancement to handle time-of-impact with rotations. + virtual btScalar getAngularMotionDisc() const; + + + ///calculateTemporalAabb calculates the enclosing aabb for the moving object over interval [0..timeStep) + ///result is conservative + void calculateTemporalAabb(const btTransform& curTrans,const btVector3& linvel,const btVector3& angvel,btScalar timeStep, btVector3& temporalAabbMin,btVector3& temporalAabbMax); + +#ifndef __SPU__ + + inline bool isPolyhedral() const + { + return btBroadphaseProxy::isPolyhedral(getShapeType()); + } + + inline bool isConvex() const + { + return btBroadphaseProxy::isConvex(getShapeType()); + } + inline bool isConcave() const + { + return btBroadphaseProxy::isConcave(getShapeType()); + } + inline bool isCompound() const + { + return btBroadphaseProxy::isCompound(getShapeType()); + } + + ///isInfinite is used to catch simulation error (aabb check) + inline bool isInfinite() const + { + return btBroadphaseProxy::isInfinite(getShapeType()); + } + + virtual int getShapeType() const=0; + virtual void setLocalScaling(const btVector3& scaling) =0; + virtual const btVector3& getLocalScaling() const =0; + virtual void calculateLocalInertia(btScalar mass,btVector3& inertia) = 0; + + +//debugging support + virtual char* getName()const =0 ; +#endif //__SPU__ + + + + virtual void setMargin(btScalar margin) = 0; + virtual btScalar getMargin() const = 0; + +}; + +#endif //COLLISION_SHAPE_H + diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btCompoundShape.cpp b/extern/bullet2/src/BulletCollision/CollisionShapes/btCompoundShape.cpp new file mode 100644 index 00000000000..a4712b3e925 --- /dev/null +++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btCompoundShape.cpp @@ -0,0 +1,100 @@ +/* +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 "btCompoundShape.h" + + +#include "btCollisionShape.h" + + +btCompoundShape::btCompoundShape() +:m_localAabbMin(btScalar(1e30),btScalar(1e30),btScalar(1e30)), +m_localAabbMax(btScalar(-1e30),btScalar(-1e30),btScalar(-1e30)), +m_aabbTree(0), +m_collisionMargin(btScalar(0.)), +m_localScaling(btScalar(1.),btScalar(1.),btScalar(1.)) +{ +} + + +btCompoundShape::~btCompoundShape() +{ +} + +void btCompoundShape::addChildShape(const btTransform& localTransform,btCollisionShape* shape) +{ + m_childTransforms.push_back(localTransform); + m_childShapes.push_back(shape); + + //extend the local aabbMin/aabbMax + btVector3 localAabbMin,localAabbMax; + shape->getAabb(localTransform,localAabbMin,localAabbMax); + for (int i=0;i<3;i++) + { + if (m_localAabbMin[i] > localAabbMin[i]) + { + m_localAabbMin[i] = localAabbMin[i]; + } + if (m_localAabbMax[i] < localAabbMax[i]) + { + m_localAabbMax[i] = localAabbMax[i]; + } + + } +} + + + + ///getAabb's default implementation is brute force, expected derived classes to implement a fast dedicated version +void btCompoundShape::getAabb(const btTransform& trans,btVector3& aabbMin,btVector3& aabbMax) const +{ + btVector3 localHalfExtents = btScalar(0.5)*(m_localAabbMax-m_localAabbMin); + btVector3 localCenter = btScalar(0.5)*(m_localAabbMax+m_localAabbMin); + + btMatrix3x3 abs_b = trans.getBasis().absolute(); + + btPoint3 center = trans(localCenter); + + btVector3 extent = btVector3(abs_b[0].dot(localHalfExtents), + abs_b[1].dot(localHalfExtents), + abs_b[2].dot(localHalfExtents)); + extent += btVector3(getMargin(),getMargin(),getMargin()); + + aabbMin = center - extent; + aabbMax = center + extent; +} + +void btCompoundShape::calculateLocalInertia(btScalar mass,btVector3& inertia) +{ + //approximation: take the inertia from the aabb for now + btTransform ident; + ident.setIdentity(); + btVector3 aabbMin,aabbMax; + getAabb(ident,aabbMin,aabbMax); + + btVector3 halfExtents = (aabbMax-aabbMin)*btScalar(0.5); + + btScalar lx=btScalar(2.)*(halfExtents.x()); + btScalar ly=btScalar(2.)*(halfExtents.y()); + btScalar lz=btScalar(2.)*(halfExtents.z()); + + inertia[0] = mass/(btScalar(12.0)) * (ly*ly + lz*lz); + inertia[1] = mass/(btScalar(12.0)) * (lx*lx + lz*lz); + inertia[2] = mass/(btScalar(12.0)) * (lx*lx + ly*ly); + +} + + + diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btCompoundShape.h b/extern/bullet2/src/BulletCollision/CollisionShapes/btCompoundShape.h new file mode 100644 index 00000000000..86dc1f80947 --- /dev/null +++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btCompoundShape.h @@ -0,0 +1,117 @@ +/* +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 COMPOUND_SHAPE_H +#define COMPOUND_SHAPE_H + +#include "btCollisionShape.h" + +#include "../../LinearMath/btVector3.h" +#include "../../LinearMath/btTransform.h" +#include "../../LinearMath/btMatrix3x3.h" +#include "btCollisionMargin.h" +#include "../../LinearMath/btAlignedObjectArray.h" + +class btOptimizedBvh; + +/// btCompoundShape allows to store multiple other btCollisionShapes +/// This allows for concave collision objects. This is more general then the Static Concave btTriangleMeshShape. +class btCompoundShape : public btCollisionShape +{ + btAlignedObjectArray m_childTransforms; + btAlignedObjectArray m_childShapes; + btVector3 m_localAabbMin; + btVector3 m_localAabbMax; + + btOptimizedBvh* m_aabbTree; + +public: + btCompoundShape(); + + virtual ~btCompoundShape(); + + void addChildShape(const btTransform& localTransform,btCollisionShape* shape); + + int getNumChildShapes() const + { + return int (m_childShapes.size()); + } + + btCollisionShape* getChildShape(int index) + { + return m_childShapes[index]; + } + const btCollisionShape* getChildShape(int index) const + { + return m_childShapes[index]; + } + + btTransform& getChildTransform(int index) + { + return m_childTransforms[index]; + } + const btTransform& getChildTransform(int index) const + { + return m_childTransforms[index]; + } + + ///getAabb's default implementation is brute force, expected derived classes to implement a fast dedicated version + void getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const; + + + virtual void setLocalScaling(const btVector3& scaling) + { + m_localScaling = scaling; + } + virtual const btVector3& getLocalScaling() const + { + return m_localScaling; + } + + virtual void calculateLocalInertia(btScalar mass,btVector3& inertia); + + virtual int getShapeType() const { return COMPOUND_SHAPE_PROXYTYPE;} + + virtual void setMargin(btScalar margin) + { + m_collisionMargin = margin; + } + virtual btScalar getMargin() const + { + return m_collisionMargin; + } + virtual char* getName()const + { + return "Compound"; + } + + //this is optional, but should make collision queries faster, by culling non-overlapping nodes + void createAabbTreeFromChildren(); + + const btOptimizedBvh* getAabbTree() const + { + return m_aabbTree; + } + +private: + btScalar m_collisionMargin; +protected: + btVector3 m_localScaling; + +}; + + + +#endif //COMPOUND_SHAPE_H diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btConcaveShape.cpp b/extern/bullet2/src/BulletCollision/CollisionShapes/btConcaveShape.cpp new file mode 100644 index 00000000000..5103500a012 --- /dev/null +++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btConcaveShape.cpp @@ -0,0 +1,28 @@ + +/* +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 "btConcaveShape.h" + +btConcaveShape::btConcaveShape() : m_collisionMargin(btScalar(0.)) +{ + +} + +btConcaveShape::~btConcaveShape() +{ + +} diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btConcaveShape.h b/extern/bullet2/src/BulletCollision/CollisionShapes/btConcaveShape.h new file mode 100644 index 00000000000..73f974e4ee9 --- /dev/null +++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btConcaveShape.h @@ -0,0 +1,50 @@ +/* +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_SHAPE_H +#define CONCAVE_SHAPE_H + +#include "btCollisionShape.h" +#include "../BroadphaseCollision/btBroadphaseProxy.h" // for the types +#include "btTriangleCallback.h" + + +///Concave shape proves an interface concave shapes that can produce triangles that overlapping a given AABB. +///Static triangle mesh, infinite plane, height field/landscapes are example that implement this interface. +class btConcaveShape : public btCollisionShape +{ +protected: + btScalar m_collisionMargin; + +public: + btConcaveShape(); + + virtual ~btConcaveShape(); + + virtual void processAllTriangles(btTriangleCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const = 0; + + virtual btScalar getMargin() const { + return m_collisionMargin; + } + virtual void setMargin(btScalar collisionMargin) + { + m_collisionMargin = collisionMargin; + } + + + +}; + +#endif //CONCAVE_SHAPE_H diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btConeShape.cpp b/extern/bullet2/src/BulletCollision/CollisionShapes/btConeShape.cpp new file mode 100644 index 00000000000..207b3024bc3 --- /dev/null +++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btConeShape.cpp @@ -0,0 +1,133 @@ +/* +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 "btConeShape.h" +#include "LinearMath/btPoint3.h" + + + +btConeShape::btConeShape (btScalar radius,btScalar height): +m_radius (radius), +m_height(height) +{ + setConeUpIndex(1); + btVector3 halfExtents; + m_sinAngle = (m_radius / btSqrt(m_radius * m_radius + m_height * m_height)); +} + +btConeShapeZ::btConeShapeZ (btScalar radius,btScalar height): +btConeShape(radius,height) +{ + setConeUpIndex(2); +} + +btConeShapeX::btConeShapeX (btScalar radius,btScalar height): +btConeShape(radius,height) +{ + setConeUpIndex(0); +} + +///choose upAxis index +void btConeShape::setConeUpIndex(int upIndex) +{ + switch (upIndex) + { + case 0: + m_coneIndices[0] = 1; + m_coneIndices[1] = 0; + m_coneIndices[2] = 2; + break; + case 1: + m_coneIndices[0] = 0; + m_coneIndices[1] = 1; + m_coneIndices[2] = 2; + break; + case 2: + m_coneIndices[0] = 0; + m_coneIndices[1] = 2; + m_coneIndices[2] = 1; + break; + default: + assert(0); + }; +} + +btVector3 btConeShape::coneLocalSupport(const btVector3& v) const +{ + + btScalar halfHeight = m_height * btScalar(0.5); + + if (v[m_coneIndices[1]] > v.length() * m_sinAngle) + { + btVector3 tmp; + + tmp[m_coneIndices[0]] = btScalar(0.); + tmp[m_coneIndices[1]] = halfHeight; + tmp[m_coneIndices[2]] = btScalar(0.); + return tmp; + } + else { + btScalar s = btSqrt(v[m_coneIndices[0]] * v[m_coneIndices[0]] + v[m_coneIndices[2]] * v[m_coneIndices[2]]); + if (s > SIMD_EPSILON) { + btScalar d = m_radius / s; + btVector3 tmp; + tmp[m_coneIndices[0]] = v[m_coneIndices[0]] * d; + tmp[m_coneIndices[1]] = -halfHeight; + tmp[m_coneIndices[2]] = v[m_coneIndices[2]] * d; + return tmp; + } + else { + btVector3 tmp; + tmp[m_coneIndices[0]] = btScalar(0.); + tmp[m_coneIndices[1]] = -halfHeight; + tmp[m_coneIndices[2]] = btScalar(0.); + return tmp; + } + } + +} + +btVector3 btConeShape::localGetSupportingVertexWithoutMargin(const btVector3& vec) const +{ + return coneLocalSupport(vec); +} + +void btConeShape::batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const +{ + for (int i=0;i maxDot) + { + maxDot = newDot; + supVec = vtx; + } + } + return supVec; +} + +void btConvexHullShape::batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const +{ + btScalar newDot; + //use 'w' component of supportVerticesOut? + { + for (int i=0;i supportVerticesOut[j][3]) + { + //WARNING: don't swap next lines, the w component would get overwritten! + supportVerticesOut[j] = vtx; + supportVerticesOut[j][3] = newDot; + } + } + } + + + +} + + + +btVector3 btConvexHullShape::localGetSupportingVertex(const btVector3& vec)const +{ + btVector3 supVertex = localGetSupportingVertexWithoutMargin(vec); + + if ( getMargin()!=btScalar(0.) ) + { + btVector3 vecnorm = vec; + if (vecnorm .length2() < (SIMD_EPSILON*SIMD_EPSILON)) + { + vecnorm.setValue(btScalar(-1.),btScalar(-1.),btScalar(-1.)); + } + vecnorm.normalize(); + supVertex+= getMargin() * vecnorm; + } + return supVertex; +} + + + + + + + + + +//currently just for debugging (drawing), perhaps future support for algebraic continuous collision detection +//Please note that you can debug-draw btConvexHullShape with the Raytracer Demo +int btConvexHullShape::getNumVertices() const +{ + return m_points.size(); +} + +int btConvexHullShape::getNumEdges() const +{ + return m_points.size(); +} + +void btConvexHullShape::getEdge(int i,btPoint3& pa,btPoint3& pb) const +{ + + int index0 = i%m_points.size(); + int index1 = (i+1)%m_points.size(); + pa = m_points[index0]*m_localScaling; + pb = m_points[index1]*m_localScaling; +} + +void btConvexHullShape::getVertex(int i,btPoint3& vtx) const +{ + vtx = m_points[i]*m_localScaling; +} + +int btConvexHullShape::getNumPlanes() const +{ + return 0; +} + +void btConvexHullShape::getPlane(btVector3& ,btPoint3& ,int ) const +{ + + btAssert(0); +} + +//not yet +bool btConvexHullShape::isInside(const btPoint3& ,btScalar ) const +{ + assert(0); + return false; +} + diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btConvexHullShape.h b/extern/bullet2/src/BulletCollision/CollisionShapes/btConvexHullShape.h new file mode 100644 index 00000000000..3fd5e382525 --- /dev/null +++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btConvexHullShape.h @@ -0,0 +1,76 @@ +/* +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 CONVEX_HULL_SHAPE_H +#define CONVEX_HULL_SHAPE_H + +#include "btPolyhedralConvexShape.h" +#include "../BroadphaseCollision/btBroadphaseProxy.h" // for the types +#include "../../LinearMath/btAlignedObjectArray.h" + +///ConvexHullShape implements an implicit (getSupportingVertex) Convex Hull of a Point Cloud (vertices) +///No connectivity is needed. localGetSupportingVertex iterates linearly though all vertices. +///on modern hardware, due to cache coherency this isn't that bad. Complex algorithms tend to trash the cash. +///(memory is much slower then the cpu) +ATTRIBUTE_ALIGNED16(class) btConvexHullShape : public btPolyhedralConvexShape +{ + btAlignedObjectArray m_points; + +public: + + + ///this constructor optionally takes in a pointer to points. Each point is assumed to be 3 consecutive btScalar (x,y,z), the striding defines the number of bytes between each point, in memory. + ///It is easier to not pass any points in the constructor, and just add one point at a time, using addPoint. + ///btConvexHullShape make an internal copy of the points. + btConvexHullShape(const btScalar* points=0,int numPoints=0, int stride=sizeof(btPoint3)); + + void addPoint(const btPoint3& point); + + btPoint3* getPoints() + { + return &m_points[0]; + } + + int getNumPoints() + { + return m_points.size(); + } + + virtual btVector3 localGetSupportingVertex(const btVector3& vec)const; + virtual btVector3 localGetSupportingVertexWithoutMargin(const btVector3& vec)const; + virtual void batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const; + + + virtual int getShapeType()const { return CONVEX_HULL_SHAPE_PROXYTYPE; } + + //debugging + virtual char* getName()const {return "Convex";} + + + virtual int getNumVertices() const; + virtual int getNumEdges() const; + virtual void getEdge(int i,btPoint3& pa,btPoint3& pb) const; + virtual void getVertex(int i,btPoint3& vtx) const; + virtual int getNumPlanes() const; + virtual void getPlane(btVector3& planeNormal,btPoint3& planeSupport,int i ) const; + virtual bool isInside(const btPoint3& pt,btScalar tolerance) const; + + + +}; + + +#endif //CONVEX_HULL_SHAPE_H + diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btConvexShape.cpp b/extern/bullet2/src/BulletCollision/CollisionShapes/btConvexShape.cpp new file mode 100644 index 00000000000..7edf1ea6db8 --- /dev/null +++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btConvexShape.cpp @@ -0,0 +1,77 @@ +/* +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 "btConvexShape.h" + + +btConvexShape::btConvexShape() +: m_localScaling(btScalar(1.),btScalar(1.),btScalar(1.)), +m_collisionMargin(CONVEX_DISTANCE_MARGIN) +{ +} + + +void btConvexShape::setLocalScaling(const btVector3& scaling) +{ + m_localScaling = scaling; +} + + + +void btConvexShape::getAabbSlow(const btTransform& trans,btVector3&minAabb,btVector3&maxAabb) const +{ + + btScalar margin = getMargin(); + for (int i=0;i<3;i++) + { + btVector3 vec(btScalar(0.),btScalar(0.),btScalar(0.)); + vec[i] = btScalar(1.); + + btVector3 sv = localGetSupportingVertex(vec*trans.getBasis()); + + btVector3 tmp = trans(sv); + maxAabb[i] = tmp[i]+margin; + vec[i] = btScalar(-1.); + tmp = trans(localGetSupportingVertex(vec*trans.getBasis())); + minAabb[i] = tmp[i]-margin; + } +}; + + +btVector3 btConvexShape::localGetSupportingVertex(const btVector3& vec)const +{ +#ifndef __SPU__ + + btVector3 supVertex = localGetSupportingVertexWithoutMargin(vec); + + if ( getMargin()!=btScalar(0.) ) + { + btVector3 vecnorm = vec; + if (vecnorm .length2() < (SIMD_EPSILON*SIMD_EPSILON)) + { + vecnorm.setValue(btScalar(-1.),btScalar(-1.),btScalar(-1.)); + } + vecnorm.normalize(); + supVertex+= getMargin() * vecnorm; + } + return supVertex; + +#else + return btVector3(0,0,0); +#endif //__SPU__ + + } + + diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btConvexShape.h b/extern/bullet2/src/BulletCollision/CollisionShapes/btConvexShape.h new file mode 100644 index 00000000000..746f383dfc7 --- /dev/null +++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btConvexShape.h @@ -0,0 +1,127 @@ +/* +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 CONVEX_SHAPE_INTERFACE1 +#define CONVEX_SHAPE_INTERFACE1 + +#include "btCollisionShape.h" + +#include "../../LinearMath/btVector3.h" +#include "../../LinearMath/btTransform.h" +#include "../../LinearMath/btMatrix3x3.h" +#include "btCollisionMargin.h" + +//todo: get rid of this btConvexCastResult thing! +struct btConvexCastResult; +#define MAX_PREFERRED_PENETRATION_DIRECTIONS 10 + +/// btConvexShape is an abstract shape interface. +/// The explicit part provides plane-equations, the implicit part provides GetClosestPoint interface. +/// used in combination with GJK or btConvexCast +ATTRIBUTE_ALIGNED16(class) btConvexShape : public btCollisionShape +{ + +protected: + + //local scaling. collisionMargin is not scaled ! + btVector3 m_localScaling; + + btVector3 m_implicitShapeDimensions; + + btScalar m_collisionMargin; + + btScalar m_padding[2]; + + + + +public: + btConvexShape(); + + virtual ~btConvexShape() + { + + } + + + virtual btVector3 localGetSupportingVertex(const btVector3& vec)const; +#ifndef __SPU__ + virtual btVector3 localGetSupportingVertexWithoutMargin(const btVector3& vec) const= 0; + + //notice that the vectors should be unit length + virtual void batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const= 0; +#endif //#ifndef __SPU__ + + const btVector3& getImplicitShapeDimensions() const + { + return m_implicitShapeDimensions; + } + + ///getAabb's default implementation is brute force, expected derived classes to implement a fast dedicated version + void getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const + { + getAabbSlow(t,aabbMin,aabbMax); + } + + + + virtual void getAabbSlow(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const; + + + virtual void setLocalScaling(const btVector3& scaling); + virtual const btVector3& getLocalScaling() const + { + return m_localScaling; + } + + const btVector3& getLocalScalingNV() const + { + return m_localScaling; + } + + virtual void setMargin(btScalar margin) + { + m_collisionMargin = margin; + } + virtual btScalar getMargin() const + { + return m_collisionMargin; + } + + btScalar getMarginNV() const + { + return m_collisionMargin; + } + + virtual int getNumPreferredPenetrationDirections() const + { + return 0; + } + + virtual void getPreferredPenetrationDirection(int index, btVector3& penetrationVector) const + { + (void)penetrationVector; + (void)index; + btAssert(0); + } + + + +} +; + + + +#endif //CONVEX_SHAPE_INTERFACE1 diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btConvexTriangleMeshShape.cpp b/extern/bullet2/src/BulletCollision/CollisionShapes/btConvexTriangleMeshShape.cpp new file mode 100644 index 00000000000..6941030b15f --- /dev/null +++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btConvexTriangleMeshShape.cpp @@ -0,0 +1,205 @@ +/* +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 "btConvexTriangleMeshShape.h" +#include "BulletCollision/CollisionShapes/btCollisionMargin.h" + +#include "LinearMath/btQuaternion.h" +#include "BulletCollision/CollisionShapes/btStridingMeshInterface.h" + + +btConvexTriangleMeshShape ::btConvexTriangleMeshShape (btStridingMeshInterface* meshInterface) +:m_stridingMesh(meshInterface) +{ + recalcLocalAabb(); +} + + + + +///It's not nice to have all this virtual function overhead, so perhaps we can also gather the points once +///but then we are duplicating +class LocalSupportVertexCallback: public btInternalTriangleIndexCallback +{ + + btVector3 m_supportVertexLocal; +public: + + btScalar m_maxDot; + btVector3 m_supportVecLocal; + + LocalSupportVertexCallback(const btVector3& supportVecLocal) + : m_supportVertexLocal(btScalar(0.),btScalar(0.),btScalar(0.)), + m_maxDot(btScalar(-1e30)), + m_supportVecLocal(supportVecLocal) + { + } + + virtual void internalProcessTriangleIndex(btVector3* triangle,int partId,int triangleIndex) + { + (void)triangleIndex; + (void)partId; + + for (int i=0;i<3;i++) + { + btScalar dot = m_supportVecLocal.dot(triangle[i]); + if (dot > m_maxDot) + { + m_maxDot = dot; + m_supportVertexLocal = triangle[i]; + } + } + } + + btVector3 GetSupportVertexLocal() + { + return m_supportVertexLocal; + } + +}; + + + + + +btVector3 btConvexTriangleMeshShape::localGetSupportingVertexWithoutMargin(const btVector3& vec0)const +{ + btVector3 supVec(btScalar(0.),btScalar(0.),btScalar(0.)); + + btVector3 vec = vec0; + btScalar lenSqr = vec.length2(); + if (lenSqr < btScalar(0.0001)) + { + vec.setValue(1,0,0); + } else + { + btScalar rlen = btScalar(1.) / btSqrt(lenSqr ); + vec *= rlen; + } + + LocalSupportVertexCallback supportCallback(vec); + btVector3 aabbMax(btScalar(1e30),btScalar(1e30),btScalar(1e30)); + m_stridingMesh->InternalProcessAllTriangles(&supportCallback,-aabbMax,aabbMax); + supVec = supportCallback.GetSupportVertexLocal(); + + return supVec; +} + +void btConvexTriangleMeshShape::batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const +{ + //use 'w' component of supportVerticesOut? + { + for (int i=0;iInternalProcessAllTriangles(&supportCallback,-aabbMax,aabbMax); + supportVerticesOut[j] = supportCallback.GetSupportVertexLocal(); + } + +} + + + +btVector3 btConvexTriangleMeshShape::localGetSupportingVertex(const btVector3& vec)const +{ + btVector3 supVertex = localGetSupportingVertexWithoutMargin(vec); + + if ( getMargin()!=btScalar(0.) ) + { + btVector3 vecnorm = vec; + if (vecnorm .length2() < (SIMD_EPSILON*SIMD_EPSILON)) + { + vecnorm.setValue(btScalar(-1.),btScalar(-1.),btScalar(-1.)); + } + vecnorm.normalize(); + supVertex+= getMargin() * vecnorm; + } + return supVertex; +} + + + + + + + + + +//currently just for debugging (drawing), perhaps future support for algebraic continuous collision detection +//Please note that you can debug-draw btConvexTriangleMeshShape with the Raytracer Demo +int btConvexTriangleMeshShape::getNumVertices() const +{ + //cache this? + return 0; + +} + +int btConvexTriangleMeshShape::getNumEdges() const +{ + return 0; +} + +void btConvexTriangleMeshShape::getEdge(int ,btPoint3& ,btPoint3& ) const +{ + btAssert(0); +} + +void btConvexTriangleMeshShape::getVertex(int ,btPoint3& ) const +{ + btAssert(0); +} + +int btConvexTriangleMeshShape::getNumPlanes() const +{ + return 0; +} + +void btConvexTriangleMeshShape::getPlane(btVector3& ,btPoint3& ,int ) const +{ + btAssert(0); +} + +//not yet +bool btConvexTriangleMeshShape::isInside(const btPoint3& ,btScalar ) const +{ + btAssert(0); + return false; +} + + + +void btConvexTriangleMeshShape::setLocalScaling(const btVector3& scaling) +{ + m_stridingMesh->setScaling(scaling); + + recalcLocalAabb(); + +} + + +const btVector3& btConvexTriangleMeshShape::getLocalScaling() const +{ + return m_stridingMesh->getScaling(); +} diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btConvexTriangleMeshShape.h b/extern/bullet2/src/BulletCollision/CollisionShapes/btConvexTriangleMeshShape.h new file mode 100644 index 00000000000..34ee7af744c --- /dev/null +++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btConvexTriangleMeshShape.h @@ -0,0 +1,51 @@ +#ifndef CONVEX_TRIANGLEMESH_SHAPE_H +#define CONVEX_TRIANGLEMESH_SHAPE_H + + +#include "btPolyhedralConvexShape.h" +#include "../BroadphaseCollision/btBroadphaseProxy.h" // for the types + + +/// btConvexTriangleMeshShape is a convex hull of a triangle mesh. If you just have a point cloud, you can use btConvexHullShape instead. +/// It uses the btStridingMeshInterface instead of a point cloud. This can avoid the duplication of the triangle mesh data. +class btConvexTriangleMeshShape : public btPolyhedralConvexShape +{ + + class btStridingMeshInterface* m_stridingMesh; + +public: + btConvexTriangleMeshShape(btStridingMeshInterface* meshInterface); + + class btStridingMeshInterface* getStridingMesh() + { + return m_stridingMesh; + } + + virtual btVector3 localGetSupportingVertex(const btVector3& vec)const; + virtual btVector3 localGetSupportingVertexWithoutMargin(const btVector3& vec)const; + virtual void batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const; + + virtual int getShapeType()const { return CONVEX_TRIANGLEMESH_SHAPE_PROXYTYPE; } + + //debugging + virtual char* getName()const {return "ConvexTrimesh";} + + virtual int getNumVertices() const; + virtual int getNumEdges() const; + virtual void getEdge(int i,btPoint3& pa,btPoint3& pb) const; + virtual void getVertex(int i,btPoint3& vtx) const; + virtual int getNumPlanes() const; + virtual void getPlane(btVector3& planeNormal,btPoint3& planeSupport,int i ) const; + virtual bool isInside(const btPoint3& pt,btScalar tolerance) const; + + + virtual void setLocalScaling(const btVector3& scaling); + virtual const btVector3& getLocalScaling() const; + +}; + + + +#endif //CONVEX_TRIANGLEMESH_SHAPE_H + + diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btCylinderShape.cpp b/extern/bullet2/src/BulletCollision/CollisionShapes/btCylinderShape.cpp new file mode 100644 index 00000000000..1666afb3b88 --- /dev/null +++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btCylinderShape.cpp @@ -0,0 +1,206 @@ +/* +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 "btCylinderShape.h" +#include "LinearMath/btPoint3.h" + +btCylinderShape::btCylinderShape (const btVector3& halfExtents) +:btBoxShape(halfExtents), +m_upAxis(1) +{ + recalcLocalAabb(); +} + + +btCylinderShapeX::btCylinderShapeX (const btVector3& halfExtents) +:btCylinderShape(halfExtents) +{ + m_upAxis = 0; + recalcLocalAabb(); +} + + +btCylinderShapeZ::btCylinderShapeZ (const btVector3& halfExtents) +:btCylinderShape(halfExtents) +{ + m_upAxis = 2; + recalcLocalAabb(); +} + +void btCylinderShape::getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const +{ + //skip the box 'getAabb' + btPolyhedralConvexShape::getAabb(t,aabbMin,aabbMax); +} + + +inline btVector3 CylinderLocalSupportX(const btVector3& halfExtents,const btVector3& v) +{ +const int cylinderUpAxis = 0; +const int XX = 1; +const int YY = 0; +const int ZZ = 2; + + //mapping depends on how cylinder local orientation is + // extents of the cylinder is: X,Y is for radius, and Z for height + + + btScalar radius = halfExtents[XX]; + btScalar halfHeight = halfExtents[cylinderUpAxis]; + + + btVector3 tmp; + btScalar d ; + + btScalar s = btSqrt(v[XX] * v[XX] + v[ZZ] * v[ZZ]); + if (s != btScalar(0.0)) + { + d = radius / s; + tmp[XX] = v[XX] * d; + tmp[YY] = v[YY] < 0.0 ? -halfHeight : halfHeight; + tmp[ZZ] = v[ZZ] * d; + return tmp; + } + else + { + tmp[XX] = radius; + tmp[YY] = v[YY] < 0.0 ? -halfHeight : halfHeight; + tmp[ZZ] = btScalar(0.0); + return tmp; + } + + +} + + + + + + +inline btVector3 CylinderLocalSupportY(const btVector3& halfExtents,const btVector3& v) +{ + +const int cylinderUpAxis = 1; +const int XX = 0; +const int YY = 1; +const int ZZ = 2; + + + btScalar radius = halfExtents[XX]; + btScalar halfHeight = halfExtents[cylinderUpAxis]; + + + btVector3 tmp; + btScalar d ; + + btScalar s = btSqrt(v[XX] * v[XX] + v[ZZ] * v[ZZ]); + if (s != btScalar(0.0)) + { + d = radius / s; + tmp[XX] = v[XX] * d; + tmp[YY] = v[YY] < 0.0 ? -halfHeight : halfHeight; + tmp[ZZ] = v[ZZ] * d; + return tmp; + } + else + { + tmp[XX] = radius; + tmp[YY] = v[YY] < 0.0 ? -halfHeight : halfHeight; + tmp[ZZ] = btScalar(0.0); + return tmp; + } + +} + +inline btVector3 CylinderLocalSupportZ(const btVector3& halfExtents,const btVector3& v) +{ +const int cylinderUpAxis = 2; +const int XX = 0; +const int YY = 2; +const int ZZ = 1; + + //mapping depends on how cylinder local orientation is + // extents of the cylinder is: X,Y is for radius, and Z for height + + + btScalar radius = halfExtents[XX]; + btScalar halfHeight = halfExtents[cylinderUpAxis]; + + + btVector3 tmp; + btScalar d ; + + btScalar s = btSqrt(v[XX] * v[XX] + v[ZZ] * v[ZZ]); + if (s != btScalar(0.0)) + { + d = radius / s; + tmp[XX] = v[XX] * d; + tmp[YY] = v[YY] < 0.0 ? -halfHeight : halfHeight; + tmp[ZZ] = v[ZZ] * d; + return tmp; + } + else + { + tmp[XX] = radius; + tmp[YY] = v[YY] < 0.0 ? -halfHeight : halfHeight; + tmp[ZZ] = btScalar(0.0); + return tmp; + } + + +} + +btVector3 btCylinderShapeX::localGetSupportingVertexWithoutMargin(const btVector3& vec)const +{ + return CylinderLocalSupportX(getHalfExtents(),vec); +} + + +btVector3 btCylinderShapeZ::localGetSupportingVertexWithoutMargin(const btVector3& vec)const +{ + return CylinderLocalSupportZ(getHalfExtents(),vec); +} +btVector3 btCylinderShape::localGetSupportingVertexWithoutMargin(const btVector3& vec)const +{ + return CylinderLocalSupportY(getHalfExtents(),vec); +} + +void btCylinderShape::batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const +{ + for (int i=0;i=0); + btAssert(y>=0); + btAssert(xstartX) + startX = quantizedAabbMin[1]; + if (quantizedAabbMax[1]startJ) + startJ = quantizedAabbMin[2]; + if (quantizedAabbMax[2]startX) + startX = quantizedAabbMin[0]; + if (quantizedAabbMax[0]startJ) + startJ = quantizedAabbMin[2]; + if (quantizedAabbMax[2]startX) + startX = quantizedAabbMin[0]; + if (quantizedAabbMax[0]startJ) + startJ = quantizedAabbMin[1]; + if (quantizedAabbMax[1]processTriangle(vertices,x,j); + //second triangle + getVertex(x,j,vertices[0]); + getVertex(x+1,j+1,vertices[1]); + getVertex(x,j+1,vertices[2]); + callback->processTriangle(vertices,x,j); + } else + { + //first triangle + getVertex(x,j,vertices[0]); + getVertex(x,j+1,vertices[1]); + getVertex(x+1,j,vertices[2]); + callback->processTriangle(vertices,x,j); + //second triangle + getVertex(x+1,j,vertices[0]); + getVertex(x,j+1,vertices[1]); + getVertex(x+1,j+1,vertices[2]); + callback->processTriangle(vertices,x,j); + } + } + } + + + +} + +void btHeightfieldTerrainShape::calculateLocalInertia(btScalar ,btVector3& inertia) +{ + //moving concave objects not supported + + inertia.setValue(btScalar(0.),btScalar(0.),btScalar(0.)); +} + +void btHeightfieldTerrainShape::setLocalScaling(const btVector3& scaling) +{ + m_localScaling = scaling; +} +const btVector3& btHeightfieldTerrainShape::getLocalScaling() const +{ + return m_localScaling; +} diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btHeightfieldTerrainShape.h b/extern/bullet2/src/BulletCollision/CollisionShapes/btHeightfieldTerrainShape.h new file mode 100644 index 00000000000..49f3e106733 --- /dev/null +++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btHeightfieldTerrainShape.h @@ -0,0 +1,88 @@ +/* +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 HEIGHTFIELD_TERRAIN_SHAPE_H +#define HEIGHTFIELD_TERRAIN_SHAPE_H + +#include "btConcaveShape.h" + +///btHeightfieldTerrainShape simulates a 2D heightfield terrain +class btHeightfieldTerrainShape : public btConcaveShape +{ +protected: + btVector3 m_localAabbMin; + btVector3 m_localAabbMax; + + ///terrain data + int m_width; + int m_length; + btScalar m_maxHeight; + union + { + unsigned char* m_heightfieldDataUnsignedChar; + btScalar* m_heightfieldDataFloat; + void* m_heightfieldDataUnknown; + }; + + bool m_useFloatData; + bool m_flipQuadEdges; + bool m_useDiamondSubdivision; + + int m_upAxis; + + btVector3 m_localScaling; + + virtual btScalar getHeightFieldValue(int x,int y) const; + void quantizeWithClamp(int* out, const btVector3& point) const; + void getVertex(int x,int y,btVector3& vertex) const; + + inline bool testQuantizedAabbAgainstQuantizedAabb(int* aabbMin1, int* aabbMax1,const int* aabbMin2,const int* aabbMax2) const + { + bool overlap = true; + overlap = (aabbMin1[0] > aabbMax2[0] || aabbMax1[0] < aabbMin2[0]) ? false : overlap; + overlap = (aabbMin1[2] > aabbMax2[2] || aabbMax1[2] < aabbMin2[2]) ? false : overlap; + overlap = (aabbMin1[1] > aabbMax2[1] || aabbMax1[1] < aabbMin2[1]) ? false : overlap; + return overlap; + } + +public: + btHeightfieldTerrainShape(int width,int height,void* heightfieldData, btScalar maxHeight,int upAxis,bool useFloatData,bool flipQuadEdges); + + virtual ~btHeightfieldTerrainShape(); + + + void setUseDiamondSubdivision(bool useDiamondSubdivision=true) { m_useDiamondSubdivision = useDiamondSubdivision;} + + virtual int getShapeType() const + { + return TERRAIN_SHAPE_PROXYTYPE; + } + + virtual void getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const; + + virtual void processAllTriangles(btTriangleCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const; + + virtual void calculateLocalInertia(btScalar mass,btVector3& inertia); + + virtual void setLocalScaling(const btVector3& scaling); + + virtual const btVector3& getLocalScaling() const; + + //debugging + virtual char* getName()const {return "HEIGHTFIELD";} + +}; + +#endif //HEIGHTFIELD_TERRAIN_SHAPE_H diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btMinkowskiSumShape.cpp b/extern/bullet2/src/BulletCollision/CollisionShapes/btMinkowskiSumShape.cpp new file mode 100644 index 00000000000..015314bc09f --- /dev/null +++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btMinkowskiSumShape.cpp @@ -0,0 +1,57 @@ +/* +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 "btMinkowskiSumShape.h" + + +btMinkowskiSumShape::btMinkowskiSumShape(const btConvexShape* shapeA,const btConvexShape* shapeB) +:m_shapeA(shapeA), +m_shapeB(shapeB) +{ + m_transA.setIdentity(); + m_transB.setIdentity(); +} + +btVector3 btMinkowskiSumShape::localGetSupportingVertexWithoutMargin(const btVector3& vec)const +{ + btVector3 supVertexA = m_transA(m_shapeA->localGetSupportingVertexWithoutMargin(vec*m_transA.getBasis())); + btVector3 supVertexB = m_transB(m_shapeB->localGetSupportingVertexWithoutMargin(vec*m_transB.getBasis())); + return supVertexA + supVertexB; +} + +void btMinkowskiSumShape::batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const +{ + //todo: could make recursive use of batching. probably this shape is not used frequently. + for (int i=0;igetMargin() + m_shapeB->getMargin(); +} + + +void btMinkowskiSumShape::calculateLocalInertia(btScalar mass,btVector3& inertia) +{ + (void)mass; + btAssert(0); + inertia.setValue(0,0,0); +} diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btMinkowskiSumShape.h b/extern/bullet2/src/BulletCollision/CollisionShapes/btMinkowskiSumShape.h new file mode 100644 index 00000000000..198faaff9f9 --- /dev/null +++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btMinkowskiSumShape.h @@ -0,0 +1,62 @@ +/* +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 MINKOWSKI_SUM_SHAPE_H +#define MINKOWSKI_SUM_SHAPE_H + +#include "btConvexShape.h" +#include "../BroadphaseCollision/btBroadphaseProxy.h" // for the types + +/// btMinkowskiSumShape represents implicit (getSupportingVertex) based minkowski sum of two convex implicit shapes. +class btMinkowskiSumShape : public btConvexShape +{ + + btTransform m_transA; + btTransform m_transB; + const btConvexShape* m_shapeA; + const btConvexShape* m_shapeB; + +public: + + btMinkowskiSumShape(const btConvexShape* shapeA,const btConvexShape* shapeB); + + virtual btVector3 localGetSupportingVertexWithoutMargin(const btVector3& vec)const; + + virtual void batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const; + + + virtual void calculateLocalInertia(btScalar mass,btVector3& inertia); + + void setTransformA(const btTransform& transA) { m_transA = transA;} + void setTransformB(const btTransform& transB) { m_transB = transB;} + + const btTransform& getTransformA()const { return m_transA;} + const btTransform& GetTransformB()const { return m_transB;} + + + virtual int getShapeType() const { return MINKOWSKI_SUM_SHAPE_PROXYTYPE; } + + virtual btScalar getMargin() const; + + const btConvexShape* getShapeA() const { return m_shapeA;} + const btConvexShape* getShapeB() const { return m_shapeB;} + + virtual char* getName()const + { + return "MinkowskiSum"; + } +}; + +#endif //MINKOWSKI_SUM_SHAPE_H diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btMultiSphereShape.cpp b/extern/bullet2/src/BulletCollision/CollisionShapes/btMultiSphereShape.cpp new file mode 100644 index 00000000000..6015a618082 --- /dev/null +++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btMultiSphereShape.cpp @@ -0,0 +1,148 @@ +/* +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 "btMultiSphereShape.h" +#include "BulletCollision/CollisionShapes/btCollisionMargin.h" +#include "LinearMath/btQuaternion.h" + +btMultiSphereShape::btMultiSphereShape (const btVector3& inertiaHalfExtents,const btVector3* positions,const btScalar* radi,int numSpheres) +:m_inertiaHalfExtents(inertiaHalfExtents) +{ + btScalar startMargin = btScalar(1e30); + + m_numSpheres = numSpheres; + for (int i=0;i maxDot) + { + maxDot = newDot; + supVec = vtx; + } + } + + return supVec; + +} + + void btMultiSphereShape::batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const +{ + + for (int j=0;j maxDot) + { + maxDot = newDot; + supportVerticesOut[j] = vtx; + } + } + } +} + + + + + + + + +void btMultiSphereShape::calculateLocalInertia(btScalar mass,btVector3& inertia) +{ + //as an approximation, take the inertia of the box that bounds the spheres + + btTransform ident; + ident.setIdentity(); +// btVector3 aabbMin,aabbMax; + +// getAabb(ident,aabbMin,aabbMax); + + btVector3 halfExtents = m_inertiaHalfExtents;//(aabbMax - aabbMin)* btScalar(0.5); + + btScalar margin = CONVEX_DISTANCE_MARGIN; + + btScalar lx=btScalar(2.)*(halfExtents[0]+margin); + btScalar ly=btScalar(2.)*(halfExtents[1]+margin); + btScalar lz=btScalar(2.)*(halfExtents[2]+margin); + const btScalar x2 = lx*lx; + const btScalar y2 = ly*ly; + const btScalar z2 = lz*lz; + const btScalar scaledmass = mass * btScalar(.08333333); + + inertia[0] = scaledmass * (y2+z2); + inertia[1] = scaledmass * (x2+z2); + inertia[2] = scaledmass * (x2+y2); + +} + + + diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btMultiSphereShape.h b/extern/bullet2/src/BulletCollision/CollisionShapes/btMultiSphereShape.h new file mode 100644 index 00000000000..1897b474057 --- /dev/null +++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btMultiSphereShape.h @@ -0,0 +1,74 @@ +/* +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 MULTI_SPHERE_MINKOWSKI_H +#define MULTI_SPHERE_MINKOWSKI_H + +#include "btConvexShape.h" +#include "../BroadphaseCollision/btBroadphaseProxy.h" // for the types + +#define MAX_NUM_SPHERES 5 + +///btMultiSphereShape represents implicit convex hull of a collection of spheres (using getSupportingVertex) +class btMultiSphereShape : public btConvexShape + +{ + + btVector3 m_localPositions[MAX_NUM_SPHERES]; + btScalar m_radi[MAX_NUM_SPHERES]; + btVector3 m_inertiaHalfExtents; + + int m_numSpheres; + + + + +public: + btMultiSphereShape (const btVector3& inertiaHalfExtents,const btVector3* positions,const btScalar* radi,int numSpheres); + + ///CollisionShape Interface + virtual void calculateLocalInertia(btScalar mass,btVector3& inertia); + + /// btConvexShape Interface + virtual btVector3 localGetSupportingVertexWithoutMargin(const btVector3& vec)const; + + virtual void batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const; + + int getSphereCount() const + { + return m_numSpheres; + } + + const btVector3& getSpherePosition(int index) const + { + return m_localPositions[index]; + } + + btScalar getSphereRadius(int index) const + { + return m_radi[index]; + } + + virtual int getShapeType() const { return MULTI_SPHERE_SHAPE_PROXYTYPE; } + + virtual char* getName()const + { + return "MultiSphere"; + } + +}; + + +#endif //MULTI_SPHERE_MINKOWSKI_H diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btOptimizedBvh.cpp b/extern/bullet2/src/BulletCollision/CollisionShapes/btOptimizedBvh.cpp new file mode 100644 index 00000000000..44438a24455 --- /dev/null +++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btOptimizedBvh.cpp @@ -0,0 +1,845 @@ +/* +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 "btOptimizedBvh.h" +#include "btStridingMeshInterface.h" +#include "LinearMath/btAabbUtil2.h" +#include "LinearMath/btIDebugDraw.h" + + + +btOptimizedBvh::btOptimizedBvh() : m_useQuantization(false), + m_traversalMode(TRAVERSAL_STACKLESS_CACHE_FRIENDLY) + //m_traversalMode(TRAVERSAL_STACKLESS) + //m_traversalMode(TRAVERSAL_RECURSIVE) +{ + +} + + +void btOptimizedBvh::build(btStridingMeshInterface* triangles, bool useQuantizedAabbCompression, const btVector3& bvhAabbMin, const btVector3& bvhAabbMax) +{ + m_useQuantization = useQuantizedAabbCompression; + + + // NodeArray triangleNodes; + + struct NodeTriangleCallback : public btInternalTriangleIndexCallback + { + + NodeArray& m_triangleNodes; + + NodeTriangleCallback& operator=(NodeTriangleCallback& other) + { + m_triangleNodes = other.m_triangleNodes; + return *this; + } + + NodeTriangleCallback(NodeArray& triangleNodes) + :m_triangleNodes(triangleNodes) + { + } + + virtual void internalProcessTriangleIndex(btVector3* triangle,int partId,int triangleIndex) + { + btOptimizedBvhNode node; + btVector3 aabbMin,aabbMax; + aabbMin.setValue(btScalar(1e30),btScalar(1e30),btScalar(1e30)); + aabbMax.setValue(btScalar(-1e30),btScalar(-1e30),btScalar(-1e30)); + aabbMin.setMin(triangle[0]); + aabbMax.setMax(triangle[0]); + aabbMin.setMin(triangle[1]); + aabbMax.setMax(triangle[1]); + aabbMin.setMin(triangle[2]); + aabbMax.setMax(triangle[2]); + + //with quantization? + node.m_aabbMinOrg = aabbMin; + node.m_aabbMaxOrg = aabbMax; + + node.m_escapeIndex = -1; + + //for child nodes + node.m_subPart = partId; + node.m_triangleIndex = triangleIndex; + m_triangleNodes.push_back(node); + } + }; + struct QuantizedNodeTriangleCallback : public btInternalTriangleIndexCallback + { + QuantizedNodeArray& m_triangleNodes; + const btOptimizedBvh* m_optimizedTree; // for quantization + + QuantizedNodeTriangleCallback& operator=(QuantizedNodeTriangleCallback& other) + { + m_triangleNodes = other.m_triangleNodes; + m_optimizedTree = other.m_optimizedTree; + return *this; + } + + QuantizedNodeTriangleCallback(QuantizedNodeArray& triangleNodes,const btOptimizedBvh* tree) + :m_triangleNodes(triangleNodes),m_optimizedTree(tree) + { + } + + virtual void internalProcessTriangleIndex(btVector3* triangle,int partId,int triangleIndex) + { + btAssert(partId==0); + //negative indices are reserved for escapeIndex + btAssert(triangleIndex>=0); + + btQuantizedBvhNode node; + btVector3 aabbMin,aabbMax; + aabbMin.setValue(btScalar(1e30),btScalar(1e30),btScalar(1e30)); + aabbMax.setValue(btScalar(-1e30),btScalar(-1e30),btScalar(-1e30)); + aabbMin.setMin(triangle[0]); + aabbMax.setMax(triangle[0]); + aabbMin.setMin(triangle[1]); + aabbMax.setMax(triangle[1]); + aabbMin.setMin(triangle[2]); + aabbMax.setMax(triangle[2]); + + m_optimizedTree->quantizeWithClamp(&node.m_quantizedAabbMin[0],aabbMin); + m_optimizedTree->quantizeWithClamp(&node.m_quantizedAabbMax[0],aabbMax); + + node.m_escapeIndexOrTriangleIndex = triangleIndex; + + m_triangleNodes.push_back(node); + } + }; + + + + int numLeafNodes = 0; + + + if (m_useQuantization) + { + + //initialize quantization values + setQuantizationValues(bvhAabbMin,bvhAabbMax); + + QuantizedNodeTriangleCallback callback(m_quantizedLeafNodes,this); + + + triangles->InternalProcessAllTriangles(&callback,m_bvhAabbMin,m_bvhAabbMax); + + //now we have an array of leafnodes in m_leafNodes + numLeafNodes = m_quantizedLeafNodes.size(); + + + m_quantizedContiguousNodes.resize(2*numLeafNodes); + + + } else + { + NodeTriangleCallback callback(m_leafNodes); + + btVector3 aabbMin(btScalar(-1e30),btScalar(-1e30),btScalar(-1e30)); + btVector3 aabbMax(btScalar(1e30),btScalar(1e30),btScalar(1e30)); + + triangles->InternalProcessAllTriangles(&callback,aabbMin,aabbMax); + + //now we have an array of leafnodes in m_leafNodes + numLeafNodes = m_leafNodes.size(); + + m_contiguousNodes.resize(2*numLeafNodes); + } + + m_curNodeIndex = 0; + + buildTree(0,numLeafNodes); + + ///if the entire tree is small then subtree size, we need to create a header info for the tree + if(m_useQuantization && !m_SubtreeHeaders.size()) + { + btBvhSubtreeInfo& subtree = m_SubtreeHeaders.expand(); + subtree.setAabbFromQuantizeNode(m_quantizedContiguousNodes[0]); + subtree.m_rootNodeIndex = 0; + subtree.m_subtreeSize = m_quantizedContiguousNodes[0].isLeafNode() ? 1 : m_quantizedContiguousNodes[0].getEscapeIndex(); + } +} + + + +void btOptimizedBvh::refitPartial(btStridingMeshInterface* meshInterface,const btVector3& aabbMin,const btVector3& aabbMax) +{ + //incrementally initialize quantization values + btAssert(m_useQuantization); + + btAssert(aabbMin.getX() > m_bvhAabbMin.getX()); + btAssert(aabbMin.getY() > m_bvhAabbMin.getY()); + btAssert(aabbMin.getZ() > m_bvhAabbMin.getZ()); + + btAssert(aabbMax.getX() < m_bvhAabbMax.getX()); + btAssert(aabbMax.getY() < m_bvhAabbMax.getY()); + btAssert(aabbMax.getZ() < m_bvhAabbMax.getZ()); + + ///we should update all quantization values, using updateBvhNodes(meshInterface); + ///but we only update chunks that overlap the given aabb + + unsigned short quantizedQueryAabbMin[3]; + unsigned short quantizedQueryAabbMax[3]; + + quantizeWithClamp(&quantizedQueryAabbMin[0],aabbMin); + quantizeWithClamp(&quantizedQueryAabbMax[0],aabbMax); + + int i; + for (i=0;im_SubtreeHeaders.size();i++) + { + btBvhSubtreeInfo& subtree = m_SubtreeHeaders[i]; + + bool overlap = testQuantizedAabbAgainstQuantizedAabb(quantizedQueryAabbMin,quantizedQueryAabbMax,subtree.m_quantizedAabbMin,subtree.m_quantizedAabbMax); + if (overlap) + { + updateBvhNodes(meshInterface,subtree.m_rootNodeIndex,subtree.m_rootNodeIndex+subtree.m_subtreeSize,i); + + subtree.setAabbFromQuantizeNode(m_quantizedContiguousNodes[subtree.m_rootNodeIndex]); + } + } + +} + +///just for debugging, to visualize the individual patches/subtrees +#ifdef DEBUG_PATCH_COLORS +btVector3 color[4]= +{ + btVector3(255,0,0), + btVector3(0,255,0), + btVector3(0,0,255), + btVector3(0,255,255) +}; +#endif //DEBUG_PATCH_COLORS + + +void btOptimizedBvh::updateBvhNodes(btStridingMeshInterface* meshInterface,int firstNode,int endNode,int index) +{ + (void)index; + + btAssert(m_useQuantization); + + int nodeSubPart=0; + + //get access info to trianglemesh data + const unsigned char *vertexbase; + int numverts; + PHY_ScalarType type; + int stride; + const unsigned char *indexbase; + int indexstride; + int numfaces; + PHY_ScalarType indicestype; + meshInterface->getLockedReadOnlyVertexIndexBase(&vertexbase,numverts, type,stride,&indexbase,indexstride,numfaces,indicestype,nodeSubPart); + + btVector3 triangleVerts[3]; + btVector3 aabbMin,aabbMax; + const btVector3& meshScaling = meshInterface->getScaling(); + + int i; + for (i=endNode-1;i>=firstNode;i--) + { + + + btQuantizedBvhNode& curNode = m_quantizedContiguousNodes[i]; + if (curNode.isLeafNode()) + { + //recalc aabb from triangle data + int nodeTriangleIndex = curNode.getTriangleIndex(); + //triangles->getLockedReadOnlyVertexIndexBase(vertexBase,numVerts, + + int* gfxbase = (int*)(indexbase+nodeTriangleIndex*indexstride); + + + for (int j=2;j>=0;j--) + { + + int graphicsindex = gfxbase[j]; + btScalar* graphicsbase = (btScalar*)(vertexbase+graphicsindex*stride); +#ifdef DEBUG_PATCH_COLORS + btVector3 mycolor = color[index&3]; + graphicsbase[8] = mycolor.getX(); + graphicsbase[9] = mycolor.getY(); + graphicsbase[10] = mycolor.getZ(); +#endif //DEBUG_PATCH_COLORS + + + triangleVerts[j] = btVector3( + graphicsbase[0]*meshScaling.getX(), + graphicsbase[1]*meshScaling.getY(), + graphicsbase[2]*meshScaling.getZ()); + } + + + + aabbMin.setValue(btScalar(1e30),btScalar(1e30),btScalar(1e30)); + aabbMax.setValue(btScalar(-1e30),btScalar(-1e30),btScalar(-1e30)); + aabbMin.setMin(triangleVerts[0]); + aabbMax.setMax(triangleVerts[0]); + aabbMin.setMin(triangleVerts[1]); + aabbMax.setMax(triangleVerts[1]); + aabbMin.setMin(triangleVerts[2]); + aabbMax.setMax(triangleVerts[2]); + + quantizeWithClamp(&curNode.m_quantizedAabbMin[0],aabbMin); + quantizeWithClamp(&curNode.m_quantizedAabbMax[0],aabbMax); + + } else + { + //combine aabb from both children + + btQuantizedBvhNode* leftChildNode = &m_quantizedContiguousNodes[i+1]; + + btQuantizedBvhNode* rightChildNode = leftChildNode->isLeafNode() ? &m_quantizedContiguousNodes[i+2] : + &m_quantizedContiguousNodes[i+1+leftChildNode->getEscapeIndex()]; + + + { + for (int i=0;i<3;i++) + { + curNode.m_quantizedAabbMin[i] = leftChildNode->m_quantizedAabbMin[i]; + if (curNode.m_quantizedAabbMin[i]>rightChildNode->m_quantizedAabbMin[i]) + curNode.m_quantizedAabbMin[i]=rightChildNode->m_quantizedAabbMin[i]; + + curNode.m_quantizedAabbMax[i] = leftChildNode->m_quantizedAabbMax[i]; + if (curNode.m_quantizedAabbMax[i] < rightChildNode->m_quantizedAabbMax[i]) + curNode.m_quantizedAabbMax[i] = rightChildNode->m_quantizedAabbMax[i]; + } + } + } + + } + + meshInterface->unLockReadOnlyVertexBase(nodeSubPart); + + +} + +void btOptimizedBvh::setQuantizationValues(const btVector3& bvhAabbMin,const btVector3& bvhAabbMax,btScalar quantizationMargin) +{ + //enlarge the AABB to avoid division by zero when initializing the quantization values + btVector3 clampValue(quantizationMargin,quantizationMargin,quantizationMargin); + m_bvhAabbMin = bvhAabbMin - clampValue; + m_bvhAabbMax = bvhAabbMax + clampValue; + btVector3 aabbSize = m_bvhAabbMax - m_bvhAabbMin; + m_bvhQuantization = btVector3(btScalar(65535.0),btScalar(65535.0),btScalar(65535.0)) / aabbSize; +} + + +void btOptimizedBvh::refit(btStridingMeshInterface* meshInterface) +{ + if (m_useQuantization) + { + //calculate new aabb + btVector3 aabbMin,aabbMax; + meshInterface->calculateAabbBruteForce(aabbMin,aabbMax); + + setQuantizationValues(aabbMin,aabbMax); + + updateBvhNodes(meshInterface,0,m_curNodeIndex,0); + + ///now update all subtree headers + + int i; + for (i=0;i gMaxStackDepth) + gMaxStackDepth = gStackDepth; +#endif //DEBUG_TREE_BUILDING + + + int splitAxis, splitIndex, i; + int numIndices =endIndex-startIndex; + int curIndex = m_curNodeIndex; + + assert(numIndices>0); + + if (numIndices==1) + { +#ifdef DEBUG_TREE_BUILDING + gStackDepth--; +#endif //DEBUG_TREE_BUILDING + + assignInternalNodeFromLeafNode(m_curNodeIndex,startIndex); + + m_curNodeIndex++; + return; + } + //calculate Best Splitting Axis and where to split it. Sort the incoming 'leafNodes' array within range 'startIndex/endIndex'. + + splitAxis = calcSplittingAxis(startIndex,endIndex); + + splitIndex = sortAndCalcSplittingIndex(startIndex,endIndex,splitAxis); + + int internalNodeIndex = m_curNodeIndex; + + setInternalNodeAabbMax(m_curNodeIndex,btVector3(btScalar(-1e30),btScalar(-1e30),btScalar(-1e30))); + setInternalNodeAabbMin(m_curNodeIndex,btVector3(btScalar(1e30),btScalar(1e30),btScalar(1e30))); + + for (i=startIndex;im_escapeIndex; + + int leftChildNodexIndex = m_curNodeIndex; + + //build left child tree + buildTree(startIndex,splitIndex); + + int rightChildNodexIndex = m_curNodeIndex; + //build right child tree + buildTree(splitIndex,endIndex); + +#ifdef DEBUG_TREE_BUILDING + gStackDepth--; +#endif //DEBUG_TREE_BUILDING + + int escapeIndex = m_curNodeIndex - curIndex; + + if (m_useQuantization) + { + //escapeIndex is the number of nodes of this subtree + const int sizeQuantizedNode =sizeof(btQuantizedBvhNode); + const int treeSizeInBytes = escapeIndex * sizeQuantizedNode; + if (treeSizeInBytes > MAX_SUBTREE_SIZE_IN_BYTES) + { + updateSubtreeHeaders(leftChildNodexIndex,rightChildNodexIndex); + } + } + + setInternalNodeEscapeIndex(internalNodeIndex,escapeIndex); + +} + +void btOptimizedBvh::updateSubtreeHeaders(int leftChildNodexIndex,int rightChildNodexIndex) +{ + btAssert(m_useQuantization); + + btQuantizedBvhNode& leftChildNode = m_quantizedContiguousNodes[leftChildNodexIndex]; + int leftSubTreeSize = leftChildNode.isLeafNode() ? 1 : leftChildNode.getEscapeIndex(); + int leftSubTreeSizeInBytes = leftSubTreeSize * sizeof(btQuantizedBvhNode); + + btQuantizedBvhNode& rightChildNode = m_quantizedContiguousNodes[rightChildNodexIndex]; + int rightSubTreeSize = rightChildNode.isLeafNode() ? 1 : rightChildNode.getEscapeIndex(); + int rightSubTreeSizeInBytes = rightSubTreeSize * sizeof(btQuantizedBvhNode); + + if(leftSubTreeSizeInBytes <= MAX_SUBTREE_SIZE_IN_BYTES) + { + btBvhSubtreeInfo& subtree = m_SubtreeHeaders.expand(); + subtree.setAabbFromQuantizeNode(leftChildNode); + subtree.m_rootNodeIndex = leftChildNodexIndex; + subtree.m_subtreeSize = leftSubTreeSize; + } + + if(rightSubTreeSizeInBytes <= MAX_SUBTREE_SIZE_IN_BYTES) + { + btBvhSubtreeInfo& subtree = m_SubtreeHeaders.expand(); + subtree.setAabbFromQuantizeNode(rightChildNode); + subtree.m_rootNodeIndex = rightChildNodexIndex; + subtree.m_subtreeSize = rightSubTreeSize; + } +} + + +int btOptimizedBvh::sortAndCalcSplittingIndex(int startIndex,int endIndex,int splitAxis) +{ + int i; + int splitIndex =startIndex; + int numIndices = endIndex - startIndex; + btScalar splitValue; + + btVector3 means(btScalar(0.),btScalar(0.),btScalar(0.)); + for (i=startIndex;i splitValue) + { + //swap + swapLeafNodes(i,splitIndex); + splitIndex++; + } + } + + //if the splitIndex causes unbalanced trees, fix this by using the center in between startIndex and endIndex + //otherwise the tree-building might fail due to stack-overflows in certain cases. + //unbalanced1 is unsafe: it can cause stack overflows + //bool unbalanced1 = ((splitIndex==startIndex) || (splitIndex == (endIndex-1))); + + //unbalanced2 should work too: always use center (perfect balanced trees) + //bool unbalanced2 = true; + + //this should be safe too: + int rangeBalancedIndices = numIndices/3; + bool unbalanced = ((splitIndex<=(startIndex+rangeBalancedIndices)) || (splitIndex >=(endIndex-1-rangeBalancedIndices))); + + if (unbalanced) + { + splitIndex = startIndex+ (numIndices>>1); + } + + bool unbal = (splitIndex==startIndex) || (splitIndex == (endIndex)); + btAssert(!unbal); + + return splitIndex; +} + + +int btOptimizedBvh::calcSplittingAxis(int startIndex,int endIndex) +{ + int i; + + btVector3 means(btScalar(0.),btScalar(0.),btScalar(0.)); + btVector3 variance(btScalar(0.),btScalar(0.),btScalar(0.)); + int numIndices = endIndex-startIndex; + + for (i=startIndex;im_aabbMinOrg,rootNode->m_aabbMaxOrg); + isLeafNode = rootNode->m_escapeIndex == -1; + + if (isLeafNode && aabbOverlap) + { + nodeCallback->processNode(rootNode->m_subPart,rootNode->m_triangleIndex); + } + + if (aabbOverlap || isLeafNode) + { + rootNode++; + curIndex++; + } else + { + escapeIndex = rootNode->m_escapeIndex; + rootNode += escapeIndex; + curIndex += escapeIndex; + } + } + if (maxIterations < walkIterations) + maxIterations = walkIterations; + +} + +/* +///this was the original recursive traversal, before we optimized towards stackless traversal +void btOptimizedBvh::walkTree(btOptimizedBvhNode* rootNode,btNodeOverlapCallback* nodeCallback,const btVector3& aabbMin,const btVector3& aabbMax) const +{ + bool isLeafNode, aabbOverlap = TestAabbAgainstAabb2(aabbMin,aabbMax,rootNode->m_aabbMin,rootNode->m_aabbMax); + if (aabbOverlap) + { + isLeafNode = (!rootNode->m_leftChild && !rootNode->m_rightChild); + if (isLeafNode) + { + nodeCallback->processNode(rootNode); + } else + { + walkTree(rootNode->m_leftChild,nodeCallback,aabbMin,aabbMax); + walkTree(rootNode->m_rightChild,nodeCallback,aabbMin,aabbMax); + } + } + +} +*/ + +void btOptimizedBvh::walkRecursiveQuantizedTreeAgainstQueryAabb(const btQuantizedBvhNode* currentNode,btNodeOverlapCallback* nodeCallback,unsigned short int* quantizedQueryAabbMin,unsigned short int* quantizedQueryAabbMax) const +{ + btAssert(m_useQuantization); + + bool aabbOverlap, isLeafNode; + + aabbOverlap = testQuantizedAabbAgainstQuantizedAabb(quantizedQueryAabbMin,quantizedQueryAabbMax,currentNode->m_quantizedAabbMin,currentNode->m_quantizedAabbMax); + isLeafNode = currentNode->isLeafNode(); + + if (aabbOverlap) + { + if (isLeafNode) + { + nodeCallback->processNode(0,currentNode->getTriangleIndex()); + } else + { + //process left and right children + const btQuantizedBvhNode* leftChildNode = currentNode+1; + walkRecursiveQuantizedTreeAgainstQueryAabb(leftChildNode,nodeCallback,quantizedQueryAabbMin,quantizedQueryAabbMax); + + const btQuantizedBvhNode* rightChildNode = leftChildNode->isLeafNode() ? leftChildNode+1:leftChildNode+leftChildNode->getEscapeIndex(); + walkRecursiveQuantizedTreeAgainstQueryAabb(rightChildNode,nodeCallback,quantizedQueryAabbMin,quantizedQueryAabbMax); + } + } +} + + + + + + + +void btOptimizedBvh::walkStacklessQuantizedTree(btNodeOverlapCallback* nodeCallback,unsigned short int* quantizedQueryAabbMin,unsigned short int* quantizedQueryAabbMax,int startNodeIndex,int endNodeIndex) const +{ + btAssert(m_useQuantization); + + int curIndex = startNodeIndex; + int walkIterations = 0; + int subTreeSize = endNodeIndex - startNodeIndex; + + const btQuantizedBvhNode* rootNode = &m_quantizedContiguousNodes[startNodeIndex]; + int escapeIndex; + + bool aabbOverlap, isLeafNode; + + while (curIndex < endNodeIndex) + { + +//#define VISUALLY_ANALYZE_BVH 1 +#ifdef VISUALLY_ANALYZE_BVH + //some code snippet to debugDraw aabb, to visually analyze bvh structure + static int drawPatch = 0; + //need some global access to a debugDrawer + extern btIDebugDraw* debugDrawerPtr; + if (curIndex==drawPatch) + { + btVector3 aabbMin,aabbMax; + aabbMin = unQuantize(rootNode->m_quantizedAabbMin); + aabbMax = unQuantize(rootNode->m_quantizedAabbMax); + btVector3 color(1,0,0); + debugDrawerPtr->drawAabb(aabbMin,aabbMax,color); + } +#endif//VISUALLY_ANALYZE_BVH + + //catch bugs in tree data + assert (walkIterations < subTreeSize); + + walkIterations++; + aabbOverlap = testQuantizedAabbAgainstQuantizedAabb(quantizedQueryAabbMin,quantizedQueryAabbMax,rootNode->m_quantizedAabbMin,rootNode->m_quantizedAabbMax); + isLeafNode = rootNode->isLeafNode(); + + if (isLeafNode && aabbOverlap) + { + nodeCallback->processNode(0,rootNode->getTriangleIndex()); + } + + if (aabbOverlap || isLeafNode) + { + rootNode++; + curIndex++; + } else + { + escapeIndex = rootNode->getEscapeIndex(); + rootNode += escapeIndex; + curIndex += escapeIndex; + } + } + if (maxIterations < walkIterations) + maxIterations = walkIterations; + +} + +//This traversal can be called from Playstation 3 SPU +void btOptimizedBvh::walkStacklessQuantizedTreeCacheFriendly(btNodeOverlapCallback* nodeCallback,unsigned short int* quantizedQueryAabbMin,unsigned short int* quantizedQueryAabbMax) const +{ + btAssert(m_useQuantization); + + int i; + + + for (i=0;im_SubtreeHeaders.size();i++) + { + const btBvhSubtreeInfo& subtree = m_SubtreeHeaders[i]; + + bool overlap = testQuantizedAabbAgainstQuantizedAabb(quantizedQueryAabbMin,quantizedQueryAabbMax,subtree.m_quantizedAabbMin,subtree.m_quantizedAabbMax); + if (overlap) + { + walkStacklessQuantizedTree(nodeCallback,quantizedQueryAabbMin,quantizedQueryAabbMax, + subtree.m_rootNodeIndex, + subtree.m_rootNodeIndex+subtree.m_subtreeSize); + } + } +} + + + + +void btOptimizedBvh::reportSphereOverlappingNodex(btNodeOverlapCallback* nodeCallback,const btVector3& aabbMin,const btVector3& aabbMax) const +{ + (void)nodeCallback; + (void)aabbMin; + (void)aabbMax; + //not yet, please use aabb + btAssert(0); +} + + +void btOptimizedBvh::quantizeWithClamp(unsigned short* out, const btVector3& point) const +{ + + btAssert(m_useQuantization); + + btVector3 clampedPoint(point); + clampedPoint.setMax(m_bvhAabbMin); + clampedPoint.setMin(m_bvhAabbMax); + + btVector3 v = (clampedPoint - m_bvhAabbMin) * m_bvhQuantization; + out[0] = (unsigned short)(v.getX()+0.5f); + out[1] = (unsigned short)(v.getY()+0.5f); + out[2] = (unsigned short)(v.getZ()+0.5f); +} + +btVector3 btOptimizedBvh::unQuantize(const unsigned short* vecIn) const +{ + btVector3 vecOut; + vecOut.setValue( + (btScalar)(vecIn[0]) / (m_bvhQuantization.getX()), + (btScalar)(vecIn[1]) / (m_bvhQuantization.getY()), + (btScalar)(vecIn[2]) / (m_bvhQuantization.getZ())); + vecOut += m_bvhAabbMin; + return vecOut; +} + + +void btOptimizedBvh::swapLeafNodes(int i,int splitIndex) +{ + if (m_useQuantization) + { + btQuantizedBvhNode tmp = m_quantizedLeafNodes[i]; + m_quantizedLeafNodes[i] = m_quantizedLeafNodes[splitIndex]; + m_quantizedLeafNodes[splitIndex] = tmp; + } else + { + btOptimizedBvhNode tmp = m_leafNodes[i]; + m_leafNodes[i] = m_leafNodes[splitIndex]; + m_leafNodes[splitIndex] = tmp; + } +} + +void btOptimizedBvh::assignInternalNodeFromLeafNode(int internalNode,int leafNodeIndex) +{ + if (m_useQuantization) + { + m_quantizedContiguousNodes[internalNode] = m_quantizedLeafNodes[leafNodeIndex]; + } else + { + m_contiguousNodes[internalNode] = m_leafNodes[leafNodeIndex]; + } +} diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btOptimizedBvh.h b/extern/bullet2/src/BulletCollision/CollisionShapes/btOptimizedBvh.h new file mode 100644 index 00000000000..d5159586344 --- /dev/null +++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btOptimizedBvh.h @@ -0,0 +1,330 @@ +/* +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 OPTIMIZED_BVH_H +#define OPTIMIZED_BVH_H + + +#include "../../LinearMath/btVector3.h" + + +//http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vclang/html/vclrf__m128.asp + + + +class btStridingMeshInterface; + +//Note: currently we have 16 bytes per quantized node +#define MAX_SUBTREE_SIZE_IN_BYTES 2048 + + +///btQuantizedBvhNode is a compressed aabb node, 16 bytes. +///Node can be used for leafnode or internal node. Leafnodes can point to 32-bit triangle index (non-negative range). +ATTRIBUTE_ALIGNED16 (struct) btQuantizedBvhNode +{ + + //12 bytes + unsigned short int m_quantizedAabbMin[3]; + unsigned short int m_quantizedAabbMax[3]; + //4 bytes + int m_escapeIndexOrTriangleIndex; + + bool isLeafNode() const + { + //skipindex is negative (internal node), triangleindex >=0 (leafnode) + return (m_escapeIndexOrTriangleIndex >= 0); + } + int getEscapeIndex() const + { + btAssert(!isLeafNode()); + return -m_escapeIndexOrTriangleIndex; + } + int getTriangleIndex() const + { + btAssert(isLeafNode()); + return m_escapeIndexOrTriangleIndex; + } +} +; + +/// btOptimizedBvhNode contains both internal and leaf node information. +/// Total node size is 44 bytes / node. You can use the compressed version of 16 bytes. +ATTRIBUTE_ALIGNED16 (struct) btOptimizedBvhNode +{ + //32 bytes + btVector3 m_aabbMinOrg; + btVector3 m_aabbMaxOrg; + + //4 + int m_escapeIndex; + + //8 + //for child nodes + int m_subPart; + int m_triangleIndex; + int m_padding[5];//bad, due to alignment + + +}; + + +///btBvhSubtreeInfo provides info to gather a subtree of limited size +ATTRIBUTE_ALIGNED16(class) btBvhSubtreeInfo +{ +public: + //12 bytes + unsigned short int m_quantizedAabbMin[3]; + unsigned short int m_quantizedAabbMax[3]; + //4 bytes, points to the root of the subtree + int m_rootNodeIndex; + //4 bytes + int m_subtreeSize; + int m_padding[3]; + + + void setAabbFromQuantizeNode(const btQuantizedBvhNode& quantizedNode) + { + m_quantizedAabbMin[0] = quantizedNode.m_quantizedAabbMin[0]; + m_quantizedAabbMin[1] = quantizedNode.m_quantizedAabbMin[1]; + m_quantizedAabbMin[2] = quantizedNode.m_quantizedAabbMin[2]; + m_quantizedAabbMax[0] = quantizedNode.m_quantizedAabbMax[0]; + m_quantizedAabbMax[1] = quantizedNode.m_quantizedAabbMax[1]; + m_quantizedAabbMax[2] = quantizedNode.m_quantizedAabbMax[2]; + } +} +; + + +class btNodeOverlapCallback +{ +public: + virtual ~btNodeOverlapCallback() {}; + + virtual void processNode(int subPart, int triangleIndex) = 0; +}; + +#include "../../LinearMath/btAlignedAllocator.h" +#include "../../LinearMath/btAlignedObjectArray.h" + + + +///for code readability: +typedef btAlignedObjectArray NodeArray; +typedef btAlignedObjectArray QuantizedNodeArray; +typedef btAlignedObjectArray BvhSubtreeInfoArray; + + +///OptimizedBvh store an AABB tree that can be quickly traversed on CPU (and SPU,GPU in future) +ATTRIBUTE_ALIGNED16(class) btOptimizedBvh +{ + NodeArray m_leafNodes; + NodeArray m_contiguousNodes; + + QuantizedNodeArray m_quantizedLeafNodes; + + QuantizedNodeArray m_quantizedContiguousNodes; + + int m_curNodeIndex; + + + //quantization data + bool m_useQuantization; + btVector3 m_bvhAabbMin; + btVector3 m_bvhAabbMax; + btVector3 m_bvhQuantization; + + enum btTraversalMode + { + TRAVERSAL_STACKLESS = 0, + TRAVERSAL_STACKLESS_CACHE_FRIENDLY, + TRAVERSAL_RECURSIVE + }; + + btTraversalMode m_traversalMode; + + + + + BvhSubtreeInfoArray m_SubtreeHeaders; + + + ///two versions, one for quantized and normal nodes. This allows code-reuse while maintaining readability (no template/macro!) + ///this might be refactored into a virtual, it is usually not calculated at run-time + void setInternalNodeAabbMin(int nodeIndex, const btVector3& aabbMin) + { + if (m_useQuantization) + { + quantizeWithClamp(&m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[0] ,aabbMin); + } else + { + m_contiguousNodes[nodeIndex].m_aabbMinOrg = aabbMin; + + } + } + void setInternalNodeAabbMax(int nodeIndex,const btVector3& aabbMax) + { + if (m_useQuantization) + { + quantizeWithClamp(&m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[0],aabbMax); + } else + { + m_contiguousNodes[nodeIndex].m_aabbMaxOrg = aabbMax; + } + } + + btVector3 getAabbMin(int nodeIndex) const + { + if (m_useQuantization) + { + return unQuantize(&m_quantizedLeafNodes[nodeIndex].m_quantizedAabbMin[0]); + } + //non-quantized + return m_leafNodes[nodeIndex].m_aabbMinOrg; + + } + btVector3 getAabbMax(int nodeIndex) const + { + if (m_useQuantization) + { + return unQuantize(&m_quantizedLeafNodes[nodeIndex].m_quantizedAabbMax[0]); + } + //non-quantized + return m_leafNodes[nodeIndex].m_aabbMaxOrg; + + } + + void setQuantizationValues(const btVector3& bvhAabbMin,const btVector3& bvhAabbMax,btScalar quantizationMargin=btScalar(1.0)); + + void setInternalNodeEscapeIndex(int nodeIndex, int escapeIndex) + { + if (m_useQuantization) + { + m_quantizedContiguousNodes[nodeIndex].m_escapeIndexOrTriangleIndex = -escapeIndex; + } + else + { + m_contiguousNodes[nodeIndex].m_escapeIndex = escapeIndex; + } + + } + + void mergeInternalNodeAabb(int nodeIndex,const btVector3& newAabbMin,const btVector3& newAabbMax) + { + if (m_useQuantization) + { + unsigned short int quantizedAabbMin[3]; + unsigned short int quantizedAabbMax[3]; + quantizeWithClamp(quantizedAabbMin,newAabbMin); + quantizeWithClamp(quantizedAabbMax,newAabbMax); + for (int i=0;i<3;i++) + { + if (m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[i] > quantizedAabbMin[i]) + m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[i] = quantizedAabbMin[i]; + + if (m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[i] < quantizedAabbMax[i]) + m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[i] = quantizedAabbMax[i]; + + } + } else + { + //non-quantized + m_contiguousNodes[nodeIndex].m_aabbMinOrg.setMin(newAabbMin); + m_contiguousNodes[nodeIndex].m_aabbMaxOrg.setMax(newAabbMax); + } + } + + void swapLeafNodes(int firstIndex,int secondIndex); + + void assignInternalNodeFromLeafNode(int internalNode,int leafNodeIndex); + +protected: + + + + void buildTree (int startIndex,int endIndex); + + int calcSplittingAxis(int startIndex,int endIndex); + + int sortAndCalcSplittingIndex(int startIndex,int endIndex,int splitAxis); + + void walkStacklessTree(btNodeOverlapCallback* nodeCallback,const btVector3& aabbMin,const btVector3& aabbMax) const; + + void walkStacklessQuantizedTree(btNodeOverlapCallback* nodeCallback,unsigned short int* quantizedQueryAabbMin,unsigned short int* quantizedQueryAabbMax,int startNodeIndex,int endNodeIndex) const; + + ///tree traversal designed for small-memory processors like PS3 SPU + void walkStacklessQuantizedTreeCacheFriendly(btNodeOverlapCallback* nodeCallback,unsigned short int* quantizedQueryAabbMin,unsigned short int* quantizedQueryAabbMax) const; + + ///use the 16-byte stackless 'skipindex' node tree to do a recursive traversal + void walkRecursiveQuantizedTreeAgainstQueryAabb(const btQuantizedBvhNode* currentNode,btNodeOverlapCallback* nodeCallback,unsigned short int* quantizedQueryAabbMin,unsigned short int* quantizedQueryAabbMax) const; + + ///use the 16-byte stackless 'skipindex' node tree to do a recursive traversal + void walkRecursiveQuantizedTreeAgainstQuantizedTree(const btQuantizedBvhNode* treeNodeA,const btQuantizedBvhNode* treeNodeB,btNodeOverlapCallback* nodeCallback) const; + + + inline bool testQuantizedAabbAgainstQuantizedAabb(unsigned short int* aabbMin1,unsigned short int* aabbMax1,const unsigned short int* aabbMin2,const unsigned short int* aabbMax2) const + { + bool overlap = true; + overlap = (aabbMin1[0] > aabbMax2[0] || aabbMax1[0] < aabbMin2[0]) ? false : overlap; + overlap = (aabbMin1[2] > aabbMax2[2] || aabbMax1[2] < aabbMin2[2]) ? false : overlap; + overlap = (aabbMin1[1] > aabbMax2[1] || aabbMax1[1] < aabbMin2[1]) ? false : overlap; + return overlap; + } + + void updateSubtreeHeaders(int leftChildNodexIndex,int rightChildNodexIndex); + +public: + btOptimizedBvh(); + + virtual ~btOptimizedBvh(); + + void build(btStridingMeshInterface* triangles,bool useQuantizedAabbCompression, const btVector3& bvhAabbMin, const btVector3& bvhAabbMax); + + void reportAabbOverlappingNodex(btNodeOverlapCallback* nodeCallback,const btVector3& aabbMin,const btVector3& aabbMax) const; + + void reportSphereOverlappingNodex(btNodeOverlapCallback* nodeCallback,const btVector3& aabbMin,const btVector3& aabbMax) const; + + void quantizeWithClamp(unsigned short* out, const btVector3& point) const; + + btVector3 unQuantize(const unsigned short* vecIn) const; + + ///setTraversalMode let's you choose between stackless, recursive or stackless cache friendly tree traversal. Note this is only implemented for quantized trees. + void setTraversalMode(btTraversalMode traversalMode) + { + m_traversalMode = traversalMode; + } + + void refit(btStridingMeshInterface* triangles); + + void refitPartial(btStridingMeshInterface* triangles,const btVector3& aabbMin, const btVector3& aabbMax); + + void updateBvhNodes(btStridingMeshInterface* meshInterface,int firstNode,int endNode,int index); + + + QuantizedNodeArray& getQuantizedNodeArray() + { + return m_quantizedContiguousNodes; + } + + BvhSubtreeInfoArray& getSubtreeInfoArray() + { + return m_SubtreeHeaders; + } + +} +; + + +#endif //OPTIMIZED_BVH_H + diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btPolyhedralConvexShape.cpp b/extern/bullet2/src/BulletCollision/CollisionShapes/btPolyhedralConvexShape.cpp new file mode 100644 index 00000000000..bbc4ba62af6 --- /dev/null +++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btPolyhedralConvexShape.cpp @@ -0,0 +1,148 @@ +/* +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 + +btPolyhedralConvexShape::btPolyhedralConvexShape() +:m_localAabbMin(1,1,1), +m_localAabbMax(-1,-1,-1), +m_isLocalAabbValid(false), +m_optionalHull(0) +{ + +} + + + +btVector3 btPolyhedralConvexShape::localGetSupportingVertexWithoutMargin(const btVector3& vec0)const +{ + int i; + btVector3 supVec(0,0,0); + + btScalar maxDot(btScalar(-1e30)); + + btVector3 vec = vec0; + btScalar lenSqr = vec.length2(); + if (lenSqr < btScalar(0.0001)) + { + vec.setValue(1,0,0); + } else + { + btScalar rlen = btScalar(1.) / btSqrt(lenSqr ); + vec *= rlen; + } + + btVector3 vtx; + btScalar newDot; + + for (i=0;i maxDot) + { + maxDot = newDot; + supVec = vtx; + } + } + + return supVec; + +} + +void btPolyhedralConvexShape::batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const +{ + int i; + + btVector3 vtx; + btScalar newDot; + + for (i=0;i supportVerticesOut[j][3]) + { + //WARNING: don't swap next lines, the w component would get overwritten! + supportVerticesOut[j] = vtx; + supportVerticesOut[j][3] = newDot; + } + } + } +} + + + +void btPolyhedralConvexShape::calculateLocalInertia(btScalar mass,btVector3& inertia) +{ + //not yet, return box inertia + + btScalar margin = getMargin(); + + btTransform ident; + ident.setIdentity(); + btVector3 aabbMin,aabbMax; + getAabb(ident,aabbMin,aabbMax); + btVector3 halfExtents = (aabbMax-aabbMin)*btScalar(0.5); + + btScalar lx=btScalar(2.)*(halfExtents.x()+margin); + btScalar ly=btScalar(2.)*(halfExtents.y()+margin); + btScalar lz=btScalar(2.)*(halfExtents.z()+margin); + const btScalar x2 = lx*lx; + const btScalar y2 = ly*ly; + const btScalar z2 = lz*lz; + const btScalar scaledmass = mass * btScalar(0.08333333); + + inertia = scaledmass * (btVector3(y2+z2,x2+z2,x2+y2)); + +} + + + +void btPolyhedralConvexShape::getAabb(const btTransform& trans,btVector3& aabbMin,btVector3& aabbMax) const +{ + getNonvirtualAabb(trans,aabbMin,aabbMax,getMargin()); +} + + + + +void btPolyhedralConvexShape::recalcLocalAabb() +{ + m_isLocalAabbValid = true; + + for (int i=0;i<3;i++) + { + btVector3 vec(btScalar(0.),btScalar(0.),btScalar(0.)); + vec[i] = btScalar(1.); + btVector3 tmp = localGetSupportingVertex(vec); + m_localAabbMax[i] = tmp[i]+m_collisionMargin; + vec[i] = btScalar(-1.); + tmp = localGetSupportingVertex(vec); + m_localAabbMin[i] = tmp[i]-m_collisionMargin; + } +} + + diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btPolyhedralConvexShape.h b/extern/bullet2/src/BulletCollision/CollisionShapes/btPolyhedralConvexShape.h new file mode 100644 index 00000000000..c35f7512663 --- /dev/null +++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btPolyhedralConvexShape.h @@ -0,0 +1,93 @@ +/* +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 BU_SHAPE +#define BU_SHAPE + +#include "../../LinearMath/btPoint3.h" +#include "../../LinearMath/btMatrix3x3.h" +#include "btConvexShape.h" + + +///PolyhedralConvexShape is an interface class for feature based (vertex/edge/face) convex shapes. +class btPolyhedralConvexShape : public btConvexShape +{ + +protected: + btVector3 m_localAabbMin; + btVector3 m_localAabbMax; + bool m_isLocalAabbValid; + +public: + + btPolyhedralConvexShape(); + + //brute force implementations + virtual btVector3 localGetSupportingVertexWithoutMargin(const btVector3& vec)const; + virtual void batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const; + + virtual void calculateLocalInertia(btScalar mass,btVector3& inertia); + + + inline void getNonvirtualAabb(const btTransform& trans,btVector3& aabbMin,btVector3& aabbMax, btScalar margin) const + { + + //lazy evaluation of local aabb + btAssert(m_isLocalAabbValid); + + btAssert(m_localAabbMin.getX() <= m_localAabbMax.getX()); + btAssert(m_localAabbMin.getY() <= m_localAabbMax.getY()); + btAssert(m_localAabbMin.getZ() <= m_localAabbMax.getZ()); + + + btVector3 localHalfExtents = btScalar(0.5)*(m_localAabbMax-m_localAabbMin); + btVector3 localCenter = btScalar(0.5)*(m_localAabbMax+m_localAabbMin); + + btMatrix3x3 abs_b = trans.getBasis().absolute(); + + btPoint3 center = trans(localCenter); + + btVector3 extent = btVector3(abs_b[0].dot(localHalfExtents), + abs_b[1].dot(localHalfExtents), + abs_b[2].dot(localHalfExtents)); + extent += btVector3(margin,margin,margin); + + aabbMin = center - extent; + aabbMax = center + extent; + + + } + + + virtual void getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const; + + void recalcLocalAabb(); + + virtual int getNumVertices() const = 0 ; + virtual int getNumEdges() const = 0; + virtual void getEdge(int i,btPoint3& pa,btPoint3& pb) const = 0; + virtual void getVertex(int i,btPoint3& vtx) const = 0; + virtual int getNumPlanes() const = 0; + virtual void getPlane(btVector3& planeNormal,btPoint3& planeSupport,int i ) const = 0; +// virtual int getIndex(int i) const = 0 ; + + virtual bool isInside(const btPoint3& pt,btScalar tolerance) const = 0; + + /// optional Hull is for optional Separating Axis Test Hull collision detection, see Hull.cpp + class Hull* m_optionalHull; + +}; + +#endif //BU_SHAPE diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btSphereShape.cpp b/extern/bullet2/src/BulletCollision/CollisionShapes/btSphereShape.cpp new file mode 100644 index 00000000000..ca65dd03f3e --- /dev/null +++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btSphereShape.cpp @@ -0,0 +1,77 @@ +/* +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 "btSphereShape.h" +#include "BulletCollision/CollisionShapes/btCollisionMargin.h" + +#include "LinearMath/btQuaternion.h" + + +btSphereShape ::btSphereShape (btScalar radius) +{ + m_implicitShapeDimensions.setX(radius); +} + +btVector3 btSphereShape::localGetSupportingVertexWithoutMargin(const btVector3& vec)const +{ + (void)vec; + return btVector3(btScalar(0.),btScalar(0.),btScalar(0.)); +} + +void btSphereShape::batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const +{ + (void)vectors; + + for (int i=0;iprocessTriangle(triangle,0,0); + + triangle[0] = projectedCenter - tangentDir0*radius - tangentDir1*radius; + triangle[1] = projectedCenter - tangentDir0*radius + tangentDir1*radius; + triangle[2] = projectedCenter + tangentDir0*radius + tangentDir1*radius; + + callback->processTriangle(triangle,0,1); + +} + +void btStaticPlaneShape::calculateLocalInertia(btScalar mass,btVector3& inertia) +{ + (void)mass; + + //moving concave objects not supported + + inertia.setValue(btScalar(0.),btScalar(0.),btScalar(0.)); +} + +void btStaticPlaneShape::setLocalScaling(const btVector3& scaling) +{ + m_localScaling = scaling; +} +const btVector3& btStaticPlaneShape::getLocalScaling() const +{ + return m_localScaling; +} diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btStaticPlaneShape.h b/extern/bullet2/src/BulletCollision/CollisionShapes/btStaticPlaneShape.h new file mode 100644 index 00000000000..f59cc0c3347 --- /dev/null +++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btStaticPlaneShape.h @@ -0,0 +1,61 @@ +/* +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 STATIC_PLANE_SHAPE_H +#define STATIC_PLANE_SHAPE_H + +#include "btConcaveShape.h" + + +///StaticPlaneShape simulates an 'infinite' plane by dynamically reporting triangles approximated by intersection of the plane with the AABB. +///Assumed is that the other objects is not also infinite, so a reasonable sized AABB. +class btStaticPlaneShape : public btConcaveShape +{ +protected: + btVector3 m_localAabbMin; + btVector3 m_localAabbMax; + + btVector3 m_planeNormal; + btScalar m_planeConstant; + btVector3 m_localScaling; + +public: + btStaticPlaneShape(const btVector3& planeNormal,btScalar planeConstant); + + virtual ~btStaticPlaneShape(); + + + virtual int getShapeType() const + { + return STATIC_PLANE_PROXYTYPE; + } + + virtual void getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const; + + virtual void processAllTriangles(btTriangleCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const; + + virtual void calculateLocalInertia(btScalar mass,btVector3& inertia); + + virtual void setLocalScaling(const btVector3& scaling); + virtual const btVector3& getLocalScaling() const; + + + //debugging + virtual char* getName()const {return "STATICPLANE";} + + +}; + +#endif //STATIC_PLANE_SHAPE_H diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btStridingMeshInterface.cpp b/extern/bullet2/src/BulletCollision/CollisionShapes/btStridingMeshInterface.cpp new file mode 100644 index 00000000000..03ca1ae7736 --- /dev/null +++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btStridingMeshInterface.cpp @@ -0,0 +1,124 @@ +/* +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 "btStridingMeshInterface.h" + +btStridingMeshInterface::~btStridingMeshInterface() +{ + +} + + +void btStridingMeshInterface::InternalProcessAllTriangles(btInternalTriangleIndexCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const +{ + (void)aabbMin; + (void)aabbMax; + int numtotalphysicsverts = 0; + int part,graphicssubparts = getNumSubParts(); + const unsigned char * vertexbase; + const unsigned char * indexbase; + int indexstride; + PHY_ScalarType type; + PHY_ScalarType gfxindextype; + int stride,numverts,numtriangles; + int gfxindex; + btVector3 triangle[3]; + btScalar* graphicsbase; + + btVector3 meshScaling = getScaling(); + + ///if the number of parts is big, the performance might drop due to the innerloop switch on indextype + for (part=0;partinternalProcessTriangleIndex(triangle,part,gfxindex); + } + break; + } + case PHY_SHORT: + { + for (gfxindex=0;gfxindexinternalProcessTriangleIndex(triangle,part,gfxindex); + } + break; + } + default: + btAssert((gfxindextype == PHY_INTEGER) || (gfxindextype == PHY_SHORT)); + } + + unLockReadOnlyVertexBase(part); + } +} + +void btStridingMeshInterface::calculateAabbBruteForce(btVector3& aabbMin,btVector3& aabbMax) +{ + + struct AabbCalculationCallback : public btInternalTriangleIndexCallback + { + btVector3 m_aabbMin; + btVector3 m_aabbMax; + + AabbCalculationCallback() + { + m_aabbMin.setValue(btScalar(1e30),btScalar(1e30),btScalar(1e30)); + m_aabbMax.setValue(btScalar(-1e30),btScalar(-1e30),btScalar(-1e30)); + } + + virtual void internalProcessTriangleIndex(btVector3* triangle,int partId,int triangleIndex) + { + (void)partId; + (void)triangleIndex; + + m_aabbMin.setMin(triangle[0]); + m_aabbMax.setMax(triangle[0]); + m_aabbMin.setMin(triangle[1]); + m_aabbMax.setMax(triangle[1]); + m_aabbMin.setMin(triangle[2]); + m_aabbMax.setMax(triangle[2]); + } + }; + + //first calculate the total aabb for all triangles + AabbCalculationCallback aabbCallback; + aabbMin.setValue(btScalar(-1e30),btScalar(-1e30),btScalar(-1e30)); + aabbMax.setValue(btScalar(1e30),btScalar(1e30),btScalar(1e30)); + InternalProcessAllTriangles(&aabbCallback,aabbMin,aabbMax); + + aabbMin = aabbCallback.m_aabbMin; + aabbMax = aabbCallback.m_aabbMax; +} \ No newline at end of file diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btStridingMeshInterface.h b/extern/bullet2/src/BulletCollision/CollisionShapes/btStridingMeshInterface.h new file mode 100644 index 00000000000..d7b354b7855 --- /dev/null +++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btStridingMeshInterface.h @@ -0,0 +1,89 @@ +/* +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 STRIDING_MESHINTERFACE_H +#define STRIDING_MESHINTERFACE_H + +#include "../../LinearMath/btVector3.h" +#include "btTriangleCallback.h" + +/// PHY_ScalarType enumerates possible scalar types. +/// See the btStridingMeshInterface for its use +typedef enum PHY_ScalarType { + PHY_FLOAT, + PHY_DOUBLE, + PHY_INTEGER, + PHY_SHORT, + PHY_FIXEDPOINT88 +} PHY_ScalarType; + +/// btStridingMeshInterface is the interface class for high performance access to triangle meshes +/// It allows for sharing graphics and collision meshes. Also it provides locking/unlocking of graphics meshes that are in gpu memory. +class btStridingMeshInterface +{ + protected: + + btVector3 m_scaling; + + public: + btStridingMeshInterface() :m_scaling(btScalar(1.),btScalar(1.),btScalar(1.)) + { + + } + + virtual ~btStridingMeshInterface(); + + + + void InternalProcessAllTriangles(btInternalTriangleIndexCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const; + + ///brute force method to calculate aabb + void calculateAabbBruteForce(btVector3& aabbMin,btVector3& aabbMax); + + /// get read and write access to a subpart of a triangle mesh + /// this subpart has a continuous array of vertices and indices + /// in this way the mesh can be handled as chunks of memory with striding + /// very similar to OpenGL vertexarray support + /// make a call to unLockVertexBase when the read and write access is finished + virtual void getLockedVertexIndexBase(unsigned char **vertexbase, int& numverts,PHY_ScalarType& type, int& stride,unsigned char **indexbase,int & indexstride,int& numfaces,PHY_ScalarType& indicestype,int subpart=0)=0; + + virtual void getLockedReadOnlyVertexIndexBase(const unsigned char **vertexbase, int& numverts,PHY_ScalarType& type, int& stride,const unsigned char **indexbase,int & indexstride,int& numfaces,PHY_ScalarType& indicestype,int subpart=0) const=0; + + /// unLockVertexBase finishes the access to a subpart of the triangle mesh + /// make a call to unLockVertexBase when the read and write access (using getLockedVertexIndexBase) is finished + virtual void unLockVertexBase(int subpart)=0; + + virtual void unLockReadOnlyVertexBase(int subpart) const=0; + + + /// getNumSubParts returns the number of seperate subparts + /// each subpart has a continuous array of vertices and indices + virtual int getNumSubParts() const=0; + + virtual void preallocateVertices(int numverts)=0; + virtual void preallocateIndices(int numindices)=0; + + const btVector3& getScaling() const { + return m_scaling; + } + void setScaling(const btVector3& scaling) + { + m_scaling = scaling; + } + + +}; + +#endif //STRIDING_MESHINTERFACE_H diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btTetrahedronShape.cpp b/extern/bullet2/src/BulletCollision/CollisionShapes/btTetrahedronShape.cpp new file mode 100644 index 00000000000..3aa1eda9964 --- /dev/null +++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btTetrahedronShape.cpp @@ -0,0 +1,195 @@ + +/* +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 "btTetrahedronShape.h" +#include "LinearMath/btMatrix3x3.h" + +btBU_Simplex1to4::btBU_Simplex1to4() +:m_numVertices(0) +{ +} + +btBU_Simplex1to4::btBU_Simplex1to4(const btPoint3& pt0) +:m_numVertices(0) +{ + addVertex(pt0); +} + +btBU_Simplex1to4::btBU_Simplex1to4(const btPoint3& pt0,const btPoint3& pt1) +:m_numVertices(0) +{ + addVertex(pt0); + addVertex(pt1); +} + +btBU_Simplex1to4::btBU_Simplex1to4(const btPoint3& pt0,const btPoint3& pt1,const btPoint3& pt2) +:m_numVertices(0) +{ + addVertex(pt0); + addVertex(pt1); + addVertex(pt2); +} + +btBU_Simplex1to4::btBU_Simplex1to4(const btPoint3& pt0,const btPoint3& pt1,const btPoint3& pt2,const btPoint3& pt3) +:m_numVertices(0) +{ + addVertex(pt0); + addVertex(pt1); + addVertex(pt2); + addVertex(pt3); +} + + + + + +void btBU_Simplex1to4::addVertex(const btPoint3& pt) +{ + m_vertices[m_numVertices++] = pt; + + recalcLocalAabb(); +} + + +int btBU_Simplex1to4::getNumVertices() const +{ + return m_numVertices; +} + +int btBU_Simplex1to4::getNumEdges() const +{ + //euler formula, F-E+V = 2, so E = F+V-2 + + switch (m_numVertices) + { + case 0: + return 0; + case 1: return 0; + case 2: return 1; + case 3: return 3; + case 4: return 6; + + + } + + return 0; +} + +void btBU_Simplex1to4::getEdge(int i,btPoint3& pa,btPoint3& pb) const +{ + + switch (m_numVertices) + { + + case 2: + pa = m_vertices[0]; + pb = m_vertices[1]; + break; + case 3: + switch (i) + { + case 0: + pa = m_vertices[0]; + pb = m_vertices[1]; + break; + case 1: + pa = m_vertices[1]; + pb = m_vertices[2]; + break; + case 2: + pa = m_vertices[2]; + pb = m_vertices[0]; + break; + + } + break; + case 4: + switch (i) + { + case 0: + pa = m_vertices[0]; + pb = m_vertices[1]; + break; + case 1: + pa = m_vertices[1]; + pb = m_vertices[2]; + break; + case 2: + pa = m_vertices[2]; + pb = m_vertices[0]; + break; + case 3: + pa = m_vertices[0]; + pb = m_vertices[3]; + break; + case 4: + pa = m_vertices[1]; + pb = m_vertices[3]; + break; + case 5: + pa = m_vertices[2]; + pb = m_vertices[3]; + break; + } + + } + + + + +} + +void btBU_Simplex1to4::getVertex(int i,btPoint3& vtx) const +{ + vtx = m_vertices[i]; +} + +int btBU_Simplex1to4::getNumPlanes() const +{ + switch (m_numVertices) + { + case 0: + return 0; + case 1: + return 0; + case 2: + return 0; + case 3: + return 2; + case 4: + return 4; + default: + { + } + } + return 0; +} + + +void btBU_Simplex1to4::getPlane(btVector3&, btPoint3& ,int ) const +{ + +} + +int btBU_Simplex1to4::getIndex(int ) const +{ + return 0; +} + +bool btBU_Simplex1to4::isInside(const btPoint3& ,btScalar ) const +{ + return false; +} + diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btTetrahedronShape.h b/extern/bullet2/src/BulletCollision/CollisionShapes/btTetrahedronShape.h new file mode 100644 index 00000000000..94bc4ec0fa5 --- /dev/null +++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btTetrahedronShape.h @@ -0,0 +1,75 @@ +/* +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 BU_SIMPLEX_1TO4_SHAPE +#define BU_SIMPLEX_1TO4_SHAPE + + +#include "btPolyhedralConvexShape.h" +#include "../BroadphaseCollision/btBroadphaseProxy.h" + + +///BU_Simplex1to4 implements feature based and implicit simplex of up to 4 vertices (tetrahedron, triangle, line, vertex). +class btBU_Simplex1to4 : public btPolyhedralConvexShape +{ +protected: + + int m_numVertices; + btPoint3 m_vertices[4]; + +public: + btBU_Simplex1to4(); + + btBU_Simplex1to4(const btPoint3& pt0); + btBU_Simplex1to4(const btPoint3& pt0,const btPoint3& pt1); + btBU_Simplex1to4(const btPoint3& pt0,const btPoint3& pt1,const btPoint3& pt2); + btBU_Simplex1to4(const btPoint3& pt0,const btPoint3& pt1,const btPoint3& pt2,const btPoint3& pt3); + + + void reset() + { + m_numVertices = 0; + } + + + virtual int getShapeType() const{ return TETRAHEDRAL_SHAPE_PROXYTYPE; } + + void addVertex(const btPoint3& pt); + + //PolyhedralConvexShape interface + + virtual int getNumVertices() const; + + virtual int getNumEdges() const; + + virtual void getEdge(int i,btPoint3& pa,btPoint3& pb) const; + + virtual void getVertex(int i,btPoint3& vtx) const; + + virtual int getNumPlanes() const; + + virtual void getPlane(btVector3& planeNormal,btPoint3& planeSupport,int i) const; + + virtual int getIndex(int i) const; + + virtual bool isInside(const btPoint3& pt,btScalar tolerance) const; + + + ///getName is for debugging + virtual char* getName()const { return "btBU_Simplex1to4";} + +}; + +#endif //BU_SIMPLEX_1TO4_SHAPE diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleBuffer.cpp b/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleBuffer.cpp new file mode 100644 index 00000000000..54864c32f3a --- /dev/null +++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleBuffer.cpp @@ -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. +*/ + +#include "btTriangleBuffer.h" + + +///example usage of this class: +// btTriangleBuffer triBuf; +// concaveShape->processAllTriangles(&triBuf,aabbMin, aabbMax); +// for (int i=0;i m_triangleBuffer; + +public: + + + virtual void processTriangle(btVector3* triangle, int partId, int triangleIndex); + + int getNumTriangles() const + { + return int(m_triangleBuffer.size()); + } + + const btTriangle& getTriangle(int index) const + { + return m_triangleBuffer[index]; + } + + void clearBuffer() + { + m_triangleBuffer.clear(); + } + +}; + + +#endif //BT_TRIANGLE_BUFFER_H + diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleCallback.cpp b/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleCallback.cpp new file mode 100644 index 00000000000..a020746db5f --- /dev/null +++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleCallback.cpp @@ -0,0 +1,28 @@ +/* +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 "btTriangleCallback.h" + +btTriangleCallback::~btTriangleCallback() +{ + +} + + +btInternalTriangleIndexCallback::~btInternalTriangleIndexCallback() +{ + +} + diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleCallback.h b/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleCallback.h new file mode 100644 index 00000000000..fbb87bc4fd8 --- /dev/null +++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleCallback.h @@ -0,0 +1,40 @@ +/* +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 TRIANGLE_CALLBACK_H +#define TRIANGLE_CALLBACK_H + +#include "../../LinearMath/btVector3.h" + + +class btTriangleCallback +{ +public: + + virtual ~btTriangleCallback(); + virtual void processTriangle(btVector3* triangle, int partId, int triangleIndex) = 0; +}; + +class btInternalTriangleIndexCallback +{ +public: + + virtual ~btInternalTriangleIndexCallback(); + virtual void internalProcessTriangleIndex(btVector3* triangle,int partId,int triangleIndex) = 0; +}; + + + +#endif //TRIANGLE_CALLBACK_H diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleIndexVertexArray.cpp b/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleIndexVertexArray.cpp new file mode 100644 index 00000000000..00847861cf1 --- /dev/null +++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleIndexVertexArray.cpp @@ -0,0 +1,65 @@ +/* +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 "btTriangleIndexVertexArray.h" + +btTriangleIndexVertexArray::btTriangleIndexVertexArray(int numTriangles,int* triangleIndexBase,int triangleIndexStride,int numVertices,btScalar* vertexBase,int vertexStride) +{ + btIndexedMesh mesh; + + mesh.m_numTriangles = numTriangles; + mesh.m_triangleIndexBase = (const unsigned char *)triangleIndexBase; + mesh.m_triangleIndexStride = triangleIndexStride; + mesh.m_numVertices = numVertices; + mesh.m_vertexBase = (const unsigned char *)vertexBase; + mesh.m_vertexStride = vertexStride; + + addIndexedMesh(mesh); + +} + +void btTriangleIndexVertexArray::getLockedVertexIndexBase(unsigned char **vertexbase, int& numverts,PHY_ScalarType& type, int& vertexStride,unsigned char **indexbase,int & indexstride,int& numfaces,PHY_ScalarType& indicestype,int subpart) +{ + btAssert(subpart< getNumSubParts() ); + + btIndexedMesh& mesh = m_indexedMeshes[subpart]; + + numverts = mesh.m_numVertices; + (*vertexbase) = (unsigned char *) mesh.m_vertexBase; + type = PHY_FLOAT; + vertexStride = mesh.m_vertexStride; + + numfaces = mesh.m_numTriangles; + + (*indexbase) = (unsigned char *)mesh.m_triangleIndexBase; + indexstride = mesh.m_triangleIndexStride; + indicestype = PHY_INTEGER; +} + +void btTriangleIndexVertexArray::getLockedReadOnlyVertexIndexBase(const unsigned char **vertexbase, int& numverts,PHY_ScalarType& type, int& vertexStride,const unsigned char **indexbase,int & indexstride,int& numfaces,PHY_ScalarType& indicestype,int subpart) const +{ + const btIndexedMesh& mesh = m_indexedMeshes[subpart]; + + numverts = mesh.m_numVertices; + (*vertexbase) = (const unsigned char *)mesh.m_vertexBase; + type = PHY_FLOAT; + vertexStride = mesh.m_vertexStride; + + numfaces = mesh.m_numTriangles; + (*indexbase) = (const unsigned char *)mesh.m_triangleIndexBase; + indexstride = mesh.m_triangleIndexStride; + indicestype = PHY_INTEGER; +} + diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleIndexVertexArray.h b/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleIndexVertexArray.h new file mode 100644 index 00000000000..6ab6a762b39 --- /dev/null +++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleIndexVertexArray.h @@ -0,0 +1,97 @@ +/* +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 BT_TRIANGLE_INDEX_VERTEX_ARRAY_H +#define BT_TRIANGLE_INDEX_VERTEX_ARRAY_H + +#include "btStridingMeshInterface.h" +#include "../../LinearMath/btAlignedObjectArray.h" + +///IndexedMesh indexes into existing vertex and index arrays, in a similar way OpenGL glDrawElements +///instead of the number of indices, we pass the number of triangles +///todo: explain with pictures +ATTRIBUTE_ALIGNED16( struct) btIndexedMesh +{ + int m_numTriangles; + const unsigned char * m_triangleIndexBase; + int m_triangleIndexStride; + int m_numVertices; + const unsigned char * m_vertexBase; + int m_vertexStride; + int pad[2]; +} +; + + +typedef btAlignedObjectArray IndexedMeshArray; + +///TriangleIndexVertexArray allows to use multiple meshes, by indexing into existing triangle/index arrays. +///Additional meshes can be added using addIndexedMesh +///No duplcate is made of the vertex/index data, it only indexes into external vertex/index arrays. +///So keep those arrays around during the lifetime of this btTriangleIndexVertexArray. +ATTRIBUTE_ALIGNED16( class) btTriangleIndexVertexArray : public btStridingMeshInterface +{ + IndexedMeshArray m_indexedMeshes; + int m_pad[3]; + + +public: + + btTriangleIndexVertexArray() + { + } + + //just to be backwards compatible + btTriangleIndexVertexArray(int numTriangleIndices,int* triangleIndexBase,int triangleIndexStride,int numVertices,btScalar* vertexBase,int vertexStride); + + void addIndexedMesh(const btIndexedMesh& mesh) + { + m_indexedMeshes.push_back(mesh); + } + + + virtual void getLockedVertexIndexBase(unsigned char **vertexbase, int& numverts,PHY_ScalarType& type, int& vertexStride,unsigned char **indexbase,int & indexstride,int& numfaces,PHY_ScalarType& indicestype,int subpart=0); + + virtual void getLockedReadOnlyVertexIndexBase(const unsigned char **vertexbase, int& numverts,PHY_ScalarType& type, int& vertexStride,const unsigned char **indexbase,int & indexstride,int& numfaces,PHY_ScalarType& indicestype,int subpart=0) const; + + /// unLockVertexBase finishes the access to a subpart of the triangle mesh + /// make a call to unLockVertexBase when the read and write access (using getLockedVertexIndexBase) is finished + virtual void unLockVertexBase(int subpart) {(void)subpart;} + + virtual void unLockReadOnlyVertexBase(int subpart) const {(void)subpart;} + + /// getNumSubParts returns the number of seperate subparts + /// each subpart has a continuous array of vertices and indices + virtual int getNumSubParts() const { + return (int)m_indexedMeshes.size(); + } + + IndexedMeshArray& getIndexedMeshArray() + { + return m_indexedMeshes; + } + + const IndexedMeshArray& getIndexedMeshArray() const + { + return m_indexedMeshes; + } + + virtual void preallocateVertices(int numverts){(void) numverts;} + virtual void preallocateIndices(int numindices){(void) numindices;} + +} +; + +#endif //BT_TRIANGLE_INDEX_VERTEX_ARRAY_H diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleMesh.cpp b/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleMesh.cpp new file mode 100644 index 00000000000..98c54ef45f8 --- /dev/null +++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleMesh.cpp @@ -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. +*/ + +#include "btTriangleMesh.h" +#include + + +btTriangleMesh::btTriangleMesh () +{ + +} + +void btTriangleMesh::getLockedVertexIndexBase(unsigned char **vertexbase, int& numverts,PHY_ScalarType& type, int& stride,unsigned char **indexbase,int & indexstride,int& numfaces,PHY_ScalarType& indicestype,int subpart) +{ + (void)subpart; + numverts = m_vertices.size(); + *vertexbase = (unsigned char*)&m_vertices[0]; + type = PHY_FLOAT; + stride = sizeof(btVector3); + + numfaces = m_indices.size()/3; + *indexbase = (unsigned char*) &m_indices[0]; + indicestype = PHY_INTEGER; + indexstride = 3*sizeof(int); + +} + +void btTriangleMesh::getLockedReadOnlyVertexIndexBase(const unsigned char **vertexbase, int& numverts,PHY_ScalarType& type, int& stride,const unsigned char **indexbase,int & indexstride,int& numfaces,PHY_ScalarType& indicestype,int subpart) const +{ + (void)subpart; + numverts = m_vertices.size(); + *vertexbase = (unsigned char*)&m_vertices[0]; + type = PHY_FLOAT; + stride = sizeof(btVector3); + + numfaces = m_indices.size()/3; + *indexbase = (unsigned char*) &m_indices[0]; + indicestype = PHY_INTEGER; + indexstride = 3*sizeof(int); + +} + + + +int btTriangleMesh::getNumSubParts() const +{ + return 1; +} diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleMesh.h b/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleMesh.h new file mode 100644 index 00000000000..525f5336b48 --- /dev/null +++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleMesh.h @@ -0,0 +1,75 @@ +/* +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 TRIANGLE_MESH_H +#define TRIANGLE_MESH_H + +#include "btStridingMeshInterface.h" +#include "../../LinearMath/btVector3.h" +#include "../../LinearMath/btAlignedObjectArray.h" + +///TriangleMesh provides storage for a concave triangle mesh. It can be used as data for the btTriangleMeshShape. +class btTriangleMesh : public btStridingMeshInterface +{ + btAlignedObjectArray m_vertices; + btAlignedObjectArray m_indices; + + public: + btTriangleMesh (); + + void addTriangle(const btVector3& vertex0,const btVector3& vertex1,const btVector3& vertex2) + { + int curIndex = m_indices.size(); + m_vertices.push_back(vertex0); + m_vertices.push_back(vertex1); + m_vertices.push_back(vertex2); + + m_indices.push_back(curIndex++); + m_indices.push_back(curIndex++); + m_indices.push_back(curIndex++); + } + + int getNumTriangles() const + { + return m_indices.size() / 3; + } + + + +//StridingMeshInterface interface implementation + + virtual void getLockedVertexIndexBase(unsigned char **vertexbase, int& numverts,PHY_ScalarType& type, int& stride,unsigned char **indexbase,int & indexstride,int& numfaces,PHY_ScalarType& indicestype,int subpart=0); + + virtual void getLockedReadOnlyVertexIndexBase(const unsigned char **vertexbase, int& numverts,PHY_ScalarType& type, int& stride,const unsigned char **indexbase,int & indexstride,int& numfaces,PHY_ScalarType& indicestype,int subpart=0) const; + + /// unLockVertexBase finishes the access to a subpart of the triangle mesh + /// make a call to unLockVertexBase when the read and write access (using getLockedVertexIndexBase) is finished + virtual void unLockVertexBase(int subpart) {(void) subpart;} + + virtual void unLockReadOnlyVertexBase(int subpart) const { (void) subpart;} + + /// getNumSubParts returns the number of seperate subparts + /// each subpart has a continuous array of vertices and indices + virtual int getNumSubParts() const; + + virtual void preallocateVertices(int numverts){(void) numverts;} + virtual void preallocateIndices(int numindices){(void) numindices;} + + +}; + +#endif //TRIANGLE_MESH_H + diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleMeshShape.cpp b/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleMeshShape.cpp new file mode 100644 index 00000000000..ed81897b515 --- /dev/null +++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleMeshShape.cpp @@ -0,0 +1,203 @@ +/* +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 "btTriangleMeshShape.h" +#include "LinearMath/btVector3.h" +#include "LinearMath/btQuaternion.h" +#include "btStridingMeshInterface.h" +#include "LinearMath/btAabbUtil2.h" +#include "BulletCollision/CollisionShapes/btCollisionMargin.h" + +#include "stdio.h" + +btTriangleMeshShape::btTriangleMeshShape(btStridingMeshInterface* meshInterface) +: m_meshInterface(meshInterface) +{ + recalcLocalAabb(); +} + + +btTriangleMeshShape::~btTriangleMeshShape() +{ + +} + + + + +void btTriangleMeshShape::getAabb(const btTransform& trans,btVector3& aabbMin,btVector3& aabbMax) const +{ + + btVector3 localHalfExtents = btScalar(0.5)*(m_localAabbMax-m_localAabbMin); + btVector3 localCenter = btScalar(0.5)*(m_localAabbMax+m_localAabbMin); + + btMatrix3x3 abs_b = trans.getBasis().absolute(); + + btPoint3 center = trans(localCenter); + + btVector3 extent = btVector3(abs_b[0].dot(localHalfExtents), + abs_b[1].dot(localHalfExtents), + abs_b[2].dot(localHalfExtents)); + extent += btVector3(getMargin(),getMargin(),getMargin()); + + aabbMin = center - extent; + aabbMax = center + extent; + + +} + +void btTriangleMeshShape::recalcLocalAabb() +{ + for (int i=0;i<3;i++) + { + btVector3 vec(btScalar(0.),btScalar(0.),btScalar(0.)); + vec[i] = btScalar(1.); + btVector3 tmp = localGetSupportingVertex(vec); + m_localAabbMax[i] = tmp[i]+m_collisionMargin; + vec[i] = btScalar(-1.); + tmp = localGetSupportingVertex(vec); + m_localAabbMin[i] = tmp[i]-m_collisionMargin; + } +} + + + +class SupportVertexCallback : public btTriangleCallback +{ + + btVector3 m_supportVertexLocal; +public: + + btTransform m_worldTrans; + btScalar m_maxDot; + btVector3 m_supportVecLocal; + + SupportVertexCallback(const btVector3& supportVecWorld,const btTransform& trans) + : m_supportVertexLocal(btScalar(0.),btScalar(0.),btScalar(0.)), m_worldTrans(trans) ,m_maxDot(btScalar(-1e30)) + + { + m_supportVecLocal = supportVecWorld * m_worldTrans.getBasis(); + } + + virtual void processTriangle( btVector3* triangle,int partId, int triangleIndex) + { + (void)partId; + (void)triangleIndex; + for (int i=0;i<3;i++) + { + btScalar dot = m_supportVecLocal.dot(triangle[i]); + if (dot > m_maxDot) + { + m_maxDot = dot; + m_supportVertexLocal = triangle[i]; + } + } + } + + btVector3 GetSupportVertexWorldSpace() + { + return m_worldTrans(m_supportVertexLocal); + } + + btVector3 GetSupportVertexLocal() + { + return m_supportVertexLocal; + } + +}; + + +void btTriangleMeshShape::setLocalScaling(const btVector3& scaling) +{ + m_meshInterface->setScaling(scaling); + recalcLocalAabb(); +} + +const btVector3& btTriangleMeshShape::getLocalScaling() const +{ + return m_meshInterface->getScaling(); +} + + + + + + +//#define DEBUG_TRIANGLE_MESH + + +void btTriangleMeshShape::processAllTriangles(btTriangleCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const +{ + struct FilteredCallback : public btInternalTriangleIndexCallback + { + btTriangleCallback* m_callback; + btVector3 m_aabbMin; + btVector3 m_aabbMax; + + FilteredCallback(btTriangleCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) + :m_callback(callback), + m_aabbMin(aabbMin), + m_aabbMax(aabbMax) + { + } + + virtual void internalProcessTriangleIndex(btVector3* triangle,int partId,int triangleIndex) + { + if (TestTriangleAgainstAabb2(&triangle[0],m_aabbMin,m_aabbMax)) + { + //check aabb in triangle-space, before doing this + m_callback->processTriangle(triangle,partId,triangleIndex); + } + + } + + }; + + FilteredCallback filterCallback(callback,aabbMin,aabbMax); + + m_meshInterface->InternalProcessAllTriangles(&filterCallback,aabbMin,aabbMax); +} + + + + + + +void btTriangleMeshShape::calculateLocalInertia(btScalar mass,btVector3& inertia) +{ + (void)mass; + //moving concave objects not supported + btAssert(0); + inertia.setValue(btScalar(0.),btScalar(0.),btScalar(0.)); +} + + +btVector3 btTriangleMeshShape::localGetSupportingVertex(const btVector3& vec) const +{ + btVector3 supportVertex; + + btTransform ident; + ident.setIdentity(); + + SupportVertexCallback supportCallback(vec,ident); + + btVector3 aabbMax(btScalar(1e30),btScalar(1e30),btScalar(1e30)); + + processAllTriangles(&supportCallback,-aabbMax,aabbMax); + + supportVertex = supportCallback.GetSupportVertexLocal(); + + return supportVertex; +} diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleMeshShape.h b/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleMeshShape.h new file mode 100644 index 00000000000..e6173e47640 --- /dev/null +++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleMeshShape.h @@ -0,0 +1,78 @@ +/* +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 TRIANGLE_MESH_SHAPE_H +#define TRIANGLE_MESH_SHAPE_H + +#include "btConcaveShape.h" +#include "btStridingMeshInterface.h" + + +///Concave triangle mesh. Uses an interface to access the triangles to allow for sharing graphics/physics triangles. +class btTriangleMeshShape : public btConcaveShape +{ +protected: + btVector3 m_localAabbMin; + btVector3 m_localAabbMax; + btStridingMeshInterface* m_meshInterface; + + +public: + btTriangleMeshShape(btStridingMeshInterface* meshInterface); + + virtual ~btTriangleMeshShape(); + + virtual btVector3 localGetSupportingVertex(const btVector3& vec) const; + + virtual btVector3 localGetSupportingVertexWithoutMargin(const btVector3& vec)const + { + assert(0); + return localGetSupportingVertex(vec); + } + + void recalcLocalAabb(); + + virtual int getShapeType() const + { + return TRIANGLE_MESH_SHAPE_PROXYTYPE; + } + + virtual void getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const; + + virtual void processAllTriangles(btTriangleCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const; + + virtual void calculateLocalInertia(btScalar mass,btVector3& inertia); + + virtual void setLocalScaling(const btVector3& scaling); + virtual const btVector3& getLocalScaling() const; + + btStridingMeshInterface* getMeshInterface() + { + return m_meshInterface; + } + + const btStridingMeshInterface* getMeshInterface() const + { + return m_meshInterface; + } + + + //debugging + virtual char* getName()const {return "TRIANGLEMESH";} + + +}; + +#endif //TRIANGLE_MESH_SHAPE_H diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleShape.h b/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleShape.h new file mode 100644 index 00000000000..c2e240c051c --- /dev/null +++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleShape.h @@ -0,0 +1,179 @@ +/* +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 OBB_TRIANGLE_MINKOWSKI_H +#define OBB_TRIANGLE_MINKOWSKI_H + +#include "btConvexShape.h" +#include "btBoxShape.h" + +class btTriangleShape : public btPolyhedralConvexShape +{ + + +public: + + btVector3 m_vertices1[3]; + + + virtual int getNumVertices() const + { + return 3; + } + + const btVector3& getVertexPtr(int index) const + { + return m_vertices1[index]; + } + virtual void getVertex(int index,btVector3& vert) const + { + vert = m_vertices1[index]; + } + virtual int getShapeType() const + { + return TRIANGLE_SHAPE_PROXYTYPE; + } + + virtual int getNumEdges() const + { + return 3; + } + + virtual void getEdge(int i,btPoint3& pa,btPoint3& pb) const + { + getVertex(i,pa); + getVertex((i+1)%3,pb); + } + + + virtual void getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax)const + { +// btAssert(0); + getAabbSlow(t,aabbMin,aabbMax); + } + + btVector3 localGetSupportingVertexWithoutMargin(const btVector3& dir)const + { + btVector3 dots(dir.dot(m_vertices1[0]), dir.dot(m_vertices1[1]), dir.dot(m_vertices1[2])); + return m_vertices1[dots.maxAxis()]; + + } + + virtual void batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const + { + for (int i=0;i= -tolerance && dist <= tolerance) + { + //inside check on edge-planes + int i; + for (i=0;i<3;i++) + { + btPoint3 pa,pb; + getEdge(i,pa,pb); + btVector3 edge = pb-pa; + btVector3 edgeNormal = edge.cross(normal); + edgeNormal.normalize(); + btScalar dist = pt.dot( edgeNormal); + btScalar edgeConst = pa.dot(edgeNormal); + dist -= edgeConst; + if (dist < -tolerance) + return false; + } + + return true; + } + + return false; + } + //debugging + virtual char* getName()const + { + return "Triangle"; + } + + virtual int getNumPreferredPenetrationDirections() const + { + return 2; + } + + virtual void getPreferredPenetrationDirection(int index, btVector3& penetrationVector) const + { + calcNormal(penetrationVector); + if (index) + penetrationVector *= btScalar(-1.); + } + + +}; + +#endif //OBB_TRIANGLE_MINKOWSKI_H + diff --git a/extern/bullet2/src/BulletCollision/Doxyfile b/extern/bullet2/src/BulletCollision/Doxyfile new file mode 100644 index 00000000000..4ecb6acb62f --- /dev/null +++ b/extern/bullet2/src/BulletCollision/Doxyfile @@ -0,0 +1,746 @@ +# Doxyfile 1.2.4 + +# This file describes the settings to be used by doxygen for a project +# +# All text after a hash (#) is considered a comment and will be ignored +# The format is: +# TAG = value [value, ...] +# For lists items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (" ") + +#--------------------------------------------------------------------------- +# General configuration options +#--------------------------------------------------------------------------- + +# The PROJECT_NAME tag is a single word (or a sequence of words surrounded +# by quotes) that should identify the project. +PROJECT_NAME = "Bullet Continuous Collision Detection Library" + +# The PROJECT_NUMBER tag can be used to enter a project or revision number. +# This could be handy for archiving the generated documentation or +# if some version control system is used. + +PROJECT_NUMBER = + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) +# base path where the generated documentation will be put. +# If a relative path is entered, it will be relative to the location +# where doxygen was started. If left blank the current directory will be used. + +OUTPUT_DIRECTORY = + +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# The default language is English, other supported languages are: +# Dutch, French, Italian, Czech, Swedish, German, Finnish, Japanese, +# Korean, Hungarian, Norwegian, Spanish, Romanian, Russian, Croatian, +# Polish, Portuguese and Slovene. + +OUTPUT_LANGUAGE = English + +# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in +# documentation are documented, even if no documentation was available. +# Private class members and static file members will be hidden unless +# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES + +EXTRACT_ALL = YES + +# If the EXTRACT_PRIVATE tag is set to YES all private members of a class +# will be included in the documentation. + +EXTRACT_PRIVATE = YES + +# If the EXTRACT_STATIC tag is set to YES all static members of a file +# will be included in the documentation. + +EXTRACT_STATIC = YES + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all +# undocumented members of documented classes, files or namespaces. +# If set to NO (the default) these members will be included in the +# various overviews, but no documentation section is generated. +# This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_MEMBERS = NO + +# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. +# If set to NO (the default) these class will be included in the various +# overviews. This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_CLASSES = NO + +# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will +# include brief member descriptions after the members that are listed in +# the file and class documentation (similar to JavaDoc). +# Set to NO to disable this. + +BRIEF_MEMBER_DESC = YES + +# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend +# the brief description of a member or function before the detailed description. +# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# brief descriptions will be completely suppressed. + +REPEAT_BRIEF = YES + +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# Doxygen will generate a detailed section even if there is only a brief +# description. + +ALWAYS_DETAILED_SEC = NO + +# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full +# path before files name in the file list and in the header files. If set +# to NO the shortest path that makes the file name unique will be used. + +FULL_PATH_NAMES = NO + +# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag +# can be used to strip a user defined part of the path. Stripping is +# only done if one of the specified strings matches the left-hand part of +# the path. It is allowed to use relative paths in the argument list. + +STRIP_FROM_PATH = + +# The INTERNAL_DOCS tag determines if documentation +# that is typed after a \internal command is included. If the tag is set +# to NO (the default) then the documentation will be excluded. +# Set it to YES to include the internal documentation. + +INTERNAL_DOCS = NO + +# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will +# generate a class diagram (in Html and LaTeX) for classes with base or +# super classes. Setting the tag to NO turns the diagrams off. + +CLASS_DIAGRAMS = YES + +# If the SOURCE_BROWSER tag is set to YES then a list of source files will +# be generated. Documented entities will be cross-referenced with these sources. + +SOURCE_BROWSER = YES + +# Setting the INLINE_SOURCES tag to YES will include the body +# of functions and classes directly in the documentation. + +INLINE_SOURCES = NO + +# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct +# doxygen to hide any special comment blocks from generated source code +# fragments. Normal C and C++ comments will always remain visible. + +STRIP_CODE_COMMENTS = YES + +# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate +# file names in lower case letters. If set to YES upper case letters are also +# allowed. This is useful if you have classes or files whose names only differ +# in case and if your file system supports case sensitive file names. Windows +# users are adviced to set this option to NO. + +CASE_SENSE_NAMES = YES + +# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen +# will show members with their full class and namespace scopes in the +# documentation. If set to YES the scope will be hidden. + +HIDE_SCOPE_NAMES = NO + +# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen +# will generate a verbatim copy of the header file for each class for +# which an include is specified. Set to NO to disable this. + +VERBATIM_HEADERS = YES + +# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen +# will put list of the files that are included by a file in the documentation +# of that file. + +SHOW_INCLUDE_FILES = YES + +# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen +# will interpret the first line (until the first dot) of a JavaDoc-style +# comment as the brief description. If set to NO, the JavaDoc +# comments will behave just like the Qt-style comments (thus requiring an +# explict @brief command for a brief description. + +JAVADOC_AUTOBRIEF = YES + +# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented +# member inherits the documentation from any documented member that it +# reimplements. + +INHERIT_DOCS = YES + +# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] +# is inserted in the documentation for inline members. + +INLINE_INFO = YES + +# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen +# will sort the (detailed) documentation of file and class members +# alphabetically by member name. If set to NO the members will appear in +# declaration order. + +SORT_MEMBER_DOCS = YES + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES, then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default +# all members of a group must be documented explicitly. + +DISTRIBUTE_GROUP_DOC = NO + +# The TAB_SIZE tag can be used to set the number of spaces in a tab. +# Doxygen uses this value to replace tabs by spaces in code fragments. + +TAB_SIZE = 8 + +# The ENABLE_SECTIONS tag can be used to enable conditional +# documentation sections, marked by \if sectionname ... \endif. + +ENABLED_SECTIONS = + +# The GENERATE_TODOLIST tag can be used to enable (YES) or +# disable (NO) the todo list. This list is created by putting \todo +# commands in the documentation. + +GENERATE_TODOLIST = YES + +# The GENERATE_TESTLIST tag can be used to enable (YES) or +# disable (NO) the test list. This list is created by putting \test +# commands in the documentation. + +GENERATE_TESTLIST = YES + +# This tag can be used to specify a number of aliases that acts +# as commands in the documentation. An alias has the form "name=value". +# For example adding "sideeffect=\par Side Effects:\n" will allow you to +# put the command \sideeffect (or @sideeffect) in the documentation, which +# will result in a user defined paragraph with heading "Side Effects:". +# You can put \n's in the value part of an alias to insert newlines. + +ALIASES = + +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- + +# The QUIET tag can be used to turn on/off the messages that are generated +# by doxygen. Possible values are YES and NO. If left blank NO is used. + +QUIET = NO + +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated by doxygen. Possible values are YES and NO. If left blank +# NO is used. + +WARNINGS = YES + +# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings +# for undocumented members. If EXTRACT_ALL is set to YES then this flag will +# automatically be disabled. + +WARN_IF_UNDOCUMENTED = YES + +# The WARN_FORMAT tag determines the format of the warning messages that +# doxygen can produce. The string should contain the $file, $line, and $text +# tags, which will be replaced by the file and line number from which the +# warning originated and the warning text. + +WARN_FORMAT = "$file:$line: $text" + +# The WARN_LOGFILE tag can be used to specify a file to which warning +# and error messages should be written. If left blank the output is written +# to stderr. + +WARN_LOGFILE = + +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- + +# The INPUT tag can be used to specify the files and/or directories that contain +# documented source files. You may enter file names like "myfile.cpp" or +# directories like "/usr/src/myproject". Separate the files or directories +# with spaces. + +INPUT = . + + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank all files are included. + +FILE_PATTERNS = *.h *.cpp *.c + +# The RECURSIVE tag can be used to turn specify whether or not subdirectories +# should be searched for input files as well. Possible values are YES and NO. +# If left blank NO is used. + +RECURSIVE = YES + +# The EXCLUDE tag can be used to specify files and/or directories that should +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. + +EXCLUDE = + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. + +EXCLUDE_PATTERNS = + +# The EXAMPLE_PATH tag can be used to specify one or more files or +# directories that contain example code fragments that are included (see +# the \include command). + +EXAMPLE_PATH = + +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank all files are included. + +EXAMPLE_PATTERNS = + +# The IMAGE_PATH tag can be used to specify one or more files or +# directories that contain image that are included in the documentation (see +# the \image command). + +IMAGE_PATH = + +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command , where +# is the value of the INPUT_FILTER tag, and is the name of an +# input file. Doxygen will then use the output that the filter program writes +# to standard output. + +INPUT_FILTER = + +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER) will be used to filter the input files when producing source +# files to browse. + +FILTER_SOURCE_FILES = NO + +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- + +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index +# of all compounds will be generated. Enable this if the project +# contains a lot of classes, structs, unions or interfaces. + +ALPHABETICAL_INDEX = NO + +# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then +# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns +# in which this list will be split (can be a number in the range [1..20]) + +COLS_IN_ALPHA_INDEX = 5 + +# In case all classes in a project start with a common prefix, all +# classes will be put under the same header in the alphabetical index. +# The IGNORE_PREFIX tag can be used to specify one or more prefixes that +# should be ignored while generating the index headers. + +IGNORE_PREFIX = + +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- + +# If the GENERATE_HTML tag is set to YES (the default) Doxygen will +# generate HTML output. + +GENERATE_HTML = YES + +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `html' will be used as the default path. + +HTML_OUTPUT = html + +# The HTML_HEADER tag can be used to specify a personal HTML header for +# each generated HTML page. If it is left blank doxygen will generate a +# standard header. + +HTML_HEADER = + +# The HTML_FOOTER tag can be used to specify a personal HTML footer for +# each generated HTML page. If it is left blank doxygen will generate a +# standard footer. + +HTML_FOOTER = + +# The HTML_STYLESHEET tag can be used to specify a user defined cascading +# style sheet that is used by each HTML page. It can be used to +# fine-tune the look of the HTML output. If the tag is left blank doxygen +# will generate a default style sheet + +HTML_STYLESHEET = + +# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, +# files or namespaces will be aligned in HTML using tables. If set to +# NO a bullet list will be used. + +HTML_ALIGN_MEMBERS = YES + +# If the GENERATE_HTMLHELP tag is set to YES, additional index files +# will be generated that can be used as input for tools like the +# Microsoft HTML help workshop to generate a compressed HTML help file (.chm) +# of the generated HTML documentation. + +GENERATE_HTMLHELP = NO + +# The DISABLE_INDEX tag can be used to turn on/off the condensed index at +# top of each HTML page. The value NO (the default) enables the index and +# the value YES disables it. + +DISABLE_INDEX = NO + +# This tag can be used to set the number of enum values (range [1..20]) +# that doxygen will group on one line in the generated HTML documentation. + +ENUM_VALUES_PER_LINE = 4 + +# If the GENERATE_TREEVIEW tag is set to YES, a side pannel will be +# generated containing a tree-like index structure (just like the one that +# is generated for HTML Help). For this to work a browser that supports +# JavaScript and frames is required (for instance Netscape 4.0+ +# or Internet explorer 4.0+). + +GENERATE_TREEVIEW = NO + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be +# used to set the initial width (in pixels) of the frame in which the tree +# is shown. + +TREEVIEW_WIDTH = 250 + +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- + +# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will +# generate Latex output. + +GENERATE_LATEX = NO + +# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `latex' will be used as the default path. + +LATEX_OUTPUT = latex + +# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact +# LaTeX documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_LATEX = NO + +# The PAPER_TYPE tag can be used to set the paper type that is used +# by the printer. Possible values are: a4, a4wide, letter, legal and +# executive. If left blank a4wide will be used. + +PAPER_TYPE = a4wide + +# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX +# packages that should be included in the LaTeX output. + +EXTRA_PACKAGES = + +# The LATEX_HEADER tag can be used to specify a personal LaTeX header for +# the generated latex document. The header should contain everything until +# the first chapter. If it is left blank doxygen will generate a +# standard header. Notice: only use this tag if you know what you are doing! + +LATEX_HEADER = + +# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated +# is prepared for conversion to pdf (using ps2pdf). The pdf file will +# contain links (just like the HTML output) instead of page references +# This makes the output suitable for online browsing using a pdf viewer. + +PDF_HYPERLINKS = NO + +# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of +# plain latex in the generated Makefile. Set this option to YES to get a +# higher quality PDF documentation. + +USE_PDFLATEX = NO + +# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. +# command to the generated LaTeX files. This will instruct LaTeX to keep +# running if errors occur, instead of asking the user for help. +# This option is also used when generating formulas in HTML. + +LATEX_BATCHMODE = NO + +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- + +# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output +# The RTF output is optimised for Word 97 and may not look very pretty with +# other RTF readers or editors. + +GENERATE_RTF = NO + +# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `rtf' will be used as the default path. + +RTF_OUTPUT = rtf + +# If the COMPACT_RTF tag is set to YES Doxygen generates more compact +# RTF documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_RTF = NO + +# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated +# will contain hyperlink fields. The RTF file will +# contain links (just like the HTML output) instead of page references. +# This makes the output suitable for online browsing using a WORD or other. +# programs which support those fields. +# Note: wordpad (write) and others do not support links. + +RTF_HYPERLINKS = NO + +# Load stylesheet definitions from file. Syntax is similar to doxygen's +# config file, i.e. a series of assigments. You only have to provide +# replacements, missing definitions are set to their default value. + +RTF_STYLESHEET_FILE = + +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- + +# If the GENERATE_MAN tag is set to YES (the default) Doxygen will +# generate man pages + +GENERATE_MAN = NO + +# The MAN_OUTPUT tag is used to specify where the man pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `man' will be used as the default path. + +MAN_OUTPUT = man + +# The MAN_EXTENSION tag determines the extension that is added to +# the generated man pages (default is the subroutine's section .3) + +MAN_EXTENSION = .3 + +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- + +# If the GENERATE_XML tag is set to YES Doxygen will +# generate an XML file that captures the structure of +# the code including all documentation. Warning: This feature +# is still experimental and very incomplete. + +GENERATE_XML = NO + +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- + +# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will +# evaluate all C-preprocessor directives found in the sources and include +# files. + +ENABLE_PREPROCESSING = YES + +# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro +# names in the source code. If set to NO (the default) only conditional +# compilation will be performed. Macro expansion can be done in a controlled +# way by setting EXPAND_ONLY_PREDEF to YES. + +MACRO_EXPANSION = NO + +# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES +# then the macro expansion is limited to the macros specified with the +# PREDEFINED and EXPAND_AS_PREDEFINED tags. + +EXPAND_ONLY_PREDEF = NO + +# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files +# in the INCLUDE_PATH (see below) will be search if a #include is found. + +SEARCH_INCLUDES = YES + +# The INCLUDE_PATH tag can be used to specify one or more directories that +# contain include files that are not input files but should be processed by +# the preprocessor. + +INCLUDE_PATH = ../../generic/extern + +# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard +# patterns (like *.h and *.hpp) to filter out the header-files in the +# directories. If left blank, the patterns specified with FILE_PATTERNS will +# be used. + +INCLUDE_FILE_PATTERNS = + +# The PREDEFINED tag can be used to specify one or more macro names that +# are defined before the preprocessor is started (similar to the -D option of +# gcc). The argument of the tag is a list of macros of the form: name +# or name=definition (no spaces). If the definition and the = are +# omitted =1 is assumed. + +PREDEFINED = + +# If the MACRO_EXPANSION and EXPAND_PREDEF_ONLY tags are set to YES then +# this tag can be used to specify a list of macro names that should be expanded. +# The macro definition that is found in the sources will be used. +# Use the PREDEFINED tag if you want to use a different macro definition. + +EXPAND_AS_DEFINED = + +#--------------------------------------------------------------------------- +# Configuration::addtions related to external references +#--------------------------------------------------------------------------- + +# The TAGFILES tag can be used to specify one or more tagfiles. + +TAGFILES = + +# When a file name is specified after GENERATE_TAGFILE, doxygen will create +# a tag file that is based on the input files it reads. + +GENERATE_TAGFILE = + +# If the ALLEXTERNALS tag is set to YES all external classes will be listed +# in the class index. If set to NO only the inherited external classes +# will be listed. + +ALLEXTERNALS = NO + +# The PERL_PATH should be the absolute path and name of the perl script +# interpreter (i.e. the result of `which perl'). + +PERL_PATH = /usr/bin/perl + +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- + +# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is +# available from the path. This tool is part of Graphviz, a graph visualization +# toolkit from AT&T and Lucent Bell Labs. The other options in this section +# have no effect if this option is set to NO (the default) + +HAVE_DOT = YES + +# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect inheritance relations. Setting this tag to YES will force the +# the CLASS_DIAGRAMS tag to NO. + +CLASS_GRAPH = YES + +# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect implementation dependencies (inheritance, containment, and +# class references variables) of the class with other documented classes. + +COLLABORATION_GRAPH = YES + +# If the ENABLE_PREPROCESSING, INCLUDE_GRAPH, and HAVE_DOT tags are set to +# YES then doxygen will generate a graph for each documented file showing +# the direct and indirect include dependencies of the file with other +# documented files. + +INCLUDE_GRAPH = YES + +# If the ENABLE_PREPROCESSING, INCLUDED_BY_GRAPH, and HAVE_DOT tags are set to +# YES then doxygen will generate a graph for each documented header file showing +# the documented files that directly or indirectly include this file + +INCLUDED_BY_GRAPH = YES + +# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen +# will graphical hierarchy of all classes instead of a textual one. + +GRAPHICAL_HIERARCHY = YES + +# The tag DOT_PATH can be used to specify the path where the dot tool can be +# found. If left blank, it is assumed the dot tool can be found on the path. + +DOT_PATH = + +# The MAX_DOT_GRAPH_WIDTH tag can be used to set the maximum allowed width +# (in pixels) of the graphs generated by dot. If a graph becomes larger than +# this value, doxygen will try to truncate the graph, so that it fits within +# the specified constraint. Beware that most browsers cannot cope with very +# large images. + +MAX_DOT_GRAPH_WIDTH = 1024 + +# The MAX_DOT_GRAPH_HEIGHT tag can be used to set the maximum allows height +# (in pixels) of the graphs generated by dot. If a graph becomes larger than +# this value, doxygen will try to truncate the graph, so that it fits within +# the specified constraint. Beware that most browsers cannot cope with very +# large images. + +MAX_DOT_GRAPH_HEIGHT = 1024 + +# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will +# generate a legend page explaining the meaning of the various boxes and +# arrows in the dot generated graphs. + +GENERATE_LEGEND = YES + +#--------------------------------------------------------------------------- +# Configuration::addtions related to the search engine +#--------------------------------------------------------------------------- + +# The SEARCHENGINE tag specifies whether or not a search engine should be +# used. If set to NO the values of all tags below this one will be ignored. + +SEARCHENGINE = NO + +# The CGI_NAME tag should be the name of the CGI script that +# starts the search engine (doxysearch) with the correct parameters. +# A script with this name will be generated by doxygen. + +CGI_NAME = search.cgi + +# The CGI_URL tag should be the absolute URL to the directory where the +# cgi binaries are located. See the documentation of your http daemon for +# details. + +CGI_URL = + +# The DOC_URL tag should be the absolute URL to the directory where the +# documentation is located. If left blank the absolute path to the +# documentation, with file:// prepended to it, will be used. + +DOC_URL = + +# The DOC_ABSPATH tag should be the absolute path to the directory where the +# documentation is located. If left blank the directory on the local machine +# will be used. + +DOC_ABSPATH = + +# The BIN_ABSPATH tag must point to the directory where the doxysearch binary +# is installed. + +BIN_ABSPATH = c:\program files\doxygen\bin + +# The EXT_DOC_PATHS tag can be used to specify one or more paths to +# documentation generated for other projects. This allows doxysearch to search +# the documentation for these projects as well. + +EXT_DOC_PATHS = diff --git a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btContinuousConvexCollision.cpp b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btContinuousConvexCollision.cpp new file mode 100644 index 00000000000..2c565734e97 --- /dev/null +++ b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btContinuousConvexCollision.cpp @@ -0,0 +1,200 @@ +/* +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 "btContinuousConvexCollision.h" +#include "BulletCollision/CollisionShapes/btConvexShape.h" +#include "BulletCollision/CollisionShapes/btMinkowskiSumShape.h" +#include "BulletCollision/NarrowPhaseCollision/btSimplexSolverInterface.h" +#include "LinearMath/btTransformUtil.h" +#include "BulletCollision/CollisionShapes/btSphereShape.h" + +#include "btGjkPairDetector.h" +#include "btPointCollector.h" + + + +btContinuousConvexCollision::btContinuousConvexCollision ( btConvexShape* convexA,btConvexShape* convexB,btSimplexSolverInterface* simplexSolver, btConvexPenetrationDepthSolver* penetrationDepthSolver) +:m_simplexSolver(simplexSolver), +m_penetrationDepthSolver(penetrationDepthSolver), +m_convexA(convexA),m_convexB(convexB) +{ +} + +/// This maximum should not be necessary. It allows for untested/degenerate cases in production code. +/// You don't want your game ever to lock-up. +#define MAX_ITERATIONS 1000 + +bool btContinuousConvexCollision::calcTimeOfImpact( + const btTransform& fromA, + const btTransform& toA, + const btTransform& fromB, + const btTransform& toB, + CastResult& result) +{ + + m_simplexSolver->reset(); + + /// compute linear and angular velocity for this interval, to interpolate + btVector3 linVelA,angVelA,linVelB,angVelB; + btTransformUtil::calculateVelocity(fromA,toA,btScalar(1.),linVelA,angVelA); + btTransformUtil::calculateVelocity(fromB,toB,btScalar(1.),linVelB,angVelB); + + btScalar boundingRadiusA = m_convexA->getAngularMotionDisc(); + btScalar boundingRadiusB = m_convexB->getAngularMotionDisc(); + + btScalar maxAngularProjectedVelocity = angVelA.length() * boundingRadiusA + angVelB.length() * boundingRadiusB; + + btScalar radius = btScalar(0.001); + + btScalar lambda = btScalar(0.); + btVector3 v(1,0,0); + + int maxIter = MAX_ITERATIONS; + + btVector3 n; + n.setValue(btScalar(0.),btScalar(0.),btScalar(0.)); + bool hasResult = false; + btVector3 c; + + btScalar lastLambda = lambda; + //btScalar epsilon = btScalar(0.001); + + int numIter = 0; + //first solution, using GJK + + + btTransform identityTrans; + identityTrans.setIdentity(); + + btSphereShape raySphere(btScalar(0.0)); + raySphere.setMargin(btScalar(0.)); + + +// result.drawCoordSystem(sphereTr); + + btPointCollector pointCollector1; + + { + + btGjkPairDetector gjk(m_convexA,m_convexB,m_simplexSolver,m_penetrationDepthSolver); + btGjkPairDetector::ClosestPointInput input; + + //we don't use margins during CCD + gjk.setIgnoreMargin(true); + + input.m_transformA = fromA; + input.m_transformB = fromB; + gjk.getClosestPoints(input,pointCollector1,0); + + hasResult = pointCollector1.m_hasResult; + c = pointCollector1.m_pointInWorld; + } + + if (hasResult) + { + btScalar dist; + dist = pointCollector1.m_distance; + n = pointCollector1.m_normalOnBInWorld; + + //not close enough + while (dist > radius) + { + numIter++; + if (numIter > maxIter) + return false; //todo: report a failure + + btScalar dLambda = btScalar(0.); + + //calculate safe moving fraction from distance / (linear+rotational velocity) + + //btScalar clippedDist = GEN_min(angularConservativeRadius,dist); + //btScalar clippedDist = dist; + + btScalar projectedLinearVelocity = (linVelB-linVelA).dot(n); + + dLambda = dist / (projectedLinearVelocity+ maxAngularProjectedVelocity); + + lambda = lambda + dLambda; + + if (lambda > btScalar(1.)) + return false; + + if (lambda < btScalar(0.)) + return false; + + //todo: next check with relative epsilon + if (lambda <= lastLambda) + break; + lastLambda = lambda; + + + + //interpolate to next lambda + btTransform interpolatedTransA,interpolatedTransB,relativeTrans; + + btTransformUtil::integrateTransform(fromA,linVelA,angVelA,lambda,interpolatedTransA); + btTransformUtil::integrateTransform(fromB,linVelB,angVelB,lambda,interpolatedTransB); + relativeTrans = interpolatedTransB.inverseTimes(interpolatedTransA); + + result.DebugDraw( lambda ); + + btPointCollector pointCollector; + btGjkPairDetector gjk(m_convexA,m_convexB,m_simplexSolver,m_penetrationDepthSolver); + btGjkPairDetector::ClosestPointInput input; + input.m_transformA = interpolatedTransA; + input.m_transformB = interpolatedTransB; + gjk.getClosestPoints(input,pointCollector,0); + if (pointCollector.m_hasResult) + { + if (pointCollector.m_distance < btScalar(0.)) + { + //degenerate ?! + result.m_fraction = lastLambda; + result.m_normal = n; + return true; + } + c = pointCollector.m_pointInWorld; + + dist = pointCollector.m_distance; + } else + { + //?? + return false; + } + + } + + result.m_fraction = lambda; + result.m_normal = n; + return true; + } + + return false; + +/* +//todo: + //if movement away from normal, discard result + btVector3 move = transBLocalTo.getOrigin() - transBLocalFrom.getOrigin(); + if (result.m_fraction < btScalar(1.)) + { + if (move.dot(result.m_normal) <= btScalar(0.)) + { + } + } +*/ + +} + diff --git a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btContinuousConvexCollision.h b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btContinuousConvexCollision.h new file mode 100644 index 00000000000..9901bab4b45 --- /dev/null +++ b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btContinuousConvexCollision.h @@ -0,0 +1,52 @@ +/* +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 CONTINUOUS_COLLISION_CONVEX_CAST_H +#define CONTINUOUS_COLLISION_CONVEX_CAST_H + +#include "btConvexCast.h" +#include "btSimplexSolverInterface.h" +class btConvexPenetrationDepthSolver; +class btConvexShape; + +/// btContinuousConvexCollision implements angular and linear time of impact for convex objects. +/// Based on Brian Mirtich's Conservative Advancement idea (PhD thesis). +/// Algorithm operates in worldspace, in order to keep inbetween motion globally consistent. +/// It uses GJK at the moment. Future improvement would use minkowski sum / supporting vertex, merging innerloops +class btContinuousConvexCollision : public btConvexCast +{ + btSimplexSolverInterface* m_simplexSolver; + btConvexPenetrationDepthSolver* m_penetrationDepthSolver; + btConvexShape* m_convexA; + btConvexShape* m_convexB; + + +public: + + btContinuousConvexCollision (btConvexShape* shapeA,btConvexShape* shapeB ,btSimplexSolverInterface* simplexSolver,btConvexPenetrationDepthSolver* penetrationDepthSolver); + + virtual bool calcTimeOfImpact( + const btTransform& fromA, + const btTransform& toA, + const btTransform& fromB, + const btTransform& toB, + CastResult& result); + + +}; + +#endif //CONTINUOUS_COLLISION_CONVEX_CAST_H + diff --git a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btConvexCast.cpp b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btConvexCast.cpp new file mode 100644 index 00000000000..d2a1310b232 --- /dev/null +++ b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btConvexCast.cpp @@ -0,0 +1,20 @@ +/* +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 "btConvexCast.h" + +btConvexCast::~btConvexCast() +{ +} diff --git a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btConvexCast.h b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btConvexCast.h new file mode 100644 index 00000000000..3101b59993d --- /dev/null +++ b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btConvexCast.h @@ -0,0 +1,71 @@ +/* +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 CONVEX_CAST_H +#define CONVEX_CAST_H + +#include "../../LinearMath/btTransform.h" +#include "../../LinearMath/btVector3.h" +#include "../../LinearMath/btScalar.h" +class btMinkowskiSumShape; +#include "../../LinearMath/btIDebugDraw.h" + +/// btConvexCast is an interface for Casting +class btConvexCast +{ +public: + + + virtual ~btConvexCast(); + + ///RayResult stores the closest result + /// alternatively, add a callback method to decide about closest/all results + struct CastResult + { + //virtual bool addRayResult(const btVector3& normal,btScalar fraction) = 0; + + virtual void DebugDraw(btScalar fraction) {(void)fraction;} + virtual void drawCoordSystem(const btTransform& trans) {(void)trans;} + + CastResult() + :m_fraction(btScalar(1e30)), + m_debugDrawer(0) + { + } + + + virtual ~CastResult() {}; + + btVector3 m_normal; + btScalar m_fraction; + btTransform m_hitTransformA; + btTransform m_hitTransformB; + + btIDebugDraw* m_debugDrawer; + + }; + + + /// cast a convex against another convex object + virtual bool calcTimeOfImpact( + const btTransform& fromA, + const btTransform& toA, + const btTransform& fromB, + const btTransform& toB, + CastResult& result) = 0; +}; + +#endif //CONVEX_CAST_H diff --git a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btConvexPenetrationDepthSolver.h b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btConvexPenetrationDepthSolver.h new file mode 100644 index 00000000000..7caeba4be45 --- /dev/null +++ b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btConvexPenetrationDepthSolver.h @@ -0,0 +1,43 @@ +/* +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 CONVEX_PENETRATION_DEPTH_H +#define CONVEX_PENETRATION_DEPTH_H + +class btStackAlloc; +class btVector3; +#include "btSimplexSolverInterface.h" +class btConvexShape; +#include "../../LinearMath/btPoint3.h" +class btTransform; + +///ConvexPenetrationDepthSolver provides an interface for penetration depth calculation. +class btConvexPenetrationDepthSolver +{ +public: + + virtual ~btConvexPenetrationDepthSolver() {}; + virtual bool calcPenDepth( btSimplexSolverInterface& simplexSolver, + btConvexShape* convexA,btConvexShape* convexB, + const btTransform& transA,const btTransform& transB, + btVector3& v, btPoint3& pa, btPoint3& pb, + class btIDebugDraw* debugDraw,btStackAlloc* stackAlloc + ) = 0; + + +}; +#endif //CONVEX_PENETRATION_DEPTH_H + diff --git a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btDiscreteCollisionDetectorInterface.h b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btDiscreteCollisionDetectorInterface.h new file mode 100644 index 00000000000..15000c1ab61 --- /dev/null +++ b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btDiscreteCollisionDetectorInterface.h @@ -0,0 +1,88 @@ +/* +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 DISCRETE_COLLISION_DETECTOR1_INTERFACE_H +#define DISCRETE_COLLISION_DETECTOR1_INTERFACE_H +#include "../../LinearMath/btTransform.h" +#include "../../LinearMath/btVector3.h" +class btStackAlloc; + +/// This interface is made to be used by an iterative approach to do TimeOfImpact calculations +/// This interface allows to query for closest points and penetration depth between two (convex) objects +/// the closest point is on the second object (B), and the normal points from the surface on B towards A. +/// distance is between closest points on B and closest point on A. So you can calculate closest point on A +/// by taking closestPointInA = closestPointInB + m_distance * m_normalOnSurfaceB +struct btDiscreteCollisionDetectorInterface +{ + + struct Result + { + + virtual ~Result(){} + + ///setShapeIdentifiers provides experimental support for per-triangle material / custom material combiner + virtual void setShapeIdentifiers(int partId0,int index0, int partId1,int index1)=0; + virtual void addContactPoint(const btVector3& normalOnBInWorld,const btVector3& pointInWorld,btScalar depth)=0; + }; + + struct ClosestPointInput + { + ClosestPointInput() + :m_maximumDistanceSquared(btScalar(1e30)), + m_stackAlloc(0) + { + } + + btTransform m_transformA; + btTransform m_transformB; + btScalar m_maximumDistanceSquared; + btStackAlloc* m_stackAlloc; + }; + + virtual ~btDiscreteCollisionDetectorInterface() {}; + + // + // give either closest points (distance > 0) or penetration (distance) + // the normal always points from B towards A + // + virtual void getClosestPoints(const ClosestPointInput& input,Result& output,class btIDebugDraw* debugDraw) = 0; + +}; + +struct btStorageResult : public btDiscreteCollisionDetectorInterface::Result +{ + btVector3 m_normalOnSurfaceB; + btVector3 m_closestPointInB; + btScalar m_distance; //negative means penetration ! + + btStorageResult() : m_distance(btScalar(1e30)) + { + + } + virtual ~btStorageResult() {}; + + virtual void addContactPoint(const btVector3& normalOnBInWorld,const btVector3& pointInWorld,btScalar depth) + { + if (depth < m_distance) + { + m_normalOnSurfaceB = normalOnBInWorld; + m_closestPointInB = pointInWorld; + m_distance = depth; + } + } +}; + +#endif //DISCRETE_COLLISION_DETECTOR_INTERFACE1_H diff --git a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkConvexCast.cpp b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkConvexCast.cpp new file mode 100644 index 00000000000..93edffeafd6 --- /dev/null +++ b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkConvexCast.cpp @@ -0,0 +1,174 @@ +/* +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 "btGjkConvexCast.h" +#include "BulletCollision/CollisionShapes/btSphereShape.h" +#include "BulletCollision/CollisionShapes/btMinkowskiSumShape.h" +#include "btGjkPairDetector.h" +#include "btPointCollector.h" + + +btGjkConvexCast::btGjkConvexCast(btConvexShape* convexA,btConvexShape* convexB,btSimplexSolverInterface* simplexSolver) +:m_simplexSolver(simplexSolver), +m_convexA(convexA), +m_convexB(convexB) +{ +} + +bool btGjkConvexCast::calcTimeOfImpact( + const btTransform& fromA, + const btTransform& toA, + const btTransform& fromB, + const btTransform& toB, + CastResult& result) +{ + + + btMinkowskiSumShape combi(m_convexA,m_convexB); + btMinkowskiSumShape* convex = &combi; + + btTransform rayFromLocalA; + btTransform rayToLocalA; + + rayFromLocalA = fromA.inverse()* fromB; + rayToLocalA = toA.inverse()* toB; + + + btTransform trA,trB; + trA = btTransform(fromA); + trB = btTransform(fromB); + trA.setOrigin(btPoint3(0,0,0)); + trB.setOrigin(btPoint3(0,0,0)); + + convex->setTransformA(trA); + convex->setTransformB(trB); + + + + + btScalar radius = btScalar(0.01); + + btScalar lambda = btScalar(0.); + btVector3 s = rayFromLocalA.getOrigin(); + btVector3 r = rayToLocalA.getOrigin()-rayFromLocalA.getOrigin(); + btVector3 x = s; + btVector3 n; + n.setValue(0,0,0); + bool hasResult = false; + btVector3 c; + + btScalar lastLambda = lambda; + + //first solution, using GJK + + //no penetration support for now, perhaps pass a pointer when we really want it + btConvexPenetrationDepthSolver* penSolverPtr = 0; + + btTransform identityTrans; + identityTrans.setIdentity(); + + btSphereShape raySphere(btScalar(0.0)); + raySphere.setMargin(btScalar(0.)); + + btTransform sphereTr; + sphereTr.setIdentity(); + sphereTr.setOrigin( rayFromLocalA.getOrigin()); + + result.drawCoordSystem(sphereTr); + { + btPointCollector pointCollector1; + btGjkPairDetector gjk(&raySphere,convex,m_simplexSolver,penSolverPtr); + + btGjkPairDetector::ClosestPointInput input; + input.m_transformA = sphereTr; + input.m_transformB = identityTrans; + gjk.getClosestPoints(input,pointCollector1,0); + + hasResult = pointCollector1.m_hasResult; + c = pointCollector1.m_pointInWorld; + n = pointCollector1.m_normalOnBInWorld; + } + + + + if (hasResult) + { + btScalar dist; + dist = (c-x).length(); + if (dist < radius) + { + //penetration + lastLambda = btScalar(1.); + } + + //not close enough + while (dist > radius) + { + + n = x - c; + btScalar nDotr = n.dot(r); + + if (nDotr >= -(SIMD_EPSILON*SIMD_EPSILON)) + return false; + + lambda = lambda - n.dot(n) / nDotr; + if (lambda <= lastLambda) + break; + + lastLambda = lambda; + + x = s + lambda * r; + + sphereTr.setOrigin( x ); + result.drawCoordSystem(sphereTr); + btPointCollector pointCollector; + btGjkPairDetector gjk(&raySphere,convex,m_simplexSolver,penSolverPtr); + btGjkPairDetector::ClosestPointInput input; + input.m_transformA = sphereTr; + input.m_transformB = identityTrans; + gjk.getClosestPoints(input,pointCollector,0); + if (pointCollector.m_hasResult) + { + if (pointCollector.m_distance < btScalar(0.)) + { + //degeneracy, report a hit + result.m_fraction = lastLambda; + result.m_normal = n; + return true; + } + c = pointCollector.m_pointInWorld; + dist = (c-x).length(); + } else + { + //?? + return false; + } + + } + + if (lastLambda < btScalar(1.)) + { + + result.m_fraction = lastLambda; + result.m_normal = n; + return true; + } + } + + return false; +} + diff --git a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkConvexCast.h b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkConvexCast.h new file mode 100644 index 00000000000..3905c45e6d6 --- /dev/null +++ b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkConvexCast.h @@ -0,0 +1,50 @@ +/* +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 GJK_CONVEX_CAST_H +#define GJK_CONVEX_CAST_H + +#include "../CollisionShapes/btCollisionMargin.h" + +#include "../../LinearMath/btVector3.h" +#include "btConvexCast.h" +class btConvexShape; +class btMinkowskiSumShape; +#include "btSimplexSolverInterface.h" + +///GjkConvexCast performs a raycast on a convex object using support mapping. +class btGjkConvexCast : public btConvexCast +{ + btSimplexSolverInterface* m_simplexSolver; + btConvexShape* m_convexA; + btConvexShape* m_convexB; + +public: + + btGjkConvexCast(btConvexShape* convexA,btConvexShape* convexB,btSimplexSolverInterface* simplexSolver); + + /// cast a convex against another convex object + virtual bool calcTimeOfImpact( + const btTransform& fromA, + const btTransform& toA, + const btTransform& fromB, + const btTransform& toB, + CastResult& result); + +}; + +#endif //GJK_CONVEX_CAST_H diff --git a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkEpa.cpp b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkEpa.cpp new file mode 100644 index 00000000000..8abdfdbb7e5 --- /dev/null +++ b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkEpa.cpp @@ -0,0 +1,628 @@ +/* +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. +*/ + +/* +GJK-EPA collision solver by Nathanael Presson +Nov.2006 +*/ + +#include "btGjkEpa.h" +#include //for memset +#include + +#if defined(DEBUG) || defined (_DEBUG) +#include //for debug printf +#ifdef __SPU__ +#include +#define printf spu_printf +#endif //__SPU__ +#endif + +namespace gjkepa_impl +{ + +// +// Port. typedefs +// + +typedef btScalar F; +typedef bool Z; +typedef int I; +typedef unsigned int U; +typedef unsigned char U1; +typedef unsigned short U2; + +typedef btVector3 Vector3; +typedef btMatrix3x3 Rotation; + +// +// Config +// + +#if 0 +#define BTLOCALSUPPORT localGetSupportingVertexWithoutMargin +#else +#define BTLOCALSUPPORT localGetSupportingVertex +#endif + +// +// Const +// + + +#define cstInf SIMD_INFINITY +#define cstPi SIMD_PI +#define cst2Pi SIMD_2_PI +#define GJK_maxiterations (128) +#define GJK_hashsize (1<<6) +#define GJK_hashmask (GJK_hashsize-1) +#define GJK_insimplex_eps F(0.0001) +#define GJK_sqinsimplex_eps (GJK_insimplex_eps*GJK_insimplex_eps) +#define EPA_maxiterations 256 +#define EPA_inface_eps F(0.01) +#define EPA_accuracy F(0.001) + +// +// Utils +// + +static inline F Abs(F v) { return(v<0?-v:v); } +static inline F Sign(F v) { return(F(v<0?-1:1)); } +template static inline void Swap(T& a,T& b) { T +t(a);a=b;b=t; } +template static inline T Min(const T& a,const T& b) { +return(a static inline T Max(const T& a,const T& b) { +return(a>b?a:b); } +static inline void ClearMemory(void* p,U sz) { memset(p,0,(size_t)sz); +} +#if 0 +template static inline void Raise(const T& object) { +throw(object); } +#else +template static inline void Raise(const T&) {} +#endif + + + +// +// GJK +// +struct GJK + { + struct Mkv + { + Vector3 w; /* Minkowski vertice */ + Vector3 r; /* Ray */ + }; + struct He + { + Vector3 v; + He* n; + }; + btStackAlloc* sa; + btBlock* sablock; + He* table[GJK_hashsize]; + Rotation wrotations[2]; + Vector3 positions[2]; + const btConvexShape* shapes[2]; + Mkv simplex[5]; + Vector3 ray; + U order; + U iterations; + F margin; + Z failed; + // + GJK(btStackAlloc* psa, + const Rotation& wrot0,const Vector3& pos0,const btConvexShape* shape0, + const Rotation& wrot1,const Vector3& pos1,const btConvexShape* shape1, + F pmargin=0) + { + wrotations[0]=wrot0;positions[0]=pos0;shapes[0]=shape0; + wrotations[1]=wrot1;positions[1]=pos1;shapes[1]=shape1; + sa =psa; + sablock =sa->beginBlock(); + margin =pmargin; + failed =false; + } + // + ~GJK() + { + sa->endBlock(sablock); + } + // vdh : very dumm hash + static inline U Hash(const Vector3& v) + { + //this doesn't compile under GCC 3.3.5, so add the ()... + //const U h(U(v[0]*15461)^U(v[1]*83003)^U(v[2]*15473)); + //return(((*((const U*)&h))*169639)&GJK_hashmask); + const U h((U)(v[0]*15461)^(U)(v[1]*83003)^(U)(v[2]*15473)); + return(((*((const U*)&h))*169639)&GJK_hashmask); + } + // + inline Vector3 LocalSupport(const Vector3& d,U i) const + { + return(wrotations[i]*shapes[i]->BTLOCALSUPPORT(d*wrotations[i])+positions[i]); + } + // + inline void Support(const Vector3& d,Mkv& v) const + { + v.r = d; + v.w = LocalSupport(d,0)-LocalSupport(-d,1)+d*margin; + } + #define SPX(_i_) simplex[_i_] + #define SPXW(_i_) simplex[_i_].w + // + inline Z FetchSupport() + { + const U h(Hash(ray)); + He* e = (He*)(table[h]); + while(e) { if(e->v==ray) { --order;return(false); } else e=e->n; } + e=(He*)sa->allocate(sizeof(He));e->v=ray;e->n=table[h];table[h]=e; + Support(ray,simplex[++order]); + return(ray.dot(SPXW(order))>0); + } + // + inline Z SolveSimplex2(const Vector3& ao,const Vector3& ab) + { + if(ab.dot(ao)>=0) + { + const Vector3 cabo(cross(ab,ao)); + if(cabo.length2()>GJK_sqinsimplex_eps) + { ray=cross(cabo,ab); } + else + { return(true); } + } + else + { order=0;SPX(0)=SPX(1);ray=ao; } + return(false); + } + // + inline Z SolveSimplex3(const Vector3& ao,const Vector3& ab,const Vector3& +ac) + { + return(SolveSimplex3a(ao,ab,ac,cross(ab,ac))); + } + // + inline Z SolveSimplex3a(const Vector3& ao,const Vector3& ab,const Vector3& +ac,const Vector3& cabc) + { + if((cross(cabc,ab)).dot(ao)<-GJK_insimplex_eps) + { order=1;SPX(0)=SPX(1);SPX(1)=SPX(2);return(SolveSimplex2(ao,ab)); } + else if((cross(cabc,ac)).dot(ao)>+GJK_insimplex_eps) + { order=1;SPX(1)=SPX(2);return(SolveSimplex2(ao,ac)); } + else + { + const F d(cabc.dot(ao)); + if(Abs(d)>GJK_insimplex_eps) + { + if(d>0) + { ray=cabc; } + else + { ray=-cabc;Swap(SPX(0),SPX(1)); } + return(false); + } else return(true); + } + } + // + inline Z SolveSimplex4(const Vector3& ao,const Vector3& ab,const Vector3& +ac,const Vector3& ad) + { + Vector3 crs; + if((crs=cross(ab,ac)).dot(ao)>GJK_insimplex_eps) + { +order=2;SPX(0)=SPX(1);SPX(1)=SPX(2);SPX(2)=SPX(3);return(SolveSimplex3a(ao,ab,ac,crs)); +} + else if((crs=cross(ac,ad)).dot(ao)>GJK_insimplex_eps) + { order=2;SPX(2)=SPX(3);return(SolveSimplex3a(ao,ac,ad,crs)); } + else if((crs=cross(ad,ab)).dot(ao)>GJK_insimplex_eps) + { +order=2;SPX(1)=SPX(0);SPX(0)=SPX(2);SPX(2)=SPX(3);return(SolveSimplex3a(ao,ad,ab,crs)); +} + else return(true); + } + // + inline Z SearchOrigin(const Vector3& initray=Vector3(1,0,0)) + { + iterations = 0; + order = (U)-1; + failed = false; + ray = initray.normalized(); + ClearMemory(table,sizeof(void*)*GJK_hashsize); + FetchSupport(); + ray = -SPXW(0); + for(;iterations0?rl:1; + if(FetchSupport()) + { + Z found(false); + switch(order) + { + case 1: found=SolveSimplex2(-SPXW(1),SPXW(0)-SPXW(1));break; + case 2: found=SolveSimplex3(-SPXW(2),SPXW(1)-SPXW(2),SPXW(0)-SPXW(2));break; + case 3: found=SolveSimplex4(-SPXW(3),SPXW(2)-SPXW(3),SPXW(1)-SPXW(3),SPXW(0)-SPXW(3));break; + } + if(found) return(true); + } else return(false); + } + failed=true; + return(false); + } + // + inline Z EncloseOrigin() + { + switch(order) + { + /* Point */ + case 0: break; + /* Line */ + case 1: + { + const Vector3 ab(SPXW(1)-SPXW(0)); + const Vector3 b[]={ cross(ab,Vector3(1,0,0)), + cross(ab,Vector3(0,1,0)), + cross(ab,Vector3(0,0,1))}; + const F m[]={b[0].length2(),b[1].length2(),b[2].length2()}; + const Rotation r(btQuaternion(ab.normalized(),cst2Pi/3)); + Vector3 w(b[m[0]>m[1]?m[0]>m[2]?0:2:m[1]>m[2]?1:2]); + Support(w.normalized(),simplex[4]);w=r*w; + Support(w.normalized(),simplex[2]);w=r*w; + Support(w.normalized(),simplex[3]);w=r*w; + order=4; + return(true); + } + break; + /* Triangle */ + case 2: + { + const +Vector3 n(cross((SPXW(1)-SPXW(0)),(SPXW(2)-SPXW(0))).normalized()); + Support( n,simplex[3]); + Support(-n,simplex[4]); + order=4; + return(true); + } + break; + /* Tetrahedron */ + case 3: return(true); + /* Hexahedron */ + case 4: return(true); + } + return(false); + } + #undef SPX + #undef SPXW + }; + +// +// EPA +// +struct EPA + { + // + struct Face + { + const GJK::Mkv* v[3]; + Face* f[3]; + U e[3]; + Vector3 n; + F d; + U mark; + Face* prev; + Face* next; + Face() {} + }; + // + GJK* gjk; + btStackAlloc* sa; + Face* root; + U nfaces; + U iterations; + Vector3 features[2][3]; + Vector3 nearest[2]; + Vector3 normal; + F depth; + Z failed; + // + EPA(GJK* pgjk) + { + gjk = pgjk; + sa = pgjk->sa; + } + // + ~EPA() + { + } + // + inline Vector3 GetCoordinates(const Face* face) const + { + const Vector3 o(face->n*-face->d); + const F a[]={ cross(face->v[0]->w-o,face->v[1]->w-o).length(), + cross(face->v[1]->w-o,face->v[2]->w-o).length(), + cross(face->v[2]->w-o,face->v[0]->w-o).length()}; + const F sm(a[0]+a[1]+a[2]); + return(Vector3(a[1],a[2],a[0])/(sm>0?sm:1)); + } + // + inline Face* FindBest() const + { + Face* bf = 0; + if(root) + { + Face* cf = root; + F bd(cstInf); + do { + if(cf->dd;bf=cf; } + } while(0!=(cf=cf->next)); + } + return(bf); + } + // + inline Z Set(Face* f,const GJK::Mkv* a,const GJK::Mkv* b,const GJK::Mkv* +c) const + { + const Vector3 nrm(cross(b->w-a->w,c->w-a->w)); + const F len(nrm.length()); + const Z valid( (cross(a->w,b->w).dot(nrm)>=-EPA_inface_eps)&& + (cross(b->w,c->w).dot(nrm)>=-EPA_inface_eps)&& + (cross(c->w,a->w).dot(nrm)>=-EPA_inface_eps)); + f->v[0] = a; + f->v[1] = b; + f->v[2] = c; + f->mark = 0; + f->n = nrm/(len>0?len:cstInf); + f->d = Max(0,-f->n.dot(a->w)); + return(valid); + } + // + inline Face* NewFace(const GJK::Mkv* a,const GJK::Mkv* b,const GJK::Mkv* c) + { + Face* pf = (Face*)sa->allocate(sizeof(Face)); + if(Set(pf,a,b,c)) + { + if(root) root->prev=pf; + pf->prev=0; + pf->next=root; + root =pf; + ++nfaces; + } + else + { + pf->prev=pf->next=0; + } + return(pf); + } + // + inline void Detach(Face* face) + { + if(face->prev||face->next) + { + --nfaces; + if(face==root) + { root=face->next;root->prev=0; } + else + { + if(face->next==0) + { face->prev->next=0; } + else + { face->prev->next=face->next;face->next->prev=face->prev; } + } + face->prev=face->next=0; + } + } + // + inline void Link(Face* f0,U e0,Face* f1,U e1) const + { + f0->f[e0]=f1;f1->e[e1]=e0; + f1->f[e1]=f0;f0->e[e0]=e1; + } + // + GJK::Mkv* Support(const Vector3& w) const + { + GJK::Mkv* v =(GJK::Mkv*)sa->allocate(sizeof(GJK::Mkv)); + gjk->Support(w,*v); + return(v); + } + // + U BuildHorizon(U markid,const GJK::Mkv* w,Face& f,U e,Face*& cf,Face*& +ff) + { + static const U mod3[]={0,1,2,0,1}; + U ne(0); + if(f.mark!=markid) + { + const U e1(mod3[e+1]); + if((f.n.dot(w->w)+f.d)>0) + { + Face* nf = NewFace(f.v[e1],f.v[e],w); + Link(nf,0,&f,e); + if(cf) Link(cf,1,nf,2); else ff=nf; + cf=nf;ne=1; + } + else + { + const U e2(mod3[e+2]); + Detach(&f); + f.mark = markid; + ne += BuildHorizon(markid,w,*f.f[e1],f.e[e1],cf,ff); + ne += BuildHorizon(markid,w,*f.f[e2],f.e[e2],cf,ff); + } + } + return(ne); + } + // + inline F EvaluatePD(F accuracy=EPA_accuracy) + { + btBlock* sablock = sa->beginBlock(); + Face* bestface = 0; + U markid(1); + depth = -cstInf; + normal = Vector3(0,0,0); + root = 0; + nfaces = 0; + iterations = 0; + failed = false; + /* Prepare hull */ + if(gjk->EncloseOrigin()) + { + const U* pfidx = 0; + U nfidx= 0; + const U* peidx = 0; + U neidx = 0; + GJK::Mkv* basemkv[5]; + Face* basefaces[6]; + switch(gjk->order) + { + /* Tetrahedron */ + case 3: { + static const U fidx[4][3]={{2,1,0},{3,0,1},{3,1,2},{3,2,0}}; + static const +U eidx[6][4]={{0,0,2,1},{0,1,1,1},{0,2,3,1},{1,0,3,2},{2,0,1,2},{3,0,2,2}}; + pfidx=(const U*)fidx;nfidx=4;peidx=(const U*)eidx;neidx=6; + } break; + /* Hexahedron */ + case 4: { + static const +U fidx[6][3]={{2,0,4},{4,1,2},{1,4,0},{0,3,1},{0,2,3},{1,3,2}}; + static const +U eidx[9][4]={{0,0,4,0},{0,1,2,1},{0,2,1,2},{1,1,5,2},{1,0,2,0},{2,2,3,2},{3,1,5,0},{3,0,4,2},{5,1,4,1}}; + pfidx=(const U*)fidx;nfidx=6;peidx=(const U*)eidx;neidx=9; + } break; + } + U i; + + for( i=0;i<=gjk->order;++i) { +basemkv[i]=(GJK::Mkv*)sa->allocate(sizeof(GJK::Mkv));*basemkv[i]=gjk->simplex[i]; +} + for( i=0;iendBlock(sablock); + return(depth); + } + /* Expand hull */ + for(;iterationsn); + const F d(bf->n.dot(w->w)+bf->d); + bestface = bf; + if(d<-accuracy) + { + Face* cf =0; + Face* ff =0; + U nf = 0; + Detach(bf); + bf->mark=++markid; + for(U i=0;i<3;++i) { +nf+=BuildHorizon(markid,w,*bf->f[i],bf->e[i],cf,ff); } + if(nf<=2) { break; } + Link(cf,1,ff,2); + } else break; + } else break; + } + /* Extract contact */ + if(bestface) + { + const Vector3 b(GetCoordinates(bestface)); + normal = bestface->n; + depth = Max(0,bestface->d); + for(U i=0;i<2;++i) + { + const F s(F(i?-1:1)); + for(U j=0;j<3;++j) + { + features[i][j]=gjk->LocalSupport(s*bestface->v[j]->r,i); + } + } + nearest[0] = features[0][0]*b.x()+features[0][1]*b.y()+features[0][2]*b.z(); + nearest[1] = features[1][0]*b.x()+features[1][1]*b.y()+features[1][2]*b.z(); + } else failed=true; + sa->endBlock(sablock); + return(depth); + } + }; +} + +// +// Api +// + +using namespace gjkepa_impl; + + + +// +bool btGjkEpaSolver::Collide(btConvexShape *shape0,const btTransform &wtrs0, + btConvexShape *shape1,const btTransform &wtrs1, + btScalar radialmargin, + btStackAlloc* stackAlloc, + sResults& results) +{ + + +/* Initialize */ +results.witnesses[0] = +results.witnesses[1] = +results.normal = Vector3(0,0,0); +results.depth = 0; +results.status = sResults::Separated; +results.epa_iterations = 0; +results.gjk_iterations = 0; +/* Use GJK to locate origin */ +GJK gjk(stackAlloc, + wtrs0.getBasis(),wtrs0.getOrigin(),shape0, + wtrs1.getBasis(),wtrs1.getOrigin(),shape1, + radialmargin+EPA_accuracy); +const Z collide(gjk.SearchOrigin()); +results.gjk_iterations = gjk.iterations+1; +if(collide) + { + /* Then EPA for penetration depth */ + EPA epa(&gjk); + const F pd(epa.EvaluatePD()); + results.epa_iterations = epa.iterations+1; + if(pd>0) + { + results.status = sResults::Penetrating; + results.normal = epa.normal; + results.depth = pd; + results.witnesses[0] = epa.nearest[0]; + results.witnesses[1] = epa.nearest[1]; + return(true); + } else { if(epa.failed) results.status=sResults::EPA_Failed; } + } else { if(gjk.failed) results.status=sResults::GJK_Failed; } +return(false); +} + + + + + diff --git a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkEpa.h b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkEpa.h new file mode 100644 index 00000000000..759b30bb17f --- /dev/null +++ b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkEpa.h @@ -0,0 +1,53 @@ +/* +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. +*/ + +/* +GJK-EPA collision solver by Nathanael Presson +Nov.2006 +*/ + + +#ifndef _05E48D53_04E0_49ad_BB0A_D74FE62E7366_ +#define _05E48D53_04E0_49ad_BB0A_D74FE62E7366_ +#include "../CollisionShapes/btConvexShape.h" + +class btStackAlloc; + +///btGjkEpaSolver contributed under zlib by Nathanael Presson +struct btGjkEpaSolver +{ +struct sResults + { + enum eStatus + { + Separated, /* Shapes doesnt penetrate */ + Penetrating, /* Shapes are penetrating */ + GJK_Failed, /* GJK phase fail, no big issue, shapes are probably just 'touching' */ + EPA_Failed, /* EPA phase fail, bigger problem, need to save parameters, and debug */ + } status; + btVector3 witnesses[2]; + btVector3 normal; + btScalar depth; + int epa_iterations; + int gjk_iterations; + }; +static bool Collide(btConvexShape* shape0,const btTransform& wtrs0, + btConvexShape* shape1,const btTransform& wtrs1, + btScalar radialmargin, + btStackAlloc* stackAlloc, + sResults& results); +}; + +#endif diff --git a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.cpp b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.cpp new file mode 100644 index 00000000000..87330493b60 --- /dev/null +++ b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.cpp @@ -0,0 +1,50 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +EPA Copyright (c) Ricardo Padrela 2006 + +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 "BulletCollision/CollisionShapes/btConvexShape.h" +#include "btGjkEpaPenetrationDepthSolver.h" +#include "BulletCollision/NarrowPhaseCollision/btGjkEpa.h" + +bool btGjkEpaPenetrationDepthSolver::calcPenDepth( btSimplexSolverInterface& simplexSolver, + btConvexShape* pConvexA, btConvexShape* pConvexB, + const btTransform& transformA, const btTransform& transformB, + btVector3& v, btPoint3& wWitnessOnA, btPoint3& wWitnessOnB, + class btIDebugDraw* debugDraw, btStackAlloc* stackAlloc ) +{ + + (void)debugDraw; + (void)v; + (void)simplexSolver; + + const btScalar radialmargin(btScalar(0.)); + + btGjkEpaSolver::sResults results; + if(btGjkEpaSolver::Collide( pConvexA,transformA, + pConvexB,transformB, + radialmargin,stackAlloc,results)) + { + // debugDraw->drawLine(results.witnesses[1],results.witnesses[1]+results.normal,btVector3(255,0,0)); + //resultOut->addContactPoint(results.normal,results.witnesses[1],-results.depth); + wWitnessOnA = results.witnesses[0]; + wWitnessOnB = results.witnesses[1]; + return true; + } + + return false; +} + + diff --git a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.h b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.h new file mode 100644 index 00000000000..3916ba0776c --- /dev/null +++ b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.h @@ -0,0 +1,39 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +EPA Copyright (c) Ricardo Padrela 2006 + +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 BT_GJP_EPA_PENETRATION_DEPTH_H +#define BT_GJP_EPA_PENETRATION_DEPTH_H + +#include "btConvexPenetrationDepthSolver.h" + +///EpaPenetrationDepthSolver uses the Expanding Polytope Algorithm to +///calculate the penetration depth between two convex shapes. +class btGjkEpaPenetrationDepthSolver : public btConvexPenetrationDepthSolver +{ + public : + + bool calcPenDepth( btSimplexSolverInterface& simplexSolver, + btConvexShape* pConvexA, btConvexShape* pConvexB, + const btTransform& transformA, const btTransform& transformB, + btVector3& v, btPoint3& wWitnessOnA, btPoint3& wWitnessOnB, + class btIDebugDraw* debugDraw,btStackAlloc* stackAlloc ); + + private : + +}; + +#endif // BT_GJP_EPA_PENETRATION_DEPTH_H + diff --git a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkPairDetector.cpp b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkPairDetector.cpp new file mode 100644 index 00000000000..f1f3f7f7f6c --- /dev/null +++ b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkPairDetector.cpp @@ -0,0 +1,299 @@ +/* +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 "btGjkPairDetector.h" +#include "BulletCollision/CollisionShapes/btConvexShape.h" +#include "BulletCollision/NarrowPhaseCollision/btSimplexSolverInterface.h" +#include "BulletCollision/NarrowPhaseCollision/btConvexPenetrationDepthSolver.h" + +#if defined(DEBUG) || defined (_DEBUG) +#include //for debug printf +#ifdef __SPU__ +#include +#define printf spu_printf +#endif //__SPU__ +#endif + +//must be above the machine epsilon +#define REL_ERROR2 btScalar(1.0e-6) + +//temp globals, to improve GJK/EPA/penetration calculations +int gNumDeepPenetrationChecks = 0; +int gNumGjkChecks = 0; + + + +btGjkPairDetector::btGjkPairDetector(btConvexShape* objectA,btConvexShape* objectB,btSimplexSolverInterface* simplexSolver,btConvexPenetrationDepthSolver* penetrationDepthSolver) +:m_cachedSeparatingAxis(btScalar(0.),btScalar(0.),btScalar(1.)), +m_penetrationDepthSolver(penetrationDepthSolver), +m_simplexSolver(simplexSolver), +m_minkowskiA(objectA), +m_minkowskiB(objectB), +m_ignoreMargin(false), +m_lastUsedMethod(-1), +m_catchDegeneracies(1) +{ +} + +void btGjkPairDetector::getClosestPoints(const ClosestPointInput& input,Result& output,class btIDebugDraw* debugDraw) +{ + btScalar distance=btScalar(0.); + btVector3 normalInB(btScalar(0.),btScalar(0.),btScalar(0.)); + btVector3 pointOnA,pointOnB; + btTransform localTransA = input.m_transformA; + btTransform localTransB = input.m_transformB; + btVector3 positionOffset = (localTransA.getOrigin() + localTransB.getOrigin()) * btScalar(0.5); + localTransA.getOrigin() -= positionOffset; + localTransB.getOrigin() -= positionOffset; + + btScalar marginA = m_minkowskiA->getMargin(); + btScalar marginB = m_minkowskiB->getMargin(); + + gNumGjkChecks++; + + //for CCD we don't use margins + if (m_ignoreMargin) + { + marginA = btScalar(0.); + marginB = btScalar(0.); + } + + m_curIter = 0; + int gGjkMaxIter = 1000;//this is to catch invalid input, perhaps check for #NaN? + m_cachedSeparatingAxis.setValue(0,1,0); + + bool isValid = false; + bool checkSimplex = false; + bool checkPenetration = true; + m_degenerateSimplex = 0; + + m_lastUsedMethod = -1; + + { + btScalar squaredDistance = SIMD_INFINITY; + btScalar delta = btScalar(0.); + + btScalar margin = marginA + marginB; + + + + m_simplexSolver->reset(); + + for ( ; ; ) + //while (true) + { + + btVector3 seperatingAxisInA = (-m_cachedSeparatingAxis)* input.m_transformA.getBasis(); + btVector3 seperatingAxisInB = m_cachedSeparatingAxis* input.m_transformB.getBasis(); + + btVector3 pInA = m_minkowskiA->localGetSupportingVertexWithoutMargin(seperatingAxisInA); + btVector3 qInB = m_minkowskiB->localGetSupportingVertexWithoutMargin(seperatingAxisInB); + btPoint3 pWorld = localTransA(pInA); + btPoint3 qWorld = localTransB(qInB); + + btVector3 w = pWorld - qWorld; + delta = m_cachedSeparatingAxis.dot(w); + + // potential exit, they don't overlap + if ((delta > btScalar(0.0)) && (delta * delta > squaredDistance * input.m_maximumDistanceSquared)) + { + checkPenetration = false; + break; + } + + //exit 0: the new point is already in the simplex, or we didn't come any closer + if (m_simplexSolver->inSimplex(w)) + { + m_degenerateSimplex = 1; + checkSimplex = true; + break; + } + // are we getting any closer ? + btScalar f0 = squaredDistance - delta; + btScalar f1 = squaredDistance * REL_ERROR2; + + if (f0 <= f1) + { + if (f0 <= btScalar(0.)) + { + m_degenerateSimplex = 2; + } + checkSimplex = true; + break; + } + //add current vertex to simplex + m_simplexSolver->addVertex(w, pWorld, qWorld); + + //calculate the closest point to the origin (update vector v) + if (!m_simplexSolver->closest(m_cachedSeparatingAxis)) + { + m_degenerateSimplex = 3; + checkSimplex = true; + break; + } + + btScalar previousSquaredDistance = squaredDistance; + squaredDistance = m_cachedSeparatingAxis.length2(); + + //redundant m_simplexSolver->compute_points(pointOnA, pointOnB); + + //are we getting any closer ? + if (previousSquaredDistance - squaredDistance <= SIMD_EPSILON * previousSquaredDistance) + { + m_simplexSolver->backup_closest(m_cachedSeparatingAxis); + checkSimplex = true; + break; + } + + //degeneracy, this is typically due to invalid/uninitialized worldtransforms for a btCollisionObject + if (m_curIter++ > gGjkMaxIter) + { + #if defined(DEBUG) || defined (_DEBUG) + + printf("btGjkPairDetector maxIter exceeded:%i\n",m_curIter); + printf("sepAxis=(%f,%f,%f), squaredDistance = %f, shapeTypeA=%i,shapeTypeB=%i\n", + m_cachedSeparatingAxis.getX(), + m_cachedSeparatingAxis.getY(), + m_cachedSeparatingAxis.getZ(), + squaredDistance, + m_minkowskiA->getShapeType(), + m_minkowskiB->getShapeType()); + + #endif + break; + + } + + + bool check = (!m_simplexSolver->fullSimplex()); + //bool check = (!m_simplexSolver->fullSimplex() && squaredDistance > SIMD_EPSILON * m_simplexSolver->maxVertex()); + + if (!check) + { + //do we need this backup_closest here ? + m_simplexSolver->backup_closest(m_cachedSeparatingAxis); + break; + } + } + + if (checkSimplex) + { + m_simplexSolver->compute_points(pointOnA, pointOnB); + normalInB = pointOnA-pointOnB; + btScalar lenSqr = m_cachedSeparatingAxis.length2(); + //valid normal + if (lenSqr < 0.0001) + { + m_degenerateSimplex = 5; + } + if (lenSqr > SIMD_EPSILON*SIMD_EPSILON) + { + btScalar rlen = btScalar(1.) / btSqrt(lenSqr ); + normalInB *= rlen; //normalize + btScalar s = btSqrt(squaredDistance); + + btAssert(s > btScalar(0.0)); + pointOnA -= m_cachedSeparatingAxis * (marginA / s); + pointOnB += m_cachedSeparatingAxis * (marginB / s); + distance = ((btScalar(1.)/rlen) - margin); + isValid = true; + + m_lastUsedMethod = 1; + } else + { + m_lastUsedMethod = 2; + } + } + + bool catchDegeneratePenetrationCase = + (m_catchDegeneracies && m_penetrationDepthSolver && m_degenerateSimplex && ((distance+margin) < 0.01)); + + //if (checkPenetration && !isValid) + if (checkPenetration && (!isValid || catchDegeneratePenetrationCase )) + { + //penetration case + + //if there is no way to handle penetrations, bail out + if (m_penetrationDepthSolver) + { + // Penetration depth case. + btVector3 tmpPointOnA,tmpPointOnB; + + gNumDeepPenetrationChecks++; + + bool isValid2 = m_penetrationDepthSolver->calcPenDepth( + *m_simplexSolver, + m_minkowskiA,m_minkowskiB, + localTransA,localTransB, + m_cachedSeparatingAxis, tmpPointOnA, tmpPointOnB, + debugDraw,input.m_stackAlloc + ); + + if (isValid2) + { + btVector3 tmpNormalInB = tmpPointOnB-tmpPointOnA; + btScalar lenSqr = tmpNormalInB.length2(); + if (lenSqr > (SIMD_EPSILON*SIMD_EPSILON)) + { + tmpNormalInB /= btSqrt(lenSqr); + btScalar distance2 = -(tmpPointOnA-tmpPointOnB).length(); + //only replace valid penetrations when the result is deeper (check) + if (!isValid || (distance2 < distance)) + { + distance = distance2; + pointOnA = tmpPointOnA; + pointOnB = tmpPointOnB; + normalInB = tmpNormalInB; + isValid = true; + m_lastUsedMethod = 3; + } else + { + + } + } else + { + //isValid = false; + m_lastUsedMethod = 4; + } + } else + { + m_lastUsedMethod = 5; + } + + } + } + } + + if (isValid) + { +#ifdef __SPU__ + //spu_printf("distance\n"); +#endif //__CELLOS_LV2__ + + + output.addContactPoint( + normalInB, + pointOnB+positionOffset, + distance); + //printf("gjk add:%f",distance); + } + + +} + + + + + diff --git a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkPairDetector.h b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkPairDetector.h new file mode 100644 index 00000000000..af0fe32f6c7 --- /dev/null +++ b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkPairDetector.h @@ -0,0 +1,85 @@ +/* +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 GJK_PAIR_DETECTOR_H +#define GJK_PAIR_DETECTOR_H + +#include "btDiscreteCollisionDetectorInterface.h" +#include "../../LinearMath/btPoint3.h" +#include "../CollisionShapes/btCollisionMargin.h" + +class btConvexShape; +#include "btSimplexSolverInterface.h" +class btConvexPenetrationDepthSolver; + +/// btGjkPairDetector uses GJK to implement the btDiscreteCollisionDetectorInterface +class btGjkPairDetector : public btDiscreteCollisionDetectorInterface +{ + + + btVector3 m_cachedSeparatingAxis; + btConvexPenetrationDepthSolver* m_penetrationDepthSolver; + btSimplexSolverInterface* m_simplexSolver; + btConvexShape* m_minkowskiA; + btConvexShape* m_minkowskiB; + bool m_ignoreMargin; + + +public: + + //some debugging to fix degeneracy problems + int m_lastUsedMethod; + int m_curIter; + int m_degenerateSimplex; + int m_catchDegeneracies; + + + btGjkPairDetector(btConvexShape* objectA,btConvexShape* objectB,btSimplexSolverInterface* simplexSolver,btConvexPenetrationDepthSolver* penetrationDepthSolver); + virtual ~btGjkPairDetector() {}; + + virtual void getClosestPoints(const ClosestPointInput& input,Result& output,class btIDebugDraw* debugDraw); + + void setMinkowskiA(btConvexShape* minkA) + { + m_minkowskiA = minkA; + } + + void setMinkowskiB(btConvexShape* minkB) + { + m_minkowskiB = minkB; + } + void setCachedSeperatingAxis(const btVector3& seperatingAxis) + { + m_cachedSeparatingAxis = seperatingAxis; + } + + void setPenetrationDepthSolver(btConvexPenetrationDepthSolver* penetrationDepthSolver) + { + m_penetrationDepthSolver = penetrationDepthSolver; + } + + ///don't use setIgnoreMargin, it's for Bullet's internal use + void setIgnoreMargin(bool ignoreMargin) + { + m_ignoreMargin = ignoreMargin; + } + + +}; + +#endif //GJK_PAIR_DETECTOR_H diff --git a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btManifoldPoint.h b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btManifoldPoint.h new file mode 100644 index 00000000000..f6a893151da --- /dev/null +++ b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btManifoldPoint.h @@ -0,0 +1,99 @@ +/* +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 MANIFOLD_CONTACT_POINT_H +#define MANIFOLD_CONTACT_POINT_H + +#include "../../LinearMath/btVector3.h" +#include "../../LinearMath/btTransformUtil.h" + + + + + +/// ManifoldContactPoint collects and maintains persistent contactpoints. +/// used to improve stability and performance of rigidbody dynamics response. +class btManifoldPoint + { + public: + btManifoldPoint() + :m_userPersistentData(0), + m_lifeTime(0) + { + } + + btManifoldPoint( const btVector3 &pointA, const btVector3 &pointB, + const btVector3 &normal, + btScalar distance ) : + m_localPointA( pointA ), + m_localPointB( pointB ), + m_normalWorldOnB( normal ), + m_distance1( distance ), + m_combinedFriction(btScalar(0.)), + m_combinedRestitution(btScalar(0.)), + m_userPersistentData(0), + m_lifeTime(0) + { + + + } + + + + btVector3 m_localPointA; + btVector3 m_localPointB; + btVector3 m_positionWorldOnB; + ///m_positionWorldOnA is redundant information, see getPositionWorldOnA(), but for clarity + btVector3 m_positionWorldOnA; + btVector3 m_normalWorldOnB; + + btScalar m_distance1; + btScalar m_combinedFriction; + btScalar m_combinedRestitution; + + + mutable void* m_userPersistentData; + + int m_lifeTime;//lifetime of the contactpoint in frames + + btScalar getDistance() const + { + return m_distance1; + } + int getLifeTime() const + { + return m_lifeTime; + } + + const btVector3& getPositionWorldOnA() const { + return m_positionWorldOnA; +// return m_positionWorldOnB + m_normalWorldOnB * m_distance1; + } + + const btVector3& getPositionWorldOnB() const + { + return m_positionWorldOnB; + } + + void setDistance(btScalar dist) + { + m_distance1 = dist; + } + + + + }; + +#endif //MANIFOLD_CONTACT_POINT_H diff --git a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.cpp b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.cpp new file mode 100644 index 00000000000..c4bab3a134a --- /dev/null +++ b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.cpp @@ -0,0 +1,334 @@ +/* +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 "btMinkowskiPenetrationDepthSolver.h" +#include "BulletCollision/CollisionShapes/btMinkowskiSumShape.h" +#include "BulletCollision/NarrowPhaseCollision/btSubSimplexConvexCast.h" +#include "BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.h" +#include "BulletCollision/NarrowPhaseCollision/btGjkPairDetector.h" + + + + +#define NUM_UNITSPHERE_POINTS 42 +static btVector3 sPenetrationDirections[NUM_UNITSPHERE_POINTS+MAX_PREFERRED_PENETRATION_DIRECTIONS*2] = +{ +btVector3(btScalar(0.000000) , btScalar(-0.000000),btScalar(-1.000000)), +btVector3(btScalar(0.723608) , btScalar(-0.525725),btScalar(-0.447219)), +btVector3(btScalar(-0.276388) , btScalar(-0.850649),btScalar(-0.447219)), +btVector3(btScalar(-0.894426) , btScalar(-0.000000),btScalar(-0.447216)), +btVector3(btScalar(-0.276388) , btScalar(0.850649),btScalar(-0.447220)), +btVector3(btScalar(0.723608) , btScalar(0.525725),btScalar(-0.447219)), +btVector3(btScalar(0.276388) , btScalar(-0.850649),btScalar(0.447220)), +btVector3(btScalar(-0.723608) , btScalar(-0.525725),btScalar(0.447219)), +btVector3(btScalar(-0.723608) , btScalar(0.525725),btScalar(0.447219)), +btVector3(btScalar(0.276388) , btScalar(0.850649),btScalar(0.447219)), +btVector3(btScalar(0.894426) , btScalar(0.000000),btScalar(0.447216)), +btVector3(btScalar(-0.000000) , btScalar(0.000000),btScalar(1.000000)), +btVector3(btScalar(0.425323) , btScalar(-0.309011),btScalar(-0.850654)), +btVector3(btScalar(-0.162456) , btScalar(-0.499995),btScalar(-0.850654)), +btVector3(btScalar(0.262869) , btScalar(-0.809012),btScalar(-0.525738)), +btVector3(btScalar(0.425323) , btScalar(0.309011),btScalar(-0.850654)), +btVector3(btScalar(0.850648) , btScalar(-0.000000),btScalar(-0.525736)), +btVector3(btScalar(-0.525730) , btScalar(-0.000000),btScalar(-0.850652)), +btVector3(btScalar(-0.688190) , btScalar(-0.499997),btScalar(-0.525736)), +btVector3(btScalar(-0.162456) , btScalar(0.499995),btScalar(-0.850654)), +btVector3(btScalar(-0.688190) , btScalar(0.499997),btScalar(-0.525736)), +btVector3(btScalar(0.262869) , btScalar(0.809012),btScalar(-0.525738)), +btVector3(btScalar(0.951058) , btScalar(0.309013),btScalar(0.000000)), +btVector3(btScalar(0.951058) , btScalar(-0.309013),btScalar(0.000000)), +btVector3(btScalar(0.587786) , btScalar(-0.809017),btScalar(0.000000)), +btVector3(btScalar(0.000000) , btScalar(-1.000000),btScalar(0.000000)), +btVector3(btScalar(-0.587786) , btScalar(-0.809017),btScalar(0.000000)), +btVector3(btScalar(-0.951058) , btScalar(-0.309013),btScalar(-0.000000)), +btVector3(btScalar(-0.951058) , btScalar(0.309013),btScalar(-0.000000)), +btVector3(btScalar(-0.587786) , btScalar(0.809017),btScalar(-0.000000)), +btVector3(btScalar(-0.000000) , btScalar(1.000000),btScalar(-0.000000)), +btVector3(btScalar(0.587786) , btScalar(0.809017),btScalar(-0.000000)), +btVector3(btScalar(0.688190) , btScalar(-0.499997),btScalar(0.525736)), +btVector3(btScalar(-0.262869) , btScalar(-0.809012),btScalar(0.525738)), +btVector3(btScalar(-0.850648) , btScalar(0.000000),btScalar(0.525736)), +btVector3(btScalar(-0.262869) , btScalar(0.809012),btScalar(0.525738)), +btVector3(btScalar(0.688190) , btScalar(0.499997),btScalar(0.525736)), +btVector3(btScalar(0.525730) , btScalar(0.000000),btScalar(0.850652)), +btVector3(btScalar(0.162456) , btScalar(-0.499995),btScalar(0.850654)), +btVector3(btScalar(-0.425323) , btScalar(-0.309011),btScalar(0.850654)), +btVector3(btScalar(-0.425323) , btScalar(0.309011),btScalar(0.850654)), +btVector3(btScalar(0.162456) , btScalar(0.499995),btScalar(0.850654)) +}; + + +bool btMinkowskiPenetrationDepthSolver::calcPenDepth(btSimplexSolverInterface& simplexSolver, + btConvexShape* convexA,btConvexShape* convexB, + const btTransform& transA,const btTransform& transB, + btVector3& v, btPoint3& pa, btPoint3& pb, + class btIDebugDraw* debugDraw,btStackAlloc* stackAlloc + ) +{ + + (void)stackAlloc; + (void)v; + + + struct btIntermediateResult : public btDiscreteCollisionDetectorInterface::Result + { + + btIntermediateResult():m_hasResult(false) + { + } + + btVector3 m_normalOnBInWorld; + btVector3 m_pointInWorld; + btScalar m_depth; + bool m_hasResult; + + virtual void setShapeIdentifiers(int partId0,int index0, int partId1,int index1) + { + (void)partId0; + (void)index0; + (void)partId1; + (void)index1; + } + void addContactPoint(const btVector3& normalOnBInWorld,const btVector3& pointInWorld,btScalar depth) + { + m_normalOnBInWorld = normalOnBInWorld; + m_pointInWorld = pointInWorld; + m_depth = depth; + m_hasResult = true; + } + }; + + //just take fixed number of orientation, and sample the penetration depth in that direction + btScalar minProj = btScalar(1e30); + btVector3 minNorm; + btVector3 minVertex; + btVector3 minA,minB; + btVector3 seperatingAxisInA,seperatingAxisInB; + btVector3 pInA,qInB,pWorld,qWorld,w; + +#define USE_BATCHED_SUPPORT 1 +#ifdef USE_BATCHED_SUPPORT + + btVector3 supportVerticesABatch[NUM_UNITSPHERE_POINTS+MAX_PREFERRED_PENETRATION_DIRECTIONS*2]; + btVector3 supportVerticesBBatch[NUM_UNITSPHERE_POINTS+MAX_PREFERRED_PENETRATION_DIRECTIONS*2]; + btVector3 seperatingAxisInABatch[NUM_UNITSPHERE_POINTS+MAX_PREFERRED_PENETRATION_DIRECTIONS*2]; + btVector3 seperatingAxisInBBatch[NUM_UNITSPHERE_POINTS+MAX_PREFERRED_PENETRATION_DIRECTIONS*2]; + int i; + + int numSampleDirections = NUM_UNITSPHERE_POINTS; + + for (i=0;igetNumPreferredPenetrationDirections(); + if (numPDA) + { + for (int i=0;igetPreferredPenetrationDirection(i,norm); + norm = transA.getBasis() * norm; + sPenetrationDirections[numSampleDirections] = norm; + seperatingAxisInABatch[numSampleDirections] = (-norm) * transA.getBasis(); + seperatingAxisInBBatch[numSampleDirections] = norm * transB.getBasis(); + numSampleDirections++; + } + } + } + + { + int numPDB = convexB->getNumPreferredPenetrationDirections(); + if (numPDB) + { + for (int i=0;igetPreferredPenetrationDirection(i,norm); + norm = transB.getBasis() * norm; + sPenetrationDirections[numSampleDirections] = norm; + seperatingAxisInABatch[numSampleDirections] = (-norm) * transA.getBasis(); + seperatingAxisInBBatch[numSampleDirections] = norm * transB.getBasis(); + numSampleDirections++; + } + } + } + + + + convexA->batchedUnitVectorGetSupportingVertexWithoutMargin(seperatingAxisInABatch,supportVerticesABatch,numSampleDirections); + convexB->batchedUnitVectorGetSupportingVertexWithoutMargin(seperatingAxisInBBatch,supportVerticesBBatch,numSampleDirections); + + for (i=0;igetNumPreferredPenetrationDirections(); + if (numPDA) + { + for (int i=0;igetPreferredPenetrationDirection(i,norm); + norm = transA.getBasis() * norm; + sPenetrationDirections[numSampleDirections] = norm; + numSampleDirections++; + } + } + } + + { + int numPDB = convexB->getNumPreferredPenetrationDirections(); + if (numPDB) + { + for (int i=0;igetPreferredPenetrationDirection(i,norm); + norm = transB.getBasis() * norm; + sPenetrationDirections[numSampleDirections] = norm; + numSampleDirections++; + } + } + } + + for (int i=0;ilocalGetSupportingVertexWithoutMargin(seperatingAxisInA); + qInB = convexB->localGetSupportingVertexWithoutMargin(seperatingAxisInB); + pWorld = transA(pInA); + qWorld = transB(qInB); + w = qWorld - pWorld; + btScalar delta = norm.dot(w); + //find smallest delta + if (delta < minProj) + { + minProj = delta; + minNorm = norm; + minA = pWorld; + minB = qWorld; + } + } +#endif //USE_BATCHED_SUPPORT + + //add the margins + + minA += minNorm*convexA->getMargin(); + minB -= minNorm*convexB->getMargin(); + //no penetration + if (minProj < btScalar(0.)) + return false; + + minProj += (convexA->getMargin() + convexB->getMargin()); + + + + + +//#define DEBUG_DRAW 1 +#ifdef DEBUG_DRAW + if (debugDraw) + { + btVector3 color(0,1,0); + debugDraw->drawLine(minA,minB,color); + color = btVector3 (1,1,1); + btVector3 vec = minB-minA; + btScalar prj2 = minNorm.dot(vec); + debugDraw->drawLine(minA,minA+(minNorm*minProj),color); + + } +#endif //DEBUG_DRAW + + + + btGjkPairDetector gjkdet(convexA,convexB,&simplexSolver,0); + + btScalar offsetDist = minProj; + btVector3 offset = minNorm * offsetDist; + + + + btGjkPairDetector::ClosestPointInput input; + + btVector3 newOrg = transA.getOrigin() + offset; + + btTransform displacedTrans = transA; + displacedTrans.setOrigin(newOrg); + + input.m_transformA = displacedTrans; + input.m_transformB = transB; + input.m_maximumDistanceSquared = btScalar(1e30);//minProj; + + btIntermediateResult res; + gjkdet.getClosestPoints(input,res,debugDraw); + + btScalar correctedMinNorm = minProj - res.m_depth; + + + //the penetration depth is over-estimated, relax it + btScalar penetration_relaxation= btScalar(1.); + minNorm*=penetration_relaxation; + + if (res.m_hasResult) + { + + pa = res.m_pointInWorld - minNorm * correctedMinNorm; + pb = res.m_pointInWorld; + +#ifdef DEBUG_DRAW + if (debugDraw) + { + btVector3 color(1,0,0); + debugDraw->drawLine(pa,pb,color); + } +#endif//DEBUG_DRAW + + + } + return res.m_hasResult; +} + + + diff --git a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.h b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.h new file mode 100644 index 00000000000..b348b21b52a --- /dev/null +++ b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.h @@ -0,0 +1,37 @@ +/* +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 MINKOWSKI_PENETRATION_DEPTH_SOLVER_H +#define MINKOWSKI_PENETRATION_DEPTH_SOLVER_H + +#include "btConvexPenetrationDepthSolver.h" + +///MinkowskiPenetrationDepthSolver implements bruteforce penetration depth estimation. +///Implementation is based on sampling the depth using support mapping, and using GJK step to get the witness points. +class btMinkowskiPenetrationDepthSolver : public btConvexPenetrationDepthSolver +{ +public: + + virtual bool calcPenDepth( btSimplexSolverInterface& simplexSolver, + btConvexShape* convexA,btConvexShape* convexB, + const btTransform& transA,const btTransform& transB, + btVector3& v, btPoint3& pa, btPoint3& pb, + class btIDebugDraw* debugDraw,btStackAlloc* stackAlloc + ); + +}; + +#endif //MINKOWSKI_PENETRATION_DEPTH_SOLVER_H + diff --git a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btPersistentManifold.cpp b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btPersistentManifold.cpp new file mode 100644 index 00000000000..08cb3ed334d --- /dev/null +++ b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btPersistentManifold.cpp @@ -0,0 +1,246 @@ +/* +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 "btPersistentManifold.h" +#include "LinearMath/btTransform.h" +#include + +btScalar gContactBreakingThreshold = btScalar(0.02); +ContactDestroyedCallback gContactDestroyedCallback = 0; + + + +btPersistentManifold::btPersistentManifold() +:m_body0(0), +m_body1(0), +m_cachedPoints (0), +m_index1(0) +{ +} + + +void btPersistentManifold::clearManifold() +{ + int i; + for (i=0;i +void btPersistentManifold::DebugPersistency() +{ + int i; + printf("DebugPersistency : numPoints %d\n",m_cachedPoints); + for (i=0;i1) + printf("error in clearUserCache\n"); + } + } + assert(occurance<=0); +#endif //DEBUG_PERSISTENCY + + if (pt.m_userPersistentData && gContactDestroyedCallback) + { + (*gContactDestroyedCallback)(pt.m_userPersistentData); + pt.m_userPersistentData = 0; + } + +#ifdef DEBUG_PERSISTENCY + DebugPersistency(); +#endif + } + + +} + + +int btPersistentManifold::sortCachedPoints(const btManifoldPoint& pt) +{ + + //calculate 4 possible cases areas, and take biggest area + //also need to keep 'deepest' + + int maxPenetrationIndex = -1; +#define KEEP_DEEPEST_POINT 1 +#ifdef KEEP_DEEPEST_POINT + btScalar maxPenetration = pt.getDistance(); + for (int i=0;i<4;i++) + { + if (m_pointCache[i].getDistance() < maxPenetration) + { + maxPenetrationIndex = i; + maxPenetration = m_pointCache[i].getDistance(); + } + } +#endif //KEEP_DEEPEST_POINT + + btScalar res0(btScalar(0.)),res1(btScalar(0.)),res2(btScalar(0.)),res3(btScalar(0.)); + if (maxPenetrationIndex != 0) + { + btVector3 a0 = pt.m_localPointA-m_pointCache[1].m_localPointA; + btVector3 b0 = m_pointCache[3].m_localPointA-m_pointCache[2].m_localPointA; + btVector3 cross = a0.cross(b0); + res0 = cross.length2(); + } + if (maxPenetrationIndex != 1) + { + btVector3 a1 = pt.m_localPointA-m_pointCache[0].m_localPointA; + btVector3 b1 = m_pointCache[3].m_localPointA-m_pointCache[2].m_localPointA; + btVector3 cross = a1.cross(b1); + res1 = cross.length2(); + } + + if (maxPenetrationIndex != 2) + { + btVector3 a2 = pt.m_localPointA-m_pointCache[0].m_localPointA; + btVector3 b2 = m_pointCache[3].m_localPointA-m_pointCache[1].m_localPointA; + btVector3 cross = a2.cross(b2); + res2 = cross.length2(); + } + + if (maxPenetrationIndex != 3) + { + btVector3 a3 = pt.m_localPointA-m_pointCache[0].m_localPointA; + btVector3 b3 = m_pointCache[2].m_localPointA-m_pointCache[1].m_localPointA; + btVector3 cross = a3.cross(b3); + res3 = cross.length2(); + } + + btVector4 maxvec(res0,res1,res2,res3); + int biggestarea = maxvec.closestAxis4(); + return biggestarea; +} + + +int btPersistentManifold::getCacheEntry(const btManifoldPoint& newPoint) const +{ + btScalar shortestDist = getContactBreakingThreshold() * getContactBreakingThreshold(); + int size = getNumContacts(); + int nearestPoint = -1; + for( int i = 0; i < size; i++ ) + { + const btManifoldPoint &mp = m_pointCache[i]; + + btVector3 diffA = mp.m_localPointA- newPoint.m_localPointA; + const btScalar distToManiPoint = diffA.dot(diffA); + if( distToManiPoint < shortestDist ) + { + shortestDist = distToManiPoint; + nearestPoint = i; + } + } + return nearestPoint; +} + +void btPersistentManifold::AddManifoldPoint(const btManifoldPoint& newPoint) +{ + assert(validContactDistance(newPoint)); + + int insertIndex = getNumContacts(); + if (insertIndex == MANIFOLD_CACHE_SIZE) + { +#if MANIFOLD_CACHE_SIZE >= 4 + //sort cache so best points come first, based on area + insertIndex = sortCachedPoints(newPoint); +#else + insertIndex = 0; +#endif + + + } else + { + m_cachedPoints++; + + + } + replaceContactPoint(newPoint,insertIndex); +} + +btScalar btPersistentManifold::getContactBreakingThreshold() const +{ + return gContactBreakingThreshold; +} + +void btPersistentManifold::refreshContactPoints(const btTransform& trA,const btTransform& trB) +{ + int i; + + /// first refresh worldspace positions and distance + for (i=getNumContacts()-1;i>=0;i--) + { + btManifoldPoint &manifoldPoint = m_pointCache[i]; + manifoldPoint.m_positionWorldOnA = trA( manifoldPoint.m_localPointA ); + manifoldPoint.m_positionWorldOnB = trB( manifoldPoint.m_localPointB ); + manifoldPoint.m_distance1 = (manifoldPoint.m_positionWorldOnA - manifoldPoint.m_positionWorldOnB).dot(manifoldPoint.m_normalWorldOnB); + manifoldPoint.m_lifeTime++; + } + + /// then + btScalar distance2d; + btVector3 projectedDifference,projectedPoint; + for (i=getNumContacts()-1;i>=0;i--) + { + + btManifoldPoint &manifoldPoint = m_pointCache[i]; + //contact becomes invalid when signed distance exceeds margin (projected on contactnormal direction) + if (!validContactDistance(manifoldPoint)) + { + removeContactPoint(i); + } else + { + //contact also becomes invalid when relative movement orthogonal to normal exceeds margin + projectedPoint = manifoldPoint.m_positionWorldOnA - manifoldPoint.m_normalWorldOnB * manifoldPoint.m_distance1; + projectedDifference = manifoldPoint.m_positionWorldOnB - projectedPoint; + distance2d = projectedDifference.dot(projectedDifference); + if (distance2d > getContactBreakingThreshold()*getContactBreakingThreshold() ) + { + removeContactPoint(i); + } + } + } +#ifdef DEBUG_PERSISTENCY + DebugPersistency(); +#endif // +} + + + + + diff --git a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btPersistentManifold.h b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btPersistentManifold.h new file mode 100644 index 00000000000..a5918b84db3 --- /dev/null +++ b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btPersistentManifold.h @@ -0,0 +1,161 @@ +/* +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 PERSISTENT_MANIFOLD_H +#define PERSISTENT_MANIFOLD_H + + +#include "../../LinearMath/btVector3.h" +#include "../../LinearMath/btTransform.h" +#include "btManifoldPoint.h" + +struct btCollisionResult; + +///contact breaking and merging threshold +extern btScalar gContactBreakingThreshold; + +typedef bool (*ContactDestroyedCallback)(void* userPersistentData); +extern ContactDestroyedCallback gContactDestroyedCallback; + + + + +#define MANIFOLD_CACHE_SIZE 4 + +///btPersistentManifold maintains contact points, and reduces them to 4. +///It does contact filtering/contact reduction. +ATTRIBUTE_ALIGNED16( class) btPersistentManifold +{ + + btManifoldPoint m_pointCache[MANIFOLD_CACHE_SIZE]; + + /// this two body pointers can point to the physics rigidbody class. + /// void* will allow any rigidbody class + void* m_body0; + void* m_body1; + int m_cachedPoints; + + + /// sort cached points so most isolated points come first + int sortCachedPoints(const btManifoldPoint& pt); + + int findContactPoint(const btManifoldPoint* unUsed, int numUnused,const btManifoldPoint& pt); + +public: + + int m_index1; + + btPersistentManifold(); + + btPersistentManifold(void* body0,void* body1) + : m_body0(body0),m_body1(body1),m_cachedPoints(0) + { + } + + inline void* getBody0() { return m_body0;} + inline void* getBody1() { return m_body1;} + + inline const void* getBody0() const { return m_body0;} + inline const void* getBody1() const { return m_body1;} + + void setBodies(void* body0,void* body1) + { + m_body0 = body0; + m_body1 = body1; + } + + void clearUserCache(btManifoldPoint& pt); + +#ifdef DEBUG_PERSISTENCY + void DebugPersistency(); +#endif // + + inline int getNumContacts() const { return m_cachedPoints;} + + inline const btManifoldPoint& getContactPoint(int index) const + { + btAssert(index < m_cachedPoints); + return m_pointCache[index]; + } + + inline btManifoldPoint& getContactPoint(int index) + { + btAssert(index < m_cachedPoints); + return m_pointCache[index]; + } + + /// todo: get this margin from the current physics / collision environment + btScalar getContactBreakingThreshold() const; + + int getCacheEntry(const btManifoldPoint& newPoint) const; + + void AddManifoldPoint( const btManifoldPoint& newPoint); + + void removeContactPoint (int index) + { + clearUserCache(m_pointCache[index]); + + int lastUsedIndex = getNumContacts() - 1; +// m_pointCache[index] = m_pointCache[lastUsedIndex]; + if(index != lastUsedIndex) + { + m_pointCache[index] = m_pointCache[lastUsedIndex]; + //get rid of duplicated userPersistentData pointer + m_pointCache[lastUsedIndex].m_userPersistentData = 0; + } + + btAssert(m_pointCache[lastUsedIndex].m_userPersistentData==0); + m_cachedPoints--; + } + void replaceContactPoint(const btManifoldPoint& newPoint,int insertIndex) + { + btAssert(validContactDistance(newPoint)); + +#define MAINTAIN_PERSISTENCY 1 +#ifdef MAINTAIN_PERSISTENCY + int lifeTime = m_pointCache[insertIndex].getLifeTime(); + btAssert(lifeTime>=0); + void* cache = m_pointCache[insertIndex].m_userPersistentData; + + m_pointCache[insertIndex] = newPoint; + + m_pointCache[insertIndex].m_userPersistentData = cache; + m_pointCache[insertIndex].m_lifeTime = lifeTime; +#else + clearUserCache(m_pointCache[insertIndex]); + m_pointCache[insertIndex] = newPoint; + +#endif + } + + bool validContactDistance(const btManifoldPoint& pt) const + { + return pt.m_distance1 <= getContactBreakingThreshold(); + } + /// calculated new worldspace coordinates and depth, and reject points that exceed the collision margin + void refreshContactPoints( const btTransform& trA,const btTransform& trB); + + void clearManifold(); + + + +} +; + + + + + +#endif //PERSISTENT_MANIFOLD_H diff --git a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btPointCollector.h b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btPointCollector.h new file mode 100644 index 00000000000..6262f44b9f1 --- /dev/null +++ b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btPointCollector.h @@ -0,0 +1,61 @@ +/* +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 POINT_COLLECTOR_H +#define POINT_COLLECTOR_H + +#include "btDiscreteCollisionDetectorInterface.h" + + + +struct btPointCollector : public btDiscreteCollisionDetectorInterface::Result +{ + + + btVector3 m_normalOnBInWorld; + btVector3 m_pointInWorld; + btScalar m_distance;//negative means penetration + + bool m_hasResult; + + btPointCollector () + : m_distance(btScalar(1e30)),m_hasResult(false) + { + } + + virtual void setShapeIdentifiers(int partId0,int index0, int partId1,int index1) + { + (void)partId0; + (void)index0; + (void)partId1; + (void)index1; + //?? + } + + virtual void addContactPoint(const btVector3& normalOnBInWorld,const btVector3& pointInWorld,btScalar depth) + { + if (depth< m_distance) + { + m_hasResult = true; + m_normalOnBInWorld = normalOnBInWorld; + m_pointInWorld = pointInWorld; + //negative means penetration + m_distance = depth; + } + } +}; + +#endif //POINT_COLLECTOR_H + diff --git a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btRaycastCallback.cpp b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btRaycastCallback.cpp new file mode 100644 index 00000000000..31b91467777 --- /dev/null +++ b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btRaycastCallback.cpp @@ -0,0 +1,101 @@ +/* +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 "btRaycastCallback.h" + +btTriangleRaycastCallback::btTriangleRaycastCallback(const btVector3& from,const btVector3& to) + : + m_from(from), + m_to(to), + m_hitFraction(btScalar(1.)) +{ + +} + + + +void btTriangleRaycastCallback::processTriangle(btVector3* triangle,int partId, int triangleIndex) +{ + + + const btVector3 &vert0=triangle[0]; + const btVector3 &vert1=triangle[1]; + const btVector3 &vert2=triangle[2]; + + btVector3 v10; v10 = vert1 - vert0 ; + btVector3 v20; v20 = vert2 - vert0 ; + + btVector3 triangleNormal; triangleNormal = v10.cross( v20 ); + + const btScalar dist = vert0.dot(triangleNormal); + btScalar dist_a = triangleNormal.dot(m_from) ; + dist_a-= dist; + btScalar dist_b = triangleNormal.dot(m_to); + dist_b -= dist; + + if ( dist_a * dist_b >= btScalar(0.0) ) + { + return ; // same sign + } + + const btScalar proj_length=dist_a-dist_b; + const btScalar distance = (dist_a)/(proj_length); + // Now we have the intersection point on the plane, we'll see if it's inside the triangle + // Add an epsilon as a tolerance for the raycast, + // in case the ray hits exacly on the edge of the triangle. + // It must be scaled for the triangle size. + + if(distance < m_hitFraction) + { + + + btScalar edge_tolerance =triangleNormal.length2(); + edge_tolerance *= btScalar(-0.0001); + btVector3 point; point.setInterpolate3( m_from, m_to, distance); + { + btVector3 v0p; v0p = vert0 - point; + btVector3 v1p; v1p = vert1 - point; + btVector3 cp0; cp0 = v0p.cross( v1p ); + + if ( (btScalar)(cp0.dot(triangleNormal)) >=edge_tolerance) + { + + + btVector3 v2p; v2p = vert2 - point; + btVector3 cp1; + cp1 = v1p.cross( v2p); + if ( (btScalar)(cp1.dot(triangleNormal)) >=edge_tolerance) + { + btVector3 cp2; + cp2 = v2p.cross(v0p); + + if ( (btScalar)(cp2.dot(triangleNormal)) >=edge_tolerance) + { + + if ( dist_a > 0 ) + { + m_hitFraction = reportHit(triangleNormal,distance,partId,triangleIndex); + } + else + { + m_hitFraction = reportHit(-triangleNormal,distance,partId,triangleIndex); + } + } + } + } + } + } +} diff --git a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btRaycastCallback.h b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btRaycastCallback.h new file mode 100644 index 00000000000..a0bbc9f8fe9 --- /dev/null +++ b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btRaycastCallback.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 RAYCAST_TRI_CALLBACK_H +#define RAYCAST_TRI_CALLBACK_H + +#include "../CollisionShapes/btTriangleCallback.h" +struct btBroadphaseProxy; + + +class btTriangleRaycastCallback: public btTriangleCallback +{ +public: + + //input + btVector3 m_from; + btVector3 m_to; + + btScalar m_hitFraction; + + btTriangleRaycastCallback(const btVector3& from,const btVector3& to); + + virtual void processTriangle(btVector3* triangle, int partId, int triangleIndex); + + virtual btScalar reportHit(const btVector3& hitNormalLocal, btScalar hitFraction, int partId, int triangleIndex ) = 0; + +}; + +#endif //RAYCAST_TRI_CALLBACK_H + diff --git a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btSimplexSolverInterface.h b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btSimplexSolverInterface.h new file mode 100644 index 00000000000..58393b2eab9 --- /dev/null +++ b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btSimplexSolverInterface.h @@ -0,0 +1,64 @@ +/* +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 SIMPLEX_SOLVER_INTERFACE_H +#define SIMPLEX_SOLVER_INTERFACE_H + +#include "../../LinearMath/btVector3.h" +#include "../../LinearMath/btPoint3.h" + +#define NO_VIRTUAL_INTERFACE 1 +#ifdef NO_VIRTUAL_INTERFACE +#include "btVoronoiSimplexSolver.h" +#define btSimplexSolverInterface btVoronoiSimplexSolver +#else + +/// btSimplexSolverInterface can incrementally calculate distance between origin and up to 4 vertices +/// Used by GJK or Linear Casting. Can be implemented by the Johnson-algorithm or alternative approaches based on +/// voronoi regions or barycentric coordinates +class btSimplexSolverInterface +{ + public: + virtual ~btSimplexSolverInterface() {}; + + virtual void reset() = 0; + + virtual void addVertex(const btVector3& w, const btPoint3& p, const btPoint3& q) = 0; + + virtual bool closest(btVector3& v) = 0; + + virtual btScalar maxVertex() = 0; + + virtual bool fullSimplex() const = 0; + + virtual int getSimplex(btPoint3 *pBuf, btPoint3 *qBuf, btVector3 *yBuf) const = 0; + + virtual bool inSimplex(const btVector3& w) = 0; + + virtual void backup_closest(btVector3& v) = 0; + + virtual bool emptySimplex() const = 0; + + virtual void compute_points(btPoint3& p1, btPoint3& p2) = 0; + + virtual int numVertices() const =0; + + +}; +#endif +#endif //SIMPLEX_SOLVER_INTERFACE_H + diff --git a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btSubSimplexConvexCast.cpp b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btSubSimplexConvexCast.cpp new file mode 100644 index 00000000000..687738b7fa9 --- /dev/null +++ b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btSubSimplexConvexCast.cpp @@ -0,0 +1,139 @@ +/* +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 "btSubSimplexConvexCast.h" +#include "BulletCollision/CollisionShapes/btConvexShape.h" +#include "BulletCollision/CollisionShapes/btMinkowskiSumShape.h" +#include "BulletCollision/NarrowPhaseCollision/btSimplexSolverInterface.h" + + +btSubsimplexConvexCast::btSubsimplexConvexCast (const btConvexShape* convexA,const btConvexShape* convexB,btSimplexSolverInterface* simplexSolver) +:m_simplexSolver(simplexSolver), +m_convexA(convexA),m_convexB(convexB) +{ +} + +///Typically the conservative advancement reaches solution in a few iterations, clip it to 32 for degenerate cases. +///See discussion about this here http://continuousphysics.com/Bullet/phpBB2/viewtopic.php?t=565 +#ifdef BT_USE_DOUBLE_PRECISION +#define MAX_ITERATIONS 64 +#else +#define MAX_ITERATIONS 32 +#endif +bool btSubsimplexConvexCast::calcTimeOfImpact( + const btTransform& fromA, + const btTransform& toA, + const btTransform& fromB, + const btTransform& toB, + CastResult& result) +{ + + btMinkowskiSumShape combi(m_convexA,m_convexB); + btMinkowskiSumShape* convex = &combi; + + btTransform rayFromLocalA; + btTransform rayToLocalA; + + rayFromLocalA = fromA.inverse()* fromB; + rayToLocalA = toA.inverse()* toB; + + + m_simplexSolver->reset(); + + convex->setTransformB(btTransform(rayFromLocalA.getBasis())); + + //btScalar radius = btScalar(0.01); + + btScalar lambda = btScalar(0.); + //todo: need to verify this: + //because of minkowski difference, we need the inverse direction + + btVector3 s = -rayFromLocalA.getOrigin(); + btVector3 r = -(rayToLocalA.getOrigin()-rayFromLocalA.getOrigin()); + btVector3 x = s; + btVector3 v; + btVector3 arbitraryPoint = convex->localGetSupportingVertex(r); + + v = x - arbitraryPoint; + + int maxIter = MAX_ITERATIONS; + + btVector3 n; + n.setValue(btScalar(0.),btScalar(0.),btScalar(0.)); + bool hasResult = false; + btVector3 c; + + btScalar lastLambda = lambda; + + + btScalar dist2 = v.length2(); +#ifdef BT_USE_DOUBLE_PRECISION + btScalar epsilon = btScalar(0.0001); +#else + btScalar epsilon = btScalar(0.0001); +#endif //BT_USE_DOUBLE_PRECISION + btVector3 w,p; + btScalar VdotR; + + while ( (dist2 > epsilon) && maxIter--) + { + p = convex->localGetSupportingVertex( v); + w = x - p; + + btScalar VdotW = v.dot(w); + + if ( VdotW > btScalar(0.)) + { + VdotR = v.dot(r); + + if (VdotR >= -(SIMD_EPSILON*SIMD_EPSILON)) + return false; + else + { + lambda = lambda - VdotW / VdotR; + x = s + lambda * r; + m_simplexSolver->reset(); + //check next line + w = x-p; + lastLambda = lambda; + n = v; + hasResult = true; + } + } + m_simplexSolver->addVertex( w, x , p); + if (m_simplexSolver->closest(v)) + { + dist2 = v.length2(); + hasResult = true; + //printf("V=%f , %f, %f\n",v[0],v[1],v[2]); + //printf("DIST2=%f\n",dist2); + //printf("numverts = %i\n",m_simplexSolver->numVertices()); + } else + { + dist2 = btScalar(0.); + } + } + + //int numiter = MAX_ITERATIONS - maxIter; +// printf("number of iterations: %d", numiter); + result.m_fraction = lambda; + result.m_normal = n; + + return true; +} + + + diff --git a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btSubSimplexConvexCast.h b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btSubSimplexConvexCast.h new file mode 100644 index 00000000000..05662db5d23 --- /dev/null +++ b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btSubSimplexConvexCast.h @@ -0,0 +1,50 @@ +/* +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 SUBSIMPLEX_CONVEX_CAST_H +#define SUBSIMPLEX_CONVEX_CAST_H + +#include "btConvexCast.h" +#include "btSimplexSolverInterface.h" +class btConvexShape; + +/// btSubsimplexConvexCast implements Gino van den Bergens' paper +///"Ray Casting against bteral Convex Objects with Application to Continuous Collision Detection" +/// GJK based Ray Cast, optimized version +/// Objects should not start in overlap, otherwise results are not defined. +class btSubsimplexConvexCast : public btConvexCast +{ + btSimplexSolverInterface* m_simplexSolver; + const btConvexShape* m_convexA; + const btConvexShape* m_convexB; + +public: + + btSubsimplexConvexCast (const btConvexShape* shapeA,const btConvexShape* shapeB,btSimplexSolverInterface* simplexSolver); + + //virtual ~btSubsimplexConvexCast(); + ///SimsimplexConvexCast calculateTimeOfImpact calculates the time of impact+normal for the linear cast (sweep) between two moving objects. + ///Precondition is that objects should not penetration/overlap at the start from the interval. Overlap can be tested using btGjkPairDetector. + virtual bool calcTimeOfImpact( + const btTransform& fromA, + const btTransform& toA, + const btTransform& fromB, + const btTransform& toB, + CastResult& result); + +}; + +#endif //SUBSIMPLEX_CONVEX_CAST_H diff --git a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.cpp b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.cpp new file mode 100644 index 00000000000..105b7eccefa --- /dev/null +++ b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.cpp @@ -0,0 +1,607 @@ + +/* +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. + + Elsevier CDROM license agreements grants nonexclusive license to use the software + for any purpose, commercial or non-commercial as long as the following credit is included + identifying the original source of the software: + + Parts of the source are "from the book Real-Time Collision Detection by + Christer Ericson, published by Morgan Kaufmann Publishers, + (c) 2005 Elsevier Inc." + +*/ + + +#include "btVoronoiSimplexSolver.h" +#include +#include + +#define VERTA 0 +#define VERTB 1 +#define VERTC 2 +#define VERTD 3 + +#define CATCH_DEGENERATE_TETRAHEDRON 1 +void btVoronoiSimplexSolver::removeVertex(int index) +{ + + assert(m_numVertices>0); + m_numVertices--; + m_simplexVectorW[index] = m_simplexVectorW[m_numVertices]; + m_simplexPointsP[index] = m_simplexPointsP[m_numVertices]; + m_simplexPointsQ[index] = m_simplexPointsQ[m_numVertices]; +} + +void btVoronoiSimplexSolver::reduceVertices (const btUsageBitfield& usedVerts) +{ + if ((numVertices() >= 4) && (!usedVerts.usedVertexD)) + removeVertex(3); + + if ((numVertices() >= 3) && (!usedVerts.usedVertexC)) + removeVertex(2); + + if ((numVertices() >= 2) && (!usedVerts.usedVertexB)) + removeVertex(1); + + if ((numVertices() >= 1) && (!usedVerts.usedVertexA)) + removeVertex(0); + +} + + + + + +//clear the simplex, remove all the vertices +void btVoronoiSimplexSolver::reset() +{ + m_cachedValidClosest = false; + m_numVertices = 0; + m_needsUpdate = true; + m_lastW = btVector3(btScalar(1e30),btScalar(1e30),btScalar(1e30)); + m_cachedBC.reset(); +} + + + + //add a vertex +void btVoronoiSimplexSolver::addVertex(const btVector3& w, const btPoint3& p, const btPoint3& q) +{ + m_lastW = w; + m_needsUpdate = true; + + m_simplexVectorW[m_numVertices] = w; + m_simplexPointsP[m_numVertices] = p; + m_simplexPointsQ[m_numVertices] = q; + + m_numVertices++; +} + +bool btVoronoiSimplexSolver::updateClosestVectorAndPoints() +{ + + if (m_needsUpdate) + { + m_cachedBC.reset(); + + m_needsUpdate = false; + + switch (numVertices()) + { + case 0: + m_cachedValidClosest = false; + break; + case 1: + { + m_cachedP1 = m_simplexPointsP[0]; + m_cachedP2 = m_simplexPointsQ[0]; + m_cachedV = m_cachedP1-m_cachedP2; //== m_simplexVectorW[0] + m_cachedBC.reset(); + m_cachedBC.setBarycentricCoordinates(btScalar(1.),btScalar(0.),btScalar(0.),btScalar(0.)); + m_cachedValidClosest = m_cachedBC.isValid(); + break; + }; + case 2: + { + //closest point origin from line segment + const btVector3& from = m_simplexVectorW[0]; + const btVector3& to = m_simplexVectorW[1]; + btVector3 nearest; + + btVector3 p (btScalar(0.),btScalar(0.),btScalar(0.)); + btVector3 diff = p - from; + btVector3 v = to - from; + btScalar t = v.dot(diff); + + if (t > 0) { + btScalar dotVV = v.dot(v); + if (t < dotVV) { + t /= dotVV; + diff -= t*v; + m_cachedBC.m_usedVertices.usedVertexA = true; + m_cachedBC.m_usedVertices.usedVertexB = true; + } else { + t = 1; + diff -= v; + //reduce to 1 point + m_cachedBC.m_usedVertices.usedVertexB = true; + } + } else + { + t = 0; + //reduce to 1 point + m_cachedBC.m_usedVertices.usedVertexA = true; + } + m_cachedBC.setBarycentricCoordinates(1-t,t); + nearest = from + t*v; + + m_cachedP1 = m_simplexPointsP[0] + t * (m_simplexPointsP[1] - m_simplexPointsP[0]); + m_cachedP2 = m_simplexPointsQ[0] + t * (m_simplexPointsQ[1] - m_simplexPointsQ[0]); + m_cachedV = m_cachedP1 - m_cachedP2; + + reduceVertices(m_cachedBC.m_usedVertices); + + m_cachedValidClosest = m_cachedBC.isValid(); + break; + } + case 3: + { + //closest point origin from triangle + btVector3 p (btScalar(0.),btScalar(0.),btScalar(0.)); + + const btVector3& a = m_simplexVectorW[0]; + const btVector3& b = m_simplexVectorW[1]; + const btVector3& c = m_simplexVectorW[2]; + + closestPtPointTriangle(p,a,b,c,m_cachedBC); + m_cachedP1 = m_simplexPointsP[0] * m_cachedBC.m_barycentricCoords[0] + + m_simplexPointsP[1] * m_cachedBC.m_barycentricCoords[1] + + m_simplexPointsP[2] * m_cachedBC.m_barycentricCoords[2]; + + m_cachedP2 = m_simplexPointsQ[0] * m_cachedBC.m_barycentricCoords[0] + + m_simplexPointsQ[1] * m_cachedBC.m_barycentricCoords[1] + + m_simplexPointsQ[2] * m_cachedBC.m_barycentricCoords[2]; + + m_cachedV = m_cachedP1-m_cachedP2; + + reduceVertices (m_cachedBC.m_usedVertices); + m_cachedValidClosest = m_cachedBC.isValid(); + + break; + } + case 4: + { + + + btVector3 p (btScalar(0.),btScalar(0.),btScalar(0.)); + + const btVector3& a = m_simplexVectorW[0]; + const btVector3& b = m_simplexVectorW[1]; + const btVector3& c = m_simplexVectorW[2]; + const btVector3& d = m_simplexVectorW[3]; + + bool hasSeperation = closestPtPointTetrahedron(p,a,b,c,d,m_cachedBC); + + if (hasSeperation) + { + + m_cachedP1 = m_simplexPointsP[0] * m_cachedBC.m_barycentricCoords[0] + + m_simplexPointsP[1] * m_cachedBC.m_barycentricCoords[1] + + m_simplexPointsP[2] * m_cachedBC.m_barycentricCoords[2] + + m_simplexPointsP[3] * m_cachedBC.m_barycentricCoords[3]; + + m_cachedP2 = m_simplexPointsQ[0] * m_cachedBC.m_barycentricCoords[0] + + m_simplexPointsQ[1] * m_cachedBC.m_barycentricCoords[1] + + m_simplexPointsQ[2] * m_cachedBC.m_barycentricCoords[2] + + m_simplexPointsQ[3] * m_cachedBC.m_barycentricCoords[3]; + + m_cachedV = m_cachedP1-m_cachedP2; + reduceVertices (m_cachedBC.m_usedVertices); + } else + { +// printf("sub distance got penetration\n"); + + if (m_cachedBC.m_degenerate) + { + m_cachedValidClosest = false; + } else + { + m_cachedValidClosest = true; + //degenerate case == false, penetration = true + zero + m_cachedV.setValue(btScalar(0.),btScalar(0.),btScalar(0.)); + } + break; + } + + m_cachedValidClosest = m_cachedBC.isValid(); + + //closest point origin from tetrahedron + break; + } + default: + { + m_cachedValidClosest = false; + } + }; + } + + return m_cachedValidClosest; + +} + +//return/calculate the closest vertex +bool btVoronoiSimplexSolver::closest(btVector3& v) +{ + bool succes = updateClosestVectorAndPoints(); + v = m_cachedV; + return succes; +} + + + +btScalar btVoronoiSimplexSolver::maxVertex() +{ + int i, numverts = numVertices(); + btScalar maxV = btScalar(0.); + for (i=0;i= btScalar(0.0) && d4 <= d3) + { + result.m_closestPointOnSimplex = b; + result.m_usedVertices.usedVertexB = true; + result.setBarycentricCoordinates(0,1,0); + + return true; // b; // barycentric coordinates (0,1,0) + } + // Check if P in edge region of AB, if so return projection of P onto AB + btScalar vc = d1*d4 - d3*d2; + if (vc <= btScalar(0.0) && d1 >= btScalar(0.0) && d3 <= btScalar(0.0)) { + btScalar v = d1 / (d1 - d3); + result.m_closestPointOnSimplex = a + v * ab; + result.m_usedVertices.usedVertexA = true; + result.m_usedVertices.usedVertexB = true; + result.setBarycentricCoordinates(1-v,v,0); + return true; + //return a + v * ab; // barycentric coordinates (1-v,v,0) + } + + // Check if P in vertex region outside C + btVector3 cp = p - c; + btScalar d5 = ab.dot(cp); + btScalar d6 = ac.dot(cp); + if (d6 >= btScalar(0.0) && d5 <= d6) + { + result.m_closestPointOnSimplex = c; + result.m_usedVertices.usedVertexC = true; + result.setBarycentricCoordinates(0,0,1); + return true;//c; // barycentric coordinates (0,0,1) + } + + // Check if P in edge region of AC, if so return projection of P onto AC + btScalar vb = d5*d2 - d1*d6; + if (vb <= btScalar(0.0) && d2 >= btScalar(0.0) && d6 <= btScalar(0.0)) { + btScalar w = d2 / (d2 - d6); + result.m_closestPointOnSimplex = a + w * ac; + result.m_usedVertices.usedVertexA = true; + result.m_usedVertices.usedVertexC = true; + result.setBarycentricCoordinates(1-w,0,w); + return true; + //return a + w * ac; // barycentric coordinates (1-w,0,w) + } + + // Check if P in edge region of BC, if so return projection of P onto BC + btScalar va = d3*d6 - d5*d4; + if (va <= btScalar(0.0) && (d4 - d3) >= btScalar(0.0) && (d5 - d6) >= btScalar(0.0)) { + btScalar w = (d4 - d3) / ((d4 - d3) + (d5 - d6)); + + result.m_closestPointOnSimplex = b + w * (c - b); + result.m_usedVertices.usedVertexB = true; + result.m_usedVertices.usedVertexC = true; + result.setBarycentricCoordinates(0,1-w,w); + return true; + // return b + w * (c - b); // barycentric coordinates (0,1-w,w) + } + + // P inside face region. Compute Q through its barycentric coordinates (u,v,w) + btScalar denom = btScalar(1.0) / (va + vb + vc); + btScalar v = vb * denom; + btScalar w = vc * denom; + + result.m_closestPointOnSimplex = a + ab * v + ac * w; + result.m_usedVertices.usedVertexA = true; + result.m_usedVertices.usedVertexB = true; + result.m_usedVertices.usedVertexC = true; + result.setBarycentricCoordinates(1-v-w,v,w); + + return true; +// return a + ab * v + ac * w; // = u*a + v*b + w*c, u = va * denom = btScalar(1.0) - v - w + +} + + + + + +/// Test if point p and d lie on opposite sides of plane through abc +int btVoronoiSimplexSolver::pointOutsideOfPlane(const btPoint3& p, const btPoint3& a, const btPoint3& b, const btPoint3& c, const btPoint3& d) +{ + btVector3 normal = (b-a).cross(c-a); + + btScalar signp = (p - a).dot(normal); // [AP AB AC] + btScalar signd = (d - a).dot( normal); // [AD AB AC] + +#ifdef CATCH_DEGENERATE_TETRAHEDRON +#ifdef BT_USE_DOUBLE_PRECISION +if (signd * signd < (btScalar(1e-8) * btScalar(1e-8))) + { + return -1; + } +#else + if (signd * signd < (btScalar(1e-4) * btScalar(1e-4))) + { +// printf("affine dependent/degenerate\n");// + return -1; + } +#endif + +#endif + // Points on opposite sides if expression signs are opposite + return signp * signd < btScalar(0.); +} + + +bool btVoronoiSimplexSolver::closestPtPointTetrahedron(const btPoint3& p, const btPoint3& a, const btPoint3& b, const btPoint3& c, const btPoint3& d, btSubSimplexClosestResult& finalResult) +{ + btSubSimplexClosestResult tempResult; + + // Start out assuming point inside all halfspaces, so closest to itself + finalResult.m_closestPointOnSimplex = p; + finalResult.m_usedVertices.reset(); + finalResult.m_usedVertices.usedVertexA = true; + finalResult.m_usedVertices.usedVertexB = true; + finalResult.m_usedVertices.usedVertexC = true; + finalResult.m_usedVertices.usedVertexD = true; + + int pointOutsideABC = pointOutsideOfPlane(p, a, b, c, d); + int pointOutsideACD = pointOutsideOfPlane(p, a, c, d, b); + int pointOutsideADB = pointOutsideOfPlane(p, a, d, b, c); + int pointOutsideBDC = pointOutsideOfPlane(p, b, d, c, a); + + if (pointOutsideABC < 0 || pointOutsideACD < 0 || pointOutsideADB < 0 || pointOutsideBDC < 0) + { + finalResult.m_degenerate = true; + return false; + } + + if (!pointOutsideABC && !pointOutsideACD && !pointOutsideADB && !pointOutsideBDC) + { + return false; + } + + + btScalar bestSqDist = FLT_MAX; + // If point outside face abc then compute closest point on abc + if (pointOutsideABC) + { + closestPtPointTriangle(p, a, b, c,tempResult); + btPoint3 q = tempResult.m_closestPointOnSimplex; + + btScalar sqDist = (q - p).dot( q - p); + // Update best closest point if (squared) distance is less than current best + if (sqDist < bestSqDist) { + bestSqDist = sqDist; + finalResult.m_closestPointOnSimplex = q; + //convert result bitmask! + finalResult.m_usedVertices.reset(); + finalResult.m_usedVertices.usedVertexA = tempResult.m_usedVertices.usedVertexA; + finalResult.m_usedVertices.usedVertexB = tempResult.m_usedVertices.usedVertexB; + finalResult.m_usedVertices.usedVertexC = tempResult.m_usedVertices.usedVertexC; + finalResult.setBarycentricCoordinates( + tempResult.m_barycentricCoords[VERTA], + tempResult.m_barycentricCoords[VERTB], + tempResult.m_barycentricCoords[VERTC], + 0 + ); + + } + } + + + // Repeat test for face acd + if (pointOutsideACD) + { + closestPtPointTriangle(p, a, c, d,tempResult); + btPoint3 q = tempResult.m_closestPointOnSimplex; + //convert result bitmask! + + btScalar sqDist = (q - p).dot( q - p); + if (sqDist < bestSqDist) + { + bestSqDist = sqDist; + finalResult.m_closestPointOnSimplex = q; + finalResult.m_usedVertices.reset(); + finalResult.m_usedVertices.usedVertexA = tempResult.m_usedVertices.usedVertexA; + + finalResult.m_usedVertices.usedVertexC = tempResult.m_usedVertices.usedVertexB; + finalResult.m_usedVertices.usedVertexD = tempResult.m_usedVertices.usedVertexC; + finalResult.setBarycentricCoordinates( + tempResult.m_barycentricCoords[VERTA], + 0, + tempResult.m_barycentricCoords[VERTB], + tempResult.m_barycentricCoords[VERTC] + ); + + } + } + // Repeat test for face adb + + + if (pointOutsideADB) + { + closestPtPointTriangle(p, a, d, b,tempResult); + btPoint3 q = tempResult.m_closestPointOnSimplex; + //convert result bitmask! + + btScalar sqDist = (q - p).dot( q - p); + if (sqDist < bestSqDist) + { + bestSqDist = sqDist; + finalResult.m_closestPointOnSimplex = q; + finalResult.m_usedVertices.reset(); + finalResult.m_usedVertices.usedVertexA = tempResult.m_usedVertices.usedVertexA; + finalResult.m_usedVertices.usedVertexB = tempResult.m_usedVertices.usedVertexC; + + finalResult.m_usedVertices.usedVertexD = tempResult.m_usedVertices.usedVertexB; + finalResult.setBarycentricCoordinates( + tempResult.m_barycentricCoords[VERTA], + tempResult.m_barycentricCoords[VERTC], + 0, + tempResult.m_barycentricCoords[VERTB] + ); + + } + } + // Repeat test for face bdc + + + if (pointOutsideBDC) + { + closestPtPointTriangle(p, b, d, c,tempResult); + btPoint3 q = tempResult.m_closestPointOnSimplex; + //convert result bitmask! + btScalar sqDist = (q - p).dot( q - p); + if (sqDist < bestSqDist) + { + bestSqDist = sqDist; + finalResult.m_closestPointOnSimplex = q; + finalResult.m_usedVertices.reset(); + // + finalResult.m_usedVertices.usedVertexB = tempResult.m_usedVertices.usedVertexA; + finalResult.m_usedVertices.usedVertexC = tempResult.m_usedVertices.usedVertexC; + finalResult.m_usedVertices.usedVertexD = tempResult.m_usedVertices.usedVertexB; + + finalResult.setBarycentricCoordinates( + 0, + tempResult.m_barycentricCoords[VERTA], + tempResult.m_barycentricCoords[VERTC], + tempResult.m_barycentricCoords[VERTB] + ); + + } + } + + //help! we ended up full ! + + if (finalResult.m_usedVertices.usedVertexA && + finalResult.m_usedVertices.usedVertexB && + finalResult.m_usedVertices.usedVertexC && + finalResult.m_usedVertices.usedVertexD) + { + return true; + } + + return true; +} + diff --git a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.h b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.h new file mode 100644 index 00000000000..356d335bc93 --- /dev/null +++ b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.h @@ -0,0 +1,157 @@ +/* +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 btVoronoiSimplexSolver_H +#define btVoronoiSimplexSolver_H + +#include "btSimplexSolverInterface.h" + + + +#define VORONOI_SIMPLEX_MAX_VERTS 5 + +struct btUsageBitfield{ + btUsageBitfield() + { + reset(); + } + + void reset() + { + usedVertexA = false; + usedVertexB = false; + usedVertexC = false; + usedVertexD = false; + } + unsigned short usedVertexA : 1; + unsigned short usedVertexB : 1; + unsigned short usedVertexC : 1; + unsigned short usedVertexD : 1; + unsigned short unused1 : 1; + unsigned short unused2 : 1; + unsigned short unused3 : 1; + unsigned short unused4 : 1; +}; + + +struct btSubSimplexClosestResult +{ + btPoint3 m_closestPointOnSimplex; + //MASK for m_usedVertices + //stores the simplex vertex-usage, using the MASK, + // if m_usedVertices & MASK then the related vertex is used + btUsageBitfield m_usedVertices; + btScalar m_barycentricCoords[4]; + bool m_degenerate; + + void reset() + { + m_degenerate = false; + setBarycentricCoordinates(); + m_usedVertices.reset(); + } + bool isValid() + { + bool valid = (m_barycentricCoords[0] >= btScalar(0.)) && + (m_barycentricCoords[1] >= btScalar(0.)) && + (m_barycentricCoords[2] >= btScalar(0.)) && + (m_barycentricCoords[3] >= btScalar(0.)); + + + return valid; + } + void setBarycentricCoordinates(btScalar a=btScalar(0.),btScalar b=btScalar(0.),btScalar c=btScalar(0.),btScalar d=btScalar(0.)) + { + m_barycentricCoords[0] = a; + m_barycentricCoords[1] = b; + m_barycentricCoords[2] = c; + m_barycentricCoords[3] = d; + } + +}; + +/// btVoronoiSimplexSolver is an implementation of the closest point distance algorithm from a 1-4 points simplex to the origin. +/// Can be used with GJK, as an alternative to Johnson distance algorithm. +#ifdef NO_VIRTUAL_INTERFACE +class btVoronoiSimplexSolver +#else +class btVoronoiSimplexSolver : public btSimplexSolverInterface +#endif +{ +public: + + int m_numVertices; + + btVector3 m_simplexVectorW[VORONOI_SIMPLEX_MAX_VERTS]; + btPoint3 m_simplexPointsP[VORONOI_SIMPLEX_MAX_VERTS]; + btPoint3 m_simplexPointsQ[VORONOI_SIMPLEX_MAX_VERTS]; + + + + btPoint3 m_cachedP1; + btPoint3 m_cachedP2; + btVector3 m_cachedV; + btVector3 m_lastW; + bool m_cachedValidClosest; + + btSubSimplexClosestResult m_cachedBC; + + bool m_needsUpdate; + + void removeVertex(int index); + void reduceVertices (const btUsageBitfield& usedVerts); + bool updateClosestVectorAndPoints(); + + bool closestPtPointTetrahedron(const btPoint3& p, const btPoint3& a, const btPoint3& b, const btPoint3& c, const btPoint3& d, btSubSimplexClosestResult& finalResult); + int pointOutsideOfPlane(const btPoint3& p, const btPoint3& a, const btPoint3& b, const btPoint3& c, const btPoint3& d); + bool closestPtPointTriangle(const btPoint3& p, const btPoint3& a, const btPoint3& b, const btPoint3& c,btSubSimplexClosestResult& result); + +public: + + void reset(); + + void addVertex(const btVector3& w, const btPoint3& p, const btPoint3& q); + + + bool closest(btVector3& v); + + btScalar maxVertex(); + + bool fullSimplex() const + { + return (m_numVertices == 4); + } + + int getSimplex(btPoint3 *pBuf, btPoint3 *qBuf, btVector3 *yBuf) const; + + bool inSimplex(const btVector3& w); + + void backup_closest(btVector3& v) ; + + bool emptySimplex() const ; + + void compute_points(btPoint3& p1, btPoint3& p2) ; + + int numVertices() const + { + return m_numVertices; + } + + +}; + +#endif //VoronoiSimplexSolver diff --git a/extern/bullet2/src/BulletDynamics/CMakeLists.txt b/extern/bullet2/src/BulletDynamics/CMakeLists.txt new file mode 100644 index 00000000000..8598575799a --- /dev/null +++ b/extern/bullet2/src/BulletDynamics/CMakeLists.txt @@ -0,0 +1,20 @@ +INCLUDE_DIRECTORIES( +${BULLET_PHYSICS_SOURCE_DIR}/src } +) + +ADD_LIBRARY(LibBulletDynamics + + ConstraintSolver/btContactConstraint.cpp + ConstraintSolver/btGeneric6DofConstraint.cpp + ConstraintSolver/btHingeConstraint.cpp + ConstraintSolver/btPoint2PointConstraint.cpp + ConstraintSolver/btSequentialImpulseConstraintSolver.cpp + ConstraintSolver/btSolve2LinearConstraint.cpp + ConstraintSolver/btTypedConstraint.cpp + Dynamics/btDiscreteDynamicsWorld.cpp + Dynamics/btSimpleDynamicsWorld.cpp + Dynamics/Bullet-C-API.cpp + Dynamics/btRigidBody.cpp + Vehicle/btRaycastVehicle.cpp + Vehicle/btWheelInfo.cpp +) diff --git a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btConeTwistConstraint.cpp b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btConeTwistConstraint.cpp new file mode 100644 index 00000000000..2289621e8e3 --- /dev/null +++ b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btConeTwistConstraint.cpp @@ -0,0 +1,285 @@ +/* +Bullet Continuous Collision Detection and Physics Library +btConeTwistConstraint is Copyright (c) 2007 Starbreeze Studios + +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. + +Written by: Marcus Hennix +*/ + + +#include "btConeTwistConstraint.h" +#include "BulletDynamics/Dynamics/btRigidBody.h" +#include "LinearMath/btTransformUtil.h" +#include "LinearMath/btSimdMinMax.h" +#include + +btConeTwistConstraint::btConeTwistConstraint() +{ +} + + +btConeTwistConstraint::btConeTwistConstraint(btRigidBody& rbA,btRigidBody& rbB, + const btTransform& rbAFrame,const btTransform& rbBFrame) + :btTypedConstraint(rbA,rbB),m_rbAFrame(rbAFrame),m_rbBFrame(rbBFrame), + m_angularOnly(false) +{ + // flip axis for correct angles + m_rbBFrame.getBasis()[1][0] *= btScalar(-1.); + m_rbBFrame.getBasis()[1][1] *= btScalar(-1.); + m_rbBFrame.getBasis()[1][2] *= btScalar(-1.); + + m_swingSpan1 = btScalar(1e30); + m_swingSpan2 = btScalar(1e30); + m_twistSpan = btScalar(1e30); + m_biasFactor = 0.3f; + m_relaxationFactor = 1.0f; + + m_solveTwistLimit = false; + m_solveSwingLimit = false; + +} + +btConeTwistConstraint::btConeTwistConstraint(btRigidBody& rbA,const btTransform& rbAFrame) + :btTypedConstraint(rbA),m_rbAFrame(rbAFrame), + m_angularOnly(false) +{ + m_rbBFrame = m_rbAFrame; + + // flip axis for correct angles + m_rbBFrame.getBasis()[1][0] *= btScalar(-1.); + m_rbBFrame.getBasis()[1][1] *= btScalar(-1.); + m_rbBFrame.getBasis()[1][2] *= btScalar(-1.); + + m_rbBFrame.getBasis()[2][0] *= btScalar(-1.); + m_rbBFrame.getBasis()[2][1] *= btScalar(-1.); + m_rbBFrame.getBasis()[2][2] *= btScalar(-1.); + + m_swingSpan1 = btScalar(1e30); + m_swingSpan2 = btScalar(1e30); + m_twistSpan = btScalar(1e30); + m_biasFactor = 0.3f; + m_relaxationFactor = 1.0f; + + m_solveTwistLimit = false; + m_solveSwingLimit = false; + +} + +void btConeTwistConstraint::buildJacobian() +{ + m_appliedImpulse = btScalar(0.); + + //set bias, sign, clear accumulator + m_swingCorrection = btScalar(0.); + m_twistLimitSign = btScalar(0.); + m_solveTwistLimit = false; + m_solveSwingLimit = false; + m_accTwistLimitImpulse = btScalar(0.); + m_accSwingLimitImpulse = btScalar(0.); + + if (!m_angularOnly) + { + btVector3 pivotAInW = m_rbA.getCenterOfMassTransform()*m_rbAFrame.getOrigin(); + btVector3 pivotBInW = m_rbB.getCenterOfMassTransform()*m_rbBFrame.getOrigin(); + btVector3 relPos = pivotBInW - pivotAInW; + + btVector3 normal[3]; + if (relPos.length2() > SIMD_EPSILON) + { + normal[0] = relPos.normalized(); + } + else + { + normal[0].setValue(btScalar(1.0),0,0); + } + + btPlaneSpace1(normal[0], normal[1], normal[2]); + + for (int i=0;i<3;i++) + { + new (&m_jac[i]) btJacobianEntry( + m_rbA.getCenterOfMassTransform().getBasis().transpose(), + m_rbB.getCenterOfMassTransform().getBasis().transpose(), + pivotAInW - m_rbA.getCenterOfMassPosition(), + pivotBInW - m_rbB.getCenterOfMassPosition(), + normal[i], + m_rbA.getInvInertiaDiagLocal(), + m_rbA.getInvMass(), + m_rbB.getInvInertiaDiagLocal(), + m_rbB.getInvMass()); + } + } + + btVector3 b1Axis1,b1Axis2,b1Axis3; + btVector3 b2Axis1,b2Axis2; + + b1Axis1 = getRigidBodyA().getCenterOfMassTransform().getBasis() * this->m_rbAFrame.getBasis().getColumn(0); + b2Axis1 = getRigidBodyB().getCenterOfMassTransform().getBasis() * this->m_rbBFrame.getBasis().getColumn(0); + + btScalar swing1=btScalar(0.),swing2 = btScalar(0.); + + // Get Frame into world space + if (m_swingSpan1 >= btScalar(0.05f)) + { + b1Axis2 = getRigidBodyA().getCenterOfMassTransform().getBasis() * this->m_rbAFrame.getBasis().getColumn(1); + swing1 = btAtan2Fast( b2Axis1.dot(b1Axis2),b2Axis1.dot(b1Axis1) ); + } + + if (m_swingSpan2 >= btScalar(0.05f)) + { + b1Axis3 = getRigidBodyA().getCenterOfMassTransform().getBasis() * this->m_rbAFrame.getBasis().getColumn(2); + swing2 = btAtan2Fast( b2Axis1.dot(b1Axis3),b2Axis1.dot(b1Axis1) ); + } + + btScalar RMaxAngle1Sq = 1.0f / (m_swingSpan1*m_swingSpan1); + btScalar RMaxAngle2Sq = 1.0f / (m_swingSpan2*m_swingSpan2); + btScalar EllipseAngle = btFabs(swing1)* RMaxAngle1Sq + btFabs(swing2) * RMaxAngle2Sq; + + if (EllipseAngle > 1.0f) + { + m_swingCorrection = EllipseAngle-1.0f; + m_solveSwingLimit = true; + + // Calculate necessary axis & factors + m_swingAxis = b2Axis1.cross(b1Axis2* b2Axis1.dot(b1Axis2) + b1Axis3* b2Axis1.dot(b1Axis3)); + m_swingAxis.normalize(); + + btScalar swingAxisSign = (b2Axis1.dot(b1Axis1) >= 0.0f) ? 1.0f : -1.0f; + m_swingAxis *= swingAxisSign; + + m_kSwing = btScalar(1.) / (getRigidBodyA().computeAngularImpulseDenominator(m_swingAxis) + + getRigidBodyB().computeAngularImpulseDenominator(m_swingAxis)); + + } + + // Twist limits + if (m_twistSpan >= btScalar(0.)) + { + btVector3 b2Axis2 = getRigidBodyB().getCenterOfMassTransform().getBasis() * this->m_rbBFrame.getBasis().getColumn(1); + btQuaternion rotationArc = shortestArcQuat(b2Axis1,b1Axis1); + btVector3 TwistRef = quatRotate(rotationArc,b2Axis2); + btScalar twist = btAtan2Fast( TwistRef.dot(b1Axis3), TwistRef.dot(b1Axis2) ); + + btScalar lockedFreeFactor = (m_twistSpan > btScalar(0.05f)) ? m_limitSoftness : btScalar(0.); + if (twist <= -m_twistSpan*lockedFreeFactor) + { + m_twistCorrection = -(twist + m_twistSpan); + m_solveTwistLimit = true; + + m_twistAxis = (b2Axis1 + b1Axis1) * 0.5f; + m_twistAxis.normalize(); + m_twistAxis *= -1.0f; + + m_kTwist = btScalar(1.) / (getRigidBodyA().computeAngularImpulseDenominator(m_twistAxis) + + getRigidBodyB().computeAngularImpulseDenominator(m_twistAxis)); + + } else + if (twist > m_twistSpan*lockedFreeFactor) + { + m_twistCorrection = (twist - m_twistSpan); + m_solveTwistLimit = true; + + m_twistAxis = (b2Axis1 + b1Axis1) * 0.5f; + m_twistAxis.normalize(); + + m_kTwist = btScalar(1.) / (getRigidBodyA().computeAngularImpulseDenominator(m_twistAxis) + + getRigidBodyB().computeAngularImpulseDenominator(m_twistAxis)); + + } + } +} + +void btConeTwistConstraint::solveConstraint(btScalar timeStep) +{ + + btVector3 pivotAInW = m_rbA.getCenterOfMassTransform()*m_rbAFrame.getOrigin(); + btVector3 pivotBInW = m_rbB.getCenterOfMassTransform()*m_rbBFrame.getOrigin(); + + btScalar tau = btScalar(0.3); + + //linear part + if (!m_angularOnly) + { + btVector3 rel_pos1 = pivotAInW - m_rbA.getCenterOfMassPosition(); + btVector3 rel_pos2 = pivotBInW - m_rbB.getCenterOfMassPosition(); + + btVector3 vel1 = m_rbA.getVelocityInLocalPoint(rel_pos1); + btVector3 vel2 = m_rbB.getVelocityInLocalPoint(rel_pos2); + btVector3 vel = vel1 - vel2; + + for (int i=0;i<3;i++) + { + const btVector3& normal = m_jac[i].m_linearJointAxis; + btScalar jacDiagABInv = btScalar(1.) / m_jac[i].getDiagonal(); + + btScalar rel_vel; + rel_vel = normal.dot(vel); + //positional error (zeroth order error) + btScalar depth = -(pivotAInW - pivotBInW).dot(normal); //this is the error projected on the normal + btScalar impulse = depth*tau/timeStep * jacDiagABInv - rel_vel * jacDiagABInv; + m_appliedImpulse += impulse; + btVector3 impulse_vector = normal * impulse; + m_rbA.applyImpulse(impulse_vector, pivotAInW - m_rbA.getCenterOfMassPosition()); + m_rbB.applyImpulse(-impulse_vector, pivotBInW - m_rbB.getCenterOfMassPosition()); + } + } + + { + ///solve angular part + const btVector3& angVelA = getRigidBodyA().getAngularVelocity(); + const btVector3& angVelB = getRigidBodyB().getAngularVelocity(); + + // solve swing limit + if (m_solveSwingLimit) + { + btScalar amplitude = ((angVelB - angVelA).dot( m_swingAxis )*m_relaxationFactor*m_relaxationFactor + m_swingCorrection*(btScalar(1.)/timeStep)*m_biasFactor); + btScalar impulseMag = amplitude * m_kSwing; + + // Clamp the accumulated impulse + btScalar temp = m_accSwingLimitImpulse; + m_accSwingLimitImpulse = btMax(m_accSwingLimitImpulse + impulseMag, 0.0f ); + impulseMag = m_accSwingLimitImpulse - temp; + + btVector3 impulse = m_swingAxis * impulseMag; + + m_rbA.applyTorqueImpulse(impulse); + m_rbB.applyTorqueImpulse(-impulse); + + } + + // solve twist limit + if (m_solveTwistLimit) + { + btScalar amplitude = ((angVelB - angVelA).dot( m_twistAxis )*m_relaxationFactor*m_relaxationFactor + m_twistCorrection*(btScalar(1.)/timeStep)*m_biasFactor ); + btScalar impulseMag = amplitude * m_kTwist; + + // Clamp the accumulated impulse + btScalar temp = m_accTwistLimitImpulse; + m_accTwistLimitImpulse = btMax(m_accTwistLimitImpulse + impulseMag, 0.0f ); + impulseMag = m_accTwistLimitImpulse - temp; + + btVector3 impulse = m_twistAxis * impulseMag; + + m_rbA.applyTorqueImpulse(impulse); + m_rbB.applyTorqueImpulse(-impulse); + + } + + } + +} + +void btConeTwistConstraint::updateRHS(btScalar timeStep) +{ + (void)timeStep; + +} diff --git a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btConeTwistConstraint.h b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btConeTwistConstraint.h new file mode 100644 index 00000000000..874669c80b3 --- /dev/null +++ b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btConeTwistConstraint.h @@ -0,0 +1,123 @@ +/* +Bullet Continuous Collision Detection and Physics Library +btConeTwistConstraint is Copyright (c) 2007 Starbreeze Studios + +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. + +Written by: Marcus Hennix +*/ + + + +#ifndef CONETWISTCONSTRAINT_H +#define CONETWISTCONSTRAINT_H + +#include "../../LinearMath/btVector3.h" +#include "btJacobianEntry.h" +#include "btTypedConstraint.h" + +class btRigidBody; + + +///btConeTwistConstraint can be used to simulate ragdoll joints (upper arm, leg etc) +class btConeTwistConstraint : public btTypedConstraint +{ + btJacobianEntry m_jac[3]; //3 orthogonal linear constraints + + btTransform m_rbAFrame; + btTransform m_rbBFrame; + + btScalar m_limitSoftness; + btScalar m_biasFactor; + btScalar m_relaxationFactor; + + btScalar m_swingSpan1; + btScalar m_swingSpan2; + btScalar m_twistSpan; + + btVector3 m_swingAxis; + btVector3 m_twistAxis; + + btScalar m_kSwing; + btScalar m_kTwist; + + btScalar m_twistLimitSign; + btScalar m_swingCorrection; + btScalar m_twistCorrection; + + btScalar m_accSwingLimitImpulse; + btScalar m_accTwistLimitImpulse; + + bool m_angularOnly; + bool m_solveTwistLimit; + bool m_solveSwingLimit; + + +public: + + btConeTwistConstraint(btRigidBody& rbA,btRigidBody& rbB,const btTransform& rbAFrame, const btTransform& rbBFrame); + + btConeTwistConstraint(btRigidBody& rbA,const btTransform& rbAFrame); + + btConeTwistConstraint(); + + virtual void buildJacobian(); + + virtual void solveConstraint(btScalar timeStep); + + void updateRHS(btScalar timeStep); + + const btRigidBody& getRigidBodyA() const + { + return m_rbA; + } + const btRigidBody& getRigidBodyB() const + { + return m_rbB; + } + + void setAngularOnly(bool angularOnly) + { + m_angularOnly = angularOnly; + } + + void setLimit(btScalar _swingSpan1,btScalar _swingSpan2,btScalar _twistSpan, btScalar _softness = 0.8f, btScalar _biasFactor = 0.3f, btScalar _relaxationFactor = 1.0f) + { + m_swingSpan1 = _swingSpan1; + m_swingSpan2 = _swingSpan2; + m_twistSpan = _twistSpan; + + m_limitSoftness = _softness; + m_biasFactor = _biasFactor; + m_relaxationFactor = _relaxationFactor; + } + + const btTransform& getAFrame() { return m_rbAFrame; }; + const btTransform& getBFrame() { return m_rbBFrame; }; + + inline int getSolveTwistLimit() + { + return m_solveTwistLimit; + } + + inline int getSolveSwingLimit() + { + return m_solveTwistLimit; + } + + inline btScalar getTwistLimitSign() + { + return m_twistLimitSign; + } + +}; + +#endif //CONETWISTCONSTRAINT_H diff --git a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btConstraintSolver.h b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btConstraintSolver.h new file mode 100644 index 00000000000..7e8458c2c7b --- /dev/null +++ b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btConstraintSolver.h @@ -0,0 +1,45 @@ +/* +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 CONSTRAINT_SOLVER_H +#define CONSTRAINT_SOLVER_H + +#include "../../LinearMath/btScalar.h" + +class btPersistentManifold; +class btRigidBody; +class btCollisionObject; +class btTypedConstraint; +struct btContactSolverInfo; +struct btBroadphaseProxy; +class btIDebugDraw; +class btStackAlloc; + +/// btConstraintSolver provides solver interface +class btConstraintSolver +{ + +public: + + virtual ~btConstraintSolver() {} + + virtual btScalar solveGroup(btCollisionObject** bodies,int numBodies,btPersistentManifold** manifold,int numManifolds,btTypedConstraint** constraints,int numConstraints, const btContactSolverInfo& info,class btIDebugDraw* debugDrawer, btStackAlloc* stackAlloc) = 0; + +}; + + + + +#endif //CONSTRAINT_SOLVER_H diff --git a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btContactConstraint.cpp b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btContactConstraint.cpp new file mode 100644 index 00000000000..bb3fe832592 --- /dev/null +++ b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btContactConstraint.cpp @@ -0,0 +1,417 @@ +/* +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 "btContactConstraint.h" +#include "BulletDynamics/Dynamics/btRigidBody.h" +#include "LinearMath/btVector3.h" +#include "btJacobianEntry.h" +#include "btContactSolverInfo.h" +#include "LinearMath/btMinMax.h" +#include "BulletCollision/NarrowPhaseCollision/btManifoldPoint.h" + +#define ASSERT2 assert + +#define USE_INTERNAL_APPLY_IMPULSE 1 + + +//bilateral constraint between two dynamic objects +void resolveSingleBilateral(btRigidBody& body1, const btVector3& pos1, + btRigidBody& body2, const btVector3& pos2, + btScalar distance, const btVector3& normal,btScalar& impulse ,btScalar timeStep) +{ + (void)timeStep; + (void)distance; + + + btScalar normalLenSqr = normal.length2(); + ASSERT2(btFabs(normalLenSqr) < btScalar(1.1)); + if (normalLenSqr > btScalar(1.1)) + { + impulse = btScalar(0.); + return; + } + btVector3 rel_pos1 = pos1 - body1.getCenterOfMassPosition(); + btVector3 rel_pos2 = pos2 - body2.getCenterOfMassPosition(); + //this jacobian entry could be re-used for all iterations + + btVector3 vel1 = body1.getVelocityInLocalPoint(rel_pos1); + btVector3 vel2 = body2.getVelocityInLocalPoint(rel_pos2); + btVector3 vel = vel1 - vel2; + + + btJacobianEntry jac(body1.getCenterOfMassTransform().getBasis().transpose(), + body2.getCenterOfMassTransform().getBasis().transpose(), + rel_pos1,rel_pos2,normal,body1.getInvInertiaDiagLocal(),body1.getInvMass(), + body2.getInvInertiaDiagLocal(),body2.getInvMass()); + + btScalar jacDiagAB = jac.getDiagonal(); + btScalar jacDiagABInv = btScalar(1.) / jacDiagAB; + + btScalar rel_vel = jac.getRelativeVelocity( + body1.getLinearVelocity(), + body1.getCenterOfMassTransform().getBasis().transpose() * body1.getAngularVelocity(), + body2.getLinearVelocity(), + body2.getCenterOfMassTransform().getBasis().transpose() * body2.getAngularVelocity()); + btScalar a; + a=jacDiagABInv; + + + rel_vel = normal.dot(vel); + + //todo: move this into proper structure + btScalar contactDamping = btScalar(0.2); + +#ifdef ONLY_USE_LINEAR_MASS + btScalar massTerm = btScalar(1.) / (body1.getInvMass() + body2.getInvMass()); + impulse = - contactDamping * rel_vel * massTerm; +#else + btScalar velocityImpulse = -contactDamping * rel_vel * jacDiagABInv; + impulse = velocityImpulse; +#endif +} + + + +//response between two dynamic objects with friction +btScalar resolveSingleCollision( + btRigidBody& body1, + btRigidBody& body2, + btManifoldPoint& contactPoint, + const btContactSolverInfo& solverInfo) +{ + + const btVector3& pos1_ = contactPoint.getPositionWorldOnA(); + const btVector3& pos2_ = contactPoint.getPositionWorldOnB(); + const btVector3& normal = contactPoint.m_normalWorldOnB; + + //constant over all iterations + btVector3 rel_pos1 = pos1_ - body1.getCenterOfMassPosition(); + btVector3 rel_pos2 = pos2_ - body2.getCenterOfMassPosition(); + + btVector3 vel1 = body1.getVelocityInLocalPoint(rel_pos1); + btVector3 vel2 = body2.getVelocityInLocalPoint(rel_pos2); + btVector3 vel = vel1 - vel2; + btScalar rel_vel; + rel_vel = normal.dot(vel); + + btScalar Kfps = btScalar(1.) / solverInfo.m_timeStep ; + + // btScalar damping = solverInfo.m_damping ; + btScalar Kerp = solverInfo.m_erp; + btScalar Kcor = Kerp *Kfps; + + btConstraintPersistentData* cpd = (btConstraintPersistentData*) contactPoint.m_userPersistentData; + assert(cpd); + btScalar distance = cpd->m_penetration; + btScalar positionalError = Kcor *-distance; + btScalar velocityError = cpd->m_restitution - rel_vel;// * damping; + + btScalar penetrationImpulse = positionalError * cpd->m_jacDiagABInv; + + btScalar velocityImpulse = velocityError * cpd->m_jacDiagABInv; + + btScalar normalImpulse = penetrationImpulse+velocityImpulse; + + // See Erin Catto's GDC 2006 paper: Clamp the accumulated impulse + btScalar oldNormalImpulse = cpd->m_appliedImpulse; + btScalar sum = oldNormalImpulse + normalImpulse; + cpd->m_appliedImpulse = btScalar(0.) > sum ? btScalar(0.): sum; + + normalImpulse = cpd->m_appliedImpulse - oldNormalImpulse; + +#ifdef USE_INTERNAL_APPLY_IMPULSE + if (body1.getInvMass()) + { + body1.internalApplyImpulse(contactPoint.m_normalWorldOnB*body1.getInvMass(),cpd->m_angularComponentA,normalImpulse); + } + if (body2.getInvMass()) + { + body2.internalApplyImpulse(contactPoint.m_normalWorldOnB*body2.getInvMass(),cpd->m_angularComponentB,-normalImpulse); + } +#else //USE_INTERNAL_APPLY_IMPULSE + body1.applyImpulse(normal*(normalImpulse), rel_pos1); + body2.applyImpulse(-normal*(normalImpulse), rel_pos2); +#endif //USE_INTERNAL_APPLY_IMPULSE + + return normalImpulse; +} + + +btScalar resolveSingleFriction( + btRigidBody& body1, + btRigidBody& body2, + btManifoldPoint& contactPoint, + const btContactSolverInfo& solverInfo) +{ + + (void)solverInfo; + + const btVector3& pos1 = contactPoint.getPositionWorldOnA(); + const btVector3& pos2 = contactPoint.getPositionWorldOnB(); + + btVector3 rel_pos1 = pos1 - body1.getCenterOfMassPosition(); + btVector3 rel_pos2 = pos2 - body2.getCenterOfMassPosition(); + + btConstraintPersistentData* cpd = (btConstraintPersistentData*) contactPoint.m_userPersistentData; + assert(cpd); + + btScalar combinedFriction = cpd->m_friction; + + btScalar limit = cpd->m_appliedImpulse * combinedFriction; + + if (cpd->m_appliedImpulse>btScalar(0.)) + //friction + { + //apply friction in the 2 tangential directions + + // 1st tangent + btVector3 vel1 = body1.getVelocityInLocalPoint(rel_pos1); + btVector3 vel2 = body2.getVelocityInLocalPoint(rel_pos2); + btVector3 vel = vel1 - vel2; + + btScalar j1,j2; + + { + + btScalar vrel = cpd->m_frictionWorldTangential0.dot(vel); + + // calculate j that moves us to zero relative velocity + j1 = -vrel * cpd->m_jacDiagABInvTangent0; + btScalar oldTangentImpulse = cpd->m_accumulatedTangentImpulse0; + cpd->m_accumulatedTangentImpulse0 = oldTangentImpulse + j1; + GEN_set_min(cpd->m_accumulatedTangentImpulse0, limit); + GEN_set_max(cpd->m_accumulatedTangentImpulse0, -limit); + j1 = cpd->m_accumulatedTangentImpulse0 - oldTangentImpulse; + + } + { + // 2nd tangent + + btScalar vrel = cpd->m_frictionWorldTangential1.dot(vel); + + // calculate j that moves us to zero relative velocity + j2 = -vrel * cpd->m_jacDiagABInvTangent1; + btScalar oldTangentImpulse = cpd->m_accumulatedTangentImpulse1; + cpd->m_accumulatedTangentImpulse1 = oldTangentImpulse + j2; + GEN_set_min(cpd->m_accumulatedTangentImpulse1, limit); + GEN_set_max(cpd->m_accumulatedTangentImpulse1, -limit); + j2 = cpd->m_accumulatedTangentImpulse1 - oldTangentImpulse; + } + +#ifdef USE_INTERNAL_APPLY_IMPULSE + if (body1.getInvMass()) + { + body1.internalApplyImpulse(cpd->m_frictionWorldTangential0*body1.getInvMass(),cpd->m_frictionAngularComponent0A,j1); + body1.internalApplyImpulse(cpd->m_frictionWorldTangential1*body1.getInvMass(),cpd->m_frictionAngularComponent1A,j2); + } + if (body2.getInvMass()) + { + body2.internalApplyImpulse(cpd->m_frictionWorldTangential0*body2.getInvMass(),cpd->m_frictionAngularComponent0B,-j1); + body2.internalApplyImpulse(cpd->m_frictionWorldTangential1*body2.getInvMass(),cpd->m_frictionAngularComponent1B,-j2); + } +#else //USE_INTERNAL_APPLY_IMPULSE + body1.applyImpulse((j1 * cpd->m_frictionWorldTangential0)+(j2 * cpd->m_frictionWorldTangential1), rel_pos1); + body2.applyImpulse((j1 * -cpd->m_frictionWorldTangential0)+(j2 * -cpd->m_frictionWorldTangential1), rel_pos2); +#endif //USE_INTERNAL_APPLY_IMPULSE + + + } + return cpd->m_appliedImpulse; +} + + +btScalar resolveSingleFrictionOriginal( + btRigidBody& body1, + btRigidBody& body2, + btManifoldPoint& contactPoint, + const btContactSolverInfo& solverInfo) +{ + + (void)solverInfo; + + const btVector3& pos1 = contactPoint.getPositionWorldOnA(); + const btVector3& pos2 = contactPoint.getPositionWorldOnB(); + + btVector3 rel_pos1 = pos1 - body1.getCenterOfMassPosition(); + btVector3 rel_pos2 = pos2 - body2.getCenterOfMassPosition(); + + btConstraintPersistentData* cpd = (btConstraintPersistentData*) contactPoint.m_userPersistentData; + assert(cpd); + + btScalar combinedFriction = cpd->m_friction; + + btScalar limit = cpd->m_appliedImpulse * combinedFriction; + //if (contactPoint.m_appliedImpulse>btScalar(0.)) + //friction + { + //apply friction in the 2 tangential directions + + { + // 1st tangent + btVector3 vel1 = body1.getVelocityInLocalPoint(rel_pos1); + btVector3 vel2 = body2.getVelocityInLocalPoint(rel_pos2); + btVector3 vel = vel1 - vel2; + + btScalar vrel = cpd->m_frictionWorldTangential0.dot(vel); + + // calculate j that moves us to zero relative velocity + btScalar j = -vrel * cpd->m_jacDiagABInvTangent0; + btScalar total = cpd->m_accumulatedTangentImpulse0 + j; + GEN_set_min(total, limit); + GEN_set_max(total, -limit); + j = total - cpd->m_accumulatedTangentImpulse0; + cpd->m_accumulatedTangentImpulse0 = total; + body1.applyImpulse(j * cpd->m_frictionWorldTangential0, rel_pos1); + body2.applyImpulse(j * -cpd->m_frictionWorldTangential0, rel_pos2); + } + + + { + // 2nd tangent + btVector3 vel1 = body1.getVelocityInLocalPoint(rel_pos1); + btVector3 vel2 = body2.getVelocityInLocalPoint(rel_pos2); + btVector3 vel = vel1 - vel2; + + btScalar vrel = cpd->m_frictionWorldTangential1.dot(vel); + + // calculate j that moves us to zero relative velocity + btScalar j = -vrel * cpd->m_jacDiagABInvTangent1; + btScalar total = cpd->m_accumulatedTangentImpulse1 + j; + GEN_set_min(total, limit); + GEN_set_max(total, -limit); + j = total - cpd->m_accumulatedTangentImpulse1; + cpd->m_accumulatedTangentImpulse1 = total; + body1.applyImpulse(j * cpd->m_frictionWorldTangential1, rel_pos1); + body2.applyImpulse(j * -cpd->m_frictionWorldTangential1, rel_pos2); + } + } + return cpd->m_appliedImpulse; +} + + +//velocity + friction +//response between two dynamic objects with friction +btScalar resolveSingleCollisionCombined( + btRigidBody& body1, + btRigidBody& body2, + btManifoldPoint& contactPoint, + const btContactSolverInfo& solverInfo) +{ + + const btVector3& pos1 = contactPoint.getPositionWorldOnA(); + const btVector3& pos2 = contactPoint.getPositionWorldOnB(); + const btVector3& normal = contactPoint.m_normalWorldOnB; + + btVector3 rel_pos1 = pos1 - body1.getCenterOfMassPosition(); + btVector3 rel_pos2 = pos2 - body2.getCenterOfMassPosition(); + + btVector3 vel1 = body1.getVelocityInLocalPoint(rel_pos1); + btVector3 vel2 = body2.getVelocityInLocalPoint(rel_pos2); + btVector3 vel = vel1 - vel2; + btScalar rel_vel; + rel_vel = normal.dot(vel); + + btScalar Kfps = btScalar(1.) / solverInfo.m_timeStep ; + + //btScalar damping = solverInfo.m_damping ; + btScalar Kerp = solverInfo.m_erp; + btScalar Kcor = Kerp *Kfps; + + btConstraintPersistentData* cpd = (btConstraintPersistentData*) contactPoint.m_userPersistentData; + assert(cpd); + btScalar distance = cpd->m_penetration; + btScalar positionalError = Kcor *-distance; + btScalar velocityError = cpd->m_restitution - rel_vel;// * damping; + + btScalar penetrationImpulse = positionalError * cpd->m_jacDiagABInv; + + btScalar velocityImpulse = velocityError * cpd->m_jacDiagABInv; + + btScalar normalImpulse = penetrationImpulse+velocityImpulse; + + // See Erin Catto's GDC 2006 paper: Clamp the accumulated impulse + btScalar oldNormalImpulse = cpd->m_appliedImpulse; + btScalar sum = oldNormalImpulse + normalImpulse; + cpd->m_appliedImpulse = btScalar(0.) > sum ? btScalar(0.): sum; + + normalImpulse = cpd->m_appliedImpulse - oldNormalImpulse; + + +#ifdef USE_INTERNAL_APPLY_IMPULSE + if (body1.getInvMass()) + { + body1.internalApplyImpulse(contactPoint.m_normalWorldOnB*body1.getInvMass(),cpd->m_angularComponentA,normalImpulse); + } + if (body2.getInvMass()) + { + body2.internalApplyImpulse(contactPoint.m_normalWorldOnB*body2.getInvMass(),cpd->m_angularComponentB,-normalImpulse); + } +#else //USE_INTERNAL_APPLY_IMPULSE + body1.applyImpulse(normal*(normalImpulse), rel_pos1); + body2.applyImpulse(-normal*(normalImpulse), rel_pos2); +#endif //USE_INTERNAL_APPLY_IMPULSE + + { + //friction + btVector3 vel1 = body1.getVelocityInLocalPoint(rel_pos1); + btVector3 vel2 = body2.getVelocityInLocalPoint(rel_pos2); + btVector3 vel = vel1 - vel2; + + rel_vel = normal.dot(vel); + + + btVector3 lat_vel = vel - normal * rel_vel; + btScalar lat_rel_vel = lat_vel.length(); + + btScalar combinedFriction = cpd->m_friction; + + if (cpd->m_appliedImpulse > 0) + if (lat_rel_vel > SIMD_EPSILON) + { + lat_vel /= lat_rel_vel; + btVector3 temp1 = body1.getInvInertiaTensorWorld() * rel_pos1.cross(lat_vel); + btVector3 temp2 = body2.getInvInertiaTensorWorld() * rel_pos2.cross(lat_vel); + btScalar friction_impulse = lat_rel_vel / + (body1.getInvMass() + body2.getInvMass() + lat_vel.dot(temp1.cross(rel_pos1) + temp2.cross(rel_pos2))); + btScalar normal_impulse = cpd->m_appliedImpulse * combinedFriction; + + GEN_set_min(friction_impulse, normal_impulse); + GEN_set_max(friction_impulse, -normal_impulse); + body1.applyImpulse(lat_vel * -friction_impulse, rel_pos1); + body2.applyImpulse(lat_vel * friction_impulse, rel_pos2); + } + } + + + + return normalImpulse; +} + +btScalar resolveSingleFrictionEmpty( + btRigidBody& body1, + btRigidBody& body2, + btManifoldPoint& contactPoint, + const btContactSolverInfo& solverInfo) +{ + (void)contactPoint; + (void)body1; + (void)body2; + (void)solverInfo; + + + return btScalar(0.); +}; + diff --git a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btContactConstraint.h b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btContactConstraint.h new file mode 100644 index 00000000000..0834deddeac --- /dev/null +++ b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btContactConstraint.h @@ -0,0 +1,122 @@ +/* +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 CONTACT_CONSTRAINT_H +#define CONTACT_CONSTRAINT_H + +//todo: make into a proper class working with the iterative constraint solver + +class btRigidBody; +#include "../../LinearMath/btVector3.h" +#include "../../LinearMath/btScalar.h" +struct btContactSolverInfo; +class btManifoldPoint; + +enum { + DEFAULT_CONTACT_SOLVER_TYPE=0, + CONTACT_SOLVER_TYPE1, + CONTACT_SOLVER_TYPE2, + USER_CONTACT_SOLVER_TYPE1, + MAX_CONTACT_SOLVER_TYPES +}; + + +typedef btScalar (*ContactSolverFunc)(btRigidBody& body1, + btRigidBody& body2, + class btManifoldPoint& contactPoint, + const btContactSolverInfo& info); + +///stores some extra information to each contact point. It is not in the contact point, because that want to keep the collision detection independent from the constraint solver. +struct btConstraintPersistentData +{ + inline btConstraintPersistentData() + :m_appliedImpulse(btScalar(0.)), + m_prevAppliedImpulse(btScalar(0.)), + m_accumulatedTangentImpulse0(btScalar(0.)), + m_accumulatedTangentImpulse1(btScalar(0.)), + m_jacDiagABInv(btScalar(0.)), + m_persistentLifeTime(0), + m_restitution(btScalar(0.)), + m_friction(btScalar(0.)), + m_penetration(btScalar(0.)), + m_contactSolverFunc(0), + m_frictionSolverFunc(0) + { + } + + + /// total applied impulse during most recent frame + btScalar m_appliedImpulse; + btScalar m_prevAppliedImpulse; + btScalar m_accumulatedTangentImpulse0; + btScalar m_accumulatedTangentImpulse1; + + btScalar m_jacDiagABInv; + btScalar m_jacDiagABInvTangent0; + btScalar m_jacDiagABInvTangent1; + int m_persistentLifeTime; + btScalar m_restitution; + btScalar m_friction; + btScalar m_penetration; + btVector3 m_frictionWorldTangential0; + btVector3 m_frictionWorldTangential1; + + btVector3 m_frictionAngularComponent0A; + btVector3 m_frictionAngularComponent0B; + btVector3 m_frictionAngularComponent1A; + btVector3 m_frictionAngularComponent1B; + + //some data doesn't need to be persistent over frames: todo: clean/reuse this + btVector3 m_angularComponentA; + btVector3 m_angularComponentB; + + ContactSolverFunc m_contactSolverFunc; + ContactSolverFunc m_frictionSolverFunc; + +}; + +///bilateral constraint between two dynamic objects +///positive distance = separation, negative distance = penetration +void resolveSingleBilateral(btRigidBody& body1, const btVector3& pos1, + btRigidBody& body2, const btVector3& pos2, + btScalar distance, const btVector3& normal,btScalar& impulse ,btScalar timeStep); + + +///contact constraint resolution: +///calculate and apply impulse to satisfy non-penetration and non-negative relative velocity constraint +///positive distance = separation, negative distance = penetration +btScalar resolveSingleCollision( + btRigidBody& body1, + btRigidBody& body2, + btManifoldPoint& contactPoint, + const btContactSolverInfo& info); + +btScalar resolveSingleFriction( + btRigidBody& body1, + btRigidBody& body2, + btManifoldPoint& contactPoint, + const btContactSolverInfo& solverInfo + ); + + + +btScalar resolveSingleCollisionCombined( + btRigidBody& body1, + btRigidBody& body2, + btManifoldPoint& contactPoint, + const btContactSolverInfo& solverInfo + ); + +#endif //CONTACT_CONSTRAINT_H diff --git a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btContactSolverInfo.h b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btContactSolverInfo.h new file mode 100644 index 00000000000..c3c73e300f4 --- /dev/null +++ b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btContactSolverInfo.h @@ -0,0 +1,47 @@ +/* +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 CONTACT_SOLVER_INFO +#define CONTACT_SOLVER_INFO + + +struct btContactSolverInfo +{ + + inline btContactSolverInfo() + { + m_tau = btScalar(0.6); + m_damping = btScalar(1.0); + m_friction = btScalar(0.3); + m_restitution = btScalar(0.); + m_maxErrorReduction = btScalar(20.); + m_numIterations = 10; + m_erp = btScalar(0.4); + m_sor = btScalar(1.3); + } + + btScalar m_tau; + btScalar m_damping; + btScalar m_friction; + btScalar m_timeStep; + btScalar m_restitution; + int m_numIterations; + btScalar m_maxErrorReduction; + btScalar m_sor; + btScalar m_erp; + +}; + +#endif //CONTACT_SOLVER_INFO diff --git a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.cpp b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.cpp new file mode 100644 index 00000000000..747d10d1f8b --- /dev/null +++ b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.cpp @@ -0,0 +1,389 @@ +/* +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 "btGeneric6DofConstraint.h" +#include "BulletDynamics/Dynamics/btRigidBody.h" +#include "LinearMath/btTransformUtil.h" +#include + +static const btScalar kSign[] = { btScalar(1.0), btScalar(-1.0), btScalar(1.0) }; +static const int kAxisA[] = { 1, 0, 0 }; +static const int kAxisB[] = { 2, 2, 1 }; +#define GENERIC_D6_DISABLE_WARMSTARTING 1 + +btGeneric6DofConstraint::btGeneric6DofConstraint() +{ +} + +btGeneric6DofConstraint::btGeneric6DofConstraint(btRigidBody& rbA, btRigidBody& rbB, const btTransform& frameInA, const btTransform& frameInB) +: btTypedConstraint(rbA, rbB) +, m_frameInA(frameInA) +, m_frameInB(frameInB) +{ + //free means upper < lower, + //locked means upper == lower + //limited means upper > lower + //so start all locked + for (int i=0; i<6;++i) + { + m_lowerLimit[i] = btScalar(0.0); + m_upperLimit[i] = btScalar(0.0); + m_accumulatedImpulse[i] = btScalar(0.0); + } + +} + + +void btGeneric6DofConstraint::buildJacobian() +{ + btVector3 localNormalInA(0,0,0); + + const btVector3& pivotInA = m_frameInA.getOrigin(); + const btVector3& pivotInB = m_frameInB.getOrigin(); + + btVector3 pivotAInW = m_rbA.getCenterOfMassTransform() * m_frameInA.getOrigin(); + btVector3 pivotBInW = m_rbB.getCenterOfMassTransform() * m_frameInB.getOrigin(); + + btVector3 rel_pos1 = pivotAInW - m_rbA.getCenterOfMassPosition(); + btVector3 rel_pos2 = pivotBInW - m_rbB.getCenterOfMassPosition(); + + int i; + //linear part + for (i=0;i<3;i++) + { + if (isLimited(i)) + { + localNormalInA[i] = 1; + btVector3 normalWorld = m_rbA.getCenterOfMassTransform().getBasis() * localNormalInA; + + + // Create linear atom + new (&m_jacLinear[i]) btJacobianEntry( + m_rbA.getCenterOfMassTransform().getBasis().transpose(), + m_rbB.getCenterOfMassTransform().getBasis().transpose(), + m_rbA.getCenterOfMassTransform()*pivotInA - m_rbA.getCenterOfMassPosition(), + m_rbB.getCenterOfMassTransform()*pivotInB - m_rbB.getCenterOfMassPosition(), + normalWorld, + m_rbA.getInvInertiaDiagLocal(), + m_rbA.getInvMass(), + m_rbB.getInvInertiaDiagLocal(), + m_rbB.getInvMass()); + + //optionally disable warmstarting +#ifdef GENERIC_D6_DISABLE_WARMSTARTING + m_accumulatedImpulse[i] = btScalar(0.); +#endif //GENERIC_D6_DISABLE_WARMSTARTING + + // Apply accumulated impulse + btVector3 impulse_vector = m_accumulatedImpulse[i] * normalWorld; + + m_rbA.applyImpulse( impulse_vector, rel_pos1); + m_rbB.applyImpulse(-impulse_vector, rel_pos2); + + localNormalInA[i] = 0; + } + } + + // angular part + for (i=0;i<3;i++) + { + if (isLimited(i+3)) + { + btVector3 axisA = m_rbA.getCenterOfMassTransform().getBasis() * m_frameInA.getBasis().getColumn( kAxisA[i] ); + btVector3 axisB = m_rbB.getCenterOfMassTransform().getBasis() * m_frameInB.getBasis().getColumn( kAxisB[i] ); + + // Dirk: This is IMO mathematically the correct way, but we should consider axisA and axisB being near parallel maybe + btVector3 axis = kSign[i] * axisA.cross(axisB); + + // Create angular atom + new (&m_jacAng[i]) btJacobianEntry(axis, + m_rbA.getCenterOfMassTransform().getBasis().transpose(), + m_rbB.getCenterOfMassTransform().getBasis().transpose(), + m_rbA.getInvInertiaDiagLocal(), + m_rbB.getInvInertiaDiagLocal()); + +#ifdef GENERIC_D6_DISABLE_WARMSTARTING + m_accumulatedImpulse[i + 3] = btScalar(0.); +#endif //GENERIC_D6_DISABLE_WARMSTARTING + + // Apply accumulated impulse + btVector3 impulse_vector = m_accumulatedImpulse[i + 3] * axis; + + m_rbA.applyTorqueImpulse( impulse_vector); + m_rbB.applyTorqueImpulse(-impulse_vector); + } + } +} + +btScalar getMatrixElem(const btMatrix3x3& mat,int index) +{ + int row = index%3; + int col = index / 3; + return mat[row][col]; +} + +///MatrixToEulerXYZ from http://www.geometrictools.com/LibFoundation/Mathematics/Wm4Matrix3.inl.html +bool MatrixToEulerXYZ(const btMatrix3x3& mat,btVector3& xyz) +{ + // rot = cy*cz -cy*sz sy + // cz*sx*sy+cx*sz cx*cz-sx*sy*sz -cy*sx + // -cx*cz*sy+sx*sz cz*sx+cx*sy*sz cx*cy + +/// 0..8 + + if (getMatrixElem(mat,2) < btScalar(1.0)) + { + if (getMatrixElem(mat,2) > btScalar(-1.0)) + { + xyz[0] = btAtan2(-getMatrixElem(mat,5),getMatrixElem(mat,8)); + xyz[1] = btAsin(getMatrixElem(mat,2)); + xyz[2] = btAtan2(-getMatrixElem(mat,1),getMatrixElem(mat,0)); + return true; + } + else + { + // WARNING. Not unique. XA - ZA = -atan2(r10,r11) + xyz[0] = -btAtan2(getMatrixElem(mat,3),getMatrixElem(mat,4)); + xyz[1] = -SIMD_HALF_PI; + xyz[2] = btScalar(0.0); + return false; + } + } + else + { + // WARNING. Not unique. XAngle + ZAngle = atan2(r10,r11) + xyz[0] = btAtan2(getMatrixElem(mat,3),getMatrixElem(mat,4)); + xyz[1] = SIMD_HALF_PI; + xyz[2] = 0.0; + + } + + return false; +} + + +void btGeneric6DofConstraint::solveConstraint(btScalar timeStep) +{ + btScalar tau = btScalar(0.1); + btScalar damping = btScalar(1.0); + + btVector3 pivotAInW = m_rbA.getCenterOfMassTransform() * m_frameInA.getOrigin(); + btVector3 pivotBInW = m_rbB.getCenterOfMassTransform() * m_frameInB.getOrigin(); + + btVector3 rel_pos1 = pivotAInW - m_rbA.getCenterOfMassPosition(); + btVector3 rel_pos2 = pivotBInW - m_rbB.getCenterOfMassPosition(); + + btVector3 localNormalInA(0,0,0); + int i; + + // linear + for (i=0;i<3;i++) + { + if (isLimited(i)) + { + btVector3 angvelA = m_rbA.getCenterOfMassTransform().getBasis().transpose() * m_rbA.getAngularVelocity(); + btVector3 angvelB = m_rbB.getCenterOfMassTransform().getBasis().transpose() * m_rbB.getAngularVelocity(); + + localNormalInA.setValue(0,0,0); + localNormalInA[i] = 1; + btVector3 normalWorld = m_rbA.getCenterOfMassTransform().getBasis() * localNormalInA; + + btScalar jacDiagABInv = btScalar(1.) / m_jacLinear[i].getDiagonal(); + + //velocity error (first order error) + btScalar rel_vel = m_jacLinear[i].getRelativeVelocity(m_rbA.getLinearVelocity(),angvelA, + m_rbB.getLinearVelocity(),angvelB); + + //positional error (zeroth order error) + btScalar depth = -(pivotAInW - pivotBInW).dot(normalWorld); + btScalar lo = btScalar(-1e30); + btScalar hi = btScalar(1e30); + + //handle the limits + if (m_lowerLimit[i] < m_upperLimit[i]) + { + { + if (depth > m_upperLimit[i]) + { + depth -= m_upperLimit[i]; + lo = btScalar(0.); + + } else + { + if (depth < m_lowerLimit[i]) + { + depth -= m_lowerLimit[i]; + hi = btScalar(0.); + } else + { + continue; + } + } + } + } + + btScalar normalImpulse= (tau*depth/timeStep - damping*rel_vel) * jacDiagABInv; + btScalar oldNormalImpulse = m_accumulatedImpulse[i]; + btScalar sum = oldNormalImpulse + normalImpulse; + m_accumulatedImpulse[i] = sum > hi ? btScalar(0.) : sum < lo ? btScalar(0.) : sum; + normalImpulse = m_accumulatedImpulse[i] - oldNormalImpulse; + + btVector3 impulse_vector = normalWorld * normalImpulse; + m_rbA.applyImpulse( impulse_vector, rel_pos1); + m_rbB.applyImpulse(-impulse_vector, rel_pos2); + + localNormalInA[i] = 0; + } + } + + btVector3 axis; + btScalar angle; + btTransform frameAWorld = m_rbA.getCenterOfMassTransform() * m_frameInA; + btTransform frameBWorld = m_rbB.getCenterOfMassTransform() * m_frameInB; + + btTransformUtil::calculateDiffAxisAngle(frameAWorld,frameBWorld,axis,angle); + btQuaternion diff(axis,angle); + btMatrix3x3 diffMat (diff); + btVector3 xyz; + ///this is not perfect, we can first check which axis are limited, and choose a more appropriate order + MatrixToEulerXYZ(diffMat,xyz); + + // angular + for (i=0;i<3;i++) + { + if (isLimited(i+3)) + { + btVector3 angvelA = m_rbA.getCenterOfMassTransform().getBasis().transpose() * m_rbA.getAngularVelocity(); + btVector3 angvelB = m_rbB.getCenterOfMassTransform().getBasis().transpose() * m_rbB.getAngularVelocity(); + + btScalar jacDiagABInv = btScalar(1.) / m_jacAng[i].getDiagonal(); + + //velocity error (first order error) + btScalar rel_vel = m_jacAng[i].getRelativeVelocity(m_rbA.getLinearVelocity(),angvelA, + m_rbB.getLinearVelocity(),angvelB); + + //positional error (zeroth order error) + btVector3 axisA = m_rbA.getCenterOfMassTransform().getBasis() * m_frameInA.getBasis().getColumn( kAxisA[i] ); + btVector3 axisB = m_rbB.getCenterOfMassTransform().getBasis() * m_frameInB.getBasis().getColumn( kAxisB[i] ); + + btScalar rel_pos = kSign[i] * axisA.dot(axisB); + + btScalar lo = btScalar(-1e30); + btScalar hi = btScalar(1e30); + + //handle the twist limit + if (m_lowerLimit[i+3] < m_upperLimit[i+3]) + { + //clamp the values + btScalar loLimit = m_lowerLimit[i+3] > -3.1415 ? m_lowerLimit[i+3] : btScalar(-1e30); + btScalar hiLimit = m_upperLimit[i+3] < 3.1415 ? m_upperLimit[i+3] : btScalar(1e30); + + btScalar projAngle = btScalar(-1.)*xyz[i]; + + if (projAngle < loLimit) + { + hi = btScalar(0.); + rel_pos = (loLimit - projAngle); + } else + { + if (projAngle > hiLimit) + { + lo = btScalar(0.); + rel_pos = (hiLimit - projAngle); + } else + { + continue; + } + } + } + + //impulse + + btScalar normalImpulse= -(tau*rel_pos/timeStep + damping*rel_vel) * jacDiagABInv; + btScalar oldNormalImpulse = m_accumulatedImpulse[i+3]; + btScalar sum = oldNormalImpulse + normalImpulse; + m_accumulatedImpulse[i+3] = sum > hi ? btScalar(0.) : sum < lo ? btScalar(0.) : sum; + normalImpulse = m_accumulatedImpulse[i+3] - oldNormalImpulse; + + // Dirk: Not needed - we could actually project onto Jacobian entry here (same as above) + btVector3 axis = kSign[i] * axisA.cross(axisB); + btVector3 impulse_vector = axis * normalImpulse; + + m_rbA.applyTorqueImpulse( impulse_vector); + m_rbB.applyTorqueImpulse(-impulse_vector); + } + } +} + +void btGeneric6DofConstraint::updateRHS(btScalar timeStep) +{ + (void)timeStep; + +} + +btScalar btGeneric6DofConstraint::computeAngle(int axis) const + { + btScalar angle = btScalar(0.f); + + switch (axis) + { + case 0: + { + btVector3 v1 = m_rbA.getCenterOfMassTransform().getBasis() * m_frameInA.getBasis().getColumn(1); + btVector3 v2 = m_rbB.getCenterOfMassTransform().getBasis() * m_frameInB.getBasis().getColumn(1); + btVector3 w2 = m_rbB.getCenterOfMassTransform().getBasis() * m_frameInB.getBasis().getColumn(2); + + btScalar s = v1.dot(w2); + btScalar c = v1.dot(v2); + + angle = btAtan2( s, c ); + } + break; + + case 1: + { + btVector3 w1 = m_rbA.getCenterOfMassTransform().getBasis() * m_frameInA.getBasis().getColumn(2); + btVector3 w2 = m_rbB.getCenterOfMassTransform().getBasis() * m_frameInB.getBasis().getColumn(2); + btVector3 u2 = m_rbB.getCenterOfMassTransform().getBasis() * m_frameInB.getBasis().getColumn(0); + + btScalar s = w1.dot(u2); + btScalar c = w1.dot(w2); + + angle = btAtan2( s, c ); + } + break; + + case 2: + { + btVector3 u1 = m_rbA.getCenterOfMassTransform().getBasis() * m_frameInA.getBasis().getColumn(0); + btVector3 u2 = m_rbB.getCenterOfMassTransform().getBasis() * m_frameInB.getBasis().getColumn(0); + btVector3 v2 = m_rbB.getCenterOfMassTransform().getBasis() * m_frameInB.getBasis().getColumn(1); + + btScalar s = u1.dot(v2); + btScalar c = u1.dot(u2); + + angle = btAtan2( s, c ); + } + break; + default: + btAssert ( 0 ) ; + + break ; + } + + return angle; + } + diff --git a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.h b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.h new file mode 100644 index 00000000000..b114e54fa69 --- /dev/null +++ b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.h @@ -0,0 +1,120 @@ +/* +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 GENERIC_6DOF_CONSTRAINT_H +#define GENERIC_6DOF_CONSTRAINT_H + +#include "../../LinearMath/btVector3.h" +#include "btJacobianEntry.h" +#include "btTypedConstraint.h" + +class btRigidBody; + + + +/// btGeneric6DofConstraint between two rigidbodies each with a pivotpoint that descibes the axis location in local space +/// btGeneric6DofConstraint can leave any of the 6 degree of freedom 'free' or 'locked' +/// Work in progress (is still a Hinge actually) +class btGeneric6DofConstraint : public btTypedConstraint +{ + btJacobianEntry m_jacLinear[3]; // 3 orthogonal linear constraints + btJacobianEntry m_jacAng[3]; // 3 orthogonal angular constraints + + btTransform m_frameInA; // the constraint space w.r.t body A + btTransform m_frameInB; // the constraint space w.r.t body B + + btScalar m_lowerLimit[6]; // the constraint lower limits + btScalar m_upperLimit[6]; // the constraint upper limits + + btScalar m_accumulatedImpulse[6]; + + btGeneric6DofConstraint& operator=(btGeneric6DofConstraint& other) + { + btAssert(0); + (void) other; + return *this; + } + +public: + btGeneric6DofConstraint(btRigidBody& rbA, btRigidBody& rbB, const btTransform& frameInA, const btTransform& frameInB ); + + btGeneric6DofConstraint(); + + + virtual void buildJacobian(); + + virtual void solveConstraint(btScalar timeStep); + + void updateRHS(btScalar timeStep); + + btScalar computeAngle(int axis) const; + + void setLinearLowerLimit(const btVector3& linearLower) + { + m_lowerLimit[0] = linearLower.getX(); + m_lowerLimit[1] = linearLower.getY(); + m_lowerLimit[2] = linearLower.getZ(); + } + + void setLinearUpperLimit(const btVector3& linearUpper) + { + m_upperLimit[0] = linearUpper.getX(); + m_upperLimit[1] = linearUpper.getY(); + m_upperLimit[2] = linearUpper.getZ(); + } + + void setAngularLowerLimit(const btVector3& angularLower) + { + m_lowerLimit[3] = angularLower.getX(); + m_lowerLimit[4] = angularLower.getY(); + m_lowerLimit[5] = angularLower.getZ(); + } + + void setAngularUpperLimit(const btVector3& angularUpper) + { + m_upperLimit[3] = angularUpper.getX(); + m_upperLimit[4] = angularUpper.getY(); + m_upperLimit[5] = angularUpper.getZ(); + } + + //first 3 are linear, next 3 are angular + void SetLimit(int axis, btScalar lo, btScalar hi) + { + m_lowerLimit[axis] = lo; + m_upperLimit[axis] = hi; + } + + //free means upper < lower, + //locked means upper == lower + //limited means upper > lower + //limitIndex: first 3 are linear, next 3 are angular + bool isLimited(int limitIndex) + { + return (m_upperLimit[limitIndex] >= m_lowerLimit[limitIndex]); + } + + const btRigidBody& getRigidBodyA() const + { + return m_rbA; + } + const btRigidBody& getRigidBodyB() const + { + return m_rbB; + } + + +}; + +#endif //GENERIC_6DOF_CONSTRAINT_H diff --git a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btHingeConstraint.cpp b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btHingeConstraint.cpp new file mode 100644 index 00000000000..27e30987549 --- /dev/null +++ b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btHingeConstraint.cpp @@ -0,0 +1,229 @@ +/* +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 "btHingeConstraint.h" +#include "BulletDynamics/Dynamics/btRigidBody.h" +#include "LinearMath/btTransformUtil.h" +#include + +btHingeConstraint::btHingeConstraint(): +m_enableAngularMotor(false) +{ +} + +btHingeConstraint::btHingeConstraint(btRigidBody& rbA,btRigidBody& rbB, const btVector3& pivotInA,const btVector3& pivotInB, + btVector3& axisInA,btVector3& axisInB) +:btTypedConstraint(rbA,rbB),m_pivotInA(pivotInA),m_pivotInB(pivotInB), +m_axisInA(axisInA), +m_axisInB(-axisInB), +m_angularOnly(false), +m_enableAngularMotor(false) +{ + +} + + +btHingeConstraint::btHingeConstraint(btRigidBody& rbA,const btVector3& pivotInA,btVector3& axisInA) +:btTypedConstraint(rbA),m_pivotInA(pivotInA),m_pivotInB(rbA.getCenterOfMassTransform()(pivotInA)), +m_axisInA(axisInA), +//fixed axis in worldspace +m_axisInB(rbA.getCenterOfMassTransform().getBasis() * -axisInA), +m_angularOnly(false), +m_enableAngularMotor(false) +{ + +} + +void btHingeConstraint::buildJacobian() +{ + m_appliedImpulse = btScalar(0.); + + btVector3 normal(0,0,0); + + if (!m_angularOnly) + { + for (int i=0;i<3;i++) + { + normal[i] = 1; + new (&m_jac[i]) btJacobianEntry( + m_rbA.getCenterOfMassTransform().getBasis().transpose(), + m_rbB.getCenterOfMassTransform().getBasis().transpose(), + m_rbA.getCenterOfMassTransform()*m_pivotInA - m_rbA.getCenterOfMassPosition(), + m_rbB.getCenterOfMassTransform()*m_pivotInB - m_rbB.getCenterOfMassPosition(), + normal, + m_rbA.getInvInertiaDiagLocal(), + m_rbA.getInvMass(), + m_rbB.getInvInertiaDiagLocal(), + m_rbB.getInvMass()); + normal[i] = 0; + } + } + + //calculate two perpendicular jointAxis, orthogonal to hingeAxis + //these two jointAxis require equal angular velocities for both bodies + + //this is unused for now, it's a todo + btVector3 jointAxis0local; + btVector3 jointAxis1local; + + btPlaneSpace1(m_axisInA,jointAxis0local,jointAxis1local); + + getRigidBodyA().getCenterOfMassTransform().getBasis() * m_axisInA; + btVector3 jointAxis0 = getRigidBodyA().getCenterOfMassTransform().getBasis() * jointAxis0local; + btVector3 jointAxis1 = getRigidBodyA().getCenterOfMassTransform().getBasis() * jointAxis1local; + btVector3 hingeAxisWorld = getRigidBodyA().getCenterOfMassTransform().getBasis() * m_axisInA; + + new (&m_jacAng[0]) btJacobianEntry(jointAxis0, + m_rbA.getCenterOfMassTransform().getBasis().transpose(), + m_rbB.getCenterOfMassTransform().getBasis().transpose(), + m_rbA.getInvInertiaDiagLocal(), + m_rbB.getInvInertiaDiagLocal()); + + new (&m_jacAng[1]) btJacobianEntry(jointAxis1, + m_rbA.getCenterOfMassTransform().getBasis().transpose(), + m_rbB.getCenterOfMassTransform().getBasis().transpose(), + m_rbA.getInvInertiaDiagLocal(), + m_rbB.getInvInertiaDiagLocal()); + + new (&m_jacAng[2]) btJacobianEntry(hingeAxisWorld, + m_rbA.getCenterOfMassTransform().getBasis().transpose(), + m_rbB.getCenterOfMassTransform().getBasis().transpose(), + m_rbA.getInvInertiaDiagLocal(), + m_rbB.getInvInertiaDiagLocal()); + + + +} + +void btHingeConstraint::solveConstraint(btScalar timeStep) +{ + + btVector3 pivotAInW = m_rbA.getCenterOfMassTransform()*m_pivotInA; + btVector3 pivotBInW = m_rbB.getCenterOfMassTransform()*m_pivotInB; + + btVector3 normal(0,0,0); + btScalar tau = btScalar(0.3); + btScalar damping = btScalar(1.); + +//linear part + if (!m_angularOnly) + { + for (int i=0;i<3;i++) + { + normal[i] = 1; + btScalar jacDiagABInv = btScalar(1.) / m_jac[i].getDiagonal(); + + btVector3 rel_pos1 = pivotAInW - m_rbA.getCenterOfMassPosition(); + btVector3 rel_pos2 = pivotBInW - m_rbB.getCenterOfMassPosition(); + + btVector3 vel1 = m_rbA.getVelocityInLocalPoint(rel_pos1); + btVector3 vel2 = m_rbB.getVelocityInLocalPoint(rel_pos2); + btVector3 vel = vel1 - vel2; + btScalar rel_vel; + rel_vel = normal.dot(vel); + //positional error (zeroth order error) + btScalar depth = -(pivotAInW - pivotBInW).dot(normal); //this is the error projected on the normal + btScalar impulse = depth*tau/timeStep * jacDiagABInv - damping * rel_vel * jacDiagABInv * damping; + m_appliedImpulse += impulse; + btVector3 impulse_vector = normal * impulse; + m_rbA.applyImpulse(impulse_vector, pivotAInW - m_rbA.getCenterOfMassPosition()); + m_rbB.applyImpulse(-impulse_vector, pivotBInW - m_rbB.getCenterOfMassPosition()); + + normal[i] = 0; + } + } + + + { + ///solve angular part + + // get axes in world space + btVector3 axisA = getRigidBodyA().getCenterOfMassTransform().getBasis() * m_axisInA; + btVector3 axisB = getRigidBodyB().getCenterOfMassTransform().getBasis() * m_axisInB; + + const btVector3& angVelA = getRigidBodyA().getAngularVelocity(); + const btVector3& angVelB = getRigidBodyB().getAngularVelocity(); + + btVector3 angVelAroundHingeAxisA = axisA * axisA.dot(angVelA); + btVector3 angVelAroundHingeAxisB = axisB * axisB.dot(angVelB); + + btVector3 angAorthog = angVelA - angVelAroundHingeAxisA; + btVector3 angBorthog = angVelB - angVelAroundHingeAxisB; + btVector3 velrelOrthog = angAorthog-angBorthog; + { + //solve orthogonal angular velocity correction + btScalar relaxation = btScalar(1.); + btScalar len = velrelOrthog.length(); + if (len > btScalar(0.00001)) + { + btVector3 normal = velrelOrthog.normalized(); + btScalar denom = getRigidBodyA().computeAngularImpulseDenominator(normal) + + getRigidBodyB().computeAngularImpulseDenominator(normal); + // scale for mass and relaxation + //todo: expose this 0.9 factor to developer + velrelOrthog *= (btScalar(1.)/denom) * btScalar(0.9); + } + + //solve angular positional correction + btVector3 angularError = -axisA.cross(axisB) *(btScalar(1.)/timeStep); + btScalar len2 = angularError.length(); + if (len2>btScalar(0.00001)) + { + btVector3 normal2 = angularError.normalized(); + btScalar denom2 = getRigidBodyA().computeAngularImpulseDenominator(normal2) + + getRigidBodyB().computeAngularImpulseDenominator(normal2); + angularError *= (btScalar(1.)/denom2) * relaxation; + } + + m_rbA.applyTorqueImpulse(-velrelOrthog+angularError); + m_rbB.applyTorqueImpulse(velrelOrthog-angularError); + } + + //apply motor + if (m_enableAngularMotor) + { + //todo: add limits too + btVector3 angularLimit(0,0,0); + + btVector3 velrel = angVelAroundHingeAxisA - angVelAroundHingeAxisB; + btScalar projRelVel = velrel.dot(axisA); + + btScalar desiredMotorVel = m_motorTargetVelocity; + btScalar motor_relvel = desiredMotorVel - projRelVel; + + btScalar denom3 = getRigidBodyA().computeAngularImpulseDenominator(axisA) + + getRigidBodyB().computeAngularImpulseDenominator(axisA); + + btScalar unclippedMotorImpulse = (btScalar(1.)/denom3) * motor_relvel;; + //todo: should clip against accumulated impulse + btScalar clippedMotorImpulse = unclippedMotorImpulse > m_maxMotorImpulse ? m_maxMotorImpulse : unclippedMotorImpulse; + clippedMotorImpulse = clippedMotorImpulse < -m_maxMotorImpulse ? -m_maxMotorImpulse : clippedMotorImpulse; + btVector3 motorImp = clippedMotorImpulse * axisA; + + m_rbA.applyTorqueImpulse(motorImp+angularLimit); + m_rbB.applyTorqueImpulse(-motorImp-angularLimit); + + } + } + +} + +void btHingeConstraint::updateRHS(btScalar timeStep) +{ + (void)timeStep; + +} + diff --git a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btHingeConstraint.h b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btHingeConstraint.h new file mode 100644 index 00000000000..5c1ceafbc5b --- /dev/null +++ b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btHingeConstraint.h @@ -0,0 +1,81 @@ +/* +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 HINGECONSTRAINT_H +#define HINGECONSTRAINT_H + +#include "../../LinearMath/btVector3.h" +#include "btJacobianEntry.h" +#include "btTypedConstraint.h" + +class btRigidBody; + + +/// hinge constraint between two rigidbodies each with a pivotpoint that descibes the axis location in local space +/// axis defines the orientation of the hinge axis +class btHingeConstraint : public btTypedConstraint +{ + btJacobianEntry m_jac[3]; //3 orthogonal linear constraints + btJacobianEntry m_jacAng[3]; //2 orthogonal angular constraints+ 1 for limit/motor + + btVector3 m_pivotInA; + btVector3 m_pivotInB; + btVector3 m_axisInA; + btVector3 m_axisInB; + + bool m_angularOnly; + + btScalar m_motorTargetVelocity; + btScalar m_maxMotorImpulse; + bool m_enableAngularMotor; + +public: + + btHingeConstraint(btRigidBody& rbA,btRigidBody& rbB, const btVector3& pivotInA,const btVector3& pivotInB,btVector3& axisInA,btVector3& axisInB); + + btHingeConstraint(btRigidBody& rbA,const btVector3& pivotInA,btVector3& axisInA); + + btHingeConstraint(); + + virtual void buildJacobian(); + + virtual void solveConstraint(btScalar timeStep); + + void updateRHS(btScalar timeStep); + + const btRigidBody& getRigidBodyA() const + { + return m_rbA; + } + const btRigidBody& getRigidBodyB() const + { + return m_rbB; + } + + void setAngularOnly(bool angularOnly) + { + m_angularOnly = angularOnly; + } + + void enableAngularMotor(bool enableMotor,btScalar targetVelocity,btScalar maxMotorImpulse) + { + m_enableAngularMotor = enableMotor; + m_motorTargetVelocity = targetVelocity; + m_maxMotorImpulse = maxMotorImpulse; + } + +}; + +#endif //HINGECONSTRAINT_H diff --git a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btJacobianEntry.h b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btJacobianEntry.h new file mode 100644 index 00000000000..aae3ed0373f --- /dev/null +++ b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btJacobianEntry.h @@ -0,0 +1,156 @@ +/* +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 JACOBIAN_ENTRY_H +#define JACOBIAN_ENTRY_H + +#include "../../LinearMath/btVector3.h" +#include "../Dynamics/btRigidBody.h" + + +//notes: +// Another memory optimization would be to store m_1MinvJt in the remaining 3 w components +// which makes the btJacobianEntry memory layout 16 bytes +// if you only are interested in angular part, just feed massInvA and massInvB zero + +/// Jacobian entry is an abstraction that allows to describe constraints +/// it can be used in combination with a constraint solver +/// Can be used to relate the effect of an impulse to the constraint error +class btJacobianEntry +{ +public: + btJacobianEntry() {}; + //constraint between two different rigidbodies + btJacobianEntry( + const btMatrix3x3& world2A, + const btMatrix3x3& world2B, + const btVector3& rel_pos1,const btVector3& rel_pos2, + const btVector3& jointAxis, + const btVector3& inertiaInvA, + const btScalar massInvA, + const btVector3& inertiaInvB, + const btScalar massInvB) + :m_linearJointAxis(jointAxis) + { + m_aJ = world2A*(rel_pos1.cross(m_linearJointAxis)); + m_bJ = world2B*(rel_pos2.cross(-m_linearJointAxis)); + m_0MinvJt = inertiaInvA * m_aJ; + m_1MinvJt = inertiaInvB * m_bJ; + m_Adiag = massInvA + m_0MinvJt.dot(m_aJ) + massInvB + m_1MinvJt.dot(m_bJ); + + btAssert(m_Adiag > btScalar(0.0)); + } + + //angular constraint between two different rigidbodies + btJacobianEntry(const btVector3& jointAxis, + const btMatrix3x3& world2A, + const btMatrix3x3& world2B, + const btVector3& inertiaInvA, + const btVector3& inertiaInvB) + :m_linearJointAxis(btVector3(btScalar(0.),btScalar(0.),btScalar(0.))) + { + m_aJ= world2A*jointAxis; + m_bJ = world2B*-jointAxis; + m_0MinvJt = inertiaInvA * m_aJ; + m_1MinvJt = inertiaInvB * m_bJ; + m_Adiag = m_0MinvJt.dot(m_aJ) + m_1MinvJt.dot(m_bJ); + + btAssert(m_Adiag > btScalar(0.0)); + } + + //angular constraint between two different rigidbodies + btJacobianEntry(const btVector3& axisInA, + const btVector3& axisInB, + const btVector3& inertiaInvA, + const btVector3& inertiaInvB) + : m_linearJointAxis(btVector3(btScalar(0.),btScalar(0.),btScalar(0.))) + , m_aJ(axisInA) + , m_bJ(-axisInB) + { + m_0MinvJt = inertiaInvA * m_aJ; + m_1MinvJt = inertiaInvB * m_bJ; + m_Adiag = m_0MinvJt.dot(m_aJ) + m_1MinvJt.dot(m_bJ); + + btAssert(m_Adiag > btScalar(0.0)); + } + + //constraint on one rigidbody + btJacobianEntry( + const btMatrix3x3& world2A, + const btVector3& rel_pos1,const btVector3& rel_pos2, + const btVector3& jointAxis, + const btVector3& inertiaInvA, + const btScalar massInvA) + :m_linearJointAxis(jointAxis) + { + m_aJ= world2A*(rel_pos1.cross(jointAxis)); + m_bJ = world2A*(rel_pos2.cross(-jointAxis)); + m_0MinvJt = inertiaInvA * m_aJ; + m_1MinvJt = btVector3(btScalar(0.),btScalar(0.),btScalar(0.)); + m_Adiag = massInvA + m_0MinvJt.dot(m_aJ); + + btAssert(m_Adiag > btScalar(0.0)); + } + + btScalar getDiagonal() const { return m_Adiag; } + + // for two constraints on the same rigidbody (for example vehicle friction) + btScalar getNonDiagonal(const btJacobianEntry& jacB, const btScalar massInvA) const + { + const btJacobianEntry& jacA = *this; + btScalar lin = massInvA * jacA.m_linearJointAxis.dot(jacB.m_linearJointAxis); + btScalar ang = jacA.m_0MinvJt.dot(jacB.m_aJ); + return lin + ang; + } + + + + // for two constraints on sharing two same rigidbodies (for example two contact points between two rigidbodies) + btScalar getNonDiagonal(const btJacobianEntry& jacB,const btScalar massInvA,const btScalar massInvB) const + { + const btJacobianEntry& jacA = *this; + btVector3 lin = jacA.m_linearJointAxis * jacB.m_linearJointAxis; + btVector3 ang0 = jacA.m_0MinvJt * jacB.m_aJ; + btVector3 ang1 = jacA.m_1MinvJt * jacB.m_bJ; + btVector3 lin0 = massInvA * lin ; + btVector3 lin1 = massInvB * lin; + btVector3 sum = ang0+ang1+lin0+lin1; + return sum[0]+sum[1]+sum[2]; + } + + btScalar getRelativeVelocity(const btVector3& linvelA,const btVector3& angvelA,const btVector3& linvelB,const btVector3& angvelB) + { + btVector3 linrel = linvelA - linvelB; + btVector3 angvela = angvelA * m_aJ; + btVector3 angvelb = angvelB * m_bJ; + linrel *= m_linearJointAxis; + angvela += angvelb; + angvela += linrel; + btScalar rel_vel2 = angvela[0]+angvela[1]+angvela[2]; + return rel_vel2 + SIMD_EPSILON; + } +//private: + + btVector3 m_linearJointAxis; + btVector3 m_aJ; + btVector3 m_bJ; + btVector3 m_0MinvJt; + btVector3 m_1MinvJt; + //Optimization: can be stored in the w/last component of one of the vectors + btScalar m_Adiag; + +}; + +#endif //JACOBIAN_ENTRY_H diff --git a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btPoint2PointConstraint.cpp b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btPoint2PointConstraint.cpp new file mode 100644 index 00000000000..aacb0a3ea66 --- /dev/null +++ b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btPoint2PointConstraint.cpp @@ -0,0 +1,116 @@ +/* +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 "btPoint2PointConstraint.h" +#include "BulletDynamics/Dynamics/btRigidBody.h" +#include + + + +btPoint2PointConstraint::btPoint2PointConstraint() +{ +} + +btPoint2PointConstraint::btPoint2PointConstraint(btRigidBody& rbA,btRigidBody& rbB, const btVector3& pivotInA,const btVector3& pivotInB) +:btTypedConstraint(rbA,rbB),m_pivotInA(pivotInA),m_pivotInB(pivotInB) +{ + +} + + +btPoint2PointConstraint::btPoint2PointConstraint(btRigidBody& rbA,const btVector3& pivotInA) +:btTypedConstraint(rbA),m_pivotInA(pivotInA),m_pivotInB(rbA.getCenterOfMassTransform()(pivotInA)) +{ + +} + +void btPoint2PointConstraint::buildJacobian() +{ + m_appliedImpulse = btScalar(0.); + + btVector3 normal(0,0,0); + + for (int i=0;i<3;i++) + { + normal[i] = 1; + new (&m_jac[i]) btJacobianEntry( + m_rbA.getCenterOfMassTransform().getBasis().transpose(), + m_rbB.getCenterOfMassTransform().getBasis().transpose(), + m_rbA.getCenterOfMassTransform()*m_pivotInA - m_rbA.getCenterOfMassPosition(), + m_rbB.getCenterOfMassTransform()*m_pivotInB - m_rbB.getCenterOfMassPosition(), + normal, + m_rbA.getInvInertiaDiagLocal(), + m_rbA.getInvMass(), + m_rbB.getInvInertiaDiagLocal(), + m_rbB.getInvMass()); + normal[i] = 0; + } + +} + +void btPoint2PointConstraint::solveConstraint(btScalar timeStep) +{ + btVector3 pivotAInW = m_rbA.getCenterOfMassTransform()*m_pivotInA; + btVector3 pivotBInW = m_rbB.getCenterOfMassTransform()*m_pivotInB; + + + btVector3 normal(0,0,0); + + +// btVector3 angvelA = m_rbA.getCenterOfMassTransform().getBasis().transpose() * m_rbA.getAngularVelocity(); +// btVector3 angvelB = m_rbB.getCenterOfMassTransform().getBasis().transpose() * m_rbB.getAngularVelocity(); + + for (int i=0;i<3;i++) + { + normal[i] = 1; + btScalar jacDiagABInv = btScalar(1.) / m_jac[i].getDiagonal(); + + btVector3 rel_pos1 = pivotAInW - m_rbA.getCenterOfMassPosition(); + btVector3 rel_pos2 = pivotBInW - m_rbB.getCenterOfMassPosition(); + //this jacobian entry could be re-used for all iterations + + btVector3 vel1 = m_rbA.getVelocityInLocalPoint(rel_pos1); + btVector3 vel2 = m_rbB.getVelocityInLocalPoint(rel_pos2); + btVector3 vel = vel1 - vel2; + + btScalar rel_vel; + rel_vel = normal.dot(vel); + + /* + //velocity error (first order error) + btScalar rel_vel = m_jac[i].getRelativeVelocity(m_rbA.getLinearVelocity(),angvelA, + m_rbB.getLinearVelocity(),angvelB); + */ + + //positional error (zeroth order error) + btScalar depth = -(pivotAInW - pivotBInW).dot(normal); //this is the error projected on the normal + + btScalar impulse = depth*m_setting.m_tau/timeStep * jacDiagABInv - m_setting.m_damping * rel_vel * jacDiagABInv; + m_appliedImpulse+=impulse; + btVector3 impulse_vector = normal * impulse; + m_rbA.applyImpulse(impulse_vector, pivotAInW - m_rbA.getCenterOfMassPosition()); + m_rbB.applyImpulse(-impulse_vector, pivotBInW - m_rbB.getCenterOfMassPosition()); + + normal[i] = 0; + } +} + +void btPoint2PointConstraint::updateRHS(btScalar timeStep) +{ + (void)timeStep; + +} + diff --git a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btPoint2PointConstraint.h b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btPoint2PointConstraint.h new file mode 100644 index 00000000000..71da8ac0347 --- /dev/null +++ b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btPoint2PointConstraint.h @@ -0,0 +1,77 @@ +/* +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 POINT2POINTCONSTRAINT_H +#define POINT2POINTCONSTRAINT_H + +#include "../../LinearMath/btVector3.h" +#include "btJacobianEntry.h" +#include "btTypedConstraint.h" + +class btRigidBody; + +struct btConstraintSetting +{ + btConstraintSetting() : + m_tau(btScalar(0.3)), + m_damping(btScalar(1.)) + { + } + btScalar m_tau; + btScalar m_damping; +}; + +/// point to point constraint between two rigidbodies each with a pivotpoint that descibes the 'ballsocket' location in local space +class btPoint2PointConstraint : public btTypedConstraint +{ + btJacobianEntry m_jac[3]; //3 orthogonal linear constraints + + btVector3 m_pivotInA; + btVector3 m_pivotInB; + + + +public: + + btConstraintSetting m_setting; + + btPoint2PointConstraint(btRigidBody& rbA,btRigidBody& rbB, const btVector3& pivotInA,const btVector3& pivotInB); + + btPoint2PointConstraint(btRigidBody& rbA,const btVector3& pivotInA); + + btPoint2PointConstraint(); + + virtual void buildJacobian(); + + + virtual void solveConstraint(btScalar timeStep); + + void updateRHS(btScalar timeStep); + + void setPivotA(const btVector3& pivotA) + { + m_pivotInA = pivotA; + } + + void setPivotB(const btVector3& pivotB) + { + m_pivotInB = pivotB; + } + + + +}; + +#endif //POINT2POINTCONSTRAINT_H diff --git a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.cpp b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.cpp new file mode 100644 index 00000000000..14b36ad44fd --- /dev/null +++ b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.cpp @@ -0,0 +1,1158 @@ +/* +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 "btSequentialImpulseConstraintSolver.h" +#include "BulletCollision/NarrowPhaseCollision/btPersistentManifold.h" +#include "BulletDynamics/Dynamics/btRigidBody.h" +#include "btContactConstraint.h" +#include "btSolve2LinearConstraint.h" +#include "btContactSolverInfo.h" +#include "LinearMath/btIDebugDraw.h" +#include "btJacobianEntry.h" +#include "LinearMath/btMinMax.h" +#include "BulletDynamics/ConstraintSolver/btTypedConstraint.h" +#include +#include "LinearMath/btStackAlloc.h" +#include "LinearMath/btQuickprof.h" +#include "btSolverBody.h" +#include "btSolverConstraint.h" + +#include "LinearMath/btAlignedObjectArray.h" + +#ifdef USE_PROFILE +#include "LinearMath/btQuickprof.h" +#endif //USE_PROFILE + +int totalCpd = 0; + +int gTotalContactPoints = 0; + +struct btOrderIndex +{ + int m_manifoldIndex; + int m_pointIndex; +}; + + + +#define SEQUENTIAL_IMPULSE_MAX_SOLVER_POINTS 16384 +static btOrderIndex gOrder[SEQUENTIAL_IMPULSE_MAX_SOLVER_POINTS]; + + +unsigned long btSequentialImpulseConstraintSolver::btRand2() +{ + m_btSeed2 = (1664525L*m_btSeed2 + 1013904223L) & 0xffffffff; + return m_btSeed2; +} + + + +//See ODE: adam's all-int straightforward(?) dRandInt (0..n-1) +int btSequentialImpulseConstraintSolver::btRandInt2 (int n) +{ + // seems good; xor-fold and modulus + const unsigned long un = n; + unsigned long r = btRand2(); + + // note: probably more aggressive than it needs to be -- might be + // able to get away without one or two of the innermost branches. + if (un <= 0x00010000UL) { + r ^= (r >> 16); + if (un <= 0x00000100UL) { + r ^= (r >> 8); + if (un <= 0x00000010UL) { + r ^= (r >> 4); + if (un <= 0x00000004UL) { + r ^= (r >> 2); + if (un <= 0x00000002UL) { + r ^= (r >> 1); + } + } + } + } + } + + return (int) (r % un); +} + + + + + +bool MyContactDestroyedCallback(void* userPersistentData) +{ + assert (userPersistentData); + btConstraintPersistentData* cpd = (btConstraintPersistentData*)userPersistentData; + delete cpd; + totalCpd--; + //printf("totalCpd = %i. DELETED Ptr %x\n",totalCpd,userPersistentData); + return true; +} + + + +btSequentialImpulseConstraintSolver::btSequentialImpulseConstraintSolver() +:m_solverMode(SOLVER_RANDMIZE_ORDER | SOLVER_CACHE_FRIENDLY), //not using SOLVER_USE_WARMSTARTING, +m_btSeed2(0) +{ + gContactDestroyedCallback = &MyContactDestroyedCallback; + + //initialize default friction/contact funcs + int i,j; + for (i=0;im_angularVelocity = rigidbody->getAngularVelocity(); + solverBody->m_centerOfMassPosition = rigidbody->getCenterOfMassPosition(); + solverBody->m_friction = rigidbody->getFriction(); +// solverBody->m_invInertiaWorld = rigidbody->getInvInertiaTensorWorld(); + solverBody->m_invMass = rigidbody->getInvMass(); + solverBody->m_linearVelocity = rigidbody->getLinearVelocity(); + solverBody->m_originalBody = rigidbody; + solverBody->m_angularFactor = rigidbody->getAngularFactor(); +} + +btScalar penetrationResolveFactor = btScalar(0.9); +btScalar restitutionCurve(btScalar rel_vel, btScalar restitution) +{ + btScalar rest = restitution * -rel_vel; + return rest; +} + + + + + + +//velocity + friction +//response between two dynamic objects with friction +SIMD_FORCE_INLINE btScalar resolveSingleCollisionCombinedCacheFriendly( + btSolverBody& body1, + btSolverBody& body2, + btSolverConstraint& contactConstraint, + const btContactSolverInfo& solverInfo) +{ + (void)solverInfo; + + btScalar normalImpulse(0.f); + { + if (contactConstraint.m_penetration < 0.f) + return 0.f; + + // Optimized version of projected relative velocity, use precomputed cross products with normal + // body1.getVelocityInLocalPoint(contactConstraint.m_rel_posA,vel1); + // body2.getVelocityInLocalPoint(contactConstraint.m_rel_posB,vel2); + // btVector3 vel = vel1 - vel2; + // btScalar rel_vel = contactConstraint.m_contactNormal.dot(vel); + + btScalar rel_vel; + btScalar vel1Dotn = contactConstraint.m_contactNormal.dot(body1.m_linearVelocity) + + contactConstraint.m_relpos1CrossNormal.dot(body1.m_angularVelocity); + btScalar vel2Dotn = contactConstraint.m_contactNormal.dot(body2.m_linearVelocity) + + contactConstraint.m_relpos2CrossNormal.dot(body2.m_angularVelocity); + + rel_vel = vel1Dotn-vel2Dotn; + + + btScalar positionalError = contactConstraint.m_penetration; + btScalar velocityError = contactConstraint.m_restitution - rel_vel;// * damping; + + btScalar penetrationImpulse = positionalError * contactConstraint.m_jacDiagABInv; + btScalar velocityImpulse = velocityError * contactConstraint.m_jacDiagABInv; + btScalar normalImpulse = penetrationImpulse+velocityImpulse; + + // See Erin Catto's GDC 2006 paper: Clamp the accumulated impulse + btScalar oldNormalImpulse = contactConstraint.m_appliedImpulse; + btScalar sum = oldNormalImpulse + normalImpulse; + contactConstraint.m_appliedImpulse = btScalar(0.) > sum ? btScalar(0.): sum; + + btScalar oldVelocityImpulse = contactConstraint.m_appliedVelocityImpulse; + btScalar velocitySum = oldVelocityImpulse + velocityImpulse; + contactConstraint.m_appliedVelocityImpulse = btScalar(0.) > velocitySum ? btScalar(0.): velocitySum; + + normalImpulse = contactConstraint.m_appliedImpulse - oldNormalImpulse; + + if (body1.m_invMass) + { + body1.internalApplyImpulse(contactConstraint.m_contactNormal*body1.m_invMass, + contactConstraint.m_angularComponentA,normalImpulse); + } + if (body2.m_invMass) + { + body2.internalApplyImpulse(contactConstraint.m_contactNormal*body2.m_invMass, + contactConstraint.m_angularComponentB,-normalImpulse); + } + + } + + + + return normalImpulse; +} + + +#ifndef NO_FRICTION_TANGENTIALS + +SIMD_FORCE_INLINE btScalar resolveSingleFrictionCacheFriendly( + btSolverBody& body1, + btSolverBody& body2, + btSolverConstraint& contactConstraint, + const btContactSolverInfo& solverInfo, + btScalar appliedNormalImpulse) +{ + (void)solverInfo; + + + const btScalar combinedFriction = contactConstraint.m_friction; + + const btScalar limit = appliedNormalImpulse * combinedFriction; + + if (appliedNormalImpulse>btScalar(0.)) + //friction + { + + btScalar j1; + { + + btScalar rel_vel; + const btScalar vel1Dotn = contactConstraint.m_contactNormal.dot(body1.m_linearVelocity) + + contactConstraint.m_relpos1CrossNormal.dot(body1.m_angularVelocity); + const btScalar vel2Dotn = contactConstraint.m_contactNormal.dot(body2.m_linearVelocity) + + contactConstraint.m_relpos2CrossNormal.dot(body2.m_angularVelocity); + rel_vel = vel1Dotn-vel2Dotn; + + // calculate j that moves us to zero relative velocity + j1 = -rel_vel * contactConstraint.m_jacDiagABInv; + btScalar oldTangentImpulse = contactConstraint.m_appliedImpulse; + contactConstraint.m_appliedImpulse = oldTangentImpulse + j1; + GEN_set_min(contactConstraint.m_appliedImpulse, limit); + GEN_set_max(contactConstraint.m_appliedImpulse, -limit); + j1 = contactConstraint.m_appliedImpulse - oldTangentImpulse; + + } + + if (body1.m_invMass) + { + body1.internalApplyImpulse(contactConstraint.m_contactNormal*body1.m_invMass,contactConstraint.m_angularComponentA,j1); + } + if (body2.m_invMass) + { + body2.internalApplyImpulse(contactConstraint.m_contactNormal*body2.m_invMass,contactConstraint.m_angularComponentB,-j1); + } + + } + return 0.f; +} + + +#else + +//velocity + friction +//response between two dynamic objects with friction +btScalar resolveSingleFrictionCacheFriendly( + btSolverBody& body1, + btSolverBody& body2, + btSolverConstraint& contactConstraint, + const btContactSolverInfo& solverInfo) +{ + + btVector3 vel1; + btVector3 vel2; + btScalar normalImpulse(0.f); + + { + const btVector3& normal = contactConstraint.m_contactNormal; + if (contactConstraint.m_penetration < 0.f) + return 0.f; + + + body1.getVelocityInLocalPoint(contactConstraint.m_rel_posA,vel1); + body2.getVelocityInLocalPoint(contactConstraint.m_rel_posB,vel2); + btVector3 vel = vel1 - vel2; + btScalar rel_vel; + rel_vel = normal.dot(vel); + + btVector3 lat_vel = vel - normal * rel_vel; + btScalar lat_rel_vel = lat_vel.length2(); + + btScalar combinedFriction = contactConstraint.m_friction; + const btVector3& rel_pos1 = contactConstraint.m_rel_posA; + const btVector3& rel_pos2 = contactConstraint.m_rel_posB; + + + //if (contactConstraint.m_appliedVelocityImpulse > 0.f) + if (lat_rel_vel > SIMD_EPSILON*SIMD_EPSILON) + { + lat_rel_vel = btSqrt(lat_rel_vel); + + lat_vel /= lat_rel_vel; + btVector3 temp1 = body1.m_invInertiaWorld * rel_pos1.cross(lat_vel); + btVector3 temp2 = body2.m_invInertiaWorld * rel_pos2.cross(lat_vel); + btScalar friction_impulse = lat_rel_vel / + (body1.m_invMass + body2.m_invMass + lat_vel.dot(temp1.cross(rel_pos1) + temp2.cross(rel_pos2))); + btScalar normal_impulse = contactConstraint.m_appliedVelocityImpulse * combinedFriction; + + GEN_set_min(friction_impulse, normal_impulse); + GEN_set_max(friction_impulse, -normal_impulse); + body1.applyImpulse(lat_vel * -friction_impulse, rel_pos1); + body2.applyImpulse(lat_vel * friction_impulse, rel_pos2); + } + } + + return normalImpulse; +} + +#endif //NO_FRICTION_TANGENTIALS + +btAlignedObjectArray tmpSolverBodyPool; +btAlignedObjectArray tmpSolverConstraintPool; +btAlignedObjectArray tmpSolverFrictionConstraintPool; + + +btScalar btSequentialImpulseConstraintSolver::solveGroupCacheFriendly(btCollisionObject** bodies,int numBodies,btPersistentManifold** manifoldPtr, int numManifolds,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& infoGlobal,btIDebugDraw* debugDrawer,btStackAlloc* stackAlloc) +{ + (void)stackAlloc; + (void)debugDrawer; + + if (!(numConstraints + numManifolds)) + { +// printf("empty\n"); + return 0.f; + } + + BEGIN_PROFILE("refreshManifolds"); + + int i; + for (i=0;igetBody0(); + btRigidBody* rb1 = (btRigidBody*)manifold->getBody1(); + + manifold->refreshContactPoints(rb0->getCenterOfMassTransform(),rb1->getCenterOfMassTransform()); + + } + + END_PROFILE("refreshManifolds"); + + + BEGIN_PROFILE("gatherSolverData"); + + //int sizeofSB = sizeof(btSolverBody); + //int sizeofSC = sizeof(btSolverConstraint); + + + //if (1) + { + //if m_stackAlloc, try to pack bodies/constraints to speed up solving +// btBlock* sablock; +// sablock = stackAlloc->beginBlock(); + + // int memsize = 16; +// unsigned char* stackMemory = stackAlloc->allocate(memsize); + + + //todo: use stack allocator for this temp memory + int minReservation = numManifolds*2; + + tmpSolverBodyPool.reserve(minReservation); + + { + for (int i=0;igetIslandTag() >= 0)) + { + btAssert(rb->getCompanionId() < 0); + int solverBodyId = tmpSolverBodyPool.size(); + btSolverBody& solverBody = tmpSolverBodyPool.expand(); + initSolverBody(&solverBody,rb); + rb->setCompanionId(solverBodyId); + } + } + } + + + tmpSolverConstraintPool.reserve(minReservation); + tmpSolverFrictionConstraintPool.reserve(minReservation); + { + int i; + + for (i=0;igetBody0(); + btRigidBody* rb1 = (btRigidBody*)manifold->getBody1(); + + + int solverBodyIdA=-1; + int solverBodyIdB=-1; + + if (manifold->getNumContacts()) + { + + + + if (rb0->getIslandTag() >= 0) + { + solverBodyIdA = rb0->getCompanionId(); + } else + { + //create a static body + solverBodyIdA = tmpSolverBodyPool.size(); + btSolverBody& solverBody = tmpSolverBodyPool.expand(); + initSolverBody(&solverBody,rb0); + } + + if (rb1->getIslandTag() >= 0) + { + solverBodyIdB = rb1->getCompanionId(); + } else + { + //create a static body + solverBodyIdB = tmpSolverBodyPool.size(); + btSolverBody& solverBody = tmpSolverBodyPool.expand(); + initSolverBody(&solverBody,rb1); + } + } + + for (int j=0;jgetNumContacts();j++) + { + + btManifoldPoint& cp = manifold->getContactPoint(j); + + int frictionIndex = tmpSolverConstraintPool.size(); + + if (cp.getDistance() <= btScalar(0.)) + { + + const btVector3& pos1 = cp.getPositionWorldOnA(); + const btVector3& pos2 = cp.getPositionWorldOnB(); + + btVector3 rel_pos1 = pos1 - rb0->getCenterOfMassPosition(); + btVector3 rel_pos2 = pos2 - rb1->getCenterOfMassPosition(); + + + btScalar relaxation = 1.f; + + { + btSolverConstraint& solverConstraint = tmpSolverConstraintPool.expand(); + + solverConstraint.m_solverBodyIdA = solverBodyIdA; + solverConstraint.m_solverBodyIdB = solverBodyIdB; + solverConstraint.m_constraintType = btSolverConstraint::BT_SOLVER_CONTACT_1D; + + + + { + //can be optimized, the cross products are already calculated + btScalar denom0 = rb0->computeImpulseDenominator(pos1,cp.m_normalWorldOnB); + btScalar denom1 = rb1->computeImpulseDenominator(pos2,cp.m_normalWorldOnB); + btScalar denom = relaxation/(denom0+denom1); + solverConstraint.m_jacDiagABInv = denom; + } + + solverConstraint.m_contactNormal = cp.m_normalWorldOnB; + solverConstraint.m_relpos1CrossNormal = rel_pos1.cross(cp.m_normalWorldOnB); + solverConstraint.m_relpos2CrossNormal = rel_pos2.cross(cp.m_normalWorldOnB); + + + btVector3 vel1 = rb0->getVelocityInLocalPoint(rel_pos1); + btVector3 vel2 = rb1->getVelocityInLocalPoint(rel_pos2); + + btVector3 vel = vel1 - vel2; + btScalar rel_vel; + rel_vel = cp.m_normalWorldOnB.dot(vel); + + + solverConstraint.m_penetration = cp.getDistance();///btScalar(infoGlobal.m_numIterations); + solverConstraint.m_friction = cp.m_combinedFriction; + btScalar rest = restitutionCurve(rel_vel, cp.m_combinedRestitution); + if (rest <= btScalar(0.)) + { + rest = 0.f; + }; + + btScalar penVel = -solverConstraint.m_penetration/infoGlobal.m_timeStep; + if (rest > penVel) + { + rest = btScalar(0.); + } + solverConstraint.m_restitution = rest; + + solverConstraint.m_penetration *= -(infoGlobal.m_erp/infoGlobal.m_timeStep); + + solverConstraint.m_appliedImpulse = 0.f; + solverConstraint.m_appliedVelocityImpulse = 0.f; + + + btVector3 torqueAxis0 = rel_pos1.cross(cp.m_normalWorldOnB); + solverConstraint.m_angularComponentA = rb0->getInvInertiaTensorWorld()*torqueAxis0; + btVector3 torqueAxis1 = rel_pos2.cross(cp.m_normalWorldOnB); + solverConstraint.m_angularComponentB = rb1->getInvInertiaTensorWorld()*torqueAxis1; + } + + //create 2 '1d axis' constraints for 2 tangential friction directions + + //re-calculate friction direction every frame, todo: check if this is really needed + btVector3 frictionTangential0a, frictionTangential1b; + + btPlaneSpace1(cp.m_normalWorldOnB,frictionTangential0a,frictionTangential1b); + + { + btSolverConstraint& solverConstraint = tmpSolverFrictionConstraintPool.expand(); + solverConstraint.m_contactNormal = frictionTangential0a; + + solverConstraint.m_solverBodyIdA = solverBodyIdA; + solverConstraint.m_solverBodyIdB = solverBodyIdB; + solverConstraint.m_constraintType = btSolverConstraint::BT_SOLVER_FRICTION_1D; + solverConstraint.m_frictionIndex = frictionIndex; + + solverConstraint.m_friction = cp.m_combinedFriction; + + solverConstraint.m_appliedImpulse = btScalar(0.); + solverConstraint.m_appliedVelocityImpulse = 0.f; + + btScalar denom0 = rb0->computeImpulseDenominator(pos1,solverConstraint.m_contactNormal); + btScalar denom1 = rb1->computeImpulseDenominator(pos2,solverConstraint.m_contactNormal); + btScalar denom = relaxation/(denom0+denom1); + solverConstraint.m_jacDiagABInv = denom; + + { + btVector3 ftorqueAxis0 = rel_pos1.cross(solverConstraint.m_contactNormal); + solverConstraint.m_relpos1CrossNormal = ftorqueAxis0; + solverConstraint.m_angularComponentA = rb0->getInvInertiaTensorWorld()*ftorqueAxis0; + } + { + btVector3 ftorqueAxis0 = rel_pos2.cross(solverConstraint.m_contactNormal); + solverConstraint.m_relpos2CrossNormal = ftorqueAxis0; + solverConstraint.m_angularComponentB = rb1->getInvInertiaTensorWorld()*ftorqueAxis0; + } + + } + + + { + + btSolverConstraint& solverConstraint = tmpSolverFrictionConstraintPool.expand(); + solverConstraint.m_contactNormal = frictionTangential1b; + + solverConstraint.m_solverBodyIdA = solverBodyIdA; + solverConstraint.m_solverBodyIdB = solverBodyIdB; + solverConstraint.m_constraintType = btSolverConstraint::BT_SOLVER_FRICTION_1D; + solverConstraint.m_frictionIndex = frictionIndex; + + solverConstraint.m_friction = cp.m_combinedFriction; + + solverConstraint.m_appliedImpulse = btScalar(0.); + solverConstraint.m_appliedVelocityImpulse = 0.f; + + btScalar denom0 = rb0->computeImpulseDenominator(pos1,solverConstraint.m_contactNormal); + btScalar denom1 = rb1->computeImpulseDenominator(pos2,solverConstraint.m_contactNormal); + btScalar denom = relaxation/(denom0+denom1); + solverConstraint.m_jacDiagABInv = denom; + { + btVector3 ftorqueAxis1 = rel_pos1.cross(solverConstraint.m_contactNormal); + solverConstraint.m_relpos1CrossNormal = ftorqueAxis1; + solverConstraint.m_angularComponentA = rb0->getInvInertiaTensorWorld()*ftorqueAxis1; + } + { + btVector3 ftorqueAxis1 = rel_pos2.cross(solverConstraint.m_contactNormal); + solverConstraint.m_relpos2CrossNormal = ftorqueAxis1; + solverConstraint.m_angularComponentB = rb1->getInvInertiaTensorWorld()*ftorqueAxis1; + } + } + + } + } + } + } + } + END_PROFILE("gatherSolverData"); + + BEGIN_PROFILE("prepareConstraints"); + + btContactSolverInfo info = infoGlobal; + + { + int j; + for (j=0;jbuildJacobian(); + } + } + + btAlignedObjectArray gOrderTmpConstraintPool; + btAlignedObjectArray gOrderFrictionConstraintPool; + + int numConstraintPool = tmpSolverConstraintPool.size(); + int numFrictionPool = tmpSolverFrictionConstraintPool.size(); + + ///todo: use stack allocator for such temporarily memory, same for solver bodies/constraints + gOrderTmpConstraintPool.resize(numConstraintPool); + gOrderFrictionConstraintPool.resize(numFrictionPool); + { + int i; + for (i=0;igetRigidBodyA().getIslandTag() >= 0) && (constraint->getRigidBodyA().getCompanionId() >= 0)) + { + tmpSolverBodyPool[constraint->getRigidBodyA().getCompanionId()].writebackVelocity(); + } + if ((constraint->getRigidBodyB().getIslandTag() >= 0) && (constraint->getRigidBodyB().getCompanionId() >= 0)) + { + tmpSolverBodyPool[constraint->getRigidBodyB().getCompanionId()].writebackVelocity(); + } + + constraint->solveConstraint(info.m_timeStep); + + if ((constraint->getRigidBodyA().getIslandTag() >= 0) && (constraint->getRigidBodyA().getCompanionId() >= 0)) + { + tmpSolverBodyPool[constraint->getRigidBodyA().getCompanionId()].readVelocity(); + } + if ((constraint->getRigidBodyB().getIslandTag() >= 0) && (constraint->getRigidBodyB().getCompanionId() >= 0)) + { + tmpSolverBodyPool[constraint->getRigidBodyB().getCompanionId()].readVelocity(); + } + + } + + { + int numPoolConstraints = tmpSolverConstraintPool.size(); + for (j=0;jgetNumContacts();p++) + { + gOrder[totalPoints].m_manifoldIndex = j; + gOrder[totalPoints].m_pointIndex = p; + totalPoints++; + } + } + } + + { + int j; + for (j=0;jbuildJacobian(); + } + } + + END_PROFILE("prepareConstraints"); + + + BEGIN_PROFILE("solveConstraints"); + + //should traverse the contacts random order... + int iteration; + + { + for ( iteration = 0;iterationsolveConstraint(info.m_timeStep); + } + + for (j=0;jgetBody0(), + (btRigidBody*)manifold->getBody1() + ,manifold->getContactPoint(gOrder[j].m_pointIndex),info,iteration,debugDrawer); + } + + for (j=0;jgetBody0(), + (btRigidBody*)manifold->getBody1(),manifold->getContactPoint(gOrder[j].m_pointIndex),info,iteration,debugDrawer); + } + } + } + + END_PROFILE("solveConstraints"); + + +#ifdef USE_PROFILE + btProfiler::endBlock("solve"); +#endif //USE_PROFILE + + + + + return btScalar(0.); +} + + + + + + + +void btSequentialImpulseConstraintSolver::prepareConstraints(btPersistentManifold* manifoldPtr, const btContactSolverInfo& info,btIDebugDraw* debugDrawer) +{ + + (void)debugDrawer; + + btRigidBody* body0 = (btRigidBody*)manifoldPtr->getBody0(); + btRigidBody* body1 = (btRigidBody*)manifoldPtr->getBody1(); + + + //only necessary to refresh the manifold once (first iteration). The integration is done outside the loop + { + manifoldPtr->refreshContactPoints(body0->getCenterOfMassTransform(),body1->getCenterOfMassTransform()); + + int numpoints = manifoldPtr->getNumContacts(); + + gTotalContactPoints += numpoints; + + btVector3 color(0,1,0); + for (int i=0;igetContactPoint(i); + if (cp.getDistance() <= btScalar(0.)) + { + const btVector3& pos1 = cp.getPositionWorldOnA(); + const btVector3& pos2 = cp.getPositionWorldOnB(); + + btVector3 rel_pos1 = pos1 - body0->getCenterOfMassPosition(); + btVector3 rel_pos2 = pos2 - body1->getCenterOfMassPosition(); + + + //this jacobian entry is re-used for all iterations + btJacobianEntry jac(body0->getCenterOfMassTransform().getBasis().transpose(), + body1->getCenterOfMassTransform().getBasis().transpose(), + rel_pos1,rel_pos2,cp.m_normalWorldOnB,body0->getInvInertiaDiagLocal(),body0->getInvMass(), + body1->getInvInertiaDiagLocal(),body1->getInvMass()); + + + btScalar jacDiagAB = jac.getDiagonal(); + + btConstraintPersistentData* cpd = (btConstraintPersistentData*) cp.m_userPersistentData; + if (cpd) + { + //might be invalid + cpd->m_persistentLifeTime++; + if (cpd->m_persistentLifeTime != cp.getLifeTime()) + { + //printf("Invalid: cpd->m_persistentLifeTime = %i cp.getLifeTime() = %i\n",cpd->m_persistentLifeTime,cp.getLifeTime()); + new (cpd) btConstraintPersistentData; + cpd->m_persistentLifeTime = cp.getLifeTime(); + + } else + { + //printf("Persistent: cpd->m_persistentLifeTime = %i cp.getLifeTime() = %i\n",cpd->m_persistentLifeTime,cp.getLifeTime()); + + } + } else + { + + cpd = new btConstraintPersistentData; + assert(cpd); + + totalCpd ++; + //printf("totalCpd = %i Created Ptr %x\n",totalCpd,cpd); + cp.m_userPersistentData = cpd; + cpd->m_persistentLifeTime = cp.getLifeTime(); + //printf("CREATED: %x . cpd->m_persistentLifeTime = %i cp.getLifeTime() = %i\n",cpd,cpd->m_persistentLifeTime,cp.getLifeTime()); + + } + assert(cpd); + + cpd->m_jacDiagABInv = btScalar(1.) / jacDiagAB; + + //Dependent on Rigidbody A and B types, fetch the contact/friction response func + //perhaps do a similar thing for friction/restutution combiner funcs... + + cpd->m_frictionSolverFunc = m_frictionDispatch[body0->m_frictionSolverType][body1->m_frictionSolverType]; + cpd->m_contactSolverFunc = m_contactDispatch[body0->m_contactSolverType][body1->m_contactSolverType]; + + btVector3 vel1 = body0->getVelocityInLocalPoint(rel_pos1); + btVector3 vel2 = body1->getVelocityInLocalPoint(rel_pos2); + btVector3 vel = vel1 - vel2; + btScalar rel_vel; + rel_vel = cp.m_normalWorldOnB.dot(vel); + + btScalar combinedRestitution = cp.m_combinedRestitution; + + cpd->m_penetration = cp.getDistance();///btScalar(info.m_numIterations); + cpd->m_friction = cp.m_combinedFriction; + cpd->m_restitution = restitutionCurve(rel_vel, combinedRestitution); + if (cpd->m_restitution <= btScalar(0.)) + { + cpd->m_restitution = btScalar(0.0); + + }; + + //restitution and penetration work in same direction so + //rel_vel + + btScalar penVel = -cpd->m_penetration/info.m_timeStep; + + if (cpd->m_restitution > penVel) + { + cpd->m_penetration = btScalar(0.); + } + + + + btScalar relaxation = info.m_damping; + if (m_solverMode & SOLVER_USE_WARMSTARTING) + { + cpd->m_appliedImpulse *= relaxation; + } else + { + cpd->m_appliedImpulse =btScalar(0.); + } + + //for friction + cpd->m_prevAppliedImpulse = cpd->m_appliedImpulse; + + //re-calculate friction direction every frame, todo: check if this is really needed + btPlaneSpace1(cp.m_normalWorldOnB,cpd->m_frictionWorldTangential0,cpd->m_frictionWorldTangential1); + + +#define NO_FRICTION_WARMSTART 1 + + #ifdef NO_FRICTION_WARMSTART + cpd->m_accumulatedTangentImpulse0 = btScalar(0.); + cpd->m_accumulatedTangentImpulse1 = btScalar(0.); + #endif //NO_FRICTION_WARMSTART + btScalar denom0 = body0->computeImpulseDenominator(pos1,cpd->m_frictionWorldTangential0); + btScalar denom1 = body1->computeImpulseDenominator(pos2,cpd->m_frictionWorldTangential0); + btScalar denom = relaxation/(denom0+denom1); + cpd->m_jacDiagABInvTangent0 = denom; + + + denom0 = body0->computeImpulseDenominator(pos1,cpd->m_frictionWorldTangential1); + denom1 = body1->computeImpulseDenominator(pos2,cpd->m_frictionWorldTangential1); + denom = relaxation/(denom0+denom1); + cpd->m_jacDiagABInvTangent1 = denom; + + btVector3 totalImpulse = + #ifndef NO_FRICTION_WARMSTART + cpd->m_frictionWorldTangential0*cpd->m_accumulatedTangentImpulse0+ + cpd->m_frictionWorldTangential1*cpd->m_accumulatedTangentImpulse1+ + #endif //NO_FRICTION_WARMSTART + cp.m_normalWorldOnB*cpd->m_appliedImpulse; + + + + /// + { + btVector3 torqueAxis0 = rel_pos1.cross(cp.m_normalWorldOnB); + cpd->m_angularComponentA = body0->getInvInertiaTensorWorld()*torqueAxis0; + btVector3 torqueAxis1 = rel_pos2.cross(cp.m_normalWorldOnB); + cpd->m_angularComponentB = body1->getInvInertiaTensorWorld()*torqueAxis1; + } + { + btVector3 ftorqueAxis0 = rel_pos1.cross(cpd->m_frictionWorldTangential0); + cpd->m_frictionAngularComponent0A = body0->getInvInertiaTensorWorld()*ftorqueAxis0; + } + { + btVector3 ftorqueAxis1 = rel_pos1.cross(cpd->m_frictionWorldTangential1); + cpd->m_frictionAngularComponent1A = body0->getInvInertiaTensorWorld()*ftorqueAxis1; + } + { + btVector3 ftorqueAxis0 = rel_pos2.cross(cpd->m_frictionWorldTangential0); + cpd->m_frictionAngularComponent0B = body1->getInvInertiaTensorWorld()*ftorqueAxis0; + } + { + btVector3 ftorqueAxis1 = rel_pos2.cross(cpd->m_frictionWorldTangential1); + cpd->m_frictionAngularComponent1B = body1->getInvInertiaTensorWorld()*ftorqueAxis1; + } + + /// + + + + //apply previous frames impulse on both bodies + body0->applyImpulse(totalImpulse, rel_pos1); + body1->applyImpulse(-totalImpulse, rel_pos2); + } + + } + } +} + + +btScalar btSequentialImpulseConstraintSolver::solveCombinedContactFriction(btRigidBody* body0,btRigidBody* body1, btManifoldPoint& cp, const btContactSolverInfo& info,int iter,btIDebugDraw* debugDrawer) +{ + btScalar maxImpulse = btScalar(0.); + + { + + btVector3 color(0,1,0); + { + if (cp.getDistance() <= btScalar(0.)) + { + + if (iter == 0) + { + if (debugDrawer) + debugDrawer->drawContactPoint(cp.m_positionWorldOnB,cp.m_normalWorldOnB,cp.getDistance(),cp.getLifeTime(),color); + } + + { + + //btConstraintPersistentData* cpd = (btConstraintPersistentData*) cp.m_userPersistentData; + btScalar impulse = resolveSingleCollisionCombined( + *body0,*body1, + cp, + info); + + if (maxImpulse < impulse) + maxImpulse = impulse; + + } + } + } + } + return maxImpulse; +} + + + +btScalar btSequentialImpulseConstraintSolver::solve(btRigidBody* body0,btRigidBody* body1, btManifoldPoint& cp, const btContactSolverInfo& info,int iter,btIDebugDraw* debugDrawer) +{ + + btScalar maxImpulse = btScalar(0.); + + { + + btVector3 color(0,1,0); + { + if (cp.getDistance() <= btScalar(0.)) + { + + if (iter == 0) + { + if (debugDrawer) + debugDrawer->drawContactPoint(cp.m_positionWorldOnB,cp.m_normalWorldOnB,cp.getDistance(),cp.getLifeTime(),color); + } + + { + + btConstraintPersistentData* cpd = (btConstraintPersistentData*) cp.m_userPersistentData; + btScalar impulse = cpd->m_contactSolverFunc( + *body0,*body1, + cp, + info); + + if (maxImpulse < impulse) + maxImpulse = impulse; + + } + } + } + } + return maxImpulse; +} + +btScalar btSequentialImpulseConstraintSolver::solveFriction(btRigidBody* body0,btRigidBody* body1, btManifoldPoint& cp, const btContactSolverInfo& info,int iter,btIDebugDraw* debugDrawer) +{ + + (void)debugDrawer; + (void)iter; + + + { + + btVector3 color(0,1,0); + { + + if (cp.getDistance() <= btScalar(0.)) + { + + btConstraintPersistentData* cpd = (btConstraintPersistentData*) cp.m_userPersistentData; + cpd->m_frictionSolverFunc( + *body0,*body1, + cp, + info); + + + } + } + + + } + return btScalar(0.); +} diff --git a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.h b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.h new file mode 100644 index 00000000000..13e70c41be4 --- /dev/null +++ b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.h @@ -0,0 +1,109 @@ +/* +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 SEQUENTIAL_IMPULSE_CONSTRAINT_SOLVER_H +#define SEQUENTIAL_IMPULSE_CONSTRAINT_SOLVER_H + +#include "btConstraintSolver.h" +class btIDebugDraw; +#include "btContactConstraint.h" + + + +/// btSequentialImpulseConstraintSolver uses a Propagation Method and Sequentially applies impulses +/// The approach is the 3D version of Erin Catto's GDC 2006 tutorial. See http://www.gphysics.com +/// Although Sequential Impulse is more intuitive, it is mathematically equivalent to Projected Successive Overrelaxation (iterative LCP) +/// Applies impulses for combined restitution and penetration recovery and to simulate friction +class btSequentialImpulseConstraintSolver : public btConstraintSolver +{ + +protected: + btScalar solve(btRigidBody* body0,btRigidBody* body1, btManifoldPoint& cp, const btContactSolverInfo& info,int iter,btIDebugDraw* debugDrawer); + btScalar solveFriction(btRigidBody* body0,btRigidBody* body1, btManifoldPoint& cp, const btContactSolverInfo& info,int iter,btIDebugDraw* debugDrawer); + void prepareConstraints(btPersistentManifold* manifoldPtr, const btContactSolverInfo& info,btIDebugDraw* debugDrawer); + + ContactSolverFunc m_contactDispatch[MAX_CONTACT_SOLVER_TYPES][MAX_CONTACT_SOLVER_TYPES]; + ContactSolverFunc m_frictionDispatch[MAX_CONTACT_SOLVER_TYPES][MAX_CONTACT_SOLVER_TYPES]; + + //choose between several modes, different friction model etc. + int m_solverMode; + ///m_btSeed2 is used for re-arranging the constraint rows. improves convergence/quality of friction + unsigned long m_btSeed2; + +public: + + enum eSolverMode + { + SOLVER_RANDMIZE_ORDER = 1, + SOLVER_FRICTION_SEPARATE = 2, + SOLVER_USE_WARMSTARTING = 4, + SOLVER_CACHE_FRIENDLY = 8 + }; + + btSequentialImpulseConstraintSolver(); + + ///Advanced: Override the default contact solving function for contacts, for certain types of rigidbody + ///See btRigidBody::m_contactSolverType and btRigidBody::m_frictionSolverType + void setContactSolverFunc(ContactSolverFunc func,int type0,int type1) + { + m_contactDispatch[type0][type1] = func; + } + + ///Advanced: Override the default friction solving function for contacts, for certain types of rigidbody + ///See btRigidBody::m_contactSolverType and btRigidBody::m_frictionSolverType + void SetFrictionSolverFunc(ContactSolverFunc func,int type0,int type1) + { + m_frictionDispatch[type0][type1] = func; + } + + virtual ~btSequentialImpulseConstraintSolver() {} + + virtual btScalar solveGroup(btCollisionObject** bodies,int numBodies,btPersistentManifold** manifold,int numManifolds,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& info, btIDebugDraw* debugDrawer, btStackAlloc* stackAlloc); + + virtual btScalar solveGroupCacheFriendly(btCollisionObject** bodies,int numBodies,btPersistentManifold** manifoldPtr, int numManifolds,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& infoGlobal,btIDebugDraw* debugDrawer,btStackAlloc* stackAlloc); + + btScalar solveCombinedContactFriction(btRigidBody* body0,btRigidBody* body1, btManifoldPoint& cp, const btContactSolverInfo& info,int iter,btIDebugDraw* debugDrawer); + + + void setSolverMode(int mode) + { + m_solverMode = mode; + } + + int getSolverMode() const + { + return m_solverMode; + } + + unsigned long btRand2(); + + int btRandInt2 (int n); + + void setRandSeed(unsigned long seed) + { + m_btSeed2 = seed; + } + unsigned long getRandSeed() const + { + return m_btSeed2; + } + +}; + + + + +#endif //SEQUENTIAL_IMPULSE_CONSTRAINT_SOLVER_H + diff --git a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSolve2LinearConstraint.cpp b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSolve2LinearConstraint.cpp new file mode 100644 index 00000000000..0c7dbd668bb --- /dev/null +++ b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSolve2LinearConstraint.cpp @@ -0,0 +1,255 @@ +/* +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 "btSolve2LinearConstraint.h" + +#include "BulletDynamics/Dynamics/btRigidBody.h" +#include "LinearMath/btVector3.h" +#include "btJacobianEntry.h" + + +void btSolve2LinearConstraint::resolveUnilateralPairConstraint( + btRigidBody* body1, + btRigidBody* body2, + + const btMatrix3x3& world2A, + const btMatrix3x3& world2B, + + const btVector3& invInertiaADiag, + const btScalar invMassA, + const btVector3& linvelA,const btVector3& angvelA, + const btVector3& rel_posA1, + const btVector3& invInertiaBDiag, + const btScalar invMassB, + const btVector3& linvelB,const btVector3& angvelB, + const btVector3& rel_posA2, + + btScalar depthA, const btVector3& normalA, + const btVector3& rel_posB1,const btVector3& rel_posB2, + btScalar depthB, const btVector3& normalB, + btScalar& imp0,btScalar& imp1) +{ + (void)linvelA; + (void)linvelB; + (void)angvelB; + (void)angvelA; + + + + imp0 = btScalar(0.); + imp1 = btScalar(0.); + + btScalar len = btFabs(normalA.length()) - btScalar(1.); + if (btFabs(len) >= SIMD_EPSILON) + return; + + btAssert(len < SIMD_EPSILON); + + + //this jacobian entry could be re-used for all iterations + btJacobianEntry jacA(world2A,world2B,rel_posA1,rel_posA2,normalA,invInertiaADiag,invMassA, + invInertiaBDiag,invMassB); + btJacobianEntry jacB(world2A,world2B,rel_posB1,rel_posB2,normalB,invInertiaADiag,invMassA, + invInertiaBDiag,invMassB); + + //const btScalar vel0 = jacA.getRelativeVelocity(linvelA,angvelA,linvelB,angvelB); + //const btScalar vel1 = jacB.getRelativeVelocity(linvelA,angvelA,linvelB,angvelB); + + const btScalar vel0 = normalA.dot(body1->getVelocityInLocalPoint(rel_posA1)-body2->getVelocityInLocalPoint(rel_posA1)); + const btScalar vel1 = normalB.dot(body1->getVelocityInLocalPoint(rel_posB1)-body2->getVelocityInLocalPoint(rel_posB1)); + +// btScalar penetrationImpulse = (depth*contactTau*timeCorrection) * massTerm;//jacDiagABInv + btScalar massTerm = btScalar(1.) / (invMassA + invMassB); + + + // calculate rhs (or error) terms + const btScalar dv0 = depthA * m_tau * massTerm - vel0 * m_damping; + const btScalar dv1 = depthB * m_tau * massTerm - vel1 * m_damping; + + + // dC/dv * dv = -C + + // jacobian * impulse = -error + // + + //impulse = jacobianInverse * -error + + // inverting 2x2 symmetric system (offdiagonal are equal!) + // + + + btScalar nonDiag = jacA.getNonDiagonal(jacB,invMassA,invMassB); + btScalar invDet = btScalar(1.0) / (jacA.getDiagonal() * jacB.getDiagonal() - nonDiag * nonDiag ); + + //imp0 = dv0 * jacA.getDiagonal() * invDet + dv1 * -nonDiag * invDet; + //imp1 = dv1 * jacB.getDiagonal() * invDet + dv0 * - nonDiag * invDet; + + imp0 = dv0 * jacA.getDiagonal() * invDet + dv1 * -nonDiag * invDet; + imp1 = dv1 * jacB.getDiagonal() * invDet + dv0 * - nonDiag * invDet; + + //[a b] [d -c] + //[c d] inverse = (1 / determinant) * [-b a] where determinant is (ad - bc) + + //[jA nD] * [imp0] = [dv0] + //[nD jB] [imp1] [dv1] + +} + + + +void btSolve2LinearConstraint::resolveBilateralPairConstraint( + btRigidBody* body1, + btRigidBody* body2, + const btMatrix3x3& world2A, + const btMatrix3x3& world2B, + + const btVector3& invInertiaADiag, + const btScalar invMassA, + const btVector3& linvelA,const btVector3& angvelA, + const btVector3& rel_posA1, + const btVector3& invInertiaBDiag, + const btScalar invMassB, + const btVector3& linvelB,const btVector3& angvelB, + const btVector3& rel_posA2, + + btScalar depthA, const btVector3& normalA, + const btVector3& rel_posB1,const btVector3& rel_posB2, + btScalar depthB, const btVector3& normalB, + btScalar& imp0,btScalar& imp1) +{ + + (void)linvelA; + (void)linvelB; + (void)angvelA; + (void)angvelB; + + + + imp0 = btScalar(0.); + imp1 = btScalar(0.); + + btScalar len = btFabs(normalA.length()) - btScalar(1.); + if (btFabs(len) >= SIMD_EPSILON) + return; + + btAssert(len < SIMD_EPSILON); + + + //this jacobian entry could be re-used for all iterations + btJacobianEntry jacA(world2A,world2B,rel_posA1,rel_posA2,normalA,invInertiaADiag,invMassA, + invInertiaBDiag,invMassB); + btJacobianEntry jacB(world2A,world2B,rel_posB1,rel_posB2,normalB,invInertiaADiag,invMassA, + invInertiaBDiag,invMassB); + + //const btScalar vel0 = jacA.getRelativeVelocity(linvelA,angvelA,linvelB,angvelB); + //const btScalar vel1 = jacB.getRelativeVelocity(linvelA,angvelA,linvelB,angvelB); + + const btScalar vel0 = normalA.dot(body1->getVelocityInLocalPoint(rel_posA1)-body2->getVelocityInLocalPoint(rel_posA1)); + const btScalar vel1 = normalB.dot(body1->getVelocityInLocalPoint(rel_posB1)-body2->getVelocityInLocalPoint(rel_posB1)); + + // calculate rhs (or error) terms + const btScalar dv0 = depthA * m_tau - vel0 * m_damping; + const btScalar dv1 = depthB * m_tau - vel1 * m_damping; + + // dC/dv * dv = -C + + // jacobian * impulse = -error + // + + //impulse = jacobianInverse * -error + + // inverting 2x2 symmetric system (offdiagonal are equal!) + // + + + btScalar nonDiag = jacA.getNonDiagonal(jacB,invMassA,invMassB); + btScalar invDet = btScalar(1.0) / (jacA.getDiagonal() * jacB.getDiagonal() - nonDiag * nonDiag ); + + //imp0 = dv0 * jacA.getDiagonal() * invDet + dv1 * -nonDiag * invDet; + //imp1 = dv1 * jacB.getDiagonal() * invDet + dv0 * - nonDiag * invDet; + + imp0 = dv0 * jacA.getDiagonal() * invDet + dv1 * -nonDiag * invDet; + imp1 = dv1 * jacB.getDiagonal() * invDet + dv0 * - nonDiag * invDet; + + //[a b] [d -c] + //[c d] inverse = (1 / determinant) * [-b a] where determinant is (ad - bc) + + //[jA nD] * [imp0] = [dv0] + //[nD jB] [imp1] [dv1] + + if ( imp0 > btScalar(0.0)) + { + if ( imp1 > btScalar(0.0) ) + { + //both positive + } + else + { + imp1 = btScalar(0.); + + // now imp0>0 imp1<0 + imp0 = dv0 / jacA.getDiagonal(); + if ( imp0 > btScalar(0.0) ) + { + } else + { + imp0 = btScalar(0.); + } + } + } + else + { + imp0 = btScalar(0.); + + imp1 = dv1 / jacB.getDiagonal(); + if ( imp1 <= btScalar(0.0) ) + { + imp1 = btScalar(0.); + // now imp0>0 imp1<0 + imp0 = dv0 / jacA.getDiagonal(); + if ( imp0 > btScalar(0.0) ) + { + } else + { + imp0 = btScalar(0.); + } + } else + { + } + } +} + + +/* +void btSolve2LinearConstraint::resolveAngularConstraint( const btMatrix3x3& invInertiaAWS, + const btScalar invMassA, + const btVector3& linvelA,const btVector3& angvelA, + const btVector3& rel_posA1, + const btMatrix3x3& invInertiaBWS, + const btScalar invMassB, + const btVector3& linvelB,const btVector3& angvelB, + const btVector3& rel_posA2, + + btScalar depthA, const btVector3& normalA, + const btVector3& rel_posB1,const btVector3& rel_posB2, + btScalar depthB, const btVector3& normalB, + btScalar& imp0,btScalar& imp1) +{ + +} +*/ + diff --git a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSolve2LinearConstraint.h b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSolve2LinearConstraint.h new file mode 100644 index 00000000000..e7d26645c6a --- /dev/null +++ b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSolve2LinearConstraint.h @@ -0,0 +1,107 @@ +/* +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 SOLVE_2LINEAR_CONSTRAINT_H +#define SOLVE_2LINEAR_CONSTRAINT_H + +#include "../../LinearMath/btMatrix3x3.h" +#include "../../LinearMath/btVector3.h" + + +class btRigidBody; + + + +/// constraint class used for lateral tyre friction. +class btSolve2LinearConstraint +{ + btScalar m_tau; + btScalar m_damping; + +public: + + btSolve2LinearConstraint(btScalar tau,btScalar damping) + { + m_tau = tau; + m_damping = damping; + } + // + // solve unilateral constraint (equality, direct method) + // + void resolveUnilateralPairConstraint( + btRigidBody* body0, + btRigidBody* body1, + + const btMatrix3x3& world2A, + const btMatrix3x3& world2B, + + const btVector3& invInertiaADiag, + const btScalar invMassA, + const btVector3& linvelA,const btVector3& angvelA, + const btVector3& rel_posA1, + const btVector3& invInertiaBDiag, + const btScalar invMassB, + const btVector3& linvelB,const btVector3& angvelB, + const btVector3& rel_posA2, + + btScalar depthA, const btVector3& normalA, + const btVector3& rel_posB1,const btVector3& rel_posB2, + btScalar depthB, const btVector3& normalB, + btScalar& imp0,btScalar& imp1); + + + // + // solving 2x2 lcp problem (inequality, direct solution ) + // + void resolveBilateralPairConstraint( + btRigidBody* body0, + btRigidBody* body1, + const btMatrix3x3& world2A, + const btMatrix3x3& world2B, + + const btVector3& invInertiaADiag, + const btScalar invMassA, + const btVector3& linvelA,const btVector3& angvelA, + const btVector3& rel_posA1, + const btVector3& invInertiaBDiag, + const btScalar invMassB, + const btVector3& linvelB,const btVector3& angvelB, + const btVector3& rel_posA2, + + btScalar depthA, const btVector3& normalA, + const btVector3& rel_posB1,const btVector3& rel_posB2, + btScalar depthB, const btVector3& normalB, + btScalar& imp0,btScalar& imp1); + +/* + void resolveAngularConstraint( const btMatrix3x3& invInertiaAWS, + const btScalar invMassA, + const btVector3& linvelA,const btVector3& angvelA, + const btVector3& rel_posA1, + const btMatrix3x3& invInertiaBWS, + const btScalar invMassB, + const btVector3& linvelB,const btVector3& angvelB, + const btVector3& rel_posA2, + + btScalar depthA, const btVector3& normalA, + const btVector3& rel_posB1,const btVector3& rel_posB2, + btScalar depthB, const btVector3& normalB, + btScalar& imp0,btScalar& imp1); + +*/ + +}; + +#endif //SOLVE_2LINEAR_CONSTRAINT_H diff --git a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSolverBody.h b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSolverBody.h new file mode 100644 index 00000000000..0ab536f42b3 --- /dev/null +++ b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSolverBody.h @@ -0,0 +1,71 @@ +/* +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 BT_SOLVER_BODY_H +#define BT_SOLVER_BODY_H + +class btRigidBody; +#include "LinearMath/btVector3.h" +#include "LinearMath/btMatrix3x3.h" + + + + +ATTRIBUTE_ALIGNED16 (struct) btSolverBody +{ + btVector3 m_centerOfMassPosition; + btVector3 m_linearVelocity; + btVector3 m_angularVelocity; + btRigidBody* m_originalBody; + float m_invMass; + float m_friction; + float m_angularFactor; + + inline void getVelocityInLocalPoint(const btVector3& rel_pos, btVector3& velocity ) const + { + velocity = m_linearVelocity + m_angularVelocity.cross(rel_pos); + } + + //Optimization for the iterative solver: avoid calculating constant terms involving inertia, normal, relative position + inline void internalApplyImpulse(const btVector3& linearComponent, const btVector3& angularComponent,btScalar impulseMagnitude) + { + m_linearVelocity += linearComponent*impulseMagnitude; + m_angularVelocity += angularComponent*impulseMagnitude*m_angularFactor; + } + + void writebackVelocity() + { + if (m_invMass) + { + m_originalBody->setLinearVelocity(m_linearVelocity); + m_originalBody->setAngularVelocity(m_angularVelocity); + } + } + + void readVelocity() + { + if (m_invMass) + { + m_linearVelocity = m_originalBody->getLinearVelocity(); + m_angularVelocity = m_originalBody->getAngularVelocity(); + } + } + + + + +}; + +#endif //BT_SOLVER_BODY_H diff --git a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSolverConstraint.h b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSolverConstraint.h new file mode 100644 index 00000000000..f1f40ffdf19 --- /dev/null +++ b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSolverConstraint.h @@ -0,0 +1,63 @@ + + +/* +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 BT_SOLVER_CONSTRAINT_H +#define BT_SOLVER_CONSTRAINT_H + +class btRigidBody; +#include "LinearMath/btVector3.h" +#include "LinearMath/btMatrix3x3.h" + +//#define NO_FRICTION_TANGENTIALS 1 + +///1D constraint along a normal axis between bodyA and bodyB. It can be combined to solve contact and friction constraints. +ATTRIBUTE_ALIGNED16 (struct) btSolverConstraint +{ + btVector3 m_relpos1CrossNormal; + btVector3 m_relpos2CrossNormal; + btVector3 m_contactNormal; + btVector3 m_angularComponentA; + btVector3 m_angularComponentB; + + btScalar m_appliedVelocityImpulse; + int m_solverBodyIdA; + int m_solverBodyIdB; + btScalar m_friction; + btScalar m_restitution; + btScalar m_jacDiagABInv; + btScalar m_penetration; + btScalar m_appliedImpulse; + + int m_constraintType; + int m_frictionIndex; + int m_unusedPadding[2]; + + enum btSolverConstraintType + { + BT_SOLVER_CONTACT_1D = 0, + BT_SOLVER_FRICTION_1D + }; +}; + + + + + + +#endif //BT_SOLVER_CONSTRAINT_H + + diff --git a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btTypedConstraint.cpp b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btTypedConstraint.cpp new file mode 100644 index 00000000000..a15b3e026cd --- /dev/null +++ b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btTypedConstraint.cpp @@ -0,0 +1,53 @@ +/* +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 "btTypedConstraint.h" +#include "BulletDynamics/Dynamics/btRigidBody.h" + +static btRigidBody s_fixed(0, 0,0); + +btTypedConstraint::btTypedConstraint() +: m_userConstraintType(-1), +m_userConstraintId(-1), +m_rbA(s_fixed), +m_rbB(s_fixed), +m_appliedImpulse(btScalar(0.)) +{ + s_fixed.setMassProps(btScalar(0.),btVector3(btScalar(0.),btScalar(0.),btScalar(0.))); +} +btTypedConstraint::btTypedConstraint(btRigidBody& rbA) +: m_userConstraintType(-1), +m_userConstraintId(-1), +m_rbA(rbA), +m_rbB(s_fixed), +m_appliedImpulse(btScalar(0.)) +{ + s_fixed.setMassProps(btScalar(0.),btVector3(btScalar(0.),btScalar(0.),btScalar(0.))); + +} + + +btTypedConstraint::btTypedConstraint(btRigidBody& rbA,btRigidBody& rbB) +: m_userConstraintType(-1), +m_userConstraintId(-1), +m_rbA(rbA), +m_rbB(rbB), +m_appliedImpulse(btScalar(0.)) +{ + s_fixed.setMassProps(btScalar(0.),btVector3(btScalar(0.),btScalar(0.),btScalar(0.))); + +} + diff --git a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btTypedConstraint.h b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btTypedConstraint.h new file mode 100644 index 00000000000..dfee6e80d0e --- /dev/null +++ b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btTypedConstraint.h @@ -0,0 +1,96 @@ +/* +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 TYPED_CONSTRAINT_H +#define TYPED_CONSTRAINT_H + +class btRigidBody; +#include "../../LinearMath/btScalar.h" + +///TypedConstraint is the baseclass for Bullet constraints and vehicles +class btTypedConstraint +{ + int m_userConstraintType; + int m_userConstraintId; + + btTypedConstraint& operator=(btTypedConstraint& other) + { + btAssert(0); + (void) other; + return *this; + } + +protected: + btRigidBody& m_rbA; + btRigidBody& m_rbB; + btScalar m_appliedImpulse; + + +public: + + btTypedConstraint(); + virtual ~btTypedConstraint() {}; + btTypedConstraint(btRigidBody& rbA); + + btTypedConstraint(btRigidBody& rbA,btRigidBody& rbB); + + virtual void buildJacobian() = 0; + + virtual void solveConstraint(btScalar timeStep) = 0; + + const btRigidBody& getRigidBodyA() const + { + return m_rbA; + } + const btRigidBody& getRigidBodyB() const + { + return m_rbB; + } + + btRigidBody& getRigidBodyA() + { + return m_rbA; + } + btRigidBody& getRigidBodyB() + { + return m_rbB; + } + + int getUserConstraintType() const + { + return m_userConstraintType ; + } + + void setUserConstraintType(int userConstraintType) + { + m_userConstraintType = userConstraintType; + }; + + void setUserConstraintId(int uid) + { + m_userConstraintId = uid; + } + + int getUserConstraintId() + { + return m_userConstraintId; + } + btScalar getAppliedImpulse() + { + return m_appliedImpulse; + } +}; + +#endif //TYPED_CONSTRAINT_H diff --git a/extern/bullet2/src/BulletDynamics/Dynamics/Bullet-C-API.cpp b/extern/bullet2/src/BulletDynamics/Dynamics/Bullet-C-API.cpp new file mode 100644 index 00000000000..248c582dcd8 --- /dev/null +++ b/extern/bullet2/src/BulletDynamics/Dynamics/Bullet-C-API.cpp @@ -0,0 +1,120 @@ +/* +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. +*/ + +/* + Draft high-level generic physics C-API. For low-level access, use the physics SDK native API's. + Work in progress, functionality will be added on demand. + + If possible, use the richer Bullet C++ API, by including +*/ + +#include "Bullet-C-Api.h" +#include "btBulletDynamicsCommon.h" +#include "LinearMath/btAlignedAllocator.h" + + +#include "LinearMath/btVector3.h" +#include "LinearMath/btScalar.h" +#include "LinearMath/btMatrix3x3.h" +#include "LinearMath/btTransform.h" +#include "BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.h" +#include "BulletCollision/CollisionShapes/btTriangleShape.h" + +#include "BulletCollision/NarrowPhaseCollision/btGjkPairDetector.h" +#include "BulletCollision/NarrowPhaseCollision/btPointCollector.h" +#include "BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.h" +#include "BulletCollision/NarrowPhaseCollision/btSubSimplexConvexCast.h" +#include "BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.h" +#include "BulletCollision/NarrowPhaseCollision/btGjkEpa.h" +#include "BulletCollision/CollisionShapes/btMinkowskiSumShape.h" +#include "BulletCollision/NarrowPhaseCollision/btSubSimplexConvexCast.h" +#include "BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.h" +#include "BulletCollision/NarrowPhaseCollision/btGjkPairDetector.h" + +#include "BulletCollision/NarrowPhaseCollision/btDiscreteCollisionDetectorInterface.h" +#include "BulletCollision/NarrowPhaseCollision/btSimplexSolverInterface.h" +#include "BulletCollision/NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.h" +#include "BulletCollision/NarrowPhaseCollision/btGjkPairDetector.h" +#include "BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.h" +#include "LinearMath/btStackAlloc.h" + +extern "C" +double plNearestPoints(float p1[3], float p2[3], float p3[3], float q1[3], float q2[3], float q3[3], float *pa, float *pb, float normal[3]) +{ + btVector3 vp(p1[0], p1[1], p1[2]); + btTriangleShape trishapeA(vp, + btVector3(p2[0], p2[1], p2[2]), + btVector3(p3[0], p3[1], p3[2])); + trishapeA.setMargin(0.000001f); + btVector3 vq(q1[0], q1[1], q1[2]); + btTriangleShape trishapeB(vq, + btVector3(q2[0], q2[1], q2[2]), + btVector3(q3[0], q3[1], q3[2])); + trishapeB.setMargin(0.000001f); + + // btVoronoiSimplexSolver sGjkSimplexSolver; + // btGjkEpaPenetrationDepthSolver penSolverPtr; + + static btSimplexSolverInterface sGjkSimplexSolver; + sGjkSimplexSolver.reset(); + + static btGjkEpaPenetrationDepthSolver Solver0; + static btMinkowskiPenetrationDepthSolver Solver1; + + btConvexPenetrationDepthSolver* Solver = NULL; + + Solver = &Solver1; + + btGjkPairDetector convexConvex(&trishapeA ,&trishapeB,&sGjkSimplexSolver,Solver); + + convexConvex.m_catchDegeneracies = 1; + + // btGjkPairDetector convexConvex(&trishapeA ,&trishapeB,&sGjkSimplexSolver,0); + + btPointCollector gjkOutput; + btGjkPairDetector::ClosestPointInput input; + + btStackAlloc gStackAlloc(1024*1024*2); + + input.m_stackAlloc = &gStackAlloc; + + btTransform tr; + tr.setIdentity(); + + input.m_transformA = tr; + input.m_transformB = tr; + + convexConvex.getClosestPoints(input, gjkOutput, 0); + + + if (gjkOutput.m_hasResult) + { + + pb[0] = pa[0] = gjkOutput.m_pointInWorld[0]; + pb[1] = pa[1] = gjkOutput.m_pointInWorld[1]; + pb[2] = pa[2] = gjkOutput.m_pointInWorld[2]; + + pb[0]+= gjkOutput.m_normalOnBInWorld[0] * gjkOutput.m_distance; + pb[1]+= gjkOutput.m_normalOnBInWorld[1] * gjkOutput.m_distance; + pb[2]+= gjkOutput.m_normalOnBInWorld[2] * gjkOutput.m_distance; + + normal[0] = gjkOutput.m_normalOnBInWorld[0]; + normal[1] = gjkOutput.m_normalOnBInWorld[1]; + normal[2] = gjkOutput.m_normalOnBInWorld[2]; + + return gjkOutput.m_distance; + } + return -1.0f; +} diff --git a/extern/bullet2/src/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.cpp b/extern/bullet2/src/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.cpp new file mode 100644 index 00000000000..29719ec9a3e --- /dev/null +++ b/extern/bullet2/src/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.cpp @@ -0,0 +1,954 @@ +/* +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 "btDiscreteDynamicsWorld.h" + +//collision detection +#include "BulletCollision/CollisionDispatch/btCollisionDispatcher.h" +#include "BulletCollision/BroadphaseCollision/btSimpleBroadphase.h" +#include "BulletCollision/CollisionShapes/btCollisionShape.h" +#include "BulletCollision/CollisionDispatch/btSimulationIslandManager.h" +#include + +//rigidbody & constraints +#include "BulletDynamics/Dynamics/btRigidBody.h" +#include "BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.h" +#include "BulletDynamics/ConstraintSolver/btContactSolverInfo.h" +#include "BulletDynamics/ConstraintSolver/btTypedConstraint.h" + +//for debug rendering +#include "BulletCollision/CollisionShapes/btBoxShape.h" +#include "BulletCollision/CollisionShapes/btCapsuleShape.h" +#include "BulletCollision/CollisionShapes/btCompoundShape.h" +#include "BulletCollision/CollisionShapes/btConeShape.h" +#include "BulletCollision/CollisionShapes/btConvexTriangleMeshShape.h" +#include "BulletCollision/CollisionShapes/btCylinderShape.h" +#include "BulletCollision/CollisionShapes/btMultiSphereShape.h" +#include "BulletCollision/CollisionShapes/btPolyhedralConvexShape.h" +#include "BulletCollision/CollisionShapes/btSphereShape.h" +#include "BulletCollision/CollisionShapes/btTriangleCallback.h" +#include "BulletCollision/CollisionShapes/btTriangleMeshShape.h" +#include "LinearMath/btIDebugDraw.h" + + + +//vehicle +#include "BulletDynamics/Vehicle/btRaycastVehicle.h" +#include "BulletDynamics/Vehicle/btVehicleRaycaster.h" +#include "BulletDynamics/Vehicle/btWheelInfo.h" +#include "LinearMath/btIDebugDraw.h" +#include "LinearMath/btQuickprof.h" +#include "LinearMath/btMotionState.h" + + + + + +btDiscreteDynamicsWorld::btDiscreteDynamicsWorld(btDispatcher* dispatcher,btOverlappingPairCache* pairCache,btConstraintSolver* constraintSolver) +:btDynamicsWorld(dispatcher,pairCache), +m_constraintSolver(constraintSolver? constraintSolver: new btSequentialImpulseConstraintSolver), +m_debugDrawer(0), +m_gravity(0,-10,0), +m_localTime(btScalar(1.)/btScalar(60.)), +m_profileTimings(0) +{ + m_islandManager = new btSimulationIslandManager(); + m_ownsIslandManager = true; + m_ownsConstraintSolver = (constraintSolver==0); +} + + +btDiscreteDynamicsWorld::~btDiscreteDynamicsWorld() +{ + //only delete it when we created it + if (m_ownsIslandManager) + delete m_islandManager; + if (m_ownsConstraintSolver) + delete m_constraintSolver; +} + +void btDiscreteDynamicsWorld::saveKinematicState(btScalar timeStep) +{ + + for (int i=0;igetActivationState() != ISLAND_SLEEPING) + { + if (body->isKinematicObject()) + { + //to calculate velocities next frame + body->saveKinematicState(timeStep); + } + } + } + } +} + +void btDiscreteDynamicsWorld::synchronizeMotionStates() +{ + //debug vehicle wheels + + + { + //todo: iterate over awake simulation islands! + for ( int i=0;igetDebugMode() & btIDebugDraw::DBG_DrawWireframe) + { + btVector3 color(btScalar(255.),btScalar(255.),btScalar(255.)); + switch(colObj->getActivationState()) + { + case ACTIVE_TAG: + color = btVector3(btScalar(255.),btScalar(255.),btScalar(255.)); break; + case ISLAND_SLEEPING: + color = btVector3(btScalar(0.),btScalar(255.),btScalar(0.));break; + case WANTS_DEACTIVATION: + color = btVector3(btScalar(0.),btScalar(255.),btScalar(255.));break; + case DISABLE_DEACTIVATION: + color = btVector3(btScalar(255.),btScalar(0.),btScalar(0.));break; + case DISABLE_SIMULATION: + color = btVector3(btScalar(255.),btScalar(255.),btScalar(0.));break; + default: + { + color = btVector3(btScalar(255.),btScalar(0.),btScalar(0.)); + } + }; + + debugDrawObject(colObj->getWorldTransform(),colObj->getCollisionShape(),color); + } + btRigidBody* body = btRigidBody::upcast(colObj); + if (body && body->getMotionState() && !body->isStaticOrKinematicObject()) + { + //we need to call the update at least once, even for sleeping objects + //otherwise the 'graphics' transform never updates properly + //so todo: add 'dirty' flag + //if (body->getActivationState() != ISLAND_SLEEPING) + { + btTransform interpolatedTransform; + btTransformUtil::integrateTransform(body->getInterpolationWorldTransform(), + body->getInterpolationLinearVelocity(),body->getInterpolationAngularVelocity(),m_localTime,interpolatedTransform); + body->getMotionState()->setWorldTransform(interpolatedTransform); + } + } + } + } + + if (getDebugDrawer() && getDebugDrawer()->getDebugMode() & btIDebugDraw::DBG_DrawWireframe) + { + for ( int i=0;im_vehicles.size();i++) + { + for (int v=0;vgetNumWheels();v++) + { + btVector3 wheelColor(0,255,255); + if (m_vehicles[i]->getWheelInfo(v).m_raycastInfo.m_isInContact) + { + wheelColor.setValue(0,0,255); + } else + { + wheelColor.setValue(255,0,255); + } + + //synchronize the wheels with the (interpolated) chassis worldtransform + m_vehicles[i]->updateWheelTransform(v,true); + + btVector3 wheelPosWS = m_vehicles[i]->getWheelInfo(v).m_worldTransform.getOrigin(); + + btVector3 axle = btVector3( + m_vehicles[i]->getWheelInfo(v).m_worldTransform.getBasis()[0][m_vehicles[i]->getRightAxis()], + m_vehicles[i]->getWheelInfo(v).m_worldTransform.getBasis()[1][m_vehicles[i]->getRightAxis()], + m_vehicles[i]->getWheelInfo(v).m_worldTransform.getBasis()[2][m_vehicles[i]->getRightAxis()]); + + + //m_vehicles[i]->getWheelInfo(v).m_raycastInfo.m_wheelAxleWS + //debug wheels (cylinders) + m_debugDrawer->drawLine(wheelPosWS,wheelPosWS+axle,wheelColor); + m_debugDrawer->drawLine(wheelPosWS,m_vehicles[i]->getWheelInfo(v).m_raycastInfo.m_contactPointWS,wheelColor); + + } + } + } + +} + + +int btDiscreteDynamicsWorld::stepSimulation( btScalar timeStep,int maxSubSteps, btScalar fixedTimeStep) +{ + int numSimulationSubSteps = 0; + + if (maxSubSteps) + { + //fixed timestep with interpolation + m_localTime += timeStep; + if (m_localTime >= fixedTimeStep) + { + numSimulationSubSteps = int( m_localTime / fixedTimeStep); + m_localTime -= numSimulationSubSteps * fixedTimeStep; + } + } else + { + //variable timestep + fixedTimeStep = timeStep; + m_localTime = timeStep; + if (btFuzzyZero(timeStep)) + { + numSimulationSubSteps = 0; + maxSubSteps = 0; + } else + { + numSimulationSubSteps = 1; + maxSubSteps = 1; + } + } + + //process some debugging flags + if (getDebugDrawer()) + { + gDisableDeactivation = (getDebugDrawer()->getDebugMode() & btIDebugDraw::DBG_NoDeactivation) != 0; + } + if (numSimulationSubSteps) + { + + saveKinematicState(fixedTimeStep); + + //clamp the number of substeps, to prevent simulation grinding spiralling down to a halt + int clampedSimulationSteps = (numSimulationSubSteps > maxSubSteps)? maxSubSteps : numSimulationSubSteps; + + for (int i=0;isetGravity(gravity); + } + } +} + + +void btDiscreteDynamicsWorld::removeRigidBody(btRigidBody* body) +{ + removeCollisionObject(body); +} + +void btDiscreteDynamicsWorld::addRigidBody(btRigidBody* body) +{ + if (!body->isStaticOrKinematicObject()) + { + body->setGravity(m_gravity); + } + + if (body->getCollisionShape()) + { + bool isDynamic = !(body->isStaticObject() || body->isKinematicObject()); + short collisionFilterGroup = isDynamic? short(btBroadphaseProxy::DefaultFilter) : short(btBroadphaseProxy::StaticFilter); + short collisionFilterMask = isDynamic? short(btBroadphaseProxy::AllFilter) : short(btBroadphaseProxy::AllFilter ^ btBroadphaseProxy::StaticFilter); + + addCollisionObject(body,collisionFilterGroup,collisionFilterMask); + } +} + +void btDiscreteDynamicsWorld::addRigidBody(btRigidBody* body, short group, short mask) +{ + if (!body->isStaticOrKinematicObject()) + { + body->setGravity(m_gravity); + } + + if (body->getCollisionShape()) + { + addCollisionObject(body,group,mask); + } +} + + +void btDiscreteDynamicsWorld::updateVehicles(btScalar timeStep) +{ + BEGIN_PROFILE("updateVehicles"); + + for ( int i=0;iupdateVehicle( timeStep); + } + END_PROFILE("updateVehicles"); +} + +void btDiscreteDynamicsWorld::updateActivationState(btScalar timeStep) +{ + BEGIN_PROFILE("updateActivationState"); + + for ( int i=0;iupdateDeactivation(timeStep); + + if (body->wantsSleeping()) + { + if (body->isStaticOrKinematicObject()) + { + body->setActivationState(ISLAND_SLEEPING); + } else + { + if (body->getActivationState() == ACTIVE_TAG) + body->setActivationState( WANTS_DEACTIVATION ); + } + } else + { + if (body->getActivationState() != DISABLE_DEACTIVATION) + body->setActivationState( ACTIVE_TAG ); + } + } + } + END_PROFILE("updateActivationState"); +} + +void btDiscreteDynamicsWorld::addConstraint(btTypedConstraint* constraint,bool disableCollisionsBetweenLinkedBodies) +{ + m_constraints.push_back(constraint); + if (disableCollisionsBetweenLinkedBodies) + { + constraint->getRigidBodyA().addConstraintRef(constraint); + constraint->getRigidBodyB().addConstraintRef(constraint); + } +} + +void btDiscreteDynamicsWorld::removeConstraint(btTypedConstraint* constraint) +{ + m_constraints.remove(constraint); + constraint->getRigidBodyA().removeConstraintRef(constraint); + constraint->getRigidBodyB().removeConstraintRef(constraint); +} + +void btDiscreteDynamicsWorld::addVehicle(btRaycastVehicle* vehicle) +{ + m_vehicles.push_back(vehicle); +} + +void btDiscreteDynamicsWorld::removeVehicle(btRaycastVehicle* vehicle) +{ + m_vehicles.remove(vehicle); +} + +inline int btGetConstraintIslandId(const btTypedConstraint* lhs) +{ + int islandId; + + const btCollisionObject& rcolObj0 = lhs->getRigidBodyA(); + const btCollisionObject& rcolObj1 = lhs->getRigidBodyB(); + islandId= rcolObj0.getIslandTag()>=0?rcolObj0.getIslandTag():rcolObj1.getIslandTag(); + return islandId; + +} + + +class btSortConstraintOnIslandPredicate +{ + public: + + bool operator() ( const btTypedConstraint* lhs, const btTypedConstraint* rhs ) + { + int rIslandId0,lIslandId0; + rIslandId0 = btGetConstraintIslandId(rhs); + lIslandId0 = btGetConstraintIslandId(lhs); + return lIslandId0 < rIslandId0; + } +}; + + + + +void btDiscreteDynamicsWorld::solveConstraints(btContactSolverInfo& solverInfo) +{ + + struct InplaceSolverIslandCallback : public btSimulationIslandManager::IslandCallback + { + + btContactSolverInfo& m_solverInfo; + btConstraintSolver* m_solver; + btTypedConstraint** m_sortedConstraints; + int m_numConstraints; + btIDebugDraw* m_debugDrawer; + btStackAlloc* m_stackAlloc; + + + InplaceSolverIslandCallback( + btContactSolverInfo& solverInfo, + btConstraintSolver* solver, + btTypedConstraint** sortedConstraints, + int numConstraints, + btIDebugDraw* debugDrawer, + btStackAlloc* stackAlloc) + :m_solverInfo(solverInfo), + m_solver(solver), + m_sortedConstraints(sortedConstraints), + m_numConstraints(numConstraints), + m_debugDrawer(debugDrawer), + m_stackAlloc(stackAlloc) + { + + } + + InplaceSolverIslandCallback& operator=(InplaceSolverIslandCallback& other) + { + btAssert(0); + (void)other; + return *this; + } + virtual void ProcessIsland(btCollisionObject** bodies,int numBodies,btPersistentManifold** manifolds,int numManifolds, int islandId) + { + //also add all non-contact constraints/joints for this island + btTypedConstraint** startConstraint = 0; + int numCurConstraints = 0; + int i; + + //find the first constraint for this island + for (i=0;isolveGroup( bodies,numBodies,manifolds, numManifolds,startConstraint,numCurConstraints,m_solverInfo,m_debugDrawer,m_stackAlloc); + } + + }; + + //sorted version of all btTypedConstraint, based on islandId + btAlignedObjectArray sortedConstraints; + sortedConstraints.resize( m_constraints.size()); + int i; + for (i=0;ibuildAndProcessIslands(getCollisionWorld()->getDispatcher(),getCollisionWorld()->getCollisionObjectArray(),&solverCallback); + + +} + + + + +void btDiscreteDynamicsWorld::calculateSimulationIslands() +{ + BEGIN_PROFILE("calculateSimulationIslands"); + + getSimulationIslandManager()->updateActivationState(getCollisionWorld(),getCollisionWorld()->getDispatcher()); + + { + int i; + int numConstraints = int(m_constraints.size()); + for (i=0;i< numConstraints ; i++ ) + { + btTypedConstraint* constraint = m_constraints[i]; + + const btRigidBody* colObj0 = &constraint->getRigidBodyA(); + const btRigidBody* colObj1 = &constraint->getRigidBodyB(); + + if (((colObj0) && ((colObj0)->mergesSimulationIslands())) && + ((colObj1) && ((colObj1)->mergesSimulationIslands()))) + { + if (colObj0->isActive() || colObj1->isActive()) + { + + getSimulationIslandManager()->getUnionFind().unite((colObj0)->getIslandTag(), + (colObj1)->getIslandTag()); + } + } + } + } + + //Store the island id in each body + getSimulationIslandManager()->storeIslandActivationState(getCollisionWorld()); + + END_PROFILE("calculateSimulationIslands"); + +} + + +void btDiscreteDynamicsWorld::updateAabbs() +{ + BEGIN_PROFILE("updateAabbs"); + + btVector3 colorvec(1,0,0); + btTransform predictedTrans; + for ( int i=0;iIsActive() && (!body->IsStatic())) + { + btPoint3 minAabb,maxAabb; + colObj->getCollisionShape()->getAabb(colObj->getWorldTransform(), minAabb,maxAabb); + btBroadphaseInterface* bp = (btBroadphaseInterface*)m_broadphasePairCache; + + //moving objects should be moderately sized, probably something wrong if not + if ( colObj->isStaticObject() || ((maxAabb-minAabb).length2() < btScalar(1e12))) + { + bp->setAabb(body->getBroadphaseHandle(),minAabb,maxAabb); + } else + { + //something went wrong, investigate + //this assert is unwanted in 3D modelers (danger of loosing work) + body->setActivationState(DISABLE_SIMULATION); + + static bool reportMe = true; + if (reportMe && m_debugDrawer) + { + reportMe = false; + m_debugDrawer->reportErrorWarning("Overflow in AABB, object removed from simulation"); + m_debugDrawer->reportErrorWarning("If you can reproduce this, please email bugs@continuousphysics.com\n"); + m_debugDrawer->reportErrorWarning("Please include above information, your Platform, version of OS.\n"); + m_debugDrawer->reportErrorWarning("Thanks.\n"); + } + + + } + if (m_debugDrawer && (m_debugDrawer->getDebugMode() & btIDebugDraw::DBG_DrawAabb)) + { + m_debugDrawer->drawAabb(minAabb,maxAabb,colorvec); + } + } + } + } + + END_PROFILE("updateAabbs"); +} + +void btDiscreteDynamicsWorld::integrateTransforms(btScalar timeStep) +{ + BEGIN_PROFILE("integrateTransforms"); + btTransform predictedTrans; + for ( int i=0;iisActive() && (!body->isStaticOrKinematicObject())) + { + body->predictIntegratedTransform(timeStep, predictedTrans); + body->proceedToTransform( predictedTrans); + } + } + } + END_PROFILE("integrateTransforms"); +} + + + +void btDiscreteDynamicsWorld::predictUnconstraintMotion(btScalar timeStep) +{ + BEGIN_PROFILE("predictUnconstraintMotion"); + for ( int i=0;iisStaticOrKinematicObject()) + { + if (body->isActive()) + { + body->applyForces( timeStep); + body->integrateVelocities( timeStep); + body->predictIntegratedTransform(timeStep,body->getInterpolationWorldTransform()); + } + } + } + } + END_PROFILE("predictUnconstraintMotion"); +} + + +void btDiscreteDynamicsWorld::startProfiling(btScalar timeStep) +{ + (void)timeStep; + #ifdef USE_QUICKPROF + + + //toggle btProfiler + if ( m_debugDrawer && m_debugDrawer->getDebugMode() & btIDebugDraw::DBG_ProfileTimings) + { + if (!m_profileTimings) + { + m_profileTimings = 1; + // To disable profiling, simply comment out the following line. + static int counter = 0; + + char filename[128]; + sprintf(filename,"quickprof_bullet_timings%i.csv",counter++); + btProfiler::init(filename, btProfiler::BLOCK_CYCLE_SECONDS);//BLOCK_TOTAL_MICROSECONDS + } else + { + btProfiler::endProfilingCycle(); + } + + } else + { + if (m_profileTimings) + { + btProfiler::endProfilingCycle(); + + m_profileTimings = 0; + btProfiler::destroy(); + } + } +#endif //USE_QUICKPROF +} + + + + + + +class DebugDrawcallback : public btTriangleCallback, public btInternalTriangleIndexCallback +{ + btIDebugDraw* m_debugDrawer; + btVector3 m_color; + btTransform m_worldTrans; + +public: + + DebugDrawcallback(btIDebugDraw* debugDrawer,const btTransform& worldTrans,const btVector3& color) : + m_debugDrawer(debugDrawer), + m_color(color), + m_worldTrans(worldTrans) + { + } + + virtual void internalProcessTriangleIndex(btVector3* triangle,int partId,int triangleIndex) + { + processTriangle(triangle,partId,triangleIndex); + } + + virtual void processTriangle(btVector3* triangle,int partId, int triangleIndex) + { + (void)partId; + (void)triangleIndex; + + btVector3 wv0,wv1,wv2; + wv0 = m_worldTrans*triangle[0]; + wv1 = m_worldTrans*triangle[1]; + wv2 = m_worldTrans*triangle[2]; + m_debugDrawer->drawLine(wv0,wv1,m_color); + m_debugDrawer->drawLine(wv1,wv2,m_color); + m_debugDrawer->drawLine(wv2,wv0,m_color); + } +}; + +void btDiscreteDynamicsWorld::debugDrawSphere(btScalar radius, const btTransform& transform, const btVector3& color) +{ + btVector3 start = transform.getOrigin(); + + const btVector3 xoffs = transform.getBasis() * btVector3(radius,0,0); + const btVector3 yoffs = transform.getBasis() * btVector3(0,radius,0); + const btVector3 zoffs = transform.getBasis() * btVector3(0,0,radius); + + // XY + getDebugDrawer()->drawLine(start-xoffs, start+yoffs, color); + getDebugDrawer()->drawLine(start+yoffs, start+xoffs, color); + getDebugDrawer()->drawLine(start+xoffs, start-yoffs, color); + getDebugDrawer()->drawLine(start-yoffs, start-xoffs, color); + + // XZ + getDebugDrawer()->drawLine(start-xoffs, start+zoffs, color); + getDebugDrawer()->drawLine(start+zoffs, start+xoffs, color); + getDebugDrawer()->drawLine(start+xoffs, start-zoffs, color); + getDebugDrawer()->drawLine(start-zoffs, start-xoffs, color); + + // YZ + getDebugDrawer()->drawLine(start-yoffs, start+zoffs, color); + getDebugDrawer()->drawLine(start+zoffs, start+yoffs, color); + getDebugDrawer()->drawLine(start+yoffs, start-zoffs, color); + getDebugDrawer()->drawLine(start-zoffs, start-yoffs, color); +} + +void btDiscreteDynamicsWorld::debugDrawObject(const btTransform& worldTransform, const btCollisionShape* shape, const btVector3& color) +{ + // Draw a small simplex at the center of the object + { + btVector3 start = worldTransform.getOrigin(); + getDebugDrawer()->drawLine(start, start+worldTransform.getBasis() * btVector3(1,0,0), btVector3(1,0,0)); + getDebugDrawer()->drawLine(start, start+worldTransform.getBasis() * btVector3(0,1,0), btVector3(0,1,0)); + getDebugDrawer()->drawLine(start, start+worldTransform.getBasis() * btVector3(0,0,1), btVector3(0,0,1)); + } + + if (shape->getShapeType() == COMPOUND_SHAPE_PROXYTYPE) + { + const btCompoundShape* compoundShape = static_cast(shape); + for (int i=compoundShape->getNumChildShapes()-1;i>=0;i--) + { + btTransform childTrans = compoundShape->getChildTransform(i); + const btCollisionShape* colShape = compoundShape->getChildShape(i); + debugDrawObject(worldTransform*childTrans,colShape,color); + } + + } else + { + switch (shape->getShapeType()) + { + + case SPHERE_SHAPE_PROXYTYPE: + { + const btSphereShape* sphereShape = static_cast(shape); + btScalar radius = sphereShape->getMargin();//radius doesn't include the margin, so draw with margin + + debugDrawSphere(radius, worldTransform, color); + break; + } + case MULTI_SPHERE_SHAPE_PROXYTYPE: + { + const btMultiSphereShape* multiSphereShape = static_cast(shape); + + for (int i = multiSphereShape->getSphereCount()-1; i>=0;i--) + { + btTransform childTransform = worldTransform; + childTransform.getOrigin() += multiSphereShape->getSpherePosition(i); + debugDrawSphere(multiSphereShape->getSphereRadius(i), childTransform, color); + } + + break; + } + case CAPSULE_SHAPE_PROXYTYPE: + { + const btCapsuleShape* capsuleShape = static_cast(shape); + + btScalar radius = capsuleShape->getRadius(); + btScalar halfHeight = capsuleShape->getHalfHeight(); + + // Draw the ends + { + btTransform childTransform = worldTransform; + childTransform.getOrigin() = worldTransform * btVector3(0,halfHeight,0); + debugDrawSphere(radius, childTransform, color); + } + + { + btTransform childTransform = worldTransform; + childTransform.getOrigin() = worldTransform * btVector3(0,-halfHeight,0); + debugDrawSphere(radius, childTransform, color); + } + + // Draw some additional lines + btVector3 start = worldTransform.getOrigin(); + getDebugDrawer()->drawLine(start+worldTransform.getBasis() * btVector3(-radius,halfHeight,0),start+worldTransform.getBasis() * btVector3(-radius,-halfHeight,0), color); + getDebugDrawer()->drawLine(start+worldTransform.getBasis() * btVector3(radius,halfHeight,0),start+worldTransform.getBasis() * btVector3(radius,-halfHeight,0), color); + getDebugDrawer()->drawLine(start+worldTransform.getBasis() * btVector3(0,halfHeight,-radius),start+worldTransform.getBasis() * btVector3(0,-halfHeight,-radius), color); + getDebugDrawer()->drawLine(start+worldTransform.getBasis() * btVector3(0,halfHeight,radius),start+worldTransform.getBasis() * btVector3(0,-halfHeight,radius), color); + + break; + } + case CONE_SHAPE_PROXYTYPE: + { + const btConeShape* coneShape = static_cast(shape); + btScalar radius = coneShape->getRadius();//+coneShape->getMargin(); + btScalar height = coneShape->getHeight();//+coneShape->getMargin(); + btVector3 start = worldTransform.getOrigin(); + getDebugDrawer()->drawLine(start+worldTransform.getBasis() * btVector3(btScalar(0.),btScalar(0.),btScalar(0.5)*height),start+worldTransform.getBasis() * btVector3(radius,btScalar(0.),btScalar(-0.5)*height),color); + getDebugDrawer()->drawLine(start+worldTransform.getBasis() * btVector3(btScalar(0.),btScalar(0.),btScalar(0.5)*height),start+worldTransform.getBasis() * btVector3(-radius,btScalar(0.),btScalar(-0.5)*height),color); + getDebugDrawer()->drawLine(start+worldTransform.getBasis() * btVector3(btScalar(0.),btScalar(0.),btScalar(0.5)*height),start+worldTransform.getBasis() * btVector3(btScalar(0.),radius,btScalar(-0.5)*height),color); + getDebugDrawer()->drawLine(start+worldTransform.getBasis() * btVector3(btScalar(0.),btScalar(0.),btScalar(0.5)*height),start+worldTransform.getBasis() * btVector3(btScalar(0.),-radius,btScalar(-0.5)*height),color); + break; + + } + case CYLINDER_SHAPE_PROXYTYPE: + { + const btCylinderShape* cylinder = static_cast(shape); + int upAxis = cylinder->getUpAxis(); + btScalar radius = cylinder->getRadius(); + btScalar halfHeight = cylinder->getHalfExtents()[upAxis]; + btVector3 start = worldTransform.getOrigin(); + btVector3 offsetHeight(0,0,0); + offsetHeight[upAxis] = halfHeight; + btVector3 offsetRadius(0,0,0); + offsetRadius[(upAxis+1)%3] = radius; + getDebugDrawer()->drawLine(start+worldTransform.getBasis() * (offsetHeight+offsetRadius),start+worldTransform.getBasis() * (-offsetHeight+offsetRadius),color); + getDebugDrawer()->drawLine(start+worldTransform.getBasis() * (offsetHeight-offsetRadius),start+worldTransform.getBasis() * (-offsetHeight-offsetRadius),color); + break; + } + default: + { + + if (shape->isConcave()) + { + btConcaveShape* concaveMesh = (btConcaveShape*) shape; + + //todo pass camera, for some culling + btVector3 aabbMax(btScalar(1e30),btScalar(1e30),btScalar(1e30)); + btVector3 aabbMin(btScalar(-1e30),btScalar(-1e30),btScalar(-1e30)); + + DebugDrawcallback drawCallback(getDebugDrawer(),worldTransform,color); + concaveMesh->processAllTriangles(&drawCallback,aabbMin,aabbMax); + + } + + if (shape->getShapeType() == CONVEX_TRIANGLEMESH_SHAPE_PROXYTYPE) + { + btConvexTriangleMeshShape* convexMesh = (btConvexTriangleMeshShape*) shape; + //todo: pass camera for some culling + btVector3 aabbMax(btScalar(1e30),btScalar(1e30),btScalar(1e30)); + btVector3 aabbMin(btScalar(-1e30),btScalar(-1e30),btScalar(-1e30)); + //DebugDrawcallback drawCallback; + DebugDrawcallback drawCallback(getDebugDrawer(),worldTransform,color); + convexMesh->getStridingMesh()->InternalProcessAllTriangles(&drawCallback,aabbMin,aabbMax); + } + + + /// for polyhedral shapes + if (shape->isPolyhedral()) + { + btPolyhedralConvexShape* polyshape = (btPolyhedralConvexShape*) shape; + + int i; + for (i=0;igetNumEdges();i++) + { + btPoint3 a,b; + polyshape->getEdge(i,a,b); + btVector3 wa = worldTransform * a; + btVector3 wb = worldTransform * b; + getDebugDrawer()->drawLine(wa,wb,color); + + } + + + } + } + } + } +} + + +void btDiscreteDynamicsWorld::setConstraintSolver(btConstraintSolver* solver) +{ + if (m_ownsConstraintSolver) + { + delete m_constraintSolver; + } + m_ownsConstraintSolver = false; + m_constraintSolver = solver; +} + +int btDiscreteDynamicsWorld::getNumConstraints() const +{ + return int(m_constraints.size()); +} +btTypedConstraint* btDiscreteDynamicsWorld::getConstraint(int index) +{ + return m_constraints[index]; +} +const btTypedConstraint* btDiscreteDynamicsWorld::getConstraint(int index) const +{ + return m_constraints[index]; +} diff --git a/extern/bullet2/src/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.h b/extern/bullet2/src/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.h new file mode 100644 index 00000000000..83b90bfeebc --- /dev/null +++ b/extern/bullet2/src/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.h @@ -0,0 +1,157 @@ +/* +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 BT_DISCRETE_DYNAMICS_WORLD_H +#define BT_DISCRETE_DYNAMICS_WORLD_H + +#include "btDynamicsWorld.h" + +class btDispatcher; +class btOverlappingPairCache; +class btConstraintSolver; +class btSimulationIslandManager; +class btTypedConstraint; +#include "../ConstraintSolver/btContactSolverInfo.h" + +class btRaycastVehicle; +class btIDebugDraw; +#include "../../LinearMath/btAlignedObjectArray.h" + + +///btDiscreteDynamicsWorld provides discrete rigid body simulation +///those classes replace the obsolete CcdPhysicsEnvironment/CcdPhysicsController +class btDiscreteDynamicsWorld : public btDynamicsWorld +{ +protected: + + btConstraintSolver* m_constraintSolver; + + btSimulationIslandManager* m_islandManager; + + btAlignedObjectArray m_constraints; + + btIDebugDraw* m_debugDrawer; + + btVector3 m_gravity; + + //for variable timesteps + btScalar m_localTime; + //for variable timesteps + + bool m_ownsIslandManager; + bool m_ownsConstraintSolver; + + btContactSolverInfo m_solverInfo; + + + btAlignedObjectArray m_vehicles; + + int m_profileTimings; + + void predictUnconstraintMotion(btScalar timeStep); + + void integrateTransforms(btScalar timeStep); + + void calculateSimulationIslands(); + + void solveConstraints(btContactSolverInfo& solverInfo); + + void updateActivationState(btScalar timeStep); + + void updateVehicles(btScalar timeStep); + + void startProfiling(btScalar timeStep); + + virtual void internalSingleStepSimulation( btScalar timeStep); + + void synchronizeMotionStates(); + + void saveKinematicState(btScalar timeStep); + + void debugDrawSphere(btScalar radius, const btTransform& transform, const btVector3& color); + +public: + + + ///this btDiscreteDynamicsWorld constructor gets created objects from the user, and will not delete those + btDiscreteDynamicsWorld(btDispatcher* dispatcher,btOverlappingPairCache* pairCache,btConstraintSolver* constraintSolver); + + virtual ~btDiscreteDynamicsWorld(); + + ///if maxSubSteps > 0, it will interpolate motion between fixedTimeStep's + virtual int stepSimulation( btScalar timeStep,int maxSubSteps=1, btScalar fixedTimeStep=btScalar(1.)/btScalar(60.)); + + virtual void updateAabbs(); + + void addConstraint(btTypedConstraint* constraint, bool disableCollisionsBetweenLinkedBodies=false); + + void removeConstraint(btTypedConstraint* constraint); + + void addVehicle(btRaycastVehicle* vehicle); + + void removeVehicle(btRaycastVehicle* vehicle); + + btSimulationIslandManager* getSimulationIslandManager() + { + return m_islandManager; + } + + const btSimulationIslandManager* getSimulationIslandManager() const + { + return m_islandManager; + } + + btCollisionWorld* getCollisionWorld() + { + return this; + } + + virtual void setDebugDrawer(btIDebugDraw* debugDrawer) + { + m_debugDrawer = debugDrawer; + } + + virtual btIDebugDraw* getDebugDrawer() + { + return m_debugDrawer; + } + + virtual void setGravity(const btVector3& gravity); + + virtual void addRigidBody(btRigidBody* body); + + virtual void addRigidBody(btRigidBody* body, short group, short mask); + + virtual void removeRigidBody(btRigidBody* body); + + void debugDrawObject(const btTransform& worldTransform, const btCollisionShape* shape, const btVector3& color); + + virtual void setConstraintSolver(btConstraintSolver* solver); + + virtual int getNumConstraints() const; + + virtual btTypedConstraint* getConstraint(int index) ; + + virtual const btTypedConstraint* getConstraint(int index) const; + + btContactSolverInfo& getSolverInfo() + { + return m_solverInfo; + } + + +}; + +#endif //BT_DISCRETE_DYNAMICS_WORLD_H diff --git a/extern/bullet2/src/BulletDynamics/Dynamics/btDynamicsWorld.h b/extern/bullet2/src/BulletDynamics/Dynamics/btDynamicsWorld.h new file mode 100644 index 00000000000..65b63fad4b5 --- /dev/null +++ b/extern/bullet2/src/BulletDynamics/Dynamics/btDynamicsWorld.h @@ -0,0 +1,78 @@ +/* +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 BT_DYNAMICS_WORLD_H +#define BT_DYNAMICS_WORLD_H + +#include "../../BulletCollision/CollisionDispatch/btCollisionWorld.h" +class btTypedConstraint; +class btRaycastVehicle; +class btConstraintSolver; + + +///btDynamicsWorld is the baseclass for several dynamics implementation, basic, discrete, parallel, and continuous +class btDynamicsWorld : public btCollisionWorld +{ + public: + + + btDynamicsWorld(btDispatcher* dispatcher,btOverlappingPairCache* pairCache) + :btCollisionWorld(dispatcher,pairCache) + { + } + + virtual ~btDynamicsWorld() + { + } + + ///stepSimulation proceeds the simulation over timeStep units + ///if maxSubSteps > 0, it will interpolate time steps + virtual int stepSimulation( btScalar timeStep,int maxSubSteps=1, btScalar fixedTimeStep=btScalar(1.)/btScalar(60.))=0; + + virtual void updateAabbs() = 0; + + virtual void addConstraint(btTypedConstraint* constraint, bool disableCollisionsBetweenLinkedBodies=false) { (void)constraint;}; + + virtual void removeConstraint(btTypedConstraint* constraint) {(void)constraint;}; + + virtual void addVehicle(btRaycastVehicle* vehicle) {(void)vehicle;}; + + virtual void removeVehicle(btRaycastVehicle* vehicle) {(void)vehicle;}; + + + virtual void setDebugDrawer(btIDebugDraw* debugDrawer) = 0; + + virtual btIDebugDraw* getDebugDrawer() = 0; + + //once a rigidbody is added to the dynamics world, it will get this gravity assigned + //existing rigidbodies in the world get gravity assigned too, during this method + virtual void setGravity(const btVector3& gravity) = 0; + + virtual void addRigidBody(btRigidBody* body) = 0; + + virtual void removeRigidBody(btRigidBody* body) = 0; + + virtual void setConstraintSolver(btConstraintSolver* solver) = 0; + + virtual int getNumConstraints() const { return 0; } + + virtual btTypedConstraint* getConstraint(int index) { (void)index; return 0; } + + virtual const btTypedConstraint* getConstraint(int index) const { (void)index; return 0; } + +}; + +#endif //BT_DYNAMICS_WORLD_H + diff --git a/extern/bullet2/src/BulletDynamics/Dynamics/btRigidBody.cpp b/extern/bullet2/src/BulletDynamics/Dynamics/btRigidBody.cpp new file mode 100644 index 00000000000..9ed3579d89c --- /dev/null +++ b/extern/bullet2/src/BulletDynamics/Dynamics/btRigidBody.cpp @@ -0,0 +1,345 @@ +/* +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 "btRigidBody.h" +#include "BulletCollision/CollisionShapes/btConvexShape.h" +#include "LinearMath/btMinMax.h" +#include "LinearMath/btTransformUtil.h" +#include "LinearMath/btMotionState.h" +#include "BulletDynamics/ConstraintSolver/btTypedConstraint.h" + +btScalar gLinearAirDamping = btScalar(1.); +//'temporarily' global variables +btScalar gDeactivationTime = btScalar(2.); +bool gDisableDeactivation = false; + +btScalar gLinearSleepingThreshold = btScalar(0.8); +btScalar gAngularSleepingThreshold = btScalar(1.0); +static int uniqueId = 0; + +btRigidBody::btRigidBody(btScalar mass, btMotionState* motionState, btCollisionShape* collisionShape, const btVector3& localInertia,btScalar linearDamping,btScalar angularDamping,btScalar friction,btScalar restitution) +: + m_linearVelocity(btScalar(0.0), btScalar(0.0), btScalar(0.0)), + m_angularVelocity(btScalar(0.),btScalar(0.),btScalar(0.)), + m_angularFactor(btScalar(1.)), + m_gravity(btScalar(0.0), btScalar(0.0), btScalar(0.0)), + m_totalForce(btScalar(0.0), btScalar(0.0), btScalar(0.0)), + m_totalTorque(btScalar(0.0), btScalar(0.0), btScalar(0.0)), + m_linearDamping(btScalar(0.)), + m_angularDamping(btScalar(0.5)), + m_optionalMotionState(motionState), + m_contactSolverType(0), + m_frictionSolverType(0) +{ + + if (motionState) + { + motionState->getWorldTransform(m_worldTransform); + } else + { + m_worldTransform = btTransform::getIdentity(); + } + + m_interpolationWorldTransform = m_worldTransform; + m_interpolationLinearVelocity.setValue(0,0,0); + m_interpolationAngularVelocity.setValue(0,0,0); + + //moved to btCollisionObject + m_friction = friction; + m_restitution = restitution; + + m_collisionShape = collisionShape; + m_debugBodyId = uniqueId++; + + //m_internalOwner is to allow upcasting from collision object to rigid body + m_internalOwner = this; + + setMassProps(mass, localInertia); + setDamping(linearDamping, angularDamping); + updateInertiaTensor(); + +} + +#ifdef OBSOLETE_MOTIONSTATE_LESS +btRigidBody::btRigidBody( btScalar mass,const btTransform& worldTransform,btCollisionShape* collisionShape,const btVector3& localInertia,btScalar linearDamping,btScalar angularDamping,btScalar friction,btScalar restitution) +: + m_gravity(btScalar(0.0), btScalar(0.0), btScalar(0.0)), + m_totalForce(btScalar(0.0), btScalar(0.0), btScalar(0.0)), + m_totalTorque(btScalar(0.0), btScalar(0.0), btScalar(0.0)), + m_linearVelocity(btScalar(0.0), btScalar(0.0), btScalar(0.0)), + m_angularVelocity(btScalar(0.),btScalar(0.),btScalar(0.)), + m_linearDamping(btScalar(0.)), + m_angularDamping(btScalar(0.5)), + m_optionalMotionState(0), + m_contactSolverType(0), + m_frictionSolverType(0) +{ + + m_worldTransform = worldTransform; + m_interpolationWorldTransform = m_worldTransform; + m_interpolationLinearVelocity.setValue(0,0,0); + m_interpolationAngularVelocity.setValue(0,0,0); + + //moved to btCollisionObject + m_friction = friction; + m_restitution = restitution; + + m_collisionShape = collisionShape; + m_debugBodyId = uniqueId++; + + //m_internalOwner is to allow upcasting from collision object to rigid body + m_internalOwner = this; + + setMassProps(mass, localInertia); + setDamping(linearDamping, angularDamping); + updateInertiaTensor(); + +} + +#endif //OBSOLETE_MOTIONSTATE_LESS + + + + +//#define EXPERIMENTAL_JITTER_REMOVAL 1 +#ifdef EXPERIMENTAL_JITTER_REMOVAL +//Bullet 2.20b has experimental damping code to reduce jitter just before objects fall asleep/deactivate +//doesn't work very well yet (value 0 disabled this damping) +//note there this influences deactivation thresholds! +btScalar gClippedAngvelThresholdSqr = btScalar(0.01); +btScalar gClippedLinearThresholdSqr = btScalar(0.01); +#endif //EXPERIMENTAL_JITTER_REMOVAL + +btScalar gJitterVelocityDampingFactor = btScalar(0.7); + +void btRigidBody::predictIntegratedTransform(btScalar timeStep,btTransform& predictedTransform) +{ + +#ifdef EXPERIMENTAL_JITTER_REMOVAL + //if (wantsSleeping()) + { + //clip to avoid jitter + if ((m_angularVelocity.length2() < gClippedAngvelThresholdSqr) && + (m_linearVelocity.length2() < gClippedLinearThresholdSqr)) + { + m_angularVelocity *= gJitterVelocityDampingFactor; + m_linearVelocity *= gJitterVelocityDampingFactor; + } + } + +#endif //EXPERIMENTAL_JITTER_REMOVAL + + btTransformUtil::integrateTransform(m_worldTransform,m_linearVelocity,m_angularVelocity,timeStep,predictedTransform); +} + +void btRigidBody::saveKinematicState(btScalar timeStep) +{ + //todo: clamp to some (user definable) safe minimum timestep, to limit maximum angular/linear velocities + if (timeStep != btScalar(0.)) + { + //if we use motionstate to synchronize world transforms, get the new kinematic/animated world transform + if (getMotionState()) + getMotionState()->getWorldTransform(m_worldTransform); + btVector3 linVel,angVel; + + btTransformUtil::calculateVelocity(m_interpolationWorldTransform,m_worldTransform,timeStep,m_linearVelocity,m_angularVelocity); + m_interpolationLinearVelocity = m_linearVelocity; + m_interpolationAngularVelocity = m_angularVelocity; + m_interpolationWorldTransform = m_worldTransform; + //printf("angular = %f %f %f\n",m_angularVelocity.getX(),m_angularVelocity.getY(),m_angularVelocity.getZ()); + } +} + +void btRigidBody::getAabb(btVector3& aabbMin,btVector3& aabbMax) const +{ + getCollisionShape()->getAabb(m_worldTransform,aabbMin,aabbMax); +} + + + + +void btRigidBody::setGravity(const btVector3& acceleration) +{ + if (m_inverseMass != btScalar(0.0)) + { + m_gravity = acceleration * (btScalar(1.0) / m_inverseMass); + } +} + + + + + + +void btRigidBody::setDamping(btScalar lin_damping, btScalar ang_damping) +{ + m_linearDamping = GEN_clamped(lin_damping, (btScalar)btScalar(0.0), (btScalar)btScalar(1.0)); + m_angularDamping = GEN_clamped(ang_damping, (btScalar)btScalar(0.0), (btScalar)btScalar(1.0)); +} + + + +#include + + +void btRigidBody::applyForces(btScalar step) +{ + if (isStaticOrKinematicObject()) + return; + + applyCentralForce(m_gravity); + + m_linearVelocity *= GEN_clamped((btScalar(1.) - step * gLinearAirDamping * m_linearDamping), (btScalar)btScalar(0.0), (btScalar)btScalar(1.0)); + m_angularVelocity *= GEN_clamped((btScalar(1.) - step * m_angularDamping), (btScalar)btScalar(0.0), (btScalar)btScalar(1.0)); + +#define FORCE_VELOCITY_DAMPING 1 +#ifdef FORCE_VELOCITY_DAMPING + btScalar speed = m_linearVelocity.length(); + if (speed < m_linearDamping) + { + btScalar dampVel = btScalar(0.005); + if (speed > dampVel) + { + btVector3 dir = m_linearVelocity.normalized(); + m_linearVelocity -= dir * dampVel; + } else + { + m_linearVelocity.setValue(btScalar(0.),btScalar(0.),btScalar(0.)); + } + } + + btScalar angSpeed = m_angularVelocity.length(); + if (angSpeed < m_angularDamping) + { + btScalar angDampVel = btScalar(0.005); + if (angSpeed > angDampVel) + { + btVector3 dir = m_angularVelocity.normalized(); + m_angularVelocity -= dir * angDampVel; + } else + { + m_angularVelocity.setValue(btScalar(0.),btScalar(0.),btScalar(0.)); + } + } +#endif //FORCE_VELOCITY_DAMPING + +} + +void btRigidBody::proceedToTransform(const btTransform& newTrans) +{ + setCenterOfMassTransform( newTrans ); +} + + +void btRigidBody::setMassProps(btScalar mass, const btVector3& inertia) +{ + if (mass == btScalar(0.)) + { + m_collisionFlags |= btCollisionObject::CF_STATIC_OBJECT; + m_inverseMass = btScalar(0.); + } else + { + m_collisionFlags &= (~btCollisionObject::CF_STATIC_OBJECT); + m_inverseMass = btScalar(1.0) / mass; + } + + m_invInertiaLocal.setValue(inertia.x() != btScalar(0.0) ? btScalar(1.0) / inertia.x(): btScalar(0.0), + inertia.y() != btScalar(0.0) ? btScalar(1.0) / inertia.y(): btScalar(0.0), + inertia.z() != btScalar(0.0) ? btScalar(1.0) / inertia.z(): btScalar(0.0)); + +} + + + +void btRigidBody::updateInertiaTensor() +{ + m_invInertiaTensorWorld = m_worldTransform.getBasis().scaled(m_invInertiaLocal) * m_worldTransform.getBasis().transpose(); +} + + +void btRigidBody::integrateVelocities(btScalar step) +{ + if (isStaticOrKinematicObject()) + return; + + m_linearVelocity += m_totalForce * (m_inverseMass * step); + m_angularVelocity += m_invInertiaTensorWorld * m_totalTorque * step; + +#define MAX_ANGVEL SIMD_HALF_PI + /// clamp angular velocity. collision calculations will fail on higher angular velocities + btScalar angvel = m_angularVelocity.length(); + if (angvel*step > MAX_ANGVEL) + { + m_angularVelocity *= (MAX_ANGVEL/step) /angvel; + } + + clearForces(); +} + +btQuaternion btRigidBody::getOrientation() const +{ + btQuaternion orn; + m_worldTransform.getBasis().getRotation(orn); + return orn; +} + + +void btRigidBody::setCenterOfMassTransform(const btTransform& xform) +{ + + if (isStaticOrKinematicObject()) + { + m_interpolationWorldTransform = m_worldTransform; + } else + { + m_interpolationWorldTransform = xform; + } + m_interpolationLinearVelocity = getLinearVelocity(); + m_interpolationAngularVelocity = getAngularVelocity(); + m_worldTransform = xform; + updateInertiaTensor(); +} + + +bool btRigidBody::checkCollideWithOverride(btCollisionObject* co) +{ + btRigidBody* otherRb = btRigidBody::upcast(co); + if (!otherRb) + return true; + + for (int i = 0; i < m_constraintRefs.size(); ++i) + { + btTypedConstraint* c = m_constraintRefs[i]; + if (&c->getRigidBodyA() == otherRb || &c->getRigidBodyB() == otherRb) + return false; + } + + return true; +} + +void btRigidBody::addConstraintRef(btTypedConstraint* c) +{ + int index = m_constraintRefs.findLinearSearch(c); + if (index == m_constraintRefs.size()) + m_constraintRefs.push_back(c); + + m_checkCollideWith = true; +} + +void btRigidBody::removeConstraintRef(btTypedConstraint* c) +{ + m_constraintRefs.remove(c); + m_checkCollideWith = m_constraintRefs.size() > 0; +} diff --git a/extern/bullet2/src/BulletDynamics/Dynamics/btRigidBody.h b/extern/bullet2/src/BulletDynamics/Dynamics/btRigidBody.h new file mode 100644 index 00000000000..0707595d48e --- /dev/null +++ b/extern/bullet2/src/BulletDynamics/Dynamics/btRigidBody.h @@ -0,0 +1,357 @@ +/* +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 RIGIDBODY_H +#define RIGIDBODY_H + +#include "../../LinearMath/btAlignedObjectArray.h" +#include "../../LinearMath/btPoint3.h" +#include "../../LinearMath/btTransform.h" +#include "../../BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" +#include "../../BulletCollision/CollisionDispatch/btCollisionObject.h" + +class btCollisionShape; +class btMotionState; +class btTypedConstraint; + + +extern btScalar gLinearAirDamping; + +extern btScalar gDeactivationTime; +extern bool gDisableDeactivation; +extern btScalar gLinearSleepingThreshold; +extern btScalar gAngularSleepingThreshold; + + +/// btRigidBody class for btRigidBody Dynamics +/// +class btRigidBody : public btCollisionObject +{ + + btMatrix3x3 m_invInertiaTensorWorld; + btVector3 m_linearVelocity; + btVector3 m_angularVelocity; + btScalar m_inverseMass; + btScalar m_angularFactor; + + btVector3 m_gravity; + btVector3 m_invInertiaLocal; + btVector3 m_totalForce; + btVector3 m_totalTorque; + + btScalar m_linearDamping; + btScalar m_angularDamping; + + + //m_optionalMotionState allows to automatic synchronize the world transform for active objects + btMotionState* m_optionalMotionState; + + //keep track of typed constraints referencing this rigid body + btAlignedObjectArray m_constraintRefs; + +public: + +#ifdef OBSOLETE_MOTIONSTATE_LESS + //not supported, please use btMotionState + btRigidBody(btScalar mass, const btTransform& worldTransform, btCollisionShape* collisionShape, const btVector3& localInertia=btVector3(0,0,0),btScalar linearDamping=btScalar(0.),btScalar angularDamping=btScalar(0.),btScalar friction=btScalar(0.5),btScalar restitution=btScalar(0.)); +#endif //OBSOLETE_MOTIONSTATE_LESS + + btRigidBody(btScalar mass, btMotionState* motionState, btCollisionShape* collisionShape, const btVector3& localInertia=btVector3(0,0,0),btScalar linearDamping=btScalar(0.),btScalar angularDamping=btScalar(0.),btScalar friction=btScalar(0.5),btScalar restitution=btScalar(0.)); + + void proceedToTransform(const btTransform& newTrans); + + ///to keep collision detection and dynamics separate we don't store a rigidbody pointer + ///but a rigidbody is derived from btCollisionObject, so we can safely perform an upcast + static const btRigidBody* upcast(const btCollisionObject* colObj) + { + return (const btRigidBody*)colObj->getInternalOwner(); + } + static btRigidBody* upcast(btCollisionObject* colObj) + { + return (btRigidBody*)colObj->getInternalOwner(); + } + + /// continuous collision detection needs prediction + void predictIntegratedTransform(btScalar step, btTransform& predictedTransform) ; + + void saveKinematicState(btScalar step); + + + void applyForces(btScalar step); + + void setGravity(const btVector3& acceleration); + + const btVector3& getGravity() const + { + return m_gravity; + } + + void setDamping(btScalar lin_damping, btScalar ang_damping); + + inline const btCollisionShape* getCollisionShape() const { + return m_collisionShape; + } + + inline btCollisionShape* getCollisionShape() { + return m_collisionShape; + } + + void setMassProps(btScalar mass, const btVector3& inertia); + + btScalar getInvMass() const { return m_inverseMass; } + const btMatrix3x3& getInvInertiaTensorWorld() const { + return m_invInertiaTensorWorld; + } + + void integrateVelocities(btScalar step); + + void setCenterOfMassTransform(const btTransform& xform); + + void applyCentralForce(const btVector3& force) + { + m_totalForce += force; + } + + const btVector3& getInvInertiaDiagLocal() + { + return m_invInertiaLocal; + }; + + void setInvInertiaDiagLocal(const btVector3& diagInvInertia) + { + m_invInertiaLocal = diagInvInertia; + } + + void applyTorque(const btVector3& torque) + { + m_totalTorque += torque; + } + + void applyForce(const btVector3& force, const btVector3& rel_pos) + { + applyCentralForce(force); + applyTorque(rel_pos.cross(force)); + } + + void applyCentralImpulse(const btVector3& impulse) + { + m_linearVelocity += impulse * m_inverseMass; + } + + void applyTorqueImpulse(const btVector3& torque) + { + m_angularVelocity += m_invInertiaTensorWorld * torque; + } + + void applyImpulse(const btVector3& impulse, const btVector3& rel_pos) + { + if (m_inverseMass != btScalar(0.)) + { + applyCentralImpulse(impulse); + if (m_angularFactor) + { + applyTorqueImpulse(rel_pos.cross(impulse)*m_angularFactor); + } + } + } + + //Optimization for the iterative solver: avoid calculating constant terms involving inertia, normal, relative position + inline void internalApplyImpulse(const btVector3& linearComponent, const btVector3& angularComponent,btScalar impulseMagnitude) + { + if (m_inverseMass != btScalar(0.)) + { + m_linearVelocity += linearComponent*impulseMagnitude; + if (m_angularFactor) + { + m_angularVelocity += angularComponent*impulseMagnitude*m_angularFactor; + } + } + } + + void clearForces() + { + m_totalForce.setValue(btScalar(0.0), btScalar(0.0), btScalar(0.0)); + m_totalTorque.setValue(btScalar(0.0), btScalar(0.0), btScalar(0.0)); + } + + void updateInertiaTensor(); + + const btPoint3& getCenterOfMassPosition() const { + return m_worldTransform.getOrigin(); + } + btQuaternion getOrientation() const; + + const btTransform& getCenterOfMassTransform() const { + return m_worldTransform; + } + const btVector3& getLinearVelocity() const { + return m_linearVelocity; + } + const btVector3& getAngularVelocity() const { + return m_angularVelocity; + } + + + inline void setLinearVelocity(const btVector3& lin_vel) + { + assert (m_collisionFlags != btCollisionObject::CF_STATIC_OBJECT); + m_linearVelocity = lin_vel; + } + + inline void setAngularVelocity(const btVector3& ang_vel) { + assert (m_collisionFlags != btCollisionObject::CF_STATIC_OBJECT); + { + m_angularVelocity = ang_vel; + } + } + + btVector3 getVelocityInLocalPoint(const btVector3& rel_pos) const + { + //we also calculate lin/ang velocity for kinematic objects + return m_linearVelocity + m_angularVelocity.cross(rel_pos); + + //for kinematic objects, we could also use use: + // return (m_worldTransform(rel_pos) - m_interpolationWorldTransform(rel_pos)) / m_kinematicTimeStep; + } + + void translate(const btVector3& v) + { + m_worldTransform.getOrigin() += v; + } + + + void getAabb(btVector3& aabbMin,btVector3& aabbMax) const; + + + + + + inline btScalar computeImpulseDenominator(const btPoint3& pos, const btVector3& normal) const + { + btVector3 r0 = pos - getCenterOfMassPosition(); + + btVector3 c0 = (r0).cross(normal); + + btVector3 vec = (c0 * getInvInertiaTensorWorld()).cross(r0); + + return m_inverseMass + normal.dot(vec); + + } + + inline btScalar computeAngularImpulseDenominator(const btVector3& axis) const + { + btVector3 vec = axis * getInvInertiaTensorWorld(); + return axis.dot(vec); + } + + inline void updateDeactivation(btScalar timeStep) + { + if ( (getActivationState() == ISLAND_SLEEPING) || (getActivationState() == DISABLE_DEACTIVATION)) + return; + + if ((getLinearVelocity().length2() < gLinearSleepingThreshold*gLinearSleepingThreshold) && + (getAngularVelocity().length2() < gAngularSleepingThreshold*gAngularSleepingThreshold)) + { + m_deactivationTime += timeStep; + } else + { + m_deactivationTime=btScalar(0.); + setActivationState(0); + } + + } + + inline bool wantsSleeping() + { + + if (getActivationState() == DISABLE_DEACTIVATION) + return false; + + //disable deactivation + if (gDisableDeactivation || (gDeactivationTime == btScalar(0.))) + return false; + + if ( (getActivationState() == ISLAND_SLEEPING) || (getActivationState() == WANTS_DEACTIVATION)) + return true; + + if (m_deactivationTime> gDeactivationTime) + { + return true; + } + return false; + } + + + + const btBroadphaseProxy* getBroadphaseProxy() const + { + return m_broadphaseHandle; + } + btBroadphaseProxy* getBroadphaseProxy() + { + return m_broadphaseHandle; + } + void setNewBroadphaseProxy(btBroadphaseProxy* broadphaseProxy) + { + m_broadphaseHandle = broadphaseProxy; + } + + //btMotionState allows to automatic synchronize the world transform for active objects + btMotionState* getMotionState() + { + return m_optionalMotionState; + } + const btMotionState* getMotionState() const + { + return m_optionalMotionState; + } + void setMotionState(btMotionState* motionState) + { + m_optionalMotionState = motionState; + if (m_optionalMotionState) + motionState->getWorldTransform(m_worldTransform); + } + + //for experimental overriding of friction/contact solver func + int m_contactSolverType; + int m_frictionSolverType; + + void setAngularFactor(btScalar angFac) + { + m_angularFactor = angFac; + } + btScalar getAngularFactor() const + { + return m_angularFactor; + } + + //is this rigidbody added to a btCollisionWorld/btDynamicsWorld/btBroadphase? + bool isInWorld() const + { + return (getBroadphaseProxy() != 0); + } + + virtual bool checkCollideWithOverride(btCollisionObject* co); + + void addConstraintRef(btTypedConstraint* c); + void removeConstraintRef(btTypedConstraint* c); + + int m_debugBodyId; +}; + + + +#endif + diff --git a/extern/bullet2/src/BulletDynamics/Dynamics/btSimpleDynamicsWorld.cpp b/extern/bullet2/src/BulletDynamics/Dynamics/btSimpleDynamicsWorld.cpp new file mode 100644 index 00000000000..4ebcb8e7517 --- /dev/null +++ b/extern/bullet2/src/BulletDynamics/Dynamics/btSimpleDynamicsWorld.cpp @@ -0,0 +1,211 @@ +/* +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 "btSimpleDynamicsWorld.h" +#include "BulletCollision/CollisionDispatch/btCollisionDispatcher.h" +#include "BulletCollision/BroadphaseCollision/btSimpleBroadphase.h" +#include "BulletCollision/CollisionShapes/btCollisionShape.h" +#include "BulletDynamics/Dynamics/btRigidBody.h" +#include "BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.h" +#include "BulletDynamics/ConstraintSolver/btContactSolverInfo.h" + + +/* + Make sure this dummy function never changes so that it + can be used by probes that are checking whether the + library is actually installed. +*/ +extern "C" void btBulletDynamicsProbe () {} + + + + +btSimpleDynamicsWorld::btSimpleDynamicsWorld(btDispatcher* dispatcher,btOverlappingPairCache* pairCache,btConstraintSolver* constraintSolver) +:btDynamicsWorld(dispatcher,pairCache), +m_constraintSolver(constraintSolver), +m_ownsConstraintSolver(false), +m_debugDrawer(0), +m_gravity(0,0,-10) +{ + +} + + +btSimpleDynamicsWorld::~btSimpleDynamicsWorld() +{ + if (m_ownsConstraintSolver) + delete m_constraintSolver; +} + +int btSimpleDynamicsWorld::stepSimulation( btScalar timeStep,int maxSubSteps, btScalar fixedTimeStep) +{ + (void)fixedTimeStep; + (void)maxSubSteps; + + + ///apply gravity, predict motion + predictUnconstraintMotion(timeStep); + + btDispatcherInfo& dispatchInfo = getDispatchInfo(); + dispatchInfo.m_timeStep = timeStep; + dispatchInfo.m_stepCount = 0; + dispatchInfo.m_debugDraw = getDebugDrawer(); + + ///perform collision detection + performDiscreteCollisionDetection(); + + ///solve contact constraints + int numManifolds = m_dispatcher1->getNumManifolds(); + if (numManifolds) + { + btPersistentManifold** manifoldPtr = ((btCollisionDispatcher*)m_dispatcher1)->getInternalManifoldPointer(); + + btContactSolverInfo infoGlobal; + infoGlobal.m_timeStep = timeStep; + + m_constraintSolver->solveGroup(0,0,manifoldPtr, numManifolds,0,0,infoGlobal,m_debugDrawer, m_stackAlloc); + } + + ///integrate transforms + integrateTransforms(timeStep); + + updateAabbs(); + + synchronizeMotionStates(); + + return 1; + +} + + +void btSimpleDynamicsWorld::setGravity(const btVector3& gravity) +{ + m_gravity = gravity; + for ( int i=0;isetGravity(gravity); + } + } +} + +void btSimpleDynamicsWorld::removeRigidBody(btRigidBody* body) +{ + removeCollisionObject(body); +} + +void btSimpleDynamicsWorld::addRigidBody(btRigidBody* body) +{ + body->setGravity(m_gravity); + + if (body->getCollisionShape()) + { + addCollisionObject(body); + } +} + +void btSimpleDynamicsWorld::updateAabbs() +{ + btTransform predictedTrans; + for ( int i=0;iisActive() && (!body->isStaticObject())) + { + btPoint3 minAabb,maxAabb; + colObj->getCollisionShape()->getAabb(colObj->getWorldTransform(), minAabb,maxAabb); + btBroadphaseInterface* bp = getBroadphase(); + bp->setAabb(body->getBroadphaseHandle(),minAabb,maxAabb); + } + } + } +} + +void btSimpleDynamicsWorld::integrateTransforms(btScalar timeStep) +{ + btTransform predictedTrans; + for ( int i=0;iisActive() && (!body->isStaticObject())) + { + body->predictIntegratedTransform(timeStep, predictedTrans); + body->proceedToTransform( predictedTrans); + } + } + } +} + + + +void btSimpleDynamicsWorld::predictUnconstraintMotion(btScalar timeStep) +{ + for ( int i=0;iisStaticObject()) + { + if (body->isActive()) + { + body->applyForces( timeStep); + body->integrateVelocities( timeStep); + body->predictIntegratedTransform(timeStep,body->getInterpolationWorldTransform()); + } + } + } + } +} + + +void btSimpleDynamicsWorld::synchronizeMotionStates() +{ + //todo: iterate over awake simulation islands! + for ( int i=0;igetMotionState()) + { + if (body->getActivationState() != ISLAND_SLEEPING) + { + body->getMotionState()->setWorldTransform(body->getWorldTransform()); + } + } + } + +} + + +void btSimpleDynamicsWorld::setConstraintSolver(btConstraintSolver* solver) +{ + if (m_ownsConstraintSolver) + { + delete m_constraintSolver; + } + m_ownsConstraintSolver = false; + m_constraintSolver = solver; +} diff --git a/extern/bullet2/src/BulletDynamics/Dynamics/btSimpleDynamicsWorld.h b/extern/bullet2/src/BulletDynamics/Dynamics/btSimpleDynamicsWorld.h new file mode 100644 index 00000000000..25f4ccd8e68 --- /dev/null +++ b/extern/bullet2/src/BulletDynamics/Dynamics/btSimpleDynamicsWorld.h @@ -0,0 +1,82 @@ +/* +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 BT_SIMPLE_DYNAMICS_WORLD_H +#define BT_SIMPLE_DYNAMICS_WORLD_H + +#include "btDynamicsWorld.h" + +class btDispatcher; +class btOverlappingPairCache; +class btConstraintSolver; + +///btSimpleDynamicsWorld demonstrates very basic usage of Bullet rigid body dynamics +///It can be used for basic simulations, and as a starting point for porting Bullet +///btSimpleDynamicsWorld lacks object deactivation, island management and other concepts. +///For more complicated simulations, btDiscreteDynamicsWorld and btContinuousDynamicsWorld are recommended +///those classes replace the obsolete CcdPhysicsEnvironment/CcdPhysicsController +class btSimpleDynamicsWorld : public btDynamicsWorld +{ +protected: + + btConstraintSolver* m_constraintSolver; + + bool m_ownsConstraintSolver; + + btIDebugDraw* m_debugDrawer; + + void predictUnconstraintMotion(btScalar timeStep); + + void integrateTransforms(btScalar timeStep); + + btVector3 m_gravity; + +public: + + + + ///this btSimpleDynamicsWorld constructor creates dispatcher, broadphase pairCache and constraintSolver + btSimpleDynamicsWorld(btDispatcher* dispatcher,btOverlappingPairCache* pairCache,btConstraintSolver* constraintSolver); + + virtual ~btSimpleDynamicsWorld(); + + ///maxSubSteps/fixedTimeStep for interpolation is currently ignored for btSimpleDynamicsWorld, use btDiscreteDynamicsWorld instead + virtual int stepSimulation( btScalar timeStep,int maxSubSteps=1, btScalar fixedTimeStep=btScalar(1.)/btScalar(60.)); + + virtual void setDebugDrawer(btIDebugDraw* debugDrawer) + { + m_debugDrawer = debugDrawer; + }; + + virtual btIDebugDraw* getDebugDrawer() + { + return m_debugDrawer; + } + + virtual void setGravity(const btVector3& gravity); + + virtual void addRigidBody(btRigidBody* body); + + virtual void removeRigidBody(btRigidBody* body); + + virtual void updateAabbs(); + + void synchronizeMotionStates(); + + virtual void setConstraintSolver(btConstraintSolver* solver); + +}; + +#endif //BT_SIMPLE_DYNAMICS_WORLD_H diff --git a/extern/bullet2/src/BulletDynamics/Vehicle/btRaycastVehicle.cpp b/extern/bullet2/src/BulletDynamics/Vehicle/btRaycastVehicle.cpp new file mode 100644 index 00000000000..d53de7f3687 --- /dev/null +++ b/extern/bullet2/src/BulletDynamics/Vehicle/btRaycastVehicle.cpp @@ -0,0 +1,733 @@ +/* + * Copyright (c) 2005 Erwin Coumans http://continuousphysics.com/Bullet/ + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies. + * Erwin Coumans makes no representations about the suitability + * of this software for any purpose. + * It is provided "as is" without express or implied warranty. +*/ + +#include "LinearMath/btVector3.h" +#include "btRaycastVehicle.h" + +#include "BulletDynamics/ConstraintSolver/btSolve2LinearConstraint.h" +#include "BulletDynamics/ConstraintSolver/btJacobianEntry.h" +#include "LinearMath/btQuaternion.h" +#include "BulletDynamics/Dynamics/btDynamicsWorld.h" +#include "btVehicleRaycaster.h" +#include "btWheelInfo.h" +#include "LinearMath/btMinMax.h" + + +#include "BulletDynamics/ConstraintSolver/btContactConstraint.h" + + + +static btRigidBody s_fixedObject( 0,0,0); + +btRaycastVehicle::btRaycastVehicle(const btVehicleTuning& tuning,btRigidBody* chassis, btVehicleRaycaster* raycaster ) +:m_vehicleRaycaster(raycaster), +m_pitchControl(btScalar(0.)) +{ + m_chassisBody = chassis; + m_indexRightAxis = 0; + m_indexUpAxis = 2; + m_indexForwardAxis = 1; + defaultInit(tuning); +} + + +void btRaycastVehicle::defaultInit(const btVehicleTuning& tuning) +{ + (void)tuning; + m_currentVehicleSpeedKmHour = btScalar(0.); + m_steeringValue = btScalar(0.); + +} + + + +btRaycastVehicle::~btRaycastVehicle() +{ +} + + +// +// basically most of the code is general for 2 or 4 wheel vehicles, but some of it needs to be reviewed +// +btWheelInfo& btRaycastVehicle::addWheel( const btVector3& connectionPointCS, const btVector3& wheelDirectionCS0,const btVector3& wheelAxleCS, btScalar suspensionRestLength, btScalar wheelRadius,const btVehicleTuning& tuning, bool isFrontWheel) +{ + + btWheelInfoConstructionInfo ci; + + ci.m_chassisConnectionCS = connectionPointCS; + ci.m_wheelDirectionCS = wheelDirectionCS0; + ci.m_wheelAxleCS = wheelAxleCS; + ci.m_suspensionRestLength = suspensionRestLength; + ci.m_wheelRadius = wheelRadius; + ci.m_suspensionStiffness = tuning.m_suspensionStiffness; + ci.m_wheelsDampingCompression = tuning.m_suspensionCompression; + ci.m_wheelsDampingRelaxation = tuning.m_suspensionDamping; + ci.m_frictionSlip = tuning.m_frictionSlip; + ci.m_bIsFrontWheel = isFrontWheel; + ci.m_maxSuspensionTravelCm = tuning.m_maxSuspensionTravelCm; + + m_wheelInfo.push_back( btWheelInfo(ci)); + + btWheelInfo& wheel = m_wheelInfo[getNumWheels()-1]; + + updateWheelTransformsWS( wheel , false ); + updateWheelTransform(getNumWheels()-1,false); + return wheel; +} + + + + +const btTransform& btRaycastVehicle::getWheelTransformWS( int wheelIndex ) const +{ + assert(wheelIndex < getNumWheels()); + const btWheelInfo& wheel = m_wheelInfo[wheelIndex]; + return wheel.m_worldTransform; + +} + +void btRaycastVehicle::updateWheelTransform( int wheelIndex , bool interpolatedTransform) +{ + + btWheelInfo& wheel = m_wheelInfo[ wheelIndex ]; + updateWheelTransformsWS(wheel,interpolatedTransform); + btVector3 up = -wheel.m_raycastInfo.m_wheelDirectionWS; + const btVector3& right = wheel.m_raycastInfo.m_wheelAxleWS; + btVector3 fwd = up.cross(right); + fwd = fwd.normalize(); +// up = right.cross(fwd); +// up.normalize(); + + //rotate around steering over de wheelAxleWS + btScalar steering = wheel.m_steering; + + btQuaternion steeringOrn(up,steering);//wheel.m_steering); + btMatrix3x3 steeringMat(steeringOrn); + + btQuaternion rotatingOrn(right,-wheel.m_rotation); + btMatrix3x3 rotatingMat(rotatingOrn); + + btMatrix3x3 basis2( + right[0],fwd[0],up[0], + right[1],fwd[1],up[1], + right[2],fwd[2],up[2] + ); + + wheel.m_worldTransform.setBasis(steeringMat * rotatingMat * basis2); + wheel.m_worldTransform.setOrigin( + wheel.m_raycastInfo.m_hardPointWS + wheel.m_raycastInfo.m_wheelDirectionWS * wheel.m_raycastInfo.m_suspensionLength + ); +} + +void btRaycastVehicle::resetSuspension() +{ + + int i; + for (i=0;igetMotionState())) + { + getRigidBody()->getMotionState()->getWorldTransform(chassisTrans); + } + + wheel.m_raycastInfo.m_hardPointWS = chassisTrans( wheel.m_chassisConnectionPointCS ); + wheel.m_raycastInfo.m_wheelDirectionWS = chassisTrans.getBasis() * wheel.m_wheelDirectionCS ; + wheel.m_raycastInfo.m_wheelAxleWS = chassisTrans.getBasis() * wheel.m_wheelAxleCS; +} + +btScalar btRaycastVehicle::rayCast(btWheelInfo& wheel) +{ + updateWheelTransformsWS( wheel,false); + + + btScalar depth = -1; + + btScalar raylen = wheel.getSuspensionRestLength()+wheel.m_wheelsRadius; + + btVector3 rayvector = wheel.m_raycastInfo.m_wheelDirectionWS * (raylen); + const btVector3& source = wheel.m_raycastInfo.m_hardPointWS; + wheel.m_raycastInfo.m_contactPointWS = source + rayvector; + const btVector3& target = wheel.m_raycastInfo.m_contactPointWS; + + btScalar param = btScalar(0.); + + btVehicleRaycaster::btVehicleRaycasterResult rayResults; + + assert(m_vehicleRaycaster); + + void* object = m_vehicleRaycaster->castRay(source,target,rayResults); + + wheel.m_raycastInfo.m_groundObject = 0; + + if (object) + { + param = rayResults.m_distFraction; + depth = raylen * rayResults.m_distFraction; + wheel.m_raycastInfo.m_contactNormalWS = rayResults.m_hitNormalInWorld; + wheel.m_raycastInfo.m_isInContact = true; + + wheel.m_raycastInfo.m_groundObject = &s_fixedObject;//todo for driving on dynamic/movable objects!; + //wheel.m_raycastInfo.m_groundObject = object; + + + btScalar hitDistance = param*raylen; + wheel.m_raycastInfo.m_suspensionLength = hitDistance - wheel.m_wheelsRadius; + //clamp on max suspension travel + + btScalar minSuspensionLength = wheel.getSuspensionRestLength() - wheel.m_maxSuspensionTravelCm*btScalar(0.01); + btScalar maxSuspensionLength = wheel.getSuspensionRestLength()+ wheel.m_maxSuspensionTravelCm*btScalar(0.01); + if (wheel.m_raycastInfo.m_suspensionLength < minSuspensionLength) + { + wheel.m_raycastInfo.m_suspensionLength = minSuspensionLength; + } + if (wheel.m_raycastInfo.m_suspensionLength > maxSuspensionLength) + { + wheel.m_raycastInfo.m_suspensionLength = maxSuspensionLength; + } + + wheel.m_raycastInfo.m_contactPointWS = rayResults.m_hitPointInWorld; + + btScalar denominator= wheel.m_raycastInfo.m_contactNormalWS.dot( wheel.m_raycastInfo.m_wheelDirectionWS ); + + btVector3 chassis_velocity_at_contactPoint; + btVector3 relpos = wheel.m_raycastInfo.m_contactPointWS-getRigidBody()->getCenterOfMassPosition(); + + chassis_velocity_at_contactPoint = getRigidBody()->getVelocityInLocalPoint(relpos); + + btScalar projVel = wheel.m_raycastInfo.m_contactNormalWS.dot( chassis_velocity_at_contactPoint ); + + if ( denominator >= btScalar(-0.1)) + { + wheel.m_suspensionRelativeVelocity = btScalar(0.0); + wheel.m_clippedInvContactDotSuspension = btScalar(1.0) / btScalar(0.1); + } + else + { + btScalar inv = btScalar(-1.) / denominator; + wheel.m_suspensionRelativeVelocity = projVel * inv; + wheel.m_clippedInvContactDotSuspension = inv; + } + + } else + { + //put wheel info as in rest position + wheel.m_raycastInfo.m_suspensionLength = wheel.getSuspensionRestLength(); + wheel.m_suspensionRelativeVelocity = btScalar(0.0); + wheel.m_raycastInfo.m_contactNormalWS = - wheel.m_raycastInfo.m_wheelDirectionWS; + wheel.m_clippedInvContactDotSuspension = btScalar(1.0); + } + + return depth; +} + + +const btTransform& btRaycastVehicle::getChassisWorldTransform() const +{ + /*if (getRigidBody()->getMotionState()) + { + btTransform chassisWorldTrans; + getRigidBody()->getMotionState()->getWorldTransform(chassisWorldTrans); + return chassisWorldTrans; + } + */ + + + return getRigidBody()->getCenterOfMassTransform(); +} + + +void btRaycastVehicle::updateVehicle( btScalar step ) +{ + { + for (int i=0;igetLinearVelocity().length(); + + const btTransform& chassisTrans = getChassisWorldTransform(); + + btVector3 forwardW ( + chassisTrans.getBasis()[0][m_indexForwardAxis], + chassisTrans.getBasis()[1][m_indexForwardAxis], + chassisTrans.getBasis()[2][m_indexForwardAxis]); + + if (forwardW.dot(getRigidBody()->getLinearVelocity()) < btScalar(0.)) + { + m_currentVehicleSpeedKmHour *= btScalar(-1.); + } + + // + // simulate suspension + // + + int i=0; + for (i=0;i gMaxSuspensionForce) + { + suspensionForce = gMaxSuspensionForce; + } + btVector3 impulse = wheel.m_raycastInfo.m_contactNormalWS * suspensionForce * step; + btVector3 relpos = wheel.m_raycastInfo.m_contactPointWS - getRigidBody()->getCenterOfMassPosition(); + + getRigidBody()->applyImpulse(impulse, relpos); + + } + + + + updateFriction( step); + + + for (i=0;igetCenterOfMassPosition(); + btVector3 vel = getRigidBody()->getVelocityInLocalPoint( relpos ); + + if (wheel.m_raycastInfo.m_isInContact) + { + const btTransform& chassisWorldTransform = getChassisWorldTransform(); + + btVector3 fwd ( + chassisWorldTransform.getBasis()[0][m_indexForwardAxis], + chassisWorldTransform.getBasis()[1][m_indexForwardAxis], + chassisWorldTransform.getBasis()[2][m_indexForwardAxis]); + + btScalar proj = fwd.dot(wheel.m_raycastInfo.m_contactNormalWS); + fwd -= wheel.m_raycastInfo.m_contactNormalWS * proj; + + btScalar proj2 = fwd.dot(vel); + + wheel.m_deltaRotation = (proj2 * step) / (wheel.m_wheelsRadius); + wheel.m_rotation += wheel.m_deltaRotation; + + } else + { + wheel.m_rotation += wheel.m_deltaRotation; + } + + wheel.m_deltaRotation *= btScalar(0.99);//damping of rotation when not in contact + + } + + + +} + + +void btRaycastVehicle::setSteeringValue(btScalar steering,int wheel) +{ + assert(wheel>=0 && wheel < getNumWheels()); + + btWheelInfo& wheelInfo = getWheelInfo(wheel); + wheelInfo.m_steering = steering; +} + + + +btScalar btRaycastVehicle::getSteeringValue(int wheel) const +{ + return getWheelInfo(wheel).m_steering; +} + + +void btRaycastVehicle::applyEngineForce(btScalar force, int wheel) +{ + assert(wheel>=0 && wheel < getNumWheels()); + btWheelInfo& wheelInfo = getWheelInfo(wheel); + wheelInfo.m_engineForce = force; +} + + +const btWheelInfo& btRaycastVehicle::getWheelInfo(int index) const +{ + btAssert((index >= 0) && (index < getNumWheels())); + + return m_wheelInfo[index]; +} + +btWheelInfo& btRaycastVehicle::getWheelInfo(int index) +{ + btAssert((index >= 0) && (index < getNumWheels())); + + return m_wheelInfo[index]; +} + +void btRaycastVehicle::setBrake(btScalar brake,int wheelIndex) +{ + btAssert((wheelIndex >= 0) && (wheelIndex < getNumWheels())); + getWheelInfo(wheelIndex).m_brake = brake; +} + + +void btRaycastVehicle::updateSuspension(btScalar deltaTime) +{ + (void)deltaTime; + + btScalar chassisMass = btScalar(1.) / m_chassisBody->getInvMass(); + + for (int w_it=0; w_itcomputeImpulseDenominator(frictionPosWorld,frictionDirectionWorld); + btScalar denom1 = body1->computeImpulseDenominator(frictionPosWorld,frictionDirectionWorld); + btScalar relaxation = 1.f; + m_jacDiagABInv = relaxation/(denom0+denom1); + } + + + +}; + +btScalar calcRollingFriction(btWheelContactPoint& contactPoint) +{ + + btScalar j1=0.f; + + const btVector3& contactPosWorld = contactPoint.m_frictionPositionWorld; + + btVector3 rel_pos1 = contactPosWorld - contactPoint.m_body0->getCenterOfMassPosition(); + btVector3 rel_pos2 = contactPosWorld - contactPoint.m_body1->getCenterOfMassPosition(); + + btScalar maxImpulse = contactPoint.m_maxImpulse; + + btVector3 vel1 = contactPoint.m_body0->getVelocityInLocalPoint(rel_pos1); + btVector3 vel2 = contactPoint.m_body1->getVelocityInLocalPoint(rel_pos2); + btVector3 vel = vel1 - vel2; + + btScalar vrel = contactPoint.m_frictionDirectionWorld.dot(vel); + + // calculate j that moves us to zero relative velocity + j1 = -vrel * contactPoint.m_jacDiagABInv; + GEN_set_min(j1, maxImpulse); + GEN_set_max(j1, -maxImpulse); + + return j1; +} + + + + +btScalar sideFrictionStiffness2 = btScalar(1.0); +void btRaycastVehicle::updateFriction(btScalar timeStep) +{ + + //calculate the impulse, so that the wheels don't move sidewards + int numWheel = getNumWheels(); + if (!numWheel) + return; + + + btVector3* forwardWS = new btVector3[numWheel]; + btVector3* axle = new btVector3[numWheel]; + btScalar* forwardImpulse = new btScalar[numWheel]; + btScalar* sideImpulse = new btScalar[numWheel]; + + int numWheelsOnGround = 0; + + + //collapse all those loops into one! + for (int i=0;i maximpSquared) + { + sliding = true; + + btScalar factor = maximp / btSqrt(impulseSquared); + + m_wheelInfo[wheel].m_skidInfo *= factor; + } + } + + } + } + + + + + if (sliding) + { + for (int wheel = 0;wheel < getNumWheels(); wheel++) + { + if (sideImpulse[wheel] != btScalar(0.)) + { + if (m_wheelInfo[wheel].m_skidInfo< btScalar(1.)) + { + forwardImpulse[wheel] *= m_wheelInfo[wheel].m_skidInfo; + sideImpulse[wheel] *= m_wheelInfo[wheel].m_skidInfo; + } + } + } + } + + // apply the impulses + { + for (int wheel = 0;wheelgetCenterOfMassPosition(); + + if (forwardImpulse[wheel] != btScalar(0.)) + { + m_chassisBody->applyImpulse(forwardWS[wheel]*(forwardImpulse[wheel]),rel_pos); + } + if (sideImpulse[wheel] != btScalar(0.)) + { + class btRigidBody* groundObject = (class btRigidBody*) m_wheelInfo[wheel].m_raycastInfo.m_groundObject; + + btVector3 rel_pos2 = wheelInfo.m_raycastInfo.m_contactPointWS - + groundObject->getCenterOfMassPosition(); + + + btVector3 sideImp = axle[wheel] * sideImpulse[wheel]; + + rel_pos[2] *= wheelInfo.m_rollInfluence; + m_chassisBody->applyImpulse(sideImp,rel_pos); + + //apply friction impulse on the ground + groundObject->applyImpulse(-sideImp,rel_pos2); + } + } + } + + delete []forwardWS; + delete [] axle; + delete[]forwardImpulse; + delete[] sideImpulse; +} + + +void* btDefaultVehicleRaycaster::castRay(const btVector3& from,const btVector3& to, btVehicleRaycasterResult& result) +{ +// RayResultCallback& resultCallback; + + btCollisionWorld::ClosestRayResultCallback rayCallback(from,to); + + m_dynamicsWorld->rayTest(from, to, rayCallback); + + if (rayCallback.HasHit()) + { + + btRigidBody* body = btRigidBody::upcast(rayCallback.m_collisionObject); + if (body) + { + result.m_hitPointInWorld = rayCallback.m_hitPointWorld; + result.m_hitNormalInWorld = rayCallback.m_hitNormalWorld; + result.m_hitNormalInWorld.normalize(); + result.m_distFraction = rayCallback.m_closestHitFraction; + return body; + } + } + return 0; +} diff --git a/extern/bullet2/src/BulletDynamics/Vehicle/btRaycastVehicle.h b/extern/bullet2/src/BulletDynamics/Vehicle/btRaycastVehicle.h new file mode 100644 index 00000000000..f4249599615 --- /dev/null +++ b/extern/bullet2/src/BulletDynamics/Vehicle/btRaycastVehicle.h @@ -0,0 +1,201 @@ +/* + * Copyright (c) 2005 Erwin Coumans http://continuousphysics.com/Bullet/ + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies. + * Erwin Coumans makes no representations about the suitability + * of this software for any purpose. + * It is provided "as is" without express or implied warranty. +*/ +#ifndef RAYCASTVEHICLE_H +#define RAYCASTVEHICLE_H + +#include "../Dynamics/btRigidBody.h" +#include "../ConstraintSolver/btTypedConstraint.h" +#include "btVehicleRaycaster.h" +class btDynamicsWorld; +#include "../../LinearMath/btAlignedObjectArray.h" +#include "btWheelInfo.h" + +class btVehicleTuning; + +///rayCast vehicle, very special constraint that turn a rigidbody into a vehicle. +class btRaycastVehicle : public btTypedConstraint +{ +public: + class btVehicleTuning + { + public: + + btVehicleTuning() + :m_suspensionStiffness(btScalar(5.88)), + m_suspensionCompression(btScalar(0.83)), + m_suspensionDamping(btScalar(0.88)), + m_maxSuspensionTravelCm(btScalar(500.)), + m_frictionSlip(btScalar(10.5)) + { + } + btScalar m_suspensionStiffness; + btScalar m_suspensionCompression; + btScalar m_suspensionDamping; + btScalar m_maxSuspensionTravelCm; + btScalar m_frictionSlip; + + }; +private: + + btScalar m_tau; + btScalar m_damping; + btVehicleRaycaster* m_vehicleRaycaster; + btScalar m_pitchControl; + btScalar m_steeringValue; + btScalar m_currentVehicleSpeedKmHour; + + btRigidBody* m_chassisBody; + + int m_indexRightAxis; + int m_indexUpAxis; + int m_indexForwardAxis; + + void defaultInit(const btVehicleTuning& tuning); + +public: + + //constructor to create a car from an existing rigidbody + btRaycastVehicle(const btVehicleTuning& tuning,btRigidBody* chassis, btVehicleRaycaster* raycaster ); + + virtual ~btRaycastVehicle() ; + + + const btTransform& getChassisWorldTransform() const; + + btScalar rayCast(btWheelInfo& wheel); + + virtual void updateVehicle(btScalar step); + + void resetSuspension(); + + btScalar getSteeringValue(int wheel) const; + + void setSteeringValue(btScalar steering,int wheel); + + + void applyEngineForce(btScalar force, int wheel); + + const btTransform& getWheelTransformWS( int wheelIndex ) const; + + void updateWheelTransform( int wheelIndex, bool interpolatedTransform = true ); + + void setRaycastWheelInfo( int wheelIndex , bool isInContact, const btVector3& hitPoint, const btVector3& hitNormal,btScalar depth); + + btWheelInfo& addWheel( const btVector3& connectionPointCS0, const btVector3& wheelDirectionCS0,const btVector3& wheelAxleCS,btScalar suspensionRestLength,btScalar wheelRadius,const btVehicleTuning& tuning, bool isFrontWheel); + + inline int getNumWheels() const { + return int (m_wheelInfo.size()); + } + + btAlignedObjectArray m_wheelInfo; + + + const btWheelInfo& getWheelInfo(int index) const; + + btWheelInfo& getWheelInfo(int index); + + void updateWheelTransformsWS(btWheelInfo& wheel , bool interpolatedTransform = true); + + + void setBrake(btScalar brake,int wheelIndex); + + void setPitchControl(btScalar pitch) + { + m_pitchControl = pitch; + } + + void updateSuspension(btScalar deltaTime); + + void updateFriction(btScalar timeStep); + + + + inline btRigidBody* getRigidBody() + { + return m_chassisBody; + } + + const btRigidBody* getRigidBody() const + { + return m_chassisBody; + } + + inline int getRightAxis() const + { + return m_indexRightAxis; + } + inline int getUpAxis() const + { + return m_indexUpAxis; + } + + inline int getForwardAxis() const + { + return m_indexForwardAxis; + } + + + ///Worldspace forward vector + btVector3 getForwardVector() const + { + const btTransform& chassisTrans = getChassisWorldTransform(); + + btVector3 forwardW ( + chassisTrans.getBasis()[0][m_indexForwardAxis], + chassisTrans.getBasis()[1][m_indexForwardAxis], + chassisTrans.getBasis()[2][m_indexForwardAxis]); + + return forwardW; + } + + ///Velocity of vehicle (positive if velocity vector has same direction as foward vector) + btScalar getCurrentSpeedKmHour() const + { + return m_currentVehicleSpeedKmHour; + } + + virtual void setCoordinateSystem(int rightIndex,int upIndex,int forwardIndex) + { + m_indexRightAxis = rightIndex; + m_indexUpAxis = upIndex; + m_indexForwardAxis = forwardIndex; + } + + virtual void buildJacobian() + { + //not yet + } + + virtual void solveConstraint(btScalar timeStep) + { + (void)timeStep; + //not yet + } + + +}; + +class btDefaultVehicleRaycaster : public btVehicleRaycaster +{ + btDynamicsWorld* m_dynamicsWorld; +public: + btDefaultVehicleRaycaster(btDynamicsWorld* world) + :m_dynamicsWorld(world) + { + } + + virtual void* castRay(const btVector3& from,const btVector3& to, btVehicleRaycasterResult& result); + +}; + + +#endif //RAYCASTVEHICLE_H + diff --git a/extern/bullet2/src/BulletDynamics/Vehicle/btVehicleRaycaster.h b/extern/bullet2/src/BulletDynamics/Vehicle/btVehicleRaycaster.h new file mode 100644 index 00000000000..64a47fcaada --- /dev/null +++ b/extern/bullet2/src/BulletDynamics/Vehicle/btVehicleRaycaster.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2005 Erwin Coumans http://continuousphysics.com/Bullet/ + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies. + * Erwin Coumans makes no representations about the suitability + * of this software for any purpose. + * It is provided "as is" without express or implied warranty. +*/ +#ifndef VEHICLE_RAYCASTER_H +#define VEHICLE_RAYCASTER_H + +#include "../../LinearMath/btVector3.h" + +/// btVehicleRaycaster is provides interface for between vehicle simulation and raycasting +struct btVehicleRaycaster +{ +virtual ~btVehicleRaycaster() +{ +} + struct btVehicleRaycasterResult + { + btVehicleRaycasterResult() :m_distFraction(btScalar(-1.)){}; + btVector3 m_hitPointInWorld; + btVector3 m_hitNormalInWorld; + btScalar m_distFraction; + }; + + virtual void* castRay(const btVector3& from,const btVector3& to, btVehicleRaycasterResult& result) = 0; + +}; + +#endif //VEHICLE_RAYCASTER_H + diff --git a/extern/bullet2/src/BulletDynamics/Vehicle/btWheelInfo.cpp b/extern/bullet2/src/BulletDynamics/Vehicle/btWheelInfo.cpp new file mode 100644 index 00000000000..ef93c16fffc --- /dev/null +++ b/extern/bullet2/src/BulletDynamics/Vehicle/btWheelInfo.cpp @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2005 Erwin Coumans http://continuousphysics.com/Bullet/ + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies. + * Erwin Coumans makes no representations about the suitability + * of this software for any purpose. + * It is provided "as is" without express or implied warranty. +*/ +#include "btWheelInfo.h" +#include "BulletDynamics/Dynamics/btRigidBody.h" // for pointvelocity + + +btScalar btWheelInfo::getSuspensionRestLength() const +{ + + return m_suspensionRestLength1; + +} + +void btWheelInfo::updateWheel(const btRigidBody& chassis,RaycastInfo& raycastInfo) +{ + (void)raycastInfo; + + + if (m_raycastInfo.m_isInContact) + + { + btScalar project= m_raycastInfo.m_contactNormalWS.dot( m_raycastInfo.m_wheelDirectionWS ); + btVector3 chassis_velocity_at_contactPoint; + btVector3 relpos = m_raycastInfo.m_contactPointWS - chassis.getCenterOfMassPosition(); + chassis_velocity_at_contactPoint = chassis.getVelocityInLocalPoint( relpos ); + btScalar projVel = m_raycastInfo.m_contactNormalWS.dot( chassis_velocity_at_contactPoint ); + if ( project >= btScalar(-0.1)) + { + m_suspensionRelativeVelocity = btScalar(0.0); + m_clippedInvContactDotSuspension = btScalar(1.0) / btScalar(0.1); + } + else + { + btScalar inv = btScalar(-1.) / project; + m_suspensionRelativeVelocity = projVel * inv; + m_clippedInvContactDotSuspension = inv; + } + + } + + else // Not in contact : position wheel in a nice (rest length) position + { + m_raycastInfo.m_suspensionLength = this->getSuspensionRestLength(); + m_suspensionRelativeVelocity = btScalar(0.0); + m_raycastInfo.m_contactNormalWS = -m_raycastInfo.m_wheelDirectionWS; + m_clippedInvContactDotSuspension = btScalar(1.0); + } +} diff --git a/extern/bullet2/src/BulletDynamics/Vehicle/btWheelInfo.h b/extern/bullet2/src/BulletDynamics/Vehicle/btWheelInfo.h new file mode 100644 index 00000000000..2e349b3fde4 --- /dev/null +++ b/extern/bullet2/src/BulletDynamics/Vehicle/btWheelInfo.h @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2005 Erwin Coumans http://continuousphysics.com/Bullet/ + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies. + * Erwin Coumans makes no representations about the suitability + * of this software for any purpose. + * It is provided "as is" without express or implied warranty. +*/ +#ifndef WHEEL_INFO_H +#define WHEEL_INFO_H + +#include "../../LinearMath/btVector3.h" +#include "../../LinearMath/btTransform.h" + +class btRigidBody; + +struct btWheelInfoConstructionInfo +{ + btVector3 m_chassisConnectionCS; + btVector3 m_wheelDirectionCS; + btVector3 m_wheelAxleCS; + btScalar m_suspensionRestLength; + btScalar m_maxSuspensionTravelCm; + btScalar m_wheelRadius; + + btScalar m_suspensionStiffness; + btScalar m_wheelsDampingCompression; + btScalar m_wheelsDampingRelaxation; + btScalar m_frictionSlip; + bool m_bIsFrontWheel; + +}; + +/// btWheelInfo contains information per wheel about friction and suspension. +struct btWheelInfo +{ + struct RaycastInfo + { + //set by raycaster + btVector3 m_contactNormalWS;//contactnormal + btVector3 m_contactPointWS;//raycast hitpoint + btScalar m_suspensionLength; + btVector3 m_hardPointWS;//raycast starting point + btVector3 m_wheelDirectionWS; //direction in worldspace + btVector3 m_wheelAxleWS; // axle in worldspace + bool m_isInContact; + void* m_groundObject; //could be general void* ptr + }; + + RaycastInfo m_raycastInfo; + + btTransform m_worldTransform; + + btVector3 m_chassisConnectionPointCS; //const + btVector3 m_wheelDirectionCS;//const + btVector3 m_wheelAxleCS; // const or modified by steering + btScalar m_suspensionRestLength1;//const + btScalar m_maxSuspensionTravelCm; + btScalar getSuspensionRestLength() const; + btScalar m_wheelsRadius;//const + btScalar m_suspensionStiffness;//const + btScalar m_wheelsDampingCompression;//const + btScalar m_wheelsDampingRelaxation;//const + btScalar m_frictionSlip; + btScalar m_steering; + btScalar m_rotation; + btScalar m_deltaRotation; + btScalar m_rollInfluence; + + btScalar m_engineForce; + + btScalar m_brake; + + bool m_bIsFrontWheel; + + void* m_clientInfo;//can be used to store pointer to sync transforms... + + btWheelInfo(btWheelInfoConstructionInfo& ci) + + { + + m_suspensionRestLength1 = ci.m_suspensionRestLength; + m_maxSuspensionTravelCm = ci.m_maxSuspensionTravelCm; + + m_wheelsRadius = ci.m_wheelRadius; + m_suspensionStiffness = ci.m_suspensionStiffness; + m_wheelsDampingCompression = ci.m_wheelsDampingCompression; + m_wheelsDampingRelaxation = ci.m_wheelsDampingRelaxation; + m_chassisConnectionPointCS = ci.m_chassisConnectionCS; + m_wheelDirectionCS = ci.m_wheelDirectionCS; + m_wheelAxleCS = ci.m_wheelAxleCS; + m_frictionSlip = ci.m_frictionSlip; + m_steering = btScalar(0.); + m_engineForce = btScalar(0.); + m_rotation = btScalar(0.); + m_deltaRotation = btScalar(0.); + m_brake = btScalar(0.); + m_rollInfluence = btScalar(0.1); + m_bIsFrontWheel = ci.m_bIsFrontWheel; + + } + + void updateWheel(const btRigidBody& chassis,RaycastInfo& raycastInfo); + + btScalar m_clippedInvContactDotSuspension; + btScalar m_suspensionRelativeVelocity; + //calculated by suspension + btScalar m_wheelsSuspensionForce; + btScalar m_skidInfo; + +}; + +#endif //WHEEL_INFO_H + diff --git a/extern/bullet2/src/CMakeLists.txt b/extern/bullet2/src/CMakeLists.txt new file mode 100644 index 00000000000..0ae1a7ab6ab --- /dev/null +++ b/extern/bullet2/src/CMakeLists.txt @@ -0,0 +1 @@ +SUBDIRS( BulletCollision BulletDynamics LinearMath ) diff --git a/extern/bullet2/src/LinearMath/CMakeLists.txt b/extern/bullet2/src/LinearMath/CMakeLists.txt new file mode 100644 index 00000000000..207eed94a3e --- /dev/null +++ b/extern/bullet2/src/LinearMath/CMakeLists.txt @@ -0,0 +1,10 @@ + +INCLUDE_DIRECTORIES( +${BULLET_PHYSICS_SOURCE_DIR}/src } +) + +ADD_LIBRARY(LibLinearMath +btQuickprof.cpp +btGeometryUtil.cpp +) + diff --git a/extern/bullet2/src/LinearMath/btAabbUtil2.h b/extern/bullet2/src/LinearMath/btAabbUtil2.h new file mode 100644 index 00000000000..429163c8138 --- /dev/null +++ b/extern/bullet2/src/LinearMath/btAabbUtil2.h @@ -0,0 +1,127 @@ +/* +Copyright (c) 2003-2006 Gino van den Bergen / 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 AABB_UTIL2 +#define AABB_UTIL2 + +#include "btVector3.h" +#include "btSimdMinMax.h" + + +#define btMin(a,b) ((a < b ? a : b)) +#define btMax(a,b) ((a > b ? a : b)) + + +/// conservative test for overlap between two aabbs +SIMD_FORCE_INLINE bool TestAabbAgainstAabb2(const btVector3 &aabbMin1, const btVector3 &aabbMax1, + const btVector3 &aabbMin2, const btVector3 &aabbMax2) +{ + bool overlap = true; + overlap = (aabbMin1[0] > aabbMax2[0] || aabbMax1[0] < aabbMin2[0]) ? false : overlap; + overlap = (aabbMin1[2] > aabbMax2[2] || aabbMax1[2] < aabbMin2[2]) ? false : overlap; + overlap = (aabbMin1[1] > aabbMax2[1] || aabbMax1[1] < aabbMin2[1]) ? false : overlap; + return overlap; +} + +/// conservative test for overlap between triangle and aabb +SIMD_FORCE_INLINE bool TestTriangleAgainstAabb2(const btVector3 *vertices, + const btVector3 &aabbMin, const btVector3 &aabbMax) +{ + const btVector3 &p1 = vertices[0]; + const btVector3 &p2 = vertices[1]; + const btVector3 &p3 = vertices[2]; + + if (btMin(btMin(p1[0], p2[0]), p3[0]) > aabbMax[0]) return false; + if (btMax(btMax(p1[0], p2[0]), p3[0]) < aabbMin[0]) return false; + + if (btMin(btMin(p1[2], p2[2]), p3[2]) > aabbMax[2]) return false; + if (btMax(btMax(p1[2], p2[2]), p3[2]) < aabbMin[2]) return false; + + if (btMin(btMin(p1[1], p2[1]), p3[1]) > aabbMax[1]) return false; + if (btMax(btMax(p1[1], p2[1]), p3[1]) < aabbMin[1]) return false; + return true; +} + + +SIMD_FORCE_INLINE int btOutcode(const btVector3& p,const btVector3& halfExtent) +{ + return (p.getX() < -halfExtent.getX() ? 0x01 : 0x0) | + (p.getX() > halfExtent.getX() ? 0x08 : 0x0) | + (p.getY() < -halfExtent.getY() ? 0x02 : 0x0) | + (p.getY() > halfExtent.getY() ? 0x10 : 0x0) | + (p.getZ() < -halfExtent.getZ() ? 0x4 : 0x0) | + (p.getZ() > halfExtent.getZ() ? 0x20 : 0x0); +} + + +SIMD_FORCE_INLINE bool btRayAabb(const btVector3& rayFrom, + const btVector3& rayTo, + const btVector3& aabbMin, + const btVector3& aabbMax, + btScalar& param, btVector3& normal) +{ + btVector3 aabbHalfExtent = (aabbMax-aabbMin)* btScalar(0.5); + btVector3 aabbCenter = (aabbMax+aabbMin)* btScalar(0.5); + btVector3 source = rayFrom - aabbCenter; + btVector3 target = rayTo - aabbCenter; + int sourceOutcode = btOutcode(source,aabbHalfExtent); + int targetOutcode = btOutcode(target,aabbHalfExtent); + if ((sourceOutcode & targetOutcode) == 0x0) + { + btScalar lambda_enter = btScalar(0.0); + btScalar lambda_exit = param; + btVector3 r = target - source; + int i; + btScalar normSign = 1; + btVector3 hitNormal(0,0,0); + int bit=1; + + for (int j=0;j<2;j++) + { + for (i = 0; i != 3; ++i) + { + if (sourceOutcode & bit) + { + btScalar lambda = (-source[i] - aabbHalfExtent[i]*normSign) / r[i]; + if (lambda_enter <= lambda) + { + lambda_enter = lambda; + hitNormal.setValue(0,0,0); + hitNormal[i] = normSign; + } + } + else if (targetOutcode & bit) + { + btScalar lambda = (-source[i] - aabbHalfExtent[i]*normSign) / r[i]; + btSetMin(lambda_exit, lambda); + } + bit<<=1; + } + normSign = btScalar(-1.); + } + if (lambda_enter <= lambda_exit) + { + param = lambda_enter; + normal = hitNormal; + return true; + } + } + return false; +} + + +#endif + diff --git a/extern/bullet2/src/LinearMath/btAlignedAllocator.cpp b/extern/bullet2/src/LinearMath/btAlignedAllocator.cpp new file mode 100644 index 00000000000..1f5877fa37e --- /dev/null +++ b/extern/bullet2/src/LinearMath/btAlignedAllocator.cpp @@ -0,0 +1,70 @@ +/* +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 "btAlignedAllocator.h" + + +#if defined (BT_HAS_ALIGNED_ALOCATOR) + +#include +void* btAlignedAlloc (int size, int alignment) +{ + return _aligned_malloc(size,alignment); +} + +void btAlignedFree (void* ptr) +{ + _aligned_free(ptr); +} + +#else + +#ifdef __CELLOS_LV2__ + +#include + +int numAllocs = 0; +int numFree = 0; + +void* btAlignedAlloc (int size, int alignment) +{ + numAllocs++; + return memalign(alignment, size); +} + +void btAlignedFree (void* ptr) +{ + numFree++; + free(ptr); +} + +#else +///todo +///will add some multi-platform version that works without _aligned_malloc/_aligned_free + +void* btAlignedAlloc (int size, int alignment) +{ + return new char[size]; +} + +void btAlignedFree (void* ptr) +{ + delete [] (char*) ptr; +} +#endif // + +#endif + + diff --git a/extern/bullet2/src/LinearMath/btAlignedAllocator.h b/extern/bullet2/src/LinearMath/btAlignedAllocator.h new file mode 100644 index 00000000000..07585717f45 --- /dev/null +++ b/extern/bullet2/src/LinearMath/btAlignedAllocator.h @@ -0,0 +1,80 @@ +/* +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 BT_ALIGNED_ALLOCATOR +#define BT_ALIGNED_ALLOCATOR + +///we probably replace this with our own aligned memory allocator +///so we replace _aligned_malloc and _aligned_free with our own +///that is better portable and more predictable + +#include "btScalar.h" + +void* btAlignedAlloc (int size, int alignment); + +void btAlignedFree (void* ptr); + + +typedef int size_type; + + +template < typename T , unsigned Alignment > +class btAlignedAllocator { + + typedef btAlignedAllocator< T , Alignment > self_type; + +public: + + //just going down a list: + btAlignedAllocator() {} + /* + btAlignedAllocator( const self_type & ) {} + */ + + template < typename Other > + btAlignedAllocator( const btAlignedAllocator< Other , Alignment > & ) {} + + typedef const T* const_pointer; + typedef const T& const_reference; + typedef T* pointer; + typedef T& reference; + typedef T value_type; + + pointer address ( reference ref ) const { return &ref; } + const_pointer address ( const_reference ref ) const { return &ref; } + pointer allocate ( size_type n , const_pointer * hint = 0 ) { + (void)hint; + return reinterpret_cast< pointer >(btAlignedAlloc( sizeof(value_type) * n , Alignment )); + } + void construct ( pointer ptr , const value_type & value ) { new (ptr) value_type( value ); } + void deallocate( pointer ptr ) { + btAlignedFree( reinterpret_cast< void * >( ptr ) ); + } + void destroy ( pointer ptr ) { ptr->~value_type(); } + + + template < typename O > struct rebind { + typedef btAlignedAllocator< O , Alignment > other; + }; + template < typename O > + self_type & operator=( const btAlignedAllocator< O , Alignment > & ) { return *this; } + + friend bool operator==( const self_type & , const self_type & ) { return true; } +}; + + + +#endif //BT_ALIGNED_ALLOCATOR + diff --git a/extern/bullet2/src/LinearMath/btAlignedObjectArray.h b/extern/bullet2/src/LinearMath/btAlignedObjectArray.h new file mode 100644 index 00000000000..8bef5eb5d06 --- /dev/null +++ b/extern/bullet2/src/LinearMath/btAlignedObjectArray.h @@ -0,0 +1,367 @@ +/* +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 BT_OBJECT_ARRAY__ +#define BT_OBJECT_ARRAY__ + +#include "btScalar.h" // has definitions like SIMD_FORCE_INLINE +#include "btAlignedAllocator.h" + +///If the platform doesn't support placement new, you can disable BT_USE_PLACEMENT_NEW +///then the btAlignedObjectArray doesn't support objects with virtual methods, and non-trivial constructors/destructors +///You can enable BT_USE_MEMCPY, then swapping elements in the array will use memcpy instead of operator= +///see discussion here: http://continuousphysics.com/Bullet/phpBB2/viewtopic.php?t=1231 and +///http://www.continuousphysics.com/Bullet/phpBB2/viewtopic.php?t=1240 + +#define BT_USE_PLACEMENT_NEW 1 +//#define BT_USE_MEMCPY 1 //disable, because it is cumbersome to find out for each platform where memcpy is defined. It can be in or or otherwise... + +#ifdef BT_USE_MEMCPY +#include +#include +#endif //BT_USE_MEMCPY + +#ifdef BT_USE_PLACEMENT_NEW +#include //for placement new +#endif //BT_USE_PLACEMENT_NEW + + +///btAlignedObjectArray uses a subset of the stl::vector interface for its methods +///It is developed to replace stl::vector to avoid STL alignment issues to add SIMD/SSE data +template +//template +class btAlignedObjectArray +{ + btAlignedAllocator m_allocator; + + int m_size; + int m_capacity; + T* m_data; + + protected: + SIMD_FORCE_INLINE int allocSize(int size) + { + return (size ? size*2 : 1); + } + SIMD_FORCE_INLINE void copy(int start,int end, T* dest) + { + int i; + for (i=start;i size()) + { + reserve(newsize); + } +#ifdef BT_USE_PLACEMENT_NEW + for (int i=curSize;i + void downHeap(T *pArr, int k, int n,L CompareFunc) + { + /* PRE: a[k+1..N] is a heap */ + /* POST: a[k..N] is a heap */ + + T temp = pArr[k - 1]; + /* k has child(s) */ + while (k <= n/2) + { + int child = 2*k; + + if ((child < n) && CompareFunc(pArr[child - 1] , pArr[child])) + { + child++; + } + /* pick larger child */ + if (CompareFunc(temp , pArr[child - 1])) + { + /* move child up */ + pArr[k - 1] = pArr[child - 1]; + k = child; + } + else + { + break; + } + } + pArr[k - 1] = temp; + } /*downHeap*/ + + void swap(int index0,int index1) + { +#ifdef BT_USE_MEMCPY + char temp[sizeof(T)]; + memcpy(temp,&m_data[index0],sizeof(T)); + memcpy(&m_data[index0],&m_data[index1],sizeof(T)); + memcpy(&m_data[index1],temp,sizeof(T)); +#else + T temp = m_data[index0]; + m_data[index0] = m_data[index1]; + m_data[index1] = temp; +#endif //BT_USE_PLACEMENT_NEW + + } + + template + void heapSort(L CompareFunc) + { + /* sort a[0..N-1], N.B. 0 to N-1 */ + int k; + int n = m_size; + for (k = n/2; k > 0; k--) + { + downHeap(m_data, k, n, CompareFunc); + } + + /* a[1..N] is now a heap */ + while ( n>=1 ) + { + swap(0,n-1); /* largest of a[0..n-1] */ + + + n = n - 1; + /* restore a[1..i-1] heap */ + downHeap(m_data, 1, n, CompareFunc); + } + } + + ///non-recursive binary search, assumes sorted array + int findBinarySearch(const T& key) const + { + int first = 0; + int last = size(); + + //assume sorted array + while (first <= last) { + int mid = (first + last) / 2; // compute mid point. + if (key > m_data[mid]) + first = mid + 1; // repeat search in top half. + else if (key < m_data[mid]) + last = mid - 1; // repeat search in bottom half. + else + return mid; // found it. return position ///// + } + return size(); // failed to find key + } + + + int findLinearSearch(const T& key) const + { + int index=size(); + int i; + + for (i=0;i& planeEquations, const btVector3& point, btScalar margin) +{ + int numbrushes = planeEquations.size(); + for (int i=0;ibtScalar(0.)) + { + return false; + } + } + return true; + +} + + +bool btGeometryUtil::areVerticesBehindPlane(const btVector3& planeNormal, const btAlignedObjectArray& vertices, btScalar margin) +{ + int numvertices = vertices.size(); + for (int i=0;ibtScalar(0.)) + { + return false; + } + } + return true; +} + +bool notExist(const btVector3& planeEquation,const btAlignedObjectArray& planeEquations) +{ + int numbrushes = planeEquations.size(); + for (int i=0;i btScalar(0.999)) + { + return false; + } + } + return true; +} + +void btGeometryUtil::getPlaneEquationsFromVertices(btAlignedObjectArray& vertices, btAlignedObjectArray& planeEquationsOut ) +{ + const int numvertices = vertices.size(); + // brute force: + for (int i=0;i btScalar(0.0001)) + { + planeEquation.normalize(); + if (notExist(planeEquation,planeEquationsOut)) + { + planeEquation[3] = -planeEquation.dot(N1); + + //check if inside, and replace supportingVertexOut if needed + if (areVerticesBehindPlane(planeEquation,vertices,btScalar(0.01))) + { + planeEquationsOut.push_back(planeEquation); + } + } + } + normalSign = btScalar(-1.); + } + + } + } + } + +} + +void btGeometryUtil::getVerticesFromPlaneEquations(const btAlignedObjectArray& planeEquations , btAlignedObjectArray& verticesOut ) +{ + const int numbrushes = planeEquations.size(); + // brute force: + for (int i=0;i btScalar(0.0001) ) && + ( n3n1.length2() > btScalar(0.0001) ) && + ( n1n2.length2() > btScalar(0.0001) ) ) + { + //point P out of 3 plane equations: + + // d1 ( N2 * N3 ) + d2 ( N3 * N1 ) + d3 ( N1 * N2 ) + //P = ------------------------------------------------------------------------- + // N1 . ( N2 * N3 ) + + + btScalar quotient = (N1.dot(n2n3)); + if (btFabs(quotient) > btScalar(0.000001)) + { + quotient = btScalar(-1.) / quotient; + n2n3 *= N1[3]; + n3n1 *= N2[3]; + n1n2 *= N3[3]; + btVector3 potentialVertex = n2n3; + potentialVertex += n3n1; + potentialVertex += n1n2; + potentialVertex *= quotient; + + //check if inside, and replace supportingVertexOut if needed + if (isPointInsidePlanes(planeEquations,potentialVertex,btScalar(0.01))) + { + verticesOut.push_back(potentialVertex); + } + } + } + } + } + } +} + diff --git a/extern/bullet2/src/LinearMath/btGeometryUtil.h b/extern/bullet2/src/LinearMath/btGeometryUtil.h new file mode 100644 index 00000000000..766cd75c383 --- /dev/null +++ b/extern/bullet2/src/LinearMath/btGeometryUtil.h @@ -0,0 +1,41 @@ +/* +Copyright (c) 2003-2006 Gino van den Bergen / 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 BT_GEOMETRY_UTIL_H +#define BT_GEOMETRY_UTIL_H + +#include "btVector3.h" +#include "btAlignedObjectArray.h" + +class btGeometryUtil +{ + public: + + + static void getPlaneEquationsFromVertices(btAlignedObjectArray& vertices, btAlignedObjectArray& planeEquationsOut ); + + static void getVerticesFromPlaneEquations(const btAlignedObjectArray& planeEquations , btAlignedObjectArray& verticesOut ); + + static bool isInside(const btAlignedObjectArray& vertices, const btVector3& planeNormal, btScalar margin); + + static bool isPointInsidePlanes(const btAlignedObjectArray& planeEquations, const btVector3& point, btScalar margin); + + static bool areVerticesBehindPlane(const btVector3& planeNormal, const btAlignedObjectArray& vertices, btScalar margin); + +}; + + +#endif //BT_GEOMETRY_UTIL_H + diff --git a/extern/bullet2/src/LinearMath/btIDebugDraw.h b/extern/bullet2/src/LinearMath/btIDebugDraw.h new file mode 100644 index 00000000000..5f40ca39157 --- /dev/null +++ b/extern/bullet2/src/LinearMath/btIDebugDraw.h @@ -0,0 +1,100 @@ +/* +Copyright (c) 2005 Gino van den Bergen / Erwin Coumans http://continuousphysics.com + +Permission is hereby granted, free of charge, to any person or organization +obtaining a copy of the software and accompanying documentation covered by +this license (the "Software") to use, reproduce, display, distribute, +execute, and transmit the Software, and to prepare derivative works of the +Software, and to permit third-parties to whom the Software is furnished to +do so, all subject to the following: + +The copyright notices in the Software and this entire statement, including +the above license grant, this restriction and the following disclaimer, +must be included in all copies of the Software, in whole or in part, and +all derivative works of the Software, unless such copies or derivative +works are solely in the form of machine-executable object code generated by +a source language processor. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +*/ + + +#ifndef IDEBUG_DRAW__H +#define IDEBUG_DRAW__H + +#include "btVector3.h" + + +class btIDebugDraw +{ + public: + + enum DebugDrawModes + { + DBG_NoDebug=0, + DBG_DrawWireframe = 1, + DBG_DrawAabb=2, + DBG_DrawFeaturesText=4, + DBG_DrawContactPoints=8, + DBG_NoDeactivation=16, + DBG_NoHelpText = 32, + DBG_DrawText=64, + DBG_ProfileTimings = 128, + DBG_EnableSatComparison = 256, + DBG_DisableBulletLCP = 512, + DBG_EnableCCD = 1024, + DBG_MAX_DEBUG_DRAW_MODE + }; + + virtual ~btIDebugDraw() {}; + + virtual void drawLine(const btVector3& from,const btVector3& to,const btVector3& color)=0; + + virtual void drawContactPoint(const btVector3& PointOnB,const btVector3& normalOnB,btScalar distance,int lifeTime,const btVector3& color)=0; + + virtual void reportErrorWarning(const char* warningString) = 0; + + virtual void setDebugMode(int debugMode) =0; + + virtual int getDebugMode() const = 0; + + inline void drawAabb(const btVector3& from,const btVector3& to,const btVector3& color) + { + + btVector3 halfExtents = (to-from)* 0.5f; + btVector3 center = (to+from) *0.5f; + int i,j; + + btVector3 edgecoord(1.f,1.f,1.f),pa,pb; + for (i=0;i<4;i++) + { + for (j=0;j<3;j++) + { + pa = btVector3(edgecoord[0]*halfExtents[0], edgecoord[1]*halfExtents[1], + edgecoord[2]*halfExtents[2]); + pa+=center; + + int othercoord = j%3; + edgecoord[othercoord]*=-1.f; + pb = btVector3(edgecoord[0]*halfExtents[0], edgecoord[1]*halfExtents[1], + edgecoord[2]*halfExtents[2]); + pb+=center; + + drawLine(pa,pb,color); + } + edgecoord = btVector3(-1.f,-1.f,-1.f); + if (i<3) + edgecoord[i]*=-1.f; + } + } +}; + + +#endif //IDEBUG_DRAW__H + diff --git a/extern/bullet2/src/LinearMath/btList.h b/extern/bullet2/src/LinearMath/btList.h new file mode 100644 index 00000000000..c87b47faf2b --- /dev/null +++ b/extern/bullet2/src/LinearMath/btList.h @@ -0,0 +1,73 @@ +/* +Copyright (c) 2003-2006 Gino van den Bergen / 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 GEN_LIST_H +#define GEN_LIST_H + +class btGEN_Link { +public: + btGEN_Link() : m_next(0), m_prev(0) {} + btGEN_Link(btGEN_Link *next, btGEN_Link *prev) : m_next(next), m_prev(prev) {} + + btGEN_Link *getNext() const { return m_next; } + btGEN_Link *getPrev() const { return m_prev; } + + bool isHead() const { return m_prev == 0; } + bool isTail() const { return m_next == 0; } + + void insertBefore(btGEN_Link *link) { + m_next = link; + m_prev = link->m_prev; + m_next->m_prev = this; + m_prev->m_next = this; + } + + void insertAfter(btGEN_Link *link) { + m_next = link->m_next; + m_prev = link; + m_next->m_prev = this; + m_prev->m_next = this; + } + + void remove() { + m_next->m_prev = m_prev; + m_prev->m_next = m_next; + } + +private: + btGEN_Link *m_next; + btGEN_Link *m_prev; +}; + +class btGEN_List { +public: + btGEN_List() : m_head(&m_tail, 0), m_tail(0, &m_head) {} + + btGEN_Link *getHead() const { return m_head.getNext(); } + btGEN_Link *getTail() const { return m_tail.getPrev(); } + + void addHead(btGEN_Link *link) { link->insertAfter(&m_head); } + void addTail(btGEN_Link *link) { link->insertBefore(&m_tail); } + +private: + btGEN_Link m_head; + btGEN_Link m_tail; +}; + +#endif + + + diff --git a/extern/bullet2/src/LinearMath/btMatrix3x3.h b/extern/bullet2/src/LinearMath/btMatrix3x3.h new file mode 100644 index 00000000000..94f53c3c0a5 --- /dev/null +++ b/extern/bullet2/src/LinearMath/btMatrix3x3.h @@ -0,0 +1,410 @@ +/* +Copyright (c) 2003-2006 Gino van den Bergen / 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 btMatrix3x3_H +#define btMatrix3x3_H + +#include "btScalar.h" + +#include "btVector3.h" +#include "btQuaternion.h" + + +class btMatrix3x3 { + public: + btMatrix3x3 () {} + +// explicit btMatrix3x3(const btScalar *m) { setFromOpenGLSubMatrix(m); } + + explicit btMatrix3x3(const btQuaternion& q) { setRotation(q); } + /* + template + Matrix3x3(const btScalar& yaw, const btScalar& pitch, const btScalar& roll) + { + setEulerYPR(yaw, pitch, roll); + } + */ + btMatrix3x3(const btScalar& xx, const btScalar& xy, const btScalar& xz, + const btScalar& yx, const btScalar& yy, const btScalar& yz, + const btScalar& zx, const btScalar& zy, const btScalar& zz) + { + setValue(xx, xy, xz, + yx, yy, yz, + zx, zy, zz); + } + + SIMD_FORCE_INLINE btMatrix3x3 (const btMatrix3x3& other) + { + m_el[0] = other.m_el[0]; + m_el[1] = other.m_el[1]; + m_el[2] = other.m_el[2]; + } + + SIMD_FORCE_INLINE btMatrix3x3& operator=(const btMatrix3x3& other) + { + m_el[0] = other.m_el[0]; + m_el[1] = other.m_el[1]; + m_el[2] = other.m_el[2]; + return *this; + } + + SIMD_FORCE_INLINE btVector3 getColumn(int i) const + { + return btVector3(m_el[0][i],m_el[1][i],m_el[2][i]); + } + + + + SIMD_FORCE_INLINE const btVector3& getRow(int i) const + { + return m_el[i]; + } + + + SIMD_FORCE_INLINE btVector3& operator[](int i) + { + btFullAssert(0 <= i && i < 3); + return m_el[i]; + } + + SIMD_FORCE_INLINE const btVector3& operator[](int i) const + { + btFullAssert(0 <= i && i < 3); + return m_el[i]; + } + + btMatrix3x3& operator*=(const btMatrix3x3& m); + + + void setFromOpenGLSubMatrix(const btScalar *m) + { + m_el[0].setValue(m[0],m[4],m[8]); + m_el[1].setValue(m[1],m[5],m[9]); + m_el[2].setValue(m[2],m[6],m[10]); + + } + + void setValue(const btScalar& xx, const btScalar& xy, const btScalar& xz, + const btScalar& yx, const btScalar& yy, const btScalar& yz, + const btScalar& zx, const btScalar& zy, const btScalar& zz) + { + m_el[0].setValue(xx,xy,xz); + m_el[1].setValue(yx,yy,yz); + m_el[2].setValue(zx,zy,zz); + } + + void setRotation(const btQuaternion& q) + { + btScalar d = q.length2(); + btFullAssert(d != btScalar(0.0)); + btScalar s = btScalar(2.0) / d; + btScalar xs = q.x() * s, ys = q.y() * s, zs = q.z() * s; + btScalar wx = q.w() * xs, wy = q.w() * ys, wz = q.w() * zs; + btScalar xx = q.x() * xs, xy = q.x() * ys, xz = q.x() * zs; + btScalar yy = q.y() * ys, yz = q.y() * zs, zz = q.z() * zs; + setValue(btScalar(1.0) - (yy + zz), xy - wz, xz + wy, + xy + wz, btScalar(1.0) - (xx + zz), yz - wx, + xz - wy, yz + wx, btScalar(1.0) - (xx + yy)); + } + + + + void setEulerYPR(const btScalar& yaw, const btScalar& pitch, const btScalar& roll) + { + + btScalar cy(btCos(yaw)); + btScalar sy(btSin(yaw)); + btScalar cp(btCos(pitch)); + btScalar sp(btSin(pitch)); + btScalar cr(btCos(roll)); + btScalar sr(btSin(roll)); + btScalar cc = cy * cr; + btScalar cs = cy * sr; + btScalar sc = sy * cr; + btScalar ss = sy * sr; + setValue(cc - sp * ss, -cs - sp * sc, -sy * cp, + cp * sr, cp * cr, -sp, + sc + sp * cs, -ss + sp * cc, cy * cp); + + } + + /** + * setEulerZYX + * @param euler a const reference to a btVector3 of euler angles + * These angles are used to produce a rotation matrix. The euler + * angles are applied in ZYX order. I.e a vector is first rotated + * about X then Y and then Z + **/ + + void setEulerZYX(btScalar eulerX,btScalar eulerY,btScalar eulerZ) { + btScalar ci ( btCos(eulerX)); + btScalar cj ( btCos(eulerY)); + btScalar ch ( btCos(eulerZ)); + btScalar si ( btSin(eulerX)); + btScalar sj ( btSin(eulerY)); + btScalar sh ( btSin(eulerZ)); + btScalar cc = ci * ch; + btScalar cs = ci * sh; + btScalar sc = si * ch; + btScalar ss = si * sh; + + setValue(cj * ch, sj * sc - cs, sj * cc + ss, + cj * sh, sj * ss + cc, sj * cs - sc, + -sj, cj * si, cj * ci); + } + + void setIdentity() + { + setValue(btScalar(1.0), btScalar(0.0), btScalar(0.0), + btScalar(0.0), btScalar(1.0), btScalar(0.0), + btScalar(0.0), btScalar(0.0), btScalar(1.0)); + } + + void getOpenGLSubMatrix(btScalar *m) const + { + m[0] = btScalar(m_el[0].x()); + m[1] = btScalar(m_el[1].x()); + m[2] = btScalar(m_el[2].x()); + m[3] = btScalar(0.0); + m[4] = btScalar(m_el[0].y()); + m[5] = btScalar(m_el[1].y()); + m[6] = btScalar(m_el[2].y()); + m[7] = btScalar(0.0); + m[8] = btScalar(m_el[0].z()); + m[9] = btScalar(m_el[1].z()); + m[10] = btScalar(m_el[2].z()); + m[11] = btScalar(0.0); + } + + void getRotation(btQuaternion& q) const + { + btScalar trace = m_el[0].x() + m_el[1].y() + m_el[2].z(); + btScalar temp[4]; + + if (trace > btScalar(0.0)) + { + btScalar s = btSqrt(trace + btScalar(1.0)); + temp[3]=(s * btScalar(0.5)); + s = btScalar(0.5) / s; + + temp[0]=((m_el[2].y() - m_el[1].z()) * s); + temp[1]=((m_el[0].z() - m_el[2].x()) * s); + temp[2]=((m_el[1].x() - m_el[0].y()) * s); + } + else + { + int i = m_el[0].x() < m_el[1].y() ? + (m_el[1].y() < m_el[2].z() ? 2 : 1) : + (m_el[0].x() < m_el[2].z() ? 2 : 0); + int j = (i + 1) % 3; + int k = (i + 2) % 3; + + btScalar s = btSqrt(m_el[i][i] - m_el[j][j] - m_el[k][k] + btScalar(1.0)); + temp[i] = s * btScalar(0.5); + s = btScalar(0.5) / s; + + temp[3] = (m_el[k][j] - m_el[j][k]) * s; + temp[j] = (m_el[j][i] + m_el[i][j]) * s; + temp[k] = (m_el[k][i] + m_el[i][k]) * s; + } + q.setValue(temp[0],temp[1],temp[2],temp[3]); + } + + void getEuler(btScalar& yaw, btScalar& pitch, btScalar& roll) const + { + + if (btScalar(m_el[1].z()) < btScalar(1)) + { + if (btScalar(m_el[1].z()) > -btScalar(1)) + { + yaw = btScalar(btAtan2(m_el[1].x(), m_el[0].x())); + pitch = btScalar(btAsin(-m_el[1].y())); + roll = btScalar(btAtan2(m_el[2].y(), m_el[2].z())); + } + else + { + yaw = btScalar(-btAtan2(-m_el[0].y(), m_el[0].z())); + pitch = SIMD_HALF_PI; + roll = btScalar(0.0); + } + } + else + { + yaw = btScalar(btAtan2(-m_el[0].y(), m_el[0].z())); + pitch = -SIMD_HALF_PI; + roll = btScalar(0.0); + } + } + + + + + btMatrix3x3 scaled(const btVector3& s) const + { + return btMatrix3x3(m_el[0].x() * s.x(), m_el[0].y() * s.y(), m_el[0].z() * s.z(), + m_el[1].x() * s.x(), m_el[1].y() * s.y(), m_el[1].z() * s.z(), + m_el[2].x() * s.x(), m_el[2].y() * s.y(), m_el[2].z() * s.z()); + } + + btScalar determinant() const; + btMatrix3x3 adjoint() const; + btMatrix3x3 absolute() const; + btMatrix3x3 transpose() const; + btMatrix3x3 inverse() const; + + btMatrix3x3 transposeTimes(const btMatrix3x3& m) const; + btMatrix3x3 timesTranspose(const btMatrix3x3& m) const; + + SIMD_FORCE_INLINE btScalar tdotx(const btVector3& v) const + { + return m_el[0].x() * v.x() + m_el[1].x() * v.y() + m_el[2].x() * v.z(); + } + SIMD_FORCE_INLINE btScalar tdoty(const btVector3& v) const + { + return m_el[0].y() * v.x() + m_el[1].y() * v.y() + m_el[2].y() * v.z(); + } + SIMD_FORCE_INLINE btScalar tdotz(const btVector3& v) const + { + return m_el[0].z() * v.x() + m_el[1].z() * v.y() + m_el[2].z() * v.z(); + } + + + + protected: + btScalar cofac(int r1, int c1, int r2, int c2) const + { + return m_el[r1][c1] * m_el[r2][c2] - m_el[r1][c2] * m_el[r2][c1]; + } + + btVector3 m_el[3]; + }; + + SIMD_FORCE_INLINE btMatrix3x3& + btMatrix3x3::operator*=(const btMatrix3x3& m) + { + setValue(m.tdotx(m_el[0]), m.tdoty(m_el[0]), m.tdotz(m_el[0]), + m.tdotx(m_el[1]), m.tdoty(m_el[1]), m.tdotz(m_el[1]), + m.tdotx(m_el[2]), m.tdoty(m_el[2]), m.tdotz(m_el[2])); + return *this; + } + + SIMD_FORCE_INLINE btScalar + btMatrix3x3::determinant() const + { + return triple((*this)[0], (*this)[1], (*this)[2]); + } + + + SIMD_FORCE_INLINE btMatrix3x3 + btMatrix3x3::absolute() const + { + return btMatrix3x3( + btFabs(m_el[0].x()), btFabs(m_el[0].y()), btFabs(m_el[0].z()), + btFabs(m_el[1].x()), btFabs(m_el[1].y()), btFabs(m_el[1].z()), + btFabs(m_el[2].x()), btFabs(m_el[2].y()), btFabs(m_el[2].z())); + } + + SIMD_FORCE_INLINE btMatrix3x3 + btMatrix3x3::transpose() const + { + return btMatrix3x3(m_el[0].x(), m_el[1].x(), m_el[2].x(), + m_el[0].y(), m_el[1].y(), m_el[2].y(), + m_el[0].z(), m_el[1].z(), m_el[2].z()); + } + + SIMD_FORCE_INLINE btMatrix3x3 + btMatrix3x3::adjoint() const + { + return btMatrix3x3(cofac(1, 1, 2, 2), cofac(0, 2, 2, 1), cofac(0, 1, 1, 2), + cofac(1, 2, 2, 0), cofac(0, 0, 2, 2), cofac(0, 2, 1, 0), + cofac(1, 0, 2, 1), cofac(0, 1, 2, 0), cofac(0, 0, 1, 1)); + } + + SIMD_FORCE_INLINE btMatrix3x3 + btMatrix3x3::inverse() const + { + btVector3 co(cofac(1, 1, 2, 2), cofac(1, 2, 2, 0), cofac(1, 0, 2, 1)); + btScalar det = (*this)[0].dot(co); + btFullAssert(det != btScalar(0.0)); + btScalar s = btScalar(1.0) / det; + return btMatrix3x3(co.x() * s, cofac(0, 2, 2, 1) * s, cofac(0, 1, 1, 2) * s, + co.y() * s, cofac(0, 0, 2, 2) * s, cofac(0, 2, 1, 0) * s, + co.z() * s, cofac(0, 1, 2, 0) * s, cofac(0, 0, 1, 1) * s); + } + + SIMD_FORCE_INLINE btMatrix3x3 + btMatrix3x3::transposeTimes(const btMatrix3x3& m) const + { + return btMatrix3x3( + m_el[0].x() * m[0].x() + m_el[1].x() * m[1].x() + m_el[2].x() * m[2].x(), + m_el[0].x() * m[0].y() + m_el[1].x() * m[1].y() + m_el[2].x() * m[2].y(), + m_el[0].x() * m[0].z() + m_el[1].x() * m[1].z() + m_el[2].x() * m[2].z(), + m_el[0].y() * m[0].x() + m_el[1].y() * m[1].x() + m_el[2].y() * m[2].x(), + m_el[0].y() * m[0].y() + m_el[1].y() * m[1].y() + m_el[2].y() * m[2].y(), + m_el[0].y() * m[0].z() + m_el[1].y() * m[1].z() + m_el[2].y() * m[2].z(), + m_el[0].z() * m[0].x() + m_el[1].z() * m[1].x() + m_el[2].z() * m[2].x(), + m_el[0].z() * m[0].y() + m_el[1].z() * m[1].y() + m_el[2].z() * m[2].y(), + m_el[0].z() * m[0].z() + m_el[1].z() * m[1].z() + m_el[2].z() * m[2].x()); + } + + SIMD_FORCE_INLINE btMatrix3x3 + btMatrix3x3::timesTranspose(const btMatrix3x3& m) const + { + return btMatrix3x3( + m_el[0].dot(m[0]), m_el[0].dot(m[1]), m_el[0].dot(m[2]), + m_el[1].dot(m[0]), m_el[1].dot(m[1]), m_el[1].dot(m[2]), + m_el[2].dot(m[0]), m_el[2].dot(m[1]), m_el[2].dot(m[2])); + + } + + SIMD_FORCE_INLINE btVector3 + operator*(const btMatrix3x3& m, const btVector3& v) + { + return btVector3(m[0].dot(v), m[1].dot(v), m[2].dot(v)); + } + + + SIMD_FORCE_INLINE btVector3 + operator*(const btVector3& v, const btMatrix3x3& m) + { + return btVector3(m.tdotx(v), m.tdoty(v), m.tdotz(v)); + } + + SIMD_FORCE_INLINE btMatrix3x3 + operator*(const btMatrix3x3& m1, const btMatrix3x3& m2) + { + return btMatrix3x3( + m2.tdotx( m1[0]), m2.tdoty( m1[0]), m2.tdotz( m1[0]), + m2.tdotx( m1[1]), m2.tdoty( m1[1]), m2.tdotz( m1[1]), + m2.tdotx( m1[2]), m2.tdoty( m1[2]), m2.tdotz( m1[2])); + } + +/* + SIMD_FORCE_INLINE btMatrix3x3 btMultTransposeLeft(const btMatrix3x3& m1, const btMatrix3x3& m2) { + return btMatrix3x3( + m1[0][0] * m2[0][0] + m1[1][0] * m2[1][0] + m1[2][0] * m2[2][0], + m1[0][0] * m2[0][1] + m1[1][0] * m2[1][1] + m1[2][0] * m2[2][1], + m1[0][0] * m2[0][2] + m1[1][0] * m2[1][2] + m1[2][0] * m2[2][2], + m1[0][1] * m2[0][0] + m1[1][1] * m2[1][0] + m1[2][1] * m2[2][0], + m1[0][1] * m2[0][1] + m1[1][1] * m2[1][1] + m1[2][1] * m2[2][1], + m1[0][1] * m2[0][2] + m1[1][1] * m2[1][2] + m1[2][1] * m2[2][2], + m1[0][2] * m2[0][0] + m1[1][2] * m2[1][0] + m1[2][2] * m2[2][0], + m1[0][2] * m2[0][1] + m1[1][2] * m2[1][1] + m1[2][2] * m2[2][1], + m1[0][2] * m2[0][2] + m1[1][2] * m2[1][2] + m1[2][2] * m2[2][2]); +} +*/ + + +#endif diff --git a/extern/bullet2/src/LinearMath/btMinMax.h b/extern/bullet2/src/LinearMath/btMinMax.h new file mode 100644 index 00000000000..1b8a3633f38 --- /dev/null +++ b/extern/bullet2/src/LinearMath/btMinMax.h @@ -0,0 +1,69 @@ +/* +Copyright (c) 2003-2006 Gino van den Bergen / 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 GEN_MINMAX_H +#define GEN_MINMAX_H + +template +SIMD_FORCE_INLINE const T& GEN_min(const T& a, const T& b) +{ + return b < a ? b : a; +} + +template +SIMD_FORCE_INLINE const T& GEN_max(const T& a, const T& b) +{ + return a < b ? b : a; +} + +template +SIMD_FORCE_INLINE const T& GEN_clamped(const T& a, const T& lb, const T& ub) +{ + return a < lb ? lb : (ub < a ? ub : a); +} + +template +SIMD_FORCE_INLINE void GEN_set_min(T& a, const T& b) +{ + if (b < a) + { + a = b; + } +} + +template +SIMD_FORCE_INLINE void GEN_set_max(T& a, const T& b) +{ + if (a < b) + { + a = b; + } +} + +template +SIMD_FORCE_INLINE void GEN_clamp(T& a, const T& lb, const T& ub) +{ + if (a < lb) + { + a = lb; + } + else if (ub < a) + { + a = ub; + } +} + +#endif diff --git a/extern/bullet2/src/LinearMath/btMotionState.h b/extern/bullet2/src/LinearMath/btMotionState.h new file mode 100644 index 00000000000..1975e5ff900 --- /dev/null +++ b/extern/bullet2/src/LinearMath/btMotionState.h @@ -0,0 +1,40 @@ +/* +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 BT_MOTIONSTATE_H +#define BT_MOTIONSTATE_H + +#include "btTransform.h" + +///btMotionState allows the dynamics world to synchronize the updated world transforms with graphics +///For optimizations, potentially only moving objects get synchronized (using setWorldPosition/setWorldOrientation) +class btMotionState +{ + public: + + virtual ~btMotionState() + { + + } + + virtual void getWorldTransform(btTransform& worldTrans ) const =0; + + //Bullet only calls the update of worldtransform for active objects + virtual void setWorldTransform(const btTransform& worldTrans)=0; + + +}; + +#endif //BT_MOTIONSTATE_H diff --git a/extern/bullet2/src/LinearMath/btPoint3.h b/extern/bullet2/src/LinearMath/btPoint3.h new file mode 100644 index 00000000000..a2020e26d12 --- /dev/null +++ b/extern/bullet2/src/LinearMath/btPoint3.h @@ -0,0 +1,24 @@ +/* +Copyright (c) 2003-2006 Gino van den Bergen / 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 btPoint3_H +#define btPoint3_H + +#include "btVector3.h" + +typedef btVector3 btPoint3; + +#endif diff --git a/extern/bullet2/src/LinearMath/btQuadWord.h b/extern/bullet2/src/LinearMath/btQuadWord.h new file mode 100644 index 00000000000..961ac484d20 --- /dev/null +++ b/extern/bullet2/src/LinearMath/btQuadWord.h @@ -0,0 +1,139 @@ +/* +Copyright (c) 2003-2006 Gino van den Bergen / 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 SIMD_QUADWORD_H +#define SIMD_QUADWORD_H + +#include "btScalar.h" + + + + +///btQuadWord is base-class for vectors, points +class btQuadWord +{ + protected: + btScalar m_x; + btScalar m_y; + btScalar m_z; + btScalar m_unusedW; + + public: + +// SIMD_FORCE_INLINE btScalar& operator[](int i) { return (&m_x)[i]; } +// SIMD_FORCE_INLINE const btScalar& operator[](int i) const { return (&m_x)[i]; } + + SIMD_FORCE_INLINE const btScalar& getX() const { return m_x; } + + SIMD_FORCE_INLINE const btScalar& getY() const { return m_y; } + + SIMD_FORCE_INLINE const btScalar& getZ() const { return m_z; } + + SIMD_FORCE_INLINE void setX(btScalar x) { m_x = x;}; + + SIMD_FORCE_INLINE void setY(btScalar y) { m_y = y;}; + + SIMD_FORCE_INLINE void setZ(btScalar z) { m_z = z;}; + + SIMD_FORCE_INLINE void setW(btScalar w) { m_unusedW = w;}; + + SIMD_FORCE_INLINE const btScalar& x() const { return m_x; } + + SIMD_FORCE_INLINE const btScalar& y() const { return m_y; } + + SIMD_FORCE_INLINE const btScalar& z() const { return m_z; } + + SIMD_FORCE_INLINE const btScalar& w() const { return m_unusedW; } + + + SIMD_FORCE_INLINE operator btScalar *() { return &m_x; } + SIMD_FORCE_INLINE operator const btScalar *() const { return &m_x; } + + SIMD_FORCE_INLINE void setValue(const btScalar& x, const btScalar& y, const btScalar& z) + { + m_x=x; + m_y=y; + m_z=z; + m_unusedW = 0.f; + } + +/* void getValue(btScalar *m) const + { + m[0] = m_x; + m[1] = m_y; + m[2] = m_z; + } +*/ + SIMD_FORCE_INLINE void setValue(const btScalar& x, const btScalar& y, const btScalar& z,const btScalar& w) + { + m_x=x; + m_y=y; + m_z=z; + m_unusedW=w; + } + + SIMD_FORCE_INLINE btQuadWord() + // :m_x(btScalar(0.)),m_y(btScalar(0.)),m_z(btScalar(0.)),m_unusedW(btScalar(0.)) + { + } + + SIMD_FORCE_INLINE btQuadWord(const btScalar& x, const btScalar& y, const btScalar& z) + :m_x(x),m_y(y),m_z(z) + //todo, remove this in release/simd ? + ,m_unusedW(btScalar(0.)) + { + } + + SIMD_FORCE_INLINE btQuadWord(const btScalar& x, const btScalar& y, const btScalar& z,const btScalar& w) + :m_x(x),m_y(y),m_z(z),m_unusedW(w) + { + } + + + SIMD_FORCE_INLINE void setMax(const btQuadWord& other) + { + if (other.m_x > m_x) + m_x = other.m_x; + + if (other.m_y > m_y) + m_y = other.m_y; + + if (other.m_z > m_z) + m_z = other.m_z; + + if (other.m_unusedW > m_unusedW) + m_unusedW = other.m_unusedW; + } + + SIMD_FORCE_INLINE void setMin(const btQuadWord& other) + { + if (other.m_x < m_x) + m_x = other.m_x; + + if (other.m_y < m_y) + m_y = other.m_y; + + if (other.m_z < m_z) + m_z = other.m_z; + + if (other.m_unusedW < m_unusedW) + m_unusedW = other.m_unusedW; + } + + + +}; + +#endif //SIMD_QUADWORD_H diff --git a/extern/bullet2/src/LinearMath/btQuaternion.h b/extern/bullet2/src/LinearMath/btQuaternion.h new file mode 100644 index 00000000000..50334970ba6 --- /dev/null +++ b/extern/bullet2/src/LinearMath/btQuaternion.h @@ -0,0 +1,321 @@ +/* +Copyright (c) 2003-2006 Gino van den Bergen / 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 SIMD__QUATERNION_H_ +#define SIMD__QUATERNION_H_ + +#include "btVector3.h" + +class btQuaternion : public btQuadWord { +public: + btQuaternion() {} + + // template + // explicit Quaternion(const btScalar *v) : Tuple4(v) {} + + btQuaternion(const btScalar& x, const btScalar& y, const btScalar& z, const btScalar& w) + : btQuadWord(x, y, z, w) + {} + + btQuaternion(const btVector3& axis, const btScalar& angle) + { + setRotation(axis, angle); + } + + btQuaternion(const btScalar& yaw, const btScalar& pitch, const btScalar& roll) + { + setEuler(yaw, pitch, roll); + } + + void setRotation(const btVector3& axis, const btScalar& angle) + { + btScalar d = axis.length(); + assert(d != btScalar(0.0)); + btScalar s = btSin(angle * btScalar(0.5)) / d; + setValue(axis.x() * s, axis.y() * s, axis.z() * s, + btCos(angle * btScalar(0.5))); + } + + void setEuler(const btScalar& yaw, const btScalar& pitch, const btScalar& roll) + { + btScalar halfYaw = btScalar(yaw) * btScalar(0.5); + btScalar halfPitch = btScalar(pitch) * btScalar(0.5); + btScalar halfRoll = btScalar(roll) * btScalar(0.5); + btScalar cosYaw = btCos(halfYaw); + btScalar sinYaw = btSin(halfYaw); + btScalar cosPitch = btCos(halfPitch); + btScalar sinPitch = btSin(halfPitch); + btScalar cosRoll = btCos(halfRoll); + btScalar sinRoll = btSin(halfRoll); + setValue(cosRoll * sinPitch * cosYaw + sinRoll * cosPitch * sinYaw, + cosRoll * cosPitch * sinYaw - sinRoll * sinPitch * cosYaw, + sinRoll * cosPitch * cosYaw - cosRoll * sinPitch * sinYaw, + cosRoll * cosPitch * cosYaw + sinRoll * sinPitch * sinYaw); + } + + btQuaternion& operator+=(const btQuaternion& q) + { + m_x += q.x(); m_y += q.y(); m_z += q.z(); m_unusedW += q.m_unusedW; + return *this; + } + + btQuaternion& operator-=(const btQuaternion& q) + { + m_x -= q.x(); m_y -= q.y(); m_z -= q.z(); m_unusedW -= q.m_unusedW; + return *this; + } + + btQuaternion& operator*=(const btScalar& s) + { + m_x *= s; m_y *= s; m_z *= s; m_unusedW *= s; + return *this; + } + + + btQuaternion& operator*=(const btQuaternion& q) + { + setValue(m_unusedW * q.x() + m_x * q.m_unusedW + m_y * q.z() - m_z * q.y(), + m_unusedW * q.y() + m_y * q.m_unusedW + m_z * q.x() - m_x * q.z(), + m_unusedW * q.z() + m_z * q.m_unusedW + m_x * q.y() - m_y * q.x(), + m_unusedW * q.m_unusedW - m_x * q.x() - m_y * q.y() - m_z * q.z()); + return *this; + } + + btScalar dot(const btQuaternion& q) const + { + return m_x * q.x() + m_y * q.y() + m_z * q.z() + m_unusedW * q.m_unusedW; + } + + btScalar length2() const + { + return dot(*this); + } + + btScalar length() const + { + return btSqrt(length2()); + } + + btQuaternion& normalize() + { + return *this /= length(); + } + + SIMD_FORCE_INLINE btQuaternion + operator*(const btScalar& s) const + { + return btQuaternion(x() * s, y() * s, z() * s, m_unusedW * s); + } + + + + btQuaternion operator/(const btScalar& s) const + { + assert(s != btScalar(0.0)); + return *this * (btScalar(1.0) / s); + } + + + btQuaternion& operator/=(const btScalar& s) + { + assert(s != btScalar(0.0)); + return *this *= btScalar(1.0) / s; + } + + + btQuaternion normalized() const + { + return *this / length(); + } + + btScalar angle(const btQuaternion& q) const + { + btScalar s = btSqrt(length2() * q.length2()); + assert(s != btScalar(0.0)); + return btAcos(dot(q) / s); + } + + btScalar getAngle() const + { + btScalar s = btScalar(2.) * btAcos(m_unusedW); + return s; + } + + + + btQuaternion inverse() const + { + return btQuaternion(m_x, m_y, m_z, -m_unusedW); + } + + SIMD_FORCE_INLINE btQuaternion + operator+(const btQuaternion& q2) const + { + const btQuaternion& q1 = *this; + return btQuaternion(q1.x() + q2.x(), q1.y() + q2.y(), q1.z() + q2.z(), q1.m_unusedW + q2.m_unusedW); + } + + SIMD_FORCE_INLINE btQuaternion + operator-(const btQuaternion& q2) const + { + const btQuaternion& q1 = *this; + return btQuaternion(q1.x() - q2.x(), q1.y() - q2.y(), q1.z() - q2.z(), q1.m_unusedW - q2.m_unusedW); + } + + SIMD_FORCE_INLINE btQuaternion operator-() const + { + const btQuaternion& q2 = *this; + return btQuaternion( - q2.x(), - q2.y(), - q2.z(), - q2.m_unusedW); + } + + SIMD_FORCE_INLINE btQuaternion farthest( const btQuaternion& qd) const + { + btQuaternion diff,sum; + diff = *this - qd; + sum = *this + qd; + if( diff.dot(diff) > sum.dot(sum) ) + return qd; + return (-qd); + } + + btQuaternion slerp(const btQuaternion& q, const btScalar& t) const + { + btScalar theta = angle(q); + if (theta != btScalar(0.0)) + { + btScalar d = btScalar(1.0) / btSin(theta); + btScalar s0 = btSin((btScalar(1.0) - t) * theta); + btScalar s1 = btSin(t * theta); + return btQuaternion((m_x * s0 + q.x() * s1) * d, + (m_y * s0 + q.y() * s1) * d, + (m_z * s0 + q.z() * s1) * d, + (m_unusedW * s0 + q.m_unusedW * s1) * d); + } + else + { + return *this; + } + } + + SIMD_FORCE_INLINE const btScalar& getW() const { return m_unusedW; } + + +}; + + + +SIMD_FORCE_INLINE btQuaternion +operator-(const btQuaternion& q) +{ + return btQuaternion(-q.x(), -q.y(), -q.z(), -q.w()); +} + + + + +SIMD_FORCE_INLINE btQuaternion +operator*(const btQuaternion& q1, const btQuaternion& q2) { + return btQuaternion(q1.w() * q2.x() + q1.x() * q2.w() + q1.y() * q2.z() - q1.z() * q2.y(), + q1.w() * q2.y() + q1.y() * q2.w() + q1.z() * q2.x() - q1.x() * q2.z(), + q1.w() * q2.z() + q1.z() * q2.w() + q1.x() * q2.y() - q1.y() * q2.x(), + q1.w() * q2.w() - q1.x() * q2.x() - q1.y() * q2.y() - q1.z() * q2.z()); +} + +SIMD_FORCE_INLINE btQuaternion +operator*(const btQuaternion& q, const btVector3& w) +{ + return btQuaternion( q.w() * w.x() + q.y() * w.z() - q.z() * w.y(), + q.w() * w.y() + q.z() * w.x() - q.x() * w.z(), + q.w() * w.z() + q.x() * w.y() - q.y() * w.x(), + -q.x() * w.x() - q.y() * w.y() - q.z() * w.z()); +} + +SIMD_FORCE_INLINE btQuaternion +operator*(const btVector3& w, const btQuaternion& q) +{ + return btQuaternion( w.x() * q.w() + w.y() * q.z() - w.z() * q.y(), + w.y() * q.w() + w.z() * q.x() - w.x() * q.z(), + w.z() * q.w() + w.x() * q.y() - w.y() * q.x(), + -w.x() * q.x() - w.y() * q.y() - w.z() * q.z()); +} + +SIMD_FORCE_INLINE btScalar +dot(const btQuaternion& q1, const btQuaternion& q2) +{ + return q1.dot(q2); +} + + +SIMD_FORCE_INLINE btScalar +length(const btQuaternion& q) +{ + return q.length(); +} + +SIMD_FORCE_INLINE btScalar +angle(const btQuaternion& q1, const btQuaternion& q2) +{ + return q1.angle(q2); +} + + +SIMD_FORCE_INLINE btQuaternion +inverse(const btQuaternion& q) +{ + return q.inverse(); +} + +SIMD_FORCE_INLINE btQuaternion +slerp(const btQuaternion& q1, const btQuaternion& q2, const btScalar& t) +{ + return q1.slerp(q2, t); +} + +SIMD_FORCE_INLINE btVector3 +quatRotate(btQuaternion& rotation, btVector3& v) +{ + btQuaternion q = rotation * v; + q *= rotation.inverse(); + return btVector3(q.getX(),q.getY(),q.getZ()); +} + +SIMD_FORCE_INLINE btQuaternion +shortestArcQuat(btVector3& v0,btVector3& v1) // Game Programming Gems 2.10. make sure v0,v1 are normalized +{ + btVector3 c = v0.cross(v1); + btScalar d = v0.dot(v1); + + if (d < -1.0 + SIMD_EPSILON) + return btQuaternion(0.0f,1.0f,0.0f,0.0f); // just pick any vector + + btScalar s = btSqrt((1.0f + d) * 2.0f); + btScalar rs = 1.0f / s; + + return btQuaternion(c.getX()*rs,c.getY()*rs,c.getZ()*rs,s * 0.5f); +} + +SIMD_FORCE_INLINE btQuaternion +shortestArcQuatNormalize(btVector3& v0,btVector3& v1) +{ + v0.normalize(); + v1.normalize(); + return shortestArcQuat(v0,v1); +} + +#endif + + + diff --git a/extern/bullet2/src/LinearMath/btQuickprof.cpp b/extern/bullet2/src/LinearMath/btQuickprof.cpp new file mode 100644 index 00000000000..37a0c8c3be5 --- /dev/null +++ b/extern/bullet2/src/LinearMath/btQuickprof.cpp @@ -0,0 +1,38 @@ +/* +Copyright (c) 2006 Tyler Streeter + +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. + +*/ + + +// Please visit the project website (http://quickprof.sourceforge.net) +// for usage instructions. + +// Credits: The Clock class was inspired by the Timer classes in +// Ogre (www.ogre3d.org). + +#include "LinearMath/btQuickprof.h" + +#ifdef USE_QUICKPROF + +// Note: We must declare these private static variables again here to +// avoid link errors. +bool btProfiler::mEnabled = false; +btClock btProfiler::mClock; +unsigned long int btProfiler::mCurrentCycleStartMicroseconds = 0; +unsigned long int btProfiler::mLastCycleDurationMicroseconds = 0; +std::map btProfiler::mProfileBlocks; +std::ofstream btProfiler::mOutputFile; +bool btProfiler::mFirstFileOutput = true; +btProfiler::BlockTimingMethod btProfiler::mFileOutputMethod; +unsigned long int btProfiler::mCycleNumber = 0; +#endif //USE_QUICKPROF diff --git a/extern/bullet2/src/LinearMath/btQuickprof.h b/extern/bullet2/src/LinearMath/btQuickprof.h new file mode 100644 index 00000000000..a885967c5fa --- /dev/null +++ b/extern/bullet2/src/LinearMath/btQuickprof.h @@ -0,0 +1,712 @@ +/* +Copyright (c) 2006 Tyler Streeter + +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. + +*/ + +// Please visit the project website (http://quickprof.sourceforge.net) +// for usage instructions. + +// Credits: The Clock class was inspired by the Timer classes in +// Ogre (www.ogre3d.org). + +#ifndef QUICK_PROF_H +#define QUICK_PROF_H + +#include "btScalar.h" + +//#define USE_QUICKPROF 1 +//Don't use quickprof for now, because it contains STL. TODO: replace STL by Bullet container classes. + + +//if you don't need btClock, you can comment next line +#define USE_BT_CLOCK 1 + +#ifdef USE_BT_CLOCK +#ifdef __CELLOS_LV2__ +#include +#include +typedef uint64_t __int64; +#endif + +#if defined (SUNOS) || defined (__SUNOS__) + #include +#endif + +#if defined(WIN32) || defined(_WIN32) + + #define USE_WINDOWS_TIMERS + #define WIN32_LEAN_AND_MEAN + #define NOWINRES + #define NOMCX + #define NOIME +#ifdef _XBOX + #include +#else + #include +#endif + #include + +#else + #include +#endif + +#define mymin(a,b) (a > b ? a : b) + +/// basic clock +class btClock + { + public: + btClock() + { +#ifdef USE_WINDOWS_TIMERS + QueryPerformanceFrequency(&mClockFrequency); +#endif + reset(); + } + + ~btClock() + { + } + + /// Resets the initial reference time. + void reset() + { +#ifdef USE_WINDOWS_TIMERS + QueryPerformanceCounter(&mStartTime); + mStartTick = GetTickCount(); + mPrevElapsedTime = 0; +#else +#ifdef __CELLOS_LV2__ + + typedef uint64_t __int64; + typedef __int64 ClockSize; + ClockSize newTime; + __asm __volatile__( "mftb %0" : "=r" (newTime) : : "memory"); + mStartTime = newTime; +#else + gettimeofday(&mStartTime, 0); +#endif + +#endif + } + + /// Returns the time in ms since the last call to reset or since + /// the btClock was created. + unsigned long int getTimeMilliseconds() + { +#ifdef USE_WINDOWS_TIMERS + LARGE_INTEGER currentTime; + QueryPerformanceCounter(¤tTime); + LONGLONG elapsedTime = currentTime.QuadPart - + mStartTime.QuadPart; + + // Compute the number of millisecond ticks elapsed. + unsigned long msecTicks = (unsigned long)(1000 * elapsedTime / + mClockFrequency.QuadPart); + + // Check for unexpected leaps in the Win32 performance counter. + // (This is caused by unexpected data across the PCI to ISA + // bridge, aka south bridge. See Microsoft KB274323.) + unsigned long elapsedTicks = GetTickCount() - mStartTick; + signed long msecOff = (signed long)(msecTicks - elapsedTicks); + if (msecOff < -100 || msecOff > 100) + { + // Adjust the starting time forwards. + LONGLONG msecAdjustment = mymin(msecOff * + mClockFrequency.QuadPart / 1000, elapsedTime - + mPrevElapsedTime); + mStartTime.QuadPart += msecAdjustment; + elapsedTime -= msecAdjustment; + + // Recompute the number of millisecond ticks elapsed. + msecTicks = (unsigned long)(1000 * elapsedTime / + mClockFrequency.QuadPart); + } + + // Store the current elapsed time for adjustments next time. + mPrevElapsedTime = elapsedTime; + + return msecTicks; +#else + +#ifdef __CELLOS_LV2__ + __int64 freq=sys_time_get_timebase_frequency(); + double dFreq=((double) freq) / 1000.0; + typedef uint64_t __int64; + typedef __int64 ClockSize; + ClockSize newTime; + __asm __volatile__( "mftb %0" : "=r" (newTime) : : "memory"); + + return (newTime-mStartTime) / dFreq; +#else + + struct timeval currentTime; + gettimeofday(¤tTime, 0); + return (currentTime.tv_sec - mStartTime.tv_sec) * 1000 + + (currentTime.tv_usec - mStartTime.tv_usec) / 1000; +#endif //__CELLOS_LV2__ +#endif + } + + /// Returns the time in us since the last call to reset or since + /// the Clock was created. + unsigned long int getTimeMicroseconds() + { +#ifdef USE_WINDOWS_TIMERS + LARGE_INTEGER currentTime; + QueryPerformanceCounter(¤tTime); + LONGLONG elapsedTime = currentTime.QuadPart - + mStartTime.QuadPart; + + // Compute the number of millisecond ticks elapsed. + unsigned long msecTicks = (unsigned long)(1000 * elapsedTime / + mClockFrequency.QuadPart); + + // Check for unexpected leaps in the Win32 performance counter. + // (This is caused by unexpected data across the PCI to ISA + // bridge, aka south bridge. See Microsoft KB274323.) + unsigned long elapsedTicks = GetTickCount() - mStartTick; + signed long msecOff = (signed long)(msecTicks - elapsedTicks); + if (msecOff < -100 || msecOff > 100) + { + // Adjust the starting time forwards. + LONGLONG msecAdjustment = mymin(msecOff * + mClockFrequency.QuadPart / 1000, elapsedTime - + mPrevElapsedTime); + mStartTime.QuadPart += msecAdjustment; + elapsedTime -= msecAdjustment; + } + + // Store the current elapsed time for adjustments next time. + mPrevElapsedTime = elapsedTime; + + // Convert to microseconds. + unsigned long usecTicks = (unsigned long)(1000000 * elapsedTime / + mClockFrequency.QuadPart); + + return usecTicks; +#else + +#ifdef __CELLOS_LV2__ + __int64 freq=sys_time_get_timebase_frequency(); + double dFreq=((double) freq)/ 1000000.0; + typedef uint64_t __int64; + typedef __int64 ClockSize; + ClockSize newTime; + __asm __volatile__( "mftb %0" : "=r" (newTime) : : "memory"); + + return (newTime-mStartTime) / dFreq; +#else + + struct timeval currentTime; + gettimeofday(¤tTime, 0); + return (currentTime.tv_sec - mStartTime.tv_sec) * 1000000 + + (currentTime.tv_usec - mStartTime.tv_usec); +#endif//__CELLOS_LV2__ +#endif + } + + private: +#ifdef USE_WINDOWS_TIMERS + LARGE_INTEGER mClockFrequency; + DWORD mStartTick; + LONGLONG mPrevElapsedTime; + LARGE_INTEGER mStartTime; +#else +#ifdef __CELLOS_LV2__ + uint64_t mStartTime; +#else + struct timeval mStartTime; +#endif +#endif //__CELLOS_LV2__ + + }; + +#endif //USE_BT_CLOCK + + +#ifdef USE_QUICKPROF + + +#include +#include +#include +#include + + + + +namespace hidden +{ + /// A simple data structure representing a single timed block + /// of code. + struct ProfileBlock + { + ProfileBlock() + { + currentBlockStartMicroseconds = 0; + currentCycleTotalMicroseconds = 0; + lastCycleTotalMicroseconds = 0; + totalMicroseconds = 0; + } + + /// The starting time (in us) of the current block update. + unsigned long int currentBlockStartMicroseconds; + + /// The accumulated time (in us) spent in this block during the + /// current profiling cycle. + unsigned long int currentCycleTotalMicroseconds; + + /// The accumulated time (in us) spent in this block during the + /// past profiling cycle. + unsigned long int lastCycleTotalMicroseconds; + + /// The total accumulated time (in us) spent in this block. + unsigned long int totalMicroseconds; + }; + +}; + +/// A static class that manages timing for a set of profiling blocks. +class btProfiler +{ +public: + /// A set of ways to retrieve block timing data. + enum BlockTimingMethod + { + /// The total time spent in the block (in seconds) since the + /// profiler was initialized. + BLOCK_TOTAL_SECONDS, + + /// The total time spent in the block (in ms) since the + /// profiler was initialized. + BLOCK_TOTAL_MILLISECONDS, + + /// The total time spent in the block (in us) since the + /// profiler was initialized. + BLOCK_TOTAL_MICROSECONDS, + + /// The total time spent in the block, as a % of the total + /// elapsed time since the profiler was initialized. + BLOCK_TOTAL_PERCENT, + + /// The time spent in the block (in seconds) in the most recent + /// profiling cycle. + BLOCK_CYCLE_SECONDS, + + /// The time spent in the block (in ms) in the most recent + /// profiling cycle. + BLOCK_CYCLE_MILLISECONDS, + + /// The time spent in the block (in us) in the most recent + /// profiling cycle. + BLOCK_CYCLE_MICROSECONDS, + + /// The time spent in the block (in seconds) in the most recent + /// profiling cycle, as a % of the total cycle time. + BLOCK_CYCLE_PERCENT + }; + + /// Initializes the profiler. This must be called first. If this is + /// never called, the profiler is effectively disabled; all other + /// functions will return immediately. The first parameter + /// is the name of an output data file; if this string is not empty, + /// data will be saved on every profiling cycle; if this string is + /// empty, no data will be saved to a file. The second parameter + /// determines which timing method is used when printing data to the + /// output file. + inline static void init(const std::string outputFilename="", + BlockTimingMethod outputMethod=BLOCK_CYCLE_MILLISECONDS); + + /// Cleans up allocated memory. + inline static void destroy(); + + /// Begins timing the named block of code. + inline static void beginBlock(const std::string& name); + + /// Updates the accumulated time spent in the named block by adding + /// the elapsed time since the last call to startBlock for this block + /// name. + inline static void endBlock(const std::string& name); + + /// Returns the time spent in the named block according to the + /// given timing method. See comments on BlockTimingMethod for details. + inline static double getBlockTime(const std::string& name, + BlockTimingMethod method=BLOCK_CYCLE_MILLISECONDS); + + /// Defines the end of a profiling cycle. Use this regularly if you + /// want to generate detailed timing information. This must not be + /// called within a timing block. + inline static void endProfilingCycle(); + + /// A helper function that creates a string of statistics for + /// each timing block. This is mainly for printing an overall + /// summary to the command line. + inline static std::string createStatsString( + BlockTimingMethod method=BLOCK_TOTAL_PERCENT); + +//private: + inline btProfiler(); + + inline ~btProfiler(); + + /// Prints an error message to standard output. + inline static void printError(const std::string& msg) + { + //btAssert(0); + std::cout << "[QuickProf error] " << msg << std::endl; + } + + /// Determines whether the profiler is enabled. + static bool mEnabled; + + /// The clock used to time profile blocks. + static btClock mClock; + + /// The starting time (in us) of the current profiling cycle. + static unsigned long int mCurrentCycleStartMicroseconds; + + /// The duration (in us) of the most recent profiling cycle. + static unsigned long int mLastCycleDurationMicroseconds; + + /// Internal map of named profile blocks. + static std::map mProfileBlocks; + + /// The data file used if this feature is enabled in 'init.' + static std::ofstream mOutputFile; + + /// Tracks whether we have begun print data to the output file. + static bool mFirstFileOutput; + + /// The method used when printing timing data to an output file. + static BlockTimingMethod mFileOutputMethod; + + /// The number of the current profiling cycle. + static unsigned long int mCycleNumber; +}; + + +btProfiler::btProfiler() +{ + // This never gets called because a btProfiler instance is never + // created. +} + +btProfiler::~btProfiler() +{ + // This never gets called because a btProfiler instance is never + // created. +} + +void btProfiler::init(const std::string outputFilename, + BlockTimingMethod outputMethod) +{ + mEnabled = true; + + if (!outputFilename.empty()) + { + mOutputFile.open(outputFilename.c_str()); + } + + mFileOutputMethod = outputMethod; + + mClock.reset(); + + // Set the start time for the first cycle. + mCurrentCycleStartMicroseconds = mClock.getTimeMicroseconds(); +} + +void btProfiler::destroy() +{ + if (!mEnabled) + { + return; + } + + if (mOutputFile.is_open()) + { + mOutputFile.close(); + } + + // Destroy all ProfileBlocks. + while (!mProfileBlocks.empty()) + { + delete (*mProfileBlocks.begin()).second; + mProfileBlocks.erase(mProfileBlocks.begin()); + } +} + +void btProfiler::beginBlock(const std::string& name) +{ + if (!mEnabled) + { + return; + } + + if (name.empty()) + { + printError("Cannot allow unnamed profile blocks."); + return; + } + + hidden::ProfileBlock* block = mProfileBlocks[name]; + + if (!block) + { + // Create a new ProfileBlock. + mProfileBlocks[name] = new hidden::ProfileBlock(); + block = mProfileBlocks[name]; + } + + // We do this at the end to get more accurate results. + block->currentBlockStartMicroseconds = mClock.getTimeMicroseconds(); +} + +void btProfiler::endBlock(const std::string& name) +{ + if (!mEnabled) + { + return; + } + + // We do this at the beginning to get more accurate results. + unsigned long int endTick = mClock.getTimeMicroseconds(); + + hidden::ProfileBlock* block = mProfileBlocks[name]; + + if (!block) + { + // The named block does not exist. Print an error. + printError("The profile block named '" + name + + "' does not exist."); + return; + } + + unsigned long int blockDuration = endTick - + block->currentBlockStartMicroseconds; + block->currentCycleTotalMicroseconds += blockDuration; + block->totalMicroseconds += blockDuration; +} + +double btProfiler::getBlockTime(const std::string& name, + BlockTimingMethod method) +{ + if (!mEnabled) + { + return 0; + } + + hidden::ProfileBlock* block = mProfileBlocks[name]; + + if (!block) + { + // The named block does not exist. Print an error. + printError("The profile block named '" + name + + "' does not exist."); + return 0; + } + + double result = 0; + + switch(method) + { + case BLOCK_TOTAL_SECONDS: + result = (double)block->totalMicroseconds * (double)0.000001; + break; + case BLOCK_TOTAL_MILLISECONDS: + result = (double)block->totalMicroseconds * (double)0.001; + break; + case BLOCK_TOTAL_MICROSECONDS: + result = (double)block->totalMicroseconds; + break; + case BLOCK_TOTAL_PERCENT: + { + double timeSinceInit = (double)mClock.getTimeMicroseconds(); + if (timeSinceInit <= 0) + { + result = 0; + } + else + { + result = 100.0 * (double)block->totalMicroseconds / + timeSinceInit; + } + break; + } + case BLOCK_CYCLE_SECONDS: + result = (double)block->lastCycleTotalMicroseconds * + (double)0.000001; + break; + case BLOCK_CYCLE_MILLISECONDS: + result = (double)block->lastCycleTotalMicroseconds * + (double)0.001; + break; + case BLOCK_CYCLE_MICROSECONDS: + result = (double)block->lastCycleTotalMicroseconds; + break; + case BLOCK_CYCLE_PERCENT: + { + if (0 == mLastCycleDurationMicroseconds) + { + // We have not yet finished a cycle, so just return zero + // percent to avoid a divide by zero error. + result = 0; + } + else + { + result = 100.0 * (double)block->lastCycleTotalMicroseconds / + mLastCycleDurationMicroseconds; + } + break; + } + default: + break; + } + + return result; +} + +void btProfiler::endProfilingCycle() +{ + if (!mEnabled) + { + return; + } + + // Store the duration of the cycle that just finished. + mLastCycleDurationMicroseconds = mClock.getTimeMicroseconds() - + mCurrentCycleStartMicroseconds; + + // For each block, update data for the cycle that just finished. + std::map::iterator iter; + for (iter = mProfileBlocks.begin(); iter != mProfileBlocks.end(); ++iter) + { + hidden::ProfileBlock* block = (*iter).second; + block->lastCycleTotalMicroseconds = + block->currentCycleTotalMicroseconds; + block->currentCycleTotalMicroseconds = 0; + } + + if (mOutputFile.is_open()) + { + // Print data to the output file. + if (mFirstFileOutput) + { + // On the first iteration, print a header line that shows the + // names of each profiling block. + mOutputFile << "#cycle, "; + + for (iter = mProfileBlocks.begin(); iter != mProfileBlocks.end(); + ++iter) + { + mOutputFile << (*iter).first << ", "; + } + + mOutputFile << std::endl; + mFirstFileOutput = false; + } + + mOutputFile << mCycleNumber << ", "; + + for (iter = mProfileBlocks.begin(); iter != mProfileBlocks.end(); + ++iter) + { + mOutputFile << getBlockTime((*iter).first, mFileOutputMethod) + << ", "; + } + + mOutputFile << std::endl; + } + + ++mCycleNumber; + mCurrentCycleStartMicroseconds = mClock.getTimeMicroseconds(); +} + +std::string btProfiler::createStatsString(BlockTimingMethod method) +{ + if (!mEnabled) + { + return ""; + } + + std::string s; + std::string suffix; + + switch(method) + { + case BLOCK_TOTAL_SECONDS: + suffix = "s"; + break; + case BLOCK_TOTAL_MILLISECONDS: + suffix = "ms"; + break; + case BLOCK_TOTAL_MICROSECONDS: + suffix = "us"; + break; + case BLOCK_TOTAL_PERCENT: + { + suffix = "%"; + break; + } + case BLOCK_CYCLE_SECONDS: + suffix = "s"; + break; + case BLOCK_CYCLE_MILLISECONDS: + suffix = "ms"; + break; + case BLOCK_CYCLE_MICROSECONDS: + suffix = "us"; + break; + case BLOCK_CYCLE_PERCENT: + { + suffix = "%"; + break; + } + default: + break; + } + + std::map::iterator iter; + for (iter = mProfileBlocks.begin(); iter != mProfileBlocks.end(); ++iter) + { + if (iter != mProfileBlocks.begin()) + { + s += "\n"; + } + + char blockTime[64]; + sprintf(blockTime, "%lf", getBlockTime((*iter).first, method)); + + s += (*iter).first; + s += ": "; + s += blockTime; + s += " "; + s += suffix; + } + + return s; +} + + +#define BEGIN_PROFILE(a) btProfiler::beginBlock(a) +#define END_PROFILE(a) btProfiler::endBlock(a) + +#else //USE_QUICKPROF +#define BEGIN_PROFILE(a) +#define END_PROFILE(a) + +#endif //USE_QUICKPROF + +#endif //QUICK_PROF_H + + diff --git a/extern/bullet2/src/LinearMath/btRandom.h b/extern/bullet2/src/LinearMath/btRandom.h new file mode 100644 index 00000000000..fdf65e01caf --- /dev/null +++ b/extern/bullet2/src/LinearMath/btRandom.h @@ -0,0 +1,42 @@ +/* +Copyright (c) 2003-2006 Gino van den Bergen / 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 GEN_RANDOM_H +#define GEN_RANDOM_H + +#ifdef MT19937 + +#include +#include + +#define GEN_RAND_MAX UINT_MAX + +SIMD_FORCE_INLINE void GEN_srand(unsigned int seed) { init_genrand(seed); } +SIMD_FORCE_INLINE unsigned int GEN_rand() { return genrand_int32(); } + +#else + +#include + +#define GEN_RAND_MAX RAND_MAX + +SIMD_FORCE_INLINE void GEN_srand(unsigned int seed) { srand(seed); } +SIMD_FORCE_INLINE unsigned int GEN_rand() { return rand(); } + +#endif + +#endif + diff --git a/extern/bullet2/src/LinearMath/btScalar.h b/extern/bullet2/src/LinearMath/btScalar.h new file mode 100644 index 00000000000..01ad93e786a --- /dev/null +++ b/extern/bullet2/src/LinearMath/btScalar.h @@ -0,0 +1,181 @@ +/* +Copyright (c) 2003-2006 Gino van den Bergen / 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 SIMD___SCALAR_H +#define SIMD___SCALAR_H + +#include + +#include +#include +#include + +#ifdef WIN32 + + #if defined(__MINGW32__) || defined(__CYGWIN__) || (defined (_MSC_VER) && _MSC_VER < 1300) + #define SIMD_FORCE_INLINE inline + #define ATTRIBUTE_ALIGNED16(a) a + #else + #define BT_HAS_ALIGNED_ALOCATOR + #pragma warning(disable:4530) + #pragma warning(disable:4996) + #pragma warning(disable:4786) + #define SIMD_FORCE_INLINE __forceinline + #define ATTRIBUTE_ALIGNED16(a) __declspec(align(16)) a + #ifdef _XBOX + #define BT_USE_VMX128 + #else + #define BT_USE_SSE + #endif + #endif //__MINGW32__ + + #include + #define btAssert assert + //btFullAssert is optional, slows down a lot + #define btFullAssert(x) +#else + +#if defined (__CELLOS_LV2__) + #define SIMD_FORCE_INLINE inline + #define ATTRIBUTE_ALIGNED16(a) a __attribute__ ((aligned (16))) + #ifndef assert + #include + #endif + #define btAssert assert + //btFullAssert is optional, slows down a lot + #define btFullAssert(x) +#else + + //non-windows systems + + #define SIMD_FORCE_INLINE inline + #define ATTRIBUTE_ALIGNED16(a) a + #ifndef assert + #include + #endif + #define btAssert assert + //btFullAssert is optional, slows down a lot + #define btFullAssert(x) +#endif //__CELLOS_LV2__ +#endif + +/// older compilers (gcc 3.x) and Sun needs double version of sqrt etc. +/// exclude Apple Intel (i's assumed to be a Macbook or new Intel Dual Core Processor) +#if defined (__sun) || defined (__sun__) || defined (__sparc) || (defined (__APPLE__) && ! defined (__i386__)) +//use slow double float precision operation on those platforms +#ifndef BT_USE_DOUBLE_PRECISION +#define BT_FORCE_DOUBLE_FUNCTIONS +#endif +#endif + +#if defined(BT_USE_DOUBLE_PRECISION) +typedef double btScalar; +#else +typedef float btScalar; +#endif + + +#if defined(BT_USE_DOUBLE_PRECISION) || defined(BT_FORCE_DOUBLE_FUNCTIONS) + +SIMD_FORCE_INLINE btScalar btSqrt(btScalar x) { return sqrt(x); } +SIMD_FORCE_INLINE btScalar btFabs(btScalar x) { return fabs(x); } +SIMD_FORCE_INLINE btScalar btCos(btScalar x) { return cos(x); } +SIMD_FORCE_INLINE btScalar btSin(btScalar x) { return sin(x); } +SIMD_FORCE_INLINE btScalar btTan(btScalar x) { return tan(x); } +SIMD_FORCE_INLINE btScalar btAcos(btScalar x) { return acos(x); } +SIMD_FORCE_INLINE btScalar btAsin(btScalar x) { return asin(x); } +SIMD_FORCE_INLINE btScalar btAtan(btScalar x) { return atan(x); } +SIMD_FORCE_INLINE btScalar btAtan2(btScalar x, btScalar y) { return atan2(x, y); } +SIMD_FORCE_INLINE btScalar btExp(btScalar x) { return exp(x); } +SIMD_FORCE_INLINE btScalar btLog(btScalar x) { return log(x); } +SIMD_FORCE_INLINE btScalar btPow(btScalar x,btScalar y) { return pow(x,y); } + +#else + +SIMD_FORCE_INLINE btScalar btSqrt(btScalar x) { return sqrtf(x); } +SIMD_FORCE_INLINE btScalar btFabs(btScalar x) { return fabsf(x); } +SIMD_FORCE_INLINE btScalar btCos(btScalar x) { return cosf(x); } +SIMD_FORCE_INLINE btScalar btSin(btScalar x) { return sinf(x); } +SIMD_FORCE_INLINE btScalar btTan(btScalar x) { return tanf(x); } +SIMD_FORCE_INLINE btScalar btAcos(btScalar x) { return acosf(x); } +SIMD_FORCE_INLINE btScalar btAsin(btScalar x) { return asinf(x); } +SIMD_FORCE_INLINE btScalar btAtan(btScalar x) { return atanf(x); } +SIMD_FORCE_INLINE btScalar btAtan2(btScalar x, btScalar y) { return atan2f(x, y); } +SIMD_FORCE_INLINE btScalar btExp(btScalar x) { return expf(x); } +SIMD_FORCE_INLINE btScalar btLog(btScalar x) { return logf(x); } +SIMD_FORCE_INLINE btScalar btPow(btScalar x,btScalar y) { return powf(x,y); } + +#endif + +#define SIMD_2_PI btScalar(6.283185307179586232) +#define SIMD_PI (SIMD_2_PI * btScalar(0.5)) +#define SIMD_HALF_PI (SIMD_2_PI * btScalar(0.25)) +#define SIMD_RADS_PER_DEG (SIMD_2_PI / btScalar(360.0)) +#define SIMD_DEGS_PER_RAD (btScalar(360.0) / SIMD_2_PI) + +#ifdef BT_USE_DOUBLE_PRECISION +#define SIMD_EPSILON DBL_EPSILON +#define SIMD_INFINITY DBL_MAX +#else +#define SIMD_EPSILON FLT_EPSILON +#define SIMD_INFINITY FLT_MAX +#endif + +SIMD_FORCE_INLINE btScalar btAtan2Fast(btScalar y, btScalar x) +{ + btScalar coeff_1 = SIMD_PI / 4.0f; + btScalar coeff_2 = 3.0f * coeff_1; + btScalar abs_y = btFabs(y); + btScalar angle; + if (x >= 0.0f) { + btScalar r = (x - abs_y) / (x + abs_y); + angle = coeff_1 - coeff_1 * r; + } else { + btScalar r = (x + abs_y) / (abs_y - x); + angle = coeff_2 - coeff_1 * r; + } + return (y < 0.0f) ? -angle : angle; +} + +SIMD_FORCE_INLINE bool btFuzzyZero(btScalar x) { return btFabs(x) < SIMD_EPSILON; } + +SIMD_FORCE_INLINE bool btEqual(btScalar a, btScalar eps) { + return (((a) <= eps) && !((a) < -eps)); +} +SIMD_FORCE_INLINE bool btGreaterEqual (btScalar a, btScalar eps) { + return (!((a) <= eps)); +} + +/*SIMD_FORCE_INLINE btScalar btCos(btScalar x) { return cosf(x); } +SIMD_FORCE_INLINE btScalar btSin(btScalar x) { return sinf(x); } +SIMD_FORCE_INLINE btScalar btTan(btScalar x) { return tanf(x); } +SIMD_FORCE_INLINE btScalar btAcos(btScalar x) { return acosf(x); } +SIMD_FORCE_INLINE btScalar btAsin(btScalar x) { return asinf(x); } +SIMD_FORCE_INLINE btScalar btAtan(btScalar x) { return atanf(x); } +SIMD_FORCE_INLINE btScalar btAtan2(btScalar x, btScalar y) { return atan2f(x, y); } +*/ + +SIMD_FORCE_INLINE int btIsNegative(btScalar x) { + return x < btScalar(0.0) ? 1 : 0; +} + +SIMD_FORCE_INLINE btScalar btRadians(btScalar x) { return x * SIMD_RADS_PER_DEG; } +SIMD_FORCE_INLINE btScalar btDegrees(btScalar x) { return x * SIMD_DEGS_PER_RAD; } + +#define BT_DECLARE_HANDLE(name) typedef struct name##__ { int unused; } *name + + +#endif //SIMD___SCALAR_H diff --git a/extern/bullet2/src/LinearMath/btSimdMinMax.h b/extern/bullet2/src/LinearMath/btSimdMinMax.h new file mode 100644 index 00000000000..75e83f3c53f --- /dev/null +++ b/extern/bullet2/src/LinearMath/btSimdMinMax.h @@ -0,0 +1,41 @@ +/* +Copyright (c) 2003-2006 Gino van den Bergen / 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 SIMD_MINMAX_H +#define SIMD_MINMAX_H +#include "btScalar.h" + +template +SIMD_FORCE_INLINE const T& btMin(const T& a, const T& b) { + return b < a ? b : a; +} + +template +SIMD_FORCE_INLINE const T& btMax(const T& a, const T& b) { + return a < b ? b : a; +} + +template +SIMD_FORCE_INLINE void btSetMin(T& a, const T& b) { + if (a > b) a = b; +} + +template +SIMD_FORCE_INLINE void btSetMax(T& a, const T& b) { + if (a < b) a = b; +} + +#endif diff --git a/extern/bullet2/src/LinearMath/btStackAlloc.h b/extern/bullet2/src/LinearMath/btStackAlloc.h new file mode 100644 index 00000000000..d219b453537 --- /dev/null +++ b/extern/bullet2/src/LinearMath/btStackAlloc.h @@ -0,0 +1,106 @@ +/* +Copyright (c) 2003-2006 Gino van den Bergen / 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. +*/ + +/* +StackAlloc extracted from GJK-EPA collision solver by Nathanael Presson +Nov.2006 +*/ + +#ifndef BT_STACK_ALLOC +#define BT_STACK_ALLOC + +#include "btScalar.h" //for btAssert + +struct btBlock +{ + btBlock* previous; + unsigned char* address; +}; + +///StackAlloc provides some fast stack-based memory allocator (LIFO last-in first-out) +class btStackAlloc +{ +public: + + btStackAlloc(unsigned int size) { ctor();create(size); } + ~btStackAlloc() { destroy(); } + + inline void create(unsigned int size) + { + destroy(); + data = new unsigned char[size]; + totalsize = size; + } + inline void destroy() + { + btAssert(usedsize==0); + //Raise(L"StackAlloc is still in use"); + + if(usedsize==0) + { + if(!ischild) delete[] data; + data = 0; + usedsize = 0; + } + + } + unsigned char* allocate(unsigned int size) + { + const unsigned int nus(usedsize+size); + if(nusprevious = current; + pb->address = data+usedsize; + current = pb; + return(pb); + } + inline void endBlock(btBlock* block) + { + btAssert(block==current); + //Raise(L"Unmatched blocks"); + if(block==current) + { + current = block->previous; + usedsize = (unsigned int)((block->address-data)-sizeof(btBlock)); + } + } + +private: + void ctor() + { + data = 0; + totalsize = 0; + usedsize = 0; + current = 0; + ischild = false; + } + unsigned char* data; + unsigned int totalsize; + unsigned int usedsize; + btBlock* current; + bool ischild; +}; + +#endif //BT_STACK_ALLOC diff --git a/extern/bullet2/src/LinearMath/btTransform.h b/extern/bullet2/src/LinearMath/btTransform.h new file mode 100644 index 00000000000..2d55fec83a4 --- /dev/null +++ b/extern/bullet2/src/LinearMath/btTransform.h @@ -0,0 +1,206 @@ +/* +Copyright (c) 2003-2006 Gino van den Bergen / 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 btTransform_H +#define btTransform_H + +#include "btVector3.h" +#include "btMatrix3x3.h" + + +///btTransform supports rigid transforms (only translation and rotation, no scaling/shear) +class btTransform { + + +public: + + + btTransform() {} + + explicit SIMD_FORCE_INLINE btTransform(const btQuaternion& q, + const btVector3& c = btVector3(btScalar(0), btScalar(0), btScalar(0))) + : m_basis(q), + m_origin(c) + {} + + explicit SIMD_FORCE_INLINE btTransform(const btMatrix3x3& b, + const btVector3& c = btVector3(btScalar(0), btScalar(0), btScalar(0))) + : m_basis(b), + m_origin(c) + {} + + SIMD_FORCE_INLINE btTransform (const btTransform& other) + : m_basis(other.m_basis), + m_origin(other.m_origin) + { + } + + SIMD_FORCE_INLINE btTransform& operator=(const btTransform& other) + { + m_basis = other.m_basis; + m_origin = other.m_origin; + return *this; + } + + + SIMD_FORCE_INLINE void mult(const btTransform& t1, const btTransform& t2) { + m_basis = t1.m_basis * t2.m_basis; + m_origin = t1(t2.m_origin); + } + +/* void multInverseLeft(const btTransform& t1, const btTransform& t2) { + btVector3 v = t2.m_origin - t1.m_origin; + m_basis = btMultTransposeLeft(t1.m_basis, t2.m_basis); + m_origin = v * t1.m_basis; + } + */ + + + SIMD_FORCE_INLINE btVector3 operator()(const btVector3& x) const + { + return btVector3(m_basis[0].dot(x) + m_origin.x(), + m_basis[1].dot(x) + m_origin.y(), + m_basis[2].dot(x) + m_origin.z()); + } + + SIMD_FORCE_INLINE btVector3 operator*(const btVector3& x) const + { + return (*this)(x); + } + + SIMD_FORCE_INLINE btMatrix3x3& getBasis() { return m_basis; } + SIMD_FORCE_INLINE const btMatrix3x3& getBasis() const { return m_basis; } + + SIMD_FORCE_INLINE btVector3& getOrigin() { return m_origin; } + SIMD_FORCE_INLINE const btVector3& getOrigin() const { return m_origin; } + + btQuaternion getRotation() const { + btQuaternion q; + m_basis.getRotation(q); + return q; + } + template + void setValue(const Scalar2 *m) + { + m_basis.setValue(m); + m_origin.setValue(&m[12]); + } + + + void setFromOpenGLMatrix(const btScalar *m) + { + m_basis.setFromOpenGLSubMatrix(m); + m_origin.setValue(m[12],m[13],m[14]); + } + + void getOpenGLMatrix(btScalar *m) const + { + m_basis.getOpenGLSubMatrix(m); + m[12] = m_origin.x(); + m[13] = m_origin.y(); + m[14] = m_origin.z(); + m[15] = btScalar(1.0); + } + + SIMD_FORCE_INLINE void setOrigin(const btVector3& origin) + { + m_origin = origin; + } + + SIMD_FORCE_INLINE btVector3 invXform(const btVector3& inVec) const; + + + + SIMD_FORCE_INLINE void setBasis(const btMatrix3x3& basis) + { + m_basis = basis; + } + + SIMD_FORCE_INLINE void setRotation(const btQuaternion& q) + { + m_basis.setRotation(q); + } + + + + void setIdentity() + { + m_basis.setIdentity(); + m_origin.setValue(btScalar(0.0), btScalar(0.0), btScalar(0.0)); + } + + + btTransform& operator*=(const btTransform& t) + { + m_origin += m_basis * t.m_origin; + m_basis *= t.m_basis; + return *this; + } + + btTransform inverse() const + { + btMatrix3x3 inv = m_basis.transpose(); + return btTransform(inv, inv * -m_origin); + } + + btTransform inverseTimes(const btTransform& t) const; + + btTransform operator*(const btTransform& t) const; + + static btTransform getIdentity() + { + btTransform tr; + tr.setIdentity(); + return tr; + } + +private: + + btMatrix3x3 m_basis; + btVector3 m_origin; +}; + + +SIMD_FORCE_INLINE btVector3 +btTransform::invXform(const btVector3& inVec) const +{ + btVector3 v = inVec - m_origin; + return (m_basis.transpose() * v); +} + +SIMD_FORCE_INLINE btTransform +btTransform::inverseTimes(const btTransform& t) const +{ + btVector3 v = t.getOrigin() - m_origin; + return btTransform(m_basis.transposeTimes(t.m_basis), + v * m_basis); +} + +SIMD_FORCE_INLINE btTransform +btTransform::operator*(const btTransform& t) const +{ + return btTransform(m_basis * t.m_basis, + (*this)(t.m_origin)); +} + + + +#endif + + + + + diff --git a/extern/bullet2/src/LinearMath/btTransformUtil.h b/extern/bullet2/src/LinearMath/btTransformUtil.h new file mode 100644 index 00000000000..bc42fd166b6 --- /dev/null +++ b/extern/bullet2/src/LinearMath/btTransformUtil.h @@ -0,0 +1,138 @@ +/* +Copyright (c) 2003-2006 Gino van den Bergen / 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 SIMD_TRANSFORM_UTIL_H +#define SIMD_TRANSFORM_UTIL_H + +#include "btTransform.h" +#define ANGULAR_MOTION_THRESHOLD btScalar(0.5)*SIMD_HALF_PI + + + +#define SIMDSQRT12 btScalar(0.7071067811865475244008443621048490) + +#define btRecipSqrt(x) ((btScalar)(btScalar(1.0)/btSqrt(btScalar(x)))) /* reciprocal square root */ + +inline btVector3 btAabbSupport(const btVector3& halfExtents,const btVector3& supportDir) +{ + return btVector3(supportDir.x() < btScalar(0.0) ? -halfExtents.x() : halfExtents.x(), + supportDir.y() < btScalar(0.0) ? -halfExtents.y() : halfExtents.y(), + supportDir.z() < btScalar(0.0) ? -halfExtents.z() : halfExtents.z()); +} + + +inline void btPlaneSpace1 (const btVector3& n, btVector3& p, btVector3& q) +{ + if (btFabs(n.z()) > SIMDSQRT12) { + // choose p in y-z plane + btScalar a = n[1]*n[1] + n[2]*n[2]; + btScalar k = btRecipSqrt (a); + p.setValue(0,-n[2]*k,n[1]*k); + // set q = n x p + q.setValue(a*k,-n[0]*p[2],n[0]*p[1]); + } + else { + // choose p in x-y plane + btScalar a = n.x()*n.x() + n.y()*n.y(); + btScalar k = btRecipSqrt (a); + p.setValue(-n.y()*k,n.x()*k,0); + // set q = n x p + q.setValue(-n.z()*p.y(),n.z()*p.x(),a*k); + } +} + + + +/// Utils related to temporal transforms +class btTransformUtil +{ + +public: + + static void integrateTransform(const btTransform& curTrans,const btVector3& linvel,const btVector3& angvel,btScalar timeStep,btTransform& predictedTransform) + { + predictedTransform.setOrigin(curTrans.getOrigin() + linvel * timeStep); +// #define QUATERNION_DERIVATIVE + #ifdef QUATERNION_DERIVATIVE + btQuaternion predictedOrn = curTrans.getRotation(); + predictedOrn += (angvel * predictedOrn) * (timeStep * btScalar(0.5)); + predictedOrn.normalize(); + #else + //exponential map + btVector3 axis; + btScalar fAngle = angvel.length(); + //limit the angular motion + if (fAngle*timeStep > ANGULAR_MOTION_THRESHOLD) + { + fAngle = ANGULAR_MOTION_THRESHOLD / timeStep; + } + + if ( fAngle < btScalar(0.001) ) + { + // use Taylor's expansions of sync function + axis = angvel*( btScalar(0.5)*timeStep-(timeStep*timeStep*timeStep)*(btScalar(0.020833333333))*fAngle*fAngle ); + } + else + { + // sync(fAngle) = sin(c*fAngle)/t + axis = angvel*( btSin(btScalar(0.5)*fAngle*timeStep)/fAngle ); + } + btQuaternion dorn (axis.x(),axis.y(),axis.z(),btCos( fAngle*timeStep*btScalar(0.5) )); + btQuaternion orn0 = curTrans.getRotation(); + + btQuaternion predictedOrn = dorn * orn0; + predictedOrn.normalize(); + #endif + predictedTransform.setRotation(predictedOrn); + } + + static void calculateVelocity(const btTransform& transform0,const btTransform& transform1,btScalar timeStep,btVector3& linVel,btVector3& angVel) + { + linVel = (transform1.getOrigin() - transform0.getOrigin()) / timeStep; + btVector3 axis; + btScalar angle; + calculateDiffAxisAngle(transform0,transform1,axis,angle); + angVel = axis * angle / timeStep; + } + + static void calculateDiffAxisAngle(const btTransform& transform0,const btTransform& transform1,btVector3& axis,btScalar& angle) + { + + #ifdef USE_QUATERNION_DIFF + btQuaternion orn0 = transform0.getRotation(); + btQuaternion orn1a = transform1.getRotation(); + btQuaternion orn1 = orn0.farthest(orn1a); + btQuaternion dorn = orn1 * orn0.inverse(); +#else + btMatrix3x3 dmat = transform1.getBasis() * transform0.getBasis().inverse(); + btQuaternion dorn; + dmat.getRotation(dorn); +#endif//USE_QUATERNION_DIFF + + angle = dorn.getAngle(); + axis = btVector3(dorn.x(),dorn.y(),dorn.z()); + axis[3] = btScalar(0.); + //check for axis length + btScalar len = axis.length2(); + if (len < SIMD_EPSILON*SIMD_EPSILON) + axis = btVector3(btScalar(1.),btScalar(0.),btScalar(0.)); + else + axis /= btSqrt(len); + } + +}; + +#endif //SIMD_TRANSFORM_UTIL_H + diff --git a/extern/bullet2/src/LinearMath/btVector3.h b/extern/bullet2/src/LinearMath/btVector3.h new file mode 100644 index 00000000000..74d41ad2a19 --- /dev/null +++ b/extern/bullet2/src/LinearMath/btVector3.h @@ -0,0 +1,402 @@ +/* +Copyright (c) 2003-2006 Gino van den Bergen / 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 SIMD__VECTOR3_H +#define SIMD__VECTOR3_H + +#include "btQuadWord.h" + +///btVector3 can be used to represent 3D points and vectors. +///It has an un-used w component to suit 16-byte alignment when btVector3 is stored in containers. This extra component can be used by derived classes (Quaternion?) or by user +///Ideally, this class should be replaced by a platform optimized SIMD version that keeps the data in registers +class btVector3 : public btQuadWord { + +public: + SIMD_FORCE_INLINE btVector3() {} + + + + SIMD_FORCE_INLINE btVector3(const btScalar& x, const btScalar& y, const btScalar& z) + :btQuadWord(x,y,z,btScalar(0.)) + { + } + +// SIMD_FORCE_INLINE btVector3(const btScalar& x, const btScalar& y, const btScalar& z,const btScalar& w) +// : btQuadWord(x,y,z,w) +// { +// } + + + + SIMD_FORCE_INLINE btVector3& operator+=(const btVector3& v) + { + m_x += v.x(); m_y += v.y(); m_z += v.z(); + return *this; + } + + + + SIMD_FORCE_INLINE btVector3& operator-=(const btVector3& v) + { + m_x -= v.x(); m_y -= v.y(); m_z -= v.z(); + return *this; + } + + SIMD_FORCE_INLINE btVector3& operator*=(const btScalar& s) + { + m_x *= s; m_y *= s; m_z *= s; + return *this; + } + + SIMD_FORCE_INLINE btVector3& operator/=(const btScalar& s) + { + btFullAssert(s != btScalar(0.0)); + return *this *= btScalar(1.0) / s; + } + + SIMD_FORCE_INLINE btScalar dot(const btVector3& v) const + { + return m_x * v.x() + m_y * v.y() + m_z * v.z(); + } + + SIMD_FORCE_INLINE btScalar length2() const + { + return dot(*this); + } + + SIMD_FORCE_INLINE btScalar length() const + { + return btSqrt(length2()); + } + + SIMD_FORCE_INLINE btScalar distance2(const btVector3& v) const; + + SIMD_FORCE_INLINE btScalar distance(const btVector3& v) const; + + SIMD_FORCE_INLINE btVector3& normalize() + { + return *this /= length(); + } + + SIMD_FORCE_INLINE btVector3 normalized() const; + + SIMD_FORCE_INLINE btVector3 rotate( const btVector3& wAxis, const btScalar angle ); + + SIMD_FORCE_INLINE btScalar angle(const btVector3& v) const + { + btScalar s = btSqrt(length2() * v.length2()); + btFullAssert(s != btScalar(0.0)); + return btAcos(dot(v) / s); + } + + SIMD_FORCE_INLINE btVector3 absolute() const + { + return btVector3( + btFabs(m_x), + btFabs(m_y), + btFabs(m_z)); + } + + SIMD_FORCE_INLINE btVector3 cross(const btVector3& v) const + { + return btVector3( + m_y * v.z() - m_z * v.y(), + m_z * v.x() - m_x * v.z(), + m_x * v.y() - m_y * v.x()); + } + + SIMD_FORCE_INLINE btScalar triple(const btVector3& v1, const btVector3& v2) const + { + return m_x * (v1.y() * v2.z() - v1.z() * v2.y()) + + m_y * (v1.z() * v2.x() - v1.x() * v2.z()) + + m_z * (v1.x() * v2.y() - v1.y() * v2.x()); + } + + SIMD_FORCE_INLINE int minAxis() const + { + return m_x < m_y ? (m_x < m_z ? 0 : 2) : (m_y < m_z ? 1 : 2); + } + + SIMD_FORCE_INLINE int maxAxis() const + { + return m_x < m_y ? (m_y < m_z ? 2 : 1) : (m_x < m_z ? 2 : 0); + } + + SIMD_FORCE_INLINE int furthestAxis() const + { + return absolute().minAxis(); + } + + SIMD_FORCE_INLINE int closestAxis() const + { + return absolute().maxAxis(); + } + + SIMD_FORCE_INLINE void setInterpolate3(const btVector3& v0, const btVector3& v1, btScalar rt) + { + btScalar s = btScalar(1.0) - rt; + m_x = s * v0.x() + rt * v1.x(); + m_y = s * v0.y() + rt * v1.y(); + m_z = s * v0.z() + rt * v1.z(); + //don't do the unused w component + // m_co[3] = s * v0[3] + rt * v1[3]; + } + + SIMD_FORCE_INLINE btVector3 lerp(const btVector3& v, const btScalar& t) const + { + return btVector3(m_x + (v.x() - m_x) * t, + m_y + (v.y() - m_y) * t, + m_z + (v.z() - m_z) * t); + } + + + SIMD_FORCE_INLINE btVector3& operator*=(const btVector3& v) + { + m_x *= v.x(); m_y *= v.y(); m_z *= v.z(); + return *this; + } + + + +}; + +SIMD_FORCE_INLINE btVector3 +operator+(const btVector3& v1, const btVector3& v2) +{ + return btVector3(v1.x() + v2.x(), v1.y() + v2.y(), v1.z() + v2.z()); +} + +SIMD_FORCE_INLINE btVector3 +operator*(const btVector3& v1, const btVector3& v2) +{ + return btVector3(v1.x() * v2.x(), v1.y() * v2.y(), v1.z() * v2.z()); +} + +SIMD_FORCE_INLINE btVector3 +operator-(const btVector3& v1, const btVector3& v2) +{ + return btVector3(v1.x() - v2.x(), v1.y() - v2.y(), v1.z() - v2.z()); +} + +SIMD_FORCE_INLINE btVector3 +operator-(const btVector3& v) +{ + return btVector3(-v.x(), -v.y(), -v.z()); +} + +SIMD_FORCE_INLINE btVector3 +operator*(const btVector3& v, const btScalar& s) +{ + return btVector3(v.x() * s, v.y() * s, v.z() * s); +} + +SIMD_FORCE_INLINE btVector3 +operator*(const btScalar& s, const btVector3& v) +{ + return v * s; +} + +SIMD_FORCE_INLINE btVector3 +operator/(const btVector3& v, const btScalar& s) +{ + btFullAssert(s != btScalar(0.0)); + return v * (btScalar(1.0) / s); +} + +SIMD_FORCE_INLINE btVector3 +operator/(const btVector3& v1, const btVector3& v2) +{ + return btVector3(v1.x() / v2.x(),v1.y() / v2.y(),v1.z() / v2.z()); +} + +SIMD_FORCE_INLINE btScalar +dot(const btVector3& v1, const btVector3& v2) +{ + return v1.dot(v2); +} + + + +SIMD_FORCE_INLINE btScalar +distance2(const btVector3& v1, const btVector3& v2) +{ + return v1.distance2(v2); +} + + +SIMD_FORCE_INLINE btScalar +distance(const btVector3& v1, const btVector3& v2) +{ + return v1.distance(v2); +} + +SIMD_FORCE_INLINE btScalar +angle(const btVector3& v1, const btVector3& v2) +{ + return v1.angle(v2); +} + +SIMD_FORCE_INLINE btVector3 +cross(const btVector3& v1, const btVector3& v2) +{ + return v1.cross(v2); +} + +SIMD_FORCE_INLINE btScalar +triple(const btVector3& v1, const btVector3& v2, const btVector3& v3) +{ + return v1.triple(v2, v3); +} + +SIMD_FORCE_INLINE btVector3 +lerp(const btVector3& v1, const btVector3& v2, const btScalar& t) +{ + return v1.lerp(v2, t); +} + + +SIMD_FORCE_INLINE bool operator==(const btVector3& p1, const btVector3& p2) +{ + return p1.x() == p2.x() && p1.y() == p2.y() && p1.z() == p2.z(); +} + +SIMD_FORCE_INLINE btScalar btVector3::distance2(const btVector3& v) const +{ + return (v - *this).length2(); +} + +SIMD_FORCE_INLINE btScalar btVector3::distance(const btVector3& v) const +{ + return (v - *this).length(); +} + +SIMD_FORCE_INLINE btVector3 btVector3::normalized() const +{ + return *this / length(); +} + +SIMD_FORCE_INLINE btVector3 btVector3::rotate( const btVector3& wAxis, const btScalar angle ) +{ + // wAxis must be a unit lenght vector + + btVector3 o = wAxis * wAxis.dot( *this ); + btVector3 x = *this - o; + btVector3 y; + + y = wAxis.cross( *this ); + + return ( o + x * btCos( angle ) + y * btSin( angle ) ); +} + +class btVector4 : public btVector3 +{ +public: + + SIMD_FORCE_INLINE btVector4() {} + + + SIMD_FORCE_INLINE btVector4(const btScalar& x, const btScalar& y, const btScalar& z,const btScalar& w) + : btVector3(x,y,z) + { + m_unusedW = w; + } + + + SIMD_FORCE_INLINE btVector4 absolute4() const + { + return btVector4( + btFabs(m_x), + btFabs(m_y), + btFabs(m_z), + btFabs(m_unusedW)); + } + + + + btScalar getW() const { return m_unusedW;} + + + SIMD_FORCE_INLINE int maxAxis4() const + { + int maxIndex = -1; + btScalar maxVal = btScalar(-1e30); + if (m_x > maxVal) + { + maxIndex = 0; + maxVal = m_x; + } + if (m_y > maxVal) + { + maxIndex = 1; + maxVal = m_y; + } + if (m_z > maxVal) + { + maxIndex = 2; + maxVal = m_z; + } + if (m_unusedW > maxVal) + { + maxIndex = 3; + maxVal = m_unusedW; + } + + + + + return maxIndex; + + } + + + SIMD_FORCE_INLINE int minAxis4() const + { + int minIndex = -1; + btScalar minVal = btScalar(1e30); + if (m_x < minVal) + { + minIndex = 0; + minVal = m_x; + } + if (m_y < minVal) + { + minIndex = 1; + minVal = m_y; + } + if (m_z < minVal) + { + minIndex = 2; + minVal = m_z; + } + if (m_unusedW < minVal) + { + minIndex = 3; + minVal = m_unusedW; + } + + return minIndex; + + } + + + SIMD_FORCE_INLINE int closestAxis4() const + { + return absolute4().maxAxis4(); + } + +}; + +#endif //SIMD__VECTOR3_H diff --git a/extern/bullet2/src/Makefile b/extern/bullet2/src/Makefile new file mode 100644 index 00000000000..d7bb6a5e427 --- /dev/null +++ b/extern/bullet2/src/Makefile @@ -0,0 +1,68 @@ +# +# $Id: Makefile 14444 2008-04-16 22:40:48Z hos $ +# +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): none yet. +# +# ***** END GPL LICENSE BLOCK ***** +# + +LIBNAME = bullet2 +DIR = $(OCGDIR)/extern/$(LIBNAME) + +BULLETDIRS = \ +LinearMath \ +BulletCollision/BroadphaseCollision \ +BulletCollision/CollisionShapes \ +BulletCollision/NarrowPhaseCollision \ +BulletCollision/CollisionDispatch \ +BulletDynamics/ConstraintSolver \ +BulletDynamics/Vehicle \ +BulletDynamics/Dynamics + +CCSRCS = $(wildcard \ +LinearMath/*.cpp \ +BulletCollision/BroadphaseCollision/*.cpp \ +BulletCollision/CollisionShapes/*.cpp \ +BulletCollision/NarrowPhaseCollision/*.cpp \ +BulletCollision/CollisionDispatch/*.cpp \ +BulletDynamics/ConstraintSolver/*.cpp \ +BulletDynamics/Vehicle/*.cpp \ +BulletDynamics/Dynamics/*.cpp) + +CPPFLAGS += -D_LIB -I. -IBulletCollision -IBulletDynamics -ILinearMath + +all debug:: objdirs + +include nan_compile.mk + +.PHONY: objdirs clean +objdirs: + @for i in $(BULLETDIRS); do \ + [ -d $(DIR)/$(DEBUG_DIR)$$i ] || mkdir -p $(DIR)/$(DEBUG_DIR)$$i; \ + done + +clean:: + rm -rf $(DIR) + rm -rf $(NAN_BULLET2)/lib/libbullet2.a + rm -rf $(NAN_BULLET2)/include diff --git a/extern/bullet2/src/SConscript b/extern/bullet2/src/SConscript new file mode 100644 index 00000000000..19702782b0d --- /dev/null +++ b/extern/bullet2/src/SConscript @@ -0,0 +1,98 @@ +#!/usr/bin/python +import sys +import os + +Import('env') + +defs = 'USE_DOUBLES QHULL _LIB' +cflags = [] + +if env['OURPLATFORM']=='win32-vc': + defs += ' WIN32 NDEBUG _WINDOWS _LIB' + #cflags += ['/MT', '/W3', '/GX', '/O2', '/Op'] + cflags += ['/MT', '/W3', '/GX', '/Og', '/Ot', '/Ob1', '/Op', '/G6'] +elif env['OURPLATFORM']=='win32-mingw': + defs += ' NDEBUG' + cflags += ['-O2'] +elif sys.platform=='linux2' or sys.platform=='linux-i386' or sys.platform=='freebsd4' or sys.platform=='freebsd5': + defs += ' NDEBUG' + cflags += ['-O2'] +elif sys.platform=='darwin': + defs += ' NDEBUG' + cflags += ['-O2','-pipe', '-fPIC', '-funsigned-char', '-ffast-math'] + +linearmath_src = env.Glob("LinearMath/*.cpp") +bulletdyn_src = ["BulletDynamics/ConstraintSolver/btContactConstraint.cpp", + "BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.cpp", + "BulletDynamics/ConstraintSolver/btHingeConstraint.cpp", + "BulletDynamics/ConstraintSolver/btPoint2PointConstraint.cpp", + "BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.cpp", + "BulletDynamics/ConstraintSolver/btSolve2LinearConstraint.cpp", + "BulletDynamics/ConstraintSolver/btTypedConstraint.cpp", + "BulletDynamics/ConstraintSolver/btConeTwistConstraint.cpp", + "BulletDynamics/Dynamics/btDiscreteDynamicsWorld.cpp", + "BulletDynamics/Dynamics/btSimpleDynamicsWorld.cpp", + "BulletDynamics/Dynamics/btRigidBody.cpp", + "BulletDynamics/Vehicle/btRaycastVehicle.cpp", + "BulletDynamics/Dynamics/Bullet-C-API.cpp", + "BulletDynamics/Vehicle/btWheelInfo.cpp"] +collision_src = ["BulletCollision/BroadphaseCollision/btAxisSweep3.cpp", + "BulletCollision/BroadphaseCollision/btBroadphaseProxy.cpp", + "BulletCollision/BroadphaseCollision/btCollisionAlgorithm.cpp", + "BulletCollision/BroadphaseCollision/btDispatcher.cpp", + "BulletCollision/BroadphaseCollision/btOverlappingPairCache.cpp", + "BulletCollision/BroadphaseCollision/btSimpleBroadphase.cpp", + "BulletCollision/CollisionDispatch/btCollisionDispatcher.cpp", + "BulletCollision/CollisionDispatch/btCollisionObject.cpp", + "BulletCollision/CollisionDispatch/btCollisionWorld.cpp", + "BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.cpp", + "BulletCollision/CollisionDispatch/btConvexConcaveCollisionAlgorithm.cpp", + "BulletCollision/CollisionDispatch/btSphereSphereCollisionAlgorithm.cpp", + "BulletCollision/CollisionDispatch/btSphereBoxCollisionAlgorithm.cpp", + "BulletCollision/CollisionDispatch/btConvexConvexAlgorithm.cpp", + "BulletCollision/CollisionDispatch/btEmptyCollisionAlgorithm.cpp", + "BulletCollision/CollisionDispatch/btManifoldResult.cpp", + "BulletCollision/CollisionDispatch/btSimulationIslandManager.cpp", + "BulletCollision/CollisionDispatch/btUnionFind.cpp", + "BulletCollision/CollisionShapes/btBoxShape.cpp", + "BulletCollision/CollisionShapes/btBvhTriangleMeshShape.cpp", + "BulletCollision/CollisionShapes/btCollisionShape.cpp", + "BulletCollision/CollisionShapes/btCompoundShape.cpp", + "BulletCollision/CollisionShapes/btConcaveShape.cpp", + "BulletCollision/CollisionShapes/btConeShape.cpp", + "BulletCollision/CollisionShapes/btConvexHullShape.cpp", + "BulletCollision/CollisionShapes/btConvexShape.cpp", + "BulletCollision/CollisionShapes/btConvexTriangleMeshShape.cpp", + "BulletCollision/CollisionShapes/btCylinderShape.cpp", + "BulletCollision/CollisionShapes/btEmptyShape.cpp", + "BulletCollision/CollisionShapes/btMinkowskiSumShape.cpp", + "BulletCollision/CollisionShapes/btMultiSphereShape.cpp", + "BulletCollision/CollisionShapes/btOptimizedBvh.cpp", + "BulletCollision/CollisionShapes/btPolyhedralConvexShape.cpp", + "BulletCollision/CollisionShapes/btTetrahedronShape.cpp", + "BulletCollision/CollisionShapes/btSphereShape.cpp", + "BulletCollision/CollisionShapes/btStaticPlaneShape.cpp", + "BulletCollision/CollisionShapes/btStridingMeshInterface.cpp", + "BulletCollision/CollisionShapes/btTriangleCallback.cpp", + "BulletCollision/CollisionShapes/btTriangleBuffer.cpp", + "BulletCollision/CollisionShapes/btTriangleIndexVertexArray.cpp", + "BulletCollision/CollisionShapes/btTriangleMesh.cpp", + "BulletCollision/CollisionShapes/btTriangleMeshShape.cpp", + "BulletCollision/CollisionShapes/btHeightfieldTerrainShape.cpp", + "BulletCollision/NarrowPhaseCollision/btContinuousConvexCollision.cpp", + "BulletCollision/NarrowPhaseCollision/btGjkEpa.cpp", + "BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.cpp", + "BulletCollision/NarrowPhaseCollision/btConvexCast.cpp", + "BulletCollision/NarrowPhaseCollision/btGjkConvexCast.cpp", + "BulletCollision/NarrowPhaseCollision/btGjkPairDetector.cpp", + "BulletCollision/NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.cpp", + "BulletCollision/NarrowPhaseCollision/btPersistentManifold.cpp", + "BulletCollision/NarrowPhaseCollision/btRaycastCallback.cpp", + "BulletCollision/NarrowPhaseCollision/btSubSimplexConvexCast.cpp", + "BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.cpp"] + +incs = '. BulletCollision BulletDynamics LinearMath' + +env.BlenderLib ( libname = 'extern_bullet2linmath', sources=linearmath_src, includes=Split(incs), defines=Split(defs), libtype=['game2', 'player'], priority=[20, 170], compileflags=cflags ) +env.BlenderLib ( libname = 'extern_bullet2dynamics', sources=bulletdyn_src, includes=Split(incs), defines=Split(defs), libtype=['game2', 'player'], priority=[19, 169], compileflags=cflags ) +env.BlenderLib ( libname = 'extern_bullet2collision', sources=collision_src, includes=Split(incs), defines=Split(defs), libtype=['game2', 'player'], priority=[20, 170], compileflags=cflags ) diff --git a/extern/bullet2/src/btBulletCollisionCommon.h b/extern/bullet2/src/btBulletCollisionCommon.h new file mode 100644 index 00000000000..8417ccc671f --- /dev/null +++ b/extern/bullet2/src/btBulletCollisionCommon.h @@ -0,0 +1,61 @@ +/* +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 BULLET_COLLISION_COMMON_H +#define BULLET_COLLISION_COMMON_H + +///Common headerfile includes for Bullet Collision Detection + +///Bullet's btCollisionWorld and btCollisionObject definitions +#include "BulletCollision/CollisionDispatch/btCollisionWorld.h" +#include "BulletCollision/CollisionDispatch/btCollisionObject.h" + +///Collision Shapes +#include "BulletCollision/CollisionShapes/btBoxShape.h" +#include "BulletCollision/CollisionShapes/btSphereShape.h" +#include "BulletCollision/CollisionShapes/btCapsuleShape.h" +#include "BulletCollision/CollisionShapes/btCylinderShape.h" +#include "BulletCollision/CollisionShapes/btConeShape.h" +#include "BulletCollision/CollisionShapes/btStaticPlaneShape.h" +#include "BulletCollision/CollisionShapes/btConvexHullShape.h" +#include "BulletCollision/CollisionShapes/btTriangleMesh.h" +#include "BulletCollision/CollisionShapes/btConvexTriangleMeshShape.h" +#include "BulletCollision/CollisionShapes/btTriangleMeshShape.h" +#include "BulletCollision/CollisionShapes/btTriangleIndexVertexArray.h" +#include "BulletCollision/CollisionShapes/btCompoundShape.h" +#include "BulletCollision/CollisionShapes/btTetrahedronShape.h" +#include "BulletCollision/CollisionShapes/btEmptyShape.h" +#include "BulletCollision/CollisionShapes/btBvhTriangleMeshShape.h" +#include "BulletCollision/CollisionShapes/btMultiSphereShape.h" + +///Narrowphase Collision Detector +#include "BulletCollision/CollisionDispatch/btSphereSphereCollisionAlgorithm.h" +#include "BulletCollision/CollisionDispatch/btSphereBoxCollisionAlgorithm.h" + +///Dispatching and generation of collision pairs (broadphase) +#include "BulletCollision/CollisionDispatch/btCollisionDispatcher.h" +#include "BulletCollision/BroadphaseCollision/btSimpleBroadphase.h" +#include "BulletCollision/BroadphaseCollision/btAxisSweep3.h" + + +///Math library & Utils +#include "LinearMath/btQuaternion.h" +#include "LinearMath/btTransform.h" +#include "LinearMath/btDefaultMotionState.h" +#include "LinearMath/btQuickprof.h" +#include "LinearMath/btIDebugDraw.h" + +#endif //BULLET_COLLISION_COMMON_H + diff --git a/extern/bullet2/src/btBulletDynamicsCommon.h b/extern/bullet2/src/btBulletDynamicsCommon.h new file mode 100644 index 00000000000..25f016cba8a --- /dev/null +++ b/extern/bullet2/src/btBulletDynamicsCommon.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 BULLET_DYNAMICS_COMMON_H +#define BULLET_DYNAMICS_COMMON_H + +///Common headerfile includes for Bullet Dynamics, including Collision Detection +#include "btBulletCollisionCommon.h" + +#include "BulletDynamics/Dynamics/btDiscreteDynamicsWorld.h" +#include "BulletDynamics/Dynamics/btSimpleDynamicsWorld.h" +#include "BulletDynamics/Dynamics/btRigidBody.h" + +#include "BulletDynamics/ConstraintSolver/btPoint2PointConstraint.h" +#include "BulletDynamics/ConstraintSolver/btHingeConstraint.h" +#include "BulletDynamics/ConstraintSolver/btConeTwistConstraint.h" +#include "BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.h" + + +#include "BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.h" +///Vehicle simulation, with wheel contact simulated by raycasts +#include "BulletDynamics/Vehicle/btRaycastVehicle.h" + + + + + + +#endif //BULLET_DYNAMICS_COMMON_H + From a68c03e409e01285bee622b12313117012e486a8 Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Wed, 7 May 2008 20:42:16 +0000 Subject: [PATCH 088/246] Reason of all this work: Commiting my work-in-progress on reviewed collision system (better + general access to kdop, uses less memory, put it into BLI_* namespace and usage defined like existing BLI_kdtree_*). Deleted old kdop.c --- intern/sph/SConscript | 11 + intern/sph/extern/sph_extern.h | 51 ++ intern/sph/intern/sph.cpp | 51 ++ source/blender/blenkernel/BKE_cloth.h | 20 +- source/blender/blenkernel/BKE_collision.h | 36 +- source/blender/blenkernel/BKE_effect.h | 1 + source/blender/blenkernel/BKE_sph.h | 69 ++ source/blender/blenkernel/CCGSubSurf.h | 152 ++++ source/blender/blenkernel/SConscript | 1 + source/blender/blenkernel/bmesh_private.h | 71 ++ source/blender/blenkernel/intern/cloth.c | 126 +-- source/blender/blenkernel/intern/collision.c | 684 ++++++++------- source/blender/blenkernel/intern/kdop.c | 860 ------------------- source/blender/blenkernel/intern/modifier.c | 125 ++- source/blender/blenkernel/intern/sph.c | 490 +++++++++++ source/blender/blenlib/BLI_kdopbvh.h | 63 ++ source/blender/blenlib/intern/BLI_kdopbvh.c | 786 +++++++++++++++++ source/blender/blenloader/intern/readfile.c | 20 +- source/blender/include/butspace.h | 4 + source/blender/makesdna/DNA_modifier_types.h | 11 +- source/blender/makesdna/DNA_sph_types.h | 102 +++ source/blender/src/buttons_editing.c | 8 +- source/blender/src/buttons_object.c | 136 +++ source/blender/src/drawobject.c | 22 +- 24 files changed, 2614 insertions(+), 1286 deletions(-) create mode 100644 intern/sph/SConscript create mode 100644 intern/sph/extern/sph_extern.h create mode 100644 intern/sph/intern/sph.cpp create mode 100644 source/blender/blenkernel/BKE_sph.h create mode 100644 source/blender/blenkernel/CCGSubSurf.h create mode 100644 source/blender/blenkernel/bmesh_private.h delete mode 100644 source/blender/blenkernel/intern/kdop.c create mode 100644 source/blender/blenkernel/intern/sph.c create mode 100644 source/blender/blenlib/BLI_kdopbvh.h create mode 100644 source/blender/blenlib/intern/BLI_kdopbvh.c create mode 100644 source/blender/makesdna/DNA_sph_types.h diff --git a/intern/sph/SConscript b/intern/sph/SConscript new file mode 100644 index 00000000000..52243f767c3 --- /dev/null +++ b/intern/sph/SConscript @@ -0,0 +1,11 @@ +#!/usr/bin/python +import sys +import os +Import('env') + +sources = env.Glob('intern/*.cpp') + +incs = ' . extern intern' +defs = '' + +env.BlenderLib ('bf_sph', sources, Split(incs), Split(defs), libtype='blender', priority=0 ) diff --git a/intern/sph/extern/sph_extern.h b/intern/sph/extern/sph_extern.h new file mode 100644 index 00000000000..b4964739212 --- /dev/null +++ b/intern/sph/extern/sph_extern.h @@ -0,0 +1,51 @@ +/** + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) Blender Foundation. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): Daniel Genrich. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + */ + +#ifndef PW_EXTERN_H +#define PW_EXTERN_H + + + +#ifdef __cplusplus +extern "C" { +#endif +/* +void sph_init_cpp(struct SphModifierData *sphmd); +void sph_free_cpp(struct SphModifierData *sphmd); +int sph_simulate_cpp(struct Object *ob, struct SphModifierData *sphmd, float frame, struct ListBase *effectors); +*/ +#ifdef __cplusplus +} +#endif + + +#endif //PW_EXTERN_H + + diff --git a/intern/sph/intern/sph.cpp b/intern/sph/intern/sph.cpp new file mode 100644 index 00000000000..f7afa3c34eb --- /dev/null +++ b/intern/sph/intern/sph.cpp @@ -0,0 +1,51 @@ +/* pw.c +* +* +* ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* as published by the Free Software Foundation; either version 2 +* of the License, or (at your option) any later version. The Blender +* Foundation also sells licenses for use in proprietary software under +* the Blender License. See http://www.blender.org/BL/ for information +* about this. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software Foundation, +* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +* +* The Original Code is Copyright (C) Blender Foundation +* All rights reserved. +* +* Contributor(s): Daniel Genrich +* +* ***** END GPL/BL DUAL LICENSE BLOCK ***** +*/ + +#include + +#include "sph_extern.h" +/* +extern "C" void sph_init_cpp(struct SphModifierData *sphmd) +{ + +} +/* +extern "C" void sph_free_cpp(struct SphModifierData *sphmd) +{ + + +} + +extern "C" int sph_simulate_cpp(struct Object *ob, struct SphModifierData *sphmd, float frame, struct ListBase *effectors) +{ + + return 1; +} +*/ diff --git a/source/blender/blenkernel/BKE_cloth.h b/source/blender/blenkernel/BKE_cloth.h index af920e9762d..f01ed6bbea4 100644 --- a/source/blender/blenkernel/BKE_cloth.h +++ b/source/blender/blenkernel/BKE_cloth.h @@ -24,14 +24,14 @@ * * The Original Code is: all of this file. * - * Contributor(s): none yet. + * Contributor(s): Daniel Genrich. * * ***** END GPL LICENSE BLOCK ***** */ #ifndef BKE_CLOTH_H #define BKE_CLOTH_H -#include "float.h" +#include #include "BLI_linklist.h" #include "BKE_customdata.h" @@ -49,6 +49,9 @@ #include "BKE_collision.h" +#include "RE_raytrace.h" + + struct Object; struct MFace; @@ -102,7 +105,8 @@ typedef struct Cloth unsigned char old_solver_type; /* unused, only 1 solver here */ unsigned char pad2; short pad3; - struct BVH *tree; /* collision tree for this cloth object */ + struct BVHTree *bvhtree; /* collision tree for this cloth object */ + struct RayTree *selftree; /* collision tree for this cloth object */ struct MFace *mfaces; struct Implicit_Data *implicit; /* our implicit solver connects to this pointer */ struct Implicit_Data *implicitEM; /* our implicit solver connects to this pointer */ @@ -171,17 +175,10 @@ ClothSpring; /* These are the bits used in SimSettings.flags. */ typedef enum { - //CLOTH_SIMSETTINGS_FLAG_RESET = ( 1 << 1 ), // The CM object requires a reinitializaiton. CLOTH_SIMSETTINGS_FLAG_COLLOBJ = ( 1 << 2 ),// object is only collision object, no cloth simulation is done CLOTH_SIMSETTINGS_FLAG_GOAL = ( 1 << 3 ), // we have goals enabled CLOTH_SIMSETTINGS_FLAG_TEARING = ( 1 << 4 ),// true if tearing is enabled - //CLOTH_SIMSETTINGS_FLAG_CCACHE_PROTECT = ( 1 << 5 ), // true if tearing is enabled - //CLOTH_SIMSETTINGS_FLAG_EDITMODE = ( 1 << 6 ), // are we in editmode? -several things disabled - //CLOTH_SIMSETTINGS_FLAG_CCACHE_FFREE = ( 1 << 7 ), /* force cache freeing */ CLOTH_SIMSETTINGS_FLAG_SCALING = ( 1 << 8 ), /* is advanced scaling active? */ - //CLOTH_SIMSETTINGS_FLAG_LOADED = ( 1 << 9 ), /* did we just got load? */ - //CLOTH_SIMSETTINGS_FLAG_AUTOPROTECT = ( 1 << 10 ), /* is autoprotect enabled? */ - //CLOTH_SIMSETTINGS_FLAG_CCACHE_OUTDATED = (1 << 11), /* while protected, did cache get outdated? */ CLOTH_SIMSETTINGS_FLAG_CCACHE_EDIT = (1 << 12) /* edit cache in editmode */ } CLOTH_SIMSETTINGS_FLAGS; @@ -208,6 +205,7 @@ typedef enum CLOTH_SPRING_FLAG_NEEDED = ( 1 << 2 ), // springs has values to be applied } CLOTH_SPRINGS_FLAGS; + ///////////////////////////////////////////////// // collision.c //////////////////////////////////////////////// @@ -246,7 +244,7 @@ DerivedMesh *clothModifier_do ( ClothModifierData *clmd,Object *ob, DerivedMesh void cloth_update_normals ( ClothVertex *verts, int nVerts, MFace *face, int totface ); // needed for collision.c -void bvh_update_from_cloth ( ClothModifierData *clmd, int moving ); +void bvhtree_update_from_cloth ( ClothModifierData *clmd, int moving ); // needed for editmesh.c void cloth_write_cache ( Object *ob, ClothModifierData *clmd, float framenr ); diff --git a/source/blender/blenkernel/BKE_collision.h b/source/blender/blenkernel/BKE_collision.h index 7328f9108e3..f0298950f8b 100644 --- a/source/blender/blenkernel/BKE_collision.h +++ b/source/blender/blenkernel/BKE_collision.h @@ -32,7 +32,7 @@ #define BKE_COLLISIONS_H #include -#include "float.h" +#include #include #include @@ -47,6 +47,8 @@ #include "DNA_modifier_types.h" #include "DNA_object_types.h" +#include "BLI_kdopbvh.h" + struct Object; struct Cloth; struct MFace; @@ -102,10 +104,16 @@ BVH; typedef void ( *CM_COLLISION_RESPONSE ) ( ModifierData *md1, ModifierData *md2, CollisionTree *tree1, CollisionTree *tree2 ); // needed for collision.c -int bvh_traverse ( ModifierData * md1, ModifierData * md2, CollisionTree * tree1, CollisionTree * tree2, float step, CM_COLLISION_RESPONSE collision_response, int selfcollision); +int bvh_traverse ( ModifierData * md1, ModifierData * md2, CollisionTree * tree1, CollisionTree * tree2, float step, CM_COLLISION_RESPONSE collision_response, int selfcollision ); //////////////////////////////////////// +/* COLLISION FLAGS */ +typedef enum +{ + COLLISION_IN_FUTURE = ( 1 << 1 ), +} COLLISION_FLAGS; + //////////////////////////////////////// // used for collisions in kdop.c and also collision.c @@ -119,10 +127,10 @@ typedef struct CollPair float normal[3]; float vector[3]; // unnormalized collision vector: p2-p1 float pa[3], pb[3]; // collision point p1 on face1, p2 on face2 - int lastsign; // indicates if the distance sign has changed, unused itm + int flag; float time; // collision time, from 0 up to 1 - unsigned int ap1, ap2, ap3, bp1, bp2, bp3; - unsigned int pointsb[4]; + int ap1, ap2, ap3, bp1, bp2, bp3; + int pointsb[4]; } CollPair; @@ -160,8 +168,9 @@ FaceCollPair; // NOTICE: mvert-routines for building + update the BVH are the most native ones // builds bounding volume hierarchy -void bvh_build (BVH *bvh); -BVH *bvh_build_from_mvert (MFace *mfaces, unsigned int numfaces, MVert *x, unsigned int numverts, float epsilon); +void bvh_build ( BVH *bvh ); +BVH *bvh_build_from_mvert ( MFace *mfaces, unsigned int numfaces, MVert *x, unsigned int numverts, float epsilon ); +BVHTree *bvhtree_build_from_mvert ( MFace *mfaces, unsigned int numfaces, MVert *x, unsigned int numverts, float epsilon ); // frees the same void bvh_free ( BVH * bvh ); @@ -169,20 +178,21 @@ void bvh_free ( BVH * bvh ); // checks two bounding volume hierarchies for potential collisions and returns some list with those -// update bounding volumes, needs updated positions in bvh->current_xold (static) +// update bounding volumes, needs updated positions in bvh->current_xold (static) // and also bvh->current_x if moving==1 -void bvh_update_from_mvert(BVH * bvh, MVert *x, unsigned int numverts, MVert *xnew, int moving); -void bvh_update(BVH * bvh, int moving); +void bvh_update_from_mvert ( BVH * bvh, MVert *x, unsigned int numverts, MVert *xnew, int moving ); +void bvh_update ( BVH * bvh, int moving ); +void bvhtree_update_from_mvert ( BVHTree * bvhtree, MFace *faces, int numfaces, MVert *x, MVert *xnew, int numverts, int moving ); LinkNode *BLI_linklist_append_fast ( LinkNode **listp, void *ptr ); // move Collision modifier object inter-frame with step = [0,1] // defined in collisions.c -void collision_move_object(CollisionModifierData *collmd, float step, float prevstep); +void collision_move_object ( CollisionModifierData *collmd, float step, float prevstep ); // interface for collision functions -void collisions_compute_barycentric (float pv[3], float p1[3], float p2[3], float p3[3], float *w1, float *w2, float *w3); -void interpolateOnTriangle(float to[3], float v1[3], float v2[3], float v3[3], double w1, double w2, double w3); +void collisions_compute_barycentric ( float pv[3], float p1[3], float p2[3], float p3[3], float *w1, float *w2, float *w3 ); +void interpolateOnTriangle ( float to[3], float v1[3], float v2[3], float v3[3], double w1, double w2, double w3 ); ///////////////////////////////////////////////// diff --git a/source/blender/blenkernel/BKE_effect.h b/source/blender/blenkernel/BKE_effect.h index 3763a659f2f..15816699285 100644 --- a/source/blender/blenkernel/BKE_effect.h +++ b/source/blender/blenkernel/BKE_effect.h @@ -31,6 +31,7 @@ #ifndef BKE_EFFECT_H #define BKE_EFFECT_H +#include "DNA_effect_types.h" #include "DNA_object_types.h" struct Effect; diff --git a/source/blender/blenkernel/BKE_sph.h b/source/blender/blenkernel/BKE_sph.h new file mode 100644 index 00000000000..9fa42f5acb2 --- /dev/null +++ b/source/blender/blenkernel/BKE_sph.h @@ -0,0 +1,69 @@ +/** + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) Blender Foundation. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): Daniel Genrich. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + */ +#ifndef BKE_SPH_H +#define BKE_SPH_H + + +#include "BKE_DerivedMesh.h" +#include "BKE_utildefines.h" + +#include "BLI_linklist.h" + +#include "DNA_modifier_types.h" +#include "DNA_object_types.h" + +void sph_init(SphModifierData *sphmd); +void sph_free_modifier (SphModifierData *sphmd); +DerivedMesh *sphModifier_do(SphModifierData *sphmd,Object *ob, DerivedMesh *dm, int useRenderParams, int isFinalCalc); +int sph_init_all (SphModifierData *sphmd, DerivedMesh *dm, Object *ob); + + +/* SIMULATION FLAGS: goal flags,.. */ +/* These are the bits used in SimSettings.flags. */ +// first 16 (short) flags are used for fluid type identification +typedef enum +{ + SPH_SIMSETTINGS_FLAG_FLUID = ( 1 << 0 ), // Fluid object? + SPH_SIMSETTINGS_FLAG_OBSTACLE = ( 1 << 1 ), // Obstacle? + SPH_SIMSETTINGS_FLAG_DOMAIN = ( 1 << 2 ), // Fluid domain + + SPH_SIMSETTINGS_FLAG_GHOSTS = ( 1 << 16 ), // use ghost particles? + SPH_SIMSETTINGS_FLAG_OFFLINE = ( 1 << 17 ), // do offline simulation? + SPH_SIMSETTINGS_FLAG_MULTIRES = ( 1 << 18 ), // use multires? + SPH_SIMSETTINGS_FLAG_VORTICITY = ( 1 << 19 ), // use vorticity enhancement? + SPH_SIMSETTINGS_FLAG_BAKING = ( 1 << 20 ), // is domain baking? + SPH_SIMSETTINGS_FLAG_INIT = ( 1 << 21 ), // inited? +} SPH_SIMSETTINGS_FLAGS; + + +#endif //BKE_SPH_H + + + diff --git a/source/blender/blenkernel/CCGSubSurf.h b/source/blender/blenkernel/CCGSubSurf.h new file mode 100644 index 00000000000..a8269b7ada0 --- /dev/null +++ b/source/blender/blenkernel/CCGSubSurf.h @@ -0,0 +1,152 @@ +/* $Id: CCGSubSurf.h 12931 2007-12-17 18:20:48Z theeth $ */ + +typedef void* CCGMeshHDL; +typedef void* CCGVertHDL; +typedef void* CCGEdgeHDL; +typedef void* CCGFaceHDL; + +typedef struct _CCGVert CCGVert; +typedef struct _CCGEdge CCGEdge; +typedef struct _CCGFace CCGFace; + +typedef struct _CCGMeshIFC CCGMeshIFC; +struct _CCGMeshIFC { + int vertUserSize, edgeUserSize, faceUserSize; + + int vertDataSize; +}; + +/***/ + +typedef void* CCGAllocatorHDL; + +typedef struct _CCGAllocatorIFC CCGAllocatorIFC; +struct _CCGAllocatorIFC { + void* (*alloc) (CCGAllocatorHDL a, int numBytes); + void* (*realloc) (CCGAllocatorHDL a, void *ptr, int newSize, int oldSize); + void (*free) (CCGAllocatorHDL a, void *ptr); + void (*release) (CCGAllocatorHDL a); +}; + +/***/ + +typedef enum { + eCCGError_None = 0, + + eCCGError_InvalidSyncState, + eCCGError_InvalidValue, +} CCGError; + +/***/ + +typedef struct _CCGSubSurf CCGSubSurf; + +CCGSubSurf* ccgSubSurf_new (CCGMeshIFC *ifc, int subdivisionLevels, CCGAllocatorIFC *allocatorIFC, CCGAllocatorHDL allocator); +void ccgSubSurf_free (CCGSubSurf *ss); + +CCGError ccgSubSurf_sync (CCGSubSurf *ss); + +CCGError ccgSubSurf_initFullSync (CCGSubSurf *ss); +CCGError ccgSubSurf_initPartialSync (CCGSubSurf *ss); + +CCGError ccgSubSurf_syncVert (CCGSubSurf *ss, CCGVertHDL vHDL, void *vertData, int seam, CCGVert **v_r); +CCGError ccgSubSurf_syncEdge (CCGSubSurf *ss, CCGEdgeHDL eHDL, CCGVertHDL e_vHDL0, CCGVertHDL e_vHDL1, float crease, CCGEdge **e_r); +CCGError ccgSubSurf_syncFace (CCGSubSurf *ss, CCGFaceHDL fHDL, int numVerts, CCGVertHDL *vHDLs, CCGFace **f_r); + +CCGError ccgSubSurf_syncVertDel (CCGSubSurf *ss, CCGVertHDL vHDL); +CCGError ccgSubSurf_syncEdgeDel (CCGSubSurf *ss, CCGEdgeHDL eHDL); +CCGError ccgSubSurf_syncFaceDel (CCGSubSurf *ss, CCGFaceHDL fHDL); + +CCGError ccgSubSurf_processSync (CCGSubSurf *ss); + +CCGError ccgSubSurf_setSubdivisionLevels (CCGSubSurf *ss, int subdivisionLevels); + +CCGError ccgSubSurf_setAllowEdgeCreation (CCGSubSurf *ss, int allowEdgeCreation, float defaultCreaseValue, void *defaultUserData); +void ccgSubSurf_getAllowEdgeCreation (CCGSubSurf *ss, int *allowEdgeCreation_r, float *defaultCreaseValue_r, void *defaultUserData_r); + +void ccgSubSurf_getUseAgeCounts (CCGSubSurf *ss, int *useAgeCounts_r, int *vertUserOffset_r, int *edgeUserOffset_r, int *faceUserOffset_r); +CCGError ccgSubSurf_setUseAgeCounts (CCGSubSurf *ss, int useAgeCounts, int vertUserOffset, int edgeUserOffset, int faceUserOffset); + +CCGError ccgSubSurf_setCalcVertexNormals (CCGSubSurf *ss, int useVertNormals, int normalDataOffset); + +/***/ + +int ccgSubSurf_getNumVerts (CCGSubSurf *ss); +int ccgSubSurf_getNumEdges (CCGSubSurf *ss); +int ccgSubSurf_getNumFaces (CCGSubSurf *ss); + +int ccgSubSurf_getSubdivisionLevels (CCGSubSurf *ss); +int ccgSubSurf_getEdgeSize (CCGSubSurf *ss); +int ccgSubSurf_getEdgeLevelSize (CCGSubSurf *ss, int level); +int ccgSubSurf_getGridSize (CCGSubSurf *ss); +int ccgSubSurf_getGridLevelSize (CCGSubSurf *ss, int level); + +CCGVert* ccgSubSurf_getVert (CCGSubSurf *ss, CCGVertHDL v); +CCGVertHDL ccgSubSurf_getVertVertHandle (CCGSubSurf *ss, CCGVert *v); +int ccgSubSurf_getVertNumFaces (CCGSubSurf *ss, CCGVert *v); +CCGFace* ccgSubSurf_getVertFace (CCGSubSurf *ss, CCGVert *v, int index); +int ccgSubSurf_getVertNumEdges (CCGSubSurf *ss, CCGVert *v); +CCGEdge* ccgSubSurf_getVertEdge (CCGSubSurf *ss, CCGVert *v, int index); + +int ccgSubSurf_getVertAge (CCGSubSurf *ss, CCGVert *v); +void* ccgSubSurf_getVertUserData (CCGSubSurf *ss, CCGVert *v); +void* ccgSubSurf_getVertData (CCGSubSurf *ss, CCGVert *v); +void* ccgSubSurf_getVertLevelData (CCGSubSurf *ss, CCGVert *v, int level); + +CCGEdge* ccgSubSurf_getEdge (CCGSubSurf *ss, CCGEdgeHDL e); +CCGEdgeHDL ccgSubSurf_getEdgeEdgeHandle (CCGSubSurf *ss, CCGEdge *e); +int ccgSubSurf_getEdgeNumFaces (CCGSubSurf *ss, CCGEdge *e); +CCGFace* ccgSubSurf_getEdgeFace (CCGSubSurf *ss, CCGEdge *e, int index); +CCGVert* ccgSubSurf_getEdgeVert0 (CCGSubSurf *ss, CCGEdge *e); +CCGVert* ccgSubSurf_getEdgeVert1 (CCGSubSurf *ss, CCGEdge *e); +float ccgSubSurf_getEdgeCrease (CCGSubSurf *ss, CCGEdge *e); + +int ccgSubSurf_getEdgeAge (CCGSubSurf *ss, CCGEdge *e); +void* ccgSubSurf_getEdgeUserData (CCGSubSurf *ss, CCGEdge *e); +void* ccgSubSurf_getEdgeDataArray (CCGSubSurf *ss, CCGEdge *e); +void* ccgSubSurf_getEdgeData (CCGSubSurf *ss, CCGEdge *e, int x); +void* ccgSubSurf_getEdgeLevelData (CCGSubSurf *ss, CCGEdge *e, int x, int level); + +CCGFace* ccgSubSurf_getFace (CCGSubSurf *ss, CCGFaceHDL f); +CCGFaceHDL ccgSubSurf_getFaceFaceHandle (CCGSubSurf *ss, CCGFace *f); +int ccgSubSurf_getFaceNumVerts (CCGSubSurf *ss, CCGFace *f); +CCGVert* ccgSubSurf_getFaceVert (CCGSubSurf *ss, CCGFace *f, int index); +CCGEdge* ccgSubSurf_getFaceEdge (CCGSubSurf *ss, CCGFace *f, int index); +int ccgSubSurf_getFaceEdgeIndex (CCGSubSurf *ss, CCGFace *f, CCGEdge *e); + +int ccgSubSurf_getFaceAge (CCGSubSurf *ss, CCGFace *f); +void* ccgSubSurf_getFaceUserData (CCGSubSurf *ss, CCGFace *f); +void* ccgSubSurf_getFaceCenterData (CCGSubSurf *ss, CCGFace *f); +void* ccgSubSurf_getFaceGridEdgeDataArray (CCGSubSurf *ss, CCGFace *f, int gridIndex); +void* ccgSubSurf_getFaceGridEdgeData (CCGSubSurf *ss, CCGFace *f, int gridIndex, int x); +void* ccgSubSurf_getFaceGridDataArray (CCGSubSurf *ss, CCGFace *f, int gridIndex); +void* ccgSubSurf_getFaceGridData (CCGSubSurf *ss, CCGFace *f, int gridIndex, int x, int y); + +int ccgSubSurf_getNumFinalVerts (CCGSubSurf *ss); +int ccgSubSurf_getNumFinalEdges (CCGSubSurf *ss); +int ccgSubSurf_getNumFinalFaces (CCGSubSurf *ss); + +/***/ + +typedef struct _CCGVertIterator CCGVertIterator; +typedef struct _CCGEdgeIterator CCGEdgeIterator; +typedef struct _CCGFaceIterator CCGFaceIterator; + +CCGVertIterator* ccgSubSurf_getVertIterator (CCGSubSurf *ss); +CCGEdgeIterator* ccgSubSurf_getEdgeIterator (CCGSubSurf *ss); +CCGFaceIterator* ccgSubSurf_getFaceIterator (CCGSubSurf *ss); + +CCGVert* ccgVertIterator_getCurrent (CCGVertIterator *vi); +int ccgVertIterator_isStopped (CCGVertIterator *vi); +void ccgVertIterator_next (CCGVertIterator *vi); +void ccgVertIterator_free (CCGVertIterator *vi); + +CCGEdge* ccgEdgeIterator_getCurrent (CCGEdgeIterator *ei); +int ccgEdgeIterator_isStopped (CCGEdgeIterator *ei); +void ccgEdgeIterator_next (CCGEdgeIterator *ei); +void ccgEdgeIterator_free (CCGEdgeIterator *ei); + +CCGFace* ccgFaceIterator_getCurrent (CCGFaceIterator *fi); +int ccgFaceIterator_isStopped (CCGFaceIterator *fi); +void ccgFaceIterator_next (CCGFaceIterator *fi); +void ccgFaceIterator_free (CCGFaceIterator *fi); diff --git a/source/blender/blenkernel/SConscript b/source/blender/blenkernel/SConscript index 1bb98239a68..4f77e4f42a7 100644 --- a/source/blender/blenkernel/SConscript +++ b/source/blender/blenkernel/SConscript @@ -10,6 +10,7 @@ incs += ' #/intern/iksolver/extern ../blenloader ../quicktime' incs += ' #/extern/bullet2/src' incs += ' #/intern/bmfont' incs += ' #/intern/opennl/extern' +incs += ' #/intern/sph/extern' incs += ' ' + env['BF_PYTHON_INC'] incs += ' ' + env['BF_OPENGL_INC'] diff --git a/source/blender/blenkernel/bmesh_private.h b/source/blender/blenkernel/bmesh_private.h new file mode 100644 index 00000000000..ad90398bf66 --- /dev/null +++ b/source/blender/blenkernel/bmesh_private.h @@ -0,0 +1,71 @@ +/** + * BME_private.h jan 2007 + * + * low level, 'private' function prototypes for bmesh kernel. + * + * $Id: BKE_bmesh.h,v 1.00 2007/01/17 17:42:01 Briggs Exp $ + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2004 Blender Foundation. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): Geoffrey Bantle. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#ifndef BMESH_PRIVATE +#define BMESH_PRIVATE + +#include "BKE_bmesh.h" + +/*ALLOCATION/DEALLOCATION*/ +struct BME_Vert *BME_addvertlist(struct BME_Mesh *bm, struct BME_Vert *example); +struct BME_Edge *BME_addedgelist(struct BME_Mesh *bm, struct BME_Vert *v1, struct BME_Vert *v2, struct BME_Edge *example); +struct BME_Poly *BME_addpolylist(struct BME_Mesh *bm, struct BME_Poly *example); +struct BME_Loop *BME_create_loop(struct BME_Mesh *bm, struct BME_Vert *v, struct BME_Edge *e, struct BME_Poly *f, struct BME_Loop *example); + +void BME_free_vert(struct BME_Mesh *bm, struct BME_Vert *v); +void BME_free_edge(struct BME_Mesh *bm, struct BME_Edge *e); +void BME_free_poly(struct BME_Mesh *bm, struct BME_Poly *f); +void BME_free_loop(struct BME_Mesh *bm, struct BME_Loop *l); +void BME_delete_loop(struct BME_Mesh *bm, struct BME_Loop *l); + +/*DOUBLE CIRCULAR LINKED LIST FUNCTIONS*/ +void BME_cycle_append(void *h, void *nt); +int BME_cycle_remove(void *h, void *remn); +int BME_cycle_validate(int len, void *h); +/*DISK CYCLE MANAGMENT*/ +int BME_disk_append_edge(struct BME_Edge *e, struct BME_Vert *v); +void BME_disk_remove_edge(struct BME_Edge *e, struct BME_Vert *v); +/*RADIAL CYCLE MANAGMENT*/ +void BME_radial_append(struct BME_Edge *e, struct BME_Loop *l); +void BME_radial_remove_loop(struct BME_Loop *l, struct BME_Edge *e); + +/*MISC FUNCTIONS*/ +int BME_edge_swapverts(struct BME_Edge *e, struct BME_Vert *orig, struct BME_Vert *new); /*relink edge*/ +int BME_disk_hasedge(struct BME_Vert *v, struct BME_Edge *e); + +/*Error reporting. Shouldnt be called by tools ever.*/ +void BME_error(void); +#endif diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c index 4be4434dfda..192ebd90faa 100644 --- a/source/blender/blenkernel/intern/cloth.c +++ b/source/blender/blenkernel/intern/cloth.c @@ -45,6 +45,8 @@ #include "BKE_pointcache.h" +#include "BLI_kdopbvh.h" + #ifdef _WIN32 void tstart ( void ) {} @@ -151,13 +153,14 @@ void cloth_init ( ClothModifierData *clmd ) clmd->sim_parms->goalfrict = 0.0f; } - -BVH *bvh_build_from_cloth (ClothModifierData *clmd, float epsilon) +BVHTree *bvhtree_build_from_cloth (ClothModifierData *clmd, float epsilon) { - unsigned int i = 0; - BVH *bvh=NULL; + int i; + BVHTree *bvhtree; Cloth *cloth = clmd->clothObject; - ClothVertex *verts = NULL; + ClothVertex *verts; + MFace *mfaces; + float co[12]; if(!clmd) return NULL; @@ -168,69 +171,86 @@ BVH *bvh_build_from_cloth (ClothModifierData *clmd, float epsilon) return NULL; verts = cloth->verts; + mfaces = cloth->mfaces; // in the moment, return zero if no faces there if(!cloth->numfaces) return NULL; - bvh = MEM_callocN(sizeof(BVH), "BVH"); - if (bvh == NULL) + // create quadtree with k=26 + bvhtree = BLI_bvhtree_new(cloth->numfaces, epsilon, 4, 26); + + // fill tree + for(i = 0; i < cloth->numfaces; i++, mfaces++) { - printf("bvh: Out of memory.\n"); - return NULL; + VECCOPY(&co[0*3], verts[mfaces->v1].xold); + VECCOPY(&co[1*3], verts[mfaces->v2].xold); + VECCOPY(&co[2*3], verts[mfaces->v3].xold); + + if(mfaces->v4) + VECCOPY(&co[3*3], verts[mfaces->v4].xold); + + BLI_bvhtree_insert(bvhtree, i, co, (mfaces->v4 ? 4 : 3)); } - // springs = cloth->springs; - // numsprings = cloth->numsprings; - - bvh->epsilon = epsilon; - bvh->numfaces = cloth->numfaces; - bvh->mfaces = cloth->mfaces; - - bvh->numverts = cloth->numverts; + // balance tree + BLI_bvhtree_balance(bvhtree); - bvh->current_x = MEM_callocN ( sizeof ( MVert ) * bvh->numverts, "bvh->current_x" ); - - if (bvh->current_x == NULL) - { - printf("bvh: Out of memory.\n"); - MEM_freeN(bvh); - return NULL; - } - - for(i = 0; i < bvh->numverts; i++) - { - VECCOPY(bvh->current_x[i].co, verts[i].tx); - } - - bvh_build (bvh); - - return bvh; + return bvhtree; } -void bvh_update_from_cloth(ClothModifierData *clmd, int moving) -{ +void bvhtree_update_from_cloth(ClothModifierData *clmd, int moving) +{ unsigned int i = 0; Cloth *cloth = clmd->clothObject; - BVH *bvh = cloth->tree; + BVHTree *bvhtree = cloth->bvhtree; ClothVertex *verts = cloth->verts; + MFace *mfaces; + float co[12], co_moving[12]; + int ret = 0; - if(!bvh) + if(!bvhtree) return; - if(cloth->numverts!=bvh->numverts) - return; + mfaces = cloth->mfaces; - if(cloth->verts) + // update vertex position in bvh tree + if(verts && mfaces) { - for(i = 0; i < bvh->numverts; i++) + for(i = 0; i < cloth->numfaces; i++, mfaces++) { - VECCOPY(bvh->current_x[i].co, verts[i].tx); - VECCOPY(bvh->current_xold[i].co, verts[i].txold); + VECCOPY(&co[0*3], verts[mfaces->v1].txold); + VECCOPY(&co[1*3], verts[mfaces->v2].txold); + VECCOPY(&co[2*3], verts[mfaces->v3].txold); + + if(mfaces->v4) + VECCOPY(&co[3*3], verts[mfaces->v4].txold); + + // copy new locations into array + if(moving) + { + // update moving positions + VECCOPY(&co_moving[0*3], verts[mfaces->v1].tx); + VECCOPY(&co_moving[1*3], verts[mfaces->v2].tx); + VECCOPY(&co_moving[2*3], verts[mfaces->v3].tx); + + if(mfaces->v4) + VECCOPY(&co_moving[3*3], verts[mfaces->v4].tx); + + ret = BLI_bvhtree_update_node(bvhtree, i, co, co_moving, (mfaces->v4 ? 4 : 3)); + } + else + { + ret = BLI_bvhtree_update_node(bvhtree, i, co, NULL, (mfaces->v4 ? 4 : 3)); + } + + // check if tree is already full + if(!ret) + break; } + + BLI_bvhtree_update_tree(bvhtree); } - - bvh_update(bvh, moving); } int modifiers_indexInObject(Object *ob, ModifierData *md_seek); @@ -541,8 +561,8 @@ void cloth_free_modifier ( Object *ob, ClothModifierData *clmd ) cloth->numsprings = 0; // free BVH collision tree - if ( cloth->tree ) - bvh_free ( ( BVH * ) cloth->tree ); + if ( cloth->bvhtree ) + BLI_bvhtree_free ( cloth->bvhtree ); // we save our faces for collision objects if ( cloth->mfaces ) @@ -611,8 +631,8 @@ void cloth_free_modifier_extern ( ClothModifierData *clmd ) cloth->numsprings = 0; // free BVH collision tree - if ( cloth->tree ) - bvh_free ( ( BVH * ) cloth->tree ); + if ( cloth->bvhtree ) + BLI_bvhtree_free ( cloth->bvhtree ); // we save our faces for collision objects if ( cloth->mfaces ) @@ -810,6 +830,7 @@ static int cloth_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *d VECCOPY ( verts->xold, verts->x ); VECCOPY ( verts->xconst, verts->x ); VECCOPY ( verts->txold, verts->x ); + VECCOPY ( verts->tx, verts->x ); VecMulf ( verts->v, 0.0f ); verts->impulse_count = 0; @@ -845,12 +866,11 @@ static int cloth_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *d if(!first) implicit_set_positions(clmd); - clmd->clothObject->tree = bvh_build_from_cloth ( clmd, clmd->coll_parms->epsilon ); - + clmd->clothObject->bvhtree = bvhtree_build_from_cloth ( clmd, clmd->coll_parms->epsilon ); + return 1; } - static void cloth_from_mesh ( Object *ob, ClothModifierData *clmd, DerivedMesh *dm ) { unsigned int numverts = dm->getNumVerts ( dm ); diff --git a/source/blender/blenkernel/intern/collision.c b/source/blender/blenkernel/intern/collision.c index e244ccca306..f3637b4dda2 100644 --- a/source/blender/blenkernel/intern/collision.c +++ b/source/blender/blenkernel/intern/collision.c @@ -41,7 +41,6 @@ #include "BKE_global.h" #include "BKE_mesh.h" #include "BKE_object.h" -#include "BKE_cloth.h" #include "BKE_modifier.h" #include "BKE_utildefines.h" #include "BKE_DerivedMesh.h" @@ -49,6 +48,38 @@ #include "Bullet-C-Api.h" +#include "BLI_kdopbvh.h" +#include "BKE_collision.h" + +#ifdef _WIN32 +static void start ( void ) +{} +static void end ( void ) +{ +} +static double val() +{ + return 0; +} +#else +#include +static void mystart ( struct timeval *start, struct timezone *z ) +{ + gettimeofday ( start, z ); +} +static void myend ( struct timeval *end, struct timezone *z ) +{ + gettimeofday ( end,z ); +} +static double myval ( struct timeval *start, struct timeval *end ) +{ + double t1, t2; + t1 = ( double ) start->tv_sec + ( double ) start->tv_usec/ ( 1000*1000 ); + t2 = ( double ) end->tv_sec + ( double ) end->tv_usec/ ( 1000*1000 ); + return t2-t1; +} +#endif + /*********************************** Collision modifier code start ***********************************/ @@ -66,58 +97,80 @@ void collision_move_object ( CollisionModifierData *collmd, float step, float pr VECADDS ( collmd->current_xnew[i].co, collmd->x[i].co, tv, step ); VECSUB ( collmd->current_v[i].co, collmd->current_xnew[i].co, collmd->current_x[i].co ); } - bvh_update_from_mvert ( collmd->bvh, collmd->current_x, collmd->numverts, collmd->current_xnew, 1 ); + bvhtree_update_from_mvert ( collmd->bvhtree, collmd->mfaces, collmd->numfaces, collmd->current_x, collmd->current_xnew, collmd->numverts, 1 ); } -/* build bounding volume hierarchy from mverts (see kdop.c for whole BVH code) */ -BVH *bvh_build_from_mvert ( MFace *mfaces, unsigned int numfaces, MVert *x, unsigned int numverts, float epsilon ) +BVHTree *bvhtree_build_from_mvert ( MFace *mfaces, unsigned int numfaces, MVert *x, unsigned int numverts, float epsilon ) { - BVH *bvh=NULL; + BVHTree *tree; + float co[12]; + int i; + MFace *tface = mfaces; - bvh = MEM_callocN ( sizeof ( BVH ), "BVH" ); - if ( bvh == NULL ) + tree = BLI_bvhtree_new ( numfaces*2, epsilon, 4, 26 ); + + // fill tree + for ( i = 0; i < numfaces; i++, tface++ ) { - printf ( "bvh: Out of memory.\n" ); - return NULL; + VECCOPY ( &co[0*3], x[tface->v1].co ); + VECCOPY ( &co[1*3], x[tface->v2].co ); + VECCOPY ( &co[2*3], x[tface->v3].co ); + if ( tface->v4 ) + VECCOPY ( &co[3*3], x[tface->v4].co ); + + BLI_bvhtree_insert ( tree, i, co, ( mfaces->v4 ? 4 : 3 ) ); } - // in the moment, return zero if no faces there - if ( !numfaces ) - return NULL; + // balance tree + BLI_bvhtree_balance ( tree ); - bvh->epsilon = epsilon; - bvh->numfaces = numfaces; - bvh->mfaces = mfaces; - - // we have no faces, we save seperate points - if ( !mfaces ) - { - bvh->numfaces = numverts; - } - - bvh->numverts = numverts; - bvh->current_x = MEM_dupallocN ( x ); - - bvh_build ( bvh ); - - return bvh; + return tree; } -void bvh_update_from_mvert ( BVH * bvh, MVert *x, unsigned int numverts, MVert *xnew, int moving ) +void bvhtree_update_from_mvert ( BVHTree * bvhtree, MFace *faces, int numfaces, MVert *x, MVert *xnew, int numverts, int moving ) { - if ( !bvh ) - return; + int i; + MFace *mfaces = faces; + float co[12], co_moving[12]; + int ret = 0; - if ( numverts!=bvh->numverts ) + if ( !bvhtree ) return; if ( x ) - memcpy ( bvh->current_xold, x, sizeof ( MVert ) * numverts ); + { + for ( i = 0; i < numfaces; i++, mfaces++ ) + { + VECCOPY ( &co[0*3], x[mfaces->v1].co ); + VECCOPY ( &co[1*3], x[mfaces->v2].co ); + VECCOPY ( &co[2*3], x[mfaces->v3].co ); + if ( mfaces->v4 ) + VECCOPY ( &co[3*3], x[mfaces->v4].co ); - if ( xnew ) - memcpy ( bvh->current_x, xnew, sizeof ( MVert ) * numverts ); + // copy new locations into array + if ( moving && xnew ) + { + // update moving positions + VECCOPY ( &co_moving[0*3], xnew[mfaces->v1].co ); + VECCOPY ( &co_moving[1*3], xnew[mfaces->v2].co ); + VECCOPY ( &co_moving[2*3], xnew[mfaces->v3].co ); + if ( mfaces->v4 ) + VECCOPY ( &co_moving[3*3], xnew[mfaces->v4].co ); - bvh_update ( bvh, moving ); + ret = BLI_bvhtree_update_node ( bvhtree, i, co, co_moving, ( mfaces->v4 ? 4 : 3 ) ); + } + else + { + ret = BLI_bvhtree_update_node ( bvhtree, i, co, NULL, ( mfaces->v4 ? 4 : 3 ) ); + } + + // check if tree is already full + if ( !ret ) + break; + } + + BLI_bvhtree_update_tree ( bvhtree ); + } } /*********************************** @@ -157,11 +210,11 @@ int gsl_poly_solve_cubic ( float a, float b, float c, float *x0, float *x1, floa else if ( CR2 == CQ3 ) { /* this test is actually R2 == Q3, written in a form suitable - for exact computation with integers */ + for exact computation with integers */ /* Due to finite precision some float roots may be missed, and - considered to be a pair of complex roots z = x +/- epsilon i - close to the real axis. */ + considered to be a pair of complex roots z = x +/- epsilon i + close to the real axis. */ float sqrtQ = sqrt ( Q ); @@ -419,24 +472,22 @@ DO_INLINE void collision_interpolateOnTriangle ( float to[3], float v1[3], float VECADDMUL ( to, v3, w3 ); } -int cloth_collision_response_static ( ClothModifierData *clmd, CollisionModifierData *collmd ) +int cloth_collision_response_static ( ClothModifierData *clmd, CollisionModifierData *collmd, CollPair *collpair, CollPair *collision_end ) { int result = 0; - LinkNode *search = NULL; - CollPair *collpair = NULL; Cloth *cloth1; float w1, w2, w3, u1, u2, u3; float v1[3], v2[3], relativeVelocity[3]; float magrelVel; - float epsilon2 = collmd->bvh->epsilon; + float epsilon2 = BLI_bvhtree_getepsilon ( collmd->bvhtree ); cloth1 = clmd->clothObject; - search = clmd->coll_parms->collision_list; - - while ( search ) + for ( ; collpair != collision_end; collpair++ ) { - collpair = search->link; + // only handle static collisions here + if ( collpair->flag & COLLISION_IN_FUTURE ) + continue; // compute barycentric coordinates for both collision points collision_compute_barycentric ( collpair->pa, @@ -530,8 +581,6 @@ int cloth_collision_response_static ( ClothModifierData *clmd, CollisionModifier result = 1; } - - search = search->next; } @@ -549,51 +598,46 @@ int cloth_collision_response_moving_edges ( ClothModifierData *clmd, ClothModifi return 1; } -void cloth_collision_static ( ModifierData *md1, ModifierData *md2, CollisionTree *tree1, CollisionTree *tree2 ) +//Determines collisions on overlap, collisions are writen to collpair[i] and collision+number_collision_found is returned +CollPair* cloth_collision ( ModifierData *md1, ModifierData *md2, BVHTreeOverlap *overlap, CollPair *collpair ) { ClothModifierData *clmd = ( ClothModifierData * ) md1; CollisionModifierData *collmd = ( CollisionModifierData * ) md2; - CollPair *collpair = NULL; - Cloth *cloth1=NULL; - MFace *face1=NULL, *face2=NULL; - ClothVertex *verts1=NULL; + MFace *face1=NULL, *face2 = NULL; + ClothVertex *verts1 = clmd->clothObject->verts; double distance = 0; - float epsilon = clmd->coll_parms->epsilon; - float epsilon2 = ( ( CollisionModifierData * ) md2 )->bvh->epsilon; - unsigned int i = 0; + float epsilon1 = clmd->coll_parms->epsilon; + float epsilon2 = BLI_bvhtree_getepsilon ( collmd->bvhtree ); + int i; + face1 = & ( clmd->clothObject->mfaces[overlap->indexA] ); + face2 = & ( collmd->mfaces[overlap->indexB] ); + + // check all 4 possible collisions for ( i = 0; i < 4; i++ ) { - collpair = ( CollPair * ) MEM_callocN ( sizeof ( CollPair ), "cloth coll pair" ); - - cloth1 = clmd->clothObject; - - verts1 = cloth1->verts; - - face1 = & ( cloth1->mfaces[tree1->tri_index] ); - face2 = & ( collmd->mfaces[tree2->tri_index] ); - - // check all possible pairs of triangles if ( i == 0 ) { + // fill faceA collpair->ap1 = face1->v1; collpair->ap2 = face1->v2; collpair->ap3 = face1->v3; + // fill faceB collpair->bp1 = face2->v1; collpair->bp2 = face2->v2; collpair->bp3 = face2->v3; - } - - if ( i == 1 ) + else if ( i == 1 ) { if ( face1->v4 ) { - collpair->ap1 = face1->v3; + // fill faceA + collpair->ap1 = face1->v1; collpair->ap2 = face1->v4; - collpair->ap3 = face1->v1; + collpair->ap3 = face1->v3; + // fill faceB collpair->bp1 = face2->v1; collpair->bp2 = face2->v2; collpair->bp3 = face2->v3; @@ -601,235 +645,215 @@ void cloth_collision_static ( ModifierData *md1, ModifierData *md2, CollisionTre else i++; } - if ( i == 2 ) { if ( face2->v4 ) { + // fill faceA collpair->ap1 = face1->v1; collpair->ap2 = face1->v2; collpair->ap3 = face1->v3; - collpair->bp1 = face2->v3; + // fill faceB + collpair->bp1 = face2->v1; collpair->bp2 = face2->v4; - collpair->bp3 = face2->v1; + collpair->bp3 = face2->v3; } else - i+=2; + break; } - - if ( i == 3 ) + else if ( i == 3 ) { - if ( ( face1->v4 ) && ( face2->v4 ) ) + if ( face1->v4 && face2->v4 ) { - collpair->ap1 = face1->v3; + // fill faceA + collpair->ap1 = face1->v1; collpair->ap2 = face1->v4; - collpair->ap3 = face1->v1; + collpair->ap3 = face1->v3; - collpair->bp1 = face2->v3; + // fill faceB + collpair->bp1 = face2->v1; collpair->bp2 = face2->v4; - collpair->bp3 = face2->v1; + collpair->bp3 = face2->v3; } else - i++; + break; } - // calc SIPcode (?) - - if ( i < 4 ) - { - // calc distance + normal #ifdef WITH_BULLET - distance = plNearestPoints ( - verts1[collpair->ap1].txold, verts1[collpair->ap2].txold, verts1[collpair->ap3].txold, collmd->current_x[collpair->bp1].co, collmd->current_x[collpair->bp2].co, collmd->current_x[collpair->bp3].co, collpair->pa,collpair->pb,collpair->vector ); + // calc distance + normal + distance = plNearestPoints ( + verts1[collpair->ap1].txold, verts1[collpair->ap2].txold, verts1[collpair->ap3].txold, collmd->current_x[collpair->bp1].co, collmd->current_x[collpair->bp2].co, collmd->current_x[collpair->bp3].co, collpair->pa,collpair->pb,collpair->vector ); #else - // just be sure that we don't add anything - distance = 2.0 * ( epsilon + epsilon2 + ALMOST_ZERO ); + // just be sure that we don't add anything + distance = 2.0 * ( epsilon1 + epsilon2 + ALMOST_ZERO ); #endif - if ( distance <= ( epsilon + epsilon2 + ALMOST_ZERO ) ) - { - // printf("dist: %f\n", (float)distance); - // collpair->face1 = tree1->tri_index; - // collpair->face2 = tree2->tri_index; + if ( distance <= ( epsilon1 + epsilon2 + ALMOST_ZERO ) ) + { + VECCOPY ( collpair->normal, collpair->vector ); + Normalize ( collpair->normal ); - VECCOPY ( collpair->normal, collpair->vector ); - Normalize ( collpair->normal ); - - collpair->distance = distance; - BLI_linklist_prepend ( &clmd->coll_parms->collision_list, collpair ); - - } - else - { - MEM_freeN ( collpair ); - } + collpair->distance = distance; + collpair->flag = 0; } else { - MEM_freeN ( collpair ); + // check for collision in the future + collpair->flag |= COLLISION_IN_FUTURE; } + collpair++; } + return collpair; } -int cloth_are_edges_adjacent ( ClothModifierData *clmd, ClothModifierData *coll_clmd, EdgeCollPair *edgecollpair ) +int cloth_are_edges_adjacent ( ClothModifierData *clmd, CollisionModifierData *collmd, EdgeCollPair *edgecollpair ) { - Cloth *cloth1 = NULL, *cloth2 = NULL; - ClothVertex *verts1 = NULL, *verts2 = NULL; + Cloth *cloth1 = NULL; + ClothVertex *verts1 = NULL; float temp[3]; + MVert *verts2 = collmd->current_x; // old x cloth1 = clmd->clothObject; - cloth2 = coll_clmd->clothObject; - verts1 = cloth1->verts; - verts2 = cloth2->verts; - VECSUB ( temp, verts1[edgecollpair->p11].xold, verts2[edgecollpair->p21].xold ); + VECSUB ( temp, verts1[edgecollpair->p11].xold, verts2[edgecollpair->p21].co ); if ( ABS ( INPR ( temp, temp ) ) < ALMOST_ZERO ) return 1; - VECSUB ( temp, verts1[edgecollpair->p11].xold, verts2[edgecollpair->p22].xold ); + VECSUB ( temp, verts1[edgecollpair->p11].xold, verts2[edgecollpair->p22].co ); if ( ABS ( INPR ( temp, temp ) ) < ALMOST_ZERO ) return 1; - VECSUB ( temp, verts1[edgecollpair->p12].xold, verts2[edgecollpair->p21].xold ); + VECSUB ( temp, verts1[edgecollpair->p12].xold, verts2[edgecollpair->p21].co ); if ( ABS ( INPR ( temp, temp ) ) < ALMOST_ZERO ) return 1; - VECSUB ( temp, verts1[edgecollpair->p12].xold, verts2[edgecollpair->p22].xold ); + VECSUB ( temp, verts1[edgecollpair->p12].xold, verts2[edgecollpair->p22].co ); if ( ABS ( INPR ( temp, temp ) ) < ALMOST_ZERO ) return 1; return 0; } -void cloth_collision_moving_edges ( ClothModifierData *clmd, ClothModifierData *coll_clmd, CollisionTree *tree1, CollisionTree *tree2 ) +void cloth_collision_moving_edges ( ClothModifierData *clmd, CollisionModifierData *collmd, CollPair *collpair ) { EdgeCollPair edgecollpair; - Cloth *cloth1=NULL, *cloth2=NULL; - MFace *face1=NULL, *face2=NULL; - ClothVertex *verts1=NULL, *verts2=NULL; + Cloth *cloth1=NULL; + ClothVertex *verts1=NULL; unsigned int i = 0, j = 0, k = 0; int numsolutions = 0; float a[3], b[3], c[3], d[3], e[3], f[3], solution[3]; + MVert *verts2 = collmd->current_x; // old x + MVert *velocity2 = collmd->current_v; // velocity + float mintime = 0; cloth1 = clmd->clothObject; - cloth2 = coll_clmd->clothObject; - verts1 = cloth1->verts; - verts2 = cloth2->verts; - face1 = & ( cloth1->mfaces[tree1->tri_index] ); - face2 = & ( cloth2->mfaces[tree2->tri_index] ); - - for ( i = 0; i < 5; i++ ) + for(i = 0; i < 9; i++) { - if ( i == 0 ) + // 9 edge - edge possibilities + + if(i == 0) // cloth edge: 1-2; coll edge: 1-2 { - edgecollpair.p11 = face1->v1; - edgecollpair.p12 = face1->v2; + edgecollpair.p11 = collpair->ap1; + edgecollpair.p12 = collpair->ap2; + + edgecollpair.p21 = collpair->bp1; + edgecollpair.p22 = collpair->bp2; } - else if ( i == 1 ) + else if(i == 1) // cloth edge: 1-2; coll edge: 2-3 { - edgecollpair.p11 = face1->v2; - edgecollpair.p12 = face1->v3; + edgecollpair.p11 = collpair->ap1; + edgecollpair.p12 = collpair->ap2; + + edgecollpair.p21 = collpair->bp2; + edgecollpair.p22 = collpair->bp3; } - else if ( i == 2 ) + else if(i == 2) // cloth edge: 1-2; coll edge: 1-3 { - if ( face1->v4 ) - { - edgecollpair.p11 = face1->v3; - edgecollpair.p12 = face1->v4; - } - else - { - edgecollpair.p11 = face1->v3; - edgecollpair.p12 = face1->v1; - i+=5; // get out of here after this edge pair is handled - } + edgecollpair.p11 = collpair->ap1; + edgecollpair.p12 = collpair->ap2; + + edgecollpair.p21 = collpair->bp1; + edgecollpair.p22 = collpair->bp3; } - else if ( i == 3 ) + else if(i == 3) // cloth edge: 2-3; coll edge: 1-2 { - if ( face1->v4 ) - { - edgecollpair.p11 = face1->v4; - edgecollpair.p12 = face1->v1; - } - else - continue; + edgecollpair.p11 = collpair->ap2; + edgecollpair.p12 = collpair->ap3; + + edgecollpair.p21 = collpair->bp1; + edgecollpair.p22 = collpair->bp2; } - else + else if(i == 4) // cloth edge: 2-3; coll edge: 2-3 { - edgecollpair.p11 = face1->v3; - edgecollpair.p12 = face1->v1; + edgecollpair.p11 = collpair->ap2; + edgecollpair.p12 = collpair->ap3; + + edgecollpair.p21 = collpair->bp2; + edgecollpair.p22 = collpair->bp3; } - - - for ( j = 0; j < 5; j++ ) + else if(i == 5) // cloth edge: 2-3; coll edge: 1-3 { - if ( j == 0 ) + edgecollpair.p11 = collpair->ap2; + edgecollpair.p12 = collpair->ap3; + + edgecollpair.p21 = collpair->bp1; + edgecollpair.p22 = collpair->bp3; + } + else if(i ==6) // cloth edge: 1-3; coll edge: 1-2 + { + edgecollpair.p11 = collpair->ap1; + edgecollpair.p12 = collpair->ap3; + + edgecollpair.p21 = collpair->bp1; + edgecollpair.p22 = collpair->bp2; + } + else if(i ==7) // cloth edge: 1-3; coll edge: 2-3 + { + edgecollpair.p11 = collpair->ap1; + edgecollpair.p12 = collpair->ap3; + + edgecollpair.p21 = collpair->bp2; + edgecollpair.p22 = collpair->bp3; + } + else if(i == 8) // cloth edge: 1-3; coll edge: 1-3 + { + edgecollpair.p11 = collpair->ap1; + edgecollpair.p12 = collpair->ap3; + + edgecollpair.p21 = collpair->bp1; + edgecollpair.p22 = collpair->bp3; + } + + if ( !cloth_are_edges_adjacent ( clmd, collmd, &edgecollpair ) ) + { + // always put coll points in p21/p22 + VECSUB ( a, verts1[edgecollpair.p12].txold, verts1[edgecollpair.p11].txold ); + VECSUB ( b, verts1[edgecollpair.p12].tv, verts1[edgecollpair.p11].tv ); + VECSUB ( c, verts2[edgecollpair.p21].co, verts1[edgecollpair.p11].txold ); + VECSUB ( d, velocity2[edgecollpair.p21].co, verts1[edgecollpair.p11].tv ); + VECSUB ( e, verts2[edgecollpair.p22].co, verts1[edgecollpair.p11].txold ); + VECSUB ( f, velocity2[edgecollpair.p22].co, verts1[edgecollpair.p11].v ); + + numsolutions = cloth_get_collision_time ( a, b, c, d, e, f, solution ); + + for ( k = 0; k < numsolutions; k++ ) { - edgecollpair.p21 = face2->v1; - edgecollpair.p22 = face2->v2; - } - else if ( j == 1 ) - { - edgecollpair.p21 = face2->v2; - edgecollpair.p22 = face2->v3; - } - else if ( j == 2 ) - { - if ( face2->v4 ) + if ( ( solution[k] >= 0.0 ) && ( solution[k] <= 1.0 ) ) { - edgecollpair.p21 = face2->v3; - edgecollpair.p22 = face2->v4; - } - else - { - edgecollpair.p21 = face2->v3; - edgecollpair.p22 = face2->v1; - } - } - else if ( j == 3 ) - { - if ( face2->v4 ) - { - edgecollpair.p21 = face2->v4; - edgecollpair.p22 = face2->v1; - } - else - continue; - } - else - { - edgecollpair.p21 = face2->v3; - edgecollpair.p22 = face2->v1; - } - - - if ( !cloth_are_edges_adjacent ( clmd, coll_clmd, &edgecollpair ) ) - { - VECSUB ( a, verts1[edgecollpair.p12].xold, verts1[edgecollpair.p11].xold ); - VECSUB ( b, verts1[edgecollpair.p12].v, verts1[edgecollpair.p11].v ); - VECSUB ( c, verts1[edgecollpair.p21].xold, verts1[edgecollpair.p11].xold ); - VECSUB ( d, verts1[edgecollpair.p21].v, verts1[edgecollpair.p11].v ); - VECSUB ( e, verts2[edgecollpair.p22].xold, verts1[edgecollpair.p11].xold ); - VECSUB ( f, verts2[edgecollpair.p22].v, verts1[edgecollpair.p11].v ); - - numsolutions = cloth_get_collision_time ( a, b, c, d, e, f, solution ); - - for ( k = 0; k < numsolutions; k++ ) - { - if ( ( solution[k] >= 0.0 ) && ( solution[k] <= 1.0 ) ) - { - //float out_collisionTime = solution[k]; - - // TODO: check for collisions - - // TODO: put into (edge) collision list - - // printf("Moving edge found!\n"); - } + //float out_collisionTime = solution[k]; + + // TODO: check for collisions + + // TODO: put into (edge) collision list + + mintime = MIN2(mintime, solution[k]); + + printf("Moving edge found!, mintime: %f\n", mintime); + break; } } } @@ -928,6 +952,7 @@ void cloth_collision_moving_tris ( ClothModifierData *clmd, ClothModifierData *c } } +/* void cloth_collision_moving ( ClothModifierData *clmd, ClothModifierData *coll_clmd, CollisionTree *tree1, CollisionTree *tree2 ) { // TODO: check for adjacent @@ -936,51 +961,68 @@ void cloth_collision_moving ( ClothModifierData *clmd, ClothModifierData *coll_c cloth_collision_moving_tris ( clmd, coll_clmd, tree1, tree2 ); cloth_collision_moving_tris ( coll_clmd, clmd, tree2, tree1 ); } +*/ -void cloth_free_collision_list ( ClothModifierData *clmd ) +int cloth_collision_moving ( ClothModifierData *clmd, CollisionModifierData *collmd, CollPair *collpair, CollPair *collision_end ) { - // free collision list - if ( clmd->coll_parms->collision_list ) + int result = 0; + Cloth *cloth1; + float w1, w2, w3, u1, u2, u3; + float v1[3], v2[3], relativeVelocity[3]; + float magrelVel; + float epsilon2 = BLI_bvhtree_getepsilon ( collmd->bvhtree ); + + cloth1 = clmd->clothObject; + + for ( ; collpair != collision_end; collpair++ ) { - LinkNode *search = clmd->coll_parms->collision_list; - while ( search ) - { - CollPair *coll_pair = search->link; - - MEM_freeN ( coll_pair ); - search = search->next; - } - BLI_linklist_free ( clmd->coll_parms->collision_list,NULL ); - - clmd->coll_parms->collision_list = NULL; + // only handle moving collisions here + if (!( collpair->flag & COLLISION_IN_FUTURE )) + continue; + + cloth_collision_moving_edges ( clmd, collmd, collpair); } } int cloth_bvh_objcollisions_do ( ClothModifierData * clmd, CollisionModifierData *collmd, float step, float dt ) { Cloth *cloth = clmd->clothObject; - BVH *cloth_bvh= ( BVH * ) cloth->tree; + BVHTree *cloth_bvh= ( BVHTree * ) cloth->bvhtree; long i=0, j = 0, numfaces = 0, numverts = 0; ClothVertex *verts = NULL; + CollPair *collisions = NULL, *collisions_index = NULL; int ret = 0; - unsigned int result = 0; + int result = 0; float tnull[3] = {0,0,0}; + BVHTreeOverlap *overlap = NULL; + numfaces = clmd->clothObject->numfaces; numverts = clmd->clothObject->numverts; verts = cloth->verts; - if ( collmd->bvh ) + if ( collmd->bvhtree ) { /* get pointer to bounding volume hierarchy */ - BVH *coll_bvh = collmd->bvh; + BVHTree *coll_bvh = collmd->bvhtree; /* move object to position (step) in time */ collision_move_object ( collmd, step + dt, step ); /* search for overlapping collision pairs */ - bvh_traverse ( ( ModifierData * ) clmd, ( ModifierData * ) collmd, cloth_bvh->root, coll_bvh->root, step, cloth_collision_static, 0 ); + overlap = BLI_bvhtree_overlap ( cloth_bvh, coll_bvh, &result ); + + collisions = ( CollPair* ) MEM_mallocN ( sizeof ( CollPair ) * result*4, "collision array" ); //*4 since cloth_collision_static can return more than 1 collision + collisions_index = collisions; + + for ( i = 0; i < result; i++ ) + { + collisions_index = cloth_collision ( ( ModifierData * ) clmd, ( ModifierData * ) collmd, overlap+i, collisions_index ); + } + + if ( overlap ) + MEM_freeN ( overlap ); } else { @@ -994,11 +1036,15 @@ int cloth_bvh_objcollisions_do ( ClothModifierData * clmd, CollisionModifierData { result = 0; - if ( collmd->bvh ) - result += cloth_collision_response_static ( clmd, collmd ); + if ( collmd->bvhtree ) + { + result += cloth_collision_response_static ( clmd, collmd, collisions, collisions_index ); + result += cloth_collision_moving ( clmd, collmd, collisions, collisions_index ); + } // apply impulses in parallel if ( result ) + { for ( i = 0; i < numverts; i++ ) { // calculate "velocities" (just xnew = xold + v; no dt in v) @@ -1011,12 +1057,10 @@ int cloth_bvh_objcollisions_do ( ClothModifierData * clmd, CollisionModifierData ret++; } } - - if ( !result ) - break; + } } - cloth_free_collision_list ( clmd ); + if ( collisions ) MEM_freeN ( collisions ); return ret; } @@ -1028,7 +1072,7 @@ int cloth_bvh_objcollision ( ClothModifierData * clmd, float step, float dt ) CollisionModifierData *collmd=NULL; Cloth *cloth=NULL; Object *coll_ob=NULL; - BVH *cloth_bvh=NULL; + BVHTree *cloth_bvh=NULL; long i=0, j = 0, numfaces = 0, numverts = 0; unsigned int result = 0, rounds = 0; // result counts applied collisions; ic is for debug output; ClothVertex *verts = NULL; @@ -1036,14 +1080,14 @@ int cloth_bvh_objcollision ( ClothModifierData * clmd, float step, float dt ) ClothModifierData *tclmd; int collisions = 0, count = 0; - if ( ( clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_COLLOBJ ) || ! ( ( ( Cloth * ) clmd->clothObject )->tree ) ) + if ( ( clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_COLLOBJ ) || ! ( ( ( Cloth * ) clmd->clothObject )->bvhtree ) ) { return 0; } cloth = clmd->clothObject; verts = cloth->verts; - cloth_bvh = ( BVH * ) cloth->tree; + cloth_bvh = ( BVHTree * ) cloth->bvhtree; numfaces = clmd->clothObject->numfaces; numverts = clmd->clothObject->numverts; @@ -1052,12 +1096,11 @@ int cloth_bvh_objcollision ( ClothModifierData * clmd, float step, float dt ) //////////////////////////////////////////////////////////// // update cloth bvh - bvh_update_from_cloth ( clmd, 0 ); // 0 means STATIC, 1 means MOVING (see later in this function) + bvhtree_update_from_cloth ( clmd, 0 ); // 0 means STATIC, 1 means MOVING (see later in this function) do { result = 0; - clmd->coll_parms->collision_list = NULL; // check all collision objects for ( base = G.scene->base.first; base; base = base->next ) @@ -1126,80 +1169,87 @@ int cloth_bvh_objcollision ( ClothModifierData * clmd, float step, float dt ) //////////////////////////////////////////////////////////// if ( clmd->coll_parms->flags & CLOTH_COLLSETTINGS_FLAG_SELF ) { + + MFace *mface = clmd->clothObject->mfaces; + collisions = 1; verts = cloth->verts; // needed for openMP + + + /* for ( count = 0; count < clmd->coll_parms->self_loop_count; count++ ) { - if ( collisions ) - { - collisions = 0; -#pragma omp parallel for private(i,j, collisions) shared(verts, ret) - for ( i = 0; i < cloth->numverts; i++ ) - { - for ( j = i + 1; j < cloth->numverts; j++ ) - { - float temp[3]; - float length = 0; - float mindistance = clmd->coll_parms->selfepsilon* ( cloth->verts[i].avg_spring_len + cloth->verts[j].avg_spring_len ); + if ( collisions ) + { + collisions = 0; + #pragma omp parallel for private(i,j, collisions) shared(verts, ret) + for ( i = 0; i < cloth->numverts; i++ ) + { + for ( j = i + 1; j < cloth->numverts; j++ ) + { + float temp[3]; + float length = 0; + float mindistance = clmd->coll_parms->selfepsilon* ( cloth->verts[i].avg_spring_len + cloth->verts[j].avg_spring_len ); - if ( clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL ) - { - if ( ( cloth->verts [i].flags & CLOTH_VERT_FLAG_PINNED ) - && ( cloth->verts [j].flags & CLOTH_VERT_FLAG_PINNED ) ) - { - continue; - } - } + if ( clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL ) + { + if ( ( cloth->verts [i].flags & CLOTH_VERT_FLAG_PINNED ) + && ( cloth->verts [j].flags & CLOTH_VERT_FLAG_PINNED ) ) + { + continue; + } + } - VECSUB ( temp, verts[i].tx, verts[j].tx ); + VECSUB ( temp, verts[i].tx, verts[j].tx ); - if ( ( ABS ( temp[0] ) > mindistance ) || ( ABS ( temp[1] ) > mindistance ) || ( ABS ( temp[2] ) > mindistance ) ) continue; + if ( ( ABS ( temp[0] ) > mindistance ) || ( ABS ( temp[1] ) > mindistance ) || ( ABS ( temp[2] ) > mindistance ) ) continue; // check for adjacent points (i must be smaller j) - if ( BLI_edgehash_haskey ( cloth->edgehash, i, j ) ) - { - continue; - } - - length = Normalize ( temp ); - - if ( length < mindistance ) - { - float correction = mindistance - length; - - if ( cloth->verts [i].flags & CLOTH_VERT_FLAG_PINNED ) - { - VecMulf ( temp, -correction ); - VECADD ( verts[j].tx, verts[j].tx, temp ); - } - else if ( cloth->verts [j].flags & CLOTH_VERT_FLAG_PINNED ) - { - VecMulf ( temp, correction ); - VECADD ( verts[i].tx, verts[i].tx, temp ); - } - else - { - VecMulf ( temp, -correction*0.5 ); - VECADD ( verts[j].tx, verts[j].tx, temp ); - - VECSUB ( verts[i].tx, verts[i].tx, temp ); - } - - collisions = 1; - - if ( !ret ) - { -#pragma omp critical - { - ret = 1; - } - } - } - } - } - } + if ( BLI_edgehash_haskey ( cloth->edgehash, i, j ) ) + { + continue; } + + length = Normalize ( temp ); + + if ( length < mindistance ) + { + float correction = mindistance - length; + + if ( cloth->verts [i].flags & CLOTH_VERT_FLAG_PINNED ) + { + VecMulf ( temp, -correction ); + VECADD ( verts[j].tx, verts[j].tx, temp ); + } + else if ( cloth->verts [j].flags & CLOTH_VERT_FLAG_PINNED ) + { + VecMulf ( temp, correction ); + VECADD ( verts[i].tx, verts[i].tx, temp ); + } + else + { + VecMulf ( temp, -correction*0.5 ); + VECADD ( verts[j].tx, verts[j].tx, temp ); + + VECSUB ( verts[i].tx, verts[i].tx, temp ); + } + + collisions = 1; + + if ( !ret ) + { + #pragma omp critical + { + ret = 1; + } + } + } + } + } + } + } + */ //////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////// diff --git a/source/blender/blenkernel/intern/kdop.c b/source/blender/blenkernel/intern/kdop.c deleted file mode 100644 index 3189fe960ad..00000000000 --- a/source/blender/blenkernel/intern/kdop.c +++ /dev/null @@ -1,860 +0,0 @@ -/* kdop.c -* -* -* ***** BEGIN GPL LICENSE BLOCK ***** -* -* This program is free software; you can redistribute it and/or -* modify it under the terms of the GNU General Public License -* as published by the Free Software Foundation; either version 2 -* of the License, or (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program; if not, write to the Free Software Foundation, -* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -* -* The Original Code is Copyright (C) Blender Foundation -* All rights reserved. -* -* The Original Code is: all of this file. -* -* Contributor(s): none yet. -* -* ***** END GPL LICENSE BLOCK ***** -*/ - -#include "MEM_guardedalloc.h" - -#include "BKE_cloth.h" - -#include "DNA_cloth_types.h" -#include "DNA_mesh_types.h" -#include "DNA_scene_types.h" - -#include "BKE_deform.h" -#include "BKE_DerivedMesh.h" -#include "BKE_cdderivedmesh.h" -#include "BKE_effect.h" -#include "BKE_global.h" -#include "BKE_object.h" -#include "BKE_modifier.h" -#include "BKE_utildefines.h" - -#ifdef _OPENMP -#include -#endif - - -//////////////////////////////////////////////////////////////////////// -// Additional fastened appending function -// It uses the link to the last inserted node as start value -// for searching the end of the list -// NEW: in compare to the original function, this one returns -// the reference to the last inserted node -//////////////////////////////////////////////////////////////////////// -LinkNode *BLI_linklist_append_fast(LinkNode **listp, void *ptr) { - LinkNode *nlink= MEM_mallocN(sizeof(*nlink), "nlink"); - LinkNode *node = *listp; - - nlink->link = ptr; - nlink->next = NULL; - - if(node == NULL){ - *listp = nlink; - } else { - while(node->next != NULL){ - node = node->next; - } - node->next = nlink; - } - return nlink; -} - - - -//////////////////////////////////////////////////////////////////////// -// Bounding Volume Hierarchy Definition -// -// Notes: From OBB until 26-DOP --> all bounding volumes possible, just choose type below -// Notes: You have to choose the type at compile time ITM -// Notes: You can choose the tree type --> binary, quad, octree, choose below -//////////////////////////////////////////////////////////////////////// - -static float KDOP_AXES[13][3] = -{ {1.0, 0, 0}, {0, 1.0, 0}, {0, 0, 1.0}, {1.0, 1.0, 1.0}, {1.0, -1.0, 1.0}, {1.0, 1.0, -1.0}, -{1.0, -1.0, -1.0}, {1.0, 1.0, 0}, {1.0, 0, 1.0}, {0, 1.0, 1.0}, {1.0, -1.0, 0}, {1.0, 0, -1.0}, -{0, 1.0, -1.0} -}; - -///////////// choose bounding volume here! ///////////// - -#define KDOP_26 - - - -#ifdef KDOP_26 -#define KDOP_END 13 -#define KDOP_START 0 -#endif - -#ifdef KDOP_18 -#define KDOP_END 13 -#define KDOP_START 7 -#endif - -#ifdef KDOP_14 -#define KDOP_END 7 -#define KDOP_START 0 -#endif - -// this is basicly some AABB -#ifdef KDOP_8 -#define KDOP_END 4 -#define KDOP_START 0 -#endif - -// this is basicly some OBB -#ifdef KDOP_6 -#define KDOP_END 3 -#define KDOP_START 0 -#endif - -////////////////////////////////////////////////////////////////////////////////////////////////////// -// Introsort -// with permission deriven from the following Java code: -// http://ralphunden.net/content/tutorials/a-guide-to-introsort/ -// and he derived it from the SUN STL -////////////////////////////////////////////////////////////////////////////////////////////////////// -static int size_threshold = 16; -/* -* Common methods for all algorithms -*/ -DO_INLINE void bvh_exchange(CollisionTree **a, int i, int j) -{ - CollisionTree *t=a[i]; - a[i]=a[j]; - a[j]=t; -} -DO_INLINE int floor_lg(int a) -{ - return (int)(floor(log(a)/log(2))); -} - -/* -* Insertion sort algorithm -*/ -void bvh_insertionsort(CollisionTree **a, int lo, int hi, int axis) -{ - int i,j; - CollisionTree *t; - for (i=lo; i < hi; i++) - { - j=i; - t = a[i]; - while((j!=lo) && (t->bv[axis] < (a[j-1])->bv[axis])) - { - a[j] = a[j-1]; - j--; - } - a[j] = t; - } -} - -static int bvh_partition(CollisionTree **a, int lo, int hi, CollisionTree * x, int axis) -{ - int i=lo, j=hi; - while (1) - { - while ((a[i])->bv[axis] < x->bv[axis]) i++; - j=j-1; - while (x->bv[axis] < (a[j])->bv[axis]) j=j-1; - if(!(i < j)) - return i; - bvh_exchange(a, i,j); - i++; - } -} - -/* -* Heapsort algorithm -*/ -static void bvh_downheap(CollisionTree **a, int i, int n, int lo, int axis) -{ - CollisionTree * d = a[lo+i-1]; - int child; - while (i<=n/2) - { - child = 2*i; - if ((child < n) && ((a[lo+child-1])->bv[axis] < (a[lo+child])->bv[axis])) - { - child++; - } - if (!(d->bv[axis] < (a[lo+child-1])->bv[axis])) break; - a[lo+i-1] = a[lo+child-1]; - i = child; - } - a[lo+i-1] = d; -} - -static void bvh_heapsort(CollisionTree **a, int lo, int hi, int axis) -{ - int n = hi-lo, i; - for (i=n/2; i>=1; i=i-1) - { - bvh_downheap(a, i,n,lo, axis); - } - for (i=n; i>1; i=i-1) - { - bvh_exchange(a, lo,lo+i-1); - bvh_downheap(a, 1,i-1,lo, axis); - } -} - -static CollisionTree *bvh_medianof3(CollisionTree **a, int lo, int mid, int hi, int axis) // returns Sortable -{ - if ((a[mid])->bv[axis] < (a[lo])->bv[axis]) - { - if ((a[hi])->bv[axis] < (a[mid])->bv[axis]) - return a[mid]; - else - { - if ((a[hi])->bv[axis] < (a[lo])->bv[axis]) - return a[hi]; - else - return a[lo]; - } - } - else - { - if ((a[hi])->bv[axis] < (a[mid])->bv[axis]) - { - if ((a[hi])->bv[axis] < (a[lo])->bv[axis]) - return a[lo]; - else - return a[hi]; - } - else - return a[mid]; - } -} -/* -* Quicksort algorithm modified for Introsort -*/ -void bvh_introsort_loop (CollisionTree **a, int lo, int hi, int depth_limit, int axis) -{ - int p; - - while (hi-lo > size_threshold) - { - if (depth_limit == 0) - { - bvh_heapsort(a, lo, hi, axis); - return; - } - depth_limit=depth_limit-1; - p=bvh_partition(a, lo, hi, bvh_medianof3(a, lo, lo+((hi-lo)/2)+1, hi-1, axis), axis); - bvh_introsort_loop(a, p, hi, depth_limit, axis); - hi=p; - } -} - -DO_INLINE void bvh_sort(CollisionTree **a0, int begin, int end, int axis) -{ - if (begin < end) - { - CollisionTree **a=a0; - bvh_introsort_loop(a, begin, end, 2*floor_lg(end-begin), axis); - bvh_insertionsort(a, begin, end, axis); - } -} -DO_INLINE void bvh_sort_along_axis(CollisionTree **face_list, int start, int end, int axis) -{ - bvh_sort(face_list, start, end, axis); -} -//////////////////////////////////////////////////////////////////////////////////////////////// -void bvh_free(BVH * bvh) -{ - LinkNode *search = NULL; - CollisionTree *tree = NULL; - - if (bvh) - { - - search = bvh->tree; - - while(search) - { - LinkNode *next= search->next; - tree = search->link; - - MEM_freeN(tree); - - search = next; - } - - BLI_linklist_free(bvh->tree,NULL); - bvh->tree = NULL; - - if(bvh->current_x) - MEM_freeN(bvh->current_x); - if(bvh->current_xold) - MEM_freeN(bvh->current_xold); - - MEM_freeN(bvh); - bvh = NULL; - } -} - -// only supports x,y,z axis in the moment -// but we should use a plain and simple function here for speed sake -DO_INLINE int bvh_largest_axis(float *bv) -{ - float middle_point[3]; - - middle_point[0] = (bv[1]) - (bv[0]); // x axis - middle_point[1] = (bv[3]) - (bv[2]); // y axis - middle_point[2] = (bv[5]) - (bv[4]); // z axis - if (middle_point[0] > middle_point[1]) - { - if (middle_point[0] > middle_point[2]) - return 1; // max x axis - else - return 5; // max z axis - } - else - { - if (middle_point[1] > middle_point[2]) - return 3; // max y axis - else - return 5; // max z axis - } -} - -// depends on the fact that the BVH's for each face is already build -DO_INLINE void bvh_calc_DOP_hull_from_faces(BVH * bvh, CollisionTree **tri, int numfaces, float *bv) -{ - float newmin,newmax; - int i, j; - - if(numfaces >0) - { - // for all Axes. - for (i = KDOP_START; i < KDOP_END; i++) - { - bv[(2 * i)] = (tri [0])->bv[(2 * i)]; - bv[(2 * i) + 1] = (tri [0])->bv[(2 * i) + 1]; - } - } - - for (j = 0; j < numfaces; j++) - { - // for all Axes. - for (i = KDOP_START; i < KDOP_END; i++) - { - newmin = (tri [j])->bv[(2 * i)]; - if ((newmin < bv[(2 * i)])) - { - bv[(2 * i)] = newmin; - } - - newmax = (tri [j])->bv[(2 * i) + 1]; - if ((newmax > bv[(2 * i) + 1])) - { - bv[(2 * i) + 1] = newmax; - } - } - } -} - -DO_INLINE void bvh_calc_DOP_hull_static(BVH * bvh, CollisionTree **tri, int numfaces, float *bv, CollisionTree *tree) -{ - MFace *tempMFace = bvh->mfaces; - float *tempBV = bv; - float newminmax; - int i, j, k; - - for (j = 0; j < numfaces; j++) - { - tempMFace = bvh->mfaces + (tri [j])->tri_index; - // 3 or 4 vertices per face. - for (k = 0; k < 4; k++) - { - int temp = 0; - // If this is a triangle. - if (k == 3 && !tempMFace->v4) - continue; - // TODO: other name for "temp" this gets all vertices of a face - if (k == 0) - temp = tempMFace->v1; - else if (k == 1) - temp = tempMFace->v2; - else if (k == 2) - temp = tempMFace->v3; - else if (k == 3) - temp = tempMFace->v4; - // for all Axes. - for (i = KDOP_START; i < KDOP_END; i++) - { - newminmax = INPR(bvh->current_xold[temp].co, KDOP_AXES[i]); - if ((newminmax < tempBV[(2 * i)]) || (k == 0 && j == 0)) - tempBV[(2 * i)] = newminmax; - if ((newminmax > tempBV[(2 * i) + 1])|| (k == 0 && j == 0)) - tempBV[(2 * i) + 1] = newminmax; - } - } - - /* calculate normal of this face */ - /* (code copied from cdderivedmesh.c) */ - /* - if(tempMFace->v4) - CalcNormFloat4(bvh->current_xold[tempMFace->v1].co, bvh->current_xold[tempMFace->v2].co, - bvh->current_xold[tempMFace->v3].co, bvh->current_xold[tempMFace->v4].co, tree->normal); - else - CalcNormFloat(bvh->current_xold[tempMFace->v1].co, bvh->current_xold[tempMFace->v2].co, - bvh->current_xold[tempMFace->v3].co, tree->normal); - - tree->alpha = 0; - */ - } -} - -DO_INLINE void bvh_calc_DOP_hull_moving(BVH * bvh, CollisionTree **tri, int numfaces, float *bv, CollisionTree *tree) -{ - MFace *tempMFace = bvh->mfaces; - float *tempBV = bv; - float newminmax; - int i, j, k; - - /* TODO: calculate normals */ - - for (j = 0; j < numfaces; j++) - { - tempMFace = bvh->mfaces + (tri [j])->tri_index; - // 3 or 4 vertices per face. - for (k = 0; k < 4; k++) - { - int temp = 0; - // If this is a triangle. - if (k == 3 && !tempMFace->v4) - continue; - // TODO: other name for "temp" this gets all vertices of a face - if (k == 0) - temp = tempMFace->v1; - else if (k == 1) - temp = tempMFace->v2; - else if (k == 2) - temp = tempMFace->v3; - else if (k == 3) - temp = tempMFace->v4; - // for all Axes. - for (i = KDOP_START; i < KDOP_END; i++) - { - newminmax = INPR(bvh->current_xold[temp].co, KDOP_AXES[i]); - if ((newminmax < tempBV[(2 * i)]) || (k == 0 && j == 0)) - tempBV[(2 * i)] = newminmax; - if ((newminmax > tempBV[(2 * i) + 1])|| (k == 0 && j == 0)) - tempBV[(2 * i) + 1] = newminmax; - - newminmax = INPR(bvh->current_x[temp].co, KDOP_AXES[i]); - if ((newminmax < tempBV[(2 * i)]) || (k == 0 && j == 0)) - tempBV[(2 * i)] = newminmax; - if ((newminmax > tempBV[(2 * i) + 1])|| (k == 0 && j == 0)) - tempBV[(2 * i) + 1] = newminmax; - } - } - } -} - -static void bvh_div_env_node(BVH *bvh, CollisionTree *tree, CollisionTree **face_list, unsigned int start, unsigned int end, int lastaxis, LinkNode *nlink) -{ - int i = 0; - CollisionTree *newtree = NULL; - int laxis = 0, max_nodes=4; - unsigned int tstart, tend; - LinkNode *nlink1 = nlink; - LinkNode *tnlink; - tree->traversed = 0; - // Determine which axis to split along - laxis = bvh_largest_axis(tree->bv); - - // Sort along longest axis - if(laxis!=lastaxis) - bvh_sort_along_axis(face_list, start, end, laxis); - - // maximum is 4 since we have a quad tree - max_nodes = MIN2((end-start + 1 ),4); - - for (i = 0; i < max_nodes; i++) - { - tree->count_nodes++; - - if(end-start+1 > 4) - { - int quarter = ((float)((float)(end - start + 1) / 4.0f)); - tstart = start + i * quarter; - tend = tstart + quarter - 1; - - // be sure that we get all faces - if(i==3) - { - tend = end; - } - } - else - { - tend = tstart = start + i; - } - - // Build tree until 4 node left. - if ((tend-tstart + 1 ) > 1) - { - newtree = (CollisionTree *)MEM_callocN(sizeof(CollisionTree), "CollisionTree"); - tnlink = BLI_linklist_append_fast(&nlink1->next, newtree); - - newtree->nodes[0] = newtree->nodes[1] = newtree->nodes[2] = newtree->nodes[3] = NULL; - newtree->count_nodes = 0; - newtree->parent = tree; - newtree->isleaf = 0; - - tree->nodes[i] = newtree; - - nlink1 = tnlink; - - bvh_calc_DOP_hull_from_faces(bvh, &face_list[tstart], tend-tstart + 1, tree->nodes[i]->bv); - - bvh_div_env_node(bvh, tree->nodes[i], face_list, tstart, tend, laxis, nlink1); - } - else // ok, we have 1 left for this node - { - CollisionTree *tnode = face_list[tstart]; - tree->nodes[i] = tnode; - tree->nodes[i]->parent = tree; - } - } - return; -} - -/* function cannot be directly called - needs alloced bvh */ -void bvh_build (BVH *bvh) -{ - unsigned int i = 0, j = 0, k = 0; - CollisionTree **face_list=NULL; - CollisionTree *tree=NULL; - LinkNode *nlink = NULL; - - bvh->flags = 0; - bvh->leaf_tree = NULL; - bvh->leaf_root = NULL; - bvh->tree = NULL; - - if(!bvh->current_x) - { - bvh_free(bvh); - return; - } - - bvh->current_xold = MEM_dupallocN(bvh->current_x); - - tree = (CollisionTree *)MEM_callocN(sizeof(CollisionTree), "CollisionTree"); - - if (tree == NULL) - { - printf("bvh_build: Out of memory for nodes.\n"); - bvh_free(bvh); - return; - } - - BLI_linklist_append(&bvh->tree, tree); - - nlink = bvh->tree; - - bvh->root = bvh->tree->link; - bvh->root->isleaf = 0; - bvh->root->parent = NULL; - bvh->root->nodes[0] = bvh->root->nodes[1] = bvh->root->nodes[1] = bvh->root->nodes[3] = NULL; - - if(bvh->numfaces<=1) - { - bvh->root->tri_index = 0; // Why that? --> only one face there - bvh->root->isleaf = 1; - bvh->root->traversed = 0; - bvh->root->count_nodes = 0; - bvh->leaf_root = bvh->root; - bvh->leaf_tree = bvh->root; - bvh->root->nextLeaf = NULL; - bvh->root->prevLeaf = NULL; - } - else - { - // create face boxes - face_list = MEM_callocN (bvh->numfaces * sizeof (CollisionTree *), "CollisionTree"); - if (face_list == NULL) - { - printf("bvh_build: Out of memory for face_list.\n"); - bvh_free(bvh); - return; - } - - // create face boxes - for(i = 0, k = 0; i < bvh->numfaces; i++) - { - LinkNode *tnlink; - - tree = (CollisionTree *)MEM_callocN(sizeof(CollisionTree), "CollisionTree"); - // TODO: check succesfull alloc - - tnlink = BLI_linklist_append_fast(&nlink->next, tree); - - face_list[i] = tree; - tree->tri_index = i; - tree->isleaf = 1; - tree->nextLeaf = NULL; - tree->prevLeaf = bvh->leaf_tree; - tree->parent = NULL; - tree->count_nodes = 0; - - if(i==0) - { - bvh->leaf_tree = bvh->leaf_root = tree; - } - else - { - bvh->leaf_tree->nextLeaf = tree; - bvh->leaf_tree = bvh->leaf_tree->nextLeaf; - } - - tree->nodes[0] = tree->nodes[1] = tree->nodes[2] = tree->nodes[3] = NULL; - - bvh_calc_DOP_hull_static(bvh, &face_list[i], 1, tree->bv, tree); - - // inflate the bv with some epsilon - for (j = KDOP_START; j < KDOP_END; j++) - { - tree->bv[(2 * j)] -= bvh->epsilon; // minimum - tree->bv[(2 * j) + 1] += bvh->epsilon; // maximum - } - - nlink = tnlink; - } - - // build root bvh - bvh_calc_DOP_hull_from_faces(bvh, face_list, bvh->numfaces, bvh->root->bv); - - // This is the traversal function. - bvh_div_env_node(bvh, bvh->root, face_list, 0, bvh->numfaces-1, 0, nlink); - if (face_list) - MEM_freeN(face_list); - - } - -} - -// bvh_overlap - is it possbile for 2 bv's to collide ? -DO_INLINE int bvh_overlap(float *bv1, float *bv2) -{ - int i = 0; - for (i = KDOP_START; i < KDOP_END; i++) - { - // Minimum test. - if (bv1[(2 * i)] > bv2[(2 * i) + 1]) - { - return 0; - } - // Maxiumum test. - if (bv2[(2 * i)] > bv1[(2 * i) + 1]) - { - return 0; - } - } - - return 1; -} - -// bvh_overlap_self - is it possbile for 2 bv's to selfcollide ? -DO_INLINE int bvh_overlap_self(CollisionTree * tree1, CollisionTree * tree2) -{ - // printf("overlap: %f, q: %f\n", (saacos(INPR(tree1->normal, tree2->normal)) / 2.0)+MAX2(tree1->alpha, tree2->alpha), saacos(INPR(tree1->normal, tree2->normal))); - - if((saacos(INPR(tree1->normal, tree2->normal)) / 2.0)+MAX2(tree1->alpha, tree2->alpha) > M_PI) - { - return 1; - } - else - return 0; -} - -/** - * bvh_traverse - traverse two bvh trees looking for potential collisions. - * - * max collisions are n*n collisions --> every triangle collide with - * every other triangle that doesn't require any realloc, but uses - * much memory - */ -int bvh_traverse ( ModifierData * md1, ModifierData * md2, CollisionTree * tree1, CollisionTree * tree2, float step, CM_COLLISION_RESPONSE collision_response, int selfcollision) -{ - int i = 0, ret=0, overlap = 0; - - /* - // Shouldn't be possible - if(!tree1 || !tree2) - { - printf("Error: no tree there\n"); - return 0; -} - */ - - if(selfcollision) - overlap = bvh_overlap_self(tree1, tree2); - else - overlap = bvh_overlap(tree1->bv, tree2->bv); - - if (overlap) - { - // Check if this node in the first tree is a leaf - if (tree1->isleaf) - { - // Check if this node in the second tree a leaf - if (tree2->isleaf) - { - // Provide the collision response. - - if(collision_response) - collision_response (md1, md2, tree1, tree2); - return 1; - } - else - { - // Process the quad tree. - for (i = 0; i < 4; i++) - { - // Only traverse nodes that exist. - if (tree2->nodes[i] && bvh_traverse (md1, md2, tree1, tree2->nodes[i], step, collision_response, selfcollision)) - ret = 1; - } - } - } - else - { - // Process the quad tree. - for (i = 0; i < 4; i++) - { - // Only traverse nodes that exist. - if (tree1->nodes [i] && bvh_traverse (md1, md2, tree1->nodes[i], tree2, step, collision_response, selfcollision)) - ret = 1; - } - } - } - - return ret; -} -// bottom up update of bvh tree: -// join the 4 children here -void bvh_join(CollisionTree *tree) -{ - int i = 0, j = 0; - float max = 0; - - if (!tree) - return; - - for (i = 0; i < 4; i++) - { - if (tree->nodes[i]) - { - for (j = KDOP_START; j < KDOP_END; j++) - { - // update minimum - if ((tree->nodes[i]->bv[(2 * j)] < tree->bv[(2 * j)]) || (i == 0)) - { - tree->bv[(2 * j)] = tree->nodes[i]->bv[(2 * j)]; - } - // update maximum - if ((tree->nodes[i]->bv[(2 * j) + 1] > tree->bv[(2 * j) + 1])|| (i == 0)) - { - tree->bv[(2 * j) + 1] = tree->nodes[i]->bv[(2 * j) + 1]; - } - } - - /* for selfcollisions */ - /* - if(!i) - { - tree->alpha = tree->nodes[i]->alpha; - VECCOPY(tree->normal, tree->nodes[i]->normal); - } - else - { - tree->alpha += saacos(INPR(tree->normal, tree->nodes[i]->normal)) / 2.0; - VECADD(tree->normal, tree->normal, tree->nodes[i]->normal); - VecMulf(tree->normal, 0.5); - max = MAX2(max, tree->nodes[i]->alpha); - } - */ - - } - else - break; - } - - tree->alpha += max; -} - -// update static bvh -/* you have to update the bvh position before calling this function */ -void bvh_update(BVH * bvh, int moving) -{ - CollisionTree *leaf, *parent; - int traversecheck = 1; // if this is zero we don't go further - unsigned int j = 0; - - for (leaf = bvh->leaf_root; leaf; leaf = leaf->nextLeaf) - { - traversecheck = 1; - if ((leaf->parent) && (leaf->parent->traversed == leaf->parent->count_nodes)) - { - leaf->parent->traversed = 0; - } - if(!moving) - bvh_calc_DOP_hull_static(bvh, &leaf, 1, leaf->bv, leaf); - else - bvh_calc_DOP_hull_moving(bvh, &leaf, 1, leaf->bv, leaf); - - // inflate the bv with some epsilon - for (j = KDOP_START; j < KDOP_END; j++) - { - leaf->bv[(2 * j)] -= bvh->epsilon; // minimum - leaf->bv[(2 * j) + 1] += bvh->epsilon; // maximum - } - - for (parent = leaf->parent; parent; parent = parent->parent) - { - if (traversecheck) - { - parent->traversed++; // we tried to go up in hierarchy - if (parent->traversed < parent->count_nodes) - { - traversecheck = 0; - - if (parent->parent) - { - if (parent->parent->traversed == parent->parent->count_nodes) - { - parent->parent->traversed = 0; - } - } - break; // we do not need to check further - } - else - { - bvh_join(parent); - } - } - - } - } -} - diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c index 2a8ba878c41..472fd951168 100644 --- a/source/blender/blenkernel/intern/modifier.c +++ b/source/blender/blenkernel/intern/modifier.c @@ -58,6 +58,7 @@ #include "DNA_material_types.h" #include "DNA_mesh_types.h" #include "DNA_meshdata_types.h" +#include "DNA_sph_types.h" #include "DNA_modifier_types.h" #include "DNA_object_types.h" #include "DNA_object_force.h" @@ -90,6 +91,7 @@ #include "BKE_object.h" #include "BKE_mesh.h" #include "BKE_softbody.h" +#include "BKE_sph.h" #include "BKE_cloth.h" #include "BKE_material.h" #include "BKE_particle.h" @@ -5178,6 +5180,89 @@ static void clothModifier_freeData(ModifierData *md) } } +/* Smooth Particly Hydrodynamics */ + +static void sphModifier_initData(ModifierData *md) +{ + SphModifierData *sphmd = (SphModifierData*) md; + + sphmd->sim_parms = MEM_callocN(sizeof(SphSimSettings), "SPH sim parms"); + sphmd->coll_parms = MEM_callocN(sizeof(SphCollSettings), "SPH coll parms"); + + /* check for alloc failing */ + if(!sphmd->sim_parms || !sphmd->coll_parms) + return; + + sph_init(sphmd); +} + +static DerivedMesh *sphModifier_applyModifier(ModifierData *md, Object *ob, + DerivedMesh *derivedData, int useRenderParams, int isFinalCalc) +{ + SphModifierData *sphmd = (SphModifierData*) md; + DerivedMesh *result=NULL; + + /* check for alloc failing */ + if(!sphmd->sim_parms || !sphmd->coll_parms) + return derivedData; + + result = sphModifier_do(sphmd, ob, derivedData, useRenderParams, isFinalCalc); + + if(result) + { + CDDM_calc_normals(result); + return result; + } + + return derivedData; +} + +static void sphModifier_updateDepgraph( + ModifierData *md, DagForest *forest, Object *ob, + DagNode *obNode) +{ + SphModifierData *sphmd = (SphModifierData*) md; + + Base *base; + +} + +CustomDataMask sphModifier_requiredDataMask(ModifierData *md) +{ + CustomDataMask dataMask = 0; + + /* ask for vertexgroups if we need them */ + dataMask |= (1 << CD_MDEFORMVERT); + + return dataMask; +} + +static void sphModifier_copyData(ModifierData *md, ModifierData *target) +{ + +} + + +static int sphModifier_dependsOnTime(ModifierData *md) +{ + return 1; +} + +static void sphModifier_freeData(ModifierData *md) +{ + SphModifierData *sphmd = (SphModifierData*) md; + + if (sphmd) + { + sph_free_modifier(sphmd); + + if(sphmd->sim_parms) + MEM_freeN(sphmd->sim_parms); + if(sphmd->coll_parms) + MEM_freeN(sphmd->coll_parms); + } +} + /* Collision */ static void collisionModifier_initData(ModifierData *md) @@ -5191,7 +5276,7 @@ static void collisionModifier_initData(ModifierData *md) collmd->current_v = NULL; collmd->time = -1; collmd->numverts = 0; - collmd->bvh = NULL; + collmd->bvhtree = NULL; } static void collisionModifier_freeData(ModifierData *md) @@ -5200,8 +5285,8 @@ static void collisionModifier_freeData(ModifierData *md) if (collmd) { - if(collmd->bvh) - bvh_free(collmd->bvh); + if(collmd->bvhtree) + BLI_bvhtree_free(collmd->bvhtree); if(collmd->x) MEM_freeN(collmd->x); if(collmd->xnew) @@ -5212,7 +5297,6 @@ static void collisionModifier_freeData(ModifierData *md) MEM_freeN(collmd->current_xnew); if(collmd->current_v) MEM_freeN(collmd->current_v); - if(collmd->mfaces) MEM_freeN(collmd->mfaces); @@ -5223,7 +5307,7 @@ static void collisionModifier_freeData(ModifierData *md) collmd->current_v = NULL; collmd->time = -1; collmd->numverts = 0; - collmd->bvh = NULL; + collmd->bvhtree = NULL; collmd->mfaces = NULL; } } @@ -5291,9 +5375,8 @@ static void collisionModifier_deformVerts( collmd->mfaces = dm->dupFaceArray(dm); collmd->numfaces = dm->getNumFaces(dm); - // TODO: epsilon // create bounding box hierarchy - collmd->bvh = bvh_build_from_mvert(collmd->mfaces, collmd->numfaces, collmd->x, numverts, ob->pd->pdef_sboft); + collmd->bvhtree = bvhtree_build_from_mvert(collmd->mfaces, collmd->numfaces, collmd->x, numverts, ob->pd->pdef_sboft); collmd->time = current_time; } @@ -5316,25 +5399,25 @@ static void collisionModifier_deformVerts( memcpy(collmd->current_x, collmd->x, numverts*sizeof(MVert)); /* check if GUI setting has changed for bvh */ - if(collmd->bvh) + if(collmd->bvhtree) { - if(ob->pd->pdef_sboft != collmd->bvh->epsilon) + if(ob->pd->pdef_sboft != BLI_bvhtree_getepsilon(collmd->bvhtree)) { - bvh_free(collmd->bvh); - collmd->bvh = bvh_build_from_mvert(collmd->mfaces, collmd->numfaces, collmd->current_x, numverts, ob->pd->pdef_sboft); + BLI_bvhtree_free(collmd->bvhtree); + collmd->bvhtree = bvhtree_build_from_mvert(collmd->mfaces, collmd->numfaces, collmd->current_x, numverts, ob->pd->pdef_sboft); } } - /* happens on file load (ONLY when i decomment changes in readfile.c */ - if(!collmd->bvh) + /* happens on file load (ONLY when i decomment changes in readfile.c) */ + if(!collmd->bvhtree) { - collmd->bvh = bvh_build_from_mvert(collmd->mfaces, collmd->numfaces, collmd->current_x, numverts, ob->pd->pdef_sboft); + collmd->bvhtree = bvhtree_build_from_mvert(collmd->mfaces, collmd->numfaces, collmd->current_x, numverts, ob->pd->pdef_sboft); } else { // recalc static bounding boxes - bvh_update_from_mvert(collmd->bvh, collmd->current_x, numverts, NULL, 0); + bvhtree_update_from_mvert ( collmd->bvhtree, collmd->mfaces, collmd->numfaces, collmd->current_x, NULL, collmd->numverts, 0 ); } collmd->time = current_time; @@ -7106,6 +7189,18 @@ ModifierTypeInfo *modifierType_getInfo(ModifierType type) mti->requiredDataMask = bevelModifier_requiredDataMask; mti->applyModifier = bevelModifier_applyModifier; mti->applyModifierEM = bevelModifier_applyModifierEM; + + mti = INIT_TYPE(Sph); + mti->type = eModifierTypeType_Nonconstructive; + mti->flags = eModifierTypeFlag_AcceptsMesh + | eModifierTypeFlag_UsesPointCache; + mti->initData = sphModifier_initData; + mti->copyData = sphModifier_copyData; + mti->requiredDataMask = sphModifier_requiredDataMask; + mti->applyModifier = sphModifier_applyModifier; + mti->dependsOnTime = sphModifier_dependsOnTime; + mti->freeData = sphModifier_freeData; + mti->updateDepgraph = sphModifier_updateDepgraph; mti = INIT_TYPE(Displace); mti->type = eModifierTypeType_OnlyDeform; diff --git a/source/blender/blenkernel/intern/sph.c b/source/blender/blenkernel/intern/sph.c new file mode 100644 index 00000000000..3db1a361d5c --- /dev/null +++ b/source/blender/blenkernel/intern/sph.c @@ -0,0 +1,490 @@ +/* pw.c +* +* +* ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* as published by the Free Software Foundation; either version 2 +* of the License, or (at your option) any later version. The Blender +* Foundation also sells licenses for use in proprietary software under +* the Blender License. See http://www.blender.org/BL/ for information +* about this. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software Foundation, +* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +* +* The Original Code is Copyright (C) Blender Foundation +* All rights reserved. +* +* Contributor(s): Daniel Genrich +* +* ***** END GPL/BL DUAL LICENSE BLOCK ***** +*/ + +#include + +#include "MEM_guardedalloc.h" + +#include "BKE_sph.h" + +#include "DNA_sph_types.h" + +#include "sph_extern.h" + +#include "DNA_effect_types.h" +#include "DNA_mesh_types.h" +#include "DNA_meshdata_types.h" +#include "DNA_particle_types.h" +#include "DNA_scene_types.h" + +#include "BKE_cdderivedmesh.h" +#include "BKE_effect.h" +#include "BKE_global.h" +#include "BKE_mesh.h" +#include "BKE_modifier.h" +#include "BKE_particle.h" + + +// necessary +#include "float.h" +#include "math.h" +#include "BLI_kdtree.h" +#include "BLI_arithb.h" + +// #include "omp.h" + +#ifdef _WIN32 +void ststart ( void ) +{} +void stend ( void ) +{ +} +double stval() +{ + return 0; +} +#else +#include + +static struct timeval _ststart, _stend; +static struct timezone stz; + +void ststart(void) +{ + gettimeofday(&_ststart, &stz); +} +void stend(void) +{ + gettimeofday(&_stend,&stz); +} +double stval() +{ + double t1, t2; + t1 = (double)_ststart.tv_sec + (double)_ststart.tv_usec/(1000*1000); + t2 = (double)_stend.tv_sec + (double)_stend.tv_usec/(1000*1000); + return t2-t1; +} +#endif + +void sph_init (SphModifierData *sphmd) +{ + /* fill modifier with standard settings */ + sphmd->sim_parms->timestep = 0.001; // 0.001 + sphmd->sim_parms->viscosity = 80000.0; + sphmd->sim_parms->incompressibility = 8000000.0; + sphmd->sim_parms->surfacetension = 8000.0; + sphmd->sim_parms->density = 1000.0; + sphmd->sim_parms->gravity[2] = -9.81; + sphmd->sim_parms->gravity[1] = 0.0; + sphmd->sim_parms->gravity[0] = 0.0; + sphmd->sim_parms->samplingdistance = 0.02; // length of one cell? 0.01 + sphmd->sim_parms->smoothinglength = 2.5; + sphmd->sim_parms->flags = SPH_SIMSETTINGS_FLAG_GHOSTS | SPH_SIMSETTINGS_FLAG_OFFLINE | SPH_SIMSETTINGS_FLAG_MULTIRES | SPH_SIMSETTINGS_FLAG_DOMAIN; + sphmd->sim_parms->computesurfaceevery = 5; // 30000000 + sphmd->sim_parms->fastmarchingevery = 5; + sphmd->sim_parms->dumppovrayevery = 300000; + sphmd->sim_parms->dumpimageevery = 30; + sphmd->sim_parms->totaltime = 0.01; // 40.0 + sphmd->sim_parms->tangentialfriction = 0.1; + sphmd->sim_parms->normalfriction = 0.95; + sphmd->sim_parms->initiallevel = 1; + sphmd->sim_parms->rotation_angle = 0.0; + + sphmd->sim_parms->rotation_axis[0] = 1.0; + sphmd->sim_parms->rotation_axis[1] = 1.0; + sphmd->sim_parms->rotation_axis[2] = 1.0; + + sphmd->sim_parms->rotation_center[0] = 0.0; + sphmd->sim_parms->rotation_center[1] = 0.0; + sphmd->sim_parms->rotation_center[2] = 0.0; + + sphmd->sim_parms->scenelowerbound[0] = -1.0; + sphmd->sim_parms->scenelowerbound[1] = -1.0; + sphmd->sim_parms->scenelowerbound[2] = -1.0; + + sphmd->sim_parms->sceneupperbound[0] = 1.0; + sphmd->sim_parms->sceneupperbound[1] = 1.0; + sphmd->sim_parms->sceneupperbound[2] = 1.0; + + sphmd->sim_parms->alpha = 2.0; + sphmd->sim_parms->beta = 3.0; + sphmd->sim_parms->gamma = 1.5; + + sphmd->sim_parms->numverts = 0; + sphmd->sim_parms->numtris = 0; + sphmd->sim_parms->verts = NULL; + sphmd->sim_parms->tris = NULL; + sphmd->sim_parms->normals = NULL; + + sphmd->sim_parms->resolution = 70; + + sphmd->sim_parms->co = NULL; + sphmd->sim_parms->r = NULL; + sphmd->sim_parms->numpart = 0; +} + +void sph_free_modifier (SphModifierData *sphmd) +{ + + // sph_free_cpp(sphmd); + + if(sphmd->sim_parms->verts) + free(sphmd->sim_parms->verts); + if(sphmd->sim_parms->tris) + free(sphmd->sim_parms->tris); + if(sphmd->sim_parms->normals) + free(sphmd->sim_parms->normals); + if(sphmd->sim_parms->co) + MEM_freeN(sphmd->sim_parms->co); + if(sphmd->sim_parms->r) + free(sphmd->sim_parms->r); + +} + + +DerivedMesh *sphModifier_do(SphModifierData *sphmd,Object *ob, DerivedMesh *dm, int useRenderParams, int isFinalCalc) +{ + SphSimSettings *sim_parms = sphmd->sim_parms; + DerivedMesh *result = NULL; + MVert *mvert = NULL; + MFace *mface = NULL; + int a = 0; + float mat[4][4], imat[4][4]; + Mat4CpyMat4(mat, ob->obmat); + Mat4Invert(imat, mat); + + // only domain is simulated + if(!(sim_parms->flags & SPH_SIMSETTINGS_FLAG_DOMAIN) && !(sim_parms->flags & SPH_SIMSETTINGS_FLAG_BAKING)) + { + return dm; + } + + ststart(); + + if(!(sim_parms->flags & SPH_SIMSETTINGS_FLAG_INIT)) + { + if(!sph_init_all (sphmd, dm, ob)) + { + sphmd->sim_parms->flags &= ~SPH_SIMSETTINGS_FLAG_INIT; + return dm; + } + } + + + + // sph_simulate_cpp(ob, sphmd, 1.0, NULL); + + stend(); + + printf ( "SPH simulation time: %f\n", ( float ) stval() ); + + if(sim_parms->numverts && sim_parms->numtris) + { + + + result = CDDM_new ( sim_parms->numverts, 0, sim_parms->numtris); + + // copy verts + mvert = CDDM_get_verts(result); + for(a=0; anumverts; a++) { + MVert *mv = &mvert[a]; + float *vbCo = &sim_parms->verts[a*3]; + VECCOPY(mv->co, vbCo); + Mat4MulVecfl(imat, mv->co); + } + + mface = CDDM_get_faces(result); + for(a=0; anumtris; a++) { + MFace *mf = &mface[a]; + int *tri = &sim_parms->tris[a*3]; + mf->v1 = tri[0]; + mf->v2 = tri[1]; + mf->v3 = tri[2]; + test_index_face(mf, NULL, 0, 3); + } + + CDDM_calc_edges ( result ); + CDDM_calc_normals ( result ); + + return result; + } + else + return dm; +} + +static void set_min_max(float *min, float *max, float *co) +{ + // also calc min + max of bounding box for 3d grid + min[0] = MIN2(min[0], co[0]); + min[1] = MIN2(min[1], co[1]); + min[2] = MIN2(min[2], co[2]); + + max[0] = MAX2(max[0], co[0]); + max[1] = MAX2(max[1], co[1]); + max[2] = MAX2(max[2], co[2]); +} + +long calc_distance_field(Object *ob, DerivedMesh *dm, SphModifierData *sphmd, float mat[4][4]) +{ + int numverts = dm->getNumVerts(dm); + int numfaces = dm->getNumFaces(dm); + MVert *mvert = dm->getVertArray(dm); + MFace *mface = dm->getFaceArray(dm); + int i, j, k; + KDTree *tree; + float co[3], co1[3], co2[3], co3[3], co4[3]; + int index; + float min[3] = {FLT_MAX, FLT_MAX, FLT_MAX}, max[3] = {-FLT_MAX, -FLT_MAX, -FLT_MAX}, slice, maxdir; + int resx, resy, resz; + int maxres = 20; + float *dist; + float *normals; + int totpart = 0; + float *cos = NULL; + int maxpart = 0; + + printf("calc_distance_field\n"); + + dist = MEM_callocN(maxres*maxres*maxres*sizeof(float), "distance_field"); + normals = MEM_callocN(numfaces*3*sizeof(float), "triangle_normals"); + + ///////////////////////////////////////////////// + // create + fill + balance kdtree + ///////////////////////////////////////////////// + tree = BLI_kdtree_new(numverts); + for(i = 0; i < numfaces; i++) + { + VECCOPY(co1, mvert[mface[i].v1].co); + Mat4MulVecfl(mat, co1); + set_min_max(min, max, co1); + VECCOPY(co2, mvert[mface[i].v2].co); + Mat4MulVecfl(mat, co2); + set_min_max(min, max, co2); + VECCOPY(co3, mvert[mface[i].v3].co); + Mat4MulVecfl(mat, co3); + set_min_max(min, max, co3); + + // calc triangle center + VECCOPY(co, co1); + VECADD(co, co, co2); + VECADD(co, co, co3); + if(mface[i].v4) + { + VECCOPY(co4, mvert[mface[i].v4].co); + Mat4MulVecfl(mat, co4); + set_min_max(min, max, co4); + VECADD(co, co, co4); + VecMulf(co, 0.25); + } + else + VecMulf(co, 1.0 / 3.0); + + if(mface[i].v4) + CalcNormFloat4(mvert[mface[i].v1].co, mvert[mface[i].v2].co, mvert[mface[i].v3].co, mvert[mface[i].v4].co, &normals[i*3]); + else + CalcNormFloat(mvert[mface[i].v1].co, mvert[mface[i].v2].co, mvert[mface[i].v3].co, &normals[i*3]); + + BLI_kdtree_insert(tree, i, co, NULL); + } + BLI_kdtree_balance(tree); + ///////////////////////////////////////////////// + + // calculate slice height + width + maxdir = max[0] - min[0]; + maxdir = MAX2(max[1]-min[1], maxdir); + maxdir = MAX2(max[2]-min[2], maxdir); + slice = maxdir / (float)maxres; + resx = MIN2(maxres, ceil((max[0] - min[0]) / slice)); + resy = MIN2(maxres, ceil((max[1] - min[1]) / slice)); + resz = MIN2(maxres, ceil((max[2] - min[2]) / slice)); + + // adjust max + max[0] = min[0] + slice * resx; + max[1] = min[1] + slice * resy; + max[2] = min[2] + slice * resz; + + if(sphmd->sim_parms->co) + MEM_freeN(sphmd->sim_parms->co); + + cos = sphmd->sim_parms->co = MEM_callocN(sizeof(float)*3*resx*resy*resz, "sph_cos"); + // r = calloc(1, sizeof(float)*resx*resy*resz); + maxpart = sizeof(float)*3*resx*resy*resz; + +// #pragma omp parallel for private(i,j,k) schedule(static) + for(i = 0; i < resx; i ++) + { + for(j = 0; j < resy; j++) + { + for(k = 0; k < resz; k++) + { + KDTreeNearest nearest; + float tco[3]; + tco[0] = min[0] + slice * i + slice * 0.5; + tco[1] = min[1] + slice * j + slice * 0.5; + tco[2] = min[2] + slice * k + slice * 0.5; + + index = BLI_kdtree_find_nearest(tree, tco, NULL, &nearest); + + if(index != -1) + { + float t[3]; + float sgn; + + VECSUB(t, tco, nearest.co); + sgn = INPR(t, &normals[nearest.index*3]); + + if(sgn < 0.0) + sgn = -1.0; + else + sgn = 1.0; + + dist[(i*resy*resz)+(j*resz)+k] = sgn * nearest.dist; + + if((int)sgn < 0) + { + // create particle if inside object + VECCOPY(&cos[totpart*3], tco); + + totpart++; + } + + } + else + { + printf("Error: no nearest point!\n"); + } + } + } + } + printf("maxpart: %d, totpart: %d\n", maxpart, totpart); + + sphmd->sim_parms->numpart = totpart; + MEM_freeN(dist); + MEM_freeN(normals); + BLI_kdtree_free(tree); + return totpart; +} + +/* add constraints, inflows, fluid, ... */ +int sph_init_all (SphModifierData *sphmd, DerivedMesh *dm, Object *ob) +{ + Base *base=NULL; + Object *fobject = NULL; + SphModifierData *fsphmd = NULL; + int fluids = 0; // only one fluid object possible + DerivedMesh *fdm = NULL; + + sphmd->sim_parms->flags |= SPH_SIMSETTINGS_FLAG_INIT; + CDDM_calc_normals ( dm ); + + /* create C++ object */ + // sph_init_cpp(sphmd); + sphmd->sim_parms->numpart = calc_distance_field(ob, dm, sphmd, ob->obmat); + return 1; + + /* create fluid domain */ + // sph_set_domain(sphmd, dm, ob->obmat); + + // check for constraints, fluid, etc. but ignore domains + for ( base = G.scene->base.first; base; base = base->next ) + { + fobject = base->object; + fsphmd = ( SphModifierData * ) modifiers_findByType ( fobject, eModifierType_Sph ); + + // TODO I could check for linked groups, too + if ( !fsphmd ) + { + // TODO + } + else + { + if(fsphmd == sphmd) + continue; + + if(fsphmd->sim_parms) + { + // check for fluid + if(((short)fsphmd->sim_parms->flags == SPH_SIMSETTINGS_FLAG_FLUID) && (!fluids)) + { + // create fluids + // particles have to be created AFTER constraints + // TODO: no particles = crash + + // get derivedmesh from object + fdm = mesh_get_derived_final(fobject, CD_MASK_BAREMESH); + + // create fluid object + /* + if(!sph_add_particles(sphmd, fdm, fobject->obmat, fsphmd->sim_parms->resolution)) + { + fluids--; + } + */ + if(fdm) + fdm->release(fdm); + + fluids++; + } + else if((short)fsphmd->sim_parms->flags & SPH_SIMSETTINGS_FLAG_OBSTACLE) + { + + } + } + } + } + + if(!fluids) + return 0; + + return 1; +} + + + + + + + + + + + + + + + + + + + + + + + diff --git a/source/blender/blenlib/BLI_kdopbvh.h b/source/blender/blenlib/BLI_kdopbvh.h new file mode 100644 index 00000000000..51f87b26aaf --- /dev/null +++ b/source/blender/blenlib/BLI_kdopbvh.h @@ -0,0 +1,63 @@ +/** + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2006 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): Daniel (Genscher) + * + * ***** END GPL LICENSE BLOCK ***** + */ + + +#ifndef BLI_KDOPBVH_H +#define BLI_KDOPBVH_H + +#include + +struct BVHTree; +typedef struct BVHTree BVHTree; + +typedef struct BVHTreeOverlap { + int indexA; + int indexB; +} BVHTreeOverlap; + +BVHTree *BLI_bvhtree_new(int maxsize, float epsilon, char tree_type, char axis); +void BLI_bvhtree_free(BVHTree *tree); + +/* construct: first insert points, then call balance */ +int BLI_bvhtree_insert(BVHTree *tree, int index, float *co, int numpoints); +void BLI_bvhtree_balance(BVHTree *tree); + +/* update: first update points/nodes, then call update_tree to refit the bounding volumes */ +int BLI_bvhtree_update_node(BVHTree *tree, int index, float *co, float *co_moving, int numpoints); +void BLI_bvhtree_update_tree(BVHTree *tree); + +/* collision/overlap: check two trees if they overlap, alloc's *overlap with length of the int return value */ +BVHTreeOverlap *BLI_bvhtree_overlap(BVHTree *tree1, BVHTree *tree2, int *result); + +float BLI_bvhtree_getepsilon(BVHTree *tree); + +#endif // BLI_KDOPBVH_H + + + + diff --git a/source/blender/blenlib/intern/BLI_kdopbvh.c b/source/blender/blenlib/intern/BLI_kdopbvh.c new file mode 100644 index 00000000000..8be52854a7b --- /dev/null +++ b/source/blender/blenlib/intern/BLI_kdopbvh.c @@ -0,0 +1,786 @@ +/* kdop.c +* +* +* ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* as published by the Free Software Foundation; either version 2 +* of the License, or (at your option) any later version. The Blender +* Foundation also sells licenses for use in proprietary software under +* the Blender License. See http://www.blender.org/BL/ for information +* about this. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software Foundation, +* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +* +* The Original Code is Copyright (C) Blender Foundation +* All rights reserved. +* +* The Original Code is: all of this file. +* +* Contributor(s): Daniel Genrich +* +* ***** END GPL/BL DUAL LICENSE BLOCK ***** +*/ + +#include "math.h" +#include +#include +#include + +#include "MEM_guardedalloc.h" + +#include "BKE_utildefines.h" + +#include "BLI_kdopbvh.h" + +#ifdef _OPENMP +#include +#endif + +typedef struct BVHNode +{ + struct BVHNode *children[8]; // max 8 children + struct BVHNode *parent; // needed for bottom - top update + float bv[26]; // Bounding volume of all nodes, max 13 axis + int index; /* face, edge, vertex index */ + char totnode; // how many nodes are used, used for speedup + char traversed; // how many nodes already traversed until this level? + char main_axis; +} BVHNode; + +struct BVHTree +{ + BVHNode **nodes; + BVHNode *nodearray; /* pre-alloc branch nodes */ + int *orig_index; /* mapping for orig_index to node_index */ + float epsilon; /* epslion is used for inflation of the k-dop */ + int totleaf; // leafs + int totbranch; + char tree_type; // type of tree (4 => quadtree) + char axis; // kdop type (6 => OBB, 7 => AABB, ...) + char start_axis, stop_axis; // KDOP_AXES array indices according to axis +}; + +typedef struct BVHOverlapData +{ + BVHTree *tree1, *tree2; + BVHTreeOverlap *overlap; + int i, max_overlap; /* i is number of overlaps */ +} BVHOverlapData; +//////////////////////////////////////// + + +//////////////////////////////////////////////////////////////////////// +// Bounding Volume Hierarchy Definition +// +// Notes: From OBB until 26-DOP --> all bounding volumes possible, just choose type below +// Notes: You have to choose the type at compile time ITM +// Notes: You can choose the tree type --> binary, quad, octree, choose below +//////////////////////////////////////////////////////////////////////// + +static float KDOP_AXES[13][3] = +{ {1.0, 0, 0}, {0, 1.0, 0}, {0, 0, 1.0}, {1.0, 1.0, 1.0}, {1.0, -1.0, 1.0}, {1.0, 1.0, -1.0}, +{1.0, -1.0, -1.0}, {1.0, 1.0, 0}, {1.0, 0, 1.0}, {0, 1.0, 1.0}, {1.0, -1.0, 0}, {1.0, 0, -1.0}, +{0, 1.0, -1.0} +}; + +////////////////////////////////////////////////////////////////////////////////////////////////////// +// Introsort +// with permission deriven from the following Java code: +// http://ralphunden.net/content/tutorials/a-guide-to-introsort/ +// and he derived it from the SUN STL +////////////////////////////////////////////////////////////////////////////////////////////////////// +static int size_threshold = 16; +/* +* Common methods for all algorithms +*/ +static void bvh_exchange(BVHNode **a, int i, int j) +{ + BVHNode *t=a[i]; + a[i]=a[j]; + a[j]=t; +} +static int floor_lg(int a) +{ + return (int)(floor(log(a)/log(2))); +} + +/* +* Insertion sort algorithm +*/ +static void bvh_insertionsort(BVHNode **a, int lo, int hi, int axis) +{ + int i,j; + BVHNode *t; + for (i=lo; i < hi; i++) + { + j=i; + t = a[i]; + while((j!=lo) && (t->bv[axis] < (a[j-1])->bv[axis])) + { + a[j] = a[j-1]; + j--; + } + a[j] = t; + } +} + +static int bvh_partition(BVHNode **a, int lo, int hi, BVHNode * x, int axis) +{ + int i=lo, j=hi; + while (1) + { + while ((a[i])->bv[axis] < x->bv[axis]) i++; + j=j-1; + while (x->bv[axis] < (a[j])->bv[axis]) j=j-1; + if(!(i < j)) + return i; + bvh_exchange(a, i,j); + i++; + } +} + +/* +* Heapsort algorithm +*/ +static void bvh_downheap(BVHNode **a, int i, int n, int lo, int axis) +{ + BVHNode * d = a[lo+i-1]; + int child; + while (i<=n/2) + { + child = 2*i; + if ((child < n) && ((a[lo+child-1])->bv[axis] < (a[lo+child])->bv[axis])) + { + child++; + } + if (!(d->bv[axis] < (a[lo+child-1])->bv[axis])) break; + a[lo+i-1] = a[lo+child-1]; + i = child; + } + a[lo+i-1] = d; +} + +static void bvh_heapsort(BVHNode **a, int lo, int hi, int axis) +{ + int n = hi-lo, i; + for (i=n/2; i>=1; i=i-1) + { + bvh_downheap(a, i,n,lo, axis); + } + for (i=n; i>1; i=i-1) + { + bvh_exchange(a, lo,lo+i-1); + bvh_downheap(a, 1,i-1,lo, axis); + } +} + +static BVHNode *bvh_medianof3(BVHNode **a, int lo, int mid, int hi, int axis) // returns Sortable +{ + if ((a[mid])->bv[axis] < (a[lo])->bv[axis]) + { + if ((a[hi])->bv[axis] < (a[mid])->bv[axis]) + return a[mid]; + else + { + if ((a[hi])->bv[axis] < (a[lo])->bv[axis]) + return a[hi]; + else + return a[lo]; + } + } + else + { + if ((a[hi])->bv[axis] < (a[mid])->bv[axis]) + { + if ((a[hi])->bv[axis] < (a[lo])->bv[axis]) + return a[lo]; + else + return a[hi]; + } + else + return a[mid]; + } +} +/* +* Quicksort algorithm modified for Introsort +*/ +static void bvh_introsort_loop (BVHNode **a, int lo, int hi, int depth_limit, int axis) +{ + int p; + + while (hi-lo > size_threshold) + { + if (depth_limit == 0) + { + bvh_heapsort(a, lo, hi, axis); + return; + } + depth_limit=depth_limit-1; + p=bvh_partition(a, lo, hi, bvh_medianof3(a, lo, lo+((hi-lo)/2)+1, hi-1, axis), axis); + bvh_introsort_loop(a, p, hi, depth_limit, axis); + hi=p; + } +} + +static void sort(BVHNode **a0, int begin, int end, int axis) +{ + if (begin < end) + { + BVHNode **a=a0; + bvh_introsort_loop(a, begin, end, 2*floor_lg(end-begin), axis); + bvh_insertionsort(a, begin, end, axis); + } +} +void sort_along_axis(BVHTree *tree, int start, int end, int axis) +{ + sort(tree->nodes, start, end, axis); +} + +////////////////////////////////////////////////////////////////////////////////////////////////////// + +void BLI_bvhtree_free(BVHTree *tree) +{ + if(tree) + { + MEM_freeN(tree->nodes); + MEM_freeN(tree->nodearray); + MEM_freeN(tree->orig_index); + MEM_freeN(tree); + } +} + +BVHTree *BLI_bvhtree_new(int maxsize, float epsilon, char tree_type, char axis) +{ + BVHTree *tree; + int numbranches=0, i; + + // only support up to octree + if(tree_type > 8) + return NULL; + + tree = (BVHTree *)MEM_callocN(sizeof(BVHTree), "BVHTree"); + + if(tree) + { + // calculate max number of branches, our bvh kdop is "almost perfect" + for(i = 1; i <= (int)ceil((float)((float)log(maxsize)/(float)log(tree_type))); i++) + numbranches += (pow(tree_type, i) / tree_type); + + tree->nodes = (BVHNode **)MEM_callocN(sizeof(BVHNode *)*(numbranches+maxsize + tree_type), "BVHNodes"); + + if(!tree->nodes) + { + MEM_freeN(tree); + return NULL; + } + + tree->nodearray = (BVHNode *)MEM_callocN(sizeof(BVHNode)*(numbranches+maxsize + tree_type), "BVHNodeArray"); + + if(!tree->nodearray) + { + MEM_freeN(tree); + MEM_freeN(tree->nodes); + return NULL; + } + + tree->orig_index = (int *)MEM_callocN(sizeof(int)*(numbranches+maxsize + tree_type), "BVHIndexArray"); + + if(!tree->orig_index) + { + MEM_freeN(tree); + MEM_freeN(tree->nodes); + MEM_freeN(tree->nodearray); + return NULL; + } + + tree->epsilon = epsilon; + tree->tree_type = tree_type; + tree->axis = axis; + + if(axis == 26) + { + tree->start_axis = 0; + tree->stop_axis = 13; + } + else if(axis == 18) + { + tree->start_axis = 7; + tree->stop_axis = 13; + } + else if(axis == 14) + { + tree->start_axis = 0; + tree->stop_axis = 7; + } + else if(axis == 8) // AABB + { + tree->start_axis = 0; + tree->stop_axis = 4; + } + else if(axis == 6) // OBB + { + tree->start_axis = 0; + tree->stop_axis = 3; + } + else + { + BLI_bvhtree_free(tree); + return NULL; + } + } + + return tree; +} + +static void create_kdop_hull(BVHTree *tree, BVHNode *node, float *co, int numpoints, int moving) +{ + float newminmax; + int i, k; + + // don't init boudings for the moving case + if(!moving) + { + for (i = tree->start_axis; i < tree->stop_axis; i++) + { + node->bv[2*i] = FLT_MAX; + node->bv[2*i + 1] = -FLT_MAX; + } + } + + for(k = 0; k < numpoints; k++) + { + // for all Axes. + for (i = tree->start_axis; i < tree->stop_axis; i++) + { + newminmax = INPR(&co[k * 3], KDOP_AXES[i]); + if (newminmax < node->bv[2 * i]) + node->bv[2 * i] = newminmax; + if (newminmax > node->bv[(2 * i) + 1]) + node->bv[(2 * i) + 1] = newminmax; + } + } +} + +// depends on the fact that the BVH's for each face is already build +static void refit_kdop_hull(BVHTree *tree, int start, int end, float *bv) +{ + float newmin,newmax; + int i, j; + + for (i = tree->start_axis; i < tree->stop_axis; i++) + { + bv[2*i] = FLT_MAX; + bv[2*i + 1] = -FLT_MAX; + } + + for (j = start; j < end; j++) + { + // for all Axes. + for (i = tree->start_axis; i < tree->stop_axis; i++) + { + newmin = tree->nodes[j]->bv[(2 * i)]; + if ((newmin < bv[(2 * i)])) + bv[(2 * i)] = newmin; + + newmax = tree->nodes[j]->bv[(2 * i) + 1]; + if ((newmax > bv[(2 * i) + 1])) + bv[(2 * i) + 1] = newmax; + } + } +} + +int BLI_bvhtree_insert(BVHTree *tree, int index, float *co, int numpoints) +{ + BVHNode *node= NULL; + int i; + + // insert should only possible as long as tree->totbranch is 0 + if(tree->totbranch > 0) + return 0; + + if(tree->totleaf+1 >= MEM_allocN_len(tree->nodes)) + return 0; + + // TODO check if have enough nodes in array + + node = tree->nodes[tree->totleaf] = &(tree->nodearray[tree->totleaf]); + tree->totleaf++; + + create_kdop_hull(tree, node, co, numpoints, 0); + + // inflate the bv with some epsilon + for (i = tree->start_axis; i < tree->stop_axis; i++) + { + node->bv[(2 * i)] -= tree->epsilon; // minimum + node->bv[(2 * i) + 1] += tree->epsilon; // maximum + } + + node->index= index; + + return 1; +} + +// only supports x,y,z axis in the moment +// but we should use a plain and simple function here for speed sake +static char get_largest_axis(float *bv) +{ + float middle_point[3]; + + middle_point[0] = (bv[1]) - (bv[0]); // x axis + middle_point[1] = (bv[3]) - (bv[2]); // y axis + middle_point[2] = (bv[5]) - (bv[4]); // z axis + if (middle_point[0] > middle_point[1]) + { + if (middle_point[0] > middle_point[2]) + return 1; // max x axis + else + return 5; // max z axis + } + else + { + if (middle_point[1] > middle_point[2]) + return 3; // max y axis + else + return 5; // max z axis + } +} + +static void bvh_div_nodes(BVHTree *tree, BVHNode *node, int start, int end, char lastaxis) +{ + char laxis; + int i, tend; + BVHNode *tnode; + int slice = (end-start+tree->tree_type-1)/tree->tree_type; //division rounded up + + // Determine which axis to split along + laxis = get_largest_axis(node->bv); + + // Sort along longest axis + if(laxis!=lastaxis) + sort_along_axis(tree, start, end, laxis); + + // split nodes along longest axis + for (i=0; start < end; start += slice, i++) //i counts the current child + { + tend = start + slice; + + if(tend > end) tend = end; + + if(tend-start == 1) // ok, we have 1 left for this node + { + node->children[i] = tree->nodes[start]; + node->children[i]->parent = node; + } + else + { + tnode = node->children[i] = tree->nodes[tree->totleaf + tree->totbranch] = &(tree->nodearray[tree->totbranch + tree->totleaf]); + tree->totbranch++; + tnode->parent = node; + + refit_kdop_hull(tree, start, tend, tnode->bv); + bvh_div_nodes(tree, tnode, start, tend, laxis); + } + node->totnode++; + } + + return; +} + +static void verify_tree(BVHTree *tree) +{ + int i, j, check = 0; + + // check the pointer list + for(i = 0; i < tree->totleaf; i++) + { + if(tree->nodes[i]->parent == NULL) + printf("Leaf has no parent: %d\n", i); + else + { + for(j = 0; j < tree->tree_type; j++) + { + if(tree->nodes[i]->parent->children[j] == tree->nodes[i]) + check = 1; + } + if(!check) + { + printf("Parent child relationship doesn't match: %d\n", i); + } + check = 0; + } + } + + // check the leaf list + for(i = 0; i < tree->totleaf; i++) + { + if(tree->nodearray[i].parent == NULL) + printf("Leaf has no parent: %d\n", i); + else + { + for(j = 0; j < tree->tree_type; j++) + { + if(tree->nodearray[i].parent->children[j] == &tree->nodearray[i]) + check = 1; + } + if(!check) + { + printf("Parent child relationship doesn't match: %d\n", i); + } + check = 0; + } + } + + printf("branches: %d, leafs: %d, total: %d\n", tree->totbranch, tree->totleaf, tree->totbranch + tree->totleaf); +} + +void BLI_bvhtree_balance(BVHTree *tree) +{ + BVHNode *node; + int i; + + if(tree->totleaf == 0) + return; + + // create root node + node = tree->nodes[tree->totleaf] = &(tree->nodearray[tree->totleaf]); + tree->totbranch++; + + // refit root bvh node + refit_kdop_hull(tree, 0, tree->totleaf, tree->nodes[tree->totleaf]->bv); + // create + balance tree + bvh_div_nodes(tree, tree->nodes[tree->totleaf], 0, tree->totleaf, 0); + + // put indices into array for O(1) access + for(i = 0; i < tree->totleaf; i++) + { + tree->orig_index[tree->nodes[i]->index] = i; + } + + verify_tree(tree); +} + +// overlap - is it possbile for 2 bv's to collide ? +static int tree_overlap(float *bv1, float *bv2, int start_axis, int stop_axis) +{ + float *bv1_end = bv1 + (stop_axis<<1); + + bv1 += start_axis<<1; + bv2 += start_axis<<1; + + // test all axis if min + max overlap + for (; bv1 != bv1_end; bv1+=2, bv2+=2) + { + if ((*(bv1) > *(bv2 + 1)) || (*(bv2) > *(bv1 + 1))) + return 0; + } + + return 1; +} + +static void traverse(BVHOverlapData *data, BVHNode *node1, BVHNode *node2) +{ + int j; + + if(tree_overlap(node1->bv, node2->bv, MIN2(data->tree1->start_axis, data->tree2->start_axis), MIN2(data->tree1->stop_axis, data->tree2->stop_axis))) + { + // check if node1 is a leaf + if(node1->index) + { + // check if node2 is a leaf + if(node2->index) + { + + if(node1 == node2) + { + return; + } + + if(data->i >= data->max_overlap) + { + // try to make alloc'ed memory bigger + data->overlap = realloc(data->overlap, sizeof(BVHTreeOverlap)*data->max_overlap*2); + + if(!data->overlap) + { + printf("Out of Memory in traverse\n"); + return; + } + data->max_overlap *= 2; + } + + // both leafs, insert overlap! + data->overlap[data->i].indexA = node1->index; + data->overlap[data->i].indexB = node2->index; + + data->i++; + } + else + { + for(j = 0; j < data->tree2->tree_type; j++) + { + if(node2->children[j]) + traverse(data, node1, node2->children[j]); + } + } + } + else + { + + for(j = 0; j < data->tree2->tree_type; j++) + { + if(node1->children[j]) + traverse(data, node1->children[j], node2); + } + } + } + return; +} + +BVHTreeOverlap *BLI_bvhtree_overlap(BVHTree *tree1, BVHTree *tree2, int *result) +{ + int j, total = 0; + BVHTreeOverlap *overlap = NULL, *to = NULL; + BVHOverlapData *data[tree1->tree_type]; + + // check for compatibility of both trees (can't compare 14-DOP with 18-DOP) + if((tree1->axis != tree2->axis) && ((tree1->axis == 14) || tree2->axis == 14)) + return 0; + + // fast check root nodes for collision before doing big splitting + traversal + if(!tree_overlap(tree1->nodes[tree1->totleaf]->bv, tree2->nodes[tree2->totleaf]->bv, MIN2(tree1->start_axis, tree2->start_axis), MIN2(tree1->stop_axis, tree2->stop_axis))) + return 0; + + for(j = 0; j < tree1->tree_type; j++) + { + data[j] = (BVHOverlapData *)MEM_callocN(sizeof(BVHOverlapData), "BVHOverlapData"); + + // init BVHOverlapData + data[j]->overlap = (BVHTreeOverlap *)malloc(sizeof(BVHTreeOverlap)*MAX2(tree1->totleaf, tree2->totleaf)); + data[j]->tree1 = tree1; + data[j]->tree2 = tree2; + data[j]->max_overlap = MAX2(tree1->totleaf, tree2->totleaf); + data[j]->i = 0; + } + +#pragma omp parallel for private(j) schedule(static) + for(j = 0; j < tree1->tree_type; j++) + { + traverse(data[j], tree1->nodes[tree1->totleaf]->children[j], tree2->nodes[tree2->totleaf]); + } + + for(j = 0; j < tree1->tree_type; j++) + total += data[j]->i; + + to = overlap = (BVHTreeOverlap *)MEM_callocN(sizeof(BVHTreeOverlap)*total, "BVHTreeOverlap"); + + for(j = 0; j < tree1->tree_type; j++) + { + memcpy(to, data[j]->overlap, data[j]->i*sizeof(BVHTreeOverlap)); + to+=data[j]->i; + } + + for(j = 0; j < tree1->tree_type; j++) + { + free(data[j]->overlap); + MEM_freeN(data[j]); + } + + (*result) = total; + return overlap; +} + + +// bottom up update of bvh tree: +// join the 4 children here +static void node_join(BVHTree *tree, BVHNode *node) +{ + int i, j; + + for (i = tree->start_axis; i < tree->stop_axis; i++) + { + node->bv[2*i] = FLT_MAX; + node->bv[2*i + 1] = -FLT_MAX; + } + + for (i = 0; i < tree->tree_type; i++) + { + if (node->children[i]) + { + for (j = tree->start_axis; j < tree->stop_axis; j++) + { + // update minimum + if (node->children[i]->bv[(2 * j)] < node->bv[(2 * j)]) + node->bv[(2 * j)] = node->children[i]->bv[(2 * j)]; + + // update maximum + if (node->children[i]->bv[(2 * j) + 1] > node->bv[(2 * j) + 1]) + node->bv[(2 * j) + 1] = node->children[i]->bv[(2 * j) + 1]; + } + } + else + break; + } +} + +// call before BLI_bvhtree_update_tree() +int BLI_bvhtree_update_node(BVHTree *tree, int index, float *co, float *co_moving, int numpoints) +{ + BVHNode *node= NULL; + int i = 0; + + // check if index exists + if(index > tree->totleaf) + return 0; + + node = tree->nodes[tree->orig_index[index]]; + + create_kdop_hull(tree, node, co, numpoints, 0); + + if(co_moving) + create_kdop_hull(tree, node, co_moving, numpoints, 1); + + // inflate the bv with some epsilon + for (i = tree->start_axis; i < tree->stop_axis; i++) + { + node->bv[(2 * i)] -= tree->epsilon; // minimum + node->bv[(2 * i) + 1] += tree->epsilon; // maximum + } + + return 1; +} + +// call BLI_bvhtree_update_node() first for every node/point/triangle +void BLI_bvhtree_update_tree(BVHTree *tree) +{ + BVHNode *leaf, *parent; + + // reset tree traversing flag + for (leaf = tree->nodearray + tree->totleaf; leaf != tree->nodearray + tree->totleaf + tree->totbranch; leaf++) + leaf->traversed = 0; + + for (leaf = tree->nodearray; leaf != tree->nodearray + tree->totleaf; leaf++) + { + for (parent = leaf->parent; parent; parent = parent->parent) + { + parent->traversed++; // we tried to go up in hierarchy + if (parent->traversed < parent->totnode) + break; // we do not need to check further + else + node_join(tree, parent); + } + } +} + +float BLI_bvhtree_getepsilon(BVHTree *tree) +{ + return tree->epsilon; +} diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 24606bd822f..e3649a0cc43 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -3073,6 +3073,7 @@ static void direct_link_modifiers(FileData *fd, ListBase *lb) clmd->sim_parms= newdataadr(fd, clmd->sim_parms); clmd->coll_parms= newdataadr(fd, clmd->coll_parms); + clmd->point_cache= newdataadr(fd, clmd->point_cache); if(clmd->point_cache) @@ -3082,22 +3083,16 @@ static void direct_link_modifiers(FileData *fd, ListBase *lb) if(clmd->sim_parms->presets > 10) clmd->sim_parms->presets = 0; } + else + { + /* Collision modifier without parameters?? */ + + } } else if (md->type==eModifierType_Collision) { CollisionModifierData *collmd = (CollisionModifierData*) md; - /* - // TODO: CollisionModifier should use pointcache - // + have proper reset events before enabling this - collmd->x = newdataadr(fd, collmd->x); - collmd->xnew = newdataadr(fd, collmd->xnew); - collmd->mfaces = newdataadr(fd, collmd->mfaces); - - collmd->current_x = MEM_callocN(sizeof(MVert)*collmd->numverts,"current_x"); - collmd->current_xnew = MEM_callocN(sizeof(MVert)*collmd->numverts,"current_xnew"); - collmd->current_v = MEM_callocN(sizeof(MVert)*collmd->numverts,"current_v"); - */ collmd->x = NULL; collmd->xnew = NULL; @@ -3106,9 +3101,8 @@ static void direct_link_modifiers(FileData *fd, ListBase *lb) collmd->current_v = NULL; collmd->time = -1; collmd->numverts = 0; - collmd->bvh = NULL; + collmd->bvhtree = NULL; collmd->mfaces = NULL; - } else if (md->type==eModifierType_Hook) { HookModifierData *hmd = (HookModifierData*) md; diff --git a/source/blender/include/butspace.h b/source/blender/include/butspace.h index 242965a820c..c6482290c86 100644 --- a/source/blender/include/butspace.h +++ b/source/blender/include/butspace.h @@ -297,6 +297,10 @@ void curvemap_buttons(struct uiBlock *block, struct CurveMapping *cumap, char la /* Cloth sim button defines */ #define B_CLOTH_CHANGEPREROLL 1480 +/* SPH sim button defines */ +#define B_SPH_BAKE 1490 + + /* *********************** */ #define B_WORLDBUTS 1600 diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h index b7b43817474..b2d6e8e5756 100644 --- a/source/blender/makesdna/DNA_modifier_types.h +++ b/source/blender/makesdna/DNA_modifier_types.h @@ -35,6 +35,7 @@ typedef enum ModifierType { eModifierType_Cloth, eModifierType_Collision, eModifierType_Bevel, + eModifierType_Sph, NUM_MODIFIER_TYPES } ModifierType; @@ -374,6 +375,14 @@ typedef struct ClothModifierData { struct PointCache *point_cache; /* definition is in DNA_object_force.h */ } ClothModifierData; +typedef struct SphModifierData { + ModifierData modifier; + + struct SPH *sph; /* pointer to cpp sph sim */ + struct SphSimSettings *sim_parms; /* definition is in DNA_sph_types.h */ + struct SphCollSettings *coll_parms; /* definition is in DNA_sph_types.h */ +} SphModifierData; + typedef struct CollisionModifierData { ModifierData modifier; @@ -390,7 +399,7 @@ typedef struct CollisionModifierData { unsigned int numfaces; int pad; float time; /* cfra time of modifier */ - struct BVH *bvh; /* bounding volume hierarchy for this cloth object */ + struct BVHTree *bvhtree; /* bounding volume hierarchy for this cloth object */ } CollisionModifierData; typedef enum { diff --git a/source/blender/makesdna/DNA_sph_types.h b/source/blender/makesdna/DNA_sph_types.h new file mode 100644 index 00000000000..add3053f612 --- /dev/null +++ b/source/blender/makesdna/DNA_sph_types.h @@ -0,0 +1,102 @@ +/** + * $Id: DNA_cloth_types.h,v 1.1 2007/08/01 02:28:34 daniel Exp $ + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2006 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): Daniel (Genscher) + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + */ +#ifndef DNA_SPH_TYPES_H +#define DNA_SPH_TYPES_H + +// string scene, constraint, backup: missing +// string _file; +// string pov; +// string rendered; +typedef struct SphSimSettings +{ + int flags; // see pw_extern.h + float timestep; + float viscosity; + float incompressibility; /* how incompressible is the fluid? */ + float surfacetension; + float density; + float gravity[3]; /* gravity on the domain */ + float samplingdistance; + float smoothinglength; + + float controlviscosity; + int dumpimageevery; + int computesurfaceevery; + int fastmarchingevery; + int dumppovrayevery; + + float totaltime; + + float tangentialfriction; /* constraint tangential friction */ + float normalfriction; /* constraint normal friction */ + + float rotation_angle; + float rotation_axis[3]; + float rotation_center[3]; + float scenelowerbound[3]; + float sceneupperbound[3]; + + int initiallevel; + + float alpha; + float beta; + float gamma; + + /* needed for better direct resolution input for constraints, fluids,... */ + int resolution; /* can also be calculated by (Max-Min) / samplingdistance */ + int pad; + float *verts; + float *normals; + int *tris; + unsigned int numverts; + unsigned int numtris; + float *co; /* particle positions */ + float *r; /* particle radius */ + long numpart; + int pad2; +} +SphSimSettings; + +typedef struct SphCollSettings +{ + float epsilon; /* min distance for collisions. */ + float self_friction; /* Fiction/damping with self contact. */ + float friction; /* Friction/damping applied on contact with other object.*/ + short self_loop_count; /* How many iterations for the selfcollision loop */ + short loop_count; /* How many iterations for the collision loop. */ + struct LinkNode *collision_list; /* e.g. pointer to temp memory for collisions */ + int flags; /* collision flags defined in BKE_cloth.h */ + float selfepsilon; /* for selfcollision */ +} +SphCollSettings; + +#endif // DNA_SPH_TYPES_H diff --git a/source/blender/src/buttons_editing.c b/source/blender/src/buttons_editing.c index b02e89233e5..815a9c3869e 100644 --- a/source/blender/src/buttons_editing.c +++ b/source/blender/src/buttons_editing.c @@ -985,7 +985,7 @@ static uiBlock *modifiers_add_menu(void *ob_v) /* Only allow adding through appropriate other interfaces */ if(ELEM3(i, eModifierType_Softbody, eModifierType_Hook, eModifierType_ParticleSystem)) continue; - if(ELEM(i, eModifierType_Cloth, eModifierType_Collision)) continue; + if(ELEM3(i, eModifierType_Cloth, eModifierType_Collision, eModifierType_Sph)) continue; if((mti->flags&eModifierTypeFlag_AcceptsCVs) || (ob->type==OB_MESH && (mti->flags&eModifierTypeFlag_AcceptsMesh))) { @@ -1807,6 +1807,8 @@ static void draw_modifier(uiBlock *block, Object *ob, ModifierData *md, int *xco height = 31; } else if (md->type==eModifierType_Collision) { height = 31; + } else if (md->type==eModifierType_Sph) { + height = 31; } else if (md->type==eModifierType_Boolean) { height = 48; } else if (md->type==eModifierType_Array) { @@ -1837,7 +1839,7 @@ static void draw_modifier(uiBlock *block, Object *ob, ModifierData *md, int *xco uiButSetFunc(but, modifiers_applyModifier, ob, md); } - if (md->type!=eModifierType_Softbody && md->type!=eModifierType_ParticleSystem && (md->type!=eModifierType_Cloth)) { + if (md->type!=eModifierType_Softbody && md->type!=eModifierType_ParticleSystem && (md->type!=eModifierType_Cloth) && (md->type!=eModifierType_Sph)) { but = uiDefBut(block, BUT, B_MODIFIER_RECALC, "Copy", lx,(cy-=19),60,19, 0, 0, 0, 0, 0, "Duplicate the current modifier at the same position in the stack"); uiButSetFunc(but, modifiers_copyModifier, ob, md); } @@ -2229,6 +2231,8 @@ static void draw_modifier(uiBlock *block, Object *ob, ModifierData *md, int *xco uiDefBut(block, LABEL, 1, "See Soft Body panel.", lx, (cy-=19), buttonWidth,19, NULL, 0.0, 0.0, 0, 0, ""); } else if (md->type==eModifierType_Cloth) { uiDefBut(block, LABEL, 1, "See Cloth panel.", lx, (cy-=19), buttonWidth,19, NULL, 0.0, 0.0, 0, 0, ""); + } else if (md->type==eModifierType_Sph) { + uiDefBut(block, LABEL, 1, "See Sph panel.", lx, (cy-=19), buttonWidth,19, NULL, 0.0, 0.0, 0, 0, ""); } else if (md->type==eModifierType_Collision) { uiDefBut(block, LABEL, 1, "See Collision panel.", lx, (cy-=19), buttonWidth,19, NULL, 0.0, 0.0, 0, 0, ""); } else if (md->type==eModifierType_Boolean) { diff --git a/source/blender/src/buttons_object.c b/source/blender/src/buttons_object.c index 9a749b6fbd9..4dcc51e03e3 100644 --- a/source/blender/src/buttons_object.c +++ b/source/blender/src/buttons_object.c @@ -52,6 +52,8 @@ #include "BKE_utildefines.h" #include "BKE_particle.h" #include "BKE_pointcache.h" +#include "BKE_sph.h" + #include "BLI_blenlib.h" #include "BLI_arithb.h" @@ -107,6 +109,7 @@ #include "DNA_particle_types.h" #include "DNA_radio_types.h" #include "DNA_screen_types.h" +#include "DNA_sph_types.h" #include "DNA_sound_types.h" #include "DNA_texture_types.h" #include "DNA_userdef_types.h" @@ -135,6 +138,7 @@ #include "BKE_object.h" #include "BKE_particle.h" #include "BKE_sound.h" +#include "BKE_sph.h" #include "BKE_texture.h" #include "BKE_utildefines.h" #include "BKE_DerivedMesh.h" @@ -2476,6 +2480,27 @@ void do_object_panels(unsigned short event) allqueue(REDRAWVIEW3D, 0); } break; + case B_SPH_BAKE: + { + SphModifierData *sphmd = (SphModifierData *)modifiers_findByType(ob, eModifierType_Sph); + int i = 0; + + if(sphmd && sphmd->sim_parms) + { + sphmd->sim_parms->flags |= SPH_SIMSETTINGS_FLAG_BAKING; + + // call baking function + for(i = 0; i < 1; i++) + { + CFRA++; + update_for_newframe(); + } + + sphmd->sim_parms->flags &= ~SPH_SIMSETTINGS_FLAG_BAKING; + + } + } + break; } } @@ -5650,6 +5675,116 @@ static void object_panel_cloth_III(Object *ob) } +static void object_sph__enabletoggle(void *ob_v, void *arg2) +{ + Object *ob = ob_v; + ModifierData *md = modifiers_findByType(ob, eModifierType_Sph); + + if (!md) { + // create particle modifier + ParticleSettings *part = psys_new_settings("PSys", G.main); + ParticleSystem *psys = MEM_callocN(sizeof(ParticleSystem), "particle_system"); + ParticleSystemModifierData *psmd; + + md = modifier_new(eModifierType_Sph); + BLI_addtail(&ob->modifiers, md); + + part->type = PART_FLUID; + psys->part = part; + psys->pointcache = BKE_ptcache_add(); + psys->flag |= PSYS_ENABLED; + BLI_addtail(&ob->particlesystem,psys); + md= modifier_new(eModifierType_ParticleSystem); + sprintf(md->name, "SphParticleSystem" ); + psmd= (ParticleSystemModifierData*) md; + psmd->psys=psys; + BLI_addtail(&ob->modifiers, md); + + DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA); + allqueue(REDRAWBUTSEDIT, 0); + allqueue(REDRAWVIEW3D, 0); + } + else { + Object *ob = ob_v; + ModifierData *md = modifiers_findByType(ob, eModifierType_Sph); + + if (!md) + return; + + BLI_remlink(&ob->modifiers, md); + + modifier_free(md); + + BIF_undo_push("Del modifier"); + + // ob->softflag |= OB_SB_RESET; + allqueue(REDRAWBUTSEDIT, 0); + allqueue(REDRAWVIEW3D, 0); + allqueue(REDRAWIMAGE, 0); + allqueue(REDRAWOOPS, 0); + DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA); + object_handle_update(ob); + countall(); + } +} + +static void object_panel_sph(Object *ob) +{ + uiBlock *block=NULL; + uiBut *but=NULL; + static int val; + SphModifierData *sphmd = (SphModifierData *)modifiers_findByType(ob, eModifierType_Sph); + + block= uiNewBlock(&curarea->uiblocks, "object_sph", UI_EMBOSS, UI_HELV, curarea->win); + if(uiNewPanel(curarea, block, "Sph ", "Physics", 640, 0, 318, 204)==0) return; + uiSetButLock(object_data_is_libdata(ob), ERROR_LIBDATA_MESSAGE); + + val = (sphmd ? 1:0); + + + but = uiDefButI(block, TOG, REDRAWBUTSOBJECT, "Sph", 10,200,130,20, &val, 0, 0, 0, 0, "Sets object to become Sph"); + uiButSetFunc(but, object_sph__enabletoggle, ob, NULL); + + + uiDefBut(block, LABEL, 0, "",10,10,300,0, NULL, 0.0, 0, 0, 0, ""); /* tell UI we go to 10,10*/ + + if(sphmd) + { + if(sphmd->sim_parms && (sphmd->sim_parms->flags & SPH_SIMSETTINGS_FLAG_DOMAIN)) + { + uiDefBut(block, BUT, B_SPH_BAKE, "BAKE",10, 180,300,20, NULL, 0.0, 0.0, 10, 0, "Perform simulation and output and surface&preview meshes for each frame."); + } + + uiDefButS(block, ROW, REDRAWBUTSOBJECT ,"Domain", 10, 160, 100, 20, (short *)&sphmd->sim_parms->flags, 15.0, SPH_SIMSETTINGS_FLAG_DOMAIN, 0.0, 0.0, " "); + uiDefButS(block, ROW, REDRAWBUTSOBJECT ,"Fluid", 110, 160, 100, 20, (short *)&sphmd->sim_parms->flags, 15.0, SPH_SIMSETTINGS_FLAG_FLUID, 0.0, 0.0, " "); + uiDefButS(block, ROW, REDRAWBUTSOBJECT ,"Obstacle", 210, 160, 100, 20, (short *)&sphmd->sim_parms->flags, 15.0, SPH_SIMSETTINGS_FLAG_OBSTACLE, 0.0, 0.0, " "); + + if(sphmd->sim_parms && (sphmd->sim_parms->flags & SPH_SIMSETTINGS_FLAG_DOMAIN)) + { + uiDefButBitI(block, TOG, SPH_SIMSETTINGS_FLAG_GHOSTS, REDRAWBUTSOBJECT, "Ghosts",10,140,100,20, &sphmd->sim_parms->flags, 0, 0, 0, 0, " "); + uiDefButBitI(block, TOG, SPH_SIMSETTINGS_FLAG_MULTIRES, REDRAWBUTSOBJECT, "Multires",110,140,100,20, &sphmd->sim_parms->flags, 0, 0, 0, 0, " "); + uiDefButBitI(block, TOG, SPH_SIMSETTINGS_FLAG_VORTICITY, REDRAWBUTSOBJECT, "Vorticity",210,140,100,20, &sphmd->sim_parms->flags, 0, 0, 0, 0, " "); + + // timestep + uiDefButF(block, NUM, REDRAWBUTSOBJECT, "Timestep:",10,120,100,20, &sphmd->sim_parms->timestep, 0.0, 1.0, 0.0001f, 0, " "); + // totaltime + uiDefButF(block, NUM, REDRAWBUTSOBJECT, "Totaltime:",110,120,100,20, &sphmd->sim_parms->totaltime, 0.0, 10000.0, 0.001f, 0, " "); + uiDefButF(block, NUM, REDRAWBUTSOBJECT, "Sampling distance:",210,120,100,20, &sphmd->sim_parms->samplingdistance, 0.0, 1.0, 0.0001f, 0, " "); + uiDefButF(block, NUM, REDRAWBUTSOBJECT, "Smoothing Length:",10,100,100,20, &sphmd->sim_parms->smoothinglength, 0.0, 10.0, 0.1f, 0, " "); + + uiDefButI(block, NUM, REDRAWBUTSOBJECT, "Surface:",110,100,100,20, &sphmd->sim_parms->computesurfaceevery, 0.0, 1000.0, 1.0, 0, " "); + uiDefButI(block, NUM, REDRAWBUTSOBJECT, "Fast Marching:",210,100,100,20, &sphmd->sim_parms->fastmarchingevery, 0.0, 1000.0, 1.0, 0, " "); + } + else if(sphmd->sim_parms && (sphmd->sim_parms->flags & SPH_SIMSETTINGS_FLAG_FLUID)) + { + uiDefButI(block, NUM, REDRAWBUTSOBJECT, "Resolution:",10,120,100,20, &sphmd->sim_parms->resolution, 1.0, 1000.0, 1.0f, 0, " "); + } + } + + + uiBlockEndAlign(block); +} + void object_panels() { Object *ob; @@ -5682,6 +5817,7 @@ void physics_panels() object_panel_cloth(ob); object_panel_cloth_II(ob); object_panel_cloth_III(ob); + object_panel_sph(ob); object_panel_fluidsim(ob); } } diff --git a/source/blender/src/drawobject.c b/source/blender/src/drawobject.c index 561024fb74b..84289be0928 100644 --- a/source/blender/src/drawobject.c +++ b/source/blender/src/drawobject.c @@ -1883,11 +1883,13 @@ static void draw_em_measure_stats(Object *ob, EditMesh *em) { EditEdge *eed; EditFace *efa; + EditVert *eve; float v1[3], v2[3], v3[3], v4[3]; float fvec[3]; char val[32]; /* Stores the measurement display text here */ char conv_float[5]; /* Use a float conversion matching the grid size */ float area, col[3]; /* area of the face, color of the text to draw */ + int i = 0; /* make the precission of the pronted value proportionate to the gridsize */ if ((G.vd->grid) < 0.01) @@ -1941,7 +1943,7 @@ static void draw_em_measure_stats(Object *ob, EditMesh *em) if(col[1]> 0.5) {col[0]*=0.7; col[2]*= 0.7;} else col[1]= col[1]*0.7 + 0.3; glColor3fv(col); - + /* for(efa= em->faces.first; efa; efa= efa->next) { if((efa->f & SELECT) || (G.moving && faceselectedOR(efa, SELECT)) ) { VECCOPY(v1, efa->v1->co); @@ -1966,6 +1968,24 @@ static void draw_em_measure_stats(Object *ob, EditMesh *em) glRasterPos3fv(efa->cent); BMF_DrawString( G.fonts, val); } + }*/ + + /* draw IDs of mesh vertexes */ + for(eve = em->verts.first; eve; eve = eve->next) { + char val[32]; + float fvec[3]; + VecLerpf(fvec, ob->loc, eve->co, 1.1); + glRasterPos3f(fvec[0], fvec[1], fvec[2]); + + sprintf(val, "%d", eve->keyindex); + BMF_DrawString(G.fonts, val); + } + for(efa= em->faces.first; efa; efa= efa->next) { + char val[32]; + sprintf(val, "%d", i); + glRasterPos3fv(efa->cent); + BMF_DrawString( G.fonts, val); + i++; } } From e02bca73d78c7a86d383d38052c29f91b8b3d623 Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Tue, 13 May 2008 00:42:51 +0000 Subject: [PATCH 089/246] New speed imrovements by Mr. Pinto/jaguarandi --- source/blender/blenlib/BLI_kdopbvh.h | 2 +- source/blender/blenlib/intern/BLI_kdopbvh.c | 52 +++++++++++++-------- 2 files changed, 33 insertions(+), 21 deletions(-) diff --git a/source/blender/blenlib/BLI_kdopbvh.h b/source/blender/blenlib/BLI_kdopbvh.h index 3261984da76..c1240da6c3a 100644 --- a/source/blender/blenlib/BLI_kdopbvh.h +++ b/source/blender/blenlib/BLI_kdopbvh.h @@ -21,7 +21,7 @@ * * The Original Code is: all of this file. * - * Contributor(s): Daniel Genrich, Jose Pinto + * Contributor(s): Daniel Genrich, Andre Pinto * * ***** END GPL LICENSE BLOCK ***** */ diff --git a/source/blender/blenlib/intern/BLI_kdopbvh.c b/source/blender/blenlib/intern/BLI_kdopbvh.c index 6a1abb5d8ad..75ff1d8f257 100644 --- a/source/blender/blenlib/intern/BLI_kdopbvh.c +++ b/source/blender/blenlib/intern/BLI_kdopbvh.c @@ -25,7 +25,7 @@ * * The Original Code is: all of this file. * -* Contributor(s): Daniel Genrich, Jose Pinto +* Contributor(s): Daniel Genrich, Andre Pinto * * ***** END GPL/BL DUAL LICENSE BLOCK ***** */ @@ -40,6 +40,7 @@ #include "BKE_utildefines.h" #include "BLI_kdopbvh.h" +#include "BLI_arithb.h" #ifdef _OPENMP #include @@ -101,12 +102,6 @@ static int size_threshold = 16; /* * Common methods for all algorithms */ -static void bvh_exchange(BVHNode **a, int i, int j) -{ - BVHNode *t=a[i]; - a[i]=a[j]; - a[j]=t; -} static int floor_lg(int a) { return (int)(floor(log(a)/log(2))); @@ -138,11 +133,11 @@ static int bvh_partition(BVHNode **a, int lo, int hi, BVHNode * x, int axis) while (1) { while ((a[i])->bv[axis] < x->bv[axis]) i++; - j=j-1; - while (x->bv[axis] < (a[j])->bv[axis]) j=j-1; + j--; + while (x->bv[axis] < (a[j])->bv[axis]) j--; if(!(i < j)) return i; - bvh_exchange(a, i,j); + SWAP( BVHNode* , a[i], a[j]); i++; } } @@ -177,7 +172,7 @@ static void bvh_heapsort(BVHNode **a, int lo, int hi, int axis) } for (i=n; i>1; i=i-1) { - bvh_exchange(a, lo,lo+i-1); + SWAP(BVHNode*, a[lo],a[lo+i-1]); bvh_downheap(a, 1,i-1,lo, axis); } } @@ -244,6 +239,25 @@ void sort_along_axis(BVHTree *tree, int start, int end, int axis) sort(tree->nodes, start, end, axis); } +//after a call to this function you can expect one of: +// every node to left of a[n] are smaller than it +// every node to the right of a[n-1] are greater than it +void partition_nth_element(BVHNode **a, int _begin, int _end, int n, int axis) +{ + int begin = _begin, end = _end; + while(begin < n && end >= n) + { + int mid = bvh_partition(a, begin, end, bvh_medianof3(a, begin, (begin+end-1)/2, end-1, axis), axis ); + + if(mid >= n) + end = n-1; + else + begin = n+1; + } + +} + + ////////////////////////////////////////////////////////////////////////////////////////////////////// void BLI_bvhtree_free(BVHTree *tree) @@ -359,10 +373,11 @@ static void create_kdop_hull(BVHTree *tree, BVHNode *node, float *co, int numpoi } // depends on the fact that the BVH's for each face is already build -static void refit_kdop_hull(BVHTree *tree, int start, int end, float *bv) +static void refit_kdop_hull(BVHTree *tree, BVHNode *node, int start, int end) { float newmin,newmax; int i, j; + float *bv = node->bv; for (i = tree->start_axis; i < tree->stop_axis; i++) { @@ -451,16 +466,14 @@ static void bvh_div_nodes(BVHTree *tree, BVHNode *node, int start, int end, char // Determine which axis to split along laxis = get_largest_axis(node->bv); - - // Sort along longest axis - if(laxis!=lastaxis) - sort_along_axis(tree, start, end, laxis); // split nodes along longest axis for (i=0; start < end; start += slice, i++) //i counts the current child { tend = start + slice; + partition_nth_element(tree->nodes, start, end, tend, laxis); + if(tend > end) tend = end; if(tend-start == 1) // ok, we have 1 left for this node @@ -474,7 +487,7 @@ static void bvh_div_nodes(BVHTree *tree, BVHNode *node, int start, int end, char tree->totbranch++; tnode->parent = node; - refit_kdop_hull(tree, start, tend, tnode->bv); + partition_nth_element(tree->nodes, start, end, tend, laxis); bvh_div_nodes(tree, tnode, start, tend, laxis); } node->totnode++; @@ -533,7 +546,6 @@ static void verify_tree(BVHTree *tree) void BLI_bvhtree_balance(BVHTree *tree) { BVHNode *node; - int i; if(tree->totleaf == 0) return; @@ -543,11 +555,11 @@ void BLI_bvhtree_balance(BVHTree *tree) tree->totbranch++; // refit root bvh node - refit_kdop_hull(tree, 0, tree->totleaf, tree->nodes[tree->totleaf]->bv); + refit_kdop_hull(tree, tree->nodes[tree->totleaf], 0, tree->totleaf); // create + balance tree bvh_div_nodes(tree, tree->nodes[tree->totleaf], 0, tree->totleaf, 0); - verify_tree(tree); + // verify_tree(tree); } // overlap - is it possbile for 2 bv's to collide ? From 3bb43aaaafdda6fcbd1b7fab1e1ea473afc5e527 Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Tue, 13 May 2008 22:29:50 +0000 Subject: [PATCH 090/246] bug in bvhkdop (bad diff merged, pointed out by jaguarandi) --- source/blender/blenlib/intern/BLI_kdopbvh.c | 1 + 1 file changed, 1 insertion(+) diff --git a/source/blender/blenlib/intern/BLI_kdopbvh.c b/source/blender/blenlib/intern/BLI_kdopbvh.c index 75ff1d8f257..b80fe2103ed 100644 --- a/source/blender/blenlib/intern/BLI_kdopbvh.c +++ b/source/blender/blenlib/intern/BLI_kdopbvh.c @@ -488,6 +488,7 @@ static void bvh_div_nodes(BVHTree *tree, BVHNode *node, int start, int end, char tnode->parent = node; partition_nth_element(tree->nodes, start, end, tend, laxis); + refit_kdop_hull(tree, tnode, start, tend); bvh_div_nodes(tree, tnode, start, tend, laxis); } node->totnode++; From 83c2acccfbf311780b7fc3ea7aa8b5e0f4e03242 Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Tue, 13 May 2008 22:30:59 +0000 Subject: [PATCH 091/246] stupid me - i left the wrong line in. --- source/blender/blenlib/intern/BLI_kdopbvh.c | 1 - 1 file changed, 1 deletion(-) diff --git a/source/blender/blenlib/intern/BLI_kdopbvh.c b/source/blender/blenlib/intern/BLI_kdopbvh.c index b80fe2103ed..0d130cd37da 100644 --- a/source/blender/blenlib/intern/BLI_kdopbvh.c +++ b/source/blender/blenlib/intern/BLI_kdopbvh.c @@ -487,7 +487,6 @@ static void bvh_div_nodes(BVHTree *tree, BVHNode *node, int start, int end, char tree->totbranch++; tnode->parent = node; - partition_nth_element(tree->nodes, start, end, tend, laxis); refit_kdop_hull(tree, tnode, start, tend); bvh_div_nodes(tree, tnode, start, tend, laxis); } From 4d8b5587b867e53c22b4f3f3c56ba8714e9b7bfb Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Wed, 14 May 2008 16:09:56 +0000 Subject: [PATCH 092/246] Pre merge commit (includes commented moving stuff) --- source/blender/blenkernel/intern/cloth.c | 40 ++- source/blender/blenkernel/intern/collision.c | 276 ++++++++++++------- source/blender/blenkernel/intern/modifier.c | 2 +- source/blender/blenlib/intern/BLI_kdopbvh.c | 37 ++- 4 files changed, 251 insertions(+), 104 deletions(-) diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c index 192ebd90faa..6eb9f731056 100644 --- a/source/blender/blenkernel/intern/cloth.c +++ b/source/blender/blenkernel/intern/cloth.c @@ -47,6 +47,8 @@ #include "BLI_kdopbvh.h" +#include + #ifdef _WIN32 void tstart ( void ) {} @@ -78,6 +80,40 @@ double tval() } #endif + +/* Util macros */ +#define TO_STR(a) #a +#define JOIN(a,b) a##b + +/* Benchmark macros */ +#if 1 + +#define BENCH(a) \ + do { \ + clock_t _clock_init = clock(); \ + (a); \ + printf("%s: %fms\n", #a, (float)(clock()-_clock_init)*1000/CLOCKS_PER_SEC); \ +} while(0) + +#define BENCH_VAR(name) clock_t JOIN(_bench_step,name) = 0, JOIN(_bench_total,name) = 0 +#define BENCH_BEGIN(name) JOIN(_bench_step, name) = clock() +#define BENCH_END(name) JOIN(_bench_total,name) += clock() - JOIN(_bench_step,name) +#define BENCH_RESET(name) JOIN(_bench_total, name) = 0 +#define BENCH_REPORT(name) printf("%s: %fms\n", TO_STR(name), JOIN(_bench_total,name)*1000.0f/CLOCKS_PER_SEC) + +#else + +#define BENCH(a) (a) +#define BENCH_VAR(name) +#define BENCH_BEGIN(name) +#define BENCH_END(name) +#define BENCH_RESET(name) +#define BENCH_REPORT(name) + +#endif + + + /* Our available solvers. */ // 255 is the magic reserved number, so NEVER try to put 255 solvers in here! // 254 = MAX! @@ -178,7 +214,7 @@ BVHTree *bvhtree_build_from_cloth (ClothModifierData *clmd, float epsilon) return NULL; // create quadtree with k=26 - bvhtree = BLI_bvhtree_new(cloth->numfaces, epsilon, 4, 26); + bvhtree = BLI_bvhtree_new(cloth->numfaces, epsilon, 8, 6); // fill tree for(i = 0; i < cloth->numfaces; i++, mfaces++) @@ -866,7 +902,7 @@ static int cloth_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *d if(!first) implicit_set_positions(clmd); - clmd->clothObject->bvhtree = bvhtree_build_from_cloth ( clmd, clmd->coll_parms->epsilon ); + BENCH(clmd->clothObject->bvhtree = bvhtree_build_from_cloth ( clmd, clmd->coll_parms->epsilon )); return 1; } diff --git a/source/blender/blenkernel/intern/collision.c b/source/blender/blenkernel/intern/collision.c index 9ba47874d3c..1e8b8706658 100644 --- a/source/blender/blenkernel/intern/collision.c +++ b/source/blender/blenkernel/intern/collision.c @@ -608,22 +608,9 @@ int cloth_collision_response_static ( ClothModifierData *clmd, CollisionModifier result = 1; } } - - return result; } -int cloth_collision_response_moving_tris ( ClothModifierData *clmd, ClothModifierData *coll_clmd ) -{ - return 1; -} - - -int cloth_collision_response_moving_edges ( ClothModifierData *clmd, ClothModifierData *coll_clmd ) -{ - return 1; -} - //Determines collisions on overlap, collisions are writen to collpair[i] and collision+number_collision_found is returned CollPair* cloth_collision ( ModifierData *md1, ModifierData *md2, BVHTreeOverlap *overlap, CollPair *collpair ) { @@ -743,25 +730,148 @@ int cloth_are_edges_adjacent ( ClothModifierData *clmd, CollisionModifierData *c cloth1 = clmd->clothObject; verts1 = cloth1->verts; - VECSUB ( temp, verts1[edgecollpair->p11].xold, verts2[edgecollpair->p21].co ); + VECSUB ( temp, verts1[edgecollpair->p11].txold, verts2[edgecollpair->p21].co ); if ( ABS ( INPR ( temp, temp ) ) < ALMOST_ZERO ) return 1; - VECSUB ( temp, verts1[edgecollpair->p11].xold, verts2[edgecollpair->p22].co ); + VECSUB ( temp, verts1[edgecollpair->p11].txold, verts2[edgecollpair->p22].co ); if ( ABS ( INPR ( temp, temp ) ) < ALMOST_ZERO ) return 1; - VECSUB ( temp, verts1[edgecollpair->p12].xold, verts2[edgecollpair->p21].co ); + VECSUB ( temp, verts1[edgecollpair->p12].txold, verts2[edgecollpair->p21].co ); if ( ABS ( INPR ( temp, temp ) ) < ALMOST_ZERO ) return 1; - VECSUB ( temp, verts1[edgecollpair->p12].xold, verts2[edgecollpair->p22].co ); + VECSUB ( temp, verts1[edgecollpair->p12].txold, verts2[edgecollpair->p22].co ); if ( ABS ( INPR ( temp, temp ) ) < ALMOST_ZERO ) return 1; + + VECSUB ( temp, verts1[edgecollpair->p11].txold, verts1[edgecollpair->p12].txold ); + if ( ABS ( INPR ( temp, temp ) ) < ALMOST_ZERO ) + return 1; + + VECSUB ( temp, verts2[edgecollpair->p21].co, verts2[edgecollpair->p22].co ); + if ( ABS ( INPR ( temp, temp ) ) < ALMOST_ZERO ) + return 1; + return 0; } +int cloth_collision_response_moving( ClothModifierData *clmd, CollisionModifierData *collmd, CollPair *collpair, CollPair *collision_end ) +{ + int result = 0; + Cloth *cloth1; + float w1, w2, w3, u1, u2, u3; + float v1[3], v2[3], relativeVelocity[3]; + float magrelVel; + float epsilon2 = BLI_bvhtree_getepsilon ( collmd->bvhtree ); + + cloth1 = clmd->clothObject; + + for ( ; collpair != collision_end; collpair++ ) + { + // only handle static collisions here + if ( collpair->flag & COLLISION_IN_FUTURE ) + continue; + + // compute barycentric coordinates for both collision points + collision_compute_barycentric ( collpair->pa, + cloth1->verts[collpair->ap1].txold, + cloth1->verts[collpair->ap2].txold, + cloth1->verts[collpair->ap3].txold, + &w1, &w2, &w3 ); + + // was: txold + collision_compute_barycentric ( collpair->pb, + collmd->current_x[collpair->bp1].co, + collmd->current_x[collpair->bp2].co, + collmd->current_x[collpair->bp3].co, + &u1, &u2, &u3 ); + + // Calculate relative "velocity". + collision_interpolateOnTriangle ( v1, cloth1->verts[collpair->ap1].tv, cloth1->verts[collpair->ap2].tv, cloth1->verts[collpair->ap3].tv, w1, w2, w3 ); + + collision_interpolateOnTriangle ( v2, collmd->current_v[collpair->bp1].co, collmd->current_v[collpair->bp2].co, collmd->current_v[collpair->bp3].co, u1, u2, u3 ); + + VECSUB ( relativeVelocity, v2, v1 ); + + // Calculate the normal component of the relative velocity (actually only the magnitude - the direction is stored in 'normal'). + magrelVel = INPR ( relativeVelocity, collpair->normal ); + + // printf("magrelVel: %f\n", magrelVel); + + // Calculate masses of points. + // TODO + + // If v_n_mag < 0 the edges are approaching each other. + if ( magrelVel > ALMOST_ZERO ) + { + // Calculate Impulse magnitude to stop all motion in normal direction. + float magtangent = 0, repulse = 0, d = 0; + double impulse = 0.0; + float vrel_t_pre[3]; + float temp[3]; + + // calculate tangential velocity + VECCOPY ( temp, collpair->normal ); + VecMulf ( temp, magrelVel ); + VECSUB ( vrel_t_pre, relativeVelocity, temp ); + + // Decrease in magnitude of relative tangential velocity due to coulomb friction + // in original formula "magrelVel" should be the "change of relative velocity in normal direction" + magtangent = MIN2 ( clmd->coll_parms->friction * 0.01 * magrelVel,sqrt ( INPR ( vrel_t_pre,vrel_t_pre ) ) ); + + // Apply friction impulse. + if ( magtangent > ALMOST_ZERO ) + { + Normalize ( vrel_t_pre ); + + impulse = 2.0 * magtangent / ( 1.0 + w1*w1 + w2*w2 + w3*w3 ); + VECADDMUL ( cloth1->verts[collpair->ap1].impulse, vrel_t_pre, w1 * impulse ); + VECADDMUL ( cloth1->verts[collpair->ap2].impulse, vrel_t_pre, w2 * impulse ); + VECADDMUL ( cloth1->verts[collpair->ap3].impulse, vrel_t_pre, w3 * impulse ); + } + + // Apply velocity stopping impulse + // I_c = m * v_N / 2.0 + // no 2.0 * magrelVel normally, but looks nicer DG + impulse = magrelVel / ( 1.0 + w1*w1 + w2*w2 + w3*w3 ); + + VECADDMUL ( cloth1->verts[collpair->ap1].impulse, collpair->normal, w1 * impulse ); + cloth1->verts[collpair->ap1].impulse_count++; + + VECADDMUL ( cloth1->verts[collpair->ap2].impulse, collpair->normal, w2 * impulse ); + cloth1->verts[collpair->ap2].impulse_count++; + + VECADDMUL ( cloth1->verts[collpair->ap3].impulse, collpair->normal, w3 * impulse ); + cloth1->verts[collpair->ap3].impulse_count++; + + // Apply repulse impulse if distance too short + // I_r = -min(dt*kd, m(0,1d/dt - v_n)) + /* + d = clmd->coll_parms->epsilon*8.0/9.0 + epsilon2*8.0/9.0 - collpair->distance; + if ( ( magrelVel < 0.1*d*clmd->sim_parms->stepsPerFrame ) && ( d > ALMOST_ZERO ) ) + { + repulse = MIN2 ( d*1.0/clmd->sim_parms->stepsPerFrame, 0.1*d*clmd->sim_parms->stepsPerFrame - magrelVel ); + + // stay on the safe side and clamp repulse + if ( impulse > ALMOST_ZERO ) + repulse = MIN2 ( repulse, 5.0*impulse ); + repulse = MAX2 ( impulse, repulse ); + + impulse = repulse / ( 1.0 + w1*w1 + w2*w2 + w3*w3 ); // original 2.0 / 0.25 + VECADDMUL ( cloth1->verts[collpair->ap1].impulse, collpair->normal, impulse ); + VECADDMUL ( cloth1->verts[collpair->ap2].impulse, collpair->normal, impulse ); + VECADDMUL ( cloth1->verts[collpair->ap3].impulse, collpair->normal, impulse ); + } +*/ + result = 1; + } + } + return result; +} + int cloth_collision_moving_edges ( ClothModifierData *clmd, CollisionModifierData *collmd, CollPair *collpair ) { EdgeCollPair edgecollpair; @@ -781,53 +891,6 @@ int cloth_collision_moving_edges ( ClothModifierData *clmd, CollisionModifierDat cloth1 = clmd->clothObject; verts1 = cloth1->verts; - /* - double p[4][3] = {{0,0,0},{0,2,0},{1,1,-1},{1,1,1}}; - double v[4][3] = {{0,0,0},{1,0,0},{-2,0,0},{-2,0,0}}; - - double pp[2][3] = {{-1,-1,-1}, {2,2,2}}; - - - VECSUB ( x1, p[1], p[0] ); - VECSUB ( v1, v[1], v[0] ); - - VECSUB ( x2, p[2], p[0] ); - VECSUB ( v2, v[2], v[0] ); - - VECSUB ( x3, p[3], p[0] ); - VECSUB ( v3, v[3], v[0] ); - - printf("x1 x: %f, y: %f, z: %f\n", x1[0], x1[1], x1[2]); - printf("x2 x: %f, y: %f, z: %f\n", x2[0], x2[1], x2[2]); - printf("x3 x: %f, y: %f, z: %f\n", x3[0], x3[1], x3[2]); - - printf("v1 x: %f, y: %f, z: %f\n", v1[0], v1[1], v1[2]); - printf("v2 x: %f, y: %f, z: %f\n", v2[0], v2[1], v2[2]); - printf("v3 x: %f, y: %f, z: %f\n", v3[0], v3[1], v3[2]); - - numsolutions = cloth_get_collision_time ( x1, v1, x2, v2, x3, v3, solution ); - - for ( k = 0; k < numsolutions; k++ ) - printf("mintime: %f\n", solution[k]); - - mintime = solution[0]; - - // move triangles to collision point in time - VECADDS(triA[0], pp[0], v[0], solution[0]); - VECADDS(triA[1], p[0], v[0], solution[0]); - VECADDS(triA[2], p[1], v[1], solution[0]); - - VECADDS(triB[0], pp[1], v[0], solution[0]); - VECADDS(triB[1], p[2], v[2], solution[0]); - VECADDS(triB[2], p[3], v[3], solution[0]); - - // check distance there - distance = plNearestPoints (triA[0], triA[1], triA[2], triB[0], triB[1], triB[2], collpair->pa,collpair->pb,collpair->vector ); - - printf("mintime: %f, dist: %f\n", mintime, distance); - - exit(0); - */ for(i = 0; i < 9; i++) { // 9 edge - edge possibilities @@ -916,19 +979,12 @@ int cloth_collision_moving_edges ( ClothModifierData *clmd, CollisionModifierDat VECSUB ( x3, verts2[edgecollpair.p22].co, verts1[edgecollpair.p11].txold ); VECSUB ( v3, velocity2[edgecollpair.p22].co, verts1[edgecollpair.p11].tv ); - /* - printf("A x: %f, y: %f, z: %f\n", a[0], a[1], a[2]); - printf("B x: %f, y: %f, z: %f\n", b[0], b[1], b[2]); - printf("C x: %f, y: %f, z: %f\n", c[0], c[1], c[2]); - printf("D x: %f, y: %f, z: %f\n", d[0], d[1], d[2]); - printf("E x: %f, y: %f, z: %f\n", e[0], e[1], e[2]); - printf("F x: %f, y: %f, z: %f\n", f[0], f[1], f[2]); - exit(0); - */ + numsolutions = cloth_get_collision_time ( x1, v1, x2, v2, x3, v3, solution ); for ( k = 0; k < numsolutions; k++ ) { + // printf("sol %d: %lf\n", k, solution[k]); if ( ( solution[k] >= DBL_EPSILON ) && ( solution[k] <= 1.0 ) ) { //float out_collisionTime = solution[k]; @@ -939,8 +995,6 @@ int cloth_collision_moving_edges ( ClothModifierData *clmd, CollisionModifierDat mintime = MIN2(mintime, (float)solution[k]); -// printf("mt: %f, %lf, %f\n", mintime, solution[k], (float)solution[k]); - result = 1; break; } @@ -962,12 +1016,25 @@ int cloth_collision_moving_edges ( ClothModifierData *clmd, CollisionModifierDat // check distance there distance = plNearestPoints (triA[0], triA[1], triA[2], triB[0], triB[1], triB[2], collpair->pa,collpair->pb,collpair->vector ); - printf("mintime: %f, dist: %f\n", mintime, distance); + if(distance <= (clmd->coll_parms->epsilon + BLI_bvhtree_getepsilon ( collmd->bvhtree ) + ALMOST_ZERO)) + { + CollPair *next = collpair; + next++; + + collpair->distance = clmd->coll_parms->epsilon; + collpair->time = mintime; + + VECCOPY ( collpair->normal, collpair->vector ); + Normalize ( collpair->normal ); + + cloth_collision_response_moving ( clmd, collmd, collpair, next ); + } } return result; } +/* void cloth_collision_moving_tris ( ClothModifierData *clmd, ClothModifierData *coll_clmd, CollisionTree *tree1, CollisionTree *tree2 ) { CollPair collpair; @@ -1060,16 +1127,6 @@ void cloth_collision_moving_tris ( ClothModifierData *clmd, ClothModifierData *c } } } - -/* -void cloth_collision_moving ( ClothModifierData *clmd, ClothModifierData *coll_clmd, CollisionTree *tree1, CollisionTree *tree2 ) -{ - // TODO: check for adjacent - cloth_collision_moving_edges ( clmd, coll_clmd, tree1, tree2 ); - - cloth_collision_moving_tris ( clmd, coll_clmd, tree1, tree2 ); - cloth_collision_moving_tris ( coll_clmd, clmd, tree2, tree1 ); -} */ int cloth_collision_moving ( ClothModifierData *clmd, CollisionModifierData *collmd, CollPair *collpair, CollPair *collision_end ) @@ -1150,24 +1207,43 @@ int cloth_bvh_objcollisions_do ( ClothModifierData * clmd, CollisionModifierData if ( collmd->bvhtree ) { result += cloth_collision_response_static ( clmd, collmd, collisions, collisions_index ); - result += cloth_collision_moving ( clmd, collmd, collisions, collisions_index ); - } - // apply impulses in parallel - if ( result ) - { - for ( i = 0; i < numverts; i++ ) + // apply impulses in parallel + if ( result ) { - // calculate "velocities" (just xnew = xold + v; no dt in v) - if ( verts[i].impulse_count ) + for ( i = 0; i < numverts; i++ ) { - VECADDMUL ( verts[i].tv, verts[i].impulse, 1.0f / verts[i].impulse_count ); - VECCOPY ( verts[i].impulse, tnull ); - verts[i].impulse_count = 0; - - ret++; + // calculate "velocities" (just xnew = xold + v; no dt in v) + if ( verts[i].impulse_count ) + { + VECADDMUL ( verts[i].tv, verts[i].impulse, 1.0f / verts[i].impulse_count ); + VECCOPY ( verts[i].impulse, tnull ); + verts[i].impulse_count = 0; + + ret++; + } } } + /* + result += cloth_collision_moving ( clmd, collmd, collisions, collisions_index ); + + // apply impulses in parallel + if ( result ) + { + for ( i = 0; i < numverts; i++ ) + { + // calculate "velocities" (just xnew = xold + v; no dt in v) + if ( verts[i].impulse_count ) + { + VECADDMUL ( verts[i].tv, verts[i].impulse, 1.0f / verts[i].impulse_count ); + VECCOPY ( verts[i].impulse, tnull ); + verts[i].impulse_count = 0; + + ret++; + } + } + } + */ } } @@ -1207,7 +1283,7 @@ int cloth_bvh_objcollision ( ClothModifierData * clmd, float step, float dt ) //////////////////////////////////////////////////////////// // update cloth bvh - bvhtree_update_from_cloth ( clmd, 0 ); // 0 means STATIC, 1 means MOVING (see later in this function) + bvhtree_update_from_cloth ( clmd, 1 ); // 0 means STATIC, 1 means MOVING (see later in this function) do { diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c index a29c10a95ac..b481055ff16 100644 --- a/source/blender/blenkernel/intern/modifier.c +++ b/source/blender/blenkernel/intern/modifier.c @@ -5417,7 +5417,7 @@ static void collisionModifier_deformVerts( else { // recalc static bounding boxes - bvhtree_update_from_mvert ( collmd->bvhtree, collmd->mfaces, collmd->numfaces, collmd->current_x, NULL, collmd->numverts, 0 ); + bvhtree_update_from_mvert ( collmd->bvhtree, collmd->mfaces, collmd->numfaces, collmd->current_x, collmd->current_xnew, collmd->numverts, 1 ); } collmd->time = current_time; diff --git a/source/blender/blenlib/intern/BLI_kdopbvh.c b/source/blender/blenlib/intern/BLI_kdopbvh.c index 0d130cd37da..b3f11039ce1 100644 --- a/source/blender/blenlib/intern/BLI_kdopbvh.c +++ b/source/blender/blenlib/intern/BLI_kdopbvh.c @@ -46,6 +46,41 @@ #include #endif +#include + +/* Util macros */ +#define TO_STR(a) #a +#define JOIN(a,b) a##b + +/* Benchmark macros */ +#if 1 + +#define BENCH(a) \ + do { \ + clock_t _clock_init = clock(); \ + (a); \ + printf("%s: %fms\n", #a, (float)(clock()-_clock_init)*1000/CLOCKS_PER_SEC); \ +} while(0) + +#define BENCH_VAR(name) clock_t JOIN(_bench_step,name) = 0, JOIN(_bench_total,name) = 0 +#define BENCH_BEGIN(name) JOIN(_bench_step, name) = clock() +#define BENCH_END(name) JOIN(_bench_total,name) += clock() - JOIN(_bench_step,name) +#define BENCH_RESET(name) JOIN(_bench_total, name) = 0 +#define BENCH_REPORT(name) printf("%s: %fms\n", TO_STR(name), JOIN(_bench_total,name)*1000.0f/CLOCKS_PER_SEC) + +#else + +#define BENCH(a) (a) +#define BENCH_VAR(name) +#define BENCH_BEGIN(name) +#define BENCH_END(name) +#define BENCH_RESET(name) +#define BENCH_REPORT(name) + +#endif + + + typedef struct BVHNode { struct BVHNode *children[8]; // max 8 children @@ -61,7 +96,7 @@ struct BVHTree { BVHNode **nodes; BVHNode *nodearray; /* pre-alloc branch nodes */ - float epsilon; /* epslion is used for inflation of the k-dop */ + float epsilon; /* epsilon is used for inflation of the k-dop */ int totleaf; // leafs int totbranch; char tree_type; // type of tree (4 => quadtree) From 4bf01e8162dd3c30791a8a1d5d20fc80fbdef1ac Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Fri, 23 May 2008 20:20:14 +0000 Subject: [PATCH 093/246] Commit of selfcollisions using new kdop design. Should result in nice speedup. --- source/blender/blenkernel/BKE_cloth.h | 3 +- source/blender/blenkernel/intern/cloth.c | 103 ++++++++++++++++++- source/blender/blenkernel/intern/collision.c | 75 +++++++++++++- source/blender/blenlib/intern/BLI_kdopbvh.c | 87 ++++++++++------ 4 files changed, 234 insertions(+), 34 deletions(-) diff --git a/source/blender/blenkernel/BKE_cloth.h b/source/blender/blenkernel/BKE_cloth.h index f01ed6bbea4..6575b8b873b 100644 --- a/source/blender/blenkernel/BKE_cloth.h +++ b/source/blender/blenkernel/BKE_cloth.h @@ -106,7 +106,7 @@ typedef struct Cloth unsigned char pad2; short pad3; struct BVHTree *bvhtree; /* collision tree for this cloth object */ - struct RayTree *selftree; /* collision tree for this cloth object */ + struct BVHTree *bvhselftree; /* collision tree for this cloth object */ struct MFace *mfaces; struct Implicit_Data *implicit; /* our implicit solver connects to this pointer */ struct Implicit_Data *implicitEM; /* our implicit solver connects to this pointer */ @@ -245,6 +245,7 @@ void cloth_update_normals ( ClothVertex *verts, int nVerts, MFace *face, int tot // needed for collision.c void bvhtree_update_from_cloth ( ClothModifierData *clmd, int moving ); +void bvhselftree_update_from_cloth ( ClothModifierData *clmd, int moving ); // needed for editmesh.c void cloth_write_cache ( Object *ob, ClothModifierData *clmd, float framenr ); diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c index 6eb9f731056..916e3d6d3e8 100644 --- a/source/blender/blenkernel/intern/cloth.c +++ b/source/blender/blenkernel/intern/cloth.c @@ -189,6 +189,47 @@ void cloth_init ( ClothModifierData *clmd ) clmd->sim_parms->goalfrict = 0.0f; } +BVHTree *bvhselftree_build_from_cloth (ClothModifierData *clmd, float epsilon) +{ + int i; + BVHTree *bvhtree; + Cloth *cloth = clmd->clothObject; + ClothVertex *verts; + MFace *mfaces; + float co[12]; + + if(!clmd) + return NULL; + + cloth = clmd->clothObject; + + if(!cloth) + return NULL; + + verts = cloth->verts; + mfaces = cloth->mfaces; + + // in the moment, return zero if no faces there + if(!cloth->numfaces) + return NULL; + + // create quadtree with k=26 + bvhtree = BLI_bvhtree_new(cloth->numfaces, epsilon, 4, 6); + + // fill tree + for(i = 0; i < cloth->numverts; i++, verts++) + { + VECCOPY(&co[0*3], verts->xold); + + BLI_bvhtree_insert(bvhtree, i, co, 1); + } + + // balance tree + BLI_bvhtree_balance(bvhtree); + + return bvhtree; +} + BVHTree *bvhtree_build_from_cloth (ClothModifierData *clmd, float epsilon) { int i; @@ -214,7 +255,7 @@ BVHTree *bvhtree_build_from_cloth (ClothModifierData *clmd, float epsilon) return NULL; // create quadtree with k=26 - bvhtree = BLI_bvhtree_new(cloth->numfaces, epsilon, 8, 6); + bvhtree = BLI_bvhtree_new(cloth->numfaces, epsilon, 4, 26); // fill tree for(i = 0; i < cloth->numfaces; i++, mfaces++) @@ -289,6 +330,50 @@ void bvhtree_update_from_cloth(ClothModifierData *clmd, int moving) } } +void bvhselftree_update_from_cloth(ClothModifierData *clmd, int moving) +{ + unsigned int i = 0; + Cloth *cloth = clmd->clothObject; + BVHTree *bvhtree = cloth->bvhselftree; + ClothVertex *verts = cloth->verts; + MFace *mfaces; + float co[12], co_moving[12]; + int ret = 0; + + if(!bvhtree) + return; + + mfaces = cloth->mfaces; + + // update vertex position in bvh tree + if(verts && mfaces) + { + for(i = 0; i < cloth->numverts; i++, verts++) + { + VECCOPY(&co[0*3], verts->txold); + + // copy new locations into array + if(moving) + { + // update moving positions + VECCOPY(&co_moving[0*3], verts->tx); + + ret = BLI_bvhtree_update_node(bvhtree, i, co, co_moving, 1); + } + else + { + ret = BLI_bvhtree_update_node(bvhtree, i, co, NULL, 1); + } + + // check if tree is already full + if(!ret) + break; + } + + BLI_bvhtree_update_tree(bvhtree); + } +} + int modifiers_indexInObject(Object *ob, ModifierData *md_seek); int cloth_read_cache(Object *ob, ClothModifierData *clmd, float framenr) @@ -599,6 +684,9 @@ void cloth_free_modifier ( Object *ob, ClothModifierData *clmd ) // free BVH collision tree if ( cloth->bvhtree ) BLI_bvhtree_free ( cloth->bvhtree ); + + if ( cloth->bvhselftree ) + BLI_bvhtree_free ( cloth->bvhselftree ); // we save our faces for collision objects if ( cloth->mfaces ) @@ -669,6 +757,9 @@ void cloth_free_modifier_extern ( ClothModifierData *clmd ) // free BVH collision tree if ( cloth->bvhtree ) BLI_bvhtree_free ( cloth->bvhtree ); + + if ( cloth->bvhselftree ) + BLI_bvhtree_free ( cloth->bvhselftree ); // we save our faces for collision objects if ( cloth->mfaces ) @@ -807,6 +898,7 @@ static int cloth_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *d ClothVertex *verts = NULL; float tnull[3] = {0,0,0}; Cloth *cloth = NULL; + float maxdist = 0; // If we have a clothObject, free it. if ( clmd->clothObject != NULL ) @@ -876,7 +968,7 @@ static int cloth_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *d // apply / set vertex groups // has to be happen before springs are build! cloth_apply_vgroup (clmd, dm); - + if ( !cloth_build_springs ( clmd, dm ) ) { @@ -904,6 +996,13 @@ static int cloth_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *d BENCH(clmd->clothObject->bvhtree = bvhtree_build_from_cloth ( clmd, clmd->coll_parms->epsilon )); + for(i = 0; i < dm->getNumVerts(dm); i++) + { + maxdist = MAX2(maxdist, clmd->coll_parms->selfepsilon* ( cloth->verts[i].avg_spring_len*2.0)); + } + + clmd->clothObject->bvhselftree = bvhselftree_build_from_cloth ( clmd, maxdist ); + return 1; } diff --git a/source/blender/blenkernel/intern/collision.c b/source/blender/blenkernel/intern/collision.c index 1e8b8706658..4d49ccc9eb3 100644 --- a/source/blender/blenkernel/intern/collision.c +++ b/source/blender/blenkernel/intern/collision.c @@ -1260,7 +1260,7 @@ int cloth_bvh_objcollision ( ClothModifierData * clmd, float step, float dt ) Cloth *cloth=NULL; Object *coll_ob=NULL; BVHTree *cloth_bvh=NULL; - long i=0, j = 0, numfaces = 0, numverts = 0; + long i=0, j = 0, k = 0, numfaces = 0, numverts = 0; unsigned int result = 0, rounds = 0; // result counts applied collisions; ic is for debug output; ClothVertex *verts = NULL; int ret = 0; @@ -1284,6 +1284,7 @@ int cloth_bvh_objcollision ( ClothModifierData * clmd, float step, float dt ) // update cloth bvh bvhtree_update_from_cloth ( clmd, 1 ); // 0 means STATIC, 1 means MOVING (see later in this function) + bvhselftree_update_from_cloth ( clmd, 0 ); // 0 means STATIC, 1 means MOVING (see later in this function) do { @@ -1357,12 +1358,82 @@ int cloth_bvh_objcollision ( ClothModifierData * clmd, float step, float dt ) if ( clmd->coll_parms->flags & CLOTH_COLLSETTINGS_FLAG_SELF ) { - MFace *mface = clmd->clothObject->mfaces; + MFace *mface = cloth->mfaces; + BVHTreeOverlap *overlap = NULL; collisions = 1; verts = cloth->verts; // needed for openMP + numfaces = clmd->clothObject->numfaces; + numverts = clmd->clothObject->numverts; + verts = cloth->verts; + + if ( cloth->bvhselftree ) + { + /* search for overlapping collision pairs */ + overlap = BLI_bvhtree_overlap ( cloth->bvhselftree, cloth->bvhselftree, &result ); + + for ( k = 0; k < result; k++ ) + { + float temp[3]; + float length = 0; + float mindistance; + + i = overlap[k].indexA; + j = overlap[k].indexB; + + mindistance = clmd->coll_parms->selfepsilon* ( cloth->verts[i].avg_spring_len + cloth->verts[j].avg_spring_len ); + + if ( clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL ) + { + if ( ( cloth->verts [i].flags & CLOTH_VERT_FLAG_PINNED ) + && ( cloth->verts [j].flags & CLOTH_VERT_FLAG_PINNED ) ) + { + continue; + } + } + + VECSUB ( temp, verts[i].tx, verts[j].tx ); + + if ( ( ABS ( temp[0] ) > mindistance ) || ( ABS ( temp[1] ) > mindistance ) || ( ABS ( temp[2] ) > mindistance ) ) continue; + + // check for adjacent points (i must be smaller j) + if ( BLI_edgehash_haskey ( cloth->edgehash, MIN2(i, j), MAX2(i, j) ) ) + { + continue; + } + + length = Normalize ( temp ); + + if ( length < mindistance ) + { + float correction = mindistance - length; + + if ( cloth->verts [i].flags & CLOTH_VERT_FLAG_PINNED ) + { + VecMulf ( temp, -correction ); + VECADD ( verts[j].tx, verts[j].tx, temp ); + } + else if ( cloth->verts [j].flags & CLOTH_VERT_FLAG_PINNED ) + { + VecMulf ( temp, correction ); + VECADD ( verts[i].tx, verts[i].tx, temp ); + } + else + { + VecMulf ( temp, -correction*0.5 ); + VECADD ( verts[j].tx, verts[j].tx, temp ); + + VECSUB ( verts[i].tx, verts[i].tx, temp ); + } + } + } + + if ( overlap ) + MEM_freeN ( overlap ); + + } /* for ( count = 0; count < clmd->coll_parms->self_loop_count; count++ ) diff --git a/source/blender/blenlib/intern/BLI_kdopbvh.c b/source/blender/blenlib/intern/BLI_kdopbvh.c index b3f11039ce1..83afe258aad 100644 --- a/source/blender/blenlib/intern/BLI_kdopbvh.c +++ b/source/blender/blenlib/intern/BLI_kdopbvh.c @@ -80,12 +80,11 @@ #endif - typedef struct BVHNode { - struct BVHNode *children[8]; // max 8 children + struct BVHNode **children; // max 8 children struct BVHNode *parent; // needed for bottom - top update - float bv[26]; // Bounding volume of all nodes, max 13 axis + float *bv; // Bounding volume of all nodes, max 13 axis int index; /* face, edge, vertex index */ char totnode; // how many nodes are used, used for speedup char traversed; // how many nodes already traversed until this level? @@ -96,7 +95,9 @@ struct BVHTree { BVHNode **nodes; BVHNode *nodearray; /* pre-alloc branch nodes */ - float epsilon; /* epsilon is used for inflation of the k-dop */ + BVHNode **nodechild; // pre-alloc childs for nodes + float *nodebv; // pre-alloc bounding-volumes for nodes + float epsilon; /* epslion is used for inflation of the k-dop */ int totleaf; // leafs int totbranch; char tree_type; // type of tree (4 => quadtree) @@ -301,6 +302,8 @@ void BLI_bvhtree_free(BVHTree *tree) { MEM_freeN(tree->nodes); MEM_freeN(tree->nodearray); + MEM_freeN(tree->nodebv); + MEM_freeN(tree->nodechild); MEM_freeN(tree); } } @@ -318,27 +321,6 @@ BVHTree *BLI_bvhtree_new(int maxsize, float epsilon, char tree_type, char axis) if(tree) { - // calculate max number of branches, our bvh kdop is "almost perfect" - for(i = 1; i <= (int)ceil((float)((float)log(maxsize)/(float)log(tree_type))); i++) - numbranches += (pow(tree_type, i) / tree_type); - - tree->nodes = (BVHNode **)MEM_callocN(sizeof(BVHNode *)*(numbranches+maxsize + tree_type), "BVHNodes"); - - if(!tree->nodes) - { - MEM_freeN(tree); - return NULL; - } - - tree->nodearray = (BVHNode *)MEM_callocN(sizeof(BVHNode)*(numbranches+maxsize + tree_type), "BVHNodeArray"); - - if(!tree->nodearray) - { - MEM_freeN(tree); - MEM_freeN(tree->nodes); - return NULL; - } - tree->epsilon = epsilon; tree->tree_type = tree_type; tree->axis = axis; @@ -370,14 +352,62 @@ BVHTree *BLI_bvhtree_new(int maxsize, float epsilon, char tree_type, char axis) } else { - BLI_bvhtree_free(tree); + MEM_freeN(tree); return NULL; } + + + // calculate max number of branches, our bvh kdop is "almost perfect" + for(i = 1; i <= (int)ceil((float)((float)log(maxsize)/(float)log(tree_type))); i++) + numbranches += (pow(tree_type, i) / tree_type); + + tree->nodes = (BVHNode **)MEM_callocN(sizeof(BVHNode *)*(numbranches+maxsize + tree_type), "BVHNodes"); + + if(!tree->nodes) + { + MEM_freeN(tree); + return NULL; + } + + tree->nodebv = (float*)MEM_callocN(sizeof(float)* axis * (numbranches+maxsize + tree_type), "BVHNodeBV"); + if(!tree->nodebv) + { + MEM_freeN(tree->nodes); + MEM_freeN(tree); + } + + tree->nodechild = (BVHNode**)MEM_callocN(sizeof(BVHNode*) * tree_type * (numbranches+maxsize + tree_type), "BVHNodeBV"); + if(!tree->nodechild) + { + MEM_freeN(tree->nodebv); + MEM_freeN(tree->nodes); + MEM_freeN(tree); + } + + tree->nodearray = (BVHNode *)MEM_callocN(sizeof(BVHNode)*(numbranches+maxsize + tree_type), "BVHNodeArray"); + + if(!tree->nodearray) + { + MEM_freeN(tree->nodechild); + MEM_freeN(tree->nodebv); + MEM_freeN(tree->nodes); + MEM_freeN(tree); + return NULL; + } + + //link the dynamic bv and child links + for(i=0; i< numbranches+maxsize + tree_type; i++) + { + tree->nodearray[i].bv = tree->nodebv + i * axis; + tree->nodearray[i].children = tree->nodechild + i * tree_type; + } + } return tree; } + static void create_kdop_hull(BVHTree *tree, BVHNode *node, float *co, int numpoints, int moving) { float newminmax; @@ -507,8 +537,6 @@ static void bvh_div_nodes(BVHTree *tree, BVHNode *node, int start, int end, char { tend = start + slice; - partition_nth_element(tree->nodes, start, end, tend, laxis); - if(tend > end) tend = end; if(tend-start == 1) // ok, we have 1 left for this node @@ -521,7 +549,8 @@ static void bvh_div_nodes(BVHTree *tree, BVHNode *node, int start, int end, char tnode = node->children[i] = tree->nodes[tree->totleaf + tree->totbranch] = &(tree->nodearray[tree->totbranch + tree->totleaf]); tree->totbranch++; tnode->parent = node; - + + partition_nth_element(tree->nodes, start, end, tend, laxis); refit_kdop_hull(tree, tnode, start, tend); bvh_div_nodes(tree, tnode, start, tend, laxis); } From fcea4573dde1ba64dffed2301447154647924b6a Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Sun, 25 May 2008 13:15:54 +0000 Subject: [PATCH 094/246] =?UTF-8?q?-=3D=3D=20Cloth=20/=20kdop=20=3D=3D-=20?= =?UTF-8?q?1.=20Bugfix=20for=20crash=20on=20enabling=20cloth=20on=20object?= =?UTF-8?q?=202.=20Correcting=20kdop=20nth=20element=20sorting=20function?= =?UTF-8?q?=20(fix=20provided=20by=20Andr=C3=A9=20Pinto)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- source/blender/blenkernel/intern/cloth.c | 4 +-- source/blender/blenlib/intern/BLI_kdopbvh.c | 37 ++++++++++++--------- 2 files changed, 23 insertions(+), 18 deletions(-) diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c index 916e3d6d3e8..55d89e5f0dd 100644 --- a/source/blender/blenkernel/intern/cloth.c +++ b/source/blender/blenkernel/intern/cloth.c @@ -210,11 +210,11 @@ BVHTree *bvhselftree_build_from_cloth (ClothModifierData *clmd, float epsilon) mfaces = cloth->mfaces; // in the moment, return zero if no faces there - if(!cloth->numfaces) + if(!cloth->numverts) return NULL; // create quadtree with k=26 - bvhtree = BLI_bvhtree_new(cloth->numfaces, epsilon, 4, 6); + bvhtree = BLI_bvhtree_new(cloth->numverts, epsilon, 4, 6); // fill tree for(i = 0; i < cloth->numverts; i++, verts++) diff --git a/source/blender/blenlib/intern/BLI_kdopbvh.c b/source/blender/blenlib/intern/BLI_kdopbvh.c index 83afe258aad..5c3849d1210 100644 --- a/source/blender/blenlib/intern/BLI_kdopbvh.c +++ b/source/blender/blenlib/intern/BLI_kdopbvh.c @@ -276,21 +276,22 @@ void sort_along_axis(BVHTree *tree, int start, int end, int axis) } //after a call to this function you can expect one of: -// every node to left of a[n] are smaller than it -// every node to the right of a[n-1] are greater than it -void partition_nth_element(BVHNode **a, int _begin, int _end, int n, int axis) -{ - int begin = _begin, end = _end; - while(begin < n && end >= n) - { - int mid = bvh_partition(a, begin, end, bvh_medianof3(a, begin, (begin+end-1)/2, end-1, axis), axis ); - - if(mid >= n) - end = n-1; - else - begin = n+1; - } +// every node to left of a[n] are smaller or equal to it +// every node to the right of a[n] are greater or equal to it +int partition_nth_element(BVHNode **a, int _begin, int _end, int n, int axis){ + int begin = _begin, end = _end, cut; + int i; + while(end-begin > 3) + { + cut = bvh_partition(a, begin, end, bvh_medianof3(a, begin, (begin+end)/2, end-1, axis), axis ); + if(cut <= n) + begin = cut; + else + end = cut; + } + bvh_insertionsort(a, begin, end, axis); + return n; } @@ -550,7 +551,8 @@ static void bvh_div_nodes(BVHTree *tree, BVHNode *node, int start, int end, char tree->totbranch++; tnode->parent = node; - partition_nth_element(tree->nodes, start, end, tend, laxis); + if(tend != end) + partition_nth_element(tree->nodes, start, end, tend, laxis); refit_kdop_hull(tree, tnode, start, tend); bvh_div_nodes(tree, tnode, start, tend, laxis); } @@ -707,7 +709,7 @@ BVHTreeOverlap *BLI_bvhtree_overlap(BVHTree *tree1, BVHTree *tree2, int *result) { int j, total = 0; BVHTreeOverlap *overlap = NULL, *to = NULL; - BVHOverlapData *data[tree1->tree_type]; + BVHOverlapData **data; // check for compatibility of both trees (can't compare 14-DOP with 18-DOP) if((tree1->axis != tree2->axis) && ((tree1->axis == 14) || tree2->axis == 14)) @@ -716,6 +718,8 @@ BVHTreeOverlap *BLI_bvhtree_overlap(BVHTree *tree1, BVHTree *tree2, int *result) // fast check root nodes for collision before doing big splitting + traversal if(!tree_overlap(tree1->nodes[tree1->totleaf]->bv, tree2->nodes[tree2->totleaf]->bv, MIN2(tree1->start_axis, tree2->start_axis), MIN2(tree1->stop_axis, tree2->stop_axis))) return 0; + + *data = MEM_callocN(sizeof(BVHOverlapData *)* tree1->tree_type, "BVHOverlapData_star"); for(j = 0; j < tree1->tree_type; j++) { @@ -751,6 +755,7 @@ BVHTreeOverlap *BLI_bvhtree_overlap(BVHTree *tree1, BVHTree *tree2, int *result) free(data[j]->overlap); MEM_freeN(data[j]); } + MEM_freeN(*data); (*result) = total; return overlap; From 2666ff7075bfd9b5be349b55243697afbfc1967b Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Sun, 25 May 2008 14:34:03 +0000 Subject: [PATCH 095/246] -== kdop ==- 1. fix crash on collision --- source/blender/blenlib/intern/BLI_kdopbvh.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/blender/blenlib/intern/BLI_kdopbvh.c b/source/blender/blenlib/intern/BLI_kdopbvh.c index 5c3849d1210..cf326f3f460 100644 --- a/source/blender/blenlib/intern/BLI_kdopbvh.c +++ b/source/blender/blenlib/intern/BLI_kdopbvh.c @@ -719,7 +719,7 @@ BVHTreeOverlap *BLI_bvhtree_overlap(BVHTree *tree1, BVHTree *tree2, int *result) if(!tree_overlap(tree1->nodes[tree1->totleaf]->bv, tree2->nodes[tree2->totleaf]->bv, MIN2(tree1->start_axis, tree2->start_axis), MIN2(tree1->stop_axis, tree2->stop_axis))) return 0; - *data = MEM_callocN(sizeof(BVHOverlapData *)* tree1->tree_type, "BVHOverlapData_star"); + data = MEM_callocN(sizeof(BVHOverlapData *)* tree1->tree_type, "BVHOverlapData_star"); for(j = 0; j < tree1->tree_type; j++) { @@ -755,7 +755,7 @@ BVHTreeOverlap *BLI_bvhtree_overlap(BVHTree *tree1, BVHTree *tree2, int *result) free(data[j]->overlap); MEM_freeN(data[j]); } - MEM_freeN(*data); + MEM_freeN(data); (*result) = total; return overlap; From cb378cbceb22ca95b4e60e46208bd1922641f00b Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Mon, 26 May 2008 09:39:32 +0000 Subject: [PATCH 096/246] -= Cloth =- 1. Fix selfcollisions (reported by nudelZ) --- source/blender/blenkernel/intern/cloth.c | 11 +- source/blender/blenkernel/intern/collision.c | 697 +++++++++++-------- 2 files changed, 424 insertions(+), 284 deletions(-) diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c index 55d89e5f0dd..4fb8eeda78d 100644 --- a/source/blender/blenkernel/intern/cloth.c +++ b/source/blender/blenkernel/intern/cloth.c @@ -499,15 +499,15 @@ static int do_step_cloth(Object *ob, ClothModifierData *clmd, DerivedMesh *resul Mat4MulVecfl(ob->obmat, verts->xconst); } - tstart(); + // tstart(); /* call the solver. */ if(solvers [clmd->sim_parms->solver_type].solver) - ret = solvers[clmd->sim_parms->solver_type].solver(ob, framenr, clmd, effectors); + BENCH(ret = solvers[clmd->sim_parms->solver_type].solver(ob, framenr, clmd, effectors)); - tend(); + // tend(); - printf ( "Cloth simulation time: %f\n", ( float ) tval() ); + // printf ( "Cloth simulation time: %f\n", ( float ) tval() ); return ret; } @@ -969,7 +969,6 @@ static int cloth_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *d // has to be happen before springs are build! cloth_apply_vgroup (clmd, dm); - if ( !cloth_build_springs ( clmd, dm ) ) { cloth_free_modifier ( ob, clmd ); @@ -994,7 +993,7 @@ static int cloth_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *d if(!first) implicit_set_positions(clmd); - BENCH(clmd->clothObject->bvhtree = bvhtree_build_from_cloth ( clmd, clmd->coll_parms->epsilon )); + clmd->clothObject->bvhtree = bvhtree_build_from_cloth ( clmd, clmd->coll_parms->epsilon ); for(i = 0; i < dm->getNumVerts(dm); i++) { diff --git a/source/blender/blenkernel/intern/collision.c b/source/blender/blenkernel/intern/collision.c index 4d49ccc9eb3..edf8fec9ae1 100644 --- a/source/blender/blenkernel/intern/collision.c +++ b/source/blender/blenkernel/intern/collision.c @@ -178,16 +178,16 @@ Collision modifier code end ***********************************/ /** - * gsl_poly_solve_cubic - - * - * copied from SOLVE_CUBIC.C --> GSL - */ +* gsl_poly_solve_cubic - +* +* copied from SOLVE_CUBIC.C --> GSL +*/ #define mySWAP(a,b) do { double tmp = b ; b = a ; a = tmp ; } while(0) int - gsl_poly_solve_cubic (double a, double b, double c, - double *x0, double *x1, double *x2) +gsl_poly_solve_cubic (double a, double b, double c, + double *x0, double *x1, double *x2) { double q = (a * a - 3 * b); double r = (2 * a * a * a - 9 * a * b + 27 * c); @@ -210,10 +210,10 @@ int } else if (CR2 == CQ3) { - /* this test is actually R2 == Q3, written in a form suitable + /* this test is actually R2 == Q3, written in a form suitable for exact computation with integers */ - /* Due to finite precision some double roots may be missed, and + /* Due to finite precision some double roots may be missed, and considered to be a pair of complex roots z = x +/- epsilon i close to the real axis. */ @@ -242,20 +242,20 @@ int *x0 = norm * cos (theta / 3) - a / 3; *x1 = norm * cos ((theta + 2.0 * M_PI) / 3) - a / 3; *x2 = norm * cos ((theta - 2.0 * M_PI) / 3) - a / 3; - + /* Sort *x0, *x1, *x2 into increasing order */ if (*x0 > *x1) mySWAP(*x0, *x1) ; - + if (*x1 > *x2) { mySWAP(*x1, *x2) ; - + if (*x0 > *x1) mySWAP(*x0, *x1) ; } - + return 3; } else @@ -271,13 +271,13 @@ int /** - * gsl_poly_solve_quadratic - * - * copied from GSL - */ +* gsl_poly_solve_quadratic +* +* copied from GSL +*/ int - gsl_poly_solve_quadratic (double a, double b, double c, - double *x0, double *x1) +gsl_poly_solve_quadratic (double a, double b, double c, + double *x0, double *x1) { double disc = b * b - 4 * a * c; @@ -338,55 +338,55 @@ int /* - * See Bridson et al. "Robust Treatment of Collision, Contact and Friction for Cloth Animation" - * page 4, left column - */ +* See Bridson et al. "Robust Treatment of Collision, Contact and Friction for Cloth Animation" +* page 4, left column +*/ int cloth_get_collision_time ( double a[3], double b[3], double c[3], double d[3], double e[3], double f[3], double solution[3] ) { int num_sols = 0; // x^0 - checked double g = a[0] * c[1] * e[2] - a[0] * c[2] * e[1] + - a[1] * c[2] * e[0] - a[1] * c[0] * e[2] + - a[2] * c[0] * e[1] - a[2] * c[1] * e[0]; - + a[1] * c[2] * e[0] - a[1] * c[0] * e[2] + + a[2] * c[0] * e[1] - a[2] * c[1] * e[0]; + // x^1 double h = -b[2] * c[1] * e[0] + b[1] * c[2] * e[0] - a[2] * d[1] * e[0] + - a[1] * d[2] * e[0] + b[2] * c[0] * e[1] - b[0] * c[2] * e[1] + - a[2] * d[0] * e[1] - a[0] * d[2] * e[1] - b[1] * c[0] * e[2] + - b[0] * c[1] * e[2] - a[1] * d[0] * e[2] + a[0] * d[1] * e[2] - - a[2] * c[1] * f[0] + a[1] * c[2] * f[0] + a[2] * c[0] * f[1] - - a[0] * c[2] * f[1] - a[1] * c[0] * f[2] + a[0] * c[1] * f[2]; + a[1] * d[2] * e[0] + b[2] * c[0] * e[1] - b[0] * c[2] * e[1] + + a[2] * d[0] * e[1] - a[0] * d[2] * e[1] - b[1] * c[0] * e[2] + + b[0] * c[1] * e[2] - a[1] * d[0] * e[2] + a[0] * d[1] * e[2] - + a[2] * c[1] * f[0] + a[1] * c[2] * f[0] + a[2] * c[0] * f[1] - + a[0] * c[2] * f[1] - a[1] * c[0] * f[2] + a[0] * c[1] * f[2]; // x^2 double i = -b[2] * d[1] * e[0] + b[1] * d[2] * e[0] + - b[2] * d[0] * e[1] - b[0] * d[2] * e[1] - - b[1] * d[0] * e[2] + b[0] * d[1] * e[2] - - b[2] * c[1] * f[0] + b[1] * c[2] * f[0] - - a[2] * d[1] * f[0] + a[1] * d[2] * f[0] + - b[2] * c[0] * f[1] - b[0] * c[2] * f[1] + - a[2] * d[0] * f[1] - a[0] * d[2] * f[1] - - b[1] * c[0] * f[2] + b[0] * c[1] * f[2] - - a[1] * d[0] * f[2] + a[0] * d[1] * f[2]; - + b[2] * d[0] * e[1] - b[0] * d[2] * e[1] - + b[1] * d[0] * e[2] + b[0] * d[1] * e[2] - + b[2] * c[1] * f[0] + b[1] * c[2] * f[0] - + a[2] * d[1] * f[0] + a[1] * d[2] * f[0] + + b[2] * c[0] * f[1] - b[0] * c[2] * f[1] + + a[2] * d[0] * f[1] - a[0] * d[2] * f[1] - + b[1] * c[0] * f[2] + b[0] * c[1] * f[2] - + a[1] * d[0] * f[2] + a[0] * d[1] * f[2]; + // x^3 - checked double j = -b[2] * d[1] * f[0] + b[1] * d[2] * f[0] + - b[2] * d[0] * f[1] - b[0] * d[2] * f[1] - - b[1] * d[0] * f[2] + b[0] * d[1] * f[2]; - + b[2] * d[0] * f[1] - b[0] * d[2] * f[1] - + b[1] * d[0] * f[2] + b[0] * d[1] * f[2]; + /* printf("r1: %lf\n", a[0] * c[1] * e[2] - a[0] * c[2] * e[1]); printf("r2: %lf\n", a[1] * c[2] * e[0] - a[1] * c[0] * e[2]); printf("r3: %lf\n", a[2] * c[0] * e[1] - a[2] * c[1] * e[0]); - + printf("x1 x: %f, y: %f, z: %f\n", a[0], a[1], a[2]); printf("x2 x: %f, y: %f, z: %f\n", c[0], c[1], c[2]); printf("x3 x: %f, y: %f, z: %f\n", e[0], e[1], e[2]); - + printf("v1 x: %f, y: %f, z: %f\n", b[0], b[1], b[2]); printf("v2 x: %f, y: %f, z: %f\n", d[0], d[1], d[2]); printf("v3 x: %f, y: %f, z: %f\n", f[0], f[1], f[2]); - + printf("t^3: %lf, t^2: %lf, t^1: %lf, t^0: %lf\n", j, i, h, g); */ @@ -517,17 +517,17 @@ int cloth_collision_response_static ( ClothModifierData *clmd, CollisionModifier // compute barycentric coordinates for both collision points collision_compute_barycentric ( collpair->pa, - cloth1->verts[collpair->ap1].txold, - cloth1->verts[collpair->ap2].txold, - cloth1->verts[collpair->ap3].txold, - &w1, &w2, &w3 ); + cloth1->verts[collpair->ap1].txold, + cloth1->verts[collpair->ap2].txold, + cloth1->verts[collpair->ap3].txold, + &w1, &w2, &w3 ); // was: txold collision_compute_barycentric ( collpair->pb, - collmd->current_x[collpair->bp1].co, - collmd->current_x[collpair->bp2].co, - collmd->current_x[collpair->bp3].co, - &u1, &u2, &u3 ); + collmd->current_x[collpair->bp1].co, + collmd->current_x[collpair->bp2].co, + collmd->current_x[collpair->bp3].co, + &u1, &u2, &u3 ); // Calculate relative "velocity". collision_interpolateOnTriangle ( v1, cloth1->verts[collpair->ap1].tv, cloth1->verts[collpair->ap2].tv, cloth1->verts[collpair->ap3].tv, w1, w2, w3 ); @@ -696,7 +696,7 @@ CollPair* cloth_collision ( ModifierData *md1, ModifierData *md2, BVHTreeOverlap #ifdef WITH_BULLET // calc distance + normal distance = plNearestPoints ( - verts1[collpair->ap1].txold, verts1[collpair->ap2].txold, verts1[collpair->ap3].txold, collmd->current_x[collpair->bp1].co, collmd->current_x[collpair->bp2].co, collmd->current_x[collpair->bp3].co, collpair->pa,collpair->pb,collpair->vector ); + verts1[collpair->ap1].txold, verts1[collpair->ap2].txold, verts1[collpair->ap3].txold, collmd->current_x[collpair->bp1].co, collmd->current_x[collpair->bp2].co, collmd->current_x[collpair->bp3].co, collpair->pa,collpair->pb,collpair->vector ); #else // just be sure that we don't add anything distance = 2.0 * ( epsilon1 + epsilon2 + ALMOST_ZERO ); @@ -745,15 +745,15 @@ int cloth_are_edges_adjacent ( ClothModifierData *clmd, CollisionModifierData *c VECSUB ( temp, verts1[edgecollpair->p12].txold, verts2[edgecollpair->p22].co ); if ( ABS ( INPR ( temp, temp ) ) < ALMOST_ZERO ) return 1; - + VECSUB ( temp, verts1[edgecollpair->p11].txold, verts1[edgecollpair->p12].txold ); if ( ABS ( INPR ( temp, temp ) ) < ALMOST_ZERO ) return 1; - + VECSUB ( temp, verts2[edgecollpair->p21].co, verts2[edgecollpair->p22].co ); if ( ABS ( INPR ( temp, temp ) ) < ALMOST_ZERO ) return 1; - + return 0; } @@ -771,23 +771,19 @@ int cloth_collision_response_moving( ClothModifierData *clmd, CollisionModifierD for ( ; collpair != collision_end; collpair++ ) { - // only handle static collisions here - if ( collpair->flag & COLLISION_IN_FUTURE ) - continue; - // compute barycentric coordinates for both collision points collision_compute_barycentric ( collpair->pa, - cloth1->verts[collpair->ap1].txold, - cloth1->verts[collpair->ap2].txold, - cloth1->verts[collpair->ap3].txold, - &w1, &w2, &w3 ); + cloth1->verts[collpair->ap1].txold, + cloth1->verts[collpair->ap2].txold, + cloth1->verts[collpair->ap3].txold, + &w1, &w2, &w3 ); // was: txold collision_compute_barycentric ( collpair->pb, - collmd->current_x[collpair->bp1].co, - collmd->current_x[collpair->bp2].co, - collmd->current_x[collpair->bp3].co, - &u1, &u2, &u3 ); + collmd->current_x[collpair->bp1].co, + collmd->current_x[collpair->bp2].co, + collmd->current_x[collpair->bp3].co, + &u1, &u2, &u3 ); // Calculate relative "velocity". collision_interpolateOnTriangle ( v1, cloth1->verts[collpair->ap1].tv, cloth1->verts[collpair->ap2].tv, cloth1->verts[collpair->ap3].tv, w1, w2, w3 ); @@ -853,25 +849,250 @@ int cloth_collision_response_moving( ClothModifierData *clmd, CollisionModifierD d = clmd->coll_parms->epsilon*8.0/9.0 + epsilon2*8.0/9.0 - collpair->distance; if ( ( magrelVel < 0.1*d*clmd->sim_parms->stepsPerFrame ) && ( d > ALMOST_ZERO ) ) { - repulse = MIN2 ( d*1.0/clmd->sim_parms->stepsPerFrame, 0.1*d*clmd->sim_parms->stepsPerFrame - magrelVel ); + repulse = MIN2 ( d*1.0/clmd->sim_parms->stepsPerFrame, 0.1*d*clmd->sim_parms->stepsPerFrame - magrelVel ); - // stay on the safe side and clamp repulse - if ( impulse > ALMOST_ZERO ) - repulse = MIN2 ( repulse, 5.0*impulse ); - repulse = MAX2 ( impulse, repulse ); + // stay on the safe side and clamp repulse + if ( impulse > ALMOST_ZERO ) + repulse = MIN2 ( repulse, 5.0*impulse ); + repulse = MAX2 ( impulse, repulse ); - impulse = repulse / ( 1.0 + w1*w1 + w2*w2 + w3*w3 ); // original 2.0 / 0.25 - VECADDMUL ( cloth1->verts[collpair->ap1].impulse, collpair->normal, impulse ); - VECADDMUL ( cloth1->verts[collpair->ap2].impulse, collpair->normal, impulse ); - VECADDMUL ( cloth1->verts[collpair->ap3].impulse, collpair->normal, impulse ); + impulse = repulse / ( 1.0 + w1*w1 + w2*w2 + w3*w3 ); // original 2.0 / 0.25 + VECADDMUL ( cloth1->verts[collpair->ap1].impulse, collpair->normal, impulse ); + VECADDMUL ( cloth1->verts[collpair->ap2].impulse, collpair->normal, impulse ); + VECADDMUL ( cloth1->verts[collpair->ap3].impulse, collpair->normal, impulse ); } -*/ + */ result = 1; } } return result; } +static float projectPointOntoLine(float *p, float *a, float *b) +{ + float ba[3], pa[3]; + VECSUB(ba, b, a); + VECSUB(pa, p, a); + return INPR(pa, ba) / INPR(ba, ba); +} + +static void calculateEENormal(float *np1, float *np2, float *np3, float *np4,float *out_normal) +{ + float line1[33], line2[3]; + float length; + + VECSUB(line1, np2, np1); + VECSUB(line2, np3, np1); + + Crossf(out_normal, line1, line2); + length = Normalize(out_normal); + if (length <= FLT_EPSILON) + { // lines are collinear + VECSUB(out_normal, np2, np1); + Normalize(out_normal); + } +} + +static void findClosestPointsEE(float *x1, float *x2, float *x3, float *x4, float *w1, float *w2) +{ + float temp[3], temp2[3]; + + double a, b, c, e, f; + + VECSUB(temp, x2, x1); + a = INPR(temp, temp); + + VECSUB(temp2, x4, x3); + b = -INPR(temp, temp2); + + c = INPR(temp2, temp2); + + VECSUB(temp2, x3, x1); + e = INPR(temp, temp2); + + VECSUB(temp, x4, x3); + f = -INPR(temp, temp2); + + *w1 = (e * c - b * f) / (a * c - b * b); + *w2 = (f - b * *w1) / c; + +} + +// calculates the distance of 2 edges +float edgedge_distance(float np11[3], float np12[3], float np21[3], float np22[3], float *out_a1, float *out_a2, float *out_normal) +{ + float line1[3], line2[3], cross[3]; + float length; + float temp[3], temp2[3]; + float dist_a1, dist_a2; + + VECSUB(line1, np12, np11); + VECSUB(line2, np22, np21); + + Crossf(cross, line1, line2); + length = INPR(cross, cross); + + if (length < FLT_EPSILON) + { + *out_a2 = projectPointOntoLine(np11, np21, np22); + if ((*out_a2 >= -FLT_EPSILON) && (*out_a2 <= 1.0 + FLT_EPSILON)) + { + *out_a1 = 0; + calculateEENormal(np11, np12, np21, np22, out_normal); + VECSUB(temp, np22, np21); + VecMulf(temp, *out_a2); + VECADD(temp2, temp, np21); + VECADD(temp2, temp2, np11); + return INPR(temp2, temp2); + } + + CLAMP(*out_a2, 0.0, 1.0); + if (*out_a2 > .5) + { // == 1.0 + *out_a1 = projectPointOntoLine(np22, np11, np12); + if ((*out_a1 >= -FLT_EPSILON) && (*out_a1 <= 1.0 + FLT_EPSILON)) + { + calculateEENormal(np11, np12, np21, np22, out_normal); + + // return (np22 - (np11 + (np12 - np11) * out_a1)).lengthSquared(); + VECSUB(temp, np12, np11); + VecMulf(temp, *out_a1); + VECADD(temp2, temp, np11); + VECSUB(temp2, np22, temp2); + return INPR(temp2, temp2); + } + } + else + { // == 0.0 + *out_a1 = projectPointOntoLine(np21, np11, np12); + if ((*out_a1 >= -FLT_EPSILON) && (*out_a1 <= 1.0 + FLT_EPSILON)) + { + calculateEENormal(np11, np11, np21, np22, out_normal); + + // return (np21 - (np11 + (np12 - np11) * out_a1)).lengthSquared(); + VECSUB(temp, np12, np11); + VecMulf(temp, *out_a1); + VECADD(temp2, temp, np11); + VECSUB(temp2, np21, temp2); + return INPR(temp2, temp2); + } + } + + CLAMP(*out_a1, 0.0, 1.0); + calculateEENormal(np11, np12, np21, np22, out_normal); + if(*out_a1 > .5) + { + if(*out_a2 > .5) + { + VECSUB(temp, np12, np22); + } + else + { + VECSUB(temp, np12, np21); + } + } + else + { + if(*out_a2 > .5) + { + VECSUB(temp, np11, np22); + } + else + { + VECSUB(temp, np11, np21); + } + } + + return INPR(temp, temp); + } + else + { + + // If the lines aren't parallel (but coplanar) they have to intersect + + findClosestPointsEE(np11, np12, np21, np22, out_a1, out_a2); + + // If both points are on the finite edges, we're done. + if (*out_a1 >= 0.0 && *out_a1 <= 1.0 && *out_a2 >= 0.0 && *out_a2 <= 1.0) + { + float p1[3], p2[3]; + + // p1= np11 + (np12 - np11) * out_a1; + VECSUB(temp, np12, np11); + VecMulf(temp, *out_a1); + VECADD(p1, np11, temp); + + // p2 = np21 + (np22 - np21) * out_a2; + VECSUB(temp, np22, np21); + VecMulf(temp, *out_a2); + VECADD(p2, np21, temp); + + calculateEENormal(np11, np12, np21, np22, out_normal); + VECSUB(temp, p1, p2); + return INPR(temp, temp); + } + + + /* + * Clamp both points to the finite edges. + * The one that moves most during clamping is one part of the solution. + */ + dist_a1 = *out_a1; + CLAMP(dist_a1, 0.0, 1.0); + dist_a2 = *out_a2; + CLAMP(dist_a2, 0.0, 1.0); + + // Now project the "most clamped" point on the other line. + if (dist_a1 > dist_a2) + { + /* keep out_a1 */ + float p1[3]; + + // p1 = np11 + (np12 - np11) * out_a1; + VECSUB(temp, np12, np11); + VecMulf(temp, *out_a1); + VECADD(p1, np11, temp); + + *out_a2 = projectPointOntoLine(p1, np21, np22); + CLAMP(*out_a2, 0.0, 1.0); + + calculateEENormal(np11, np12, np21, np22, out_normal); + + // return (p1 - (np21 + (np22 - np21) * out_a2)).lengthSquared(); + VECSUB(temp, np22, np21); + VecMulf(temp, *out_a2); + VECADD(temp, temp, np21); + VECSUB(temp, p1, temp); + return INPR(temp, temp); + } + else + { + /* keep out_a2 */ + float p2[3]; + + // p2 = np21 + (np22 - np21) * out_a2; + VECSUB(temp, np22, np21); + VecMulf(temp, *out_a2); + VECADD(p2, np21, temp); + + *out_a1 = projectPointOntoLine(p2, np11, np12); + CLAMP(*out_a1, 0.0, 1.0); + + calculateEENormal(np11, np12, np21, np22, out_normal); + + // return ((np11 + (np12 - np11) * out_a1) - p2).lengthSquared(); + VECSUB(temp, np12, np11); + VecMulf(temp, *out_a1); + VECADD(temp, temp, np11); + VECSUB(temp, temp, p2); + return INPR(temp, temp); + } + } + + printf("Error in edgedge_distance: end of function\n"); + return 0; +} + int cloth_collision_moving_edges ( ClothModifierData *clmd, CollisionModifierData *collmd, CollPair *collpair ) { EdgeCollPair edgecollpair; @@ -890,16 +1111,16 @@ int cloth_collision_moving_edges ( ClothModifierData *clmd, CollisionModifierDat cloth1 = clmd->clothObject; verts1 = cloth1->verts; - + for(i = 0; i < 9; i++) { // 9 edge - edge possibilities - + if(i == 0) // cloth edge: 1-2; coll edge: 1-2 { edgecollpair.p11 = collpair->ap1; edgecollpair.p12 = collpair->ap2; - + edgecollpair.p21 = collpair->bp1; edgecollpair.p22 = collpair->bp2; } @@ -907,7 +1128,7 @@ int cloth_collision_moving_edges ( ClothModifierData *clmd, CollisionModifierDat { edgecollpair.p11 = collpair->ap1; edgecollpair.p12 = collpair->ap2; - + edgecollpair.p21 = collpair->bp2; edgecollpair.p22 = collpair->bp3; } @@ -915,7 +1136,7 @@ int cloth_collision_moving_edges ( ClothModifierData *clmd, CollisionModifierDat { edgecollpair.p11 = collpair->ap1; edgecollpair.p12 = collpair->ap2; - + edgecollpair.p21 = collpair->bp1; edgecollpair.p22 = collpair->bp3; } @@ -923,7 +1144,7 @@ int cloth_collision_moving_edges ( ClothModifierData *clmd, CollisionModifierDat { edgecollpair.p11 = collpair->ap2; edgecollpair.p12 = collpair->ap3; - + edgecollpair.p21 = collpair->bp1; edgecollpair.p22 = collpair->bp2; } @@ -931,7 +1152,7 @@ int cloth_collision_moving_edges ( ClothModifierData *clmd, CollisionModifierDat { edgecollpair.p11 = collpair->ap2; edgecollpair.p12 = collpair->ap3; - + edgecollpair.p21 = collpair->bp2; edgecollpair.p22 = collpair->bp3; } @@ -939,7 +1160,7 @@ int cloth_collision_moving_edges ( ClothModifierData *clmd, CollisionModifierDat { edgecollpair.p11 = collpair->ap2; edgecollpair.p12 = collpair->ap3; - + edgecollpair.p21 = collpair->bp1; edgecollpair.p22 = collpair->bp3; } @@ -947,7 +1168,7 @@ int cloth_collision_moving_edges ( ClothModifierData *clmd, CollisionModifierDat { edgecollpair.p11 = collpair->ap1; edgecollpair.p12 = collpair->ap3; - + edgecollpair.p21 = collpair->bp1; edgecollpair.p22 = collpair->bp2; } @@ -955,7 +1176,7 @@ int cloth_collision_moving_edges ( ClothModifierData *clmd, CollisionModifierDat { edgecollpair.p11 = collpair->ap1; edgecollpair.p12 = collpair->ap3; - + edgecollpair.p21 = collpair->bp2; edgecollpair.p22 = collpair->bp3; } @@ -963,171 +1184,144 @@ int cloth_collision_moving_edges ( ClothModifierData *clmd, CollisionModifierDat { edgecollpair.p11 = collpair->ap1; edgecollpair.p12 = collpair->ap3; - + edgecollpair.p21 = collpair->bp1; edgecollpair.p22 = collpair->bp3; } - + if ( !cloth_are_edges_adjacent ( clmd, collmd, &edgecollpair ) ) { // always put coll points in p21/p22 VECSUB ( x1, verts1[edgecollpair.p12].txold, verts1[edgecollpair.p11].txold ); VECSUB ( v1, verts1[edgecollpair.p12].tv, verts1[edgecollpair.p11].tv ); - + VECSUB ( x2, verts2[edgecollpair.p21].co, verts1[edgecollpair.p11].txold ); VECSUB ( v2, velocity2[edgecollpair.p21].co, verts1[edgecollpair.p11].tv ); - + VECSUB ( x3, verts2[edgecollpair.p22].co, verts1[edgecollpair.p11].txold ); VECSUB ( v3, velocity2[edgecollpair.p22].co, verts1[edgecollpair.p11].tv ); - + numsolutions = cloth_get_collision_time ( x1, v1, x2, v2, x3, v3, solution ); - + for ( k = 0; k < numsolutions; k++ ) { // printf("sol %d: %lf\n", k, solution[k]); if ( ( solution[k] >= DBL_EPSILON ) && ( solution[k] <= 1.0 ) ) { - //float out_collisionTime = solution[k]; - + float a,b; + float out_normal[3]; + float distance; + + // move verts + VECADDS(triA[0], verts1[edgecollpair.p11].txold, verts1[edgecollpair.p11].tv, mintime); + VECADDS(triA[1], verts1[edgecollpair.p12].txold, verts1[edgecollpair.p12].tv, mintime); + + VECADDS(triB[0], collmd->current_x[edgecollpair.p21].co, collmd->current_v[edgecollpair.p21].co, mintime); + VECADDS(triB[1], collmd->current_x[edgecollpair.p22].co, collmd->current_v[edgecollpair.p22].co, mintime); + // TODO: check for collisions - - // TODO: put into (edge) collision list + distance = edgedge_distance(triA[0], triA[1], triB[0], triB[1], &a, &b, out_normal); + if ((distance <= clmd->coll_parms->epsilon + BLI_bvhtree_getepsilon ( collmd->bvhtree ) + ALMOST_ZERO) && (INPR(out_normal, out_normal) > 0)) + { + // printf("found edge, dist: %f\n", distance); + + /* Inelastic repulsion impulse. */ +/* + // Calculate which normal velocity we need. + float desiredVn = (normalVelocity * (float)solution[k] - (.1 * (clmd->coll_parms->epsilon + BLI_bvhtree_getepsilon ( collmd->bvhtree )) - sqrt(squaredDistance)) - ALMOST_ZERO); + + // Now calculate what impulse we need to reach that velocity. + float m1 = interpolateOnEdge(cloth1.getVertexWeight(v11idx), cloth1.getVertexWeight(v12idx), a1); + float m2 = interpolateOnEdge(cloth2.getVertexWeight(v21idx), cloth2.getVertexWeight(v22idx), a2); + float I_mag = (normalVelocity - desiredVn) / (1/m1 + 1/m2); + + // Finally apply that impulse. + applyInterpolatedImpulsesEdge(out_impulses1[v11idx], out_impulses1[v12idx], out_impulses2[v21idx], out_impulses2[v22idx], + a1, a2, -I_mag, normal); + ++out_impulseCounter1[v11idx]; ++out_impulseCounter1[v12idx]; + ++out_impulseCounter2[v21idx]; ++out_impulseCounter2[v22idx]; + + */ // return true; + result = 1; + } + mintime = MIN2(mintime, (float)solution[k]); - - result = 1; + break; } } } } - +/* if(result) { // move triangles to collision point in time VECADDS(triA[0], verts1[collpair->ap1].txold, verts1[collpair->ap1].tv, mintime); VECADDS(triA[1], verts1[collpair->ap2].txold, verts1[collpair->ap2].tv, mintime); VECADDS(triA[2], verts1[collpair->ap3].txold, verts1[collpair->ap3].tv, mintime); - + VECADDS(triB[0], collmd->current_x[collpair->bp1].co, collmd->current_v[collpair->bp1].co, mintime); VECADDS(triB[1], collmd->current_x[collpair->bp2].co, collmd->current_v[collpair->bp2].co, mintime); VECADDS(triB[2], collmd->current_x[collpair->bp3].co, collmd->current_v[collpair->bp3].co, mintime); - + // check distance there distance = plNearestPoints (triA[0], triA[1], triA[2], triB[0], triB[1], triB[2], collpair->pa,collpair->pb,collpair->vector ); - + if(distance <= (clmd->coll_parms->epsilon + BLI_bvhtree_getepsilon ( collmd->bvhtree ) + ALMOST_ZERO)) { CollPair *next = collpair; next++; - + collpair->distance = clmd->coll_parms->epsilon; collpair->time = mintime; - + VECCOPY ( collpair->normal, collpair->vector ); Normalize ( collpair->normal ); - - cloth_collision_response_moving ( clmd, collmd, collpair, next ); + + // cloth_collision_response_moving ( clmd, collmd, collpair, next ); + } } - +*/ return result; } -/* -void cloth_collision_moving_tris ( ClothModifierData *clmd, ClothModifierData *coll_clmd, CollisionTree *tree1, CollisionTree *tree2 ) +int cloth_collision_moving_tris ( ClothModifierData *clmd, CollisionModifierData *collmd, CollPair *collpair ) { - CollPair collpair; - Cloth *cloth1=NULL, *cloth2=NULL; - MFace *face1=NULL, *face2=NULL; - ClothVertex *verts1=NULL, *verts2=NULL; + EdgeCollPair edgecollpair; + Cloth *cloth1=NULL; + ClothVertex *verts1=NULL; unsigned int i = 0, j = 0, k = 0; int numsolutions = 0; - float a[3], b[3], c[3], d[3], e[3], f[3]; + double x1[3], v1[3], x2[3], v2[3], x3[3], v3[3]; double solution[3]; + MVert *verts2 = collmd->current_x; // old x + MVert *velocity2 = collmd->current_v; // velocity + float mintime = FLT_MAX; + float distance; + float triA[3][3], triB[3][3]; + int result = 0; - for ( i = 0; i < 2; i++ ) + cloth1 = clmd->clothObject; + verts1 = cloth1->verts; + + for(i = 0; i < 9; i++) { - cloth1 = clmd->clothObject; - cloth2 = coll_clmd->clothObject; + // 9 edge - edge possibilities - verts1 = cloth1->verts; - verts2 = cloth2->verts; - - face1 = & ( cloth1->mfaces[tree1->tri_index] ); - face2 = & ( cloth2->mfaces[tree2->tri_index] ); - - // check all possible pairs of triangles - if ( i == 0 ) + if(i == 0) { - collpair.ap1 = face1->v1; - collpair.ap2 = face1->v2; - collpair.ap3 = face1->v3; - - collpair.pointsb[0] = face2->v1; - collpair.pointsb[1] = face2->v2; - collpair.pointsb[2] = face2->v3; - collpair.pointsb[3] = face2->v4; - } - - if ( i == 1 ) - { - if ( face1->v4 ) - { - collpair.ap1 = face1->v3; - collpair.ap2 = face1->v4; - collpair.ap3 = face1->v1; - - collpair.pointsb[0] = face2->v1; - collpair.pointsb[1] = face2->v2; - collpair.pointsb[2] = face2->v3; - collpair.pointsb[3] = face2->v4; - } - else - i++; - } - - // calc SIPcode (?) - - if ( i < 2 ) - { - VECSUB ( a, verts1[collpair.ap2].xold, verts1[collpair.ap1].xold ); - VECSUB ( b, verts1[collpair.ap2].v, verts1[collpair.ap1].v ); - VECSUB ( c, verts1[collpair.ap3].xold, verts1[collpair.ap1].xold ); - VECSUB ( d, verts1[collpair.ap3].v, verts1[collpair.ap1].v ); - - for ( j = 0; j < 4; j++ ) - { - if ( ( j==3 ) && ! ( face2->v4 ) ) - break; - - VECSUB ( e, verts2[collpair.pointsb[j]].xold, verts1[collpair.ap1].xold ); - VECSUB ( f, verts2[collpair.pointsb[j]].v, verts1[collpair.ap1].v ); - - numsolutions = cloth_get_collision_time ( a, b, c, d, e, f, solution ); - - for ( k = 0; k < numsolutions; k++ ) - { - if ( ( solution[k] >= ALMOST_ZERO ) && ( solution[k] <= 1.0 ) ) - { - //float out_collisionTime = solution[k]; - - // TODO: check for collisions - - // TODO: put into (point-face) collision list - - // printf("Moving found!\n"); - - } - } - - // TODO: check borders for collisions - } + edgecollpair.p11 = collpair->ap1; + edgecollpair.p12 = collpair->ap2; + edgecollpair.p21 = collpair->bp1; + edgecollpair.p22 = collpair->bp2; } } + + return result; } -*/ int cloth_collision_moving ( ClothModifierData *clmd, CollisionModifierData *collmd, CollPair *collpair, CollPair *collision_end ) { @@ -1145,10 +1339,11 @@ int cloth_collision_moving ( ClothModifierData *clmd, CollisionModifierData *col // only handle moving collisions here if (!( collpair->flag & COLLISION_IN_FUTURE )) continue; - + cloth_collision_moving_edges ( clmd, collmd, collpair); + // cloth_collision_moving_tris ( clmd, collmd, collpair); } - + return 1; } @@ -1219,14 +1414,14 @@ int cloth_bvh_objcollisions_do ( ClothModifierData * clmd, CollisionModifierData VECADDMUL ( verts[i].tv, verts[i].impulse, 1.0f / verts[i].impulse_count ); VECCOPY ( verts[i].impulse, tnull ); verts[i].impulse_count = 0; - + ret++; } } } - /* +/* result += cloth_collision_moving ( clmd, collmd, collisions, collisions_index ); - + // apply impulses in parallel if ( result ) { @@ -1238,12 +1433,12 @@ int cloth_bvh_objcollisions_do ( ClothModifierData * clmd, CollisionModifierData VECADDMUL ( verts[i].tv, verts[i].impulse, 1.0f / verts[i].impulse_count ); VECCOPY ( verts[i].impulse, tnull ); verts[i].impulse_count = 0; - + ret++; } } } - */ +*/ } } @@ -1371,24 +1566,25 @@ int cloth_bvh_objcollision ( ClothModifierData * clmd, float step, float dt ) if ( cloth->bvhselftree ) { - /* search for overlapping collision pairs */ + // search for overlapping collision pairs overlap = BLI_bvhtree_overlap ( cloth->bvhselftree, cloth->bvhselftree, &result ); +// #pragma omp parallel for private(k, i, j) schedule(static) for ( k = 0; k < result; k++ ) { float temp[3]; float length = 0; float mindistance; - + i = overlap[k].indexA; j = overlap[k].indexB; - + mindistance = clmd->coll_parms->selfepsilon* ( cloth->verts[i].avg_spring_len + cloth->verts[j].avg_spring_len ); if ( clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL ) { if ( ( cloth->verts [i].flags & CLOTH_VERT_FLAG_PINNED ) - && ( cloth->verts [j].flags & CLOTH_VERT_FLAG_PINNED ) ) + && ( cloth->verts [j].flags & CLOTH_VERT_FLAG_PINNED ) ) { continue; } @@ -1427,87 +1623,18 @@ int cloth_bvh_objcollision ( ClothModifierData * clmd, float step, float dt ) VECSUB ( verts[i].tx, verts[i].tx, temp ); } + ret = 1; + } + else + { + // check for approximated time collisions } } - + if ( overlap ) MEM_freeN ( overlap ); - - } - /* - for ( count = 0; count < clmd->coll_parms->self_loop_count; count++ ) - { - if ( collisions ) - { - collisions = 0; - #pragma omp parallel for private(i,j, collisions) shared(verts, ret) - for ( i = 0; i < cloth->numverts; i++ ) - { - for ( j = i + 1; j < cloth->numverts; j++ ) - { - float temp[3]; - float length = 0; - float mindistance = clmd->coll_parms->selfepsilon* ( cloth->verts[i].avg_spring_len + cloth->verts[j].avg_spring_len ); - - if ( clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL ) - { - if ( ( cloth->verts [i].flags & CLOTH_VERT_FLAG_PINNED ) - && ( cloth->verts [j].flags & CLOTH_VERT_FLAG_PINNED ) ) - { - continue; } - } - - VECSUB ( temp, verts[i].tx, verts[j].tx ); - - if ( ( ABS ( temp[0] ) > mindistance ) || ( ABS ( temp[1] ) > mindistance ) || ( ABS ( temp[2] ) > mindistance ) ) continue; - - // check for adjacent points (i must be smaller j) - if ( BLI_edgehash_haskey ( cloth->edgehash, i, j ) ) - { - continue; - } - - length = Normalize ( temp ); - - if ( length < mindistance ) - { - float correction = mindistance - length; - - if ( cloth->verts [i].flags & CLOTH_VERT_FLAG_PINNED ) - { - VecMulf ( temp, -correction ); - VECADD ( verts[j].tx, verts[j].tx, temp ); - } - else if ( cloth->verts [j].flags & CLOTH_VERT_FLAG_PINNED ) - { - VecMulf ( temp, correction ); - VECADD ( verts[i].tx, verts[i].tx, temp ); - } - else - { - VecMulf ( temp, -correction*0.5 ); - VECADD ( verts[j].tx, verts[j].tx, temp ); - - VECSUB ( verts[i].tx, verts[i].tx, temp ); - } - - collisions = 1; - - if ( !ret ) - { - #pragma omp critical - { - ret = 1; - } - } - } - } - } - } - } - */ //////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////// @@ -1517,8 +1644,10 @@ int cloth_bvh_objcollision ( ClothModifierData * clmd, float step, float dt ) { for ( i = 0; i < cloth->numverts; i++ ) { - if ( ! ( cloth->verts [i].flags & CLOTH_VERT_FLAG_PINNED ) ) + if ( ! ( verts [i].flags & CLOTH_VERT_FLAG_PINNED ) ) + { VECSUB ( verts[i].tv, verts[i].tx, verts[i].txold ); + } } } //////////////////////////////////////////////////////////// @@ -1528,3 +1657,15 @@ int cloth_bvh_objcollision ( ClothModifierData * clmd, float step, float dt ) return MIN2 ( ret, 1 ); } + + +/* +if ( verts[i].impulse_count ) +{ + VECADDMUL ( verts[i].tv, verts[i].impulse, 1.0f / verts[i].impulse_count ); + VECCOPY ( verts[i].impulse, tnull ); + verts[i].impulse_count = 0; + + ret++; +} +*/ \ No newline at end of file From 391c7615d19561555ab29c090fcfd56447942548 Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Mon, 26 May 2008 10:36:14 +0000 Subject: [PATCH 097/246] -= Collisions =- 1. fix for collisions (were working better with selfcolls enabled, now generally better) --- source/blender/blenkernel/intern/collision.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/source/blender/blenkernel/intern/collision.c b/source/blender/blenkernel/intern/collision.c index edf8fec9ae1..0b291aaa695 100644 --- a/source/blender/blenkernel/intern/collision.c +++ b/source/blender/blenkernel/intern/collision.c @@ -1458,7 +1458,7 @@ int cloth_bvh_objcollision ( ClothModifierData * clmd, float step, float dt ) long i=0, j = 0, k = 0, numfaces = 0, numverts = 0; unsigned int result = 0, rounds = 0; // result counts applied collisions; ic is for debug output; ClothVertex *verts = NULL; - int ret = 0; + int ret = 0, ret2 = 0; ClothModifierData *tclmd; int collisions = 0, count = 0; @@ -1484,6 +1484,7 @@ int cloth_bvh_objcollision ( ClothModifierData * clmd, float step, float dt ) do { result = 0; + ret2 = 0; // check all collision objects for ( base = G.scene->base.first; base; base = base->next ) @@ -1512,6 +1513,7 @@ int cloth_bvh_objcollision ( ClothModifierData * clmd, float step, float dt ) continue; ret += cloth_bvh_objcollisions_do ( clmd, collmd, step, dt ); + ret2 += ret; } } } @@ -1522,6 +1524,7 @@ int cloth_bvh_objcollision ( ClothModifierData * clmd, float step, float dt ) continue; ret += cloth_bvh_objcollisions_do ( clmd, collmd, step, dt ); + ret2 += ret; } } rounds++; @@ -1624,6 +1627,7 @@ int cloth_bvh_objcollision ( ClothModifierData * clmd, float step, float dt ) VECSUB ( verts[i].tx, verts[i].tx, temp ); } ret = 1; + ret2 += ret; } else { @@ -1640,7 +1644,7 @@ int cloth_bvh_objcollision ( ClothModifierData * clmd, float step, float dt ) //////////////////////////////////////////////////////////// // SELFCOLLISIONS: update velocities //////////////////////////////////////////////////////////// - if ( ret ) + if ( ret2 ) { for ( i = 0; i < cloth->numverts; i++ ) { @@ -1653,7 +1657,7 @@ int cloth_bvh_objcollision ( ClothModifierData * clmd, float step, float dt ) //////////////////////////////////////////////////////////// } } - while ( result && ( clmd->coll_parms->loop_count>rounds ) ); + while ( ret2 && ( clmd->coll_parms->loop_count>rounds ) ); return MIN2 ( ret, 1 ); } From c25b845abe39f82a35e1cdd83fa2f4533768769f Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Tue, 27 May 2008 13:26:52 +0000 Subject: [PATCH 098/246] Fix for bug #12463: hair didn't draw z-buffered in wireframe mode. Instead of making it an exception compared to other objects which don't draw z-buffered either, it now draws without lighting in the wire color like it did before. --- source/blender/src/drawobject.c | 124 +++++++++++++++++++++----------- 1 file changed, 84 insertions(+), 40 deletions(-) diff --git a/source/blender/src/drawobject.c b/source/blender/src/drawobject.c index 045b98bb784..3ef14574bc8 100644 --- a/source/blender/src/drawobject.c +++ b/source/blender/src/drawobject.c @@ -2885,7 +2885,7 @@ static int drawDispList(Base *base, int dt) /* 5. start filling the arrays */ /* 6. draw the arrays */ /* 7. clean up */ -static void draw_new_particle_system(Base *base, ParticleSystem *psys) +static void draw_new_particle_system(Base *base, ParticleSystem *psys, int dt) { View3D *v3d= G.vd; Object *ob=base->object; @@ -3334,14 +3334,24 @@ static void draw_new_particle_system(Base *base, ParticleSystem *psys) float *cd2=0,*cdata2=0; glEnableClientState(GL_VERTEX_ARRAY); - glEnableClientState(GL_NORMAL_ARRAY); - glEnable(GL_LIGHTING); - glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE); - glEnable(GL_COLOR_MATERIAL); + if(dt > OB_WIRE) { + glEnableClientState(GL_NORMAL_ARRAY); - if(part->draw&PART_DRAW_MAT_COL) - glEnableClientState(GL_COLOR_ARRAY); + if(part->draw&PART_DRAW_MAT_COL) + glEnableClientState(GL_COLOR_ARRAY); + + glEnable(GL_LIGHTING); + glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE); + glEnable(GL_COLOR_MATERIAL); + } + else { + glDisableClientState(GL_NORMAL_ARRAY); + + glDisable(GL_COLOR_MATERIAL); + glDisable(GL_LIGHTING); + BIF_ThemeColor(TH_WIRE); + } if(totchild && (part->draw&PART_DRAW_PARENT)==0) totpart=0; @@ -3350,9 +3360,13 @@ static void draw_new_particle_system(Base *base, ParticleSystem *psys) for(a=0, pa=psys->particles; aco); - glNormalPointer(GL_FLOAT, sizeof(ParticleCacheKey), path->vel); - if(part->draw&PART_DRAW_MAT_COL) - glColorPointer(3, GL_FLOAT, sizeof(ParticleCacheKey), path->col); + + if(dt > OB_WIRE) { + glNormalPointer(GL_FLOAT, sizeof(ParticleCacheKey), path->vel); + if(part->draw&PART_DRAW_MAT_COL) + glColorPointer(3, GL_FLOAT, sizeof(ParticleCacheKey), path->col); + } + glDrawArrays(GL_LINE_STRIP, 0, path->steps + 1); } @@ -3360,15 +3374,21 @@ static void draw_new_particle_system(Base *base, ParticleSystem *psys) for(a=0; aco); - glNormalPointer(GL_FLOAT, sizeof(ParticleCacheKey), path->vel); - if(part->draw&PART_DRAW_MAT_COL) - glColorPointer(3, GL_FLOAT, sizeof(ParticleCacheKey), path->col); + + if(dt > OB_WIRE) { + glNormalPointer(GL_FLOAT, sizeof(ParticleCacheKey), path->vel); + if(part->draw&PART_DRAW_MAT_COL) + glColorPointer(3, GL_FLOAT, sizeof(ParticleCacheKey), path->col); + } + glDrawArrays(GL_LINE_STRIP, 0, path->steps + 1); } - if(part->draw&PART_DRAW_MAT_COL) - glDisable(GL_COLOR_ARRAY); - glDisable(GL_COLOR_MATERIAL); + if(dt > OB_WIRE) { + if(part->draw&PART_DRAW_MAT_COL) + glDisable(GL_COLOR_ARRAY); + glDisable(GL_COLOR_MATERIAL); + } if(cdata2) MEM_freeN(cdata2); @@ -3389,7 +3409,7 @@ static void draw_new_particle_system(Base *base, ParticleSystem *psys) else glDisableClientState(GL_VERTEX_ARRAY); - if(ndata && MIN2(G.vd->drawtype, ob->dt)>OB_WIRE){ + if(ndata && dt>OB_WIRE){ glEnableClientState(GL_NORMAL_ARRAY); glNormalPointer(GL_FLOAT, 0, ndata); glEnable(GL_LIGHTING); @@ -3412,7 +3432,7 @@ static void draw_new_particle_system(Base *base, ParticleSystem *psys) glDrawArrays(GL_LINES, 0, 2*totpoint); break; case PART_DRAW_BB: - if(MIN2(G.vd->drawtype, ob->dt)<=OB_WIRE) + if(dt<=OB_WIRE) glPolygonMode(GL_FRONT_AND_BACK,GL_LINE); glDrawArrays(GL_QUADS, 0, 4*totpoint); @@ -3466,7 +3486,7 @@ static void draw_new_particle_system(Base *base, ParticleSystem *psys) mymultmatrix(ob->obmat); // bring back local matrix for dtx } -static void draw_particle_edit(Object *ob, ParticleSystem *psys) +static void draw_particle_edit(Object *ob, ParticleSystem *psys, int dt) { ParticleEdit *edit = psys->edit; ParticleData *pa; @@ -3479,6 +3499,7 @@ static void draw_particle_edit(Object *ob, ParticleSystem *psys) float nosel_col[3]; char val[32]; + /* create path and child path cache if it doesn't exist already */ if(psys->pathcache==0){ PE_hide_keys_time(psys,CFRA); psys_cache_paths(ob,psys,CFRA,0); @@ -3493,11 +3514,13 @@ static void draw_particle_edit(Object *ob, ParticleSystem *psys) else if(!(pset->flag & PE_SHOW_CHILD) && psys->childcache) free_child_path_cache(psys); + /* opengl setup */ if((G.vd->flag & V3D_ZBUF_SELECT)==0) glDisable(GL_DEPTH_TEST); myloadmatrix(G.vd->viewmat); + /* get selection theme colors */ BIF_GetThemeColor3ubv(TH_VERTEX_SELECT, sel); BIF_GetThemeColor3ubv(TH_VERTEX, nosel); sel_col[0]=(float)sel[0]/255.0f; @@ -3511,41 +3534,61 @@ static void draw_particle_edit(Object *ob, ParticleSystem *psys) totchild = psys->totchildcache; /* draw paths */ - glEnableClientState(GL_VERTEX_ARRAY); - glEnableClientState(GL_NORMAL_ARRAY); - glEnableClientState(GL_COLOR_ARRAY); if(timed) glEnable(GL_BLEND); - if(pset->brushtype == PE_BRUSH_WEIGHT){ - glLineWidth(2.0f); + glEnableClientState(GL_VERTEX_ARRAY); + + if(dt > OB_WIRE) { + /* solid shaded with lighting */ + glEnableClientState(GL_NORMAL_ARRAY); glEnableClientState(GL_COLOR_ARRAY); + + glEnable(GL_COLOR_MATERIAL); + glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE); + } + else { + /* flat wire color */ + glDisableClientState(GL_NORMAL_ARRAY); glDisable(GL_LIGHTING); + BIF_ThemeColor(TH_WIRE); } - glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE); - glEnable(GL_COLOR_MATERIAL); + /* only draw child paths with lighting */ + if(dt > OB_WIRE) + glEnable(GL_LIGHTING); - for(i=0, pa=psys->particles, path = psys->pathcache; ico); - glNormalPointer(GL_FLOAT, sizeof(ParticleCacheKey), (*path)->vel); - glColorPointer(3, GL_FLOAT, sizeof(ParticleCacheKey), (*path)->col); - - glDrawArrays(GL_LINE_STRIP, 0, (int)(*path)->steps + 1); - } - - glEnable(GL_LIGHTING); if(psys->part->draw_as == PART_DRAW_PATH) { for(i=0, path=psys->childcache; ico); - glNormalPointer(GL_FLOAT, sizeof(ParticleCacheKey), (*path)->vel); - glColorPointer(3, GL_FLOAT, sizeof(ParticleCacheKey), (*path)->col); + if(dt > OB_WIRE) { + glNormalPointer(GL_FLOAT, sizeof(ParticleCacheKey), (*path)->vel); + glColorPointer(3, GL_FLOAT, sizeof(ParticleCacheKey), (*path)->col); + } glDrawArrays(GL_LINE_STRIP, 0, (int)(*path)->steps + 1); } } - glDisable(GL_COLOR_MATERIAL); + if(dt > OB_WIRE) + glDisable(GL_LIGHTING); + + if(pset->brushtype == PE_BRUSH_WEIGHT) { + glLineWidth(2.0f); + glEnableClientState(GL_COLOR_ARRAY); + glDisable(GL_LIGHTING); + } + + /* draw parents last without lighting */ + for(i=0, pa=psys->particles, path = psys->pathcache; ico); + if(dt > OB_WIRE) + glNormalPointer(GL_FLOAT, sizeof(ParticleCacheKey), (*path)->vel); + if(dt > OB_WIRE || pset->brushtype == PE_BRUSH_WEIGHT) + glColorPointer(3, GL_FLOAT, sizeof(ParticleCacheKey), (*path)->col); + + glDrawArrays(GL_LINE_STRIP, 0, (int)(*path)->steps + 1); + } /* draw edit vertices */ if(G.scene->selectmode!=SCE_SELECT_PATH){ @@ -3619,6 +3662,7 @@ static void draw_particle_edit(Object *ob, ParticleSystem *psys) glDisable(GL_BLEND); glDisable(GL_LIGHTING); + glDisable(GL_COLOR_MATERIAL); glDisableClientState(GL_COLOR_ARRAY); glEnableClientState(GL_NORMAL_ARRAY); glEnable(GL_DEPTH_TEST); @@ -5011,12 +5055,12 @@ void draw_object(Base *base, int flag) glDepthMask(GL_FALSE); for(psys=ob->particlesystem.first; psys; psys=psys->next) - draw_new_particle_system(base, psys); + draw_new_particle_system(base, psys, dt); if(G.f & G_PARTICLEEDIT && ob==OBACT) { psys= PE_get_current(ob); if(psys && !G.obedit && psys_in_edit_mode(psys)) - draw_particle_edit(ob, psys); + draw_particle_edit(ob, psys, dt); } glDepthMask(GL_TRUE); if(col) cpack(col); From 0eb8ea7429ad09fd463211550b3ab089de2630fb Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 27 May 2008 13:32:10 +0000 Subject: [PATCH 099/246] bugfix, edges with no faces raised an error. --- release/scripts/uv_seams_from_islands.py | 30 ++++++++++++++++++++---- 1 file changed, 26 insertions(+), 4 deletions(-) diff --git a/release/scripts/uv_seams_from_islands.py b/release/scripts/uv_seams_from_islands.py index 241f38fc4aa..7f156efde7d 100644 --- a/release/scripts/uv_seams_from_islands.py +++ b/release/scripts/uv_seams_from_islands.py @@ -1,12 +1,31 @@ #!BPY """ Name: 'Seams from Islands' -Blender: 243 +Blender: 246 Group: 'UV' Tooltip: 'Add seams onto the mesh at the bounds of UV islands' """ -# Add a licence here if you wish to re-distribute, we recommend the GPL +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# Script copyright (C) Campbell Barton +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# ***** END GPL LICENCE BLOCK ***** +# -------------------------------------------------------------------------- from Blender import Scene, Mesh, Window, sys import BPyMessages @@ -37,8 +56,11 @@ def seams_from_islands(me): # add seams SEAM = Mesh.EdgeFlags.SEAM for ed in me.edges: - if len(set(edge_uvs[ed.key])) > 1: - ed.flag |= SEAM + try: # the edge might not be in a face + if len(set(edge_uvs[ed.key])) > 1: + ed.flag |= SEAM + except: + pass def main(): From 056f0564c2ccf391d5a2c114c24e58f00a2a24a0 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 27 May 2008 15:14:35 +0000 Subject: [PATCH 100/246] bugfix for zero area faces and adding uv layers was not checking if the UV layer existed alredy. --- release/scripts/uvcalc_lightmap.py | 34 +++++++++++++++++++++++------- 1 file changed, 26 insertions(+), 8 deletions(-) diff --git a/release/scripts/uvcalc_lightmap.py b/release/scripts/uvcalc_lightmap.py index 5f9f88a241d..37423b7197e 100644 --- a/release/scripts/uvcalc_lightmap.py +++ b/release/scripts/uvcalc_lightmap.py @@ -41,6 +41,12 @@ import BPyMesh from math import sqrt +def AngleBetweenVecs(a1,a2): + try: + return Mathutils.AngleBetweenVecs(a1,a2) + except: + return 180.0 + class prettyface(object): __slots__ = 'uv', 'width', 'height', 'children', 'xoff', 'yoff', 'has_parent', 'rot' def __init__(self, data): @@ -148,9 +154,9 @@ class prettyface(object): if len(uv) == 2: # match the order of angle sizes of the 3d verts with the UV angles and rotate. def get_tri_angles(v1,v2,v3): - a1= Mathutils.AngleBetweenVecs(v2-v1,v3-v1) - a2= Mathutils.AngleBetweenVecs(v1-v2,v3-v2) - a3 = 180 - (a1+a2) #a3= Mathutils.AngleBetweenVecs(v2-v3,v1-v3) + a1= AngleBetweenVecs(v2-v1,v3-v1) + a2= AngleBetweenVecs(v1-v2,v3-v2) + a3 = 180 - (a1+a2) #a3= AngleBetweenVecs(v2-v3,v1-v3) return [(a1,0),(a2,1),(a3,2)] @@ -237,8 +243,17 @@ PREF_MARGIN_DIV= 512): face_groups.append(faces) if PREF_NEW_UVLAYER: - me.addUVLayer('lightmap') - me.activeUVLayer = 'lightmap' + uvname_org = uvname = 'lightmap' + uvnames = me.getUVLayerNames() + i = 1 + while uvname in uvnames: + uvname = '%s.%03d' % (uvname_org, i) + i+=1 + + me.addUVLayer(uvname) + me.activeUVLayer = uvname + + del uvnames, uvname_org, uvname for face_sel in face_groups: print "\nStarting unwrap" @@ -402,11 +417,14 @@ PREF_MARGIN_DIV= 512): # ...limiting this is needed or you end up with bug unused texture spaces # ...however if its too high, boxpacking is way too slow for high poly meshes. float_to_int_factor = lengths_to_ints[0][0] - max_int_dimension = int(((side_len / float_to_int_factor)) / PREF_BOX_DIV) - + if float_to_int_factor > 0: + max_int_dimension = int(((side_len / float_to_int_factor)) / PREF_BOX_DIV) + ok = True + else: + max_int_dimension = 0.0 # wont be used + ok = False # RECURSIVE prettyface grouping - ok = True while ok: ok = False From 83a7fbf499ee51051f66bfa5fe23caa96cb262b7 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Tue, 27 May 2008 15:36:36 +0000 Subject: [PATCH 101/246] Another fix for bug #11140: explode modifier was still using more memory than needed. --- source/blender/blenkernel/intern/modifier.c | 115 +++++++++++--------- 1 file changed, 62 insertions(+), 53 deletions(-) diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c index b867b8d22bb..f9f17e7762d 100644 --- a/source/blender/blenkernel/intern/modifier.c +++ b/source/blender/blenkernel/intern/modifier.c @@ -6485,12 +6485,14 @@ static DerivedMesh * explodeModifier_explodeMesh(ExplodeModifierData *emd, MFace *mf=0; MVert *dupvert=0; ParticleSettings *part=psmd->psys->part; - ParticleData *pa, *pars=psmd->psys->particles; + ParticleData *pa=NULL, *pars=psmd->psys->particles; ParticleKey state; + EdgeHash *vertpahash; + EdgeHashIterator *ehi; float *vertco=0, imat[4][4]; float loc0[3], nor[3]; float timestep, cfra; - int *facepa=emd->facepa, *vertpa=0; + int *facepa=emd->facepa; int totdup=0,totvert=0,totface=0,totpart=0; int i, j, v, mindex=0; @@ -6505,34 +6507,36 @@ static DerivedMesh * explodeModifier_explodeMesh(ExplodeModifierData *emd, else cfra=bsystem_time(ob,(float)G.scene->r.cfra,0.0); - /* table for vertice <-> particle relations (row totpart+1 is for yet unexploded verts) */ - vertpa = MEM_callocN(sizeof(int)*(totpart+1)*totvert, "explode_vertpatab"); - for(i=0; i<(totpart+1)*totvert; i++) - vertpa[i] = -1; + /* hash table for vertice <-> particle relations */ + vertpahash= BLI_edgehash_new(); for (i=0; itime) - mindex = totpart*totvert; + mindex = totvert+totpart; else - mindex = facepa[i]*totvert; + mindex = totvert+facepa[i]; mf=CDDM_get_face(dm,i); - /*set face vertices to exist in particle group*/ - vertpa[mindex+mf->v1] = 1; - vertpa[mindex+mf->v2] = 1; - vertpa[mindex+mf->v3] = 1; + /* set face vertices to exist in particle group */ + BLI_edgehash_insert(vertpahash, mf->v1, mindex, NULL); + BLI_edgehash_insert(vertpahash, mf->v2, mindex, NULL); + BLI_edgehash_insert(vertpahash, mf->v3, mindex, NULL); if(mf->v4) - vertpa[mindex+mf->v4] = 1; + BLI_edgehash_insert(vertpahash, mf->v4, mindex, NULL); } - /*make new vertice indexes & count total vertices after duplication*/ - for(i=0; i<(totpart+1)*totvert; i++){ - if(vertpa[i] != -1) - vertpa[i] = totdup++; + /* make new vertice indexes & count total vertices after duplication */ + ehi= BLI_edgehashIterator_new(vertpahash); + for(; !BLI_edgehashIterator_isDone(ehi); BLI_edgehashIterator_step(ehi)) { + BLI_edgehashIterator_setValue(ehi, SET_INT_IN_POINTER(totdup)); + totdup++; } + BLI_edgehashIterator_free(ehi); - /*the final duplicated vertices*/ + /* the final duplicated vertices */ explode= CDDM_from_template(dm, totdup, 0,totface); dupvert= CDDM_get_verts(explode); @@ -6541,45 +6545,49 @@ static DerivedMesh * explodeModifier_explodeMesh(ExplodeModifierData *emd, psmd->psys->lattice = psys_get_lattice(ob, psmd->psys); - /*duplicate & displace vertices*/ - for(i=0, pa=pars; i<=totpart; i++, pa++){ - if(i!=totpart){ + /* duplicate & displace vertices */ + ehi= BLI_edgehashIterator_new(vertpahash); + for(; !BLI_edgehashIterator_isDone(ehi); BLI_edgehashIterator_step(ehi)) { + MVert source; + MVert *dest; + + /* get particle + vertex from hash */ + BLI_edgehashIterator_getKey(ehi, &j, &i); + i -= totvert; + v= GET_INT_FROM_POINTER(BLI_edgehashIterator_getValue(ehi)); + + dm->getVert(dm, j, &source); + dest = CDDM_get_vert(explode,v); + + DM_copy_vert_data(dm,explode,j,v,1); + *dest = source; + + if(i!=totpart) { + /* get particle */ + pa= pars+i; + + /* get particle state */ psys_particle_on_emitter(ob, psmd,part->from,pa->num,-1,pa->fuv,pa->foffset,loc0,nor,0,0,0,0); Mat4MulVecfl(ob->obmat,loc0); state.time=cfra; psys_get_particle_state(ob,psmd->psys,i,&state,1); - } - for(j=0; jco; + + Mat4MulVecfl(ob->obmat,vertco); - dm->getVert(dm, j, &source); - dest = CDDM_get_vert(explode,v); + VECSUB(vertco,vertco,loc0); - DM_copy_vert_data(dm,explode,j,v,1); - *dest = source; + /* apply rotation, size & location */ + QuatMulVecf(state.rot,vertco); + VecMulf(vertco,pa->size); + VECADD(vertco,vertco,state.co); - if(i!=totpart){ - vertco=CDDM_get_vert(explode,v)->co; - - Mat4MulVecfl(ob->obmat,vertco); - - VECSUB(vertco,vertco,loc0); - - /* apply rotation, size & location */ - QuatMulVecf(state.rot,vertco); - VecMulf(vertco,pa->size); - VECADD(vertco,vertco,state.co); - - Mat4MulVecfl(imat,vertco); - } - } + Mat4MulVecfl(imat,vertco); } } + BLI_edgehashIterator_free(ehi); /*map new vertices to faces*/ for (i=0; itime) - mindex = totpart*totvert; + mindex = totvert+totpart; else - mindex = facepa[i]*totvert; + mindex = totvert+facepa[i]; - source.v1 = vertpa[mindex+source.v1]; - source.v2 = vertpa[mindex+source.v2]; - source.v3 = vertpa[mindex+source.v3]; + source.v1 = edgesplit_get(vertpahash, source.v1, mindex); + source.v2 = edgesplit_get(vertpahash, source.v2, mindex); + source.v3 = edgesplit_get(vertpahash, source.v3, mindex); if(source.v4) - source.v4 = vertpa[mindex+source.v4]; + source.v4 = edgesplit_get(vertpahash, source.v4, mindex); DM_copy_face_data(dm,explode,i,i,1); @@ -6618,9 +6626,10 @@ static DerivedMesh * explodeModifier_explodeMesh(ExplodeModifierData *emd, test_index_face(mf, &explode->faceData, i, (mf->v4 ? 4 : 3)); } + MEM_printmemlist_stats(); /* cleanup */ - if(vertpa) MEM_freeN(vertpa); + BLI_edgehash_free(vertpahash, NULL); /* finalization */ CDDM_calc_edges(explode); From c1874b3cee1fdb2220f26f75e676942aee4be561 Mon Sep 17 00:00:00 2001 From: Martin Poirier Date: Tue, 27 May 2008 20:02:38 +0000 Subject: [PATCH 102/246] [#10223] a new object function to add vertex group from an armature Patch from Jean-Michel Soler (with slight modifs) Small BPy feature to help script writers deal with armatures and vertex groups (calls the bone heat method to create and assign groups) --- source/blender/python/api2_2x/Object.c | 39 +++++++++++++++++++++ source/blender/python/api2_2x/doc/Object.py | 7 ++++ 2 files changed, 46 insertions(+) diff --git a/source/blender/python/api2_2x/Object.c b/source/blender/python/api2_2x/Object.c index 82f99adcdb1..1a806932bdb 100644 --- a/source/blender/python/api2_2x/Object.c +++ b/source/blender/python/api2_2x/Object.c @@ -341,6 +341,7 @@ static int setupPI(Object* ob); static PyObject *Object_getParticleSys( BPy_Object * self ); /* fixme Object_newParticleSys( self, default-partsys-name ) */ +static PyObject *Object_addVertexGroupsFromArmature( BPy_Object * self, PyObject * args); static PyObject *Object_newParticleSys( BPy_Object * self ); static PyObject *Object_buildParts( BPy_Object * self ); static PyObject *Object_clearIpo( BPy_Object * self ); @@ -475,6 +476,8 @@ static PyMethodDef BPy_Object_methods[] = { "Return a list of particle systems"}, {"newParticleSystem", ( PyCFunction ) Object_newParticleSys, METH_NOARGS, "Create and link a new particle system"}, + {"addVertexGroupsFromArmature" , ( PyCFunction ) Object_addVertexGroupsFromArmature, METH_VARARGS, + "Add vertex groups from armature using the bone heat method"}, {"buildParts", ( PyCFunction ) Object_buildParts, METH_NOARGS, "Recalcs particle system (if any), (depricated, will always return an empty list in version 2.46)"}, {"getIpo", ( PyCFunction ) Object_getIpo, METH_NOARGS, @@ -1109,6 +1112,42 @@ PyObject *Object_newParticleSys( BPy_Object * self ){ return ParticleSys_CreatePyObject(rpsys,ob); } +/*****************************************************************************/ +/* attribute: addVertexGroupsFromArmature */ +/* Description: evaluate and add vertex groups to the current object */ +/* for each bone of the selected armature */ +/* Data: self Object, Bpy armature */ +/* Return: nothing */ +/*****************************************************************************/ +static PyObject *Object_addVertexGroupsFromArmature( BPy_Object * self, PyObject * args) +{ + + Object *ob = self->object; + BPy_Object *arm; + + if( ob->type != OB_MESH ) + return EXPP_ReturnPyObjError( PyExc_TypeError, + "Only useable on Mesh type Objects" ); + + if( G.obedit != NULL) + return EXPP_ReturnPyObjError( PyExc_TypeError, + "Not useable when inside edit mode" ); + + /* Check if the arguments passed to makeParent are valid. */ + if( !PyArg_ParseTuple( args, "O!",&Object_Type, &arm ) ) + return EXPP_ReturnPyObjError( PyExc_TypeError, + "An armature object is expected." ); + + if( arm->object->type != OB_ARMATURE ) + return EXPP_ReturnPyObjError( PyExc_TypeError, + "An armature object is expected." ); + + add_verts_to_dgroups(ob, arm->object, 1, 0); + ob->recalc |= OB_RECALC_OB; + + Py_RETURN_NONE; +} + static PyObject *Object_buildParts( BPy_Object * self ) { /* This is now handles by modifiers */ diff --git a/source/blender/python/api2_2x/doc/Object.py b/source/blender/python/api2_2x/doc/Object.py index 521be3b0cea..09167c0e117 100644 --- a/source/blender/python/api2_2x/doc/Object.py +++ b/source/blender/python/api2_2x/doc/Object.py @@ -651,6 +651,13 @@ class Object: Link a new particle system (see Blender.Particle). """ + def addVertexGroupsFromArmature(object): + """ + Add vertex groups from armature using the bone heat method + This method can be only used with an Object of the type Mesh when NOT in edit mode. + @type object: a bpy armature + """ + def buildParts(): """ Recomputes the particle system. This method only applies to an Object of From da36e8abca19b667d1c300a154e6e6798af119e9 Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Tue, 27 May 2008 22:42:38 +0000 Subject: [PATCH 103/246] -= KDOP / Collisions =- 1. Fix for face with index=0 not handled --- source/blender/blenlib/intern/BLI_kdopbvh.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/blender/blenlib/intern/BLI_kdopbvh.c b/source/blender/blenlib/intern/BLI_kdopbvh.c index cf326f3f460..c884b97b182 100644 --- a/source/blender/blenlib/intern/BLI_kdopbvh.c +++ b/source/blender/blenlib/intern/BLI_kdopbvh.c @@ -653,10 +653,10 @@ static void traverse(BVHOverlapData *data, BVHNode *node1, BVHNode *node2) if(tree_overlap(node1->bv, node2->bv, MIN2(data->tree1->start_axis, data->tree2->start_axis), MIN2(data->tree1->stop_axis, data->tree2->stop_axis))) { // check if node1 is a leaf - if(node1->index) + if(!node1->totnode) { // check if node2 is a leaf - if(node2->index) + if(!node2->totnode) { if(node1 == node2) From ed42c9a6768712c1eeba3b36af09620f668d663b Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Tue, 27 May 2008 22:46:57 +0000 Subject: [PATCH 104/246] -= Collisions -= 1. Test for fast moving edges --- source/blender/blenkernel/intern/collision.c | 102 ++++++++++--------- 1 file changed, 56 insertions(+), 46 deletions(-) diff --git a/source/blender/blenkernel/intern/collision.c b/source/blender/blenkernel/intern/collision.c index 0b291aaa695..37784b43cf9 100644 --- a/source/blender/blenkernel/intern/collision.c +++ b/source/blender/blenkernel/intern/collision.c @@ -498,6 +498,7 @@ DO_INLINE void collision_interpolateOnTriangle ( float to[3], float v1[3], float VECADDMUL ( to, v3, w3 ); } + int cloth_collision_response_static ( ClothModifierData *clmd, CollisionModifierData *collmd, CollPair *collpair, CollPair *collision_end ) { int result = 0; @@ -1189,8 +1190,16 @@ int cloth_collision_moving_edges ( ClothModifierData *clmd, CollisionModifierDat edgecollpair.p22 = collpair->bp3; } + if((edgecollpair.p11 == 3) && (edgecollpair.p12 == 6)) + printf("Ahier!\n"); + if((edgecollpair.p11 == 6) && (edgecollpair.p12 == 3)) + printf("Ahier!\n"); + if ( !cloth_are_edges_adjacent ( clmd, collmd, &edgecollpair ) ) { + // printf("Collision between:\n"); + // printf("p11: %d, p12: %d, p21: %d, p22: %d\n", edgecollpair.p11, edgecollpair.p12, edgecollpair.p21, edgecollpair.p22); + // always put coll points in p21/p22 VECSUB ( x1, verts1[edgecollpair.p12].txold, verts1[edgecollpair.p11].txold ); VECSUB ( v1, verts1[edgecollpair.p12].tv, verts1[edgecollpair.p11].tv ); @@ -1206,11 +1215,14 @@ int cloth_collision_moving_edges ( ClothModifierData *clmd, CollisionModifierDat for ( k = 0; k < numsolutions; k++ ) { // printf("sol %d: %lf\n", k, solution[k]); - if ( ( solution[k] >= DBL_EPSILON ) && ( solution[k] <= 1.0 ) ) + if ( ( solution[k] >= ALMOST_ZERO ) && ( solution[k] <= 1.0 ) && ( solution[k] > ALMOST_ZERO)) { float a,b; float out_normal[3]; float distance; + float impulse = 0; + float I_mag; + float m1, m2; // move verts VECADDS(triA[0], verts1[edgecollpair.p11].txold, verts1[edgecollpair.p11].tv, mintime); @@ -1224,28 +1236,57 @@ int cloth_collision_moving_edges ( ClothModifierData *clmd, CollisionModifierDat if ((distance <= clmd->coll_parms->epsilon + BLI_bvhtree_getepsilon ( collmd->bvhtree ) + ALMOST_ZERO) && (INPR(out_normal, out_normal) > 0)) { - // printf("found edge, dist: %f\n", distance); + float vrel_1_to_2[3], temp[3], temp2[3], out_normalVelocity; + float desiredVn; + + VECCOPY(vrel_1_to_2, verts1[edgecollpair.p11].tv); + VecMulf(vrel_1_to_2, 1.0 - a); + VECCOPY(temp, verts1[edgecollpair.p12].tv); + VecMulf(temp, a); + + VECADD(vrel_1_to_2, vrel_1_to_2, temp); + + VECCOPY(temp, verts1[edgecollpair.p21].tv); + VecMulf(temp, 1.0 - b); + VECCOPY(temp2, verts1[edgecollpair.p22].tv); + VecMulf(temp2, b); + VECADD(temp, temp, temp2); + + VECSUB(vrel_1_to_2, vrel_1_to_2, temp); + + out_normalVelocity = INPR(vrel_1_to_2, out_normal); + + if(out_normalVelocity < 0.0) + { + out_normalVelocity*= -1.0; + VecMulf(out_normal, -1.0); + } /* Inelastic repulsion impulse. */ -/* + // Calculate which normal velocity we need. - float desiredVn = (normalVelocity * (float)solution[k] - (.1 * (clmd->coll_parms->epsilon + BLI_bvhtree_getepsilon ( collmd->bvhtree )) - sqrt(squaredDistance)) - ALMOST_ZERO); + desiredVn = (out_normalVelocity * (float)solution[k] - (.1 * (clmd->coll_parms->epsilon + BLI_bvhtree_getepsilon ( collmd->bvhtree )) - sqrt(distance)) - ALMOST_ZERO); // Now calculate what impulse we need to reach that velocity. - float m1 = interpolateOnEdge(cloth1.getVertexWeight(v11idx), cloth1.getVertexWeight(v12idx), a1); - float m2 = interpolateOnEdge(cloth2.getVertexWeight(v21idx), cloth2.getVertexWeight(v22idx), a2); - float I_mag = (normalVelocity - desiredVn) / (1/m1 + 1/m2); + I_mag = (out_normalVelocity - desiredVn) / 2.0; // / (1/m1 + 1/m2); // Finally apply that impulse. - applyInterpolatedImpulsesEdge(out_impulses1[v11idx], out_impulses1[v12idx], out_impulses2[v21idx], out_impulses2[v22idx], - a1, a2, -I_mag, normal); - ++out_impulseCounter1[v11idx]; ++out_impulseCounter1[v12idx]; - ++out_impulseCounter2[v21idx]; ++out_impulseCounter2[v22idx]; + impulse = (2.0 * -I_mag) / (a*a + (1.0-a)*(1.0-a) + b*b + (1.0-b)*(1.0-b)); - */ // return true; + VECADDMUL ( verts1[edgecollpair.p11].impulse, out_normal, (1.0-a) * impulse ); + verts1[edgecollpair.p11].impulse_count++; + + VECADDMUL ( verts1[edgecollpair.p12].impulse, out_normal, a * impulse ); + verts1[edgecollpair.p12].impulse_count++; + + // return true; result = 1; + break; + } + else + { + // missing from collision.hpp } - mintime = MIN2(mintime, (float)solution[k]); break; @@ -1253,37 +1294,6 @@ int cloth_collision_moving_edges ( ClothModifierData *clmd, CollisionModifierDat } } } -/* - if(result) - { - // move triangles to collision point in time - VECADDS(triA[0], verts1[collpair->ap1].txold, verts1[collpair->ap1].tv, mintime); - VECADDS(triA[1], verts1[collpair->ap2].txold, verts1[collpair->ap2].tv, mintime); - VECADDS(triA[2], verts1[collpair->ap3].txold, verts1[collpair->ap3].tv, mintime); - - VECADDS(triB[0], collmd->current_x[collpair->bp1].co, collmd->current_v[collpair->bp1].co, mintime); - VECADDS(triB[1], collmd->current_x[collpair->bp2].co, collmd->current_v[collpair->bp2].co, mintime); - VECADDS(triB[2], collmd->current_x[collpair->bp3].co, collmd->current_v[collpair->bp3].co, mintime); - - // check distance there - distance = plNearestPoints (triA[0], triA[1], triA[2], triB[0], triB[1], triB[2], collpair->pa,collpair->pb,collpair->vector ); - - if(distance <= (clmd->coll_parms->epsilon + BLI_bvhtree_getepsilon ( collmd->bvhtree ) + ALMOST_ZERO)) - { - CollPair *next = collpair; - next++; - - collpair->distance = clmd->coll_parms->epsilon; - collpair->time = mintime; - - VECCOPY ( collpair->normal, collpair->vector ); - Normalize ( collpair->normal ); - - // cloth_collision_response_moving ( clmd, collmd, collpair, next ); - - } - } -*/ return result; } @@ -1419,7 +1429,7 @@ int cloth_bvh_objcollisions_do ( ClothModifierData * clmd, CollisionModifierData } } } -/* + result += cloth_collision_moving ( clmd, collmd, collisions, collisions_index ); // apply impulses in parallel @@ -1438,7 +1448,7 @@ int cloth_bvh_objcollisions_do ( ClothModifierData * clmd, CollisionModifierData } } } -*/ + } } From b36a358c1b785661c105a6ff59f6a1313053dd4f Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 28 May 2008 00:44:41 +0000 Subject: [PATCH 105/246] bugfix * python api render() would clamp the endframe to a short. * python api's render() and renderAnim() would not render compositing because the name they gave to RE_NewRender was NOT G.scene->id.name, added comments to G.scene->id.name --- source/blender/python/api2_2x/sceneRender.c | 10 ++++++---- source/blender/render/intern/source/pipeline.c | 1 + 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/source/blender/python/api2_2x/sceneRender.c b/source/blender/python/api2_2x/sceneRender.c index f54c2cd4e3b..bfad069f943 100644 --- a/source/blender/python/api2_2x/sceneRender.c +++ b/source/blender/python/api2_2x/sceneRender.c @@ -478,9 +478,11 @@ PyObject *RenderData_Render( BPy_RenderData * self ) } else { /* background mode (blender -b file.blend -P script) */ - Render *re= RE_NewRender("Render"); + Render *re= RE_NewRender(G.scene->id.name); - int end_frame = G.scene->r.efra; /* is of type short currently */ + + + int end_frame = G.scene->r.efra; if (G.scene != self->scene) return EXPP_ReturnPyObjError (PyExc_RuntimeError, @@ -490,7 +492,7 @@ PyObject *RenderData_Render( BPy_RenderData * self ) RE_BlenderAnim(re, G.scene, G.scene->r.sfra, G.scene->r.efra); - G.scene->r.efra = (short)end_frame; + G.scene->r.efra = end_frame; } Py_RETURN_NONE; @@ -571,7 +573,7 @@ PyObject *RenderData_RenderAnim( BPy_RenderData * self ) set_scene( oldsce ); } else { /* background mode (blender -b file.blend -P script) */ - Render *re= RE_NewRender("Render"); + Render *re= RE_NewRender(G.scene->id.name); if (G.scene != self->scene) return EXPP_ReturnPyObjError (PyExc_RuntimeError, diff --git a/source/blender/render/intern/source/pipeline.c b/source/blender/render/intern/source/pipeline.c index fb699f5b382..ebb52c49132 100644 --- a/source/blender/render/intern/source/pipeline.c +++ b/source/blender/render/intern/source/pipeline.c @@ -993,6 +993,7 @@ RenderStats *RE_GetStats(Render *re) return &re->i; } +/* Note, when rendering from a scene, ALWAYS use G.scene->id.name, else compositing wont work */ Render *RE_NewRender(const char *name) { Render *re; From c6668755ff865f79d9526301ca6edac48d982b06 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 28 May 2008 17:13:15 +0000 Subject: [PATCH 106/246] bugfix for baking AO with greater then 16 samples, since it was being clamped in sphere_sampler but not in ray_ao_spheresamp that calls it. giving uneven art deco results. --- source/blender/render/intern/source/rayshade.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/source/blender/render/intern/source/rayshade.c b/source/blender/render/intern/source/rayshade.c index 8fd07001bd1..cbba5d2bb2c 100644 --- a/source/blender/render/intern/source/rayshade.c +++ b/source/blender/render/intern/source/rayshade.c @@ -1473,8 +1473,6 @@ static float *sphere_sampler(int type, int resol, int thread, int xs, int ys) int tot; float *vec; - if(resol>16) resol= 16; - tot= 2*resol*resol; if (type & WO_AORNDSMP) { @@ -1663,7 +1661,7 @@ void ray_ao_spheresamp(ShadeInput *shi, float *shadfac) float *vec, *nrm, div, bias, sh=0.0f; float maxdist = R.wrld.aodist; float dxyview[3]; - int j= -1, tot, actual=0, skyadded=0, aocolor; + int j= -1, tot, actual=0, skyadded=0, aocolor, resol= R.wrld.aosamp; isec.faceorig= (RayFace*)shi->vlr; isec.oborig= RAY_OBJECT_SET(&R, shi->obi); @@ -1690,14 +1688,16 @@ void ray_ao_spheresamp(ShadeInput *shi, float *shadfac) if(shi->mat->mode & MA_ONLYSHADOW) aocolor= WO_AOPLAIN; - vec= sphere_sampler(R.wrld.aomode, R.wrld.aosamp, shi->thread, shi->xs, shi->ys); + if(resol>32) resol= 32; + + vec= sphere_sampler(R.wrld.aomode, resol, shi->thread, shi->xs, shi->ys); // warning: since we use full sphere now, and dotproduct is below, we do twice as much - tot= 2*R.wrld.aosamp*R.wrld.aosamp; + tot= 2*resol*resol; if(aocolor == WO_AOSKYTEX) { - dxyview[0]= 1.0f/(float)R.wrld.aosamp; - dxyview[1]= 1.0f/(float)R.wrld.aosamp; + dxyview[0]= 1.0f/(float)resol; + dxyview[1]= 1.0f/(float)resol; dxyview[2]= 0.0f; } From 9a3b25d8a098577a1889900353af536151683f91 Mon Sep 17 00:00:00 2001 From: Janne Karhu Date: Wed, 28 May 2008 17:16:43 +0000 Subject: [PATCH 107/246] Fix for bug: [#11680] "Col" option for particle systems does not work correctly with Mat IPOs -the feature simply was not coded --- source/blender/src/drawobject.c | 83 +++++++++++++++++++++++++++------ 1 file changed, 68 insertions(+), 15 deletions(-) diff --git a/source/blender/src/drawobject.c b/source/blender/src/drawobject.c index 3ef14574bc8..d2555f355bb 100644 --- a/source/blender/src/drawobject.c +++ b/source/blender/src/drawobject.c @@ -2902,7 +2902,7 @@ static void draw_new_particle_system(Base *base, ParticleSystem *psys, int dt) float *vdata=0, *vedata=0, *cdata=0, *ndata=0, *vd=0, *ved=0, *cd=0, *nd=0, xvec[3], yvec[3], zvec[3]; int a, k, k_max=0, totpart, totpoint=0, draw_as, path_nbr=0; int path_possible=0, keys_possible=0, draw_keys=0, totchild=0; - int select=ob->flag&SELECT; + int select=ob->flag&SELECT, create_cdata=0; GLint polygonmode[2]; char val[32]; @@ -2956,8 +2956,10 @@ static void draw_new_particle_system(Base *base, ParticleSystem *psys, int dt) if(select) cpack(0xFFFFFF); - else if((ma) && (part->draw&PART_DRAW_MAT_COL)) + else if((ma) && (part->draw&PART_DRAW_MAT_COL)) { glColor3f(ma->r,ma->g,ma->b); + create_cdata = 1; + } else cpack(0); @@ -3065,19 +3067,25 @@ static void draw_new_particle_system(Base *base, ParticleSystem *psys, int dt) if(draw_as!=PART_DRAW_CIRC){ switch(draw_as){ case PART_DRAW_AXIS: - cdata=MEM_callocN((totpart+totchild)*(path_nbr+1)*6*3*sizeof(float), "particle_cdata"); - /* no break! */ case PART_DRAW_CROSS: + if(draw_as!=PART_DRAW_CROSS || create_cdata) + cdata=MEM_callocN((totpart+totchild)*(path_nbr+1)*6*3*sizeof(float), "particle_cdata"); vdata=MEM_callocN((totpart+totchild)*(path_nbr+1)*6*3*sizeof(float), "particle_vdata"); break; case PART_DRAW_LINE: + if(create_cdata) + cdata=MEM_callocN((totpart+totchild)*(path_nbr+1)*2*3*sizeof(float), "particle_cdata"); vdata=MEM_callocN((totpart+totchild)*(path_nbr+1)*2*3*sizeof(float), "particle_vdata"); break; case PART_DRAW_BB: + if(create_cdata) + cdata=MEM_callocN((totpart+totchild)*(path_nbr+1)*4*3*sizeof(float), "particle_cdata"); vdata=MEM_callocN((totpart+totchild)*(path_nbr+1)*4*3*sizeof(float), "particle_vdata"); ndata=MEM_callocN((totpart+totchild)*(path_nbr+1)*4*3*sizeof(float), "particle_vdata"); break; default: + if(create_cdata) + cdata=MEM_callocN((totpart+totchild)*(path_nbr+1)*3*sizeof(float), "particle_cdata"); vdata=MEM_callocN((totpart+totchild)*(path_nbr+1)*3*sizeof(float), "particle_vdata"); } } @@ -3102,9 +3110,17 @@ static void draw_new_particle_system(Base *base, ParticleSystem *psys, int dt) pa_time=(cfra-pa->time)/pa->lifetime; - if((part->flag&PART_ABS_TIME)==0 && part->ipo){ - calc_ipo(part->ipo, 100*pa_time); - execute_ipo((ID *)part, part->ipo); + if((part->flag&PART_ABS_TIME)==0){ + if(ma->ipo){ + /* correction for lifetime */ + calc_ipo(ma->ipo, 100.0f*pa_time); + execute_ipo((ID *)ma, ma->ipo); + } + if(part->ipo) { + /* correction for lifetime */ + calc_ipo(part->ipo, 100*pa_time); + execute_ipo((ID *)part, part->ipo); + } } pa_size=pa->size; @@ -3121,9 +3137,17 @@ static void draw_new_particle_system(Base *base, ParticleSystem *psys, int dt) pa_time=psys_get_child_time(psys,cpa,cfra); - if((part->flag&PART_ABS_TIME)==0 && part->ipo){ - calc_ipo(part->ipo, 100*pa_time); - execute_ipo((ID *)part, part->ipo); + if((part->flag&PART_ABS_TIME)==0) { + if(ma->ipo){ + /* correction for lifetime */ + calc_ipo(ma->ipo, 100.0f*pa_time); + execute_ipo((ID *)ma, ma->ipo); + } + if(part->ipo) { + /* correction for lifetime */ + calc_ipo(part->ipo, 100*pa_time); + execute_ipo((ID *)part, part->ipo); + } } pa_size=psys_get_child_size(psys,cpa,cfra,0); @@ -3161,6 +3185,12 @@ static void draw_new_particle_system(Base *base, ParticleSystem *psys, int dt) switch(draw_as){ case PART_DRAW_DOT: + if(cd) { + cd[0]=ma->r; + cd[1]=ma->g; + cd[2]=ma->b; + cd+=3; + } if(vd){ VECCOPY(vd,state.co) vd+=3; } @@ -3181,7 +3211,15 @@ static void draw_new_particle_system(Base *base, ParticleSystem *psys, int dt) VECCOPY(vec2,state.co); } - else VECSUB(vec2,state.co,vec); + else { + if(cd) { + cd[0]=cd[3]=cd[6]=cd[9]=cd[12]=cd[15]=ma->r; + cd[1]=cd[4]=cd[7]=cd[10]=cd[13]=cd[16]=ma->g; + cd[2]=cd[5]=cd[8]=cd[11]=cd[14]=cd[17]=ma->b; + cd+=18; + } + VECSUB(vec2,state.co,vec); + } VECADD(vec,state.co,vec); VECCOPY(vd,vec); vd+=3; @@ -3219,11 +3257,25 @@ static void draw_new_particle_system(Base *base, ParticleSystem *psys, int dt) VecMulf(vec,VecLength(state.vel)); VECADDFAC(vd,state.co,vec,-part->draw_line[0]); vd+=3; VECADDFAC(vd,state.co,vec,part->draw_line[1]); vd+=3; + if(cd) { + cd[0]=cd[3]=ma->r; + cd[1]=cd[4]=ma->g; + cd[2]=cd[5]=ma->b; + cd+=3; + } break; case PART_DRAW_CIRC: + if(create_cdata) + glColor3f(ma->r,ma->g,ma->b); drawcircball(GL_LINE_LOOP, state.co, pixsize, imat); break; case PART_DRAW_BB: + if(cd) { + cd[0]=cd[3]=cd[6]=cd[9]=ma->r; + cd[1]=cd[4]=cd[7]=cd[10]=ma->g; + cd[2]=cd[5]=cd[8]=cd[11]=ma->b; + cd+=12; + } if(part->draw&PART_DRAW_BB_LOCK && part->bb_align==PART_BB_VIEW){ VECCOPY(xvec,bb_ob->obmat[0]); Normalize(xvec); @@ -3419,13 +3471,14 @@ static void draw_new_particle_system(Base *base, ParticleSystem *psys, int dt) glDisable(GL_LIGHTING); } + if(cdata){ + glEnableClientState(GL_COLOR_ARRAY); + glColorPointer(3, GL_FLOAT, 0, cdata); + } + switch(draw_as){ case PART_DRAW_AXIS: case PART_DRAW_CROSS: - if(cdata){ - glEnableClientState(GL_COLOR_ARRAY); - glColorPointer(3, GL_FLOAT, 0, cdata); - } glDrawArrays(GL_LINES, 0, 6*totpoint); break; case PART_DRAW_LINE: From d49d0e174eaa5391b058f500e8aaa286fd30969d Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Wed, 28 May 2008 17:42:03 +0000 Subject: [PATCH 108/246] Small fix for last AO sphere sampling bugfix, didn't update random sampling code as well. --- source/blender/render/intern/source/rayshade.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/source/blender/render/intern/source/rayshade.c b/source/blender/render/intern/source/rayshade.c index cbba5d2bb2c..1155d2ea817 100644 --- a/source/blender/render/intern/source/rayshade.c +++ b/source/blender/render/intern/source/rayshade.c @@ -1476,9 +1476,12 @@ static float *sphere_sampler(int type, int resol, int thread, int xs, int ys) tot= 2*resol*resol; if (type & WO_AORNDSMP) { - static float sphere[2*3*256]; + float *sphere; int a; + // always returns table + sphere= threadsafe_table_sphere(0, thread, xs, ys, tot); + /* total random sampling. NOT THREADSAFE! (should be removed, is not useful) */ vec= sphere; for (a=0; a Date: Wed, 28 May 2008 17:55:06 +0000 Subject: [PATCH 109/246] Fix for bug #13230: particle mirror could fail on some faces. --- source/blender/src/meshtools.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/source/blender/src/meshtools.c b/source/blender/src/meshtools.c index e27e772edee..ac165d6aeb2 100644 --- a/source/blender/src/meshtools.c +++ b/source/blender/src/meshtools.c @@ -957,6 +957,12 @@ int *mesh_get_x_mirror_faces(Object *ob) mirrormf.v3= mirrorverts[mf->v1]; mirrormf.v4= (mf->v4)? mirrorverts[mf->v4]: 0; + /* make sure v4 is not 0 if a quad */ + if(mf->v4 && mirrormf.v4==0) { + SWAP(int, mirrormf.v1, mirrormf.v3); + SWAP(int, mirrormf.v2, mirrormf.v4); + } + hashmf= BLI_ghash_lookup(fhash, &mirrormf); if(hashmf) { mirrorfaces[a*2]= hashmf - mface; From 04067c183305c31b1f5f9e7ccfe1e6c8af89e5b8 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Wed, 28 May 2008 18:11:45 +0000 Subject: [PATCH 110/246] Fix for bug #13224: vertex parenting didn't work correct with multiple unconnected curves. --- source/blender/blenkernel/intern/object.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index ab1bc5a2265..4f901ba7216 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -1614,7 +1614,7 @@ static void give_parvert(Object *par, int nr, float *vec) for(eve= em->verts.first; eve; eve= eve->next) { if(eve->keyindex==nr) { - memcpy(vec, eve->co, 12); + memcpy(vec, eve->co, sizeof(float)*3); break; } } @@ -1652,18 +1652,20 @@ static void give_parvert(Object *par, int nr, float *vec) Curve *cu; BPoint *bp; BezTriple *bezt; + int found= 0; cu= par->data; nu= cu->nurb.first; if(par==G.obedit) nu= editNurb.first; count= 0; - while(nu) { + while(nu && !found) { if((nu->type & 7)==CU_BEZIER) { bezt= nu->bezt; a= nu->pntsu; while(a--) { if(count==nr) { + found= 1; VECCOPY(vec, bezt->vec[1]); break; } @@ -1676,7 +1678,8 @@ static void give_parvert(Object *par, int nr, float *vec) a= nu->pntsu*nu->pntsv; while(a--) { if(count==nr) { - memcpy(vec, bp->vec, 12); + found= 1; + memcpy(vec, bp->vec, sizeof(float)*3); break; } count++; From 1a5181c9c71802309b9947456e528cb5ee644d5e Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 28 May 2008 21:15:40 +0000 Subject: [PATCH 111/246] bugfix for own bug. mousewheel while playing in the sequencer crashes blender. --- source/blender/src/drawview.c | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/source/blender/src/drawview.c b/source/blender/src/drawview.c index 52e0d3d6f05..e83ecb13960 100644 --- a/source/blender/src/drawview.c +++ b/source/blender/src/drawview.c @@ -3732,18 +3732,22 @@ int play_anim(int mode) else viewmove(0); } } else if (event==WHEELDOWNMOUSE || (val && event==PADMINUS)) { /* copied from persptoetsen */ - /* this min and max is also in viewmove() */ - if(G.vd->persp==V3D_CAMOB) { - G.vd->camzoom-= 10; - if(G.vd->camzoom<-30) G.vd->camzoom= -30; + if (G.vd) { /* when using the sequencer this can be NULL */ + /* this min and max is also in viewmove() */ + if(G.vd->persp==V3D_CAMOB) { + G.vd->camzoom-= 10; + if(G.vd->camzoom<-30) G.vd->camzoom= -30; + } + else if(G.vd->dist<10.0*G.vd->far) G.vd->dist*=1.2f; } - else if(G.vd->dist<10.0*G.vd->far) G.vd->dist*=1.2f; } else if (event==WHEELUPMOUSE || (val && event==PADPLUSKEY)) { /* copied from persptoetsen */ - if(G.vd->persp==V3D_CAMOB) { - G.vd->camzoom+= 10; - if(G.vd->camzoom>300) G.vd->camzoom= 300; + if (G.vd) { + if(G.vd->persp==V3D_CAMOB) { + G.vd->camzoom+= 10; + if(G.vd->camzoom>300) G.vd->camzoom= 300; + } + else if(G.vd->dist> 0.001*G.vd->grid) G.vd->dist*=.83333f; } - else if(G.vd->dist> 0.001*G.vd->grid) G.vd->dist*=.83333f; } else if(event==MKEY) { if(val) add_marker(CFRA-1); } From a17f322dd0796cc76e1c8f40ce60ddddc990f93e Mon Sep 17 00:00:00 2001 From: Janne Karhu Date: Wed, 28 May 2008 23:38:40 +0000 Subject: [PATCH 112/246] Bug fix: [#13268] Crash when creating a new particle system -Ugh.. sorry about that.. damn default cube with it's default material! --- source/blender/src/drawobject.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/blender/src/drawobject.c b/source/blender/src/drawobject.c index d2555f355bb..96ba8c71755 100644 --- a/source/blender/src/drawobject.c +++ b/source/blender/src/drawobject.c @@ -3111,7 +3111,7 @@ static void draw_new_particle_system(Base *base, ParticleSystem *psys, int dt) pa_time=(cfra-pa->time)/pa->lifetime; if((part->flag&PART_ABS_TIME)==0){ - if(ma->ipo){ + if(ma && ma->ipo){ /* correction for lifetime */ calc_ipo(ma->ipo, 100.0f*pa_time); execute_ipo((ID *)ma, ma->ipo); @@ -3138,7 +3138,7 @@ static void draw_new_particle_system(Base *base, ParticleSystem *psys, int dt) pa_time=psys_get_child_time(psys,cpa,cfra); if((part->flag&PART_ABS_TIME)==0) { - if(ma->ipo){ + if(ma && ma->ipo){ /* correction for lifetime */ calc_ipo(ma->ipo, 100.0f*pa_time); execute_ipo((ID *)ma, ma->ipo); From e015796b3667e40bba093d0d3b67cb8bcbcdd34a Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Thu, 29 May 2008 01:04:12 +0000 Subject: [PATCH 113/246] Fill Bone Between Joints: This tool now parents the newly created bone to whichever bone acted as it's 'head' point. It also sets the connected-to-parent flag. --- source/blender/src/editarmature.c | 46 +++++++++++++++++++++++-------- 1 file changed, 34 insertions(+), 12 deletions(-) diff --git a/source/blender/src/editarmature.c b/source/blender/src/editarmature.c index c166a9df762..a68503b0d06 100644 --- a/source/blender/src/editarmature.c +++ b/source/blender/src/editarmature.c @@ -2396,6 +2396,7 @@ void fill_bones_armature(void) else if (count == 2) { EditBonePoint *ebp, *ebp2; float head[3], tail[3]; + short headtail = 0; /* check that the points don't belong to the same bone */ ebp= (EditBonePoint *)points.first; @@ -2420,7 +2421,7 @@ void fill_bones_armature(void) float distA, distB; /* get cursor location */ - VECCOPY (curs, give_cursor()); + VECCOPY(curs, give_cursor()); Mat4Invert(G.obedit->imat, G.obedit->obmat); Mat4MulVecfl(G.obedit->imat, curs); @@ -2432,26 +2433,47 @@ void fill_bones_armature(void) distB= VecLength(vecB); /* compare distances - closer one therefore acts as direction for bone to go */ - if (distA < distB) { - VECCOPY(head, ebp2->vec); - VECCOPY(tail, ebp->vec); - } - else { - VECCOPY(head, ebp->vec); - VECCOPY(tail, ebp2->vec); - } + headtail= (distA < distB) ? 2 : 1; } else if (ebp->head_owner) { + headtail = 1; + } + else if (ebp2->head_owner) { + headtail = 2; + } + + /* assign head/tail combinations */ + if (headtail == 1) { VECCOPY(head, ebp->vec); VECCOPY(tail, ebp2->vec); } - else if (ebp2->head_owner) { + else if (headtail == 2) { VECCOPY(head, ebp2->vec); VECCOPY(tail, ebp->vec); } - /* add new bone */ - newbone= add_points_bone(head, tail); + /* add new bone and parent it to the appropriate end */ + if (headtail) { + newbone= add_points_bone(head, tail); + + /* do parenting (will need to set connected flag too) */ + if (headtail == 1) { + /* ebp tail or head - tail gets priority */ + if (ebp->tail_owner) + newbone->parent= ebp->tail_owner; + else + newbone->parent= ebp->head_owner; + } + else { + /* ebp2 tail or head - tail gets priority */ + if (ebp2->tail_owner) + newbone->parent= ebp2->tail_owner; + else + newbone->parent= ebp2->head_owner; + } + + newbone->flag |= BONE_CONNECTED; + } } else { // FIXME.. figure out a method for multiple bones From fe7b591280ed1dec135d1cb95c5351dba4ec9d12 Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Thu, 29 May 2008 06:14:53 +0000 Subject: [PATCH 114/246] Another bugfix for Fill Bone Between Joints. Changed the order that bones are created between 'head'/'tail' points --- source/blender/src/editarmature.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source/blender/src/editarmature.c b/source/blender/src/editarmature.c index a68503b0d06..39f93510358 100644 --- a/source/blender/src/editarmature.c +++ b/source/blender/src/editarmature.c @@ -2443,11 +2443,11 @@ void fill_bones_armature(void) } /* assign head/tail combinations */ - if (headtail == 1) { + if (headtail == 2) { VECCOPY(head, ebp->vec); VECCOPY(tail, ebp2->vec); } - else if (headtail == 2) { + else if (headtail == 1) { VECCOPY(head, ebp2->vec); VECCOPY(tail, ebp->vec); } @@ -2457,7 +2457,7 @@ void fill_bones_armature(void) newbone= add_points_bone(head, tail); /* do parenting (will need to set connected flag too) */ - if (headtail == 1) { + if (headtail == 2) { /* ebp tail or head - tail gets priority */ if (ebp->tail_owner) newbone->parent= ebp->tail_owner; From f1d54f892b7480b746b6423d4388455fe7ede2b9 Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Thu, 29 May 2008 14:23:08 +0000 Subject: [PATCH 115/246] -= Collisions =- Getting some weird results on moving fast edges. This is a backup commit, will try another thing --- source/blender/blenkernel/intern/collision.c | 127 ++++++++++--------- 1 file changed, 66 insertions(+), 61 deletions(-) diff --git a/source/blender/blenkernel/intern/collision.c b/source/blender/blenkernel/intern/collision.c index 37784b43cf9..36cc37eab44 100644 --- a/source/blender/blenkernel/intern/collision.c +++ b/source/blender/blenkernel/intern/collision.c @@ -388,8 +388,8 @@ int cloth_get_collision_time ( double a[3], double b[3], double c[3], double d[3 printf("v3 x: %f, y: %f, z: %f\n", f[0], f[1], f[2]); printf("t^3: %lf, t^2: %lf, t^1: %lf, t^0: %lf\n", j, i, h, g); - */ - + +*/ // Solve cubic equation to determine times t1, t2, t3, when the collision will occur. if ( ABS ( j ) > DBL_EPSILON ) { @@ -453,6 +453,7 @@ int cloth_get_collision_time ( double a[3], double b[3], double c[3], double d[3 return num_sols; } + // w3 is not perfect void collision_compute_barycentric ( float pv[3], float p1[3], float p2[3], float p3[3], float *w1, float *w2, float *w3 ) { @@ -713,52 +714,43 @@ CollPair* cloth_collision ( ModifierData *md1, ModifierData *md2, BVHTreeOverlap } else { - // check for collision in the future - collpair->flag |= COLLISION_IN_FUTURE; + float w1, w2, w3, u1, u2, u3; + float v1[3], v2[3], relativeVelocity[3]; + + // calc relative velocity + + // compute barycentric coordinates for both collision points + collision_compute_barycentric ( collpair->pa, + verts1[collpair->ap1].txold, + verts1[collpair->ap2].txold, + verts1[collpair->ap3].txold, + &w1, &w2, &w3 ); + + // was: txold + collision_compute_barycentric ( collpair->pb, + collmd->current_x[collpair->bp1].co, + collmd->current_x[collpair->bp2].co, + collmd->current_x[collpair->bp3].co, + &u1, &u2, &u3 ); + + // Calculate relative "velocity". + collision_interpolateOnTriangle ( v1, verts1[collpair->ap1].tv, verts1[collpair->ap2].tv, verts1[collpair->ap3].tv, w1, w2, w3 ); + + collision_interpolateOnTriangle ( v2, collmd->current_v[collpair->bp1].co, collmd->current_v[collpair->bp2].co, collmd->current_v[collpair->bp3].co, u1, u2, u3 ); + + VECSUB ( relativeVelocity, v2, v1 ); + + if(sqrt(INPR(relativeVelocity, relativeVelocity)) >= distance) + { + // check for collision in the future + collpair->flag |= COLLISION_IN_FUTURE; + } } collpair++; } return collpair; } -int cloth_are_edges_adjacent ( ClothModifierData *clmd, CollisionModifierData *collmd, EdgeCollPair *edgecollpair ) -{ - Cloth *cloth1 = NULL; - ClothVertex *verts1 = NULL; - float temp[3]; - MVert *verts2 = collmd->current_x; // old x - - cloth1 = clmd->clothObject; - verts1 = cloth1->verts; - - VECSUB ( temp, verts1[edgecollpair->p11].txold, verts2[edgecollpair->p21].co ); - if ( ABS ( INPR ( temp, temp ) ) < ALMOST_ZERO ) - return 1; - - VECSUB ( temp, verts1[edgecollpair->p11].txold, verts2[edgecollpair->p22].co ); - if ( ABS ( INPR ( temp, temp ) ) < ALMOST_ZERO ) - return 1; - - VECSUB ( temp, verts1[edgecollpair->p12].txold, verts2[edgecollpair->p21].co ); - if ( ABS ( INPR ( temp, temp ) ) < ALMOST_ZERO ) - return 1; - - VECSUB ( temp, verts1[edgecollpair->p12].txold, verts2[edgecollpair->p22].co ); - if ( ABS ( INPR ( temp, temp ) ) < ALMOST_ZERO ) - return 1; - - VECSUB ( temp, verts1[edgecollpair->p11].txold, verts1[edgecollpair->p12].txold ); - if ( ABS ( INPR ( temp, temp ) ) < ALMOST_ZERO ) - return 1; - - VECSUB ( temp, verts2[edgecollpair->p21].co, verts2[edgecollpair->p22].co ); - if ( ABS ( INPR ( temp, temp ) ) < ALMOST_ZERO ) - return 1; - - - return 0; -} - int cloth_collision_response_moving( ClothModifierData *clmd, CollisionModifierData *collmd, CollPair *collpair, CollPair *collision_end ) { int result = 0; @@ -879,13 +871,18 @@ static float projectPointOntoLine(float *p, float *a, float *b) static void calculateEENormal(float *np1, float *np2, float *np3, float *np4,float *out_normal) { - float line1[33], line2[3]; + float line1[3], line2[3]; float length; VECSUB(line1, np2, np1); VECSUB(line2, np3, np1); + // printf("l1: %f, l1: %f, l2: %f, l2: %f\n", line1[0], line1[1], line2[0], line2[1]); + Crossf(out_normal, line1, line2); + + + length = Normalize(out_normal); if (length <= FLT_EPSILON) { // lines are collinear @@ -1102,10 +1099,9 @@ int cloth_collision_moving_edges ( ClothModifierData *clmd, CollisionModifierDat unsigned int i = 0, j = 0, k = 0; int numsolutions = 0; double x1[3], v1[3], x2[3], v2[3], x3[3], v3[3]; - double solution[3]; + double solution[3], solution2[3]; MVert *verts2 = collmd->current_x; // old x MVert *velocity2 = collmd->current_v; // velocity - float mintime = FLT_MAX; float distance; float triA[3][3], triB[3][3]; int result = 0; @@ -1189,17 +1185,15 @@ int cloth_collision_moving_edges ( ClothModifierData *clmd, CollisionModifierDat edgecollpair.p21 = collpair->bp1; edgecollpair.p22 = collpair->bp3; } - - if((edgecollpair.p11 == 3) && (edgecollpair.p12 == 6)) + /* + if((edgecollpair.p11 == 3) && (edgecollpair.p12 == 16)) printf("Ahier!\n"); - if((edgecollpair.p11 == 6) && (edgecollpair.p12 == 3)) + if((edgecollpair.p11 == 16) && (edgecollpair.p12 == 3)) printf("Ahier!\n"); + */ - if ( !cloth_are_edges_adjacent ( clmd, collmd, &edgecollpair ) ) + // if ( !cloth_are_edges_adjacent ( clmd, collmd, &edgecollpair ) ) { - // printf("Collision between:\n"); - // printf("p11: %d, p12: %d, p21: %d, p22: %d\n", edgecollpair.p11, edgecollpair.p12, edgecollpair.p21, edgecollpair.p22); - // always put coll points in p21/p22 VECSUB ( x1, verts1[edgecollpair.p12].txold, verts1[edgecollpair.p11].txold ); VECSUB ( v1, verts1[edgecollpair.p12].tv, verts1[edgecollpair.p11].tv ); @@ -1212,6 +1206,16 @@ int cloth_collision_moving_edges ( ClothModifierData *clmd, CollisionModifierDat numsolutions = cloth_get_collision_time ( x1, v1, x2, v2, x3, v3, solution ); + if((edgecollpair.p11 == 3 && edgecollpair.p12==16)|| (edgecollpair.p11==16 && edgecollpair.p12==3)) + { + if(edgecollpair.p21==6 || edgecollpair.p22 == 6) + { + printf("dist: %f, sol[k]: %lf, sol2[k]: %lf\n", distance, solution[k], solution2[k]); + printf("a1: %f, a2: %f, b1: %f, b2: %f\n", x1[0], x2[0], x3[0], v1[0]); + printf("b21: %d, b22: %d\n", edgecollpair.p21, edgecollpair.p22); + } + } + for ( k = 0; k < numsolutions; k++ ) { // printf("sol %d: %lf\n", k, solution[k]); @@ -1225,11 +1229,11 @@ int cloth_collision_moving_edges ( ClothModifierData *clmd, CollisionModifierDat float m1, m2; // move verts - VECADDS(triA[0], verts1[edgecollpair.p11].txold, verts1[edgecollpair.p11].tv, mintime); - VECADDS(triA[1], verts1[edgecollpair.p12].txold, verts1[edgecollpair.p12].tv, mintime); + VECADDS(triA[0], verts1[edgecollpair.p11].txold, verts1[edgecollpair.p11].tv, solution[k]); + VECADDS(triA[1], verts1[edgecollpair.p12].txold, verts1[edgecollpair.p12].tv, solution[k]); - VECADDS(triB[0], collmd->current_x[edgecollpair.p21].co, collmd->current_v[edgecollpair.p21].co, mintime); - VECADDS(triB[1], collmd->current_x[edgecollpair.p22].co, collmd->current_v[edgecollpair.p22].co, mintime); + VECADDS(triB[0], collmd->current_x[edgecollpair.p21].co, collmd->current_v[edgecollpair.p21].co, solution[k]); + VECADDS(triB[1], collmd->current_x[edgecollpair.p22].co, collmd->current_v[edgecollpair.p22].co, solution[k]); // TODO: check for collisions distance = edgedge_distance(triA[0], triA[1], triB[0], triB[1], &a, &b, out_normal); @@ -1255,13 +1259,14 @@ int cloth_collision_moving_edges ( ClothModifierData *clmd, CollisionModifierDat VECSUB(vrel_1_to_2, vrel_1_to_2, temp); out_normalVelocity = INPR(vrel_1_to_2, out_normal); - +/* + // this correction results in wrong normals sometimes? if(out_normalVelocity < 0.0) { out_normalVelocity*= -1.0; VecMulf(out_normal, -1.0); } - +*/ /* Inelastic repulsion impulse. */ // Calculate which normal velocity we need. @@ -1287,7 +1292,7 @@ int cloth_collision_moving_edges ( ClothModifierData *clmd, CollisionModifierDat { // missing from collision.hpp } - mintime = MIN2(mintime, (float)solution[k]); + // mintime = MIN2(mintime, (float)solution[k]); break; } @@ -1429,7 +1434,7 @@ int cloth_bvh_objcollisions_do ( ClothModifierData * clmd, CollisionModifierData } } } - +/* result += cloth_collision_moving ( clmd, collmd, collisions, collisions_index ); // apply impulses in parallel @@ -1448,7 +1453,7 @@ int cloth_bvh_objcollisions_do ( ClothModifierData * clmd, CollisionModifierData } } } - +*/ } } From 8e46d777f33ffb86b1ed4e43437f2f974be98a0d Mon Sep 17 00:00:00 2001 From: Martin Poirier Date: Thu, 29 May 2008 19:10:09 +0000 Subject: [PATCH 116/246] Transform Orientations Edit Bone and Pose Bone can now be used as transform orientations Also fix a bug with CTO comming from non-uniformally scaled meshes. --- source/blender/include/transform.h | 1 + source/blender/src/transform_manipulator.c | 49 ++------- source/blender/src/transform_orientations.c | 105 +++++++++++++++++++- 3 files changed, 111 insertions(+), 44 deletions(-) diff --git a/source/blender/include/transform.h b/source/blender/include/transform.h index 982a2f25df7..82adb1ac12a 100644 --- a/source/blender/include/transform.h +++ b/source/blender/include/transform.h @@ -515,6 +515,7 @@ int handleNDofInput(NDofInput *n, unsigned short event, short val); int manageObjectSpace(int confirm, int set); int manageMeshSpace(int confirm, int set); +int manageBoneSpace(int confirm, int set); /* Those two fill in mat and return non-zero on success */ int createSpaceNormal(float mat[3][3], float normal[3]); diff --git a/source/blender/src/transform_manipulator.c b/source/blender/src/transform_manipulator.c index 5c06aaea890..050360887b4 100644 --- a/source/blender/src/transform_manipulator.c +++ b/source/blender/src/transform_manipulator.c @@ -158,7 +158,7 @@ static void protectflag_to_drawflags(short protectflag, short *drawflags) } /* for pose mode */ -static void stats_pose(View3D *v3d, bPoseChannel *pchan, float *normal, float *plane) +static void stats_pose(View3D *v3d, bPoseChannel *pchan) { Bone *bone= pchan->bone; @@ -166,9 +166,6 @@ static void stats_pose(View3D *v3d, bPoseChannel *pchan, float *normal, float *p if (bone->flag & BONE_TRANSFORM) { calc_tw_center(pchan->pose_head); protectflag_to_drawflags(pchan->protectflag, &v3d->twdrawflag); - - VecAddf(normal, normal, pchan->pose_mat[2]); - VecAddf(plane, plane, pchan->pose_mat[1]); } } } @@ -349,26 +346,24 @@ int calc_manipulator_stats(ScrArea *sa) } } else if(ob && (ob->flag & OB_POSEMODE)) { - bArmature *arm= ob->data; + bArmature *arm = ob->data; bPoseChannel *pchan; int mode; if((ob->lay & G.vd->lay)==0) return 0; - mode= Trans.mode; - Trans.mode= TFM_ROTATION; // mislead counting bones... bah + mode = Trans.mode; + Trans.mode = TFM_ROTATION; // mislead counting bones... bah /* count total, we use same method as transform will do */ Trans.total= 0; count_bone_select(&Trans, arm, &arm->bonebase, 1); - totsel= Trans.total; + totsel = Trans.total; if(totsel) { /* use channels to get stats */ for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) { - stats_pose(v3d, pchan, normal, plane); + stats_pose(v3d, pchan); } - //VecMulf(normal, -1.0); - VecMulf(plane, -1.0); VecMulf(G.scene->twcent, 1.0f/(float)totsel); // centroid! Mat4MulVecfl(ob->obmat, G.scene->twcent); @@ -376,7 +371,7 @@ int calc_manipulator_stats(ScrArea *sa) Mat4MulVecfl(ob->obmat, G.scene->twmax); } /* restore, mode can be TFM_INIT */ - Trans.mode= mode; + Trans.mode = mode; } else if(G.f & (G_VERTEXPAINT + G_TEXTUREPAINT + G_WEIGHTPAINT + G_SCULPTMODE)) { ; @@ -433,7 +428,7 @@ int calc_manipulator_stats(ScrArea *sa) break; case V3D_MANIP_NORMAL: - if(G.obedit) { + if(G.obedit || ob->flag & OB_POSEMODE) { float mat[3][3]; int type; @@ -479,34 +474,6 @@ int calc_manipulator_stats(ScrArea *sa) } break; } - /* pose mode is a bit weird, so keep it separated */ - else if (ob->flag & OB_POSEMODE) - { - strcpy(t->spacename, "normal"); - if(normal[0]!=0.0 || normal[1]!=0.0 || normal[2]!=0.0) { - float imat[3][3], mat[3][3]; - - /* we need the transpose of the inverse for a normal... */ - Mat3CpyMat4(imat, ob->obmat); - - Mat3Inv(mat, imat); - Mat3Transp(mat); - Mat3MulVecfl(mat, normal); - Mat3MulVecfl(mat, plane); - - Normalize(normal); - if(0.0==Normalize(plane)) VECCOPY(plane, mat[1]); - - VECCOPY(mat[2], normal); - Crossf(mat[0], normal, plane); - Crossf(mat[1], mat[2], mat[0]); - - Mat4CpyMat3(v3d->twmat, mat); - Mat4Ortho(v3d->twmat); - - break; - } - } /* no break we define 'normal' as 'local' in Object mode */ case V3D_MANIP_LOCAL: strcpy(t->spacename, "local"); diff --git a/source/blender/src/transform_orientations.c b/source/blender/src/transform_orientations.c index 6696fcf95d6..9c7a2f67b89 100644 --- a/source/blender/src/transform_orientations.c +++ b/source/blender/src/transform_orientations.c @@ -27,6 +27,7 @@ #include "MEM_guardedalloc.h" #include "DNA_armature_types.h" +#include "DNA_action_types.h" #include "DNA_curve_types.h" #include "DNA_listBase.h" #include "DNA_object_types.h" @@ -68,11 +69,17 @@ void BIF_clearTransformOrientation(void) } void BIF_manageTransformOrientation(int confirm, int set) { + Object *ob = OBACT; int index = -1; if (G.obedit) { if (G.obedit->type == OB_MESH) index = manageMeshSpace(confirm, set); + else if (G.obedit->type == OB_ARMATURE) + index = manageBoneSpace(confirm, set); + } + else if (ob && (ob->flag & OB_POSEMODE)) { + index = manageBoneSpace(confirm, set); } else { index = manageObjectSpace(confirm, set); @@ -122,6 +129,31 @@ int confirmSpace(int set, char text[]) } } +int manageBoneSpace(int confirm, int set) { + float mat[3][3]; + float normal[3], plane[3]; + char name[36] = ""; + int index; + + getTransformOrientation(normal, plane, 0); + + if (confirm == 0 && confirmSpace(set, "Bone") == 0) { + return -1; + } + + if (createSpaceNormalTangent(mat, normal, plane) == 0) { + error("Cannot use zero-length bone"); + return -1; + } + + strcpy(name, "Bone"); + + /* Input name */ + sbutton(name, 1, 35, "name: "); + + index = addMatrixSpace(mat, name); + return index; +} int manageMeshSpace(int confirm, int set) { float mat[3][3]; @@ -363,6 +395,29 @@ void applyTransformOrientation() { } } +static int count_bone_select(bArmature *arm, ListBase *lb, int do_it) +{ + Bone *bone; + int do_next; + int total = 0; + + for(bone= lb->first; bone; bone= bone->next) { + bone->flag &= ~BONE_TRANSFORM; + do_next = do_it; + if(do_it) { + if(bone->layer & arm->layer) { + if (bone->flag & BONE_SELECTED) { + bone->flag |= BONE_TRANSFORM; + total++; + do_next= 0; // no transform on children if one parent bone is selected + } + } + } + total += count_bone_select(arm, &bone->childbase, do_next); + } + + return total; +} int getTransformOrientation(float normal[3], float plane[3], int activeOnly) { @@ -375,6 +430,14 @@ int getTransformOrientation(float normal[3], float plane[3], int activeOnly) if(G.obedit) { + float imat[3][3], mat[3][3]; + + /* we need the transpose of the inverse for a normal... */ + Mat3CpyMat4(imat, ob->obmat); + + Mat3Inv(mat, imat); + Mat3Transp(mat); + ob= G.obedit; if(G.obedit->type==OB_MESH) @@ -639,12 +702,48 @@ int getTransformOrientation(float normal[3], float plane[3], int activeOnly) } } - - Mat4Mul3Vecfl(G.obedit->obmat, plane); - Mat4Mul3Vecfl(G.obedit->obmat, normal); + + /* Vectors from edges don't need the special transpose inverse multiplication */ + if (result == ORIENTATION_EDGE) + { + Mat4Mul3Vecfl(ob->obmat, normal); + Mat4Mul3Vecfl(ob->obmat, plane); + } + else + { + Mat3MulVecfl(mat, normal); + Mat3MulVecfl(mat, plane); + } } else if(ob && (ob->flag & OB_POSEMODE)) { + bArmature *arm= ob->data; + bPoseChannel *pchan; + int totsel; + + totsel = count_bone_select(arm, &arm->bonebase, 1); + if(totsel) { + float imat[3][3], mat[3][3]; + + /* use channels to get stats */ + for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) { + if (pchan->bone && pchan->bone->flag & BONE_TRANSFORM) { + VecAddf(normal, normal, pchan->pose_mat[2]); + VecAddf(plane, plane, pchan->pose_mat[1]); + } + } + VecMulf(plane, -1.0); + + /* we need the transpose of the inverse for a normal... */ + Mat3CpyMat4(imat, ob->obmat); + + Mat3Inv(mat, imat); + Mat3Transp(mat); + Mat3MulVecfl(mat, normal); + Mat3MulVecfl(mat, plane); + + result = ORIENTATION_EDGE; + } } else if(G.f & (G_VERTEXPAINT + G_TEXTUREPAINT + G_WEIGHTPAINT + G_SCULPTMODE)) { From 6af06ecdd2b748507e3dad41055fdf41253b7493 Mon Sep 17 00:00:00 2001 From: Simon Clitherow Date: Thu, 29 May 2008 21:12:11 +0000 Subject: [PATCH 117/246] Reverted win installer to give 'current user' option only for Application Data. Added shfolder.lib linking for win9x SHGetFolderPath() support. --- config/win32-vc-config.py | 2 +- release/windows/installer/00.sconsblender.nsi | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/config/win32-vc-config.py b/config/win32-vc-config.py index 32b6597b5d5..02e5dbb7f8f 100644 --- a/config/win32-vc-config.py +++ b/config/win32-vc-config.py @@ -157,7 +157,7 @@ REL_CCFLAGS = ['-O2', '-DNDEBUG'] C_WARN = [] CC_WARN = [] -LLIBS = 'ws2_32 vfw32 winmm kernel32 user32 gdi32 comdlg32 advapi32 shell32 ole32 oleaut32 uuid' +LLIBS = 'ws2_32 vfw32 winmm kernel32 user32 gdi32 comdlg32 advapi32 shfolder shell32 ole32 oleaut32 uuid' PLATFORM_LINKFLAGS = ''' /SUBSYSTEM:CONSOLE diff --git a/release/windows/installer/00.sconsblender.nsi b/release/windows/installer/00.sconsblender.nsi index c4e504a5bff..338075c1b18 100644 --- a/release/windows/installer/00.sconsblender.nsi +++ b/release/windows/installer/00.sconsblender.nsi @@ -32,7 +32,7 @@ Name "Blender VERSION" !insertmacro MUI_PAGE_DIRECTORY Page custom DataLocation DataLocationOnLeave -Page custom AppDataChoice AppDataChoiceOnLeave +;Page custom AppDataChoice AppDataChoiceOnLeave Page custom PreMigrateUserSettings MigrateUserSettings !insertmacro MUI_PAGE_INSTFILES !insertmacro MUI_PAGE_FINISH @@ -271,7 +271,9 @@ Function DataLocationOnLeave StrCpy $SETUSERCONTEXT "false" ${NSD_GetState} $HWND_APPDATA $R0 ${If} $R0 == "1" - StrCpy $SETUSERCONTEXT "true" + ; FIXME: disabled 'all users' until fully multi-user compatible + ;StrCpy $SETUSERCONTEXT "true" + Call SetWinXPPathCurrentUser ${Else} ${NSD_GetState} $HWND_INSTDIR $R0 ${If} $R0 == "1" From da2d4904af51507fc211a0101f8e33306135e76a Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 30 May 2008 01:59:15 +0000 Subject: [PATCH 118/246] bugfix * scene.object.context and scene.object.selected had broken get_item funcs so scene.object.context[i] returned the wrong object. * aligning the view to an object (numpad*key), did not disable the ortho view grid. * long standing problem where opening a relative image would fail with no message. BLI_convertstringcode was returning a path with /../../'s that need to be cleaned before the path could be read, the path was also invalid from unix shell so its not a blender path reading problem. --- source/blender/blenlib/intern/util.c | 1 + source/blender/python/api2_2x/Scene.c | 27 ++++++++++++++++++++------- source/blender/src/view.c | 2 ++ 3 files changed, 23 insertions(+), 7 deletions(-) diff --git a/source/blender/blenlib/intern/util.c b/source/blender/blenlib/intern/util.c index c85849b5ed4..3610813f2da 100644 --- a/source/blender/blenlib/intern/util.c +++ b/source/blender/blenlib/intern/util.c @@ -1166,6 +1166,7 @@ int BLI_convertstringcode(char *path, const char *basepath) MEM_freeN(filepart); } + BLI_cleanup_file(NULL, tmp); strcpy(path, tmp); #ifdef WIN32 diff --git a/source/blender/python/api2_2x/Scene.c b/source/blender/python/api2_2x/Scene.c index 7ef351b1127..eba951b8813 100644 --- a/source/blender/python/api2_2x/Scene.c +++ b/source/blender/python/api2_2x/Scene.c @@ -1355,16 +1355,29 @@ static PyObject *SceneObSeq_item( BPy_SceneObSeq * self, int i ) for (base= scene->base.first; base && i!=index; base= base->next, index++) {} /* selected */ else if (self->mode==EXPP_OBSEQ_SELECTED) { - for (base= scene->base.first; base && i!=index; base= base->next) - if (base->flag & SELECT) - index++; + for (base= scene->base.first; base; base= base->next) { + if (base->flag & SELECT) { + if (i==index) { + break; + } else { + index++; + } + } + } } /* context */ else if (self->mode==EXPP_OBSEQ_CONTEXT) { - if (G.vd) - for (base= scene->base.first; base && i!=index; base= base->next) - if TESTBASE(base) - index++; + if (G.vd) { + for (base= scene->base.first; base; base= base->next) { + if (TESTBASE(base)) { + if (i==index) { + break; + } else { + index++; + } + } + } + } } if (!(base)) diff --git a/source/blender/src/view.c b/source/blender/src/view.c index 2904ca60a12..1e45f2bf3e0 100644 --- a/source/blender/src/view.c +++ b/source/blender/src/view.c @@ -1448,6 +1448,8 @@ void obmat_to_viewmat(Object *ob, short smooth) float bmat[4][4]; float tmat[3][3]; + G.vd->view= 0; /* dont show the grid */ + Mat4CpyMat4(bmat, ob->obmat); Mat4Ortho(bmat); Mat4Invert(G.vd->viewmat, bmat); From 2eb897e6db6099ef8a62969511eb72f0f75ff624 Mon Sep 17 00:00:00 2001 From: Martin Poirier Date: Fri, 30 May 2008 09:05:09 +0000 Subject: [PATCH 119/246] Fix crash with hidden bezier handles See Cambo, that's why we have module owners. --- source/blender/src/transform_conversions.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/src/transform_conversions.c b/source/blender/src/transform_conversions.c index 4be525f4945..dcebf6b7557 100644 --- a/source/blender/src/transform_conversions.c +++ b/source/blender/src/transform_conversions.c @@ -1365,7 +1365,7 @@ static void createTransCurveVerts(TransInfo *t) tail++; } if( propmode || - ((bezt->f1 & SELECT) && (G.f & G_HIDDENHANDLES)) || + ((bezt->f2 & SELECT) && (G.f & G_HIDDENHANDLES)) || ((bezt->f3 & SELECT) && (G.f & G_HIDDENHANDLES)==0) ) { VECCOPY(td->iloc, bezt->vec[2]); From 0caf1573d5b0893630788bd41809d56cc7dd187c Mon Sep 17 00:00:00 2001 From: Kent Mein Date: Fri, 30 May 2008 19:46:48 +0000 Subject: [PATCH 120/246] This is patch [#9053] More concrete makesdna reporting Submitted by gsr It just makes the printf's all different so you can tell where the problem is. Kent --- source/blender/makesdna/intern/makesdna.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/source/blender/makesdna/intern/makesdna.c b/source/blender/makesdna/intern/makesdna.c index 9b837f9f988..83f4e633fa1 100644 --- a/source/blender/makesdna/intern/makesdna.c +++ b/source/blender/makesdna/intern/makesdna.c @@ -688,18 +688,18 @@ static int calculate_structlens(int firststruct) /* 4-8 aligned/ */ if(sizeof(void *) == 4) { if (len % 4) { - printf("Align pointer error in struct: %s %s\n", types[structtype], cp); + printf("Align pointer error in struct (len4): %s %s\n", types[structtype], cp); dna_error = 1; } } else { if (len % 8) { - printf("Align pointer error in struct: %s %s\n", types[structtype], cp); + printf("Align pointer error in struct (len8): %s %s\n", types[structtype], cp); dna_error = 1; } } if (alphalen % 8) { - printf("Align pointer error in struct: %s %s\n", types[structtype],cp); + printf("Align pointer error in struct (alphalen8): %s %s\n", types[structtype],cp); dna_error = 1; } @@ -748,13 +748,13 @@ static int calculate_structlens(int firststruct) // has_pointer is set or alphalen != len if (has_pointer || alphalen != len) { if (alphalen % 8) { - printf("Sizeerror in struct: %s (add %d bytes)\n", types[structtype], alphalen%8); + printf("Sizeerror 8 in struct: %s (add %d bytes)\n", types[structtype], alphalen%8); dna_error = 1; } } if(len % 4) { - printf("Sizeerror in struct: %s (add %d bytes)\n", types[structtype], len%4); + printf("Sizeerror 4 in struct: %s (add %d bytes)\n", types[structtype], len%4); dna_error = 1; } From 791510f690ccf441d0de041129402b4b796c90c8 Mon Sep 17 00:00:00 2001 From: Kent Mein Date: Fri, 30 May 2008 19:52:42 +0000 Subject: [PATCH 121/246] This is patch [#9057] Updated doc string to match current defines also submitted by gsr It just updates a comment to correct values. Kent --- source/blender/render/extern/include/RE_raytrace.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/render/extern/include/RE_raytrace.h b/source/blender/render/extern/include/RE_raytrace.h index aec1c69b3dc..8f429f7dd90 100644 --- a/source/blender/render/extern/include/RE_raytrace.h +++ b/source/blender/render/extern/include/RE_raytrace.h @@ -70,7 +70,7 @@ typedef struct Isect { int ob_last; short isect; /* which half of quad */ - short mode; /* RE_RAYSHADOW, RE_RAYMIRROR, RE_RAYSHADOW_TRA */ + short mode; /* RE_RAY_SHADOW, RE_RAY_MIRROR, RE_RAY_SHADOW_TRA */ int lay; /* -1 default, set for layer lamps */ /* only used externally */ From 5c1acc5ced3ef9a312c9120a75d6021eb9464907 Mon Sep 17 00:00:00 2001 From: Willian Padovani Germano Date: Fri, 30 May 2008 20:04:52 +0000 Subject: [PATCH 122/246] == PyNodes == Bug #13277, reported by Juho (bebraw) Vepsalainen (thanks!) - a typo made pynodes w/o input socket definitions fail with an out of range error when accessing the output sockets in the script. --- source/blender/python/api2_2x/Node.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/python/api2_2x/Node.c b/source/blender/python/api2_2x/Node.c index 92529023b7e..792b2331508 100644 --- a/source/blender/python/api2_2x/Node.c +++ b/source/blender/python/api2_2x/Node.c @@ -848,7 +848,7 @@ static int Sockoutmap_assign_subscript(BPy_SockMap *self, PyObject *pyidx, PyObj if (PyInt_Check(pyidx)) { idx = (int)PyInt_AsLong(pyidx); - if (idx < 0 || idx >= Sockinmap_len(self)) + if (idx < 0 || idx >= Sockoutmap_len(self)) return EXPP_ReturnIntError(PyExc_IndexError, "index out of range"); } else if (PyString_Check(pyidx)) { From 57270125d8ff4f525514c9202bba6089a4ec11a4 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sat, 31 May 2008 12:12:03 +0000 Subject: [PATCH 123/246] bugfix for own error, introduced when running scripts were saved with the blend file. a script error with a script that has an interface would not stop the interface from running again immediately, causing an annoying error message loop. --- source/blender/python/api2_2x/Draw.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/source/blender/python/api2_2x/Draw.c b/source/blender/python/api2_2x/Draw.c index 3d4546613be..047a035fb8b 100644 --- a/source/blender/python/api2_2x/Draw.c +++ b/source/blender/python/api2_2x/Draw.c @@ -613,6 +613,8 @@ static void exit_pydraw( SpaceScript * sc, short err ) PyErr_Print( ); script->flags = 0; /* mark script struct for deletion */ SCRIPT_SET_NULL(script); + script->scriptname[0] = '\0'; + script->scriptarg[0] = '\0'; error_pyscript(); scrarea_queue_redraw( sc->area ); } From 32de0da6df27a0eebd76524d883f8fe80e3b4e56 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sat, 31 May 2008 16:22:07 +0000 Subject: [PATCH 124/246] bugfix * [#13394] Sequencer: if internal strips have handles selected, dragging the metastrip changes the meta length * Extend did not work correctly on metastrips when the nested seq's are out of the meta's frame range, added an argument to seq_tx_get_final_left/right that returns the frame clipped by metastrip(s) if any. --- source/blender/include/BIF_editseq.h | 4 +- source/blender/src/drawseq.c | 2 +- source/blender/src/editseq.c | 93 ++++++++++++++++++---------- 3 files changed, 64 insertions(+), 35 deletions(-) diff --git a/source/blender/include/BIF_editseq.h b/source/blender/include/BIF_editseq.h index 0d1e792eb1c..b353e7bb45c 100644 --- a/source/blender/include/BIF_editseq.h +++ b/source/blender/include/BIF_editseq.h @@ -92,8 +92,8 @@ start and end are from the start and fixed length of the sequence. int seq_tx_get_start(struct Sequence *seq); int seq_tx_get_end(struct Sequence *seq); -int seq_tx_get_final_left(struct Sequence *seq); -int seq_tx_get_final_right(struct Sequence *seq); +int seq_tx_get_final_left(struct Sequence *seq, int metaclip); +int seq_tx_get_final_right(struct Sequence *seq, int metaclip); void seq_tx_set_final_left(struct Sequence *seq, int i); void seq_tx_set_final_right(struct Sequence *seq, int i); diff --git a/source/blender/src/drawseq.c b/source/blender/src/drawseq.c index e979f6e16fc..e554b91dd52 100644 --- a/source/blender/src/drawseq.c +++ b/source/blender/src/drawseq.c @@ -691,7 +691,7 @@ static void draw_seq_strip(Sequence *seq, ScrArea *sa, SpaceSeq *sseq, int outli /* draw the main strip body */ if (is_single_image) /* single image */ - draw_shadedstrip(seq, col, seq_tx_get_final_left(seq), y1, seq_tx_get_final_right(seq), y2); + draw_shadedstrip(seq, col, seq_tx_get_final_left(seq, 0), y1, seq_tx_get_final_right(seq, 0), y2); else /* normal operation */ draw_shadedstrip(seq, col, x1, y1, x2, y2); diff --git a/source/blender/src/editseq.c b/source/blender/src/editseq.c index bb706f1aa3f..fb0fac4489d 100644 --- a/source/blender/src/editseq.c +++ b/source/blender/src/editseq.c @@ -184,13 +184,24 @@ int seq_tx_get_end(Sequence *seq) return seq->start+seq->len; } -int seq_tx_get_final_left(Sequence *seq) +int seq_tx_get_final_left(Sequence *seq, int metaclip) { - return (seq->start - seq->startstill) + seq->startofs; + if (metaclip && seq->tmp) { + /* return the range clipped by the parents range */ + return MAX2( seq_tx_get_final_left(seq, 0), seq_tx_get_final_left((Sequence *)seq->tmp, 1) ); + } else { + return (seq->start - seq->startstill) + seq->startofs; + } + } -int seq_tx_get_final_right(Sequence *seq) +int seq_tx_get_final_right(Sequence *seq, int metaclip) { - return ((seq->start+seq->len) + seq->endstill) - seq->endofs; + if (metaclip && seq->tmp) { + /* return the range clipped by the parents range */ + return MIN2( seq_tx_get_final_right(seq, 0), seq_tx_get_final_right((Sequence *)seq->tmp, 1) ); + } else { + return ((seq->start+seq->len) + seq->endstill) - seq->endofs; + } } void seq_tx_set_final_left(Sequence *seq, int val) @@ -260,12 +271,12 @@ static void fix_single_image_seq(Sequence *seq) /* make sure the image is always at the start since there is only one, adjusting its start should be ok */ - left = seq_tx_get_final_left(seq); + left = seq_tx_get_final_left(seq, 0); start = seq->start; if (start != left) { offset = left - start; - seq_tx_set_final_left( seq, seq_tx_get_final_left(seq) - offset ); - seq_tx_set_final_right( seq, seq_tx_get_final_right(seq) - offset ); + seq_tx_set_final_left( seq, seq_tx_get_final_left(seq, 0) - offset ); + seq_tx_set_final_right( seq, seq_tx_get_final_right(seq, 0) - offset ); seq->start += offset; } } @@ -2927,34 +2938,34 @@ static int seq_get_snaplimit(void) static void transform_grab_xlimits(Sequence *seq, int leftflag, int rightflag) { if(leftflag) { - if (seq_tx_get_final_left(seq) >= seq_tx_get_final_right(seq)) { - seq_tx_set_final_left(seq, seq_tx_get_final_right(seq)-1); + if (seq_tx_get_final_left(seq, 0) >= seq_tx_get_final_right(seq, 0)) { + seq_tx_set_final_left(seq, seq_tx_get_final_right(seq, 0)-1); } if (check_single_seq(seq)==0) { - if (seq_tx_get_final_left(seq) >= seq_tx_get_end(seq)) { + if (seq_tx_get_final_left(seq, 0) >= seq_tx_get_end(seq)) { seq_tx_set_final_left(seq, seq_tx_get_end(seq)-1); } /* dosnt work now - TODO */ /* - if (seq_tx_get_start(seq) >= seq_tx_get_final_right(seq)) { + if (seq_tx_get_start(seq) >= seq_tx_get_final_right(seq, 0)) { int ofs; - ofs = seq_tx_get_start(seq) - seq_tx_get_final_right(seq); + ofs = seq_tx_get_start(seq) - seq_tx_get_final_right(seq, 0); seq->start -= ofs; - seq_tx_set_final_left(seq, seq_tx_get_final_left(seq) + ofs ); + seq_tx_set_final_left(seq, seq_tx_get_final_left(seq, 0) + ofs ); }*/ } } if(rightflag) { - if (seq_tx_get_final_right(seq) <= seq_tx_get_final_left(seq)) { - seq_tx_set_final_right(seq, seq_tx_get_final_left(seq)+1); + if (seq_tx_get_final_right(seq, 0) <= seq_tx_get_final_left(seq, 0)) { + seq_tx_set_final_right(seq, seq_tx_get_final_left(seq, 0)+1); } if (check_single_seq(seq)==0) { - if (seq_tx_get_final_right(seq) <= seq_tx_get_start(seq)) { + if (seq_tx_get_final_right(seq, 0) <= seq_tx_get_start(seq)) { seq_tx_set_final_right(seq, seq_tx_get_start(seq)+1); } } @@ -3033,9 +3044,24 @@ void transform_seq(int mode, int context) for(seq_index=0, seq=seqar[0]; seq_index < totseq_index; seq=seqar[++seq_index]) { if((seq->flag & SELECT) && !(seq->depth==0 && seq->flag & SEQ_LOCK)) totstrip++; + /* only needed for extend but can set here anyway since were alredy looping */ + seq->tmp= NULL; } } + /* for extending we need the metastrip clipped left/right values, set the metastrips as parents in seq->tmp */ + if (mode=='e') { + Sequence *meta_seq; + for(seq_index=0, seq=seqar[0]; seq_index < totseq_index; seq=seqar[++seq_index]) { + if (seq->type == SEQ_META) { + for (meta_seq = seq->seqbase.first; meta_seq; meta_seq= meta_seq->next){ + meta_seq->tmp= (void *)seq; + } + } + } + } + + if (sseq->flag & SEQ_MARKER_TRANS) { for(marker= G.scene->markers.first; marker; marker= marker->next) { if(marker->flag & SELECT) totmark++; @@ -3064,8 +3090,8 @@ void transform_seq(int mode, int context) /* for extend only */ if (mode=='e') { - ts->final_left = seq_tx_get_final_left(seq); - ts->final_right = seq_tx_get_final_right(seq); + ts->final_left = seq_tx_get_final_left(seq, 1); + ts->final_right = seq_tx_get_final_right(seq, 1); } ts++; } @@ -3151,9 +3177,9 @@ void transform_seq(int mode, int context) snap_point_num=0; if (last_seq && (last_seq->flag & SELECT)) { /* active seq bounds */ if(seq_tx_check_left(last_seq)) - snap_points[snap_point_num++] = seq_tx_get_final_left(last_seq); + snap_points[snap_point_num++] = seq_tx_get_final_left(last_seq, 0); if(seq_tx_check_right(last_seq)) - snap_points[snap_point_num++] = seq_tx_get_final_right(last_seq); + snap_points[snap_point_num++] = seq_tx_get_final_right(last_seq, 0); } if (totstrip > 1) { /* selection bounds */ @@ -3163,9 +3189,9 @@ void transform_seq(int mode, int context) for(seq_index=0, seq=seqar[0]; seq_index < totseq_index; seq=seqar[++seq_index]) { if(seq->flag & SELECT) { if(seq_tx_check_left(seq)) - bounds_left = MIN2(bounds_left, seq_tx_get_final_left(seq)); + bounds_left = MIN2(bounds_left, seq_tx_get_final_left(seq, 0)); if(seq_tx_check_right(seq)) - bounds_right = MAX2(bounds_right,seq_tx_get_final_right(seq)); + bounds_right = MAX2(bounds_right,seq_tx_get_final_right(seq, 0)); } } @@ -3214,13 +3240,13 @@ void transform_seq(int mode, int context) if (snap_dist && last_seq && seq_tx_check_left(last_seq)) { seq = find_next_prev_sequence(last_seq, 1, 0); /* left */ if(seq && !seq_tx_check_right(seq)) - TESTSNAP(seq_tx_get_final_right(seq)); + TESTSNAP(seq_tx_get_final_right(seq, 0)); } if (snap_dist && last_seq && seq_tx_check_right(last_seq)) { seq = find_next_prev_sequence(last_seq, 2, 0); /* right */ if(seq && !seq_tx_check_left(seq)) - TESTSNAP(seq_tx_get_final_left(seq)); + TESTSNAP(seq_tx_get_final_left(seq, 0)); } #undef TESTSNAP @@ -3242,20 +3268,23 @@ void transform_seq(int mode, int context) for(seq_index=0, seq=seqar[0]; seq_index < totseq_index; seq=seqar[++seq_index]) { if(seq->flag & SELECT && !(seq->depth==0 && seq->flag & SEQ_LOCK)) { int myofs; + /* flag, ignores lefsel/rightsel for nested strips */ + int sel_flag = (seq->depth==0) ? seq->flag : seq->flag & ~(SEQ_LEFTSEL+SEQ_RIGHTSEL); + // SEQ_DEBUG_INFO(seq); /* X Transformation */ - if(seq->flag & SEQ_LEFTSEL) { + if((seq->depth==0) && (sel_flag & SEQ_LEFTSEL)) { myofs = (ts->startofs - ts->startstill); seq_tx_set_final_left(seq, ts->start + (myofs + ix)); } - if(seq->flag & SEQ_RIGHTSEL) { + if((seq->depth==0) && (sel_flag & SEQ_RIGHTSEL)) { myofs = (ts->endstill - ts->endofs); seq_tx_set_final_right(seq, ts->start + seq->len + (myofs + ix)); } - transform_grab_xlimits(seq, seq->flag & SEQ_LEFTSEL, seq->flag & SEQ_RIGHTSEL); + transform_grab_xlimits(seq, sel_flag & SEQ_LEFTSEL, sel_flag & SEQ_RIGHTSEL); - if( (seq->flag & (SEQ_LEFTSEL+SEQ_RIGHTSEL))==0 ) { + if( (sel_flag & (SEQ_LEFTSEL+SEQ_RIGHTSEL))==0 ) { if(sequence_is_free_transformable(seq)) seq->start= ts->start+ ix; /* Y Transformation */ @@ -3300,8 +3329,8 @@ void transform_seq(int mode, int context) //SEQ_DEBUG_INFO(seq); - final_left = seq_tx_get_final_left(seq); - final_right = seq_tx_get_final_right(seq); + final_left = seq_tx_get_final_left(seq, 1); + final_right = seq_tx_get_final_right(seq, 1); /* Only X Axis moving */ @@ -3591,8 +3620,8 @@ void seq_separate_images(void) BLI_remlink(ed->seqbasep, seq); if(seq->ipo) seq->ipo->id.us--; - start_ofs = cfra = seq_tx_get_final_left(seq); - frame_end = seq_tx_get_final_right(seq); + start_ofs = cfra = seq_tx_get_final_left(seq, 0); + frame_end = seq_tx_get_final_right(seq, 0); while (cfra < frame_end) { /* new seq */ From c6528b3cd4d3507c9ae5b9cfa70d832731d95aec Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sat, 31 May 2008 19:01:14 +0000 Subject: [PATCH 125/246] bufgfix for [#13584] SIGSEV in fluid bake with large amount of small fluid objects the maximum number of objects (255) wasnt being checked, added a check before baking. also changed bakeing to use G.scene->base rather then G.main->objects since these can be in other scenes, from linked groups, or used only by python so they should not be used for baking. it also meant having a domain in 2 scenes would fail with an error. Nils, could be good to have a dynamic number of bakeable objects. --- source/blender/src/fluidsim.c | 33 +++++++++++++++++++++++++++------ 1 file changed, 27 insertions(+), 6 deletions(-) diff --git a/source/blender/src/fluidsim.c b/source/blender/src/fluidsim.c index a7361a9ffca..8b9c89656fb 100644 --- a/source/blender/src/fluidsim.c +++ b/source/blender/src/fluidsim.c @@ -481,6 +481,7 @@ void fluidsimBake(struct Object *ob) struct Object *fsDomain = NULL; FluidsimSettings *domainSettings; struct Object *obit = NULL; /* object iterator */ + Base *base; int origFrame = G.scene->r.cfra; char debugStrBuffer[256]; int dirExist = 0; @@ -522,7 +523,7 @@ void fluidsimBake(struct Object *ob) float *channelObjMove[256][3]; // object movments , 0=trans, 1=rot, 2=scale float *channelObjInivel[256]; // initial velocities float *channelObjActive[256]; // obj active channel - + if(getenv(strEnvName)) { int dlevel = atoi(getenv(strEnvName)); elbeemSetDebugLevel(dlevel); @@ -545,7 +546,6 @@ void fluidsimBake(struct Object *ob) /* no object pointer, find in selected ones.. */ if(!ob) { - Base *base; for(base=G.scene->base.first; base; base= base->next) { if ( ((base)->flag & SELECT) // ignore layer setting for now? && ((base)->lay & G.vd->lay) @@ -561,8 +561,26 @@ void fluidsimBake(struct Object *ob) if(!ob) return; } + channelObjCount = 0; + for(base=G.scene->base.first; base; base= base->next) { + obit = base->object; + //{ snprintf(debugStrBuffer,256,"DEBUG object name=%s, type=%d ...\n", obit->id.name, obit->type); elbeemDebugOut(debugStrBuffer); } // DEBUG + if( (obit->fluidsimFlag & OB_FLUIDSIM_ENABLE) && + (obit->type==OB_MESH) && + (obit->fluidsimSettings->type != OB_FLUIDSIM_DOMAIN) && // if has to match 3 places! // CHECKMATCH + (obit->fluidsimSettings->type != OB_FLUIDSIM_PARTICLE) ) { + channelObjCount++; + } + } + + if (channelObjCount>=255) { + pupmenu("Fluidsim Bake Error%t|Cannot bake with more then 256 objects"); + return; + } + /* check if there's another domain... */ - for(obit= G.main->object.first; obit; obit= obit->id.next) { + for(base=G.scene->base.first; base; base= base->next) { + obit = base->object; if((obit->fluidsimFlag & OB_FLUIDSIM_ENABLE)&&(obit->type==OB_MESH)) { if(obit->fluidsimSettings->type == OB_FLUIDSIM_DOMAIN) { if(obit != ob) { @@ -605,7 +623,8 @@ void fluidsimBake(struct Object *ob) // check if theres any fluid // abort baking if not... - for(obit= G.main->object.first; obit; obit= obit->id.next) { + for(base=G.scene->base.first; base; base= base->next) { + obit = base->object; if( (obit->fluidsimFlag & OB_FLUIDSIM_ENABLE) && (obit->type==OB_MESH) && ( (obit->fluidsimSettings->type == OB_FLUIDSIM_FLUID) || @@ -749,7 +768,8 @@ void fluidsimBake(struct Object *ob) // init obj movement channels channelObjCount=0; - for(obit= G.main->object.first; obit; obit= obit->id.next) { + for(base=G.scene->base.first; base; base= base->next) { + obit = base->object; //{ snprintf(debugStrBuffer,256,"DEBUG object name=%s, type=%d ...\n", obit->id.name, obit->type); elbeemDebugOut(debugStrBuffer); } // DEBUG if( (obit->fluidsimFlag & OB_FLUIDSIM_ENABLE) && (obit->type==OB_MESH) && @@ -952,7 +972,8 @@ void fluidsimBake(struct Object *ob) // init objects channelObjCount = 0; - for(obit= G.main->object.first; obit; obit= obit->id.next) { + for(base=G.scene->base.first; base; base= base->next) { + obit = base->object; //{ snprintf(debugStrBuffer,256,"DEBUG object name=%s, type=%d ...\n", obit->id.name, obit->type); elbeemDebugOut(debugStrBuffer); } // DEBUG if( (obit->fluidsimFlag & OB_FLUIDSIM_ENABLE) && // if has to match 3 places! // CHECKMATCH (obit->type==OB_MESH) && From 526d9cc5fc9bd423815bddd0191fbafb82209f1e Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sat, 31 May 2008 19:08:12 +0000 Subject: [PATCH 126/246] bugfix for own error glitch when typing in / would ask the user to make a new directory. the last shash was being removed, then the "" path didnt exist and asked to create it. --- source/blender/src/filesel.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/src/filesel.c b/source/blender/src/filesel.c index 9689ffdafeb..2ba5745b19b 100644 --- a/source/blender/src/filesel.c +++ b/source/blender/src/filesel.c @@ -1591,7 +1591,7 @@ static void do_filesel_buttons(short event, SpaceFile *sfile) BLI_del_slash(butname); if(sfile->type & FILE_UNIX) { - if (!BLI_exists(butname)) { + if (butname[0] != '\0' && !BLI_exists(butname)) { if (okee("Makedir")) { BLI_recurdir_fileops(butname); if (!BLI_exists(butname)) parent(sfile); From 74903b77f48c9c2ec9c226fc6ae34381d258e47e Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Sat, 31 May 2008 21:23:57 +0000 Subject: [PATCH 127/246] Merging revisions 15020-15073 of https://svn.blender.org/svnroot/bf-blender/trunk/blender --- config/win32-vc-config.py | 2 +- release/windows/installer/00.sconsblender.nsi | 6 +- source/blender/blenkernel/intern/object.c | 9 +- source/blender/blenlib/intern/util.c | 1 + source/blender/include/BIF_editseq.h | 4 +- source/blender/include/transform.h | 1 + source/blender/makesdna/intern/makesdna.c | 10 +- source/blender/python/api2_2x/Draw.c | 2 + source/blender/python/api2_2x/Node.c | 2 +- source/blender/python/api2_2x/Scene.c | 27 +++-- source/blender/python/api2_2x/sceneRender.c | 10 +- .../render/extern/include/RE_raytrace.h | 2 +- .../blender/render/intern/source/pipeline.c | 1 + .../blender/render/intern/source/rayshade.c | 22 ++-- source/blender/src/drawobject.c | 83 +++++++++++--- source/blender/src/drawseq.c | 2 +- source/blender/src/drawview.c | 22 ++-- source/blender/src/editarmature.c | 46 ++++++-- source/blender/src/editseq.c | 93 ++++++++++------ source/blender/src/filesel.c | 2 +- source/blender/src/fluidsim.c | 33 +++++- source/blender/src/meshtools.c | 6 + source/blender/src/transform_conversions.c | 2 +- source/blender/src/transform_manipulator.c | 49 ++------ source/blender/src/transform_orientations.c | 105 +++++++++++++++++- source/blender/src/view.c | 2 + 26 files changed, 388 insertions(+), 156 deletions(-) diff --git a/config/win32-vc-config.py b/config/win32-vc-config.py index 32b6597b5d5..02e5dbb7f8f 100644 --- a/config/win32-vc-config.py +++ b/config/win32-vc-config.py @@ -157,7 +157,7 @@ REL_CCFLAGS = ['-O2', '-DNDEBUG'] C_WARN = [] CC_WARN = [] -LLIBS = 'ws2_32 vfw32 winmm kernel32 user32 gdi32 comdlg32 advapi32 shell32 ole32 oleaut32 uuid' +LLIBS = 'ws2_32 vfw32 winmm kernel32 user32 gdi32 comdlg32 advapi32 shfolder shell32 ole32 oleaut32 uuid' PLATFORM_LINKFLAGS = ''' /SUBSYSTEM:CONSOLE diff --git a/release/windows/installer/00.sconsblender.nsi b/release/windows/installer/00.sconsblender.nsi index c4e504a5bff..338075c1b18 100644 --- a/release/windows/installer/00.sconsblender.nsi +++ b/release/windows/installer/00.sconsblender.nsi @@ -32,7 +32,7 @@ Name "Blender VERSION" !insertmacro MUI_PAGE_DIRECTORY Page custom DataLocation DataLocationOnLeave -Page custom AppDataChoice AppDataChoiceOnLeave +;Page custom AppDataChoice AppDataChoiceOnLeave Page custom PreMigrateUserSettings MigrateUserSettings !insertmacro MUI_PAGE_INSTFILES !insertmacro MUI_PAGE_FINISH @@ -271,7 +271,9 @@ Function DataLocationOnLeave StrCpy $SETUSERCONTEXT "false" ${NSD_GetState} $HWND_APPDATA $R0 ${If} $R0 == "1" - StrCpy $SETUSERCONTEXT "true" + ; FIXME: disabled 'all users' until fully multi-user compatible + ;StrCpy $SETUSERCONTEXT "true" + Call SetWinXPPathCurrentUser ${Else} ${NSD_GetState} $HWND_INSTDIR $R0 ${If} $R0 == "1" diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index ab1bc5a2265..4f901ba7216 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -1614,7 +1614,7 @@ static void give_parvert(Object *par, int nr, float *vec) for(eve= em->verts.first; eve; eve= eve->next) { if(eve->keyindex==nr) { - memcpy(vec, eve->co, 12); + memcpy(vec, eve->co, sizeof(float)*3); break; } } @@ -1652,18 +1652,20 @@ static void give_parvert(Object *par, int nr, float *vec) Curve *cu; BPoint *bp; BezTriple *bezt; + int found= 0; cu= par->data; nu= cu->nurb.first; if(par==G.obedit) nu= editNurb.first; count= 0; - while(nu) { + while(nu && !found) { if((nu->type & 7)==CU_BEZIER) { bezt= nu->bezt; a= nu->pntsu; while(a--) { if(count==nr) { + found= 1; VECCOPY(vec, bezt->vec[1]); break; } @@ -1676,7 +1678,8 @@ static void give_parvert(Object *par, int nr, float *vec) a= nu->pntsu*nu->pntsv; while(a--) { if(count==nr) { - memcpy(vec, bp->vec, 12); + found= 1; + memcpy(vec, bp->vec, sizeof(float)*3); break; } count++; diff --git a/source/blender/blenlib/intern/util.c b/source/blender/blenlib/intern/util.c index c85849b5ed4..3610813f2da 100644 --- a/source/blender/blenlib/intern/util.c +++ b/source/blender/blenlib/intern/util.c @@ -1166,6 +1166,7 @@ int BLI_convertstringcode(char *path, const char *basepath) MEM_freeN(filepart); } + BLI_cleanup_file(NULL, tmp); strcpy(path, tmp); #ifdef WIN32 diff --git a/source/blender/include/BIF_editseq.h b/source/blender/include/BIF_editseq.h index 0d1e792eb1c..b353e7bb45c 100644 --- a/source/blender/include/BIF_editseq.h +++ b/source/blender/include/BIF_editseq.h @@ -92,8 +92,8 @@ start and end are from the start and fixed length of the sequence. int seq_tx_get_start(struct Sequence *seq); int seq_tx_get_end(struct Sequence *seq); -int seq_tx_get_final_left(struct Sequence *seq); -int seq_tx_get_final_right(struct Sequence *seq); +int seq_tx_get_final_left(struct Sequence *seq, int metaclip); +int seq_tx_get_final_right(struct Sequence *seq, int metaclip); void seq_tx_set_final_left(struct Sequence *seq, int i); void seq_tx_set_final_right(struct Sequence *seq, int i); diff --git a/source/blender/include/transform.h b/source/blender/include/transform.h index 982a2f25df7..82adb1ac12a 100644 --- a/source/blender/include/transform.h +++ b/source/blender/include/transform.h @@ -515,6 +515,7 @@ int handleNDofInput(NDofInput *n, unsigned short event, short val); int manageObjectSpace(int confirm, int set); int manageMeshSpace(int confirm, int set); +int manageBoneSpace(int confirm, int set); /* Those two fill in mat and return non-zero on success */ int createSpaceNormal(float mat[3][3], float normal[3]); diff --git a/source/blender/makesdna/intern/makesdna.c b/source/blender/makesdna/intern/makesdna.c index 9b837f9f988..83f4e633fa1 100644 --- a/source/blender/makesdna/intern/makesdna.c +++ b/source/blender/makesdna/intern/makesdna.c @@ -688,18 +688,18 @@ static int calculate_structlens(int firststruct) /* 4-8 aligned/ */ if(sizeof(void *) == 4) { if (len % 4) { - printf("Align pointer error in struct: %s %s\n", types[structtype], cp); + printf("Align pointer error in struct (len4): %s %s\n", types[structtype], cp); dna_error = 1; } } else { if (len % 8) { - printf("Align pointer error in struct: %s %s\n", types[structtype], cp); + printf("Align pointer error in struct (len8): %s %s\n", types[structtype], cp); dna_error = 1; } } if (alphalen % 8) { - printf("Align pointer error in struct: %s %s\n", types[structtype],cp); + printf("Align pointer error in struct (alphalen8): %s %s\n", types[structtype],cp); dna_error = 1; } @@ -748,13 +748,13 @@ static int calculate_structlens(int firststruct) // has_pointer is set or alphalen != len if (has_pointer || alphalen != len) { if (alphalen % 8) { - printf("Sizeerror in struct: %s (add %d bytes)\n", types[structtype], alphalen%8); + printf("Sizeerror 8 in struct: %s (add %d bytes)\n", types[structtype], alphalen%8); dna_error = 1; } } if(len % 4) { - printf("Sizeerror in struct: %s (add %d bytes)\n", types[structtype], len%4); + printf("Sizeerror 4 in struct: %s (add %d bytes)\n", types[structtype], len%4); dna_error = 1; } diff --git a/source/blender/python/api2_2x/Draw.c b/source/blender/python/api2_2x/Draw.c index 3d4546613be..047a035fb8b 100644 --- a/source/blender/python/api2_2x/Draw.c +++ b/source/blender/python/api2_2x/Draw.c @@ -613,6 +613,8 @@ static void exit_pydraw( SpaceScript * sc, short err ) PyErr_Print( ); script->flags = 0; /* mark script struct for deletion */ SCRIPT_SET_NULL(script); + script->scriptname[0] = '\0'; + script->scriptarg[0] = '\0'; error_pyscript(); scrarea_queue_redraw( sc->area ); } diff --git a/source/blender/python/api2_2x/Node.c b/source/blender/python/api2_2x/Node.c index 92529023b7e..792b2331508 100644 --- a/source/blender/python/api2_2x/Node.c +++ b/source/blender/python/api2_2x/Node.c @@ -848,7 +848,7 @@ static int Sockoutmap_assign_subscript(BPy_SockMap *self, PyObject *pyidx, PyObj if (PyInt_Check(pyidx)) { idx = (int)PyInt_AsLong(pyidx); - if (idx < 0 || idx >= Sockinmap_len(self)) + if (idx < 0 || idx >= Sockoutmap_len(self)) return EXPP_ReturnIntError(PyExc_IndexError, "index out of range"); } else if (PyString_Check(pyidx)) { diff --git a/source/blender/python/api2_2x/Scene.c b/source/blender/python/api2_2x/Scene.c index 7ef351b1127..eba951b8813 100644 --- a/source/blender/python/api2_2x/Scene.c +++ b/source/blender/python/api2_2x/Scene.c @@ -1355,16 +1355,29 @@ static PyObject *SceneObSeq_item( BPy_SceneObSeq * self, int i ) for (base= scene->base.first; base && i!=index; base= base->next, index++) {} /* selected */ else if (self->mode==EXPP_OBSEQ_SELECTED) { - for (base= scene->base.first; base && i!=index; base= base->next) - if (base->flag & SELECT) - index++; + for (base= scene->base.first; base; base= base->next) { + if (base->flag & SELECT) { + if (i==index) { + break; + } else { + index++; + } + } + } } /* context */ else if (self->mode==EXPP_OBSEQ_CONTEXT) { - if (G.vd) - for (base= scene->base.first; base && i!=index; base= base->next) - if TESTBASE(base) - index++; + if (G.vd) { + for (base= scene->base.first; base; base= base->next) { + if (TESTBASE(base)) { + if (i==index) { + break; + } else { + index++; + } + } + } + } } if (!(base)) diff --git a/source/blender/python/api2_2x/sceneRender.c b/source/blender/python/api2_2x/sceneRender.c index f54c2cd4e3b..bfad069f943 100644 --- a/source/blender/python/api2_2x/sceneRender.c +++ b/source/blender/python/api2_2x/sceneRender.c @@ -478,9 +478,11 @@ PyObject *RenderData_Render( BPy_RenderData * self ) } else { /* background mode (blender -b file.blend -P script) */ - Render *re= RE_NewRender("Render"); + Render *re= RE_NewRender(G.scene->id.name); - int end_frame = G.scene->r.efra; /* is of type short currently */ + + + int end_frame = G.scene->r.efra; if (G.scene != self->scene) return EXPP_ReturnPyObjError (PyExc_RuntimeError, @@ -490,7 +492,7 @@ PyObject *RenderData_Render( BPy_RenderData * self ) RE_BlenderAnim(re, G.scene, G.scene->r.sfra, G.scene->r.efra); - G.scene->r.efra = (short)end_frame; + G.scene->r.efra = end_frame; } Py_RETURN_NONE; @@ -571,7 +573,7 @@ PyObject *RenderData_RenderAnim( BPy_RenderData * self ) set_scene( oldsce ); } else { /* background mode (blender -b file.blend -P script) */ - Render *re= RE_NewRender("Render"); + Render *re= RE_NewRender(G.scene->id.name); if (G.scene != self->scene) return EXPP_ReturnPyObjError (PyExc_RuntimeError, diff --git a/source/blender/render/extern/include/RE_raytrace.h b/source/blender/render/extern/include/RE_raytrace.h index aec1c69b3dc..8f429f7dd90 100644 --- a/source/blender/render/extern/include/RE_raytrace.h +++ b/source/blender/render/extern/include/RE_raytrace.h @@ -70,7 +70,7 @@ typedef struct Isect { int ob_last; short isect; /* which half of quad */ - short mode; /* RE_RAYSHADOW, RE_RAYMIRROR, RE_RAYSHADOW_TRA */ + short mode; /* RE_RAY_SHADOW, RE_RAY_MIRROR, RE_RAY_SHADOW_TRA */ int lay; /* -1 default, set for layer lamps */ /* only used externally */ diff --git a/source/blender/render/intern/source/pipeline.c b/source/blender/render/intern/source/pipeline.c index fb699f5b382..ebb52c49132 100644 --- a/source/blender/render/intern/source/pipeline.c +++ b/source/blender/render/intern/source/pipeline.c @@ -993,6 +993,7 @@ RenderStats *RE_GetStats(Render *re) return &re->i; } +/* Note, when rendering from a scene, ALWAYS use G.scene->id.name, else compositing wont work */ Render *RE_NewRender(const char *name) { Render *re; diff --git a/source/blender/render/intern/source/rayshade.c b/source/blender/render/intern/source/rayshade.c index 8fd07001bd1..1155d2ea817 100644 --- a/source/blender/render/intern/source/rayshade.c +++ b/source/blender/render/intern/source/rayshade.c @@ -1473,14 +1473,15 @@ static float *sphere_sampler(int type, int resol, int thread, int xs, int ys) int tot; float *vec; - if(resol>16) resol= 16; - tot= 2*resol*resol; if (type & WO_AORNDSMP) { - static float sphere[2*3*256]; + float *sphere; int a; + // always returns table + sphere= threadsafe_table_sphere(0, thread, xs, ys, tot); + /* total random sampling. NOT THREADSAFE! (should be removed, is not useful) */ vec= sphere; for (a=0; avlr; isec.oborig= RAY_OBJECT_SET(&R, shi->obi); @@ -1690,14 +1692,16 @@ void ray_ao_spheresamp(ShadeInput *shi, float *shadfac) if(shi->mat->mode & MA_ONLYSHADOW) aocolor= WO_AOPLAIN; - vec= sphere_sampler(R.wrld.aomode, R.wrld.aosamp, shi->thread, shi->xs, shi->ys); + if(resol>32) resol= 32; + + vec= sphere_sampler(R.wrld.aomode, resol, shi->thread, shi->xs, shi->ys); // warning: since we use full sphere now, and dotproduct is below, we do twice as much - tot= 2*R.wrld.aosamp*R.wrld.aosamp; + tot= 2*resol*resol; if(aocolor == WO_AOSKYTEX) { - dxyview[0]= 1.0f/(float)R.wrld.aosamp; - dxyview[1]= 1.0f/(float)R.wrld.aosamp; + dxyview[0]= 1.0f/(float)resol; + dxyview[1]= 1.0f/(float)resol; dxyview[2]= 0.0f; } diff --git a/source/blender/src/drawobject.c b/source/blender/src/drawobject.c index 0b042fc542f..0bb9e5f9e55 100644 --- a/source/blender/src/drawobject.c +++ b/source/blender/src/drawobject.c @@ -2922,7 +2922,7 @@ static void draw_new_particle_system(Base *base, ParticleSystem *psys, int dt) float *vdata=0, *vedata=0, *cdata=0, *ndata=0, *vd=0, *ved=0, *cd=0, *nd=0, xvec[3], yvec[3], zvec[3]; int a, k, k_max=0, totpart, totpoint=0, draw_as, path_nbr=0; int path_possible=0, keys_possible=0, draw_keys=0, totchild=0; - int select=ob->flag&SELECT; + int select=ob->flag&SELECT, create_cdata=0; GLint polygonmode[2]; char val[32]; @@ -2976,8 +2976,10 @@ static void draw_new_particle_system(Base *base, ParticleSystem *psys, int dt) if(select) cpack(0xFFFFFF); - else if((ma) && (part->draw&PART_DRAW_MAT_COL)) + else if((ma) && (part->draw&PART_DRAW_MAT_COL)) { glColor3f(ma->r,ma->g,ma->b); + create_cdata = 1; + } else cpack(0); @@ -3085,19 +3087,25 @@ static void draw_new_particle_system(Base *base, ParticleSystem *psys, int dt) if(draw_as!=PART_DRAW_CIRC){ switch(draw_as){ case PART_DRAW_AXIS: - cdata=MEM_callocN((totpart+totchild)*(path_nbr+1)*6*3*sizeof(float), "particle_cdata"); - /* no break! */ case PART_DRAW_CROSS: + if(draw_as!=PART_DRAW_CROSS || create_cdata) + cdata=MEM_callocN((totpart+totchild)*(path_nbr+1)*6*3*sizeof(float), "particle_cdata"); vdata=MEM_callocN((totpart+totchild)*(path_nbr+1)*6*3*sizeof(float), "particle_vdata"); break; case PART_DRAW_LINE: + if(create_cdata) + cdata=MEM_callocN((totpart+totchild)*(path_nbr+1)*2*3*sizeof(float), "particle_cdata"); vdata=MEM_callocN((totpart+totchild)*(path_nbr+1)*2*3*sizeof(float), "particle_vdata"); break; case PART_DRAW_BB: + if(create_cdata) + cdata=MEM_callocN((totpart+totchild)*(path_nbr+1)*4*3*sizeof(float), "particle_cdata"); vdata=MEM_callocN((totpart+totchild)*(path_nbr+1)*4*3*sizeof(float), "particle_vdata"); ndata=MEM_callocN((totpart+totchild)*(path_nbr+1)*4*3*sizeof(float), "particle_vdata"); break; default: + if(create_cdata) + cdata=MEM_callocN((totpart+totchild)*(path_nbr+1)*3*sizeof(float), "particle_cdata"); vdata=MEM_callocN((totpart+totchild)*(path_nbr+1)*3*sizeof(float), "particle_vdata"); } } @@ -3122,9 +3130,17 @@ static void draw_new_particle_system(Base *base, ParticleSystem *psys, int dt) pa_time=(cfra-pa->time)/pa->lifetime; - if((part->flag&PART_ABS_TIME)==0 && part->ipo){ - calc_ipo(part->ipo, 100*pa_time); - execute_ipo((ID *)part, part->ipo); + if((part->flag&PART_ABS_TIME)==0){ + if(ma && ma->ipo){ + /* correction for lifetime */ + calc_ipo(ma->ipo, 100.0f*pa_time); + execute_ipo((ID *)ma, ma->ipo); + } + if(part->ipo) { + /* correction for lifetime */ + calc_ipo(part->ipo, 100*pa_time); + execute_ipo((ID *)part, part->ipo); + } } pa_size=pa->size; @@ -3141,9 +3157,17 @@ static void draw_new_particle_system(Base *base, ParticleSystem *psys, int dt) pa_time=psys_get_child_time(psys,cpa,cfra); - if((part->flag&PART_ABS_TIME)==0 && part->ipo){ - calc_ipo(part->ipo, 100*pa_time); - execute_ipo((ID *)part, part->ipo); + if((part->flag&PART_ABS_TIME)==0) { + if(ma && ma->ipo){ + /* correction for lifetime */ + calc_ipo(ma->ipo, 100.0f*pa_time); + execute_ipo((ID *)ma, ma->ipo); + } + if(part->ipo) { + /* correction for lifetime */ + calc_ipo(part->ipo, 100*pa_time); + execute_ipo((ID *)part, part->ipo); + } } pa_size=psys_get_child_size(psys,cpa,cfra,0); @@ -3181,6 +3205,12 @@ static void draw_new_particle_system(Base *base, ParticleSystem *psys, int dt) switch(draw_as){ case PART_DRAW_DOT: + if(cd) { + cd[0]=ma->r; + cd[1]=ma->g; + cd[2]=ma->b; + cd+=3; + } if(vd){ VECCOPY(vd,state.co) vd+=3; } @@ -3201,7 +3231,15 @@ static void draw_new_particle_system(Base *base, ParticleSystem *psys, int dt) VECCOPY(vec2,state.co); } - else VECSUB(vec2,state.co,vec); + else { + if(cd) { + cd[0]=cd[3]=cd[6]=cd[9]=cd[12]=cd[15]=ma->r; + cd[1]=cd[4]=cd[7]=cd[10]=cd[13]=cd[16]=ma->g; + cd[2]=cd[5]=cd[8]=cd[11]=cd[14]=cd[17]=ma->b; + cd+=18; + } + VECSUB(vec2,state.co,vec); + } VECADD(vec,state.co,vec); VECCOPY(vd,vec); vd+=3; @@ -3239,11 +3277,25 @@ static void draw_new_particle_system(Base *base, ParticleSystem *psys, int dt) VecMulf(vec,VecLength(state.vel)); VECADDFAC(vd,state.co,vec,-part->draw_line[0]); vd+=3; VECADDFAC(vd,state.co,vec,part->draw_line[1]); vd+=3; + if(cd) { + cd[0]=cd[3]=ma->r; + cd[1]=cd[4]=ma->g; + cd[2]=cd[5]=ma->b; + cd+=3; + } break; case PART_DRAW_CIRC: + if(create_cdata) + glColor3f(ma->r,ma->g,ma->b); drawcircball(GL_LINE_LOOP, state.co, pixsize, imat); break; case PART_DRAW_BB: + if(cd) { + cd[0]=cd[3]=cd[6]=cd[9]=ma->r; + cd[1]=cd[4]=cd[7]=cd[10]=ma->g; + cd[2]=cd[5]=cd[8]=cd[11]=ma->b; + cd+=12; + } if(part->draw&PART_DRAW_BB_LOCK && part->bb_align==PART_BB_VIEW){ VECCOPY(xvec,bb_ob->obmat[0]); Normalize(xvec); @@ -3439,13 +3491,14 @@ static void draw_new_particle_system(Base *base, ParticleSystem *psys, int dt) glDisable(GL_LIGHTING); } + if(cdata){ + glEnableClientState(GL_COLOR_ARRAY); + glColorPointer(3, GL_FLOAT, 0, cdata); + } + switch(draw_as){ case PART_DRAW_AXIS: case PART_DRAW_CROSS: - if(cdata){ - glEnableClientState(GL_COLOR_ARRAY); - glColorPointer(3, GL_FLOAT, 0, cdata); - } glDrawArrays(GL_LINES, 0, 6*totpoint); break; case PART_DRAW_LINE: diff --git a/source/blender/src/drawseq.c b/source/blender/src/drawseq.c index e979f6e16fc..e554b91dd52 100644 --- a/source/blender/src/drawseq.c +++ b/source/blender/src/drawseq.c @@ -691,7 +691,7 @@ static void draw_seq_strip(Sequence *seq, ScrArea *sa, SpaceSeq *sseq, int outli /* draw the main strip body */ if (is_single_image) /* single image */ - draw_shadedstrip(seq, col, seq_tx_get_final_left(seq), y1, seq_tx_get_final_right(seq), y2); + draw_shadedstrip(seq, col, seq_tx_get_final_left(seq, 0), y1, seq_tx_get_final_right(seq, 0), y2); else /* normal operation */ draw_shadedstrip(seq, col, x1, y1, x2, y2); diff --git a/source/blender/src/drawview.c b/source/blender/src/drawview.c index 52e0d3d6f05..e83ecb13960 100644 --- a/source/blender/src/drawview.c +++ b/source/blender/src/drawview.c @@ -3732,18 +3732,22 @@ int play_anim(int mode) else viewmove(0); } } else if (event==WHEELDOWNMOUSE || (val && event==PADMINUS)) { /* copied from persptoetsen */ - /* this min and max is also in viewmove() */ - if(G.vd->persp==V3D_CAMOB) { - G.vd->camzoom-= 10; - if(G.vd->camzoom<-30) G.vd->camzoom= -30; + if (G.vd) { /* when using the sequencer this can be NULL */ + /* this min and max is also in viewmove() */ + if(G.vd->persp==V3D_CAMOB) { + G.vd->camzoom-= 10; + if(G.vd->camzoom<-30) G.vd->camzoom= -30; + } + else if(G.vd->dist<10.0*G.vd->far) G.vd->dist*=1.2f; } - else if(G.vd->dist<10.0*G.vd->far) G.vd->dist*=1.2f; } else if (event==WHEELUPMOUSE || (val && event==PADPLUSKEY)) { /* copied from persptoetsen */ - if(G.vd->persp==V3D_CAMOB) { - G.vd->camzoom+= 10; - if(G.vd->camzoom>300) G.vd->camzoom= 300; + if (G.vd) { + if(G.vd->persp==V3D_CAMOB) { + G.vd->camzoom+= 10; + if(G.vd->camzoom>300) G.vd->camzoom= 300; + } + else if(G.vd->dist> 0.001*G.vd->grid) G.vd->dist*=.83333f; } - else if(G.vd->dist> 0.001*G.vd->grid) G.vd->dist*=.83333f; } else if(event==MKEY) { if(val) add_marker(CFRA-1); } diff --git a/source/blender/src/editarmature.c b/source/blender/src/editarmature.c index c166a9df762..39f93510358 100644 --- a/source/blender/src/editarmature.c +++ b/source/blender/src/editarmature.c @@ -2396,6 +2396,7 @@ void fill_bones_armature(void) else if (count == 2) { EditBonePoint *ebp, *ebp2; float head[3], tail[3]; + short headtail = 0; /* check that the points don't belong to the same bone */ ebp= (EditBonePoint *)points.first; @@ -2420,7 +2421,7 @@ void fill_bones_armature(void) float distA, distB; /* get cursor location */ - VECCOPY (curs, give_cursor()); + VECCOPY(curs, give_cursor()); Mat4Invert(G.obedit->imat, G.obedit->obmat); Mat4MulVecfl(G.obedit->imat, curs); @@ -2432,26 +2433,47 @@ void fill_bones_armature(void) distB= VecLength(vecB); /* compare distances - closer one therefore acts as direction for bone to go */ - if (distA < distB) { - VECCOPY(head, ebp2->vec); - VECCOPY(tail, ebp->vec); - } - else { - VECCOPY(head, ebp->vec); - VECCOPY(tail, ebp2->vec); - } + headtail= (distA < distB) ? 2 : 1; } else if (ebp->head_owner) { + headtail = 1; + } + else if (ebp2->head_owner) { + headtail = 2; + } + + /* assign head/tail combinations */ + if (headtail == 2) { VECCOPY(head, ebp->vec); VECCOPY(tail, ebp2->vec); } - else if (ebp2->head_owner) { + else if (headtail == 1) { VECCOPY(head, ebp2->vec); VECCOPY(tail, ebp->vec); } - /* add new bone */ - newbone= add_points_bone(head, tail); + /* add new bone and parent it to the appropriate end */ + if (headtail) { + newbone= add_points_bone(head, tail); + + /* do parenting (will need to set connected flag too) */ + if (headtail == 2) { + /* ebp tail or head - tail gets priority */ + if (ebp->tail_owner) + newbone->parent= ebp->tail_owner; + else + newbone->parent= ebp->head_owner; + } + else { + /* ebp2 tail or head - tail gets priority */ + if (ebp2->tail_owner) + newbone->parent= ebp2->tail_owner; + else + newbone->parent= ebp2->head_owner; + } + + newbone->flag |= BONE_CONNECTED; + } } else { // FIXME.. figure out a method for multiple bones diff --git a/source/blender/src/editseq.c b/source/blender/src/editseq.c index bb706f1aa3f..fb0fac4489d 100644 --- a/source/blender/src/editseq.c +++ b/source/blender/src/editseq.c @@ -184,13 +184,24 @@ int seq_tx_get_end(Sequence *seq) return seq->start+seq->len; } -int seq_tx_get_final_left(Sequence *seq) +int seq_tx_get_final_left(Sequence *seq, int metaclip) { - return (seq->start - seq->startstill) + seq->startofs; + if (metaclip && seq->tmp) { + /* return the range clipped by the parents range */ + return MAX2( seq_tx_get_final_left(seq, 0), seq_tx_get_final_left((Sequence *)seq->tmp, 1) ); + } else { + return (seq->start - seq->startstill) + seq->startofs; + } + } -int seq_tx_get_final_right(Sequence *seq) +int seq_tx_get_final_right(Sequence *seq, int metaclip) { - return ((seq->start+seq->len) + seq->endstill) - seq->endofs; + if (metaclip && seq->tmp) { + /* return the range clipped by the parents range */ + return MIN2( seq_tx_get_final_right(seq, 0), seq_tx_get_final_right((Sequence *)seq->tmp, 1) ); + } else { + return ((seq->start+seq->len) + seq->endstill) - seq->endofs; + } } void seq_tx_set_final_left(Sequence *seq, int val) @@ -260,12 +271,12 @@ static void fix_single_image_seq(Sequence *seq) /* make sure the image is always at the start since there is only one, adjusting its start should be ok */ - left = seq_tx_get_final_left(seq); + left = seq_tx_get_final_left(seq, 0); start = seq->start; if (start != left) { offset = left - start; - seq_tx_set_final_left( seq, seq_tx_get_final_left(seq) - offset ); - seq_tx_set_final_right( seq, seq_tx_get_final_right(seq) - offset ); + seq_tx_set_final_left( seq, seq_tx_get_final_left(seq, 0) - offset ); + seq_tx_set_final_right( seq, seq_tx_get_final_right(seq, 0) - offset ); seq->start += offset; } } @@ -2927,34 +2938,34 @@ static int seq_get_snaplimit(void) static void transform_grab_xlimits(Sequence *seq, int leftflag, int rightflag) { if(leftflag) { - if (seq_tx_get_final_left(seq) >= seq_tx_get_final_right(seq)) { - seq_tx_set_final_left(seq, seq_tx_get_final_right(seq)-1); + if (seq_tx_get_final_left(seq, 0) >= seq_tx_get_final_right(seq, 0)) { + seq_tx_set_final_left(seq, seq_tx_get_final_right(seq, 0)-1); } if (check_single_seq(seq)==0) { - if (seq_tx_get_final_left(seq) >= seq_tx_get_end(seq)) { + if (seq_tx_get_final_left(seq, 0) >= seq_tx_get_end(seq)) { seq_tx_set_final_left(seq, seq_tx_get_end(seq)-1); } /* dosnt work now - TODO */ /* - if (seq_tx_get_start(seq) >= seq_tx_get_final_right(seq)) { + if (seq_tx_get_start(seq) >= seq_tx_get_final_right(seq, 0)) { int ofs; - ofs = seq_tx_get_start(seq) - seq_tx_get_final_right(seq); + ofs = seq_tx_get_start(seq) - seq_tx_get_final_right(seq, 0); seq->start -= ofs; - seq_tx_set_final_left(seq, seq_tx_get_final_left(seq) + ofs ); + seq_tx_set_final_left(seq, seq_tx_get_final_left(seq, 0) + ofs ); }*/ } } if(rightflag) { - if (seq_tx_get_final_right(seq) <= seq_tx_get_final_left(seq)) { - seq_tx_set_final_right(seq, seq_tx_get_final_left(seq)+1); + if (seq_tx_get_final_right(seq, 0) <= seq_tx_get_final_left(seq, 0)) { + seq_tx_set_final_right(seq, seq_tx_get_final_left(seq, 0)+1); } if (check_single_seq(seq)==0) { - if (seq_tx_get_final_right(seq) <= seq_tx_get_start(seq)) { + if (seq_tx_get_final_right(seq, 0) <= seq_tx_get_start(seq)) { seq_tx_set_final_right(seq, seq_tx_get_start(seq)+1); } } @@ -3033,9 +3044,24 @@ void transform_seq(int mode, int context) for(seq_index=0, seq=seqar[0]; seq_index < totseq_index; seq=seqar[++seq_index]) { if((seq->flag & SELECT) && !(seq->depth==0 && seq->flag & SEQ_LOCK)) totstrip++; + /* only needed for extend but can set here anyway since were alredy looping */ + seq->tmp= NULL; } } + /* for extending we need the metastrip clipped left/right values, set the metastrips as parents in seq->tmp */ + if (mode=='e') { + Sequence *meta_seq; + for(seq_index=0, seq=seqar[0]; seq_index < totseq_index; seq=seqar[++seq_index]) { + if (seq->type == SEQ_META) { + for (meta_seq = seq->seqbase.first; meta_seq; meta_seq= meta_seq->next){ + meta_seq->tmp= (void *)seq; + } + } + } + } + + if (sseq->flag & SEQ_MARKER_TRANS) { for(marker= G.scene->markers.first; marker; marker= marker->next) { if(marker->flag & SELECT) totmark++; @@ -3064,8 +3090,8 @@ void transform_seq(int mode, int context) /* for extend only */ if (mode=='e') { - ts->final_left = seq_tx_get_final_left(seq); - ts->final_right = seq_tx_get_final_right(seq); + ts->final_left = seq_tx_get_final_left(seq, 1); + ts->final_right = seq_tx_get_final_right(seq, 1); } ts++; } @@ -3151,9 +3177,9 @@ void transform_seq(int mode, int context) snap_point_num=0; if (last_seq && (last_seq->flag & SELECT)) { /* active seq bounds */ if(seq_tx_check_left(last_seq)) - snap_points[snap_point_num++] = seq_tx_get_final_left(last_seq); + snap_points[snap_point_num++] = seq_tx_get_final_left(last_seq, 0); if(seq_tx_check_right(last_seq)) - snap_points[snap_point_num++] = seq_tx_get_final_right(last_seq); + snap_points[snap_point_num++] = seq_tx_get_final_right(last_seq, 0); } if (totstrip > 1) { /* selection bounds */ @@ -3163,9 +3189,9 @@ void transform_seq(int mode, int context) for(seq_index=0, seq=seqar[0]; seq_index < totseq_index; seq=seqar[++seq_index]) { if(seq->flag & SELECT) { if(seq_tx_check_left(seq)) - bounds_left = MIN2(bounds_left, seq_tx_get_final_left(seq)); + bounds_left = MIN2(bounds_left, seq_tx_get_final_left(seq, 0)); if(seq_tx_check_right(seq)) - bounds_right = MAX2(bounds_right,seq_tx_get_final_right(seq)); + bounds_right = MAX2(bounds_right,seq_tx_get_final_right(seq, 0)); } } @@ -3214,13 +3240,13 @@ void transform_seq(int mode, int context) if (snap_dist && last_seq && seq_tx_check_left(last_seq)) { seq = find_next_prev_sequence(last_seq, 1, 0); /* left */ if(seq && !seq_tx_check_right(seq)) - TESTSNAP(seq_tx_get_final_right(seq)); + TESTSNAP(seq_tx_get_final_right(seq, 0)); } if (snap_dist && last_seq && seq_tx_check_right(last_seq)) { seq = find_next_prev_sequence(last_seq, 2, 0); /* right */ if(seq && !seq_tx_check_left(seq)) - TESTSNAP(seq_tx_get_final_left(seq)); + TESTSNAP(seq_tx_get_final_left(seq, 0)); } #undef TESTSNAP @@ -3242,20 +3268,23 @@ void transform_seq(int mode, int context) for(seq_index=0, seq=seqar[0]; seq_index < totseq_index; seq=seqar[++seq_index]) { if(seq->flag & SELECT && !(seq->depth==0 && seq->flag & SEQ_LOCK)) { int myofs; + /* flag, ignores lefsel/rightsel for nested strips */ + int sel_flag = (seq->depth==0) ? seq->flag : seq->flag & ~(SEQ_LEFTSEL+SEQ_RIGHTSEL); + // SEQ_DEBUG_INFO(seq); /* X Transformation */ - if(seq->flag & SEQ_LEFTSEL) { + if((seq->depth==0) && (sel_flag & SEQ_LEFTSEL)) { myofs = (ts->startofs - ts->startstill); seq_tx_set_final_left(seq, ts->start + (myofs + ix)); } - if(seq->flag & SEQ_RIGHTSEL) { + if((seq->depth==0) && (sel_flag & SEQ_RIGHTSEL)) { myofs = (ts->endstill - ts->endofs); seq_tx_set_final_right(seq, ts->start + seq->len + (myofs + ix)); } - transform_grab_xlimits(seq, seq->flag & SEQ_LEFTSEL, seq->flag & SEQ_RIGHTSEL); + transform_grab_xlimits(seq, sel_flag & SEQ_LEFTSEL, sel_flag & SEQ_RIGHTSEL); - if( (seq->flag & (SEQ_LEFTSEL+SEQ_RIGHTSEL))==0 ) { + if( (sel_flag & (SEQ_LEFTSEL+SEQ_RIGHTSEL))==0 ) { if(sequence_is_free_transformable(seq)) seq->start= ts->start+ ix; /* Y Transformation */ @@ -3300,8 +3329,8 @@ void transform_seq(int mode, int context) //SEQ_DEBUG_INFO(seq); - final_left = seq_tx_get_final_left(seq); - final_right = seq_tx_get_final_right(seq); + final_left = seq_tx_get_final_left(seq, 1); + final_right = seq_tx_get_final_right(seq, 1); /* Only X Axis moving */ @@ -3591,8 +3620,8 @@ void seq_separate_images(void) BLI_remlink(ed->seqbasep, seq); if(seq->ipo) seq->ipo->id.us--; - start_ofs = cfra = seq_tx_get_final_left(seq); - frame_end = seq_tx_get_final_right(seq); + start_ofs = cfra = seq_tx_get_final_left(seq, 0); + frame_end = seq_tx_get_final_right(seq, 0); while (cfra < frame_end) { /* new seq */ diff --git a/source/blender/src/filesel.c b/source/blender/src/filesel.c index 9689ffdafeb..2ba5745b19b 100644 --- a/source/blender/src/filesel.c +++ b/source/blender/src/filesel.c @@ -1591,7 +1591,7 @@ static void do_filesel_buttons(short event, SpaceFile *sfile) BLI_del_slash(butname); if(sfile->type & FILE_UNIX) { - if (!BLI_exists(butname)) { + if (butname[0] != '\0' && !BLI_exists(butname)) { if (okee("Makedir")) { BLI_recurdir_fileops(butname); if (!BLI_exists(butname)) parent(sfile); diff --git a/source/blender/src/fluidsim.c b/source/blender/src/fluidsim.c index a7361a9ffca..8b9c89656fb 100644 --- a/source/blender/src/fluidsim.c +++ b/source/blender/src/fluidsim.c @@ -481,6 +481,7 @@ void fluidsimBake(struct Object *ob) struct Object *fsDomain = NULL; FluidsimSettings *domainSettings; struct Object *obit = NULL; /* object iterator */ + Base *base; int origFrame = G.scene->r.cfra; char debugStrBuffer[256]; int dirExist = 0; @@ -522,7 +523,7 @@ void fluidsimBake(struct Object *ob) float *channelObjMove[256][3]; // object movments , 0=trans, 1=rot, 2=scale float *channelObjInivel[256]; // initial velocities float *channelObjActive[256]; // obj active channel - + if(getenv(strEnvName)) { int dlevel = atoi(getenv(strEnvName)); elbeemSetDebugLevel(dlevel); @@ -545,7 +546,6 @@ void fluidsimBake(struct Object *ob) /* no object pointer, find in selected ones.. */ if(!ob) { - Base *base; for(base=G.scene->base.first; base; base= base->next) { if ( ((base)->flag & SELECT) // ignore layer setting for now? && ((base)->lay & G.vd->lay) @@ -561,8 +561,26 @@ void fluidsimBake(struct Object *ob) if(!ob) return; } + channelObjCount = 0; + for(base=G.scene->base.first; base; base= base->next) { + obit = base->object; + //{ snprintf(debugStrBuffer,256,"DEBUG object name=%s, type=%d ...\n", obit->id.name, obit->type); elbeemDebugOut(debugStrBuffer); } // DEBUG + if( (obit->fluidsimFlag & OB_FLUIDSIM_ENABLE) && + (obit->type==OB_MESH) && + (obit->fluidsimSettings->type != OB_FLUIDSIM_DOMAIN) && // if has to match 3 places! // CHECKMATCH + (obit->fluidsimSettings->type != OB_FLUIDSIM_PARTICLE) ) { + channelObjCount++; + } + } + + if (channelObjCount>=255) { + pupmenu("Fluidsim Bake Error%t|Cannot bake with more then 256 objects"); + return; + } + /* check if there's another domain... */ - for(obit= G.main->object.first; obit; obit= obit->id.next) { + for(base=G.scene->base.first; base; base= base->next) { + obit = base->object; if((obit->fluidsimFlag & OB_FLUIDSIM_ENABLE)&&(obit->type==OB_MESH)) { if(obit->fluidsimSettings->type == OB_FLUIDSIM_DOMAIN) { if(obit != ob) { @@ -605,7 +623,8 @@ void fluidsimBake(struct Object *ob) // check if theres any fluid // abort baking if not... - for(obit= G.main->object.first; obit; obit= obit->id.next) { + for(base=G.scene->base.first; base; base= base->next) { + obit = base->object; if( (obit->fluidsimFlag & OB_FLUIDSIM_ENABLE) && (obit->type==OB_MESH) && ( (obit->fluidsimSettings->type == OB_FLUIDSIM_FLUID) || @@ -749,7 +768,8 @@ void fluidsimBake(struct Object *ob) // init obj movement channels channelObjCount=0; - for(obit= G.main->object.first; obit; obit= obit->id.next) { + for(base=G.scene->base.first; base; base= base->next) { + obit = base->object; //{ snprintf(debugStrBuffer,256,"DEBUG object name=%s, type=%d ...\n", obit->id.name, obit->type); elbeemDebugOut(debugStrBuffer); } // DEBUG if( (obit->fluidsimFlag & OB_FLUIDSIM_ENABLE) && (obit->type==OB_MESH) && @@ -952,7 +972,8 @@ void fluidsimBake(struct Object *ob) // init objects channelObjCount = 0; - for(obit= G.main->object.first; obit; obit= obit->id.next) { + for(base=G.scene->base.first; base; base= base->next) { + obit = base->object; //{ snprintf(debugStrBuffer,256,"DEBUG object name=%s, type=%d ...\n", obit->id.name, obit->type); elbeemDebugOut(debugStrBuffer); } // DEBUG if( (obit->fluidsimFlag & OB_FLUIDSIM_ENABLE) && // if has to match 3 places! // CHECKMATCH (obit->type==OB_MESH) && diff --git a/source/blender/src/meshtools.c b/source/blender/src/meshtools.c index e27e772edee..ac165d6aeb2 100644 --- a/source/blender/src/meshtools.c +++ b/source/blender/src/meshtools.c @@ -957,6 +957,12 @@ int *mesh_get_x_mirror_faces(Object *ob) mirrormf.v3= mirrorverts[mf->v1]; mirrormf.v4= (mf->v4)? mirrorverts[mf->v4]: 0; + /* make sure v4 is not 0 if a quad */ + if(mf->v4 && mirrormf.v4==0) { + SWAP(int, mirrormf.v1, mirrormf.v3); + SWAP(int, mirrormf.v2, mirrormf.v4); + } + hashmf= BLI_ghash_lookup(fhash, &mirrormf); if(hashmf) { mirrorfaces[a*2]= hashmf - mface; diff --git a/source/blender/src/transform_conversions.c b/source/blender/src/transform_conversions.c index 4be525f4945..dcebf6b7557 100644 --- a/source/blender/src/transform_conversions.c +++ b/source/blender/src/transform_conversions.c @@ -1365,7 +1365,7 @@ static void createTransCurveVerts(TransInfo *t) tail++; } if( propmode || - ((bezt->f1 & SELECT) && (G.f & G_HIDDENHANDLES)) || + ((bezt->f2 & SELECT) && (G.f & G_HIDDENHANDLES)) || ((bezt->f3 & SELECT) && (G.f & G_HIDDENHANDLES)==0) ) { VECCOPY(td->iloc, bezt->vec[2]); diff --git a/source/blender/src/transform_manipulator.c b/source/blender/src/transform_manipulator.c index 5c06aaea890..050360887b4 100644 --- a/source/blender/src/transform_manipulator.c +++ b/source/blender/src/transform_manipulator.c @@ -158,7 +158,7 @@ static void protectflag_to_drawflags(short protectflag, short *drawflags) } /* for pose mode */ -static void stats_pose(View3D *v3d, bPoseChannel *pchan, float *normal, float *plane) +static void stats_pose(View3D *v3d, bPoseChannel *pchan) { Bone *bone= pchan->bone; @@ -166,9 +166,6 @@ static void stats_pose(View3D *v3d, bPoseChannel *pchan, float *normal, float *p if (bone->flag & BONE_TRANSFORM) { calc_tw_center(pchan->pose_head); protectflag_to_drawflags(pchan->protectflag, &v3d->twdrawflag); - - VecAddf(normal, normal, pchan->pose_mat[2]); - VecAddf(plane, plane, pchan->pose_mat[1]); } } } @@ -349,26 +346,24 @@ int calc_manipulator_stats(ScrArea *sa) } } else if(ob && (ob->flag & OB_POSEMODE)) { - bArmature *arm= ob->data; + bArmature *arm = ob->data; bPoseChannel *pchan; int mode; if((ob->lay & G.vd->lay)==0) return 0; - mode= Trans.mode; - Trans.mode= TFM_ROTATION; // mislead counting bones... bah + mode = Trans.mode; + Trans.mode = TFM_ROTATION; // mislead counting bones... bah /* count total, we use same method as transform will do */ Trans.total= 0; count_bone_select(&Trans, arm, &arm->bonebase, 1); - totsel= Trans.total; + totsel = Trans.total; if(totsel) { /* use channels to get stats */ for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) { - stats_pose(v3d, pchan, normal, plane); + stats_pose(v3d, pchan); } - //VecMulf(normal, -1.0); - VecMulf(plane, -1.0); VecMulf(G.scene->twcent, 1.0f/(float)totsel); // centroid! Mat4MulVecfl(ob->obmat, G.scene->twcent); @@ -376,7 +371,7 @@ int calc_manipulator_stats(ScrArea *sa) Mat4MulVecfl(ob->obmat, G.scene->twmax); } /* restore, mode can be TFM_INIT */ - Trans.mode= mode; + Trans.mode = mode; } else if(G.f & (G_VERTEXPAINT + G_TEXTUREPAINT + G_WEIGHTPAINT + G_SCULPTMODE)) { ; @@ -433,7 +428,7 @@ int calc_manipulator_stats(ScrArea *sa) break; case V3D_MANIP_NORMAL: - if(G.obedit) { + if(G.obedit || ob->flag & OB_POSEMODE) { float mat[3][3]; int type; @@ -479,34 +474,6 @@ int calc_manipulator_stats(ScrArea *sa) } break; } - /* pose mode is a bit weird, so keep it separated */ - else if (ob->flag & OB_POSEMODE) - { - strcpy(t->spacename, "normal"); - if(normal[0]!=0.0 || normal[1]!=0.0 || normal[2]!=0.0) { - float imat[3][3], mat[3][3]; - - /* we need the transpose of the inverse for a normal... */ - Mat3CpyMat4(imat, ob->obmat); - - Mat3Inv(mat, imat); - Mat3Transp(mat); - Mat3MulVecfl(mat, normal); - Mat3MulVecfl(mat, plane); - - Normalize(normal); - if(0.0==Normalize(plane)) VECCOPY(plane, mat[1]); - - VECCOPY(mat[2], normal); - Crossf(mat[0], normal, plane); - Crossf(mat[1], mat[2], mat[0]); - - Mat4CpyMat3(v3d->twmat, mat); - Mat4Ortho(v3d->twmat); - - break; - } - } /* no break we define 'normal' as 'local' in Object mode */ case V3D_MANIP_LOCAL: strcpy(t->spacename, "local"); diff --git a/source/blender/src/transform_orientations.c b/source/blender/src/transform_orientations.c index 6696fcf95d6..9c7a2f67b89 100644 --- a/source/blender/src/transform_orientations.c +++ b/source/blender/src/transform_orientations.c @@ -27,6 +27,7 @@ #include "MEM_guardedalloc.h" #include "DNA_armature_types.h" +#include "DNA_action_types.h" #include "DNA_curve_types.h" #include "DNA_listBase.h" #include "DNA_object_types.h" @@ -68,11 +69,17 @@ void BIF_clearTransformOrientation(void) } void BIF_manageTransformOrientation(int confirm, int set) { + Object *ob = OBACT; int index = -1; if (G.obedit) { if (G.obedit->type == OB_MESH) index = manageMeshSpace(confirm, set); + else if (G.obedit->type == OB_ARMATURE) + index = manageBoneSpace(confirm, set); + } + else if (ob && (ob->flag & OB_POSEMODE)) { + index = manageBoneSpace(confirm, set); } else { index = manageObjectSpace(confirm, set); @@ -122,6 +129,31 @@ int confirmSpace(int set, char text[]) } } +int manageBoneSpace(int confirm, int set) { + float mat[3][3]; + float normal[3], plane[3]; + char name[36] = ""; + int index; + + getTransformOrientation(normal, plane, 0); + + if (confirm == 0 && confirmSpace(set, "Bone") == 0) { + return -1; + } + + if (createSpaceNormalTangent(mat, normal, plane) == 0) { + error("Cannot use zero-length bone"); + return -1; + } + + strcpy(name, "Bone"); + + /* Input name */ + sbutton(name, 1, 35, "name: "); + + index = addMatrixSpace(mat, name); + return index; +} int manageMeshSpace(int confirm, int set) { float mat[3][3]; @@ -363,6 +395,29 @@ void applyTransformOrientation() { } } +static int count_bone_select(bArmature *arm, ListBase *lb, int do_it) +{ + Bone *bone; + int do_next; + int total = 0; + + for(bone= lb->first; bone; bone= bone->next) { + bone->flag &= ~BONE_TRANSFORM; + do_next = do_it; + if(do_it) { + if(bone->layer & arm->layer) { + if (bone->flag & BONE_SELECTED) { + bone->flag |= BONE_TRANSFORM; + total++; + do_next= 0; // no transform on children if one parent bone is selected + } + } + } + total += count_bone_select(arm, &bone->childbase, do_next); + } + + return total; +} int getTransformOrientation(float normal[3], float plane[3], int activeOnly) { @@ -375,6 +430,14 @@ int getTransformOrientation(float normal[3], float plane[3], int activeOnly) if(G.obedit) { + float imat[3][3], mat[3][3]; + + /* we need the transpose of the inverse for a normal... */ + Mat3CpyMat4(imat, ob->obmat); + + Mat3Inv(mat, imat); + Mat3Transp(mat); + ob= G.obedit; if(G.obedit->type==OB_MESH) @@ -639,12 +702,48 @@ int getTransformOrientation(float normal[3], float plane[3], int activeOnly) } } - - Mat4Mul3Vecfl(G.obedit->obmat, plane); - Mat4Mul3Vecfl(G.obedit->obmat, normal); + + /* Vectors from edges don't need the special transpose inverse multiplication */ + if (result == ORIENTATION_EDGE) + { + Mat4Mul3Vecfl(ob->obmat, normal); + Mat4Mul3Vecfl(ob->obmat, plane); + } + else + { + Mat3MulVecfl(mat, normal); + Mat3MulVecfl(mat, plane); + } } else if(ob && (ob->flag & OB_POSEMODE)) { + bArmature *arm= ob->data; + bPoseChannel *pchan; + int totsel; + + totsel = count_bone_select(arm, &arm->bonebase, 1); + if(totsel) { + float imat[3][3], mat[3][3]; + + /* use channels to get stats */ + for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) { + if (pchan->bone && pchan->bone->flag & BONE_TRANSFORM) { + VecAddf(normal, normal, pchan->pose_mat[2]); + VecAddf(plane, plane, pchan->pose_mat[1]); + } + } + VecMulf(plane, -1.0); + + /* we need the transpose of the inverse for a normal... */ + Mat3CpyMat4(imat, ob->obmat); + + Mat3Inv(mat, imat); + Mat3Transp(mat); + Mat3MulVecfl(mat, normal); + Mat3MulVecfl(mat, plane); + + result = ORIENTATION_EDGE; + } } else if(G.f & (G_VERTEXPAINT + G_TEXTUREPAINT + G_WEIGHTPAINT + G_SCULPTMODE)) { diff --git a/source/blender/src/view.c b/source/blender/src/view.c index 2904ca60a12..1e45f2bf3e0 100644 --- a/source/blender/src/view.c +++ b/source/blender/src/view.c @@ -1448,6 +1448,8 @@ void obmat_to_viewmat(Object *ob, short smooth) float bmat[4][4]; float tmat[3][3]; + G.vd->view= 0; /* dont show the grid */ + Mat4CpyMat4(bmat, ob->obmat); Mat4Ortho(bmat); Mat4Invert(G.vd->viewmat, bmat); From edd2b6ca7374c475cbd6fe0c8a15d6bcce6f1e8c Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 1 Jun 2008 01:49:11 +0000 Subject: [PATCH 128/246] bugfix for own error [#13588] Python API Material.sssRadiusBlue broken --- source/blender/python/api2_2x/Material.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/python/api2_2x/Material.c b/source/blender/python/api2_2x/Material.c index 818c58109f3..ddf161e5efa 100644 --- a/source/blender/python/api2_2x/Material.c +++ b/source/blender/python/api2_2x/Material.c @@ -1179,7 +1179,7 @@ static PyGetSetDef BPy_Material_getseters[] = { {"sssRadiusBlue", (getter)Material_getSssRadius, (setter)Material_setSssRadius, "Mean red scattering path length", - (void *) 0}, + (void *) 2}, {"sssIOR", (getter)Material_getSssIOR, (setter)Material_setSssIOR, "index of refraction", From 26cb5fa0db6f43a44358f8adc1529ebe58d41d3a Mon Sep 17 00:00:00 2001 From: Geoffrey Bantle Date: Sun, 1 Jun 2008 01:56:35 +0000 Subject: [PATCH 129/246] -Fix for bug #13067 Bevel tool was hanging on certain geometry where the edge to be beveled was shared by two faces that had more than one edge in common and caller was not checking return status of Bmesh eulers. Fixed. --- source/blender/blenkernel/intern/BME_tools.c | 30 ++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/source/blender/blenkernel/intern/BME_tools.c b/source/blender/blenkernel/intern/BME_tools.c index 90fa9793644..7ce967d1d22 100644 --- a/source/blender/blenkernel/intern/BME_tools.c +++ b/source/blender/blenkernel/intern/BME_tools.c @@ -811,7 +811,18 @@ static float BME_bevel_get_angle(BME_Mesh *bm, BME_Edge *e, BME_Vert *v) { return Inpf(vec3,vec4); } - +static int BME_face_sharededges(BME_Poly *f1, BME_Poly *f2){ + BME_Loop *l; + int count = 0; + + l = f1->loopbase; + do{ + if(BME_radial_find_face(l->e,f2)) count++; + l = l->next; + }while(l != f1->loopbase); + + return count; +} /** * BME_bevel_initialize * @@ -990,6 +1001,17 @@ static BME_Mesh *BME_bevel_initialize(BME_Mesh *bm, int options, int defgrp_inde /* face pass */ for (f=bm->polys.first; f; f=f->next) f->tflag1 = BME_BEVEL_ORIG; + /*clean up edges with 2 faces that share more than one edge*/ + for (e=bm->edges.first; e; e=e->next){ + if(e->tflag1 & BME_BEVEL_BEVEL){ + int count = 0; + count = BME_face_sharededges(e->loop->f, ((BME_Loop*)e->loop->radial.next->data)->f); + if(count > 1){ + e->tflag1 &= ~BME_BEVEL_BEVEL; + } + } + } + return bm; } @@ -1075,7 +1097,7 @@ static BME_Mesh *BME_bevel_mesh(BME_Mesh *bm, float value, int res, int options, v = BME_bevel_wire(bm, v, value, res, options, td); } else if (res && ((v->tflag1 & BME_BEVEL_BEVEL) && (v->tflag1 & BME_BEVEL_ORIG))) { - + int count = 0; /* first, make sure we're not sitting on an edge to be removed */ oe = v->edge; e = BME_disk_nextedge(oe,v); @@ -1089,6 +1111,7 @@ static BME_Mesh *BME_bevel_mesh(BME_Mesh *bm, float value, int res, int options, /* look for original edges, and remove them */ oe = e; while ( (e = BME_disk_next_edgeflag(oe, v, 0, BME_BEVEL_ORIG | BME_BEVEL_BEVEL)) ) { + count++; /* join the faces (we'll split them later) */ f = BME_JFKE_safe(bm,e->loop->f,((BME_Loop*)e->loop->radial.next->data)->f,e); if (!f){ @@ -1096,6 +1119,9 @@ static BME_Mesh *BME_bevel_mesh(BME_Mesh *bm, float value, int res, int options, } } + /*need to do double check *before* you bevel to make sure that manifold edges are for two faces that share only *one* edge to make sure it doesnt hang here!*/ + + /* all original edges marked to be beveled have been removed; * now we need to link up the edges for this "corner" */ len = BME_cycle_length(BME_disk_getpointer(v->edge, v)); From c0199e192dca28b4d08207dea51c86c3add72cd8 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 1 Jun 2008 13:18:26 +0000 Subject: [PATCH 130/246] bugfix (typo) [#13587] Python API Material.sssFront broken --- source/blender/python/api2_2x/Material.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/python/api2_2x/Material.c b/source/blender/python/api2_2x/Material.c index ddf161e5efa..c36213950b0 100644 --- a/source/blender/python/api2_2x/Material.c +++ b/source/blender/python/api2_2x/Material.c @@ -1196,7 +1196,7 @@ static PyGetSetDef BPy_Material_getseters[] = { (getter)Material_getSssTexScatter, (setter)Material_setSssTexScatter, "Texture scattering factor", NULL}, - {"sssFont", + {"sssFront", (getter)Material_getSssFront, (setter)Material_setSssFront, "Front scattering weight", NULL}, From 8937989a911fcc1bc634bbbb00be71fe62197fc4 Mon Sep 17 00:00:00 2001 From: Peter Schlaile Date: Sun, 1 Jun 2008 14:37:09 +0000 Subject: [PATCH 131/246] == FFMPEG == Shouldn't crash any more in the case that a) invalid video options were selected and b) audio multiplexing was active [#13311] video_stream NULL when writing ffmpeg (did'nt crash for me though, but added extra protection :) ) --- source/blender/blenkernel/intern/writeffmpeg.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/blenkernel/intern/writeffmpeg.c b/source/blender/blenkernel/intern/writeffmpeg.c index c95e3d20442..64af8258f80 100644 --- a/source/blender/blenkernel/intern/writeffmpeg.c +++ b/source/blender/blenkernel/intern/writeffmpeg.c @@ -867,7 +867,7 @@ void end_ffmpeg(void) fprintf(stderr, "Closing ffmpeg...\n"); - if (audio_stream) { + if (audio_stream && video_stream) { write_audio_frames(); } From 652ee1e31baa52c8e504bfcf3759ea94c7f5ab66 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 1 Jun 2008 16:13:04 +0000 Subject: [PATCH 132/246] functionality fix Originally the only way to run scripts automatically was with scriptlinks, which could be disabled for loading untrusted blend files. Since then PyDrivers and PyConstraints would run even when G.f&G_DOSCRIPTLINKS was disabled. Gensher, Theeth and Ianwill agree its acceptable to reuse the flag for other areas python runs automatically. PyNodes still have no way to be disabled, (todo before 2.46a) --- source/blender/blenkernel/intern/constraint.c | 4 +++- source/blender/python/BPY_interface.c | 4 ++-- source/creator/creator.c | 2 +- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c index f60e39769a2..068501780bc 100644 --- a/source/blender/blenkernel/intern/constraint.c +++ b/source/blender/blenkernel/intern/constraint.c @@ -1882,7 +1882,7 @@ static void pycon_get_tarmat (bConstraint *con, bConstraintOb *cob, bConstraintT { bPythonConstraint *data= con->data; - if (VALID_CONS_TARGET(ct)) { + if ((G.f & G_DOSCRIPTLINKS) && VALID_CONS_TARGET(ct)) { /* special exception for curves - depsgraph issues */ if (ct->tar->type == OB_CURVE) { Curve *cu= ct->tar->data; @@ -1906,6 +1906,8 @@ static void pycon_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *targ { bPythonConstraint *data= con->data; + if ((G.f & G_DOSCRIPTLINKS)==0) return; + /* currently removed, until I this can be re-implemented for multiple targets */ #if 0 /* Firstly, run the 'driver' function which has direct access to the objects involved diff --git a/source/blender/python/BPY_interface.c b/source/blender/python/BPY_interface.c index 257203908b1..279c3727442 100644 --- a/source/blender/python/BPY_interface.c +++ b/source/blender/python/BPY_interface.c @@ -1222,7 +1222,7 @@ static int bpy_pydriver_create_dict(void) { PyObject *d, *mod; - if (bpy_pydriver_Dict) return -1; + if (bpy_pydriver_Dict || (G.f&G_DOSCRIPTLINKS)==0) return -1; d = PyDict_New(); if (!d) return -1; @@ -1998,7 +1998,7 @@ float BPY_pydriver_eval(IpoDriver *driver) int setitem_retval; PyGILState_STATE gilstate; - if (!driver) return result; + if (!driver || (G.f&G_DOSCRIPTLINKS)==0) return result; expr = driver->name; /* the py expression to be evaluated */ if (!expr || expr[0]=='\0') return result; diff --git a/source/creator/creator.c b/source/creator/creator.c index a4588bb4597..2e6b5d7353e 100644 --- a/source/creator/creator.c +++ b/source/creator/creator.c @@ -219,7 +219,7 @@ static void print_help(void) printf (" -d\t\tTurn debugging on\n"); printf (" -noaudio\tDisable audio on systems that support audio\n"); printf (" -h\t\tPrint this help text\n"); - printf (" -y\t\tDisable script links, use -Y to find out why its -y\n"); + printf (" -y\t\tDisable automatic python script execution (scriptlinks, pydrivers, pyconstraints, pynodes)\n"); printf (" -P \tRun the given Python script (filename or Blender Text)\n"); #ifdef WIN32 printf (" -R\t\tRegister .blend extension\n"); From 07b1608fbe52f729eae39c307060f92948aabf37 Mon Sep 17 00:00:00 2001 From: Geoffrey Bantle Date: Sun, 1 Jun 2008 17:15:03 +0000 Subject: [PATCH 133/246] -> New memory allocator for Bmesh Added a new pooling allocator for Bmesh based upon the pool allocator availible in the Boost C++ library as described here: http://www.boost.org/doc/libs/1_34_0/libs/pool/doc/concepts.html Each pool allocates elements of a fixed size, so every element type in a mesh gets its own pool. For instance verts occupy a different pool than edges. Each pool is comprised of multiple arrays of a fixed size and allocating /freeing elements is simple as removing or adding a head to a linked list. Since the list of free elements is interleaved throughout the unused space in the arrays, the overhead for storing the free list is only 1 pointer total per pool. This makes building/destroying bmesh structures much faster and saves quite a bit of memory as well. --- source/blender/blenkernel/BKE_bmesh.h | 19 +- source/blender/blenkernel/intern/BME_mesh.c | 65 +++---- .../blender/blenkernel/intern/BME_structure.c | 164 +++++++++++++++--- .../blender/blenkernel/intern/bmesh_private.h | 11 +- source/blender/blenkernel/intern/modifier.c | 2 +- source/blender/src/editmesh_tools.c | 2 +- 6 files changed, 185 insertions(+), 78 deletions(-) diff --git a/source/blender/blenkernel/BKE_bmesh.h b/source/blender/blenkernel/BKE_bmesh.h index 08ad8192688..87202ce047a 100644 --- a/source/blender/blenkernel/BKE_bmesh.h +++ b/source/blender/blenkernel/BKE_bmesh.h @@ -50,6 +50,9 @@ struct BME_Edge; struct BME_Poly; struct BME_Loop; +struct BME_mempool; +typedef struct BME_mempool BME_mempool; + typedef struct BME_CycleNode{ struct BME_CycleNode *next, *prev; void *data; @@ -57,16 +60,21 @@ typedef struct BME_CycleNode{ typedef struct BME_Mesh { - ListBase verts, edges, polys, loops; - int totvert, totedge, totpoly, totloop; /*record keeping*/ - int nextv, nexte, nextp, nextl; /*Next element ID for verts/edges/faces/loops. Never reused*/ - struct CustomData vdata, edata, pdata, ldata; /*Custom Data Layer information*/ + ListBase verts, edges, polys; + /*memory pools used for storing mesh elements*/ + struct BME_mempool *vpool; + struct BME_mempool *epool; + struct BME_mempool *ppool; + struct BME_mempool *lpool; /*some scratch arrays used by eulers*/ struct BME_Vert **vtar; struct BME_Edge **edar; struct BME_Loop **lpar; struct BME_Poly **plar; int vtarlen, edarlen, lparlen, plarlen; + int totvert, totedge, totpoly, totloop; /*record keeping*/ + int nextv, nexte, nextp, nextl; /*Next element ID for verts/edges/faces/loops. Never reused*/ + //struct CustomData vdata, edata, pdata, ldata; /*Custom Data Layer information*/ } BME_Mesh; typedef struct BME_Vert @@ -102,7 +110,6 @@ typedef struct BME_Loop struct BME_Loop *next, *prev; /*circularly linked list around face*/ int EID; struct BME_CycleNode radial; /*circularly linked list used to find faces around an edge*/ - struct BME_CycleNode *gref; /*pointer to loop ref. Nasty.*/ struct BME_Vert *v; /*vertex that this loop starts at.*/ struct BME_Edge *e; /*edge this loop belongs to*/ struct BME_Poly *f; /*face this loop belongs to*/ @@ -146,7 +153,7 @@ int BME_radial_find_face(struct BME_Edge *e,struct BME_Poly *f); struct BME_Loop *BME_loop_find_loop(struct BME_Poly *f, struct BME_Vert *v); /*MESH CREATION/DESTRUCTION*/ -struct BME_Mesh *BME_make_mesh(void); +struct BME_Mesh *BME_make_mesh(int valloc, int ealloc, int lalloc, int palloc); void BME_free_mesh(struct BME_Mesh *bm); /*FULL MESH VALIDATION*/ int BME_validate_mesh(struct BME_Mesh *bm, int halt); diff --git a/source/blender/blenkernel/intern/BME_mesh.c b/source/blender/blenkernel/intern/BME_mesh.c index d9d2354ef36..307047463cf 100644 --- a/source/blender/blenkernel/intern/BME_mesh.c +++ b/source/blender/blenkernel/intern/BME_mesh.c @@ -62,11 +62,21 @@ * Allocates a new BME_Mesh structure */ -BME_Mesh *BME_make_mesh(void){ + + +BME_Mesh *BME_make_mesh(int valloc, int ealloc, int lalloc, int palloc){ + /*allocate the structure*/ BME_Mesh *bm = MEM_callocN(sizeof(BME_Mesh),"BMesh"); + /*allocate the memory pools for the mesh elements*/ + bm->vpool = BME_mempool_create(sizeof(BME_Vert), valloc, valloc); + bm->epool = BME_mempool_create(sizeof(BME_Edge), ealloc, ealloc); + bm->ppool = BME_mempool_create(sizeof(BME_Poly), palloc, palloc); + bm->lpool = BME_mempool_create(sizeof(BME_Loop), lalloc, lalloc); + /*allocate the customdata pools*/ return bm; } + /* * BME FREE MESH * @@ -75,45 +85,13 @@ BME_Mesh *BME_make_mesh(void){ void BME_free_mesh(BME_Mesh *bm) { - BME_Poly *bf, *nextf; - BME_Edge *be, *nexte; - BME_Vert *bv, *nextv; - BME_CycleNode *loopref; - - /*destroy polygon data*/ - bf = bm->polys.first; - while(bf){ - nextf = bf->next; - BLI_remlink(&(bm->polys), bf); - BME_free_poly(bm, bf); - - bf = nextf; - } - /*destroy edge data*/ - be = bm->edges.first; - while(be){ - nexte = be->next; - BLI_remlink(&(bm->edges), be); - BME_free_edge(bm, be); - be = nexte; - } - /*destroy vert data*/ - bv = bm->verts.first; - while(bv){ - nextv = bv->next; - BLI_remlink(&(bm->verts), bv); - BME_free_vert(bm, bv); - bv = nextv; - } - - for(loopref=bm->loops.first;loopref;loopref=loopref->next) BME_delete_loop(bm,loopref->data); - BLI_freelistN(&(bm->loops)); - - //CustomData_free(&bm->vdata, 0); - //CustomData_free(&bm->edata, 0); - //CustomData_free(&bm->ldata, 0); - //CustomData_free(&bm->pdata, 0); - + /*destroy element pools*/ + BME_mempool_destroy(bm->vpool); + BME_mempool_destroy(bm->epool); + BME_mempool_destroy(bm->ppool); + BME_mempool_destroy(bm->lpool); + /*destroy custom data pools*/ + MEM_freeN(bm); } @@ -156,8 +134,7 @@ void BME_model_end(BME_Mesh *bm){ totvert = BLI_countlist(&(bm->verts)); totedge = BLI_countlist(&(bm->edges)); totpoly = BLI_countlist(&(bm->polys)); - totloop = BLI_countlist(&(bm->loops)); - + if(bm->vtar) MEM_freeN(bm->vtar); if(bm->edar) MEM_freeN(bm->edar); if(bm->lpar) MEM_freeN(bm->lpar); @@ -167,10 +144,10 @@ void BME_model_end(BME_Mesh *bm){ bm->edar = NULL; bm->lpar = NULL; bm->plar = NULL; - bm->vtarlen = bm->edarlen = bm->lparlen = bm->plarlen = 1024; + bm->vtarlen = bm->edarlen = bm->lparlen = bm->plarlen = 0; - if(bm->totvert!=totvert || bm->totedge!=totedge || bm->totpoly!=totpoly || bm->totloop!=totloop) + if(bm->totvert!=totvert || bm->totedge!=totedge || bm->totpoly!=totpoly) BME_error(); meshok = BME_validate_mesh(bm, 1); diff --git a/source/blender/blenkernel/intern/BME_structure.c b/source/blender/blenkernel/intern/BME_structure.c index d283e1df5ca..d261238d128 100644 --- a/source/blender/blenkernel/intern/BME_structure.c +++ b/source/blender/blenkernel/intern/BME_structure.c @@ -43,6 +43,105 @@ #include "BLI_ghash.h" #include "BKE_customdata.h" + +/* + Simple, fast memory allocator for allocating many elements of the same size. +*/ +typedef struct BME_mempool_chunk{ + struct BME_mempool_chunk *next, *prev; + void *data; +}BME_mempool_chunk; + +/*this is just to make things prettier*/ +typedef struct BME_freenode{ + struct BME_freenode *next; +}BME_freenode; + +typedef struct BME_mempool{ + struct ListBase chunks; + int esize, csize, pchunk; /*size of elements and chunks in bytes and number of elements per chunk*/ + struct BME_freenode *free; /*free element list. Interleaved into chunk datas.*/ +}BME_mempool; + +BME_mempool *BME_mempool_create(int esize, int tote, int pchunk) +{ BME_mempool *pool = NULL; + BME_freenode *lasttail = NULL, *curnode = NULL; + int i,j, maxchunks; + char *addr; + + /*allocate the pool structure*/ + pool = MEM_mallocN(sizeof(BME_mempool),"memory pool"); + pool->esize = esize; + pool->pchunk = pchunk; + pool->csize = esize * pchunk; + pool->chunks.first = pool->chunks.last = NULL; + + maxchunks = tote / pchunk; + + /*allocate the actual chunks*/ + for(i=0; i < maxchunks; i++){ + BME_mempool_chunk *mpchunk = MEM_mallocN(sizeof(BME_mempool_chunk), "BME_Mempool Chunk"); + mpchunk->next = mpchunk->prev = NULL; + mpchunk->data = MEM_mallocN(pool->csize, "BME Mempool Chunk Data"); + BLI_addtail(&(pool->chunks), mpchunk); + + if(i==0) pool->free = mpchunk->data; /*start of the list*/ + /*loop through the allocated data, building the pointer structures*/ + for(addr = mpchunk->data, j=0; j < pool->pchunk; j++){ + curnode = ((BME_freenode*)addr); + addr += pool->esize; + curnode->next = (BME_freenode*)addr; + } + /*final pointer in the previously allocated chunk is wrong.*/ + if(lasttail) lasttail->next = mpchunk->data; + /*set the end of this chunks memory to the new tail for next iteration*/ + lasttail = curnode; + } + /*terminate the list*/ + curnode->next = NULL; + return pool; +} + +void *BME_mempool_alloc(BME_mempool *pool){ + void *retval=NULL; + BME_freenode *curnode=NULL; + char *addr=NULL; + int j; + + if(!(pool->free)){ + /*need to allocate a new chunk*/ + BME_mempool_chunk *mpchunk = MEM_mallocN(sizeof(BME_mempool_chunk), "BME_Mempool Chunk"); + mpchunk->next = mpchunk->prev = NULL; + mpchunk->data = MEM_mallocN(pool->csize, "BME_Mempool Chunk Data"); + BLI_addtail(&(pool->chunks), mpchunk); + + pool->free = mpchunk->data; /*start of the list*/ + for(addr = mpchunk->data, j=0; j < pool->pchunk; j++){ + curnode = ((BME_freenode*)addr); + addr += pool->esize; + curnode->next = (BME_freenode*)addr; + } + curnode->next = NULL; /*terminate the list*/ + } + + retval = pool->free; + pool->free = pool->free->next; + //memset(retval, 0, pool->esize); + return retval; +} + +void BME_mempool_free(BME_mempool *pool, void *addr){ //doesnt protect against double frees, dont be stupid! + BME_freenode *newhead = addr; + newhead->next = pool->free; + pool->free = newhead; +} +void BME_mempool_destroy(BME_mempool *pool) +{ + BME_mempool_chunk *mpchunk=NULL; + for(mpchunk = pool->chunks.first; mpchunk; mpchunk = mpchunk->next) MEM_freeN(mpchunk->data); + BLI_freelistN(&(pool->chunks)); + MEM_freeN(pool); +} /** * MISC utility functions. * @@ -86,9 +185,17 @@ int BME_edge_swapverts(BME_Edge *e, BME_Vert *orig, BME_Vert *new){ BME_Vert *BME_addvertlist(BME_Mesh *bm, BME_Vert *example){ BME_Vert *v=NULL; - v = MEM_callocN(sizeof(BME_Vert), "BME Vertex"); - BLI_addtail(&(bm->verts), v); + v = BME_mempool_alloc(bm->vpool); + v->next = v->prev = NULL; v->EID = bm->nextv; + v->co[0] = v->co[1] = v->co[2] = 0.0f; + v->no[0] = v->no[1] = v->no[2] = 0.0f; + v->edge = NULL; + v->data = NULL; + v->eflag1 = v->eflag2 = v->tflag1 = v->tflag2 = 0; + v->flag = v->h = 0; + v->bweight = 0.0f; + BLI_addtail(&(bm->verts), v); bm->nextv++; bm->totvert++; @@ -103,12 +210,19 @@ BME_Vert *BME_addvertlist(BME_Mesh *bm, BME_Vert *example){ } BME_Edge *BME_addedgelist(BME_Mesh *bm, BME_Vert *v1, BME_Vert *v2, BME_Edge *example){ BME_Edge *e=NULL; - e = MEM_callocN(sizeof(BME_Edge), "BME_Edge"); + e = BME_mempool_alloc(bm->epool); + e->next = e->prev = NULL; + e->EID = bm->nexte; e->v1 = v1; e->v2 = v2; + e->d1.next = e->d1.prev = e->d2.next = e->d2.prev = NULL; e->d1.data = e; e->d2.data = e; - e->EID = bm->nexte; + e->loop = NULL; + e->data = NULL; + e->eflag1 = e->eflag2 = e->tflag1 = e->tflag2 = 0; + e->flag = e->h = 0; + e->crease = e->bweight = 0.0f; bm->nexte++; bm->totedge++; BLI_addtail(&(bm->edges), e); @@ -124,16 +238,17 @@ BME_Edge *BME_addedgelist(BME_Mesh *bm, BME_Vert *v1, BME_Vert *v2, BME_Edge *ex BME_Loop *BME_create_loop(BME_Mesh *bm, BME_Vert *v, BME_Edge *e, BME_Poly *f, BME_Loop *example){ /*allocate a BME_Loop and add it to the loophash*/ BME_Loop *l=NULL; - BME_CycleNode *loopnode = MEM_callocN(sizeof(BME_CycleNode),"BME Loop Reference"); - l = MEM_callocN(sizeof(BME_Loop), "BME_Loop"); + l = BME_mempool_alloc(bm->lpool); + l->next = l->prev = NULL; + l->EID = bm->nextl; + l->radial.next = l->radial.prev = NULL; l->radial.data = l; l->v = v; l->e = e; l->f = f; - l->EID = bm->nextl; - l->gref = loopnode; - loopnode->data = l; - BLI_addtail(&(bm->loops),loopnode); + l->data = NULL; + l->eflag1 = l->eflag2 = l->tflag1 = l->tflag2 = 0; + l->flag = l->h = 0; //stupid waste! bm->nextl++; bm->totloop++; @@ -148,9 +263,15 @@ BME_Loop *BME_create_loop(BME_Mesh *bm, BME_Vert *v, BME_Edge *e, BME_Poly *f, B BME_Poly *BME_addpolylist(BME_Mesh *bm, BME_Poly *example){ BME_Poly *f = NULL; - f= MEM_callocN(sizeof(BME_Poly),"BME_Poly"); - BLI_addtail(&(bm->polys),f); + f = BME_mempool_alloc(bm->ppool); + f->next = f->prev = NULL; f->EID = bm->nextp; + f->loopbase = NULL; + f->len = 0; + f->data = NULL; + f->eflag1 = f->eflag2 = f->tflag1 = f->tflag2 = 0; + f->flag = f->h = f->mat_nr; + BLI_addtail(&(bm->polys),f); bm->nextp++; bm->totpoly++; @@ -169,30 +290,23 @@ BME_Poly *BME_addpolylist(BME_Mesh *bm, BME_Poly *example){ void BME_free_vert(BME_Mesh *bm, BME_Vert *v){ bm->totvert--; //CustomData_em_free_block(&bm->vdata, &v->data); - MEM_freeN(v); + BME_mempool_free(bm->vpool, v); } void BME_free_edge(BME_Mesh *bm, BME_Edge *e){ bm->totedge--; //CustomData_em_free_block(&bm->edata, &e->data); - MEM_freeN(e); + BME_mempool_free(bm->epool, e); } void BME_free_poly(BME_Mesh *bm, BME_Poly *f){ bm->totpoly--; //CustomData_em_free_block(&bm->pdata, &f->data); - MEM_freeN(f); -} -void BME_delete_loop(BME_Mesh *bm, BME_Loop *l){ - bm->totloop--; - //CustomData_em_free_block(&bm->ldata, &l->data); - MEM_freeN(l); + BME_mempool_free(bm->ppool, f); } void BME_free_loop(BME_Mesh *bm, BME_Loop *l){ - BME_CycleNode *loopref = l->gref; - BLI_freelinkN(&(bm->loops),loopref); - BME_delete_loop(bm,l); + bm->totloop--; + //CustomData_em_free_block(&bm->ldata, &l->data); + BME_mempool_free(bm->lpool, l); } - - /** * BMESH CYCLES * diff --git a/source/blender/blenkernel/intern/bmesh_private.h b/source/blender/blenkernel/intern/bmesh_private.h index ad90398bf66..ed58421ffb7 100644 --- a/source/blender/blenkernel/intern/bmesh_private.h +++ b/source/blender/blenkernel/intern/bmesh_private.h @@ -39,6 +39,15 @@ #include "BKE_bmesh.h" +/*MEMORY MANAGMENT*/ +struct BME_mempool; +typedef struct BME_mempool BME_mempool; + +struct BME_mempool *BME_mempool_create(int esize, int tote, int pchunk); +void BME_mempool_destroy(struct BME_mempool *pool); +void *BME_mempool_alloc(struct BME_mempool *pool); +void BME_mempool_free(struct BME_mempool *pool, void *address); + /*ALLOCATION/DEALLOCATION*/ struct BME_Vert *BME_addvertlist(struct BME_Mesh *bm, struct BME_Vert *example); struct BME_Edge *BME_addedgelist(struct BME_Mesh *bm, struct BME_Vert *v1, struct BME_Vert *v2, struct BME_Edge *example); @@ -49,7 +58,7 @@ void BME_free_vert(struct BME_Mesh *bm, struct BME_Vert *v); void BME_free_edge(struct BME_Mesh *bm, struct BME_Edge *e); void BME_free_poly(struct BME_Mesh *bm, struct BME_Poly *f); void BME_free_loop(struct BME_Mesh *bm, struct BME_Loop *l); -void BME_delete_loop(struct BME_Mesh *bm, struct BME_Loop *l); +//void BME_delete_loop(struct BME_Mesh *bm, struct BME_Loop *l); /*DOUBLE CIRCULAR LINKED LIST FUNCTIONS*/ void BME_cycle_append(void *h, void *nt); diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c index f9f17e7762d..6185e249b5a 100644 --- a/source/blender/blenkernel/intern/modifier.c +++ b/source/blender/blenkernel/intern/modifier.c @@ -2754,7 +2754,7 @@ static DerivedMesh *bevelModifier_applyModifier( //~ } //~ } - bm = BME_make_mesh(); + bm = BME_make_mesh(512,512,2048,512); bm = BME_derivedmesh_to_bmesh(derivedData, bm); BME_bevel(bm,bmd->value,bmd->res,options,defgrp_index,bmd->bevel_angle,NULL); result = BME_bmesh_to_derivedmesh(bm,derivedData); diff --git a/source/blender/src/editmesh_tools.c b/source/blender/src/editmesh_tools.c index d4ebe181218..d90a7eb7c16 100644 --- a/source/blender/src/editmesh_tools.c +++ b/source/blender/src/editmesh_tools.c @@ -4497,7 +4497,7 @@ void bevel_menu() { while(G.editBMesh->options & BME_BEVEL_RUNNING) { options = G.editBMesh->options; res = G.editBMesh->res; - bm = BME_make_mesh(); + bm = BME_make_mesh(512,512,2048,512); bm = BME_editmesh_to_bmesh(G.editMesh, bm); BIF_undo_push("Pre-Bevel"); free_editMesh(G.editMesh); From 33321d13d32a960be7e3aa7ee652ad4b23667d97 Mon Sep 17 00:00:00 2001 From: Geoffrey Bantle Date: Sun, 1 Jun 2008 18:02:29 +0000 Subject: [PATCH 134/246] -> Beginning of Custom Data support for BMesh Now that new allocator is in place, Custom Data can be effeciently added to BMesh. The plan is to make all data not directly related to topology Custom Data and allow callers to decide precisely what information a mesh should have in order to make the best tradeoff between memory usage/speed. Right now not much to look at, just some structure definitions and commented out code. More to come soon... --- source/blender/blenkernel/BKE_bmesh.h | 67 ++++++++++++++++++- source/blender/blenkernel/intern/BME_mesh.c | 30 +++++++-- .../blender/blenkernel/intern/bmesh_private.h | 4 -- 3 files changed, 87 insertions(+), 14 deletions(-) diff --git a/source/blender/blenkernel/BKE_bmesh.h b/source/blender/blenkernel/BKE_bmesh.h index 87202ce047a..ab2fd34cd42 100644 --- a/source/blender/blenkernel/BKE_bmesh.h +++ b/source/blender/blenkernel/BKE_bmesh.h @@ -41,18 +41,79 @@ #include "BLI_ghash.h" #include "BLI_memarena.h" #include "DNA_customdata_types.h" +#include "DNA_image_types.h" #include "BLI_editVert.h" #include "BKE_DerivedMesh.h" #include "transform.h" +/*forward declerations*/ struct BME_Vert; struct BME_Edge; struct BME_Poly; struct BME_Loop; + struct BME_mempool; typedef struct BME_mempool BME_mempool; +/*Custom Data Types and defines + Eventual plan is to move almost everything to custom data and let caller + decide when making the mesh what layers they want to store in the mesh + + This stuff should probably go in a seperate file.... +*/ +typedef struct BME_CustomDataLayer { + int type; /* type of data in layer */ + int offset; /* offset of layer in block */ + int active; /* offset of active layer*/ + char name[32]; /* layer name */ +} BME_CustomDataLayer; + +typedef struct BME_CustomData { + BME_CustomDataLayer *layers; /*Custom Data Layers*/ + BME_mempool *pool; /*pool for alloc of blocks*/ + int totlayer, totsize; /*total layers and total size in bytes of each block*/ +} BME_CustomData; + +#define BME_CD_FACETEX 1 /*Image texture/texface*/ +#define BME_CD_LOOPTEX 2 /*UV coordinates*/ +#define BME_CD_LOOPCOL 3 /*Vcolors*/ +#define BME_CD_DEFORMVERT 4 /*Vertex Group/Weights*/ +#define BME_CD_NUMTYPES 5 + +typedef struct BME_DeformWeight { + int def_nr; + float weight; +} BME_DeformWeight; + +typedef struct BME_DeformVert { + struct BME_DeformWeight *dw; + int totweight; +} BME_DeformVert; + +typedef struct BME_facetex{ + struct Image *tpage; + char flag, transp; + short mode, tile, unwrap; +}BME_facetex; + +typedef struct BME_looptex{ + float u, v; +}BME_looptex; + +typedef struct BME_loopcol{ + char r, g, b, a; +}BME_loopcol; + +/*Notes on further structure Cleanup: + -Remove the tflags, they belong in custom data layers + -Remove the eflags completely, they are mostly not used + -Remove the selection/vis/bevel weight flag/values ect and move them to custom data + -Remove EID member and move to custom data + -Add a radial cycle length, disk cycle length and loop cycle lenght attributes to custom data and have eulers maintain/use them if present. + -Move data such as vertex coordinates/normals to custom data and leave pointers in structures to active layer data. + -Remove BME_CycleNode structure? +*/ typedef struct BME_CycleNode{ struct BME_CycleNode *next, *prev; void *data; @@ -72,9 +133,9 @@ typedef struct BME_Mesh struct BME_Loop **lpar; struct BME_Poly **plar; int vtarlen, edarlen, lparlen, plarlen; - int totvert, totedge, totpoly, totloop; /*record keeping*/ - int nextv, nexte, nextp, nextl; /*Next element ID for verts/edges/faces/loops. Never reused*/ - //struct CustomData vdata, edata, pdata, ldata; /*Custom Data Layer information*/ + int totvert, totedge, totpoly, totloop; /*record keeping*/ + int nextv, nexte, nextp, nextl; /*Next element ID for verts/edges/faces/loops. Never reused*/ + struct BME_CustomData vdata, edata, pdata, ldata; /*Custom Data Layer information*/ } BME_Mesh; typedef struct BME_Vert diff --git a/source/blender/blenkernel/intern/BME_mesh.c b/source/blender/blenkernel/intern/BME_mesh.c index 307047463cf..e12ba2f8c65 100644 --- a/source/blender/blenkernel/intern/BME_mesh.c +++ b/source/blender/blenkernel/intern/BME_mesh.c @@ -62,8 +62,7 @@ * Allocates a new BME_Mesh structure */ - - +//BME_Mesh *BME_make_mesh(int valloc, int ealloc, int lalloc, int palloc, int vdata[BME_CD_NUMTYPES], int edata[BME_CD_NUMTYPES], int ldata[BME_CD_NUMTYPES], int pdata[BME_CD_NUMTYPES]) BME_Mesh *BME_make_mesh(int valloc, int ealloc, int lalloc, int palloc){ /*allocate the structure*/ BME_Mesh *bm = MEM_callocN(sizeof(BME_Mesh),"BMesh"); @@ -72,11 +71,17 @@ BME_Mesh *BME_make_mesh(int valloc, int ealloc, int lalloc, int palloc){ bm->epool = BME_mempool_create(sizeof(BME_Edge), ealloc, ealloc); bm->ppool = BME_mempool_create(sizeof(BME_Poly), palloc, palloc); bm->lpool = BME_mempool_create(sizeof(BME_Loop), lalloc, lalloc); - /*allocate the customdata pools*/ + + /*Setup Custom data structs and layers*/ + /* + BME_CD_Create(bm, &bm->vdata, vdata); + BME_CD_Create(bm, &bm->edata, edata); + BME_CD_Create(bm, &bm->ldata, ldata); + BME_CD_Create(bm, &bm->pdata, pdata); + + */ return bm; } - - /* * BME FREE MESH * @@ -90,8 +95,12 @@ void BME_free_mesh(BME_Mesh *bm) BME_mempool_destroy(bm->epool); BME_mempool_destroy(bm->ppool); BME_mempool_destroy(bm->lpool); - /*destroy custom data pools*/ - + /* + BME_CD_Free(bm, &bm->vdata); + BME_CD_Free(bm, &bm->edata); + BME_CD_Free(bm, &bm->ldata); + BME_CD_Free(bm, &bm->pdata); + */ MEM_freeN(bm); } @@ -156,6 +165,13 @@ void BME_model_end(BME_Mesh *bm){ } } +/*note, this needs to be turned on for debugging only. + We need two levels of debugging, + 1: Mesh level + 2: Euler level + Both need to be turned off in production builds (they really slow things down) +*/ + /* * BME VALIDATE MESH * diff --git a/source/blender/blenkernel/intern/bmesh_private.h b/source/blender/blenkernel/intern/bmesh_private.h index ed58421ffb7..4aa2a85b8b1 100644 --- a/source/blender/blenkernel/intern/bmesh_private.h +++ b/source/blender/blenkernel/intern/bmesh_private.h @@ -39,10 +39,6 @@ #include "BKE_bmesh.h" -/*MEMORY MANAGMENT*/ -struct BME_mempool; -typedef struct BME_mempool BME_mempool; - struct BME_mempool *BME_mempool_create(int esize, int tote, int pchunk); void BME_mempool_destroy(struct BME_mempool *pool); void *BME_mempool_alloc(struct BME_mempool *pool); From 85e77e53ef29274d456ecfdb95ec2a60cb5253f1 Mon Sep 17 00:00:00 2001 From: Geoffrey Bantle Date: Sun, 1 Jun 2008 18:43:22 +0000 Subject: [PATCH 135/246] -> Fix for last few commits New memory allocator broke compilation on GCC/Linux. Fixed --- source/blender/blenkernel/BKE_bmesh.h | 8 ++++++-- source/blender/blenkernel/intern/BME_structure.c | 6 ------ 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/source/blender/blenkernel/BKE_bmesh.h b/source/blender/blenkernel/BKE_bmesh.h index ab2fd34cd42..e44e9e02aaa 100644 --- a/source/blender/blenkernel/BKE_bmesh.h +++ b/source/blender/blenkernel/BKE_bmesh.h @@ -53,8 +53,12 @@ struct BME_Poly; struct BME_Loop; -struct BME_mempool; -typedef struct BME_mempool BME_mempool; +/*structure for fast memory allocation/frees*/ +typedef struct BME_mempool{ + struct ListBase chunks; + int esize, csize, pchunk; /*size of elements and chunks in bytes and number of elements per chunk*/ + struct BME_freenode *free; /*free element list. Interleaved into chunk datas.*/ +}BME_mempool; /*Custom Data Types and defines Eventual plan is to move almost everything to custom data and let caller diff --git a/source/blender/blenkernel/intern/BME_structure.c b/source/blender/blenkernel/intern/BME_structure.c index d261238d128..8f885d6c2cb 100644 --- a/source/blender/blenkernel/intern/BME_structure.c +++ b/source/blender/blenkernel/intern/BME_structure.c @@ -57,12 +57,6 @@ typedef struct BME_freenode{ struct BME_freenode *next; }BME_freenode; -typedef struct BME_mempool{ - struct ListBase chunks; - int esize, csize, pchunk; /*size of elements and chunks in bytes and number of elements per chunk*/ - struct BME_freenode *free; /*free element list. Interleaved into chunk datas.*/ -}BME_mempool; - BME_mempool *BME_mempool_create(int esize, int tote, int pchunk) { BME_mempool *pool = NULL; BME_freenode *lasttail = NULL, *curnode = NULL; From 86a0afb8295c2ba6560f8ceb9b35c873b614317e Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Mon, 2 Jun 2008 01:02:08 +0000 Subject: [PATCH 136/246] Compiler warning fixes (unused vars). Notes: - edgehash.c still has some weirdo code causing warnings on lines 80 and 117 i.e. if (v1verts)); totedge = BLI_countlist(&(bm->edges)); From 8a2a91ddfe635d2f2d26f1434512b0859811abcc Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Mon, 2 Jun 2008 02:54:33 +0000 Subject: [PATCH 137/246] Added missing newline for error print in Py-button expressions --- source/blender/python/BPY_interface.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/python/BPY_interface.c b/source/blender/python/BPY_interface.c index 279c3727442..c63fa28c46e 100644 --- a/source/blender/python/BPY_interface.c +++ b/source/blender/python/BPY_interface.c @@ -2103,7 +2103,7 @@ int BPY_button_eval(char *expr, double *value) if (!bpy_pydriver_Dict) { if (bpy_pydriver_create_dict() != 0) { fprintf(stderr, - "Button Python Eval error: couldn't create Python dictionary"); + "Button Python Eval error: couldn't create Python dictionary \n"); PyGILState_Release(gilstate); return -1; } From 1cc61f633fb16a4aca576bccef365f8e515c5a3d Mon Sep 17 00:00:00 2001 From: Benoit Bolsee Date: Mon, 2 Jun 2008 17:31:05 +0000 Subject: [PATCH 138/246] Patch #11000 approved: [new function] KX_GameObject::alignAxisToVect() Align an object's axis to a given vector --- source/gameengine/Ketsji/KX_GameObject.cpp | 81 +++++++++++++++++++++- source/gameengine/Ketsji/KX_GameObject.h | 10 +++ source/gameengine/PyDoc/KX_GameObject.py | 15 +++- 3 files changed, 104 insertions(+), 2 deletions(-) diff --git a/source/gameengine/Ketsji/KX_GameObject.cpp b/source/gameengine/Ketsji/KX_GameObject.cpp index dada47e2fa4..c192cd01261 100644 --- a/source/gameengine/Ketsji/KX_GameObject.cpp +++ b/source/gameengine/Ketsji/KX_GameObject.cpp @@ -580,7 +580,68 @@ void KX_GameObject::SetObjectColor(const MT_Vector4& rgbavec) m_objectColor = rgbavec; } +void KX_GameObject::AlignAxisToVect(const MT_Vector3& dir, int axis) +{ + MT_Matrix3x3 orimat; + MT_Vector3 vect,ori,z,x,y; + MT_Scalar len; + vect = dir; + len = vect.length(); + if (MT_fuzzyZero(len)) + { + cout << "alignAxisToVect() Error: Null vector!\n"; + return; + } + // normalize + vect /= len; + orimat = GetSGNode()->GetWorldOrientation(); + switch (axis) + { + case 0: //x axis + ori = MT_Vector3(orimat[0][2], orimat[1][2], orimat[2][2]); //pivot axis + if (MT_abs(vect.dot(ori)) > 1.0-3.0*MT_EPSILON) //is the vector paralell to the pivot? + ori = MT_Vector3(orimat[0][1], orimat[1][1], orimat[2][1]); //change the pivot! + x = vect; + y = ori.cross(x); + z = x.cross(y); + break; + case 1: //y axis + ori = MT_Vector3(orimat[0][0], orimat[1][0], orimat[2][0]); + if (MT_abs(vect.dot(ori)) > 1.0-3.0*MT_EPSILON) + ori = MT_Vector3(orimat[0][2], orimat[1][2], orimat[2][2]); + y = vect; + z = ori.cross(y); + x = y.cross(z); + break; + case 2: //z axis + ori = MT_Vector3(orimat[0][1], orimat[1][1], orimat[2][1]); + if (MT_abs(vect.dot(ori)) > 1.0-3.0*MT_EPSILON) + ori = MT_Vector3(orimat[0][0], orimat[1][0], orimat[2][0]); + z = vect; + x = ori.cross(z); + y = z.cross(x); + break; + default: //wrong input? + cout << "alignAxisToVect(): Wrong axis '" << axis <<"'\n"; + return; + } + x.normalize(); //normalize the vectors + y.normalize(); + z.normalize(); + orimat = MT_Matrix3x3( x[0],y[0],z[0], + x[1],y[1],z[1], + x[2],y[2],z[2]); + if (GetSGNode()->GetSGParent() != NULL) + { + // the object is a child, adapt its local orientation so that + // the global orientation is aligned as we want. + MT_Matrix3x3 invori = GetSGNode()->GetSGParent()->GetWorldOrientation().inverse(); + NodeSetLocalOrientation(invori*orimat); + } + else + NodeSetLocalOrientation(orimat); +} MT_Vector3 KX_GameObject::GetLinearVelocity(bool local) { @@ -723,6 +784,7 @@ void KX_GameObject::Suspend(void) PyMethodDef KX_GameObject::Methods[] = { {"setVisible",(PyCFunction) KX_GameObject::sPySetVisible, METH_VARARGS}, + {"alignAxisToVect",(PyCFunction) KX_GameObject::sPyAlignAxisToVect, METH_VARARGS}, {"setPosition", (PyCFunction) KX_GameObject::sPySetPosition, METH_VARARGS}, {"getPosition", (PyCFunction) KX_GameObject::sPyGetPosition, METH_VARARGS}, {"getOrientation", (PyCFunction) KX_GameObject::sPyGetOrientation, METH_VARARGS}, @@ -1255,7 +1317,24 @@ PyObject* KX_GameObject::PySetOrientation(PyObject* self, return NULL; } - +PyObject* KX_GameObject::PyAlignAxisToVect(PyObject* self, + PyObject* args, + PyObject* kwds) +{ + PyObject* pyvect; + int axis = 2; //z axis is the default + + if (PyArg_ParseTuple(args,"O|i",&pyvect,&axis)) + { + MT_Vector3 vect; + if (PyVecTo(pyvect, vect)) + { + AlignAxisToVect(vect,axis); + Py_Return; + } + } + return NULL; +} PyObject* KX_GameObject::PySetPosition(PyObject* self, PyObject* args, diff --git a/source/gameengine/Ketsji/KX_GameObject.h b/source/gameengine/Ketsji/KX_GameObject.h index 3758651f53d..56b9f3f6375 100644 --- a/source/gameengine/Ketsji/KX_GameObject.h +++ b/source/gameengine/Ketsji/KX_GameObject.h @@ -258,6 +258,15 @@ public: bool local=false ); + /** + * Align the object to a given normal. + */ + void + AlignAxisToVect( + const MT_Vector3& vect, + int axis = 2 + ); + /** * Quick'n'dirty obcolor ipo stuff */ @@ -662,6 +671,7 @@ public: KX_PYMETHOD(KX_GameObject,GetOrientation); KX_PYMETHOD(KX_GameObject,SetOrientation); KX_PYMETHOD(KX_GameObject,SetVisible); + KX_PYMETHOD(KX_GameObject,AlignAxisToVect); KX_PYMETHOD(KX_GameObject,SuspendDynamics); KX_PYMETHOD(KX_GameObject,RestoreDynamics); KX_PYMETHOD(KX_GameObject,EnableRigidBody); diff --git a/source/gameengine/PyDoc/KX_GameObject.py b/source/gameengine/PyDoc/KX_GameObject.py index fbd896a55d1..8d29a704380 100644 --- a/source/gameengine/PyDoc/KX_GameObject.py +++ b/source/gameengine/PyDoc/KX_GameObject.py @@ -51,6 +51,18 @@ class KX_GameObject: @type orn: 3x3 rotation matrix, or Quaternion. @param orn: a rotation matrix specifying the new rotation. """ + def alignAxisToVect(vect, axis): + """ + Aligns any of the game object's axis along the given vector. + + @type vect: 3d vector. + @param vect: a vector to align the axis. + @type axis: integer. + @param axis:The axis you want to align + - 0: X axis + - 1: Y axis + - 2: Z axis (default) + """ def getOrientation(): """ Gets the game object's orientation. @@ -213,4 +225,5 @@ class KX_GameObject: @rtype: 3-tuple (L{KX_GameObject}, 3-tuple (x,y,z), 3-tuple (nx,ny,nz)) @return: (object,hitpoint,hitnormal) or (None,None,None) """ - \ No newline at end of file + + From 8a5f36219214b4a5b8348b8e200ef5aac2297963 Mon Sep 17 00:00:00 2001 From: Geoffrey Bantle Date: Mon, 2 Jun 2008 20:52:40 +0000 Subject: [PATCH 139/246] -> More Bmesh Custom Data stuff Some more Bmesh custom data functions and structures. This still does not do anything yet because the various conversion functions don't bother making use of the new custom data functions. Hooking them up should be fairly simple though. Also note that the custom data code is mostly copy/pasted from the existing custom data functions for editmode with a few modifications. Duplicating code like this isn't nice, but I felt it was better to keep things for Bmesh 'standalone' for the moment and take only what is immediatly needed instead of creating a tangle of interdependant code. --- source/blender/blenkernel/BKE_bmesh.h | 59 +----- .../blender/blenkernel/BKE_bmeshCustomData.h | 108 ++++++++++ .../blenkernel/intern/BME_Customdata.c | 197 ++++++++++++++++++ .../blenkernel/intern/BME_conversions.c | 22 +- source/blender/blenkernel/intern/BME_mesh.c | 92 ++++---- .../blender/blenkernel/intern/BME_structure.c | 44 ++-- source/blender/blenkernel/intern/modifier.c | 4 +- source/blender/src/editmesh_tools.c | 8 +- 8 files changed, 406 insertions(+), 128 deletions(-) create mode 100644 source/blender/blenkernel/BKE_bmeshCustomData.h create mode 100644 source/blender/blenkernel/intern/BME_Customdata.c diff --git a/source/blender/blenkernel/BKE_bmesh.h b/source/blender/blenkernel/BKE_bmesh.h index e44e9e02aaa..51a5d29dbb7 100644 --- a/source/blender/blenkernel/BKE_bmesh.h +++ b/source/blender/blenkernel/BKE_bmesh.h @@ -40,11 +40,11 @@ #include "DNA_listBase.h" #include "BLI_ghash.h" #include "BLI_memarena.h" -#include "DNA_customdata_types.h" #include "DNA_image_types.h" #include "BLI_editVert.h" #include "BKE_DerivedMesh.h" #include "transform.h" +#include "BKE_bmeshCustomData.h" /*forward declerations*/ struct BME_Vert; @@ -60,55 +60,6 @@ typedef struct BME_mempool{ struct BME_freenode *free; /*free element list. Interleaved into chunk datas.*/ }BME_mempool; -/*Custom Data Types and defines - Eventual plan is to move almost everything to custom data and let caller - decide when making the mesh what layers they want to store in the mesh - - This stuff should probably go in a seperate file.... -*/ -typedef struct BME_CustomDataLayer { - int type; /* type of data in layer */ - int offset; /* offset of layer in block */ - int active; /* offset of active layer*/ - char name[32]; /* layer name */ -} BME_CustomDataLayer; - -typedef struct BME_CustomData { - BME_CustomDataLayer *layers; /*Custom Data Layers*/ - BME_mempool *pool; /*pool for alloc of blocks*/ - int totlayer, totsize; /*total layers and total size in bytes of each block*/ -} BME_CustomData; - -#define BME_CD_FACETEX 1 /*Image texture/texface*/ -#define BME_CD_LOOPTEX 2 /*UV coordinates*/ -#define BME_CD_LOOPCOL 3 /*Vcolors*/ -#define BME_CD_DEFORMVERT 4 /*Vertex Group/Weights*/ -#define BME_CD_NUMTYPES 5 - -typedef struct BME_DeformWeight { - int def_nr; - float weight; -} BME_DeformWeight; - -typedef struct BME_DeformVert { - struct BME_DeformWeight *dw; - int totweight; -} BME_DeformVert; - -typedef struct BME_facetex{ - struct Image *tpage; - char flag, transp; - short mode, tile, unwrap; -}BME_facetex; - -typedef struct BME_looptex{ - float u, v; -}BME_looptex; - -typedef struct BME_loopcol{ - char r, g, b, a; -}BME_loopcol; - /*Notes on further structure Cleanup: -Remove the tflags, they belong in custom data layers -Remove the eflags completely, they are mostly not used @@ -196,7 +147,7 @@ typedef struct BME_Poly unsigned short flag, h, mat_nr; } BME_Poly; -//*EDGE UTILITIES*/ +/*EDGE UTILITIES*/ int BME_verts_in_edge(struct BME_Vert *v1, struct BME_Vert *v2, struct BME_Edge *e); int BME_vert_in_edge(struct BME_Edge *e, BME_Vert *v); struct BME_Vert *BME_edge_getothervert(struct BME_Edge *e, struct BME_Vert *v); @@ -218,7 +169,7 @@ int BME_radial_find_face(struct BME_Edge *e,struct BME_Poly *f); struct BME_Loop *BME_loop_find_loop(struct BME_Poly *f, struct BME_Vert *v); /*MESH CREATION/DESTRUCTION*/ -struct BME_Mesh *BME_make_mesh(int valloc, int ealloc, int lalloc, int palloc); +struct BME_Mesh *BME_make_mesh(int allocsize[4], struct BME_CustomDataInit init[4]); void BME_free_mesh(struct BME_Mesh *bm); /*FULL MESH VALIDATION*/ int BME_validate_mesh(struct BME_Mesh *bm, int halt); @@ -302,8 +253,8 @@ float *BME_bevel_calc_polynormal(struct BME_Poly *f, struct BME_TransData_Head * struct BME_Mesh *BME_bevel(struct BME_Mesh *bm, float value, int res, int options, int defgrp_index, float angle, BME_TransData_Head **rtd); /*CONVERSION FUNCTIONS*/ -struct BME_Mesh *BME_editmesh_to_bmesh(EditMesh *em, struct BME_Mesh *bm); +struct BME_Mesh *BME_editmesh_to_bmesh(EditMesh *em); struct EditMesh *BME_bmesh_to_editmesh(struct BME_Mesh *bm, BME_TransData_Head *td); -struct BME_Mesh *BME_derivedmesh_to_bmesh(struct DerivedMesh *dm, struct BME_Mesh *bm); +struct BME_Mesh *BME_derivedmesh_to_bmesh(struct DerivedMesh *dm); struct DerivedMesh *BME_bmesh_to_derivedmesh(struct BME_Mesh *bm, struct DerivedMesh *dm); #endif diff --git a/source/blender/blenkernel/BKE_bmeshCustomData.h b/source/blender/blenkernel/BKE_bmeshCustomData.h new file mode 100644 index 00000000000..423f75e532d --- /dev/null +++ b/source/blender/blenkernel/BKE_bmeshCustomData.h @@ -0,0 +1,108 @@ +/** + * BKE_bmesh.h jan 2007 + * + * BMesh modeler structure and functions. + * + * $Id: BKE_bmesh.h,v 1.00 2007/01/17 17:42:01 Briggs Exp $ + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2004 Blender Foundation. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): Geoffrey Bantle. + * + * ***** END GPL LICENSE BLOCK ***** + */ + + +#ifndef BKE_BMESHCUSTOMDATA_H +#define BKE_BMESHCUSTOMDATA_H + +struct BME_mempool; + +/*Custom Data Types and defines + Eventual plan is to move almost everything to custom data and let caller + decide when making the mesh what layers they want to store in the mesh + + This stuff should probably go in a seperate file.... +*/ + +#define BME_CD_FACETEX 0 /*Image texture/texface*/ +#define BME_CD_LOOPTEX 1 /*UV coordinates*/ +#define BME_CD_LOOPCOL 2 /*Vcolors*/ +#define BME_CD_DEFORMVERT 3 /*Vertex Group/Weights*/ +#define BME_CD_NUMTYPES 4 + +typedef struct BME_CustomDataLayer { + int type; /* type of data in layer */ + int offset; /* offset of layer in block */ + int active; /* offset of active layer*/ + char name[32]; /* layer name */ +} BME_CustomDataLayer; + +typedef struct BME_CustomData { + struct BME_CustomDataLayer *layers; /*Custom Data Layers*/ + struct BME_mempool *pool; /*pool for alloc of blocks*/ + int totlayer, totsize; /*total layers and total size in bytes of each block*/ +} BME_CustomData; + +typedef struct BME_CustomDataInit{ + int layout[BME_CD_NUMTYPES]; + int active[BME_CD_NUMTYPES]; + int totlayers; + char *nametemplate; +} BME_CustomDataInit; + +/*Custom data types*/ +typedef struct BME_DeformWeight { + int def_nr; + float weight; +} BME_DeformWeight; + +typedef struct BME_DeformVert { + struct BME_DeformWeight *dw; + int totweight; +} BME_DeformVert; + +typedef struct BME_facetex{ + struct Image *tpage; + char flag, transp; + short mode, tile, unwrap; +}BME_facetex; + +typedef struct BME_looptex{ + float u, v; +}BME_looptex; + +typedef struct BME_loopcol{ + char r, g, b, a; +}BME_loopcol; + +/*CUSTOM DATA API*/ +void BME_CD_Create(struct BME_CustomData *data, struct BME_CustomDataInit *init, int initalloc); +void BME_CD_Free(struct BME_CustomData *data); +void BME_CD_free_block(struct BME_CustomData *data, void **block); +void BME_CD_copy_data(const struct BME_CustomData *source, struct BME_CustomData *dest, void *src_block, void **dest_block); +void BME_CD_set_default(struct BME_CustomData *data, void **block); + +#endif diff --git a/source/blender/blenkernel/intern/BME_Customdata.c b/source/blender/blenkernel/intern/BME_Customdata.c new file mode 100644 index 00000000000..68bc75327d9 --- /dev/null +++ b/source/blender/blenkernel/intern/BME_Customdata.c @@ -0,0 +1,197 @@ +/** + * BME_customdata.c jan 2007 + * + * Custom Data functions for Bmesh + * + * $Id: BKE_bmesh.h,v 1.00 2007/01/17 17:42:01 Briggs Exp $ + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2004 Blender Foundation. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): Geoffrey Bantle, Brecht Van Lommel, Ben Batt + * + * ***** END GPL LICENSE BLOCK ***** + */ + + +#include "BKE_bmesh.h" +#include "BKE_bmeshCustomData.h" +#include "bmesh_private.h" +#include + +/********************* Layer type information **********************/ +typedef struct BME_LayerTypeInfo { + int size; + char *defaultname; + void (*copy)(const void *source, void *dest, int count); + void (*free)(void *data, int count, int size); + void (*interp)(void **sources, float *weights, float *sub_weights, int count, void *dest); + void (*set_default)(void *data, int count); +} BME_LayerTypeInfo; +const BME_LayerTypeInfo BMELAYERTYPEINFO[BME_CD_NUMTYPES] = { + {sizeof(BME_facetex), "TexFace", NULL, NULL, NULL, NULL}, + {sizeof(BME_looptex), "UV", NULL, NULL, NULL, NULL}, + {sizeof(BME_loopcol), "VCol", NULL, NULL, NULL, NULL}, + {sizeof(BME_DeformVert), "Group", NULL, NULL, NULL, NULL} +}; +static const BME_LayerTypeInfo *BME_layerType_getInfo(int type) +{ + if(type < 0 || type >= CD_NUMTYPES) return NULL; + + return &BMELAYERTYPEINFO[type]; +} +void BME_CD_Create(BME_CustomData *data, BME_CustomDataInit *init, int initalloc) +{ + int i, j, offset=0; + const BME_LayerTypeInfo *info; + + /*initialize data members*/ + data->layers = NULL; + data->pool = NULL; + data->totlayer = 0; + data->totsize = 0; + + /*first count how many layers to alloc*/ + for(i=0; i < BME_CD_NUMTYPES; i++){ + info = BME_layerType_getInfo(i); + data->totlayer += init->layout[i]; + data->totsize += (init->layout[i] * info->size); + } + /*alloc our layers*/ + if(data->totlayer){ + /*alloc memory*/ + data->layers = MEM_callocN(sizeof(BME_CustomDataLayer)*data->totlayer, "BMesh Custom Data Layers"); + data->pool = BME_mempool_create(data->totsize, initalloc, initalloc); + /*initialize layer data*/ + for(i=0; i < BME_CD_NUMTYPES; i++){ + if(init->layout[i]){ + info = BME_layerType_getInfo(i); + for(j=0; j < init->layout[i]; j++){ + if(j=0) data->layers[j+i].active = init->active[i]; + data->layers[j+i].type = i; + data->layers[j+i].offset = offset; + strcpy(data->layers[j+i].name, &(init->nametemplate[j+i])); + offset += info->size; + } + } + } + } +} + +void BME_CD_Free(BME_CustomData *data) +{ + if(data->pool) BME_mempool_destroy(data->pool); +} + +/*Block level ops*/ +void BME_CD_free_block(BME_CustomData *data, void **block) +{ + const BME_LayerTypeInfo *typeInfo; + int i; + + if(!*block) return; + for(i = 0; i < data->totlayer; ++i) { + typeInfo = BME_layerType_getInfo(data->layers[i].type); + if(typeInfo->free) { + int offset = data->layers[i].offset; + typeInfo->free((char*)*block + offset, 1, typeInfo->size); + } + } + BME_mempool_free(data->pool, *block); + *block = NULL; +} + + +static void BME_CD_alloc_block(BME_CustomData *data, void **block) +{ + + if (*block) BME_CD_free_block(data, block); //if we copy layers that have their own free functions like deformverts + + if (data->totsize > 0) + *block = BME_mempool_alloc(data->pool); + else + *block = NULL; +} + +void BME_CD_copy_data(const BME_CustomData *source, BME_CustomData *dest, + void *src_block, void **dest_block) +{ + const BME_LayerTypeInfo *typeInfo; + int dest_i, src_i; + + if (!*dest_block) /*for addXXXlist functions!*/ + BME_CD_alloc_block(dest, dest_block); + + /* copies a layer at a time */ + dest_i = 0; + for(src_i = 0; src_i < source->totlayer; ++src_i) { + + /* find the first dest layer with type >= the source type + * (this should work because layers are ordered by type) + */ + while(dest_i < dest->totlayer + && dest->layers[dest_i].type < source->layers[src_i].type) + ++dest_i; + + /* if there are no more dest layers, we're done */ + if(dest_i >= dest->totlayer) return; + + /* if we found a matching layer, copy the data */ + if(dest->layers[dest_i].type == source->layers[src_i].type && + strcmp(dest->layers[dest_i].name, source->layers[src_i].name) == 0) { + char *src_data = (char*)src_block + source->layers[src_i].offset; + char *dest_data = (char*)*dest_block + dest->layers[dest_i].offset; + + typeInfo = BME_layerType_getInfo(source->layers[src_i].type); + + if(typeInfo->copy) + typeInfo->copy(src_data, dest_data, 1); + else + memcpy(dest_data, src_data, typeInfo->size); + + /* if there are multiple source & dest layers of the same type, + * we don't want to copy all source layers to the same dest, so + * increment dest_i + */ + ++dest_i; + } + } +} +void BME_CD_set_default(BME_CustomData *data, void **block) +{ + const BME_LayerTypeInfo *typeInfo; + int i; + + if (!*block) + BME_CD_alloc_block(data, block); //for addXXXlist functions... + + for(i = 0; i < data->totlayer; ++i) { + int offset = data->layers[i].offset; + + typeInfo = BME_layerType_getInfo(data->layers[i].type); + + if(typeInfo->set_default) + typeInfo->set_default((char*)*block + offset, 1); + } +} diff --git a/source/blender/blenkernel/intern/BME_conversions.c b/source/blender/blenkernel/intern/BME_conversions.c index 369c19b16c8..08483711c45 100644 --- a/source/blender/blenkernel/intern/BME_conversions.c +++ b/source/blender/blenkernel/intern/BME_conversions.c @@ -55,7 +55,10 @@ #include "BSE_edit.h" -BME_Mesh *BME_editmesh_to_bmesh(EditMesh *em, BME_Mesh *bm) { +BME_Mesh *BME_editmesh_to_bmesh(EditMesh *em) { + BME_Mesh *bm; + int allocsize[4] = {512,512,2048,512}; + BME_CustomDataInit *init = MEM_callocN(sizeof(BME_CustomDataInit) * 4, "Bmesh custom data init"); BME_Vert *v1, *v2; BME_Edge *e, *edar[4]; BME_Poly *f; @@ -65,7 +68,7 @@ BME_Mesh *BME_editmesh_to_bmesh(EditMesh *em, BME_Mesh *bm) { EditFace *efa; int len; - + bm = BME_make_mesh(allocsize,init); BME_model_begin(bm); /*add verts*/ @@ -134,6 +137,7 @@ BME_Mesh *BME_editmesh_to_bmesh(EditMesh *em, BME_Mesh *bm) { efa = efa->next; } BME_model_end(bm); + MEM_freeN(init); return bm; } @@ -224,21 +228,24 @@ EditMesh *BME_bmesh_to_editmesh(BME_Mesh *bm, BME_TransData_Head *td) { } /* Adds the geometry found in dm to bm - * NOTE: it does not allocate a new BME_Mesh! - */ -BME_Mesh *BME_derivedmesh_to_bmesh(DerivedMesh *dm, BME_Mesh *bm) + */ +BME_Mesh *BME_derivedmesh_to_bmesh(DerivedMesh *dm) { + + BME_Mesh *bm; + int allocsize[4] = {512,512,2048,512}; + BME_CustomDataInit *init = MEM_callocN(sizeof(BME_CustomDataInit) * 4, "Bmesh custom data init"); MVert *mvert, *mv; MEdge *medge, *me; MFace *mface, *mf; int totface,totedge,totvert,i,len; - BME_Vert *v1=NULL,*v2=NULL, **vert_array; BME_Edge *e=NULL; BME_Poly *f=NULL; EdgeHash *edge_hash = BLI_edgehash_new(); - + + bm = BME_make_mesh(allocsize,init); totvert = dm->getNumVerts(dm); totedge = dm->getNumEdges(dm); totface = dm->getNumFaces(dm); @@ -293,6 +300,7 @@ BME_Mesh *BME_derivedmesh_to_bmesh(DerivedMesh *dm, BME_Mesh *bm) BME_model_end(bm); BLI_edgehash_free(edge_hash, NULL); MEM_freeN(vert_array); + MEM_freeN(init); return bm; } diff --git a/source/blender/blenkernel/intern/BME_mesh.c b/source/blender/blenkernel/intern/BME_mesh.c index 0423d9a0ac6..184ef2b8a0e 100644 --- a/source/blender/blenkernel/intern/BME_mesh.c +++ b/source/blender/blenkernel/intern/BME_mesh.c @@ -59,27 +59,37 @@ /* * BME MAKE MESH * - * Allocates a new BME_Mesh structure + * Allocates a new BME_Mesh structure. + * The arguments are two arrays, one of type int + * and another of type BME_CustomDataInit. The first array + * contains the allocation size for each element pool in + * the mesh. For instance allocsize[0] contains the number + * of vertices to allocate at a time for the vertex pool. + * + * The second array contains structures describing the layout + * of custom data for each element type in the mesh. So init[0] + * contains the custom data layout information for vertices, init[1] + * the layout information for edges and so on. + * + * Returns - + * Pointer to a Bmesh + * */ -//BME_Mesh *BME_make_mesh(int valloc, int ealloc, int lalloc, int palloc, int vdata[BME_CD_NUMTYPES], int edata[BME_CD_NUMTYPES], int ldata[BME_CD_NUMTYPES], int pdata[BME_CD_NUMTYPES]) -BME_Mesh *BME_make_mesh(int valloc, int ealloc, int lalloc, int palloc){ +BME_Mesh *BME_make_mesh(int allocsize[4], BME_CustomDataInit init[4]) +{ /*allocate the structure*/ BME_Mesh *bm = MEM_callocN(sizeof(BME_Mesh),"BMesh"); /*allocate the memory pools for the mesh elements*/ - bm->vpool = BME_mempool_create(sizeof(BME_Vert), valloc, valloc); - bm->epool = BME_mempool_create(sizeof(BME_Edge), ealloc, ealloc); - bm->ppool = BME_mempool_create(sizeof(BME_Poly), palloc, palloc); - bm->lpool = BME_mempool_create(sizeof(BME_Loop), lalloc, lalloc); - - /*Setup Custom data structs and layers*/ - /* - BME_CD_Create(bm, &bm->vdata, vdata); - BME_CD_Create(bm, &bm->edata, edata); - BME_CD_Create(bm, &bm->ldata, ldata); - BME_CD_Create(bm, &bm->pdata, pdata); - - */ + bm->vpool = BME_mempool_create(sizeof(BME_Vert), allocsize[0], allocsize[0]); + bm->epool = BME_mempool_create(sizeof(BME_Edge), allocsize[1], allocsize[1]); + bm->lpool = BME_mempool_create(sizeof(BME_Loop), allocsize[2], allocsize[2]); + bm->ppool = BME_mempool_create(sizeof(BME_Poly), allocsize[3], allocsize[3]); + /*Setup custom data layers*/ + BME_CD_Create(&bm->vdata, &init[0], allocsize[0]); + BME_CD_Create(&bm->edata, &init[1], allocsize[1]); + BME_CD_Create(&bm->ldata, &init[2], allocsize[2]); + BME_CD_Create(&bm->pdata, &init[3], allocsize[3]); return bm; } /* @@ -90,17 +100,31 @@ BME_Mesh *BME_make_mesh(int valloc, int ealloc, int lalloc, int palloc){ void BME_free_mesh(BME_Mesh *bm) { + BME_Vert *v; + BME_Edge *e; + BME_Loop *l; + BME_Poly *f; + + for(v=bm->verts.first; v; v=v->next) BME_CD_free_block(&bm->vdata, &v->data); + for(e=bm->edges.first; e; e=e->next) BME_CD_free_block(&bm->edata, &e->data); + for(f=bm->polys.first; f; f=f->next){ + BME_CD_free_block(&bm->pdata, &f->data); + l = f->loopbase; + do{ + BME_CD_free_block(&bm->ldata, &l->data); + l = l->next; + }while(l!=f->loopbase); + } /*destroy element pools*/ BME_mempool_destroy(bm->vpool); BME_mempool_destroy(bm->epool); BME_mempool_destroy(bm->ppool); BME_mempool_destroy(bm->lpool); - /* - BME_CD_Free(bm, &bm->vdata); - BME_CD_Free(bm, &bm->edata); - BME_CD_Free(bm, &bm->ldata); - BME_CD_Free(bm, &bm->pdata); - */ + /*free custom data pools*/ + BME_CD_Free(&bm->vdata); + BME_CD_Free(&bm->edata); + BME_CD_Free(&bm->ldata); + BME_CD_Free(&bm->pdata); MEM_freeN(bm); } @@ -111,17 +135,12 @@ void BME_free_mesh(BME_Mesh *bm) * must begin with a call to BME_model_end() and finish with a call to BME_model_end(). * No modification of mesh data is allowed except in between these two calls. * - * TODO - * FOR BME_MODEL_BEGIN: - * -integrate euler undo system. - * -make full copy of structure to safely recover from errors. - * -accept a toolname string. - * -accept param to turn off full copy if just selection tool. (perhaps check for this in eulers...) + * The purpose of these calls is allow for housekeeping tasks to be performed, + * such as allocating/freeing scratch arrays or performing debug validation of + * the mesh structure. * - * BME_MODEL_END: - * -full mesh validation if debugging turned on - * -free structure copy or use it to restore. - * -do euler undo push. + * Returns - + * Nothing * */ @@ -165,13 +184,6 @@ void BME_model_end(BME_Mesh *bm){ } } -/*note, this needs to be turned on for debugging only. - We need two levels of debugging, - 1: Mesh level - 2: Euler level - Both need to be turned off in production builds (they really slow things down) -*/ - /* * BME VALIDATE MESH * @@ -187,7 +199,7 @@ void BME_model_end(BME_Mesh *bm){ * * TODO * - * -Write a full mesh validation function for debugging purposes. + * -Make this only part of debug builds */ #define VHALT(halt) {BME_error(); if(halt) return 0;} diff --git a/source/blender/blenkernel/intern/BME_structure.c b/source/blender/blenkernel/intern/BME_structure.c index 8f885d6c2cb..cbf780c6467 100644 --- a/source/blender/blenkernel/intern/BME_structure.c +++ b/source/blender/blenkernel/intern/BME_structure.c @@ -193,12 +193,12 @@ BME_Vert *BME_addvertlist(BME_Mesh *bm, BME_Vert *example){ bm->nextv++; bm->totvert++; - if(example) + if(example){ VECCOPY(v->co,example->co); - //if(example) - // CustomData_em_copy_data(&bm->vdata, &bm->vdata, example->data, &v->data); - //else - // CustomData_em_set_default(&bm->vdata, &v->data); + BME_CD_copy_data(&bm->vdata, &bm->vdata, example->data, &v->data); + } + else + BME_CD_set_default(&bm->vdata, &v->data); return v; } @@ -221,16 +221,15 @@ BME_Edge *BME_addedgelist(BME_Mesh *bm, BME_Vert *v1, BME_Vert *v2, BME_Edge *ex bm->totedge++; BLI_addtail(&(bm->edges), e); - //if(example) - // CustomData_em_copy_data(&bm->edata, &bm->edata, example->data, &e->data); - //else - // CustomData_em_set_default(&bm->edata, &e->data); + if(example) + BME_CD_copy_data(&bm->edata, &bm->edata, example->data, &e->data); + else + BME_CD_set_default(&bm->edata, &e->data); return e; } BME_Loop *BME_create_loop(BME_Mesh *bm, BME_Vert *v, BME_Edge *e, BME_Poly *f, BME_Loop *example){ - /*allocate a BME_Loop and add it to the loophash*/ BME_Loop *l=NULL; l = BME_mempool_alloc(bm->lpool); l->next = l->prev = NULL; @@ -246,12 +245,11 @@ BME_Loop *BME_create_loop(BME_Mesh *bm, BME_Vert *v, BME_Edge *e, BME_Poly *f, B bm->nextl++; bm->totloop++; - -/* if(example) - BME_CustomData_copy_data(&bm->ldata, &bm->ldata, example->data, &l->data); + if(example) + BME_CD_copy_data(&bm->ldata, &bm->ldata, example->data, &l->data); else - BME_CustomData_set_default(&bm->ldata, &l->data); -*/ + BME_CD_set_default(&bm->ldata, &l->data); + return l; } @@ -269,10 +267,10 @@ BME_Poly *BME_addpolylist(BME_Mesh *bm, BME_Poly *example){ bm->nextp++; bm->totpoly++; - //if(example) - // CustomData_em_copy_data(&bm->pdata, &bm->pdata, example->data, &f->data); - //else - // CustomData_em_set_default(&bm->pdata, &f->data); + if(example) + BME_CD_copy_data(&bm->pdata, &bm->pdata, example->data, &f->data); + else + BME_CD_set_default(&bm->pdata, &f->data); return f; @@ -283,22 +281,22 @@ BME_Poly *BME_addpolylist(BME_Mesh *bm, BME_Poly *example){ */ void BME_free_vert(BME_Mesh *bm, BME_Vert *v){ bm->totvert--; - //CustomData_em_free_block(&bm->vdata, &v->data); + BME_CD_free_block(&bm->vdata, &v->data); BME_mempool_free(bm->vpool, v); } void BME_free_edge(BME_Mesh *bm, BME_Edge *e){ bm->totedge--; - //CustomData_em_free_block(&bm->edata, &e->data); + BME_CD_free_block(&bm->edata, &e->data); BME_mempool_free(bm->epool, e); } void BME_free_poly(BME_Mesh *bm, BME_Poly *f){ bm->totpoly--; - //CustomData_em_free_block(&bm->pdata, &f->data); + BME_CD_free_block(&bm->pdata, &f->data); BME_mempool_free(bm->ppool, f); } void BME_free_loop(BME_Mesh *bm, BME_Loop *l){ bm->totloop--; - //CustomData_em_free_block(&bm->ldata, &l->data); + BME_CD_free_block(&bm->ldata, &l->data); BME_mempool_free(bm->lpool, l); } /** diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c index 6185e249b5a..efc250fdc0d 100644 --- a/source/blender/blenkernel/intern/modifier.c +++ b/source/blender/blenkernel/intern/modifier.c @@ -2736,6 +2736,7 @@ static DerivedMesh *bevelModifier_applyModifier( { DerivedMesh *result; BME_Mesh *bm; + /*bDeformGroup *def;*/ int /*i,*/ options, defgrp_index = -1; BevelModifierData *bmd = (BevelModifierData*) md; @@ -2754,8 +2755,7 @@ static DerivedMesh *bevelModifier_applyModifier( //~ } //~ } - bm = BME_make_mesh(512,512,2048,512); - bm = BME_derivedmesh_to_bmesh(derivedData, bm); + bm = BME_derivedmesh_to_bmesh(derivedData); BME_bevel(bm,bmd->value,bmd->res,options,defgrp_index,bmd->bevel_angle,NULL); result = BME_bmesh_to_derivedmesh(bm,derivedData); BME_free_mesh(bm); diff --git a/source/blender/src/editmesh_tools.c b/source/blender/src/editmesh_tools.c index d90a7eb7c16..f85161c3e23 100644 --- a/source/blender/src/editmesh_tools.c +++ b/source/blender/src/editmesh_tools.c @@ -4480,6 +4480,11 @@ static void bevel_mesh_recurs(float bsize, short recurs, int allfaces) } void bevel_menu() { + int vlayers[BME_CD_NUMTYPES] = {0,0,0,0}; + int elayers[BME_CD_NUMTYPES] = {0,0,0,0}; + int llayers[BME_CD_NUMTYPES] = {0,0,0,0}; + int players[BME_CD_NUMTYPES] = {0,0,0,0}; + BME_Mesh *bm; BME_TransData_Head *td; TransInfo *t; @@ -4497,8 +4502,7 @@ void bevel_menu() { while(G.editBMesh->options & BME_BEVEL_RUNNING) { options = G.editBMesh->options; res = G.editBMesh->res; - bm = BME_make_mesh(512,512,2048,512); - bm = BME_editmesh_to_bmesh(G.editMesh, bm); + bm = BME_editmesh_to_bmesh(G.editMesh); BIF_undo_push("Pre-Bevel"); free_editMesh(G.editMesh); BME_bevel(bm,0.1f,res,options,0,0,&td); From ca8aa8c901934dc0e3eb1b65618d40bfb65f9111 Mon Sep 17 00:00:00 2001 From: Peter Schlaile Date: Mon, 2 Jun 2008 21:35:57 +0000 Subject: [PATCH 140/246] == RED one (redcode) == This adds redcode (the file format of RED one, R3D) support to blender. Seems to work fine with the footage I found on the web, but keep in mind, that because of the unoptimized nature of libopenjpeg, frame decoding isn't that fast. It is also a rather challenging task, to make 4k-float-footage realtime :) --- config/linux2-config.py | 18 + extern/SConscript | 6 + extern/libopenjpeg/SConscript | 20 + extern/libopenjpeg/bio.c | 187 ++ extern/libopenjpeg/bio.h | 125 ++ extern/libopenjpeg/cio.c | 191 ++ extern/libopenjpeg/cio.h | 86 + extern/libopenjpeg/dwt.c | 825 ++++++++ extern/libopenjpeg/dwt.h | 113 ++ extern/libopenjpeg/event.c | 121 ++ extern/libopenjpeg/event.h | 58 + extern/libopenjpeg/fix.h | 64 + extern/libopenjpeg/image.c | 89 + extern/libopenjpeg/image.h | 48 + extern/libopenjpeg/int.h | 119 ++ extern/libopenjpeg/j2k.c | 2498 ++++++++++++++++++++++++ extern/libopenjpeg/j2k.h | 446 +++++ extern/libopenjpeg/j2k_lib.c | 59 + extern/libopenjpeg/j2k_lib.h | 54 + extern/libopenjpeg/jp2.c | 710 +++++++ extern/libopenjpeg/jp2.h | 177 ++ extern/libopenjpeg/jpt.c | 155 ++ extern/libopenjpeg/jpt.h | 75 + extern/libopenjpeg/license.txt | 30 + extern/libopenjpeg/mct.c | 148 ++ extern/libopenjpeg/mct.h | 98 + extern/libopenjpeg/mqc.c | 538 +++++ extern/libopenjpeg/mqc.h | 197 ++ extern/libopenjpeg/openjpeg.c | 329 ++++ extern/libopenjpeg/openjpeg.h | 911 +++++++++ extern/libopenjpeg/opj_includes.h | 132 ++ extern/libopenjpeg/opj_malloc.h | 145 ++ extern/libopenjpeg/pi.c | 963 +++++++++ extern/libopenjpeg/pi.h | 154 ++ extern/libopenjpeg/raw.c | 87 + extern/libopenjpeg/raw.h | 100 + extern/libopenjpeg/t1.c | 1208 ++++++++++++ extern/libopenjpeg/t1.h | 147 ++ extern/libopenjpeg/t1_generate_luts.c | 275 +++ extern/libopenjpeg/t1_luts.h | 143 ++ extern/libopenjpeg/t2.c | 787 ++++++++ extern/libopenjpeg/t2.h | 103 + extern/libopenjpeg/tcd.c | 1506 ++++++++++++++ extern/libopenjpeg/tcd.h | 285 +++ extern/libopenjpeg/tgt.c | 213 ++ extern/libopenjpeg/tgt.h | 114 ++ extern/libredcode/AUTHOR | 1 + extern/libredcode/LICENSE | 340 ++++ extern/libredcode/NOTES | 23 + extern/libredcode/SConscript | 28 + extern/libredcode/codec.c | 141 ++ extern/libredcode/codec.h | 34 + extern/libredcode/debayer.c | 129 ++ extern/libredcode/debayer.h | 11 + extern/libredcode/format.c | 213 ++ extern/libredcode/format.h | 24 + intern/bsp/SConscript | 2 +- source/blender/imbuf/SConscript | 8 + source/blender/imbuf/intern/IMB_anim.h | 8 + source/blender/imbuf/intern/anim.c | 74 +- source/blender/imbuf/intern/util.c | 18 + tools/btools.py | 12 + 62 files changed, 15921 insertions(+), 2 deletions(-) create mode 100644 extern/libopenjpeg/SConscript create mode 100644 extern/libopenjpeg/bio.c create mode 100644 extern/libopenjpeg/bio.h create mode 100644 extern/libopenjpeg/cio.c create mode 100644 extern/libopenjpeg/cio.h create mode 100644 extern/libopenjpeg/dwt.c create mode 100644 extern/libopenjpeg/dwt.h create mode 100644 extern/libopenjpeg/event.c create mode 100644 extern/libopenjpeg/event.h create mode 100644 extern/libopenjpeg/fix.h create mode 100644 extern/libopenjpeg/image.c create mode 100644 extern/libopenjpeg/image.h create mode 100644 extern/libopenjpeg/int.h create mode 100644 extern/libopenjpeg/j2k.c create mode 100644 extern/libopenjpeg/j2k.h create mode 100644 extern/libopenjpeg/j2k_lib.c create mode 100644 extern/libopenjpeg/j2k_lib.h create mode 100644 extern/libopenjpeg/jp2.c create mode 100644 extern/libopenjpeg/jp2.h create mode 100644 extern/libopenjpeg/jpt.c create mode 100644 extern/libopenjpeg/jpt.h create mode 100644 extern/libopenjpeg/license.txt create mode 100644 extern/libopenjpeg/mct.c create mode 100644 extern/libopenjpeg/mct.h create mode 100644 extern/libopenjpeg/mqc.c create mode 100644 extern/libopenjpeg/mqc.h create mode 100644 extern/libopenjpeg/openjpeg.c create mode 100644 extern/libopenjpeg/openjpeg.h create mode 100644 extern/libopenjpeg/opj_includes.h create mode 100644 extern/libopenjpeg/opj_malloc.h create mode 100644 extern/libopenjpeg/pi.c create mode 100644 extern/libopenjpeg/pi.h create mode 100644 extern/libopenjpeg/raw.c create mode 100644 extern/libopenjpeg/raw.h create mode 100644 extern/libopenjpeg/t1.c create mode 100644 extern/libopenjpeg/t1.h create mode 100644 extern/libopenjpeg/t1_generate_luts.c create mode 100644 extern/libopenjpeg/t1_luts.h create mode 100644 extern/libopenjpeg/t2.c create mode 100644 extern/libopenjpeg/t2.h create mode 100644 extern/libopenjpeg/tcd.c create mode 100644 extern/libopenjpeg/tcd.h create mode 100644 extern/libopenjpeg/tgt.c create mode 100644 extern/libopenjpeg/tgt.h create mode 100644 extern/libredcode/AUTHOR create mode 100644 extern/libredcode/LICENSE create mode 100644 extern/libredcode/NOTES create mode 100644 extern/libredcode/SConscript create mode 100644 extern/libredcode/codec.c create mode 100644 extern/libredcode/codec.h create mode 100644 extern/libredcode/debayer.c create mode 100644 extern/libredcode/debayer.h create mode 100644 extern/libredcode/format.c create mode 100644 extern/libredcode/format.h diff --git a/config/linux2-config.py b/config/linux2-config.py index 4d8b5c97512..6bde0664fe5 100644 --- a/config/linux2-config.py +++ b/config/linux2-config.py @@ -130,6 +130,24 @@ BF_FFMPEG_LIB = '' BF_FFMPEG_INC = '${BF_FFMPEG}/include' BF_FFMPEG_LIBPATH='${BF_FFMPEG}/lib' +WITH_BF_OPENJPEG = 'true' +BF_OPENJPEG = '#extern/libopenjpeg' +BF_OPENJPEG_LIB = '' +# Uncomment the following two lines to use system's ffmpeg +# BF_FFMPEG = '/usr' +# BF_FFMPEG_LIB = 'avformat avcodec swscale avutil' +BF_OPENJPEG_INC = '${BF_OPENJPEG}/include' +BF_OPENJPEG_LIBPATH='${BF_OPENJPEG}/lib' + +WITH_BF_REDCODE = 'true' +BF_REDCODE = '#extern/libredcode' +BF_REDCODE_LIB = '' +# Uncomment the following two lines to use system's ffmpeg +# BF_FFMPEG = '/usr' +# BF_FFMPEG_LIB = 'avformat avcodec swscale avutil' +BF_REDCODE_INC = '${BF_REDCODE}/include' +BF_REDCODE_LIBPATH='${BF_REDCODE}/lib' + # Mesa Libs should go here if your using them as well.... WITH_BF_STATICOPENGL = 'false' BF_OPENGL = '/usr' diff --git a/extern/SConscript b/extern/SConscript index 09eaf080c28..c94b6573eb9 100644 --- a/extern/SConscript +++ b/extern/SConscript @@ -21,5 +21,11 @@ if env['WITH_BF_FFMPEG'] and env['BF_FFMPEG_LIB'] == '': SConscript(['xvidcore/SConscript']) SConscript(['ffmpeg/SConscript']) +if env['WITH_BF_OPENJPEG'] and env['BF_OPENJPEG_LIB'] == '': + SConscript(['libopenjpeg/SConscript']) + +if env['WITH_BF_REDCODE'] and env['BF_REDCODE_LIB'] == '': + SConscript(['libredcode/SConscript']) + if env['OURPLATFORM'] == 'linux2': SConscript(['binreloc/SConscript']); diff --git a/extern/libopenjpeg/SConscript b/extern/libopenjpeg/SConscript new file mode 100644 index 00000000000..f0a93f6e2d9 --- /dev/null +++ b/extern/libopenjpeg/SConscript @@ -0,0 +1,20 @@ +#!/usr/bin/python + +import sys + +Import('env') + +sources = env.Glob('*.c') +incs = '.' + +flags = "-Wall -O3 -ffast-math -std=c99" + +oj_env = env.Copy(); +oj_env.Replace(CCFLAGS = '') +oj_env.Replace(BF_DEBUG_FLAGS = '') + +oj_env.BlenderLib ( libname='extern_openjpeg', + sources=sources, includes=Split(incs), + defines=[], + libtype=['core','intern','player'], + priority=[10, 10, 300], compileflags = Split(flags)) diff --git a/extern/libopenjpeg/bio.c b/extern/libopenjpeg/bio.c new file mode 100644 index 00000000000..4c02f464d8d --- /dev/null +++ b/extern/libopenjpeg/bio.c @@ -0,0 +1,187 @@ +/* + * Copyright (c) 2002-2007, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium + * Copyright (c) 2002-2007, Professor Benoit Macq + * Copyright (c) 2001-2003, David Janssens + * Copyright (c) 2002-2003, Yannick Verschueren + * Copyright (c) 2003-2007, Francois-Olivier Devaux and Antonin Descampe + * Copyright (c) 2005, Herve Drolon, FreeImage Team + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 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. + */ + +#include "opj_includes.h" + +/** @defgroup BIO BIO - Individual bit input-output stream */ +/*@{*/ + +/** @name Local static functions */ +/*@{*/ + +/** +Write a bit +@param bio BIO handle +@param b Bit to write (0 or 1) +*/ +static void bio_putbit(opj_bio_t *bio, int b); +/** +Read a bit +@param bio BIO handle +@return Returns the read bit +*/ +static int bio_getbit(opj_bio_t *bio); +/** +Write a byte +@param bio BIO handle +@return Returns 0 if successful, returns 1 otherwise +*/ +static int bio_byteout(opj_bio_t *bio); +/** +Read a byte +@param bio BIO handle +@return Returns 0 if successful, returns 1 otherwise +*/ +static int bio_bytein(opj_bio_t *bio); + +/*@}*/ + +/*@}*/ + +/* +========================================================== + local functions +========================================================== +*/ + +static int bio_byteout(opj_bio_t *bio) { + bio->buf = (bio->buf << 8) & 0xffff; + bio->ct = bio->buf == 0xff00 ? 7 : 8; + if (bio->bp >= bio->end) { + return 1; + } + *bio->bp++ = bio->buf >> 8; + return 0; +} + +static int bio_bytein(opj_bio_t *bio) { + bio->buf = (bio->buf << 8) & 0xffff; + bio->ct = bio->buf == 0xff00 ? 7 : 8; + if (bio->bp >= bio->end) { + return 1; + } + bio->buf |= *bio->bp++; + return 0; +} + +static void bio_putbit(opj_bio_t *bio, int b) { + if (bio->ct == 0) { + bio_byteout(bio); + } + bio->ct--; + bio->buf |= b << bio->ct; +} + +static int bio_getbit(opj_bio_t *bio) { + if (bio->ct == 0) { + bio_bytein(bio); + } + bio->ct--; + return (bio->buf >> bio->ct) & 1; +} + +/* +========================================================== + Bit Input/Output interface +========================================================== +*/ + +opj_bio_t* bio_create(void) { + opj_bio_t *bio = (opj_bio_t*)opj_malloc(sizeof(opj_bio_t)); + return bio; +} + +void bio_destroy(opj_bio_t *bio) { + if(bio) { + opj_free(bio); + } +} + +int bio_numbytes(opj_bio_t *bio) { + return (bio->bp - bio->start); +} + +void bio_init_enc(opj_bio_t *bio, unsigned char *bp, int len) { + bio->start = bp; + bio->end = bp + len; + bio->bp = bp; + bio->buf = 0; + bio->ct = 8; +} + +void bio_init_dec(opj_bio_t *bio, unsigned char *bp, int len) { + bio->start = bp; + bio->end = bp + len; + bio->bp = bp; + bio->buf = 0; + bio->ct = 0; +} + +void bio_write(opj_bio_t *bio, int v, int n) { + int i; + for (i = n - 1; i >= 0; i--) { + bio_putbit(bio, (v >> i) & 1); + } +} + +int bio_read(opj_bio_t *bio, int n) { + int i, v; + v = 0; + for (i = n - 1; i >= 0; i--) { + v += bio_getbit(bio) << i; + } + return v; +} + +int bio_flush(opj_bio_t *bio) { + bio->ct = 0; + if (bio_byteout(bio)) { + return 1; + } + if (bio->ct == 7) { + bio->ct = 0; + if (bio_byteout(bio)) { + return 1; + } + } + return 0; +} + +int bio_inalign(opj_bio_t *bio) { + bio->ct = 0; + if ((bio->buf & 0xff) == 0xff) { + if (bio_bytein(bio)) { + return 1; + } + bio->ct = 0; + } + return 0; +} diff --git a/extern/libopenjpeg/bio.h b/extern/libopenjpeg/bio.h new file mode 100644 index 00000000000..764d7cb2e92 --- /dev/null +++ b/extern/libopenjpeg/bio.h @@ -0,0 +1,125 @@ +/* + * Copyright (c) 2002-2007, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium + * Copyright (c) 2002-2007, Professor Benoit Macq + * Copyright (c) 2001-2003, David Janssens + * Copyright (c) 2002-2003, Yannick Verschueren + * Copyright (c) 2003-2007, Francois-Olivier Devaux and Antonin Descampe + * Copyright (c) 2005, Herve Drolon, FreeImage Team + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 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. + */ + +#ifndef __BIO_H +#define __BIO_H +/** +@file bio.h +@brief Implementation of an individual bit input-output (BIO) + +The functions in BIO.C have for goal to realize an individual bit input - output. +*/ + +/** @defgroup BIO BIO - Individual bit input-output stream */ +/*@{*/ + +/** +Individual bit input-output stream (BIO) +*/ +typedef struct opj_bio { + /** pointer to the start of the buffer */ + unsigned char *start; + /** pointer to the end of the buffer */ + unsigned char *end; + /** pointer to the present position in the buffer */ + unsigned char *bp; + /** temporary place where each byte is read or written */ + unsigned int buf; + /** coder : number of bits free to write. decoder : number of bits read */ + int ct; +} opj_bio_t; + +/** @name Exported functions */ +/*@{*/ +/* ----------------------------------------------------------------------- */ +/** +Create a new BIO handle +@return Returns a new BIO handle if successful, returns NULL otherwise +*/ +opj_bio_t* bio_create(void); +/** +Destroy a previously created BIO handle +@param bio BIO handle to destroy +*/ +void bio_destroy(opj_bio_t *bio); +/** +Number of bytes written. +@param bio BIO handle +@return Returns the number of bytes written +*/ +int bio_numbytes(opj_bio_t *bio); +/** +Init encoder +@param bio BIO handle +@param bp Output buffer +@param len Output buffer length +*/ +void bio_init_enc(opj_bio_t *bio, unsigned char *bp, int len); +/** +Init decoder +@param bio BIO handle +@param bp Input buffer +@param len Input buffer length +*/ +void bio_init_dec(opj_bio_t *bio, unsigned char *bp, int len); +/** +Write bits +@param bio BIO handle +@param v Value of bits +@param n Number of bits to write +*/ +void bio_write(opj_bio_t *bio, int v, int n); +/** +Read bits +@param bio BIO handle +@param n Number of bits to read +@return Returns the corresponding read number +*/ +int bio_read(opj_bio_t *bio, int n); +/** +Flush bits +@param bio BIO handle +@return Returns 1 if successful, returns 0 otherwise +*/ +int bio_flush(opj_bio_t *bio); +/** +Passes the ending bits (coming from flushing) +@param bio BIO handle +@return Returns 1 if successful, returns 0 otherwise +*/ +int bio_inalign(opj_bio_t *bio); +/* ----------------------------------------------------------------------- */ +/*@}*/ + +/*@}*/ + +#endif /* __BIO_H */ + diff --git a/extern/libopenjpeg/cio.c b/extern/libopenjpeg/cio.c new file mode 100644 index 00000000000..2ac262a1f6b --- /dev/null +++ b/extern/libopenjpeg/cio.c @@ -0,0 +1,191 @@ +/* + * Copyright (c) 2002-2007, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium + * Copyright (c) 2002-2007, Professor Benoit Macq + * Copyright (c) 2001-2003, David Janssens + * Copyright (c) 2002-2003, Yannick Verschueren + * Copyright (c) 2003-2007, Francois-Olivier Devaux and Antonin Descampe + * Copyright (c) 2005, Herve Drolon, FreeImage Team + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 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. + */ + +#include "opj_includes.h" + +/* ----------------------------------------------------------------------- */ + +opj_cio_t* OPJ_CALLCONV opj_cio_open(opj_common_ptr cinfo, unsigned char *buffer, int length) { + opj_cp_t *cp = NULL; + opj_cio_t *cio = (opj_cio_t*)opj_malloc(sizeof(opj_cio_t)); + if(!cio) return NULL; + cio->cinfo = cinfo; + if(buffer && length) { + /* wrap a user buffer containing the encoded image */ + cio->openmode = OPJ_STREAM_READ; + cio->buffer = buffer; + cio->length = length; + } + else if(!buffer && !length && cinfo) { + /* allocate a buffer for the encoded image */ + cio->openmode = OPJ_STREAM_WRITE; + switch(cinfo->codec_format) { + case CODEC_J2K: + cp = ((opj_j2k_t*)cinfo->j2k_handle)->cp; + break; + case CODEC_JP2: + cp = ((opj_jp2_t*)cinfo->jp2_handle)->j2k->cp; + break; + default: + opj_free(cio); + return NULL; + } + cio->length = (unsigned int) (0.1625 * cp->img_size + 2000); /* 0.1625 = 1.3/8 and 2000 bytes as a minimum for headers */ + cio->buffer = (unsigned char *)opj_malloc(cio->length); + if(!cio->buffer) { + opj_event_msg(cio->cinfo, EVT_ERROR, "Error allocating memory for compressed bitstream\n"); + opj_free(cio); + return NULL; + } + } + else { + opj_free(cio); + return NULL; + } + + /* Initialize byte IO */ + cio->start = cio->buffer; + cio->end = cio->buffer + cio->length; + cio->bp = cio->buffer; + + return cio; +} + +void OPJ_CALLCONV opj_cio_close(opj_cio_t *cio) { + if(cio) { + if(cio->openmode == OPJ_STREAM_WRITE) { + /* destroy the allocated buffer */ + opj_free(cio->buffer); + } + /* destroy the cio */ + opj_free(cio); + } +} + + +/* ----------------------------------------------------------------------- */ + +/* + * Get position in byte stream. + */ +int OPJ_CALLCONV cio_tell(opj_cio_t *cio) { + return cio->bp - cio->start; +} + +/* + * Set position in byte stream. + * + * pos : position, in number of bytes, from the beginning of the stream + */ +void OPJ_CALLCONV cio_seek(opj_cio_t *cio, int pos) { + cio->bp = cio->start + pos; +} + +/* + * Number of bytes left before the end of the stream. + */ +int cio_numbytesleft(opj_cio_t *cio) { + return cio->end - cio->bp; +} + +/* + * Get pointer to the current position in the stream. + */ +unsigned char *cio_getbp(opj_cio_t *cio) { + return cio->bp; +} + +/* + * Write a byte. + */ +bool cio_byteout(opj_cio_t *cio, unsigned char v) { + if (cio->bp >= cio->end) { + opj_event_msg(cio->cinfo, EVT_ERROR, "write error\n"); + return false; + } + *cio->bp++ = v; + return true; +} + +/* + * Read a byte. + */ +unsigned char cio_bytein(opj_cio_t *cio) { + if (cio->bp >= cio->end) { + opj_event_msg(cio->cinfo, EVT_ERROR, "read error: passed the end of the codestream (start = %d, current = %d, end = %d\n", cio->start, cio->bp, cio->end); + return 0; + } + return *cio->bp++; +} + +/* + * Write some bytes. + * + * v : value to write + * n : number of bytes to write + */ +unsigned int cio_write(opj_cio_t *cio, unsigned int v, int n) { + int i; + for (i = n - 1; i >= 0; i--) { + if( !cio_byteout(cio, (unsigned char) ((v >> (i << 3)) & 0xff)) ) + return 0; + } + return n; +} + +/* + * Read some bytes. + * + * n : number of bytes to read + * + * return : value of the n bytes read + */ +unsigned int cio_read(opj_cio_t *cio, int n) { + int i; + unsigned int v; + v = 0; + for (i = n - 1; i >= 0; i--) { + v += cio_bytein(cio) << (i << 3); + } + return v; +} + +/* + * Skip some bytes. + * + * n : number of bytes to skip + */ +void cio_skip(opj_cio_t *cio, int n) { + cio->bp += n; +} + + + diff --git a/extern/libopenjpeg/cio.h b/extern/libopenjpeg/cio.h new file mode 100644 index 00000000000..580bf9c0d12 --- /dev/null +++ b/extern/libopenjpeg/cio.h @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2002-2007, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium + * Copyright (c) 2002-2007, Professor Benoit Macq + * Copyright (c) 2001-2003, David Janssens + * Copyright (c) 2002-2003, Yannick Verschueren + * Copyright (c) 2003-2007, Francois-Olivier Devaux and Antonin Descampe + * Copyright (c) 2005, Herve Drolon, FreeImage Team + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 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. + */ + +#ifndef __CIO_H +#define __CIO_H +/** +@file cio.h +@brief Implementation of a byte input-output process (CIO) + +The functions in CIO.C have for goal to realize a byte input / output process. +*/ + +/** @defgroup CIO CIO - byte input-output stream */ +/*@{*/ + +/** @name Exported functions (see also openjpeg.h) */ +/*@{*/ +/* ----------------------------------------------------------------------- */ +/** +Number of bytes left before the end of the stream +@param cio CIO handle +@return Returns the number of bytes before the end of the stream +*/ +int cio_numbytesleft(opj_cio_t *cio); +/** +Get pointer to the current position in the stream +@param cio CIO handle +@return Returns a pointer to the current position +*/ +unsigned char *cio_getbp(opj_cio_t *cio); +/** +Write some bytes +@param cio CIO handle +@param v Value to write +@param n Number of bytes to write +@return Returns the number of bytes written or 0 if an error occured +*/ +unsigned int cio_write(opj_cio_t *cio, unsigned int v, int n); +/** +Read some bytes +@param cio CIO handle +@param n Number of bytes to read +@return Returns the value of the n bytes read +*/ +unsigned int cio_read(opj_cio_t *cio, int n); +/** +Skip some bytes +@param cio CIO handle +@param n Number of bytes to skip +*/ +void cio_skip(opj_cio_t *cio, int n); +/* ----------------------------------------------------------------------- */ +/*@}*/ + +/*@}*/ + +#endif /* __CIO_H */ + diff --git a/extern/libopenjpeg/dwt.c b/extern/libopenjpeg/dwt.c new file mode 100644 index 00000000000..78d18d175f4 --- /dev/null +++ b/extern/libopenjpeg/dwt.c @@ -0,0 +1,825 @@ +/* + * Copyright (c) 2002-2007, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium + * Copyright (c) 2002-2007, Professor Benoit Macq + * Copyright (c) 2001-2003, David Janssens + * Copyright (c) 2002-2003, Yannick Verschueren + * Copyright (c) 2003-2007, Francois-Olivier Devaux and Antonin Descampe + * Copyright (c) 2005, Herve Drolon, FreeImage Team + * Copyright (c) 2007, Jonathan Ballard + * Copyright (c) 2007, Callum Lerwick + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 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. + */ + +#ifdef __SSE__ +#include +#endif + +#include "opj_includes.h" + +/** @defgroup DWT DWT - Implementation of a discrete wavelet transform */ +/*@{*/ + +#define WS(i) v->mem[(i)*2] +#define WD(i) v->mem[(1+(i)*2)] + +/** @name Local data structures */ +/*@{*/ + +typedef struct dwt_local { + int* mem; + int dn; + int sn; + int cas; +} dwt_t; + +typedef union { + float f[4]; +} v4; + +typedef struct v4dwt_local { + v4* wavelet ; + int dn ; + int sn ; + int cas ; +} v4dwt_t ; + +static const float dwt_alpha = 1.586134342f; // 12994 +static const float dwt_beta = 0.052980118f; // 434 +static const float dwt_gamma = -0.882911075f; // -7233 +static const float dwt_delta = -0.443506852f; // -3633 + +static const float K = 1.230174105f; // 10078 +/* FIXME: What is this constant? */ +static const float c13318 = 1.625732422f; + +/*@}*/ + +/** +Virtual function type for wavelet transform in 1-D +*/ +typedef void (*DWT1DFN)(dwt_t* v); + +/** @name Local static functions */ +/*@{*/ + +/** +Forward lazy transform (horizontal) +*/ +static void dwt_deinterleave_h(int *a, int *b, int dn, int sn, int cas); +/** +Forward lazy transform (vertical) +*/ +static void dwt_deinterleave_v(int *a, int *b, int dn, int sn, int x, int cas); +/** +Inverse lazy transform (horizontal) +*/ +static void dwt_interleave_h(dwt_t* h, int *a); +/** +Inverse lazy transform (vertical) +*/ +static void dwt_interleave_v(dwt_t* v, int *a, int x); +/** +Forward 5-3 wavelet transform in 1-D +*/ +static void dwt_encode_1(int *a, int dn, int sn, int cas); +/** +Inverse 5-3 wavelet transform in 1-D +*/ +static void dwt_decode_1(dwt_t *v); +/** +Forward 9-7 wavelet transform in 1-D +*/ +static void dwt_encode_1_real(int *a, int dn, int sn, int cas); +/** +Explicit calculation of the Quantization Stepsizes +*/ +static void dwt_encode_stepsize(int stepsize, int numbps, opj_stepsize_t *bandno_stepsize); +/** +Inverse wavelet transform in 2-D. +*/ +static void dwt_decode_tile(opj_tcd_tilecomp_t* tilec, int i, DWT1DFN fn); + +/*@}*/ + +/*@}*/ + +#define S(i) a[(i)*2] +#define D(i) a[(1+(i)*2)] +#define S_(i) ((i)<0?S(0):((i)>=sn?S(sn-1):S(i))) +#define D_(i) ((i)<0?D(0):((i)>=dn?D(dn-1):D(i))) +/* new */ +#define SS_(i) ((i)<0?S(0):((i)>=dn?S(dn-1):S(i))) +#define DD_(i) ((i)<0?D(0):((i)>=sn?D(sn-1):D(i))) + +/* */ +/* This table contains the norms of the 5-3 wavelets for different bands. */ +/* */ +static const double dwt_norms[4][10] = { + {1.000, 1.500, 2.750, 5.375, 10.68, 21.34, 42.67, 85.33, 170.7, 341.3}, + {1.038, 1.592, 2.919, 5.703, 11.33, 22.64, 45.25, 90.48, 180.9}, + {1.038, 1.592, 2.919, 5.703, 11.33, 22.64, 45.25, 90.48, 180.9}, + {.7186, .9218, 1.586, 3.043, 6.019, 12.01, 24.00, 47.97, 95.93} +}; + +/* */ +/* This table contains the norms of the 9-7 wavelets for different bands. */ +/* */ +static const double dwt_norms_real[4][10] = { + {1.000, 1.965, 4.177, 8.403, 16.90, 33.84, 67.69, 135.3, 270.6, 540.9}, + {2.022, 3.989, 8.355, 17.04, 34.27, 68.63, 137.3, 274.6, 549.0}, + {2.022, 3.989, 8.355, 17.04, 34.27, 68.63, 137.3, 274.6, 549.0}, + {2.080, 3.865, 8.307, 17.18, 34.71, 69.59, 139.3, 278.6, 557.2} +}; + +/* +========================================================== + local functions +========================================================== +*/ + +/* */ +/* Forward lazy transform (horizontal). */ +/* */ +static void dwt_deinterleave_h(int *a, int *b, int dn, int sn, int cas) { + int i; + for (i=0; i */ +/* Forward lazy transform (vertical). */ +/* */ +static void dwt_deinterleave_v(int *a, int *b, int dn, int sn, int x, int cas) { + int i; + for (i=0; i */ +/* Inverse lazy transform (horizontal). */ +/* */ +static void dwt_interleave_h(dwt_t* h, int *a) { + int *ai = a; + int *bi = h->mem + h->cas; + int i = h->sn; + while( i-- ) { + *bi = *(ai++); + bi += 2; + } + ai = a + h->sn; + bi = h->mem + 1 - h->cas; + i = h->dn ; + while( i-- ) { + *bi = *(ai++); + bi += 2; + } +} + +/* */ +/* Inverse lazy transform (vertical). */ +/* */ +static void dwt_interleave_v(dwt_t* v, int *a, int x) { + int *ai = a; + int *bi = v->mem + v->cas; + int i = v->sn; + while( i-- ) { + *bi = *ai; + bi += 2; + ai += x; + } + ai = a + (v->sn * x); + bi = v->mem + 1 - v->cas; + i = v->dn ; + while( i-- ) { + *bi = *ai; + bi += 2; + ai += x; + } +} + + +/* */ +/* Forward 5-3 wavelet transform in 1-D. */ +/* */ +static void dwt_encode_1(int *a, int dn, int sn, int cas) { + int i; + + if (!cas) { + if ((dn > 0) || (sn > 1)) { /* NEW : CASE ONE ELEMENT */ + for (i = 0; i < dn; i++) D(i) -= (S_(i) + S_(i + 1)) >> 1; + for (i = 0; i < sn; i++) S(i) += (D_(i - 1) + D_(i) + 2) >> 2; + } + } else { + if (!sn && dn == 1) /* NEW : CASE ONE ELEMENT */ + S(0) *= 2; + else { + for (i = 0; i < dn; i++) S(i) -= (DD_(i) + DD_(i - 1)) >> 1; + for (i = 0; i < sn; i++) D(i) += (SS_(i) + SS_(i + 1) + 2) >> 2; + } + } +} + +/* */ +/* Inverse 5-3 wavelet transform in 1-D. */ +/* */ +static void dwt_decode_1_(int *a, int dn, int sn, int cas) { + int i; + + if (!cas) { + if ((dn > 0) || (sn > 1)) { /* NEW : CASE ONE ELEMENT */ + for (i = 0; i < sn; i++) S(i) -= (D_(i - 1) + D_(i) + 2) >> 2; + for (i = 0; i < dn; i++) D(i) += (S_(i) + S_(i + 1)) >> 1; + } + } else { + if (!sn && dn == 1) /* NEW : CASE ONE ELEMENT */ + S(0) /= 2; + else { + for (i = 0; i < sn; i++) D(i) -= (SS_(i) + SS_(i + 1) + 2) >> 2; + for (i = 0; i < dn; i++) S(i) += (DD_(i) + DD_(i - 1)) >> 1; + } + } +} + +/* */ +/* Inverse 5-3 wavelet transform in 1-D. */ +/* */ +static void dwt_decode_1(dwt_t *v) { + dwt_decode_1_(v->mem, v->dn, v->sn, v->cas); +} + +/* */ +/* Forward 9-7 wavelet transform in 1-D. */ +/* */ +static void dwt_encode_1_real(int *a, int dn, int sn, int cas) { + int i; + if (!cas) { + if ((dn > 0) || (sn > 1)) { /* NEW : CASE ONE ELEMENT */ + for (i = 0; i < dn; i++) + D(i) -= fix_mul(S_(i) + S_(i + 1), 12993); + for (i = 0; i < sn; i++) + S(i) -= fix_mul(D_(i - 1) + D_(i), 434); + for (i = 0; i < dn; i++) + D(i) += fix_mul(S_(i) + S_(i + 1), 7233); + for (i = 0; i < sn; i++) + S(i) += fix_mul(D_(i - 1) + D_(i), 3633); + for (i = 0; i < dn; i++) + D(i) = fix_mul(D(i), 5038); /*5038 */ + for (i = 0; i < sn; i++) + S(i) = fix_mul(S(i), 6659); /*6660 */ + } + } else { + if ((sn > 0) || (dn > 1)) { /* NEW : CASE ONE ELEMENT */ + for (i = 0; i < dn; i++) + S(i) -= fix_mul(DD_(i) + DD_(i - 1), 12993); + for (i = 0; i < sn; i++) + D(i) -= fix_mul(SS_(i) + SS_(i + 1), 434); + for (i = 0; i < dn; i++) + S(i) += fix_mul(DD_(i) + DD_(i - 1), 7233); + for (i = 0; i < sn; i++) + D(i) += fix_mul(SS_(i) + SS_(i + 1), 3633); + for (i = 0; i < dn; i++) + S(i) = fix_mul(S(i), 5038); /*5038 */ + for (i = 0; i < sn; i++) + D(i) = fix_mul(D(i), 6659); /*6660 */ + } + } +} + +static void dwt_encode_stepsize(int stepsize, int numbps, opj_stepsize_t *bandno_stepsize) { + int p, n; + p = int_floorlog2(stepsize) - 13; + n = 11 - int_floorlog2(stepsize); + bandno_stepsize->mant = (n < 0 ? stepsize >> -n : stepsize << n) & 0x7ff; + bandno_stepsize->expn = numbps - p; +} + +/* +========================================================== + DWT interface +========================================================== +*/ + +/* */ +/* Forward 5-3 wavelet transform in 2-D. */ +/* */ +void dwt_encode(opj_tcd_tilecomp_t * tilec) { + int i, j, k; + int *a = NULL; + int *aj = NULL; + int *bj = NULL; + int w, l; + + w = tilec->x1-tilec->x0; + l = tilec->numresolutions-1; + a = tilec->data; + + for (i = 0; i < l; i++) { + int rw; /* width of the resolution level computed */ + int rh; /* height of the resolution level computed */ + int rw1; /* width of the resolution level once lower than computed one */ + int rh1; /* height of the resolution level once lower than computed one */ + int cas_col; /* 0 = non inversion on horizontal filtering 1 = inversion between low-pass and high-pass filtering */ + int cas_row; /* 0 = non inversion on vertical filtering 1 = inversion between low-pass and high-pass filtering */ + int dn, sn; + + rw = tilec->resolutions[l - i].x1 - tilec->resolutions[l - i].x0; + rh = tilec->resolutions[l - i].y1 - tilec->resolutions[l - i].y0; + rw1= tilec->resolutions[l - i - 1].x1 - tilec->resolutions[l - i - 1].x0; + rh1= tilec->resolutions[l - i - 1].y1 - tilec->resolutions[l - i - 1].y0; + + cas_row = tilec->resolutions[l - i].x0 % 2; + cas_col = tilec->resolutions[l - i].y0 % 2; + + sn = rh1; + dn = rh - rh1; + bj = (int*)opj_malloc(rh * sizeof(int)); + for (j = 0; j < rw; j++) { + aj = a + j; + for (k = 0; k < rh; k++) bj[k] = aj[k*w]; + dwt_encode_1(bj, dn, sn, cas_col); + dwt_deinterleave_v(bj, aj, dn, sn, w, cas_col); + } + opj_free(bj); + + sn = rw1; + dn = rw - rw1; + bj = (int*)opj_malloc(rw * sizeof(int)); + for (j = 0; j < rh; j++) { + aj = a + j * w; + for (k = 0; k < rw; k++) bj[k] = aj[k]; + dwt_encode_1(bj, dn, sn, cas_row); + dwt_deinterleave_h(bj, aj, dn, sn, cas_row); + } + opj_free(bj); + } +} + + +/* */ +/* Inverse 5-3 wavelet transform in 2-D. */ +/* */ +void dwt_decode(opj_tcd_tilecomp_t* tilec, int numres) { + dwt_decode_tile(tilec, numres, &dwt_decode_1); +} + + +/* */ +/* Get gain of 5-3 wavelet transform. */ +/* */ +int dwt_getgain(int orient) { + if (orient == 0) + return 0; + if (orient == 1 || orient == 2) + return 1; + return 2; +} + +/* */ +/* Get norm of 5-3 wavelet. */ +/* */ +double dwt_getnorm(int level, int orient) { + return dwt_norms[orient][level]; +} + +/* */ +/* Forward 9-7 wavelet transform in 2-D. */ +/* */ + +void dwt_encode_real(opj_tcd_tilecomp_t * tilec) { + int i, j, k; + int *a = NULL; + int *aj = NULL; + int *bj = NULL; + int w, l; + + w = tilec->x1-tilec->x0; + l = tilec->numresolutions-1; + a = tilec->data; + + for (i = 0; i < l; i++) { + int rw; /* width of the resolution level computed */ + int rh; /* height of the resolution level computed */ + int rw1; /* width of the resolution level once lower than computed one */ + int rh1; /* height of the resolution level once lower than computed one */ + int cas_col; /* 0 = non inversion on horizontal filtering 1 = inversion between low-pass and high-pass filtering */ + int cas_row; /* 0 = non inversion on vertical filtering 1 = inversion between low-pass and high-pass filtering */ + int dn, sn; + + rw = tilec->resolutions[l - i].x1 - tilec->resolutions[l - i].x0; + rh = tilec->resolutions[l - i].y1 - tilec->resolutions[l - i].y0; + rw1= tilec->resolutions[l - i - 1].x1 - tilec->resolutions[l - i - 1].x0; + rh1= tilec->resolutions[l - i - 1].y1 - tilec->resolutions[l - i - 1].y0; + + cas_row = tilec->resolutions[l - i].x0 % 2; + cas_col = tilec->resolutions[l - i].y0 % 2; + + sn = rh1; + dn = rh - rh1; + bj = (int*)opj_malloc(rh * sizeof(int)); + for (j = 0; j < rw; j++) { + aj = a + j; + for (k = 0; k < rh; k++) bj[k] = aj[k*w]; + dwt_encode_1_real(bj, dn, sn, cas_col); + dwt_deinterleave_v(bj, aj, dn, sn, w, cas_col); + } + opj_free(bj); + + sn = rw1; + dn = rw - rw1; + bj = (int*)opj_malloc(rw * sizeof(int)); + for (j = 0; j < rh; j++) { + aj = a + j * w; + for (k = 0; k < rw; k++) bj[k] = aj[k]; + dwt_encode_1_real(bj, dn, sn, cas_row); + dwt_deinterleave_h(bj, aj, dn, sn, cas_row); + } + opj_free(bj); + } +} + + +/* */ +/* Get gain of 9-7 wavelet transform. */ +/* */ +int dwt_getgain_real(int orient) { + (void)orient; + return 0; +} + +/* */ +/* Get norm of 9-7 wavelet. */ +/* */ +double dwt_getnorm_real(int level, int orient) { + return dwt_norms_real[orient][level]; +} + +void dwt_calc_explicit_stepsizes(opj_tccp_t * tccp, int prec) { + int numbands, bandno; + numbands = 3 * tccp->numresolutions - 2; + for (bandno = 0; bandno < numbands; bandno++) { + double stepsize; + int resno, level, orient, gain; + + resno = (bandno == 0) ? 0 : ((bandno - 1) / 3 + 1); + orient = (bandno == 0) ? 0 : ((bandno - 1) % 3 + 1); + level = tccp->numresolutions - 1 - resno; + gain = (tccp->qmfbid == 0) ? 0 : ((orient == 0) ? 0 : (((orient == 1) || (orient == 2)) ? 1 : 2)); + if (tccp->qntsty == J2K_CCP_QNTSTY_NOQNT) { + stepsize = 1.0; + } else { + double norm = dwt_norms_real[orient][level]; + stepsize = (1 << (gain)) / norm; + } + dwt_encode_stepsize((int) floor(stepsize * 8192.0), prec + gain, &tccp->stepsizes[bandno]); + } +} + + +/* */ +/* Determine maximum computed resolution level for inverse wavelet transform */ +/* */ +static int dwt_decode_max_resolution(opj_tcd_resolution_t* restrict r, int i) { + int mr = 1; + int w; + while( --i ) { + r++; + if( mr < ( w = r->x1 - r->x0 ) ) + mr = w ; + if( mr < ( w = r->y1 - r->y0 ) ) + mr = w ; + } + return mr ; +} + + +/* */ +/* Inverse wavelet transform in 2-D. */ +/* */ +static void dwt_decode_tile(opj_tcd_tilecomp_t* tilec, int numres, DWT1DFN dwt_1D) { + dwt_t h; + dwt_t v; + + opj_tcd_resolution_t* tr = tilec->resolutions; + + int rw = tr->x1 - tr->x0; /* width of the resolution level computed */ + int rh = tr->y1 - tr->y0; /* height of the resolution level computed */ + + int w = tilec->x1 - tilec->x0; + + h.mem = opj_aligned_malloc(dwt_decode_max_resolution(tr, numres) * sizeof(int)); + v.mem = h.mem; + + while( --numres) { + int * restrict tiledp = tilec->data; + int j; + + ++tr; + h.sn = rw; + v.sn = rh; + + rw = tr->x1 - tr->x0; + rh = tr->y1 - tr->y0; + + h.dn = rw - h.sn; + h.cas = tr->x0 % 2; + + for(j = 0; j < rh; ++j) { + dwt_interleave_h(&h, &tiledp[j*w]); + (dwt_1D)(&h); + memcpy(&tiledp[j*w], h.mem, rw * sizeof(int)); + } + + v.dn = rh - v.sn; + v.cas = tr->y0 % 2; + + for(j = 0; j < rw; ++j){ + int k; + dwt_interleave_v(&v, &tiledp[j], w); + (dwt_1D)(&v); + for(k = 0; k < rh; ++k) { + tiledp[k * w + j] = v.mem[k]; + } + } + } + opj_aligned_free(h.mem); +} + +static void v4dwt_interleave_h(v4dwt_t* restrict w, float* restrict a, int x, int size){ + float* restrict bi = (float*) (w->wavelet + w->cas); + int count = w->sn; + int i, k; + for(k = 0; k < 2; ++k){ + for(i = 0; i < count; ++i){ + int j = i; + bi[i*8 ] = a[j]; + j += x; + if(j > size) continue; + bi[i*8 + 1] = a[j]; + j += x; + if(j > size) continue; + bi[i*8 + 2] = a[j]; + j += x; + if(j > size) continue; + bi[i*8 + 3] = a[j]; + } + bi = (float*) (w->wavelet + 1 - w->cas); + a += w->sn; + size -= w->sn; + count = w->dn; + } +} + +static void v4dwt_interleave_v(v4dwt_t* restrict v , float* restrict a , int x){ + v4* restrict bi = v->wavelet + v->cas; + int i; + for(i = 0; i < v->sn; ++i){ + memcpy(&bi[i*2], &a[i*x], 4 * sizeof(float)); + } + a += v->sn * x; + bi = v->wavelet + 1 - v->cas; + for(i = 0; i < v->dn; ++i){ + memcpy(&bi[i*2], &a[i*x], 4 * sizeof(float)); + } +} + +#ifdef __SSE__ + +static void v4dwt_decode_step1_sse(v4* w, int count, const __m128 c){ + __m128* restrict vw = (__m128*) w; + int i; + for(i = 0; i < count; ++i){ + __m128 tmp = vw[i*2]; + vw[i*2] = tmp * c; + } +} + +static void v4dwt_decode_step2_sse(v4* l, v4* w, int k, int m, __m128 c){ + __m128* restrict vl = (__m128*) l; + __m128* restrict vw = (__m128*) w; + int i; + for(i = 0; i < m; ++i){ + __m128 tmp1 = vl[ 0]; + __m128 tmp2 = vw[-1]; + __m128 tmp3 = vw[ 0]; + vw[-1] = tmp2 + ((tmp1 + tmp3) * c); + vl = vw; + vw += 2; + } + if(m >= k){ + return; + } + c += c; + c *= vl[0]; + for(; m < k; ++m){ + __m128 tmp = vw[-1]; + vw[-1] = tmp + c; + vw += 2; + } +} + +#else + +static void v4dwt_decode_step1(v4* w, int count, const float c){ + float* restrict fw = (float*) w; + int i; + for(i = 0; i < count; ++i){ + float tmp1 = fw[i*8 ]; + float tmp2 = fw[i*8 + 1]; + float tmp3 = fw[i*8 + 2]; + float tmp4 = fw[i*8 + 3]; + fw[i*8 ] = tmp1 * c; + fw[i*8 + 1] = tmp2 * c; + fw[i*8 + 2] = tmp3 * c; + fw[i*8 + 3] = tmp4 * c; + } +} + +static void v4dwt_decode_step2(v4* l, v4* w, int k, int m, float c){ + float* restrict fl = (float*) l; + float* restrict fw = (float*) w; + int i; + for(i = 0; i < m; ++i){ + float tmp1_1 = fl[0]; + float tmp1_2 = fl[1]; + float tmp1_3 = fl[2]; + float tmp1_4 = fl[3]; + float tmp2_1 = fw[-4]; + float tmp2_2 = fw[-3]; + float tmp2_3 = fw[-2]; + float tmp2_4 = fw[-1]; + float tmp3_1 = fw[0]; + float tmp3_2 = fw[1]; + float tmp3_3 = fw[2]; + float tmp3_4 = fw[3]; + fw[-4] = tmp2_1 + ((tmp1_1 + tmp3_1) * c); + fw[-3] = tmp2_2 + ((tmp1_2 + tmp3_2) * c); + fw[-2] = tmp2_3 + ((tmp1_3 + tmp3_3) * c); + fw[-1] = tmp2_4 + ((tmp1_4 + tmp3_4) * c); + fl = fw; + fw += 8; + } + if(m < k){ + float c1; + float c2; + float c3; + float c4; + c += c; + c1 = fl[0] * c; + c2 = fl[1] * c; + c3 = fl[2] * c; + c4 = fl[3] * c; + for(; m < k; ++m){ + float tmp1 = fw[-4]; + float tmp2 = fw[-3]; + float tmp3 = fw[-2]; + float tmp4 = fw[-1]; + fw[-4] = tmp1 + c1; + fw[-3] = tmp2 + c2; + fw[-2] = tmp3 + c3; + fw[-1] = tmp4 + c4; + fw += 8; + } + } +} + +#endif + +/* */ +/* Inverse 9-7 wavelet transform in 1-D. */ +/* */ +static void v4dwt_decode(v4dwt_t* restrict dwt){ + int a, b; + if(dwt->cas == 0) { + if(!((dwt->dn > 0) || (dwt->sn > 1))){ + return; + } + a = 0; + b = 1; + }else{ + if(!((dwt->sn > 0) || (dwt->dn > 1))) { + return; + } + a = 1; + b = 0; + } +#ifdef __SSE__ + v4dwt_decode_step1_sse(dwt->wavelet+a, dwt->sn, _mm_set1_ps(K)); + v4dwt_decode_step1_sse(dwt->wavelet+b, dwt->dn, _mm_set1_ps(c13318)); + v4dwt_decode_step2_sse(dwt->wavelet+b, dwt->wavelet+a+1, dwt->sn, int_min(dwt->sn, dwt->dn-a), _mm_set1_ps(dwt_delta)); + v4dwt_decode_step2_sse(dwt->wavelet+a, dwt->wavelet+b+1, dwt->dn, int_min(dwt->dn, dwt->sn-b), _mm_set1_ps(dwt_gamma)); + v4dwt_decode_step2_sse(dwt->wavelet+b, dwt->wavelet+a+1, dwt->sn, int_min(dwt->sn, dwt->dn-a), _mm_set1_ps(dwt_beta)); + v4dwt_decode_step2_sse(dwt->wavelet+a, dwt->wavelet+b+1, dwt->dn, int_min(dwt->dn, dwt->sn-b), _mm_set1_ps(dwt_alpha)); +#else + v4dwt_decode_step1(dwt->wavelet+a, dwt->sn, K); + v4dwt_decode_step1(dwt->wavelet+b, dwt->dn, c13318); + v4dwt_decode_step2(dwt->wavelet+b, dwt->wavelet+a+1, dwt->sn, int_min(dwt->sn, dwt->dn-a), dwt_delta); + v4dwt_decode_step2(dwt->wavelet+a, dwt->wavelet+b+1, dwt->dn, int_min(dwt->dn, dwt->sn-b), dwt_gamma); + v4dwt_decode_step2(dwt->wavelet+b, dwt->wavelet+a+1, dwt->sn, int_min(dwt->sn, dwt->dn-a), dwt_beta); + v4dwt_decode_step2(dwt->wavelet+a, dwt->wavelet+b+1, dwt->dn, int_min(dwt->dn, dwt->sn-b), dwt_alpha); +#endif +} + +/* */ +/* Inverse 9-7 wavelet transform in 2-D. */ +/* */ +void dwt_decode_real(opj_tcd_tilecomp_t* restrict tilec, int numres){ + v4dwt_t h; + v4dwt_t v; + + opj_tcd_resolution_t* res = tilec->resolutions; + + int rw = res->x1 - res->x0; /* width of the resolution level computed */ + int rh = res->y1 - res->y0; /* height of the resolution level computed */ + + int w = tilec->x1 - tilec->x0; + + h.wavelet = (v4*) opj_aligned_malloc((dwt_decode_max_resolution(res, numres)+5) * sizeof(v4)); + v.wavelet = h.wavelet; + + while( --numres) { + float * restrict aj = (float*) tilec->data; + int bufsize = (tilec->x1 - tilec->x0) * (tilec->y1 - tilec->y0); + int j; + + h.sn = rw; + v.sn = rh; + + ++res; + + rw = res->x1 - res->x0; /* width of the resolution level computed */ + rh = res->y1 - res->y0; /* height of the resolution level computed */ + + h.dn = rw - h.sn; + h.cas = res->x0 % 2; + + for(j = rh; j > 0; j -= 4){ + v4dwt_interleave_h(&h, aj, w, bufsize); + v4dwt_decode(&h); + if(j >= 4){ + int k; + for(k = rw; --k >= 0;){ + aj[k ] = h.wavelet[k].f[0]; + aj[k+w ] = h.wavelet[k].f[1]; + aj[k+w*2] = h.wavelet[k].f[2]; + aj[k+w*3] = h.wavelet[k].f[3]; + } + }else{ + int k; + for(k = rw; --k >= 0;){ + switch(j) { + case 3: aj[k+w*2] = h.wavelet[k].f[2]; + case 2: aj[k+w ] = h.wavelet[k].f[1]; + case 1: aj[k ] = h.wavelet[k].f[0]; + } + } + } + aj += w*4; + bufsize -= w*4; + } + + v.dn = rh - v.sn; + v.cas = res->y0 % 2; + + aj = (float*) tilec->data; + for(j = rw; j > 0; j -= 4){ + v4dwt_interleave_v(&v, aj, w); + v4dwt_decode(&v); + if(j >= 4){ + int k; + for(k = 0; k < rh; ++k){ + memcpy(&aj[k*w], &v.wavelet[k], 4 * sizeof(float)); + } + }else{ + int k; + for(k = 0; k < rh; ++k){ + memcpy(&aj[k*w], &v.wavelet[k], j * sizeof(float)); + } + } + aj += 4; + } + } + + opj_aligned_free(h.wavelet); +} + diff --git a/extern/libopenjpeg/dwt.h b/extern/libopenjpeg/dwt.h new file mode 100644 index 00000000000..adf73e54400 --- /dev/null +++ b/extern/libopenjpeg/dwt.h @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2002-2007, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium + * Copyright (c) 2002-2007, Professor Benoit Macq + * Copyright (c) 2001-2003, David Janssens + * Copyright (c) 2002-2003, Yannick Verschueren + * Copyright (c) 2003-2007, Francois-Olivier Devaux and Antonin Descampe + * Copyright (c) 2005, Herve Drolon, FreeImage Team + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 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. + */ + +#ifndef __DWT_H +#define __DWT_H +/** +@file dwt.h +@brief Implementation of a discrete wavelet transform (DWT) + +The functions in DWT.C have for goal to realize forward and inverse discret wavelet +transform with filter 5-3 (reversible) and filter 9-7 (irreversible). The functions in +DWT.C are used by some function in TCD.C. +*/ + +/** @defgroup DWT DWT - Implementation of a discrete wavelet transform */ +/*@{*/ + + +/** @name Exported functions */ +/*@{*/ +/* ----------------------------------------------------------------------- */ +/** +Forward 5-3 wavelet tranform in 2-D. +Apply a reversible DWT transform to a component of an image. +@param tilec Tile component information (current tile) +*/ +void dwt_encode(opj_tcd_tilecomp_t * tilec); +/** +Inverse 5-3 wavelet tranform in 2-D. +Apply a reversible inverse DWT transform to a component of an image. +@param tilec Tile component information (current tile) +@param numres Number of resolution levels to decode +*/ +void dwt_decode(opj_tcd_tilecomp_t* tilec, int numres); +/** +Get the gain of a subband for the reversible 5-3 DWT. +@param orient Number that identifies the subband (0->LL, 1->HL, 2->LH, 3->HH) +@return Returns 0 if orient = 0, returns 1 if orient = 1 or 2, returns 2 otherwise +*/ +int dwt_getgain(int orient); +/** +Get the norm of a wavelet function of a subband at a specified level for the reversible 5-3 DWT. +@param level Level of the wavelet function +@param orient Band of the wavelet function +@return Returns the norm of the wavelet function +*/ +double dwt_getnorm(int level, int orient); +/** +Forward 9-7 wavelet transform in 2-D. +Apply an irreversible DWT transform to a component of an image. +@param tilec Tile component information (current tile) +*/ +void dwt_encode_real(opj_tcd_tilecomp_t * tilec); +/** +Inverse 9-7 wavelet transform in 2-D. +Apply an irreversible inverse DWT transform to a component of an image. +@param tilec Tile component information (current tile) +@param numres Number of resolution levels to decode +*/ +void dwt_decode_real(opj_tcd_tilecomp_t* tilec, int numres); +/** +Get the gain of a subband for the irreversible 9-7 DWT. +@param orient Number that identifies the subband (0->LL, 1->HL, 2->LH, 3->HH) +@return Returns the gain of the 9-7 wavelet transform +*/ +int dwt_getgain_real(int orient); +/** +Get the norm of a wavelet function of a subband at a specified level for the irreversible 9-7 DWT +@param level Level of the wavelet function +@param orient Band of the wavelet function +@return Returns the norm of the 9-7 wavelet +*/ +double dwt_getnorm_real(int level, int orient); +/** +Explicit calculation of the Quantization Stepsizes +@param tccp Tile-component coding parameters +@param prec Precint analyzed +*/ +void dwt_calc_explicit_stepsizes(opj_tccp_t * tccp, int prec); +/* ----------------------------------------------------------------------- */ +/*@}*/ + +/*@}*/ + +#endif /* __DWT_H */ diff --git a/extern/libopenjpeg/event.c b/extern/libopenjpeg/event.c new file mode 100644 index 00000000000..291ff585811 --- /dev/null +++ b/extern/libopenjpeg/event.c @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2005, Hervé Drolon, FreeImage Team + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 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. + */ + +#include "opj_includes.h" + +/* ========================================================== + Utility functions + ==========================================================*/ + +#if !defined(_MSC_VER) && !defined(__MINGW32__) +static char* +i2a(unsigned i, char *a, unsigned r) { + if (i/r > 0) a = i2a(i/r,a,r); + *a = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"[i%r]; + return a+1; +} + +/** + Transforms integer i into an ascii string and stores the result in a; + string is encoded in the base indicated by r. + @param i Number to be converted + @param a String result + @param r Base of value; must be in the range 2 - 36 + @return Returns a +*/ +static char * +_itoa(int i, char *a, int r) { + r = ((r < 2) || (r > 36)) ? 10 : r; + if(i < 0) { + *a = '-'; + *i2a(-i, a+1, r) = 0; + } + else *i2a(i, a, r) = 0; + return a; +} + +#endif /* !WIN32 */ + +/* ----------------------------------------------------------------------- */ + +opj_event_mgr_t* OPJ_CALLCONV opj_set_event_mgr(opj_common_ptr cinfo, opj_event_mgr_t *event_mgr, void *context) { + if(cinfo) { + opj_event_mgr_t *previous = cinfo->event_mgr; + cinfo->event_mgr = event_mgr; + cinfo->client_data = context; + return previous; + } + + return NULL; +} + +bool opj_event_msg(opj_common_ptr cinfo, int event_type, const char *fmt, ...) { +#define MSG_SIZE 512 /* 512 bytes should be more than enough for a short message */ + opj_msg_callback msg_handler = NULL; + + opj_event_mgr_t *event_mgr = cinfo->event_mgr; + if(event_mgr != NULL) { + switch(event_type) { + case EVT_ERROR: + msg_handler = event_mgr->error_handler; + break; + case EVT_WARNING: + msg_handler = event_mgr->warning_handler; + break; + case EVT_INFO: + msg_handler = event_mgr->info_handler; + break; + default: + break; + } + if(msg_handler == NULL) { + return false; + } + } else { + return false; + } + + if ((fmt != NULL) && (event_mgr != NULL)) { + va_list arg; + int str_length/*, i, j*/; /* UniPG */ + char message[MSG_SIZE]; + memset(message, 0, MSG_SIZE); + /* initialize the optional parameter list */ + va_start(arg, fmt); + /* check the length of the format string */ + str_length = (strlen(fmt) > MSG_SIZE) ? MSG_SIZE : strlen(fmt); + /* parse the format string and put the result in 'message' */ + vsprintf(message, fmt, arg); /* UniPG */ + /* deinitialize the optional parameter list */ + va_end(arg); + + /* output the message to the user program */ + msg_handler(message, cinfo->client_data); + } + + return true; +} + diff --git a/extern/libopenjpeg/event.h b/extern/libopenjpeg/event.h new file mode 100644 index 00000000000..11910b0e4bc --- /dev/null +++ b/extern/libopenjpeg/event.h @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2005, Hervé Drolon, FreeImage Team + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 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. + */ +#ifndef __EVENT_H +#define __EVENT_H +/** +@file event.h +@brief Implementation of a event callback system + +The functions in EVENT.C have for goal to send output messages (errors, warnings, debug) to the user. +*/ + +#define EVT_ERROR 1 /**< Error event type */ +#define EVT_WARNING 2 /**< Warning event type */ +#define EVT_INFO 4 /**< Debug event type */ + +/** @defgroup EVENT EVENT - Implementation of a event callback system */ +/*@{*/ + +/** @name Exported functions (see also openjpeg.h) */ +/*@{*/ +/* ----------------------------------------------------------------------- */ +/** +Write formatted data to a string and send the string to a user callback. +@param cinfo Codec context info +@param event_type Event type or callback to use to send the message +@param fmt Format-control string (plus optionnal arguments) +@return Returns true if successful, returns false otherwise +*/ +bool opj_event_msg(opj_common_ptr cinfo, int event_type, const char *fmt, ...); +/* ----------------------------------------------------------------------- */ +/*@}*/ + +/*@}*/ + +#endif /* __EVENT_H */ diff --git a/extern/libopenjpeg/fix.h b/extern/libopenjpeg/fix.h new file mode 100644 index 00000000000..bcb2acb54c8 --- /dev/null +++ b/extern/libopenjpeg/fix.h @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2002-2007, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium + * Copyright (c) 2002-2007, Professor Benoit Macq + * Copyright (c) 2001-2003, David Janssens + * Copyright (c) 2002-2003, Yannick Verschueren + * Copyright (c) 2003-2007, Francois-Olivier Devaux and Antonin Descampe + * Copyright (c) 2005, Herve Drolon, FreeImage Team + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 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. + */ +#ifndef __FIX_H +#define __FIX_H + +#if defined(_MSC_VER) || defined(__BORLANDC__) +#define int64 __int64 +#else +#define int64 long long +#endif + +/** +@file fix.h +@brief Implementation of operations of specific multiplication (FIX) + +The functions in FIX.H have for goal to realize specific multiplication. +*/ + +/** @defgroup FIX FIX - Implementation of operations of specific multiplication */ +/*@{*/ + +/** +Multiply two fixed-precision rational numbers. +@param a +@param b +@return Returns a * b +*/ +static INLINE int fix_mul(int a, int b) { + int64 temp = (int64) a * (int64) b ; + temp += temp & 4096; + return (int) (temp >> 13) ; +} + +/*@}*/ + +#endif /* __FIX_H */ diff --git a/extern/libopenjpeg/image.c b/extern/libopenjpeg/image.c new file mode 100644 index 00000000000..ea8e59ea547 --- /dev/null +++ b/extern/libopenjpeg/image.c @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2005, Hervé Drolon, FreeImage Team + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 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. + */ + +#include "opj_includes.h" + +opj_image_t* opj_image_create0(void) { + opj_image_t *image = (opj_image_t*)opj_malloc(sizeof(opj_image_t)); + return image; +} + +opj_image_t* OPJ_CALLCONV opj_image_create(int numcmpts, opj_image_cmptparm_t *cmptparms, OPJ_COLOR_SPACE clrspc) { + int compno; + opj_image_t *image = NULL; + + image = (opj_image_t*) opj_calloc(1, sizeof(opj_image_t)); + if(image) { + image->color_space = clrspc; + image->numcomps = numcmpts; + /* allocate memory for the per-component information */ + image->comps = (opj_image_comp_t*)opj_malloc(image->numcomps * sizeof(opj_image_comp_t)); + if(!image->comps) { + fprintf(stderr,"Unable to allocate memory for image.\n"); + opj_image_destroy(image); + return NULL; + } + /* create the individual image components */ + for(compno = 0; compno < numcmpts; compno++) { + opj_image_comp_t *comp = &image->comps[compno]; + comp->dx = cmptparms[compno].dx; + comp->dy = cmptparms[compno].dy; + comp->w = cmptparms[compno].w; + comp->h = cmptparms[compno].h; + comp->x0 = cmptparms[compno].x0; + comp->y0 = cmptparms[compno].y0; + comp->prec = cmptparms[compno].prec; + comp->bpp = cmptparms[compno].bpp; + comp->sgnd = cmptparms[compno].sgnd; + comp->data = (int*) opj_calloc(comp->w * comp->h, sizeof(int)); + if(!comp->data) { + fprintf(stderr,"Unable to allocate memory for image.\n"); + opj_image_destroy(image); + return NULL; + } + } + } + + return image; +} + +void OPJ_CALLCONV opj_image_destroy(opj_image_t *image) { + int i; + if(image) { + if(image->comps) { + /* image components */ + for(i = 0; i < image->numcomps; i++) { + opj_image_comp_t *image_comp = &image->comps[i]; + if(image_comp->data) { + opj_free(image_comp->data); + } + } + opj_free(image->comps); + } + opj_free(image); + } +} + diff --git a/extern/libopenjpeg/image.h b/extern/libopenjpeg/image.h new file mode 100644 index 00000000000..04c362eb834 --- /dev/null +++ b/extern/libopenjpeg/image.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2005, Hervé Drolon, FreeImage Team + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 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. + */ +#ifndef __IMAGE_H +#define __IMAGE_H +/** +@file image.h +@brief Implementation of operations on images (IMAGE) + +The functions in IMAGE.C have for goal to realize operations on images. +*/ + +/** @defgroup IMAGE IMAGE - Implementation of operations on images */ +/*@{*/ + +/** +Create an empty image +@todo this function should be removed +@return returns an empty image if successful, returns NULL otherwise +*/ +opj_image_t* opj_image_create0(void); + +/*@}*/ + +#endif /* __IMAGE_H */ + diff --git a/extern/libopenjpeg/int.h b/extern/libopenjpeg/int.h new file mode 100644 index 00000000000..4e5fe08eb76 --- /dev/null +++ b/extern/libopenjpeg/int.h @@ -0,0 +1,119 @@ +/* + * Copyright (c) 2002-2007, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium + * Copyright (c) 2002-2007, Professor Benoit Macq + * Copyright (c) 2001-2003, David Janssens + * Copyright (c) 2002-2003, Yannick Verschueren + * Copyright (c) 2003-2007, Francois-Olivier Devaux and Antonin Descampe + * Copyright (c) 2005, Herve Drolon, FreeImage Team + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 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. + */ +#ifndef __INT_H +#define __INT_H +/** +@file int.h +@brief Implementation of operations on integers (INT) + +The functions in INT.H have for goal to realize operations on integers. +*/ + +/** @defgroup INT INT - Implementation of operations on integers */ +/*@{*/ + +/** @name Exported functions (see also openjpeg.h) */ +/*@{*/ +/* ----------------------------------------------------------------------- */ +/** +Get the minimum of two integers +@return Returns a if a < b else b +*/ +static INLINE int int_min(int a, int b) { + return a < b ? a : b; +} +/** +Get the maximum of two integers +@return Returns a if a > b else b +*/ +static INLINE int int_max(int a, int b) { + return (a > b) ? a : b; +} +/** +Clamp an integer inside an interval +@return +
    +
  • Returns a if (min < a < max) +
  • Returns max if (a > max) +
  • Returns min if (a < min) +
+*/ +static INLINE int int_clamp(int a, int min, int max) { + if (a < min) + return min; + if (a > max) + return max; + return a; +} +/** +@return Get absolute value of integer +*/ +static INLINE int int_abs(int a) { + return a < 0 ? -a : a; +} +/** +Divide an integer and round upwards +@return Returns a divided by b +*/ +static INLINE int int_ceildiv(int a, int b) { + return (a + b - 1) / b; +} +/** +Divide an integer by a power of 2 and round upwards +@return Returns a divided by 2^b +*/ +static INLINE int int_ceildivpow2(int a, int b) { + return (a + (1 << b) - 1) >> b; +} +/** +Divide an integer by a power of 2 and round downwards +@return Returns a divided by 2^b +*/ +static INLINE int int_floordivpow2(int a, int b) { + return a >> b; +} +/** +Get logarithm of an integer and round downwards +@return Returns log2(a) +*/ +static INLINE int int_floorlog2(int a) { + int l; + for (l = 0; a > 1; l++) { + a >>= 1; + } + return l; +} +/* ----------------------------------------------------------------------- */ +/*@}*/ + +/*@}*/ + +#endif diff --git a/extern/libopenjpeg/j2k.c b/extern/libopenjpeg/j2k.c new file mode 100644 index 00000000000..8e7b1ce081f --- /dev/null +++ b/extern/libopenjpeg/j2k.c @@ -0,0 +1,2498 @@ +/* + * Copyright (c) 2002-2007, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium + * Copyright (c) 2002-2007, Professor Benoit Macq + * Copyright (c) 2001-2003, David Janssens + * Copyright (c) 2002-2003, Yannick Verschueren + * Copyright (c) 2003-2007, Francois-Olivier Devaux and Antonin Descampe + * Copyright (c) 2005, Herve Drolon, FreeImage Team + * Copyright (c) 2006-2007, Parvatha Elangovan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 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. + */ + +#include "opj_includes.h" + +/** @defgroup J2K J2K - JPEG-2000 codestream reader/writer */ +/*@{*/ + +/** @name Local static functions */ +/*@{*/ + +/** +Write the SOC marker (Start Of Codestream) +@param j2k J2K handle +*/ +static void j2k_write_soc(opj_j2k_t *j2k); +/** +Read the SOC marker (Start of Codestream) +@param j2k J2K handle +*/ +static void j2k_read_soc(opj_j2k_t *j2k); +/** +Write the SIZ marker (image and tile size) +@param j2k J2K handle +*/ +static void j2k_write_siz(opj_j2k_t *j2k); +/** +Read the SIZ marker (image and tile size) +@param j2k J2K handle +*/ +static void j2k_read_siz(opj_j2k_t *j2k); +/** +Write the COM marker (comment) +@param j2k J2K handle +*/ +static void j2k_write_com(opj_j2k_t *j2k); +/** +Read the COM marker (comment) +@param j2k J2K handle +*/ +static void j2k_read_com(opj_j2k_t *j2k); +/** +Write the value concerning the specified component in the marker COD and COC +@param j2k J2K handle +@param compno Number of the component concerned by the information written +*/ +static void j2k_write_cox(opj_j2k_t *j2k, int compno); +/** +Read the value concerning the specified component in the marker COD and COC +@param j2k J2K handle +@param compno Number of the component concerned by the information read +*/ +static void j2k_read_cox(opj_j2k_t *j2k, int compno); +/** +Write the COD marker (coding style default) +@param j2k J2K handle +*/ +static void j2k_write_cod(opj_j2k_t *j2k); +/** +Read the COD marker (coding style default) +@param j2k J2K handle +*/ +static void j2k_read_cod(opj_j2k_t *j2k); +/** +Write the COC marker (coding style component) +@param j2k J2K handle +@param compno Number of the component concerned by the information written +*/ +static void j2k_write_coc(opj_j2k_t *j2k, int compno); +/** +Read the COC marker (coding style component) +@param j2k J2K handle +*/ +static void j2k_read_coc(opj_j2k_t *j2k); +/** +Write the value concerning the specified component in the marker QCD and QCC +@param j2k J2K handle +@param compno Number of the component concerned by the information written +*/ +static void j2k_write_qcx(opj_j2k_t *j2k, int compno); +/** +Read the value concerning the specified component in the marker QCD and QCC +@param j2k J2K handle +@param compno Number of the component concern by the information read +@param len Length of the information in the QCX part of the marker QCD/QCC +*/ +static void j2k_read_qcx(opj_j2k_t *j2k, int compno, int len); +/** +Write the QCD marker (quantization default) +@param j2k J2K handle +*/ +static void j2k_write_qcd(opj_j2k_t *j2k); +/** +Read the QCD marker (quantization default) +@param j2k J2K handle +*/ +static void j2k_read_qcd(opj_j2k_t *j2k); +/** +Write the QCC marker (quantization component) +@param j2k J2K handle +@param compno Number of the component concerned by the information written +*/ +static void j2k_write_qcc(opj_j2k_t *j2k, int compno); +/** +Read the QCC marker (quantization component) +@param j2k J2K handle +*/ +static void j2k_read_qcc(opj_j2k_t *j2k); +/** +Write the POC marker (progression order change) +@param j2k J2K handle +*/ +static void j2k_write_poc(opj_j2k_t *j2k); +/** +Read the POC marker (progression order change) +@param j2k J2K handle +*/ +static void j2k_read_poc(opj_j2k_t *j2k); +/** +Read the CRG marker (component registration) +@param j2k J2K handle +*/ +static void j2k_read_crg(opj_j2k_t *j2k); +/** +Read the TLM marker (tile-part lengths) +@param j2k J2K handle +*/ +static void j2k_read_tlm(opj_j2k_t *j2k); +/** +Read the PLM marker (packet length, main header) +@param j2k J2K handle +*/ +static void j2k_read_plm(opj_j2k_t *j2k); +/** +Read the PLT marker (packet length, tile-part header) +@param j2k J2K handle +*/ +static void j2k_read_plt(opj_j2k_t *j2k); +/** +Read the PPM marker (packet packet headers, main header) +@param j2k J2K handle +*/ +static void j2k_read_ppm(opj_j2k_t *j2k); +/** +Read the PPT marker (packet packet headers, tile-part header) +@param j2k J2K handle +*/ +static void j2k_read_ppt(opj_j2k_t *j2k); +/** +Write the TLM marker (Mainheader) +@param j2k J2K handle +*/ +static void j2k_write_tlm(opj_j2k_t *j2k); +/** +Write the SOT marker (start of tile-part) +@param j2k J2K handle +*/ +static void j2k_write_sot(opj_j2k_t *j2k); +/** +Read the SOT marker (start of tile-part) +@param j2k J2K handle +*/ +static void j2k_read_sot(opj_j2k_t *j2k); +/** +Write the SOD marker (start of data) +@param j2k J2K handle +@param tile_coder Pointer to a TCD handle +*/ +static void j2k_write_sod(opj_j2k_t *j2k, void *tile_coder); +/** +Read the SOD marker (start of data) +@param j2k J2K handle +*/ +static void j2k_read_sod(opj_j2k_t *j2k); +/** +Write the RGN marker (region-of-interest) +@param j2k J2K handle +@param compno Number of the component concerned by the information written +@param tileno Number of the tile concerned by the information written +*/ +static void j2k_write_rgn(opj_j2k_t *j2k, int compno, int tileno); +/** +Read the RGN marker (region-of-interest) +@param j2k J2K handle +*/ +static void j2k_read_rgn(opj_j2k_t *j2k); +/** +Write the EOC marker (end of codestream) +@param j2k J2K handle +*/ +static void j2k_write_eoc(opj_j2k_t *j2k); +/** +Read the EOC marker (end of codestream) +@param j2k J2K handle +*/ +static void j2k_read_eoc(opj_j2k_t *j2k); +/** +Read an unknown marker +@param j2k J2K handle +*/ +static void j2k_read_unk(opj_j2k_t *j2k); + +/*@}*/ + +/*@}*/ + +/* ----------------------------------------------------------------------- */ +typedef struct j2k_prog_order{ + OPJ_PROG_ORDER enum_prog; + char str_prog[4]; +}j2k_prog_order_t; + +j2k_prog_order_t j2k_prog_order_list[] = { + {CPRL, "CPRL"}, + {LRCP, "LRCP"}, + {PCRL, "PCRL"}, + {RLCP, "RLCP"}, + {RPCL, "RPCL"}, + {-1, ""} +}; + +char *j2k_convert_progression_order(OPJ_PROG_ORDER prg_order){ + j2k_prog_order_t *po; + for(po = j2k_prog_order_list; po->enum_prog != -1; po++ ){ + if(po->enum_prog == prg_order){ + break; + } + } + return po->str_prog; +} + +void j2k_dump_image(FILE *fd, opj_image_t * img) { + int compno; + fprintf(fd, "image {\n"); + fprintf(fd, " x0=%d, y0=%d, x1=%d, y1=%d\n", img->x0, img->y0, img->x1, img->y1); + fprintf(fd, " numcomps=%d\n", img->numcomps); + for (compno = 0; compno < img->numcomps; compno++) { + opj_image_comp_t *comp = &img->comps[compno]; + fprintf(fd, " comp %d {\n", compno); + fprintf(fd, " dx=%d, dy=%d\n", comp->dx, comp->dy); + fprintf(fd, " prec=%d\n", comp->prec); + fprintf(fd, " sgnd=%d\n", comp->sgnd); + fprintf(fd, " }\n"); + } + fprintf(fd, "}\n"); +} + +void j2k_dump_cp(FILE *fd, opj_image_t * img, opj_cp_t * cp) { + int tileno, compno, layno, bandno, resno, numbands; + fprintf(fd, "coding parameters {\n"); + fprintf(fd, " tx0=%d, ty0=%d\n", cp->tx0, cp->ty0); + fprintf(fd, " tdx=%d, tdy=%d\n", cp->tdx, cp->tdy); + fprintf(fd, " tw=%d, th=%d\n", cp->tw, cp->th); + for (tileno = 0; tileno < cp->tw * cp->th; tileno++) { + opj_tcp_t *tcp = &cp->tcps[tileno]; + fprintf(fd, " tile %d {\n", tileno); + fprintf(fd, " csty=%x\n", tcp->csty); + fprintf(fd, " prg=%d\n", tcp->prg); + fprintf(fd, " numlayers=%d\n", tcp->numlayers); + fprintf(fd, " mct=%d\n", tcp->mct); + fprintf(fd, " rates="); + for (layno = 0; layno < tcp->numlayers; layno++) { + fprintf(fd, "%.1f ", tcp->rates[layno]); + } + fprintf(fd, "\n"); + for (compno = 0; compno < img->numcomps; compno++) { + opj_tccp_t *tccp = &tcp->tccps[compno]; + fprintf(fd, " comp %d {\n", compno); + fprintf(fd, " csty=%x\n", tccp->csty); + fprintf(fd, " numresolutions=%d\n", tccp->numresolutions); + fprintf(fd, " cblkw=%d\n", tccp->cblkw); + fprintf(fd, " cblkh=%d\n", tccp->cblkh); + fprintf(fd, " cblksty=%x\n", tccp->cblksty); + fprintf(fd, " qmfbid=%d\n", tccp->qmfbid); + fprintf(fd, " qntsty=%d\n", tccp->qntsty); + fprintf(fd, " numgbits=%d\n", tccp->numgbits); + fprintf(fd, " roishift=%d\n", tccp->roishift); + fprintf(fd, " stepsizes="); + numbands = tccp->qntsty == J2K_CCP_QNTSTY_SIQNT ? 1 : tccp->numresolutions * 3 - 2; + for (bandno = 0; bandno < numbands; bandno++) { + fprintf(fd, "(%d,%d) ", tccp->stepsizes[bandno].mant, + tccp->stepsizes[bandno].expn); + } + fprintf(fd, "\n"); + + if (tccp->csty & J2K_CCP_CSTY_PRT) { + fprintf(fd, " prcw="); + for (resno = 0; resno < tccp->numresolutions; resno++) { + fprintf(fd, "%d ", tccp->prcw[resno]); + } + fprintf(fd, "\n"); + fprintf(fd, " prch="); + for (resno = 0; resno < tccp->numresolutions; resno++) { + fprintf(fd, "%d ", tccp->prch[resno]); + } + fprintf(fd, "\n"); + } + fprintf(fd, " }\n"); + } + fprintf(fd, " }\n"); + } + fprintf(fd, "}\n"); +} + +/* ----------------------------------------------------------------------- */ +static int j2k_get_num_tp(opj_cp_t *cp,int pino,int tileno){ + char *prog; + int i; + int tpnum=1,tpend=0; + opj_tcp_t *tcp = &cp->tcps[tileno]; + prog = j2k_convert_progression_order(tcp->prg); + + if(cp->tp_on == 1){ + for(i=0;i<4;i++){ + if(tpend!=1){ + if( cp->tp_flag == prog[i] ){ + tpend=1;cp->tp_pos=i; + } + switch(prog[i]){ + case 'C': + tpnum= tpnum * tcp->pocs[pino].compE; + break; + case 'R': + tpnum= tpnum * tcp->pocs[pino].resE; + break; + case 'P': + tpnum= tpnum * tcp->pocs[pino].prcE; + break; + case 'L': + tpnum= tpnum * tcp->pocs[pino].layE; + break; + } + } + } + }else{ + tpnum=1; + } + return tpnum; +} + +/** mem allocation for TLM marker*/ +int j2k_calculate_tp(opj_cp_t *cp,int img_numcomp,opj_image_t *image,opj_j2k_t *j2k ){ + int pino,tileno,totnum_tp=0; + j2k->cur_totnum_tp = (int *) opj_malloc(cp->tw * cp->th * sizeof(int)); + for (tileno = 0; tileno < cp->tw * cp->th; tileno++) { + int cur_totnum_tp = 0; + opj_tcp_t *tcp = &cp->tcps[tileno]; + for(pino = 0; pino <= tcp->numpocs; pino++) { + int tp_num=0; + opj_pi_iterator_t *pi = pi_initialise_encode(image, cp, tileno,FINAL_PASS); + if(!pi) { return -1;} + tp_num = j2k_get_num_tp(cp,pino,tileno); + totnum_tp = totnum_tp + tp_num; + cur_totnum_tp = cur_totnum_tp + tp_num; + pi_destroy(pi, cp, tileno); + } + j2k->cur_totnum_tp[tileno] = cur_totnum_tp; + /* INDEX >> */ + if (j2k->cstr_info) { + j2k->cstr_info->tile[tileno].num_tps = cur_totnum_tp; + j2k->cstr_info->tile[tileno].tp = (opj_tp_info_t *) opj_malloc(cur_totnum_tp * sizeof(opj_tp_info_t)); + } + /* << INDEX */ + } + return totnum_tp; +} + +static void j2k_write_soc(opj_j2k_t *j2k) { + opj_cio_t *cio = j2k->cio; + cio_write(cio, J2K_MS_SOC, 2); + +/* UniPG>> */ +#ifdef USE_JPWL + + /* update markers struct */ + j2k_add_marker(j2k->cstr_info, J2K_MS_SOC, cio_tell(cio) - 2, 2); + +#endif /* USE_JPWL */ +/* <state = J2K_STATE_MHSIZ; + /* Index */ + if (j2k->cstr_info) { + j2k->cstr_info->main_head_start = cio_tell(j2k->cio) - 2; + j2k->cstr_info->codestream_size = cio_numbytesleft(j2k->cio) + 2 - j2k->cstr_info->main_head_start; + } +} + +static void j2k_write_siz(opj_j2k_t *j2k) { + int i; + int lenp, len; + + opj_cio_t *cio = j2k->cio; + opj_image_t *image = j2k->image; + opj_cp_t *cp = j2k->cp; + + cio_write(cio, J2K_MS_SIZ, 2); /* SIZ */ + lenp = cio_tell(cio); + cio_skip(cio, 2); + cio_write(cio, cp->rsiz, 2); /* Rsiz (capabilities) */ + cio_write(cio, image->x1, 4); /* Xsiz */ + cio_write(cio, image->y1, 4); /* Ysiz */ + cio_write(cio, image->x0, 4); /* X0siz */ + cio_write(cio, image->y0, 4); /* Y0siz */ + cio_write(cio, cp->tdx, 4); /* XTsiz */ + cio_write(cio, cp->tdy, 4); /* YTsiz */ + cio_write(cio, cp->tx0, 4); /* XT0siz */ + cio_write(cio, cp->ty0, 4); /* YT0siz */ + cio_write(cio, image->numcomps, 2); /* Csiz */ + for (i = 0; i < image->numcomps; i++) { + cio_write(cio, image->comps[i].prec - 1 + (image->comps[i].sgnd << 7), 1); /* Ssiz_i */ + cio_write(cio, image->comps[i].dx, 1); /* XRsiz_i */ + cio_write(cio, image->comps[i].dy, 1); /* YRsiz_i */ + } + len = cio_tell(cio) - lenp; + cio_seek(cio, lenp); + cio_write(cio, len, 2); /* Lsiz */ + cio_seek(cio, lenp + len); +} + +static void j2k_read_siz(opj_j2k_t *j2k) { + int len, i; + + opj_cio_t *cio = j2k->cio; + opj_image_t *image = j2k->image; + opj_cp_t *cp = j2k->cp; + + len = cio_read(cio, 2); /* Lsiz */ + cio_read(cio, 2); /* Rsiz (capabilities) */ + image->x1 = cio_read(cio, 4); /* Xsiz */ + image->y1 = cio_read(cio, 4); /* Ysiz */ + image->x0 = cio_read(cio, 4); /* X0siz */ + image->y0 = cio_read(cio, 4); /* Y0siz */ + cp->tdx = cio_read(cio, 4); /* XTsiz */ + cp->tdy = cio_read(cio, 4); /* YTsiz */ + cp->tx0 = cio_read(cio, 4); /* XT0siz */ + cp->ty0 = cio_read(cio, 4); /* YT0siz */ + + image->numcomps = cio_read(cio, 2); /* Csiz */ + +#ifdef USE_JPWL + if (j2k->cp->correct) { + /* if JPWL is on, we check whether TX errors have damaged + too much the SIZ parameters */ + if (!(image->x1 * image->y1)) { + opj_event_msg(j2k->cinfo, EVT_ERROR, + "JPWL: bad image size (%d x %d)\n", + image->x1, image->y1); + if (!JPWL_ASSUME || JPWL_ASSUME) { + opj_event_msg(j2k->cinfo, EVT_ERROR, "JPWL: giving up\n"); + return; + } + } + if (image->numcomps != ((len - 38) / 3)) { + opj_event_msg(j2k->cinfo, JPWL_ASSUME ? EVT_WARNING : EVT_ERROR, + "JPWL: Csiz is %d => space in SIZ only for %d comps.!!!\n", + image->numcomps, ((len - 38) / 3)); + if (!JPWL_ASSUME) { + opj_event_msg(j2k->cinfo, EVT_ERROR, "JPWL: giving up\n"); + return; + } + /* we try to correct */ + opj_event_msg(j2k->cinfo, EVT_WARNING, "- trying to adjust this\n"); + if (image->numcomps < ((len - 38) / 3)) { + len = 38 + 3 * image->numcomps; + opj_event_msg(j2k->cinfo, EVT_WARNING, "- setting Lsiz to %d => HYPOTHESIS!!!\n", + len); + } else { + image->numcomps = ((len - 38) / 3); + opj_event_msg(j2k->cinfo, EVT_WARNING, "- setting Csiz to %d => HYPOTHESIS!!!\n", + image->numcomps); + } + } + + /* update components number in the jpwl_exp_comps filed */ + cp->exp_comps = image->numcomps; + } +#endif /* USE_JPWL */ + + image->comps = (opj_image_comp_t*) opj_calloc(image->numcomps, sizeof(opj_image_comp_t)); + for (i = 0; i < image->numcomps; i++) { + int tmp, w, h; + tmp = cio_read(cio, 1); /* Ssiz_i */ + image->comps[i].prec = (tmp & 0x7f) + 1; + image->comps[i].sgnd = tmp >> 7; + image->comps[i].dx = cio_read(cio, 1); /* XRsiz_i */ + image->comps[i].dy = cio_read(cio, 1); /* YRsiz_i */ + +#ifdef USE_JPWL + if (j2k->cp->correct) { + /* if JPWL is on, we check whether TX errors have damaged + too much the SIZ parameters, again */ + if (!(image->comps[i].dx * image->comps[i].dy)) { + opj_event_msg(j2k->cinfo, JPWL_ASSUME ? EVT_WARNING : EVT_ERROR, + "JPWL: bad XRsiz_%d/YRsiz_%d (%d x %d)\n", + i, i, image->comps[i].dx, image->comps[i].dy); + if (!JPWL_ASSUME) { + opj_event_msg(j2k->cinfo, EVT_ERROR, "JPWL: giving up\n"); + return; + } + /* we try to correct */ + opj_event_msg(j2k->cinfo, EVT_WARNING, "- trying to adjust them\n"); + if (!image->comps[i].dx) { + image->comps[i].dx = 1; + opj_event_msg(j2k->cinfo, EVT_WARNING, "- setting XRsiz_%d to %d => HYPOTHESIS!!!\n", + i, image->comps[i].dx); + } + if (!image->comps[i].dy) { + image->comps[i].dy = 1; + opj_event_msg(j2k->cinfo, EVT_WARNING, "- setting YRsiz_%d to %d => HYPOTHESIS!!!\n", + i, image->comps[i].dy); + } + } + + } +#endif /* USE_JPWL */ + + /* TODO: unused ? */ + w = int_ceildiv(image->x1 - image->x0, image->comps[i].dx); + h = int_ceildiv(image->y1 - image->y0, image->comps[i].dy); + + image->comps[i].resno_decoded = 0; /* number of resolution decoded */ + image->comps[i].factor = cp->reduce; /* reducing factor per component */ + } + + cp->tw = int_ceildiv(image->x1 - cp->tx0, cp->tdx); + cp->th = int_ceildiv(image->y1 - cp->ty0, cp->tdy); + +#ifdef USE_JPWL + if (j2k->cp->correct) { + /* if JPWL is on, we check whether TX errors have damaged + too much the SIZ parameters */ + if ((cp->tw < 1) || (cp->th < 1) || (cp->tw > cp->max_tiles) || (cp->th > cp->max_tiles)) { + opj_event_msg(j2k->cinfo, JPWL_ASSUME ? EVT_WARNING : EVT_ERROR, + "JPWL: bad number of tiles (%d x %d)\n", + cp->tw, cp->th); + if (!JPWL_ASSUME) { + opj_event_msg(j2k->cinfo, EVT_ERROR, "JPWL: giving up\n"); + return; + } + /* we try to correct */ + opj_event_msg(j2k->cinfo, EVT_WARNING, "- trying to adjust them\n"); + if (cp->tw < 1) { + cp->tw= 1; + opj_event_msg(j2k->cinfo, EVT_WARNING, "- setting %d tiles in x => HYPOTHESIS!!!\n", + cp->tw); + } + if (cp->tw > cp->max_tiles) { + cp->tw= 1; + opj_event_msg(j2k->cinfo, EVT_WARNING, "- too large x, increase expectance of %d\n" + "- setting %d tiles in x => HYPOTHESIS!!!\n", + cp->max_tiles, cp->tw); + } + if (cp->th < 1) { + cp->th= 1; + opj_event_msg(j2k->cinfo, EVT_WARNING, "- setting %d tiles in y => HYPOTHESIS!!!\n", + cp->th); + } + if (cp->th > cp->max_tiles) { + cp->th= 1; + opj_event_msg(j2k->cinfo, EVT_WARNING, "- too large y, increase expectance of %d to continue\n", + "- setting %d tiles in y => HYPOTHESIS!!!\n", + cp->max_tiles, cp->th); + } + } + } +#endif /* USE_JPWL */ + + cp->tcps = (opj_tcp_t*) opj_calloc(cp->tw * cp->th, sizeof(opj_tcp_t)); + cp->tileno = (int*) opj_malloc(cp->tw * cp->th * sizeof(int)); + cp->tileno_size = 0; + +#ifdef USE_JPWL + if (j2k->cp->correct) { + if (!cp->tcps) { + opj_event_msg(j2k->cinfo, JPWL_ASSUME ? EVT_WARNING : EVT_ERROR, + "JPWL: could not alloc tcps field of cp\n"); + if (!JPWL_ASSUME || JPWL_ASSUME) { + opj_event_msg(j2k->cinfo, EVT_ERROR, "JPWL: giving up\n"); + return; + } + } + } +#endif /* USE_JPWL */ + + for (i = 0; i < cp->tw * cp->th; i++) { + cp->tcps[i].POC = 0; + cp->tcps[i].numpocs = 0; + cp->tcps[i].first = 1; + } + + /* Initialization for PPM marker */ + cp->ppm = 0; + cp->ppm_data = NULL; + cp->ppm_data_first = NULL; + cp->ppm_previous = 0; + cp->ppm_store = 0; + + j2k->default_tcp->tccps = (opj_tccp_t*) opj_calloc(image->numcomps, sizeof(opj_tccp_t)); + for (i = 0; i < cp->tw * cp->th; i++) { + cp->tcps[i].tccps = (opj_tccp_t*) opj_malloc(image->numcomps * sizeof(opj_tccp_t)); + } + j2k->tile_data = (unsigned char**) opj_calloc(cp->tw * cp->th, sizeof(unsigned char*)); + j2k->tile_len = (int*) opj_calloc(cp->tw * cp->th, sizeof(int)); + j2k->state = J2K_STATE_MH; + + /* Index */ + if (j2k->cstr_info) { + opj_codestream_info_t *cstr_info = j2k->cstr_info; + cstr_info->image_w = image->x1 - image->x0; + cstr_info->image_h = image->y1 - image->y0; + cstr_info->numcomps = image->numcomps; + cstr_info->tw = cp->tw; + cstr_info->th = cp->th; + cstr_info->tile_x = cp->tdx; + cstr_info->tile_y = cp->tdy; + cstr_info->tile_Ox = cp->tx0; + cstr_info->tile_Oy = cp->ty0; + cstr_info->tile = (opj_tile_info_t*) opj_calloc(cp->tw * cp->th, sizeof(opj_tile_info_t)); + } +} + +static void j2k_write_com(opj_j2k_t *j2k) { + unsigned int i; + int lenp, len; + + if(j2k->cp->comment) { + opj_cio_t *cio = j2k->cio; + char *comment = j2k->cp->comment; + + cio_write(cio, J2K_MS_COM, 2); + lenp = cio_tell(cio); + cio_skip(cio, 2); + cio_write(cio, 1, 2); /* General use (IS 8859-15:1999 (Latin) values) */ + for (i = 0; i < strlen(comment); i++) { + cio_write(cio, comment[i], 1); + } + len = cio_tell(cio) - lenp; + cio_seek(cio, lenp); + cio_write(cio, len, 2); + cio_seek(cio, lenp + len); + } +} + +static void j2k_read_com(opj_j2k_t *j2k) { + int len; + + opj_cio_t *cio = j2k->cio; + + len = cio_read(cio, 2); + cio_skip(cio, len - 2); +} + +static void j2k_write_cox(opj_j2k_t *j2k, int compno) { + int i; + + opj_cp_t *cp = j2k->cp; + opj_tcp_t *tcp = &cp->tcps[j2k->curtileno]; + opj_tccp_t *tccp = &tcp->tccps[compno]; + opj_cio_t *cio = j2k->cio; + + cio_write(cio, tccp->numresolutions - 1, 1); /* SPcox (D) */ + cio_write(cio, tccp->cblkw - 2, 1); /* SPcox (E) */ + cio_write(cio, tccp->cblkh - 2, 1); /* SPcox (F) */ + cio_write(cio, tccp->cblksty, 1); /* SPcox (G) */ + cio_write(cio, tccp->qmfbid, 1); /* SPcox (H) */ + + if (tccp->csty & J2K_CCP_CSTY_PRT) { + for (i = 0; i < tccp->numresolutions; i++) { + cio_write(cio, tccp->prcw[i] + (tccp->prch[i] << 4), 1); /* SPcox (I_i) */ + } + } +} + +static void j2k_read_cox(opj_j2k_t *j2k, int compno) { + int i; + + opj_cp_t *cp = j2k->cp; + opj_tcp_t *tcp = j2k->state == J2K_STATE_TPH ? &cp->tcps[j2k->curtileno] : j2k->default_tcp; + opj_tccp_t *tccp = &tcp->tccps[compno]; + opj_cio_t *cio = j2k->cio; + + tccp->numresolutions = cio_read(cio, 1) + 1; /* SPcox (D) */ + + // If user wants to remove more resolutions than the codestream contains, return error + if (cp->reduce >= tccp->numresolutions) { + opj_event_msg(j2k->cinfo, EVT_ERROR, "Error decoding component %d.\nThe number of resolutions to remove is higher than the number " + "of resolutions of this component\nModify the cp_reduce parameter.\n\n", compno); + j2k->state |= J2K_STATE_ERR; + } + + tccp->cblkw = cio_read(cio, 1) + 2; /* SPcox (E) */ + tccp->cblkh = cio_read(cio, 1) + 2; /* SPcox (F) */ + tccp->cblksty = cio_read(cio, 1); /* SPcox (G) */ + tccp->qmfbid = cio_read(cio, 1); /* SPcox (H) */ + if (tccp->csty & J2K_CP_CSTY_PRT) { + for (i = 0; i < tccp->numresolutions; i++) { + int tmp = cio_read(cio, 1); /* SPcox (I_i) */ + tccp->prcw[i] = tmp & 0xf; + tccp->prch[i] = tmp >> 4; + } + } + + /* INDEX >> */ + if(j2k->cstr_info && compno == 0) { + for (i = 0; i < tccp->numresolutions; i++) { + if (tccp->csty & J2K_CP_CSTY_PRT) { + j2k->cstr_info->tile[j2k->curtileno].pdx[i] = tccp->prcw[i]; + j2k->cstr_info->tile[j2k->curtileno].pdy[i] = tccp->prch[i]; + } + else { + j2k->cstr_info->tile[j2k->curtileno].pdx[i] = 15; + j2k->cstr_info->tile[j2k->curtileno].pdx[i] = 15; + } + } + } + /* << INDEX */ +} + +static void j2k_write_cod(opj_j2k_t *j2k) { + opj_cp_t *cp = NULL; + opj_tcp_t *tcp = NULL; + int lenp, len; + + opj_cio_t *cio = j2k->cio; + + cio_write(cio, J2K_MS_COD, 2); /* COD */ + + lenp = cio_tell(cio); + cio_skip(cio, 2); + + cp = j2k->cp; + tcp = &cp->tcps[j2k->curtileno]; + + cio_write(cio, tcp->csty, 1); /* Scod */ + cio_write(cio, tcp->prg, 1); /* SGcod (A) */ + cio_write(cio, tcp->numlayers, 2); /* SGcod (B) */ + cio_write(cio, tcp->mct, 1); /* SGcod (C) */ + + j2k_write_cox(j2k, 0); + len = cio_tell(cio) - lenp; + cio_seek(cio, lenp); + cio_write(cio, len, 2); /* Lcod */ + cio_seek(cio, lenp + len); +} + +static void j2k_read_cod(opj_j2k_t *j2k) { + int len, i, pos; + + opj_cio_t *cio = j2k->cio; + opj_cp_t *cp = j2k->cp; + opj_tcp_t *tcp = j2k->state == J2K_STATE_TPH ? &cp->tcps[j2k->curtileno] : j2k->default_tcp; + opj_image_t *image = j2k->image; + + len = cio_read(cio, 2); /* Lcod */ + tcp->csty = cio_read(cio, 1); /* Scod */ + tcp->prg = (OPJ_PROG_ORDER)cio_read(cio, 1); /* SGcod (A) */ + tcp->numlayers = cio_read(cio, 2); /* SGcod (B) */ + tcp->mct = cio_read(cio, 1); /* SGcod (C) */ + + pos = cio_tell(cio); + for (i = 0; i < image->numcomps; i++) { + tcp->tccps[i].csty = tcp->csty & J2K_CP_CSTY_PRT; + cio_seek(cio, pos); + j2k_read_cox(j2k, i); + } + + /* Index */ + if (j2k->cstr_info) { + opj_codestream_info_t *cstr_info = j2k->cstr_info; + cstr_info->prog = tcp->prg; + cstr_info->numlayers = tcp->numlayers; + cstr_info->numdecompos = (int*) opj_malloc(image->numcomps * sizeof(int)); + for (i = 0; i < image->numcomps; i++) { + cstr_info->numdecompos[i] = tcp->tccps[i].numresolutions - 1; + } + } +} + +static void j2k_write_coc(opj_j2k_t *j2k, int compno) { + int lenp, len; + + opj_cp_t *cp = j2k->cp; + opj_tcp_t *tcp = &cp->tcps[j2k->curtileno]; + opj_image_t *image = j2k->image; + opj_cio_t *cio = j2k->cio; + + cio_write(cio, J2K_MS_COC, 2); /* COC */ + lenp = cio_tell(cio); + cio_skip(cio, 2); + cio_write(cio, compno, image->numcomps <= 256 ? 1 : 2); /* Ccoc */ + cio_write(cio, tcp->tccps[compno].csty, 1); /* Scoc */ + j2k_write_cox(j2k, compno); + len = cio_tell(cio) - lenp; + cio_seek(cio, lenp); + cio_write(cio, len, 2); /* Lcoc */ + cio_seek(cio, lenp + len); +} + +static void j2k_read_coc(opj_j2k_t *j2k) { + int len, compno; + + opj_cp_t *cp = j2k->cp; + opj_tcp_t *tcp = j2k->state == J2K_STATE_TPH ? &cp->tcps[j2k->curtileno] : j2k->default_tcp; + opj_image_t *image = j2k->image; + opj_cio_t *cio = j2k->cio; + + len = cio_read(cio, 2); /* Lcoc */ + compno = cio_read(cio, image->numcomps <= 256 ? 1 : 2); /* Ccoc */ + tcp->tccps[compno].csty = cio_read(cio, 1); /* Scoc */ + j2k_read_cox(j2k, compno); +} + +static void j2k_write_qcx(opj_j2k_t *j2k, int compno) { + int bandno, numbands; + int expn, mant; + + opj_cp_t *cp = j2k->cp; + opj_tcp_t *tcp = &cp->tcps[j2k->curtileno]; + opj_tccp_t *tccp = &tcp->tccps[compno]; + opj_cio_t *cio = j2k->cio; + + cio_write(cio, tccp->qntsty + (tccp->numgbits << 5), 1); /* Sqcx */ + numbands = tccp->qntsty == J2K_CCP_QNTSTY_SIQNT ? 1 : tccp->numresolutions * 3 - 2; + + for (bandno = 0; bandno < numbands; bandno++) { + expn = tccp->stepsizes[bandno].expn; + mant = tccp->stepsizes[bandno].mant; + + if (tccp->qntsty == J2K_CCP_QNTSTY_NOQNT) { + cio_write(cio, expn << 3, 1); /* SPqcx_i */ + } else { + cio_write(cio, (expn << 11) + mant, 2); /* SPqcx_i */ + } + } +} + +static void j2k_read_qcx(opj_j2k_t *j2k, int compno, int len) { + int tmp; + int bandno, numbands; + + opj_cp_t *cp = j2k->cp; + opj_tcp_t *tcp = j2k->state == J2K_STATE_TPH ? &cp->tcps[j2k->curtileno] : j2k->default_tcp; + opj_tccp_t *tccp = &tcp->tccps[compno]; + opj_cio_t *cio = j2k->cio; + + tmp = cio_read(cio, 1); /* Sqcx */ + tccp->qntsty = tmp & 0x1f; + tccp->numgbits = tmp >> 5; + numbands = (tccp->qntsty == J2K_CCP_QNTSTY_SIQNT) ? + 1 : ((tccp->qntsty == J2K_CCP_QNTSTY_NOQNT) ? len - 1 : (len - 1) / 2); + +#ifdef USE_JPWL + if (j2k->cp->correct) { + + /* if JPWL is on, we check whether there are too many subbands */ + if ((numbands < 0) || (numbands >= J2K_MAXBANDS)) { + opj_event_msg(j2k->cinfo, JPWL_ASSUME ? EVT_WARNING : EVT_ERROR, + "JPWL: bad number of subbands in Sqcx (%d)\n", + numbands); + if (!JPWL_ASSUME) { + opj_event_msg(j2k->cinfo, EVT_ERROR, "JPWL: giving up\n"); + return; + } + /* we try to correct */ + numbands = 1; + opj_event_msg(j2k->cinfo, EVT_WARNING, "- trying to adjust them\n" + "- setting number of bands to %d => HYPOTHESIS!!!\n", + numbands); + }; + + }; +#endif /* USE_JPWL */ + + for (bandno = 0; bandno < numbands; bandno++) { + int expn, mant; + if (tccp->qntsty == J2K_CCP_QNTSTY_NOQNT) { + expn = cio_read(cio, 1) >> 3; /* SPqcx_i */ + mant = 0; + } else { + tmp = cio_read(cio, 2); /* SPqcx_i */ + expn = tmp >> 11; + mant = tmp & 0x7ff; + } + tccp->stepsizes[bandno].expn = expn; + tccp->stepsizes[bandno].mant = mant; + } + + /* Add Antonin : if scalar_derived -> compute other stepsizes */ + if (tccp->qntsty == J2K_CCP_QNTSTY_SIQNT) { + for (bandno = 1; bandno < J2K_MAXBANDS; bandno++) { + tccp->stepsizes[bandno].expn = + ((tccp->stepsizes[0].expn) - ((bandno - 1) / 3) > 0) ? + (tccp->stepsizes[0].expn) - ((bandno - 1) / 3) : 0; + tccp->stepsizes[bandno].mant = tccp->stepsizes[0].mant; + } + } + /* ddA */ +} + +static void j2k_write_qcd(opj_j2k_t *j2k) { + int lenp, len; + + opj_cio_t *cio = j2k->cio; + + cio_write(cio, J2K_MS_QCD, 2); /* QCD */ + lenp = cio_tell(cio); + cio_skip(cio, 2); + j2k_write_qcx(j2k, 0); + len = cio_tell(cio) - lenp; + cio_seek(cio, lenp); + cio_write(cio, len, 2); /* Lqcd */ + cio_seek(cio, lenp + len); +} + +static void j2k_read_qcd(opj_j2k_t *j2k) { + int len, i, pos; + + opj_cio_t *cio = j2k->cio; + opj_image_t *image = j2k->image; + + len = cio_read(cio, 2); /* Lqcd */ + pos = cio_tell(cio); + for (i = 0; i < image->numcomps; i++) { + cio_seek(cio, pos); + j2k_read_qcx(j2k, i, len - 2); + } +} + +static void j2k_write_qcc(opj_j2k_t *j2k, int compno) { + int lenp, len; + + opj_cio_t *cio = j2k->cio; + + cio_write(cio, J2K_MS_QCC, 2); /* QCC */ + lenp = cio_tell(cio); + cio_skip(cio, 2); + cio_write(cio, compno, j2k->image->numcomps <= 256 ? 1 : 2); /* Cqcc */ + j2k_write_qcx(j2k, compno); + len = cio_tell(cio) - lenp; + cio_seek(cio, lenp); + cio_write(cio, len, 2); /* Lqcc */ + cio_seek(cio, lenp + len); +} + +static void j2k_read_qcc(opj_j2k_t *j2k) { + int len, compno; + int numcomp = j2k->image->numcomps; + opj_cio_t *cio = j2k->cio; + + len = cio_read(cio, 2); /* Lqcc */ + compno = cio_read(cio, numcomp <= 256 ? 1 : 2); /* Cqcc */ + +#ifdef USE_JPWL + if (j2k->cp->correct) { + + static int backup_compno = 0; + + /* compno is negative or larger than the number of components!!! */ + if ((compno < 0) || (compno >= numcomp)) { + opj_event_msg(j2k->cinfo, EVT_ERROR, + "JPWL: bad component number in QCC (%d out of a maximum of %d)\n", + compno, numcomp); + if (!JPWL_ASSUME) { + opj_event_msg(j2k->cinfo, EVT_ERROR, "JPWL: giving up\n"); + return; + } + /* we try to correct */ + compno = backup_compno % numcomp; + opj_event_msg(j2k->cinfo, EVT_WARNING, "- trying to adjust this\n" + "- setting component number to %d\n", + compno); + } + + /* keep your private count of tiles */ + backup_compno++; + }; +#endif /* USE_JPWL */ + + j2k_read_qcx(j2k, compno, len - 2 - (numcomp <= 256 ? 1 : 2)); +} + +static void j2k_write_poc(opj_j2k_t *j2k) { + int len, numpchgs, i; + + int numcomps = j2k->image->numcomps; + + opj_cp_t *cp = j2k->cp; + opj_tcp_t *tcp = &cp->tcps[j2k->curtileno]; + opj_tccp_t *tccp = &tcp->tccps[0]; + opj_cio_t *cio = j2k->cio; + + numpchgs = 1 + tcp->numpocs; + cio_write(cio, J2K_MS_POC, 2); /* POC */ + len = 2 + (5 + 2 * (numcomps <= 256 ? 1 : 2)) * numpchgs; + cio_write(cio, len, 2); /* Lpoc */ + for (i = 0; i < numpchgs; i++) { + opj_poc_t *poc = &tcp->pocs[i]; + cio_write(cio, poc->resno0, 1); /* RSpoc_i */ + cio_write(cio, poc->compno0, (numcomps <= 256 ? 1 : 2)); /* CSpoc_i */ + cio_write(cio, poc->layno1, 2); /* LYEpoc_i */ + poc->layno1 = int_min(poc->layno1, tcp->numlayers); + cio_write(cio, poc->resno1, 1); /* REpoc_i */ + poc->resno1 = int_min(poc->resno1, tccp->numresolutions); + cio_write(cio, poc->compno1, (numcomps <= 256 ? 1 : 2)); /* CEpoc_i */ + poc->compno1 = int_min(poc->compno1, numcomps); + cio_write(cio, poc->prg, 1); /* Ppoc_i */ + } +} + +static void j2k_read_poc(opj_j2k_t *j2k) { + int len, numpchgs, i, old_poc; + + int numcomps = j2k->image->numcomps; + + opj_cp_t *cp = j2k->cp; + opj_tcp_t *tcp = j2k->state == J2K_STATE_TPH ? &cp->tcps[j2k->curtileno] : j2k->default_tcp; + opj_cio_t *cio = j2k->cio; + + old_poc = tcp->POC ? tcp->numpocs + 1 : 0; + tcp->POC = 1; + len = cio_read(cio, 2); /* Lpoc */ + numpchgs = (len - 2) / (5 + 2 * (numcomps <= 256 ? 1 : 2)); + + for (i = old_poc; i < numpchgs + old_poc; i++) { + opj_poc_t *poc; + poc = &tcp->pocs[i]; + poc->resno0 = cio_read(cio, 1); /* RSpoc_i */ + poc->compno0 = cio_read(cio, numcomps <= 256 ? 1 : 2); /* CSpoc_i */ + poc->layno1 = cio_read(cio, 2); /* LYEpoc_i */ + poc->resno1 = cio_read(cio, 1); /* REpoc_i */ + poc->compno1 = int_min( + cio_read(cio, numcomps <= 256 ? 1 : 2), (unsigned int) numcomps); /* CEpoc_i */ + poc->prg = (OPJ_PROG_ORDER)cio_read(cio, 1); /* Ppoc_i */ + } + + tcp->numpocs = numpchgs + old_poc - 1; +} + +static void j2k_read_crg(opj_j2k_t *j2k) { + int len, i, Xcrg_i, Ycrg_i; + + opj_cio_t *cio = j2k->cio; + int numcomps = j2k->image->numcomps; + + len = cio_read(cio, 2); /* Lcrg */ + for (i = 0; i < numcomps; i++) { + Xcrg_i = cio_read(cio, 2); /* Xcrg_i */ + Ycrg_i = cio_read(cio, 2); /* Ycrg_i */ + } +} + +static void j2k_read_tlm(opj_j2k_t *j2k) { + int len, Ztlm, Stlm, ST, SP, tile_tlm, i; + long int Ttlm_i, Ptlm_i; + + opj_cio_t *cio = j2k->cio; + + len = cio_read(cio, 2); /* Ltlm */ + Ztlm = cio_read(cio, 1); /* Ztlm */ + Stlm = cio_read(cio, 1); /* Stlm */ + ST = ((Stlm >> 4) & 0x01) + ((Stlm >> 4) & 0x02); + SP = (Stlm >> 6) & 0x01; + tile_tlm = (len - 4) / ((SP + 1) * 2 + ST); + for (i = 0; i < tile_tlm; i++) { + Ttlm_i = cio_read(cio, ST); /* Ttlm_i */ + Ptlm_i = cio_read(cio, SP ? 4 : 2); /* Ptlm_i */ + } +} + +static void j2k_read_plm(opj_j2k_t *j2k) { + int len, i, Zplm, Nplm, add, packet_len = 0; + + opj_cio_t *cio = j2k->cio; + + len = cio_read(cio, 2); /* Lplm */ + Zplm = cio_read(cio, 1); /* Zplm */ + len -= 3; + while (len > 0) { + Nplm = cio_read(cio, 4); /* Nplm */ + len -= 4; + for (i = Nplm; i > 0; i--) { + add = cio_read(cio, 1); + len--; + packet_len = (packet_len << 7) + add; /* Iplm_ij */ + if ((add & 0x80) == 0) { + /* New packet */ + packet_len = 0; + } + if (len <= 0) + break; + } + } +} + +static void j2k_read_plt(opj_j2k_t *j2k) { + int len, i, Zplt, packet_len = 0, add; + + opj_cio_t *cio = j2k->cio; + + len = cio_read(cio, 2); /* Lplt */ + Zplt = cio_read(cio, 1); /* Zplt */ + for (i = len - 3; i > 0; i--) { + add = cio_read(cio, 1); + packet_len = (packet_len << 7) + add; /* Iplt_i */ + if ((add & 0x80) == 0) { + /* New packet */ + packet_len = 0; + } + } +} + +static void j2k_read_ppm(opj_j2k_t *j2k) { + int len, Z_ppm, i, j; + int N_ppm; + + opj_cp_t *cp = j2k->cp; + opj_cio_t *cio = j2k->cio; + + len = cio_read(cio, 2); + cp->ppm = 1; + + Z_ppm = cio_read(cio, 1); /* Z_ppm */ + len -= 3; + while (len > 0) { + if (cp->ppm_previous == 0) { + N_ppm = cio_read(cio, 4); /* N_ppm */ + len -= 4; + } else { + N_ppm = cp->ppm_previous; + } + j = cp->ppm_store; + if (Z_ppm == 0) { /* First PPM marker */ + cp->ppm_data = (unsigned char *) opj_malloc(N_ppm * sizeof(unsigned char)); + cp->ppm_data_first = cp->ppm_data; + cp->ppm_len = N_ppm; + } else { /* NON-first PPM marker */ + cp->ppm_data = (unsigned char *) opj_realloc(cp->ppm_data, (N_ppm + cp->ppm_store) * sizeof(unsigned char)); + +#ifdef USE_JPWL + /* this memory allocation check could be done even in non-JPWL cases */ + if (cp->correct) { + if (!cp->ppm_data) { + opj_event_msg(j2k->cinfo, EVT_ERROR, + "JPWL: failed memory allocation during PPM marker parsing (pos. %x)\n", + cio_tell(cio)); + if (!JPWL_ASSUME || JPWL_ASSUME) { + opj_free(cp->ppm_data); + opj_event_msg(j2k->cinfo, EVT_ERROR, "JPWL: giving up\n"); + return; + } + } + } +#endif + + cp->ppm_data_first = cp->ppm_data; + cp->ppm_len = N_ppm + cp->ppm_store; + } + for (i = N_ppm; i > 0; i--) { /* Read packet header */ + cp->ppm_data[j] = cio_read(cio, 1); + j++; + len--; + if (len == 0) + break; /* Case of non-finished packet header in present marker but finished in next one */ + } + cp->ppm_previous = i - 1; + cp->ppm_store = j; + } +} + +static void j2k_read_ppt(opj_j2k_t *j2k) { + int len, Z_ppt, i, j = 0; + + opj_cp_t *cp = j2k->cp; + opj_tcp_t *tcp = cp->tcps + j2k->curtileno; + opj_cio_t *cio = j2k->cio; + + len = cio_read(cio, 2); + Z_ppt = cio_read(cio, 1); + tcp->ppt = 1; + if (Z_ppt == 0) { /* First PPT marker */ + tcp->ppt_data = (unsigned char *) opj_malloc((len - 3) * sizeof(unsigned char)); + tcp->ppt_data_first = tcp->ppt_data; + tcp->ppt_store = 0; + tcp->ppt_len = len - 3; + } else { /* NON-first PPT marker */ + tcp->ppt_data = (unsigned char *) opj_realloc(tcp->ppt_data, (len - 3 + tcp->ppt_store) * sizeof(unsigned char)); + tcp->ppt_data_first = tcp->ppt_data; + tcp->ppt_len = len - 3 + tcp->ppt_store; + } + j = tcp->ppt_store; + for (i = len - 3; i > 0; i--) { + tcp->ppt_data[j] = cio_read(cio, 1); + j++; + } + tcp->ppt_store = j; +} + +static void j2k_write_tlm(opj_j2k_t *j2k){ + int lenp; + opj_cio_t *cio = j2k->cio; + j2k->tlm_start = cio_tell(cio); + cio_write(cio, J2K_MS_TLM, 2);/* TLM */ + lenp = 4 + (5*j2k->totnum_tp); + cio_write(cio,lenp,2); /* Ltlm */ + cio_write(cio, 0,1); /* Ztlm=0*/ + cio_write(cio,80,1); /* Stlm ST=1(8bits-255 tiles max),SP=1(Ptlm=32bits) */ + cio_skip(cio,5*j2k->totnum_tp); +} + +static void j2k_write_sot(opj_j2k_t *j2k) { + int lenp, len; + + opj_cio_t *cio = j2k->cio; + + j2k->sot_start = cio_tell(cio); + cio_write(cio, J2K_MS_SOT, 2); /* SOT */ + lenp = cio_tell(cio); + cio_skip(cio, 2); /* Lsot (further) */ + cio_write(cio, j2k->curtileno, 2); /* Isot */ + cio_skip(cio, 4); /* Psot (further in j2k_write_sod) */ + cio_write(cio, j2k->cur_tp_num , 1); /* TPsot */ + cio_write(cio, j2k->cur_totnum_tp[j2k->curtileno], 1); /* TNsot */ + len = cio_tell(cio) - lenp; + cio_seek(cio, lenp); + cio_write(cio, len, 2); /* Lsot */ + cio_seek(cio, lenp + len); + + /* UniPG>> */ +#ifdef USE_JPWL + /* update markers struct */ + j2k_add_marker(j2k->cstr_info, J2K_MS_SOT, j2k->sot_start, len + 2); +#endif /* USE_JPWL */ + /* <cp; + opj_cio_t *cio = j2k->cio; + + len = cio_read(cio, 2); + tileno = cio_read(cio, 2); + +#ifdef USE_JPWL + if (j2k->cp->correct) { + + static int backup_tileno = 0; + + /* tileno is negative or larger than the number of tiles!!! */ + if ((tileno < 0) || (tileno > (cp->tw * cp->th))) { + opj_event_msg(j2k->cinfo, EVT_ERROR, + "JPWL: bad tile number (%d out of a maximum of %d)\n", + tileno, (cp->tw * cp->th)); + if (!JPWL_ASSUME) { + opj_event_msg(j2k->cinfo, EVT_ERROR, "JPWL: giving up\n"); + return; + } + /* we try to correct */ + tileno = backup_tileno; + opj_event_msg(j2k->cinfo, EVT_WARNING, "- trying to adjust this\n" + "- setting tile number to %d\n", + tileno); + } + + /* keep your private count of tiles */ + backup_tileno++; + }; +#endif /* USE_JPWL */ + + if (cp->tileno_size == 0) { + cp->tileno[cp->tileno_size] = tileno; + cp->tileno_size++; + } else { + i = 0; + while (i < cp->tileno_size && status == 0) { + status = cp->tileno[i] == tileno ? 1 : 0; + i++; + } + if (status == 0) { + cp->tileno[cp->tileno_size] = tileno; + cp->tileno_size++; + } + } + + totlen = cio_read(cio, 4); + +#ifdef USE_JPWL + if (j2k->cp->correct) { + + /* totlen is negative or larger than the bytes left!!! */ + if ((totlen < 0) || (totlen > (cio_numbytesleft(cio) + 8))) { + opj_event_msg(j2k->cinfo, EVT_ERROR, + "JPWL: bad tile byte size (%d bytes against %d bytes left)\n", + totlen, cio_numbytesleft(cio) + 8); + if (!JPWL_ASSUME) { + opj_event_msg(j2k->cinfo, EVT_ERROR, "JPWL: giving up\n"); + return; + } + /* we try to correct */ + totlen = 0; + opj_event_msg(j2k->cinfo, EVT_WARNING, "- trying to adjust this\n" + "- setting Psot to %d => assuming it is the last tile\n", + totlen); + } + + }; +#endif /* USE_JPWL */ + + if (!totlen) + totlen = cio_numbytesleft(cio) + 8; + + partno = cio_read(cio, 1); + numparts = cio_read(cio, 1); + + j2k->curtileno = tileno; + j2k->cur_tp_num = partno; + j2k->eot = cio_getbp(cio) - 12 + totlen; + j2k->state = J2K_STATE_TPH; + tcp = &cp->tcps[j2k->curtileno]; + + /* Index */ + if (j2k->cstr_info) { + if (tcp->first) { + if (tileno == 0) + j2k->cstr_info->main_head_end = cio_tell(cio) - 13; + j2k->cstr_info->tile[tileno].tileno = tileno; + j2k->cstr_info->tile[tileno].start_pos = cio_tell(cio) - 12; + j2k->cstr_info->tile[tileno].end_pos = j2k->cstr_info->tile[tileno].start_pos + totlen - 1; + j2k->cstr_info->tile[tileno].num_tps = numparts; + if (numparts) + j2k->cstr_info->tile[tileno].tp = (opj_tp_info_t *) opj_malloc(numparts * sizeof(opj_tp_info_t)); + else + j2k->cstr_info->tile[tileno].tp = (opj_tp_info_t *) opj_malloc(10 * sizeof(opj_tp_info_t)); // Fixme (10) + } + else { + j2k->cstr_info->tile[tileno].end_pos += totlen; + } + j2k->cstr_info->tile[tileno].tp[partno].tp_start_pos = cio_tell(cio) - 12; + j2k->cstr_info->tile[tileno].tp[partno].tp_end_pos = + j2k->cstr_info->tile[tileno].tp[partno].tp_start_pos + totlen - 1; + } + + if (tcp->first == 1) { + /* Initialization PPT */ + opj_tccp_t *tmp = tcp->tccps; + memcpy(tcp, j2k->default_tcp, sizeof(opj_tcp_t)); + tcp->ppt = 0; + tcp->ppt_data = NULL; + tcp->ppt_data_first = NULL; + tcp->tccps = tmp; + + for (i = 0; i < j2k->image->numcomps; i++) { + tcp->tccps[i] = j2k->default_tcp->tccps[i]; + } + cp->tcps[j2k->curtileno].first = 0; + } +} + +static void j2k_write_sod(opj_j2k_t *j2k, void *tile_coder) { + int l, layno; + int totlen; + opj_tcp_t *tcp = NULL; + opj_codestream_info_t *cstr_info = NULL; + + opj_tcd_t *tcd = (opj_tcd_t*)tile_coder; /* cast is needed because of conflicts in header inclusions */ + opj_cp_t *cp = j2k->cp; + opj_cio_t *cio = j2k->cio; + + tcd->tp_num = j2k->tp_num ; + tcd->cur_tp_num = j2k->cur_tp_num; + + cio_write(cio, J2K_MS_SOD, 2); + if (j2k->curtileno == 0) { + j2k->sod_start = cio_tell(cio) + j2k->pos_correction; + } + + /* INDEX >> */ + cstr_info = j2k->cstr_info; + if (cstr_info) { + if (!j2k->cur_tp_num ) { + cstr_info->tile[j2k->curtileno].end_header = cio_tell(cio) + j2k->pos_correction - 1; + j2k->cstr_info->tile[j2k->curtileno].tileno = j2k->curtileno; + } + else{ + if(cstr_info->tile[j2k->curtileno].packet[cstr_info->packno - 1].end_pos < cio_tell(cio)) + cstr_info->tile[j2k->curtileno].packet[cstr_info->packno].start_pos = cio_tell(cio); + } + /* UniPG>> */ +#ifdef USE_JPWL + /* update markers struct */ + j2k_add_marker(j2k->cstr_info, J2K_MS_SOD, j2k->sod_start, 2); +#endif /* USE_JPWL */ + /* <tcps[j2k->curtileno]; + for (layno = 0; layno < tcp->numlayers; layno++) { + tcp->rates[layno] -= tcp->rates[layno] ? (j2k->sod_start / (cp->th * cp->tw)) : 0; + } + if(j2k->cur_tp_num == 0){ + tcd->tcd_image->tiles->packno = 0; + if(cstr_info) + cstr_info->packno = 0; + } + + l = tcd_encode_tile(tcd, j2k->curtileno, cio_getbp(cio), cio_numbytesleft(cio) - 2, cstr_info); + + /* Writing Psot in SOT marker */ + totlen = cio_tell(cio) + l - j2k->sot_start; + cio_seek(cio, j2k->sot_start + 6); + cio_write(cio, totlen, 4); + cio_seek(cio, j2k->sot_start + totlen); + /* Writing Ttlm and Ptlm in TLM marker */ + if(cp->cinema){ + cio_seek(cio, j2k->tlm_start + 6 + (5*j2k->cur_tp_num)); + cio_write(cio, j2k->curtileno, 1); + cio_write(cio, totlen, 4); + } + cio_seek(cio, j2k->sot_start + totlen); +} + +static void j2k_read_sod(opj_j2k_t *j2k) { + int len, truncate = 0, i; + unsigned char *data = NULL, *data_ptr = NULL; + + opj_cio_t *cio = j2k->cio; + int curtileno = j2k->curtileno; + + /* Index */ + if (j2k->cstr_info) { + j2k->cstr_info->tile[j2k->curtileno].tp[j2k->cur_tp_num].tp_end_header = + cio_tell(cio) + j2k->pos_correction - 1; + if (j2k->cur_tp_num == 0) + j2k->cstr_info->tile[j2k->curtileno].end_header = cio_tell(cio) + j2k->pos_correction - 1; + j2k->cstr_info->packno = 0; + } + + len = int_min(j2k->eot - cio_getbp(cio), cio_numbytesleft(cio) + 1); + + if (len == cio_numbytesleft(cio) + 1) { + truncate = 1; /* Case of a truncate codestream */ + } + + data = j2k->tile_data[curtileno]; + data = (unsigned char*) opj_realloc(data, (j2k->tile_len[curtileno] + len) * sizeof(unsigned char)); + + data_ptr = data + j2k->tile_len[curtileno]; + for (i = 0; i < len; i++) { + data_ptr[i] = cio_read(cio, 1); + } + + j2k->tile_len[curtileno] += len; + j2k->tile_data[curtileno] = data; + + if (!truncate) { + j2k->state = J2K_STATE_TPHSOT; + } else { + j2k->state = J2K_STATE_NEOC; /* RAJOUTE !! */ + } + j2k->cur_tp_num++; +} + +static void j2k_write_rgn(opj_j2k_t *j2k, int compno, int tileno) { + opj_cp_t *cp = j2k->cp; + opj_tcp_t *tcp = &cp->tcps[tileno]; + opj_cio_t *cio = j2k->cio; + int numcomps = j2k->image->numcomps; + + cio_write(cio, J2K_MS_RGN, 2); /* RGN */ + cio_write(cio, numcomps <= 256 ? 5 : 6, 2); /* Lrgn */ + cio_write(cio, compno, numcomps <= 256 ? 1 : 2); /* Crgn */ + cio_write(cio, 0, 1); /* Srgn */ + cio_write(cio, tcp->tccps[compno].roishift, 1); /* SPrgn */ +} + +static void j2k_read_rgn(opj_j2k_t *j2k) { + int len, compno, roisty; + + opj_cp_t *cp = j2k->cp; + opj_tcp_t *tcp = j2k->state == J2K_STATE_TPH ? &cp->tcps[j2k->curtileno] : j2k->default_tcp; + opj_cio_t *cio = j2k->cio; + int numcomps = j2k->image->numcomps; + + len = cio_read(cio, 2); /* Lrgn */ + compno = cio_read(cio, numcomps <= 256 ? 1 : 2); /* Crgn */ + roisty = cio_read(cio, 1); /* Srgn */ + +#ifdef USE_JPWL + if (j2k->cp->correct) { + /* totlen is negative or larger than the bytes left!!! */ + if (compno >= numcomps) { + opj_event_msg(j2k->cinfo, EVT_ERROR, + "JPWL: bad component number in RGN (%d when there are only %d)\n", + compno, numcomps); + if (!JPWL_ASSUME || JPWL_ASSUME) { + opj_event_msg(j2k->cinfo, EVT_ERROR, "JPWL: giving up\n"); + return; + } + } + }; +#endif /* USE_JPWL */ + + tcp->tccps[compno].roishift = cio_read(cio, 1); /* SPrgn */ +} + +static void j2k_write_eoc(opj_j2k_t *j2k) { + opj_cio_t *cio = j2k->cio; + /* opj_event_msg(j2k->cinfo, "%.8x: EOC\n", cio_tell(cio) + j2k->pos_correction); */ + cio_write(cio, J2K_MS_EOC, 2); + +/* UniPG>> */ +#ifdef USE_JPWL + /* update markers struct */ + j2k_add_marker(j2k->cstr_info, J2K_MS_EOC, cio_tell(cio) - 2, 2); +#endif /* USE_JPWL */ +/* <cp->limit_decoding != DECODE_ALL_BUT_PACKETS) { + opj_tcd_t *tcd = tcd_create(j2k->cinfo); + tcd_malloc_decode(tcd, j2k->image, j2k->cp); + for (i = 0; i < j2k->cp->tileno_size; i++) { + tcd_malloc_decode_tile(tcd, j2k->image, j2k->cp, i, j2k->cstr_info); + tileno = j2k->cp->tileno[i]; + success = tcd_decode_tile(tcd, j2k->tile_data[tileno], j2k->tile_len[tileno], tileno, j2k->cstr_info); + opj_free(j2k->tile_data[tileno]); + j2k->tile_data[tileno] = NULL; + tcd_free_decode_tile(tcd, i); + if (success == false) { + j2k->state |= J2K_STATE_ERR; + break; + } + } + tcd_free_decode(tcd); + tcd_destroy(tcd); + } + /* if packets should not be decoded */ + else { + for (i = 0; i < j2k->cp->tileno_size; i++) { + tileno = j2k->cp->tileno[i]; + opj_free(j2k->tile_data[tileno]); + j2k->tile_data[tileno] = NULL; + } + } + if (j2k->state & J2K_STATE_ERR) + j2k->state = J2K_STATE_MT + J2K_STATE_ERR; + else + j2k->state = J2K_STATE_MT; +} + +typedef struct opj_dec_mstabent { + /** marker value */ + int id; + /** value of the state when the marker can appear */ + int states; + /** action linked to the marker */ + void (*handler) (opj_j2k_t *j2k); +} opj_dec_mstabent_t; + +opj_dec_mstabent_t j2k_dec_mstab[] = { + {J2K_MS_SOC, J2K_STATE_MHSOC, j2k_read_soc}, + {J2K_MS_SOT, J2K_STATE_MH | J2K_STATE_TPHSOT, j2k_read_sot}, + {J2K_MS_SOD, J2K_STATE_TPH, j2k_read_sod}, + {J2K_MS_EOC, J2K_STATE_TPHSOT, j2k_read_eoc}, + {J2K_MS_SIZ, J2K_STATE_MHSIZ, j2k_read_siz}, + {J2K_MS_COD, J2K_STATE_MH | J2K_STATE_TPH, j2k_read_cod}, + {J2K_MS_COC, J2K_STATE_MH | J2K_STATE_TPH, j2k_read_coc}, + {J2K_MS_RGN, J2K_STATE_MH | J2K_STATE_TPH, j2k_read_rgn}, + {J2K_MS_QCD, J2K_STATE_MH | J2K_STATE_TPH, j2k_read_qcd}, + {J2K_MS_QCC, J2K_STATE_MH | J2K_STATE_TPH, j2k_read_qcc}, + {J2K_MS_POC, J2K_STATE_MH | J2K_STATE_TPH, j2k_read_poc}, + {J2K_MS_TLM, J2K_STATE_MH, j2k_read_tlm}, + {J2K_MS_PLM, J2K_STATE_MH, j2k_read_plm}, + {J2K_MS_PLT, J2K_STATE_TPH, j2k_read_plt}, + {J2K_MS_PPM, J2K_STATE_MH, j2k_read_ppm}, + {J2K_MS_PPT, J2K_STATE_TPH, j2k_read_ppt}, + {J2K_MS_SOP, 0, 0}, + {J2K_MS_CRG, J2K_STATE_MH, j2k_read_crg}, + {J2K_MS_COM, J2K_STATE_MH | J2K_STATE_TPH, j2k_read_com}, + +#ifdef USE_JPWL + {J2K_MS_EPC, J2K_STATE_MH | J2K_STATE_TPH, j2k_read_epc}, + {J2K_MS_EPB, J2K_STATE_MH | J2K_STATE_TPH, j2k_read_epb}, + {J2K_MS_ESD, J2K_STATE_MH | J2K_STATE_TPH, j2k_read_esd}, + {J2K_MS_RED, J2K_STATE_MH | J2K_STATE_TPH, j2k_read_red}, +#endif /* USE_JPWL */ +#ifdef USE_JPSEC + {J2K_MS_SEC, J2K_STATE_MH, j2k_read_sec}, + {J2K_MS_INSEC, 0, j2k_read_insec}, +#endif /* USE_JPSEC */ + + {0, J2K_STATE_MH | J2K_STATE_TPH, j2k_read_unk} +}; + +static void j2k_read_unk(opj_j2k_t *j2k) { + opj_event_msg(j2k->cinfo, EVT_WARNING, "Unknown marker\n"); + +#ifdef USE_JPWL + if (j2k->cp->correct) { + int m = 0, id, i; + int min_id = 0, min_dist = 17, cur_dist = 0, tmp_id; + cio_seek(j2k->cio, cio_tell(j2k->cio) - 2); + id = cio_read(j2k->cio, 2); + opj_event_msg(j2k->cinfo, EVT_ERROR, + "JPWL: really don't know this marker %x\n", + id); + if (!JPWL_ASSUME) { + opj_event_msg(j2k->cinfo, EVT_ERROR, + "- possible synch loss due to uncorrectable codestream errors => giving up\n"); + return; + } + /* OK, activate this at your own risk!!! */ + /* we look for the marker at the minimum hamming distance from this */ + while (j2k_dec_mstab[m].id) { + + /* 1's where they differ */ + tmp_id = j2k_dec_mstab[m].id ^ id; + + /* compute the hamming distance between our id and the current */ + cur_dist = 0; + for (i = 0; i < 16; i++) { + if ((tmp_id >> i) & 0x0001) { + cur_dist++; + } + } + + /* if current distance is smaller, set the minimum */ + if (cur_dist < min_dist) { + min_dist = cur_dist; + min_id = j2k_dec_mstab[m].id; + } + + /* jump to the next marker */ + m++; + } + + /* do we substitute the marker? */ + if (min_dist < JPWL_MAXIMUM_HAMMING) { + opj_event_msg(j2k->cinfo, EVT_ERROR, + "- marker %x is at distance %d from the read %x\n", + min_id, min_dist, id); + opj_event_msg(j2k->cinfo, EVT_ERROR, + "- trying to substitute in place and crossing fingers!\n"); + cio_seek(j2k->cio, cio_tell(j2k->cio) - 2); + cio_write(j2k->cio, min_id, 2); + + /* rewind */ + cio_seek(j2k->cio, cio_tell(j2k->cio) - 2); + + } + + }; +#endif /* USE_JPWL */ + +} + +/** +Read the lookup table containing all the marker, status and action +@param id Marker value +*/ +static opj_dec_mstabent_t *j2k_dec_mstab_lookup(int id) { + opj_dec_mstabent_t *e; + for (e = j2k_dec_mstab; e->id != 0; e++) { + if (e->id == id) { + break; + } + } + return e; +} + +/* ----------------------------------------------------------------------- */ +/* J2K / JPT decoder interface */ +/* ----------------------------------------------------------------------- */ + +opj_j2k_t* j2k_create_decompress(opj_common_ptr cinfo) { + opj_j2k_t *j2k = (opj_j2k_t*) opj_calloc(1, sizeof(opj_j2k_t)); + if(!j2k) + return NULL; + + j2k->default_tcp = (opj_tcp_t*) opj_calloc(1, sizeof(opj_tcp_t)); + if(!j2k->default_tcp) { + opj_free(j2k); + return NULL; + } + + j2k->cinfo = cinfo; + j2k->tile_data = NULL; + + return j2k; +} + +void j2k_destroy_decompress(opj_j2k_t *j2k) { + int i = 0; + + if(j2k->tile_len != NULL) { + opj_free(j2k->tile_len); + } + if(j2k->tile_data != NULL) { + opj_free(j2k->tile_data); + } + if(j2k->default_tcp != NULL) { + opj_tcp_t *default_tcp = j2k->default_tcp; + if(default_tcp->ppt_data_first != NULL) { + opj_free(default_tcp->ppt_data_first); + } + if(j2k->default_tcp->tccps != NULL) { + opj_free(j2k->default_tcp->tccps); + } + opj_free(j2k->default_tcp); + } + if(j2k->cp != NULL) { + opj_cp_t *cp = j2k->cp; + if(cp->tcps != NULL) { + for(i = 0; i < cp->tw * cp->th; i++) { + if(cp->tcps[i].ppt_data_first != NULL) { + opj_free(cp->tcps[i].ppt_data_first); + } + if(cp->tcps[i].tccps != NULL) { + opj_free(cp->tcps[i].tccps); + } + } + opj_free(cp->tcps); + } + if(cp->ppm_data_first != NULL) { + opj_free(cp->ppm_data_first); + } + if(cp->tileno != NULL) { + opj_free(cp->tileno); + } + if(cp->comment != NULL) { + opj_free(cp->comment); + } + + opj_free(cp); + } + opj_free(j2k); +} + +void j2k_setup_decoder(opj_j2k_t *j2k, opj_dparameters_t *parameters) { + if(j2k && parameters) { + /* create and initialize the coding parameters structure */ + opj_cp_t *cp = (opj_cp_t*) opj_calloc(1, sizeof(opj_cp_t)); + cp->reduce = parameters->cp_reduce; + cp->layer = parameters->cp_layer; + cp->limit_decoding = parameters->cp_limit_decoding; + +#ifdef USE_JPWL + cp->correct = parameters->jpwl_correct; + cp->exp_comps = parameters->jpwl_exp_comps; + cp->max_tiles = parameters->jpwl_max_tiles; +#endif /* USE_JPWL */ + + + /* keep a link to cp so that we can destroy it later in j2k_destroy_decompress */ + j2k->cp = cp; + } +} + +opj_image_t* j2k_decode(opj_j2k_t *j2k, opj_cio_t *cio, opj_codestream_info_t *cstr_info) { + opj_image_t *image = NULL; + + opj_common_ptr cinfo = j2k->cinfo; + + j2k->cio = cio; + j2k->cstr_info = cstr_info; + if (cstr_info) + memset(cstr_info, 0, sizeof(opj_codestream_info_t)); + + /* create an empty image */ + image = opj_image_create0(); + j2k->image = image; + + j2k->state = J2K_STATE_MHSOC; + + for (;;) { + opj_dec_mstabent_t *e; + int id = cio_read(cio, 2); + +#ifdef USE_JPWL + /* we try to honor JPWL correction power */ + if (j2k->cp->correct) { + + int orig_pos = cio_tell(cio); + bool status; + + /* call the corrector */ + status = jpwl_correct(j2k); + + /* go back to where you were */ + cio_seek(cio, orig_pos - 2); + + /* re-read the marker */ + id = cio_read(cio, 2); + + /* check whether it begins with ff */ + if (id >> 8 != 0xff) { + opj_event_msg(cinfo, EVT_ERROR, + "JPWL: possible bad marker %x at %d\n", + id, cio_tell(cio) - 2); + if (!JPWL_ASSUME) { + opj_image_destroy(image); + opj_event_msg(cinfo, EVT_ERROR, "JPWL: giving up\n"); + return 0; + } + /* we try to correct */ + id = id | 0xff00; + cio_seek(cio, cio_tell(cio) - 2); + cio_write(cio, id, 2); + opj_event_msg(cinfo, EVT_WARNING, "- trying to adjust this\n" + "- setting marker to %x\n", + id); + } + + } +#endif /* USE_JPWL */ + + if (id >> 8 != 0xff) { + opj_image_destroy(image); + opj_event_msg(cinfo, EVT_ERROR, "%.8x: expected a marker instead of %x\n", cio_tell(cio) - 2, id); + return 0; + } + e = j2k_dec_mstab_lookup(id); + // Check if the marker is known + if (!(j2k->state & e->states)) { + opj_image_destroy(image); + opj_event_msg(cinfo, EVT_ERROR, "%.8x: unexpected marker %x\n", cio_tell(cio) - 2, id); + return 0; + } + // Check if the decoding is limited to the main header + if (e->id == J2K_MS_SOT && j2k->cp->limit_decoding == LIMIT_TO_MAIN_HEADER) { + opj_event_msg(cinfo, EVT_INFO, "Main Header decoded.\n"); + return image; + } + + if (e->handler) { + (*e->handler)(j2k); + } + if (j2k->state & J2K_STATE_ERR) + return NULL; + + if (j2k->state == J2K_STATE_MT) { + break; + } + if (j2k->state == J2K_STATE_NEOC) { + break; + } + } + if (j2k->state == J2K_STATE_NEOC) { + j2k_read_eoc(j2k); + } + + if (j2k->state != J2K_STATE_MT) { + opj_event_msg(cinfo, EVT_WARNING, "Incomplete bitstream\n"); + } + + return image; +} + +/* +* Read a JPT-stream and decode file +* +*/ +opj_image_t* j2k_decode_jpt_stream(opj_j2k_t *j2k, opj_cio_t *cio, opj_codestream_info_t *cstr_info) { + opj_image_t *image = NULL; + opj_jpt_msg_header_t header; + int position; + + opj_common_ptr cinfo = j2k->cinfo; + + j2k->cio = cio; + + /* create an empty image */ + image = opj_image_create0(); + j2k->image = image; + + j2k->state = J2K_STATE_MHSOC; + + /* Initialize the header */ + jpt_init_msg_header(&header); + /* Read the first header of the message */ + jpt_read_msg_header(cinfo, cio, &header); + + position = cio_tell(cio); + if (header.Class_Id != 6) { /* 6 : Main header data-bin message */ + opj_image_destroy(image); + opj_event_msg(cinfo, EVT_ERROR, "[JPT-stream] : Expecting Main header first [class_Id %d] !\n", header.Class_Id); + return 0; + } + + for (;;) { + opj_dec_mstabent_t *e = NULL; + int id; + + if (!cio_numbytesleft(cio)) { + j2k_read_eoc(j2k); + return image; + } + /* data-bin read -> need to read a new header */ + if ((unsigned int) (cio_tell(cio) - position) == header.Msg_length) { + jpt_read_msg_header(cinfo, cio, &header); + position = cio_tell(cio); + if (header.Class_Id != 4) { /* 4 : Tile data-bin message */ + opj_image_destroy(image); + opj_event_msg(cinfo, EVT_ERROR, "[JPT-stream] : Expecting Tile info !\n"); + return 0; + } + } + + id = cio_read(cio, 2); + if (id >> 8 != 0xff) { + opj_image_destroy(image); + opj_event_msg(cinfo, EVT_ERROR, "%.8x: expected a marker instead of %x\n", cio_tell(cio) - 2, id); + return 0; + } + e = j2k_dec_mstab_lookup(id); + if (!(j2k->state & e->states)) { + opj_image_destroy(image); + opj_event_msg(cinfo, EVT_ERROR, "%.8x: unexpected marker %x\n", cio_tell(cio) - 2, id); + return 0; + } + if (e->handler) { + (*e->handler)(j2k); + } + if (j2k->state == J2K_STATE_MT) { + break; + } + if (j2k->state == J2K_STATE_NEOC) { + break; + } + } + if (j2k->state == J2K_STATE_NEOC) { + j2k_read_eoc(j2k); + } + + if (j2k->state != J2K_STATE_MT) { + opj_event_msg(cinfo, EVT_WARNING, "Incomplete bitstream\n"); + } + + return image; +} + +/* ----------------------------------------------------------------------- */ +/* J2K encoder interface */ +/* ----------------------------------------------------------------------- */ + +opj_j2k_t* j2k_create_compress(opj_common_ptr cinfo) { + opj_j2k_t *j2k = (opj_j2k_t*) opj_calloc(1, sizeof(opj_j2k_t)); + if(j2k) { + j2k->cinfo = cinfo; + } + return j2k; +} + +void j2k_destroy_compress(opj_j2k_t *j2k) { + int tileno; + + if(!j2k) return; + if(j2k->cp != NULL) { + opj_cp_t *cp = j2k->cp; + + if(cp->comment) { + opj_free(cp->comment); + } + if(cp->matrice) { + opj_free(cp->matrice); + } + for (tileno = 0; tileno < cp->tw * cp->th; tileno++) { + opj_free(cp->tcps[tileno].tccps); + } + opj_free(cp->tcps); + opj_free(cp); + } + + opj_free(j2k); +} + +void j2k_setup_encoder(opj_j2k_t *j2k, opj_cparameters_t *parameters, opj_image_t *image) { + int i, j, tileno, numpocs_tile; + opj_cp_t *cp = NULL; + + if(!j2k || !parameters || ! image) { + return; + } + + /* create and initialize the coding parameters structure */ + cp = (opj_cp_t*) opj_calloc(1, sizeof(opj_cp_t)); + + /* keep a link to cp so that we can destroy it later in j2k_destroy_compress */ + j2k->cp = cp; + + /* set default values for cp */ + cp->tw = 1; + cp->th = 1; + + /* + copy user encoding parameters + */ + cp->cinema = parameters->cp_cinema; + cp->max_comp_size = parameters->max_comp_size; + cp->rsiz = parameters->cp_rsiz; + cp->disto_alloc = parameters->cp_disto_alloc; + cp->fixed_alloc = parameters->cp_fixed_alloc; + cp->fixed_quality = parameters->cp_fixed_quality; + + /* mod fixed_quality */ + if(parameters->cp_matrice) { + size_t array_size = parameters->tcp_numlayers * parameters->numresolution * 3 * sizeof(int); + cp->matrice = (int *) opj_malloc(array_size); + memcpy(cp->matrice, parameters->cp_matrice, array_size); + } + + /* tiles */ + cp->tdx = parameters->cp_tdx; + cp->tdy = parameters->cp_tdy; + + /* tile offset */ + cp->tx0 = parameters->cp_tx0; + cp->ty0 = parameters->cp_ty0; + + /* comment string */ + if(parameters->cp_comment) { + cp->comment = (char*)opj_malloc(strlen(parameters->cp_comment) + 1); + if(cp->comment) { + strcpy(cp->comment, parameters->cp_comment); + } + } + + /* + calculate other encoding parameters + */ + + if (parameters->tile_size_on) { + cp->tw = int_ceildiv(image->x1 - cp->tx0, cp->tdx); + cp->th = int_ceildiv(image->y1 - cp->ty0, cp->tdy); + } else { + cp->tdx = image->x1 - cp->tx0; + cp->tdy = image->y1 - cp->ty0; + } + + if(parameters->tp_on){ + cp->tp_flag = parameters->tp_flag; + cp->tp_on = 1; + } + + cp->img_size = 0; + for(i=0;inumcomps ;i++){ + cp->img_size += (image->comps[i].w *image->comps[i].h * image->comps[i].prec); + } + + +#ifdef USE_JPWL + /* + calculate JPWL encoding parameters + */ + + if (parameters->jpwl_epc_on) { + int i; + + /* set JPWL on */ + cp->epc_on = true; + cp->info_on = false; /* no informative technique */ + + /* set EPB on */ + if ((parameters->jpwl_hprot_MH > 0) || (parameters->jpwl_hprot_TPH[0] > 0)) { + cp->epb_on = true; + + cp->hprot_MH = parameters->jpwl_hprot_MH; + for (i = 0; i < JPWL_MAX_NO_TILESPECS; i++) { + cp->hprot_TPH_tileno[i] = parameters->jpwl_hprot_TPH_tileno[i]; + cp->hprot_TPH[i] = parameters->jpwl_hprot_TPH[i]; + } + /* if tile specs are not specified, copy MH specs */ + if (cp->hprot_TPH[0] == -1) { + cp->hprot_TPH_tileno[0] = 0; + cp->hprot_TPH[0] = parameters->jpwl_hprot_MH; + } + for (i = 0; i < JPWL_MAX_NO_PACKSPECS; i++) { + cp->pprot_tileno[i] = parameters->jpwl_pprot_tileno[i]; + cp->pprot_packno[i] = parameters->jpwl_pprot_packno[i]; + cp->pprot[i] = parameters->jpwl_pprot[i]; + } + } + + /* set ESD writing */ + if ((parameters->jpwl_sens_size == 1) || (parameters->jpwl_sens_size == 2)) { + cp->esd_on = true; + + cp->sens_size = parameters->jpwl_sens_size; + cp->sens_addr = parameters->jpwl_sens_addr; + cp->sens_range = parameters->jpwl_sens_range; + + cp->sens_MH = parameters->jpwl_sens_MH; + for (i = 0; i < JPWL_MAX_NO_TILESPECS; i++) { + cp->sens_TPH_tileno[i] = parameters->jpwl_sens_TPH_tileno[i]; + cp->sens_TPH[i] = parameters->jpwl_sens_TPH[i]; + } + } + + /* always set RED writing to false: we are at the encoder */ + cp->red_on = false; + + } else { + cp->epc_on = false; + } +#endif /* USE_JPWL */ + + + /* initialize the mutiple tiles */ + /* ---------------------------- */ + cp->tcps = (opj_tcp_t*) opj_calloc(cp->tw * cp->th, sizeof(opj_tcp_t)); + + for (tileno = 0; tileno < cp->tw * cp->th; tileno++) { + opj_tcp_t *tcp = &cp->tcps[tileno]; + tcp->numlayers = parameters->tcp_numlayers; + for (j = 0; j < tcp->numlayers; j++) { + if(cp->cinema){ + if (cp->fixed_quality) { + tcp->distoratio[j] = parameters->tcp_distoratio[j]; + } + tcp->rates[j] = parameters->tcp_rates[j]; + }else{ + if (cp->fixed_quality) { /* add fixed_quality */ + tcp->distoratio[j] = parameters->tcp_distoratio[j]; + } else { + tcp->rates[j] = parameters->tcp_rates[j]; + } + } + } + tcp->csty = parameters->csty; + tcp->prg = parameters->prog_order; + tcp->mct = parameters->tcp_mct; + + numpocs_tile = 0; + tcp->POC = 0; + if (parameters->numpocs) { + /* initialisation of POC */ + tcp->POC = 1; + for (i = 0; i < parameters->numpocs; i++) { + if((tileno == parameters->POC[i].tile - 1) || (parameters->POC[i].tile == -1)) { + opj_poc_t *tcp_poc = &tcp->pocs[numpocs_tile]; + tcp_poc->resno0 = parameters->POC[numpocs_tile].resno0; + tcp_poc->compno0 = parameters->POC[numpocs_tile].compno0; + tcp_poc->layno1 = parameters->POC[numpocs_tile].layno1; + tcp_poc->resno1 = parameters->POC[numpocs_tile].resno1; + tcp_poc->compno1 = parameters->POC[numpocs_tile].compno1; + tcp_poc->prg1 = parameters->POC[numpocs_tile].prg1; + tcp_poc->tile = parameters->POC[numpocs_tile].tile; + numpocs_tile++; + } + } + tcp->numpocs = numpocs_tile -1 ; + }else{ + tcp->numpocs = 0; + } + + tcp->tccps = (opj_tccp_t*) opj_calloc(image->numcomps, sizeof(opj_tccp_t)); + + for (i = 0; i < image->numcomps; i++) { + opj_tccp_t *tccp = &tcp->tccps[i]; + tccp->csty = parameters->csty & 0x01; /* 0 => one precinct || 1 => custom precinct */ + tccp->numresolutions = parameters->numresolution; + tccp->cblkw = int_floorlog2(parameters->cblockw_init); + tccp->cblkh = int_floorlog2(parameters->cblockh_init); + tccp->cblksty = parameters->mode; + tccp->qmfbid = parameters->irreversible ? 0 : 1; + tccp->qntsty = parameters->irreversible ? J2K_CCP_QNTSTY_SEQNT : J2K_CCP_QNTSTY_NOQNT; + tccp->numgbits = 2; + if (i == parameters->roi_compno) { + tccp->roishift = parameters->roi_shift; + } else { + tccp->roishift = 0; + } + + if(parameters->cp_cinema) + { + //Precinct size for lowest frequency subband=128 + tccp->prcw[0] = 7; + tccp->prch[0] = 7; + //Precinct size at all other resolutions = 256 + for (j = 1; j < tccp->numresolutions; j++) { + tccp->prcw[j] = 8; + tccp->prch[j] = 8; + } + }else{ + if (parameters->csty & J2K_CCP_CSTY_PRT) { + int p = 0; + for (j = tccp->numresolutions - 1; j >= 0; j--) { + if (p < parameters->res_spec) { + + if (parameters->prcw_init[p] < 1) { + tccp->prcw[j] = 1; + } else { + tccp->prcw[j] = int_floorlog2(parameters->prcw_init[p]); + } + + if (parameters->prch_init[p] < 1) { + tccp->prch[j] = 1; + }else { + tccp->prch[j] = int_floorlog2(parameters->prch_init[p]); + } + + } else { + int res_spec = parameters->res_spec; + int size_prcw = parameters->prcw_init[res_spec - 1] >> (p - (res_spec - 1)); + int size_prch = parameters->prch_init[res_spec - 1] >> (p - (res_spec - 1)); + + if (size_prcw < 1) { + tccp->prcw[j] = 1; + } else { + tccp->prcw[j] = int_floorlog2(size_prcw); + } + + if (size_prch < 1) { + tccp->prch[j] = 1; + } else { + tccp->prch[j] = int_floorlog2(size_prch); + } + } + p++; + /*printf("\nsize precinct for level %d : %d,%d\n", j,tccp->prcw[j], tccp->prch[j]); */ + } //end for + } else { + for (j = 0; j < tccp->numresolutions; j++) { + tccp->prcw[j] = 15; + tccp->prch[j] = 15; + } + } + } + + dwt_calc_explicit_stepsizes(tccp, image->comps[i].prec); + } + } +} + +bool j2k_encode(opj_j2k_t *j2k, opj_cio_t *cio, opj_image_t *image, opj_codestream_info_t *cstr_info) { + int tileno, compno; + opj_cp_t *cp = NULL; + + opj_tcd_t *tcd = NULL; /* TCD component */ + + j2k->cio = cio; + j2k->image = image; + + cp = j2k->cp; + + /* j2k_dump_cp(stdout, image, cp); */ + + /* INDEX >> */ + j2k->cstr_info = cstr_info; + if (cstr_info) { + int compno; + cstr_info->tile = (opj_tile_info_t *) opj_malloc(cp->tw * cp->th * sizeof(opj_tile_info_t)); + cstr_info->image_w = image->x1 - image->x0; + cstr_info->image_h = image->y1 - image->y0; + cstr_info->prog = (&cp->tcps[0])->prg; + cstr_info->tw = cp->tw; + cstr_info->th = cp->th; + cstr_info->tile_x = cp->tdx; /* new version parser */ + cstr_info->tile_y = cp->tdy; /* new version parser */ + cstr_info->tile_Ox = cp->tx0; /* new version parser */ + cstr_info->tile_Oy = cp->ty0; /* new version parser */ + cstr_info->numcomps = image->numcomps; + cstr_info->numlayers = (&cp->tcps[0])->numlayers; + cstr_info->numdecompos = (int*) opj_malloc(image->numcomps * sizeof(int)); + for (compno=0; compno < image->numcomps; compno++) { + cstr_info->numdecompos[compno] = (&cp->tcps[0])->tccps->numresolutions - 1; + } + cstr_info->D_max = 0.0; /* ADD Marcela */ + cstr_info->main_head_start = cio_tell(cio); /* position of SOC */ + cstr_info->maxmarknum = 100; + cstr_info->marker = (opj_marker_info_t *) opj_malloc(cstr_info->maxmarknum * sizeof(opj_marker_info_t)); + cstr_info->marknum = 0; + } + /* << INDEX */ + + j2k_write_soc(j2k); + j2k_write_siz(j2k); + j2k_write_cod(j2k); + j2k_write_qcd(j2k); + + if(cp->cinema){ + for (compno = 1; compno < image->numcomps; compno++) { + j2k_write_coc(j2k, compno); + j2k_write_qcc(j2k, compno); + } + } + + for (compno = 0; compno < image->numcomps; compno++) { + opj_tcp_t *tcp = &cp->tcps[0]; + if (tcp->tccps[compno].roishift) + j2k_write_rgn(j2k, compno, 0); + } + if (cp->comment != NULL) { + j2k_write_com(j2k); + } + + j2k->totnum_tp = j2k_calculate_tp(cp,image->numcomps,image,j2k); + /* TLM Marker*/ + if(cp->cinema){ + j2k_write_tlm(j2k); + if (cp->cinema == CINEMA4K_24) { + j2k_write_poc(j2k); + } + } + + /* uncomment only for testing JPSEC marker writing */ + /* j2k_write_sec(j2k); */ + + /* INDEX >> */ + if(cstr_info) { + cstr_info->main_head_end = cio_tell(cio) - 1; + } + /* << INDEX */ + /**** Main Header ENDS here ***/ + + /* create the tile encoder */ + tcd = tcd_create(j2k->cinfo); + + /* encode each tile */ + for (tileno = 0; tileno < cp->tw * cp->th; tileno++) { + int pino; + int tilepartno=0; + /* UniPG>> */ + int acc_pack_num = 0; + /* <tcps[tileno]; + opj_event_msg(j2k->cinfo, EVT_INFO, "tile number %d / %d\n", tileno + 1, cp->tw * cp->th); + + j2k->curtileno = tileno; + j2k->cur_tp_num = 0; + tcd->cur_totnum_tp = j2k->cur_totnum_tp[j2k->curtileno]; + /* initialisation before tile encoding */ + if (tileno == 0) { + tcd_malloc_encode(tcd, image, cp, j2k->curtileno); + } else { + tcd_init_encode(tcd, image, cp, j2k->curtileno); + } + + /* INDEX >> */ + if(cstr_info) { + cstr_info->tile[j2k->curtileno].start_pos = cio_tell(cio) + j2k->pos_correction; + } + /* << INDEX */ + + for(pino = 0; pino <= tcp->numpocs; pino++) { + int tot_num_tp; + tcd->cur_pino=pino; + + /*Get number of tile parts*/ + tot_num_tp = j2k_get_num_tp(cp,pino,tileno); + tcd->tp_pos = cp->tp_pos; + + for(tilepartno = 0; tilepartno < tot_num_tp ; tilepartno++){ + j2k->tp_num = tilepartno; + /* INDEX >> */ + if(cstr_info) + cstr_info->tile[j2k->curtileno].tp[j2k->cur_tp_num].tp_start_pos = + cio_tell(cio) + j2k->pos_correction; + /* << INDEX */ + j2k_write_sot(j2k); + + if(j2k->cur_tp_num == 0 && cp->cinema == 0){ + for (compno = 1; compno < image->numcomps; compno++) { + j2k_write_coc(j2k, compno); + j2k_write_qcc(j2k, compno); + } + if (cp->tcps[tileno].numpocs) { + j2k_write_poc(j2k); + } + } + + /* INDEX >> */ + if(cstr_info) + cstr_info->tile[j2k->curtileno].tp[j2k->cur_tp_num].tp_end_header = + cio_tell(cio) + j2k->pos_correction + 1; + /* << INDEX */ + + j2k_write_sod(j2k, tcd); + + /* INDEX >> */ + if(cstr_info) { + cstr_info->tile[j2k->curtileno].tp[j2k->cur_tp_num].tp_end_pos = + cio_tell(cio) + j2k->pos_correction - 1; + cstr_info->tile[j2k->curtileno].tp[j2k->cur_tp_num].tp_start_pack = + acc_pack_num; + cstr_info->tile[j2k->curtileno].tp[j2k->cur_tp_num].tp_numpacks = + cstr_info->packno - acc_pack_num; + acc_pack_num = cstr_info->packno; + } + /* << INDEX */ + + j2k->cur_tp_num++; + } + } + if(cstr_info) { + cstr_info->tile[j2k->curtileno].end_pos = cio_tell(cio) + j2k->pos_correction - 1; + } + + + /* + if (tile->PPT) { // BAD PPT !!! + FILE *PPT_file; + int i; + PPT_file=fopen("PPT","rb"); + fprintf(stderr,"%c%c%c%c",255,97,tile->len_ppt/256,tile->len_ppt%256); + for (i=0;ilen_ppt;i++) { + unsigned char elmt; + fread(&elmt, 1, 1, PPT_file); + fwrite(&elmt,1,1,f); + } + fclose(PPT_file); + unlink("PPT"); + } + */ + + } + + /* destroy the tile encoder */ + tcd_free_encode(tcd); + tcd_destroy(tcd); + + opj_free(j2k->cur_totnum_tp); + + j2k_write_eoc(j2k); + + if(cstr_info) { + cstr_info->codestream_size = cio_tell(cio) + j2k->pos_correction; + /* UniPG>> */ + /* The following adjustment is done to adjust the codestream size */ + /* if SOD is not at 0 in the buffer. Useful in case of JP2, where */ + /* the first bunch of bytes is not in the codestream */ + cstr_info->codestream_size -= cstr_info->main_head_start; + /* <epc_on) { + + /* encode according to JPWL */ + jpwl_encode(j2k, cio, image); + + } +#endif /* USE_JPWL */ + + return true; +} + + + + + + diff --git a/extern/libopenjpeg/j2k.h b/extern/libopenjpeg/j2k.h new file mode 100644 index 00000000000..5599be47a8d --- /dev/null +++ b/extern/libopenjpeg/j2k.h @@ -0,0 +1,446 @@ +/* + * Copyright (c) 2002-2007, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium + * Copyright (c) 2002-2007, Professor Benoit Macq + * Copyright (c) 2001-2003, David Janssens + * Copyright (c) 2002-2003, Yannick Verschueren + * Copyright (c) 2003-2007, Francois-Olivier Devaux and Antonin Descampe + * Copyright (c) 2005, Herve Drolon, FreeImage Team + * Copyright (c) 2006-2007, Parvatha Elangovan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 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. + */ +#ifndef __J2K_H +#define __J2K_H +/** +@file j2k.h +@brief The JPEG-2000 Codestream Reader/Writer (J2K) + +The functions in J2K.C have for goal to read/write the several parts of the codestream: markers and data. +*/ + +/** @defgroup J2K J2K - JPEG-2000 codestream reader/writer */ +/*@{*/ + +#define J2K_CP_CSTY_PRT 0x01 +#define J2K_CP_CSTY_SOP 0x02 +#define J2K_CP_CSTY_EPH 0x04 +#define J2K_CCP_CSTY_PRT 0x01 +#define J2K_CCP_CBLKSTY_LAZY 0x01 +#define J2K_CCP_CBLKSTY_RESET 0x02 +#define J2K_CCP_CBLKSTY_TERMALL 0x04 +#define J2K_CCP_CBLKSTY_VSC 0x08 +#define J2K_CCP_CBLKSTY_PTERM 0x10 +#define J2K_CCP_CBLKSTY_SEGSYM 0x20 +#define J2K_CCP_QNTSTY_NOQNT 0 +#define J2K_CCP_QNTSTY_SIQNT 1 +#define J2K_CCP_QNTSTY_SEQNT 2 + +/* ----------------------------------------------------------------------- */ + +#define J2K_MS_SOC 0xff4f /**< SOC marker value */ +#define J2K_MS_SOT 0xff90 /**< SOT marker value */ +#define J2K_MS_SOD 0xff93 /**< SOD marker value */ +#define J2K_MS_EOC 0xffd9 /**< EOC marker value */ +#define J2K_MS_SIZ 0xff51 /**< SIZ marker value */ +#define J2K_MS_COD 0xff52 /**< COD marker value */ +#define J2K_MS_COC 0xff53 /**< COC marker value */ +#define J2K_MS_RGN 0xff5e /**< RGN marker value */ +#define J2K_MS_QCD 0xff5c /**< QCD marker value */ +#define J2K_MS_QCC 0xff5d /**< QCC marker value */ +#define J2K_MS_POC 0xff5f /**< POC marker value */ +#define J2K_MS_TLM 0xff55 /**< TLM marker value */ +#define J2K_MS_PLM 0xff57 /**< PLM marker value */ +#define J2K_MS_PLT 0xff58 /**< PLT marker value */ +#define J2K_MS_PPM 0xff60 /**< PPM marker value */ +#define J2K_MS_PPT 0xff61 /**< PPT marker value */ +#define J2K_MS_SOP 0xff91 /**< SOP marker value */ +#define J2K_MS_EPH 0xff92 /**< EPH marker value */ +#define J2K_MS_CRG 0xff63 /**< CRG marker value */ +#define J2K_MS_COM 0xff64 /**< COM marker value */ +/* UniPG>> */ +#ifdef USE_JPWL +#define J2K_MS_EPC 0xff68 /**< EPC marker value (Part 11: JPEG 2000 for Wireless) */ +#define J2K_MS_EPB 0xff66 /**< EPB marker value (Part 11: JPEG 2000 for Wireless) */ +#define J2K_MS_ESD 0xff67 /**< ESD marker value (Part 11: JPEG 2000 for Wireless) */ +#define J2K_MS_RED 0xff69 /**< RED marker value (Part 11: JPEG 2000 for Wireless) */ +#endif /* USE_JPWL */ +#ifdef USE_JPSEC +#define J2K_MS_SEC 0xff65 /**< SEC marker value (Part 8: Secure JPEG 2000) */ +#define J2K_MS_INSEC 0xff94 /**< INSEC marker value (Part 8: Secure JPEG 2000) */ +#endif /* USE_JPSEC */ +/* < there was a PPT marker for the present tile */ + int ppt; + /** used in case of multiple marker PPT (number of info already stored) */ + int ppt_store; + /** ppmbug1 */ + int ppt_len; + /** add fixed_quality */ + float distoratio[100]; + /** tile-component coding parameters */ + opj_tccp_t *tccps; +} opj_tcp_t; + +/** +Coding parameters +*/ +typedef struct opj_cp { + /** Digital cinema profile*/ + OPJ_CINEMA_MODE cinema; + /** Maximum rate for each component. If == 0, component size limitation is not considered */ + int max_comp_size; + /** Size of the image in bits*/ + int img_size; + /** Rsiz*/ + OPJ_RSIZ_CAPABILITIES rsiz; + /** Enabling Tile part generation*/ + char tp_on; + /** Flag determining tile part generation*/ + char tp_flag; + /** Position of tile part flag in progression order*/ + int tp_pos; + /** allocation by rate/distortion */ + int disto_alloc; + /** allocation by fixed layer */ + int fixed_alloc; + /** add fixed_quality */ + int fixed_quality; + /** if != 0, then original dimension divided by 2^(reduce); if == 0 or not used, image is decoded to the full resolution */ + int reduce; + /** if != 0, then only the first "layer" layers are decoded; if == 0 or not used, all the quality layers are decoded */ + int layer; + /** if == NO_LIMITATION, decode entire codestream; if == LIMIT_TO_MAIN_HEADER then only decode the main header */ + OPJ_LIMIT_DECODING limit_decoding; + /** XTOsiz */ + int tx0; + /** YTOsiz */ + int ty0; + /** XTsiz */ + int tdx; + /** YTsiz */ + int tdy; + /** comment for coding */ + char *comment; + /** number of tiles in width */ + int tw; + /** number of tiles in heigth */ + int th; + /** ID number of the tiles present in the codestream */ + int *tileno; + /** size of the vector tileno */ + int tileno_size; + /** packet header store there for futur use in t2_decode_packet */ + unsigned char *ppm_data; + /** pointer remaining on the first byte of the first header if ppm is used */ + unsigned char *ppm_data_first; + /** if ppm == 1 --> there was a PPM marker for the present tile */ + int ppm; + /** use in case of multiple marker PPM (number of info already store) */ + int ppm_store; + /** use in case of multiple marker PPM (case on non-finished previous info) */ + int ppm_previous; + /** ppmbug1 */ + int ppm_len; + /** tile coding parameters */ + opj_tcp_t *tcps; + /** fixed layer */ + int *matrice; +/* UniPG>> */ +#ifdef USE_JPWL + /** enables writing of EPC in MH, thus activating JPWL */ + bool epc_on; + /** enables writing of EPB, in case of activated JPWL */ + bool epb_on; + /** enables writing of ESD, in case of activated JPWL */ + bool esd_on; + /** enables writing of informative techniques of ESD, in case of activated JPWL */ + bool info_on; + /** enables writing of RED, in case of activated JPWL */ + bool red_on; + /** error protection method for MH (0,1,16,32,37-128) */ + int hprot_MH; + /** tile number of header protection specification (>=0) */ + int hprot_TPH_tileno[JPWL_MAX_NO_TILESPECS]; + /** error protection methods for TPHs (0,1,16,32,37-128) */ + int hprot_TPH[JPWL_MAX_NO_TILESPECS]; + /** tile number of packet protection specification (>=0) */ + int pprot_tileno[JPWL_MAX_NO_PACKSPECS]; + /** packet number of packet protection specification (>=0) */ + int pprot_packno[JPWL_MAX_NO_PACKSPECS]; + /** error protection methods for packets (0,1,16,32,37-128) */ + int pprot[JPWL_MAX_NO_PACKSPECS]; + /** enables writing of ESD, (0/2/4 bytes) */ + int sens_size; + /** sensitivity addressing size (0=auto/2/4 bytes) */ + int sens_addr; + /** sensitivity range (0-3) */ + int sens_range; + /** sensitivity method for MH (-1,0-7) */ + int sens_MH; + /** tile number of sensitivity specification (>=0) */ + int sens_TPH_tileno[JPWL_MAX_NO_TILESPECS]; + /** sensitivity methods for TPHs (-1,0-7) */ + int sens_TPH[JPWL_MAX_NO_TILESPECS]; + /** enables JPWL correction at the decoder */ + bool correct; + /** expected number of components at the decoder */ + int exp_comps; + /** maximum number of tiles at the decoder */ + int max_tiles; +#endif /* USE_JPWL */ +/* <cp. +@param j2k J2K decompressor handle +@param parameters decompression parameters +*/ +void j2k_setup_decoder(opj_j2k_t *j2k, opj_dparameters_t *parameters); +/** +Decode an image from a JPEG-2000 codestream +@param j2k J2K decompressor handle +@param cio Input buffer stream +@param cstr_info Codestream information structure if required, NULL otherwise +@return Returns a decoded image if successful, returns NULL otherwise +*/ +opj_image_t* j2k_decode(opj_j2k_t *j2k, opj_cio_t *cio, opj_codestream_info_t *cstr_info); +/** +Decode an image form a JPT-stream (JPEG 2000, JPIP) +@param j2k J2K decompressor handle +@param cio Input buffer stream +@param cstr_info Codestream information structure if required, NULL otherwise +@return Returns a decoded image if successful, returns NULL otherwise +*/ +opj_image_t* j2k_decode_jpt_stream(opj_j2k_t *j2k, opj_cio_t *cio, opj_codestream_info_t *cstr_info); +/** +Creates a J2K compression structure +@param cinfo Codec context info +@return Returns a handle to a J2K compressor if successful, returns NULL otherwise +*/ +opj_j2k_t* j2k_create_compress(opj_common_ptr cinfo); +/** +Destroy a J2K compressor handle +@param j2k J2K compressor handle to destroy +*/ +void j2k_destroy_compress(opj_j2k_t *j2k); +/** +Setup the encoder parameters using the current image and using user parameters. +Coding parameters are returned in j2k->cp. +@param j2k J2K compressor handle +@param parameters compression parameters +@param image input filled image +*/ +void j2k_setup_encoder(opj_j2k_t *j2k, opj_cparameters_t *parameters, opj_image_t *image); +/** +Converts an enum type progression order to string type +*/ +char *j2k_convert_progression_order(OPJ_PROG_ORDER prg_order); +/** +Encode an image into a JPEG-2000 codestream +@param j2k J2K compressor handle +@param cio Output buffer stream +@param image Image to encode +@param cstr_info Codestream information structure if required, NULL otherwise +@return Returns true if successful, returns false otherwise +*/ +bool j2k_encode(opj_j2k_t *j2k, opj_cio_t *cio, opj_image_t *image, opj_codestream_info_t *cstr_info); + +/* ----------------------------------------------------------------------- */ +/*@}*/ + +/*@}*/ + +#endif /* __J2K_H */ diff --git a/extern/libopenjpeg/j2k_lib.c b/extern/libopenjpeg/j2k_lib.c new file mode 100644 index 00000000000..91aee007152 --- /dev/null +++ b/extern/libopenjpeg/j2k_lib.c @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2005, Hervé Drolon, FreeImage Team + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 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. + */ + +#ifdef WIN32 +#include +#else +#include +#include +#include +#endif /* WIN32 */ +#include "opj_includes.h" + +double opj_clock(void) { +#ifdef WIN32 + /* WIN32: use QueryPerformance (very accurate) */ + LARGE_INTEGER freq , t ; + /* freq is the clock speed of the CPU */ + QueryPerformanceFrequency(&freq) ; + /* cout << "freq = " << ((double) freq.QuadPart) << endl; */ + /* t is the high resolution performance counter (see MSDN) */ + QueryPerformanceCounter ( & t ) ; + return ( t.QuadPart /(double) freq.QuadPart ) ; +#else + /* Unix or Linux: use resource usage */ + struct rusage t; + double procTime; + /* (1) Get the rusage data structure at this moment (man getrusage) */ + getrusage(0,&t); + /* (2) What is the elapsed time ? - CPU time = User time + System time */ + /* (2a) Get the seconds */ + procTime = t.ru_utime.tv_sec + t.ru_stime.tv_sec; + /* (2b) More precisely! Get the microseconds part ! */ + return ( procTime + (t.ru_utime.tv_usec + t.ru_stime.tv_usec) * 1e-6 ) ; +#endif +} + diff --git a/extern/libopenjpeg/j2k_lib.h b/extern/libopenjpeg/j2k_lib.h new file mode 100644 index 00000000000..7df4d367757 --- /dev/null +++ b/extern/libopenjpeg/j2k_lib.h @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2005, Hervé Drolon, FreeImage Team + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 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. + */ +#ifndef __J2K_LIB_H +#define __J2K_LIB_H +/** +@file j2k_lib.h +@brief Internal functions + +The functions in J2K_LIB.C are internal utilities mainly used for timing. +*/ + +/** @defgroup MISC MISC - Miscellaneous internal functions */ +/*@{*/ + +/** @name Exported functions */ +/*@{*/ +/* ----------------------------------------------------------------------- */ + +/** +Difference in successive opj_clock() calls tells you the elapsed time +@return Returns time in seconds +*/ +double opj_clock(void); + +/* ----------------------------------------------------------------------- */ +/*@}*/ + +/*@}*/ + +#endif /* __J2K_LIB_H */ + diff --git a/extern/libopenjpeg/jp2.c b/extern/libopenjpeg/jp2.c new file mode 100644 index 00000000000..14f9493c401 --- /dev/null +++ b/extern/libopenjpeg/jp2.c @@ -0,0 +1,710 @@ +/* + * Copyright (c) 2002-2007, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium + * Copyright (c) 2002-2007, Professor Benoit Macq + * Copyright (c) 2001-2003, David Janssens + * Copyright (c) 2002-2003, Yannick Verschueren + * Copyright (c) 2003-2007, Francois-Olivier Devaux and Antonin Descampe + * Copyright (c) 2005, Herve Drolon, FreeImage Team + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 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. + */ + +#include "opj_includes.h" + +/** @defgroup JP2 JP2 - JPEG-2000 file format reader/writer */ +/*@{*/ + +/** @name Local static functions */ +/*@{*/ + +/** +Read box headers +@param cinfo Codec context info +@param cio Input stream +@param box +@return Returns true if successful, returns false otherwise +*/ +static bool jp2_read_boxhdr(opj_common_ptr cinfo, opj_cio_t *cio, opj_jp2_box_t *box); +/*static void jp2_write_url(opj_cio_t *cio, char *Idx_file);*/ +/** +Read the IHDR box - Image Header box +@param jp2 JP2 handle +@param cio Input buffer stream +@return Returns true if successful, returns false otherwise +*/ +static bool jp2_read_ihdr(opj_jp2_t *jp2, opj_cio_t *cio); +static void jp2_write_ihdr(opj_jp2_t *jp2, opj_cio_t *cio); +static void jp2_write_bpcc(opj_jp2_t *jp2, opj_cio_t *cio); +static bool jp2_read_bpcc(opj_jp2_t *jp2, opj_cio_t *cio); +static void jp2_write_colr(opj_jp2_t *jp2, opj_cio_t *cio); +static bool jp2_read_colr(opj_jp2_t *jp2, opj_cio_t *cio); +/** +Write the FTYP box - File type box +@param jp2 JP2 handle +@param cio Output buffer stream +*/ +static void jp2_write_ftyp(opj_jp2_t *jp2, opj_cio_t *cio); +/** +Read the FTYP box - File type box +@param jp2 JP2 handle +@param cio Input buffer stream +@return Returns true if successful, returns false otherwise +*/ +static bool jp2_read_ftyp(opj_jp2_t *jp2, opj_cio_t *cio); +static int jp2_write_jp2c(opj_jp2_t *jp2, opj_cio_t *cio, opj_image_t *image, opj_codestream_info_t *cstr_info); +static bool jp2_read_jp2c(opj_jp2_t *jp2, opj_cio_t *cio, unsigned int *j2k_codestream_length, unsigned int *j2k_codestream_offset); +static void jp2_write_jp(opj_cio_t *cio); +/** +Read the JP box - JPEG 2000 signature +@param jp2 JP2 handle +@param cio Input buffer stream +@return Returns true if successful, returns false otherwise +*/ +static bool jp2_read_jp(opj_jp2_t *jp2, opj_cio_t *cio); +/** +Decode the structure of a JP2 file +@param jp2 JP2 handle +@param cio Input buffer stream +@return Returns true if successful, returns false otherwise +*/ +static bool jp2_read_struct(opj_jp2_t *jp2, opj_cio_t *cio); + +/*@}*/ + +/*@}*/ + +/* ----------------------------------------------------------------------- */ + +static bool jp2_read_boxhdr(opj_common_ptr cinfo, opj_cio_t *cio, opj_jp2_box_t *box) { + box->init_pos = cio_tell(cio); + box->length = cio_read(cio, 4); + box->type = cio_read(cio, 4); + if (box->length == 1) { + if (cio_read(cio, 4) != 0) { + opj_event_msg(cinfo, EVT_ERROR, "Cannot handle box sizes higher than 2^32\n"); + return false; + } + box->length = cio_read(cio, 4); + if (box->length == 0) + box->length = cio_numbytesleft(cio) + 12; + } + else if (box->length == 0) { + box->length = cio_numbytesleft(cio) + 8; + } + + return true; +} + +#if 0 +static void jp2_write_url(opj_cio_t *cio, char *Idx_file) { + unsigned int i; + opj_jp2_box_t box; + + box.init_pos = cio_tell(cio); + cio_skip(cio, 4); + cio_write(cio, JP2_URL, 4); /* DBTL */ + cio_write(cio, 0, 1); /* VERS */ + cio_write(cio, 0, 3); /* FLAG */ + + if(Idx_file) { + for (i = 0; i < strlen(Idx_file); i++) { + cio_write(cio, Idx_file[i], 1); + } + } + + box.length = cio_tell(cio) - box.init_pos; + cio_seek(cio, box.init_pos); + cio_write(cio, box.length, 4); /* L */ + cio_seek(cio, box.init_pos + box.length); +} +#endif + +static bool jp2_read_ihdr(opj_jp2_t *jp2, opj_cio_t *cio) { + opj_jp2_box_t box; + + opj_common_ptr cinfo = jp2->cinfo; + + jp2_read_boxhdr(cinfo, cio, &box); + if (JP2_IHDR != box.type) { + opj_event_msg(cinfo, EVT_ERROR, "Expected IHDR Marker\n"); + return false; + } + + jp2->h = cio_read(cio, 4); /* HEIGHT */ + jp2->w = cio_read(cio, 4); /* WIDTH */ + jp2->numcomps = cio_read(cio, 2); /* NC */ + jp2->comps = (opj_jp2_comps_t*) opj_malloc(jp2->numcomps * sizeof(opj_jp2_comps_t)); + + jp2->bpc = cio_read(cio, 1); /* BPC */ + + jp2->C = cio_read(cio, 1); /* C */ + jp2->UnkC = cio_read(cio, 1); /* UnkC */ + jp2->IPR = cio_read(cio, 1); /* IPR */ + + if (cio_tell(cio) - box.init_pos != box.length) { + opj_event_msg(cinfo, EVT_ERROR, "Error with IHDR Box\n"); + return false; + } + + return true; +} + +static void jp2_write_ihdr(opj_jp2_t *jp2, opj_cio_t *cio) { + opj_jp2_box_t box; + + box.init_pos = cio_tell(cio); + cio_skip(cio, 4); + cio_write(cio, JP2_IHDR, 4); /* IHDR */ + + cio_write(cio, jp2->h, 4); /* HEIGHT */ + cio_write(cio, jp2->w, 4); /* WIDTH */ + cio_write(cio, jp2->numcomps, 2); /* NC */ + + cio_write(cio, jp2->bpc, 1); /* BPC */ + + cio_write(cio, jp2->C, 1); /* C : Always 7 */ + cio_write(cio, jp2->UnkC, 1); /* UnkC, colorspace unknown */ + cio_write(cio, jp2->IPR, 1); /* IPR, no intellectual property */ + + box.length = cio_tell(cio) - box.init_pos; + cio_seek(cio, box.init_pos); + cio_write(cio, box.length, 4); /* L */ + cio_seek(cio, box.init_pos + box.length); +} + +static void jp2_write_bpcc(opj_jp2_t *jp2, opj_cio_t *cio) { + unsigned int i; + opj_jp2_box_t box; + + box.init_pos = cio_tell(cio); + cio_skip(cio, 4); + cio_write(cio, JP2_BPCC, 4); /* BPCC */ + + for (i = 0; i < jp2->numcomps; i++) { + cio_write(cio, jp2->comps[i].bpcc, 1); + } + + box.length = cio_tell(cio) - box.init_pos; + cio_seek(cio, box.init_pos); + cio_write(cio, box.length, 4); /* L */ + cio_seek(cio, box.init_pos + box.length); +} + + +static bool jp2_read_bpcc(opj_jp2_t *jp2, opj_cio_t *cio) { + unsigned int i; + opj_jp2_box_t box; + + opj_common_ptr cinfo = jp2->cinfo; + + jp2_read_boxhdr(cinfo, cio, &box); + if (JP2_BPCC != box.type) { + opj_event_msg(cinfo, EVT_ERROR, "Expected BPCC Marker\n"); + return false; + } + + for (i = 0; i < jp2->numcomps; i++) { + jp2->comps[i].bpcc = cio_read(cio, 1); + } + + if (cio_tell(cio) - box.init_pos != box.length) { + opj_event_msg(cinfo, EVT_ERROR, "Error with BPCC Box\n"); + return false; + } + + return true; +} + +static void jp2_write_colr(opj_jp2_t *jp2, opj_cio_t *cio) { + opj_jp2_box_t box; + + box.init_pos = cio_tell(cio); + cio_skip(cio, 4); + cio_write(cio, JP2_COLR, 4); /* COLR */ + + cio_write(cio, jp2->meth, 1); /* METH */ + cio_write(cio, jp2->precedence, 1); /* PRECEDENCE */ + cio_write(cio, jp2->approx, 1); /* APPROX */ + + if (jp2->meth == 1) { + cio_write(cio, jp2->enumcs, 4); /* EnumCS */ + } else { + cio_write(cio, 0, 1); /* PROFILE (??) */ + } + + box.length = cio_tell(cio) - box.init_pos; + cio_seek(cio, box.init_pos); + cio_write(cio, box.length, 4); /* L */ + cio_seek(cio, box.init_pos + box.length); +} + +static bool jp2_read_colr(opj_jp2_t *jp2, opj_cio_t *cio) { + opj_jp2_box_t box; + int skip_len; + + opj_common_ptr cinfo = jp2->cinfo; + + jp2_read_boxhdr(cinfo, cio, &box); + do { + if (JP2_COLR != box.type) { + cio_skip(cio, box.length - 8); + jp2_read_boxhdr(cinfo, cio, &box); + } + } while(JP2_COLR != box.type); + + jp2->meth = cio_read(cio, 1); /* METH */ + jp2->precedence = cio_read(cio, 1); /* PRECEDENCE */ + jp2->approx = cio_read(cio, 1); /* APPROX */ + + if (jp2->meth == 1) { + jp2->enumcs = cio_read(cio, 4); /* EnumCS */ + } else { + /* skip PROFILE */ + skip_len = box.init_pos + box.length - cio_tell(cio); + if (skip_len < 0) { + opj_event_msg(cinfo, EVT_ERROR, "Error with JP2H box size\n"); + return false; + } + cio_skip(cio, box.init_pos + box.length - cio_tell(cio)); + } + + if (cio_tell(cio) - box.init_pos != box.length) { + opj_event_msg(cinfo, EVT_ERROR, "Error with BPCC Box\n"); + return false; + } + return true; +} + +void jp2_write_jp2h(opj_jp2_t *jp2, opj_cio_t *cio) { + opj_jp2_box_t box; + + box.init_pos = cio_tell(cio); + cio_skip(cio, 4); + cio_write(cio, JP2_JP2H, 4); /* JP2H */ + + jp2_write_ihdr(jp2, cio); + + if (jp2->bpc == 255) { + jp2_write_bpcc(jp2, cio); + } + jp2_write_colr(jp2, cio); + + box.length = cio_tell(cio) - box.init_pos; + cio_seek(cio, box.init_pos); + cio_write(cio, box.length, 4); /* L */ + cio_seek(cio, box.init_pos + box.length); +} + +bool jp2_read_jp2h(opj_jp2_t *jp2, opj_cio_t *cio) { + opj_jp2_box_t box; + int skip_len; + + opj_common_ptr cinfo = jp2->cinfo; + + jp2_read_boxhdr(cinfo, cio, &box); + do { + if (JP2_JP2H != box.type) { + if (box.type == JP2_JP2C) { + opj_event_msg(cinfo, EVT_ERROR, "Expected JP2H Marker\n"); + return false; + } + cio_skip(cio, box.length - 8); + jp2_read_boxhdr(cinfo, cio, &box); + } + } while(JP2_JP2H != box.type); + + if (!jp2_read_ihdr(jp2, cio)) + return false; + + if (jp2->bpc == 255) { + if (!jp2_read_bpcc(jp2, cio)) + return false; + } + if (!jp2_read_colr(jp2, cio)) + return false; + + skip_len = box.init_pos + box.length - cio_tell(cio); + if (skip_len < 0) { + opj_event_msg(cinfo, EVT_ERROR, "Error with JP2H Box\n"); + return false; + } + cio_skip(cio, box.init_pos + box.length - cio_tell(cio)); + + return true; +} + +static void jp2_write_ftyp(opj_jp2_t *jp2, opj_cio_t *cio) { + unsigned int i; + opj_jp2_box_t box; + + box.init_pos = cio_tell(cio); + cio_skip(cio, 4); + cio_write(cio, JP2_FTYP, 4); /* FTYP */ + + cio_write(cio, jp2->brand, 4); /* BR */ + cio_write(cio, jp2->minversion, 4); /* MinV */ + + for (i = 0; i < jp2->numcl; i++) { + cio_write(cio, jp2->cl[i], 4); /* CL */ + } + + box.length = cio_tell(cio) - box.init_pos; + cio_seek(cio, box.init_pos); + cio_write(cio, box.length, 4); /* L */ + cio_seek(cio, box.init_pos + box.length); +} + +static bool jp2_read_ftyp(opj_jp2_t *jp2, opj_cio_t *cio) { + int i; + opj_jp2_box_t box; + + opj_common_ptr cinfo = jp2->cinfo; + + jp2_read_boxhdr(cinfo, cio, &box); + + if (JP2_FTYP != box.type) { + opj_event_msg(cinfo, EVT_ERROR, "Expected FTYP Marker\n"); + return false; + } + + jp2->brand = cio_read(cio, 4); /* BR */ + jp2->minversion = cio_read(cio, 4); /* MinV */ + jp2->numcl = (box.length - 16) / 4; + jp2->cl = (unsigned int *) opj_malloc(jp2->numcl * sizeof(unsigned int)); + + for (i = 0; i < (int)jp2->numcl; i++) { + jp2->cl[i] = cio_read(cio, 4); /* CLi */ + } + + if (cio_tell(cio) - box.init_pos != box.length) { + opj_event_msg(cinfo, EVT_ERROR, "Error with FTYP Box\n"); + return false; + } + + return true; +} + +static int jp2_write_jp2c(opj_jp2_t *jp2, opj_cio_t *cio, opj_image_t *image, opj_codestream_info_t *cstr_info) { + unsigned int j2k_codestream_offset, j2k_codestream_length; + opj_jp2_box_t box; + + opj_j2k_t *j2k = jp2->j2k; + + box.init_pos = cio_tell(cio); + cio_skip(cio, 4); + cio_write(cio, JP2_JP2C, 4); /* JP2C */ + + /* J2K encoding */ + j2k_codestream_offset = cio_tell(cio); + if(!j2k_encode(j2k, cio, image, cstr_info)) { + opj_event_msg(j2k->cinfo, EVT_ERROR, "Failed to encode image\n"); + return 0; + } + j2k_codestream_length = cio_tell(cio) - j2k_codestream_offset; + + jp2->j2k_codestream_offset = j2k_codestream_offset; + jp2->j2k_codestream_length = j2k_codestream_length; + + box.length = 8 + jp2->j2k_codestream_length; + cio_seek(cio, box.init_pos); + cio_write(cio, box.length, 4); /* L */ + cio_seek(cio, box.init_pos + box.length); + + return box.length; +} + +static bool jp2_read_jp2c(opj_jp2_t *jp2, opj_cio_t *cio, unsigned int *j2k_codestream_length, unsigned int *j2k_codestream_offset) { + opj_jp2_box_t box; + + opj_common_ptr cinfo = jp2->cinfo; + + jp2_read_boxhdr(cinfo, cio, &box); + do { + if(JP2_JP2C != box.type) { + cio_skip(cio, box.length - 8); + jp2_read_boxhdr(cinfo, cio, &box); + } + } while(JP2_JP2C != box.type); + + *j2k_codestream_offset = cio_tell(cio); + *j2k_codestream_length = box.length - 8; + + return true; +} + +static void jp2_write_jp(opj_cio_t *cio) { + opj_jp2_box_t box; + + box.init_pos = cio_tell(cio); + cio_skip(cio, 4); + cio_write(cio, JP2_JP, 4); /* JP2 signature */ + cio_write(cio, 0x0d0a870a, 4); + + box.length = cio_tell(cio) - box.init_pos; + cio_seek(cio, box.init_pos); + cio_write(cio, box.length, 4); /* L */ + cio_seek(cio, box.init_pos + box.length); +} + +static bool jp2_read_jp(opj_jp2_t *jp2, opj_cio_t *cio) { + opj_jp2_box_t box; + + opj_common_ptr cinfo = jp2->cinfo; + + jp2_read_boxhdr(cinfo, cio, &box); + if (JP2_JP != box.type) { + opj_event_msg(cinfo, EVT_ERROR, "Expected JP Marker\n"); + return false; + } + if (0x0d0a870a != cio_read(cio, 4)) { + opj_event_msg(cinfo, EVT_ERROR, "Error with JP Marker\n"); + return false; + } + if (cio_tell(cio) - box.init_pos != box.length) { + opj_event_msg(cinfo, EVT_ERROR, "Error with JP Box size\n"); + return false; + } + + return true; +} + + +static bool jp2_read_struct(opj_jp2_t *jp2, opj_cio_t *cio) { + if (!jp2_read_jp(jp2, cio)) + return false; + if (!jp2_read_ftyp(jp2, cio)) + return false; + if (!jp2_read_jp2h(jp2, cio)) + return false; + if (!jp2_read_jp2c(jp2, cio, &jp2->j2k_codestream_length, &jp2->j2k_codestream_offset)) + return false; + + return true; +} + +/* ----------------------------------------------------------------------- */ +/* JP2 decoder interface */ +/* ----------------------------------------------------------------------- */ + +opj_jp2_t* jp2_create_decompress(opj_common_ptr cinfo) { + opj_jp2_t *jp2 = (opj_jp2_t*) opj_calloc(1, sizeof(opj_jp2_t)); + if(jp2) { + jp2->cinfo = cinfo; + /* create the J2K codec */ + jp2->j2k = j2k_create_decompress(cinfo); + if(jp2->j2k == NULL) { + jp2_destroy_decompress(jp2); + return NULL; + } + } + return jp2; +} + +void jp2_destroy_decompress(opj_jp2_t *jp2) { + if(jp2) { + /* destroy the J2K codec */ + j2k_destroy_decompress(jp2->j2k); + + if(jp2->comps) { + opj_free(jp2->comps); + } + if(jp2->cl) { + opj_free(jp2->cl); + } + opj_free(jp2); + } +} + +void jp2_setup_decoder(opj_jp2_t *jp2, opj_dparameters_t *parameters) { + /* setup the J2K codec */ + j2k_setup_decoder(jp2->j2k, parameters); + /* further JP2 initializations go here */ +} + +opj_image_t* jp2_decode(opj_jp2_t *jp2, opj_cio_t *cio, opj_codestream_info_t *cstr_info) { + opj_common_ptr cinfo; + opj_image_t *image = NULL; + + if(!jp2 || !cio) { + return NULL; + } + + cinfo = jp2->cinfo; + + /* JP2 decoding */ + if(!jp2_read_struct(jp2, cio)) { + opj_event_msg(cinfo, EVT_ERROR, "Failed to decode jp2 structure\n"); + return NULL; + } + + /* J2K decoding */ + image = j2k_decode(jp2->j2k, cio, cstr_info); + if(!image) { + opj_event_msg(cinfo, EVT_ERROR, "Failed to decode J2K image\n"); + } + + /* Set Image Color Space */ + if (jp2->enumcs == 16) + image->color_space = CLRSPC_SRGB; + else if (jp2->enumcs == 17) + image->color_space = CLRSPC_GRAY; + else if (jp2->enumcs == 18) + image->color_space = CLRSPC_SYCC; + else + image->color_space = CLRSPC_UNKNOWN; + + return image; +} + +/* ----------------------------------------------------------------------- */ +/* JP2 encoder interface */ +/* ----------------------------------------------------------------------- */ + +opj_jp2_t* jp2_create_compress(opj_common_ptr cinfo) { + opj_jp2_t *jp2 = (opj_jp2_t*)opj_malloc(sizeof(opj_jp2_t)); + if(jp2) { + jp2->cinfo = cinfo; + /* create the J2K codec */ + jp2->j2k = j2k_create_compress(cinfo); + if(jp2->j2k == NULL) { + jp2_destroy_compress(jp2); + return NULL; + } + } + return jp2; +} + +void jp2_destroy_compress(opj_jp2_t *jp2) { + if(jp2) { + /* destroy the J2K codec */ + j2k_destroy_compress(jp2->j2k); + + if(jp2->comps) { + opj_free(jp2->comps); + } + if(jp2->cl) { + opj_free(jp2->cl); + } + opj_free(jp2); + } +} + +void jp2_setup_encoder(opj_jp2_t *jp2, opj_cparameters_t *parameters, opj_image_t *image) { + int i; + int depth_0, sign; + + if(!jp2 || !parameters || !image) + return; + + /* setup the J2K codec */ + /* ------------------- */ + + /* Check if number of components respects standard */ + if (image->numcomps < 1 || image->numcomps > 16384) { + opj_event_msg(jp2->cinfo, EVT_ERROR, "Invalid number of components specified while setting up JP2 encoder\n"); + return; + } + + j2k_setup_encoder(jp2->j2k, parameters, image); + + /* setup the JP2 codec */ + /* ------------------- */ + + /* Profile box */ + + jp2->brand = JP2_JP2; /* BR */ + jp2->minversion = 0; /* MinV */ + jp2->numcl = 1; + jp2->cl = (unsigned int*) opj_malloc(jp2->numcl * sizeof(unsigned int)); + jp2->cl[0] = JP2_JP2; /* CL0 : JP2 */ + + /* Image Header box */ + + jp2->numcomps = image->numcomps; /* NC */ + jp2->comps = (opj_jp2_comps_t*) opj_malloc(jp2->numcomps * sizeof(opj_jp2_comps_t)); + jp2->h = image->y1 - image->y0; /* HEIGHT */ + jp2->w = image->x1 - image->x0; /* WIDTH */ + /* BPC */ + depth_0 = image->comps[0].prec - 1; + sign = image->comps[0].sgnd; + jp2->bpc = depth_0 + (sign << 7); + for (i = 1; i < image->numcomps; i++) { + int depth = image->comps[i].prec - 1; + sign = image->comps[i].sgnd; + if (depth_0 != depth) + jp2->bpc = 255; + } + jp2->C = 7; /* C : Always 7 */ + jp2->UnkC = 0; /* UnkC, colorspace specified in colr box */ + jp2->IPR = 0; /* IPR, no intellectual property */ + + /* BitsPerComponent box */ + + for (i = 0; i < image->numcomps; i++) { + jp2->comps[i].bpcc = image->comps[i].prec - 1 + (image->comps[i].sgnd << 7); + } + + /* Colour Specification box */ + + if ((image->numcomps == 1 || image->numcomps == 3) && (jp2->bpc != 255)) { + jp2->meth = 1; /* METH: Enumerated colourspace */ + } else { + jp2->meth = 2; /* METH: Restricted ICC profile */ + } + if (jp2->meth == 1) { + if (image->color_space == 1) + jp2->enumcs = 16; /* sRGB as defined by IEC 61966–2–1 */ + else if (image->color_space == 2) + jp2->enumcs = 17; /* greyscale */ + else if (image->color_space == 3) + jp2->enumcs = 18; /* YUV */ + } else { + jp2->enumcs = 0; /* PROFILE (??) */ + } + jp2->precedence = 0; /* PRECEDENCE */ + jp2->approx = 0; /* APPROX */ + +} + +bool jp2_encode(opj_jp2_t *jp2, opj_cio_t *cio, opj_image_t *image, opj_codestream_info_t *cstr_info) { + + /* JP2 encoding */ + + /* JPEG 2000 Signature box */ + jp2_write_jp(cio); + /* File Type box */ + jp2_write_ftyp(jp2, cio); + /* JP2 Header box */ + jp2_write_jp2h(jp2, cio); + + /* J2K encoding */ + + if(!jp2_write_jp2c(jp2, cio, image, cstr_info)) { + opj_event_msg(jp2->cinfo, EVT_ERROR, "Failed to encode image\n"); + return false; + } + + return true; +} + + diff --git a/extern/libopenjpeg/jp2.h b/extern/libopenjpeg/jp2.h new file mode 100644 index 00000000000..7e363be2eee --- /dev/null +++ b/extern/libopenjpeg/jp2.h @@ -0,0 +1,177 @@ +/* + * Copyright (c) 2002-2007, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium + * Copyright (c) 2002-2007, Professor Benoit Macq + * Copyright (c) 2002-2003, Yannick Verschueren + * Copyright (c) 2005, Herve Drolon, FreeImage Team + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 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. + */ +#ifndef __JP2_H +#define __JP2_H +/** +@file jp2.h +@brief The JPEG-2000 file format Reader/Writer (JP2) + +*/ + +/** @defgroup JP2 JP2 - JPEG-2000 file format reader/writer */ +/*@{*/ + +#define JPIP_JPIP 0x6a706970 + +#define JP2_JP 0x6a502020 /**< JPEG 2000 signature box */ +#define JP2_FTYP 0x66747970 /**< File type box */ +#define JP2_JP2H 0x6a703268 /**< JP2 header box */ +#define JP2_IHDR 0x69686472 /**< Image header box */ +#define JP2_COLR 0x636f6c72 /**< Colour specification box */ +#define JP2_JP2C 0x6a703263 /**< Contiguous codestream box */ +#define JP2_URL 0x75726c20 /**< URL box */ +#define JP2_DBTL 0x6474626c /**< ??? */ +#define JP2_BPCC 0x62706363 /**< Bits per component box */ +#define JP2_JP2 0x6a703220 /**< File type fields */ + +/* ----------------------------------------------------------------------- */ + +/** +JP2 component +*/ +typedef struct opj_jp2_comps { + int depth; + int sgnd; + int bpcc; +} opj_jp2_comps_t; + +/** +JPEG-2000 file format reader/writer +*/ +typedef struct opj_jp2 { + /** codec context */ + opj_common_ptr cinfo; + /** handle to the J2K codec */ + opj_j2k_t *j2k; + unsigned int w; + unsigned int h; + unsigned int numcomps; + unsigned int bpc; + unsigned int C; + unsigned int UnkC; + unsigned int IPR; + unsigned int meth; + unsigned int approx; + unsigned int enumcs; + unsigned int precedence; + unsigned int brand; + unsigned int minversion; + unsigned int numcl; + unsigned int *cl; + opj_jp2_comps_t *comps; + unsigned int j2k_codestream_offset; + unsigned int j2k_codestream_length; +} opj_jp2_t; + +/** +JP2 Box +*/ +typedef struct opj_jp2_box { + int length; + int type; + int init_pos; +} opj_jp2_box_t; + +/** @name Exported functions */ +/*@{*/ +/* ----------------------------------------------------------------------- */ +/** +Write the JP2H box - JP2 Header box (used in MJ2) +@param jp2 JP2 handle +@param cio Output buffer stream +*/ +void jp2_write_jp2h(opj_jp2_t *jp2, opj_cio_t *cio); +/** +Read the JP2H box - JP2 Header box (used in MJ2) +@param jp2 JP2 handle +@param cio Input buffer stream +@return Returns true if successful, returns false otherwise +*/ +bool jp2_read_jp2h(opj_jp2_t *jp2, opj_cio_t *cio); +/** +Creates a JP2 decompression structure +@param cinfo Codec context info +@return Returns a handle to a JP2 decompressor if successful, returns NULL otherwise +*/ +opj_jp2_t* jp2_create_decompress(opj_common_ptr cinfo); +/** +Destroy a JP2 decompressor handle +@param jp2 JP2 decompressor handle to destroy +*/ +void jp2_destroy_decompress(opj_jp2_t *jp2); +/** +Setup the decoder decoding parameters using user parameters. +Decoding parameters are returned in jp2->j2k->cp. +@param jp2 JP2 decompressor handle +@param parameters decompression parameters +*/ +void jp2_setup_decoder(opj_jp2_t *jp2, opj_dparameters_t *parameters); +/** +Decode an image from a JPEG-2000 file stream +@param jp2 JP2 decompressor handle +@param cio Input buffer stream +@param cstr_info Codestream information structure if required, NULL otherwise +@return Returns a decoded image if successful, returns NULL otherwise +*/ +opj_image_t* jp2_decode(opj_jp2_t *jp2, opj_cio_t *cio, opj_codestream_info_t *cstr_info); +/** +Creates a JP2 compression structure +@param cinfo Codec context info +@return Returns a handle to a JP2 compressor if successful, returns NULL otherwise +*/ +opj_jp2_t* jp2_create_compress(opj_common_ptr cinfo); +/** +Destroy a JP2 compressor handle +@param jp2 JP2 compressor handle to destroy +*/ +void jp2_destroy_compress(opj_jp2_t *jp2); +/** +Setup the encoder parameters using the current image and using user parameters. +Coding parameters are returned in jp2->j2k->cp. +@param jp2 JP2 compressor handle +@param parameters compression parameters +@param image input filled image +*/ +void jp2_setup_encoder(opj_jp2_t *jp2, opj_cparameters_t *parameters, opj_image_t *image); +/** +Encode an image into a JPEG-2000 file stream +@param jp2 JP2 compressor handle +@param cio Output buffer stream +@param image Image to encode +@param cstr_info Codestream information structure if required, NULL otherwise +@return Returns true if successful, returns false otherwise +*/ +bool jp2_encode(opj_jp2_t *jp2, opj_cio_t *cio, opj_image_t *image, opj_codestream_info_t *cstr_info); +/* ----------------------------------------------------------------------- */ +/*@}*/ + +/*@}*/ + +#endif /* __JP2_H */ + diff --git a/extern/libopenjpeg/jpt.c b/extern/libopenjpeg/jpt.c new file mode 100644 index 00000000000..a2566ea8872 --- /dev/null +++ b/extern/libopenjpeg/jpt.c @@ -0,0 +1,155 @@ +/* + * Copyright (c) 2002-2007, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium + * Copyright (c) 2002-2007, Professor Benoit Macq + * Copyright (c) 2002-2003, Yannick Verschueren + * Copyright (c) 2005, Herve Drolon, FreeImage Team + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 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. + */ + +#include "opj_includes.h" + +/* + * Read the information contains in VBAS [JPP/JPT stream message header] + * Store information (7 bits) in value + * + */ +unsigned int jpt_read_VBAS_info(opj_cio_t *cio, unsigned int value) { + unsigned char elmt; + + elmt = cio_read(cio, 1); + while ((elmt >> 7) == 1) { + value = (value << 7); + value |= (elmt & 0x7f); + elmt = cio_read(cio, 1); + } + value = (value << 7); + value |= (elmt & 0x7f); + + return value; +} + +/* + * Initialize the value of the message header structure + * + */ +void jpt_init_msg_header(opj_jpt_msg_header_t * header) { + header->Id = 0; /* In-class Identifier */ + header->last_byte = 0; /* Last byte information */ + header->Class_Id = 0; /* Class Identifier */ + header->CSn_Id = 0; /* CSn : index identifier */ + header->Msg_offset = 0; /* Message offset */ + header->Msg_length = 0; /* Message length */ + header->Layer_nb = 0; /* Auxiliary for JPP case */ +} + +/* + * Re-initialize the value of the message header structure + * + * Only parameters always present in message header + * + */ +void jpt_reinit_msg_header(opj_jpt_msg_header_t * header) { + header->Id = 0; /* In-class Identifier */ + header->last_byte = 0; /* Last byte information */ + header->Msg_offset = 0; /* Message offset */ + header->Msg_length = 0; /* Message length */ +} + +/* + * Read the message header for a JPP/JPT - stream + * + */ +void jpt_read_msg_header(opj_common_ptr cinfo, opj_cio_t *cio, opj_jpt_msg_header_t *header) { + unsigned char elmt, Class = 0, CSn = 0; + jpt_reinit_msg_header(header); + + /* ------------- */ + /* VBAS : Bin-ID */ + /* ------------- */ + elmt = cio_read(cio, 1); + + /* See for Class and CSn */ + switch ((elmt >> 5) & 0x03) { + case 0: + opj_event_msg(cinfo, EVT_ERROR, "Forbidden value encounter in message header !!\n"); + break; + case 1: + Class = 0; + CSn = 0; + break; + case 2: + Class = 1; + CSn = 0; + break; + case 3: + Class = 1; + CSn = 1; + break; + default: + break; + } + + /* see information on bits 'c' [p 10 : A.2.1 general, ISO/IEC FCD 15444-9] */ + if (((elmt >> 4) & 0x01) == 1) + header->last_byte = 1; + + /* In-class identifier */ + header->Id |= (elmt & 0x0f); + if ((elmt >> 7) == 1) + header->Id = jpt_read_VBAS_info(cio, header->Id); + + /* ------------ */ + /* VBAS : Class */ + /* ------------ */ + if (Class == 1) { + header->Class_Id = 0; + header->Class_Id = jpt_read_VBAS_info(cio, header->Class_Id); + } + + /* ---------- */ + /* VBAS : CSn */ + /* ---------- */ + if (CSn == 1) { + header->CSn_Id = 0; + header->CSn_Id = jpt_read_VBAS_info(cio, header->CSn_Id); + } + + /* ----------------- */ + /* VBAS : Msg_offset */ + /* ----------------- */ + header->Msg_offset = jpt_read_VBAS_info(cio, header->Msg_offset); + + /* ----------------- */ + /* VBAS : Msg_length */ + /* ----------------- */ + header->Msg_length = jpt_read_VBAS_info(cio, header->Msg_length); + + /* ---------- */ + /* VBAS : Aux */ + /* ---------- */ + if ((header->Class_Id & 0x01) == 1) { + header->Layer_nb = 0; + header->Layer_nb = jpt_read_VBAS_info(cio, header->Layer_nb); + } +} diff --git a/extern/libopenjpeg/jpt.h b/extern/libopenjpeg/jpt.h new file mode 100644 index 00000000000..eb01f98eb85 --- /dev/null +++ b/extern/libopenjpeg/jpt.h @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2002-2007, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium + * Copyright (c) 2002-2007, Professor Benoit Macq + * Copyright (c) 2002-2003, Yannick Verschueren + * Copyright (c) 2005, Herve Drolon, FreeImage Team + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 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. + */ + +#ifndef __JPT_H +#define __JPT_H +/** +@file jpt.h +@brief JPT-stream reader (JPEG 2000, JPIP) + +JPT-stream functions are implemented in J2K.C. +*/ + +/** +Message Header JPT stream structure +*/ +typedef struct opj_jpt_msg_header { + /** In-class Identifier */ + unsigned int Id; + /** Last byte information */ + unsigned int last_byte; + /** Class Identifier */ + unsigned int Class_Id; + /** CSn : index identifier */ + unsigned int CSn_Id; + /** Message offset */ + unsigned int Msg_offset; + /** Message length */ + unsigned int Msg_length; + /** Auxiliary for JPP case */ + unsigned int Layer_nb; +} opj_jpt_msg_header_t; + +/* ----------------------------------------------------------------------- */ + +/** +Initialize the value of the message header structure +@param header Message header structure +*/ +void jpt_init_msg_header(opj_jpt_msg_header_t * header); + +/** +Read the message header for a JPP/JPT - stream +@param cinfo Codec context info +@param cio CIO handle +@param header Message header structure +*/ +void jpt_read_msg_header(opj_common_ptr cinfo, opj_cio_t *cio, opj_jpt_msg_header_t *header); + +#endif diff --git a/extern/libopenjpeg/license.txt b/extern/libopenjpeg/license.txt new file mode 100644 index 00000000000..d1e5b6a5333 --- /dev/null +++ b/extern/libopenjpeg/license.txt @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2002-2007, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium + * Copyright (c) 2002-2007, Professor Benoit Macq + * Copyright (c) 2001-2003, David Janssens + * Copyright (c) 2002-2003, Yannick Verschueren + * Copyright (c) 2003-2007, Francois-Olivier Devaux and Antonin Descampe + * Copyright (c) 2005, Herve Drolon, FreeImage Team + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 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/extern/libopenjpeg/mct.c b/extern/libopenjpeg/mct.c new file mode 100644 index 00000000000..ca21744f3e4 --- /dev/null +++ b/extern/libopenjpeg/mct.c @@ -0,0 +1,148 @@ +/* + * Copyright (c) 2002-2007, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium + * Copyright (c) 2002-2007, Professor Benoit Macq + * Copyright (c) 2001-2003, David Janssens + * Copyright (c) 2002-2003, Yannick Verschueren + * Copyright (c) 2003-2007, Francois-Olivier Devaux and Antonin Descampe + * Copyright (c) 2005, Herve Drolon, FreeImage Team + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 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. + */ + +#include "opj_includes.h" + +/* */ +/* This table contains the norms of the basis function of the reversible MCT. */ +/* */ +static const double mct_norms[3] = { 1.732, .8292, .8292 }; + +/* */ +/* This table contains the norms of the basis function of the irreversible MCT. */ +/* */ +static const double mct_norms_real[3] = { 1.732, 1.805, 1.573 }; + +/* */ +/* Foward reversible MCT. */ +/* */ +void mct_encode( + int* restrict c0, + int* restrict c1, + int* restrict c2, + int n) +{ + int i; + for(i = 0; i < n; ++i) { + int r = c0[i]; + int g = c1[i]; + int b = c2[i]; + int y = (r + (g * 2) + b) >> 2; + int u = b - g; + int v = r - g; + c0[i] = y; + c1[i] = u; + c2[i] = v; + } +} + +/* */ +/* Inverse reversible MCT. */ +/* */ +void mct_decode( + int* restrict c0, + int* restrict c1, + int* restrict c2, + int n) +{ + int i; + for (i = 0; i < n; ++i) { + int y = c0[i]; + int u = c1[i]; + int v = c2[i]; + int g = y - ((u + v) >> 2); + int r = v + g; + int b = u + g; + c0[i] = r; + c1[i] = g; + c2[i] = b; + } +} + +/* */ +/* Get norm of basis function of reversible MCT. */ +/* */ +double mct_getnorm(int compno) { + return mct_norms[compno]; +} + +/* */ +/* Foward irreversible MCT. */ +/* */ +void mct_encode_real( + int* restrict c0, + int* restrict c1, + int* restrict c2, + int n) +{ + int i; + for(i = 0; i < n; ++i) { + int r = c0[i]; + int g = c1[i]; + int b = c2[i]; + int y = fix_mul(r, 2449) + fix_mul(g, 4809) + fix_mul(b, 934); + int u = -fix_mul(r, 1382) - fix_mul(g, 2714) + fix_mul(b, 4096); + int v = fix_mul(r, 4096) - fix_mul(g, 3430) - fix_mul(b, 666); + c0[i] = y; + c1[i] = u; + c2[i] = v; + } +} + +/* */ +/* Inverse irreversible MCT. */ +/* */ +void mct_decode_real( + float* restrict c0, + float* restrict c1, + float* restrict c2, + int n) +{ + int i; + for(i = 0; i < n; ++i) { + float y = c0[i]; + float u = c1[i]; + float v = c2[i]; + float r = y + (v * 1.402f); + float g = y - (u * 0.34413f) - (v * (0.71414f)); + float b = y + (u * 1.772f); + c0[i] = r; + c1[i] = g; + c2[i] = b; + } +} + +/* */ +/* Get norm of basis function of irreversible MCT. */ +/* */ +double mct_getnorm_real(int compno) { + return mct_norms_real[compno]; +} diff --git a/extern/libopenjpeg/mct.h b/extern/libopenjpeg/mct.h new file mode 100644 index 00000000000..84e3f8add19 --- /dev/null +++ b/extern/libopenjpeg/mct.h @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2002-2007, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium + * Copyright (c) 2002-2007, Professor Benoit Macq + * Copyright (c) 2001-2003, David Janssens + * Copyright (c) 2002-2003, Yannick Verschueren + * Copyright (c) 2003-2007, Francois-Olivier Devaux and Antonin Descampe + * Copyright (c) 2005, Herve Drolon, FreeImage Team + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 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. + */ + +#ifndef __MCT_H +#define __MCT_H +/** +@file mct.h +@brief Implementation of a multi-component transforms (MCT) + +The functions in MCT.C have for goal to realize reversible and irreversible multicomponent +transform. The functions in MCT.C are used by some function in TCD.C. +*/ + +/** @defgroup MCT MCT - Implementation of a multi-component transform */ +/*@{*/ + +/** @name Exported functions */ +/*@{*/ +/* ----------------------------------------------------------------------- */ +/** +Apply a reversible multi-component transform to an image +@param c0 Samples for red component +@param c1 Samples for green component +@param c2 Samples blue component +@param n Number of samples for each component +*/ +void mct_encode(int *c0, int *c1, int *c2, int n); +/** +Apply a reversible multi-component inverse transform to an image +@param c0 Samples for luminance component +@param c1 Samples for red chrominance component +@param c2 Samples for blue chrominance component +@param n Number of samples for each component +*/ +void mct_decode(int *c0, int *c1, int *c2, int n); +/** +Get norm of the basis function used for the reversible multi-component transform +@param compno Number of the component (0->Y, 1->U, 2->V) +@return +*/ +double mct_getnorm(int compno); + +/** +Apply an irreversible multi-component transform to an image +@param c0 Samples for red component +@param c1 Samples for green component +@param c2 Samples blue component +@param n Number of samples for each component +*/ +void mct_encode_real(int *c0, int *c1, int *c2, int n); +/** +Apply an irreversible multi-component inverse transform to an image +@param c0 Samples for luminance component +@param c1 Samples for red chrominance component +@param c2 Samples for blue chrominance component +@param n Number of samples for each component +*/ +void mct_decode_real(float* c0, float* c1, float* c2, int n); +/** +Get norm of the basis function used for the irreversible multi-component transform +@param compno Number of the component (0->Y, 1->U, 2->V) +@return +*/ +double mct_getnorm_real(int compno); +/* ----------------------------------------------------------------------- */ +/*@}*/ + +/*@}*/ + +#endif /* __MCT_H */ diff --git a/extern/libopenjpeg/mqc.c b/extern/libopenjpeg/mqc.c new file mode 100644 index 00000000000..9aa9d2c2e5b --- /dev/null +++ b/extern/libopenjpeg/mqc.c @@ -0,0 +1,538 @@ +/* + * Copyright (c) 2002-2007, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium + * Copyright (c) 2002-2007, Professor Benoit Macq + * Copyright (c) 2001-2003, David Janssens + * Copyright (c) 2002-2003, Yannick Verschueren + * Copyright (c) 2003-2007, Francois-Olivier Devaux and Antonin Descampe + * Copyright (c) 2005, Herve Drolon, FreeImage Team + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 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. + */ + +#include "opj_includes.h" + +/** @defgroup MQC MQC - Implementation of an MQ-Coder */ +/*@{*/ + +/** @name Local static functions */ +/*@{*/ + +/** +Output a byte, doing bit-stuffing if necessary. +After a 0xff byte, the next byte must be smaller than 0x90. +@param mqc MQC handle +*/ +static void mqc_byteout(opj_mqc_t *mqc); +/** +Renormalize mqc->a and mqc->c while encoding, so that mqc->a stays between 0x8000 and 0x10000 +@param mqc MQC handle +*/ +static void mqc_renorme(opj_mqc_t *mqc); +/** +Encode the most probable symbol +@param mqc MQC handle +*/ +static void mqc_codemps(opj_mqc_t *mqc); +/** +Encode the most least symbol +@param mqc MQC handle +*/ +static void mqc_codelps(opj_mqc_t *mqc); +/** +Fill mqc->c with 1's for flushing +@param mqc MQC handle +*/ +static void mqc_setbits(opj_mqc_t *mqc); +/** +FIXME: documentation ??? +@param mqc MQC handle +@return +*/ +static int mqc_mpsexchange(opj_mqc_t *mqc); +/** +FIXME: documentation ??? +@param mqc MQC handle +@return +*/ +static int mqc_lpsexchange(opj_mqc_t *mqc); +/** +Input a byte +@param mqc MQC handle +*/ +static void mqc_bytein(opj_mqc_t *mqc); +/** +Renormalize mqc->a and mqc->c while decoding +@param mqc MQC handle +*/ +static void mqc_renormd(opj_mqc_t *mqc); + +/*@}*/ + +/*@}*/ + +/* */ +/* This array defines all the possible states for a context. */ +/* */ +static opj_mqc_state_t mqc_states[47 * 2] = { + {0x5601, 0, &mqc_states[2], &mqc_states[3]}, + {0x5601, 1, &mqc_states[3], &mqc_states[2]}, + {0x3401, 0, &mqc_states[4], &mqc_states[12]}, + {0x3401, 1, &mqc_states[5], &mqc_states[13]}, + {0x1801, 0, &mqc_states[6], &mqc_states[18]}, + {0x1801, 1, &mqc_states[7], &mqc_states[19]}, + {0x0ac1, 0, &mqc_states[8], &mqc_states[24]}, + {0x0ac1, 1, &mqc_states[9], &mqc_states[25]}, + {0x0521, 0, &mqc_states[10], &mqc_states[58]}, + {0x0521, 1, &mqc_states[11], &mqc_states[59]}, + {0x0221, 0, &mqc_states[76], &mqc_states[66]}, + {0x0221, 1, &mqc_states[77], &mqc_states[67]}, + {0x5601, 0, &mqc_states[14], &mqc_states[13]}, + {0x5601, 1, &mqc_states[15], &mqc_states[12]}, + {0x5401, 0, &mqc_states[16], &mqc_states[28]}, + {0x5401, 1, &mqc_states[17], &mqc_states[29]}, + {0x4801, 0, &mqc_states[18], &mqc_states[28]}, + {0x4801, 1, &mqc_states[19], &mqc_states[29]}, + {0x3801, 0, &mqc_states[20], &mqc_states[28]}, + {0x3801, 1, &mqc_states[21], &mqc_states[29]}, + {0x3001, 0, &mqc_states[22], &mqc_states[34]}, + {0x3001, 1, &mqc_states[23], &mqc_states[35]}, + {0x2401, 0, &mqc_states[24], &mqc_states[36]}, + {0x2401, 1, &mqc_states[25], &mqc_states[37]}, + {0x1c01, 0, &mqc_states[26], &mqc_states[40]}, + {0x1c01, 1, &mqc_states[27], &mqc_states[41]}, + {0x1601, 0, &mqc_states[58], &mqc_states[42]}, + {0x1601, 1, &mqc_states[59], &mqc_states[43]}, + {0x5601, 0, &mqc_states[30], &mqc_states[29]}, + {0x5601, 1, &mqc_states[31], &mqc_states[28]}, + {0x5401, 0, &mqc_states[32], &mqc_states[28]}, + {0x5401, 1, &mqc_states[33], &mqc_states[29]}, + {0x5101, 0, &mqc_states[34], &mqc_states[30]}, + {0x5101, 1, &mqc_states[35], &mqc_states[31]}, + {0x4801, 0, &mqc_states[36], &mqc_states[32]}, + {0x4801, 1, &mqc_states[37], &mqc_states[33]}, + {0x3801, 0, &mqc_states[38], &mqc_states[34]}, + {0x3801, 1, &mqc_states[39], &mqc_states[35]}, + {0x3401, 0, &mqc_states[40], &mqc_states[36]}, + {0x3401, 1, &mqc_states[41], &mqc_states[37]}, + {0x3001, 0, &mqc_states[42], &mqc_states[38]}, + {0x3001, 1, &mqc_states[43], &mqc_states[39]}, + {0x2801, 0, &mqc_states[44], &mqc_states[38]}, + {0x2801, 1, &mqc_states[45], &mqc_states[39]}, + {0x2401, 0, &mqc_states[46], &mqc_states[40]}, + {0x2401, 1, &mqc_states[47], &mqc_states[41]}, + {0x2201, 0, &mqc_states[48], &mqc_states[42]}, + {0x2201, 1, &mqc_states[49], &mqc_states[43]}, + {0x1c01, 0, &mqc_states[50], &mqc_states[44]}, + {0x1c01, 1, &mqc_states[51], &mqc_states[45]}, + {0x1801, 0, &mqc_states[52], &mqc_states[46]}, + {0x1801, 1, &mqc_states[53], &mqc_states[47]}, + {0x1601, 0, &mqc_states[54], &mqc_states[48]}, + {0x1601, 1, &mqc_states[55], &mqc_states[49]}, + {0x1401, 0, &mqc_states[56], &mqc_states[50]}, + {0x1401, 1, &mqc_states[57], &mqc_states[51]}, + {0x1201, 0, &mqc_states[58], &mqc_states[52]}, + {0x1201, 1, &mqc_states[59], &mqc_states[53]}, + {0x1101, 0, &mqc_states[60], &mqc_states[54]}, + {0x1101, 1, &mqc_states[61], &mqc_states[55]}, + {0x0ac1, 0, &mqc_states[62], &mqc_states[56]}, + {0x0ac1, 1, &mqc_states[63], &mqc_states[57]}, + {0x09c1, 0, &mqc_states[64], &mqc_states[58]}, + {0x09c1, 1, &mqc_states[65], &mqc_states[59]}, + {0x08a1, 0, &mqc_states[66], &mqc_states[60]}, + {0x08a1, 1, &mqc_states[67], &mqc_states[61]}, + {0x0521, 0, &mqc_states[68], &mqc_states[62]}, + {0x0521, 1, &mqc_states[69], &mqc_states[63]}, + {0x0441, 0, &mqc_states[70], &mqc_states[64]}, + {0x0441, 1, &mqc_states[71], &mqc_states[65]}, + {0x02a1, 0, &mqc_states[72], &mqc_states[66]}, + {0x02a1, 1, &mqc_states[73], &mqc_states[67]}, + {0x0221, 0, &mqc_states[74], &mqc_states[68]}, + {0x0221, 1, &mqc_states[75], &mqc_states[69]}, + {0x0141, 0, &mqc_states[76], &mqc_states[70]}, + {0x0141, 1, &mqc_states[77], &mqc_states[71]}, + {0x0111, 0, &mqc_states[78], &mqc_states[72]}, + {0x0111, 1, &mqc_states[79], &mqc_states[73]}, + {0x0085, 0, &mqc_states[80], &mqc_states[74]}, + {0x0085, 1, &mqc_states[81], &mqc_states[75]}, + {0x0049, 0, &mqc_states[82], &mqc_states[76]}, + {0x0049, 1, &mqc_states[83], &mqc_states[77]}, + {0x0025, 0, &mqc_states[84], &mqc_states[78]}, + {0x0025, 1, &mqc_states[85], &mqc_states[79]}, + {0x0015, 0, &mqc_states[86], &mqc_states[80]}, + {0x0015, 1, &mqc_states[87], &mqc_states[81]}, + {0x0009, 0, &mqc_states[88], &mqc_states[82]}, + {0x0009, 1, &mqc_states[89], &mqc_states[83]}, + {0x0005, 0, &mqc_states[90], &mqc_states[84]}, + {0x0005, 1, &mqc_states[91], &mqc_states[85]}, + {0x0001, 0, &mqc_states[90], &mqc_states[86]}, + {0x0001, 1, &mqc_states[91], &mqc_states[87]}, + {0x5601, 0, &mqc_states[92], &mqc_states[92]}, + {0x5601, 1, &mqc_states[93], &mqc_states[93]}, +}; + +/* +========================================================== + local functions +========================================================== +*/ + +static void mqc_byteout(opj_mqc_t *mqc) { + if (*mqc->bp == 0xff) { + mqc->bp++; + *mqc->bp = mqc->c >> 20; + mqc->c &= 0xfffff; + mqc->ct = 7; + } else { + if ((mqc->c & 0x8000000) == 0) { /* ((mqc->c&0x8000000)==0) CHANGE */ + mqc->bp++; + *mqc->bp = mqc->c >> 19; + mqc->c &= 0x7ffff; + mqc->ct = 8; + } else { + (*mqc->bp)++; + if (*mqc->bp == 0xff) { + mqc->c &= 0x7ffffff; + mqc->bp++; + *mqc->bp = mqc->c >> 20; + mqc->c &= 0xfffff; + mqc->ct = 7; + } else { + mqc->bp++; + *mqc->bp = mqc->c >> 19; + mqc->c &= 0x7ffff; + mqc->ct = 8; + } + } + } +} + +static void mqc_renorme(opj_mqc_t *mqc) { + do { + mqc->a <<= 1; + mqc->c <<= 1; + mqc->ct--; + if (mqc->ct == 0) { + mqc_byteout(mqc); + } + } while ((mqc->a & 0x8000) == 0); +} + +static void mqc_codemps(opj_mqc_t *mqc) { + mqc->a -= (*mqc->curctx)->qeval; + if ((mqc->a & 0x8000) == 0) { + if (mqc->a < (*mqc->curctx)->qeval) { + mqc->a = (*mqc->curctx)->qeval; + } else { + mqc->c += (*mqc->curctx)->qeval; + } + *mqc->curctx = (*mqc->curctx)->nmps; + mqc_renorme(mqc); + } else { + mqc->c += (*mqc->curctx)->qeval; + } +} + +static void mqc_codelps(opj_mqc_t *mqc) { + mqc->a -= (*mqc->curctx)->qeval; + if (mqc->a < (*mqc->curctx)->qeval) { + mqc->c += (*mqc->curctx)->qeval; + } else { + mqc->a = (*mqc->curctx)->qeval; + } + *mqc->curctx = (*mqc->curctx)->nlps; + mqc_renorme(mqc); +} + +static void mqc_setbits(opj_mqc_t *mqc) { + unsigned int tempc = mqc->c + mqc->a; + mqc->c |= 0xffff; + if (mqc->c >= tempc) { + mqc->c -= 0x8000; + } +} + +static int mqc_mpsexchange(opj_mqc_t *mqc) { + int d; + if (mqc->a < (*mqc->curctx)->qeval) { + d = 1 - (*mqc->curctx)->mps; + *mqc->curctx = (*mqc->curctx)->nlps; + } else { + d = (*mqc->curctx)->mps; + *mqc->curctx = (*mqc->curctx)->nmps; + } + + return d; +} + +static int mqc_lpsexchange(opj_mqc_t *mqc) { + int d; + if (mqc->a < (*mqc->curctx)->qeval) { + mqc->a = (*mqc->curctx)->qeval; + d = (*mqc->curctx)->mps; + *mqc->curctx = (*mqc->curctx)->nmps; + } else { + mqc->a = (*mqc->curctx)->qeval; + d = 1 - (*mqc->curctx)->mps; + *mqc->curctx = (*mqc->curctx)->nlps; + } + + return d; +} + +static void mqc_bytein(opj_mqc_t *mqc) { + if (mqc->bp != mqc->end) { + unsigned int c; + if (mqc->bp + 1 != mqc->end) { + c = *(mqc->bp + 1); + } else { + c = 0xff; + } + if (*mqc->bp == 0xff) { + if (c > 0x8f) { + mqc->c += 0xff00; + mqc->ct = 8; + } else { + mqc->bp++; + mqc->c += c << 9; + mqc->ct = 7; + } + } else { + mqc->bp++; + mqc->c += c << 8; + mqc->ct = 8; + } + } else { + mqc->c += 0xff00; + mqc->ct = 8; + } +} + +static void mqc_renormd(opj_mqc_t *mqc) { + do { + if (mqc->ct == 0) { + mqc_bytein(mqc); + } + mqc->a <<= 1; + mqc->c <<= 1; + mqc->ct--; + } while (mqc->a < 0x8000); +} + +/* +========================================================== + MQ-Coder interface +========================================================== +*/ + +opj_mqc_t* mqc_create(void) { + opj_mqc_t *mqc = (opj_mqc_t*)opj_malloc(sizeof(opj_mqc_t)); + return mqc; +} + +void mqc_destroy(opj_mqc_t *mqc) { + if(mqc) { + opj_free(mqc); + } +} + +int mqc_numbytes(opj_mqc_t *mqc) { + return mqc->bp - mqc->start; +} + +void mqc_init_enc(opj_mqc_t *mqc, unsigned char *bp) { + mqc_setcurctx(mqc, 0); + mqc->a = 0x8000; + mqc->c = 0; + mqc->bp = bp - 1; + mqc->ct = 12; + if (*mqc->bp == 0xff) { + mqc->ct = 13; + } + mqc->start = bp; +} + +void mqc_encode(opj_mqc_t *mqc, int d) { + if ((*mqc->curctx)->mps == d) { + mqc_codemps(mqc); + } else { + mqc_codelps(mqc); + } +} + +void mqc_flush(opj_mqc_t *mqc) { + mqc_setbits(mqc); + mqc->c <<= mqc->ct; + mqc_byteout(mqc); + mqc->c <<= mqc->ct; + mqc_byteout(mqc); + + if (*mqc->bp != 0xff) { + mqc->bp++; + } +} + +void mqc_bypass_init_enc(opj_mqc_t *mqc) { + mqc->c = 0; + mqc->ct = 8; + /*if (*mqc->bp == 0xff) { + mqc->ct = 7; + } */ +} + +void mqc_bypass_enc(opj_mqc_t *mqc, int d) { + mqc->ct--; + mqc->c = mqc->c + (d << mqc->ct); + if (mqc->ct == 0) { + mqc->bp++; + *mqc->bp = mqc->c; + mqc->ct = 8; + if (*mqc->bp == 0xff) { + mqc->ct = 7; + } + mqc->c = 0; + } +} + +int mqc_bypass_flush_enc(opj_mqc_t *mqc) { + unsigned char bit_padding; + + bit_padding = 0; + + if (mqc->ct != 0) { + while (mqc->ct > 0) { + mqc->ct--; + mqc->c += bit_padding << mqc->ct; + bit_padding = (bit_padding + 1) & 0x01; + } + mqc->bp++; + *mqc->bp = mqc->c; + mqc->ct = 8; + mqc->c = 0; + } + + return 1; +} + +void mqc_reset_enc(opj_mqc_t *mqc) { + mqc_resetstates(mqc); + mqc_setstate(mqc, T1_CTXNO_UNI, 0, 46); + mqc_setstate(mqc, T1_CTXNO_AGG, 0, 3); + mqc_setstate(mqc, T1_CTXNO_ZC, 0, 4); +} + +int mqc_restart_enc(opj_mqc_t *mqc) { + int correction = 1; + + /* */ + int n = 27 - 15 - mqc->ct; + mqc->c <<= mqc->ct; + while (n > 0) { + mqc_byteout(mqc); + n -= mqc->ct; + mqc->c <<= mqc->ct; + } + mqc_byteout(mqc); + + return correction; +} + +void mqc_restart_init_enc(opj_mqc_t *mqc) { + /* */ + mqc_setcurctx(mqc, 0); + mqc->a = 0x8000; + mqc->c = 0; + mqc->ct = 12; + mqc->bp--; + if (*mqc->bp == 0xff) { + mqc->ct = 13; + } +} + +void mqc_erterm_enc(opj_mqc_t *mqc) { + int k = 11 - mqc->ct + 1; + + while (k > 0) { + mqc->c <<= mqc->ct; + mqc->ct = 0; + mqc_byteout(mqc); + k -= mqc->ct; + } + + if (*mqc->bp != 0xff) { + mqc_byteout(mqc); + } +} + +void mqc_segmark_enc(opj_mqc_t *mqc) { + int i; + mqc_setcurctx(mqc, 18); + + for (i = 1; i < 5; i++) { + mqc_encode(mqc, i % 2); + } +} + +void mqc_init_dec(opj_mqc_t *mqc, unsigned char *bp, int len) { + mqc_setcurctx(mqc, 0); + mqc->start = bp; + mqc->end = bp + len; + mqc->bp = bp; + if (len==0) mqc->c = 0xff << 16; + else mqc->c = *mqc->bp << 16; + mqc_bytein(mqc); + mqc->c <<= 7; + mqc->ct -= 7; + mqc->a = 0x8000; +} + +int mqc_decode(opj_mqc_t *mqc) { + int d; + mqc->a -= (*mqc->curctx)->qeval; + if ((mqc->c >> 16) < (*mqc->curctx)->qeval) { + d = mqc_lpsexchange(mqc); + mqc_renormd(mqc); + } else { + mqc->c -= (*mqc->curctx)->qeval << 16; + if ((mqc->a & 0x8000) == 0) { + d = mqc_mpsexchange(mqc); + mqc_renormd(mqc); + } else { + d = (*mqc->curctx)->mps; + } + } + + return d; +} + +void mqc_resetstates(opj_mqc_t *mqc) { + int i; + for (i = 0; i < MQC_NUMCTXS; i++) { + mqc->ctxs[i] = mqc_states; + } +} + +void mqc_setstate(opj_mqc_t *mqc, int ctxno, int msb, int prob) { + mqc->ctxs[ctxno] = &mqc_states[msb + (prob << 1)]; +} + + diff --git a/extern/libopenjpeg/mqc.h b/extern/libopenjpeg/mqc.h new file mode 100644 index 00000000000..8cc8c934598 --- /dev/null +++ b/extern/libopenjpeg/mqc.h @@ -0,0 +1,197 @@ +/* + * Copyright (c) 2002-2007, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium + * Copyright (c) 2002-2007, Professor Benoit Macq + * Copyright (c) 2001-2003, David Janssens + * Copyright (c) 2002-2003, Yannick Verschueren + * Copyright (c) 2003-2007, Francois-Olivier Devaux and Antonin Descampe + * Copyright (c) 2005, Herve Drolon, FreeImage Team + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 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. + */ + +#ifndef __MQC_H +#define __MQC_H +/** +@file mqc.h +@brief Implementation of an MQ-Coder (MQC) + +The functions in MQC.C have for goal to realize the MQ-coder operations. The functions +in MQC.C are used by some function in T1.C. +*/ + +/** @defgroup MQC MQC - Implementation of an MQ-Coder */ +/*@{*/ + +/** +This struct defines the state of a context. +*/ +typedef struct opj_mqc_state { + /** the probability of the Least Probable Symbol (0.75->0x8000, 1.5->0xffff) */ + unsigned int qeval; + /** the Most Probable Symbol (0 or 1) */ + int mps; + /** next state if the next encoded symbol is the MPS */ + struct opj_mqc_state *nmps; + /** next state if the next encoded symbol is the LPS */ + struct opj_mqc_state *nlps; +} opj_mqc_state_t; + +#define MQC_NUMCTXS 19 + +/** +MQ coder +*/ +typedef struct opj_mqc { + unsigned int c; + unsigned int a; + unsigned int ct; + unsigned char *bp; + unsigned char *start; + unsigned char *end; + opj_mqc_state_t *ctxs[MQC_NUMCTXS]; + opj_mqc_state_t **curctx; +} opj_mqc_t; + +/** @name Exported functions */ +/*@{*/ +/* ----------------------------------------------------------------------- */ +/** +Create a new MQC handle +@return Returns a new MQC handle if successful, returns NULL otherwise +*/ +opj_mqc_t* mqc_create(void); +/** +Destroy a previously created MQC handle +@param mqc MQC handle to destroy +*/ +void mqc_destroy(opj_mqc_t *mqc); +/** +Return the number of bytes written/read since initialisation +@param mqc MQC handle +@return Returns the number of bytes already encoded +*/ +int mqc_numbytes(opj_mqc_t *mqc); +/** +Reset the states of all the context of the coder/decoder +(each context is set to a state where 0 and 1 are more or less equiprobable) +@param mqc MQC handle +*/ +void mqc_resetstates(opj_mqc_t *mqc); +/** +Set the state of a particular context +@param mqc MQC handle +@param ctxno Number that identifies the context +@param msb The MSB of the new state of the context +@param prob Number that identifies the probability of the symbols for the new state of the context +*/ +void mqc_setstate(opj_mqc_t *mqc, int ctxno, int msb, int prob); +/** +Initialize the encoder +@param mqc MQC handle +@param bp Pointer to the start of the buffer where the bytes will be written +*/ +void mqc_init_enc(opj_mqc_t *mqc, unsigned char *bp); +/** +Set the current context used for coding/decoding +@param mqc MQC handle +@param ctxno Number that identifies the context +*/ +#define mqc_setcurctx(mqc, ctxno) (mqc)->curctx = &(mqc)->ctxs[(int)(ctxno)] +/** +Encode a symbol using the MQ-coder +@param mqc MQC handle +@param d The symbol to be encoded (0 or 1) +*/ +void mqc_encode(opj_mqc_t *mqc, int d); +/** +Flush the encoder, so that all remaining data is written +@param mqc MQC handle +*/ +void mqc_flush(opj_mqc_t *mqc); +/** +BYPASS mode switch, initialization operation. +JPEG 2000 p 505. +

Not fully implemented and tested !!

+@param mqc MQC handle +*/ +void mqc_bypass_init_enc(opj_mqc_t *mqc); +/** +BYPASS mode switch, coding operation. +JPEG 2000 p 505. +

Not fully implemented and tested !!

+@param mqc MQC handle +@param d The symbol to be encoded (0 or 1) +*/ +void mqc_bypass_enc(opj_mqc_t *mqc, int d); +/** +BYPASS mode switch, flush operation +

Not fully implemented and tested !!

+@param mqc MQC handle +@return Returns 1 (always) +*/ +int mqc_bypass_flush_enc(opj_mqc_t *mqc); +/** +RESET mode switch +@param mqc MQC handle +*/ +void mqc_reset_enc(opj_mqc_t *mqc); +/** +RESTART mode switch (TERMALL) +@param mqc MQC handle +@return Returns 1 (always) +*/ +int mqc_restart_enc(opj_mqc_t *mqc); +/** +RESTART mode switch (TERMALL) reinitialisation +@param mqc MQC handle +*/ +void mqc_restart_init_enc(opj_mqc_t *mqc); +/** +ERTERM mode switch (PTERM) +@param mqc MQC handle +*/ +void mqc_erterm_enc(opj_mqc_t *mqc); +/** +SEGMARK mode switch (SEGSYM) +@param mqc MQC handle +*/ +void mqc_segmark_enc(opj_mqc_t *mqc); +/** +Initialize the decoder +@param mqc MQC handle +@param bp Pointer to the start of the buffer from which the bytes will be read +@param len Length of the input buffer +*/ +void mqc_init_dec(opj_mqc_t *mqc, unsigned char *bp, int len); +/** +Decode a symbol +@param mqc MQC handle +@return Returns the decoded symbol (0 or 1) +*/ +int mqc_decode(opj_mqc_t *mqc); +/* ----------------------------------------------------------------------- */ +/*@}*/ + +/*@}*/ + +#endif /* __MQC_H */ diff --git a/extern/libopenjpeg/openjpeg.c b/extern/libopenjpeg/openjpeg.c new file mode 100644 index 00000000000..96fa0ad57e5 --- /dev/null +++ b/extern/libopenjpeg/openjpeg.c @@ -0,0 +1,329 @@ +/* + * Copyright (c) 2005, Hervé Drolon, FreeImage Team + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 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. + */ + +#ifdef WIN32 +#include +#endif /* WIN32 */ + +#include "opj_includes.h" + +/* ---------------------------------------------------------------------- */ +#ifdef WIN32 +#ifndef OPJ_STATIC +BOOL APIENTRY +DllMain(HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) { + switch (ul_reason_for_call) { + case DLL_PROCESS_ATTACH : + break; + case DLL_PROCESS_DETACH : + break; + case DLL_THREAD_ATTACH : + case DLL_THREAD_DETACH : + break; + } + + return TRUE; +} +#endif /* OPJ_STATIC */ +#endif /* WIN32 */ + +/* ---------------------------------------------------------------------- */ + + +const char* OPJ_CALLCONV opj_version(void) { + return OPENJPEG_VERSION; +} + +opj_dinfo_t* OPJ_CALLCONV opj_create_decompress(OPJ_CODEC_FORMAT format) { + opj_dinfo_t *dinfo = (opj_dinfo_t*)opj_malloc(sizeof(opj_dinfo_t)); + if(!dinfo) return NULL; + dinfo->is_decompressor = true; + switch(format) { + case CODEC_J2K: + case CODEC_JPT: + /* get a J2K decoder handle */ + dinfo->j2k_handle = (void*)j2k_create_decompress((opj_common_ptr)dinfo); + if(!dinfo->j2k_handle) { + opj_free(dinfo); + return NULL; + } + break; + case CODEC_JP2: + /* get a JP2 decoder handle */ + dinfo->jp2_handle = (void*)jp2_create_decompress((opj_common_ptr)dinfo); + if(!dinfo->jp2_handle) { + opj_free(dinfo); + return NULL; + } + break; + case CODEC_UNKNOWN: + default: + opj_free(dinfo); + return NULL; + } + + dinfo->codec_format = format; + + return dinfo; +} + +void OPJ_CALLCONV opj_destroy_decompress(opj_dinfo_t *dinfo) { + if(dinfo) { + /* destroy the codec */ + switch(dinfo->codec_format) { + case CODEC_J2K: + case CODEC_JPT: + j2k_destroy_decompress((opj_j2k_t*)dinfo->j2k_handle); + break; + case CODEC_JP2: + jp2_destroy_decompress((opj_jp2_t*)dinfo->jp2_handle); + break; + case CODEC_UNKNOWN: + default: + break; + } + /* destroy the decompressor */ + opj_free(dinfo); + } +} + +void OPJ_CALLCONV opj_set_default_decoder_parameters(opj_dparameters_t *parameters) { + if(parameters) { + memset(parameters, 0, sizeof(opj_dparameters_t)); + /* default decoding parameters */ + parameters->cp_layer = 0; + parameters->cp_reduce = 0; + parameters->cp_limit_decoding = NO_LIMITATION; + + parameters->decod_format = -1; + parameters->cod_format = -1; +/* UniPG>> */ +#ifdef USE_JPWL + parameters->jpwl_correct = false; + parameters->jpwl_exp_comps = JPWL_EXPECTED_COMPONENTS; + parameters->jpwl_max_tiles = JPWL_MAXIMUM_TILES; +#endif /* USE_JPWL */ +/* <codec_format) { + case CODEC_J2K: + case CODEC_JPT: + j2k_setup_decoder((opj_j2k_t*)dinfo->j2k_handle, parameters); + break; + case CODEC_JP2: + jp2_setup_decoder((opj_jp2_t*)dinfo->jp2_handle, parameters); + break; + case CODEC_UNKNOWN: + default: + break; + } + } +} + +opj_image_t* OPJ_CALLCONV opj_decode(opj_dinfo_t *dinfo, opj_cio_t *cio) { + return opj_decode_with_info(dinfo, cio, NULL); +} + +opj_image_t* OPJ_CALLCONV opj_decode_with_info(opj_dinfo_t *dinfo, opj_cio_t *cio, opj_codestream_info_t *cstr_info) { + if(dinfo && cio) { + switch(dinfo->codec_format) { + case CODEC_J2K: + return j2k_decode((opj_j2k_t*)dinfo->j2k_handle, cio, cstr_info); + case CODEC_JPT: + return j2k_decode_jpt_stream((opj_j2k_t*)dinfo->j2k_handle, cio, cstr_info); + case CODEC_JP2: + return jp2_decode((opj_jp2_t*)dinfo->jp2_handle, cio, cstr_info); + case CODEC_UNKNOWN: + default: + break; + } + } + return NULL; +} + +opj_cinfo_t* OPJ_CALLCONV opj_create_compress(OPJ_CODEC_FORMAT format) { + opj_cinfo_t *cinfo = (opj_cinfo_t*)opj_malloc(sizeof(opj_cinfo_t)); + if(!cinfo) return NULL; + cinfo->is_decompressor = false; + switch(format) { + case CODEC_J2K: + /* get a J2K coder handle */ + cinfo->j2k_handle = (void*)j2k_create_compress((opj_common_ptr)cinfo); + if(!cinfo->j2k_handle) { + opj_free(cinfo); + return NULL; + } + break; + case CODEC_JP2: + /* get a JP2 coder handle */ + cinfo->jp2_handle = (void*)jp2_create_compress((opj_common_ptr)cinfo); + if(!cinfo->jp2_handle) { + opj_free(cinfo); + return NULL; + } + break; + case CODEC_JPT: + case CODEC_UNKNOWN: + default: + opj_free(cinfo); + return NULL; + } + + cinfo->codec_format = format; + + return cinfo; +} + +void OPJ_CALLCONV opj_destroy_compress(opj_cinfo_t *cinfo) { + if(cinfo) { + /* destroy the codec */ + switch(cinfo->codec_format) { + case CODEC_J2K: + j2k_destroy_compress((opj_j2k_t*)cinfo->j2k_handle); + break; + case CODEC_JP2: + jp2_destroy_compress((opj_jp2_t*)cinfo->jp2_handle); + break; + case CODEC_JPT: + case CODEC_UNKNOWN: + default: + break; + } + /* destroy the decompressor */ + opj_free(cinfo); + } +} + +void OPJ_CALLCONV opj_set_default_encoder_parameters(opj_cparameters_t *parameters) { + if(parameters) { + memset(parameters, 0, sizeof(opj_cparameters_t)); + /* default coding parameters */ + parameters->cp_cinema = OFF; + parameters->max_comp_size = 0; + parameters->numresolution = 6; + parameters->cp_rsiz = STD_RSIZ; + parameters->cblockw_init = 64; + parameters->cblockh_init = 64; + parameters->prog_order = LRCP; + parameters->roi_compno = -1; /* no ROI */ + parameters->subsampling_dx = 1; + parameters->subsampling_dy = 1; + parameters->tp_on = 0; + parameters->decod_format = -1; + parameters->cod_format = -1; +/* UniPG>> */ +#ifdef USE_JPWL + parameters->jpwl_epc_on = false; + parameters->jpwl_hprot_MH = -1; /* -1 means unassigned */ + { + int i; + for (i = 0; i < JPWL_MAX_NO_TILESPECS; i++) { + parameters->jpwl_hprot_TPH_tileno[i] = -1; /* unassigned */ + parameters->jpwl_hprot_TPH[i] = 0; /* absent */ + } + }; + { + int i; + for (i = 0; i < JPWL_MAX_NO_PACKSPECS; i++) { + parameters->jpwl_pprot_tileno[i] = -1; /* unassigned */ + parameters->jpwl_pprot_packno[i] = -1; /* unassigned */ + parameters->jpwl_pprot[i] = 0; /* absent */ + } + }; + parameters->jpwl_sens_size = 0; /* 0 means no ESD */ + parameters->jpwl_sens_addr = 0; /* 0 means auto */ + parameters->jpwl_sens_range = 0; /* 0 means packet */ + parameters->jpwl_sens_MH = -1; /* -1 means unassigned */ + { + int i; + for (i = 0; i < JPWL_MAX_NO_TILESPECS; i++) { + parameters->jpwl_sens_TPH_tileno[i] = -1; /* unassigned */ + parameters->jpwl_sens_TPH[i] = -1; /* absent */ + } + }; +#endif /* USE_JPWL */ +/* <codec_format) { + case CODEC_J2K: + j2k_setup_encoder((opj_j2k_t*)cinfo->j2k_handle, parameters, image); + break; + case CODEC_JP2: + jp2_setup_encoder((opj_jp2_t*)cinfo->jp2_handle, parameters, image); + break; + case CODEC_JPT: + case CODEC_UNKNOWN: + default: + break; + } + } +} + +bool OPJ_CALLCONV opj_encode(opj_cinfo_t *cinfo, opj_cio_t *cio, opj_image_t *image, char *index) { + if (index != NULL) + opj_event_msg((opj_common_ptr)cinfo, EVT_WARNING, "Set index to NULL when calling the opj_encode function.\n" + "To extract the index, use the opj_encode_with_info() function.\n" + "No index will be generated during this encoding\n"); + return opj_encode_with_info(cinfo, cio, image, NULL); +} + +bool OPJ_CALLCONV opj_encode_with_info(opj_cinfo_t *cinfo, opj_cio_t *cio, opj_image_t *image, opj_codestream_info_t *cstr_info) { + if(cinfo && cio && image) { + switch(cinfo->codec_format) { + case CODEC_J2K: + return j2k_encode((opj_j2k_t*)cinfo->j2k_handle, cio, image, cstr_info); + case CODEC_JP2: + return jp2_encode((opj_jp2_t*)cinfo->jp2_handle, cio, image, cstr_info); + case CODEC_JPT: + case CODEC_UNKNOWN: + default: + break; + } + } + return false; +} + +void OPJ_CALLCONV opj_destroy_cstr_info(opj_codestream_info_t *cstr_info) { + if (cstr_info) { + int tileno; + for (tileno = 0; tileno < cstr_info->tw * cstr_info->th; tileno++) { + opj_tile_info_t *tile_info = &cstr_info->tile[tileno]; + opj_free(tile_info->thresh); + opj_free(tile_info->packet); + opj_free(tile_info->tp); + } + opj_free(cstr_info->tile); + opj_free(cstr_info->marker); + } +} diff --git a/extern/libopenjpeg/openjpeg.h b/extern/libopenjpeg/openjpeg.h new file mode 100644 index 00000000000..ffcaacaf6e5 --- /dev/null +++ b/extern/libopenjpeg/openjpeg.h @@ -0,0 +1,911 @@ + /* + * Copyright (c) 2002-2007, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium + * Copyright (c) 2002-2007, Professor Benoit Macq + * Copyright (c) 2001-2003, David Janssens + * Copyright (c) 2002-2003, Yannick Verschueren + * Copyright (c) 2003-2007, Francois-Olivier Devaux and Antonin Descampe + * Copyright (c) 2005, Herve Drolon, FreeImage Team + * Copyright (c) 2006-2007, Parvatha Elangovan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 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. + */ +#ifndef OPENJPEG_H +#define OPENJPEG_H + +#define OPENJPEG_VERSION "1.3.0" + +/* +========================================================== + Compiler directives +========================================================== +*/ + +#if defined(OPJ_STATIC) || !(defined(WIN32) || defined(__WIN32__)) +#define OPJ_API +#define OPJ_CALLCONV +#else +#define OPJ_CALLCONV __stdcall +/* +The following ifdef block is the standard way of creating macros which make exporting +from a DLL simpler. All files within this DLL are compiled with the OPJ_EXPORTS +symbol defined on the command line. this symbol should not be defined on any project +that uses this DLL. This way any other project whose source files include this file see +OPJ_API functions as being imported from a DLL, wheras this DLL sees symbols +defined with this macro as being exported. +*/ +#ifdef OPJ_EXPORTS +#define OPJ_API __declspec(dllexport) +#else +#define OPJ_API __declspec(dllimport) +#endif /* OPJ_EXPORTS */ +#endif /* !OPJ_STATIC || !WIN32 */ + +#ifndef __cplusplus +#if defined(HAVE_STDBOOL_H) +/* +The C language implementation does correctly provide the standard header +file "stdbool.h". + */ +#include +#else +/* +The C language implementation does not provide the standard header file +"stdbool.h" as required by ISO/IEC 9899:1999. Try to compensate for this +braindamage below. +*/ +#if !defined(bool) +#define bool int +#endif +#if !defined(true) +#define true 1 +#endif +#if !defined(false) +#define false 0 +#endif +#endif +#endif /* __cplusplus */ + +/* +========================================================== + Useful constant definitions +========================================================== +*/ + +#define OPJ_PATH_LEN 4096 /**< Maximum allowed size for filenames */ + +#define J2K_MAXRLVLS 33 /**< Number of maximum resolution level authorized */ +#define J2K_MAXBANDS (3*J2K_MAXRLVLS-2) /**< Number of maximum sub-band linked to number of resolution level */ + +/* UniPG>> */ +#define JPWL_MAX_NO_TILESPECS 16 /**< Maximum number of tile parts expected by JPWL: increase at your will */ +#define JPWL_MAX_NO_PACKSPECS 16 /**< Maximum number of packet parts expected by JPWL: increase at your will */ +#define JPWL_MAX_NO_MARKERS 512 /**< Maximum number of JPWL markers: increase at your will */ +#define JPWL_PRIVATEINDEX_NAME "jpwl_index_privatefilename" /**< index file name used when JPWL is on */ +#define JPWL_EXPECTED_COMPONENTS 3 /**< Expect this number of components, so you'll find better the first EPB */ +#define JPWL_MAXIMUM_TILES 8192 /**< Expect this maximum number of tiles, to avoid some crashes */ +#define JPWL_MAXIMUM_HAMMING 2 /**< Expect this maximum number of bit errors in marker id's */ +#define JPWL_MAXIMUM_EPB_ROOM 65450 /**< Expect this maximum number of bytes for composition of EPBs */ +/* < +
  • Error messages +
  • Warning messages +
  • Debugging messages + +*/ +typedef struct opj_event_mgr { + /** Error message callback if available, NULL otherwise */ + opj_msg_callback error_handler; + /** Warning message callback if available, NULL otherwise */ + opj_msg_callback warning_handler; + /** Debug message callback if available, NULL otherwise */ + opj_msg_callback info_handler; +} opj_event_mgr_t; + + +/* +========================================================== + codec typedef definitions +========================================================== +*/ + +/** +Progression order changes +*/ +typedef struct opj_poc { + /** Resolution num start, Component num start, given by POC */ + int resno0, compno0; + /** Layer num end,Resolution num end, Component num end, given by POC */ + int layno1, resno1, compno1; + /** Layer num start,Precinct num start, Precinct num end */ + int layno0, precno0, precno1; + /** Progression order enum*/ + OPJ_PROG_ORDER prg1,prg; + /** Progression order string*/ + char progorder[5]; + /** Tile number */ + int tile; + /** Start and end values for Tile width and height*/ + int tx0,tx1,ty0,ty1; + /** Start value, initialised in pi_initialise_encode*/ + int layS, resS, compS, prcS; + /** End value, initialised in pi_initialise_encode */ + int layE, resE, compE, prcE; + /** Start and end values of Tile width and height, initialised in pi_initialise_encode*/ + int txS,txE,tyS,tyE,dx,dy; + /** Temporary values for Tile parts, initialised in pi_create_encode */ + int lay_t, res_t, comp_t, prc_t,tx0_t,ty0_t; +} opj_poc_t; + +/** +Compression parameters +*/ +typedef struct opj_cparameters { + /** size of tile: tile_size_on = false (not in argument) or = true (in argument) */ + bool tile_size_on; + /** XTOsiz */ + int cp_tx0; + /** YTOsiz */ + int cp_ty0; + /** XTsiz */ + int cp_tdx; + /** YTsiz */ + int cp_tdy; + /** allocation by rate/distortion */ + int cp_disto_alloc; + /** allocation by fixed layer */ + int cp_fixed_alloc; + /** add fixed_quality */ + int cp_fixed_quality; + /** fixed layer */ + int *cp_matrice; + /** comment for coding */ + char *cp_comment; + /** csty : coding style */ + int csty; + /** progression order (default LRCP) */ + OPJ_PROG_ORDER prog_order; + /** progression order changes */ + opj_poc_t POC[32]; + /** number of progression order changes (POC), default to 0 */ + int numpocs; + /** number of layers */ + int tcp_numlayers; + /** rates of layers */ + float tcp_rates[100]; + /** different psnr for successive layers */ + float tcp_distoratio[100]; + /** number of resolutions */ + int numresolution; + /** initial code block width, default to 64 */ + int cblockw_init; + /** initial code block height, default to 64 */ + int cblockh_init; + /** mode switch (cblk_style) */ + int mode; + /** 1 : use the irreversible DWT 9-7, 0 : use lossless compression (default) */ + int irreversible; + /** region of interest: affected component in [0..3], -1 means no ROI */ + int roi_compno; + /** region of interest: upshift value */ + int roi_shift; + /* number of precinct size specifications */ + int res_spec; + /** initial precinct width */ + int prcw_init[J2K_MAXRLVLS]; + /** initial precinct height */ + int prch_init[J2K_MAXRLVLS]; + + /**@name command line encoder parameters (not used inside the library) */ + /*@{*/ + /** input file name */ + char infile[OPJ_PATH_LEN]; + /** output file name */ + char outfile[OPJ_PATH_LEN]; + /** DEPRECATED. Index generation is now handeld with the opj_encode_with_info() function. Set to NULL */ + int index_on; + /** DEPRECATED. Index generation is now handeld with the opj_encode_with_info() function. Set to NULL */ + char index[OPJ_PATH_LEN]; + /** subimage encoding: origin image offset in x direction */ + int image_offset_x0; + /** subimage encoding: origin image offset in y direction */ + int image_offset_y0; + /** subsampling value for dx */ + int subsampling_dx; + /** subsampling value for dy */ + int subsampling_dy; + /** input file format 0: PGX, 1: PxM, 2: BMP 3:TIF*/ + int decod_format; + /** output file format 0: J2K, 1: JP2, 2: JPT */ + int cod_format; + /*@}*/ + +/* UniPG>> */ + /**@name JPWL encoding parameters */ + /*@{*/ + /** enables writing of EPC in MH, thus activating JPWL */ + bool jpwl_epc_on; + /** error protection method for MH (0,1,16,32,37-128) */ + int jpwl_hprot_MH; + /** tile number of header protection specification (>=0) */ + int jpwl_hprot_TPH_tileno[JPWL_MAX_NO_TILESPECS]; + /** error protection methods for TPHs (0,1,16,32,37-128) */ + int jpwl_hprot_TPH[JPWL_MAX_NO_TILESPECS]; + /** tile number of packet protection specification (>=0) */ + int jpwl_pprot_tileno[JPWL_MAX_NO_PACKSPECS]; + /** packet number of packet protection specification (>=0) */ + int jpwl_pprot_packno[JPWL_MAX_NO_PACKSPECS]; + /** error protection methods for packets (0,1,16,32,37-128) */ + int jpwl_pprot[JPWL_MAX_NO_PACKSPECS]; + /** enables writing of ESD, (0=no/1/2 bytes) */ + int jpwl_sens_size; + /** sensitivity addressing size (0=auto/2/4 bytes) */ + int jpwl_sens_addr; + /** sensitivity range (0-3) */ + int jpwl_sens_range; + /** sensitivity method for MH (-1=no,0-7) */ + int jpwl_sens_MH; + /** tile number of sensitivity specification (>=0) */ + int jpwl_sens_TPH_tileno[JPWL_MAX_NO_TILESPECS]; + /** sensitivity methods for TPHs (-1=no,0-7) */ + int jpwl_sens_TPH[JPWL_MAX_NO_TILESPECS]; + /*@}*/ +/* <> */ + /**@name JPWL decoding parameters */ + /*@{*/ + /** activates the JPWL correction capabilities */ + bool jpwl_correct; + /** expected number of components */ + int jpwl_exp_comps; + /** maximum number of tiles */ + int jpwl_max_tiles; + /*@}*/ +/* <> */ +/** +Marker structure +*/ +typedef struct opj_marker_info_t { + /** marker type */ + unsigned short int type; + /** position in codestream */ + int pos; + /** length, marker val included */ + int len; +} opj_marker_info_t; +/* <> */ + /** number of markers */ + int marknum; + /** list of markers */ + opj_marker_info_t *marker; + /** actual size of markers array */ + int maxmarknum; +/* <cp. +@param dinfo decompressor handle +@param parameters decompression parameters +*/ +OPJ_API void OPJ_CALLCONV opj_setup_decoder(opj_dinfo_t *dinfo, opj_dparameters_t *parameters); +/** +Decode an image from a JPEG-2000 codestream +@param dinfo decompressor handle +@param cio Input buffer stream +@return Returns a decoded image if successful, returns NULL otherwise +*/ +OPJ_API opj_image_t* OPJ_CALLCONV opj_decode(opj_dinfo_t *dinfo, opj_cio_t *cio); + +/** +Decode an image from a JPEG-2000 codestream and extract the codestream information +@param dinfo decompressor handle +@param cio Input buffer stream +@param cstr_info Codestream information structure if needed afterwards, NULL otherwise +@return Returns a decoded image if successful, returns NULL otherwise +*/ +OPJ_API opj_image_t* OPJ_CALLCONV opj_decode_with_info(opj_dinfo_t *dinfo, opj_cio_t *cio, opj_codestream_info_t *cstr_info); +/** +Creates a J2K/JP2 compression structure +@param format Coder to select +@return Returns a handle to a compressor if successful, returns NULL otherwise +*/ +OPJ_API opj_cinfo_t* OPJ_CALLCONV opj_create_compress(OPJ_CODEC_FORMAT format); +/** +Destroy a compressor handle +@param cinfo compressor handle to destroy +*/ +OPJ_API void OPJ_CALLCONV opj_destroy_compress(opj_cinfo_t *cinfo); +/** +Set encoding parameters to default values, that means : +
      +
    • Lossless +
    • 1 tile +
    • Size of precinct : 2^15 x 2^15 (means 1 precinct) +
    • Size of code-block : 64 x 64 +
    • Number of resolutions: 6 +
    • No SOP marker in the codestream +
    • No EPH marker in the codestream +
    • No sub-sampling in x or y direction +
    • No mode switch activated +
    • Progression order: LRCP +
    • No index file +
    • No ROI upshifted +
    • No offset of the origin of the image +
    • No offset of the origin of the tiles +
    • Reversible DWT 5-3 +
    +@param parameters Compression parameters +*/ +OPJ_API void OPJ_CALLCONV opj_set_default_encoder_parameters(opj_cparameters_t *parameters); +/** +Setup the encoder parameters using the current image and using user parameters. +@param cinfo Compressor handle +@param parameters Compression parameters +@param image Input filled image +*/ +OPJ_API void OPJ_CALLCONV opj_setup_encoder(opj_cinfo_t *cinfo, opj_cparameters_t *parameters, opj_image_t *image); +/** +Encode an image into a JPEG-2000 codestream +@param cinfo compressor handle +@param cio Output buffer stream +@param image Image to encode +@param index Depreacted -> Set to NULL. To extract index, used opj_encode_wci() +@return Returns true if successful, returns false otherwise +*/ +OPJ_API bool OPJ_CALLCONV opj_encode(opj_cinfo_t *cinfo, opj_cio_t *cio, opj_image_t *image, char *index); +/** +Encode an image into a JPEG-2000 codestream and extract the codestream information +@param cinfo compressor handle +@param cio Output buffer stream +@param image Image to encode +@param cstr_info Codestream information structure if needed afterwards, NULL otherwise +@return Returns true if successful, returns false otherwise +*/ +OPJ_API bool OPJ_CALLCONV opj_encode_with_info(opj_cinfo_t *cinfo, opj_cio_t *cio, opj_image_t *image, opj_codestream_info_t *cstr_info); +/** +Destroy Codestream information after compression or decompression +@param cstr_info Codestream information structure +*/ +OPJ_API void OPJ_CALLCONV opj_destroy_cstr_info(opj_codestream_info_t *cstr_info); + +#ifdef __cplusplus +} +#endif + +#endif /* OPENJPEG_H */ diff --git a/extern/libopenjpeg/opj_includes.h b/extern/libopenjpeg/opj_includes.h new file mode 100644 index 00000000000..80d43df990f --- /dev/null +++ b/extern/libopenjpeg/opj_includes.h @@ -0,0 +1,132 @@ +/* + * Copyright (c) 2005, Hervé Drolon, FreeImage Team + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 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. + */ +#ifndef OPJ_INCLUDES_H +#define OPJ_INCLUDES_H + +/* + ========================================================== + Standard includes used by the library + ========================================================== +*/ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + ========================================================== + OpenJPEG interface + ========================================================== + */ +#include "openjpeg.h" + +/* + ========================================================== + OpenJPEG modules + ========================================================== +*/ + +/* Ignore GCC attributes if this is not GCC */ +#ifndef __GNUC__ + #define __attribute__(x) /* __attribute__(x) */ +#endif + +/* +The inline keyword is supported by C99 but not by C90. +Most compilers implement their own version of this keyword ... +*/ +#ifndef INLINE + #if defined(_MSC_VER) + #define INLINE __inline + #elif defined(__GNUC__) + #define INLINE __inline__ + #elif defined(__MWERKS__) + #define INLINE inline + #else + /* add other compilers here ... */ + #define INLINE + #endif /* defined() */ +#endif /* INLINE */ + +/* Are restricted pointers available? (C99) */ +#if (__STDC_VERSION__ != 199901L) + /* Not a C99 compiler */ + #ifdef __GNUC__ + #define restrict __restrict__ + #else + #define restrict /* restrict */ + #endif +#endif + +/* MSVC does not have lrintf */ +#ifdef _MSC_VER +static INLINE long lrintf(float f){ + int i; + + _asm{ + fld f + fistp i + }; + + return i; +} +#endif + +#include "j2k_lib.h" +#include "opj_malloc.h" +#include "event.h" +#include "cio.h" + +#include "image.h" +#include "j2k.h" +#include "jp2.h" +#include "jpt.h" + +#include "mqc.h" +#include "raw.h" +#include "bio.h" +#include "tgt.h" +#include "pi.h" +#include "tcd.h" +#include "t1.h" +#include "dwt.h" +#include "t2.h" +#include "mct.h" +#include "int.h" +#include "fix.h" + +/* JPWL>> */ +#ifdef USE_JPWL +#include "../jpwl/jpwl.h" +#endif /* USE_JPWL */ +/* < + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 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. + */ +#ifndef __OPJ_MALLOC_H +#define __OPJ_MALLOC_H +/** +@file opj_malloc.h +@brief Internal functions + +The functions in opj_malloc.h are internal utilities used for memory management. +*/ + +/** @defgroup MISC MISC - Miscellaneous internal functions */ +/*@{*/ + +/** @name Exported functions */ +/*@{*/ +/* ----------------------------------------------------------------------- */ + +/** +Allocate an uninitialized memory block +@param size Bytes to allocate +@return Returns a void pointer to the allocated space, or NULL if there is insufficient memory available +*/ +#define opj_malloc(size) malloc(size) + +/** +Allocate a memory block with elements initialized to 0 +@param num Blocks to allocate +@param size Bytes per block to allocate +@return Returns a void pointer to the allocated space, or NULL if there is insufficient memory available +*/ +#define opj_calloc(num, size) calloc(num, size) + +/** +Allocate memory aligned to a 16 byte boundry +@param size Bytes to allocate +@return Returns a void pointer to the allocated space, or NULL if there is insufficient memory available +*/ +/* FIXME: These should be set with cmake tests, but we're currently not requiring use of cmake */ +#ifdef WIN32 + /* Someone should tell the mingw people that their malloc.h ought to provide _mm_malloc() */ + #ifdef __GNUC__ + #include + #define HAVE_MM_MALLOC + #else /* MSVC, Intel C++ */ + #include + #ifdef _mm_malloc + #define HAVE_MM_MALLOC + #endif + #endif +#else /* Not WIN32 */ + #if defined(__sun) + #define HAVE_MEMALIGN + #elif defined(__GNUC__) + #define HAVE_MEMALIGN + #include + /* Linux x86_64 and OSX always align allocations to 16 bytes */ + #elif !defined(__amd64__) && !defined(__APPLE__) + /* FIXME: Yes, this is a big assumption */ + #define HAVE_POSIX_MEMALIGN + #endif +#endif + + + +#define opj_aligned_malloc(size) malloc(size) +#define opj_aligned_free(m) free(m) + +#ifdef HAVE_MM_MALLOC + #undef opj_aligned_malloc + #define opj_aligned_malloc(size) _mm_malloc(size, 16) + #undef opj_aligned_free + #define opj_aligned_free(m) _mm_free(m) +#endif + +#ifdef HAVE_MEMALIGN + extern void* memalign(size_t, size_t); + #undef opj_aligned_malloc + #define opj_aligned_malloc(size) memalign(16, (size)) + #undef opj_aligned_free + #define opj_aligned_free(m) free(m) +#endif + +#ifdef HAVE_POSIX_MEMALIGN + #undef opj_aligned_malloc + extern int posix_memalign(void**, size_t, size_t); + + static INLINE void* __attribute__ ((malloc)) opj_aligned_malloc(size_t size){ + void* mem = NULL; + posix_memalign(&mem, 16, size); + return mem; + } + #undef opj_aligned_free + #define opj_aligned_free(m) free(m) +#endif + +/** +Reallocate memory blocks. +@param memblock Pointer to previously allocated memory block +@param size New size in bytes +@return Returns a void pointer to the reallocated (and possibly moved) memory block +*/ +#define opj_realloc(m, s) realloc(m, s) + +/** +Deallocates or frees a memory block. +@param memblock Previously allocated memory block to be freed +*/ +#define opj_free(m) free(m) + +#ifdef __GNUC__ +#pragma GCC poison malloc calloc realloc free +#endif + +/* ----------------------------------------------------------------------- */ +/*@}*/ + +/*@}*/ + +#endif /* __OPJ_MALLOC_H */ + diff --git a/extern/libopenjpeg/pi.c b/extern/libopenjpeg/pi.c new file mode 100644 index 00000000000..ac7654c5f14 --- /dev/null +++ b/extern/libopenjpeg/pi.c @@ -0,0 +1,963 @@ +/* + * Copyright (c) 2002-2007, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium + * Copyright (c) 2002-2007, Professor Benoit Macq + * Copyright (c) 2001-2003, David Janssens + * Copyright (c) 2002-2003, Yannick Verschueren + * Copyright (c) 2003-2007, Francois-Olivier Devaux and Antonin Descampe + * Copyright (c) 2005, Herve Drolon, FreeImage Team + * Copyright (c) 2006-2007, Parvatha Elangovan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 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. + */ + +#include "opj_includes.h" + +/** @defgroup PI PI - Implementation of a packet iterator */ +/*@{*/ + +/** @name Local static functions */ +/*@{*/ + +/** +Get next packet in layer-resolution-component-precinct order. +@param pi packet iterator to modify +@return returns false if pi pointed to the last packet or else returns true +*/ +static bool pi_next_lrcp(opj_pi_iterator_t * pi); +/** +Get next packet in resolution-layer-component-precinct order. +@param pi packet iterator to modify +@return returns false if pi pointed to the last packet or else returns true +*/ +static bool pi_next_rlcp(opj_pi_iterator_t * pi); +/** +Get next packet in resolution-precinct-component-layer order. +@param pi packet iterator to modify +@return returns false if pi pointed to the last packet or else returns true +*/ +static bool pi_next_rpcl(opj_pi_iterator_t * pi); +/** +Get next packet in precinct-component-resolution-layer order. +@param pi packet iterator to modify +@return returns false if pi pointed to the last packet or else returns true +*/ +static bool pi_next_pcrl(opj_pi_iterator_t * pi); +/** +Get next packet in component-precinct-resolution-layer order. +@param pi packet iterator to modify +@return returns false if pi pointed to the last packet or else returns true +*/ +static bool pi_next_cprl(opj_pi_iterator_t * pi); + +/*@}*/ + +/*@}*/ + +/* +========================================================== + local functions +========================================================== +*/ + +static bool pi_next_lrcp(opj_pi_iterator_t * pi) { + opj_pi_comp_t *comp = NULL; + opj_pi_resolution_t *res = NULL; + long index = 0; + + if (!pi->first) { + comp = &pi->comps[pi->compno]; + res = &comp->resolutions[pi->resno]; + goto LABEL_SKIP; + } else { + pi->first = 0; + } + + for (pi->layno = pi->poc.layno0; pi->layno < pi->poc.layno1; pi->layno++) { + for (pi->resno = pi->poc.resno0; pi->resno < pi->poc.resno1; + pi->resno++) { + for (pi->compno = pi->poc.compno0; pi->compno < pi->poc.compno1; pi->compno++) { + comp = &pi->comps[pi->compno]; + if (pi->resno >= comp->numresolutions) { + continue; + } + res = &comp->resolutions[pi->resno]; + if (!pi->tp_on){ + pi->poc.precno1 = res->pw * res->ph; + } + for (pi->precno = pi->poc.precno0; pi->precno < pi->poc.precno1; pi->precno++) { + index = pi->layno * pi->step_l + pi->resno * pi->step_r + pi->compno * pi->step_c + pi->precno * pi->step_p; + if (!pi->include[index]) { + pi->include[index] = 1; + return true; + } +LABEL_SKIP:; + } + } + } + } + + return false; +} + +static bool pi_next_rlcp(opj_pi_iterator_t * pi) { + opj_pi_comp_t *comp = NULL; + opj_pi_resolution_t *res = NULL; + long index = 0; + + if (!pi->first) { + comp = &pi->comps[pi->compno]; + res = &comp->resolutions[pi->resno]; + goto LABEL_SKIP; + } else { + pi->first = 0; + } + + for (pi->resno = pi->poc.resno0; pi->resno < pi->poc.resno1; pi->resno++) { + for (pi->layno = pi->poc.layno0; pi->layno < pi->poc.layno1; pi->layno++) { + for (pi->compno = pi->poc.compno0; pi->compno < pi->poc.compno1; pi->compno++) { + comp = &pi->comps[pi->compno]; + if (pi->resno >= comp->numresolutions) { + continue; + } + res = &comp->resolutions[pi->resno]; + if(!pi->tp_on){ + pi->poc.precno1 = res->pw * res->ph; + } + for (pi->precno = pi->poc.precno0; pi->precno < pi->poc.precno1; pi->precno++) { + index = pi->layno * pi->step_l + pi->resno * pi->step_r + pi->compno * pi->step_c + pi->precno * pi->step_p; + if (!pi->include[index]) { + pi->include[index] = 1; + return true; + } +LABEL_SKIP:; + } + } + } + } + + return false; +} + +static bool pi_next_rpcl(opj_pi_iterator_t * pi) { + opj_pi_comp_t *comp = NULL; + opj_pi_resolution_t *res = NULL; + long index = 0; + + if (!pi->first) { + goto LABEL_SKIP; + } else { + int compno, resno; + pi->first = 0; + pi->dx = 0; + pi->dy = 0; + for (compno = 0; compno < pi->numcomps; compno++) { + comp = &pi->comps[compno]; + for (resno = 0; resno < comp->numresolutions; resno++) { + int dx, dy; + res = &comp->resolutions[resno]; + dx = comp->dx * (1 << (res->pdx + comp->numresolutions - 1 - resno)); + dy = comp->dy * (1 << (res->pdy + comp->numresolutions - 1 - resno)); + pi->dx = !pi->dx ? dx : int_min(pi->dx, dx); + pi->dy = !pi->dy ? dy : int_min(pi->dy, dy); + } + } + } +if (!pi->tp_on){ + pi->poc.ty0 = pi->ty0; + pi->poc.tx0 = pi->tx0; + pi->poc.ty1 = pi->ty1; + pi->poc.tx1 = pi->tx1; + } + for (pi->resno = pi->poc.resno0; pi->resno < pi->poc.resno1; pi->resno++) { + for (pi->y = pi->poc.ty0; pi->y < pi->poc.ty1; pi->y += pi->dy - (pi->y % pi->dy)) { + for (pi->x = pi->poc.tx0; pi->x < pi->poc.tx1; pi->x += pi->dx - (pi->x % pi->dx)) { + for (pi->compno = pi->poc.compno0; pi->compno < pi->poc.compno1; pi->compno++) { + int levelno; + int trx0, try0; + int trx1, try1; + int rpx, rpy; + int prci, prcj; + comp = &pi->comps[pi->compno]; + if (pi->resno >= comp->numresolutions) { + continue; + } + res = &comp->resolutions[pi->resno]; + levelno = comp->numresolutions - 1 - pi->resno; + trx0 = int_ceildiv(pi->tx0, comp->dx << levelno); + try0 = int_ceildiv(pi->ty0, comp->dy << levelno); + trx1 = int_ceildiv(pi->tx1, comp->dx << levelno); + try1 = int_ceildiv(pi->ty1, comp->dy << levelno); + rpx = res->pdx + levelno; + rpy = res->pdy + levelno; + if (!((pi->y % (comp->dy << rpy) == 0) || ((pi->y == pi->ty0) && ((try0 << levelno) % (1 << rpx))))){ + continue; + } + if (!((pi->x % (comp->dx << rpx) == 0) || ((pi->x == pi->tx0) && ((trx0 << levelno) % (1 << rpx))))){ + continue; + } + + if ((res->pw==0)||(res->pw==0)) continue; + + if ((trx0==trx1)||(try0==try1)) continue; + + prci = int_floordivpow2(int_ceildiv(pi->x, comp->dx << levelno), res->pdx) + - int_floordivpow2(trx0, res->pdx); + prcj = int_floordivpow2(int_ceildiv(pi->y, comp->dy << levelno), res->pdy) + - int_floordivpow2(try0, res->pdy); + pi->precno = prci + prcj * res->pw; + for (pi->layno = pi->poc.layno0; pi->layno < pi->poc.layno1; pi->layno++) { + index = pi->layno * pi->step_l + pi->resno * pi->step_r + pi->compno * pi->step_c + pi->precno * pi->step_p; + if (!pi->include[index]) { + pi->include[index] = 1; + return true; + } +LABEL_SKIP:; + } + } + } + } + } + + return false; +} + +static bool pi_next_pcrl(opj_pi_iterator_t * pi) { + opj_pi_comp_t *comp = NULL; + opj_pi_resolution_t *res = NULL; + long index = 0; + + if (!pi->first) { + comp = &pi->comps[pi->compno]; + goto LABEL_SKIP; + } else { + int compno, resno; + pi->first = 0; + pi->dx = 0; + pi->dy = 0; + for (compno = 0; compno < pi->numcomps; compno++) { + comp = &pi->comps[compno]; + for (resno = 0; resno < comp->numresolutions; resno++) { + int dx, dy; + res = &comp->resolutions[resno]; + dx = comp->dx * (1 << (res->pdx + comp->numresolutions - 1 - resno)); + dy = comp->dy * (1 << (res->pdy + comp->numresolutions - 1 - resno)); + pi->dx = !pi->dx ? dx : int_min(pi->dx, dx); + pi->dy = !pi->dy ? dy : int_min(pi->dy, dy); + } + } + } + if (!pi->tp_on){ + pi->poc.ty0 = pi->ty0; + pi->poc.tx0 = pi->tx0; + pi->poc.ty1 = pi->ty1; + pi->poc.tx1 = pi->tx1; + } + for (pi->y = pi->poc.ty0; pi->y < pi->poc.ty1; pi->y += pi->dy - (pi->y % pi->dy)) { + for (pi->x = pi->poc.tx0; pi->x < pi->poc.tx1; pi->x += pi->dx - (pi->x % pi->dx)) { + for (pi->compno = pi->poc.compno0; pi->compno < pi->poc.compno1; pi->compno++) { + comp = &pi->comps[pi->compno]; + for (pi->resno = pi->poc.resno0; pi->resno < int_min(pi->poc.resno1, comp->numresolutions); pi->resno++) { + int levelno; + int trx0, try0; + int trx1, try1; + int rpx, rpy; + int prci, prcj; + res = &comp->resolutions[pi->resno]; + levelno = comp->numresolutions - 1 - pi->resno; + trx0 = int_ceildiv(pi->tx0, comp->dx << levelno); + try0 = int_ceildiv(pi->ty0, comp->dy << levelno); + trx1 = int_ceildiv(pi->tx1, comp->dx << levelno); + try1 = int_ceildiv(pi->ty1, comp->dy << levelno); + rpx = res->pdx + levelno; + rpy = res->pdy + levelno; + if (!((pi->y % (comp->dy << rpy) == 0) || ((pi->y == pi->ty0) && ((try0 << levelno) % (1 << rpx))))){ + continue; + } + if (!((pi->x % (comp->dx << rpx) == 0) || ((pi->x == pi->tx0) && ((trx0 << levelno) % (1 << rpx))))){ + continue; + } + + if ((res->pw==0)||(res->pw==0)) continue; + + if ((trx0==trx1)||(try0==try1)) continue; + + prci = int_floordivpow2(int_ceildiv(pi->x, comp->dx << levelno), res->pdx) + - int_floordivpow2(trx0, res->pdx); + prcj = int_floordivpow2(int_ceildiv(pi->y, comp->dy << levelno), res->pdy) + - int_floordivpow2(try0, res->pdy); + pi->precno = prci + prcj * res->pw; + for (pi->layno = pi->poc.layno0; pi->layno < pi->poc.layno1; pi->layno++) { + index = pi->layno * pi->step_l + pi->resno * pi->step_r + pi->compno * pi->step_c + pi->precno * pi->step_p; + if (!pi->include[index]) { + pi->include[index] = 1; + return true; + } +LABEL_SKIP:; + } + } + } + } + } + + return false; +} + +static bool pi_next_cprl(opj_pi_iterator_t * pi) { + opj_pi_comp_t *comp = NULL; + opj_pi_resolution_t *res = NULL; + long index = 0; + + if (!pi->first) { + comp = &pi->comps[pi->compno]; + goto LABEL_SKIP; + } else { + pi->first = 0; + } + + for (pi->compno = pi->poc.compno0; pi->compno < pi->poc.compno1; pi->compno++) { + int resno; + comp = &pi->comps[pi->compno]; + pi->dx = 0; + pi->dy = 0; + for (resno = 0; resno < comp->numresolutions; resno++) { + int dx, dy; + res = &comp->resolutions[resno]; + dx = comp->dx * (1 << (res->pdx + comp->numresolutions - 1 - resno)); + dy = comp->dy * (1 << (res->pdy + comp->numresolutions - 1 - resno)); + pi->dx = !pi->dx ? dx : int_min(pi->dx, dx); + pi->dy = !pi->dy ? dy : int_min(pi->dy, dy); + } + if (!pi->tp_on){ + pi->poc.ty0 = pi->ty0; + pi->poc.tx0 = pi->tx0; + pi->poc.ty1 = pi->ty1; + pi->poc.tx1 = pi->tx1; + } + for (pi->y = pi->poc.ty0; pi->y < pi->poc.ty1; pi->y += pi->dy - (pi->y % pi->dy)) { + for (pi->x = pi->poc.tx0; pi->x < pi->poc.tx1; pi->x += pi->dx - (pi->x % pi->dx)) { + for (pi->resno = pi->poc.resno0; pi->resno < int_min(pi->poc.resno1, comp->numresolutions); pi->resno++) { + int levelno; + int trx0, try0; + int trx1, try1; + int rpx, rpy; + int prci, prcj; + res = &comp->resolutions[pi->resno]; + levelno = comp->numresolutions - 1 - pi->resno; + trx0 = int_ceildiv(pi->tx0, comp->dx << levelno); + try0 = int_ceildiv(pi->ty0, comp->dy << levelno); + trx1 = int_ceildiv(pi->tx1, comp->dx << levelno); + try1 = int_ceildiv(pi->ty1, comp->dy << levelno); + rpx = res->pdx + levelno; + rpy = res->pdy + levelno; + if (!((pi->y % (comp->dy << rpy) == 0) || ((pi->y == pi->ty0) && ((try0 << levelno) % (1 << rpx))))){ + continue; + } + if (!((pi->x % (comp->dx << rpx) == 0) || ((pi->x == pi->tx0) && ((trx0 << levelno) % (1 << rpx))))){ + continue; + } + + if ((res->pw==0)||(res->pw==0)) continue; + + if ((trx0==trx1)||(try0==try1)) continue; + + prci = int_floordivpow2(int_ceildiv(pi->x, comp->dx << levelno), res->pdx) + - int_floordivpow2(trx0, res->pdx); + prcj = int_floordivpow2(int_ceildiv(pi->y, comp->dy << levelno), res->pdy) + - int_floordivpow2(try0, res->pdy); + pi->precno = prci + prcj * res->pw; + for (pi->layno = pi->poc.layno0; pi->layno < pi->poc.layno1; pi->layno++) { + index = pi->layno * pi->step_l + pi->resno * pi->step_r + pi->compno * pi->step_c + pi->precno * pi->step_p; + if (!pi->include[index]) { + pi->include[index] = 1; + return true; + } +LABEL_SKIP:; + } + } + } + } + } + + return false; +} + +/* +========================================================== + Packet iterator interface +========================================================== +*/ + +opj_pi_iterator_t *pi_create_decode(opj_image_t *image, opj_cp_t *cp, int tileno) { + int p, q; + int compno, resno, pino; + opj_pi_iterator_t *pi = NULL; + opj_tcp_t *tcp = NULL; + opj_tccp_t *tccp = NULL; + + tcp = &cp->tcps[tileno]; + + pi = (opj_pi_iterator_t*) opj_calloc((tcp->numpocs + 1), sizeof(opj_pi_iterator_t)); + if(!pi) { + /* TODO: throw an error */ + return NULL; + } + + for (pino = 0; pino < tcp->numpocs + 1; pino++) { /* change */ + int maxres = 0; + int maxprec = 0; + p = tileno % cp->tw; + q = tileno / cp->tw; + + pi[pino].tx0 = int_max(cp->tx0 + p * cp->tdx, image->x0); + pi[pino].ty0 = int_max(cp->ty0 + q * cp->tdy, image->y0); + pi[pino].tx1 = int_min(cp->tx0 + (p + 1) * cp->tdx, image->x1); + pi[pino].ty1 = int_min(cp->ty0 + (q + 1) * cp->tdy, image->y1); + pi[pino].numcomps = image->numcomps; + + pi[pino].comps = (opj_pi_comp_t*) opj_calloc(image->numcomps, sizeof(opj_pi_comp_t)); + if(!pi[pino].comps) { + /* TODO: throw an error */ + pi_destroy(pi, cp, tileno); + return NULL; + } + + for (compno = 0; compno < pi->numcomps; compno++) { + int tcx0, tcy0, tcx1, tcy1; + opj_pi_comp_t *comp = &pi[pino].comps[compno]; + tccp = &tcp->tccps[compno]; + comp->dx = image->comps[compno].dx; + comp->dy = image->comps[compno].dy; + comp->numresolutions = tccp->numresolutions; + + comp->resolutions = (opj_pi_resolution_t*) opj_calloc(comp->numresolutions, sizeof(opj_pi_resolution_t)); + if(!comp->resolutions) { + /* TODO: throw an error */ + pi_destroy(pi, cp, tileno); + return NULL; + } + + tcx0 = int_ceildiv(pi->tx0, comp->dx); + tcy0 = int_ceildiv(pi->ty0, comp->dy); + tcx1 = int_ceildiv(pi->tx1, comp->dx); + tcy1 = int_ceildiv(pi->ty1, comp->dy); + if (comp->numresolutions > maxres) { + maxres = comp->numresolutions; + } + + for (resno = 0; resno < comp->numresolutions; resno++) { + int levelno; + int rx0, ry0, rx1, ry1; + int px0, py0, px1, py1; + opj_pi_resolution_t *res = &comp->resolutions[resno]; + if (tccp->csty & J2K_CCP_CSTY_PRT) { + res->pdx = tccp->prcw[resno]; + res->pdy = tccp->prch[resno]; + } else { + res->pdx = 15; + res->pdy = 15; + } + levelno = comp->numresolutions - 1 - resno; + rx0 = int_ceildivpow2(tcx0, levelno); + ry0 = int_ceildivpow2(tcy0, levelno); + rx1 = int_ceildivpow2(tcx1, levelno); + ry1 = int_ceildivpow2(tcy1, levelno); + px0 = int_floordivpow2(rx0, res->pdx) << res->pdx; + py0 = int_floordivpow2(ry0, res->pdy) << res->pdy; + px1 = int_ceildivpow2(rx1, res->pdx) << res->pdx; + py1 = int_ceildivpow2(ry1, res->pdy) << res->pdy; + res->pw = (rx0==rx1)?0:((px1 - px0) >> res->pdx); + res->ph = (ry0==ry1)?0:((py1 - py0) >> res->pdy); + + if (res->pw*res->ph > maxprec) { + maxprec = res->pw*res->ph; + } + + } + } + + tccp = &tcp->tccps[0]; + pi[pino].step_p = 1; + pi[pino].step_c = maxprec * pi[pino].step_p; + pi[pino].step_r = image->numcomps * pi[pino].step_c; + pi[pino].step_l = maxres * pi[pino].step_r; + + if (pino == 0) { + pi[pino].include = (short int*) opj_calloc(image->numcomps * maxres * tcp->numlayers * maxprec, sizeof(short int)); + if(!pi[pino].include) { + /* TODO: throw an error */ + pi_destroy(pi, cp, tileno); + return NULL; + } + } + else { + pi[pino].include = pi[pino - 1].include; + } + + if (tcp->POC == 0) { + pi[pino].first = 1; + pi[pino].poc.resno0 = 0; + pi[pino].poc.compno0 = 0; + pi[pino].poc.layno1 = tcp->numlayers; + pi[pino].poc.resno1 = maxres; + pi[pino].poc.compno1 = image->numcomps; + pi[pino].poc.prg = tcp->prg; + } else { + pi[pino].first = 1; + pi[pino].poc.resno0 = tcp->pocs[pino].resno0; + pi[pino].poc.compno0 = tcp->pocs[pino].compno0; + pi[pino].poc.layno1 = tcp->pocs[pino].layno1; + pi[pino].poc.resno1 = tcp->pocs[pino].resno1; + pi[pino].poc.compno1 = tcp->pocs[pino].compno1; + pi[pino].poc.prg = tcp->pocs[pino].prg; + } + pi[pino].poc.layno0 = 0; + pi[pino].poc.precno0 = 0; + pi[pino].poc.precno1 = maxprec; + + } + + return pi; +} + + +opj_pi_iterator_t *pi_initialise_encode(opj_image_t *image, opj_cp_t *cp, int tileno, J2K_T2_MODE t2_mode){ + int p, q, pino; + int compno, resno; + int maxres = 0; + int maxprec = 0; + opj_pi_iterator_t *pi = NULL; + opj_tcp_t *tcp = NULL; + opj_tccp_t *tccp = NULL; + + tcp = &cp->tcps[tileno]; + + pi = (opj_pi_iterator_t*) opj_calloc((tcp->numpocs + 1), sizeof(opj_pi_iterator_t)); + if(!pi) { return NULL;} + pi->tp_on = cp->tp_on; + + for(pino = 0;pino < tcp->numpocs+1 ; pino ++){ + p = tileno % cp->tw; + q = tileno / cp->tw; + + pi[pino].tx0 = int_max(cp->tx0 + p * cp->tdx, image->x0); + pi[pino].ty0 = int_max(cp->ty0 + q * cp->tdy, image->y0); + pi[pino].tx1 = int_min(cp->tx0 + (p + 1) * cp->tdx, image->x1); + pi[pino].ty1 = int_min(cp->ty0 + (q + 1) * cp->tdy, image->y1); + pi[pino].numcomps = image->numcomps; + + pi[pino].comps = (opj_pi_comp_t*) opj_calloc(image->numcomps, sizeof(opj_pi_comp_t)); + if(!pi[pino].comps) { + pi_destroy(pi, cp, tileno); + return NULL; + } + + for (compno = 0; compno < pi[pino].numcomps; compno++) { + int tcx0, tcy0, tcx1, tcy1; + opj_pi_comp_t *comp = &pi[pino].comps[compno]; + tccp = &tcp->tccps[compno]; + comp->dx = image->comps[compno].dx; + comp->dy = image->comps[compno].dy; + comp->numresolutions = tccp->numresolutions; + + comp->resolutions = (opj_pi_resolution_t*) opj_malloc(comp->numresolutions * sizeof(opj_pi_resolution_t)); + if(!comp->resolutions) { + pi_destroy(pi, cp, tileno); + return NULL; + } + + tcx0 = int_ceildiv(pi[pino].tx0, comp->dx); + tcy0 = int_ceildiv(pi[pino].ty0, comp->dy); + tcx1 = int_ceildiv(pi[pino].tx1, comp->dx); + tcy1 = int_ceildiv(pi[pino].ty1, comp->dy); + if (comp->numresolutions > maxres) { + maxres = comp->numresolutions; + } + + for (resno = 0; resno < comp->numresolutions; resno++) { + int levelno; + int rx0, ry0, rx1, ry1; + int px0, py0, px1, py1; + opj_pi_resolution_t *res = &comp->resolutions[resno]; + if (tccp->csty & J2K_CCP_CSTY_PRT) { + res->pdx = tccp->prcw[resno]; + res->pdy = tccp->prch[resno]; + } else { + res->pdx = 15; + res->pdy = 15; + } + levelno = comp->numresolutions - 1 - resno; + rx0 = int_ceildivpow2(tcx0, levelno); + ry0 = int_ceildivpow2(tcy0, levelno); + rx1 = int_ceildivpow2(tcx1, levelno); + ry1 = int_ceildivpow2(tcy1, levelno); + px0 = int_floordivpow2(rx0, res->pdx) << res->pdx; + py0 = int_floordivpow2(ry0, res->pdy) << res->pdy; + px1 = int_ceildivpow2(rx1, res->pdx) << res->pdx; + py1 = int_ceildivpow2(ry1, res->pdy) << res->pdy; + res->pw = (rx0==rx1)?0:((px1 - px0) >> res->pdx); + res->ph = (ry0==ry1)?0:((py1 - py0) >> res->pdy); + + if (res->pw*res->ph > maxprec) { + maxprec = res->pw * res->ph; + } + } + } + + tccp = &tcp->tccps[0]; + pi[pino].step_p = 1; + pi[pino].step_c = maxprec * pi[pino].step_p; + pi[pino].step_r = image->numcomps * pi[pino].step_c; + pi[pino].step_l = maxres * pi[pino].step_r; + + for (compno = 0; compno < pi->numcomps; compno++) { + opj_pi_comp_t *comp = &pi->comps[compno]; + for (resno = 0; resno < comp->numresolutions; resno++) { + int dx, dy; + opj_pi_resolution_t *res = &comp->resolutions[resno]; + dx = comp->dx * (1 << (res->pdx + comp->numresolutions - 1 - resno)); + dy = comp->dy * (1 << (res->pdy + comp->numresolutions - 1 - resno)); + pi[pino].dx = !pi->dx ? dx : int_min(pi->dx, dx); + pi[pino].dy = !pi->dy ? dy : int_min(pi->dy, dy); + } + } + + if (pino == 0) { + pi[pino].include = (short int*) opj_calloc(tcp->numlayers * pi[pino].step_l, sizeof(short int)); + if(!pi[pino].include) { + pi_destroy(pi, cp, tileno); + return NULL; + } + } + else { + pi[pino].include = pi[pino - 1].include; + } + + /* Generation of boundaries for each prog flag*/ + if(tcp->POC && ( cp->cinema || ((!cp->cinema) && (t2_mode == FINAL_PASS)))){ + tcp->pocs[pino].compS= tcp->pocs[pino].compno0; + tcp->pocs[pino].compE= tcp->pocs[pino].compno1; + tcp->pocs[pino].resS = tcp->pocs[pino].resno0; + tcp->pocs[pino].resE = tcp->pocs[pino].resno1; + tcp->pocs[pino].layE = tcp->pocs[pino].layno1; + tcp->pocs[pino].prg = tcp->pocs[pino].prg1; + if (pino > 0) + tcp->pocs[pino].layS = (tcp->pocs[pino].layE > tcp->pocs[pino - 1].layE) ? tcp->pocs[pino - 1].layE : 0; + }else { + tcp->pocs[pino].compS= 0; + tcp->pocs[pino].compE= image->numcomps; + tcp->pocs[pino].resS = 0; + tcp->pocs[pino].resE = maxres; + tcp->pocs[pino].layS = 0; + tcp->pocs[pino].layE = tcp->numlayers; + tcp->pocs[pino].prg = tcp->prg; + } + tcp->pocs[pino].prcS = 0; + tcp->pocs[pino].prcE = maxprec;; + tcp->pocs[pino].txS = pi[pino].tx0; + tcp->pocs[pino].txE = pi[pino].tx1; + tcp->pocs[pino].tyS = pi[pino].ty0; + tcp->pocs[pino].tyE = pi[pino].ty1; + tcp->pocs[pino].dx = pi[pino].dx; + tcp->pocs[pino].dy = pi[pino].dy; + } + return pi; + } + + + +void pi_destroy(opj_pi_iterator_t *pi, opj_cp_t *cp, int tileno) { + int compno, pino; + opj_tcp_t *tcp = &cp->tcps[tileno]; + if(pi) { + for (pino = 0; pino < tcp->numpocs + 1; pino++) { + if(pi[pino].comps) { + for (compno = 0; compno < pi->numcomps; compno++) { + opj_pi_comp_t *comp = &pi[pino].comps[compno]; + if(comp->resolutions) { + opj_free(comp->resolutions); + } + } + opj_free(pi[pino].comps); + } + } + if(pi->include) { + opj_free(pi->include); + } + opj_free(pi); + } +} + +bool pi_next(opj_pi_iterator_t * pi) { + switch (pi->poc.prg) { + case LRCP: + return pi_next_lrcp(pi); + case RLCP: + return pi_next_rlcp(pi); + case RPCL: + return pi_next_rpcl(pi); + case PCRL: + return pi_next_pcrl(pi); + case CPRL: + return pi_next_cprl(pi); + case PROG_UNKNOWN: + return false; + } + + return false; +} + +bool pi_create_encode( opj_pi_iterator_t *pi, opj_cp_t *cp,int tileno, int pino,int tpnum, int tppos, J2K_T2_MODE t2_mode,int cur_totnum_tp){ + char prog[4]; + int i; + int incr_top=1,resetX=0; + opj_tcp_t *tcps =&cp->tcps[tileno]; + opj_poc_t *tcp= &tcps->pocs[pino]; + + pi[pino].first = 1; + pi[pino].poc.prg = tcp->prg; + + switch(tcp->prg){ + case CPRL: strncpy(prog, "CPRL",4); + break; + case LRCP: strncpy(prog, "LRCP",4); + break; + case PCRL: strncpy(prog, "PCRL",4); + break; + case RLCP: strncpy(prog, "RLCP",4); + break; + case RPCL: strncpy(prog, "RPCL",4); + break; + case PROG_UNKNOWN: + return true; + } + + if(!(cp->tp_on && ((!cp->cinema && (t2_mode == FINAL_PASS)) || cp->cinema))){ + pi[pino].poc.resno0 = tcp->resS; + pi[pino].poc.resno1 = tcp->resE; + pi[pino].poc.compno0 = tcp->compS; + pi[pino].poc.compno1 = tcp->compE; + pi[pino].poc.layno0 = tcp->layS; + pi[pino].poc.layno1 = tcp->layE; + pi[pino].poc.precno0 = tcp->prcS; + pi[pino].poc.precno1 = tcp->prcE; + pi[pino].poc.tx0 = tcp->txS; + pi[pino].poc.ty0 = tcp->tyS; + pi[pino].poc.tx1 = tcp->txE; + pi[pino].poc.ty1 = tcp->tyE; + }else { + if( tpnum < cur_totnum_tp){ + for(i=3;i>=0;i--){ + switch(prog[i]){ + case 'C': + if (i > tppos){ + pi[pino].poc.compno0 = tcp->compS; + pi[pino].poc.compno1 = tcp->compE; + }else{ + if (tpnum == 0){ + tcp->comp_t = tcp->compS; + pi[pino].poc.compno0 = tcp->comp_t; + pi[pino].poc.compno1 = tcp->comp_t+1; + tcp->comp_t+=1; + }else{ + if (incr_top == 1){ + if(tcp->comp_t ==tcp->compE){ + tcp->comp_t = tcp->compS; + pi[pino].poc.compno0 = tcp->comp_t; + pi[pino].poc.compno1 = tcp->comp_t+1; + tcp->comp_t+=1; + incr_top=1; + }else{ + pi[pino].poc.compno0 = tcp->comp_t; + pi[pino].poc.compno1 = tcp->comp_t+1; + tcp->comp_t+=1; + incr_top=0; + } + }else{ + pi[pino].poc.compno0 = tcp->comp_t-1; + pi[pino].poc.compno1 = tcp->comp_t; + } + } + } + break; + + case 'R': + if (i > tppos){ + pi[pino].poc.resno0 = tcp->resS; + pi[pino].poc.resno1 = tcp->resE; + }else{ + if (tpnum == 0){ + tcp->res_t = tcp->resS; + pi[pino].poc.resno0 = tcp->res_t; + pi[pino].poc.resno1 = tcp->res_t+1; + tcp->res_t+=1; + }else{ + if (incr_top == 1){ + if(tcp->res_t==tcp->resE){ + tcp->res_t = tcp->resS; + pi[pino].poc.resno0 = tcp->res_t; + pi[pino].poc.resno1 = tcp->res_t+1; + tcp->res_t+=1; + incr_top=1; + }else{ + pi[pino].poc.resno0 = tcp->res_t; + pi[pino].poc.resno1 = tcp->res_t+1; + tcp->res_t+=1; + incr_top=0; + } + }else{ + pi[pino].poc.resno0 = tcp->res_t - 1; + pi[pino].poc.resno1 = tcp->res_t; + } + } + } + break; + + case 'L': + if (i > tppos){ + pi[pino].poc.layno0 = tcp->layS; + pi[pino].poc.layno1 = tcp->layE; + }else{ + if (tpnum == 0){ + tcp->lay_t = tcp->layS; + pi[pino].poc.layno0 = tcp->lay_t; + pi[pino].poc.layno1 = tcp->lay_t+1; + tcp->lay_t+=1; + }else{ + if (incr_top == 1){ + if(tcp->lay_t == tcp->layE){ + tcp->lay_t = tcp->layS; + pi[pino].poc.layno0 = tcp->lay_t; + pi[pino].poc.layno1 = tcp->lay_t+1; + tcp->lay_t+=1; + incr_top=1; + }else{ + pi[pino].poc.layno0 = tcp->lay_t; + pi[pino].poc.layno1 = tcp->lay_t+1; + tcp->lay_t+=1; + incr_top=0; + } + }else{ + pi[pino].poc.layno0 = tcp->lay_t - 1; + pi[pino].poc.layno1 = tcp->lay_t; + } + } + } + break; + + case 'P': + switch(tcp->prg){ + case LRCP: + case RLCP: + if (i > tppos){ + pi[pino].poc.precno0 = tcp->prcS; + pi[pino].poc.precno1 = tcp->prcE; + }else{ + if (tpnum == 0){ + tcp->prc_t = tcp->prcS; + pi[pino].poc.precno0 = tcp->prc_t; + pi[pino].poc.precno1 = tcp->prc_t+1; + tcp->prc_t+=1; + }else{ + if (incr_top == 1){ + if(tcp->prc_t == tcp->prcE){ + tcp->prc_t = tcp->prcS; + pi[pino].poc.precno0 = tcp->prc_t; + pi[pino].poc.precno1 = tcp->prc_t+1; + tcp->prc_t+=1; + incr_top=1; + }else{ + pi[pino].poc.precno0 = tcp->prc_t; + pi[pino].poc.precno1 = tcp->prc_t+1; + tcp->prc_t+=1; + incr_top=0; + } + }else{ + pi[pino].poc.precno0 = tcp->prc_t - 1; + pi[pino].poc.precno1 = tcp->prc_t; + } + } + } + break; + default: + if (i > tppos){ + pi[pino].poc.tx0 = tcp->txS; + pi[pino].poc.ty0 = tcp->tyS; + pi[pino].poc.tx1 = tcp->txE; + pi[pino].poc.ty1 = tcp->tyE; + }else{ + if (tpnum == 0){ + tcp->tx0_t = tcp->txS; + tcp->ty0_t = tcp->tyS; + pi[pino].poc.tx0 = tcp->tx0_t; + pi[pino].poc.tx1 = tcp->tx0_t + tcp->dx - (tcp->tx0_t % tcp->dx); + pi[pino].poc.ty0 = tcp->ty0_t; + pi[pino].poc.ty1 = tcp->ty0_t + tcp->dy - (tcp->ty0_t % tcp->dy); + tcp->tx0_t = pi[pino].poc.tx1; + tcp->ty0_t = pi[pino].poc.ty1; + }else{ + if (incr_top == 1){ + if(tcp->tx0_t >= tcp->txE){ + if(tcp->ty0_t >= tcp->tyE){ + tcp->ty0_t = tcp->tyS; + pi[pino].poc.ty0 = tcp->ty0_t; + pi[pino].poc.ty1 = tcp->ty0_t + tcp->dy - (tcp->ty0_t % tcp->dy); + tcp->ty0_t = pi[pino].poc.ty1; + incr_top=1;resetX=1; + }else{ + pi[pino].poc.ty0 = tcp->ty0_t; + pi[pino].poc.ty1 = tcp->ty0_t + tcp->dy - (tcp->ty0_t % tcp->dy); + tcp->ty0_t = pi[pino].poc.ty1; + incr_top=0;resetX=1; + } + if(resetX==1){ + tcp->tx0_t = tcp->txS; + pi[pino].poc.tx0 = tcp->tx0_t; + pi[pino].poc.tx1 = tcp->tx0_t + tcp->dx- (tcp->tx0_t % tcp->dx); + tcp->tx0_t = pi[pino].poc.tx1; + } + }else{ + pi[pino].poc.tx0 = tcp->tx0_t; + pi[pino].poc.tx1 = tcp->tx0_t + tcp->dx- (tcp->tx0_t % tcp->dx); + tcp->tx0_t = pi[pino].poc.tx1; + pi[pino].poc.ty0 = tcp->ty0_t - tcp->dy - (tcp->ty0_t % tcp->dy); + pi[pino].poc.ty1 = tcp->ty0_t ; + incr_top=0; + } + }else{ + pi[pino].poc.tx0 = tcp->tx0_t - tcp->dx - (tcp->tx0_t % tcp->dx); + pi[pino].poc.tx1 = tcp->tx0_t ; + pi[pino].poc.ty0 = tcp->ty0_t - tcp->dy - (tcp->ty0_t % tcp->dy); + pi[pino].poc.ty1 = tcp->ty0_t ; + } + } + } + break; + } + break; + } + } + } + } + return false; +} + diff --git a/extern/libopenjpeg/pi.h b/extern/libopenjpeg/pi.h new file mode 100644 index 00000000000..b5e0f6a4df8 --- /dev/null +++ b/extern/libopenjpeg/pi.h @@ -0,0 +1,154 @@ +/* + * Copyright (c) 2002-2007, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium + * Copyright (c) 2002-2007, Professor Benoit Macq + * Copyright (c) 2001-2003, David Janssens + * Copyright (c) 2002-2003, Yannick Verschueren + * Copyright (c) 2003-2007, Francois-Olivier Devaux and Antonin Descampe + * Copyright (c) 2005, Herve Drolon, FreeImage Team + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 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. + */ + +#ifndef __PI_H +#define __PI_H +/** +@file pi.h +@brief Implementation of a packet iterator (PI) + +The functions in PI.C have for goal to realize a packet iterator that permits to get the next +packet following the progression order and change of it. The functions in PI.C are used +by some function in T2.C. +*/ + +/** @defgroup PI PI - Implementation of a packet iterator */ +/*@{*/ + +/** +FIXME: documentation +*/ +typedef struct opj_pi_resolution { + int pdx, pdy; + int pw, ph; +} opj_pi_resolution_t; + +/** +FIXME: documentation +*/ +typedef struct opj_pi_comp { + int dx, dy; + /** number of resolution levels */ + int numresolutions; + opj_pi_resolution_t *resolutions; +} opj_pi_comp_t; + +/** +Packet iterator +*/ +typedef struct opj_pi_iterator { + /** Enabling Tile part generation*/ + char tp_on; + /** precise if the packet has been already used (usefull for progression order change) */ + short int *include; + /** layer step used to localize the packet in the include vector */ + int step_l; + /** resolution step used to localize the packet in the include vector */ + int step_r; + /** component step used to localize the packet in the include vector */ + int step_c; + /** precinct step used to localize the packet in the include vector */ + int step_p; + /** component that identify the packet */ + int compno; + /** resolution that identify the packet */ + int resno; + /** precinct that identify the packet */ + int precno; + /** layer that identify the packet */ + int layno; + /** 0 if the first packet */ + int first; + /** progression order change information */ + opj_poc_t poc; + /** number of components in the image */ + int numcomps; + /** Components*/ + opj_pi_comp_t *comps; + int tx0, ty0, tx1, ty1; + int x, y, dx, dy; +} opj_pi_iterator_t; + +/** @name Exported functions */ +/*@{*/ +/* ----------------------------------------------------------------------- */ +/** +Create a packet iterator for Encoder +@param image Raw image for which the packets will be listed +@param cp Coding parameters +@param tileno Number that identifies the tile for which to list the packets +@param t2_mode If == 0 In Threshold calculation ,If == 1 Final pass +@return Returns a packet iterator that points to the first packet of the tile +@see pi_destroy +*/ +opj_pi_iterator_t *pi_initialise_encode(opj_image_t *image, opj_cp_t *cp, int tileno,J2K_T2_MODE t2_mode); +/** +Modify the packet iterator for enabling tile part generation +@param pi Handle to the packet iterator generated in pi_initialise_encode +@param cp Coding parameters +@param tileno Number that identifies the tile for which to list the packets +@param tpnum Tile part number of the current tile +@param tppos The position of the tile part flag in the progression order +@param cur_totnum_tp The total number of tile parts in the current tile +@return Returns true if an error is detected +*/ +bool pi_create_encode(opj_pi_iterator_t *pi, opj_cp_t *cp,int tileno, int pino,int tpnum, int tppos, J2K_T2_MODE t2_mode,int cur_totnum_tp); +/** +Create a packet iterator for Decoder +@param image Raw image for which the packets will be listed +@param cp Coding parameters +@param tileno Number that identifies the tile for which to list the packets +@return Returns a packet iterator that points to the first packet of the tile +@see pi_destroy +*/ +opj_pi_iterator_t *pi_create_decode(opj_image_t * image, opj_cp_t * cp, int tileno); + +/** +Destroy a packet iterator +@param pi Previously created packet iterator +@param cp Coding parameters +@param tileno Number that identifies the tile for which the packets were listed +@see pi_create +*/ +void pi_destroy(opj_pi_iterator_t *pi, opj_cp_t *cp, int tileno); + +/** +Modify the packet iterator to point to the next packet +@param pi Packet iterator to modify +@return Returns false if pi pointed to the last packet or else returns true +*/ +bool pi_next(opj_pi_iterator_t * pi); +/* ----------------------------------------------------------------------- */ +/*@}*/ + +/*@}*/ + +#endif /* __PI_H */ diff --git a/extern/libopenjpeg/raw.c b/extern/libopenjpeg/raw.c new file mode 100644 index 00000000000..3d231bfdc6b --- /dev/null +++ b/extern/libopenjpeg/raw.c @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2002-2007, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium + * Copyright (c) 2002-2007, Professor Benoit Macq + * Copyright (c) 2003-2007, Francois-Olivier Devaux and Antonin Descampe + * Copyright (c) 2005, Herve Drolon, FreeImage Team + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 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. + */ + +#include "opj_includes.h" + +/* +========================================================== + local functions +========================================================== +*/ + + +/* +========================================================== + RAW encoding interface +========================================================== +*/ + +opj_raw_t* raw_create(void) { + opj_raw_t *raw = (opj_raw_t*)opj_malloc(sizeof(opj_raw_t)); + return raw; +} + +void raw_destroy(opj_raw_t *raw) { + if(raw) { + opj_free(raw); + } +} + +int raw_numbytes(opj_raw_t *raw) { + return raw->bp - raw->start; +} + +void raw_init_dec(opj_raw_t *raw, unsigned char *bp, int len) { + raw->start = bp; + raw->lenmax = len; + raw->len = 0; + raw->c = 0; + raw->ct = 0; +} + +int raw_decode(opj_raw_t *raw) { + int d; + if (raw->ct == 0) { + raw->ct = 8; + if (raw->len == raw->lenmax) { + raw->c = 0xff; + } else { + if (raw->c == 0xff) { + raw->ct = 7; + } + raw->c = *(raw->start + raw->len); + raw->len++; + } + } + raw->ct--; + d = (raw->c >> raw->ct) & 0x01; + + return d; +} + diff --git a/extern/libopenjpeg/raw.h b/extern/libopenjpeg/raw.h new file mode 100644 index 00000000000..3c4b372f3f6 --- /dev/null +++ b/extern/libopenjpeg/raw.h @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2002-2007, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium + * Copyright (c) 2002-2007, Professor Benoit Macq + * Copyright (c) 2003-2007, Francois-Olivier Devaux and Antonin Descampe + * Copyright (c) 2005, Herve Drolon, FreeImage Team + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 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. + */ + +#ifndef __RAW_H +#define __RAW_H +/** +@file raw.h +@brief Implementation of operations for raw encoding (RAW) + +The functions in RAW.C have for goal to realize the operation of raw encoding linked +with the corresponding mode switch. +*/ + +/** @defgroup RAW RAW - Implementation of operations for raw encoding */ +/*@{*/ + +/** +RAW encoding operations +*/ +typedef struct opj_raw { + /** temporary buffer where bits are coded or decoded */ + unsigned char c; + /** number of bits already read or free to write */ + unsigned int ct; + /** maximum length to decode */ + unsigned int lenmax; + /** length decoded */ + unsigned int len; + /** pointer to the current position in the buffer */ + unsigned char *bp; + /** pointer to the start of the buffer */ + unsigned char *start; + /** pointer to the end of the buffer */ + unsigned char *end; +} opj_raw_t; + +/** @name Exported functions */ +/*@{*/ +/* ----------------------------------------------------------------------- */ +/** +Create a new RAW handle +@return Returns a new RAW handle if successful, returns NULL otherwise +*/ +opj_raw_t* raw_create(void); +/** +Destroy a previously created RAW handle +@param raw RAW handle to destroy +*/ +void raw_destroy(opj_raw_t *raw); +/** +Return the number of bytes written/read since initialisation +@param raw RAW handle to destroy +@return Returns the number of bytes already encoded +*/ +int raw_numbytes(opj_raw_t *raw); +/** +Initialize the decoder +@param raw RAW handle +@param bp Pointer to the start of the buffer from which the bytes will be read +@param len Length of the input buffer +*/ +void raw_init_dec(opj_raw_t *raw, unsigned char *bp, int len); +/** +Decode a symbol using raw-decoder. Cfr p.506 TAUBMAN +@param raw RAW handle +@return Returns the decoded symbol (0 or 1) +*/ +int raw_decode(opj_raw_t *raw); +/* ----------------------------------------------------------------------- */ +/*@}*/ + +/*@}*/ + +#endif /* __RAW_H */ diff --git a/extern/libopenjpeg/t1.c b/extern/libopenjpeg/t1.c new file mode 100644 index 00000000000..ad1c6a83ab6 --- /dev/null +++ b/extern/libopenjpeg/t1.c @@ -0,0 +1,1208 @@ +/* + * Copyright (c) 2002-2007, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium + * Copyright (c) 2002-2007, Professor Benoit Macq + * Copyright (c) 2001-2003, David Janssens + * Copyright (c) 2002-2003, Yannick Verschueren + * Copyright (c) 2003-2007, Francois-Olivier Devaux and Antonin Descampe + * Copyright (c) 2005, Herve Drolon, FreeImage Team + * Copyright (c) 2007, Callum Lerwick + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 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. + */ + +#include "opj_includes.h" +#include "t1_luts.h" + +/** @defgroup T1 T1 - Implementation of the tier-1 coding */ +/*@{*/ + +/** @name Local static functions */ +/*@{*/ + +static INLINE char t1_getctxno_zc(int f, int orient); +static char t1_getctxno_sc(int f); +static INLINE int t1_getctxno_mag(int f); +static char t1_getspb(int f); +static short t1_getnmsedec_sig(int x, int bitpos); +static short t1_getnmsedec_ref(int x, int bitpos); +static void t1_updateflags(flag_t *flagsp, int s, int stride); +/** +Encode significant pass +*/ +static void t1_enc_sigpass_step( + opj_t1_t *t1, + flag_t *flagsp, + int *datap, + int orient, + int bpno, + int one, + int *nmsedec, + char type, + int vsc); +/** +Decode significant pass +*/ +static void t1_dec_sigpass_step( + opj_t1_t *t1, + flag_t *flagsp, + int *datap, + int orient, + int oneplushalf, + char type, + int vsc); +/** +Encode significant pass +*/ +static void t1_enc_sigpass( + opj_t1_t *t1, + int bpno, + int orient, + int *nmsedec, + char type, + int cblksty); +/** +Decode significant pass +*/ +static void t1_dec_sigpass( + opj_t1_t *t1, + int bpno, + int orient, + char type, + int cblksty); +/** +Encode refinement pass +*/ +static void t1_enc_refpass_step( + opj_t1_t *t1, + flag_t *flagsp, + int *datap, + int bpno, + int one, + int *nmsedec, + char type, + int vsc); +/** +Decode refinement pass +*/ +static void t1_dec_refpass_step( + opj_t1_t *t1, + flag_t *flagsp, + int *datap, + int poshalf, + int neghalf, + char type, + int vsc); +/** +Encode refinement pass +*/ +static void t1_enc_refpass( + opj_t1_t *t1, + int bpno, + int *nmsedec, + char type, + int cblksty); +/** +Decode refinement pass +*/ +static void t1_dec_refpass( + opj_t1_t *t1, + int bpno, + char type, + int cblksty); +/** +Encode clean-up pass +*/ +static void t1_enc_clnpass_step( + opj_t1_t *t1, + flag_t *flagsp, + int *datap, + int orient, + int bpno, + int one, + int *nmsedec, + int partial, + int vsc); +/** +Decode clean-up pass +*/ +static void t1_dec_clnpass_step( + opj_t1_t *t1, + flag_t *flagsp, + int *datap, + int orient, + int oneplushalf, + int partial, + int vsc); +/** +Encode clean-up pass +*/ +static void t1_enc_clnpass( + opj_t1_t *t1, + int bpno, + int orient, + int *nmsedec, + int cblksty); +/** +Decode clean-up pass +*/ +static void t1_dec_clnpass( + opj_t1_t *t1, + int bpno, + int orient, + int cblksty); +static double t1_getwmsedec( + int nmsedec, + int compno, + int level, + int orient, + int bpno, + int qmfbid, + double stepsize, + int numcomps); +/** +Encode 1 code-block +@param t1 T1 handle +@param cblk Code-block coding parameters +@param orient +@param compno Component number +@param level +@param qmfbid +@param stepsize +@param cblksty Code-block style +@param numcomps +@param tile +*/ +static void t1_encode_cblk( + opj_t1_t *t1, + opj_tcd_cblk_enc_t* cblk, + int orient, + int compno, + int level, + int qmfbid, + double stepsize, + int cblksty, + int numcomps, + opj_tcd_tile_t * tile); +/** +Decode 1 code-block +@param t1 T1 handle +@param cblk Code-block coding parameters +@param orient +@param roishift Region of interest shifting value +@param cblksty Code-block style +*/ +static void t1_decode_cblk( + opj_t1_t *t1, + opj_tcd_cblk_dec_t* cblk, + int orient, + int roishift, + int cblksty); + +/*@}*/ + +/*@}*/ + +/* ----------------------------------------------------------------------- */ + +static char t1_getctxno_zc(int f, int orient) { + return lut_ctxno_zc[(orient << 8) | (f & T1_SIG_OTH)]; +} + +static char t1_getctxno_sc(int f) { + return lut_ctxno_sc[(f & (T1_SIG_PRIM | T1_SGN)) >> 4]; +} + +static int t1_getctxno_mag(int f) { + int tmp1 = (f & T1_SIG_OTH) ? T1_CTXNO_MAG + 1 : T1_CTXNO_MAG; + int tmp2 = (f & T1_REFINE) ? T1_CTXNO_MAG + 2 : tmp1; + return (tmp2); +} + +static char t1_getspb(int f) { + return lut_spb[(f & (T1_SIG_PRIM | T1_SGN)) >> 4]; +} + +static short t1_getnmsedec_sig(int x, int bitpos) { + if (bitpos > T1_NMSEDEC_FRACBITS) { + return lut_nmsedec_sig[(x >> (bitpos - T1_NMSEDEC_FRACBITS)) & ((1 << T1_NMSEDEC_BITS) - 1)]; + } + + return lut_nmsedec_sig0[x & ((1 << T1_NMSEDEC_BITS) - 1)]; +} + +static short t1_getnmsedec_ref(int x, int bitpos) { + if (bitpos > T1_NMSEDEC_FRACBITS) { + return lut_nmsedec_ref[(x >> (bitpos - T1_NMSEDEC_FRACBITS)) & ((1 << T1_NMSEDEC_BITS) - 1)]; + } + + return lut_nmsedec_ref0[x & ((1 << T1_NMSEDEC_BITS) - 1)]; +} + +static void t1_updateflags(flag_t *flagsp, int s, int stride) { + flag_t *np = flagsp - stride; + flag_t *sp = flagsp + stride; + + static const flag_t mod[] = { + T1_SIG_S, T1_SIG_S|T1_SGN_S, + T1_SIG_E, T1_SIG_E|T1_SGN_E, + T1_SIG_W, T1_SIG_W|T1_SGN_W, + T1_SIG_N, T1_SIG_N|T1_SGN_N + }; + + np[-1] |= T1_SIG_SE; + np[0] |= mod[s]; + np[1] |= T1_SIG_SW; + + flagsp[-1] |= mod[s+2]; + flagsp[0] |= T1_SIG; + flagsp[1] |= mod[s+4]; + + sp[-1] |= T1_SIG_NE; + sp[0] |= mod[s+6]; + sp[1] |= T1_SIG_NW; +} + +static void t1_enc_sigpass_step( + opj_t1_t *t1, + flag_t *flagsp, + int *datap, + int orient, + int bpno, + int one, + int *nmsedec, + char type, + int vsc) +{ + int v, flag; + + opj_mqc_t *mqc = t1->mqc; /* MQC component */ + + flag = vsc ? ((*flagsp) & (~(T1_SIG_S | T1_SIG_SE | T1_SIG_SW | T1_SGN_S))) : (*flagsp); + if ((flag & T1_SIG_OTH) && !(flag & (T1_SIG | T1_VISIT))) { + v = int_abs(*datap) & one ? 1 : 0; + mqc_setcurctx(mqc, t1_getctxno_zc(flag, orient)); /* ESSAI */ + if (type == T1_TYPE_RAW) { /* BYPASS/LAZY MODE */ + mqc_bypass_enc(mqc, v); + } else { + mqc_encode(mqc, v); + } + if (v) { + v = *datap < 0 ? 1 : 0; + *nmsedec += t1_getnmsedec_sig(int_abs(*datap), bpno + T1_NMSEDEC_FRACBITS); + mqc_setcurctx(mqc, t1_getctxno_sc(flag)); /* ESSAI */ + if (type == T1_TYPE_RAW) { /* BYPASS/LAZY MODE */ + mqc_bypass_enc(mqc, v); + } else { + mqc_encode(mqc, v ^ t1_getspb(flag)); + } + t1_updateflags(flagsp, v, t1->flags_stride); + } + *flagsp |= T1_VISIT; + } +} + +static void t1_dec_sigpass_step( + opj_t1_t *t1, + flag_t *flagsp, + int *datap, + int orient, + int oneplushalf, + char type, + int vsc) +{ + int v, flag; + + opj_raw_t *raw = t1->raw; /* RAW component */ + opj_mqc_t *mqc = t1->mqc; /* MQC component */ + + flag = vsc ? ((*flagsp) & (~(T1_SIG_S | T1_SIG_SE | T1_SIG_SW | T1_SGN_S))) : (*flagsp); + if ((flag & T1_SIG_OTH) && !(flag & (T1_SIG | T1_VISIT))) { + if (type == T1_TYPE_RAW) { + if (raw_decode(raw)) { + v = raw_decode(raw); /* ESSAI */ + *datap = v ? -oneplushalf : oneplushalf; + t1_updateflags(flagsp, v, t1->flags_stride); + } + } else { + mqc_setcurctx(mqc, t1_getctxno_zc(flag, orient)); + if (mqc_decode(mqc)) { + mqc_setcurctx(mqc, t1_getctxno_sc(flag)); + v = mqc_decode(mqc) ^ t1_getspb(flag); + *datap = v ? -oneplushalf : oneplushalf; + t1_updateflags(flagsp, v, t1->flags_stride); + } + } + *flagsp |= T1_VISIT; + } +} /* VSC and BYPASS by Antonin */ + +static void t1_enc_sigpass( + opj_t1_t *t1, + int bpno, + int orient, + int *nmsedec, + char type, + int cblksty) +{ + int i, j, k, one, vsc; + *nmsedec = 0; + one = 1 << (bpno + T1_NMSEDEC_FRACBITS); + for (k = 0; k < t1->h; k += 4) { + for (i = 0; i < t1->w; ++i) { + for (j = k; j < k + 4 && j < t1->h; ++j) { + vsc = ((cblksty & J2K_CCP_CBLKSTY_VSC) && (j == k + 3 || j == t1->h - 1)) ? 1 : 0; + t1_enc_sigpass_step( + t1, + &t1->flags[((j+1) * t1->flags_stride) + i + 1], + &t1->data[(j * t1->w) + i], + orient, + bpno, + one, + nmsedec, + type, + vsc); + } + } + } +} + +static void t1_dec_sigpass( + opj_t1_t *t1, + int bpno, + int orient, + char type, + int cblksty) +{ + int i, j, k, one, half, oneplushalf, vsc; + one = 1 << bpno; + half = one >> 1; + oneplushalf = one | half; + for (k = 0; k < t1->h; k += 4) { + for (i = 0; i < t1->w; ++i) { + for (j = k; j < k + 4 && j < t1->h; ++j) { + vsc = ((cblksty & J2K_CCP_CBLKSTY_VSC) && (j == k + 3 || j == t1->h - 1)) ? 1 : 0; + t1_dec_sigpass_step( + t1, + &t1->flags[((j+1) * t1->flags_stride) + i + 1], + &t1->data[(j * t1->w) + i], + orient, + oneplushalf, + type, + vsc); + } + } + } +} /* VSC and BYPASS by Antonin */ + +static void t1_enc_refpass_step( + opj_t1_t *t1, + flag_t *flagsp, + int *datap, + int bpno, + int one, + int *nmsedec, + char type, + int vsc) +{ + int v, flag; + + opj_mqc_t *mqc = t1->mqc; /* MQC component */ + + flag = vsc ? ((*flagsp) & (~(T1_SIG_S | T1_SIG_SE | T1_SIG_SW | T1_SGN_S))) : (*flagsp); + if ((flag & (T1_SIG | T1_VISIT)) == T1_SIG) { + *nmsedec += t1_getnmsedec_ref(int_abs(*datap), bpno + T1_NMSEDEC_FRACBITS); + v = int_abs(*datap) & one ? 1 : 0; + mqc_setcurctx(mqc, t1_getctxno_mag(flag)); /* ESSAI */ + if (type == T1_TYPE_RAW) { /* BYPASS/LAZY MODE */ + mqc_bypass_enc(mqc, v); + } else { + mqc_encode(mqc, v); + } + *flagsp |= T1_REFINE; + } +} + +static void t1_dec_refpass_step( + opj_t1_t *t1, + flag_t *flagsp, + int *datap, + int poshalf, + int neghalf, + char type, + int vsc) +{ + int v, t, flag; + + opj_mqc_t *mqc = t1->mqc; /* MQC component */ + opj_raw_t *raw = t1->raw; /* RAW component */ + + flag = vsc ? ((*flagsp) & (~(T1_SIG_S | T1_SIG_SE | T1_SIG_SW | T1_SGN_S))) : (*flagsp); + if ((flag & (T1_SIG | T1_VISIT)) == T1_SIG) { + mqc_setcurctx(mqc, t1_getctxno_mag(flag)); /* ESSAI */ + if (type == T1_TYPE_RAW) { + v = raw_decode(raw); + } else { + v = mqc_decode(mqc); + } + t = v ? poshalf : neghalf; + *datap += *datap < 0 ? -t : t; + *flagsp |= T1_REFINE; + } +} /* VSC and BYPASS by Antonin */ + +static void t1_enc_refpass( + opj_t1_t *t1, + int bpno, + int *nmsedec, + char type, + int cblksty) +{ + int i, j, k, one, vsc; + *nmsedec = 0; + one = 1 << (bpno + T1_NMSEDEC_FRACBITS); + for (k = 0; k < t1->h; k += 4) { + for (i = 0; i < t1->w; ++i) { + for (j = k; j < k + 4 && j < t1->h; ++j) { + vsc = ((cblksty & J2K_CCP_CBLKSTY_VSC) && (j == k + 3 || j == t1->h - 1)) ? 1 : 0; + t1_enc_refpass_step( + t1, + &t1->flags[((j+1) * t1->flags_stride) + i + 1], + &t1->data[(j * t1->w) + i], + bpno, + one, + nmsedec, + type, + vsc); + } + } + } +} + +static void t1_dec_refpass( + opj_t1_t *t1, + int bpno, + char type, + int cblksty) +{ + int i, j, k, one, poshalf, neghalf; + int vsc; + one = 1 << bpno; + poshalf = one >> 1; + neghalf = bpno > 0 ? -poshalf : -1; + for (k = 0; k < t1->h; k += 4) { + for (i = 0; i < t1->w; ++i) { + for (j = k; j < k + 4 && j < t1->h; ++j) { + vsc = ((cblksty & J2K_CCP_CBLKSTY_VSC) && (j == k + 3 || j == t1->h - 1)) ? 1 : 0; + t1_dec_refpass_step( + t1, + &t1->flags[((j+1) * t1->flags_stride) + i + 1], + &t1->data[(j * t1->w) + i], + poshalf, + neghalf, + type, + vsc); + } + } + } +} /* VSC and BYPASS by Antonin */ + +static void t1_enc_clnpass_step( + opj_t1_t *t1, + flag_t *flagsp, + int *datap, + int orient, + int bpno, + int one, + int *nmsedec, + int partial, + int vsc) +{ + int v, flag; + + opj_mqc_t *mqc = t1->mqc; /* MQC component */ + + flag = vsc ? ((*flagsp) & (~(T1_SIG_S | T1_SIG_SE | T1_SIG_SW | T1_SGN_S))) : (*flagsp); + if (partial) { + goto LABEL_PARTIAL; + } + if (!(*flagsp & (T1_SIG | T1_VISIT))) { + mqc_setcurctx(mqc, t1_getctxno_zc(flag, orient)); + v = int_abs(*datap) & one ? 1 : 0; + mqc_encode(mqc, v); + if (v) { +LABEL_PARTIAL: + *nmsedec += t1_getnmsedec_sig(int_abs(*datap), bpno + T1_NMSEDEC_FRACBITS); + mqc_setcurctx(mqc, t1_getctxno_sc(flag)); + v = *datap < 0 ? 1 : 0; + mqc_encode(mqc, v ^ t1_getspb(flag)); + t1_updateflags(flagsp, v, t1->flags_stride); + } + } + *flagsp &= ~T1_VISIT; +} + +static void t1_dec_clnpass_step( + opj_t1_t *t1, + flag_t *flagsp, + int *datap, + int orient, + int oneplushalf, + int partial, + int vsc) +{ + int v, flag; + + opj_mqc_t *mqc = t1->mqc; /* MQC component */ + + flag = vsc ? ((*flagsp) & (~(T1_SIG_S | T1_SIG_SE | T1_SIG_SW | T1_SGN_S))) : (*flagsp); + if (partial) { + goto LABEL_PARTIAL; + } + if (!(flag & (T1_SIG | T1_VISIT))) { + mqc_setcurctx(mqc, t1_getctxno_zc(flag, orient)); + if (mqc_decode(mqc)) { +LABEL_PARTIAL: + mqc_setcurctx(mqc, t1_getctxno_sc(flag)); + v = mqc_decode(mqc) ^ t1_getspb(flag); + *datap = v ? -oneplushalf : oneplushalf; + t1_updateflags(flagsp, v, t1->flags_stride); + } + } + *flagsp &= ~T1_VISIT; +} /* VSC and BYPASS by Antonin */ + +static void t1_enc_clnpass( + opj_t1_t *t1, + int bpno, + int orient, + int *nmsedec, + int cblksty) +{ + int i, j, k, one, agg, runlen, vsc; + + opj_mqc_t *mqc = t1->mqc; /* MQC component */ + + *nmsedec = 0; + one = 1 << (bpno + T1_NMSEDEC_FRACBITS); + for (k = 0; k < t1->h; k += 4) { + for (i = 0; i < t1->w; ++i) { + if (k + 3 < t1->h) { + if (cblksty & J2K_CCP_CBLKSTY_VSC) { + agg = !(MACRO_t1_flags(1 + k,1 + i) & (T1_SIG | T1_VISIT | T1_SIG_OTH) + || MACRO_t1_flags(1 + k + 1,1 + i) & (T1_SIG | T1_VISIT | T1_SIG_OTH) + || MACRO_t1_flags(1 + k + 2,1 + i) & (T1_SIG | T1_VISIT | T1_SIG_OTH) + || (MACRO_t1_flags(1 + k + 3,1 + i) + & (~(T1_SIG_S | T1_SIG_SE | T1_SIG_SW | T1_SGN_S))) & (T1_SIG | T1_VISIT | T1_SIG_OTH)); + } else { + agg = !(MACRO_t1_flags(1 + k,1 + i) & (T1_SIG | T1_VISIT | T1_SIG_OTH) + || MACRO_t1_flags(1 + k + 1,1 + i) & (T1_SIG | T1_VISIT | T1_SIG_OTH) + || MACRO_t1_flags(1 + k + 2,1 + i) & (T1_SIG | T1_VISIT | T1_SIG_OTH) + || MACRO_t1_flags(1 + k + 3,1 + i) & (T1_SIG | T1_VISIT | T1_SIG_OTH)); + } + } else { + agg = 0; + } + if (agg) { + for (runlen = 0; runlen < 4; ++runlen) { + if (int_abs(t1->data[((k + runlen)*t1->w) + i]) & one) + break; + } + mqc_setcurctx(mqc, T1_CTXNO_AGG); + mqc_encode(mqc, runlen != 4); + if (runlen == 4) { + continue; + } + mqc_setcurctx(mqc, T1_CTXNO_UNI); + mqc_encode(mqc, runlen >> 1); + mqc_encode(mqc, runlen & 1); + } else { + runlen = 0; + } + for (j = k + runlen; j < k + 4 && j < t1->h; ++j) { + vsc = ((cblksty & J2K_CCP_CBLKSTY_VSC) && (j == k + 3 || j == t1->h - 1)) ? 1 : 0; + t1_enc_clnpass_step( + t1, + &t1->flags[((j+1) * t1->flags_stride) + i + 1], + &t1->data[(j * t1->w) + i], + orient, + bpno, + one, + nmsedec, + agg && (j == k + runlen), + vsc); + } + } + } +} + +static void t1_dec_clnpass( + opj_t1_t *t1, + int bpno, + int orient, + int cblksty) +{ + int i, j, k, one, half, oneplushalf, agg, runlen, vsc; + int segsym = cblksty & J2K_CCP_CBLKSTY_SEGSYM; + + opj_mqc_t *mqc = t1->mqc; /* MQC component */ + + one = 1 << bpno; + half = one >> 1; + oneplushalf = one | half; + for (k = 0; k < t1->h; k += 4) { + for (i = 0; i < t1->w; ++i) { + if (k + 3 < t1->h) { + if (cblksty & J2K_CCP_CBLKSTY_VSC) { + agg = !(MACRO_t1_flags(1 + k,1 + i) & (T1_SIG | T1_VISIT | T1_SIG_OTH) + || MACRO_t1_flags(1 + k + 1,1 + i) & (T1_SIG | T1_VISIT | T1_SIG_OTH) + || MACRO_t1_flags(1 + k + 2,1 + i) & (T1_SIG | T1_VISIT | T1_SIG_OTH) + || (MACRO_t1_flags(1 + k + 3,1 + i) + & (~(T1_SIG_S | T1_SIG_SE | T1_SIG_SW | T1_SGN_S))) & (T1_SIG | T1_VISIT | T1_SIG_OTH)); + } else { + agg = !(MACRO_t1_flags(1 + k,1 + i) & (T1_SIG | T1_VISIT | T1_SIG_OTH) + || MACRO_t1_flags(1 + k + 1,1 + i) & (T1_SIG | T1_VISIT | T1_SIG_OTH) + || MACRO_t1_flags(1 + k + 2,1 + i) & (T1_SIG | T1_VISIT | T1_SIG_OTH) + || MACRO_t1_flags(1 + k + 3,1 + i) & (T1_SIG | T1_VISIT | T1_SIG_OTH)); + } + } else { + agg = 0; + } + if (agg) { + mqc_setcurctx(mqc, T1_CTXNO_AGG); + if (!mqc_decode(mqc)) { + continue; + } + mqc_setcurctx(mqc, T1_CTXNO_UNI); + runlen = mqc_decode(mqc); + runlen = (runlen << 1) | mqc_decode(mqc); + } else { + runlen = 0; + } + for (j = k + runlen; j < k + 4 && j < t1->h; ++j) { + vsc = ((cblksty & J2K_CCP_CBLKSTY_VSC) && (j == k + 3 || j == t1->h - 1)) ? 1 : 0; + t1_dec_clnpass_step( + t1, + &t1->flags[((j+1) * t1->flags_stride) + i + 1], + &t1->data[(j * t1->w) + i], + orient, + oneplushalf, + agg && (j == k + runlen), + vsc); + } + } + } + if (segsym) { + int v = 0; + mqc_setcurctx(mqc, T1_CTXNO_UNI); + v = mqc_decode(mqc); + v = (v << 1) | mqc_decode(mqc); + v = (v << 1) | mqc_decode(mqc); + v = (v << 1) | mqc_decode(mqc); + /* + if (v!=0xa) { + opj_event_msg(t1->cinfo, EVT_WARNING, "Bad segmentation symbol %x\n", v); + } + */ + } +} /* VSC and BYPASS by Antonin */ + + +/** mod fixed_quality */ +static double t1_getwmsedec( + int nmsedec, + int compno, + int level, + int orient, + int bpno, + int qmfbid, + double stepsize, + int numcomps) +{ + double w1, w2, wmsedec; + if (qmfbid == 1) { + w1 = (numcomps > 1) ? mct_getnorm(compno) : 1.0; + w2 = dwt_getnorm(level, orient); + } else { /* if (qmfbid == 0) */ + w1 = (numcomps > 1) ? mct_getnorm_real(compno) : 1.0; + w2 = dwt_getnorm_real(level, orient); + } + wmsedec = w1 * w2 * stepsize * (1 << bpno); + wmsedec *= wmsedec * nmsedec / 8192.0; + + return wmsedec; +} + +static bool allocate_buffers( + opj_t1_t *t1, + int w, + int h) +{ + int datasize=w * h; + int flagssize; + + if(datasize > t1->datasize){ + opj_aligned_free(t1->data); + t1->data = (int*) opj_aligned_malloc(datasize * sizeof(int)); + if(!t1->data){ + return false; + } + t1->datasize=datasize; + } + memset(t1->data,0,datasize * sizeof(int)); + + t1->flags_stride=w+2; + flagssize=t1->flags_stride * (h+2); + + if(flagssize > t1->flagssize){ + opj_aligned_free(t1->flags); + t1->flags = (flag_t*) opj_aligned_malloc(flagssize * sizeof(flag_t)); + if(!t1->flags){ + return false; + } + t1->flagssize=flagssize; + } + memset(t1->flags,0,flagssize * sizeof(flag_t)); + + t1->w=w; + t1->h=h; + + return true; +} + +/** mod fixed_quality */ +static void t1_encode_cblk( + opj_t1_t *t1, + opj_tcd_cblk_enc_t* cblk, + int orient, + int compno, + int level, + int qmfbid, + double stepsize, + int cblksty, + int numcomps, + opj_tcd_tile_t * tile) +{ + double cumwmsedec = 0.0; + + opj_mqc_t *mqc = t1->mqc; /* MQC component */ + + int passno, bpno, passtype; + int nmsedec = 0; + int i, max; + char type = T1_TYPE_MQ; + double tempwmsedec; + + max = 0; + for (i = 0; i < t1->w * t1->h; ++i) { + int tmp = abs(t1->data[i]); + max = int_max(max, tmp); + } + + cblk->numbps = max ? (int_floorlog2(max) + 1) - T1_NMSEDEC_FRACBITS : 0; + + bpno = cblk->numbps - 1; + passtype = 2; + + mqc_resetstates(mqc); + mqc_setstate(mqc, T1_CTXNO_UNI, 0, 46); + mqc_setstate(mqc, T1_CTXNO_AGG, 0, 3); + mqc_setstate(mqc, T1_CTXNO_ZC, 0, 4); + mqc_init_enc(mqc, cblk->data); + + for (passno = 0; bpno >= 0; ++passno) { + opj_tcd_pass_t *pass = &cblk->passes[passno]; + int correction = 3; + type = ((bpno < (cblk->numbps - 4)) && (passtype < 2) && (cblksty & J2K_CCP_CBLKSTY_LAZY)) ? T1_TYPE_RAW : T1_TYPE_MQ; + + switch (passtype) { + case 0: + t1_enc_sigpass(t1, bpno, orient, &nmsedec, type, cblksty); + break; + case 1: + t1_enc_refpass(t1, bpno, &nmsedec, type, cblksty); + break; + case 2: + t1_enc_clnpass(t1, bpno, orient, &nmsedec, cblksty); + /* code switch SEGMARK (i.e. SEGSYM) */ + if (cblksty & J2K_CCP_CBLKSTY_SEGSYM) + mqc_segmark_enc(mqc); + break; + } + + /* fixed_quality */ + tempwmsedec = t1_getwmsedec(nmsedec, compno, level, orient, bpno, qmfbid, stepsize, numcomps); + cumwmsedec += tempwmsedec; + tile->distotile += tempwmsedec; + + /* Code switch "RESTART" (i.e. TERMALL) */ + if ((cblksty & J2K_CCP_CBLKSTY_TERMALL) && !((passtype == 2) && (bpno - 1 < 0))) { + if (type == T1_TYPE_RAW) { + mqc_flush(mqc); + correction = 1; + /* correction = mqc_bypass_flush_enc(); */ + } else { /* correction = mqc_restart_enc(); */ + mqc_flush(mqc); + correction = 1; + } + pass->term = 1; + } else { + if (((bpno < (cblk->numbps - 4) && (passtype > 0)) + || ((bpno == (cblk->numbps - 4)) && (passtype == 2))) && (cblksty & J2K_CCP_CBLKSTY_LAZY)) { + if (type == T1_TYPE_RAW) { + mqc_flush(mqc); + correction = 1; + /* correction = mqc_bypass_flush_enc(); */ + } else { /* correction = mqc_restart_enc(); */ + mqc_flush(mqc); + correction = 1; + } + pass->term = 1; + } else { + pass->term = 0; + } + } + + if (++passtype == 3) { + passtype = 0; + bpno--; + } + + if (pass->term && bpno > 0) { + type = ((bpno < (cblk->numbps - 4)) && (passtype < 2) && (cblksty & J2K_CCP_CBLKSTY_LAZY)) ? T1_TYPE_RAW : T1_TYPE_MQ; + if (type == T1_TYPE_RAW) + mqc_bypass_init_enc(mqc); + else + mqc_restart_init_enc(mqc); + } + + pass->distortiondec = cumwmsedec; + pass->rate = mqc_numbytes(mqc) + correction; /* FIXME */ + + /* Code-switch "RESET" */ + if (cblksty & J2K_CCP_CBLKSTY_RESET) + mqc_reset_enc(mqc); + } + + /* Code switch "ERTERM" (i.e. PTERM) */ + if (cblksty & J2K_CCP_CBLKSTY_PTERM) + mqc_erterm_enc(mqc); + else /* Default coding */ if (!(cblksty & J2K_CCP_CBLKSTY_LAZY)) + mqc_flush(mqc); + + cblk->totalpasses = passno; + + for (passno = 0; passnototalpasses; passno++) { + opj_tcd_pass_t *pass = &cblk->passes[passno]; + if (pass->rate > mqc_numbytes(mqc)) + pass->rate = mqc_numbytes(mqc); + /*Preventing generation of FF as last data byte of a pass*/ + if((pass->rate>1) && (cblk->data[pass->rate - 1] == 0xFF)){ + pass->rate--; + } + pass->len = pass->rate - (passno == 0 ? 0 : cblk->passes[passno - 1].rate); + } +} + +static void t1_decode_cblk( + opj_t1_t *t1, + opj_tcd_cblk_dec_t* cblk, + int orient, + int roishift, + int cblksty) +{ + opj_raw_t *raw = t1->raw; /* RAW component */ + opj_mqc_t *mqc = t1->mqc; /* MQC component */ + + int bpno, passtype; + int segno, passno; + char type = T1_TYPE_MQ; /* BYPASS mode */ + + if(!allocate_buffers( + t1, + cblk->x1 - cblk->x0, + cblk->y1 - cblk->y0)) + { + return; + } + + bpno = roishift + cblk->numbps - 1; + passtype = 2; + + mqc_resetstates(mqc); + mqc_setstate(mqc, T1_CTXNO_UNI, 0, 46); + mqc_setstate(mqc, T1_CTXNO_AGG, 0, 3); + mqc_setstate(mqc, T1_CTXNO_ZC, 0, 4); + + for (segno = 0; segno < cblk->numsegs; ++segno) { + opj_tcd_seg_t *seg = &cblk->segs[segno]; + + /* BYPASS mode */ + type = ((bpno <= (cblk->numbps - 1) - 4) && (passtype < 2) && (cblksty & J2K_CCP_CBLKSTY_LAZY)) ? T1_TYPE_RAW : T1_TYPE_MQ; + /* FIXME: slviewer gets here with a null pointer. Why? Partially downloaded and/or corrupt textures? */ + if(seg->data == NULL){ + continue; + } + if (type == T1_TYPE_RAW) { + raw_init_dec(raw, (*seg->data) + seg->dataindex, seg->len); + } else { + mqc_init_dec(mqc, (*seg->data) + seg->dataindex, seg->len); + } + + for (passno = 0; passno < seg->numpasses; ++passno) { + switch (passtype) { + case 0: + t1_dec_sigpass(t1, bpno+1, orient, type, cblksty); + break; + case 1: + t1_dec_refpass(t1, bpno+1, type, cblksty); + break; + case 2: + t1_dec_clnpass(t1, bpno+1, orient, cblksty); + break; + } + + if ((cblksty & J2K_CCP_CBLKSTY_RESET) && type == T1_TYPE_MQ) { + mqc_resetstates(mqc); + mqc_setstate(mqc, T1_CTXNO_UNI, 0, 46); + mqc_setstate(mqc, T1_CTXNO_AGG, 0, 3); + mqc_setstate(mqc, T1_CTXNO_ZC, 0, 4); + } + if (++passtype == 3) { + passtype = 0; + bpno--; + } + } + } +} + +/* ----------------------------------------------------------------------- */ + +opj_t1_t* t1_create(opj_common_ptr cinfo) { + opj_t1_t *t1 = (opj_t1_t*) opj_malloc(sizeof(opj_t1_t)); + if(!t1) + return NULL; + + t1->cinfo = cinfo; + /* create MQC and RAW handles */ + t1->mqc = mqc_create(); + t1->raw = raw_create(); + + t1->data=NULL; + t1->flags=NULL; + t1->datasize=0; + t1->flagssize=0; + + return t1; +} + +void t1_destroy(opj_t1_t *t1) { + if(t1) { + /* destroy MQC and RAW handles */ + mqc_destroy(t1->mqc); + raw_destroy(t1->raw); + opj_aligned_free(t1->data); + opj_aligned_free(t1->flags); + opj_free(t1); + } +} + +void t1_encode_cblks( + opj_t1_t *t1, + opj_tcd_tile_t *tile, + opj_tcp_t *tcp) +{ + int compno, resno, bandno, precno, cblkno; + + tile->distotile = 0; /* fixed_quality */ + + for (compno = 0; compno < tile->numcomps; ++compno) { + opj_tcd_tilecomp_t* tilec = &tile->comps[compno]; + opj_tccp_t* tccp = &tcp->tccps[compno]; + int tile_w = tilec->x1 - tilec->x0; + + for (resno = 0; resno < tilec->numresolutions; ++resno) { + opj_tcd_resolution_t *res = &tilec->resolutions[resno]; + + for (bandno = 0; bandno < res->numbands; ++bandno) { + opj_tcd_band_t* restrict band = &res->bands[bandno]; + + for (precno = 0; precno < res->pw * res->ph; ++precno) { + opj_tcd_precinct_t *prc = &band->precincts[precno]; + + for (cblkno = 0; cblkno < prc->cw * prc->ch; ++cblkno) { + opj_tcd_cblk_enc_t* cblk = &prc->cblks.enc[cblkno]; + int* restrict datap; + int* restrict tiledp; + int cblk_w; + int cblk_h; + int i, j; + + int x = cblk->x0 - band->x0; + int y = cblk->y0 - band->y0; + if (band->bandno & 1) { + opj_tcd_resolution_t *pres = &tilec->resolutions[resno - 1]; + x += pres->x1 - pres->x0; + } + if (band->bandno & 2) { + opj_tcd_resolution_t *pres = &tilec->resolutions[resno - 1]; + y += pres->y1 - pres->y0; + } + + if(!allocate_buffers( + t1, + cblk->x1 - cblk->x0, + cblk->y1 - cblk->y0)) + { + return; + } + + datap=t1->data; + cblk_w = t1->w; + cblk_h = t1->h; + + tiledp=&tilec->data[(y * tile_w) + x]; + if (tccp->qmfbid == 1) { + for (j = 0; j < cblk_h; ++j) { + for (i = 0; i < cblk_w; ++i) { + int tmp = tiledp[(j * tile_w) + i]; + datap[(j * cblk_w) + i] = tmp << T1_NMSEDEC_FRACBITS; + } + } + } else { /* if (tccp->qmfbid == 0) */ + for (j = 0; j < cblk_h; ++j) { + for (i = 0; i < cblk_w; ++i) { + int tmp = tiledp[(j * tile_w) + i]; + datap[(j * cblk_w) + i] = + fix_mul( + tmp, + 8192 * 8192 / ((int) floor(band->stepsize * 8192))) >> (11 - T1_NMSEDEC_FRACBITS); + } + } + } + + t1_encode_cblk( + t1, + cblk, + band->bandno, + compno, + tilec->numresolutions - 1 - resno, + tccp->qmfbid, + band->stepsize, + tccp->cblksty, + tile->numcomps, + tile); + + } /* cblkno */ + } /* precno */ + } /* bandno */ + } /* resno */ + } /* compno */ +} + +void t1_decode_cblks( + opj_t1_t* t1, + opj_tcd_tilecomp_t* tilec, + opj_tccp_t* tccp) +{ + int resno, bandno, precno, cblkno; + + int tile_w = tilec->x1 - tilec->x0; + + for (resno = 0; resno < tilec->numresolutions; ++resno) { + opj_tcd_resolution_t* res = &tilec->resolutions[resno]; + + for (bandno = 0; bandno < res->numbands; ++bandno) { + opj_tcd_band_t* restrict band = &res->bands[bandno]; + + for (precno = 0; precno < res->pw * res->ph; ++precno) { + opj_tcd_precinct_t* precinct = &band->precincts[precno]; + + for (cblkno = 0; cblkno < precinct->cw * precinct->ch; ++cblkno) { + opj_tcd_cblk_dec_t* cblk = &precinct->cblks.dec[cblkno]; + int* restrict datap; + void* restrict tiledp; + int cblk_w, cblk_h; + int x, y; + int i, j; + + t1_decode_cblk( + t1, + cblk, + band->bandno, + tccp->roishift, + tccp->cblksty); + + x = cblk->x0 - band->x0; + y = cblk->y0 - band->y0; + if (band->bandno & 1) { + opj_tcd_resolution_t* pres = &tilec->resolutions[resno - 1]; + x += pres->x1 - pres->x0; + } + if (band->bandno & 2) { + opj_tcd_resolution_t* pres = &tilec->resolutions[resno - 1]; + y += pres->y1 - pres->y0; + } + + datap=t1->data; + cblk_w = t1->w; + cblk_h = t1->h; + + if (tccp->roishift) { + int thresh = 1 << tccp->roishift; + for (j = 0; j < cblk_h; ++j) { + for (i = 0; i < cblk_w; ++i) { + int val = datap[(j * cblk_w) + i]; + int mag = abs(val); + if (mag >= thresh) { + mag >>= tccp->roishift; + datap[(j * cblk_w) + i] = val < 0 ? -mag : mag; + } + } + } + } + + tiledp=(void*)&tilec->data[(y * tile_w) + x]; + if (tccp->qmfbid == 1) { + for (j = 0; j < cblk_h; ++j) { + for (i = 0; i < cblk_w; ++i) { + int tmp = datap[(j * cblk_w) + i]; + ((int*)tiledp)[(j * tile_w) + i] = tmp / 2; + } + } + } else { /* if (tccp->qmfbid == 0) */ + for (j = 0; j < cblk_h; ++j) { + for (i = 0; i < cblk_w; ++i) { + float tmp = datap[(j * cblk_w) + i] * band->stepsize; + ((float*)tiledp)[(j * tile_w) + i] = tmp; + } + } + } + opj_free(cblk->data); + opj_free(cblk->segs); + } /* cblkno */ + opj_free(precinct->cblks.dec); + } /* precno */ + } /* bandno */ + } /* resno */ +} + diff --git a/extern/libopenjpeg/t1.h b/extern/libopenjpeg/t1.h new file mode 100644 index 00000000000..0b4294e1d6b --- /dev/null +++ b/extern/libopenjpeg/t1.h @@ -0,0 +1,147 @@ +/* + * Copyright (c) 2002-2007, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium + * Copyright (c) 2002-2007, Professor Benoit Macq + * Copyright (c) 2001-2003, David Janssens + * Copyright (c) 2002-2003, Yannick Verschueren + * Copyright (c) 2003-2007, Francois-Olivier Devaux and Antonin Descampe + * Copyright (c) 2005, Herve Drolon, FreeImage Team + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 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. + */ +#ifndef __T1_H +#define __T1_H +/** +@file t1.h +@brief Implementation of the tier-1 coding (coding of code-block coefficients) (T1) + +The functions in T1.C have for goal to realize the tier-1 coding operation. The functions +in T1.C are used by some function in TCD.C. +*/ + +/** @defgroup T1 T1 - Implementation of the tier-1 coding */ +/*@{*/ + +/* ----------------------------------------------------------------------- */ +#define T1_NMSEDEC_BITS 7 + +#define T1_SIG_NE 0x0001 /**< Context orientation : North-East direction */ +#define T1_SIG_SE 0x0002 /**< Context orientation : South-East direction */ +#define T1_SIG_SW 0x0004 /**< Context orientation : South-West direction */ +#define T1_SIG_NW 0x0008 /**< Context orientation : North-West direction */ +#define T1_SIG_N 0x0010 /**< Context orientation : North direction */ +#define T1_SIG_E 0x0020 /**< Context orientation : East direction */ +#define T1_SIG_S 0x0040 /**< Context orientation : South direction */ +#define T1_SIG_W 0x0080 /**< Context orientation : West direction */ +#define T1_SIG_OTH (T1_SIG_N|T1_SIG_NE|T1_SIG_E|T1_SIG_SE|T1_SIG_S|T1_SIG_SW|T1_SIG_W|T1_SIG_NW) +#define T1_SIG_PRIM (T1_SIG_N|T1_SIG_E|T1_SIG_S|T1_SIG_W) + +#define T1_SGN_N 0x0100 +#define T1_SGN_E 0x0200 +#define T1_SGN_S 0x0400 +#define T1_SGN_W 0x0800 +#define T1_SGN (T1_SGN_N|T1_SGN_E|T1_SGN_S|T1_SGN_W) + +#define T1_SIG 0x1000 +#define T1_REFINE 0x2000 +#define T1_VISIT 0x4000 + +#define T1_NUMCTXS_ZC 9 +#define T1_NUMCTXS_SC 5 +#define T1_NUMCTXS_MAG 3 +#define T1_NUMCTXS_AGG 1 +#define T1_NUMCTXS_UNI 1 + +#define T1_CTXNO_ZC 0 +#define T1_CTXNO_SC (T1_CTXNO_ZC+T1_NUMCTXS_ZC) +#define T1_CTXNO_MAG (T1_CTXNO_SC+T1_NUMCTXS_SC) +#define T1_CTXNO_AGG (T1_CTXNO_MAG+T1_NUMCTXS_MAG) +#define T1_CTXNO_UNI (T1_CTXNO_AGG+T1_NUMCTXS_AGG) +#define T1_NUMCTXS (T1_CTXNO_UNI+T1_NUMCTXS_UNI) + +#define T1_NMSEDEC_FRACBITS (T1_NMSEDEC_BITS-1) + +#define T1_TYPE_MQ 0 /**< Normal coding using entropy coder */ +#define T1_TYPE_RAW 1 /**< No encoding the information is store under raw format in codestream (mode switch RAW)*/ + +/* ----------------------------------------------------------------------- */ + +typedef short flag_t; + +/** +Tier-1 coding (coding of code-block coefficients) +*/ +typedef struct opj_t1 { + /** codec context */ + opj_common_ptr cinfo; + + /** MQC component */ + opj_mqc_t *mqc; + /** RAW component */ + opj_raw_t *raw; + + int *data; + flag_t *flags; + int w; + int h; + int datasize; + int flagssize; + int flags_stride; +} opj_t1_t; + +#define MACRO_t1_flags(x,y) t1->flags[((x)*(t1->flags_stride))+(y)] + +/** @name Exported functions */ +/*@{*/ +/* ----------------------------------------------------------------------- */ +/** +Create a new T1 handle +and initialize the look-up tables of the Tier-1 coder/decoder +@return Returns a new T1 handle if successful, returns NULL otherwise +@see t1_init_luts +*/ +opj_t1_t* t1_create(opj_common_ptr cinfo); +/** +Destroy a previously created T1 handle +@param t1 T1 handle to destroy +*/ +void t1_destroy(opj_t1_t *t1); +/** +Encode the code-blocks of a tile +@param t1 T1 handle +@param tile The tile to encode +@param tcp Tile coding parameters +*/ +void t1_encode_cblks(opj_t1_t *t1, opj_tcd_tile_t *tile, opj_tcp_t *tcp); +/** +Decode the code-blocks of a tile +@param t1 T1 handle +@param tile The tile to decode +@param tcp Tile coding parameters +*/ +void t1_decode_cblks(opj_t1_t* t1, opj_tcd_tilecomp_t* tilec, opj_tccp_t* tccp); +/* ----------------------------------------------------------------------- */ +/*@}*/ + +/*@}*/ + +#endif /* __T1_H */ diff --git a/extern/libopenjpeg/t1_generate_luts.c b/extern/libopenjpeg/t1_generate_luts.c new file mode 100644 index 00000000000..1925b951f1b --- /dev/null +++ b/extern/libopenjpeg/t1_generate_luts.c @@ -0,0 +1,275 @@ +/* + * Copyright (c) 2002-2007, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium + * Copyright (c) 2002-2007, Professor Benoit Macq + * Copyright (c) 2001-2003, David Janssens + * Copyright (c) 2002-2003, Yannick Verschueren + * Copyright (c) 2003-2007, Francois-Olivier Devaux and Antonin Descampe + * Copyright (c) 2005, Herve Drolon, FreeImage Team + * Copyright (c) 2007, Callum Lerwick + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 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. + */ + +#include "opj_includes.h" +#include + +static int t1_init_ctxno_zc(int f, int orient) { + int h, v, d, n, t, hv; + n = 0; + h = ((f & T1_SIG_W) != 0) + ((f & T1_SIG_E) != 0); + v = ((f & T1_SIG_N) != 0) + ((f & T1_SIG_S) != 0); + d = ((f & T1_SIG_NW) != 0) + ((f & T1_SIG_NE) != 0) + ((f & T1_SIG_SE) != 0) + ((f & T1_SIG_SW) != 0); + + switch (orient) { + case 2: + t = h; + h = v; + v = t; + case 0: + case 1: + if (!h) { + if (!v) { + if (!d) + n = 0; + else if (d == 1) + n = 1; + else + n = 2; + } else if (v == 1) { + n = 3; + } else { + n = 4; + } + } else if (h == 1) { + if (!v) { + if (!d) + n = 5; + else + n = 6; + } else { + n = 7; + } + } else + n = 8; + break; + case 3: + hv = h + v; + if (!d) { + if (!hv) { + n = 0; + } else if (hv == 1) { + n = 1; + } else { + n = 2; + } + } else if (d == 1) { + if (!hv) { + n = 3; + } else if (hv == 1) { + n = 4; + } else { + n = 5; + } + } else if (d == 2) { + if (!hv) { + n = 6; + } else { + n = 7; + } + } else { + n = 8; + } + break; + } + + return (T1_CTXNO_ZC + n); +} + +static int t1_init_ctxno_sc(int f) { + int hc, vc, n; + n = 0; + + hc = int_min(((f & (T1_SIG_E | T1_SGN_E)) == + T1_SIG_E) + ((f & (T1_SIG_W | T1_SGN_W)) == T1_SIG_W), + 1) - int_min(((f & (T1_SIG_E | T1_SGN_E)) == + (T1_SIG_E | T1_SGN_E)) + + ((f & (T1_SIG_W | T1_SGN_W)) == + (T1_SIG_W | T1_SGN_W)), 1); + + vc = int_min(((f & (T1_SIG_N | T1_SGN_N)) == + T1_SIG_N) + ((f & (T1_SIG_S | T1_SGN_S)) == T1_SIG_S), + 1) - int_min(((f & (T1_SIG_N | T1_SGN_N)) == + (T1_SIG_N | T1_SGN_N)) + + ((f & (T1_SIG_S | T1_SGN_S)) == + (T1_SIG_S | T1_SGN_S)), 1); + + if (hc < 0) { + hc = -hc; + vc = -vc; + } + if (!hc) { + if (vc == -1) + n = 1; + else if (!vc) + n = 0; + else + n = 1; + } else if (hc == 1) { + if (vc == -1) + n = 2; + else if (!vc) + n = 3; + else + n = 4; + } + + return (T1_CTXNO_SC + n); +} + +static int t1_init_spb(int f) { + int hc, vc, n; + + hc = int_min(((f & (T1_SIG_E | T1_SGN_E)) == + T1_SIG_E) + ((f & (T1_SIG_W | T1_SGN_W)) == T1_SIG_W), + 1) - int_min(((f & (T1_SIG_E | T1_SGN_E)) == + (T1_SIG_E | T1_SGN_E)) + + ((f & (T1_SIG_W | T1_SGN_W)) == + (T1_SIG_W | T1_SGN_W)), 1); + + vc = int_min(((f & (T1_SIG_N | T1_SGN_N)) == + T1_SIG_N) + ((f & (T1_SIG_S | T1_SGN_S)) == T1_SIG_S), + 1) - int_min(((f & (T1_SIG_N | T1_SGN_N)) == + (T1_SIG_N | T1_SGN_N)) + + ((f & (T1_SIG_S | T1_SGN_S)) == + (T1_SIG_S | T1_SGN_S)), 1); + + if (!hc && !vc) + n = 0; + else + n = (!(hc > 0 || (!hc && vc > 0))); + + return n; +} + +void dump_array16(int array[],int size){ + int i; + --size; + for (i = 0; i < size; ++i) { + printf("0x%04x, ", array[i]); + if(!((i+1)&0x7)) + printf("\n "); + } + printf("0x%04x\n};\n\n", array[size]); +} + +int main(){ + int i, j; + double u, v, t; + + int lut_ctxno_zc[1024]; + int lut_nmsedec_sig[1 << T1_NMSEDEC_BITS]; + int lut_nmsedec_sig0[1 << T1_NMSEDEC_BITS]; + int lut_nmsedec_ref[1 << T1_NMSEDEC_BITS]; + int lut_nmsedec_ref0[1 << T1_NMSEDEC_BITS]; + + printf("/* This file was automatically generated by t1_generate_luts.c */\n\n"); + + // lut_ctxno_zc + for (j = 0; j < 4; ++j) { + for (i = 0; i < 256; ++i) { + int orient = j; + if (orient == 2) { + orient = 1; + } else if (orient == 1) { + orient = 2; + } + lut_ctxno_zc[(orient << 8) | i] = t1_init_ctxno_zc(i, j); + } + } + + printf("static char lut_ctxno_zc[1024] = {\n "); + for (i = 0; i < 1023; ++i) { + printf("%i, ", lut_ctxno_zc[i]); + if(!((i+1)&0x1f)) + printf("\n "); + } + printf("%i\n};\n\n", lut_ctxno_zc[1023]); + + // lut_ctxno_sc + printf("static char lut_ctxno_sc[256] = {\n "); + for (i = 0; i < 255; ++i) { + printf("0x%x, ", t1_init_ctxno_sc(i << 4)); + if(!((i+1)&0xf)) + printf("\n "); + } + printf("0x%x\n};\n\n", t1_init_ctxno_sc(255 << 4)); + + // lut_spb + printf("static char lut_spb[256] = {\n "); + for (i = 0; i < 255; ++i) { + printf("%i, ", t1_init_spb(i << 4)); + if(!((i+1)&0x1f)) + printf("\n "); + } + printf("%i\n};\n\n", t1_init_spb(255 << 4)); + + /* FIXME FIXME FIXME */ + /* fprintf(stdout,"nmsedec luts:\n"); */ + for (i = 0; i < (1 << T1_NMSEDEC_BITS); ++i) { + t = i / pow(2, T1_NMSEDEC_FRACBITS); + u = t; + v = t - 1.5; + lut_nmsedec_sig[i] = + int_max(0, + (int) (floor((u * u - v * v) * pow(2, T1_NMSEDEC_FRACBITS) + 0.5) / pow(2, T1_NMSEDEC_FRACBITS) * 8192.0)); + lut_nmsedec_sig0[i] = + int_max(0, + (int) (floor((u * u) * pow(2, T1_NMSEDEC_FRACBITS) + 0.5) / pow(2, T1_NMSEDEC_FRACBITS) * 8192.0)); + u = t - 1.0; + if (i & (1 << (T1_NMSEDEC_BITS - 1))) { + v = t - 1.5; + } else { + v = t - 0.5; + } + lut_nmsedec_ref[i] = + int_max(0, + (int) (floor((u * u - v * v) * pow(2, T1_NMSEDEC_FRACBITS) + 0.5) / pow(2, T1_NMSEDEC_FRACBITS) * 8192.0)); + lut_nmsedec_ref0[i] = + int_max(0, + (int) (floor((u * u) * pow(2, T1_NMSEDEC_FRACBITS) + 0.5) / pow(2, T1_NMSEDEC_FRACBITS) * 8192.0)); + } + + printf("static short lut_nmsedec_sig[1 << T1_NMSEDEC_BITS] = {\n "); + dump_array16(&lut_nmsedec_sig, 1 << T1_NMSEDEC_BITS); + + printf("static short lut_nmsedec_sig0[1 << T1_NMSEDEC_BITS] = {\n "); + dump_array16(&lut_nmsedec_sig0, 1 << T1_NMSEDEC_BITS); + + printf("static short lut_nmsedec_ref[1 << T1_NMSEDEC_BITS] = {\n "); + dump_array16(&lut_nmsedec_ref, 1 << T1_NMSEDEC_BITS); + + printf("static short lut_nmsedec_ref0[1 << T1_NMSEDEC_BITS] = {\n "); + dump_array16(&lut_nmsedec_ref0, 1 << T1_NMSEDEC_BITS); + + return 0; +} diff --git a/extern/libopenjpeg/t1_luts.h b/extern/libopenjpeg/t1_luts.h new file mode 100644 index 00000000000..e5e33f6656a --- /dev/null +++ b/extern/libopenjpeg/t1_luts.h @@ -0,0 +1,143 @@ +/* This file was automatically generated by t1_generate_luts.c */ + +static char lut_ctxno_zc[1024] = { + 0, 1, 1, 2, 1, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 0, 1, 1, 2, 1, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 0, 1, 1, 2, 1, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 0, 3, 3, 6, 3, 6, 6, 8, 3, 6, 6, 8, 6, 8, 8, 8, 1, 4, 4, 7, 4, 7, 7, 8, 4, 7, 7, 8, 7, 8, 8, 8, + 1, 4, 4, 7, 4, 7, 7, 8, 4, 7, 7, 8, 7, 8, 8, 8, 2, 5, 5, 7, 5, 7, 7, 8, 5, 7, 7, 8, 7, 8, 8, 8, + 1, 4, 4, 7, 4, 7, 7, 8, 4, 7, 7, 8, 7, 8, 8, 8, 2, 5, 5, 7, 5, 7, 7, 8, 5, 7, 7, 8, 7, 8, 8, 8, + 2, 5, 5, 7, 5, 7, 7, 8, 5, 7, 7, 8, 7, 8, 8, 8, 2, 5, 5, 7, 5, 7, 7, 8, 5, 7, 7, 8, 7, 8, 8, 8, + 1, 4, 4, 7, 4, 7, 7, 8, 4, 7, 7, 8, 7, 8, 8, 8, 2, 5, 5, 7, 5, 7, 7, 8, 5, 7, 7, 8, 7, 8, 8, 8, + 2, 5, 5, 7, 5, 7, 7, 8, 5, 7, 7, 8, 7, 8, 8, 8, 2, 5, 5, 7, 5, 7, 7, 8, 5, 7, 7, 8, 7, 8, 8, 8, + 2, 5, 5, 7, 5, 7, 7, 8, 5, 7, 7, 8, 7, 8, 8, 8, 2, 5, 5, 7, 5, 7, 7, 8, 5, 7, 7, 8, 7, 8, 8, 8, + 2, 5, 5, 7, 5, 7, 7, 8, 5, 7, 7, 8, 7, 8, 8, 8, 2, 5, 5, 7, 5, 7, 7, 8, 5, 7, 7, 8, 7, 8, 8, 8 +}; + +static char lut_ctxno_sc[256] = { + 0x9, 0xa, 0xc, 0xd, 0xa, 0xa, 0xd, 0xd, 0xc, 0xd, 0xc, 0xd, 0xd, 0xd, 0xd, 0xd, + 0x9, 0xa, 0xc, 0xb, 0xa, 0x9, 0xd, 0xc, 0xc, 0xb, 0xc, 0xb, 0xd, 0xc, 0xd, 0xc, + 0x9, 0xa, 0xc, 0xb, 0xa, 0xa, 0xb, 0xb, 0xc, 0xd, 0x9, 0xa, 0xd, 0xd, 0xa, 0xa, + 0x9, 0xa, 0xc, 0xd, 0xa, 0x9, 0xb, 0xc, 0xc, 0xb, 0x9, 0xa, 0xd, 0xc, 0xa, 0x9, + 0x9, 0xa, 0xc, 0xd, 0xa, 0x9, 0xb, 0xc, 0xc, 0xd, 0xc, 0xd, 0xb, 0xc, 0xb, 0xc, + 0x9, 0xa, 0xc, 0xb, 0xa, 0xa, 0xb, 0xb, 0xc, 0xb, 0xc, 0xb, 0xb, 0xb, 0xb, 0xb, + 0x9, 0xa, 0xc, 0xb, 0xa, 0x9, 0xd, 0xc, 0xc, 0xd, 0x9, 0xa, 0xb, 0xc, 0xa, 0x9, + 0x9, 0xa, 0xc, 0xd, 0xa, 0xa, 0xd, 0xd, 0xc, 0xb, 0x9, 0xa, 0xb, 0xb, 0xa, 0xa, + 0x9, 0xa, 0xc, 0xd, 0xa, 0xa, 0xd, 0xd, 0xc, 0xb, 0x9, 0xa, 0xb, 0xb, 0xa, 0xa, + 0x9, 0xa, 0xc, 0xb, 0xa, 0x9, 0xd, 0xc, 0xc, 0xd, 0x9, 0xa, 0xb, 0xc, 0xa, 0x9, + 0x9, 0xa, 0xc, 0xb, 0xa, 0xa, 0xb, 0xb, 0xc, 0xb, 0xc, 0xb, 0xb, 0xb, 0xb, 0xb, + 0x9, 0xa, 0xc, 0xd, 0xa, 0x9, 0xb, 0xc, 0xc, 0xd, 0xc, 0xd, 0xb, 0xc, 0xb, 0xc, + 0x9, 0xa, 0xc, 0xd, 0xa, 0x9, 0xb, 0xc, 0xc, 0xb, 0x9, 0xa, 0xd, 0xc, 0xa, 0x9, + 0x9, 0xa, 0xc, 0xb, 0xa, 0xa, 0xb, 0xb, 0xc, 0xd, 0x9, 0xa, 0xd, 0xd, 0xa, 0xa, + 0x9, 0xa, 0xc, 0xb, 0xa, 0x9, 0xd, 0xc, 0xc, 0xb, 0xc, 0xb, 0xd, 0xc, 0xd, 0xc, + 0x9, 0xa, 0xc, 0xd, 0xa, 0xa, 0xd, 0xd, 0xc, 0xd, 0xc, 0xd, 0xd, 0xd, 0xd, 0xd +}; + +static char lut_spb[256] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1, + 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, + 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, + 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 +}; + +static short lut_nmsedec_sig[1 << T1_NMSEDEC_BITS] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0180, 0x0300, 0x0480, 0x0600, 0x0780, 0x0900, 0x0a80, + 0x0c00, 0x0d80, 0x0f00, 0x1080, 0x1200, 0x1380, 0x1500, 0x1680, + 0x1800, 0x1980, 0x1b00, 0x1c80, 0x1e00, 0x1f80, 0x2100, 0x2280, + 0x2400, 0x2580, 0x2700, 0x2880, 0x2a00, 0x2b80, 0x2d00, 0x2e80, + 0x3000, 0x3180, 0x3300, 0x3480, 0x3600, 0x3780, 0x3900, 0x3a80, + 0x3c00, 0x3d80, 0x3f00, 0x4080, 0x4200, 0x4380, 0x4500, 0x4680, + 0x4800, 0x4980, 0x4b00, 0x4c80, 0x4e00, 0x4f80, 0x5100, 0x5280, + 0x5400, 0x5580, 0x5700, 0x5880, 0x5a00, 0x5b80, 0x5d00, 0x5e80, + 0x6000, 0x6180, 0x6300, 0x6480, 0x6600, 0x6780, 0x6900, 0x6a80, + 0x6c00, 0x6d80, 0x6f00, 0x7080, 0x7200, 0x7380, 0x7500, 0x7680 +}; + +static short lut_nmsedec_sig0[1 << T1_NMSEDEC_BITS] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0080, 0x0080, + 0x0080, 0x0080, 0x0100, 0x0100, 0x0100, 0x0180, 0x0180, 0x0200, + 0x0200, 0x0280, 0x0280, 0x0300, 0x0300, 0x0380, 0x0400, 0x0400, + 0x0480, 0x0500, 0x0580, 0x0580, 0x0600, 0x0680, 0x0700, 0x0780, + 0x0800, 0x0880, 0x0900, 0x0980, 0x0a00, 0x0a80, 0x0b80, 0x0c00, + 0x0c80, 0x0d00, 0x0e00, 0x0e80, 0x0f00, 0x1000, 0x1080, 0x1180, + 0x1200, 0x1300, 0x1380, 0x1480, 0x1500, 0x1600, 0x1700, 0x1780, + 0x1880, 0x1980, 0x1a80, 0x1b00, 0x1c00, 0x1d00, 0x1e00, 0x1f00, + 0x2000, 0x2100, 0x2200, 0x2300, 0x2400, 0x2500, 0x2680, 0x2780, + 0x2880, 0x2980, 0x2b00, 0x2c00, 0x2d00, 0x2e80, 0x2f80, 0x3100, + 0x3200, 0x3380, 0x3480, 0x3600, 0x3700, 0x3880, 0x3a00, 0x3b00, + 0x3c80, 0x3e00, 0x3f80, 0x4080, 0x4200, 0x4380, 0x4500, 0x4680, + 0x4800, 0x4980, 0x4b00, 0x4c80, 0x4e00, 0x4f80, 0x5180, 0x5300, + 0x5480, 0x5600, 0x5800, 0x5980, 0x5b00, 0x5d00, 0x5e80, 0x6080, + 0x6200, 0x6400, 0x6580, 0x6780, 0x6900, 0x6b00, 0x6d00, 0x6e80, + 0x7080, 0x7280, 0x7480, 0x7600, 0x7800, 0x7a00, 0x7c00, 0x7e00 +}; + +static short lut_nmsedec_ref[1 << T1_NMSEDEC_BITS] = { + 0x1800, 0x1780, 0x1700, 0x1680, 0x1600, 0x1580, 0x1500, 0x1480, + 0x1400, 0x1380, 0x1300, 0x1280, 0x1200, 0x1180, 0x1100, 0x1080, + 0x1000, 0x0f80, 0x0f00, 0x0e80, 0x0e00, 0x0d80, 0x0d00, 0x0c80, + 0x0c00, 0x0b80, 0x0b00, 0x0a80, 0x0a00, 0x0980, 0x0900, 0x0880, + 0x0800, 0x0780, 0x0700, 0x0680, 0x0600, 0x0580, 0x0500, 0x0480, + 0x0400, 0x0380, 0x0300, 0x0280, 0x0200, 0x0180, 0x0100, 0x0080, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0080, 0x0100, 0x0180, 0x0200, 0x0280, 0x0300, 0x0380, + 0x0400, 0x0480, 0x0500, 0x0580, 0x0600, 0x0680, 0x0700, 0x0780, + 0x0800, 0x0880, 0x0900, 0x0980, 0x0a00, 0x0a80, 0x0b00, 0x0b80, + 0x0c00, 0x0c80, 0x0d00, 0x0d80, 0x0e00, 0x0e80, 0x0f00, 0x0f80, + 0x1000, 0x1080, 0x1100, 0x1180, 0x1200, 0x1280, 0x1300, 0x1380, + 0x1400, 0x1480, 0x1500, 0x1580, 0x1600, 0x1680, 0x1700, 0x1780 +}; + +static short lut_nmsedec_ref0[1 << T1_NMSEDEC_BITS] = { + 0x2000, 0x1f00, 0x1e00, 0x1d00, 0x1c00, 0x1b00, 0x1a80, 0x1980, + 0x1880, 0x1780, 0x1700, 0x1600, 0x1500, 0x1480, 0x1380, 0x1300, + 0x1200, 0x1180, 0x1080, 0x1000, 0x0f00, 0x0e80, 0x0e00, 0x0d00, + 0x0c80, 0x0c00, 0x0b80, 0x0a80, 0x0a00, 0x0980, 0x0900, 0x0880, + 0x0800, 0x0780, 0x0700, 0x0680, 0x0600, 0x0580, 0x0580, 0x0500, + 0x0480, 0x0400, 0x0400, 0x0380, 0x0300, 0x0300, 0x0280, 0x0280, + 0x0200, 0x0200, 0x0180, 0x0180, 0x0100, 0x0100, 0x0100, 0x0080, + 0x0080, 0x0080, 0x0080, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0080, 0x0080, + 0x0080, 0x0080, 0x0100, 0x0100, 0x0100, 0x0180, 0x0180, 0x0200, + 0x0200, 0x0280, 0x0280, 0x0300, 0x0300, 0x0380, 0x0400, 0x0400, + 0x0480, 0x0500, 0x0580, 0x0580, 0x0600, 0x0680, 0x0700, 0x0780, + 0x0800, 0x0880, 0x0900, 0x0980, 0x0a00, 0x0a80, 0x0b80, 0x0c00, + 0x0c80, 0x0d00, 0x0e00, 0x0e80, 0x0f00, 0x1000, 0x1080, 0x1180, + 0x1200, 0x1300, 0x1380, 0x1480, 0x1500, 0x1600, 0x1700, 0x1780, + 0x1880, 0x1980, 0x1a80, 0x1b00, 0x1c00, 0x1d00, 0x1e00, 0x1f00 +}; + diff --git a/extern/libopenjpeg/t2.c b/extern/libopenjpeg/t2.c new file mode 100644 index 00000000000..be9b42a4132 --- /dev/null +++ b/extern/libopenjpeg/t2.c @@ -0,0 +1,787 @@ +/* + * Copyright (c) 2002-2007, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium + * Copyright (c) 2002-2007, Professor Benoit Macq + * Copyright (c) 2001-2003, David Janssens + * Copyright (c) 2002-2003, Yannick Verschueren + * Copyright (c) 2003-2007, Francois-Olivier Devaux and Antonin Descampe + * Copyright (c) 2005, Herve Drolon, FreeImage Team + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 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. + */ + +#include "opj_includes.h" + +/** @defgroup T2 T2 - Implementation of a tier-2 coding */ +/*@{*/ + +/** @name Local static functions */ +/*@{*/ + +static void t2_putcommacode(opj_bio_t *bio, int n); +static int t2_getcommacode(opj_bio_t *bio); +/** +Variable length code for signalling delta Zil (truncation point) +@param bio Bit Input/Output component +@param n delta Zil +*/ +static void t2_putnumpasses(opj_bio_t *bio, int n); +static int t2_getnumpasses(opj_bio_t *bio); +/** +Encode a packet of a tile to a destination buffer +@param tile Tile for which to write the packets +@param tcp Tile coding parameters +@param pi Packet identity +@param dest Destination buffer +@param len Length of the destination buffer +@param cstr_info Codestream information structure +@param tileno Number of the tile encoded +@return +*/ +static int t2_encode_packet(opj_tcd_tile_t *tile, opj_tcp_t *tcp, opj_pi_iterator_t *pi, unsigned char *dest, int len, opj_codestream_info_t *cstr_info, int tileno); +/** +@param seg +@param cblksty +@param first +*/ +static void t2_init_seg(opj_tcd_cblk_dec_t* cblk, int index, int cblksty, int first); +/** +Decode a packet of a tile from a source buffer +@param t2 T2 handle +@param src Source buffer +@param len Length of the source buffer +@param tile Tile for which to write the packets +@param tcp Tile coding parameters +@param pi Packet identity +@return +*/ +static int t2_decode_packet(opj_t2_t* t2, unsigned char *src, int len, opj_tcd_tile_t *tile, + opj_tcp_t *tcp, opj_pi_iterator_t *pi, opj_packet_info_t *pack_info); + +/*@}*/ + +/*@}*/ + +/* ----------------------------------------------------------------------- */ + +/* #define RESTART 0x04 */ + +static void t2_putcommacode(opj_bio_t *bio, int n) { + while (--n >= 0) { + bio_write(bio, 1, 1); + } + bio_write(bio, 0, 1); +} + +static int t2_getcommacode(opj_bio_t *bio) { + int n; + for (n = 0; bio_read(bio, 1); n++) { + ; + } + return n; +} + +static void t2_putnumpasses(opj_bio_t *bio, int n) { + if (n == 1) { + bio_write(bio, 0, 1); + } else if (n == 2) { + bio_write(bio, 2, 2); + } else if (n <= 5) { + bio_write(bio, 0xc | (n - 3), 4); + } else if (n <= 36) { + bio_write(bio, 0x1e0 | (n - 6), 9); + } else if (n <= 164) { + bio_write(bio, 0xff80 | (n - 37), 16); + } +} + +static int t2_getnumpasses(opj_bio_t *bio) { + int n; + if (!bio_read(bio, 1)) + return 1; + if (!bio_read(bio, 1)) + return 2; + if ((n = bio_read(bio, 2)) != 3) + return (3 + n); + if ((n = bio_read(bio, 5)) != 31) + return (6 + n); + return (37 + bio_read(bio, 7)); +} + +static int t2_encode_packet(opj_tcd_tile_t * tile, opj_tcp_t * tcp, opj_pi_iterator_t *pi, unsigned char *dest, int length, opj_codestream_info_t *cstr_info, int tileno) { + int bandno, cblkno; + unsigned char *c = dest; + + int compno = pi->compno; /* component value */ + int resno = pi->resno; /* resolution level value */ + int precno = pi->precno; /* precinct value */ + int layno = pi->layno; /* quality layer value */ + + opj_tcd_tilecomp_t *tilec = &tile->comps[compno]; + opj_tcd_resolution_t *res = &tilec->resolutions[resno]; + + opj_bio_t *bio = NULL; /* BIO component */ + + /* */ + if (tcp->csty & J2K_CP_CSTY_SOP) { + c[0] = 255; + c[1] = 145; + c[2] = 0; + c[3] = 4; + c[4] = (tile->packno % 65536) / 256; + c[5] = (tile->packno % 65536) % 256; + c += 6; + } + /* */ + + if (!layno) { + for (bandno = 0; bandno < res->numbands; bandno++) { + opj_tcd_band_t *band = &res->bands[bandno]; + opj_tcd_precinct_t *prc = &band->precincts[precno]; + tgt_reset(prc->incltree); + tgt_reset(prc->imsbtree); + for (cblkno = 0; cblkno < prc->cw * prc->ch; cblkno++) { + opj_tcd_cblk_enc_t* cblk = &prc->cblks.enc[cblkno]; + cblk->numpasses = 0; + tgt_setvalue(prc->imsbtree, cblkno, band->numbps - cblk->numbps); + } + } + } + + bio = bio_create(); + bio_init_enc(bio, c, length); + bio_write(bio, 1, 1); /* Empty header bit */ + + /* Writing Packet header */ + for (bandno = 0; bandno < res->numbands; bandno++) { + opj_tcd_band_t *band = &res->bands[bandno]; + opj_tcd_precinct_t *prc = &band->precincts[precno]; + for (cblkno = 0; cblkno < prc->cw * prc->ch; cblkno++) { + opj_tcd_cblk_enc_t* cblk = &prc->cblks.enc[cblkno]; + opj_tcd_layer_t *layer = &cblk->layers[layno]; + if (!cblk->numpasses && layer->numpasses) { + tgt_setvalue(prc->incltree, cblkno, layno); + } + } + for (cblkno = 0; cblkno < prc->cw * prc->ch; cblkno++) { + opj_tcd_cblk_enc_t* cblk = &prc->cblks.enc[cblkno]; + opj_tcd_layer_t *layer = &cblk->layers[layno]; + int increment = 0; + int nump = 0; + int len = 0, passno; + /* cblk inclusion bits */ + if (!cblk->numpasses) { + tgt_encode(bio, prc->incltree, cblkno, layno + 1); + } else { + bio_write(bio, layer->numpasses != 0, 1); + } + /* if cblk not included, go to the next cblk */ + if (!layer->numpasses) { + continue; + } + /* if first instance of cblk --> zero bit-planes information */ + if (!cblk->numpasses) { + cblk->numlenbits = 3; + tgt_encode(bio, prc->imsbtree, cblkno, 999); + } + /* number of coding passes included */ + t2_putnumpasses(bio, layer->numpasses); + + /* computation of the increase of the length indicator and insertion in the header */ + for (passno = cblk->numpasses; passno < cblk->numpasses + layer->numpasses; passno++) { + opj_tcd_pass_t *pass = &cblk->passes[passno]; + nump++; + len += pass->len; + if (pass->term || passno == (cblk->numpasses + layer->numpasses) - 1) { + increment = int_max(increment, int_floorlog2(len) + 1 - (cblk->numlenbits + int_floorlog2(nump))); + len = 0; + nump = 0; + } + } + t2_putcommacode(bio, increment); + + /* computation of the new Length indicator */ + cblk->numlenbits += increment; + + /* insertion of the codeword segment length */ + for (passno = cblk->numpasses; passno < cblk->numpasses + layer->numpasses; passno++) { + opj_tcd_pass_t *pass = &cblk->passes[passno]; + nump++; + len += pass->len; + if (pass->term || passno == (cblk->numpasses + layer->numpasses) - 1) { + bio_write(bio, len, cblk->numlenbits + int_floorlog2(nump)); + len = 0; + nump = 0; + } + } + } + } + + if (bio_flush(bio)) { + bio_destroy(bio); + return -999; /* modified to eliminate longjmp !! */ + } + + c += bio_numbytes(bio); + bio_destroy(bio); + + /* */ + if (tcp->csty & J2K_CP_CSTY_EPH) { + c[0] = 255; + c[1] = 146; + c += 2; + } + /* */ + + /* << INDEX */ + // End of packet header position. Currently only represents the distance to start of packet + // Will be updated later by incrementing with packet start value + if(cstr_info && cstr_info->index_write) { + opj_packet_info_t *info_PK = &cstr_info->tile[tileno].packet[cstr_info->packno]; + info_PK->end_ph_pos = (int)(c - dest); + } + /* INDEX >> */ + + /* Writing the packet body */ + + for (bandno = 0; bandno < res->numbands; bandno++) { + opj_tcd_band_t *band = &res->bands[bandno]; + opj_tcd_precinct_t *prc = &band->precincts[precno]; + for (cblkno = 0; cblkno < prc->cw * prc->ch; cblkno++) { + opj_tcd_cblk_enc_t* cblk = &prc->cblks.enc[cblkno]; + opj_tcd_layer_t *layer = &cblk->layers[layno]; + if (!layer->numpasses) { + continue; + } + if (c + layer->len > dest + length) { + return -999; + } + + memcpy(c, layer->data, layer->len); + cblk->numpasses += layer->numpasses; + c += layer->len; + /* << INDEX */ + if(cstr_info && cstr_info->index_write) { + opj_packet_info_t *info_PK = &cstr_info->tile[tileno].packet[cstr_info->packno]; + info_PK->disto += layer->disto; + if (cstr_info->D_max < info_PK->disto) { + cstr_info->D_max = info_PK->disto; + } + } + /* INDEX >> */ + } + } + + return (c - dest); +} + +static void t2_init_seg(opj_tcd_cblk_dec_t* cblk, int index, int cblksty, int first) { + opj_tcd_seg_t* seg; + cblk->segs = (opj_tcd_seg_t*) opj_realloc(cblk->segs, (index + 1) * sizeof(opj_tcd_seg_t)); + seg = &cblk->segs[index]; + seg->data = NULL; + seg->dataindex = 0; + seg->numpasses = 0; + seg->len = 0; + if (cblksty & J2K_CCP_CBLKSTY_TERMALL) { + seg->maxpasses = 1; + } + else if (cblksty & J2K_CCP_CBLKSTY_LAZY) { + if (first) { + seg->maxpasses = 10; + } else { + seg->maxpasses = (((seg - 1)->maxpasses == 1) || ((seg - 1)->maxpasses == 10)) ? 2 : 1; + } + } else { + seg->maxpasses = 109; + } +} + +static int t2_decode_packet(opj_t2_t* t2, unsigned char *src, int len, opj_tcd_tile_t *tile, + opj_tcp_t *tcp, opj_pi_iterator_t *pi, opj_packet_info_t *pack_info) { + int bandno, cblkno; + unsigned char *c = src; + + opj_cp_t *cp = t2->cp; + + int compno = pi->compno; /* component value */ + int resno = pi->resno; /* resolution level value */ + int precno = pi->precno; /* precinct value */ + int layno = pi->layno; /* quality layer value */ + + opj_tcd_resolution_t* res = &tile->comps[compno].resolutions[resno]; + + unsigned char *hd = NULL; + int present; + + opj_bio_t *bio = NULL; /* BIO component */ + + if (layno == 0) { + for (bandno = 0; bandno < res->numbands; bandno++) { + opj_tcd_band_t *band = &res->bands[bandno]; + opj_tcd_precinct_t *prc = &band->precincts[precno]; + + if ((band->x1-band->x0 == 0)||(band->y1-band->y0 == 0)) continue; + + tgt_reset(prc->incltree); + tgt_reset(prc->imsbtree); + for (cblkno = 0; cblkno < prc->cw * prc->ch; cblkno++) { + opj_tcd_cblk_dec_t* cblk = &prc->cblks.dec[cblkno]; + cblk->numsegs = 0; + } + } + } + + /* SOP markers */ + + if (tcp->csty & J2K_CP_CSTY_SOP) { + if ((*c) != 0xff || (*(c + 1) != 0x91)) { + opj_event_msg(t2->cinfo, EVT_WARNING, "Expected SOP marker\n"); + } else { + c += 6; + } + + /** TODO : check the Nsop value */ + } + + /* + When the marker PPT/PPM is used the packet header are store in PPT/PPM marker + This part deal with this caracteristic + step 1: Read packet header in the saved structure + step 2: Return to codestream for decoding + */ + + bio = bio_create(); + + if (cp->ppm == 1) { /* PPM */ + hd = cp->ppm_data; + bio_init_dec(bio, hd, cp->ppm_len); + } else if (tcp->ppt == 1) { /* PPT */ + hd = tcp->ppt_data; + bio_init_dec(bio, hd, tcp->ppt_len); + } else { /* Normal Case */ + hd = c; + bio_init_dec(bio, hd, src+len-hd); + } + + present = bio_read(bio, 1); + + if (!present) { + bio_inalign(bio); + hd += bio_numbytes(bio); + bio_destroy(bio); + + /* EPH markers */ + + if (tcp->csty & J2K_CP_CSTY_EPH) { + if ((*hd) != 0xff || (*(hd + 1) != 0x92)) { + printf("Error : expected EPH marker\n"); + } else { + hd += 2; + } + } + + /* << INDEX */ + // End of packet header position. Currently only represents the distance to start of packet + // Will be updated later by incrementing with packet start value + if(pack_info) { + pack_info->end_ph_pos = (int)(c - src); + } + /* INDEX >> */ + + if (cp->ppm == 1) { /* PPM case */ + cp->ppm_len += cp->ppm_data-hd; + cp->ppm_data = hd; + return (c - src); + } + if (tcp->ppt == 1) { /* PPT case */ + tcp->ppt_len+=tcp->ppt_data-hd; + tcp->ppt_data = hd; + return (c - src); + } + + return (hd - src); + } + + for (bandno = 0; bandno < res->numbands; bandno++) { + opj_tcd_band_t *band = &res->bands[bandno]; + opj_tcd_precinct_t *prc = &band->precincts[precno]; + + if ((band->x1-band->x0 == 0)||(band->y1-band->y0 == 0)) continue; + + for (cblkno = 0; cblkno < prc->cw * prc->ch; cblkno++) { + int included, increment, n, segno; + opj_tcd_cblk_dec_t* cblk = &prc->cblks.dec[cblkno]; + /* if cblk not yet included before --> inclusion tagtree */ + if (!cblk->numsegs) { + included = tgt_decode(bio, prc->incltree, cblkno, layno + 1); + /* else one bit */ + } else { + included = bio_read(bio, 1); + } + /* if cblk not included */ + if (!included) { + cblk->numnewpasses = 0; + continue; + } + /* if cblk not yet included --> zero-bitplane tagtree */ + if (!cblk->numsegs) { + int i, numimsbs; + for (i = 0; !tgt_decode(bio, prc->imsbtree, cblkno, i); i++) { + ; + } + numimsbs = i - 1; + cblk->numbps = band->numbps - numimsbs; + cblk->numlenbits = 3; + } + /* number of coding passes */ + cblk->numnewpasses = t2_getnumpasses(bio); + increment = t2_getcommacode(bio); + /* length indicator increment */ + cblk->numlenbits += increment; + segno = 0; + if (!cblk->numsegs) { + t2_init_seg(cblk, segno, tcp->tccps[compno].cblksty, 1); + } else { + segno = cblk->numsegs - 1; + if (cblk->segs[segno].numpasses == cblk->segs[segno].maxpasses) { + ++segno; + t2_init_seg(cblk, segno, tcp->tccps[compno].cblksty, 0); + } + } + n = cblk->numnewpasses; + + do { + cblk->segs[segno].numnewpasses = int_min(cblk->segs[segno].maxpasses - cblk->segs[segno].numpasses, n); + cblk->segs[segno].newlen = bio_read(bio, cblk->numlenbits + int_floorlog2(cblk->segs[segno].numnewpasses)); + n -= cblk->segs[segno].numnewpasses; + if (n > 0) { + ++segno; + t2_init_seg(cblk, segno, tcp->tccps[compno].cblksty, 0); + } + } while (n > 0); + } + } + + if (bio_inalign(bio)) { + bio_destroy(bio); + return -999; + } + + hd += bio_numbytes(bio); + bio_destroy(bio); + + /* EPH markers */ + if (tcp->csty & J2K_CP_CSTY_EPH) { + if ((*hd) != 0xff || (*(hd + 1) != 0x92)) { + opj_event_msg(t2->cinfo, EVT_ERROR, "Expected EPH marker\n"); + } else { + hd += 2; + } + } + + /* << INDEX */ + // End of packet header position. Currently only represents the distance to start of packet + // Will be updated later by incrementing with packet start value + if(pack_info) { + pack_info->end_ph_pos = (int)(hd - src); + } + /* INDEX >> */ + + if (cp->ppm==1) { + cp->ppm_len+=cp->ppm_data-hd; + cp->ppm_data = hd; + } else if (tcp->ppt == 1) { + tcp->ppt_len+=tcp->ppt_data-hd; + tcp->ppt_data = hd; + } else { + c=hd; + } + + for (bandno = 0; bandno < res->numbands; bandno++) { + opj_tcd_band_t *band = &res->bands[bandno]; + opj_tcd_precinct_t *prc = &band->precincts[precno]; + + if ((band->x1-band->x0 == 0)||(band->y1-band->y0 == 0)) continue; + + for (cblkno = 0; cblkno < prc->cw * prc->ch; cblkno++) { + opj_tcd_cblk_dec_t* cblk = &prc->cblks.dec[cblkno]; + opj_tcd_seg_t *seg = NULL; + if (!cblk->numnewpasses) + continue; + if (!cblk->numsegs) { + seg = &cblk->segs[0]; + cblk->numsegs++; + cblk->len = 0; + } else { + seg = &cblk->segs[cblk->numsegs - 1]; + if (seg->numpasses == seg->maxpasses) { + seg++; + cblk->numsegs++; + } + } + + do { + if (c + seg->newlen > src + len) { + return -999; + } + +#ifdef USE_JPWL + /* we need here a j2k handle to verify if making a check to + the validity of cblocks parameters is selected from user (-W) */ + + /* let's check that we are not exceeding */ + if ((cblk->len + seg->newlen) > 8192) { + opj_event_msg(t2->cinfo, EVT_WARNING, + "JPWL: segment too long (%d) for codeblock %d (p=%d, b=%d, r=%d, c=%d)\n", + seg->newlen, cblkno, precno, bandno, resno, compno); + if (!JPWL_ASSUME) { + opj_event_msg(t2->cinfo, EVT_ERROR, "JPWL: giving up\n"); + return -999; + } + seg->newlen = 8192 - cblk->len; + opj_event_msg(t2->cinfo, EVT_WARNING, " - truncating segment to %d\n", seg->newlen); + break; + }; + +#endif /* USE_JPWL */ + + cblk->data = (unsigned char*) opj_realloc(cblk->data, (cblk->len + seg->newlen) * sizeof(unsigned char*)); + memcpy(cblk->data + cblk->len, c, seg->newlen); + if (seg->numpasses == 0) { + seg->data = &cblk->data; + seg->dataindex = cblk->len; + } + c += seg->newlen; + cblk->len += seg->newlen; + seg->len += seg->newlen; + seg->numpasses += seg->numnewpasses; + cblk->numnewpasses -= seg->numnewpasses; + if (cblk->numnewpasses > 0) { + seg++; + cblk->numsegs++; + } + } while (cblk->numnewpasses > 0); + } + } + + return (c - src); +} + +/* ----------------------------------------------------------------------- */ + +int t2_encode_packets(opj_t2_t* t2,int tileno, opj_tcd_tile_t *tile, int maxlayers, unsigned char *dest, int len, opj_codestream_info_t *cstr_info,int tpnum, int tppos,int pino, J2K_T2_MODE t2_mode, int cur_totnum_tp){ + unsigned char *c = dest; + int e = 0; + int compno; + opj_pi_iterator_t *pi = NULL; + int poc; + opj_image_t *image = t2->image; + opj_cp_t *cp = t2->cp; + opj_tcp_t *tcp = &cp->tcps[tileno]; + int pocno = cp->cinema == CINEMA4K_24? 2: 1; + int maxcomp = cp->max_comp_size > 0 ? image->numcomps : 1; + + pi = pi_initialise_encode(image, cp, tileno, t2_mode); + if(!pi) { + /* TODO: throw an error */ + return -999; + } + + if(t2_mode == THRESH_CALC ){ /* Calculating threshold */ + for(compno = 0; compno < maxcomp; compno++ ){ + for(poc = 0; poc < pocno ; poc++){ + int comp_len = 0; + int tpnum = compno; + if (pi_create_encode(pi, cp,tileno,poc,tpnum,tppos,t2_mode,cur_totnum_tp)) { + opj_event_msg(t2->cinfo, EVT_ERROR, "Error initializing Packet Iterator\n"); + return -999; + } + while (pi_next(&pi[poc])) { + if (pi[poc].layno < maxlayers) { + e = t2_encode_packet(tile, &cp->tcps[tileno], &pi[poc], c, dest + len - c, cstr_info, tileno); + comp_len = comp_len + e; + if (e == -999) { + break; + } else { + c += e; + } + } + } + if (e == -999) break; + if (cp->max_comp_size){ + if (comp_len > cp->max_comp_size){ + e = -999; + break; + } + } + } + if (e == -999) break; + } + }else{ /* t2_mode == FINAL_PASS */ + pi_create_encode(pi, cp,tileno,pino,tpnum,tppos,t2_mode,cur_totnum_tp); + while (pi_next(&pi[pino])) { + if (pi[pino].layno < maxlayers) { + e = t2_encode_packet(tile, &cp->tcps[tileno], &pi[pino], c, dest + len - c, cstr_info, tileno); + if (e == -999) { + break; + } else { + c += e; + } + /* INDEX >> */ + if(cstr_info) { + if(cstr_info->index_write) { + opj_tile_info_t *info_TL = &cstr_info->tile[tileno]; + opj_packet_info_t *info_PK = &info_TL->packet[cstr_info->packno]; + if (!cstr_info->packno) { + info_PK->start_pos = info_TL->end_header + 1; + } else { + info_PK->start_pos = ((cp->tp_on | tcp->POC)&& info_PK->start_pos) ? info_PK->start_pos : info_TL->packet[cstr_info->packno - 1].end_pos + 1; + } + info_PK->end_pos = info_PK->start_pos + e - 1; + info_PK->end_ph_pos += info_PK->start_pos - 1; // End of packet header which now only represents the distance + // to start of packet is incremented by value of start of packet + } + + cstr_info->packno++; + } + /* << INDEX */ + tile->packno++; + } + } + } + + pi_destroy(pi, cp, tileno); + + if (e == -999) { + return e; + } + + return (c - dest); +} + +int t2_decode_packets(opj_t2_t *t2, unsigned char *src, int len, int tileno, opj_tcd_tile_t *tile, opj_codestream_info_t *cstr_info) { + unsigned char *c = src; + opj_pi_iterator_t *pi; + int pino, e = 0; + int n = 0, curtp = 0; + int tp_start_packno; + + opj_image_t *image = t2->image; + opj_cp_t *cp = t2->cp; + + /* create a packet iterator */ + pi = pi_create_decode(image, cp, tileno); + if(!pi) { + /* TODO: throw an error */ + return -999; + } + + tp_start_packno = 0; + + for (pino = 0; pino <= cp->tcps[tileno].numpocs; pino++) { + while (pi_next(&pi[pino])) { + if ((cp->layer==0) || (cp->layer>=((pi[pino].layno)+1))) { + opj_packet_info_t *pack_info; + if (cstr_info) + pack_info = &cstr_info->tile[tileno].packet[cstr_info->packno]; + else + pack_info = NULL; + e = t2_decode_packet(t2, c, src + len - c, tile, &cp->tcps[tileno], &pi[pino], pack_info); + } else { + e = 0; + } + + /* progression in resolution */ + image->comps[pi[pino].compno].resno_decoded = + (e > 0) ? + int_max(pi[pino].resno, image->comps[pi[pino].compno].resno_decoded) + : image->comps[pi[pino].compno].resno_decoded; + n++; + + /* INDEX >> */ + if(cstr_info) { + opj_tile_info_t *info_TL = &cstr_info->tile[tileno]; + opj_packet_info_t *info_PK = &info_TL->packet[cstr_info->packno]; + if (!cstr_info->packno) { + info_PK->start_pos = info_TL->end_header + 1; + } else if (info_TL->packet[cstr_info->packno-1].end_pos >= (int)cstr_info->tile[tileno].tp[curtp].tp_end_pos){ // New tile part + info_TL->tp[curtp].tp_numpacks = cstr_info->packno - tp_start_packno; // Number of packets in previous tile-part + tp_start_packno = cstr_info->packno; + curtp++; + info_PK->start_pos = cstr_info->tile[tileno].tp[curtp].tp_end_header+1; + } else { + info_PK->start_pos = (cp->tp_on && info_PK->start_pos) ? info_PK->start_pos : info_TL->packet[cstr_info->packno - 1].end_pos + 1; + } + info_PK->end_pos = info_PK->start_pos + e - 1; + info_PK->end_ph_pos += info_PK->start_pos - 1; // End of packet header which now only represents the distance + // to start of packet is incremented by value of start of packet + cstr_info->packno++; + } + /* << INDEX */ + + if (e == -999) { /* ADD */ + break; + } else { + c += e; + } + } + } + /* INDEX >> */ + if(cstr_info) { + cstr_info->tile[tileno].tp[curtp].tp_numpacks = cstr_info->packno - tp_start_packno; // Number of packets in last tile-part + } + /* << INDEX */ + + /* don't forget to release pi */ + pi_destroy(pi, cp, tileno); + + if (e == -999) { + return e; + } + + return (c - src); +} + +/* ----------------------------------------------------------------------- */ + +opj_t2_t* t2_create(opj_common_ptr cinfo, opj_image_t *image, opj_cp_t *cp) { + /* create the tcd structure */ + opj_t2_t *t2 = (opj_t2_t*)opj_malloc(sizeof(opj_t2_t)); + if(!t2) return NULL; + t2->cinfo = cinfo; + t2->image = image; + t2->cp = cp; + + return t2; +} + +void t2_destroy(opj_t2_t *t2) { + if(t2) { + opj_free(t2); + } +} + + + + + diff --git a/extern/libopenjpeg/t2.h b/extern/libopenjpeg/t2.h new file mode 100644 index 00000000000..b15b7520019 --- /dev/null +++ b/extern/libopenjpeg/t2.h @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2002-2007, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium + * Copyright (c) 2002-2007, Professor Benoit Macq + * Copyright (c) 2001-2003, David Janssens + * Copyright (c) 2002-2003, Yannick Verschueren + * Copyright (c) 2003-2007, Francois-Olivier Devaux and Antonin Descampe + * Copyright (c) 2005, Herve Drolon, FreeImage Team + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 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. + */ +#ifndef __T2_H +#define __T2_H +/** +@file t2.h +@brief Implementation of a tier-2 coding (packetization of code-block data) (T2) + +*/ + +/** @defgroup T2 T2 - Implementation of a tier-2 coding */ +/*@{*/ + +/** +Tier-2 coding +*/ +typedef struct opj_t2 { + /** codec context */ + opj_common_ptr cinfo; + + /** Encoding: pointer to the src image. Decoding: pointer to the dst image. */ + opj_image_t *image; + /** pointer to the image coding parameters */ + opj_cp_t *cp; +} opj_t2_t; + +/** @name Exported functions */ +/*@{*/ +/* ----------------------------------------------------------------------- */ + +/** +Encode the packets of a tile to a destination buffer +@param t2 T2 handle +@param tileno number of the tile encoded +@param tile the tile for which to write the packets +@param maxlayers maximum number of layers +@param dest the destination buffer +@param len the length of the destination buffer +@param cstr_info Codestream information structure +@param tpnum Tile part number of the current tile +@param tppos The position of the tile part flag in the progression order +@param t2_mode If == 0 In Threshold calculation ,If == 1 Final pass +@param cur_totnum_tp The total number of tile parts in the current tile +*/ +int t2_encode_packets(opj_t2_t* t2,int tileno, opj_tcd_tile_t *tile, int maxlayers, unsigned char *dest, int len, opj_codestream_info_t *cstr_info,int tpnum, int tppos,int pino,J2K_T2_MODE t2_mode,int cur_totnum_tp); +/** +Decode the packets of a tile from a source buffer +@param t2 T2 handle +@param src the source buffer +@param len length of the source buffer +@param tileno number that identifies the tile for which to decode the packets +@param tile tile for which to decode the packets + */ +int t2_decode_packets(opj_t2_t *t2, unsigned char *src, int len, int tileno, opj_tcd_tile_t *tile, opj_codestream_info_t *cstr_info); + +/** +Create a T2 handle +@param cinfo Codec context info +@param image Source or destination image +@param cp Image coding parameters +@return Returns a new T2 handle if successful, returns NULL otherwise +*/ +opj_t2_t* t2_create(opj_common_ptr cinfo, opj_image_t *image, opj_cp_t *cp); +/** +Destroy a T2 handle +@param t2 T2 handle to destroy +*/ +void t2_destroy(opj_t2_t *t2); + +/* ----------------------------------------------------------------------- */ +/*@}*/ + +/*@}*/ + +#endif /* __T2_H */ diff --git a/extern/libopenjpeg/tcd.c b/extern/libopenjpeg/tcd.c new file mode 100644 index 00000000000..f4a54553e28 --- /dev/null +++ b/extern/libopenjpeg/tcd.c @@ -0,0 +1,1506 @@ +/* + * Copyright (c) 2002-2007, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium + * Copyright (c) 2002-2007, Professor Benoit Macq + * Copyright (c) 2001-2003, David Janssens + * Copyright (c) 2002-2003, Yannick Verschueren + * Copyright (c) 2003-2007, Francois-Olivier Devaux and Antonin Descampe + * Copyright (c) 2005, Herve Drolon, FreeImage Team + * Copyright (c) 2006-2007, Parvatha Elangovan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 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. + */ + +#include "opj_includes.h" + +void tcd_dump(FILE *fd, opj_tcd_t *tcd, opj_tcd_image_t * img) { + int tileno, compno, resno, bandno, precno;//, cblkno; + + fprintf(fd, "image {\n"); + fprintf(fd, " tw=%d, th=%d x0=%d x1=%d y0=%d y1=%d\n", + img->tw, img->th, tcd->image->x0, tcd->image->x1, tcd->image->y0, tcd->image->y1); + + for (tileno = 0; tileno < img->th * img->tw; tileno++) { + opj_tcd_tile_t *tile = &tcd->tcd_image->tiles[tileno]; + fprintf(fd, " tile {\n"); + fprintf(fd, " x0=%d, y0=%d, x1=%d, y1=%d, numcomps=%d\n", + tile->x0, tile->y0, tile->x1, tile->y1, tile->numcomps); + for (compno = 0; compno < tile->numcomps; compno++) { + opj_tcd_tilecomp_t *tilec = &tile->comps[compno]; + fprintf(fd, " tilec {\n"); + fprintf(fd, + " x0=%d, y0=%d, x1=%d, y1=%d, numresolutions=%d\n", + tilec->x0, tilec->y0, tilec->x1, tilec->y1, tilec->numresolutions); + for (resno = 0; resno < tilec->numresolutions; resno++) { + opj_tcd_resolution_t *res = &tilec->resolutions[resno]; + fprintf(fd, "\n res {\n"); + fprintf(fd, + " x0=%d, y0=%d, x1=%d, y1=%d, pw=%d, ph=%d, numbands=%d\n", + res->x0, res->y0, res->x1, res->y1, res->pw, res->ph, res->numbands); + for (bandno = 0; bandno < res->numbands; bandno++) { + opj_tcd_band_t *band = &res->bands[bandno]; + fprintf(fd, " band {\n"); + fprintf(fd, + " x0=%d, y0=%d, x1=%d, y1=%d, stepsize=%f, numbps=%d\n", + band->x0, band->y0, band->x1, band->y1, band->stepsize, band->numbps); + for (precno = 0; precno < res->pw * res->ph; precno++) { + opj_tcd_precinct_t *prec = &band->precincts[precno]; + fprintf(fd, " prec {\n"); + fprintf(fd, + " x0=%d, y0=%d, x1=%d, y1=%d, cw=%d, ch=%d\n", + prec->x0, prec->y0, prec->x1, prec->y1, prec->cw, prec->ch); + /* + for (cblkno = 0; cblkno < prec->cw * prec->ch; cblkno++) { + opj_tcd_cblk_t *cblk = &prec->cblks[cblkno]; + fprintf(fd, " cblk {\n"); + fprintf(fd, + " x0=%d, y0=%d, x1=%d, y1=%d\n", + cblk->x0, cblk->y0, cblk->x1, cblk->y1); + fprintf(fd, " }\n"); + } + */ + fprintf(fd, " }\n"); + } + fprintf(fd, " }\n"); + } + fprintf(fd, " }\n"); + } + fprintf(fd, " }\n"); + } + fprintf(fd, " }\n"); + } + fprintf(fd, "}\n"); +} + +/* ----------------------------------------------------------------------- */ + +/** +Create a new TCD handle +*/ +opj_tcd_t* tcd_create(opj_common_ptr cinfo) { + /* create the tcd structure */ + opj_tcd_t *tcd = (opj_tcd_t*)opj_malloc(sizeof(opj_tcd_t)); + if(!tcd) return NULL; + tcd->cinfo = cinfo; + tcd->tcd_image = (opj_tcd_image_t*)opj_malloc(sizeof(opj_tcd_image_t)); + if(!tcd->tcd_image) { + opj_free(tcd); + return NULL; + } + + return tcd; +} + +/** +Destroy a previously created TCD handle +*/ +void tcd_destroy(opj_tcd_t *tcd) { + if(tcd) { + opj_free(tcd->tcd_image); + opj_free(tcd); + } +} + +/* ----------------------------------------------------------------------- */ + +void tcd_malloc_encode(opj_tcd_t *tcd, opj_image_t * image, opj_cp_t * cp, int curtileno) { + int tileno, compno, resno, bandno, precno, cblkno; + + tcd->image = image; + tcd->cp = cp; + tcd->tcd_image->tw = cp->tw; + tcd->tcd_image->th = cp->th; + tcd->tcd_image->tiles = (opj_tcd_tile_t *) opj_malloc(sizeof(opj_tcd_tile_t)); + + for (tileno = 0; tileno < 1; tileno++) { + opj_tcp_t *tcp = &cp->tcps[curtileno]; + int j; + + /* cfr p59 ISO/IEC FDIS15444-1 : 2000 (18 august 2000) */ + int p = curtileno % cp->tw; /* si numerotation matricielle .. */ + int q = curtileno / cp->tw; /* .. coordonnees de la tile (q,p) q pour ligne et p pour colonne */ + + /* opj_tcd_tile_t *tile=&tcd->tcd_image->tiles[tileno]; */ + opj_tcd_tile_t *tile = tcd->tcd_image->tiles; + + /* 4 borders of the tile rescale on the image if necessary */ + tile->x0 = int_max(cp->tx0 + p * cp->tdx, image->x0); + tile->y0 = int_max(cp->ty0 + q * cp->tdy, image->y0); + tile->x1 = int_min(cp->tx0 + (p + 1) * cp->tdx, image->x1); + tile->y1 = int_min(cp->ty0 + (q + 1) * cp->tdy, image->y1); + tile->numcomps = image->numcomps; + /* tile->PPT=image->PPT; */ + + /* Modification of the RATE >> */ + for (j = 0; j < tcp->numlayers; j++) { + tcp->rates[j] = tcp->rates[j] ? + cp->tp_on ? + (((float) (tile->numcomps + * (tile->x1 - tile->x0) + * (tile->y1 - tile->y0) + * image->comps[0].prec)) + /(tcp->rates[j] * 8 * image->comps[0].dx * image->comps[0].dy)) - (((tcd->cur_totnum_tp - 1) * 14 )/ tcp->numlayers) + : + ((float) (tile->numcomps + * (tile->x1 - tile->x0) + * (tile->y1 - tile->y0) + * image->comps[0].prec))/ + (tcp->rates[j] * 8 * image->comps[0].dx * image->comps[0].dy) + : 0; + + if (tcp->rates[j]) { + if (j && tcp->rates[j] < tcp->rates[j - 1] + 10) { + tcp->rates[j] = tcp->rates[j - 1] + 20; + } else { + if (!j && tcp->rates[j] < 30) + tcp->rates[j] = 30; + } + + if(j == (tcp->numlayers-1)){ + tcp->rates[j] = tcp->rates[j]- 2; + } + } + } + /* << Modification of the RATE */ + + tile->comps = (opj_tcd_tilecomp_t *) opj_malloc(image->numcomps * sizeof(opj_tcd_tilecomp_t)); + for (compno = 0; compno < tile->numcomps; compno++) { + opj_tccp_t *tccp = &tcp->tccps[compno]; + + opj_tcd_tilecomp_t *tilec = &tile->comps[compno]; + + /* border of each tile component (global) */ + tilec->x0 = int_ceildiv(tile->x0, image->comps[compno].dx); + tilec->y0 = int_ceildiv(tile->y0, image->comps[compno].dy); + tilec->x1 = int_ceildiv(tile->x1, image->comps[compno].dx); + tilec->y1 = int_ceildiv(tile->y1, image->comps[compno].dy); + + tilec->data = (int *) opj_aligned_malloc((tilec->x1 - tilec->x0) * (tilec->y1 - tilec->y0) * sizeof(int)); + tilec->numresolutions = tccp->numresolutions; + + tilec->resolutions = (opj_tcd_resolution_t *) opj_malloc(tilec->numresolutions * sizeof(opj_tcd_resolution_t)); + + for (resno = 0; resno < tilec->numresolutions; resno++) { + int pdx, pdy; + int levelno = tilec->numresolutions - 1 - resno; + int tlprcxstart, tlprcystart, brprcxend, brprcyend; + int tlcbgxstart, tlcbgystart, brcbgxend, brcbgyend; + int cbgwidthexpn, cbgheightexpn; + int cblkwidthexpn, cblkheightexpn; + + opj_tcd_resolution_t *res = &tilec->resolutions[resno]; + + /* border for each resolution level (global) */ + res->x0 = int_ceildivpow2(tilec->x0, levelno); + res->y0 = int_ceildivpow2(tilec->y0, levelno); + res->x1 = int_ceildivpow2(tilec->x1, levelno); + res->y1 = int_ceildivpow2(tilec->y1, levelno); + + res->numbands = resno == 0 ? 1 : 3; + /* p. 35, table A-23, ISO/IEC FDIS154444-1 : 2000 (18 august 2000) */ + if (tccp->csty & J2K_CCP_CSTY_PRT) { + pdx = tccp->prcw[resno]; + pdy = tccp->prch[resno]; + } else { + pdx = 15; + pdy = 15; + } + /* p. 64, B.6, ISO/IEC FDIS15444-1 : 2000 (18 august 2000) */ + tlprcxstart = int_floordivpow2(res->x0, pdx) << pdx; + tlprcystart = int_floordivpow2(res->y0, pdy) << pdy; + + brprcxend = int_ceildivpow2(res->x1, pdx) << pdx; + brprcyend = int_ceildivpow2(res->y1, pdy) << pdy; + + res->pw = (brprcxend - tlprcxstart) >> pdx; + res->ph = (brprcyend - tlprcystart) >> pdy; + + if (resno == 0) { + tlcbgxstart = tlprcxstart; + tlcbgystart = tlprcystart; + brcbgxend = brprcxend; + brcbgyend = brprcyend; + cbgwidthexpn = pdx; + cbgheightexpn = pdy; + } else { + tlcbgxstart = int_ceildivpow2(tlprcxstart, 1); + tlcbgystart = int_ceildivpow2(tlprcystart, 1); + brcbgxend = int_ceildivpow2(brprcxend, 1); + brcbgyend = int_ceildivpow2(brprcyend, 1); + cbgwidthexpn = pdx - 1; + cbgheightexpn = pdy - 1; + } + + cblkwidthexpn = int_min(tccp->cblkw, cbgwidthexpn); + cblkheightexpn = int_min(tccp->cblkh, cbgheightexpn); + + for (bandno = 0; bandno < res->numbands; bandno++) { + int x0b, y0b, i; + int gain, numbps; + opj_stepsize_t *ss = NULL; + + opj_tcd_band_t *band = &res->bands[bandno]; + + band->bandno = resno == 0 ? 0 : bandno + 1; + x0b = (band->bandno == 1) || (band->bandno == 3) ? 1 : 0; + y0b = (band->bandno == 2) || (band->bandno == 3) ? 1 : 0; + + if (band->bandno == 0) { + /* band border (global) */ + band->x0 = int_ceildivpow2(tilec->x0, levelno); + band->y0 = int_ceildivpow2(tilec->y0, levelno); + band->x1 = int_ceildivpow2(tilec->x1, levelno); + band->y1 = int_ceildivpow2(tilec->y1, levelno); + } else { + /* band border (global) */ + band->x0 = int_ceildivpow2(tilec->x0 - (1 << levelno) * x0b, levelno + 1); + band->y0 = int_ceildivpow2(tilec->y0 - (1 << levelno) * y0b, levelno + 1); + band->x1 = int_ceildivpow2(tilec->x1 - (1 << levelno) * x0b, levelno + 1); + band->y1 = int_ceildivpow2(tilec->y1 - (1 << levelno) * y0b, levelno + 1); + } + + ss = &tccp->stepsizes[resno == 0 ? 0 : 3 * (resno - 1) + bandno + 1]; + gain = tccp->qmfbid == 0 ? dwt_getgain_real(band->bandno) : dwt_getgain(band->bandno); + numbps = image->comps[compno].prec + gain; + + band->stepsize = (float)((1.0 + ss->mant / 2048.0) * pow(2.0, numbps - ss->expn)); + band->numbps = ss->expn + tccp->numgbits - 1; /* WHY -1 ? */ + + band->precincts = (opj_tcd_precinct_t *) opj_malloc(3 * res->pw * res->ph * sizeof(opj_tcd_precinct_t)); + + for (i = 0; i < res->pw * res->ph * 3; i++) { + band->precincts[i].imsbtree = NULL; + band->precincts[i].incltree = NULL; + } + + for (precno = 0; precno < res->pw * res->ph; precno++) { + int tlcblkxstart, tlcblkystart, brcblkxend, brcblkyend; + + int cbgxstart = tlcbgxstart + (precno % res->pw) * (1 << cbgwidthexpn); + int cbgystart = tlcbgystart + (precno / res->pw) * (1 << cbgheightexpn); + int cbgxend = cbgxstart + (1 << cbgwidthexpn); + int cbgyend = cbgystart + (1 << cbgheightexpn); + + opj_tcd_precinct_t *prc = &band->precincts[precno]; + + /* precinct size (global) */ + prc->x0 = int_max(cbgxstart, band->x0); + prc->y0 = int_max(cbgystart, band->y0); + prc->x1 = int_min(cbgxend, band->x1); + prc->y1 = int_min(cbgyend, band->y1); + + tlcblkxstart = int_floordivpow2(prc->x0, cblkwidthexpn) << cblkwidthexpn; + tlcblkystart = int_floordivpow2(prc->y0, cblkheightexpn) << cblkheightexpn; + brcblkxend = int_ceildivpow2(prc->x1, cblkwidthexpn) << cblkwidthexpn; + brcblkyend = int_ceildivpow2(prc->y1, cblkheightexpn) << cblkheightexpn; + prc->cw = (brcblkxend - tlcblkxstart) >> cblkwidthexpn; + prc->ch = (brcblkyend - tlcblkystart) >> cblkheightexpn; + + prc->cblks.enc = (opj_tcd_cblk_enc_t*) opj_calloc((prc->cw * prc->ch), sizeof(opj_tcd_cblk_enc_t)); + prc->incltree = tgt_create(prc->cw, prc->ch); + prc->imsbtree = tgt_create(prc->cw, prc->ch); + + for (cblkno = 0; cblkno < prc->cw * prc->ch; cblkno++) { + int cblkxstart = tlcblkxstart + (cblkno % prc->cw) * (1 << cblkwidthexpn); + int cblkystart = tlcblkystart + (cblkno / prc->cw) * (1 << cblkheightexpn); + int cblkxend = cblkxstart + (1 << cblkwidthexpn); + int cblkyend = cblkystart + (1 << cblkheightexpn); + + opj_tcd_cblk_enc_t* cblk = &prc->cblks.enc[cblkno]; + + /* code-block size (global) */ + cblk->x0 = int_max(cblkxstart, prc->x0); + cblk->y0 = int_max(cblkystart, prc->y0); + cblk->x1 = int_min(cblkxend, prc->x1); + cblk->y1 = int_min(cblkyend, prc->y1); + cblk->data = (unsigned char*) opj_calloc(8192+2, sizeof(unsigned char)); + /* FIXME: mqc_init_enc and mqc_byteout underrun the buffer if we don't do this. Why? */ + cblk->data += 2; + cblk->layers = (opj_tcd_layer_t*) opj_calloc(100, sizeof(opj_tcd_layer_t)); + cblk->passes = (opj_tcd_pass_t*) opj_calloc(100, sizeof(opj_tcd_pass_t)); + } + } + } + } + } + } + + /* tcd_dump(stdout, tcd, &tcd->tcd_image); */ +} + +void tcd_free_encode(opj_tcd_t *tcd) { + int tileno, compno, resno, bandno, precno, cblkno; + + for (tileno = 0; tileno < 1; tileno++) { + opj_tcd_tile_t *tile = tcd->tcd_image->tiles; + + for (compno = 0; compno < tile->numcomps; compno++) { + opj_tcd_tilecomp_t *tilec = &tile->comps[compno]; + + for (resno = 0; resno < tilec->numresolutions; resno++) { + opj_tcd_resolution_t *res = &tilec->resolutions[resno]; + + for (bandno = 0; bandno < res->numbands; bandno++) { + opj_tcd_band_t *band = &res->bands[bandno]; + + for (precno = 0; precno < res->pw * res->ph; precno++) { + opj_tcd_precinct_t *prc = &band->precincts[precno]; + + if (prc->incltree != NULL) { + tgt_destroy(prc->incltree); + prc->incltree = NULL; + } + if (prc->imsbtree != NULL) { + tgt_destroy(prc->imsbtree); + prc->imsbtree = NULL; + } + for (cblkno = 0; cblkno < prc->cw * prc->ch; cblkno++) { + opj_free(prc->cblks.enc[cblkno].data - 2); + opj_free(prc->cblks.enc[cblkno].layers); + opj_free(prc->cblks.enc[cblkno].passes); + } + opj_free(prc->cblks.enc); + } /* for (precno */ + opj_free(band->precincts); + band->precincts = NULL; + } /* for (bandno */ + } /* for (resno */ + opj_free(tilec->resolutions); + tilec->resolutions = NULL; + } /* for (compno */ + opj_free(tile->comps); + tile->comps = NULL; + } /* for (tileno */ + opj_free(tcd->tcd_image->tiles); + tcd->tcd_image->tiles = NULL; +} + +void tcd_init_encode(opj_tcd_t *tcd, opj_image_t * image, opj_cp_t * cp, int curtileno) { + int tileno, compno, resno, bandno, precno, cblkno; + + for (tileno = 0; tileno < 1; tileno++) { + opj_tcp_t *tcp = &cp->tcps[curtileno]; + int j; + /* cfr p59 ISO/IEC FDIS15444-1 : 2000 (18 august 2000) */ + int p = curtileno % cp->tw; + int q = curtileno / cp->tw; + + opj_tcd_tile_t *tile = tcd->tcd_image->tiles; + + /* 4 borders of the tile rescale on the image if necessary */ + tile->x0 = int_max(cp->tx0 + p * cp->tdx, image->x0); + tile->y0 = int_max(cp->ty0 + q * cp->tdy, image->y0); + tile->x1 = int_min(cp->tx0 + (p + 1) * cp->tdx, image->x1); + tile->y1 = int_min(cp->ty0 + (q + 1) * cp->tdy, image->y1); + + tile->numcomps = image->numcomps; + /* tile->PPT=image->PPT; */ + + /* Modification of the RATE >> */ + for (j = 0; j < tcp->numlayers; j++) { + tcp->rates[j] = tcp->rates[j] ? + ((float) (tile->numcomps + * (tile->x1 - tile->x0) + * (tile->y1 - tile->y0) + * image->comps[0].prec))/ + (tcp->rates[j] * 8 * image->comps[0].dx * image->comps[0].dy) + : 0; + + if (tcp->rates[j]) { + if (j && tcp->rates[j] < tcp->rates[j - 1] + 10) { + tcp->rates[j] = tcp->rates[j - 1] + 20; + } else { + if (!j && tcp->rates[j] < 30) + tcp->rates[j] = 30; + } + } + } + /* << Modification of the RATE */ + + /* tile->comps=(opj_tcd_tilecomp_t*)opj_realloc(tile->comps,image->numcomps*sizeof(opj_tcd_tilecomp_t)); */ + for (compno = 0; compno < tile->numcomps; compno++) { + opj_tccp_t *tccp = &tcp->tccps[compno]; + + opj_tcd_tilecomp_t *tilec = &tile->comps[compno]; + + /* border of each tile component (global) */ + tilec->x0 = int_ceildiv(tile->x0, image->comps[compno].dx); + tilec->y0 = int_ceildiv(tile->y0, image->comps[compno].dy); + tilec->x1 = int_ceildiv(tile->x1, image->comps[compno].dx); + tilec->y1 = int_ceildiv(tile->y1, image->comps[compno].dy); + + tilec->data = (int *) opj_aligned_malloc((tilec->x1 - tilec->x0) * (tilec->y1 - tilec->y0) * sizeof(int)); + tilec->numresolutions = tccp->numresolutions; + /* tilec->resolutions=(opj_tcd_resolution_t*)opj_realloc(tilec->resolutions,tilec->numresolutions*sizeof(opj_tcd_resolution_t)); */ + for (resno = 0; resno < tilec->numresolutions; resno++) { + int pdx, pdy; + + int levelno = tilec->numresolutions - 1 - resno; + int tlprcxstart, tlprcystart, brprcxend, brprcyend; + int tlcbgxstart, tlcbgystart, brcbgxend, brcbgyend; + int cbgwidthexpn, cbgheightexpn; + int cblkwidthexpn, cblkheightexpn; + + opj_tcd_resolution_t *res = &tilec->resolutions[resno]; + + /* border for each resolution level (global) */ + res->x0 = int_ceildivpow2(tilec->x0, levelno); + res->y0 = int_ceildivpow2(tilec->y0, levelno); + res->x1 = int_ceildivpow2(tilec->x1, levelno); + res->y1 = int_ceildivpow2(tilec->y1, levelno); + res->numbands = resno == 0 ? 1 : 3; + + /* p. 35, table A-23, ISO/IEC FDIS154444-1 : 2000 (18 august 2000) */ + if (tccp->csty & J2K_CCP_CSTY_PRT) { + pdx = tccp->prcw[resno]; + pdy = tccp->prch[resno]; + } else { + pdx = 15; + pdy = 15; + } + /* p. 64, B.6, ISO/IEC FDIS15444-1 : 2000 (18 august 2000) */ + tlprcxstart = int_floordivpow2(res->x0, pdx) << pdx; + tlprcystart = int_floordivpow2(res->y0, pdy) << pdy; + brprcxend = int_ceildivpow2(res->x1, pdx) << pdx; + brprcyend = int_ceildivpow2(res->y1, pdy) << pdy; + + res->pw = (brprcxend - tlprcxstart) >> pdx; + res->ph = (brprcyend - tlprcystart) >> pdy; + + if (resno == 0) { + tlcbgxstart = tlprcxstart; + tlcbgystart = tlprcystart; + brcbgxend = brprcxend; + brcbgyend = brprcyend; + cbgwidthexpn = pdx; + cbgheightexpn = pdy; + } else { + tlcbgxstart = int_ceildivpow2(tlprcxstart, 1); + tlcbgystart = int_ceildivpow2(tlprcystart, 1); + brcbgxend = int_ceildivpow2(brprcxend, 1); + brcbgyend = int_ceildivpow2(brprcyend, 1); + cbgwidthexpn = pdx - 1; + cbgheightexpn = pdy - 1; + } + + cblkwidthexpn = int_min(tccp->cblkw, cbgwidthexpn); + cblkheightexpn = int_min(tccp->cblkh, cbgheightexpn); + + for (bandno = 0; bandno < res->numbands; bandno++) { + int x0b, y0b; + int gain, numbps; + opj_stepsize_t *ss = NULL; + + opj_tcd_band_t *band = &res->bands[bandno]; + + band->bandno = resno == 0 ? 0 : bandno + 1; + x0b = (band->bandno == 1) || (band->bandno == 3) ? 1 : 0; + y0b = (band->bandno == 2) || (band->bandno == 3) ? 1 : 0; + + if (band->bandno == 0) { + /* band border */ + band->x0 = int_ceildivpow2(tilec->x0, levelno); + band->y0 = int_ceildivpow2(tilec->y0, levelno); + band->x1 = int_ceildivpow2(tilec->x1, levelno); + band->y1 = int_ceildivpow2(tilec->y1, levelno); + } else { + band->x0 = int_ceildivpow2(tilec->x0 - (1 << levelno) * x0b, levelno + 1); + band->y0 = int_ceildivpow2(tilec->y0 - (1 << levelno) * y0b, levelno + 1); + band->x1 = int_ceildivpow2(tilec->x1 - (1 << levelno) * x0b, levelno + 1); + band->y1 = int_ceildivpow2(tilec->y1 - (1 << levelno) * y0b, levelno + 1); + } + + ss = &tccp->stepsizes[resno == 0 ? 0 : 3 * (resno - 1) + bandno + 1]; + gain = tccp->qmfbid == 0 ? dwt_getgain_real(band->bandno) : dwt_getgain(band->bandno); + numbps = image->comps[compno].prec + gain; + band->stepsize = (float)((1.0 + ss->mant / 2048.0) * pow(2.0, numbps - ss->expn)); + band->numbps = ss->expn + tccp->numgbits - 1; /* WHY -1 ? */ + + for (precno = 0; precno < res->pw * res->ph; precno++) { + int tlcblkxstart, tlcblkystart, brcblkxend, brcblkyend; + + int cbgxstart = tlcbgxstart + (precno % res->pw) * (1 << cbgwidthexpn); + int cbgystart = tlcbgystart + (precno / res->pw) * (1 << cbgheightexpn); + int cbgxend = cbgxstart + (1 << cbgwidthexpn); + int cbgyend = cbgystart + (1 << cbgheightexpn); + + opj_tcd_precinct_t *prc = &band->precincts[precno]; + + /* precinct size (global) */ + prc->x0 = int_max(cbgxstart, band->x0); + prc->y0 = int_max(cbgystart, band->y0); + prc->x1 = int_min(cbgxend, band->x1); + prc->y1 = int_min(cbgyend, band->y1); + + tlcblkxstart = int_floordivpow2(prc->x0, cblkwidthexpn) << cblkwidthexpn; + tlcblkystart = int_floordivpow2(prc->y0, cblkheightexpn) << cblkheightexpn; + brcblkxend = int_ceildivpow2(prc->x1, cblkwidthexpn) << cblkwidthexpn; + brcblkyend = int_ceildivpow2(prc->y1, cblkheightexpn) << cblkheightexpn; + prc->cw = (brcblkxend - tlcblkxstart) >> cblkwidthexpn; + prc->ch = (brcblkyend - tlcblkystart) >> cblkheightexpn; + + opj_free(prc->cblks.enc); + prc->cblks.enc = (opj_tcd_cblk_enc_t*) opj_calloc(prc->cw * prc->ch, sizeof(opj_tcd_cblk_enc_t)); + + if (prc->incltree != NULL) { + tgt_destroy(prc->incltree); + } + if (prc->imsbtree != NULL) { + tgt_destroy(prc->imsbtree); + } + + prc->incltree = tgt_create(prc->cw, prc->ch); + prc->imsbtree = tgt_create(prc->cw, prc->ch); + + for (cblkno = 0; cblkno < prc->cw * prc->ch; cblkno++) { + int cblkxstart = tlcblkxstart + (cblkno % prc->cw) * (1 << cblkwidthexpn); + int cblkystart = tlcblkystart + (cblkno / prc->cw) * (1 << cblkheightexpn); + int cblkxend = cblkxstart + (1 << cblkwidthexpn); + int cblkyend = cblkystart + (1 << cblkheightexpn); + + opj_tcd_cblk_enc_t* cblk = &prc->cblks.enc[cblkno]; + + /* code-block size (global) */ + cblk->x0 = int_max(cblkxstart, prc->x0); + cblk->y0 = int_max(cblkystart, prc->y0); + cblk->x1 = int_min(cblkxend, prc->x1); + cblk->y1 = int_min(cblkyend, prc->y1); + cblk->data = (unsigned char*) opj_calloc(8192, sizeof(unsigned char)); + cblk->layers = (opj_tcd_layer_t*) opj_calloc(100, sizeof(opj_tcd_layer_t)); + cblk->passes = (opj_tcd_pass_t*) opj_calloc(100, sizeof(opj_tcd_pass_t)); + } + } /* precno */ + } /* bandno */ + } /* resno */ + } /* compno */ + } /* tileno */ + + /* tcd_dump(stdout, tcd, &tcd->tcd_image); */ +} + +void tcd_malloc_decode(opj_tcd_t *tcd, opj_image_t * image, opj_cp_t * cp) { + int i, j, tileno, p, q; + unsigned int x0 = 0, y0 = 0, x1 = 0, y1 = 0, w, h; + + tcd->image = image; + tcd->tcd_image->tw = cp->tw; + tcd->tcd_image->th = cp->th; + tcd->tcd_image->tiles = (opj_tcd_tile_t *) opj_malloc(cp->tw * cp->th * sizeof(opj_tcd_tile_t)); + + /* + Allocate place to store the decoded data = final image + Place limited by the tile really present in the codestream + */ + + for (j = 0; j < cp->tileno_size; j++) { + opj_tcd_tile_t *tile; + + tileno = cp->tileno[j]; + tile = &(tcd->tcd_image->tiles[cp->tileno[tileno]]); + tile->numcomps = image->numcomps; + tile->comps = (opj_tcd_tilecomp_t*) opj_calloc(image->numcomps, sizeof(opj_tcd_tilecomp_t)); + } + + for (i = 0; i < image->numcomps; i++) { + for (j = 0; j < cp->tileno_size; j++) { + opj_tcd_tile_t *tile; + opj_tcd_tilecomp_t *tilec; + + /* cfr p59 ISO/IEC FDIS15444-1 : 2000 (18 august 2000) */ + + tileno = cp->tileno[j]; + + tile = &(tcd->tcd_image->tiles[cp->tileno[tileno]]); + tilec = &tile->comps[i]; + + p = tileno % cp->tw; /* si numerotation matricielle .. */ + q = tileno / cp->tw; /* .. coordonnees de la tile (q,p) q pour ligne et p pour colonne */ + + /* 4 borders of the tile rescale on the image if necessary */ + tile->x0 = int_max(cp->tx0 + p * cp->tdx, image->x0); + tile->y0 = int_max(cp->ty0 + q * cp->tdy, image->y0); + tile->x1 = int_min(cp->tx0 + (p + 1) * cp->tdx, image->x1); + tile->y1 = int_min(cp->ty0 + (q + 1) * cp->tdy, image->y1); + + tilec->x0 = int_ceildiv(tile->x0, image->comps[i].dx); + tilec->y0 = int_ceildiv(tile->y0, image->comps[i].dy); + tilec->x1 = int_ceildiv(tile->x1, image->comps[i].dx); + tilec->y1 = int_ceildiv(tile->y1, image->comps[i].dy); + + x0 = j == 0 ? tilec->x0 : int_min(x0, (unsigned int) tilec->x0); + y0 = j == 0 ? tilec->y0 : int_min(y0, (unsigned int) tilec->x0); + x1 = j == 0 ? tilec->x1 : int_max(x1, (unsigned int) tilec->x1); + y1 = j == 0 ? tilec->y1 : int_max(y1, (unsigned int) tilec->y1); + } + + w = int_ceildivpow2(x1 - x0, image->comps[i].factor); + h = int_ceildivpow2(y1 - y0, image->comps[i].factor); + + image->comps[i].w = w; + image->comps[i].h = h; + image->comps[i].x0 = x0; + image->comps[i].y0 = y0; + } +} + +void tcd_malloc_decode_tile(opj_tcd_t *tcd, opj_image_t * image, opj_cp_t * cp, int tileno, opj_codestream_info_t *cstr_info) { + int compno, resno, bandno, precno, cblkno; + opj_tcp_t *tcp; + opj_tcd_tile_t *tile; + + tcd->cp = cp; + + tcp = &(cp->tcps[cp->tileno[tileno]]); + tile = &(tcd->tcd_image->tiles[cp->tileno[tileno]]); + + tileno = cp->tileno[tileno]; + + for (compno = 0; compno < tile->numcomps; compno++) { + opj_tccp_t *tccp = &tcp->tccps[compno]; + opj_tcd_tilecomp_t *tilec = &tile->comps[compno]; + + /* border of each tile component (global) */ + tilec->x0 = int_ceildiv(tile->x0, image->comps[compno].dx); + tilec->y0 = int_ceildiv(tile->y0, image->comps[compno].dy); + tilec->x1 = int_ceildiv(tile->x1, image->comps[compno].dx); + tilec->y1 = int_ceildiv(tile->y1, image->comps[compno].dy); + + tilec->numresolutions = tccp->numresolutions; + tilec->resolutions = (opj_tcd_resolution_t *) opj_malloc(tilec->numresolutions * sizeof(opj_tcd_resolution_t)); + + for (resno = 0; resno < tilec->numresolutions; resno++) { + int pdx, pdy; + int levelno = tilec->numresolutions - 1 - resno; + int tlprcxstart, tlprcystart, brprcxend, brprcyend; + int tlcbgxstart, tlcbgystart, brcbgxend, brcbgyend; + int cbgwidthexpn, cbgheightexpn; + int cblkwidthexpn, cblkheightexpn; + + opj_tcd_resolution_t *res = &tilec->resolutions[resno]; + + /* border for each resolution level (global) */ + res->x0 = int_ceildivpow2(tilec->x0, levelno); + res->y0 = int_ceildivpow2(tilec->y0, levelno); + res->x1 = int_ceildivpow2(tilec->x1, levelno); + res->y1 = int_ceildivpow2(tilec->y1, levelno); + res->numbands = resno == 0 ? 1 : 3; + + /* p. 35, table A-23, ISO/IEC FDIS154444-1 : 2000 (18 august 2000) */ + if (tccp->csty & J2K_CCP_CSTY_PRT) { + pdx = tccp->prcw[resno]; + pdy = tccp->prch[resno]; + } else { + pdx = 15; + pdy = 15; + } + + /* p. 64, B.6, ISO/IEC FDIS15444-1 : 2000 (18 august 2000) */ + tlprcxstart = int_floordivpow2(res->x0, pdx) << pdx; + tlprcystart = int_floordivpow2(res->y0, pdy) << pdy; + brprcxend = int_ceildivpow2(res->x1, pdx) << pdx; + brprcyend = int_ceildivpow2(res->y1, pdy) << pdy; + + res->pw = (res->x0 == res->x1) ? 0 : ((brprcxend - tlprcxstart) >> pdx); + res->ph = (res->y0 == res->y1) ? 0 : ((brprcyend - tlprcystart) >> pdy); + + if (resno == 0) { + tlcbgxstart = tlprcxstart; + tlcbgystart = tlprcystart; + brcbgxend = brprcxend; + brcbgyend = brprcyend; + cbgwidthexpn = pdx; + cbgheightexpn = pdy; + } else { + tlcbgxstart = int_ceildivpow2(tlprcxstart, 1); + tlcbgystart = int_ceildivpow2(tlprcystart, 1); + brcbgxend = int_ceildivpow2(brprcxend, 1); + brcbgyend = int_ceildivpow2(brprcyend, 1); + cbgwidthexpn = pdx - 1; + cbgheightexpn = pdy - 1; + } + + cblkwidthexpn = int_min(tccp->cblkw, cbgwidthexpn); + cblkheightexpn = int_min(tccp->cblkh, cbgheightexpn); + + for (bandno = 0; bandno < res->numbands; bandno++) { + int x0b, y0b; + int gain, numbps; + opj_stepsize_t *ss = NULL; + + opj_tcd_band_t *band = &res->bands[bandno]; + band->bandno = resno == 0 ? 0 : bandno + 1; + x0b = (band->bandno == 1) || (band->bandno == 3) ? 1 : 0; + y0b = (band->bandno == 2) || (band->bandno == 3) ? 1 : 0; + + if (band->bandno == 0) { + /* band border (global) */ + band->x0 = int_ceildivpow2(tilec->x0, levelno); + band->y0 = int_ceildivpow2(tilec->y0, levelno); + band->x1 = int_ceildivpow2(tilec->x1, levelno); + band->y1 = int_ceildivpow2(tilec->y1, levelno); + } else { + /* band border (global) */ + band->x0 = int_ceildivpow2(tilec->x0 - (1 << levelno) * x0b, levelno + 1); + band->y0 = int_ceildivpow2(tilec->y0 - (1 << levelno) * y0b, levelno + 1); + band->x1 = int_ceildivpow2(tilec->x1 - (1 << levelno) * x0b, levelno + 1); + band->y1 = int_ceildivpow2(tilec->y1 - (1 << levelno) * y0b, levelno + 1); + } + + ss = &tccp->stepsizes[resno == 0 ? 0 : 3 * (resno - 1) + bandno + 1]; + gain = tccp->qmfbid == 0 ? dwt_getgain_real(band->bandno) : dwt_getgain(band->bandno); + numbps = image->comps[compno].prec + gain; + band->stepsize = (float)(((1.0 + ss->mant / 2048.0) * pow(2.0, numbps - ss->expn)) * 0.5); + band->numbps = ss->expn + tccp->numgbits - 1; /* WHY -1 ? */ + + band->precincts = (opj_tcd_precinct_t *) opj_malloc(res->pw * res->ph * sizeof(opj_tcd_precinct_t)); + + for (precno = 0; precno < res->pw * res->ph; precno++) { + int tlcblkxstart, tlcblkystart, brcblkxend, brcblkyend; + int cbgxstart = tlcbgxstart + (precno % res->pw) * (1 << cbgwidthexpn); + int cbgystart = tlcbgystart + (precno / res->pw) * (1 << cbgheightexpn); + int cbgxend = cbgxstart + (1 << cbgwidthexpn); + int cbgyend = cbgystart + (1 << cbgheightexpn); + + opj_tcd_precinct_t *prc = &band->precincts[precno]; + /* precinct size (global) */ + prc->x0 = int_max(cbgxstart, band->x0); + prc->y0 = int_max(cbgystart, band->y0); + prc->x1 = int_min(cbgxend, band->x1); + prc->y1 = int_min(cbgyend, band->y1); + + tlcblkxstart = int_floordivpow2(prc->x0, cblkwidthexpn) << cblkwidthexpn; + tlcblkystart = int_floordivpow2(prc->y0, cblkheightexpn) << cblkheightexpn; + brcblkxend = int_ceildivpow2(prc->x1, cblkwidthexpn) << cblkwidthexpn; + brcblkyend = int_ceildivpow2(prc->y1, cblkheightexpn) << cblkheightexpn; + prc->cw = (brcblkxend - tlcblkxstart) >> cblkwidthexpn; + prc->ch = (brcblkyend - tlcblkystart) >> cblkheightexpn; + + prc->cblks.dec = (opj_tcd_cblk_dec_t*) opj_malloc(prc->cw * prc->ch * sizeof(opj_tcd_cblk_dec_t)); + + prc->incltree = tgt_create(prc->cw, prc->ch); + prc->imsbtree = tgt_create(prc->cw, prc->ch); + + for (cblkno = 0; cblkno < prc->cw * prc->ch; cblkno++) { + int cblkxstart = tlcblkxstart + (cblkno % prc->cw) * (1 << cblkwidthexpn); + int cblkystart = tlcblkystart + (cblkno / prc->cw) * (1 << cblkheightexpn); + int cblkxend = cblkxstart + (1 << cblkwidthexpn); + int cblkyend = cblkystart + (1 << cblkheightexpn); + + opj_tcd_cblk_dec_t* cblk = &prc->cblks.dec[cblkno]; + cblk->data = NULL; + cblk->segs = NULL; + /* code-block size (global) */ + cblk->x0 = int_max(cblkxstart, prc->x0); + cblk->y0 = int_max(cblkystart, prc->y0); + cblk->x1 = int_min(cblkxend, prc->x1); + cblk->y1 = int_min(cblkyend, prc->y1); + cblk->numsegs = 0; + } + } /* precno */ + } /* bandno */ + } /* resno */ + } /* compno */ + /* tcd_dump(stdout, tcd, &tcd->tcd_image); */ +} + +void tcd_makelayer_fixed(opj_tcd_t *tcd, int layno, int final) { + int compno, resno, bandno, precno, cblkno; + int value; /*, matrice[tcd_tcp->numlayers][tcd_tile->comps[0].numresolutions][3]; */ + int matrice[10][10][3]; + int i, j, k; + + opj_cp_t *cp = tcd->cp; + opj_tcd_tile_t *tcd_tile = tcd->tcd_tile; + opj_tcp_t *tcd_tcp = tcd->tcp; + + /*matrice=(int*)opj_malloc(tcd_tcp->numlayers*tcd_tile->comps[0].numresolutions*3*sizeof(int)); */ + + for (compno = 0; compno < tcd_tile->numcomps; compno++) { + opj_tcd_tilecomp_t *tilec = &tcd_tile->comps[compno]; + for (i = 0; i < tcd_tcp->numlayers; i++) { + for (j = 0; j < tilec->numresolutions; j++) { + for (k = 0; k < 3; k++) { + matrice[i][j][k] = + (int) (cp->matrice[i * tilec->numresolutions * 3 + j * 3 + k] + * (float) (tcd->image->comps[compno].prec / 16.0)); + } + } + } + + for (resno = 0; resno < tilec->numresolutions; resno++) { + opj_tcd_resolution_t *res = &tilec->resolutions[resno]; + for (bandno = 0; bandno < res->numbands; bandno++) { + opj_tcd_band_t *band = &res->bands[bandno]; + for (precno = 0; precno < res->pw * res->ph; precno++) { + opj_tcd_precinct_t *prc = &band->precincts[precno]; + for (cblkno = 0; cblkno < prc->cw * prc->ch; cblkno++) { + opj_tcd_cblk_enc_t *cblk = &prc->cblks.enc[cblkno]; + opj_tcd_layer_t *layer = &cblk->layers[layno]; + int n; + int imsb = tcd->image->comps[compno].prec - cblk->numbps; /* number of bit-plan equal to zero */ + /* Correction of the matrix of coefficient to include the IMSB information */ + if (layno == 0) { + value = matrice[layno][resno][bandno]; + if (imsb >= value) { + value = 0; + } else { + value -= imsb; + } + } else { + value = matrice[layno][resno][bandno] - matrice[layno - 1][resno][bandno]; + if (imsb >= matrice[layno - 1][resno][bandno]) { + value -= (imsb - matrice[layno - 1][resno][bandno]); + if (value < 0) { + value = 0; + } + } + } + + if (layno == 0) { + cblk->numpassesinlayers = 0; + } + + n = cblk->numpassesinlayers; + if (cblk->numpassesinlayers == 0) { + if (value != 0) { + n = 3 * value - 2 + cblk->numpassesinlayers; + } else { + n = cblk->numpassesinlayers; + } + } else { + n = 3 * value + cblk->numpassesinlayers; + } + + layer->numpasses = n - cblk->numpassesinlayers; + + if (!layer->numpasses) + continue; + + if (cblk->numpassesinlayers == 0) { + layer->len = cblk->passes[n - 1].rate; + layer->data = cblk->data; + } else { + layer->len = cblk->passes[n - 1].rate - cblk->passes[cblk->numpassesinlayers - 1].rate; + layer->data = cblk->data + cblk->passes[cblk->numpassesinlayers - 1].rate; + } + if (final) + cblk->numpassesinlayers = n; + } + } + } + } + } +} + +void tcd_rateallocate_fixed(opj_tcd_t *tcd) { + int layno; + for (layno = 0; layno < tcd->tcp->numlayers; layno++) { + tcd_makelayer_fixed(tcd, layno, 1); + } +} + +void tcd_makelayer(opj_tcd_t *tcd, int layno, double thresh, int final) { + int compno, resno, bandno, precno, cblkno, passno; + + opj_tcd_tile_t *tcd_tile = tcd->tcd_tile; + + tcd_tile->distolayer[layno] = 0; /* fixed_quality */ + + for (compno = 0; compno < tcd_tile->numcomps; compno++) { + opj_tcd_tilecomp_t *tilec = &tcd_tile->comps[compno]; + for (resno = 0; resno < tilec->numresolutions; resno++) { + opj_tcd_resolution_t *res = &tilec->resolutions[resno]; + for (bandno = 0; bandno < res->numbands; bandno++) { + opj_tcd_band_t *band = &res->bands[bandno]; + for (precno = 0; precno < res->pw * res->ph; precno++) { + opj_tcd_precinct_t *prc = &band->precincts[precno]; + for (cblkno = 0; cblkno < prc->cw * prc->ch; cblkno++) { + opj_tcd_cblk_enc_t *cblk = &prc->cblks.enc[cblkno]; + opj_tcd_layer_t *layer = &cblk->layers[layno]; + + int n; + if (layno == 0) { + cblk->numpassesinlayers = 0; + } + n = cblk->numpassesinlayers; + for (passno = cblk->numpassesinlayers; passno < cblk->totalpasses; passno++) { + int dr; + double dd; + opj_tcd_pass_t *pass = &cblk->passes[passno]; + if (n == 0) { + dr = pass->rate; + dd = pass->distortiondec; + } else { + dr = pass->rate - cblk->passes[n - 1].rate; + dd = pass->distortiondec - cblk->passes[n - 1].distortiondec; + } + if (!dr) { + if (dd != 0) + n = passno + 1; + continue; + } + if (dd / dr >= thresh) + n = passno + 1; + } + layer->numpasses = n - cblk->numpassesinlayers; + + if (!layer->numpasses) { + layer->disto = 0; + continue; + } + if (cblk->numpassesinlayers == 0) { + layer->len = cblk->passes[n - 1].rate; + layer->data = cblk->data; + layer->disto = cblk->passes[n - 1].distortiondec; + } else { + layer->len = cblk->passes[n - 1].rate - cblk->passes[cblk->numpassesinlayers - 1].rate; + layer->data = cblk->data + cblk->passes[cblk->numpassesinlayers - 1].rate; + layer->disto = cblk->passes[n - 1].distortiondec - cblk->passes[cblk->numpassesinlayers - 1].distortiondec; + } + + tcd_tile->distolayer[layno] += layer->disto; /* fixed_quality */ + + if (final) + cblk->numpassesinlayers = n; + } + } + } + } + } +} + +bool tcd_rateallocate(opj_tcd_t *tcd, unsigned char *dest, int len, opj_codestream_info_t *cstr_info) { + int compno, resno, bandno, precno, cblkno, passno, layno; + double min, max; + double cumdisto[100]; /* fixed_quality */ + const double K = 1; /* 1.1; fixed_quality */ + double maxSE = 0; + + opj_cp_t *cp = tcd->cp; + opj_tcd_tile_t *tcd_tile = tcd->tcd_tile; + opj_tcp_t *tcd_tcp = tcd->tcp; + + min = DBL_MAX; + max = 0; + + tcd_tile->numpix = 0; /* fixed_quality */ + + for (compno = 0; compno < tcd_tile->numcomps; compno++) { + opj_tcd_tilecomp_t *tilec = &tcd_tile->comps[compno]; + tilec->numpix = 0; + + for (resno = 0; resno < tilec->numresolutions; resno++) { + opj_tcd_resolution_t *res = &tilec->resolutions[resno]; + + for (bandno = 0; bandno < res->numbands; bandno++) { + opj_tcd_band_t *band = &res->bands[bandno]; + + for (precno = 0; precno < res->pw * res->ph; precno++) { + opj_tcd_precinct_t *prc = &band->precincts[precno]; + + for (cblkno = 0; cblkno < prc->cw * prc->ch; cblkno++) { + opj_tcd_cblk_enc_t *cblk = &prc->cblks.enc[cblkno]; + + for (passno = 0; passno < cblk->totalpasses; passno++) { + opj_tcd_pass_t *pass = &cblk->passes[passno]; + int dr; + double dd, rdslope; + if (passno == 0) { + dr = pass->rate; + dd = pass->distortiondec; + } else { + dr = pass->rate - cblk->passes[passno - 1].rate; + dd = pass->distortiondec - cblk->passes[passno - 1].distortiondec; + } + if (dr == 0) { + continue; + } + rdslope = dd / dr; + if (rdslope < min) { + min = rdslope; + } + if (rdslope > max) { + max = rdslope; + } + } /* passno */ + + /* fixed_quality */ + tcd_tile->numpix += ((cblk->x1 - cblk->x0) * (cblk->y1 - cblk->y0)); + tilec->numpix += ((cblk->x1 - cblk->x0) * (cblk->y1 - cblk->y0)); + } /* cbklno */ + } /* precno */ + } /* bandno */ + } /* resno */ + + maxSE += (((double)(1 << tcd->image->comps[compno].prec) - 1.0) + * ((double)(1 << tcd->image->comps[compno].prec) -1.0)) + * ((double)(tilec->numpix)); + } /* compno */ + + /* index file */ + if(cstr_info) { + opj_tile_info_t *tile_info = &cstr_info->tile[tcd->tcd_tileno]; + tile_info->numpix = tcd_tile->numpix; + tile_info->distotile = tcd_tile->distotile; + tile_info->thresh = (double *) opj_malloc(tcd_tcp->numlayers * sizeof(double)); + } + + for (layno = 0; layno < tcd_tcp->numlayers; layno++) { + double lo = min; + double hi = max; + int success = 0; + int maxlen = tcd_tcp->rates[layno] ? int_min(((int) ceil(tcd_tcp->rates[layno])), len) : len; + double goodthresh = 0; + double stable_thresh = 0; + int i; + double distotarget; /* fixed_quality */ + + /* fixed_quality */ + distotarget = tcd_tile->distotile - ((K * maxSE) / pow((float)10, tcd_tcp->distoratio[layno] / 10)); + + /* Don't try to find an optimal threshold but rather take everything not included yet, if + -r xx,yy,zz,0 (disto_alloc == 1 and rates == 0) + -q xx,yy,zz,0 (fixed_quality == 1 and distoratio == 0) + ==> possible to have some lossy layers and the last layer for sure lossless */ + if ( ((cp->disto_alloc==1) && (tcd_tcp->rates[layno]>0)) || ((cp->fixed_quality==1) && (tcd_tcp->distoratio[layno]>0))) { + opj_t2_t *t2 = t2_create(tcd->cinfo, tcd->image, cp); + double thresh = 0; + + for (i = 0; i < 32; i++) { + int l = 0; + double distoachieved = 0; /* fixed_quality */ + thresh = (lo + hi) / 2; + + tcd_makelayer(tcd, layno, thresh, 0); + + if (cp->fixed_quality) { /* fixed_quality */ + if(cp->cinema){ + l = t2_encode_packets(t2,tcd->tcd_tileno, tcd_tile, layno + 1, dest, maxlen, cstr_info,tcd->cur_tp_num,tcd->tp_pos,tcd->cur_pino,THRESH_CALC, tcd->cur_totnum_tp); + if (l == -999) { + lo = thresh; + continue; + }else{ + distoachieved = layno == 0 ? + tcd_tile->distolayer[0] : cumdisto[layno - 1] + tcd_tile->distolayer[layno]; + if (distoachieved < distotarget) { + hi=thresh; + stable_thresh = thresh; + continue; + }else{ + lo=thresh; + } + } + }else{ + distoachieved = (layno == 0) ? + tcd_tile->distolayer[0] : (cumdisto[layno - 1] + tcd_tile->distolayer[layno]); + if (distoachieved < distotarget) { + hi = thresh; + stable_thresh = thresh; + continue; + } + lo = thresh; + } + } else { + l = t2_encode_packets(t2, tcd->tcd_tileno, tcd_tile, layno + 1, dest, maxlen, cstr_info,tcd->cur_tp_num,tcd->tp_pos,tcd->cur_pino,THRESH_CALC, tcd->cur_totnum_tp); + /* TODO: what to do with l ??? seek / tell ??? */ + /* opj_event_msg(tcd->cinfo, EVT_INFO, "rate alloc: len=%d, max=%d\n", l, maxlen); */ + if (l == -999) { + lo = thresh; + continue; + } + hi = thresh; + stable_thresh = thresh; + } + } + success = 1; + goodthresh = stable_thresh == 0? thresh : stable_thresh; + t2_destroy(t2); + } else { + success = 1; + goodthresh = min; + } + + if (!success) { + return false; + } + + if(cstr_info) { /* Threshold for Marcela Index */ + cstr_info->tile[tcd->tcd_tileno].thresh[layno] = goodthresh; + } + tcd_makelayer(tcd, layno, goodthresh, 1); + + /* fixed_quality */ + cumdisto[layno] = (layno == 0) ? tcd_tile->distolayer[0] : (cumdisto[layno - 1] + tcd_tile->distolayer[layno]); + } + + return true; +} + +int tcd_encode_tile(opj_tcd_t *tcd, int tileno, unsigned char *dest, int len, opj_codestream_info_t *cstr_info) { + int compno; + int l, i, numpacks = 0; + opj_tcd_tile_t *tile = NULL; + opj_tcp_t *tcd_tcp = NULL; + opj_cp_t *cp = NULL; + + opj_tcp_t *tcp = &tcd->cp->tcps[0]; + opj_tccp_t *tccp = &tcp->tccps[0]; + opj_image_t *image = tcd->image; + + opj_t1_t *t1 = NULL; /* T1 component */ + opj_t2_t *t2 = NULL; /* T2 component */ + + tcd->tcd_tileno = tileno; + tcd->tcd_tile = tcd->tcd_image->tiles; + tcd->tcp = &tcd->cp->tcps[tileno]; + + tile = tcd->tcd_tile; + tcd_tcp = tcd->tcp; + cp = tcd->cp; + + if(tcd->cur_tp_num == 0){ + tcd->encoding_time = opj_clock(); /* time needed to encode a tile */ + /* INDEX >> "Precinct_nb_X et Precinct_nb_Y" */ + if(cstr_info) { + opj_tcd_tilecomp_t *tilec_idx = &tile->comps[0]; /* based on component 0 */ + for (i = 0; i < tilec_idx->numresolutions; i++) { + opj_tcd_resolution_t *res_idx = &tilec_idx->resolutions[i]; + + cstr_info->tile[tileno].pw[i] = res_idx->pw; + cstr_info->tile[tileno].ph[i] = res_idx->ph; + + numpacks += res_idx->pw * res_idx->ph; + + cstr_info->tile[tileno].pdx[i] = tccp->prcw[i]; + cstr_info->tile[tileno].pdy[i] = tccp->prch[i]; + } + cstr_info->tile[tileno].packet = (opj_packet_info_t*) opj_calloc(cstr_info->numcomps * cstr_info->numlayers * numpacks, sizeof(opj_packet_info_t)); + } + /* << INDEX */ + + /*---------------TILE-------------------*/ + + for (compno = 0; compno < tile->numcomps; compno++) { + int x, y; + + int adjust = image->comps[compno].sgnd ? 0 : 1 << (image->comps[compno].prec - 1); + int offset_x = int_ceildiv(image->x0, image->comps[compno].dx); + int offset_y = int_ceildiv(image->y0, image->comps[compno].dy); + + opj_tcd_tilecomp_t *tilec = &tile->comps[compno]; + int tw = tilec->x1 - tilec->x0; + int w = int_ceildiv(image->x1 - image->x0, image->comps[compno].dx); + + /* extract tile data */ + + if (tcd_tcp->tccps[compno].qmfbid == 1) { + for (y = tilec->y0; y < tilec->y1; y++) { + /* start of the src tile scanline */ + int *data = &image->comps[compno].data[(tilec->x0 - offset_x) + (y - offset_y) * w]; + /* start of the dst tile scanline */ + int *tile_data = &tilec->data[(y - tilec->y0) * tw]; + for (x = tilec->x0; x < tilec->x1; x++) { + *tile_data++ = *data++ - adjust; + } + } + } else if (tcd_tcp->tccps[compno].qmfbid == 0) { + for (y = tilec->y0; y < tilec->y1; y++) { + /* start of the src tile scanline */ + int *data = &image->comps[compno].data[(tilec->x0 - offset_x) + (y - offset_y) * w]; + /* start of the dst tile scanline */ + int *tile_data = &tilec->data[(y - tilec->y0) * tw]; + for (x = tilec->x0; x < tilec->x1; x++) { + *tile_data++ = (*data++ - adjust) << 11; + } + + } + } + } + + /*----------------MCT-------------------*/ + if (tcd_tcp->mct) { + int samples = (tile->comps[0].x1 - tile->comps[0].x0) * (tile->comps[0].y1 - tile->comps[0].y0); + if (tcd_tcp->tccps[0].qmfbid == 0) { + mct_encode_real(tile->comps[0].data, tile->comps[1].data, tile->comps[2].data, samples); + } else { + mct_encode(tile->comps[0].data, tile->comps[1].data, tile->comps[2].data, samples); + } + } + + /*----------------DWT---------------------*/ + + for (compno = 0; compno < tile->numcomps; compno++) { + opj_tcd_tilecomp_t *tilec = &tile->comps[compno]; + if (tcd_tcp->tccps[compno].qmfbid == 1) { + dwt_encode(tilec); + } else if (tcd_tcp->tccps[compno].qmfbid == 0) { + dwt_encode_real(tilec); + } + } + + /*------------------TIER1-----------------*/ + t1 = t1_create(tcd->cinfo); + t1_encode_cblks(t1, tile, tcd_tcp); + t1_destroy(t1); + + /*-----------RATE-ALLOCATE------------------*/ + + /* INDEX */ + if(cstr_info) { + cstr_info->index_write = 0; + } + if (cp->disto_alloc || cp->fixed_quality) { /* fixed_quality */ + /* Normal Rate/distortion allocation */ + tcd_rateallocate(tcd, dest, len, cstr_info); + } else { + /* Fixed layer allocation */ + tcd_rateallocate_fixed(tcd); + } + } + /*--------------TIER2------------------*/ + + /* INDEX */ + if(cstr_info) { + cstr_info->index_write = 1; + } + + t2 = t2_create(tcd->cinfo, image, cp); + l = t2_encode_packets(t2,tileno, tile, tcd_tcp->numlayers, dest, len, cstr_info,tcd->tp_num,tcd->tp_pos,tcd->cur_pino,FINAL_PASS,tcd->cur_totnum_tp); + t2_destroy(t2); + + /*---------------CLEAN-------------------*/ + + + if(tcd->cur_tp_num == tcd->cur_totnum_tp - 1){ + tcd->encoding_time = opj_clock() - tcd->encoding_time; + opj_event_msg(tcd->cinfo, EVT_INFO, "- tile encoded in %f s\n", tcd->encoding_time); + + /* cleaning memory */ + for (compno = 0; compno < tile->numcomps; compno++) { + opj_tcd_tilecomp_t *tilec = &tile->comps[compno]; + opj_aligned_free(tilec->data); + } + } + + return l; +} + +bool tcd_decode_tile(opj_tcd_t *tcd, unsigned char *src, int len, int tileno, opj_codestream_info_t *cstr_info) { + int l; + int compno; + int eof = 0; + double tile_time, t1_time, dwt_time; + opj_tcd_tile_t *tile = NULL; + + opj_t1_t *t1 = NULL; /* T1 component */ + opj_t2_t *t2 = NULL; /* T2 component */ + + tcd->tcd_tileno = tileno; + tcd->tcd_tile = &(tcd->tcd_image->tiles[tileno]); + tcd->tcp = &(tcd->cp->tcps[tileno]); + tile = tcd->tcd_tile; + + tile_time = opj_clock(); /* time needed to decode a tile */ + opj_event_msg(tcd->cinfo, EVT_INFO, "tile %d of %d\n", tileno + 1, tcd->cp->tw * tcd->cp->th); + + /* INDEX >> */ + if(cstr_info) { + int resno, compno, numprec = 0; + for (compno = 0; compno < cstr_info->numcomps; compno++) { + opj_tcp_t *tcp = &tcd->cp->tcps[0]; + opj_tccp_t *tccp = &tcp->tccps[compno]; + opj_tcd_tilecomp_t *tilec_idx = &tile->comps[compno]; + for (resno = 0; resno < tilec_idx->numresolutions; resno++) { + opj_tcd_resolution_t *res_idx = &tilec_idx->resolutions[resno]; + cstr_info->tile[tileno].pw[resno] = res_idx->pw; + cstr_info->tile[tileno].ph[resno] = res_idx->ph; + numprec += res_idx->pw * res_idx->ph; + if (tccp->csty & J2K_CP_CSTY_PRT) { + cstr_info->tile[tileno].pdx[resno] = tccp->prcw[resno]; + cstr_info->tile[tileno].pdy[resno] = tccp->prch[resno]; + } + else { + cstr_info->tile[tileno].pdx[resno] = 15; + cstr_info->tile[tileno].pdx[resno] = 15; + } + } + } + cstr_info->tile[tileno].packet = (opj_packet_info_t *) opj_malloc(cstr_info->numlayers * numprec * sizeof(opj_packet_info_t)); + cstr_info->packno = 0; + } + /* << INDEX */ + + /*--------------TIER2------------------*/ + + t2 = t2_create(tcd->cinfo, tcd->image, tcd->cp); + l = t2_decode_packets(t2, src, len, tileno, tile, cstr_info); + t2_destroy(t2); + + if (l == -999) { + eof = 1; + opj_event_msg(tcd->cinfo, EVT_ERROR, "tcd_decode: incomplete bistream\n"); + } + + /*------------------TIER1-----------------*/ + + t1_time = opj_clock(); /* time needed to decode a tile */ + t1 = t1_create(tcd->cinfo); + for (compno = 0; compno < tile->numcomps; ++compno) { + opj_tcd_tilecomp_t* tilec = &tile->comps[compno]; + /* The +3 is headroom required by the vectorized DWT */ + tilec->data = (int*) opj_aligned_malloc((((tilec->x1 - tilec->x0) * (tilec->y1 - tilec->y0))+3) * sizeof(int)); + t1_decode_cblks(t1, tilec, &tcd->tcp->tccps[compno]); + } + t1_destroy(t1); + t1_time = opj_clock() - t1_time; + opj_event_msg(tcd->cinfo, EVT_INFO, "- tiers-1 took %f s\n", t1_time); + + /*----------------DWT---------------------*/ + + dwt_time = opj_clock(); /* time needed to decode a tile */ + for (compno = 0; compno < tile->numcomps; compno++) { + opj_tcd_tilecomp_t *tilec = &tile->comps[compno]; + int numres2decode; + + if (tcd->cp->reduce != 0) { + tcd->image->comps[compno].resno_decoded = + tile->comps[compno].numresolutions - tcd->cp->reduce - 1; + if (tcd->image->comps[compno].resno_decoded < 0) { + opj_event_msg(tcd->cinfo, EVT_ERROR, "Error decoding tile. The number of resolutions to remove [%d+1] is higher than the number " + " of resolutions in the original codestream [%d]\nModify the cp_reduce parameter.\n", tcd->cp->reduce, tile->comps[compno].numresolutions); + return false; + } + } + + numres2decode = tcd->image->comps[compno].resno_decoded + 1; + if(numres2decode > 0){ + if (tcd->tcp->tccps[compno].qmfbid == 1) { + dwt_decode(tilec, numres2decode); + } else { + dwt_decode_real(tilec, numres2decode); + } + } + } + dwt_time = opj_clock() - dwt_time; + opj_event_msg(tcd->cinfo, EVT_INFO, "- dwt took %f s\n", dwt_time); + + /*----------------MCT-------------------*/ + + if (tcd->tcp->mct) { + int n = (tile->comps[0].x1 - tile->comps[0].x0) * (tile->comps[0].y1 - tile->comps[0].y0); + if (tcd->tcp->tccps[0].qmfbid == 1) { + mct_decode( + tile->comps[0].data, + tile->comps[1].data, + tile->comps[2].data, + n); + } else { + mct_decode_real( + (float*)tile->comps[0].data, + (float*)tile->comps[1].data, + (float*)tile->comps[2].data, + n); + } + } + + /*---------------TILE-------------------*/ + + for (compno = 0; compno < tile->numcomps; ++compno) { + opj_tcd_tilecomp_t* tilec = &tile->comps[compno]; + opj_image_comp_t* imagec = &tcd->image->comps[compno]; + opj_tcd_resolution_t* res = &tilec->resolutions[imagec->resno_decoded]; + int adjust = imagec->sgnd ? 0 : 1 << (imagec->prec - 1); + int min = imagec->sgnd ? -(1 << (imagec->prec - 1)) : 0; + int max = imagec->sgnd ? (1 << (imagec->prec - 1)) - 1 : (1 << imagec->prec) - 1; + + int tw = tilec->x1 - tilec->x0; + int w = imagec->w; + + int offset_x = int_ceildivpow2(imagec->x0, imagec->factor); + int offset_y = int_ceildivpow2(imagec->y0, imagec->factor); + + int i, j; + if(!imagec->data){ + imagec->data = (int*) opj_malloc(imagec->w * imagec->h * sizeof(int)); + } + if(tcd->tcp->tccps[compno].qmfbid == 1) { + for(j = res->y0; j < res->y1; ++j) { + for(i = res->x0; i < res->x1; ++i) { + int v = tilec->data[i - res->x0 + (j - res->y0) * tw]; + v += adjust; + imagec->data[(i - offset_x) + (j - offset_y) * w] = int_clamp(v, min, max); + } + } + }else{ + for(j = res->y0; j < res->y1; ++j) { + for(i = res->x0; i < res->x1; ++i) { + float tmp = ((float*)tilec->data)[i - res->x0 + (j - res->y0) * tw]; + int v = lrintf(tmp); + v += adjust; + imagec->data[(i - offset_x) + (j - offset_y) * w] = int_clamp(v, min, max); + } + } + } + opj_aligned_free(tilec->data); + } + + tile_time = opj_clock() - tile_time; /* time needed to decode a tile */ + opj_event_msg(tcd->cinfo, EVT_INFO, "- tile decoded in %f s\n", tile_time); + + if (eof) { + return false; + } + + return true; +} + +void tcd_free_decode(opj_tcd_t *tcd) { + opj_tcd_image_t *tcd_image = tcd->tcd_image; + opj_free(tcd_image->tiles); +} + +void tcd_free_decode_tile(opj_tcd_t *tcd, int tileno) { + int compno,resno,bandno,precno; + + opj_tcd_image_t *tcd_image = tcd->tcd_image; + + opj_tcd_tile_t *tile = &tcd_image->tiles[tileno]; + for (compno = 0; compno < tile->numcomps; compno++) { + opj_tcd_tilecomp_t *tilec = &tile->comps[compno]; + for (resno = 0; resno < tilec->numresolutions; resno++) { + opj_tcd_resolution_t *res = &tilec->resolutions[resno]; + for (bandno = 0; bandno < res->numbands; bandno++) { + opj_tcd_band_t *band = &res->bands[bandno]; + for (precno = 0; precno < res->ph * res->pw; precno++) { + opj_tcd_precinct_t *prec = &band->precincts[precno]; + if (prec->imsbtree != NULL) tgt_destroy(prec->imsbtree); + if (prec->incltree != NULL) tgt_destroy(prec->incltree); + } + opj_free(band->precincts); + } + } + opj_free(tilec->resolutions); + } + opj_free(tile->comps); +} + + diff --git a/extern/libopenjpeg/tcd.h b/extern/libopenjpeg/tcd.h new file mode 100644 index 00000000000..f0ac5619f1e --- /dev/null +++ b/extern/libopenjpeg/tcd.h @@ -0,0 +1,285 @@ +/* + * Copyright (c) 2002-2007, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium + * Copyright (c) 2002-2007, Professor Benoit Macq + * Copyright (c) 2001-2003, David Janssens + * Copyright (c) 2002-2003, Yannick Verschueren + * Copyright (c) 2003-2007, Francois-Olivier Devaux and Antonin Descampe + * Copyright (c) 2005, Herve Drolon, FreeImage Team + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 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. + */ +#ifndef __TCD_H +#define __TCD_H +/** +@file tcd.h +@brief Implementation of a tile coder/decoder (TCD) + +The functions in TCD.C have for goal to encode or decode each tile independently from +each other. The functions in TCD.C are used by some function in J2K.C. +*/ + +/** @defgroup TCD TCD - Implementation of a tile coder/decoder */ +/*@{*/ + +/** +FIXME: documentation +*/ +typedef struct opj_tcd_seg { + unsigned char** data; + int dataindex; + int numpasses; + int len; + int maxpasses; + int numnewpasses; + int newlen; +} opj_tcd_seg_t; + +/** +FIXME: documentation +*/ +typedef struct opj_tcd_pass { + int rate; + double distortiondec; + int term, len; +} opj_tcd_pass_t; + +/** +FIXME: documentation +*/ +typedef struct opj_tcd_layer { + int numpasses; /* Number of passes in the layer */ + int len; /* len of information */ + double disto; /* add for index (Cfr. Marcela) */ + unsigned char *data; /* data */ +} opj_tcd_layer_t; + +/** +FIXME: documentation +*/ +typedef struct opj_tcd_cblk_enc { + unsigned char* data; /* Data */ + opj_tcd_layer_t* layers; /* layer information */ + opj_tcd_pass_t* passes; /* information about the passes */ + int x0, y0, x1, y1; /* dimension of the code-blocks : left upper corner (x0, y0) right low corner (x1,y1) */ + int numbps; + int numlenbits; + int numpasses; /* number of pass already done for the code-blocks */ + int numpassesinlayers; /* number of passes in the layer */ + int totalpasses; /* total number of passes */ +} opj_tcd_cblk_enc_t; + +typedef struct opj_tcd_cblk_dec { + unsigned char* data; /* Data */ + opj_tcd_seg_t* segs; /* segments informations */ + int x0, y0, x1, y1; /* dimension of the code-blocks : left upper corner (x0, y0) right low corner (x1,y1) */ + int numbps; + int numlenbits; + int len; /* length */ + int numnewpasses; /* number of pass added to the code-blocks */ + int numsegs; /* number of segments */ +} opj_tcd_cblk_dec_t; + +/** +FIXME: documentation +*/ +typedef struct opj_tcd_precinct { + int x0, y0, x1, y1; /* dimension of the precinct : left upper corner (x0, y0) right low corner (x1,y1) */ + int cw, ch; /* number of precinct in width and heigth */ + union{ /* code-blocks informations */ + opj_tcd_cblk_enc_t* enc; + opj_tcd_cblk_dec_t* dec; + } cblks; + opj_tgt_tree_t *incltree; /* inclusion tree */ + opj_tgt_tree_t *imsbtree; /* IMSB tree */ +} opj_tcd_precinct_t; + +/** +FIXME: documentation +*/ +typedef struct opj_tcd_band { + int x0, y0, x1, y1; /* dimension of the subband : left upper corner (x0, y0) right low corner (x1,y1) */ + int bandno; + opj_tcd_precinct_t *precincts; /* precinct information */ + int numbps; + float stepsize; +} opj_tcd_band_t; + +/** +FIXME: documentation +*/ +typedef struct opj_tcd_resolution { + int x0, y0, x1, y1; /* dimension of the resolution level : left upper corner (x0, y0) right low corner (x1,y1) */ + int pw, ph; + int numbands; /* number sub-band for the resolution level */ + opj_tcd_band_t bands[3]; /* subband information */ +} opj_tcd_resolution_t; + +/** +FIXME: documentation +*/ +typedef struct opj_tcd_tilecomp { + int x0, y0, x1, y1; /* dimension of component : left upper corner (x0, y0) right low corner (x1,y1) */ + int numresolutions; /* number of resolutions level */ + opj_tcd_resolution_t *resolutions; /* resolutions information */ + int *data; /* data of the component */ + int numpix; /* add fixed_quality */ +} opj_tcd_tilecomp_t; + +/** +FIXME: documentation +*/ +typedef struct opj_tcd_tile { + int x0, y0, x1, y1; /* dimension of the tile : left upper corner (x0, y0) right low corner (x1,y1) */ + int numcomps; /* number of components in tile */ + opj_tcd_tilecomp_t *comps; /* Components information */ + int numpix; /* add fixed_quality */ + double distotile; /* add fixed_quality */ + double distolayer[100]; /* add fixed_quality */ + /** packet number */ + int packno; +} opj_tcd_tile_t; + +/** +FIXME: documentation +*/ +typedef struct opj_tcd_image { + int tw, th; /* number of tiles in width and heigth */ + opj_tcd_tile_t *tiles; /* Tiles information */ +} opj_tcd_image_t; + +/** +Tile coder/decoder +*/ +typedef struct opj_tcd { + /** Position of the tilepart flag in Progression order*/ + int tp_pos; + /** Tile part number*/ + int tp_num; + /** Current tile part number*/ + int cur_tp_num; + /** Total number of tileparts of the current tile*/ + int cur_totnum_tp; + /** Current Packet iterator number */ + int cur_pino; + /** codec context */ + opj_common_ptr cinfo; + + /** info on each image tile */ + opj_tcd_image_t *tcd_image; + /** image */ + opj_image_t *image; + /** coding parameters */ + opj_cp_t *cp; + /** pointer to the current encoded/decoded tile */ + opj_tcd_tile_t *tcd_tile; + /** coding/decoding parameters common to all tiles */ + opj_tcp_t *tcp; + /** current encoded/decoded tile */ + int tcd_tileno; + /** Time taken to encode a tile*/ + double encoding_time; +} opj_tcd_t; + +/** @name Exported functions */ +/*@{*/ +/* ----------------------------------------------------------------------- */ + +/** +Dump the content of a tcd structure +*/ +void tcd_dump(FILE *fd, opj_tcd_t *tcd, opj_tcd_image_t *img); +/** +Create a new TCD handle +@param cinfo Codec context info +@return Returns a new TCD handle if successful returns NULL otherwise +*/ +opj_tcd_t* tcd_create(opj_common_ptr cinfo); +/** +Destroy a previously created TCD handle +@param tcd TCD handle to destroy +*/ +void tcd_destroy(opj_tcd_t *tcd); +/** +Initialize the tile coder (allocate the memory) +@param tcd TCD handle +@param image Raw image +@param cp Coding parameters +@param curtileno Number that identifies the tile that will be encoded +*/ +void tcd_malloc_encode(opj_tcd_t *tcd, opj_image_t * image, opj_cp_t * cp, int curtileno); +/** +Free the memory allocated for encoding +@param tcd TCD handle +*/ +void tcd_free_encode(opj_tcd_t *tcd); +/** +Initialize the tile coder (reuses the memory allocated by tcd_malloc_encode) +@param tcd TCD handle +@param image Raw image +@param cp Coding parameters +@param curtileno Number that identifies the tile that will be encoded +*/ +void tcd_init_encode(opj_tcd_t *tcd, opj_image_t * image, opj_cp_t * cp, int curtileno); +/** +Initialize the tile decoder +@param tcd TCD handle +@param image Raw image +@param cp Coding parameters +*/ +void tcd_malloc_decode(opj_tcd_t *tcd, opj_image_t * image, opj_cp_t * cp); +void tcd_malloc_decode_tile(opj_tcd_t *tcd, opj_image_t * image, opj_cp_t * cp, int tileno, opj_codestream_info_t *cstr_info); +void tcd_makelayer_fixed(opj_tcd_t *tcd, int layno, int final); +void tcd_rateallocate_fixed(opj_tcd_t *tcd); +void tcd_makelayer(opj_tcd_t *tcd, int layno, double thresh, int final); +bool tcd_rateallocate(opj_tcd_t *tcd, unsigned char *dest, int len, opj_codestream_info_t *cstr_info); +/** +Encode a tile from the raw image into a buffer +@param tcd TCD handle +@param tileno Number that identifies one of the tiles to be encoded +@param dest Destination buffer +@param len Length of destination buffer +@param cstr_info Codestream information structure +@return +*/ +int tcd_encode_tile(opj_tcd_t *tcd, int tileno, unsigned char *dest, int len, opj_codestream_info_t *cstr_info); +/** +Decode a tile from a buffer into a raw image +@param tcd TCD handle +@param src Source buffer +@param len Length of source buffer +@param tileno Number that identifies one of the tiles to be decoded +*/ +bool tcd_decode_tile(opj_tcd_t *tcd, unsigned char *src, int len, int tileno, opj_codestream_info_t *cstr_info); +/** +Free the memory allocated for decoding +@param tcd TCD handle +*/ +void tcd_free_decode(opj_tcd_t *tcd); +void tcd_free_decode_tile(opj_tcd_t *tcd, int tileno); + +/* ----------------------------------------------------------------------- */ +/*@}*/ + +/*@}*/ + +#endif /* __TCD_H */ diff --git a/extern/libopenjpeg/tgt.c b/extern/libopenjpeg/tgt.c new file mode 100644 index 00000000000..a5dbcd3cef4 --- /dev/null +++ b/extern/libopenjpeg/tgt.c @@ -0,0 +1,213 @@ +/* + * Copyright (c) 2002-2007, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium + * Copyright (c) 2002-2007, Professor Benoit Macq + * Copyright (c) 2001-2003, David Janssens + * Copyright (c) 2002-2003, Yannick Verschueren + * Copyright (c) 2003-2007, Francois-Olivier Devaux and Antonin Descampe + * Copyright (c) 2005, Herve Drolon, FreeImage Team + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 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. + */ + +#include "opj_includes.h" + +/* +========================================================== + Tag-tree coder interface +========================================================== +*/ + +opj_tgt_tree_t *tgt_create(int numleafsh, int numleafsv) { + int nplh[32]; + int nplv[32]; + opj_tgt_node_t *node = NULL; + opj_tgt_node_t *parentnode = NULL; + opj_tgt_node_t *parentnode0 = NULL; + opj_tgt_tree_t *tree = NULL; + int i, j, k; + int numlvls; + int n; + + tree = (opj_tgt_tree_t *) opj_malloc(sizeof(opj_tgt_tree_t)); + if(!tree) return NULL; + tree->numleafsh = numleafsh; + tree->numleafsv = numleafsv; + + numlvls = 0; + nplh[0] = numleafsh; + nplv[0] = numleafsv; + tree->numnodes = 0; + do { + n = nplh[numlvls] * nplv[numlvls]; + nplh[numlvls + 1] = (nplh[numlvls] + 1) / 2; + nplv[numlvls + 1] = (nplv[numlvls] + 1) / 2; + tree->numnodes += n; + ++numlvls; + } while (n > 1); + + /* ADD */ + if (tree->numnodes == 0) { + opj_free(tree); + return NULL; + } + + tree->nodes = (opj_tgt_node_t*) opj_calloc(tree->numnodes, sizeof(opj_tgt_node_t)); + if(!tree->nodes) { + opj_free(tree); + return NULL; + } + + node = tree->nodes; + parentnode = &tree->nodes[tree->numleafsh * tree->numleafsv]; + parentnode0 = parentnode; + + for (i = 0; i < numlvls - 1; ++i) { + for (j = 0; j < nplv[i]; ++j) { + k = nplh[i]; + while (--k >= 0) { + node->parent = parentnode; + ++node; + if (--k >= 0) { + node->parent = parentnode; + ++node; + } + ++parentnode; + } + if ((j & 1) || j == nplv[i] - 1) { + parentnode0 = parentnode; + } else { + parentnode = parentnode0; + parentnode0 += nplh[i]; + } + } + } + node->parent = 0; + + tgt_reset(tree); + + return tree; +} + +void tgt_destroy(opj_tgt_tree_t *tree) { + opj_free(tree->nodes); + opj_free(tree); +} + +void tgt_reset(opj_tgt_tree_t *tree) { + int i; + + if (NULL == tree) + return; + + for (i = 0; i < tree->numnodes; i++) { + tree->nodes[i].value = 999; + tree->nodes[i].low = 0; + tree->nodes[i].known = 0; + } +} + +void tgt_setvalue(opj_tgt_tree_t *tree, int leafno, int value) { + opj_tgt_node_t *node; + node = &tree->nodes[leafno]; + while (node && node->value > value) { + node->value = value; + node = node->parent; + } +} + +void tgt_encode(opj_bio_t *bio, opj_tgt_tree_t *tree, int leafno, int threshold) { + opj_tgt_node_t *stk[31]; + opj_tgt_node_t **stkptr; + opj_tgt_node_t *node; + int low; + + stkptr = stk; + node = &tree->nodes[leafno]; + while (node->parent) { + *stkptr++ = node; + node = node->parent; + } + + low = 0; + for (;;) { + if (low > node->low) { + node->low = low; + } else { + low = node->low; + } + + while (low < threshold) { + if (low >= node->value) { + if (!node->known) { + bio_write(bio, 1, 1); + node->known = 1; + } + break; + } + bio_write(bio, 0, 1); + ++low; + } + + node->low = low; + if (stkptr == stk) + break; + node = *--stkptr; + } +} + +int tgt_decode(opj_bio_t *bio, opj_tgt_tree_t *tree, int leafno, int threshold) { + opj_tgt_node_t *stk[31]; + opj_tgt_node_t **stkptr; + opj_tgt_node_t *node; + int low; + + stkptr = stk; + node = &tree->nodes[leafno]; + while (node->parent) { + *stkptr++ = node; + node = node->parent; + } + + low = 0; + for (;;) { + if (low > node->low) { + node->low = low; + } else { + low = node->low; + } + while (low < threshold && low < node->value) { + if (bio_read(bio, 1)) { + node->value = low; + } else { + ++low; + } + } + node->low = low; + if (stkptr == stk) { + break; + } + node = *--stkptr; + } + + return (node->value < threshold) ? 1 : 0; +} diff --git a/extern/libopenjpeg/tgt.h b/extern/libopenjpeg/tgt.h new file mode 100644 index 00000000000..c08c8da0af4 --- /dev/null +++ b/extern/libopenjpeg/tgt.h @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2002-2007, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium + * Copyright (c) 2002-2007, Professor Benoit Macq + * Copyright (c) 2001-2003, David Janssens + * Copyright (c) 2002-2003, Yannick Verschueren + * Copyright (c) 2003-2007, Francois-Olivier Devaux and Antonin Descampe + * Copyright (c) 2005, Herve Drolon, FreeImage Team + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * 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. + */ + +#ifndef __TGT_H +#define __TGT_H +/** +@file tgt.h +@brief Implementation of a tag-tree coder (TGT) + +The functions in TGT.C have for goal to realize a tag-tree coder. The functions in TGT.C +are used by some function in T2.C. +*/ + +/** @defgroup TGT TGT - Implementation of a tag-tree coder */ +/*@{*/ + +/** +Tag node +*/ +typedef struct opj_tgt_node { + struct opj_tgt_node *parent; + int value; + int low; + int known; +} opj_tgt_node_t; + +/** +Tag tree +*/ +typedef struct opj_tgt_tree { + int numleafsh; + int numleafsv; + int numnodes; + opj_tgt_node_t *nodes; +} opj_tgt_tree_t; + +/** @name Exported functions */ +/*@{*/ +/* ----------------------------------------------------------------------- */ +/** +Create a tag-tree +@param numleafsh Width of the array of leafs of the tree +@param numleafsv Height of the array of leafs of the tree +@return Returns a new tag-tree if successful, returns NULL otherwise +*/ +opj_tgt_tree_t *tgt_create(int numleafsh, int numleafsv); +/** +Destroy a tag-tree, liberating memory +@param tree Tag-tree to destroy +*/ +void tgt_destroy(opj_tgt_tree_t *tree); +/** +Reset a tag-tree (set all leaves to 0) +@param tree Tag-tree to reset +*/ +void tgt_reset(opj_tgt_tree_t *tree); +/** +Set the value of a leaf of a tag-tree +@param tree Tag-tree to modify +@param leafno Number that identifies the leaf to modify +@param value New value of the leaf +*/ +void tgt_setvalue(opj_tgt_tree_t *tree, int leafno, int value); +/** +Encode the value of a leaf of the tag-tree up to a given threshold +@param bio Pointer to a BIO handle +@param tree Tag-tree to modify +@param leafno Number that identifies the leaf to encode +@param threshold Threshold to use when encoding value of the leaf +*/ +void tgt_encode(opj_bio_t *bio, opj_tgt_tree_t *tree, int leafno, int threshold); +/** +Decode the value of a leaf of the tag-tree up to a given threshold +@param bio Pointer to a BIO handle +@param tree Tag-tree to decode +@param leafno Number that identifies the leaf to decode +@param threshold Threshold to use when decoding value of the leaf +@return Returns 1 if the node's value < threshold, returns 0 otherwise +*/ +int tgt_decode(opj_bio_t *bio, opj_tgt_tree_t *tree, int leafno, int threshold); +/* ----------------------------------------------------------------------- */ +/*@}*/ + +/*@}*/ + +#endif /* __TGT_H */ diff --git a/extern/libredcode/AUTHOR b/extern/libredcode/AUTHOR new file mode 100644 index 00000000000..b3d20a4eb7a --- /dev/null +++ b/extern/libredcode/AUTHOR @@ -0,0 +1 @@ +Peter Schlaile * peter at schlaile dot de diff --git a/extern/libredcode/LICENSE b/extern/libredcode/LICENSE new file mode 100644 index 00000000000..14db8fc79db --- /dev/null +++ b/extern/libredcode/LICENSE @@ -0,0 +1,340 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 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. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +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 Program or any portion +of it, thus forming a work based on the Program, 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) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +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 Program, 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 Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) 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; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, 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 executable. However, as a +special exception, the source code 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. + +If distribution of executable or 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 counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program 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. + + 5. 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 Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program 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 to +this License. + + 7. 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 Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program 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 Program. + +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. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program 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. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies 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 Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, 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 + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. 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 PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +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 program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/extern/libredcode/NOTES b/extern/libredcode/NOTES new file mode 100644 index 00000000000..39101e0bd63 --- /dev/null +++ b/extern/libredcode/NOTES @@ -0,0 +1,23 @@ +This is a redcode decoder written solely by looking at some +R3D files that are floating around on the web. + +This decoder works with the files I tested, but I don't give +any guarantee (especially, if RED decides to change the +file format). + +That said: I found it a really nice idea of them, to make +such a clear and comprehensible file layout. + +Choosing JPEG2000 as an encoding format and the way, they +did YCbCr encoding of the sensor data is simply brilliant. + +My approach of decoding the sensor data is probably not +so brilliant, but seems to work rather nicely (and sharply!). + +If someone finds a better way and/or RED decides to release +specification, just go ahead and feel free to change it! + +Until that happens: simply enjoy opening RED footage within Blender! + +-- Peter Schlaile, June 2008 + diff --git a/extern/libredcode/SConscript b/extern/libredcode/SConscript new file mode 100644 index 00000000000..4e83ba5cbb4 --- /dev/null +++ b/extern/libredcode/SConscript @@ -0,0 +1,28 @@ +#!/usr/bin/python + +import sys +import os +import shutil + +Import('env') + +sources = env.Glob('*.c') +incs = '. ../libopenjpeg' + +root = "extern/libredcode" + +if not os.path.isdir(root + "/include"): + os.mkdir(root + "/include"); +if not os.path.isdir(root + "/include/redcode"): + os.mkdir(root + "/include/redcode"); + +for h in env.Glob('*.h'): + shutil.copyfile(root + "/" + h, + root + "/include/redcode/" + h) + + +env.BlenderLib ( libname='extern_redcode', + sources=sources, includes=Split(incs), + defines=[], + libtype=['core','intern','player'], + priority=[5, 5, 200], compileflags = []) diff --git a/extern/libredcode/codec.c b/extern/libredcode/codec.c new file mode 100644 index 00000000000..e0b79119e80 --- /dev/null +++ b/extern/libredcode/codec.c @@ -0,0 +1,141 @@ +#include "codec.h" +#include "format.h" +#include "debayer.h" + +#include +#include +#include +#include + +static void error_callback(const char *msg, void *client_data) { + FILE *stream = (FILE*)client_data; + fprintf(stream, "[R3D ERR] %s", msg); +} + +static void warning_callback(const char *msg, void *client_data) { + FILE *stream = (FILE*)client_data; + fprintf(stream, "[R3D WARN] %s", msg); +} + +static void info_callback(const char *msg, void *client_data) { + (void)client_data; + fprintf(stdout, "[R3D INFO] %s", msg); +} + +#define J2K_CFMT 0 +#define JP2_CFMT 1 +#define JPT_CFMT 2 + +struct redcode_frame_raw * redcode_decode_video_raw( + struct redcode_frame * frame, int scale) +{ + struct redcode_frame_raw * rv = NULL; + opj_dparameters_t parameters; /* decompression parameters */ + opj_event_mgr_t event_mgr; /* event manager */ + opj_image_t *image = NULL; + opj_dinfo_t* dinfo = NULL; /* handle to a decompressor */ + opj_cio_t *cio = NULL; + + memset(&event_mgr, 0, sizeof(opj_event_mgr_t)); + event_mgr.error_handler = error_callback; + event_mgr.warning_handler = warning_callback; + event_mgr.info_handler = info_callback; + + opj_set_default_decoder_parameters(¶meters); + + parameters.decod_format = JP2_CFMT; + + if (scale == 2) { + parameters.cp_reduce = 1; + } else if (scale == 4) { + parameters.cp_reduce = 2; + } else if (scale == 8) { + parameters.cp_reduce = 3; + } + + /* JPEG 2000 compressed image data */ + + /* get a decoder handle */ + dinfo = opj_create_decompress(CODEC_JP2); + + /* catch events using our callbacks and give a local context */ + opj_set_event_mgr((opj_common_ptr)dinfo, &event_mgr, stderr); + + /* setup the decoder decoding parameters using the current image + and user parameters */ + opj_setup_decoder(dinfo, ¶meters); + + /* open a byte stream */ + cio = opj_cio_open((opj_common_ptr)dinfo, + frame->data + frame->offset, frame->length); + + image = opj_decode(dinfo, cio); + + if(!image) { + fprintf(stderr, + "ERROR -> j2k_to_image: failed to decode image!\n"); + opj_destroy_decompress(dinfo); + opj_cio_close(cio); + return 0; + } + + /* close the byte stream */ + opj_cio_close(cio); + + /* free remaining structures */ + if(dinfo) { + opj_destroy_decompress(dinfo); + } + + if((image->numcomps * image->x1 * image->y1) == 0) { + opj_image_destroy(image); + return 0; + } + + rv = (struct redcode_frame_raw *) calloc( + 1, sizeof(struct redcode_frame_raw)); + + rv->data = image; + rv->width = image->comps[0].w; + rv->height = image->comps[0].h; + + return rv; +} + +int redcode_decode_video_float(struct redcode_frame_raw * frame, + float * out, int scale) +{ + int* planes[4]; + int i; + opj_image_t *image = (opj_image_t*) frame->data; + + if (image->numcomps != 4) { + fprintf(stderr, "R3D: need 4 planes, but got: %d\n", + image->numcomps); + return 0; + } + + for (i = 0; i < 4; i++) { + planes[i] = image->comps[i].data; + } + + if (scale == 1) { + redcode_ycbcr2rgb_fullscale( + planes, frame->width, frame->height, out); + } else if (scale == 2) { + redcode_ycbcr2rgb_halfscale( + planes, frame->width, frame->height, out); + } else if (scale == 4) { + redcode_ycbcr2rgb_quarterscale( + planes, frame->width, frame->height, out); + } + + opj_image_destroy(image); + + free(frame); + + return 1; +} + + + diff --git a/extern/libredcode/codec.h b/extern/libredcode/codec.h new file mode 100644 index 00000000000..928cab589ed --- /dev/null +++ b/extern/libredcode/codec.h @@ -0,0 +1,34 @@ +#ifndef __redcode_codec_h_included__ +#define __redcode_codec_h_included__ + +struct redcode_frame; + +struct redcode_frame_raw { + void * data; + int width; + int height; +}; + +/* do the JPEG2000 decompression into YCbCrY planes */ +struct redcode_frame_raw * redcode_decode_video_raw( + struct redcode_frame * frame, int scale); + +/* finally decode RAW frame into out-buffer (which has to be allocated + in advance) + + Keep in mind: frame_raw-width + height is half sized. + (one pixel contains 2x2 bayer-sensor data) + + output-buffer should have room for + + scale = 1 : width * height * 4 * 4 * sizeof(float) + scale = 2 : width * height * 4 * sizeof(float) + scale = 4 : width * height * sizeof(float) + +*/ + +int redcode_decode_video_float(struct redcode_frame_raw * frame, + float * out, int scale); + + +#endif diff --git a/extern/libredcode/debayer.c b/extern/libredcode/debayer.c new file mode 100644 index 00000000000..f7f22e1cc54 --- /dev/null +++ b/extern/libredcode/debayer.c @@ -0,0 +1,129 @@ +#include "debayer.h" + +/* pretty simple but astonishingly very effective "debayer" function + */ + +void redcode_ycbcr2rgb_fullscale( + int ** planes, int width, int height, float * out) +{ + int x,y; + int pix_max = 4096; + int mask = pix_max - 1; + float Kb = 0.0722; + float Kr = 0.2126; + float *o; + + for (y = 0; y < height; y++) { + for (x = 0; x < width; x++) { + int i = x + y*width; + int i_p = (y > 0) ? i-width : i; + int i_n = (y < (height-1)) ? i + width : i; + float y1n = planes[0][i_n] & mask; + float y1 = planes[0][i] & mask; + float cb = (planes[1][i] & mask) - pix_max/2; + float cr = (planes[2][i] & mask) - pix_max/2; + float y2 = (planes[3][i] & mask); + float y2p = (planes[3][i_p] & mask); + + float b_ = cb * (1.0 - Kb)/(pix_max/2); + float r_ = cr * (1.0 - Kr)/(pix_max/2); + float g_ = (- Kr * r_ - Kb * b_)/(1.0 - Kr - Kb); + + float y_[4] = {y1 / pix_max, + (y2 + y2p)/2 / pix_max, + (y1 + y1n)/2 / pix_max, + y2 / pix_max}; + + int j; + int yc = 0; + + o = out + (2*height-1-2*y)*2*4*width + + x*2*4; + + for (j = 0; j < 8; j += 4) { + o[j+0] = r_ + y_[yc]; + o[j+1] = g_ + y_[yc]; + o[j+2] = b_ + y_[yc]; + o[j+3] = 1.0; + yc++; + } + + o = out + (2*height-1-2*y)*2*4*width + + x*2*4 - 2*4*width; + + for (j = 0; j < 8; j += 4) { + o[j+0] = r_ + y_[yc]; + o[j+1] = g_ + y_[yc]; + o[j+2] = b_ + y_[yc]; + o[j+3] = 1.0; + yc++; + } + } + } +} + +void redcode_ycbcr2rgb_halfscale( + int ** planes, int width, int height, float * out) +{ + int x,y; + int pix_max = 4096; + int mask = pix_max - 1; + float Kb = 0.0722; + float Kr = 0.2126; + + for (y = 0; y < height; y++) { + float *o = out + width * (height - y - 1); + for (x = 0; x < width; x++) { + int i = y*height + x; + float y1 = (planes[0][i] & mask); + float cb = (planes[1][i] & mask) - pix_max/2; + float cr = (planes[2][i] & mask) - pix_max/2; + float y2 = (planes[3][i] & mask); + + float b_ = cb * (1.0 - Kb)/(pix_max/2); + float r_ = cr * (1.0 - Kr)/(pix_max/2); + float g_ = (- Kr * r_ - Kb * b_)/(1.0 - Kr - Kb); + + float y = (y1 + y2)/2 / pix_max; + + *o++ = r_ + y; + *o++ = g_ + y; + *o++ = b_ + y; + *o++ = 1.0; + } + } +} + + +void redcode_ycbcr2rgb_quarterscale( + int ** planes, int width, int height, float * out) +{ + int x,y; + int pix_max = 4096; + int mask = pix_max - 1; + float Kb = 0.0722; + float Kr = 0.2126; + + for (y = 0; y < height; y += 2) { + float *o = out + (width/2) * (height/2 - y/2 - 1); + for (x = 0; x < width; x += 2) { + int i = y * width + x; + float y1 = planes[0][i] & mask; + float cb = (planes[1][i] & mask) - pix_max/2; + float cr = (planes[2][i] & mask) - pix_max/2; + float y2 = planes[3][i] & mask; + + float b_ = cb * (1.0 - Kb)/(pix_max/2); + float r_ = cr * (1.0 - Kr)/(pix_max/2); + float g_ = (- Kr * r_ - Kb * b_)/(1.0 - Kr - Kb); + + float y = (y1 + y2)/2 / pix_max; + + *o++ = r_ + y; + *o++ = g_ + y; + *o++ = b_ + y; + *o++ = 1.0; + } + } +} + diff --git a/extern/libredcode/debayer.h b/extern/libredcode/debayer.h new file mode 100644 index 00000000000..b58c7678671 --- /dev/null +++ b/extern/libredcode/debayer.h @@ -0,0 +1,11 @@ +#ifndef __redcode_debayer_h_included__ +#define __redcode_debayer_h_included__ 1 + +void redcode_ycbcr2rgb_fullscale( + int ** planes, int width, int height, float * out); +void redcode_ycbcr2rgb_halfscale( + int ** planes, int width, int height, float * out); +void redcode_ycbcr2rgb_quarterscale( + int ** planes, int width, int height, float * out); + +#endif diff --git a/extern/libredcode/format.c b/extern/libredcode/format.c new file mode 100644 index 00000000000..35410e9e269 --- /dev/null +++ b/extern/libredcode/format.c @@ -0,0 +1,213 @@ +#include +#include +#include +#include +#include "format.h" + +struct red_reob { + unsigned long len; + char head[4]; + + unsigned long rdvo; + unsigned long rdvs; + unsigned long rdao; + unsigned long rdas; + + unsigned long unknown1; + unsigned long unknown2; + unsigned long totlen; + + unsigned long avgv; + unsigned long avgs; + + unsigned long unknown3; + unsigned long unknown4; + unsigned long unknown5; +}; + +struct redcode_handle { + FILE * fp; + struct red_reob * reob; + unsigned long * rdvo; + unsigned long * rdvs; + unsigned long * rdao; + unsigned long * rdas; + long cfra; +}; + + +static unsigned char* read_packet(FILE * fp, char * expect) +{ + unsigned long len; + char head[5]; + unsigned char * rv; + + fread(&len, 4, 1, fp); + fread(&head, 4, 1, fp); + + head[4] = 0; + + len = ntohl(len); + + if (strcmp(expect, head) != 0) { + fprintf(stderr, "Read: %s, expect: %s\n", head, expect); + return NULL; + } + + rv = (unsigned char*) malloc(len + 8); + + memcpy(rv, &len, 4); + memcpy(rv + 4, &head, 4); + + fread(rv + 8, len, 1, fp); + + return rv; +} + +static unsigned long * read_index_packet(FILE * fp, char * expect) +{ + unsigned long * rv = (unsigned long*) read_packet(fp, expect); + int i; + + if (!rv) { + return NULL; + } + + for (i = 2; i < rv[0]/4; i++) { + rv[i] = ntohl(rv[i]); + } + return rv; +} + +static struct red_reob * read_reob(FILE * fp) +{ + fseek(fp, -0x38, SEEK_END); + + return (struct red_reob *) read_index_packet(fp, "REOB"); +} + +static unsigned long * read_index(FILE * fp, unsigned long i, char * expect) +{ + fseek(fp, i, SEEK_SET); + + return (unsigned long*) read_index_packet(fp, expect); +} + +static unsigned char * read_data(FILE * fp, unsigned long i, char * expect) +{ + fseek(fp, i, SEEK_SET); + + return read_packet(fp, expect); +} + +struct redcode_handle * redcode_open(const char * fname) +{ + struct redcode_handle * rv = NULL; + struct red_reob * reob = NULL; + + FILE * fp = fopen(fname, "rb"); + + if (!fp) { + return NULL; + } + + reob = read_reob(fp); + if (!reob) { + fclose(fp); + return NULL; + } + + rv = (struct redcode_handle*) calloc(1, sizeof(struct redcode_handle)); + + rv->fp = fp; + rv->reob = reob; + rv->rdvo = read_index(fp, reob->rdvo, "RDVO"); + rv->rdvs = read_index(fp, reob->rdvs, "RDVS"); + rv->rdao = read_index(fp, reob->rdao, "RDAO"); + rv->rdas = read_index(fp, reob->rdas, "RDAS"); + + if (!rv->rdvo || !rv->rdvs || !rv->rdao || !rv->rdas) { + redcode_close(rv); + return NULL; + } + + return rv; +} + +void redcode_close(struct redcode_handle * handle) +{ + if (handle->reob) { + free(handle->reob); + } + if (handle->rdvo) { + free(handle->rdvo); + } + if (handle->rdvs) { + free(handle->rdvs); + } + if (handle->rdao) { + free(handle->rdao); + } + if (handle->rdas) { + free(handle->rdas); + } + fclose(handle->fp); + free(handle); +} + +long redcode_get_length(struct redcode_handle * handle) +{ + return handle->rdvo[0]/4; +} + +struct redcode_frame * redcode_read_video_frame( + struct redcode_handle * handle, long frame) +{ + struct redcode_frame * rv; + unsigned char * data; + + if (frame > handle->rdvo[0]/4 || handle->rdvo[frame + 2] == 0) { + return NULL; + } + data = read_data(handle->fp, handle->rdvo[frame + 2], "REDV"); + if (!data) { + return NULL; + } + + rv = (struct redcode_frame*) calloc(1, sizeof(struct redcode_frame)); + + rv->offset = 12+8; + rv->length = *(unsigned long*)data - rv->offset; + rv->data = data; + + return rv; +} + +struct redcode_frame * redcode_read_audio_frame( + struct redcode_handle * handle, long frame) +{ + struct redcode_frame * rv; + unsigned char * data; + + if (frame > handle->rdao[0]/4 || handle->rdao[frame + 2] == 0) { + return NULL; + } + data = read_data(handle->fp, handle->rdao[frame+2], "REDA"); + if (!data) { + return NULL; + } + + rv = (struct redcode_frame*) calloc(1, sizeof(struct redcode_frame)); + + rv->offset = 24+8; + rv->length = *(unsigned long*)data - rv->offset; + rv->data = data; + + return rv; +} + +void redcode_free_frame(struct redcode_frame * frame) +{ + free(frame->data); + free(frame); +} diff --git a/extern/libredcode/format.h b/extern/libredcode/format.h new file mode 100644 index 00000000000..e09ea8a3b64 --- /dev/null +++ b/extern/libredcode/format.h @@ -0,0 +1,24 @@ +#ifndef __redcode_format_h_included__ +#define __redcode_format_h_included__ + +struct redcode_handle; +struct redcode_frame { + unsigned long length; + unsigned long offset; + unsigned char * data; +}; + +struct redcode_handle * redcode_open(const char * fname); +void redcode_close(struct redcode_handle * handle); + +long redcode_get_length(struct redcode_handle * handle); + +struct redcode_frame * redcode_read_video_frame( + struct redcode_handle * handle, long frame); +struct redcode_frame * redcode_read_audio_frame( + struct redcode_handle * handle, long frame); + +void redcode_free_frame(struct redcode_frame * frame); + + +#endif diff --git a/intern/bsp/SConscript b/intern/bsp/SConscript index e363fd1d4c3..88d2529ae59 100644 --- a/intern/bsp/SConscript +++ b/intern/bsp/SConscript @@ -8,5 +8,5 @@ incs = 'intern ../container ../moto/include ../memutil' if (env['OURPLATFORM'] == 'win32-mingw'): env.BlenderLib ('blender_BSP', sources, Split(incs), [], libtype=['common','intern'], priority=[26,26] ) else: - env.BlenderLib ('blender_BSP', sources, Split(incs), [], libtype='core', priority=15 ) + env.BlenderLib ('blender_BSP', sources, Split(incs), [], libtype='core', priority=26 ) diff --git a/source/blender/imbuf/SConscript b/source/blender/imbuf/SConscript index f9e46b20d9a..7349f481731 100644 --- a/source/blender/imbuf/SConscript +++ b/source/blender/imbuf/SConscript @@ -27,6 +27,14 @@ if env['WITH_BF_FFMPEG'] == 1: defs.append('WITH_FFMPEG') incs += ' ' + env['BF_FFMPEG_INC'] +if env['WITH_BF_OPENJPEG'] == 1: + defs.append('WITH_OPENJPEG') + incs += ' ' + env['BF_OPENJPEG_INC'] + +if env['WITH_BF_REDCODE'] == 1: + defs.append('WITH_REDCODE') + incs += ' ' + env['BF_REDCODE_INC'] + if env['WITH_BF_QUICKTIME']==1: incs += ' ' + env['BF_QUICKTIME_INC'] defs.append('WITH_QUICKTIME') diff --git a/source/blender/imbuf/intern/IMB_anim.h b/source/blender/imbuf/intern/IMB_anim.h index 4948ff11b4a..71d35949833 100644 --- a/source/blender/imbuf/intern/IMB_anim.h +++ b/source/blender/imbuf/intern/IMB_anim.h @@ -81,6 +81,10 @@ #include #endif +#ifdef WITH_REDCODE +#include +#endif + #include "IMB_imbuf_types.h" #include "IMB_imbuf.h" @@ -116,6 +120,7 @@ #define ANIM_AVI (1 << 6) #define ANIM_QTIME (1 << 7) #define ANIM_FFMPEG (1 << 8) +#define ANIM_REDCODE (1 << 9) #define ANIM5_MMAP 0 #define ANIM5_MALLOC 1 @@ -184,6 +189,9 @@ struct anim { int videoStream; #endif +#ifdef WITH_REDCODE + struct redcode_handle * redcodeCtx; +#endif }; #endif diff --git a/source/blender/imbuf/intern/anim.c b/source/blender/imbuf/intern/anim.c index d2743b680d8..f9c584fba39 100644 --- a/source/blender/imbuf/intern/anim.c +++ b/source/blender/imbuf/intern/anim.c @@ -96,6 +96,11 @@ #endif +#ifdef WITH_REDCODE +#include +#include +#endif + /****/ #ifdef __sgi @@ -830,6 +835,58 @@ static void free_anim_ffmpeg(struct anim * anim) { #endif +#ifdef WITH_REDCODE + +static int startredcode(struct anim * anim) { + anim->redcodeCtx = redcode_open(anim->name); + if (!anim->redcodeCtx) { + return -1; + } + anim->duration = redcode_get_length(anim->redcodeCtx); + + return 0; +} + +static ImBuf * redcode_fetchibuf(struct anim * anim, int position) { + struct ImBuf * ibuf; + struct redcode_frame * frame; + struct redcode_frame_raw * raw_frame; + + if (!anim->redcodeCtx) { + return NULL; + } + + frame = redcode_read_video_frame(anim->redcodeCtx, position); + + if (!frame) { + return NULL; + } + + raw_frame = redcode_decode_video_raw(frame, 1); + + redcode_free_frame(frame); + + if (!raw_frame) { + return NULL; + } + + ibuf = IMB_allocImBuf(raw_frame->width * 2, + raw_frame->height * 2, 32, IB_rectfloat, 0); + + redcode_decode_video_float(raw_frame, ibuf->rect_float, 1); + + return ibuf; +} + +static void free_anim_redcode(struct anim * anim) { + if (anim->redcodeCtx) { + redcode_close(anim->redcodeCtx); + anim->redcodeCtx = 0; + } + anim->duration = 0; +} + +#endif /* probeer volgende plaatje te lezen */ /* Geen plaatje, probeer dan volgende animatie te openen */ @@ -849,6 +906,10 @@ static struct ImBuf * anim_getnew(struct anim * anim) { #ifdef WITH_FFMPEG free_anim_ffmpeg(anim); #endif +#ifdef WITH_REDCODE + free_anim_redcode(anim); +#endif + if (anim->curtype != 0) return (0); anim->curtype = imb_get_anim_type(anim->name); @@ -888,8 +949,13 @@ static struct ImBuf * anim_getnew(struct anim * anim) { ibuf = IMB_allocImBuf (anim->x, anim->y, 24, 0, 0); break; #endif +#ifdef WITH_REDCODE + case ANIM_REDCODE: + if (startredcode(anim)) return (0); + ibuf = IMB_allocImBuf (8, 8, 32, 0, 0); + break; } - +#endif return(ibuf); } @@ -969,6 +1035,12 @@ struct ImBuf * IMB_anim_absolute(struct anim * anim, int position) { ibuf = ffmpeg_fetchibuf(anim, position); if (ibuf) anim->curposition = position; break; +#endif +#ifdef WITH_REDCODE + case ANIM_REDCODE: + ibuf = redcode_fetchibuf(anim, position); + if (ibuf) anim->curposition = position; + break; #endif } diff --git a/source/blender/imbuf/intern/util.c b/source/blender/imbuf/intern/util.c index 632a471ecd0..4f6730db1f1 100644 --- a/source/blender/imbuf/intern/util.c +++ b/source/blender/imbuf/intern/util.c @@ -321,6 +321,19 @@ static int isffmpeg (char *filename) { } #endif +#ifdef WITH_REDCODE +static int isredcode(char * filename) +{ + struct redcode_handle * h = redcode_open(filename); + if (!h) { + return 0; + } + redcode_close(h); + return 1; +} + +#endif + int imb_get_anim_type(char * name) { int type; struct stat st; @@ -354,6 +367,9 @@ int imb_get_anim_type(char * name) { # ifdef WITH_FFMPEG if (isffmpeg(name)) return (ANIM_FFMPEG); # endif +#endif +#ifdef WITH_REDCODE + if (isredcode(name)) return (ANIM_REDCODE); #endif type = IMB_ispic(name); if (type == ANIM) return (ANIM_ANIM5); @@ -369,6 +385,7 @@ int IMB_isanim(char *filename) { if( BLI_testextensie(filename, ".avi") || BLI_testextensie(filename, ".flc") || BLI_testextensie(filename, ".dv") + || BLI_testextensie(filename, ".r3d") || BLI_testextensie(filename, ".mov") || BLI_testextensie(filename, ".movie") || BLI_testextensie(filename, ".mv")) { @@ -379,6 +396,7 @@ int IMB_isanim(char *filename) { } else { // no quicktime if( BLI_testextensie(filename, ".avi") || BLI_testextensie(filename, ".dv") + || BLI_testextensie(filename, ".r3d") || BLI_testextensie(filename, ".mv")) { type = imb_get_anim_type(filename); } diff --git a/tools/btools.py b/tools/btools.py index 51367d6bd42..cd3d8cd83f6 100755 --- a/tools/btools.py +++ b/tools/btools.py @@ -192,6 +192,18 @@ def read_opts(cfg, args): ('BF_JPEG_LIB', 'JPEG library', ''), ('BF_JPEG_LIBPATH', 'JPEG library path', ''), + (BoolOption('WITH_BF_OPENJPEG', 'Use OPENJPEG if true', 'true')), + ('BF_OPENJPEG', 'OPENJPEG base path', ''), + ('BF_OPENJPEG_INC', 'OPENJPEG include path', ''), + ('BF_OPENJPEG_LIB', 'OPENJPEG library', ''), + ('BF_OPENJPEG_LIBPATH', 'OPENJPEG library path', ''), + + (BoolOption('WITH_BF_REDCODE', 'Use REDCODE if true', 'true')), + ('BF_REDCODE', 'REDCODE base path', ''), + ('BF_REDCODE_INC', 'REDCODE include path', ''), + ('BF_REDCODE_LIB', 'REDCODE library', ''), + ('BF_REDCODE_LIBPATH', 'REDCODE library path', ''), + (BoolOption('WITH_BF_PNG', 'Use PNG if true', 'true')), ('BF_PNG', 'PNG base path', ''), ('BF_PNG_INC', 'PNG include path', ''), From 6be7bb5e03a61600e3d231462eeb7391e299fc96 Mon Sep 17 00:00:00 2001 From: Peter Schlaile Date: Mon, 2 Jun 2008 21:39:45 +0000 Subject: [PATCH 141/246] == redcode == Disabled by default now on all platforms besides Linux. --- tools/btools.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/btools.py b/tools/btools.py index cd3d8cd83f6..ad4cf71c3e8 100755 --- a/tools/btools.py +++ b/tools/btools.py @@ -192,13 +192,13 @@ def read_opts(cfg, args): ('BF_JPEG_LIB', 'JPEG library', ''), ('BF_JPEG_LIBPATH', 'JPEG library path', ''), - (BoolOption('WITH_BF_OPENJPEG', 'Use OPENJPEG if true', 'true')), + (BoolOption('WITH_BF_OPENJPEG', 'Use OPENJPEG if true', 'false')), ('BF_OPENJPEG', 'OPENJPEG base path', ''), ('BF_OPENJPEG_INC', 'OPENJPEG include path', ''), ('BF_OPENJPEG_LIB', 'OPENJPEG library', ''), ('BF_OPENJPEG_LIBPATH', 'OPENJPEG library path', ''), - (BoolOption('WITH_BF_REDCODE', 'Use REDCODE if true', 'true')), + (BoolOption('WITH_BF_REDCODE', 'Use REDCODE if true', 'false')), ('BF_REDCODE', 'REDCODE base path', ''), ('BF_REDCODE_INC', 'REDCODE include path', ''), ('BF_REDCODE_LIB', 'REDCODE library', ''), From cfd67321d2cf20b7504ec6a506364e313e114318 Mon Sep 17 00:00:00 2001 From: Peter Schlaile Date: Mon, 2 Jun 2008 22:02:26 +0000 Subject: [PATCH 142/246] == REDCODE == Forgot to free redcontext in IMB_free_anim... --- source/blender/imbuf/intern/anim.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/source/blender/imbuf/intern/anim.c b/source/blender/imbuf/intern/anim.c index f9c584fba39..e14c433391a 100644 --- a/source/blender/imbuf/intern/anim.c +++ b/source/blender/imbuf/intern/anim.c @@ -312,6 +312,9 @@ void IMB_free_anim_ibuf(struct anim * anim) { #ifdef WITH_FFMPEG static void free_anim_ffmpeg(struct anim * anim); #endif +#ifdef WITH_REDCODE +static void free_anim_redcode(struct anim * anim); +#endif void IMB_free_anim(struct anim * anim) { if (anim == NULL) { @@ -330,6 +333,9 @@ void IMB_free_anim(struct anim * anim) { #ifdef WITH_FFMPEG free_anim_ffmpeg(anim); #endif +#ifdef WITH_REDCODE + free_anim_redcode(anim); +#endif free(anim); } From 510d4b22ec63e5b70c3647cf84aec387dc328a65 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 3 Jun 2008 01:01:47 +0000 Subject: [PATCH 143/246] increase the level you can zoom out (andy's timelapse videos were a pain to edit) --- source/blender/src/space.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/src/space.c b/source/blender/src/space.c index 47e3387755b..8cc7e6975b4 100644 --- a/source/blender/src/space.c +++ b/source/blender/src/space.c @@ -5121,7 +5121,7 @@ static void init_seqspace(ScrArea *sa) sseq->v2d.min[0]= 10.0; sseq->v2d.min[1]= 4.0; - sseq->v2d.max[0]= 32000.0; + sseq->v2d.max[0]= MAXFRAMEF; sseq->v2d.max[1]= MAXSEQ; sseq->v2d.minzoom= 0.1f; From 6eeef64370a2dfb752c220f9434407a68251e54f Mon Sep 17 00:00:00 2001 From: Peter Schlaile Date: Tue, 3 Jun 2008 06:42:13 +0000 Subject: [PATCH 144/246] == REDCODE == got #endif position wrong, breaking compile without redcode, sorry. (Thanks to jms for pointing that out) --- source/blender/imbuf/intern/anim.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/imbuf/intern/anim.c b/source/blender/imbuf/intern/anim.c index e14c433391a..87d67f5263b 100644 --- a/source/blender/imbuf/intern/anim.c +++ b/source/blender/imbuf/intern/anim.c @@ -960,8 +960,8 @@ static struct ImBuf * anim_getnew(struct anim * anim) { if (startredcode(anim)) return (0); ibuf = IMB_allocImBuf (8, 8, 32, 0, 0); break; - } #endif + } return(ibuf); } From 29f839b4a58ace4c4a42e361341e3768c019f9de Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Tue, 3 Jun 2008 10:00:09 +0000 Subject: [PATCH 145/246] Bugfix #13603: Action Editor Copy/Paste didn't trigger a depsgraph update for the active object (if the action was applied to it). --- source/blender/src/editaction.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/source/blender/src/editaction.c b/source/blender/src/editaction.c index 12b9cb8919f..40b6b7ba6fe 100644 --- a/source/blender/src/editaction.c +++ b/source/blender/src/editaction.c @@ -1485,7 +1485,7 @@ void insertkey_action(void) data= get_action_context(&datatype); if (data == NULL) return; cfra = frame_to_float(CFRA); - + if (datatype == ACTCONT_ACTION) { ListBase act_data = {NULL, NULL}; bActListElem *ale; @@ -1941,6 +1941,7 @@ void paste_actdata () int filter; void *data; short datatype; + Object *ob= OBACT; short no_name= 0; float offset = CFRA - actcopy_firstframe; @@ -2017,7 +2018,7 @@ void paste_actdata () /* loop over curves, pasting keyframes */ for (ico= ipo_src->curve.first; ico; ico= ico->next) { - icu= verify_ipocurve((ID*)OBACT, ico->blocktype, actname, conname, "", ico->adrcode); + icu= verify_ipocurve((ID*)ob, ico->blocktype, actname, conname, "", ico->adrcode); if (icu) { /* just start pasting, with the the first keyframe on the current frame, and so on */ @@ -2045,6 +2046,14 @@ void paste_actdata () /* free temp memory */ BLI_freelistN(&act_data); + /* do depsgraph updates (for 3d-view)? */ + if ((ob) && (G.saction->pin==0)) { + if (ob->type == OB_ARMATURE) + DAG_object_flush_update(G.scene, ob, OB_RECALC_OB|OB_RECALC_DATA); + else + DAG_object_flush_update(G.scene, ob, OB_RECALC_OB); + } + /* undo and redraw stuff */ allqueue(REDRAWVIEW3D, 0); allspace(REMAKEIPO, 0); From 62ca0e07dad7d79c79eda2c3eeef0afd7e939896 Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Tue, 3 Jun 2008 10:04:42 +0000 Subject: [PATCH 146/246] A few compiler warning fixes. Those in BME_customdata.c were more serious. --- source/blender/blenkernel/intern/BME_Customdata.c | 3 ++- source/blender/src/editmesh_tools.c | 5 ----- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/source/blender/blenkernel/intern/BME_Customdata.c b/source/blender/blenkernel/intern/BME_Customdata.c index 68bc75327d9..8b48efbdbd2 100644 --- a/source/blender/blenkernel/intern/BME_Customdata.c +++ b/source/blender/blenkernel/intern/BME_Customdata.c @@ -39,6 +39,7 @@ #include "BKE_bmeshCustomData.h" #include "bmesh_private.h" #include +#include "MEM_guardedalloc.h" /********************* Layer type information **********************/ typedef struct BME_LayerTypeInfo { @@ -88,7 +89,7 @@ void BME_CD_Create(BME_CustomData *data, BME_CustomDataInit *init, int initalloc if(init->layout[i]){ info = BME_layerType_getInfo(i); for(j=0; j < init->layout[i]; j++){ - if(j=0) data->layers[j+i].active = init->active[i]; + if(j==0) data->layers[j+i].active = init->active[i]; data->layers[j+i].type = i; data->layers[j+i].offset = offset; strcpy(data->layers[j+i].name, &(init->nametemplate[j+i])); diff --git a/source/blender/src/editmesh_tools.c b/source/blender/src/editmesh_tools.c index f85161c3e23..f9bb14a08c6 100644 --- a/source/blender/src/editmesh_tools.c +++ b/source/blender/src/editmesh_tools.c @@ -4480,11 +4480,6 @@ static void bevel_mesh_recurs(float bsize, short recurs, int allfaces) } void bevel_menu() { - int vlayers[BME_CD_NUMTYPES] = {0,0,0,0}; - int elayers[BME_CD_NUMTYPES] = {0,0,0,0}; - int llayers[BME_CD_NUMTYPES] = {0,0,0,0}; - int players[BME_CD_NUMTYPES] = {0,0,0,0}; - BME_Mesh *bm; BME_TransData_Head *td; TransInfo *t; From 0c0c43f62001eb652b8a8c374cca390824ef2c5e Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Tue, 3 Jun 2008 19:06:54 +0000 Subject: [PATCH 147/246] Collision commit code cleanup for nicer compile --- source/blender/blenkernel/BKE_collision.h | 7 ++ source/blender/blenkernel/intern/collision.c | 97 ++------------------ source/blender/blenkernel/intern/modifier.c | 1 + 3 files changed, 14 insertions(+), 91 deletions(-) diff --git a/source/blender/blenkernel/BKE_collision.h b/source/blender/blenkernel/BKE_collision.h index b38bf8662d7..2966d932a49 100644 --- a/source/blender/blenkernel/BKE_collision.h +++ b/source/blender/blenkernel/BKE_collision.h @@ -116,6 +116,13 @@ FaceCollPair; // forward declarations ///////////////////////////////////////////////// +///////////////////////////////////////////////// +// used in modifier.c from collision.c +///////////////////////////////////////////////// +BVHTree *bvhtree_build_from_mvert ( MFace *mfaces, unsigned int numfaces, MVert *x, unsigned int numverts, float epsilon ); +void bvhtree_update_from_mvert ( BVHTree * bvhtree, MFace *faces, int numfaces, MVert *x, MVert *xnew, int numverts, int moving ); +///////////////////////////////////////////////// + LinkNode *BLI_linklist_append_fast ( LinkNode **listp, void *ptr ); // move Collision modifier object inter-frame with step = [0,1] diff --git a/source/blender/blenkernel/intern/collision.c b/source/blender/blenkernel/intern/collision.c index 36cc37eab44..fc9a8132aaf 100644 --- a/source/blender/blenkernel/intern/collision.c +++ b/source/blender/blenkernel/intern/collision.c @@ -51,34 +51,6 @@ #include "BLI_kdopbvh.h" #include "BKE_collision.h" -#ifdef _WIN32 -static void start ( void ) -{} -static void end ( void ) -{ -} -static double val() -{ - return 0; -} -#else -#include -static void mystart ( struct timeval *start, struct timezone *z ) -{ - gettimeofday ( start, z ); -} -static void myend ( struct timeval *end, struct timezone *z ) -{ - gettimeofday ( end,z ); -} -static double myval ( struct timeval *start, struct timeval *end ) -{ - double t1, t2; - t1 = ( double ) start->tv_sec + ( double ) start->tv_usec/ ( 1000*1000 ); - t2 = ( double ) end->tv_sec + ( double ) end->tv_usec/ ( 1000*1000 ); - return t2-t1; -} -#endif /*********************************** Collision modifier code start @@ -758,7 +730,6 @@ int cloth_collision_response_moving( ClothModifierData *clmd, CollisionModifierD float w1, w2, w3, u1, u2, u3; float v1[3], v2[3], relativeVelocity[3]; float magrelVel; - float epsilon2 = BLI_bvhtree_getepsilon ( collmd->bvhtree ); cloth1 = clmd->clothObject; @@ -797,7 +768,7 @@ int cloth_collision_response_moving( ClothModifierData *clmd, CollisionModifierD if ( magrelVel > ALMOST_ZERO ) { // Calculate Impulse magnitude to stop all motion in normal direction. - float magtangent = 0, repulse = 0, d = 0; + float magtangent = 0; double impulse = 0.0; float vrel_t_pre[3]; float temp[3]; @@ -1096,13 +1067,13 @@ int cloth_collision_moving_edges ( ClothModifierData *clmd, CollisionModifierDat EdgeCollPair edgecollpair; Cloth *cloth1=NULL; ClothVertex *verts1=NULL; - unsigned int i = 0, j = 0, k = 0; + unsigned int i = 0, k = 0; int numsolutions = 0; double x1[3], v1[3], x2[3], v2[3], x3[3], v3[3]; double solution[3], solution2[3]; MVert *verts2 = collmd->current_x; // old x MVert *velocity2 = collmd->current_v; // velocity - float distance; + float distance = 0; float triA[3][3], triB[3][3]; int result = 0; @@ -1226,7 +1197,6 @@ int cloth_collision_moving_edges ( ClothModifierData *clmd, CollisionModifierDat float distance; float impulse = 0; float I_mag; - float m1, m2; // move verts VECADDS(triA[0], verts1[edgecollpair.p11].txold, verts1[edgecollpair.p11].tv, solution[k]); @@ -1302,51 +1272,9 @@ int cloth_collision_moving_edges ( ClothModifierData *clmd, CollisionModifierDat return result; } -int cloth_collision_moving_tris ( ClothModifierData *clmd, CollisionModifierData *collmd, CollPair *collpair ) -{ - EdgeCollPair edgecollpair; - Cloth *cloth1=NULL; - ClothVertex *verts1=NULL; - unsigned int i = 0, j = 0, k = 0; - int numsolutions = 0; - double x1[3], v1[3], x2[3], v2[3], x3[3], v3[3]; - double solution[3]; - MVert *verts2 = collmd->current_x; // old x - MVert *velocity2 = collmd->current_v; // velocity - float mintime = FLT_MAX; - float distance; - float triA[3][3], triB[3][3]; - int result = 0; - - cloth1 = clmd->clothObject; - verts1 = cloth1->verts; - - for(i = 0; i < 9; i++) - { - // 9 edge - edge possibilities - - if(i == 0) - { - edgecollpair.p11 = collpair->ap1; - edgecollpair.p12 = collpair->ap2; - - edgecollpair.p21 = collpair->bp1; - edgecollpair.p22 = collpair->bp2; - } - } - - return result; -} - int cloth_collision_moving ( ClothModifierData *clmd, CollisionModifierData *collmd, CollPair *collpair, CollPair *collision_end ) { - int result = 0; Cloth *cloth1; - float w1, w2, w3, u1, u2, u3; - float v1[3], v2[3], relativeVelocity[3]; - float magrelVel; - float epsilon2 = BLI_bvhtree_getepsilon ( collmd->bvhtree ); - cloth1 = clmd->clothObject; for ( ; collpair != collision_end; collpair++ ) @@ -1471,11 +1399,11 @@ int cloth_bvh_objcollision ( ClothModifierData * clmd, float step, float dt ) Object *coll_ob=NULL; BVHTree *cloth_bvh=NULL; long i=0, j = 0, k = 0, numfaces = 0, numverts = 0; - unsigned int result = 0, rounds = 0; // result counts applied collisions; ic is for debug output; + int result = 0, rounds = 0; // result counts applied collisions; ic is for debug output; ClothVertex *verts = NULL; int ret = 0, ret2 = 0; ClothModifierData *tclmd; - int collisions = 0, count = 0; + int collisions = 0; if ( ( clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_COLLOBJ ) || ! ( ( ( Cloth * ) clmd->clothObject )->bvhtree ) ) { @@ -1570,8 +1498,7 @@ int cloth_bvh_objcollision ( ClothModifierData * clmd, float step, float dt ) //////////////////////////////////////////////////////////// if ( clmd->coll_parms->flags & CLOTH_COLLSETTINGS_FLAG_SELF ) { - - MFace *mface = cloth->mfaces; + // TODO: add coll quality rounds again BVHTreeOverlap *overlap = NULL; collisions = 1; @@ -1676,15 +1603,3 @@ int cloth_bvh_objcollision ( ClothModifierData * clmd, float step, float dt ) return MIN2 ( ret, 1 ); } - - -/* -if ( verts[i].impulse_count ) -{ - VECADDMUL ( verts[i].tv, verts[i].impulse, 1.0f / verts[i].impulse_count ); - VECCOPY ( verts[i].impulse, tnull ); - verts[i].impulse_count = 0; - - ret++; -} -*/ \ No newline at end of file diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c index 18912e32e3c..bd8a2ea219a 100644 --- a/source/blender/blenkernel/intern/modifier.c +++ b/source/blender/blenkernel/intern/modifier.c @@ -77,6 +77,7 @@ #include "BKE_anim.h" #include "BKE_bad_level_calls.h" #include "BKE_cloth.h" +#include "BKE_collision.h" #include "BKE_curve.h" #include "BKE_customdata.h" #include "BKE_global.h" From 772d241582a8d396425cd7f53438871858669a99 Mon Sep 17 00:00:00 2001 From: Benoit Bolsee Date: Tue, 3 Jun 2008 22:54:24 +0000 Subject: [PATCH 148/246] Fix BGE bug #13605: GameEngine corrupts Pose data --- source/gameengine/Converter/BL_ArmatureObject.cpp | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/source/gameengine/Converter/BL_ArmatureObject.cpp b/source/gameengine/Converter/BL_ArmatureObject.cpp index ff9c6a75aa9..08567dde840 100644 --- a/source/gameengine/Converter/BL_ArmatureObject.cpp +++ b/source/gameengine/Converter/BL_ArmatureObject.cpp @@ -153,9 +153,12 @@ void BL_ArmatureObject::GetPose(bPose **pose) int copy_constraint_channels_hack = 1; copy_pose(pose, m_pose, copy_constraint_channels_hack); } - else + else { + if (*pose == m_pose) + // no need to copy if the pointers are the same + return; extract_pose_from_pose(*pose, m_pose); - + } } void BL_ArmatureObject::GetMRDPose(bPose **pose) @@ -169,7 +172,11 @@ void BL_ArmatureObject::GetMRDPose(bPose **pose) //} if (!*pose) - copy_pose(pose, m_objArma->pose, 0); + // must duplicate the constraints too otherwise we have corruption in free_pose_channels() + // because it will free the blender constraints. + // Ideally, blender should rememeber that the constraints were not copied so that + // free_pose_channels() would not free them. + copy_pose(pose, m_objArma->pose, 1); else extract_pose_from_pose(*pose, m_objArma->pose); From d565e8a02f94e61fbebcfbcdcef1f547b4e6b65b Mon Sep 17 00:00:00 2001 From: Hamed Zaghaghi Date: Wed, 4 Jun 2008 02:54:42 +0000 Subject: [PATCH 149/246] bugfix #13618 - 2d filters + GLSL python scripts --- source/gameengine/Rasterizer/RAS_2DFilterManager.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/source/gameengine/Rasterizer/RAS_2DFilterManager.cpp b/source/gameengine/Rasterizer/RAS_2DFilterManager.cpp index 9454edfacfe..e8562c54539 100644 --- a/source/gameengine/Rasterizer/RAS_2DFilterManager.cpp +++ b/source/gameengine/Rasterizer/RAS_2DFilterManager.cpp @@ -166,6 +166,9 @@ void RAS_2DFilterManager::StartShaderProgram(unsigned int shaderprogram) GLint uniformLoc; bgl::blUseProgramObjectARB(shaderprogram); uniformLoc = bgl::blGetUniformLocationARB(shaderprogram, "bgl_RenderedTexture"); + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, texname); + if (uniformLoc != -1) { bgl::blUniform1iARB(uniformLoc, 0); From e26323bcdd89f992ab772cb8860502e2bfe2e681 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 4 Jun 2008 16:19:15 +0000 Subject: [PATCH 150/246] Python API object.parentVertexIndex - access vertex parent indicies --- source/blender/python/api2_2x/Object.c | 92 +++++++++++++++++++++ source/blender/python/api2_2x/doc/Object.py | 2 + 2 files changed, 94 insertions(+) diff --git a/source/blender/python/api2_2x/Object.c b/source/blender/python/api2_2x/Object.c index 1a806932bdb..3db9664d47d 100644 --- a/source/blender/python/api2_2x/Object.c +++ b/source/blender/python/api2_2x/Object.c @@ -360,6 +360,8 @@ static PyObject *Object_getMatrix( BPy_Object * self, PyObject * args ); static PyObject *Object_getParent( BPy_Object * self ); static PyObject *Object_getParentBoneName( BPy_Object * self ); static int Object_setParentBoneName( BPy_Object * self, PyObject * value ); +static PyObject *Object_getParentVertexIndex( BPy_Object * self ); +static int Object_setParentVertexIndex( BPy_Object * self, PyObject * value ); static PyObject *Object_getSize( BPy_Object * self, PyObject * args ); static PyObject *Object_getTimeOffset( BPy_Object * self ); static PyObject *Object_getTracked( BPy_Object * self ); @@ -1491,6 +1493,92 @@ static int Object_setParentBoneName( BPy_Object * self, PyObject *value ) return 0; } +static PyObject *Object_getParentVertexIndex( BPy_Object * self ) +{ + PyObject *pyls = NULL; + + if( self->object->parent) { + if (self->object->partype==PARVERT1) { + pyls = PyList_New(1); + PyList_SET_ITEM( pyls, 0, PyInt_FromLong( self->object->par1 )); + return pyls; + } else if (self->object->partype==PARVERT3) { + pyls = PyList_New(3); + PyList_SET_ITEM( pyls, 0, PyInt_FromLong( self->object->par1 )); + PyList_SET_ITEM( pyls, 1, PyInt_FromLong( self->object->par2 )); + PyList_SET_ITEM( pyls, 2, PyInt_FromLong( self->object->par3 )); + return pyls; + } + } + return PyList_New(0); +} + +static int Object_setParentVertexIndex( BPy_Object * self, PyObject *value ) +{ + PyObject *item; + int val[3] = {0,0,0}; + if( !self->object->parent) { + return EXPP_ReturnIntError( PyExc_RuntimeError, + "This object has no vertex parent, cant set the vertex parent indicies" ); + } + if (self->object->partype==PARVERT1) { + if (PySequence_Length(value) != 1) + return EXPP_ReturnIntError( PyExc_RuntimeError, + "Vertex parented to 1 vertex, can only assign a sequence with 1 vertex parent index" ); + item = PySequence_GetItem(value, 0); + if (item) { + val[0] = PyInt_AsLong(item); + Py_DECREF(item); + } + } else if (self->object->partype==PARVERT3) { + int i; + if (PySequence_Length(value) != 3) + return EXPP_ReturnIntError( PyExc_RuntimeError, + "Vertex parented to 3 verts, can only assign a sequence with 3 verts parent index" ); + + for (i=0; i<3; i++) { + item = PySequence_GetItem(value, i); + if (item) { + val[i] = PyInt_AsLong(item); + Py_DECREF(item); + } + } + } else { + return EXPP_ReturnIntError( PyExc_RuntimeError, + "This object has no vertex parent, cant set the vertex parent indicies" ); + } + + if (PyErr_Occurred()) { + return EXPP_ReturnIntError( PyExc_RuntimeError, + "This object has no vertex parent, cant set the vertex parent indicies" ); + } else { + if (self->object->partype==PARVERT1) { + if (val[0] < 0) { + return EXPP_ReturnIntError( PyExc_RuntimeError, + "vertex index less then zero" ); + } + + self->object->par1 = val[0]; + } else if (self->object->partype==PARVERT3) { + if (val[0]==val[1] || val[0]==val[2] || val[1]==val[2]) { + return EXPP_ReturnIntError( PyExc_RuntimeError, + "duplicate indicies in vertex parent assignment" ); + } + if (val[0] < 0 || val[1] < 0 || val[2] < 0) { + return EXPP_ReturnIntError( PyExc_RuntimeError, + "vertex index less then zero" ); + } + + self->object->par1 = val[0]; + self->object->par2 = val[1]; + self->object->par3 = val[2]; + } + } + + return 0; +} + + static PyObject *Object_getSize( BPy_Object * self, PyObject * args ) { char *space = "localspace"; /* default to local */ @@ -4916,6 +5004,10 @@ static PyGetSetDef BPy_Object_getseters[] = { (getter)Object_getParentBoneName, (setter)Object_setParentBoneName, "The object's parent object's sub name", NULL}, + {"parentVertexIndex", + (getter)Object_getParentVertexIndex, (setter)Object_setParentVertexIndex, + "Indicies used for vertex parents", + NULL}, {"track", (getter)Object_getTracked, (setter)Object_setTracked, "The object's tracked object", diff --git a/source/blender/python/api2_2x/doc/Object.py b/source/blender/python/api2_2x/doc/Object.py index 09167c0e117..2e4850aeb14 100644 --- a/source/blender/python/api2_2x/doc/Object.py +++ b/source/blender/python/api2_2x/doc/Object.py @@ -389,6 +389,8 @@ class Object: @ivar parentbonename: The string name of the parent bone (if defined). This can be set to another bone in the armature if the object already has a bone parent. @type parentbonename: string or None + @ivar parentVertexIndex: A list of vertex parent indicies, with a length of 0, 1 or 3. When there are 1 or 3 vertex parents, the indicies can be assigned to a sequence of the same length. + @type parentVertexIndex: list @ivar protectFlags: The "transform locking" bitfield flags for the object. See L{ProtectFlags} const dict for values. @type protectFlags: int From 61193cf2302fde403d39085d67e300ec2e9ad0f0 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 4 Jun 2008 16:38:55 +0000 Subject: [PATCH 151/246] svn merge -r15118:15119 https://svn.blender.org/svnroot/bf-blender/branches/soc-2008-quorn --- source/blender/blenkernel/intern/text.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/source/blender/blenkernel/intern/text.c b/source/blender/blenkernel/intern/text.c index 872f81ead63..876547042dc 100644 --- a/source/blender/blenkernel/intern/text.c +++ b/source/blender/blenkernel/intern/text.c @@ -2075,13 +2075,13 @@ void txt_backspace_char (Text *text) return; } else if (text->curc==0) { /* Appending two lines */ - if (text->curl->prev) { - text->curl= text->curl->prev; - text->curc= text->curl->len; - - txt_combine_lines(text, text->curl, text->curl->next); - txt_pop_sel(text); - } + if (!text->curl->prev) return; + + text->curl= text->curl->prev; + text->curc= text->curl->len; + + txt_combine_lines(text, text->curl, text->curl->next); + txt_pop_sel(text); } else { /* Just backspacing a char */ int i= text->curc-1; From fbb56ee99731bb788e89ce7c54706654a998e7ea Mon Sep 17 00:00:00 2001 From: Kent Mein Date: Wed, 4 Jun 2008 18:11:48 +0000 Subject: [PATCH 152/246] Issue jms was having with # else on msvc. Seems odd but easy to fix. Kent --- .../Rasterizer/RAS_OpenGLRasterizer/RAS_GLExtensionManager.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_GLExtensionManager.h b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_GLExtensionManager.h index a18ed038f35..3e24ee204a1 100644 --- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_GLExtensionManager.h +++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_GLExtensionManager.h @@ -53,9 +53,9 @@ #elif defined(__APPLE__) # include "mac_compat_glext.h" # include -# else +#else # include -# endif +#endif #endif #ifdef __sgi From c8e19a6b25f4b32ef64ba23479d80febc7c95db9 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 4 Jun 2008 22:32:15 +0000 Subject: [PATCH 153/246] numbutton python expression evaluation used driver dictionary, when EnableScriptlinks was disabled number button input didnt work. narrow down this test to the part of the pydriver module init that uses a blender textblock as a module. This should should reload the pydriver dict whenever the "EnableScriptlinks" state changes. but for now working numbuttons is priority. --- source/blender/python/BPY_interface.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/source/blender/python/BPY_interface.c b/source/blender/python/BPY_interface.c index c63fa28c46e..7c23c86d9ba 100644 --- a/source/blender/python/BPY_interface.c +++ b/source/blender/python/BPY_interface.c @@ -1222,7 +1222,7 @@ static int bpy_pydriver_create_dict(void) { PyObject *d, *mod; - if (bpy_pydriver_Dict || (G.f&G_DOSCRIPTLINKS)==0) return -1; + if (bpy_pydriver_Dict) return -1; d = PyDict_New(); if (!d) return -1; @@ -1259,15 +1259,16 @@ static int bpy_pydriver_create_dict(void) /* If there's a Blender text called pydrivers.py, import it. * Users can add their own functions to this module. */ - mod = importText("pydrivers"); /* can also use PyImport_Import() */ - if (mod) { - PyDict_SetItemString(d, "pydrivers", mod); - PyDict_SetItemString(d, "p", mod); - Py_DECREF(mod); + if (G.f&G_DOSCRIPTLINKS) { + mod = importText("pydrivers"); /* can also use PyImport_Import() */ + if (mod) { + PyDict_SetItemString(d, "pydrivers", mod); + PyDict_SetItemString(d, "p", mod); + Py_DECREF(mod); + } else { + PyErr_Clear(); + } } - else - PyErr_Clear(); - /* short aliases for some Get() functions: */ /* ob(obname) == Blender.Object.Get(obname) */ From ded6a1c2e7aaadcd982b22fdfeeedc436000182f Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 5 Jun 2008 10:43:53 +0000 Subject: [PATCH 154/246] bugfix introduced in own commit 15055 - [#13621] Cloth cache files are in same directory as .blend --- source/blender/blenkernel/intern/pointcache.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/blenkernel/intern/pointcache.c b/source/blender/blenkernel/intern/pointcache.c index 7b727528b3d..57ecffbb796 100644 --- a/source/blender/blenkernel/intern/pointcache.c +++ b/source/blender/blenkernel/intern/pointcache.c @@ -185,8 +185,8 @@ static int ptcache_path(PTCacheID *pid, char *filename) file[i-6] = '\0'; sprintf(filename, "//"PTCACHE_PATH"%s", file); /* add blend file name to pointcache dir */ - BLI_add_slash(filename); BLI_convertstringcode(filename, blendfilename); + BLI_add_slash(filename); return strlen(filename); } From 3d51c59034be1c3410ab5d2224cb0ef3b35f0ea1 Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Thu, 5 Jun 2008 10:52:52 +0000 Subject: [PATCH 155/246] Bugfix for exploding cloth collisions --- source/blender/blenkernel/intern/collision.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/source/blender/blenkernel/intern/collision.c b/source/blender/blenkernel/intern/collision.c index fc9a8132aaf..1809617fb3c 100644 --- a/source/blender/blenkernel/intern/collision.c +++ b/source/blender/blenkernel/intern/collision.c @@ -683,7 +683,8 @@ CollPair* cloth_collision ( ModifierData *md1, ModifierData *md2, BVHTreeOverlap collpair->distance = distance; collpair->flag = 0; - } + collpair++; + }/* else { float w1, w2, w3, u1, u2, u3; @@ -716,9 +717,9 @@ CollPair* cloth_collision ( ModifierData *md1, ModifierData *md2, BVHTreeOverlap { // check for collision in the future collpair->flag |= COLLISION_IN_FUTURE; + collpair++; } - } - collpair++; + }*/ } return collpair; } From fcdbd766257f09c04470f8d24ff5f9576a76f531 Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Thu, 5 Jun 2008 11:08:51 +0000 Subject: [PATCH 156/246] Collisions: enabling self collision quality setting again (request by Nudel) --- source/blender/blenkernel/intern/collision.c | 143 ++++++++++--------- 1 file changed, 73 insertions(+), 70 deletions(-) diff --git a/source/blender/blenkernel/intern/collision.c b/source/blender/blenkernel/intern/collision.c index 1809617fb3c..7f41ca033d3 100644 --- a/source/blender/blenkernel/intern/collision.c +++ b/source/blender/blenkernel/intern/collision.c @@ -1399,7 +1399,7 @@ int cloth_bvh_objcollision ( ClothModifierData * clmd, float step, float dt ) Cloth *cloth=NULL; Object *coll_ob=NULL; BVHTree *cloth_bvh=NULL; - long i=0, j = 0, k = 0, numfaces = 0, numverts = 0; + long i=0, j = 0, k = 0, l = 0, numfaces = 0, numverts = 0; int result = 0, rounds = 0; // result counts applied collisions; ic is for debug output; ClothVertex *verts = NULL; int ret = 0, ret2 = 0; @@ -1499,88 +1499,91 @@ int cloth_bvh_objcollision ( ClothModifierData * clmd, float step, float dt ) //////////////////////////////////////////////////////////// if ( clmd->coll_parms->flags & CLOTH_COLLSETTINGS_FLAG_SELF ) { - // TODO: add coll quality rounds again - BVHTreeOverlap *overlap = NULL; - - collisions = 1; - verts = cloth->verts; // needed for openMP - - numfaces = clmd->clothObject->numfaces; - numverts = clmd->clothObject->numverts; - - verts = cloth->verts; - - if ( cloth->bvhselftree ) + for(l = 0; l < clmd->coll_parms->self_loop_count; l++) { - // search for overlapping collision pairs - overlap = BLI_bvhtree_overlap ( cloth->bvhselftree, cloth->bvhselftree, &result ); - -// #pragma omp parallel for private(k, i, j) schedule(static) - for ( k = 0; k < result; k++ ) + // TODO: add coll quality rounds again + BVHTreeOverlap *overlap = NULL; + + collisions = 1; + verts = cloth->verts; // needed for openMP + + numfaces = clmd->clothObject->numfaces; + numverts = clmd->clothObject->numverts; + + verts = cloth->verts; + + if ( cloth->bvhselftree ) { - float temp[3]; - float length = 0; - float mindistance; - - i = overlap[k].indexA; - j = overlap[k].indexB; - - mindistance = clmd->coll_parms->selfepsilon* ( cloth->verts[i].avg_spring_len + cloth->verts[j].avg_spring_len ); - - if ( clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL ) + // search for overlapping collision pairs + overlap = BLI_bvhtree_overlap ( cloth->bvhselftree, cloth->bvhselftree, &result ); + + // #pragma omp parallel for private(k, i, j) schedule(static) + for ( k = 0; k < result; k++ ) { - if ( ( cloth->verts [i].flags & CLOTH_VERT_FLAG_PINNED ) - && ( cloth->verts [j].flags & CLOTH_VERT_FLAG_PINNED ) ) + float temp[3]; + float length = 0; + float mindistance; + + i = overlap[k].indexA; + j = overlap[k].indexB; + + mindistance = clmd->coll_parms->selfepsilon* ( cloth->verts[i].avg_spring_len + cloth->verts[j].avg_spring_len ); + + if ( clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL ) + { + if ( ( cloth->verts [i].flags & CLOTH_VERT_FLAG_PINNED ) + && ( cloth->verts [j].flags & CLOTH_VERT_FLAG_PINNED ) ) + { + continue; + } + } + + VECSUB ( temp, verts[i].tx, verts[j].tx ); + + if ( ( ABS ( temp[0] ) > mindistance ) || ( ABS ( temp[1] ) > mindistance ) || ( ABS ( temp[2] ) > mindistance ) ) continue; + + // check for adjacent points (i must be smaller j) + if ( BLI_edgehash_haskey ( cloth->edgehash, MIN2(i, j), MAX2(i, j) ) ) { continue; } - } - - VECSUB ( temp, verts[i].tx, verts[j].tx ); - - if ( ( ABS ( temp[0] ) > mindistance ) || ( ABS ( temp[1] ) > mindistance ) || ( ABS ( temp[2] ) > mindistance ) ) continue; - - // check for adjacent points (i must be smaller j) - if ( BLI_edgehash_haskey ( cloth->edgehash, MIN2(i, j), MAX2(i, j) ) ) - { - continue; - } - - length = Normalize ( temp ); - - if ( length < mindistance ) - { - float correction = mindistance - length; - - if ( cloth->verts [i].flags & CLOTH_VERT_FLAG_PINNED ) + + length = Normalize ( temp ); + + if ( length < mindistance ) { - VecMulf ( temp, -correction ); - VECADD ( verts[j].tx, verts[j].tx, temp ); - } - else if ( cloth->verts [j].flags & CLOTH_VERT_FLAG_PINNED ) - { - VecMulf ( temp, correction ); - VECADD ( verts[i].tx, verts[i].tx, temp ); + float correction = mindistance - length; + + if ( cloth->verts [i].flags & CLOTH_VERT_FLAG_PINNED ) + { + VecMulf ( temp, -correction ); + VECADD ( verts[j].tx, verts[j].tx, temp ); + } + else if ( cloth->verts [j].flags & CLOTH_VERT_FLAG_PINNED ) + { + VecMulf ( temp, correction ); + VECADD ( verts[i].tx, verts[i].tx, temp ); + } + else + { + VecMulf ( temp, -correction*0.5 ); + VECADD ( verts[j].tx, verts[j].tx, temp ); + + VECSUB ( verts[i].tx, verts[i].tx, temp ); + } + ret = 1; + ret2 += ret; } else { - VecMulf ( temp, -correction*0.5 ); - VECADD ( verts[j].tx, verts[j].tx, temp ); - - VECSUB ( verts[i].tx, verts[i].tx, temp ); + // check for approximated time collisions } - ret = 1; - ret2 += ret; - } - else - { - // check for approximated time collisions } + + if ( overlap ) + MEM_freeN ( overlap ); + } - - if ( overlap ) - MEM_freeN ( overlap ); - } //////////////////////////////////////////////////////////// From cc0d7309234e0c5444a101ce414e322f917628dc Mon Sep 17 00:00:00 2001 From: Remigiusz Fiedler Date: Thu, 5 Jun 2008 12:31:16 +0000 Subject: [PATCH 157/246] import_dxf.py script update: ver. 1.0.12b3-2008.06.05 bugfix: ob.name conflict with existing meshes (different ob.name/mesh.name) refactor/support for LWPOLYLINEs --- release/scripts/import_dxf.py | 1031 +++++++++++++++++++-------------- 1 file changed, 602 insertions(+), 429 deletions(-) diff --git a/release/scripts/import_dxf.py b/release/scripts/import_dxf.py index 88b42e3e564..ce7df610d98 100644 --- a/release/scripts/import_dxf.py +++ b/release/scripts/import_dxf.py @@ -1,5 +1,5 @@ #!BPY -# coding: utf-8 + """ Name: 'Autodesk DXF (.dxf)' Blender: 244 @@ -7,14 +7,15 @@ Group: 'Import' Tooltip: 'Import for DXF geometry data (Drawing eXchange Format).' """ __author__ = 'Kitsu(Ed Blake) & migius(Remigiusz Fiedler)' -__version__ = '1.0.12 - 2008.02.08 by migius' +__version__ = '1.0.12 - 2008.06.05 by migius' __url__ = ["http://blenderartists.org/forum/showthread.php?t=84319", "http://wiki.blender.org/index.php/Scripts/Manual/Import/DXF-3D"] __email__ = ["Kitsune_e(at)yahoo.com", "migius(at)4d-vectors.de"] __bpydoc__ = """\ This script imports objects from DXF (2d/3d) into Blender. -This script imports 2d and 3d geometery from DXFr12 format files. +This script imports 2d and 3d geometery from DXF files. +Supported DXF format versions: from (r2.5) r12 up to 2008. Enhanced features are: - configurable object filtering and geometry manipulation, - configurable material pre-processing, @@ -40,22 +41,23 @@ XREF (External Reference). Supported DXF>r12 objects: ELLIPSE, -(wip v1.0.12 partly supported) LWPOLYLINE (LightWeight), -(wip v1.0.12) MLINE, -(wip v1.0.12) MTEXT +LWPOLYLINE (LightWeight Polylines), +(wip v1.0.12) SPLINE, +(wip v1.0.13) MLINE, +(wip v1.0.13) MTEXT -Unsupported Objects: +Unsupported objects: DXF r12: DIMENSION. -DXF>r12: SPLINE, GROUP, RAY/XLINE, LEADER, 3DSOLID, BODY, REGION, dynamic BLOCK +DXF>r12: GROUP, RAY/XLINE, LEADER, 3DSOLID, BODY, REGION, dynamic BLOCK -Supported Geometry: 2d and 3d DXF-objects. -Curves imported as curves or meshes optionally. +Supported geometry: 2d and 3d DXF-objects. +Curves imported as Blender curves or meshes optionally. Supported layout modes: "model space" is default, "paper space" as option (= "layout views") -Scene definitions produced with AVE_RENDER: +Supported scene definition objescts produced with AVE_RENDER: scene: selection of lights assigned to the camera, lights: DIRECT, OVERHEAD, SH_SPOT, (wip v1.0.13 import of AVE_RENDER material definitions) @@ -77,14 +79,10 @@ It is recommended to use DXF-object properties for assign Blender materials. Notes: - Recommend that you run 'RemoveDoubles' on each imported mesh after using this script - Blocks are created on layer 19 then referenced at each insert point. -- Big DXF-files (over 1500 objects) decrease import performance. +- support for DXF-files up to 160MB on systems with 1GB RAM +- DXF-files with over 1500 objects decrease import performance. The problem is not the inefficiency of python-scripting but Blenders performance -in creating new objects in his database - probably a database management problem. - -TODO: -- the new style object visibility -- support for real 3d-solids (ACIS) -- (to see more, search for "--todo--" in script code) +in creating new objects in scene database - probably a database management problem. """ @@ -92,6 +90,7 @@ TODO: History: v1.0 - 2008.01. by migius planned tasks: + -- (to see more, search for "--todo--" in script code) -- command-line-mode/batch-mode -- in-place-editing for dupliGroups -- support for MLINE (is exported to r12 as BLOCK*Unnamed with LINEs) @@ -102,17 +101,23 @@ History: -- added f_layerFilter -- to-check: obj/mat/group/_mapping-idea from ideasman42: -- curves: added "fill/non-fill" option for closed curves: CIRCLEs,ELLIPSEs,POLYLINEs - -- bug:? object = Object.Get(obname) -> = SCENE.getChildren(obname) -- "normalize Z" option to correct non-planar figures -- LINEs need "width" in 3d-space incl vGroups -- support width_force for LINEs/ELLIPSEs = "solidify" -- add better support for color_index BYLAYER=256, BYBLOCK=0 - -- bug: "oneMesh" produces sometimes errors + -- bug: "oneMesh" produces irregularly errors -- bug: Registry recall from hd_cache ?? only win32 bug?? - - v1.0.12: 2008.02.08 by migius -- support DXF-definitions of scene, lights and cameras -- support ortho mode for VIEWs and VPORTs as cameras + -- add support for SPLINEs + + v1.0.12: 2008.06.05 by migius + b3 bugfix: ob.name conflict with existing meshes (different ob.name/mesh.name) + v1.0.12: 2008.05.24 by migius + b2 added support for LWPOLYLINEs + b2 added support for ProE in readerDXF.py + v1.0.12: 2008.02.08 by migius + b1 update: object = Object.Get(obname) -> f_getSceChild().getChildren() a9 bugfix by non-existing tables views, vports, layers (Kai reported) v1.0.12: 2008.01.17 by migius a8 lately used INI-dir/filename persistently stored in Registry @@ -279,9 +284,9 @@ History: # -------------------------------------------------------------------------- import Blender -#import bpy from Blender import * #from Blender.Mathutils import Vector, Matrix +import bpy #import BPyMessages from dxfReader import readDXF @@ -313,6 +318,8 @@ WORLDX = Mathutils.Vector((1,0,0)) WORLDY = Mathutils.Vector((1,1,0)) WORLDZ = Mathutils.Vector((0,0,1)) +oblist = [] #to be sure, it is an empty list + G_SCALE = 1.0 #(0.0001-1000) global scaling factor for all dxf data G_ORIGIN_X = 0.0 #global translation-vector (x,y,z) in DXF units G_ORIGIN_Y = 0.0 @@ -330,6 +337,10 @@ ELEVATION = 0.0 #standard elevation = coordinate Z TARGET_LAYER = 3 #target blender_layer GROUP_BYLAYER = 0 #(0/1) all entities from same layer import into one blender-group +cur_COUNTER = 0 #counter for progress_bar +M_OBJ = False +BYBLOCK = 0 +BYLAYER = 256 FILENAME_MAX = 180 #max length of path+file_name string (FILE_MAXDIR + FILE_MAXFILE) MAX_NAMELENGTH = 17 #max_effective_obnamelength in blender =21=17+(.001) @@ -342,75 +353,6 @@ AUTO = BezTriple.HandleTypes.AUTO FREE = BezTriple.HandleTypes.FREE VECT = BezTriple.HandleTypes.VECT ALIGN = BezTriple.HandleTypes.ALIGN -cur_COUNTER = 0 #counter for progress_bar - - -"""This module provides wrapper objects for dxf entities. - - The wrappers expect a "dxf object" as input. The dxf object is - an object with a type and a data attribute. Type is a lowercase - string matching the 0 code of a dxf entity. Data is a list containing - dxf objects or lists of [code, data] pairs. - - This module is not general, and is only for dxf import. -""" - -# from Stani's dxf writer v1.1 (c)www.stani.be (GPL) -#---color values -BYBLOCK = 0 -BYLAYER = 256 - -#---block-type flags (bit coded values, may be combined): -ANONYMOUS =1 # This is an anonymous block generated by hatching, associative dimensioning, other internal operations, or an application -NON_CONSTANT_ATTRIBUTES =2 # This block has non-constant attribute definitions (this bit is not set if the block has any attribute definitions that are constant, or has no attribute definitions at all) -XREF =4 # This block is an external reference (xref) -XREF_OVERLAY =8 # This block is an xref overlay -EXTERNAL =16 # This block is externally dependent -RESOLVED =32 # This is a resolved external reference, or dependent of an external reference (ignored on input) -REFERENCED =64 # This definition is a referenced external reference (ignored on input) - -#---polyline flags -CLOSED =1 # This is a closed polyline (or a polygon mesh closed in the M direction) -CURVE_FIT =2 # Curve-fit vertices have been added -SPLINE_FIT =4 # Spline-fit vertices have been added -POLYLINE_3D =8 # This is a 3D polyline -POLYGON_MESH =16 # This is a 3D polygon mesh -CLOSED_N =32 # The polygon mesh is closed in the N direction -POLYFACE_MESH =64 # The polyline is a polyface mesh -CONTINOUS_LINETYPE_PATTERN =128 # The linetype pattern is generated continuously around the vertices of this polyline - -#---text flags -#horizontal -LEFT = 0 -CENTER = 1 -RIGHT = 2 -ALIGNED = 3 #if vertical alignment = 0 -MIDDLE = 4 #if vertical alignment = 0 -FIT = 5 #if vertical alignment = 0 -#vertical -BASELINE = 0 -BOTTOM = 1 -MIDDLE = 2 -TOP = 3 - -#---mtext flags -#attachment point -TOP_LEFT = 1 -TOP_CENTER = 2 -TOP_RIGHT = 3 -MIDDLE_LEFT = 4 -MIDDLE_CENTER = 5 -MIDDLE_RIGHT = 6 -BOTTOM_LEFT = 7 -BOTTOM_CENTER = 8 -BOTTOM_RIGHT = 9 -#drawing direction -LEFT_RIGHT = 1 -TOP_BOTTOM = 3 -BY_STYLE = 5 #the flow direction is inherited from the associated text style -#line spacing style (optional): -AT_LEAST = 1 #taller characters will override -EXACT = 2 #taller characters will not override class View: #----------------------------------------------------------------- @@ -652,6 +594,14 @@ def get_extrusion(data): #------------------------------------------------- return vec +#------------------------------------------ +def getSceneChild(name): + dudu = [i for i in SCENE.objects if i.name==name] +# dudu = [i for i in SCENE.getChildren() if i.name==name] + #print 'deb:getSceneChild %s -result: %s:' %(name,dudu) #----------------- + if dudu!=[]: return dudu[0] + return None + class Solid: #----------------------------------------------------------------- """Class for objects representing dxf SOLID or TRACE. @@ -754,16 +704,16 @@ class Solid: #----------------------------------------------------------------- if l == 4: faces = [[0,1,3,2]] elif l == 3: faces = [[0,1,2]] elif l == 2: edges = [[0,1]] - - - - me = Mesh.New(obname) # create a new mesh + + if M_OBJ: obname, me, ob = makeNewObject() + else: + me = Mesh.New(obname) # create a new mesh + ob = SCENE.objects.new(me) # create a new mesh_object me.verts.extend(points) # add vertices to mesh if faces: me.faces.extend(faces) # add faces to the mesh if edges: me.edges.extend(edges) # add faces to the mesh - ob = SCENE.objects.new(me) # create a new mesh_object - if settings.var['vGroup_on']: + if settings.var['vGroup_on'] and not M_OBJ: # each MeshSide becomes vertexGroup for easier material assignment --------------------- replace = Blender.Mesh.AssignModes.ADD #or .AssignModes.ADD/REPLACE if vg_left: me.addVertGroup('side.left') ; me.assignVertsToGroup('side.left', vg_left, 1.0, replace) @@ -777,9 +727,6 @@ class Solid: #----------------------------------------------------------------- return ob - - - class Line: #----------------------------------------------------------------- """Class for objects representing dxf LINEs. """ @@ -838,7 +785,7 @@ class Line: #----------------------------------------------------------------- elif settings.var['lines_as'] == 3: # as thin cylinder cyl_rad = 0.5 * settings.var['width_min'] - if settings.var['lines_as'] == 5: # LINE curve representation------------------------- + elif settings.var['lines_as'] == 5: # LINE curve representation------------------------- obname = 'li_%s' %self.layer # create object name from layer name obname = obname[:MAX_NAMELENGTH] @@ -872,20 +819,23 @@ class Line: #----------------------------------------------------------------- global activObjectName #print 'deb:draw:line.ob IN activObjectName: ', activObjectName #--------------------- - if activObjectLayer == self.layer and settings.var['one_mesh_on']: - obname = activObjectName - #print 'deb:line.draw obname from activObjectName: ', obname #--------------------- - ob = Object.Get(obname) # open an existing mesh_object - #ob = SCENE.getChildren(obname) # open an existing mesh_object - me = Mesh.Get(ob.name) # open objects mesh data - else: - obname = 'li_%s' %self.layer # create object name from layer name - obname = obname[:MAX_NAMELENGTH] - me = Mesh.New(obname) # create a new mesh - ob = SCENE.objects.new(me) # create a new mesh_object - activObjectName = ob.name - activObjectLayer = self.layer - #print ('deb:line.draw new line.ob+mesh:"%s" created!' %ob.name) #--------------------- + if M_OBJ: obname, me, ob = makeNewObject() + else: + if activObjectLayer == self.layer and settings.var['one_mesh_on']: + obname = activObjectName + #print 'deb:line.draw obname from activObjectName: ', obname #--------------------- + ob = getSceneChild(obname) # open an existing mesh_object + #ob = SCENE.getChildren(obname) # open an existing mesh_object + #me = Mesh.Get(ob.name) # open objects mesh data + me = ob.getData(name_only=False, mesh=True) + else: + obname = 'li_%s' %self.layer # create object name from layer name + obname = obname[:MAX_NAMELENGTH] + me = Mesh.New(obname) # create a new mesh + ob = SCENE.objects.new(me) # create a new mesh_object + activObjectName = ob.name + activObjectLayer = self.layer + #print ('deb:line.draw new line.ob+mesh:"%s" created!' %ob.name) #--------------------- faces, edges = [], [] n = len(me.verts) @@ -904,7 +854,7 @@ class Line: #----------------------------------------------------------------- if faces: me.faces.extend(faces) # add faces to the mesh if edges: me.edges.extend(edges) # add faces to the mesh - if settings.var['vGroup_on']: + if settings.var['vGroup_on'] and not M_OBJ: # entities with the same color build one vertexGroup for easier material assignment ---- ob.link(me) # link mesh to that object vG_name = 'color_%s' %self.color_index @@ -988,155 +938,23 @@ class Point: #----------------------------------------------------------------- global activObjectLayer global activObjectName #print 'deb:draw:point.ob IN activObjectName: ', activObjectName #--------------------- - if activObjectLayer == self.layer and settings.var['one_mesh_on']: - obname = activObjectName - #print 'deb:draw:point.ob obname from activObjectName: ', obname #--------------------- - ob = Object.Get(obname) # open an existing mesh_object - #ob = SCENE.getChildren(obname) # open an existing mesh_object - me = Mesh.Get(ob.name) # open objects mesh data - else: - me = Mesh.New(obname) # create a new mesh - ob = SCENE.objects.new(me) # create a new mesh_object - activObjectName = ob.name - activObjectLayer = self.layer - #print ('deb:draw:point new point.ob+mesh:"%s" created!' %ob.name) #--------------------- - me.verts.extend(points) # add vertices to mesh - - return ob - - - -class LWpolyline: #----------------------------------------------------------------- - """Class for objects representing dxf LWPOLYLINEs. - """ - def __init__(self, obj): - """Expects an entity object of type lwpolyline as input. - """ - #print 'deb:LWpolyline.START:----------------' #------------------------ - if not obj.type == 'lwpolyline': - raise TypeError, "Wrong type %s for polyline object!" %obj.type - self.type = obj.type - self.data = obj.data[:] - - # required data - self.num_points = obj.get_type(90)[0] - - # optional data (with defaults) - self.space = getit(obj, 67, 0) - - self.color_index = getit(obj, 62, BYLAYER) - - self.elevation = getit(obj, 30, 0) - self.thic = getit(obj, 39, 0) - self.flags = getit(obj, 70, 0) - - self.closed = self.flags&1 # byte coded, 1 = closed, 128 = plinegen - - self.layer = getit(obj.data, 8, None) - self.points = self.get_points(obj.data) - self.extrusion = get_extrusion(obj.data) - - #print 'deb:LWpolyline.obj.data:\n', obj.data #------------------------ - #print 'deb:LWpolyline.ENDinit:----------------' #------------------------ - - - def get_points(self, data): - """Gets points for a polyline type object. - - LW-Polylines have no fixed number of verts, and - each vert can have a number of properties. - Verts should be coded as - 10:xvalue - 20:yvalue - 40:startwidth or 0 - 41:endwidth or 0 - 42:bulge or 0 - for each vert - """ - num = self.num_points - point = None - points = [] - for item in data: - if item[0] == 10: # 10 = x - if point: - points.append(point) - point = Vertex() - point.x = item[1] - elif item[0] == 20: # 20 = y - point.y = item[1] - elif item[0] == 40: # 40 = start width - point.swidth = item[1] - elif item[0] == 41: # 41 = end width - point.ewidth = item[1] - elif item[0] == 42: # 42 = bulge - point.bulge = item[1] - points.append(point) - return points - - - - def __repr__(self): - return "%s: layer - %s, points - %s" %(self.__class__.__name__, self.layer, self.points) - - - def draw(self, settings): - """for LWPOLYLINE: generate Blender_geometry. - """ - #print 'deb:LWpolyline.draw.START:----------------' #------------------------ - points = [] - obname = 'lw_%s' %self.layer # create object name from layer name - obname = obname[:MAX_NAMELENGTH] - #settings.var['curves_on'] == True - #print 'deb:index_len: ', len(self.points) #------------------ - for i, point in enumerate(self.points): - #print 'deb:index: ', i #------------------ - if not point.bulge: - points.append(point.loc) - elif point.bulge and not self.closed and i == len(self.points)-1: - points.append(point.loc) - elif point.bulge: # - if i == len(self.points)-1: - point2 = self.points[0] + if M_OBJ: obname, me, ob = makeNewObject() + else: + if activObjectLayer == self.layer and settings.var['one_mesh_on']: + obname = activObjectName + #print 'deb:draw:point.ob obname from activObjectName: ', obname #--------------------- + ob = getSceneChild(obname) # open an existing mesh_object + #ob = SCENE.getChildren(obname) # open an existing mesh_object + me = ob.getData(name_only=False, mesh=True) + #me = Mesh.Get(ob.name) # open objects mesh data else: - point2 = self.points[i+1] - arc_res = settings.var['arc_res']/sqrt(settings.var['arc_rad']) - verts, center = calcBulge(point, point2, arc_res) -# if i == len(self.points)-1: -# if self.closed: -# verts.pop() #remove last(=first) vertex -# else: -# verts.pop() #remove last vertex, because this point will be writen as the next vertex - points.extend(verts) - - thic = self.thic - if settings.var['thick_force'] and thic == 0: thic = settings.var['thick_min'] - if settings.var['thick_on'] and thic != 0: - len1 = len(points) - points.extend([[point[0], point[1], point[2]+thic] for point in points]) - faces = [] - #print 'deb:len1:', len1 #----------------------- - faces = [[num, num+1, num+len1+1, num+len1] for num in xrange(len1 - 1)] - if self.closed: - faces.append([len1-1, 0, len1, 2*len1-1]) - #print 'deb:faces_list:\n', faces #----------------------- - me = Mesh.New(obname) # create a new mesh - ob = SCENE.objects.new(me) # create a new mesh_object + me = Mesh.New(obname) # create a new mesh + ob = SCENE.objects.new(me) # create a new mesh_object + activObjectName = ob.name + activObjectLayer = self.layer + #print ('deb:draw:point new point.ob+mesh:"%s" created!' %ob.name) #--------------------- me.verts.extend(points) # add vertices to mesh - me.faces.extend(faces) # add faces to the mesh - else: - edges = [[num, num+1] for num in xrange(len(points)-1)] - if self.closed: - edges.append([len(points)-1, 0]) - #print 'deb:edges_list:\n', edges #----------------------- - me = Mesh.New(obname) # create a new mesh - ob = SCENE.objects.new(me) # create a new mesh_object - me.verts.extend(points) # add vertices to mesh - me.edges.extend(edges) # add edges to the mesh - ob.LocZ = self.elevation - transform(self.extrusion, 0, ob) - - #print 'deb:LWpolyline.draw.END:----------------' #------------------------ return ob @@ -1172,10 +990,10 @@ class Polyline: #-------------------------------------------------------------- self.plface = self.flags & 64 # 3D-polyface mesh self.contin = self.flags & 128 # the linetype pattern is generated continuously - if self.poly3d or self.plface or self.plmesh: - self.poly2d = False # its not a 2D-polyline - else: - self.poly2d = True # it is a 2D-polyline + self.pltype='poly2d' # default is a 2D-polyline + if self.poly3d: self.pltype='poly3d' + elif self.plface: self.pltype='plface' + elif self.plmesh: self.pltype='plmesh' self.swidth = getit(obj, 40, 0) # default start width self.ewidth = getit(obj, 41, 0) # default end width @@ -1213,19 +1031,19 @@ class Polyline: #-------------------------------------------------------------- """ ob = [] #---- 3dPolyFace - mesh with free topology - if self.plface and settings.drawTypes['plmesh']: + if self.pltype=='plface' and settings.drawTypes['plmesh']: ob = self.drawPlFace(settings) #---- 3dPolyMesh - mesh with ortogonal topology - elif self.plmesh and settings.drawTypes['plmesh']: + elif self.pltype=='plmesh' and settings.drawTypes['plmesh']: ob = self.drawPlMesh(settings) #---- 2dPolyline - plane polyline with arc/wide/thic segments - elif (self.poly2d and settings.drawTypes['polyline']): + elif self.pltype=='poly2d' and settings.drawTypes['polyline']: if settings.var['plines_as'] == 5: # and self.spline: ob = self.drawPolyCurve(settings) else: ob = self.drawPoly2d(settings) #---- 3dPolyline - non-plane polyline (thin segments = without arc/wide/thic) - elif (self.poly3d and settings.drawTypes['pline3']): + elif self.pltype=='poly3d' and settings.drawTypes['pline3']: if settings.var['plines3_as'] == 5: # and self.spline: ob = self.drawPolyCurve(settings) else: @@ -1355,21 +1173,7 @@ class Polyline: #-------------------------------------------------------------- pline = Curve.New(obname) # create new curve data #pline.setResolu(24) #--todo----- - if False: #self.spline: # NURBSplines-----FAKE(with Bezier)----- - #print 'deb:polyline2dCurve.draw self.spline!' #--------------- - curve = pline.appendNurb(BezTriple.New(d_points[0])) - for p in d_points[1:]: - curve.append(BezTriple.New(p)) - for point in curve: - point.handleTypes = [AUTO, AUTO] - if self.closed: - curve.flagU = 1 # Set curve cyclic=close - else: - curve.flagU = 0 # Set curve not cyclic=open - curve[0].handleTypes = [FREE, ALIGN] #remi--todo----- - curve[-1].handleTypes = [ALIGN, FREE] #remi--todo----- - - elif self.spline: # NURBSplines-----OK----- + if self.spline: # NURBSplines-----OK----- #print 'deb:polyline2dCurve.draw self.spline!' #--------------- weight1 = 0.5 weight2 = 1.0 @@ -1562,6 +1366,7 @@ class Polyline: #-------------------------------------------------------------- ewidths = [] swidth_default = self.swidth #default start width of POLYLINEs segments ewidth_default = self.ewidth #default end width of POLYLINEs segments + #print 'deb:drawPoly2d self.swidth=', self.swidth #------------------------ thic = set_thick(self.thic, settings) if self.spline: pline_typ = 'ps' elif self.curved: pline_typ = 'pc' @@ -1633,9 +1438,11 @@ class Polyline: #-------------------------------------------------------------- swidth = point1.swidth ewidth = point1.ewidth + #print 'deb:drawPoly2d point1.swidth=', swidth #------------------------ if swidth == None: swidth = swidth_default if ewidth == None: ewidth = ewidth_default if swidth != 0.0 or ewidth != 0.0: wide_segment_exist = True + #print 'deb:drawPoly2d vertex_swidth=', swidth #------------------------ if settings.var['width_force']: # force minimal width for thin segments width_min = settings.var['width_min'] @@ -1819,14 +1626,14 @@ class Polyline: #-------------------------------------------------------------- left_angle = False limit_dist = settings.var['dist_min'] if left_angle: # if left turning angle - print 'deb:drawPoly2d it is left turning angle' #------------- + #print 'deb:drawPoly2d it is left turning angle' #------------- # to avoid triangelface/doubleVertex delta1 = (cornerpointL - vecL1).normalize() * limit_dist delta4 = (cornerpointL - vecL4).normalize() * limit_dist pointsLc.extend((cornerpointL - delta1, cornerpointL - delta4)) pointsRc.extend((pointsRe[i],pointsRs[i+1])) else: # if right turning angle - print 'deb:drawPoly2d right turning angle' #------------- + #print 'deb:drawPoly2d right turning angle' #------------- delta1 = (cornerpointR - vecR1).normalize() * limit_dist delta4 = (cornerpointR - vecR4).normalize() * limit_dist pointsRc.extend((cornerpointR - delta1, cornerpointR - delta4)) @@ -1917,8 +1724,10 @@ class Polyline: #-------------------------------------------------------------- #faces = f_bottom + f_top #faces = f_left + f_right + f_start + f_end #print 'deb:faces_list:\n', faces #----------------------- - me = Mesh.New(obname) # create a new mesh - ob = SCENE.objects.new(me) # create a new mesh_object + if M_OBJ: obname, me, ob = makeNewObject() + else: + me = Mesh.New(obname) # create a new mesh + ob = SCENE.objects.new(me) # create a new mesh_object me.verts.extend(pointsW) # add vertices to mesh me.faces.extend(faces) # add faces to the mesh @@ -1926,7 +1735,7 @@ class Polyline: #-------------------------------------------------------------- # The mesh must first be linked to an object so the method knows which object to update. # This is because vertex groups in Blender are stored in the object -- not in the mesh, # which may be linked to more than one object. - if settings.var['vGroup_on']: + if settings.var['vGroup_on'] and not M_OBJ: # each MeshSide becomes vertexGroup for easier material assignment --------------------- replace = Blender.Mesh.AssignModes.REPLACE #or .AssignModes.ADD vg_left, vg_right, vg_top, vg_bottom = [], [], [], [] @@ -1956,8 +1765,10 @@ class Polyline: #-------------------------------------------------------------- faces = [[num, len1+num, len1+num+1, num+1] for num in xrange(len1 - 1)] if self.closed: faces.append([len1, 0, len1-1, len1+len1-1]) - me = Mesh.New(obname) # create a new mesh - ob = SCENE.objects.new(me) # create a new mesh_object + if M_OBJ: obname, me, ob = makeNewObject() + else: + me = Mesh.New(obname) # create a new mesh + ob = SCENE.objects.new(me) # create a new mesh_object me.verts.extend(pointsW) # add vertices to mesh me.faces.extend(faces) # add faces to the mesh @@ -1976,8 +1787,10 @@ class Polyline: #-------------------------------------------------------------- faces = [[num, num+1, num+len1+1, num+len1] for num in xrange(len1 - 1)] if self.closed: faces.append([len1-1, 0, len1, 2*len1-1]) - me = Mesh.New(obname) # create a new mesh - ob = SCENE.objects.new(me) # create a new mesh_object + if M_OBJ: obname, me, ob = makeNewObject() + else: + me = Mesh.New(obname) # create a new mesh + ob = SCENE.objects.new(me) # create a new mesh_object me.verts.extend(points) # add vertices to mesh me.faces.extend(faces) # add faces to the mesh @@ -1993,8 +1806,10 @@ class Polyline: #-------------------------------------------------------------- edges = [[num, num+1] for num in xrange(len(points)-1)] if self.closed: edges.append([len(points)-1, 0]) - me = Mesh.New(obname) # create a new mesh - ob = SCENE.objects.new(me) # create a new mesh_object + if M_OBJ: obname, me, ob = makeNewObject() + else: + me = Mesh.New(obname) # create a new mesh + ob = SCENE.objects.new(me) # create a new mesh_object me.verts.extend(points) # add vertices to mesh me.edges.extend(edges) # add edges to the mesh @@ -2006,7 +1821,8 @@ class Polyline: #-------------------------------------------------------------- class Vertex(object): #----------------------------------------------------------------- - """Generic vertex object used by POLYLINEs (and maybe others). + """Generic vertex object used by POLYLINEs, (and maybe others). + also used by class_LWPOLYLINEs but without obj-parameter """ def __init__(self, obj=None): @@ -2017,8 +1833,8 @@ class Vertex(object): #-------------------------------------------------------- #print 'deb:Vertex.init.START:----------------' #----------------------- self.loc = [0,0,0] self.face = [] - self.swidth = 0 - self.ewidth = 0 + self.swidth = None #0 + self.ewidth = None #0 self.bulge = 0 if obj is not None: if not obj.type == 'vertex': @@ -2058,14 +1874,14 @@ class Vertex(object): #-------------------------------------------------------- self.curv_tangent = getit(data, 50, None) # curve_tangent if self.plface and not self.plmesh: - v1 = getit(data, 71, 0) # polyface:Face.vertex 1. - v2 = getit(data, 72, 0) # polyface:Face.vertex 2. - v3 = getit(data, 73, 0) # polyface:Face.vertex 3. - v4 = getit(data, 74, None) # polyface:Face.vertex 4. - self.face = [abs(v1)-1,abs(v2)-1,abs(v3)-1] - if v4 != None: - if abs(v4) != abs(v1): - self.face.append(abs(v4)-1) + v1 = getit(data, 71, 0) # polyface:Face.vertex 1. + v2 = getit(data, 72, 0) # polyface:Face.vertex 2. + v3 = getit(data, 73, 0) # polyface:Face.vertex 3. + v4 = getit(data, 74, None) # polyface:Face.vertex 4. + self.face = [abs(v1)-1,abs(v2)-1,abs(v3)-1] + if v4 != None: + if abs(v4) != abs(v1): + self.face.append(abs(v4)-1) else: #--parameter for polyline2d self.swidth = getit(data, 40, None) # start width self.ewidth = getit(data, 41, None) # end width @@ -2119,6 +1935,304 @@ class Vertex(object): #-------------------------------------------------------- +class Spline(Polyline): #----------------------------------------------------------------- + """Class for objects representing dxf SPLINEs. + """ + def __init__(self, obj): + """Expects an entity object of type spline as input. +100 - Subclass marker (AcDbSpline) +210,220, 230 - Normal vector (omitted if the spline is nonplanar) X,Y,Z values of normal vector +70 - Spline flag (bit coded): + 1 = Closed spline + 2 = Periodic spline + 4 = Rational spline + 8 = Planar + 16 = Linear (planar bit is also set) +71 - Degree of the spline curve +72 - Number of knots +73 - Number of control points +74 - Number of fit points (if any) +42 - Knot tolerance (default = 0.0000001) +43 - Control-point tolerance (default = 0.0000001) +44 - Fit tolerance (default = 0.0000000001) +12,22,32 - Start tangent--may be omitted (in WCS). X,Y,Z values of start tangent--may be omitted (in WCS). +13,23, 33 - End tangent--may be omitted (in WCS). X,Y,Z values of end tangent--may be omitted (in WCS) +40 - Knot value (one entry per knot) +41 - Weight (if not 1); with multiple group pairs, are present if all are not 1 +10,20, 30 - Control points (in WCS) one entry per control point. +DXF: X value; APP: 3D point, Y and Z values of control points (in WCS) (one entry per control point) +11,21, 31 - Fit points (in WCS) one entry per fit point. + X,Y,Z values of fit points (in WCS) (one entry per fit point) + """ + #print 'deb:Spline.START:----------------' #------------------------ + if not obj.type == 'spline': + raise TypeError, "Wrong type %s for spline object!" %obj.type + self.type = obj.type + self.data = obj.data[:] + + # required data + self.num_points = obj.get_type(73)[0] + + # optional data (with defaults) + self.space = getit(obj, 67, 0) + + self.color_index = getit(obj, 62, BYLAYER) + + #self.elevation = getit(obj, 30, 0) + self.thic = 0 # getit(obj, 39, 0) + + width = 0 + self.swidth = width # default start width + self.ewidth = width # default end width + + self.flags = getit(obj, 70, 0) + self.closed = self.flags & 1 # closed spline + self.period = self.flags & 2 # Periodic spline + self.ration = self.flags & 4 # Rational spline + self.planar = self.flags & 8 # Planar + self.linear = self.flags & 16 # Linear (and Planar) + + self.degree = getit(obj, 71, 0) # Degree of the spline curve + self.curvNormal = False + self.curvQBspline = False + self.curvCBspline = False + self.curvBezier = False + if self.degree == 0: self.curvNormal = True + elif self.degree == 1: self.curvQBspline = True + elif self.degree == 2: self.curvCBspline = True + #elif self.degree == 3: self.curvBezier = True + elif self.degree == 3: self.spline = True + + self.num_knots = getit(obj, 72, 0) # Number of knots + self.num_contr = getit(obj, 73, 0) # Number of control points + self.num_fitpk = getit(obj, 74, 0) # Number of fit points (if any) + + self.layer = getit(obj.data, 8, None) + self.extrusion = get_extrusion(obj.data) + + self.points = self.get_points(obj.data) + + if self.planar: self.pltype = 'poly2d' + else: self.pltype = 'poly3d' + self.curved = False + #self.curved = False + + #print 'deb:Spline obj.data:\n', obj.data #------------------------ + #print 'deb:Spline self.points:\n', self.points #------------------------ + #print 'deb:Spline.ENDinit:----------------' #------------------------ + + + def get_points(self, data): + """Gets points for a spline type object. + + Splines have fixed number of verts, and + each vert can have a number of properties. + Verts should be coded as + 10:xvalue + 20:yvalue + for each vert + """ + num = self.num_contr + point = None + points = [] + #point = Vertex() + for item in data: + #print 'deb:Spline item:', item #------------------------ + if item[0] == 10: # control point + if point: points.append(point) + point = Vertex() + point.curved = True + point.x = item[1] + elif item[0] == 20: # 20 = y + point.y = item[1] + elif item[0] == 30: # 30 = z + point.z = item[1] + + elif item[0] == 11: # fit point + if point: points.append(point) + point = Vertex() + point.curved = True + point.x = item[1] + elif item[0] == 21: # 20 = y + point.y = item[1] + elif item[0] == 31: # 30 = z + point.z = item[1] + + elif item[0] == 12: # start tangent + if point: points.append(point) + point = Vertex() + point.curved = True + point.x = item[1] + elif item[0] == 22: # = y + point.y = item[1] + elif item[0] == 32: # = z + point.z = item[1] + + elif item[0] == 13: # end tangent + if point: points.append(point) + point = Vertex() + point.curved = True + point.x = item[1] + elif item[0] == 23: # 20 = y + point.y = item[1] + elif item[0] == 33: # 30 = z + point.z = item[1] + points.append(point) + #print 'deb:Spline points:\n', points #------------------------ + return points + + + + def __repr__(self): + return "%s: layer - %s, points - %s" %(self.__class__.__name__, self.layer, self.points) + + + + +class LWpolyline(Polyline): #------------------------------------------------------------- + """Class for objects representing dxf LWPOLYLINEs. + """ + def __init__(self, obj): + """Expects an entity object of type lwpolyline as input. + """ + #print 'deb:LWpolyline.START:----------------' #------------------------ + if not obj.type == 'lwpolyline': + raise TypeError, "Wrong type %s for polyline object!" %obj.type + self.type = obj.type + self.data = obj.data[:] + + # required data + self.num_points = obj.get_type(90)[0] + + # optional data (with defaults) + self.space = getit(obj, 67, 0) + self.elevation = getit(obj, 38, 0) + self.thic = getit(obj, 39, 0) + self.color_index = getit(obj, 62, BYLAYER) + width = getit(obj, 43, 0) + self.swidth = width # default start width + self.ewidth = width # default end width + #print 'deb:LWpolyline width=', width #------------------------ + #print 'deb:LWpolyline elevation=', self.elevation #------------------------ + + self.flags = getit(obj, 70, 0) + self.closed = self.flags&1 # byte coded, 1 = closed, 128 = plinegen + + self.layer = getit(obj.data, 8, None) + self.extrusion = get_extrusion(obj.data) + + self.points = self.get_points(obj.data) + + self.pltype = 'poly2d' # LW-polyline is a 2D-polyline + self.spline = False + self.curved = False + + + #print 'deb:LWpolyline.obj.data:\n', obj.data #------------------------ + #print 'deb:LWpolyline.ENDinit:----------------' #------------------------ + + + def get_points(self, data): + """Gets points for a polyline type object. + + LW-Polylines have no fixed number of verts, and + each vert can have a number of properties. + Verts should be coded as + 10:xvalue + 20:yvalue + 40:startwidth or 0 + 41:endwidth or 0 + 42:bulge or 0 + for each vert + """ + num = self.num_points + point = None + points = [] + for item in data: + if item[0] == 10: # 10 = x + if point: + points.append(point) + point = Vertex() + point.x = item[1] + point.z = self.elevation + elif item[0] == 20: # 20 = y + point.y = item[1] + elif item[0] == 40: # 40 = start width + point.swidth = item[1] + elif item[0] == 41: # 41 = end width + point.ewidth = item[1] + elif item[0] == 42: # 42 = bulge + point.bulge = item[1] + points.append(point) + return points + + + + def __repr__(self): + return "%s: layer - %s, points - %s" %(self.__class__.__name__, self.layer, self.points) + + + def draw_old(self, settings): + """for LWPOLYLINE: generate Blender_geometry. + """ + #print 'deb:LWpolyline.draw.START:----------------' #------------------------ + points = [] + obname = 'lw_%s' %self.layer # create object name from layer name + obname = obname[:MAX_NAMELENGTH] + #settings.var['curves_on'] == True + #print 'deb:index_len: ', len(self.points) #------------------ + for i, point in enumerate(self.points): + #print 'deb:index: ', i #------------------ + if not point.bulge: + points.append(point.loc) + elif point.bulge and not self.closed and i == len(self.points)-1: + points.append(point.loc) + elif point.bulge: # + if i == len(self.points)-1: + point2 = self.points[0] + else: + point2 = self.points[i+1] + arc_res = settings.var['arc_res']/sqrt(settings.var['arc_rad']) + verts, center = calcBulge(point, point2, arc_res) +# if i == len(self.points)-1: +# if self.closed: +# verts.pop() #remove last(=first) vertex +# else: +# verts.pop() #remove last vertex, because this point will be writen as the next vertex + points.extend(verts) + + thic = self.thic + if settings.var['thick_force'] and thic == 0: thic = settings.var['thick_min'] + if settings.var['thick_on'] and thic != 0: + len1 = len(points) + points.extend([[point[0], point[1], point[2]+thic] for point in points]) + faces = [] + #print 'deb:len1:', len1 #----------------------- + faces = [[num, num+1, num+len1+1, num+len1] for num in xrange(len1 - 1)] + if self.closed: + faces.append([len1-1, 0, len1, 2*len1-1]) + #print 'deb:faces_list:\n', faces #----------------------- + me = Mesh.New(obname) # create a new mesh + ob = SCENE.objects.new(me) # create a new mesh_object + me.verts.extend(points) # add vertices to mesh + me.faces.extend(faces) # add faces to the mesh + else: + edges = [[num, num+1] for num in xrange(len(points)-1)] + if self.closed: + edges.append([len(points)-1, 0]) + #print 'deb:edges_list:\n', edges #----------------------- + me = Mesh.New(obname) # create a new mesh + ob = SCENE.objects.new(me) # create a new mesh_object + me.verts.extend(points) # add vertices to mesh + me.edges.extend(edges) # add edges to the mesh + + ob.LocZ = self.elevation + transform(self.extrusion, 0, ob) + + #print 'deb:LWpolyline.draw.END:----------------' #------------------------ + return ob + + class Text: #----------------------------------------------------------------- """Class for objects representing dxf TEXT. """ @@ -2363,8 +2477,6 @@ class Mtext: #----------------------------------------------------------------- return ob - - class Circle: #----------------------------------------------------------------- """Class for objects representing dxf CIRCLEs. """ @@ -2494,8 +2606,10 @@ class Circle: #---------------------------------------------------------------- return ob else: # draw CIRCLE as mesh ----------------------------------------------- - cir = Mesh.New(obname) # create a new mesh - ob = SCENE.objects.new(cir) # create a new circle_object + if M_OBJ: obname, me, ob = makeNewObject() + else: + me = Mesh.New(obname) # create a new mesh + ob = SCENE.objects.new(me) # create a new mesh_object # set a number of segments in entire circle arc_res = settings.var['arc_res'] * sqrt(radius) / sqrt(settings.var['arc_rad']) start, end = 0.0 , 360.0 @@ -2534,24 +2648,24 @@ class Circle: #---------------------------------------------------------------- #print 'deb:circleDraw:verts:', verts #--------------- faces = f_band + f_bottom + f_top #print 'deb:circleDraw:faces:', faces #--------------- - cir.verts.extend(verts) # add vertices to mesh - cir.faces.extend(faces) # add faces to the mesh + me.verts.extend(verts) # add vertices to mesh + me.faces.extend(faces) # add faces to the mesh if settings.var['meshSmooth_on']: # left and right side become smooth ---------------------- for i in xrange(smooth_len): - cir.faces[i].smooth = True + me.faces[i].smooth = True # each MeshSide becomes vertexGroup for easier material assignment --------------------- - if settings.var['vGroup_on']: + if settings.var['vGroup_on'] and not M_OBJ: # each MeshSide becomes vertexGroup for easier material assignment --------------------- replace = Blender.Mesh.AssignModes.REPLACE #or .AssignModes.ADD vg_band, vg_top, vg_bottom = [], [], [] for v in f_band: vg_band.extend(v) - cir.addVertGroup('side.band') ; cir.assignVertsToGroup('side.band', list(set(vg_band)), 1.0, replace) + me.addVertGroup('side.band') ; me.assignVertsToGroup('side.band', list(set(vg_band)), 1.0, replace) if settings.var['fill_on']: for v in f_top: vg_top.extend(v) for v in f_bottom: vg_bottom.extend(v) - cir.addVertGroup('side.top') ; cir.assignVertsToGroup('side.top', list(set(vg_top)), 1.0, replace) - cir.addVertGroup('side.bottom'); cir.assignVertsToGroup('side.bottom',list(set(vg_bottom)), 1.0, replace) + me.addVertGroup('side.top') ; me.assignVertsToGroup('side.top', list(set(vg_top)), 1.0, replace) + me.addVertGroup('side.bottom'); me.assignVertsToGroup('side.bottom',list(set(vg_bottom)), 1.0, replace) else: # if thic == 0 if settings.var['fill_on']: @@ -2563,20 +2677,18 @@ class Circle: #---------------------------------------------------------------- faces.append([len1-1, 0, center1]) #print 'deb:circleDraw:verts:', verts #--------------- #print 'deb:circleDraw:faces:', faces #--------------- - cir.verts.extend(verts) # add vertices to mesh - cir.faces.extend(faces) # add faces to the mesh + me.verts.extend(verts) # add vertices to mesh + me.faces.extend(faces) # add faces to the mesh else: - cir.verts.extend(verts) # add vertices to mesh + me.verts.extend(verts) # add vertices to mesh edges = [[num, num+1] for num in xrange(len(verts))] edges[-1][1] = 0 # it points the "new" last edge to the first vertex - cir.edges.extend(edges) # add edges to the mesh + me.edges.extend(edges) # add edges to the mesh ob.loc = tuple(self.loc) transform(self.extrusion, 0, ob) return ob - - class Arc: #----------------------------------------------------------------- """Class for objects representing dxf ARCs. @@ -2670,8 +2782,10 @@ class Arc: #----------------------------------------------------------------- return ob else: # draw ARC as mesh -------------------- - me = Mesh.New(obname) # create a new mesh - ob = SCENE.objects.new(me) # create a new mesh_object + if M_OBJ: obname, me, ob = makeNewObject() + else: + me = Mesh.New(obname) # create a new mesh + ob = SCENE.objects.new(me) # create a new mesh_object # set a number of segments in entire circle arc_res = settings.var['arc_res'] * sqrt(radius) / sqrt(settings.var['arc_rad']) @@ -2719,7 +2833,7 @@ class Arc: #----------------------------------------------------------------- for i in xrange(smooth_len): me.faces[i].smooth = True # each MeshSide becomes vertexGroup for easier material assignment --------------------- - if settings.var['vGroup_on']: + if settings.var['vGroup_on'] and not M_OBJ: # each MeshSide becomes vertexGroup for easier material assignment --------------------- replace = Blender.Mesh.AssignModes.REPLACE #or .AssignModes.ADD vg_left, vg_right, vg_top, vg_bottom = [], [], [], [] @@ -2792,8 +2906,8 @@ class BlockRecord: #----------------------------------------------------------- # optional data (with defaults) self.insertion_units = getit(obj, 70, None) self.insert_units = getit(obj, 1070, None) - """code 1070 Einfügeeinheiten: - 0 = Keine Einheiten; 1 = Zoll; 2 = Fuß; 3 = Meilen; 4 = Millimeter; + """code 1070 Einfuegeeinheiten: + 0 = Keine Einheiten; 1 = Zoll; 2 = Fuss; 3 = Meilen; 4 = Millimeter; 5 = Zentimeter; 6 = Meter; 7 = Kilometer; 8 = Mikrozoll; 9 = Mils; 10 = Yard; 11 = Angstrom; 12 = Nanometer; 13 = Mikrons; 14 = Dezimeter; 15 = Dekameter; @@ -3048,7 +3162,7 @@ class Insert: #---------------------------------------------------------------- return ob elif settings.drawTypes['insert']: #if insert_drawType activated - print 'deb:draw. settings.blocknamesmap:', settings.blocknamesmap #-------------------- + #print 'deb:draw. settings.blocknamesmap:', settings.blocknamesmap #-------------------- obname = settings.blocknamesmap[self.name] obname = 'in_%s' %obname # create object name from block name #obname = obname[:MAX_NAMELENGTH] @@ -3193,10 +3307,10 @@ class Ellipse: #--------------------------------------------------------------- if settings.var['lines_as'] == 4: # as thin_box thic = settings.var['thick_min'] width = settings.var['width_min'] - if settings.var['lines_as'] == 3: # as thin cylinder + elif settings.var['lines_as'] == 3: # as thin cylinder cyl_rad = 0.5 * settings.var['width_min'] - if settings.var['lines_as'] == 5: # draw ELLIPSE as curve ------------- + elif settings.var['lines_as'] == 5: # draw ELLIPSE as curve ------------- arc_res = settings.var['curve_arc'] triples = True VectorTriples = calcArc(None, radius, start, end, arc_res, triples) @@ -3236,12 +3350,13 @@ class Ellipse: #--------------------------------------------------------------- else: # draw ELLIPSE as mesh -------------------------------------- - me = Mesh.New(obname) # create a new mesh - ob = SCENE.objects.new(me) # create a new mesh_object + if M_OBJ: obname, me, ob = makeNewObject() + else: + me = Mesh.New(obname) # create a new mesh + ob = SCENE.objects.new(me) # create a new mesh_object # set a number of segments in entire circle arc_res = settings.var['arc_res'] * sqrt(radius) / sqrt(settings.var['arc_rad']) - verts = calcArc(None, radius, start, end, arc_res, False) #verts = [list(point) for point in verts] if False: #--todo--: if ellipse_closed: @@ -3287,8 +3402,7 @@ class Ellipse: #--------------------------------------------------------------- smooth_len = len(f_left) + len(f_right) for i in xrange(smooth_len): me.faces[i].smooth = True - - if settings.var['vGroup_on']: + if settings.var['vGroup_on'] and not M_OBJ: # each MeshSide becomes vertexGroup for easier material assignment --------------------- replace = Blender.Mesh.AssignModes.REPLACE #or .AssignModes.ADD vg_left, vg_right, vg_top, vg_bottom = [], [], [], [] @@ -3408,21 +3522,24 @@ class Face: #----------------------------------------------------------------- global activObjectName #print 'deb:draw:face.ob IN activObjectName: ', activObjectName #--------------------- - if activObjectLayer == self.layer and settings.var['one_mesh_on']: - obname = activObjectName - #print 'deb:face.draw obname from activObjectName: ', obname #--------------------- - ob = Object.Get(obname) # open an existing mesh_object - #ob = SCENE.getChildren(obname) # open an existing mesh_object - else: - obname = 'fa_%s' %self.layer # create object name from layer name - obname = obname[:MAX_NAMELENGTH] - me = Mesh.New(obname) # create a new mesh - ob = SCENE.objects.new(me) # create a new mesh_object - activObjectName = ob.name - activObjectLayer = self.layer - #print ('deb:except. new face.ob+mesh:"%s" created!' %ob.name) #--------------------- - - me = Mesh.Get(ob.name) # open objects mesh data + if M_OBJ: obname, me, ob = makeNewObject() + else: + if activObjectLayer == self.layer and settings.var['one_mesh_on']: + obname = activObjectName + #print 'deb:face.draw obname from activObjectName: ', obname #--------------------- + ob = getSceneChild(obname) # open an existing mesh_object + #ob = SCENE.getChildren(obname) # open an existing mesh_object + me = ob.getData(name_only=False, mesh=True) + else: + obname = 'fa_%s' %self.layer # create object name from layer name + obname = obname[:MAX_NAMELENGTH] + me = Mesh.New(obname) # create a new mesh + ob = SCENE.objects.new(me) # create a new mesh_object + activObjectName = ob.name + activObjectLayer = self.layer + #print ('deb:except. new face.ob+mesh:"%s" created!' %ob.name) #--------------------- + + #me = Mesh.Get(ob.name) # open objects mesh data faces, edges = [], [] n = len(me.verts) if len(self.points) == 4: @@ -3435,7 +3552,7 @@ class Face: #----------------------------------------------------------------- me.verts.extend(points) # add vertices to mesh if faces: me.faces.extend(faces) # add faces to the mesh if edges: me.edges.extend(edges) # add faces to the mesh - if settings.var['vGroup_on']: + if settings.var['vGroup_on'] and not M_OBJ: # entities with the same color build one vertexGroup for easier material assignment --------------------- ob.link(me) # link mesh to that object vG_name = 'color_%s' %self.color_index @@ -3468,6 +3585,7 @@ type_map = { # 'mline':MLine, 'polyline':Polyline, 'lwpolyline':LWpolyline, + 'spline':Spline, # 'region':Region, 'trace':Solid, 'solid':Solid, @@ -3738,7 +3856,11 @@ class Blocks: #---------------------------------------------------------------- global oblist oblist.append((ob, insertFlag, blockFlag)) else: + if M_OBJ: + car_end() + car_start() drawEntities(block.entities, self.settings, block_def) + if M_OBJ: car_end() self.settings.write("Drawing block:\'%s\' done!" %name) self.blocks[name] = blender_group @@ -3809,7 +3931,8 @@ class Settings: #-------------------------------------------------------------- """Given the drawing, build dictionaries of Layers, Colors and Blocks. """ - #de: paßt die distance parameter an globalScale + global oblist + #adjust the distance parameter to globalScale if self.var['g_scale'] != 1.0: self.var['dist_min'] = self.var['dist_min'] / self.var['g_scale'] self.var['thick_min'] = self.var['thick_min'] / self.var['g_scale'] @@ -3859,7 +3982,6 @@ class Settings: #-------------------------------------------------------------- if views: #---------------------------------- if self.var['views_on']: - global oblist for item in views.data: if type(item) != list and item.type == 'view': #print 'deb:settings_valid views dir(item)=', dir(item) #------------- @@ -3876,7 +3998,6 @@ class Settings: #-------------------------------------------------------------- if vports: #---------------------------------- if self.var['views_on']: - global oblist for item in vports.data: if type(item) != list and item.type == 'vport': #print 'deb:settings_valid views dir(item)=', dir(item) #------------- @@ -3901,7 +4022,8 @@ class Settings: #-------------------------------------------------------------- # Read the block definitions and build our block object if self.drawTypes['insert']: #if support for entity type 'Insert' is activated #Build a dictionary of blockname:block_data pairs - blocksmap, self.obj_number = getBlocksmap(drawing, layersmap, self.var['layFrozen_on']) + blocksmap, obj_number = getBlocksmap(drawing, layersmap, self.var['layFrozen_on']) + self.obj_number += obj_number self.blocknamesmap = getBlocknamesmap(blocksmap) self.blocks = Blocks(blocksmap, self) # initiates container for blocks_data self.usedBlocks = blocksmap.keys() @@ -3916,9 +4038,7 @@ class Settings: #-------------------------------------------------------------- # The section:entities if 'entities' in sections.keys(): self.write("found section:entities") - self.obj_number += len(drawing.entities.data) - #print 'deb:settings_valid self.obj_number', self.obj_number #---------- self.obj_number = 1.0 / self.obj_number @@ -4152,6 +4272,7 @@ def analyzeDXF(dxfFile): #--------------------------------------- def main(dxfFile): #---------------#############################----------- #print 'deb:filename:', filename #-------------- global SCENE + global oblist editmode = Window.EditMode() # are we in edit mode? If so ... if editmode: Window.EditMode(0) # leave edit mode before @@ -4206,7 +4327,6 @@ def main(dxfFile): #---------------#############################----------- return None # Draw all the know entity types in the current scene - global oblist oblist = [] # a list of all created AND linked objects for final f_globalScale time2 = Blender.sys.time() #time marker2 @@ -4218,9 +4338,12 @@ def main(dxfFile): #---------------#############################----------- global activObjectLayer, activObjectName activObjectLayer, activObjectName = None, None + if M_OBJ: car_init() + drawEntities(drawing.entities, settings) #print 'deb:drawEntities after: oblist:', oblist #----------------------- + if M_OBJ: car_end() if oblist: # and settings.var['g_scale'] != 1: globalScale(oblist, settings.var['g_scale']) @@ -4357,7 +4480,7 @@ def getBlocksmap(drawing, layersmap, layFrozen_on=False): #-------------------- try: usedblocks[item.name] = [used, childList] except KeyError: print 'Cannot map "%s" - "%s" as Block!' %(item.name, item) #print 'deb:getBlocksmap: usedblocks=' , usedblocks #------------- - print 'deb:getBlocksmap: layersmap=' , layersmap #------------- + #print 'deb:getBlocksmap: layersmap=' , layersmap #------------- for item in drawing.entities.data: if type(item) != list and item.type == 'insert': @@ -4527,19 +4650,27 @@ def drawer(_type, entities, settings, block_def): #---------------------------- insertFlag = False alt_obname = activObjectName ob = entity.draw(settings) - if ob and ob.name != alt_obname: - if block_def: - blockFlag = True - bl_loc = block_def[1] - ob.loc = [ob.loc[0]-bl_loc[0],ob.loc[1]-bl_loc[1],ob.loc[2]-bl_loc[2]] - else: blockFlag = False - setObjectProperties(ob, group, entity, settings, block_def) - if settings.var['optimization'] <= settings.MIN: - #if settings.var['g_origin_on'] and not block_def: ob.loc = Mathutils.Vector(ob.loc) + settings.g_origin - if settings.var['g_scale_on']: globalScaleOne(ob, insertFlag, blockFlag, settings.var['g_scale']) - settings.redraw() - else: oblist.append((ob, insertFlag, blockFlag)) - + if ob: + if M_OBJ and ob.type=='Mesh': #'Curve', 'Text' + if block_def: + blockFlag = True + bl_loc = block_def[1] + ob.loc = [ob.loc[0]-bl_loc[0],ob.loc[1]-bl_loc[1],ob.loc[2]-bl_loc[2]] + car_nr() + + elif ob.name != alt_obname: + if block_def: + blockFlag = True + bl_loc = block_def[1] + ob.loc = [ob.loc[0]-bl_loc[0],ob.loc[1]-bl_loc[1],ob.loc[2]-bl_loc[2]] + else: blockFlag = False + setObjectProperties(ob, group, entity, settings, block_def) + if settings.var['optimization'] <= settings.MIN: + #if settings.var['g_origin_on'] and not block_def: ob.loc = Mathutils.Vector(ob.loc) + settings.g_origin + if settings.var['g_scale_on']: globalScaleOne(ob, insertFlag, blockFlag, settings.var['g_scale']) + settings.redraw() + else: oblist.append((ob, insertFlag, blockFlag)) + #print 'deb:Finished drawing:', entities[0].type #------------------------ message = "\nDrawing dxf\'%ss\' done!" % _type settings.write(message, True) @@ -4569,7 +4700,8 @@ def globalScaleOne(ob, insertFlag, blockFlag, SCALE): #------------------------ ob.loc = Mathutils.Vector(ob.loc) * SCALE_MAT else: # entire scaling for all other imported objects ------------ if ob.type == 'Mesh': - me = Mesh.Get(ob.name) + me = ob.getData(name_only=False, mesh=True) + #me = Mesh.Get(ob.name) # set centers of all objects in (0,0,0) #me.transform(ob.matrixWorld*SCALE_MAT) #ob.loc = Mathutils.Vector([0,0,0]) @@ -4990,6 +5122,7 @@ points_as_menu = "convert to: %t|empty %x1|mesh.vertex %x2|thin sphere %x3|thin lines_as_menu = "convert to: %t|*edge %x1|mesh %x2|*thin cylinder %x3|thin box %x4|curve %x5" mlines_as_menu = "convert to: %t|*edge %x1|*mesh %x2|*thin cylinder %x3|*thin box %x|*curve %x5" plines_as_menu = "convert to: %t|*edge %x1|mesh %x2|*thin cylinder %x3|*thin box %x4|curve %x5" +splines_as_menu = "convert to: %t|*edge %x1|mesh %x2|*thin cylinder %x3|*thin box %x4|curve %x5" plines3_as_menu = "convert to: %t|*edge %x1|mesh %x2|*thin cylinder %x3|*thin box %x4|curve %x5" plmesh_as_menu = "convert to: %t|*edge %x1|mesh %x2" solids_as_menu = "convert to: %t|*edge %x1|mesh %x2" @@ -5072,6 +5205,7 @@ keywords_org = { 'lines_as' : 2, 'mlines_as' : 2, 'plines_as' : 2, + 'splines_as' : 2, 'plines3_as': 2, 'plmesh_as' : 2, 'solids_as' : 2, @@ -5087,6 +5221,7 @@ drawTypes_org = { 'ellipse': 1, 'mline' : 0, 'polyline': 1, + 'spline': 0, 'plmesh': 1, 'pline3': 1, 'lwpolyline': 1, @@ -5272,12 +5407,14 @@ def presetConfig_curv(): #----------------------------------------------- GUI_A['lines_as'].val = 5 GUI_A['mlines_as'].val = 5 GUI_A['plines_as'].val = 5 + GUI_A['splines_as'].val = 5 GUI_A['plines3_as'].val = 5 else: GUI_A['points_as'].val = 2 GUI_A['lines_as'].val = 2 GUI_A['mlines_as'].val = 2 GUI_A['plines_as'].val = 2 + GUI_A['splines_as'].val = 2 GUI_A['plines3_as'].val = 2 @@ -5315,6 +5452,7 @@ def resetDefaultConfig_2D(): #----------------------------------------------- 'ellipse': 1, 'mline' : 0, 'polyline': 1, + 'spline': 0, 'plmesh': 0, 'pline3': 0, 'lwpolyline': 1, @@ -5361,6 +5499,7 @@ def resetDefaultConfig_3D(): #----------------------------------------------- 'ellipse': 1, 'mline' : 0, 'polyline': 1, + 'spline': 0, 'plmesh': 1, 'pline3': 1, 'lwpolyline': 1, @@ -5429,7 +5568,7 @@ def draw_UI(): #--------------------------------------------------------------- menu_w = (3 * butt_margin) + but_0c + but_1c + but_2c + but_3c #menu width simple_menu_h = 80 - extend_menu_h = 350 + extend_menu_h = 370 y = simple_menu_h # y is menu upper.y if config_UI.val: y += extend_menu_h x = 20 #menu left.x @@ -5450,8 +5589,9 @@ def draw_UI(): #--------------------------------------------------------------- if config_UI.val: b0, b0_ = but0c, but_0c + butt_margin b1, b1_ = but1c, but_1c - y -= 10 + y_top = y + y -= 10 y -= 20 Draw.BeginAlign() GUI_B['point'] = Draw.Toggle('POINT', EVENT_REDRAW, b0, y, b0_, 20, GUI_B['point'].val, "support dxf-POINT on/off") @@ -5476,7 +5616,14 @@ def draw_UI(): #--------------------------------------------------------------- y -= 20 Draw.BeginAlign() - GUI_B['polyline'] = Draw.Toggle('2D-PLINE', EVENT_REDRAW, b0, y, b0_, 20, GUI_B['polyline'].val, "support dxf-2D-POLYLINE on/off") + GUI_B['spline'] = Draw.Toggle('SPLINE', EVENT_REDRAW, b0, y, b0_, 20, GUI_B['spline'].val, "support dxf-SPLINE on/off") + if GUI_B['spline'].val: + GUI_A['splines_as'] = Draw.Menu(splines_as_menu, EVENT_NONE, but1c, y, but_1c, 20, GUI_A['splines_as'].val, "select target Blender-object") + Draw.EndAlign() + + y -= 20 + Draw.BeginAlign() + GUI_B['polyline'] = Draw.Toggle('2D/LWPLINE', EVENT_REDRAW, b0, y, b0_, 20, GUI_B['polyline'].val, "support dxf-2D-POLYLINE on/off") if GUI_B['polyline'].val: GUI_A['plines_as'] = Draw.Menu(plines_as_menu, EVENT_NONE, but1c, y, but_1c, 20, GUI_A['plines_as'].val, "select target Blender-object") Draw.EndAlign() @@ -5488,6 +5635,64 @@ def draw_UI(): #--------------------------------------------------------------- GUI_A['plines3_as'] = Draw.Menu(plines3_as_menu, EVENT_NONE, but1c, y, but_1c, 20, GUI_A['plines3_as'].val, "select target Blender-object") Draw.EndAlign() + y_down = y + # ----------------------------------------------- + + y = y_top + b0, b0_ = but2c, but_2c + butt_margin + b1, b1_ = but3c, but_3c + + y -= 10 + y -= 20 + Draw.BeginAlign() + GUI_B['plmesh'] = Draw.Toggle('POLY-MESH/FACE', EVENT_NONE, b0, y, b0_+b1_, 20, GUI_B['plmesh'].val, "support dxf-POLYMESH/POLYFACE on/off") +# GUI_A['plmesh_as'] = Draw.Menu(plmesh_as_menu, EVENT_NONE, but1c, y, but_1c, 20, GUI_A['plmesh_as'].val, "select target Blender-object") + Draw.EndAlign() + + y -= 20 + Draw.BeginAlign() + GUI_B['solid'] = Draw.Toggle('SOLID', EVENT_NONE, b0, y, b0_, 20, GUI_B['solid'].val, "support dxf-SOLID and TRACE on/off") + GUI_B['face'] = Draw.Toggle('3DFACE', EVENT_NONE, b1, y, b1_, 20, GUI_B['face'].val, "support dxf-3DFACE on/off") +# GUI_A['solids_as'] = Draw.Menu(solids_as_menu, EVENT_NONE, but3c, y, but_3c, 20, GUI_A['solids_as'].val, "select target Blender-object") + Draw.EndAlign() + #print 'deb:support solid, trace', GUI_B['trace'].val, GUI_B['solid'].val # ------------ + + + y -= 20 + Draw.BeginAlign() + GUI_B['text'] = Draw.Toggle('TEXT', EVENT_NONE, b0, y, b0_, 20, GUI_B['text'].val, "support dxf-TEXT on/off") + GUI_B['mtext'] = Draw.Toggle('*MTEXT', EVENT_NONE, b1, y, b1_, 20, GUI_B['mtext'].val, "(*wip)support dxf-MTEXT on/off") +# GUI_A['texts_as'] = Draw.Menu(texts_as_menu, EVENT_NONE, but3c, y, but_3c, 20, GUI_A['texts_as'].val, "select target Blender-object") + Draw.EndAlign() + + y -= 20 + Draw.BeginAlign() + GUI_B['block'] = Draw.Toggle('BLOCK', EVENT_REDRAW, b0, y, b0_-30, 20, GUI_B['block'].val, "support dxf-BLOCK and ARRAY on/off") + GUI_B['insert'].val = GUI_B['block'].val + if GUI_B['block'].val: + GUI_A['block_nn'] = Draw.Toggle('n', EVENT_NONE, b1-30, y, 15, 20, GUI_A['block_nn'].val, "support hatch/noname BLOCKs *X... on/off") + GUI_A['blockFilter_on'] = Draw.Toggle('F', EVENT_NONE, b1-15, y, 15, 20, GUI_A['blockFilter_on'].val, "(*wip) support name filtering of BLOCKs on/off") + GUI_A['xref_on'] = Draw.Toggle('Xref', EVENT_NONE, b1, y, 20, 20, GUI_A['xref_on'].val, "support place holder for XREF-BLOCKs on/off") + GUI_A['blocks_as'] = Draw.Menu(blocks_as_menu, EVENT_NONE, b1+20, y, b1_-20, 20, GUI_A['blocks_as'].val, "select target representation for imported BLOCKs") + Draw.EndAlign() + + + y -= 20 + Draw.BeginAlign() + GUI_A['views_on'] = Draw.Toggle('views', EVENT_NONE, b0, y, b0_-25, 20, GUI_A['views_on'].val, "imports VIEWs and VIEWPORTs as cameras on/off") + GUI_A['cams_on'] = Draw.Toggle('*cams', EVENT_NONE, b1-25, y, b1_-25, 20, GUI_A['cams_on'].val, "(*wip) support ASHADE cameras on/off") + GUI_A['lights_on'] = Draw.Toggle('*lights', EVENT_NONE, b1+25, y, b1_-25, 20, GUI_A['lights_on'].val, "(*wip) support AVE_RENDER lights on/off") + Draw.EndAlign() + + + if y < y_down: y_down = y + # -----end supported objects-------------------------------------- + + b0, b0_ = but0c, but_0c + butt_margin + b1, b1_ = but1c, but_1c + + y_top = y_down + y = y_top y -= 10 y -= 20 Draw.BeginAlign() @@ -5534,6 +5739,14 @@ def draw_UI(): #--------------------------------------------------------------- Draw.Label(scale_str, b1+45, y, 200, 20) Draw.EndAlign() + y_down = y + # -----end material,translate,scale------------------------------------------ + + b0, b0_ = but0c, but_0c + butt_margin + b1, b1_ = but1c, but_1c + + y_top = y_down + y = y_top y -= 10 y -= 20 Draw.BeginAlign() @@ -5571,56 +5784,11 @@ def draw_UI(): #--------------------------------------------------------------- y_down = y # ----------------------------------------------- - y = simple_menu_h + extend_menu_h +20 + b0, b0_ = but2c, but_2c + butt_margin b1, b1_ = but3c, but_3c - y -= 20 - Draw.BeginAlign() - GUI_B['plmesh'] = Draw.Toggle('POLY-MESH/FACE', EVENT_NONE, b0, y, b0_+b1_, 20, GUI_B['plmesh'].val, "support dxf-POLYMESH/POLYFACE on/off") -# GUI_A['plmesh_as'] = Draw.Menu(plmesh_as_menu, EVENT_NONE, but1c, y, but_1c, 20, GUI_A['plmesh_as'].val, "select target Blender-object") - Draw.EndAlign() - - y -= 20 - Draw.BeginAlign() - GUI_B['solid'] = Draw.Toggle('SOLID', EVENT_NONE, b0, y, b0_, 20, GUI_B['solid'].val, "support dxf-SOLID and TRACE on/off") - GUI_B['face'] = Draw.Toggle('3DFACE', EVENT_NONE, b1, y, b1_, 20, GUI_B['face'].val, "support dxf-3DFACE on/off") -# GUI_A['solids_as'] = Draw.Menu(solids_as_menu, EVENT_NONE, but3c, y, but_3c, 20, GUI_A['solids_as'].val, "select target Blender-object") - Draw.EndAlign() - #print 'deb:support solid, trace', GUI_B['trace'].val, GUI_B['solid'].val # ------------ - - - y -= 20 - Draw.BeginAlign() - GUI_B['text'] = Draw.Toggle('TEXT', EVENT_NONE, b0, y, b0_, 20, GUI_B['text'].val, "support dxf-TEXT on/off") - GUI_B['mtext'] = Draw.Toggle('*MTEXT', EVENT_NONE, b1, y, b1_, 20, GUI_B['mtext'].val, "(*wip)support dxf-MTEXT on/off") -# GUI_A['texts_as'] = Draw.Menu(texts_as_menu, EVENT_NONE, but3c, y, but_3c, 20, GUI_A['texts_as'].val, "select target Blender-object") - Draw.EndAlign() - - y -= 20 - Draw.BeginAlign() - GUI_B['block'] = Draw.Toggle('BLOCK', EVENT_REDRAW, b0, y, b0_-30, 20, GUI_B['block'].val, "support dxf-BLOCK and ARRAY on/off") - GUI_B['insert'].val = GUI_B['block'].val - if GUI_B['block'].val: - GUI_A['block_nn'] = Draw.Toggle('n', EVENT_NONE, b1-30, y, 15, 20, GUI_A['block_nn'].val, "support hatch/noname BLOCKs *X... on/off") - GUI_A['blockFilter_on'] = Draw.Toggle('F', EVENT_NONE, b1-15, y, 15, 20, GUI_A['blockFilter_on'].val, "(*wip) support name filtering of BLOCKs on/off") - GUI_A['xref_on'] = Draw.Toggle('Xref', EVENT_NONE, b1, y, 20, 20, GUI_A['xref_on'].val, "support place holder for XREF-BLOCKs on/off") - GUI_A['blocks_as'] = Draw.Menu(blocks_as_menu, EVENT_NONE, b1+20, y, b1_-20, 20, GUI_A['blocks_as'].val, "select target representation for imported BLOCKs") - Draw.EndAlign() - - - y -= 20 - Draw.BeginAlign() - GUI_A['views_on'] = Draw.Toggle('views', EVENT_NONE, b0, y, b0_-25, 20, GUI_A['views_on'].val, "imports VIEWs and VIEWPORTs as cameras on/off") - GUI_A['cams_on'] = Draw.Toggle('*cams', EVENT_NONE, b1-25, y, b1_-25, 20, GUI_A['cams_on'].val, "(*wip) support ASHADE cameras on/off") - GUI_A['lights_on'] = Draw.Toggle('*lights', EVENT_NONE, b1+25, y, b1_-25, 20, GUI_A['lights_on'].val, "(*wip) support AVE_RENDER lights on/off") - Draw.EndAlign() - - y -= 10 - y -= 20 - y -= 20 - y -= 20 - + y = y_top y -= 10 y -= 20 Draw.BeginAlign() @@ -5656,8 +5824,13 @@ def draw_UI(): #--------------------------------------------------------------- GUI_A['newScene_on'] = Draw.Toggle('newScene', EVENT_NONE, b0, y, b0_, 20, GUI_A['newScene_on'].val, "creates new Blender-Scene for each import on/off") GUI_A['target_layer'] = Draw.Number('layer', EVENT_NONE, b1, y, b1_, 20, GUI_A['target_layer'].val, 1, 18, "imports into this Blender-layer (<19> reserved for block_definitions)") + if y < y_down: y_down = y + # -----end options -------------------------------------- + + #-------------------------------------- - if y > y_down: y = y_down + y_top = y_down + y = y_top #GUI_A['dummy_on'] = Draw.Toggle(' - ', EVENT_NONE, but0c, y, but_0c, 20, GUI_A['dummy_on'].val, "reserved") y -= 30 Draw.BeginAlign() @@ -5891,6 +6064,7 @@ def multi_import(DIR): +UI_MODE = True if __name__ == "__main__": UI_MODE = True @@ -5942,5 +6116,4 @@ if 1: main(_dxf) print 'TOTAL TIME: %.6f' % (Blender.sys.time() - TIME) -""" - +""" \ No newline at end of file From 4f601b478c99ef9d74086e73a9eb38c9c598791d Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 5 Jun 2008 13:02:00 +0000 Subject: [PATCH 158/246] * python sys.cleanpath() used strstr incorrectly, resulting in paths containing a slash, always returning a path that ends with a slash. * python Blender.GetPaths() - absolute=0 wasnt working * BLI_cleanup_file and BLI_cleanup_file were treating the // prefix as a duplicate path, now ignores // * BLI_convertstringcode was removing the trailing slash from a path (tested these path functions didnt mess up with some of the peach files and with pointcache) --- source/blender/blenlib/intern/util.c | 38 ++++++++++++++++--------- source/blender/python/api2_2x/Blender.c | 2 +- source/blender/python/api2_2x/Sys.c | 5 ++-- 3 files changed, 28 insertions(+), 17 deletions(-) diff --git a/source/blender/blenlib/intern/util.c b/source/blender/blenlib/intern/util.c index 3610813f2da..ad34af05ac7 100644 --- a/source/blender/blenlib/intern/util.c +++ b/source/blender/blenlib/intern/util.c @@ -865,11 +865,8 @@ int BLI_strcaseeq(char *a, char *b) { void BLI_cleanup_dir(const char *relabase, char *dir) { BLI_cleanup_file(relabase, dir); -#ifdef WIN32 - strcat(dir, "\\"); -#else - strcat(dir, "/"); -#endif + BLI_add_slash(dir); + } void BLI_cleanup_file(const char *relabase, char *dir) @@ -878,6 +875,13 @@ void BLI_cleanup_file(const char *relabase, char *dir) char *start, *eind; if (relabase) { BLI_convertstringcode(dir, relabase); + } else { + if (dir[0]=='/' && dir[1]=='/') { + if (dir[2]== '\0') { + return; /* path is "//" - cant clean it */ + } + dir = dir+2; /* skip the first // */ + } } #ifdef WIN32 if(dir[0]=='.') { /* happens for example in FILE_MAIN */ @@ -1150,24 +1154,30 @@ int BLI_convertstringcode(char *path, const char *basepath) BLI_char_switch(tmp, '\\', '/'); BLI_char_switch(base, '\\', '/'); + /* Paths starting with // will get the blend file as their base, + * this isnt standard in any os but is uesed in blender all over the place */ if (tmp[0] == '/' && tmp[1] == '/') { - char *filepart= BLI_strdup(tmp+2); /* skip code */ char *lslash= BLI_last_slash(base); - if (lslash) { int baselen= (int) (lslash-base) + 1; - + /* use path for for temp storage here, we copy back over it right away */ + BLI_strncpy(path, tmp+2, FILE_MAX); + memcpy(tmp, base, baselen); - strcpy(tmp+baselen, filepart); + strcpy(tmp+baselen, path); + strcpy(path, tmp); } else { - strcpy(tmp, filepart); + strcpy(path, tmp+2); } - - MEM_freeN(filepart); + } else { + strcpy(path, tmp); } - BLI_cleanup_file(NULL, tmp); - strcpy(path, tmp); + if (path[strlen(path)-1]=='/') { + BLI_cleanup_dir(NULL, path); + } else { + BLI_cleanup_file(NULL, path); + } #ifdef WIN32 /* skip first two chars, which in case of diff --git a/source/blender/python/api2_2x/Blender.c b/source/blender/python/api2_2x/Blender.c index 6fce0864189..6b2e00f27de 100644 --- a/source/blender/python/api2_2x/Blender.c +++ b/source/blender/python/api2_2x/Blender.c @@ -952,7 +952,7 @@ static PyObject *Blender_GetPaths( PyObject * self, PyObject *args, PyObject *ke if (absolute) { BLI_bpathIterator_getPathExpanded( &bpi, filepath_expanded ); } else { - BLI_bpathIterator_getPathExpanded( &bpi, filepath_expanded ); + BLI_bpathIterator_getPath( &bpi, filepath_expanded ); } st = PyString_FromString(filepath_expanded); diff --git a/source/blender/python/api2_2x/Sys.c b/source/blender/python/api2_2x/Sys.c index 3863cc12227..b0d18f9f4aa 100644 --- a/source/blender/python/api2_2x/Sys.c +++ b/source/blender/python/api2_2x/Sys.c @@ -406,11 +406,12 @@ static PyObject *M_sys_cleanpath( PyObject * self, PyObject * value ) { char *path = PyString_AsString(value); char cleaned[FILE_MAXDIR + FILE_MAXFILE]; - int trailing_slash = 0; + int trailing_slash = 0, last; if (!path) return EXPP_ReturnPyObjError( PyExc_TypeError, "expected string argument" ); - if (strstr(path, "/") || strstr(path, "\\")) { + last = strlen(path)-1; + if ((path[last]=='/') || (path[last]=='\\')) { trailing_slash = 1; } BLI_strncpy(cleaned, path, FILE_MAXDIR + FILE_MAXFILE); From f35289574ac8a6c96fb82652a99509406ac2368e Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Thu, 5 Jun 2008 13:02:17 +0000 Subject: [PATCH 159/246] BLI_kdopbvh: crashed when traversing with little faces --- source/blender/blenlib/intern/BLI_kdopbvh.c | 25 ++++++++++----------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/source/blender/blenlib/intern/BLI_kdopbvh.c b/source/blender/blenlib/intern/BLI_kdopbvh.c index 9c4238431dc..a85883f6572 100644 --- a/source/blender/blenlib/intern/BLI_kdopbvh.c +++ b/source/blender/blenlib/intern/BLI_kdopbvh.c @@ -240,17 +240,16 @@ void sort_along_axis(BVHTree *tree, int start, int end, int axis) //after a call to this function you can expect one of: // every node to left of a[n] are smaller or equal to it // every node to the right of a[n] are greater or equal to it -int partition_nth_element(BVHNode **a, int _begin, int _end, int n, int axis){ - int begin = _begin, end = _end, cut; - int i; - while(end-begin > 3) - { - cut = bvh_partition(a, begin, end, bvh_medianof3(a, begin, (begin+end)/2, end-1, axis), axis ); - if(cut <= n) - begin = cut; - else - end = cut; - } +int partition_nth_element(BVHNode **a, int _begin, int _end, int n, int axis){ + int begin = _begin, end = _end, cut; + while(end-begin > 3) + { + cut = bvh_partition(a, begin, end, bvh_medianof3(a, begin, (begin+end)/2, end-1, axis), axis ); + if(cut <= n) + begin = cut; + else + end = cut; + } bvh_insertionsort(a, begin, end, axis); return n; @@ -415,7 +414,7 @@ static void refit_kdop_hull(BVHTree *tree, BVHNode *node, int start, int end) for (j = start; j < end; j++) { - // for all Axes. +// for all Axes. for (i = tree->start_axis; i < tree->stop_axis; i++) { newmin = tree->nodes[j]->bv[(2 * i)]; @@ -696,7 +695,7 @@ BVHTreeOverlap *BLI_bvhtree_overlap(BVHTree *tree1, BVHTree *tree2, int *result) } #pragma omp parallel for private(j) schedule(static) - for(j = 0; j < tree1->tree_type; j++) + for(j = 0; j < MIN2(tree1->tree_type, tree1->nodes[tree1->totleaf]->totnode); j++) { traverse(data[j], tree1->nodes[tree1->totleaf]->children[j], tree2->nodes[tree2->totleaf]); } From 6757b759ea29f8b59d92b2772efd2d0d1dac2c8a Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 5 Jun 2008 13:12:17 +0000 Subject: [PATCH 160/246] added checks for zero length strings when checking for the last character --- source/blender/blenlib/intern/util.c | 10 ++++++---- source/blender/python/api2_2x/Sys.c | 2 +- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/source/blender/blenlib/intern/util.c b/source/blender/blenlib/intern/util.c index ad34af05ac7..848e45ccb1b 100644 --- a/source/blender/blenlib/intern/util.c +++ b/source/blender/blenlib/intern/util.c @@ -1173,10 +1173,12 @@ int BLI_convertstringcode(char *path, const char *basepath) strcpy(path, tmp); } - if (path[strlen(path)-1]=='/') { - BLI_cleanup_dir(NULL, path); - } else { - BLI_cleanup_file(NULL, path); + if (path[0]!='\0') { + if ( path[strlen(path)-1]=='/') { + BLI_cleanup_dir(NULL, path); + } else { + BLI_cleanup_file(NULL, path); + } } #ifdef WIN32 diff --git a/source/blender/python/api2_2x/Sys.c b/source/blender/python/api2_2x/Sys.c index b0d18f9f4aa..baae2220143 100644 --- a/source/blender/python/api2_2x/Sys.c +++ b/source/blender/python/api2_2x/Sys.c @@ -411,7 +411,7 @@ static PyObject *M_sys_cleanpath( PyObject * self, PyObject * value ) return EXPP_ReturnPyObjError( PyExc_TypeError, "expected string argument" ); last = strlen(path)-1; - if ((path[last]=='/') || (path[last]=='\\')) { + if ((last >= 0) && ((path[last]=='/') || (path[last]=='\\'))) { trailing_slash = 1; } BLI_strncpy(cleaned, path, FILE_MAXDIR + FILE_MAXFILE); From 172fe6ed2f963b952833f39729e1bac52b479a2f Mon Sep 17 00:00:00 2001 From: Martin Poirier Date: Thu, 5 Jun 2008 14:49:12 +0000 Subject: [PATCH 161/246] Bugfix: [#13619] Transform Rotate and Scale Strange view: noclip version of int and float projection. Also project from behind the view's position and return coherent values for near clipping transform: use the above functions for 2d center and helpline drawing NOTE: the result for centers behind the camera (in perspective) isn't 100% perfect in the case of rotations because they always use the centered view vector as rotation axis and not the one aligned with the 2d center. Changing this would not be desirable anyway. At least it's predictible now. --- source/blender/include/BSE_view.h | 2 ++ source/blender/src/transform.c | 45 ++++++++++++++--------------- source/blender/src/view.c | 47 +++++++++++++++++++++++++++++-- 3 files changed, 70 insertions(+), 24 deletions(-) diff --git a/source/blender/include/BSE_view.h b/source/blender/include/BSE_view.h index 236f35f17c6..4b334fdd959 100644 --- a/source/blender/include/BSE_view.h +++ b/source/blender/include/BSE_view.h @@ -63,7 +63,9 @@ void window_to_3d(float *vec, short mx, short my); void project_short(float *vec, short *adr); void project_short_noclip(float *vec, short *adr); void project_int(float *vec, int *adr); +void project_int_noclip(float *vec, int *adr); void project_float(float *vec, float *adr); +void project_float_noclip(float *vec, float *adr); int boundbox_clip(float obmat[][4], struct BoundBox *bb); void fdrawline(float x1, float y1, float x2, float y2); diff --git a/source/blender/src/transform.c b/source/blender/src/transform.c index 10035c61651..4f6c33b0a64 100644 --- a/source/blender/src/transform.c +++ b/source/blender/src/transform.c @@ -135,24 +135,23 @@ static void helpline(TransInfo *t, float *vec) getmouseco_areawin(mval); projectFloatView(t, vecrot, cent); // no overflow in extreme cases - if(cent[0]!=IS_CLIPPED) { - persp(PERSP_WIN); - - glDrawBuffer(GL_FRONT); - - BIF_ThemeColor(TH_WIRE); - - setlinestyle(3); - glBegin(GL_LINE_STRIP); - glVertex2sv(mval); - glVertex2fv(cent); - glEnd(); - setlinestyle(0); - - persp(PERSP_VIEW); - bglFlush(); // flush display for frontbuffer - glDrawBuffer(GL_BACK); - } + + persp(PERSP_WIN); + + glDrawBuffer(GL_FRONT); + + BIF_ThemeColor(TH_WIRE); + + setlinestyle(3); + glBegin(GL_LINE_STRIP); + glVertex2sv(mval); + glVertex2fv(cent); + glEnd(); + setlinestyle(0); + + persp(PERSP_VIEW); + bglFlush(); // flush display for frontbuffer + glDrawBuffer(GL_BACK); } @@ -354,8 +353,9 @@ void convertViewVec(TransInfo *t, float *vec, short dx, short dy) void projectIntView(TransInfo *t, float *vec, int *adr) { - if (t->spacetype==SPACE_VIEW3D) - project_int(vec, adr); + if (t->spacetype==SPACE_VIEW3D) { + project_int_noclip(vec, adr); + } else if(t->spacetype==SPACE_IMAGE) { float aspx, aspy, v[2]; @@ -376,8 +376,9 @@ void projectIntView(TransInfo *t, float *vec, int *adr) void projectFloatView(TransInfo *t, float *vec, float *adr) { - if (t->spacetype==SPACE_VIEW3D) - project_float(vec, adr); + if (t->spacetype==SPACE_VIEW3D) { + project_float_noclip(vec, adr); + } else if(t->spacetype==SPACE_IMAGE) { int a[2]; diff --git a/source/blender/src/view.c b/source/blender/src/view.c index 1e45f2bf3e0..f53bcb3a9f7 100644 --- a/source/blender/src/view.c +++ b/source/blender/src/view.c @@ -228,6 +228,29 @@ void project_int(float *vec, int *adr) } } +void project_int_noclip(float *vec, int *adr) +{ + float fx, fy, vec4[4]; + + VECCOPY(vec4, vec); + vec4[3]= 1.0; + + Mat4MulVec4fl(G.vd->persmat, vec4); + + if( fabs(vec4[3]) > BL_NEAR_CLIP ) { + fx = (curarea->winx/2)*(1 + vec4[0]/vec4[3]); + fy = (curarea->winy/2)*(1 + vec4[1]/vec4[3]); + + adr[0] = floor(fx); + adr[1] = floor(fy); + } + else + { + adr[0] = curarea->winx / 2; + adr[1] = curarea->winy / 2; + } +} + void project_short_noclip(float *vec, short *adr) { float fx, fy, vec4[4]; @@ -264,8 +287,28 @@ void project_float(float *vec, float *adr) Mat4MulVec4fl(G.vd->persmat, vec4); if( vec4[3]>BL_NEAR_CLIP ) { - adr[0]= (curarea->winx/2.0)+(curarea->winx/2.0)*vec4[0]/vec4[3]; - adr[1]= (curarea->winy/2.0)+(curarea->winy/2.0)*vec4[1]/vec4[3]; + adr[0] = (curarea->winx/2.0)+(curarea->winx/2.0)*vec4[0]/vec4[3]; + adr[1] = (curarea->winy/2.0)+(curarea->winy/2.0)*vec4[1]/vec4[3]; + } +} + +void project_float_noclip(float *vec, float *adr) +{ + float vec4[4]; + + VECCOPY(vec4, vec); + vec4[3]= 1.0; + + Mat4MulVec4fl(G.vd->persmat, vec4); + + if( fabs(vec4[3]) > BL_NEAR_CLIP ) { + adr[0] = (curarea->winx/2.0)+(curarea->winx/2.0)*vec4[0]/vec4[3]; + adr[1] = (curarea->winy/2.0)+(curarea->winy/2.0)*vec4[1]/vec4[3]; + } + else + { + adr[0] = curarea->winx / 2.0f; + adr[1] = curarea->winy / 2.0f; } } From f2407fec559fe5853db935499b37b52c67578290 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 5 Jun 2008 18:26:34 +0000 Subject: [PATCH 162/246] Apricot feature, thats fit for trunk. Baking would split non-planer quads in an unpredictable way, which is fine for rending but game engines often use a fixed order (0,1,2), (0,2,3) or (1,2,3) (1,3,0). Added an option to use a fixed order when baking. --- source/blender/makesdna/DNA_scene_types.h | 2 +- .../render/intern/include/render_types.h | 1 + .../render/intern/source/convertblender.c | 34 +++++++++++++------ source/blender/src/buttons_scene.c | 4 +++ 4 files changed, 30 insertions(+), 11 deletions(-) diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h index 7b1b979b777..aae8a697cbe 100644 --- a/source/blender/makesdna/DNA_scene_types.h +++ b/source/blender/makesdna/DNA_scene_types.h @@ -274,7 +274,7 @@ typedef struct RenderData { /* Bake Render options */ short bake_osa, bake_filter, bake_mode, bake_flag; - short bake_normal_space, bpad; + short bake_normal_space, bake_quad_split; float bake_maxdist, bake_biasdist, bake_pad; /* yafray: global panel params. TODO: move elsewhere */ diff --git a/source/blender/render/intern/include/render_types.h b/source/blender/render/intern/include/render_types.h index d7e71b3e531..8414b6aefe3 100644 --- a/source/blender/render/intern/include/render_types.h +++ b/source/blender/render/intern/include/render_types.h @@ -499,6 +499,7 @@ typedef struct LampRen { #define R_NEED_TANGENT 32 #define R_SKIP_MULTIRES 64 #define R_BAKE_TRACE 128 +#define R_BAKING 256 /* vlakren->flag (vlak = face in dutch) char!!! */ #define R_SMOOTH 1 diff --git a/source/blender/render/intern/source/convertblender.c b/source/blender/render/intern/source/convertblender.c index dbade68ba1d..bef3690a43a 100644 --- a/source/blender/render/intern/source/convertblender.c +++ b/source/blender/render/intern/source/convertblender.c @@ -3935,7 +3935,7 @@ static void set_fullsample_flag(Render *re, ObjectRen *obr) } } -static void check_non_flat_quads(ObjectRen *obr) +static void check_non_flat_quads(ObjectRen *obr, int quad_flip) { VlakRen *vlr, *vlr1; VertRen *v1, *v2, *v3, *v4; @@ -3997,20 +3997,27 @@ static void check_non_flat_quads(ObjectRen *obr) xn= nor[0]*vlr->n[0] + nor[1]*vlr->n[1] + nor[2]*vlr->n[2]; if(ABS(xn) < 0.999995 ) { // checked on noisy fractal grid + float d1, d2; vlr1= RE_vlakren_copy(obr, vlr); vlr1->flag |= R_FACE_SPLIT; - /* split direction based on vnorms */ - CalcNormFloat(vlr->v1->co, vlr->v2->co, vlr->v3->co, nor); - d1= nor[0]*vlr->v1->n[0] + nor[1]*vlr->v1->n[1] + nor[2]*vlr->v1->n[2]; + if (quad_flip==0) { /* nonzero quad_flip is used to force dividing one way */ + /* split direction based on vnorms */ + CalcNormFloat(vlr->v1->co, vlr->v2->co, vlr->v3->co, nor); + d1= nor[0]*vlr->v1->n[0] + nor[1]*vlr->v1->n[1] + nor[2]*vlr->v1->n[2]; - CalcNormFloat(vlr->v2->co, vlr->v3->co, vlr->v4->co, nor); - d2= nor[0]*vlr->v2->n[0] + nor[1]*vlr->v2->n[1] + nor[2]*vlr->v2->n[2]; + CalcNormFloat(vlr->v2->co, vlr->v3->co, vlr->v4->co, nor); + d2= nor[0]*vlr->v2->n[0] + nor[1]*vlr->v2->n[1] + nor[2]*vlr->v2->n[2]; - if( fabs(d1) < fabs(d2) ) vlr->flag |= R_DIVIDE_24; - else vlr->flag &= ~R_DIVIDE_24; + if( fabs(d1) < fabs(d2) ) vlr->flag |= R_DIVIDE_24; + else vlr->flag &= ~R_DIVIDE_24; + } else if (quad_flip==1) { + vlr->flag &= ~R_DIVIDE_24; + } else { /* quad_flip == 3 */ + vlr->flag |= R_DIVIDE_24; + } /* new vertex pointers */ if (vlr->flag & R_DIVIDE_24) { @@ -4064,8 +4071,14 @@ static void finalize_render_object(Render *re, ObjectRen *obr, int timeoffset) ob->smoothresh= 0.0; if((re->r.mode & R_RAYTRACE) && (re->r.mode & R_SHADOW)) set_phong_threshold(obr); - - check_non_flat_quads(obr); + + if (re->flag & R_BAKING) { + /* Baking lets us define a quad split order */ + check_non_flat_quads(obr, re->r.bake_quad_split); + } else { + check_non_flat_quads(obr, 0); + } + set_fullsample_flag(re, obr); /* compute bounding boxes for clipping */ @@ -5421,6 +5434,7 @@ void RE_Database_Baking(Render *re, Scene *scene, int type, Object *actob) RE_init_threadcount(re); re->flag |= R_GLOB_NOPUNOFLIP; + re->flag |= R_BAKING; re->excludeob= actob; if(type == RE_BAKE_LIGHT) re->flag |= R_SKIP_MULTIRES; diff --git a/source/blender/src/buttons_scene.c b/source/blender/src/buttons_scene.c index b98a8c58102..cc26f1fc2bf 100644 --- a/source/blender/src/buttons_scene.c +++ b/source/blender/src/buttons_scene.c @@ -2150,6 +2150,10 @@ static void render_panel_bake(void) "Normalized displacement value to fit the 'Dist' range" ); } + + uiDefButS(block, MENU, B_NOP, "Quad Split Order%t|Quad Split Auto%x0|Quad Split A (0,1,2) (0,2,3)%x1|Quad Split B (1,2,3) (1,3,0)%x2", + 10,30,190,20, &G.scene->r.bake_quad_split, 0, 0, 0, 0, "Method to divide quads (use A or B for external applications that use a fixed order)"); + #if 0 uiBlockBeginAlign(block); uiDefButBitS(block, TOG, R_BAKE_OSA, B_DIFF, "OSA", 10,120,190,20, &G.scene->r.bake_flag, 0, 0, 0, 0, "Enables Oversampling (Anti-aliasing)"); From 49abcc980c389914e69ec2cbc79accf58adfefd9 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 5 Jun 2008 22:07:59 +0000 Subject: [PATCH 163/246] Added shadow baking --- source/blender/python/api2_2x/sceneRender.c | 3 ++- .../blender/render/extern/include/RE_pipeline.h | 2 ++ .../render/intern/source/convertblender.c | 7 ++++++- source/blender/render/intern/source/rendercore.c | 16 ++++++++++++++-- source/blender/src/buttons_scene.c | 13 +++++++------ source/blender/src/meshtools.c | 5 +++-- 6 files changed, 34 insertions(+), 12 deletions(-) diff --git a/source/blender/python/api2_2x/sceneRender.c b/source/blender/python/api2_2x/sceneRender.c index bfad069f943..b446af7efd4 100644 --- a/source/blender/python/api2_2x/sceneRender.c +++ b/source/blender/python/api2_2x/sceneRender.c @@ -2048,7 +2048,7 @@ static int RenderData_setIValueAttrClamp( BPy_RenderData *self, PyObject *value, break; case EXPP_RENDER_ATTR_BAKEMODE: min = RE_BAKE_LIGHT; - max = RE_BAKE_DISPLACEMENT; + max = RE_BAKE_SHADOW; size = 'h'; param = &self->renderContext->bake_mode; break; @@ -3781,6 +3781,7 @@ static PyObject *M_Render_BakeModesDict( void ) PyConstant_Insert( d, "NORMALS", PyInt_FromLong( RE_BAKE_NORMALS ) ); PyConstant_Insert( d, "TEXTURE", PyInt_FromLong( RE_BAKE_TEXTURE ) ); PyConstant_Insert( d, "DISPLACEMENT", PyInt_FromLong( RE_BAKE_DISPLACEMENT ) ); + PyConstant_Insert( d, "SHADOW", PyInt_FromLong( RE_BAKE_SHADOW ) ); } return M; } diff --git a/source/blender/render/extern/include/RE_pipeline.h b/source/blender/render/extern/include/RE_pipeline.h index 66dc1dd5fef..64cf7fcb37b 100644 --- a/source/blender/render/extern/include/RE_pipeline.h +++ b/source/blender/render/extern/include/RE_pipeline.h @@ -220,6 +220,8 @@ void RE_zbuf_accumulate_vecblur(struct NodeBlurData *nbd, int xsize, int ysize, #define RE_BAKE_NORMALS 3 #define RE_BAKE_TEXTURE 4 #define RE_BAKE_DISPLACEMENT 5 +#define RE_BAKE_SHADOW 6 + void RE_Database_Baking(struct Render *re, struct Scene *scene, int type, struct Object *actob); void RE_DataBase_GetView(struct Render *re, float mat[][4]); diff --git a/source/blender/render/intern/source/convertblender.c b/source/blender/render/intern/source/convertblender.c index bef3690a43a..afe4c47a9a4 100644 --- a/source/blender/render/intern/source/convertblender.c +++ b/source/blender/render/intern/source/convertblender.c @@ -5419,6 +5419,7 @@ void RE_Database_FromScene_Vectors(Render *re, Scene *sce) RE_BAKE_AO: for baking, no lamps, but all objects RE_BAKE_TEXTURE:for baking, no lamps, only selected objects RE_BAKE_DISPLACEMENT:for baking, no lamps, only selected objects + RE_BAKE_SHADOW: for baking, only shadows, but all objects */ void RE_Database_Baking(Render *re, Scene *scene, int type, Object *actob) { @@ -5449,6 +5450,10 @@ void RE_Database_Baking(Render *re, Scene *scene, int type, Object *actob) re->r.mode &= ~R_RAYTRACE; } + if(!actob && (type==RE_BAKE_SHADOW)) { + re->r.mode |= R_SHADOW; + } + /* setup render stuff */ re->memArena = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE); @@ -5486,7 +5491,7 @@ void RE_Database_Baking(Render *re, Scene *scene, int type, Object *actob) set_node_shader_lamp_loop(shade_material_loop); /* MAKE RENDER DATA */ - nolamps= !ELEM(type, RE_BAKE_LIGHT, RE_BAKE_ALL); + nolamps= !ELEM3(type, RE_BAKE_LIGHT, RE_BAKE_ALL, RE_BAKE_SHADOW); onlyselected= ELEM3(type, RE_BAKE_NORMALS, RE_BAKE_TEXTURE, RE_BAKE_DISPLACEMENT); database_init_objects(re, lay, nolamps, onlyselected, actob, 0); diff --git a/source/blender/render/intern/source/rendercore.c b/source/blender/render/intern/source/rendercore.c index ff31ba8a6ee..dae7b0dcd88 100644 --- a/source/blender/render/intern/source/rendercore.c +++ b/source/blender/render/intern/source/rendercore.c @@ -2017,9 +2017,12 @@ static void bake_shade(void *handle, Object *ob, ShadeInput *shi, int quad, int ambient_occlusion_to_diffuse(shi, shr.combined); } else { + if (bs->type==RE_BAKE_SHADOW) /* Why do shadows set the color anyhow?, ignore material color for baking */ + shi->r = shi->g = shi->b = 1.0f; + shade_input_set_shade_texco(shi); - if(!ELEM(bs->type, RE_BAKE_NORMALS, RE_BAKE_TEXTURE)) + if(!ELEM3(bs->type, RE_BAKE_NORMALS, RE_BAKE_TEXTURE, RE_BAKE_SHADOW)) shade_samples_do_AO(ssamp); if(shi->mat->nodetree && shi->mat->use_nodes) { @@ -2070,6 +2073,10 @@ static void bake_shade(void *handle, Object *ob, ShadeInput *shi, int quad, int shr.combined[2]= shi->b; shr.alpha = shi->alpha; } + else if(bs->type==RE_BAKE_SHADOW) { + VECCOPY(shr.combined, shr.shad); + shr.alpha = shi->alpha; + } } if(bs->rect_float) { @@ -2505,7 +2512,12 @@ int RE_bake_shade_all_selected(Render *re, int type, Object *actob) memset(&handles[a], 0, sizeof(BakeShade)); handles[a].ssamp.shi[0].lay= re->scene->lay; - handles[a].ssamp.shi[0].passflag= SCE_PASS_COMBINED; + + if (type==RE_BAKE_SHADOW) { + handles[a].ssamp.shi[0].passflag= SCE_PASS_SHADOW; + } else { + handles[a].ssamp.shi[0].passflag= SCE_PASS_COMBINED; + } handles[a].ssamp.shi[0].combinedflag= ~(SCE_PASS_SPEC); handles[a].ssamp.shi[0].thread= a; handles[a].ssamp.tot= 1; diff --git a/source/blender/src/buttons_scene.c b/source/blender/src/buttons_scene.c index cc26f1fc2bf..3797a92f16f 100644 --- a/source/blender/src/buttons_scene.c +++ b/source/blender/src/buttons_scene.c @@ -2152,7 +2152,7 @@ static void render_panel_bake(void) } uiDefButS(block, MENU, B_NOP, "Quad Split Order%t|Quad Split Auto%x0|Quad Split A (0,1,2) (0,2,3)%x1|Quad Split B (1,2,3) (1,3,0)%x2", - 10,30,190,20, &G.scene->r.bake_quad_split, 0, 0, 0, 0, "Method to divide quads (use A or B for external applications that use a fixed order)"); + 10,10,190,20, &G.scene->r.bake_quad_split, 0, 0, 0, 0, "Method to divide quads (use A or B for external applications that use a fixed order)"); #if 0 uiBlockBeginAlign(block); @@ -2165,14 +2165,15 @@ static void render_panel_bake(void) uiBlockBeginAlign(block); uiDefButS(block, ROW,B_REDR,"Full Render", 210,170,120,20,&G.scene->r.bake_mode, 1.0, RE_BAKE_ALL, 0, 0, ""); uiDefButS(block, ROW,B_REDR,"Ambient Occlusion",210,150,120,20,&G.scene->r.bake_mode, 1.0, RE_BAKE_AO, 0, 0, ""); - uiDefButS(block, ROW,B_REDR,"Normals", 210,130,120,20,&G.scene->r.bake_mode, 1.0, RE_BAKE_NORMALS, 0, 0, ""); - uiDefButS(block, ROW,B_REDR,"Textures", 210,110,120,20,&G.scene->r.bake_mode, 1.0, RE_BAKE_TEXTURE, 0, 0, ""); - uiDefButS(block, ROW,B_REDR,"Displacement", 210,90,120,20,&G.scene->r.bake_mode, 1.0, RE_BAKE_DISPLACEMENT, 0, 0, ""); + uiDefButS(block, ROW,B_REDR,"Shadow", 210,130,120,20,&G.scene->r.bake_mode, 1.0, RE_BAKE_SHADOW, 0, 0, ""); + uiDefButS(block, ROW,B_REDR,"Normals", 210,110,120,20,&G.scene->r.bake_mode, 1.0, RE_BAKE_NORMALS, 0, 0, ""); + uiDefButS(block, ROW,B_REDR,"Textures", 210,90,120,20,&G.scene->r.bake_mode, 1.0, RE_BAKE_TEXTURE, 0, 0, ""); + uiDefButS(block, ROW,B_REDR,"Displacement", 210,70,120,20,&G.scene->r.bake_mode, 1.0, RE_BAKE_DISPLACEMENT, 0, 0, ""); uiBlockEndAlign(block); - uiDefButBitS(block, TOG, R_BAKE_CLEAR, B_DIFF, "Clear", 210,60,120,20,&G.scene->r.bake_flag, 0.0, 0, 0, 0, "Clear Images before baking"); + uiDefButBitS(block, TOG, R_BAKE_CLEAR, B_DIFF, "Clear", 210,40,120,20,&G.scene->r.bake_flag, 0.0, 0, 0, 0, "Clear Images before baking"); - uiDefButS(block, NUM, B_DIFF,"Margin:", 210,30,120,20,&G.scene->r.bake_filter, 0.0, 32.0, 0, 0, "Amount of pixels to extend the baked result with, as post process filter"); + uiDefButS(block, NUM, B_DIFF,"Margin:", 210,10,120,20,&G.scene->r.bake_filter, 0.0, 32.0, 0, 0, "Amount of pixels to extend the baked result with, as post process filter"); } static void render_panel_simplify(void) diff --git a/source/blender/src/meshtools.c b/source/blender/src/meshtools.c index ac165d6aeb2..0f30aef04df 100644 --- a/source/blender/src/meshtools.c +++ b/source/blender/src/meshtools.c @@ -1026,7 +1026,7 @@ void objects_bake_render_menu(void) { short event; - event= pupmenu("Bake Selected Meshes %t|Full Render %x1|Ambient Occlusion %x2|Normals %x3|Texture Only %x4|Displacement %x5"); + event= pupmenu("Bake Selected Meshes %t|Full Render %x1|Ambient Occlusion %x2|Normals %x3|Texture Only %x4|Displacement %x5|Shadow %x6"); if (event < 1) return; objects_bake_render_ui(event); } @@ -1062,7 +1062,8 @@ void objects_bake_render(short event, char **error_msg) else if(event==2) event= RE_BAKE_AO; else if(event==3) event= RE_BAKE_NORMALS; else if(event==4) event= RE_BAKE_TEXTURE; - else event= RE_BAKE_DISPLACEMENT; + else if(event==5) event= RE_BAKE_DISPLACEMENT; + else event= RE_BAKE_SHADOW; if(event==RE_BAKE_AO) { if(G.scene->world==NULL) { From 6ffadbfb103f498b7400ae6d7d960c98404a9bdc Mon Sep 17 00:00:00 2001 From: Hamed Zaghaghi Date: Fri, 6 Jun 2008 01:28:51 +0000 Subject: [PATCH 164/246] fix 2dfilter problem on AMD64, Patches item #13626 --- source/gameengine/Rasterizer/RAS_2DFilterManager.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source/gameengine/Rasterizer/RAS_2DFilterManager.cpp b/source/gameengine/Rasterizer/RAS_2DFilterManager.cpp index e8562c54539..80d6d55df25 100644 --- a/source/gameengine/Rasterizer/RAS_2DFilterManager.cpp +++ b/source/gameengine/Rasterizer/RAS_2DFilterManager.cpp @@ -166,7 +166,8 @@ void RAS_2DFilterManager::StartShaderProgram(unsigned int shaderprogram) GLint uniformLoc; bgl::blUseProgramObjectARB(shaderprogram); uniformLoc = bgl::blGetUniformLocationARB(shaderprogram, "bgl_RenderedTexture"); - glActiveTexture(GL_TEXTURE0); + bgl::blActiveTextureARB(GL_TEXTURE0); + //glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, texname); if (uniformLoc != -1) From 14393c9ffbe67eb41281fcc50f8a0ff44e4fe0fc Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 6 Jun 2008 08:58:08 +0000 Subject: [PATCH 165/246] bugfix - Blender.GetPaths() was returning relative paths from libraries, but with no way to access the library path the the file is relative too. Check for these cases and make them absolute. bpath also assigned one var it didnt need to. --- source/blender/blenlib/intern/bpath.c | 3 --- source/blender/python/api2_2x/Blender.c | 8 +++++++- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/source/blender/blenlib/intern/bpath.c b/source/blender/blenlib/intern/bpath.c index 79d3e487712..898ad6ddd67 100644 --- a/source/blender/blenlib/intern/bpath.c +++ b/source/blender/blenlib/intern/bpath.c @@ -456,13 +456,10 @@ void checkMissingFiles( char *txtname ) { /* be sure there is low chance of the path being too short */ char filepath_expanded[FILE_MAXDIR*2]; - char *libpath; int files_missing = 0; BLI_bpathIterator_init(&bpi); while (!BLI_bpathIterator_isDone(&bpi)) { - libpath = BLI_bpathIterator_getLib(&bpi); - BLI_bpathIterator_getPathExpanded( &bpi, filepath_expanded ); if (!BLI_exists(filepath_expanded)) { diff --git a/source/blender/python/api2_2x/Blender.c b/source/blender/python/api2_2x/Blender.c index 6b2e00f27de..d8385c1d660 100644 --- a/source/blender/python/api2_2x/Blender.c +++ b/source/blender/python/api2_2x/Blender.c @@ -936,6 +936,7 @@ static PyObject *Blender_GetPaths( PyObject * self, PyObject *args, PyObject *ke PyObject *list = PyList_New(0), *st; /* stupidly big string to be safe */ /* be sure there is low chance of the path being too short */ char filepath_expanded[FILE_MAXDIR*2]; + char *lib; int absolute = 0; static char *kwlist[] = {"absolute", NULL}; @@ -952,7 +953,12 @@ static PyObject *Blender_GetPaths( PyObject * self, PyObject *args, PyObject *ke if (absolute) { BLI_bpathIterator_getPathExpanded( &bpi, filepath_expanded ); } else { - BLI_bpathIterator_getPath( &bpi, filepath_expanded ); + lib = BLI_bpathIterator_getLib( &bpi ); + if ( lib && ( strcmp(lib, G.sce) ) ) { /* relative path to the library is NOT the same as our blendfile path, return an absolute path */ + BLI_bpathIterator_getPathExpanded( &bpi, filepath_expanded ); + } else { + BLI_bpathIterator_getPath( &bpi, filepath_expanded ); + } } st = PyString_FromString(filepath_expanded); From b62955cf3ea9a5e0f47ee93291820e5b60870b4b Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 6 Jun 2008 11:00:32 +0000 Subject: [PATCH 166/246] bugfix, memory leaks when getting particles and particle system loc/size/rot/life (Just remember PyList_Append adds a reference! :) ) --- source/blender/python/api2_2x/Object.c | 2 ++ source/blender/python/api2_2x/Particle.c | 14 ++++++++++++-- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/source/blender/python/api2_2x/Object.c b/source/blender/python/api2_2x/Object.c index 3db9664d47d..45cce46d389 100644 --- a/source/blender/python/api2_2x/Object.c +++ b/source/blender/python/api2_2x/Object.c @@ -1056,10 +1056,12 @@ PyObject *Object_getParticleSys( BPy_Object * self ){ /* fixme: for(;;) */ current = ParticleSys_CreatePyObject( blparticlesys, ob ); PyList_Append(partsyslist,current); + Py_DECREF(current); while((blparticlesys = blparticlesys->next)){ current = ParticleSys_CreatePyObject( blparticlesys, ob ); PyList_Append(partsyslist,current); + Py_DECREF(current); } return partsyslist; diff --git a/source/blender/python/api2_2x/Particle.c b/source/blender/python/api2_2x/Particle.c index f0a32db0623..95de9757b87 100644 --- a/source/blender/python/api2_2x/Particle.c +++ b/source/blender/python/api2_2x/Particle.c @@ -854,7 +854,7 @@ static PyObject *Part_GetLoc( BPy_PartSys * self, PyObject * args ){ return EXPP_ReturnPyObjError( PyExc_RuntimeError, "Couldn't append item to PyList" ); } - + Py_DECREF(loc); /* PyList_Append increfs */ path++; } @@ -864,6 +864,7 @@ static PyObject *Part_GetLoc( BPy_PartSys * self, PyObject * args ){ return EXPP_ReturnPyObjError( PyExc_RuntimeError, "Couldn't append item to PyList" ); } + Py_DECREF(seglist); /* PyList_Append increfs */ } cache=psys->childcache; @@ -885,7 +886,7 @@ static PyObject *Part_GetLoc( BPy_PartSys * self, PyObject * args ){ return EXPP_ReturnPyObjError( PyExc_RuntimeError, "Couldn't append item to PyList" ); } - + Py_DECREF(loc);/* PyList_Append increfs */ path++; } @@ -895,6 +896,7 @@ static PyObject *Part_GetLoc( BPy_PartSys * self, PyObject * args ){ return EXPP_ReturnPyObjError( PyExc_RuntimeError, "Couldn't append item to PyList" ); } + Py_DECREF(seglist); /* PyList_Append increfs */ } } else { @@ -933,6 +935,7 @@ static PyObject *Part_GetLoc( BPy_PartSys * self, PyObject * args ){ return EXPP_ReturnPyObjError( PyExc_RuntimeError, "Couldn't append item to PyList" ); } + Py_DECREF(loc);/* PyList_Append increfs */ } else { if ( all ){ @@ -941,6 +944,7 @@ static PyObject *Part_GetLoc( BPy_PartSys * self, PyObject * args ){ return EXPP_ReturnPyObjError( PyExc_RuntimeError, "Couldn't append item to PyList" ); } + Py_DECREF(Py_None); /* PyList_Append increfs */ } } } @@ -985,6 +989,7 @@ static PyObject *Part_GetRot( BPy_PartSys * self, PyObject * args ){ if(psys_get_particle_state(ob,psys,i,&state,0)==0){ if ( all ){ PyList_Append(partlist,Py_None); + Py_DECREF(Py_None); /* PyList_Append increfs */ continue; } else { continue; @@ -1001,6 +1006,7 @@ static PyObject *Part_GetRot( BPy_PartSys * self, PyObject * args ){ if (id) PyTuple_SetItem(loc,4,PyInt_FromLong(i)); PyList_Append(partlist,loc); + Py_DECREF(loc); /* PyList_Append increfs */ } } return partlist; @@ -1060,9 +1066,11 @@ static PyObject *Part_GetSize( BPy_PartSys * self, PyObject * args ){ PyTuple_SetItem(tuple,0,PyFloat_FromDouble((double)size)); PyTuple_SetItem(tuple,1,PyInt_FromLong(i)); PyList_Append(partlist,tuple); + Py_DECREF(tuple); } else { siz = PyFloat_FromDouble((double)size); PyList_Append(partlist,siz); + Py_DECREF(siz); } } } @@ -1125,9 +1133,11 @@ static PyObject *Part_GetAge( BPy_PartSys * self, PyObject * args ){ PyTuple_SetItem(tuple,0,PyFloat_FromDouble((double)life)); PyTuple_SetItem(tuple,1,PyInt_FromLong(i)); PyList_Append(partlist,tuple); + Py_DECREF(tuple); } else { lif = PyFloat_FromDouble((double)life); PyList_Append(partlist,lif); + Py_DECREF(lif); } } } From cdd461f4889da5abcfb6e1cfa1e28c4d77970cb1 Mon Sep 17 00:00:00 2001 From: Ton Roosendaal Date: Sat, 7 Jun 2008 15:06:00 +0000 Subject: [PATCH 167/246] March 22 commit from Campbell to allow Lasso select in Compositor with CTRL+LMB disabled the recently before added option to make a Viewer connected to a node using same hotkey. Now both work! --- source/blender/src/editnode.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/source/blender/src/editnode.c b/source/blender/src/editnode.c index 9057556b796..4c7334c55e0 100644 --- a/source/blender/src/editnode.c +++ b/source/blender/src/editnode.c @@ -2382,14 +2382,14 @@ void winqreadnodespace(ScrArea *sa, void *spacedata, BWinEvent *evt) } else { - if(G.qual & LR_CTRLKEY) { - gesture(); - } else { - if(node_add_link(snode)==0) - if(node_mouse_groupheader(snode)==0) - if(node_mouse_select(snode, event)==0) - node_border_link_delete(snode); - } + if(G.qual & LR_CTRLKEY) + if(gesture()) + break; + + if(node_add_link(snode)==0) + if(node_mouse_groupheader(snode)==0) + if(node_mouse_select(snode, event)==0) + node_border_link_delete(snode); } break; From 12461cde17dcd3803e2578b1b72edd1ce0951698 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sat, 7 Jun 2008 18:16:23 +0000 Subject: [PATCH 168/246] error in customdata editmesh function, was using the active index when it should use the first index, not a big deal since CustomData_em_get_n isnt used in trunk yet. --- source/blender/blenkernel/intern/customdata.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/blenkernel/intern/customdata.c b/source/blender/blenkernel/intern/customdata.c index 3644a50b799..77068d8ed66 100644 --- a/source/blender/blenkernel/intern/customdata.c +++ b/source/blender/blenkernel/intern/customdata.c @@ -1278,7 +1278,7 @@ void *CustomData_em_get_n(const CustomData *data, void *block, int type, int n) int layer_index; /* get the layer index of the first layer of type */ - layer_index = CustomData_get_active_layer_index(data, type); + layer_index = CustomData_get_layer_index(data, type); if(layer_index < 0) return NULL; return (char *)block + data->layers[layer_index+n].offset; From a2192ffa0910b28054625bc062d85e44660491a1 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sat, 7 Jun 2008 22:44:18 +0000 Subject: [PATCH 169/246] made the quad split-direction options force splitting since planer quads with UV distortion would get very different results depending on the split direction. --- .../render/intern/source/convertblender.c | 83 ++++++++++++++----- 1 file changed, 64 insertions(+), 19 deletions(-) diff --git a/source/blender/render/intern/source/convertblender.c b/source/blender/render/intern/source/convertblender.c index afe4c47a9a4..89a0a5ba7cb 100644 --- a/source/blender/render/intern/source/convertblender.c +++ b/source/blender/render/intern/source/convertblender.c @@ -3935,7 +3935,58 @@ static void set_fullsample_flag(Render *re, ObjectRen *obr) } } -static void check_non_flat_quads(ObjectRen *obr, int quad_flip) +/* split quads for pradictable baking + * dir 1 == (0,1,2) (0,2,3), 2 == (1,3,0) (1,2,3) + */ +static void split_quads(ObjectRen *obr, int dir) +{ + VlakRen *vlr, *vlr1; + int a; + + for(a=obr->totvlak-1; a>=0; a--) { + vlr= RE_findOrAddVlak(obr, a); + + /* test if rendering as a quad or triangle, skip wire */ + if(vlr->v4 && (vlr->flag & R_STRAND)==0 && (vlr->mat->mode & MA_WIRE)==0) { + + if(vlr->v4) { + + vlr1= RE_vlakren_copy(obr, vlr); + vlr1->flag |= R_FACE_SPLIT; + + if( dir==2 ) vlr->flag |= R_DIVIDE_24; + else vlr->flag &= ~R_DIVIDE_24; + + /* new vertex pointers */ + if (vlr->flag & R_DIVIDE_24) { + vlr1->v1= vlr->v2; + vlr1->v2= vlr->v3; + vlr1->v3= vlr->v4; + + vlr->v3 = vlr->v4; + + vlr1->flag |= R_DIVIDE_24; + } + else { + vlr1->v1= vlr->v1; + vlr1->v2= vlr->v3; + vlr1->v3= vlr->v4; + + vlr1->flag &= ~R_DIVIDE_24; + } + vlr->v4 = vlr1->v4 = NULL; + + /* new normals */ + CalcNormFloat(vlr->v3->co, vlr->v2->co, vlr->v1->co, vlr->n); + CalcNormFloat(vlr1->v3->co, vlr1->v2->co, vlr1->v1->co, vlr1->n); + } + /* clear the flag when not divided */ + else vlr->flag &= ~R_DIVIDE_24; + } + } +} + +static void check_non_flat_quads(ObjectRen *obr) { VlakRen *vlr, *vlr1; VertRen *v1, *v2, *v3, *v4; @@ -4003,22 +4054,16 @@ static void check_non_flat_quads(ObjectRen *obr, int quad_flip) vlr1= RE_vlakren_copy(obr, vlr); vlr1->flag |= R_FACE_SPLIT; - if (quad_flip==0) { /* nonzero quad_flip is used to force dividing one way */ - /* split direction based on vnorms */ - CalcNormFloat(vlr->v1->co, vlr->v2->co, vlr->v3->co, nor); - d1= nor[0]*vlr->v1->n[0] + nor[1]*vlr->v1->n[1] + nor[2]*vlr->v1->n[2]; + /* split direction based on vnorms */ + CalcNormFloat(vlr->v1->co, vlr->v2->co, vlr->v3->co, nor); + d1= nor[0]*vlr->v1->n[0] + nor[1]*vlr->v1->n[1] + nor[2]*vlr->v1->n[2]; + + CalcNormFloat(vlr->v2->co, vlr->v3->co, vlr->v4->co, nor); + d2= nor[0]*vlr->v2->n[0] + nor[1]*vlr->v2->n[1] + nor[2]*vlr->v2->n[2]; + + if( fabs(d1) < fabs(d2) ) vlr->flag |= R_DIVIDE_24; + else vlr->flag &= ~R_DIVIDE_24; - CalcNormFloat(vlr->v2->co, vlr->v3->co, vlr->v4->co, nor); - d2= nor[0]*vlr->v2->n[0] + nor[1]*vlr->v2->n[1] + nor[2]*vlr->v2->n[2]; - - if( fabs(d1) < fabs(d2) ) vlr->flag |= R_DIVIDE_24; - else vlr->flag &= ~R_DIVIDE_24; - } else if (quad_flip==1) { - vlr->flag &= ~R_DIVIDE_24; - } else { /* quad_flip == 3 */ - vlr->flag |= R_DIVIDE_24; - } - /* new vertex pointers */ if (vlr->flag & R_DIVIDE_24) { vlr1->v1= vlr->v2; @@ -4072,11 +4117,11 @@ static void finalize_render_object(Render *re, ObjectRen *obr, int timeoffset) if((re->r.mode & R_RAYTRACE) && (re->r.mode & R_SHADOW)) set_phong_threshold(obr); - if (re->flag & R_BAKING) { + if (re->flag & R_BAKING && re->r.bake_quad_split != 0) { /* Baking lets us define a quad split order */ - check_non_flat_quads(obr, re->r.bake_quad_split); + split_quads(obr, re->r.bake_quad_split); } else { - check_non_flat_quads(obr, 0); + check_non_flat_quads(obr); } set_fullsample_flag(re, obr); From 96808303c0caea5e89aa85917a1e574e91fa7d7b Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Sun, 8 Jun 2008 02:59:14 +0000 Subject: [PATCH 170/246] Fix for incorrect tooltip (provided by JMS va bf-committers) --- source/blender/src/buttons_editing.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/src/buttons_editing.c b/source/blender/src/buttons_editing.c index 1365baf075a..6250b69345b 100644 --- a/source/blender/src/buttons_editing.c +++ b/source/blender/src/buttons_editing.c @@ -4369,7 +4369,7 @@ static void editing_panel_armature_bones(Object *ob, bArmature *arm) /* bone types */ uiDefButBitI(block, TOG, BONE_HINGE, B_ARM_RECALCDATA, "Hinge", -10,by-38,80,18, &curBone->flag, 1.0, 32.0, 0.0, 0.0, "Don't inherit rotation or scale from parent Bone"); - uiDefButBitI(block, TOG, BONE_NO_SCALE, B_ARM_RECALCDATA, "S", 70,by-38,20,18, &curBone->flag, 1.0, 32.0, 0.0, 0.0, "Don't inherit rotation or scale from parent Bone"); + uiDefButBitI(block, TOG, BONE_NO_SCALE, B_ARM_RECALCDATA, "S", 70,by-38,20,18, &curBone->flag, 1.0, 32.0, 0.0, 0.0, "Don't inherit scale from parent Bone"); uiDefButBitI(block, TOGN, BONE_NO_DEFORM, B_ARM_RECALCDATA, "Deform", 90, by-38, 80, 18, &curBone->flag, 0.0, 0.0, 0.0, 0.0, "Indicate if Bone deforms geometry"); uiDefButBitI(block, TOG, BONE_MULT_VG_ENV, B_ARM_RECALCDATA, "Mult", 170,by-38,80,18, &curBone->flag, 1.0, 32.0, 0.0, 0.0, "Multiply Bone Envelope with VertexGroup"); uiDefButBitI(block, TOG, BONE_HIDDEN_A, REDRAWVIEW3D, "Hide", 250,by-38,80,18, &curBone->flag, 0, 0, 0, 0, "Toggles display of this bone in Edit Mode"); From 7e095fa695247996a678504bcace0c1d5ab00db2 Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Sun, 8 Jun 2008 03:39:24 +0000 Subject: [PATCH 171/246] Another minor typo fix in button naming --- source/blender/src/buttons_object.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/src/buttons_object.c b/source/blender/src/buttons_object.c index fb36d103656..52261f7d3fb 100644 --- a/source/blender/src/buttons_object.c +++ b/source/blender/src/buttons_object.c @@ -4044,7 +4044,7 @@ static void object_softbodies(Object *ob) uiDefButS(block, NUM, B_BAKE_CACHE_CHANGE, "Aero:", 30,10,60,20, &sb->aeroedge, 0.00, 30000.0, 10, 0, "Make edges 'sail'"); uiDefButS(block, NUM, B_BAKE_CACHE_CHANGE, "Plas:", 90,10,60,20, &sb->plastic, 0.0, 100.0, 10, 0, "Permanent deform"); if(ob->type==OB_MESH) { - uiDefButF(block, NUM, B_BAKE_CACHE_CHANGE, "Be:", 150,10,80,20, &sb->secondspring, 0.0, 10.0, 10, 0, "Bendig Stiffness"); + uiDefButF(block, NUM, B_BAKE_CACHE_CHANGE, "Be:", 150,10,80,20, &sb->secondspring, 0.0, 10.0, 10, 0, "Bending Stiffness"); if (*softflag & OB_SB_QUADS){ uiDefButF(block, NUM, B_BAKE_CACHE_CHANGE, "Sh:", 230,10,80,20, &sb->shearstiff, 0.0, 1.0, 10, 0, "Shear Stiffness"); } From 08f9bcf8ece2ded4cc95a3c5b982c316e72da865 Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Sun, 8 Jun 2008 09:35:05 +0000 Subject: [PATCH 172/246] Bugfix #13649: Segmentation fault when deleting object When the IPO editor was pinned, and the active object was changed, deleting the active object would cause a crash. --- source/blender/src/drawipo.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/source/blender/src/drawipo.c b/source/blender/src/drawipo.c index 552e87a57d1..0e7476bbe82 100644 --- a/source/blender/src/drawipo.c +++ b/source/blender/src/drawipo.c @@ -1712,7 +1712,7 @@ static void boundbox_ipo_curves(SpaceIpo *si) /* is used for both read and write... */ static void ipo_editvertex_buts(uiBlock *block, SpaceIpo *si, float min, float max) { - Object *ob= OBACT; + Object *ob; EditIpo *ei; BezTriple *bezt; float median[3]; @@ -1721,6 +1721,12 @@ static void ipo_editvertex_buts(uiBlock *block, SpaceIpo *si, float min, float m median[0]= median[1]= median[2]= 0.0; tot= 0; + /* use G.sipo->from (which should be an object) so that pinning ipo's will still work ok */ + if((G.sipo->from) && (GS(G.sipo->from->name) == ID_OB)) + ob= (Object *)(G.sipo->from); + else + ob= OBACT; + ei= G.sipo->editipo; for(a=0; atotipo; a++, ei++) { From cee9c7a8faddb2b73b985e7d0911cc8a2aa679db Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Sun, 8 Jun 2008 10:46:30 +0000 Subject: [PATCH 173/246] Bugfix #13667: Outliner doesn't update when changing Parent in Transform Properties There was a missing refresh call for the Outliner. --- source/blender/src/drawview.c | 1 + 1 file changed, 1 insertion(+) diff --git a/source/blender/src/drawview.c b/source/blender/src/drawview.c index e83ecb13960..deb7ddc068d 100644 --- a/source/blender/src/drawview.c +++ b/source/blender/src/drawview.c @@ -2154,6 +2154,7 @@ void do_viewbuts(unsigned short event) } allqueue(REDRAWVIEW3D, 1); allqueue(REDRAWBUTSOBJECT, 0); + allqueue(REDRAWOOPS, 0); } break; From 71573cbd55a9088f4f3011da473ad6101fc2b531 Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Sun, 8 Jun 2008 10:48:37 +0000 Subject: [PATCH 174/246] Bugfix #13666: Missing #include in source/gameengine/Ketsji/KX_RayCast.cpp --- source/gameengine/Ketsji/KX_RayCast.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/source/gameengine/Ketsji/KX_RayCast.cpp b/source/gameengine/Ketsji/KX_RayCast.cpp index ce7ed984985..b88741625b6 100644 --- a/source/gameengine/Ketsji/KX_RayCast.cpp +++ b/source/gameengine/Ketsji/KX_RayCast.cpp @@ -29,6 +29,7 @@ */ #include +#include #include "KX_RayCast.h" From 57d83522a22fb90ea42bee1d80cb6e47710cad7b Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Mon, 9 Jun 2008 10:03:30 +0000 Subject: [PATCH 175/246] Fix for bug #13627: bFTGL sconscript missing opengl includes, didn't compile with non-standard paths. --- extern/bFTGL/SConscript | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extern/bFTGL/SConscript b/extern/bFTGL/SConscript index bd20db5a459..c03992631e6 100644 --- a/extern/bFTGL/SConscript +++ b/extern/bFTGL/SConscript @@ -22,7 +22,7 @@ Import('env') #ftgl_env.Append (CPPDEFINES = defines) -incs = 'include src ' + env['BF_FREETYPE_INC'] +incs = 'include src ' + env['BF_FREETYPE_INC'] + ' ' + env['BF_OPENGL_INC'] defs = '' sources = env.Glob('src/*.cpp') From 610b877f60083ef064058efc7011a5b35c5e96b7 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 9 Jun 2008 12:13:51 +0000 Subject: [PATCH 176/246] ctrl+LMB drag would add an ipo vert AND zoom in ipo view. checked revisions 7915 and 10663, it seems this functionality was accidental. --- source/blender/src/space.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/source/blender/src/space.c b/source/blender/src/space.c index 8cc7e6975b4..90a48565a8f 100644 --- a/source/blender/src/space.c +++ b/source/blender/src/space.c @@ -2974,8 +2974,11 @@ static void winqreadipospace(ScrArea *sa, void *spacedata, BWinEvent *evt) do_ipo_selectbuttons(); doredraw= 1; } + else if(G.qual == LR_CTRLKEY) { + if (sipo->showkey==0) + add_vert_ipo(); + } else if(view2dmove(LEFTMOUSE)); /* only checks for sliders */ - else if((G.qual & LR_CTRLKEY) && (sipo->showkey==0)) add_vert_ipo(); else { do { getmouseco_areawin(mval); From f39758cddca1d6eeec299e8cd3eef9a2a1852e32 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 9 Jun 2008 15:45:46 +0000 Subject: [PATCH 177/246] adding clip alpha (binary alpha) to the 3D view and game engine. --- source/blender/makesdna/DNA_meshdata_types.h | 4 +++- source/blender/src/buttons_editing.c | 1 + source/blender/src/drawmesh.c | 12 ++++++++---- .../GamePlayer/common/GPC_PolygonMaterial.cpp | 11 +++++++++-- source/gameengine/Ketsji/KX_BlenderMaterial.cpp | 9 ++++++++- 5 files changed, 29 insertions(+), 8 deletions(-) diff --git a/source/blender/makesdna/DNA_meshdata_types.h b/source/blender/makesdna/DNA_meshdata_types.h index 79c1710a897..a717df640f1 100644 --- a/source/blender/makesdna/DNA_meshdata_types.h +++ b/source/blender/makesdna/DNA_meshdata_types.h @@ -229,14 +229,16 @@ typedef struct PartialVisibility { #define TF_SHADOW 8192 #define TF_BMFONT 16384 -/* mtface->transp */ +/* mtface->transp, values 1-4 are used as flags in the GL, WARNING, TF_SUB cant work with this */ #define TF_SOLID 0 #define TF_ADD 1 #define TF_ALPHA 2 +#define TF_CLIP 4 /* clipmap alpha/binary alpha all or nothing! */ /* sub is not available in the user interface anymore */ #define TF_SUB 3 + /* mtface->unwrap */ #define TF_DEPRECATED1 1 #define TF_DEPRECATED2 2 diff --git a/source/blender/src/buttons_editing.c b/source/blender/src/buttons_editing.c index 6250b69345b..7e154d6c341 100644 --- a/source/blender/src/buttons_editing.c +++ b/source/blender/src/buttons_editing.c @@ -6235,6 +6235,7 @@ static void editing_panel_mesh_texface(void) uiDefButC(block, ROW, REDRAWVIEW3D, "Opaque", 600,80,60,19, &tf->transp, 2.0, (float)TF_SOLID,0, 0, "Render color of textured face as color"); uiDefButC(block, ROW, REDRAWVIEW3D, "Add", 660,80,60,19, &tf->transp, 2.0, (float)TF_ADD, 0, 0, "Render face transparent and add color of face"); uiDefButC(block, ROW, REDRAWVIEW3D, "Alpha", 720,80,60,19, &tf->transp, 2.0, (float)TF_ALPHA,0, 0, "Render polygon transparent, depending on alpha channel of the texture"); + uiDefButC(block, ROW, REDRAWVIEW3D, "Clip Alpha", 780,80,80,19, &tf->transp, 2.0, (float)TF_CLIP,0, 0, "Use the images alpha values clipped with no blending (binary alpha)"); } else uiDefBut(block,LABEL,B_NOP, "(No Active Face)", 10,200,150,19,0,0,0,0,0,""); diff --git a/source/blender/src/drawmesh.c b/source/blender/src/drawmesh.c index b72cd3f56f8..dd512595ebc 100644 --- a/source/blender/src/drawmesh.c +++ b/source/blender/src/drawmesh.c @@ -228,13 +228,14 @@ int set_tpage(MTFace *tface) alphamode= tface->transp; if(alphamode) { - glEnable(GL_BLEND); - if(alphamode==TF_ADD) { + glEnable(GL_BLEND); glBlendFunc(GL_ONE, GL_ONE); + glDisable ( GL_ALPHA_TEST ); /* glBlendEquationEXT(GL_FUNC_ADD_EXT); */ } else if(alphamode==TF_ALPHA) { + glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); /* added after 2.45 to clip alpha */ @@ -245,9 +246,12 @@ int set_tpage(MTFace *tface) glEnable ( GL_ALPHA_TEST ); glAlphaFunc ( GL_GREATER, U.glalphaclip ); } - - /* glBlendEquationEXT(GL_FUNC_ADD_EXT); */ + } else if (alphamode==TF_CLIP){ + glDisable(GL_BLEND); + glEnable ( GL_ALPHA_TEST ); + glAlphaFunc(GL_GREATER, 0.5f); } + /* glBlendEquationEXT(GL_FUNC_ADD_EXT); */ /* else { */ /* glBlendFunc(GL_ONE, GL_ONE); */ /* glBlendEquationEXT(GL_FUNC_REVERSE_SUBTRACT_EXT); */ diff --git a/source/gameengine/GamePlayer/common/GPC_PolygonMaterial.cpp b/source/gameengine/GamePlayer/common/GPC_PolygonMaterial.cpp index 46fe24d8b87..09dd14172c8 100644 --- a/source/gameengine/GamePlayer/common/GPC_PolygonMaterial.cpp +++ b/source/gameengine/GamePlayer/common/GPC_PolygonMaterial.cpp @@ -154,16 +154,23 @@ int set_tpage(MTFace *tface) fAlphamode= tface->transp; if(fAlphamode) { - glEnable(GL_BLEND); - if(fAlphamode==TF_ADD) { + glEnable(GL_BLEND); glBlendFunc(GL_ONE, GL_ONE); + glDisable ( GL_ALPHA_TEST ); /* glBlendEquationEXT(GL_FUNC_ADD_EXT); */ } else if(fAlphamode==TF_ALPHA) { + glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glDisable ( GL_ALPHA_TEST ); /* glBlendEquationEXT(GL_FUNC_ADD_EXT); */ } + else if (alphamode==TF_CLIP){ + glDisable(GL_BLEND); + glEnable ( GL_ALPHA_TEST ); + glAlphaFunc(GL_GREATER, 0.5f); + } /* else { */ /* glBlendFunc(GL_ONE, GL_ONE); */ /* glBlendEquationEXT(GL_FUNC_REVERSE_SUBTRACT_EXT); */ diff --git a/source/gameengine/Ketsji/KX_BlenderMaterial.cpp b/source/gameengine/Ketsji/KX_BlenderMaterial.cpp index 44727588106..5efe1ad26ca 100644 --- a/source/gameengine/Ketsji/KX_BlenderMaterial.cpp +++ b/source/gameengine/Ketsji/KX_BlenderMaterial.cpp @@ -478,16 +478,23 @@ bool KX_BlenderMaterial::setDefaultBlending() if( mMaterial->transp &TF_ADD) { glEnable(GL_BLEND); glBlendFunc(GL_ONE, GL_ONE); + glDisable ( GL_ALPHA_TEST ); return true; } if( mMaterial->transp & TF_ALPHA ) { glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glDisable ( GL_ALPHA_TEST ); return true; } - glDisable(GL_BLEND); + if( mMaterial->transp & TF_CLIP ) { + glDisable(GL_BLEND); + glEnable ( GL_ALPHA_TEST ); + glAlphaFunc(GL_GREATER, 0.5f); + return true; + } return false; } From 4e2bb896b0cb0adad94158fd53a0de505b9df642 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Mon, 9 Jun 2008 16:49:33 +0000 Subject: [PATCH 178/246] Added back a feature from the old particle system: negative start frame. At the moment this does mean it will compute all the frames before the point caching start frame on the first frame, which might be slow. --- .../blender/blenkernel/intern/particle_system.c | 17 ++++++++++++++--- source/blender/src/buttons_object.c | 2 +- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c index 5112fb08fe6..f06ef221795 100644 --- a/source/blender/blenkernel/intern/particle_system.c +++ b/source/blender/blenkernel/intern/particle_system.c @@ -4814,9 +4814,20 @@ static void system_step(Object *ob, ParticleSystem *psys, ParticleSystemModifier pa->flag &= ~PARS_NO_DISP; } - /* ok now we're all set so let's go */ - if(psys->totpart) - dynamics_step(ob,psys,psmd,cfra,vg_vel,vg_tan,vg_rot,vg_size); + if(psys->totpart) { + int dframe, totframesback = 0; + + /* handle negative frame start at the first frame by doing + * all the steps before the first frame */ + if(framenr == startframe && part->sta < startframe) + totframesback = (startframe - (int)part->sta); + + for(dframe=-totframesback; dframe<=0; dframe++) { + /* ok now we're all set so let's go */ + dynamics_step(ob,psys,psmd,cfra+dframe,vg_vel,vg_tan,vg_rot,vg_size); + psys->cfra = cfra+dframe; + } + } cache->simframe= framenr; cache->flag |= PTCACHE_SIMULATION_VALID; diff --git a/source/blender/src/buttons_object.c b/source/blender/src/buttons_object.c index 52261f7d3fb..ba409723784 100644 --- a/source/blender/src/buttons_object.c +++ b/source/blender/src/buttons_object.c @@ -4832,7 +4832,7 @@ static void object_panel_particle_system(Object *ob) uiDefButS(block, NUM, B_PART_RECALC, "Segments:", butx,(buty-=buth),butw,buth, &part->hair_step, 2.0, 50.0, 0, 0, "Amount of hair segments"); } else { - uiDefButF(block, NUM, B_PART_INIT, "Sta:", butx,(buty-=buth),butw,buth, &part->sta, 1.0, part->end, 100, 1, "Frame # to start emitting particles"); + uiDefButF(block, NUM, B_PART_INIT, "Sta:", butx,(buty-=buth),butw,buth, &part->sta, -MAXFRAMEF, part->end, 100, 1, "Frame # to start emitting particles"); uiDefButF(block, NUM, B_PART_INIT, "End:", butx,(buty-=buth),butw,buth, &part->end, part->sta, MAXFRAMEF, 100, 1, "Frame # to stop emitting particles"); } From 83af2c1757d7ce76842dd13d92395d4bf5f0c410 Mon Sep 17 00:00:00 2001 From: Martin Poirier Date: Mon, 9 Jun 2008 16:54:54 +0000 Subject: [PATCH 179/246] PATCH: [#13656] Bad rotation computing for manual rotation higher than 180 degrees By Fabrice Tiercelin This enables rotation angles of more than 180 degrees to result in the same rotation applied to the object (the result used to be clamps between -180 - 180 of the initial rotation). The patch had to be modified to deal with IPO keys properly --- source/blender/src/transform.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/source/blender/src/transform.c b/source/blender/src/transform.c index 4f6c33b0a64..64d244dc1a0 100644 --- a/source/blender/src/transform.c +++ b/source/blender/src/transform.c @@ -2530,15 +2530,22 @@ static void ElementRotation(TransInfo *t, TransData *td, float mat[3][3]) { /* are there ipo keys? */ if(td->tdi) { TransDataIpokey *tdi= td->tdi; + float current_rot[3]; float rot[3]; + /* current IPO value for compatible euler */ + current_rot[0] = tdi->rotx[0]; + current_rot[1] = tdi->roty[0]; + current_rot[2] = tdi->rotz[0]; + VecMulf(current_rot, (float)(M_PI_2 / 9.0)); + /* calculate the total rotatation in eulers */ VecAddf(eul, td->ext->irot, td->ext->drot); EulToMat3(eul, obmat); /* mat = transform, obmat = object rotation */ Mat3MulMat3(fmat, mat, obmat); - Mat3ToCompatibleEul(fmat, eul, td->ext->irot); + Mat3ToCompatibleEul(fmat, eul, current_rot); /* correct back for delta rot */ if(tdi->flag & TOB_IPODROT) { @@ -2567,7 +2574,7 @@ static void ElementRotation(TransInfo *t, TransData *td, float mat[3][3]) { /* mat = transform, obmat = object rotation */ Mat3MulMat3(fmat, smat, obmat); - Mat3ToCompatibleEul(fmat, eul, td->ext->irot); + Mat3ToCompatibleEul(fmat, eul, td->ext->rot); /* correct back for delta rot */ VecSubf(eul, eul, td->ext->drot); From ac0a91920af0c9de9f6dfbbf493ecb9e2509c15e Mon Sep 17 00:00:00 2001 From: Martin Poirier Date: Mon, 9 Jun 2008 17:16:20 +0000 Subject: [PATCH 180/246] Revision 14894 merged from apricot ---------------------------------- Arith: - axis angle to quat conversion function - short to float / float to short normals conversion function (eventually, we could go over the go and replace copy/pasted code everywhere) - ray triangle intersection (to complement the line triangle intersection function) View: - viewray / viewline (get near plane point under mouse and ray normal/far point) Particles: - extract viewline from brush_add function --- source/blender/blenlib/BLI_arithb.h | 4 ++ source/blender/blenlib/intern/arithb.c | 67 ++++++++++++++++++++++++++ source/blender/include/BSE_view.h | 2 + source/blender/src/editparticle.c | 36 ++------------ source/blender/src/view.c | 42 ++++++++++++++++ 5 files changed, 120 insertions(+), 31 deletions(-) diff --git a/source/blender/blenlib/BLI_arithb.h b/source/blender/blenlib/BLI_arithb.h index 9ed23bc32b6..4d277cf98e1 100644 --- a/source/blender/blenlib/BLI_arithb.h +++ b/source/blender/blenlib/BLI_arithb.h @@ -258,6 +258,7 @@ void Vec2Addf(float *v, float *v1, float *v2); void Vec2Subf(float *v, float *v1, float *v2); void Vec2Copyf(float *v1, float *v2); +void AxisAngleToQuat(float *q, float *axis, float angle); void vectoquat(float *vec, short axis, short upflag, float *q); float VecAngle2(float *v1, float *v2); @@ -269,6 +270,8 @@ float NormalizedVecAngle2_2D(float *v1, float *v2); void euler_rot(float *beul, float ang, char axis); +void NormalShortToFloat(float *out, short *in); +void NormalFloatToShort(short *out, float *in); float DistVL2Dfl(float *v1, float *v2, float *v3); float PdistVL2Dfl(float *v1, float *v2, float *v3); @@ -372,6 +375,7 @@ void tubemap(float x, float y, float z, float *u, float *v); void spheremap(float x, float y, float z, float *u, float *v); int LineIntersectsTriangle(float p1[3], float p2[3], float v0[3], float v1[3], float v2[3], float *lambda, float *uv); +int RayIntersectsTriangle(float p1[3], float d[3], float v0[3], float v1[3], float v2[3], float *lambda, float *uv); int SweepingSphereIntersectsTriangleUV(float p1[3], float p2[3], float radius, float v0[3], float v1[3], float v2[3], float *lambda, float *ipoint); int AxialLineIntersectsTriangle(int axis, float co1[3], float co2[3], float v0[3], float v1[3], float v2[3], float *lambda); int AabbIntersectAabb(float min1[3], float max1[3], float min2[3], float max2[3]); diff --git a/source/blender/blenlib/intern/arithb.c b/source/blender/blenlib/intern/arithb.c index 48a149f4b3a..322a9e6fd02 100644 --- a/source/blender/blenlib/intern/arithb.c +++ b/source/blender/blenlib/intern/arithb.c @@ -1335,6 +1335,22 @@ void NormalQuat(float *q) } } +void AxisAngleToQuat(float *q, float *axis, float angle) +{ + float nor[3]; + float si; + + VecCopyf(nor, axis); + Normalize(nor); + + angle /= 2; + si = (float)sin(angle); + q[0] = (float)cos(angle); + q[1] = nor[0] * si; + q[2] = nor[1] * si; + q[3] = nor[2] * si; +} + void vectoquat(float *vec, short axis, short upflag, float *q) { float q2[4], nor[3], *fp, mat[3][3], angle, si, co, x2, y2, z2, len1; @@ -2258,6 +2274,20 @@ double Sqrt3d(double d) else return exp(log(d)/3); } +void NormalShortToFloat(float *out, short *in) +{ + out[0] = in[0] / 32767.0; + out[1] = in[1] / 32767.0; + out[2] = in[2] / 32767.0; +} + +void NormalFloatToShort(short *out, float *in) +{ + out[0] = (short)(in[0] * 32767.0); + out[1] = (short)(in[1] * 32767.0); + out[2] = (short)(in[2] * 32767.0); +} + /* distance v1 to line v2-v3 */ /* using Hesse formula, NO LINE PIECE! */ float DistVL2Dfl( float *v1, float *v2, float *v3) { @@ -3671,6 +3701,43 @@ int LineIntersectsTriangle(float p1[3], float p2[3], float v0[3], float v1[3], f return 1; } +/* moved from effect.c + test if the ray starting at p1 going in d direction intersects the triangle v0..v2 + return non zero if it does +*/ +int RayIntersectsTriangle(float p1[3], float d[3], float v0[3], float v1[3], float v2[3], float *lambda, float *uv) +{ + float p[3], s[3], e1[3], e2[3], q[3]; + float a, f, u, v; + + VecSubf(e1, v1, v0); + VecSubf(e2, v2, v0); + + Crossf(p, d, e2); + a = Inpf(e1, p); + if ((a > -0.000001) && (a < 0.000001)) return 0; + f = 1.0f/a; + + VecSubf(s, p1, v0); + + Crossf(q, s, e1); + *lambda = f * Inpf(e2, q); + if ((*lambda < 0.0)) return 0; + + u = f * Inpf(s, p); + if ((u < 0.0)||(u > 1.0)) return 0; + + v = f * Inpf(d, q); + if ((v < 0.0)||((u + v) > 1.0)) return 0; + + if(uv) { + uv[0]= u; + uv[1]= v; + } + + return 1; +} + /* Adapted from the paper by Kasper Fauerby */ /* "Improved Collision detection and Response" */ int SweepingSphereIntersectsTriangleUV(float p1[3], float p2[3], float radius, float v0[3], float v1[3], float v2[3], float *lambda, float *ipoint) diff --git a/source/blender/include/BSE_view.h b/source/blender/include/BSE_view.h index 4b334fdd959..f7afce958f5 100644 --- a/source/blender/include/BSE_view.h +++ b/source/blender/include/BSE_view.h @@ -66,6 +66,8 @@ void project_int(float *vec, int *adr); void project_int_noclip(float *vec, int *adr); void project_float(float *vec, float *adr); void project_float_noclip(float *vec, float *adr); +void viewray(short mval[2], float ray_start[3], float ray_normal[3]); +void viewline(short mval[2], float ray_start[3], float ray_end[3]); int boundbox_clip(float obmat[][4], struct BoundBox *bb); void fdrawline(float x1, float y1, float x2, float y2); diff --git a/source/blender/src/editparticle.c b/source/blender/src/editparticle.c index 95a4abe1f9d..f420d46c827 100644 --- a/source/blender/src/editparticle.c +++ b/source/blender/src/editparticle.c @@ -2273,9 +2273,9 @@ static void brush_add(Object *ob, ParticleSystem *psys, short *mval, short numbe ParticleEditSettings *pset= PE_settings(); ParticleEdit *edit = psys->edit; int i, k, n = 0, totpart = psys->totpart; + short mco[2]; short dmx = 0, dmy = 0; - short mx = mval[0] - curarea->winx / 2, my = mval[1] - curarea->winy / 2; - float co1[3], co2[3], vec[4], min_d, imat[4][4]; + float co1[3], co2[3], min_d, imat[4][4]; float framestep, timestep = psys_get_timestep(psys->part); short size = pset->brush[PE_BRUSH_ADD].size; short size2 = size*size; @@ -2302,35 +2302,9 @@ static void brush_add(Object *ob, ParticleSystem *psys, short *mval, short numbe } } - /* create intersection coordinates in view Z direction at mouse coordinates */ - /* Thanks to who ever wrote the "Mouse Location 3D Space" tutorial in "Blender 3D: Blending Into Python/Cookbook". */ - if(G.vd->persp != V3D_ORTHO){ - vec[0]= (2.0f*(mx+dmx)/curarea->winx); - vec[1]= (2.0f*(my+dmy)/curarea->winy); - vec[2]= -1.0f; - vec[3]= 1.0f; - - Mat4MulVec4fl(G.vd->persinv, vec); - VecMulf(vec, 1.0f/vec[3]); - - VECCOPY(co1, G.vd->viewinv[3]); - VECSUB(vec, vec, co1); - Normalize(vec); - - VECADDFAC(co1, G.vd->viewinv[3], vec, G.vd->near); - VECADDFAC(co2, G.vd->viewinv[3], vec, G.vd->far); - } - else { - vec[0] = 2.0f*(mx+dmx)/curarea->winx; - vec[1] = 2.0f*(my+dmy)/curarea->winy; - vec[2] = 0.0f; - vec[3] = 1.0f; - - Mat4MulVec4fl(G.vd->persinv,vec); - - VECADDFAC(co1,vec,G.vd->viewinv[2],1000.0f); - VECADDFAC(co2,vec,G.vd->viewinv[2],-1000.0f); - } + mco[0] = mval[0] + dmx; + mco[1] = mval[1] + dmy; + viewline(mco, co1, co2); Mat4MulVecfl(imat,co1); Mat4MulVecfl(imat,co2); diff --git a/source/blender/src/view.c b/source/blender/src/view.c index f53bcb3a9f7..835aeb9bb30 100644 --- a/source/blender/src/view.c +++ b/source/blender/src/view.c @@ -144,6 +144,48 @@ void persp(int a) } } +/* create intersection ray in view Z direction at mouse coordinates */ +void viewray(short mval[2], float ray_start[3], float ray_normal[3]) +{ + float ray_end[3]; + viewline(mval, ray_start, ray_end); + VecSubf(ray_normal, ray_end, ray_start); + Normalize(ray_normal); +} + +/* create intersection coordinates in view Z direction at mouse coordinates */ +void viewline(short mval[2], float ray_start[3], float ray_end[3]) +{ + float vec[3]; + + if(G.vd->persp != V3D_ORTHO){ + vec[0]= 2.0f * mval[0] / curarea->winx - 1; + vec[1]= 2.0f * mval[1] / curarea->winy - 1; + vec[2]= -1.0f; + vec[3]= 1.0f; + + Mat4MulVec4fl(G.vd->persinv, vec); + VecMulf(vec, 1.0f / vec[3]); + + VECCOPY(ray_start, G.vd->viewinv[3]); + VECSUB(vec, vec, ray_start); + Normalize(vec); + + VECADDFAC(ray_start, G.vd->viewinv[3], vec, G.vd->near); + VECADDFAC(ray_end, G.vd->viewinv[3], vec, G.vd->far); + } + else { + vec[0] = 2.0f * mval[0] / curarea->winx - 1; + vec[1] = 2.0f * mval[1] / curarea->winy - 1; + vec[2] = 0.0f; + vec[3] = 1.0f; + + Mat4MulVec4fl(G.vd->persinv, vec); + + VECADDFAC(ray_start, vec, G.vd->viewinv[2], 1000.0f); + VECADDFAC(ray_end, vec, G.vd->viewinv[2], -1000.0f); + } +} void initgrabz(float x, float y, float z) { From ccc78eebdee6b019e485d94f8524daf0567d50a0 Mon Sep 17 00:00:00 2001 From: Martin Poirier Date: Mon, 9 Jun 2008 17:22:38 +0000 Subject: [PATCH 181/246] Revision 15045 merged from apricot ---------------------------------- Small fix to derivedmesh for snapping: don't create origindex for editmesh derivedmesh since it's not being filled correct anyway. --- source/blender/blenkernel/intern/DerivedMesh.c | 4 ---- source/blender/blenkernel/intern/cdderivedmesh.c | 9 +++++++++ 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c index 654cf0991cc..30405660658 100644 --- a/source/blender/blenkernel/intern/DerivedMesh.c +++ b/source/blender/blenkernel/intern/DerivedMesh.c @@ -186,10 +186,6 @@ void DM_init_funcs(DerivedMesh *dm) void DM_init(DerivedMesh *dm, int numVerts, int numEdges, int numFaces) { - CustomData_add_layer(&dm->vertData, CD_ORIGINDEX, CD_CALLOC, NULL, numVerts); - CustomData_add_layer(&dm->edgeData, CD_ORIGINDEX, CD_CALLOC, NULL, numEdges); - CustomData_add_layer(&dm->faceData, CD_ORIGINDEX, CD_CALLOC, NULL, numFaces); - dm->numVertData = numVerts; dm->numEdgeData = numEdges; dm->numFaceData = numFaces; diff --git a/source/blender/blenkernel/intern/cdderivedmesh.c b/source/blender/blenkernel/intern/cdderivedmesh.c index c2946bb666f..472df3d0f26 100644 --- a/source/blender/blenkernel/intern/cdderivedmesh.c +++ b/source/blender/blenkernel/intern/cdderivedmesh.c @@ -732,6 +732,10 @@ DerivedMesh *CDDM_new(int numVerts, int numEdges, int numFaces) DM_init(dm, numVerts, numEdges, numFaces); + CustomData_add_layer(&dm->vertData, CD_ORIGINDEX, CD_CALLOC, NULL, numVerts); + CustomData_add_layer(&dm->edgeData, CD_ORIGINDEX, CD_CALLOC, NULL, numEdges); + CustomData_add_layer(&dm->faceData, CD_ORIGINDEX, CD_CALLOC, NULL, numFaces); + CustomData_add_layer(&dm->vertData, CD_MVERT, CD_CALLOC, NULL, numVerts); CustomData_add_layer(&dm->edgeData, CD_MEDGE, CD_CALLOC, NULL, numEdges); CustomData_add_layer(&dm->faceData, CD_MFACE, CD_CALLOC, NULL, numFaces); @@ -753,6 +757,11 @@ DerivedMesh *CDDM_from_mesh(Mesh *mesh, Object *ob) * with an exception for fluidsim */ DM_init(dm, mesh->totvert, mesh->totedge, mesh->totface); + + CustomData_add_layer(&dm->vertData, CD_ORIGINDEX, CD_CALLOC, NULL, mesh->totvert); + CustomData_add_layer(&dm->edgeData, CD_ORIGINDEX, CD_CALLOC, NULL, mesh->totedge); + CustomData_add_layer(&dm->faceData, CD_ORIGINDEX, CD_CALLOC, NULL, mesh->totface); + dm->deformedOnly = 1; if(ob && ob->fluidsimSettings && ob->fluidsimSettings->meshSurface) From d5c80a3a1b05a184ab9dbf9e8b7be31f00c3461c Mon Sep 17 00:00:00 2001 From: Martin Poirier Date: Mon, 9 Jun 2008 17:50:21 +0000 Subject: [PATCH 182/246] Revision 14929 partial merged from apricot (partial because I'll merge all snap code in one fell swoop after the libs are done) ---------------------------------- object: ray - boundbox intersection test --- source/blender/blenkernel/BKE_object.h | 1 + source/blender/blenkernel/intern/object.c | 28 +++++++++++++++++++++++ 2 files changed, 29 insertions(+) diff --git a/source/blender/blenkernel/BKE_object.h b/source/blender/blenkernel/BKE_object.h index a940ac62876..116a59fa97e 100644 --- a/source/blender/blenkernel/BKE_object.h +++ b/source/blender/blenkernel/BKE_object.h @@ -108,6 +108,7 @@ void object_boundbox_flag(struct Object *ob, int flag, int set); void minmax_object(struct Object *ob, float *min, float *max); void minmax_object_duplis(struct Object *ob, float *min, float *max); void solve_tracking (struct Object *ob, float targetmat[][4]); +int ray_hit_boundbox(struct BoundBox *bb, float ray_start[3], float ray_normal[3]); void object_handle_update(struct Object *ob); diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index 4f901ba7216..125243bc56f 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -2380,3 +2380,31 @@ int give_obdata_texspace(Object *ob, int **texflag, float **loc, float **size, f } return 1; } + +/* + * Test a bounding box for ray intersection + * assumes the ray is already local to the boundbox space + */ +int ray_hit_boundbox(struct BoundBox *bb, float ray_start[3], float ray_normal[3]) +{ + static int triangle_indexes[12][3] = {{0, 1, 2}, {0, 2, 3}, + {3, 2, 6}, {3, 6, 7}, + {1, 2, 6}, {1, 6, 5}, + {5, 6, 7}, {4, 5, 7}, + {0, 3, 7}, {0, 4, 7}, + {0, 1, 5}, {0, 4, 5}}; + int result = 0; + int i; + + for (i = 0; i < 12 && result == 0; i++) + { + float lambda; + int v1, v2, v3; + v1 = triangle_indexes[i][0]; + v2 = triangle_indexes[i][1]; + v3 = triangle_indexes[i][2]; + result = RayIntersectsTriangle(ray_start, ray_normal, bb->vec[v1], bb->vec[v2], bb->vec[v3], &lambda, NULL); + } + + return result; +} From 8c68895741c75960e879ffde7231c10ee5e0373c Mon Sep 17 00:00:00 2001 From: Martin Poirier Date: Mon, 9 Jun 2008 18:07:12 +0000 Subject: [PATCH 183/246] Revision 14869 merged from apricot ---------------------------------- Centralize handling of individual center for rotations --- source/blender/src/transform.c | 71 ++++++++++------------------------ 1 file changed, 21 insertions(+), 50 deletions(-) diff --git a/source/blender/src/transform.c b/source/blender/src/transform.c index 64d244dc1a0..553b0993e5b 100644 --- a/source/blender/src/transform.c +++ b/source/blender/src/transform.c @@ -2415,15 +2415,28 @@ void initRotation(TransInfo *t) static void ElementRotation(TransInfo *t, TransData *td, float mat[3][3]) { float vec[3], totmat[3][3], smat[3][3]; float eul[3], fmat[3][3], quat[4]; - + float *center = t->center; + + /* local constraint shouldn't alter center */ + if (t->around == V3D_LOCAL) { + if (t->flag & (T_OBJECT|T_POSE)) { + center = td->center; + } + else { + if(G.vd->around==V3D_LOCAL && (G.scene->selectmode & SCE_SELECT_FACE)) { + center = td->center; + } + } + } + if (t->flag & T_POINTS) { Mat3MulMat3(totmat, mat, td->mtx); Mat3MulMat3(smat, td->smtx, totmat); - VecSubf(vec, td->iloc, t->center); + VecSubf(vec, td->iloc, center); Mat3MulVecfl(smat, vec); - VecAddf(td->loc, vec, t->center); + VecAddf(td->loc, vec, center); VecSubf(vec,td->loc,td->iloc); protectedTransBits(td->protectflag, vec); @@ -2460,13 +2473,13 @@ static void ElementRotation(TransInfo *t, TransData *td, float mat[3][3]) { Mat3CpyMat4(pmtx, t->poseobj->obmat); Mat3Inv(imtx, pmtx); - VecSubf(vec, td->center, t->center); + VecSubf(vec, td->center, center); Mat3MulVecfl(pmtx, vec); // To Global space Mat3MulVecfl(mat, vec); // Applying rotation Mat3MulVecfl(imtx, vec); // To Local space - VecAddf(vec, vec, t->center); + VecAddf(vec, vec, center); /* vec now is the location where the object has to be */ VecSubf(vec, vec, td->center); // Translation needed from the initial location @@ -2495,9 +2508,9 @@ static void ElementRotation(TransInfo *t, TransData *td, float mat[3][3]) { } else { /* translation */ - VecSubf(vec, td->center, t->center); + VecSubf(vec, td->center, center); Mat3MulVecfl(mat, vec); - VecAddf(vec, vec, t->center); + VecAddf(vec, vec, center); /* vec now is the location where the object has to be */ VecSubf(vec, vec, td->center); Mat3MulVecfl(td->smtx, vec); @@ -2593,17 +2606,9 @@ static void ElementRotation(TransInfo *t, TransData *td, float mat[3][3]) { static void applyRotation(TransInfo *t, float angle, float axis[3]) { TransData *td = t->data; - float mat[3][3], center[3]; + float mat[3][3]; int i; - /* saving original center */ - if (t->around == V3D_LOCAL) { - VECCOPY(center, t->center); - } - else { - center[0] = center[1] = center[2] = 0.0f; - } - VecRotToMat3(axis, angle, mat); for(i = 0 ; i < t->total; i++, td++) { @@ -2614,18 +2619,6 @@ static void applyRotation(TransInfo *t, float angle, float axis[3]) if (td->flag & TD_SKIP) continue; - /* local constraint shouldn't alter center */ - if (t->around == V3D_LOCAL) { - if (t->flag & (T_OBJECT|T_POSE)) { - VECCOPY(t->center, td->center); - } - else { - if(G.vd->around==V3D_LOCAL && (G.scene->selectmode & SCE_SELECT_FACE)) { - VECCOPY(t->center, td->center); - } - } - } - if (t->con.applyRot) { t->con.applyRot(t, td, axis); VecRotToMat3(axis, angle * td->factor, mat); @@ -2636,11 +2629,6 @@ static void applyRotation(TransInfo *t, float angle, float axis[3]) ElementRotation(t, td, mat); } - - /* restoring original center */ - if (t->around == V3D_LOCAL) { - VECCOPY(t->center, center); - } } int Rotation(TransInfo *t, short mval[2]) @@ -2737,7 +2725,6 @@ static void applyTrackball(TransInfo *t, float axis1[3], float axis2[3], float a { TransData *td = t->data; float mat[3][3], smat[3][3], totmat[3][3]; - float center[3]; int i; VecRotToMat3(axis1, angles[0], smat); @@ -2752,20 +2739,6 @@ static void applyTrackball(TransInfo *t, float axis1[3], float axis2[3], float a if (td->flag & TD_SKIP) continue; - VECCOPY(center, t->center); - - if (t->around == V3D_LOCAL) { - /* local-mode shouldn't change center */ - if (t->flag & (T_OBJECT|T_POSE)) { - VECCOPY(t->center, td->center); - } - else { - if(G.vd->around==V3D_LOCAL && (G.scene->selectmode & SCE_SELECT_FACE)) { - VECCOPY(t->center, td->center); - } - } - } - if (t->flag & T_PROP_EDIT) { VecRotToMat3(axis1, td->factor * angles[0], smat); VecRotToMat3(axis2, td->factor * angles[1], totmat); @@ -2774,8 +2747,6 @@ static void applyTrackball(TransInfo *t, float axis1[3], float axis2[3], float a } ElementRotation(t, td, mat); - - VECCOPY(t->center, center); } } From fd1faa55425db3097e7bc6ae533dcca564a677cb Mon Sep 17 00:00:00 2001 From: Martin Poirier Date: Mon, 9 Jun 2008 18:41:16 +0000 Subject: [PATCH 184/246] Merge from Apricot Revisions 14897, 14913, 14914, 14915, 14929, 15009, 15046 --------------------------------------------------- Snappy stuff * Align rotation with snapping target: rotate the object, aligning it with the target (object mode only - temporarily) (New icon in the header when snap is turned on) * Snap to different mesh elements (face, edge, vertice): snapping target slide on faces and edge or use exact position of vertice. When using Align rotation with edge snapping, the normal is interpolated as you slide along. Snaps correctly to derived mesh (sculpt, modifiers, ...) and duplis. In object and edit mode. NOTE: The snapping code is now based on faces, so even if you're snapping to vertices or edges, it will not work on meshes without faces. This might change if needed. --- release/datafiles/blenderbuttons | Bin 69070 -> 69599 bytes source/blender/include/BIF_resources.h | 2 +- source/blender/include/transform.h | 5 + source/blender/makesdna/DNA_scene_types.h | 9 +- source/blender/src/blenderbuttons.c | 4338 +++++++++++---------- source/blender/src/header_view3d.c | 16 + source/blender/src/transform.c | 43 +- source/blender/src/transform_generics.c | 1 - source/blender/src/transform_snap.c | 516 ++- 9 files changed, 2633 insertions(+), 2297 deletions(-) diff --git a/release/datafiles/blenderbuttons b/release/datafiles/blenderbuttons index ebd0ec82ebda124f306c90764fe75abfb055b279..a4834091692c0cc61b50ad4c1604350d12622b2e 100644 GIT binary patch literal 69599 zcmZ^~by!qg*f+X|mhMjJMv?AD8brE5X@-=BLApUwX_0Q}F6nNiyStmSpZELTbDe+A zzzpn}xi;)s>%P~oR=Apq90n>WDgXc&@8zX6000jB6#}3jfj@fUMlJt4a?y~J1jXX6-Sj5BERZ<(Z!hyMW1YFfev#l!0Wyzo2pjShz zHuJ@Me}C%Qyt46dL8O?DTO?4#L&TAYvo{I(HFX0>tM@PA9?6$Np;yC_Re(4 z+sW5}e-EhA1=0`!>SGkx|9RD+ffo3mxBd69062DI z@Gbt&1JeKdhO-o4<=SMq#q-a{pS8Ag%e=`QBRku+h^|NTwf;KyzpJaQ4GhSgcKWhX zP8J(oIEdN`3z-@&x<_ubw_WCeTOlcyBwjDr+wW1Xo37>h^_W4}>!Sj5=N{LG|KwFw zq5LWe3ipb_Ln7W|HS^eXDlyNBDJ0=9Dq(J|I1u>#Dx$mjdOc6#av+hawL#9Z{FYoDp{h+^BYZ3R2F5# zz;E6iV;yNepo2XFvs4Qzs#}5p&@nR7($M7eT$ZWosL~F-&bWWNHQu1;Cwldm)e0E) zsxaYCb8HD!FOIh0_G9?Di2K+S8Jf2vU-h8R|t+($mSa;^N|#;`g<@Ya#w2 z53P6}JJCd8DIF=hJ(9&0GjFf-=x;h1OI`@8Hx5aG|1P-t8Cs&IPxj5do;^UD&v<&J zuzP_SI>7z*?P^`fkrYEhJb1-=nwmjBf4)9ksITbu!kukN9|&TwVGKDVGwd6@nCa*Ylf=ki%eCQ_rraT|g<7YYmGBj{J?EnVH$4 zGdLy;@3`mZ9Fc&U4v+V5G4HcNs9?l0QQceh%#)Loo7UFW6hB*k=U0i$!^FCu z>iBrebQLKvB3IkvF8Mis`4e|D(nx>M?hD7UF>7+=*>f=B7Pvih5S$2ccY;9!@O(;+ z3n6jw@iZ&fCwy_|%Nm|$X0NRkA=Rj2fTneEfVjz7r+YS=rucnD47~;W$1pL$=sMXB zcr0NU_#p*_hPpRcGNzoO#Sq(WLKb-@ofgSKkN2rh9bn|>Hf-|quO-AIlIv) zR>NAlWX=%Va&4)zKF(`xgm=r*JIuk`xkip|Rb>V0O~c682j3wAwAiW4!SzQ*N0&Jz z$_-hQNF^C@dG5Pb!O2#MckHmbnaMIuI}1~(&QiZ2z1!luGRu@N;NDZ#C`x?C_xTTD zZEfvKZQIz`SjG9}rNy)jkEQoWe>|<2>$~Vgjpi;D6y5Pz%fb4cr<=VgwzXvS@3R*ae?b=;AiyqIVYxT6E4A9x#};8@vnX7o zx~2N{$1$FeQD`A#_3OX7yyPVl;zd$T8_Fs>9m^CU>kh$i2`^}Ef>%I|%vrvp@({Ut)AhQE=AGKt zu8iQ%XEzsb+#x6)m`=5!r|{xgk=jlhNA%{iEq+}zyEGzhO=z52y|W7{*O zDyH22cs|6t<*A|)!wK6%#-e=0>T~iU!`Zy>5LN|VqN1ah%wrkbxw1HMB6{Eg`V-dh zs0Q&o9fc{gXwmt*_|z#?$2P)LM!2nogW!*VPZY(!1-2P0hmu=kOO4X{9cf+B+{#2J|N4{d;1HLmPR$gY zJZjJ%T4a2+XxelRV}h<~1$R;r9gqKqe}R4;Z?fx=;NvXRbbcF;`q z@r9|z0s(-HW{0X2xO`t=nV%IsUtKlPhZ4r{GAN6zB}<0Kyz@fJT|T@!zyNzzWc!3w zkX~7cLeag{#UDGaynjfWrT%~G*hfCmf>m7BHO7Vh$Lx)8tMGi{Hn{GNCmUV2HAByY zP^8)Z2JJuqqeg9~w(NPkN_t_ejbQhHVw-|VZuesYn|T3uz+m2SjxhZ61>)j6 zu)qPZ8eBcr=h?$EseQsBwc(JaPW%xKt9kc}j!|fdVqEhP5e_2#8V4NUKW0^mH%o;^ z_2cv=6^gdKO-I=uXdP{p-ofFZ4GgPxCVzzU6J6DY_QXh> zfBycBYdcroGoB-Lw(NaEBPd9!S5{XP`kANbr1(^bWxV_ga*c(2Lsvq2`XcpX`E>O5 zpLPkmTc1j{13Pz^yOGf{!C7V&!bD$7gn{n&psf-OuIv#j<3AEx`u|xmW`IxiZsvc znN`c&Uj2P==zMUYNxfqRN7V1QfXl(3^7Nv!+%mz@caBH6!3?jXeP}3Rw_FOBApmR$ zDg}YyRB~|ONM_fcJ=~(CoJAS@SkSZZv10!Ej@NgYoua;{->O`{gCsL32;p0LdepC9 zbRZh+-0J_6V(j-`r_L#D_%~ZR1sXOPnK!+FfaflFrd}!$uW2C~nzf*hkL)ol;M{BV zdulQ{S#I@xdU{gr?d>Ie*Y{CdzfVT?QazedL~w7t$N1z!@y84%TZ_(){(X{Gql!5e z_43V2!H?EX0uLLM|Dh1Wn(#J-mS)RSZ*WLZU8$8Zlk7f!4=17G|7EDQ$%t#c>tS>;@0&g`@o57n zDJf6S&%f5E5Vf=jtK}AkBggp`NIkKy`AG0Y5iQH`IE&+IfBo}}jCeBEGfiMD#byFP zRvw)p-6V%ky0BSHC_}v#nAqB!4snmwG`$-Mq15SxJxlgu~jxA+{ z^O)bN+v@#3x6TrrEKVFlEQaD=s@ap(nDlS{?=+d+wkRaM=Xo$yV6YApO!{rPD23! ztJ63+)lB|3=5xm{>>_UK(gl%s?co)PgyT@LXQOXT`%e(vX7`HyrIMRiqnu1RGjnrg zN3Japbn$zhTTC~(9W2l6xqiI?8&RNP^Oq40cJ|ihu8CO=Sck1lVO7wx{Toq!V%D>? z4Wm%{KQ9Y=k*5b_L9bSXgQEKU;`Fi@#>RH$${4jO^>*#DhH@BvRnT zfv6uH!N=t<@7uSya}g10dU_FM`t99^|FAYzI|HYAamV%G=@JHl0G%SuL7p9m0Qbj< z{kxs*ZArrlYp#w&7W%|NL8hcDj?k{M<@QhX;wk6>AhF;Rj6uPYYk%IBaB4Sf3bIWO zlbbpq?@aaX6{o|OcpWd!Mkqyxo72*=XnIypwD0Z~4I>%iH9>|UYrJ5+JNg)x_>tdO z4Fh*IwuD}x`sT!fNPMasC@4U-sRb&s-+QdEU4qTZ*yjwfH}=KX;BO~mHw+cy{#c!w zr9n;+!{bXr8&qI?{BbDF=pe$ReinLCymL}a<5X}mXNFMYNht2&aXSk(Z=|fDA;k%s zTB*%*DcpFSKb9zgQlXfhSj1c=ADo@f{aIL9kGu}5Ek`!}79Td&a->4p-&Nitmv0;E z4iXSl0)@m;PL3yS)-*Jo-X1<{^)J4*jcW_hWNf}Z?B<*O@l*_SbN~RJB|a%>>taUR zm>m(8z^EES&hNO|CKe1axf(rr`J#AW6oU5wu51>1*)@SezE~u2X)pC+sr7i6xHWI& zqETjju+lEZVbCxxuVZ6tiw0cU91E3~w=T}Q@`}71@vZz<=g{$P6D|{QR4W;uwH(u5 znS~S8=uvPOwxG0$1G$|5mMWIrQWJqN<(Qy*+l;p%2xUc!G;QJrENH;f=puI%jcIt?55I`pzGmRf%Hlh5IU-0zWMnft zXX#IWPz6DPE>C#Jgoo$M%J{Viw@@dCyiHU{Vc`_ zXLG>VsFnVw>Z@DGg*d-$_p+;6diB)0UEfK~%muVu*)jM)Wx1jZXPj~iy4n$tRhU@Z zN^2GptI3=MDGi?q4GGZ-2@XzTO&YvNN=m}yL;b*@x(3*Zcx_5M9R95mlc&Qqh8x6@ z>~N}4DbecZ+#x7wTWaXc`LcXJ3|xrs=fhut3&nL7IC63S$u-G{{^ZQ1T2dV>k4MbA z_U{+KnsGYce6Oj+8-(Hw5qGN<_<8x)JoYK)`^+VYy24&=tVqO6$(+vpuhz~cfubWLhWA~*1<{)8~-p-YLw7i8*-{gePg4e?Qbmkd~Q$k zy&>;>jt^1)6Qe9FEvL%#>v{DG`v#8`JYymwX=P_oatHsG-z@9xuKa6-d}dn!{<1x~ zoRGE0Dr(e!@FJ4|km?+Kl6#YX;)`ECJnJ|&VSR;Y5*AK0yF-BvM#aZB*3w+B8McHj z7emMH;9`bTNkP#8dt*@`or*nAQKGY-6PtsRf zO}xe@B&^fdBiCJ?(@pnO4&dg(LZ`@L>wMnu#ok{FHdbAdG)C@OF}gb_99paE(}VNR ze>j4TwJQo;lr`yFw;wb^mWxoNyh$No*IXCVh0yt*LiM!^P0NsA&1bv(R<%Jk+jx#$ASkTWY_8aphmdwhyH)1$Fm!_4L^kc)ggI-|06+yI%GZM zf0avz1`Oc;N|TNooB^`c!1hSm&Uydz_I7ylogn23C_RFoC$HUKdmqcOOg91Fk+Ub= z^X`9^4SrAe&EMLtM`N46w_oRn3qCx~r;RPOHQfDJJ3tkOh@)iJ<>rl9!*@iti_TUU zpZKBpbKlaagu^w0l% zp|aeU-f0%tjl%)>p1raYdFS{4&Y*P6*V-N#af1Y@VR(30mNim2m5b)NBLJS`BdBa# ze!lzm?VBKiu^bXj&?O3njJl^lSy@@_@!0A#ZeU&SdJ#p5B1)&r?^aKe$pNXh9Q?tn zhx1JRcjj~usXNr97|g7@mMMMb&!0Z^=%%FCKDt{s{sSp5`;GmQRYBuP)8Ic!AN!@Z zf0L{RGO%Anys!HUR5I=@`9@10Dpw}TFWr|t0?u%6-+EQWP0iWdfr{e;s5mZs3hi7# zhh5{NXg8*B(FSo5vMMPuZwcz%&nucNbOV*V`*qgzLA%U(KkKAXQE2c1tunnCtG-G^ zG{XK@G}(!`mSpt6YTFIeHS>ECGpJd(HbLxE+r*^sgEbU3yk*93jc@>%GrUkiLR|a5 z`#b2Mm-=^jvI3xE;3#X`g}m#S1aI@AQ_&m?on+npsd0<;1r4a*fA_+;n(zYITn7gl zS@6N`2Zzi;^44ejo_3KaSaRD&u}&Sbv9t4AkmZv%FM*6o~1*zdES$ zy!b3=IZD26L5cS1t!{H^N~_1&dSg*hQMr~CRpd@Z8=jlT)Q{TXTvMENqHmN$A(vPi z7w=JWi%QIUPLO30N7*xzKB zKi0vYxF=4A8WQ}CfeSI!J0YWcQzNyd!7SgJ~yU;}wRnsAJNVJ!8Dz5E#4V21onI zpz@M$_NH*o_FIXf zZShtM4u>1X>ZV)oL7l)Q5mYLO*mPhY3REVt{O(_Y7Kc;vATcdq&y#x1P_cc35~ z1wStT-&Ii8Mtctj?u`&8u$b=XP+IGiK#rvh%{UjMY#e@TrtDv8{N)H@*5&j^n-%12QP!92V zegJ@E!0#+_ynW5=yeeH1?dVg1GH=M#$vQSV5$g3S_#=^X7-M%I+Q#dN9@Vc0jdJ0$ z;sakBV@cM*s`R5=X3G6&@wd`+MA$yt^8C(hptOL94e-lR`o5u}S+_9wWz zXql+RH3!u5p8N0!_B}VAQ{fih9YXc_GI-!h=l;gfR=Q`j9@Q@-fbwtL06u^pr|>k9 zZY30v9EGYVov*BprGK{4>Rq31O3Z~G2*Q-L-HF`j^C9(ArF>z^Sj$9(JfH7Mv$JPx z-}d+SPvGI!fEJ*G`wPEH2a9FSLnUI0)tRhK)&K#HFhtl?K&%oYB)DR$ zj1kD=ru>42gHHqF1K5%VERbB;qJTK~Y&;r^5_;7(Yn$;Ji)@R}p9k%`pV0`}toZAE z+ihlwJt9rVZKA=}n79zK_gxp&;Gg+&aQyqne2JRIlc&z%!Ni4y@d5!+Tl3!GZyJ_& zOnFWqiR(@ma5)7@*6Q$gZl{TfiGRu!IFUW)pzI-pTM~QVb4X;6iHBUl$pK5WUbnKu zLZhlO_{twp-YlH$a-jdO_a-9S2EHz^Bvqnn$X9^M;}9~X~lq;R9ekl8UkJoAN%>!2!T zs- z(9w~)b#v7E>!j$ikwDF)q#hXwskb0Me=y^gg9^y>Ie)JX>V%)Qw6qH76_YEWtyfyK zhMl3|2F1)EHdMFAIT zKcaTGx^2G4vy?BP!x((KO@StLg|e?NqBNU9nk*Q(iOGT+ow$;e)nQl203pO<8dvf? zlA02VXR^k9G~Vkc5bZGM*`mZwPkD&LkiAGvG=A48fAws1>47D%VNG(@y{CJ}c+u{r)9G zulDPo@70&qXmR4c?R$B=_4$Q4G|TK$lxucE;4?`nJoeK~q;J`?_kHq*-#S(A|cDYFy*RMRB=C zq(XxwNkdyIpW>CWh<~*QytVZapM0f=u)hMc&b50qrO+3)7)p`-Z@2m;_$UYrF&i;& z(9P{~aj?yNKNuRaW1*ubf*nGz$wfk z#pcdVE+{QCadP%GpS0O}Jsj010K#NsWDmNLQRD}*bdv6GXae>XTkulYYy#Acf5@w6MuV>c&sUC?cx&XO1@l8BQbxtGoX^dp^Hjbd?VWo!P9M>l@? zU?f^BCN6(nk&}NLumiU#h zz8~o2)J^U~QZKzk^!4<9kPs4nt|8L3Lu6S9+~2p+H8EKY1i@ZR%|n}DM)?@X*9%6| z_+l|Bg;N15Z2$kSF8wxE_#99`oa+0qW6uyG;u zuPrvDHs>J<10AkKlqhyBw6&JhX-mGhd$+y|mIDE;BfMX<9Tq*ZMHMb3B_(s4EGhAs&UB%Yl-kx=6V`I zQd{Wtk)fE$YW59=pt5f>@qhM`e4d8wx{$6>DErhQ>CbF{5L>dTL%0hE_)$B~{_`Ae z82+-HXU#goHu=DaI>=`ll?uWI-{CCeV+^k&jdC}ra&L#G%s;$AVP@f$n1#AHMyvbUi%{qLns}UE3LB>Ec zn>Ajyu<9cbkc&cd0eM6)aaY`fAHLYt-#w6>7ne7mKu}bEb9x#V*|Sb~*ENVy#Hm-Yo}dw8SBOdThD>_ZxA4@k>zP! z#Y0eWCj20D^edlVTAv;XJ21R6Sz!(NQ!jd_;v0s#c-f85FYWO2f*;53pK5B}&1 z>+?<>9@@pZR-5{)vO|>&es7VYh$zT zfZRR=SJ)5Q7h;#=Qr#fC2~AaEcpWd#W!i;sxYABV-beH1O?=z!dL$hSi-MSWZxkgD z4^O?TprK;K@Uz$6V7^3P=xwI3)B01j&vSOBh?n0U9+mHrsBR}M1=OG z0@bW;P-(Y)aF2ci)_biY0u1@WwOt1|fp{#x7S61@dbKTKrVV*qn51_sM)X74miUYe zc<{$%nga|!w}J_Xflj~+;I|LGsM%`5u36+8=xB+`ZO>a+rHORh(Qmk5@6!h!fr}`3 zL?Do&O*gq;N-Q$oB5m|7paHb&mOm|Ht|)SiIXM1e?S}6V1=5Z-`;>r}+D9?l1knI` z&MCkL)g*lD;&-y&DJYrz3&O?+S#lXSf`TZ306Leb9wE<>hM2F^`yyO|YTm&052Pu+gbRTV!&7LLE5T z(9pwgss!fzpQQ^|+98WnaDxy}MZ}uS3(4qNWYo9lQhi4e(6Yb!pB?RxD_h-TE8760 z*);xNI|QZ%g^kS#YQ-8=hu-xLOHEti-@T|{md{Y0*xAfwLQQq8zzBVo)4Q3>E7Sqe zA`A@q-Ndgk0x8PYv-->e7Y+L6S)ONqpB+|@Azj=(Mws`-_R=m+g6V>b-HH&dCW0DPHjA*Z&+gwUbH%Z(Ew@>lT4@e3gm@i<5H2v^fK9?>0%HJ; zJk3v^@|Fboyl0iJ`&z~P1YLJ4Gm*5!?rffu3L1ZYEda#PLokn*ZY<>G9eHCpeU93p z>=iFxat}lXM@Rrp{n8v}fCF-Bv+eE8M(K?Uizhs@;~jiOjoYDxi~+M5x@yt7T?Y)D z;!YyA?kUPnM-WfxU}#)pY7MhN`VME$S=AohWC4V72B&P44;#QwHua$G$)Xycwox+# zJGxGUy?Qc9h5k-s&4{>YG*lo%qLu&>-tW zIkx}Xx^t$wwxUq52M(ty#59^5zZNN3KJ1rD&o!p?KN>47wjXUTv?(X8Q`Nxy;M}*q z|7Ig5?epTzGk=^VWkS8WLx+1GdUj%+Vw;|T62k``Kw3_&-dcjXH61EyFrHt#BiLq+bA+9cDgNo8j9|-brQO>Qh%Y!eI$b&e zvUuhzC(i8-M{DyEzlGy5_Ua<8@FJWHYIJ~0@vnk{zBkqLmV3+B+Yj8?*_-*IzxC^* zFP4pOeqE(YblA;WH~4P#^st1YPTgPC>|Y}Neta+{JT~%O8QowU%zSmdmH!qZ>X!%? zq}H0bH7Jlhn7#9;FjNyF&p4S1hAE*76rhGgzM`IKENAfQbnNSUMNRih%1>`e7?Tu) zz!l^7?(XixLLfH}&y@)X1rxyPAj{wabQCx70WPoM-7O%QueEZIm`3i6!()Gz$#I1J zSFX!r?!u9q#dJuvOF(EH?(2!>yXW6N(IzUQZce4 z+b8Gd#uMC_R-)XnC6EEvF)>1w5L94vcY4<7nI$Ur@D~XDA&r1?D?u&2LBFPrxxbTe z!sae12?xq?E}pG-LiCyb$tdD|+?2yrIqecxsMY+#%eM)~Nb)~_{(PpCvRDEY`%_O? zXc%l`*xt2u*6?Y`aRa(Q*+3OQ=J4p-@dL=~Wx01abMKCB=O(_P{ol0l|BuRF5he>F zjQ>&jN495Y9b!)WSNtjYtmL7dJLRTlEM0=)~A){g`o?&xuK!+VVnJKf_H*M_;-~k`5o5Nvu>O~k397%(Bj@~Zn4Nx*ei0wp=c_p?T3#B$QaxI# zai}mq=D9I#TMQMi9ZI=TYfO_K4^r&+geBaSd+3%EK7xqXO`@W)?$>?Qx{b6kF?j0U z%nN!G;(jr|9rn!~V_6RmtS~yCMYaK`lT&;bMV5Mw8cMkI*RNmUTwk3@V6UJVHa&D2 zucN7&!F6+Gr@tb_p>nI=S9`PgY;fN6m1kOCBlHceSLaXyR!$Hk3zIzXol@fJx&Hk-JvB3y~c0Umi3?8r8`1#5O zi{wBzt}+2x*KZz=^))p$S>kMPJ8Mzk_zL_n7gv|(=U$HcnpmmYl?R2iLS+-5%gdxSil+PK=G-Mfpl%r^{j;1Nyn&3G z5mcHqzAI_1!ewQ(x4(P?V`$Lx>M>EWXHb1xY;s)ddXu4YQ?A6&yo%EI{Pb|P(N95K zeX~peM!zaNy}Zo8s8E6BXu80oDjvj2;?Xnn^>bKX@3r25da;n#-7I5DodQ;vw@Zl*p8`KX{zaMz4uicNU{j_9+>5_LI0A5kfJydQ+_Q2MhD? zC5^GMsL~sCqArMD0xH@TR!#-_AXrf(@Y5;qr?Q>Fir5HuG+!>MJh-_z-6xAeE}#8@o@@C_VVYpiGyK`t zsOfnWHg)WzUMCihUzoa!gqyycRkqw@H{6~+WAQ`r8Rz)jJQWmB>*y_Oy_9{lHp=9Y zZofloCHo|Xeq4OCzvCp^3Kd=cs&%JTZt(r7SFs{QDecXYV!_n<29}r!7!WB-6Z7{Y zhNT@D-drCoq*S`>j4E|B@*q3AxLB*J>L}=$N#H@#vMWyYBGgXxsGW$~Ge2v^NSpa^|n4j9Q@LJMMya z3Qhg>3iWUeY?cjHq}Umu72;$jsnB8N*O z1cnDIn8)3aEHwvrIZdM&tm-jidR%)%M~13 z&)C%@o4vBSe0u#YySxo|D``t@dg-gW-0Ip|!0M{baJpZB!^*$a%UXg$z+eQR6h zSFXlnm9UWtgTZ_x!(ucB!5s1p6B84PlA_{JrjWY>kv7_Iu6M3qx}kv6vv{+N&}>28 z#7?F+$Fh$48vahKfWRb}D&n9ZBS6fR4+3pJC+?GGC|usVA!h9u>{6edjF1gPXnXX> zleUHZDv@_QaLJsixnQuWe~{(Zt5+h(a7+em!paA~Zg(&#`N#Y8EQNb;6F+K+7Zu7} z_N!Bh`PI_c4t{tcM!DEVEDP{8-LrYl<)+${3kh}68aqAun8n+)yM#EFhS8p~-6tmM z_I2tG)KvL&`XMR?>8tp)j9IIX&8mU72%VZ9l=of6@y5Bmr>z8-zWy0XUoHvuTtp~e zc0Tx7r?qc%b$5TKAJXo4$e_Pn3#C$^^4g_IL7yND^6vue2rQjgkX|0gITvXbH-P&g z`lDrOy{`6yL9eHCZjJ~{KQ?$?Fq9iMhotdAC;tPB-rn9q>8ju?zxTaax;Yz6Vy(v{ z<2^JlsRD%&qTzIb1UhPq)-L63pY7v)D{XiHg2 z8yagzh=Ioq#RUw3OPC5&d=egy=Gwf{dPtNDJ??o)Hj(g|^hM3U;(Duk#Kj4Jl^>J5 zuhZhK1ZOrEE-g9|{5wiP7+zowLuwHI6%xhtV3XDq;b9(f7N>-X3ANYFarC%KE^bY99>HV>UX}G8KcjOKRK6MpZ|=2mOSs|IIDwxq=ouVe9!I>lnz$ zxr5?Nz@9@foF?R1lf#BKTdG^V1@my_1Hr&BO?~uJuh4mwukTf zji%4QDenTLvdYLPedvVhi5NECI6U?CS?0B>Fe>>9W=6a=e2ZY`ew4fLc$8UhD{*(` z)VdthjrWztLmg==9p&^%DjoMF5E&~u)cx4`B5O=^>gXzk$m}Y_jYv*b?#AF|PcSxx zuq|T5T-Fp!u*ZsksphnKrbj0bx!5_TvYB2HnJlv`abS}3Q)6Lb_Ews9>x7uzZtt=o z2Z)2+1aRG-el=Ha*c||myvc1j>RMP1N@|;S zPZ;Cpgi~o7vInP()L1N{^iE)$|P_;gww+@6&o(oPh?W-5O z4Vc*L_(?9@Dd4(S{->b6%P^?S^jZ=O&*#03v6y-Y< zkdzaYXjhEFVT;+FuJX!39s}&G6;N@4g8q~lwd!%8yb5<=z%{`Sryf73@_qOc6cl9A z`zL(X3UKR1Y4}hX(Wb;uZGY={d%9LRk()pzJ+vUZU>20s?k`5!y-M}|ePP*$pTF}- z;UH8#ZFlt8DAeCPvb8;KL$y^iL|42$q82Ill77DSX@2sr_k5g{?cByy$ybEq zOS8}Mn&o{|a>q+a$uK7r#!(w8#b&|JAG+DxW%pA!>SNt9@?(Xiu z*t4XP68hlKP<&dN;*lFNSP1_>jgOVeV-->X`oQ--k7s?7sqX9}2-p}GNS0KcEg26I zsqVt|NzfhE3Oma2b}`+ILdJ4s`&W@xsMArPNNhr11N;eQ^ zT>daE6MHQA2JJ`$ADn1H+xl^uQrU26(tQ)9j>U+a|ChZ@H?x)B*+A)lub=tjykQ(HJwFFZT2poo#YmCcu`re7faJY$y5pAnj+y16z9MPzDJ5B92s z6nlvbDjYbj&Dr*kh(vz-eNHG~ABn18AUn{gc>C#u#=_wiJG9P0{C(#~$7z(9IHWcA z{Otv_iv{?sF=UuN;BfcwkmBL(eL%#n=Zd=xF-IS^{j}3O*#3Fs$27Qi01%gUbPUT= zO`pq5>Snp0m50Hvy&wQOwKfFhiAkp5oUfFHKR-VQ0HICieNZX$c(8A|9~Ht_^F8oB zsJd#UUGr!C{TtQ#!&$w^=pf7EEDoiZ=u5j`Af+%RRyzS^~Uu*tAv%@I-L5dyr z<1I?_jYN;j4fV-EYzNl<;;H(72lB%mp(|cadu0FWBSS+A`WTH%Cwf-AD;%d&C(v;inYn^(B3<#i-&Tks0kQd88 zS*xb0i7+(#M+xKuZ@IbSQ&Ny?^)P}Z1HhP5PD2ARpTnYfETsteu4$H)7S9Vxe-L1; z#70J5fEDyBRyOypK>GCn(rJ+rgFairz&`MZ)qx@z7N=ojH?o&1=Ks7Q#->v#z)KfY ziAH1=)d@>z{xShB*ae^7{#yX!YPcP}pey{FZ3x^;f@W%JY9yOmrF)k3&KeiY6o5OU z!JWc#;I`Zqux7-|wD5u@C$h$NR4WPm8x3NRseG_05J%h~L2$b~z8*K0&4^y30qSU% z88Gh7DW{dkitMst#IZiI^H{3B28b9fHK&U(?3n#Y9GX>rOAif=Zq2E4#Uq8}Qu@Ro z_iCKDKbssoL}a8-I!m;QpLK98*kgxp@gl&)(UVgLpe2_C7B8bv;)sut znr0(`bBubk0~;2`KW(kdR52}HW|@Z3%k^j41i(IT&Lnozo1U45(FmX3;b;4th8_;FNXn4;Z*%T__MC5U}a7=Z-3xe%n*<#^$3fGgPn7|mZjVB0yn zE>;Z&ut_M5oQ~Ex?FZ+AHa~6FbMHBMyZbRiW94DorZ2Ll|Ln79_rp_YB8bf#Sc?ba zjLny&Ro;C@jZkJ2)}n$YNfl|{htru|#)M%Tvo=mNHvJ~8rp%ySapA(F;?z%Sa~UiD z)gLA=EPC-~GjpJG^k`wv6~0+MV#TR9R9u5P3*xcFr0M zqPO3J$Thlb>1D3Mr3|W+pY$MC%oa=xFD|xtXJ>^sQz*pDl1=wK_ z)0_8P_*C|e)kF&!L-|~`kRGUHi>WZ}iwSig#X>k8zWCGvN^P9+G5%#67x zDT&M2;qQ0N_6o5e{{06T4qE-_bS?|=?adxs+E9O%^RT$KOPk=|iQ9fVI;#>Z3pM7^ z{)89*kcDvGK+RpNU}tA1EnS9X$4P%NG6WUPA#|m2L5F|smzQFPA-LzbDT!9o%7)|jt{#j>4*W0_j zN89s_G|Bwl{#?sF49?hl4_bmD^hoN?_|n$)&onirXS=hBCOI*(G zMEPSbZtjYCfFW%WV|6uhC)$O*yv&^kO?{~y5NJ{&u%KSZ2aU6eyroh-pJ#M$B%hz! zLdOfk!EkI`d@NuugVexnv7_E;eF+GJCz?I^wc|xm78b{LrwLJwuHBk!IQ)?|D=n=# zd-6+Q1&!>t;29GDdg4ktxTiiOnv1vB(kV|*rjtLiBkq#zDCkDNaQJG5My34x0-fMF zCl!YRqp1xCvcn>jC-LL^XuDAL&r)_YLlhCt6LY%@Gja$y{clGWs!vp!^qAsN_>Yp= z$8GyNVOmRSu*?S&)t)p#s$O&3H_}ilib7&cc;~?|1U((cZrj8uetR72_te67obtE- z-LVim4+ZY#)>el4m}IuPWPU+#NeeZwp|1WgR81dEy#E>_%P1I^&KSznw3bNu6*8rJ zbeCj9!iz=1>&#YQgH!ir)RBT*$rvW_0wrKk0uz-9HCyCs-F#(aWfk?G?(VC|jmU4J zf)j8nxc@7Mi%aw1mcHeKHvV-jGK2xEW|07%(aBb6>#aJlGUzx(wSD7c>`KFsmUe|n zSXuphMfC_Kl{plG57+>>5$P zwcSNyocH9(u^Ah#?l4;G-*p#U5t_YufiIZ9C{POu3e@xq5xSYa;H#j8dQ<4BM)h4< zGi#*%_o>@?VV$HJ2~w9|x>?&5L>Z{QDC&9iEJ{d=pS)3%m(b|NG&E+^+{Ll$hDI3u z_IxG6u#?$*vnr}a{IJ6$G6tn|uwFJiwXUge6_3HRR{WxzZLW(^l*KZzH6y`nkx^0zA3K=)+~tA~bdB0fY#>@dXtI1;dkn zsP7g}8}5+wQm2UZTdv8ore`@<%`(r^{P9_yOe73ajQz4DtH{JLuz)y$m+x?8Mo_?M zlgN?x3V%!lC-S8?&LaEc4^LX5{!YSxprG&G;}6a~ZpPiL|FY)g@3$)L+$()=Re+WF zm5z>JxG|X%a4~Rx{HJ!jGfi5oTkR)9FA1h+E~7RGK&rq!+n@~IyBMf_$HB;Gd8TFP z{d8#KW9iuAtt?eAGNvqVfD>Gb#BEv zbiCEwWe(d9G-Zpx0Db?5Y@w##N2iJSUlgU_caKsuSP0+fvOp3E>~DjBjp#Pxrnp7E zln&4EMv_*cEo$xQ>SeVdK>schOy0HpmHV@BDX7rmjDZ2#|3xe^EC@63CbstNT=B9_U@@-a)Bc9%E|DlDP3S#{f8?@ zhU;}7?VVo#cR736h<2=$u^`7{)KwwuUw!O#KC|J4 zDE%Sj&4aXlZg63sU;o3KaZ&V`Ne0R_t3eJg2%~aWJ z?}~x(=q7f^2iWyeC&9fLgUI5|{n<#A14eD$Ey^JoiPqhc!hv4zOf^-6d{(!1jn{dU zEM%%G8rBwN&}=sMXXkH83Y)0tqn@y^!j{QuZ15lYsCxq(ECI`3FOu~e)%5hjU!$VR z*>l^=;y{p)$ML^hJ;k&uaX!BI1YuGLOEs0fOt+Xb`Q@Midq;Jjmcz}jH+rp(#8VZv zc}yI^ilwzZ0~#7eQF^<@xW!?^;v~;h?zAz|u^?f){aOB$6++TBO2*G-%E|*IdFVLJ zA8^zY}n8!GBJj{GeRMZ?AP4N865bG^wm~fi}FGB8!1>ors7? z4KF}};bqbj(0o&2(1E&r_VU>cso@F@<4A?MvR=bSOeg>Z64bfuP+XqvMS?vADCn=R zy*P1@r7)fWyD0G3dBo*wu*~x&_h-f`t)h`u_}Bp&a{~wtKHsZ~@TJJ0d6;&(21}_& z^jWDiNnh0EVGjGX#d79w8pGK@FJf&F6VUaQZ{ECNR?0pUiDZ_6jP`8iM4E=_dUxffHFwku zbj;6)zZTc&Wyss(@sE}}i9Cy65t@5JM~FUQ3b{~K8?BGo={5UcvUlvTV*co&pAqdm z@=$vofM2OOK?^BkkWpf57nOYqfQ;Lkzpw?0Y9Y`?M0TDY&caCt@wo!kR+fy*AWf{1 zB&6hCG%1XbuWdHS#|%cAhpnF)H9qr^;zpQj;|E{Omk{AkXrqOHzULn_=w25QAl*Ew&(id=mYR^90Y5f2=w8DqWJ1++#@w6B9k7Tb_b~5>kH)kXmFi)d6jipyRbN+rGhYSywn#T zEw&=BxEM8?C|3QO@PRO!#lu|+!mVOl{hn_Q(C?dyzuVxqv)?V%Ym}xBhY9vs34ciP zkkV}vo}IU(lBPSaw{y?P;ap_kpq?Qio31i>dI(H;yWr%Ui2EVKfGrrW8xFnx zD6K|xI$;Ga9e9Gxt+C7?yB%?Ve}5WIiU=AYoY`~#b=CD|4tb!&&}nZ% zab=zb@zD)`uf#3T23s`;yn)TWLa)g#Ysw@aA00I#P&?cxxj(CR(yrG3`r`X%7_IvY zcfG6XrK%OKr~KJEj@!0fc%#*tH)V~wvoz%Nb@E09xYg=84NX(u5dYx1z_cJGoB%VU|4h-r3AN<+SVXSaqHCe+3c{`pLpc<(?S~OL{vJeD{_c1oY zMr@prhDH?>WSK}RL3(NtH_q?f zg%c*el59bPsVBiVnVydl(A!22U26x5Sw{n}>v!hES~X*d3`=`a2j>nBlb~1_Q;bN? z@#Yeh$bw}5!Mu_g-_(npOUIFag|zrVNG~vMPmu12zI=Lk8ST0zLW^pu*2rgHX<=NZ z^AQ@&JU3!U6lDKf$cBvqWxIS2f=o8mP^eby2aqrj>r?$JBU*}UJ@#save+4>#vIv1 ze5|s?sCfl7KVVp_=CnivZ0=iM(Dpn}?L4E#l143=$|s89SO|5PT5y*HDlLqJjkOaS zyZgYVW72*gK1JMf?jcf`kzv8&rxa}nAOnLN9~-~}-r3!K3)G2&=^&kE5hP2Ut{Stk z&Q@7}naV)Pb7w+|&+6>VD!I9u-rX2g-usuyFrrWJDNE+6a_84$=D{$I7A9l_ov7#B zM>dx>gdBm)-CVP{DOtD6VQ!if$h`7wp5I@zeV;407c_EGUS3}EckGXIkr)#aBU;3x z=XOW%mI|8NjVeis#PO)#IgKBb08ySlj+wEKx?-i9|I zP`h_|+fBHj6n3}O(WB54RjSm|U_TSkxuYs3W_ve_d^z8EamD`gW|dR@_3PSVyEciV z?-;)?Pp9qgj&^G2yPq;J9JbT}!Zl*@KC=;YVe}xt2Y4tju(5^pb#%y`uFpS!>d6J> zQ1GTNR~~7f+uE|<*4SBdat_M7i?b4ip0)J(>=T=g;E=&R;+m`MdzV{&IWZwscbS`i zCsj#nv3gGS)sS3nM1{8QyBgE`J|aY;9bzsAnvpvEs*bn7-;-wOc70&UV{OgR%N=W9 znAva)8Tm0O_=P1Da(XPiSZZuS=XE^^ZQpz|57}`+bVb#2GSzrroZlO--W^VBV*n2a zeL#q=Jrk@9HiFjTYh0q>eToZ%!VFWTWu+Rc?agwI4_&k099pvDD?PsmSKG z93hm7WVm)a8&y9yYy;5@A*FdaoEG^&D2z^yY}IIwwUcq1O-;>rOfS>75MtMJf=W5N z*T%_CPHt&d>+31vc8%84udS{(`UnE72_nmvKW%sRR@UixY2ZQtjw^jX4J_w(W$^PN zloyHIs4Y2X)dU0XwaN_D9e4>g_7@0ou$j_8oT#X%+o?@dRd%C<5%~krU%#HqnwTtU z?WfMwKS<)YFY!74E3XJbe?SAxc6f9IvW6ZF6IDZ0W>;{mK&jZ|4Hl_laI{~xq&W2M;G~D~37L&U2u) zjpqlT>A#5-$(XD;!f|(#!g%*^6m!akRZi7yX74jTT$O_mKESHRWRTnTMuvy7mtBU&7v}b2q{I4x0ZPAJ@2NZv)BN_N?WK1V6 zzS!RE=1Y9RncS~Jzl_1A_H-}|dnow0!{vC=aPEcE0-oz zlyZjthY!8^uGLzJ93EXY%6`k)8x%Nx6e?GnUHe1q#My`y(=YmuJg5p zlU;byd)A7+2Yr~U&BagXRtA__(E*x>j7uN^A))LuB0aS7gOXrKhj_FI2!_D~Uc|ru z3BH5`62^aCy8j2(e_sNxJ50Y~jB+FJt`Dm~9{zJ+;LO9oz<^rRWt$9e6N;@qHx%rV9bf=nR5XC# zCU_9K;n0^u#n@#P1L;-c8^xw0EtWMl7jA6iC zQ6hfeF%O=LgZVp;KWetziU0N&JMJSriu4<6fYs9Zy_LQj(2iLA{@T7}P-@T|3hbo| zDu3S5wBe4ZqJ3n2h=f`+@it`dc~dTrkK3OIX=VkZ{5V;|xvGzOct!*<>Z{OcY{SOp zOT-aiHcJA5HnpgLW*6E3h7iiwc{1QX`U^~ay*WTM^H9fbs!DM*=Orajy*w03`TSB< zb-rkLBS%(7<~&w59N!O26YcdWU%!St5_WN$ISsm0LP%w#gPrQ<@84N^CJctXtrZpA zwVr3Y?2rU~G_8ODnYp=nUS6Jrwl>*)%Ha;c7sa`_${7)?sR1Wj<9LA24*A>?ePR#X zNX~zB>Ky1SdkgLrJV!^T!PkOC+U4Ifr2pum-qQ2%5HYHJLnu7)o3sNhjj$R>z5}^n zlZ=8|Tg1H{0Ln#$R>W`5mp}i_lsEJS)YUY|zy!weJbfxVtSty9(Q+Aya(%D8gIap|R62JUtXBc{sNcU|Xeo!3Ryz;Z=soM% zoo!^MTgh3zUFe~KYqSC%%+Ei6x>tI?Bxl{Y?9M2H&=hIr?4P~8uhv&q&a=|L0kQ;$ zD$I~LP0GK5uo6koY_M&lUN!ATb-kNs!Bzq$i6ZXY zgoK0`5Qx9w@8tz?%qp8@{}gm|5_wozmGw0>8BRt`T!TTtQw;cR0@Cn?K<|A50=T?l z3Wqm}2nYz4UMBOkFXHBb`||?aOuiHq{%7>`CTBZdEmRwgr{;lDl7deo7-BDn_%lFevvaJp3etiI5?ISE zdYQsohVgN6+3&;Gdr`;Gx|QbU5Mc2#S ze2yy$Y`Rq#%JFR0X)!U}C*?iV(m=rufsC);c9RvWB-!fL2O2n5;KG`kAW)~i^1Y)F zM}EqJ1snmJAQU)HgQesq8~lrnitmGkF~7&~-RHR|*NfDMptbTFO#G%%r8Y3&%v-4< zIL=o4>_skrtJqzdd3~uOK7;XTyai#OizJ z#^msk8ixrqx64G(vLQV8N87au75T=g4pu!@R$Yk>i)1Lz+Nw!Sbj zFpPcrRKM49wdsa-UUxIgG&`byx0D*T^%21cW@J-EAe?~iqX9r%D#&H~(|{+HfggZB zVaEr!7cXFS24SuSh0p3^;9!})UF~uXZKHWA@hkyQypoh#xK^PbhD^$h_7~cLu#}A3 z4CC0N*~vye^RE%`%9J@i{pnqKU2fJJ^8ozskb=h!d%YYiGb11xx?5GAc!|>wT-OAY zlwtq=S>XUrEpRZ(bVtL%6b=CVG_tr1C>3d672NzIhdC7J71Z*EC2kxxa)<6>CwBhW zA4-}(tDMwoQ8sJJ)YVX?p z(f@+DV1`$h6sF!E#_m8ROL1PyR?jbDZicAjBB|Ly8ptb8VSA8)Mn)#DIm+%)#Tm)NL88!ga7|m^=GCIK&CFID zfFrhWG!zKIq-gQm?D#qW?_{pC?rB%94H)P;*D2etZqm>00gW6L7k@NdM-Pd*<4N$%4{#NOpx~#O?M~O?0d9C3? zfyUi>Hx>$%I>13hK1vQF!jk349`gKj*~(pKgGf|1Y_P^!;GjfyU}QmhZt*)kjD)?R zm-rvvh4|%*;XlJ0Czr{7*8+uxz@vIE!;HJuFNSONfkkRf5g|9cVgMP6FoJ^017Tp| z;&$1VHlsx=tcaw3`-TIBgoLz#{F!q2-EA|N=dYzphO3+P*Y9TO`1op6vb%%E2$K6P ztg3ZK#>VK`*l@sy08m;$1m z;j+;@AJcs&pwjy+(R&UV1ke-H(a`~21<1a^z{L$z$?e!2Eo|p(=^_O&ixs9yO1~}u zGGq++fO}Uwls*f1;*!f@l?Q>anXg?DZ(3qn3mJ_-rgR1P2nvw?^WCpsN)dQBlSOJw z7LfLqB&LGH#SFOwd?FzWZ9(c9cab9z(*baB6*(9f$Ky(_kD?OTbcU=B*E!t=CAKFE zyBnJ6RI+LJ^wQ*JP3`R1LPJBNQc@zohh*HJ#OtH2ukp(pV5hc(hwDXmV4v2xG0l`? z)eblPpB5k@#@y0Uc)%J9l!&|wkF<|MvwLL&*p(pKstsHn60|j53SxklRVo2of&~V< z7WO@aZB?uAYPfyk8gSzHgMmgUUHBWw5Y#;D8&A!Ajh53dQ8_-;fW-CHV3Ac&zyP`xqzF0x!9leq5Ir;jR2Qz0!|0c%1M-;K6=sUBqr@Qv!9#S!{e1#$V_y|_ed$GIkjEPkBPQwt`%<}e%9Y{&rg0JhTpp!G+9JqsKD`nXH zFIOCPHnvW1i;O^q2MrDQ;|LHj_98`y80eydBxo0kA;1}bT=^+3E>2_LbbtnZOa)!Q zDkzIF-dCr*HaM#yND*{*6BF9MPAWm+0MMpHd{R=u?qnq+NMUux#5taR2(0UCu&M!?Z1LB*MGo*ow5u9 zlMfZ=Kzo&fCE?=22N1rkBCP$@+wmfuOf&@OK|4ARENbV6nyX zzI-DuFAvVOP#5z>oWvrmp)uiDgg-vE3=^@(8=`V>~$@k zQoaws7{kCGdYdz916r%V=io?_d&PZdD3+R%VBu_Tugm+}*4v8K%MUQG-uV;3d23~N z!KVw^2?qD_oBKxtOp16QvYxjL99Kz16A@$><9H5QhKL;6 zJK+z5Uxi&uw!s2>$uew=o1d)CAn!Ia2K(8~e96r_SppXR?^I0ZqK%c#m!HxKNXZ zbuDP3ma&Ba&J1k$&p?a_L}}>X#(Ta8hCR?wICnp^UsePC3Ofr+%&6-Dzhf^A0&VtY z42ZInp|8e~X-l_W>M*^BcOoYvum22yVbs8|vaU{GsMg-_66BMLHi7(?J;4fnU|REv zxLkMG74>eH;aq==B|@Uce}ibb>JxsNgHQDPVUSaCy9u2_7ibFTXzGe6GDV(4W0KG29G_PZ2DM9H=Is**%M&vjy$QpKh5;esdf| zqu6%u^s;oCIJo2C7NB+VsLje+5d>E!{;`->!=PiMStUjWvSi^3yw`<@tFLc2s@9W---1n<+jeKfW9;1>4=;E!uRc70B; z(H~IJf@^AhidEd2h`z}vmaT2v;pmy$16e3;)!)$`P?3>^ApaK)S+GZA z7)1FWNTLQHlm82nAYlK+P1@4%H6gona@anKaXRLIe{AXr!H-n9LC#<6<7cz7&Ym&r z?{3OV50fr0{{xon9{TuXPwe@c4>syM6s|ta03@w0#Y`VP)&Z7w%e<6Ml7Lv#*!i8_z2m{gUX8C&`n9 z75i+MXxxoH_3iWkhivwAt-V%mtI7QB`*{VhbNY`vO(uA%{lfn)=6v`BsHPe|ZunXB zCqL#grrKL?0MLLC$9oqS5bTKsxJsWh$`ZBLa&mIZm-;bd2fi>`3C*m#3X=rnzp4}B zq{V0t2JEk;Q@omYPt0qVPI#p-Mz>BXKn!y}$eW6KV)Mx*MK@E^UZ$))lmI)mGw;*u z@{=$eyU9v<(f2a~laB@iRj2K0PC*sgMj#<~0-935apfl~umL>;#62BjfE9E0Tn?;2 zpT9_x^~kn;Kvd`tMF1RkXIjX99G#N?QQYlN=KR+)s>5eOL}+{q*5}FfpS=3#_mru< z414Em-Y4_4ILq^X3Y9Z{i8|%_ub`%k@7uK*?yrWbc-#~>aSqvqGF?ee=k*$ta~IMu zZ}C@ID##wr=xZF-R3DsBl_-)^ey4E%)o`Tr9~sdI?Lt{84jRaag@s|}T&I5QDXMOf zyd9Ce%`Ai8`P{c9TdsT5Wnrfq&rx)A5oZ~%$b%5dOM~*nu36Algb+C2CTX1H zL^=?bt1bTz=2T*?>`g!Rtz&4ze`(Z&5}T6Ak5$THb&6LnzeJ`s-GYZLSk zFLe~JS4&jP2BP8#U8fzOox)wWH{6~VZaJy!8)9#5S=4Z2I5uSS+)sQELG8eAKgR}6 zcS=q&CTrS%_HA_Fe55@j~!+M`xaO7!!ITy(y6+dQckn64?lf7oh=A4*_hVJ!)RRIX?L zmA9&-ihKeI`<*>KwT9I;qtmZ*UbqjTqe_&)2gVJ>xCaMM9jc*W((#2kNt&fZ_t$|m zY(@WS_Wi4eGtpmaefQ=0SrV`-l#`pC{mS(!xq(&>s%=AFxQrUx(SG~)ret?9v^Ldj zJ>0E3!A9lD^XFe2trhFo6J;fQ?H`jaW;pd5DYTC@OOI zcwd?qJFN^5h(kzxxLYn3?91&mILSnwITWdY=!J@SO0Wb^#L|9i>1; zvtg*j%W}WZHV!V2t68jV)IE9knGt&q|L{5OCL)&YTfLW$ zjt0yNpWhC@?k-CaF<_Lx1)V7xXd+g=s3vWr0<=%%u(Xhf$x1G0-SukjB611d$OO&+`y#AQ55H-lw`Ke9VpT(&z^^a7~Pzi$lwSOZJ?L>QBfCYYXfQX zS^gEZ8k5h=l$o*@Q%Gf}u+K__vLtp*!w(9ZrhvQW?Gxs5$)F=!=>}wODQZJR`0%?q~sCpVHK^ zCRsD16EksC17WRR&O~I3Ud3*{kG=hk*&)BFsW&0v8g#6z*ezKHR1_mpvpHjEy-T@9 zjU|C6L(Ujo^a1!tQlFp<7#+PV;lBb_2lqWm=ZUNgDcy{`9l(OKS z^SSm%S!{g(d$%+ zBWk47DE$Vl6WS^OI$!~!4>{&V>P1*;FVvUb)L)Q0d#x0nuQcjdb$>*IL{98famXkl zs?*ktR`2FCSmiI*g`S|OiNJpg{+k6V*@;^FG%e8YkPpk)7;zv>^XjH>M1_#k;0DOm z6hM3%^0_7qy!QK+`}9u#X1X*bgz<15q;YA-JI5Rc;Zjn(q%D~~>7{|1qQxOIrnmr@ zI?M_Xt(4p6MSba|Ah(kMR&;H*`jU%-^?7W`EirSp#trbn3b}d#$XmPI1eKecds8#| zaa6;X1Y=cW*34KNkWbl*Rywe`B-?v^?LJi>RlM{n2aJywpCF)8Mr&Y25V7`}{+O{W~qv}51Ujtq#c@h&5dF@Zx zmY&=IBU-0LB{?88`;+;D4NBz!WAQyRv%Uc}wdhVw3PYJWqNvVoA(y|E?bEf10lL+R zNk|}$keq_UY6E#F{4JM}f}NEmM`{3wulmIdEAcMR7(klwa9A-k6f|nWrPpiT6MFxr zlU&SD!oq@~`pcaV%0gQ6_M0~uQ}4blZm`SSk5c9HDh`ssr9(G7z5DvIM5X{sd^U=i}u4170A;{ z8+X-NgS{JG<7d3kN|;vW#3M6egqPr_-)M6d^!XEzJ5FZ)?)}0Dj@L5=d;eD@#*!A%g$IoOiaI3C9c@gmeA2ltbcMnf|2lp)=@XpcDv5sa2)$b zvtbbpP6}@Ok{}M~N(8kGm}m0=*HfrjTreDbba*(Dnv(%yMx}m6-Ot+qFtP%&@4z}$ zu?rcnT9?^|^#E-FoLIyvps`;MA$Tn0`RWOoltMygeey4ry>D=z+rEvRTDD!pymDY( z5dq?e~3$>0$S}dP)Z1sM(?wkNImC<0F;5BB|zMEhx4?oQMVg zLcL&rJF?Gdg-2+2jR5oz=K9dOY4N<-4f6SA;;C~@aFYfKLGuG_>p&2g*X-2{#Zd6l z&tKA%G)Dz(O&NVGqYCcVM1h!YvuEFJl~KBS6{U)*=m4UsQ?@B|(VOwH*r5R5uA985 z3*nul8Q}Jh@8Ng%3+*bqdh~wX6Xa|noQ{1g85U-w(9q8x9%3T0&~!yPKjwL>8q@7> z(>*dw- z+lr@vQf-^f-QE2LzzToAzpZ^g(c;~hQBk1|+Q6N;2R+w4U?efcplgp+&!prE4-?7x zH^RX>cdn&W882F~?=<%Cd_5kP zy^gqNtNwvHr!Iy`M2kY)wZA$E7|6jAyvEjhVx&2N zx>u8c;=hS6E`KX&$K^L+(!^yD0?@kWhKb34%B@mT7iYwBYZsR$)xQZjP-*?qnmPU4 zxcj^jru#;Yz+@YFgN=?_ht2Ue+y2`F*bh$$kAHJiB3y=_Lz+Zs0~W53PvzSZK*2cP z)KM*m#4b<-oVs^0-Hu*ver$cM1W3+BZxol~SIPZo07bcf@PW;#3&1h}p0NgqByd3*0a^wR^S28=si?si{tlq&@n2{{HyU5(P624GqU~ z2q6Rx@Gvu&djC7`RiUkJrk0t;FHF#+ys7 z`%Eq`K+-A%w_TE9=4_CN1X0scviY)pWjAu*qXblo7oHmoE+u&&MVJ&+GF0ej+ST&-|Y2Cp5(oMkj_DNfXEKChU0@HuQ8bwv*q3PJj*uS}EcI^=8 z+@-n@-XI7jKp$NHUEt=h-?Dxm#U%4dQ1n?i>;!qA!5tc)+wIFRp zhq7^`L}Rjby*n_C6FhwQdVLR^PWa=keRH64!nvpUO#gTzJ$t_^Hrw;(uWP(69BTvm z$1hz!h|Uw`w!N!lYb83hkZPlNfnU7^>k{6h7385>OwwCF(799Srlh$>5A18{-n!{A zQj+1{o@*ipu*m!Q*5F~Hf77LD;n+4SMBL*WnKD2S0B`p{YfyW0Z0=_6EdB*#(<+t-p#G9w%c^8w-N}$$f;jmDb!r% z(h0ybu-2qyqBbVq+9LPn$dnO4p(tfyj$3k|h2AN?SE*pEDT*j}D=ShT~b{W5Qe(qYWRH>6s4la;;Nh#3{N>}FH& zUoi=^z{N@M+fcnWayl2LJz?}?&$6K0MmkRQY)k1Fl>687*b4>BzR7r zLw}h#S_!@}T5xpyuId@SQC&VXzmh1@U^&~5PCk8U@u-Ux%qBBgotK&D-nwyrN8A?j zPm|cOLXiuWA;hBhPU68WuRYfT>b)>LK9yj{t=BfIGCnA`onC_UkKdF8u~q2`GW9#w zu`pLu#JKe)UH{B9JNu(gRMvQF&h58F`XhZ@(Wr>f^oGK(-ibN1uYik9?7?uZ%Cb4} zv>o5NSF4hFtEScu4pvrhkXquvt~cP!$%E=YX*}nS?TmaPL7`*~B&wv5kiAx2p>3R1HF9&0FC`~`urzv^J_)OVl*r&h4zY&2=s6)PW{W~~$ zpaL9nvBB_^_GJbnF#_#t=q5RBq*qf4HQ`$+?zGLSv{o(5~HnA_pHbXCvWB*Ei+1 zkMq6radtDfx?XVzmSPnP%;-E;auO{YTPO^bPe~HGHhAr;E=|motw%^njr>q{lgID( z3IF9vZ>2=(t|mshJ<&y@iwj)e0BlGVMMb$I5=d3L#r0WPGIcyizkkeTa+c0Z<`Q>n zc>ik>5C{pbgV%Fs6y*6ZI+QOAFMq73Y56`6-MM=$PiZ+y9wqXk-Q<`ok zsAUL~l*O-2$l~qv*7Q=>h|Tt&txs!@JP#Y>KA&?KG+{t>j;o==&mB%S->kQ7;>9XG zT_i*rP3!1aW5G=Gf=bS>j|R3nVQhviGnRm1G(N`$>3FPN>wk+q@yawGhK!;aACXvz zxnU&XHlP>HVI{Yt*i<9&kzi~2Ao7QEL3&qRoTWZZ`q#Y~JIL zahU{6*DOii(gu`4F2~!GPJ^I_wQB*&h<8#_KcvBfT?)4RLvZvC^F3p5lCdKT3H9Jo zjtRZfr1+yRlI!iIIrUSzaXibgWb6SAw~+6*SEoirPTp(K;zfRRsb3;}+j1S$czQ^oMXs z$G?g>Cs|yMSZC>-m5*rZ7c;=x)F^S(-vvey{Ag1!Th93%6h&A%o){G+vD>iq%%gBl zys5=0*4*~&B)GPcQop!jp>`ihCC)^wlZxdl$@+}BUF1+1J7$IV7laucP!Qakyc zbT9%8$xfJ8YB>&j_X9~_+_@VZY5wMX-+58<*?qMG2Hs2bd-0a*vk6obN=r=GvYq2F*k|Lj*683==WO-~q{ zo8B9f@Zv(W_wQ%i`FWzaUmP#*+AW2wsAZPZB2#8CQ@@ILC+2>m?9t5KleAjL0k^%E zF>#SSb(D$;%{UQTJ+s{aomPW>JV3TRmpJp;jq1vvK(d!X+-q2pRQzKSiGJ_*MIvym zc;~&jM?0yWDm5nK&z%2G&(kT65H5aR5|#5Ob|P)UkyLn6Q~GLYToYxPBD!|oqVmT$ zS^A|CM8i6-EF2BUA;ZkroU_f*t-ixU$7Vn|j@o3izpeS`p#cK@!8x|WVJnhzd7$c* zY5FZbMr-t(7{G&5Fa8@8)w1NbNq?#H&M`q+}!cBO|9x?8M>Kanr z8ztZQ&abrNw30sZvR{N^AxG@BzwaFDukThIFYb7|PIwn@VsZr5HGjMxMgB~5b@KTs zuM%H}%TR!l5O0^c?t61e9^=2n5gbk@2Cbc;HE9WU$VCIGOg5`hmzCUk%&A%Z|!69(OH8m=1j1@ZH&7&M3* zL;)ihNbcpr`|G~M66}!TL&^_xSZD_&Ok{0o$iBhk|NWUCzQl9t6?=qeNMrsvLe^+< z-mv5`>VGJ-{c&jp1P2Vm?f)m&Bp|r!$cGIeC+pe6P;u?@-2LeO*WVwX>LV)s2UP8` z7Pc3(Ms4`MH}D_?aE@W@*cusk#lNFhQzGcC3WyvhMM)>#MiLn<<2b8m(l`(aCn9It~fYrl`RAVy-LV04IU@)6XV038>LI(TYr4C0ApI~2jS$pND?8Q z%gl$^0WK8lNGI(#M3BsgpYh`!qO{u`#@9M;-i7z8Vb|+XKS<|J55BFBzUhZ&i#E8v zHf+?K&I?e5(<^`wb^RlVXEPOibEASz1?~$^G&-UqskCLG_@xM!Q~Y>Bb^a>v(?e_- zg%@Ru5PnJNu^v*O4Z*IV3z`|z*zIHZTSE%ax zF$AlpYw3&rk11#A!UufU`!{C*sUoiR^lnnhZV(4LFv{AL*w|x)-m`fUH{Pb@TEjOZ zx}JJ`JMFtR@$B;E=$V%*&Y)jd%Y(QqBYdwsz@$Q*!gVD5Q=P$n5hSzSZ6%7U#C z#L@#mo6>7e&yQx@&Q}i?DM1(ZXMJ0joC}eInt&VS-#7!g#-bzIX{PaZX)KWfAt_%B zpvVM{b$;^L|;K~M=uKU@%cfr?nS7)WjA1>HQ* zGMrtn8ic03;Zev7jN;0y84FVK=G=Y6+m(Ad|Me!WO16yT?yC@)expd<`@i%!B!$Gl zyDdK*gUuxJHozaf>f?Dx@U=$?n5Rd~9a@Ib_k9`vU5IiuNf!`jb zfx}VZ%^uj?#?gnX5=)uzz3roumedBC#!V=9I^+dYNst-!g z@aii@_x0BC-^Ju(&%Q}&JUPns_JM2F#WV|Nw-ur^^}_SEsGkSLclc1asfcPJj+^<8ZZa6l}cC$GAXn6->Qk z{|+33xa0g3&Tkc$nrd+H1Dj*JW%e}@ZuA{c_lyA1YEvmYgOK{8(Hg8`-JtKL8o~hq zLFsjMM0}KCc@O$OT%YL`iM?TZ>EjjO(+;#VH^-wdN_cnSrMIrSLPs>$#Bst@>TL#Ip&ek={d{+|f(p>z?2>23TG&IQ zPiKjSvF%%L_`tdEuQQzv`c@sKFz)3($6rm;q;+*EoY(2Jn?0&ySs$#Ze0sw~RF$Do zQgTAY1e_*ABM}EuBMJP+s}$GA29-jcG;L|am!Fy9jdT|EN^SC+)hPbn zV~7fyQa?#WVLTfwkQ480&Z_3W?D8%wE#>rg2FP3psvz|mgk1qOtB6}Eyl+mCta5Uu zJwj^9b_N$0JF1`JqP?;p8r1P*elPt)iP3i4VFo*02Y1`{AL#TA|9L+Fy&u=#yfgnA zTxMK|<+VI<63Bys+}b{U`vx*Chy+pOBvasIrxn8zT2YsD*CBqVfs?KtT4_#c@s0os ziLHT^Pja{#O2*%fRXLnC!6BClyrvd9$!XKt4|uru%tUpX+YLOYmqAWRuOmf_XQHGv zy}$k7#ze`J@b#md@mXA_+bBtJJG(gj=DzyQ+`18Pa~y^?zDK5I3ASEU=9FlUVcd=JNKJK6S?l z3;L;Rcg|}W6r;J8bm9)lxqPRuaX&~nnlL#ko>}@(A-uDn_I`?Ng^|;9*ZTf=hZ7Ra40~hK?;=jqF--1p zewKOXUetVGp@O_+qNz+STr9S^;1V(+#nZ>EP1%ZsToL%pm82g&sQj$YrzLkLgY6mT zegN68TLk3AION64?>`h?_lo8B-M&8XQ+}Y%kR~uFM6o&Hk!8{8Y_i2U=FI!w_Oxlp zj`2Ant+tjC1k1JdI(~kB^}m17&;3I-0;kibWZ}8Eykn7kp+rVbS75HLE98bt<>ab= z%`Q&+(oS4A70^Yr%_pMH#b;}0U!?cLX38ky!K3SB{qyF|!c)@1R- zTx9i}9Q)pdb{pWe%-@p?={pCd*<83UI}}3~$p>?^d@G*5yrzw6Xg`W$Xkb9o3g)Lq zuibz=BPuOD9(&3b-~AnwauyY@1cf8+9YByHCx^>xlBY znUt2FGdxhJpJ@t`9y@8{mTYWnwfOhJ6f!Kl!+P`PSXBdLl^?+*feu_q6^ou=_Ob!9 z6#yP{t@U-0pdFKvZfu{7B1s)j>% zItxsm7}q^;UR-niyEVx~CB>wqh^PIFCcV(Ce_25Gcez94+qYymxVZDXv9@FiIHmzt z1r|m*a}fz%xC*z2r8KTlqXk6~Lhf4=iM2!mgT(Zx0++5B9#{TR(A{41ls#U_P*G7~ z^`XeBEIv*Cy8Y~H6iDdERkH`X`d|`6p_r8E9~~Vn22XrvPmlKhG~#bY6+#bQ0X|q| z8_ZTxD{~?(3<@*|ChHS<(|j?en>gEh#0Ajsu!m2se5h_lG~QyGd7aHi-1|@MT^QDn zlu9_T^`yDOPU~&--xPNNeu|(UC3+=v-Ts?1XRpO>3D%3*e8xS^2(7<$A+3G6+?5!NZV^C_~#APDNj+8MyzulUD(G#7~T@F-2 z)6fXA-y(Tl0y3Mgf<~22gJ%yw$~R*65qioRCMNZX9G-{|V0H(T`KC-3h{oZTjaIwz zK?}Bh;!Q6^Nne9x9qr}i<=iT>Vh}$zEIB>Ja4epWo$T&>$vHhcnAk9WcAw||SY`ku zud&);;Zhc{f9vEjwX&wC)itA3US9t3m0JMK!SOBP^(CrjRQ!54M1)*5}_t)xHL){2p~jp?JAnV1U%-(=8bC;6-%D3oa88 zi}6HhsuHp(<-d7xqW)LPqPN#Am;ieFo>k`z!IW;ES5fuA z^7}tNSHx)y&u2rh=@khG*i_Uua#hvThN^i8_D8Vl+b>;<`j~@#P0;>v79OeX+G`2{ zPaoC=#Kg^=Y{bMHYPk?V^NOvX5Vy#4zNq)&6j~V>M}B;~^%%iPPE3c>X@yqeyxkr5 zB2>xMNm8#U@7%%L@|RfWe9gQMh9;EihR5mRRlkSaVDqi9`cAIx5{Klvc5ONLm+gg$ zwZJkdvv6eHT$ElI*k6c7s9Zw9$N2R2)aWtdv91m3wb zXVHI^GXC*=2+Ko7U52o`EVP~-$7;)cTG(hj)(?d`H3UiftiHi)5A4%Z;tA39CUcQ{ zL$*Xj6>3xg5S5K*f_|FnOC3n|BQa~(X@eB&?`GmkWUbMbhbd=A{HZK>J70r?E;nH? z>JdvWi>S?8TQCCtZttyW`^SJAFWtyv+ADf4?x!zKaKud$;p-5}0jl5}FF1ND2O z2sEW0!|;B<$pHgK%nkqzT8#pv%^d;Tj>#8zMlMoIGevr|X$Ux@0ot4j`Q%rTAlR$_ZXY<2a+UsB~z|G!pZeUS!J{c#! zvanc(kd?k~t2Wx!n-P9IhzghHyJ>Bx3Fj3Wx&=)hX6A>DWC8y7+!#;Pk-?Idm|wq$ zf0tAHvuQHkW^%-)Y136KXe{;9y%C2U%YkXGD^bJ!R2u0(xZ zJOQjLCOYS?6dN0I&ya8TO|5=XG@J*DJDb1lzA8kU$6cR;f2E=$^<2cTGj8scDK*kK zRsPjtP|&5s+rvGWdwWaDH9X`^Y@(*0H%OmJRHXPd$P^AMvu?BL zQVC6=^s*L`z)cpDXgob#*h`9){D$?jn1Y(9f+mV#LGy~0CWFPN#r5MX zI$W7+AEBZ3dvA(>-|L^L(7pLT>VCr2T$0xhic%{q`ln4kZP$6P$DkJ$tlp=l78;d5 z|JXh$O-8)9=61)oIMsT3{)fJ8$$2BQfr&oJpcu!(E^Vv(7R6gl=d31u5^0qR{cj`% zR7mC2sa@~A*a`Ov^NrSy(~=3_BjzAR^!R;3n}}0iF9e20e)h-OHDX*`<(HRU%bv8o zy?^!Xy*3rPhYCF5UumT`NU-8uhaURX_h&^TDZYGeV%-YXF;D;S$40b7oXLd;Dc&Jb zaf-RAEKe)q?@hHe?A<+7r#z5hQkz0ol7Sr?^7kuEq1>a&B7L0(^b*_tcWs6B7WbMz zPFXz2TbF0x3bNU7$fFTRES%FQ1@6E6|NS)q(SJTfK*lPsfxx-=3I06*#L55taHaH5 zGpa^lA7S^-{M9j(9^JL>O9a(3t!uC+BJbr87R)Eg^;OP-mo`^7aYK;0 zSg-19xr!A$=43#e^hJjzFSG&@xA z^;q8sRl!muV02^nOfGCC^0B-sA!O1)7YnV&?+}+)onuE3>9EO;8Qzpef~BLL>}_o_ zUrO@_++3s9{nQC8L}N4$wzI_C+a+nvY_1vj3DFoh^bvu+MC0Ila#r*0u_ygcPDIWi z+J$t#O%Q>=6YxHXD^JwP&4l3tz!fgPf%B=lk`fL8#O$jWUz3S!0Fv!iCP~PjznOM| zk5ns&+%zauv)V+~z&mjT2I2W&r#2*}6-twokvZLyUxczD^1`W<0srpZeeH3pF6K_n(xZfileqY}nLyoNYh~LO`Z1Ac?z4RTkQ&xI6-qMCkne)r-fnyYr*75ZIlTisW^?!mWh>&foPw&*2A(Jc z%YE0GA2h`-ZCVBXL!++h`Ne-vQ#G?G(WPo!-BKMDEwfH%es?%$?Uk|R6LoqulXZN> z_}$jAS$_x!+|R=*ClCREvh!0I5{|Malp)NzH^$Sk(d<+VJDv0 zMihkQRcEr=L*WD#?k!B~)Ob0niYu?+kTW>5r;k1G$Cns~`bn-Y7YjquF{O_){Wo2BjP(?y4rVnHUgP&y9CshzSa{CVvq{Ivo_uj?EQb}xvdCnpj z5tVPe9nV}j4yRZoriN_A?4Q>&{@;fU#-@=ZZ}lUT&Mn$F@%3|+#%eD*8sG_RiMOX|t%6c)n z7K7nM>f~yVWh{HDPj4-=SuoOXrn~WGE6v46z~ic+)Xplx&WJEV)ftae`(8_(LSH`nCjf-M&p1h@4X$E&RhnB|xn)vCSfY~l z7i*_9opy1gcW#eL@aW0@0h0**ANyps_a1@^)9?oCN`lYHsER!1-@KO5e)fQ-lz=E@ zq3k{ntBa4AH_V+;ue0rQL9e9*U?lpJKv=lw6lFh4*w}Q zo0v>lLvIO2>K~VXeB{63-a@y)p)RK7kJ;f~}us9rUo?qaK^^!%wwDCg72hNCedKr(RLciN3B_+35#2p5P217_g=f}&-A9`Duyz+EE zaGy?d-=3NTga`8)cnt&)AZTp3r@46J;%4Krp`&Ed-dte_~cv@XSUM7@2c z(f3h+?4NPO`g;UWt7BW*Z{@5`vEhjjVuR{<^S2nI^b1-Y=}U2$fYWUn4dJp?qpq1g z*Wlv0Jwh^qxYFc1DR7%hV1Inq{o46Dzl`s7ScKpWRLd~&|I*n_k?Oa9IYo^w)c=O* z^P!x5yzIwB?^FUqLkR#kq>wdulPVkWy+J)!GB8ZpBFuDw6oE3`XF2u#g)&-bs4F1pi%MRRq2pV0 zolZ6JxqlR|Olp&|a;U5FK`4+NhgivmMuPHTUAczVkQ=U`m}2g)--sDVNf*O<>oU$= zXjt(Emu#*+zeEQP1OiV*>0>dB%jQR*{cOG4HHBFGs_dvSikyB6{hH`x3F!9KXkN*-1j_VGX#Rp&{OVpxTpc*_IV-k^<*QJ@#9W3yKIuB@ix_SV{)Y}5#)=bBxvpI# zX=`q+ZkB0oBOyb0vq4~AtpD9*263?M-_F+wfz+}_IxMt7{++XBuS;DK@R>td8wkJ7 zg#AB#3GfbCfn=8v8{-vGz?+Gwho~E*eGj964;RR%ya2xOeLL>6YGak8&R@<^UXsXpD zt_dPy{@5Gd2dgIn5fl_OdNwJs%Xf7|@1jw8{d$ks6r7;SKi!<)+`LKgXS}N0W-{}# z#?uAg?I%>RMPnQLE@e#OiA?c=CT}H{KYDqQ;y5;M2H_QOhqndzP1e{cQj!<(2ff1e z8?9hD_t|tUqLg&`$Nz@;hzjcGAQdGi$9NCQGmDUbZEXPgz zet*$hWFa?33uOKMCdWD0)q)?o?7sV)faWvNK_1#ROi)l(5`B)~(yJ*W5Pp;_?8!a* z%P*-0UlzEu6*>d=uy!W32WFiPGlecfdw>IB zo7d2ZoWPftv29)e6v-#*AZx|}`~TGf1O;7yZqT3DzZ4abA;6e|kdYK2ykahrcWk9K z7D0C-4%{MM{tfe+YfBYmQ(A9|9Qw@X4N-TdP4b<$TSq_!q>#`>Uf4eZI0YoM4}>G` zxM-y2%O6+Z`8ndXmhdZDY3glK5+iA`YL5#?X3hMorLe&={JIia*D*npB%N0+LOD;3 ziri|9JxxdW65<|tp~G zW<;fV=Q8I^yV;1H4Xm*i4>wIED|_-ZeD3#J?2&;WMO_@`=b6c?rk{yP)LJLhir9X_TU%q?#^yw>(bMR`kmOY!lHC5hxU8(VDZKj+I7XJM%vMCA1 zw(&mX3%V~dvJCxyC_H<6NGMIOm)+;I5MD+i(A_kGqU%-S)KX-W0ft#*9=ym135pO+ zqBtxPa9faJ`RuupFefLyjw{YLqF~*(EPQ@ND>&uA$jx_akgs)-a~)-RMM>@Bw8X;d z)`8m;%lh=-URUdjXT;}2?=3!XOoJ_Nr1hdVS2~%&F$8tf$FDttZWR+zF?%o_zK~An zF>ks(R~PGfh%()1uYGi{@}E7k?Mtszt3-Ie2Q--jd#vT2myT_25g{O7b3YSJXvlhO zc*(IC^{`ML8y9U(J472nCXC}&gUz2=RNBiqz|p|m{ zl8_RYn%soZ75ex%VJou_E~8{v@S^Wa<`zpcs@6+%=pU$G#m2L$6MttkPYTNwG>}O? zss#ga90;A&@3G(<3xStsnuvkvQ8Y?WhpmJn?d-CL^+!CY=DFlfxC)9!iu{f)kqMtJ z0=@^0Bn;ggAk4QgRO})fB~5O+GE5ZCzWY>3sg;$p{Q7fkDaNVet2wy> zxIp;d{V!VPuOKKzWYz*>6;AO1r14ZcxfpF?nSCp-wisk4oT-$%?*o` z&3h(SNg$?noqq^to`!$HeAb5_bwHS6h|79;xbX~gvW-Ll+vYK7nT$_XGNP*a@7!8o zVPL4S2Ny{?lz5*2+dNaXoRR^Kc3L%_Nr!L!%rOJ0rxi<|=v`0n6Ub=Qb`Ll`+=HF~ z?B#P>8am$Y9Nf70l?O12EQntgCIK=K;^!!*2d=yrVoCM8*eSI93O>MB4}W%V1?#P(%iPx-t#O-3MfTv9rU1Bs=$HG^u$X7mGo$;T zw|^g0eyi#$UA$S&`?qGh_Jsd+gMegIVZ+MOKytKKa!V73EGu=}@sl%e4nHmRs|Xyc zGj9eP*#5B)Q^RsIM$6OHu6BC-)G={!&9hEvPrBp2=H)3t2;Ta5tekngsdTum$w=A~ z)=uxIS)oxTy-I$DZNUdEpB4?-xN!V->?`Cj5!m3Oz%lBkCqP z`r1szzTA^7MU_v;J2-jW(ouzSKFluDU5(8lCv)HXna*q*pdj=Re8Q`79X}MuW83&M zrj}ItP9MJK-m|x_1b0d>$eEE`VOpyke+9OHM*??8c*ym>5{gCOxN)MTB8s$)+DKW3 z%$6bwDy)7|Q&SIkS+HI#?NYv$4~SWAC0%?cJtDOqFW)=>SBCWpXgFBkselB)AKX^I zxic4gj(pYgzmv8~lfhm8hDmPqI@?vaRfT~3q^I@AYq@N0(hXD(0KVWrk!6QW!WWwP zJB#fUb#(5!_1I@R^HQZ#W4VB_A}kqy!sO;Rix(6^tuo94aZC$6=vf@jsQTn2iCyBJ zvbnA<`{~bYwFTBPQ4DWSC)>;*$-LE8*0<3hLQv6l|cJgOplz#jFx@-#W@rP1msTB}*^4I}(o4JMYaVGDW?cNt&l65&|2Ph0}C2JwB-*T4H_L zmrCB|rCmekbmIPYing?M6K_Lj_f4KPpwqzDZ8R*`T~g41;YFktdJr~HZY${7JsmKu z)C=6TdwPW}I<0z*NQv10!z_*8Qr`K${#nUKFPYtPsYHq?@m|qQ+mf)}6KfLOUH-lO zF3Y6l7}Y?^ap~JOebn?DmR7i>ctd`Oq9Qx;@}#lLL!(H~`y2d{$layEi(>BZy&U4l zO1a)iOD|TV!6oeMpf|#4cb>oMNe}t)Jg{~_Mx6iVs|R6(HtfhEB&Ea0LJ+OLsG3;6 zS+7^)c73?Ocs#F(k(n9u0|foIIoR2Oh(pH26bV8@GR26dBvHw50PLh<^#;nL-ebK| z$6TDt-yfT-_u45#$cIg}9{;UnPamN9UFJt2R)C)PK012js039IV`TSs^So=CMxHB< zT|j_jVhw$~mkx`y9N)=ImHYHv`)70(90s$8VfR0j%3Oj4gp;gfseT#b>wYuf+DvaF zxN3e|!Pg>-*pCh^*Qn7~e)jr{);MioNT-u&q0+=isbDLynb1wARa+{eZ`0Y$ino0* zucR`r5Hb}uKY#b?#huHzlrL^@LvY9w1hV<|=1Q^?@`PmnHV6nE*QY1vbd}oW746Yy zQAfRO|IQdD^HJ{MsnTx$4$Vi(d~!Cb_>hR7)n!_A**Q6iN=kv-PBT$TDMkJB~G zzyj+RbB%}@?AFtskdUqgcbP9LA|mikMiVT!`#QP%O=cLD-nr$t?xRGq4@pUCFRO(` zX`zR}SiHx^%}j-t4|*%+T0kUcKoE~T$oxgL9_}^(U{AhR^xg!6Jz72N)vTi~U`FpCL^h)vYyr z4}tyrZpgepK67K?)7SkaE`50On{d4&5VvMP>4eGKcqM!!XTFr1YTg=p1;{LWIX1Yt z3X)eFQ_CIH*eGH`4euV;sv@!F;h`SZbk#o!|M!i^$$CIjl`Z-^8C_Eio;W9Yn7Af8 z;c<_1f#17Hg3-tVVvje6XU5@eRmXkIauKB+q#WYn)QgLY$SWwT=Z1QooOgHIevI7e z@b~?l_PxewHo&ezF0svr>FDJ4DWmlP>1BfxBtrjBK=|R!T{%vA}6N9&>5Z`M9Btn(6cE(wd`Lj|E;_nYqj01! zEruHB1chTsXeRW16|aesnYkW>r2@~tB%Ohxk%1`9rMp))Qat?TXTRE2j7iM##eDwttbh*6+9IuVs`vnU>pm&RDX3g2{Tjj|?}qe(2_0j5j| zACT1Sx$rXRrZ#{3oQC;mr ze7SVpdHn)AM2tu^&Jm@zr!MuD5&3jmO@;Dw;w*|o+g;+E>GNa4$}m-g;B7u(;YTVP z|DEDsVLBQK)c<#q^Z%Li@crL85Bq-kz+Vkqs=)7tRxY?9nj$oBG#f?wL} zm0GKdCVA6KI$g>!tcLR&z#Rs__CpA#ybH_6Pv-zo=nTGtVc+xK1IRhbflRy%>$Rcm ztq?IF)m_#joT0oR$QC@#GA+3{Po|z1e&27DcK4erl!<*n68jP2jL`s96IU%i>s&JatF ztd;hwzLXBi+dhstt@hV8-oQ<^0J8FkEMyNH2JAkUcmn7pyu$Zh0qQk=bAGX+ zUW!cWxW5Evj-Nn8P5b5zK!@m*l->(Y{NJopKgHG62lC1>jcb1I8?Jr$!nF%eoRzh; zrXz(7tMqNL5ygY6eLYksi9Y7I)EzP& z1Qq4y8Vla)IAcSp@>EWa`D_j>S7D+#^10hDUDY!if#0di=$M-b9Hg*oQ*H#;AteMlU{hdU`qu7{#jq)J~7% zIA1c;`o|8eYb@Z-^?y>H;TTLlMVi6<&T!3m_7Pm;3UK_8!|ZI)?wiM({#ZWUxnlgJ za`WL*A~go~woCIV%f1i6a|bUn4!oN8KnOWP<9^xniJ+`(GH%j%9&AP`L5*uYoabCr zh&Oq#0UAHKHkp476*l}t0moBw_Y?8gfH4mk5e?xe1m90r0U?O9y@x~-{5?RaJnFgy zl}#;GJFG?$;9=ztHvd3(!#WLswlIQytHMbZ-Ui>`7m)P>oKKVcpS(WK#6Sx95Sijz z5Xit5^Y%hY0F45WEmdJMu6%j@<$FW@b?phxEzAb=p&!GgHDE1z{|$b&f)gw!Oetap z(zq=J>;94h`_Xg%is|7}qGLOw)JyILSdhS9C@Lx%bHS}e^L-a#-8HTExkNc6bStF`0?0qNJ6lop$#fm#TPFI&7**K_6)%)CbnPg zXL$bcg;G^smj>z^?mc}JcdDGaOY2l&jj)-QObG-yj}swYeRk{wp7OJ0`2?qQ#dY>IqE$JI;P zx$F46Br+&1{5kyH%efLyV zKPB{8m=|KG0`u`0dy{qO-Z35f5_4(_^S_~%^hg&p(JyELonL6hlV4b;j}bDmNQ?mn z%6ZWbTMnkXYc1pod!n##z6S*xx_;wO!=|N3<4KHPNS zQoMcp3N>{w;3<{v+$jP4u^I$1Fr!YLM_l1F3(|=ogZwX%8#+{$Wd@Ice+t=tot-M3 zRwARDZW^kyPLgJ22Ii$>Ffl*v65OFGQB_xO+ayc)6HB%tD0!822D4w-KJKvg{o8SE zVxyI}!THu}E7tGmlwp+CYaY{GnlL3%c6KZ$uAwW4A&5qSMFqseL@V_-EmircEt>*x zC10+PVM0&#wg;zCP~*3Rkm94ABwMQPAb^H^I~TG=lr&V0yTnsn=lG^g!=Ak=tiU|Q zjE7#vf1VceX*$C1gTxDF!k3etX{u;jH?A|kCwD_Hdo^yIj_@P0X}Rl%v1$Y_J6ZYZ z3jj%x46gnAc@(2h9twT;Y9l-Y@$1vFaJB)Ep(3d00;r>x*#u_}kD*q}Ugm?-`=SnR zWj+DHH;RzS9wvbsHz=U5>iDxza`)lAdjJU~LYRS!T0JZb_-i84j3i)~fBg8dJY)<& z6byVb6Ou0+$$+mK(%h)S+hQq)IK!?409Lz!vRs-D7;g4EFFJtK8?%*q)S4t~iAjm` zb}9K+=j(p4Oo9;jYt;oUrFL21%_&`Q`u;_*{`Y5>fy4Cga|45)s(VR5mI1M+g2 zi%iQ9nUp{eagxob!}nO;WP_)Y9HEwatFF=nS>$uHc&r1Yd&e^Py)t0ewmjAU;$eTH zO-7dIUW$2I>lkQbaJgQ_tj(oQHsr~4gD>9_)s-w9nZqQeAxgp(87{_8fNIG9s`GZ=%-?8<)IZ>k8*c|7EN2!UEFcO$a+iN9=?xS_x{4pGTPnWtYPW`3#J>2#tF4+d4Jye3qpJ zTAbdV*V5F~EI+)FjOZOb|Hk${m|BjTTBZWwY-u=M5}*(G=gXo#2A4YX5cdf;NQmfg z=O`mi_T31ab`MHu7_`YGN%KBLEy|fSqStqkr_TMJ@7>5c$Fx$G@LtxM9334gM7vjT zVVr}WNJ=;ZF*(I!ju7$o#YkmpZt6GsmOntPmn-;XTgpU&560H#;)#4)j^c^N_lc`o z8=+pe_54foJ~>%^y$*5t*d7pG?u@V(*VbxFNaHu&;GbFd6m>Pp*BPYZ)3IUp-VpYI zR0*W4OW$I}#BwBqgzZ51uMcZ21I!R0DT~6$)SqKc?u?&+O71@%o|9AAXV1n&uiJ~Z zNAM^d|6E=_ixwdd8`5%`O;lL2vJ|uI?*MB2@EzsEZ$MPE=_{1BV^n=ry`MmK)X)rfp~k95wuu z-Nc=`D?VDP@^|jweUxxyz8rYUz=^1qb+7m=kE%mN@@~-x7&-CS_*}kxps~1r(BoK; zlbxLo$Ahhf^PDydg?sl1r65Xx>z-KTjl=AZ-(S?5BW?_(Ud)?Vy<`f&_pSvpo&n}UN>DICi;oF0~&CVfYahQjX z{bjV|QwEtaa;Db!KVC2BZvC9>@qf*nYZ*eVK|=Kcc|eQT(m&Dx@~8 z;QW9ae?tP+$wm(IcM|k22l(`OHa{j=RA?LPYV)ogiMkdP8(s~}O8|_10=(7ZpEY^- zsV{A~NrU$o0s%nG@pfr>pcHVZ_O`aXV^uEKdcJ>GfXBJA8sxo;Rc04)*Dsp`3Bes; zSNeTAdSN%2=;K4j38=SG$g<`fZfpu-hnn zj+YWOV#na)KyrivW?s`;>GQ1$!|EzsEMn>e&CcO`!{zw>!UvlMyMLa2>*>6S@4iL% zCsnQ5d#X-SE2j|-3~8F#tgHmg2!u_u!eUED=}zP~7a_6;6zyIMqHfoEpIw z)^HDMH~bX4d^07`E){m#v0}@R-GR*e^q}GjY4JbVs(Ba-r`4T3W`F}gK}{^tf=`)H z)qfLFe`~K;a=o;Lf&5LXvUR0+b8g@g$EK9G5ES%ZXmSHlg0;)7Fey4*3_ zGvhJiRxqrn_C_4x}%c9AhyzaO;DHQ+BVKU)VSSRUwdCyhU@{MPGN7ETl;B|EP7zC@ZshVED-MEcuG8+dVlpkz3l<ZDDm?W;u4*T6*9&IK_ zAW8c0;R9(@jyJMP3j#@SApXa|ymr#_qSb?;`Lo-NdzpSKQUdS&xT;B0Hzi_<_7Kk* z#qw3AKr;!%LGX{(h?wV;G4n*+s`Iq-dA&itTk<^L0qROb*#mvdI5HxXcjQ~CY5TL^ zbRlb>w674pV!eEM-jkd}})1Nj|rX1#1x z!hfk|k_5g1bqj=-@YxnKp$Y2a$G&owJ9pU<&^NulzrUK-F#)(z1IP=&`G)X?4_x-^ zThv7Lk*a6niBjV{iMlzt?P*&xDJ9M%8mG;UnfNTajh2BEP&< z3fC~?3Hme~$b47l84<-&b_5$!S)}269LT{Ae9YSh6fmRD*Wal$3K4T>LYzm@_$JWa zDt(SbMCsKt40&%5V*|Dfx^8BNJG0OXxKQ4BCSk$h3r2ZP8>7M>daN6WZagb9$W-AR z0NE+@UOwgJZDa%Ja-?fj!{wG7aQCk;BFZ${3cuM+?gmPo3qf0pn|E(1Lf@7>xDmV z`5vd`Z^*HmW6UJ+izOS9GvEE>eik-tlirR zvFVW9nXT#GyQ`kaRM$Z53A6c`1klvppbkfC2SVhhd#39mBWsX1U zD*9OrKA*BO-u`{fgzNdib`2%YEjGj!${Vx)7csFaq^rw)SC7Q5ONnHHg7D>rJlh&a zQ009ZmFw1eewD=cBWc-nuv{?9^wy`PygD1QjEz;xaDE8?`js1)X|M{ZWNL=CS;YT> z+U=31W&l)|psau}?k@{B8A%xB{1_or<~B&^7hc?iLojTtP#8nK=Z86Z3e_oQCih131cX|0?4Unp^EiDq;h9mg~8)5I2z^pp=f z2G*MCokh+@-<9Kd_&h-!3dm$a{mx5nwHbQC~N>=#;@pE=Yy*MccnR ze`&zY!m8v1NWZ|qzzgw$&959P3row3b2zm7!0=wBh!e>}nG%P3_AGk|^jRwtRX5rr z8A8Al2Zu%rsDUm>_IIsIKe}&P5vzL4qIvluQeWb&&w?{P zoc!tNl=h+Z3?a?fAAE?7cwSyD>mM->R_lbs#Bd(1FGj?qq)$PEMs$gY=mJp>=UP@a zwkAQ(ZI)ZF+(|LPW!v>HAM=a&I}gom# z>0}X${zs*6(c+|v@=Ta|Y4%C3a3NZ-u-SECSc7h7L`#8QdTW(x<`t~Jiy#aX1qxLp zvy0pa&6J zcL;oZq;Ge7+va0%6c%gr_lwAdBnUGCZ49sr6oF?5CrL18lZGi_Wk3GCU_zASj@H8B z&g2Go`pcK1bMx~TQDYFu0;*?dfv98-;PH{xs`E`GLfzj3o!Os|k|%RG^9szYpKRw^ z!*U?W3pUw{%s{0_kNV9JwR40pkg2(!YfCm+CP@B%Ic+)cXhqnZS?bmfci!XH@ALaU z>n<#!ApV=(($;=>`UCD$(aTj$2z2=y^VCG%k}Pbo>+1@0!tiGBvriUYXdw%qzhQVT zav0i+@Au;clp)FQuxqdAbT#g}p^#N48AN6`a3GH0%Hdu3j5?xNLcUu;4NY<9Pi*}D z$&=cHJ)S(z`Jl$9E%Mp z6bj&^j`fk7{!Z{E6Sg2^lgqh;ZBTXF(AiZK&}bc!@v-aQlb-p5J0mV8#-_5zm|mKi zpchs$P_n8+3sGA&Q*(T@_)b{voCt}Ln7N_~!9Qc`{_+OmwGCUg6L`U zDBH?NxLb)g#74-*0tdDVa9|ZQs`a=6Qz}JR8q)_?opxpvbor-sYg5SPcCnmxxic@e zBoMVnLjR_SA0Ry>VM=obR~tL9FTzn^69UT+;?JKyy#MtF5YvmQxWfOV=VB-^vJOYV zZVc4vW^_EiuX1H5`(V+&!+9O5_mWl=Nkh8y$z%%G^aXcj7le4KJ39+Q*9d*#xrIb+ zH|R*g>vZ)cR2Tn_J#Vmyh>-6Sz0TnI_`;Le!s4XaHd{e?(Oi$ex?eoeoE0qrmR({5 zcb(hi{asF{@xNbqz`HG&4HL!=03clyatJeUc(C<$celVQ(D83|@M)Hu@6orZ&^B+s zHbaz_iqvgfalcZ0Iu_qZ`%BAd_s6LC2TgCkd>Qc;$0MY1a&!B-X=XnoqHnam z5IVyFbvS|=wSMR8yo#OnV^hrc&*&GB9=zC1MwkxWn-})-xVShVYT8A2Bw$0e0j-os zlR{lj>A3gr2Ubd@HJ>O(#6#U?LvG;i zSlioQf8pX{+_eBjtmXdI!g^FDcv-9-eh_L>#sI1kyVP^fnme{D4Dl*9+A0DBE{n41*wl31row3oA{>+WnjbGgTMP{;bCSsspSe8)T@zU3q+G(=Y@Ah}O zpC6>|o~DdpmN%KbC98Ybuy#%O+XoMr|Jjm_Yf%K+$t3O-LKcl~^qkkoDE zClcDWFps!k2)55UL3c442EF$zg=is87axKKWjfv8to=;KrX7Ag*K+i={snzr3tn_R zW4zxn$*>gDwL%J(#o*g&Y7xOt^y9N!V1T#)Oy{rH?5X9GDgy4N6pgDFjT37GmIoVM zxs2vUjzS_P{X7>bq@phpaeLM+!yA4)_B6F0hGWNtsI&EPIOM7&Nxs{|Td8Awi!L`YHR2`gPn5I`N(Tqc8f$k*#a8`M&kTD9c?U6TgqtwWlG{(|e_Y50#1* zs$RJqp>|iEa*`dOV942B;>bVM$K>8HOyjdidPu>n!5jM<+~<0WCQ0q%#qv&Y3Yr0) zzQfGgfm>exwtEf!q@psxHFTtA(vW^JCJ)z?nY*cPIY+|+i?@d)>4t_;nFej1xVF|p z+x4DOgM1i&UECBeFjEz-C|g1*vq1BbN{w*y62T;d4ce9kkOjax{0Zi~@q(szw6&=q z{sRY$EYL(R)-#&^69k!R+F(U{!y@-)yWyM}5Zk|=!=rTo34(B<-f6@pO@lR_Ylq*8 zf`K8CoQ5f^>yzo9lir6;r!~JMkBspIFqL#7!HWx2C+|6^!^@nVopZngb%ExDz>0q8 zie}cZYitvm4Hue5rO0|8pW5r(zigY+r^rsI9KN!Z@UzJ6t%_o7pwO!-yXM@z^rH>B zh*gJ~n5FfdN%v`mbd5A%60ZzpQ>?Y%yCpw(3X!+ZAo}}*i0#nV>pmwACR6V4=e2~s zdleCOb~4l7&>Qq_^pS~9kmtjO;3xME(ongLu?vtDFjz6|XQ+YYK%v~o;E-5{aM;fY zkS7>5CH85_man7`bKkK3?o!d5Ix5Nl#oXjf-HC8LbxqB+ro_AHRi4PL6hvQx&lP6o z0!ZKcW($}4KQ)0>O^vaf*IyfLk3*L3-C8EQ0jZdv9IuLJVd=sm6D(Ji4R2!8Wxh4s zSRvyIexrG6T{QnPnQ7CYEp70OgCVv}|7=3D0TM>j9H;AluD<+QP;kf9Rjj$CMc8A< zOfO$YR~_9>kf_D=T$}-*3Mwk-?^cSi;exFmbjWXDvE=0BgcEknf|!nOqZUtic(|4; z=yObJE3*4*x@%K)yLTHbvU^mFKw*D=vP-DO3G7&r?d|el|Ec;| zQli!XJQnU4Ki~&8H=xiw;!JRGo1~sGH8ecq|G6~uc;*AD$`z89%A*K)AaM!&KY zc;<>Fa%nARr*<2oH}u6p9S}=mTL5eeTp4tYjU&Lx>NTJv2mY>kG7L~_wxF9UA#tC` zA2m-n87rGF?{c}g=;)e;96CMfa7l>oS|fPc$8-ZKpnSk+00j^sf_0wl@0eAvTMYrq z8)tW0e($=B3s_UJek(z&;by<~3(Z3yUR|QSA2TU_q}?-}^QMJPEwq$F$7`p@@`-2N zF`6lC-hE~UfDs?6?6Oy>74*jr-hW$wEpxafrM5pxjKCF^rA*4TqkLtH8KTP8H7kJG zdyj~lG|%NX*3Tx^CmDJW7$a~90w8HDz(o`)$2wd^nnqX6%Z)&+fgRYZ$AQ}sH_JRe zK}5&>$jbaKyQ`!2fuwVXE9y`v`D> ze0!Gn)1cn#nq|No8Fi^O3k3Cu*UXY308L)Lx8S{bS9v$wrUvu_3;{$=03Ly{+iDZ6 zm-4_V`6B>4DFNzt8*9hJ$r*LxQ9Ttm={&Q`Ro#HYlTRXKv#?D}Hw5#p?KGb?J0||9 zt=^R~5bo#3P5?;RDxgaTGmG8Ocehk=M1Zs`))Z*})EH6QVP`=Nl^ zhRtgSpIK37W`!3SsPOn`p6ysBj%$jUsV7;vM7$&Vu7hKkK_2N$TN+LO;n3!ZxD=En z?%j?GL9-D^127H4do|0jKGSs&wnPa!{a-!iWj<|I8;yCh>`tZd<|!H2gfWAyLyIs02E-%t*DNbOXrpAc$3eugJ8J zEaMCTP6H)C#fg&dTkWK1M0Dhr3zBh{k5a#v50)bx%IB7EpJZYw68K` zG}C*vCt$JeN}%_Mi;7D6axVrf!Y~+%y7V53i0N(j( zoYiXf1V#5fW}DLh1V_nZRwD}_d*G!HuwMHI*}0TfNh z)C)s7{V>wVqq$T`ZS^d#nG2?E>mIKY1j4_Svl58rWUhZ*SfO?BO@1F*R5i?cNcE)d zu_8r`XTmmDyWL;D55B(NYg~$>HSVr^z0^?yR&q{YYWLnr0IgPl)>Qm%*|7-)OOf5$ zVBVl}ONU1g_^^D9hq?s;0)0@xqmD1e4LkpKR;_3)a$8{zCWYBpYm@xI%DAnhIw$&>nUoA0N#SH2~tg6u+^ zm8}&rFLql_OaS@~fpv4Q^zw_u`3b$O;>q02;B;_v%IZ6nw6L&%B)%uV?^T&JOB1C5 zLO&_Sky}1ONa@_hr|8nOxcw01s(#YbX!Ge z4)~ZT7#O_c?#KZJ3~tT=1Pp7ZoB(e(hm{n|22^yV&H)O3rjW11zVrAqjx{jpf;o9sJZd>_w3nC5X3$RbJ?Yjj9XU*T==`z?>|Rt z;kiu|8*n`Ov99D)$8Gz@WA|4_dj05$#6v8Y962%ZdoG6PdWIdd_a=#S38_5;_(vnYp&?eJvjb-Zi zhGD$_LQ)c&{q23h)!xjLt5&amUuR}Q5D^bjlIS68a5|=x@VU2X(7ruHp#Q0xh=L{$ z-JU5;L-}TeMD*Y1_`}2JZxV_A{0(+tLaIopK$MA^<)X-3$B9;t#$tl@?3tUpZUcXg zCcXM-ul%Y0-WT_>w$vS3SGn{@c$Zd;qB=UTMLpgP+Sn-UgyYl6kf0oRF|_Yq$G%Ip zQ0%^Qry_;)a6^l+s15;S8j+L-Cj|fYGDt{zAE9l_*@F_tFf3xXYqA#q=K$vH%L8_c zwjj%e)m2QOAOz{j>ma&!0ZR^e;llJREqUVNCTeY@Ku}UDQ`fYxJ#PO|sCwah>8ZM)!pIlTkDb|{ei9zt%93chzrWwPjl<~7 z7l6a(PDyk~r1SFi{QOf^A1*DsA1j?7v{jp*qZl@+wkNqJZFr*@QhJJyNnk*|->H6I zIM>CPffL)LDxcsM;590Jt;iHoSy^d&0Ys)#b(PNnihFif0{IhE8qYUJHHm3yH3LDQ zJCqB+x(-rp$q-;4_^icFyH5inveRJ<_9#cA;o}aqAhG$M8pENk9~FCNte=Sl0NtGQvSri?|-r{ zODIzpalGX2&%?Wrb`KKep=y5lw8{4JGxg;Gl`O{}T#h*MwI!S|477rdknL#dyAN6{ z`K<>PGw5Eb;KNccq?zG6zIJ{A0d^NY6o(syib2vkrkwJgo_wLNUftF>!0K*kbrrBL zl!q#+eT}u}e6I#r5h)xzJgf;a*J3H>A7BjZ<^-~AgKd-X zfEyz`CR!c!rdUAaFTnfG~6Ob|-0s472>7`DG`VA+zV1xQ;2l z!3cCSgLBV>;GQ{pY#fC6fWb}>+!YXmK?yvn0I!j(wG~CG9XY=$3I{m)J2n;;9RP^@ zPEDl*BaP3lm5Dl;3$8p}|CGZ-Lqo&NGjVx5<-rWTyrZS1MILMpx;-ExH_27i2N)V6 zkY>CoF}qR70Q*J&1hyN>-j?KN1A1vZ`SEUPtowwQ+oGL^`k%;Jc*zwk^k3~z1S>2h zbwpQu(&m;`{lK#wc(|quu+vyFa&qNK{{cRc@po0VP8x@{4to0o?P(IqqZ8H51gF4$oo6H4t2qB-Iwq2GQEXr)xzVNI z!5xurGc!_c6%7B^wqAdP1TJ)nE;?$9c= z65OvwMgs@(dOPRJc-JND=g908T|uowSAF5b*I&m4k7#Mwd802cUtyeHG=vb%qZT$F z>umU1#!>!_sIau~yi(?|eA%GKK!QCeI*5CH{VjXYW5}6=)!2Yi6z}mLsOcCM-GR8C z;Xq(O36gk+g!v348+GLLv;>#x6}Ey5pqUTWWN~8<(%loj z*5DxH!oVv+eR1%AaXuSB@pM@&)zqBp{jZW$k4RwqWg_JWz{fuTe@yQVTI`DZZo;6E z%9m%kQNhy;WKIDW@$%(EvJ6B>tk=0usHxL2%7^7X6%183Tj&ZtFX|hc9vppj*?cU4=3TEP#JRY*ChtZ6R^0ES3l4bO2Eai9RX}oZ*j(-Mm^iCs!0+tum&Zbf6Uh_FJiyY=e zKe*wie`F3gTnhmyN}%^(#UFI(SDcYSgMiCPLx2vq-r&_5T{qhZi_X{4B@RtYoUQl! zm;WGutw+>t@{f45A{KD@?psgCSCUm>3Ra0kC`@lpp#7cWMT)^})7RL)Zq(?I(o)x$ zalE>aSega`S*+-MSEgWy^1(9}>{_oAaB1UBu1545cQVWFJ7S`*H+@*OpSRQ9{&61(}|fw z-w{^TLd0KB!@*wiLP>Ub^k02Y0XZl&EHJD`%kegNzTHPxJ0yg^42P+&qT#N>>2}UP z-Jro-WSB0{{&E<$~4(%4^Ww;pN?|^1!7ND}B0iv${;pUjO_>z7`tlaTv%B=i2B-jVPJ136Fnj5axc&?T;kf}Qu zmitx~k(U^nyf&CSlxtM3oYvO%=STd3kGD6vlJ0L}X62HsU1`F%>>B zVkR6yrH;x&b=X*Isnt1!uvQz{UdPzc(#?V~k|4{iAM0_YlRHo7 z;GgDF89Cy{KFo>28kY$BQ6N075xaseOXI&n zdnmf|T~hp_;I<^aZfO?bs868ys6h~#@(BT!jZDb^+|Cqk(1U)-u`)Cv1Fv`Qv(8EM zTMr2Z_TA{hsRG!ie***AP;W|6DH(^^Z3J0E>@1I*H)|&a5vb(LDLVq$7cUzA^z^7a zy*#CdkTDbzcHbjmYrhL|SxB$}m$MMmBbjEMP9FSkNk{28C28{x~PCh?8Gc93P$;y!;rO5i8we&A)AjtUn3d+g+ z*)jV05f-)EX9`r(=g*8Pi=;W07`fSTEwEQ?D}XElFc$z%A(JJwaM(=%urmv}1v_Ykdz`FQnm9o^Dq zE$N8Os~<8{B7Tx@`MdCugve)*nowcja%d!f@F&-Y`@^G0gGu{plpP}@!oeU&^iL{( zd}TdgvAh)HXkZoG@zB^OWz)z7Q%Y65{Ut<4tBo*`h9uAGVB?N31jGf_fBJw0fU^+N zNnYE|pTOt;|7$-O>ObEDl2vpFTmzrKy`q5r|1)NS45nEbJQc8y`>F*rS)a{s*TzYS zWQ^B*YH4n6R)wO0?Qz8T6u@LyG=~YQf6N7MJ9>y9HQinYX+bQ5?B%+0ZRxL398vgl zbj>X?O;SLAP5mGhEv3*P{;RJ{Ql^0>139x-0dDC*Pft%wFUb5A+wjNVE`QWw2Eq&S zKRX22=pWQn2aTDP0`$G@Yq6CGG2uyAq~ z7fjPzuC~0{@0%nvl0ly*#2m*>z4_f^_42wqLOZ=`6(Nh;Lp70^J1{-&z0jW0c6Pc* zm=hW#$WBf0bII}Yu2-`tL7kz34%r=cA}kCnM5tVaeL|SJ{wQ1FJ0t(J3zai@$jHs`s z8)IoAcYQY9I<=n5n|Klf2^Tixc?Ui+xyw{qF&*+Iy{O1zD{MTK>u|5Y^YWBYPrso3 z!^5|ehFHB;^?R&?hf8O;6s?D6Kj_=s>sruptr&!8rGme;r$}4b{mu@5O@$9Re+zwm zf2hWNKNMUxvzttYM3($NlR9@??1Hw64tU@c#9!<$y$p!OdEIW3q$(uGLL$XWhSP$8 zhnRzgj5TQK4QxCYe|+R;@oAV9IxT#ND9Si*6QReLsj|bgnVJJ_uBVNkfOGc4tutxD z9~}y0Lyfk+2q7k^#L^GBPsH{ZpPKNt%Fcsu=|<) z!tx)1S>nx`G?KFEGFwAqx?f}he2S6&tlzk`A9{XJ#dVO9dqtfXPLa2kAFnTzdw3r4 zVZ)KV-j}?ivWceA2e)g4MA)Bj5cN8pjnDydE__9vQcRZ%+k;MHB2grAVb|upJ+4w(hZa!kkYN`Mkca`4oL!*~SFk zdt^XE1oULpw);!n<&%6&Orgz3qvilw`#j#tl=S$G$vrv_@)!zmmK_5fHIJ|LH=e=oE zErQpB%?RYqiw1ds^XC)T#`6@2Lw|zh?4=5z;%<`XJ)tHtkeewA9XEv!W)oo{ZsiBU z<6_UAFjDn*5XxwXc+BE?9Xs}CMuBxh?`t+a^lnaE8*gAB+og^*-I^Dlj~fQ|g$X8M z;gJn~*T|l`XO%z`2Vhn=UH4KfRl4MdgJ1|{l=Q;sfμ9qM%fZ^TAnH2G&6r-1c{ zi&OhyI9=<%!BC##doNDa9ly+R_N$!XtY0J&@%EF^?Nj{qVa1O#ij*)!jCdnD+lGiO*1{yS9`FECo$ z)FdRKfLS2VLbC8yTRKDwn1{)|+FMMJx%F`q^IE|RlV5NW&vGwe%>b-px1H6pqgSq2 z#=I%&SC^MS6B$D=2%!E4yYIh^e?7Xu)6J0yp0#Zwrl#gvR$Bqx2xGuh2j>X|=L90L zr~5=NHnYyw{&W|PI2|3SEnWIiJ1sqPRy)~Q^0&=DYrR4_2inn@#O=KO%NRvTV5w@- zvp3;OGkTmzTf>oo+wK3QAgtW zHAeIpIP%|k`HKx&bU+L+X?$L+32!Gk%nlN`m7TnK|A2&u8#|*aSl`}F<5zMxdha(K z9nic~hX0xMHRVo>|e+SxUTo$C!c0 zcyYRc%g@jB>zI+}@o~`NzqYHsGhymIv-B08&BNj`Hx^SkL_)YLdcE7-_Moz{OkrT6 z*quUcAoYurw~7cbA?l~g_UL`F&$%i%#+7uc_+_eX?qSu@bg%M$?|XCNS@9LBsDuO+ zz?2FyG9rJc=HNvmkR1%#y`>`FK0b8jR#tN|LPBJ~mjEpEemf1Thgl8EuK-cLAU7BK zFDOG;s7IwS{Jabd`bUkYYgaXPKM0HzyvUR|>%;f(-KO@hJ`Q>Yfu1F3NooY`?Cuhp zV>bi#Bk;!c!447pbpLM#{uDTbnS|kQ3|TySevAQ{iDC4jHyU3a1>PAWC0!73zx%H3 z()PF3$|)HR#Or3FfMLAVr5{kIKtY1BoWBe~DTX}@fb0>Y-nn*h7#eV761@AM_IZ%* z(4twE)oiwv=gOgyA|9>F!IfQ4VyI31oSu;E_Ypf^p`pnbu=O{!=45g*uMya@tw~h$ zhAxrY1hxFI(u`$>xpp@KMnq_k+R4b>HVzb!M=Wh#YTqyoaq^-L%GAvdu!GO8;SD-OEziv zJ;y2Qy^r}EN-a@-H)KjSfbPU1Elme3yCPy@)a^kKM=0(YnrB5xiN9IF5SE3dCBIEO z0_1Gt0BjBXEub@r2CO|jmwpmof~dz^k?2eCQDe5P@L2%y23U%e;lpk@oMrvhJQ2`W z_nD1EMu?D*@CgVBZJ%~J{@TPNFKebJzf)!rMF`FB*-U3qMT{uOrz;%Wpn*f`7U!Df z3mP!gLk`^}9HF5_-@tJHdqAvCudM3ILVo`R#f?0%Q9^cD2(vQdsXOOr0D)5R4<5WX zs*!4iwj-^-A1dtq8U81BzG=GEe}(M1+Qekb8kiLU0^wvwIiPB1U3j zKWoT*_PxwIe7ZXM5k{CTi}nt_-?6gea473nyPNp%g2-P*IQ?wAwv!i`6s^)vB=nk%)?CW(`&@`^JXD8hEZaQBs4L>$f zf?3Q=TLrJbS99J^jFFGPx|U^aC|@vMNg`aQ~bKJekgm-8Mpbte~qS<6EsQApXgL$$Ngh9RsB3 z#v!uvE`6t<2j3fQ@A&vu%9h!FNb8M-(j!CB?an=7)G;+2xttYsqr>>v_rtHij#uXV zuK$iq{2QhF^Txr!^^h2IiauY}J*{GcH`!7WiyOiW_n62`&Zr+2F{Hz6U~BMJ>|UHGp3g0L<8%_}DEz?0Qrd>G(Ys_N;zc}FEEL=Fq5B@v|a*nA0v z9|Fs6&MQ77Wg5-y?vX(CbwPf95g?V?@=)8lP2{o4uZrK@J1jlg+hs$MV%ru`!w7wG z;3eIgm?0&wB4g4&+}In22q74Pe8obh@e`#XdDgDZ)K+E+SvQE>ZdKFcak_yb6(zA^>RTI z%8@v@6zG8PZoAda*GW+gkVXL}npiDh0#-34{oLNHZ0iCg(q6CNfHlZF%H_ZTM4S-4 zVnqP{)tK=BX8{#`GKV9W=aTDryfng^6K5W4ch1Ol{4*?AJ^S@Wi84bV&j#ULl~4aV zGGr=Mtzwv*oOEvd=+K;GqB}NyZT9Ag9k(qT4I=p$ZFNnSUf1S0*j%1g`K=B+_;EWE zw4x8*6gyQNSKo{5e3UBgCf2%Qy}L*#VxxG;&@A!z4$i0gZ`=z%$bX#It9c4pg&^Dd zmMsV|38OzhD~!1VJE4e%C=-}7m`^`0nlM+($|zWBU#27;bvvvX!)nOTUBh8_X-5Zo zdYHp!Wk`wnEQtuswIIY(1P*U=lbyOI{z@*J5LamtsZW|2yW;AuF)HR8`7 zA|h%(KN9pPL}Xl6G%#rT()e-fNI<}?V!Kok;htp`XrmOaPe5E_ZAJ4UglN)aD!$J<&+=|EV2H%+1JCkWvvtsqdKwN z>Hv0);J;L#GH-%9*QY1BoSjPUfg(Fo>?s_q=q^WDVPS~3ny_3VRPjiuG2uVZue58Q zw+cMElO1?$T4r8XF%e@0>~=~@N_0R1iHN;B)vo^%m$4} zgs=YWQjeliPA4((DDdFtjTDJD!RqmR@SM)*N9g7CgGn}G9Ti16xsZ{GC19tLRF*;} z?kjJ!dxiXp%++RR`E(-Z7$k{q|0W=mVRFR=S}a7aBx9s+-g6Kz6+ENShV11xG|~#O zka@U%l(=xTMnzCZsAB3*Q9T0c)tF|G$5|d zm#e+~@!j!HXspn6{X@CG@U1EQqW5GRaJ+a=`3Yfa(5RBLu(;dFMrw5IPi1<>^m$2t zN(svI=5OSc4z)a#BHzG3CBWZxgh%nZc=Km&5sQOe0N$x-S=~}Wf>M$H<~_)#JLLO3 z_QCzhcja0;*`cL%CFzmqp1x1Rn@TB(7ZjAtTUq(HFW1t`yc|bCVfOMs>X+g!IJG?K zMk`12JOh#xZ@|9U#d#%s1xDIXu-jRP8i3dqjnA|B<{%Eh-CKw581T#9HRt(mCnR$ts z@H#>8bp;8|uY)%0O&70CpGJ?3mx-3U7)LRO`=brzyTa z!ueqQOXpiBuZE95gMo2gdHW@x|Gr{kWP~}sLGUY9VtAGSVhbzR`;rJ9j(7Eq8!5JK zv&~e%d^1e1I83cj-p-C09F7gdvv?zjp1tks7Izj#y%IoJQ=(hX)?xk=TpRvDSox9F z?xeyhsbv|F*_rh(V4{V%Ec+VVxeB@OpRZ5%3hbM6t{<=mw6@Z5h#UX8d@+vX12wptPc*Ydk{1bV5+sz>(}oFvwkBy4Dn`K|iam zq5@+IYWE~I4+?;0eD^fXuNw1EW2lMm&_kL)^;j@b;z5&`vXd+*rGVwEN*Wm>D$usD zb7Y>rJ&-6oCA`(OBEfuRc3t`PYh;hqg1%JbRm2}O)C%{qULwI0l%H#a%r;E|q%4 zm+2qZ{Xh3YKUvUi<+m*4ZwM!ekTzr};%yi89Z26#$cKzBj&|fQ=ZgAkVat=_D2W03 zLBB=9w@fo|Q6saM^p%D70#w9U$XDp+RY8vJIYHCG80-Ncim7m=&*Rra z#=$AEM*5=40=dTw{7-RgZEefGs(`iaVIaxgbF^RXXuSQ9CQ^%p!4l&`w;Krz6RfhX za<CWs1UIiIU+mV2y=}`Y2apc`PF!&7XD>Omk|`&8 zN4}-t$?w&b%eGUKgT!O2ePm}K=r;jiF2JrpnIrlO3u5|@vv-y(!_R}0lU-AD^NYX# z7JoDWy3V^%=UV)ck&!x({t;LR)Sj%s2Ab25>wQM8**1?nmJ1BUf-Vq=Gyc2vx5ySQ zt^1Vj;`Q;QF6V0ksoA095-#+ggTILU#tExsYI!xlOFs_OKL5$v%RU?s198}^#+)S&JxFY_+M`ER4lE|Z0pNV0xY`cvZ-!dRcT~(RBBe&yu1cmG+~gEt|DltpV`Te1JD2%9^QML zj-ffs5N2{ArB*u9NFx7SNK@2VDE&%4FOdWb(GO)lNe|chL<;6sl~L(-#qfGR&C9wz zQP|%FN@CAK10|o`=}?zD!g~kKkFU2J3%TJhB?^LXu8q1I%eU~U1i~6kM^#5()}VE^ z&AB_=um3~{M?*7B3O4_y7f*KERG6cC3t9?9ho ze;Nt@Ai3Wx@W*I>DduO1BCupnKAs3!S%MY=90`6lm;ei^r@9;&UZ}Q_E=A>~ant9+Mu>29E?L;BcJ|wNZ2FkNpuEhTHej?=+qeVTntGrc zqmqFQ@lT-v&0pU{eQ}>HWh#^IVw}i0NjVSA;%8#A*co86U~g~F(Ywvlf7j_r`Nw|` zj@O29Ay4(fP@{>W`(-7t+_?*+x;sK)AM>!Gv!SdOKp={;>(!e;pBHKTCmVtYZf>~% z%O^RNEjOXP^-`37>uRO$a&l4aC&a|*zyuy@eVtyJvqpqHficu=N{(z8EUmBsc?&5v zHdP-n%sdSBE&tV0US7*y-pf197A>+a-a1LjojX>+(GyL(P68sHnFdTrCU@Y#*NaIr z>9r9Z@qM`8<@;OsnfxYWV|a@g%3L8#o$Txu^1!05^Q#o_io=EaD%rYo@*&)lR~l^036fuM1x(8nlw>Vj6%~Nz8h2t; zrmOpR_qBy7_5BsVWC892pBi z94S4)i^XliXMzr0Ou4V2TUHx@U?C(5B}?fpf|lEP^HEwfB03sJ34oKEs>pwjPLfqq zoz-4H(a5(@*a8MBMhV?LJ$6dhpo(;S7!0IAKY#v2=E+*Wq6_q2P<9Xw$`mEFEPBdu zW=jnJglVfS@m2=u*p7(=y49~7PE2Uw%kjrsJjDFNbStXCSLa9I$7Q$b^Tv;Q9->-E zb@YAbHa%A>NGoL7e0IbahysS4lTBZWR7LRB#=3gLlo{MXk(I<4)deEit%S8#W+&kMvX^@dw(dLMT=Y&Yle!f!A-QWiVHY?5u(r`Dg*!%kM#`OZ( zX$qKbWdXqr+I7JR`NL5ru`4(H8nd0KejxchFm-Km238+;_D0QejkV`TefULQ7I#hW z_NI6>9z@v*8q#PTa}PX%o$z5#pI?(^7)d5DqFoK%zqT~m{zq5Px+rHlSI5htEUsUTASmYJtZJDl%ico|Z z!QZ_GdbbzuJq<^SF|skS?S|UMX+E-Za44J^15Sj{7C8)@an3IkUk+>cU zYUsO1`-Ri&)U$H5^vJ=ed=6vC2I_~c0go(a$e?@qnRL07%5WYQh=$% z-_;dzJ8pjwk8J2hCQGV#!3%j%ekUvKSFSC=(D>EHGnVEXSdH!?1AN}6o-#mf2ZCyJ zadRJRqLpmUJ$Oqt#Sz0gopvm9&u>MXx8FSUJZA*Nz+3D@Vj+3{T7wzyFPzB-Q~AX; zFa4cX^qD#oCFsa|O4A(BRX6qOvHNISLB3hC5tfNLZDK}dOlmJ>?=&9E>c-qE+v>A; z_@83ug~i|KW`<~yNbB!ElWz4p8wG^YiGyL*{cpYIXF6%{y}buFYCL^6@Zx0chL4O4 z4QowkQQq>_-1|<}1z5m*h7I_x0&19j%syC^n53j=!5+WO2A_;RjRWryO!;bIoIUQt z#Vg^#h--GVdW1C}@-DPFSfl@`a0ek0{`-amj!Gp;m0F#6>HcI?2+h$iB#r22FTQm? z8kq1nj`g`M;*V6?CrxA)ud1tr?Y12gzf0E(v%xL-2zUj@WX-QJ=O?K0C2l&76L6rs z#Dm(YFF5U#pRCSg@CY&C6l6@j+f){Q9N4EPB-P8?cVJ+ZM4b{}5ef4muwNxxAF1Rl zT71Lr%@DdP>gAK)_@#^S4xEr10)jC$Pza^XVAo}>Aa|8#{o0&06)8O2hu`IfQHvE8G{qvUz`*IV(|Sp2a!qMwQVQuhQi^ZBSTjm+`5U7xqt+8|^5p=fw18elz{TCD=G zzv$f!vMi_-D=*OO=K8G1`NJhUo@=-NWX%%;aLcIxu@UeA%>o|*8Zj^yQwm55ek-a~ zyFA{;xD^TKOU1id+EvbOr{#bqabi~qAz%=d?C9XYnL5};^^~Cnz-^)2*i(}a#r>&r z^G-aXPpR@cmS1Y8Ooyy&nb*Izny0A40a(Vv6(&UA4Uy;=4?I&5nHwk|VO5GLANZ-7 z*CPQ7*p?~JY!&G))72PPVu(Ey0j-7{H<{O+3DU6*^p_L~Ehm~y8gveb$NF^8uSZXv zwTtHT$QT;Bt3}y@6?W&SF9WZtE@XMTj;V3SwA^!_z+pq7A32ERbD5FJY=h3VI!0r5 zKdNYnHos@G7gAT^sG9Q;=wGTQy@+kW_hLeFpV3UJtE)2uLa`#?i0xuuydeR_Y%a6k zbv!xzV{>poKBPII$byW3nvW?`FEJr`s1ef)q8vEaR#S7P^A#n-4By@UH}AIoleQLb zF!RKN`=4NHl`U-$VsGt2U-k=mNO~a*TSlvoCxf7QNzQefFkp4f4OI9sQo&g2o4HR z^L$7kt&9e0`$*%!fh2=igNfNK$CA5t)#)HF;t+sYtH-^T2Q8Y=QYi(dH7rga{FdOw zmw6a=%C4w`m#O9)`0Ri}GlpCWgfGj+oAVlR9> zWCADZt15;)LDz=?MMN+D3rVTX_429fCj7>UNkP&8&AZc`Ew~2Mcd!_VV!jvYiOm1p zm9e|3qhX+B@K*i%`L?96>A<*W_FW1SB}EK1{hS+|1vI2oNoeh--F3J;DtUJ@LjtwO zj|^&Q!$EOF@nF-V^-C=cxK&}^Rt?LrHN<@-=-G*&9JKe%DX`Q^zl0b51h6z2Q) z6L@)egjoch0ACQNT}Nz$S5ywc8boIhI>++FUx38KG|70NP0z6 za1gXDx!PCBn9|b;@bj4=fvj51?V-^m$mI-x-#p=n-lR5AON~3u@V_Oc5?n2 zs!4m(KD7GSJ$7QKVdp_R6;hQqrOllP9`Nf?#!zLTE?AY>mzI}rZNJfFe;+!D{u9)N z%r|?fyS1~}T%O)F{_FESQT9LF^GvNvic|HWsY8B;?gpH%2QcOExDV9S)J$V7Z3M7y zgq+a4{DQ~t(=|j`c*Nv19iZ$N0vgb?vmsKsplTE2nULwtgyV%Tw5NWlp$LoZF~Nmg zvc=4`XGXP>+?dD%qJ9l2{ul=gKW1<%nL5sK@bGHZ>(a4)Ezl~fP+o|@d?D}iuuC#@ z6#D4c$(JVy+~EK9HhxJ*p->fIFYc$!;M1& literal 69070 zcmagGWmFt(&@I}7ySux)1eX8-f?IG6!QCAuSa1mr!9uX$!IIz-+}+*XT~5E>J>U6z zVS0vXX3b*ysi$i1UAu@>Q;|bQAwdBE0R6qZj0OO}fImV2Bn0r`U&4qL_<-h1w~c zsX9X(cQt8O9X3L|cW`eT%q-KNN5tABEW^XG)8Y9leA?0p-AUV_m9zPO?hyXp z3(nJk)fdy9p^R?Lw`JNDe=XQP>*VMd^X7q19wrCUl9Hrxad09U#ZQcUidA!OexIWg zaRDn2X9JI{gKmq!orp9`${TMePe#nr@U~%#FFz7>w}D&E^!e5PWMW2!UeLF1-=5OE zQ=2?4XfS}6;oK5Uu!z-0t50Fs*`{nyb zVE}MExHk1b80^=_2dL=j;orZ1ubk?nJV8QYKyWy7%J`DAC)Fa4_0*}i*XR@?#Z8O? zxO^@2mUD$6@0KiV#X8;7SbkVOIywrCi9!4G{3kg%x%$^q2a!-DUs6t~-uk5{Mn`d~Y$%!W7x`Du6jt@7{`)JxN6_atn9cIB|IQ1GXJ0S5 z6$fz-?|N7DV5R*%Fa{~0XPzVUhj|MiFeCg~3M5ZVOr##|>-)`ml~NH?kq>(k_UPbH zZt^Eelmfpii244#vCJq_xGGJAcIj4k1RwA5Le{lFWu}q8r@+$K`mtexKrgz_pi>#7 zI^fasekZ6cZ0eS<9}EUn{fTz_ZcO0Af-MzZdfTa3NhK3iz{v^CuOi{@Tq9XO+O_;I z6jI=o0x#IZrKLgM(8*#|Ic;riSlB%Ng(${r=Z$XUui#GTjU)FPwDP+>`B$Wzbr7FL+UOj8 zz7n+$ElI~<`oL6keP4=1f6nx@dblV0hxgYKRS@aK!~_#iu2)<1&*6=&8%N#jff`G! z&CTE14STjdKiqw*RY&!J288{FqL`ToxTTXv2llOUmv(XKR@TM92j>I z?$NctipdhxD~G;k!#cZXX-UUM@gU=DPvcimVhFrP4@qa7I2=Z()ncKKjU}#;b8t8g zayUgrLHX$)5I`I&+cj^(>%KP@Z^%wtIK^CpE45R1m2r{n^Sb=kL%Q4q(8qzVW_)FF z;GcLsH-5HyU3!7Rf+!h(J&iXKu!kSse&F)R}=a_b!e1ot@GSxDRGgYa}mXI2_;BuFGY_P78PyWoo`{RD(wCn|sbhVoAA5*gg0R6JV2tc#Vp zeG*LVUtzG$48Km3fHANsNWjli6^q+c5B9kHv)y+6-kcXAuAr1aT&Bp=S+A{|;d(ttyr$Os=pY~W;&wWoRsz;Zbj>2>`k#4pmY$krl zfT@5%IWzgU=frMm-^bf(gxRLxKdh)+UKS8bc9Hnvl~;7lom|IrSY~Esmwv9_np-AX zT2pk~a&mHApZGq`jpehykQ=1?U+xSi3~pan?Vwc@^>J}?k0(AIqFd=DSfiEe8YvX^mp}J_=8$b(&h}WUEI@u3rDY*I+fH0 z<#bjYxpQ&p&J4D>+Kyu*k5U)#A+qi{Wcs6lCj4iYaz&x%aIFy?F*x|7M6RTiC6vRQ zoT*UI?}kk_o&r5mW&(N_5)zU>xt}+=ucogb)$7i=9=)cMnQSxoS>V>+K38aG(1`wI z##P&X)q^g`3PZ!~HY+9N9WO60m~lQI9oa8TJO&V}C4=E-=#y10F5viM}}ZVBF!Kai^Fm-b#~`Nl_#&ggwhe9a9j ziUEKzQuMLIYl^{!#0GXb3JMCx)8Wn!78`rW0{9B<@Aiq65u$gUxH_$E6%|tmuDd*OxZx8D7WY@3VY`9#3-aPpR?F zO_Pk_fV*v@o{Uc0=#JDY8YL@2;KQ_I3L`sv?7{>jr=9Qv0QESW`L6`){&i=LqYy(0 z>3~K>p=9Z32L)(p;kg6ezaNV0(ux*Z3It9|-;V3*w;TD~Bv!}7#1Jgk#y&yXHEF2? z1R7&go+evg9uD13n=eObNd+8b8XcDbAY0fYSfdn=UAKCz`{ntuZFqP%)=>)!(yk5@ zho3cUACbY|D3GCS6M|Mih#G;NdwwlYVQ-k0Xdym*^~ ziK%45n$OVO>;-%?6F!pIikZ}h+tXFsUw6aUx33d9&ms1Tm7CWqV%7GKo{haQbIn1d z`vPYgJ@KRStpOqcRh<)QBZ^5euXKe){zSFfOijs$T1N?JkL=5$-~G*LmEoV@g@px? zB0lXZp6ty`Q3*?4Q3+{@LUOJ_aZ>GSPJcCE8o4hVTKc>pjoW5k$ic*>y=2z z%slw&`nCTP9XEH)XY4hierJ#J;BnK?aZ_mjC%D1P!~RuMF3Ga#@0FDpw)Kw)&;XQn z1XZ!uVd5+Zik4nvxIPIsQXv5?6)kKjGqYncELpz^6_z9&&RaGDX*L2s_f_-<4_s!5 z6>|l1StC>>rehe}1?inAou&k=fi^N6Jk+EGSt7t6X6<~5MNv@`LXz{Y_(ySZ!LMI9 zAjXpdcfk3}<0&l%2ZnI=$hdTE#*|m`oe{mY>Lf&&7$>I>#6qQvfvOL(=36GJZ~Vn| zQ#}O8*K%`nU-ySHcrkB|7X<)d#qU%M4-XFj!Z9i1DhwJwZuKR$#*5wPnyIL$yovAi zJJNoK85$bytW$~iOXwn?smU{TIC38^Aa0klbPYQ{92>bVW=_sw>oO*ffr9bPeVJm} zbKHr97$2LUYni6`6vu9x!(u}*gKExGJ^N9WMk!Ig+T2FNl)hO|F*cBuCh=R5?J6Z@ zELm6Hxo%p-T>!;-yK%6w&++K@gZ&?aFem2wMO=wOJaS=o>$8mhPd|gEXJ(`d#`B7b zcH)>Z7e!yi{BHOn;O6?;Oxgm+4n3};;ugw@3GpWfMs+$r@#F_+;VD_V6>Ocx(bSMY z8olWoN~4G0@i=k=F-5)?5}sE?b;9IRw*1Ko^tN_(q~4wF2xzxCz0mzh!+w%bsTFxlD%tR>w5jI z?d|mtOmXWgS4v6)xb0tyTgRn34zK>?xn7#R?A$ygim1P78JU?QL4ZmnBt&f96LT)e zbH1Hsf|Ke{lBAa!)?^OZ*xckS{PE*z^|#CBp7a-tdq#SC^7_QKY4tF9y6>}nv?}}HnSxrc zkKSVJR4j91NSqtA!gJHr{Y%j6giIw{H1g&7LAq*Ix_DB$YI1$isrB=*u#WJ<#rEKM znH6Wc5`*DicjWT^h>5Qg+5trk=7*W^5pi*z@43PBTWzU0_u7|el0R;vR;>NDR7*e5?lmZ7-Hz^}u5E6@ zN=QiDJ>GYWjw13$Wy%0TjUrR4cq4e)UGAQcpNXhEfyDApL2BUAI9!5appc+9U~zaF?;p05iFy{UDBxpD_~MAu~eH0mko zto)oFhde77SN@dkLv;FAHAmZO9+edoXuwscX8&U%N865j(MZk4#`c;hN8!UJCf4$p z!E3cakAv*A(H$v6hx2(;kSFlz?kUYA@Q+EZc!1~Ap~TgqZlr56xbv$v+*e1Uk0zz8L-?|q+ ze$bJLc-prgOqUUYq1*9z+V;90M=ny7mYTYvw_$CALUm<}ZCjonb%=)|evc1Lr+RMZHE>%qf7;9wvu ztgPJNM-VZ7-=O|lrc>1eV%U5EqP)q&yhaSiiG6k(C_byU;0FefIdbUzg0rk8W>onW z3UxwW?CI&*uvN!aP*kk3ne<8*e^x(QY>Z!!gUQsC1bG({G)1A%(3~PcL=)d3C&<{C zg3n{Y7gniI`)#3yRN>D{K|IIHmkL&h?W*bs3tHfD)nh8;%5H@ zW8cO?<(YzIXg=$*h0D`P`S|=9+&X2OI^8FMXo~AbR{#_WuM%T1vu`!hHbG7%FVDr1 zR>HQ@mcgrdTy=;JNOx820%Q^PAl#bW9_T-*pkJET151 z+(eqImCL*|G@V}Ocb!hJk0T#98xLpn-Tal!K>|TZPfrg4z*R}i&L%&b)-hp+ftvTm zp&u_d-RAgp0@XgduXmp2m&W0wnlKJCPD@McNXLssIakNhuZ(F=2dUc&`feHy7Kih- zj3YT>i%?xK`ZH`28DqEH&T!nL9Z?c^7XAjM|NKE-iYCiSj2+{_T3XY)FbYlu< zQ|yjr!jLct1#a2Cn?XwU zUw!rzpI=%3?iH!Z1?$w-@|90;(e$Vprq$J$?U3 zfzLqeM(VZ@IXVPL*cC>7vm&!9CeHM#j{2`tVkA?EA%=t>1;D~*>)`x_q5II`;UB0m zTh8YfPg#u?TFdO&`_|<|CAyZfZBk>jjXQfSvV75}?M7D8uC8sR#V_cmcBvO8F`svd zej$q4a5*&(&o3SpmY;@&8rh}gp;Hprmc@XJ1PHvyPw>WLVSx;4Zt~S#L^@EiasX_iAS7%GY1l z$BTp@bC$NS2#Bag1+;VwXcSaM&%1N=_2Nb&G!!Uz%qKCV8P z8-6WH8Cax(8Ef*{tmSLPD+D%D5zN;k9gz^#^h(}>wGIO0a-j8uNOxjintoPnJ08($ z1Z5r{w?PV#Nr8&|OMR9@l_e*;k9QI4X@KEh`j6x!2Z_z<1z!mA$JO)I_ZBMRMZ&ep zR;=vUE;bV(&P~Yn;JYF(rY!~dLFR-f5~!uC?PfVzQm%vm@kZKy6D8i?IK09xsjT+Hs07G8X?Ed|{xYO9%}OB}f~bUwEnbocaT9XE^H% zt4?K|zMi4p%B;~hf9cOj)o5ts*)$!aa(}5OdNJE5+agamzP8ogcr|i-StPMTUQ)dE zBNTu2tYCAx&t`cfUqwIjd`F}|i9{q3*nCG}2i;PAaacs*FCPZZSmK)y*_DyqPnI&k z_(5X*?C6>gNO_2OBwQiHOQxyc5lkh|0_tM1OHcoJnOUr z{-2C#4BP&{(&U|DUI!Z#tUwK6 zDt(tl&BPS(*}|8>q*Ti_S>tk9OMJ2Qa(;fkj-MdYrXuC0`FFrvjk#QBcO&RG|qfiHS@soW=F^^$pL&OZp$jR&+&MJ>DTxr_(QHw;2gnt_mbe)my5* zl>2Cg<8UQcsU7aGm2&=Vp||q%^bB_B*E}J^LU6hxzHR7Av4KxvcXG+${oTCqC@Qj22$)xkd4xvxz4WpbT z2Qn5M_TOND-Uff|c9)31PBOafU#eo37OPCg>h+?(ybuD8EcLI9Ye|$4R}OaeipHkV z9v9|?R5k%S)t3r0IKFFg)&5`nTOb^zqNVLB^mAqWKJl%2CTeIdNut+9x7HHFpB?h~c>t7%O$W6`3IkEYIQSJMZxj6o1w#x7ys65gJg36;As62}2%5doy ze#NJq=&Q4Hnp*vBYrpSwW~A<@QOZZwZVL2T@aSzD?d-z=@-SS)?Qf*y-xO+1qqw#e zB#R#~cdW3R5*6vuhGFsGK@+fW-ZEEMAN<`x!;?Y^0JWp>8uMO*22`U~f1i&oE;Zk< zq>T7set>lG_B&?|na|-4&(dv&?rSu*YSTV{eUWIPM#kArmeYWyreR=e*6uj88BttX2L)HH53${EoTaq`tZ6woTRF8p4v*rk-KmXW$<;C;T0 zszL+g7aPo;E-q{>+o3&PGh{e50ynbBs%lRG>w}0GDA?r&UP8j6N*dSWta7P@Mx@ph zx2B8D!HNeP#kog3D>IHu`>;2pTXo&2V378{>_f3)R=(a_L18Wo^&c#I7Y zBGcC!+_YMj^MIHBb$_0+D4$3^DH#zD2S^Axwr+PeX7NTdqXV%huJ^l>>#p z0E#3!)EX#ub8{1c+>uE}wD<$LJ-xk6&AY*IljpG?5OQ5`84+1bQSgxNXi|)a2vI!P zINN7UlhfUwE=X;;Rkg|lNMkfg>-t|7H;@48AF$9@2owC-FD;gUI1S%t6`yJqd11VE zUqApLLpZ~NS|L-bYABQ$Fa?rOe+sYl-_J&?S!F;&bjFrMgQ9%2u+>4&1Xq{=u$Fvr z+Zjq+l!GnL?FVaI)*2gm0=WBuJcu6eBwqFHN-i05_hhcke<#=2{8tw)fVI9vTGtxg znC9kYghz5Nw2;Qtz^u9C<&kWW?f+I-AL0=AElINmcxDN^h>~dd2ye#p(BeP`#kRsU zR{ULK5lkkyP>!Q=gd;72LhpSXMjS3Lkzaja&v9;X=WV0KwgCU$nf(-NoR~Qy=_ZuB zMiK3JeKVd%{~ZDb*<49;HP`yH6g925|L-GA+0&Ma1hQnHLQ<+>Fb1iiu3vz2t4cAC%hpZ=;*%N+7}p)mVMuoOc>VM$ZA( z)_YUnBC|UN>L3mVavy+#t2odALhLHiUY8p(c#8O2BM>AY0F3ir4AgjL`4moxMYW51lOx(GcYhes_Kx4fvy(=1%|efwcG9 z&6H;xP@5sbdK0%}0h^E`7-zJ0#$=5!L>f%}!TKnT0c0;yS(cPP9Q~u z!V?!8j~dztuz?DW?2-`?3>BdysZ<|>UAF(G^%$Q;-X{x-{^PFyqM%fwA*jv&{z9hA zY|K7>bYS4?;+Opl8x+F@i}|ob;#Xxc8@E-&kc?D%uZDb8^9%cdm<)!(lYxR{1~PGf zuu(PC{vUErVpL`5{`YTN(3qAWdK=U{Jm|G^$8OG?ehbn<0!_ZbGfy&%HHd5bbo(OX zz&*rWBs2^=S!98!x9Hg}lY2skiOWcw0}bPr@q!1x2xAXQq5c+Y#yHflLK^Wi(%VqR z^w%RaeMUTdI?u>_BqUp{qVL+|Jnki{uJ|JMIYG{a@}qaII1&ZabZp7z$T*ky{1!AR zU&ADAsBRpJghFOAZ_`9*M?e}NW3>q(xqJdqs#grKXf>Qz^Xy~Qy~h;qh|&6C^#{w^ z&*q)ZXLf1_xdIqKO6r$E*pt=BH=FluE@Z|*&mR6y=e^fkZMM@ajTT_E6pVW-FyZ~G zz(Ov8Ko1TM*z@!ABlq|BT?JYP5uwGof%?f=Sy?IB*~^yeonc2Jr_Ga49cgLlnxNMg zIDipbMs}{B_ z$+Y8#ZKoC>gU^F4oRYm$M5dN2)Ud%TteYaoOvSngO(~avP`8O|+^S0wHdV z0E}S=*a!i+3%B)HUbji${X1hVExP#VTKm#L7qW@TNgE?0a*)~teeAx4)d@yDxl>n^UVc$o`@+r3DHIfkR#kanZ=APcY6(M6lPQ`< z3quDcXd^_E@c60Ecm5{xaF={4Uc zUxAMC%f*5IBRb%i`opGA%vaRv|Mdc74i6S5laO)v;IyBHCRikER4}dw0VaB{O%{M4 zPLUSNGb2=Q#_G>EtdC%~%k9vj^_ACt zj_c{H3)6cmQ4VLJ&W6^C2;p*flu_H_YqiZJ!=Db*c9274YPr)^t|X*k9wK9Xz4ZGb zRCBwJ^(ROAJ3TybmE}Yy$AtiY#%@M(uV5hktJCs4pxDKUSolD@he1QJ0(j=XDvUY z?mhzvJNCxXOk~B&x2h8 z2INKY<`W`h=j{hSd{ANTUO8<15`ff3Z;dYG;o;#5tX49MM0TN?iy62GmM&g2zuS4TDvdP zlFuX5`Xk^JWREn>wl3@P7$A&q-jyhpb%BcXv!|}}mPn3xpCv7zQR>bHMaM8c4g`3? zMsKU@zYzM+v-0)R_sZMb%!SjT30lA+GWBW`m+Cz?;Ky7zz_7)POzl@O8?es6EDliN zwc7((NYt2W3b%eZ5UNl*SY4Dn+(IpBBw~!UOf8lVnhLx|v4A{#Q7fxLbf3K=)Q$+U z##ES$6TRq;4h_ee=y)^Im5l@~=v~D*Z4+mcc*%NTlC(!{ewFBa3JP^9)VOU9O6r%1 zr2n?HW^jMHOlJcmj@#1VXf~otRy^Yvy`xfll<;o@ z`D6JWr7J#~ikl#YzFA6K5J(>07rc|%$YGz{YCn-pSuQ-BU5z*%gOp6PU;yyK_?}S; ztbWT9!p&*ilx;?urn~!DPn`pQ0f0&1Af$>^i8-vW&;T*?i-0Y#Bte~WjvaSAXdB3S zGRIq*b@4#3xxMJv^>6$HvAO zfvKTfiPv1P7>$teZ-WA*!tK%g<%f?SH+aQ-uOu}zaE3=lDmi;Wahe(@()oCSAJoRP z>g;CYV&mgqx1a7WV^Lya_qB^A_a`wZM1M2zv1#EGVX2|zkF}Ge3#VF@OkaNZ(28Jk z9vd~#{_N*jwLjf7s!?EUFw62^Ux{9$bV~c~&CD$1kgw^1i3utcn&4R-;|vFtWp`&S zZH5~JTFNk7$y}y=mlZ=3;N!S;Y5#K@`WhVd z4^$|PA88l7PdtqGjKVKrJ3Wt?&FN4qYUpWZl2t`CBQWGX4J0TOmI3~g$)aUL7Qhpz zq|TYKXA!0PY_vg$WRWt^*9ZZTEEY=B47pXAO3FBM*q#{T%_*Y)JU2AF$MMZA!${RF zjhMTBY)%UmnlMI*UJq9`?jWP7YJIQ`$kJ;I6dN8K>e*1W zoshp~mz8&aXmJtC#o|ZeHsWCJhl3U&KpLV?xCz_821|1iM$#5DDGdHQ9#o8rq(<7; zcONGEU=&C$l~48E>&K~iz3pTpP$_b02%!^Hd9~|=RlfS94DGpi4MMDQ|Cw|A2!>N# z;l&%rB}q3|S4kfB@beX~CvMMtk^;H-aFNLulK&!!23Yc14Oq~Y*JP5CmbL<_g^I&L zjGN67mxXLLiaej5wM1Qr|sjb~yE}lc|-|p@HQt4$HB!8Vg*qK|b+AqjC_Pei^mi%24 z=;shwBiwKLY4!NF=jrK5I}$iE%{U>%Tnhj=^&@*{TO~Sp)dd>QOktiZHwk>f3f|cG_{V_(S}<#3Xvo%Rba;dS`fc36zDD&6q4{%P zfE;JQGiT3(-RTdIHi^cNOgoqOxx2gnPuj{B@lx3mRB5#yr?JgKkVonO<-jaHmcP5( z>rG=3-9VF@m{ok3<-W%nC3YTJLYutgp`gUn9!wq;?0C>rT=!09iw8n40buagGwJ|i z?L$b0v}GW+>^uF5>`;yROpDbvpUWL(!i6afpcS6bmZD0mMyULIIRd`G^x9=vz#$%9 zJqvFv5+TC5kkSnC&?>t>zc|zPUCnxx2!>wbKXrm%vg_tABt)i_G4F0hV5mw_>ST;H zDIW9QhMbT{{|Kxuh<&=$D^D?a&{gbToq6-0S9jRfN&P52C#Q9S z1U}s|8=H$=OzhcDCpZc?0JPr8$=y;4xqjN;e|l;V&W`Kbex$~UZvP*}p0UOEdZOsZ z5418+*In2x0tNdQP_Q3;xTTz%?<45}1^X*D9j!YwAfjWe)u@RwIs$2Q{XER+={EbH z$7m0>|Mu!k_O{ZJ6U5Gs3ONe z)2Eg|JKl>4KootAjg1$tQn)YGpygFh+sT`JY%2maXWBdnrya1v%dc_$S)NCM}^E+x)g^< zu%}EEOHA_pa*pqG2)1VT;cU5@V4sbl5EHh#+8c)hD7@Dojmcw`X~r~=IFiC7lekas zRAGP?3z(0{19P&LCT=yvx`+RiqT3O@JwU5QS+u_<8$pvWX&B&rs&>Pi+jo;qv9pG2 zpkX+|yKiTcg(R`D%Su%q8S;Im4+lAsY1)1^qKG_Lw!icIIroqM>2VJHn1+wC57_AP zYPIXjeH171yJR=NnCXwbJE_J_p3pAU$wI50H$(?qTwK`ovHE0Rw6#D$xF8U!-Frj_ zT%9b7C{$>SlJZ!e;o7FKB=FZ3_4V~-sjI7}X|YUq4h#&y=nV3kEx{4AM}NVfASae^ z-GYmh!I7054#jdNtC+FDW98f-Obcjobcoi5bLRtwfR}l+&vTpU*A@+}Bq7A9*w>0P@OU20!I7>nepwUKL(yeON*o#*g0s{=WLsWbxHy5wOI_mX_S~y> z+?kkGT^u2XA3|tJUDPx-EcYzsuF#V%Qz@s9ZhLh&8NtW27jdmSx<8Y2q`}3(l3|ua z;wRFr{093o27#lbPRT09qaX%!Fh$<%L;v$rHf`T8$Ff3JSiPO|9~xE)lo&RDXxJFk z=o%6b65htoBxHbFgp-f&Y9GwD9*#snIln6kKqUV0?jsOQ&go7@yTu|KOYwlpR;r6A zlW*53&fdD)g9fx9x?1y6PEIs3;TlJw76QI`=Fv`KM246F)uV8SyB*D z|K}{JKx&#!PJZ%VQ3n?LF^T<~_@2b9*7%)z%E;!UDsg{)IvKwBQQEq4{h*qmzRENt zqMFdr%?w?YBb9r5p}@s4N+5 zka5r~TRuy@+54}42Jhd+%#?sOt!XxC8lnL@Fx>K!@(u$t`R~so^6@z)&#LCO22swF zKrI~|P2CAY_D<#1emnrf;VzU;>~cX)wP-u&X5*@>C58kCmuBtDXRM0cP?Py$ImypW zzmh=9o2+bj@8R$&$3?Ra4d9h~ZW@XHjQ&?AdD`rzSL`n-6)~4-`>J_FIVj*m#4*pX zv7NuYlbhXdUS37zd}(-Se?)3N+c<@tK`W_yGjaR1jnMchyW{^?@DF;&M+D2|wxbj; z=lG_f!PERA@aZK8IpDz~rO|;hrDVot3vtUQvVYRJ?_6sos;YqwZBIZcu(l4b701Mo zlUd3CB;!5BpxyDKn4hU-=b2gdHjW9!ohX8gl3I~(hBwRU)^H%QbU1n<;=?&0uIA>8 z?o#hxgW2Qj-K@&kFa5=r?R0Ovpm8Ajy4hcjb6LODZ27Mb+o}B94l%~l4$A|t z^9?j%Cu4=A+}9=f=N|E^yxn7q(b2|+T|_Y_&gj~oHh|9DnxXDd0mWe1->YTzZISC4 z{&@WT_IKHiLbvL=rM(x%6;YkJ`Bg6`7ohyxR+9~X`tQ+W5wJ#iP@d2Qvd#1u^VCF* zJg28A=Prgf;9xM;-%|I9IBUFI&*oBzGgFkyvYt+x^9f>HteUr~kO@{(a+tItSX3Yc z$PM+`D6C{UZ6o8sW&ia|RWvb(I8bd|%X$sKkc=_1QfTK&2)bAiVPg6nvA3s!_5SX+ zy2jYn28~Wbph}n&H60Ez3M%S22Mu86FHv_$6l(gO%0H4AtqbaEY5mTh$%#dsd+y%Q z)nZ-YfK&ZrcLK-R<+e1FS^F*|CL#Vr{k4E$peu!R^ta(UtLGu^_wV1af=vAWs5k+% zUjYWHHV%%r#nYy`-T%Hx3`QA(D!sCz;-kTERhz+j%$|XF3n!G?flmCDot^!d8Y{Z} z{>~p597y-@8sueq3h?Tjc0+WWx1(a-4rx;$rC%*K33^M1ryv-IdUbty>F2#6L#eA> z-DDu=x$u41P!axp;RLk3ySx$~L+V4gr=+e?bZO!O#+U3|NEjE5Bc*oUV<#UKN!>uqfU23|8baOhY$TrUZ zK|Pu&^fQ$>M9`;_$ZF&n*CgQ9?Rl3BQIzi^oSF_sJ7t*Fs5BNq=-qn2R{esdJwYcB z+5ru8vEF2rY2xCBk&?z@yO66+M})*9Ce6p_r*_r+#8siRz0U~aqr*ZvJAdn~%LD`C zFGk9Ngzfv*rRG~wa3!L8wN zLL-ym$mdccqU^^B!~N|Ae~rOY2#g;9Rig=4FGegL=MeHgYxlcV&0fHjtl_0b$Vuq@ z<&9!T4?ptr3(54m=TpirsE>_JALMjK$rHSelM;xQFR5>1HNCi@tVvxTsw)u9VGZGtmV~2MtOLkE<>6C!l%O(Rpbu-0_J)z6}=2QO!ndH$yac z=#$1GPJvB&egWIE&^pVYHlfn`{x5R-yK{HFq^v2T1KY8pLy79MSY}gM1rC_Vo$_nnc$Xz!NkuoPq%w0LS|vu%Su|qX9V4ZTU-Y3w71q-!@r)FVqTgT6bNNm-JM*F zk{H&Rjzkl5ouOXC;FkbW`LN44Iw_Cyz9DMO} z=mk3o6o&)1Q??$RU|V_{bPOB)b?+!qFTf%qidb0CU;6C=t5aqC4^&Y1zo`Eee)ixJ-a(W~S_}v^0>D5|t zgKjB+8V=OquB*WOi~0qV^5u^fi`Yg~b5q8X!!Frr$STtP7mPUM09VQ41maLENa0ks zp0RB0`zl->!=_e;Zl_Rq_x-=ebJM3+SwFsXPg+UJOAFsF5k!c`CI3r3QW^5nR-{WT+`i8JAV2eeeA2ycf%`|n1OR~82 z?z`1n^bb&DI9l^y**>{!8K6}X$+?wEG*~#6AnL-7Ni;D!bK|2k8DjW_s4bsK#Y2~K zpydwl$n_5o6EB0w{=UBSTQIMPffRTMORCd?XWpyY{$y)1xPeXgkLz|%mVgrtFE4IL zlh-ahIFqn}@m1W5Lmfa)*0_(tXWas*l$AZ^S-DAK%jEP$lGK>~^IBJ1yuPs6@wHnB zHQJRefSFj{^9J8{Bb5H5#qH}Y=(uZhUujO3)Daq-?RMN>Z1Mu)&CWVEdGjVotDgor z*J%?aL91ldWd3VAq(;JNj_a_4m{;7Bz{8Mh_ZYEwZUB zY`IYzsfBl#NNw6?N4ZRPbk(eh$`TQ8=V3`kgp1KJ$Wvn34W%SoC%8Wa8-1dG9hyjA zeb?_XoLYqmS!XK61^75BFAqkwADek@J?x3N(Lmq0|3*zOg~6)ShU#2{gF#EzC-ky5 zxIyiGl^U;8V;^sCK`>JLc+k2UWvqmd;9x*gOrCPqo8P|IEH@|1thvG-KNSPsv7{6! zrE{%!fh8eerp52}LnszT`z}BM=Zw`3qhNzgz2yO*8YVW{-yEIF75zvc7x9FS?n-l{ zZGuMUJ#a*8CFnH(?93yAYK`dYapS77C+F9og=WkbXLo|O`4a50IW{1C)clT3Zdw@E zF9eI`0{8p@9*J9b;_-z;-XCL+8^s}De~WR$d<6~pjJRNx&OtWAdF|Xj6c5M~gDGH; zw3;zbv1f0cPmipLJO_XZg0=H30{ZiP41g=^__l}{F#$20u`@|kEP887>#1&1>XUdY zw5YOt{)+`nRnC)gIWa;C@`66Qt+MQtb*viERLO_gx9a(_$`us+9?G2gfwHaXI8yDK z*jTb~wHd+F1k##*$c5VqQ%nbWT3PA^V+B8cknM7OldZVm3;&01>+0lA0mxQ-Ik`aB zdiA83{x_SaF(X-6-cj$y=q$L&y5(RTKQNeP_Qo|etj5QS0X;o6RkqwL$Q)!)qhY9o ztux?qDT7l!ZJ_8+2|=sV{@aVHf=o-h3$&k!2XKM8Im(=n<5RA%-m! zqxo7~h$I&Fda7X(|IjasK>`^WnYH2hT5iyWVxKa28YNmDdj%Rao>2h|GC?f(H8aA0 zXvioSCmrTQPrO3J^$Pe31CEkZYayeJ&0w2M28Yr;GVW#X;vAR5VF!#_q*cfJniq?% zra_7SIXLbim?yf~0I>WRH~K#F&i>;}9Ow2tvC|5^N8;;sZ;3Yt#;w(d?>bnN%}}iB zC=|36BZx_B7_5)V&L^W5|3AL5M?uSNFRQb6SA(Nf0j)<}UM7C$g0ZIuGVM#CHUfs6`H!47D21LBFe64A_#aZjPKO=O8r6j=; z>&oQ#4KH#tizONMUbO`+4i-wHo2vXKU-MQl;+=oG9&E|D)X$ffmy$|#J|A4lpeqsx z)U7QLIoxKC&iU_ZzCe0AZp7QrRI*I{!p;cn;aT!r-r!BaYBp4G;6yksY{EMDrxN@& zI=$95e~J3^cf+bM1Jq(0`|JE9XgK%>%(*Mbqk8+n2@B5Z7{sEtC z$srmO>xYe_Q=P;#FBE!I4S5NydZO_le7dn-O89Cp+fvOoYW_=PIEWr`ggp`!9rzd}KECKAWkb&cs|Ni~^9r!H#Uy~N(ik92M--Isv z!DfuRjg(aIDrl#Hsnb7hqr-WR0UiCsGw+|FR8&U-NFz~8DU>1)D>>zYFg;0PD5I8I zoF=&1ZTDm7c!ar#=NQ;{vjS^n6Hi7tPWxYQ{l_`$1ckFe5c7aaLn=%J+?d71 zS{$c4(sec@31d$jfw7Bm^YgsPTb&Q6#!!i^T+vANmcV!Nfiu>VdI+y;jGj ztAgy2jVww7{mkDXA8V>CE7|v%8o+i@I~ZcBnvya%CH449{IOC1K)Mf6Rq`cI=I1v> z!t@u1XQC9{@Yy)ssE_VB$^MIKg#0Lgl!OBlDFXut1G3_|@t_;j^nBwVChTu&yXCt<|WC`#<20SwO%H z^lYosBBBB3x4j$xqW_yC25W3O9ts=+!UmX?4}0N%^9YV{_nz7-NowjI^{kEHGODbB ze#Glpfs{?Hsi~{8%Uih=Dad^y?HaErkrIQohp;o5j)ZO^Kd~7fkzuJh24JoX>+Fec z;v^RDl@`PR2c6s7iz?dblj%y_g)#nyBmM07S)hV}2N zb}#BD58jmSn?&5$bm&K3)LeYI%#?hM(qI`J?!P_V5ml*%P6kGLu{QCe38xEbVXES~ zIe#2x}n1wct@u1~VR z&*ixw2QvXF{FkLlNAV5-SHGPyeUM+K0V5?oRBxNi6eDRZ$MsEp$uQ#fmqM81TZk!o z`}Q}dasKrVU&N75eBcPThwmUpJtlqkTO5*U`_GgIiq(f`VUlP_BH~Eq=lQ<9Z>jJ) z;KZKjQpw+Y9W8{e#_iCJ5Q&u7ICQ&Uk$7;uMG7~Aw7jdyP+}muf;qc`k;GIR`AV~g zM?U$3ts)0DUe5HR@))UL$yBPR^#)T60>&DwCh$rh+PUfz`I#|FJVu5xMV z%*Oj4+VX3|A;3}u-mOPXL`C&}_xFFZ6!~i&^PqP0RUjPv7XsAGrEbsHu@$fYP~H)t zZ;pQDD;5j`OHB}E%2S({+-d)&%bE`?*q_aZD`z;pK!h9_8`t0iw^aC@W@nLIBI=kH zre=J+-ny{EUTov5n*vIF;{flCJ6ij*UP?*CNNBaWKtg)pUfm7e&nq(jd$=Bx!1jNv zI@u?=#pbbsiC%b=oR3Ji^fBEcucu;9&5u_0y07T6F%%g~)c=R3vjB@KTD$O>p@!~| z7L_igJ4FPf8ze*!X#}KUNRf~ZX+#{DreH?j^k~y=_-rru| zTJQdL=S&*DCGmxrt`&uC5;zqMx)G!3%U1NAfjDlDy8(1|_Hzr1>J|ET`1$t`NXr{x zL(rDQOHwtxR;Ngv6@R%$%ZXhEYc%}v1AwSg!hZRiRwH}KAZI@lr}NKf#@z_4R%Di_>7dyWHsv2i%w||#BL@suAl;j6wR`vn_O4PW^QF!hY>^<};feGq!?(D#YM4Mr8U)^%;nCx;D%v zd_U)4D{6m1&1V*kASO1rx~0O*Q6gZaXZsGXwS8Tkun9urXHFC7#lZFS^ol>}$>xvC zgU3??oEU8^4@aIOah_-&Dba~7-SrNoN59>%aoTKih#;hM-Bkpbrl~NQN9Qi310M*q z-`_PqyW9ztG2uvk5~WmBTO|AJqTPj=d=e!_(&87aVD-J7lk2{h23F>CC@wQoE!)?d zmDju}qA61WaYWp4^zs)e1#NKRqu3uB?BSJ_d^1XQKMHq+{|wYE$Um)EZyf9D>}ukN679i5AJwMk ziwiVFmzI$@`@^D^#zk8!*rgwrhwKv9Ak)dlwDyh4R>v_>G~-*^G%Y(DR(xdD3*}IN2@TXIr?Aou5B8P*AF|~`CIcMPCBeH^@xYEmY$UW>N zOg=YibIs$pWA1{DZR={8crQ*jCB@jql9Zi-J*i;$qshri_5xEc;mgN~8D9{#*+Xn` zjYk6wAYPSy>ObT=Z$P_1{5F4!AqFp$|M!{s^U=k5FErXeG^@LGq};?@^5XB^t(jB8 zue%pH*Gmpmm{F3kZb`N6T{9K8M9Xi13MPL95z-E2%|jt(IN;ITi>T?Hs=DkSrq`<# z)}=E9kIPe9s#ct%d`5Qw8W+0IG*$!|DuY#@A*D6x^!M$TVu>kI?+&9&z=U`_X&t5 z#X5wCO7-Koo#P)Rn1xh5iaHQ=zD^Ews*z?7dovw_7#Q`H$QMuNN|=Mx@7hGL5nbx& zj2buJosR+Yomd6Rtl6jC_2<>`&Ro6MK8rdv<*laPCi43bWGgTK{qWPrp=%~Oy8iww ze5kW%kkY6^KW%{3_EYL|*SLMX_qMo`StHStb3$Ex-L{Xvrk7uUA#TWe_?oyPN6}zd`%9*W!jYkWfhlw3 zucr9r?cu}L4+Ew72orBigQC|8TZ6AiwD?0YNgm8o4!1V%!MzXjPxqIC&#S70Grws@ z-_p={6lWN{+cF0?bl|`BWXjwffvvzZs-trV3h`nb`MW?0OnFBqLKI2@w$|&ysVJ_> zy;yR)>Cg8*nKrlQ>9SKWr46i& z;DtTQ$2XFZvKuS@3A!hb06XI??rj33GsLaQPBGcsbJ=YfWo_&4{fjD~`CrMuz&qq? z&*l8j?miF@m$1AJk8QSN#d1n!BAW z9r3kdChtS(%nld7iEFL)8)-(~Qk_&UQ{Dm3ruXu93BPnhTaq^IpBx+N0}kDzKm!>ox>E7Z#)m z!(x}=Lvo!r{+6y^w(zXfArq!kW4#%vmta`);_$PJhJ zB~jyb>%~TyfFSLYY@F3!(`?kh-RjjIj5XEZ#^yfh9GKcz=M)3Xd>F_`jc2*x38;vf zFY$ihCg4=z2tV1l$MC=cIg?Qi^S>y@{Shs5yc|0RVPc%6-V>!^NyL@#^n?1m~@y#0}ls`8qY{V9`fFemdQ|6qG+lHKxhIVtC@!LBwQYZ~~6!UekV4nJL zj#VU5ME&}zcBQX@g%Wb#oS|G8KZJkTd7$Vcg0q~rkedIO)IzhIU^S2~=(Rch_ggVU z@p71yv^=4qUdND2nwXnSmH<#TRoK-0Fn@n__yJHndnX@6s!f`y;du~)goj#j=|Pjb z7zfAWEZ|aqy)(;kOT@`E%Mb}Rkc(jaD}~9AWNZ8e1xro4e`fGFg13M3RFK2Av%&=i}n|N%)xJ&>g z{0L9B6R-ZIG;C1cywim5qgoj9;LgCUHeTXL{;{n_}HYLKhK(d@%M8#YRXol=+d` zJRu>OOT+uiUO+#(qT0V3cs+rPg@j>zQhM}Aqs8Tq{1A|2DdAp{A|j`*lZi4HfA1WZ zRkm=B+X~JjzI!WxU=Xe3zmgX@Sc@jln0YtN{0TOHJrYmDId}WJP&VmgprK@Av-Tp9 z^~vXKX@6s{{iTQQ_R|kqt!&vVp-zc-oLt5R^P&EJx0rp=HBHPj8-lU0FV3f9CC!%y zcfNl&*0txdtTmQn*bO@I5i6}V)>Jt+M4zM{>;J@EHYDmHU^-xCRVL4T8x+ZBx>$+% zH!$9mm)G6+d|}nE1df~-xl@2)#a6OAzo+7C0I$Lec`*N7D5bMaD2!drE-K*nCk18X z8VlO4=1IEX+bx~ld@Hir=`}3o*RaK>UN!Hb_%Qi{L$x?V083wVXbPplu24^9F zq?LAj8ym|8=GweRfPq8%;5nk}9Roga>GD4P)&`_Mko`*1J^?aIwDR2pu{*h@yt{Oa zj4gf}VvM9Hnw(c>u0G{L-TY==weyy^y zua%cCPwoZKiE1{|Hvn-@($7Y8h zQDlfjhFoonL9nT_fhQjeTjf5>_-7dN&>|S{fe*UMh$EUR_gfbpK6`mmkfvhQ%G?lb z)6R6www$s3WM)CfvpN(9q=GBUK!rhxL>N|;lkoA;bZ;^a1~`8``rd$_jWEQ#)F#x} z>VN}`O0a&}c=($)cZ7vcQh{S03s5UC)(5j{_=v5HdV#Z9kLaFkrvh%($Gi6m-0Aq+ zPBeGt#UC*Vj(c=9T^l2 z(6N7KTtA97^c67=5c&8iDkjDw=IiTER>yLJRP;PHvf=D|7_$=!y*FZhUoO236bWM{ubA1M&Dj4d`Bn7s z^0mJ~cc+Za)v|WsL%;lNdj(j)>QL6_^?^7Fri)0~Q-iRFP%e!mYn0lpcip>0ON9 zS!QM3_S$)Ggu_TLy7-4@!SNw#=usT-L-|`{V5d_*w3rZC@H^afZaHV=1&%7uqzY zp~4xRJC&#dL9A5rY?$FQ&(k6Ey<&}+^3n?JM_*$c9MI38OHRNtf-(leL4zNNSW^zd zz^F|`6@`TtCa*U{o_nA#V6lgUH9*4@x6lxCB#98DNJ#JX=x0+vvyZiqQd@r%^`z0g z>c#E4O)qS}_m`duYvLMZFh6A+zm4kYnhOk)%)b5_nq%xLVY-WsE|uTiM-S_Q{Lh=+ zlGNsouV1gPMYN0z?l!h81OT4R@R@+Y9o%0mj8@&`|9W-SU5=OTQ$kz6kF!c0Q{6^k zKhR4xWc=2B6ldx4lS-gB&6_n#v|xUJejgSHpp6R{7NEkLYR2-moi4pctCMqwgX3R6 z0J~H!N;SJN2s+Q3f{cttJP=}ic4oyWsHi>^7P1y{*ug}VFVVfLue1UJP*BbERrsc9 zOU?mR?`j}v*y)*Fz<9%)04>+9Q-}%HqEo9m9OsN{pu5-wpnjJ&6;*N z)rqxRzl{0Lq;uiG=Sc#?>s_6s0(jHO#0>Ry5G+qv^xk(yp6t7C7UeE$E(aV zN_>fX_&toHorpNHBK|WwWWO64D(<*5(Zb*iYcGF%y>&N-P-ct|%d{KiL|U{X!cBA? zo;PwjYGRplAzqb?`J>ItEZ*l+S7h3nUw9AeKRf`!%X>0ibTx=1XJXQ5y7$Z;^JO6D zx3qf15ZZoh3hY@uIQ~=(J8dLu!+AcOD@Ost99BNsnkEM-b`Tw@ECj=J$wA`I21Ds^ z*a0y!5`rVx!3RlhK0_ia3q$p>ub==J#Pv@S* z{#D&PTd(PtizuuWtd;BPmGg4Q1tY9dUXqae2@fCAmwX<MLuhl1h}NeX)0 z`e9*VSt=?jK5%5Wb^-|P9Q87bdhO*>Na{$r^?>JA@bROv^@H~_lk4#y;jMECjPlACO)XVnnnGeTxo5U6>1qo{_D`$>D73QsGH>@1s4ZsFb0e9d;9tE=2r6SeM z)B5`I7q-BQ!BG7&Yrv|jv#p(Z34nFd)}(hr7eOQ5(+MD!EWxV9Sl67_LI%d-O9uz; z&own1scF3i2bHCzeY+$1kMJSDbwl9d%6WT>0fGuCBjdY+1K{%W+~HPJQQ5#+OlPwM zFY+T56}%7m&eqo^-`rnjxl!?&_85IGz4>LXnyzmL5^?F5+y0HK(GO|`+R2aJL^hCI z0m61Q$WBpEQ!m#}`jv_LHk-wlcQg8`L9!=5h-J3al$GmI9poBc^f;4A5SSHrSXeMy zdh8I?yrzh_4u2KYtaN29v||8pkj4oqDTPkunU|f(bFP0c>&iiaewC0nZU>kwSyale zUw1ksRkmETDD7?MB zOMy2lhaw4F#2a8OH^d4!4sYMSl>=2FHbe(tpKOH%1>1{vz;nP@N~4L&AZS5L1Nio;#x%f@`QVy3PA z>UT?_tcptHm}{1HAZ1XhnNRPz|M|h{tU=*?z&svoUC4VmMudclDjc)|?%ut7_7HV^ zA0(dJvJ3Vrha?XPd_b@4HF!abi;EXkcG8=h@Sn_G-vyl!UB`u%xvW#A2cXG7c^eb( zL<#GCclpnY_^uF8T=S7$ol4v82M7Qw8-0hr$4yN;%<0nHtjBk>>y`B+{39k^tsOJ$uqL?Bsy5B%-C zINrQ>b16Y1`0}nn*|_nYJ9k2ao#zSOh_nI2+k4>V-ZrjyZTkHAN_OM9pV+A9cK@q} z%vUP38j`xErnA1FqE8dDrz$Ni)zs30#VcdxX(GTQUO6-_j^w7>m)!RcXvVwqp(#m8 zV_HOFSja=nj;^kYQ6a@iTLG&(aBBCFfevx0X2zLJu?El)E@v-qX#5{ z>?@nsj#_Xr;W>1|;EHk^e?b5M%*&jV6yamA2UB|Xj0KWqCi&?w{drYCOx|)|m%#S= z;<%{^vbMHP6LzGP!6>kL1R!^1U>?cU>h~WbcAbdhSv= z3fxF#foFekzP$XU6vnEOIoJz=ObTXZ*#@39>O~nK405938I-4}# zKK=|u5Klnil!;GCS*w-y255w=v^2oo`uOezGWPdE%;=N3W4@h+dUYJH?|=u8+R@Pg zK>%@tufn08BfVXI$xMMKhX@+52{Ehe1|=QFd$qONjRdaqqK_Zz^~_9*5La4o5Fn24 zU;R=&k1V8NCRSI@h5If+d*M)zx4^?*jQ!u>W{eKz|OLwXzlZhi|oRVJ~7qfqLu| z!o=%OFo#LoMDW6vl#myJ-R}l)T3?V@=&-{;7Rf$|4N3QWvchEjX6UO<=KcUSC6bh%=<{K8*xsHc+i%;@~U;F~bXeeF|n8z@9#@&@W>kzjdqR zK>o8w&%6m}PO@h|dPiU47N8*a4D^TZfTf~bp9{Ram_f3j3?cxfVTyIuZguCgpx)<8 z^Diqcmk1lKz##p51Xq0YC?A+SMmdtFQFk29RPq$rS`_gGg$Ag7?xjjgWB7yglV|nAkX%1o!^l($UwhS z2AOU>0NU#WVQ4+b1q9^)$8X=CNCpD|tCHhQ)o?4q1Vsro!0ziw#E|C~%4f>8pjCcHav7=@;7($4|0>J?IkZ^w-(yMZe~#R=SO@S>h1@Jk(gW zvTJwUXzT=V**az88?2}Bvn8?jVs3?uvbKhXH1mFkPr&6|-ya*(g=C*UzYAcqp%^$s zTN%K(x;v^qdATi)-X#J9!-G>u_{%#`Lo4KuwAl)R9Rz)QdwZ2}1!#lW)PN%H$Fu4- zo0$L^Dqw-&kaCYSlv$S9h2_*5J4wCEbD+YXaa4dG*MTU8&L*CzLoFZ z@C?C9D_1uDY#?38f@Wa}|4|I>I0tZxe{b?WtOA}ONz~agH0%TbmXp^F8bo36*|g3W zy_SU5GByja!5J;lDJq5j^ImBwXD#vdG*R}no9kMy(oW0_=osC zt_uiTjTRyhN0Ta^3~_)DJ!*Tf&i{Omd26od`-Oj=dO_}@--6OpE3hboNd-){QQ!u( z+McNmFnp@}-M_!5$Cm71y&MfD-j~-_AP|_cwzeid^b!xejwNS4Il$cDTs4GW1I%n4 z=|c7p1X8I06Hm&9tc^ZPYGGE@-GAOy`PP#U>ozuP$W8Jn2+ z@a-Ed*rD;$5P%(j)wBZ?xBJ+}|CJ}TvT>juWX_(f^7z_bpEJ4TByqSffD!OW!xUNM zY;D=qvn6rC6i`*g-vp?`qArV&neVnx4h2#xU#V7ARkcyjaYoSZ`goH5+!Jz{OT0Jq z2-ooQ^T#@IGLW+90S@x!T9T2G6~|f?--7DYT|-QHE1B3`CsutqkXEo6&s#WD0lI8d zxzZ?pIpmWksCUPoV!qDS|3lsqusM5z(rB*2SHNC)HRpi3pmRXYp!|2GDfyM~+Ul&4 zuNvsVP=dDFk>J*B&z3q#s|5=c&^+34UMdpK;$7K0d_>(WTRY|G3tLV;s7M(MkCHmK z{QUfGYa5%LY{8dgV0MfFb;08G=|UZx1Y9kEDgN%NcB2tV9{vnhvTB z0f4EfML|jV_!pQPK$b5Upf`Dgf&zTuz`|t;k;Cp{*kbq+wB^iP6VDoBE%GAvK9$4I znuDQTp@YgwOu?>$(=W}QIej_QM=1^Dw2{*O7h_@pXM2`8EBDygBq))fasjp0gc0Rp z|8eEhMtv*@6q4?$*?@m;0RBw{wcb-Bym$SFf>4D6y!;=*jBz;Q30k-(wu0%^AX7a{ zM@}9BE<6C(;(u6W53+LNK|!E|c!_iWAY6?#M2)qqhI@FD12XuK+WUOt z!YZmvdpLAaD&UpswOPQqH7Hw@3$#Jmnh$!R>^wZH6%YWbq^EdC2qZmH zF;CM}0eUhSlp#)+(}>I|P)!xCM>{2;0kddFxo^0ur^$WV7fpn_KVbjwWxy0u&+`W_ zpFR8Fvpe7H4lbAnMbO2^4g(t{C8dyb!qlXW)DBrfj!Zzpp+0wuh>UzSxS1pAeZU6@ zLFhk{aL}sVy6B>FR>r;Ev@-Wr5<1?kX*_pkO45D`I#Nr(H`ruVYpi8t^e-9)A;D~t z3qZa}+JkndFF$8xpetLqDg!bh^8-)+!P6OSGj-e>j6!^B>YK-jtbag(-4Tq152}dU zR8h@R2J#%%F9y=X(4ZM<2uQ||`+RF4n(|HOj=_sp@4wnT0BU9X6Gq4b6zuNc%mB{7 z6iM-N)Jy0qEDfKTR~AM1<0%OVy8t(0W?oZYFFIOjE^`5}lv33|OxzXyJXd9j;TLnU?y}lP`9fuhHP{D`u?dek zj$8aM{Yv%z{MpmFNgvesl#eo z2=@zM)hSea`8RIZx{2T$-EyRSo&_L5ywi}mPJ$Mblh$_wPcsu=PE}c^NqRrn74}M` zZfh>W6jVexQG%z?E*n-4%^t%7`wdXHb_S%b=)SowcMXKiU2jkWkb!ccMoz#Z3gbWl z98`ASGpi9Wc3643evKWV2$ZI;KVo{-e!wQArJ#wx_^%qWsDaJuf)D?HX(Si=pIQRJ zu>M~yxg^nt92SK!7jeJ0@%;DeqPJmJy%N2E=yCO~-ko}U`*C*Nad%6f{l>|E#FFXN z>!XW@tvD&|OzxdoDV{4r=+({uuf`^TXoN$dByT&PwVxlZ>w#%rK93}o&%Eo`pSh~C zVnjHO1b|+vbCMurIrK1O0ePPxkkRzgR1WbEKX(9#pkF=z4hN0c3NC^Au!)I`>@!&# zW%ny>RxYmoH90f4H+8Zah&;&U-&vqR@1x|x3cg4&J_iBbPezASwGexOE`s?17uTlt zqJLxE>YNr&yz^Hc^P1N4#0Pb+1}4cYb?Y}~-`9-d1ZUjd+7%c(O-LEnls;%9OKpth zG5M+tVzzmGese9?+bFG@nyzyFvkW>e^tPhM#TW;`Ji7zgWFTGSk@k}4{E!FOLwlG3 zdX{NyEd}7&U+;*R<`tHgmvrfKHg0bJavN41ia!|5Ed4B2N8?wuF{(HhXwWDt5BMU>m zmZ{0x6NYak+~tHt(k4*{pDGG|us&HVK+tRTzT9P;O@S7+Y^u?ZB9C6m?lQJr-HW;7 z^hx%yRZU`p4r{uKlNAub)vMExO~3cVlC&-Ew#eznA?URWN~8NT39s1s`{hjDq9uoIvZaMF|vw?P=ovb&@iGm zhoUrl{x?BGrp%0B%xJ$3)>2ovw`@7!uq6D+(h-w8U^zZwhH;FF;} z9R6u2uS~dgA6re~`lnEJa$UffZI~cZyf_CcmcHV|UJ*wUq>DjrN-b^37ppB7Do9h_ zB2b9|nXvGawW>eMMAMywe<90ya>7)?nxVSkOEWQa_4+ztJM9A&oGl;3n>^mQixS_< z^(0;#6T?o5w7k>q#WE7yyG&3|sqpJe7dPhK%XepB^ArIVS*YzqhlPfRD*38X!CxEG zPiu*u!%Rvhwe#c$_&*8Poz1rvBwDtk$`UGCo3?emScwd|{kOu1Vi;ZO9HvQl|#BSLTZam@X@o`o95w*Q2zi zDuEAkt@mJE`$40bxl(xG%EI%Ar`V8T^|MYMEDL2;m!s9j(M?^YIab z#<4sYBA@{LT?r0EY39%=lw1#iGmBQ82BJ?_nEij>5rV6kn?}9C2@IxQdqNq|RQ37t zd+g+sSVqaGLD-|rjbz_8)3W2^<>t1XH-cSYvoK=hrh;*++f(aU93RD=1^;(h0tZ;; zrDE~_(YEfb{!iNyDf3ys-Fuc6P|BQ7d7G&fUN%p#->*u-csE?@Idafe7CfueKCpGr z8{OM;i4EB+ag#m4rb2=?f|68+#epb%Qg#O1LMPZVl7$=`+T9)())j6mL!>egJCUIU z|0V=kQSZnNjw(_@^9Muz?nErwer0#!9>nQ4KmFQ2a#4Au9h%^|y|P={t*YEHGUDog5X z;vIBoC?@E(4M|^?_nNshnC{#~e^Uv{w6XRMSWn}a5#Qi*z4}pDFBU7Re)ohA17}{k zdr)m$y!ilX`&^PH;+%bWcC({=)``b2^(SAWKPEHkd`0+eWs{;$J3~^3MP|V8n19m76vxb)f!yFKHB5 zr1)7lIq`rPfZhLDG!P{@QEn6hs_xNS=iWcT0ZX6Q_aecciDz`?H^XnjkWo#vWCjBgp$F& zM?jYF+aDC4+1hiudMw=5J6m}qN#wqx?2nEuSAan&JS@4GRd2e_=Gz%Qat{FMeHG~3 zLSc(4C=xu)SL4!W$z~!SR88*t6goW|On=PTvg1L@5gwN$C+qZG$>erDq1@CLE(;^V z=q~!HNYtMUw$w+f!saSXoL`%ABV&Cqa{MLm2hw;UfL4rYCm>KjxoG8WMZza5qPAI-= ztCU z(M!P!M^#1l`$_2~07{fLXQC|iH{f6+ph3BL;7b~zEkj9Cv}yIc&lh8NugqVLr5=jQ=Htu9#mN;Z-~Tix zsDRSo!X}C#++6BRi~}=@*u%D3KH(!Nqy+K1t4%JP=sLO3veT#C1MdZYtYZVESx4f$ z(lep;tQ&uL*C%(-wKApbS@T^}9SmV*#9=%+|Fu4RdFLA09?GmjiU$j2=C9VbRa5e- zevx7DzMpEk!q;G`PRuQA>BuPZT=i6lxEXD_QYS#yeAQEjOc?_`@NIk>4^7e!Fj2##2H`KcTtCd&mhWu2Qv-!;eoIrj|Xnt4OE#wh*;jPhy&!k*h*?y(=z$7Ms#OPs(_0Qc`#85 zdDXNE1W^Y%c}|LN6=vm>+QjONfi9J6yt9R3>+_CBS#5<`yJcPKYcdh#CUx&npi@*_ zOcRyDbNa!k43(P{Y)NAlq+C!S`?%NDi3LV7DW8uKPFSQ=8;<#BosF8tQ4gH;jJ0SPJ+3 z_Y0j0&p+POAZJTaXOpd{RnJSM_bjs0#y?ROq}X@a6!zP3EYeIQi`bze+mf z4ro@?^m&TV#AdC*qMiA?u zr8b65$6idF<%mi!Q9(-aE>ivDGr23f#uA*GYDnk*3$$j_xt{jn;Ja;|`oC29n7Ehq z$jiB3d+K3JN<8^WIkm9+{7+Q%ju}#W&euM?a!*8`Av#@}Z@dbOKS zJMf>zSHw*=!pn&o(l7TI!Jdr(v@t?S9xH@OeRHNRM;*9zsOP-%ocHd|ALVzRm*fUt z0hr#}mp;3PhlhHmRlrzS1bXwOKxcmiL^;q3EGa4309h8{vs0gD>1Q|RS4zC*j*N;@ z0F4fADtwyoplJss(Ass4YYd9D>VN(Ki(y)lAwS2Dy76G}&y^mm)Pn$1K39!8nA-d) z1@Yno^PTl2btvE$3^vQK$+R;onrW}Z5--aVzX+(?t^q0mO%a?5l*UAd{&RefcJlHB zm{I$1MQSctT)E-$Nb&AwGJ`ls7|(P<@52|B5V~<=-CHrk>4f!`4;D+cVjo!X2vU)M zDaW#z@D={4Mci;}&vXfHqv41h$*j51hm?4Fb}S)be%ku$pvkFY{?3ee$54DAzb|R~ z*25+#vxw1AZ2|N58ACO;S?^at_qgWILBoSgX)pLBukJj6m!t3-;l@wZN$vjP_j2FP zHsyX5@Id4V4(yKjL*jyH1AZeS!SpIjLlOl2r{Q8}<4Q{ZuE3+=&sw5LqGL{prTaQ&D zrTj$QuZ%QdAtJ345*2|hi0vsYJ4Y%!p4vYj)uWd6C`GmW$=OPUL`!}xmYYT4C6dYuOV3a=+3XpVXx)f4CQ3p57ro9J$+AYb( zKMU;CZ`v$ce63kn3H?mcD~*DW(GAv1f!FV_z&bFi&CYafnqJVelx*_soKAM*syc#Q zQ~qKIlb;+`YrJj11Wt{0Iyy_cFRO@2!azvCG)2F}48#1%Q@s>NQi<{42mfFL3S64o ztgMBDfbp@=3CMa;Tn1;p*0TeXjVyP5c;a(QNSJ&BRFJyRfyoO`SE&W6qBh4G?pBHu z8~L`4CnU9-c<11#G$C#{>4x9>zER-g&fiREI&c!ln>y_1_N1PjsTym1Afe2*1Zq6* z8L12myz%nicXq6wKr|63Ln@_7hs64uoIEMtqJP@;gBEnsy9@-%1^(F$@E zz2i!7W<;jM#^@QWY$50E+3yQw1J2~)?DLzOs|HG2Liy4V8rA?s} zN_dgrlUXfs2S^X_F*V#We=(`m1PB3bPgER4U-uO0-Fg!9D95>Sp0h}_SP}-&j0|Pp z+GRSVS{{BIaOU;Po&Bp+rMBAAqs5`Y)Z3gY|Ll6?^W%d?>EDzkfIUuFYWWIV4vX*W z?Ls8zpC^;eHc=2|=@Te;kO-IGOOr@ldge_S-ra3^G4`^l{8`4pTIQ|+=eDEAJ#gZ| ztEAM_%dL4}5=pX5`>ia*r7Cx&4F6b|H1QV8WgoHkI;`>A$>yV7U$@IigIDE3LL{}3 z!OUN7T}UNIdv@Pj@^G4-U%Xv)E1IO%AqwV7=Ds<`fWF{i0w$bP(4dU1O1{|0$Zv~LBaaZ4AZ^;XzTeH{Y~qqj!u9GT7YkRu@+)g* z^R4hVzD9!>RW5kx3VC0=eONzPJ+;7FoX5^Ne8sHXB z*cPN{R+mOvx(*oP8**1^;lUT{W>k{?mC13eCQJeN3HxXf>2v4$aW;)C44=~~dFW|= z&q8g@<>rCPjUv63jg?q8v$ zr9vXl?|tyR+*prrko_xKgW*)PXb`z#iARNN^>MVxpL0CzKJwi7g=r}P_GX%+W2JqR z!Ki&zQ7(15=SF8)4E?@&i{CBi2F_dbVi9x`2ZP3$KrsFLJ$R|in~VZY66tfuv>Ff< z#H%6DA2^-9sMMfA$#YXJ&vfGdozG`8EW_=v3#szP7i4-sF@PD#dSFxl%V_jKuoGT^6`HN3WOD~aUDN%*?kCo>mX#B7q`;K9yFJ(^tRFOD*oX+ zVPjS?5>1mH*YkCo;_xF~C2aF0x65i|cmf)e3^pf&CmS*mCbKdWPnb&H#&j>Y(J!19 z;?OD2Ly#({R`8otSa3w8{P|N~Ubd9lJ_z&dzjOjA@07O#Sy8Rk|9lt%C0+t=qzRDi zXh7?+6Xc^P4=>Cs6i_W!;f^?ZPs`2n{xhfTmmiN+!DYJ{GAlzY0r6|{f{NTCeQO?tsA>gZU5Q-~ z^5AqG^{D4caP<{qkGBXMUrpZk(knsn<$kNi%L1s#H)T6f~aL=LH zPV!typl(-Hf?7KmvpqE-N1d^UKl zw_@`Qez6|wy2i2IRW0=1mvrJ@RH(<}{l_+nQLSafW|)@mRmno;&2X62xOLumhH7vr zJ-x{3$#WGxZ{h^ao-po5+{nnwc|&j1C+^LWe4Lr)vk&f_J9DK8r!5a7i|?_}clr|e zaINur5e5&lZyA=g@l_zYgjk$g2W-MB@5>%1L(=*!sh5ht+3FUeoj%>@xr;6G;kS;UiYLAG=SZMJ({|uOD%$%H&+hZk(DZau$ zqXZ5|=1^u)(X`Z&ZVuez*2&XIY?mBwXeUW~QRF^r-Q|HGk0`^K<>F3m{m%=)&W;ErSv#fqjj_k%r~McMx+Q3?CL0rMqVibciC|&-;Pk8h9o?wUX0(y@E&xV@m&!+H`&a~ zOdQ=eM4AwZ7Jhgvt=s<3N}2S&vY7kA&7=?BbHiozWQm(w<1dc`?@IZ)8_d;PI_Q2c zxP$xhMB)9{z)P%h#4rDHW-;x}z!x49nZd;8i z`W9Zd`A(m~;SANd3tWU;yC)Z31=?b_+1Or4)B!K_L9rU^Z$>YnrsYZVq%k|m+gT@u z#FYK|xuqd;9vf$@W9c(iwp+zA+;0nj6%pi6aO4q{pPT*K?nS)}esu^F)P@}*RN|ZM z^g@O*RQHzCdE&}$FKVl{oo7Dfx`RFZW$`oYl}jq!V)g;Vf98ML9_mV^iD0IP;D076 zmoY&QDv#aH0`uwSulMSWw5%pDR(iXC-9iOHFrl_=yx(idSAjg7@^wU6d-ee^q70tl z`7svuda(-v#}rJ*{`S4Z;NVL^`;OogmujtO{23-shj2 z1M5?l*zOTh*)c!=$xrK8JQ}w6XGF*E8#?1vYr+@A$ReN4n_QF0Ze1SZ&>zogm%3sy zY)yP{JJ(fQ{^o|iqdBiP9}<#~$oNJ890`l;FsI}n9=bS5i@XIGD24^kx96p12nw1hj_{!@mSGUCH=i;Te8!TR@5dA0&*wBi<1gZ9{-{80ikbW%c-iCH0 z&l`8#^e`nkAsk}*uAVn<&`vQn{yjMx=_;cOTRPF2P=!*&Yez-fNmfK{Elb2h`Ki!$ zng>XW;Se~#;&Y844!q!q`#}*Q7ULNDe`D@O=|q~Z3m1uGE9r~64;Ro5dR{+$Ih>J*?+ zUU0$g_C0^F+C0?`L_QwCC|vfRL;tSVAC)O=D7E*!^W6k9#8Tdp-%u;>KC?zcaHI)A z`<`XK_wgOlPnHMy#HFBC2`QWWB6{#kYiweJgmIpJWaMc(LJ>%2`@e>8{w~T9qw~r$ zz@0Fz%GbOyn=RtZn8IiN$#}J$^XP5#jutUe;c-zzLxYQf;lI<+vg8WQ=Z`rYGs)WA z{reuzhcOAe*@xFgSq$HgY;ew5$f5l7d{>=gZv!Ukwa5<%8k36dJ*)0sCPtSPErej* z?x?i$Rq>#U2xW2K(Tqx`C4EP~O90H1Fj8ja=MP)6eU3IbAXo^q7Jo1%W;Jm-DP`}o zYqWRDT#>JdsiZ*w(BIoWbXF!3&tI}RGNGAS?xY_&RkmBi0c?_~2LRQGUxb4*OqXL1 z>x2Ph|D++ImF`R5&!6Rf;8?ZO*=>%<@E$ZcWVjT#YUdrJ-oDfJa4?C{=lL;QVkHq8 z9=5d9`C!U{Tl}@{JMz|5tAT&d9&ZTLND>tSK{Z!HeItbTsra82XKL4#9_M=38tf!^ zeEjX9WeQiY*_?^MYw59K4rCW699-)cAu51MGz6eu z#K6)FA%SsL+dK)}*s{tF2(q_(zxF3c5Mj2wqtnY!`h9jT`*%2()nL(Fz0bwo58a*G z@ltpa^6EG_)#Zs!RO*6HS^HOA{g=7Tt^>EDL|iA?0--kWBQ0vC?`lY&f1HG=m*~DL zF~3ONlSR%axU@8P)syi`D$6M@KNCihSchx4~Sg9d!-y%gt5x^;+un9~KBySwPHef98T(xwz|ID;OKdfxh&XWJ_NI^d3k_9YsC}}Z> zQOaf2PKaQF%FJ3k;+@a$-A#8{g$LL1oknN?CTny=-;87fZlnZRg^cH{uGtMpijvkS z?gg+^0S7q_pn|)IFtl~+bjHg-AknIfE{-^1x` zs};pEO~IMeJaC|jnaTYh&ge0Qbs2*S6JRRJo5+@(b!4C#!^A58r&bmZ0$0Oh{3{7|p)!BYA33ordek6A`UnWbz(ecMEQ5oZ= zG;EwGOMcz5Cuvm?`Qk9Pg?N%zpDI+dS`U{DbAPzT|lieRk$GulHBn z!=db1nrhXIVH%JAY<)=(yD~vyFFa}-yDT|uTuG~>`JbMCoHCB9GMlchZr(Q~;+P2} z6%Wp{ju7GxdyDGs{3cp@Ps2c+&Mc~ocp9@7`#@irybO! zT?VkKRG&5O8TM!fiLdH`s|2AyfJ@dcIV$4^Z`~7QL>Pc`-KKKIctIyQC#P}=zOeF2 zjE9|F^Z$rC3#h8QZtEYqL!<;mQc6nc1_>pkLnOsOknTPpAQDodNQZPwcY}(AN_UFV zAr0qzi}$_veq;DN1`G!LWAC-sn)5dydPySsaz25-JKY4|cY*E41<=>5{WbHVC)3r@ ziD4+~Qby>0Sl=14t!CW5C@)Cc*1r((c1>UZVVcdv>kguQ4?h>IXq( znc(}JZC_N&mm*}EDW0f&%JrK-j2PO1g_V$nqplN01@I5d22x3gk=c z8Adpka}x7*VH0;U-GA1zbQN-N7BABM9P)GuJ_TtB3S}AKSDW-q+zuCv`_Y8<2ML~- z>z|k@D`2}e;i;7vNRA5bFbNBf)VF43b(}~G3sbGEtaz+=f$^q*h=?c_o|?xG4ZaBw zi}kf;dg*F%HoGcKHiVc_F|Z*gIy$TyBGo?dWc)Ay!FaZUm0U;}MY9i$OMQjr=DgN}^I|=HSV1S8lO7mXh0(&b(%NyNkBh-W8Bcb75 zh~9un%8M1~xfJ3v5BzMqY`nuF1NlfrIsl*qyG?2@_^~H4rZ1PCPVyJ>ffuQXcb=2_ zqfR)uR2HCZ&%Jee!g&?&YF(>8@2Q(+;#s7VI(83Jd9Plm$A@En_ip9fB$6#Ga^?4< zl0~22LF*$tf{snCFzBo<#;TXs;{qT#XxX`btN>|Hf^89oD0xIMREgJ}z@s35i5Ux) z8m(aS=n!UZbucF&V>|7j+`#SAK~A2tpr6@EE_w5YY!%Zfu(a_+&|JBJC-N5#jd~xz zF}~@|p_%sGwp<+wrQ-bj@y=K&1iS|Xz}j?5(=|1Xf~MEYsTvYkMXk1!SEHa6{TqJn z%h8lcxsi!Uin&YO9dumo>`v>;q0csdNT{t}MP&?iSXX5=Oa|{Idz;i7M`-^nHG6vP zdx@4a3OB3KL;h$hRZH9HYU~w}e;e1{ij-tClM={3eaicmK{}-G>4^1M!JMBYQVU6e z$<>=v`f2UOjEoyL(X72p)|3I}8{_c16^_)sV|}Og zUPXP|^VyGe88S{#uCGBlo#|xaQzSG*xjyvmb`bH49XY-CcXJa4i8u@z5D0VMT^vfn zkTrX$DH#6<_kGqG*t;R}(kL6VPQq<7BrC|&`WH84X6B*2!|e$zQ>##ATe;P(i=CY? z?6Scp9l?2DwzkpH)Rbv$`LS4+gkq!b%EXNSm^wN-ohm+2J~iZa5r^1gM}nyN@V>YNsv;aa!P!6V>0N~2LfcE{crj^%g%&^AMQ~FL2`zK84?oIg2;m+ ziR;6y0>~}q+vK;t^!z^y6%QwkV?xVOFour>~v)_z?~fHDO4w z(y(g5hEYZ_udBwd+=)A@M=BD6BropV?_6sdjOY0JeL4Q)9hZT#iGfwA^YX`Vd|k^u zlt^bCLAs%uNqfUhi z$sA4Ez%FB;zSN| zN`s7Qdm6Egc^6x-R<^ovM4$P!ob!Gj{az7G!YV1u5`ehJh>p2<^;BU z&Cr1m%QFWt-A{0%g&OVD6PrzOulun&on~MzC$VbzV%Pm^*54TS%L+1o@EIeLD3-3DUDs*+3X3Z?j%<|Q) ze|7$W*4YG_LGV`yE7gpO2!=* z575TS5OGjt&kI1~*kuPXC4^`E`l#*PO#QB$HSJ=ZLFQ37(OW)@$LaFfe?xF09x06S z%H*8vccxMjpvjXsbPhwS9vKg|nI^N#vQ(HCEi_zoFQqBLoQ`#Y-)^NybaOu+aoos= z-YnhT9_b__q$3GIS`%JbprpVxVxl5qy7Gwp3ZESND0L#jR?RcAFn*+NS3b4%N6MGj&zc%dqiG7hMh7aG0F+-V1#4ufm5+`psDsz!I~6%J&No&7c1$M$Ur zw+0;ceyK*cN@ks6K!3f?^)CelGj)Yb-~0F9SbbZZ%;)Ug zMcYmtzLyOs-2>D03RG!P-0W{}$eP8zd-tj3>cyp%{<#-Sby`PORd|ic5gz-;&K%3o z*%<_5x#lSd#&cnD+HZXS&Bg4`7jag!zn!d^8BD$n5GKH#S-Et!$YFbuhQ#i)h=w z|H@HzF>DQwjq~O_{Dx=?eo=`)eBhfoIXu&R_^}CJs~aPnrL86O^rs;L@yejZLuE>% z#2`K;g@HDzM|le7)7)%q*v|Fmr75IJ+QUP54OQr%@t3DrJfdc-!5j0N8PDE5h=1|K z($exCByGBSdU_Utrs_RdD+5-FnqYg-2D8s}dRiLl7IG*r?V~Ii!ez1RjW{?$ESh3_ zOT9WM0@O~E*SX)Il75c8)9F~^+ee6H*F4~Gpg)SSQA}sVj|r0l2dlE<-tFSMtkR7MM`Kr7%ryjmTG;b*GK+i%IC{ z_6m#k{ydQFehjgiAJs!EjvQdBCl+ALwD?j9OKwW!P$%{GBwb>$0RlN-^I`1ick`hV z!+-}}WQdE<$c`%`WTcA@Yjsl-{)ioghu1KW6@h_YO3Dl?;1gQ6XI*|d?b=N_OK93z z`F z-Su<-?cXeu-?B^`dXxWN9;Xc{^OLC=5do-{W8V+w&3~pfaw#{uwFlMZ2pGi}rohX8 zNtFd0i$7EhRA8et+2&7$>&%acCcZBD5W?&k4~FmTzrq+tl#^{?k@S+Rdi%W$(B)3} zRDkMXTrFtjN>Fv4&-2B{Rv3S2V7=~|D1P9y*N%6iDy-ZzA^iO;4P)AZ{e(Gn3OB|m z{r5fX`*-xOPX)8cabtH1lnWxY3La1p}#br zg4~qe8tW$2CBt)kbQ3>`O*2C>cS|xVFA-Svdi7Lf?jZc?AraN0n4@S{WM@J4L0~RH6e*MI&Wi zPY;ghZxddhoVd$&eL5yUT|JVO0f7MP>b}~U6Ibae+_G!*v|+Voo{Wf{_g8lvfXStf zGSjo233w6Tw0}ooq$u@SXBV472YE`tbj0A?pqBc2^0$L)lmKdYd54yGyv`}x3FKZn z2zf*zD1nl|rq3fpOALvZh0r9RCUKqfJ4*EhKu+QN(a#=Il8;Z(e&?e+pAGU_LqXPb zy!xel{zHx7d1L!tQ_&Y$R#q&!e(Si8A2$xF0}dyi@4b)F@bhby0zHAgq2a1K8tnG5 z2?;rC6P0<7VaZENqvwVYzoJYl4o!Y;saqREe3Peecj==V&-{-`0qFY|*cK?GbQ!hxxc(ar{TH1B$VpBMVwZ?Z8iN4+sM$6 z$wQKAn$tKI6H4k+LS)bPehV&ymV-R<}AlzBmp+wWa{zi9M&*JDArp9%^J zS|%pMQOZ_^pM2TSHFjC#Y?SkFXy$sX?!30>{Yo({kkP%o9d4T=>bUkLI*gd8BED5? z{=*@?=m8pmuvCaOTqZ-Hjn2#=bUEPqa{43l=nuW>Roju2E)84!e62j_^*9y1L05lL z776@7d;|%`q>6Mn&8%@Tw|#9=JYA+i5ieq=o5uVP#=VKB@4(3U1%dBqW&ohZGs+LY z)(@N=YFx_CU&{zFnWdl17(7MKIt88n@^LC?A|12+XMw-Vbw!MwJ%o+pc^r7k&#Ge* zub!|KrH^74DnHaH!>&(hYE7N9UeSSw)L@V!XnV{&u#r3C{a`_);J!-eE2+RV%rs?rs zM3k8S2CbP{6FDXZNlyAN2f36X#q zK1vxYP_B*idrH~Kl-;8W$A0^l7sn)3c2`4?ZH^|@3G?u_GUrp%j0Aiobo1Z@XHyUTmPWC6gPnfZ?&OuzHOI?KLb~C-O-$HMvm- z9w`#nVbJP9NP4CoHx{V4EXXkA3iPrTd|u%^?ShXqZB;?YQv$zPlhMHsl^a*Wv-A*- zJM;3NLF&H;7R%!*A(!&t+2c9G^w=mn2MPumA1q0}AD(W{KmIkhNv)X;Lhmc(D&ILZ zFh=2%4R#hktZXui`uTAOfH9gCefM3up--^#^yzdYMdd^!fIT*Bx4bZzwuktPQ!euX zI5|1nT5hz&oAETam&0=oCxEvoci1jRc>g+V_os%%)0DC_*gncI8$6lp<0-PJFrx3V z;kiZ4Q)<@2X7^Rv?SOG-Hn@=}%0wFm!xujPv~a#CTF_$BW1V~MkfRPpr!4Rtx6Zv7 zWDn`RkGAjvksVm3k{QSORJY$oEWHU?35(#u38pMHt3@af`uUhBquw}^R~`MuOqn^` zlET8Z)6bqjq|I;4dgQ%Wb?~RjrYUht?%pCU8VN@t5ko?khVeh(JRh6-fbljmQc+(& z!H~$2R=ADnBQbw~FM0ME#s{K6bNa*P^IiG#=dqX~J-^+~QYH4Xm-h1mrJ0CxV~b>> zP|^}CZ1;lrKkvn4BqD9?pJ8~~v~K*ut|MiO$||>15oGCTu=tiunRjS4b5VZ~a0>{E z^>o%{I6#k=hioJ{dbyRdHYm~70{XErALro~NYv7W87Gt8?Dz6@W5517PRMiTAx=*d zE%w84tQf*hCiS0-W841hWb9JI!%Qp3WJ$U5_=2LGKa`Vl4}xPH$K&gK)6Ax_Rmcv& zSw{&I=R$DKH7>>{N2E#nWC4RuhIi29`D3%BqiFQYfB*#{jY#8jH<#FMn~GxLiSi(F zoy~~vU*r30Q_dmlsPxd_fxo|hb_~Hf&U{1Rr~YUAs+M&?lf8t9=cdtcA@MNqRURbj z=mI~bFe3v2PG4Fh6LsjPA`p;U6XwK9K~BNeJ~>$X9so)%697S=_L`b2b?~8SZ~lb8 z)#>2YHq!W0$$94NQWK1%zyP26Ng9A-(2eXmR4 z5rH*f2G@LlKr0D7*6`T6<5G{CqLR`pa$Ex*CMp7EawnH|;}V0DR~2J=C7m`H;h)!g zDCM-VvAk1tFPx=R7d9giqYVz+Y;E1A9wS-FEdCC~0c~jl!;lpKCh6CGF&gJYBqSmC z*g8PS%)H3Cz29`<>Ar|x{#zqFH%Ke%=~#+z%uVn2YP#GNJb%;sBU?kW`|FI2K6=?Z z?E69ap@o)q5ATaAd9OQ{V;X!&OlQHo>~GZ6)$~9*+wi6F4lcPe6*)N)9{KM{!hL!2 z@3Qj$Ksj%Jd^U%E(AxBeJy+BvP2?l*!87`kMp0+5jfW}Up^N887PK9`^=)jwK4E!# zV5Sui)2an}anNpek}ywwF!p70JF+{1#%lNRS(Xw30l`48S`zsfshs*N9a;hVwU(61 zXaB1OcxeU2O%6O47GGt>#jk1GO-UTpUUwwC;`rBrD?W5-^`|rT5s~u!EgU)S_F|=e!EU{W&yb*}`wG}nqhBA#1QqPe20WR!PRmA2%7jrO@85sqjPf8r$ zBRlG}#M>k#tW#pRa*N%@6POJQ%?+k*zS~ohZ3}GlI~Ic2uJvOy%WGR6wR80Ab0ag` z_O1IShrhKRJ&I^(kVsU&3AF@t)nA{PLn>6>FE1+0@zY&;t#s_F4~Phi<3XK}&WnI5 z^5f0ZXmZa9|H+?3_+%uCik?i2Ve4-eBd9pJ3l#Fgv=YC4b3#p@C|4uus^-W~mS_tT z152jvWJtsW{?k_zaQjNgP>Z0_UrCu96dy%@k9jS)-ahbUyn(DY+PtIiD$e+AZ_=H= zmhax_2^HcDQA*IVmw)836tTrXXm3hpsSKut8-J9h>1_KWpS;FgM3b>`N}?HTbM%Ea zN`Nj(2k{KiuAD8{<))fZHne`Q2WXRgU^TtDoYq1a4v{;3^_AL`!g?ℜ_lm1f)YP zEv|omx&zID2UWdue9W7t{+t)yw&(+cy7P_^4E-Vi`h;_sBN;Hg(QaaR*f@( zfG3#tzUf#cxudKTxw*MIU+*u$wm`&7T{Q9#1A(M+X!(7|a$hmv`2yeJ_8OJ-Cs?LQ zN*<75Xtdi@2Qp(D^rR_zZ`3M8G6;`u-DJhaG)77^Uo)uuS{eGH@@r#NYiT&~m_$`1 z^Q)kZnb0hFt~Bm7M*K!|?lTmVCc-7Z=WeK(0apK*ZGaItwf7_4|Qv zgcTMRHseBY_0`VHs!`!bVGMHwelRG6s?Xxv+-$q>Z(NZwZyd~|Myb)$8)5>av8Gl- zH$Mw^3E}W4X=ytka|izDp7|YbiKuT);4m{^!4G?hr&f&{BH5y>aX^*MxHvfLhhg*% zKXW89(L2LLD*|nTrXqjs_}&OX>Ndns(q-wlL?J^(}d*mexC? zab7w#ovDp~soJ0ZyA+=2zQFzQ9)5BZhLUy$CzH~N6uzZ}Z9ZOxD4kPoKJDX*=NvU7 zI#DPxGgn5X-RZ1|V|QJT*IOw=XPEvnqgNH=KN*g;N-m087a`g>*5^!B`sU905RNq{ zj58@TKrrAnzvMnVtITv;AI&c;R9GJ^p`T2Uv^1O+ix!lEQ+}INQG?a`wLII3(eG8+AK#T zHGT@tj9pvWL~_mhEcxl? z3r{Yv+8oAMcgp37Qq>X7dg0>*EQw(l#>Ut@i*hf$jkwEzcvzh%eCP13>m;Zyf65UL zU#{`)bBWghc$ghZLf;c|e#368bfy$s85}#H{e#2{7^}2{nTt0#Cj32&K3w+vc1e%p z&rM4LBr9g6{9@GjVcj5ENtYPU1+=>ck0;pEeQk-2JtO!DdN>cw99_3mEl;a zMJI-2qdN&8s(-J}{;TDDz3ERvHL;9@snN$Pp@gM@1_ZFU+}c-eZ%zNySZ#n zFALBYMOHGT98-o(X?kx+kv@4icKIZ&QLzYvv@w#u^_<}uePDNw+^tXAr9U#4ziSdg zFw&u1@LpQQ2Xr}V^Db4(4CV71OV*HHE7Wh{*m{SX9*-X>xjyGbec4blguUt1W1#SQ zvvrB#^3xlX!b5*u;m0OjhXk44##+KQ!y@y}A8{A>;WZo=I7B%4bxw@T6jy8t%jD&B z$$w6F3>F{E2?Eh7g1^H?fs zI)vKjWpxbgLCkxzuJ=z@$*1eyx-H;V@~(Y{1_^(v zY=Dda^s{b%BwkopfW-=-r0pF*N>|*S4jp@hk3xp%{Xo=BG&qCRA4mLB#(FktCM1k;u9D^yfC?(TA(C^=ZEEB9KA zj@wo8d3aQw+@nvC@WXL2%wZK4PS^`6o|qFy&pssGCa4qLnQ~|qengyqpG>ZkDT`0b zL6EPp@-58AqJZ@I`{jk?qw~*0_+eo<wwJQaC;^ib3DsLSOx8Ha`J_ z#_5{d2X3v34&2mSEb9J;9Vele9=^D*Pr3kU@^z05ZXc{L`&m-4Xe~p-Bh>z&YYiz+#4F(89t~h&H+V0g9wtizS-f-L(Bd!L?>Kh{_0mL;$}_CE5|b(S#LhYHZEWAuQnyw-osE%==r#8wnj^*UBGUY~qjtvo zR--L$gIKF?u4^Fwb%nCW=N~Ap%#tDbwV5Q!JB|GM+usK|g!^&y^h{MAYLjEvkV{Q^ z&{Dckdbn!st5nM>e1WsFvMy!yYId|t9Kgfs4a&x%ciDf>F`NtHXcZ9e6P+{~7x*iz zKy$-teQoVMoMmotb8*T0`AI`(2y6)vkjVQL@+6MavWxE^aNUW?dRU{Sg60MiGTc6x zMV(I76;vJ|WPU54Zlxt0b^mEH7g+D-7xX=Lgkws*e%1L1Q!&N7#v{?3m|fMbR93$S zIYgui?Zqi8l3W00b? z)}_M85PhN>A{J0c4zyKRBX-^#-({U@|IREP$MdZDfQs~n-kHWM%+48#E*`4)B!8Ks zUwkh3TrOj7k_?eQQYIFb&W?^aI0%OeDDWnGWScbF?W1z0S|`m7imCrJ0!C2a(oqpN zL`~H>u~q}ft9KRJeRGEoH1Wk1wTE{A!_r+{U0p=Le1bxe1*l{E;}D-=p}mYF?_1gH z=6&b#2cpuVG5`E*0Nqpf6JqN>4%LV%#DHr!z9+@u6Zrw!i=NOag>zo*D$lsqJ7Lk$ ztBNQ_60JgF1E3bM! zxd(59fM@;b4Yk4ndz8<;f<-6#1jK_-14xccAOD}x&G}ckeT}yNj&XJf5&s?Xw7)V$ zz?=7X$3HsGMi=3lG& z1e2E)3C>0sm0Mt7^eR2`oE8Ubd>@!Zhh3}@88vH^zsZpUmhwypvN|R=cRpQjttTivI&~55|X>^Eq^_-wY5e6ghQ)ALPCPI zk^ND#L+iz1Go;C5G!>_h24EDMaEsmS!;F;iVx*vF2 z>k~rgpp)o-b7I{c2x7M|F3E4Ll&b1>+LvweHL>bVR@=%cr^f|y`x<^aJ{Hhf?EP2!@Ws;p^rETPUVpHCAs)LH{P zdK#lE&qQ9{vpr;h{+kAZNud014hb~=F%V$DJNS!Akf%wzzPY-3|XPDd9Gb5=h{DboR@{Q%Dj z8$W+^IZ>q+We5ykSOf*N<+UlFi%(2UF{H=G-Sj!%A_(o|KmRd(cU0tbt3gAgYd=eM z!?|PNlAH*_HK$+A<5e%NE{xmn!TqC}{X~Z^a`HRyOrx-ydeKy>M(A@DIJ~KX$zRSk zePobu#Ro^v!SPh5#_*HrqH0A0n^?Bmv@WakJLOB>s6Mav+wIDxX3O)NJI zZRVq5^VYP(p2uj5LAroRaMEPe0$*Q{#2j z+)F8bnI6>vdOmJo0Y6SaAj02sQc@~0Lnk7b{M+B@CIh|vzjVD3eeRn0lNAHIi=Suc z_c(%)rm6kExb3#m?nf!_Kee|0qlfqhAQi~;y#);%@~%=e=`BHv#%v(q8TjkBH2nnez8}92Imb z(*y!gzI%Ip{Ml+B`25A^Kx%h2=Qi<`D?S&Kq+pY#Px$bm7BUw7hXL1-_3Uda`#4-@ zaMV?b##aw<4L!$!+*i!19EsE^cv45lTk7Wu90t$5D~)!EDA8;1 zEcftOng90H0F42yjIS8Hn)zK_inaWQw58w7zmd~- zrP#Lz5|1=zDM~tncJ?!tm9J?XSMI{1qvs#9pv4J72CA3zvzm_ZeQnhNcTKM zyJ(~(du;vrFCh(R{app#C%EUJI=@t*!ml@qF<+km?$cf^tKr)GGKfmFwJAeh{K~b2 z#YYdSpv$WTsVY%^{(9$HKcr4Xt8#*_ccpIoIXi#8e6C534dO%u1!Ij{{iPE=ek4!` zGk;exX68czy{443E1Jh!joZqA`DNq3c@tM6^({6oZX7J+n2u}@PZd#MM#F?N<_kKQ zd|>eWB8u)>qEuQa$V>Yy^78f|JgEkJAFNR4C*P0e0=9Q2Q}0^BV~Rytev%_wNSz1I z>K(=ei@$Y-V(BzAed&FIAkSoivGUt70Q6-v-X<5Im&17o!E4vVwx65(4%(@sxYXv{ z8qLQ|Uf<&5y9x5HFWH)H#=B?nKL}-ztCjZs$&z!eaEdpO3aM_R`jIC zpk1d&2L;ZD)ya{P?Z1*VJn2fh3kbf_0MS>^BjP_X2nKNAyw$guNDN53dUE!-q*9eu zO&Orw`X_X_7AtPsvllm=_i^BT?EHA=`90v}PS!eX8y%kf%u$1H=6E{*z5eS)q~|ag z5IY4fdx~#CsXPxmV+JQ-d>ksg??WB$d>yQeb|gpR_-Dk|a1lWH233pxg9oIX;fuvu z6D8>6F~N%0Sje(pM6o6PEq1e?A)oa!lrE}f!iKNI#u8CTTGI2-vFmBYI^dAfPQ+sZ zD!~dk74o>m|NZ$)52}f2{r4?-KBvc;dnQM71ylt<@7rRqy}5N*nHESLYabf0WYO@3 z$oKPkGTlqa)^q$-(LWt;00*mPjhj~si;A28QE(ai+W(A}7*~LJ$td9`(0!lWb|Mrk zKgujvy?o5R0pTB>EXD+a#t}DLXT+1cqqBsQeg*! zWC#ObIz(G{;_=jXk5^V!_KI|&G_kBn+Po?I_VTpTJ=N*>J+eP6dO>%L#l0RN&-0g z|B{cvGe@of(tP0YTUHpsADX`L?@)eD0X*I3#Z`gI7p*g)PM{GT6s_2`m-pmOsz1b2V z_z5vFOx@`WCdC2ByXjzJ*iJhJqdAlFw3Y(T-U*xN?xgddZg+ zn5)8MzT9uzr?atMi?41nOG^6OMqF;@pX4zF{4NfDi$K|GT?wBnbvSO7-TX1vll4e~ zQ)_(V$;IILJ+gLPV_(1VNJxEuyi$6!)m6u0k$`j}Dq#xM%Al6xWy;60=|iT5*u@^Y zg=DlpVghlm;NJ4~$8%|K1XRIv-506*7O!u~yE9}v*Z&gD*$A0r> z+V{S`bwANri_x{C4`=Dsr_FBYN}#b;F73CX4)`x4;}90OOwT}e1DM>U`xpX%=anxT z>wGDaot1@2@djHVb7%o0zpU)FS=sCVWG;0N7wAfJCll@Aipl* zy7MB^YiZ;PqM6AdHY%zHcqsi$F?@9*uM-`w`s zIJY9|E4N>SdhZe_jbM5f?KC?kU@aV?3;U%%%+j7uz7zpQcgN!ju|4O`Gt>xr5 zefn1Y`oBkqK5$~-&QW~xm+{snB&5ed66s^;X=~IR!C(mk0j@5_K@M^8cs7pcjz2%T zIr;e9lTFR^g$a?ks!x9{QLCYzRepqG>@YDvgcIAr47MOh1U~$_m-pgZX?f*xz;yVa z{xd||Ucy;3BkQ^%McOpI!IoPHqcn_%H7MqEwQ;htK4xN~C~K&1)9? zN6-$9?|V%8K9#^&>%IUlZ`6~fNm6-z8mG(}tcH8s$Tm*=^*(YPbDWH*POJGsp`D#} zta+)K!R`?ih(Kr;w)~b*b>X%+uy-ziPFEpX*ii7e$y}2byxwy2ahL&O4o(@1-7rIs zE-~PN0-iw}fq=A$z@#KPa)o&f&lixa5)Ns8`S8U+R-XE7eh;Q=`ZA-H36KwtX1KV99`Vb?ho4;@_X+6??{_s1l7JeUh9w%17Cq*s$JlSmv#PZyz=%s9V zPxg!;$&&U8!goI&hlqwx@!xn29|~i;&ESL{ibsrT%_EmW>@O!M_uTcsFP>7(@vp1M?@n;sD*({sZ69M$h*0(FNlT2oIMP@c^s27C#V{6O30_sYHC8 zOIY69ApEG}Fb%m7zVS{A;f7{jA&we*dfc5--*ma_yU|Z?tNc|{zz;MlQ+e^CU{DaP zoEBZXPUq)9a1sE9Ih6M^hykhf@F>Op!!MKey*gJ<1boVVs*B}d^0{>V;RwCi{V^?KrEs2mfF2Uso3 zwkW@HSAFwyV$WcX%<4YGARnlhS8z<#ygT1K`c$8TwC`zfYn>K}vOtBM3~w@CZDJ6` zv>fF6EXI}oR;*PaGsClQ?#^@wZa!GMS}ZXCPqN!Dit#_q93I4_aQCvAV}|j+irxR; z>RD=$%YKM}4Q@xAe%REK#*C3a`h&;WGBB}Q)^o|966iCie| zYg|kJGnXdF6d@!e9D+oLvt4R!cQdxVxd8Nac%*czZAJ)TdSR=5BahRVFE%t=e;ljO z+w_fsp~;HY`~TGfc<67H5QkbW!^!vz{MhAIy`*rKzV-04A|kK;Nal+!mAP27bfXLN z`+G3B%!&;rr<&8<)`eD6FqA9Nbc0alNx7@P&oF&6WqAB3t#v`~WAv|#?wqPyhF&D$ zauJ0QmHIfTXmr|kNbncU8z68lKY zL-u*-qQP0_5=9Il2}|AF*u^6b)y5#?gyFO!T#t>Z+QAa3X0vF3R6-643?XS*V)J9w zLoF@f)8H2rvI4YPMn?Fl4?GP2=#mUxi;^Y$as2%U4ArendZ>p-MwnSxI`Rnqz(3f! z%9!WS$lbIB^;z-H5z_&P|@L%G5U%N3Rc+Z>r=UJ&)N}@k*PqDTj}>?Yg}8j zy8lh(^Gs6Gw#5;2%VdDu_S>Xo=2hYGir6{QK)B z(tfR1m(kNMgTg+M%GvE;+|j7x#JKgacG$R;YA=Ns{oWY;fK45P2_BiH4nc;mNsr&8 zRv)JF20SlZI{hx@#U17%ZV8J+jiE9z*Ds+<0xg{mk9V^~!X0S9>q zk(MEQXz>6tt#`DLaPc?KKaA87jYn~mpc%)iFp7i|vBbScY!rdHFQE8`s|DBW_D9Eq zHT`_O!kZuTa$nFvNFkV*JIgIQ0dCI}dyiqy2nWtz@_D}&pnnX?1~aN>Iz=PSfpQse zT)PZJ_wqU+0#al_ylRg5iNd5!wReLY({ayzvmY=Q_5Yxn^UK0K^QW!aag^w+R*6wX z76S>-z$K>cf6{A`iW|4yoXaMQk}aJb;UN@Tk6E5zXb+8;$(I}k1(7FDKKclqEhXr( zT_z-b%zcp}=7b3+#>+MtD2IF9i@l#aWpB$rBbs~|WpuokeBCf$hrbEk&S9-NweuCP zXir&2IR5#VPt5tmX38ig!oC!}`S)xySk`c@k!HRayJ`rljp7y#(iheB!JgpcV~LAc zyxS|=bmu!3lIYn?CPxB{a`fiu)*43Lm}POnJ2FwK!f!Ytu0%Kz9xUYlsP2we^K{*0 zRhKmjxz7`fywaX{ln~B{7R6z8y+LX*1C7jd6-d0HB*gio!v%v2c(^;)MCqacxZe%u zANgNG)=A1PdoM-kAEZizz+%7x<3>2WVFn@$il_i74}JaPgE4csRgkH0y&jQP4i518 z2YI@tO`ccagMcyt)Tfybs1Av*-BzTfr9G|}Rc!;OSsILC=jy&hNP6yAOhdX-3n?*i zN{>G9XPiMy2 z)`3h^-ldf30$OC3c@MTYnDSwI+}-eXGjs|7yZP#HbINC7JEQ#Xxtp&~DfYx%00yW9 z7irR;ohsGl{-SPqLo)kq$w}qQoW8hQ9_6tV(fk8`hbb_Yh2)KG){HuYNCg;OXe{h= zw0ugNka%6k8sJEFMdy=MGpT6?-c`cP%b5*VP9);vAWwr2M*|Za9~I221h8wzEn8O z$uIzZPdEF=mwNXKsOsM(82TFennujqzq%rN$ZsvnNkDfsO4`fEX=A*COF4VD%;alp zO$~K#^bJEe!(4WHyFWkeGtOpCYk_0*A!4579u1jLnUL@Soh`GkXZbq} zGRG%uBECD5PMK|pNrTr%qrS=kE*XfND)LKM(%|PK0&8;u6e*vXlkKgIvHdr)ONXfU z9z0Zm&ua#l2g-7rFw>d{MPnaXJ#BlWi8C_nZdit(fz|gbOizlw4GuauC-1lXp7%Y6 z*gbtWH#g^1ztX9syI~cC;)apqUJy7%67rc4NgW!L%OZD;J)b|@@tpA0Rl~^q!paQI zI>l}!jF@|Db&d;|kXsf3v~fsrV!m~Y*t?k#o=}Le2{O86@6L-e3hq6OU~(9jg4~(` zF5P9)6re6)Pl2_Ki8_M5U&>Lmxcmk;H@6;~dF}#KUBG@?Og%+RTM))K-LMWqZ)E3} zrfgfe!EP|zV!x*&#=*UZcTE;e{w0+oq&dE;tg56TKjIsCrEEFe-FmeKs*jCo zZo05^vznLJpqU>C*v}NVej;l^%uGE->RDZ?8UK9lTUi{O#$lSWhL*F>)Bp2dcR1Ch z#K6#t@4YPG=p`XmEeHb(ruj_Z<=$?C#`FT5hoM=UC}7!fuXOKcKx;TzfONz`pLyxl zj@)XCcPj4Rxy|m~tF23IWIh?q+MxtjdpLr6O(Twvk8hR)JP=1frJ@HZaw+RaKG#rH z!|>9z1#F>jmT2WAHq@LECr81;UFVlu#I~nGG9!&0~p%DdRCu|`2cfbg`5Z>=KSbcS% zHeiJsv_>Q{*$FJ^)>>LG`@g8j<0NgifaD-R@+Sv+HS{i$kpV#LbMCY6ZbT$SUJ|6Gt z+VM7JzuhtwJ*?T)WCG$F(s|vNru|JFEX>OTWoOj7}4*J5NQDlV?UR6V8Um#)_azMYUDK z&dx6Ewf$C~K12A9n1Q9zizq5>S)w1JOHzF15+QQ|f}PxyZQl{fcLGBN!iZV>DQfor z$%=WZ!71?c)cb6nlad=7 zGjOsyp6&a^L@PPGNCpjc3=9l@2NPUnSVk{J%l?D`4CH~O|KU9`A4}eG9T+qc^TW)QmZtKy z;;ngBRPj6B)mQvCvny|FPvu{~4B|R&jM^Lu*qGP`1Wh&PyrzZ9=XCatgmVWdT5W4u zBi7SxJnN-v3Rb&+xwId6-B(rB@z|a56<2^JH0;~W(KZPnDjYNy5|!eJ;7 z%A9`IIs2IP_U))~4_=DZ?##N}>Uo>%ue^COYANoqWJy!pk!+oVP&%9HODvbXy!@Z( z`a58Zuxe}!k}KUCKe>P%9rqP1Nv<2?SKxM7Pu1|kVxql-PW)H8xGPk zlSX%qreN%Ci4QG&way%5-kZq!vhgc|u| zt*Gpa?qD-A_Tky?k+|;8PaYx*p>@aI4*gHL&n%`sF~@kkTymKkhY^}=>70CBD3-}p z32_TdQgi{M-lP=5+2T6t#iAPRS~4Eh+9wLV&|x)fZM4%swfKm- zl2I}xV%`d#kL-!;U)4B1b>#AI){4@>(t2985cGDw;f>t$8cwhux!a_{8Mxg-4j#21 z@Ydog@iV-_C2=MfQJd7bBBJ&OYGbIzU}gzWS&*n+u2N6~U%7e}D=8QH>rkIDwC)Cf z`EpMQHX+BgVJ-+RCW4J#YZKZXb8xO@Cdc3T!Wx|cjc{DYTTdW0@*^b`V|d}>+|F6r zpwrrGH?jS@+#42Aq7+n#IQr@{yp%nuVfjTC&+-%zDOXl zcu9#?-Y2r__X<-Cw5FQ9OGP`($fBK*lJ%#3L$F=gOUv(sLiuQ@LUmsQJmWW@tRE^e zpD#cqIC7TLKABt%&O5-G&`3(X`ztwOUT^!_VXH&wJwz;edo=wgCJ%+?U zuAo=w#P_TAk19tq*|dJ-+1X0bF}L5fd|Va(Glm?q;A{8;c?E0y_WP++N(Tm24p##c zUn>i7MO2?o6!^oEt^iVbFaT=l>b`=G9(YTwptT^7-2XNS0XMTq9i|n~QmLyGgFzE8 zZ!(&i7^tYIp!2L^V!{9=`du?!Hyo3M&-wYBN)X4$XVw%3at2^`ure_r;8H2V*Y^i2 zUqrhgHsmPRs#L#8xjt1xVX7n4~lQD@o#THzYnJxq>2}@mA0+$D%A)T2UBb)Yr_m{;g>)1h4V3q zH)hfEvhhY<<}mksM4a=?v*3YLiTQ%OILuj3Kjy-#N7g(Du=a=)x?PgHWyP5*-<>RZ%zZ;DH?JsfcUxHkMgbkBB+QVDR%^7k#qrO zL=B;NdZ|#h0J25i(XqS`a)fE2^@loYMZ=LHaKHXxiMLzSZ;y~4Mo|WqPK6osZ}Cb0 z2A?*>ZElyIQ{G8a?HUUpa-4c_3zBi8K?nm2{Qv9gD}bs9`+oP(-5t{1(%m2+2uQbp zfFRu=970MO6(poY1*DOVqad9k-ICJX@jbln{bugWow*D%azI3O_u2hFzl<*ffZvEi z2LO2@aMkTg>uvzHdNA4OE$Qe~>{fa#aeI1AbJSN}Mj$KTff1SE2upT7uDD-&Lm{`L zI(QP`Rmds-ze~HO+;MWr zD&KB}bbGSe8Ky~-|1P_(A-Y&-+ZFY{MIpzBHKD;phx&4gJUel8*b_3p7012`WT>KY zYfhjqAH)(+W(Xr-pRQFf^7@qD-tK|_{_`9%0qAA~At*n9%o3a~ZZb)X%gzkQ7+h=Xi1=Hld>c>X}+heC? za2wWU$tUpCZ*I^S)Lf?dc(kSw9BSZyPgGzgsvM=$hqOVbBIpdi54t~8|2$x)JF%s{ zVpnazP}1@V>jmi>c&-lyhGW!RV4qyPfLOwc z0u9JEj9P=lEkbU*EimhU0lA#(Z*0U1s>M>ooK#7!_|Jo1m#*p`O9}@Yccqg-zJPcj zQqbH&mf;WY13K5$n<=@`8j0XPM#YWu^!VR1^uqdnZP+y=EJm~AfP5mt9aAoaWmUgz zIxs1K%_G>Kd3P+MBEcTBrWSaWd#2xa`}iG?sOA|ok@KYX5YW-#gMRGlsqORZqd)TN zAUq;Nfuh4 zUz@&VC9p+;rijX%!XMr7gENE7dUTDBq}pE7!N5Y%JY*AeJKEx)Aw%@Myn`i&eS=_O z(zEz&#Xu%56y7FXM zdvCIJn=(Q4X6D1>)DSOk;4Q=7=w!9jG2C&k$gBM;KtX^Fo%q9R%1HP6ePetm^SG-F zgMykGJ2oGb^1jbpDK)M}0~&w?8)qQeU4?@kIcN?=ut?ro=#PWWMgqWzgFQUiF|7gN zS7c4>XHUAU^=MX;Sv1~jq+Ycz3uNJ{JK12V#pL*O0t z52_+saMe(DbmYVp^&Gwc`a&Md)>-%dt@1XlgB{<%RsT|`BD<+5{MCm;55B%5<+Zus z78iOn0wns}C4VbO?J|FxE9 z?z+GodNxCD->>fmn0gHOUY%5RglwMw7y>0{BAkt{UcNPOl6UxuA*#;H5ALHSyJNnS z^bmOqq2KYBCyx$ZGn&=gc8qPI(9Y;a$0z4Iy`({tI-E5hxtQZ1+BQM<4eJKInt8E_ z3$IVMPP9uxMHgn{!KGK6Ur+#~_c|sf#eTp&vxxutUbmuDGR6st3vgqU{=Si-f;weI z;9v?RM0#-^oY_)>XzM#YtjD(!;Zt^T!Rk!V1Uf=4+6OQT!g^^igZRVjtG=+qFIcx* zTMXVb-2R(2U*HDkBQTL8RW;Y)pHP(U6&4+=wtI&WPj@-7G?qN=~+Lr=d1znL|= z3RLe!t#|;Nr*;dBS@6H2cPlSNZlujJMu|TW@AqcXAE}~j!%p&-;i>d z*YM~EO;2A=Qw5bykDr+oVeRTUx)qs_*2Nm2&T?|CY6X+q*N=hv&NQ~fdLgKTWEu#|8CA!PPjQ)j&T5N${ zU$eJ(PoU<1yM_KZDZpi5PiV5RTv8P->Ss`4bih-Odn-IZF_76@ro|Y7eJToGhDlmrRdN){jNs0cB%PeBAwN-4S zwsf}0*Oef)cR6stOf=4#DcspqqfgN1hK*&FUPk8Yfo%BsIlVllAH>fRXcq!4`!HZ5 zj`QwPEiHe1K-LHk4-dpi*qHoe&YTa@gO(Um5j|=Vxh@tMSXie#VxCq_!pa97OG7af z@BDU9<({IOwc@?ihgRPqLh6t_$za%N$n8uJVNpj+dk*$^J|Tcdn1%-NLd*H~`vr;4 zFK_`hU$6?scs-DmAXtPfx$- zne&n9<-kcTL)B)1ozetA+N_lP;?Kqlar9YlVr091~;=j`J%+lm)9Ttja+rfQ~; z6fgTjoP#R%5wi4u?VqBZC!atyp9)n>_OEGHt?gD!FKM0Hbli5m`v3GCs{9s3|4@yx zO6t8qxDwybQ=B{8$|TL*!^PVe{bCun+;FNg5RA$^gTHga+Q6&Z%ts&Pszt{FX z~rzdwAqQP0o8X81o z=1~KC7KldH)BTW8YGnF3q4!}6=L88n3M-s@^5r9kF%)%VdfloY8}{~b%-)_~pr4$c zc_K3)Lfa>FN<_9BsYZtIcV-$EFXK5I_dPy5VkFE9%q73R37390nLoxITjs!T4QU(V zZ%?Ct#UnoV%_X3Kqz=S}xuV0AUQU_>If(7^6-MfZP&chiHQN;&P?euhpEWTF;+*F` zlQcZunK5*^{9wdwaI$M2`x+Z}^IsI5MaMg?JhJC6gs3v#w+WP)HCP{|gIyYUk9TCg z0+uO)r>M{VeAOxa?aTA*23hV*(pP`_G9X%sk)V=7NVDMMXZfv@;jI^5t^QB-r`lxq zoPfC;6&eGA6EGOApC`Q6MxuFsvCh0oFTq6hR0O6b9yuYdCLZ4#>SdaTXvQb#6o7rR zhPa=@_6P7PY~2qkJHBz?29c6DO*mhg*BV3=<|@b>etQ*lL5l^ojM!}>IY*!RqCsYS zMG+>Y$Pfy8K;A1!@+@9lmD$zk0;~z;> zOFT@)GT|8}ohPE~`1ovZ-#INV@5FXQSPcJrAtw2TfhfNK8}tWB^GJ-eG#C` zP@pqz%?}P|%pn9U4Shq|NBTS#LC8R^PyOEQ1Z5t^wRcV7>X5RGqK6EDtNb!J`HTL-Q)PPp%tD?mN zeurT>6cm(hAS%OwI6V)+;XnpD_02kOi8-dbZK_mRYGrsSk@lZ?!`+~@xL8&cXCQz4*?40CaSd?(^V2lFP0x<1m~n)%uVkzi#X__Z=KKi#dyaREe^L*lbzK zZKbs3LQ)vm<*%P&0sD+kY$UHxjiuVs>cgDiyjCNAU-t2vJ;VBLW(@oz)K6L{AO2Sh zpsb_vo>?CJy@<$DN$lL-6a*so!DQu`klkb0BLRM|hXj+TlS$5A!)9{j=sw%RGz%sb zYaEWHLI`jlEmBb6wb?O&hL>B;1{YU)O!S?dc|f%gNbHFN^4j}eAs`2;{($xfBY9M) zlqlvU+c|$Mx*@*?bboIJ$dAd%1*mq(qxf6*9mQ&k!p84pFR{sl=eStPp-{_>iO9i$ ziqwRsxKj$214H%;K;^)p5{f=+Y^%hv$rqilOC)mJo)jo?erc6(P1#2WCm@*YUEyPg z62+({?xy&VHx#cDXsTar8KQ^u`0feY!ey=Vkt(mgSZ|+??7OwTlcEvQ+}8-k1c?LX zoh;4!_|VCF6cwB+$?rC!)GN#7I7RRhS^iJA%JKZ4kbfmSZIpfngz9rPE+zag^P5(BM0`BFPc42MTrS{oimpL;=}j6jXx08qlkfJ>3q{fG4Tbb@AjB*o{Ksa90VA)RxK=K zz+(=CEtxe>l7*w4r~u;u02x<076c99A&aW%%3#cO{9CvWGI~B)t|N8EHm-hk+I7P*^~{1tja2PQc|1N^ z#K|4{U(AY66mIIsE7aUw!njH0U|rC@3Ld}g(OI{DvY4M*6aSER>GdAgAkBG@#%Zfu zo0hy{{3((c5!LjbgV|4PY}lWQx!qpjnh$6~!q--e`(b-`FR~Iq!F)qKe8QILyG$2Lp%-F7?`Zg2tmq z-QnS}rVqDnKQqe$5t$><{j5BTMkm*RI3lc;8^(hgZ zs3;MfQ&4b};qY{Kj#_QBrhNtT%(A2>6V1v7J12)2qQp^l65_Y5CP*i#B5`Gw)y^GED~ic}`XH^2%nwm3D*iR6nSeT!d|J z+uoV*RGnozxy$NrZg%k~`7s0sHlmcbZ*3?1PB-?Y|46vj*Voev3Z^o%vdVCusa_eE zvxQV&7LX3X&f8&!NOocnW5~fX;DzXd*I3ca!sin z_HOoZj!nW@=hAyBjM#i@Wkwy>s1Y6rT z(;>WIW$%9Gsh6T4|Ij3wn5FiCheGuCsDz`4C3b%^9wXKJvU(9V!bmd^VZOMve0B2XiH!e@i@)bu>tlz2?QL;S%Ny%=#{MVV9efg|&ZQ*#S6^$MPi z>90MHK@^OKXAe^?gveg+hdTm);Gz3+=js%b9yeLnBjywxqL`Hzl}6hvL@~2q08(~s zKIp^-$g>3U$MLO`11Q)<8>t5O$np(e`0iw7ct!S}wT+GV+$eYsGM@%n!k3q-UQ*`j zNj&}-a2wRrI;4lPQbWs6eMkpz-uwIuQ4{zw$FPZ<)TKwEc$-vVCOq``d~!dOrP*BN4o(u)E=on*T)AFb zs*2X^5yX`!n|SS*wu3U+5(77<-8!6~?avHJv3{Ye z7gh~E@ZY%spLW?JbbRUeq-lkN1gj{=va3P17*8Ad>a|IVa-Bk*u#0T^hYv*nYw7~K ze?2fWIf+DqbTnJgPyqnNI*C@I7~42KPFx_Z^8BP*v;`c$_m2}GyRC0(0$HI1E-o%9 z015PeAQNwNUAj+fKB#7Xc62)fiUE`5hL^mPWJuna- z7aLn8!C}^Ns$=`ejR0?Va7VX)g4Aw#iLAb7+;>9@VJ6QA6C zRO>$GiNT|IB><+p8|*#WV%Kv zG5!E`Y*;|R2-?}LKnVrF9w`1R&AV=}D9^Fdyyv^A*2PVa=&65#y|{<0tSl)*M={K6 zYn*2=@Hv0gMQ{$oCQy`_W{UzcX~nGP8u%NF!R!J~VfT&>idL4C5?Pxpwexhn(ABrk zD)HL`U))uSK6UzTKPqEmHu^Y&|BWAKEtGUaj1{jcI&}C9!+BHY%0;^Q{bL2!fh(H)Z?fi@1}ds~DUXVuejT4Id<K~g9Fc30)pbUoo&{`At>7(ouI;t4c_1eS3@WzB(&p<*4TDO0V4}d?4(}?3q zVA*0+cSVH-XVKfmRZ7L&3F2AKvA@&t9*BPuX3d*!)yG&$zp=6;4e{{#whm3O2IuGZ zq;Bfk#M_jSEwFXxTykViM4qIuK=eoZ!RvP)Z!(V#`vSZ^zW?i!cOED1FXC$p7PZ6H z(#7DheU7J$XDJTm5Oc%L)s1cIy4^^sebHRx-%|UJ$$&WoAp)zwbD>abAez8na{+ob zE2*B^+pjMHa<~PY9zY8wgA!nJ%b*ed4-*qMbB*5JLqlEv2bEDQH9#K~qP5Xn0|o80 z0kQxb3?KVVqpZVO#v5ca71X-0NHqu=&g4LP@YK-F&CQQAgoe60;6AL=7~R&6m4m8- zB~=n=5{6~6sb;W)TL6cI_w49%&Lhz5{x?7Y$qblJFV}MhdV457Jcc0(Pf8vw{GRi3 z+4I>5j8KqvC4>;qFBt31xe?UAbiG1?2XBJEHQZ&HNVa{gWXj04-2Is24t|W%G2P(R z?Naq8tL@#oHQXf7UQMf6bIJ%F{$+b?&)G2~kSGr#W4M@Pi()bttPTtbo<4z0t9W^M zoD~Lxx-)nv3KjFT2~1CNON~WvD9+kg{38fF)@QdiCKoSV|D>OwQ1NIl3>%a)(KEJh zSq`lT8Y9^)?ONm&>%0Nm+L*(@@9gF5UCGOJZp$K}HJUsUsD_H>f#`Er;{{HSXj?5) z69J~GDuXc9`lQXC|G7EqPhLkmwz33*#gRtIVkd|M>z7!e?nMEivE&bjxtZV1<=X6> ztb=|H?R1RzW~F6O_DUqoyB41hAs^Vw5n?vYT{)0w@wG^C68_B1Y3rGmK?%I_mLv8j z$jyBOrrBE81w3-{v~Hm0CnY~bUo^9@xD5h9tleW{qyP@N?{HpPSwVTN5DM0T^v5E93Tu7$uu@*u9r1o_Ea28>q2IPZ@)I@|8luWTRYk2n~`mj^wTl{yQe zNw_`a@>#!*_Jw^jY9-5S30!ViU)C;Z#im5}|6C!822Vv_)CmLa9W;dB2a^KV!usGw zv7g+{VMArz4v&nin@;x}C@iUokL_PxWQN7yR*>Ly+q3<|J(@N;#;7-BU5->2Z)fxaNCXMe_;DMW4>? z@}!@M!0F<mOn~?9%w@e-qQV#;I z^>q1D$-Wqrr~wzR`w0~R6(JILAa?ny22{Z?tpZDPhWUD)Usu#*)@sw_Vn=mR*z4M6U6BcDSY4@IOVx1Q(U z0t4SyppdZcqqgSS8K%nfG{^J19iTe*C0P34$06hmkCH?s9J4wJmwSr+#{tvv4~j4q zQU=7xB``5GR4Shn{A+*98$ZzJ-QRg>+@DeU`Q^UCi+bpqJn_G&QG|s_yd<#ZWk}?t z_l;_YZ*MMfkFhWi3@yorhyB&{X(>{2dD_PYobT4fW``KURpK5@4$4AZi6Widc`es> zZr%e(o`>I@U(W@0fJVrh8_DI_n7;TOrjHbfcN}S+GIeBf%MF4GvzgDh8Sz{J9WDv^y>Z8wn55nFWu zi9O7?eP)SNv4-jvaWX`He|0RRe9q5r#(QKMpMl&pVz+|m9MTvyC_qe6{*kp%n53Of$iMg4XwMXXyy&ia@p zx?H^bYNa5af@A`n?$|h?dU)nUXWZK~Q+oHO!O8FzkQ({;sDLtLN4IG^6 z%8`HYlr0l8KF;nZGaIWI0I$~|X+<%M>2X(#o-)6+5UrBo$O zy(VAiiS74?hzJ|LzdBki{HHag^d}3t2bat4K>E~i`mLrX|DQ0;<=@P)QK1~~Cm6zY zOv}T`Oya2K+IkLNu9{Cc9XyUQl*{?5__wW7?(z@eG2Tx6aK&Qhk%qqwX;@gtx4lfZ z+r5~to?>C>d=<hBaNzATrl1PG7RZXk%2YMWrcR3mZnwmq6 zAYXF(`X+VIVs2TrYDzTMn^-m_W1oM!{P!=_o=#_==<{9@Co%_Ncpu}8`E9YXLlsRtd5}#l zpCg=f_r_IfNaG{NyjO_lP)ae2jq6{#H_}Ny91w^C$8UC|vsrzpL{3Vo{DC3lXFVw~ zF|q$mf;$;B+BtS8iVMAzvoQte0Vjw-I8n5Fe7k0iRNq_u`gx{M1q+{uh=}X6UIQtC zKbS)B03KZXqP)yvM~ux)Os@d?yKfHyG7tv67B64EoR@TU{|sm|MZw*VvXlxHESEkI$#1AcN z9CQRl@9<@>bHPqI>NTT0&WIB%3jpr+$tnf^n91He2O289Z@`4{toJPk(5w$T2z>?K zq|D4rmGTLDVg;8I78Je1dQz1Da4tCU$SuKTXP%f&IDZwfIk3ZXq9N=6XVmu>% zHbuYC3!Sy=!u3$+DS+wANIw{9`qKIGAlnZWkm!-;Ag0=%9QFCvvHEqDT zwgG$Vl~?Jl83C_$xfxSoLb%8OI9g>Nv~B8?vki}0KmI87;ho3fJbFnHXxSso1~V4% zhBrJKiLnb=f0ZOyvNY0!NkQS-cHHGonGfklHtt@y1T07zre1g$t&kVpAk5%nh#1dy zfiXQ$y~zuoq@gn{EiI1K;e3ZK-YfZ4o85Y_P0~H>uB~cL0+%W@<0z_PiH^8<%dw%y z#BhB{qE~?DmN*;&G`I}s^S~eO@eA| zwrys1mpDxXuOvqhF86)$fs0E~3Zgve#ChRo--b7%H?MT{R&t0=+qaQwC`9JL-k!O` zSwoS1aZK7Ec804Een-VxAygB&>gxE4qN$Rn;gZ%r!EF4NR`XV+H^H5OUIkNE*iS;N zrXQ zsd-oUwdU&TKu$&9D&1b=>UE%i{h{dllU}a!j@F~0G~YorE%&SIWv|HVCz<}I-e$Hl zCK7)yn?Eq!f!tX_R$?n4S&qnOcZ!8)8kCfh#V9r0-ri<|o+t}(FllxH-g;CbyR0@p z|L-XyCD#9#xv$M006fnS+%_S&K*ngtNq*RdM zQ|#v#;M%)kp{GZDX>QI6xZ0`X;^O4o_1XMWR19eQPa9L!d?&l6l(w6rHiT5;1ApC7?fGn$eFKN9?JYOud%>_r_wL~nwa+rrO(ZnQ+1!dfF^Rz#CLBN&}b;f?&zhM%tUV7BShg_=@ehQ zr<$0baVBzI%n%<8Mb^Mjq~i{0Ub)~k)^R|<4-ODH{*XBA!0Ypa=$IIo<|xQbiXbp; zQ~l>9VW<%O@$&kSZ7^Oid>qSPSMLGGFmqd})mo1P1Iz;`d?w2TxXpw?t zQN1#9d%gj6LY-@AU4Q0$s`Q~D%6Y9a(7?V-@z&_M|6ROGJ|%oJX+VD6w(x?Luf7@| z zlEq&=-H?4I^}xp;Q0wtsp8&@$wE`pSg<+pnJAe3j#MQmbm{^U3Al#Xv>DZoMXOI6? zLlM(32My4UQcaU8@&gFjBhn!q%WB*)O!g7b8B2SBB^J*t29}dQfOh6{bY_G_AFK~i zKWqmtO-^RP9pVGOPUtpw;Z&f{dKodZq{fRAi}{AFh%q&K5!SFX%`_02_IEivqq(jS zWl}-kTYqJou8xskNE;PPEaWgN$mrZH;uvSi>kdeFzD{}L)5&CofkR~S7?xBe?FPW? ztk;<{+>xQ;M8b0p;XEUUQxsA03O~9v)zstz0vdaN&;RXrANLT}9IAX;#|yz{sBpbD zB@}J^S)lfLbTdaLid0#vuRMb+6Zc1s@cGxWu50vfZMW7Z;fCFhyTTcQTbGv}6{axU zO{Qbu<|aM2=kUKnE09Y!gx>mOe=*1m%gSO_Qnd$arHyIBY|f(N|ERZNqx2tGh-3JRP`v_KJSAvGdm3Fw)Y-#PCZ*&6AB~& zemdkepGr?~c3;%t{Io!~vT5KV!2(GuVZdyJB)1&m*)=uI@QqSx=I`SJUpIOCjRQgT zJ5Qu9Z+5K@e}6CaDagJ!;l4b@MAn2?+vAppUX{nsym)W!Y!*I81#;2YYnKIVI&mO} zYuESJ99R_|vf%!6*g@QstKA`{hZ!9o^Hoz_-2?SuQueR-$#|ZiK(+al6QHvD{8B+H zVF|Qn5>g~W7%5)_`ahT@+Q+^=pwur1y58N+Qp3 z-Zg<6kRB39Wf)z#IZt-xx7{7`lQ18(rSFQPY!7U%s;cS+PHI|_`GofqKb44HxEe12 zFORZF5`m@oD*zFlWCHjQ26g_Zz_iDJKjnXkg$hx>RbO>QIuT_H`8=S9>5vZrM`J3G zvq5rJR`hYAnXuuNmWCl7pu*4t0c<_f#8!tAt2^P8E&$yC4N6+;Pn$K*-Q+qXa~m)m)V1D1mk7tHCl4oySm3Sw$fRj@Qf z&$d8USAY?O!#j6m)d_yLl9LUZMB~4Il^ej=Un|<@RYkqmHpsoSH`kQ5uY+`dJO}H1 z8BSk`Mbv=!ziwcR1wnq-Q6`xG;Wm_&U*DVjfC9!R+aA2wynQ>cCC-P&kBm@*ERiX& z7uBE;QC(>FTJ0h$?42{BluDNaEurU;rPb*XE7tu1CZ(X5e017bwgN&hSobt#!45a& z7qRWzSfEqZ2il*}wRN2y&!8rSApqsiLnI4lU1e7Kr$xCo*x2i3v^ zy~Y=HFfG%SkA2y1-Bf#}-p?5rZ=~OJ;6r_O9nZ#gnf9@_qfHH6XKHR?@OX0g8|nqC zC9Zyx%l>JZiK~FA5S}xgMB_#GauneUK%Yl?nKEqcO%yu`SWml+4JRmS8$LyjsTO2T zxq7PY{*0m4&VIq~*;<^Ic{cKJh?n0VKJhjsJW8>M)UothPc&fij{5S^aazW%pCYz| z2$3Y)7#x@F+GbZrlmudO49d)6Kq89OSg}5+vK>_Xf7V8TKHa6Qt(nL2R?|RqWjxkU zM~c(^{AZSgw_{(CiwcU};O3JjPoe-U`BK@v*d2E)H4caoWyZVJW72JtVb z1XznSa4oFY`9yLJKv~>7?b(6Mg|f1>#r5Rzt4N`v}8yo)T?dI$FCO}8Je2a&V&ozY>AxvLEc_Fx1gaYzC z??YXIhNNCC5M(QWFr%c5jA=)8ISsc^~ZXz6-;#`nFifqznhoI=Czz1kp1^+Q!rkpcvP1DWK))luuL9RC4&jL5C4tDCw= z`}|_#1$~hQKpk zP(hN(p3pf3GpqW~9W*u#3o_<++p1ne?+&Z{TZqJb7nS{=_00M>ogN<>`{^8rKbl&H z!C=679(JvRg|lLFGqa4U&H2t>Wynw!`T~2b%lXc%_91EaLI#qR?najZLoREMspkh) zR@RIYB!1hy`wLV}O-I0~3XE3#A~?+LoTr#~jQR?wPRRk`Y8URkMIk>)3xTOOv}PQ!@G4 zBGK7l2V^-xHC*hiKHfe z7DFc|*q4JzFOy?r)kKC7dv6ZXSAO3wTX><`sO&52QZ3X(dCjH4FE6Ux$`jXwb4ul?zKf5%jc+b3$(Kcf zBQ3W*a`TClDUS$*u54yaB=Ox+p#1To?VwULjDzfs#ui~I2qY|zjpj$r9_O|+{`sj^ z`)^tNJm`v}`Cw%^{a_^I;7`;-jru-&0bJw{EO%R9YsdY>^azPr*y!~0itEdpnXtBU zSs%LYAN#!ROVgdWLYnl962l~@3K+*I!y_mF7T=7e+7_!t)@^y~sa^cSKyEXOkYdj= zF3x8AxsfhXeM(zpGmtS>y_|Xo9MK1@)|Pq^0D+aldEZt*3iBLqlLm2}_KZXb8)*I# z8|4lLr-0uk8$gc>ZUHn#Juw&m4taUv)M!75)kC!qW>R%~K_naAqcLGE2xm)+L+{B# zcihCv;%&t4oxy(HW=Qodq_SRrS6k!a_Vf?Ts=%#M9}gsWd_mPd(Y0OZ4dK00x?1~5 zqIp%@>We*SzQw;h8!~4i>C{0aPR%#sHpI?L$-O7H9}*+=>{Y;RC9{ z1)N3Y+s?!L_&5+Vf(o8yvn_$-Z^(Flwy&M~Mlf3ST&{y9#!f;DoeR&h-@urW*)QKv z{JVTlax1q9869GLGpbZ@DP{-4r{elvLDsOSypA$(F=X5tf*P<-3-x+CHgDl-8m&lE zDChm!jC(mxmJW__;i<&a-JeQ5S~|sV*DQ{{A?G5~J5rb?XD_=4n*2#h39);*RlEPo z-TCH*@jEmK{`COJZCUccnVLkT)IkR?)0u4Do@w=Bd>?YPKC?+aMG{MTip(-$Ma{~= z^`G@Rm#aOIjW7QO<8~i5x=Nn;4F7Qgb*y@f$_a-Mf+-Rw*tl?&*~yxiR@1(JIJJtbx;nwnOI z8i#ckXHnmH;H}9u`;zCmG^ijTLP%5m4*B@~>1=5l1`YlnG=En=wPP=;#lWwFIGK5Tfx3CZcq{1qOE(Tn%)bi^Q1N*uN{Q4wH}7RyRCrYC5+!OwMSQ zaOCp!I2S}bLZ$7?`zu{bd%%cN0KN&dOqIasozAN>&nfw!1(|B)Lt<9W44STY^|Y1D z;EAbT$WlmnCw}YUB^>ftO*bLdSqiZ@{6o*#*?DD}#fgyMIvoq*&AQQiAS&{JVTqx+ z%Latb-+PrZo}+?Xi5YKX@r-YGFGp_iVG$&!I$T$|9MA8`ly%g%fv2ngjRCT}c+gKjit*L~1g+fnJbGDWm|N)1wS~yCJBz4jS`SwV z4i3&sItq%7YyRWHmiP5MQwb(S6>7Uhv%5Nmh7-+2#GeIHMI$5eyu1CiK0H*WpOBTE zqV_au3GcB)YxihpDo2^z?gr5?@=iqm)i~Z-6JVPEKXS)KKKLDak0P4mibb6U1m4t? LwUo*ftit{Wv>>__ diff --git a/source/blender/include/BIF_resources.h b/source/blender/include/BIF_resources.h index adddb0d1347..e6cbe7bb69a 100644 --- a/source/blender/include/BIF_resources.h +++ b/source/blender/include/BIF_resources.h @@ -293,7 +293,7 @@ typedef enum { ICON_ARMATURE_DEHLT, ICON_SNAP_GEAR, ICON_SNAP_GEO, - ICON_BLANK41, + ICON_SNAP_NORMAL, ICON_BLANK42, ICON_SMOOTHCURVE, diff --git a/source/blender/include/transform.h b/source/blender/include/transform.h index 82adb1ac12a..7d497dc05ec 100644 --- a/source/blender/include/transform.h +++ b/source/blender/include/transform.h @@ -75,6 +75,8 @@ typedef struct TransSnap { int status; float snapPoint[3]; float snapTarget[3]; + float snapNormal[3]; + float snapTangent[3]; float dist; // Distance from snapPoint to snapTarget double last; void (*applySnap)(struct TransInfo *, float *); @@ -457,6 +459,8 @@ void applySnapping(TransInfo *t, float *vec); void resetSnapping(TransInfo *t); int handleSnapping(TransInfo *t, int event); void drawSnapping(TransInfo *t); +int usingSnappingNormal(TransInfo *t); +int validSnappingNormal(TransInfo *t); /*********************** Generics ********************************/ @@ -487,6 +491,7 @@ void calculateCenterCursor2D(TransInfo *t); void calculatePropRatio(TransInfo *t); void getViewVector(float coord[3], float vec[3]); +void getViewRay(short mval[2], float p[3], float d[3]); TransInfo * BIF_GetTransInfo(void); diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h index aae8a697cbe..75affbfa7f5 100644 --- a/source/blender/makesdna/DNA_scene_types.h +++ b/source/blender/makesdna/DNA_scene_types.h @@ -543,8 +543,8 @@ typedef struct Scene { ListBase markers; ListBase transform_spaces; - short jumpframe, pad1; - short snap_flag, snap_target; + short jumpframe; + short snap_mode, snap_flag, snap_target; /* none of the dependancy graph vars is mean to be saved */ struct DagForest *theDag; @@ -707,11 +707,16 @@ typedef struct Scene { /* scene->snap_flag */ #define SCE_SNAP 1 +#define SCE_SNAP_ROTATE 2 /* scene->snap_target */ #define SCE_SNAP_TARGET_CLOSEST 0 #define SCE_SNAP_TARGET_CENTER 1 #define SCE_SNAP_TARGET_MEDIAN 2 #define SCE_SNAP_TARGET_ACTIVE 3 +/* scene->snap_mode */ +#define SCE_SNAP_MODE_VERTEX 0 +#define SCE_SNAP_MODE_EDGE 1 +#define SCE_SNAP_MODE_FACE 2 /* sce->selectmode */ #define SCE_SELECT_VERTEX 1 /* for mesh */ diff --git a/source/blender/src/blenderbuttons.c b/source/blender/src/blenderbuttons.c index 6c6afdef68c..e15ef3fd898 100644 --- a/source/blender/src/blenderbuttons.c +++ b/source/blender/src/blenderbuttons.c @@ -1,2165 +1,2181 @@ /* DataToC output of file */ -int datatoc_blenderbuttons_size= 69070; +int datatoc_blenderbuttons_size= 69599; char datatoc_blenderbuttons[]= { -137, 80, 78, 71, 13, 10, 26, 10, 0, 0, 0, 13, 73, 72, - 68, 82, 0, 0, 2, 0, 0, 0, 1, 0, 8, 6, 0, 0, 0,197,144,206,103, 0, 0, 0, 6, 98, 75, 71, 68, 0,255, 0,255, 0, -255,160,189,167,147, 0, 0, 0, 9,112, 72, 89,115, 0, 0, 11, 19, 0, 0, 11, 19, 1, 0,154,156, 24, 0, 0, 0, 7,116, 73, - 77, 69, 7,216, 3, 21, 16, 3, 34,240,181, 88,200, 0, 0, 32, 0, 73, 68, 65, 84,120,218,236,125,121, 92, 84, 85,255,255,251, -220,217,217,119, 84, 92, 64,197,125,197, 61,212,160, 7, 45,253,154,166, 2,102,182, 61,245,196,100,218,106,105, 86,207, 83,254, -242,145,220, 90, 53, 29,159, 74,179,212, 18,212,180, 92, 18,116, 80, 67,114, 87, 44, 23, 20, 69, 4, 65,182, 97,102,152,253,206, - 61,191, 63,102,134,134, 17,152, 5, 52,173,121,191,152, 23,115,239,220,249,204,185,247,156,243,121,127,150,179,144, 1, 3, 6, - 80,120,225,133, 23, 94,120,225,133, 23,127, 43, 48,222, 71,224,133, 23, 94,120,225,133, 23,127, 31,156, 60,149, 13, 0, 32,222, - 8,128, 23, 94,120,225,133, 23, 94,120, 35, 0, 94,120,225,133, 23, 94,120,225,133,215, 0,240,194, 11, 47,188,240,194, 11, 47, -188, 6,128, 23, 94,120,225,133, 23, 94,120,241,151, 0,223,254, 96,230,204,153,196, 83, 65,171, 86,173,186,101, 44,129, 87,158, - 87, 94, 51,160,171, 86,173,250,211,202,151,147,147, 67, 19, 18, 18,136,183, 62,238, 93,121,167, 79,159,246,184,241, 13, 24, 48, - 0,222,250,240,202,251, 43,203,115,219, 0,248, 59, 67, 42,149, 54,120,128, 50,153,140,220,205,229, 92,189,122, 53, 8, 33,196, - 91,115,158,213,241,244,233,211,145,153,153, 89,127,156,156,156,252,151,120,150,187,118,159,108, 86, 17,140, 31, 23,247,151,110, - 51,146,224,109, 16,235,187, 34, 6, 70,212, 97, 55, 10,116,239,220,181,109,241,110,213, 49, 94,252, 77, 35, 0,119,162,177,238, -218,181, 43, 97,251,246,237,114,219,241,164, 73,147, 18,199,143, 31,159,115, 55, 60, 12, 74, 45,186,243,110,229, 85,169, 84, 74, -139,138,138, 0, 0,209,209,209, 0,112, 79, 40, 17, 71,227,202,106, 96, 53,233,153,187, 42,119,211,166, 77, 46, 27,106, 82,169, -148,110,222,188,185,254,120,219,182,109, 24, 51,102, 76,253,113,102,102, 38,253,179,140,128, 65,131, 6, 81, 0, 56,113,226, 4, -105,141,235,182,255, 32,107,198, 0,144,181,184,254,162, 98, 58, 0, 0,110,234,245, 96,117, 6,203,201, 90, 21, 0, 32, 37, 37, - 5, 73, 73, 73, 77,150,111, 77,210, 26, 26, 91, 22,235,214,239, 39,254,158,232, 66,189, 72, 16,252,194, 89,232,183,111,131, 66, - 49, 25, 10, 0,113,146,165,120, 71,114, 2, 29,196, 64,165,190, 16,239,232, 82,221,250,221,236,236,236,132,140,140, 12,185,253, -185,148,148,148,196,164,164,164,156,187,169,111,181,150, 14,184, 23,238,247,118,224,189,183, 94, 34,126,130, 64, 98, 16, 11,169, -161, 86,199,212,233, 84,220,135,159,174,248, 91,204,142,115,106, 0,236,218,181, 43,193,246,191,165, 68,109, 83, 36, 11, 54, 47, -132, 95,135, 64,212, 93, 87,226,221,212,119,228,219,183,111,135,215, 26,118, 14,153, 76, 70,162,163,163,105, 81, 81, 17,138,138, -138,176,103,207,158,187,214,147,176,213,181, 76, 38, 35, 50,153, 76, 32,149, 74, 77, 75,150, 44, 57, 6, 0,115,231,206, 29,210, -220,119, 39, 79,158, 92,255,158,101,205, 48,154, 12, 48, 26,140, 48, 26, 45, 47,150,101, 49,119,238, 92,183,202, 98, 79,254,141, - 97,204,152, 49,127,170, 17,224,138,241, 51,104,208, 32,167, 50,198,143,139, 35,158,144,188,203, 8, 10, 64,254,149,239, 32, 65, -123,152,145,139,138, 47, 78,226, 76, 97, 53,166,124,176,214,165,175,199,150,197,186, 72,232, 22,200,123,203,157, 42, 98,201,248, -119, 16, 50,233, 89,148,190, 18, 7,232, 20,245,231, 79,234,222,192, 73, 0,208, 1,163, 37, 41,216, 23,124, 2, 65, 0, 6, 41, - 6,185,220,126, 29,145,145,145, 33,207,200,200,184, 43,244,149,173,140,173,161, 3,238,133,251,109,109,172, 95,185,138, 60, 30, - 21,195,127, 41,249, 73, 94, 68,207, 40,134, 79, 34,136, 86,169,228,196,136, 52, 51,237,218,155,245, 55,174,154, 93,124,118, 55, -220,208,225,237, 92,144, 55,199, 13,121,203,111,171, 1,176,125,251,118,249,230,127,191,133,212,247, 23,201,199,143, 31, 79, 90, -210,192,108,196, 15, 0, 85,218,106, 32, 20,152,191,239, 61,168,174, 40, 32,125,238,238, 34,178,166, 58,196,159, 93, 70,123, 35, -224,161,135, 30, 66, 81, 81, 17,162,163,163,239,186,103, 39,151, 91, 28,137,196,196, 68, 42,147,201, 24,153, 76, 22, 37,149, 74, - 75,151, 44, 89,114,194, 85, 57, 44,203,194,104, 52,213, 19,191, 61,249, 31, 63,126, 28,131, 7, 15,118,171, 92,169,169,127,120, -128,211,167, 79, 71, 86, 86, 86, 3, 3,160, 53,218,138, 39,245,112,226,196, 9,146,147,147, 67,199,142, 29,123,203,103,123,247, -238,197,166, 77,155,234,143,155, 27,183,112,139,241,222,138,233,128,168,152, 14, 40, 85, 40,177,245,249,169, 8, 37,241, 40,252, -223,235,232, 60,185, 51,178,220, 32,127, 27,210,210,210, 40, 0,172, 89,179,166,197,109, 54,106,115, 46,180,215,234, 80, 42,141, -105,246,186,179,226,108, 44,232,123, 19,233,103,223,110, 81,125,182, 6,233,182,166,140,214,136, 4,220,238,251,109, 45,228,230, -230,250, 0,184, 15,128,159,221,233, 90, 0,249,241,241,241, 53,174,202,209,113, 58,198, 88,101, 16,140,155, 56, 89,172,128, 73, - 44, 16,240,249, 42,189,152, 17, 10,117, 28, 47,192,151, 53, 74, 76, 38,126,249, 13,131,152, 39,210,235,205, 6,179, 84, 42, 37, -141,141, 25,177, 71,109,109,237,127,109,239, 11, 10, 10,170,124,125,125, 25,141, 70,195,217, 95, 51,116,232,208,143, 92, 45, 35, -165,212, 41,177, 19, 66,230,180,244,153,242,157,121,255,221,186,117, 67,172, 95, 0, 90, 18, 5,176, 39,255, 42,109, 53,210,255, -241, 94,253,103,255,220,254, 2, 16, 1, 76, 94,146,234, 86, 35,107,138,160, 91,139,164,175, 95,191, 14, 0,232,208,161, 67,131, -247,182,223,117,214, 32,110,103,136,207,222, 8, 48,153, 88,172, 94,189,250,182,121, 1,238,202,116, 32,127,251,239,223,144,201, -100,193, 82,169, 84,225, 50,249,155, 76, 48, 26, 13, 48, 24,141, 48, 57,144, 63,229,220,139,208,165,166,166,226,248,241,227,245, -199,203,151, 47, 71,114,114,114,253,113,102,102,102,139,141, 29, 59,131,167,197,237,207,158,248,167, 79,159,142,129, 3, 7,122, - 36,167,181,210, 1, 37, 87,138,161,217,246, 31,248, 61,243, 9,162, 98, 58, 32, 50, 84,130, 43,219,174, 88,200, 63, 40,192,146, - 2, 16,240, 92,146,213, 26,196, 15, 0,221,206, 93,198,245,119, 23, 66,151,177,174,249, 8,129, 68, 2,189, 94,143,194,194, 66, - 84,232, 47,162, 27,162,154,188, 54, 59, 59, 59,161,185,182, 47,147,201,136,173,159,100,103,103, 39,184, 19, 30,183,143,138,217, -250,171,253, 57,119, 29,129,166,136,219, 29, 93,208,216,253,102,101,101, 81, 66, 8,146,146,146, 72, 75,238,215,134,103,159,125, -150,126,249,229,151, 45,170,243,220,220,220, 64, 0,147,247,237,219,247, 31,142,227, 12,118, 36,200,231,241,120,190, 0,254, 21, - 31, 31,191,203,153,156,130, 43, 5,124,137, 80, 44, 22, 8, 68,190, 12,159, 4, 80,158,200,135,227,241,248, 28, 97,192, 17,190, -153,242,120, 6, 30, 71,244, 26,158, 89,235, 43, 20, 16, 94,151, 14,122,241,196, 8, 14,197,206,203,168, 80, 40, 84, 90,173,150, - 5, 0,141, 70,195,189,245,214, 91,245,132,191,104,209,162, 87, 91,218,222,199,140, 25,243,188,237,125, 86, 86,214,234,214,232, - 67,140, 51,239,127,225,180,100,232, 43, 43,241,122,239, 30,176,207,221,187,236,133, 88, 83, 8,246,228, 63,105,210,164, 68,153, - 76, 70, 38, 77,154,148,184,118,210,231,150,200, 98,247,176, 6,215,187,130,185, 43, 11, 48,119,101, 1,102, 45, 59,143,167,222, -255, 13, 83,230,159,110,241, 3, 41, 41, 41,113,201, 48,184, 83,228, 95, 84, 84,212, 36, 49, 71, 71, 71,195,100, 52, 98,216,208, -161, 45,254, 29, 91,152,124,243,230,205,144,203,229,245,175,230, 12,173,166,200, 48, 49, 49,209,145,252,235, 13,101, 87, 20, 19, -203,154, 45,158,191,193, 18,250,119, 36,127,179,217, 12,141, 78,227,214, 61,218, 34, 6,142, 81,131,204,204, 76,100,102,102, 54, - 48, 6,220,186,223,156,134,250, 80,158,147,227,214, 51,107,142,252,167, 79,159,142, 37, 75,150,212,147,191,128, 47,112, 75,206, -248,113,113,196,154,130,105,244,229,142, 44, 29,138, 81, 55,121, 24,104,198,235, 40,185, 82, 12, 58,185,231, 31,222, 74,198,235, -224,183, 13, 7,130,130,238,168, 71,168,169, 42,132, 46, 99, 29, 40,165, 56,123,246, 44, 70,143, 30, 13,137, 68,210,128,248,131, -131,131,161,211,233,160,211,233, 80, 90, 90,138,199,116, 47,225,139,224, 87,154,148,105,203,129, 55,247,124,108,159, 57,230,203, - 93, 37,238,214,114, 86,108,223,117, 36,127,103, 14, 82,115,247,155,149,149, 69, 51, 51, 51,145,145,145,129,236,236,108,218,210, -251,125,246,217,103, 41,159,207,199,179,207, 62,235,113,159,200,205,205, 21, 3,120, 46, 59, 59,251,173,247,223,127,255, 8, 33, - 36,218,246, 2,208, 62, 52, 52,212,103,255,254,253,171,114,115,115, 71, 55, 39,199, 76, 57, 30,143, 8, 68, 70,150, 6, 24, 12, -166, 8, 51,199,181, 55,115, 92,140,153,144,142,224,241, 66, 9, 33, 65, 32,188, 0,142, 34,132, 26,185, 32,149,206,228, 27, 17, -192,242,152,161,106,151,234, 72,171,213,178,142, 94,255,221, 14,198, 21,239, 95, 91, 94,134,113, 3,227,220, 38,104,155, 17,177, - 96,243, 66, 0,168, 39,127, 91, 20, 97,252,248,241, 57, 54, 35,160, 68,117, 3,113,115,135,187,101,100,104,116,102,104,116,102, -148, 85, 27, 80, 90,169,199,245,155,122,143,136,207,214, 89,156,145,255,159,133,166,140, 0, 0,208, 27, 13,208,235,245, 30,203, -182,145,182, 45, 71, 30, 30, 30,110,239,205,194, 85,101,226,232, 9, 55, 21, 74,116, 69,233, 25, 77, 6,139,231,111, 48,194,104, -106, 72,254, 38,147, 9, 26,141, 6,106,149,250, 79,173, 19,139,193,148, 97, 31,144,179,253, 97,243,230, 12,143,141, 0,123,242, -183, 17, 63,195, 48, 16,139,197,240,245,243,105, 81,153,119,237, 62, 73,155,122, 57,251,238,158,249,239, 33, 20,241, 96,147, 94, - 4, 0,248,229, 93,198,153,194,106,139,193,150,244, 34, 76,103, 23, 0, 85,213,110,149, 39, 45, 45,141,218,210, 1,158,192, 23, - 85, 0,128,117,235,214, 97,251,246,237, 88,186,116, 41,142, 30, 61, 10,131,193,128,138,138, 10,155, 87, 86,127,125, 84, 84, 20, -116, 0,120,184,250,167,180,151,166,218,189,163, 55,239,169, 65,209, 88, 90,192, 93,121,246,145,176,140,140,140, 22,221,179,141, -252, 1,192, 83, 35, 32, 55, 55,183,141,149,252,211,190,254,250,235,115,239,188,243,206, 35, 27, 55,110, 68,183,110,221, 0, 0, -157, 58,117,130, 82,169, 20, 45, 88,176,224,196,254,253,251,191,205,205,205,141,110, 84, 16, 1,192, 81, 2,142, 21,155,205,108, -136,153, 53,183, 55,153, 77, 93,121, 12,105, 39,228, 51, 2,177,128,167,227,251, 8,107,125,253,121, 42,158,152,178, 98, 30,207, -151,207, 26, 3,174,158, 60, 37,122, 34,252, 99,167,229, 46, 40, 40,168,210,104, 52, 92, 99, 97,254,254,253,251, 95, 52, 26,141, -173,214,150,250,247,239,223,106,178,248,205, 17,247,255,210,158,253,131,108, 75,174,227,245,222, 61,176,108,251,118,183,199, 2, -216,188,127, 27,233, 55,240, 82,198,143,207,217,190,125, 59, 0, 32,180,111, 27,183, 10, 95,167, 51, 67,173,101,161,210,176, 80, -214,177,168, 85,179,110, 63,128,198, 70,254,219,123,249,246,239,175, 92,185,130,218,218,218, 59,166, 52, 86,175, 94,141,232,232, -104,216, 6,253,217,231,250,165, 82, 41, 93,189,122, 53,244, 58,157,199, 6,128, 84, 42,165,107,215,174, 69, 73,105, 41, 4, 60, - 30, 34,219,180,105, 64,254,255,248,199, 63,144,154,154,234,146,114,146,201,100, 36, 49, 49,177,129, 17,224, 24,201,112,117,172, -130,209, 96,132,209, 96,128,201,100, 4,203,154,235,201,223, 96, 48, 64,171,213,162,174,174, 14,106,181,251, 6,128,125, 10,192, - 6, 79, 61,255,205, 25,155, 1, 10, 84, 89,137,134, 90, 26, 17, 8,165, 22, 35, 32, 35, 3,169, 41, 41,110,167, 3, 28,201, 95, - 32, 16, 64, 36, 18, 65, 44, 22, 67, 44, 22,123,116,223, 13,250,117, 19, 41, 1,103, 41,173, 41,171,183,128, 78,140,193,205, 17, -113, 8, 69, 60, 36, 83, 63, 3, 91, 86, 9, 4, 5,128, 95,189, 9, 63,125,124, 2,224,241,220, 42, 75, 75, 83, 1, 26,158, 69, -167,164,167,167,163,178,178, 18,171, 86,173, 66,255,254,253,241,254,251,239, 35, 46, 46, 14, 58,157,206,209, 67,179,153,212,119, -148,248, 93, 37,104, 79,211, 1, 77, 25, 18,158,200, 73, 73, 73,169, 39,126, 79,250, 70, 99,228, 95, 79, 54,124, 62, 88,150,117, - 55, 29,224,159,159,159,255,233,204,153, 51, 15,246,237,219, 55, 0, 0,222,123,239, 61, 20, 20, 20, 0, 0,134, 15, 31,142,173, - 91,183, 98,228,200,145,190,143, 61,246, 88, 97, 78, 78, 78, 54,143,199,123,236, 86, 69, 15,132,132,134,112, 87,174, 20,178, 57, -242,125,187,187,118,141,205,137,233, 20,125,142,231, 47,169,224, 17,161,134, 17, 9,180,140,216, 71,109,228,243,140,160, 38, 30, - 39, 54,249,171, 75,171,253,142,238, 63, 61, 52, 44, 56,114,171, 83, 99,212, 46,231,191,109,219,182,167, 38, 79,158,252,181, 45, -236,175, 82,169, 24,161, 80,216,226,182,212, 90, 97,127,167, 17, 0,155,151, 63,184, 75, 44,244,149,149,208,148, 88, 72,112,180, -213, 59,116, 55, 10,112,229,183,203,183,200,110,236,184,250,108,185, 91,133,111, 41,249,219, 19, 63,165, 20, 29, 58,116,104,240, -153,201,100,170,127,213,214,214, 66,163,209,160,166,166,230,142, 41, 15,219, 60,255, 61,123,246, 52,136, 4,216,200,191, 95,191, -126,208,235,117,245,138,142,218,172, 25, 23, 21,211,202,207, 87,194,100, 50,161,125, 84, 20, 76,102,115,163,228,239,142, 34,177, - 26, 1,183,120, 37,182,169,139,205, 69, 50,110, 49, 0,140,166,122,242, 63,118,244, 24,180, 58, 29,212,106, 53,148, 74, 37,106, -107,107, 27,120,118,238,194,150, 6,240, 52,239, 15, 0,213, 85,213,168,174,174, 66, 85,117, 13,170,170,171, 81, 93, 93,141,234, - 42,139, 71,218,163,103, 79,212, 88,223,187,235,253, 3,192,192,129, 3,255,240,250,125,125,225,231,231, 15,127, 63,127,168,213, -234,196,150,180,167,230, 82, 2,206,190, 91,184, 52, 13,130,169,159, 33, 20,241,224,231,125, 6,211,150, 23,129,160, 0,236,120, - 33, 25,215,118, 92,197,195, 75,214, 3,252, 59,188,172,136,254, 26, 36, 81, 18,104, 52, 26,232,245,122,104,181, 90,228,229,229, -225,131, 15, 62,104,244,114, 31, 31, 91, 4,229,178,219,228,237,169, 87,109,255,124, 29,159,119, 83,199, 45, 49, 50, 26, 75, 11, -184, 35, 39, 41, 41,137,164,164,164, 32, 57, 57, 25, 99,198,140,241, 56, 50,241,229,151, 95, 18,150,109,168,147, 89,150,133,187, - 99, 1,226,227,227, 47,165,164,164,244,223,184,113,227,232, 67,135, 14,249, 39, 37, 37, 29,181,145,191,213, 81,133, 72, 36,162, -215,174, 93, 19,236,222,189,187,123,112,112,240,177,248,248,248,194,198,100, 41,107,149, 92,108, 76, 55,245,240,225,195,147,207, -157,251,253, 1,149, 70,221,134,178, 38, 22, 12, 76,172,129, 49, 24, 12, 6,157, 10,229, 42,206,160, 87,151, 22,151,179, 63,237, -220,181, 56, 44, 52,188,194,104,212, 58,117,223, 27,243,254, 21, 10, 5, 31, 0, 2, 2, 2,238,218,180, 0,211,148,247,191,249, -223,111, 89,172,230,242,178, 6,159,185, 59, 22, 96,210,164, 73,137, 43,159,251, 4,128,101,192,223,246,237,219,229,246, 83, 11, -183,111,223, 46, 31,243,205, 35, 0,128,147, 75,126,197,164, 73,147, 18,239,212,205,219,119,146,146,146,146,122,111,223, 70,250, -118,149, 11,181, 90, 13,189, 94,111,167, 68,238, 92, 25,159,127,222, 50,246,195,196,178, 56,119,238, 28, 78,157, 60,137,254,253, -250, 67,175,215, 67,167,211, 67,175,211,225,219,111,190,129,237, 58, 87, 58,250,242,229,203,209,171,103, 47,152, 76, 38, 92,186, -116, 9,172,201,136,210,146,210, 86,125,166,182, 99,235,154, 5,136,142,142,118, 73, 49, 25, 77, 6,176,102, 75,216,255,200,145, - 95,161,209,105, 80,167, 86, 65,169, 84, 66, 81, 91, 11,133,162,166, 69,134,152, 45, 18,208, 18, 15,231,224,193,131, 80,171,213, - 80,171, 85,214,255,106,132,133,134,162, 71,207,158,184,112,254, 60, 14, 28, 60,232,182, 76,155,247,207,231, 11,224,227,227, 3, - 63, 63, 63,248,251,249,193,207,207, 7, 53,138,154, 68, 0, 57,183, 59,212,223, 20,206, 20, 86,195,116,118, 1,170,145, 11, 50, -126, 25, 72,252,127, 80,184, 52, 13, 19,151,124, 13,177,128, 1, 4,124,203,203, 3,120,154, 10, 40,157,240, 57, 66, 54, 77,128, - 86,171, 69, 72, 72, 8, 20, 10, 5, 20, 10, 5, 14, 31, 62,140,178,178,178,250, 48,113,253,245,165,165,120, 33, 88,130, 48,159, -202,230, 60,224, 68,123, 82,181, 31, 36,103,123,111,251,204,118,173, 39,222,185,171,233, 1, 87,201,223, 83,207,191,177,251, 77, - 74, 74, 34, 99,198,140, 33, 45,185, 95, 71, 35,192, 19,242,183, 33, 44, 44, 44,255,145, 71, 30,121, 44, 61, 61,189,251,153, 51, -103,226, 37, 18, 9,111,226,196,137, 68, 36, 18,129,227, 56, 50,126,252,248,252,151, 95,126,185, 95,159, 62,125,118,252,235, 95, -255,122,202,108, 54, 87, 55, 19,243,230,126, 63,127,233, 88,159,190,253, 30, 63,118,244,232,148, 29, 59,127, 92,116,252,232,209, - 54,231, 10, 46,136, 47,149, 22,210,111, 63,249, 94,146,190,124,105,175,236,157, 59,151,119,237,210,245, 39,191, 72,223,131,241, -241,241,102,184, 88,242,164,164, 36, 28, 59,118,108,192,234,213,171, 23,232,245,122,193,251,239,191,255,225,142, 29, 59,166,151, -150,150,222, 89,226,104,105, 10, 32,244,106, 17,106,172,161,127,123,140, 14, 15,199, 50, 92,112,221,235,176,134,248, 47,156, 56, -135,160,238, 97, 24,243,205, 35,216,254,196, 15,114, 91,216,223, 70,254, 54,239,223,157, 89, 6, 91,211, 91,103, 36, 62, 33, 4, -231,207,159,135,173,177, 58,134, 89, 5, 2, 1, 4, 2, 1, 42, 43, 43, 49,126,252,248, 59, 94, 73,182, 81,255,171, 87,175,198, -208,161, 67,161, 55, 24,160,211,235,160,183, 14,110,210,233, 45,105,128, 21, 43, 86, 56, 85, 38, 82,169,148, 46, 89,178, 4,102, -179, 25, 39, 78,156,132,128,111, 9,219,198,198,198,226,106, 81, 17, 74, 75, 75,177,105,211,119,152, 62,253, 81,236,219,183,143, -218, 71, 2,154, 83, 64, 50,153, 76, 8,128,149, 74,165, 92, 99, 30,144, 59, 83, 21,109,158,127, 94, 94, 30, 52,117,218,122, 3, - 76,165, 86, 65,165, 82, 66,165,170,243, 56, 20,110,243,254,173, 43, 1,122,100, 8, 76,159, 62,189,193,113, 76,116, 52,122,244, -180, 12,138,187,112,254, 60,174, 90, 35, 30,142,215,185,130, 17,247,141,128, 72, 40,130, 68, 34,129, 88, 44,134, 72, 36, 66,121, -121,185,203,228,239, 44,212,239,233, 26, 1, 83, 62, 88,139,173, 0, 30, 74,255, 63,208,140,215, 65, 82,151,227, 76, 97, 53, 72, - 72, 48, 46,151,168, 44,222,191,155, 41, 0,199, 84,128,219,211, 3,117, 58,128, 87,232, 16,222,183, 16,189,201,100,194, 23, 95, -124,129,209,163,255, 24, 23,182,239,233, 40,160, 66,139,238,187, 20, 24, 16,222,169, 41, 5,158,227,144,251,150, 3,245,234, 95, -238,120,173, 39,132,221, 92,222,222, 83,207,223, 83, 67,226,118,223,175,213, 8,104,241, 44,128,232,232,232, 77, 35, 71,142, 12, - 63,157,159,159,170,211,233,250,201,229,251, 37, 34,177,136,207, 16, 6,251,247,239,247,239,213,171,215,250,148,148,148,255, 84, - 86, 86, 58,245,214,167, 79,155,202,253,180,251,167, 3,253,251, 15,156,107,100, 13, 15, 93, 46,184,180,136, 43, 42,100, 1, 80, - 49, 24, 83,223,174,221, 51, 34, 34,194,119,241,248,194,111,255,251,206, 98,227,183,235,214, 90,115,124, 77, 99,232,208,161, 31, - 37, 37, 37, 1, 0, 42, 43, 43,145,157,157, 29,240,213, 87, 95, 45, 2,128, 99,199,142, 13,237,221,187,247,158,123,194, 0,176, -121,231,255,248,118, 99,243, 94,134, 27, 83, 2,109,214,111,220,220,225, 8,237,219,166,158,244,237, 67,255, 39,151,252,234,150, -229,218, 90,115, 82,109,101,235,217,179, 39,206,158, 61,219,128, 88,106,107,107, 11, 1,116,105,236, 59,158,174,189,220,210,114, - 58,158,255,246,155,111,161,215,235, 97, 48, 26, 96, 52, 26,177,100,201, 18, 56, 35,127, 27, 56,206, 12,177,196, 15, 58,157, 30, -231,207,157, 3, 95, 32,128,201,104,132,143,175, 15, 54,109,218, 4, 30,143,103,155, 59,223,236,189, 46, 89,178,100,143, 84, 42, - 53,202,100,178, 8, 91, 57, 29,214, 1,112, 43,180, 57,119,238, 92,228,230,230,162,174,174, 14,117, 26, 13,212, 42,149,149,252, - 85, 80,171,212,168, 83,215, 65, 99,167,240, 93,121,118,131, 7, 15,166,199,143, 31,175,247,254, 27,155, 6,232,234, 34, 64, 9, - 9, 9,183,212,133,141,244, 79,157, 58, 85,239,205,187,122,207,131, 6, 13,162,182, 69,126,252,124,252, 32,150,136,161, 86,171, - 19,237,114,216,110, 41,222,219,181, 24,144,205, 8,152,156,254, 21,232, 22, 32,236,105, 25,114, 94, 73,198,200,197, 27, 0,129, - 0,190,226,150,229, 57, 29, 13, 1, 0,144,231, 58, 11, 54,222, 68,223, 61, 62, 40,255, 81, 11,197,194, 63,206,154, 76, 38,140, - 26, 53, 10, 0, 16, 21, 44,193, 47,178, 14, 88,250,193,117,124,126, 82,215,172, 52,123,143, 31,176, 12,132,179, 41,118,199, 65, -113,238, 78,139,179, 31,191,211, 82,207,191, 49,157,224,137,172,219,121,191,246, 70, 64,107,180,191,222,189,123,127,170, 86,169, -119, 15, 25, 52,120,168, 90,165, 10, 97,205,172, 33, 50, 50,178, 50, 42, 42,170, 92,165, 82,157,169,172,172,116, 89, 41, 76, 24, - 55,129, 3,176,233,208,193,163,121,241, 35, 71,254, 32,145, 72, 2, 9, 40, 71, 8, 1,199, 81,165, 78,163,144, 95,204, 47, 86, -127,187,110,173, 75,122,222,246,204, 0,203, 64,106,199,129,122, 31,124,240,193,127,238, 9, 3, 96,252,248,241, 57, 45, 89,240, -199,149,198,106, 51, 4,108,196,223,154,132,222,146,178,245,237,219, 23,199,142, 29, 67,101,101,125,136,176, 11, 0, 84, 87, 91, - 34, 74, 79, 60,241,196,159, 90, 89,142,207,136, 82, 74, 31,127,226,113,172, 88,177,210,154, 51,103, 17, 24, 24, 72, 92,253,190, - 13, 18,137,216, 38,207,226, 77,105,180,246,223, 1,224,116,179,137,158, 75,150, 44,185, 36,149, 74, 43,100, 50, 25,207,126, 64, -160,117, 90,160,203,138,206, 54,247, 61, 62, 62,190,213,159,221,224,193,131, 29,247, 2,168,255,220,221, 21, 0,101, 50, 25,201, -201,201,161,155, 54,109,106,176, 80,143, 77,182, 39,237, 57, 33, 33,129,152, 88, 19, 76,106, 83,171,222,123,115,161,127,119,247, - 6,152,242,193, 90,192,110,225,159,251,223,250, 99, 92,146,166,149,202,219, 32, 2,208,187,121,227,179, 52,190, 20,165, 0,226, -150, 6, 99,225,137,110, 8, 7, 80, 89,168, 65,215,174, 93, 1, 0,159, 46, 12,198,131, 67,194, 17,243, 96,129, 75,191,237,206, - 84,183,140,140, 12,121,115,203, 30, 59,211, 55,173,161,243, 90, 42,235, 78,220,111,107, 98,248,136,225,151, 0, 92,186, 37, 98, - 29, 26,234,145,188, 81,163,135, 22,161,209, 81,161, 81,232,218,173,143, 59,134, 84,171,222,103,107, 44,242,227,145, 1,112,187, - 9,108,215,174, 93, 9,219,151,220,125,123, 1,216, 58,210,144, 33, 67,176,107,215, 46,189,149,244, 57, 0, 62,183, 35,242,208, - 74,141,132,200,100,178,122,207,190, 57,242,191,157,152, 59,119,174,125, 60,181, 94, 97,219,166, 17,186,227,237,220,206,231,107, - 47, 59, 39, 39,167,197,203,254, 38, 36, 36,144,132,132,132, 22,151,203,217,218,254,173,129,150,164, 4,230,205,155,135, 43, 87, -174,180, 90, 89, 92, 89,222,215, 93,156,124, 67,129,147,176, 12, 12, 29,157, 34,193,207, 71,186, 33,210,199, 15,191, 31,191,137, -238, 46,146,191,179,246,119,183, 46,135,219, 26,107, 9,220, 75,247,123, 23, 62,255,118,173, 44,111,249,157, 42,251, 29,223, 13, -240,118, 69, 24, 90,211, 8, 24, 63,126,188,248, 30,107,128,228, 79,254,109,219, 10, 53,172,205, 0,240, 42,143,187, 7, 45, 77, - 9,116,238,220,153,116,238,220,185, 85,244,141, 59,251, 0,120,138,131, 25, 58, 28,204, 40,240,246, 89, 47,188,112,230, 68, 14, - 24, 48,128,122, 31,131, 23, 94,120,225,133, 23, 94,252,189,192,120, 31,129, 23, 94,120,225,133, 23, 94,120, 13, 0, 47,188,240, -194, 11, 47,188,240,194,107, 0,120,225,133, 23, 94,120,225,133, 23, 94, 3,192, 11, 47,188,240,194, 11, 47,188,248, 75,160,193, - 44,128,153, 51,103,122, 60, 50,181,177,121,226, 94,121,119,159,188,180,180, 52,143,228, 13, 28, 56,240, 22,121,167, 78,157,242, -184,124,141,201,187, 87,234,195,221,103,184,102,205,154, 59, 82,190,214,174,143, 59, 89,191,206,166,137,186,251,252, 90, 91,158, - 87,191,120,229, 53, 34,175, 61, 0, 5, 0, 33,128,218,187,173,124,110, 27, 0, 94,252,245,177,102,205, 26,239, 67,248,155, 33, - 40, 40,136,129,101,122, 38, 95,169, 84,114,148, 82,243,221, 84, 62,219,190,243,217,217,217,180, 53, 22,154,105,173,149,246,188, -184,125,216,177, 99, 71,194,196,137, 19,115,238,241,219,176,173,125, 37,113,215, 0,184, 43, 35, 0, 94,252,245, 64, 41,109,176, -213,177,167, 17,128, 85,171, 86, 57,189,102,236,216,177, 9, 89, 89, 89, 13, 86, 22, 27, 51,102, 76,226,222,189,123, 61,234,232, -153,153,153,141,202, 75, 78, 78,190, 43,228,221,205, 32,132,144, 78,145,145, 40, 42, 47,167,181,181,181,182,253, 25,220, 90, 98, -208,222, 88, 60,190,117, 69, 9, 33,152, 37,219,157,191, 93, 58,174,223, 55,148, 66,181,102, 79,254,172,121, 83,134, 18, 48,148, -175, 80,235,233,224,169, 47,186,189, 37,103,118,118,118,130,109,201, 89,235,127,143,150,155,117, 36,127, 91,187,111,233, 70, 59, -141,125,215, 83,153,173, 33,175,165, 91, 6,123, 18, 45,185, 29,228,191,107,215, 46,249,196,137, 19,239,117,227,204,182, 15,251, -109, 77,165,191,247,214, 75,140,159, 32,144, 49,136,133,156,161, 86,199,175,211,169,216, 15, 63, 93,209, 42, 59, 12,222, 98, 0, -180, 38, 65,120, 42,203, 93,121,132, 16,198,106,133,233, 40,165,220,221, 86,190,214, 34,216,214, 48, 0,108, 74,221,190,172,132, - 16, 3,165, 84,212,146, 72, 1, 33,132, 2,192,242,229,203, 27,236, 24, 54,103,206, 28, 57, 33, 4,148, 82,226,174, 82, 2, 0, -238,251,224, 6,231,153,105, 89,242,172,172, 44,183, 21, 96,107,202,187, 23,162, 40,148, 82,154,216, 37,134, 38,118,137, 1, 0, -148, 27,217, 25,109,132,252, 13,182,207, 47,168,234, 68,101, 46,108,156, 2, 0,199,182,124, 86,192,113,136,186,111, 68, 88,192, -135,175,140,220,219,175, 95,208,181, 89,139,135,254, 23, 0,110, 42,181,255, 39,224,147, 31, 1,114, 46, 45, 45,173,183,187,207, -198,113, 41,218,150, 44, 55,107, 79,254,173, 97, 4, 52,245, 29, 79,201,178, 53,228,165,164,164, 32, 35, 35,195,165,123,114, 39, -162,210,156,188,214,138,204,216,147, 63,199,113, 88,179,102, 13, 54,108,216, 64,103,204,152, 65,220,172, 99,161, 76, 38,107,149, -245,178,231,207,159,159,150,158,158,238,105,135, 14,176,122,254,154,219,209,135,215,175, 92,197, 60, 30, 21, 35,126, 41,249, 73, - 97, 68,207, 40, 62,159, 68, 48, 90,165,146, 21, 35,210,200,180,107,111,212,223,184,106,108,233,111,240, 93, 81,110, 82,169, 52, - 28,192, 96, 0,199,101, 50, 89,229, 93,230,233, 4, 0, 72, 2, 48, 25,192, 54, 66, 72, 54,165, 84,213, 10,114,191,163,148, 62, -234, 41,193,222, 45, 96, 24,166, 89, 35,133, 16, 50, 20,128,144, 16, 18, 65, 41,173,104,234,186,230, 12, 20, 66, 8,125,249,229, -151,209,177, 99,199, 91,182, 11, 93,190,124,121, 98,113,113,177,156, 16, 66, 93, 53, 2,164, 82, 41, 93,247,162, 47,158, 28,121, -235,230, 50,220,247,193, 88,255,139, 17, 79,187,233, 53,181,166, 60,165, 82,153,240,230,155,111,202, 83, 83, 83,145,152,104, 89, -217,238,244,233,211, 9,171, 86,173,146,119,236,216, 17, 28,199, 65,167,211, 33, 33, 33, 1, 99,199,142,117, 42, 83,168,212, 36, -116,127,115,179, 60, 43,174,125, 98,155,231,198,228, 0, 0, 91,206, 38, 92,124,151,149,155, 59, 6, 64,197,249, 66,161, 11, 64, - 69,224,177,196,103,231, 69, 56,245,142,187,116,104,211,166,163, 80, 82,246,226,172, 39, 12,145, 18,161, 80, 85,163, 35, 75,190, -218,184,225,173,231, 31, 71,176, 68, 66,245, 38, 51,253,247,138,175, 12, 0, 72,219,182, 97,252,242,242,106,102,192,128,198,119, -214, 28, 18,177, 55,246, 70,148, 79, 80,252,125,225,203, 7, 14, 10, 17,172, 91,119, 57, 58, 60, 76, 82,245,209, 43, 71,150, 23, - 93, 27,104, 30,247, 96,219,188,130, 75,234,226,167,159,236, 50,222,214,110,220,233, 3,246, 27,228,180,196, 11,117, 36,127,199, -254,233,137,252,187, 49, 2, 96, 37, 98,106, 51, 2, 82, 82, 82,236,207, 55, 32,109,251,141,125, 60, 53, 42,108,114, 50, 50, 50, - 90, 28, 37,176, 39,255, 57,115,230,224,248,241,227,244,151, 95,126,193,140, 25, 51,220, 21,101,148, 74,165, 2,153, 76,198,182, -130,138, 44,159, 63,127,254,228,244,244,244,109, 30,124, 55, 10, 64, 13,128,104, 0,167,115,115,115, 59, 1,248, 28, 64,136,189, -124, 0,159,198,199,199,187,188,231,130,142,211,241,141, 85, 6,159,113, 19, 39, 7, 42, 96, 10, 20, 8,248, 34,149, 94,204, 23, - 10,117, 44, 47,192,215, 96,148,152,116,252,242, 27,106, 49, 79, 84,171, 55, 27,140, 82,169,180,201,254,219,226, 8, 0, 33,164, - 3,128,255, 1, 40, 5,240,178, 84, 42,125,142, 82,122,253, 78,121,176, 78, 72, 58, 20,192,122, 0, 55, 0, 28, 6,240, 16,128, -103, 9, 33, 79, 82, 74,171, 91, 40,126, 26, 33,100,134,179,124,233,157, 12,177,223, 38, 12, 7,112, 17, 64, 12,128, 10, 98,101, -106, 87, 13,154,177, 99,199, 38, 0,104, 64,254,115,230,204,145,219, 71, 3,172,159,201,199,142, 29,155,224, 44, 29,144,153,153, -153, 0,160, 1, 89, 51,211, 20,176,247,222,159, 28, 41,196,211,159,105,144,153,153,153,224, 44,124,223,218,242, 0,224,200,145, - 35,114,177, 88,140,188,188,188, 6,251, 29, 48, 12,131,183,223,126,155,216,148,221,206,157, 59,229, 99,199,142,117, 90, 1,109, -142,156,147, 83,177, 0,253, 42,133,242,138, 63,182, 98, 5, 97, 40,250,189,109, 36,128, 17,103, 15, 94, 75,184,177,101,130, 28, - 56,218,172, 18, 78,236, 18, 67, 59, 10, 37,120,237,133, 25,134, 72, 63,161,176,234,108, 46,241,101,248,120,105, 84, 44,218, 5, - 73,112, 45,239, 16,209, 25, 41,153,147,246,132, 49,177, 75, 12,237,225,227,143, 50, 90, 69, 6, 14, 28,216,168,188,176, 48,225, -253, 66, 33, 35, 62,124,184,236,101,214,172,255, 56,178,125,103, 83, 80,152,128,168, 84,151,125, 58,199,248,132,133,132,136, 42, - 57,170, 50,252,116,180, 66, 51,115,212,159,211,128, 29,195,254,246,125,211, 93, 35,192,118,141,253, 56, 2,103,215, 57,219,126, -187, 53,229,217, 27, 1, 50,153, 2,128, 2, 82,105, 48, 26, 35,109, 87,209,148, 81, 97,141,200,180, 40,234, 97, 79,254, 59,119, -238,148, 51, 12, 3,134, 97, 48,106,212, 40, 28, 58,116,168, 65,125,185, 10,179,217,156,207,227,241, 76, 82,169,148, 47,147,201, - 90, 58,158, 69, 82, 93, 93,253,125,104,104,232,212,244,244,244, 45,110,126, 87, 7,203,126, 49,234,220,220,220, 62, 0,182,236, -219,183,175, 27,199,113,246, 28, 5, 30,143,247, 8,128,156,248,248,248, 68,103, 2, 11,174, 20,136, 37, 66,113,160, 64, 32, 10, -103,248,164, 45,229,137,130, 56, 30, 79,196, 17, 6, 28,225,155, 40,143, 87,199,227,136, 90,195, 51,215,248, 10, 5,132,215,165, -131, 82, 60, 49,130, 69,241,237,139, 0,124, 12, 96,159,213,178,121, 1,192,199,107,214,172,153,234, 33, 97, 7, 3,120, 25,192, - 16, 0,227, 1,236, 2,112, 12,192, 39,148, 82,133, 7, 34, 15, 90,203,181,138, 82,202, 17, 66,124, 1, 60,101, 61,223,187, 5, -134, 69,160,245,173, 47, 0,149, 59, 30,118, 19, 17, 20, 33,128,183, 0, 44,146,201,100, 70,220, 93, 24, 2, 32, 23, 64, 27, 66, -200, 38,107,157,124,227,104,208, 52,101,160,100,101,101,201,237,195,254,115,230,204,169, 63,182,127,191,124,249,242, 68,171, 97, -208,108,143,207,202,202,146,219,135,233,153,105, 10, 92,218,101,217,133,145, 25,255, 77, 61,105,115,223, 7,131,153,150, 37,119, -182,161, 79, 99,242,108,202,140,153, 38,165,238,202,163,148, 38, 28, 62,124, 24, 51,102,204,192, 23, 95,124,129,147, 39, 79, 38, -196,197,197,229, 56, 94, 35, 22,139,229,109,219,182,117, 37, 86,159,208,246,240,111,184, 56, 35, 1,126, 95,156, 5, 41,211, 38, -208,182, 62, 86,121,196,122, 9, 18, 4,250,142,242,144,182,205,111,101,155,216, 37,134,166,253,107,154, 49,210, 87, 40, 48, 93, - 62, 46, 12, 14,247, 39,242, 50, 21,166, 14,232,128, 30, 81, 65, 16,214, 94,132, 92,173, 67, 7,129, 8, 65,132, 39,152,255,236, - 12, 90, 39, 20, 21, 36,118,137,161, 8, 8,106, 84,166,162, 86, 29, 50,116,168,223,114, 21, 59,108,158,127,112,165, 72,207,248, -114, 18, 63,163, 33, 36, 44,148,241, 9, 18,243, 21, 53,101, 34,149,146,133, 64,105, 32,246,109,166, 57,131,214,154,247,151, 59, - 35,206,148,148,148, 68,103,227, 1, 26,243,252, 29, 13, 1,119,140, 0,219,103,205,145,177,253,121,103,196,232, 40,143,110, 14, -190, 85,223,164, 42,224,170,188,230,194,253, 45, 33,109, 71,163, 2, 0, 66, 66,178, 91,133,252,103,206,156,105, 73,191,113, 28, - 94,127,253,117,124,252,241,199,245,228,191,106,213, 42,183,101, 51, 12, 3,163,209,120, 74, 40, 20,178,173, 16, 9,168, 1,128, -234,234,234, 45,161,161,161,137,233,233,233,114, 55,190,203, 7,128,167,159,126, 90,148,155,155,155,149,157,157,221,102,225,194, -133,236, 59,239,188,211,128, 87, 67, 67, 67,177,127,255,254, 4, 0, 25,241,241,241, 41,205, 9,228, 17, 65,128,145,165,237, 56, -206, 20, 35,228,241, 58, 81, 66, 34, 8,159, 79,248, 60,158,146, 16,162, 3,225,169, 56,138, 96,106,228,124, 84,102, 19,186, 4, -176, 58,102,168,154,107, 53, 3,192, 33, 55, 28, 5,160, 3,165,212, 70,248, 75, 9, 33, 71,165, 82,105, 20,165,180,212, 29, 15, -150, 16,242,132,149,172, 63, 4, 48, 15,192,227,214, 16, 74, 10,128, 98, 66,200, 11,148,210,111,220, 32,233,255, 0,184, 76, 41, - 93, 73, 8, 17, 89, 59, 60, 75, 41,253,156, 16,242, 32, 33,228, 63,148,210,255,231, 97,163, 24, 13,160, 18,192,253, 0,126,116, -231,139,141, 69, 0,164, 82,233, 51, 0,222, 5, 80,158,150,150,182,250, 46,139, 0,244,182,150,109, 12,128,113, 0,174, 57, 51, -104,154,130, 61,225,219,147,190,227,184, 0,151, 59,186, 29,249, 3,192,165, 93, 79, 52, 48, 2, 60,145,103,175,204,100, 50, 25, -177, 55, 2, 92,193,129, 3, 7, 96, 52, 26, 49,104,208,160,196, 95,126,249, 69, 94, 84, 84, 36,143,139,179,108,169,203,113, 28, -210,211,211,105, 93, 93, 29, 4, 2, 1,166, 76,153,226,244,190,245,121,199,192, 24, 89,212, 14,138, 78, 20,252,114, 67,126,121, -237, 1,116,121,107,156,133,180, 56,138,252,116, 33,173,169,243,135, 78,224,135, 49, 51, 47, 57,127,142, 12,175,174,242,108, 94, -160,222, 96,102, 2, 37, 34,154, 60,160, 35, 2, 36, 2, 82, 82, 93, 7, 95,134,143,212,129, 29,233,145,223, 43,240,235,143,123, -208,201,215,143,158, 81,171,174, 1,232,222,148,184,188, 83,237,102, 13, 31, 88,117,192,143, 31,195, 10,217,155, 93, 70,143, 72, -245,211, 27,125, 39,240,252,142, 49,170,218, 26,159,162,243,199, 98, 76,198,243,149, 87, 10, 53, 1,214, 62,227,148,168, 92,245, - 78,109,227, 3,154,202, 63, 55,229, 77, 59,243, 42,165, 82, 41,245, 52,100,122, 55,193,209,243,183,144, 55,144,145,209,122,131, - 4, 91,195,243,167,148,130,101,255,224,232,145, 35, 71,226,208,161, 67, 30,145,191, 21, 38,129, 64, 96,230, 56,238, 48,195, 48, -166, 22, 26, 1, 17,182, 55,213,213,213,242,208,208, 80,105,122,122,186,171, 59,103, 21,165,166,166, 6, 28, 56,112, 32, 61, 59, - 59,187,205,215, 95,127,205, 61,245,212, 83,252,141, 27, 55,226,189,247,222, 67, 65, 65, 1, 58,117,234,132,242,242,114, 44, 88, -176,192,252,238,187,239, 38, 3,120, 33, 62, 62,254,243, 38, 37,114,108,160, 25, 76, 39,194,161,183, 9, 92,172,143, 64, 36, 20, -242,153, 50,177,128,167,226, 73,132, 85, 34, 17,175,206, 96,230,124,248, 38,126,136,145, 53,152,175,158, 60,165,120, 34,252, 99, -237, 17,120,198, 31,206, 34, 0, 15, 2,200,117, 24, 56,150, 11,224,193, 53,107,214,124,229, 6, 89, 63, 6,224, 21, 0,209, 14, -161,121, 5,128,223, 8, 33,159, 2,216, 75, 8, 49, 83, 74, 55,186, 32,207, 7, 64,154,255, 11,176, 0, 0, 32, 0, 73, 68, 65, - 84,154,205,203,167,148, 26, 28, 46,121, 18,192,239,132,144,101,148, 82,173, 39,225,127, 0, 95, 89,255,187,101, 0, 56, 18,166, - 84, 42,253, 39,128, 89,214,103,185,156, 16, 98,144,201,100,107,239, 6, 5, 66, 8,233,106, 13, 97,253, 4, 96, 59, 0, 91, 61, -193,213, 8,192,223, 13,165,165,165,242, 97,195,134,129, 16,146, 51,108,216, 48,252,240,195, 15,120,228,145, 71, 18,218,180,105, - 35,103, 24, 6,243,231,207, 39, 86,101,146,176,105,211, 38,185,193, 96,192,144, 33, 67,154, 84,116, 35,174,222,144,151, 15,235, - 9, 16,146,243,123,164, 57,177,247,233, 16,185,158, 67,162, 37, 5, 0,244,155,111, 36, 64, 53, 52,213,202,132,253,155,186,202, - 53,254, 71, 19, 31,125, 42,160, 81,175,184,196,200, 46, 91,179,102,227,235,225, 97,146, 34,165,198, 24, 24, 29,236, 43, 72,233, -223,217,103, 96,180,136,232,181,102,104,117, 28, 46, 19,157,121,123, 81,169,182,176,188,206,220, 70, 40, 46, 43, 55,234,199, 94, - 55,152, 62,244, 7, 94,107, 76,102, 64,112, 84,123, 93,221,165,118,189,146, 30, 96,206, 29, 41, 27, 93,122,225,135,235, 93, 7, -167, 69,240,122, 14, 40, 57,117,232,123, 37,225, 5, 12,225, 56,174,230,230, 77,157, 83, 43,202,145,176,157, 29,219,188,217,140, -140,140, 38, 9,219, 62,188,238, 24, 9,112,229,250,123, 21, 73, 73, 73,196,222,235,183,135,125, 8,191, 37,104, 13, 57,117,117, -117,114, 0,224,243,249,120,245,213, 87,113,252,248,113,252,242,203, 47, 45, 21,107, 0, 96, 54, 24, 12,108,105,105,105, 86, 84, - 84,148,201, 89,100,177, 25,168,237, 15,170,171,171,101,161,161,161, 15,167,167,167,187,162,247, 3,245,122,125,183,185,115,231, - 78,156, 57,115, 38,237,219,183, 47, 1, 80, 79,254, 0, 48,124,248,112,108,221,186, 21, 35, 71,142,100, 30,123,236, 49,154,147, -147,179,146,199,227,233,124,124,124,160,213,222, 74, 77, 28, 71,245, 57,242,125,153, 93,187,198, 22,199,116,138,190,196,243,151, -148,241,136, 80,201,136, 4, 74, 70,236, 83, 97,228,243,180,160, 38, 1, 39, 54, 69,168, 75,171,195,142,238, 63,253,118, 88,112, -228, 59,158, 62,200,102, 35, 0, 82,169,116, 44,128, 13, 14, 94,237,126, 0, 51,210,210,210,190,114,197,131, 37,132,240,172,225, -239, 73, 77,229,229, 41,165,213,132,144, 84, 0,219, 9, 33,223,187, 48, 79,249, 49, 0,123, 41,165,202, 38,228, 41, 9, 33,123, -173,215,125,225, 38, 41, 62, 0, 32, 20,192,108, 0,155, 8, 33, 15, 80, 74,247,123, 18, 1, 32,132, 36, 3, 88, 10,160, 19,165, - 84, 67, 8, 25, 14,224,154, 84, 42, 85, 83, 74, 51, 93,141, 0, 72, 45,166,190, 43, 74,139,200,108,110,128,107, 24, 1,224, 40, -165,148, 18,139,219,116, 13,128,134, 16,210,193, 54,206,195,157, 8,128,163,199,223, 18,239,191, 62, 44, 63,254,155,250, 40, 64, -108, 11,188,255, 63,194,252,127,132,111,165, 82,247,188,127,147,201, 68,143, 31, 63, 14,127,127,127,228,231,231, 83,179,217, 12, -149, 74,133,243,231,207,203, 67, 67, 67,225, 16,246,203,233,213,171, 87,226,230,205,155,229, 67,134, 12,105, 60,220,103, 50,209, - 14,199,207, 66,232, 31, 5, 65,126, 53,141, 52,251, 67,173, 98, 96, 62, 95, 7,132, 54,220,145,218, 55,148,205,233, 56,248, 68, -226,158, 45,211,228,192,238, 70,149,221,165,235,215,223,136,237,208, 1,168,210,189, 14, 0, 5, 58, 21,118,138, 74, 43,123,221, - 63, 58,188,151, 49, 31,191, 93, 83, 96,231,233,155,252,194,202,186, 0, 0, 40, 55,234,131,175, 27, 76, 41,133,165,165, 91, 7, -132,135, 55,106, 0,220, 63, 33,149,241, 17,142,237,203,106,126, 43,238,216, 51,169,155,242,250, 22,227,229,223,178,106, 77,156, -223,205,138,226, 95, 43, 84, 53,190, 67,192, 48,164, 70,173, 15,148, 78,139,235, 32,251,254,228,245,166,218,140, 76, 38, 35,246, - 17, 0,123,239,210, 49,220,110, 35,233,148,148, 20, 36, 37, 37,145,198, 22, 58,105,201,104,124, 79, 23, 78,185,219, 96,235,238, - 82,105,240, 45, 17, 1, 79,163, 10, 25, 25, 25,173, 66,254, 27, 54,108,160, 7, 15, 30, 4,221, 28, 12,146,170,192, 71, 31,125, - 4, 74, 41, 24,134,193,234,213,171, 61,142, 44, 40, 20, 10, 67, 72, 72, 72,226,193,131, 7,119,143, 30, 61,122, 92, 99,237,199, - 13, 4, 89,251,107, 90,117,117,245,154,208,208,208, 39, 0,212,204,159, 63,255,159,233,233,233,206, 28, 53,229,142, 29, 59, 74, -247,236,217,243, 85, 98, 98,226, 51, 61,122,244, 64, 82, 82, 18,205,206,206,174, 47,199,246,237,219, 33, 18,137,112,237,218, 53, -236,222,189,155,180,107,215,142,141,143,143,255,229,252,249,243,141, 10,140,141,233, 86,166,211,233,211, 14, 30, 60,184, 38, 52, - 44, 84, 21, 24, 16, 80, 12,161,208,192, 26,152, 58,150,103,168,213,243, 85, 85,190, 6, 95,241,141,138,202,192,253,123,118,175, -233,213,187,207, 82,163, 94, 91,215, 42, 6,128, 84, 42, 37, 82,169,212, 86,248, 54,214,215, 1,235, 52,187,250, 40, 40,128, 57, -132,144,118,176,140,112, 4,128, 70, 45,116, 43,169,188, 4,203, 0,189,171, 14,114, 28,113,213,122,221, 75,132,144,143,155,145, - 71, 0, 76, 1,176,216,137,188,175, 1,204, 35,132,124,229,164,124,246,141, 38, 26,150,241, 14,131, 96,201,253,191, 13,224, 4, - 33,164, 11,128, 34,123, 27,195, 5,121,143, 2,120,214, 74,178, 58,107, 89,117,214,227,213,132, 16, 33,128,239,154,147,103,173, -139, 39, 0,204,116,213, 0,144, 74,165,171, 0,124,211,148, 60,171,204,101, 0,252, 1, 4, 2,216, 97, 45,155, 24,150,121,226, -191, 1, 24, 70, 8,153, 13,224, 23, 0, 59,155, 42, 31, 96,153, 71,223, 68,174, 31,142, 99, 3,198,140, 25,227,212, 24, 24, 51, -102, 76, 34, 51,237,143,188,189,205, 8,176,189,183, 15,231,123, 44,111,218,173, 83, 2, 93,145,119,250,244,105,116,236,216, 17, -175,190,250,106,125,155, 89,191,126, 61,205,203,203,195,132, 9, 19,110,185,222,199,199, 71, 46, 22,139,155,148, 23,125,250, 52, -106, 59,182,197,145, 87,159,169,151,119,241,141,173, 9, 49,121, 74, 57, 51, 65,124, 75, 89,138, 11,140, 16,137,155,159,253,116, -185,164,100, 46,218,183,255, 21,192,112, 10,202,195,213,202, 87,181, 44, 11, 86,111, 9,146,157,171,172,196, 85,189,113, 61,159, - 16, 53, 8, 49, 93, 46, 41,201, 4,128,166, 6, 1,182,139,238, 49, 23,192,146,130, 67, 47, 23,137, 35,167, 40, 74,203,197,237, -203, 75,142,137, 33, 8,233, 90,116,205, 28, 85, 93,126, 29, 66,161, 32,162,119,164,239, 99,181,106,211,183, 0,174, 59,243, 92, - 1, 36, 56, 78,255,107,194, 3, 77,244,100, 77,128,198,242,255,127, 7,180,116,170,158,237,251, 25, 25, 25,180,165,242, 54,110, -220, 64,115,114,114, 64, 50, 45,134,241,222,119,252, 49,118,161, 26,163, 71,143,134, 59,211,254, 26, 67, 72, 72, 72, 34, 0,220, -119,223,125,218, 86, 72, 83, 40, 66, 67, 67,103, 0,176, 57,167,134,244,244,244,157, 46,126,151, 5, 80,177,125,251,118,249, 35, -143, 60, 50, 56, 61, 61,189,159,217,108, 38, 18,137, 4, 99,198,140,193,207, 63,255, 12,142,227, 48,126,252,120,250,242,203, 47, -147, 1, 3, 6, 24,166, 76,153,210,169,166,166,230,166, 94,175,111,138,145,217,223,207, 95, 90,223,167,111,191,192, 99, 71,143, - 46, 61,197,231,247,233,220,169,243,151, 1,161,225, 37,130,112, 49, 61,176,123,127,112,141,162,122, 84, 84, 72,248,187,221,186, -117, 59,224, 23,233,187,170,103,251, 65,198,252,252,252, 86,137, 0,240, 96,153,238, 23, 15,224,125, 0, 47, 90,137,199,215,190, - 63,193, 50, 72,236, 50,128,127, 91, 83, 2,199,155,144,207,192, 50,200,108, 47, 0, 31, 23,202,115, 24,192, 88, 52,189,176, 2, - 3, 32, 28, 64, 39, 0, 39,156,200, 60, 97,189, 46, 2, 77,231, 38, 25, 88,150,113, 12,182,166, 13, 30,177, 18,119,129, 85,118, -129,245,120, 35,128, 31, 96,153,113,160, 0, 96,116, 34,111,154, 53,242,208,195,106, 36,217,151,179, 12,128, 20,192, 5,235,181, -223, 59,145,247, 10, 44,179, 27, 92, 73,101,248, 0,216, 3, 96,131,147,250,152, 10,224,191,214,255,167,236,202, 39,176,214,101, - 6,128,207, 0, 44,180,126, 94,214,212, 15,238,221,187, 55,135, 16,130,226,226, 98,185,109, 38,128,163,215, 95, 92, 92, 44,183, - 93,235,236, 6,146,147,147,115,178,178,178,176,254, 23, 99,253,200,125, 71, 47,125,253, 47,198,250,107,239,164,188,188,188, 60, -140, 26,213,112,168,123,116,116,116,226,230,205,155,229,157, 59,119, 78,228, 56, 78,190,104,209, 34,106,155, 6, 72, 8,193,224, -193,131,155, 52, 42,186,231,229,225,187,208,136,196, 0,187,115, 61,103,143,133,102,233,117,224, 31, 17,160, 28,144,191, 72, 64, -235, 56, 63,212,232, 2,160, 32, 3,209,127,212,142,196,230,154,189,117, 6,199, 22, 0, 91,186,118,138,234, 14,224, 85,131,153, - 67,102,126, 17, 70, 69, 90,210,157,132, 82,181,154,101,223,191,121,243,230, 77, 23,218,212, 82, 0,190, 5, 23,106, 30,175, 61, -177, 57,172,162,172, 6, 21, 55,213,224,243,171,125,235, 20, 20,181, 42, 51,141, 8, 23, 6,241, 57, 76,214, 25,204,223, 45,124, - 53, 62, 40,162,231, 83,181, 78,136, 38,199, 25,185,180, 56,135,157,180,217,242, 63, 59,213, 77, 15,248,246,206, 2, 32,169, 10, -180, 68, 94, 83, 30,251,160, 65,131,238, 26, 67,164,126,176,163,141,252,243, 89,172,149, 91,250, 88, 75,201,223,214, 54, 94,120, -225,133,112, 62,159, 95,113,248,240,225, 47,239,187,239,190,150, 76, 81,236,152,158,158,190,210, 26, 5,152,102,157, 17, 48, 45, - 61, 61,253,123, 87,130,138, 0,234, 0, 84, 69, 71, 71,247, 31, 57,114,100,233,233,252,252,182, 58,157,142,200,229,251, 33, 18, -139,192, 16, 6,251,247,239, 39,189,122,245,210,166,164,164, 12,171,172,172,116,218,231,166, 79,155,202,254,180,251,167,207,250, -247, 31,216,217,200, 26,198, 93, 46,184,244, 44, 87, 84,248, 12, 0,136,193,208,190, 93,187, 31,139,136, 8,207,225,241,133,111, -252,247,157,197,117,223,174,243, 60,163,220,152, 1,240,170,213, 26,154, 0,224, 60, 0,191, 70,190,183,203,234,177, 39, 3, 24, -106, 37,207, 70,163,156, 0, 98, 1,108,114,209, 0,168,182, 94,207,107, 70, 94, 2,128, 75, 46,202,187,100,189,126,107, 51,242, -210, 0, 60, 13,224, 44, 44, 51, 20,174, 58,200,150, 91,189,255, 89, 86,111,120, 29,208,228,136, 11,158,213, 99,127, 18,192, 0, -107, 20,161,177,114,170,172,159,175,182, 26, 1,235,154,145,247,181,213,232,114,229,126,169,245,250,230,158,223,135,214,200,198, - 94,171, 81, 3, 7,217, 63, 3,232,101,173,139, 2,171, 33,213,161,217, 31,181,100, 16, 40, 0,121, 99, 11, 1,217,174,113,167, -131, 63, 45,149,210,167, 63,211, 52,178,112,143,194,109,130,104, 45,121, 47,189,244,210, 45,215,140, 30, 61, 58,103,244,232,209, - 4, 0, 30,120,224, 1,183,148,208,174,151, 94, 34, 1,142, 26,165,147, 95,142,100, 69, 79, 2, 0,189,101, 2, 98, 9,202,216, - 70,102, 95,115,177, 25, 88,235,197, 76,139,192, 7,120,117,168, 39,127,171,139,124, 83, 44, 22,187, 58, 27,133, 0,120,239, 80, -246, 41,159,200,246,157, 30,230,224, 19, 91, 82, 92,206, 51,233,107,105,155, 8, 63,226,231, 43, 32,172,137,131,162,214,200, 18, - 9,145, 40,213,108,215,136,166, 29,130, 70,201,194,241,253,159,185,124,239,237,158, 5,208, 82,121, 77,121,236,157, 59,119,190, -107,200,159,251, 62, 24,123,243, 45, 99,242,214,201,141,248,238,176, 17,148,210, 86,169, 87,155, 12,179,217, 92, 13, 0,113,113, -113, 45, 90, 16,200, 70,254, 86, 84, 89,255,187,218, 55,132, 86,199,236, 36, 0,244,238,221, 59, 74,173, 82,207, 27, 50,104,240, - 19,106,149, 42,144, 53,179,166,200,200,200,155, 81, 81, 81,151, 84, 42,213,194,202,202,202, 2, 87,203, 53, 97,220, 4, 22,192, -139,135, 14, 30, 29, 25, 63,114,228, 4,137, 68, 18, 70, 64,205,132, 16,112, 28,173,214,105, 20, 43, 47,230, 23,151,125,187,110, -109,139, 86, 4,116, 52, 0,204, 0,254,217, 12,129,216,227,152,245,101,182,190, 26,131, 25,150, 17,245, 60, 23,203, 35, 7,144, -237, 68,222,118, 88, 6,173,185,130,199, 93, 40,223, 26, 0, 95, 58,145,243, 59, 44, 83, 32,225,130,188,111,172, 17, 3,103, 40, -178,122,246,174,148,143,231, 70,157,174,113, 34,239, 31, 46,200,179, 69, 27,214, 89,159,141,211,185,182,148, 82, 50,118,236,216, - 4, 27,225,219,135,224, 61, 89, 10, 88, 38,147,145,204,204,204, 4,102, 90,235, 44,221,219,218,242,238, 5, 20,150,220, 48,196, -118,232,176,110,230,210,213, 79,219,206, 25, 5,204, 6,189,150,219, 83, 94, 92,172,118,169, 49,173, 89, 67,171, 78,172, 37,139, -191,255,109,238,206, 21, 15,108, 59,114,180,236,249,240, 64,110, 34, 19, 18, 16, 68, 41, 64, 8, 53, 24, 88,174,156, 3,170,140, - 6, 46,168,180, 76,103,140,117,163,140, 41, 41, 41,137,246,233,128,148,148,148,196,187,229,249,221,141, 43, 1,222, 43,120,112, -161,250,182,222,163, 76, 38,227,164, 82,105, 91,177, 88, 92, 22, 23, 23,247,143,214,144,153,158,158,190, 47, 52, 52,244,233,244, -244,244,117,110, 24, 0,172, 53,114, 10, 0, 24, 62, 98,248, 98, 0,139, 29, 47,116, 28, 35,228, 42, 70,141, 30,250, 11, 44,169, - 88, 7, 68,161,107,183, 62, 45,190,231,198, 12, 0,189, 7,114,104, 51, 33, 18,131, 87,222, 95, 86, 94, 3, 88,137,190,213, 58, -122,114,114,114,142,179,121,249,127,166,188,123, 1, 53, 90,237, 51,128,143, 9, 64, 56, 7, 90,170,215, 27, 55,150,151, 87,158, -161,148,186, 60,109, 42,108,208, 63,233,246,143,198,145,155,190,143,230,181, 31,137,188,236,175, 62,124, 53, 36, 68, 52,143,207, - 35,180,172, 90,127,177,204,200,174,151, 8, 24,177,132,207,227,153, 88, 78,236, 78,249,108, 57,126,219,192, 51, 79,247, 1,184, -101,234,159, 93,232,223,147,197,102, 28, 61,115, 87,206,223,105,121,119,218,240,113, 21,204, 52, 5, 8, 33,152, 56,233,143, 1, -209,187,118,159,172,215, 33,227,199,197,181,214, 20,197,242,214,212, 55, 86, 35, 96,157, 27,151, 7, 91, 13, 0,205,189,170, 31, -248, 14, 15,148,186,170,236, 29,209,216, 40,118,175,188,191,182, 60, 47,238,126, 84, 87, 87, 83, 88,210, 92, 45,194, 77,223,201, - 20, 0, 14,109,248,132, 36, 61,243,218, 71, 79,166,229,127,246,226,244,195,189,140, 26, 18, 19, 34,224,135,129, 16,173,159,132, - 95,217,167, 71, 64,129,187,178,147,146,146, 72, 70, 70,134,199,235,205,223, 46,242,188, 87, 34, 0,119,159,241, 96,137, 13,253, - 13,186, 87,148,213, 97,246,199, 61,186, 27, 32, 25, 48, 96,192,223, 99,136,172, 23, 94,120, 1, 62, 15,240, 17, 17,112,156, 69, - 71,215,233,188,221,223, 11, 47,254,182,250,192,251, 8,188,240,226,239, 3,214, 12,168,180, 54,210,247,146,191, 23, 94,252,157, -193,120, 31,129, 23, 94,120,225,133, 23, 94,120, 13, 0, 47,188,240,194, 11, 47,188,240,194,107, 0,120,225,133, 23, 94,120,225, -133, 23,127, 69, 52, 24, 3, 48,115,230, 76,143, 71,110, 54,182,182,118, 99,242,126,252,254,127, 9,125,250,117,149,183,109, 31, -149,168,214,105,228, 7,228,121,137,201,211, 94,200,241, 84,222,138,175,182, 36, 12,232, 55, 76,126,179,180, 20,190, 18, 95, 92, - 47, 41, 76,124,238,153, 73, 30,203,107,237,251, 61,123, 96,102,194,240, 97,157,229, 18, 95, 30,248, 60, 6, 68, 76, 80,166,122, -153,120, 42,239,228,205,126, 9, 67,134, 13,145, 7,250,241, 0, 62, 80,115,122, 13,113,181,124,177, 15,198,122,124,191,151,126, -190,116,139,188,161, 67,135,122, 44,239,232,209,163,183,202,139,245,188,124, 71, 47,221, 90,190, 97,221,186,121, 44,239, 72, 65, -193, 61, 39,239,193,102,234,119,241,226, 12, 58,111, 94, 74,147,159,255,220, 72,253,198, 62,244,160,231,237,101,207,207,183,182, -231, 7, 61,111, 47,139,179,170,105, 0, 87,216,224, 92, 88,236,163, 30,203,171,186,244,221, 45,229, 59,245,214, 53,143, 21,233, -192, 69,157,110, 57,247, 81, 88,169,199,242, 94,173,138,194,159,161,175,254,238,242,164, 82, 41,191,177,157, 5,239,197,251,117, -219, 0,104, 10,250, 77,210, 88, 0,157, 97, 89, 39,160, 80, 60, 93,118,213,213, 31,216,242,205,226, 4, 2, 14,225, 65, 33,200, - 59,112, 82,254,245,215,159, 32, 62, 41, 30,172, 70, 43,239,213, 99, 52, 56, 14,242,223, 99,190, 78, 28, 56,176, 31, 46, 95,190, - 6,101,173, 6,125, 71,204,200,105, 74,222,154,111,229, 9, 20, 4,157,186,118,150, 75, 95, 91,136,234, 79,183,224,155,255,125, - 14, 64,140, 93,103, 74,192, 48,144,127,242,222, 59, 40, 40,184,136,232,232, 78, 16, 73,248,184, 81, 82,208,228,226, 34, 87,182, -126, 78,133, 66, 33, 36, 18, 9, 10, 11, 11,209, 46, 34, 0, 97,124, 63,180,235, 24,132, 96, 73, 32,124,137, 25, 12,195,128,114, -102,104, 69,124, 40,111, 42, 81, 49,216,249, 92,114,101,225, 74,234, 47, 81, 98,196,144, 46,240,243,229, 67, 40, 97,192,231, 1, -140,144,143,238, 81,255,163, 38,202,195,149, 27,207,184, 92,225, 43,118,235, 19,162,162,162, 16,127, 95,123,185, 78,111, 0, 35, -146, 0, 38, 32,191, 46, 46, 65,167,213, 96, 88,196,197,156, 63,203,138, 92,179,102, 13, 77, 75, 75,251, 91,205,175,191, 91,225, -140,232, 91,120,189, 47,128, 33,109, 36, 62,255, 45, 45, 45,237, 33, 16,139,192,249,248,124, 0,203,202,152,117,119,203, 51, 40, -252,125,119,194,213,115, 7,110,217,107, 32, 41,229,131,191, 74, 27, 37,223,172, 95,127, 65, 36, 20, 74, 56,142, 11,244,245,243, -243,123,120,226, 68, 31, 88, 86,176,187, 91, 71,118,218,162,205, 92, 75, 5, 73,165,210,128,192,192,192, 57,221,187,119,159, 34, - 18,137,218,151,148,148,148,148,150,150, 30, 53, 26,141,139,100, 50, 89,161, 7,242,130,130,131,131, 23, 62,240,192, 3,227, 94, -120,225,133,232, 47,190,248,226,230,217,179,103, 15,235,245,250, 5, 50,153,236,236,223, 38, 2,208, 4,249,243,124, 69,252, 33, - 79,140,236,178,140,163, 84,127,232,226,205, 79,207,111,146,238, 21, 79,151,157,115,246,221,148,137, 93,233,196, 7, 22,195, 84, - 87, 11,190,153,193,111,231, 46,226,169,167, 94,254,163, 69, 48,192,175,121,235, 16,214, 49, 74,206,213,169, 96,228, 8,246,239, -207, 75, 44,209, 53, 85, 81,139, 40,132,129, 32, 62, 1, 56,121,174, 24,103,206,253, 19, 95,125,247,115,253,231, 28, 7, 60, 52, - 98, 4, 80, 87, 14,192, 31,133,103,207, 67, 16, 22,132,248,225,125,228,181,218,102,108, 22,194, 0,132,193,128,126,113,104,227, - 43, 68,187, 48, 49, 2, 66, 67, 16, 44,242, 71,176,152, 7, 1,143, 7,147,217,140, 90,150,195,177,170, 19, 78, 31,106,249,153, -133, 52, 36, 16, 8,240,241, 65,120, 88, 40, 2, 2,124, 64, 25, 51, 88,174, 14,102,152,225,231,231,131,176, 54,237,209, 57,246, - 23,154,125, 96,100,179, 74,105,117,150,145, 6,250,251,162,115, 76, 4,194,195, 66,161,209,104, 32, 20,137, 33,208, 91, 22,231, -139,137,238, 36,175, 81,212,226,251,188,162,196,226,146, 27, 80,148, 95,195,162, 23,226,154, 53, 6, 50, 22,103,184,172, 36,146, -158, 78, 74, 12,142, 12,206,105,142,252,239,132, 17,240,214,210,165, 20, 0, 22,189,241, 70,171,252,198,252, 37, 75, 40, 0,164, -207,157,235,177,188,159,114,115,159, 50, 26,141,235, 0, 96, 74, 98, 34,227,137,242,149,109,222,108, 89, 35,222,110,218, 52,165, - 20,132,144,250,255,182,115,182,235,210, 82,154, 38,236,121,243, 82,136,171,164,238, 38,249,247,242, 53,177, 91,252,131, 2,123, - 0,128, 80, 34,134, 81,167, 7,167,209, 46, 57,124,240,192,123,247, 79,157,218, 19, 64,177, 51, 33, 6,158,144,194,178,120, 10, -107, 37, 5,206,170,135, 26,213, 69,253,239, 31,135, 11,251,183,187, 85, 71, 87,207, 29,144,119,237,147,144, 24,221,243, 33,247, -141,226,148, 26,183, 46, 79, 77, 77,197,230,148,236,102,175, 73,204,110,184, 21, 73,175, 32,203,173, 86,232, 57,232, 88, 75,189, -106,172,255,101,195,130,208,205, 95,208,172,188,101,203,150,229,188,245,202,235, 17,147,166, 76,246,211,235,117,248,228,163, 15, -153, 21, 43, 86,232,103,207,158, 29, 5,224, 70,107,247,189, 61,123,246, 36,109,219,182, 45, 11,112,111,205,129,188,188, 60, 90, - 84, 84,132,234,234,106,168,213,106,248,251,251, 35, 52, 52, 20,209,209,209, 24, 49, 98,132, 71,253, 78, 42,149,142,142,139,139, - 91,255,218,107,175, 93,238,222,189,251,186,129, 3, 7,158,191,121,243,102,251,188,188,188,184,103,158,121,102,167, 84, 42, 93, - 34,147,201,190,114, 67, 94,226,148, 41, 83, 50, 22, 47, 94, 28,106, 50,153, 32,145, 72,224,235,235,219, 86,163,209, 76,157, 52, -105,210,195, 82,169,116,182, 76, 38,251,223,189, 72,238,167, 79,159,110,112,220,216,134,110,252, 38, 72,191, 3,128, 46,176, 44, - 25,107,214, 24,216,235,121,151, 42, 62, 30, 17, 27,241,242, 3,189,218,190,215, 38, 80,210, 78,190, 73,186, 9,192, 69,241,116, - 89,147,155,212, 24,234,106,208,166,235, 63,176,240,141, 41, 88, 39,251,163, 47, 30, 56,188, 26, 26,173, 1,227,147, 94,198,125, -241, 79,227,209,212, 7, 32,145,136, 96, 52,179, 80,107,141,242,110,195,187, 54,209, 56,174, 1, 70, 96,202,140, 85,120,238,181, -231,235,207, 62,116, 95, 2,196, 98, 17,126,216,255, 51,118,229,230, 97,253,218,207,161,215, 25, 32,228,241,225,231, 35,132,166, -186, 36,177,182, 4,141,238, 62, 70, 41, 5, 40,103,121, 49, 28, 40,165, 48, 24, 69, 22,245, 36, 2,168,209, 12, 51, 15, 48,195, - 12,179,145, 3,107,110,222,128, 45, 60,154, 78,219,135, 83, 4,248,251, 34,170,125, 12,122,244,237, 10,127, 63, 9,148,117,149, - 40,175, 44,135, 66,121, 19, 38, 61,129,143,143, 15,194,195,227, 49,117,242, 89,186,101, 91,247,198,195,248, 27,174, 83,179,191, - 63,116,124, 64, 40, 22, 66,167, 21,194,168, 21, 66, 47, 22,129, 79, 88, 80,240,160,215,213, 65,167, 85,163,125,251,118,114, 33, -143,143, 26,168,240,241,199, 7, 33, 18, 53,223, 56,150,174, 95,234,180, 1,189,241,228, 27,205,126,174, 80, 40,168,195,241,160, -144,144,144, 2, 66,136,158, 82,202, 15, 14, 14,246, 41, 44, 44, 12,205,200,200,200, 73, 75, 75,107,231,105, 67, 22, 70, 70, 78, -175,255, 13, 32, 33, 24,104,181,104,199,154,140, 12, 58,107,214,172, 68, 83, 69,133, 91, 50,127,202,205,149, 14, 29, 58,116,209, -200, 1, 3, 96, 18,137,176,124,249,114,110,234, 3, 15,140,161,148,102,187,229,202, 17,130,101,239,189, 87,127, 60,231,221,119, -177,124,193,130,102,143,157,193,209, 8, 88,188, 56,131, 14, 26, 52, 8,217,217, 87,104, 82, 82,231,222, 0,174, 44, 94,156,161, -115,147,252,243,250,246,238, 29, 96,235, 51,190, 98, 9,202, 42, 43,160, 82,212, 34,110,232, 48,159,159,190, 90,155, 61,225,153, -127,246,134,101,243,130,230,192,190,180,104, 5,255,241,169, 15,243, 99,163,163, 57,155,103,248,238,242,207, 26, 92,180, 96,206, -139, 22,195,239,149,217,137, 79, 78, 28,227,118,189,122, 68,254,245, 22,114,136, 27, 23, 39,185, 37,218,151, 79,112,102,193,179, - 32, 1, 97, 48, 95, 57, 3,195,149,223, 81, 80,163,193,224,221, 21, 46,125,127,181, 76,118,232, 53,233,172, 78, 79,254,235,153, -160,140, 13,223,113,209,209,209,204,194,197, 75,224,255,222, 66,252,240,195, 15,165,143, 60,242,136, 71,134,104, 19,196, 63,102, -219,182,109,123,109,199,147, 39, 79, 30,235,202,247,212,106,117,194,222,189,123,229, 38,147, 9, 93,186,116,193,168, 81,163, 16, - 24, 24,136,218,218, 90,220,184,113, 3, 87,175, 94,197,141, 27, 55,232,216,177, 99, 19,253,253,253, 93,174, 39,169, 84, 58,249, -129, 7, 30,248,100,217,178,101,155, 6, 14, 28,248,137,205,216,105,215,174, 29,166, 78,157, 74,146,147,147,253, 0,228, 73,165, -210,188,166,118, 47,117,148, 55,123,246,236,204, 89,179,102, 49, 39, 78,156, 0, 33, 4,161,161,161,245,175,221,187,119, 11,135, - 15, 31,254,185, 84, 42, 61,226,138,188,187,153,252,109,231, 28,239,131,223, 8,249,135, 14,142, 9,125,114, 64,167,144, 25,132, - 16, 1,165,212,196, 89, 94, 70,179, 73,175, 19, 50, 92,187,190,109,196,111,132, 5,116,233,186,237,216,213,239,244,155,164,135, -196,211,101,101,205,168,111,244,234,217, 29, 12,147,131,130,218,106, 0,231,161, 44,189, 4,129, 88,132,237, 59, 63,133,182,202, -140, 25,255,124, 21, 28, 7, 76,124,120, 4,204,124, 63,167, 55, 87, 80,112, 30, 28, 7,140,239, 79, 0,180, 3,208, 9,122,131, - 17,201, 15,141,133, 56,136,193,250,141,123,192, 48, 64,230,119,235, 80,122,229,247,196, 71, 18, 98,115, 46,158,106, 92, 22, 71, - 1,142,227,192,113, 28,204,102, 51, 12, 2, 10, 19, 49,193,104, 52, 66,235,163, 7, 56, 49, 24,106,134, 89, 72, 81,103,212, 67, -163, 82, 54, 91,182,112, 63, 3,248,124, 9, 66, 67, 67,209,181,107, 87, 68,182, 25, 6,240, 24,152,205, 39,192,208, 90,232, 53, - 44,204,156, 6,229, 55,106, 16, 30, 90,133,208,160,120, 40,212,243, 19, 26,219,228, 69,162,103, 65, 13, 85,128, 94, 4, 35, 99, -130, 70,200, 71,157, 68, 0,190, 64, 8,112,190, 32, 60,130, 58,141, 22,138,242,107, 40, 60,145,139,154,226, 98,112, 28, 7,134, -242, 60,106, 52, 95,173,250,195,112,126,102,230, 51,206,245,164,117, 95,119, 91,211,201,200,200,152,247,218,107,175, 61, 95, 92, - 92,204, 16, 66,194,101, 50,217,119,176,108,238,228,211,130,182, 44, 88,185,114,229,198,155, 55,111, 34, 51, 51, 19,131,187,119, -231, 5,247,237,219,226, 14,146, 62,119, 46, 81, 0, 9,148, 82,249,138, 21, 43,228, 0, 32, 77, 77,117,217, 43, 49, 26,141,171, - 71, 90, 59,147, 80, 40, 68,183,110,221,176,101,255,254, 44,107, 52,192,101, 57,183,107,171,218,121,243, 82, 72,118,246, 21,122, -226,132, 37, 98,101,247,255,247,251,239,191,191,116,222,188,148, 64, 87, 57,203,215,196,110,233,219,187,119, 0,143, 97,240,194, -227, 51,160,211, 27,176,252,203, 47,225, 35,145, 64,175,215, 67,175,211,161,255,192, 1,177, 63,111,216, 48,235,193, 25, 51, 62, -118, 22,117, 92, 48,231, 69, 14, 0,115,169,168,136,113, 36,124,199,238,233,201,189,119,232, 49, 58, 49, 59,227, 77, 58,102,226, -179,137, 84, 20,235,145, 33, 96,191,107, 31,221, 28,236,244,188, 83, 11, 42,136,143,107,117,102, 28, 24, 19, 14,193,203, 50,168, -102,196,128, 31, 28,225, 22,249,239,219,183,175, 60,186,109,187, 27,255,122,225,249, 14,111,190, 58, 23, 43,214,174, 62, 55, 52, - 46,174,243,234,207, 86,251,188, 50,247,117,108, 24, 49, 12, 27, 55,110,124,226,177,199, 30, 91,223, 66,226, 79,216,182,109, 91, -189,195,100, 13,171,191, 4,203, 86,233, 78,177,119,239, 94,121,120,120, 56, 6, 14, 28,200, 50, 12,195,183, 68,103, 57, 8, 4, - 2,132,132,132,160, 77,155, 54,184,122,245, 42,246,238,221, 43,159, 58,117,170, 75,125, 69, 42,149,166, 76,152, 48,225,195,101, -203,150,125,214,189,123,247, 85,132, 16, 14,192,231, 0, 30, 4,112, 16,192, 2, 74,105, 17, 33,228,117, 0, 11, 92,145,183,108, -246,236,239, 71,166,164,144, 29, 59,118,128,207,231, 67, 46,151,227,204,153, 51,232,218,181, 43,222,127,255,125,244,233,211, 7, -207, 63,255, 60,255,237,183,223, 94,118, 47,146,127,218,188, 15,254,112,116, 22,191,217,168, 17,208,216, 44, 0,134,207, 99,248, - 44, 71,213, 58, 19,123,131, 16, 34,242, 19,241,250, 5, 8, 49, 88,210,251,254, 46, 72,124, 14,232, 49, 10,109,125,233,228, 39, -226, 99,222, 12, 9,240, 25,163,223, 36,109, 70,153,112,224,241,108,132, 20, 0,160, 61, 2,163, 38, 64,103,214, 99,149,108, 45, -190,217,152,137,177,137,241, 0, 0,173, 22,224,241,155, 22, 37,241,233, 14, 0, 48,155,237,247,166, 41, 7,144, 7,134, 39,194, -147, 79, 61,139,228,212, 84,252,180,211, 66,100, 62,190,128,166,174,172,217,135,101, 2,175,158,252, 77,172, 25, 6,149, 9,218, - 90, 45,106, 77, 70,212,104,141, 80, 24,212,168, 85,215, 65, 81,161, 70, 77,173, 30, 53,117, 77, 47,161,126, 70,190,152, 18, 66, -192,227, 17, 16, 70, 4,179,153,130,213, 22, 67, 83,123, 9,165,229, 74,212, 40,234,160, 84,155, 81,163,208,163,164,164, 28,231, - 46,156, 70,173,242, 52,134,197, 13,106,114,111,116, 30, 0, 70,173,135,238,242, 13, 84,255,118, 30,213,197,215,160, 82,214, 64, -165,172,193,181,115, 39,112, 56,227, 43,228,109, 94,143,202,203,151, 97, 54,114,150,133,177,121,119, 38, 13,152,150,150, 70,172, - 97,127, 99,114,114,114,207,133, 11, 23,190,214,182,109, 91, 77,102,102,102,191,140,140,140, 31, 1, 12,180, 86,186,199, 11, 78, - 9, 35, 35,231, 0,192,240, 62,125, 48,107,214,172,138, 99, 23, 46,100,159, 58,123, 54,161, 53,202, 31, 12,228, 72, 83, 83,201, -236,217,179, 19, 1, 64, 16, 17,225,150, 92,147, 53,204,178,101,203, 22, 68, 68, 68,224,205,217,179, 49,103,206, 28,108,149,203, -239,138, 60,172,141,244,101, 50, 89,253, 11, 0, 14, 28, 56, 16, 5,224, 97, 23,197, 12, 9, 10, 14,238,193, 99, 24,252, 51, 57, - 25,181, 74, 21, 74,202,110, 64, 32,224,131,207,183,188, 4, 2, 1, 68, 18, 31,116,137,142,254,232,242,241, 19, 46,109,230,115, -169,168, 8,223,110,249,177,254,101,195,187,203, 63,195,187,203, 63,195, 46,249, 1, 15,238, 88,157, 0, 0,221,251,142,207, 73, -154,248,108, 98,214,142, 47,229,217, 25,111,222, 21,117,145,255,245,199,168,120, 46, 14,247,103, 85,162, 87, 16, 31,188,128, 16, -176,138, 10, 12,222, 93, 1, 95,190,133, 3,121, 78,230,100, 93,189,124,185,122,141,236,127,221,191,254,223,215,248,244,203,207, -175,125,190,236,195,119, 95,123,241,165,135, 23, 46, 90, 8,137,191, 47, 70, 13,143,199,177,163,199,190, 62,148,123,200,227,123, -118, 36,255, 29, 59,118, 96,200,144, 33, 93, 0,204,112, 53,236,111, 50,153, 16, 23, 23,199,153,205,102,190, 82,169,132,193, 96, -128,193, 96,192,133, 11, 23, 32,151,203,145,155,155,139,182,109,219,194,100, 50, 33, 47, 47,207,105, 89,165, 82,233,244,212,212, -212,143,167, 76,153, 18,176,106,213,170, 0, 66,136, 16,192, 1, 0, 74, 0,113, 0,126, 4, 96, 51, 60,247, 1,232,227, 76,222, -182,215, 94,251,254,225,254,253,201,134,228,100,148,158, 58,133, 15, 63,252,144,251,233,167,159,254,223,245,235,215, 35,228,114, -249,115,243,230,205,131,201,100, 66,124,124, 60,124,125,125, 71,224, 30,135,189, 49,208,128,236, 29, 79,136,167,203, 42,127,189, - 92,185,122,221,193,203,175, 94, 40, 85,238,101, 64,249, 0, 5, 38,188,143, 95, 7,125,136,255, 42,146,177,191,247, 18,224,193, -249,240, 23,112, 3, 31, 26, 16, 61,195,154, 46,184, 5, 59,246,215, 16, 64,133, 73, 79,189, 12,142, 3,128, 26, 88,150, 77, 54, -161, 83,247, 56,136, 69,124,152, 89, 3,168,209, 66,170,254,254,254,168,174, 81, 52,121, 19, 31,127,244, 26, 1,128,115,191,126, - 9,134,105,232, 36,112,186,223,161, 55,152,192, 19,136, 65,132,150, 28,154, 90,165,194,136, 17,205,215, 29,159, 51,130,227, 56, -176, 44, 11,131,193,128, 58,142,133,210,104,130,170, 76, 5,229, 13, 37, 84,229, 53,168, 81,213,162, 92,175,133, 74, 83,139, 90, - 67,211, 99,157,252,253, 52, 96, 89, 14, 6,163, 25,181, 74, 21, 10, 46, 23,227,232,137,124,252,122, 52, 31,231, 47, 20,162,228, -122, 21,234, 52, 70,168,235, 12, 40, 43, 85,226,236,239, 87,145,151,119, 10, 37,101,229, 77,202,180, 55,117, 88,165, 6, 37,167, -207,227,183,221,251,145,181,246, 35,236,223,180, 22, 37,133,151,193, 81, 19, 56, 66,234,137,223,157,228,154,179, 48,191, 51,240, -249,124, 0,184, 9,224,102,112,112,112,137,191,191,191, 97,222,188,121,199, 96, 25, 48,198,192,178, 86,118,129,167,242, 87,174, - 92,153,158,156,156, 12, 0,136, 9, 15,143,176,230,196,121,173,217, 57,108,225,127, 91, 36,192,133,240,127, 18, 0, 44, 95,190, - 28,151,202,202, 48,101,236, 88,216,162, 1,249,249,249, 0, 96, 51, 2, 92,170,138, 57,239,190,139,215,223,123,175, 62,188,111, -123,111, 59,182,189,119, 37,252,111, 67,118,246, 21,219,214,186, 13,206,219,142,179,179,175,124,235,138,156, 32, 62,255,191,122, -163, 1, 60, 30, 15, 23,174, 20,226, 74,201,117, 28, 57,125, 6, 70,163, 9, 12, 8,248,124, 62, 8, 33,224,204,102,232, 52, 90, -228, 31,200,217,239,130, 88,198,158,244, 31,159,250,240, 45, 30,255,145,147,249,176,143, 16,184, 6,187,112,178, 40, 54,199, 54, -232, 47, 59,227, 77, 42, 96, 47, 37,252,169, 26,184,166, 12,194,142,221, 80, 49,235, 62,228,127,253, 49,248, 97,109,235, 63,170, -152,117, 31,194,196, 12, 2,248,205, 55,151,238,177,221,219,249,248,248,250,124,250,197, 74,125,226,253,247, 11,135,141, 24,190, -225,234,229,171,220,133,203, 5, 0, 71, 33, 22,137, 16, 63, 40, 30, 59,119,236,196,182,109,219,220, 50, 2,246,236,217,147, 32, -149, 74,169,141,252,247,238,221,139,213,171, 87, 27, 1,224,232,209,163, 70,169, 84,250,152, 43,169,133,162,162, 34, 88,183, 38, -102,138,138,138,144,149,149,133,252,252,124,104, 52, 26, 40, 20, 10, 28, 63,126, 28,197,197,197,184,126,253, 58, 58,117,234,132, -162,162,162,102,229,205,156, 57,243,201, 71, 31,125,116,105, 66, 66,130,223,177, 99,199, 2,180, 90,237,191, 36, 18, 73, 14,128, -207,100, 50,217,124,153, 76,166,180, 26, 0, 67, 8, 33, 66, 74,169, 9,205, 76,111,159, 61,123,246,147, 63,204,153,179, 33, 62, - 34,130,176,115,231, 98,132,209,136, 99, 59,118,208,210,210,210,103,101, 50,217,187, 50,153,172, 18,192,186,115,231,206,177, 44, -203,194,207,207, 15, 81, 81, 81,126, 38,147, 9,127, 69, 52,150, 2,136, 4,208,101,242,224,142, 47,116, 8,245,157, 1,147, 14, -232, 62, 6, 39,195, 39,227,129,217, 95, 65, 87, 85, 11, 94,128, 63,228,159, 60,137, 81,189,126, 69, 72,126,214,104, 0, 29,155, -250,129,174, 1,237,241, 91,254, 86, 59,123, 67, 3, 75,154,208, 4,152, 12,224,115, 60, 48,214,126,191,237, 7, 75,186, 41,126, - 92,106,211, 13,245, 44,197, 67, 3,237, 13, 60, 98,189, 13, 1, 32, 16,131, 37,102, 88,253, 96, 76,155,241, 18, 0,200,175, 29, - 94,211,100,207, 50,115, 20, 44,199,128, 97, 89, 48, 70, 3,180, 86,203, 66,199,227,193,151,213, 65,165,163, 32, 2, 2,179,217, - 12,173, 25,168,208, 24,209, 84, 50,155, 53,114,208, 11,120,224,180, 44, 88, 78, 9,117,157, 9, 60, 34,128,129, 53,193, 72,141, - 96, 77, 70, 64,200,129, 33, 0, 17,113, 80,234,204, 40,175,212, 66, 99, 96, 27,117,146, 25, 98,174, 55, 0, 8,249,131, 79, 76, -122, 29,148, 53, 53, 96, 8, 15,124, 62, 5, 40, 31, 60,226,121,226,239,226,181,139,198,238,157,186, 11, 93, 9,251, 55, 8,147, - 18, 2,137, 68, 2, 0, 58, 0, 70, 62,159,143, 43, 87,174, 96,241,226,197, 15, 3,184, 62,111,222,188,129,129,129,129, 65, 74, -165,242, 90,109,109,173,219,225,110, 97,100,228, 51, 0,208,166, 77, 27,251, 14, 92,251,217,103,159,101, 3, 72, 26,216,183,239, -190,214,234, 8,179,103,207, 78,116,197, 0,248, 41, 55, 55, 97,232,208,161, 81, 35, 7, 12, 0,241,247,199,226,197,139, 49,119, -238, 92, 8, 4, 2,152, 20, 10, 4, 6, 6,226,205,217,179,235,199, 5,184, 50, 56,208, 49,199,239,108, 76, 64, 83, 88,236,198, -224,206, 19, 39, 78,224,196,137, 19,245,215, 55,149,227, 84,212,212,244,240,243,247, 71,149, 66, 1,249,145, 35,224, 51, 60, 24, - 76, 38,104,117, 58,112, 28, 87, 63, 88,145, 53, 25, 97, 52, 24, 92,169, 99, 14, 0, 99, 77, 3,112,118, 13, 95,111, 61,143,119, -151,127, 38, 4,128,216,232,232,138,171,231,126,107, 81,189, 38,165,124, 64, 46,156,204, 76,216,189,237, 75,121,107,204, 2,112, - 39,236,223, 32, 44,187,249,127, 24,240,212,171, 16,197,244,179,232,138,170, 50, 20,212, 88, 54,145, 19,141,152,128, 98, 51, 11, -159, 21, 71,154,149,161, 82,169,130, 68, 18, 49,186,198,196,136,175,150, 92,111, 91, 93, 89,141,105,143,207,144,239,218,151,133, - 79, 62, 88,158,185,109,215,142,228,216,152, 88, 60, 57,245, 9,228,157,204,197,182, 45, 91,232,100, 23, 66,236,246, 94,255,222, -189,123, 49,102,204, 24,155,177, 40,188,113,227, 6,158,127,254,121,161,237,246,157,201,170,174,174,198,168, 81,163, 96, 54,155, - 81, 84, 84,132,220,220, 92,244,234,213, 11,129,129,129,232,208,161, 3, 6, 12, 24, 0,134, 97,192, 48, 12,218,182,109, 91, 31, -165,220, 29,174, 51, 0, 0, 32, 0, 73, 68, 65, 84,106,194, 83,239,213,175, 95,191,143, 71,140, 24,193,203,207,207, 15, 48,155, -205,229, 91,182,108, 81,233,116,186,197, 50,153,204,222,128,125, 97,220,184,113,197,187,118,237,138, 33,132,148,161,137, 29,109, -165, 82,233,192,217,137,137,235,134,241,249,164,114,209, 34, 80,147, 9,114, 30,143,203,211,106,159,150,201,100,223,216,219, 29, -239,188,243, 14,159, 97, 24,212,212,212,224,202,149, 43, 21,125,250,244,137,248,203, 27, 0,250, 77,210,216,200, 64,201,200,113, -253,163,158, 15,144, 8,134,178,102, 78,193,167,230, 0, 4,181,229,149,213,234,161,171, 82, 2, 66, 62,204,181,106,148, 40,140, - 64,104, 71, 48,156, 81,220, 92,136,247,178, 74,133,110, 65, 1, 96, 13,192,229,156,111,209, 53,225,193,122, 7,206,100, 52, 65, - 0, 6,117,122,203, 14,181, 15, 37,196, 65, 18, 26,213,108,129, 31,234, 75,176,235, 12,133, 64, 12, 8, 59, 62, 8, 99,241,161, -122,199, 65, 32, 20,193, 4, 61,252, 36,150, 29, 73,119,236,218,132,223,142,230, 36,206, 24, 59,168,105,109,196,113, 16, 26,117, - 48, 65, 8,134, 97, 1,189, 69,177,153, 76, 38, 24,244, 2,240,248, 2, 64, 15, 80,206,146, 34,232, 20, 29,211,164, 44,173,158, - 3,143, 71, 96, 98, 77,208, 27, 56,168,212,150,118,104,226, 40,140, 6, 14,224, 3, 60, 1, 15,124, 49, 64,116,102,112,132, 5, - 7, 29,212, 58,107, 64,218, 9,204, 0, 24, 14,160, 4, 96, 24, 14,132,240,192, 81, 2,134,177,142,165,226, 24,112, 12, 3,194, -185,230, 32,219,121,255, 66, 79, 27,144,143,143, 15,172,222,126,248,149, 43, 87, 42, 22, 47, 94,156, 8,224,145,121,243,230,141, -237,220,185,179, 70,173, 86, 87,179, 44, 91, 79, 20,238,240,255,202,149, 43,191, 76, 78, 78, 70,116, 88, 88,253,201,232,176,176, - 32,107, 20, 32,252,207,232, 48, 70,163, 81,110,243,246,169, 90,141,127,255,251,223, 48, 84, 87,215,143,124,235,106, 53, 86, 4, - 6, 3, 30,126,248,225,138,210,138,138,199,162,124,124, 54,220,137,178,217, 15,234,179,207,255, 55,134, 65,131, 6, 33, 41,169, -115,253,245,141,173, 3, 0, 0,172,193,136, 90, 99, 13,244,122, 61,130, 2, 3, 33, 22,138, 96, 50,179,160,148,194,108, 54,195, -104, 52,194,100, 50,129, 99,205,174,214, 47,119,169,168,136,137,141,142,182,121, 4,220,165,162, 34,230,219, 45, 63,138,237, 35, - 2,177,209,209,181,104,165,193,108, 61,226,146,115, 74, 10,143,183,202, 51,246,116, 12,192,253, 89,149,168,136,206,132,176, 99, - 55,144,152,126,232,180,246, 20,170,244, 28,124,249, 4,198, 95,126,192,197, 43, 87,157,238,159,167, 99,141, 56,145,119, 20, 31, - 47,251, 8,247, 37,140,196, 59,255,239, 61,252,188,251,103,108, 88,255, 13, 70,140, 30,153,220, 33,186, 35,248, 62, 2,236, 59, -180, 15, 27,191,254, 6, 91,127,216,130,157, 59,119,210,255,251,191,255, 35,205,144, 44,117, 36,126, 27,106,107,221,223,224, 78, -173, 86, 35, 48, 48,240, 8,128, 97,209,209,209, 24, 52,104, 16,120, 60, 75,154,181, 83,167, 78, 16,137, 68, 80, 42,149,136,142, -142,134,191,191,255, 53,181, 90,221,169, 41, 89, 50,153,236,156, 84, 42, 77,223,186,117,235,248,216,216,216, 30, 91,182,108,169, - 83, 40, 20, 11,100, 50,217, 70,187,242, 79,190,255,254,251, 95, 91,187,118,237,102, 0, 21, 0, 82, 0,252, 10,160,127, 35,242, - 78, 73,165,210,244,160,227,199,223,122,148,101,241, 17,192,125, 89, 87,247,132,131,188, 71, 94,122,233,165,143,210,210,210,112, -245,234, 85,236,220,185, 19, 44,203,238, 7,240,232,189, 66,234, 3, 6, 12,192,233,211,167,235,243,254,205,134,226, 28,142, 59, - 79, 30,220,113, 97,128, 68, 48,180, 82,165,255,249,240,165,202,197,224,137,128,139,135,240,143,104,138,249, 47, 62,140, 65,189, -163,241,146,116, 28, 38,118, 49, 2,103,247,130, 10, 36, 44,154, 29,172, 83,139,130,218, 98,240, 69,192, 67, 19, 95,197,198, 79, - 63, 0, 96, 4,180, 6,152,117,192, 15,242,211,200, 62,102,153, 81,216,190, 99, 12, 24,190,115,242, 26,223,159,192,164, 7,118, -236,220,131,193, 99, 95,180,120,255, 16,128, 39, 1, 82, 39,164, 96,252,232, 73, 0,128,146,107,133, 96,245,198,230, 45,122, 74, -193, 18, 11,193, 27,140,150,193,127, 6,189, 14, 90,173, 22,117,117,117, 80,171,148, 80,171,213, 80,169,235,160,175,171,131, 78, -167,107,186,241,215, 17,232,244,102,232,244,102,104,180, 38,168,235, 12, 80,168, 13,168, 85, 25,161, 84,155, 80, 91,107,249, 95, - 83,205,162, 70,193,162, 70,201,162,170,198,136,155, 85, 77,151,145,161, 20,102, 0,196, 76, 64, 24, 14,148, 80,128, 82, 80,202, -131,153,251,163,250, 56,171,246,112, 55, 54,222,115, 68, 79,228,238,202,197,207,251,127,174, 55, 10, 46, 94,187,232,210,119,121, - 60, 30,248,150,250,138, 2,208,101,201,146, 37,103, 0,172,120,243,205, 55, 95,233,220,185, 51,107, 9, 18, 88, 10,230, 38,249, - 19, 97,100,228, 54, 0,136,140,140,188,229,195, 89,179,102,177,199, 47, 94,220,212, 90, 99, 1,108,225,127, 87,247,141, 55,217, - 77,177,248,254,251,239,113,185,220,146,194,249, 41, 39,167,193,103, 23, 47, 94,140, 8, 15, 15, 87,252, 25, 74, 32, 41,169, 51, - 99, 85,104,142, 10,191,193,231, 78, 13,188, 0,255, 11,156,217, 12, 85,141, 2, 85, 85, 85,168,174, 85, 64,163,213, 66,163,213, - 66, 93, 87, 7,141, 82, 5,117,109, 45,244, 58, 45,140,122, 61, 56,214,236, 84,231,196, 70, 71,219,116, 6, 7,192,104,159, 14, - 0,128,111,183,252,136,119,151,127, 22, 4, 32,210,221,251, 62,127, 50, 51,193, 49,239, 95,248,251,238,132, 63, 91, 41,151, 77, -139, 70,167,181,167, 64, 98,250,193,112, 32, 19,215,254, 57, 16,190,124,130, 67, 99,194,193, 42, 43, 49,120, 79, 5,156,100, 0, -144,156,156, 76,158,123,121, 38, 46, 95,188,136,188,156, 67, 8,244, 15,196,244,105,211, 17, 20, 26,130,147, 71,143,195, 79, 40, -134,175,175, 47,218, 70,183,195,166,239, 54,225,205,183,223, 66, 93,173,231,187,212,198,197,197,185,253, 29,127,127,127, 40,149, -202, 97, 12,195, 24, 59,116,232,128,161, 67,135,162,119,239,222, 8, 11, 11,131, 88, 44, 70,116,116, 52,250,247,239,143,160,160, - 32,168,213,234, 78,254,254,254,205,202,147,201,100, 75, 15, 28, 56,144,181,126,253,122,129, 66,161,120,199,129,172, 83, 70,141, - 26,245,241,218,181,107,191,138,140,140, 92, 68, 8,241, 3,240, 38,128,119,155,145,247,246, 66,181,122,233,179, 44,107,254, 82, -167,123,204, 65, 94,242,163,210,255,108,125,241,149, 57,188,139, 23, 47,226,200,145, 35, 88,187,118,109, 29,128,249,247,154,103, -239, 24,209,107, 42,194,231,168, 4, 68, 60,134,248, 23, 87,107, 54,108,202,187, 58,255,244,181,154,163, 58, 51,185,140,170,171, - 16,111,125, 1,139,226,213, 56,190, 96, 40, 62, 73,172,131,239, 15,179,128,154, 18,212, 81,241, 89,171,229,213, 4,254, 24,213, -127, 38,255, 71,252,231, 63,235,209, 53,160, 47,126, 63,124, 6,123,229,231,241,255,217,251,242,248,166,170,244,253,231,220, 36, -109,218, 2, 93,216,119, 40, 82,118, 89,138,208,130,208, 4, 82,168, 32, 42,218, 2,194,136,157,130, 77,113, 28, 65,196, 65, 69, -197, 13,149,249, 89,192,113,161, 41, 35, 95,112, 6, 6,104,113, 97,147, 37,144, 84,150,150, 90,112, 97, 17, 40, 20, 40,148,165, -208,164, 91,246,228,158,223, 31,201, 13,105, 73,147,155,180, 8,104,158,207, 39,144,187,244,205,185,247,158,123,158,247,125,207, -123,222, 87, 26,223, 15,137,163,236, 29,141, 10,132, 48,219,248, 95,100,210,224,222,120,255,255,125,132,157,199,170,209,172, 91, - 95, 60,250,232, 36,236,218,247, 13,182,239,250,159,253,226,108, 22, 4,139, 60,143,115,148,181,193,198,218,173, 25, 56,172, 25, -179,217, 12,163,209, 8,131,193, 0,157,222, 0,131, 94, 7,131, 94, 7,189,201, 8,179,201,216,176,251,203,208, 28, 85,181, 54, - 84, 27, 88, 84, 27, 88,251,247, 26, 22,181, 58, 43,106,245, 86,104, 53, 54, 84,104, 44,168,208, 90, 80, 81, 97,193,205,155,102, - 92,191,105,241,168, 0,220,114,255,187,180,153,115,223, 8, 40, 4,132,128,214,139,250,167,196, 59,217,190, 50,243, 21,244,137, -239,227,220, 86,174, 81, 58, 61, 2, 7,119, 28,196,233,139,167,121, 37,123, 98, 89,251,111,229,230,230, 30,160,148,246, 79, 78, - 78,158,217,189,123,247,214, 0, 24,150,101,131, 45, 22, 75,164,213,106,109,225, 70, 1, 96, 61,184,254, 23,127,254,249,231, 19, -146,147,147,209,189,117,107, 94, 83, 87,141, 1, 23,252, 55,180,119,111,175, 1,108, 61,219,181,147,102,102,102,226,196,197,139, -213, 95,239,222,141, 83,167, 78, 57,173,254, 94,189,122,193,113,204,252,245,238,221,184,120,241, 34, 78, 23, 21, 25,188,201,188, - 19, 49, 0, 0,104, 66, 66,194,243,174,164,207,253, 31, 27, 27,203,203,157, 11, 0,197,167,206, 21, 89,173, 86,152,205, 38,104, -174,151,227,198,213,107,184,121,237, 58,110, 94,187, 14, 77,249, 13, 84, 86, 84,192,164,211,217,227,103, 42, 43, 49, 88, 38,243, -118, 15,173,139, 51, 63, 21, 46,206,252, 84, 8,160, 26, 0, 59,124,200,131,183,157,228, 18, 23,192, 27, 39,143,230, 74,202,206, - 21,169, 6, 14,187,213,134,243,103, 15, 73, 42,111,148,168, 26,211, 63,200, 20,109, 29,203,223, 31,156,209,232, 80, 58,251, 33, -208,243,191,162,205,170,163, 8, 91,121, 4, 87,167,118, 67,236,206,114, 16, 81, 48,132, 4, 16, 50,222, 21,208,191,189,240, 2, -121,243,163,247,241,226,130,249,176,176, 54,156,186, 80,140, 25, 79, 79, 71,144, 88,140,239,190,221, 2, 88,108, 48, 25, 77,216, - 95,116, 8, 6, 67, 45,210, 83, 83,243,138,138,138,168, 7, 66, 36,147, 39, 79,150,142, 27, 55, 14,132, 16,236,217,179,231, 54, -151,254, 43,175,240,143, 19,106,217,178, 37,174, 92,185, 2, 0,194,172,172, 44,220,184,113, 3, 3, 6, 12, 64, 68, 68, 4, 24, -134, 65, 97, 97, 33, 24,134, 1, 33, 4, 87,174, 92, 65,203,150, 45,189,202, 84, 40, 20, 31,152,205,230,209, 10,133, 98,163, 11, - 89, 63, 61,106,212,168,204,217,179,103, 71,102,101,101,137, 9, 33, 12,128,111, 0, 44, 80, 40, 20,215,189,200,251,199, 97,139, -101,104,125,121,211, 22,126,189,233,169,233,127, 35, 19,230,100, 65,125,248, 36, 50, 51, 51,217,234,234,234, 52,133, 66,113,225, -126,116,239, 15, 26, 52,200,249,225, 53, 5, 0,224,220,255, 14,157,127, 65,163, 51, 29,129, 61,112,171,125,126,241,141,236,209, -189,219, 46, 18,158, 63, 28,133,255,123, 6, 8, 14, 3, 76, 58,128, 82, 88, 4,226,235,251, 79, 92,253, 18, 64,131,217,151,214, -175,251, 66, 58,125,198, 76, 21, 0,232, 88, 11,206, 86,150, 2,176,225,129, 22,221, 33,149, 62,136,182,173,218,161,162,170,218, -238, 43, 48, 91,113,181, 82,135, 62, 30, 46,170, 83,151,120, 92, 46,205,119,188,153, 66, 36, 13,180,199, 0,236, 60,102,193,174, -109,185,184,126,243, 10, 90, 70,216, 87, 18, 68, 4,137,240,224, 80,207,235, 55,205, 16, 34,136,181,194, 6, 1, 88, 66,192,216, - 88,192, 98,133, 77, 36, 4, 8, 3,238,157,100, 41,236,185, 2, 60,224,137,105,175,146,111,255,179,128,134, 6, 81, 8, 69, 46, - 30, 6, 11, 96,165,128,209, 12,216, 76, 54, 16, 66, 64,130, 8,172, 54, 64,103, 2,102,165,254,147,184, 75,229,104,115,209,208, - 88,134, 5,113,184,255,237, 74, 1,129,141,101,192, 8, 28, 43, 5, 0, 80, 1, 5, 40, 63, 47,128, 43,249,187,219, 62,184,227, - 96,119,175, 83, 18, 54, 27, 76, 38, 19,146,147,147,251,229,230,230, 46, 7, 48, 40, 55, 55,119,103,110,110,238,254,228,228,228, - 23,122,244,232, 97, 33,132,180,252,228,147, 79,118,191,250,234,171, 51, 52, 26, 77,158, 7,229,211,217, 39, 23, 44, 88,176,120, -193,130, 5,216,185,115, 39,116,215,111,127,151,187,183,110,141,243,231,207, 3,128,138, 79, 98,160,134,146,254,136,218,180,145, -124,254,249,231, 42, 74, 41,134,246,234, 37, 29, 50, 96,128,218,155,172, 1,125,250,168, 9,195,140, 63,245,227,143,221, 0, 4, - 3,248,151, 37, 56, 24, 34,147, 9, 61,219,183,199,252,249,243,113,240,224,193,165, 49, 49, 49,121,253, 59,118,244, 26,163,224, - 46, 15,128,191, 49, 0,174,224,242, 0,196,197,165,252, 88, 80, 80,126, 80, 46,151, 7, 57,166, 9, 70, 0,200,231,155, 4,168, -219,192,190,175, 27,174, 94, 27,199, 90,109,189,117, 85, 85,168,186,121, 3,132, 48,160,148,133,209,104, 4,165, 20,148, 82,156, - 63,249, 27, 44,102, 19, 30, 24, 26,235,237, 30,186,142, 57, 17, 0,152, 9,210, 4,118,130, 52,161, 78,208,159, 99,138,128, 55, - 78,253,252,181,228,202,185, 34, 21, 0,116,235,218, 21,223,213,243, 2,180,238, 50, 68,122, 55, 7,227,161,223,151,163,232, 17, - 96, 80,172, 12,229,127, 27,129,118, 95, 28,194, 25,141, 14,145, 65, 4, 21, 26, 45,132,132,120,245, 0,112,152, 57,115,102,157, - 51,183,110,221, 74, 39, 76,124, 4,219,182,108,195,166, 77,155,240,246,162, 55,177, 91,189, 23, 2,161, 0, 29, 59,117, 76,168, -170,242,188,116, 57, 41, 41, 73,157,148,148, 68,118,238,220, 41, 25, 55,110, 92,157, 88,128, 61,123,246,224,236,217,179, 70,133, - 66,209,158, 79,219,186,117,235,134,146,146, 18,244,237,219,215, 58,111,222,188,160, 13, 27, 54, 32, 60, 60, 28,167, 78,157,186, -205,243, 90, 82, 82,130,110, 60,159,179, 66,113, 43,241,156, 92, 46,127,230,161,135, 30,122,247,233,167,159, 14, 47, 42, 42,106, -110, 52, 26,255, 26, 18, 18,242,168,193, 96,248, 88,161, 80,124,199, 83,222,207,174,242, 30,253,251,134,181, 15,143,157, 76,254, -169, 4, 72,135,199,240,193,138,215,169,166,248, 84,154, 66,161,200,193, 31, 24,117, 20, 0,241,211,138, 19,154,255,201,207,136, -159, 86,112, 83,154,165,199,255, 39,255,190,198,104,213, 13,127,160,213,132,168, 80,193, 67, 2,147, 49,204, 74,153,154,138, 26, -115, 65,254,217,107,187,202, 52,250, 60,241,211,138,171, 88,185,210,237, 15,212,234, 90,171, 51,254, 54, 71, 10, 64,197, 10,184, -105, 62, 1,206, 86, 95,197, 91, 47,164, 65,175, 55,161,218, 96,143, 1, 48, 51,193, 24,147,228, 57,205,238,155,139, 82,201,206, -237, 67,237, 47,183,141,179,156,173, 72, 26, 64, 48,237,249,101, 8, 13, 13, 70,139, 16,177, 20,128,170,248,248, 81,105,124,127, -207, 9, 65,132,212, 10, 51,177, 43, 1, 32, 4, 54, 74,237,138,128,213,177,220,143, 48, 16,178, 44,172,220,178, 3, 47, 74, 64, -165, 33, 2, 6, 83, 5,130,132,140, 51,205,153,149, 5, 44, 22, 10,139,149,162,214,192,130, 8, 8,108, 32,176,176,183, 92,247, -110, 9,150,101,192, 16, 27,136,141,128, 50,212,233,254, 39, 13, 24,207,156,164, 23, 95,146,146,149, 43, 79,121,180,240,126,203, -255,173,177,125,199, 76, 41,133,193, 96,192,128, 1, 3,174, 70, 71, 71, 79,190,112,225, 66,207, 77,155, 54, 21, 2,120, 60, 55, - 55,247,113,215,147, 63,250,232, 35,245,171,175,190, 42,213,104, 52,222, 8,194,121, 67, 50, 50, 50, 26, 60,233,169,103,159, 5, -224, 91, 98, 32, 46,235, 94,125, 12,235,211, 71, 58,152, 7,249,115,232,223,171,215,110, 87, 79, 70,102,102,230,103,147, 38, 77, -178,158, 62,125, 90,120,241,226, 69,116,107,217, 50,191, 99,104, 40,175, 0,197, 59,145, 7,160, 30,185, 95,207,203,203,115,141, -241, 56,230, 80, 4,248,102, 12,212,133,180,111,247,212,169,189,251,242, 35,194,194, 90, 84,107, 43, 97,181, 90, 65, 29,239,129, -246,122, 57,170,181, 90, 80, 74,249, 88,255,246,151,245, 86,204, 9,227, 88, 14,200, 12, 31,242, 32, 38, 72, 19,156,137,129,138, - 47, 92,224,175, 4,232,127,145, 92, 46, 46,116, 90,249,223,229,124,169, 2,128,214,209, 35,165, 3, 99, 39,169,239,222,240, 74, -111, 87, 2,176, 10,131, 50,222,194, 53,150,197,192, 53,133, 40, 76,106,139,126,219,174, 67, 72,128,230, 34,255,106,179, 77,154, - 52,137,236, 83,239,163, 99, 18,199, 98,203,230,111,241,222,210,143,176,176,170, 10,148,101,177,113,227,102,148,149,149, 61, 10, - 96,155, 87,143,170, 27, 69, 0, 0, 38, 79,158,252, 51,128, 26, 62,109,137,143,143, 39, 87,174, 92,161, 71,143, 30, 13, 26, 50, -100, 8,198,142, 29, 11,149, 74,133, 46, 93,186,192,100, 50, 33, 33, 33, 1,148, 82,246,232,209,163,140, 72, 36,242, 57, 35,160, - 92, 46,239, 27, 30, 30,190,124,234,212,169,162,147, 39, 79,182, 48,153, 76, 13, 5, 6,242,149, 55,184,227,160, 41,107, 7,141, -158, 74,190,204, 3,170, 13,128,249,252, 78, 86, 83,172,170, 31, 24,120,223,128,203, 3,224,106,249,187,219,231,214,149,234, 66, -254,220,246,111, 23,255, 39, 47,189,120,179, 54, 31, 64,123,199,203,107, 2, 80, 6,160, 68,252,180,194,171,139,115,200,192,199, -212, 39,126, 45,149,218,104, 51,149,235,203, 81,171,171,182,175,251,103, 66,241,143,143,249,167,152, 76,154,216,159,188, 63,231, - 81, 9, 24,189,202,149, 11,155, 53, 11,135,205,162, 5,168, 14, 23, 15,101,147,153,211,146,188,202,178, 64, 0, 80,106, 39,106, - 8, 16, 68, 29,138,128,131,252,237, 57, 0, 1,216,248,205, 77,164,166,191, 65,178, 63,125,155, 90, 45, 26, 8, 29, 11,123, 41, -165,176, 89, 41,140, 22,160,186,198, 10, 11, 40,172,148,129, 80, 68,176,228,221,207, 26,188,238,217,179,237, 65, 90,107,215,156, -165,196, 98,183,254, 41, 0, 74, 9, 64, 29, 22, 3, 21,128, 8, 88,176,172, 16, 47, 47, 24,199,235, 30,206,126,111,182,244,194, -185, 11,158, 8, 88, 4,251, 82, 13, 79,236,196, 2,128,201,100,130, 86,171,213,134,135,135, 35, 54, 54,246,151, 97,195,134, 5, -223,184,113, 3,231,206,157,179, 47, 15, 99, 89,201,230,205,155, 85, 14, 37, 64,197, 67, 9,176,164, 36, 37,165,116, 27, 48,192, -246, 80,239,222, 58, 71, 31, 53,161,238,138, 72,164, 36,217,159,109, 55, 30, 73,129, 94,121,229, 21, 41, 0, 12,237,213,235,182, - 99,177, 3, 7, 54,138, 32, 6,244,233,243, 5,195, 48,182, 83, 63,254, 24,214,182,109,219,155,253, 71,140, 88,123, 55, 95,126, - 55,164,174,139,141,141,117,141,182,118,174, 99,245, 65, 9, 56, 57,120,236,152,225, 91,254,253,229,230,232,238,221,250,154, 76, - 70,216, 44, 86,176, 44,139,230,145,145,168,210,104, 48, 88, 38,147,242,176,254, 1,160,242,157,151,255,222, 6,128,185,248,194, -133, 32,110,254,255,240,209, 95, 49, 65,154,192, 46,206,252,212, 91,114, 32, 39, 98,218,107,233,169,211,167,164,251,118,125, 87, -199,197, 63,102,252,227, 82,166, 69,124,163,158,107, 67, 1,126,238,247,243,231,176,161,223,151, 3,223,191,224,220,126,224,187, - 91, 75,128,171, 44, 54,191,219, 59, 70, 50,134,124, 85,250,213, 35,227, 38, 38,237,120,238,153, 89, 7, 30, 28, 56,224,225, 45, -223,109, 69,254,207, 71,144,158,158,190,125,101, 3, 6,154, 23, 69, 96,214, 55,223,124,243,239,111,190,249, 38, 46, 41, 41,137, -119,227,198,141, 27, 55,102,247,238,221,251,182,109,219,134,232,232,104, 36, 38, 38, 34, 60, 60,252, 76, 85, 85, 85,204,137, 19, - 39, 80, 82, 82,194,136, 68, 34,140, 27, 55, 78,230,235,117, 58, 2, 3,151,110,221,186,181,193,192, 64, 31,229,253, 36,151,203, - 63,252, 54,247,177,215, 13, 29,103,192,240,227, 27,236,149,253, 75,158,241, 87,222,189,168, 8,240,246, 0, 52, 4,241,211, 10, - 29,128, 95, 29, 31,191,240,204, 51, 47,168, 51, 50, 94,149,102, 41,222, 83,117,236,218, 19,128, 9,162, 96, 49, 46, 95,173, 70, -194,164,153,196,119,121,143,169, 31,232, 29,131, 53,171,191, 6,216,139, 0,132,176, 26, 13,232,216, 62, 92,218,165,133,149,255, -203,111, 99, 33,100, 88, 88,136, 16, 34,106,189,165, 8,192, 10, 80, 27,248, 6,134,185, 34,253,239,111, 19, 0, 88,252,218, 28, - 42, 18,218,173,125, 43,107,119,153, 87,214, 80,216,172,128, 64,200,226,139,207,249, 41, 61,207,166,218, 83, 35,175,254,242, 52, - 5,151, 19,158, 1, 88, 98,119,247,207, 95,240,168, 79,141,172,170,173, 82, 71,182,141,108,108,255, 98, 0,251, 42, 10,131,193, - 0,155,205,134,234,234,106, 8, 4, 2,216,108, 54,180,107,215, 14, 22,139, 5, 10,133, 66, 85,207, 19,160,242, 86, 51, 96,240, -128, 1,185, 0,208, 20, 25,255, 0, 32,138, 16, 53, 0, 68, 13, 28,120, 71,204,188,126,189,122,101, 53, 70,192,203,139, 23,215, - 89, 37,177,224,237,183,235,120, 6,124,153,251,119, 67,230, 58, 79,171, 1,124, 72, 7,124,234,177,217,179,250, 3, 16,156,202, -203,179, 24,245, 6,176, 54, 27,250,196,198, 74,219,199,244, 69,183,129,125,249,189,115,148, 76,221,245,253,118,231,230,136,190, -209,206,239,187,190,223,126,219,182,167,208,248, 51, 87, 35, 9,211, 34, 30, 99,199, 19,233,201, 83,231,112,245,226, 49, 21, 0, -236,219,245,157,170,109,151,115,210, 1,195,255,226,179, 18, 48,101,202, 20,248,154,222,215, 70, 60,231,221, 46,157,220, 14,223, - 95, 49,222,241, 1,127,230,204,153,223, 3, 96,138,138,138,216,189, 5,121,104,217,170, 37, 26, 83,159, 35, 41, 41,233,203,164, -164,164,175,224, 61,189,115, 29, 52,111,222, 92,245,212, 83, 79,145,252,252,124,122,238,220, 57, 20, 22, 22,162,166,166, 38,166, - 41,106, 1, 56, 72,251,255,201,229,114, 81,126,126,254, 0,179,217,252,134,235, 92,190,159,242, 22,201,229,127, 17,133,247,248, -106,126,213,185,221, 51, 26, 43,239,110,131, 91, 5,224,110,191, 95, 10,128,175, 83, 9, 13,186,170,158,124, 86,189,125,215, 89, -242,196,196, 80,218,166, 99,103,104,106,172, 72,152,248,140,223, 29, 33,254,161,222, 36,254,161,215, 33,151,191, 69,129,235,136, -108, 46, 68,151, 40,214,167,151,126,232, 95, 23,220,177, 2, 54,239,124,184,146, 0,192,220,121, 47, 80,179,193, 2, 22,246,101, -115,203, 63, 95,238,215,111,166,205,178,215, 12, 88,253,239, 83,148,165, 2,188,246,234,227,119,179,186, 89,144,171, 27,219,100, - 50,193,108, 54, 59,137,140, 35,176, 64,149, 64, 47, 46, 72, 31,210, 15,251, 9,243,194,133, 41,193, 14, 15,138,173,145,178, 40, - 0,107,239,132,132, 58,109,238,214,190, 29,111, 1,193,172, 73,253,236, 36,159, 13, 63,212, 47, 5, 92,199,254,110, 17,167,238, - 55, 44, 14,253,134,161,209,247,210, 91, 97,159,250, 58,176,149, 4,195,192,120, 94,145,122,174,198,138,152,230,124,134,200, 38, -233, 10,116,232,208,161, 77,217,167,252,206,128, 19, 31, 31, 79,188, 37, 98,107, 4,105,127, 32,151,203,191,117,141, 13,104,164, -188,127,200,229,242,245,174,177, 1,247,187, 18,192, 7,100,208,160, 65, 20, 1, 4,208, 72,244,236,217, 19,197,197,197,129, 27, - 17, 64, 0, 1, 4,112,159,128, 9,220,130, 0,154, 2, 1,242, 15, 32,128, 0, 2, 8, 40, 0, 1, 4, 16, 64, 0, 1, 4, 16, - 64, 64, 1, 8, 32,128, 0, 2, 8, 32,128, 0, 2, 10, 64, 0, 1, 4, 16, 64, 0, 1, 4,112,215, 81, 39, 52,117,206,156, 57, -126, 71,143,186,203,100, 23,144, 23,144, 23,144,119,111,200,147,203,229, 84,161,104,120,217,105,224,254, 5,228, 5,228,253,177, -228,249,172, 0,112, 3,133,175, 66, 60, 13, 44, 77, 45, 47,128,123, 19,222, 8, 38,128,123,243, 57,248,120,126, 24,128,135, 14, - 28, 56,176, 68, 32, 16,140, 8, 14, 14,134, 94,175, 63,244,240,195, 15, 47, 2, 80, 8, 64,127, 47,220, 3,165, 82, 41,201,201, -201, 81,253, 17,199,149,227,199,143,163,176,176,208,235,121, 5, 5, 5,244,248,241,227,200,206,206, 38,253,251,247,111,180, 60, - 14,195,134, 13,131, 39,121, 1,220,199, 30, 0, 14,190,164, 39,229,147, 40,199,157,188,134,202,195,250,147,120,231,143, 62,160, -243, 61,119,252,248,241,210, 39,159,124, 82,205, 87,102,199,142,183,151, 94, 46, 43, 43,171,179,157,146,146, 2,153, 76, 70,248, -200,187,147, 74,192,248,241,227, 41, 0,236,218,181,139,220, 11,242,116, 58,221,216,205,155, 55, 43,207,156, 57, 3, 0,136,142, -142,126, 44, 45, 45,109,171,191,207,215,181,223, 83, 74,157,239, 7,183,159,123, 87, 8, 33,200,202,202, 34,158,148,103,190,207, -193,199,231,213,247,248,241,227,155,171,171,171,123,119,237,218, 21, 55,111,222,132,209,104, 4,128, 17,155, 55,111, 86,133,133, -133,157, 74, 74, 74,122, 2,128,199, 82,146, 35, 71,142,244,201, 32, 56,120,240,160, 20, 60, 83, 61,115,200,201,201, 81,165,164, -164, 72,101, 50,153,218,215,231,145,158,158,238, 83,251,166, 76,153,194,251,253,224,208,181,171,189, 2,110, 77, 77, 13, 76, 38, - 19,215,159,120,189,111,133,133,133,248,207,127, 60,103,168, 53,153, 76,116,196,136, 17,232,211,167, 15,214,173, 91, 87,110, 50, -153,186, 52,180, 46,188,176,176, 16, 51,102,204,224,117,173,215,175, 95,199,146, 37, 75,160, 80, 40, 2, 3,243,125,128,250,201, -128,238,100, 34,160,128, 21,123, 7,241, 93,150,247,148,198, 79,204,217,233,147, 76,149,234,150,129,116,230,204, 25,132,133,133, - 57, 7, 33,151,251,193,199,218,162,245,183,235, 15, 96, 74,165,146,230,228,228,248,109,129,173, 95,191, 94, 50,126,252,248, 6, -229, 55, 6, 25, 25, 25,116,244,232,209,210,233,211,167,251, 68, 22,155, 55,111, 86,182,105,211, 6, 51,103,206,132, 86,171,101, - 51, 51, 51,183,104,181,218,105,145,145,145, 62,101, 17, 35,132,224,251,239,191,119,110, 39, 37, 37, 97,231,206,157, 30,183,189, -161,190, 18, 32,151,203,105,108,108, 44,178,179,179, 41,151,152,201, 87,242,175,170,170,202,239,209,163, 71, 11, 0, 16,139,197, - 8, 9, 9, 65,121,121, 57, 42, 43, 43, 17, 30, 30,142,242,242,242,222, 59,119,238, 44, 76, 74, 74,234, 5,224,154, 39, 97,253, -251,247, 71, 74, 74, 10,162,163,111,101,253, 91,186,116,105,157,115, 22, 46, 92,200, 89,178,170,233,211,167,251,252,188,253, 33, -127, 14, 43, 86,172,104,232,144,179, 86,129,191, 8, 11, 11,195,201,147, 39, 33, 18,137, 96, 54,155,177,115,231, 78, 20, 23, 23, -227,181,215,124,171, 56,123,189, 94,145,172,199, 30,123, 76, 0, 64,246,195, 15, 63,236, 76, 72, 72,184,254,196, 19, 79,180, 85, - 42,149, 16, 8, 4,173, 35, 34, 34, 4,190,200,106, 8, 23, 46, 92, 8,144,196,125, 74,254,220, 62,175,181, 0,238, 87,172, 94, -189, 90,146,150,150,166,110,172,156,251,197,149,221,113,232,251,183,172,246,162, 55,252,146,161,213,106,161,215,235,157, 22, 72, -118,118,182,171, 37,196,215,218,186,109, 91, 38,147, 97,207,158, 61,148, 16,114,219,113,127,240,195, 15, 63,168, 94,121,229, 21, -228,230,230, 34, 57, 57,185, 73,238,223,174, 93,187,200,222,189,123, 41,165, 20,121,121,121,170,188,188, 60,159, 20,148, 51,103, -206, 96,230,204,153, 44, 0, 38, 40, 40,136,137,137,137, 65,102,102,230, 6, 0, 27,162,163,163, 39,166,165,165,237,224, 35,231, - 78, 20, 3,226,148,128,236,236,108,202,165, 1,230,254,151,203,229, 52, 37, 37,197,151,107, 13,211,106,181,155,197, 98,113, 11, - 0,248,219,223,254, 6,163,209,136,172,172, 44,132,132,132, 56,203,102, 11, 4, 2, 84, 85, 85,181, 0,144, 9,224, 47,158, 4, -114,228, 94, 82, 82,114,219,190,166, 64, 74, 74,138,212,113,157, 82,127, 21,129,151, 94,122,201,249,125,249,242,229,220, 87,166, -222,126,222, 10, 1,231, 53,121,227,141, 55, 16, 22, 22,134,220,220, 92, 36, 36, 36,248, 69,254,245, 49,106,212, 40,192,158,165, -241,175,207, 60,243, 12,122,246,236,217,118,231,206,157,168,168,168,224, 74,238,154,189,188, 11, 77,221,253, 36, 19, 39, 78, 84, -109,223,190,221,157,247, 70, 50,102,204, 24, 21, 33, 4,123,247,238, 13,184,123,239, 48,249,167, 47,252, 8, 0,144,189,244, 85, -183, 74,192,239,162, 0,100,103,103,187,123,208,180,161,253,254,252,198,225,195,135, 85, 0,164,141, 85, 2,102,204,152,241,167, -153,207,214,235,245,183, 89,253,254, 16, 13, 71, 44,201,201,201, 72, 76, 76, 36, 0,144,155,155,219, 36,109, 92,191,126,189,196, - 97,209,145,242,242,114, 73, 78, 78,142,170,188,188, 92,226,171,197,238, 14, 99,199,142, 37, 99,199,142,197,250,245,235, 37,121, -121,121,170,245,235,215,251, 36, 87,171,213, 90, 35, 35, 35,131, 54,111,222, 12,135, 55,192,168,213,106,153,204,204,204,237, 90, -173,118, 92,100,100,228,158,187,249,124, 57,210,119,237,203,114,185,156,114, 74, 26, 79, 60, 84, 92, 92,220,123,192,128, 1,152, - 53,107, 22,170,170,170, 80, 81, 81, 1,145, 72, 4,161, 80, 8,161, 80, 8,145, 72,132,144,144, 16,104, 52, 26, 40,149,202,233, - 50,153,236,239,222,132,150,148,148,212, 81, 14, 57, 5,128,243, 4,196,198,198,250,210, 70,119,214,191, 52, 39, 39, 71,213, 24, -207,147, 11,172, 13,140,149,188,189, 1, 23, 46, 92, 64, 94, 94, 30, 38, 78,156,136,174, 93,187,162, 85,171, 86,200,203,203,195, -107,175,189,230,244,190, 9, 4, 2,159, 27, 54,106,212, 40, 44, 90,180, 8, 75,150, 44,105,159,150,150, 54,245,233,167,159, 70, - 98, 98, 34, 0, 64, 32, 16,204,108,217,178,229, 86,133, 66, 97,241, 84, 12,104,253,250,245,188,188, 0,101,101,101,152, 54,109, - 26, 63, 3,165, 99, 71,164,167,167,171, 74, 74, 74,160, 84, 42,185,251, 47, 73, 79, 79, 87,113, 10,116, 0,119, 22, 28,249,115, -223, 57, 37,224,119,247, 0, 52, 52,143,237, 79,128,224,157, 86, 2, 38, 76,152,208,104, 79,128, 47,215,229,203,111, 60,245,194, - 46,108,254,108,124,147,220, 43,238, 5,148,203,229,110,231,244, 14, 29, 58,212,104,197,160, 41,158,239, 15, 63,252,160,226,172, -254,233,211,167,171,127,248,225, 7,180,105,211, 70,133, 38, 74,156,206,201,205,203,203, 67, 94, 94,158, 87,119,179, 78,167,155, -176,121,243,230,237, 0,144,153,153, 25, 20, 29, 29,141,180,180, 52,238,176,248,215, 95,237,245,178, 50, 51, 51,119, 71, 71, 71, - 63,145,150,150,230,181, 62,121, 82, 82, 82,157,152,152, 71, 30,121,164,142,103,128,143,219,223,141,210, 77,221,245, 47,238,185, -184, 78, 7,120,194,206,157, 59,151,196,196,196, 0, 0,206,158, 61, 11, 74, 41, 78,159, 62,237,172,251, 32, 20, 10, 65, 8,129, -205,102,131, 94,175,199, 55,223,124, 3,153, 76,230,181,234,146, 43,249,167,164,164,184, 85, 94, 92,167, 8,252, 81, 2,100, 50, - 25,145,203,229,180,177,222,128,166, 24, 39, 45, 22, 11,134, 12, 25, 2,181, 90,141,161, 67,135, 66,167,211, 57,167,118,212,106, - 53,198,143, 31, 15, 43, 87,130,220, 55,203, 31, 75,150, 44,233,144,150,150,118,249,203, 47,191,116, 30,235,208,161, 3,150, 45, - 91,246, 31,190,132,221,196, 80, 31, 57,114, 4,177,177,177,136,142,142,198,144, 33, 67,232,209,163, 71,165, 28,249,151,148,148, - 64,173, 86,243,137, 81, 25, 6,224, 5, 0,127, 85, 40, 20, 54, 15,231, 77, 4,208, 17,192, 55, 10,133,226, 70,128,250,127,199, -142,205, 7,191,103, 16, 96, 83, 40, 1,221,186,117,107,148, 39,128, 27,100,215,173, 91,231,246,248,142, 29, 59,176,110,221, 58, -191, 44,147,130,243,125, 17,215,253,164,223,110,127, 14,174,115,254, 74,165, 18, 50,153,204,233,246, 63,116,232, 16, 58,119,238, -220, 36, 74, 95, 99,172, 47,206,250,191,121,243,166,179,206,188, 68, 34,145, 54,165, 23,128, 67, 66, 66,130, 52, 47, 47, 79,229, -237,188,205,155, 55,111,231,230,254,117, 58, 29,150, 46, 93,138,218,218, 90,136, 68, 34, 4, 7, 7,227,252,249,243,120,255,253, -247,161,213,106,145,153,153,249,173, 86,171, 29, 19, 25, 25,169,242, 66,178,117,200,222, 91, 76, 64, 83, 40,158, 71,142, 28,169, -115,126, 67, 65, 98, 81, 81, 81, 35, 76, 38, 19,172, 86, 43, 14, 29, 58, 4,129, 64, 0,179,217, 12,131,193, 0,150,101,157,239, -177,197, 98,129,201,100,226,222,105,175, 97,226, 13,185,252, 23, 46, 92,232,244, 2, 68, 71, 71,163,188,188,188,209,138, 40,183, - 42,192,135,216, 17, 13,128, 40,119, 7, 92,166, 3,124, 66,102,102, 38, 94,121,229, 21, 12, 30, 60,216,233, 1,225,210,103, 15, - 30, 60, 24,167, 79,159, 70,155, 54,109,124,146,185,127,255,126,140, 26, 53,170,107, 90, 90,218, 5,142,252, 29,227,103,199,141, - 27, 55, 94,169, 31,208,203, 87,161,104,232,183,124,244, 62,145, 35, 71,142, 72,210,211,211, 85, 67,135, 14,197,208,161, 67, 85, - 0,112,250,244,105,228,229,229,241,125, 14, 63, 3, 8, 1,176, 65, 46,151, 79,115,167, 4,200,229,242, 23, 0,124,234,216, 92, - 36,151,203,123, 43, 20,222, 75,212,255,145,193, 85, 3,204, 94,250,234,109, 83, 0,127,216, 24,128,123, 81, 9,152, 49, 99, 6, - 93,180,104,209,109,174, 64,127,200,255,169, 23,154,118,158, 78,167,211,221, 22,228,199, 89,253, 34,145, 8,215,174, 93,187,171, -228,239,106,253,187, 90,110,211,166, 77, 83,171,213,234, 38,247, 2,248,226, 57,153, 57,115,166, 30, 64,104, 88, 88, 24,222,124, -243, 77,136, 68, 34,231,241,212,212, 84, 0, 64,100,100, 36, 38, 77,154,132, 3, 7, 14,236,155, 52,105,210,239,210, 78,215,251, -237, 58,255,239, 14,177,177,177,117, 42, 53, 54,180,142,216,108, 54, 67,163,209,192,104, 52, 34, 60, 60, 28,193,193,193,176, 90, -173,160,148,194,102,179,193,108, 54,195, 98,177,192,102,179,185, 42,244, 55, 61,181,179,164,164,164,142,117, 95,127, 58,160,126, -128, 96, 99, 33,147,201,212, 62,198,162,136, 27, 58,208, 64,108,128, 87,188,255,254,251,152, 56,113, 34,186,117,235,134,208,208, - 80, 72, 36, 18,104, 52, 26,132,133,133, 65,171,213, 98,205,154, 53, 96, 24,223,226, 11, 71,141, 26,213, 41, 45, 45,237,194,188, -121,243,176,101,203, 22, 60,254,248,227, 0,208,110,255,254,253,215,253,185, 79, 14,133, 2,220,152,197,141, 85,190,146,191,171, - 39, 96,227,198,141,210,169, 83,167,170, 0, 96,227,198,141,210,170,170, 42,181, 15,253,217, 44,151,203,103, 0, 88,231, 65, 9, - 72,116,249,222, 5,192, 0,216,151,164, 6,224, 66,252, 13,225, 15,153, 9,112,248,240,225,210,166, 8, 8,244,215, 74,119, 29, -144,151, 44, 89,210,104,242,231, 48,100,240, 32,236,221,167,194,250,125,161, 78,165,160,224,124,223, 70, 93, 99,108,108, 44, 74, - 74, 74,144,155,155,139,206,157, 59, 99,237,218,181,126, 88, 93, 84,194,125,203,200,200,104, 18,242,231,172,255,242,242,114,105, -253, 99,163, 71,143,150,230,230,230, 58,207,105, 10,228,229,229,169,248,122,159,180, 90,237,111,176,207, 11,179, 27, 55,110,196, -154, 53,107, 0, 0, 27, 54,108,128, 86,171,229, 78,179,158, 62,125, 26,173, 91,183,190, 43,239,128,107,180,191, 59,229,140,111, -153,230,146,146,146, 67, 54,155, 13, 90,173, 22, 55,111,222,116, 6,142,234,245,122,212,214,214,162,186,186, 26, 85, 85, 85, 48, - 24, 12, 48,153, 76,176,217,108, 0,144,239, 73,102,125,114,119, 23, 72, 90,127, 85, 0, 95, 40,149, 74, 73,253,107, 86, 42,149, -190,246,147,208,166,126, 30,107,215,174,133, 68, 34, 65,104,104, 40, 78,158, 60, 9,181, 90,141,176,176, 48,188,245,214, 91, 56, -112,224, 0, 94,123,237, 53,159, 20,128, 81,163, 70,181, 75, 75, 75,187, 52,109,218, 52,124,253,245,215, 28,249,119, 0,112,221, -147, 37,207, 71, 9, 88,178,100, 73, 83,144, 63, 0, 72, 56,242, 7,128,169, 83,167,170, 18, 18, 18,168,143, 99,168, 25, 0,183, - 78,113,131, 92, 46,175, 31, 40,113,214,229,123, 41,128, 99, 1,218,119, 25, 7, 22,126, 84, 39, 22,160, 62,254, 48, 65,128, 77, - 77,254,142,245,174,141,182,220,184,233,128, 25, 51,102,248, 77,254, 79,189,176, 11, 67, 6,223,114,221,108,254,250, 27,108,254, -218,254,125,239, 62, 21, 48, 70, 10,192,183,101,128,114,185, 28,177,177,177, 0,236,193,128, 71,142, 28,193,158, 61,246,152,181, - 99,199,142, 33, 33, 33,193, 7,105, 68, 13,220, 10,252,107,108,164,254,250,245,235, 37,238,172,255,250,104, 42, 47, 0,167, 72, - 72, 36, 18,169,183,115,163,163,163,199,101,102,102,238,158, 52,105, 18, 78,159, 62,141, 51,103,206,224,253,247,223,183, 2, 16, -234,245,122,100,102,102,194,113, 76,120,241,226, 69, 60,243,204, 51, 94,101,222,137, 24, 0,206,146,206,201,201,113,122,177, 56, - 98,228,158, 59, 31,196,196,196, 20,233,245,250, 17,102,179, 25, 55,110,220, 64,112,112, 48,132, 66,161,211, 3,160,211,233,160, -215,235, 97, 50,153, 80, 85, 85,197,205,231, 95,246, 36,147, 35,119,110, 26, 32, 54, 54, 22,245,189, 21,238,226, 2,248,144, 63, -151, 3,160,254,190,198,244, 15,206,234,119, 99,241, 91,249,142,161,197,197,197, 56,125,250, 52,244,122, 61,226,227,227,161,215, -235,145,147,147,131,169, 83,167, 98,203,150, 45, 16, 20,150, 5, 38, 0, 0, 32, 0, 73, 68, 65, 84, 8, 4,188, 21,128,152,152, -152, 78, 28,249, 23, 22, 22,226,237,183,223, 6,128, 46, 51,102,204,184,186,110,221, 58,178,127,255,254, 70,141,161,156, 39,160, - 49,228, 31, 27, 27, 75,185,126,118,244,232, 81, 20, 21, 21, 73,211,211,211, 85,189,122,245,130, 72, 36,162, 46,129,129,126,123, - 2,228,114,249, 92, 0, 19, 1, 36, 3,104, 3,123, 12,192,159,218,253, 15,220, 90, 5,224, 46, 8,240,174,172, 2,248,189,130, - 0,239, 53,242,175,175, 4, 52,198,242,247,180,189,119,159,202,159, 23,244,150,185, 19, 26,138, 62,125,250,212, 57,126,248,240, - 97,159,228, 37, 39, 39, 59, 21,128,220,220, 92,228,230,230,214, 89, 21,224,203,245,175, 93,187, 86, 5, 0, 59,119,238,116, 75, -158,211,167, 79, 87,175, 93,187, 22, 0,191, 37, 76, 13, 37,253,225, 20, 13, 74, 41, 18, 18, 18,164,211,166, 77,243,218,119,210, -210,210,246,104, 52,154,177, 7, 15, 30,220, 27, 19, 19,131, 51,103,206, 64,171,213, 10, 35, 35, 35,145,150,150, 6,141, 70,115, -241,224,193,131, 93, 99, 98, 98, 48,115,230, 76,175,215,235, 46, 15,128,191, 49, 0,245,223, 45,133, 66, 65,100, 50, 25,148, 74, - 37,173, 63, 45,195,247,121,196,197,197,189,174, 86,171, 95,180,217,108,168,174,174,134,197, 98,113, 42, 43, 70,163, 17,148,210, - 58,129,129, 50,153,236,105, 7, 49,242,134, 76, 38,131, 76, 38,171,179, 44,208,215, 41, 0, 87,162,151,201,100,234,250, 99,139, -171, 82,208,132,224, 61,126,114, 75,253, 94,126,249,101,168,213,106, 72,165, 82, 20, 23, 23,163, 89,179,102, 40, 45, 45,229,173, - 0, 28, 62,124,152,164,165,165, 93,122,230,153,103,176,127,255,126,188,245,214, 91, 0,208,113,198,140, 25, 87,154,130,252, 93, -149,128,198, 88,254,220,248, 82, 82, 82,130,162,162, 34,226, 48, 4,165,233,233,233,170,232,232,104, 72, 36, 18,202, 39, 16,176, -158, 18, 48, 13,192, 6,135, 18,112, 8,128, 28,128, 68,161, 80, 92, 67, 0, 77,215,129,155, 58, 27,159,187,128,159,165, 75,151, - 54,184,255,110,146,255,140, 25, 51,238, 72,202,208,198,200,188,116,217,123,255, 14, 9,241,205,107,233,105,126,216, 31,200,100, - 50,105, 98, 98,162,122,239,222,189,116,211,166, 77,117, 20,129,250,164,196, 87,102, 70, 70, 70,131,154, 13,151,148,196,151,196, - 64, 13, 41,156, 82,169,148, 23,249,115,136,138,138,114,206,235,159, 60,121,242, 47,153,153,153,255,225, 60, 2, 23, 47, 94,236, -250,198, 27,111, 72, 9, 33,188,228,221,137, 60, 0,245,239,179,187,249,111, 31,148, 82, 93, 66, 66,194,226, 29, 59,118,188, 99, -181, 90, 81, 89, 89,233,140, 1, 0,128, 27, 55,110,160,178,178, 18,148, 82,206,106,247,105,178,157,155,255,175,191,236,175,126, -156, 0, 95,242,119,125,206,247,218, 82, 94, 78, 9,120,245,213, 87,145,151,151,135, 73,147, 38,225,195, 15, 63,196,130, 5, 11, - 32, 20, 10, 33, 22,139,189, 61, 87, 66, 41,101,103,205,154,133,255,252,231, 63, 88,189,122, 53, 0,116,222,191,127,255, 21,135, -197,238, 87,103,114,153,182,106, 50,148,149,149,193, 77, 30, 0,117,118,118,182,116,204,152, 49, 42,127,150, 60, 58,172,254,105, - 0,182, 1,152, 11, 32, 46, 64,254, 13,195, 93, 16, 32, 47, 5,192,151,164, 28,254, 18,118, 83,163, 41,200,255, 94, 28, 52,230, -206,157, 43, 61,117,234, 84,147,202,116, 88, 67,170,166,148,201, 17, 30,183,182, 30,128, 51, 25, 16,203,178,216,188,121, 51,111, - 37,224,149, 87, 94,225,218,121, 91, 12, 0,195, 48, 96, 89, 22,255,248,199, 63, 84,124,201,211,147,188,198,174, 36, 72, 75, 75, -251,175, 70,163,185,113,240,224,193,157,124,173,254, 59,237,109,171,127,127,221,185,216,125, 81, 2, 8, 33,239, 78,156, 56, 49, -119,221,186,117, 39,130,130,130,192,173, 10, 96, 89, 22, 17, 17, 17,208,106,181, 92, 10,219, 80, 0, 54,190, 6,129,107,240,223, -145, 35, 71, 32,147,201,234,140, 39,222,198,161,146,146, 18, 90, 82, 82, 34,173,239,226,111,228,146, 63, 0, 13,186,251,173,203, -151, 47, 23, 3, 48,195, 30, 63,197,125,124, 82, 2, 92, 19,255, 60,255,252,243,206,239,213,213,213, 94, 95,179,184,184, 56,210, -175, 95, 63,250,213, 87, 95, 61,177, 97,195,134,239, 56,178,221,176, 97, 3,124,141,250,231,112,229,202, 21,103, 74,226, 38,130, -122,251,246,237, 13,245, 41,245,190,125,251,124,170, 85,225,225,240, 85,119,217, 74,255,236, 53, 73,184, 85, 0,238,136,159,215, - 42,128,166, 38,245,134,228,221, 43,202,195,189,220,113,250,246,237,171,238,219,183,111,147,202,116, 12,142,119,252, 90, 93,221, -255,245, 95,234,134,150,157, 57,218,199,167,109,196,135,235,189,163,215, 26, 21, 21,181,171, 49,145,254, 77, 25, 3,224,174, 15, -123,242,246,248,208,231, 79,206,152, 49,163,217,238,221,187, 63, 40, 45, 45,125,209, 96, 48,192,102,179, 97,208,160, 65, 24, 58, -116,104,166, 76, 38, 91,200,135,252, 1,160,160,160,192,249,221, 53,214,164,160,160,224,182,109, 79,136,142,142, 38, 14, 47,129, - 20,128,138, 83, 38, 92,166, 2,124,126, 38, 83,166, 76,105,232,144,208,101,188, 12,186, 27,227,138, 66,161, 96,143, 31, 63,142, - 79, 63,253,148, 0,224,149,148,231,239,127,247,156,147,105,216,176, 97,152, 60,121, 50,239, 54,120,147, 23,192,189,167, 4, 52, - 68,254,110, 21,128,166, 38,193, 64,133,184, 0,220,245, 1,127,203, 87,254, 25,238,205, 61,252, 27,186,113,227,198,205,133,221, -253,234, 23, 14, 30, 60, 72,166, 79,159,126, 71, 20, 90,127, 51, 7,254,158,202, 98, 99,209,191,127,255, 38, 45,198,211,212,242, -254, 12, 70,217,253,164, 4,120,181,162, 6, 13, 26, 20, 24,136, 3, 8, 32,128, 0, 2, 8,224, 79, 6, 38,112, 11, 2, 8, 32, -128, 0, 2, 8, 32,160, 0, 4, 16, 64, 0, 1, 4, 16, 64, 0, 1, 5, 32,128, 0, 2, 8, 32,128,251, 16, 86, 0,108,224, 54, - 4,224, 9,194,192, 45, 8, 32,128, 0, 2, 8,140,237, 1,252,201, 59,201,156, 57,115,252,142,184,116, 23,213,237, 73,158,183, -245,199,190,202,107,234,246, 5,228, 5,228,253,217,229,253,244,250, 69,191, 7,150,193, 31,116,197,157,150,119,228, 53,255,229, -197,126,120,187,188,140,140, 12, 2, 0,132, 16,137,197, 98,193,249,243,231, 85,102,179, 25, 66,161, 16,151, 47, 95,198,211,225, -221,176,171,168, 8,134, 7, 59, 35, 46, 46, 78, 42, 16, 8, 64, 41, 85, 3, 64, 86, 86,214, 29,127, 30, 92,251, 92, 65, 8,233, - 11,160,205,137, 19, 39,182,119,232,208,129,209,104, 52,226, 14, 29, 58,188, 31, 18, 18,178, 18,192, 21,199,114, 82, 38, 43, 43, -203,230, 65, 94,115,135,183, 64, 79, 8,161, 0,112,233,248,127, 87,201, 71,149,166,173, 47,138, 57, 47,108, 51, 46,174, 89,243, - 22,181, 0, 40,165, 84, 8, 32, 50, 43, 43,235, 82,224,125,187,183,229,221, 81, 45,145,111,182, 45, 95,179,191,249,147, 50,183, -114,205,215, 18, 97, 84,184,234,220,153,179,210, 7,130,155, 33,236,239, 51,212,247,146,150,213, 80, 62,242,192, 18,151,187,143, - 45, 91,182, 72,118,236,216,161,202,124,221,190,253,237,254, 81,152, 49, 99, 6,175,231,178, 63,255,144,132, 33, 68,117,250,212, - 41,104,181, 90,116,237,218, 21,205,154, 55, 71, 82,226, 56,222,207,117,207,158, 61,117, 94,220,220,220, 92,143,181, 20,114,115, -115,253,238, 55, 92,161,166,172,172,172,198,245,187, 20,141,227, 11, 5, 64,128,156, 40,255,101,197, 46, 7,162,159,181,127, 47, - 89, 3, 28,153,223,248,135,154,124,179,110,251,114, 91,241,250, 51, 66, 8,213,233,116,210,221,187,119,171, 74, 74, 74,144, 34, -106,137,118,157, 91,195,168, 51, 32, 68,111,197,200, 5,207, 97,244,164,169,216,246,101, 22,182,238,221,171, 26, 55,110,156,244, - 30,232,194,103,108, 54, 91,251,146,146, 18,118,224,192,129, 65, 49, 49, 49, 56,122,244,232,235, 70,163,113, 98,207,158, 61,101, -132, 16, 13,165,212,219, 84, 64,141,235,134,213,106,101,126, 41,250,169,103,167, 89,131,241,143, 97,253, 90, 23,236,254,120,211, -230, 99,146,159,123,246, 31,243,161, 67,222,101,135,194,192, 6, 60, 13,127, 50, 55,145,175,249,251,125,201,131,239, 43,249,219, -214,111,151,196,183,238,164, 34, 29,163, 81, 92, 91,137,246, 29,186,169, 44,172, 13,167, 62, 91,139,242,174,173,165,195, 38, 77, -224,165, 8, 28, 81,201,105,239, 30,220,150, 0,223,236,102,177,255, 71,138,244,105, 64,239, 30,192,252, 37,141, 35,110,174, 64, - 73, 99,179,147,185, 83, 38,154, 74,110, 99,144,158,158, 78,177,152,128,188,219,240, 57,148, 82, 96, 49,193,148,223, 82,238,153, -181,214,183,200,159, 58,200,127, 52, 14, 28, 56,128, 25, 51,102,120,253,219, 7, 7,238,166,125,251, 14, 69, 78,206, 85, 28,206, -183, 39,172, 57,115,234, 52, 0, 96,246, 95,191,166,167,207, 38, 75,195,196,252,158, 75, 98, 98, 34,187,103,207, 30, 38, 55, 55, - 23,251,246,237,243, 88,136,201,159, 20,170,158,222,219, 12,185,156,102,249,161, 80,112,233,194, 27,157,202, 56,250,217,186,197, -118,154, 66, 1,112,185, 79,142,234,132,188,112,238,220, 57,168, 55,109, 82,189, 43,155,130, 65, 51,158, 71, 80,219, 72, 64,232, - 72,246,199, 82,128, 21,129, 53, 81, 76,120, 54, 29,165,255,250, 8,135, 14, 29, 82,141, 24, 49, 66,202,121, 1,238, 18,108, 12, -195,180,105,213,170, 21,212,106,181,112,224,192,129, 24, 54,108, 24,115,237,218,181,193,191,252,242,203,241, 7, 31,124,112, 8, - 33,228,154,131,172, 25,158,247,174,217,216, 49,137,209, 31, 46,219,194, 44, 76, 61,214, 34, 46,105,142, 52,110,184,114,212,130, - 79, 47, 63, 26,243,208,204, 88, 66, 72, 13,236, 49, 6, 76, 67,253,204, 53,177,149,183,126,212,104,133, 52,128, 58,168,159, 0, -168, 62,252, 42, 6,228, 58,128, 12,154, 57, 0,115, 70,190,192,128,103,229,190,250, 74,128, 92, 46,167,177,177,177,200,206,206, -166,174,101, 75,125, 34,214,188, 35,146,233,131,227, 85, 65, 54, 22, 54, 80,132, 84,134,226,218,141, 27,184, 86, 83,133,238,193, -205, 96, 42,190,162, 58,188,117,135,116, 56, 15, 37,160,119, 15,224,212, 57, 6,148,138, 97, 35,193,120, 34,209,130,201,227, 12, -184, 21, 67,211,248, 84, 9,141, 37,105,142,248, 23, 46, 92,136,162,162, 34, 0,192,246, 83, 34, 24, 45, 22,149,252,175, 67,125, - 82, 4,124, 81,226, 28, 41, 94, 61, 63,151,197,246,195,177,177,177, 13,231,111, 95,236,223, 59,190,237,139,171,146,173,191,188, -237, 84,120, 38, 14, 88, 44,125,236,133, 14,141, 30,112,183,108,217, 34,217,190,125,187,138, 97, 24,188,252, 1,156,213,207,248, -212,193,136,140,252, 65, 18, 55, 60, 3,192, 86,140, 26,245,175, 58,199,166, 79, 7, 38, 76, 0, 38, 32, 87,181,252, 95,224,165, - 4,112,228,175, 86,219, 79,157, 58,117,170,179,176,146, 47, 4,230,201,242,231, 82, 50,187, 94, 95, 70,134,127,228,223,100,136, - 93, 6, 0, 88,177, 98,197, 45, 5, 96, 72, 38,112,244,229,187,210,156,125,251,246, 97,229,228,116,116, 31,147, 8, 8, 76, 32, - 34, 6, 68,200,128, 8, 68,160,148,128,213, 89, 65,109, 54, 80,179, 13,207, 61,251, 60,158,127,107, 46,206,181,109,171,234,209, -163,199,221,244, 4,144,162,162,162,248,206,157, 59, 7,149,148,148, 32, 47, 47, 15,167, 78,157, 66, 98, 98, 34,226,227,227,219, -175, 94,189,250,189, 41, 83,166, 60,231,131, 2, 32, 56,176,247,127,255,247,228, 32,125,219, 35, 53, 2, 76, 95, 92,139,135, 7, -127,130, 23,230, 77, 21,126,188,176,178,251,194,143,215, 77,143, 30, 60, 93,129, 6,210, 32,187, 18,186,235,152,158,145,145, 65, -221,237,111,234,130,112, 1,220, 1, 15,128,235, 67, 90,191,115, 93,101,143, 7,122, 68,200,223,125,142,157, 51,242, 5, 95,170, - 57,145,236,236,108,202,165, 37,229,254,151,203,229, 52, 37, 37,197, 55,171,122,231, 33,201,248,152,126,170, 32,163, 21, 33, 31, -191, 2,171,222, 12,241,203, 75, 16, 30, 36,134, 81,100,128,206,104, 64, 8, 8, 76,151,202, 85, 85, 85, 85,210,240,240,112,143, -131,240,169,115, 64,246, 6, 22,128,222,241, 1, 70, 61,196, 96,242, 56, 2,215, 64,218,244,105, 64,246, 6, 63, 60,166, 41, 41, - 82,199,117,250,101,173,115,228,207, 17, 63, 0, 40, 14, 88, 96, 48,235, 0, 0, 99, 23,238, 65,206,210, 68, 21, 0,222,242,207, -125,116, 14, 34, 82,124,171, 35,144, 50,144, 86,189, 93,182,203,209,250,175,252, 82,132,146,119,237,228,239,169,198, 60,145,231, - 80,251, 57,252,172,255,163,219, 45,146,236, 45,127, 87, 81, 80,124, 56,239, 91, 12,151,196, 96,253, 23,251,241,239,221, 25,170, -237,114,138, 57,127,121, 91, 58,104, 84,123,191, 20,129,218,139,114, 58,102, 32,144,243,213, 9, 80, 74,209,188,205,131, 78,242, - 95,185,114,165,199,246,233,140, 74, 73,122, 74,123, 21,240, 57,128,111,113,248, 48, 48,124,248,173,227,239,189,119,235,251, 75, - 47,230,170,178,254,221, 75,202,176,157, 61,182,147, 35,255,132,132, 4,176, 44,139,207, 62,251,172,201, 94,112,185, 92,238, 36, -255,186, 74,129,156,102,101,121,126,231,152, 41,218, 58,234, 47,113,252,195,166,184, 57,143, 56, 78, 36,246, 47, 3, 7,222, 62, -199,206, 76,213, 58,189,242, 0,192,178,169,152, 55,111,158,243,248,188,121,243,176, 98,197, 10, 48, 61,103,221,250, 85,199,249, -238,228, 9,167,186,111,159,213,234,230, 60, 30,237, 51, 26,141,104,215,181, 27,192,154,193, 4, 3, 68, 40,128,181,166, 10,198, -146,243,184,113,185, 12,157, 70, 72, 64,130, 34, 64, 44,102, 64,192, 96,233,156, 5, 72,204,126, 27,243,231,207,111,210, 65,217, - 91,170,108, 23,178, 37,148,210, 8,131,193, 48, 34, 42, 42, 10,167, 79,159, 6,203,178, 56,127,254, 60,214,172, 89,131, 62,125, -250,160, 99,199,142, 51, 1, 60, 87,143,172,217,134,200,155, 82,218,170, 43,115, 88,210,190, 75, 82, 80,101,222, 49, 84,105,131, -241,159,109, 86,236, 40,248, 47, 94, 76, 9, 17, 10,245,108, 44, 48,189,193, 58, 8,119,162,184, 85, 0,190,161,161,190,227,206, - 51, 32,228, 75,252,148, 82, 72, 95, 79, 64,118,158, 34, 34, 29,114,252,252,213, 49, 96,164,243,181,226, 5,142,244,245,250,117, - 0, 8,140,198,213,136,138, 82, 34, 39, 39, 7,190,164,241, 28, 22,220, 66,213,198,104,131,120,241,243,176,221,212,192,122,229, - 38,132, 65, 34,132, 18, 1,194,136, 0, 97, 2, 33,162, 68, 98,104,107, 42,113,117,223, 33, 85,248,228, 71, 60, 14,116,238, 72, -125,255,143,172, 67, 1, 0,150, 45, 34,160, 4,176,135,199,248,222,193, 29,164, 44,205,201,201, 81,229,228,228,248, 53,133,224, - 74,254, 16, 10, 80,114,213, 62,248,149, 94, 55,162, 75, 91, 49,122,166,110, 69,206,154, 73, 42,190,238,117, 17, 41,134,144,148, - 65, 64,110,194, 70, 91, 33,184, 13, 65,216,180, 43, 96, 89, 13,140,198, 28,216,138,254,225,155, 39,151, 71,229, 54, 95, 74,188, - 42,182,188,160,138,143,122, 3,159,125, 59, 11,205,152, 46, 0,128,231,255,222, 11, 3,135, 69, 99,221,231,121, 88,249,223,119, - 84,138, 81,254,185, 14, 9, 1,228, 47, 29,119, 14,122, 15, 63,252, 48,246,239,223,239,149,252, 1, 96,198, 52,145, 10,216, 7, -224, 56, 42,175, 55, 67,207, 46,192,170, 85,181, 80,169,128,158, 61,129,232,104,187,136,202,235,205,236, 47,227,128,223, 84,191, -254,210,153,120, 34,255,125,251,246,129,101, 89, 39, 73,111,220,184,177,209, 4,226,186, 93,159,252, 1,192, 27,249, 3, 64,150, - 66, 65, 40, 32, 33,128, 58, 61, 61,189,193,142,207,186, 12,250,138,236,108, 41, 33,192,202, 47, 86,222, 22,243,178, 50, 75,225, -234, 95,145, 80, 74, 85,159,124,242,137,115,199, 39,159,124,130, 21, 43, 86, 32, 43, 43,171,110, 21, 57, 2,137, 59,121, 89,246, - 20,182, 82, 74,169,250,185,231,158,107,176,125, 86, 23, 47, 74,246,170, 85, 82, 66,128,172,149, 89, 42,119,228, 37,108,222, 28, - 16, 9, 96,211, 87,226,183, 29,123,177,110, 83, 46,190,184,114, 30, 0, 80,248, 78, 11,244, 28, 61, 1,166,210, 75, 56,241,203, - 17, 28, 59,127, 6, 85,215,174,225,248,241,227, 77, 86, 88,107,205,154, 53, 18,126,125,152,132, 83, 74,123, 23, 21, 21,125,252, -230,155,111,246,251,248,227,143,131,204,102, 51, 4, 2, 1,154, 55,111, 14,157, 78,135,194,194, 66, 68, 71, 71,115,117, 11, 60, - 89,255, 97,132, 16,150, 82, 26, 85,121,249,224,143,239,252, 95,105,212,151,243, 58, 64,163, 11, 66,144,144, 65,167, 72, 49,174, -221, 52, 67,254, 79, 43, 6, 14,141, 13,235,226,197,147,144,145,145, 65, 57, 69,192,181, 47, 54,244, 61,128, 59, 15,142,252,235, - 43, 7,140,183, 65,132,171,247, 93,199,205,153, 52,195,231, 6,100,103,103, 83, 59,249,175,119,146,191,248,199, 11,208,239,122, -160,206,113,175,150,171, 98,189, 36, 92, 83, 3, 54, 72, 8,243,145, 19, 48,253, 86, 2,227,238,253,128,193,132, 32, 74, 17, 10, - 1,132, 32, 48,177, 86,104, 76, 70,124,177,103,155, 87,153,203, 22,217,173,123, 87,216,183, 57,115,133,226,244, 89,138,249, 75, -252,239,179, 50,153, 76,237,234,246, 82, 42,149,188, 94,116,165, 82,233,172,173,205,225,233, 21,151,177,247,136, 22,165,215,141, - 78, 37,160,248,178, 1,144,109,130, 82,169,228,229,142, 20, 18,123,229, 48, 81,205, 49,132,133,157, 69,176,184, 6, 44,171,129, -197,114, 4, 2, 65, 52,204,186,138,187,214, 89,247,126,115, 92, 2,144, 58,228,127,245, 52,197,144, 73, 2,252,253,253, 68, 60, -156,216, 15, 0,117,156,231, 27,214,175, 95, 79, 95,254,128,160, 89,235, 1,160, 0,146, 38,207,193,129, 3, 7,120,253, 45,203, - 92,162,109,218,252,234, 36,255,154, 10,123, 9,230,129, 3,237,228,207, 21, 2,180, 31, 11, 65, 77, 69, 8,162, 66,175,122,148, -153,156,156, 12,169, 84,138, 49, 99,198, 96,234,212,169, 16, 8, 4,183,125, 92,247,243,133,187,247,214, 47,101,201,133,136, 9, - 33,206, 79, 67,251, 8,160, 6,133,186, 1, 89,183,222,175,244,116,149, 59,203,121,222,188,121, 72, 79, 79,175, 75,168, 13,200, -251, 86,161,192,241,227,199, 85,132, 16, 9,128, 58,247,204,233,207,174,183,207, 83,251,130, 40, 5, 19, 26, 12,203,181,139, 80, -188,241, 6,214,232, 42,161, 77,136,115, 30,255,242,191,107,240,246,130,217,136,153,255, 52,222, 61,182, 15,155,180,231,145,248, -216, 99,136,142,142,246,121, 10, 96,205,154, 53, 18,185, 92, 78, 87,175, 94, 93,167, 15, 23, 20, 20,168, 60, 77, 67, 17, 66, 68, -132,144,161,199,142, 29, 43,205,203,203, 83,191,252,242,203,113,159,125,246,153,184,182,182,214, 89,166,217,104, 52,162, 89,179, -102,197, 83,166, 76,233, 53,114,228,200, 46, 94, 20, 9,134, 16,210,245, 88,254,230,242, 51,187,230, 95,152,255, 90,102,251,173, -139, 59,224,183, 50, 33,170,106, 5, 96, 9, 80, 81,107, 6,109,217,195,248,210,235, 75,250, 61,250,196, 95,188, 78, 39,100,101, -101, 17,110,172, 83, 40, 20, 94,191, 7,112,119,200,223,173, 7,192,149,248,249,140, 51,190, 88, 34,183, 92,109,171,221,122, 7, -234,196, 25, 52,224,198,232,215,170,173, 74, 67, 45, 8,170,208, 64,252,237, 62, 16, 33, 3, 24,205,160, 53, 58, 16,171, 21, 34, - 0, 54,202,194,104,179,162,198,106, 6, 88,239,115,168, 92,144,223,178, 69, 13, 15,131,246, 32,193,198, 15,168, 10,133,130,112, - 46,125, 62,214,250,109,214, 63,128,255,189,208,190,206,246,208, 87, 75, 32,162, 55, 97, 33,173,144,147,147,179,143,175, 23, 64, - 92,171, 66,212,187,255,197,141,151, 51,112, 83, 19,130, 14,150, 19,176,217, 74, 0, 0, 23,127,110,119,215, 58,236,166,157,159, -170,102,143, 83,212, 33,127, 14,113,145,111, 96, 68,191,100,196, 71,157,192,166,157,239,171,198, 78,230, 63,136,172, 91,183,142, -254,240,195, 15,168,168, 24,139,150, 45,247,162, 89,171,254,160,148,130, 97, 24, 94,129, 72,165,165, 64, 73,201,113,110, 34, 1, - 16,215, 66,163, 3,134, 13,179,239, 41, 46, 6, 62,255, 28,168,169, 6,116,181, 64,173, 14, 8,139,172,230,213,182,134,230,250, -207,157, 59, 7, 0,248,224,131, 15, 0, 0, 49, 49, 49, 77,230,102,118,237,147,124,254,102,238,220,185,112,181,216,235, 19,183, - 15,144, 0,183,230,254, 93,193,121, 1, 28,231,168, 61, 9,153,213, 49, 6,103, 78,156, 68, 89,100,164,138, 97, 24,188,248,226, -139,248,215,191,254,229,119,251, 70,153, 34, 64,217, 90,204,254, 96, 17, 6, 36, 39, 67,241,193, 7, 96,152, 91, 60,167, 40, 62, -126,203, 67,184,127, 63,246,236,217,131,243,231,207,251, 28, 4,184,102,205, 26, 73,126,126,190, 10, 0, 10, 11, 11, 85, 12,195, - 72, 83, 83, 83,213,171, 87,175,150, 80, 74, 17, 31, 31, 47, 53, 24, 12,170, 6, 20, 59, 75, 65, 65,193,128, 25, 51,102,180,232, -222,189, 59,118,236,216,161,175,170,170, 18, 26, 12, 6,187,183,195, 49,255, 49,126,252,248, 24, 66, 72, 8,165,212,224, 70, 12, -227, 34,143, 41, 57,253,243,138,183,255,145,214,172,101,207, 28,252,148,243, 44,126,189, 68, 80,122, 93, 8, 80, 6, 38,179, 5, - 26,218,178,236,111,179,158,143, 35,132,148,209, 38,208, 42,249,196,217, 4,240,251,160,193, 41,128,188,188,188,219,246, 85,150, -105,125, 38, 59, 87, 15,128,125, 10,192,222,127,196, 63, 94, 64,240,241, 50,216, 34,236, 86, 84,253, 57,228,134,214, 53,158,188, - 92, 10,125,112, 8,162,173, 86,116, 10,105,134, 80, 81, 16,136,197, 2,176, 20, 86,155, 13, 53, 54, 51,244, 54, 43, 76,212, 6, - 27, 40,168, 15,157,109,254,146, 91, 74,128, 61, 46,224, 22,233, 47, 91, 36, 64,230, 34,130,151,151, 88, 27,125,211,101, 50,153, -154, 43, 93,202, 7, 11,115,236,247,125,105, 74,164,147,240,157,174,124,122, 19, 34, 0, 66,170,197, 87,179, 35,173, 79, 43,249, -197,117,136,174,255, 8, 27,236,110,234,143,133,225,120,250,250, 69, 20,253,179, 19,194,218,245, 65, 85, 89, 25,174, 93,184,114, - 87, 59,230,192, 97,209,208, 57,186,155, 62,228, 36, 66, 13,125,241,245, 59, 22,231,241,145,178,126,200,223,228,155,229, 63,121, -244, 15,248,246, 91, 25, 34,242,149, 88,190, 8,120,105, 9,197,232,209,163,121, 47,251,235,214,169, 51,233,209,163,174, 22,184, -109,155, 61,240,111,253,122,160,103, 79,138, 21, 43, 8,222,125,183,214,174, 32, 0,232,217, 43, 18, 47,191,196,175,141,156,149, -154,156,156,140,141, 27, 55,214,177,100,147,146,146, 26, 36, 55,127, 21, 81, 31, 61,120,210, 21, 43, 86,168, 26, 82, 0,150, 45, - 91,134,236,236,108, 94,150,240,115,207, 61,167,226, 34,255,221,225,165,151, 94,194,242,229,203, 85,217,217,217, 30,219,248,195, -201, 82,188,254,238, 2,204, 90,252, 15,188,102, 54,227,147, 79, 62,105,240, 30, 45, 91,182, 12, 74,165, 18,132, 16, 73, 67,132, - 61,186,111, 23,172,254,242,115,196, 78,159,142,119,222,121,199,163,210, 48,111,222, 60, 44, 91,182, 12,171, 86,173, 82,251,122, -239,243,243,243, 85, 92,176,156, 92, 46,167, 5, 5, 5,170,212,212, 84,114,248,240, 97, 21, 33, 4,169,169,169,234,149, 43, 87, - 54,248,247,122,189, 62, 98,219,182,109, 24, 59,118, 44,138,139,139, 67,117, 58, 29, 44, 22, 11, 24,134,129,217,108, 70, 74, 74, - 10,113,144,187,129,143, 99,203,100, 50, 5, 29,217, 60, 29,163,159,124, 23,187,242,206,225,252, 85, 1,170,117, 12, 4, 66,160, - 76, 23,130, 23, 95, 93, 20, 15,224, 50, 95,238,231,226, 78, 0,126,211, 1, 1,220, 29,235, 31,238,220, 56,156,107, 70, 34,145, - 64, 34,145,224,151, 95,126,113,126, 74,126,188,136, 42, 67, 21, 90, 14,243,125,221, 47, 71,238,161,161, 51, 32,254,241, 2, 68, - 23, 43, 64, 9, 65,208,172,138, 58,199,189, 18, 87,144, 0, 54, 10, 92,214, 85,162,180, 74,131, 27,213, 90, 84, 25,141,208,154, - 13,184, 97, 50,224,170, 81,143, 50, 99, 45, 52, 22, 19,180,172, 5,102,214,123, 54,204, 81, 15,185, 25,240, 92,226, 2,102, 79, -109, 6,138, 32, 80,223,202,128, 59, 93,248,245, 59, 59, 95,247,191,211,242,188,110,196,222, 35,218, 58,196,207,145,127, 48,123, - 17,193,236, 69,188, 61, 94,136,210,210, 82, 51, 95,153,155,207,179,104,157,153,229,220, 62,175,179,225,242,185, 50,156, 62,120, - 2,215, 46, 84,222,245,142,187,254, 11,187, 2, 90, 93, 78, 17,106,232, 11,201, 44, 33,158, 92, 44,114,126, 50, 55, 77, 7, 1, -225, 61, 32, 61,254,112, 30,158,157, 47, 67,100,193, 94, 16, 66,240,221, 65,251, 35,224, 75,254, 28, 98,122,247,170,167, 88, 0, -159,125, 6,156, 61,107,247, 4,188,243, 14,117,186,223, 41,165,136,140,140,244, 62, 2, 59,250,168,205,102,131,205,102,195, 7, - 31,124,128,115,231,206,225,204,153, 51, 56,115,230, 12,148, 74, 37, 22, 44, 88,128,210,210,210,187,249, 72,212, 13, 89,210,115, -231,206,229,172, 58, 94,100, 72, 8,113,107,253,115,240,116,204, 21,251,131, 43, 65,152,102,248,247,235, 75,208,108,155, 18,233, -233,233,112, 45, 53, 44,239,217, 31,115, 99, 71, 32, 52, 52, 20,163, 71,143,198,155,111,190, 9,165, 82,169,210,106,181,110,223, -191, 47,203,206,224,106,191,190,232,216,177,163,148,101,217, 6,189, 29,156,167,194, 95,207,139,107,164,124,124,124,188,148, 35, - 74, 0,136,139,139,147,122,185,119, 99, 70,143, 30,221,162,180,180, 20,251,247,239,199, 3, 15, 60, 0,161, 80,232, 84, 22, 59, -118,236,200,119, 58,130,117,200, 35, 61,122, 15, 94,152,189, 59, 2,191,238, 88,140, 81,241,125, 16, 38,102, 16, 22,106, 67, 72, -176, 9,143, 60, 62,133, 5,160,169,175,171,122, 83, 46,185,235,227, 51, 29, 16,192,221, 3,227,233, 33, 42, 20,138,230,115,231, -206,197,220,185,115, 1,192,252, 94,198,123,176,148, 91, 17, 18, 34,246, 43, 25, 73, 74,138, 61,124, 56,116,252, 89, 80, 1,131, - 55,191,214, 59,173,127,190, 8,237,216, 81,106,109, 22, 10, 45,181,225,164, 78,139,227, 85, 21, 56, 81,125, 19, 39,170, 53, 56, -169,211,224,172, 94,139, 10,147, 17,181, 86, 43,174,232,117,206,223,244,132,201,227, 8,150, 45, 18, 96,217, 34, 1, 40, 4,160, -132, 65,250, 52,130,231,166, 5, 97,214,212,214,232,209,163, 45, 88,136, 0,248,118,201,156,171, 63, 37, 37, 69, 90,127,159, 15, -247, 76, 90,124,217,174,200, 23,125,100, 15,162,219,245, 74,184,221,125, 67,181, 16, 80, 29, 76,140, 61,162, 89,163,209,132,166, -164,164,248, 84, 20, 61, 54, 54, 22, 74,165, 18,235,107,117, 48,152, 25, 60,187,225,223, 40, 23,135,192, 96,190,123,101, 34, 38, - 13,124, 91,154,175, 89,130,245,255,185,101,226,127,253,142, 5,113,145,111,220, 82, 40, 31,253, 92,154,165,200,226,149, 91, 98, -249, 27, 64,234,252,177,136, 40, 80, 66,250,207, 4, 48, 19, 1,181, 90,237, 87, 31,238,218,181,110,244,248,152, 49, 64, 68, 4, - 16, 29, 13, 12, 31,216, 28,226, 32, 1, 4,204, 45,177,226,144, 16,175, 3, 50,195, 48,206,185,254,115,231,206, 33, 38, 38,166, -206,231,221,119,223,197,187,239,190,139, 43, 87,248,123,101,220,205,215,187, 34, 35,195,119, 11, 44, 59, 59, 91,186,124,249,114, -183,132,205,215,250,119,113, 61,223, 22,167,192,109,179, 44,191, 20,246,102, 66,192,234, 77, 16,181,235, 10,249,251,239, 35, 53, - 44, 2, 17,234,124,231,241, 89,127, 73,197,219, 31,255, 27,197,203,254,135,183, 6,140,193,148,200,238,216,179,101, 11, 74, 74, - 74,220,190,127, 79,100,200,209,175,127,127, 41, 23,212,200, 41,100,174,211, 51,238,246,121,176,190,104, 70, 70, 6,229, 2,251, -184,249,126, 87,146, 79, 77, 77, 85,199,197,197, 73, 57,215,127,106,106,170,218,203,125,203, 19,137, 68, 15, 60,241,196, 19,231, -170,170,170,160,213,106, 17, 18, 18,130,214,173, 91, 35, 34, 34, 2, 17, 17, 17,222,110, 30, 91, 79,158, 45, 56, 56, 88,255, 84, -198,191,164,107,126, 28,138, 11,151,170,209, 54, 92,128,248, 94, 4, 15,118,167, 8,107,209,162, 18,128,205, 3,111, 4,234, 13, -220,167,214, 63,224,125, 25, 96,173, 66,161, 8, 6, 16, 38,151,203,157, 90, 96,167,132, 14,126,105,190, 10,133,130,200,100, 50, - 40,149, 74, 26, 52, 43,167,142, 43,146,111, 30,128,150,143,141, 85, 87,228,236,128,222,106, 66,181, 78,143,115, 22, 11, 68,172, -221, 81, 95,101, 49,130,165, 20, 20,192,142,235,231,161,179, 90, 0,128,199,192, 68, 48,127, 73,221, 62,110,159, 10, 96, 97,131, - 9,191,157,173,193,234,141,213, 62, 93,175, 43,209,203,100, 50,117,125, 47,128,171, 82,224, 9, 50,153, 76,157, 35,159, 2,209, -216, 47, 0, 68,163,162,226, 86,112, 94, 16,123, 21,102,166, 61,254, 54,224, 12,174, 94,181, 15,196, 10,133, 98, 47, 31,185, 25, - 95,103,215, 81,188,114,114,114,192, 77, 74,108, 56,118,200,167, 85, 25, 77,141, 71,159,111,175,222, 42,167, 56,168, 60, 1, 0, - 24,209,207,158, 25,239, 31,243, 22,227,208,137,126,248,120,211,116, 40,182, 61,175, 82, 76,226, 71,224,207,206,151, 33, 42, 74, -233,106,200, 66,163,145,129,210, 28,135,171,146, 34, 39, 39,133,151,172,228, 39,159, 34,123,118,237,166,128,221,245, 47,149, 18, -220,188, 20, 14,157, 86, 12, 67,117, 16, 54,172, 37,152, 59,151,226, 98,121, 13,134,199,199, 97,250,212,105,188,172, 98,155,205, -230,156,239, 87, 42,237,109,117, 37,252,242,242,114,148,151,151,251,236,222,151,203,229,148, 97,152,219, 72, 53, 43, 75, 65,252, - 72, 2,164,166,148,214,137, 5,112,241, 8,240,118,133,187,186,246,235, 71,239,123,115,251,215, 87,114,172, 53, 53, 16,181,138, -130, 32,180, 25,250, 61,149,140,119,199, 37,226,117,110,217,222,224, 33,176, 25,140, 16,181,108,139, 1,113, 18,116,235,212, 29, -255,250, 45, 31,253,251,247,151,254,248,227,143,183, 41, 1, 25,114, 57, 0,162, 2,128,231, 51, 50,156, 75, 7,173,245,200, 94, - 40, 20, 0,244,214, 66, 69, 2, 96,160,155, 65,118,208,160, 65,132, 82,234,116,241, 23, 22, 22, 58, 93,252,174,231, 57,182,189, -146,191,195, 96,127, 35, 34, 34,162, 95, 92, 92, 92,143, 83,167, 78,225,232,209,163,176,217,108, 8, 11, 11,131, 94,175, 47,143, -138,138,186,224,139,209, 71, 8, 97,218,182,109,187,231,241,199, 31,111, 91,112,160, 16, 43,114,246,160, 5, 9, 66,175,182, 38, -156,189, 25,134,135,123, 89,206, 3,176,112, 10,154, 67,161,180,121,122, 38,174, 99, 93, 96, 10,224,222, 6,159,249, 98, 51, 0, -179, 43, 81, 95,206,187, 2, 76,247,157,252, 93,201,198,221,160,197, 87, 9,168,214,104,165,150, 80,177,170,138, 97,113,205, 88, - 11, 88, 44,176, 81, 10, 2,224,183,218, 74,148,233,171, 65, 41,229,146,216,240, 24,152, 40,210,167, 17,100,111,184,213, 39, 79, -157, 3,122,247,176, 66, 0, 93,163,200,223,181,179,251,235,242, 74, 73, 73,145,230,228, 60,175, 2,138,160,209,104,204,165,165, -165,194,165,137, 96, 22,238, 25,141,121,253, 15, 57,173, 48,190, 74,133, 59,175, 75,253,109,142,132,248, 90,115, 88, 76, 48, 52, -187,132, 2,238,151,251, 57, 51, 1, 42, 65,249, 4, 41,102, 76,250, 66,170,216,250, 55, 85,254, 38,138,248,168, 19, 24, 41,235, -135, 3,123, 78,160, 64,251, 62, 8, 8,228,147, 62,231,125,173, 81, 81, 74, 16, 66, 48,121,242,100,172, 90, 85, 13,206, 40,182, -255, 79, 29,247, 56,167,206,128,228, 97, 10, 22, 9, 99,164,210,188,125, 42,213,152, 49,128,249, 90,103, 92,170, 12, 6,235,152, -109,109,175,107,139, 87,210,107,176,167,160, 23,154,119,234,197,171,141, 28,241, 95,190,124, 25, 0,112,237,218, 53,167,103,224, -250,245,235,206,129,213, 31, 40, 20, 10,194, 37, 2,170, 63,135,155,165, 80, 16, 62,249, 0, 92,177,106,213,170, 58,177, 0,203, -151, 47,247,217,250,175, 79, 24,254, 66, 44, 22,227,218,197, 11,232,222,163, 39, 88,171, 9,196,106,131,176,121, 11, 52, 31, 50, - 20,205, 6, 63, 4, 86,103,133, 77,111, 2,181,218, 0, 27,139,133, 43, 63,198,212,233, 83, 33, 22,139,221,202,179,110,136,228, -245,187,238,206,139,253,208,253,185,241,241,241,210,130,130, 2, 21, 55, 6,140, 28, 57,210,237,189,226, 65,254, 32,132,176, 0, -118,246,234,213,107,240,167,159,126,106,190,113,227,134, 49, 49, 49,241,241,162,162,162,183,244,122,125, 69,171, 86,173,228,125, -251,246,213,248,112,239, 69, 0,186,196, 13, 31,222, 58, 99, 86, 6,206, 95, 62,175,121,102, 86,198,168,195,123,214,102, 94,173, -209,140, 24,154,144,200,182,237, 20,243,164, 27,175, 1,235,105, 44,112,229,138,134,146,255, 4, 18, 1,221, 63, 10, 64,131,214, -133, 63,228,207,145, 13,151, 19,192, 31, 37,160,187,124,134, 26, 0, 41, 83,172,161, 8, 17, 67, 75,173, 48, 91,173, 96, 41,139, -150,225,225,184,172,171,226,151,193,206, 1,119,203,251,110,197, 0,248,150,137,205,157,139,191,177,233,122, 29,127, 59,105,232, -208,161, 91, 23, 46, 92, 24, 20, 21, 21,197, 94,189,122, 21,243,250, 95,173, 67,254,190,252,134,187,251,239, 55, 28, 89,254,234, - 39,121,114,119, 14, 95, 12,126, 84,160,206,122, 52,139,108,249,236,138,100,251,177,119, 84,249,155, 0, 2,130, 73, 3,223,150, - 62,250, 60,255, 4, 64, 92, 95,178, 19,124,181, 99,144, 2,220,241,206,154, 76,187,243, 36,172, 75, 22, 1, 26, 46,174, 49,125, -234, 52,245,244,169,211, 72,133,246, 83,137,173,166, 70, 69, 4,128,222, 24, 2, 82, 99,133,144, 17, 66,207,136,165,227,166,204, -134,144, 18,175,237, 76, 76, 76, 36, 15, 60,240, 0,189, 83,239,159,221,218,207, 34, 25, 25, 25,212, 53,162,221,213, 19,224,163, - 56, 53,103,249,187, 40, 20,234,187, 49,120,141, 25, 51, 6,127,219,148,141,119,107, 42, 49, 40,225, 97, 48,109, 35,237,109,178, - 80,123,234, 94,136, 64, 4, 66,144, 32, 1, 86,101, 45, 67,139,177, 67,209,163, 71,143,223, 53,117, 47,103,221,231,231,231,171, -134, 15, 31, 46,157, 57,115,102,163,126,251,220,185,115,178,189,123,247, 94, 20, 8, 4, 91, 70,141, 26,245, 30,195, 48, 55,226, -226,226,242,156,150,140,139, 71,137, 16, 2,119,207,220,197, 19,160, 60,122,244,232,176,175,214,172,101,130, 4,193,151,146,159, - 78, 30,200, 48,140,246,225, 9,179, 39, 2, 8,119, 16,127, 13, 0,106,181, 90,157,242,234, 41,109,129,146,242,247, 32,248,184, -255,253, 82, 0,154, 66, 97,240, 68, 62,190, 12,112, 82,121, 42, 81,238, 81, 74,216,211,197, 42,157,201, 12,171,205,134, 30,195, -134, 32,198, 58,220, 39, 50,108,202, 96, 20, 46,233, 15, 0, 21,231,233,112,153, 10, 32,141,144,187, 77, 38,147, 9,149, 74,229, -252,165, 75,151,254,211, 69,185, 24,163, 80, 40,124, 74, 68,226,240, 20, 52, 89,242,146, 41,191,165, 56,238, 99,195,215, 55, 69, -169,244, 75,211,127,236,133, 14,234,199,208,248,231, 99, 39,119,130,103,231,143,113,230, 41,231,198,177, 53,153,123, 17,214, 37, -139,132,117, 73,241, 73,102, 68,139,191,171, 15, 94, 4, 97,153, 75, 18,131,222, 94, 7, 32, 76, 44, 83,135,119,132, 79, 43, 70, - 93,250,159,200,161,113, 54,249,188, 42,167, 4, 52,133, 44, 71, 44,128,138,251,222, 88,121,254,174, 44,235,209,163, 7,218,189, -248,162,116,197,238,221,170,146,247,190, 69,138,168, 37, 34, 28,197,123, 12,122, 43,230, 46,120, 13,130,208, 40,236, 88,171,192, - 47,173, 8,198, 53, 34,111,191,205,102,133,175, 49, 64,245,149, 0, 62, 86,190,151,251, 68,206,156, 57,115,131, 82,154,217,187, -119,239,255,171,168,168,208, 9,133, 66, 88,173, 86,218,178,101, 75,167, 71, 69,167,211, 33, 40, 40,200,233, 69,242, 32,111,116, - 97, 97, 33, 88, 43,193,136,145, 3,223,190,124,249,178, 86,163,209, 32, 42, 42,138,237,212,169,147,150,123, 54, 85, 85, 85, 16, -139,197, 32,132, 32, 56, 56,152,151,209,199, 41, 9,245,191,215,247,138, 6,112,159,121, 0,238,148, 82,224, 55, 49, 38,202,212, - 72,148,221, 83,209,164, 14, 37,128,220,129,121,116,155, 76, 38,251,127, 50,153,236,255, 53, 69,251,154,240,122, 73, 83,156,115, - 39, 97,183,234, 1, 71,138,253,122,199, 82, 26, 37,155, 97, 59,171,195,196,157,155,162,153,150, 59,121, 15,154,176,232,138,218, -151,185,122, 47,202,132,223,114, 40,165, 36, 52, 52, 20,147, 39, 79,134,163,124, 47, 74, 93,202,247, 30,220,187,199, 89,190,119, -108,220, 88, 56,148,222, 6,127,111,149,246, 67,242, 92,228,107,183, 19, 19,207,106,130, 60,148,128, 70,227,161,135, 30, 50, 89, -173,214, 60, 0, 58,150,101,169,217,108, 95,248,115,227,198, 13, 0, 64,179,102,246,165,189,220,126,145, 72,228,241,254, 61,250, -232,163,156,140,221, 44,203, 34, 34, 34, 2, 44,203, 58, 87,156, 56, 86,177, 16,163,209, 72, 1, 32, 65,144,246, 25, 0, 0, 32, - 0, 73, 68, 65, 84, 40, 40, 8,132, 16,230,247, 24,219, 3,240, 31,124, 82, 73, 3, 0, 25, 52,104, 80, 64, 19, 11, 32,128, 0, - 2,184,127, 96, 5, 96, 4, 32,110, 98, 35,206, 91,193, 32,222, 21, 5, 3,184, 63, 16,120,152, 1, 4, 16, 64, 0,247, 23,132, - 0,154,241, 32,127, 61,236, 65,220, 77,197, 7, 44, 2,203,254,254,112, 29, 41,128, 0, 2, 8, 32,128, 63, 30, 66, 3,124, 17, - 64,192, 3, 16, 64, 0, 1, 4, 16, 64, 0, 1, 4, 20,128, 0, 2, 8, 32,128, 0, 2,248,179,163,142, 75,103,206,156, 57,126, - 71,112,186, 43,222,115,175,203,139, 30, 18,140,144,224,107, 16, 5, 85,130,101,237,203,194, 4, 2, 6, 12, 17,216,255,103, 8, - 8, 97, 64,137,208,190, 6, 22, 86,108,221, 46, 2,165, 20, 81, 76, 75,248,216,190, 96, 0,173, 96, 15,224,169,129,125,185,151, - 5,142, 57,181,251,241,254, 5,228, 5,228, 5,228, 5,228, 5,228,221,155,242,124, 86, 0,254,108,248,225,192, 89, 12, 27,106, - 65,100, 4,160,209, 18,252,244,139, 24, 66, 70,136, 9,227,109,216,163,106, 13, 66, 24, 16,134,129,184, 57, 48,102, 88, 37, 0, - 33, 30,142,167, 40, 44, 18,218,105,156, 7, 84,135, 14, 80, 0, 16, 81, 11,134,143, 26,115,241,204,175, 63,154,202,171,141, 49, - 54,189, 17, 50,153, 44, 2, 64, 85, 64, 15,189,191,145,251,245,127, 36, 61,123,116, 87,221,184, 97,108, 84,194,167,251, 8,146, -244,244,116,215, 60, 0,141,186,230,244,244,116,191,211, 1, 7, 16, 64, 0, 77,228, 1,224,176,246,171, 47,121,107, 19,207,206, -156,229,245,101,109,106,121, 77,137,194, 34, 17,146, 18,109,248,229,215, 16, 4,137,132, 16, 10,132, 16,137, 40,130, 5, 22, 64, -216, 28, 66, 24, 48,172,159, 21,226,160, 96, 80, 0,237,219, 2,143, 77, 96,177,119, 11, 63,242, 63,251,219, 25, 60,208,183, 7, - 58,116,140,192,229,139,167,186,134,183,235,142, 86, 29,108,248,254,187,239,160, 84, 42, 43,239,246,250,120,165, 82, 57, 33, 39, - 39,103, 59,183,157,146,146,242,168, 76, 38,219, 30,120, 53,188,227,215, 95,148,212,106, 60, 33,157,246, 88, 15, 21,203, 86,160, -170,131, 65,117,234,248, 38,212,154,218, 99,104,236,168, 63, 44,137,165,167,167,171,230,205,155, 7, 66, 8,175,178,189,124,192, - 37,139,105,130,114,243, 1, 52, 82, 1,243, 8, 74,145,189,106, 85,131,207,155, 75,240,227,154, 45,144,171, 33,224, 82, 75,192, -249,156, 93, 43, 35, 6,208,180,224,178, 1,114,112,151, 27,224,158,242, 0, 48,248,125,251,193,132,113, 22, 80, 8, 32, 20,136, - 48, 98, 56, 65,155,214, 12,132, 66, 6,193, 34, 1,122,199, 48,184,120,201,138, 97,177, 12, 90, 70,137,241,253,190, 22, 0, 0, - 1, 53,192,158, 10,219,230,149,252,127, 45, 42, 66,183, 14,157,240,107,126, 1, 14,155, 45,208,222,212, 34, 40,184, 57,250, 12, - 30,137,129, 35,199, 65,181, 53, 7, 0,191,220,248,119,128,248,199,228,228,228,236, 93,184,112, 33,138,138,138,184, 14, 83, 9, -224,197,217,179,103,111, 75, 73, 73,145,201,100,178,189,127,184,151,226, 39, 37, 13, 22,106, 32,100,204, 48, 26,109,168,210,133, -224,225,209, 83,124,186,255,155,114,191,146,180, 8,209,224, 47, 83,135,160, 91,215,199, 84, 45, 90,132,195, 98,181,226,198,141, -155,104, 91,122, 9,197,231, 74,112,232,160,134,142, 24,249,184, 95,207, 53, 59, 59,155,186, 12,206,247,218,224, 40, 1,110,149, -195,117, 84, 7,148,224, 46,165, 3,254, 29,223, 23,186,121,243,230,219,235, 41,220, 53,242,162, 18, 2, 2,218, 4,247,157,150, -126, 13,114,120,182, 43,199, 59,178,100, 58,170, 33,185, 96,118,150, 14,195,166,126,234, 81,145,251,254,251,239,157,219, 73, 73, - 73,216,185,115,167,199,237, 0,238, 60,249,187,238,115, 85, 4, 60, 42, 0, 7, 15, 28,198,200,135,135,255,110,141,102,125,200, -159,234,154, 74,210,223,236, 83,140, 80, 0,173, 70,136,118,109, 68,104,215, 38, 8,181,181, 34,136, 69, 66,216,132,193, 24, 50, -128, 96,208,131, 2, 48, 68,100, 79,129, 41, 10,130,136, 49,129,136,131, 96,213, 3, 86,232, 60,146,255,129,125,123,209,189,125, -107, 28,255,229, 56, 22,189,247,118,157,246, 45,121,231, 3,202, 8, 8,134,196, 14,193,247, 59,247,250, 84,121,143,101, 89, 73, - 81, 81,145,234,236,217,179, 8, 9, 9, 65, 72, 72,136, 52, 41, 41, 73,237,227, 96, 38,205,201,201,217,203, 17,191, 75,231,136, - 0, 48,238,223,255,254,247,205,217,179,103, 43, 1, 36,202,100, 50,229,189,216,193, 87,175, 94, 45, 73, 75, 75,227,125,221,255, -219,184, 86,210, 63,166,185,170,107,123, 35,194, 91, 4,131, 97, 66, 97, 48, 88, 81,161, 49, 32, 79,185,130,138, 91, 12,193,240, - 97,163,121,245, 35, 17,174, 97,242,163, 15,170,250,245,235,131,171,215,180, 56,242,211, 81,212,214,234, 16, 30,222, 28,209,209, - 93,193, 8, 68,176,217, 74,241,211,207, 7,232,224, 65, 15,255,161,172,155,244,244,116,213, 75, 47,189,228,220,158, 55,111, 30, -150, 47, 95,174, 90,229,193, 42,244,137,140,238, 81, 15,128, 67, 73,167,185,185,185,112, 87, 88,233,247,132,171,149,173, 80,100, - 73, 41,109,156, 18,192,116,125,202, 73,222,133, 31, 54,115,107,134,181,139, 96,208, 49,138,185,111,159,223,159, 21,174,100,239, - 78, 41,240,234, 1, 56,120,224, 48, 0, 52, 90, 17, 56,240, 98,177,199,227, 15,255,171,167,223,131, 5, 33,196,175,106,123, 74, -117, 27,136,132, 34,116,238, 80,139,154, 26, 17,142, 28,239, 12,129, 64, 0, 1, 17, 32, 72,100, 69,191,158,122,244,234, 41, 0, - 1,131, 32, 81, 48,130, 4, 4,177, 15,154, 17, 21,201, 98,253,255,121,150,221,167,123, 91, 92, 60, 87,126, 27,249, 3,192,162, -197,175,147, 15,222,251, 39,109, 31,255, 32, 34, 35,154,243,110,175,193, 96,144, 44, 95,190, 92,117,241,226,197, 58,250,134,201, -100,194,227,143,243,183, 54,115,114,114,246,185,146,191, 27,180,202,204,204,172,124,249,229,151,247,220,237, 41,138,134,200,255, -240,225,195,170,180,180, 52,222,109,139,137,142, 82,117,108, 91,141, 86, 45,195,208,169, 99, 59,132,134,133,226,226,197, 50,216, -108, 44, 58,118,104,142, 19,191,229, 99,205,233, 98, 73,234, 51,179, 60, 14,166,199,142, 29,160, 79, 78,234,131, 46, 93, 58,225, -228,111, 23,113,228,200,111,184,113,179, 6,148, 2,145,145, 33,208,235,107, 49,120,112, 63, 84, 86, 86,161,236,200, 79,248,234, -191,103, 36, 51,255,194, 95, 81,185,199, 33, 1,236,197,167, 56,124,242,201, 39,220,182, 79, 94,128,244,244,116,234,234, 18,118, -181, 32, 93, 93,210, 77, 49,189,240,222,123,239,209,206,157, 59, 55, 58, 23,191, 76, 38, 35,132, 16,186,105,211, 38,143, 57,246, - 57,100,100,100, 80,119, 30,130, 53,107,214, 72,184,226, 64,238,148, 88,185, 92, 78, 27, 74,229,234, 90,207,129, 82, 10,185, 60, - 67,213, 24, 47, 68,125,121,195, 94,171,197,143, 31, 54,171, 67,252, 1,220,159,214,127,253, 62,212,168, 41,128,198, 42, 2, 15, -255,171,103,131, 74,128, 63,228,207, 33, 47, 47, 15,101,101,101, 0,128,142, 29, 59, 82, 95,148, 0, 1, 53, 64, 72,108, 8, 18, -137,240,211,241,214, 16, 8,133,104, 46,210,217,227, 0,154, 49, 40, 43,107,142, 7,251,177, 32,132, 32,229, 49, 43, 40,203, 0, - 36,216,238,120, 67, 77,131,114,245,149,151,112, 77, 83,139,151,223,122,171,193,182, 84, 86,105,160,189,113,205, 33,139, 55,113, -215, 39,127, 0,192,142, 29, 59, 96,179,217, 36, 79, 62,249,164,215, 1, 78,169, 84,142,169, 95,250,151,235, 48, 85, 85,117,226, - 17, 35, 22, 47, 94, 12,165, 82, 57,246, 94,154, 10,224,200,223,151,191,249,223,198,181,146, 7, 99, 76, 8, 9,137,128, 56, 56, - 8,221,187,119, 67,231,110,221, 80, 93,173,134, 70, 83,139,160, 32, 1,162, 34,197, 16,134, 68,120,204, 21, 15, 0, 66, 90,134, -230,205, 90, 66,111,176,226,248,241, 98, 92,185, 86,133,171,215,106, 97, 48,137,209,165,163, 21,226, 96, 1,138,207,148,224,129, - 30, 61,112,229,106, 53, 12,214, 22, 94,101, 58,136,142,122,219,239,235,116, 64, 67, 50,253,145,197, 89,255,243,230,205,187,109, -255, 75, 47,189,228, 87, 44,128, 59, 18,173, 63,119,220, 84, 94,133,252,252,124, 21, 26, 89,144,103,239,222,189, 52, 39, 39, 7, - 41, 41, 41,112, 55, 29,192,199, 83,197,145, 63, 0, 20, 22, 22,170, 24,134,169,211,166, 53,107,214, 72,248, 24, 61,241,241,241, - 82, 78, 78, 83,120, 92, 54,189, 20,134, 41,203,117,110,137,191, 99, 20,227, 24,165,248, 61,222,164,164,164, 58, 94,146, 71, 30, -121,164,206,189, 10,184,253,239, 29,248, 28, 3,208, 84, 30,129,166, 68,113,177, 93,177, 40, 43, 43,243, 73, 9, 16, 10,133, 16, - 9, 68, 16,137, 8, 70,143, 4,244, 58, 19,206,159, 11,130, 72, 40,130,208, 38, 68,220,112,138, 32,145, 8, 2, 1, 3, 80, 2, -141, 22,248,241,168, 16, 44,203, 2,184,209,160,220,163, 63,157, 67,109,109,195, 25, 56, 63, 90,188,152, 6, 7,139, 97, 48, 84, -193,198, 90,121, 95,231,209,163, 71, 27, 86, 58,244,122, 94, 68, 83,223,245,239, 78, 51,220,186,117,171,235,249,202,187,225, 5, -112,231,226,119, 37,255,248,248,120,222, 85,232, 58,117,108,171, 98,152, 75,176,218, 88,152, 45, 86,220,184,169,129, 40, 72, 12, -147,201, 2,139,213, 6,171,149,133,213, 70, 81,169,189,233, 85, 86,144, 72, 7,113, 72, 39, 84, 84, 84,161,186, 70, 15,141,214, -128, 22, 45, 7, 98,196,131, 15,162,240,224, 78,116, 48, 91, 81, 85, 93,133, 94,189,122, 32, 56, 72, 8, 93,141,230,143, 50, 86, - 72, 40,165,206,185,127, 87,172, 88,177,194,175, 88,128,121,243,230,213,241, 38,212, 63,198, 87, 1,176,151,122,230, 44,218, 40, -140, 29, 59,182, 78,127,229, 12,132,210,210, 82,149, 82,169,244,171, 48,149, 82,169,116,146, 63, 55, 29,176,121,243,102,175,228, - 90,223, 83,149,159,159,175,226, 2,223,228,114, 57, 45, 40, 40, 80,165,166,166, 58,143, 23, 20, 20,168, 8,241,220,188,248,248, -120,169,107,153,225,140,140, 12,234,233, 94,121, 27, 15, 83, 82, 82,144, 28,175,196, 70, 0, 83,151,235,240,208,107,181, 30,239, -253,176,169,158,239, 85,253, 57,126,111, 49, 1, 1,220,121,111, 64, 67, 30,128,223,213,191,227,206,210,111,140,245, 95,207, 98, - 69,113,113, 49, 86,172, 88,193,187,212,164, 64, 32, 68,220, 48, 22, 2, 70,136, 31,139,196, 56, 93, 44,198,196,241,192,163,143, - 0,147,146, 8,218,183, 13,130, 56, 40, 24,226,160, 96,132,136,131,209,177,125, 48,196, 65, 98,136,131, 60,151,196,124,115,209, - 27,100,233,135,239,146,134, 6,146, 30,221,187, 34, 60, 34, 12, 98,214,140, 90,189,229,119,239, 20, 7, 14, 28,216,123,224,192, -129, 58,132,239,250, 1,128,138,138, 10, 76,154, 52,233,174, 89,249,133,133,133, 42, 87,107,136,219, 7, 0,195,135, 15,247,201, -146,179,217, 0,157,222, 2,157,206,140,234,106, 19,174, 95,215,226,202,149,155,168,169, 49,161,182,214,130,218, 90, 51,116, 58, - 11,170, 42,189,175,200, 52,153,172, 48, 26,109,176, 88,204,104,222, 60, 8,157, 59,182, 64,104, 88, 24, 0, 32,186, 71, 55,116, -234,208, 2,225, 45,196,160,212, 6,139,149,133,201,164,251, 67, 12, 36,233,233,233,170,249,243,231,123, 36,115,110,105, 32, 79, -239,132,212,161, 52,184,197,242,229,203,177,106,213, 42,159, 75, 13,219,221,226,114,234,250,225, 8,181,172,172, 12, 57, 57, 57, - 62,151,162,221,187,119, 47,205,205,205,117, 37,127,200,100, 50,146,156,156,236,241,239,230,204,153, 3, 66,136,211,170, 95,189, -122,181, 4, 0,226,226,226,164,174, 74,172,235,113, 74,169,243, 56,143,171,173, 99,197,187, 83, 28,188, 41, 19, 0,208,170, 85, - 43, 16, 23,235,161,177,242, 2,184,247,200,223,221,182, 95, 30,128,123,201,242,191, 53,192,219, 32, 16, 8,124,254,187,145,195, - 88,180,105, 29,140,234,106, 33,130,133, 86, 4, 7, 9,160, 62, 28,132,137, 82, 17,130, 68, 34, 84, 87,139,112,176, 40, 12, 45, -196, 4, 12,195, 32, 73,102,198,227, 19, 41, 24,134,226,253,159,125,111,167, 82,169,164,130, 80, 49, 52,162, 86, 8,181, 92,198, -217, 50,138, 49,146,209,188,255,126,240,224,193, 56,116,232,144,219, 99,161,161,161,188, 7, 75,173, 86, 59,214, 49,240, 32, 53, - 53,213,185,191,162,162,194,249, 61, 53, 53, 21,229,229,229,119,229,121,166,165,165,169, 11, 11, 11,145,159,159,175, 98, 89, 86, -202, 48, 12, 56,203,191,161,121, 83, 79, 40,189,116, 69,218,186,133, 94, 21, 28, 36,128,217,194,194,104,186,140, 75,151, 43,160, -209, 86, 67,163,209,163, 66, 99, 64,133,198,128,136,168,110, 94,101, 93,191, 73,113,237,250, 77,244,233,211, 3,149, 90, 45, 68, - 66, 6,213, 53,151,161,171,100,209,247, 1, 29,218,182,110,141,208,208, 80, 4, 7,135,224,234,181, 26, 16, 65, 36, 95,130, 37, - 46,228,216, 36,171, 0,154,122, 5, 65, 67,214, 58, 80, 39, 22,128, 47,212, 0, 48,119,238,220,219,188, 10, 46,211, 12,106,127, -218, 57,101,202,148, 58, 22,108, 78, 78,142,147,188,158,122,234, 41, 36, 38, 38, 18,190,137, 83,220, 88,254, 78,212,247, 52,212, -199,160, 65,131, 8,165,212,105,229, 23, 22, 22,170, 8, 33,206,210,192,169,169,169,234,252,252,124,228,231,231,171, 82, 83, 83, -201,225,195,135,157,199, 87,174, 92,217,160,220,252,252,124, 21,195, 16,105, 65,129,253,157,152, 51,103, 14,126,254,249, 39, 41, - 71,225, 5, 5, 5, 42,238,250,249, 40, 19, 43, 87,174,196,231,210, 72, 76, 93,161, 7, 96,159, 14,112,197,212, 21,122,231,253, - 76,147,138, 2,204,122,191, 40,237, 11, 63,170,171,116, 47,125, 21, 63,255,252, 51,255, 85, 0,119,130,248, 93, 99, 1, 26, 99, -253,215,181,228,235,146,127, 82, 82, 18,228,114,185,215,169,128, 86,173, 4, 96,136, 0,173, 91, 9,208,179, 7,197,149, 43, 66, - 48, 2, 2,145, 80, 8,145, 80,132, 95,143,133, 33, 42, 76, 4,129, 64,128,145,195,109, 8, 9, 9, 6,203, 82,128,218,252, 34, -255,102,109, 59,227,122, 45,133,238,172, 26, 66, 34,192, 43,139, 23, 17, 31, 7, 54,233,165, 75,151, 84,151, 46, 93,186,237,122, - 39, 79,158,204,107,176, 76, 73, 73, 73,172,168,168,216,195,145, 60, 0, 76,154, 52, 9,107,214,172,113,158, 83, 93, 93,141,242, -242,114,108,219,182, 13, 41, 41, 41, 99,238, 70,231,141,139,139,147,230,231,231,171, 10, 11, 11, 85, 92,176, 88, 92, 92,156, 95, -115,184, 51,255,146,166,222,240,191,108,208,178,106,232, 13, 22,104,131,141,160,208,194,104,180,162,186,218,132,242,155,122, 92, -185, 90,139, 81,210,174, 94,101, 25,204,173, 80,114,254, 6,162,187,119, 65,247,238,157, 80, 81,113, 19,145, 17, 54,244,236, 25, -142, 54,173,163, 33, 14, 9, 65,101,101, 45,142, 28, 61,133,203,101,213,104,215,169,223,125, 59,128, 80,128, 18, 2, 41,199,165, -174,164,234,105,221, 62,117, 4, 11,222,110, 62,162,206,170,178,236,236,108,233,138, 21, 43, 84,245, 21,128,101,203,150,113, 9, -134, 60,202,163,148, 82, 66, 8,145,203, 35, 93,218, 68,111, 35,230,156, 28,251, 20, 65,114,114, 50, 47,247,127,221, 41,133,189, -110,201,159, 47,226,227,227,165, 5, 5, 5, 42,206,235, 48,114,228, 72,169,187,227, 92, 48,158, 55,194,230,230,214, 15, 30, 60, -164, 34,132,128, 16,130, 65,131, 6, 74, 7, 13, 26,164,118, 81, 16, 28,231, 2,222,222, 23, 78, 30, 51, 69, 11, 78, 94,202,152, -110,117, 30,212,148,229, 39,157,242,248, 32, 16, 3,112,255,192,171, 2,112, 47, 90,252, 28,166, 77,155,214,168,191,103, 24, 6, - 2,129,253,211, 39,134,193,224, 1, 54, 4, 7,137,237, 10,128, 72,132, 17,195,129,224, 96, 64, 36, 8, 70,171, 86, 98, 8, 4, - 58,216,108, 44, 88,214,119,183,189, 94,115, 13,226, 78,189,113, 94,249, 95,180, 22, 50,120,102,209,235, 62, 15, 40, 33, 33, 33, -234,215, 95,127, 93,218,152,101,128, 50,153, 76, 41,151,203,241,194, 11, 47, 56,247,113,150,126,117,117, 53,244,122, 61,210,210, -210, 0, 0, 95,124,241, 5, 20, 10,133,234,110, 60,219,212,212, 84, 53,203,178, 82,206,242, 31, 54,108, 88,163, 2,184, 58,117, -237,133,162,130, 93,104,211, 42, 20,161,161,246,110,111, 50,217, 80, 93, 99,134, 70,107, 64,231,238,253,240,240,136, 4,175,207, -100,194,132,167,200,238,239,255,143, 22, 20,158,192,168,145, 3,209,181,107, 87, 88,204, 70, 12, 30,244, 32,194,194,195,113,177, -164, 20,101, 87, 42,113, 48,255, 55,104,107,194, 49, 57, 62,225,190,245,153,206,201,144, 3,128, 10, 32,152, 35,151, 59, 9,156, -173, 71,250, 12, 67,236,218,130,131,151, 9,128,129,110,230, 27, 51,228,114, 10, 10,151, 72, 21,130,244,244,244, 58, 94,128,185, -115,231,130, 16,130,140, 12,185,138, 99,127, 16, 96,224,192, 65,238,200,203,233,142,247, 70,114,124,201,191, 62,146,147,147, 49, -118,236, 88,105, 99,250, 49, 28,115,245,195,255, 63,123, 95, 30,222, 68,181,191,255,206,100,239, 74, 91, 74,203, 94, 40, 84,144, -173, 64, 69, 68,150, 4,202, 34, 75, 69,160, 40,139,124,145,235,109,192,237,178, 92, 69,209,251,243,222,171,160,184, 0, 94,185, - 66,203, 85, 81,161, 98, 91, 5, 11, 22, 10,133,132, 69,212, 74,169,236, 88,160,172, 45,116, 77,211,166,217, 51,231,247, 71, 58, - 49, 13,105, 51, 73,195,234,188,207,147, 39,201,204,228,147,153, 51,115,206,251,217,206,231, 60,252,176, 98,206,156, 57,234,166, -246, 59,197,246,155, 4,155, 59,192, 42, 95,246, 48, 2,165,118, 85, 42,184,158,159,171,188,140, 69, 65,246, 70,151, 70, 57,142, -201, 88,116,197,161, 16,228, 30,107,126,236,115, 87, 7,128,207, 1,184, 71, 21,128, 33,143, 14,186, 37, 49, 31,127, 89,254,206, - 15,146, 47,168,214, 80,104, 27, 69, 59, 74,254,238,222,107,143,239, 75, 36, 82, 72,196, 18, 76,122,140,130, 84, 34,134, 76, 74, -161,186, 74,128,252,130, 96,216, 24, 27, 58,118,240, 46,174,155,151,151, 71,106,244, 6,104,142,228,160,123, 71, 17, 78,150,248, - 30, 23,166,105, 90, 61,104,208, 32,106,208,160, 65, 62,203, 72, 78, 78, 86,172, 93,187, 86,197,186,249,171,170,170,158,124,248, -225,135,117,123,246,236,249,225,241,199, 31, 31, 83, 85, 85, 69, 61,253,244,211,185,201,201,201,138, 59,249,112, 54,184,250, 21, - 78,159,125,127,230,236,228, 78,138,206,158, 70,105,241,101,208, 52, 5,155,141, 64, 42, 11, 71, 92,207,222,120, 98,114, 50,231, - 7,189,180,130, 81, 84, 87,149,170,140, 70, 43,250,244,238,138,246,237, 90,227,202,213, 50,104, 78, 92,192,239, 69, 87,176,119, -223,113, 92, 46, 33,120,246,175, 47,250,212,121,238,150,226, 63,204, 55, 97, 62, 31,215,127, 5, 71,121, 23, 62,199,154, 53,107, - 28, 10,192,154, 53,107,128,226,141, 55, 29,235, 78, 94, 19, 94,129,155,198,172,150, 22,235,161, 40,170, 69,207, 30, 75,242, 77, -145,187,167,253,238,188, 10, 46,191,117, 39,143,251,125,190,252, 45,178,214,204,177,143, 13, 35, 59, 53, 34,127, 0, 72, 30,255, -144,253,131,230, 55,143, 10, 0, 95, 7,224,238, 65,218,202, 87,111, 10, 3,120,165, 0,220,205, 9, 31,190, 22,255,113,198,145, -163, 18, 72,197, 98, 76, 26, 79,129,166, 40, 12, 74,176,226,196, 73, 25,104,202, 30,243,175,169,161,209, 46, 90, 0,154, 18,227, -216, 9, 49,164, 18,192,108, 49,227,242, 21,153, 87,228,127,161,168, 16, 15,143,154, 8, 97,235,135,113,161, 40, 31,194, 27, 89, -120,229,229,215,200,123,239,191,115, 71, 26,184,161, 94,189, 34, 33, 33, 65,181,116,233, 82,244,238,221,187, 92,163,209, 32, 33, - 33, 65,161,209,104,240,210, 75, 47,169,146,147,147,239,138,186,246, 45, 37,126, 87, 37, 96,232,144, 17,216,248,213,167,242,182, -209,109, 85,129,129,129,156,172,254,155, 6,216, 57,127, 81, 3,160, 54,111, 74, 37,167,127,255, 5,109,163,130, 32,149,138,160, -211,153, 81,114,189, 22,148,176, 35,158,253,235, 28, 62, 91,138, 11,142, 46, 1, 98,159, 65,163,233,133, 5,139, 91, 66,214, 45, - 62,165,249,243,195,157, 20, 9,255, 16,154, 39, 82,246,134,180, 91, 90,207,192, 93,155, 37, 63, 34,177, 95,171,225,186,253,197, -227,158, 69,124,124,188, 35,225, 47,109,229,171, 55,237,243,168, 0,248,187, 30,255,237,174,239,239,213,195, 15, 10, 26, 13,133, -128,104, 10, 17,225, 20, 18, 6, 88, 32, 21, 11, 32, 17, 91, 16, 17, 46,109, 24, 4, 40, 12, 78,176, 33,255,168,200,238, 45,224, - 56,200,228,229,229,145, 94, 15,132, 96,201,223,254, 13,131,184, 3,190,203, 43, 65,108,156,221,114, 15,250,117, 7,150,252,253, - 53,242,225, 7,119, 78, 9, 72, 76, 76,164,242,242,242,228, 43, 87,174, 84, 57,123, 7,252,161, 92,221,205,104, 40,246,211,226, -107,156, 53, 91, 73, 29, 58,188,159, 84, 84, 85,192,112, 67, 15,169, 52, 2, 29,186,244,245, 73,169,184,215, 96, 47,135,237,167, -203, 44,222, 8,199,140,128,226, 47,238,248,181,121, 74,238,187,223, 48,102,226,147, 94, 89,238,158,124,143,124, 14,192,221,165, - 4, 52, 69,254, 30, 61, 0,127, 6, 16,216,179,250, 41,154,128,128, 32,188, 21,193,254, 67, 66, 72,197, 34, 72,196, 66, 36,141, - 39, 32,132, 65, 88,132, 21, 86, 27, 5,134,177, 53, 12,126,158,209, 55, 70,135, 9, 83,147,161, 19,118, 71,155,160, 64,204,124, - 34, 28,233, 91, 79, 56,148, 0,139,237,187, 59,126,253,172, 34,192,119, 25,223,189, 10,247,235,181,165,105,222,165, 82,194, 94, -189,153, 25, 50,195,125,149,135,148,176, 87,111,222, 81,176,184, 69, 86, 63,143,150, 97,218,243,107,253,246, 12,223,239,198,195, -189,166, 4,120, 52,128,227,227,227,249,160, 13, 15, 30, 60,120,240,224,241, 39, 3, 95,232,153, 7, 15, 30, 60,120,240,224, 21, - 0, 30, 60,120,240,224,193,131, 7,175, 0,240,224,193,131, 7, 15, 30, 60,120, 5,128, 7, 15, 30, 60,120,240,224,113,127,160, -209, 44,128, 5, 11, 22,248,156,193,233,174,182,182,191,229,205,154, 55,223,227,239,234,171,111, 56, 62, 7,134, 71, 59, 62,111, -254,108,253, 77,199, 70, 42,158,245, 40,111,207,234, 63, 42,230,141, 94,180,214,241,185, 66,245, 63,248,114,126, 77,193,215,243, -107, 10,238,206,111,242,211, 74,143,191, 59,162,250, 1, 49, 49, 49,184,116,233, 18, 18, 20, 19, 28,219,183,125,149,122,203,219, -239,217,235,215,155,125, 94, 76, 66,161,124, 73, 73,137, 99,202,226,218,168, 40,199,241,255,107,219,246,150, 63,127,174,242,178, -179,179,229, 57, 57, 57,141, 42, 37,142, 31, 63, 94,145,148,148,164,190, 19,253,163,176,176,208,103,121,253,251,247,191,213,231, - 71, 45, 88,176, 0,119,243,248,114, 39,228,165,167,167,207,232,211,167, 79,250,137, 19, 39,166,206,156, 57,243,187,150,202,115, - 94,232,200, 57, 35,255,126,109, 63, 94, 94,211,242,188, 86, 0, 92, 97,181, 90,229, 70,163, 17,148, 64, 4,138,162, 96,179, 90, - 32, 22, 9, 33,145, 72,212, 45,213, 60,172, 86,171, 28, 0,132, 66, 97,139,100,213, 87,223, 64, 96,120,180,131,248,163, 59,198, - 0, 0,110, 92,189,228,147,188, 61,171, 95,192,232, 69,107, 29,196,245,223,236,124, 0,192,243, 73,131,112, 63,226,136,234, 7, - 36, 40, 38,224,136,234, 7, 0,192,132,105,179, 0, 0,151, 46,221,249,246,251, 79, 89,153,188, 8, 80,197, 1,138, 34,192,190, -134,250,210, 87, 0, 0,131, 86,190,119, 71,219, 77,173, 86,147,156,156, 28, 24,141,198, 70,219,165, 82,169, 42, 36, 36, 4,114, -185,252,174,156, 14, 69, 81,212,208, 7,186,180,255,130,216,108,250,162, 43, 55, 94, 35,132,236,224,237,160,102,148, 78,147,105, -100, 97, 97, 97, 72,105,105,105,116,120,120,120,171,129, 3, 7,150, 4, 7, 7,127,229,171,188,244,244,244, 81, 51,103,206,220, -159,158,158,254, 44,128,208,167,158,153, 63, 15, 0,115,226,196,137, 57, 0,182, 1, 96,188,145,199,174,121,194, 18,127, 75,250, -155,235, 42,137,254,154,210,215,148, 82,194,227, 46,243, 0, 56,163,182, 78, 39,111, 27,247,144,106, 68,159, 30, 8,144,136, 64, - 8,129,205, 70,112,242,220,101, 92, 60,126, 80, 33,147,136, 32, 16, 8,124, 34,239, 32,233, 37,121,175,238,197,170,147, 69, 93, - 21,245,166, 24,159,137, 31, 0,100,161, 17,168,175,190,225, 32,254,230, 60, 2, 92, 44,213, 65,179, 94,197,158,213, 47, 56, 58, - 82, 83,199, 53, 55,199,210,245, 63,197, 98, 49, 0,123,153, 76,134,177,247,111,155,205,230, 56,127, 90, 32,226,108, 69, 3, 64, -219, 54,246, 82,157,230,218, 26,152,172, 86, 0,128,206,106,151,215,101,204, 95,208,173, 87,127, 78,196, 15, 0,253,134,140,194, - 17,213, 15, 14,226,111,234,184,219,217,126, 0,240, 66, 89, 25, 1,128,177,129,129,200,173,175, 87,177,196, 15, 0,191,239,222, -115,211,113,241,109,219,114, 58, 79,109, 96,165,188,160,242, 87,148, 92, 57,134,238,157, 7, 99,176, 84,238,245, 51,156,157,157, -253,248,206,157, 59, 89,242,183, 2, 48, 2, 8, 0,192, 24,141, 70,161, 76, 38, 67,109,109,173,220,157, 39,224, 14,147,127,212, - 67,241,125,118,230,126,189, 62,168,190,228, 12,134, 38, 47, 72,167, 40,106, 14, 33,100,219,221, 54, 48,229,229,229,145,150,212, -167,224,178, 24, 88,115,176, 88, 44,242,252,252,124,213,169, 83,167, 28,219, 42, 43, 43, 81, 84, 84,132,182,109,219,126, 41,151, -203, 21,193,193,193, 92,239, 47,157,158,158,254, 47, 0,143, 12, 29, 59, 89,150,158,158, 30,245,212, 51,243,131, 1,216, 0,176, - 15,238, 3, 13,199, 13,231,122,125,108,127, 83, 42,149,164,169,254,198, 30,231,169,191, 41,149, 74,114,224,167,124, 8, 4, 66, -216,108, 86,104,235,116,152, 57,245,113,242,193, 7, 31,180,136,176, 93,149,138,150,222, 23, 30,158,225,110,217, 95, 22,156, 42, - 1,214, 27,204,242, 81, 73, 51, 85, 29,219,132, 34, 64, 42, 4,195, 48,176, 49,128, 80, 64, 33, 60,180, 7,122,117,239,164,202, -203,253, 65, 97,179,212,203,189, 85, 2,204,102,179,188,103,175,139,170,126, 61, 46, 66, 64,219, 84,234, 35,237, 21, 98,145,200, - 43, 25,245,213, 55, 32, 11,141, 64,104, 72, 48, 0, 56,222,221, 29, 23,221, 49,198,163, 55, 96,207,234, 23, 48,104,214,171,248, -191, 39,167, 0,128,227,221,221,113,255,205,206,247, 74,187, 22, 8, 4,232,208,161, 3, 4, 2, 1,204,102, 51,234,235,235, 97, -179,217,160,209,104,124,186,185, 65, 66, 1, 62, 91,179, 21,146, 80,160,236, 18,240,171,174, 4, 21, 55,206,227,171,213,175,121, -101,245,247, 27, 50, 10, 29,218,217, 67, 36, 29,220,144,127, 76, 76,140, 35, 28, 0, 0,215,174, 93,243, 75,251,113, 41,174,250, - 66, 89, 25, 25, 27, 24,136,183, 94,120, 30, 0,240,150, 19,241,111, 42, 42,106, 76,254, 94, 84,107,221,127,105,147,188,243, 51, - 66,213,171,157,102,195,196, 36, 66,194, 16,156,169,220,139,207,223,207, 80, 76,235,155,202,245, 25, 20,230,228,228,108, 51, 24, - 12,216,184,113,163,113,238,220,185, 82, 0, 65, 0,152,141, 27, 55,154,231,206,157, 43, 52, 24, 12,144, 74,165,170,164,164,164, - 22, 13,116,223,125,247,157,124,247,238,221,170,150,214,178,119, 60, 59, 98,250,255,125,252,214, 43,178, 86,167,191,134,236,247, -125,248,231,200,176,224,151,182, 87,252,187,193,242,188,171,200, 63, 35, 35, 3, 26,205,104,146,153,153,236,245,181,127,246,217, -103,242,150,144, 77,125,125,189, 60, 59, 59, 91, 85, 87, 87,231,118,255,245,235,215,145,149,149,165,234,217,179,167, 98,240,224, -193,158,158, 27, 42, 61, 61,253,171,161, 99, 39, 79, 47, 42, 60, 44,236,208, 46,218,250,212, 51,243, 27,141,187,251,126,248, 14, -125,250,244,233,145,158,158,254, 88,159, 62,125,178, 1,224,208,161, 67,205,146, 42,151,254,166, 84, 42, 9, 40, 10,240, 80,229, -111,253,250,245,228, 70,121, 37, 10, 79,158,118,108, 51, 26, 77,120,239,227, 52,157,114,238, 12,158,176,239, 99,220,148, 4, 88, - 87, 87, 39, 31, 58,230, 9, 85,143, 78, 17,144,136,104, 48, 12,131, 27, 55,110,224,196,177, 66,152,173, 12, 24,134, 32, 34, 52, - 0, 99, 30,155,168, 50,152,172, 94,255,161, 68, 84,142,216, 78, 55, 0, 1,133, 7,187, 95,133, 68, 88,230,181,229,239, 76,254, - 55, 89,120,181,117,184,113,245, 18,100,161, 17, 77,122, 5,154, 35, 47, 87,124,241,205,119,120, 62,105, 16, 6,205,122,181, 73, -171,214, 29,196, 98, 49, 4, 2, 1, 66, 66, 66, 80, 92, 92, 12,141, 70, 99, 87,164,124, 36,255,182,109,162, 16, 36, 20,224,137, - 23,223,198, 99, 51,135, 96,199,201, 18,220, 48,160,197,228,239,138,107,165, 55,112,234,200,143,136, 12, 11,177,147,191, 80,224, -151,246, 27, 55,245,255, 0, 0, 97, 66,145, 87,228, 15, 0,255, 88,251, 95,252, 99,237,127, 29,228,159, 91, 95,143,151,199, 76, -180,239,140, 20,115,186,238, 47, 46,191, 43,255,235,146, 71, 84,207,116,126, 14, 34, 58, 8,129, 8, 0, 13, 1,218, 71, 61,138, - 23,222, 90,172, 42,110,183,154,147, 26,161, 86,171, 45, 0,240,197, 23, 95,232, 1, 72,217,101,148, 55,110,220,200, 0, 8,112, - 94, 86, 89,173, 86,251, 20,151,211,235,245,114,111,182,115,176,252,135, 62, 52, 32, 94,159,249,221, 86,101,255,222,113,130,250, -211,123,113,169,188, 14,215,107,244, 96, 8,241, 41, 17, 56, 37, 37,133, 36, 39,103,146,205,155, 55,251,181,144,152, 19,249, 35, - 60, 60,207, 39, 25,249,249,249,170,212,212, 84,138,162, 40,135, 50,224,229, 57,220, 68,254, 71,142, 28,193,204,153, 51,157, 61, - 4, 56,123,246,172, 74,175,215, 55,187, 96, 86,122,122,250, 11, 67,199, 78,158,184,124,217, 34, 97,102,102, 38,254,247,241, 7, -194, 6,143,145,131,252, 51, 51, 51,177,118,237, 90,244,233,211, 39,219, 83,127,115, 37,255,166,250,219, 99,143, 54,120, 1,131, - 3, 61,202,251,240,227,117, 14,242, 47,175,172, 66,121,101, 21,180,117, 58,136, 68,194,160,117, 27,191, 54,186, 90,241, 60,238, - 13,196,199,199,223,244,106, 86, 1,176,217,108, 36, 34,166, 47, 98,162, 91,193,104,177,129,162,128,220,220, 93,248,242,139,141, - 56,126,236, 24, 94, 94,188, 16, 2, 1, 13,198,198, 32, 36, 64,130,152,190, 67, 85, 6,131,129,115, 7,179, 88, 44,242, 94,221, - 47,171, 66,130,244,248,236,139,114,208, 20,193,160, 62,191,171, 44, 22,139, 87,157,212, 29,249,179,196,111,208, 86, 53, 82, 16, -180,181,117, 30,229,185,235, 76,108, 71,202,223,252,110, 35,130,251,226, 27,110,229,123, 99, 99, 99, 17, 17, 17,129,218,218, 90, -136,197, 98,208, 52, 13,131,193, 0,141, 70, 3,129, 64,192, 14,204,156,175,249,219,109, 91,177,112,205,110,108,253,248, 13,180, -109, 19,133,128,192,112, 92,181,149,224,171,213,175, 33,168, 97,208, 16,112,148,231,142,252, 89,226,215,150, 94, 64,143, 14,109, - 80,167, 55, 66, 18, 32, 1,108, 54,143,249, 0,158,218,239,181, 13, 59,112,234,232, 79,232,221,245, 65,104,109,158,149, 70,150, -252,127,223,189, 7,255, 88,251, 95,199,246,220,250,122,228,214,215,163, 88,249, 47,236, 62,125, 28,189, 6,117, 5,170, 60, 47, -205,156,126,110,165,124,193, 75,163, 84,145,129, 61, 97, 32,117,128,169, 28, 98, 83, 53, 76,182, 58, 24, 25, 3, 24,113, 16,218, - 15, 75, 64,214,111, 43, 60, 13,116,212,150, 45, 91, 96, 52, 26,161, 84, 42, 3,148, 74, 37, 96, 15, 1, 64,169, 84,162,225,123, -131, 5,101,196,150, 45, 91,188,238,180,103,207,158,149, 47, 94,188, 88,245,209, 71, 31, 17,138,162, 84, 0,112,240,224, 65,178, - 98,197, 10,242,198, 27,111,248,180, 52,115,176,132,222,248,223, 87,159,145,141,109,111, 18, 28, 62,123, 3, 59, 46,209,120,117, -103,153,233, 95,106,157,182,222,130,255,243, 69,166, 70, 51,250, 86, 90,254, 8, 15,207,195,172, 89,179,188, 94,141,210,153,240, -215,175, 95, 79,177,203, 73,115,197,225,195,135,229,101,101,220,140, 18,179,217,140, 19, 39, 78,236,107,238,121, 1, 32,239,208, - 46, 90,156,156,156, 12, 0, 40, 40, 40,192,190, 31,190,147, 94, 43,189,193,176,228, 15, 0,201,201,201,142,254,118,226,196,137, -213, 45,233,111,239,205,157,136,147, 23,174, 34,186,107, 91,160, 94,207,249,218,203, 43,171, 96,177, 88, 27,198,106, 43, 44, 22, - 43,174, 94,190, 36,109,201, 61,117,245, 30,240,222,132,187, 11,141, 92, 81, 38,147, 9,253,123,244, 80, 5,200, 68, 96, 24, 2, - 27, 3,252,120,240, 16,254,245,214,219, 96, 8,112,238,252,121, 28, 63,246, 27,122,247,238, 7,129,128,194, 3, 93, 59,160,248, -168, 21, 50,142,139,227,137,133,229,136,139, 41, 5,132, 20,174, 94,183, 0, 66, 10,125,123, 92, 70,254,137,114, 16,180,247,233, - 2,156,221,251,238, 60, 3, 6,109, 85,163,217, 0,158,224,236,222,119,167,105,231,111,126, 23,163, 23,173,117,155,197,238, 12, -171,213,138,128,128, 0,208, 52,141,176,176, 48,232,245,122,212,215,219,151, 1,142,140,140, 68, 85, 85,149, 87, 11,112, 24, 53, -192, 32,153, 12, 47,127,124, 16,163,251, 1,151, 11,129, 95, 27,246,189,252,241, 65,252,103,145, 2, 54,198,230,117,251,157, 58, -242,163,227,243,168,129, 61, 32, 12,166,145,171, 62,141,254, 61, 58, 34, 36, 72,130, 47,178,242,144,160,152,128,107,110,102, 1, -120,106,191,236,211, 4,184, 14, 36,141,162,176, 97, 71, 49, 34,194,186, 96,202,163, 20,167,246, 99,221,253,185,245,127, 44,157, - 76,254,185, 26,104,175, 5,245,215, 55, 65,254,245, 22, 64, 27, 64,229,175,192,218,168, 40,234,127,205, 4, 2, 98,167, 6,169, - 58,183, 26,136, 90,155, 14, 38,205,121,124,117, 37, 29,135,146, 52,120,240, 89, 5,198,188, 24, 4, 89,216, 3,144, 10,195, 32, - 76,210,226,215,239,126, 37, 15, 37, 60,212,212, 32,229,248, 15,154,166, 65, 8, 49, 55, 40,209, 70,154,166,245,132,144,112,216, -147,184,124,158, 94,219,163, 71, 15,245,152, 49, 99, 20, 85, 85, 85,170,220,220, 92,187,226,147,155,139,158, 61,123,162, 71,143, - 30, 62, 45,207, 92,103, 98, 94,154,247,143,255,108,127,127, 66, 52, 77,140, 90,252,117,115,145,197,106,177,172, 53,217,176,130, - 16, 82,237,139,204,201,147,205,183,156,252,135, 15, 31,174,246, 86, 78,126,126,126,163,144, 9,235, 5,224,186,170,164,205,102, -243, 74, 97,184,120,241, 34, 30,126,248,225,166,158, 23, 41,128, 7, 1, 8, 71, 78,152, 82, 83, 92, 92,220,170,160,160, 0,153, -153,153, 24, 88, 92, 76, 23, 20, 20, 0, 0, 6, 14, 28,136,113, 35, 18, 16, 18, 36,193,218,207,183,150,207,156, 57,115,217,186, -117,235, 22,121,219,223,174,111,123, 23,193,189,164, 8,234,190, 16, 25,239, 62,139,126,189,163,241,192,196,183,145,154,154, 74, - 53,151, 37,174,173,173,131, 84, 42, 1, 0,136, 68, 66,232,245, 70,191,222, 91,158,244,239, 12,188, 94, 12,136, 97, 24, 4, 72, -196, 48, 91, 9,104, 10,160, 41,224,205,127,191, 13, 27, 3,212,215,235,112,227,198,117, 68, 69, 69,131, 16, 6, 86, 43, 32, 21, - 9, 33, 16,113,115,193, 90,173, 86,249,131,177,215, 84,173,195,106, 1,138,178,235,198, 20, 64, 81, 4, 3,122,157, 83,253,114, - 60, 74,225,237,140, 0,214,186,111, 42, 36,192,197,250,119,213,162,155, 34,126,111,172,127,192,158, 48,212,166, 77, 27, 72, 36, - 18,135,203,144, 77,252, 11, 13, 13,133, 72, 36,194,213,171, 87, 33,226, 40,239,243,188,253,120,118,226, 8,176,230, 77,145,213, -238,254, 7, 0,121, 28, 16,242,182, 10,139,254, 62, 4, 97, 94, 92,239,181, 82,123,178, 98,167, 54,225,208,152, 76, 16,134, 8, - 96,172,208, 3, 52,141,182,157, 59, 96,247,190, 95,125,106,191,255, 91,178, 28, 23,127,220, 11,225, 13,160, 38, 10, 8,160,105, - 12,142,233,130,145, 35,162, 56,201,113,141,245,111,122,242, 89,124,107,250, 29,232,102, 4,126, 17, 2, 65, 66, 96,210, 64,116, -152,196,205,120,141,109, 31, 14,179,185, 26, 34,171, 5, 95, 93, 73,199, 79,115, 67, 49,252,137,199,209,163, 77, 79,197,201,221, -106, 85,255,228,122,136,204,245,176,246, 96, 80, 81,198, 45,105,180, 65,121, 51,206,157, 59, 55, 8,128,134, 16, 34, 2,128,185, -115,231,182,184,182,198,148, 41, 83,212,135, 14, 29, 82,156, 57,115, 70, 21, 16, 16,128,128,128, 0,204,154, 53,203,167, 65,148, -162,168,232,137, 19, 39,110,248,251,223,255, 78,191,188,232, 37,166, 55,115,158, 54,153, 45,245,102, 27,249,187, 55,114, 82, 82, - 82,136, 70, 51, 26,147, 39,155, 49,107,214, 44,202,215,243,185,149,228,239,206,221,191,126,253,122, 74,169, 84,146,121,243,230, -113, 58, 95,157, 78,215,200,237,239,140,197,139, 23, 99,241, 98,251,162, 69, 9, 9, 9,206,199, 75,154, 16,215, 14, 64, 76,131, - 82, 24, 48,110,234,190,156,179,102, 0, 0, 32, 0, 73, 68, 65, 84,108, 99,215,174, 93,165,153,153,153, 96,201, 63, 57, 57, 25, - 81,109,219, 58,247,183, 29,112, 10, 17,112,233,111, 41,147,134,227,231,210,114, 4,247, 11, 70, 73,238, 5, 64, 42,193,212, 23, -231, 32,188,195, 68,142, 99,179, 13, 37,215,203,172, 34,145, 80,200,122, 0, 0,224,234,229, 75, 45,186,175, 77,133, 14,120,133, -224,206, 41, 4,174, 74, 0,237,206,196, 33,132,128, 33,128,141,177, 43, 1, 20, 5,124,247,109, 22,158,152, 50, 13,173, 35,219, - 56, 6, 64,226,197, 90,217, 2,186, 28,189,186, 93,117,124,239,219, 59,192,225, 36, 27,240, 96, 49, 4,116,185,215, 23,228,234, -238,119,183,223, 27,235,223,213,221,239,110,191,243, 92,246,230, 80, 91, 91,139,186,186, 58,152, 76, 38, 48, 12,131,138,138, 10, -135,251, 95,175,215, 67,167,211,121, 21, 2,216,250,241, 27, 80,159, 4,180,151, 0,139, 1,248,207, 82,133,195,253,127,180, 16, -248,237,250,143, 16,120,217,126,218,210, 11, 8, 15, 13, 68, 68,120, 32, 30,136,235,137,226,139, 21, 40, 42,169, 66,167,136, 80, -152,202,202,113,254,220,249, 70,181, 0,184,180,223, 16,249,227, 24,170,152,129,173,219, 51,160, 58,144,129,244, 85, 75, 48,117, -201, 10, 28,183, 0, 21, 85,229,156,218,207, 57,214,255,204,144,135, 49,235,193,206,200,216,186, 15,199,143, 95,194,170, 19, 5, -216, 50,122, 14,240,233, 97,148,148, 84, 52,170, 5,208, 20, 58, 24, 37,176,153, 43, 97, 54,107, 1, 0, 81,237, 59,162, 71,207, -158,138, 90,153, 61, 23,195,192,232, 65,155,234, 33,171, 23,160,236,250, 13, 79,132,106,247,200, 24,141, 48, 26,141, 82, 0,102, - 0,193, 70,163, 49,196,117, 74,160,175,208,235,245,242, 3, 7, 14,168,122,246,236,137,217,179,103, 43, 42, 43, 43,145,155,155, -203,185,179, 81, 20, 53, 84, 34,145,232,130,131,131,173,163, 71,143,190,190,116,233,210,118,203,150, 45, 43,254,181,240,248,248, - 45,167, 76,103, 45, 12,188, 94,143,245, 86,184,252,253, 73,254,174,214, 63,155,163,224,236, 5,224, 34, 67, 36,250, 67, 37, 95, -181,106,149,227,229,238, 59,224,152,225,211,212,189, 17, 55,188,104, 0, 66,109,233, 5,183,238,116,182,191, 21, 30, 45,188, 56, -115,230,204, 20,111,250,219,176,135, 30, 64,226,163,113, 88,254,239, 15,240,225,154, 28,252,191, 77,251, 48,127,100, 2,110,124, -159, 3,173,166,214, 35,217,166,166,166, 82,201, 73,227, 96,177, 88, 11, 45, 22,171,213, 89, 1, 0,128, 21,111,190,230, 51, 97, -243, 68,127,103,225, 46,246,239,234, 21,104,164, 0,208, 52, 13,173, 78, 15, 1, 77,193,106,181,129, 33, 4, 86,198,158, 68,122, -236,183, 66,140, 28, 53,214,238, 38, 35, 4, 2, 90,128, 58,189, 25, 86,179,201,179,134,105,179,201,187,180,191,174,138, 12,215, - 58,180,140, 33,131,130,236,221,134,162, 64, 81, 4,253,123,158, 87, 89,109, 54, 57,215,139, 99,173,251,230,146, 1,125,178, 94, -155, 73,174,241, 6, 97, 97, 97,168,168,168,128, 68, 34, 65, 93, 93, 29, 34, 35, 35, 29, 73,129, 70,163, 17, 53, 53, 53, 94, 41, - 0, 41,203,183,224, 63, 75, 21, 8,141, 1,212, 39,129,151, 86,170, 16, 36, 20, 96,202,223,222,193, 53,230, 6, 54,175,122, 5, - 2,154,187, 60,214,250, 31, 56, 48, 14,145, 93, 99,208, 38,178, 53,196, 52, 5, 43, 69, 80, 81,111,128,166,206,232, 83,251,125, -248,238, 54, 76,238,217, 5, 33, 33, 17, 8,136,108, 7, 75,181, 6,133, 59,190, 70, 77,245, 21,159, 30,226,207,222,125, 1, 88, -148, 8,161,213,140,152,122,160, 92, 80,139,255, 92,255, 21, 16,135,112,150,113,116,251,207,138, 74,218,128, 43, 98, 61, 18,186, - 41,240,224,156, 32, 20,135,169, 85,145,145,133,170,142,131,139,161,165,235, 96, 34, 6,232, 55, 49,144, 6, 5,115,177,252,157, - 7,120,118, 22,128,216, 95, 29,119,215,174, 93, 0,128, 89,179,102, 41,122,244,232,161,126,226,137, 39, 28, 22, 35, 23,242,143, -140,140,220,185, 97,195,134,192,212,212, 84,193,162, 69,139,176,112,225, 66,114,248,240,225,193,132,144, 92,189,133,244, 36,132, -252,226,189, 53, 23,214,164,219,223,215,132, 64,127,146,191, 43,193, 59, 43, 44,235,215,175,167,242,243,243, 57,185,246,175, 93, -187,118,152,253,156,158,158,238,120,185,110, 99, 17, 30, 30, 14, 0, 77, 13,130,215, 0,212, 0,160,175,149,222,192, 79, 63,253, -228,136,249, 15, 28, 56, 16, 0,144,153,153,137,111,178,115,160,169, 51,234, 1,172,128,125,106, 32,231,254,246,253,214,127, 98, -236,210, 23, 49,126,252, 40,180,150, 8, 80, 71, 17,228, 22, 93,197, 79, 39, 75,188, 34,234, 5,115,103, 60, 84,124,254,188,240, -234,229, 75, 96, 95, 43,222,124,173, 89, 75,158,199,221, 77,252,174,219,220,161, 81, 8, 64, 34,145,224,220,233,227,138,152,118, -225, 42,153, 72, 8,155,141, 1, 69, 81,160, 40, 32, 69,249, 60, 8, 97, 96,107,168, 7,160, 55, 26,113,166,168, 24, 98,177,103, - 39,182,213, 82,141,254, 15, 94,116, 30, 69,241,220,162,139,248,118, 83,119,135,238,156,208,251, 2,126, 62,214, 19, 66, 65,164, - 87,214,191, 59,226, 55,104,171, 0,192, 39,235,223, 93, 71,203,223,252, 46, 0,112,182,254, 1,251, 60,255,232,232,104,152, 76, - 38,148,149,149,193,102,179,161,117,235,214,168,170,170, 66,235,214,173, 27,218,149, 59, 97, 87,220, 56,143, 55,222, 86, 65,123, - 9,120,127,201, 48,232,172, 54, 44, 94,153,137,143,150, 38, 99,201,170, 29, 16, 82, 20,188,224,127,104, 75, 47,160,109,235, 86, - 16, 65, 4, 27, 40, 92,191,120, 10,151,203,181,136,141, 12,199,247, 71, 15,227,204,105,120,109,253, 79,157,183, 24,162,112,128, - 22, 0, 27,115, 46,226,219, 79, 94,198,188,119, 83,177,120, 82, 63, 60, 63,170,179, 87,237,151, 91, 95,143, 15,147,166, 3, 53, - 82,128, 18, 1, 31,126,128,105,191, 30,196,238, 81, 11, 64,189,243, 34,168,159, 95,225,100,253, 3,192,111,215, 35,240,176, 65, - 11,157, 76, 0,189, 84,138,216,169, 34,152,136, 1, 90, 90, 4, 43,226, 64,108,122, 88, 42,175,227,199,143,181,152, 53, 51,246, -142,116,218,130,130, 2,210, 64, 12,212,148, 41, 83,212,118,223,152, 29,195,134, 13,163,134, 13, 27,198,133,252, 31,109,215,174, -221,174,119,222,121, 39,240,220,185,115, 16,137, 68, 8, 9, 9,193,241,227,199, 45,132,144,138,150,156, 95,115,115,242,125,241, - 14,248,147,252, 93,173,127, 59,177,222, 60,125,144, 75, 46, 64,114,114,242,185,111,190,249,102,136,213,202,109,134,147, 84, 42, -157,215,204,238, 58, 0, 23, 1, 12, 44, 42, 60, 12,231,152,255,115,243,166, 99, 87,215,174, 96,195, 1, 59,187,118, 13,152, 57, -115,230,231,222,244,183, 39, 19, 31, 70, 40, 19, 6, 61, 68,248,118,245,139,248,100,199,111,120,121,220, 80,204, 93,149,142,105, - 43,190,242,202, 2,119, 46, 38,228,110, 27, 63,127,255,254, 68, 35, 15,128, 64, 32,160,106,174,159,199,133,171, 85, 16,138, 4, -176,218, 24, 88,172, 54, 28, 61, 90,128, 47,191,252, 28,102, 27,129,197,198, 64, 44,164, 81,174,209,161,228,204, 79, 10,153, 76, -166,246, 64,132,242,158,177,151,255,176,254,237, 67, 21,190,221, 20,103, 31,227,104, 2,208, 4, 52,205, 96,112,191, 51, 42, 27, - 7, 47,128, 59,235,223,121, 22, 64, 96,120,180, 87,228,239,206,250,119,206,170, 29,189,104,173, 87,228,101, 31, 20, 53,208,233, -116, 16,137, 68, 14,235,159, 97, 24,199,187,183, 10,192, 87,171, 95,195,209,146,253, 8,138,182, 39,253, 5, 11, 5,168,184,113, - 30, 33, 18, 17,106,170,175, 65, 64, 83, 16,210,220,194,207,172,245,223, 49, 60, 24,167,139, 47,194,106, 54, 67, 34, 20, 67,167, - 51,226,123,213, 97, 36, 40, 38,120, 69,254,108,251, 61,254,194, 91,216,252,159,143,160,103,128,142,177, 29,112,242,212,207, 88, - 60,169,159, 79,237, 7, 0,139, 99, 19,176,253,220, 62, 64,107, 5,164,173,177, 39,255, 52,168,119, 94,196,218,168, 40,138, 43, -249, 3,192,204,238, 75,213, 63,238,201, 7,204,117,208, 81,117,208,208, 58,104,133, 22, 88,108,181,144, 24,245,144,150, 94,196, -150,101,231, 16, 19, 31,135,102, 18, 0, 27, 65,230,148,249, 42,149, 74, 33,149, 74,221,238,227,138, 13, 27, 54, 96,195,134, 13, - 45,234,204,193,193,193, 47,157, 63,127, 62, 48, 36, 36, 4, 50,153, 12,225,225,225,168,168,168, 0, 69, 81,122,127, 14, 26,172, -197,159,151,151, 71, 0,123, 66,160, 55, 73,129,254, 38,255,207, 62,251, 76, 78, 60,207,117,231, 52, 35, 32, 48, 48, 48, 69, 40, - 20, 94,112,221,190,106,213,170, 70,150, 63, 0,116,238,220, 25,137,137,137, 27, 61,217, 63,215, 74,111, 52,202,246,127,227, 31, -139, 32, 17,138, 17, 21, 21, 5,118,118, 64,195,254, 64,111,250,219,179,242,190, 88,248,193, 71,168, 43, 43, 71,100, 72, 27,156, - 58,125, 5,115, 87,165, 35, 53, 53,149,242,133,172,217,223, 57,255,222, 89, 14,239, 9,184, 55,240,219,111,191, 53, 91, 12,168, - 73, 15, 64,195, 32,162, 46, 80,111, 83, 16,146,164,138,105, 23,129,224, 0, 9, 30,236, 29,143, 7,123,245,131,144, 6,116, 6, - 27,174, 92,175, 70,190,250, 7, 69, 80, 96,128,199, 63,168,215,235, 17,215,249, 58,140, 38, 41, 8,107,212, 16, 64, 38, 53,130, - 16,160,186, 70, 2, 80, 64,112,160, 21,125,226, 46,225,224,145,254, 8, 14, 14,230,108,253, 59, 91,252,178,208, 8,136,136, 5, -176,254, 49,222,217,132,158,207,209,217,250,119,182,248,217,109,231, 79, 21, 58,142,229, 82,101,207, 89, 9, 0,128,232,104,187, - 50, 82, 93, 93,141,144,144, 16,135,251,223, 27, 5,128, 85, 2,128,119,176, 32,121, 4,240,159,131,248,228,245, 9,152,182,228, - 35,164,191,251, 60,132, 20, 5,177,132,219,140, 29,214,250, 63,125,165, 28,221, 58,182,198,167,255,219,130,152,152, 24,132,182, -139, 69,191,118,177,176,152,254,112,255,139, 56,200,100,173,255,183,231,141,194, 75,111,110, 68,199,174, 84,139,218,143,181,254, -199,108,253, 12,187,103,205, 0,213, 97, 48, 0,123, 85, 64,192, 94, 34,152, 61,246,165,168, 40, 78,196,209,215,244, 10,149,254, -193, 74,121,236,148, 58, 85, 76,247,222,168,149, 1, 23,113, 25,117,151, 42, 80,177,194, 6,157,166, 3, 22,205, 89,194,249,134, -172, 91,183,142,146,201,100,196, 96, 48,192,201,242, 36, 50,153, 12,235,214,173,243,162, 60,145,255, 80, 87, 87,247,254,243,207, - 63,159,180, 97,195, 6,105,104,104, 40, 84, 42, 21,214,172, 89, 83,107, 54,155,199,249,243,127, 88,139,159,157, 46,231,109, 66, - 96, 98, 98, 34,165,209,140, 38,254, 32,127, 0, 96,137,157, 11, 65,113,168, 48,104,158, 51,103,206,224,140,140,140,227,245,245, -245,109, 45, 22,251, 52, 83, 87,242,127,240,193, 7, 49,120,240,224,137, 28,238,179, 80, 91,122, 1,203,255,249, 6,190,219,190, - 19, 99,135, 14,192,222,188,159,237, 6, 76,187, 88,132,182,139,197,192,226, 98,140,155, 58,187,242, 74,149,126, 76,167,136,128, - 44,174,214,255,194,180,237, 88,246,151, 49,104, 23, 45,119, 40, 23,236, 53,114,241,220,248,226, 29,224, 61, 1,247,174, 82,192, - 73, 1, 0,128,144,224, 32,245, 81,245, 54,197,197, 14, 15,160,107,247,158,170,144, 64, 25, 24, 2, 24, 76,102, 20, 23, 23,163, -162,248, 55, 69,112, 80, 32,104,154,246,216,113,101, 82, 41, 50,118,141, 80,176, 25,240,205,186, 35,104, 26,129,129,220,173, 39, -118, 10, 96, 96,120, 52, 24,155,197, 78,254, 13,176, 80, 34,143, 37,118, 93,193, 78,169, 25,189,104,109, 35,210,242,133,252,157, -149, 0,231,194, 63,213,213,213,158,111,128, 7, 37,224, 43,167, 89,194, 27, 86, 60,247,199, 23,139, 14, 65, 28,229,116, 12, 15, - 70,198,145,223,112,242,236,239, 72, 80, 76,104, 68,250,222,144, 63,139,199, 95,120, 11,223, 14, 8,196, 11, 79,244,240, 75,251, - 45,142, 77,192,146,236, 12, 80,203,223,196,206,168,135,177, 70,119,178,209,254, 41,161,173,208, 65,234,221,154, 20, 51,187, 47, - 85,239,204,206,194, 53,205, 5, 84, 84, 93, 71, 89, 81, 16, 4,182, 16, 60,218,119, 24, 20,115, 20,119,116, 80,243, 71,181, 63, - 66,200, 17,138,162, 70, 83, 20,181,231,163,143, 62,146, 78,158, 60,185, 86,175,215,143,241, 37,230,223, 28,252, 49, 5, 80,169, - 12,243, 11,249,187, 90,169,126, 66,229,244,233,211, 99,235,234,234,150, 23, 20, 20, 44, 42, 41, 41, 65,125,125, 61,196, 98, 49, -218,182,109,139,200,200,200,201, 3, 6, 12,248,158,163,172, 51, 0, 6,118, 12, 15,198, 35,143, 60,130,223,206,149,160,117,151, - 94,141,250,219,184,169,179,245, 0, 62,230, 66,254, 44,158,149,247,197,232,188, 95, 48,235,205, 47, 49,124,248,112, 68, 69, 69, -185, 85,180,252,213, 32,172, 18,224, 77, 91, 55,165,144,241, 74,196,157, 35,125, 78,165,128, 1, 32, 36, 36, 68,109,170,190, 42, - 63,170, 46, 82, 0,246, 76, 90, 66, 8, 36, 18, 9, 66, 67, 56,215,192,134, 72, 36, 82,135,138, 68,126,191, 56,214,213, 47,176, -234, 1,171,222,145, 1,207, 18,191,183,115,177, 88, 87,255,249, 83,133, 56,127,170, 16,145,145,145,168,168,168,240,137,248, 67, - 35,219,193,204, 33, 57,146, 43,102,189,245, 21, 14, 31, 84,251, 77,222,165, 75,151, 28,171,253, 89, 76,198,155,200,223, 27,226, -103, 49,103, 64,160,223,218, 15, 0,168,213,175, 56,136,159, 37,255,139,245,245,138, 41,161,173, 48,137,163,213,239, 14,143,117, -153, 70,161, 75,195, 23, 31, 18,219,215,175, 95, 79,177,213,254,214,173, 91, 71, 57, 87,254,219,184,113, 35,181,110,221, 58,199, -231,245,235,215,223,246, 78, 79, 8, 57, 68, 81,212,240,172,172,172,197,181,181,181,171, 9, 33,249,254,254, 15,127, 76, 1,244, - 39, 57,221, 34, 24,130,131,131, 23,203,229,242,197, 45,148,115,232,196,137, 19,143, 2,232,210,186, 75, 47,189,197,100, 12,104, -232,111,181, 0,180, 0,206,116,138, 8,120, 18,246,100, 65,206, 24,253,198,134,219, 66,252, 45, 81,180,120,146,191, 51,136,143, -143,231, 68,254, 30, 13, 80,161, 80,168,246,228,142,191,221, 96, 99,251, 44,241,163,133,196,207,198,166,181,229,215,160, 45,191, -134,200,200,200, 22, 89,252, 0, 96,181, 49, 94,123, 31,154, 67,121,181,214,231,115,113, 5, 27,219,247, 23,241,251,187,253,216, -216,254,118,157,142, 56, 91,253,253,133,162, 22, 17,255,159, 9,132,144, 95, 1,204,224, 91,226,206, 99,230,204,153,169, 0,190, -188, 82,165,215, 91, 76, 70,231,120,100, 72,167,136,128, 48,120,185,250, 31, 75,170,206,110,254,123, 72,169,226,113, 27,149, 0, - 78,134, 86,124,124, 60,159,216,193,131, 7, 15, 30, 60,120,252,201, 64,243, 77,192,131, 7, 15, 30, 60,120,240, 10, 0, 15, 30, - 60,120,240,224,193,131, 87, 0,120,240,224,193,131, 7, 15, 30,188, 2,192,131, 7, 15, 30, 60,120,240,184, 47,208,104, 22,192, -130, 5, 11,124,206, 34,117,183,220,228,221, 46,175,176,176,208,103,121,253,251,247,191,229,242,252,125,189,173, 91,199,251, 44, -175,178,242,183, 59,125,127,169, 6,133,149,129,155,226, 43,247,226,243,119,187,228, 53, 20, 38,162, 27,218,144, 0, 32, 11, 22, - 44, 96,248,246,227,229,221, 75,242,210,210,210,132, 41, 41, 41, 86, 0,248,244,211, 79, 73,247,238,221, 49,124,248,112,138,111, - 63,247,242,188, 86, 0,238, 7,180,180,200,196,244,233,211,229, 0,156, 75,134, 42, 50, 50, 50,212,188,174,120,103,160,213,106, -159, 62,113,226, 68, 63,129, 64,176, 68, 34,145, 64,175,215,191, 50,116,232,208, 15,224,135, 74,123,132, 16,175,171, 49,222,139, - 88,176, 96, 1, 1,199, 69,102,120,220, 57,100,103,103,203,147,146,146,212, 62,254, 86,145,147,147,179,207, 31, 5,165, 26,228, - 61,153,147,147,179,101,253,250,245,225,176,175,105, 96,195, 29,168,110,233, 12,150,252, 15, 28, 56, 64,126,249,229, 23, 36, 36, - 36, 96,248,240,225,252,131,227, 47, 15,192,189,142,188,188, 60,121, 75,126, 63,125,250,116,121, 70, 70,134,106,250,244,233,206, -155, 85,211,167, 79,247, 89, 9, 96, 21,138,204,204, 76,182, 84,167, 87,178, 82, 82, 82,136,151,255,215,236,124,224, 61,123, 62, -247, 86,158, 66,163, 9,188, 19, 10, 16,117,242,228,201,247,107,107,107,255,210,185,115,231, 86,149,149,149,104, 88,110,247,189, -111,191,253,246,189,192,192,192,145,227,198,141, 83,181,232, 15,124, 32,127,165,114,129,215,131, 96,106,234, 58,234,246,201,107, -190, 28,110, 83,139,190,112,237, 95, 25, 25, 25, 42,188, 73,129,250,183,123,133, 10,111, 82,152,126, 38,217,235,118, 29, 59,118, - 44, 1,128,220,220, 92,191, 16, 24,187, 20,176, 82, 25,230,247,249,241,217,217,217,242,156,156, 28,149, 55,100,251,215,191,166, - 16, 66,236, 75,171,187,195,164, 73, 19, 21, 57, 57, 57,170,164,164, 36,202,135,231,120,228,206,157, 59,247,142, 24, 49, 2,243, -231,207, 39,233,233,233,163,107,107,107,243,188, 57, 55, 55, 74, 35,158, 26, 34,134,114,190,178,250,149, 77, 75,191,127,119,198, -187,143,179,251, 54,108, 72,107,246, 28,103,207,158, 77, 0, 32, 48,176,233,165, 13,234,235,235, 1, 0,115,231,206,245,233,254, -156, 61,162, 64, 94,218, 49, 36,166,164,145,148,148, 20,190,254, 1, 7,176,197,129,156,107, 4, 8, 61,116,120,183,117,179, 57, -212,211,190, 83,104, 17, 33, 56,147,127, 70, 70, 6, 53,125,250,116,226, 36,215,235,235,101, 21, 10,150,104, 26, 22,252,240, 94, -161,200, 12,247,226, 95, 19, 61, 30, 81, 63,233, 57,238,226,188, 92,215,166, 41, 2,242,210, 43, 67,105,181,218,111,122,247,238, - 61, 21, 0, 77, 8,129, 76, 38, 67,121,121, 57,106,106,106, 16, 26, 26,138,242,242,242,125,187,118,237, 82,140, 27, 55,206, 43, -229, 36, 47, 47,143,176, 11,179, 80, 20,133,169, 83,167, 34, 49, 49, 81, 65, 81, 20,103, 57,217,217,219, 28,159,147,146, 38,123, -252,238, 9,134,195, 47,252,209,220, 67,214, 54,250,238,186, 77, 54,196,243,162, 74,236,114,194,206, 56,112,224, 0, 86,172, 88, -113,211,189,216,180,105, 19,225,216,110,242,204,204, 76, 21,222,164, 26, 8, 54,249,230,129,251, 77,170,197, 22,226, 93, 60,182, - 52,178,180, 83, 83, 83, 21,132, 16,108,222,188,153, 28, 58,116, 8,125,251,246,245,248,219,195, 77,212,100,220,154,185, 4, 57, - 57, 57, 42,134, 97,144,150,150, 6, 79,203, 42, 83, 20, 37, 39,132, 56,158,215,239,191,255, 62,128,162, 40,204,152, 49,163, 12, - 64,212,204,153, 51,247,172, 95,191,158,246,198, 98,255, 96,207, 7,142,207, 55,114,175,131,162, 40,164,255, 45, 0, 0,133,247, -103,191,247,120,235,214,173, 1, 0, 95,127,145,142,249, 35,230,115,146, 57,112,224, 64,116,237,218,213, 47,237,158,150,150, 70, -167,164,164, 48,159,126,250, 41,249,229,151, 95, 80, 86, 20, 3, 84,134,241,172,238, 37,249,187,130,110,110, 32,207,204,204, 68, - 90, 90, 26,113, 55,128,250,178, 50, 84, 75, 45,116, 79,242,156,172,108,159,141,194,140,140, 12, 42, 35, 35,131, 98,149, 0, 0, -138,150, 40, 20, 20, 69, 33, 57, 57, 25,132, 16,202,233,220,188, 86, 84,168,233, 26,199,139,203,118, 79, 8,218,177,206,241,226, -178,221, 27,242, 39,132,128, 93,157,205,211, 42,109,238,158, 73,141, 70,243,101,104,104,232, 84, 0,244,188,121,243, 48,107,214, - 44,136,197, 98,200,100, 50, 72,165, 82, 80, 20, 5,129, 64, 0,173, 86,203,185, 29,179,178,178,228, 74,165,146,100,101,101,193, -233,158,224,219,111,191,197,252,249,243, 85, 89, 89, 89,242,187,177,227,186, 83, 8,238,132,103, 45, 51, 51, 83,149,154,154, 74, - 61,121,118,186, 91, 11, 95,169, 84,146,233,103,146, 21,238, 60, 3,158, 48,127,254,124,242,242,203, 47,163, 75,151, 46,126, 57, -223,249,243,231, 19,165, 50, 12, 17, 17,123,253,218, 14,219,182,109, 27,149,151,151,183,175, 95,191,126,212, 39,159,124,162,102, -201,191, 37,216,154,185, 4,171, 87,175, 6,195, 48, 88,178,100, 9,184,200,116, 38,127, 0,216,185,115,231,246, 6, 87,120,216, -140, 25, 51,172, 35, 70,140,128, 82,169,100,184, 26, 45,174,125,116,205,154, 53,120,242, 17,187,109,152,254, 55, 25,158, 26, 34, -198, 43, 99, 95,230,124, 77,129,129,129, 24, 62,124, 56, 82, 82, 82,168,196,196, 68,183, 47,246, 24,174,202, 94, 74, 74, 10, 3, -216,151, 89, 7,128,144,128, 74,158,213, 91, 72,254,205, 42, 0, 44, 89, 21, 20, 20, 56,202, 78, 58, 91, 79,222, 18,173,195,130, -240,243,160,228, 70, 25, 80,248,179,241, 50, 50, 50, 84,126,144,225, 80, 40,146,147,147, 21,108, 27,222, 79,112, 38,127, 0, 40, - 41, 41,113,236,187,118,237, 26,103,133, 81,171,213,190,163,215,235,103,211, 52, 77,207,156, 57, 19, 90,173, 22,165,165,165, 16, -137, 68, 16, 10,133, 16, 10,133, 16,137, 68,144,201,100, 48, 24, 12,110, 75,162,186, 25,224,228,123,246,236, 81, 81, 20,133,105, -211,166, 97,253,250,245, 84, 98, 98, 34,149,154,154, 74, 77,155, 54,141,125,126, 84,252, 80,209, 60,249, 55,180,165,130, 29,196, -157,239,125,114,114,178, 34, 49, 49, 81, 13,248, 86,146, 54, 49, 49,145, 90,191,126, 61,149,153,153, 9, 66,136, 95,148,177,215, - 94,123, 13,153,153,153,156,158, 17, 79,248,238,187,239, 70, 31, 57,114, 36, 47, 38, 38, 6, 58,157,142, 4, 6, 6,146,131, 7, - 15, 2,112, 36, 89,250, 68,254,171, 86,173, 2, 69, 81,160,105, 26, 71,142, 28, 1, 43,211, 11,143,196,227, 20, 69,225,169,167, -158,178, 54,108, 50,207,152, 49,163, 86, 46,151, 99,254,252,249,204,247,223,127,239,241,218,157, 67, 97, 55,114,175, 3, 20,176, -249,165, 63,170, 22,167,255, 45, 0, 51, 30,149, 96,233,184, 87, 56,159, 23, 23,203,159,203, 49, 7, 14, 28, 32,105,105,105,142, -215,145, 35, 71,160,187, 50, 16, 48, 27, 64, 5, 89,145,247,246, 25, 56,239,103, 95,124,207,109, 76,254, 41, 75,223,117,187, 95, -216, 92,135, 44, 46, 46, 38, 5, 5, 5,200,204,204, 4,251,153,117,237,120,211,201,111, 53,249, 59, 91,213,236, 32,116,183,194, - 57, 36,112,191,129, 16,130,146,146, 18,220,184,113,195,177,205,245,187, 7, 8,126,250,233,167,241,113,113,113, 16, 8, 4, 56, -127,254, 60, 8, 33,248,253,247,223, 97, 54,155, 65, 81, 20,132, 66, 33, 40,138,130,205,102,131, 94,175,199,214,173, 91,145,152, -216,124,216, 99,239,222,189, 42, 0,152, 54,109,218, 77,207,109,195,119,194, 18, 5,151,231,218,213,173,239,233, 59, 23, 43,159, - 69, 83,225, 0, 46,174,127, 55,131,103,139,147,164, 28, 49,127, 39, 5,142, 85, 96,217,152,127,158, 19,249,251, 98,173,179, 74, - 24, 75, 70,123,247,238, 85,249, 26, 6, 96,229,117,239,222,253, 38,114,243, 5,235,214,173,195,153, 51,103, 72,100,100, 36,218, -183,111,239, 88,246,249,210,165, 75, 16, 8, 4,248,239,127,255,235,211, 31,140,120,212,190,124, 25,195, 48,248,251,223,255,142, - 53,107,214,224,224,193,131,160, 40, 10,147,146,254,138,203,151,184, 45,224,184,115,231,206,109, 13,247,216, 8,251, 12, 25, 6, - 0,102,204,152, 81, 3,160, 85, 78, 78, 14, 40,138,226,172, 80,217,173,255,155,215, 49,177,135, 3,128,175,211, 11,145,173,205, -190,109,222,178,179,103,207,226,200,145, 35,141,182,217,106, 46,194,106, 97, 0,170, 14,173,198, 89,112,196,101,177,235,132,132, - 4,158,249, 57,144,127,179, 10, 64,131,219,133, 98,173,126,150,252,221,198,254,188, 32,235,230, 44, 65, 46,113, 98, 79,242, 92, -247,223,169, 21,169,166, 79,159,238, 28,107, 38,238,246,179,158,129, 22,145,110,134,127,227, 96,186,137, 11,124,178,252,155, 26, -108, 59,116,232,112,211,177,205,220,147, 86,225,225,225,189, 77, 38, 19,170,171,171,113,248,240, 97, 8, 4, 2,152,205,102, 24, - 12, 6, 48, 12,227, 88,149,210, 98,177,192,100, 50,113, 10, 49,176,247,161,169,231, 54, 49, 49,145,202,202,202, 34,153,153,153, - 30,149, 9,187,213,117,107,114, 0,100, 67,214,222, 68,244,236,119, 95, 20,129,225,195,135,183, 92, 9,112,137,249,231,229,229, -201, 29,100,255, 71,204,223,167, 28, 25, 23, 37, 12,128,125,181, 69,165, 82, 73,184,220, 7,174, 94,128,134,220, 7,175,115, 11, -216,149, 29,219,183,111,143,144,144, 16,202, 85,217,237,221,187,183,207,150, 63, 33, 4, 86,171,213,177,109,232,208,161, 56,120, -240, 32,246,255,104,195, 7, 43,185,197,216,179,179,179,199, 54,196,254, 79, 3,104, 13,192,121,177,161, 82, 0,173, 0, 32, 39, - 39, 71,213,175, 95, 63,143,242, 26,199,254,221,120, 10, 26,222,185,202,243, 7, 82, 82, 82,168,132,132, 4,162,250, 50, 18,214, -154,223, 64, 49, 53,128,205,190,210, 42, 45,176,162,246, 32, 13,145, 88, 8,147,173, 21,126,190,212, 15,111,172,210,224,200,145, - 35,148,187,105,213, 60,188, 84, 0, 92, 61, 1,222, 90,254,197,197,197,196,159,238,110, 79,242, 26,194, 18,126,243, 52,164,165, -165, 81, 41, 41, 41, 62,253,214,245, 60, 83, 83, 83,117, 74,165, 50,168,169,253,190,194, 57,246,239, 15,101,192, 57,246,207, 85, - 25,152, 53,107, 22, 2, 3, 3, 17, 20, 20,132,224,224, 96,132,134,134, 50, 97, 97, 97,116, 78, 78, 14,158,126,250,105,199,113, - 82,169, 20, 99,198,140,129, 82,169, 36, 77,172, 86, 21, 97, 54,155, 81, 93, 93, 13,163,209,136,208,208, 80, 72, 36, 18, 88,173, - 86, 16, 66, 96,179,217, 96, 54,155, 97,177, 88, 96,179,217,188,202, 47,240, 20,178,154, 54,109, 26,238,134,208,140,167,132, 64, -111,193, 42, 1, 62, 63, 95,255,110,186,237,166,159, 73,110,200,187,241, 77,182,171,245,239,172, 72,250,146, 12,232,106,253, 55, -167,152,114, 37,127,129, 64, 64, 66, 66, 66, 0,123, 66, 29, 5,128, 88, 44, 22,104,181, 90,180,105,211,198,167,235,102,141, 41, -161, 80,136, 69,139, 22,225,200,145, 35,248, 35,238,207,253,153,222,181,107,215,174, 97,195,134, 1, 64, 48,236,225, 92, 61, 0, -108,217,178,165,205,254,253,251, 67, 8, 33, 14,101,155,203, 60,241, 53, 31,173,193, 83,131,111,182,254,103,253, 71,143, 45,135, - 45, 32,132,160,255,204,254,152, 63, 98, 62,229,235,188,115, 95,149, 0,197,156, 52,178,107, 77,103, 8,117,181,128,213,254,215, - 12, 0,177, 16, 40,185,209, 10,251,174, 12,180,165,125, 93, 33, 56,114,228, 8,149,144,144, 32,197,159, 28, 92,172,127,128, 67, - 37,192,188,188, 60,135,235,223, 57, 31,128, 11,186,118,237, 74, 37, 39, 39,251, 45, 38,207, 65,158,207,241,245,233,211,167, 19, -215, 87, 94, 94, 30,195,206, 10,112,154, 17,224,235, 67, 28,116, 63, 63,112,105,105,105, 88,181,106, 85,163,231,138, 37,255,164, -164, 36, 36, 37, 37, 1, 0,246,239,223,223,156,152,240,226,226, 98,163,205,102,131, 70,163, 65,101,101, 37, 52, 26, 13,244,122, - 61,244,122, 61,116, 58, 29,106,107,107,161,213,106, 97, 48, 24, 96, 50,153, 28, 73, 65,205,146, 24, 69, 33, 43, 43,203, 43,133, -237, 94,198,129, 3, 7, 26,189,156,113,246,236, 89,185,243,119, 46, 49,103,215,152,191,171,229,222,146,172,125,119,191, 93,191, -126, 61,149,149,149,229,215, 92,128,172,172, 44,206, 99, 23, 75,254, 52, 77,147,134,231,203,225,250,103, 24, 6,101,101,101,232, -222,189, 59,181, 96,193, 2,175,207,229,245,165, 35,176,127,255,126, 48,223,180, 2, 33, 4,171, 87,175,118,220,163, 3,135, 57, -231,237, 33, 59, 59,123, 50, 0,204,152, 49,163,164, 65, 1, 48,125,253,245,230, 54, 11, 22, 44,104,179,127,255,126, 60,246,216, - 99,163,189,153,166,120, 35,247, 58, 40, 80,216,236,100,253,207,252, 72, 15,193, 83, 90,124,125,216,140,133, 11, 23, 98,229,174, -247,238,196,184, 34, 96,149,128,113, 11,173, 32,134, 80,160, 22, 64, 45, 32,168, 3,106,203,128,157,133,109,145,246,117,133,160, -193, 91, 32, 76, 73, 73, 49,242,228,239,153,252, 61,122, 0,210,210,210, 26,197,253,157,243, 1,184,206,189,108,112, 23, 42, 88, -183,124, 75, 93,242,238,228,177,110,255,196,196, 68,181,191,166, 16, 37, 38, 38,158,204,203,203,235,125, 55,222, 96,214,234,247, -151,251,159,181,250,189,117,255,179,216,188,121,179,227,243,191,254,245, 47,124,254,249,231, 0, 96, 6, 32,102,137, 31, 0,198, -140, 25,227, 73, 1, 48,196,197,197, 65,175,215,195,108, 54,163,162,162, 2, 18,137, 4, 66,161,208,225, 1,168,175,175,135, 94, -175,135,201,100,130, 86,171,197,212,169, 83, 61, 42,152,172,117,223,220,180, 86,246, 56, 46,184,149, 57, 0,190,236,119, 5, 59, -221,207, 29, 86,175, 94,173, 90,180,104,145,162, 71,143, 30,234, 59,249, 12, 55,101,253, 59,195,155, 92,128,166,172,127, 95, 45, -127,154,166, 9,195, 48, 20,128,127,178,143,182,205,102,123, 51, 48, 48, 16, 29, 58,116,240,105,140,121,227,213, 17, 80,171,213, -160,178, 34, 0, 0,187,223, 8,198,152,183,235, 48,124,248,112, 44, 95,185,223,171,194, 84, 59,119,238,220, 58, 98,196, 8, 0, -168,216,178, 37,189,253,254,253, 7, 91, 17,138, 96,252, 99,227,147,146,146,146,182,123, 51,156, 0,246,216,255, 83, 67, 68,141, - 45,126, 16, 44, 90,184, 8, 81, 99,162,239, 88,193,172,148,148,148, 70, 26, 62,169, 3, 36,102,128, 33, 20,172, 54, 2, 9, 1, -162,100,180,243,241, 86,240,176,243,247,202, 87,155, 84, 16, 88, 15,172,144,139,229, 63,112,224,192,155,242, 1,188,113,209,185, -146,182, 31,200,217, 85,158,234, 22, 60,120,189,243,242,242,252, 38,239,126, 77,252, 99, 11,203,176,110,226,204,204, 76, 60,243, -204, 51, 0, 32,102,143,113,222,215, 48,104, 53,133, 83,131, 7, 15,126, 90,173, 86,103,218,108, 54,212,214,214,194, 98,177, 56, -226,254, 70,163,209, 49,197,144, 77, 12, 28, 51,102,140,154,195,243, 66,101,102,102,146, 6, 47, 64,163,231, 54, 47, 47,143,221, -142,196,196, 68, 78,222,170,219,157, 3,224, 26, 22,240,116, 63,154,219,175, 84, 42,201,234,213,171, 85, 79, 62,249, 36,190,249, -230, 27,159,238,185,235,244, 91,246,123, 70, 70,134, 42,165, 68,137,233, 30, 44,237,177, 99,199,146,139, 23, 47, 98,215,174, 93, - 77,182,247,197,139, 23, 1, 0,185,185,185, 30,207, 39, 57, 57,147, 36, 39,143,194,232,209,197, 40, 46, 46,118,155, 93, 94, 85, - 53, 10,128, 6, 74,101,211,227, 22, 75,254,102,179,153,136,197, 98,246,152,127, 54, 40, 4,111, 94,190,124, 25,157, 59,119,246, -201,242,167,105,202,174,176,179,228,127,220,138,207, 85,102, 0,192,242,149,251,189, 30, 35,216, 62,177, 96,193,130,120, 66, 8, - 38, 76,156, 48,117,210,196, 73,223,249, 50, 52, 77,126,226,241,211, 20, 69, 61, 72, 8, 32,120, 74, 11, 66, 8, 22, 45, 94,132, -232, 49,109,255, 8,124,248, 14,150,157, 9, 90, 80, 73, 48, 45, 45,141,100,188,218, 14, 65, 85, 23,113,161,182, 3,186, 72, 42, -128,192, 40, 8,235,203, 16, 82, 95, 5,160,141,195, 99,224,170, 52,240,240,193, 3,224, 60,221,207,197,213, 71, 50, 51, 51,193, - 53, 97,202,149,180,253,117,226,206,242,252, 48,255,159, 71, 11,225,236, 66,119, 38, 33,182,158,132,235,190, 38, 98,136, 86, 0, -223,142, 24, 49,226,197,156,156,156,143,173, 86, 43,106,106,106, 28, 57, 0, 0, 80, 81, 81,129,154,154, 26, 16, 66,224, 77,120, -105,244,232,209,138, 61,123,246,168, 50, 51, 51,145,149,149, 69, 92, 99,254,163, 71,143,246,170, 24,208,173,128,225,240, 11, 94, - 19,190, 59,130,111, 78, 9, 72, 77, 77,165,230,207,159, 79,124, 33,255, 70, 9,128, 78,247,221, 41, 41,208, 91, 47, 64,147,138, -251,165, 75,151, 28, 10, 26, 87, 67,195, 57, 84,121,243,117,115, 27,171,180, 90, 45, 9, 13, 13,117, 38,255, 55, 77, 38, 19, 74, - 75, 75,209,165, 75, 23,159,200, 95,169, 84, 18,230,155, 48,236, 62,110, 55, 78, 55,170,204,216,114,216, 12, 66, 8, 14,254,228, -123,100,241,192,129, 3,120,236,177,199, 20,190,150, 15,102, 9,154, 97, 24, 17, 0,124,243,147, 5, 11, 23, 46, 68,244,216,182, - 46,254, 1,239,192, 86,249, 27, 62,124, 56, 1,220, 79,247,115,170, 4,200,249,254,118,166,235,129,200,120, 60,189, 65, 11, 32, -202,222, 6,207,183, 70, 39,225, 85,188,157, 88,142, 47, 84, 42,190, 42, 32, 26, 87,250,115,181,252, 93,247, 11,155, 27, 40,210, -210,210,136,187,105, 83,222,132, 0,220,144,182,223,224, 34,207,175,243,255, 93,202, 1,123,141,228,228,100,112, 72, 88,228,140, -166,220,253,190,134, 1,154,114,247,251, 18, 6,112, 46, 47,235, 74, 62,205,237,107,234, 82, 41,138, 90, 59, 97,194,132,245,155, - 55,111,182,136,197, 98,152, 76, 38, 88,173, 86, 48, 12,131, 86,173, 90, 65,163,209, 32,217,203,169,103,211,166, 77, 83, 79,155, - 54,141,218,179,103, 15,201,202,202, 66,102,102, 38,216,186, 0,119,115,229, 57,127, 99,223,190,125,100,194,132, 9,216,177, 99, - 71,139,201,223,149,228,242,236, 10,153, 71,111,220,203, 47,191,124,147,113,225,138, 87, 94,121,133,112, 77,242, 84, 42,195, 60, -202, 83, 42,185,197,255,101, 50, 71,233, 75, 66, 8,129, 94,175, 71,105,105,169,207, 49,255, 70,158,143,183,235, 26,125,111, 9, -249,127,242,201, 39,254,122,102,153,236,239,183,119,119,174, 4,232, 47, 52,167,144,109,220,184,209, 43,235, 95, 57, 45,182,244, -179, 34,180, 75,205,186, 0,103,238, 25,254,223, 52,178,111,254, 3, 56, 87, 38,195,185,115,231,160, 80, 40,192,195, 15, 30, 0, - 0,104,138,228,239, 70, 45,235,110,155,255,239,143, 41,126,127, 40, 34,137,126, 59,175,233,211,167, 43,188, 45,239,235,129, 24, -136,179, 66,227, 46,209,202,117, 31, 71,194,181,206,154, 53,139,218,189,123,183,252,202,149, 43, 42,131,193, 0,155,205,134, 7, - 31,124, 80,145,144,144,224,243,253, 30, 61,122, 52, 53,122,244,104,118,132,247, 41, 52,115,171,115, 0, 60,125,231, 98,113, 54, -100,135, 55, 38, 28, 47,139,204,176,109,132, 55, 41,146,135,228,155,236,193,148,148, 20,146, 82,162, 4,213,184, 16, 16, 5, 0, -231,206,157, 35,205,244, 85,143,141, 62,106,212, 40,202,139,190, 79,249,227, 24, 0,168,174,174,134, 76, 38, 35, 20, 69,161,115, -231,206,160, 40,138,234,222,189, 59, 90, 74,254,244,147, 26, 80, 20,133,164,199,237,179,138, 40,138,114, 76,247, 99,221,249,119, - 8,204,192,217, 3,252, 42,112,238,220,185,172,242, 31,212,224,213,179,194,238,254,103,156,142,241,234,130, 83,179, 46,180,115, -230, 30,214,213,159,146,146, 66, 41,247,170,200,185,115,231,120, 54,247,183, 2,112,175,192, 31,115,253,253, 69,216,183, 64,177, -241,235,121,249,123, 97,159, 91,109, 61, 55,196,248,221,254,135,217,108,134, 64, 32,128, 64, 32,184,141,207,218, 58,234,238,150, -215,116, 95,152, 61,123,182,247, 2,223,252, 99, 29,139,204,204,204, 70,131,118, 74,137,210,217,242, 86,223, 15, 99, 73,116,116, - 52,245, 71, 95,177, 39,219,182,148,252,237,247,164,185,165,128,110,198,186,117,191,220, 54,141, 96,254,136,249,212,237, 30, 19, -188, 28, 55, 2, 97,207, 41,178, 56, 41,159,142, 56,191, 66,161,160,120,203,223, 51,220,133, 6,168,248,248,120,190, 96, 2, 15, - 30, 60,120,240,224,241, 39, 3,205, 55, 1, 15, 30, 60,120,240,224,193, 43, 0, 60,120,240,224,193,131, 7, 15, 94, 1,224,193, -131, 7, 15, 30, 60,120,240, 10, 0, 15, 30, 60,120,240,224,193,227,190, 64,163, 89, 0, 11, 22, 44,240, 57, 27,212, 93, 97, 23, - 94, 30, 47,143,151,119,251,228, 45, 91,182,172,177,118, 79,211,142,105,142,206, 83,205,216,106,138,206, 83,207,220,149, 15, 14, - 10, 10,130, 84, 42,117,252,158,166,105,199,140, 11,103,121,236,194, 76, 12, 99,159,229,197, 46,150,195,223, 95,111,228, 81,114, -129, 80, 2,194, 88,193, 48, 86,181, 47,242, 8, 33,138, 99,199,142, 9,227,227,227,243,224, 82,117,207, 71,121,242, 99,199,142, - 33, 62, 62, 94,205,247,183,123, 79,158,215, 10,192,159, 17,175,191,158,223,168,225,150, 47, 31, 68,221, 85,242,242, 95, 39, 0, -176,124,208,114,202,249,179,175,242,216, 74,113, 74,165, 18,169,169,169,205, 29,215,236,126,103,121,112,154,166,199,254,198,249, -247, 74,165,210,177,143,171,220, 63, 35,104,115,189,188,226,228, 97, 12, 15,171, 80,181,183, 94, 69, 17,233,130, 35,245,225,138, -144,184,135, 33, 14, 12, 86,123,250,253,161, 67,135, 48,116,232, 80, 7,241,179,132, 77, 81,212, 77,132,205, 48,140,227,117,249, -242,101,183,242,142, 30, 61,138,129, 3, 7, 66, 38,147, 65, 40, 20, 66, 32, 16, 52,146,201,146,190,205,102,115,188, 76, 38, 19, - 10, 10, 10,208,173, 91,183,251,241, 22, 81,118, 94, 36,242,223,127,255, 29,231,206,157, 83,181,106,213, 10,195,134, 13,107, 81, - 31,167, 40, 90, 46,145,134,163, 85,216, 3,170,122, 93,137, 66, 87, 92,229, 80,150, 0, 0, 32, 0, 73, 68, 65, 84,119, 85,238, -173, 12,134, 97,228, 89, 89, 89,251,138,138,138,176, 99,199, 14,200,100, 50, 44, 89,178, 68, 0,167,185,247, 62,200, 83, 21, 95, - 56,143, 61,187,115, 33,150, 72,176,112,225,162,145,132, 16, 21,223, 83,239, 83, 15,192,189,132,172,172, 44,143, 26,207,180,105, -211, 60,118, 76,150,160, 93,137,219, 87,248, 91,158,191,225, 84,153,143,211,160,197,165,180, 44, 87,121, 13,138, 64,139,170,139, -179, 85, 5,157,255,255,158,239,133,132,200, 79, 31,218,141,144,139, 63,169,244,122, 19, 44, 15,211,144,117,160,208,253,202,113, - 60, 20, 76, 84,154,138, 95,241, 91,192, 28, 69, 37,213,190, 89, 37,224,244,233,211, 16, 8, 4, 24, 54,108, 24,132, 66,161,227, -197, 42, 4,172,213,111,181, 90, 97,179,217, 96,177, 88,112,249,242,101,236,219,183,207,173, 60,189, 94,143,194,194, 66, 12, 30, - 60, 24, 98,177, 24, 34,145,168,145, 76,134, 97, 96,181, 90, 97,181, 90, 97,177, 88, 96, 48, 24, 80, 88, 88, 8,157, 78,119, 87, -232, 83, 13,207, 25,141, 63, 10,209,248,204,209,203,150, 45, 99, 92,198, 22,212,213,213, 33, 34, 34,194,167, 9,232,203,150, 45, -107,116, 62, 95,165, 23, 64, 38,107, 3,129, 64,172,210,213, 93,245, 90,102,126,126, 62,116, 58, 29, 6, 15, 30,124, 57, 49, 49, -177,109, 85, 85, 21,118,239,222,109, 11, 15, 15, 71, 66, 66, 66,179,125,100,238,216, 81, 55,181,205,137,179,103,161, 14, 14,192, -226,213,255,190,218,127, 64,239,142,215,175,149, 99,119,142,122, 95, 76,239,254,137,181,181,218,189, 60,117,222,253, 96, 75,255, - 58,195,181, 22,128,176,185, 65,150, 29, 92, 61,125,191, 19,228,255,220,115,207, 53,123,140, 70,163,193,215, 95,127, 77,184, 40, - 1, 44, 89,183,212, 90,191, 21,242,156, 45,255,150, 90,255, 78, 36, 76, 1, 32, 74,165,210,227,194, 49, 28,201,154, 98,137,157, -181,246,157, 45,127,103,170,227,250,204, 56,121, 42,136,115, 57, 97, 0,168,174,182, 87, 70, 12, 15,207,187, 47, 58,234,165, 95, -242,208,237,170, 74,117, 85,207, 96, 74, 55, 1, 30,136,180,130, 9, 39, 16,133, 11, 80, 87, 37,134,172,206,128,158,199,214,170, - 10,226,230, 43,244, 1,157,213, 77, 91,146, 20,206,156, 57, 3,177, 88,140,145, 35, 71, 58, 72, 91, 36, 18,129,166,105, 16, 66, - 96,177, 88, 96,181, 90, 97, 50,153,112,245,234, 85,168, 84,170, 38,151, 84,166,105, 26, 22,139, 5,199,142, 29,195,176, 97,195, - 32,147,201, 32,145, 72, 28,242, 88, 5,192,100, 50, 65,167,211,225,196,137, 19, 48, 26,141, 94, 21,102, 82,171,213,114,129, 64, -160,170,171,171,131, 88, 44, 70,121,121,249, 11, 83,166, 76,169,147, 74,165, 95,249, 66,218,106,181,122,186, 64, 32,248,198, 73, - 94,209,148, 41, 83,126,151, 74,165,211, 96, 95,161,210,107, 75,248,141, 55,222, 80,173, 88,177,162, 28, 13, 43,206, 44, 91,182, - 12,167, 79,159, 70,155, 54,109,154,172,187,238,137,252, 63,155, 55, 15,227,251,247, 7, 0, 68,191,248, 34,100, 1, 81,208,213, - 94, 65,173,246,130,130, 16,155,218, 91,153,125,251,246, 69,121,121, 57, 14, 29, 58,212,153,166,105,156, 56,113, 2,225,225,225, - 56,112,224, 0,204,102,179,199,118,172,122,103,113,163,239, 65,102, 11,218, 89,141, 88,248,242,155, 29, 87,127,240, 47,188,255, -193, 39,104, 79,219,240,201, 7,171,242, 70, 62, 53,147,103,215,123,144,252,217,237,156,214, 2, 0,110,174,255,237,233,251,237, -132, 63, 87,234,187, 23,224,172, 4,180,208, 3,192, 18, 44, 5,128,124,254,196,151,110, 9,249,153,173,115, 56,147,117,131,107, -159,114, 51, 96, 59,255,222,161, 32,112, 9, 1,176,255,237,250,238,234, 1,184,215, 97,172,169,148, 15, 55, 21,170,202, 5, 54, -116, 11, 5, 58,119, 34, 16,244, 21, 67,216,181, 43,196, 38, 35, 76, 63, 94,133, 73, 43,132,128, 17,193,152,247,149,138, 30,255, - 55, 5, 35,116, 31, 14, 96,221,243,231,207,159, 71, 88, 88, 24, 20, 10, 5,164, 82, 41,196, 98, 49,132, 66,161,195,234, 55, 26, -141, 40, 45, 45,197,254,253,251, 65,211, 52,104,154, 70,115,242,108, 54, 27, 78,157, 58,133,161, 67,135, 34, 36, 36, 4, 82,169, - 20, 2,129, 0, 86,171, 21,102,179, 25,181,181,181,248,245,215, 95, 97, 50,153, 32, 20, 10, 29,185, 0,158,176,105,211, 38,185, - 78,167, 83, 93,188,120, 17,181,181,181, 16,139,197,136,142,142, 94,123,240,224, 65, 12, 25, 50, 68, 24, 24, 24,248,185, 55, 74, -192,166, 77,155,158,208,233,116,223,184,200,139, 59,120,240, 96,220,144, 33, 67,190, 14, 12, 12,156,198, 85, 30,195, 48,114,179, -217,140,234,234,106,149,147, 71, 1, 0,176, 98,197,138,146,101,203,150,181,159, 54,109,218, 72,169, 84,234,213,248, 71, 11,196, -114,215,109, 55, 62,254, 24,209,147, 59,224,253,247, 63, 82, 88, 44,245, 62,141,167,135, 14, 29, 82,253,242,203, 47,120,245,213, - 87,107, 5, 2, 65,136, 84, 42,197,144, 33, 67,160, 82,169,144,147,147,131,246,237,219,123,225,239,160,176,233,252,117,124,123, -174, 4,217,223,127, 1,129,128,194,226, 23,159,102,250, 69,183,166,211, 22,190,137, 13,222,202,227,113, 71,200,223, 85, 57,117, -167, 20,248, 60, 11,224, 78, 47,111,219,181,107, 87,133,167,215,237,182,214,111,133, 60,127, 88,253, 77,225,243, 39,190,164,158, -217, 58,135,184, 35,127,112, 15, 17, 52,178,244,171,171, 19, 29, 22, 58,254, 88, 2,212,107,183,127,115, 68, 31, 30,158,231,147, -245,111,181, 90,229,191,254,250, 43,105,106,155,235,190,166,224,124,188,213,106,149,187,238,115,221,214, 28,170, 79, 29, 85,149, -150,212,162, 77,176, 16, 93,131, 9,132,173, 25, 8, 31, 25,135,192,126, 95, 65, 54,224, 67, 72, 66,101, 16,235, 12,208,235,109, -232, 36,208,227,192,230,166,149, 39,154,166, 33, 20, 10, 33, 18,137,112,238,220, 57,156, 56,113, 2, 33, 33, 33,136,136,136, 64, - 68, 68, 4, 90,183,110,141, 86,173, 90, 65,171,213,226,192,129, 3, 16, 8, 4,142,216,190, 59,176,251,197, 98, 49,108, 54, 27, -138,138,138, 16, 16, 16,128,214,173, 91,163, 77,155, 54,136,140,140, 68, 80, 80, 16,138,138,138, 96,177, 88, 28, 33,130,166, 20, - 10, 87,203,191,172,172, 76,117,225,194, 5,116,233,210, 5, 99,199,142,197,160, 65,131,160,215,235,177,111,223, 62, 28, 59,118, -236, 83,163,209,200,185,118,177, 90,173, 86,148,149, 87,124, 87,124, 93,139,224,110,131, 17, 55,246, 47,104, 63, 40, 9, 26, 19, -141, 61,121,123,113,236,216,177, 41, 70,163,241,175, 92,201,191,182,182, 22,199,143, 31, 87, 29, 58,116, 8,125,251,246,197,178, -101,203, 90,163, 33,158,190,108,217,178,246, 0,224, 13,249,211, 2,177, 60, 48,168,157, 60, 60,162,183,106,243,150,227,152,247, -217,103,200, 41, 44, 68, 78, 97, 33,162, 95,124, 17, 0, 96,177,212,239,247,165, 31,231,228,228,144,236,236,108, 76,157, 58,245, -114,112,112, 48, 29, 16, 16, 80,144,159,159,143, 67,135, 14,161,178,178, 18,113,113,113, 94,201,251,168,240, 28, 62,248,249, 36, - 54,124,240,218,113,161,192, 0,218, 86,135,247,214,124, 70,127,115,160, 0,165,180, 16, 15, 60,240, 0,207,178,247, 9,104, 95, - 9,254, 14, 46, 94,113,107, 44,236,215,243,137, 63,227,246,254,150,119, 43, 21,129,103,182,206, 33,206,175,166,188, 2,158,188, - 10, 55,145, 91, 99,101,192, 91, 79, 5,213,212,118, 87,175, 0, 23,212,213,213,201,247,238,221,171,202,207,207,111,114,155,243, -190,230,224,124,252,222,189,123, 85,117,117,117,114,231,125,174,219,154, 67,136,177, 10, 57, 87,140,216,121,145,193, 85, 13,133, -178, 10,128, 22,134,130,166, 34, 64, 25, 37,168, 47,163,112,252, 10,131, 19, 87,140,168,170,179,160, 79,184, 68,197, 69, 1,144, - 72, 36,184,112,225, 2,206,158, 61,139,240,240,112,132,133,133, 33, 44, 44, 12,122,189, 30,135, 14, 29,130, 72, 36,130, 88, 44, -110,118, 45, 5,214, 59,192, 42, 1,132, 16, 20, 23, 23, 35, 60, 60, 28, 29, 58,116, 64,100,100, 36,138,139,139, 97,179,217, 32, -145, 72, 32, 22,139, 27,205, 60,112, 55,172,176, 31, 42, 42, 42, 84,215,174, 93, 67,175, 94,189, 48,110,220, 56, 76,156, 56, 81, - 49,113,226, 68,197,176, 97,195, 96,179,217,240,211, 79, 63,161,184,184,120, 48, 0, 78,241,132,138,138,138,125,101,213, 90,132, -199,246, 67, 92,226, 92,244,154,176, 0, 61, 39,204, 71,231, 71,158,128,153, 8, 88,121,156,238,111, 67,238,131,234,220,185,115, -236,181, 42, 26,136,159, 94,182,108, 25, 86,172, 88,129, 21, 43, 86,156,117,205, 11,104, 10, 2,161, 84, 30, 22,222, 83, 21,221, -126,168, 42, 44,162, 39, 40, 90,136, 79, 63, 87, 97,222,103,159, 97,222,103,159, 97,197,138, 21,168,168,168, 0, 87,121, 46,150, - 63,217,190,125, 59,134, 12, 25,130, 1, 3, 6,116, 6, 32,221,187,119,239,192, 75,151, 46,225,212,169, 83, 48, 24, 12,152, 48, - 97,194, 72,174,242,210,127,191,138, 15,127, 61,139,245,203, 95,174,238,240, 64,231,190,122,157, 6,233,223,237,197,241, 19,191, -227,192, 15,123,160,189, 81,134, 9, 19,198, 39,130,199, 93,139,248,248,248, 38,173,127, 78, 57, 0,169,169,169, 84, 94, 94,158, -156,235,247,123, 25,254,180,212,111,133, 60,192,127,238,255, 38,173, 80,167,152,186,183,228,207,122, 1,156,173,115,127,192, 83, -242,161, 55, 80,171,213,242,210,210, 82, 21,187,184, 75, 83,219,124,193,249,243,231, 81, 85, 85,165,106,215,174,157, 66, 46,151, -171,155,218,214, 36,113, 85, 94,197,225,235, 6, 76, 8, 8,192,193,171, 12,218, 13,144,160,139,169, 0,154,211,207, 97,235,123, -199,193, 92,210, 66,103, 38, 40,169,179, 65, 38,164, 97,213,222, 64,104, 51, 74,187,179, 18, 32,149, 74,113,249,242,101,156, 61, -123, 22,189,122,245,130, 70,163,193,207, 63,255,236,136,229,123,138,215, 83, 20,229,240, 2,176,242, 8, 33,184,122,245, 42,250, -244,233,131,188,188, 60, 48, 12, 3,169, 84, 10,145, 72,228,152, 37,192,197, 3,112,229,202, 21, 24,141, 70, 12, 28, 56, 16, 29, - 58,116, 80, 8, 4, 2,132,132,132,224,225,135, 31, 86,252,252,243,207,170, 43, 87,174,160,182,182,246, 4, 56,186,236,175, 92, -185, 2,134, 22,163,125,124, 34, 90,117,136, 3, 45, 16, 65, 22, 18,137, 78, 15, 79,192,229,159,179,209, 32,239,146, 39, 57,132, - 16,121, 77, 77,141,170,164,164, 4,157, 58,117,194,163,143, 62,170, 16, 8, 4,234,161, 67,135, 82,203,150, 45, 35,131, 7, 15, -182, 54,140,155,113,161,161,161,104, 80, 80,108,205,201,148, 74, 35, 16, 17,217, 15,102,147, 22,149, 85,133, 48,153, 52,163, 44, - 22,221, 32, 0,239, 12, 30, 60, 24, 0, 80,118,227, 6, 26,228,137,224,180,232, 77,115, 56,122,244,232,180,205,155, 55, 99,214, -172, 89, 24, 58,116, 40, 0, 48,187,119,239, 22,230,228,228, 96,222,188,121, 99,250,246,237,187,199,155,103,185,168, 86,143,165, -251,127,195,187,127, 87, 98,216,196,196,240,122, 93, 37, 50,190,219,143,212, 79,191,197,206,197,115,209,181,252, 26, 86,214,222, - 64,120,120, 4,159, 4,120,143,192,217,237,239, 46, 95,165,201, 28, 0,215,216,190,167,239,247, 35,252, 61, 5,207, 87,188,253, -208,219, 10,138,162,238,202,246,118,153,234,215, 40, 15,192, 85, 25,240,231,244, 63,174,202, 65,118,118,182,188,172,172, 76,101, - 54,155,155,221,214, 18,104, 52, 26,212,215,215,171,106,107,107, 21,238,182, 37, 37, 37, 53,121,239,142, 85, 27,160, 53, 51, 56, - 86, 97, 69,105,141, 21, 81, 63, 11,209, 55,227, 60, 46, 95, 58,133,223,127, 49,195, 42, 20,192,204, 0, 70, 51,129,134, 48,136, - 12, 35,205, 18,182,243,244, 63, 54, 99,191,172,172, 12,157, 59,119,198,165, 75,151, 28, 46,127,161, 80,232, 56,222,219,112,158, -115, 13, 1,246,253, 22,133, 4,107,208,178,236,253,155,140,113, 79, 7, 48, 12,131,250,250,122,251,224, 40, 20, 42, 4, 2,129, -218,197,147, 36,204,206,206, 70, 82, 82, 18,189,116,233,210,178,149, 43, 87, 90,151, 46, 93,218,236,197, 83,148, 93, 33, 50,232, -203,160,171,187,170,176,217,140,106, 0, 7, 0,188, 83, 87, 87,135,236,236,108,135, 50,217,173, 91, 55,179, 39,121, 13,207, 87, - 82, 86, 86, 86,230,132, 9, 19, 28,228,255,227,143, 63,210,219,182,109,131, 92, 46,159,232, 45,249, 95,215,155,240,116,206,207, - 88, 56,125, 2,166, 61, 61, 21,122, 99, 45,182,102,171,177,230,147,116,124, 57,230, 33,116, 45,191,198,179,233,125,160, 12,184, - 42, 1,183,165, 18,160, 82,169, 36,206, 49, 93, 79,223,121,220, 52,176,223, 82,242,247, 53,166,206, 18,191,107,182,191,139,235, -159,106,120,185, 61,182,169,231,197,211,115,193,245,121, 73, 74, 74, 82,119,239,222, 93, 17, 22, 22,214,236,182,150, 32, 44, 44, - 12,221,187,119,111, 68,244,238,182,185,131,193, 22, 2, 11, 5, 28,169, 52,161,220,102,195,222, 98, 35, 50, 50,141,216,119, 45, - 18,231,197,161,184,166,181,224,106, 29,131,122, 43,160,183, 18, 72, 34,162, 61, 18, 51, 59,191,223,102,179,193,106,181, 34, 34, - 34, 2, 65, 65, 65,232,220,185, 51, 44, 22,139, 99,187,187,130, 64,174,242,216,249,253, 86,171, 21, 6,131, 1,132, 16,116,236, -216, 17, 37, 37, 37,104,219,182, 45,132, 66, 33, 76, 38, 19,204,102,179,227,127,185,132, 7, 59,117,234, 4,169, 84,138,130,130, - 2, 92,187,118, 77,101,179,217, 80, 91, 91, 75,253,242,203, 47, 42,157, 78,135, 78,157, 58, 33, 36, 36,100, 28,215, 49,170, 83, -167, 78,160, 25, 51, 74, 10,243, 80,115,173, 8,140,205, 2, 67,109, 5,174,252,242, 3,204,245, 26, 86, 94, 12, 23,229,134, 69, - 68, 68,132,138, 97, 24,135,167,115,197,138, 21,212,169, 83,167,208, 64,218, 12,128, 40,119, 5,143, 92, 97,181, 26, 96,181,232, - 32, 11,140,134, 84, 22, 14,128,146, 3,176,174, 88,177, 34,194, 73, 30, 54,108,216,192, 22, 80,114,123,205, 85, 85, 85,228,203, - 47,191, 36,169,169,169,228,223,255,254,247,247, 73, 73, 73,152, 56,113, 34,235, 13,168,221,190,125, 59,166, 77,155,150, 52,125, -250,244, 31,184,180, 89, 85, 85, 21,249,234,171,175,200, 83,207,189,128,145, 89,251,241,247, 57, 83,240,210, 43, 11, 96, 52,235, -112,241,194, 85,164,166,102, 96,219,164, 33,144,119,108,227,115,223,216,182,109, 27, 63,174,223, 65,184,134, 3, 92, 19, 1,111, -107, 41, 96,215,176,129,167,239,183,205,210,111, 34, 86,239,106,237,115,181,254,155,146,151,255,250,235, 36,255,245, 63,220,249, -174,223, 61,121, 34,252, 37,207, 25,172,203,255,243, 39,190,164,124,113,255,167,166,166, 58, 44,251,166,226,253,236,118,231, 99, - 61,193, 83,254,128, 55,225, 1,185, 92,174,158, 52,105,146,194,185, 56,141,187,109,190,160, 91,183,110,152, 52,105, 82, 35, 87, -191,187,109, 77,254,190,123, 55,116, 15, 20, 32,152, 2, 44,132,224,140,198,140,205,231, 77,248,250,112, 41,126,189, 80,141, 82, - 3, 80,101,180,225,130,142,224,186,137, 64,103,182, 40,154, 35, 47,118,106,158,217,108,134,193, 96, 64,219,182,109,209,187,119, -239, 6, 69, 47, 28,131, 6, 13,114, 16, 54, 75,218, 77, 17, 54, 75,232, 22,139, 5,102,179, 25, 20, 69, 33, 54, 54, 22, 53, 53, - 53,184,122,245, 42,170,171,171, 17, 19, 19, 3,154,166, 97, 54,155, 97, 50,153, 28,191,241,132,200,200, 72, 69,135, 14, 29,112, -234,212, 41,236,218,181, 11, 59,118,236, 80,237,216,177, 99,223,193,131, 7, 33, 16, 8,240,200, 35,143,160,107,215,174, 6,112, - 44,100, 19, 25, 25,153, 20, 21, 30,138,170,226,223,240,251,158,207,113,234,135,117, 56,243, 67, 42, 46,255,180, 13, 18,154, 97, -229,149,120,146, 35, 20, 10,213, 81, 81, 81,138,144,144, 16, 28, 59,118, 12,215,174, 93, 83,233,245,122,185,179, 34,208,224, 9, -160, 55,111,222,140, 94,189,122,121, 60, 55,179, 73, 11,109,205,121,136, 68,129,104, 21,222, 67, 21, 24,212, 30, 34, 81,160,156, -162,232,193,236, 49,193, 53,121, 80,125,249, 18, 70,247,208,177, 74,243, 77,248,225,135, 31, 32,147,201,208,171, 87, 47,196,196, -196,160, 33,124, 96,213,104, 52,186,172,172,172, 86,241,241,241, 73, 35, 71,142,220,206,245,217,205,201,249, 1, 33, 33, 65, 24, - 62,226, 97,125,252,128,190,120,226,185,121,208, 83, 86, 84,148, 87, 99,254,139,111, 97,101, 66, 55, 12,104,227,187,146,188,109, -219, 54,242,222,123,239,241, 74,192, 93,162, 8,184,195, 93,179, 22,192,157,158, 85,224, 11, 1,123,139, 65,203,237, 10,132, 51, - 81,179,219,110,151, 60,103, 43,252,153,173,115,240,204,214, 57,141, 62, 59,111,227,106,177, 59,123, 18,220,121, 20, 90,154, 23, -224,236, 9,112,125,231,138,224,224, 96,245,168, 81,163, 20,131, 6, 13,106,114,155,243,190,102,219,221,233,248, 81,163, 70, 41, -130,131,255,152,150,231,110, 91,179,214,161, 36, 80,209,167,109,107, 60, 26, 33,193, 67, 97, 98,180,147,210,144, 16, 2,169,201, -138, 78, 65, 66,104, 8,193, 73,157, 21, 69,245, 86,180,111, 19,129,152,135, 70, 52, 41,139,181,250,217,169,126,157, 58,117, 66, -191,126,253,160,209,104, 80, 83, 83,131,154,154, 26, 4, 7, 7, 99,240,224,193, 48,155,205,142,154, 0, 77, 17, 54,171, 76, 88, - 44, 22, 80, 20,133,184,184, 56, 24, 12, 6, 84, 84, 84,160,188,188, 28, 21, 21, 21,168,175,175, 71, 92, 92, 28,132, 66,161, 67, - 94, 83,117, 5, 92,149,178,168,168, 40, 69,108,108, 44, 46, 94,188,136,220,220, 92,228,231,231, 35, 32, 32, 0, 35, 71,142, 68, -191,126,253,126,144, 74,165,139,193, 49, 4, 32,151,203,183, 71,181,137,156, 29,219,182, 21,116, 23,126, 65, 81,238,167, 40,201, -255, 30, 97, 18, 27, 18, 71,141, 68,191,126,253,230, 74,165,210,108, 46,178, 66, 66, 66, 48, 96,192, 0, 16, 66,112,248,240, 97, - 20, 20, 20,168, 74, 74, 74, 84,213,213,213,242,101,203,150, 41,216,202,137, 9, 9, 9, 56,112,224,128, 71,121, 12, 99, 81,107, - 53,231, 21,213, 21, 39, 32,145,134, 35,186,221, 35,170,200,232, 65,170,224,144,152, 31,222,255,224, 63,147, 88,121, 95,255, 45, - 0, 91,126, 52,161, 41,165,167,168,168, 8,173, 91,183,198,208,161, 67,153,135, 30,122, 8,122,189, 30,245,245,245, 88,187,118, -109, 80,143, 30, 61, 38, 63,245,212, 83,219,189,233, 19,191,255, 94,132,206,157, 58,224,169,167,146, 2,222,120,125, 33,170,234, -180,168,172,170, 68,202, 75,111,225,173, 39, 70, 97, 84,167,168, 22,145,255,154, 53,107,208,187,119,111,124,252,241,199,188, 18, -112, 27,241,219,111,191, 53, 89, 7,224, 38,133,247,110, 33,120,111,102, 21, 76,155, 54,141,242, 87, 37, 64, 79,112, 45,196,227, - 15, 37,192, 31,228,239,171,188,166, 74,245,186, 90,230,222,148,236,117, 81, 18, 28, 69,129, 90,114, 93,206, 74,131,179,181,239, -203, 12, 0,103,235,238,161,135, 30,162,154,218,230,186,175, 41, 52,119, 60, 87, 25, 44, 30,145,143, 84, 23, 11, 9,172,249, 57, -184,164, 5,130, 40, 17, 58, 7,209, 40,177, 81, 16, 72,132, 56, 80,110,131,145, 1, 34, 37, 2,196, 38, 12,135,180,123,130,186, - 57, 5,192, 98,177, 64, 32, 16,160, 75,151, 46, 24, 48, 96, 0,106,107,107, 97, 52, 26, 29,243,243,205,102, 51,194,195,195, 49, -116,232, 80,108,223,190,221, 17, 18,112, 7,155,205,230,200,234,239,217,179, 39, 26,220,244, 48, 26,141,142,254,204,122, 18,122, -246,236,137,234,234,106,232,116,186,230,250,114,163, 29,179,103,207, 86,171,213,234,145,189,122,245,218,231, 84,184,167,102,216, -176, 97,251,164, 82,233, 44, 0, 70,111,218,114,246,236,217,155,213,106,117,109,175, 94,189,178,157,228, 85, 14, 27, 54,108,173, - 84, 42,253,130,171, 28,154,166,213,237,218,181, 83,140, 29, 59, 22, 23, 47, 94, 84,157, 61,123, 22, 87,174, 92, 65,112,112,176, -170, 85,171, 86, 24, 61,122, 52,254,247,191,255, 33, 33, 33,129,243,185, 89,173,122,117,141,230,119,133,209, 88,141, 86, 97,113, -170,160,224,142, 8, 14,233,132,250,186,146,237,239,174,252, 20, 51,158, 74,196,215,127, 11,112,219, 78, 44,198,143, 31,143,156, -156, 28, 92,187,118,141,174,174,174,134,209,104,196,129, 3, 7,132, 13, 74,103,173,183,253, 97,194,132,241,216,186,117, 59,106, -107,170,112,173,244, 58,254,246,252, 28,243,203,175,174, 16, 63, 49,114, 8,134,154,106, 1,145,111,244,176,109,219, 54,242,207, -127,254,211, 81, 14, 58, 54, 54, 22,239,189,247, 30, 94,121,229, 21, 50,121,242,228,123,191,114,231, 61,170, 20,220, 49, 5,224, - 86,204, 42,240, 7,185,179,168,172,252, 20,175,231,127,223,108,181, 61,111,146,255, 42, 43, 63, 69,254,235,127,200,115, 38,102, - 87,151, 61, 23,210,174,252,180, 18,249,223,191,238, 55,121,254, 4, 23, 15, 1,187, 6,128, 55,207,203,159,169,115,198, 12, 81, - 40,142,155,172,170,138,125,123, 33,178, 26,112,188,142, 32,175,206, 10, 49, 69, 33,130, 16, 40,218,182, 66, 88,116,164,162,195, -195,114, 15,150,166,221, 3, 16, 19, 19,131, 65,131, 6,193, 96, 48,192, 98,177, 64, 44, 22, 59, 8,155,181,210, 35, 35, 35,241, -232,163,143, 34, 55, 55,183, 89, 15,128, 80, 40, 68,191,126,253, 64, 81, 20,244,122,189,195,187,192, 42,237,108,117, 65,134, 97, -208,167, 79, 31,252,252,243,207,240, 38,185, 82, 46,151,171,240, 71,158, 72, 16,236,213,246,174,128, 99, 38,188, 59, 79,128,147, -172,112, 0,213, 0,188,174, 77, 76,211,180,186, 85,171, 86,232,211,167,143, 66, 36, 18,177,211, 31, 85, 0, 80, 82, 82,130,199, - 30,123, 12,171, 86,173,242, 74,166,205,102, 82,215,235, 74,228,102,179, 86, 33,171,189,164, 10,105, 21,139,128,160,118, 8, 8, -106,135,221,123,203, 64,141,106,222,226, 30, 50,100, 8, 37, 22,139, 73,117,117, 53,198,143, 31,111,142,136,136, 16, 51, 12,131, - 43, 87,174, 0, 62, 36, 75, 62,242,200, 16, 74, 34,145,144,144,211, 5,120,254,249,191,160, 67, 92,119,241,123, 11,255,194,108, -252,228, 11,122,173,192,232,211,179,188,109,219, 54,178,116,233, 82,180,106,213, 10,165,165,165,144,201,100, 96, 24, 6,129,129, -129, 88,190,124, 57, 94,127,253,117, 94, 9,184,197,136,143,143,111,210, 11,192,105, 26,224,173,192,221, 60,171,160, 57,194,241, -197,250,111, 74,158,171,165,206,186,238, 61,145,182,191,229, 57,123, 2,124,221,223,156, 87,193,117,241, 31,111,229,253,217, 64, -211,180, 58,126,212, 88,170,186,222, 32, 15,181,154, 84,130,203,197,232,102,185,142,224,136, 40, 12,233,211, 3, 17,237, 91, 43, - 66,227, 71,120,236, 31,132, 16,116,233,210, 5, 67,135, 14,117,196,227, 5, 2, 1, 76, 38,147,163,116,175,115,152,160, 99,199, -142,120,244,209, 71,161, 86,187, 23, 45,147,201, 16, 31, 31, 15,161, 80, 8,179,217,236,248,157,243,212, 65,231,133,128,104,154, - 70,255,254,253, 81, 80, 80,224, 75, 51, 16, 0,117, 13, 47,127, 64,231, 11,241,187,243, 26,245,238,221,155,205,163,160, 24,134, -145,235,245,122,152, 76, 38,244,232,209, 3,171, 87,175,246,114,113, 28,162,182,152,235, 96, 49,235, 20, 6, 67, 5, 36,146, 48, -136,196,193, 42,154, 22, 98,211,230, 31, 20,179,103, 77,104, 86, 94, 67, 93,127,234,195, 15, 63,100, 12, 6, 3, 0, 32, 46, 46, -206,171,242,203,206, 24, 48, 96, 32, 37,120,232,161,199,230,253,243,195, 28,187, 60, 66,199,197, 61,128,184,201,147,103, 11,133, -194,205,190,200, 92,185,114, 37,223,169,239, 18, 37,160, 57,242,191,173, 10,192,189, 10,127, 78,251,115, 37,230,150, 90,235,254, -146,215, 18,139,219,153,216,217,207, 46, 46,123,254, 33,226,136,145, 73,147,213, 13,214, 43,134,251,240,251,228,228,100,132,133, -133, 57, 50,252, 25,134,113,184,240, 89, 15, 0,155,244,199,174, 8, 24, 27, 27, 11,138,162,176,101,203,150,155,228,173, 89,179, - 6,153,153,153,142, 99,109, 54,155,199,229,128,197, 98, 49, 18, 18, 18,192, 37, 59,254, 94, 85,214,130,130,130, 16, 20, 20,132, -136,136,136, 22,244, 29, 86, 17,168, 3, 77, 11, 97, 79,199, 98, 84, 28,229,145, 37, 75,150, 80, 13,247,147,208, 52,221,162,113, -196,102, 99,118, 46, 90,180,136, 2, 64, 51, 12, 99,163,105, 90, 6, 47,195, 47, 44,120,235,254,238, 82, 2, 60,129,138,143,143, -231,147, 51,120,240,224,193,131, 7,143, 63, 25,104,190, 9,120,240,224,193,131, 7, 15, 94, 1,224,193,131, 7, 15, 30, 60,120, -240, 10, 0, 15, 30, 60,120,240,224,193,131, 87, 0,120,240,224,193,131, 7, 15, 30,247, 5, 26,205, 2, 88,176, 96,129,207, 25, -156,235,214,173,187, 41,153,144,151,199,203,227,229,221,127,242,148, 74, 37,121,124,178, 18,223,111, 75, 69,106,106, 42, 13, 55, -115,208,249,246,227,229, 45, 95,190,220,113,204,235,175,191, 78,241,237,119,123,229,121,173, 0,176,157,187,169,131,125,153,242, -114, 47,203,243, 69,230,221,126,189,110, 32, 6, 16, 2, 32,160,225,121, 96, 0, 84,194, 15,115,168,253, 9,182, 29,252,113,205, -238,218,244, 78, 21, 31,170,171,171,147, 31, 62,124, 88,181,127,255,126, 0,192,136, 17, 35, 48,100,200, 16,206,165,132,239,196, -125,120,124,178, 18,227, 31, 27, 96, 5,148, 66,165, 82,201,252,217, 10, 55,241,240,140,229,203,151,147, 73,147, 98, 27,125,247, -164, 4,240,184,195, 30, 0, 22, 36,227,230, 5, 32,168,233,190,175,155,238,110,128,104,201,234,127,254,150,231,238,122, 91,114, -205,119,251,245,178,196,127,234,248,193,207, 79,157, 58, 54, 42,186,125,108,148, 86,107, 65,104,168, 8, 55, 74, 46, 48,189,122, -245,171,238,213,119,216, 32, 0, 23,189, 17,120,244,167, 79, 72,241,133, 34, 92,184,100,196,213,235, 4, 29,219, 82,136,141,145, -162,107,108, 28, 6, 60,242,220, 93,209,249,221, 41, 18,236, 90, 3,119,130,200, 78,156, 56,161,138,143,223,133,245,235,245, 80, -171,129, 55,223,220,141,171, 87,175,170,162,163,163, 33,149, 74, 81, 90, 90,170,120,226,137, 39,224, 15,133,224,224,193,131, 68, -171,213, 42, 70,143, 30, 13,137, 68,226,139, 60, 26, 0,198, 63, 54,128, 73, 73, 73, 17, 2,105,248,126,155,189,171,192,191,203, -246,242,184, 15, 96, 54, 47, 69,110,110, 10,198,142, 77,195,164, 73, 43, 29, 30, 1, 94, 17,184, 61,224, 11, 1,121, 1,103,178, -167, 40,128,249, 38,236,190,189, 86,139,185,254,233,220, 93,223, 44,235,214,173,123,143, 41,147, 71,160, 99,251, 16,180, 10,149, - 64, 83, 99, 68,201,245,142,244,185, 98, 77,235, 29,217,159,169,198,142,123,242, 67,145, 56,240, 99, 79,242, 78,159,216, 47,191, - 88,180, 67, 37, 64, 45,158,156, 0, 60, 58, 16,136,237, 12,156,191, 68,112,232,136, 1, 57,170, 99,248,225,219,151, 73,151,184, -137,138, 7,251,120,174,104,119,171,188, 29, 77,121, 17, 82, 83, 83,169, 59,165, 4, 84, 87, 87,227,165,151,244,136,140, 4,146, -147,129,119,223,213,161,176,176, 16, 86,171, 21, 82,169, 20,109,218,180, 81,237,216,177, 3,221,187,119, 87, 36, 36, 36,168,189, - 28, 0,228, 39, 79,158, 68, 84, 84,148,106,244,232,209,212,166, 77,155, 0, 64,149,151,151,135,153, 51,103, 98,208,160, 65,222, - 94,171, 24, 0,114,118, 30,165,129, 52,198,254,110,215,161,249, 17,132,135,179,181, 15, 0, 83,167,126,139,220, 92,251,123, 74, -202, 5,176, 30, 1,222, 27,112,123,137,223,121,251, 29, 43, 5,124,183,131,100,132, 57,148,128,251,153,252, 1, 8,247,228,102, -188,161, 24, 62, 32,238,161,254,109, 65, 81,246,170,110, 12, 67, 16, 18, 36, 65, 96,172, 24, 49,255,191,189, 43,143,107,226,218, -254,223, 73, 66, 8, 8,178,136,136,168, 84, 1, 23, 4, 21,113,215,170,196,162, 20, 4,220,138,246, 87,219, 87,237, 66,244,245, - 89, 95,139, 21, 43, 93,180, 45, 85,124,218,218,250,218, 26,124,173,218,214,247, 90,169, 10,238, 84,106,112,169, 90, 21,183,138, - 86, 5,220, 42, 42, 85,217, 73, 8,201,220,223, 31, 97, 48,132, 44, 51,147, 32,218,206,247,243,225, 67,114, 51, 57,153,185,119, -230,126,207, 57,247,156,115,187,120,160,147,159,219, 99,123,114, 54,190, 21, 27, 63, 51, 19,192, 45,107, 2, 47, 95,220,174, 26, - 57,160, 18,255,156, 9,136,197, 6, 5,170, 94, 7,180,113, 5, 66,130,129,161,225,192,118, 85, 37,142,156,222,174,234,221,103, - 52,175, 7,223, 81, 75, 0,150,190,207, 40, 1, 15,122, 48,188,189,189,177,125,187, 11,186,116, 81, 35, 47, 15, 40, 43,147, 32, - 56, 56, 24,193,193,193,168,174,174, 70,113,113, 49,242,242,242, 80, 89, 89,169,234,217,179, 39,235,165,129,205,155, 55, 71,170, -213,106,149, 84, 42, 69, 89, 89, 83, 79,150, 90,173,198,151, 95,126,137,226,226, 98,242,244,211, 79,115,233, 79, 26, 0,178,179, -148, 0, 20, 34,195,127,254, 56,118,236, 88, 99,127, 51,155, 40,153,107, 99,115, 95, 24,143, 45,219, 54,155, 70, 1, 33,145,184, -112, 1,131,171,171, 85,237,110,220,192,239,190,190, 56,209,182,173,220,169,119,111, 16,138,202,227,123,205, 92, 55,140, 98, 35, -131,109, 91, 75,203, 51,118,253, 39, 37,229, 32, 62, 62,168,241, 63,131,248,248, 32, 65, 9,120, 0, 48, 37,123,102,127, 0,227, -118, 33, 11,192,244,161,255,147, 95, 95,193,153, 3, 75,131,131,131,123, 12,142,232,216,164, 93, 36,162, 32,149,138,225, 34,147, -192,201, 73,132,160,110, 94, 8, 10, 10,246, 45, 56,115, 96,187, 53, 69,241,196,225,207,137, 24,149,120,237, 5, 64, 83, 7, 92, -190, 14,148, 85, 0,229,149,192,127,183, 2,115, 22, 1, 11,151, 3,195, 35, 0, 17,169,196,137,195,159, 11,214,162, 17,250,244, -233, 35,207,206, 14,129,175, 47,240,204, 51, 18,248,249, 13,194,232,209,163,229,241,241,241, 84, 92, 92,156, 60, 58, 58, 26, 29, - 58,116,192,137, 19, 39,240,253,247,223,171,126,252,241,199,200,186,186,186, 72,107, 50,191,253,246,219,200,186,186, 58,149,147, -147,147,213,223, 86,169, 84,216,184,113, 99, 36, 27,146,221,191,127, 63, 1,160, 85, 42,149,210,251, 74,192,125, 50,221,191,127, - 63,225,170, 64, 29, 61,122,180,241,207, 90, 27, 31,165,142,109,155, 53,242, 15,252,237, 55,213,164, 83,167, 84, 93, 46, 22, 66, - 90, 89,137,142, 23,127, 67,228,145,195,170,246,167, 79,171, 64, 72, 36,159,241, 62,122,244, 40,142, 29, 59, 70,206,158, 61, 27, -201,247,158, 97,100,176,105, 99, 43,207,148,232,217,180,217, 2, 67,250,204,127,109,124,176,240,192, 63, 32,226,103, 83, 6,248, -145,245, 0,180,164,165, 70, 90,240,252, 28,229, 98,102,228, 91,250, 29,107,191, 81,112,238,116,204,212,201,242, 70,210, 55, 7, -153,179, 4,229, 21,117,232, 17,228,141,204, 45,170,160,208,190, 35, 61, 44,201, 43, 46,186,136,105,227, 13,175,119,239, 7, 62, -251, 6, 24, 55, 18,136,141, 4,126, 43, 4, 78, 22, 16,184,200, 40,244, 15, 5,162, 71, 3,155,115, 46, 34, 98,152,227, 44,119, - 62,125,215, 66, 49, 21,188,224,238,238,158, 87, 93,109,136,183,124,230,153,103, 48, 98,196, 8,202,248,179,123,247,238,201, 67, - 66, 36,170,132, 4,128,162,142,163,180,180, 86,245,251,239, 65,214,220,127,145, 20, 69,169,216,110, 14, 83, 90, 90,170,178,165, -247, 78,159, 62, 29, 27, 54,108,192,134, 13, 27,200,244,233,211,155,140,197,254,253,251,201,134, 13, 27, 26,143,123, 88,230, 3, -182,109,150, 80,119,246, 44,186,229,231, 67, 43, 18,193,137, 2,116, 52, 1, 93,175, 7,173,211,161,253,129,253, 40, 36, 4,109, -251,247,231, 77,224,174,174,174,170,227,199,143,203,103,204,152,145,199, 87, 6,128, 38, 22,185,185, 54, 62,222, 5,123,201,223, - 18,209,231,152,120, 2, 4,180, 62,204, 42, 0,150,130,223,248, 16,142, 45, 66,228, 42,239, 65,175,209,242,137, 24,183, 22, 84, -200, 71,158,185,239,240, 12, 92,148,248,249, 7,245,246,247,115, 3, 33,192,129,195,215, 81,171, 54,236,186, 26,209,207, 15,237, -219,185,224,250,141, 42,186,240,114,153, 72, 34, 17,161,123,160, 23,252,253,131, 61, 97,216,162,213, 44,138,174,104, 48, 98, 0, - 80, 87, 15,236,218, 7,168, 14, 19,248,119,160, 16, 24, 0, 60,241, 56,208, 43,136,130, 68,108,216, 90,124,104, 56,240, 47,165, -134, 85,127, 27,187,228,217,188,102,163,241, 26,175,245, 27,247,187, 35, 51, 12,248,160, 97, 59, 87,244,237,219, 87,110,250,153, - 88, 44, 86,245,238, 93,138,133, 11, 13,234,233,135, 31, 94,196,149, 43,161, 22,101,105, 52, 26,155,150,191, 49,174, 92,185, 98, -243,152, 81,163, 70, 81,163, 70,141,106, 36,251, 13, 27, 54, 16, 83, 5, 97,212,168, 81,173,210,119, 45, 97,253, 3, 64,247, 59, -119, 85,218,250,122,136, 68, 34, 16,177, 24, 52, 77,163,158,166, 65,235,245,208,235,105,116,190,121, 83, 85,217,191, 63,239,107, -174,173,173, 5, 0,213,177, 99,199, 64, 81, 20,231,248,142,150, 80, 2, 28,101,249,231, 36,229, 32, 58, 35, 26, 83, 54, 1, 73, - 57,134,215, 57, 73, 57,141,202,129,116, 91,161,192,188, 15, 16,198, 49, 1,172, 98, 0, 44,101, 1,240,205, 14,176,100,113,241, -177,196,172, 41, 13,124, 21, 20,107,215,109,250, 93,182, 86,132,165,160, 66, 62,242,172,125,135,249, 29, 10, 0,189,209,102,236, - 2,109,136,246,119, 6, 0, 92, 47,169,132, 90,173, 3, 0, 4, 7,122,161,125, 59, 23,156, 46, 40, 21, 93,184,116, 15, 50,153, - 24, 65,221, 60, 81, 86,161, 5, 0,139,130,175,223, 36, 8,122,204,240,251, 79,142, 2,194,123, 83,112,150, 2, 58,157,193, 19, -224,233, 14, 20, 95, 3,162, 71, 1,143,117, 54, 28,223,154, 48, 38,125, 62,235,194, 15, 59, 74, 75, 75, 91,204,139,210, 64,242, -141, 22,127,107,147,191, 49,210,211,211, 73, 74, 74, 10,197,247,115, 83, 56, 21, 21,162,174, 94, 11, 74, 44,129,158, 16, 80, 0, -116,122, 26,245, 58, 26, 68,175, 7,117,233, 2,128, 88,187,207,251,236,217,179,240,241,241, 81, 85, 84, 84,200, 61, 60, 60,120, - 43, 1,182,218, 30, 20,249,167,166,166, 82,105,105,105,100,202,166,166, 10, 1, 0, 68,103, 68, 67,186,173, 16,219,182, 21, 53, -102, 2, 48, 1,131,222,222,222, 2, 83, 63, 96,242,183,168, 0, 60,236,176, 70,136,124, 8,214,158, 20, 71,171,114, 91, 56,155, -128,154, 90,198,245, 55, 40, 15, 15, 39,148,149,107,224,227,237,138,196,132, 94,208,233,105, 56, 59,139, 33, 22,137, 64, 8, 65, -220,184, 32,140, 31, 27, 4,138, 2,238,150,169,225,225,225, 4, 0,247, 44, 9,236,210,145, 66,209, 85,130, 94, 65,192,152, 97, -134, 89,231,183, 66,160,111, 47,192,171, 45, 16, 19, 9,208, 52, 32, 17, 3, 23, 47, 27,142,103, 59,182, 92, 94,243, 45,132, 97, - 75, 33,109,105,208, 52, 29,217,169, 83, 39, 20, 21, 21, 97,255,254,253,170,145, 35, 71,202,221,220,220, 32, 18,137,242, 0, 64, -175,215,203,207,157,243, 85, 45, 94,124, 3, 20, 69,161,180,180, 7,122,244,232,138,139, 23, 47, 90,146,103,182,125,227,198,141, -205,189, 72,132, 96,218,180,105,156,174,217, 88, 9,120,152,200,223, 17, 74,130, 49,238,117,238, 4,233,111, 23, 64,156, 0, 41, - 77, 12,129,173,122, 29,180, 68,143, 90,157, 14,234,224, 94, 14, 57,247,176,176, 48, 80, 20,197,139,252, 1, 96,240,224,193, 24, - 52,104, 16,117,244,232, 81, 98,173,205, 22, 26, 60, 6, 77, 8,223, 92, 27, 23, 36,229,220, 39,126, 0,205, 44,127, 38, 96,112, -219,182, 34,129,169, 91,129,252, 31, 89, 5,160,165, 21, 10, 71, 17, 2, 33,128,104, 90, 89,139, 41, 1, 76,230,130,104,106, 25, - 27,235, 31, 0, 36,183,110, 20,221,185,126,163,179,143,143,183, 43, 62,250,226, 24, 70, 13,239,130,136,190, 29, 64, 57, 81,141, - 25, 1, 13, 91,199,227,250,141, 42,220,186, 81,116, 25,128, 69,179, 50,168,171, 12, 63,231,171,209, 43, 8,240, 25, 0, 44,152, - 13,204,157, 1,120,184, 27,220,254,139, 63, 5, 22,205, 53, 28,251,115,190,225,120,190, 4,237, 40, 75,253, 97,170, 5,112,238, -220, 57,200,100,134, 62,217,177, 99, 7,174, 93,187,166,234,217,179,167,124,204,152, 49,168,170,170,138,244,246,246, 86, 29, 60, -168, 67, 94, 30, 48,104,208, 64, 4, 4, 4,200, 59,119,238, 12, 0, 42,115,242,218,180,105, 3,173, 86,203,234,183,117, 58,221, - 35,255,236, 26,147, 63, 27, 69,128,173, 18, 80,212,222, 87,238,124,230,140,138, 38, 4,109, 68, 18,136,197, 20,116, 68,143,218, -250,122, 84,105,181, 40,241,247,151,251,216,113,222,174,174,174,160, 40, 74, 62,104,208,160, 60,190, 50, 24,162,183,213,246,160, -149,128,212,212, 84, 42,169,193,178, 55, 37,127, 99,235, 95, 64,235,146,191,160, 0, 60, 8, 11,175,133, 83, 10, 27,149, 0,118, -138,134, 46, 52,180, 95, 73,225,229, 50,159,126,161,190, 88, 48,119, 40,214,253,239, 87,184,200, 36, 8, 15,243, 5,164, 78, 4, -153, 0, 0, 32, 0, 73, 68, 65, 84, 69, 81, 70,150, 36, 65,225,229, 50,132,134,246, 59, 11,160,202,146,192,192,160, 30,216,177, -247, 52,102, 76, 1, 72, 49, 48,116, 50, 16,216, 5,216,144,109,116,208, 92, 64,175, 7,118,236, 53, 28,223, 90,176,230, 41,106, -173, 52,192,123,247,238,169, 66, 66, 46, 99,237, 90, 0,208,227,189,247,206,224,228,201, 90, 85,109,109, 45,170,170,170, 80, 92, - 92,140,219,183,111, 35, 34, 34, 2,211,166, 77,179,153, 6, 72, 8,145,211, 52,173, 18,137,108, 39,248, 48,138, 7, 87, 48, 75, - 0, 27, 54,108,192,168, 81,163, 90,245,249, 74, 73, 73,161, 24,226,183,181, 4, 96,235, 24, 99,120,245,239,143,187, 90, 45,244, -170, 60,104,165, 78,112, 35, 18,104,104, 26, 21, 90, 45,170,198, 60, 1,159, 1, 3,120,122, 5, 41, 12, 26, 52,136,247,186,191, -177, 12, 99,162, 55,215,102,143, 18,112,236,216, 49,171,109,108, 96,142,252, 25,203, 31,128, 16, 16,216,202,228, 47, 40, 0,143, - 56, 26,215,255,217, 47, 3,232, 67,251,142, 28,179,125,235, 87, 7,127,201,119,239, 53,100,128, 63, 98,162, 2,177,251,167, 98, -236,248,209,240,112,190,149, 60, 28, 52, 77,240, 75,126, 9,138,138, 10,175,198, 37,188,240, 15, 0,245,150, 4, 70, 12,251, 59, -181, 99,211, 27,228,227,175, 12,169,128,171, 63, 48,164,254, 69,141, 48,164, 2,126,252,182,129,252, 63,254, 10,208,163, 45,239, -138,128,246, 90,230,182, 60, 8,173,149, 5, 80, 83, 83,131,254,253, 53, 24, 52,200,240,126,224, 64,130,221,187,139,113,241,226, - 69,166, 16, 16, 34, 35, 35,209,189,123,119, 86, 53, 0,198,141, 27,151,151,149,149,101,211, 11,160,211,233,224,233,233, 41,231, -122,190, 13,233,128,141,153, 1,251,247,239, 39,124,151, 1, 6, 15, 30,204,170,141,139, 18, 96,235, 56,214, 66, 69,162, 60,237, -144, 33,242,243, 78, 78,232,114,243,166,202,237,218, 53,104,186,117,195, 21, 95, 95,185,119, 68, 4,208,176, 68,195,131, 96, 29, - 65,210,205,100,152,107, 99,219,151,166,199, 49,132,111,171,141, 15, 76, 73,159,241, 8,216,187,132, 39,160, 57,216, 4, 70, 11, - 10, 64, 11, 90,230, 15,233,111,220,141,126,114,218,202,156,221,223,191,241,251,205,170,160,224,110, 94, 24, 63, 46, 8, 94,158, - 50,148,149,107,112,242,215,219, 40,188, 92,134,162,162,194, 67,209, 79, 78,219, 12,224,186, 45,129,221,122,196,201, 15,228,111, - 87, 29,202,175,196,248, 49,192,154, 37,134, 74,128, 69, 87,129, 47, 55, 26, 44,127, 61,218,162, 91,143, 56, 57,223,107,181,103, - 9,128, 45,249,183, 70, 12,192,205,155, 55,229, 94, 94, 62,170,227,199,255, 0, 0, 92,188,216, 22,131, 6,245, 70,187,118,237, - 32,147,201,112,243,230, 77,121, 92, 92, 28,167, 82,192, 93,187,118,149, 95,184,112, 65,101,236,209, 49, 37,255,224,224, 96, 12, - 30, 60,152, 19,137, 49, 89, 0, 70,107,255, 76, 64, 32, 47, 37,192, 28, 17,242, 37, 71, 91,228,206,137,252,141,148,128,118, 3, - 7,162, 22,160,106, 27,154,236, 13, 85,179,151,252,185,244, 27,219,223,114,180, 60,182,228,175,141, 15, 6,132,245,255, 7,226, - 9,176,164, 24,112, 74, 3,228, 27, 44,199, 53, 13,144,175, 60,190, 50, 29,125,126,214,250,201, 81,231,103, 79,224,162,147,180, -141, 50, 46,225,133,239, 10,206, 28,248,124, 75,246,190, 64,191, 78, 65, 67,141,246, 2, 56, 18, 26,218,239,104, 92,194, 11, 11, - 1,212,176,145,215,187,207,232,188,222,125, 70, 83, 39, 14,127, 78,190,223,113, 17, 31,126,246,240,237, 5,240, 48,146, 63, 0, - 60,253,244,211, 56,125,250, 52,102,206, 60,222,224, 1, 24,136,169, 83,251,201, 93, 93, 93,243,248,202, 12, 15, 15,207, 11, 15, - 15,167,182,110,221, 26, 89, 85, 85,165, 18,139,197, 16,137, 68,208,233,116,144, 74,165,112,115,115,147, 59,128,252, 29,162, 4, - 8,248,115, 34, 53, 53,149, 74, 75, 74, 35,254,115,252,229,232,106,254,152,146,164, 28,149, 16, 15,208,186,144,176,157, 40, 29, - 61,241,182,132, 60, 62,191,245, 40, 95,175,157,168, 8,237, 59,242,217,208,190, 35,153,138, 49,110, 0,124, 0,220, 4,160, 70, - 67,217, 87, 46,136, 24,246,119,138, 79,145,159,150,238,135,135,169,174,132, 41, 92, 93, 93,243,134, 13, 27, 70, 13, 27,230,248, -142, 75, 72, 72,200,131,131,138, 91, 50,235,254,166, 36, 63,106,212, 40,106,195,134, 13,228, 97,136, 7, 16,240,240, 41, 1,214, - 15,128, 64,254, 45, 0,182, 85, 0, 1,128, 10, 15, 15, 23,214, 94, 4, 8, 16, 32, 64,128,128,191, 24,132,189, 0, 4, 8, 16, - 32, 64,128, 0, 65, 1, 16, 32, 64,128, 0, 1, 2, 4, 8, 10,128, 0, 1, 2, 4, 8, 16, 32, 64, 80, 0, 4, 8, 16, 32, 64, -128, 0, 1,127, 14, 52,201, 2,152, 61,123, 54,239,168, 76,115,133, 28, 4,121, 45, 35,143,205, 38, 54,173, 41, 47, 55, 55, 55, - 18,128, 42, 51, 51,211, 33,242,246,238,221, 27, 73,211,180,195,228, 9,247, 95,171,201,155, 6, 96, 99, 11,159,159, 19, 0, 25, - 12, 69,107, 52, 48,100,179, 16,152, 20,177, 17,198, 67,144,247,103,151,199, 89, 1,176, 69, 14,150,192, 37,149,202,209,242, 30, - 36,146, 18, 43, 8,164, 82,100,108,112, 97,117,126,185,185,185,145,153,153,153, 42, 71, 93,175,177,188, 21, 43, 86,200,147,147, -147, 85,124,182, 23, 54, 39,239,236,103,109, 17,246, 74, 37,236,145,199, 96,226,160,157,170,211, 23,244, 0,128,140,140, 12,146, -148,148,100,215,120,246,232,240, 61,212, 58,111,184,184,184, 32, 51, 51,147, 36, 38, 38, 62, 44,247, 71,251, 89,175, 39,127,179, -250,163, 21,207, 1,248,195, 1,242, 2,102,191,250,218,154, 47, 62,253,248, 89, 11,242,156, 0,232, 96,189, 34,155, 19, 12,149, - 27,219,207,157,251,218, 55,159,124,242,241,115, 48,108,230, 68,195, 1,149,220, 76,159, 99,142,247,198,225,150, 26, 8,138,162, - 98, 69, 34, 81,111,145, 72, 20, 73, 81, 84, 15, 0,174, 90,173, 54, 71, 44, 22,123,210, 52, 93, 74, 8,121, 27,192, 93, 71,246, -129, 0, 1,230,240, 92, 81, 17,249, 38, 40,200, 97,115, 84,146, 66, 65, 50, 90,136, 19, 37,182, 30,114, 66,136,181,135,142,243, -132,225, 40,121, 92, 45, 88, 71, 98,207,158, 61, 54, 39, 17,134, 92, 83, 82, 82,224,235,235,107,182, 2, 94,114,114,178,138,237, -111, 50,242, 24,226, 63,114,228, 72,163, 34, 96,143, 60,250,220, 59, 16,245,126, 15, 95,239, 53,148,142,165,207,189,211,120,140, -168,247,123,156,250,165,109,229,235,132, 38,192,119,187, 13,178, 98, 70, 59, 33, 52,184, 0, 25, 25, 25, 4, 0,184, 42, 2, 21, -186,239, 34,203,175,220,133,154, 26,173,170,169,107,131,152,232,114,116,242,163,112,252,248, 33, 82, 89,169,193,152, 49, 99, 90, - 85, 17,152, 61,119,238,171,160,233,113,179,231,206,125,245,139, 79, 62,121,219,110,121,115,230,190, 76,104,122,236,236, 57,115, - 95,253, 98,149, 89,121,245, 44,196,212, 3,160,230,204,153,251, 42, 77,235,199,205,153, 51,247,213, 85,230,101,137,192,163,214, -131,157,208, 26,223,127, 63,252,240,131,106,242,228,201,242,113,227,198,229,217, 35, 84, 44, 22,199, 72, 36,146, 81, 18,137,228, -105,177, 88,236, 37, 18,137,220,210,211,211, 69,111,188,241,198, 11,122,189, 30, 58, 3,158,214,235,245,241, 0,126,110, 80, 2, -180, 13,243, 95,139, 47,131,238,216,177,131,176,157,239, 98, 99, 99, 57,221,211, 59,119,238, 36,246,124, 95,128,227,225,178,108, - 25,160, 84, 58, 76,158,122,254,124,187,190,207, 84, 4,228,180, 29, 48, 27,242, 31, 48, 96, 0,242,243,243, 57, 89,252,214, 72, -158,141, 60,115,242, 83, 82, 82, 80, 92, 92,140,204,204, 76,135,110,235,154, 20,159, 65,224,210, 3, 25, 27, 35, 41, 0,200,200, -244,160,184,144,255,138, 21, 43,228,165,165,165, 42, 75,228,159,146,146,130,244,244,116, 78,228, 15, 0,137,137,137, 24, 58,116, -168,124,232,208,161,118,201, 99,200,158,249,191,244,125, 52, 33,255,249, 83,100, 88,182, 73,195,170,175, 60,212,201, 36,172,135, - 24, 53,106,130,215,159,147,225, 72,129, 14,234, 26,130, 90, 45, 32, 15, 47, 64,193, 69, 61, 39,111, 64,241,245,143, 73,249,173, - 54,112,111, 43,133, 95, 71, 55,180,239, 16,140,171, 69, 90,116,237, 93, 15, 39, 89, 41,114,183,220,193,150, 45, 91,200,164, 73, -147, 90,101,194, 83, 40, 20,206, 62,157, 58,205,253,246,200, 81, 42,166,103,247, 87, 21, 10,197, 7, 74,165,178,206, 30,121,237, -253, 58,205,253,110,239, 17,106,108,120, 79,187,228, 41, 20, 10,169,159, 95,199,185, 63,170, 14, 80, 3,251,133, 90,146, 69,183, - 66,183, 53,110, 63,152,153,153,169,138,143,143,199,166, 77,155, 84,227,198,141,107, 54,134, 17, 17, 17,100,241,226,197,136,143, -143,183, 58,190, 18,137,100,140, 84, 42, 13,147, 74,165,115,164, 82,169,235,245,235,215,209,189,123,119,136,197, 98,184,187,187, -163,176,176, 16,110,110,110,146, 99,199,142,121, 30, 62,124,248,192, 43,175,188,210, 21,192, 85, 0, 82, 75,125,144,148,148,212, -204, 88, 49,158,183,152,118,138,162,144,145,145, 97,243,254,219,186,117,171, 69, 25,198,237,132, 16,196,198,198,114,234,208,236, -236,108,187,190,223,146, 56,117,234, 84,100,120,120,120,158, 35,100,221,190,125,155,208, 52, 13,136,202,161,173,211, 64,234, 44, - 3,104, 79,136, 68, 34,116,232,208,129,234,107,234,185,180, 82, 12,231,241,199, 31, 39,155, 54,109,130, 37,121, 83,166, 76,193, -193,131, 7, 41,190,231, 7, 0, 55,111,159, 39,198,231,103,207,181,243,241, 38, 88, 42, 3,204, 74, 1, 96, 75,254,108,145,146, -146, 98,243, 24, 54,196,101,137,252,151, 46, 93,138, 5, 11, 22, 52,105,231,171, 4, 36, 13,200, 32,104,215, 3, 25, 63, 70, 82, -198, 22,255,216,177, 99, 41, 0, 96,254, 23, 22, 22, 18, 54,100,109,141,252, 27, 60, 3, 54,173,118,198, 77,111,108,225,155, 46, - 45,240,145,103,205,194,159, 63,133,253, 78,113, 62,234,215, 73,247,199,196,112,113,166,240,152,191, 24,119,202,104,212,235,196, -184, 91, 78, 80, 81, 77, 80,248, 59, 13,136, 0, 31,215, 51,200,205,205,141,140,138,138,178, 58, 41, 92,189,246, 81,100, 72,112, - 16, 14,223,186,141,110, 1,237, 17,214, 55, 16, 98,103,111, 60,214,173, 12,101,106, 13, 74,111,233,241,251,109, 13, 92, 37,197, -200,205,117,183, 41,175,133, 48,253,185, 55,222,144, 22,119,244,135,243,128,129, 34,205,129,253,211, 1,124,197, 67, 14, 99,137, - 79,127,254,213,121,210,223,165,126,112,235, 17, 33,170, 60,123,144,175, 60, 0,152,254,202,220,215,164,112,118, 71,183,158,161, -162, 11,191,158,176, 71,150, 35, 65, 51,207, 8, 69, 81,144,201,100,114, 0, 42,211,123, 98,192,128, 1,172,200, 31, 0,156,156, -156, 60,101, 50,217,140, 59,119,238,184,246,232,209, 3,253,251,247,135, 68, 34,193,167,159,126, 10,189, 94,143, 62,125,250, 96, -243,230,205, 56,118,236, 24,206,156, 57, 3,177, 88,252,185, 94,175,159, 96, 77,230,132, 9, 19, 26,231, 57, 91,243, 32, 27,194, - 85, 42,149,114, 63, 63, 63, 21, 33,196,170, 1,116,235,214, 45,206,123,101, 48,178,249,126,159, 33,234,243,231,207, 91,157, 55, - 66, 66, 66,228, 92,201,252,252,249,243,170,138,138, 10,120,120,120,200,237, 81, 4, 78,156, 60, 68, 22,191, 63, 27,109,218,184, - 52,251,172,166, 70,141,236,205,167,113, 70,169,164,198,119,236, 72,174, 39, 36, 88,158,219, 15,172, 48, 12,230,129, 21,232, 56, - 38, 14,178,136,129,208,247, 8,109,234, 62,251,110, 61,188,150, 76, 66,111,163,165, 34,245,147, 47,225, 11, 27,231,183, 48,117, - 22,188,219,185, 26, 26,222, 89,137,228,121, 51, 1, 0,247,238,214,226,195,180,213, 36,162,255,112,222, 74,128,163,151, 20,172, - 42, 0,140,197,110,203, 82,127, 88, 80, 92, 92,140, 5, 11, 22,240, 82, 32,172,193, 96,233, 39, 81,123,246,236, 33,153, 25,131, - 1,169,154,176, 89,251, 55, 71,214,166,164,108,109, 89,192, 18,140, 21,138, 35, 71,142,168,134, 14, 29,218,196,245,207, 85,222, -127,223,112,179, 56,185, 77, 95, 94,195, 90, 14, 77,211,145,206,174, 20, 68, 34,192,213, 5, 40,175,164, 81, 71, 8,218,184, 80, -208,208,128,186,142,160,115,123, 17,104, 29,112,233,186, 30,197,197,197, 42, 88, 41, 79,123,174,224,135,200,176,176, 94, 42,169, -148,224,229, 25, 67,160,215, 19,220, 42,213,226,218,141,114,192,233, 58, 92,188,234,112,179,244, 10, 68,210, 10,156, 59, 87, 14, - 15, 47,235,242, 90, 10,206,222,222,239, 60,253,183,191, 57,191, 69, 3, 94, 11, 82,221,110,159, 62,245, 54, 79,146, 37, 0, 32, -243,240,126,231,255,158,253,155,243,242,203,122,116,158,150,226,118,161,248,140, 57,121, 54,119,100, 83, 40, 20,104,235,225,249, -206,244,103,159,115, 62,115,173, 12, 9,207, 36,185,253,251,253,100,190,231,102,209,147,103,169,221,134,226,173,103,158,145,184, -184, 56, 68, 69, 69,229,101,102,102, 66,173, 86, 55,142, 33, 99,249,199,197,197,177, 26, 83,103,103,231,225, 53, 53, 53,189, 66, - 66, 66, 32,151,203,145,156,156,140, 23, 95,124,209, 48,153,215,215, 99,221,186,117,200,207,207,199,137, 19, 39,240,253,247,223, - 67,173, 86, 7,211, 52, 29, 99, 77,230,248,241,227, 29,122, 63,237,216,177,131,213,210, 28, 69, 81, 42,174, 46,124, 99,217,124, -190,223,224, 26,206,171,168,168, 64, 73, 73,137,217,207,253,253,253,193,151,192, 75, 74, 74, 80, 82, 82, 98,151, 34,112,230,244, - 69,124,179,126, 59, 70,142, 28,142,208, 62,157, 26,219, 11,126,189,129, 3, 7, 14, 97,243,166,159, 72,230,155,111,226,122, 66, - 2, 92, 70,140,128,250,231,159,205,202,201, 24,153, 76, 1,192,165,245,171, 72,223,210,221,120,110,239,118,232,123,132, 66, 61, -111, 17, 0,192,101,249, 34,184, 93, 44,192, 27,197, 82,116,127,126,206,253,126,172,185,255,156, 90, 59,191,168,177, 35,154,157, - 95,238,158,159,113,230,244, 69, 68,244, 31,206,251,254,225,179,164, 96,236,238,183,230, 13,144,112,181,216, 29, 77,180,246, 34, - 51, 51,211,174,239, 39,101, 40, 8, 58, 2, 25,241,134,137, 43, 35, 63,169,137,155,223, 96,241, 87, 16, 83, 79, 0, 91,178, 46, - 45, 45,109, 66,206,124,200,154, 45, 24,165, 67,161, 80, 16, 91,245,160,173, 89, 54, 12, 24,247,191, 37,121,132, 16,114,231,220, -235,232,216,224,250,111,212,152,245, 4, 26, 45, 80,223,208, 86,175, 35, 32, 34,195,235, 95,207,228, 51, 89, 2,102,225,238, 94, -161,170, 81,139,224,227,237,137,242,123,181, 40,175, 40,199,145,227,183,112,227, 54,129,180, 77, 45, 58, 5, 87, 67, 93,123, 7, -221,251,214,163,107, 72, 29,190, 95,147,143,221,187,119, 71, 62,192, 91, 78,164, 80, 40,162,166,188,156,212,161,196,195, 11, 69, - 58,192, 37,106, 28, 68, 94,237,124, 20, 10,197, 56,165, 82,249,163, 17, 89, 59,193,104,221,219,210,188,175, 80, 40,198, 38,206, -120,185,195, 31, 34, 15, 92,173,174,135,103, 68, 20, 36,238, 94,166,242, 0,118, 1,108,209, 19, 39, 77,238, 64,196,206,168,168, -169, 67,216,128, 97,112,107,235, 97, 78, 86,171,128,177,254, 41,138,194,182,109,219, 72, 92, 92, 28,182,111,223, 14, 23, 23,151, -200,148,148, 20, 21, 23,242, 7,224, 92, 94, 94,254,124,125,125,189,200,213,213, 21,163, 70,141,194,242,229,203,225,228,228, 4, -133, 66,129,245,235,215, 35, 63, 63, 31, 71,142, 28,193, 79, 63,253,132, 95,127,253, 21, 62, 62, 62, 62, 58,157,238, 49,216, 88, - 2, 73, 74, 74, 34,182,150, 0,214,172, 89,195,234, 60, 91,114, 9, 96,235,214,173, 14, 89, 2,240,240,240,144,151,148,148,168, - 44,125,102,239,184,243, 81, 4,228, 69, 69,228,238,178,101,248, 8, 0, 14, 31,198,189, 41,177, 88,209,175, 71,163,203, 62,180, -119,111, 76,157, 54, 30, 93,203,238,224,122, 66, 2,218,205,159, 15, 85, 80, 16,213,247,231,159,173, 62, 39, 82,249,227,232, 17, - 19,137, 55,230,127,128,127,161, 0, 43,134,142, 65,216,160, 33, 8,190, 87,140,117,158,253, 81,236,113, 27,125,100, 50,162,209, -104, 88,141,175,124, 76, 63, 60,247,124, 28,142,254,242, 43,118,231,252,136,119, 1,172, 88,190, 22,161,189,123,227,185,231,227, - 80,171,190, 11, 25, 7,121,166,176, 55, 6,128,147, 7,224, 81,130, 82,169,164, 28, 17,181,206,144,123,230,130,203,128, 88,138, -164,113, 93, 1,207,174,200,104, 72, 88, 98,187,246,239,104, 24, 95, 27, 19,244,103,108,249,155,130,137, 13,176, 20, 12,200,103, - 39,194, 13,243,218, 88,244, 8,184, 87, 38,227,138,150,224,214, 29, 26,128, 8,110,174, 6, 23,103,189,142, 64, 83, 7,104,180, -128,166, 14,208,214, 3, 26, 53,160,173,187,239, 37, 49,167, 80,184,233, 94, 39, 55,174, 5,160, 75, 55, 55, 16, 39, 9,238,168, -213, 80,237,187,142,115,133, 55,112,239, 94, 53, 66, 7,232, 81,163,209, 65, 83,167,135,186,150,198,173,107,128,186, 6,216,178, -101,139,138,203, 6, 24,118,142, 9, 45,246,244,124,103,230,155,111,202,190, 55,162, 16,175, 55, 83,221,238, 45,152,247, 54,128, - 31,141,200, 90,203, 66, 36,145,184,121,190,243,226,107, 11,100,187,110,232, 27, 27, 59, 63,189,192,237,234,151,111, 26,203, 99, -229, 5,112,117,115,127,251,213,215,231,201,138, 74,238,239, 22, 25,255, 76,146,219,119, 25, 43,204,201,226,244,172,153,187,151, - 56, 62,107,132,177,254,101, 50,153, 60, 42, 42, 42,143, 73, 25, 85,171,213,170,252,252,124, 42, 46, 46,142,173, 44, 29,128, 96, - 0,116,120,120, 56, 45,147,201, 68,235,215,175,199, 11, 47,188,128, 37, 75,150,128, 16,130, 95,126,249, 5,251,246,237,195,153, - 51,103, 80, 81, 81,129,238,221,187,163,178,178,210, 85, 36, 18,249,218, 18, 62,113,226, 68,139, 74, 50,179, 52, 48,126,252,120, - 78,110,250,135,117, 9,192,154, 23,192, 30,235,223, 94, 69,160,172,188,188,241,181,111,234, 44,132,165,206,198, 72,147, 99, 46, - 63,249, 34, 58,239, 63,142,162,121, 47,227, 23,127,127,184, 0, 56,163, 84, 82, 48,147, 22,167, 86,171, 73,231,206,109,113,245, - 26, 16, 26, 17, 2, 44,123, 11,175,125,185, 5, 51,130, 78,163, 95, 93, 33,222,184, 45,197,251, 27, 22, 98, 73,218, 23, 56,243, -235, 65,116,233, 28, 74, 92, 92, 44,123,125,141,229,121,183,115,197,147,177, 67,240,100,236, 16, 44,166, 87, 66, 91,183, 0, 39, - 79, 2, 39, 79, 2, 7, 14,196,225,223,171, 46, 34, 54, 54,134, 4, 4, 60,134,160,160,111, 56,241, 83,238,227,111,161,232,160, -196,198,220,253,197, 95, 67, 1, 80, 40, 20, 36, 49, 49, 81,206,172, 25,154, 42, 1,198, 19, 18,179, 30,207, 55, 30,128, 33,253, -177, 99,199, 82,134,101, 0, 41, 50, 54, 60,216,235,101,162,254,163,162,162,168,220,220, 92, 98,203, 27, 98, 43,237,208, 26,161, -115, 93, 14,120,254,205, 26,248,119, 16,225,153,120, 41, 52,117,128,135, 59, 5, 17,213, 96,245,131, 64, 83, 11,212,104, 9,106, -212, 4, 53, 26, 2,154, 0, 34, 43, 49,215,207,207,173, 65,159,126,197,240,235,117, 15,123,118,149,226,222, 61, 13,194,135, 85, -162,175,119, 53,224, 84, 7, 77, 45,141,210, 27, 4, 53, 53, 20,116, 58, 10,222, 62, 20, 64, 61,240, 88,182,208,254,253,250, 13, -244, 10, 8,192, 33,189,145,242,242,204,179,184,151,146, 60, 64,161, 80,244, 86, 42,149,231, 56,220,207, 33,131, 70,140, 30,216, -206, 63, 0,199,143, 54,198,200,161,189,252,255,112,117,205, 2,115,242,172,109,133,221,123,196,136,145, 3,253,253, 59,227,220, -137,203,141,237, 35,158, 24,143,255, 41,151,115, 62,183, 22, 64,227,185, 51,207, 47,179, 12,192, 96,251,246,237,205,226,143,204, -196, 2, 48,131, 30, 12,224,212,252,249,243,135, 75, 36, 18,183,175,191,254, 26,107,215,174,197,204,153, 51,177,116,233, 82, 80, - 20,133, 43, 87,174, 64,173, 86, 35, 37, 37, 5, 58,157, 14,179,102,205,162, 41,138,178,249, 0, 56, 50,154,254, 97, 95, 2,176, -230, 5,112,132,245,207, 23,235,215,175,199,223,146,166,162,162,188, 14, 72, 91,141,154, 3,199,209,102,228,192,198,207, 75,211, - 86,163,192,217, 25,212, 63, 94, 66,216,180, 39,113,120,221, 46,244,237, 59,200,162,188, 75,151,206, 98,216,136, 24,156, 45,240, -194,234,207, 51, 49,114,228,112,188,255,217, 66, 44,142,154,142,111, 1,244,122,238, 5,172,254, 60, 19, 82,169, 23, 38, 76, 28, -136,175, 57,200,251,228,163,141, 24, 20,215, 7, 31,244, 89,142,179,227,221,224, 21,191,185,201,177, 62,174, 50, 28,205, 83, 33, -224,111, 51, 56,247,195,193,131, 18, 44, 91,230, 98, 67,129,251, 11,121, 0, 76,215,145, 45, 17,124,195,113,172,145,145,111,136, - 80, 55, 16,255, 37,100,126,122, 25,134, 44,128,166, 74, 1,155,101, 0, 71,187,245,115,115,115,137,177,245,207,120, 4,140,223, - 39, 38, 38,130, 41,150, 99,169, 48, 4, 23,242,103,178, 0, 44,201,211,233,129,154, 90,130, 58,173, 33,216,175, 78, 75, 32,113, -190,255,153,166, 22, 80,215, 19,220,189, 71,240, 71, 25,193,137,115, 58,208, 52,144,152,152, 40,191,116,233, 82,179,177,209,233, -128,146,235, 90, 92, 47, 42,195,193,195,101, 32,132,194,185,223,104,196, 61,163,131, 84, 66,240,199,109,224,224,143, 64,101, 37, - 1,161,129,199,199, 80,144,201,128,152,152, 9,184,122,245, 42,171,107,202, 90,167, 32, 19,103,240,207, 18, 17,185,181,125,243, -229,165,233, 78,217, 68,212,132,137,125,156,157,225,244,143,185, 78, 87, 86,173, 92, 8,224, 89,182,242,196, 46,110, 11,103,191, -189,212,233,199, 18,210, 68, 94,187, 54,206, 8,155,246,138,211,185,141,159,154,202,179,232, 1,144,185,180, 89,184,224,157, 69, - 78,151,111, 85, 52, 57,160,173,123, 27, 76,122,102,166, 83,246,127,191,226,116,110, 45,229,181, 51,215, 22, 17, 17, 65, 78,156, - 56,129,109,219,182, 53,251, 78,124,124,188,217,161, 0,112, 22,192,169, 21, 43, 86,244,243,244,244,116, 99,220,224, 95,125,245, - 21, 94,120,225, 5,172, 93,187,182,209,138, 95,177, 98, 5,202,203,203, 81, 89, 89, 89, 93, 91, 91, 91,220,224, 65,144, 90, 59, -215,151, 95,126,153,152,186,232, 25,235,159,173,251,255, 81, 89, 2, 48,231, 5,112,180,245,207,200,100,187, 4,112,110,216, 48, - 80, 47, 79,131, 39, 0, 50,102, 0,106, 79,156, 69, 77,218,234,251,253,150, 52, 21,221,159,155, 10,153,204,112,253, 5, 5,133, - 86, 9,187,160,160, 16, 0, 16, 19,107, 80, 34,242,143,159,193,183,223,124, 7,215, 33,131, 81, 91,175,131, 22, 90,140, 26,221, -191,201,241,108,229, 93,215,107,241, 76,135, 87, 64,159,168, 67,226,191,198, 64,250,212, 17,244, 14,237,141,208,176,224,198,243, - 75,121, 99, 21,130,130,196,172,239,155, 39,254,239,137,168,115, 56,183, 7,255,251,134,178, 21, 2,240,197, 23,104,153, 66, 64, - 15, 35,242,243,243,109, 70,147,231,230,230, 70,178, 78, 41,116,110,131,204,174,251, 1, 93, 62, 65,183, 54, 72, 74,235,134,140, -188, 56, 10,200, 32,247, 21,130,177,188,151, 1, 76, 83, 1, 45,165, 6, 90,154, 44, 21, 10, 69, 35,249,155, 6, 0, 50, 46,117, -166,205,154, 7,192, 88,158,163, 38,243,157, 59,119, 70,222,184,185, 75, 69,183,167, 33,146, 0, 78, 34,195,253, 93, 79, 19,232, -116, 64, 85, 21,129,182, 30,208,213, 27,148,130, 9, 19, 13,222,155, 75,151, 46, 89,148, 87,119,103,167, 42, 52,148,198,129,125, -122, 80, 34,224,143, 91, 20,100, 46,192,190,221,128, 86, 77,129, 34, 64,223, 8, 39,148, 92,163, 49,122,244,120,196,198,198, 82, -108, 42, 97,101,173, 83,144,101,175, 0,243, 63,227,175, 4, 16, 90, 31,173,111,231, 35,218, 69,223,103,161, 14, 0,252, 40, 64, - 61, 96,128,228,178, 78, 31,205, 73, 30,161,163,225,238, 45, 82,221,210, 55,202,107, 47, 3,124,100, 20, 92,251, 12,144, 20,124, - 71, 71, 91,178,162,205,201,106,227,238, 41,186,122,187,188,129, 88, 0,119, 23,103,184,187, 74, 17, 17,222, 95,178,229, 91, 18, -221,202,143,174,217, 62,103,162,254,227,226,226, 26,239, 81,198,123, 55,101,202, 20,107, 22,104, 53,128,203, 39, 79,158,172, 30, - 57,114,100,123, 24,229,244,127,245,213, 87,141, 36, 91, 95, 95, 15,189, 94,143, 75,151, 46,161,125,251,246,119,104,154,102,165, - 45, 78,156, 56,209,226, 18, 0, 23,162,125, 20,150, 0,204,121, 1, 28,105,253,115, 33,126, 6, 29,253, 61,177,102,205, 94, 36, -196, 15, 67,135, 1,161,192,128, 80, 80, 47, 79,107,170,244, 2,184,125, 75,141,173,219, 14,163,163,191, 39,123,121,126, 46, 24, - 48,176, 59, 6, 12,236,222,236, 56,174,242, 70, 77, 14, 65,234,232, 79, 65,159, 53,144,255,139,111, 60,207, 75,158, 41,222,116, -127,115,207,146,170, 37, 99,111,226,102,139, 61,144,118, 41, 0,249,249,249, 15,188,106, 31, 99,229, 50, 68, 23, 21, 21, 69,153, - 33,127,194,184, 21, 19, 19, 19,121,253,142,113, 22, 0,211,198,213,242, 55, 13, 0,108, 64, 99, 91,114,114,178, 42, 49, 49,145, -245, 67,102, 76,254,230, 98, 2,184,202,179,133,101,155, 52,176, 37, 47, 54, 54, 54,111, 97,202, 86, 60, 49,212, 9, 52,128,122, - 45, 13,103,169,161,155,170,106, 8,234,234, 9,116,122, 32,255,172, 30,122,154,192, 86,202, 94,108,108,108,222, 59,111,109,197, -232, 72, 49, 38, 77, 23,163,186,138,160,170, 2,168,169,162,208,173, 59,129,190,158,130, 68, 36, 67,249, 61, 26, 37,191,107, 49, -239, 53,118, 1, 99, 89,235, 20,100,229, 92,160, 71, 0,176,234,117, 96,206, 71,252,148, 0, 82, 91, 51,249, 31, 3,250,239,244, -203,222,233,230, 53,226,113,116, 0,208,129, 2,244,135, 14, 34,247,249,103,171,235,107,107, 38,113,145, 71,107,106, 39,189, 28, - 53,112, 87,200,226, 44, 55,223,190,195,225,227, 76,161,189,140,130,250,252,207,216,250,214,140,234,122,117, 45,107,121,117, 26, -245,164,216, 39, 70,238, 74, 78,251,220,173,119,191, 1,112,119,149,194,221,197, 25, 69,231, 78,225,157,148, 87,171,213, 28,100, -241,177,228,217, 92,174, 57,242, 95,180,104, 81, 51, 55,255, 15, 63,252,160,138,143,143,135,133, 34, 65, 12,209,107, 1,156,234, -217,179,103,145, 70,163,233, 36, 22,139,101,174,174,134, 84,172, 77,155, 54, 97,202,148, 41, 80,171,213,208,104, 52,168,171,171, -131,155,155,155, 70,175,215,103, 19, 66,110,177, 57, 89, 71,101, 3, 60, 42, 75, 0,198, 94, 0,230,117,107, 16, 63,131,110,221, -252,240,102,106, 18,118,239,250, 5, 89, 91, 78,192, 89,218, 22,191,151,220, 95,193,234,236,223, 27,117,218, 74, 68, 12,232,133, -143, 87, 38, 97, 73,218, 23,156,228,249,250,122,160,224, 92, 65,227,231,161,189, 67, 81, 90, 90,193, 73,222,248,185,147, 48, 69, -244, 44,234,206, 86, 99,232,156, 48,208,125,101, 88,179,230,251,198,243,171,168,168,192,240,199, 67, 88,201, 51, 69, 84, 70, 20, -245, 19,126,106, 81, 62,229,173, 0,180, 4,249,179,145, 25, 21, 21, 69,101,102,102,146, 6,107, 23,153,153,153,196, 56, 45,209, -212,234, 55,167, 32, 52,247,195, 82,128, 84, 4,184,136, 1, 55, 9, 80, 87,133,204, 37, 78,128,203, 81,146,244, 84, 55,192,197, - 27, 25,223,112,183,250,173, 69,251, 51,100,205, 54,135,221,148,252, 77, 99, 2,184,202, 99, 75,254,108,228,125,152,190,154,122, -125,238, 44, 34,147, 1, 52, 13,244,233, 41,190, 63, 30,191,234, 81,175, 39,208,211, 98, 76,158, 60,153,149,114,242,222, 7,171, -169,121,243,102, 17,157, 14,208,214, 19,232,117,128,136, 2, 34,199, 3, 85,229, 20,126, 59,173,134, 90, 35, 66, 66,252,100,214, -110,255, 69, 47, 2,193,157, 13,239,131, 58, 1,124, 61, 1, 74,165,242,136, 66,161,136,185, 53, 33,118, 87,192,214,157,110, 1, - 35, 30, 71,253,161,131,216, 28, 31, 91,173,173,170,138, 81, 42,149, 7, 57,202, 59,168, 80, 40, 98,206,191, 59,113,151,255,191, -178,221, 58, 13, 26,129,154,243,135,176,225, 31, 19,170,235,106,185,201, 99,100,173, 72,253,251,174,247, 63,249,210,109,232,176, -225, 40, 44, 56,133, 87,147,158,173,174,173,174,230,124,110, 45, 13, 75,197,126, 20, 10, 5,137,139,139, 99,147, 13, 32,246,244, -244, 60,165, 86,171,191, 45, 46, 46,238,218,175, 95,191, 64,157, 78, 39,113,114,114, 66,118,118, 54,198,142, 29, 11,141, 70,131, -218,218, 90, 92,186,116,169,210,203,203,107,175, 90,173,254,154,166,233, 26,176,172, 0,200, 20, 5, 98, 92,236, 92, 92,255,143, -218, 18,128,177, 23,192, 17,227,203,167,118,128, 57, 60, 25, 51, 4, 79,198, 12,105,120,103,191, 14,219, 84,222, 68,251,148, 59, -207, 31, 80,119,186, 26,207,127, 62, 30,239,239, 93,104,247,185,169,103,170,137,151,206, 11,154,111, 52, 15,196,176,230,165, 0, -180,134,229,111,106,125, 24,187,177, 45,185,250, 29,121,142, 92,214,254, 29, 77,254, 70,202,142,113, 33, 32, 70, 9, 82, 53,120, - 58, 56,201,179, 21, 11,192, 85,222, 71,159,172,166, 20, 10, 5, 17,137,128,131,249,134,181,126, 38,224,207,176,238, 63,153,147, -188,229,203, 87, 83,179,102, 55,212,164, 16, 25,100, 28,221, 15,212, 84,211, 32, 52,144,144, 48, 30,209,209,209, 54,199, 35,107, -157,130,164, 60, 11,120,186, 1, 37,119, 0, 23,103,128, 38, 64, 27, 25,144,166, 0, 82,149,188,148,128,131, 10,133, 34, 38, 63, - 33,118,151,199,162,247,220,242, 22,189, 83, 93,199,131,252, 77,229,229,205,159,176,203,229, 31,239,186,229,252,123, 49,103,242, - 55,150,245,202, 43,175,196,190,243,207,151,119,206, 73, 78,113,251,252,227,116,134,252, 79,155,121,246,117, 92,100,219, 90, 58, -226,250,188,153, 35,255, 89,179,102, 17, 38, 19, 96,219,182,109,132,162, 40,107,138,128,155, 86,171,173, 22,137, 68,185,254,254, -254,157,171,170,170, 94, 57,126,252,120,199,254,253,251,211, 58,157,174,182,162,162,226,246,233,211,167,175,116,235,214,173,168, - 93,187,118,197,106,181,122,147, 78,167,187, 77, 8, 97,173, 0, 48, 69,129,140,188, 2,124,198, 87,222,130,115,161,195,101, 59, -106,221,223, 94, 57, 26,181,216,161,199, 59, 90, 94,121,153, 8,233, 58, 5, 2, 15,251, 97,218,103,182, 21,147,242, 50, 17, 30, - 11,176,126,204,131, 36,127,139, 10,128,173, 92,127,174, 15, 58,219,218, 1, 92,228, 42,149, 74,202,210,102, 59, 92,200, 43, 35, - 73,105,112,243, 95, 4,112,209,244,211,138,134,191,203,224,113,189, 42, 71,145,171,113,191, 40, 20, 10,194,212, 25, 72, 78, 78, -230,149,225, 96, 42,111,195,188, 54,141, 74,129, 61, 74,147,233,152, 48, 1,127,124,189, 18,171,191,104, 42,175,186,210, 48, 1, - 39, 36, 36,112,187,255,190,117,232, 51, 83,111, 76,218,251, 22,189,187,190,174,170,234,121,123,173,107, 70,222,143,159, 47, 94, -175,169,173,154,161, 84, 42, 15,241,149,245,217,103,159, 29, 80, 40, 20, 49,159,175, 92,182,190,186,186,218,210,185,233,240,224, -209,100, 70, 53, 37,255,220,220,220, 72, 66, 8,182,111,223,110,124,140, 53,121,215,180, 90,173, 51, 33,164,138,166,105,165, 86, -171,253, 37, 32, 32,192,167,188,188,156,122,251,237,183, 43, 43, 42, 42,238,118,234,212,169,170,186,186,186, 70,171,213, 86,214, -215,215,215,233,245,122, 53,151, 19,118,208, 50, 64, 94, 11,246,105, 30,254,164,232,217,179, 47,245,238, 91, 25,100,234,211, 99, - 17, 26,214,205,226,113, 5,103, 47, 99,227,119,123,208,179,103, 95,234, 65,202,235,215,175, 31,149, 50, 79, 73,166, 62, 61,214, -186,193,124,188, 24, 27,191,219,131,126,253,250,217,188,151, 30, 36,249,155, 85, 0, 28,109,217,183,164,167, 32, 42, 42, 42,143, -149,139,223, 6, 28, 25,213,255, 32, 60, 35, 92, 54,253,113,132, 55,128,235,152, 24,167,117,217,187, 36, 97, 42,143, 43,249,219, - 19,241,207,134,180, 1, 4, 61,140,242, 28,125,110, 14,186,183, 41, 0,160, 40,138,136, 68, 34, 48,127,140, 11,123,252,248,241, -136,137,137, 1, 77,211,160,105, 26,132, 16, 91,191, 71,233,116, 58, 87, 66,136,158,166,233,186,250,250,250,253, 98,177,152, 18, -137, 68,206, 0,156,105,154,134, 94,175, 23,235,116, 58,169, 78,167,235,168,215,235,207, 27,125,183,197, 55, 1, 18,224, 24, 37, -224, 74,177,134,236,222,185, 5,215, 74, 43,225,231, 85,219,248,217,173, 50, 87, 4,248,182, 69,175, 94,189,108,146,117, 75,201, -235,215,175, 31,117,171,164,142,172, 90,185, 3,133,191,223,105, 38, 47,184,179, 15, 2, 3, 3, 89,145,127, 75,193, 90,141, 20, - 42, 60, 60, 92,216, 30, 83,128, 0, 1,143, 42,106,141, 8,157, 54, 50,108, 36, 70,237, 55, 1,120,192, 16, 52, 46, 16,191, 0, - 1,150, 60, 0, 2, 4, 8, 16,240, 8, 65,214,160, 4,208, 70,196, 47,194,253, 37, 14, 9,128,142, 13,175,105,161,187, 4, 8, - 16, 20, 0, 1, 2, 4,252, 57, 32, 2,224,102,244,158, 33,126,169, 17,233,211, 13,199, 9,214,191, 0, 1,130, 2, 32, 64,128, -128,191,200,156, 38,144,190, 0, 1, 86,180,103, 1, 2, 4, 8, 16, 32, 64,192, 95, 89, 91,158, 61,123,182,241, 70, 58,196, 56, -194, 94,161, 80, 16,147,141,118,174, 69, 69, 69, 53,102, 53,154, 43,197,106, 44,143, 43,254,140,242, 76,211, 22,141,251, 83,232, - 63, 97, 60, 30,118,121,105,105,105,141,199,164,166,166, 82, 60,228, 1, 22,202, 1, 11,247,179,109,153,194,243, 43,200,227, 34, -143,179, 2,192, 17,237,217, 28,196,236,222,231, 40,141,197,180, 24,137,185,221, 0,205, 29,211, 26,218, 21, 67, 48,137,137,137, -114,134,104,152, 10, 96,214,106,130, 63, 72,108,223,190, 61,114,219,182,109,141, 36, 56,126,252,120,121, 66, 66, 66,222,159, 81, -219, 53, 55, 30,231,207, 27, 50,195, 66, 66, 66, 90,245,220, 20, 10, 5,153, 48, 81,129,236, 44,165,217,123,118,231,174, 19, 36, - 59, 75,105,245, 94,222,185,235,132,213, 73, 32, 54, 38,130,247, 77,151,150,150, 70,226,227,131,154,188,183,165, 4,216, 66, 85, -117, 85,228,214, 31,183, 34, 48, 52, 80, 5, 10, 56,127,242,156,124, 88,248,112,132,244, 12,225,116,255, 29, 58,116,168,217,117, - 15, 31, 62,156,130, 0, 1, 2, 90, 76, 1,144,178, 61,112,232,208,161,156,133,155,219, 44,134,129, 57, 18, 53,221,104,131, 45, -209,242,217, 24,135,141, 66,193,200, 77, 73, 73, 65,122,122,186,202,210,222,226,204,113,214,114, 53, 77,207,177, 83,183, 46, 0, -128,219, 26, 13,116,234, 58, 67, 99,121, 37, 0,195,222, 7, 92,106, 35, 24,147, 63, 96,168, 45,206, 37,215, 94,161, 80, 16, 17, -101,168,174,199,252, 7,172,191,254, 98,245,131, 87,200, 76,199,131, 33,126,190,227,225, 72,165,146, 33,255,216,152, 8, 13,160, -144,101,103, 41,121,255, 6,163, 64,152, 87, 0,148,118,157,167, 86,155,130,156,156, 36, 68, 71,103, 32, 62, 62,189,209, 35,192, - 71, 17, 56, 88,112,144, 60,214,191, 11, 62, 86, 46,135,151,171, 23,104,157, 30, 26, 82,167,218,253,203,143,209,123,247,253, 68, -134, 7,142,144,203,100, 50,155,138,192,161, 67,135, 72,131,103,161,153, 69, 36, 40, 1, 2,254,202, 56,117,234, 84,147,247,230, -230, 52,123, 20, 0, 78,241, 3,230,118,177,115, 4, 8, 16,105,183, 12,194, 94, 7, 96, 99,185, 43, 20, 10,146,146,146,130,165, - 75,151, 2, 64,227,127,115,199,217,218, 33,172, 25, 60,219,226, 76,241,119,112, 65,103,232,241, 51, 74,255,115, 2,167,139,238, - 98,242,210,181,173,118,163,157,249,245, 44,250,246, 9, 3, 77,128,179,103, 13,175,129,251,175,141,219,105,150, 93,109, 92,131, -221, 26, 50, 50, 50, 40,182,227, 49, 99,198, 12, 0,104,252,111,150,252, 41, 10,176,114, 63, 40, 20, 10,242,196, 19,187,160, 80, -196, 56, 84, 9,136,141,137,168, 77, 74, 74,114, 5, 50,144,157,197,141,216,141, 45,124,123, 73,222,146,245, 15, 0, 83,166,108, - 66, 78,142,225,127, 82, 82, 17, 24,143, 0, 23,111, 0, 33, 36, 82,117, 97,175,234,149,127,204,198,192,246,253,225,226,225, 1, -162,213,129, 38,122,136, 37, 82, 4, 71, 5,231,252, 54,224, 2,150,102,164,171,134,248, 12,149,187,186,186,218, 84, 2,238,220, -185,211,228,253,248,145,109, 48,100,238,207,120, 58, 93,211,100, 32,199,140, 25,195,123,188,178,178,178,200,196,137, 19, 29, 54, -222,142,150,215,194, 68, 18,105,111, 89,223, 83,167, 78, 69, 54,144, 16, 95, 57,125, 95,127,253,245,155, 53, 53, 53, 1, 0,198, -193,176, 9,103, 8,128, 83, 48,108, 10, 5, 0, 27,148, 74,229,111, 2,245, 55, 39,127,166,205, 84, 9,104,162, 0, 20, 23, 23, -147,226,226, 98, 0, 64, 96, 96, 32,140, 55,155, 1,208,228,189,185,207, 45,161,180,180, 84,149,153,153,201,218, 19, 96,186,215, -189, 53, 18,166, 26, 74, 97,154,146, 40, 87, 23,123, 70, 70,134,205, 99,114,115,115, 89,145,127, 98, 98,162, 69,210, 95,176, 96, - 1,210,211,211, 97,172, 32,176, 65,241,156,149,240, 0, 0, 12,251, 73, 68, 65, 84,167,110, 93,112,163,172, 2,155,103, 77, 65, - 59,106, 4,138,214,204, 67,224,164, 64,236,105,101,242, 7,208, 72,248, 0, 16, 22, 22,214,164,157,241, 12, 24,183, 59,218,178, -183, 70,196,204,120, 88, 34,253,117,235,214, 33, 61, 61, 29, 49, 35,250, 99,215,207, 39, 1,247, 54, 64,101,245, 3,239,195,157, -187, 78,184, 2, 25,216,185,235,132, 67,228, 77,172, 92,104,245,217,204,106,251, 33,171, 7,196,216,245,159,148,148,131,248,248, -160,198,255, 12,226,227,131, 88, 43, 1,107,254,183, 6, 75, 62,251, 0, 35,187, 71, 66, 95, 87, 7,157, 94, 7, 74, 66, 1, 16, -131,128,198,237, 63, 74, 16,210,190, 23, 22,206, 90,136, 15,150,125,160,122, 34,204,182, 55,203,116,178, 27,239,191,206, 44,225, -239,221,187,151,240, 81, 2,178,178,178,200,206,183,119, 33,246,125, 56,132,180,179,178,178,200,178,101,203, 48,127,254,252,135, - 90, 9, 56,117,234, 84,100, 69, 69,133,170,164,164, 4,225,225,225,118,157,103, 69, 69,133,234,254,148,205,235, 57, 47, 6, 48, - 3,192, 73, 0, 95, 3, 24, 11,224, 73, 0,127, 55, 82, 0,238,252, 73,249,156,130,149,109,192,173, 26, 82, 41, 6,142,201, 72, - 95, 96,246,243, 38, 10, 64, 96, 96, 32, 21, 24, 24,216, 72,246,198,174,228,204,204,204, 38,239, 77, 63,191,116,233,146,197, 19, -100,148,138,228,228,100, 85, 74, 74, 10, 76, 55,202, 49,221, 60, 39, 51, 51,211,162, 11,214,220,100,111,218,214,154, 27, 21, 1, -192,198,141, 27, 45, 18, 63,128, 38,228,191, 96,193, 2, 86, 50,127, 47,190,134,154, 45,239,192,237,133, 79,208,169, 91, 23,116, -104,231,130,226, 45,197, 6,242,247,108,107, 88, 2,112, 18,115, 62,215,248,248,120,185,241, 50, 64,124,124, 60,103, 47, 13, 77, -128,128, 54,192,191,159, 5, 94, 90, 7,180,119, 5,206,151,155,111, 47, 40,227,120,231, 91, 80,228,184,120,109,222,123,239, 61, -139,196, 15, 0,203,102,196, 97,213,238, 35,240, 11,236,136, 91, 87,111,219,180,254, 1,128,141, 23,128,139, 27,223, 96,225, 43, -204, 90,250,204,218, 62,215,251,122,217,127, 45,247, 81,143, 89,224,113,175, 4, 53,249,175,141, 15,134,116, 91, 33,235,239,215, -170,107, 49, 98,218,112,213,208,142, 67, 80, 87, 83, 3,137,179, 51, 36,146,251, 83, 80,113, 97, 33,182,102,103,223,120, 97,230, -140, 78, 93,157, 3,208,127,116,120,212, 47, 57,191, 68, 14, 25, 56,132,147,213,152,182,115, 6,246,237,219,135,167,158,106,218, - 62,102,204, 24,138,171, 18,192,144, 63,186,126,140,157,111,191,102,183, 18,144,149,149, 69, 86,174, 92,137, 30, 61,122, 96,213, -170, 85,152, 51,103,206, 67,167, 4, 24, 19,191,163,228, 49,178,236,240, 38,200, 1,140, 6,176,142, 16, 82, 77, 81,148, 31,128, - 11, 0,174, 42,149, 74, 29,254,220, 32, 28,251,187, 9,249, 51,175, 51,210, 23, 52,243, 2, 60,144, 58, 0,153,153,153,204,218, - 43,138,139,139,225,235,235,219, 76, 65, 96,218, 74, 75, 75, 89,213,185,183, 21, 12,200,101,194,156, 58,117,106,203,169,110, 70, - 4,102,206,234, 79, 79, 79,135, 82,169,164,108, 69,113,170,113, 13,213,147,134,128,184,207, 3,162,222, 70, 53,254, 7,252,199, - 96, 45,146,204,121,112,250,219, 42,232,116,220, 11,157,197,197,197,229,177,216,118,213,186,135,231, 43, 96,241,106,160, 75,103, -224,246,118, 41,214,127,169,197,140,239, 44,183,115,186,243,137, 99, 43, 85, 27, 7,251,221,204, 90, 10,247, 80, 25,220,186,255, - 19, 27,151,190,132,126, 97,126,232, 25,247, 1,171,241, 96,115,127,178, 93, 42, 96,238, 93, 99,242, 87, 42,149, 20, 19,248,199, -139,104,218,126, 72,241, 33,121,115,208,198, 7,155,109,207, 49,241, 4,216,194,205,210,155, 24,151, 56, 14,238,109,189,160,167, -116, 56,176,111, 63,170,170,171, 17,159,144,128, 63, 74, 75,241,195,166,205,120,113,230,140, 78,206, 50,103,136,136, 19,162, 35, -162,115, 47,168, 86,241,178, 26,203,202,202,236,190,110, 99,242, 7, 96,183, 18,144,149,149, 69, 22, 45, 90,132,224, 96, 67,127, - 6, 5, 5,225, 97,242, 4, 56,154,248,205, 88,255,204,107, 62,215,218,187,129, 8,157, 40,138,114, 5, 16, 10,224, 28,128, 78, - 10,133,162, 18, 64,185, 82,169, 20,202,218,115,196, 3, 43, 4,228,235,235, 43, 79, 76, 76,108,182, 20,112,228,200, 17, 85,195, -102, 47,156, 99, 4, 44, 5, 3, 90,179, 28, 45, 41, 40, 45, 1,198,186,183,228,238,103,107,253, 3,192,238, 55, 23, 33,126,201, - 71,208, 69,141,128, 4,128,219,225, 66,236, 41,186, 11, 0,208, 69,205, 65,253,175, 62,160,218,255,157, 51, 73,177,245,178, 88, -195,221,137,255,195,156,153,215,113,113,214,124,212,252,164,133,159,143,245,118, 71,120, 0,248, 40, 7,235,214,173, 51,104,195, -241,163,112,164,164, 20,238,253,220,113, 35,167, 8,144, 57, 99,202,156,191,193,187,115, 92,171, 61,136,150,162,254, 29,229,213, -178,150, 33, 96, 43, 59, 32, 39, 41, 7,209, 25,209,152,178, 9, 72,202, 49,188,206, 73,202,225,236, 5,168,214, 84,193,199,165, - 29,116,154, 90, 16, 17,193,160,193,131,177,101,203, 22,205,202,143, 62,146,209,132, 96,250,179,211,225,221,206, 27,181,213,213, -208,233,117,112,119,106,139,122, 81, 61,175,235, 45, 47, 47,111,146, 29,192, 53, 32,176, 25,249, 51,224,169, 4,100,101,101,145, -148,148, 20, 12, 30, 60,184, 73,123, 88, 88, 24,210,210,210,144,154,154,218,106, 74, 64, 75, 17,191,169,245, 15, 0, 37, 37, 37, -124,189, 0,191,192,176,222, 95, 9,131,235,127, 28,128, 75, 0,250, 2,200, 6,176, 22, 13, 59,117, 90,155, 78,192,211,149,254, -151, 80, 0, 76, 9,129,217,115,158,205,231,214,162,166, 25, 48,203, 11, 76, 64, 32, 19, 27,192,120, 7, 2, 3, 3, 85,204,114, - 65,107, 77,188,142,132,173,181,126,198,250,103, 35,107,242,234, 77, 32, 9,221,112,123, 88, 4,218, 97, 4, 92,166,172,130,238, -230, 31,128,103, 91, 72,238,254, 15,219, 87,230, 3, 98, 49,231,107,231,147, 5, 97,138,211,175,255, 31, 6,134, 3,129,115,206, - 34,212,109, 38, 46, 60,150, 8,252,123,190,197,246,214,242, 0,164,167,167, 99,228,160,158,136, 26,209, 3,241,125,230, 99,197, -202, 47,112, 46,255, 6,102,141, 25,136, 91,217, 59, 81, 81, 86,233,144,251,193,220, 82,129,173,231,195,154,181,239,168,123,212, -146,124,107,129,131,169,169,169, 84, 90, 90, 26,153,178,169,169, 66, 0, 0,209, 25,209,144,110, 43,196,182,109, 69,141,153, 0, - 76,192,160,183,183,183,217,249,151,166,105,232,105,128,208, 58, 56,187,200,240,236,115,207,201, 22,191,251, 46, 58,116,232, 64, -119,242,243, 19,105,106,170,161, 39, 0,161,245,160,105,219, 30,173,225,195,135, 83, 63,252,240, 3,185,123,247, 46, 42, 43, 43, -155, 40,142,198,217, 1, 92,178, 2,178,178,178,200,138,151, 10, 0, 89, 48,112,235,179,230, 7,200,130,177,226,165, 2, 36,255, -135,157, 18,144,149,149, 69, 38, 76,152, 32, 15, 11, 11, 83,221,189,123,183,217,231, 1, 1, 1,152, 48, 97,130,252, 81, 10, 12, -228, 99,253,219,227, 5, 80, 42,149,121, 70,207, 87, 71, 0,167, 1, 76, 82, 42,149, 92,182, 50, 21,200,223,154, 2, 96, 82,232, -199, 86, 33,160, 38,159, 91,115,153, 38, 38, 38,154,245, 2, 48,100,239,235,235, 43, 79, 73, 73, 81, 49,107,178,137,137,137, 86, -211, 0,173, 89,135, 92,131,255, 90, 42, 13,144,177,238,173, 5, 3,114, 65,209,191,146,224, 52,101, 21,212, 37, 23, 33, 57,188, - 10,245,155,230,128,138, 93,142,173,127,127, 10, 87,183, 94, 70,252,178,175, 1, 73,235, 84,118,158,159, 9,228, 44,219,130,208, -171,209,192,157, 26,188, 49,118,190,213,118, 71,120, 0,248, 90,255,217, 91, 22, 65,220,169, 55,220,208, 3,215,246,101,160,138, - 34, 56,122,241, 58,162,206,222, 96, 57,238,215, 26,223, 79,157,170,108, 66,246, 0,240,211, 79, 49,102,143,179,246,124,216,114, -245, 59, 34,237,208, 17, 25, 2, 73, 57,247,137, 31, 64, 51,203,159, 9, 24,220,182,173,200,236,247,221, 93,220, 81, 82, 81,130, -193, 93,135, 64, 93,167, 1,212, 26,232,180,245, 88,152,146, 2, 74, 4, 81,109, 77, 53,104, 90, 15,157,158,192, 89,226,132, 63, -170,255,128,147,222,118,182,241, 83, 79, 61,213,216, 55,135, 14, 29, 34,204,124, 99,156, 29,112,243,230, 77,214,215, 57,113,226, - 68, 42,249, 63, 32, 43, 94, 42, 64, 72,183,230,191,127,254,178, 22,201,255, 9, 5, 91,178,158, 56,113, 34,149,149,149, 69, 6, - 15, 30,140,128,128,128,102,159,159, 61,123, 22,217,217,217,170,214, 34,255, 6,107,156,106,201,181,127, 99,216,225, 5, 96, 48, - 14,134,224,239, 58,129,194, 29,168, 0,180, 20, 24,203, 31, 0,134, 14, 29, 42,207,204,204, 84, 49,174,127, 11,202,129,252,210, -165, 75, 42,174, 36,204,119,146,116,116, 26,160,177,245,111,142,248, 25, 69,135,203,249,158, 46,186,139,250, 95, 23,227, 54,126, -134, 95,236,114,160,162, 18, 69, 25,243, 16, 52,251, 99,220, 90, 59, 15,112,146, 0,162,214,169,236,124,173, 6, 8,241,157,196, -186,189, 53, 60, 0,233,233,233,213,211,162,134,220,244,160,189,186,212,194, 73,182,233,227, 57,248,124,251, 41,188,241,228,227, -152,241,209,127,241,212,135,223,180, 74,240, 40,163,128, 54,212, 1,160,236, 85, 78,237,113,245, 91,243, 2, 36, 53, 88,246,166, -228,111,108,253,219,130,191,175, 63,118, 31,200,193,240, 46,195,225,218,198, 13, 52, 77, 32, 34, 58,208, 20, 5, 66, 8,244, 4, -208,209, 4, 58,157, 14,234,138, 26,236, 56,182, 3, 82,189,148,115, 80,170,105, 86, 64,234,156, 17, 24,239, 95,140,140, 99,236, -101, 88, 82, 2,184,146,191,177,188,212,212, 84,178,108,217, 50,116,236,216,241,190, 98, 95, 84,132,244,244,116, 60, 12,150,191, -163, 21, 1,115,214,191, 61, 94,128,134,103, 34, 18,192, 99, 0,222,250, 11, 4,255, 1,128, 24,128,254,145, 86, 0, 76,163,254, - 19, 19, 19, 27,215,221,141,149, 3,227,215,246, 88,240,124, 38,114, 71,165, 1, 90,178,254,249, 18, 63,131,201, 75,215, 98, 51, -128, 39,151,140, 7,201,156, 7,106,234, 10,156, 46,186, 11,202,219, 11,133,191, 87, 26,172,127,177,184, 85,238, 80, 75,249,254, -246,212, 1, 96,163,112,177, 85, 14,214,173, 91,167, 5, 80,245, 82,100,223,202,127, 46,255, 68,251,230,194, 20, 77,251,182,190, -119, 11,206, 93,235, 48,227,220,127,221, 90, 59,107,196, 18, 57, 27, 47,209,112,207, 40, 48,247, 27,246,121, 0,204,145, 63, 99, -249, 3,176, 25, 16, 40,147,201,168,115, 91,207, 39,168, 70,228,101, 39,246,121, 10,149,154, 74, 80, 34,192, 80, 82,132,134, 94, - 79, 64,235,116,104,227,236,142, 67, 21, 39,113,233,112, 33,198, 70,140,205,179,187,115,139, 94, 6,192, 61, 13,176,137, 18,208, -241, 26,206,223, 12,224, 69,254,198,242,230,207,159, 79, 86,173, 90, 5, 79, 79, 79,220,189,123, 23,139, 22, 45,194,195,230,246, -119,132, 34, 96,201,250,231,227, 5, 80, 40, 20, 29, 0,248, 53,220, 40,253, 1, 36, 3, 40,250,139, 24,233,250,150, 20,254, 64, -234, 0, 88,242, 8,172, 88,177, 66,110,170, 40, 36, 38, 38,170,184,202, 51, 38,130,135,161,196,174,177,245,111,154,254, 87, 92, - 92,220,164,223,184, 84,237, 99,148,128, 73, 75,190, 2,217, 4,248,204, 80, 34,239,159, 79,225,241,244, 13,128,147, 19,218,200, -164,173,114,189,198, 57,254,230, 94,243,172, 3,160, 3, 32,106, 24, 91,145,157,227,113,123, 90,212,144,146,127,102,108,235,182, -240,197,113,109,253,253, 34,181, 0,206, 36, 38, 38,122, 0,112,227, 59, 30,247, 73, 58,134, 60,241,196, 46, 35,247, 63,183,239, - 91,179,224,141,203, 3,179, 85, 36, 90,162, 24,144, 37,152,146, 62,227, 17,176,180,228,241,252,212,231,183,110,251,239, 54,232, -167,233,206,140,238, 50,186,111, 59,247,118,208,212,107, 64, 8,129, 84, 34, 69,185,186, 22, 71,126,255, 9,235,190, 93, 15,121, -111,185, 67, 10,135,165,237,156,129,245,235,215, 99,222, 60,238, 53, 0,238, 43, 1,176,139,252,141,229,205,153, 51,135,169, 3, -128,135,121,205,223, 88, 17,224,243, 93,123,107, 7, 24, 63, 6, 48,228,251,107, 0,188, 14,224,152, 82,169,212, 67,128,165,190, -199,169, 83,167,144,145,190,160, 89, 29, 0,171,133,128, 90,170, 14,128, 57,143,128, 37,162,231,227, 5,176, 23, 45,149, 6,200, - 40, 35, 74,165, 18,185,185,185,116,113,113,177, 49,145,201,163,162,162, 56, 91, 55,147,151,174, 5,140, 10,255,140, 94,184,186, -241,117, 77, 43,220,108, 45,101, 61, 83, 20,181, 18,192, 61, 24,210,127,158,181, 83,220,173,151, 34,251,214,141,205,253,165,237, -244,119,191,134, 82,169,148,230,230,230,118, 68,211,114,214,188,198,163,165, 61, 1,182,234,251,219, 66, 75, 44, 9, 88, 34,127, -109,124, 48,176,205,182, 97, 38,239, 59,134,218,247,195, 1,114, 56,224, 8, 70, 12, 25,129, 78,238,157, 0,154,224, 15,205, 93, - 28, 58,113, 8,183, 10,110, 97, 76,200, 24,185,179,179,115,171,143,135,177, 18,224, 40,178,102, 60, 1,143, 74,192,159,189, 85, - 0, 29, 48,199,100, 0,200,128, 0,206,176, 84, 0,200,172, 2,208, 82, 72, 78, 78, 54, 75,246,198, 59,177,153, 64,197, 38,171, -192, 81, 86,127, 75,164, 1, 54, 68,248,235,114,115,115, 37, 13, 75, 7, 12,249,143,137,138,138,226,228,229,104,216, 76, 73,229, -232,115,180,180,198,236,232, 90,247, 28,225, 12, 64,162, 84, 42,223, 54,114,129, 61,103,175,204,177,111,173,201, 87, 42,149,163, -114,115,115,145,155,155,171, 1, 32,107,248,179,155,248, 25, 47, 0,223, 62,179, 69,242, 19, 38, 42,154, 28,199,149,184, 29,177, - 36,144,154,154, 74,165, 37,165, 17,255, 57,254,114,116, 53,127, 76, 73, 82,142,138,109, 60,192,224,208,193, 84,109,109,109,228, -218, 37,107, 17, 16,252,152, 10, 0, 46,156,253, 77, 30, 55, 54, 30, 33,225, 33,188,199, 99,248,240,225,212,166, 77,155,154,101, - 5,212,215,215,219,117, 3, 57,154,172,255,108,209,254, 15, 1,132, 20, 63, 51, 94, 0,211, 54,214, 10,128, 45, 75,156,173,165, -206,119, 82,100, 91,136,197, 94,162,114, 52,209, 49,242,114,115,115, 73,110,110,174,196,184,191, 2, 3, 3,121,253, 86, 3, 65, - 57,124,194,120, 24,214,190,205,192, 29, 64,181,161, 32, 63, 69, 1,112,129,237,252, 94, 54,227,113, 37, 55, 55,151,201, 43,171, - 12, 12, 12,108, 31, 24, 24,232,252, 48,244,165,189,150,184, 45,217,142, 90, 18,176, 73,238,169,220,238, 81, 87, 87,215,188,169, - 19,166, 49,147, 55,134,134, 14,117,200,121, 78,153, 50, 69, 32,215, 63, 63,217, 27,115, 88,189,131,201, 95, 6,195,114,195, 35, -175, 4,216,236,200,240,240,112, 65,107, 18, 32, 64,128, 0, 1, 2,254, 98, 16, 9, 93, 32, 64,128, 0, 1, 2, 4, 8, 10,128, - 0, 1, 2, 4, 8, 16, 32,224, 47,128,255, 7,201, 67, 6,106,228, 94,183, 75, 0, 0, 0, 0, 73, 69, 78, 68,174, 66, 96,130, -}; +137, 80, 78, 71, 13, 10, 26, 10, 0, 0, 0, 13, 73, 72, 68, 82, 0, 0, 2, 0, 0, 0, 1, 0, 8, 6, 0, 0, 0,197,144, +206,103, 0, 0, 0, 1,115, 82, 71, 66, 0,174,206, 28,233, 0, 0, 0, 6, 98, 75, 71, 68, 0,255, 0,255, 0,255,160,189,167, +147, 0, 0, 0, 9,112, 72, 89,115, 0, 0, 11, 19, 0, 0, 11, 19, 1, 0,154,156, 24, 0, 0, 0, 7,116, 73, 77, 69, 7,216, + 5, 19, 11, 8, 1, 11,126, 22,156, 0, 0, 32, 0, 73, 68, 65, 84,120,218,236,125,121, 92, 84,229,254,255,251, 57,179,179,239, +168,184,128,138,251,130,224, 26,106, 80,168,201,215, 52, 21, 48,179,237,214,189, 78,150,173,150,102,117,111,245,203, 43,106,218, +170,233,216,162, 89,106, 9,106,120,115, 5, 29,212,144,220, 21, 75, 19, 5, 17, 65,144,109, 96,134,217,207,156,231,247,199,204, +208,128,192, 44,160, 81,205,251,197,188,152,115,230,204,123,158,115,158,229,253,249,124,158,141, 68, 69, 69, 81,184,225,134, 27, +110,184,225,134, 27,127, 43, 48,238, 71,224,134, 27,110,184,225,134, 27,127, 31,156, 57,155, 5, 0, 32,238, 8,128, 27,110,184, +225,134, 27,110,184, 35, 0,110,184,225,134, 27,110,184,225,134,219, 0,112,195, 13, 55,220,112,195, 13, 55,220, 6,128, 27,110, +184,225,134, 27,110,184,241,151, 0,223,246, 96,222,188,121,196, 85,162,181,107,215,222, 54,150,192,205,231,230,107, 5,116,237, +218,181,127, 88,250,178,179,179,105, 92, 92, 28,113,231,199,159,151,239,220,185,115, 46, 23,190,168,168, 40,184,243,195,205,247, + 87,230,115,218, 0,248, 59, 67, 42,149, 54,122,128, 50,153,140,116,228,116,174, 91,183, 14,132, 16,226,206, 57,215,242,120,246, +236,217, 72, 79, 79,111, 56, 78, 74, 74,250, 75, 60,203, 61,123,207,180,218, 16, 36, 78,142,254, 75,151, 25,137,255, 78,136,117, +189, 17, 1, 3,234,177, 23,249,218,183, 58,108, 89,236,168,109,140, 27,127,211, 8,192,221, 40,172,123,246,236,137,203,200,200, +144, 91,143,167, 77,155, 22,159,152,152,152,221, 17, 30, 6,165,230,182,179,163,234,170, 84, 42,165, 69, 69, 69, 0,128,240,240, +112, 0,248, 83, 52, 34, 77,141, 43,139,129,213,162,103,238, 40,239,214,173, 91, 29, 54,212,164, 82, 41,221,182,109, 91,195,241, +206,157, 59, 49, 97,194,132,134,227,244,244,116,250, 71, 25, 1, 49, 49, 49, 20, 0, 78,159, 62, 77,218,227,186,140, 31,100,173, + 24, 0,178, 54,231, 95, 88, 68, 55, 0,192, 45,157, 14,172, 86,111, 62, 89,171, 4, 0, 36, 39, 39, 35, 33, 33,161,197,244,173, + 79, 88, 79, 35,203, 34,157,250,253,248, 95,227, 29,200, 23, 9,252,159,189, 0, 93,198, 78, 40, 20,211,161, 0, 16, 45,121, 31, +111, 73, 78,163,155, 24,168,212, 21,224, 45,109,138, 83,191,155,149,149, 21,151,150,150, 38,183, 61,151,156,156, 28,159,144,144, +144,221,145,234, 86,123,181, 1,127,134,251,189, 19,120,231,141, 23,136,151,192,151,232,197, 66,170,175,213, 50,245, 90, 37,247, +193, 39,171,255, 22,179,227,236, 26, 0,123,246,236,137,179,254,111,171, 80, 91, 27,146,119,183, 45,129, 87, 55, 95,212,223,168, +195,219, 41,111,201, 51, 50, 50,224,182,134,237, 67, 38,147,145,240,240,112, 90, 84, 84,132,162,162, 34,236,219,183,175,195,122, + 18,214,188,150,201,100, 68, 38,147, 9,164, 82,169,113,197,138, 21, 39, 1, 96,225,194,133, 35, 90,251,238,244,233,211, 27,222, +179,172, 9, 6,163, 30, 6,189, 1, 6,131,249,197,178, 44, 22, 46, 92,232, 84, 90,108,197,191, 57, 76,152, 48,225, 15, 53, 2, + 28, 49,126, 98, 98, 98,236,114, 36, 78,142, 38,174,136,188,195,240,243, 65, 94,225,119,144,160, 43, 76,200, 65,197, 23,103,112, +190,160, 26, 51,150,109,112,232,235,145,101,145, 14, 10,186, 25,242,129,114,187, 13,177, 36,241, 45, 4, 76,123, 26,165, 47, 69, + 3, 90, 69,195,249, 51,218,215,112, 6, 0,180,192,120, 73, 50, 14,250,159,134, 31,128, 24, 69,140,195,229,183, 41,210,210,210, +228,105,105,105, 29,162,189,178,166,177, 61,218,128, 63,195,253,182, 55, 54,173, 89, 75, 30, 13,139,224,191,144,244, 56, 47,164, +127, 24,195, 39, 33, 68, 83, 87,199,137, 17,106, 98,186,116, 53,233,110, 94, 51, 57,248,236,110, 58,209,134,119,113,128,111,129, + 19,124,171,238,168, 1,144,145,145, 33,223,246,239, 55,144,242,222, 82,121, 98, 98, 34,105, 75, 1,179, 10, 63, 0, 84,105,170, +129, 64, 96,241,193,119,160, 44, 84, 64,250,175,142, 37,100, 45, 85,136, 63, 58,141,182, 70,192, 3, 15, 60,128,162,162, 34,132, +135,135,119,184,103, 39,151,155, 29,137,248,248,120, 42,147,201, 24,153, 76, 22, 38,149, 74, 75, 87,172, 88,113,218, 81, 30,150, +101, 97, 48, 24, 27,132,223, 86,252, 79,157, 58,133,225,195,135, 59,149,174,148,148,223, 61,192,217,179,103, 35, 51, 51,179,145, + 1,208, 30,101,197,149,124, 56,125,250, 52,201,206,206,166, 19, 39, 78,188,237,179, 3, 7, 14, 96,235,214,173, 13,199,173,141, + 91,184,205,120,111,199,238,128,176,136,110, 40, 85,212, 97,199, 51, 51, 17, 72, 98, 81,240,249,171,232, 57,189, 39, 50,157, 16, +127, 43,230,206,157, 75, 1, 96,253,250,245,109, 46,179, 97,219,114,160,185, 94,143, 82,105, 68,171,215, 93, 16,103,225,221,193, +183,144,122,225,205, 54,229,103,123,136,110,123,114,180, 71, 36,224, 78,223,111,123, 33, 39, 39,199, 3,192, 61, 0,188,108, 78, +215, 2,200,139,141,141,173,113,148, 71,203,105, 25, 67,149, 94, 48,121,234,116,177, 2, 70,177, 64,192,231, 43,117, 98, 70, 40, +212,114, 60, 31, 79,214, 32, 49, 26,249,229, 55,245, 98,158, 72,167, 51,233, 77, 82,169,148, 52, 55,102,196, 22,181,181,181,255, +181,190,207,207,207,175,242,244,244,100,212,106, 53,103,123,205,200,145, 35, 63,116, 52,141,148, 82,187,194, 78, 8, 89,208,214, +103,202,183,231,253,247,233,211, 7,145, 94, 62,104, 75, 20,192, 86,252,171, 52,213, 72,189,255,157,134,207,254,145,241, 44, 16, + 2, 76, 95,145,226, 84, 33,107, 73,160,219, 75,164,111,220,184, 1, 0,232,214,173, 91,163,247,214,223,181, 87, 32,238,100,136, +207,214, 8, 48, 26, 89,172, 91,183,238,142,121, 1,206,114, 54, 17,127,219,239,223,148,201,100,254, 82,169, 84,225,176,248, 27, +141, 48, 24,244,208, 27, 12, 48, 54, 17,127,202, 57, 23,161, 75, 73, 73,193,169, 83,167, 26,142, 87,173, 90,133,164,164,164,134, +227,244,244,244, 54, 27, 59, 54, 6, 79,155,203,159,173,240,207,158, 61, 27,195,134, 13,115,137,167,189,186, 3, 74, 10,139,161, +222,249, 31,120, 61,245, 49,194, 34,186, 33, 52, 80,130,194,157,133,102,241,247,243, 49,119, 1, 8,120, 14,113,181,135,240, 3, + 64,159,139, 87,113,227,237, 37,208,166,109,108, 61, 66, 32,145, 64,167,211,161,160,160, 0, 21,186,203,232,131,176, 22,175,205, +202,202,138,107,173,236,203,100, 50, 98,173, 39, 89, 89, 89,113,206,132,199,109,163, 98,214,250,106,123,206, 89, 71,160, 37,225, +118,166, 45,104,238,126, 51, 51, 51, 41, 33, 4, 9, 9, 9,164, 45,247,107,197,211, 79, 63, 77,191,252,242,203, 54,229,121, 78, + 78,142, 47,128,233, 7, 15, 30,252, 15,199,113,122, 27, 17,228,243,120, 60, 79, 0,255,140,141,141,221, 99,143, 39,191, 48,159, + 47, 17,138,197, 2,129,200,147,225, 19, 31,202, 19,121,112, 60, 30,159, 35, 12, 56,194, 55, 81, 30, 79,207,227,136, 78,205, 51, +105, 60,133, 2,194,235,213, 77, 39,158, 26,194,161,216,126, 26, 21, 10,133, 82,163,209,176, 0,160, 86,171,185, 55,222,120,163, + 65,240,151, 46, 93,250,114, 91,203,251,132, 9, 19,158,177,190,207,204,204, 92,215, 30,117,136,177,231,253, 47,153,149, 4, 93, +101, 37, 94, 29,216, 15,182,125,247, 14,123, 33,150, 46, 4, 91,241,159, 54,109, 90,188, 76, 38, 35,211,166, 77,139,223, 48,237, + 51,115,100,177,111, 80,163,235, 29,193,194, 53,249, 88,184, 38, 31,207,173,188,132, 39,222,251, 5, 51, 22,159,107,243, 3, 41, + 41, 41,113,200, 48,184, 91,226, 95, 84, 84,212,162, 48,135,135,135,195,104, 48, 96,212,200,145,109,254, 29,107,152,124,219,182, +109,144,203,229, 13,175,214, 12,173,150,196, 48, 62, 62,190,169,248, 55, 24,202,142, 52, 76, 44,107, 50,123,254,122,115,232,191, +169,248,155, 76, 38,168,181,106,167,238,209, 26, 49,104, 26, 53, 72, 79, 79, 71,122,122,122, 35, 99,192,169,251,205,110,220, 30, +202,179,179,157,122,102,173,137,255,236,217,179,177, 98,197,138, 6,241, 23,240, 5, 78,241, 36, 78,142, 38,150, 46,152,102, 95, +206,112,105, 81,140,250,233,163, 64,211, 94, 69, 73, 97, 49,232,244,254,191,123, 43,105,175,130,223, 57, 24,240,243,187,171, 30, +161,186,170, 0,218,180,141,160,148,226,194,133, 11, 24, 63,126, 60, 36, 18, 73, 35,225,247,247,247,135, 86,171,133, 86,171, 69, +105,105, 41, 30,209,190,128, 47,252, 95,106,145,211,218, 7,222,218,243,177,126,214,180,191,220, 81,225,110, 47,103,197,250,221, +166,226,111,207, 65,106,237,126, 51, 51, 51,105,122,122, 58,210,210,210,144,149,149, 69,219,122,191, 79, 63,253, 52,229,243,249, +120,250,233,167, 93,174, 19, 57, 57, 57, 98, 0,255,202,202,202,122,227,189,247,222, 59, 78, 8, 9,183,190, 0,116, 13, 12, 12, +244, 56,116,232,208,218,156,156,156,241,173,241,152, 40,199,227, 17,129,200,192, 82, 31,189,222, 24, 98,226,184,174, 38,142,139, + 48, 17,210, 29, 60, 94, 32, 33,196, 15,132,231,195, 81, 4, 80, 3,231,167,212, 26, 61, 67,124, 88, 30, 51, 82,229, 80, 30,105, + 52, 26,182,169,215,223,209,193, 56,226,253,107,202,203, 48,121, 88,180,211, 2,109, 53, 34,222,221,182, 4, 0, 26,196,223, 26, + 69, 72, 76, 76,204,182, 26, 1, 37,202,155,136, 94, 56,218, 41, 35, 67,173, 53, 65,173, 53,161,172, 90,143,210, 74, 29,110,220, +210,185, 36,124,214,202, 98, 79,252,255, 40,180,100, 4, 0,128,206,160,135, 78,167,115,153,219, 42,218,214, 62,242,224,224, 96, + 91,111, 22,142, 54, 38, 77, 61,225,150, 66,137,142, 52,122, 6,163,222,236,249,235, 13, 48, 24, 27,139,191,209,104,132, 90,173, +134, 74,169,250, 67,243,196,108, 48,165,217, 6,228,172,127,216,182, 45,205,101, 35,192, 86,252,173,194,207, 48, 12,196, 98, 49, + 60,189, 60,218,148,230, 61,123,207,208,150, 94,246,190,187,111,241, 59, 8, 68, 44,216,132,231, 1, 0, 94,185, 87,113,190,160, +218,108,176, 37, 60, 15,227,133,119,129,170,106,167,210, 51,119,238, 92,106,237, 14,112, 5,158,168, 2, 0,108,220,184, 17, 25, + 25, 25,120,255,253,247,113,226,196, 9,232,245,122, 84, 84, 84, 88,189,178,134,235,195,194,194,160, 5,192,195,181, 63,164,188, +180, 84,238,155,122,243,174, 26, 20,205,117, 11, 56,203,103, 27, 9, 75, 75, 75,107,211, 61, 91,197, 31, 0, 92, 53, 2,114,114, +114, 58, 89,196,127,238,215, 95,127,125,241,173,183,222,122,104,203,150, 45,232,211,167, 15, 0,160, 71,143, 30,168,171,171, 19, +189,251,238,187,167, 15, 29, 58,244,109, 78, 78, 78,120,179, 68, 4, 0, 71, 9, 56, 86,108, 50,177, 1, 38,214,212,213,104, 50, +246,230, 49,164,139,144,207, 8,196, 2,158,150,239, 33,172,245,244,230, 41,121, 98,202,138,121, 60, 79, 62,107,240,185,118,230, +172,232,177,224,143,236,166, 59, 63, 63,191, 74,173, 86,115,205,133,249,135, 14, 29,122,217, 96, 48,180, 91, 89, 26, 58,116,104, +187,113,241, 91, 19,238,207,231, 62,253,187,216,150,220,192,171, 3,251, 97,101, 70,134,211, 99, 1,172,222,191, 85,244, 27,121, + 41,137,137,217, 25, 25, 25, 0,128,192,193,157,156, 74,124,189,214, 4,149,134,133, 82,205,162,174,158, 69,173,138,117,250, 1, + 52, 55,242,223,214,203,183,125, 95, 88, 88,136,218,218,218,187,214,104,172, 91,183, 14,225,225,225,176, 14,250,179,237,235,151, + 74,165,116,221,186,117,208,105,181, 46, 27, 0, 82,169,148,110,216,176, 1, 37,165,165, 16,240,120, 8,237,212,169,145,248,223, +127,255,253, 72, 73, 73,113,168,113,146,201,100, 36, 62, 62,190,145, 17,208, 52,146,225,232, 88, 5,131,222, 0,131, 94, 15,163, +209, 0,150, 53, 53,136,191, 94,175,135, 70,163, 65,125,125, 61, 84, 42,231, 13, 0,219, 46, 0, 43, 92,245,252,183,165,109, 3, + 40, 80,101, 17, 26,106, 46, 68, 32,148,154,141,128,180, 52,164, 36, 39, 59,221, 29,208, 84,252, 5, 2, 1, 68, 34, 17,196, 98, + 49,196, 98,177, 75,247,221,168, 94,183,208, 37, 96,175, 75,107,198,186,237,160, 83, 35,112,107, 76, 52, 2, 17, 11,201,204, 79, +193,150, 85, 2,126, 62,224, 87,111,197,143, 31,157, 6,120, 60,167,210,210,214,174, 0, 53,207,220,166,164,166,166,162,178,178, + 18,107,215,174,197,208,161, 67,241,222,123,239, 33, 58, 58, 26, 90,173,182,169,135,102, 53,169,239,170,240, 59, 42,208,174,118, + 7,180,100, 72,184,194,147,156,156,220, 32,252,174,212,141,230,196,191, 65,108,248,124,176, 44,235,108,119,128,119, 94, 94,222, + 39,243,230,205, 59, 50,120,240, 96, 31, 0,120,231,157,119,144,159,159, 15, 0, 24, 61,122, 52,118,236,216,129,177, 99,199,122, + 62,242,200, 35, 5,217,217,217, 89, 60, 30,239,145,219, 27,122, 32, 32, 48,128, 43, 44, 44, 96,179,229, 7,247,246,238, 29,153, + 29,209, 35,252, 34,207, 91, 82,193, 35, 66, 53, 35, 18,104, 24,177,135,202,192,231, 25, 64,141, 60, 78,108,244, 86,149, 86,123, +157, 56,116,110,100,144,127,232, 14,187,198,168, 77,159,255,206,157, 59,159,152, 62,125,250,215,214,176,191, 82,169,100,132, 66, + 97,155,203, 82,123,133,253,237, 70, 0,172, 94,254,240, 94,145,208, 85, 86, 66, 93, 98, 22,193,241, 22,239,208,217, 40, 64,225, + 47, 87,111,227,110,238,184,250, 66,185, 83,137,111,171,248,219, 10, 63,165, 20,221,186,117,107,244,153,209,104,108,120,213,214, +214, 66,173, 86,163,166,166,230,174, 53, 30,214,121,254,251,246,237,107, 20, 9,176,138,255,144, 33, 67,160,211,105, 27, 26, 58, +106,181,102, 28,108,152,214,124,182, 6, 70,163, 17, 93,195,194, 96, 52,153,154, 21,127,103, 26, 18,139, 17,112,155, 87, 98,157, +186,216, 90, 36,227, 54, 3,192, 96,108, 16,255,147, 39, 78, 66,163,213, 66,165, 82,161,174,174, 14,181,181,181,141, 60, 59,103, + 97,237, 6,112,181,223, 31, 0,170,171,170, 81, 93, 93,133,170,234, 26, 84, 85, 87,163,186,186, 26,213, 85,102,143,180, 95,255, +254,168,177,188,119,214,251, 7,128, 97,195,134,253,238,245,123,122,194,203,203, 27,222, 94,222, 80,169, 84,241,109, 41, 79,173, +117, 9,216,251,110,193,251,115, 33,152,249, 41, 2, 17, 11,126,238,167, 48,110,127, 30,240,243,193,174,103,147,112,125,215, 53, + 60,184, 98, 19,192,191,203,203,138,232,174, 67, 18, 38,129, 90,173,134, 78,167,131, 70,163, 65,110,110, 46,150, 45, 91,214,236, +229, 30, 30,214, 8,202, 85,167,197,219, 85,175,218,246,249, 54,125,222, 45, 29,183,197,200,104,174, 91,192, 25,158,132,132, 4, +146,156,156,140,164,164, 36, 76,152, 48,193,229,200,196,151, 95,126, 73, 88,182,113,155,204,178, 44,156, 29, 11, 16, 27, 27,123, + 37, 57, 57,121,232,150, 45, 91,198, 31, 61,122,212, 59, 33, 33,225,132, 85,252, 45,142, 42, 68, 34, 17,189,126,253,186, 96,239, +222,189,125,253,253,253, 79,198,198,198, 22, 52,199, 85, 87, 91,199, 69, 70,244, 81,141, 30, 61, 58,233,226,197, 95,239, 83,170, + 85,157, 40,107,100,193,192,200,234, 25,189, 94,175,215, 42, 81,174,228,244, 58, 85,105,113, 57,251,227,238, 61,203,131, 2,131, + 43, 12, 6,141, 93,247,189, 57,239, 95,161, 80,240, 1,192,199,199,167,195,118, 11, 48, 45,121,255,219,254,253,134,217,106, 46, + 47,107,244,153,179, 99, 1,166, 77,155, 22,191,230, 95, 31, 3, 48, 15,248,203,200,200,144,219, 78, 45,204,200,200,144, 79,248, +230, 33, 0,192,153, 21, 63, 99,218,180,105,241,119,235,230,109, 43, 73, 73, 73, 73,131,183,111, 21,125,155,204,133, 74,165,130, + 78,167,179,105, 68,238, 94, 26,159,121,198, 60,246,195,200,178,184,120,241, 34,206,158, 57,131,161, 67,134, 66,167,211, 65,171, +213, 65,167,213,226,219,111,190,129,245, 58, 71, 42,250,170, 85,171, 48,160,255, 0, 24,141, 70, 92,185,114, 5,172,209,128,210, +146,210,118,125,166,214, 99,203,154, 5, 8, 15, 15,119,168, 97, 50, 24,245, 96, 77,230,176,255,241,227, 63, 67,173, 85,163, 94, +165, 68, 93, 93, 29, 20,181,181, 80, 40,106,218,100,136, 89, 35, 1,109,241,112,142, 28, 57, 2,149, 74, 5,149, 74,105,249,175, + 66, 80, 96, 32,250,245,239,143,223, 46, 93,194,225, 35, 71,156,230,180,122,255,124,190, 0, 30, 30, 30,240,242,242,130,183,151, + 23,188,188, 60, 80,163,168,137, 7,144,125,167, 67,253, 45,225,124, 65, 53,140, 23,222, 69, 53,114, 64, 18, 87,130,196,254, 7, + 5,239,207,197,212, 21, 95, 67, 44, 96, 0, 1,223,252,114, 1,174,118, 5,148, 78,249, 12, 1, 91,167, 64,163,209, 32, 32, 32, + 0, 10,133, 2, 10,133, 2,199,142, 29, 67, 89, 89, 89, 67,152,184,225,250,210, 82, 60,235, 47, 65,144, 71,101,107, 30,112,188, +173,168,218, 14,146,179,190,183,126,102,189,214, 21,239,220,209,238, 1, 71,197,223, 85,207,191,185,251, 77, 72, 72, 32, 19, 38, + 76, 32,109,185,223,166, 70,128, 43,226,111, 69, 80, 80, 80,222, 67, 15, 61,244, 72,106,106,106,223,243,231,207,199, 74, 36, 18, +222,212,169, 83,137, 72, 36, 2,199,113, 36, 49, 49, 49,239,197, 23, 95, 28, 50,104,208,160, 93,255,252,231, 63,159, 48,153, 76, +213,173,196,188,185, 95, 47, 93, 57, 57,104,240,144, 71, 79,158, 56, 49, 99,215,238,255, 45, 61,117,226, 68,167,139,249,191,137, +175,148, 22,208,111, 63,254, 94,146,186,234,253, 1, 89,187,119,175,234,221,171,247,143, 94,161,158, 71, 98, 99, 99, 77,112, 48, +229, 9, 9, 9, 56,121,242,100,212,186,117,235,222,213,233,116,130,247,222,123,239,131, 93,187,118,205, 46, 45, 45,189,187,194, +209,214, 46,128,192,107, 69,168,177,132,254,109, 49, 62, 56, 24, 43,241,155,227, 94,135, 37,196,255,219,233,139,240,235, 27,132, + 9,223, 60,132,140,199,126,144, 91,195,254, 86,241,183,122,255,206,204, 50,216,145,218, 62, 35,241, 9, 33,184,116,233, 18,172, +133,181,105,152, 85, 32, 16, 64, 32, 16,160,178,178, 18,137,137,137,119, 61,147,172,163,254,215,173, 91,135,145, 35, 71, 66,167, +215, 67,171,211, 66,103, 25,220,164,213,153,187, 1, 86,175, 94,109,183, 49,145, 74,165,116,197,138, 21, 48,153, 76, 56,125,250, + 12, 4,124,115,216, 54, 50, 50, 18,215,138,138, 80, 90, 90,138,173, 91,191,195,236,217, 15,227,224,193,131,212, 54, 18,208, 90, + 3, 36,147,201,132, 0, 88,169, 84,202, 53,231, 1, 57, 51, 85,209,234,249,231,230,230, 66, 93,175,105, 48,192,148, 42, 37,148, +202, 58, 40,149,245, 46,135,194,173,222,191,101, 37, 64,151, 12,129,217,179,103, 55, 58,142, 8, 15, 71,191,254,230, 65,113,191, + 93,186,132,107,150,136, 71,211,235, 28,193,152,123,198, 64, 36, 20, 65, 34,145, 64, 44, 22, 67, 36, 18,161,188,188,220, 97,241, +183, 23,234,119,117,141,128, 25,203, 54, 96, 7,128, 7, 82,255, 15, 52,237, 85,144,148, 85, 56, 95, 80, 13, 18,224,143,171, 37, + 74,179,247,239,100, 23, 64,211,174, 0,167,167, 7,106,181, 0,175,160, 73,120,223, 44,244, 70,163, 17, 95,124,241, 5,198,143, +255,125, 92,216,193, 39,195,128, 10, 13,250,238, 81, 32, 42,184, 71, 75, 13,120,118,147,190,111, 57,208,208,252,203,155, 94,235, +138, 96,183,214,111,239,170,231,239,170, 33,113,167,239,215, 98, 4,180,121, 22, 64,120,120,248,214,177, 99,199, 6,159,203,203, + 75,209,106,181, 67,228,242, 67, 18,145, 88,196,103, 8,131, 67,135, 14,121, 15, 24, 48, 96, 83,114,114,242,127, 42, 43, 43,237, +122,235,179,103,205,228,126,220,251,227,225,161, 67,135, 45, 52,176,250, 7,174,230, 95, 89,202, 21, 21,176, 0,168, 24,140,113, +112,239,190,105, 33, 33,193,123,120,124,225,183,255,125,107,185,225,219,141, 27, 44,125,124, 45, 99,228,200,145, 31, 38, 36, 36, + 0, 0, 42, 43, 43,145,149,149,229,243,213, 87, 95, 45, 5,128,147, 39, 79,142, 28, 56,112,224,190, 63,133, 1, 96,245,206,239, +255,118, 75,235, 94,134, 19, 83, 2,173,214,111,244,194,209, 8, 28,220,169, 65,244,109, 67,255,103, 86,252,236,148,229,218, 94, +115, 82,173,105,235,223,191, 63, 46, 92,184,208, 72, 88,106,107,107, 11, 0,244,106,238, 59,174,174,189,220,214,116, 54, 61,255, +237, 55,223, 66,167,211, 65,111,208,195, 96, 48, 96,197,138, 21,176, 39,254, 86,112,156, 9, 98,137, 23,180, 90, 29, 46, 93,188, + 8,190, 64, 0,163,193, 0, 15, 79, 15,108,221,186, 21, 60, 30,207, 58,119,190,213,123, 93,177, 98,197, 62,169, 84,106,144,201, +100, 33,214,116, 54, 89, 7,192,169,208,230,194,133, 11,145,147,147,131,250,250,122,212,171,213, 80, 41,149, 22,241, 87, 66,165, + 84,161, 94, 85, 15,181, 77,131,239,200,179, 27, 62,124, 56, 61,117,234, 84,131,247,223,220, 52, 64, 71, 23, 1,138,139,139,187, + 45, 47,172,162,127,246,236,217, 6,111,222,209,123,142,137,137,161,214, 69,126,188, 60,188, 32,150,136,161, 82,169,226,109,250, +176,157,106,120,239,212, 98, 64, 86, 35, 96,122,234, 87,160,219,129,160, 39,101,200,126, 41, 9, 99,151,111, 6, 4, 2,120,138, +219,214,207,217,212, 16, 0, 0,121,142,189, 96,227, 45, 12,222,231,129,242,255,105,160, 88,242,251, 89,163,209,136,113,227,198, + 1, 0,194,252, 37,248, 73,214, 13,239, 47,187,129,207,206,104, 91,101,179,245,248, 1,243, 64, 56,107,195,222,116, 80,156,179, +211,226,108,199,239,180,213,243,111,174, 77,112,133,235, 78,222,175,173, 17,208, 30,229,111,224,192,129,159,168,148,170,189, 35, + 98,134,143, 84, 41,149, 1,172,137,213,135,134,134, 86,134,133,133,149, 43,149,202,243,149,149,149, 14, 55, 10, 83, 38, 79,225, + 0,108, 61,122,228, 68,110,236,216,177, 63, 72, 36, 18, 95, 2,202, 17, 66,192,113,180, 78,171, 86,200, 47,231, 21,171,190,221, +184,193,161,118,222,250,204, 0,243, 64,234,166, 3,245,150, 45, 91,246,159, 63,133, 1,144,152,152,152,221,150, 5,127, 28, 41, +172, 86, 67,192, 42,252,237, 41,232,109, 73,219,224,193,131,113,242,228, 73, 84, 86, 54,132, 8,123, 1, 64,117,181, 57,162,244, +216, 99,143,253,161,153,213,244, 25, 81, 74,233,163,143, 61,138,213,171,215, 88,250,204, 89,248,250,250, 18, 71,191,111,133, 68, + 34,182,242,153,189, 41,181,198,246, 59, 0,236,110, 54,209,127,197,138, 21, 87,164, 82,105,133, 76, 38,227,217, 14, 8,180, 76, + 11,116,184,161,179,206,125,143,141,141,109,247,103, 55,124,248,240,166,123, 1, 52,124,238,236, 10,128, 50,153,140,100,103,103, +211,173, 91,183, 54, 90,168,199,202,237, 74,121,142,139,139, 35, 70,214, 8,163,202,216,174,247,222, 90,232,223,217,189, 1,102, + 44,219, 0,216, 44,252,115,239, 27,191,143, 75, 82,183, 83,122, 27, 69, 0, 6,182,110,124,150,198,150,162, 20, 64,244,251,254, + 88,114,186, 15,130, 1, 84, 22,168,209,187,119,111, 0,192, 39, 75,252, 49,105, 68, 48, 34, 38,229, 59,244,219,206, 76,117, 75, + 75, 75,147,183,182,236,177,189,246,166, 61,218,188,182,114,221,141,251,109, 79,140, 30, 51,250, 10,128, 43,183, 69,172, 3, 3, + 93,226, 27, 55,126,100, 17,154, 29, 21, 26,134,222,125, 6, 57, 99, 72,181,235,125,182,199, 34, 63, 46, 25, 0,119, 90,192,246, +236,217, 19,151,177,162,227,237, 5, 96,173, 72, 35, 70,140,192,158, 61,123,116, 22,209,231, 0,120,220,137,200, 67, 59, 21, 18, + 34,147,201, 26, 60,251,214,196,255, 78, 98,225,194,133,182,241,212,134, 6,219, 58,141,208, 25,111,231, 78, 62, 95, 91,238,236, +236,236, 54, 47,251, 27, 23, 23, 71,226,226,226,218,156, 46,123,107,251,183, 7,218,210, 37,176,104,209, 34, 20, 22, 22,182, 91, + 90, 28, 89,222,215, 89,156,121, 77,129, 51, 48, 15, 12, 29,159, 44,193,254,227,125, 16,234,225,133, 95, 79,221, 66, 95, 7,197, +223, 94,249,235,168,203,225,182,199, 90, 2,127,166,251,237,128,207,191, 75, 59,243,173,186, 91,105,191,235,187, 1,222,169, 8, + 67,123, 26, 1,137,137,137,226, 63, 89, 1, 36,127,240,111, 91, 87,168, 97,173, 6,128,187,241,232, 56,104,107,151, 64,207,158, + 61, 73,207,158, 61,219,165,189,113,102, 31, 0, 87,113, 36, 77,139, 35,105,249,238, 58,235,134, 27,246,156,200,168,168, 40,234, +126, 12,110,184,225,134, 27,110,184,241,247, 2,227,126, 4,110,184,225,134, 27,110,184,225, 54, 0,220,112,195, 13, 55,220,112, +195, 13,183, 1,224,134, 27,110,184,225,134, 27,110,184, 13, 0, 55,220,112,195, 13, 55,220,112,227, 47,129, 70,179, 0,230,205, +155,231,242,200,212,230,230,137,187,249, 58, 30,223,220,185,115, 93,226, 27, 54,108,216,109,124,103,207,158,117, 57,125,205,241, +253, 89,242,195,217,103,184,126,253,250,187,146,190,246,206,143,187,153,191,246,166,137, 58,251,252,218,155,207,221,190,184,249, +154,225,235, 10, 64, 1, 64, 8,160,182,163,165,207,105, 3,192,141,191, 62,214,175, 95,239,126, 8,127, 51,248,249,249, 49, 48, + 79,207,228,215,213,213,113,148, 82, 83, 71, 74,159,117,223,249,172,172, 44,218, 30, 11,205,180,215, 74,123,110,220, 57,236,218, +181, 43,110,234,212,169,217,127,242,219,176,174,125, 37,113,214, 0,232,144, 17, 0, 55,254,122,160,148, 54,218,234,216,213, 8, +192,218,181,107,237, 94, 51,113,226,196,184,204,204,204, 70, 43,139, 77,152, 48, 33,254,192,129, 3, 46, 85,244,244,244,244,102, +249,146,146,146, 58, 4, 95, 71, 6, 33,132,244, 8, 13, 69, 81,121, 57,173,173,173,181,238,207,224,212, 18,131,182,198,226,169, + 29,171, 75, 8,193,115,178,189,121, 25,210,201, 67,190,161, 20,202,245,251,242,158, 91, 52, 99, 36, 1, 67,249, 10,149,142, 14, +159,249,188,211, 91,114,102,101,101,197, 89,151,156,181,252,119,105,185,217,166,226,111, 45,247,109,221,104,167,185,239,186,202, +217, 30,124,109,221, 50,216,149,104,201,157, 16,255, 61,123,246,200,167, 78,157,250,103, 55,206,172,251,176,223,209,174,244,119, +222,120,129,241, 18,248, 50,122,177,144,211,215,106,249,245, 90, 37,251,193, 39,171,219,101,135,193,219, 12,128,246, 20, 8, 87, +185,156,229, 35,132, 48, 22, 43, 76, 75, 41,229, 58, 90,250,218, 75, 96,219,195, 0,176, 54,234,182,105, 37,132,232, 41,165,162, +182, 68, 10, 8, 33, 20, 0, 86,173, 90,213,104,199,176, 5, 11, 22,200, 9, 33,160,148, 18,103, 27, 37, 0,224,190,247,111,116, +158,153,149, 41,207,204,204,116,186, 1,108, 79,190, 63, 67, 20,133, 82, 74,227,123, 69,208,248, 94, 17, 0,128,114, 3, 59,167, +147,144,191,217,250,249,111,202,122, 81,153, 3, 27,167, 0,192,201,237,159,230,115, 28,194,238, 25, 19,228,243,193, 75, 99, 15, + 12, 25,226,119,253,185,229, 35,255, 11, 0,183,234, 52,255, 39,224,147,255, 1,228,226,220,185,115, 7, 58,251,108,154, 46, 69, +219,150,229,102,109,197,191, 61,140,128,150,190,227,170, 88,182, 7, 95,114,114, 50,210,210,210, 28,186, 39,103, 34, 42,173,241, +181, 87,100,198, 86,252, 57,142,195,250,245,235,177,121,243,102, 58,103,206, 28,226,100, 30, 11,101, 50, 89,187,172,151,189,120, +241,226,185,169,169,169,174, 86,104, 31,139,231,175,190, 19,117,120,211,154,181,204,163, 97, 17,226, 23,146, 30, 23,134,244, 15, +227,243, 73, 8,163,169,171, 99,197, 8, 53, 48, 93,186, 26,116, 55,175, 25,218,250, 27,124, 71, 26, 55,169, 84, 26, 12, 96, 56, +128, 83, 50,153,172,178,131,121, 58, 62, 0, 18, 0, 76, 7,176,147, 16,146, 69, 41, 85,182, 3,239,119,148,210,135, 93, 21,216, +142, 2,134, 97, 90, 53, 82, 8, 33, 35, 1, 8, 9, 33, 33,148,210,138,150,174,107,205, 64, 33,132,208, 23, 95,124, 17,221,187, +119,191,109,187,208, 85,171, 86,197, 23, 23, 23,203, 9, 33,212, 81, 35, 64, 42,149,210,141,207,123,226,241,177,183,111, 46,195, +125,239,143, 77, 63, 25,240,164,147, 94, 83,123,242,213,213,213,197,189,254,250,235,242,148,148, 20,196,199,155, 87,182, 59,119, +238, 92,220,218,181,107,229,221,187,119, 7,199,113,208,106,181,136,139,139,195,196,137, 19,237,114, 10,235,212,113,125, 95,223, + 38,207,140,238, 26,223,233, 95, 19,178, 1,128, 45,103,227, 46,191,205,202, 77,221,125,160,228, 60,161,208,250,160,194,247,100, +252,211,139, 66,236,122,199,189,186,117,234,212, 93, 40, 41,123,254,185,199,244,161, 18,161, 80, 89,163, 37, 43,190,218,178,249, +141,103, 30,133,191, 68, 66,117, 70, 19,253,247,234,175,244, 0, 72,231,206, 65,252,242,242,106, 38, 42,170,249,157, 53, 71,132, + 28,136,188, 25,230,225, 23,123, 79,240,170, 97, 49, 1,130,141, 27,175,134, 7, 7, 73,170, 62,124,233,248,170,162,235,195, 76, +147, 39,117,206,205,191,162, 42,126,242,241, 94,137,214,114,227, 76, 29,176,221, 32,167, 45, 94,104, 83,241,111, 90, 63, 93,225, +239,136, 17, 0,139, 16, 83,171, 17,144,156,156,108,123,190,145,104,219,110,236,227,170, 81, 97,229, 73, 75, 75,107,115,148,192, + 86,252, 23, 44, 88,128, 83,167, 78,209,159,126,250, 9,115,230,204,113,150,202, 32,149, 74, 5, 50,153,140,109,135, 38,178,124, +241,226,197,211, 83, 83, 83,119,186,240,221, 48, 0, 53, 0,194, 1,156,203,201,201,233, 1,224, 51, 0, 1,182,252, 0, 62,137, +141,141,117,120,207, 5, 45,167,229, 27,170,244, 30,147,167, 78,247, 85,192,232, 43, 16,240, 69, 74,157,152, 47, 20,106, 89,158, +143,167,222, 32, 49,106,249,229, 55, 85, 98,158,168, 86,103,210, 27,164, 82,105,139,245,183,205, 17, 0, 66, 72, 55, 0,159, 3, + 40, 5,240,162, 84, 42,253, 23,165,244,198,221,242, 96,237,136,116, 32,128, 77, 0,110, 2, 56, 6,224, 1, 0, 79, 19, 66, 30, +167,148, 86,183,145,126, 22, 33,100,142,189,254,210,187, 25, 98,191, 67, 24, 13,224, 50,128, 8, 0, 21,196,162,212,142, 26, 52, + 19, 39, 78,140, 3,208, 72,252, 23, 44, 88, 32,183,141, 6, 88, 62,147, 79,156, 56, 49,206, 94,119, 64,122,122,122, 28,128, 70, + 98,205,204, 82,192,214,123,127,124,172, 16, 79,126,170, 70,122,122,122,156,189,240,125,123,243, 1,192,241,227,199,229, 98,177, + 24,185,185,185,141,246, 59, 96, 24, 6,111,190,249, 38,177, 54,118,187,119,239,150, 79,156, 56,209,110, 6,116, 58,126, 81, 78, +197, 2, 12,169, 20,202, 43,126,223,138, 21,132,161, 24,242,166,129, 0, 6, 92, 56,114, 61,238,230,246, 41,114,224, 68,171,141, +112,124,175, 8,218, 93, 40,193, 43,207,206,209,135,122, 9,133, 85, 23,114,136, 39,195,199, 11,227, 34,209,197, 79,130,235,185, + 71,137,214, 64,201,130,185,143, 25,226,123, 69,208,126, 30,222, 40,163, 85,100,216,176, 97,205,242, 5, 5, 9,239, 21, 10, 25, +241,177, 99,101, 47,178, 38,221, 71,161, 93,123, 26,253,130, 4, 68,169,188,234,209, 51,194, 35, 40, 32, 64, 84,201, 81,165,254, +199, 19, 21,234,121,227,254,152, 2,220, 52,236,111, 91, 55,157, 53, 2,172,215,216,142, 35,176,119,157,189,237,183,219,147,207, +214, 8,144,201, 20, 0, 20,144, 74,253,209,156,104, 59,138,150,140, 10, 75, 68,166, 77, 81, 15, 91,241,223,189,123,183,156, 97, + 24, 48, 12,131,113,227,198,225,232,209,163,141,242,203, 81,152, 76,166, 60, 30,143,103,148, 74,165,124,153, 76,214,214,241, 44, +146,234,234,234,239, 3, 3, 3,103,166,166,166,110,119,242,187, 90,152,247,139, 81,229,228,228, 12, 2,176,253,224,193,131,125, + 56,142,179,213, 40,240,120,188,135, 0,100,199,198,198,198,219, 35,204, 47,204, 23, 75,132, 98, 95,129, 64, 20,204,240, 73,103, +202, 19,249,113, 60,158,136, 35, 12, 56,194, 55, 82, 30,175,158,199, 17,149,154,103,170,241, 20, 10, 8,175, 87,183, 58,241,212, + 16, 22,197,119, 46, 2,240, 17,128,131, 22,203,230, 89, 0, 31,173, 95,191,126,166,139,130,237, 15,224, 69, 0, 35, 0, 36, 2, +216, 3,224, 36,128,143, 41,165, 10, 23, 40,143, 88,210,181,150, 82,202, 17, 66, 60, 1, 60, 97, 57, 63,176, 13,134,133,175,229, +173, 39, 0,165, 51, 30,118, 11, 17, 20, 33,128, 55, 0, 44,149,201,100, 6,116, 44,140, 0,144, 3,160, 19, 33,100,171, 37, 79, +190,105,106,208,180,100,160,100,102,102,202,109,195,254, 11, 22, 44,104, 56,182,125,191,106,213,170,120,139, 97,208,106,141,207, +204,204,148,219,134,233,153, 89, 10, 92,217, 99,222,133,145, 73,252,166, 65,180,185,239,253,193,204,202,148,219,219,208,167, 57, + 62,107, 99,198,204,146, 82,103,249, 40,165,113,199,142, 29,195,156, 57,115,240,197, 23, 95,224,204,153, 51,113,209,209,209,217, + 77,175, 17,139,197,242,206,157, 59, 59, 18,171,143,235,124,236, 23, 92,158, 19, 7,175, 47, 46,128,148,105,226,104,103, 15, 11, + 31,177, 92,130, 56,129,174,187, 60,160,115,235, 91,217,198,247,138,160,115,255, 57,203, 16,234, 41, 20, 24,175,158, 18,250, 7, +123, 19,121,153, 18, 51,163,186,161, 95,152, 31,132,181,151, 33, 87,105,209, 77, 32,130, 31,225, 9, 22, 63, 61,135,214, 11, 69, +249,241,189, 34, 40,124,252,154,229, 84,212,170, 2, 70,142,244, 90,165,100, 71, 45,242,246,175, 20,233, 24, 79, 78,226,101,208, + 7, 4, 5, 50, 30,126, 98,190,162,166, 76,164,172, 99, 33,168,211, 19,219, 50,211,154, 65,107,233,247,151,219, 19,206,228,228, +228,120,123,227, 1,154,243,252,155, 26, 2,206, 24, 1,214,207, 90, 19, 99,219,243,246,132,177, 41, 31,221,230,127,123,123,147, +162,128,163,124,173,133,251,219, 34,218, 77,141, 10, 0, 8, 8,200,106, 23,241,159, 55,111,158,185,251,141,227,240,234,171,175, +226,163,143, 62,106, 16,255,181,107,215, 58,205,205, 48, 12, 12, 6,195, 89,161, 80,200,182, 67, 36,160, 6, 0,170,171,171,183, + 7, 6, 6,198,167,166,166,202,157,248, 46, 31, 0,158,124,242, 73, 81, 78, 78, 78,102, 86, 86, 86,167, 37, 75,150,176,111,189, +245, 86, 35, 93, 13, 12, 12,196,161, 67,135,226, 0,164,197,198,198, 38,183, 70,200, 35, 2, 31, 3, 75,187,112,156, 49, 66,200, +227,245,160,132,132, 16, 62,159,240,121,188, 58, 66,136, 22,132,167,228, 40,252,169,129,243, 80,154,140,232,229,195,106,153,145, + 42,174,221, 12,128, 38,125,195, 97, 0,186, 81, 74,173,130,255, 62, 33,228,132, 84, 42, 13,163,148,150, 58,227,193, 18, 66, 30, +179,136,245, 7, 0, 22, 1,120,212, 18, 66, 73, 6, 80, 76, 8,121,150, 82,250,141, 19, 34,253, 31, 0, 87, 41,165,107, 8, 33, + 34, 75,133,103, 41,165,159, 17, 66, 38, 17, 66,254, 67, 41,253,127, 46, 22,138,241, 0, 42, 1,220, 11,224,127,206,124,177,185, + 8,128, 84, 42,125, 10,192,219, 0,202,231,206,157,187,174,131, 69, 0, 6, 90,210, 54, 1,192,100, 0,215,237, 25, 52, 45,193, + 86,240,109, 69,191,233,184, 0,135, 43,186,141,248, 3,192,149, 61,143, 53, 50, 2, 92,225,179,109,204,100, 50, 25,177, 53, 2, + 28,193,225,195,135, 97, 48, 24, 16, 19, 19, 19,255,211, 79, 63,201,139,138,138,228,209,209,230, 45,117, 57,142, 67,106,106, 42, +173,175,175,135, 64, 32,192,140, 25, 51,236,222,183, 46,247, 36, 24, 3,139,218,152,240,120,193, 79, 55,229, 87, 55, 28, 70,175, + 55, 38,155, 69,139,163,200, 75, 21,210,154,122,111,104, 5, 94,152, 48,239,138,253,231,200,240,234, 43, 47,228,250,234,244, 38, +198, 87, 34,162, 73, 81,221,225, 35, 17,144,146,234,122,120, 50,124,164, 12,235, 78,143,255, 90,129,159,255,183, 15, 61, 60,189, +232,121,149,242, 58,128,190, 45,209,229,158,237,242,220,232, 97, 85,135,189,248, 17,172,144,189,213,107,252,152, 20, 47,157,193, +115, 10,207,235, 36,163,172,173,241, 40,186,116, 50,194,104,184, 84, 89, 88,160,246,177,212, 25,187, 66,229,168,119,106, 29, 31, +208, 82,255,115, 75,222,180, 61,175, 82, 42,149, 82, 87, 67,166, 29, 9, 77, 61,127,179,120, 3,105,105,237, 55, 72,176, 61, 60, +127, 74, 41, 88,246,119,141, 30, 59,118, 44,142, 30, 61,234,146,248, 91, 96, 20, 8, 4, 38,142,227,142, 49, 12, 99,108,163, 17, + 16, 98,125, 83, 93, 93, 45, 15, 12, 12,148,166,166,166, 58,186,115, 86, 81, 74, 74,138,207,225,195,135, 83,179,178,178, 58,125, +253,245,215,220, 19, 79, 60,193,223,178,101, 11,222,121,231, 29,228,231,231,163, 71,143, 30, 40, 47, 47,199,187,239,190,107,122, +251,237,183,147, 0, 60, 27, 27, 27,251, 89,139,140, 28,235,107, 2,211,131,112, 24,104, 4, 23,233, 33, 16, 9,133,124,166, 76, + 44,224, 41,121, 18, 97,149, 72,196,171,215,155, 56, 15,190,145, 31, 96, 96,245,166,107,103,206, 42, 30, 11,254, 72,115, 28,174, +233,135,189, 8,192, 36, 0, 57, 77, 6,142,229, 0,152,180,126,253,250,175,156, 16,235, 71, 0,188, 4, 32,188, 73,104, 94, 1, +224, 23, 66,200, 39, 0, 14, 16, 66, 76,148,210, 45, 14,240,121, 0, 19, 92,166, 19, 0, 0, 32, 0, 73, 68, 65, 84,152,107,245, +242, 41,165,250, 38,151, 60, 14,224, 87, 66,200, 74, 74,169,198,149,240, 63,128,175, 44,255,157, 50, 0,154, 10,166, 84, 42,253, + 7,128,231, 44,207,114, 21, 33, 68, 47,147,201, 54,116,132, 6,132, 16,210,219, 18,194,250, 17, 64, 6, 0,107, 62,193,209, 8, +192,223, 13,165,165,165,242, 81,163, 70,129, 16,146, 61,106,212, 40,252,240,195, 15,120,232,161,135,226, 58,117,234, 36,103, 24, + 6,139, 23, 47, 38,150,198, 36,110,235,214,173,114,189, 94,143, 17, 35, 70,180,216,208,141,185,118, 83, 94, 62,170, 63, 64, 72, +246,175,161,166,248,129,231, 2,228, 58, 14,241,230, 46, 0, 96,200, 98, 3, 1,170,161,174,174,139, 59,180,181,183, 92,237,125, + 34,254,225, 39,124,154,245,138, 75, 12,236,202,245,235,183,188, 26, 28, 36, 41,170, 83, 27,124,195,253, 61, 5,201, 67,123,122, + 12, 11, 23, 17,157,198, 4,141,150,195, 85,162, 53,101, 20,149,106, 10,202,235, 77,157,132,226,178,114,131,110,226, 13,189,241, + 3,111,224,149,230, 56,125,252,195,186,106,235,175,116, 25,144,112, 31,115,241,120,217,248,210,223,126,184,209,123,248,220, 16, + 94,255,168,146,179, 71,191,175, 35, 60,159, 17, 28,199,213,220,186,165,181,107, 69, 53, 21,108,123,199, 86,111, 54, 45, 45,173, + 69,193,182, 13,175, 55,141, 4, 56,114,253,159, 21, 9, 9, 9,196,214,235,183,133,109, 8,191, 45,104, 15,158,250,250,122, 57, + 0,240,249,124,188,252,242,203, 56,117,234, 20,126,250,233,167,182,210,234, 1,152,244,122, 61, 91, 90, 90,154, 25, 22, 22,102, +180, 23, 89,108, 5, 42,219,131,234,234,106, 89, 96, 96,224,131,169,169,169,142,180,251,190, 58,157,174,207,194,133, 11,167,206, +155, 55,143, 14, 30, 60,152, 0,104, 16,127, 0, 24, 61,122, 52,118,236,216,129,177, 99,199, 50,143, 60,242, 8,205,206,206, 94, +195,227,241,180, 30, 30, 30,208,104,110,151, 38,142,163,186,108,249,193,244,222,189, 35,139, 35,122,132, 95,225,121, 75,202,120, + 68, 88,199,136, 4,117,140,216,163,194,192,231,105, 64,141, 2, 78,108, 12, 81,149, 86, 7,157, 56,116,238,205, 32,255,208,183, + 92,125,144,173, 70, 0,164, 82,233, 68, 0,155,155,120,181,135, 0,204,153, 59,119,238, 87,142,120,176,132, 16,158, 37,252, 61, +173,165,126,121, 74,105, 53, 33, 36, 5, 64, 6, 33,228,123, 7,230, 41, 63, 2,224, 0,165,180,174, 5,190, 58, 66,200, 1,203, +117, 95, 56, 41,138,247, 1, 8, 4, 48, 31,192, 86, 66,200,125,148,210, 67,174, 68, 0, 8, 33, 73, 0,222, 7,208,131, 82,170, + 38,132,140, 6,112, 93, 42,149,170, 40,165,233,142, 70, 0,164,102, 83,223,145, 70,139,200,172,110,128, 99, 24, 3,224, 4,165, +148, 18,179,219,116, 29,128,154, 16,210,205, 58,206,195,153, 8, 64, 83,143,191, 45,222,127, 67, 88, 62,241,155,134, 40, 64,100, + 27,188,255,223,195,252,191,135,111,165, 82,231,188,127,163,209, 72, 79,157, 58, 5,111,111,111,228,229,229, 81,147,201, 4,165, + 82,137, 75,151, 46,201, 3, 3, 3,209, 36,236,151, 61, 96,192,128,248,109,219,182,201, 71,140, 24,209,124,184,207,104,164,221, + 78, 93,128,208, 59, 12,130,188,106, 26,106,242,134, 74,201,192,116,169, 30, 8,108,188, 35,181,103, 32,155,221,125,248,233,248, +125,219,103,201,129,189,205, 54,118, 87,110,220,120, 45,178, 91, 55,160, 74,251, 42, 0,228,107,149,216, 45, 42,173, 28,112,239, +248,224, 1,134, 60,252,114, 93,129,221,231,110,241, 11, 42,235,125, 0,160,220,160,243,191,161, 55, 38, 23,148,150,238,136, 10, + 14,110,214, 0,184,119, 74, 10,227, 33,156, 56,152, 85,255, 82,220,189,127, 66,159,186, 27,219, 13, 87,127,201,172, 53,114, 94, +183, 42,138,127,174, 80,214,120,142, 0,195,144, 26,149,206, 87, 58, 43,186,155,236,251, 51, 55, 90, 42, 51, 50,153,140,216, 70, + 0,108,189,203,166,225,118,171, 72, 39, 39, 39, 35, 33, 33,129, 52,183,208, 73, 91, 70,227,187,186,112, 74, 71,131,181,186, 75, +165,254,183, 69, 4, 92,141, 42,164,165,165,181,139,248,111,222,188,153, 30, 57,114, 4,116,155, 63, 72,138, 2, 31,126,248, 33, + 40,165, 96, 24, 6,235,214,173,115, 57,178,160, 80, 40,244, 1, 1, 1,241, 71,142, 28,217, 59,126,252,248,201,205,149, 31, 39, +224,103,169,175,115,171,171,171,215, 7, 6, 6, 62, 6,160,102,241,226,197,255, 72, 77, 77,181,231,168,213,237,218,181,171,116, +223,190,125, 95,197,199,199, 63,213,175, 95, 63, 36, 36, 36,208,172,172,172,134,116,100,100,100, 64, 36, 18,225,250,245,235,216, +187,119, 47,233,210,165, 11, 27, 27, 27,251,211,165, 75,151,154, 37,140,140,232, 83,166,213,234,230, 30, 57,114,100,125, 96, 80, +160,210,215,199,167, 24, 66,161,158,213, 51,245, 44, 79, 95,171,227, 43,171, 60,245,158,226,155, 21,149,190,135,246,237, 93, 63, + 96,224,160,247, 13, 58, 77,125,187, 24, 0, 82,169,148, 72,165, 82,107,226, 59, 89, 94,135, 45,211,236, 26,162,160, 0, 22, 16, + 66,186,192, 60,194, 17, 0,154,181,208, 45,162,242, 2,204, 3,244,174, 53,225,105,138,107,150,235, 94, 32,132,124,212, 10, 31, + 1, 48, 3,192,114, 59,124, 95, 3, 88, 68, 8,249,202, 78,250,108, 11, 77, 56,204,227, 29, 98, 96,238,251,127, 19,192,105, 66, + 72, 47, 0, 69,182, 54,134, 3,124, 15, 3,120,218, 34,178, 90, 75, 90,181,150,227,117,132, 16, 33,128,239, 90,227,179,228,197, + 99, 0,230, 57,106, 0, 72,165,210,181, 0,190,105,137,207,194,185, 18,128, 55, 0, 95, 0,187, 44,105, 19,195, 60, 79,252, 23, + 0,163, 8, 33,243, 1,252, 4, 96,119, 75,233, 3,204,243,232, 91,232,235, 71,211,177, 1, 19, 38, 76,176,107, 12, 76,152, 48, + 33,158,153,245,123,191,189,213, 8,176,190,183, 13,231,187,204, 55,235,246, 41,129,142,240,157, 59,119, 14,221,187,119,199,203, + 47,191,220, 80,102, 54,109,218, 68,115,115,115, 49,101,202,148,219,174,247,240,240,144,139,197,226, 22,249,194,207,157, 67,109, +247,206, 56,254,242, 83, 13,124,151, 95,219, 17, 23,145, 91, 39,103,166,136,111, 75, 75,113,190, 1, 34,113,235,179,159,174,150, +148, 44, 68,215,174, 63, 3, 24, 77, 65,121,184, 86,249,178,134,101,193,234,204, 65,178,139,149,149,184,166, 51,108,226, 19,162, + 2, 33,198,171, 37, 37,233, 0,208,210, 32,192, 46,225,253, 22, 2, 88,145,127,244,197, 34,113,232, 12, 69,105,185,184,107,121, +201, 73, 49, 4, 1,189,139,174,155,194,170,203,111, 64, 40, 20,132, 12, 12,245,124,164, 86,101,252, 22,192, 13,123,158, 43,128, +184,166,211,255, 90,240, 64,227, 93, 89, 19,160,185,254,255,191, 3,218, 58, 85,207,250,253,180,180, 52,218, 86,190, 45, 91, 54, +211,236,236,108,144,116,179, 97,124,224, 45,111, 76, 92,162,194,248,241,227,225,204,180,191,230, 16, 16, 16, 16, 15, 0,247,220, +115,143,166, 29,186, 41, 20,129,129,129,115, 0, 88,157, 83,125,106,106,234,110, 7,191,203, 2,168,200,200,200,144, 63,244,208, + 67,195, 83, 83, 83,135,152, 76, 38, 34,145, 72, 48, 97,194, 4,236,223,191, 31, 28,199, 33, 49, 49,145,190,248,226,139, 36, 42, + 42, 74, 63, 99,198,140, 30, 53, 53, 53,183,116, 58, 93, 75,138,204,254,122,233,202,166, 65,131,135,248,158, 60,113,226,253,179, +124,254,160,158, 61,122,126,233, 19, 24, 92, 34, 8, 22,211,195,123, 15,249,215, 40,170,199,133, 5, 4,191,221,167, 79,159,195, + 94,161,158,107,251,119,141, 49,228,229,229,181, 75, 4,128, 7,243,116,191, 88, 0,239, 1,120,222, 34, 60,158,182,245, 9,230, + 65, 98, 87, 1,252,219,210, 37,112,170, 5,126, 6,230, 65,102, 7, 0,120, 56,144,158, 99, 0, 38,162,229,133, 21, 24, 0,193, + 0,122, 0, 56,109,135,243,180,229,186, 16,180,220, 55,201,192,188,140,163,191,165,219,224, 33,139,112,231, 91,184,243, 45,199, + 91, 0,252, 0,243,140, 3, 5, 0,131, 29,190, 89,150,200, 67, 63,139,145,100,155,206, 50, 0, 82, 0,191, 89,174,253,222, 14, +223, 75, 48,207,110,112,164, 43,195, 3,192, 62, 0,155,237,228,199, 76, 0,255,181,252, 63,107,147, 62,129, 37, 47,211, 0,124, + 10, 96,137,229,243,178,150,126,240,192,129, 3,217,132, 16, 20, 23, 23,203,173, 51, 1,154,122,253,197,197,197,114,235,181,246, +110, 32, 41, 41, 41, 59, 51, 51, 19,155,126, 50, 52,140,220,111,234,165,111,250,201,208,112,237,221,228,203,205,205,197,184,113, +141,135,186,135,135,135,199,111,219,182, 77,222,179,103,207,120,142,227,228, 75,151, 46,165,214,105,128,132, 16, 12, 31, 62,188, + 69,163,162,111,110, 46,190, 11, 12,137,247,177, 57,215,127,254, 68,168,223,191, 1,220, 31, 2,202, 1,121, 75, 5,180,158,243, + 66,141,214, 7, 10, 50, 12, 67,199,237,138,111,173,216, 91,102,112,108, 7,176,189,119,143,176,190, 0, 94,214,155, 56,164,231, + 21, 97, 92,168,185,187,147, 80,170, 82,177,236,123,183,110,221,186,229, 64,153,122, 31,128,103,254,111, 53,143,214,158,222, 22, + 84, 81, 86,131,138, 91, 42,240,249,213,158,245, 10,138, 90,165,137,134, 4, 11,253,248, 28,166,107,245,166,239,150,188, 28,235, + 23,210,255,137, 90, 59, 66,147,109, 79, 92,218,220,135,157,176,205,252, 63, 43,197, 73, 15,248,206,206, 2, 32, 41, 10,180,133, +175, 37,143, 61, 38, 38,166,195, 24, 34, 13,131, 29,173,226,159,199, 98,131,220, 92,199,218, 42,254,214,178,241,236,179,207, 6, +243,249,252,138, 99,199,142,125,121,207, 61,247,180,101,138, 98,247,212,212,212, 53,150, 40,192, 44,203,140,128, 89,169,169,169, +223, 59, 18, 84, 4, 80, 15,160, 42, 60, 60,124,232,216,177, 99, 75,207,229,229,117,214,106,181, 68, 46, 63, 4,145, 88, 4,134, + 48, 56,116,232, 16, 25, 48, 96,128, 38, 57, 57,121, 84,101,101,165,221, 58, 55,123,214, 76,246,199,189, 63,126, 58,116,232,176, +158, 6, 86, 63,249,106,254,149,167,185,162,130,167, 0, 64, 12,134, 14,238,221,247,100, 72, 72,112, 54,143, 47,124,237,191,111, + 45,175,255,118,163,235, 61,202,205, 25, 0, 47, 91,172,161, 41, 0, 46, 1,240,106,230,123,123, 44, 30,123, 18,128,145, 22,241, +108, 54,202, 9, 32, 18,192, 86, 7, 13,128,106,203,245,188, 86,248,226, 0, 92,113,144,239,138,229,250, 29,173,240,205, 5,240, + 36,128, 11, 48,207, 80,184,214,132, 91,110,241,254,159,179,120,195, 27,129, 22, 71, 92,240, 44, 30,251,227, 0,162, 44, 81,132, +230,210,169,180,124,190,206, 98, 4,108,108,133,239,107,139,209,229,200,253, 82,203,245,173, 61,191, 15, 44,145,141, 3, 22,163, + 6, 77,184,247, 3, 24, 96,201,139,124,139, 33,213,173,213, 31, 53,247, 32, 80, 0,242,230, 22, 2,178, 94,227, 76, 5,127, 82, + 42,165, 79,126,170,110,102,225, 30,133,211, 2,209, 94,124, 47,188,240,194,109,215,140, 31, 63, 62,123,252,248,241, 4, 0,238, +187,239, 62,167, 26,161, 61, 47,188, 64,124,154,182, 40, 61,188,178, 37,171,251, 19, 0, 24, 40, 19, 16,115, 80,198, 58, 50,251, +186,131,197,192,146, 47, 38, 90, 4, 62,192,171, 71,131,248, 91, 92,228, 91, 98,177,216,209,217, 40, 4,192, 59, 71,179,206,122, +132,118,237,241, 32, 7,143,200,146,226,114,158, 81, 87, 75, 59,133,120, 17, 47, 79, 1, 97,141, 28, 20,181, 6,150, 72,136,164, + 78,197,246, 14,105,217, 33,104, 86, 44,154,190,255, 35,151,239,189,211,179, 0,218,202,215,146,199,222,179,103,207, 14, 35,254, +220,247,254, 56,144,103, 30,147,183, 81,110,192,119,199, 12,160,148,182, 75,190, 90, 57, 76, 38, 83, 53, 0, 68, 71, 71,183,105, + 65, 32,171,248, 91, 80,101,249,239,104,221, 16, 90, 28,179, 51, 0, 48,112,224,192, 48,149, 82,181,104, 68,204,240,199, 84, 74, +165, 47,107, 98,141,161,161,161,183,194,194,194,174, 40,149,202, 37,149,149,149,249,142,166,107,202,228, 41, 44,128,231,143, 30, + 57, 49, 54,118,236,216, 41, 18,137, 36,136,128,154, 8, 33,224, 56, 90,173, 85, 43,214, 92,206, 43, 46,251,118,227,134, 54,173, + 8,216,212, 0, 48, 1,248, 71, 43, 2, 98,139,147,150,151,201,242,106, 14, 38,152, 71,212,243, 28, 76,143, 28, 64,150, 29,190, + 12,152, 7,173, 57,130, 71, 29, 72,223,122, 0, 95,218,225,249, 21,230, 41,144,112,128,239, 27, 75,196,192, 30,138, 44,158,189, + 35,233,227, 57,145,167,235,237,240,221,239, 0,159, 53,218,176,209,242,108,236,206,181,165,148,146,137, 19, 39,198, 89, 5,223, + 54, 4,239,202, 82,192, 50,153,140,164,167,167,199, 49,179,218,103,233,222,246,230,251, 51,160,160,228,166, 62,178, 91,183,141, +243,222, 95,247,164,245,156, 65,192,108,214,105,184,125,229,197,197, 42,135, 10,211,250,245,180,234,244, 6,178,252,251, 95, 22, +238, 94,125,223,206,227, 39,202,158, 9,246,229,166, 50, 1, 62,126,148, 2,132, 80,189,158,229,202, 57,160,202,160,231,252, 74, +203,180,134, 72, 39,210,152,156,156, 28,111,219, 29,144,156,156, 28,223, 81,158, 95, 71, 92, 9,240,207,130, 73, 75, 84,119,244, + 30,101, 50, 25, 39,149, 74, 59,139,197,226,178,232,232,232,251,219,131, 51, 53, 53,245, 96, 96, 96,224,147,169,169,169, 27,157, + 48, 0, 88, 75,228, 20, 0, 48,122,204,232,229, 0,150, 55,189,176,233, 24, 33, 71, 49,110,252,200,159, 96,238,138,109,130, 48, +244,238, 51,168,205,247,220,156, 1,160,115,129,135,182, 18, 34,209,187,249,254,178,124,141, 96, 17,250,118,171,232, 73, 73, 73, +217,246,230,229,255,145,124,127, 6,212,104, 52, 79, 1, 30, 70, 0,193, 28,104,169, 78,103,216, 82, 94, 94,121,158, 82,234,240, +180,169,160,152,127,208,140, 15, 39,147, 91,158, 15,231,118, 29,139,220,172,175, 62,120, 57, 32, 64,180,136,207, 35,180,172, 90, +119,185,204,192,110,146, 8, 24,177,132,207,227, 25, 89, 78,236, 76,250,172,125,252,214,129,103,174,238, 3,112,219,212, 63,155, +208,191, 43,139,205, 52,245,204, 29, 57,127,183,249,238,182,225,227, 40,152, 89, 10, 16, 66, 48,117,218,239, 3,162,247,236, 61, +211,208,134, 36, 78,142,110,175, 41,138,229,237,217,222, 88,140,128,141, 78, 92,238,111, 49, 0,212,127,214,246,129,223,228,129, + 82, 71, 27,251,166,104,110, 20,187,155,239,175,205,231, 70,199, 71,117,117, 53,133,185,155,171, 77,184,229, 57,157, 2,192,209, +205, 31,147,132,167, 94,249,240,241,185,121,159, 62, 63,251,216, 0,131,154, 68, 4, 8,248, 65, 32, 68,227, 37,225, 87, 14,234, +231,147,239, 44,119, 66, 66, 2, 73, 75, 75,115,121,189,249, 59, 37,158,127,150, 8, 64,199, 51, 30,204,177,161,191, 65,245, 10, +179, 56,204,222,248,147,238, 6, 72,162,162,162,254, 30, 67,100,221,112,195, 13,240,121,128,135,136,128,227,204,109,116,189,214, + 93,253,221,112,227,111,219, 30,184, 31,129, 27,110,252,125,192,154, 0,165,198, 42,250,110,241,119,195,141,191, 51, 24,247, 35, +112,195, 13, 55,220,112,195, 13,183, 1,224,134, 27,110,184,225,134, 27,110,184, 13, 0, 55,220,112,195, 13, 55,220,112,227,175, +136, 70, 99, 0,230,205,155,231,242,200,205,230,214,214,110,142,239,127,223,127, 30, 55,104, 72,111,121,231,174, 97,241, 42,173, + 90,126, 88,158, 27,159, 52,235,217,108, 87,249, 86,127,181, 61, 46,106,200, 40,249,173,210, 82,120, 74, 60,113,163,164, 32,254, + 95, 79, 77,115,153,175,189,239,247,194,225,121,113,163, 71,245,148, 75, 60,121,224,243, 24, 16, 49, 65,153,242, 69,226, 42,223, +153, 91, 67,226, 70,140, 26, 33,247,245,226, 1,124,160,230,220,122,226,104,250, 34, 39, 69,186,124,191, 87,246, 95,185,141,111, +228,200,145, 46,243,157, 56,113,226,118,190, 72,215,211,119,226,202,237,233, 27,213,167,143,203,124,199,243,243,255,116,124,147, + 90,201,223,229,203,211,232,162, 69,201, 45,126,190,191,153,252,141,124, 96,146,235,229,101,223,254,219,203,243, 36,215,203,203, +242,204,106,234,195, 21, 52, 58, 23, 20,249,176,203,124, 85, 87,190,187, 45,125,103,223,184,238,114, 67, 58,108,105,143,219,206, +125, 24, 84,234, 50,223,203, 85, 97,248, 35,218,171,191, 59,159, 84, 42,229, 55,183,179,160, 35,124,251,247,239, 7, 0, 40, 20, +138, 8,157, 78,167,120,242,201, 39,107,255,200,251,117,218, 0,104, 9,186,173,210, 72, 0, 61, 97, 94, 39,160, 64, 60, 91,118, +205,209, 31,216,254,205,242, 56, 2, 14,193,126, 1,200, 61,124, 70,254,245,215, 31, 35, 54, 33, 22,172, 90, 35, 31,208,111, 60, + 56, 14,242, 95, 35,190,142, 31, 54,108, 8,174, 94,189,142,186, 90, 53, 6,143,153,147,221, 18,223,250,111,229,113, 20, 4, 61, +122,247,148, 75, 95, 89,130,234, 79,182,227,155,207, 63, 3, 32,198,158,243, 37, 96, 24,200, 63,126,231, 45,228,231, 95, 70,120, +120, 15,136, 36,124,220, 44,201,111,113,113,145,194, 29,159, 81,161, 80, 8,137, 68,130,130,130, 2,116, 9,241, 65, 16,223, 11, + 93,186,251,193, 95,226, 11, 79, 98, 2,195, 48,160,156, 9, 26, 17, 31,117,183,234, 80, 49,220,254, 92,242,186,130, 53,212, 91, + 82,135, 49, 35,122,193,203,147, 15,161,132, 1,159, 7, 48, 66, 62,250,134,125, 78,141,148,135,194,155, 79, 57,156,225,171,247, +234,226,194,194,194, 16,123, 79, 87,185, 86,167, 7, 35,146, 0, 70, 32,175, 62, 58, 78,171, 81, 99, 84,200,229,236, 63,202,138, + 92,191,126, 61,157, 59,119,238,223,106,126,125, 71,133, 61,161,111,227,245,158, 0, 70,116,146,120,252,183,180,180,180,159, 64, + 44, 2,231,225,177, 12,230,149, 49,235, 59,202, 51, 40,248,117,111,220,181,139,135,111,219,107, 32, 33,121,217, 95,165,140,146, +111, 54,109,250, 77, 36, 20, 74, 56,142,243,245,244,242,242,122,112,234, 84, 15,152, 87,176,235,168, 35, 59,173,209,102,174,173, + 68, 82,169,212,199,215,215,119, 65,223,190,125,103,136, 68,162,174, 37, 37, 37, 37,165,165,165, 39, 12, 6,195, 82,153, 76, 86, +224, 2,159,159,191,191,255,146,251,238,187,111,242,179,207, 62, 27,254,197, 23, 95,220,186,112,225,194, 49,157, 78,247,174, 76, + 38,187,224, 8,199,254,253,251,241,227,200, 29, 24,179,247,222, 21,225,225,225,175,121,122,122, 98,251,246,237,167,103,206,156, + 57,252, 79, 19, 1,104, 65,252,121,158, 34,254,136,199,198,246, 90,201, 81,170, 59,122,249,214, 39,151,182, 74, 15,136,103,203, + 46,218,251,110,242,212,222,116,234,125,203, 97,172,175, 5,223,196,224,151,139,151,241,196, 19, 47,254, 94, 34, 24,224,231,220, +141, 8,234, 30, 38,231,234,149, 48,112, 4,135, 14,229,198,151,104, 91,202,168,165, 20, 66, 95, 16, 15, 31,156,185, 88,140,243, + 23,255,129,175,190,219,223,240, 57,199, 1, 15,140, 25, 3,212,151, 3,240, 70,193,133, 75, 16, 4,249, 33,118,244, 32,121,173, +166, 21,155,133, 48, 0, 97, 16, 53, 36, 26,157, 60,133,232, 18, 36,134, 79, 96, 0,252, 69,222,240, 23,243, 32,224,241, 96, 52, +153, 80,203,114, 56, 89,117,218,238, 67, 45, 63,191,132, 6,248, 2, 62, 30, 30, 8, 14, 10,132,143,143, 7, 40, 99, 2,203,213, +195, 4, 19,188,188, 60, 16,212,169, 43,122, 70,254, 68,179, 14,143,109,181, 81, 90,151,105,160,190,222,158,232, 25, 17,130,224, +160, 64,168,213,106, 8, 69, 98, 8,116,230,197,249, 34,194,123,200,107, 20,181,248, 62,183, 40,190,184,228, 38, 20,229,215,177, +244,217,232, 86,141,129,180,229,105, 14, 55, 18, 9, 79, 38,196,251,135,250,103,183, 38,254,119,195, 8,120,227,253,247, 41, 0, + 44,125,237,181,118,249,141,197, 43, 86, 80, 0, 72, 93,184,208,101,190, 31,115,114,158, 48, 24, 12, 27, 1, 96, 70,124, 60,227, + 74,227, 43,219,182,205,188, 70,188,205,180,105, 74, 41, 8, 33, 13,255,173,231,172,215,205, 77,110, 89,176, 23, 45, 74, 38,142, +138,186,147,226, 63,192,211,200,110,247,246,243,237, 7, 0, 66,137, 24, 6,173, 14,156, 90,179,226,216,145,195,239,220, 59,115, +102,127, 0,197,246, 72,244, 60, 33,133,121,241, 20,214, 34, 10,156,165, 29,106,182, 45, 26,122,239,100,252,118, 40,195,169, 60, +186,118,241,176,188,247,160,184,248,240,254, 15, 56,111, 20, 39,215, 56,117,121, 74, 74, 10,182, 37,103,181,122, 77,124, 86,227, +173, 72, 6,248,153,111,181, 66,199, 65,203,154,243, 85,109,249, 47, 27,229,135, 62,222,130, 86,249, 86,174, 92,153,253,198, 75, +175,134, 76,155, 49,221, 75,167,211,226,227, 15, 63, 96, 86,175, 94,173,155, 63,127,126, 24,128,155,237, 93,247,246,237,219,151, +176,115,231,206, 76,192,185, 53, 7,114,115,115,105, 81, 81, 17,170,171,171,161, 82,169,224,237,237,141,192,192, 64,132,135,135, + 99,204,152, 49, 46,213, 59,169, 84, 58, 62, 58, 58,122,211, 43,175,188,114,181,111,223,190, 27,135, 13, 27,118,233,214,173, 91, + 93,115,115,115,163,159,122,234,169,221, 82,169,116,133, 76, 38,251,202, 9,190,248, 25, 51,102,164, 45, 95,190, 60,208,104, 52, + 66, 34,145,192,211,211,179,179, 90,173,158, 57,109,218,180, 7,165, 82,233,124,153, 76,246,121,107, 28,207, 43,164,192, 72, 96, +202,137, 25,240,236,238,217,101,209,162, 69, 56,117,234, 20, 85,169, 84,126, 54,191, 3, 0,188,153, 51,103,154, 38, 78,156,120, + 87,196,253,220,185,115,141,142,155,219,208,141,223,130,232,119, 3,208, 11,230, 37, 99, 77,106, 61,123, 35,247, 74,197, 71, 99, + 34, 67, 94,188,111, 64,231,119, 58,249, 74,186,200,183, 74,183, 2,184, 44,158, 45,107,113,147, 26,125,125, 13, 58,245,190, 31, + 75, 94,155,129,141,178,223,235,226,225, 99,235,160,214,232,145,152,240, 34,238,137,125, 18, 15,167,220, 7,137, 68, 4,131,137, +133, 74, 99,144,247, 25,221,187,133,194,113, 29, 48, 0, 51,230,172,197,191, 94,121,166,225,236, 3,247,196, 65, 44, 22,225,135, + 67,251,177, 39, 39, 23,155, 54,124, 6,157, 86, 15, 33,143, 15, 47, 15, 33,212,213, 37,241,181, 37,104,118,247, 49, 74, 41, 64, + 57,243,139,225, 64, 41,133,222, 32, 50, 55, 79, 34,128, 26, 76, 48,241, 0, 19, 76, 48, 25, 56,176,166,214, 13,216,130, 19,169, +180,107, 48,133,143,183, 39,194,186, 70,160,223,224,222,240,246,146,160,174,190, 18,229,149,229, 80,212,221,130, 81, 71,224,225, +225,129,224,224, 88,204,156,126,129,110,223,217,183,249, 48,254,230, 27,212,228,237, 13, 45, 31, 16,138,133,208,106,132, 48,104, +132,208,137, 69,224, 19, 22, 20, 60,232,180,245,208,106, 84,232,218,181,139, 92,200,227,163, 6, 74,124,244,209, 17,136, 68,173, + 23,142,247, 55,189,111,183, 0,189,246,248,107,173,126,174, 80, 40,104,147,227,152,128,128,128,124, 66,136,142, 82,202,247,247, +247,247, 40, 40, 40, 8, 76, 75, 75,203,158, 59,119,110, 23, 87, 11,178, 48, 52,116,118,195,111, 0,113,254, 64,187, 69, 59,214, +167,165,209,231,158,123, 46,222, 88, 81,225, 20,231,143, 57, 57,210,145, 35, 71, 46, 29, 27, 21, 5,163, 72,132, 85,171, 86,113, + 51,239,187,111, 2,165, 52,203, 41, 87,142, 16,172,124,231,157,134,227, 5,111,191,141, 85,239,190,219,234,177, 61, 52, 53, 2, +150, 47, 79,163, 49, 49, 49,200,202, 42,164, 9, 9, 61, 7, 2, 40, 92,190, 60, 77,235,164,248,231, 14, 30, 56,208,199, 90,103, + 60,197, 18,148, 85, 86, 64,169,168, 69,244,200, 81, 30, 63,126,181, 33,107,202, 83,255, 24, 8,243,230, 5,173,129,125, 97,233, +106,254,163, 51, 31,228, 71,134,135,115, 86,207,240,237, 85,159, 54,186,232,221, 5,207,155, 13,191,151,230,199, 63, 62,117,130, +211,249,234,146,248, 55, 88,200, 1, 78, 92,156,224, 20,181, 39,159,224,252,187, 79,131,248, 4,193, 84,120, 30,250,194, 95,145, + 95,163,198,240,189, 21, 14,125,127,157, 76,118,244, 21,233,115, 61, 30,255,231, 83,126,105,155,191,227,194,195,195,153, 37,203, + 87,192,251,157, 37,248,225,135, 31, 74, 31,122,232, 33,151, 12,209, 22,132,127,194,206,157, 59, 15, 88,143,167, 79,159,238,144, +114,169, 84,170,184, 3, 7, 14,200,141, 70, 35,122,245,234,133,113,227,198,193,215,215, 23,181,181,181,184,121,243, 38,174, 93, +187,134,155, 55,111,210,137, 19, 39,198,123,123,123, 59,156, 79, 82,169,116,250,125,247,221,247,241,202,149, 43,183, 14, 27, 54, +236, 99,171,177,211,165, 75, 23,204,156, 57,147, 36, 37, 37,121, 1,200,149, 74,165,185, 45,237, 94,218,148,111,254,252,249,233, +207, 61,247, 28,115,250,244,105, 16, 66, 16, 24, 24,216,240,218,187,119,175,112,244,232,209,159, 73,165,210,227, 45,241, 61,175, +144, 98,202,137, 25, 0, 64,182,167,236,160,247,126, 54,190,123,126,126, 62, 10, 11, 11, 73, 93, 93, 93, 47,169, 84,202,159, 54, +109,154, 9, 0,157, 54,109,154,137,101, 89,220, 13, 52, 21,127,235,185,166,247,193,111, 70,252, 3,135, 71, 4, 62, 30,213, 35, + 96, 14, 33, 68, 64, 41, 53,114,230,151,193,100,212,105,133, 12,215,101,112, 39,241,107, 65, 62,189,122,239, 60,121,237, 59,221, + 86,233, 81,241,108, 89, 89, 43,205, 55, 6,244,239, 11,134,201, 70,126,109, 53,128, 75,168, 43,189, 2,129, 88,132,140,221,159, + 64, 83,101,194,156,127,188, 12,142, 3,166, 62, 56, 6, 38,190,151,221,155,203,207,191, 4,142, 3, 18,135, 18, 0, 93, 0,244, +128, 78,111, 64,210, 3, 19, 33,246, 99,176,105,203, 62, 48, 12,144,254,221, 70,148, 22,254, 26,255, 80, 92,100,246,229,179,205, +115,113, 20,224, 56, 14, 28,199,193,100, 50, 65, 47,160, 48, 18, 35, 12, 6, 3, 52, 30, 58,128, 19,131,161, 38,152,132, 20,245, + 6, 29,212,202,186, 86,211, 22,236,165, 7,159, 47, 65, 96, 96, 32,122,247,238,141,208, 78,163, 0, 30, 3,147,233, 52, 24, 90, + 11,157,154,133,137, 83,163,252,102, 13,130, 3,171, 16,232, 23, 11,133,106,113, 92,115,155,188, 72,116, 44,168,190, 10,208,137, + 96, 96,140, 80, 11,249,168,151, 8,192, 23, 8, 1,206, 19,132, 71, 80,175,214, 64, 81,126, 29, 5,167,115, 80, 83, 92, 12,142, +227,192, 80,158, 75,133,230,171,181,191, 27,206, 79,205,123,202,126, 59,105,217,215,221, 90,116,210,210,210, 22,189,242,202, 43, +207, 20, 23, 23, 51,132,144, 96,153, 76,246, 29,204,155, 59,121,180,161, 44, 11,214,172, 89,179,229,214,173, 91, 72, 79, 79,199, +240,190,125,121,254,131, 7,183,185,130,164, 46, 92, 72, 20, 64, 28,165, 84,190,122,245,106, 57, 0, 72, 83, 82, 28,246, 74, 12, + 6,195,186,177,150,202, 36, 20, 10,209,167, 79, 31,108, 63,116, 40,211, 18, 13,112,152,231, 78,109, 85,187,104, 81, 50,201,202, + 42,164,167, 79,155, 35, 86, 54,255,127,189,247,222,123, 75, 23, 45, 74,246,117, 84,179, 60,141,236,246,193, 3, 7,250,240, 24, + 6,207, 62, 58, 7, 90,157, 30,171,190,252, 18, 30, 18, 9,116, 58, 29,116, 90, 45,134, 14,139,138,220,191,121,243,115,147,230, +204,249,200, 94,212,241,221, 5,207,115, 0,152, 43, 69, 69, 76, 83,193,111, 90, 61, 93,185,247,110,253,198,199,103,165,189, 78, + 39, 76,125, 58,158,138, 34, 93, 50, 4,108,119,237,163,219,252,237,158,183,107, 65,249,241,113,189,222,132,195, 19,130, 33,120, + 81, 6,229,156, 8,240,253, 67,156, 18,255,131, 7, 15,150,135,119,238,114,243,159,207, 62,211,237,245,151, 23, 98,245,134,117, + 23, 71, 70, 71,247, 92,247,233, 58,143,151, 22,190,138,205, 99, 70, 97,203,150, 45,143, 61,242,200, 35,155,218, 40,252,113, 59, +119,238,108,112,152, 44, 97,245, 23, 96,222, 42,221, 46, 14, 28, 56, 32, 15, 14, 14,198,176, 97,195, 88,134, 97,248,230,232, 44, + 7,129, 64,128,128,128, 0,116,234,212, 9,215,174, 93,195,129, 3, 7,228, 51,103,206,116,168,174, 72,165,210,228, 41, 83,166, +124,176,114,229,202, 79,251,246,237,187,150, 16,194, 1,248, 12,192, 36, 0, 71, 0,188, 75, 41, 45, 34,132,188, 10,224, 93, 71, +248, 86,206,159,255,253,216,228,100,178,107,215, 46,240,249,124,200,229,114,156, 63,127, 30,189,123,247,198,123,239,189,135, 65, +131, 6,225,153,103,158,225,191,249,230,155, 43, 91,244,252, 45,216,158,178,131, 2,128,135,135, 71,153,159,159, 31,196, 98, 49, +132, 66, 97,189,112, 25, 88,122,140,146,105,211,166, 97,217,178,101, 56,127,254, 60,182,110,221,122, 87,196,127,238,162,101,191, + 59, 58,203, 95,111,214, 8,104, 46, 2,192,240,121, 12,159,229,168,138,229, 76, 58,137,128,223,213, 75,200,244, 7,199, 2,145, +247, 2,157,122, 3,183,174,160,243,229,156,233,143,197, 70,132,103,156, 43, 19,215,108,149,102,152, 55,183,107,190, 14,243,120, + 86, 65,242, 1,208, 21,190, 97,125,113,253,114, 58,214,202, 54,128,209,123, 96, 98,124, 44,246, 29,204,129, 70, 3,120, 4,180, +220, 46, 73, 60,250, 66,171,185, 12,147,201,118,111,154,114, 0, 55,193,240,226,240,248, 19, 79,131, 19,169,241,227,238,175, 48, +245,193,167,224,225, 9,168,235,203, 44, 26,212, 60,140,224, 65, 96, 17,127, 35,107,130, 94,105,132,198,168, 65,173,132, 15,163, + 70, 0, 61,223, 8,158,145,128, 53,113, 80,106, 89,212,212,179, 45,170,217,121,249,114,218,179, 19, 1,143, 71, 64, 24, 17, 76, + 38, 10, 86, 83, 12,189,201,136,210,242, 58,212, 40,234, 81,167, 50,129,209,233,192,162, 28, 60,193, 57,116,233,174,196,168,232, + 24,249,119,223, 94,106,150,147, 7,128,170,116,208,170,110,194,116,171, 14,188, 94, 93,193, 48, 12, 76,172, 30,181,229, 69,184, +124, 34, 23,149,215,139, 45, 66,194, 7,195, 7,192,187, 59,221,128,214,144,255,250,245,235,245, 73, 73, 73,253,163,162,162, 88, +145, 72,164,254,224,131, 15, 70,194,188, 41, 81, 31,180,113,166,137, 48, 52,116, 1, 0,140, 30, 52, 8,161,161,161, 21,171, 87, +175,206, 2, 16, 63,108,240,224, 54, 71, 1,252,129,108,105, 74, 10, 17,132,132,196,173, 94,189, 90, 46, 8, 9,137,115, 38, 18, + 96, 20,137, 32,208,235,177,125,251,118,132,132,132, 96,198,196,137,214,104, 0,117,198, 8,184, 83,176,138,190, 76, 38,179,109, +248,112,248,240,225,176,209,163,147, 31, 68,203,219, 70,219, 98,132,159,191,127, 63, 30,195,224, 31, 73, 73,168,173, 83,162,178, +166, 26, 2, 1, 31,124,190,249, 37, 16, 8, 32,146,120,160, 87,120,248,135, 87, 79,157, 62,223,123,120,140,220, 30,233,149,162, + 34,124,187,253,127,183,121,252,214, 72,192,168,232, 33, 72,140,191,215,201, 59, 86,197, 1,222,217,125, 7, 39,102,247,237, 19, + 25,159,185,235, 75, 57,208, 49,250,254,243,190,254, 8,250,125, 27, 16,242,249, 25, 12,240,227,131,231, 19, 0, 86, 81,129,225, +123, 43,224,201, 39, 80,179, 20, 60, 59, 53,229,218,213,171,213,123,118,237,238,251,245,231, 95,227,147, 47, 63,187,190,238,131, +143,222, 14, 8, 12,168, 93,178,116,201,193, 77, 91, 54, 99,220,232, 88,124,155,182,245,235,110, 61,186,125, 61, 46,118,156, 75, +247,220, 84,252,119,237,218,133,174, 93,187,246, 58,121,242,228, 28,152,183, 26,183, 27,246, 55, 26,141,136,142,142,230, 88,150, +229,171, 84, 42,136,197, 98,112, 28,135,223,126,251, 13,249,249,249,240,242,242, 66, 76, 76, 12,202,203,203,145,155,155, 75,237, +117, 7, 72,165,210,217, 41, 41, 41, 43, 31,120,224, 1,175,181,107,215,250,124,252,241,199, 66,152,119, 45,205, 4, 16, 13,243, + 6,103, 31,193,188,157,251, 65,152,119, 60,109,149,111,231, 43,175,108, 30,208,191, 63, 89,157,148, 4,114,255,253,216,126,244, + 40, 87, 90, 90,186, 4,192,234, 27, 55,110, 76, 91,180,104,209,231, 63,252,240, 3, 98, 99, 99,225,233,233, 57,166, 37,174, 41, + 39,102, 96,199,142, 29, 88, 63,201, 92,199,252,252,228, 85,157, 58,117,130,151,151, 23,245,244,244,188, 97,120, 29, 32,211, 8, + 93,182,108, 25,172,134, 70, 99,253,186, 59,152,187,104, 89,131, 17,208, 72,236,155,158, 16,207,150, 85,254,124,181,114,221,198, + 35, 87, 95,254,173,180,238, 0, 3,202, 7, 40, 48,229, 61,252, 28,243, 1,254,171, 72,194,161,129, 43,128, 73,139,225, 45,224, +134, 61, 16, 21, 62,199,210, 93,112, 27,118, 29,170, 33,128, 18,211,158,120, 17, 28, 7, 0, 53, 48, 47,155,108, 68,143,190,209, + 16,139,248, 48,177,122, 80,131, 57, 44,226,237,237,141,234, 26, 69,139, 55,241,209,135,175, 16, 0,184,248,243,151, 96,152,198, + 78, 2,167,253, 21, 58,189, 17, 60,129, 24, 68,104,238, 67, 83, 41,149, 24, 51,102, 76,235,238, 8,103, 0,199,113, 96, 89, 22, +122,189, 30,245, 28,139, 58,131, 17,202, 50, 37,234,110,214, 65, 89, 94,131, 26,101, 45,202,117, 26, 40,213,181,168,213,183, 60, +214,201,219, 75, 13,150,229,160, 55,152, 80, 91,167, 68,254,213, 98,156, 56,157,135,159, 79,228,225,210,111, 5, 40,185, 81,133, +122,181, 1,170,122, 61,202, 74,235,112,225,215,107,200,205, 61,139,146,178,242, 22, 57,109,139, 10, 91,167, 70,201,185, 75,248, +101,239, 33,100,110,248, 16,135,182,110, 64, 73,193, 85,112,212, 8,142,144, 6,225,119,166,230,219, 11,243,219, 3,159,207, 7, +128, 91, 0,110,249,251,251,151,120,123,123,235, 23, 45, 90,116, 18,230, 1, 99, 12,204,107,101,231,187,202,191,102,205,154,212, +164,164, 36, 0, 64, 68,112,112,136,165, 79,156,215,158,149,195, 42,250,214, 72,128, 3,225,255, 4, 0, 88,181,106, 21,174,148, +149, 97,198,196,137,176, 70, 3,242,242,242, 0, 0, 59,228,114,234,104, 86, 44,120,251,109,188,250,206, 59, 13,225,125,235,123, +235,177,245,189, 35,225,127, 43,178,178, 10,105, 83,241,183, 61,206,202, 42,252,214, 17, 30, 63, 62,255,191, 58,131, 30, 60, 30, + 15,191, 21, 22,160,176,228, 6,142,159, 59, 15,131,193, 8, 6, 4,124, 62, 31,132, 16,112, 38, 19,180,106, 13,242, 14,103, 31, +114,128,150,177, 21,255, 71,103, 62,120,155,199,127,252, 76, 30,108, 35, 4,142,193, 38,156, 44,138,204,182, 10,127, 86,218,235, + 84,192, 94,137,251, 67, 45,128,154, 50, 8,187,247, 65,197,115,247, 32,239,235,143,192, 15,234,220,240, 81,197,115,247, 32, 72, +204,192,135,223,122,113,233, 27,217,183,139,135,135,167,199, 39, 95,172,209,197,223,123,175,112,212,152,209,155,175, 93,189,198, +253,118, 53, 31,224, 40,196, 34, 17, 98, 99, 98,177,123,215,110,236,220,185,211, 41, 47, 96,223,190,125,113, 82,169,148, 90,197, +255,192,129, 3, 88,183,110,157, 1, 0, 78,156, 56, 97,144, 74,165,143, 56,210,181, 80, 84, 84, 4,203,214,196, 76, 81, 81, 17, + 50, 51, 51,145,151,151, 7,181, 90, 13,133, 66,129, 83,167, 78,161,184,184, 24, 55,110,220, 64,143, 30, 61, 80, 84, 84,212, 42, +223,188,121,243, 30,127,248,225,135,223,143,139,139,243, 58,121,242,164,143, 70,163,249,167, 68, 34,201, 6,240,169, 76, 38, 91, + 44,147,201,234, 0,252, 15,192, 8, 66,136,144, 82,106,108,205,233,152, 63,127,254,227, 63, 44, 88,176, 57, 54, 36,132,176, 11, + 23, 98,140,193,128,147,187,118,209,210,210,210,167,101, 50,217,219, 50,153,172, 18,192,198,139, 23, 47,178, 44,203,194,203,203, + 11, 97, 97, 97, 94, 70,163,177, 89,241,159, 52,105, 18,100, 50, 25,164, 82, 41,164, 82,169, 71,105,105,105,223, 27, 55,110, 64, +173, 86, 19,133, 66,209,159,207,231, 79,176, 21,127,185, 92,142, 7, 31,124, 16, 29, 5,205,117, 1,132, 2,232, 53,125,120,247, +103,187, 5,122,206,129, 81, 11,244,157,128, 51,193,211,113,223,252,175,160,173,170, 5,207,199, 27,242,143, 31,199,184, 1, 63, + 35, 32, 47,115, 60,128,238, 45,253, 64,111,159,174,248, 37,111,135,141,189,161,182,116, 19, 26, 1,163, 30,124,142, 7,198, 82, +239,119,254, 96,238,110,138,157,156,210,114, 65,189, 64,241,192, 48,219,109, 16,137,229, 54, 4,128, 64, 12,150,152,192, 89,218, +221, 89,115, 94, 0, 0,249,245, 99,235, 91,172, 89, 38,142,130,229, 24, 48, 44, 11,198,160,135,198, 98, 89,104,121, 60,120,178, + 90, 40,181, 20, 68, 64, 96, 50,153,160, 49, 1, 21,106, 3, 90,234,204,102, 13, 28,116, 2, 30, 56, 13, 11,150,171,131,170,222, + 8, 30, 17, 64,207, 26, 97,160, 6,176, 70, 3, 32,228,192, 16,128,136, 56,212,105, 77, 40,175,212, 64,173,103,155, 13,198, 48, +196,212, 96, 0, 16,242,187,158, 24,117, 90,212,213,212,128, 33, 60,240,249, 20,160,124,240,136,235, 29,127,151,175, 95, 54,244, +237,209, 87,232, 72,216,191, 81,152,148, 16, 72, 36, 18, 0,208, 2, 48,240,249,124, 20, 22, 22, 98,249,242,229, 15, 2,184,177, +104,209,162, 97,190,190,190,126,117,117,117,215,107,107,107,157, 14,119, 11, 67, 67,159, 2,128, 78,157, 58,217, 86,224,218, 79, + 63,253, 52, 11, 64,194,176,193,131, 15,182, 87, 69,152, 63,127,126,188, 35, 6,192,143, 57, 57,113, 35, 71,142, 12,150, 42,201, +129, 0, 0, 32, 0, 73, 68, 65, 84, 27, 27, 21, 5,226,237,141,229,203,151, 99,225,194,133, 16, 8, 4, 48, 42, 20,240,245,245, +197,235,243,231, 55,140, 11,112,100,112, 96,211, 62,126,123, 99, 2, 90,194,114, 39, 6,119,158, 62,125, 26,167, 79,159,110,184, +190,165, 62, 78, 69, 77, 77, 63, 47,111,111, 84, 41, 20,144, 31, 63, 14, 62,195,131,222,104,132, 70,171, 5,199,113, 13,131, 21, + 89,163, 1, 6,189,222,145, 60,230, 0, 48,150,110, 0,206,166,224,235, 44,231,241,246,170, 79,133, 0, 16, 25, 30, 94,113,237, +226, 47,109,202,215,132,228,101,228,183, 51,233,113,123,119,126, 41,111,143, 72,128, 51, 97,255, 70, 97,217,109,159, 35,234,137, +151, 33,138, 24, 98,110, 43,170,202,144, 95, 99,222, 68, 78, 52,102, 10,138, 77, 44, 60, 86, 31,111,149, 67,169, 84,250,137, 36, + 98,244,142,136, 16, 95, 43,185,209,185,186,178, 26,179, 30,157, 35,223,115, 48, 19, 31, 47, 91,149,190,115,207,174,164,200,136, + 72, 60, 62,243, 49,228,158,201,193,206,237,219,233,116, 7, 66,236,182, 94,255,129, 3, 7, 48, 97,194, 4,171,177, 40,188,121, +243, 38,158,121,230, 25,161,245,246,237,113, 85, 87, 87, 99,220,184,113, 48,153, 76, 40, 42, 42, 66, 78, 78, 14, 6, 12, 24, 0, + 95, 95, 95,116,235,214, 13, 81, 81, 81, 96, 24, 6, 12,195,160,115,231,206, 13, 81,170, 22, 60,245, 1, 67,134, 12,249,104,204, +152, 49,188,188,188, 60, 31,147,201, 84,190,125,251,118,165, 86,171, 93, 46,147,201,108, 13,216,103, 39, 79,158, 92,188,103,207, +158, 8, 66, 72, 25, 90,216,209, 86, 42,149, 14,155, 31, 31,191,113, 20,159, 79, 42,151, 46, 5, 53, 26, 33,231,241,184, 92,141, +230, 73,153, 76,246,141,173,221,241,214, 91,111,241, 25,134, 65, 77, 77, 13, 10, 11, 11, 43, 6, 13, 26, 20,210,148,111,210,164, + 73,183,253, 70, 88, 88, 88,128,137, 82,104, 53, 26, 92,188,120, 17, 44,203,146,142, 42,254,183, 25, 0,186,173,210,200, 80, 95, +201,216,201, 67,195,158,241,145, 8, 70,178, 38, 78,193,167, 38, 31,248,117,230,149,213,234,160,173,170, 3,132,124,152,106, 85, + 40, 81, 24,128,192,238, 96, 56,131, 24,173,204, 38,184,170, 84,162,143,159, 15, 88, 61,112, 53,251, 91,244,142,155,212,224,192, + 25, 13, 70, 8,192,160, 94,103,222,161,246,129,184,104, 72, 2,195, 90, 77,240, 3,131, 9,246,156,167, 16,136, 1, 97,247, 73, + 48, 20, 31,109,112, 28, 4, 66, 17,140,208,193, 75, 98,222,145,116,215,158,173,248,229, 68,118,252,156,137, 49, 45,183, 70, 28, + 7,161, 65, 11, 35,132, 96, 24, 22,208,153, 27, 54,163,209, 8,189, 78, 0, 30, 95, 0,232, 0,202,153,187, 8,122,132, 71,180, +200,165,209,113,224,241, 8,140,172, 17, 58, 61, 7,165,202, 92, 14,141, 28,133, 65,207, 1,124,128, 39,224,129, 47, 6,136,214, + 4,142,176,224,160,133, 74,107, 9, 72,219,129, 9, 0,195, 1,148, 0, 12,195,129, 16, 30, 56, 74,192, 48,150,177, 84, 28, 3, +142, 97, 64, 56,199, 28,100, 27,239, 95,232,106, 1,242,240,240,128,197,219, 15, 46, 44, 44,172, 88,190,124,121, 60,128,135, 22, + 45, 90, 52,177,103,207,158,106,149, 74, 85,205,178,108,131, 80, 56,163,255,107,214,172,249, 50, 41, 41, 9,225, 65, 65, 13, 39, +195,131,130,252, 44, 81,128,224, 63,162,194, 24, 12, 6,185,213,219,167, 42, 21,254,253,239,127, 67, 95, 93,221, 48,242,173,183, +197, 88, 17,232,245,120,240,193, 7, 43, 74, 43, 42, 30, 9,243,240,216,124, 55,210,102, 59,168,207,182,255,191, 57,196,196,196, + 32, 33,161,103,195,245,205,173, 3, 0, 0,172,222,128, 90, 67, 13,116, 58, 29,252,124,125, 33, 22,138, 96, 52,177,160,148,194, +100, 50,193, 96, 48,192,104, 52,130, 99, 77,142,230, 47,119,165,168,136,137, 12, 15,183,122, 4,220,149,162, 34,230,219,237,255, + 19,219, 70, 4, 34,195,195,107,209, 78,131,217,250, 69, 39,101,151, 20,156,106,151,103,236,234, 24,128,123, 51, 43, 81, 17,158, + 14, 97,247, 62, 32, 17, 67,208, 99,195, 89, 84,233, 56,120,242, 9, 12, 63,253,128,203,133,215,236,238,159,167,101, 13, 56,157, +123, 2, 31,173,252, 16,247,196,141,197, 91,255,239, 29,236,223,187, 31,155, 55,125,131, 49,227,199, 38,117, 11,239, 14,190,135, + 0, 7,143, 30,196,150,175,191,193,142, 31,182, 99,247,238,221,244,255,254,239,255, 72, 43, 34, 75,155, 10,191, 21,181,181,206, +111,112,167, 82,169,224,235,235,123, 28,192,168,240,240,112,196,196,196,128,199,227,129,227, 56,244,232,209, 3, 34,145, 8,117, +117,117, 8, 15, 15,135,183,183,247,117,149, 74,213,163, 37, 46,153, 76,118, 81, 42,149,166,238,216,177, 35, 49, 50, 50,178,223, +246,237,219,235, 21, 10,197,187, 50,153,108,139, 77,250,167,223,123,239,189,175,108,216,176, 97, 27,128, 10, 0,201, 0,126, 6, + 48,180, 25,190,179, 82,169, 52,213,239,212,169, 55, 30,102, 89,124, 8,112, 95,214,215, 63,214,132,239,161, 23, 94,120,225,195, +185,115,231,226,218,181,107,216,189,123, 55, 88,150, 61, 4,224,225,214,238,219, 18, 5, 96,252,120,188,106, 47,131, 1,234,179, +103,105, 48,199,169,174, 2,170,187, 45,254, 81, 81, 81, 56,119,238, 92,179, 33,127,123, 93, 0, 61,167, 15,239,190,196, 71, 34, + 24, 89,169,212,237, 63,118,165,114, 57,120, 34,224,242, 81,220, 31, 78,177,248,249, 7, 17, 51, 48, 28, 47, 72, 39, 99,106, 47, + 3,112,225, 0,168, 64,194,162,213,193, 58,181,200,175, 45, 6, 95, 4, 60, 48,245,101,108,249,100, 25, 0, 3,160,209,195,164, + 5,126,144,159, 67,214, 73,243,140,194,174,221, 35,192,240,237,139, 87,226, 80, 2,163, 14,216,181,123, 31,134, 79,124,222,236, +253, 67, 0,158, 4, 72,153,146,140,196,241,211, 0, 0, 37,215, 11,192,234, 12,173, 91,244,148,130, 37,102,129,215, 27,204,131, +255,244, 58, 45, 52, 26, 13,234,235,235,161, 82,214, 65,165, 82, 65,169,170,135,174,190, 30, 90,173,182,229,194, 95, 79,160,213, +153,160,213,153,160,214, 24,161,170,215, 67,161,210,163, 86,105, 64,157,202,136,218, 90,243,255,154,106, 22, 53, 10, 22, 53,117, + 44,170,106, 12,184, 85,213,114, 26, 25, 74, 97, 2, 64, 76, 4,132,225, 64, 9, 5, 40, 5,165, 60,152,184,223,179,143,179,180, + 30,206,198,198,251,143,233,143,156, 61, 57,216,127,104,127,131, 81,112,249,250,101,135,190,203,227,241,192, 55,231, 87, 24,128, + 94, 43, 86,172, 56, 15, 96,245,235,175,191,254, 82,207,158, 61, 89,115,144,192,156, 48, 39,197,159, 8, 67, 67,119, 2, 64,104, +104,232,109, 31, 62,247,220,115,236,169,203,151,183,158,189,112,161,221,194,186,171, 87,175,150, 59,186,111,188,209,102,138,197, +247,223,127,143,171,229,230, 46,156, 31,179,179, 27,125,118,249,242,229,144,224,224, 96,197, 31, 97,168, 36, 36,244,100, 44, 13, + 90,211, 6,191,209,231,118, 13, 60, 31,239,223, 56,147, 9,202, 26, 5,170,170,170, 80, 93,171,128, 90,163,129, 90,163,129,170, +190, 30,234, 58, 37, 84,181,255,159,189, 43,143,111,162,218,254,223, 59, 89,154,182, 64, 23,118,202, 90,164,236,178, 20,161, 5, +129, 4, 82,168, 34, 42, 74, 1,225,137,125, 5,155,226, 6, 34, 62, 84, 84,220, 80,121, 63, 11,184,210,212, 39,130,239,129, 64, +139, 11,155, 44,129,164,178,180,212,130, 11,139, 64,161,208, 66, 89, 10, 77,186, 37,105,182,185,191, 63,146, 9,105, 73,147, 73, + 90, 4, 53,223,207,167,144, 89,114, 50,115,231,206,253,158,115,238,185,231, 84,160,214,104,128,185,182, 22,172,213,235,252, 38, +211,163,107, 87,110,204, 96, 1,152, 93,167, 3, 0,224,127,155,182, 96,113,250,199,225, 0,218,250,122,223,191, 31,201,150,170, +178, 94,170,211,217,206, 30,255,225,246,186,255, 1, 92,158,218, 21, 93,190,252, 25,164,219,221, 48,229,100,163,248,159,131, 16, + 42, 36,216,151,208, 26,214,202,107, 24,178,163, 12, 94,102, 0, 48,121,242,100,242,228,220, 57, 56,115,234, 20,114, 53,251, 16, +214, 60, 12,143, 77,125, 12,225, 45, 35,113, 36,191, 0,205,196, 18,132,134,134,162,125,215, 14,248,122,253,215,120,105,209, 43, +168,169,240,191, 74,237,224,193,131,125,254, 78,243,230,205, 81, 89, 89, 57,140, 97, 24,115,167, 78,157, 48,116,232, 80,244,237, +219, 23,173, 90,181,130, 68, 34, 65,215,174, 93, 49, 96,192, 0,132,135,135,163,186,186,186, 75,243,230,205,225,133, 88,255, 47, + 39, 39,103,247, 87, 95,125, 37,210,233,116,175,214, 35,235,164,145, 35, 71,174,248,242,203, 47, 87,181,109,219,246, 93, 66, 72, + 51, 0, 47, 1, 88,236, 65,222,162,119,170,171,255,111,150,213,106,251,194,104,156, 94, 79,222,228,105,138,215,191,121,118,222, + 11,130, 83,167, 78,225,208,161, 67,248,242,203, 47,107, 0,188,204,243,246,153, 16,147, 73, 66,127,255, 29,157, 84, 42, 18, 85, + 90, 42, 0, 64,151, 45, 91,134,173, 91,183,254,161,253,173,190, 71,175, 33, 15, 95,253, 65, 32, 72,192,144,230, 37,229,250,181, + 95,231,158,123,249,151, 98,109,190,209, 70,206,224,250, 57, 72,190,121, 10,239,142,168, 70,193,155, 67,241,161,172, 6,161,223, + 61, 13,104, 47,162,134, 74,142, 58, 52,175, 6,112, 35,170,255,215,223,182,224,245,215,191,194, 93, 45,250,227,248,193, 95,177, + 75,253, 59,100,241,125,145, 48,210,222,209,168, 64, 8,179, 15,241, 17,137,131,122,225,157,255,123, 31, 59,142, 86,161, 89,215, + 62,120,224,129,137,216,185,247, 91,108,219,105,143,178,100,108, 22, 4,137, 60,143,115,148,181,193,198,218,173, 25, 56,172, 25, +179,217,140,218,218, 90, 24,141, 70,232, 13, 70, 24, 13,122, 24, 13,122, 24, 76,181, 48,155,106, 27,118,127, 25,155,163,178,198, +134, 42, 35,139, 42, 35,107,255, 92,205,162, 70,111, 69,141,193, 10,157,214,134,114,173, 5,229, 58, 11,202,203, 45,184,126,221, +140,171,215, 45, 30, 21,128, 27,238,127,151,107,230,220, 55, 2, 10, 1, 33,160,245,162,254, 41,241, 78,182, 47,206,124, 17,189, +227,123, 59,183, 85,171, 85, 78,143,192,129,237, 7,112,170,248, 20,175,100, 79, 44,107,255,173,236,236,236,253,148,210,126,147, + 39, 79,158,217,173, 91,183,214, 0, 24,150,101,131, 44, 22, 75,132,213,106,109,225, 70, 1, 96, 61,184,254, 23,127,250,233,167, +247, 79,158, 60, 25,221, 90,183,230, 53,117,213, 24,136,218,180,145, 2,192,144, 94,189,100,222,206,237,209,174,157, 44, 61, 61, + 29,199,139,139,171,190,217,181, 11, 39, 79,158,116, 90,253, 61,123,246,132,227,152,249,155, 93,187, 80, 92, 92,140, 83, 5, 5, + 70,111, 50,111, 69, 12, 0, 0, 58,122,244,232,167, 92, 73,159,251, 63, 54, 54,150,151, 59, 23, 0, 10, 79,158, 45,176, 90,173, + 48,155, 77,208, 94, 45,195,181,203, 87,112,253,202, 85, 92,191,114, 21,218,178,107,168, 40, 47,135, 73,175,183,199,207, 84, 84, + 96,144, 92,238,173, 13,173,139,211, 63, 22, 46, 78,255, 88, 8,160, 10, 0, 59,108,240,221, 55,157,228, 18, 23,192, 27, 39,142, +100, 75, 75,207, 22,168, 7, 12,189,113, 13,231,206, 28,148, 86, 92, 43, 82, 55,166,127,144, 41,186, 58,150,191, 63, 56,173,213, +163,100,246, 61,160,231,126, 67,155,207,143, 32,116,229, 97, 92,158,218, 21,177, 59,202, 64, 68, 65, 16, 18, 64,200,120, 87, 64, +159,126,230, 25,242,218,251,239,224,185, 5,243, 97, 97,109, 56,121,190, 16, 51, 30,155, 14,177, 68,130,239,191,219, 12, 88,108, + 48,213,154,176,175,224, 32,140,198, 26,164, 38, 39,231, 20, 20, 20, 80, 15,132, 72, 38, 77,154, 36, 27, 55,110, 28, 8, 33,216, +189,123,247, 77, 46,253, 23, 95,228, 31, 39,212,178,101, 75, 92,186,116, 9, 0,132, 25, 25, 25,184,118,237, 26,250,247,239,143, +240,240,112, 48, 12,131,252,252,124, 48, 12, 3, 66, 8, 46, 93,186,132,150, 45, 91,122,149,169, 84, 42,223, 53,155,205,163,148, + 74,229, 6, 23,178,126,108,228,200,145,233,179,103,207,142,200,200,200,144, 16, 66, 24, 0,223, 2, 88,160, 84, 42,175,122,145, +247,175, 67, 22,203,144,250,242,166, 45,252,102,227,163,211,159, 38,247,207,201,128,230,208, 9,164,167,167,179, 85, 85, 85, 41, + 74,165,242, 60,143, 41, 68, 0, 96,239,106,222, 60,188,211,149, 43,184,215, 96, 64,123,145, 40, 52, 84, 32, 96, 74, 75, 75,111, +138,197,249,163,148, 0,238,143,215, 20, 0,128,179, 95, 31, 60,247,140, 86,111, 58, 12,123,224, 86,251,220,194,107,153,163,122, +181, 93, 36, 60,119, 40, 18, 95, 62, 14, 4,133, 2, 38, 61, 64, 41, 44, 2,201,213,125,199, 47,127, 1,160,193,236, 75,235,214, +126, 38,155, 62, 99,166, 26, 0,244,172, 5,103, 42, 74, 0,216,112, 87,139,110,144,201,238, 70,219, 86,237, 80, 94, 89,101,247, + 21,152,173,184, 92,161, 71,111, 15, 55,213,177,115, 60, 46,150,228, 58,222, 76, 33, 18, 7,216, 99, 0,118, 28,181, 96,231,214, +108, 92,189,126, 9, 45,195,237, 43, 9,194,197, 34,220, 61,196,243,122, 80, 51,132, 16,179, 86,216, 32, 0, 75, 8, 24, 27, 11, + 88,172,176,137,132, 0, 97,192,189,147, 44,133, 61, 87,128, 7, 60, 60,237, 37,242,221,127, 23,208, 16, 49,133, 80,228,226, 97, +176, 0, 86, 10,212,154, 1,155,201, 6, 66, 8,136,152,192,106, 3,244, 38, 96, 86,242,191,137,187, 84,142, 54, 23, 13,141,101, + 88, 16,135,251,223,174, 20, 16,216, 88, 6,140,192,110,245, 51, 0,168,128, 2,148,159, 23,192,149,252,221,109, 31,216,126,160, +155,215, 41, 9,155, 13, 38,147, 9,147, 39, 79,238,155,157,157,189, 28,192,192,236,236,236, 29,217,217,217,251, 38, 79,158,252, + 76,247,238,221, 45,132,144,150, 31,126,248,225,174,151, 94,122,105,134, 86,171,205,241,160,124, 58,251,228,130, 5, 11, 22, 47, + 88,176, 0, 59,118,236,128,254,234,205,239,114,183,214,173,113,238,220, 57, 0, 80,243, 73, 12,212, 80,210, 31, 81,155, 54,210, + 79, 63,253, 84, 77, 41,197,144,158, 61,101,131,121,172, 44,232,223,187,183,134, 48,204,248,147, 63,253,212, 21, 64, 16,128,143, +184,213, 0, 61,218,183,199,252,249,243,113,224,192,129,165, 49, 49, 49, 57,253,162,162,188,198, 40,184,203, 3,224,111, 12,128, + 43,184, 60, 0,113,113, 73, 63,229,229,149, 29, 80, 40, 20, 98,199, 52,193,112, 0,185,124,147, 0,117, 29,208,231, 21,227,229, + 43,227, 88,171,173,151,190,178, 18,149,215,175,129, 16, 6,148,178,168,173,173, 5,165, 20,148, 82,156, 59,241, 59, 44,102, 19, +238, 26, 18,235,173, 13, 93,199,156,112, 0,204,253,178,209,236,253,178,209,117,130,254, 28, 83, 4,188,113,242,151,111,164,151, +206, 22,168, 1,160,107,151, 46,248,190,158, 23,160,117,231,193, 50,220, 70, 12,249,161, 12, 5,247, 1, 3, 99,229, 40,123,122, + 56,218,125,118, 16,167,181,122, 68,136, 9,202,181, 58, 8, 9,241,234, 1,224, 48,115,230,204, 58,103,110,217,178,133,222, 63, +225, 62,108,221,188, 21, 27, 55,110,196, 27,139, 94,195, 46,205, 30, 8,132, 2, 68,117,140, 26, 93, 89,233,121,233,114, 98, 98, +162, 38, 49, 49,145,236,216,177, 67, 58,110,220,184, 58,177, 0,187,119,239,198,153, 51,103,106,149, 74,101,123, 62,215,214,181, +107, 87, 20, 21, 21,161, 79,159, 62,214,121,243,230,137,215,175, 95,143,176,176, 48,156, 60,121,242, 38,207,107, 81, 81, 17,186, +242,124,206, 74,229,141,196,115, 10,133,226,241,123,238,185,231,173,199, 30,123, 44,172,160,160,160,121,109,109,237, 63,131,131, +131, 31, 48, 26,141, 31, 40,149,202,239,121,202,251,197, 85,222, 3,207,174, 95,115,239,216, 73,228,223, 42,128,116,120, 16,239, +174,120,133,106, 11, 79,166, 40,149,202, 44,111,178, 92,188,108,164,218, 98,169, 16, 7, 5,161,133, 88,140, 96,155,205,164,183, +217,108,183,131,252,249,162,142, 2, 32,121, 76,121, 92,251,181,226,180,228, 49, 37, 55,165, 89,114,236,107,197, 15,213,181, 86, +253,176,187, 90,221, 31, 25, 34,184, 71, 96,170, 13,181, 82,166,186,188,218,156,151,123,230,202,206, 82,173, 33, 71,242,152,242, + 50, 86,174,116,251, 3, 53,250,214,154,180,167,231,200, 0,168, 89, 1, 55,205, 39,192,153,170,203,120,253,153, 20, 24, 12, 38, + 84, 25,237, 49, 0,102, 38, 8, 99, 18, 61,167,217,125,109, 81, 50,217,177,109,136,253,229,182,113,150,179, 21,137,253, 9,166, + 61,181, 12, 33, 33, 65,104, 17, 44,145, 1, 80, 23, 30, 59, 34,139,239,231, 57, 33,136,144, 90, 97, 38,118, 37, 0,132,192, 70, +169, 93, 17,224, 18, 54, 16, 6, 66,150,133,149, 91,118,224, 69, 9,168, 48,134,195,104, 42,135, 88,200, 56,211,156, 89, 89,192, + 98,161,176, 88, 41,106,140, 44,136,128,192, 6, 2, 11,123,195,117,239,150, 96, 89, 6, 12,177,129,216, 8, 40, 67,157,238,127, +210,128,241,204, 73,122,238,121, 25, 89,185,242,164, 71, 11,239,247,220,223, 27,219,119,204,148, 82, 24,141, 70,244,239,223,255, +114,116,116,244,164,243,231,207,247,216,184,113, 99, 62,128,135,178,179,179, 31,114, 61,249,253,247,223,215,188,244,210, 75, 50, +173, 86,235,141, 32,156, 13,146,150,150,214,224, 73,143, 62,241, 4, 0,223, 18, 3,113, 89,247,234, 99,104,239,222, 62, 45, 43, +236,215,179,231, 46, 87, 79, 70,122,122,250, 39, 19, 39, 78,180,158, 58,117, 74, 88, 92, 92,140,174, 45, 91,230, 70,133,132,240, + 10, 80,188, 21,121, 0,234,145,251,213,156,156, 28,215, 24,143,163, 14, 69,128,111,198, 64,125,112,251,118,143,158,220,179, 55, + 55, 60, 52,180, 69,149,174, 2, 86,171, 21,212,241, 30,232,174,150,161, 74,167, 3,165,148,143,245,111,127, 89,111,196,156, 48, +142,229,128,140, 99,217,159, 51, 49, 80,225,249,243,252,149, 0,195,175,210,139,133,249, 78, 43,255,251, 44,251,242,191,214,209, + 35,100, 3, 98, 39,106,110,223,240, 74,111, 86, 2,240, 57, 6,166,189,142, 43, 44,139, 1,171,243,145,159,216, 22,125,183, 94, +133,144, 0,205, 69,254,173,152,157, 56,113, 34,217,171,217, 75,199, 36,140,197,230, 77,223,225,237,165,239, 99, 97,101, 37, 40, +203, 98,195,134, 77, 40, 45, 45,125, 0,128, 87, 31,180, 59, 69, 0, 0, 38, 77,154,244, 11,128,106, 62,215, 18, 31, 31, 79, 46, + 93,186, 68,143, 28, 57, 34, 30, 60,120, 48,198,142, 29, 11,181, 90,141,206,157, 59,195,100, 50, 97,244,232,209,160,148,178, 71, +142, 28, 97, 68, 34,145,207, 25, 1, 21, 10, 69,159,176,176,176,229, 83,167, 78, 21,157, 56,113,162,133,201,100,106, 40, 48,144, +175,188, 65, 81, 3,167,172, 25, 56,106, 42,249, 34, 7,168, 50, 2,230,115, 59, 88,109,161,186,126, 96,160, 39,101,130, 83, 2, +132,218,202, 74,171,216, 98,129, 65, 44,134,208,158,245,135,253,163,123, 29,151, 7,192,213,242,119,183,207,173, 43,213,133,252, +185,237,223,139,191, 86,148, 20, 95,175,201, 5,208,222,241,242,154, 0,148, 2, 40,146, 60,166,244,234,226, 28, 60,224, 65,205, +241,223, 74,100, 54,218, 76,237,250,114,212,232,171, 32, 16,134, 1, 76, 8,254,245, 1,255, 20,147,137, 19,250,145,119,230, 60, + 32, 5, 99, 80,187, 54,111,179,102, 97,176, 89,116, 0,213,163,248, 96, 38,153, 57, 45,209,171, 44, 11, 4, 0,165,118,162,134, + 0, 98,234, 80, 4, 28,228,111,207, 1, 8,128,231,218,205,228,212, 87, 73,230,199,111, 80,171, 69, 11,161, 99, 97, 47,165, 20, + 54, 43, 69,173, 5,168,170,182,194, 2, 10, 43,101, 32, 20, 17, 44,121,235,147, 6,239,123,246,108,123,144,214,154,213,103, 40, +177,216,173,127, 10,128, 82, 2, 80,135,197, 64, 5, 32, 2, 22, 44, 43,196, 11, 11,198,241,106,195,217,111,207,150,157, 63,123, +222, 19, 1,139, 96, 95,170,225,137,157, 88, 0, 48,153, 76,208,233,116,186,176,176, 48,196,198,198,254, 58,116,232,208,160,107, +215,174,225,236,217,179,246,229, 97, 44, 43,221,180,105,147,218,161, 4,168,121, 40, 1,150,164,196,196,164,174,253,251,219,238, +233,213, 75,239,232,163, 38,212, 93, 17,137,164, 68,251,179,237,202, 35, 41,208,139, 47,190, 40, 3,128, 33, 61,123,222,116, 44, +118,192,128, 70, 17, 68,255,222,189, 63, 99, 24,198,118,242,167,159, 66,219,182,109,123,189,223,240,225,107,110,167, 70,239,134, +212,245,177,177,177,174,209,214,206,117,172, 62, 40, 1, 39, 6,141, 29, 51,108,243,127,190,216, 20,221,173,107, 31,147,169, 22, + 54,139, 21, 44,203,162,121, 68, 4, 42,181, 90, 12,146,203,101, 60,172,127, 0,168,120,243,133,103,219, 0, 48, 23,158, 63, 47, +230,230,255, 15, 29,249, 13,247,203, 70,179,139,211, 63,246,150, 28,200,137,152,246, 58,122,242,212, 73,217,222,157,223,215,113, +241,143, 25,255,144,140,105, 17,223,168,231,218, 80,128,159,251,253,252, 57,108,200, 15,101,192, 15,207, 56,183,239,250,254,198, + 18,224, 74,139,255,235,195,199, 72,199,144,175, 74,190,186,111,220,132,196,237, 79, 62, 62,107,255,221, 3,250,223,187,249,251, + 45,200,253,229, 48, 82, 83, 83,183,173,108,192, 64,243,162, 8,204,250,246,219,111,255,243,237,183,223,198, 37, 38, 38,242,190, +184,113,227,198,141,217,181,107,215,222,173, 91,183, 34, 58, 58, 26, 9, 9, 9, 8, 11, 11, 59, 93, 89, 89, 25,115,252,248,113, + 20, 21, 21, 49, 34,145, 8,227,198,141,147,251,122,159,142,192,192,165, 91,182,108,105, 48, 48,208, 71,121, 63, 43, 20,138,247, +190,203,126,240, 21, 99,212, 12, 24,127,122,149,189,180,111,201,227,190,202,115, 40, 1,181,197,101,101,162, 23, 78,159,190,104, + 51, 24,152, 95, 25, 70,212, 78, 32,184,162, 80, 40,110,203, 20,128,187,108,128,222,166, 0,220, 66,242,152, 82, 15,224, 55,199, +159, 95,120,252,241,103, 52,105,105, 47,201, 50,148,111,171,163,186,244, 0, 96,130, 40, 72,130,139,151,171, 48,122,226, 76,226, +187,188, 7, 53,119,245,138,193,234, 85,223, 0,108, 49, 0, 33,172,181, 70, 68,181, 15,147,117,110, 97,229,255,242,219, 88, 8, + 25, 22, 22, 34,132,136, 90,111, 40, 2,176, 2,212, 6,190,129, 97,174, 72,125,246, 13, 2, 0,139, 95,158, 67, 69, 66,187,181, +111,101,237, 46,243,138,106, 10,155, 21, 16, 8, 89,124,246, 41, 63,165,231,137,100,123,106,228, 85, 95,156,162,224,114,194, 51, + 0, 75,236,238,254,249, 11, 30,240,233, 34, 43,107, 42, 53, 17,109, 35, 26,219,191, 24,192,190,138,194,104, 52,194,102,179,161, +170,170, 10, 2,129, 0, 54,155, 13,237,218,181,131,197, 98,129, 82,169, 84,215,243, 4,168,189,213, 12, 24,212,191,127, 54, 0, + 52, 69,198, 63, 0,136, 36, 68, 3, 0,145, 3, 6,220, 18, 51,175,111,207,158, 25,141, 17,240,194,226,197,117, 86, 73, 44,120, +227,141, 58,158, 1, 95,230,254,221,144,185,222,211,106, 0, 31,210, 1,159,124,112,246,172,126, 0, 4, 39,115,114, 44,181, 6, + 35, 88,155, 13,189, 99, 99,101,237, 99,250,160,235,128, 62,252,222, 57, 74,166,238,252, 97,155,115,115,120,159,104,231,231,157, + 63,108,187,105,219, 83,104,252,233,203, 17,132,105, 17,143,177,227,137,236,196,201,179,184, 92,124, 84, 13, 0,123,119,126,175, +110,219,249,172,172,255,176,127,248,172, 4, 76,153, 50, 5,190,166,247,181, 17,207,121,183, 75, 38,181,195, 15,151,106,111,249, +128, 63,115,230,204, 31, 0, 48, 5, 5, 5,236,158,188, 28,180,108,213, 18,141,169,207,145,152,152,248, 69, 98, 98,226, 87,240, +158,222,185, 14,154, 55,111,174,126,244,209, 71, 73,110,110, 46, 61,123,246, 44,242,243,243, 81, 93, 93, 29,211, 20,181, 0, 28, +100,251,127, 10,133, 66,148,155,155,219,223,108, 54,191,234, 58,151,239,167,188, 69, 10,197, 63, 68, 97,221,191,154, 95,121,118, +215,140, 70,200,179,174, 63,116,232, 1, 0, 9, 0,126, 6,203, 86, 3,184, 58,109,225, 55, 72, 13,123, 4,153,149,127,140, 18, +192,173, 2,112,183,223, 47, 5,192,215,169,132, 6, 93, 85,143, 60,161,217,182,243, 12,121,120, 66, 8,109, 19,213, 9,218,106, + 43, 70, 79,120,220,239,142, 16,127, 79, 47, 18,127,207, 43, 80, 40, 94,167,192, 85, 68, 52, 23,162,115, 36,235,211, 75, 63,228, +159, 11,110, 89,150,176, 55,223, 91, 73, 0, 96,238,188,103,168,217,104, 1, 11,251,178,185,229,159, 46,247,235, 55, 83,102,217, +107, 6,172,250,207, 73,202, 82, 1, 94,126,233,161,219,153,225, 76,236,234,198, 54,153, 76, 48,155,205, 78, 34,227, 8, 44, 80, + 37,208,139, 11,210,135,244,195,126,194,188,112, 97, 82,144,195,131,210,216, 20,100, 20,128,181,215,232,209,117,174,185,107,251, +118,188, 5, 4,177, 38,205, 19, 19,125, 54,252, 80,191, 20,112, 29,251,187, 69,156,166,239,208, 56,244, 29,138, 70,183,165,183, +194, 62,245,117, 96, 43, 9,130,145,241,188, 34,245,108,181, 21, 49,205,249, 12,145, 77,210, 21,232,144, 33, 67,154,178, 79, 89, +252,253, 98,124,124, 60,241,150,136,173, 17,164,253,174, 66,161,248,206, 53, 54,160,145,242,254,165, 80, 40,214,185,198, 6,248, + 33,195, 2,160, 2, 64,189,184,129,107,127, 24,249,123, 34,123,183, 61,110,224,192,129,119,106,249,200, 0,254, 68,232,209,163, + 7, 10, 11, 11, 3, 13, 17, 64, 0, 1, 4,240, 39, 1, 19,104,130, 0,154, 2, 1,242, 15, 32,128, 0, 2, 8, 40, 0, 1, 4, + 16, 64, 0, 1, 4, 16, 64, 64, 1, 8, 32,128, 0, 2, 8, 32,128, 0, 2, 10, 64, 0, 1, 4, 16, 64, 0, 1, 4,112,219, 81, + 39, 52,117,206,156, 57,126, 71,143,186,203,100, 23,144, 23,144, 23,144,119,103,200, 83, 40, 20, 84,169,108,120,217,105,160,253, + 2,242, 2,242,254, 90,242,124, 86, 0,184,129,194, 87, 33,158, 6,150,166,150, 23,192,157, 9,111, 4, 19,192,157,249, 28,124, + 60, 63, 20,192, 61,251,247,239, 95, 34, 16, 8,134, 7, 5, 5,193, 96, 48, 28,188,247,222,123, 23, 1,200, 7, 96,184, 19,218, + 64,165, 82, 73,179,178,178,212,127,197,113,229,216,177, 99,200,207,207,247,122, 94, 94, 94, 30, 61,118,236, 24, 50, 51, 51, 73, +191,126,253, 26, 45,143,195,208,161, 67,225, 73, 94, 0,127, 98, 15, 0, 7, 95,210,147,242, 73,148,227, 78, 94, 67,229, 97,253, + 73,188,243, 87, 31,208,249,158, 59,126,252,120,217, 35,143, 60,162,225, 43, 51, 42,234,230,210,203,165,165,165,117,182,147,146, +146, 32,151,203, 9, 31,121,183, 82, 9, 24, 63,126, 60, 5,128,157, 59,119,146, 59, 65,158, 94,175, 31,187,105,211, 38,213,233, +211,167, 1, 0,209,209,209, 15,166,164,164,108,241,247,249,186,246,123, 74,169,243,253,224,246,115,239, 10, 33, 4, 25, 25, 25, +196,147,242,204,247, 57,248,248,188,250, 28, 59,118,108, 83, 85, 85, 85,175, 46, 93,186,224,250,245,235,168,173,173, 5,128,225, +155, 54,109, 82,135,134,134,158, 76, 76, 76,124, 24,128,199, 82,146, 35, 70,140,240,201, 32, 56,112,224,128, 12, 60, 83, 61,115, +200,202,202, 82, 39, 37, 37,201,228,114,185,198,215,231,145,154,154,234,211,245, 77,153, 50,133,247,251,193,161, 75, 23,123, 5, +220,234,234,106,152, 76, 38,174, 63,241,122,223,242,243,243,241,223,255,122,206, 80,107, 50,153,232,240,225,195,209,187,119,111, +172, 93,187,182,204,100, 50,117,110,104, 93,120,126,126, 62,102,204,152,193,235, 94,175, 94,189,138, 37, 75,150,224, 78,206,109, + 31,192, 13,212, 79, 6,116, 43, 19, 1, 5,172,216, 91,136,239, 51,188,167, 52,126,120,206, 14,159,100,170,213, 55, 12,164,211, +167, 79, 35, 52, 52,212, 57, 8,185,180, 7, 31,107,139,214,223,174, 63,128,169, 84, 42,154,149,149,229,183, 5,182,110,221, 58, +233,248,241,227, 27,148,223, 24,164,165,165,209, 81,163, 70,201,166, 79,159,238, 19, 89,108,218,180, 73,213,166, 77, 27,204,156, + 57, 19, 58,157,142, 77, 79, 79,223,172,211,233,166, 69, 68, 68,248,148, 69,140, 16,130, 31,126,248,193,185,157,152,152,136, 29, + 59,118,120,220,246,134,250, 74,128, 66,161,160,177,177,177,200,204,204,164, 92, 98, 38, 95,201,191,178,178, 50,183,123,247,238, + 45, 0, 64, 34,145, 32, 56, 56, 24,101,101,101,168,168,168, 64, 88, 88, 24,202,202,202,122,237,216,177, 35, 63, 49, 49,177, 39, +128, 43,158,132,245,235,215, 15, 73, 73, 73,136,142,190,145,245,111,233,210,165,117,206, 89,184,112, 33,103,201,170,167, 79,159, +238,243,243,246,135,252, 57,172, 88,177,162,161, 67,206, 90, 5,254, 34, 52, 52, 20, 39, 78,156,128, 72, 36,130,217,108,198,142, + 29, 59, 80, 88, 88,136,151, 95,126,217, 39, 57, 87,235, 21,201,122,240,193, 7, 5, 0,228, 63,254,248,227,142,209,163, 71, 95, +125,248,225,135,219,170, 84, 42, 8, 4,130,214,225,225,225, 2, 95,100, 53,132,243,231,207, 7, 72,226, 79, 74,254,220, 62,175, +181, 0,254,172, 88,181,106,149, 52, 37, 37, 69,211, 88, 57,127, 22, 87,118,212,144,119,110, 88,237, 5,175,250, 37, 67,167,211, +193, 96, 48, 56, 45,144,204,204, 76, 87, 75,136,175,181,117,211,182, 92, 46,199,238,221,187, 41, 33,228,166,227,254,224,199, 31, +127, 84,191,248,226,139,200,206,206,198,228,201,147,155,164,253,118,238,220, 73,246,236,217, 67, 41,165,200,201,201, 81,231,228, +228,248,164,160,156, 62,125, 26, 51,103,206,100, 1, 48, 98,177,152,137,137,137, 65,122,122,250,122, 0,235,163,163,163, 39,164, +164,164,108,231, 35,231, 86, 20, 3,226,148,128,204,204, 76,202,165, 1,230,254, 87, 40, 20, 52, 41, 41,201,151,123, 13,213,233, +116,155, 36, 18, 73, 11, 0,120,250,233,167, 81, 91, 91,139,140,140, 12, 4, 7, 7, 59,203,102, 11, 4, 2, 84, 86, 86,182, 0, +144, 14,224, 31,158, 4,114,228, 94, 84, 84,116,211,190,166, 64, 82, 82,146,204,113,159, 50,127, 21,129,231,159,127,222,249,121, +249,242,229,220, 71,166,222,126,222, 10, 1,231, 53,121,245,213, 87, 17, 26, 26,138,236,236,108,140, 30, 61,218, 47,242,175,143, +145, 35, 71, 2,246, 44,141,255,124,252,241,199,209,163, 71,143,182, 59,118,236, 64,121,121, 57, 87,114,215,236,229, 93,104,234, +238, 39,157, 48, 97,130,122,219,182,109,238,188, 55,210, 49, 99,198,168, 9, 33,216,179,103, 79,192,221,123,139,201, 63,117,225, +251, 0,128,204,165, 47,185, 85, 2,254, 16, 5, 32, 51, 51,211,221,131,166, 13,237,247,231, 55, 14, 29, 58,164, 6, 32,107,172, + 18, 48, 99,198,140,191,205,124,182,193, 96,184,201,234,247,135,104, 56, 98,153, 60,121, 50, 18, 18, 18, 8, 0,100,103,103, 55, +201, 53,174, 91,183, 78,234,176,232, 72, 89, 89,153, 52, 43, 43, 75, 93, 86, 86, 38,245,213, 98,119,135,177, 99,199,146,177, 99, +199, 98,221,186,117,210,156,156, 28,245,186,117,235,124,146,171,211,233,172, 17, 17, 17,226, 77,155, 54,193,225, 13,168,213,233, +116, 76,122,122,250, 54,157, 78, 55, 46, 34, 34, 98,247,237,124,190, 28,233,187,246,101,133, 66, 65, 57, 37,141, 39,238, 41, 44, + 44,236,213,191,127,127,204,154, 53, 11,149,149,149, 40, 47, 47,135, 72, 36,130, 80, 40,132, 80, 40,132, 72, 36, 66,112,112, 48, +180, 90, 45, 84, 42,213,116,185, 92,254,172, 55,161, 69, 69, 69,117,148, 67, 78, 1,224, 60, 1,177,177,177,190, 92,163, 59,235, + 95,150,149,149,165,110,140,231,201, 5,214, 6,198, 74,222,222,128,243,231,207, 35, 39, 39, 7, 19, 38, 76, 64,151, 46, 93,208, +170, 85, 43,228,228,228,224,229,151, 95,118,122,223, 4, 2,129,207, 23, 54,114,228, 72, 44, 90,180, 8, 75,150, 44,105,159,146, +146, 50,245,177,199, 30, 67, 66, 66, 2, 0, 64, 32, 16,204,108,217,178,229, 22,165, 82,105,241, 84, 12,104,221,186,117,188,188, + 0,165,165,165,152, 54,109, 26, 63, 3, 37, 42, 10,169,169,169,234,162,162, 34,168, 84, 42,174,253,165,169,169,169,106, 78,129, + 14,224,214,130, 35,127,238, 51,167, 4,252,225, 30,128,134,230,177,253, 9, 16,188,213, 74,192,253,247,223,223,104, 79,128, 47, +247,229,203,111, 60,250,204, 78,108,250,100,124,147,180, 21,247, 2, 54, 84,169,234,224,193,131,141, 86, 12,154,226,249,254,248, +227,143,106,206,234,159, 62,125,186,230,199, 31,127, 68,155, 54,109,212,104,162,196,233,156,220,156,156, 28,228,228,228,120,117, + 55,235,245,250,251, 55,109,218,180, 13, 0,210,211,211,197,209,209,209, 72, 73, 73,225, 14, 75,126,251,205, 94, 47, 43, 61, 61, +125, 87,116,116,244,195, 41, 41, 41, 94,235,147, 39, 38, 38,214,137,137,185,239,190,251,234,120, 6,248,184,253,221, 40,221,212, + 93,255,226,158,139,235,116,128, 39,236,216,177, 99, 73, 76, 76, 12, 0,224,204,153, 51,160,148,226,212,169, 83,206,186, 15, 66, +161, 16,132, 16,216,108, 54, 24, 12, 6,124,251,237,183,144,203,229, 94,171, 46,185,146,127, 82, 82,146, 91,229,197,117,138,192, + 31, 37, 64, 46,151, 19,133, 66, 65, 27,235, 13,104,138,113,210, 98,177, 96,240,224,193,208,104, 52, 24, 50,100, 8,244,122,189, +115,106, 71,163,209, 96,252,248,241,176,114, 37,200,125,179,252,177,100,201,146, 14, 41, 41, 41, 23,191,248,226, 11,231,177, 14, + 29, 58, 96,217,178,101,255,229, 75,216, 77, 12,205,225,195,135, 17, 27, 27,139,232,232,104, 12, 30, 60,152, 30, 57,114, 68,198, +145,127, 81, 81, 17, 52, 26, 13,159, 24,149,161, 0,158, 1,240, 79,165, 82,105,243,112,222, 4, 0, 81, 0,190, 85, 42,149,215, + 2,212,255, 7,118,108, 62,248, 35,131, 0,155, 66, 9,232,218,181,107,163, 60, 1,220, 32,187,118,237, 90,183,199,183,111,223, +142,181,107,215,250,101,153,228,157,235,131,184,110, 39,252,118,251,115,112,157,243, 87,169, 84,144,203,229, 78,183,255,193,131, + 7,209,169, 83,167, 38, 81,250, 26, 99,125,113,214,255,245,235,215,157,117,230,165, 82,169,172, 41,189, 0, 28, 70,143, 30, 45, +203,201,201, 81,123, 59,111,211,166, 77,219,184,185,127,189, 94,143,165, 75,151,162,166,166, 6, 34,145, 8, 65, 65, 65, 56,119, +238, 28,222,121,231, 29,232,116, 58,164,167,167,127,167,211,233,198, 68, 68, 68,168,189,144,108, 29,178,247, 22, 19,208, 20,138, +231,225,195,135,235,156,223, 80,144, 88,100,100,228,112,147,201, 4,171,213,138,131, 7, 15, 66, 32, 16,192,108, 54,195,104, 52, +130,101, 89,231,123,108,177, 88, 96, 50,153,184,119,218,107,152,120, 67, 46,255,133, 11, 23, 58,189, 0,209,209,209, 40, 43, 43, +107,180, 34,202,173, 10,240, 33,118, 68, 11, 32,210,221, 1,151,233, 0,159,144,158,158,142, 23, 95,124, 17,131, 6, 13,114,122, + 64,184,244,217,131, 6, 13,194,169, 83,167,208,166, 77, 27,159,100,238,219,183, 15, 35, 71,142,236,146,146,146,114,158, 35,127, +199,248, 25,181, 97,195,134, 75,245, 3,122,249, 42, 20, 13,253,150,143,222, 39,114,248,240, 97,105,106,106,170,122,200,144, 33, + 24, 50,100,136, 26, 0, 78,157, 58,133,156,156, 28,190,207,225, 23, 0,193, 0,214, 43, 20,138,105,238,148, 0,133, 66,241, 12, +128,143, 29,155,139, 20, 10, 69, 47,165,210,123,137,250,191, 50,184,106,128,153, 75, 95,186,105, 10,224, 47, 27, 3,112, 39, 42, + 1, 51,102,204,160,139, 22, 45,186,201, 21,232, 15,249, 63,250, 76,211,206,211,233,245,250,155,130,252, 56,171, 95, 36, 18,225, +202,149, 43,183,149,252, 93,173,127, 87,203,109,218,180,105, 26,141, 70,211,228, 94, 0, 95, 60, 39, 51,103,206, 52, 0, 8, 9, + 13, 13,197,107,175,189, 6,145, 72,228, 60,158,156,156, 12, 0,136,136,136,192,196,137, 19,177,127,255,254,189, 19, 39, 78,252, + 67,174,211,181,189, 93,231,255,221, 33, 54, 54,182, 78,165,198,134,214, 17,155,205,102,104,181, 90,212,214,214, 34, 44, 44, 12, + 65, 65, 65,176, 90,173,160,148,194,102,179,193,108, 54,195, 98,177,192,102,179,185, 42,244,215, 61, 93,103, 81, 81, 81, 29,235, +190,254,116, 64,253, 0,193,198, 66, 46,151,107,124,140, 69,145, 52,116,160,129,216, 0,175,120,231,157,119, 48, 97,194, 4,116, +237,218, 21, 33, 33, 33,144, 74,165,208,106,181, 8, 13, 13,133, 78,167,195,234,213,171,193, 48,190,197, 23,142, 28, 57,178, 99, + 74, 74,202,249,121,243,230, 97,243,230,205,120,232,161,135, 0,160,221,190,125,251,174,250,211, 78, 14,133, 2,220,152,197,141, + 85,190,146,191,171, 39, 96,195,134, 13,178,169, 83,167,170, 1, 96,195,134, 13,178,202,202, 74,141, 15,253,217,172, 80, 40,102, + 0, 88,235, 65, 9, 72,112,249,220, 25, 64,127,216,151,164, 6,224, 66,252, 13,225, 47,153, 9,112,216,176, 97,178,166, 8, 8, +244,215, 74,119, 29,144,151, 44, 89,210,104,242,231, 48,120,208, 64,236,217,171,198,186,189, 33, 78,165, 32,239, 92,159, 70,221, + 99,108,108, 44,138,138,138,144,157,157,141, 78,157, 58, 97,205,154, 53,126, 88, 93, 84,202,125, 74, 75, 75,107, 18,242,231,172, +255,178,178, 50, 89,253, 99,163, 70, 43, 88,140, 99, 0, 0, 32, 0, 73, 68, 65, 84,141,146,101,103,103, 59,207,105, 10,228,228, +228,168,249,122,159,116, 58,221,239,176,207, 11,179, 27, 54,108,192,234,213,171, 1, 0,235,215,175,135, 78,167,227, 78,179,158, + 58,117, 10,173, 91,183,190, 45,239,128,107,180,191, 59,229,140,111,153,230,162,162,162,131, 54,155, 13, 58,157, 14,215,175, 95, +119, 6,142, 26, 12, 6,212,212,212,160,170,170, 10,149,149,149, 48, 26,141, 48,153, 76,176,217,108, 0,144,235, 73,102,125,114, +119, 23, 72, 90,127, 85, 0, 95,168, 84, 42,105,253,123, 86,169, 84,190,246,147,144,166,126, 30,107,214,172,129, 84, 42, 69, 72, + 72, 8, 78,156, 56, 1,141, 70,131,208,208, 80,188,254,250,235,216,191,127, 63, 94,126,249,101,159, 20,128,145, 35, 71,182, 75, + 73, 73,185, 48,109,218, 52,124,243,205, 55, 28,249,119, 0,112,213,147, 37,207, 71, 9, 88,178,100, 73, 83,144, 63, 0, 72, 57, +242, 7,128,169, 83,167,170, 71,143, 30, 77,125, 28, 67,205, 0,184,117,138,235, 21, 10, 69,253, 64,137, 51, 46,159, 75, 0, 28, + 13,208,190,203, 56,176,240,253, 58,177, 0,245,241,151, 9, 2,108,106,242,119,172,119,109,180,229,198, 77, 7,204,152, 49,195, +111,242,127,244,153,157, 24, 60,232,134,235,102,211, 55,223, 98,211, 55,246,207,123,246,170,129, 49, 50, 0,190, 45, 3, 84, 40, + 20,136,141,141, 5, 96, 15, 6, 60,124,248, 48,118,239,182,199,172, 29, 61,122, 20,163, 71,143,246, 65, 26,209, 0, 55, 2,255, + 26, 27,169,191,110,221, 58,169, 59,235,191, 62,154,202, 11,192, 41, 18, 82,169, 84,230,237,220,232,232,232,113,233,233,233,187, + 38, 78,156,136, 83,167, 78,225,244,233,211,120,231,157,119,172, 0,132, 6,131, 1,233,233,233,112, 28, 19, 22, 23, 23,227,241, +199, 31,247, 42,243, 86,196, 0,112,150,116, 86, 86,150,211,139,197, 17, 35,247,220,249, 32, 38, 38,166,192, 96, 48, 12, 55,155, +205,184,118,237, 26,130,130,130, 32, 20, 10,157, 30, 0,189, 94, 15,131,193, 0,147,201,132,202,202, 74,110, 62,255,162, 39,153, + 28,185,115,211, 0,177,177,177,168,239,173,112, 23, 23,192,135,252,185, 28, 0,245,247, 53,166,127,112, 86,191, 27,139,223,202, +119, 12, 45, 44, 44,196,169, 83,167, 96, 48, 24, 16, 31, 31, 15,131,193,128,172,172, 44, 76,157, 58, 21,155, 55,111,134, 64, 32, +224,173, 0,196,196,196,116,228,200, 63, 63, 63, 31,111,188,241, 6, 0,116,158, 49, 99,198,229,181,107,215,146,125,251,246, 53, +106, 12,229, 60, 1,141, 33,255,216,216, 88,202,245,179, 35, 71,142,160,160,160, 64,150,154,154,170,238,217,179, 39, 68, 34, 17, +117, 9, 12,244,219, 19,160, 80, 40,230, 2,152, 0, 96, 50,128, 54,176,199, 0,252,173,221,255,192,141, 85, 0,238,130, 0,111, +203, 42,128, 63, 42, 8,240, 78, 35,255,250, 74, 64, 99, 44,127, 79,219,123,246,170,253,121, 65,111,152, 59, 33, 33,232,221,187, +119,157,227,135, 14, 29,242, 73,222,228,201,147,157, 10, 64,118,118, 54,178,179,179,235,172, 10,240,229,254,215,172, 89,163, 6, +128, 29, 59,118,184, 37,207,233,211,167,107,214,172, 89, 3,128,223, 18,166,134,146,254,112,138, 6,165, 20,163, 71,143,150, 77, +155, 54,205,107,223, 73, 73, 73,217,173,213,106,199, 30, 56,112, 96, 79, 76, 76, 12, 78,159, 62, 13,157, 78, 39,140,136,136, 64, + 74, 74, 10,180, 90,109,241,129, 3, 7,186,196,196,196, 96,230,204,153, 94,239,215, 93, 30, 0,127, 99, 0,234,191, 91, 74,165, +146,200,229,114,168, 84, 42, 90,127, 90,134,239,243,136,139,139,123, 69,163,209, 60,103,179,217, 80, 85, 85, 5,139,197,226, 84, + 86,106,107,107, 65, 41,173, 19, 24, 40,151,203, 31,115, 16, 35,111,200,229,114,200,229,242, 58,203, 2,125,157, 2,112, 37,122, +185, 92,174,169, 63,182,184, 42, 5, 77, 8,222,227, 39,183,212,239,133, 23, 94,128, 70,163,129, 76, 38, 67, 97, 97, 33,154, 53, +107,134,146,146, 18,222, 10,192,161, 67,135, 72, 74, 74,202,133,199, 31,127, 28,251,246,237,195,235,175,191, 14, 0, 81, 51,102, +204,184,212, 20,228,239,170, 4, 52,198,242,231,198,151,162,162, 34, 20, 20, 20, 16,135, 33, 40, 75, 77, 77, 85, 71, 71, 71, 67, + 42,149, 82, 62,129,128,245,148,128,105, 0,214, 59,148,128,131, 0, 20, 0,164, 74,165,242, 10, 2,104,186, 14,220,212,217,248, +220, 5,252, 44, 93,186,180,193,253,183,147,252,103,204,152,113, 75, 82,134, 54, 70,230,133,139,222,251,119,112,176,111, 94, 75, + 79,243,195,254, 64, 46,151,203, 18, 18, 18, 52,123,246,236,161, 27, 55,110,172,163, 8,212, 39, 37,190, 50,211,210,210, 26,212, +108,184,164, 36,190, 36, 6,106, 72,225,148,201,100,188,200,159, 67,100,100,164,115, 94,255,196,137, 19,255, 72, 79, 79,255, 47, +231, 17, 40, 46, 46,238,242,234,171,175,202, 8, 33,188,228,221,138, 60, 0,245,219,217,221,252,183, 15, 74,169,126,244,232,209, +139,183,111,223,254,166,213,106, 69, 69, 69,133, 51, 6, 0, 0,174, 93,187,134,138,138, 10, 80, 74, 57,171,221,167,201,118,110, +254,191,254,178,191,250,113, 2,124,201,223,245, 57,223,105, 75,121, 57, 37,224,165,151, 94, 66, 78, 78, 14, 38, 78,156,136,247, +222,123, 15, 11, 22, 44,128, 80, 40,132, 68, 34,241,246, 92, 9,165,148,157, 53,107, 22,254,251,223,255, 98,213,170, 85, 0,208, +105,223,190,125,151, 28, 22,187, 95,157,201,101,218,170,201, 80, 90, 90, 10, 55,121, 0, 52,153,153,153,178, 49, 99,198,168,253, + 89,242,232,176,250,167, 1,216, 10, 96, 46,128,184, 0,249, 55, 12,119, 65,128,188, 20, 0, 95,146,114,248, 75,216, 77,141,166, + 32,255, 59,113,208,152, 59,119,174,236,228,201,147, 77, 42,211, 97, 13,169,155, 82, 38, 71,120,220,218,122, 0,206,100, 64, 44, +203, 98,211,166, 77,188,149,128, 23, 95,124,145,187,206,155, 98, 0, 24,134, 1,203,178,248,215,191,254,165,230, 75,158,158,228, + 53,118, 37, 65, 74, 74,202,255,180, 90,237,181, 3, 7, 14,236,224,107,245,223,106,111, 91,253,246,117,231, 98,247, 69, 9, 32, +132,188, 53, 97,194,132,236,181,107,215, 30, 23,139,197,224, 86, 5,176, 44,139,240,240,112,232,116, 58, 46,133,109, 8, 0, 27, + 95,131,192, 53,248,239,240,225,195,144,203,229,117,198, 19,111,227, 80, 81, 81, 17, 45, 42, 42,146,213,119,241, 55,114,201, 31, +128, 6,221,253,214,229,203,151, 75, 0,152, 97,143,159,226,254,124, 82, 2, 92, 19,255, 60,245,212, 83,206,207, 85, 85, 85, 94, + 95,179,184,184, 56,210,183,111, 95,250,213, 87, 95, 61,188,126,253,250,239, 57,178, 93,191,126, 61,124,141,250,231,112,233,210, + 37,103, 74,226, 38,130,102,219,182,109, 13,245, 41,205,222,189,123,125,170, 85,225,225,240,101,119,217, 74,255,238, 53, 73,184, + 85, 0,238,136,159,215, 42,128,166, 38,245,134,228,221, 41,202,195,157,220,113,250,244,233,163,233,211,167, 79,147,202,116, 12, +142,183,252, 94, 93,221,255,245, 95,234,134,150,157, 57,174,143,207,181, 17, 31,238,247,150,222,107,100,100,228,206,198, 68,250, + 55,101, 12,128,187, 62,236,201,219,227, 67,159, 63, 49, 99,198,140,102,187,118,237,122,183,164,164,228, 57,163,209, 8,155,205, +134,129, 3, 7, 98,200,144, 33,233,114,185,124, 33, 31,242, 7,128,188,188, 60,231,103,215, 88,147,188,188,188,155,182, 61, 33, + 58, 58,154, 56,188, 4, 50, 0,106, 78,153,112,153, 10,240,249,153, 76,153, 50,165,161, 67, 66,151,241, 82,124, 59,198, 21,165, + 82,201, 30, 59,118, 12, 31,127,252, 49, 1,192, 43, 41,207,179,207,122,206,201, 52,116,232, 80, 76,154, 52,137,247, 53,120,147, + 23,192,157,167, 4, 52, 68,254,110, 21,128,166, 38,193, 64,133,184, 0,220,245, 1,127,203, 87,254, 29,218,230, 14,254, 13,253, +184,113,227,230,194,238,126,245, 11, 7, 14, 28, 32,211,167, 79,191, 37, 10,173,191,153, 3,255, 72,101,177,177,232,215,175, 95, +147, 22,227,105,106,121,127, 7,163,236,207,164, 4,120,181,162, 6, 14, 28, 24, 24,136, 3, 8, 32,128, 0, 2, 8,224,111, 6, + 38,208, 4, 1, 4, 16, 64, 0, 1, 4, 16, 80, 0, 2, 8, 32,128, 0, 2, 8, 32,128,128, 2, 16, 64, 0, 1, 4, 16,192,159, + 16, 86, 0,108,160, 25, 2,240, 4, 97,160, 9, 2, 8, 32,128, 0, 2, 99,123, 0,127,243, 78, 50,103,206, 28,191, 35, 46,221, + 69,117,123,146,231,109,253,177,175,242,154,250,250, 2,242, 2,242,254,238,242,126,126,165,216,239,129,101,208,187, 93,112,171, +229, 29,126,217,127,121,177,239,221, 44, 47, 45, 45,141, 0, 0, 33, 68,106,177, 88,112,238,220, 57,181,217,108,134, 80, 40,196, +197,139, 23,241, 88, 88, 87,236, 44, 40,128,241,238, 78,136,139,139,147, 9, 4, 2, 80, 74, 53, 0,144,145,145,113,203,159, 7, +119,125,174, 32,132,244, 1,208,230,248,241,227,219, 58,116,232,192,104,181, 90, 73,135, 14, 29,222, 9, 14, 14, 94, 9,224,146, + 99, 57, 41,147,145,145, 97,243, 32,175,185,195, 91, 96, 32,132, 80, 0,184,112,236,127,159, 43, 70,150,164,172, 43,136, 57, 39, +108, 51, 46,174, 89,243, 22, 53, 0, 40,165, 84, 8, 32, 34, 35, 35,227, 66,224,125,187,179,229,221, 82, 45,145,111,182, 45, 95, +179,191,249,147, 50,183, 98,245, 55, 82, 97,100,152,250,236,233, 51,178,187,130,154, 33,244,217, 25,154, 59, 73,203,106, 40, 31, +121, 96,137,203,237,199,230,205,155,165,219,183,111, 87,167,191, 98,223,254,110,223, 72,204,152, 49,131,215,115,217,151,123, 80, +202, 16,162, 62,117,242, 36,116, 58, 29,186,116,233,130,102,205,155, 35, 49, 97, 28,239,231,186,123,247,238, 58, 47,110,118,118, +182,199, 90, 10,217,217,217,126,247, 27,174, 80, 83, 70, 70, 70,227,250, 93,146,214,241,129, 2, 32, 64, 86,164,255,178, 98,151, + 3,209, 79,216, 63, 23,173, 6, 14,207,111,252, 67,157,124,189,238,245,101,183,226,245, 53, 66, 8,213,235,245,178, 93,187,118, +169,139,138,138,144, 36,106,137,118,157, 90,163, 86,111, 68,176,193,138, 17, 11,158,196,168,137, 83,177,245,139, 12,108,217,179, + 71, 61,110,220, 56,217, 29,208,133, 79,219,108,182,246, 69, 69, 69,236,128, 1, 3,196, 49, 49, 49, 56,114,228,200, 43,181,181, +181, 19,122,244,232, 33, 39,132,104, 41,165,222,166, 2,170, 93, 55,172, 86, 43,243,107,193,207, 61, 58,206, 26,132,127, 13,237, +219, 58,111,215, 7, 27, 55, 29,149,254,210,163,223,152,247, 28,242, 46, 58, 20, 6, 54,224,105,248,155,185,137,124,205,223,239, + 75, 30,124, 95,201,223,182,110,155, 52,190,117, 71, 53,137,138, 70, 97, 77, 5,218,119,232,170,182,176, 54,156,252,100, 13,202, +186,180,150, 13,157,120, 63, 47, 69,224,176, 90, 65,123,117,231,182, 4,248,118, 23,139,125, 63, 81,164, 78, 3,122,117, 7,230, + 47,105, 28,113,115, 5, 74, 26,155,157,204,157, 50,209, 84,114, 27,131,212,212, 84,138,197, 4,228,173,134,207,161,148, 2,139, + 9,166,252,158,116,199,172,181,190, 65,254,212, 65,254,163,176,127,255,126,204,152, 49,195,235,119,239, 30,176,139,246,233, 51, + 4, 89, 89,151,113, 40,215,158,176,230,244,201, 83, 0,128,217,255,252,134,158, 58, 51, 89, 22, 42,225,247, 92, 18, 18, 18,216, +221,187,119, 51,217,217,217,216,187,119,175,199, 66, 76,254,164, 80,245,244,222,166, 41, 20, 52,195, 15,133,130, 75, 23,222,232, + 84,198,209, 79,212, 45,182,211, 20, 10,128, 75, 59, 57,170, 19,242,194,217,179,103,161,217,184, 81,253,150,124, 10, 6,206,120, + 10,226,182, 17,128,208,145,236,143,165, 0, 43, 2,107,162,184,255,137, 84,148,124,244, 62, 14, 30, 60,168, 30, 62,124,184,140, +243, 2,220, 38,216, 24,134,105,211,170, 85, 43,104, 52, 26,225,128, 1, 3, 48,116,232, 80,230,202,149, 43,131,126,253,245,215, + 99,119,223,125,247, 96, 66,200, 21, 7, 89, 51, 60,219,174,217,216, 49, 9,209,239, 45,219,204, 44, 76, 62,218, 34, 46,113,142, + 44,110,152,106,228,130,143, 47, 62, 16,115,207,204, 88, 66, 72, 53,236, 49, 6, 76, 67,253,204, 53,177,149,183,126,212,104,133, + 52,128, 58,168,159, 0,168, 62,252, 42, 6,228, 58,128, 12,156,217, 31,115, 70, 60,195,128,103,229,190,250, 74,128, 66,161,160, +177,177,177,200,204,204,164,174,101, 75,125, 34,214,156,195,210,233,131,226,213, 98, 27, 11, 27, 40,130, 43, 66,112,229,218, 53, + 92,169,174, 68,183,160,102, 48, 21, 94, 82, 31,218,178, 93, 54,140,135, 18,208,171, 59,112,242, 44, 3, 74, 37,176,145, 32, 60, +156, 96,193,164,113, 70,220,136,161,105,124,170,132,198,146, 52, 71,252, 11, 23, 46, 68, 65, 65, 1, 0, 96,219, 73, 17,106, 45, + 22,181,226,159, 67,124, 82, 4,124, 81,226, 28, 41, 94, 61, 63,151,197,246,195,177,177,177, 13,231,111, 95,236,223, 59,190,245, +179,203,210, 45,191,190,225, 84,120, 38,244, 95, 44,123,240,153, 14,141, 30,112, 55,111,222, 44,221,182,109,155,154, 97, 24,188, +240, 46,156,213,207,248,212,193,136,136,248, 81, 26, 55, 44, 13,192, 22,140, 28,249, 81,157, 99,211,167, 3,247,223, 15,220,143, +108,245,242,143,192, 75, 9,224,200, 95,163,177,159, 58,117,234, 84,103, 97, 37, 95, 8,204,147,229,207,165,100,118,189,191,180, + 52,255,200,191,201, 16,187, 12, 0,176, 98,197,138, 27, 10,192,224,116,224,200, 11,183,229,114,246,238,221,139,149,147, 82,209, +109, 76, 2, 32, 48,129,136, 24, 16, 33, 3, 34, 16,129, 82, 2, 86,111, 5,181,217, 64,205, 54, 60,249,196, 83,120,234,245,185, + 56,219,182,173,186,123,247,238,183,211, 19, 64, 10, 10, 10,226, 59,117,234, 36, 46, 42, 42, 66, 78, 78, 14, 78,158, 60,137,132, +132, 4,196,199,199,183, 95,181,106,213,219, 83,166, 76,121,210, 7, 5, 64,176,127,207,215, 95, 62, 50,208,208,246,112,181, 0, +211, 23,215,224,222, 65, 31,226,153,121, 83,133, 31, 44,172,232,182,240,131,181,211,163, 7, 77, 87,162,129, 52,200,174,132,238, + 58,166,167,165,165, 81,119,251,155,186, 32, 92, 0,183,192, 3,224,250,144,214,237, 88, 91,209,253,174,238,225,138,183,158,100, +231,140,120,198,151,106, 78, 36, 51, 51,147,114,105, 73,185,255, 21, 10, 5, 77, 74, 74,242,205,170,222,113, 80, 58, 62,166,175, + 90, 92,107, 69,240, 7, 47,194,106, 48, 67,242,194, 18,132,137, 37,168, 21, 25,161,175, 53, 34, 24, 4,166, 11,101,234,202,202, + 74, 89, 88, 88,152,199, 65,248,228, 89, 32,115, 61, 11,192,224,248, 3, 70,222,195, 96,210, 56, 2,215, 64,218,212,105, 64,230, +122, 63, 60,166, 73, 73, 50,199,125,250,101,173,115,228,207, 17, 63, 0, 40,247, 91, 96, 52,235, 1, 0, 99, 23,238, 70,214,210, + 4, 53, 0,222,242,207,190,127, 22, 34, 82,120,163, 35,144, 82,144, 86,189, 92,182,203,208,250,159,252, 82,132,146,183,236,228, +239,169,198, 60, 81,100, 81,251, 57,252,172,255, 35,219, 44,210,204,205,207,170, 41, 40,222,155,247, 29,134, 73, 99,176,238,179, +125,248,207,174, 52,245, 54, 5,197,156,127,188, 33, 27, 56,178,189, 95,138, 64, 77,177,130,142, 25, 0,100,125,117, 28,148, 82, + 52,111,115,183,147,252, 87,174, 92,233,241,250,244,181, 42,105,106, 82,123, 53,240, 41,128,239,112,232, 16, 48,108,216,141,227, +111,191,125,227,243,243,207,101,171, 51,254,211, 83,198,176,157, 60, 94, 39, 71,254,163, 71,143, 6,203,178,248,228,147, 79,154, +236, 5, 87, 40, 20, 78,242,175,171, 20, 40,104, 70,134,231,119,142,153,162,171,163,254, 18,199, 63,108,146,155,243,136,227, 68, + 98,255, 48, 96,192,205,115,236,204, 84,157,211, 43, 15, 0, 44,155,140,121,243,230, 57,143,207,155, 55, 15, 43, 86,172, 0,211, + 99,214,141, 95,117,156,239, 78,158,112,170,251,235,179, 90,221,156,199,227,250,106,107,107,209,174, 75, 87,128, 53,131, 9, 2, +136, 80, 0,107,117, 37,106,139,206,225,218,197, 82,116, 28, 46, 5, 17,135,131, 88,204,128,128,193,210, 57, 11,144,144,249, 6, +230,207,159,223,164,131,178,183, 84,217, 46,100, 75, 40,165,225, 70,163,113,120,100,100, 36, 78,157, 58, 5,150,101,113,238,220, + 57,172, 94,189, 26,189,123,247, 70, 84, 84,212, 76, 0, 79,214, 35,107,182, 33,242,166,148,182,234,194, 28,146,182,239,156, 40, +174,200, 57,138, 74, 93, 16,254,187,213,138,237,121,255,195,115, 73,193, 66,161,129,141, 5,166, 55, 88, 7,225, 86, 20,183, 10, +192, 55, 52,212,119,220,121, 6,132,124,137,159, 82, 10,217, 43,163,145,153,163, 12, 79,133, 2,191,124,117, 20, 24,225,124,173, +120,129, 35,125,131, 97, 45, 0,130,218,218, 85,136,140, 84, 33, 43, 43, 11,190,164,241, 28, 26,212, 66,221,166,214, 6,201,226, +167, 96,187,174,133,245,210,117, 8,197, 34,132, 16, 1, 66,137, 0,161, 2, 33, 34, 69, 18,232,170, 43,112,121,239, 65,117,216, +164,251, 60, 14,116,238, 72,125,223, 79,172, 67, 1, 0,150, 45, 34,160, 4,176,135,199,248,222,193, 29,164, 44,203,202,202, 82, +103,101,101,249, 53,133,224, 74,254, 16, 10, 80,116,217, 62,248,149, 92,173, 69,231,182, 18,244, 72,222,130,172,213, 19,213,124, +221,235, 34, 82, 8, 33, 41,133,128, 92,135,141,182, 66, 80, 27,130,208,105,151,192,178, 90,212,214,102,193, 86,240, 47,223, 60, +185, 60, 42,183,249, 82,226, 85,185,249, 25,117,124,228,171,248,228,187, 89,104,198,116, 6, 0, 60,245,108, 79, 12, 24, 26,141, +181,159,230, 96,229,255,222, 84, 43, 71,250,231, 58, 36, 4, 80, 60,127,204, 57,232,221,123,239,189,216,183,111,159, 87,242, 7, +128, 25,211, 68,106, 96, 47,128, 99,168,184,218, 12, 61, 58, 3,159,127, 94, 3,181, 26,232,209, 3,136,142,182,139,168,184,218, +204,254, 50,246,255, 93,253,219,175,157,136, 39,242,223,187,119, 47, 88,150,117,146,244,134, 13, 27, 26, 77, 32,174,219,245,201, + 31, 0,188,145, 63, 0,100, 40,149,132, 2, 82, 2,104, 82, 83, 83, 27,236,248,172,203,160,175,204,204,148, 17, 2,172,252,108, +229, 77, 49, 47, 43, 51,148,174,254, 21, 41,165, 84,253,225,135, 31, 58,119,124,248,225,135, 88,177, 98, 5, 50, 50, 50,234, 86, +145, 35,144,186,147,151, 97, 79, 97, 43,163,148,106,158,124,242,201, 6,175,207,234,226, 69,201,252,252,115, 25, 33, 64,198,202, + 12,181, 59,242, 18, 54,111, 14,136, 4,176, 25, 42,240,251,246, 61, 88,187, 49, 27,159, 93, 58, 7, 0,200,127,179, 5,122,140, +186, 31,166,146, 11, 56,254,235, 97, 28, 61,119, 26,149, 87,174,224,216,177, 99, 77, 86, 88,107,245,234,213, 82,126,125,152,132, + 81, 74,123, 21, 20, 20,124,240,218,107,175,245,253,224,131, 15,196,102,179, 25, 2,129, 0,205,155, 55,135, 94,175, 71,126,126, + 62,162,163,163,185,186, 5,158,172,255, 80, 66, 8, 75, 41,141,172,184,120,224,167, 55,191, 44,137,252, 98, 94, 7,104,245, 98, +136,133, 12, 58, 70, 72,112,229,186, 25,138,127, 91, 49, 96, 72,108,104,103, 47,158,132,180,180, 52,202, 41, 2,174,125,177,161, +207, 1,220,122,112,228, 95, 95, 57, 96,188, 13, 34, 92,189,239, 58,110,206,196, 25, 62, 95, 64,102,102, 38,181,147,255, 58, 39, +249, 75,126, 58, 15,195,206,187,234, 28,247,106,185, 42,215, 73,195,180,213, 96,197, 66,152, 15, 31,135,233,247, 34,212,238,218, + 7, 24, 77, 16, 83,138, 16, 8, 32, 4,129,137,181, 66,107,170,197,103,187,183,122,149,185,108,145,221,186,119,133,125,155, 51, + 87, 40, 78,157,161,152,191,196,255, 62, 43,151,203, 53,174,110, 47,149, 74,197,235, 69, 87,169, 84,206,218,218, 28, 30, 91,113, + 17,123, 14,235, 80,114,181,214,169, 4, 20, 94, 52, 2,242,141, 80,169, 84,188,220,145, 66, 98,175, 28, 38,170, 62,138,208,208, + 51, 8,146, 84,131,101,181,176, 88, 14, 67, 32,136,134, 89, 95,126,219, 58,235,158,111,143, 73, 1, 82,135,252, 47,159,162, 24, + 60, 81,128,103,223, 73,192,189, 9,125, 1, 80,199,121,190, 97,221,186,117,244,133,119, 9,154,181,238, 15, 10, 32,113,210, 28, +236,223,191,159,215,119, 89,230, 2,109,211,230, 55, 39,249, 87,151,219, 75, 48, 15, 24, 96, 39,127,174, 16,160,253, 88, 48,170, +203,131, 17, 25,114,217,163,204,201,147, 39, 67, 38,147, 97,204,152, 49,152, 58,117, 42, 4, 2,193, 77,127,174,251,249,194,221, +123,235,151,178,228, 66,196,132, 16,231, 95, 67,251, 8,160, 1,133,166, 1, 89, 55,222,175,212, 84,181, 59,203,121,222,188,121, + 72, 77, 77,173, 75,168, 13,200,251, 78,169,196,177, 99,199,212,132, 16, 41,128, 58,109,230,244,103,215,219,231,233,250,196,148, +130, 9, 9,130,229, 74, 49,148,175,190,138,213,250, 10,232, 70,199, 57,143,127,241,191,213,120, 99,193,108,196,204,127, 12,111, + 29,221,139,141,186,115, 72,120,240, 65, 68, 71, 71,251, 60, 5,176,122,245,106,169, 66,161,160,171, 86,173,170,211,135,243,242, +242,212,158,166,161, 8, 33, 34, 66,200,144,163, 71,143,150,228,228,228,104, 94,120,225,133,184, 79, 62,249, 68, 82, 83, 83,227, + 44,211, 92, 91, 91,139,102,205,154, 21, 78,153, 50,165,231,136, 17, 35, 58,123, 81, 36, 24, 66, 72,151,163,185,155,202, 78,239, +156,127,126,254,203,233,237,183, 44,238,128,223, 75,133,168,172, 17,128, 37, 64,121,141, 25,180,101,247,218,231, 95, 89,210,247, +129,135,255,225,117, 58, 33, 35, 35,131,112, 99,157, 82,169,244,250, 57,128,219, 67,254,110, 61, 0,174,196,207,103,156,241,197, + 18,185,225,106, 91,229,214, 59, 80, 39,206,160, 1, 55, 70,223, 86,109,213, 90,106,129,184, 92, 11,201,119,123, 65,132, 12, 80, +107, 6,173,214,131, 88,173, 16, 1,176, 81, 22,181, 54, 43,170,173,102,128,245, 62,135,202, 5,249, 45, 91,212,240, 48,104, 15, + 18,108,252,128,170, 84, 42, 9,231,210,231, 99,173,223,100,253, 3,248,250,153,246,117,182,135,188, 84, 4, 17,189, 14, 11,105, +133,172,172,172,189,124,189, 0,146, 26, 53, 34,223,250, 31,174,189,144,134,235,218, 96,116,176, 28,135,205, 86, 4, 0, 40,254, +165,221,109,235,176, 27,119,124,172,158, 61, 78, 89,135,252, 57,196, 69,188,138,225,125, 39, 35, 62,242, 56, 54,238,120, 71, 61, +118, 18,255, 65,100,237,218,181,244,199, 31,127, 68,121,249, 88,180,108,185, 7,205, 90,245, 3,165, 20, 12,195,240, 10, 68, 42, + 41, 1,138,138,142,113, 19, 9,128,164, 6, 90, 61, 48,116,168,125, 79, 97, 33,240,233,167, 64,117, 21,160,175, 1,106,244, 64, +104, 68, 21,175,107,107,104,174,255,236,217,179, 0,128,119,223,125, 23, 0, 16, 19, 19,211,100,110,102,215, 62,201,231, 59,115, +231,206,133,171,197, 94,159,184,125,128, 20,184, 49,247,239, 10,206, 11,224, 56, 71,227, 73,200,172,168, 24,156, 62,126, 2,165, + 17, 17,106,134, 97,240,220,115,207,225,163,143, 62,242,251,250, 70,154,194, 65,217, 26,204,126,119, 17,250, 79,158, 12,229,187, +239,130, 97,110,240,156,178,240,216, 13, 15,225,190,125,216,189,123, 55,206,157, 59,231,115, 16,224,234,213,171,165,185,185,185, +106, 0,200,207,207, 87, 51, 12, 35, 75, 78, 78,214,172, 90,181, 74, 74, 41, 69,124,124,188,204,104, 52,170, 27, 80,236, 44,121, +121,121,253,103,204,152,209,162, 91,183,110,216,190,125,187,161,178,178, 82,104, 52, 26,237,222, 14,199,252,199,248,241,227, 99, + 8, 33,193,148, 82,163, 27, 49,140,139, 60,166,232,212, 47, 43,222,248, 87, 74,179,150, 61,178,240,115,214, 19,248,237, 2, 65, +201, 85, 33, 64, 25,152,204, 22,104,105,203,210,167,103, 61, 21, 71, 8, 41,165, 77,160, 85,242,137,179, 9,224,143, 65,131, 83, + 0, 57, 57, 57, 55,237,171, 40,213,249, 76,118,174, 30, 0,251, 20,128,189,255, 72,126, 58,143,160, 99,165,176,133,219,173,168, +250,115,200, 13,173,107, 60,113,177, 4,134,160, 96, 68, 91,173,232, 24,220, 12, 33, 34, 49,136,197, 2,176, 20, 86,155, 13,213, + 54, 51, 12, 54, 43, 76,212, 6, 27, 40,168, 15,157,109,254,146, 27, 74,128, 61, 46,224, 6,233, 47, 91, 36, 64,250, 34,130, 23, +150, 88, 27,221,232,114,185, 92,195,149, 46,229,131,133, 89,246,118, 95,154, 20,225, 36,124,167, 43,159, 94,135, 8,128,144,234, +240,213,236, 8,235, 99, 42,126,113, 29,162,171, 63,193, 6,187,155,250, 3, 97, 24, 30,187, 90,140,130,127,119, 68,104,187,222, +168, 44, 45,197,149,243,151,110,107,199, 28, 48, 52, 26,122, 71,119, 51, 4,159, 64,136,177, 15,190,121,211,226, 60, 62, 66,222, + 23,185, 27,125,179,252, 39,141,250, 17,223,125, 39, 71,120,174, 10,203, 23, 1,207, 47,161, 24, 53,106, 20,239,101,127, 93, 59, +118, 34,221,187,215,213, 2,183,110,181, 7,254,173, 91, 7,244,232, 65,177, 98, 5,193, 91,111,213,216, 21, 4, 0, 61,122, 70, +224,133,231,249, 93, 35,103,165, 78,158, 60, 25, 27, 54,108,168, 99,201, 38, 38, 38, 54, 72,110,254, 42,162, 62,122,240,100, 43, + 86,172, 80, 55,164, 0, 44, 91,182, 12,153,153,153,188, 44,225, 39,159,124, 82,205, 69,254,187,195,243,207, 63,143,229,203,151, +171, 51, 51, 51, 61, 94,227,143, 39, 74,240,202, 91, 11, 48,107,241,191,240,178,217,140, 15, 63,252,176,193, 54, 90,182,108, 25, + 84, 42, 21, 8, 33,210,134, 8,123, 84,159,206, 88,245,197,167,136,157, 62, 29,111,190,249,166, 71,165, 97,222,188,121, 88,182, +108, 25, 62,255,252,115,141,175,109,159,155,155,171,230,130,229, 20, 10, 5,205,203,203, 83, 39, 39, 39,147, 67,135, 14,169, 9, + 33, 72, 78, 78,214,172, 92,185,178,193,239, 27, 12,134,240,173, 91,183, 98,236,216,177, 40, 44, 44, 12,209,235,245,176, 88, 44, + 96, 24, 6,102,179, 25, 73, 73, 73,196, 65,238, 70, 62,142, 45,147,201, 36, 62,188,105, 58, 70, 61,242, 22,118,230,156,197,185, +203, 2, 84,233, 25, 8,132, 64,169, 62, 24,207,189,180, 40, 30,192, 69,190,220,207,197,157, 0,252,166, 3, 2,184, 61,214, 63, +220,185,113, 56,215,140, 84, 42,133, 84, 42,197,175,191,254,234,252, 43,250,169, 24,149,198, 74,180, 28,234,251,186, 95,142,220, + 67, 66,102, 64,242,211,121,136,138,203, 65, 9,129,120, 86,121,157,227, 94,137, 75, 44,128,141, 2, 23,245, 21, 40,169,212,226, + 90,149, 14,149,181,181,208,153,141,184,102, 50,226,114,173, 1,165,181, 53,208, 90, 76,208,177, 22,152, 89,239,217, 48, 71,222, +227,102,192,115,137, 11,152, 61,181, 25, 40,196,160,190,149, 1,119,186,240,235,119,118,190,238,127,167,229,121,181, 22,123, 14, +235,234, 16, 63, 71,254, 65,108, 49,130,216, 98,188, 49, 94,136,146,146, 18, 51, 95,153,155,206,177,104,157,158,225,220, 62,167, +183,225,226,217, 82,156, 58,112, 28, 87,206, 87,220,246,142,187,238, 51,187, 2, 90, 85, 70, 17, 98,236, 3,233, 44, 33, 30, 89, + 44,114,254,165,111,156, 14, 2,194,123, 64,122,232,222, 28, 60, 49, 95,142,136,188, 61, 32,132,224,251, 3,246, 71,192,151,252, + 57,196,244,234, 89, 79,177, 0, 62,249, 4, 56,115,198,238, 9,120,243, 77,234,116,191, 83, 74, 17, 17, 17,225,125, 4,118,244, + 81,155,205, 6,155,205,134,119,223,125, 23,103,207,158,197,233,211,167,113,250,244,105,168, 84, 42, 44, 88,176, 0, 37, 37, 37, +183,243,145,104, 26,178,164,231,206,157,203, 89,117,188,200,144, 16,226,214,250,231,224,233,152, 43,246, 5, 85,128, 48,205,240, +159, 87,150,160,217, 86, 21, 82, 83, 83,225, 90,106, 88,209,163, 31,230,198, 14, 71, 72, 72, 8, 70,141, 26,133,215, 94,123, 13, + 42,149, 74,173,211,233,220,190,127, 95,148,158,198,229,190,125, 16, 21, 21, 37, 99, 89,182, 65,111, 7,231,169,240,215,243,226, + 26, 41, 31, 31, 31, 47,227,136, 18, 0,226,226,226,100, 94,218,110,204,168, 81,163, 90,148,148,148, 96,223,190,125,184,235,174, +187, 32, 20, 10,157,202, 98, 84, 84, 20,223,233, 8,214, 33,143,116,239, 53,104, 97,230,174,112,252,182,125, 49, 70,198,247, 70, +168,132, 65,104,136, 13,193, 65, 38,220,247,208, 20, 22,128,182,190,174,234, 77,185,228,238,143,207,116, 64, 0,183, 15,140,167, +135,168, 84, 42,155,207,157, 59, 23,115,231,206, 5, 0,243,219,105,111,195, 82,102, 69,112,176,196,175,100, 36, 73, 73,246,240, +225,144,241,103, 64, 5, 12, 94,251,198,224,180,254,249, 34, 36, 42, 74,102,109, 22, 2, 29,181,225,132, 94,135, 99,149,229, 56, + 94,117, 29,199,171,180, 56,161,215,226,140, 65,135,114, 83, 45,106,172, 86, 92, 50,232,157,191,233, 9,147,198, 17, 44, 91, 36, +192,178, 69, 2, 80, 8, 64, 9,131,212,105, 4, 79, 78, 19, 99,214,212,214,232,222,189, 45, 88,136, 0,248,118,203,156,171, 63, + 41, 41, 73, 86,127,159, 15,109, 38, 43,188,104, 87,228, 11,222,183, 7,209,237,124, 49,204,238,190,161, 58, 8,168, 30, 38,198, + 30,209,172,213,106, 67,146,146,146,124, 42,138, 30, 27, 27, 11,149, 74,133,117, 53,122, 24,205, 12,158, 88,255, 31,148, 73,130, + 97, 52,223,190, 50, 17, 19, 7,188, 33,203,213, 46,193,186,255,222, 48,241,191,121,211,130,184,136, 87,111, 40,148, 15,124, 42, +203, 80,102,240,202, 45,177,252, 85, 32,121,254, 88,132,231,169, 32,251,247,104, 48, 19, 0,141, 70,227, 87, 31,238,210,165,110, +244,248,152, 49, 64,120, 56, 16, 29, 13, 12, 27,208, 28, 18,177, 0, 2,230,134, 88, 73,112,176,215, 1,153, 97, 24,231, 92,255, +217,179,103, 17, 19, 19, 83,231,239,173,183,222,194, 91,111,189,133, 75,151,248,123,101,220,205,215,187, 34, 45,205,119, 11, 44, + 51, 51, 83,182,124,249,114,183,132,205,215,250,119,113, 61,223, 20,167,192,109,179, 44,191, 20,246,102, 66,192, 26, 76, 16,181, +235, 2,197, 59,239, 32, 57, 52, 28,225,154, 92,231,241, 89,255, 72,198, 27, 31,252, 7,133,203,190,198,235,253,199, 96, 74, 68, + 55,236,222,188, 25, 69, 69, 69,110,223,191,135,211, 20,232,219,175,159,140, 11,106,228, 20, 50,215,233, 25,119,251, 60, 88, 95, + 52, 45, 45,141,114,129,125,220,124,191, 43,201, 39, 39, 39,107,226,226,226,100,156,235, 63, 57, 57, 89,227,165,221,114, 68, 34, +209, 93, 15, 63,252,240,217,202,202, 74,232,116, 58, 4, 7, 7,163,117,235,214, 8, 15, 15, 71,120,120,184,183,198, 99,235,201, +179, 5, 5, 5, 25, 30, 77,251, 72,182,250,167, 33, 56,127,161, 10,109,195, 4,136,239, 73,112,119, 55,138,208, 22, 45, 42, 0, +216, 60,240, 70,160,222,192,159,212,250, 7,188, 47, 3,172, 81, 42,149, 65, 0, 66, 21, 10,133, 83, 11,236, 56,186,131, 95,154, +175, 82,169, 36,114,185, 28, 42,149,138,138,103,101,213,113, 69,242,205, 3,208,242,193,177,154,242,172,237, 48, 88, 77,168,210, + 27,112,214, 98,129,136,181, 59,234, 43, 45,181, 96, 41, 5, 5,176,253,234, 57,232,173, 22, 0,224, 49, 48, 17,204, 95, 82,183, +143,219,167, 2, 88,216, 96,194,239,103,170,177,106, 67,149, 79,247,235, 74,244,114,185, 92, 83,223, 11,224,170, 20,120,130, 92, + 46,215,100, 41,166, 64, 52,246, 51, 0,209, 40, 47,191, 17,156, 39,102, 47,195,204,180,199,211,253, 79,227,242,101,251, 64,172, + 84, 42,247,240,145,155,246, 77,102, 29,197, 43, 43, 43, 11,220,164,196,250,163, 7,125, 90,149,209,212,120,224,169,246,154, 45, + 10,138, 3,170,227, 0,128,225,125,237,153,241,254, 53,111, 49, 14, 30,239,139, 15, 54, 78,135,114,235, 83,106,229, 68,126, 4, +254,196,124, 57, 34, 35, 85,174,134, 44,180, 90, 57, 40,205,114,184, 42, 41,178,178,146,120,201,154,252,200,163,100,247,206, 93, + 20,176,187,254,101, 50,130,235, 23,194,160,215, 73, 96,172, 18, 99,253, 26,130,185,115, 41,138,203,170, 49, 44, 62, 14,211,167, + 78,227,101, 21,219,108, 54,231,124,191, 74,101,191, 86, 87,194, 47, 43, 43, 67, 89, 89,153,207,238,125,133, 66, 65, 25,134,185, +137, 84, 51, 50,148,196,143, 36, 64, 26, 74,105,157, 88, 0, 23,143, 0,111, 87,184,171,107,191,126,244,190, 55,183,127,125, 37, +199, 90, 93, 13, 81,171, 72, 8, 66,154,161,239,163,147,241,214,184, 4,188,194, 45,219, 27, 52, 24, 54, 99, 45, 68, 45,219,162, +127,156, 20, 93, 59,118,195, 71,191,231,162, 95,191,126,178,159,126,250,233, 38, 37, 32, 77,161, 0, 64,212, 0,240, 84, 90,154, +115,233,160,181, 30,217, 11,133, 2,128,222, 88,168, 72, 0, 12,112, 51,200, 14, 28, 56,144, 80, 74,157, 46,254,252,252,124,167, +139,223,245, 60,199,182, 87,242,119, 24,236,175,134,135,135,247,141,139,139,235,126,242,228, 73, 28, 57,114, 4, 54,155, 13,161, +161,161, 48, 24, 12,101,145,145,145,231,125, 49,250, 8, 33, 76,219,182,109,119, 63,244,208, 67,109,243,246,231, 99, 69,214,110, +180, 32, 98,244,108,107,194,153,235,161,184,183,167,229, 28, 0, 11,167,160, 57, 20, 74,155,167,103,226, 58,214, 5,166, 0,238, +108,240,153, 47, 54, 3, 48,187, 18,245,197,156, 75,192,116,223,201,223,149,108,220, 13, 90,124,149,128, 42,173, 78,102, 9,145, +168, 43, 25, 22, 87,106,107, 0,139, 5, 54, 74, 65, 0,252, 94, 83,129, 82, 67, 21, 40,165, 92, 18, 27, 30, 3, 19, 69,234, 52, +130,204,245, 55,250,228,201,179, 64,175,238, 86, 8,160,111, 20,249,187,118,118,127, 93, 94, 73, 73, 73,178,172,172,167,212, 64, + 1,180, 90,173,185,164,164, 68,184, 52, 1,204,194,221,163, 48,175,223, 65,167, 21,198, 87,169,112,231,117,169,191,205,145, 16, + 95,107, 14,139, 9,134,100, 22, 81,192,253,114, 63,103, 38, 64, 21, 40,159, 32,197,180,137,159,201,148, 91,158, 86,231,110,164, +136,143, 60,142, 17,242,190,216,191,251, 56,242,116,239,128,128, 64, 49,241, 83,222,247, 26, 25,169, 2, 33, 4,147, 38, 77,194, +231,159, 87,129, 51,138,237,255, 83, 71, 27,103,213, 25,144, 60, 76,193, 98,244, 24,153, 44,103,175, 90, 61,102, 12, 96,190,210, + 9, 23, 42,130,192, 58,102, 91,219,235,219,226,197,212,106,236,206,235,137,230, 29,123,242,186, 70,142,248, 47, 94,188, 8, 0, +184,114,229,138,211, 51,112,245,234, 85,231,192,234, 15,148, 74, 37,225, 18, 1,213,159,195,205, 80, 42, 9,159,124, 0,174,248, +252,243,207,235,196, 2, 44, 95,190,220,103,235,191, 62, 97,248, 11,137, 68,130, 43,197,231,209,173,123, 15,176, 86, 19,136,213, + 6, 97,243, 22,104, 62,120, 8,154, 13,186, 7,172,222, 10,155,193, 4,106,181, 1, 54, 22, 11, 87,126,128,169,211,167, 66, 34, +145,184,149,103, 93, 31,193,235,119,221,157, 23,251,158,251,115,227,227,227,101,121,121,121,106,110, 12, 24, 49, 98,132,219,182, +226, 65,254, 32,132,176, 0,118,244,236,217,115,208,199, 31,127,108,190,118,237, 90,109, 66, 66,194, 67, 5, 5, 5,175, 27, 12, +134,242, 86,173, 90, 41,250,244,233,163,245,161,237, 69, 0, 58,199, 13, 27,214, 58,109, 86, 26,206, 93, 60,167,125,124, 86,218, +200, 67,187,215,164, 95,174,214, 14, 31, 50, 58,129,109,219, 49,230, 17, 55, 94, 3,214,211, 88,224,202, 21, 13, 37,255, 9, 36, + 2,250,243, 40, 0, 13, 90, 23,254,144, 63, 71, 54, 92, 78, 0,127,148,128,110,138, 25, 26, 0,164, 84,185,154, 34, 88, 2, 29, +181,194,108,181,130,165, 44, 90,134,133,225,162,190,146, 95, 6, 59, 7,220, 45,239,187, 17, 3,224, 91, 38, 54,119, 46,254,198, +166,235,117,124,119,226,144, 33, 67,182, 44, 92,184, 80, 28, 25, 25,201, 94,190,124, 25,243,250, 93,174, 67,254,190,252,134,187, +246,247, 27,142, 44,127,245,147, 60,185, 59,135, 47, 6, 61, 32,208,100, 60,144, 65, 54,127,114, 73,186,237,232,155,234,220,141, + 0, 1,193,196, 1,111,200, 30,120,138,127, 2, 32,174, 47,217, 9,190,202, 49, 72, 1,238,120,103,117,186,221,121, 18,218, 57, +131, 0, 13, 23,215,152, 62,117,154,102,250,212,105,164, 92,247,177,212, 86, 93,173, 38, 2,192, 80, 27, 12, 82,109,133,144, 17, +194,192, 72,100,227,166,204,134,144, 18,175,215,153,144,144, 64,238,186,235, 46,122,171,222, 63,187,181,159, 65,210,210,210,168, +107, 68,187,171, 39,192, 71,113, 26,206,242,119, 81, 40, 52,183, 99,240, 26, 51,102, 12,158,222,152,137,183,170, 43, 48,112,244, +189, 96,218, 70,216,175,201, 66,237,169,123, 33, 2, 17, 8, 65,196, 2,124,158,177, 12, 45,198, 14, 65,247,238,221,255,208,212, +189,156,117,159,155,155,171, 30, 54,108,152,108,230,204,153,141,250,237,179,103,207,202,247,236,217, 83, 44, 16, 8, 54,143, 28, + 57,242,109,134, 97,174,197,197,197,229, 56, 45, 25, 23,143, 18, 33, 4,238,158,185,139, 39, 64,117,228,200,145,161, 95,173, 94, +195,136, 5, 65, 23, 38, 63, 54,121, 0,195, 48,186,123,239,159, 61, 1, 64,152,131,248,171, 1, 80,171,213,234,148, 87, 79,105, + 11,148,148,191, 3,193,199,253,239,151, 2,208, 20, 10,131, 39,242,241,101,128,147, 10,122,251,182, 0, 0, 32, 0, 73, 68, 65, + 84, 41,146,137,106,183, 74,202,158, 42, 84,235, 77,102, 88,109, 54,116, 31, 58, 24, 49,214, 97, 62,145, 97, 83, 6,163,112, 73, +127, 0,168, 57, 79,135,203, 84, 0,105,132,220,173,114,185, 92,168, 82,169,230, 47, 93,186,244,223, 46,202,197, 24,165, 82,233, + 83, 34, 18,135,167,160,201,146,151, 76,249, 61,201,209,142, 13,223,223, 20,149,202, 47, 77,255,193,103, 58,104, 30, 68,227,159, +143,157,220, 9,158,152, 63,198,153,167,156, 27,199, 86,167,239, 65,104,231, 12, 18,218, 57,201, 39,153,225, 45,158,213, 28, 40, + 6, 97,153, 11, 82,163,193, 94, 7, 32, 84, 34,215,132, 69,193,167, 21,163, 46,253, 79,228,208, 56,155,124, 94,149, 83, 2,154, + 66,150, 35, 22, 64,205,125,110,172, 60,127, 87,150,117,239,222, 29,237,158,123, 78,182, 98,215, 46,117,209,219,223, 33, 73,212, + 18,225,142,226, 61, 70,131, 21,115, 23,188, 12, 65, 72, 36,182,175, 81,226,215, 86, 4,227, 26,145,183,223,102,179,194,215, 24, +160,250, 74, 0, 31, 43,223, 75, 59,145,211,167, 79, 95,163,148,166,247,234,213,235,203,242,242,114,189, 80, 40,132,213,106,165, + 45, 91,182,116,122, 84,244,122, 61,196, 98,177,211,139,228, 65,222,168,252,252,124,176, 86,130,225, 35, 6,188,113,241,226, 69, +157, 86,171, 69,100,100, 36,219,177, 99, 71, 29,247,108, 42, 43, 43, 33,145, 72, 64, 8, 65, 80, 80, 16, 47,163,143, 83, 18,234, +127,174,239, 21, 13,224, 79,230, 1,184, 85, 74,129,223,196,152, 32,215, 32, 65,126, 71, 69,147, 58,148, 0,114, 11,230,209,109, +114,185,252,255,228,114,249,255, 53,197,245, 53,225,253,146,166, 56,231, 86,194,110,213, 3,142, 20,251,245,142, 37, 53, 74, 54, +195,118,210,132, 74, 58, 53,197,101, 90,110,101, 27, 52, 97,209, 21,141, 47,115,245, 94,148, 9,191,229, 80, 74, 73, 72, 72, 8, + 38, 77,154, 4, 71,249, 94,148,184,148,239, 61,176,103,183,179,124,239,216,184,177,112, 40,189, 13,254,222,231,186,247,200,147, + 17, 47,223, 76, 76, 60,171, 9,242, 80, 2, 26,141,123,238,185,199,100,181, 90,115, 0,232, 89,150,165,102,179,125,225,207,181, +107,215, 0, 0,205,154,217,151,246,114,251, 69, 34,145,199,246,123,224,129, 7, 56, 25,187, 88,150, 69,120,120, 56, 88,150,117, +174, 56,113,172, 98, 33,181,181,181, 20, 0,196, 98, 49, 8, 33,204, 31, 49,182, 7,224, 63,248,164,146, 6, 0, 50,112,224,192, +128, 38, 22, 64, 0, 1, 4,240,231,129, 21, 64, 45, 0, 73, 19, 27,113,222, 10, 6,241,174, 40, 24,192,159, 3,129,135, 25, 64, + 0, 1, 4,240,231,130, 16, 64, 51, 30,228,111,128, 61,136,187,169,248,128, 69, 96,217,223, 95,174, 35, 5, 16, 64, 0, 1, 4, +240,215, 67, 72,128, 47, 2, 8,120, 0, 2, 8, 32,128, 0, 2, 8, 32,128,128, 2, 16, 64, 0, 1, 4, 16, 64, 0,127,119,212, +113,233,204,153, 51,199,239, 8, 78,119,197,123,238,116,121,209,131,131, 16, 28,116, 5, 34,113, 5, 88,214,190, 44, 76, 32, 96, +192, 16,129,253,127,134,128, 16, 6,148, 8,237,107, 96, 97,197,150,109, 34, 80, 74, 17,201,180,132,143,215, 23, 4,160, 21,236, + 1, 60,213,176, 47,247,178,192, 49,167,246,103,108,191,128,188,128,188,128,188,128,188,128,188, 59, 83,158,207, 10,192,223, 13, + 63,238, 63,131,161, 67, 44,136, 8, 7,180, 58,130,159,127,149, 64,200, 8,113,255,120, 27,118,171, 91,131, 16, 6,132, 97, 32, +105, 14,140, 25, 90, 1, 64,136,123,227, 41,242, 11,132,118, 26,231, 1,245,193,253, 20, 0, 68,212,130, 97, 35,199, 20,159,254, +237, 39, 83, 89, 85,109,140,205, 80, 11,185, 92, 30, 14,160, 50,160,135,254,185,145,253,205,127,165, 61,186,119, 83, 95,187, 86, +219,168,132, 79,127, 34, 72, 83, 83, 83, 93,243, 0, 52,234,158, 83, 83, 83,253, 78, 7, 28, 64, 0, 1, 52,145, 7,128,195,154, +175,190,224,173, 77, 60, 49,115,150,215,151,181,169,229, 53, 37,242, 11, 68, 72, 76,176,225,215,223,130, 33, 22, 9, 33, 20, 8, + 33, 18, 81, 4, 9, 44,128,176, 57,132, 48, 98,104, 95, 43, 36,226, 32, 80, 0,237,219, 2, 15,222,207, 98,207,102,126,228,127, +230,247,211,184,171, 79,119,116,136, 10,199,197,226,147, 93,194,218,117, 67,171, 14, 54,252,240,253,247, 80,169, 84, 21,183,123, +125,188, 74,165,186, 63, 43, 43,107, 27,183,157,148,148,244,128, 92, 46,223, 22,120, 53,188,227,183, 95, 85,212, 90,123, 92, 54, +237,193,238,106,150, 45, 71,101, 7,163,250,228,177,141,168, 49,181,199,144,216,145,127, 89, 18, 75, 77, 77, 85,207,155, 55, 15, +132, 16, 94,101,123,249,128, 75, 22,211, 4,229,230, 3,104,164, 2,230, 17,148, 34,243,243,207, 27,124,222, 92,130, 31,215,108, +129, 92, 13, 1,151, 90, 2,206,231,236, 90, 25, 49,128,166, 5,151, 13,144,131,187,220, 0,119,148, 7,128,193, 31,219, 15,238, + 31,103, 1,133, 0, 66,129, 8,195,135, 17,180,105,205, 64, 40,100, 16, 36, 18,160, 87, 12,131,226, 11, 86, 12,141,101,208, 50, + 82,130, 31,246,182, 0, 0, 8,168, 17,246, 84,216, 54,175,228,255, 91, 65, 1,186,118,232,136,223,114,243,112,200,108,129,238, +186, 14,226,160,230,232, 61,104, 4, 6,140, 24, 7,245,150, 44, 0,252,114,227,223, 2,226, 31,147,149,149,181,103,225,194,133, + 40, 40, 40,224, 58, 76, 5,128,231,102,207,158,189, 53, 41, 41, 73, 46,151,203,247,252,229, 94,138,159, 85, 52, 72,168,133,144, + 49,163,182,214,134, 74,125, 48,238, 29, 53,197,167,246,223,152,253,149,180, 69,176, 22,255,152, 58, 24, 93,187, 60,168,110,209, + 34, 12, 22,171, 21,215,174, 93, 71,219,146, 11, 40, 60, 91,132,131, 7,180,116,248,136,135,252,122,174,153,153,153,212,101,112, +190,211, 6, 71, 41,112,163, 28,174,163, 58,160, 20,183, 41, 29,240, 31,248,190,208, 77,155, 54,221, 92, 79,225,182,145, 23,149, + 18, 16,208, 38,104,119, 90,242, 13,200,161,217,174, 28,239,200,146,233,168,134,228,130,217, 25,122, 12,157,250,177, 71, 69,238, +135, 31,126,112,110, 39, 38, 38, 98,199,142, 29, 30,183, 3,184,245,228,239,186,207, 85, 17,240,168, 0, 28,216,127, 8, 35,238, + 29,246,135, 93, 52,235, 67,254, 84,215, 84,146,254,102,159, 98,132, 2,232,180, 66,180,107, 35, 66,187, 54, 98,212,212,136, 32, + 17, 9, 97, 19, 6, 97,112,127,130,129,119, 11,192, 16,145, 61, 5,166, 72, 12, 17, 99, 2,145,136, 97, 53, 0, 86,232, 61,146, +255,254,189,123,208,173,125,107, 28,251,245, 24, 22,189,253, 70,157,235, 91,242,230,187,148, 17, 16, 12,142, 29,140, 31,118,236, +241,169,242, 30,203,178,210,130,130, 2,245,153, 51,103, 16, 28, 28,140,224,224, 96, 89, 98, 98,162,198,199,193, 76,150,149,149, +181,135, 35,126,151,206, 17, 14, 96,220,127,254,243,159,235,179,103,207, 86, 1, 72,144,203,229,170, 59,177,131,175, 90,181, 74, +154,146,146,194,251,190,191,222,176, 70,218, 47,166,185,186, 75,251, 90,132,181, 8, 2,195,132,192,104,180,162, 92,107, 68,142, +106, 5,149,180, 24,140, 97, 67, 71,241,234, 71, 34, 92,193,164, 7,238, 86,247,237,219, 27,151,175,232,112,248,231, 35,168,169, +209, 35, 44,172, 57,162,163,187,128, 17,136, 96,179,149,224,231, 95,246,211, 65, 3,239,253, 75, 89, 55,169,169,169,234,231,159, +127,222,185, 61,111,222, 60, 44, 95,190, 92,253,185, 7,171,208, 39, 50,186, 67, 61, 0, 14, 37,157,102,103,103,195, 93, 97,165, + 63, 18,174, 86,182, 82,153, 33,163,180,113, 74, 0,211,229, 81, 39,121,231,191,215,204,173, 25,214, 46,156, 65, 84, 36,243,167, +125,126,127, 87,184,146,189, 59,165,192,171, 7,224,192,254, 67, 0,208,104, 69, 96,255,115,133, 30,143,223,251, 81, 15,191, 7, + 11, 66,136, 95,213,246, 84,154, 54, 16, 9, 69,232,212,161, 6,213,213, 34, 28, 62,214, 9, 2,129, 0, 2, 34,128, 88,100, 69, +223, 30, 6,244,236, 33, 0, 1, 3,177, 40, 8, 98, 1, 65,236,221,102, 68, 70,176, 88,247,165,103,217,189,187,181, 69,241,217, +178,155,200, 31, 0, 22, 45,126,133,188,251,246,191,105,251,248,187, 17, 17,222,156,247,245, 26,141, 70,233,242,229,203,213,197, +197,197,117,244, 13,147,201,132,135, 30,226,111,109,102,101,101,237,117, 37,127, 55,104,149,158,158, 94,241,194, 11, 47,236,190, +221, 83, 20, 13,145,255,161, 67,135,212, 41, 41, 41,188,175, 45, 38, 58, 82, 29,213,182, 10,173, 90,134,162, 99, 84, 59,132,132, +134,160,184,184, 20, 54, 27,139,168, 14,205,113,252,247, 92,172, 62, 85, 40, 77,126,124,150,199,193,244,232,209,253,244,145,137, +189,209,185,115, 71,156,248,189, 24,135, 15,255,142,107,215,171, 65, 41, 16, 17, 17, 12,131,161, 6,131, 6,245, 69, 69, 69, 37, + 74, 15,255,140,175,254,119, 90, 58,243, 31,252, 21,149, 59, 28, 82,192, 94,124,138,195,135, 31,126,200,109,251,228, 5, 72, 77, + 77,165,174, 46, 97, 87, 11,210,213, 37,221, 20,211, 11,111,191,253, 54,237,212,169, 83,163,115,241,203,229,114, 66, 8,161, 27, + 55,110,244,152, 99,159, 67, 90, 90, 26,117,231, 33, 88,189,122,181,148, 43, 14,228, 78,137, 85, 40, 20,180,161, 84,174,174,245, + 28, 40,165, 80, 40,210,212,141,241, 66,212,151, 55,244,229, 26,252,244, 94,179, 58,196, 31,192,159,211,250,175,223,135, 26, 53, + 5,208, 88, 69,224,222,143,122, 52,168, 4,248, 67,254, 28,114,114,114, 80, 90, 90, 10, 0,136,138,138,162,190, 40, 1, 2,106, +132,144,216, 32, 22,137,240,243,177,214, 16, 8,133,104, 46,210,219,227, 0,154, 49, 40, 45,109,142,187,251,178, 32,132, 32,233, + 65, 43, 40,203, 0, 36,200,238,120, 67,117,131,114, 13, 21, 23,112, 69, 91,131, 23, 94,127,189,193,107,169,168,212, 66,119,237, +138, 67, 22,111,226,174, 79,254, 0,128,237,219,183,195,102,179, 73, 31,121,228, 17,175, 3,156, 74,165, 26, 83,191,244, 47,215, + 97, 42, 43,235,196, 35,134, 47, 94,188, 24, 42,149,106,236,157, 52, 21,192,145,191, 47,223,249,122,195, 26,233,221, 49, 38, 4, + 7,135, 67, 18, 36, 70,183,110, 93,209,169,107, 87, 84, 85,105,160,213,214, 64, 44, 22, 32, 50, 66, 2, 97,112,184,199, 92,241, + 0, 32,164,165,104,222,172, 37, 12, 70, 43,142, 29, 43,196,165, 43,149,184,124,165, 6, 70,147, 4,157,163,172,144, 4, 9, 80, +120,186, 8,119,117,239,142, 75,151,171, 96,180,182,240, 42,211, 65,116,212,219,126, 95,167, 3, 26,146,233,143, 44,206,250,159, + 55,111,222, 77,251,159,127,254,121,191, 98, 1,220,145,104,253,185,227,166,242, 42,228,230,230,170,209,200,130, 60,123,246,236, +161, 89, 89, 89, 72, 74, 74,130,187,233, 0, 62,158, 42,142,252, 1, 32, 63, 63, 95,205, 48, 76,157,107, 90,189,122,181,148,143, +209, 19, 31, 31, 47,227,228, 52,133,199,101,227,243,161,152,178, 92,239,150,248,163, 34, 25,199, 40,197,239,241, 38, 38, 38,214, +241,146,220,119,223,125,117,218, 42,224,246,191,115,224,115, 12, 64, 83,121, 4,154, 18,133,133,118,197,162,180,180,212, 39, 37, + 64, 40, 20, 66, 36, 16, 65, 36, 34, 24, 53, 2, 48,232, 77, 56,119, 86, 12,145, 80, 4,161, 77,136,184, 97, 20, 98,145, 8, 2, + 1, 3, 80, 2,173, 14,248,233,136, 16, 44,203, 2,184,214,160,220, 35, 63,159, 69, 77, 77,195, 25, 56,223, 95,188,152, 6, 5, + 73, 96, 52, 86,194,198, 90,121,223,231,145, 35, 71, 26, 86, 58, 12, 6, 94, 68, 83,223,245,239, 78, 51,220,178,101,139,235,249, +170,219,225, 5,112,231,226,119, 37,255,248,248,120,222, 85,232, 58, 70,181, 85, 51,204, 5, 88,109, 44,204, 22, 43,174, 93,215, + 66, 36,150,192,100,178,192, 98,181,193,106,101, 97,181, 81, 84,232,174,123,149, 37, 22,233, 33, 9,238,136,242,242, 74, 84, 85, + 27,160,213, 25,209,162,229, 0, 12,191,251,110,228, 31,216,129, 14,102, 43, 42,171, 42,209,179,103,119, 4,137,133,208, 87,107, +255, 42, 99,133,148, 82,234,156,251,119,197,138, 21, 43,252,138, 5,152, 55,111, 94, 29,111, 66,253, 99,124, 21, 0,123,169,103, +206,162,141,196,216,177, 99,235,244, 87,206, 64, 40, 41, 41, 81,171, 84, 42,191, 10, 83,169, 84, 42, 39,249,115,211, 1,155, 54, +109,242, 74,174,245, 61, 85,185,185,185,106, 46,240, 77,161, 80,208,188,188, 60,117,114,114,178,243,120, 94, 94,158,154, 16,207, +151, 23, 31, 31, 47,115, 45, 51,156,150,150, 70, 61,181,149,183,241, 48, 41, 41, 9,147,227, 85,216, 0, 96,234,114, 61,238,121, +185,198, 99,219, 15,157,234,185,173,234,207,241,123,139, 9, 8,224,214,123, 3, 26,242, 0,252,161,254, 29,119,150,126, 99,172, +255,122, 22, 43, 10, 11, 11,177, 98,197, 10,222,165, 38, 5, 2, 33,226,134,178, 16, 48, 66,252, 84, 32,193,169, 66, 9, 38,140, + 7, 30,184, 15,152,152, 72,208,190,173, 24, 18,113, 16, 36,226, 32, 4, 75,130, 16,213, 62, 8, 18,177, 4, 18,177,231,146,152, +175, 45,122,149, 44,125,239, 45,210,208, 64,210,189, 91, 23,132,133,135, 66,194,154, 81, 99,176,252,225,157, 98,255,254,253,123, +246,239,223, 95,135,240, 93,255, 0,160,188,188, 28, 19, 39, 78,188,109, 86,126,126,126,190,218,213, 26,226,246, 1,192,176, 97, +195,124,178,228,108, 54, 64,111,176, 64,175, 55,163,170,202,132,171, 87,117,184,116,233, 58,170,171, 77,168,169,177,160,166,198, + 12,189,222,130,202, 10,239, 43, 50, 77, 38, 43,106,107,109,176, 88,204,104,222, 92,140, 78, 81, 45, 16, 18, 26, 10, 0,136,238, +222, 21, 29, 59,180, 64, 88, 11, 9, 40,181,193, 98,101, 97, 50,233,255, 18, 3, 73,106,106,170,122,254,252,249, 30,201,156, 91, + 26,200,211, 59, 33,115, 40, 13,110,177,124,249,114,124,254,249,231, 62,151, 26,182,187,197, 21,212,245,143, 35,212,210,210, 82, +100,101,101,249, 92,138,118,207,158, 61, 52, 59, 59,219,149,252, 33,151,203,201,228,201,147, 61,126,111,206,156, 57, 32,132, 56, +173,250, 85,171, 86, 73, 1, 32, 46, 46, 78,230,170,196,186, 30,167,148, 58,143,243,184,219, 58, 86,188, 59,197,193,155, 50, 1, + 0,173, 90,181, 2,113,177, 30, 26, 43, 47,128, 59,143,252,221,109,251,229, 1,184,147, 44,255, 27, 3,188, 13, 2,129,192,231, +239,141, 24,202,162, 77,235, 32, 84, 85, 9, 17, 36,180, 34, 72, 44,128,230,144, 24, 19,100, 34,136, 69, 34, 84, 85,137,112,160, + 32, 20, 45, 36, 4, 12,195, 32, 81,110,198, 67, 19, 40, 24,134,226,157, 95,124,191, 78,149, 74, 69, 5, 33, 18,104, 69,173, 16, + 98,185,136, 51,165, 20, 99,164,163,120,127,127,208,160, 65, 56,120,240,160,219, 99, 33, 33, 33,188, 7, 75,157, 78, 55,214, 49, +240, 32, 57, 57,217,185,191,188,188,220,249, 57, 57, 57, 25,101,101,101,183,229,121,166,164,164,104,242,243,243,145,155,155,171, +102, 89, 86,198, 48, 12, 56,203,191,161,121, 83, 79, 40,185,112, 73,214,186,133, 65, 29, 36, 22,192,108, 97, 81,107,186,136, 11, + 23,203,161,213, 85, 65,171, 53,160, 92,107, 68,185,214,136,240,200,174, 94,101, 93,189, 78,113,229,234,117,244,238,221, 29, 21, + 58, 29, 68, 66, 6, 85,213, 23,161,175, 96,209,231, 46, 61,218,182,110,141,144,144, 16, 4, 5, 5,227,242,149,106, 16, 65, 4, + 95,130, 37, 46,228,216, 36,171, 0,154,122, 5, 65, 67,214, 58, 80, 39, 22,128, 47, 52, 0, 48,119,238,220,155,188, 10, 46,211, + 12, 26,127,174,115,202,148, 41,117, 44,216,172,172, 44, 39,121, 61,250,232,163, 72, 72, 72, 32,124, 19,167,184,177,252,157,168, +239,105,168,143,129, 3, 7, 18, 74,169,211,202,207,207,207, 87, 19, 66,156,165,129,147,147,147, 53,185,185,185,200,205,205, 85, + 39, 39, 39,147, 67,135, 14, 57,143,175, 92,185,178, 65,185,185,185,185,106,134, 33,178,188, 60,251, 59, 49,103,206, 28,252,242, +203,207, 50,142,194,243,242,242,212,220,253,243, 81, 38, 86,174, 92,137, 79,101, 17,152,186,194, 0,192, 62, 29,224,138,169, 43, + 12,206,246, 76,145,137, 2,204,250,103, 81,218, 23,190, 95, 87,233, 94,250, 18,126,249,229, 23,254,171, 0,110, 5,241,187,198, + 2, 52,198,250,175,107,201,215, 37,255,196,196, 68, 40, 20, 10,175, 83, 1,173, 90, 9,192, 16, 1, 90,183, 18,160, 71,119,138, + 75,151,132, 96, 4, 4, 34,161, 16, 34,161, 8,191, 29, 13, 69,100,168, 8, 2,129, 0, 35,134,217, 16, 28, 28, 4,150,165, 0, +181,249, 69,254,205,218,118,194,213, 26, 10,253, 25, 13,132, 68,128, 23, 23, 47, 34, 62, 14,108,178, 11, 23, 46,168, 47, 92,184, +112,211,253, 78,154, 52,137,215, 96,153,148,148,148, 80, 94, 94,190,155, 35,121, 0,152, 56,113, 34, 86,175, 94,237, 60,167,170, +170, 10,101,101,101,216,186,117, 43,146,146,146,198,220,142,206, 27, 23, 23, 39,203,205,205, 85,231,231,231,171,185, 96,177,184, +184, 56,191,230,112,103,254, 35,229,255,217,251,242,240,166,170,252,253,247,220,236, 93,105, 75, 41, 75,217,165,130,108, 5, 42, + 32,107, 2, 5, 20,176, 34,180,200, 38, 95,100,102, 26, 24, 87, 96, 20, 69,231,231,204,168, 40, 46,128, 35, 35,180,140,138, 11, + 21,105, 21, 44, 88, 4, 10, 9,139,136,149,138,128, 44,178,148,181,133,174,105,211, 52,123,238,249,253,145,222,152,134,180,185, + 73,195, 58,247,125,158, 60, 77,238,189,249, 52,247,220,115,206,251,217,206,231,104, 55,124,153, 9, 90,172,135,209,100,131, 78, +102, 6,133, 14,102,179, 29,122,189, 5,101, 21, 70,148, 92, 53, 96,184,170,163, 79, 89, 38,107, 75, 20,157, 47, 71,151,206, 29, +208,185,115, 60, 42, 43, 43, 16,213,194,129,110,221, 34,209, 42,182, 11,228, 10, 5,170,171, 13, 40,252,229, 20,174, 20,235,209, + 58,190,231, 29, 59,129, 80,128, 18, 2, 21,199,165,238,164,218,212,186,125, 90,159, 44,120,189,249,136, 6,171,202, 50, 51, 51, + 85, 43, 87,174,212,120, 42, 0,203,151, 47,231, 10, 12, 53, 41,143, 82, 74, 9, 33, 68,173,142,114,251, 77,244, 58, 98,206,206, +118,134, 8, 82, 83, 83,121,185,255, 27,134, 20,118,121, 37,127,190,120,224,129, 7, 84, 7, 15, 30,212,112, 94,135,161, 67,135, +170,188,157,231,146,241,124, 17, 54, 23, 91,255,225,135, 3, 26, 66, 8, 8, 33, 72, 76,236,171, 74, 76, 76,212,186, 41, 8,245, +215, 2,190,198, 11, 39,143,153,170, 3, 39, 47,109, 84,167, 6, 15,106,234,138, 19, 46,121,124, 32,228, 0,220, 57,240,169, 0, +220,142, 22, 63,135,105,211,166, 53,235,251, 12,195, 64, 36,114,190,122, 36, 48,232,215,219, 1,153, 84,238, 84, 0, 36, 18, 12, + 25, 4,200,100,128, 68, 36, 67,203,150,114,136, 68,117,112, 56, 88,176,172,255,110,123, 99,213, 53,200,227,187,227,124,254, 23, +136, 21, 51,120,252,229, 37,126, 79, 40, 10,133, 66,187,100,201, 18, 85,115,150, 1, 38, 39, 39,231,171,213,106, 60,245,212, 83, +174, 99,156,165,175,215,235, 97, 52, 26, 49,119,238, 92, 0,192,135, 31,126,136,140,140, 12,205,173,120,182,115,230,204,209,178, + 44,171,226, 44,255,129, 3, 7, 54, 43,129, 43,190,227,189, 56,116,112, 59, 90,181, 12, 65, 72,136,179,219, 91, 44, 14,232,107, +173,168,210,153,208,190,115, 79, 12, 27, 50,210,231, 51, 25, 63,126, 10,217,177,237, 19,122,176,224, 56,134, 15,237,139,142, 29, + 59,194,102, 53,163, 95, 98, 31,132, 70, 70,226, 98,209, 37, 20,151, 84,227,135, 31, 79, 66, 87, 27,137, 71, 31, 24,121,199,250, + 76,231,207, 83, 3,128, 6, 32,152,175, 86,187, 8,156,245, 32,125,134, 33, 78,109,161,158,151, 9,128,190, 94,226,141,243,212, +106, 10, 10,183, 76, 21,130,244,244,244, 6, 94,128,103,159,125, 22,132, 16,204,155,167,214,112,236, 15, 2,244,237,155,232,141, +188, 92,238,120, 95, 36,199,151,252, 61,145,154,154,138,209,163, 71,171,154,211,143, 81, 31,171, 31, 52,104,144,106,246,236,217, +218,198,206,187,197,246, 27, 5,151, 59,192, 41, 95,206, 48, 2,209,122, 42, 21,124,127,159,167,188,141, 11,194,156,141, 46,143, +115, 93,179,113,193, 37,151, 66,176,253, 72,211,115,159,183, 58, 0, 66, 14,192, 29,170, 0, 12, 25, 58,240,134,196,124,130,101, +249,187,119,164, 64, 80,165, 35,104, 19,199,184, 74,254,238,216,229,140,239,203,100,114,200,164, 50, 60,252, 16,129, 92, 38,133, + 66, 78, 80, 85, 41, 66, 65, 97, 56, 28,172, 3,237,227,253,139,235,230,231,231,211,106,163, 9,186, 67,121,232,214, 94,130,223, +138, 3,143, 11, 51, 12,163, 29, 56,112, 32, 25, 56,112, 96,192, 50,210,210,210, 84,171, 86,173,210,112,110,254,202,202,202,199, + 6, 13, 26,100,216,185,115,231,119,143, 60,242,200,216,202,202, 74,242,248,227,143,111, 79, 75, 75, 83,221,202,206, 89,239,234, + 87,185,189, 15,188,207, 57,201,157,158, 62,117, 2, 37, 69, 23,193, 48, 4, 14, 7,133, 92, 17,141,132, 30,189,240,232,164, 52, +222, 29,189,164,156, 85, 85, 85,150,104,204,102, 59,122,247,234,130,118,109, 91,226,210,229, 82,232,142,157,195,239,167, 47, 97, +215,238,163,184, 88, 76,241,231,191, 60, 29,208,224,185, 93,138,255,176, 95, 69, 5,124, 93,191,165, 60,229,157,251, 4, 43, 87, +174,116, 41, 0, 43, 87,174, 4,138,214, 93,119,173, 55,121,141,120, 5,174,155,179,154, 91,172,135, 16,210,172,190,199,145,124, + 99,228,238,235,188, 55,175,130,199,119,189,201,227,255,156, 47,126,141,156,149,179,157,115,195,168, 14, 13,200, 31, 0,210,198, +223,239,124,163,251,213,167, 2, 32,212, 1,184,125,144,185,236,197,235,194, 0,126, 41, 0,183,115,194, 71,160,197,127,220,113, +232, 23, 25,228, 82, 41, 30, 30, 79,192, 16,130,129, 73,118, 28,251, 77, 1,134, 56, 99,254,213,213, 12,218,182, 22,129, 33, 82, + 28, 57, 38,133, 92, 6, 88,109, 86, 92,188,164,240,139,252,207,157, 62,140, 65,163, 39, 66,220,114, 16,206,157, 46,128,248, 90, + 14, 94,120,254, 37,250,246, 59,111,222,146, 6,174,175, 87,175, 74, 74, 74,210, 44, 94,188, 24,189,122,245, 42,211,233,116, 72, + 74, 74, 82,233,116, 58, 60,243,204, 51,154,180,180,180,219,162,174,125,115,137,223, 83, 9, 24, 54,100, 36,214,125,254,145,178, + 77,235, 54,154,208,208, 80, 94, 86,255,117, 19,236,236, 63,105, 1,144,245, 95,100,208, 19,191,255,132, 54,113, 97,144,203, 37, + 48, 24,172, 40,190,170, 7, 17,183,199,159,255, 50, 91,200,150,226,131, 95, 22, 1, 93,159, 64,131,229,133,133, 11,155, 67,214, +205,254, 73,243,230, 69,187, 41, 18,193, 33, 52, 95,164,236, 15,105, 55,183,158,129,183, 54, 75,123, 64,230,188, 87,211, 85,231, + 75,192, 29,139,196,196, 68, 87,194, 95,230,178, 23,175, 59,231, 83, 1, 8,118, 61,254,155, 93,223,223,175,206, 15, 2,157,142, + 32,164, 53, 65, 76, 52, 65, 82,127, 27,228, 82, 17,100, 82, 27, 98,162,229,245,147, 0,193,224, 36, 7, 10,126,145, 56,189, 5, + 60, 39,153,252,252,124,218,243,222, 8, 44,122,246, 95, 48, 73,227,241, 77,126, 49,186, 38, 56, 45,247,176,159,183, 98,209,223, + 94,162,239,189,123,235,148,128,228,228,100,146,159,159,175, 92,182,108,153,198,221, 59, 16, 12,229,234,118, 70,125,177,159,102, +223,227,204, 89,106,178,255,192, 30, 90, 94, 89, 14,211, 53, 35,228,242, 24,196,119,238, 19,144, 82,113,167,193, 89, 14, 59, 72, +183, 89,180, 14,174, 21, 1, 69,159,222,242,123,243,149,220,119,183, 97,236,196,199,252,178,220,125,249, 30,133, 28,128,219, 75, + 9,104,140,252,125,122, 0,254, 23, 64,225,204,234, 39, 12, 5, 5, 69,116, 11,138, 61,251,197,144, 75, 37,144, 73,197, 72, 25, + 79, 65, 41,139,168, 24, 59,236, 14, 2,150,117,212, 79,126,190,209,167,147, 1, 19,166,164,193, 32,238,134, 86, 97,161,152,241, +104, 52,178, 54, 29,115, 41, 1, 54,199, 55,183,252,254, 57, 69, 64, 24, 50,129,123, 21,238,214,123,203,212,189, 69,210,163, 94, +188,158, 25,178,163, 3,149,135,244,168, 23,175, 63, 81,184,176, 89, 86,191,128,230, 33,245,201, 85, 65,235,195,119,187,241,112, +167, 41, 1, 62, 13,224,196,196, 68, 33,104, 35, 64,128, 0, 1, 2, 4,252,143, 65, 40,244, 44, 64,128, 0, 1, 2, 4, 8, 10, +128, 0, 1, 2, 4, 8, 16, 32, 64, 80, 0, 4, 8, 16, 32, 64,128, 0, 1,130, 2, 32, 64,128, 0, 1, 2, 4, 8,184, 59,208, + 96, 21,192,252,249,243, 3,206,224,244, 86, 91, 59,216,242,102,206,157,231,243,123,117, 85,215, 92,239, 67,163, 91,187,222,175, +255,120,205,117,215,198,170,254,236, 83,222,206, 21,127, 84,204, 27,179, 96,149,235,125,185,230,191, 8,228,247, 53,134, 64,127, + 95, 99,240,246,251, 38, 61,174,246,249,189, 67,154,239,208,169, 83, 39, 92,184,112, 1, 73,170, 9,174,227,155, 63,207,184,225, +237,247,231,171, 87,155,236, 47, 22,177, 88,185,168,184,216,181,100,113, 85, 92,156,235,250,255,182,105,115,195,251,159,167,188, +220,220, 92,101, 94, 94, 94,131, 74,137,227,199,143, 87,165,164,164,104,111,197,248, 56,124,248,112,192,242,250,245,235,119,163, +127, 31,153, 63,127, 62,110,231,249,229, 86,200,203,202,202,154,222,187,119,239,172, 99,199,142, 77,153, 49, 99,198, 55,205,149, +231,190,209,145,123, 70,254,221,218,126,130,188,198,229,249,173, 0,120,194,110,183, 43,205,102, 51,136, 72, 2, 66, 8, 28,118, + 27,164, 18, 49,100, 50,153,182,185,154,135,221,110, 87, 2,128, 88, 44,110,150,172,186,170,107, 8,141,110,237, 34,254,214,237, + 59, 1, 0,174, 93,190, 16,144,188,157, 43,158,194,152, 5,171, 92,196,245,159,220, 2, 0,192,147, 41, 3,113, 55,226,144,230, + 59, 36,169, 38,224,144,230, 59, 0,192,132,212,153, 0,128, 11, 23,110,125,251,253,187,180, 84,121, 26,208, 36, 0,170,211,128, +115, 15,245,197, 47, 0, 0, 6, 46,123,251,150,182,155, 86,171,165,121,121,121, 48,155,205, 13,142,203,229,114, 77, 68, 68, 4, +148, 74,229,109,185, 28,138, 16, 50,236,222,206,237, 62,165, 14,135,241,244,165,107, 47, 81, 74,183, 10,118, 80, 19, 74,167,197, + 50,234,240,225,195, 17, 37, 37, 37,173,163,163,163, 91, 12, 24, 48,160, 56, 60, 60,252,243, 64,229,101,101,101,141,158, 49, 99, +198,158,172,172,172, 63, 3,136,156,246,196,188,185, 0,216, 99,199,142,205, 6,176, 25, 0,235,143, 60,110,207, 19,142,248,155, + 51,222, 60,119, 73, 12,214,146,190,198,148, 18, 1,183,153, 7,192, 29,250, 90,131,178, 77,194,253,154,145,189,187, 35, 68, 38, + 1,165, 20, 14, 7,197,111,103, 46,226,252,209,125, 42,133, 76, 2,145, 72, 20, 16,121,135,201, 47, 40,123,118, 43,210,252,118, +186,139,170,206,210, 41, 96,226, 7, 0, 69,100, 12,234,170,174,185,136,191, 41,143, 0, 31, 75,117,224,204, 23,177,115,197, 83, +174,129,212,216,117, 77,173,177,244,252,159, 82,169, 20,128,179, 76, 38,203, 58,199,183,195,225,112,253,126, 70, 36,225,109, 69, + 3, 64,155, 86,206, 82,157, 86,125, 53, 44,118, 59, 0,192, 96,119,202,235, 60,246, 79,184,167,103, 63, 94,196, 15, 0,125,135, +140,198, 33,205,119, 46,226,111,236,186,155,217,126, 0,240, 84,105, 41, 5,128,113,161,161,216, 94, 87,167,225,136, 31, 0,126, +223,177,243,186,235, 18,219,180,225,245, 59,107, 66, 43,148,133, 21, 63,163,248,210, 17,116,235, 56, 24,131,229, 74,191,251,112, +110,110,238, 35,219,182,109,227,200,223, 14,192, 12, 32, 4, 0,107, 54,155,197, 10,133, 2,122,189, 94,233,205, 19,112,139,201, + 63,238,254,196,222,219,182,127,185, 38,172,174,248, 36,134,165,205,207, 34,132,204,166,148,110,190,221, 38,166,252,252,124,218, +156,250, 20,124, 54, 3,107, 10, 54,155, 77, 89, 80, 80,160, 57,126,252,184,235, 88, 69, 69, 5, 78,159, 62,141, 54,109,218,124, +166, 84, 42, 85,225,225,225,124,159, 47,147,149,149,245, 79, 0, 15, 12, 27, 55, 73,145,149,149, 21, 55,237,137,121,225, 0, 28, + 0,184,142,123,111,253,117, 35,248,222, 31, 55,222,212,106, 53,109,108,188,113,215,249, 26,111,106,181,154,238,253,177, 0, 34, +145, 24, 14,135, 29, 53,181, 6,204,152,242, 8,125,247,221,119,155, 69,216,158, 74, 69,115,159,139, 0,223,240,182,237, 47, 7, + 94,149, 0,235, 76, 86,229,232,148, 25,154,246,173, 34, 17, 34, 23,131,101, 89, 56, 88, 64, 44, 34,136,142,236,142,158,221, 58, +104,242,183,127,167,114,216,234,148,254, 42, 1, 86,171, 85,217,163,231,121, 77,223,238,231, 33, 98, 28, 26,237,161,118, 42,169, + 68,226,151,140,186,170,107, 80, 68,198, 32, 50, 34, 28, 0, 92,127,189, 93,215,186,125, 39,159,222,128,157, 43,158,194,192,153, + 47,226,255, 30,155, 12, 0,174,191,222,174,251, 79,110,129, 95,218,181, 72, 36, 66,124,124, 60, 68, 34, 17,172, 86, 43,234,234, +234,224,112, 56,160,211,233, 2,122,184, 97, 98, 17, 62, 94,185, 9,178, 72,160,244, 2,240,179,161, 24,229,215,206,226,243, 21, + 47,249,101,245,247, 29, 50, 26,241,109,157, 33,146,120, 47,228,223,169, 83, 39, 87, 56, 0, 0,174, 92,185, 18,148,246,227, 83, + 92,245,169,210, 82, 58, 46, 52, 20,175, 61,245, 36, 0,224, 53, 55,226,255,226,244,233,134,228,239, 71,181,214, 61, 23,190, 80, +118,124, 66,172,121,177,195, 44, 88,216,100,200, 88,138,147, 21,187,240,201, 59, 27, 85,169,125, 50,248,246, 65,113, 94, 94,222, +102,147,201,132,117,235,214,153,231,204,153, 35, 7, 16, 6,128, 93,183,110,157,117,206,156, 57, 98,147,201, 4,185, 92,174, 73, + 73, 73,105,214, 68,247,205, 55,223, 40,119,236,216,161,105,110, 45,123, 87,223,145, 50,255,239,131,215, 94, 80,180, 56,241, 37, + 20,191,239,198, 63, 70, 69,133, 63,179,165,252, 95,245,150,231,109, 69,254, 27, 55,110,132, 78, 55,134,102,103,167,249,125,239, + 31,127,252,177,178, 57,100, 83, 87, 87,167,204,205,205,213,212,214,214,122, 61,127,245,234, 85,228,228,228,104,122,244,232,161, + 26, 60,120,176,175,126, 67,178,178,178, 62, 31, 54,110,210,212,211,135, 15,136,227,219,182,182, 79,123, 98, 94,131,121,119,247, +119,223,160,119,239,222,221,179,178,178, 30,234,221,187,119, 46, 0,236,223,191,191, 73, 82,229, 51,222,212,106, 53, 5, 33,128, +143, 42,127,107,214,172,161,215,202, 42,112,248,183, 19,174, 99,102,179, 5,111,127,144,105, 80,207,153, 46, 16,246, 93,140,235, +146, 0,107,107,107,149,195,198, 62,170,233,222, 33, 6, 50, 9, 3,150,101,113,237,218, 53, 28, 59,114, 24, 86, 59, 11,150,165, +136,137, 12,193,216,135, 38,106, 76, 22,187,223,255, 80, 38, 41, 67,215, 14,215, 0, 17,193,125,221, 46, 67, 38, 46,245,219,242, +119, 39,255,235, 44, 60,125, 45,174, 93,190, 0, 69,100, 76,163, 94,129,166,200,203, 19,159,126,245, 13,158, 76, 25,136,129, 51, + 95,108,212,170,245, 6,169, 84, 10,145, 72,132,136,136, 8, 20, 21, 21, 65,167,211, 57, 21,169, 0,201,191, 77,171, 56,132,137, + 69,120,244,233,215,241,208,140, 33,216,250, 91, 49,174,153,208,108,242,247,196,149,146,107, 56,126,232, 7,196, 70, 69, 56,201, + 95, 44, 10, 74,251, 61, 56,229,255, 0, 0, 81, 98,137, 95,228, 15, 0,127, 95,245, 31,252,125,213,127, 92,228,191,189,174, 14, +207,143,157,232, 60, 25, 43,229,117,223,159, 94,124, 75,249,151, 69, 15,104,158,232,248, 87, 72,152, 48,132, 34, 4, 12, 68,104, + 23, 55, 20, 79,189,182, 80, 83,212,118, 5, 47, 53, 66,171,213,218, 0,224,211, 79, 63, 53, 2,144,115,219, 40,175, 91,183,142, + 5, 16,226,190,173,178, 86,171, 13, 40, 46,103, 52, 26,149,254, 28,231, 97,249, 15,187,191,127,162, 49,251,155, 77,234,126,189, + 18, 68,117, 39,118,225, 66, 89, 45,174, 86, 27,193, 82, 26, 80, 34,112,122,122, 58, 77, 75,203,166,235,215,175, 15,106, 33, 49, + 55,242, 71,116,116,126, 64, 50, 10, 10, 10, 52, 25, 25, 25,132, 16,226, 82, 6,252,252, 13,215,145,255,161, 67,135, 48, 99,198, + 12,119, 15, 1, 78,157, 58,165, 49, 26,141, 77,110,152,149,149,149,245,212,176,113,147, 38,190,177,100,129, 56, 59, 59, 27,255, +253,224, 93,113,189,199,200, 69,254,217,217,217, 88,181,106, 21,122,247,238,157,235,107,188,121,146,127, 99,227,237,161,161,245, + 94,192,240, 80,159,242,222,251, 96,181,139,252,203, 42, 42, 81, 86, 81,137,154, 90, 3, 36, 18,113,216,234,117, 95,154, 61,173, +120, 1,119, 6, 18, 19, 19,175,123, 53,169, 0, 56, 28, 14, 26,211,169, 15, 58,181,110, 1,179,205, 1, 66,128,237,219,191,199, +103,159,174,195,209, 35, 71,240,252,194,231, 32, 18, 49, 96, 29, 44, 34, 66,100,232,212,103,152,198,100, 50,241, 30, 96, 54,155, + 77,217,179,219, 69, 77, 68,152, 17, 31,127, 90, 6,134, 80, 12,236,253,187,198,102,179,249, 53, 72,189,145, 63, 71,252,166,154, +202, 6, 10, 66,141,190,214,167, 60,111,131,137, 27, 72, 5,235,223,106, 64,112,159,126,197,175,124,111,215,174, 93, 17, 19, 19, + 3,189, 94, 15,169, 84, 10,134, 97, 96, 50,153,160,211,233, 32, 18,137,184,137,153,247, 61,127,189,121, 19,158, 91,185, 3,155, + 62,120, 5,109, 90,197, 33, 36, 52, 26,151, 29,197,248,124,197, 75, 8,171,159, 52, 68, 60,229,121, 35,127,142,248,107, 74,206, +161,123,124, 43,212, 26,205,144,133,200, 0,135,195,103, 62,128,175,246,123,105,237, 86, 28,255,229, 71,244,234,114, 31,106, 28, +190,149, 70,142,252,127,223,177, 19,127, 95,245, 31,215,241,237,117,117,216, 94, 87,135, 34,245, 63,177,227,196, 81,244, 28,216, + 5,168,244,189, 53,115,214,153,101,202,249,207,140,214,196,134,246,128,137,214, 2,150, 50, 72, 45, 85,176, 56,106, 97,102, 77, + 96,165, 97,104, 55, 60, 9, 57,191, 46,245, 53,209,145, 13, 27, 54,192,108, 54, 67,173, 86,135,168,213,106,192, 25, 2,128, 90, +173, 70,253,231,122, 11,202,140, 13, 27, 54,248, 61,104, 79,157, 58,165, 92,184,112,161,230,253,247,223,167,132, 16, 13, 0,236, +219,183,143, 46, 93,186,148,190,242,202, 43, 1,109,205, 28, 46, 99,214,253,231,197, 39, 20,227,218, 89, 68, 7, 78, 93,195,214, + 11, 12, 94,220, 86,106,249,167,214, 80, 83,103,195,255, 5, 34, 83,167, 27,115, 35, 45,127, 68, 71,231, 99,230,204,153,126,239, + 70,233, 78,248,107,214,172, 33,220,118,210,124,113,224,192, 1,101,105, 41, 63,163,196,106,181,226,216,177, 99,187,155,234, 47, + 0,148,241,109, 91, 75,211,210,210, 0, 0,133,133,133,216,253,221, 55,242, 43, 37,215, 88,142,252, 1, 32, 45, 45,205, 53,222, +142, 29, 59,182,162, 57,227,237,237, 57, 19,241,219,185,203,104,221,165, 13, 80,103,228,125,239,101, 21,149,176,217,236,245,115, +181, 29, 54,155, 29,151, 47, 94,144, 55,231,153,122,122, 15, 4,111,194,237,133, 6,174, 40,139,197,130,126,221,187,107, 66, 20, + 18,176, 44,133,131, 5,126,216,183, 31,255,124,237,117,176, 20, 56,115,246, 44,142, 30,249, 21,189,122,245,133, 72, 68,112,111, +151,120, 20,253, 98,135,130,231,230,120, 82,113, 25, 18, 58,149, 0, 98,130,203, 87,109,128,152,160, 79,247,139, 40, 56, 86, 6, +138,118, 1,221,128,187,123,223,155,103,192, 84, 83,217, 96, 53,128, 47,184,187,247,189,105,218, 5,235,223,194,152, 5,171,188, +102,177,187,195,110,183, 35, 36, 36, 4, 12,195, 32, 42, 42, 10, 70,163, 17,117,117,206,109,128, 99, 99, 99, 81, 89, 89,233,215, + 6, 28,102, 29, 48, 80,161,192,243, 31,236,195,152,190,192,197,195,192,207,245,231,158,255, 96, 31,254,189, 64, 5, 7,235,240, +187,253,142, 31,250,193,245,126,244,128,238, 16,135, 51,216,174, 61,129,126,221,219, 35, 34, 76,134, 79,115,242,145,164,154,128, + 43, 94, 86, 1,248,106,191,220, 19, 20,184, 10,164,140, 38, 88,187,181, 8, 49, 81,157, 49,121, 40,225,213,126,156,187,127,123, +221, 31, 91, 39,211,127,172, 0,218,213,128,252,229, 85,208,127,190, 6, 48, 38,144,130,165, 88, 21, 23, 71,254,219, 68, 32,160, +235,148, 48, 77,199, 22, 3,160,119, 24, 96,209,157,197,231,151,178,176, 63, 69,135,251,254,172,194,216,167,195,160,136,186, 23, +114,113, 20,196, 41, 53,248,249,155,159,233,253, 73,247, 55, 54, 73,185,254, 7,195, 48,160,148, 90,235,149,104, 51,195, 48, 70, + 74,105, 52,156, 73, 92, 1, 47,175,237,222,189,187,118,236,216,177,170,202,202, 74,205,246,237,219,157,138,207,246,237,232,209, +163, 7,186,119,239, 30,208,246,204,181, 22,246,153,185,127,255,247,150,119, 38,180,102,168,185, 6,127, 89,127,218,102,183,217, + 86, 89, 28, 88, 74, 41,173, 10, 68,230,164, 73,214, 27, 78,254, 35, 70,140,208,250, 43,167,160,160,160, 65,200,132,243, 2,240, +221, 85,210,225,112,248,165, 48,156, 63,127, 30,131, 6, 13,106,172,191,200, 1,220, 7, 64, 60,106,194,228,234,162,162,162, 22, +133,102, 28,210,109, 0, 0, 32, 0, 73, 68, 65, 84,133,133,200,206,206,198,128,162, 34,166,176,176, 16, 0, 48, 96,192, 0, 60, + 56, 50, 9, 17, 97, 50,172,250,100, 83,217,140, 25, 51,150,172, 94,189,122,129,191,227,237,234,230,183, 16,222, 83,142,176,110, +207, 97,227, 91,127, 70,223, 94,173,113,239,196,215,145,145,145, 65,154,202, 18,175,209,215, 66, 46,151, 1, 0, 36, 18, 49,140, + 70,115, 80,159,173, 64,250,183, 6,126,111, 6,196,178, 44, 66,100, 82, 88,237, 20, 12, 1, 24, 2,188,250,175,215,225, 96,129, +186, 58, 3,174, 93,187,138,184,184,214,160,148,133,221, 14,200, 37, 98,136, 36,252, 92,176,118,187, 93,121, 95,215, 43,154,150, + 81,122,128, 16,167,110, 76, 0, 66, 40,250,247, 60,163,249,233,104,156,202,223, 21, 1,156,117,223, 88, 72,128,143,245,239,169, + 69, 55, 70,252,254, 88,255,128, 51, 97,168, 85,171, 86,144,201,100, 46,151, 33,151,248, 23, 25, 25, 9,137, 68,130,203,151, 47, + 67,194, 83,222, 39,249,123,240,231,137, 35,193,153, 55,167,237, 78,247, 63, 0, 40, 19,128,136,215, 53, 88,240,183, 33,136,242, +227,126,175,148, 56,147, 21, 59,180,138,134,206, 98,129, 56, 66, 4,115,185, 17, 96, 24,180,233, 24,143, 29,187,127, 14,168,253, +254,111,209, 27, 56,255,195, 46,136,175, 1,213,113, 64, 8,195, 96,112,167,206, 24, 53, 50,142,151, 28,207, 88,255, 23,143,253, + 25, 95, 91,126, 7,238, 49, 3, 63,137,129, 48, 49,240,240, 0,196, 63,204,207,120,237,218, 46, 26, 86,107, 21, 36,118, 27, 62, +191,148,133, 31,231, 68, 98,196,163,143,160,123,171, 30,170,223,118,104, 53,253,210,234, 32,177,214,193,222,157, 69,121, 41,191, +164,209,122,229,205, 60,103,206,156, 48, 0, 58, 74,169, 4, 0,230,204,153,211,236,218, 26,147, 39, 79,214,238,223,191, 95,117, +242,228, 73, 77, 72, 72, 8, 66, 66, 66, 48,115,230,204,128, 38, 81, 66, 72,235,137, 19, 39,174,253,219,223,254,198, 60,191,224, + 25,182, 23,123,150,177, 88,109,117, 86, 7,253,155, 63,114,210,211,211,169, 78, 55, 6,147, 38, 89, 49,115,230, 76, 18,232,239, +185,145,228,239,205,221,191,102,205, 26,162, 86,171,233,220,185,115,121,253, 94,131,193,208,192,237,239,142,133, 11, 23, 98,225, + 66,231,166, 69, 73, 73, 73,238,215,203, 26, 17,215, 22, 64,167,122,165, 48,228,193, 41,179,204, 93,186,116,145,103,103,103,131, + 35,255,180,180, 52,196,181,105,227, 62,222,182,194, 45, 68,192,103,188,165, 63, 60, 2, 7, 75,202, 16,222, 55, 28,197,219,207, + 1,114, 25,166, 60, 61, 27,209,241, 19,121,206,205, 14, 20, 95, 45,181, 75, 36, 98, 49,231, 1, 0,128,203, 23, 47, 52,235,185, + 54, 22, 58, 16, 20,130, 91,167, 16,120, 42, 1,140, 55, 19,135, 82, 10,150, 2, 14,214,169, 4, 16, 2,124,243,117, 14, 30,157, +156,138,150,177,173, 92, 19, 32,245, 99,175,108, 17, 83,134,158,247, 92,118,125,238,211, 43,196,229, 36,235,127, 95, 17, 68, 76, +153,223, 55,228,233,238,247,118,222, 31,235,223,211,221,239,237,188,251, 90,246,166,160,215,235, 81, 91, 91, 11,139,197, 2,150, +101, 81, 94, 94,238,114,255, 27,141, 70, 24, 12, 6,191, 66, 0,155, 62,120, 5,218,223,128,154, 11,128,205, 4,252,123,177,202, +229,254,255,229, 48,240,235,213, 31, 32,242,179,253,106, 74,206, 33, 58, 50, 20, 49,209,161,184, 55,161, 7,138,206,151,227,116, +113, 37, 58,196, 68,194, 82, 90,134,179,103,206, 54,168, 5,192,167,253,134, 40, 31,193, 48,213,116,108,218,178, 17,154,189, 27, +145,181,124, 17,166, 44, 90,138,163, 54,160,188,178,140, 87,251,185,199,250,159, 24, 50, 8, 51,239,235,136,141,155,118,227,232, +209, 11, 88,126,172, 16, 27,198,204, 6, 62, 58,128,226,226,242, 6,181, 0, 26, 67,188, 89, 6,135,181, 2, 86,107, 13, 0, 32, +174, 93,123,116,239,209, 67,165, 87, 56,115, 49, 76,172, 17,140,165, 14,138, 58, 17, 74,175, 94,243, 69,168, 78,143,140,217, 12, +179,217, 44, 7, 96, 5, 16,110, 54,155, 35, 60,151, 4, 6, 10,163,209,168,220,187,119,175,166, 71,143, 30,152, 53,107,150,170, +162,162, 2,219,183,111,231, 61,216, 8, 33,195,100, 50,153, 33, 60, 60,220, 62,102,204,152,171,139, 23, 47,110,187,100,201,146, +162,159, 15, 31, 29,191,225,184,229,148,141,133,223,251,177,222, 8,151,127, 48,201,223,211,250,231,114, 20,220,189, 0,124,100, + 72, 36,127,168,228,203,151, 47,119,189,188,125, 6, 92, 43,124, 26,123, 54,210,250, 23, 3, 64, 92, 83,114,206,171, 59,157, 27, +111,135,127, 57,124,126,198,140, 25,233,254,140,183,225,247,223,139,228,161, 9,120,227, 95,239,226,189,149,121,248,127, 95,236, +198,188, 81, 73,184,246,109, 30,106,116,122,159,100,155,145,145, 65,210, 82, 30,132,205,102, 63,108,179,217,237,238, 10, 0, 0, + 44,125,245,165,128, 9, 91, 32,250, 91, 11,111,177,127, 79,175, 64, 3, 5,128, 97, 24,212, 24,140, 16, 49, 4,118,187, 3, 44, +165,176,179,206, 36,210, 35,191, 30,198,168,209,227,156,110, 50, 74, 33, 98, 68,168, 53, 90, 97,183, 90,124,107,152, 14,135,178, +115,187,171,154,216,232, 26,151,150, 49,100, 96,152,115,216, 16, 2, 66, 40,250,245, 56,171,177, 59, 28, 74,190, 55,199, 89,247, + 77, 37, 3, 6,100,189, 54,145, 92,227, 15,162,162,162, 80, 94, 94, 14,153, 76,134,218,218, 90,196,198,198,186,146, 2,205,102, + 51,170,171,171,253, 82, 0,210,223,216,128,127, 47, 86, 33,178, 19,160,253, 13,120,102,153, 6, 97, 98, 17, 38, 63,251, 38,174, +176,215,176,126,249, 11, 16, 49,252,229,113,214,255,128, 1, 9,136,237,210, 9,173, 98, 91, 66,202, 16,216, 9, 69,121,157, 9, +186, 90,115, 64,237,247,222, 91,155, 49,169, 71,103, 68, 68,196, 32, 36,182, 45,108, 85, 58, 28,222,250, 37,170,171, 46, 5,212, +137, 63,126,235, 41, 96, 65, 50,196,118, 43, 58,213, 1,101, 34, 61,254,125,245,103, 64, 26,193, 91,198, 47, 91, 14,170, 42, 24, + 19, 46, 73,141, 72,186, 71,133,251,102,135,161, 40, 74,171,137,141, 61,172,105, 63,184, 8, 53, 76, 45, 44,212, 4,227, 23, 44, +228, 97,225,124, 44,127,247, 9,158, 91, 5, 32, 13,214,192,253,254,251,239, 1, 0, 51,103,206, 84,117,239,222, 93,251,232,163, +143,186, 44, 70, 62,228, 31, 27, 27,187,109,237,218,181,161, 25, 25, 25,162, 5, 11, 22,224,185,231,158,163, 7, 14, 28, 24, 76, + 41,221,110,180,209, 30,148,210,159,252,183,230,162, 26,117,251, 7,154, 16, 24, 76,242,247, 36,120,119,133,101,205,154, 53,164, +160,160,128,151,107,255,202,149, 43, 7,184,247, 89, 89, 89,174,151,231, 49, 14,209,209,209, 0,208,216, 36,120, 5, 64, 53, 0, +230, 74,201, 53,252,248,227,143,174,152,255,128, 1, 3, 0, 0,217,217,217,248, 42, 55, 15,186, 90,179, 17,192, 82, 56,151, 6, +242, 30,111,223,110,250, 7,198, 45,126, 26,227,199,143, 70, 75,153, 8,181,132, 98,251,233,203,248,241,183, 98,191,136,122,254, +156,233,247, 23,157, 61, 43,190,124,241, 2,184,215,210, 87, 95,106,210,146, 23,112,123, 19,191,231, 49,111,104, 16, 2,144,201, +100, 56,115,226,168,170, 83,219,104,141, 66, 34,134,195,193,130, 16, 2, 66,128,116,245,147,160,148,133,163,190, 30,128,209,108, +198,201,211, 69,144, 74,125, 59,177,237,182, 42,244,187,239,188,251, 44,138,191, 46, 56,143,175,191,232,230,210,157,147,122,157, +195,193, 35, 61, 32, 22,197,250,101,253,123, 35,126, 83, 77, 37, 0, 4,100,253,123, 27,104, 5,235,223, 2, 0,222,214, 63,224, + 92,231,223,186,117,107, 88, 44, 22,148,150,150,194,225,112,160,101,203,150,168,172,172, 68,203,150, 45,235,219,149, 63, 97,151, + 95, 59,139, 87, 94,215,160,230, 2,240,206,162,225, 48,216, 29, 88,184, 44, 27,239, 47, 78,195,162,229, 91, 33, 38, 4,126,240, + 63,106, 74,206,161, 77,203, 22,144, 64, 2, 7, 8,174,158, 63,142,139,101, 53,232, 26, 27,141,111,127, 57,128,147, 39,224,183, +245, 63,101,238, 66, 72,162, 1, 70, 4,172,203, 59,143,175, 63,124, 30,115,223,202,192,194,135,251,226,201,209, 29,253,106,191, +237,117,117,120, 47,101, 42, 80, 45, 7,136, 4,120,239, 93,164,254,188, 15, 59, 70,207, 7,121,243,105,144,131, 47,240,178,254, + 1,224,215,171, 49, 24,100,170,129, 65, 33,130, 81, 46, 71,215, 41, 18, 88,168, 9, 53,140, 4,118, 36,128, 58,140,176, 85, 92, +197, 15, 31,212, 96,230,140,174,183,100,208, 22, 22, 22,210,122, 98, 32,147, 39, 79,214, 58,125, 99, 78, 12, 31, 62,156, 12, 31, + 62,156, 15,249, 15,109,219,182,237,247,111,190,249,102,232,153, 51,103, 32,145, 72, 16, 17, 17,129,163, 71,143,218, 40,165,229, +205,249,125, 77,173,201, 15,196, 59, 16, 76,242,247,180,254,157,196,122,253,242, 65, 62,185, 0,105,105,105,103,190,250,234,171, + 33,118, 59,191, 21, 78,114,185,124,110, 19,167,107, 1,156, 7, 48,224,244,225, 3,112,143,249,255,117,238, 84,124,223,165, 11, +184,112,192,182, 46, 93, 66,102,204,152,241,137, 63,227,237,177,228, 65,136,100,163, 96,132, 4, 95,175,120, 26, 31,110,253, 21, +207, 63, 56, 12,115,150,103, 33,117,233,231,126, 89,224,238,197,132,188, 29, 19,214,239,223,157,104,224, 1, 16,137, 68,164,250, +234, 89,156,187, 92, 9,177, 68, 4,187,131,133,205,238,192, 47,191, 20,226,179,207, 62,129,213, 65, 97,115,176,144,138, 25,148, +233, 12, 40, 62,249,163, 74,161, 80,104,125, 16,161,178, 71,215,139,127, 88,255,206,169, 10, 95,127,145,224,156,227, 24, 10, 48, + 20, 12,195, 98,112,223,147, 26, 7, 15, 47,128, 55,235,223,125, 21, 64,104,116,107,191,200,223,155,245,239,158, 85, 59,102,193, + 42,191,200,203, 57, 41,234, 96, 48, 24, 32,145, 72, 92,214, 63,203,178,174,191,254, 42, 0,159,175,120, 9,191, 20,239, 65, 88, +107,103,210, 95,184, 88,132,242,107,103, 17, 33,147,160,186,234, 10, 68, 12,129,152,225, 23,126,230,172,255,246,209,225, 56, 81, +116, 30,118,171, 21, 50,177, 20, 6,131, 25,223,106, 14, 32, 73, 53,193, 47,242,231,218,239,145,167, 94,195,250,127,191, 15, 35, + 11,180,239, 26,143,223,142, 31,196,194,135,251, 6,212,126, 0,176,176,107, 18,182,156,217, 13,212,216, 1,121, 75,236, 44, 56, + 1,242,230,211, 88, 21, 23, 71,248,146, 63, 0,204,232,182, 88,251,195,206, 2,192, 90, 11, 3,169,133,142, 49,160, 70,108,131, +205,161,135,204,108,132,188,228, 60, 54, 44, 57,131, 78,137, 9,104, 34, 1,176, 1, 20,110,153,175,114,185, 28,114,185,220,235, + 57,190, 88,187,118, 45,214,174, 93,219,172,193, 28, 30, 30,254,204,217,179,103, 67, 35, 34, 34,160, 80, 40, 16, 29, 29,141,242, +242,114, 16, 66,140,193,156, 52, 56,139, 63, 63, 63,159, 2,206,132, 64,127,146, 2,131, 77,254, 31,127,252,177,146,250, 94,235, +206,107, 69, 64,104,104,104,186, 88, 44, 62,231,121,124,249,242,229, 13, 44,127, 0,232,216,177, 35,146,147,147,215,249,178,127, +174,148, 92,107,144,237,255,202,223, 23, 64, 38,150, 34, 46, 46, 14,220,234,128,250,243,161,254,140,183, 63, 43,251,224,185,119, +223, 71,109,105, 25, 98, 35, 90,225,248,137, 75,152,179, 60, 11, 25, 25, 25, 36, 16,178,230,190,231,254,125,119, 57,130, 39,224, +206,192,175,191,254,218,100, 49,160, 70, 61, 0,245,147,136,182, 80,187, 89, 69,105,138,166, 83,219, 24,132,135,200,112, 95,175, + 68,220,215,179, 47,196, 12, 96, 48, 57,112,233,106, 21, 10,180,223,169,194, 66, 67,124,254,131, 58,163, 17, 9, 29,175,194,108, +145,131,114, 70, 13, 5, 20,114, 51, 40, 5,170,170,101, 0, 1,194, 67,237,232,157,112, 1,251, 14,245, 67,120,120, 56,111,235, +223,221,226, 87, 68,198, 64, 66,109,128,253,143,249,206, 33,246,253, 27,221,173,127,119,139,159, 59,118,246,248, 97,215,181,124, +170,236,185, 43, 1, 0,208,186,181, 83, 25,169,170,170, 66, 68, 68,132,203,253,239,143, 2,192, 41, 1,192,155,152,159, 54, 18, +248,247, 62,124,248,242, 4,164, 46,122, 31, 89,111, 61, 9, 49, 33,144,202,248,173,216,225,172,255, 19,151,202,112, 79,251,150, +248,232,191, 27,208,169, 83, 39, 68,182,237,138,190,109,187,194,102,249,195,253, 47,225, 33,147,179,254, 95,159, 59, 26,207,188, +186, 14,237,187,144,102,181, 31,103,253,143,221,244, 49,118,204,156, 14, 18, 63, 24,128,179, 42, 32,224, 44, 17,204, 93,251, 76, + 92, 28, 47,226,232, 99,121,129,100,189,187, 76,217,117,114,173,166, 83,183, 94,208, 43,128,243,184,136,218, 11,229, 40, 95,234, +128, 65, 23,143, 5,179, 23,241,126, 32,171, 87,175, 38, 10,133,130,154, 76, 38,184, 89,158, 84,161, 80, 96,245,234,213,126,148, + 39, 10, 30,106,107,107,223,121,242,201, 39, 83,214,174, 93, 43,143,140,140,132, 70,163,193,202,149, 43,245, 86,171,245,193, 96, +254, 31,206,226,231,150,203,249,155, 16,152,156,156, 76,116,186, 49, 52, 24,228, 15, 0, 28,177,243, 33, 40, 30, 21, 6,173,179, +103,207, 30,188,113,227,198,163,117,117,117,109,108, 54,231, 50, 83, 79,242,191,239,190,251, 48,120,240,224,137, 60,158,179,184, +166,228, 28,222,248,199, 43,248,102,203, 54,140, 27,214, 31,187,242, 15, 58, 13,152,182, 93, 17,217,182, 43, 6, 20, 21,225,193, + 41,179, 42, 46, 85, 26,199,118,136, 9,201,225,107,253, 63,151,185, 5, 75,254, 52, 22,109, 91, 43, 93,202, 5,119,143,124, 60, + 55,129,120, 7, 4, 79,192,157,171, 20,240, 82, 0, 0, 32, 34, 60, 76,251,139,118,179,234,124,252,189,232,210,173,135, 38, 34, + 84, 1,150, 2, 38,139, 21, 69, 69, 69, 40, 47,250, 85, 21, 30, 22, 10,134, 97,124, 14, 92,133, 92,142,141,223,143, 84,113, 25, +240, 77,186, 35, 24, 6,161,161,252,173, 39,110, 9, 96,104,116,107,176, 14,155,147,252,235, 97, 35, 18,159, 37,118, 61,193, 45, +169, 25,179, 96, 85, 3,210, 10,132,252,221,149, 0,247,194, 63, 85, 85, 85,190, 31,128, 15, 37,224,115,183, 85,194,107,151,254, +245,143, 15, 54, 3,194,120,202,105, 31, 29,142,141,135,126,197,111,167,126, 71,146,106, 66, 3,210,247,135,252, 57, 60,242,212, +107,248,186,127, 40,158,122,180,123, 80,218,111, 97,215, 36, 44,202,221, 8,242,198,171,216, 22, 55, 8, 43, 13,191, 53, 56, 63, + 57,178, 5,226,229,254,237, 73, 49,163,219, 98,237,182,220, 28, 92,209,157, 67,121,229, 85,148,158, 14,131,200, 17,129,161,125, +134, 67, 53, 91,117, 75, 39,181, 96, 84,251,163,148, 30, 34,132,140, 33,132,236,124,255,253,247,229,147, 38, 77,210, 27,141,198, +177,129,196,252,155, 66, 48,150, 0,170,213, 81, 65, 33,127, 79, 43, 53, 72,168,152, 58,117,106,215,218,218,218, 55, 10, 11, 11, + 23, 20, 23, 23,163,174,174, 14, 82,169, 20,109,218,180, 65,108,108,236,164,254,253,251,127,203, 83,214, 73, 0, 3,218, 71,135, +227,129, 7, 30,192,175,103,138,209,178,115,207, 6,227,237,193, 41,179,140, 0, 62,224, 67,254, 28,254,172,236,131, 49,249, 63, + 97,230,171,159, 97,196,136, 17,136,139,139,243,170,104, 5,171, 65, 56, 37,192,159,182,110, 76, 33, 19,148,136, 91, 71,250,188, + 74, 1, 3, 64, 68, 68,132,214, 82,117, 89,249,139,246,180, 10,112,102,210, 82, 74, 33,147,201, 16, 25,193,187, 6, 54, 36, 18, +137, 54, 82, 34, 9,250,205,113,174,126,145,221, 8,216,141,174, 12,120,142,248,253, 93,139,197,185,250,207, 30, 63,140,179,199, + 15, 35, 54, 54, 22,229,229,229, 1, 17,127,100,108, 91, 88,121, 36, 71,242,197,204,215, 62,199,129,125,218,160,201,187,112,225, +130,107,183, 63,155,197,124, 29,249,251, 67,252, 28,102,247, 15, 13, 90,251, 1, 0, 89,241,130,139,248, 57,242, 63, 95, 87,167, +154, 28,217, 2, 15,243,180,250,189,225,161,206,169, 4,157,235, 63, 4,144,216,190,102,205, 26,194, 85,251, 91,189,122, 53,113, +175,252,183,110,221, 58,178,122,245,106,215,251, 53,107,214,220,244, 65, 79, 41,221, 79, 8, 25,145,147,147,179, 80,175,215,175, +160,148, 22, 4,251,127, 4, 99, 9, 96, 48,201,233, 6,193, 20, 30, 30,190, 80,169, 84, 46,108,166,156,253,199,142, 29, 27, 10, +160,115,203,206, 61,141, 54,139, 57,164,126,188,233, 1,212, 0, 56,217, 33, 38,228, 49, 56,147, 5,121, 99,204, 43,107,111, 10, +241, 55, 71,209, 18, 72,254,214, 32, 49, 49,145, 23,249,251, 52, 64,197, 98,177,214,151, 59,254,102,131,139,237,115,196,143,102, + 18, 63, 23,155,174, 41,187,130,154,178, 43,136,141,141,109,150,197, 15, 0,118, 7,235,183,247,161, 41,148, 85,213, 4,252, 91, + 60,193,197,246,131, 69,252,193,110, 63, 46,182,191,197, 96,160,238, 86,127, 63,177,164, 89,196,255,191, 4, 74,233,207, 0,166, + 11, 45,113,235, 49, 99,198,140, 12, 0,159, 93,170, 52, 26,109, 22,179,123, 60, 50,162, 67, 76, 72, 20,252,220,253,143, 35, 85, +119, 55,255, 29,164, 84, 9,184,137, 74, 0, 47, 67, 43, 49, 49, 81, 72,236, 16, 32, 64,128, 0, 1, 2,254,199,192, 8, 77, 32, + 64,128, 0, 1, 2, 4, 8, 10,128, 0, 1, 2, 4, 8, 16, 32, 64, 80, 0, 4, 8, 16, 32, 64,128, 0, 1,130, 2, 32, 64,128, + 0, 1, 2, 4, 8,184, 43,208, 96, 21,192,252,249,243, 3,206, 34,245,182,221,228,237, 46,239,240,225,195, 1,203,235,215,175, +223, 13,151, 23,236,251,109,217, 50, 49, 96,121, 21, 21,191,222,234,231, 75,234, 21, 86, 22, 94,138,175,220,137,253,239,102,201, +171, 47, 76,196,212,183, 33, 5, 64,231,207,159,207, 10,237, 39,200,187,147,228,101,102,102,138,211,211,211,237, 0,240,209, 71, + 31,209,110,221,186, 97,196,136, 17, 68,104, 63,239,242,252, 86, 0,238, 6, 52,183,200,196,212,169, 83,149, 0,220, 75,134,170, + 54,110,220,168, 21,116,197, 91,131,154,154,154,199,143, 29, 59,214, 87, 36, 18, 45,146,201,100, 48, 26,141, 47, 12, 27, 54,236, + 93, 4,161,210, 30,165,212,239,106,140,119, 34,230,207,159, 79,193,115,147, 25, 1,183, 14,185,185,185,202,148,148, 20,109,128, +223, 85,229,229,229,237, 14, 70, 65,169,122,121,143,229,229,229,109, 88,179,102, 77, 52,156,123, 26, 56,112, 11,170, 91,186,131, + 35,255,189,123,247,210,159,126,250, 9, 73, 73, 73, 24, 49, 98,132,208,113,130,229, 1,184,211,145,159,159,175,108,206,247,167, + 78,157,170,220,184,113,163,102,234,212,169,238,135, 53, 83,167, 78, 13, 88, 9,224, 20,138,236,236,108,174, 84,167, 95,178,210, +211,211,169,159,255,175,201,245,192, 59,119,126,226,175, 60,149, 78, 23,122, 43, 20, 32,242,219,111,191,189,163,215,235,255,212, +177, 99,199, 22, 21, 21, 21,168,223,110,247,237,175,191,254,250,237,208,208,208, 81, 15, 62,248,160,166, 89,255, 32, 0,242, 87, +171,231,251, 61, 9,102,100,172, 38, 55, 79, 94,211,229,112, 27,219,244,133,239,248,218,184,113,163, 6,175, 18,144,127,121, 87, +168,240, 42,193,212,147,105,126,183,235,184,113,227, 40, 0,108,223,190, 61, 40, 4,198,109, 5,172, 86, 71, 5,125,125,124,110, +110,174, 50, 47, 47, 79,227, 15,217,254,229, 47,233,148, 82,231,214,234,222,240,240,195, 19, 85,121,121,121,154,148,148, 20, 18, + 64, 63, 30,181,109,219,182, 93, 35, 71,142,196,188,121,243,104, 86, 86,214, 24,189, 94,159,239,207,111,243,162, 52, 98,218, 16, + 41,212,243,212, 85, 47,124,177,248,219,183,166,191,245, 8,119,110,237,218,204, 38,127,227,172, 89,179, 40, 0,132,134, 54,190, +181, 65, 93, 93, 29, 0, 96,206,156, 57, 1, 61,159, 83,135, 84,200,207, 60,130,228,244, 76,154,158,158, 46,212, 63,224, 1,174, + 56,144,123,141, 0,177,143, 1,239,181,110, 54,143,122,218,183, 10,205, 34, 4,119,242,223,184,113, 35,153, 58,117, 42,117,147, +235,247,253,114, 10, 5, 71, 52,245, 27,126,248,175, 80,100, 71,251,241, 95,147,125, 94, 81,247,240, 95,249,139,243,115, 95,155, +198, 8,200, 79,175, 12,169,169,169,249,170, 87,175, 94, 83, 0, 48,148, 82, 40, 20, 10,148,149,149,161,186,186, 26,145,145,145, + 40, 43, 43,219,253,253,247,223,171, 30,124,240, 65,191,148,147,252,252,124,202,109,204, 66, 8,193,148, 41, 83,144,156,156,172, + 34,132,240,150,147,155,187,217,245, 62, 37,101,146,207,207,190, 96, 58,240,212, 31,205, 61,100, 85,131,207,158,199, 20, 67,124, +111,170,196,109, 39,236,142,189,123,247, 98,233,210,165,215, 61,139, 47,190,248,130,242,108, 55,101,118,118,182, 6,175,146,122, +130, 77,187,126,226,126,149, 52,219, 66,188,141,231,150, 6,150,118, 70, 70,134,138, 82,138,245,235,215,211,253,251,247,163, 79, +159, 62, 62,191,123,160,145,154,140,155,178, 23, 33, 47, 47, 79,195,178, 44, 50, 51, 51,225,107, 91,101, 66,136,146, 82,234,234, +175,223,126,251,109, 8, 33, 4,211,167, 79, 47, 5, 16, 55, 99,198,140,157,107,214,172, 97,252,177,216,223,221,249,174,235,253, +181,237, 87, 65, 8, 65,214,179, 33, 0, 8,222,153,245,246, 35, 45, 91,182, 4, 0,124,249,105, 22,230,141,156,199, 75,230,128, + 1, 3,208,165, 75,151,160,180,123,102,102, 38,147,158,158,206,126,244,209, 71,244,167,159,126, 66,233,233, 78, 64, 69,148,192, +234,126,146,191, 39,152,166, 38,242,236,236,108,100,102,102, 82,111, 19,104, 32, 59, 67, 53,215, 66,247, 37,207,205,202, 14,216, + 40,220,184,113, 35,217,184,113, 35,225,148, 0, 0,170,230, 40, 20,132, 16,164,165,165,129, 82, 74,220,126,155,223,138, 10,153, +170,115,189,248, 28,247,133,176,173,171, 93, 47, 62,199,253, 33,127, 74, 41,184,221,217,124,237,210,230,173, 79,234,116,186,207, + 34, 35, 35,167, 0, 96,230,206,157,139,153, 51,103, 66, 42,149, 66,161, 80, 64, 46,151,131, 16, 2,145, 72,132,154,154, 26,222, +237,152,147,147,163, 84,171,213, 52, 39, 39, 7,110,207, 4, 95,127,253, 53,230,205,155,167,201,201,201, 81,222,142, 3,215,155, + 66,112, 43, 60,107,217,217,217,154,140,140, 12,242,216,169,169, 94, 45,124,181, 90, 77,167,158, 76, 83,121,243, 12,248,194,188, +121,243,232,243,207, 63,143,206,157, 59, 7,229,247,206,155, 55,143,170,213, 81,136,137,217, 21,212,118,216,188,121,243,232,252, +252,252,221,125,251,246, 37, 31,126,248,161,150, 35,255,230, 96, 83,246, 34,172, 88,177, 2, 44,203, 98,209,162, 69,224, 35,211, +157,252, 1, 96,219,182,109, 91,234, 93,225, 81,211,167, 79,183,143, 28, 57, 18,106,181,154,229,107,180,120,142,209,149, 43, 87, +226,177, 7,156,182, 97,214,179, 10, 76, 27, 34,197, 11,227,158,231,125, 79,161,161,161, 24, 49, 98, 4,210,211,211, 73,114,114, +178,215, 23,119, 13, 95,101, 47, 61, 61,157, 5,156,219,172, 3, 64, 68, 72,133,192,234,205, 36,255, 38, 21, 0,142,172, 10, 11, + 11, 93,101, 39,221,173, 39,127,137,214,101, 65, 4,121, 82,242,162, 12,168,130,217,120, 27, 55,110,212, 4, 65,134, 75,161, 72, + 75, 75, 83,113,109,120, 55,193,157,252, 1,160,184,184,216,117,238,202,149, 43,188, 21,198,154,154,154, 55,141, 70,227, 44,134, + 97,152, 25, 51,102,160,166,166, 6, 37, 37, 37,144, 72, 36, 16,139,197, 16,139,197,144, 72, 36, 80, 40, 20, 48,153, 76, 94, 75, +162,122,153,224,148, 59,119,238,212, 16, 66,144,154,154,138, 53,107,214,144,228,228,100,146,145,145, 65, 82, 83, 83,185,254,163, + 17,166,138,166,201,191,190, 45, 85,220, 36,238,254,236,211,210,210, 84,201,201,201, 90, 32,176,146,180,201,201,201,100,205,154, + 53, 36, 59, 59, 27,148,210,160, 40, 99, 47,189,244, 18,178,179,179,121,245, 17, 95,248,230,155,111,198, 28, 58,116, 40,191, 83, +167, 78, 48, 24, 12, 52, 52, 52,148,238,219,183, 15,128, 43,201, 50, 32,242, 95,190,124, 57, 8, 33, 96, 24, 6,135, 14, 29, 2, + 39,211, 15,143,196, 35,132, 16, 76,155, 54,205, 94,127,200, 58,125,250,116,189, 82,169,196,188,121,243,216,111,191,253,214,231, +189,187,135,194,174,109,191, 10, 16, 96,253, 51,127, 84, 45,206,122, 54, 4,211,135,202,176,248,193, 23,120,255, 46, 62,150, 63, +159,107,246,238,221, 75, 51, 51, 51, 93,175, 67,135, 14,193,112,105, 0, 96, 53,129,132,217,145,255,250, 73,184,159,231, 94,194, +200,109, 72,254,233,139,223,242,122, 94,220,212,128, 44, 42, 42,162,133,133,133,200,206,206, 6,247,158,115,237,248, 51,200,111, + 52,249,187, 91,213,220, 36,116,187,194, 61, 36,112,183,129, 82,138,226,226, 98, 92,187,118,205,117,204,243,179, 15,136,126,252, +241,199,241, 9, 9, 9, 16,137, 68, 56,123,246, 44, 40,165,248,253,247,223, 97,181, 90, 65, 8,129, 88, 44, 6, 33, 4, 14,135, + 3, 70,163, 17,155, 54,109, 66,114,114,211, 97,143, 93,187,118,105, 0, 32, 53, 53,245,186,126, 91,255,153,114, 68,193,167, 95, +123,186,245,125,125,230, 99,229,115,104, 44, 28,192,199,245,239,101,242,108,118,146,148, 43,230,239,166,192,113, 10, 44, 23,243, +207,119, 35,255, 64,172,117, 78, 9,227,200,104,215,174, 93,154, 64,195, 0,156,188,110,221,186, 93, 71,110,129, 96,245,234,213, + 56,121,242, 36,141,141,141, 69,187,118,237, 92,219, 62, 95,184,112, 1, 34,145, 8,255,249,207,127, 2,250, 7, 35,135, 58,183, + 47, 99, 89, 22,127,251,219,223,176,114,229, 74,236,219,183, 15,132, 16, 60,156,242, 23, 92,188,192,111, 3,199,109,219,182,109, +174,127,198,102, 56, 87,200,176, 0, 48,125,250,244,106, 0, 45,242,242,242, 64, 8,225,173, 80, 57,173,255,235,247, 49,113,134, + 3,128, 47,179, 14, 35,183, 38,247,166,121,203, 78,157, 58,133, 67,135, 14, 53, 56,230,168, 62, 15,187,141, 5, 72, 45, 90, 60, +104,195, 33,143,205,174,147,146,146, 4,230,231, 65,254, 77, 42, 0,245,110, 23,194, 89,253, 28,249,123,141,253,249, 65,214, 77, + 89,130,124,226,196,190,228,121,158,191, 85, 59, 82, 77,157, 58,213, 61,214, 76,189,157,231, 60, 3,205, 34,221,141,193,141,131, + 25, 38,206, 15,200,242,111,108,178,141,143,143,191,238,218, 38,158, 73,139,232,232,232, 94, 22,139, 5, 85, 85, 85, 56,112,224, + 0, 68, 34, 17,172, 86, 43, 76, 38, 19, 88,150,117,237, 74,105,179,217, 96,177, 88,120,133, 24,184,231,208, 88,191, 77, 78, 78, + 38, 57, 57, 57, 52, 59, 59,219,167, 50,225,180,186,110, 76, 14,128, 98,200,170,235,136,158,251, 28,136, 34, 48, 98,196,136,230, + 43, 1, 30, 49,255,252,252,124,165,139,236,255,136,249, 7,148, 35,227,161,132, 1,112,238,182,168, 86,171, 41,159,231,192,215, + 11, 80,159,251,224,119,110, 1,183,179, 99,187,118,237, 16, 17, 17, 65, 60,149,221, 94,189,122, 5,108,249, 83, 74, 97,183,219, + 93,199,134, 13, 27,134,125,251,246, 97,207, 15, 14,188,187,140, 95,140, 61, 55, 55,119, 92,125,236,255, 4,128,150, 0,220, 55, + 27, 42, 1,208, 2, 0,242,242,242, 52,125,251,246,245, 41,175, 97,236,223,139,167,160,254, 47, 95,121,193, 64,122,122, 58, 73, + 74, 74,162,154,207, 98, 97,175,254, 21,132,173, 6, 28,206,157, 86, 25,145, 29,250,125, 12, 36, 82, 49, 44,142, 22, 56,120,161, + 47, 94, 89,174,195,161, 67,135,136,183,101,213, 2,252, 84, 0, 60, 61, 1,254, 90,254, 69, 69, 69, 52,152,238,110, 95,242,234, +195, 18, 65,243, 52,100,102,102,146,244,244,244,128,190,235,249, 59, 51, 50, 50, 12,106,181, 58,172,177,243,129,194, 61,246, 31, + 12,101,192, 61,246,207, 87, 25,152, 57,115, 38, 66, 67, 67, 17, 22, 22,134,240,240,112, 68, 70, 70,178, 81, 81, 81, 76, 94, 94, + 30, 30,127,252,113,215,117,114,185, 28, 99,199,142,133, 90,173,166,141,236, 86, 21, 99,181, 90, 81, 85, 85, 5,179,217,140,200, +200, 72,200,100, 50,216,237,118, 80, 74,225,112, 56, 96,181, 90, 97,179,217,224,112, 56,252,202, 47,240, 21,178, 74, 77, 77,197, +237, 16,154,241,149, 16,232, 47, 56, 37, 32,224,254,245,175,198,219,110,234,201,180,250,188,155,192,100,123, 90,255,238,138,100, + 32,201,128,158,214,127, 83,138, 41, 95,242, 23,137, 68, 52, 34, 34, 2,112, 38,212, 17, 0,212,102,179,161,166,166, 6,173, 90, +181, 10,232,190, 57, 99, 74, 44, 22, 99,193,130, 5, 56,116,232, 16,254,136,251,243,239,211,223,127,255,253,247,195,135, 15, 7, +128,112, 56,195,185, 70, 0,216,176, 97, 67,171, 61,123,246, 68, 80, 74, 93,202, 54,159,117,226, 43,223, 95,137,105,131,175,183, +254,103,254,219,136, 13, 7,108,160,148,162,223,140,126,152, 55,114, 30, 9,116,221,121,160, 74,128,106,118, 38,253,126,101, 71, +136, 13,122,192,238,252,215, 44, 0,169, 24, 40,190,214, 2,187, 47, 13,112,100,126, 89, 46, 58,116,232, 16, 73, 74, 74,146,227, +127, 28,124,172,127,128, 71, 37,192,252,252,124,151,235,223, 61, 31,128, 15,186,116,233, 66,210,210,210,130, 22,147,231, 33, 47, +224,248,250,212,169, 83,169,231, 43, 63, 63,159,229, 86, 5,184,173, 8, 8,180, 19,135,221,205, 29, 46, 51, 51, 19,203,151, 47, +111,208,175, 56,242, 79, 73, 73, 65, 74, 74, 10, 0, 96,207,158, 61, 77,137,137, 46, 42, 42, 50, 59, 28, 14,232,116, 58, 84, 84, + 84, 64,167,211,193,104, 52,194,104, 52,194, 96, 48, 64,175,215,163,166,166, 6, 38,147, 9, 22,139,197,149, 20,212, 36,137, 17, +130,156,156, 28,191, 20,182, 59, 25,123,247,238,109,240,114,199,169, 83,167,148,238,159,249,196,156, 61, 99,254,158,150,123,115, +178,246,189,125,119,205,154, 53, 36, 39, 39, 39,168,185, 0, 57, 57, 57,188,231, 46,142,252, 25,134,161,245,253,203,229,250,103, + 89, 22,165,165,165,232,214,173, 27,153, 63,127,190,223,191,229,229,197, 35,177,103,207, 30,176, 95,181, 0,165, 20, 43, 86,172, +112, 61,163,189, 7,120,231,237, 33, 55, 55,119, 18, 0, 76,159, 62,189,184, 94, 1,176,124,249,229,250, 86,243,231,207,111,181, +103,207, 30, 60,244,208, 67, 99,252, 89,166,120,109,251, 85, 16, 16,172,119,179,254,103,188,111,132,104, 90, 13,190, 60, 96,197, +115,207, 61,135,101,223,191,125, 43,230, 21, 17,167, 4, 60,248,156, 29,212, 20, 9,232, 1,232, 1, 81, 45,160, 47, 5,182, 29, +110,131,204, 47,203, 69,245,222, 2,113,122,122,186, 89, 32,127,223,228,239,211, 3,144,153,153,217, 32,238,239,158, 15,192,119, +237,101,189,187, 80,197,185,229,155,235,146,247, 38,143,115,251, 39, 39, 39,107,131,181,132, 40, 57, 57,249,183,252,252,252, 94, +183,227, 3,230,172,254, 96,185,255, 57,171,223, 95,247, 63,135,245,235,215,187,222,255,243,159,255,196, 39,159,124, 2, 0, 86, + 0, 82,142,248, 1, 96,236,216,177,190, 20, 0, 83, 66, 66, 2,140, 70, 35,172, 86, 43,202,203,203, 33,147,201, 32, 22,139, 93, + 30,128,186,186, 58, 24,141, 70, 88, 44, 22,212,212,212, 96,202,148, 41, 62, 21, 76,206,186,111,106, 89, 43,119, 29, 31,220,200, + 28,128, 64,206,123,130, 91,238,231, 13, 43, 86,172,208, 44, 88,176, 64,213,189,123,119,237,173,236,195,141, 89,255,238,240, 39, + 23,160, 49,235, 63, 80,203,159, 97, 24,202,178, 44, 1,240, 15,174,107, 59, 28,142, 87, 67, 67, 67, 17, 31, 31, 31,208, 28,243, +202,139, 35,161,213,106, 65,114, 98, 0, 0, 59, 94, 9,199,216,215,107, 49, 98,196, 8,188,177,108,143, 95,133,169,182,109,219, +182,105,228,200,145, 0, 80,190, 97, 67, 86,187, 61,123,246,181,160,132, 98,252, 67,227, 83, 82, 82, 82,182,248, 51,157, 0,206, +216,255,180, 33,146,134, 22, 63, 40, 22, 60,183, 0,113, 99, 91,223,178,130, 89,233,233,233, 13, 52,124, 90, 11,200,172, 0, 75, + 9,236, 14, 10, 25, 5,226, 20,140,251,245,118, 8,112,242,247,178, 23, 27, 85, 16, 56, 15,172,152,143,229, 63, 96,192,128,235, +242, 1,252,113,209,121,146,118, 16,200,217, 83,158,230, 6,116,188, 94,249,249,249, 65,147,119,183, 38,254,113,133,101, 56, 55, +113,118,118, 54,158,120,226, 9, 0,144,114,215,184,159,171,159,180, 26,195,241,193,131, 7, 63,174,213,106,179, 29, 14, 7,244, +122, 61,108, 54,155, 43,238,111, 54,155, 93, 75, 12,185,196,192,177, 99,199,106,121,244, 23,146,157,157, 77,235,189, 0, 13,250, +109,126,126, 62,119, 28,201,201,201,188,188, 85, 55, 59, 7,192, 51, 44,224,235,121, 52,117, 94,173, 86,211, 21, 43, 86,104, 30, +123,236, 49,124,245,213, 87, 1, 61,115,207,229,183,220,231,141, 27, 55,106,210,139,213,152,234,195,210, 30, 55,110, 28, 61,127, +254, 60,190,255,254,251, 70,219,251,252,249,243, 0,128,237,219,183,251,252, 61,105,105,217, 52, 45,109, 52,198,140, 41, 66, 81, + 81,145,215,236,242,202,202,209, 0,116, 80,171, 27,159,183, 56,242,183, 90,173, 84, 42,149,114,215,252,163, 94, 33,120,245,226, +197,139,232,216,177, 99, 64,150, 63,195, 16,167,194,206,145,255, 81, 59, 62,209, 88, 1, 0,111, 44,219,227,247, 28,193,141,137, +249,243,231, 39, 82, 74, 49, 97,226,132, 41, 15, 79,124,248,155, 64,166,166, 73,143, 62,114,130, 16,114, 31,165,128,104, 90, 13, + 40,165, 88,176,112, 1, 90,143,109,243, 71,224, 35,112,112,236, 76,209,140, 74,130,153,153,153,116,227,139,109, 17, 86,121, 30, +231,244,241,232, 44, 43, 7, 66,227, 32,174, 43, 69, 68, 93, 37,128, 86, 46,143,129,167,210, 32, 32, 0, 15,128,251,114, 63, 15, + 87, 31,205,206,206, 6,223,132, 41, 79,210, 14,214, 15,119,151, 23,132,245,255, 2,154, 9,119, 23,186, 59, 9,113,245, 36, 60, +207, 53, 18, 67,180, 3,248,122,228,200,145, 79,231,229,229,125, 96,183,219, 81, 93, 93,237,202, 1, 0,128,242,242,114, 84, 87, + 87,131, 82, 10,127,194, 75, 99,198,140, 81,237,220,185, 83,147,157,157,141,156,156, 28,234, 25,243, 31, 51,102,140, 95,197,128, +110, 4, 76, 7,158,242,155,240,189, 17,124, 83, 74, 64, 70, 70, 6,153, 55,111, 30, 13,132,252, 27, 36, 0,186, 61,119,183,164, + 64,127,189, 0,141, 42,238, 23, 46, 92,112, 41,104,124, 13, 13,247, 80,229,245,247,205,111,174,170,169,169,161,145,145,145,238, +228,255,170,197, 98, 65, 73, 73, 9, 58,119,238, 28, 16,249,171,213,106,202,126, 21,133, 29, 71,157,198,233, 58,141, 21, 27, 14, + 88, 65, 41,197,190, 31, 3,143, 44,238,221,187, 23, 15, 61,244,144, 42,208,242,193, 28, 65,179, 44, 43, 1,128,175,126,180,225, +185,231,158, 67,235,113,109, 60,252, 3,254,129,171,242, 55, 98,196, 8, 10,120, 95,238,231, 86, 9,144,247,243,237,200,212, 1, +177,137,120,124,109, 13,128, 56,103, 27, 60,217, 18, 29,196,151,241,122,114, 25, 62,213,104,132,170,128,104, 88,233,207,211,242, +247, 60, 47,110,106,162,200,204,204,164,222,150, 77,249, 19, 2,240, 66,218, 65,131,135,188,160,174,255,247, 40, 7,236, 55,210, +210,210,192, 35, 97,145, 55, 26,115,247, 7, 26, 6,104,204,221, 31, 72, 24,192,189,188,172, 39,249, 52,117,174,177, 91, 37,132, +172,154, 48, 97,194,154,245,235,215,219,164, 82, 41, 44, 22, 11,236,118, 59, 88,150, 69,139, 22, 45,160,211,233,144,230,231,210, +179,212,212, 84,109,106,106, 42,217,185,115, 39,205,201,201, 65,118,118, 54,184,186, 0,183,115,229,185, 96, 99,247,238,221,116, +194,132, 9,216,186,117,107,179,201,223,147,228,242,157, 10,153, 79,111,220,243,207, 63,127,157,113,225,137, 23, 94,120,129,242, + 77,242, 84,171,163,124,202, 83,171,249,197,255, 21, 10, 87,233, 75, 74, 41,133,209,104, 68, 73, 73, 73,192, 49,255, 6,158,143, +215,107, 27,124,110, 14,249,127,248,225,135,193,234,179,108,238,183, 91,186,185, 87, 2, 12, 22,154, 82,200,214,173, 91,231,151, +245,175, 78,237, 90,242,241,105,180,205,200, 57, 7,119,238, 25,241,159, 76,186,123,222,189, 56, 83,170,192,153, 51,103,160, 82, +169, 32, 32, 8, 30, 0, 0,104,140,228,111, 71, 45,235,118, 91,255, 31,140, 37,126,127, 40, 34,201, 65,251, 93, 83,167, 78, 85, +249, 91,222,215, 7, 49, 80,119,133,198, 91,162,149,231, 57,158,132,107,159, 57,115, 38,217,177, 99,135,242,210,165, 75, 26,147, +201, 4,135,195,129,251,238,187, 79,149,148,148, 20,240,243, 30, 51,102, 12, 25, 51,102, 12, 55,195, 7, 20,154,185,209, 57, 0, +190, 62,243,177, 56,235,179,195, 27, 18,142,159, 69,102,184, 54,194,171,132,230, 35,237, 58,123, 48, 61, 61,157,166, 23,171, 65, + 26, 22, 2, 34, 0,112,230,204, 25,218,196, 88,245,217,232,163, 71,143, 38,126,140,125, 18,140,107, 0,160,170,170, 10, 10,133, +130, 18, 66,208,177, 99, 71, 16, 66, 72,183,110,221,208, 92,242,103, 30,211,129, 16,130,148, 71,156,171,138, 8, 33,174,229,126, +156, 59,255, 22,129, 29, 48,171,127, 80, 5,206,153, 51,135, 83,254,195,234,189,122,118, 56,221,255,172,219, 53,126,221,112, 70, +206,185,182,238,220,195,185,250,211,211,211,137,122,195, 61,135,103, 0, 0, 32, 0, 73, 68, 65, 84,151,134,158, 57,115, 70, 96, +243, 96, 43, 0,119, 10,130,177,214, 63, 88,132,125, 3, 20,155,160,254,174, 96,111,236,115,163,173,231,250, 24,191,215,255, 97, +181, 90, 33, 18,137, 32, 18,137,110, 98, 95, 91, 77,110,111,121,141,143,133, 89,179,102,249, 47,240,213, 63,246,177,200,206,206, +110, 48,105,167, 23,171,221, 45,111,237,221, 48,151,180,110,221,154,252, 49, 86,156,201,182,205, 37,127,231, 51,105,106, 43,160, +235,177,122,245, 79, 55, 77, 35,152, 55,114, 30,185,217,115,130,159,243, 70, 40,156, 57, 69, 54, 55,229,211, 21,231, 87,169, 84, + 68,176,252,125,195, 91,104,128, 36, 38, 38, 10, 5, 19, 4, 8, 16, 32, 64,128,128,255, 49, 48, 66, 19, 8, 16, 32, 64,128, 0, + 1,130, 2, 32, 64,128, 0, 1, 2, 4, 8, 16, 20, 0, 1, 2, 4, 8, 16, 32, 64,128,160, 0, 8, 16, 32, 64,128, 0, 1, 2, +238, 10, 52, 88, 5, 48,127,254,252,128,179, 65,189, 21,118, 17,228, 9,242, 4,121, 55, 79,222,146, 37, 75, 26,106,247, 12,227, + 90,230,232,190,212,140,171,166,232,190,244,204, 91,249,224,176,176, 48,200,229,114,215,247, 25,134,113,173,184,112,151,199,109, +204,196,178,206, 85, 94,220,102, 57,194,243,245, 71, 30, 81,138,196, 50, 80,214, 14,150,181,107, 3,145, 71, 41, 85, 29, 57,114, + 68,156,152,152,152, 15,143,170,123, 1,202, 83, 30, 57,114, 4,137,137,137, 90, 97,188,221,121,242,252, 86, 0,254, 23,241,242, +203, 5, 13, 26,238,141, 55, 6,146,219, 74, 94,193,203, 20, 0,222, 24,248, 6,113,127, 31,168, 60,174, 82,156, 90,173, 70, 70, + 70, 70, 83,215, 53,121,222, 93, 30,220,150,233,113,223,113,255,190, 90,173,118,157,227, 43,247,127, 17,140,181, 78, 89,254,219, + 1,140,136, 42,215,180,179, 95,198,105,218, 25,135,234,162, 85, 17, 9,131, 32, 13, 13,215,250,250,254,254,253,251, 49,108,216, + 48, 23,241,115,132, 77, 8,185,142,176, 89,150,117,189, 46, 94,188,232, 85,222, 47,191,252,130, 1, 3, 6, 64,161, 80, 64, 44, + 22, 67, 36, 18, 53,144,201,145,190,195,225,112,189, 44, 22, 11, 10, 11, 11,113,207, 61,247,220,141,143,136, 56,121,145, 42,127, +255,253,119,156, 57,115, 70,211,162, 69, 11, 12, 31, 62,188, 89, 99,156, 16, 70, 41,147, 71,163, 69,212,189,154, 58, 67,177,202, + 80,123, 89,233,175, 12,150,101,149, 57, 57, 57,187, 79,159, 62,141,173, 91,183, 66,161, 80, 96,209,162, 69, 34,184,173,189, 15, + 64,158,166,232,220, 89,236,220,177, 29, 82,153, 12,207, 61,183, 96, 20,165, 84, 35,140,212,187,212, 3,112, 39, 33, 39, 39,199, +167,198,147,154,154,234,115, 96,114, 4,237, 73,220,129, 34,216,242,130, 13,183,202,124,188, 38, 45, 62,165,101,249,202,171, 87, + 4,154, 85, 93,156,171, 42,232,254,255,239,248, 81, 72,169,242,196,254, 29,136, 56,255,163,198,104,180,192, 54,136,129, 34,158, +160,219,165,163,184, 63,156,106,116,229, 63,227,215,144,217,170, 10,210,174, 73, 37,224,196,137, 19, 16,137, 68, 24, 62,124, 56, +196, 98,177,235,197, 41, 4,156,213,111,183,219,225,112, 56, 96,179,217,112,241,226, 69,236,222,189,219,171, 60,163,209,136,195, +135, 15, 99,240,224,193,144, 74,165,144, 72, 36, 13,100,178, 44, 11,187,221, 14,187,221, 14,155,205, 6,147,201,132,195,135, 15, +195, 96, 48,220, 22,250, 84,125, 63, 99,240, 71, 33,154,128, 57,122,201,146, 37,172,199,220,130,218,218, 90,196,196,196, 4,180, + 0,125,201,146, 37, 13,126,207,231, 89,133, 80, 40, 90, 65, 36,146,106, 12,181,151,253,150, 89, 80, 80, 0,131,193,128,193,131, + 7, 95, 76, 78, 78,110, 83, 89, 89,137, 29, 59,118, 56,162,163,163,145,148,148,212,228, 24,153, 51,110,244,117,109,115,236,212, + 41,104,195, 67,176,112,197,191, 46,247,235,223,171,253,213, 43,101,216,145,167,221,221,169, 87,191,100,189,190,102,151, 64,157, +183, 63,184,210,191,238,240,172, 5, 32,110,106,146,229, 38, 87, 95,159,111, 5,249,255,245,175,127,109,242, 26,157, 78,135, 47, +191,252,146,242, 81, 2, 56,178,110,174,181,126, 35,228,185, 91,254,205,181,254,221, 72,152, 0,160,106,181,218,231,198, 49, 60, +201,154,112,196,206, 89,251,238,150,191, 59,213,241,237, 51,110,158, 10,234, 94, 78, 24, 0,170,170,156,149, 17,163,163,243,239, +138,129,122,225,167,124,220,115, 89,163,185,108,100, 49,249, 30, 17,238,141,181,131,141,166,144, 68,139, 80, 91, 41,133,162,214, +132, 30, 71, 86,105, 10, 19,230,169,140, 33, 29,181,141, 91,146, 4, 39, 79,158,132, 84, 42,197,168, 81,163, 92,164, 45,145, 72, +192, 48, 12, 40,165,176,217,108,176,219,237,176, 88, 44,184,124,249, 50, 52, 26, 77,163, 91, 42, 51, 12, 3,155,205,134, 35, 71, +142, 96,248,240,225, 80, 40, 20,144,201,100, 46,121,156, 2, 96,177, 88, 96, 48, 24,112,236,216, 49,152,205,102,191, 10, 51,105, +181, 90,165, 72, 36,210,212,214,214, 66, 42,149,162,172,172,236,169,201,147, 39,215,202,229,242,207, 3, 33,109,173, 86, 59, 85, + 36, 18,125,229, 38,239,244,228,201,147,127,151,203,229,169,112,238, 80,233,183, 37,252,202, 43,175,104,150, 46, 93, 90,134,250, + 29,103,150, 44, 89,130, 19, 39, 78,160, 85,171, 86,141,214, 93,247, 69,254, 31,207,157,139,241,253,250, 1, 0, 90, 63,253, 52, + 20, 33,113, 48,232, 47, 65, 95,115, 78, 69,169, 67,235,175,204, 62,125,250,160,172,172, 12,251,247,239,239,200, 48, 12,142, 29, + 59,134,232,232,104,236,221,187, 23, 86,171,213,103, 59, 86,190,185,176,193,231, 48,171, 13,109,237,102, 60,247,252,171,237, 87, +188,251, 79,188,243,238,135,104,199, 56,240,225,187,203,243, 71, 77,155, 33,176,235, 29, 72,254,220,113, 94,123, 1, 0,215,215, +255,246,245,249,102, 34,152, 59,245,221, 9,112, 87, 2,154,233, 1,224, 8,150, 0,160,159, 60,250,153, 87, 66,126, 98,211,108, +222,100, 93,239,218, 39, 94, 38,108,247,239,187, 20, 4, 62, 33, 0,238,127,123,254,245,244, 0,220,233, 48, 87, 87, 40, 71, 88, + 14,107,202, 68, 14,220, 19, 9,116,236, 64, 33,234, 35,133,184, 75, 23, 72, 45,102, 88,126,184, 12, 75,141, 24, 34, 86, 2,115, +254,231, 26,102,252,179, 42, 86,236, 61, 28,192,185,231,207,158, 61,139,168,168, 40,168, 84, 42,200,229,114, 72,165, 82,136,197, + 98,151,213,111, 54,155, 81, 82, 82,130, 61,123,246,128, 97, 24, 48, 12,131,166,228, 57, 28, 14, 28, 63,126, 28,195,134, 13, 67, + 68, 68, 4,228,114, 57, 68, 34, 17,236,118, 59,172, 86, 43,244,122, 61,126,254,249,103, 88, 44, 22,136,197, 98, 87, 46,128, 47, +124,241,197, 23, 74,131,193,160, 57,127,254, 60,244,122, 61,164, 82, 41, 90,183,110,189,106,223,190,125, 24, 50,100,136, 56, 52, + 52,244, 19,127,148,128, 47,190,248,226, 81,131,193,240,149,135,188,132,125,251,246, 37, 12, 25, 50,228,203,208,208,208, 84,190, +242, 88,150, 85, 90,173, 86, 84, 85, 85,105,220, 60, 10, 0,128,165, 75,151, 22, 47, 89,178,164, 93,106,106,234, 40,185, 92,238, +215,252,199,136,164, 74,207, 99,215, 62,248, 0,173, 39,197,227,157,119,222, 87,217,108,117, 1,205,167,251,247,239,215,252,244, +211, 79,120,241,197, 23,245, 34,145, 40, 66, 46,151, 99,200,144, 33,208,104, 52,200,203,203, 67,187,118,237,252,240,119, 16,124, +113,246, 42,190, 62, 83,140,220,111, 63,133, 72, 68,176,240,233,199,217,190,173, 91, 50,153,207,189,138,181,254,202, 19,112, 75, +200,223, 83, 57,245,166, 20, 4,188, 10,224, 86,111,111,219,165, 75, 23,149,175,215,205,182,214,111,132,188, 96, 88,253,141,225, +147, 71, 63, 35, 79,108,154, 77,189,145, 63,248,135, 8, 26, 88,250, 85, 85,201, 46, 11, 29,127,108, 1,234,183,219,191, 41,162, +143,142,206, 15,200,250,183,219,237,202,159,127,254,153, 54,118,204,243, 92, 99,112,191,222,110,183, 43, 61,207,121, 30,107, 10, + 85,199,127,209,148, 20,235,209, 42, 92,140, 46,225, 20,226,150, 44,196, 15, 60,136,208,190,159, 67,209,255, 61,200, 34, 21,144, + 26, 76, 48, 26, 29,232, 32, 50, 98,239,250,198,149, 39,134, 97, 32, 22,139, 33,145, 72,112,230,204, 25, 28, 59,118, 12, 17, 17, + 17,136,137,137, 65, 76, 76, 12, 90,182,108,137, 22, 45, 90,160,166,166, 6,123,247,238,133, 72, 36,114,197,246,189,129, 59, 47, +149, 74,225,112, 56,112,250,244,105,132,132,132,160,101,203,150,104,213,170, 21, 98, 99, 99, 17, 22, 22,134,211,167, 79,195,102, +179,185, 66, 4,141, 41, 20,158,150,127,105,105,169,230,220,185,115,232,220,185, 51,198,141, 27,135,129, 3, 7,194,104, 52, 98, +247,238,221, 56,114,228,200, 71,102,179,153,119,237, 98,173, 86,171, 42, 45, 43,255,166,232,106, 13,194,239, 25,140,132,113,127, + 66,187,129, 41,208, 89, 24,236,204,223,133, 35, 71,142, 76, 54,155,205,127,225, 75,254,122,189, 30, 71,143, 30,213,236,223,191, + 31,125,250,244,193,146, 37, 75, 90,162, 62,158,190,100,201,146,118, 0,224, 15,249, 51, 34,169, 50, 52,172,173, 50, 58,166,151, +102,253,134,163,152,251,241,199,200, 59,124, 24,121,135, 15,163,245,211, 79, 3, 0,108,182,186, 61,129,140,227,188,188, 60,154, +155,155,139, 41, 83,166, 92, 12, 15, 15,103, 66, 66, 66, 10, 11, 10, 10,176,127,255,126, 84, 84, 84, 32, 33, 33,193, 47,121,239, + 31, 62,131,119, 15,254,134,181,239,190,116, 84, 44, 50,129,113,212,226,237,149, 31, 51, 95,237, 45, 68, 9, 35,198,189,247,222, + 43,176,236, 93, 2, 38, 80,130,191,133,155, 87,220, 24, 11,251,229, 2, 26,204,184,125,176,229,221, 72, 69,224,137, 77,179,169, +251,171, 49,175,128, 47,175,194,117,228,214, 80, 25,240,215, 83, 65, 26, 59,238,233, 21,224,131,218,218, 90,229,174, 93,187, 52, + 5, 5, 5,141, 30,115, 63,215, 20,220,175,223,181,107,151,166,182,182, 86,233,126,206,243, 88, 83,136, 48, 87, 34,239,146, 25, +219,206,179,184,172, 35, 40, 45, 7, 24,113, 36, 24, 18, 3, 98,150,161,174,148,224,232, 37, 22,199, 46,153, 81, 89,107, 67,239, +104,153,134,143, 2, 32,147,201,112,238,220, 57,156, 58,117, 10,209,209,209,136,138,138, 66, 84, 84, 20,140, 70, 35,246,239,223, + 15,137, 68, 2,169, 84,218,228, 94, 10,156,119,128, 83, 2, 40,165, 40, 42, 42, 66,116,116, 52,226,227,227, 17, 27, 27,139,162, +162, 34, 56, 28, 14,200,100, 50, 72,165,210, 6, 43, 15,188, 77, 43,220,155,242,242,114,205,149, 43, 87,208,179,103, 79, 60,248, +224,131,152, 56,113,162,106,226,196,137,170,225,195,135,195,225,112,224,199, 31,127, 68, 81, 81,209, 96, 0,188,226, 9,229,229, +229,187, 75,171,106, 16,221,181, 47, 18,146,231,160,231,132,249,232, 49, 97, 30, 58, 62,240, 40,172, 84,196,201,227,245,124,235, +115, 31, 52,103,206,156,225,238, 85, 85, 79,252,204,146, 37, 75,176,116,233, 82, 44, 93,186,244,148,103, 94, 64, 99, 16,137,229, +202,168,232, 30,154,214,237,134,105,162, 98,122,128, 48, 98,124,244,137, 6,115, 63,254, 24,115, 63,254, 24, 75,151, 46, 69,121, +121, 57,248,202,243,176,252,233,150, 45, 91, 48,100,200, 16,244,239,223,191, 35, 0,249,174, 93,187, 6, 92,184,112, 1,199,143, + 31,135,201,100,194,132, 9, 19, 70,241,149,151,245,251,101,188,247,243, 41,172,121,227,249,170,248,123, 59,246, 49, 26,116,200, +250,102, 23,142, 30,251, 29,123,191,219,137,154,107,165,152, 48, 97,124, 50, 4,220,182, 72, 76, 76,108,212,250,231,149, 3,144, +145,145, 65,242,243,243,149,124, 63,223,201, 8,166,165,126, 35,228, 1,193,115,255, 55,106,133,186,197,212,253, 37,127,206, 11, +224,110,157, 7, 3,190,146, 15,253,129, 86,171, 85,150,148,148,104,184,205, 93, 26, 59, 22, 8,206,158, 61,139,202,202, 74, 77, +219,182,109, 85, 74,165, 82,219,216,177, 70,137,171,226, 50, 14, 92, 53, 97, 66, 72, 8,246, 93,102,209,182,191, 12,157, 45,133, +208,157,248, 43, 54,189,125, 20,236,133, 26, 24,172, 20,197,181, 14, 40,196, 12,236, 53,215, 16,217,132,210,238,174, 4,200,229, +114, 92,188,120, 17,167, 78,157, 66,207,158, 61,161,211,233,112,240,224, 65, 87, 44,223, 87,188,158, 16,226,242, 2,112,242, 40, +165,184,124,249, 50,122,247,238,141,252,252,124,176, 44, 11,185, 92, 14,137, 68,226, 90, 37,192,199, 3,112,233,210, 37,152,205, +102, 12, 24, 48, 0,241,241,241, 42,145, 72,132,136,136, 8, 12, 26, 52, 72,117,240,224, 65,205,165, 75,151,160,215,235,143,129, +167,203,254,210,165, 75, 96, 25, 41,218, 37, 38,163, 69,124, 2, 24,145, 4,138,136, 88,116, 24, 52, 1, 23, 15,230,162, 94,222, + 5, 95,114, 40,165,202,234,234,106, 77,113,113, 49, 58,116,232,128,161, 67,135,170, 68, 34,145,118,216,176, 97,100,201,146, 37, +116,240,224,193,246,250,121, 51, 33, 50, 50, 18,245, 10,138,163, 41,153,114,121, 12, 98, 98,251,194,106,169, 65, 69,229, 97, 88, + 44,186,209, 54,155, 97, 32,128, 55, 7, 15, 30, 12, 0, 40,189,118, 13,245,242, 36,112,219,244,166, 41,252,242,203, 47,169,235, +215,175,199,204,153, 51, 49,108,216, 48, 0, 96,119,236,216, 33,206,203,203,195,220,185,115,199,246,233,211,103,167, 63,125,249, +180,222,136,197,123,126,197, 91,127, 83, 99,248,196,228,232, 58, 67, 5, 54,126,179, 7, 25, 31,125,141,109, 11,231,160, 75,217, + 21, 44,211, 95, 67,116,116,140,144, 4,120,135,192,221,237,239, 45, 95,165,209, 28, 0,207,216,190,175,207,119, 35,130,189, 4, + 47, 80,188,126,255,235, 42, 66,200,109,217,222, 30, 75,253, 26,228, 1,120, 42, 3,193, 92,254,199, 87, 57,200,205,205, 85,150, +150,150,106,172, 86,107,147,199,154, 3,157, 78,135,186,186, 58,141, 94,175, 87,121, 59,150,146,146,210,232,179, 59, 82,101, 66, +141,149,197,145,114, 59, 74,170,237,136, 59, 40, 70,159,141,103,113,241,194,113,252,254,147, 21,118,177, 8, 86, 22, 48, 91, 41, +116,148, 69,108, 20,109,146,176,221,151,255,113, 25,251,165,165,165,232,216,177, 35, 46, 92,184,224,114,249,139,197, 98,215,245, +254,134,243,220,107, 8,112,127,111, 80, 72,176, 26,205,203,222,191,206, 24,247,117, 1,203,178,168,171,171,115, 78,142, 98,177, + 74, 36, 18,105, 61, 60, 73,226,220,220, 92,164,164,164, 48,139, 23, 47, 46, 93,182,108,153,125,241,226,197, 77,222, 60, 33, 78, +133,200,100, 44,133,161,246,178,202,225, 48,107, 1,236, 5,240,102,109,109, 45,114,115,115, 93,202,228, 61,247,220, 99,245, 37, +175,190,127,165,228,228,228,100, 79,152, 48,193, 69,254, 63,252,240, 3,179,121,243,102, 40,149,202,137,254,146,255, 85,163, 5, +143,231, 29,196,115, 83, 39, 32,245,241, 41, 48,154,245,216,148,171,197,202, 15,179,240,217,216,251,209,165,236,138,192,166,119, +129, 50,224,169, 4,220,148, 74,128,106,181,154,186,199,116,125,125, 22,112,221,196,126, 67,201, 63,208,152, 58, 71,252,158,217, +254, 30,174,127, 82,255,242,122,109, 99,253,197, 87,191,224,219, 95, 82, 82, 82,180,221,186,117, 83, 69, 69, 69, 53,121,172, 57, +136,138,138, 66,183,110,221, 26, 16,189,183, 99,222, 96,114, 68,192, 70,128, 67, 21, 22,148, 57, 28,216, 85,100,198,198,108, 51, +118, 95,137,197, 89,105, 36,174,212,216,112,185,150, 69,157, 29, 48,218, 41,100, 49,173,125, 18, 51,183,190,223,225,112,192,110, +183, 35, 38, 38, 6, 97, 97, 97,232,216,177, 35,108, 54,155,235,184,183,130, 64,158,242,184,245,253,118,187, 29, 38,147, 9,148, + 82,180,111,223, 30,197,197,197,104,211,166, 13,196, 98, 49, 44, 22, 11,172, 86,171,235,255,242, 9, 15,118,232,208, 1,114,185, + 28,133,133,133,184,114,229,138,198,225,112, 64,175,215,147,159,126,250, 73, 99, 48, 24,208,161, 67, 7, 68, 68, 68, 60,200,119, +142,234,208,161, 3, 24,214,138,226,195,249,168,190,114, 26,172,195, 6,147,190, 28,151,126,250, 14,214, 58, 29, 39,175, 19, 31, +229,134, 67, 76, 76,140,134,101, 89,151,167,115,233,210,165,228,248,241,227,168, 39,109, 22, 64,156,183,130, 71,158,176,219, 77, +176,219, 12, 80,132,182,134, 92, 17, 13,128, 40, 1,216,151, 46, 93, 26,227, 38, 15,107,215,174,229, 10, 40,121,189,231,202,202, + 74,250,217,103,159,209,140,140, 12,250,175,127,253,235,219,148,148, 20, 76,156, 56,145,243, 6,232,183,108,217,130,212,212,212, +148,169, 83,167,126,199,167,205, 42, 43, 43,233,231,159,127, 78,167,253,245, 41,140,202,217,131,191,205,158,140,103, 94,152, 15, +179,213,128,243,231, 46, 35, 35, 99, 35, 54, 63, 60, 4,202,246,173, 2, 30, 27,155, 55,111, 22,230,245, 91, 8,207,112,128,103, + 34,224, 77, 45, 5,236, 25, 54,240,245,249,166, 89,250,141,196,234, 61,173,125,190,214,127, 99,242, 10, 94,126,153, 22,188,252, +135, 59,223,243,179, 47, 79, 68,176,228,185,131,115,249,127,242,232,103, 36, 16,247,127, 70, 70,134,203,178,111, 44,222,207, 29, +119,191,214, 23,124,229, 15,248, 19, 30, 80, 42,149,218,135, 31,126, 88,229, 94,156,198,219,177, 64,112,207, 61,247,224,225,135, + 31,110,224,234,247,118,172,209,239,119,187, 7,221, 66, 69, 8, 39,128,141, 82,156,212, 89,177,254,172, 5, 95, 30, 40,193,207, +231,170, 80, 98, 2, 42,205, 14,156, 51, 80, 92,181, 80, 24,172, 54, 85, 83,228,197, 45,205,179, 90,173, 48,153, 76,104,211,166, + 13,122,245,234, 85,175,232, 69, 99,224,192,129, 46,194,230, 72,187, 49,194,230, 8,221,102,179,193,106,181,130, 16,130,174, 93, +187,162,186,186, 26,151, 47, 95, 70, 85, 85, 21, 58,117,234, 4,134, 97, 96,181, 90, 97,177, 88, 92,223,241,133,216,216, 88, 85, +124,124, 60,142, 31, 63,142,239,191,255, 30, 91,183,110,213,108,221,186,117,247,190,125,251, 32, 18,137,240,192, 3, 15,160, 75, +151, 46, 38,240, 44,100, 19, 27, 27,155, 18, 23, 29,137,202,162, 95,241,251,206, 79,112,252,187,213, 56,249, 93, 6, 46,254,184, + 25, 50,134,229,228, 21,251,146, 35, 22,139,181,113,113,113,170,136,136, 8, 28, 57,114, 4, 87,174, 92,209, 24,141, 70,165,187, + 34, 80,239, 9, 96,214,175, 95,143,158, 61,123,250,252,109, 86, 75, 13,106,170,207, 66, 34, 9, 69,139,232,238,154,208,176,118, +144, 72, 66,149,132, 48,131,185,107,194,171,243,161,249,236, 25,140,233,110,224,148,230,235,240,221,119,223, 65,161, 80,160,103, +207,158,232,212,169, 19,234,195, 7,118,157, 78,103,200,201,201,105,145,152,152,152, 50,106,212,168, 45,124,251,110, 94,222,119, +136,136, 8,195,136,145,131,140,137,253,251,224,209,191,206,133,145,216, 81, 94, 86,133,121, 79,191,134,101, 73,247,160,127,171, +192,149,228,205,155, 55,211,183,223,126, 91, 80, 2,110, 19, 69,192, 27,110,155,189, 0,110,245,170,130, 64, 8,216, 95, 12,124, +195,169, 64,184, 19, 53,119,236,102,201,115,183,194,159,216, 52, 27, 79,108,154,221,224,189,251, 49,190, 22,187,187, 39,193,155, + 71,161,185,121, 1,238,158, 0,207,191,124, 17, 30, 30,174, 29, 61,122,180,106,224,192,129,141, 30,115, 63,215,100,187,187, 93, + 63,122,244,104, 85,120,248, 31,203,242,188, 29,107,210, 58,148,133,170,122,183,105,137,161, 49, 50,220, 31, 37, 69, 91, 57, 3, + 25,165,144, 91,236,232, 16, 38,134,142, 82,252,102,176,227,116,157, 29,237, 90,197,160,211,253, 35, 27,149,197, 89,253,220, 82, +191, 14, 29, 58,160,111,223,190,208,233,116,168,174,174, 70,117,117, 53,194,195,195, 49,120,240, 96, 88,173, 86, 87, 77,128,198, + 8,155, 83, 38,108, 54, 27, 8, 33, 72, 72, 72,128,201,100, 66,121,121, 57,202,202,202, 80, 94, 94,142,186,186, 58, 36, 36, 36, + 64, 44, 22,187,228, 53, 86, 87,192, 83, 41,139,139,139, 83,117,237,218, 21,231,207,159,199,246,237,219, 81, 80, 80,128,144,144, + 16,140, 26, 53, 10,125,251,246,253, 78, 46,151, 47, 4,207, 16,128, 82,169,220, 18,215, 42,118, 86,215, 54, 45, 96, 56,247, 19, + 78,111,255, 8,197, 5,223, 34, 74,230, 64,242,232, 81,232,219,183,239, 28,185, 92,158,203, 71, 86, 68, 68, 4,250,247,239, 15, + 74, 41, 14, 28, 56,128,194,194, 66, 77,113,113,177,166,170,170, 74,185,100,201, 18, 21, 87, 57, 49, 41, 41, 9,123,247,238,245, + 41,143,101,109,218, 26,221, 89, 85, 85,249, 49,200,228,209,104,221,246, 1, 77,108,235,129,154,240,136, 78,223,189,243,238,191, + 31,230,228,125,249,108, 8, 54,252, 96, 65, 99, 74,207,233,211,167,209,178,101, 75, 12, 27, 54,140,189,255,254,251, 97, 52, 26, + 81, 87, 87,135, 85,171, 86,133,117,239,222,125,210,180,105,211,182,248, 51, 38,126,255,253, 52, 58,118,136,199,180,105, 41, 33, +175,188,252, 28, 42,107,107, 80, 81, 89,129,244,103, 94,195,107,143,142,198,232, 14,113,205, 34,255,149, 43, 87,162, 87,175, 94, +248,224,131, 15, 4, 37,224, 38,226,215, 95,127,109,180, 14,192,117, 10,239,237, 66,240,254,172, 42, 72, 77, 77, 37,193,170, 4, +232, 11,158,133,120,130,161, 4, 4,131,252, 3,149,215, 88,169, 94, 79,203,220,159,146,189, 30, 74,130,171, 40, 80,115,238,203, + 93,105,112,183,246, 3, 89, 1,224,110,221,221,127,255,253,164,177, 99,158,231, 26, 67, 83,215,243,149,193,225, 1,229, 40,109, +145,152,194, 94,144,135, 11, 53, 64, 24,145,160, 99, 24,131, 98, 7,129, 72, 38,198,222, 50, 7,204, 44, 16, 43, 19,161,107,210, + 8,200,187, 37,105,155, 82, 0,108, 54, 27, 68, 34, 17, 58,119,238,140,254,253,251, 67,175,215,195,108, 54,187,214,231, 91,173, + 86, 68, 71, 71, 99,216,176, 97,216,178,101,139, 43, 36,224, 13, 14,135,195,149,213,223,163, 71, 15,212,187,233, 97, 54,155, 93, +227,153,243, 36,244,232,209, 3, 85, 85, 85, 48, 24, 12, 77,141,229, 6, 39,102,205,154,165,213,106,181,163,122,246,236,185,219, +173,112, 79,245,240,225,195,119,203,229,242,153, 0,204,254,180,229,172, 89,179,214,107,181, 90,125,207,158, 61,115,221,228, 85, + 12, 31, 62,124,149, 92, 46,255,148,175, 28,134, 97,180,109,219,182, 85,141, 27, 55, 14,231,207,159,215,156, 58,117, 10,151, 46, + 93, 66,120,120,184,166, 69,139, 22, 24, 51,102, 12,254,251,223,255, 34, 41, 41,137,247,111,179,219,141,218,106,221,239, 42,179, +185, 10, 45,162, 18, 52, 97,225,237, 17, 30,209, 1,117,181,197, 91,222, 90,246, 17,166, 79, 75,198,151,207,134,120,109, 39, 14, +227,199,143, 71, 94, 94, 30,174, 92,185,194, 84, 85, 85,193,108, 54, 99,239,222,189,226,122,165, 83,239,239,120,152, 48, 97, 60, + 54,109,218, 2,125,117, 37,174,148, 92,197,179, 79,206,182, 62,255,226, 82,233,163,163,134, 96,152, 69, 15, 72, 2,163,135,205, +155, 55,211,127,252,227, 31,174,114,208, 93,187,118,197,219,111,191,141, 23, 94,120,129, 78,154, 52,233,206,175,220,121,135, 42, + 5,183, 76, 1,184, 17,171, 10,130, 65,238, 28, 42, 42, 62,194,203, 5,223, 54, 89,109,207,159,228,191,138,138,143, 80,240,242, + 31,242,220,137,217,211,101,207,135,180, 43, 62,170, 64,193,183, 47, 7, 77, 94, 48,193,199, 67,192,237, 1,224, 79,127,249, 95, + 26,156,157,134,168, 84, 71, 45,118, 77,249,238, 93,144,216, 77, 56, 90, 75,145, 95,107,135,148, 16,196, 80, 10, 85,155, 22,136, +106, 29,171,138, 31,164,244, 97,105, 58, 61, 0,157, 58,117,194,192,129, 3, 97, 50,153, 96,179,217, 32,149, 74, 93,132,205, 89, +233,177,177,177, 24, 58,116, 40,182,111,223,222,164, 7, 64, 44, 22,163,111,223,190, 32,132,192,104, 52,186,188, 11,156,210,206, + 85, 23,100, 89, 22,189,123,247,198,193,131, 7,225, 79,114,165, 82,169,212,224,143, 60,145, 48, 56,171,237, 93, 2,207, 76,120, +111,158, 0, 55, 89,209, 0,170, 0,248, 93,155,152, 97, 24,109,139, 22, 45,208,187,119,111,149, 68, 34,225,150, 63,106, 0,160, +184,184, 24, 15, 61,244, 16,150, 47, 95,238,151, 76,135,195,162,173, 51, 20, 43,173,214, 26,149, 66,127, 65, 19,209,162, 43, 66, +194,218, 34, 36,172, 45,118,236, 42, 5, 25,221,180,197, 61,100,200, 16, 34,149, 74,105, 85, 85, 21,198,143, 31,111,141,137,137, +145,178, 44,139, 75,151, 46, 1, 1, 36, 75, 62,240,192, 16, 34,147,201,104,196,137, 66, 60,249,228,159, 16,159,208, 77,250,246, +115,127, 98,215,125,248, 41,179, 74,100, 14,168, 47,111,222,188,153, 46, 94,188, 24, 45, 90,180, 64, 73, 73, 9, 20, 10, 5, 88, +150, 69,104,104, 40,222,120,227, 13,188,252,242,203,130, 18,112,131,145,152,152,216,168, 23,128,215, 50,192, 27,129,219,121, 85, + 65, 83,132, 19,136,245,223,152, 60, 79, 75,157,115,221,251, 34,237, 96,203,115,247, 4, 4,122,190, 41,175,130,231,230, 63,254, +202,251, 95, 3,195, 48,218,196,209,227, 72, 85,157, 73, 25,105,183,104, 68, 23,139,112,143,237, 42,194, 99,226, 48,164,119,119, +196,180,107,169,138, 76, 28,233,115,124, 80, 74,209,185,115,103, 12, 27, 54,204, 21,143, 23,137, 68,176, 88, 44,174,210,189,238, + 97,130,246,237,219, 99,232,208,161,208,106,189,139, 86, 40, 20, 72, 76, 76,132, 88, 44,134,213,106,117,125,207,125,233,160,251, + 70, 64, 12,195,160, 95,191,126, 40, 44, 44, 12,164, 25, 40,128,218,250, 87, 48, 96, 8,132,248,189,121,141,122,245,234,197,229, + 81, 16,150,101,149, 70,163, 17, 22,139, 5,221,187,119,199,138, 21, 43,252,220, 28,135,106,109,214, 90,216,172, 6,149,201, 84, + 14,153, 44, 10, 18,105,184,134, 97,196,248, 98,253,119,170, 89, 51, 39, 52, 41,175,190,174, 63,121,239,189,247, 88,147,201, 4, + 0, 72, 72, 72,240,171,252,178, 59,250,247, 31, 64, 68,247,223,255,208,220,127,188,151,231,148, 71,153,132,132,123,145, 48,105, +210, 44,177, 88,188, 62, 16,153,203,150, 45, 19, 6,245,109,162, 4, 52, 69,254, 55, 85, 1,184, 83, 17,204,101,127,158,196,220, + 92,107, 61, 88,242,154, 99,113,187, 19, 59,247,222,195,101, 47,116, 34,158, 24,149, 50, 73, 91,111,189, 98, 68, 0,223, 79, 75, + 75, 67, 84, 84,148, 43,195,159,101, 89,151, 11,159,243, 0,112, 73,127,220,142,128, 93,187,118, 5, 33, 4, 27, 54,108,184, 78, +222,202,149, 43,145,157,157,237,186,214,225,112,248,220, 14, 88, 42,149, 34, 41, 41, 9,124,178,227,239, 84,101, 45, 44, 44, 12, + 97, 97, 97,136,137,137,105,198,216,225, 20,129, 90, 48,140, 24,206,116, 44, 86,195, 83, 30, 93,180,104, 17,169,127,158,148, 97, +152,102,205, 35, 14, 7,187,109,193,130, 5, 4, 0,195,178,172,131, 97, 24, 5,252, 12,191,112, 16,172,251,219, 75, 9,240, 5, +146,152,152, 40, 36,103, 8, 16, 32, 64,128, 0, 1,255, 99, 96,132, 38, 16, 32, 64,128, 0, 1, 2, 4, 5, 64,128, 0, 1, 2, + 4, 8, 16, 32, 40, 0, 2, 4, 8, 16, 32, 64,128, 0, 65, 1, 16, 32, 64,128, 0, 1, 2, 4,220, 21,104,176, 10, 96,254,252, +249, 1,103,112,174, 94,189,250,186,100, 66, 65,158, 32, 79,144,119,247,201, 83,171,213,244,145, 73,106,124,187, 57, 3, 25, 25, + 25, 12,188,172, 65, 23,218, 79,144,247,198, 27,111,184,174,121,249,229,151,137,208,126, 55, 87,158,223, 10, 0, 55,184, 27,187, + 56,144, 37, 47,119,178,188, 64,100,222,238,247,235, 5, 82, 0, 17, 0, 66,234,251, 3, 11,160, 2, 65, 88, 67, 29, 76,112,237, + 16,140,123,246,214,166,183,170,248, 80,109,237,255,111,239,202,195,154,184,214,247, 59, 73, 8, 1, 65, 22, 17, 17,149, 42, 32, +138,184, 32,238, 90,149, 88,144,130,128, 91,209,254,106,123,107, 55,162,183,215,122, 91, 84,172,116,177, 11,173,120,181,155,183, +173,161,183, 85,219,122,111, 43,181,130, 59,149, 26, 92,170, 86,197, 21,180, 42,224, 86, 65,169,202, 78, 66,150, 57,191, 63,194, + 96, 8, 89,102,146, 32,216,206,251, 60, 60, 9, 39,147, 47, 51,231,204,156,247,253,190,115,206,119,106, 35, 15, 29, 58,164,216, +183,111, 31, 0, 96,226,196,137, 24, 59,118, 44,235, 84,194,237,209, 14, 83,167,201, 16, 23, 27,161, 5,100, 34,153, 76, 70,255, +213, 18, 55,241,176,142,244,244,116,146,144, 16,212,226,127,107, 34,128, 71, 59, 71, 0, 24,144, 77,173, 55,128,160,102,217,190, +111,186,169, 14,194,158,221,255, 28,109,207,212,245,218,115,205, 29,253,122, 25,226, 47, 58,115, 96, 93, 81,209,233, 71,252,122, + 4,117,171,174,214,192,195,195, 9, 55,111,148,208, 97, 97, 67,238,134, 13, 30, 63, 18,192,101, 46, 6, 79, 28,254,140,148,150, + 92, 68,201, 21, 21,174,151, 19,244,234, 78, 33,168,183, 4,129, 65, 33,136, 24,243,247, 14,241,240,155, 18, 18,204, 94, 3,237, + 65,100,103,207,158, 85,132,135,239,198,218,181, 13,200,207, 7,222,124,243, 39, 92,191,126, 93,225,231,231, 7,137, 68,130,178, +178, 50,233,244,233,211,225, 8, 65,112,224,192, 1, 82, 93, 93, 45,141,142,142,134,179,179,179, 45,246, 4, 0, 16, 23, 27, 65, + 39, 39, 39,139,128, 76,228,100,235, 31, 21, 56,118,219, 94, 30,127, 2,168,213,169,200,205, 77, 70, 76, 76, 38, 18, 18, 50,154, + 35, 2,188, 16,184, 63,224, 19, 1,113,128, 33,217, 83, 20, 64,127,239,245,167,189, 86,141,186,254,169,220,221,223, 47, 11, 14, +238,219,127,198,180,137,232,213,163, 51, 60, 61,156, 81, 89,165,194,141,242, 94,130, 75,165,149, 62,219,183,126,165,136,121,116, +246,106, 39,113,167, 53,214,236,157, 59,187, 47,242,242,197,237, 10, 33,106, 48,123, 10, 48,110, 24, 16,244, 16, 80,124,133,224, +224,113, 37,118, 42, 78, 99,199,230,197,164, 79, 72,188,116,192, 32,235, 25,237,218, 42,218, 97, 46,138, 32,151,203,169,246, 18, + 1,119,239,222,197, 75, 47, 53,160,107, 87, 32, 41, 9, 88,177,162, 14, 39, 79,158,132, 86,171,133, 68, 34,129,175,175,175, 98, +251,246,237,232,219,183,175,116,248,240,225,249, 28, 59,128,200,194,194, 66,116,235,214, 77, 17, 29, 29, 77,125,251,237,183, 0, +160,200,203,203,195, 19, 79, 60,129,145, 35, 71,114,189, 86, 49, 0,236,220,117, 66, 0,100,210,250, 87,189,134,230,123, 16, 30, +134,222, 62, 0,204,156,185, 25,185,185,250,215,228,228, 18, 48, 17, 1, 62, 26,112,127,137,223,176,188,221, 82, 1,119,116,144, + 77, 94,205, 34,224,207, 76,254, 0, 68,123,114, 55,189, 38,157, 16, 17, 50, 98,104,119, 80,148, 62,171, 27, 77, 19,116,118,115, + 70,167, 32, 49,122,247,242, 64, 15, 63,183,135,246,228,110,122, 45, 46,225,153, 44, 0, 55, 45, 25,188,124,113,187, 98,252,176, + 26,252,243, 25, 64, 40,212, 11, 40,141, 22,232,228, 10,132, 6, 3,163,195,129,237,138, 26, 28, 57,189, 93, 49, 96,208, 68,155, + 30,124, 71, 13, 1,152,251, 62, 35, 2,238,119, 99,120,123,123, 99,251,118, 23,244,234,165, 68,126, 62, 80, 89, 41, 66,112,112, + 48,130,131,131, 81, 87, 87,135,210,210, 82,228,231,231,163,166,166, 70,209,175, 95, 63,214, 67, 3, 63,254,248, 99,164, 82,169, + 84,136,197, 98, 84, 86,182,140,100, 41,149, 74,124,249,229,151, 40, 45, 45, 37,143, 63,254, 56,151,250,164, 1, 32, 39, 91, 14, + 64, 38,208,191,218,142, 99,199,142, 53,215, 55,179,137,146,169, 50, 54,247,133, 97,219,178, 45,179,234, 20, 16, 18,137, 11, 23, + 48,178,174, 78,209,229,198, 13,252,238,235,139, 19,157, 59, 75,157, 6, 12, 0,161,168,124, 91,175,153,235,134, 81,108,108,176, + 45,107,107,123,134,161,255,228,228, 92, 36, 36, 4, 53,191, 50, 72, 72, 8,226, 69,192,125,128, 49,217, 51,251, 3, 24,150,243, +171, 0,140, 31,250, 63,249,245, 21,157, 57,176, 34, 56, 56, 56,100,100, 68,247, 22,229, 2, 1, 5,177, 88, 8, 23,137, 8, 78, + 78, 2, 4,245,241, 66, 80, 80,176,111,209,153, 3,219, 45, 9,197, 19,135, 63, 35, 66,212,224,229,103, 1, 85, 35,112,249, 58, + 80, 89, 13, 84,213, 0,255,221, 10, 44, 88, 14, 44, 91, 5,140,141, 0, 4,164, 6, 39, 14,127,198,123,139, 6, 24, 52,104,144, + 52, 39, 39, 20,190,190,192, 19, 79,136,224,231, 55, 2, 19, 39, 78,148, 38, 36, 36, 80,241,241,241,210,152,152, 24,116,235,214, + 13, 39, 78,156,192,247,223,127,175,248,233,167,159, 34, 27, 27, 27, 35, 45,217,252,246,219,111, 35, 27, 27, 27, 21, 78, 78, 78, + 22,127, 91,161, 80, 96,211,166, 77,145,108, 72,118,255,254,253, 4,128, 90, 46,151,139,239,137,128,123,100,186,127,255,126,194, + 85, 64, 29, 61,122,180,249,207, 82,153, 45,162,142,109,153, 37,242, 15,252,237, 55,197,244, 83,167, 20,189, 46, 22, 67, 92, 83, +131,238, 23,127, 67,228,145,195,138,174,167, 79, 43, 64, 72,164, 45,237,125,244,232, 81, 28, 59,118,140, 20, 22, 22, 70,218,122, +207, 48, 54,216,148,177,181,103, 76,244,108,202,172,129, 33,125,230, 85,157, 16,204, 63,240,247,137,248,217,164, 1,126, 96, 35, + 0,109,233,169,145, 54, 60, 63, 71,133,152, 25,251,230,126,199,210,111, 20,157, 59, 29, 59,107,134,180,153,244, 77, 65,226, 44, + 66, 85,117, 35, 66,130,188,145,181, 69, 17, 20, 54,120,188,135, 57,123,165, 37, 23, 49,123,138,254,253,238,253,192,167,223, 0, +147,199, 3,113,145,192,111,197,192,201, 34, 2, 23, 9,133,161, 97, 64,204, 68,224,199,220,139,136, 24,227, 56,207,221,150,186, +107,163, 57, 21, 54,193,221,221, 61,191,174, 78, 63,223,242,137, 39,158,192,184,113,227, 40,195,207,238,222,189, 43, 13, 13, 21, + 41, 18, 19, 1,138, 58,142,138,138, 6,197,239,191, 7, 89, 10,255, 69, 82, 20,165, 96,187, 57, 76, 69, 69,133,194,154,238,157, + 51,103, 14, 54,110,220,136,141, 27, 55,146, 57,115,230,180,104,139,253,251,247,147,141, 27, 55, 54, 31,215, 81,250, 3,182,101, +230,208, 88, 88,136, 62, 5, 5, 80, 11, 4,112,162, 0, 45, 77, 64,107,116,160,181, 90,116, 61,176, 31,197,132,160,243,208,161, + 54, 19,184,171,171,171,226,248,241,227,210,185,115,231,230,219,106, 3, 64, 11,143,220, 84,153, 45,209, 5,123,201,223, 28,209, +231, 26, 69, 2,120,180, 63, 76, 10, 0,115,147,223,108, 33, 28,107,132,200,213,222,253, 30,163,181,101,198,184,165, 73,133,182, +216, 51,245, 29, 27, 39, 46,138,252,252,131, 6,248,251,185,129, 16,224,192,225,235,104, 80,234,119, 93,141, 24,226,135,174, 93, + 92,112,253, 70, 45, 93,124,185, 82, 32, 18, 9,208, 55,208, 11,254,254,193,158,208,111,209,106, 18, 37, 87, 84, 24, 55, 12,104, +212, 0,187,246, 1,138,195, 4,254,221, 40, 4, 6, 0,143, 60, 12,244, 15,162, 32, 18,234,183, 22, 31, 29, 14,252, 75,174, 98, + 85,223,134, 33,121, 54,239,217, 40, 94,195,177,126,195,122,119,228, 10, 3, 91,208,180,157, 43, 6, 15, 30, 44, 53,254, 76, 40, + 20, 42, 6, 12,168,192,178,101,122,121,250,222,123, 23,113,229, 74,152, 89, 91, 42,149,202,170,231,111,136, 43, 87,174, 88, 61, +102,194,132, 9,212,132, 9, 19,154,201,126,227,198,141,196, 88, 32, 76,152, 48,161, 93,234,174, 45,188,127, 0,232,123,251,142, + 66,173,209, 64, 32, 16,128, 8,133,160,105, 26, 26,154, 6,173,211, 65,167,163,209,179,188, 92, 81, 51,116,168,205,215,220,208, +208, 0, 0,138, 99,199,142,129,162, 40,206,243, 59,218, 66, 4, 56,202,243,207, 77,206, 69, 76,102, 12,102,110, 6,146,115,245, +239,115,147,115,155,197,129,120, 91, 49,207,188,247, 17,134,115, 2, 88,205, 1, 48,183, 10,192,214,213, 1,230, 60, 46, 91, 60, + 49, 75,162,193, 86,129, 98,233,186,141,191,203,214,139, 48, 55,169,208, 22,123,150,190,195,252, 14, 5,128,222,100,117,238, 2, +173,159,237,239, 12, 0,184, 94, 86, 3,165, 82, 11, 0, 8, 14,244, 66,215, 46, 46, 56, 93, 84, 33,184,112,233, 46, 36, 18, 33, +130,250,120,162,178, 90, 13, 0,102, 13, 95, 47, 39, 8,122, 72,255,251,143, 78, 0,194, 7, 80,112, 22, 3, 90,173, 62, 18,224, +233, 14,148, 94, 3, 98, 38, 0, 15,245,212, 31,223,158, 48, 36,125, 91,198,133, 59, 58, 42, 42, 42,218, 44,138,210, 68,242,205, + 30,127,123,147,191, 33, 50, 50, 50, 72,106,106, 42,101,235,231,198,112, 42, 41, 70,163, 70, 13, 74, 40,130,142, 16, 80, 0,180, + 58, 26, 26, 45, 13,162,211,129,186,116, 1, 64,156,221,231, 93, 88, 88, 8, 31, 31, 31, 69,117,117,181,212,195,195,195,102, 17, + 96,173,236,126,145,127, 90, 90, 26,149,158,158, 78,102,110,110, 41, 8, 0, 32, 38, 51, 6,226,109,197,216,182,173,164,121, 37, + 0, 51, 97,208,219,219,155,103,234,251, 76,254,102, 5, 64, 71,135, 37, 66,180,133, 96,237, 89,226,104,209,110, 27,175, 38,160, +102, 85,114,253, 13,202,195,195, 9,149, 85, 42,248,120,187, 34, 41,177, 63,180, 58, 26,206,206, 66, 8, 5, 2, 16, 66, 16, 63, + 57, 8, 83,162,131, 64, 81,192,157, 74, 37, 60, 60,156, 0,224,174, 57,131,189,186, 83, 40,185, 74,189,136,105, 47, 0, 0, 32, + 0, 73, 68, 65, 84,208, 63, 8,152, 52, 70,223,235,252, 86, 12, 12,238, 15,120,117, 6, 98, 35, 1,154, 6, 68, 66,224,226,101, +253,241,108,219,150,203,123, 91, 19, 97, 88, 19,164,109, 13,154,166, 35,123,244,232,129,146,146, 18,236,223,191, 95, 49,126,252, +120,169,155,155, 27, 4, 2, 65, 62, 0,232,116, 58,233,185,115,190,138,183,222,186, 1,138,162, 80, 81, 17,130,144,144,222,184, +120,241,162, 57,123, 38,203, 55,109,218,212, 58,138, 68, 8,102,207,158,205,233,154, 13, 69, 64, 71, 34,127, 71,136, 4, 67,220, +237,217, 3,226,223, 46,128, 56, 1, 98,154,232, 39,182,234,180, 80, 19, 29, 26,180, 90, 40,131,251, 59,228,220, 7, 14, 28, 8, +138,162,108, 34,127, 0, 24, 57,114, 36, 70,140, 24, 65, 29, 61,122,148, 88, 42,179,134,166,136, 65, 11,194, 55, 85,198, 5,201, +185,247,136, 31, 64, 43,207,159,153, 48,184,109, 91, 9,207,212,237, 64,254, 15,172, 0,104,107, 65,225, 40, 66, 32, 4, 16,204, +174,108, 51, 17,192,172, 92, 16,204,170,100,227,253, 3,128,232,230,141,146,219,215,111,244,244,241,241,118,197, 7,159, 31,195, +132,177,189, 16, 49,184, 27, 40, 39,170,121, 69, 64,211,214,241,184,126,163, 22, 55,111,148, 92, 6, 96,214,173, 12,234, 45,193, + 47, 5, 74,244, 15, 2,124,134, 1, 75,231, 3, 11,231, 2, 30,238,250,176,255, 91,159, 0,203, 23,234,143,253,165, 64,127,188, +173, 4,237, 40, 79,189, 35,229, 2, 56,119,238, 28, 36, 18,125,157,236,216,177, 3,215,174, 93, 83,244,235,215, 79, 58,105,210, + 36,212,214,214, 70,122,123,123, 43, 14, 30,212, 34, 63, 31, 24, 49, 98, 56, 2, 2, 2,164, 61,123,246, 4, 0,133, 41,123,157, + 58,117,130, 90,173,102,245,219, 90,173,246,129,127,118, 13,201,159,141, 16, 96, 43, 2, 74,186,250, 74,157,207,156, 81,208,132, +160,147, 64, 4,161,144,130,150,232,208,160,209,160, 86,173, 70,153,191,191,212,199,142,243,118,117,117, 5, 69, 81,210, 17, 35, + 70,228,219,106,131, 33,122,107,101,247, 91, 4,164,165,165, 81,201, 77,158,189, 49,249, 27,122,255, 60,218,151,252,121, 1,112, + 63, 60,188, 54, 94, 82,216, 44, 2,216, 9, 13,109, 88,216,144,178,226,203,149, 62, 67,194,124,177,116,225,104,172,255,223, 89, +184, 72, 68, 8, 31,232, 11,138,162, 12, 60, 73,130,226,203,149, 8, 11, 27, 82, 8,160,214,156,193,192,160, 16,236,216,123, 26, +115,103, 2,164, 20, 24, 61, 3, 8,236, 5,108,204, 49, 56,104, 33,160,211, 1, 59,246,234,143,111, 47, 88,138, 20,181,215, 50, +192,187,119,239, 42, 66, 67, 47, 99,221, 58, 0,208,225,237,183,207,224,228,201, 6, 69, 67, 67, 3,106,107,107, 81, 90, 90,138, + 91,183,110, 33, 34, 34, 2,179,103,207,182,186, 12,144, 16, 34,165,105, 90, 33, 16, 88, 95,224,195, 8, 15,174, 96,134, 0, 54, +110,220,136, 9, 19, 38,180,235,243,149,154,154, 74, 49,196,111,109, 8,192,218, 49,134,240, 26, 58, 20,119,212,106,232, 20,249, + 80,139,157,224, 70, 68, 80,209, 52,170,213,106,212, 78,122, 4, 62,195,134,217, 24, 21,164, 48, 98,196, 8,155,199,253, 13,109, + 24, 18,189,169, 50,123, 68,192,177, 99,199, 44,150,177,129, 41,242,103, 60,127, 0,252,132,192,118, 38,127, 94, 0, 60,224,104, + 30,255,103, 63, 12,160, 11, 27, 60,126,210,246,173, 95, 29,252,181,192,189,255,168, 97,254,136,141, 10,196,238,159, 75,177,227, + 39,253,195,249, 90,202, 88,208, 52,193,175, 5,101, 40, 41, 41,190, 26,159,248,236, 63, 0,104,204, 25,140, 24,243,119,106,199, +230,197,228,195,175,244, 75, 1,215,190,171, 95,250, 23, 53, 78,191, 20,240,195,215,245,228,255,225, 87,128, 14,157,109,206, 8, +104,175,103,110, 45,130,208, 94,171, 0,234,235,235, 49,116,168, 10, 35, 70,232,255, 31, 62,156, 96,247,238, 82, 92,188,120,145, + 73, 4,132,200,200, 72,244,237,219,151, 85, 14,128,201,147, 39,231,103,103,103, 91,141, 2,104,181, 90,120,122,122, 74,185,158, +111,211,114,192,230,149, 1,251,247,239, 39,182, 14, 3,140, 28, 57,146, 85, 25, 23, 17, 96,237, 56,214, 70, 5,130,124,245,168, + 81,210,243, 78, 78,232, 85, 94,174,112,187,118, 13,170, 62,125,112,197,215, 87,234, 29, 17, 1, 52, 13,209,216, 64,176,142, 32, +233, 86, 54, 76,149,177,173, 75,227,227, 24,194,183, 86,102, 11,140, 73,159,137, 8,216, 59,132,199,163, 53,216, 76,140,230, 5, + 64, 27,122,230, 29,244, 55,238,196, 60, 58,251,163,220,221,223, 47,254,189,188, 54, 40,184,143, 23,166, 76, 14,130,151,167, 4, +149, 85, 42,156, 60,123, 11,197,151, 43, 81, 82, 82,124, 40,230,209,217, 63, 2,184,110,205, 96,159,144,120,233,129,130,237,138, + 67, 5, 53,152, 50, 9,248,226,125,125, 38,192,146,171,192,151,155,244,158,191, 14,157,209, 39, 36, 94,106,235,181,218, 51, 4, +192,150,252,219, 99, 14, 64,121,121,185,212,203,203, 71,113,252,248, 31, 0,128,139, 23, 59, 99,196,136, 1,232,210,165, 11, 36, + 18, 9,202,203,203,165,241,241,241,156, 82, 1,247,238,221, 91,122,225,194, 5,133, 97, 68,199,152,252,131,131,131, 49,114,228, + 72, 78, 36,198,172, 2, 48, 24,251,103, 38, 4,218, 36, 2, 76, 17,161,173,228,104,141,220, 57,145,191,129, 8,232, 50,124, 56, + 26, 0,170,161,169,200,222,169,106,246,146, 63,151,122, 99,251, 91,142,182,199,150,252,213, 9,193, 0, 63,254,127, 95, 34, 1, +230,132, 1,167,101,128,182, 78,150,227,186, 12,208, 86,123,182,218,116,244,249, 89,170, 39, 71,157,159, 61, 19, 23,157,196,157, +228,241,137,207,126, 87,116,230,192,103, 91,114,246, 5,250,245, 8, 26,109,176, 23,192,145,176,176, 33, 71,227, 19,159, 93, 6, +160,158,141,189, 1,131, 38,230, 15, 24, 52,145, 58,113,248, 51,242,253,142,139,120,239,211,142,183, 23, 64, 71, 36,127, 0,120, +252,241,199,113,250,244,105, 60,243,204,241,166, 8,192,112,204,154, 53, 68,234,234,234,154,111,171,205,240,240,240,252,240,240, +112,106,235,214,173,145,181,181,181, 10,161, 80, 8,129, 64, 0,173, 86, 11,177, 88, 12, 55, 55, 55,169, 3,200,223, 33, 34,128, +199,159, 19,105,105,105, 84,122,114, 58,241, 95,224, 47, 69,111,211,199,148, 37,231, 42,248,249, 0,237, 11, 17,219,142,210,209, + 29,111, 91,216,179,229,183, 30,228,235,181, 19,213, 97,131,199, 63, 25, 54,120, 60,147, 49,198, 13,128, 15,128,114, 0, 74, 52, +165,125,229,130,136, 49,127,167,108, 73,242,211,214,245,208,145,242, 74, 24,195,213,213, 53,127,204,152, 49,212,152, 49,142,175, +184,196,196,196,124, 56, 40,185, 37, 51,238,111, 76,242, 19, 38, 76,160, 54,110,220, 72, 58,194,124, 0, 30, 29, 79, 4, 88, 62, + 0, 60,249,183, 1,216,102, 1, 4, 0, 42, 60, 60,156, 31,123,225,193,131, 7, 15, 30, 60,254, 98,224,247, 2,224,193,131, 7, + 15, 30, 60,120, 1,192,131, 7, 15, 30, 60,120,240,224, 5, 0, 15, 30, 60,120,240,224,193,131, 23, 0, 60,120,240,224,193,131, + 7,143, 63, 7, 90,172, 2,152, 63,127,190,205,179, 50, 77, 37,114,224,237,181,141, 61, 54,155,216,180,167,189,188,188,188, 72, + 0,138,172,172, 44,135,216,219,187,119,111, 36, 77,211, 14,179,199,223,127,237,102,111, 54,128, 77,109,124,126, 78, 0, 36,208, + 39,173, 81, 65,191,154,133,192, 40,137, 13,223, 30,188,189, 63,187, 61,206, 2,192, 26, 57,152, 3,151,165, 84,142,182,119, 63, +145,156, 84, 77, 32, 22, 35,115,163, 11,171,243,203,203,203,139,204,202,202, 82, 56,234,122, 13,237,173, 94,189, 90,154,146,146, +162,176,101,123, 97, 83,246, 10, 63,237,140,129, 47,214,192, 30,123, 12,166,141,216,169, 56,125, 65, 7, 0,200,204,204, 36,201, +201,201,118,181,103, 72,183,239,161,212,122,195,197,197, 5, 89, 89, 89, 36, 41, 41,169,163,220, 31, 93,231,189,146,242,205,218, + 15, 86, 63, 5,224, 15, 7,216, 11,152,255,210,203, 95,124,254,201,135, 79,154,177,231, 4, 64, 11,203, 25,217,156,160,207,220, +216,117,225,194,151,191,249,248,227, 15,159,130,126, 51, 39, 26, 14,200,228,102,252, 28,115,188, 55, 14,183, 85, 67, 80, 20, 21, + 39, 16, 8, 6, 8, 4,130, 72,138,162, 66, 0,184,170,213,234, 92,161, 80,232, 73,211,116, 5, 33,228,117, 0,119, 28, 89, 7, + 60,120,152,194, 83, 37, 37,228,155,160, 32,135,245, 81,201, 50, 25,201,108, 35, 78, 20, 89,123,200, 9, 33,150, 30, 58,206, 29, +134,163,236,113,245, 96, 29,137, 61,123,246, 88,237, 68, 24,114, 77, 77, 77,133,175,175,175,201, 12,120, 41, 41, 41, 10,182,191, +201,216, 99,136,255,200,145, 35,205, 66,192, 30,123,244,185, 55, 32, 24,240, 54,190,222,171, 79, 29, 75,159,123,163,249, 24,193, +128,183, 57,213, 75,231,154, 87, 8, 77,128,239,118,235,109,197, 78,116, 66, 88,112, 17, 50, 51, 51, 9, 0,112, 21, 2,213,218, +239, 34,171,174,220,129,146,154,168,168,111,236,132,216,152, 42,244,240,163,112,252,248, 33, 82, 83,163,194,164, 73,147,218, 85, + 8,204, 95,184,240, 37,208,244,228,249, 11, 23,190,244,249,199, 31,191,110,183,189, 5, 11, 95, 32, 52, 29, 61,127,193,194,151, + 62, 95, 99,210,158,134,133, 25, 13, 0,106,193,130,133, 47,209,180,110,242,130, 5, 11, 95, 90, 99,218,150, 0, 54,228,122,176, + 19,106,195,251,239,135, 31,126, 80,204,152, 49, 67, 58,121,242,228,124,123,140, 10,133,194, 88,145, 72, 52, 65, 36, 18, 61, 46, + 20, 10,189, 4, 2,129, 91, 70, 70,134, 96,241,226,197,207,234,116, 58,104,245,120, 92,167,211, 37, 0,248,165, 73, 4,168,155, +250,191, 54, 31, 6,221,177, 99, 7, 97,219,223,197,197,197,113,186,167,119,238,220, 73,236,249, 62, 15,199,195,101,229, 74, 64, + 46,119,152, 61,229,146, 37,118,125,159,201, 8,200,105, 59, 96, 54,228, 63,108,216, 48, 20, 20, 20,112,242,248, 45,145, 60, 27, +123,166,236,167,166,166,162,180,180, 20, 89, 89, 89, 14,221,214, 53, 57, 33,147,192, 37, 4,153,155, 34, 41, 0,200,204,242,160, +184,144,255,234,213,171,165, 21, 21, 21, 10,115,228,159,154,154,138,140,140, 12, 78,228, 15, 0, 73, 73, 73, 24, 61,122,180,116, +244,232,209,118,217, 99,200,158,121, 93,241, 14, 90,144,255,146,153, 18,172,220,172, 98, 85, 87, 30,202, 20, 50, 48, 68,136,122, + 37,193, 43, 79, 73,112,164, 72, 11,101, 61, 65,131, 26,144,134, 23,161,232,162,142, 83, 52,160,244,250,135,164,234,102, 39,184, +119, 22,195,175,187, 27,186,118, 11,198,213, 18, 53,122, 15,208,192, 73, 82,129,188, 45,183,177,101,203, 22, 50,125,250,244,118, +233,240,100, 50,153,179, 79,143, 30, 11,191, 61,114,148,138,237,215,247, 37,153, 76,246,174, 92, 46,111,180,199, 94, 87,191, 30, + 11,191,219,123,132,138, 14,239,103,151, 61,153, 76, 38,246,243,235,190,240, 39,197, 1,106,248,144, 48,115,182,232,118,168,182, +230,237, 7,179,178,178, 20, 9, 9, 9,216,188,121,179, 98,242,228,201,173,218, 48, 34, 34,130,188,245,214, 91, 72, 72, 72,176, +216,190, 34,145,104,146, 88, 44, 30, 40, 22,139, 23,136,197, 98,215,235,215,175,163,111,223,190, 16, 10,133,112,119,119, 71,113, +113, 49,220,220,220, 68,199,142, 29,243, 60,124,248,240,129, 23, 95,124,177, 55,128,171, 0,196,230,234, 32, 57, 57,185,149,179, + 98,216,111, 49,229, 20, 69, 33, 51, 51,211,234,253,183,117,235, 86,179, 54, 12,203, 9, 33,136,139,139,227, 84,161, 57, 57, 57, +118,125,191, 45,113,234,212,169,200,240,240,240,124, 71,216,186,117,235, 22,161,105, 26, 16, 84, 65,221,168,130,216, 89, 2,208, +158, 16, 8, 4,232,214,173, 27, 53,216, 56,114,105, 33, 25,206,195, 15, 63, 76, 54,111,222, 12,115,246,102,206,156,137,131, 7, + 15, 82,182,158, 31, 0,148,223, 58, 79, 12,207,207,158,107,183, 37,154, 96, 46, 13, 48, 43, 1,192,150,252,217, 34, 53, 53,213, +234, 49,108,136,203, 28,249,175, 88,177, 2, 75,151, 46,109, 81,110,171, 8, 72, 30,150, 73,208, 37, 4,153, 63, 69, 82,134, 30, +127,116,116, 52, 5, 0,204,107,113,113, 49, 97, 67,214,150,200,191, 41, 50, 96,213,107,103,194,244,134, 30,190,241,208,130, 45, +246, 44,121,248, 75,102,178,223, 41,206, 71,249, 10,233,251,144, 16, 46,206, 20, 30,242, 23,226,118, 37, 13,141, 86,136, 59, 85, + 4,213,117, 4,197,191,211,128, 0,240,113, 61,131,188,188,188,200,168,168, 40,139,157,194,213,107, 31, 68,134, 6, 7,225,240, +205, 91,232, 19,208, 21, 3, 7, 7, 66,232,236,141,135,250, 84,162, 82,169, 66,197, 77, 29,126,191,165,130,171,168, 20,121,121, +238, 86,237,181, 17,230, 60,181,120,177,184,180,187, 63,156,135, 13, 23,168, 14,236,159, 3,224, 43, 27,236, 48,158,248,156,167, + 95, 90, 36,254, 93,236, 7,183,144, 8, 65, 77,225, 65, 91,237, 1,192,156, 23, 23,190, 44,134,179, 59,250,244, 11, 19, 92, 56, +123,194, 30, 91,142, 4,205, 60, 35, 20, 69, 65, 34,145, 72, 1, 40,140,239,137, 97,195,134,177, 34,127, 0,112,114,114,242,148, + 72, 36,115,111,223,190,237, 26, 18, 18,130,161, 67,135, 66, 36, 18,225,147, 79, 62,129, 78,167,195,160, 65,131,240,227,143, 63, +226,216,177, 99, 56,115,230, 12,132, 66,225,103, 58,157,110,170, 37,155, 83,167, 78,109,238,231,172,245,131,108, 8, 87, 46,151, + 75,253,252,252, 20,132, 16,139, 14,208,205,155, 55, 57,239,149,193,216,182,245,251, 12, 81,159, 63,127,222, 98,191, 17, 26, 26, + 42,229, 74,230,231,207,159, 87, 84, 87, 87,195,195,195, 67,106,143, 16, 56,113,242, 16,121,235,157,249,232,212,201,165,213,103, +245,245, 74,228,252,120, 26,103,228,114,106, 74,247,238,228,122, 98,162,249,190,253,192,106,125, 99, 30, 88,141,238,147,226, 33, +137, 24, 14, 93, 72, 88,203,240,217,119, 27,224,245,254,116, 12, 48, 24, 42, 82, 62,250, 60, 62,183,114,126,203,210,230,193,187, +139,171,190,224,141,143,144,178,232, 25, 0,192,221, 59, 13,120, 47,125, 45,137, 24, 58,214,102, 17,224,232, 33, 5,139, 2,128, +241,216,173,121,234, 29, 5,165,165,165, 88,186,116,169, 77, 2,194, 18,244,158,126, 50,181,103,207, 30,146,149, 57, 18, 16, 43, + 9,155,177,127, 83,100,109, 76,202,150,134, 5,204,193, 80, 80, 28, 57,114, 68, 49,122,244,232, 22,161,127,174,246,254,187,216, +205,108,231, 54,103, 85, 61,107, 59, 52, 77, 71, 58,187, 82, 16, 8, 0, 87, 23,160,170,134, 70, 35, 33,232,228, 66, 65, 69, 3, +202, 70,130,158, 93, 5,160,181,192,165,235, 58,148,150,150, 42, 96, 33, 61,237,185,162, 31, 34, 7, 14,236,175, 16,139, 9, 94, +152, 59, 10, 58, 29,193,205, 10, 53,174,221,168, 2,156,174,195,197,171, 17,229, 21, 87, 32, 16, 87,227,220,185, 42,120,120, 89, +182,215, 86,112,246,246,126,227,241,191,253,205,249, 53, 26,240, 90,154,230,118,235,244,169,215,109, 36, 89, 2, 0, 18, 15,239, + 55,254,239,201,191, 57,175,186,172, 67,207,217,169,110, 23, 74,207,152,178,103,117, 71, 54,153, 76,134,206, 30,158,111,204,121, +242, 41,231, 51,215, 42,145,248, 68,178,219,191,223, 73,177,245,220,204, 70,242,204,149, 91, 17,222, 58,230, 25,137,143,143, 71, + 84, 84, 84,126, 86, 86, 22,148, 74,101,115, 27, 50,158,127,124,124, 60,171, 54,117,118,118, 30, 91, 95, 95,223, 63, 52, 52, 20, + 82,169, 20, 41, 41, 41,120,238,185,231,244,157,185, 70,131,245,235,215,163,160,160, 0, 39, 78,156,192,247,223,127, 15,165, 82, + 25, 76,211,116,172, 37,155, 83,166, 76,113,232,253,180, 99,199, 14, 86, 67,115, 20, 69, 41,184,134,240, 13,109,219,242,253,166, +208,112,126,117,117, 53,202,202,202, 76,126,238,239,239, 15, 91, 9,188,172,172, 12,101,101,101,118, 9,129, 51,167, 47,226,155, + 13,219, 49,126,252, 88,132, 13,234,209, 92, 94,116,246, 6, 14, 28, 56,132, 31, 55,255, 76,178, 94,125, 21,215, 19, 19,225, 50, +110, 28,148,191,252, 98,210, 78,230,248, 20, 10, 0, 46,109, 88, 67, 6, 87,236,198, 83,123,183, 67, 23, 18, 6,229,162,229, 0, + 0,151, 85,203,225,118,177, 8,139, 75,197,232,251,244,130,123,245, 88,127,239, 57,181,116,126, 81,209,227, 90,157, 95,222,158, + 95,112,230,244, 69, 68, 12, 29,107,243,253, 99,203,144,130, 97,184,223, 82, 52, 64,196,213, 99,119, 52,209,218,139,172,172, 44, +187,190,159,156, 41, 35,232, 14,100, 38,232, 59,174,204,130,228, 22, 97,126,189,199, 95, 77,140, 35, 1,108,201,186,162,162,162, + 5, 57,219, 66,214,108,193,136, 14,153, 76, 70,172,229,131,182,228,217, 48, 96,194,255,230,236, 17, 66,200,237,115,175,160,123, + 83,232,191, 89, 49,235, 8, 84,106, 64,211, 84,166,209, 18, 16,129,254,253,217, 51, 5,204, 42, 1,147,112,119,175, 86,212, 43, + 5,240,241,246, 68,213,221, 6, 84, 85, 87,225,200,241,155,184,113,139, 64,220,169, 1, 61,130,235,160,108,184,141,190,131, 53, +232, 29,218,136,239,191, 40,192,238,221,187, 35,239,227, 45, 39,144,201,100, 81, 51, 95, 72,238, 86,230,225,133, 18, 45,224, 18, + 53, 25, 2,175, 46, 62, 50,153,108,178, 92, 46,255,201,128,172,157, 96, 48,238,109,174,223,151,201,100,209, 73,115, 95,232,246, +135,192, 3, 87,235, 52,240,140,136,130,200,221,203,216, 30,192,110, 2, 91,204,180,233, 51,186, 17,161, 51,170,235, 27, 49,112, +216, 24,184,117,246, 48,101,171, 93,192,120,255, 20, 69, 97,219,182,109, 36, 62, 62, 30,219,183,111,135,139,139, 75,100,106,106, +170,130, 11,249, 3,112,174,170,170,122, 90,163,209, 8, 92, 93, 93, 49, 97,194, 4,172, 90,181, 10, 78, 78, 78,144,201,100,216, +176, 97, 3, 10, 10, 10,112,228,200, 17,252,252,243,207, 56,123,246, 44,124,124,124,124,180, 90,237, 67,176, 50, 4,146,156,156, + 76,172, 13, 1,124,241,197, 23,172,206,179, 45,135, 0,182,110,221,234,144, 33, 0, 15, 15, 15,105, 89, 89,153,194,220,103,246, +182,187, 45, 66, 64, 90, 82, 66,238,172, 92,137, 15, 0,224,240, 97,220,157, 25,135,213, 67, 66,154, 67,246, 97, 3, 6, 96,214, +236, 41,232, 93,121, 27,215, 19, 19,209,101,201, 18, 40,130,130,168,193,191,252, 98,241, 57, 17, 75, 31, 70, 72,108, 36, 22, 47, +121, 23,255, 66, 17, 86,143,158,132,129, 35, 70, 33,248,110, 41,214,123, 14, 69,169,199, 45, 12,146, 72,136, 74,165, 98,213,190, +210, 73, 67,240,212,211,241, 56,250,235, 89,236,206,253, 9,111, 2, 88,189,106, 29,194, 6, 12,192, 83, 79,199,163, 65,121, 7, + 18, 14,246,140, 97,239, 28, 0, 78, 17,128, 7, 9,114,185,156,114,196,172,117,134,220,179,150, 94, 6,132, 98, 36, 79,238, 13, +120,246, 70,102,211,130, 37,182, 99,255,142,134,225,181, 49,147,254, 12, 61,127, 99, 48,115, 3,204, 77, 6,180,101, 39,194,141, +139, 58,153,141, 8,184,215,164,224,138,154,224,230,109, 26,128, 0,110,174,250, 16,167, 70, 75,160,106, 4, 84,106, 64,213, 8, +168, 53,128, 74, 9,168, 27,239, 69, 73, 76, 9, 10, 55,237, 43,228,198,181, 0,244,234,227, 6,226, 36,194,109,165, 18,138,125, +215,113,174,248, 6,238,222,173, 67,216, 48, 29,234, 85, 90,168, 26,117, 80, 54,208,184,121, 13, 80,214, 3, 91,182,108, 81,112, +217, 0,195,206, 54,161,133,158,158,111, 60,243,234,171,146,239, 13, 40,196,235,213, 52,183,187, 75, 23,189, 14,224, 39, 3,178, + 86,179, 48, 73, 68,110,158,111, 60,247,242, 82,201,174, 27,186,230,194,158,143, 47,117,187,250,229,171,134,246, 88, 69, 1, 92, +221,220, 95,127,233,149, 69,146,146,178,123,187, 69, 38, 60,145,236,246, 93,230,106, 83,182, 56, 61,107,166,238, 37,142,207, 26, + 97,188,127,137, 68, 34,141,138,138,202,103,150,140, 42,149, 74, 69, 65, 65, 1, 21, 31, 31,207,214,150, 22, 64, 48, 0, 58, 60, + 60,156,150, 72, 36,130, 13, 27, 54,224,217,103,159,197,251,239,191, 15, 66, 8,126,253,245, 87,236,219,183, 15,103,206,156, 65, +117,117, 53,250,246,237,139,154,154, 26, 87,129, 64,224,107,205,248,180,105,211,204,138,100,102,104, 96,202,148, 41,156,194,244, + 29,117, 8,192, 82, 20,192, 30,239,223, 94, 33, 80, 89, 85,213,252,222, 55,109, 30, 6,166,205,199,120,163, 99, 46, 63,250, 28, +122,238, 63,142,146, 69, 47,224, 87,127,127,184, 0, 56, 35,151, 83, 48,177, 44, 78,169, 84,146,158, 61, 59,227,234, 53, 32, 44, + 34, 20, 88,249, 26, 94,254,114, 11,230, 6,157,198,144,198, 98, 44,190, 37,198, 59, 27,151,225,253,244,207,113,230,236, 65,244, +234, 25, 70, 92, 92,204, 71,125, 13,237,121,119,113,197,163,113,163,240,104,220, 40,188, 69,127, 4,117,227, 82,156, 60, 9,156, + 60, 9, 28, 56, 16,143,127,175,185,136,184,184, 88, 18, 16,240, 16,130,130,190,225,196, 79,121, 15,191,134,146,131, 34, 43,125, +247,231,127, 13, 1, 32,147,201, 72, 82, 82,146,148, 25, 51, 52, 22, 1,134, 29, 18, 51, 30,111,235,124, 0,134,244,163,163,163, + 41,253, 48,128, 24,153, 27,239,239,245, 50,179,254,163,162,162,168,188,188, 60, 98, 45, 26, 98,109,217,161, 37, 66,231, 58, 28, +240,244,171,245,240,239, 38,192, 19, 9, 98,168, 26, 1, 15,119, 10, 2,170,201,235, 7,129,170, 1,168, 87, 19,212, 43, 9,234, + 85, 4, 52, 1, 4, 22,230, 92, 63,189,176, 30,131,134,148,194,175,255, 93,236,217, 85,129,187,119, 85, 8, 31, 83,131,193,222, +117,128, 83, 35, 84, 13, 52, 42,110, 16,212,215, 83,208,106, 41,120,251, 80, 0,117,223,231,178,133, 13, 29, 50,100,184, 87, 64, + 0, 14,233, 12,196,203, 19, 79,226,110,106,202, 48,153, 76, 54, 64, 46,151,159,227,112, 63,135,142, 24, 55,113,120, 23,255, 0, + 28, 63,218, 60, 71, 14, 93,165,255,135,171, 95, 44, 53,101,207,210, 86,216, 3,198,141, 27, 63,220,223,191, 39,206,157,184,220, + 92, 62,238,145, 41,248,159,124, 21,231,115,107, 3, 52,159, 59,243,252, 50,195, 0, 12,182,111,223,222,106,254,145,137,185, 0, + 76,163, 7, 3, 56,181,100,201,146,177, 34,145,200,237,235,175,191,198,186,117,235,240,204, 51,207, 96,197,138, 21,160, 40, 10, + 87,174, 92,129, 82,169, 68,106,106, 42,180, 90, 45,230,205,155, 71, 83, 20,101,245, 1,112,228,108,250,142, 62, 4, 96, 41, 10, +224, 8,239,223, 86,108,216,176, 1,127, 75,158,133,234,170, 70, 32,125, 45,234, 15, 28, 71,167,241,195,155, 63,175, 72, 95,139, + 34,103,103, 80,255,120, 30, 3,103, 63,138,195,235,119, 97,240,224, 17,102,237, 93,186, 84,136, 49,227, 98, 81, 88,228,133,181, +159,101, 97,252,248,177,120,231,211,101,120, 43,106, 14,190, 5,208,255,169,103,177,246,179, 44,136,197, 94,152, 58,109, 56,190, +230, 96,239,227, 15, 54, 97, 68,252, 32,188, 59,104, 21, 10,167,184,193, 43,225,199, 22,199,250,184, 74,112, 52, 95,129,128,191, +205,229, 92, 15, 7, 15,138,176,114,165,139, 21, 1,247, 23,138, 0, 24,143, 35,155, 35,248,166,227, 88, 35,179, 64, 63, 67, 93, + 79,252,151,144,245,201,101,232, 87, 1,180, 20, 5,108,134, 1, 28, 29,214,207,203,203, 35,134,222, 63, 19, 17, 48,252, 63, 41, + 41, 9, 76,178, 28,115,137, 33,184,144, 63,179, 10,192,156, 61,173, 14,168,111, 32,104, 84,235, 39,251, 53,170, 9, 68,206,247, + 62, 83, 53, 0, 74, 13,193,157,187, 4,127, 84, 18,156, 56,167, 5, 77, 3, 73, 73, 73,210, 75,151, 46,181,106, 27,173, 22, 40, +187,174,198,245,146, 74, 28, 60, 92, 9, 66, 40,156,251,141, 70,252, 19, 90,136, 69, 4,127,220, 2, 14,254, 4,212,212, 16, 16, + 26,120,120, 18, 5,137, 4,136,141,157,138,171, 87,175,178,186,166,236,245, 50, 50,109,174,237,171, 68, 4,110,157, 95,125, 97, + 69,134, 83, 14, 17,180, 96, 98, 31,103,103, 56,253, 99,161,211,149, 53, 31, 45, 3,240, 36, 91,123, 66, 23,183,101,243, 95, 95, +225,244, 83, 25,105, 97,175, 75, 39,103, 12,156,253,162,211,185, 77,159, 24,219, 51, 27, 1,144,184,116, 90,182,244,141,229, 78, +151,111, 86,183, 56,160,179,123, 39, 76,127,226, 25,167,156,255,126,197,233,220,218, 42,106,103,170, 44, 34, 34,130,156, 56,113, + 2,219,182,109,107,245,157,132,132, 4,147, 77, 1,160, 16,192,169,213,171, 87, 15,241,244,244,116, 99,194,224, 95,125,245, 21, +158,125,246, 89,172, 91,183,174,217,139, 95,189,122, 53,170,170,170, 80, 83, 83, 83,215,208,208, 80,218, 20, 65, 16, 91, 58,215, + 23, 94,120,129, 24,135,232, 25,239,159,109,248,255, 65, 25, 2, 48, 21, 5,112,180,247,207,216,100, 59, 4,112,110,204, 24, 80, + 47,204,134, 39, 0, 50,105, 24, 26, 78, 20,162, 62,125,237,189,122, 75,158,133,190, 79,205,130, 68,162,191,254,162,162, 98,139, +132, 93, 84, 84, 12, 0,136,141,211,139,136,130,227,103,240,237, 55,223,193,117,212, 72, 52,104,180, 80, 67,141, 9, 19,135,182, + 56,158,173,189,235, 58, 53,158,232,246, 34,232, 19,141, 72,250,215, 36,136, 31, 59,130, 1, 97, 3, 16, 54, 48,184,249,252, 82, + 23,175, 65, 80,144,144,245,125,243,200,255, 61, 18,117, 14,231,246,224,127,223, 80,214,166, 0,124,254, 57,218, 38, 17, 80, 71, + 68, 65, 65,129,213,217,228,121,121,121,145,172,151, 20, 58,119, 66, 86,239,253,128,182,128,160, 79, 39, 36,167,247, 65,102,126, + 60, 5,100,146,123,130, 32,218,230, 97, 0,227,165,128,230,150, 6,154,235, 44,101, 50, 89, 51,249, 27, 79, 0,100, 66,234, 76, +153,165, 8,128,161, 61, 71,117,230, 59,119,238,140,188, 81,190, 75, 65,119,165, 33, 16, 1, 78, 2,253,253,173,161, 9,180, 90, +160,182,150, 64,173, 1,180, 26,189, 40,152, 58, 77, 31,189,185,116,233,146, 89,123,141,183,119, 42,194,194,104, 28,216,167, 3, + 37, 0,254,184, 73, 65,226, 2,236,219, 13,168,149, 20, 40, 2, 12,142,112, 66,217, 53, 26, 19, 39, 78, 65, 92, 92, 28,197, 38, + 19, 86,246,122, 25, 89,249, 34,176,228, 83,219, 69, 0,161,117, 49,186, 46, 62,130, 93,244, 61, 22,234, 6,192,143, 2,148,195, +134,137, 46,107,117, 49,156,236, 17, 58, 6,238,222, 2,197, 77, 93,179,189,174, 18,192, 71, 66,193,117,208, 48, 81,209,119,116, +140, 57, 47,218,148,173, 78,238,158,130,171,183,170,154,136, 5,112,119,113,134,187,171, 24, 17,225, 67, 69, 91,190, 37, 49,237, +252,232,154,172,115,102,214,127,124,124,124,243, 61,202, 68,239,102,206,156,105,201, 3,173, 3,112,249,228,201,147,117,227,199, +143,239, 10,131, 53,253, 95,125,245, 85, 51,201,106, 52, 26,232,116, 58, 92,186,116, 9, 93,187,118,189, 77,211, 52, 43,181, 56, +109,218, 52,179, 67, 0, 92,136,246, 65, 24, 2, 48, 21, 5,112,164,247,207,133,248, 25,116,247,247,196, 23, 95,236, 69, 98,194, + 24,116, 27, 22, 6, 12, 11, 3,245,194,236,150,162, 23,192,173,155, 74,108,221,118, 24,221,253, 61,217,219,243,115,193,176,225, +125, 49,108,120,223, 86,199,113,181, 55, 97, 70, 40,210, 38,126, 2,186, 80, 79,254,207, 45,126,218, 38,123,198,120,213,253,213, + 61,239,215,190, 31, 93,142,242, 54,123, 32,237, 18, 0, 5, 5, 5,247, 61,107, 31,227,229, 50, 68, 23, 21, 21, 69,153, 32,127, +194,132, 21,147,146,146,108,250, 29,195, 85, 0, 76, 25, 87,207,223,120, 2, 96, 19,154,203, 82, 82, 82, 20, 73, 73, 73,172, 31, + 50, 67,242, 55, 53, 39,128,171, 61,107, 88,185, 89, 5,107,246,226,226,226,242,151,165,110,197, 35,163,157, 64, 3,208,168,105, + 56,139,245,213, 84, 91, 79,208,168, 33,208,234,128,130, 66, 29,116, 52,129,181, 37,123,113,113,113,249,111,188,182, 21, 19, 35, +133,152, 62, 71,136,186, 90,130,218,106,160,190,150, 66,159,190, 4, 58, 13, 5,145, 64,130,170,187, 52,202,126, 87, 99,209,203, +236, 38,140,101,175,151,145,143, 22, 2, 33, 1,192,154, 87,128, 5, 31,216, 38, 2, 72, 67,253,140,127, 12, 27,186,211, 47,103, +167,155,215,184,135,209, 13, 64, 55, 10,208, 29, 58,136,188,167,159,172,211, 52,212, 79,231, 98,143, 86, 53, 76,127, 33,106,248, +174,208,183,178,221,124, 7,143,133,143, 51,133,174, 18, 10,202,243,191, 96,235,107,115,235, 52,202, 6,214,246, 26, 85,202,233, +113,143,140,223,149,146,254,153,219,128, 33,195,224,238, 42,134,187,139, 51, 74,206,157,194, 27,169, 47,213, 41, 57,216,178,197, +147,103,115,185,166,200,127,249,242,229,173,194,252, 63,252,240,131, 34, 33, 33, 1,102,146, 4, 49, 68,175, 6,112,170, 95,191, +126, 37, 42,149,170,135, 80, 40,148,184,186,234,151, 98,109,222,188, 25, 51,103,206,132, 82,169,132, 74,165, 66, 99, 99, 35,220, +220,220, 84, 58,157, 46,135, 16,114,147,205,201, 58,106, 53,192,131, 50, 4, 96, 24, 5, 96,222,183, 7,241, 51,232,211,199, 15, +175,166, 37, 99,247,174, 95,145,189,229, 4,156,197,157,241,123,217,189, 17,172,158,254, 3,208,168,174, 65,196,176,254,248,240, +163,100,188,159,254, 57, 39,123,190,190, 30, 40, 58, 87,212,252,121,216,128, 48, 84, 84, 84,115,178, 55,101,225,116,204, 20, 60, +137,198,194, 58,140, 94, 48, 16,244, 96, 9,190,248,226,251,230,243,171,174,174,198,216,135, 67, 89,217, 51, 70, 84,102, 20,245, + 51,126,110, 83, 62,181, 89, 0,180, 5,249,179,177, 25, 21, 21, 69,101,101,101,145, 38,111, 23, 89, 89, 89,196,112, 89,162,177, +215,111, 74, 32,180,142,195, 82,128, 88, 0,184, 8, 1, 55, 17,208, 88,139,172,247,157, 0,151,163, 36,249,177, 62,128,139, 55, + 50,191,225,238,245, 91,154,237,207,144, 53,219, 53,236,198,228,111, 60, 39,128,171, 61,182,228,207,198,222,123, 25,107,169, 87, + 22,206, 35, 18, 9, 64,211,192,160,126,194,123,237,113, 86, 7,141,142, 64, 71, 11, 49, 99,198, 12, 86,226,228,237,119,215, 82, +139, 22,205, 35, 90, 45,160,214, 16,232,180,128,128, 2, 34,167, 0,181, 85, 20,126, 59,173,132, 82, 37, 64, 98,194, 12,214, 97, +255,229,207, 1,193, 61,245,255, 7,245, 0,108,141, 4,200,229,242, 35, 50,153, 44,246,230,212,184, 93, 1, 91,119,186, 5,140, +123, 24,154, 67, 7,241, 99, 66, 92,157,186,182, 54, 86, 46,151, 31,228,104,239,160, 76, 38,139, 61,255,230,180, 93,254,255,202, +113,235, 49, 98, 28,234,207, 31,194,198,127, 76,173,107,108,224,102,143,177,181, 58,237,239,187,222,249,248, 75,183,209, 99,198, +162,184,232, 20, 94, 74,126,178,174,161,174,142,243,185,181, 53,204, 37,251,145,201,100, 36, 62, 62,158,205,106, 0,161,167,167, +231, 41,165, 82,249,109,105,105,105,239, 33, 67,134, 4,106,181, 90,145,147,147, 19,114,114,114, 16, 29, 29, 13,149, 74,133,134, +134, 6, 92,186,116,169,198,203,203,107,175, 82,169,252,154,166,233,122,176,204, 0,200, 36, 5, 98, 66,236, 92, 66,255, 15,218, + 16,128, 97, 20,192, 17,237,107, 75,238, 0, 83,120, 52,118, 20, 30,141, 29,213,244,159,253, 26,182,165,189,105,246,137, 59,207, + 31,208,120,186, 14, 79,127, 54, 5,239,236, 93,102,247,185, 41,159, 81, 18, 47,173, 23, 84,223,168,238,139, 99,109,147, 0,104, + 15,207,223,216,251, 48, 12, 99,155, 11,245, 59,242, 28,185,140,253, 59,154,252, 13,196,142, 97, 34, 32, 70, 4, 41,154, 34, 29, +156,236, 89,155, 11,192,213,222, 7, 31,175,165,100, 50, 25, 17, 8,128,131, 5,250,177,126,102,194,159,126,220,127, 6, 39,123, +171, 86,173,165,230,205,111,202, 73, 33,208,219, 56,186, 31,168,175,163, 65,104, 32, 49,113, 10, 98, 98, 98,172,182, 71,246,122, + 25, 73,125, 18,240,116, 3,202,110, 3, 46,206, 0, 77,128, 78, 18, 32, 93, 6,164,201,109, 18, 1, 7,101, 50, 89,108, 65, 98, +220, 46,143,229,111,187,229, 47,127,163,174,209, 6,242, 55,182,151,191,100,234, 46,151,127,188,233,150,251,239,183, 56,147,191, +161,173, 23, 95,124, 49,238,141,127,190,176,115, 65, 74,170,219,103, 31,102, 48,228,127,218,196,179,175,229, 98,219,218,208, 17, +215,231,205, 20,249,207,155, 55,143, 48, 43, 1,182,109,219, 70, 40,138,178, 36, 4,220,212,106,117,157, 64, 32,200,243,247,247, +239, 89, 91, 91,251,226,241,227,199,187, 15, 29, 58,148,214,106,181, 13,213,213,213,183, 78,159, 62,125,165, 79,159, 62, 37, 93, +186,116, 41, 85, 42,149,155,181, 90,237, 45, 66, 8,107, 1,192, 36, 5, 50,136, 10,216,210,190,210, 54,236, 11, 29,110,219, 81, +227,254,246,218, 81, 41,133, 14, 61,222,209,246,170, 42, 5,200,208,202, 16,120,216, 15,179, 63,181, 46, 76,170, 42, 5,120, 40, +192,242, 49,247,147,252,205, 10, 0,107,107,253,185, 62,232,108,115, 7,112,177, 43,151,203, 41,115,155,237,112, 33,175,204,100, +185, 62,204,127, 17,192, 69,227, 79,171,155,254, 46,195,134,235, 85, 56,138, 92, 13,235, 69, 38,147, 17, 38,207, 64, 74, 74,138, + 77, 43, 28,140,237,109, 92,212,169, 89, 20,216, 35,154,140,219,132,153,240,103,107, 84, 98,237,231, 45,237,213,213,232, 59,224, +196,196, 68,110,247,223,183, 14,125,102, 52,134,164,189,111,249,155, 27, 26,107,107,159,182,215,187,102,236,253,244,217, 91, 27, + 84, 13,181,115,229,114,249, 33, 91,109,125,250,233,167, 7,100, 50, 89,236,103, 31,173,220, 80, 87, 87,103,238,220,180,184,255, +104,209,163, 26,147,127, 94, 94, 94, 36, 33, 4,219,183,111, 55, 60,198,146,189,107,106,181,218,153, 16, 82, 75,211,180, 92,173, + 86,255, 26, 16, 16,224, 83, 85, 85, 69,189,254,250,235, 53,213,213,213,119,122,244,232, 81, 91, 87, 87, 87,175, 86,171,107, 52, + 26, 77,163, 78,167, 83,114, 57, 97, 7, 13, 3,228,183, 97,157,230,227, 79,138,126,253, 6, 83,111,190,150, 73,102, 61, 30,141, +176,129,125,204, 30, 87, 84,120, 25,155,190,219,131,126,253, 6, 83,247,211,222,144, 33, 67,168,212, 69,114, 50,235,241,104,203, + 14,243,241, 82,108,250,110, 15,134, 12, 25, 98,245, 94,186,159,228,111, 82, 0, 56,218,179,111,203, 72, 65, 84, 84, 84, 62,171, + 16,191, 21, 56,114, 86,255,253,136,140,112,217,244,199, 17,209, 0,174,109, 98,184,172,203,222, 33, 9, 99,123, 92,201,223,158, + 25,255,108, 72, 27, 64, 80, 71,180,231,232,115,115,208,189, 77, 1, 0, 69, 81, 68, 32, 16,128,249, 99, 66,216, 83,166, 76, 65, +108,108, 44,104,154, 6, 77,211, 32,132, 88,251, 61, 74,171,213,186, 18, 66,116, 52, 77, 55,106, 52,154,253, 66,161,144, 18, 8, + 4,206, 0,156,105,154,134, 78,167, 19,106,181, 90,177, 86,171,237,174,211,233,206, 27,124,183,205, 55, 1,226,225, 24, 17,112, +165, 84, 69,118,239,220,130,107, 21, 53,240,243,106,104,254,236,102,165, 43, 2,124, 59,163,127,255,254, 86,201,186,173,236, 13, + 25, 50,132,186, 89,214, 72,214,124,180, 3,197,191,223,110,101, 47,184,167, 15, 2, 3, 3, 89,145,127, 91,193, 82,142, 20, 42, + 60, 60,156,223, 30,147, 7, 15, 30, 15, 42, 26, 12, 8,157, 54,112,108, 68, 6,229,229, 0, 60,160,159, 52,206, 19, 63, 15, 30, +230, 34, 0, 60,120,240,224,241, 0, 65,210, 36, 2,104, 3,226, 23,224,222, 16,135, 8, 64,247,166,247, 52, 95, 93, 60,120,240, + 2,128, 7, 15, 30,127, 14, 8, 0,184, 25,252,207, 16,191,216,128,244,233,166,227,120,239,159, 7, 15, 94, 0,240,224,193,227, + 47,210,167,241,164,207,131,135, 5,245,204,131, 7, 15, 30, 60,120,240,248, 43,171,229,249,243,231, 27,110,164, 67, 12,103,216, +203,100, 50, 98,180,209,206,181,168,168,168,230, 85,141,166, 82,177, 26,218,227,138, 63,163, 61,227,101,139,134,245,201,215, 31, +223, 30, 29,221, 94,122,122,122,243, 49,105,105,105,148, 13,246, 0, 51,233,128,249,251,217,186, 77,254,249,229,237,113,177,199, + 89, 0,112, 68, 87, 54, 7, 49,187,247, 57, 74,177, 24, 39, 35, 49,181, 27,160,169, 99,218, 67, 93, 49, 4,147,148,148, 36,101, +136,134,201, 0,102, 41, 39,248,253,196,246,237,219, 35,183,109,219,214, 76,130, 83,166, 76,145, 38, 38, 38,230,255, 25,213,174, +169,246, 56,127, 94,191, 50, 44, 52, 52,180, 93,207, 77, 38,147,145,169,211,100,200,201,150,155,188,103,119,238, 58, 65,114,178, +229, 22,239,229,157,187, 78, 88,236, 4,226, 98, 35,108,190,233,210,211,211, 73, 66, 66, 80,139,255,173,137, 0,107,168,173,171, +141,220,250,211, 86, 4,134, 5, 42, 64, 1,231, 79,158,147,142, 9, 31,139,208,126,161,156,238,191, 67,135, 14,181,186,238,177, + 99,199, 82,224,193,131, 71,155, 9, 0, 49,219, 3, 71,143, 30,205,217,184,169,205, 98, 24,152, 34, 81,227,141, 54,216, 18,173, + 45, 27,227,176, 17, 20,140,221,212,212, 84,100,100,100, 40,204,237, 45,206, 28,103,105,173,166,241, 57,246,232,211, 11, 0,112, + 75,165,130, 86,217,168, 47,172,170, 1,160,223,251,128, 75,110, 4, 67,242, 7,244,185,197,185,172,181,151,201,100, 68, 64,233, +179,235, 49,175,128,136, 87,212,158, 0, 0, 14,255, 73, 68, 65, 84,229,247,159,175,189,255,130,204,184, 61, 24,226,183,181, 61, + 28, 41, 42, 25,242,143,139,141, 80, 1, 50, 73, 78,182,220,230,223, 96, 4,132,105, 1, 32,183,235, 60,213,234, 84,228,230, 38, + 35, 38, 38, 19, 9, 9, 25,205, 17, 1, 91,132,192,193,162,131,228,161,161,189,240,161,124, 21,188, 92,189, 64,107,117, 80,145, + 70,197,238, 95,127,138,217,187,239,103, 50, 54,112,156, 84, 34,145, 88, 21, 2,135, 14, 29, 34, 77,145,133, 86, 30, 17, 47, 2, +120,252,149,113,234,212,169, 22,255,155,234,211,236, 17, 0,156,230, 15,152,218,197,206, 17, 32, 64,164,221, 54, 8,123, 13,192, +198,115,151,201,100, 36, 53, 53, 21, 43, 86,172, 0,128,230, 87, 83,199, 89,219, 33,172, 21, 60, 59,227, 76,233,119,112, 65, 79, +232,240, 11, 42,254,115, 2,167, 75,238, 96,198,138,117,237,118,163,157, 57, 91,136,193,131, 6,130, 38, 64, 97,161,254, 61,112, +239,189, 97, 57,205,178,170, 13,115,176, 91, 66,102,102, 38,197,182, 61,230,206,157, 11, 0,205,175, 38,201,159,162, 0, 11,247, +131, 76, 38, 35,143, 60,178, 11, 50, 89,172, 67, 69, 64, 92,108, 68, 67,114,114,178, 43,144,137,156,108,110,196,110,232,225,219, + 75,242,230,188,127, 0,152, 57,115, 51,114,115,245,175,201,201, 37, 96, 34, 2, 92,162, 1,132,144, 72,197,133,189,138, 23,255, + 49, 31,195,187, 14,133,139,135, 7,136, 90, 11,154,232, 32, 20,137, 17, 28, 21,156,251,219,176, 11, 88,145,153,161, 24,229, 51, + 90,234,234,234,106, 85, 4,220,190,125,187,197,255, 83,198,119,194,168,133,191,224,241, 12, 85,139,134,156, 52,105,146,205,237, +149,157,157, 77,166, 77,155,230,176,246,118,180,189, 54, 38,146, 72,123,211,250,158, 58,117, 42,178,137,132,108,181, 51,248,149, + 87, 94, 41,175,175,175, 15, 0, 48, 25,250, 77, 56, 67, 1,156,130,126, 83, 40, 0,216, 40,151,203,127,227,169,191, 53,249, 51, +101,198, 34,160,133, 0, 40, 45, 45, 37,165,165,165, 0,128,192,192, 64, 24,110, 54, 3,160,197,255,166, 62, 55,135,138,138, 10, + 69, 86, 86, 22,235, 72,128,241, 94,247,150, 72,152,106, 74,133,105, 76,162, 92, 67,236,153,153,153, 86,143,201,203,203, 99, 69, +254, 73, 73, 73,102, 73,127,233,210,165,200,200,200,128,161, 64, 96,131, 30,125,122,225, 70,101, 53,126,156, 55, 19, 93,168,113, + 40,249, 98, 17, 2,167, 7, 98, 79, 59,147, 63,128,102,194, 7,128,129, 3, 7,182, 40,103, 34, 3,134,229,142,246,236, 45, 17, + 49,211, 30,230, 72,127,253,250,245,200,200,200, 64,236,184,161,216,245,203, 73,192,189, 19, 80, 83,119,223,235,112,231,174, 19, +174, 64, 38,118,238, 58,225, 16,123,211,106,150, 89,124, 54,179, 59,191,199,234, 1, 49, 12,253, 39, 39,231, 34, 33, 33,168,249, +149, 65, 66, 66, 16,107, 17,240,197,255,190,192,251,159,190,139,241,125, 35,161,107,108,132, 86,167, 5, 37,162, 0, 8, 65, 64, +227,214, 31,101, 8,237,218, 31,203,230, 45,195,187, 43,223, 85, 60, 50,208,122, 52,203,184,179,155,226,191,222, 36,225,239,221, +187,151,216, 34, 2,178,179,179,201,206,215,119, 33,238, 29, 56,132,180,179,179,179,201,202,149, 43,177,100,201,146, 14, 45, 2, + 78,157, 58, 21, 89, 93, 93,173, 40, 43, 43, 67,120,120,184, 93,231, 89, 93, 93,173,184,215,101,219,244,156,151, 2,152, 11,224, + 36,128,175, 1, 68, 3,120, 20,192,223, 13, 4,192,237, 63, 41,159, 83,176,176, 13,184, 69, 71, 42, 85,207, 49,153, 25, 75, 77, +126,222, 66, 0, 4, 6, 6, 82,129,129,129,205,100,111, 24, 74,206,202,202,106,241,191,241,231,151, 46, 93, 50,123,130,140,168, + 72, 73, 73, 81,164,166,166,194,120,163, 28,227,205,115,178,178,178,204,134, 96, 77,117,246,198,101,237,185, 81, 17, 0,108,218, +180,201, 44,241, 3,104, 65,254, 75,151, 46,101,101,243,247,210,107,168,223,242, 6,220,158,253, 24, 61,250,244, 66,183, 46, 46, + 40,221, 82,170, 39,127,207,206,250, 33, 0, 39, 33,231,115, 77, 72, 72,144, 26, 14, 3, 36, 36, 36,112,142,210,208, 4, 8,232, + 4,252,251, 73,224,249,245, 64, 87, 87,224,124,149,233,242,162, 74,142,119,190, 25, 33,199, 37,106,243,246,219,111,155, 37,126, + 0, 88, 57, 55, 30,107,118, 31,129, 95, 96,119,220,188,122,203,170,247, 15, 0,108,162, 0, 92,194,248,122, 15, 95,102,210,211, +103,198,246,185,222,215, 43,255,107,190,142, 66,230,193,134,123, 37,168,197,171, 58, 33, 24,226,109,197,172,191,223,160,108,192, +184,217, 99, 21,163,187,143, 66, 99,125, 61, 68,206,206, 16,137,238,117, 65,165,197,197,216,154,147,115,227,217,103,230,246,232, +237, 28,128,161, 19,195,163,126,205,253, 53,114,212,240, 81,156,188,198,244,157,115,177,111,223, 62, 60,246, 88,203,242, 73,147, + 38, 81, 92, 69, 0, 67,254,232,253, 33,118,190,254,178,221, 34, 32, 59, 59,155,124,244,209, 71, 8, 9, 9,193,154, 53,107,176, + 96,193,130, 14, 39, 2, 12,137,223, 81,246, 24, 91,118, 68, 19,164, 0, 38, 2, 88, 79, 8,169,163, 40,202, 15,192, 5, 0, 87, +229,114,185, 22,127,110, 16,142,245,221,130,252,153,247,153, 25, 75, 91, 69, 1,238, 75, 30,128,172,172, 44,102,236, 21,165,165, +165,240,245,245,109, 37, 16,152,178,138,138, 10, 86,121,238,173, 77, 6,228,210, 97,206,154, 53,171,237,164,155, 1,129,153,242, +250, 51, 50, 50, 32,151,203, 41,107,179, 56,149,184,134,186,233,163, 64,220, 23, 1, 81,175,163, 14,255, 3,254,163,247, 22, 73, +214, 34, 56,253,109, 13,180, 90,238,137,206,226,227,227,243, 89,108,187,106, 57,194,243, 21,240,214, 90,160, 87, 79,224,214,118, + 49, 54,124,169,198,220,239,204,151,115,186,243,137, 99, 51, 85, 27, 78,246, 43,207, 94, 1,247, 48, 9,220,250,254, 19,155, 86, + 60,143, 33, 3,253,208, 47,254, 93, 86,237,193,230,254,100, 59, 84,192,220,187,134,228, 47,151,203, 41,102,226,159, 77, 68,211, +249, 61,202, 22,146, 55, 5,117, 66,176,201,242, 92,163, 72,128, 53,148, 87,148, 99,114,210,100,184,119,246,130,142,210,226,192, +190,253,168,173,171, 67, 66, 98, 34,254,168,168,192, 15,155,127,196,115,207,204,237,225, 44,113,134,128, 56, 33, 38, 34, 38,239, +130, 98,141, 77, 94, 99,101,101,165,221,215,109, 72,254, 0,236, 22, 1,217,217,217,100,249,242,229, 8, 14,214,215,103, 80, 80, + 16, 58, 82, 36,192,209,196,111,194,251,103,222,219,114,173, 3,154,136,208,137,162, 40, 87, 0, 97, 0,206, 1,232, 33,147,201, +106, 0, 84,201,229,114, 62,173, 61, 71,220,183, 68, 64,190,190,190,210,164,164,164, 86, 67, 1, 71,142, 28, 81, 52,109,246,194, +121,142,128,185,201,128,150, 60, 71,115, 2,165, 45,192,120,247,230,194,253,108,189,127, 0,216,253,234,114, 36,188,255, 1,180, + 81,227, 32, 2,224,118,184, 24,123, 74,238, 0, 0,180, 81, 11,160, 57,235, 3,170,235,223, 57,147, 20,219, 40,139, 37,220,153, +246, 63, 44,120,230, 58, 46,206, 91,130,250,159,213,240,243,177, 92,238,136, 8,128, 45,226, 96,253,250,245,122, 53,156, 48, 1, + 71,202, 42,224, 62,196, 29, 55,114, 75, 0,137, 51,102, 46,248, 27,188,123,198,183,219,131,104,110,214,191,163,162, 90,150, 86, + 8, 88, 91, 29,144,155,156,139,152,204, 24,204,220, 12, 36,231,234,223,231, 38,231,114,142, 2,212,169,106,225,227,210, 5, 90, + 85, 3,136,128, 96,196,200,145,216,178,101,139,234,163, 15, 62,144,208,132, 96,206,147,115,224,221,197, 27, 13,117,117,208,234, +180,112,119,234, 12,141, 64, 99,211,245, 86, 85, 85,181, 88, 29,192,117, 66, 96, 43,242,103, 96,163, 8,200,206,206, 38,169,169, +169, 24, 57,114,100,139,242,129, 3, 7, 34, 61, 61, 29,105,105,105,237, 38, 2,218,138,248,141,189,127, 0, 40, 43, 43,179, 53, + 10,240, 43,244,227,253, 53,208,135,254, 39, 3,184, 4, 96, 48,128, 28, 0,235,208,180, 83,167,165,238, 4, 54,134,210,255, 18, + 2,192,152, 16,152, 61,231,217,124,110,105,214, 52, 3,102,120,129,153, 16,200,204, 13, 96,162, 3,129,129,129, 10,102,184,160, +189, 58, 94, 71,194,218, 88, 63,227,253,179,177, 53, 99,237,102,144,196, 62,184, 53, 38, 2, 93, 48, 14, 46, 51,215, 64, 91,254, + 7,224,217, 25,162, 59,255,195,246,143, 10, 0,161,144,243,181,219,178, 10,194, 24,167, 95,249, 63, 12, 15, 7, 2, 23, 20, 34, +204,237, 25, 92,120, 40, 9,248,247, 18,179,229,237, 21, 1,200,200,200,192,248, 17,253, 16, 53, 46, 4, 9,131,150, 96,245, 71, +159,227, 92,193, 13,204,155, 52, 28, 55,115,118,162,186,178,198, 33,247,131,169,161, 2,107,207,135, 37,111,223, 81,247,168, 57, +251,150, 38, 14,166,165,165, 81,233,233,233,100,230,230,150,130, 0, 0, 98, 50, 99, 32,222, 86,140,109,219, 74,154, 87, 2, 48, + 19, 6,189,189,189, 77,246,191, 52, 77, 67, 71, 3,132,214,194,217, 69,130, 39,159,122, 74,242,214,155,111,162, 91,183,110,116, + 15, 63, 63,129,170,190, 14, 58, 2, 16, 90, 7,154,182, 30,209, 26, 59,118, 44,245,195, 15, 63,144, 59,119,238,160,166,166,166, +133,112, 52, 92, 29,192,101, 85, 64,118,118, 54, 89,253,124, 17, 32, 9, 6,110,126,218,250, 0, 73, 48, 86, 63, 95,132,148,255, +176, 19, 1,217,217,217,100,234,212,169,210,129, 3, 7, 42,238,220,185,211,234,243,128,128, 0, 76,157, 58, 85,250, 32, 77, 12, +180,197,251,183, 39, 10, 32,151,203,243, 13,158,175,238, 0, 78, 3,152, 46,151,203,185,108,101,202,147,191, 37, 1, 96,148,232, +199, 90, 34,160, 22,159, 91, 10,153, 38, 37, 37,153,140, 2, 48,100,239,235,235, 43, 77, 77, 77, 85, 48, 99,178, 73, 73, 73, 22, +151, 1, 90,242, 14,185, 78,254,107,171,101,128,140,119,111,105, 50, 32, 23,148,252, 43, 25, 78, 51,215, 64, 89,118, 17,162,195, +107,160,217,188, 0, 84,220, 42,108,253,251, 99,184,186,245, 50, 18, 86,126, 13,136,218, 39,179,243,146, 44, 32,119,229, 22,132, + 93,141, 1,110,215, 99,113,244, 18,139,229,142,136, 0,216,234,253,231,108, 89, 14, 97,143, 1,112, 67, 8,174,237,203, 68, 45, + 69,112,244,226,117, 68, 21,222, 96,217,238,215,154,255,159, 53, 75,222,130,236, 1,224,231,159, 99, 77, 30,103,233,249,176, 22, +234,119,196,178, 67, 71,172, 16, 72,206,189, 71,252, 0, 90,121,254,204,132,193,109,219, 74, 76,126,223,221,197, 29,101,213,101, + 24,217,123, 20,148,141, 42, 64,169,130, 86,173,193,178,212, 84, 80, 2, 8, 26,234,235, 64,211, 58,104,117, 4,206, 34, 39,252, + 81,247, 7,156,116,214, 87, 27, 63,246,216, 99,205,117,115,232,208, 33,194,244, 55,134,171, 3,202,203,203, 89, 95,231,180,105, +211,168,148,255,128,172,126,190, 8,161,125, 90,255,254,249,203,106,164,252, 39, 12,108,201,122,218,180,105, 84,118,118, 54, 25, + 57,114, 36, 2, 2, 2, 90,125, 94, 88, 88,136,156,156, 28, 69,123,145,127,147, 55, 78,181,229,216,191, 33,236,136, 2, 48,152, + 12,253,228,239, 70,158,194, 29, 40, 0,218, 10,140,231, 15, 0,163, 71,143,150,102,101,101, 41,152,208,191, 25,113, 32,189,116, +233,146,130, 43, 9,219,218, 73, 58,122, 25,160,161,247,111,138,248, 25,161,195,229,124, 79,151,220,129,230,236, 91,184,133, 95, +224, 23,183, 10,168,174, 65, 73,230, 34, 4,205,255, 16, 55,215, 45, 2,156, 68,128,160,125, 50, 59, 95,171, 7, 66,125,167,179, + 46,111,143, 8, 64, 70, 70, 70,221,236,168, 81,229, 30,180, 87,175, 6, 56, 73, 54,127,184, 0,159,109, 63,133,197,143, 62,140, +185, 31,252, 23,143,189,247, 77,187, 76, 30,101, 4,104, 83, 30, 0,202, 94,113,106, 79,168,223, 82, 20, 32,185,201,179, 55, 38, +127, 67,239,223, 26,252,125,253,177,251, 64, 46,198,246, 26, 11,215, 78,110,160,105, 2, 1,209,130,166, 40, 16, 66,160, 35,128, +150, 38,208,106,181, 80, 86,215, 99,199,177, 29, 16,235,196,156, 39,165, 26,175, 10, 72, 91, 48, 14, 83,252, 75,145,121,140,189, + 13,115, 34,128, 43,249, 27,218, 75, 75, 75, 35, 43, 87,174, 68,247,238,221,239, 9,251,146, 18,100,100,100,160, 35,120,254,142, + 22, 2,166,188,127,123,162, 0, 77,207, 68, 36,128,135, 0,188,246, 23,152,252, 7, 0, 66, 0,186, 7, 90, 0, 24,207,250, 79, + 74, 74,106, 30,119, 55, 20, 7,134,239,237,241,224,109,233,200, 29,181, 12,208,156,247,111, 43,241, 51,152,177, 98, 29,126, 4, +240,232,251, 83, 64,178, 22,129,154,181, 26,167, 75,238,128,242,246, 66,241,239, 53,122,239, 95, 40,108,151, 59,212,220,122,127, +123,242, 0,176, 17, 92,108,197,193,250,245,235,213, 0,106,159,143, 28, 92,243,207, 85, 31,171, 95, 93,150,170,234,218,217,247, + 78,209,185,107,221,230,158,251,175, 91,123,175, 26, 49, 71,206,134, 67, 52,220, 87, 20,152,250, 13,251, 34, 0,166,200,159,241, +252, 1, 88,157, 16, 40,145, 72,168,115, 91,207, 39, 42,198,229,231, 36, 13,122, 12, 53,170, 26, 80, 2, 64,159, 82,132,134, 78, + 71, 64,107,181,232,228,236,142, 67,213, 39,113,233,112, 49,162, 35,162,243,237,174,220,146, 23, 0,112, 95, 6,216, 66, 4,116, +191,134,243,229, 1, 54,145,191,161,189, 37, 75,150,144, 53,107,214,192,211,211, 19,119,238,220,193,242,229,203,209,209,194,254, +142, 16, 2,230,188,127, 91,162, 0, 50,153,172, 27, 0,191,166, 27,101, 40,128, 20, 0, 37,127, 17, 39, 93,215,150,198,239, 75, + 30, 0,115, 17,129,213,171, 87, 75,141,133, 66, 82, 82,146,130,171, 61, 67, 34,232, 8, 41,118, 13,189,127,227,229,127,165,165, +165, 45,234,141, 75,214, 62, 70, 4, 76,127,255, 43,144,205,128,207, 92, 57,242,255,249, 24, 30,206,216, 8, 56, 57,161,147, 68, +220, 46,215,107,184,198,223,212,123, 27,243, 0,104, 1, 8,154,218, 86, 96,103,123,220,154, 29, 53,170,236,159,153,219,250, 44, +123,110,114,103,127,191, 72, 53,128, 51, 73, 73, 73, 30, 0,220,108,109,143,123, 36, 29, 75, 30,121,100,151, 65,248,159,219,247, + 45,121,240,134,233,129,217, 10,137,182, 72, 6,100, 14,198,164,207, 68, 4,204, 13,121, 60, 61,235,233,173,219,254,187, 13,186, +217,218, 51, 19,123, 77, 28,220,197,189, 11, 84, 26, 21, 8, 33, 16,139,196,168, 82, 54,224,200,239, 63, 99,253,183, 27, 32, 29, + 32,117, 72,226,176,244,157,115,177, 97,195, 6, 44, 90,196, 61, 7,192, 61, 17, 0,187,200,223,208,222,130, 5, 11,152, 60, 0, +232,200, 99,254,134, 66,192,150,239,218,155, 59,192,240, 49,128,126,189,191, 10,192, 43, 0,142,201,229,114, 29,120,152,171,123, +156, 58,117, 10,153, 25, 75, 91,229, 1,176,152, 8,168,173,242, 0,152,138, 8,152, 35,122, 91,162, 0,246,162,173,150, 1, 50, + 98, 68, 46,151, 35, 47, 47,143, 46, 45, 45, 53, 36, 50,105, 84, 84, 20,103,239,102,198,138,117,128, 65,226,159,137,203,214, 54, +191,175,111,135,155,173,173,188,103,138,162, 62, 2,112, 23,250,229, 63, 79,218,105,238,230,243,145,131, 27,163,243,126,237, 60, +231,205,175, 33,151,203,197,121,121,121,221,209, 50,157,181, 77,237,209,214,145, 0,107,249,253,173,161, 45,134, 4,204,145,191, + 58, 33, 24,216,102,221, 49,147, 14,158, 68,237,251,225, 0, 57, 28,112, 4,227, 70,141, 67, 15,247, 30, 0, 77,240,135,234, 14, + 14,157, 56,132,155, 69, 55, 49, 41,116,146,212,217,217,185,221,219,195, 80, 4, 56,138,172,153, 72,192,131, 50,225,207,222, 44, +128, 14,232, 99, 50, 1,100,130, 7,103,152, 75, 0,100, 82, 0,180, 21, 82, 82, 82, 76,146,189,225, 78,108, 70, 80,176, 89, 85, +224, 40,175,191, 45,150, 1, 54,205,240,215,230,229,229,137,154,134, 14, 24,242,159, 20, 21, 21,197, 41,202,209,180,153,146,194, +209,231,104,110,140,217,209,185,238, 57,194, 25,128, 72, 46,151,191,110, 16, 2,123,202, 94,155,209,175,125, 81, 32,151,203, 39, +228,229,229, 33, 47, 47, 79, 5, 64,210,244,103, 55,241, 51, 81, 0, 91,235,204, 26,201, 79,157, 38,107,113, 28, 87,226,118,196, +144, 64, 90, 90, 26,149,158,156, 78,252, 23,248, 75,209,219,244, 49,101,201,185, 10,182,243, 1, 70,134,141,164, 26, 26, 26, 34, +215,189,191, 14, 1,193, 15, 41, 0,224, 66,225,111,210,248,232, 4,132,134,135,218,220, 30, 99,199,142,165, 54,111,222,220,106, + 85,128, 70,163,177,235, 6,114, 52, 89,255,217,102,251,119, 0,240, 75,252, 76, 68, 1,140,203, 88, 11, 0,107,158, 56, 91, 79, +221,214, 78,145,109, 34, 22,123,137,202,209, 68,199,216,203,203,203, 35,121,121,121, 34,195,250, 10, 12, 12,180,233,183,154, 8, +202,225, 29, 70, 71, 24,251, 54, 1,119, 0,117,250,132,252, 20, 5,192, 5,214,215,247,178,105,143, 43,121,121,121,204,186,178, +154,192,192,192,174,129,129,129,206, 29,161, 46,237,245,196,173,217,118,212,144,128, 85,114, 79,227,118,143,186,186,186,230,207, +154, 58,155,233,188, 49, 58,108,180, 67,206,115,230,204,153, 60,185,254,249,201,222,144,195, 52, 14, 38,127, 9,244,195, 13, 15, +188, 8,176, 90,145,225,225,225,188,106,226,193,131, 7, 15, 30, 60,254, 98, 16,240, 85,192,131, 7, 15, 30, 60,120,240, 2,128, + 7, 15, 30, 60,120,240,224,241, 23,192,255, 3,211,238,250, 72,118, 88, 93,170, 0, 0, 0, 0, 73, 69, 78, 68,174, 66, 96,130, + 0}; diff --git a/source/blender/src/header_view3d.c b/source/blender/src/header_view3d.c index 82fcdd23c1f..1ada2729289 100644 --- a/source/blender/src/header_view3d.c +++ b/source/blender/src/header_view3d.c @@ -5071,6 +5071,18 @@ static char *ndof_pup(void) } +static char *snapmode_pup(void) +{ + static char string[512]; + char *str = string; + + str += sprintf(str, "%s", "Snap Mode: %t"); + str += sprintf(str, "%s", "|Vertex%x0"); + str += sprintf(str, "%s", "|Edge%x1"); + str += sprintf(str, "%s", "|Face%x2"); + return string; +} + static char *propfalloff_pup(void) { static char string[512]; @@ -5698,6 +5710,10 @@ void view3d_buttons(void) if (G.scene->snap_flag & SCE_SNAP) { uiDefIconButBitS(block, TOG, SCE_SNAP, B_REDR, ICON_SNAP_GEO,xco,0,XIC,YIC, &G.scene->snap_flag, 0, 0, 0, 0, "Use Snap or Grid (Shift Tab)"); xco+= XIC; + uiDefIconButBitS(block, TOG, SCE_SNAP_ROTATE, B_REDR, ICON_SNAP_NORMAL,xco,0,XIC,YIC, &G.scene->snap_flag, 0, 0, 0, 0, "Align rotation with the snapping target"); + xco+= XIC; + uiDefIconTextButS(block, ICONTEXTROW,B_REDR, ICON_VERTEXSEL, snapmode_pup(), xco,0,XIC+10,YIC, &(G.scene->snap_mode), 0.0, 0.0, 0, 0, "Snapping mode"); + xco+= XIC; uiDefButS(block, MENU, B_NOP, "Mode%t|Closest%x0|Center%x1|Median%x2|Active%x3",xco,0,70,YIC, &G.scene->snap_target, 0, 0, 0, 0, "Snap Target Mode"); xco+= 70; } else { diff --git a/source/blender/src/transform.c b/source/blender/src/transform.c index 553b0993e5b..4270ce6a069 100644 --- a/source/blender/src/transform.c +++ b/source/blender/src/transform.c @@ -2412,18 +2412,19 @@ void initRotation(TransInfo *t) t->flag |= T_NO_CONSTRAINT; } -static void ElementRotation(TransInfo *t, TransData *td, float mat[3][3]) { +static void ElementRotation(TransInfo *t, TransData *td, float mat[3][3], short around) { float vec[3], totmat[3][3], smat[3][3]; float eul[3], fmat[3][3], quat[4]; float *center = t->center; /* local constraint shouldn't alter center */ - if (t->around == V3D_LOCAL) { + if (around == V3D_LOCAL) { if (t->flag & (T_OBJECT|T_POSE)) { center = td->center; } else { - if(G.vd->around==V3D_LOCAL && (G.scene->selectmode & SCE_SELECT_FACE)) { + /* !TODO! Make this if not rely on G */ + if(around==V3D_LOCAL && (G.scene->selectmode & SCE_SELECT_FACE)) { center = td->center; } } @@ -2627,7 +2628,7 @@ static void applyRotation(TransInfo *t, float angle, float axis[3]) VecRotToMat3(axis, angle * td->factor, mat); } - ElementRotation(t, td, mat); + ElementRotation(t, td, mat, t->around); } } @@ -2746,7 +2747,7 @@ static void applyTrackball(TransInfo *t, float axis1[3], float axis2[3], float a Mat3MulMat3(mat, smat, totmat); } - ElementRotation(t, td, mat); + ElementRotation(t, td, mat, t->around); } } @@ -2921,6 +2922,36 @@ static void applyTranslation(TransInfo *t, float vec[3]) { if (td->flag & TD_SKIP) continue; + /* handle snapping rotation before doing the translation */ + if (usingSnappingNormal(t)) + { + if (validSnappingNormal(t)) + { + float *original_normal = td->axismtx[2]; + float axis[3]; + float quat[4]; + float mat[3][3]; + float angle; + + Crossf(axis, original_normal, t->tsnap.snapNormal); + angle = saacos(Inpf(original_normal, t->tsnap.snapNormal)); + + AxisAngleToQuat(quat, axis, angle); + + QuatToMat3(quat, mat); + + ElementRotation(t, td, mat, V3D_LOCAL); + } + else + { + float mat[3][3]; + + Mat3One(mat); + + ElementRotation(t, td, mat, V3D_LOCAL); + } + } + if (t->con.applyVec) { float pvec[3]; t->con.applyVec(t, td, vec, tvec, pvec); @@ -4135,7 +4166,7 @@ int Align(TransInfo *t, short mval[2]) Mat3MulMat3(mat, t->spacemtx, invmat); - ElementRotation(t, td, mat); + ElementRotation(t, td, mat, t->around); } /* restoring original center */ diff --git a/source/blender/src/transform_generics.c b/source/blender/src/transform_generics.c index 8154929eb17..eaa4a1d0ecf 100644 --- a/source/blender/src/transform_generics.c +++ b/source/blender/src/transform_generics.c @@ -113,7 +113,6 @@ extern TransInfo Trans; /* From transform.c */ /* ************************** Functions *************************** */ - void getViewVector(float coord[3], float vec[3]) { TransInfo *t = BIF_GetTransInfo(); diff --git a/source/blender/src/transform_snap.c b/source/blender/src/transform_snap.c index 0e69e823d92..83940fa3729 100644 --- a/source/blender/src/transform_snap.c +++ b/source/blender/src/transform_snap.c @@ -55,11 +55,13 @@ #include "BIF_screen.h" #include "BIF_editsima.h" #include "BIF_drawimage.h" +#include "BIF_editmesh.h" #include "BKE_global.h" #include "BKE_utildefines.h" #include "BKE_DerivedMesh.h" #include "BKE_object.h" +#include "BKE_anim.h" /* for duplis */ #include "BSE_view.h" @@ -92,7 +94,8 @@ float ResizeBetween(TransInfo *t, float p1[3], float p2[3]); /* Modes */ #define NOT_SELECTED 0 #define NOT_ACTIVE 1 -int findNearestVertFromObjects(int *dist, float *loc, int mode); +int snapObjects(int *dist, float *loc, float *no, int mode); + /****************** IMPLEMENTATIONS *********************/ @@ -131,6 +134,15 @@ void drawSnapping(TransInfo *t) glTranslatef(t->tsnap.snapPoint[0], t->tsnap.snapPoint[1], t->tsnap.snapPoint[2]); + /* draw normal if needed */ + if (usingSnappingNormal(t) && validSnappingNormal(t)) + { + glBegin(GL_LINES); + glVertex3f(0, 0, 0); + glVertex3f(t->tsnap.snapNormal[0], t->tsnap.snapNormal[1], t->tsnap.snapNormal[2]); + glEnd(); + } + /* sets view screen aligned */ glRotatef( -360.0f*saacos(G.vd->viewquat[0])/(float)M_PI, G.vd->viewquat[1], G.vd->viewquat[2], G.vd->viewquat[3]); @@ -201,7 +213,8 @@ void applySnapping(TransInfo *t, float *vec) double current = PIL_check_seconds_timer(); // Time base quirky code to go around findnearest slowness - if (current - t->tsnap.last >= 0.25) + /* !TODO! add exception for object mode, no need to slow it down then */ + if (current - t->tsnap.last >= 0.1) { t->tsnap.calcSnap(t, vec); t->tsnap.targetSnap(t); @@ -222,6 +235,35 @@ void resetSnapping(TransInfo *t) t->tsnap.modeTarget = 0; t->tsnap.last = 0; t->tsnap.applySnap = NULL; + + t->tsnap.snapNormal[0] = 0; + t->tsnap.snapNormal[1] = 0; + t->tsnap.snapNormal[2] = 0; +} + +int usingSnappingNormal(TransInfo *t) +{ + if (G.scene->snap_flag & SCE_SNAP_ROTATE) + { + return 1; + } + else + { + return 0; + } +} + +int validSnappingNormal(TransInfo *t) +{ + if ((t->tsnap.status & (POINT_INIT|TARGET_INIT)) == (POINT_INIT|TARGET_INIT)) + { + if (Inpf(t->tsnap.snapNormal, t->tsnap.snapNormal) > 0) + { + return 1; + } + } + + return 0; } void initSnapping(TransInfo *t) @@ -445,14 +487,26 @@ void CalcSnapGeometry(TransInfo *t, float *vec) if (t->spacetype == SPACE_VIEW3D) { float vec[3]; + float no[3]; int found = 0; int dist = 40; // Use a user defined value here - found = findNearestVertFromObjects(&dist, vec, NOT_SELECTED); + found = snapObjects(&dist, vec, no, NOT_SELECTED); if (found == 1) { - VECCOPY(t->tsnap.snapPoint, vec); + float tangent[3]; + VecSubf(tangent, vec, t->tsnap.snapPoint); + tangent[2] = 0; + + if (Inpf(tangent, tangent) > 0) + { + VECCOPY(t->tsnap.snapTangent, tangent); + } + + VECCOPY(t->tsnap.snapPoint, vec); + VECCOPY(t->tsnap.snapNormal, no); + t->tsnap.status |= POINT_INIT; } else @@ -464,31 +518,18 @@ void CalcSnapGeometry(TransInfo *t, float *vec) /* Mesh edit mode */ else if (G.obedit != NULL && G.obedit->type==OB_MESH) { - /*if (G.scene->selectmode & B_SEL_VERT)*/ - if (t->spacetype == SPACE_VIEW3D) { - EditVert *nearest=NULL; float vec[3]; + float no[3]; int found = 0; int dist = 40; // Use a user defined value here - - // use findnearestverts in vert mode, others in other modes - nearest = findnearestvert(&dist, SELECT, 1); - - found = findNearestVertFromObjects(&dist, vec, NOT_ACTIVE); + + found = snapObjects(&dist, vec, no, NOT_ACTIVE); if (found == 1) { VECCOPY(t->tsnap.snapPoint, vec); - - t->tsnap.status |= POINT_INIT; - } - /* If there's no outside vertex nearer, but there's one in this mesh - */ - else if (nearest != NULL) - { - VECCOPY(t->tsnap.snapPoint, nearest->co); - Mat4MulVecfl(G.obedit->obmat, t->tsnap.snapPoint); + VECCOPY(t->tsnap.snapNormal, no); t->tsnap.status |= POINT_INIT; } @@ -522,33 +563,6 @@ void CalcSnapGeometry(TransInfo *t, float *vec) t->tsnap.status &= ~POINT_INIT; } } - - - /* - if (G.scene->selectmode & B_SEL_EDGE) - { - EditEdge *nearest=NULL; - int dist = 50; // Use a user defined value here - - // use findnearestverts in vert mode, others in other modes - nearest = findnearestedge(&dist); - - if (nearest != NULL) - { - VecAddf(t->tsnap.snapPoint, nearest->v1->co, nearest->v2->co); - - VecMulf(t->tsnap.snapPoint, 0.5f); - - Mat4MulVecfl(G.obedit->obmat, t->tsnap.snapPoint); - - t->tsnap.status |= POINT_INIT; - } - else - { - t->tsnap.status &= ~POINT_INIT; - } - } - */ } } @@ -723,101 +737,351 @@ void TargetSnapClosest(TransInfo *t) } /*================================================================*/ -int findNearestVertFromObjects(int *dist, float *loc, int mode) { + +/* find snapping point on face, return 1 on success */ +int snapFace(MFace *face, MVert *verts, float *intersect, float *loc, float *no) +{ + MVert *v[4]; + int totvert; + int result = 0; + + v[0] = verts + face->v1; + v[1] = verts + face->v2; + v[2] = verts + face->v3; + + if (face->v4) + { + v[3] = verts + face->v4; + totvert = 4; + } + else + { + v[3] = NULL; + totvert = 3; + } + + switch(G.scene->snap_mode) + { + case SCE_SNAP_MODE_VERTEX: + { + float min_dist = FLT_MAX; + int i; + + for(i = 0; i < totvert; i++) + { + float vert_dist = VecLenf(v[i]->co, intersect); + + if (vert_dist < min_dist) + { + result = 1; + + min_dist = vert_dist; + + VECCOPY(loc, v[i]->co); + NormalShortToFloat(no, v[i]->no); + } + } + break; + } + case SCE_SNAP_MODE_EDGE: + { + float min_dist = FLT_MAX; + int i; + + for(i = 0; i < totvert; i++) + { + MVert *v1, *v2; + float edge_loc[3]; + float vec[3]; + float mul; + float edge_dist; + + v1 = v[i]; + v2 = v[(i + 1) % totvert]; + + VecSubf(edge_loc, v2->co, v1->co); + VecSubf(vec, intersect, v1->co); + + mul = Inpf(vec, edge_loc) / Inpf(edge_loc, edge_loc); + + VecMulf(edge_loc, mul); + VecAddf(edge_loc, edge_loc, v1->co); + + edge_dist = VecLenf(edge_loc, intersect); + + if (edge_dist < min_dist) + { + float n1[3], n2[3]; + result = 1; + + min_dist = edge_dist; + + VECCOPY(loc, edge_loc); + + NormalShortToFloat(n1, v1->no); + NormalShortToFloat(n2, v2->no); + VecLerpf(no, n1, n2, mul); + Normalize(no); + } + } + break; + } + case SCE_SNAP_MODE_FACE: + { + result = 1; + + VECCOPY(loc, intersect); + + if (totvert == 4) + CalcNormFloat4(v[0]->co, v[1]->co, v[2]->co, v[3]->co, no); + else + CalcNormFloat(v[0]->co, v[1]->co, v[2]->co, no); + break; + } + } + + return result; +} + +int snapDerivedMesh(Object *ob, DerivedMesh *dm, float obmat[][4], float ray_start[3], float ray_normal[3], short mval[2], float *loc, float *no, int *dist, float *depth, short EditMesh) +{ + float object_depth = FLT_MAX; + int retval = 0; + int totvert = dm->getNumVerts(dm); + int totface = dm->getNumFaces(dm); + + if (totvert > 0) { + float imat[4][4]; + float timat[3][3]; /* transpose inverse matrix for normals */ + float ray_start_local[3], ray_normal_local[3]; + int test = 1; + + Mat4Invert(imat, obmat); + + Mat3CpyMat4(timat, imat); + Mat3Transp(timat); + + VECCOPY(ray_start_local, ray_start); + VECCOPY(ray_normal_local, ray_normal); + + Mat4MulVecfl(imat, ray_start_local); + Mat4Mul3Vecfl(imat, ray_normal_local); + + + /* If number of vert is more than an arbitrary limit, + * test against boundbox first + * */ + if (totface > 16) { + struct BoundBox *bb = object_get_boundbox(ob); + test = ray_hit_boundbox(bb, ray_start_local, ray_normal_local); + } + + if (test == 1) { + MVert *verts = dm->getVertArray(dm); + MFace *faces = dm->getFaceArray(dm); + int *index_array; + int index = 0; + int i; + + test = 1; + + if (EditMesh) + { + index_array = dm->getFaceDataArray(dm, CD_ORIGINDEX); + EM_init_index_arrays(0, 0, 1); + } + + for( i = 0; i < totface; i++) { + MFace *f = faces + i; + float lambda; + int result; + + if (EditMesh) + { + EditFace *efa = NULL; + + if (index_array) + { + index = index_array[i]; + } + else + { + index = i; + } + + if (index == ORIGINDEX_NONE) + { + test = 0; + } + else + { + efa = EM_get_face_for_index(index); + + if (efa) + { + if (efa->v1->f1 & SELECT || efa->v2->f1 & SELECT || efa->v3->f1 & SELECT || (efa->v4 && efa->v4->f1 & SELECT)) + { + test = 0; + } + } + } + } + + + if (test) + { + result = RayIntersectsTriangle(ray_start_local, ray_normal_local, verts[f->v1].co, verts[f->v2].co, verts[f->v3].co, &lambda, NULL); + + if (result && lambda < object_depth) { + float location[3], normal[3]; + float intersect[3]; + + VECCOPY(intersect, ray_normal_local); + VecMulf(intersect, lambda); + VecAddf(intersect, intersect, ray_start_local); + + if (snapFace(f, verts, intersect, location, normal)) + { + float new_depth; + int screen_loc[2]; + + Mat4MulVecfl(obmat, location); + + new_depth = VecLenf(location, ray_start); + + if (new_depth < *depth) + { + object_depth = lambda; + *depth = new_depth; + retval = 1; + + VECCOPY(loc, location); + VECCOPY(no, normal); + + Mat3MulVecfl(timat, no); + Normalize(no); + + project_int(loc, screen_loc); + + *dist = abs(screen_loc[0] - mval[0]) + abs(screen_loc[1] - mval[1]); + } + } + } + + if (f->v4 && result == 0) + { + result = RayIntersectsTriangle(ray_start_local, ray_normal_local, verts[f->v3].co, verts[f->v4].co, verts[f->v1].co, &lambda, NULL); + + if (result && lambda < object_depth) { + float location[3], normal[3]; + float intersect[3]; + + VECCOPY(intersect, ray_normal_local); + VecMulf(intersect, lambda); + VecAddf(intersect, intersect, ray_start_local); + + if (snapFace(f, verts, intersect, location, normal)) + { + float new_depth; + int screen_loc[2]; + + Mat4MulVecfl(obmat, location); + + new_depth = VecLenf(location, ray_start); + + if (new_depth < *depth) + { + object_depth = lambda; + *depth = new_depth; + retval = 1; + + VECCOPY(loc, location); + VECCOPY(no, normal); + + Mat3MulVecfl(timat, no); + Normalize(no); + + project_int(loc, screen_loc); + + *dist = abs(screen_loc[0] - mval[0]) + abs(screen_loc[1] - mval[1]); + } + } + } + } + } + } + + if (EditMesh) + { + EM_free_index_arrays(); + } + } + } + + return retval; +} + +int snapObjects(int *dist, float *loc, float *no, int mode) { Base *base; + float depth = FLT_MAX; int retval = 0; short mval[2]; + float ray_start[3], ray_normal[3]; getmouseco_areawin(mval); + viewray(mval, ray_start, ray_normal); + + if (mode == NOT_ACTIVE) + { + DerivedMesh *dm, *dm_cage; + Object *ob = G.obedit; + + dm_cage = editmesh_get_derived_cage_and_final(&dm, CD_MASK_BAREMESH); + + retval = snapDerivedMesh(ob, dm, ob->obmat, ray_start, ray_normal, mval, loc, no, dist, &depth, 1); + + dm_cage->release(dm_cage); + dm->release(dm); + } base= FIRSTBASE; for ( base = FIRSTBASE; base != NULL; base = base->next ) { if ( BASE_SELECTABLE(base) && ((mode == NOT_SELECTED && (base->flag & SELECT) == 0) || (mode == NOT_ACTIVE && base != BASACT)) ) { Object *ob = base->object; - if (ob->type == OB_MESH) { - Mesh *me = ob->data; + if (ob->transflag & OB_DUPLI) + { + DupliObject *dupli_ob; + ListBase *lb = object_duplilist(G.scene, ob); - if (me->totvert > 0) { - int test = 1; - int i; + for(dupli_ob = lb->first; dupli_ob; dupli_ob = dupli_ob->next) + { + Object *ob = dupli_ob->ob; - /* If number of vert is more than an arbitrary limit, - * test against boundbox first - * */ - if (me->totvert > 16) { - struct BoundBox *bb = object_get_boundbox(ob); + if (ob->type == OB_MESH) { + DerivedMesh *dm = mesh_get_derived_final(ob, CD_MASK_BAREMESH); + int val; - int minx = 0, miny = 0, maxx = 0, maxy = 0; - int i; - - for (i = 0; i < 8; i++) { - float gloc[3]; - int sloc[2]; - - VECCOPY(gloc, bb->vec[i]); - Mat4MulVecfl(ob->obmat, gloc); - project_int(gloc, sloc); - - if (i == 0) { - minx = maxx = sloc[0]; - miny = maxy = sloc[1]; - } - else { - if (minx > sloc[0]) minx = sloc[0]; - else if (maxx < sloc[0]) maxx = sloc[0]; - - if (miny > sloc[1]) miny = sloc[1]; - else if (maxy < sloc[1]) maxy = sloc[1]; - } - } - - /* Pad with distance */ + val = snapDerivedMesh(ob, dm, dupli_ob->mat, ray_start, ray_normal, mval, loc, no, dist, &depth, 0); - minx -= *dist; - miny -= *dist; - maxx += *dist; - maxy += *dist; - - if (mval[0] > maxx || mval[0] < minx || - mval[1] > maxy || mval[1] < miny) { - - test = 0; - } - } - - if (test == 1) { - float *verts = mesh_get_mapped_verts_nors(ob); - - if (verts != NULL) { - float *fp; - - fp = verts; - for( i = 0; i < me->totvert; i++, fp += 6) { - float gloc[3]; - int sloc[2]; - int curdist; - - VECCOPY(gloc, fp); - Mat4MulVecfl(ob->obmat, gloc); - project_int(gloc, sloc); - - sloc[0] -= mval[0]; - sloc[1] -= mval[1]; - - curdist = abs(sloc[0]) + abs(sloc[1]); - - if (curdist < *dist) { - *dist = curdist; - retval = 1; - VECCOPY(loc, gloc); - } - } - } - - MEM_freeN(verts); + retval = retval || val; + + dm->release(dm); } } + + free_object_duplilist(lb); + } + + if (ob->type == OB_MESH) { + DerivedMesh *dm = mesh_get_derived_final(ob, CD_MASK_BAREMESH); + int val; + + val = snapDerivedMesh(ob, dm, ob->obmat, ray_start, ray_normal, mval, loc, no, dist, &depth, 0); + + retval = retval || val; + + dm->release(dm); } } } From 192037960d0b0f104aee6a8652bf1f410d880b1f Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 9 Jun 2008 22:54:56 +0000 Subject: [PATCH 185/246] error in variable name, not sure how this even compiled --- source/gameengine/GamePlayer/common/GPC_PolygonMaterial.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/gameengine/GamePlayer/common/GPC_PolygonMaterial.cpp b/source/gameengine/GamePlayer/common/GPC_PolygonMaterial.cpp index 09dd14172c8..c2f15aefe16 100644 --- a/source/gameengine/GamePlayer/common/GPC_PolygonMaterial.cpp +++ b/source/gameengine/GamePlayer/common/GPC_PolygonMaterial.cpp @@ -166,7 +166,7 @@ int set_tpage(MTFace *tface) glDisable ( GL_ALPHA_TEST ); /* glBlendEquationEXT(GL_FUNC_ADD_EXT); */ } - else if (alphamode==TF_CLIP){ + else if (fAlphamode==TF_CLIP){ glDisable(GL_BLEND); glEnable ( GL_ALPHA_TEST ); glAlphaFunc(GL_GREATER, 0.5f); From f72d450ae99927e7240f62900af4608a5db2d664 Mon Sep 17 00:00:00 2001 From: Peter Schlaile Date: Tue, 10 Jun 2008 05:12:51 +0000 Subject: [PATCH 186/246] == redcode == This makes it work for Mac OS X. Thanks to Jean-Luc Peuriere for the patch. --- extern/libopenjpeg/opj_malloc.h | 6 ++++-- extern/libopenjpeg/patches/osx.patch | 17 +++++++++++++++++ 2 files changed, 21 insertions(+), 2 deletions(-) create mode 100644 extern/libopenjpeg/patches/osx.patch diff --git a/extern/libopenjpeg/opj_malloc.h b/extern/libopenjpeg/opj_malloc.h index 79698f8ff1b..4e9727af0f3 100644 --- a/extern/libopenjpeg/opj_malloc.h +++ b/extern/libopenjpeg/opj_malloc.h @@ -76,8 +76,10 @@ Allocate memory aligned to a 16 byte boundry #if defined(__sun) #define HAVE_MEMALIGN #elif defined(__GNUC__) - #define HAVE_MEMALIGN - #include + #ifndef __APPLE__ + #define HAVE_MEMALIGN + #include + #endif /* Linux x86_64 and OSX always align allocations to 16 bytes */ #elif !defined(__amd64__) && !defined(__APPLE__) /* FIXME: Yes, this is a big assumption */ diff --git a/extern/libopenjpeg/patches/osx.patch b/extern/libopenjpeg/patches/osx.patch new file mode 100644 index 00000000000..c518978eed6 --- /dev/null +++ b/extern/libopenjpeg/patches/osx.patch @@ -0,0 +1,17 @@ +Index: opj_malloc.h +=================================================================== +--- opj_malloc.h (revision 15089) ++++ opj_malloc.h (working copy) +@@ -76,8 +76,10 @@ + #if defined(__sun) + #define HAVE_MEMALIGN + #elif defined(__GNUC__) +- #define HAVE_MEMALIGN +- #include ++ #ifndef __APPLE__ ++ #define HAVE_MEMALIGN ++ #include ++ #endif + /* Linux x86_64 and OSX always align allocations to 16 bytes */ + #elif !defined(__amd64__) && !defined(__APPLE__) + /* FIXME: Yes, this is a big assumption */ From 70453c9e809eb92c6dfbd40949daa5dd792d8e28 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 10 Jun 2008 10:26:13 +0000 Subject: [PATCH 187/246] bugfix, missing calls to free editmesh index arrays --- source/blender/src/editmesh_lib.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/source/blender/src/editmesh_lib.c b/source/blender/src/editmesh_lib.c index 6251ba1a650..4d9679b6b8a 100644 --- a/source/blender/src/editmesh_lib.c +++ b/source/blender/src/editmesh_lib.c @@ -2199,18 +2199,25 @@ UvVertMap *make_uv_vert_map_EM(int selected, int do_face_idx_array, float *limit if(!selected || ((!efa->h) && (efa->f & SELECT))) totuv += (efa->v4)? 4: 3; - if(totuv==0) + if(totuv==0) { + if (do_face_idx_array) + EM_free_index_arrays(); return NULL; - + } vmap= (UvVertMap*)MEM_callocN(sizeof(*vmap), "UvVertMap"); - if (!vmap) + if (!vmap) { + if (do_face_idx_array) + EM_free_index_arrays(); return NULL; + } vmap->vert= (UvMapVert**)MEM_callocN(sizeof(*vmap->vert)*totverts, "UvMapVert*"); buf= vmap->buf= (UvMapVert*)MEM_callocN(sizeof(*vmap->buf)*totuv, "UvMapVert"); if (!vmap->vert || !vmap->buf) { free_uv_vert_map(vmap); + if (do_face_idx_array) + EM_free_index_arrays(); return NULL; } From d086126616fce3be0899369f21e1117b1d8d865a Mon Sep 17 00:00:00 2001 From: Geoffrey Bantle Date: Tue, 10 Jun 2008 16:18:45 +0000 Subject: [PATCH 188/246] -> Stack corruption in viewline in viw.c viewline() would write past the end of an array allocated on the stack causing crashes. Fixed this. Martin, could you take a look at this? --- source/blender/src/view.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/src/view.c b/source/blender/src/view.c index 835aeb9bb30..008387d5a70 100644 --- a/source/blender/src/view.c +++ b/source/blender/src/view.c @@ -156,7 +156,7 @@ void viewray(short mval[2], float ray_start[3], float ray_normal[3]) /* create intersection coordinates in view Z direction at mouse coordinates */ void viewline(short mval[2], float ray_start[3], float ray_end[3]) { - float vec[3]; + float vec[4]; if(G.vd->persp != V3D_ORTHO){ vec[0]= 2.0f * mval[0] / curarea->winx - 1; From bdb3ef08cf694b167689a54e25ab026118b43e6d Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 11 Jun 2008 05:25:52 +0000 Subject: [PATCH 189/246] Increased new nla, sound, action, ipo, timeline spaces max zoomlevel to use MAXFRAMEF, so you can view an entire animation ans so all time spaces have the same maximum which is important when the views lock to each others zoomlevel. Not ideal since it only affects newly created spaces, but probably not worth going through doversions since it wont effect many blender users. --- source/blender/src/space.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/source/blender/src/space.c b/source/blender/src/space.c index 90a48565a8f..6de12cf0f1e 100644 --- a/source/blender/src/space.c +++ b/source/blender/src/space.c @@ -3216,7 +3216,7 @@ void initipo(ScrArea *sa) sipo->v2d.min[0]= 0.01f; sipo->v2d.min[1]= 0.01f; - sipo->v2d.max[0]= 15000.0f; + sipo->v2d.max[0]= MAXFRAMEF; sipo->v2d.max[1]= 10000.0f; sipo->v2d.scroll= L_SCROLL+B_SCROLL; @@ -5175,7 +5175,7 @@ static void init_actionspace(ScrArea *sa) saction->v2d.min[0]= 0.0; saction->v2d.min[1]= 0.0; - saction->v2d.max[0]= 32000.0; + saction->v2d.max[0]= MAXFRAMEF; saction->v2d.max[1]= 1000.0; saction->v2d.minzoom= 0.01; @@ -5247,7 +5247,7 @@ static void init_soundspace(ScrArea *sa) ssound->v2d.min[0]= 1.0; ssound->v2d.min[1]= 259.0; - ssound->v2d.max[0]= 32000.0; + ssound->v2d.max[0]= MAXFRAMEF; ssound->v2d.max[1]= 259; ssound->v2d.minzoom= 0.1f; @@ -5977,7 +5977,7 @@ static void init_nlaspace(ScrArea *sa) snla->v2d.min[0]= 0.0; snla->v2d.min[1]= 0.0; - snla->v2d.max[0]= 1000.0; + snla->v2d.max[0]= MAXFRAMEF; snla->v2d.max[1]= 1000.0; snla->v2d.minzoom= 0.1F; @@ -6065,7 +6065,7 @@ static void init_timespace(ScrArea *sa) stime->v2d.min[0]= 1.0; stime->v2d.min[1]= (float)sa->winy; - stime->v2d.max[0]= 32000.0; + stime->v2d.max[0]= MAXFRAMEF; stime->v2d.max[1]= (float)sa->winy; stime->v2d.minzoom= 0.1f; From ef0ea178b13b6642517f820a2baf3c316110d7ae Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 11 Jun 2008 09:04:41 +0000 Subject: [PATCH 190/246] bugfix, off by 1 error when filling in uninitialized values for new ID values when the requested name length was greater to or equal to 21. Also replaced incorrect use of strcpy with memmove since the strings overlap --- source/blender/blenkernel/intern/library.c | 2 +- source/blender/blenlib/intern/util.c | 22 ++++++++++++++++------ 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/source/blender/blenkernel/intern/library.c b/source/blender/blenkernel/intern/library.c index cc3f3f211a4..7c50b409693 100644 --- a/source/blender/blenkernel/intern/library.c +++ b/source/blender/blenkernel/intern/library.c @@ -934,7 +934,7 @@ int new_id(ListBase *lb, ID *id, const char *tname) } /* if result > 21, strncpy don't put the final '\0' to name. */ - if( result > 21 ) name[21]= 0; + if( result >= 21 ) name[21]= 0; result = check_for_dupid( lb, id, name ); strcpy( id->name+2, name ); diff --git a/source/blender/blenlib/intern/util.c b/source/blender/blenlib/intern/util.c index 848e45ccb1b..a353015052c 100644 --- a/source/blender/blenlib/intern/util.c +++ b/source/blender/blenlib/intern/util.c @@ -883,6 +883,15 @@ void BLI_cleanup_file(const char *relabase, char *dir) dir = dir+2; /* skip the first // */ } } + + /* Note + * memmove( start, eind, strlen(eind)+1 ); + * is the same as + * strcpy( start, eind ); + * except strcpy should not be used because there is overlap, + * so use memmove's slightly more obscure syntax - Campbell + */ + #ifdef WIN32 if(dir[0]=='.') { /* happens for example in FILE_MAIN */ get_default_root(dir); @@ -896,17 +905,18 @@ void BLI_cleanup_file(const char *relabase, char *dir) if (dir[a] == '\\') break; a--; } - strcpy(dir+a,eind); + memmove( dir+a, eind, strlen(eind)+1 ); + } while ( (start = strstr(dir,"\\.\\")) ){ eind = start + strlen("\\.\\") - 1; - strcpy(start,eind); + memmove( start, eind, strlen(eind)+1 ); } while ( (start = strstr(dir,"\\\\" )) ){ eind = start + strlen("\\\\") - 1; - strcpy(start,eind); + memmove( start, eind, strlen(eind)+1 ); } if((a = strlen(dir))){ /* remove the '\\' at the end */ @@ -929,17 +939,17 @@ void BLI_cleanup_file(const char *relabase, char *dir) if (dir[a] == '/') break; a--; } - strcpy(dir+a,eind); + memmove( dir+a, eind, strlen(eind)+1 ); } while ( (start = strstr(dir,"/./")) ){ eind = start + strlen("/./") - 1; - strcpy(start,eind); + memmove( start, eind, strlen(eind)+1 ); } while ( (start = strstr(dir,"//" )) ){ eind = start + strlen("//") - 1; - strcpy(start,eind); + memmove( start, eind, strlen(eind)+1 ); } if( (a = strlen(dir)) ){ /* remove all '/' at the end */ From d0fc57e5dfb574fa63d34572a6e6e9c0f39127bc Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 11 Jun 2008 10:45:41 +0000 Subject: [PATCH 191/246] [#13723] Select -> Grouped -> Objects in Same Group doesn't work directly after appending Menu was shown even when it couldn't do anything. behavior now matches the object copy menu. --- source/blender/src/space.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/src/space.c b/source/blender/src/space.c index 6de12cf0f1e..53962d9519b 100644 --- a/source/blender/src/space.c +++ b/source/blender/src/space.c @@ -2084,7 +2084,7 @@ static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt) } else if(ob && (ob->flag & OB_POSEMODE)) pose_select_grouped_menu(); - else + else if (ob) select_object_grouped_menu(); else if((G.obedit==0) && G.qual==LR_ALTKEY) { if(okee("Clear location")) { From 21a46a0155b4eefc91deb805b5f6f42afdf404cd Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 11 Jun 2008 14:31:51 +0000 Subject: [PATCH 192/246] bugfix - duplicated script spaces would keep a pointer to the PyObject button list. (causing python errors with negative reference counts when freeing spaces) - Exiting blender would crash when a UI was open because the ScriptSpaces button PyList was being free'd after python Py_Finalize was called. --- source/blender/python/BPY_interface.c | 14 +++++++++----- source/blender/src/space.c | 5 ++++- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/source/blender/python/BPY_interface.c b/source/blender/python/BPY_interface.c index 7c23c86d9ba..2f94e0eeebc 100644 --- a/source/blender/python/BPY_interface.c +++ b/source/blender/python/BPY_interface.c @@ -1154,13 +1154,17 @@ static void unlink_script( Script * script ) if( sl->spacetype == SPACE_SCRIPT ) { SpaceScript *sc = ( SpaceScript * ) sl; - if( sc->script == script ) { + if( sc->script == script ) { sc->script = NULL; - if( sc == - area->spacedata.first ) { - scrarea_queue_redraw - ( area ); + if( sc == area->spacedata.first ) { + scrarea_queue_redraw( area ); + } + + if (sc->but_refs) { + BPy_Set_DrawButtonsList(sc->but_refs); + BPy_Free_DrawButtonsList(); + sc->but_refs = NULL; } } } diff --git a/source/blender/src/space.c b/source/blender/src/space.c index 53962d9519b..a31bd457f47 100644 --- a/source/blender/src/space.c +++ b/source/blender/src/space.c @@ -6334,7 +6334,10 @@ void duplicatespacelist(ScrArea *newarea, ListBase *lb1, ListBase *lb2) SpaceNode *snode= (SpaceNode *)sl; snode->nodetree= NULL; } - + else if(sl->spacetype==SPACE_SCRIPT) { + SpaceScript *sc = ( SpaceScript * ) sl; + sc->but_refs = NULL; + } sl= sl->next; } From 39a47826e31219996c8a08b6cbe80d87ad3661cd Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Wed, 11 Jun 2008 20:15:47 +0000 Subject: [PATCH 193/246] Fix for commit revision 15197, missing braces caused some shortcut keys not to work anymore. --- source/blender/src/space.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source/blender/src/space.c b/source/blender/src/space.c index a31bd457f47..c49486a6294 100644 --- a/source/blender/src/space.c +++ b/source/blender/src/space.c @@ -2077,7 +2077,7 @@ static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt) vgroup_operation_with_menu(); } } - else if((G.qual==LR_SHIFTKEY)) + else if((G.qual==LR_SHIFTKEY)) { if(G.obedit) { if(G.obedit->type==OB_MESH) select_mesh_group_menu(); @@ -2086,6 +2086,7 @@ static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt) pose_select_grouped_menu(); else if (ob) select_object_grouped_menu(); + } else if((G.obedit==0) && G.qual==LR_ALTKEY) { if(okee("Clear location")) { clear_object('g'); From 82a108b4134cf43a185c22bfe7bf2035c4f6375a Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 12 Jun 2008 14:46:32 +0000 Subject: [PATCH 194/246] Curve Smoorth for venomgfx adjusting animation paths over terrain. --- source/blender/include/BDR_editcurve.h | 1 + source/blender/src/editcurve.c | 56 ++++++++++++++++++++++++++ source/blender/src/editobject.c | 5 ++- 3 files changed, 61 insertions(+), 1 deletion(-) diff --git a/source/blender/include/BDR_editcurve.h b/source/blender/include/BDR_editcurve.h index 4604359fcc9..363a6567f3e 100644 --- a/source/blender/include/BDR_editcurve.h +++ b/source/blender/include/BDR_editcurve.h @@ -99,6 +99,7 @@ int bezt_compare (const void *e1, const void *e2); void setweightNurb( void ); void setradiusNurb( void ); void smoothradiusNurb( void ); +void smoothNurb( void ); extern void undo_push_curve(char *name); diff --git a/source/blender/src/editcurve.c b/source/blender/src/editcurve.c index bd0abe83ee4..261bb26b0c4 100644 --- a/source/blender/src/editcurve.c +++ b/source/blender/src/editcurve.c @@ -1158,6 +1158,62 @@ void setradiusNurb( void ) allqueue(REDRAWINFO, 1); /* 1, because header->win==0! */ } +void smoothNurb( void ) +{ + + extern ListBase editNurb; + Nurb *nu; + BezTriple *bezt, *beztOrig; + BPoint *bp, *bpOrig; + int a, i, change = 0; + + /* floats for smoothing */ + float val, newval, offset; + + for(nu= editNurb.first; nu; nu= nu->next) { + if(nu->bezt) { + change = 0; + beztOrig = MEM_dupallocN( nu->bezt ); + for(bezt=nu->bezt+1, a=1; apntsu-1; a++, bezt++) { + if(bezt->f2 & SELECT) { + for(i=0; i<3; i++) { + val = bezt->vec[1][i]; + newval = ((beztOrig+(a-1))->vec[1][i] * 0.5) + ((beztOrig+(a+1))->vec[1][i] * 0.5); + offset = (val*((1.0/6.0)*5)) + (newval*(1.0/6.0)) - val; + /* offset handles */ + bezt->vec[1][i] += offset; + bezt->vec[0][i] += offset; + bezt->vec[2][i] += offset; + } + change = 1; + } + } + MEM_freeN(beztOrig); + if (change) + calchandlesNurb(nu); + } else if (nu->bp) { + bpOrig = MEM_dupallocN( nu->bp ); + /* Same as above, keep these the same! */ + for(bp=nu->bp+1, a=1; apntsu-1; a++, bp++) { + if(bp->f1 & SELECT) { + for(i=0; i<3; i++) { + val = bp->vec[i]; + newval = ((bpOrig+(a-1))->vec[i] * 0.5) + ((bpOrig+(a+1))->vec[i] * 0.5); + offset = (val*((1.0/6.0)*5)) + (newval*(1.0/6.0)) - val; + + bp->vec[i] += offset; + } + } + } + MEM_freeN(bpOrig); + } + } + BIF_undo_push("Smooth Curve"); + DAG_object_flush_update(G.scene, OBACT, OB_RECALC_DATA); + allqueue(REDRAWVIEW3D, 0); + allqueue(REDRAWBUTSALL, 0); + allqueue(REDRAWINFO, 1); /* 1, because header->win==0! */ +} /* TODO, make smoothing distance based */ void smoothradiusNurb( void ) diff --git a/source/blender/src/editobject.c b/source/blender/src/editobject.c index 4029e031b63..38664f72b25 100644 --- a/source/blender/src/editobject.c +++ b/source/blender/src/editobject.c @@ -2735,7 +2735,7 @@ void special_editmenu(void) } else if ELEM(G.obedit->type, OB_CURVE, OB_SURF) { - nr= pupmenu("Specials%t|Subdivide%x1|Switch Direction%x2|Set Goal Weight %x3|Set Radius %x4|Smooth Radius %x5"); + nr= pupmenu("Specials%t|Subdivide%x1|Switch Direction%x2|Set Goal Weight %x3|Set Radius %x4|Smooth Radius %x5|Smooth Radius %x6"); switch(nr) { case 1: @@ -2751,6 +2751,9 @@ void special_editmenu(void) setradiusNurb(); break; case 5: + smoothNurb(); + break; + case 6: smoothradiusNurb(); break; } From 1091db8f9b67772cc688cfb545bb616e203e3942 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 12 Jun 2008 15:00:07 +0000 Subject: [PATCH 195/246] didnt name the smooth curve menu item. --- source/blender/src/editobject.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/src/editobject.c b/source/blender/src/editobject.c index 38664f72b25..3c945775b5b 100644 --- a/source/blender/src/editobject.c +++ b/source/blender/src/editobject.c @@ -2735,7 +2735,7 @@ void special_editmenu(void) } else if ELEM(G.obedit->type, OB_CURVE, OB_SURF) { - nr= pupmenu("Specials%t|Subdivide%x1|Switch Direction%x2|Set Goal Weight %x3|Set Radius %x4|Smooth Radius %x5|Smooth Radius %x6"); + nr= pupmenu("Specials%t|Subdivide%x1|Switch Direction%x2|Set Goal Weight%x3|Set Radius%x4|Smooth%x5|Smooth Radius%x6"); switch(nr) { case 1: From 7ffd70f39aec2388e3240b6981a20a4b9b23c271 Mon Sep 17 00:00:00 2001 From: Ben Batt Date: Thu, 12 Jun 2008 15:43:55 +0000 Subject: [PATCH 196/246] Patch #8613 - Vertex groups in the mirror modifier. This patch re-assigns the mirrored data to use vertex groups with "mirrored" names (e.g. L_arm -> R_arm, Leg.R -> Leg.L etc.). Vertex groups with the "mirrored" names must already exist in the base mesh. This means that it is no longer necessary to apply the mirror modifier in order to rig the mirrored data independently. Thanks to Michael Fox for the patch! --- source/blender/blenkernel/intern/modifier.c | 169 ++++++++++++++++++- source/blender/makesdna/DNA_modifier_types.h | 1 + source/blender/src/buttons_editing.c | 3 +- 3 files changed, 170 insertions(+), 3 deletions(-) diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c index bd8a2ea219a..861534deb80 100644 --- a/source/blender/blenkernel/intern/modifier.c +++ b/source/blender/blenkernel/intern/modifier.c @@ -40,6 +40,7 @@ #include "stdarg.h" #include "math.h" #include "float.h" +#include "ctype.h" #include "BLI_arithb.h" #include "BLI_blenlib.h" @@ -1269,7 +1270,7 @@ static void mirrorModifier_initData(ModifierData *md) { MirrorModifierData *mmd = (MirrorModifierData*) md; - mmd->flag |= MOD_MIR_AXIS_X; + mmd->flag |= (MOD_MIR_AXIS_X | MOD_MIR_VGROUP); mmd->tolerance = 0.001; mmd->mirror_ob = NULL; } @@ -1308,6 +1309,118 @@ static void mirrorModifier_updateDepgraph(ModifierData *md, DagForest *forest, } } +/* finds the best possible flipped name. For renaming; check for unique names afterwards */ +/* if strip_number: removes number extensions */ +void vertgroup_flip_name (char *name, int strip_number) +{ + int len; + char prefix[128]={""}; /* The part before the facing */ + char suffix[128]={""}; /* The part after the facing */ + char replace[128]={""}; /* The replacement string */ + char number[128]={""}; /* The number extension string */ + char *index=NULL; + + len= strlen(name); + if(len<3) return; // we don't do names like .R or .L + + /* We first check the case with a .### extension, let's find the last period */ + if(isdigit(name[len-1])) { + index= strrchr(name, '.'); // last occurrance + if (index && isdigit(index[1]) ) { // doesnt handle case bone.1abc2 correct..., whatever! + if(strip_number==0) + strcpy(number, index); + *index= 0; + len= strlen(name); + } + } + + strcpy (prefix, name); + +#define IS_SEPARATOR(a) ((a)=='.' || (a)==' ' || (a)=='-' || (a)=='_') + + /* first case; separator . - _ with extensions r R l L */ + if( IS_SEPARATOR(name[len-2]) ) { + switch(name[len-1]) { + case 'l': + prefix[len-1]= 0; + strcpy(replace, "r"); + break; + case 'r': + prefix[len-1]= 0; + strcpy(replace, "l"); + break; + case 'L': + prefix[len-1]= 0; + strcpy(replace, "R"); + break; + case 'R': + prefix[len-1]= 0; + strcpy(replace, "L"); + break; + } + } + /* case; beginning with r R l L , with separator after it */ + else if( IS_SEPARATOR(name[1]) ) { + switch(name[0]) { + case 'l': + strcpy(replace, "r"); + strcpy(suffix, name+1); + prefix[0]= 0; + break; + case 'r': + strcpy(replace, "l"); + strcpy(suffix, name+1); + prefix[0]= 0; + break; + case 'L': + strcpy(replace, "R"); + strcpy(suffix, name+1); + prefix[0]= 0; + break; + case 'R': + strcpy(replace, "L"); + strcpy(suffix, name+1); + prefix[0]= 0; + break; + } + } + else if(len > 5) { + /* hrms, why test for a separator? lets do the rule 'ultimate left or right' */ + index = BLI_strcasestr(prefix, "right"); + if (index==prefix || index==prefix+len-5) { + if(index[0]=='r') + strcpy (replace, "left"); + else { + if(index[1]=='I') + strcpy (replace, "LEFT"); + else + strcpy (replace, "Left"); + } + *index= 0; + strcpy (suffix, index+5); + } + else { + index = BLI_strcasestr(prefix, "left"); + if (index==prefix || index==prefix+len-4) { + if(index[0]=='l') + strcpy (replace, "right"); + else { + if(index[1]=='E') + strcpy (replace, "RIGHT"); + else + strcpy (replace, "Right"); + } + *index= 0; + strcpy (suffix, index+4); + } + } + } + +#undef IS_SEPARATOR + + sprintf (name, "%s%s%s%s", prefix, replace, suffix, number); +} + static DerivedMesh *doMirrorOnAxis(MirrorModifierData *mmd, Object *ob, DerivedMesh *dm, @@ -1321,6 +1434,9 @@ static DerivedMesh *doMirrorOnAxis(MirrorModifierData *mmd, int maxVerts = dm->getNumVerts(dm); int maxEdges = dm->getNumEdges(dm); int maxFaces = dm->getNumFaces(dm); + int vector_size, j, a, b; + bDeformGroup *def, *defb; + bDeformGroup **vector_def = NULL; int (*indexMap)[2]; float mtx[4][4], imtx[4][4]; @@ -1330,6 +1446,21 @@ static DerivedMesh *doMirrorOnAxis(MirrorModifierData *mmd, result = CDDM_from_template(dm, maxVerts * 2, maxEdges * 2, maxFaces * 2); + + if (mmd->flag & MOD_MIR_VGROUP) { + /* calculate the number of deformedGroups */ + for(vector_size = 0, def = ob->defbase.first; def; + def = def->next, vector_size++); + + /* load the deformedGroups for fast access */ + vector_def = + (bDeformGroup **)MEM_mallocN(sizeof(bDeformGroup*) * vector_size, + "group_index"); + for(a = 0, def = ob->defbase.first; def; def = def->next, a++) { + vector_def[a] = def; + } + } + if (mmd->mirror_ob) { float obinv[4][4]; @@ -1374,16 +1505,48 @@ static DerivedMesh *doMirrorOnAxis(MirrorModifierData *mmd, mv->flag |= ME_VERT_MERGED; } else { MVert *mv2 = CDDM_get_vert(result, numVerts); + MDeformVert *dvert = NULL; DM_copy_vert_data(dm, result, i, numVerts, 1); *mv2 = *mv; - numVerts++; co[axis] = -co[axis]; if (mmd->mirror_ob) { VecMat4MulVecfl(co, imtx, co); } VecCopyf(mv2->co, co); + + if (mmd->flag & MOD_MIR_VGROUP){ + dvert = DM_get_vert_data(result, numVerts, CD_MDEFORMVERT); + + if (dvert) + { + for(j = 0; j < dvert[0].totweight; ++j) + { + char tmpname[32]; + + if(dvert->dw[j].def_nr < 0 || + dvert->dw[j].def_nr >= vector_size) + continue; + + def = vector_def[dvert->dw[j].def_nr]; + strcpy(tmpname, def->name); + vertgroup_flip_name(tmpname,0); + + for(b = 0, defb = ob->defbase.first; defb; + defb = defb->next, b++) + { + if(!strcmp(defb->name, tmpname)) + { + dvert->dw[j].def_nr = b; + break; + } + } + } + } + } + + numVerts++; } } @@ -1467,6 +1630,8 @@ static DerivedMesh *doMirrorOnAxis(MirrorModifierData *mmd, } } + if (vector_def) MEM_freeN(vector_def); + MEM_freeN(indexMap); CDDM_lower_num_verts(result, numVerts); diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h index fc015775f49..8c1df1450e8 100644 --- a/source/blender/makesdna/DNA_modifier_types.h +++ b/source/blender/makesdna/DNA_modifier_types.h @@ -176,6 +176,7 @@ typedef struct MirrorModifierData { #define MOD_MIR_AXIS_X 1<<3 #define MOD_MIR_AXIS_Y 1<<4 #define MOD_MIR_AXIS_Z 1<<5 +#define MOD_MIR_VGROUP 1<<6 typedef struct EdgeSplitModifierData { ModifierData modifier; diff --git a/source/blender/src/buttons_editing.c b/source/blender/src/buttons_editing.c index 7e154d6c341..5d477b7ab09 100644 --- a/source/blender/src/buttons_editing.c +++ b/source/blender/src/buttons_editing.c @@ -1767,7 +1767,7 @@ static void draw_modifier(uiBlock *block, Object *ob, ModifierData *md, int *xco } else if (md->type==eModifierType_Build) { height = 86; } else if (md->type==eModifierType_Mirror) { - height = 86; + height = 105; } else if (md->type==eModifierType_Bevel) { BevelModifierData *bmd = (BevelModifierData*) md; height = 105; /* height = 124; */ @@ -1899,6 +1899,7 @@ static void draw_modifier(uiBlock *block, Object *ob, ModifierData *md, int *xco uiDefButBitS(block, TOG, MOD_MIR_AXIS_Y, B_MODIFIER_RECALC, "Y", lx+20,cy,20,19, &mmd->flag, 0, 0, 0, 0, "Enable Y axis mirror"); uiDefButBitS(block, TOG, MOD_MIR_AXIS_Z, B_MODIFIER_RECALC, "Z", lx+40,cy,20,19, &mmd->flag, 0, 0, 0, 0, "Enable Z axis mirror"); uiDefButBitS(block, TOG, MOD_MIR_CLIPPING, B_MODIFIER_RECALC, "Do Clipping", lx+60, cy, buttonWidth-60,19, &mmd->flag, 1, 2, 0, 0, "Prevents during Transform vertices to go through Mirror"); + uiDefButBitS(block, TOG, MOD_MIR_VGROUP, B_MODIFIER_RECALC, "Mirror Vgroups", lx, (cy-=19), buttonWidth,19, &mmd->flag, 1, 2, 0, 0, "Mirror vertex groups (e.g. .R->.L)"); uiDefButBitS(block, TOG, MOD_MIR_MIRROR_U, B_MODIFIER_RECALC, "Mirror U", lx, (cy-=19), buttonWidth/2, 19, From 1e7f1f753f239f071e195d49a6c05963b09f9b42 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 12 Jun 2008 16:29:00 +0000 Subject: [PATCH 197/246] When your home directory is full, saving defaults would fail without raising an error. checked all others instances of BLO_write_file give errors too. When autosave fails it reports an error in the console so its not too annoying. --- source/blender/src/usiblender.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/source/blender/src/usiblender.c b/source/blender/src/usiblender.c index 6c0838288b8..5ac8e186b68 100644 --- a/source/blender/src/usiblender.c +++ b/source/blender/src/usiblender.c @@ -925,7 +925,7 @@ void BIF_write_file(char *target) writeBlog(); } else { - error("%s", err); + error("failed to write blend file: %s", err); } waitcursor(0); @@ -940,7 +940,10 @@ void BIF_write_homefile(void) /* force save as regular blend file */ write_flags = G.fileflags & ~(G_FILE_COMPRESS | G_FILE_LOCK | G_FILE_SIGN); - BLO_write_file(tstr, write_flags, &err); + + if (!BLO_write_file(tstr, write_flags, &err)) { + error("failed writing defaults: %s", err); + } } void BIF_write_autosave(void) @@ -952,7 +955,9 @@ void BIF_write_autosave(void) /* force save as regular blend file */ write_flags = G.fileflags & ~(G_FILE_COMPRESS | G_FILE_LOCK | G_FILE_SIGN); - BLO_write_file(tstr, write_flags, &err); + if (!BLO_write_file(tstr, write_flags, &err)) { + fprintf(stderr, "failed to write autosave: %s\n", err); /* using error(...) is too annoying here */ + } } /* remove temp files assosiated with this blend file when quitting, loading or saving in a new path */ From 21c2613622a99bfea1871ef5b15ff21da706007b Mon Sep 17 00:00:00 2001 From: Benoit Bolsee Date: Thu, 12 Jun 2008 21:17:02 +0000 Subject: [PATCH 198/246] Update MSVC project files --- .../blender/blenkernel/BKE_blenkernel.vcproj | 9 ++++++--- projectfiles_vc7/blender/blenlib/BLI_blenlib.vcproj | 6 ++++++ 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/projectfiles_vc7/blender/blenkernel/BKE_blenkernel.vcproj b/projectfiles_vc7/blender/blenkernel/BKE_blenkernel.vcproj index 98bb21e7ad1..8efff1742b0 100644 --- a/projectfiles_vc7/blender/blenkernel/BKE_blenkernel.vcproj +++ b/projectfiles_vc7/blender/blenkernel/BKE_blenkernel.vcproj @@ -344,6 +344,9 @@ + + @@ -425,9 +428,6 @@ - - @@ -558,6 +558,9 @@ + + diff --git a/projectfiles_vc7/blender/blenlib/BLI_blenlib.vcproj b/projectfiles_vc7/blender/blenlib/BLI_blenlib.vcproj index 8a2b8b95e38..34c195cf23d 100644 --- a/projectfiles_vc7/blender/blenlib/BLI_blenlib.vcproj +++ b/projectfiles_vc7/blender/blenlib/BLI_blenlib.vcproj @@ -346,6 +346,9 @@ + + @@ -458,6 +461,9 @@ + + From 8bd82d4e3645a1e1e141522f6a127bb73759096b Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 13 Jun 2008 02:20:09 +0000 Subject: [PATCH 199/246] Some pose action ipo corruptions when using BGE, added some debug printf's when copying to/from the same pose since it should never happen. --- source/blender/blenkernel/intern/action.c | 17 +++++++++++++++++ .../gameengine/Converter/BL_ArmatureObject.cpp | 5 +++-- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/source/blender/blenkernel/intern/action.c b/source/blender/blenkernel/intern/action.c index 5fb3d6f869a..4860c65f06c 100644 --- a/source/blender/blenkernel/intern/action.c +++ b/source/blender/blenkernel/intern/action.c @@ -290,6 +290,12 @@ void copy_pose(bPose **dst, bPose *src, int copycon) return; } + if (*dst==src) { + printf("copy_pose source and target are the same\n"); + *dst=NULL; + return; + } + outPose= MEM_callocN(sizeof(bPose), "pose"); duplicatelist(&outPose->chanbase, &src->chanbase); @@ -740,6 +746,11 @@ void extract_pose_from_pose(bPose *pose, const bPose *src) const bPoseChannel *schan; bPoseChannel *pchan= pose->chanbase.first; + if (pose==src) { + printf("extract_pose_from_pose source and target are the same\n"); + return; + } + for (schan=src->chanbase.first; schan; schan=schan->next, pchan= pchan->next) { copy_pose_channel_data(pchan, schan); } @@ -817,6 +828,12 @@ void copy_pose_result(bPose *to, bPose *from) return; } + if (to==from) { + printf("copy_pose_result source and target are the same\n"); + return; + } + + for(pchanfrom= from->chanbase.first; pchanfrom; pchanfrom= pchanfrom->next) { pchanto= get_pose_channel(to, pchanfrom->name); if(pchanto) { diff --git a/source/gameengine/Converter/BL_ArmatureObject.cpp b/source/gameengine/Converter/BL_ArmatureObject.cpp index 08567dde840..d4712efda9e 100644 --- a/source/gameengine/Converter/BL_ArmatureObject.cpp +++ b/source/gameengine/Converter/BL_ArmatureObject.cpp @@ -92,9 +92,10 @@ BL_ArmatureObject::~BL_ArmatureObject() /* there is only 1 unique Pose per Armature */ void BL_ArmatureObject::ApplyPose() { - if (m_pose){ + if (m_pose) { // copy to armature object - extract_pose_from_pose(m_objArma->pose, m_pose); + if (m_objArma->pose != m_pose)/* This should never happen but it does - Campbell */ + extract_pose_from_pose(m_objArma->pose, m_pose); // is this needed anymore? //if (!m_mrdPose) From 714c6d5010356505e7b393bdda5e187b19e2da55 Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Sat, 14 Jun 2008 03:00:38 +0000 Subject: [PATCH 200/246] Bugfix: Campbell's recent commit to fix game-engine pose/ipo corruption was causing segfaults with duplicating armatures. --- source/blender/blenkernel/intern/object.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index 125243bc56f..b72d9a0b044 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -1100,6 +1100,8 @@ static void copy_object_pose(Object *obn, Object *ob) { bPoseChannel *chan; + /* note: need to clear obn->pose pointer first, so that copy_pose works (otherwise there's a crash) */ + obn->pose= NULL; copy_pose(&obn->pose, ob->pose, 1); /* 1 = copy constraints */ for (chan = obn->pose->chanbase.first; chan; chan=chan->next){ From 9c2bf9bdbcc23bb008af543b4fbbdf7c33d0decd Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sat, 14 Jun 2008 16:54:46 +0000 Subject: [PATCH 201/246] bugfix for memory corruption caused by BLI_cleanup_file on paths that went too far back. /a/b/../../../ - problematic /a/b/c/../../../ - ok Also got rid of warnings in shadbuf.c with GET_INT_FROM_POINTER --- source/blender/blenlib/intern/util.c | 19 +++++++++++++------ source/blender/render/intern/source/shadbuf.c | 4 ++-- 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/source/blender/blenlib/intern/util.c b/source/blender/blenlib/intern/util.c index a353015052c..5a85fbfc375 100644 --- a/source/blender/blenlib/intern/util.c +++ b/source/blender/blenlib/intern/util.c @@ -905,8 +905,11 @@ void BLI_cleanup_file(const char *relabase, char *dir) if (dir[a] == '\\') break; a--; } - memmove( dir+a, eind, strlen(eind)+1 ); - + if (a<0) { + break; + } else { + memmove( dir+a, eind, strlen(eind)+1 ); + } } while ( (start = strstr(dir,"\\.\\")) ){ @@ -939,7 +942,11 @@ void BLI_cleanup_file(const char *relabase, char *dir) if (dir[a] == '/') break; a--; } - memmove( dir+a, eind, strlen(eind)+1 ); + if (a<0) { + break; + } else { + memmove( dir+a, eind, strlen(eind)+1 ); + } } while ( (start = strstr(dir,"/./")) ){ @@ -1128,8 +1135,8 @@ int BLI_convertstringcode(char *path, const char *basepath) char vol[3] = {'\0', '\0', '\0'}; BLI_strncpy(vol, path, 3); - wasrelative= (strncmp(vol, "//", 2)==0); - + wasrelative= (vol[0]=='/' && vol[1]=='/'); + #ifdef WIN32 /* we are checking here if we have an absolute path that is not in the current blend file as a lib main - we are basically checking for the case that a @@ -1166,7 +1173,7 @@ int BLI_convertstringcode(char *path, const char *basepath) /* Paths starting with // will get the blend file as their base, * this isnt standard in any os but is uesed in blender all over the place */ - if (tmp[0] == '/' && tmp[1] == '/') { + if (wasrelative) { char *lslash= BLI_last_slash(base); if (lslash) { int baselen= (int) (lslash-base) + 1; diff --git a/source/blender/render/intern/source/shadbuf.c b/source/blender/render/intern/source/shadbuf.c index 796272eab2e..f3258b601de 100644 --- a/source/blender/render/intern/source/shadbuf.c +++ b/source/blender/render/intern/source/shadbuf.c @@ -636,7 +636,7 @@ static float readshadowbuf(ShadBuf *shb, ShadSampleBuf *shsample, int bias, int else { /* got warning on this for 64 bits.... */ /* but it's working code! in this case rz is not a pointer but zvalue (ton) */ - zsamp= (int) rz; + zsamp= GET_INT_FROM_POINTER(rz); } /* tricky stuff here; we use ints which can overflow easily with bias values */ @@ -816,7 +816,7 @@ static float readshadowbuf_halo(ShadBuf *shb, ShadSampleBuf *shsample, int xs, i else { /* same as before */ /* still working code! (ton) */ - zsamp= (int) rz; + zsamp= GET_INT_FROM_POINTER(rz); } /* NO schadow when sampled at 'eternal' distance */ From fc7a83b458811883b01e948a37e6177ae96602db Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sat, 14 Jun 2008 17:12:49 +0000 Subject: [PATCH 202/246] Added access for adjusting timeOffset value at runtime, used for apricot (Franky climbing walls) --- source/gameengine/Ketsji/KX_GameObject.cpp | 21 +++++++++++++++++++ .../Ketsji/KX_SG_NodeRelationships.h | 15 +++++++++++++ source/gameengine/PyDoc/KX_GameObject.py | 2 ++ source/gameengine/SceneGraph/SG_Node.cpp | 11 ++++++++++ source/gameengine/SceneGraph/SG_Node.h | 8 +++++++ .../gameengine/SceneGraph/SG_ParentRelation.h | 10 +++++++++ source/gameengine/SceneGraph/SG_Spatial.cpp | 7 +++++++ source/gameengine/SceneGraph/SG_Spatial.h | 4 ++++ 8 files changed, 78 insertions(+) diff --git a/source/gameengine/Ketsji/KX_GameObject.cpp b/source/gameengine/Ketsji/KX_GameObject.cpp index c192cd01261..6fde94fec53 100644 --- a/source/gameengine/Ketsji/KX_GameObject.cpp +++ b/source/gameengine/Ketsji/KX_GameObject.cpp @@ -911,6 +911,14 @@ PyObject* KX_GameObject::_getattr(const STR_String& attr) if (attr == "name") return PyString_FromString(m_name.ReadPtr()); + if (attr == "timeOffset") { + if (m_pSGNode->GetSGParent()->IsSlowParent()) { + return PyFloat_FromDouble(static_cast(m_pSGNode->GetSGParent()->GetParentRelation())->GetTimeOffset()); + } else { + return PyFloat_FromDouble(0.0); + } + } + _getattr_up(SCA_IObject); } @@ -932,6 +940,19 @@ int KX_GameObject::_setattr(const STR_String& attr, PyObject *value) // _setattr return 0; } } + + if (PyFloat_Check(value)) + { + MT_Scalar val = PyFloat_AsDouble(value); + if (attr == "timeOffset") { + if (m_pSGNode->GetSGParent()->IsSlowParent()) { + static_cast(m_pSGNode->GetSGParent()->GetParentRelation())->SetTimeOffset(val); + return 0; + } else { + return 0; + } + } + } if (PySequence_Check(value)) { diff --git a/source/gameengine/Ketsji/KX_SG_NodeRelationships.h b/source/gameengine/Ketsji/KX_SG_NodeRelationships.h index e53af22408e..faa650106c8 100644 --- a/source/gameengine/Ketsji/KX_SG_NodeRelationships.h +++ b/source/gameengine/Ketsji/KX_SG_NodeRelationships.h @@ -177,8 +177,23 @@ public : NewCopy( ); + MT_Scalar + GetTimeOffset( + ) { return m_relax; } + + void + SetTimeOffset( + MT_Scalar relaxation + ) { m_relax = relaxation; } + ~KX_SlowParentRelation( ); + + bool + IsSlowRelation( + ) { + return true; + } private : diff --git a/source/gameengine/PyDoc/KX_GameObject.py b/source/gameengine/PyDoc/KX_GameObject.py index 8d29a704380..678df59e4a9 100644 --- a/source/gameengine/PyDoc/KX_GameObject.py +++ b/source/gameengine/PyDoc/KX_GameObject.py @@ -22,6 +22,8 @@ class KX_GameObject: @type orientation: 3x3 Matrix [[float]] @ivar scaling: The object's scaling factor. list [sx, sy, sz] @type scaling: list [sx, sy, sz] + @ivar timeOffset: adjust the slowparent delay at runtime. + @type timeOffset: float """ def setVisible(visible): diff --git a/source/gameengine/SceneGraph/SG_Node.cpp b/source/gameengine/SceneGraph/SG_Node.cpp index ff9a9f7f371..4e90d7c4653 100644 --- a/source/gameengine/SceneGraph/SG_Node.cpp +++ b/source/gameengine/SceneGraph/SG_Node.cpp @@ -159,6 +159,17 @@ IsVertexParent() return false; } + bool +SG_Node:: +IsSlowParent() +{ + if (m_parent_relation) + { + return m_parent_relation->IsSlowRelation(); + } + return false; +} + void SG_Node:: DisconnectFromParent( diff --git a/source/gameengine/SceneGraph/SG_Node.h b/source/gameengine/SceneGraph/SG_Node.h index 5cf24de68f3..f86e3046d93 100644 --- a/source/gameengine/SceneGraph/SG_Node.h +++ b/source/gameengine/SceneGraph/SG_Node.h @@ -159,6 +159,14 @@ public: bool IsVertexParent( ) ; + + /** + * Return slow parent status. + */ + + bool + IsSlowParent( + ) ; /** * Update the spatial data of this node. Iterate through diff --git a/source/gameengine/SceneGraph/SG_ParentRelation.h b/source/gameengine/SceneGraph/SG_ParentRelation.h index 9d360d1c274..6507cb98519 100644 --- a/source/gameengine/SceneGraph/SG_ParentRelation.h +++ b/source/gameengine/SceneGraph/SG_ParentRelation.h @@ -99,6 +99,16 @@ public : ) { return false; } + + /** + * Need this to see if we are able to adjust time-offset from the python api + */ + virtual + bool + IsSlowRelation( + ) { + return false; + } protected : /** diff --git a/source/gameengine/SceneGraph/SG_Spatial.cpp b/source/gameengine/SceneGraph/SG_Spatial.cpp index 18049592977..5ba116e59db 100644 --- a/source/gameengine/SceneGraph/SG_Spatial.cpp +++ b/source/gameengine/SceneGraph/SG_Spatial.cpp @@ -87,6 +87,13 @@ SG_Spatial:: delete (m_parent_relation); } + SG_ParentRelation * +SG_Spatial:: +GetParentRelation( +){ + return m_parent_relation; +} + void SG_Spatial:: SetParentRelation( diff --git a/source/gameengine/SceneGraph/SG_Spatial.h b/source/gameengine/SceneGraph/SG_Spatial.h index a70784472a7..28848b0f933 100644 --- a/source/gameengine/SceneGraph/SG_Spatial.h +++ b/source/gameengine/SceneGraph/SG_Spatial.h @@ -83,6 +83,10 @@ public: SetParentRelation( SG_ParentRelation *relation ); + + SG_ParentRelation * + GetParentRelation( + ); /** From 13d081c62c6014e30db719e558b2ad3ea000fd0f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jean-Luc=20Peuri=C3=A8re?= Date: Sat, 14 Jun 2008 18:57:42 +0000 Subject: [PATCH 203/246] fix for ndof inconsistencies, bug #13954 patch provided by Ettore Pasquini --- intern/ghost/intern/GHOST_SystemX11.cpp | 8 ++-- source/blender/src/view.c | 60 +++++++++++++++---------- 2 files changed, 40 insertions(+), 28 deletions(-) diff --git a/intern/ghost/intern/GHOST_SystemX11.cpp b/intern/ghost/intern/GHOST_SystemX11.cpp index ff1bf51bbb5..3003e0b8b14 100644 --- a/intern/ghost/intern/GHOST_SystemX11.cpp +++ b/intern/ghost/intern/GHOST_SystemX11.cpp @@ -488,12 +488,12 @@ GHOST_SystemX11::processEvent(XEvent *xe) data.changed = 1; data.delta = xcme.data.s[8] - data.time; data.time = xcme.data.s[8]; - data.tx = xcme.data.s[2]; - data.ty = xcme.data.s[3]; - data.tz = xcme.data.s[4]; + data.tx = xcme.data.s[2] >> 2; + data.ty = xcme.data.s[3] >> 2; + data.tz = xcme.data.s[4] >> 2; data.rx = xcme.data.s[5]; data.ry = xcme.data.s[6]; - data.rz = xcme.data.s[7]; + data.rz =-xcme.data.s[7]; g_event = new GHOST_EventNDOF(getMilliSeconds(), GHOST_kEventNDOFMotion, window, data); diff --git a/source/blender/src/view.c b/source/blender/src/view.c index 008387d5a70..356a297b284 100644 --- a/source/blender/src/view.c +++ b/source/blender/src/view.c @@ -753,10 +753,11 @@ void viewmoveNDOFfly(int mode) // Apply rotation - - rvec[0] = -dval[3]; - rvec[1] = -dval[4]; - rvec[2] = dval[5]; + // Rotations feel relatively faster than translations only in fly mode, so + // we have no choice but to fix that here (not in the plugins) + rvec[0] = -0.5 * dval[3]; + rvec[1] = -0.5 * dval[4]; + rvec[2] = -0.5 * dval[5]; // rotate device x and y by view z @@ -824,8 +825,7 @@ void viewmove(int mode) return; } - // dist correction from other movement devices - + // dist correction from other movement devices if((dz_flag)||G.vd->dist==0) { dz_flag = 0; G.vd->dist = m_dist; @@ -1166,6 +1166,8 @@ void viewmoveNDOF(int mode) float reverse; float diff[4]; float d, curareaX, curareaY; + float mat[3][3]; + float upvec[3]; /* Sensitivity will control how fast the view rotates. The value was * obtained experimentally by tweaking until the author didn't get dizzy watching. @@ -1186,6 +1188,16 @@ void viewmoveNDOF(int mode) use_sel = 1; } + if((dz_flag)||G.vd->dist==0) { + dz_flag = 0; + G.vd->dist = m_dist; + upvec[0] = upvec[1] = 0; + upvec[2] = G.vd->dist; + Mat3CpyMat4(mat, G.vd->viewinv); + Mat3MulVecfl(mat, upvec); + VecAddf(G.vd->ofs, G.vd->ofs, upvec); + } + /*---------------------------------------------------- * sometimes this routine is called from headerbuttons * viewmove needs to refresh the screen @@ -1212,25 +1224,25 @@ void viewmoveNDOF(int mode) filterNDOFvalues(fval); - // put scaling back here, was previously in ghostwinlay - fval[0] = fval[0] * (1.0f/800.0f); - fval[1] = fval[1] * (1.0f/800.0f); - fval[2] = fval[2] * (1.0f/800.0f); - fval[3] = fval[3] * 0.00005f; - fval[4] = fval[4] * 0.00005f; - fval[5] = fval[5] * 0.00005f; - fval[6] = fval[6] / 1000000.0f; + // put scaling back here, was previously in ghostwinlay + fval[0] = fval[0] * (1.0f/1200.0f); + fval[1] = fval[1] * (1.0f/1200.0f); + fval[2] = fval[2] * (1.0f/1200.0f); + fval[3] = fval[3] * 0.00005f; + fval[4] =-fval[4] * 0.00005f; + fval[5] = fval[5] * 0.00005f; + fval[6] = fval[6] / 1000000.0f; - // scale more if not in perspective mode - if (G.vd->persp == V3D_ORTHO) { - fval[0] = fval[0] * 0.05f; - fval[1] = fval[1] * 0.05f; - fval[2] = fval[2] * 0.05f; - fval[3] = fval[3] * 0.9f; - fval[4] = fval[4] * 0.9f; - fval[5] = fval[5] * 0.9f; - zsens *= 8; - } + // scale more if not in perspective mode + if (G.vd->persp == V3D_ORTHO) { + fval[0] = fval[0] * 0.05f; + fval[1] = fval[1] * 0.05f; + fval[2] = fval[2] * 0.05f; + fval[3] = fval[3] * 0.9f; + fval[4] = fval[4] * 0.9f; + fval[5] = fval[5] * 0.9f; + zsens *= 8; + } /* set object offset */ From 89c1875bc9a761b52f2f2041203bfcf3ef34030e Mon Sep 17 00:00:00 2001 From: Benoit Bolsee Date: Sat, 14 Jun 2008 20:42:15 +0000 Subject: [PATCH 204/246] BGE patch: support Set Scene in BGE. Linked Set Scene should have no name conflict in Object, Object data and Action of the main scene to avoid confusion in Python scripting. Nested Set Scene are supported. You will need Python scripting to create cross references between objects in the main scene and the Set (e.g TrackTo actuator) --- source/blender/blenkernel/BKE_scene.h | 2 +- .../Converter/BL_BlenderDataConversion.cpp | 15 ++++++++++----- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/source/blender/blenkernel/BKE_scene.h b/source/blender/blenkernel/BKE_scene.h index c50f5498de9..2bd528ab8c8 100644 --- a/source/blender/blenkernel/BKE_scene.h +++ b/source/blender/blenkernel/BKE_scene.h @@ -53,7 +53,7 @@ struct RenderData; } /* note; doesn't work when scene is empty */ -#define SETLOOPER(s, b) sce= s, b= sce->base.first; b; b= (b->next?b->next:sce->set?(sce=sce->set)->base.first:NULL) +#define SETLOOPER(s, b) sce= s, b= (Base*)sce->base.first; b; b= (Base*)(b->next?b->next:sce->set?(sce=sce->set)->base.first:NULL) void free_avicodecdata(struct AviCodecData *acd); diff --git a/source/gameengine/Converter/BL_BlenderDataConversion.cpp b/source/gameengine/Converter/BL_BlenderDataConversion.cpp index 82d16ffa181..5a9cda67941 100644 --- a/source/gameengine/Converter/BL_BlenderDataConversion.cpp +++ b/source/gameengine/Converter/BL_BlenderDataConversion.cpp @@ -88,6 +88,7 @@ #include "BKE_main.h" #include "BKE_global.h" #include "BKE_object.h" +#include "BKE_scene.h" #include "BL_SkinMeshObject.h" #include "BL_SkinDeformer.h" #include "BL_MeshDeformer.h" @@ -1808,6 +1809,9 @@ void BL_ConvertBlenderObjects(struct Main* maggie, { Scene *blenderscene = GetSceneForName(maggie, scenename); + // for SETLOOPER + Scene *sce; + Base *base; // Get the frame settings of the canvas. // Get the aspect ratio of the canvas as designed by the user. @@ -1881,9 +1885,11 @@ void BL_ConvertBlenderObjects(struct Main* maggie, } SetDefaultFaceType(blenderscene); - - Base *base = static_cast(blenderscene->base.first); - while(base) + // Let's support scene set. + // Beware of name conflict in linked data, it will not crash but will create confusion + // in Python scripting and in certain actuators (replace mesh). Linked scene *should* have + // no conflicting name for Object, Object data and Action. + for (SETLOOPER(blenderscene, base)) { Object* blenderobject = base->object; KX_GameObject* gameobj = gameobject_from_blenderobject( @@ -2038,7 +2044,6 @@ void BL_ConvertBlenderObjects(struct Main* maggie, if (gameobj) gameobj->Release(); - base = base->next; } if (blenderscene->camera) { @@ -2048,7 +2053,7 @@ void BL_ConvertBlenderObjects(struct Main* maggie, } // Set up armatures - for (base = static_cast(blenderscene->base.first); base; base=base->next){ + for(SETLOOPER(blenderscene, base)){ if (base->object->type==OB_MESH){ Mesh *me = (Mesh*)base->object->data; From c76bce9e6407aa9adda3bd1b1d66fe3b8d88299f Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 15 Jun 2008 08:56:11 +0000 Subject: [PATCH 205/246] bugfix, simple crash in drawaction --- source/blender/src/drawaction.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/src/drawaction.c b/source/blender/src/drawaction.c index 65221dceaf9..8c4958a651a 100644 --- a/source/blender/src/drawaction.c +++ b/source/blender/src/drawaction.c @@ -730,7 +730,7 @@ void check_action_context(SpaceAction *saction) for (achan=saction->action->chanbase.first; achan; achan=achan->next) { pchan= get_pose_channel(ob->pose, achan->name); - if (pchan) { + if (pchan && pchan->bone) { if ((pchan->bone->layer & arm->layer)==0) achan->flag |= ACHAN_HIDDEN; else if (pchan->bone->flag & BONE_HIDDEN_P) From f63b70635c91062a8ef71b2a1f82ac8d4bb06372 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 15 Jun 2008 09:43:24 +0000 Subject: [PATCH 206/246] bugfix, clip alpha wasn't working in the GE, not happy with these functions, they probably need bigger changes not to assume all alpha requires face sorting with a disabled depth buffer, --- source/gameengine/Converter/BL_BlenderDataConversion.cpp | 6 +++--- source/gameengine/Ketsji/KX_BlenderMaterial.cpp | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/source/gameengine/Converter/BL_BlenderDataConversion.cpp b/source/gameengine/Converter/BL_BlenderDataConversion.cpp index 5a9cda67941..cb981f55c5a 100644 --- a/source/gameengine/Converter/BL_BlenderDataConversion.cpp +++ b/source/gameengine/Converter/BL_BlenderDataConversion.cpp @@ -542,7 +542,7 @@ BL_Material* ConvertMaterial( material->amb = mat->amb; // set alpha testing without z-sorting - if( ( validface && (!tface->transp)) && mat->mode & MA_ZTRA) { + if( ( validface && (!(tface->transp &~ TF_CLIP))) && mat->mode & MA_ZTRA) { // sets the RAS_IPolyMaterial::m_flag |RAS_FORCEALPHA // this is so we don't have the overhead of the z-sorting code material->ras_mode|=ALPHA_TEST; @@ -598,7 +598,7 @@ BL_Material* ConvertMaterial( material->ras_mode |= ( (tface->mode & TF_DYNAMIC)!= 0 )?COLLIDER:0; material->transp = tface->transp; - if(tface->transp) + if(tface->transp&~TF_CLIP) material->ras_mode |= TRANSP; material->tile = tface->tile; @@ -947,7 +947,7 @@ RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, RAS_IRenderTools* // Use texface colors if available //TF_DYNAMIC means the polygon is a collision face collider = ((tface->mode & TF_DYNAMIC) != 0); - transp = tface->transp; + transp = tface->transp &~ TF_CLIP; tile = tface->tile; mode = tface->mode; diff --git a/source/gameengine/Ketsji/KX_BlenderMaterial.cpp b/source/gameengine/Ketsji/KX_BlenderMaterial.cpp index 5efe1ad26ca..cc978760da7 100644 --- a/source/gameengine/Ketsji/KX_BlenderMaterial.cpp +++ b/source/gameengine/Ketsji/KX_BlenderMaterial.cpp @@ -493,7 +493,7 @@ bool KX_BlenderMaterial::setDefaultBlending() glDisable(GL_BLEND); glEnable ( GL_ALPHA_TEST ); glAlphaFunc(GL_GREATER, 0.5f); - return true; + return false; } return false; } From a54edca11970f942d9335eb057cff18cfa96e2c7 Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Sun, 15 Jun 2008 10:19:38 +0000 Subject: [PATCH 207/246] Whitespace commit in armature.c --- source/blender/blenkernel/intern/armature.c | 61 ++++++++++----------- 1 file changed, 30 insertions(+), 31 deletions(-) diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c index eca10e5b079..fb7d59c137a 100644 --- a/source/blender/blenkernel/intern/armature.c +++ b/source/blender/blenkernel/intern/armature.c @@ -1709,13 +1709,13 @@ static void execute_posetree(Object *ob, PoseTree *tree) if (tree->totchannel == 0) return; - + iktree= MEM_mallocN(sizeof(void*)*tree->totchannel, "ik tree"); for(a=0; atotchannel; a++) { pchan= tree->pchan[a]; bone= pchan->bone; - + /* set DoF flag */ flag= 0; if(!(pchan->ikflag & BONE_IK_NO_XDOF) && !(pchan->ikflag & BONE_IK_NO_XDOF_TEMP)) @@ -1724,32 +1724,32 @@ static void execute_posetree(Object *ob, PoseTree *tree) flag |= IK_YDOF; if(!(pchan->ikflag & BONE_IK_NO_ZDOF) && !(pchan->ikflag & BONE_IK_NO_ZDOF_TEMP)) flag |= IK_ZDOF; - + if(tree->stretch && (pchan->ikstretch > 0.0)) { flag |= IK_TRANS_YDOF; hasstretch = 1; } - + seg= iktree[a]= IK_CreateSegment(flag); - + /* find parent */ if(a == 0) parent= NULL; else parent= iktree[tree->parent[a]]; - + IK_SetParent(seg, parent); - + /* get the matrix that transforms from prevbone into this bone */ Mat3CpyMat4(R_bonemat, pchan->pose_mat); - + /* gather transformations for this IK segment */ - + if (pchan->parent) Mat3CpyMat4(R_parmat, pchan->parent->pose_mat); else Mat3One(R_parmat); - + /* bone offset */ if (pchan->parent && (a > 0)) VecSubf(start, pchan->pose_head, pchan->parent->pose_tail); @@ -1759,37 +1759,37 @@ static void execute_posetree(Object *ob, PoseTree *tree) /* change length based on bone size */ length= bone->length*VecLength(R_bonemat[1]); - + /* compute rest basis and its inverse */ Mat3CpyMat3(rest_basis, bone->bone_mat); Mat3CpyMat3(irest_basis, bone->bone_mat); Mat3Transp(irest_basis); - + /* compute basis with rest_basis removed */ Mat3Inv(iR_parmat, R_parmat); Mat3MulMat3(full_basis, iR_parmat, R_bonemat); Mat3MulMat3(basis, irest_basis, full_basis); - + /* basis must be pure rotation */ Mat3Ortho(basis); - + /* transform offset into local bone space */ Mat3Ortho(iR_parmat); Mat3MulVecfl(iR_parmat, start); - + IK_SetTransform(seg, start, rest_basis, basis, length); - + if (pchan->ikflag & BONE_IK_XLIMIT) IK_SetLimit(seg, IK_X, pchan->limitmin[0], pchan->limitmax[0]); if (pchan->ikflag & BONE_IK_YLIMIT) IK_SetLimit(seg, IK_Y, pchan->limitmin[1], pchan->limitmax[1]); if (pchan->ikflag & BONE_IK_ZLIMIT) IK_SetLimit(seg, IK_Z, pchan->limitmin[2], pchan->limitmax[2]); - + IK_SetStiffness(seg, IK_X, pchan->stiffness[0]); IK_SetStiffness(seg, IK_Y, pchan->stiffness[1]); IK_SetStiffness(seg, IK_Z, pchan->stiffness[2]); - + if(tree->stretch && (pchan->ikstretch > 0.0)) { float ikstretch = pchan->ikstretch*pchan->ikstretch; IK_SetStiffness(seg, IK_TRANS_Y, MIN2(1.0-ikstretch, 0.99)); @@ -1818,7 +1818,7 @@ static void execute_posetree(Object *ob, PoseTree *tree) for (target=tree->targets.first; target; target=target->next) { float polepos[3]; int poleconstrain= 0; - + data= (bKinematicConstraint*)target->con->data; /* 1.0=ctime, we pass on object for auto-ik (owner-type here is object, even though @@ -1835,7 +1835,7 @@ static void execute_posetree(Object *ob, PoseTree *tree) /* same for pole vector target */ if(data->poletar) { get_constraint_target_matrix(target->con, 1, CONSTRAINT_OBTYPE_OBJECT, ob, rootmat, 1.0); - + if(data->flag & CONSTRAINT_IK_SETANGLE) { /* don't solve IK when we are setting the pole angle */ break; @@ -1844,7 +1844,7 @@ static void execute_posetree(Object *ob, PoseTree *tree) Mat4MulMat4(goal, rootmat, goalinv); VECCOPY(polepos, goal[3]); poleconstrain= 1; - + if(data->flag & CONSTRAINT_IK_GETANGLE) { poleangledata= data; data->flag &= ~CONSTRAINT_IK_GETANGLE; @@ -1903,36 +1903,35 @@ static void execute_posetree(Object *ob, PoseTree *tree) tree->basis_change= MEM_mallocN(sizeof(float[3][3])*tree->totchannel, "ik basis change"); if(hasstretch) ikstretch= MEM_mallocN(sizeof(float)*tree->totchannel, "ik stretch"); - + for(a=0; atotchannel; a++) { IK_GetBasisChange(iktree[a], tree->basis_change[a]); - + if(hasstretch) { /* have to compensate for scaling received from parent */ float parentstretch, stretch; - + pchan= tree->pchan[a]; parentstretch= (tree->parent[a] >= 0)? ikstretch[tree->parent[a]]: 1.0; - + if(tree->stretch && (pchan->ikstretch > 0.0)) { float trans[3], length; - + IK_GetTranslationChange(iktree[a], trans); length= pchan->bone->length*VecLength(pchan->pose_mat[1]); - + ikstretch[a]= (length == 0.0)? 1.0: (trans[1]+length)/length; } else ikstretch[a] = 1.0; - + stretch= (parentstretch == 0.0)? 1.0: ikstretch[a]/parentstretch; - + VecMulf(tree->basis_change[a][0], stretch); VecMulf(tree->basis_change[a][1], stretch); VecMulf(tree->basis_change[a][2], stretch); - } - + IK_FreeSegment(iktree[a]); } From eb9c4de83f8153fe028935ad83eadba467c499a0 Mon Sep 17 00:00:00 2001 From: Martin Poirier Date: Sun, 15 Jun 2008 14:22:12 +0000 Subject: [PATCH 208/246] Patch [#13668] Tool tip correction By Olivier Saraja --- source/blender/src/buttons_editing.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/src/buttons_editing.c b/source/blender/src/buttons_editing.c index 5d477b7ab09..caa1f2195e2 100644 --- a/source/blender/src/buttons_editing.c +++ b/source/blender/src/buttons_editing.c @@ -2403,7 +2403,7 @@ static void draw_modifier(uiBlock *block, Object *ob, ModifierData *md, int *xco but= uiDefBut(block, BUT, B_MODIFIER_RECALC, "Bind", lx,(cy-=24), buttonWidth,19, 0, 0, 0, 0, 0, "Bind mesh to cage"); uiButSetFunc(but,modifiers_bindMeshDeform,ob,md); uiDefButS(block, NUM, B_NOP, "Precision:", lx,(cy-19), buttonWidth/2 + 20,19, &mmd->gridsize, 2, 10, 0.5, 0, "The grid size for binding"); - uiDefButBitS(block, TOG, MOD_MDEF_DYNAMIC_BIND, B_MODIFIER_RECALC, "Dynamic", lx+(buttonWidth+1)/2 + 20, (cy-=19), buttonWidth/2 - 20,19, &mmd->flag, 0.0, 31.0, 0, 0, "Invert vertex group influence"); + uiDefButBitS(block, TOG, MOD_MDEF_DYNAMIC_BIND, B_MODIFIER_RECALC, "Dynamic", lx+(buttonWidth+1)/2 + 20, (cy-=19), buttonWidth/2 - 20,19, &mmd->flag, 0.0, 31.0, 0, 0, "Recompute binding dynamically on top of other deformers like Shape Keys (slower and more memory consuming!)"); } uiBlockEndAlign(block); } else if (md->type==eModifierType_ParticleSystem) { From ad023e108a59331a454a8c4fb2cea99500b49528 Mon Sep 17 00:00:00 2001 From: Martin Poirier Date: Sun, 15 Jun 2008 17:54:42 +0000 Subject: [PATCH 209/246] =?UTF-8?q?[#13691]=20apricot=20Snap=20didn?= =?UTF-8?q?=E2=80=99t=20work=20correct=20in=20svn?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. Updated selected restriction to not be so stingy. Snapping on edges and vertices work if they are part of a partially moving face 2. Change depth ordering (which didn't work all the time). Hits are sorted according to 2D distance and then depth, so for overlapping hits, it picks the one in front. --- source/blender/src/transform_snap.c | 147 ++++++++++++++++------------ 1 file changed, 85 insertions(+), 62 deletions(-) diff --git a/source/blender/src/transform_snap.c b/source/blender/src/transform_snap.c index 83940fa3729..3a1017915f9 100644 --- a/source/blender/src/transform_snap.c +++ b/source/blender/src/transform_snap.c @@ -739,9 +739,10 @@ void TargetSnapClosest(TransInfo *t) /* find snapping point on face, return 1 on success */ -int snapFace(MFace *face, MVert *verts, float *intersect, float *loc, float *no) +int snapFace(MFace *face, EditFace *efa, MVert *verts, float *intersect, float *loc, float *no) { MVert *v[4]; + EditVert *eve[4]; int totvert; int result = 0; @@ -760,6 +761,14 @@ int snapFace(MFace *face, MVert *verts, float *intersect, float *loc, float *no) totvert = 3; } + if (efa) + { + eve[0] = efa->v1; + eve[1] = efa->v2; + eve[2] = efa->v3; + eve[3] = efa->v4; + } + switch(G.scene->snap_mode) { case SCE_SNAP_MODE_VERTEX: @@ -769,16 +778,20 @@ int snapFace(MFace *face, MVert *verts, float *intersect, float *loc, float *no) for(i = 0; i < totvert; i++) { - float vert_dist = VecLenf(v[i]->co, intersect); - if (vert_dist < min_dist) + if (efa == NULL || (eve[i]->f1 & SELECT) == 0) { - result = 1; + float vert_dist = VecLenf(v[i]->co, intersect); - min_dist = vert_dist; - - VECCOPY(loc, v[i]->co); - NormalShortToFloat(no, v[i]->no); + if (vert_dist < min_dist) + { + result = 1; + + min_dist = vert_dist; + + VECCOPY(loc, v[i]->co); + NormalShortToFloat(no, v[i]->no); + } } } break; @@ -791,51 +804,62 @@ int snapFace(MFace *face, MVert *verts, float *intersect, float *loc, float *no) for(i = 0; i < totvert; i++) { MVert *v1, *v2; - float edge_loc[3]; - float vec[3]; - float mul; - float edge_dist; + EditVert *eve1, *eve2; v1 = v[i]; v2 = v[(i + 1) % totvert]; - VecSubf(edge_loc, v2->co, v1->co); - VecSubf(vec, intersect, v1->co); + eve1 = eve[i]; + eve2 = eve[(i + 1) % totvert]; - mul = Inpf(vec, edge_loc) / Inpf(edge_loc, edge_loc); - - VecMulf(edge_loc, mul); - VecAddf(edge_loc, edge_loc, v1->co); - - edge_dist = VecLenf(edge_loc, intersect); - - if (edge_dist < min_dist) + if (efa == NULL || ((eve1->f1 & SELECT) == 0 && (eve2->f1 & SELECT) == 0)) { - float n1[3], n2[3]; - result = 1; + float edge_loc[3]; + float vec[3]; + float mul; + float edge_dist; - min_dist = edge_dist; - - VECCOPY(loc, edge_loc); + VecSubf(edge_loc, v2->co, v1->co); + VecSubf(vec, intersect, v1->co); - NormalShortToFloat(n1, v1->no); - NormalShortToFloat(n2, v2->no); - VecLerpf(no, n1, n2, mul); - Normalize(no); + mul = Inpf(vec, edge_loc) / Inpf(edge_loc, edge_loc); + + VecMulf(edge_loc, mul); + VecAddf(edge_loc, edge_loc, v1->co); + + edge_dist = VecLenf(edge_loc, intersect); + + if (edge_dist < min_dist) + { + float n1[3], n2[3]; + result = 1; + + min_dist = edge_dist; + + VECCOPY(loc, edge_loc); + + NormalShortToFloat(n1, v1->no); + NormalShortToFloat(n2, v2->no); + VecLerpf(no, n1, n2, mul); + Normalize(no); + } } } break; } case SCE_SNAP_MODE_FACE: { - result = 1; - - VECCOPY(loc, intersect); - - if (totvert == 4) - CalcNormFloat4(v[0]->co, v[1]->co, v[2]->co, v[3]->co, no); - else - CalcNormFloat(v[0]->co, v[1]->co, v[2]->co, no); + if (efa == NULL || ((efa->f1 & SELECT) == 0)) + { + result = 1; + + VECCOPY(loc, intersect); + + if (totvert == 4) + CalcNormFloat4(v[0]->co, v[1]->co, v[2]->co, v[3]->co, no); + else + CalcNormFloat(v[0]->co, v[1]->co, v[2]->co, no); + } break; } } @@ -845,7 +869,6 @@ int snapFace(MFace *face, MVert *verts, float *intersect, float *loc, float *no) int snapDerivedMesh(Object *ob, DerivedMesh *dm, float obmat[][4], float ray_start[3], float ray_normal[3], short mval[2], float *loc, float *no, int *dist, float *depth, short EditMesh) { - float object_depth = FLT_MAX; int retval = 0; int totvert = dm->getNumVerts(dm); int totface = dm->getNumFaces(dm); @@ -883,8 +906,6 @@ int snapDerivedMesh(Object *ob, DerivedMesh *dm, float obmat[][4], float ray_sta int index = 0; int i; - test = 1; - if (EditMesh) { index_array = dm->getFaceDataArray(dm, CD_ORIGINDEX); @@ -892,14 +913,15 @@ int snapDerivedMesh(Object *ob, DerivedMesh *dm, float obmat[][4], float ray_sta } for( i = 0; i < totface; i++) { + EditFace *efa = NULL; MFace *f = faces + i; float lambda; int result; + test = 1; /* reset for every face */ + if (EditMesh) { - EditFace *efa = NULL; - if (index_array) { index = index_array[i]; @@ -917,12 +939,9 @@ int snapDerivedMesh(Object *ob, DerivedMesh *dm, float obmat[][4], float ray_sta { efa = EM_get_face_for_index(index); - if (efa) + if (efa && efa->f1 & SELECT) { - if (efa->v1->f1 & SELECT || efa->v2->f1 & SELECT || efa->v3->f1 & SELECT || (efa->v4 && efa->v4->f1 & SELECT)) - { - test = 0; - } + test = 0; } } } @@ -932,7 +951,7 @@ int snapDerivedMesh(Object *ob, DerivedMesh *dm, float obmat[][4], float ray_sta { result = RayIntersectsTriangle(ray_start_local, ray_normal_local, verts[f->v1].co, verts[f->v2].co, verts[f->v3].co, &lambda, NULL); - if (result && lambda < object_depth) { + if (result) { float location[3], normal[3]; float intersect[3]; @@ -940,18 +959,21 @@ int snapDerivedMesh(Object *ob, DerivedMesh *dm, float obmat[][4], float ray_sta VecMulf(intersect, lambda); VecAddf(intersect, intersect, ray_start_local); - if (snapFace(f, verts, intersect, location, normal)) + if (snapFace(f, efa, verts, intersect, location, normal)) { float new_depth; int screen_loc[2]; + int new_dist; Mat4MulVecfl(obmat, location); new_depth = VecLenf(location, ray_start); - if (new_depth < *depth) + project_int(location, screen_loc); + new_dist = abs(screen_loc[0] - mval[0]) + abs(screen_loc[1] - mval[1]); + + if (new_dist <= *dist && new_depth < *depth) { - object_depth = lambda; *depth = new_depth; retval = 1; @@ -963,7 +985,7 @@ int snapDerivedMesh(Object *ob, DerivedMesh *dm, float obmat[][4], float ray_sta project_int(loc, screen_loc); - *dist = abs(screen_loc[0] - mval[0]) + abs(screen_loc[1] - mval[1]); + *dist = new_dist; } } } @@ -972,7 +994,7 @@ int snapDerivedMesh(Object *ob, DerivedMesh *dm, float obmat[][4], float ray_sta { result = RayIntersectsTriangle(ray_start_local, ray_normal_local, verts[f->v3].co, verts[f->v4].co, verts[f->v1].co, &lambda, NULL); - if (result && lambda < object_depth) { + if (result) { float location[3], normal[3]; float intersect[3]; @@ -980,18 +1002,21 @@ int snapDerivedMesh(Object *ob, DerivedMesh *dm, float obmat[][4], float ray_sta VecMulf(intersect, lambda); VecAddf(intersect, intersect, ray_start_local); - if (snapFace(f, verts, intersect, location, normal)) + if (snapFace(f, efa, verts, intersect, location, normal)) { float new_depth; int screen_loc[2]; + int new_dist; Mat4MulVecfl(obmat, location); - new_depth = VecLenf(location, ray_start); + new_depth = VecLenf(location, ray_start); - if (new_depth < *depth) + project_int(location, screen_loc); + new_dist = abs(screen_loc[0] - mval[0]) + abs(screen_loc[1] - mval[1]); + + if (new_dist <= *dist && new_depth < *depth) { - object_depth = lambda; *depth = new_depth; retval = 1; @@ -1001,9 +1026,7 @@ int snapDerivedMesh(Object *ob, DerivedMesh *dm, float obmat[][4], float ray_sta Mat3MulVecfl(timat, no); Normalize(no); - project_int(loc, screen_loc); - - *dist = abs(screen_loc[0] - mval[0]) + abs(screen_loc[1] - mval[1]); + *dist = new_dist; } } } From f445dfbfb6113c0465491a5e1c275e81b602cc58 Mon Sep 17 00:00:00 2001 From: Diego Borghetti Date: Mon, 16 Jun 2008 07:15:09 +0000 Subject: [PATCH 210/246] Patch [#13777] This commit fix the following problem in the DPX code: 1) The code always assume a depth of 10 bits 2) The code don't check the file type (Log or Linear) --- source/blender/imbuf/intern/cineon/dpxlib.c | 45 ++++++++++++++++++--- 1 file changed, 40 insertions(+), 5 deletions(-) diff --git a/source/blender/imbuf/intern/cineon/dpxlib.c b/source/blender/imbuf/intern/cineon/dpxlib.c index a81e632a797..500c09ba265 100644 --- a/source/blender/imbuf/intern/cineon/dpxlib.c +++ b/source/blender/imbuf/intern/cineon/dpxlib.c @@ -441,10 +441,15 @@ intern_dpxOpen(int mode, const char* bytestuff, int bufsize) { default: break; } } - dpx->bitsPerPixel = 10; - /* dpx->bitsPerPixel = header.imageInfo.channel[0].bits_per_pixel; */ - dpx->imageOffset = ntohl(header.fileInfo.offset); + /* dpx->bitsPerPixel = 10; */ + dpx->bitsPerPixel = header.imageInfo.channel[0].bits_per_pixel; + if (dpx->bitsPerPixel != 10) { + if (verbose) d_printf("Don't support depth: %d\n", dpx->bitsPerPixel); + dpxClose(dpx); + return 0; + } + dpx->imageOffset = ntohl(header.fileInfo.offset); dpx->lineBufferLength = pixelsToLongs(dpx->width * dpx->depth); dpx->lineBuffer = malloc(dpx->lineBufferLength * 4); if (dpx->lineBuffer == 0) { @@ -471,6 +476,26 @@ intern_dpxOpen(int mode, const char* bytestuff, int bufsize) { dpx->fileYPos = 0; logImageGetByteConversionDefaults(&dpx->params); + /* The SMPTE define this code: + * 2 - Linear + * 3 - Logarithmic + * + * Note that transfer_characteristics is U8, don't need + * check the byte order. + */ + switch (header.imageInfo.channel[0].transfer_characteristics) { + case 2: + dpx->params.doLogarithm= 0; + break; + case 3: + dpx->params.doLogarithm= 1; + break; + default: + if (verbose) d_printf("Un-supported Transfer Characteristics: %d\n", header.imageInfo.channel[0].transfer_characteristics); + dpxClose(dpx); + return 0; + break; + } setupLut(dpx); dpx->getRow = &dpxGetRowBytes; @@ -563,6 +588,18 @@ dpxCreate(const char* filename, int width, int height, int depth) { ++shortFilename; } initDpxMainHeader(dpx, &header, shortFilename); + logImageGetByteConversionDefaults(&dpx->params); + /* Need set the file type before write the header! + * 2 - Linear + * 3 - Logarithmic + * + * Note that transfer characteristics is U8, don't need + * check the byte order. + */ + if (dpx->params.doLogarithm == 0) + header.imageInfo.channel[0].transfer_characteristics= 2; + else + header.imageInfo.channel[0].transfer_characteristics= 3; if (fwrite(&header, sizeof(header), 1, dpx->file) == 0) { if (verbose) d_printf("Couldn't write image header\n"); @@ -570,8 +607,6 @@ dpxCreate(const char* filename, int width, int height, int depth) { return 0; } dpx->fileYPos = 0; - - logImageGetByteConversionDefaults(&dpx->params); setupLut(dpx); dpx->getRow = 0; From 9b69c569178e118e1e2486f167164673a4201be0 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 16 Jun 2008 09:16:04 +0000 Subject: [PATCH 211/246] Material color was always overriding OBCOL for blender text. --- source/gameengine/BlenderRoutines/KX_BlenderGL.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/source/gameengine/BlenderRoutines/KX_BlenderGL.cpp b/source/gameengine/BlenderRoutines/KX_BlenderGL.cpp index 7c9dbcdaab2..2a5cc14018f 100644 --- a/source/gameengine/BlenderRoutines/KX_BlenderGL.cpp +++ b/source/gameengine/BlenderRoutines/KX_BlenderGL.cpp @@ -133,7 +133,12 @@ void BL_RenderText(int mode,const char* textstr,int textlen,struct MTFace* tface characters = 0; } - if(!col) glColor3f(1.0f, 1.0f, 1.0f); + /* When OBCOL flag is on the color is set in IndexPrimitives_3DText */ + if (tface->mode & TF_OBCOL) { /* Color has been set */ + col= NULL; + } else { + if(!col) glColor3f(1.0f, 1.0f, 1.0f); + } glPushMatrix(); for (index = 0; index < characters; index++) { From 1e3bdcf19846974b11c5a497eea56a34cdec0dde Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 16 Jun 2008 14:08:24 +0000 Subject: [PATCH 212/246] bugfix from Markus Ilmola (glome) patch was in [#8540] Import scripts for MilkShape3D file formats Some animations were incorrectly imported and this adds support for weights. --- release/scripts/ms3d_import.py | 132 +++++++++++++++++++++++++++++---- 1 file changed, 119 insertions(+), 13 deletions(-) diff --git a/release/scripts/ms3d_import.py b/release/scripts/ms3d_import.py index 78ffbb92847..c1438cbfc97 100644 --- a/release/scripts/ms3d_import.py +++ b/release/scripts/ms3d_import.py @@ -50,7 +50,7 @@ def RM(a): cp = cos(a[1]) sr = sin(a[0]) cr = cos(a[0]) - return Matrix([cp*cy, sr*sp*cy+cr*-sy, cr*sp*cy+-sr*-sy],[cp*sy, sr*sp*sy+cr*cy, cr*sp*sy+-sr*cy], [-sp, sr*cp, cr*cp]) + return Matrix([cp*cy, cp*sy, -sp], [sr*sp*cy+cr*-sy, sr*sp*sy+cr*cy, sr*cp],[cr*sp*cy+-sr*-sy, cr*sp*sy+-sr*cy, cr*cp]) # Converts ms3d euler angles to a quaternion @@ -94,7 +94,12 @@ def import_ms3d(path): except IOError: return "Failed to open the file!" - # read id + # get the file size + file.seek(0, os.SEEK_END); + fileSize = file.tell(); + file.seek(0, os.SEEK_SET); + + # read id to check if the file is a MilkShape3D file id = file.read(10) if id!="MS3D000000": return "The file is not a MS3D file!" @@ -123,7 +128,7 @@ def import_ms3d(path): coords.append(struct.unpack("fff", file.read(3*4))) # read bone ids - boneIds.append(struct.unpack("B", file.read(1))[0]) + boneIds.append(struct.unpack("b", file.read(1))[0]) # skip refcount file.read(1) @@ -190,9 +195,10 @@ def import_ms3d(path): triangleIndices = struct.unpack(str(numGroupTriangles) + "H", file.read(2*numGroupTriangles)); # read material - material = struct.unpack("B", file.read(1))[0] - for j in xrange(numGroupTriangles): - mesh.faces[triangleIndices[j]].mat = material + material = struct.unpack("b", file.read(1))[0] + if material>=0: + for j in xrange(numGroupTriangles): + mesh.faces[triangleIndices[j]].mat = material # read the number of materials numMaterials = struct.unpack("H", file.read(2))[0] @@ -224,7 +230,6 @@ def import_ms3d(path): # read shininess shininess = struct.unpack("f", file.read(4))[0] - print "Shininess: " + str(shininess) # read transparency transparency = struct.unpack("f", file.read(4))[0] @@ -272,6 +277,7 @@ def import_ms3d(path): armature.makeEditable() # read joints + joints = [] rotKeys = {} posKeys = {} for i in xrange(numJoints): @@ -280,6 +286,7 @@ def import_ms3d(path): # read name name = uku(file.read(32)) + joints.append(name) # create the bone bone = Blender.Armature.Editbone() @@ -295,11 +302,13 @@ def import_ms3d(path): # read position pos = struct.unpack("fff", file.read(3*4)) - + # set head if bone.hasParent(): - bone.head = bone.parent.matrix * Vector(pos) + bone.parent.head - bone.matrix = bone.parent.matrix * RM(rot) + bone.head = Vector(pos) * bone.parent.matrix + bone.parent.head + tempM = RM(rot) * bone.parent.matrix + tempM.transpose; + bone.matrix = tempM else: bone.head = Vector(pos) bone.matrix = RM(rot) @@ -355,13 +364,111 @@ def import_ms3d(path): # create position keys for key in posKeys[name]: pbone.loc = Vector(key[1]) - pbone.insertKey(armOb, int(key[0]), Blender.Object.Pose.LOC, True) + pbone.insertKey(armOb, int(key[0]+0.5), Blender.Object.Pose.LOC, True) # create rotation keys for key in rotKeys[name]: pbone.quat = RQ(key[1]) - pbone.insertKey(armOb, int(key[0]), Blender.Object.Pose.ROT, True) + pbone.insertKey(armOb, int(key[0]+0.5), Blender.Object.Pose.ROT, True) + + # The old format ends here. If there is more data then the file is newer version + + # check to see if there are any comments + if file.tell()0: + print "Group comment: " + file.read(size) + + # Material comments + numComments = struct.unpack("i", file.read(4))[0] + for i in range(numComments): + file.read(4) # index + size = struct.unpack("i", file.read(4))[0] # comment size + if size>0: + print "Material comment: " + file.read(size) + + # Joint comments + numComments = struct.unpack("i", file.read(4))[0] + for i in range(numComments): + file.read(4) # index + size = struct.unpack("i", file.read(4))[0] # comment size + if size>0: + print "Joint comment: " + file.read(size) + + # Model comments + numComments = struct.unpack("i", file.read(4))[0] + for i in range(numComments): + file.read(4) # index + size = struct.unpack("i", file.read(4))[0] # comment size + if size>0: + print "Model comment: " + file.read(size) + + # Unknown version give a warning + else: + print "Warning: Unknown version!" + + + # check to see if there is any extra vertex data + if file.tell()=0 or ids[1]>=0 or ids[2]>=0: + mesh.assignVertsToGroup(joints[boneIds[i]], [i], 0.01*weights[0], 1) + if ids[0]>=0: + mesh.assignVertsToGroup(joints[ids[0]], [i], 0.01*weights[1], 1) + if ids[1]>=0: + mesh.assignVertsToGroup(joints[ids[1]], [i], 0.01*weights[2], 1) + if ids[2]>=0: + mesh.assignVertsToGroup(joints[ids[2]], [i], 0.01*(100-(weights[0]+weights[1]+weights[2])), 1) + + elif subVersion==1: + # read extra data for each vertex + for i in xrange(numVertices): + # bone ids + ids = struct.unpack("bbb", file.read(3)) + # weights + weights = struct.unpack("BBB", file.read(3)) + # add extra vertices with weights to deform groups + if ids[0]>=0 or ids[1]>=0 or ids[2]>=0: + mesh.assignVertsToGroup(joints[boneIds[i]], [i], 0.01*weights[0], 1) + if ids[0]>=0: + mesh.assignVertsToGroup(joints[ids[0]], [i], 0.01*weights[1], 1) + if ids[1]>=0: + mesh.assignVertsToGroup(joints[ids[1]], [i], 0.01*weights[2], 1) + if ids[2]>=0: + mesh.assignVertsToGroup(joints[ids[2]], [i], 0.01*(100-(weights[0]+weights[1]+weights[2])), 1) + + # non supported subversion give a warning + else: + print "Warning: Unknown subversion!" + # rest of the extra data in the file is not imported/used + + # refresh the view Blender.Redraw() # close the file @@ -378,4 +485,3 @@ def fileCallback(filename): Blender.Draw.PupMenu("An error occured during import: " + error + "|Not all data might have been imported succesfully.", 2) Blender.Window.FileSelector(fileCallback, 'Import') - From bb539ce1b5171fb2b34379655071054905c802cf Mon Sep 17 00:00:00 2001 From: Martin Poirier Date: Mon, 16 Jun 2008 16:48:09 +0000 Subject: [PATCH 213/246] Snapping Snap to cage only in edit mode (respect the edit cage flag of modifiers). Especially important for subsurf, otherwise, Andy's automerge + snap video doesn't work in current SVN. --- source/blender/src/transform_snap.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/source/blender/src/transform_snap.c b/source/blender/src/transform_snap.c index 3a1017915f9..405b512bb5d 100644 --- a/source/blender/src/transform_snap.c +++ b/source/blender/src/transform_snap.c @@ -1056,14 +1056,13 @@ int snapObjects(int *dist, float *loc, float *no, int mode) { if (mode == NOT_ACTIVE) { - DerivedMesh *dm, *dm_cage; + DerivedMesh *dm; Object *ob = G.obedit; - dm_cage = editmesh_get_derived_cage_and_final(&dm, CD_MASK_BAREMESH); + dm = editmesh_get_derived_cage(CD_MASK_BAREMESH); retval = snapDerivedMesh(ob, dm, ob->obmat, ray_start, ray_normal, mval, loc, no, dist, &depth, 1); - dm_cage->release(dm_cage); dm->release(dm); } From 6be46f9ee3c29da2022e14bf812a5dac172453cb Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 16 Jun 2008 19:54:43 +0000 Subject: [PATCH 214/246] [#11456] New datablock type(s) added to Oops Schematic patch from Shawn Zilbert (enigmatic) This patch adds the camera data block type to the oops schematic view of the outliner. It also includes a little bit of code cleanup in the oops files. --- source/blender/include/BIF_oops.h | 8 ++ source/blender/makesdna/DNA_space_types.h | 1 + source/blender/src/drawoops.c | 9 ++ source/blender/src/header_oops.c | 4 +- source/blender/src/oops.c | 114 ++++++++++++++++++---- 5 files changed, 117 insertions(+), 19 deletions(-) diff --git a/source/blender/include/BIF_oops.h b/source/blender/include/BIF_oops.h index f6984a23f47..adeac4f3871 100644 --- a/source/blender/include/BIF_oops.h +++ b/source/blender/include/BIF_oops.h @@ -39,6 +39,10 @@ struct Mesh; struct MetaBall; struct Object; struct Lamp; +struct Camera; +struct Texture; +struct Lattice; +struct bArmature; void add_curve_oopslinks(struct Curve *cu, struct Oops *oops, short flag); void add_from_link(struct Oops *from, struct Oops *oops); void add_material_oopslinks(struct Material *ma, struct Oops *oops, short flag); @@ -46,6 +50,9 @@ void add_mball_oopslinks(struct MetaBall *mb, struct Oops *oops, short flag); void add_mesh_oopslinks(struct Mesh *me, struct Oops *oops, short flag); void add_object_oopslinks(struct Object *ob, struct Oops *oops, short flag); void add_lamp_oopslinks(struct Lamp *la, struct Oops *oops, short flag); +void add_camera_oopslinks(struct Camera *ca, struct Oops *oops, short flag); +void add_texture_oopslinks(struct Tex *tex, struct Oops *oops, short flag); +void add_lattice_oopslinks(struct Lattice *lt, struct Oops *oops, short flag); struct Oops *add_oops(void *id); struct OopsLink *add_oopslink(char *name, struct Oops *oops, short type, void *from, float xof, float yof); struct Oops *add_test_oops(void *id); /* incl links */ @@ -66,3 +73,4 @@ void test_oopslinko(struct OopsLink *ol); #endif + diff --git a/source/blender/makesdna/DNA_space_types.h b/source/blender/makesdna/DNA_space_types.h index 619dfbb43a0..af60f9ca713 100644 --- a/source/blender/makesdna/DNA_space_types.h +++ b/source/blender/makesdna/DNA_space_types.h @@ -559,6 +559,7 @@ typedef struct SpaceImaSel { #define OOPS_IM 4096 #define OOPS_AR 8192 #define OOPS_GR 16384 +#define OOPS_CA 32768 /* SpaceOops->outlinevis */ #define SO_ALL_SCENES 0 diff --git a/source/blender/src/drawoops.c b/source/blender/src/drawoops.c index 5da38135be3..75bea40a8b4 100644 --- a/source/blender/src/drawoops.c +++ b/source/blender/src/drawoops.c @@ -229,6 +229,8 @@ void draw_icon_oops(float *co, short type) case ID_LI: icon= ICON_LIBRARY_HLT; break; case ID_IM: icon= ICON_IMAGE_HLT; break; case ID_GR: icon= ICON_CIRCLE_DEHLT; break; + case ID_CA: icon= ICON_CAMERA_DEHLT; break; + case ID_AR: icon= ICON_ARMATURE; break; } glEnable(GL_BLEND); @@ -282,6 +284,12 @@ unsigned int give_oops_color(short type, short sel, unsigned int *border) body= 0x35659F; break; case ID_GR: body= 0x507050; break; + case ID_CA: + body= 0x7570A0; break; + case ID_LT: + body= 0xA08090; break; + case ID_AR: + body= 0x70B0C0; break; default: body= 0x606070; break; } @@ -516,3 +524,4 @@ void drawoopsspace(ScrArea *sa, void *spacedata) + diff --git a/source/blender/src/header_oops.c b/source/blender/src/header_oops.c index 7bfbf0ee667..ad65705b79d 100644 --- a/source/blender/src/header_oops.c +++ b/source/blender/src/header_oops.c @@ -509,8 +509,9 @@ void oops_buttons(void) uiDefIconButBitS(block, TOG, OOPS_IM, B_NEWOOPS, ICON_IMAGE_HLT, (short)(xco+=XIC),0,XIC,YIC, &soops->visiflag, 0, 0, 0, 0, "Displays Image datablocks"); uiDefIconButBitS(block, TOG, OOPS_GR, B_NEWOOPS, ICON_CIRCLE_DEHLT, (short)(xco+=XIC),0,XIC,YIC, &soops->visiflag, 0, 0, 0, 0, "Displays Group datablocks"); uiDefIconButBitS(block, TOG, OOPS_LI, B_NEWOOPS, ICON_LIBRARY_HLT, (short)(xco+=XIC),0,XIC,YIC, &soops->visiflag, 0, 0, 0, 0, "Displays Library datablocks"); + uiDefIconButBitS(block, TOG, OOPS_CA, B_NEWOOPS, ICON_CAMERA_DEHLT, (short)(xco+=XIC),0,XIC,YIC, &soops->visiflag, 0, 0, 0, 0, "Displays Camera datablocks"); + uiDefIconButBitS(block, TOG, OOPS_AR, B_NEWOOPS, ICON_ARMATURE, (short)(xco+=XIC),0,XIC,YIC, &soops->visiflag, 0, 0, 0, 0, "Displays Armature datablocks"); - uiBlockEndAlign(block); /* name */ @@ -576,3 +577,4 @@ void oops_buttons(void) uiDrawBlock(block); } + diff --git a/source/blender/src/oops.c b/source/blender/src/oops.c index 1f851d2fa6c..99645b5e71f 100644 --- a/source/blender/src/oops.c +++ b/source/blender/src/oops.c @@ -48,6 +48,9 @@ #include "DNA_texture_types.h" #include "DNA_key_types.h" #include "DNA_group_types.h" +#include "DNA_camera_types.h" +#include "DNA_lattice_types.h" +#include "DNA_armature_types.h" #include "BKE_utildefines.h" #include "BKE_global.h" @@ -661,7 +664,6 @@ void add_material_oopslinks(Material *ma, Oops *oops, short flag) add_oopslink("group", oops, ID_GR, &(ma->group), OOPSX, (float)(0.5*OOPSY)); } - void add_group_oopslinks(Group *gp, Oops *oops, short flag) { GroupObject *gob; @@ -672,7 +674,6 @@ void add_group_oopslinks(Group *gp, Oops *oops, short flag) } } - void add_object_oopslinks(Object *ob, Oops *oops, short flag) { ID *id; @@ -698,6 +699,12 @@ void add_object_oopslinks(Object *ob, Oops *oops, short flag) case ID_LA: if(flag & OOPS_LA) add_oopslink("data", oops, ID_LA, &ob->data, (float)(.5*OOPSX), (float)OOPSY); break; + case ID_CA: + if(flag & OOPS_CA) add_oopslink("data", oops, ID_CA, &ob->data, (float)(.5*OOPSX), (float)OOPSY); + break; + case ID_AR: + if(flag & OOPS_AR) add_oopslink("data", oops, ID_AR, &ob->data, (float)(.5*OOPSX), (float)OOPSY); + break; } } @@ -748,7 +755,6 @@ void add_curve_oopslinks(Curve *cu, Oops *oops, short flag) add_oopslink("speed", oops, ID_IP, &cu->ipo, OOPSX, (float)(0.5*OOPSY)); if(cu->key) add_oopslink("ipo", oops, ID_IP, &cu->key->ipo, OOPSX, (float)(0.5*OOPSY)); } - } void add_mball_oopslinks(MetaBall *mb, Oops *oops, short flag) @@ -775,15 +781,36 @@ void add_lamp_oopslinks(Lamp *la, Oops *oops, short flag) } } } + if(flag & OOPS_IP) { + add_oopslink("ipo", oops, ID_IP, &la->ipo, OOPSX, (float)(0.5*OOPSY)); + } } +void add_camera_oopslinks(Camera *ca, Oops *oops, short flag) +{ + if(flag & OOPS_IP) { + add_oopslink("ipo", oops, ID_IP, &ca->ipo, OOPSX, (float)(0.5*OOPSY)); + } +} + +void add_texture_oopslinks(Tex *tex, Oops *oops, short flag) +{ + if(flag & OOPS_IM) { + add_oopslink("image", oops, ID_IM, &tex->ima, OOPSX, (float)(0.5*OOPSY)); + } +} + +void add_lattice_oopslinks(Lattice *lt, Oops *oops, short flag) +{ + if(flag & OOPS_IP) { + if(lt->key) add_oopslink("ipo", oops, ID_IP, <->key->ipo, OOPSX, (float)(0.5*OOPSY)); + } +} Oops *add_test_oops(void *id) /* incl links */ { Oops *oops; Object *ob; - Lamp *la; - Tex *tex; if(id==0) return NULL; @@ -821,9 +848,10 @@ Oops *add_test_oops(void *id) /* incl links */ add_mball_oopslinks((MetaBall *)id, oops, G.soops->visiflag); break; case ID_LA: - la= (Lamp *)id; - add_lamp_oopslinks(la, oops, G.soops->visiflag); - if(la->ipo) if(G.soops->visiflag & OOPS_IP) add_oopslink("ipo", oops, ID_IP, &la->ipo, OOPSX, (float)(0.3*OOPSY)); + add_lamp_oopslinks((Lamp *)id, oops, G.soops->visiflag); + break; + case ID_CA: + add_camera_oopslinks((Camera *)id, oops, G.soops->visiflag); break; case ID_IP: @@ -835,8 +863,14 @@ Oops *add_test_oops(void *id) /* incl links */ add_group_oopslinks((Group *)id, oops, G.soops->visiflag); break; case ID_TE: - tex= (Tex *)id; - if(tex->ima) if(G.soops->visiflag & OOPS_IM) add_oopslink("image", oops, ID_IM, &tex->ima, OOPSX, (float)(0.3*OOPSY)); + add_texture_oopslinks((Tex *)id, oops, G.soops->visiflag); + break; + case ID_LT: + add_lattice_oopslinks((Lattice *)id, oops, G.soops->visiflag); + break; + case ID_AR: + + break; } return oops; @@ -897,7 +931,7 @@ void build_oops() while(sce) { oops= add_test_oops(sce); - + if(G.soops->visiflag & OOPS_OB) { base= sce->base.first; while(base) { @@ -912,12 +946,13 @@ void build_oops() if(G.soops->visiflag & OOPS_OB) { Object *ob= G.main->object.first; - + while(ob) { oops= add_test_oops(ob); ob= ob->id.next; } } + if(G.soops->visiflag & OOPS_ME) { Mesh *me= G.main->mesh.first; while(me) { @@ -925,7 +960,7 @@ void build_oops() me= me->id.next; } } - + if(G.soops->visiflag & OOPS_CU) { Curve *cu= G.main->curve.first; while(cu) { @@ -933,7 +968,7 @@ void build_oops() cu= cu->id.next; } } - + if(G.soops->visiflag & OOPS_MB) { MetaBall *mb= G.main->mball.first; while(mb) { @@ -941,7 +976,7 @@ void build_oops() mb= mb->id.next; } } - + if(G.soops->visiflag & OOPS_LA) { Lamp *la= G.main->lamp.first; while(la) { @@ -950,6 +985,14 @@ void build_oops() } } + if(G.soops->visiflag & OOPS_CA) { + Camera *ca= G.main->camera.first; + while(ca) { + oops= add_test_oops(ca); + ca= ca->id.next; + } + } + if(G.soops->visiflag & OOPS_IP) { Ipo *ipo= G.main->ipo.first; while(ipo) { @@ -972,6 +1015,7 @@ void build_oops() tex= tex->id.next; } } + if(G.soops->visiflag & OOPS_IM) { Image *ima= G.main->image.first; while(ima) { @@ -979,6 +1023,7 @@ void build_oops() ima= ima->id.next; } } + if(G.soops->visiflag & OOPS_GR) { Group *gp= G.main->group.first; while(gp) { @@ -986,6 +1031,23 @@ void build_oops() gp= gp->id.next; } } + + if(G.soops->visiflag & OOPS_LT) { + Lattice *lt= G.main->latt.first; + while(lt) { + oops= add_test_oops(lt); + lt= lt->id.next; + } + } + + if(G.soops->visiflag & OOPS_AR) { + bArmature *ar= G.main->armature.first; + while(ar) { + oops= add_test_oops(ar); + ar= ar->id.next; + } + } + } else { @@ -1068,6 +1130,7 @@ void build_oops() else if(type==ID_LA && G.soops->visiflag & OOPS_LA) { Lamp *la= ob->data; oops= add_test_oops(ob->data); + if(G.soops->visiflag & OOPS_IP) add_test_oops(la->ipo); if(G.soops->visiflag & OOPS_TE) { for(a=0; avisiflag & OOPS_CA) { + Camera *ca= ob->data; + oops= add_test_oops(ob->data); + + if(G.soops->visiflag & OOPS_IP) add_test_oops(ca->ipo); + } + else if(type==ID_LT && G.soops->visiflag & OOPS_LT) { + Lattice *lt= ob->data; + oops= add_test_oops(ob->data); + + if(G.soops->visiflag & OOPS_IP) { + if(lt->key) oops= add_test_oops(lt->key->ipo); + } + } + else if(type==ID_AR && G.soops->visiflag & OOPS_AR) { + bArmature *ar= ob->data; + oops= add_test_oops(ob->data); + } } } base= base->next; } } - - - /* test links */ oops= G.soops->oops.first; From 4c391a0c30018917f6173d1200efcb93c02211f5 Mon Sep 17 00:00:00 2001 From: Matt Ebb Date: Tue, 17 Jun 2008 04:18:34 +0000 Subject: [PATCH 215/246] * Simple addition to math node (comp and shading): Greater Than and Less Than modes. --- .../blender/nodes/intern/CMP_nodes/CMP_math.c | 18 +++++++++++++++++- .../blender/nodes/intern/SHD_nodes/SHD_math.c | 18 +++++++++++++++++- source/blender/src/drawnode.c | 2 +- 3 files changed, 35 insertions(+), 3 deletions(-) diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_math.c b/source/blender/nodes/intern/CMP_nodes/CMP_math.c index e317998b5fc..d00ce18a44f 100644 --- a/source/blender/nodes/intern/CMP_nodes/CMP_math.c +++ b/source/blender/nodes/intern/CMP_nodes/CMP_math.c @@ -131,7 +131,23 @@ static void do_math(bNode *node, float *out, float *in, float *in2) { out[0]= (int)(in[0] + 0.5f); } - break; + break; + case 15: /* Less Than */ + { + if( in[0] < in2[0] ) + out[0]= 1.0f; + else + out[0]= 0.0f; + } + break; + case 16: /* Greater Than */ + { + if( in[0] > in2[0] ) + out[0]= 1.0f; + else + out[0]= 0.0f; + } + break; } } diff --git a/source/blender/nodes/intern/SHD_nodes/SHD_math.c b/source/blender/nodes/intern/SHD_nodes/SHD_math.c index 95162e508d5..2e156cf12bf 100644 --- a/source/blender/nodes/intern/SHD_nodes/SHD_math.c +++ b/source/blender/nodes/intern/SHD_nodes/SHD_math.c @@ -174,7 +174,23 @@ bNodeStack **out) else out[0]->vec[0]= (int)(in[1]->vec[0] + 0.5f); } - break; + break; + case 15: /* Less Than */ + { + if( in[0]->vec[0] < in[1]->vec[0] ) + out[0]->vec[0]= 1.0f; + else + out[0]->vec[0]= 0.0f; + } + break; + case 16: /* Greater Than */ + { + if( in[0]->vec[0] > in[1]->vec[0] ) + out[0]->vec[0]= 1.0f; + else + out[0]->vec[0]= 0.0f; + } + break; } } diff --git a/source/blender/src/drawnode.c b/source/blender/src/drawnode.c index cea33685744..1169062fdd0 100644 --- a/source/blender/src/drawnode.c +++ b/source/blender/src/drawnode.c @@ -517,7 +517,7 @@ static int node_buts_math(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *b if(block) { uiBut *bt; - bt=uiDefButS(block, MENU, B_NODE_EXEC, "Add %x0|Subtract %x1|Multiply %x2|Divide %x3|Sine %x4|Cosine %x5|Tangent %x6|Arcsine %x7|Arccosine %x8|Arctangent %x9|Power %x10|Logarithm %x11|Minimum %x12|Maximum %x13|Round %x14", butr->xmin, butr->ymin, butr->xmax-butr->xmin, 20, &node->custom1, 0, 0, 0, 0, ""); + bt=uiDefButS(block, MENU, B_NODE_EXEC, "Add %x0|Subtract %x1|Multiply %x2|Divide %x3|Sine %x4|Cosine %x5|Tangent %x6|Arcsine %x7|Arccosine %x8|Arctangent %x9|Power %x10|Logarithm %x11|Minimum %x12|Maximum %x13|Round %x14|Less Than %x15|Greater Than %x16", butr->xmin, butr->ymin, butr->xmax-butr->xmin, 20, &node->custom1, 0, 0, 0, 0, ""); uiButSetFunc(bt, node_but_title_cb, node, bt); } return 20; From c9d1924ea5575ae2a4ce2cc7fd16e63e6ef14d84 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 17 Jun 2008 10:06:38 +0000 Subject: [PATCH 216/246] Use the scenes framerate for ipo and action framerate in the game engine, was hard coded to 25. --- .../BlenderRoutines/BL_KetsjiEmbedStart.cpp | 6 ++++++ source/gameengine/Converter/BL_ActionActuator.cpp | 8 ++++---- source/gameengine/Ketsji/KX_GameObject.h | 3 +-- source/gameengine/Ketsji/KX_IpoActuator.cpp | 6 +++--- source/gameengine/Ketsji/KX_KetsjiEngine.cpp | 13 ++++++++++++- source/gameengine/Ketsji/KX_KetsjiEngine.h | 10 ++++++++++ 6 files changed, 36 insertions(+), 10 deletions(-) diff --git a/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp b/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp index fa8409b123e..eb575c70ad7 100644 --- a/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp +++ b/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp @@ -372,6 +372,12 @@ extern "C" void StartKetsjiShell(struct ScrArea *area, // start the engine ketsjiengine->StartEngine(true); + + // Set the animation playback rate for ipo's and actions + // the framerate below should patch with FPS macro defined in blendef.h + // Could be in StartEngine set the framerate, we need the scene to do this + ketsjiengine->SetAnimFrameRate( (((double) blscene->r.frs_sec) / blscene->r.frs_sec_base) ); + // the mainloop while (!exitrequested) { diff --git a/source/gameengine/Converter/BL_ActionActuator.cpp b/source/gameengine/Converter/BL_ActionActuator.cpp index 1055c8771ef..ad126ebf123 100644 --- a/source/gameengine/Converter/BL_ActionActuator.cpp +++ b/source/gameengine/Converter/BL_ActionActuator.cpp @@ -134,14 +134,14 @@ void BL_ActionActuator::SetStartTime(float curtime) float direction = m_startframe < m_endframe ? 1.0 : -1.0; if (!(m_flag & ACT_FLAG_REVERSE)) - m_starttime = curtime - direction*(m_localtime - m_startframe)/KX_FIXED_FRAME_PER_SEC; + m_starttime = curtime - direction*(m_localtime - m_startframe)/KX_KetsjiEngine::GetAnimFrameRate(); else - m_starttime = curtime - direction*(m_endframe - m_localtime)/KX_FIXED_FRAME_PER_SEC; + m_starttime = curtime - direction*(m_endframe - m_localtime)/KX_KetsjiEngine::GetAnimFrameRate(); } void BL_ActionActuator::SetLocalTime(float curtime) { - float delta_time = (curtime - m_starttime)*KX_FIXED_FRAME_PER_SEC; + float delta_time = (curtime - m_starttime)*KX_KetsjiEngine::GetAnimFrameRate(); if (m_endframe < m_startframe) delta_time = -delta_time; @@ -385,7 +385,7 @@ bool BL_ActionActuator::Update(double curtime, bool frame) blend_poses(m_pose, m_blendpose, 1.0 - newweight, ACTSTRIPMODE_BLEND); /* Increment current blending percentage */ - m_blendframe = (curtime - m_blendstart)*KX_FIXED_FRAME_PER_SEC; + m_blendframe = (curtime - m_blendstart)*KX_KetsjiEngine::GetAnimFrameRate(); if (m_blendframe>m_blendin) m_blendframe = m_blendin; diff --git a/source/gameengine/Ketsji/KX_GameObject.h b/source/gameengine/Ketsji/KX_GameObject.h index 56b9f3f6375..8a90ec1463a 100644 --- a/source/gameengine/Ketsji/KX_GameObject.h +++ b/source/gameengine/Ketsji/KX_GameObject.h @@ -45,9 +45,8 @@ #include "GEN_Map.h" #include "GEN_HashedPtr.h" #include "KX_Scene.h" +#include "KX_KetsjiEngine.h" /* for m_anim_framerate */ -#define KX_FIXED_FRAME_PER_SEC 25.0f -#define KX_FIXED_SEC_PER_FRAME (1.0f / KX_FIXED_FRAME_PER_SEC) #define KX_OB_DYNAMIC 1 diff --git a/source/gameengine/Ketsji/KX_IpoActuator.cpp b/source/gameengine/Ketsji/KX_IpoActuator.cpp index 0f9caa456d9..cf246342cf9 100644 --- a/source/gameengine/Ketsji/KX_IpoActuator.cpp +++ b/source/gameengine/Ketsji/KX_IpoActuator.cpp @@ -164,14 +164,14 @@ void KX_IpoActuator::SetStartTime(float curtime) curtime = curtime - KX_KetsjiEngine::GetSuspendedDelta(); if (m_direction > 0) - m_starttime = curtime - direction*(m_localtime - m_startframe)/KX_FIXED_FRAME_PER_SEC; + m_starttime = curtime - direction*(m_localtime - m_startframe)/KX_KetsjiEngine::GetAnimFrameRate(); else - m_starttime = curtime - direction*(m_endframe - m_localtime)/KX_FIXED_FRAME_PER_SEC; + m_starttime = curtime - direction*(m_endframe - m_localtime)/KX_KetsjiEngine::GetAnimFrameRate(); } void KX_IpoActuator::SetLocalTime(float curtime) { - float delta_time = ((curtime - m_starttime) - KX_KetsjiEngine::GetSuspendedDelta())*KX_FIXED_FRAME_PER_SEC; + float delta_time = ((curtime - m_starttime) - KX_KetsjiEngine::GetSuspendedDelta())*KX_KetsjiEngine::GetAnimFrameRate(); // negative delta_time is caused by floating point inaccuracy // perhaps the inaccuracy could be reduced a bit diff --git a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp index 1e3393d59a8..56a06786679 100644 --- a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp +++ b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp @@ -71,6 +71,7 @@ #include "KX_TimeCategoryLogger.h" #include "RAS_FramingManager.h" +#include "stdio.h" // If define: little test for Nzc: guarded drawing. If the canvas is // not valid, skip rendering this frame. @@ -91,7 +92,7 @@ const char KX_KetsjiEngine::m_profileLabels[tc_numCategories][15] = { }; double KX_KetsjiEngine::m_ticrate = DEFAULT_LOGIC_TIC_RATE; - +double KX_KetsjiEngine::m_anim_framerate = 25.0; double KX_KetsjiEngine::m_suspendedtime = 0.0; double KX_KetsjiEngine::m_suspendeddelta = 0.0; @@ -1383,6 +1384,16 @@ void KX_KetsjiEngine::SetTicRate(double ticrate) m_ticrate = ticrate; } +double KX_KetsjiEngine::GetAnimFrameRate() +{ + return m_anim_framerate; +} + +void KX_KetsjiEngine::SetAnimFrameRate(double framerate) +{ + m_anim_framerate = framerate; +} + void KX_KetsjiEngine::SetTimingDisplay(bool frameRate, bool profile, bool properties) { m_show_framerate = frameRate; diff --git a/source/gameengine/Ketsji/KX_KetsjiEngine.h b/source/gameengine/Ketsji/KX_KetsjiEngine.h index bc2e3864be8..4c09bc3fcd5 100644 --- a/source/gameengine/Ketsji/KX_KetsjiEngine.h +++ b/source/gameengine/Ketsji/KX_KetsjiEngine.h @@ -103,6 +103,7 @@ private: double m_remainingTime; static double m_ticrate; + static double m_anim_framerate; /* for animation playback only - ipo and action */ static double m_suspendedtime; static double m_suspendeddelta; @@ -260,6 +261,15 @@ public: */ static void SetTicRate(double ticrate); + /** + * Gets the framerate for playing animations. (actions and ipos) + */ + static double GetAnimFrameRate(); + /** + * Sets the framerate for playing animations. (actions and ipos) + */ + static void SetAnimFrameRate(double framerate); + /** * Activates or deactivates timing information display. * @param frameRate Display for frame rate on or off. From 272a91f754fd215f2ad9b48ba80fe56ee0564d7a Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Tue, 17 Jun 2008 10:27:34 +0000 Subject: [PATCH 217/246] Merge of apricot branch game engine changes into trunk, excluding GLSL. GLEW ==== Added the GLEW opengl extension library into extern/, always compiled into Blender now. This is much nicer than doing this kind of extension management manually, and will be used in the game engine, for GLSL, and other opengl extensions. * According to the GLEW website it works on Windows, Linux, Mac OS X, FreeBSD, Irix, and Solaris. There might still be platform specific issues due to this commit, so let me know and I'll look into it. * This means also that all extensions will now always be compiled in, regardless of the glext.h on the platform where compilation happens. Game Engine =========== Refactoring of the use of opengl extensions and other drawing code in the game engine, and cleaning up some hacks related to GLSL integration. These changes will be merged into trunk too after this. The game engine graphics demos & apricot level survived my tests, but this could use some good testing of course. For users: please test with the options "Generate Display Lists" and "Vertex Arrays" enabled, these should be the fastest and are supposed to be "unreliable", but if that's the case that's probably due to bugs that can be fixed. * The game engine now also uses GLEW for extensions, replacing the custom opengl extensions code that was there. Removes a lot of #ifdef's, but the runtime checks stay of course. * Removed the WITHOUT_GLEXT environment variable. This was added to work around a specific bug and only disabled multitexturing anyway. It might also have caused a slowdown since it was retrieving the environment variable for every vertex in immediate mode (bug #13680). * Refactored the code to allow drawing skinned meshes with vertex arrays too, removing some specific immediate mode drawing functions for this that only did extra normal calculation. Now it always splits vertices of flat faces instead. * Refactored normal recalculation with some minor optimizations, required for the above change. * Removed some outdated code behind the __NLA_OLDDEFORM #ifdef. * Fixed various bugs in setting of multitexture coordinates and vertex attributes for vertex arrays. These were not being enabled/disabled correct according to the opengl spec, leading to crashes. Also tangent attributes used an immediate mode call for vertex arrays, which can't work. * Fixed use of uninitialized variable in RAS_TexVert. * Exporting skinned meshes was doing O(n^2) lookups for vertices and deform weights, now uses same trick as regular meshes. --- blenderplayer/CMakeLists.txt | 1 + extern/CMakeLists.txt | 3 + extern/Makefile | 2 +- extern/SConscript | 2 + extern/glew/CMakeLists.txt | 33 + extern/glew/README.txt | 18 + extern/glew/SConscript | 12 + extern/glew/include/GL/glew.h | 9797 +++++++++++++++++ extern/glew/include/GL/glxew.h | 1062 ++ extern/glew/include/GL/wglew.h | 934 ++ extern/glew/src/Makefile | 56 + extern/glew/src/glew.c | 9756 ++++++++++++++++ source/Makefile | 1 + source/blender/src/CMakeLists.txt | 2 +- source/blender/src/Makefile | 1 + source/blender/src/SConscript | 2 +- source/blender/src/usiblender.c | 1 + source/creator/CMakeLists.txt | 1 + .../BlenderRoutines/BL_KetsjiEmbedStart.cpp | 44 +- .../gameengine/BlenderRoutines/CMakeLists.txt | 1 + .../BlenderRoutines/KX_BlenderCanvas.h | 8 +- .../BlenderRoutines/KX_BlenderGL.cpp | 52 +- .../BlenderRoutines/KX_BlenderRenderTools.cpp | 13 +- source/gameengine/BlenderRoutines/Makefile | 3 +- source/gameengine/BlenderRoutines/SConscript | 1 + .../BlenderRoutines/mac_compat_glext.h | 132 - .../Converter/BL_ArmatureObject.cpp | 2 +- .../Converter/BL_BlenderDataConversion.cpp | 33 +- .../gameengine/Converter/BL_MeshDeformer.cpp | 160 +- source/gameengine/Converter/BL_MeshDeformer.h | 7 +- .../gameengine/Converter/BL_SkinDeformer.cpp | 43 +- source/gameengine/Converter/BL_SkinDeformer.h | 4 +- .../Converter/BL_SkinMeshObject.cpp | 24 +- .../gameengine/Converter/BL_SkinMeshObject.h | 43 +- .../Converter/KX_BlenderSceneConverter.cpp | 14 +- .../Converter/KX_BlenderSceneConverter.h | 5 + .../GamePlayer/common/CMakeLists.txt | 1 + .../gameengine/GamePlayer/common/GPC_Canvas.h | 18 +- .../GamePlayer/common/GPC_PolygonMaterial.cpp | 19 +- .../GamePlayer/common/GPC_RenderTools.cpp | 14 +- .../GamePlayer/common/GPC_RenderTools.h | 15 +- source/gameengine/GamePlayer/common/Makefile | 1 + .../gameengine/GamePlayer/common/SConscript | 3 +- .../GamePlayer/ghost/CMakeLists.txt | 1 + .../GamePlayer/ghost/GPG_Application.cpp | 43 +- .../GamePlayer/ghost/GPG_Application.h | 1 + source/gameengine/GamePlayer/ghost/Makefile | 1 + source/gameengine/GamePlayer/ghost/SConscript | 3 +- source/gameengine/Ketsji/BL_BlenderShader.cpp | 149 + source/gameengine/Ketsji/BL_BlenderShader.h | 44 + source/gameengine/Ketsji/BL_Material.cpp | 1 + source/gameengine/Ketsji/BL_Material.h | 3 +- source/gameengine/Ketsji/BL_Shader.cpp | 306 +- source/gameengine/Ketsji/BL_Texture.cpp | 161 +- source/gameengine/Ketsji/CMakeLists.txt | 1 + .../gameengine/Ketsji/KX_BlenderMaterial.cpp | 309 +- source/gameengine/Ketsji/KX_BlenderMaterial.h | 13 +- source/gameengine/Ketsji/KX_GameObject.cpp | 4 +- source/gameengine/Ketsji/KX_ISceneConverter.h | 3 + source/gameengine/Ketsji/KX_PythonInit.cpp | 70 +- source/gameengine/Ketsji/Makefile | 1 + source/gameengine/Ketsji/SConscript | 2 +- source/gameengine/Rasterizer/CMakeLists.txt | 1 + source/gameengine/Rasterizer/Makefile | 1 + .../Rasterizer/RAS_2DFilterManager.cpp | 63 +- source/gameengine/Rasterizer/RAS_CameraData.h | 4 +- .../Rasterizer/RAS_IPolygonMaterial.cpp | 6 - .../Rasterizer/RAS_IPolygonMaterial.h | 2 - .../gameengine/Rasterizer/RAS_IRasterizer.h | 29 +- .../Rasterizer/RAS_MaterialBucket.cpp | 39 +- .../gameengine/Rasterizer/RAS_MeshObject.cpp | 27 +- source/gameengine/Rasterizer/RAS_MeshObject.h | 1 + .../RAS_OpenGLRasterizer/ARB_multitexture.h | 150 - .../RAS_OpenGLRasterizer/CMakeLists.txt | 1 + .../EXT_separate_specular_color.h | 12 - .../Rasterizer/RAS_OpenGLRasterizer/Makefile | 1 + .../RAS_GLExtensionManager.cpp | 674 +- .../RAS_GLExtensionManager.h | 507 +- .../RAS_ListRasterizer.cpp | 19 +- .../RAS_OpenGLRasterizer.cpp | 1071 +- .../RAS_OpenGLRasterizer.h | 37 +- .../RAS_VAOpenGLRasterizer.cpp | 302 +- .../RAS_VAOpenGLRasterizer.h | 7 +- .../RAS_OpenGLRasterizer/SConscript | 6 +- .../RAS_OpenGLRasterizer/mkglext.py | 627 -- source/gameengine/Rasterizer/SConscript | 2 +- source/nan_definitions.mk | 1 + 87 files changed, 23076 insertions(+), 3974 deletions(-) create mode 100644 extern/glew/CMakeLists.txt create mode 100644 extern/glew/README.txt create mode 100644 extern/glew/SConscript create mode 100644 extern/glew/include/GL/glew.h create mode 100644 extern/glew/include/GL/glxew.h create mode 100644 extern/glew/include/GL/wglew.h create mode 100644 extern/glew/src/Makefile create mode 100644 extern/glew/src/glew.c delete mode 100644 source/gameengine/BlenderRoutines/mac_compat_glext.h create mode 100644 source/gameengine/Ketsji/BL_BlenderShader.cpp create mode 100644 source/gameengine/Ketsji/BL_BlenderShader.h delete mode 100644 source/gameengine/Rasterizer/RAS_OpenGLRasterizer/ARB_multitexture.h delete mode 100644 source/gameengine/Rasterizer/RAS_OpenGLRasterizer/EXT_separate_specular_color.h delete mode 100644 source/gameengine/Rasterizer/RAS_OpenGLRasterizer/mkglext.py diff --git a/blenderplayer/CMakeLists.txt b/blenderplayer/CMakeLists.txt index 62b64ff04bb..d90639562d2 100644 --- a/blenderplayer/CMakeLists.txt +++ b/blenderplayer/CMakeLists.txt @@ -108,6 +108,7 @@ IF(UNIX) blenkernel_blc bf_quicktime extern_binreloc + extern_glew ) FOREACH(SORTLIB ${BLENDER_SORTED_LIBS}) diff --git a/extern/CMakeLists.txt b/extern/CMakeLists.txt index d092e0d494d..ee5cab31e09 100644 --- a/extern/CMakeLists.txt +++ b/extern/CMakeLists.txt @@ -43,3 +43,6 @@ ENDIF(WITH_VERSE) IF(CMAKE_SYSTEM_NAME MATCHES "Linux") SUBDIRS(binreloc) ENDIF(CMAKE_SYSTEM_NAME MATCHES "Linux") + +SUBDIRS(glew) + diff --git a/extern/Makefile b/extern/Makefile index fd4573cc8b1..26ee25b608f 100644 --- a/extern/Makefile +++ b/extern/Makefile @@ -30,7 +30,7 @@ include nan_definitions.mk SOURCEDIR = extern DIR = $(OCGDIR)/extern -DIRS = qhull/src solid +DIRS = qhull/src solid glew/src ifeq ($(WITH_FREETYPE2), true) DIRS += bFTGL/src diff --git a/extern/SConscript b/extern/SConscript index c94b6573eb9..6612d38f4cf 100644 --- a/extern/SConscript +++ b/extern/SConscript @@ -2,6 +2,8 @@ Import('env') +SConscript(['glew/SConscript']) + if env['WITH_BF_GAMEENGINE']: SConscript(['qhull/SConscript', 'solid/SConscript']) diff --git a/extern/glew/CMakeLists.txt b/extern/glew/CMakeLists.txt new file mode 100644 index 00000000000..53ef014927c --- /dev/null +++ b/extern/glew/CMakeLists.txt @@ -0,0 +1,33 @@ +# $Id$ +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# The Original Code is Copyright (C) 2006, Blender Foundation +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): Jacques Beaurain. +# +# ***** END GPL LICENSE BLOCK ***** + +SET(INC include src) + +SET(SRC + src/glew.c +) + +BLENDERLIB(extern_glew "${SRC}" "${INC}") diff --git a/extern/glew/README.txt b/extern/glew/README.txt new file mode 100644 index 00000000000..1b19c53523f --- /dev/null +++ b/extern/glew/README.txt @@ -0,0 +1,18 @@ +See doc/index.html for more information. + +If you downloaded the tarball from the GLEW website, you just need to: + + Unix: + + make + + Windows: + + use the project file in build/vc6/ + +If you wish to build GLEW from scratch (update the extension data from +the net or add your own extension information), you need a Unix +environment (including wget, perl, and GNU make). The extension data +is regenerated from the top level source directory with: + + make extensions diff --git a/extern/glew/SConscript b/extern/glew/SConscript new file mode 100644 index 00000000000..32b3b478113 --- /dev/null +++ b/extern/glew/SConscript @@ -0,0 +1,12 @@ +#!/usr/bin/python +import sys +import os + +Import('env') + +sources = ['src/glew.c'] + +defs = '' +incs = 'include' + +env.BlenderLib ( 'extern_glew', sources, Split(incs), Split(defs), libtype=['intern', 'player'], priority=[25, 50]) diff --git a/extern/glew/include/GL/glew.h b/extern/glew/include/GL/glew.h new file mode 100644 index 00000000000..fd3fe10b938 --- /dev/null +++ b/extern/glew/include/GL/glew.h @@ -0,0 +1,9797 @@ +/* +** The OpenGL Extension Wrangler Library +** Copyright (C) 2002-2006, Milan Ikits +** Copyright (C) 2002-2006, Marcelo E. Magallon +** Copyright (C) 2002, Lev Povalahev +** 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. +** * The name of the author 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. +*/ + +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: This software was created using the +** OpenGL(R) version 1.2.1 Sample Implementation published by SGI, but has +** not been independently verified as being compliant with the OpenGL(R) +** version 1.2.1 Specification. +*/ + +/* added this here for blender, should be moved elsewhere */ +#define GLEW_STATIC + +#ifndef __glew_h__ +#define __glew_h__ +#define __GLEW_H__ + +#if defined(__gl_h_) || defined(__GL_H__) +#error gl.h included before glew.h +#endif +#if defined(__glext_h_) || defined(__GLEXT_H_) +#error glext.h included before glew.h +#endif +#if defined(__gl_ATI_h_) +#error glATI.h included before glew.h +#endif + +#define __gl_h_ +#define __GL_H__ +#define __glext_h_ +#define __GLEXT_H_ +#define __gl_ATI_h_ + +#if defined(_WIN32) || defined(__CYGWIN__) || defined(__MINGW32__) + +/* + * GLEW does not include to avoid name space pollution. + * GL needs GLAPI and GLAPIENTRY, GLU needs APIENTRY, CALLBACK, and wchar_t + * defined properly. + */ +/* */ +#ifndef APIENTRY +#define GLEW_APIENTRY_DEFINED +# if defined(__CYGWIN__) || defined(__MINGW32__) +# define APIENTRY __stdcall +# elif (_MSC_VER >= 800) || defined(_STDCALL_SUPPORTED) || defined(__BORLANDC__) +# define APIENTRY __stdcall +# else +# define APIENTRY +# endif +#endif +#ifndef GLAPI +# if defined(__CYGWIN__) || defined(__MINGW32__) +# define GLAPI extern +# endif +#endif +/* */ +#ifndef CALLBACK +#define GLEW_CALLBACK_DEFINED +# if defined(__CYGWIN__) || defined(__MINGW32__) +# define CALLBACK __attribute__ ((__stdcall__)) +# elif (defined(_M_MRX000) || defined(_M_IX86) || defined(_M_ALPHA) || defined(_M_PPC)) && !defined(MIDL_PASS) +# define CALLBACK __stdcall +# else +# define CALLBACK +# endif +#endif +/* and */ +#ifndef WINGDIAPI +#define GLEW_WINGDIAPI_DEFINED +#define WINGDIAPI __declspec(dllimport) +#endif +/* */ +#if (defined(_MSC_VER) || defined(__BORLANDC__)) && !defined(_WCHAR_T_DEFINED) +typedef unsigned short wchar_t; +# define _WCHAR_T_DEFINED +#endif +/* */ +#if !defined(_W64) +# if !defined(__midl) && (defined(_X86_) || defined(_M_IX86)) && _MSC_VER >= 1300 +# define _W64 __w64 +# else +# define _W64 +# endif +#endif +#if !defined(_PTRDIFF_T_DEFINED) && !defined(_PTRDIFF_T_) +# ifdef _WIN64 +typedef __int64 ptrdiff_t; +# else +typedef _W64 int ptrdiff_t; +# endif +# define _PTRDIFF_T_DEFINED +# define _PTRDIFF_T_ +#endif + +#ifndef GLAPI +# if defined(__CYGWIN__) || defined(__MINGW32__) +# define GLAPI extern +# else +# define GLAPI WINGDIAPI +# endif +#endif + +#ifndef GLAPIENTRY +#define GLAPIENTRY APIENTRY +#endif + +/* + * GLEW_STATIC needs to be set when using the static version. + * GLEW_BUILD is set when building the DLL version. + */ +#ifdef GLEW_STATIC +# define GLEWAPI extern +#else +# ifdef GLEW_BUILD +# define GLEWAPI extern __declspec(dllexport) +# else +# define GLEWAPI extern __declspec(dllimport) +# endif +#endif + +#else /* _UNIX */ + +/* + * Needed for ptrdiff_t in turn needed by VBO. This is defined by ISO + * C. On my system, this amounts to _3 lines_ of included code, all of + * them pretty much harmless. If you know of a way of detecting 32 vs + * 64 _targets_ at compile time you are free to replace this with + * something that's portable. For now, _this_ is the portable solution. + * (mem, 2004-01-04) + */ + +#include + +#define GLEW_APIENTRY_DEFINED +#define APIENTRY +#define GLEWAPI extern + +/* */ +#ifndef GLAPI +#define GLAPI extern +#endif +#ifndef GLAPIENTRY +#define GLAPIENTRY +#endif + +#endif /* _WIN32 */ + +#ifdef __cplusplus +extern "C" { +#endif + +/* ----------------------------- GL_VERSION_1_1 ---------------------------- */ + +#ifndef GL_VERSION_1_1 +#define GL_VERSION_1_1 1 + +#if defined(__APPLE__) +typedef unsigned long GLenum; +typedef unsigned long GLbitfield; +typedef unsigned long GLuint; +typedef long GLint; +typedef long GLsizei; +#else +typedef unsigned int GLenum; +typedef unsigned int GLbitfield; +typedef unsigned int GLuint; +typedef int GLint; +typedef int GLsizei; +#endif +typedef unsigned char GLboolean; +typedef signed char GLbyte; +typedef short GLshort; +typedef unsigned char GLubyte; +typedef unsigned short GLushort; +typedef float GLfloat; +typedef float GLclampf; +typedef double GLdouble; +typedef double GLclampd; +typedef void GLvoid; + +#define GL_ACCUM 0x0100 +#define GL_LOAD 0x0101 +#define GL_RETURN 0x0102 +#define GL_MULT 0x0103 +#define GL_ADD 0x0104 +#define GL_NEVER 0x0200 +#define GL_LESS 0x0201 +#define GL_EQUAL 0x0202 +#define GL_LEQUAL 0x0203 +#define GL_GREATER 0x0204 +#define GL_NOTEQUAL 0x0205 +#define GL_GEQUAL 0x0206 +#define GL_ALWAYS 0x0207 +#define GL_CURRENT_BIT 0x00000001 +#define GL_POINT_BIT 0x00000002 +#define GL_LINE_BIT 0x00000004 +#define GL_POLYGON_BIT 0x00000008 +#define GL_POLYGON_STIPPLE_BIT 0x00000010 +#define GL_PIXEL_MODE_BIT 0x00000020 +#define GL_LIGHTING_BIT 0x00000040 +#define GL_FOG_BIT 0x00000080 +#define GL_DEPTH_BUFFER_BIT 0x00000100 +#define GL_ACCUM_BUFFER_BIT 0x00000200 +#define GL_STENCIL_BUFFER_BIT 0x00000400 +#define GL_VIEWPORT_BIT 0x00000800 +#define GL_TRANSFORM_BIT 0x00001000 +#define GL_ENABLE_BIT 0x00002000 +#define GL_COLOR_BUFFER_BIT 0x00004000 +#define GL_HINT_BIT 0x00008000 +#define GL_EVAL_BIT 0x00010000 +#define GL_LIST_BIT 0x00020000 +#define GL_TEXTURE_BIT 0x00040000 +#define GL_SCISSOR_BIT 0x00080000 +#define GL_ALL_ATTRIB_BITS 0x000fffff +#define GL_POINTS 0x0000 +#define GL_LINES 0x0001 +#define GL_LINE_LOOP 0x0002 +#define GL_LINE_STRIP 0x0003 +#define GL_TRIANGLES 0x0004 +#define GL_TRIANGLE_STRIP 0x0005 +#define GL_TRIANGLE_FAN 0x0006 +#define GL_QUADS 0x0007 +#define GL_QUAD_STRIP 0x0008 +#define GL_POLYGON 0x0009 +#define GL_ZERO 0 +#define GL_ONE 1 +#define GL_SRC_COLOR 0x0300 +#define GL_ONE_MINUS_SRC_COLOR 0x0301 +#define GL_SRC_ALPHA 0x0302 +#define GL_ONE_MINUS_SRC_ALPHA 0x0303 +#define GL_DST_ALPHA 0x0304 +#define GL_ONE_MINUS_DST_ALPHA 0x0305 +#define GL_DST_COLOR 0x0306 +#define GL_ONE_MINUS_DST_COLOR 0x0307 +#define GL_SRC_ALPHA_SATURATE 0x0308 +#define GL_TRUE 1 +#define GL_FALSE 0 +#define GL_CLIP_PLANE0 0x3000 +#define GL_CLIP_PLANE1 0x3001 +#define GL_CLIP_PLANE2 0x3002 +#define GL_CLIP_PLANE3 0x3003 +#define GL_CLIP_PLANE4 0x3004 +#define GL_CLIP_PLANE5 0x3005 +#define GL_BYTE 0x1400 +#define GL_UNSIGNED_BYTE 0x1401 +#define GL_SHORT 0x1402 +#define GL_UNSIGNED_SHORT 0x1403 +#define GL_INT 0x1404 +#define GL_UNSIGNED_INT 0x1405 +#define GL_FLOAT 0x1406 +#define GL_2_BYTES 0x1407 +#define GL_3_BYTES 0x1408 +#define GL_4_BYTES 0x1409 +#define GL_DOUBLE 0x140A +#define GL_NONE 0 +#define GL_FRONT_LEFT 0x0400 +#define GL_FRONT_RIGHT 0x0401 +#define GL_BACK_LEFT 0x0402 +#define GL_BACK_RIGHT 0x0403 +#define GL_FRONT 0x0404 +#define GL_BACK 0x0405 +#define GL_LEFT 0x0406 +#define GL_RIGHT 0x0407 +#define GL_FRONT_AND_BACK 0x0408 +#define GL_AUX0 0x0409 +#define GL_AUX1 0x040A +#define GL_AUX2 0x040B +#define GL_AUX3 0x040C +#define GL_NO_ERROR 0 +#define GL_INVALID_ENUM 0x0500 +#define GL_INVALID_VALUE 0x0501 +#define GL_INVALID_OPERATION 0x0502 +#define GL_STACK_OVERFLOW 0x0503 +#define GL_STACK_UNDERFLOW 0x0504 +#define GL_OUT_OF_MEMORY 0x0505 +#define GL_2D 0x0600 +#define GL_3D 0x0601 +#define GL_3D_COLOR 0x0602 +#define GL_3D_COLOR_TEXTURE 0x0603 +#define GL_4D_COLOR_TEXTURE 0x0604 +#define GL_PASS_THROUGH_TOKEN 0x0700 +#define GL_POINT_TOKEN 0x0701 +#define GL_LINE_TOKEN 0x0702 +#define GL_POLYGON_TOKEN 0x0703 +#define GL_BITMAP_TOKEN 0x0704 +#define GL_DRAW_PIXEL_TOKEN 0x0705 +#define GL_COPY_PIXEL_TOKEN 0x0706 +#define GL_LINE_RESET_TOKEN 0x0707 +#define GL_EXP 0x0800 +#define GL_EXP2 0x0801 +#define GL_CW 0x0900 +#define GL_CCW 0x0901 +#define GL_COEFF 0x0A00 +#define GL_ORDER 0x0A01 +#define GL_DOMAIN 0x0A02 +#define GL_CURRENT_COLOR 0x0B00 +#define GL_CURRENT_INDEX 0x0B01 +#define GL_CURRENT_NORMAL 0x0B02 +#define GL_CURRENT_TEXTURE_COORDS 0x0B03 +#define GL_CURRENT_RASTER_COLOR 0x0B04 +#define GL_CURRENT_RASTER_INDEX 0x0B05 +#define GL_CURRENT_RASTER_TEXTURE_COORDS 0x0B06 +#define GL_CURRENT_RASTER_POSITION 0x0B07 +#define GL_CURRENT_RASTER_POSITION_VALID 0x0B08 +#define GL_CURRENT_RASTER_DISTANCE 0x0B09 +#define GL_POINT_SMOOTH 0x0B10 +#define GL_POINT_SIZE 0x0B11 +#define GL_POINT_SIZE_RANGE 0x0B12 +#define GL_POINT_SIZE_GRANULARITY 0x0B13 +#define GL_LINE_SMOOTH 0x0B20 +#define GL_LINE_WIDTH 0x0B21 +#define GL_LINE_WIDTH_RANGE 0x0B22 +#define GL_LINE_WIDTH_GRANULARITY 0x0B23 +#define GL_LINE_STIPPLE 0x0B24 +#define GL_LINE_STIPPLE_PATTERN 0x0B25 +#define GL_LINE_STIPPLE_REPEAT 0x0B26 +#define GL_LIST_MODE 0x0B30 +#define GL_MAX_LIST_NESTING 0x0B31 +#define GL_LIST_BASE 0x0B32 +#define GL_LIST_INDEX 0x0B33 +#define GL_POLYGON_MODE 0x0B40 +#define GL_POLYGON_SMOOTH 0x0B41 +#define GL_POLYGON_STIPPLE 0x0B42 +#define GL_EDGE_FLAG 0x0B43 +#define GL_CULL_FACE 0x0B44 +#define GL_CULL_FACE_MODE 0x0B45 +#define GL_FRONT_FACE 0x0B46 +#define GL_LIGHTING 0x0B50 +#define GL_LIGHT_MODEL_LOCAL_VIEWER 0x0B51 +#define GL_LIGHT_MODEL_TWO_SIDE 0x0B52 +#define GL_LIGHT_MODEL_AMBIENT 0x0B53 +#define GL_SHADE_MODEL 0x0B54 +#define GL_COLOR_MATERIAL_FACE 0x0B55 +#define GL_COLOR_MATERIAL_PARAMETER 0x0B56 +#define GL_COLOR_MATERIAL 0x0B57 +#define GL_FOG 0x0B60 +#define GL_FOG_INDEX 0x0B61 +#define GL_FOG_DENSITY 0x0B62 +#define GL_FOG_START 0x0B63 +#define GL_FOG_END 0x0B64 +#define GL_FOG_MODE 0x0B65 +#define GL_FOG_COLOR 0x0B66 +#define GL_DEPTH_RANGE 0x0B70 +#define GL_DEPTH_TEST 0x0B71 +#define GL_DEPTH_WRITEMASK 0x0B72 +#define GL_DEPTH_CLEAR_VALUE 0x0B73 +#define GL_DEPTH_FUNC 0x0B74 +#define GL_ACCUM_CLEAR_VALUE 0x0B80 +#define GL_STENCIL_TEST 0x0B90 +#define GL_STENCIL_CLEAR_VALUE 0x0B91 +#define GL_STENCIL_FUNC 0x0B92 +#define GL_STENCIL_VALUE_MASK 0x0B93 +#define GL_STENCIL_FAIL 0x0B94 +#define GL_STENCIL_PASS_DEPTH_FAIL 0x0B95 +#define GL_STENCIL_PASS_DEPTH_PASS 0x0B96 +#define GL_STENCIL_REF 0x0B97 +#define GL_STENCIL_WRITEMASK 0x0B98 +#define GL_MATRIX_MODE 0x0BA0 +#define GL_NORMALIZE 0x0BA1 +#define GL_VIEWPORT 0x0BA2 +#define GL_MODELVIEW_STACK_DEPTH 0x0BA3 +#define GL_PROJECTION_STACK_DEPTH 0x0BA4 +#define GL_TEXTURE_STACK_DEPTH 0x0BA5 +#define GL_MODELVIEW_MATRIX 0x0BA6 +#define GL_PROJECTION_MATRIX 0x0BA7 +#define GL_TEXTURE_MATRIX 0x0BA8 +#define GL_ATTRIB_STACK_DEPTH 0x0BB0 +#define GL_CLIENT_ATTRIB_STACK_DEPTH 0x0BB1 +#define GL_ALPHA_TEST 0x0BC0 +#define GL_ALPHA_TEST_FUNC 0x0BC1 +#define GL_ALPHA_TEST_REF 0x0BC2 +#define GL_DITHER 0x0BD0 +#define GL_BLEND_DST 0x0BE0 +#define GL_BLEND_SRC 0x0BE1 +#define GL_BLEND 0x0BE2 +#define GL_LOGIC_OP_MODE 0x0BF0 +#define GL_INDEX_LOGIC_OP 0x0BF1 +#define GL_COLOR_LOGIC_OP 0x0BF2 +#define GL_AUX_BUFFERS 0x0C00 +#define GL_DRAW_BUFFER 0x0C01 +#define GL_READ_BUFFER 0x0C02 +#define GL_SCISSOR_BOX 0x0C10 +#define GL_SCISSOR_TEST 0x0C11 +#define GL_INDEX_CLEAR_VALUE 0x0C20 +#define GL_INDEX_WRITEMASK 0x0C21 +#define GL_COLOR_CLEAR_VALUE 0x0C22 +#define GL_COLOR_WRITEMASK 0x0C23 +#define GL_INDEX_MODE 0x0C30 +#define GL_RGBA_MODE 0x0C31 +#define GL_DOUBLEBUFFER 0x0C32 +#define GL_STEREO 0x0C33 +#define GL_RENDER_MODE 0x0C40 +#define GL_PERSPECTIVE_CORRECTION_HINT 0x0C50 +#define GL_POINT_SMOOTH_HINT 0x0C51 +#define GL_LINE_SMOOTH_HINT 0x0C52 +#define GL_POLYGON_SMOOTH_HINT 0x0C53 +#define GL_FOG_HINT 0x0C54 +#define GL_TEXTURE_GEN_S 0x0C60 +#define GL_TEXTURE_GEN_T 0x0C61 +#define GL_TEXTURE_GEN_R 0x0C62 +#define GL_TEXTURE_GEN_Q 0x0C63 +#define GL_PIXEL_MAP_I_TO_I 0x0C70 +#define GL_PIXEL_MAP_S_TO_S 0x0C71 +#define GL_PIXEL_MAP_I_TO_R 0x0C72 +#define GL_PIXEL_MAP_I_TO_G 0x0C73 +#define GL_PIXEL_MAP_I_TO_B 0x0C74 +#define GL_PIXEL_MAP_I_TO_A 0x0C75 +#define GL_PIXEL_MAP_R_TO_R 0x0C76 +#define GL_PIXEL_MAP_G_TO_G 0x0C77 +#define GL_PIXEL_MAP_B_TO_B 0x0C78 +#define GL_PIXEL_MAP_A_TO_A 0x0C79 +#define GL_PIXEL_MAP_I_TO_I_SIZE 0x0CB0 +#define GL_PIXEL_MAP_S_TO_S_SIZE 0x0CB1 +#define GL_PIXEL_MAP_I_TO_R_SIZE 0x0CB2 +#define GL_PIXEL_MAP_I_TO_G_SIZE 0x0CB3 +#define GL_PIXEL_MAP_I_TO_B_SIZE 0x0CB4 +#define GL_PIXEL_MAP_I_TO_A_SIZE 0x0CB5 +#define GL_PIXEL_MAP_R_TO_R_SIZE 0x0CB6 +#define GL_PIXEL_MAP_G_TO_G_SIZE 0x0CB7 +#define GL_PIXEL_MAP_B_TO_B_SIZE 0x0CB8 +#define GL_PIXEL_MAP_A_TO_A_SIZE 0x0CB9 +#define GL_UNPACK_SWAP_BYTES 0x0CF0 +#define GL_UNPACK_LSB_FIRST 0x0CF1 +#define GL_UNPACK_ROW_LENGTH 0x0CF2 +#define GL_UNPACK_SKIP_ROWS 0x0CF3 +#define GL_UNPACK_SKIP_PIXELS 0x0CF4 +#define GL_UNPACK_ALIGNMENT 0x0CF5 +#define GL_PACK_SWAP_BYTES 0x0D00 +#define GL_PACK_LSB_FIRST 0x0D01 +#define GL_PACK_ROW_LENGTH 0x0D02 +#define GL_PACK_SKIP_ROWS 0x0D03 +#define GL_PACK_SKIP_PIXELS 0x0D04 +#define GL_PACK_ALIGNMENT 0x0D05 +#define GL_MAP_COLOR 0x0D10 +#define GL_MAP_STENCIL 0x0D11 +#define GL_INDEX_SHIFT 0x0D12 +#define GL_INDEX_OFFSET 0x0D13 +#define GL_RED_SCALE 0x0D14 +#define GL_RED_BIAS 0x0D15 +#define GL_ZOOM_X 0x0D16 +#define GL_ZOOM_Y 0x0D17 +#define GL_GREEN_SCALE 0x0D18 +#define GL_GREEN_BIAS 0x0D19 +#define GL_BLUE_SCALE 0x0D1A +#define GL_BLUE_BIAS 0x0D1B +#define GL_ALPHA_SCALE 0x0D1C +#define GL_ALPHA_BIAS 0x0D1D +#define GL_DEPTH_SCALE 0x0D1E +#define GL_DEPTH_BIAS 0x0D1F +#define GL_MAX_EVAL_ORDER 0x0D30 +#define GL_MAX_LIGHTS 0x0D31 +#define GL_MAX_CLIP_PLANES 0x0D32 +#define GL_MAX_TEXTURE_SIZE 0x0D33 +#define GL_MAX_PIXEL_MAP_TABLE 0x0D34 +#define GL_MAX_ATTRIB_STACK_DEPTH 0x0D35 +#define GL_MAX_MODELVIEW_STACK_DEPTH 0x0D36 +#define GL_MAX_NAME_STACK_DEPTH 0x0D37 +#define GL_MAX_PROJECTION_STACK_DEPTH 0x0D38 +#define GL_MAX_TEXTURE_STACK_DEPTH 0x0D39 +#define GL_MAX_VIEWPORT_DIMS 0x0D3A +#define GL_MAX_CLIENT_ATTRIB_STACK_DEPTH 0x0D3B +#define GL_SUBPIXEL_BITS 0x0D50 +#define GL_INDEX_BITS 0x0D51 +#define GL_RED_BITS 0x0D52 +#define GL_GREEN_BITS 0x0D53 +#define GL_BLUE_BITS 0x0D54 +#define GL_ALPHA_BITS 0x0D55 +#define GL_DEPTH_BITS 0x0D56 +#define GL_STENCIL_BITS 0x0D57 +#define GL_ACCUM_RED_BITS 0x0D58 +#define GL_ACCUM_GREEN_BITS 0x0D59 +#define GL_ACCUM_BLUE_BITS 0x0D5A +#define GL_ACCUM_ALPHA_BITS 0x0D5B +#define GL_NAME_STACK_DEPTH 0x0D70 +#define GL_AUTO_NORMAL 0x0D80 +#define GL_MAP1_COLOR_4 0x0D90 +#define GL_MAP1_INDEX 0x0D91 +#define GL_MAP1_NORMAL 0x0D92 +#define GL_MAP1_TEXTURE_COORD_1 0x0D93 +#define GL_MAP1_TEXTURE_COORD_2 0x0D94 +#define GL_MAP1_TEXTURE_COORD_3 0x0D95 +#define GL_MAP1_TEXTURE_COORD_4 0x0D96 +#define GL_MAP1_VERTEX_3 0x0D97 +#define GL_MAP1_VERTEX_4 0x0D98 +#define GL_MAP2_COLOR_4 0x0DB0 +#define GL_MAP2_INDEX 0x0DB1 +#define GL_MAP2_NORMAL 0x0DB2 +#define GL_MAP2_TEXTURE_COORD_1 0x0DB3 +#define GL_MAP2_TEXTURE_COORD_2 0x0DB4 +#define GL_MAP2_TEXTURE_COORD_3 0x0DB5 +#define GL_MAP2_TEXTURE_COORD_4 0x0DB6 +#define GL_MAP2_VERTEX_3 0x0DB7 +#define GL_MAP2_VERTEX_4 0x0DB8 +#define GL_MAP1_GRID_DOMAIN 0x0DD0 +#define GL_MAP1_GRID_SEGMENTS 0x0DD1 +#define GL_MAP2_GRID_DOMAIN 0x0DD2 +#define GL_MAP2_GRID_SEGMENTS 0x0DD3 +#define GL_TEXTURE_1D 0x0DE0 +#define GL_TEXTURE_2D 0x0DE1 +#define GL_FEEDBACK_BUFFER_POINTER 0x0DF0 +#define GL_FEEDBACK_BUFFER_SIZE 0x0DF1 +#define GL_FEEDBACK_BUFFER_TYPE 0x0DF2 +#define GL_SELECTION_BUFFER_POINTER 0x0DF3 +#define GL_SELECTION_BUFFER_SIZE 0x0DF4 +#define GL_TEXTURE_WIDTH 0x1000 +#define GL_TEXTURE_HEIGHT 0x1001 +#define GL_TEXTURE_INTERNAL_FORMAT 0x1003 +#define GL_TEXTURE_BORDER_COLOR 0x1004 +#define GL_TEXTURE_BORDER 0x1005 +#define GL_DONT_CARE 0x1100 +#define GL_FASTEST 0x1101 +#define GL_NICEST 0x1102 +#define GL_LIGHT0 0x4000 +#define GL_LIGHT1 0x4001 +#define GL_LIGHT2 0x4002 +#define GL_LIGHT3 0x4003 +#define GL_LIGHT4 0x4004 +#define GL_LIGHT5 0x4005 +#define GL_LIGHT6 0x4006 +#define GL_LIGHT7 0x4007 +#define GL_AMBIENT 0x1200 +#define GL_DIFFUSE 0x1201 +#define GL_SPECULAR 0x1202 +#define GL_POSITION 0x1203 +#define GL_SPOT_DIRECTION 0x1204 +#define GL_SPOT_EXPONENT 0x1205 +#define GL_SPOT_CUTOFF 0x1206 +#define GL_CONSTANT_ATTENUATION 0x1207 +#define GL_LINEAR_ATTENUATION 0x1208 +#define GL_QUADRATIC_ATTENUATION 0x1209 +#define GL_COMPILE 0x1300 +#define GL_COMPILE_AND_EXECUTE 0x1301 +#define GL_CLEAR 0x1500 +#define GL_AND 0x1501 +#define GL_AND_REVERSE 0x1502 +#define GL_COPY 0x1503 +#define GL_AND_INVERTED 0x1504 +#define GL_NOOP 0x1505 +#define GL_XOR 0x1506 +#define GL_OR 0x1507 +#define GL_NOR 0x1508 +#define GL_EQUIV 0x1509 +#define GL_INVERT 0x150A +#define GL_OR_REVERSE 0x150B +#define GL_COPY_INVERTED 0x150C +#define GL_OR_INVERTED 0x150D +#define GL_NAND 0x150E +#define GL_SET 0x150F +#define GL_EMISSION 0x1600 +#define GL_SHININESS 0x1601 +#define GL_AMBIENT_AND_DIFFUSE 0x1602 +#define GL_COLOR_INDEXES 0x1603 +#define GL_MODELVIEW 0x1700 +#define GL_PROJECTION 0x1701 +#define GL_TEXTURE 0x1702 +#define GL_COLOR 0x1800 +#define GL_DEPTH 0x1801 +#define GL_STENCIL 0x1802 +#define GL_COLOR_INDEX 0x1900 +#define GL_STENCIL_INDEX 0x1901 +#define GL_DEPTH_COMPONENT 0x1902 +#define GL_RED 0x1903 +#define GL_GREEN 0x1904 +#define GL_BLUE 0x1905 +#define GL_ALPHA 0x1906 +#define GL_RGB 0x1907 +#define GL_RGBA 0x1908 +#define GL_LUMINANCE 0x1909 +#define GL_LUMINANCE_ALPHA 0x190A +#define GL_BITMAP 0x1A00 +#define GL_POINT 0x1B00 +#define GL_LINE 0x1B01 +#define GL_FILL 0x1B02 +#define GL_RENDER 0x1C00 +#define GL_FEEDBACK 0x1C01 +#define GL_SELECT 0x1C02 +#define GL_FLAT 0x1D00 +#define GL_SMOOTH 0x1D01 +#define GL_KEEP 0x1E00 +#define GL_REPLACE 0x1E01 +#define GL_INCR 0x1E02 +#define GL_DECR 0x1E03 +#define GL_VENDOR 0x1F00 +#define GL_RENDERER 0x1F01 +#define GL_VERSION 0x1F02 +#define GL_EXTENSIONS 0x1F03 +#define GL_S 0x2000 +#define GL_T 0x2001 +#define GL_R 0x2002 +#define GL_Q 0x2003 +#define GL_MODULATE 0x2100 +#define GL_DECAL 0x2101 +#define GL_TEXTURE_ENV_MODE 0x2200 +#define GL_TEXTURE_ENV_COLOR 0x2201 +#define GL_TEXTURE_ENV 0x2300 +#define GL_EYE_LINEAR 0x2400 +#define GL_OBJECT_LINEAR 0x2401 +#define GL_SPHERE_MAP 0x2402 +#define GL_TEXTURE_GEN_MODE 0x2500 +#define GL_OBJECT_PLANE 0x2501 +#define GL_EYE_PLANE 0x2502 +#define GL_NEAREST 0x2600 +#define GL_LINEAR 0x2601 +#define GL_NEAREST_MIPMAP_NEAREST 0x2700 +#define GL_LINEAR_MIPMAP_NEAREST 0x2701 +#define GL_NEAREST_MIPMAP_LINEAR 0x2702 +#define GL_LINEAR_MIPMAP_LINEAR 0x2703 +#define GL_TEXTURE_MAG_FILTER 0x2800 +#define GL_TEXTURE_MIN_FILTER 0x2801 +#define GL_TEXTURE_WRAP_S 0x2802 +#define GL_TEXTURE_WRAP_T 0x2803 +#define GL_CLAMP 0x2900 +#define GL_REPEAT 0x2901 +#define GL_CLIENT_PIXEL_STORE_BIT 0x00000001 +#define GL_CLIENT_VERTEX_ARRAY_BIT 0x00000002 +#define GL_CLIENT_ALL_ATTRIB_BITS 0xffffffff +#define GL_POLYGON_OFFSET_FACTOR 0x8038 +#define GL_POLYGON_OFFSET_UNITS 0x2A00 +#define GL_POLYGON_OFFSET_POINT 0x2A01 +#define GL_POLYGON_OFFSET_LINE 0x2A02 +#define GL_POLYGON_OFFSET_FILL 0x8037 +#define GL_ALPHA4 0x803B +#define GL_ALPHA8 0x803C +#define GL_ALPHA12 0x803D +#define GL_ALPHA16 0x803E +#define GL_LUMINANCE4 0x803F +#define GL_LUMINANCE8 0x8040 +#define GL_LUMINANCE12 0x8041 +#define GL_LUMINANCE16 0x8042 +#define GL_LUMINANCE4_ALPHA4 0x8043 +#define GL_LUMINANCE6_ALPHA2 0x8044 +#define GL_LUMINANCE8_ALPHA8 0x8045 +#define GL_LUMINANCE12_ALPHA4 0x8046 +#define GL_LUMINANCE12_ALPHA12 0x8047 +#define GL_LUMINANCE16_ALPHA16 0x8048 +#define GL_INTENSITY 0x8049 +#define GL_INTENSITY4 0x804A +#define GL_INTENSITY8 0x804B +#define GL_INTENSITY12 0x804C +#define GL_INTENSITY16 0x804D +#define GL_R3_G3_B2 0x2A10 +#define GL_RGB4 0x804F +#define GL_RGB5 0x8050 +#define GL_RGB8 0x8051 +#define GL_RGB10 0x8052 +#define GL_RGB12 0x8053 +#define GL_RGB16 0x8054 +#define GL_RGBA2 0x8055 +#define GL_RGBA4 0x8056 +#define GL_RGB5_A1 0x8057 +#define GL_RGBA8 0x8058 +#define GL_RGB10_A2 0x8059 +#define GL_RGBA12 0x805A +#define GL_RGBA16 0x805B +#define GL_TEXTURE_RED_SIZE 0x805C +#define GL_TEXTURE_GREEN_SIZE 0x805D +#define GL_TEXTURE_BLUE_SIZE 0x805E +#define GL_TEXTURE_ALPHA_SIZE 0x805F +#define GL_TEXTURE_LUMINANCE_SIZE 0x8060 +#define GL_TEXTURE_INTENSITY_SIZE 0x8061 +#define GL_PROXY_TEXTURE_1D 0x8063 +#define GL_PROXY_TEXTURE_2D 0x8064 +#define GL_TEXTURE_PRIORITY 0x8066 +#define GL_TEXTURE_RESIDENT 0x8067 +#define GL_TEXTURE_BINDING_1D 0x8068 +#define GL_TEXTURE_BINDING_2D 0x8069 +#define GL_VERTEX_ARRAY 0x8074 +#define GL_NORMAL_ARRAY 0x8075 +#define GL_COLOR_ARRAY 0x8076 +#define GL_INDEX_ARRAY 0x8077 +#define GL_TEXTURE_COORD_ARRAY 0x8078 +#define GL_EDGE_FLAG_ARRAY 0x8079 +#define GL_VERTEX_ARRAY_SIZE 0x807A +#define GL_VERTEX_ARRAY_TYPE 0x807B +#define GL_VERTEX_ARRAY_STRIDE 0x807C +#define GL_NORMAL_ARRAY_TYPE 0x807E +#define GL_NORMAL_ARRAY_STRIDE 0x807F +#define GL_COLOR_ARRAY_SIZE 0x8081 +#define GL_COLOR_ARRAY_TYPE 0x8082 +#define GL_COLOR_ARRAY_STRIDE 0x8083 +#define GL_INDEX_ARRAY_TYPE 0x8085 +#define GL_INDEX_ARRAY_STRIDE 0x8086 +#define GL_TEXTURE_COORD_ARRAY_SIZE 0x8088 +#define GL_TEXTURE_COORD_ARRAY_TYPE 0x8089 +#define GL_TEXTURE_COORD_ARRAY_STRIDE 0x808A +#define GL_EDGE_FLAG_ARRAY_STRIDE 0x808C +#define GL_VERTEX_ARRAY_POINTER 0x808E +#define GL_NORMAL_ARRAY_POINTER 0x808F +#define GL_COLOR_ARRAY_POINTER 0x8090 +#define GL_INDEX_ARRAY_POINTER 0x8091 +#define GL_TEXTURE_COORD_ARRAY_POINTER 0x8092 +#define GL_EDGE_FLAG_ARRAY_POINTER 0x8093 +#define GL_V2F 0x2A20 +#define GL_V3F 0x2A21 +#define GL_C4UB_V2F 0x2A22 +#define GL_C4UB_V3F 0x2A23 +#define GL_C3F_V3F 0x2A24 +#define GL_N3F_V3F 0x2A25 +#define GL_C4F_N3F_V3F 0x2A26 +#define GL_T2F_V3F 0x2A27 +#define GL_T4F_V4F 0x2A28 +#define GL_T2F_C4UB_V3F 0x2A29 +#define GL_T2F_C3F_V3F 0x2A2A +#define GL_T2F_N3F_V3F 0x2A2B +#define GL_T2F_C4F_N3F_V3F 0x2A2C +#define GL_T4F_C4F_N3F_V4F 0x2A2D +#define GL_LOGIC_OP GL_INDEX_LOGIC_OP +#define GL_TEXTURE_COMPONENTS GL_TEXTURE_INTERNAL_FORMAT +#define GL_COLOR_INDEX1_EXT 0x80E2 +#define GL_COLOR_INDEX2_EXT 0x80E3 +#define GL_COLOR_INDEX4_EXT 0x80E4 +#define GL_COLOR_INDEX8_EXT 0x80E5 +#define GL_COLOR_INDEX12_EXT 0x80E6 +#define GL_COLOR_INDEX16_EXT 0x80E7 + +GLAPI void GLAPIENTRY glAccum (GLenum op, GLfloat value); +GLAPI void GLAPIENTRY glAlphaFunc (GLenum func, GLclampf ref); +GLAPI GLboolean GLAPIENTRY glAreTexturesResident (GLsizei n, const GLuint *textures, GLboolean *residences); +GLAPI void GLAPIENTRY glArrayElement (GLint i); +GLAPI void GLAPIENTRY glBegin (GLenum mode); +GLAPI void GLAPIENTRY glBindTexture (GLenum target, GLuint texture); +GLAPI void GLAPIENTRY glBitmap (GLsizei width, GLsizei height, GLfloat xorig, GLfloat yorig, GLfloat xmove, GLfloat ymove, const GLubyte *bitmap); +GLAPI void GLAPIENTRY glBlendFunc (GLenum sfactor, GLenum dfactor); +GLAPI void GLAPIENTRY glCallList (GLuint list); +GLAPI void GLAPIENTRY glCallLists (GLsizei n, GLenum type, const GLvoid *lists); +GLAPI void GLAPIENTRY glClear (GLbitfield mask); +GLAPI void GLAPIENTRY glClearAccum (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); +GLAPI void GLAPIENTRY glClearColor (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha); +GLAPI void GLAPIENTRY glClearDepth (GLclampd depth); +GLAPI void GLAPIENTRY glClearIndex (GLfloat c); +GLAPI void GLAPIENTRY glClearStencil (GLint s); +GLAPI void GLAPIENTRY glClipPlane (GLenum plane, const GLdouble *equation); +GLAPI void GLAPIENTRY glColor3b (GLbyte red, GLbyte green, GLbyte blue); +GLAPI void GLAPIENTRY glColor3bv (const GLbyte *v); +GLAPI void GLAPIENTRY glColor3d (GLdouble red, GLdouble green, GLdouble blue); +GLAPI void GLAPIENTRY glColor3dv (const GLdouble *v); +GLAPI void GLAPIENTRY glColor3f (GLfloat red, GLfloat green, GLfloat blue); +GLAPI void GLAPIENTRY glColor3fv (const GLfloat *v); +GLAPI void GLAPIENTRY glColor3i (GLint red, GLint green, GLint blue); +GLAPI void GLAPIENTRY glColor3iv (const GLint *v); +GLAPI void GLAPIENTRY glColor3s (GLshort red, GLshort green, GLshort blue); +GLAPI void GLAPIENTRY glColor3sv (const GLshort *v); +GLAPI void GLAPIENTRY glColor3ub (GLubyte red, GLubyte green, GLubyte blue); +GLAPI void GLAPIENTRY glColor3ubv (const GLubyte *v); +GLAPI void GLAPIENTRY glColor3ui (GLuint red, GLuint green, GLuint blue); +GLAPI void GLAPIENTRY glColor3uiv (const GLuint *v); +GLAPI void GLAPIENTRY glColor3us (GLushort red, GLushort green, GLushort blue); +GLAPI void GLAPIENTRY glColor3usv (const GLushort *v); +GLAPI void GLAPIENTRY glColor4b (GLbyte red, GLbyte green, GLbyte blue, GLbyte alpha); +GLAPI void GLAPIENTRY glColor4bv (const GLbyte *v); +GLAPI void GLAPIENTRY glColor4d (GLdouble red, GLdouble green, GLdouble blue, GLdouble alpha); +GLAPI void GLAPIENTRY glColor4dv (const GLdouble *v); +GLAPI void GLAPIENTRY glColor4f (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); +GLAPI void GLAPIENTRY glColor4fv (const GLfloat *v); +GLAPI void GLAPIENTRY glColor4i (GLint red, GLint green, GLint blue, GLint alpha); +GLAPI void GLAPIENTRY glColor4iv (const GLint *v); +GLAPI void GLAPIENTRY glColor4s (GLshort red, GLshort green, GLshort blue, GLshort alpha); +GLAPI void GLAPIENTRY glColor4sv (const GLshort *v); +GLAPI void GLAPIENTRY glColor4ub (GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha); +GLAPI void GLAPIENTRY glColor4ubv (const GLubyte *v); +GLAPI void GLAPIENTRY glColor4ui (GLuint red, GLuint green, GLuint blue, GLuint alpha); +GLAPI void GLAPIENTRY glColor4uiv (const GLuint *v); +GLAPI void GLAPIENTRY glColor4us (GLushort red, GLushort green, GLushort blue, GLushort alpha); +GLAPI void GLAPIENTRY glColor4usv (const GLushort *v); +GLAPI void GLAPIENTRY glColorMask (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha); +GLAPI void GLAPIENTRY glColorMaterial (GLenum face, GLenum mode); +GLAPI void GLAPIENTRY glColorPointer (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); +GLAPI void GLAPIENTRY glCopyPixels (GLint x, GLint y, GLsizei width, GLsizei height, GLenum type); +GLAPI void GLAPIENTRY glCopyTexImage1D (GLenum target, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLint border); +GLAPI void GLAPIENTRY glCopyTexImage2D (GLenum target, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); +GLAPI void GLAPIENTRY glCopyTexSubImage1D (GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width); +GLAPI void GLAPIENTRY glCopyTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); +GLAPI void GLAPIENTRY glCullFace (GLenum mode); +GLAPI void GLAPIENTRY glDeleteLists (GLuint list, GLsizei range); +GLAPI void GLAPIENTRY glDeleteTextures (GLsizei n, const GLuint *textures); +GLAPI void GLAPIENTRY glDepthFunc (GLenum func); +GLAPI void GLAPIENTRY glDepthMask (GLboolean flag); +GLAPI void GLAPIENTRY glDepthRange (GLclampd zNear, GLclampd zFar); +GLAPI void GLAPIENTRY glDisable (GLenum cap); +GLAPI void GLAPIENTRY glDisableClientState (GLenum array); +GLAPI void GLAPIENTRY glDrawArrays (GLenum mode, GLint first, GLsizei count); +GLAPI void GLAPIENTRY glDrawBuffer (GLenum mode); +GLAPI void GLAPIENTRY glDrawElements (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices); +GLAPI void GLAPIENTRY glDrawPixels (GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels); +GLAPI void GLAPIENTRY glEdgeFlag (GLboolean flag); +GLAPI void GLAPIENTRY glEdgeFlagPointer (GLsizei stride, const GLvoid *pointer); +GLAPI void GLAPIENTRY glEdgeFlagv (const GLboolean *flag); +GLAPI void GLAPIENTRY glEnable (GLenum cap); +GLAPI void GLAPIENTRY glEnableClientState (GLenum array); +GLAPI void GLAPIENTRY glEnd (void); +GLAPI void GLAPIENTRY glEndList (void); +GLAPI void GLAPIENTRY glEvalCoord1d (GLdouble u); +GLAPI void GLAPIENTRY glEvalCoord1dv (const GLdouble *u); +GLAPI void GLAPIENTRY glEvalCoord1f (GLfloat u); +GLAPI void GLAPIENTRY glEvalCoord1fv (const GLfloat *u); +GLAPI void GLAPIENTRY glEvalCoord2d (GLdouble u, GLdouble v); +GLAPI void GLAPIENTRY glEvalCoord2dv (const GLdouble *u); +GLAPI void GLAPIENTRY glEvalCoord2f (GLfloat u, GLfloat v); +GLAPI void GLAPIENTRY glEvalCoord2fv (const GLfloat *u); +GLAPI void GLAPIENTRY glEvalMesh1 (GLenum mode, GLint i1, GLint i2); +GLAPI void GLAPIENTRY glEvalMesh2 (GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2); +GLAPI void GLAPIENTRY glEvalPoint1 (GLint i); +GLAPI void GLAPIENTRY glEvalPoint2 (GLint i, GLint j); +GLAPI void GLAPIENTRY glFeedbackBuffer (GLsizei size, GLenum type, GLfloat *buffer); +GLAPI void GLAPIENTRY glFinish (void); +GLAPI void GLAPIENTRY glFlush (void); +GLAPI void GLAPIENTRY glFogf (GLenum pname, GLfloat param); +GLAPI void GLAPIENTRY glFogfv (GLenum pname, const GLfloat *params); +GLAPI void GLAPIENTRY glFogi (GLenum pname, GLint param); +GLAPI void GLAPIENTRY glFogiv (GLenum pname, const GLint *params); +GLAPI void GLAPIENTRY glFrontFace (GLenum mode); +GLAPI void GLAPIENTRY glFrustum (GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar); +GLAPI GLuint GLAPIENTRY glGenLists (GLsizei range); +GLAPI void GLAPIENTRY glGenTextures (GLsizei n, GLuint *textures); +GLAPI void GLAPIENTRY glGetBooleanv (GLenum pname, GLboolean *params); +GLAPI void GLAPIENTRY glGetClipPlane (GLenum plane, GLdouble *equation); +GLAPI void GLAPIENTRY glGetDoublev (GLenum pname, GLdouble *params); +GLAPI GLenum GLAPIENTRY glGetError (void); +GLAPI void GLAPIENTRY glGetFloatv (GLenum pname, GLfloat *params); +GLAPI void GLAPIENTRY glGetIntegerv (GLenum pname, GLint *params); +GLAPI void GLAPIENTRY glGetLightfv (GLenum light, GLenum pname, GLfloat *params); +GLAPI void GLAPIENTRY glGetLightiv (GLenum light, GLenum pname, GLint *params); +GLAPI void GLAPIENTRY glGetMapdv (GLenum target, GLenum query, GLdouble *v); +GLAPI void GLAPIENTRY glGetMapfv (GLenum target, GLenum query, GLfloat *v); +GLAPI void GLAPIENTRY glGetMapiv (GLenum target, GLenum query, GLint *v); +GLAPI void GLAPIENTRY glGetMaterialfv (GLenum face, GLenum pname, GLfloat *params); +GLAPI void GLAPIENTRY glGetMaterialiv (GLenum face, GLenum pname, GLint *params); +GLAPI void GLAPIENTRY glGetPixelMapfv (GLenum map, GLfloat *values); +GLAPI void GLAPIENTRY glGetPixelMapuiv (GLenum map, GLuint *values); +GLAPI void GLAPIENTRY glGetPixelMapusv (GLenum map, GLushort *values); +GLAPI void GLAPIENTRY glGetPointerv (GLenum pname, GLvoid* *params); +GLAPI void GLAPIENTRY glGetPolygonStipple (GLubyte *mask); +GLAPI const GLubyte * GLAPIENTRY glGetString (GLenum name); +GLAPI void GLAPIENTRY glGetTexEnvfv (GLenum target, GLenum pname, GLfloat *params); +GLAPI void GLAPIENTRY glGetTexEnviv (GLenum target, GLenum pname, GLint *params); +GLAPI void GLAPIENTRY glGetTexGendv (GLenum coord, GLenum pname, GLdouble *params); +GLAPI void GLAPIENTRY glGetTexGenfv (GLenum coord, GLenum pname, GLfloat *params); +GLAPI void GLAPIENTRY glGetTexGeniv (GLenum coord, GLenum pname, GLint *params); +GLAPI void GLAPIENTRY glGetTexImage (GLenum target, GLint level, GLenum format, GLenum type, GLvoid *pixels); +GLAPI void GLAPIENTRY glGetTexLevelParameterfv (GLenum target, GLint level, GLenum pname, GLfloat *params); +GLAPI void GLAPIENTRY glGetTexLevelParameteriv (GLenum target, GLint level, GLenum pname, GLint *params); +GLAPI void GLAPIENTRY glGetTexParameterfv (GLenum target, GLenum pname, GLfloat *params); +GLAPI void GLAPIENTRY glGetTexParameteriv (GLenum target, GLenum pname, GLint *params); +GLAPI void GLAPIENTRY glHint (GLenum target, GLenum mode); +GLAPI void GLAPIENTRY glIndexMask (GLuint mask); +GLAPI void GLAPIENTRY glIndexPointer (GLenum type, GLsizei stride, const GLvoid *pointer); +GLAPI void GLAPIENTRY glIndexd (GLdouble c); +GLAPI void GLAPIENTRY glIndexdv (const GLdouble *c); +GLAPI void GLAPIENTRY glIndexf (GLfloat c); +GLAPI void GLAPIENTRY glIndexfv (const GLfloat *c); +GLAPI void GLAPIENTRY glIndexi (GLint c); +GLAPI void GLAPIENTRY glIndexiv (const GLint *c); +GLAPI void GLAPIENTRY glIndexs (GLshort c); +GLAPI void GLAPIENTRY glIndexsv (const GLshort *c); +GLAPI void GLAPIENTRY glIndexub (GLubyte c); +GLAPI void GLAPIENTRY glIndexubv (const GLubyte *c); +GLAPI void GLAPIENTRY glInitNames (void); +GLAPI void GLAPIENTRY glInterleavedArrays (GLenum format, GLsizei stride, const GLvoid *pointer); +GLAPI GLboolean GLAPIENTRY glIsEnabled (GLenum cap); +GLAPI GLboolean GLAPIENTRY glIsList (GLuint list); +GLAPI GLboolean GLAPIENTRY glIsTexture (GLuint texture); +GLAPI void GLAPIENTRY glLightModelf (GLenum pname, GLfloat param); +GLAPI void GLAPIENTRY glLightModelfv (GLenum pname, const GLfloat *params); +GLAPI void GLAPIENTRY glLightModeli (GLenum pname, GLint param); +GLAPI void GLAPIENTRY glLightModeliv (GLenum pname, const GLint *params); +GLAPI void GLAPIENTRY glLightf (GLenum light, GLenum pname, GLfloat param); +GLAPI void GLAPIENTRY glLightfv (GLenum light, GLenum pname, const GLfloat *params); +GLAPI void GLAPIENTRY glLighti (GLenum light, GLenum pname, GLint param); +GLAPI void GLAPIENTRY glLightiv (GLenum light, GLenum pname, const GLint *params); +GLAPI void GLAPIENTRY glLineStipple (GLint factor, GLushort pattern); +GLAPI void GLAPIENTRY glLineWidth (GLfloat width); +GLAPI void GLAPIENTRY glListBase (GLuint base); +GLAPI void GLAPIENTRY glLoadIdentity (void); +GLAPI void GLAPIENTRY glLoadMatrixd (const GLdouble *m); +GLAPI void GLAPIENTRY glLoadMatrixf (const GLfloat *m); +GLAPI void GLAPIENTRY glLoadName (GLuint name); +GLAPI void GLAPIENTRY glLogicOp (GLenum opcode); +GLAPI void GLAPIENTRY glMap1d (GLenum target, GLdouble u1, GLdouble u2, GLint stride, GLint order, const GLdouble *points); +GLAPI void GLAPIENTRY glMap1f (GLenum target, GLfloat u1, GLfloat u2, GLint stride, GLint order, const GLfloat *points); +GLAPI void GLAPIENTRY glMap2d (GLenum target, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, const GLdouble *points); +GLAPI void GLAPIENTRY glMap2f (GLenum target, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, const GLfloat *points); +GLAPI void GLAPIENTRY glMapGrid1d (GLint un, GLdouble u1, GLdouble u2); +GLAPI void GLAPIENTRY glMapGrid1f (GLint un, GLfloat u1, GLfloat u2); +GLAPI void GLAPIENTRY glMapGrid2d (GLint un, GLdouble u1, GLdouble u2, GLint vn, GLdouble v1, GLdouble v2); +GLAPI void GLAPIENTRY glMapGrid2f (GLint un, GLfloat u1, GLfloat u2, GLint vn, GLfloat v1, GLfloat v2); +GLAPI void GLAPIENTRY glMaterialf (GLenum face, GLenum pname, GLfloat param); +GLAPI void GLAPIENTRY glMaterialfv (GLenum face, GLenum pname, const GLfloat *params); +GLAPI void GLAPIENTRY glMateriali (GLenum face, GLenum pname, GLint param); +GLAPI void GLAPIENTRY glMaterialiv (GLenum face, GLenum pname, const GLint *params); +GLAPI void GLAPIENTRY glMatrixMode (GLenum mode); +GLAPI void GLAPIENTRY glMultMatrixd (const GLdouble *m); +GLAPI void GLAPIENTRY glMultMatrixf (const GLfloat *m); +GLAPI void GLAPIENTRY glNewList (GLuint list, GLenum mode); +GLAPI void GLAPIENTRY glNormal3b (GLbyte nx, GLbyte ny, GLbyte nz); +GLAPI void GLAPIENTRY glNormal3bv (const GLbyte *v); +GLAPI void GLAPIENTRY glNormal3d (GLdouble nx, GLdouble ny, GLdouble nz); +GLAPI void GLAPIENTRY glNormal3dv (const GLdouble *v); +GLAPI void GLAPIENTRY glNormal3f (GLfloat nx, GLfloat ny, GLfloat nz); +GLAPI void GLAPIENTRY glNormal3fv (const GLfloat *v); +GLAPI void GLAPIENTRY glNormal3i (GLint nx, GLint ny, GLint nz); +GLAPI void GLAPIENTRY glNormal3iv (const GLint *v); +GLAPI void GLAPIENTRY glNormal3s (GLshort nx, GLshort ny, GLshort nz); +GLAPI void GLAPIENTRY glNormal3sv (const GLshort *v); +GLAPI void GLAPIENTRY glNormalPointer (GLenum type, GLsizei stride, const GLvoid *pointer); +GLAPI void GLAPIENTRY glOrtho (GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar); +GLAPI void GLAPIENTRY glPassThrough (GLfloat token); +GLAPI void GLAPIENTRY glPixelMapfv (GLenum map, GLsizei mapsize, const GLfloat *values); +GLAPI void GLAPIENTRY glPixelMapuiv (GLenum map, GLsizei mapsize, const GLuint *values); +GLAPI void GLAPIENTRY glPixelMapusv (GLenum map, GLsizei mapsize, const GLushort *values); +GLAPI void GLAPIENTRY glPixelStoref (GLenum pname, GLfloat param); +GLAPI void GLAPIENTRY glPixelStorei (GLenum pname, GLint param); +GLAPI void GLAPIENTRY glPixelTransferf (GLenum pname, GLfloat param); +GLAPI void GLAPIENTRY glPixelTransferi (GLenum pname, GLint param); +GLAPI void GLAPIENTRY glPixelZoom (GLfloat xfactor, GLfloat yfactor); +GLAPI void GLAPIENTRY glPointSize (GLfloat size); +GLAPI void GLAPIENTRY glPolygonMode (GLenum face, GLenum mode); +GLAPI void GLAPIENTRY glPolygonOffset (GLfloat factor, GLfloat units); +GLAPI void GLAPIENTRY glPolygonStipple (const GLubyte *mask); +GLAPI void GLAPIENTRY glPopAttrib (void); +GLAPI void GLAPIENTRY glPopClientAttrib (void); +GLAPI void GLAPIENTRY glPopMatrix (void); +GLAPI void GLAPIENTRY glPopName (void); +GLAPI void GLAPIENTRY glPrioritizeTextures (GLsizei n, const GLuint *textures, const GLclampf *priorities); +GLAPI void GLAPIENTRY glPushAttrib (GLbitfield mask); +GLAPI void GLAPIENTRY glPushClientAttrib (GLbitfield mask); +GLAPI void GLAPIENTRY glPushMatrix (void); +GLAPI void GLAPIENTRY glPushName (GLuint name); +GLAPI void GLAPIENTRY glRasterPos2d (GLdouble x, GLdouble y); +GLAPI void GLAPIENTRY glRasterPos2dv (const GLdouble *v); +GLAPI void GLAPIENTRY glRasterPos2f (GLfloat x, GLfloat y); +GLAPI void GLAPIENTRY glRasterPos2fv (const GLfloat *v); +GLAPI void GLAPIENTRY glRasterPos2i (GLint x, GLint y); +GLAPI void GLAPIENTRY glRasterPos2iv (const GLint *v); +GLAPI void GLAPIENTRY glRasterPos2s (GLshort x, GLshort y); +GLAPI void GLAPIENTRY glRasterPos2sv (const GLshort *v); +GLAPI void GLAPIENTRY glRasterPos3d (GLdouble x, GLdouble y, GLdouble z); +GLAPI void GLAPIENTRY glRasterPos3dv (const GLdouble *v); +GLAPI void GLAPIENTRY glRasterPos3f (GLfloat x, GLfloat y, GLfloat z); +GLAPI void GLAPIENTRY glRasterPos3fv (const GLfloat *v); +GLAPI void GLAPIENTRY glRasterPos3i (GLint x, GLint y, GLint z); +GLAPI void GLAPIENTRY glRasterPos3iv (const GLint *v); +GLAPI void GLAPIENTRY glRasterPos3s (GLshort x, GLshort y, GLshort z); +GLAPI void GLAPIENTRY glRasterPos3sv (const GLshort *v); +GLAPI void GLAPIENTRY glRasterPos4d (GLdouble x, GLdouble y, GLdouble z, GLdouble w); +GLAPI void GLAPIENTRY glRasterPos4dv (const GLdouble *v); +GLAPI void GLAPIENTRY glRasterPos4f (GLfloat x, GLfloat y, GLfloat z, GLfloat w); +GLAPI void GLAPIENTRY glRasterPos4fv (const GLfloat *v); +GLAPI void GLAPIENTRY glRasterPos4i (GLint x, GLint y, GLint z, GLint w); +GLAPI void GLAPIENTRY glRasterPos4iv (const GLint *v); +GLAPI void GLAPIENTRY glRasterPos4s (GLshort x, GLshort y, GLshort z, GLshort w); +GLAPI void GLAPIENTRY glRasterPos4sv (const GLshort *v); +GLAPI void GLAPIENTRY glReadBuffer (GLenum mode); +GLAPI void GLAPIENTRY glReadPixels (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *pixels); +GLAPI void GLAPIENTRY glRectd (GLdouble x1, GLdouble y1, GLdouble x2, GLdouble y2); +GLAPI void GLAPIENTRY glRectdv (const GLdouble *v1, const GLdouble *v2); +GLAPI void GLAPIENTRY glRectf (GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2); +GLAPI void GLAPIENTRY glRectfv (const GLfloat *v1, const GLfloat *v2); +GLAPI void GLAPIENTRY glRecti (GLint x1, GLint y1, GLint x2, GLint y2); +GLAPI void GLAPIENTRY glRectiv (const GLint *v1, const GLint *v2); +GLAPI void GLAPIENTRY glRects (GLshort x1, GLshort y1, GLshort x2, GLshort y2); +GLAPI void GLAPIENTRY glRectsv (const GLshort *v1, const GLshort *v2); +GLAPI GLint GLAPIENTRY glRenderMode (GLenum mode); +GLAPI void GLAPIENTRY glRotated (GLdouble angle, GLdouble x, GLdouble y, GLdouble z); +GLAPI void GLAPIENTRY glRotatef (GLfloat angle, GLfloat x, GLfloat y, GLfloat z); +GLAPI void GLAPIENTRY glScaled (GLdouble x, GLdouble y, GLdouble z); +GLAPI void GLAPIENTRY glScalef (GLfloat x, GLfloat y, GLfloat z); +GLAPI void GLAPIENTRY glScissor (GLint x, GLint y, GLsizei width, GLsizei height); +GLAPI void GLAPIENTRY glSelectBuffer (GLsizei size, GLuint *buffer); +GLAPI void GLAPIENTRY glShadeModel (GLenum mode); +GLAPI void GLAPIENTRY glStencilFunc (GLenum func, GLint ref, GLuint mask); +GLAPI void GLAPIENTRY glStencilMask (GLuint mask); +GLAPI void GLAPIENTRY glStencilOp (GLenum fail, GLenum zfail, GLenum zpass); +GLAPI void GLAPIENTRY glTexCoord1d (GLdouble s); +GLAPI void GLAPIENTRY glTexCoord1dv (const GLdouble *v); +GLAPI void GLAPIENTRY glTexCoord1f (GLfloat s); +GLAPI void GLAPIENTRY glTexCoord1fv (const GLfloat *v); +GLAPI void GLAPIENTRY glTexCoord1i (GLint s); +GLAPI void GLAPIENTRY glTexCoord1iv (const GLint *v); +GLAPI void GLAPIENTRY glTexCoord1s (GLshort s); +GLAPI void GLAPIENTRY glTexCoord1sv (const GLshort *v); +GLAPI void GLAPIENTRY glTexCoord2d (GLdouble s, GLdouble t); +GLAPI void GLAPIENTRY glTexCoord2dv (const GLdouble *v); +GLAPI void GLAPIENTRY glTexCoord2f (GLfloat s, GLfloat t); +GLAPI void GLAPIENTRY glTexCoord2fv (const GLfloat *v); +GLAPI void GLAPIENTRY glTexCoord2i (GLint s, GLint t); +GLAPI void GLAPIENTRY glTexCoord2iv (const GLint *v); +GLAPI void GLAPIENTRY glTexCoord2s (GLshort s, GLshort t); +GLAPI void GLAPIENTRY glTexCoord2sv (const GLshort *v); +GLAPI void GLAPIENTRY glTexCoord3d (GLdouble s, GLdouble t, GLdouble r); +GLAPI void GLAPIENTRY glTexCoord3dv (const GLdouble *v); +GLAPI void GLAPIENTRY glTexCoord3f (GLfloat s, GLfloat t, GLfloat r); +GLAPI void GLAPIENTRY glTexCoord3fv (const GLfloat *v); +GLAPI void GLAPIENTRY glTexCoord3i (GLint s, GLint t, GLint r); +GLAPI void GLAPIENTRY glTexCoord3iv (const GLint *v); +GLAPI void GLAPIENTRY glTexCoord3s (GLshort s, GLshort t, GLshort r); +GLAPI void GLAPIENTRY glTexCoord3sv (const GLshort *v); +GLAPI void GLAPIENTRY glTexCoord4d (GLdouble s, GLdouble t, GLdouble r, GLdouble q); +GLAPI void GLAPIENTRY glTexCoord4dv (const GLdouble *v); +GLAPI void GLAPIENTRY glTexCoord4f (GLfloat s, GLfloat t, GLfloat r, GLfloat q); +GLAPI void GLAPIENTRY glTexCoord4fv (const GLfloat *v); +GLAPI void GLAPIENTRY glTexCoord4i (GLint s, GLint t, GLint r, GLint q); +GLAPI void GLAPIENTRY glTexCoord4iv (const GLint *v); +GLAPI void GLAPIENTRY glTexCoord4s (GLshort s, GLshort t, GLshort r, GLshort q); +GLAPI void GLAPIENTRY glTexCoord4sv (const GLshort *v); +GLAPI void GLAPIENTRY glTexCoordPointer (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); +GLAPI void GLAPIENTRY glTexEnvf (GLenum target, GLenum pname, GLfloat param); +GLAPI void GLAPIENTRY glTexEnvfv (GLenum target, GLenum pname, const GLfloat *params); +GLAPI void GLAPIENTRY glTexEnvi (GLenum target, GLenum pname, GLint param); +GLAPI void GLAPIENTRY glTexEnviv (GLenum target, GLenum pname, const GLint *params); +GLAPI void GLAPIENTRY glTexGend (GLenum coord, GLenum pname, GLdouble param); +GLAPI void GLAPIENTRY glTexGendv (GLenum coord, GLenum pname, const GLdouble *params); +GLAPI void GLAPIENTRY glTexGenf (GLenum coord, GLenum pname, GLfloat param); +GLAPI void GLAPIENTRY glTexGenfv (GLenum coord, GLenum pname, const GLfloat *params); +GLAPI void GLAPIENTRY glTexGeni (GLenum coord, GLenum pname, GLint param); +GLAPI void GLAPIENTRY glTexGeniv (GLenum coord, GLenum pname, const GLint *params); +GLAPI void GLAPIENTRY glTexImage1D (GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *pixels); +GLAPI void GLAPIENTRY glTexImage2D (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels); +GLAPI void GLAPIENTRY glTexParameterf (GLenum target, GLenum pname, GLfloat param); +GLAPI void GLAPIENTRY glTexParameterfv (GLenum target, GLenum pname, const GLfloat *params); +GLAPI void GLAPIENTRY glTexParameteri (GLenum target, GLenum pname, GLint param); +GLAPI void GLAPIENTRY glTexParameteriv (GLenum target, GLenum pname, const GLint *params); +GLAPI void GLAPIENTRY glTexSubImage1D (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid *pixels); +GLAPI void GLAPIENTRY glTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels); +GLAPI void GLAPIENTRY glTranslated (GLdouble x, GLdouble y, GLdouble z); +GLAPI void GLAPIENTRY glTranslatef (GLfloat x, GLfloat y, GLfloat z); +GLAPI void GLAPIENTRY glVertex2d (GLdouble x, GLdouble y); +GLAPI void GLAPIENTRY glVertex2dv (const GLdouble *v); +GLAPI void GLAPIENTRY glVertex2f (GLfloat x, GLfloat y); +GLAPI void GLAPIENTRY glVertex2fv (const GLfloat *v); +GLAPI void GLAPIENTRY glVertex2i (GLint x, GLint y); +GLAPI void GLAPIENTRY glVertex2iv (const GLint *v); +GLAPI void GLAPIENTRY glVertex2s (GLshort x, GLshort y); +GLAPI void GLAPIENTRY glVertex2sv (const GLshort *v); +GLAPI void GLAPIENTRY glVertex3d (GLdouble x, GLdouble y, GLdouble z); +GLAPI void GLAPIENTRY glVertex3dv (const GLdouble *v); +GLAPI void GLAPIENTRY glVertex3f (GLfloat x, GLfloat y, GLfloat z); +GLAPI void GLAPIENTRY glVertex3fv (const GLfloat *v); +GLAPI void GLAPIENTRY glVertex3i (GLint x, GLint y, GLint z); +GLAPI void GLAPIENTRY glVertex3iv (const GLint *v); +GLAPI void GLAPIENTRY glVertex3s (GLshort x, GLshort y, GLshort z); +GLAPI void GLAPIENTRY glVertex3sv (const GLshort *v); +GLAPI void GLAPIENTRY glVertex4d (GLdouble x, GLdouble y, GLdouble z, GLdouble w); +GLAPI void GLAPIENTRY glVertex4dv (const GLdouble *v); +GLAPI void GLAPIENTRY glVertex4f (GLfloat x, GLfloat y, GLfloat z, GLfloat w); +GLAPI void GLAPIENTRY glVertex4fv (const GLfloat *v); +GLAPI void GLAPIENTRY glVertex4i (GLint x, GLint y, GLint z, GLint w); +GLAPI void GLAPIENTRY glVertex4iv (const GLint *v); +GLAPI void GLAPIENTRY glVertex4s (GLshort x, GLshort y, GLshort z, GLshort w); +GLAPI void GLAPIENTRY glVertex4sv (const GLshort *v); +GLAPI void GLAPIENTRY glVertexPointer (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); +GLAPI void GLAPIENTRY glViewport (GLint x, GLint y, GLsizei width, GLsizei height); + +#define GLEW_VERSION_1_1 GLEW_GET_VAR(__GLEW_VERSION_1_1) + +#endif /* GL_VERSION_1_1 */ + +/* ---------------------------------- GLU ---------------------------------- */ + +/* this is where we can safely include GLU */ +#if defined(__APPLE__) && defined(__MACH__) +#include +#else +#include +#endif + +/* ----------------------------- GL_VERSION_1_2 ---------------------------- */ + +#ifndef GL_VERSION_1_2 +#define GL_VERSION_1_2 1 + +#define GL_SMOOTH_POINT_SIZE_RANGE 0x0B12 +#define GL_SMOOTH_POINT_SIZE_GRANULARITY 0x0B13 +#define GL_SMOOTH_LINE_WIDTH_RANGE 0x0B22 +#define GL_SMOOTH_LINE_WIDTH_GRANULARITY 0x0B23 +#define GL_UNSIGNED_BYTE_3_3_2 0x8032 +#define GL_UNSIGNED_SHORT_4_4_4_4 0x8033 +#define GL_UNSIGNED_SHORT_5_5_5_1 0x8034 +#define GL_UNSIGNED_INT_8_8_8_8 0x8035 +#define GL_UNSIGNED_INT_10_10_10_2 0x8036 +#define GL_RESCALE_NORMAL 0x803A +#define GL_TEXTURE_BINDING_3D 0x806A +#define GL_PACK_SKIP_IMAGES 0x806B +#define GL_PACK_IMAGE_HEIGHT 0x806C +#define GL_UNPACK_SKIP_IMAGES 0x806D +#define GL_UNPACK_IMAGE_HEIGHT 0x806E +#define GL_TEXTURE_3D 0x806F +#define GL_PROXY_TEXTURE_3D 0x8070 +#define GL_TEXTURE_DEPTH 0x8071 +#define GL_TEXTURE_WRAP_R 0x8072 +#define GL_MAX_3D_TEXTURE_SIZE 0x8073 +#define GL_BGR 0x80E0 +#define GL_BGRA 0x80E1 +#define GL_MAX_ELEMENTS_VERTICES 0x80E8 +#define GL_MAX_ELEMENTS_INDICES 0x80E9 +#define GL_CLAMP_TO_EDGE 0x812F +#define GL_TEXTURE_MIN_LOD 0x813A +#define GL_TEXTURE_MAX_LOD 0x813B +#define GL_TEXTURE_BASE_LEVEL 0x813C +#define GL_TEXTURE_MAX_LEVEL 0x813D +#define GL_LIGHT_MODEL_COLOR_CONTROL 0x81F8 +#define GL_SINGLE_COLOR 0x81F9 +#define GL_SEPARATE_SPECULAR_COLOR 0x81FA +#define GL_UNSIGNED_BYTE_2_3_3_REV 0x8362 +#define GL_UNSIGNED_SHORT_5_6_5 0x8363 +#define GL_UNSIGNED_SHORT_5_6_5_REV 0x8364 +#define GL_UNSIGNED_SHORT_4_4_4_4_REV 0x8365 +#define GL_UNSIGNED_SHORT_1_5_5_5_REV 0x8366 +#define GL_UNSIGNED_INT_8_8_8_8_REV 0x8367 +#define GL_UNSIGNED_INT_2_10_10_10_REV 0x8368 +#define GL_ALIASED_POINT_SIZE_RANGE 0x846D +#define GL_ALIASED_LINE_WIDTH_RANGE 0x846E + +typedef void (GLAPIENTRY * PFNGLCOPYTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (GLAPIENTRY * PFNGLDRAWRANGEELEMENTSPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices); +typedef void (GLAPIENTRY * PFNGLTEXIMAGE3DPROC) (GLenum target, GLint level, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels); +typedef void (GLAPIENTRY * PFNGLTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels); + +#define glCopyTexSubImage3D GLEW_GET_FUN(__glewCopyTexSubImage3D) +#define glDrawRangeElements GLEW_GET_FUN(__glewDrawRangeElements) +#define glTexImage3D GLEW_GET_FUN(__glewTexImage3D) +#define glTexSubImage3D GLEW_GET_FUN(__glewTexSubImage3D) + +#define GLEW_VERSION_1_2 GLEW_GET_VAR(__GLEW_VERSION_1_2) + +#endif /* GL_VERSION_1_2 */ + +/* ----------------------------- GL_VERSION_1_3 ---------------------------- */ + +#ifndef GL_VERSION_1_3 +#define GL_VERSION_1_3 1 + +#define GL_MULTISAMPLE 0x809D +#define GL_SAMPLE_ALPHA_TO_COVERAGE 0x809E +#define GL_SAMPLE_ALPHA_TO_ONE 0x809F +#define GL_SAMPLE_COVERAGE 0x80A0 +#define GL_SAMPLE_BUFFERS 0x80A8 +#define GL_SAMPLES 0x80A9 +#define GL_SAMPLE_COVERAGE_VALUE 0x80AA +#define GL_SAMPLE_COVERAGE_INVERT 0x80AB +#define GL_CLAMP_TO_BORDER 0x812D +#define GL_TEXTURE0 0x84C0 +#define GL_TEXTURE1 0x84C1 +#define GL_TEXTURE2 0x84C2 +#define GL_TEXTURE3 0x84C3 +#define GL_TEXTURE4 0x84C4 +#define GL_TEXTURE5 0x84C5 +#define GL_TEXTURE6 0x84C6 +#define GL_TEXTURE7 0x84C7 +#define GL_TEXTURE8 0x84C8 +#define GL_TEXTURE9 0x84C9 +#define GL_TEXTURE10 0x84CA +#define GL_TEXTURE11 0x84CB +#define GL_TEXTURE12 0x84CC +#define GL_TEXTURE13 0x84CD +#define GL_TEXTURE14 0x84CE +#define GL_TEXTURE15 0x84CF +#define GL_TEXTURE16 0x84D0 +#define GL_TEXTURE17 0x84D1 +#define GL_TEXTURE18 0x84D2 +#define GL_TEXTURE19 0x84D3 +#define GL_TEXTURE20 0x84D4 +#define GL_TEXTURE21 0x84D5 +#define GL_TEXTURE22 0x84D6 +#define GL_TEXTURE23 0x84D7 +#define GL_TEXTURE24 0x84D8 +#define GL_TEXTURE25 0x84D9 +#define GL_TEXTURE26 0x84DA +#define GL_TEXTURE27 0x84DB +#define GL_TEXTURE28 0x84DC +#define GL_TEXTURE29 0x84DD +#define GL_TEXTURE30 0x84DE +#define GL_TEXTURE31 0x84DF +#define GL_ACTIVE_TEXTURE 0x84E0 +#define GL_CLIENT_ACTIVE_TEXTURE 0x84E1 +#define GL_MAX_TEXTURE_UNITS 0x84E2 +#define GL_TRANSPOSE_MODELVIEW_MATRIX 0x84E3 +#define GL_TRANSPOSE_PROJECTION_MATRIX 0x84E4 +#define GL_TRANSPOSE_TEXTURE_MATRIX 0x84E5 +#define GL_TRANSPOSE_COLOR_MATRIX 0x84E6 +#define GL_SUBTRACT 0x84E7 +#define GL_COMPRESSED_ALPHA 0x84E9 +#define GL_COMPRESSED_LUMINANCE 0x84EA +#define GL_COMPRESSED_LUMINANCE_ALPHA 0x84EB +#define GL_COMPRESSED_INTENSITY 0x84EC +#define GL_COMPRESSED_RGB 0x84ED +#define GL_COMPRESSED_RGBA 0x84EE +#define GL_TEXTURE_COMPRESSION_HINT 0x84EF +#define GL_NORMAL_MAP 0x8511 +#define GL_REFLECTION_MAP 0x8512 +#define GL_TEXTURE_CUBE_MAP 0x8513 +#define GL_TEXTURE_BINDING_CUBE_MAP 0x8514 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_X 0x8515 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X 0x8516 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y 0x8517 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y 0x8518 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z 0x8519 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z 0x851A +#define GL_PROXY_TEXTURE_CUBE_MAP 0x851B +#define GL_MAX_CUBE_MAP_TEXTURE_SIZE 0x851C +#define GL_COMBINE 0x8570 +#define GL_COMBINE_RGB 0x8571 +#define GL_COMBINE_ALPHA 0x8572 +#define GL_RGB_SCALE 0x8573 +#define GL_ADD_SIGNED 0x8574 +#define GL_INTERPOLATE 0x8575 +#define GL_CONSTANT 0x8576 +#define GL_PRIMARY_COLOR 0x8577 +#define GL_PREVIOUS 0x8578 +#define GL_SOURCE0_RGB 0x8580 +#define GL_SOURCE1_RGB 0x8581 +#define GL_SOURCE2_RGB 0x8582 +#define GL_SOURCE0_ALPHA 0x8588 +#define GL_SOURCE1_ALPHA 0x8589 +#define GL_SOURCE2_ALPHA 0x858A +#define GL_OPERAND0_RGB 0x8590 +#define GL_OPERAND1_RGB 0x8591 +#define GL_OPERAND2_RGB 0x8592 +#define GL_OPERAND0_ALPHA 0x8598 +#define GL_OPERAND1_ALPHA 0x8599 +#define GL_OPERAND2_ALPHA 0x859A +#define GL_TEXTURE_COMPRESSED_IMAGE_SIZE 0x86A0 +#define GL_TEXTURE_COMPRESSED 0x86A1 +#define GL_NUM_COMPRESSED_TEXTURE_FORMATS 0x86A2 +#define GL_COMPRESSED_TEXTURE_FORMATS 0x86A3 +#define GL_DOT3_RGB 0x86AE +#define GL_DOT3_RGBA 0x86AF +#define GL_MULTISAMPLE_BIT 0x20000000 + +typedef void (GLAPIENTRY * PFNGLACTIVETEXTUREPROC) (GLenum texture); +typedef void (GLAPIENTRY * PFNGLCLIENTACTIVETEXTUREPROC) (GLenum texture); +typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXIMAGE1DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid *data); +typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXIMAGE2DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data); +typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXIMAGE3DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *data); +typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC) (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid *data); +typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *data); +typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *data); +typedef void (GLAPIENTRY * PFNGLGETCOMPRESSEDTEXIMAGEPROC) (GLenum target, GLint lod, GLvoid *img); +typedef void (GLAPIENTRY * PFNGLLOADTRANSPOSEMATRIXDPROC) (const GLdouble m[16]); +typedef void (GLAPIENTRY * PFNGLLOADTRANSPOSEMATRIXFPROC) (const GLfloat m[16]); +typedef void (GLAPIENTRY * PFNGLMULTTRANSPOSEMATRIXDPROC) (const GLdouble m[16]); +typedef void (GLAPIENTRY * PFNGLMULTTRANSPOSEMATRIXFPROC) (const GLfloat m[16]); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1DPROC) (GLenum target, GLdouble s); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1DVPROC) (GLenum target, const GLdouble *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1FPROC) (GLenum target, GLfloat s); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1FVPROC) (GLenum target, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1IPROC) (GLenum target, GLint s); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1IVPROC) (GLenum target, const GLint *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1SPROC) (GLenum target, GLshort s); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1SVPROC) (GLenum target, const GLshort *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2DPROC) (GLenum target, GLdouble s, GLdouble t); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2DVPROC) (GLenum target, const GLdouble *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2FPROC) (GLenum target, GLfloat s, GLfloat t); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2FVPROC) (GLenum target, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2IPROC) (GLenum target, GLint s, GLint t); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2IVPROC) (GLenum target, const GLint *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2SPROC) (GLenum target, GLshort s, GLshort t); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2SVPROC) (GLenum target, const GLshort *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3DPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3DVPROC) (GLenum target, const GLdouble *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3FPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3FVPROC) (GLenum target, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3IPROC) (GLenum target, GLint s, GLint t, GLint r); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3IVPROC) (GLenum target, const GLint *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3SPROC) (GLenum target, GLshort s, GLshort t, GLshort r); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3SVPROC) (GLenum target, const GLshort *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4DPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4DVPROC) (GLenum target, const GLdouble *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4FPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4FVPROC) (GLenum target, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4IPROC) (GLenum target, GLint s, GLint t, GLint r, GLint q); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4IVPROC) (GLenum target, const GLint *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4SPROC) (GLenum target, GLshort s, GLshort t, GLshort r, GLshort q); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4SVPROC) (GLenum target, const GLshort *v); +typedef void (GLAPIENTRY * PFNGLSAMPLECOVERAGEPROC) (GLclampf value, GLboolean invert); + +#define glActiveTexture GLEW_GET_FUN(__glewActiveTexture) +#define glClientActiveTexture GLEW_GET_FUN(__glewClientActiveTexture) +#define glCompressedTexImage1D GLEW_GET_FUN(__glewCompressedTexImage1D) +#define glCompressedTexImage2D GLEW_GET_FUN(__glewCompressedTexImage2D) +#define glCompressedTexImage3D GLEW_GET_FUN(__glewCompressedTexImage3D) +#define glCompressedTexSubImage1D GLEW_GET_FUN(__glewCompressedTexSubImage1D) +#define glCompressedTexSubImage2D GLEW_GET_FUN(__glewCompressedTexSubImage2D) +#define glCompressedTexSubImage3D GLEW_GET_FUN(__glewCompressedTexSubImage3D) +#define glGetCompressedTexImage GLEW_GET_FUN(__glewGetCompressedTexImage) +#define glLoadTransposeMatrixd GLEW_GET_FUN(__glewLoadTransposeMatrixd) +#define glLoadTransposeMatrixf GLEW_GET_FUN(__glewLoadTransposeMatrixf) +#define glMultTransposeMatrixd GLEW_GET_FUN(__glewMultTransposeMatrixd) +#define glMultTransposeMatrixf GLEW_GET_FUN(__glewMultTransposeMatrixf) +#define glMultiTexCoord1d GLEW_GET_FUN(__glewMultiTexCoord1d) +#define glMultiTexCoord1dv GLEW_GET_FUN(__glewMultiTexCoord1dv) +#define glMultiTexCoord1f GLEW_GET_FUN(__glewMultiTexCoord1f) +#define glMultiTexCoord1fv GLEW_GET_FUN(__glewMultiTexCoord1fv) +#define glMultiTexCoord1i GLEW_GET_FUN(__glewMultiTexCoord1i) +#define glMultiTexCoord1iv GLEW_GET_FUN(__glewMultiTexCoord1iv) +#define glMultiTexCoord1s GLEW_GET_FUN(__glewMultiTexCoord1s) +#define glMultiTexCoord1sv GLEW_GET_FUN(__glewMultiTexCoord1sv) +#define glMultiTexCoord2d GLEW_GET_FUN(__glewMultiTexCoord2d) +#define glMultiTexCoord2dv GLEW_GET_FUN(__glewMultiTexCoord2dv) +#define glMultiTexCoord2f GLEW_GET_FUN(__glewMultiTexCoord2f) +#define glMultiTexCoord2fv GLEW_GET_FUN(__glewMultiTexCoord2fv) +#define glMultiTexCoord2i GLEW_GET_FUN(__glewMultiTexCoord2i) +#define glMultiTexCoord2iv GLEW_GET_FUN(__glewMultiTexCoord2iv) +#define glMultiTexCoord2s GLEW_GET_FUN(__glewMultiTexCoord2s) +#define glMultiTexCoord2sv GLEW_GET_FUN(__glewMultiTexCoord2sv) +#define glMultiTexCoord3d GLEW_GET_FUN(__glewMultiTexCoord3d) +#define glMultiTexCoord3dv GLEW_GET_FUN(__glewMultiTexCoord3dv) +#define glMultiTexCoord3f GLEW_GET_FUN(__glewMultiTexCoord3f) +#define glMultiTexCoord3fv GLEW_GET_FUN(__glewMultiTexCoord3fv) +#define glMultiTexCoord3i GLEW_GET_FUN(__glewMultiTexCoord3i) +#define glMultiTexCoord3iv GLEW_GET_FUN(__glewMultiTexCoord3iv) +#define glMultiTexCoord3s GLEW_GET_FUN(__glewMultiTexCoord3s) +#define glMultiTexCoord3sv GLEW_GET_FUN(__glewMultiTexCoord3sv) +#define glMultiTexCoord4d GLEW_GET_FUN(__glewMultiTexCoord4d) +#define glMultiTexCoord4dv GLEW_GET_FUN(__glewMultiTexCoord4dv) +#define glMultiTexCoord4f GLEW_GET_FUN(__glewMultiTexCoord4f) +#define glMultiTexCoord4fv GLEW_GET_FUN(__glewMultiTexCoord4fv) +#define glMultiTexCoord4i GLEW_GET_FUN(__glewMultiTexCoord4i) +#define glMultiTexCoord4iv GLEW_GET_FUN(__glewMultiTexCoord4iv) +#define glMultiTexCoord4s GLEW_GET_FUN(__glewMultiTexCoord4s) +#define glMultiTexCoord4sv GLEW_GET_FUN(__glewMultiTexCoord4sv) +#define glSampleCoverage GLEW_GET_FUN(__glewSampleCoverage) + +#define GLEW_VERSION_1_3 GLEW_GET_VAR(__GLEW_VERSION_1_3) + +#endif /* GL_VERSION_1_3 */ + +/* ----------------------------- GL_VERSION_1_4 ---------------------------- */ + +#ifndef GL_VERSION_1_4 +#define GL_VERSION_1_4 1 + +#define GL_BLEND_DST_RGB 0x80C8 +#define GL_BLEND_SRC_RGB 0x80C9 +#define GL_BLEND_DST_ALPHA 0x80CA +#define GL_BLEND_SRC_ALPHA 0x80CB +#define GL_POINT_SIZE_MIN 0x8126 +#define GL_POINT_SIZE_MAX 0x8127 +#define GL_POINT_FADE_THRESHOLD_SIZE 0x8128 +#define GL_POINT_DISTANCE_ATTENUATION 0x8129 +#define GL_GENERATE_MIPMAP 0x8191 +#define GL_GENERATE_MIPMAP_HINT 0x8192 +#define GL_DEPTH_COMPONENT16 0x81A5 +#define GL_DEPTH_COMPONENT24 0x81A6 +#define GL_DEPTH_COMPONENT32 0x81A7 +#define GL_MIRRORED_REPEAT 0x8370 +#define GL_FOG_COORDINATE_SOURCE 0x8450 +#define GL_FOG_COORDINATE 0x8451 +#define GL_FRAGMENT_DEPTH 0x8452 +#define GL_CURRENT_FOG_COORDINATE 0x8453 +#define GL_FOG_COORDINATE_ARRAY_TYPE 0x8454 +#define GL_FOG_COORDINATE_ARRAY_STRIDE 0x8455 +#define GL_FOG_COORDINATE_ARRAY_POINTER 0x8456 +#define GL_FOG_COORDINATE_ARRAY 0x8457 +#define GL_COLOR_SUM 0x8458 +#define GL_CURRENT_SECONDARY_COLOR 0x8459 +#define GL_SECONDARY_COLOR_ARRAY_SIZE 0x845A +#define GL_SECONDARY_COLOR_ARRAY_TYPE 0x845B +#define GL_SECONDARY_COLOR_ARRAY_STRIDE 0x845C +#define GL_SECONDARY_COLOR_ARRAY_POINTER 0x845D +#define GL_SECONDARY_COLOR_ARRAY 0x845E +#define GL_MAX_TEXTURE_LOD_BIAS 0x84FD +#define GL_TEXTURE_FILTER_CONTROL 0x8500 +#define GL_TEXTURE_LOD_BIAS 0x8501 +#define GL_INCR_WRAP 0x8507 +#define GL_DECR_WRAP 0x8508 +#define GL_TEXTURE_DEPTH_SIZE 0x884A +#define GL_DEPTH_TEXTURE_MODE 0x884B +#define GL_TEXTURE_COMPARE_MODE 0x884C +#define GL_TEXTURE_COMPARE_FUNC 0x884D +#define GL_COMPARE_R_TO_TEXTURE 0x884E + +typedef void (GLAPIENTRY * PFNGLBLENDCOLORPROC) (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha); +typedef void (GLAPIENTRY * PFNGLBLENDEQUATIONPROC) (GLenum mode); +typedef void (GLAPIENTRY * PFNGLBLENDFUNCSEPARATEPROC) (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha); +typedef void (GLAPIENTRY * PFNGLFOGCOORDPOINTERPROC) (GLenum type, GLsizei stride, const GLvoid *pointer); +typedef void (GLAPIENTRY * PFNGLFOGCOORDDPROC) (GLdouble coord); +typedef void (GLAPIENTRY * PFNGLFOGCOORDDVPROC) (const GLdouble *coord); +typedef void (GLAPIENTRY * PFNGLFOGCOORDFPROC) (GLfloat coord); +typedef void (GLAPIENTRY * PFNGLFOGCOORDFVPROC) (const GLfloat *coord); +typedef void (GLAPIENTRY * PFNGLMULTIDRAWARRAYSPROC) (GLenum mode, GLint *first, GLsizei *count, GLsizei primcount); +typedef void (GLAPIENTRY * PFNGLMULTIDRAWELEMENTSPROC) (GLenum mode, GLsizei *count, GLenum type, const GLvoid **indices, GLsizei primcount); +typedef void (GLAPIENTRY * PFNGLPOINTPARAMETERFPROC) (GLenum pname, GLfloat param); +typedef void (GLAPIENTRY * PFNGLPOINTPARAMETERFVPROC) (GLenum pname, GLfloat *params); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3BPROC) (GLbyte red, GLbyte green, GLbyte blue); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3BVPROC) (const GLbyte *v); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3DPROC) (GLdouble red, GLdouble green, GLdouble blue); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3DVPROC) (const GLdouble *v); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3FPROC) (GLfloat red, GLfloat green, GLfloat blue); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3FVPROC) (const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3IPROC) (GLint red, GLint green, GLint blue); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3IVPROC) (const GLint *v); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3SPROC) (GLshort red, GLshort green, GLshort blue); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3SVPROC) (const GLshort *v); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3UBPROC) (GLubyte red, GLubyte green, GLubyte blue); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3UBVPROC) (const GLubyte *v); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3UIPROC) (GLuint red, GLuint green, GLuint blue); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3UIVPROC) (const GLuint *v); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3USPROC) (GLushort red, GLushort green, GLushort blue); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3USVPROC) (const GLushort *v); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLORPOINTERPROC) (GLint size, GLenum type, GLsizei stride, GLvoid *pointer); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS2DPROC) (GLdouble x, GLdouble y); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS2DVPROC) (const GLdouble *p); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS2FPROC) (GLfloat x, GLfloat y); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS2FVPROC) (const GLfloat *p); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS2IPROC) (GLint x, GLint y); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS2IVPROC) (const GLint *p); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS2SPROC) (GLshort x, GLshort y); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS2SVPROC) (const GLshort *p); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS3DPROC) (GLdouble x, GLdouble y, GLdouble z); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS3DVPROC) (const GLdouble *p); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS3FPROC) (GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS3FVPROC) (const GLfloat *p); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS3IPROC) (GLint x, GLint y, GLint z); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS3IVPROC) (const GLint *p); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS3SPROC) (GLshort x, GLshort y, GLshort z); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS3SVPROC) (const GLshort *p); + +#define glBlendColor GLEW_GET_FUN(__glewBlendColor) +#define glBlendEquation GLEW_GET_FUN(__glewBlendEquation) +#define glBlendFuncSeparate GLEW_GET_FUN(__glewBlendFuncSeparate) +#define glFogCoordPointer GLEW_GET_FUN(__glewFogCoordPointer) +#define glFogCoordd GLEW_GET_FUN(__glewFogCoordd) +#define glFogCoorddv GLEW_GET_FUN(__glewFogCoorddv) +#define glFogCoordf GLEW_GET_FUN(__glewFogCoordf) +#define glFogCoordfv GLEW_GET_FUN(__glewFogCoordfv) +#define glMultiDrawArrays GLEW_GET_FUN(__glewMultiDrawArrays) +#define glMultiDrawElements GLEW_GET_FUN(__glewMultiDrawElements) +#define glPointParameterf GLEW_GET_FUN(__glewPointParameterf) +#define glPointParameterfv GLEW_GET_FUN(__glewPointParameterfv) +#define glSecondaryColor3b GLEW_GET_FUN(__glewSecondaryColor3b) +#define glSecondaryColor3bv GLEW_GET_FUN(__glewSecondaryColor3bv) +#define glSecondaryColor3d GLEW_GET_FUN(__glewSecondaryColor3d) +#define glSecondaryColor3dv GLEW_GET_FUN(__glewSecondaryColor3dv) +#define glSecondaryColor3f GLEW_GET_FUN(__glewSecondaryColor3f) +#define glSecondaryColor3fv GLEW_GET_FUN(__glewSecondaryColor3fv) +#define glSecondaryColor3i GLEW_GET_FUN(__glewSecondaryColor3i) +#define glSecondaryColor3iv GLEW_GET_FUN(__glewSecondaryColor3iv) +#define glSecondaryColor3s GLEW_GET_FUN(__glewSecondaryColor3s) +#define glSecondaryColor3sv GLEW_GET_FUN(__glewSecondaryColor3sv) +#define glSecondaryColor3ub GLEW_GET_FUN(__glewSecondaryColor3ub) +#define glSecondaryColor3ubv GLEW_GET_FUN(__glewSecondaryColor3ubv) +#define glSecondaryColor3ui GLEW_GET_FUN(__glewSecondaryColor3ui) +#define glSecondaryColor3uiv GLEW_GET_FUN(__glewSecondaryColor3uiv) +#define glSecondaryColor3us GLEW_GET_FUN(__glewSecondaryColor3us) +#define glSecondaryColor3usv GLEW_GET_FUN(__glewSecondaryColor3usv) +#define glSecondaryColorPointer GLEW_GET_FUN(__glewSecondaryColorPointer) +#define glWindowPos2d GLEW_GET_FUN(__glewWindowPos2d) +#define glWindowPos2dv GLEW_GET_FUN(__glewWindowPos2dv) +#define glWindowPos2f GLEW_GET_FUN(__glewWindowPos2f) +#define glWindowPos2fv GLEW_GET_FUN(__glewWindowPos2fv) +#define glWindowPos2i GLEW_GET_FUN(__glewWindowPos2i) +#define glWindowPos2iv GLEW_GET_FUN(__glewWindowPos2iv) +#define glWindowPos2s GLEW_GET_FUN(__glewWindowPos2s) +#define glWindowPos2sv GLEW_GET_FUN(__glewWindowPos2sv) +#define glWindowPos3d GLEW_GET_FUN(__glewWindowPos3d) +#define glWindowPos3dv GLEW_GET_FUN(__glewWindowPos3dv) +#define glWindowPos3f GLEW_GET_FUN(__glewWindowPos3f) +#define glWindowPos3fv GLEW_GET_FUN(__glewWindowPos3fv) +#define glWindowPos3i GLEW_GET_FUN(__glewWindowPos3i) +#define glWindowPos3iv GLEW_GET_FUN(__glewWindowPos3iv) +#define glWindowPos3s GLEW_GET_FUN(__glewWindowPos3s) +#define glWindowPos3sv GLEW_GET_FUN(__glewWindowPos3sv) + +#define GLEW_VERSION_1_4 GLEW_GET_VAR(__GLEW_VERSION_1_4) + +#endif /* GL_VERSION_1_4 */ + +/* ----------------------------- GL_VERSION_1_5 ---------------------------- */ + +#ifndef GL_VERSION_1_5 +#define GL_VERSION_1_5 1 + +#define GL_FOG_COORD_SRC GL_FOG_COORDINATE_SOURCE +#define GL_FOG_COORD GL_FOG_COORDINATE +#define GL_FOG_COORD_ARRAY GL_FOG_COORDINATE_ARRAY +#define GL_SRC0_RGB GL_SOURCE0_RGB +#define GL_FOG_COORD_ARRAY_POINTER GL_FOG_COORDINATE_ARRAY_POINTER +#define GL_FOG_COORD_ARRAY_TYPE GL_FOG_COORDINATE_ARRAY_TYPE +#define GL_SRC1_ALPHA GL_SOURCE1_ALPHA +#define GL_CURRENT_FOG_COORD GL_CURRENT_FOG_COORDINATE +#define GL_FOG_COORD_ARRAY_STRIDE GL_FOG_COORDINATE_ARRAY_STRIDE +#define GL_SRC0_ALPHA GL_SOURCE0_ALPHA +#define GL_SRC1_RGB GL_SOURCE1_RGB +#define GL_FOG_COORD_ARRAY_BUFFER_BINDING GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING +#define GL_SRC2_ALPHA GL_SOURCE2_ALPHA +#define GL_SRC2_RGB GL_SOURCE2_RGB +#define GL_BUFFER_SIZE 0x8764 +#define GL_BUFFER_USAGE 0x8765 +#define GL_QUERY_COUNTER_BITS 0x8864 +#define GL_CURRENT_QUERY 0x8865 +#define GL_QUERY_RESULT 0x8866 +#define GL_QUERY_RESULT_AVAILABLE 0x8867 +#define GL_ARRAY_BUFFER 0x8892 +#define GL_ELEMENT_ARRAY_BUFFER 0x8893 +#define GL_ARRAY_BUFFER_BINDING 0x8894 +#define GL_ELEMENT_ARRAY_BUFFER_BINDING 0x8895 +#define GL_VERTEX_ARRAY_BUFFER_BINDING 0x8896 +#define GL_NORMAL_ARRAY_BUFFER_BINDING 0x8897 +#define GL_COLOR_ARRAY_BUFFER_BINDING 0x8898 +#define GL_INDEX_ARRAY_BUFFER_BINDING 0x8899 +#define GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING 0x889A +#define GL_EDGE_FLAG_ARRAY_BUFFER_BINDING 0x889B +#define GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING 0x889C +#define GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING 0x889D +#define GL_WEIGHT_ARRAY_BUFFER_BINDING 0x889E +#define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING 0x889F +#define GL_READ_ONLY 0x88B8 +#define GL_WRITE_ONLY 0x88B9 +#define GL_READ_WRITE 0x88BA +#define GL_BUFFER_ACCESS 0x88BB +#define GL_BUFFER_MAPPED 0x88BC +#define GL_BUFFER_MAP_POINTER 0x88BD +#define GL_STREAM_DRAW 0x88E0 +#define GL_STREAM_READ 0x88E1 +#define GL_STREAM_COPY 0x88E2 +#define GL_STATIC_DRAW 0x88E4 +#define GL_STATIC_READ 0x88E5 +#define GL_STATIC_COPY 0x88E6 +#define GL_DYNAMIC_DRAW 0x88E8 +#define GL_DYNAMIC_READ 0x88E9 +#define GL_DYNAMIC_COPY 0x88EA +#define GL_SAMPLES_PASSED 0x8914 + +typedef ptrdiff_t GLsizeiptr; +typedef ptrdiff_t GLintptr; + +typedef void (GLAPIENTRY * PFNGLBEGINQUERYPROC) (GLenum target, GLuint id); +typedef void (GLAPIENTRY * PFNGLBINDBUFFERPROC) (GLenum target, GLuint buffer); +typedef void (GLAPIENTRY * PFNGLBUFFERDATAPROC) (GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage); +typedef void (GLAPIENTRY * PFNGLBUFFERSUBDATAPROC) (GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data); +typedef void (GLAPIENTRY * PFNGLDELETEBUFFERSPROC) (GLsizei n, const GLuint* buffers); +typedef void (GLAPIENTRY * PFNGLDELETEQUERIESPROC) (GLsizei n, const GLuint* ids); +typedef void (GLAPIENTRY * PFNGLENDQUERYPROC) (GLenum target); +typedef void (GLAPIENTRY * PFNGLGENBUFFERSPROC) (GLsizei n, GLuint* buffers); +typedef void (GLAPIENTRY * PFNGLGENQUERIESPROC) (GLsizei n, GLuint* ids); +typedef void (GLAPIENTRY * PFNGLGETBUFFERPARAMETERIVPROC) (GLenum target, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETBUFFERPOINTERVPROC) (GLenum target, GLenum pname, GLvoid** params); +typedef void (GLAPIENTRY * PFNGLGETBUFFERSUBDATAPROC) (GLenum target, GLintptr offset, GLsizeiptr size, GLvoid* data); +typedef void (GLAPIENTRY * PFNGLGETQUERYOBJECTIVPROC) (GLuint id, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETQUERYOBJECTUIVPROC) (GLuint id, GLenum pname, GLuint* params); +typedef void (GLAPIENTRY * PFNGLGETQUERYIVPROC) (GLenum target, GLenum pname, GLint* params); +typedef GLboolean (GLAPIENTRY * PFNGLISBUFFERPROC) (GLuint buffer); +typedef GLboolean (GLAPIENTRY * PFNGLISQUERYPROC) (GLuint id); +typedef GLvoid* (GLAPIENTRY * PFNGLMAPBUFFERPROC) (GLenum target, GLenum access); +typedef GLboolean (GLAPIENTRY * PFNGLUNMAPBUFFERPROC) (GLenum target); + +#define glBeginQuery GLEW_GET_FUN(__glewBeginQuery) +#define glBindBuffer GLEW_GET_FUN(__glewBindBuffer) +#define glBufferData GLEW_GET_FUN(__glewBufferData) +#define glBufferSubData GLEW_GET_FUN(__glewBufferSubData) +#define glDeleteBuffers GLEW_GET_FUN(__glewDeleteBuffers) +#define glDeleteQueries GLEW_GET_FUN(__glewDeleteQueries) +#define glEndQuery GLEW_GET_FUN(__glewEndQuery) +#define glGenBuffers GLEW_GET_FUN(__glewGenBuffers) +#define glGenQueries GLEW_GET_FUN(__glewGenQueries) +#define glGetBufferParameteriv GLEW_GET_FUN(__glewGetBufferParameteriv) +#define glGetBufferPointerv GLEW_GET_FUN(__glewGetBufferPointerv) +#define glGetBufferSubData GLEW_GET_FUN(__glewGetBufferSubData) +#define glGetQueryObjectiv GLEW_GET_FUN(__glewGetQueryObjectiv) +#define glGetQueryObjectuiv GLEW_GET_FUN(__glewGetQueryObjectuiv) +#define glGetQueryiv GLEW_GET_FUN(__glewGetQueryiv) +#define glIsBuffer GLEW_GET_FUN(__glewIsBuffer) +#define glIsQuery GLEW_GET_FUN(__glewIsQuery) +#define glMapBuffer GLEW_GET_FUN(__glewMapBuffer) +#define glUnmapBuffer GLEW_GET_FUN(__glewUnmapBuffer) + +#define GLEW_VERSION_1_5 GLEW_GET_VAR(__GLEW_VERSION_1_5) + +#endif /* GL_VERSION_1_5 */ + +/* ----------------------------- GL_VERSION_2_0 ---------------------------- */ + +#ifndef GL_VERSION_2_0 +#define GL_VERSION_2_0 1 + +#define GL_BLEND_EQUATION_RGB GL_BLEND_EQUATION +#define GL_VERTEX_ATTRIB_ARRAY_ENABLED 0x8622 +#define GL_VERTEX_ATTRIB_ARRAY_SIZE 0x8623 +#define GL_VERTEX_ATTRIB_ARRAY_STRIDE 0x8624 +#define GL_VERTEX_ATTRIB_ARRAY_TYPE 0x8625 +#define GL_CURRENT_VERTEX_ATTRIB 0x8626 +#define GL_VERTEX_PROGRAM_POINT_SIZE 0x8642 +#define GL_VERTEX_PROGRAM_TWO_SIDE 0x8643 +#define GL_VERTEX_ATTRIB_ARRAY_POINTER 0x8645 +#define GL_STENCIL_BACK_FUNC 0x8800 +#define GL_STENCIL_BACK_FAIL 0x8801 +#define GL_STENCIL_BACK_PASS_DEPTH_FAIL 0x8802 +#define GL_STENCIL_BACK_PASS_DEPTH_PASS 0x8803 +#define GL_MAX_DRAW_BUFFERS 0x8824 +#define GL_DRAW_BUFFER0 0x8825 +#define GL_DRAW_BUFFER1 0x8826 +#define GL_DRAW_BUFFER2 0x8827 +#define GL_DRAW_BUFFER3 0x8828 +#define GL_DRAW_BUFFER4 0x8829 +#define GL_DRAW_BUFFER5 0x882A +#define GL_DRAW_BUFFER6 0x882B +#define GL_DRAW_BUFFER7 0x882C +#define GL_DRAW_BUFFER8 0x882D +#define GL_DRAW_BUFFER9 0x882E +#define GL_DRAW_BUFFER10 0x882F +#define GL_DRAW_BUFFER11 0x8830 +#define GL_DRAW_BUFFER12 0x8831 +#define GL_DRAW_BUFFER13 0x8832 +#define GL_DRAW_BUFFER14 0x8833 +#define GL_DRAW_BUFFER15 0x8834 +#define GL_BLEND_EQUATION_ALPHA 0x883D +#define GL_POINT_SPRITE 0x8861 +#define GL_COORD_REPLACE 0x8862 +#define GL_MAX_VERTEX_ATTRIBS 0x8869 +#define GL_VERTEX_ATTRIB_ARRAY_NORMALIZED 0x886A +#define GL_MAX_TEXTURE_COORDS 0x8871 +#define GL_MAX_TEXTURE_IMAGE_UNITS 0x8872 +#define GL_FRAGMENT_SHADER 0x8B30 +#define GL_VERTEX_SHADER 0x8B31 +#define GL_MAX_FRAGMENT_UNIFORM_COMPONENTS 0x8B49 +#define GL_MAX_VERTEX_UNIFORM_COMPONENTS 0x8B4A +#define GL_MAX_VARYING_FLOATS 0x8B4B +#define GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS 0x8B4C +#define GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS 0x8B4D +#define GL_SHADER_TYPE 0x8B4F +#define GL_FLOAT_VEC2 0x8B50 +#define GL_FLOAT_VEC3 0x8B51 +#define GL_FLOAT_VEC4 0x8B52 +#define GL_INT_VEC2 0x8B53 +#define GL_INT_VEC3 0x8B54 +#define GL_INT_VEC4 0x8B55 +#define GL_BOOL 0x8B56 +#define GL_BOOL_VEC2 0x8B57 +#define GL_BOOL_VEC3 0x8B58 +#define GL_BOOL_VEC4 0x8B59 +#define GL_FLOAT_MAT2 0x8B5A +#define GL_FLOAT_MAT3 0x8B5B +#define GL_FLOAT_MAT4 0x8B5C +#define GL_SAMPLER_1D 0x8B5D +#define GL_SAMPLER_2D 0x8B5E +#define GL_SAMPLER_3D 0x8B5F +#define GL_SAMPLER_CUBE 0x8B60 +#define GL_SAMPLER_1D_SHADOW 0x8B61 +#define GL_SAMPLER_2D_SHADOW 0x8B62 +#define GL_DELETE_STATUS 0x8B80 +#define GL_COMPILE_STATUS 0x8B81 +#define GL_LINK_STATUS 0x8B82 +#define GL_VALIDATE_STATUS 0x8B83 +#define GL_INFO_LOG_LENGTH 0x8B84 +#define GL_ATTACHED_SHADERS 0x8B85 +#define GL_ACTIVE_UNIFORMS 0x8B86 +#define GL_ACTIVE_UNIFORM_MAX_LENGTH 0x8B87 +#define GL_SHADER_SOURCE_LENGTH 0x8B88 +#define GL_ACTIVE_ATTRIBUTES 0x8B89 +#define GL_ACTIVE_ATTRIBUTE_MAX_LENGTH 0x8B8A +#define GL_FRAGMENT_SHADER_DERIVATIVE_HINT 0x8B8B +#define GL_SHADING_LANGUAGE_VERSION 0x8B8C +#define GL_CURRENT_PROGRAM 0x8B8D +#define GL_POINT_SPRITE_COORD_ORIGIN 0x8CA0 +#define GL_LOWER_LEFT 0x8CA1 +#define GL_UPPER_LEFT 0x8CA2 +#define GL_STENCIL_BACK_REF 0x8CA3 +#define GL_STENCIL_BACK_VALUE_MASK 0x8CA4 +#define GL_STENCIL_BACK_WRITEMASK 0x8CA5 + +typedef char GLchar; + +typedef void (GLAPIENTRY * PFNGLATTACHSHADERPROC) (GLuint program, GLuint shader); +typedef void (GLAPIENTRY * PFNGLBINDATTRIBLOCATIONPROC) (GLuint program, GLuint index, const GLchar* name); +typedef void (GLAPIENTRY * PFNGLBLENDEQUATIONSEPARATEPROC) (GLenum, GLenum); +typedef void (GLAPIENTRY * PFNGLCOMPILESHADERPROC) (GLuint shader); +typedef GLuint (GLAPIENTRY * PFNGLCREATEPROGRAMPROC) (void); +typedef GLuint (GLAPIENTRY * PFNGLCREATESHADERPROC) (GLenum type); +typedef void (GLAPIENTRY * PFNGLDELETEPROGRAMPROC) (GLuint program); +typedef void (GLAPIENTRY * PFNGLDELETESHADERPROC) (GLuint shader); +typedef void (GLAPIENTRY * PFNGLDETACHSHADERPROC) (GLuint program, GLuint shader); +typedef void (GLAPIENTRY * PFNGLDISABLEVERTEXATTRIBARRAYPROC) (GLuint); +typedef void (GLAPIENTRY * PFNGLDRAWBUFFERSPROC) (GLsizei n, const GLenum* bufs); +typedef void (GLAPIENTRY * PFNGLENABLEVERTEXATTRIBARRAYPROC) (GLuint); +typedef void (GLAPIENTRY * PFNGLGETACTIVEATTRIBPROC) (GLuint program, GLuint index, GLsizei maxLength, GLsizei* length, GLint* size, GLenum* type, GLchar* name); +typedef void (GLAPIENTRY * PFNGLGETACTIVEUNIFORMPROC) (GLuint program, GLuint index, GLsizei maxLength, GLsizei* length, GLint* size, GLenum* type, GLchar* name); +typedef void (GLAPIENTRY * PFNGLGETATTACHEDSHADERSPROC) (GLuint program, GLsizei maxCount, GLsizei* count, GLuint* shaders); +typedef GLint (GLAPIENTRY * PFNGLGETATTRIBLOCATIONPROC) (GLuint program, const GLchar* name); +typedef void (GLAPIENTRY * PFNGLGETPROGRAMINFOLOGPROC) (GLuint program, GLsizei bufSize, GLsizei* length, GLchar* infoLog); +typedef void (GLAPIENTRY * PFNGLGETPROGRAMIVPROC) (GLuint program, GLenum pname, GLint* param); +typedef void (GLAPIENTRY * PFNGLGETSHADERINFOLOGPROC) (GLuint shader, GLsizei bufSize, GLsizei* length, GLchar* infoLog); +typedef void (GLAPIENTRY * PFNGLGETSHADERSOURCEPROC) (GLint obj, GLsizei maxLength, GLsizei* length, GLchar* source); +typedef void (GLAPIENTRY * PFNGLGETSHADERIVPROC) (GLuint shader, GLenum pname, GLint* param); +typedef GLint (GLAPIENTRY * PFNGLGETUNIFORMLOCATIONPROC) (GLint programObj, const GLchar* name); +typedef void (GLAPIENTRY * PFNGLGETUNIFORMFVPROC) (GLuint program, GLint location, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETUNIFORMIVPROC) (GLuint program, GLint location, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBPOINTERVPROC) (GLuint, GLenum, GLvoid*); +typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBDVPROC) (GLuint, GLenum, GLdouble*); +typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBFVPROC) (GLuint, GLenum, GLfloat*); +typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBIVPROC) (GLuint, GLenum, GLint*); +typedef GLboolean (GLAPIENTRY * PFNGLISPROGRAMPROC) (GLuint program); +typedef GLboolean (GLAPIENTRY * PFNGLISSHADERPROC) (GLuint shader); +typedef void (GLAPIENTRY * PFNGLLINKPROGRAMPROC) (GLuint program); +typedef void (GLAPIENTRY * PFNGLSHADERSOURCEPROC) (GLuint shader, GLsizei count, const GLchar** strings, const GLint* lengths); +typedef void (GLAPIENTRY * PFNGLSTENCILFUNCSEPARATEPROC) (GLenum frontfunc, GLenum backfunc, GLint ref, GLuint mask); +typedef void (GLAPIENTRY * PFNGLSTENCILMASKSEPARATEPROC) (GLenum, GLuint); +typedef void (GLAPIENTRY * PFNGLSTENCILOPSEPARATEPROC) (GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass); +typedef void (GLAPIENTRY * PFNGLUNIFORM1FPROC) (GLint location, GLfloat v0); +typedef void (GLAPIENTRY * PFNGLUNIFORM1FVPROC) (GLint location, GLsizei count, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLUNIFORM1IPROC) (GLint location, GLint v0); +typedef void (GLAPIENTRY * PFNGLUNIFORM1IVPROC) (GLint location, GLsizei count, const GLint* value); +typedef void (GLAPIENTRY * PFNGLUNIFORM2FPROC) (GLint location, GLfloat v0, GLfloat v1); +typedef void (GLAPIENTRY * PFNGLUNIFORM2FVPROC) (GLint location, GLsizei count, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLUNIFORM2IPROC) (GLint location, GLint v0, GLint v1); +typedef void (GLAPIENTRY * PFNGLUNIFORM2IVPROC) (GLint location, GLsizei count, const GLint* value); +typedef void (GLAPIENTRY * PFNGLUNIFORM3FPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2); +typedef void (GLAPIENTRY * PFNGLUNIFORM3FVPROC) (GLint location, GLsizei count, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLUNIFORM3IPROC) (GLint location, GLint v0, GLint v1, GLint v2); +typedef void (GLAPIENTRY * PFNGLUNIFORM3IVPROC) (GLint location, GLsizei count, const GLint* value); +typedef void (GLAPIENTRY * PFNGLUNIFORM4FPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); +typedef void (GLAPIENTRY * PFNGLUNIFORM4FVPROC) (GLint location, GLsizei count, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLUNIFORM4IPROC) (GLint location, GLint v0, GLint v1, GLint v2, GLint v3); +typedef void (GLAPIENTRY * PFNGLUNIFORM4IVPROC) (GLint location, GLsizei count, const GLint* value); +typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX2FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX3FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX4FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLUSEPROGRAMPROC) (GLuint program); +typedef void (GLAPIENTRY * PFNGLVALIDATEPROGRAMPROC) (GLuint program); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1DPROC) (GLuint index, GLdouble x); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1DVPROC) (GLuint index, const GLdouble* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1FPROC) (GLuint index, GLfloat x); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1FVPROC) (GLuint index, const GLfloat* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1SPROC) (GLuint index, GLshort x); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1SVPROC) (GLuint index, const GLshort* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2DPROC) (GLuint index, GLdouble x, GLdouble y); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2DVPROC) (GLuint index, const GLdouble* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2FPROC) (GLuint index, GLfloat x, GLfloat y); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2FVPROC) (GLuint index, const GLfloat* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2SPROC) (GLuint index, GLshort x, GLshort y); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2SVPROC) (GLuint index, const GLshort* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3DPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3DVPROC) (GLuint index, const GLdouble* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3FPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3FVPROC) (GLuint index, const GLfloat* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3SPROC) (GLuint index, GLshort x, GLshort y, GLshort z); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3SVPROC) (GLuint index, const GLshort* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4NBVPROC) (GLuint index, const GLbyte* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4NIVPROC) (GLuint index, const GLint* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4NSVPROC) (GLuint index, const GLshort* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4NUBPROC) (GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4NUBVPROC) (GLuint index, const GLubyte* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4NUIVPROC) (GLuint index, const GLuint* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4NUSVPROC) (GLuint index, const GLushort* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4BVPROC) (GLuint index, const GLbyte* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4DPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4DVPROC) (GLuint index, const GLdouble* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4FPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4FVPROC) (GLuint index, const GLfloat* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4IVPROC) (GLuint index, const GLint* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4SPROC) (GLuint index, GLshort x, GLshort y, GLshort z, GLshort w); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4SVPROC) (GLuint index, const GLshort* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4UBVPROC) (GLuint index, const GLubyte* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4UIVPROC) (GLuint index, const GLuint* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4USVPROC) (GLuint index, const GLushort* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBPOINTERPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* pointer); + +#define glAttachShader GLEW_GET_FUN(__glewAttachShader) +#define glBindAttribLocation GLEW_GET_FUN(__glewBindAttribLocation) +#define glBlendEquationSeparate GLEW_GET_FUN(__glewBlendEquationSeparate) +#define glCompileShader GLEW_GET_FUN(__glewCompileShader) +#define glCreateProgram GLEW_GET_FUN(__glewCreateProgram) +#define glCreateShader GLEW_GET_FUN(__glewCreateShader) +#define glDeleteProgram GLEW_GET_FUN(__glewDeleteProgram) +#define glDeleteShader GLEW_GET_FUN(__glewDeleteShader) +#define glDetachShader GLEW_GET_FUN(__glewDetachShader) +#define glDisableVertexAttribArray GLEW_GET_FUN(__glewDisableVertexAttribArray) +#define glDrawBuffers GLEW_GET_FUN(__glewDrawBuffers) +#define glEnableVertexAttribArray GLEW_GET_FUN(__glewEnableVertexAttribArray) +#define glGetActiveAttrib GLEW_GET_FUN(__glewGetActiveAttrib) +#define glGetActiveUniform GLEW_GET_FUN(__glewGetActiveUniform) +#define glGetAttachedShaders GLEW_GET_FUN(__glewGetAttachedShaders) +#define glGetAttribLocation GLEW_GET_FUN(__glewGetAttribLocation) +#define glGetProgramInfoLog GLEW_GET_FUN(__glewGetProgramInfoLog) +#define glGetProgramiv GLEW_GET_FUN(__glewGetProgramiv) +#define glGetShaderInfoLog GLEW_GET_FUN(__glewGetShaderInfoLog) +#define glGetShaderSource GLEW_GET_FUN(__glewGetShaderSource) +#define glGetShaderiv GLEW_GET_FUN(__glewGetShaderiv) +#define glGetUniformLocation GLEW_GET_FUN(__glewGetUniformLocation) +#define glGetUniformfv GLEW_GET_FUN(__glewGetUniformfv) +#define glGetUniformiv GLEW_GET_FUN(__glewGetUniformiv) +#define glGetVertexAttribPointerv GLEW_GET_FUN(__glewGetVertexAttribPointerv) +#define glGetVertexAttribdv GLEW_GET_FUN(__glewGetVertexAttribdv) +#define glGetVertexAttribfv GLEW_GET_FUN(__glewGetVertexAttribfv) +#define glGetVertexAttribiv GLEW_GET_FUN(__glewGetVertexAttribiv) +#define glIsProgram GLEW_GET_FUN(__glewIsProgram) +#define glIsShader GLEW_GET_FUN(__glewIsShader) +#define glLinkProgram GLEW_GET_FUN(__glewLinkProgram) +#define glShaderSource GLEW_GET_FUN(__glewShaderSource) +#define glStencilFuncSeparate GLEW_GET_FUN(__glewStencilFuncSeparate) +#define glStencilMaskSeparate GLEW_GET_FUN(__glewStencilMaskSeparate) +#define glStencilOpSeparate GLEW_GET_FUN(__glewStencilOpSeparate) +#define glUniform1f GLEW_GET_FUN(__glewUniform1f) +#define glUniform1fv GLEW_GET_FUN(__glewUniform1fv) +#define glUniform1i GLEW_GET_FUN(__glewUniform1i) +#define glUniform1iv GLEW_GET_FUN(__glewUniform1iv) +#define glUniform2f GLEW_GET_FUN(__glewUniform2f) +#define glUniform2fv GLEW_GET_FUN(__glewUniform2fv) +#define glUniform2i GLEW_GET_FUN(__glewUniform2i) +#define glUniform2iv GLEW_GET_FUN(__glewUniform2iv) +#define glUniform3f GLEW_GET_FUN(__glewUniform3f) +#define glUniform3fv GLEW_GET_FUN(__glewUniform3fv) +#define glUniform3i GLEW_GET_FUN(__glewUniform3i) +#define glUniform3iv GLEW_GET_FUN(__glewUniform3iv) +#define glUniform4f GLEW_GET_FUN(__glewUniform4f) +#define glUniform4fv GLEW_GET_FUN(__glewUniform4fv) +#define glUniform4i GLEW_GET_FUN(__glewUniform4i) +#define glUniform4iv GLEW_GET_FUN(__glewUniform4iv) +#define glUniformMatrix2fv GLEW_GET_FUN(__glewUniformMatrix2fv) +#define glUniformMatrix3fv GLEW_GET_FUN(__glewUniformMatrix3fv) +#define glUniformMatrix4fv GLEW_GET_FUN(__glewUniformMatrix4fv) +#define glUseProgram GLEW_GET_FUN(__glewUseProgram) +#define glValidateProgram GLEW_GET_FUN(__glewValidateProgram) +#define glVertexAttrib1d GLEW_GET_FUN(__glewVertexAttrib1d) +#define glVertexAttrib1dv GLEW_GET_FUN(__glewVertexAttrib1dv) +#define glVertexAttrib1f GLEW_GET_FUN(__glewVertexAttrib1f) +#define glVertexAttrib1fv GLEW_GET_FUN(__glewVertexAttrib1fv) +#define glVertexAttrib1s GLEW_GET_FUN(__glewVertexAttrib1s) +#define glVertexAttrib1sv GLEW_GET_FUN(__glewVertexAttrib1sv) +#define glVertexAttrib2d GLEW_GET_FUN(__glewVertexAttrib2d) +#define glVertexAttrib2dv GLEW_GET_FUN(__glewVertexAttrib2dv) +#define glVertexAttrib2f GLEW_GET_FUN(__glewVertexAttrib2f) +#define glVertexAttrib2fv GLEW_GET_FUN(__glewVertexAttrib2fv) +#define glVertexAttrib2s GLEW_GET_FUN(__glewVertexAttrib2s) +#define glVertexAttrib2sv GLEW_GET_FUN(__glewVertexAttrib2sv) +#define glVertexAttrib3d GLEW_GET_FUN(__glewVertexAttrib3d) +#define glVertexAttrib3dv GLEW_GET_FUN(__glewVertexAttrib3dv) +#define glVertexAttrib3f GLEW_GET_FUN(__glewVertexAttrib3f) +#define glVertexAttrib3fv GLEW_GET_FUN(__glewVertexAttrib3fv) +#define glVertexAttrib3s GLEW_GET_FUN(__glewVertexAttrib3s) +#define glVertexAttrib3sv GLEW_GET_FUN(__glewVertexAttrib3sv) +#define glVertexAttrib4Nbv GLEW_GET_FUN(__glewVertexAttrib4Nbv) +#define glVertexAttrib4Niv GLEW_GET_FUN(__glewVertexAttrib4Niv) +#define glVertexAttrib4Nsv GLEW_GET_FUN(__glewVertexAttrib4Nsv) +#define glVertexAttrib4Nub GLEW_GET_FUN(__glewVertexAttrib4Nub) +#define glVertexAttrib4Nubv GLEW_GET_FUN(__glewVertexAttrib4Nubv) +#define glVertexAttrib4Nuiv GLEW_GET_FUN(__glewVertexAttrib4Nuiv) +#define glVertexAttrib4Nusv GLEW_GET_FUN(__glewVertexAttrib4Nusv) +#define glVertexAttrib4bv GLEW_GET_FUN(__glewVertexAttrib4bv) +#define glVertexAttrib4d GLEW_GET_FUN(__glewVertexAttrib4d) +#define glVertexAttrib4dv GLEW_GET_FUN(__glewVertexAttrib4dv) +#define glVertexAttrib4f GLEW_GET_FUN(__glewVertexAttrib4f) +#define glVertexAttrib4fv GLEW_GET_FUN(__glewVertexAttrib4fv) +#define glVertexAttrib4iv GLEW_GET_FUN(__glewVertexAttrib4iv) +#define glVertexAttrib4s GLEW_GET_FUN(__glewVertexAttrib4s) +#define glVertexAttrib4sv GLEW_GET_FUN(__glewVertexAttrib4sv) +#define glVertexAttrib4ubv GLEW_GET_FUN(__glewVertexAttrib4ubv) +#define glVertexAttrib4uiv GLEW_GET_FUN(__glewVertexAttrib4uiv) +#define glVertexAttrib4usv GLEW_GET_FUN(__glewVertexAttrib4usv) +#define glVertexAttribPointer GLEW_GET_FUN(__glewVertexAttribPointer) + +#define GLEW_VERSION_2_0 GLEW_GET_VAR(__GLEW_VERSION_2_0) + +#endif /* GL_VERSION_2_0 */ + +/* -------------------------- GL_3DFX_multisample -------------------------- */ + +#ifndef GL_3DFX_multisample +#define GL_3DFX_multisample 1 + +#define GL_MULTISAMPLE_3DFX 0x86B2 +#define GL_SAMPLE_BUFFERS_3DFX 0x86B3 +#define GL_SAMPLES_3DFX 0x86B4 +#define GL_MULTISAMPLE_BIT_3DFX 0x20000000 + +#define GLEW_3DFX_multisample GLEW_GET_VAR(__GLEW_3DFX_multisample) + +#endif /* GL_3DFX_multisample */ + +/* ---------------------------- GL_3DFX_tbuffer ---------------------------- */ + +#ifndef GL_3DFX_tbuffer +#define GL_3DFX_tbuffer 1 + +typedef void (GLAPIENTRY * PFNGLTBUFFERMASK3DFXPROC) (GLuint mask); + +#define glTbufferMask3DFX GLEW_GET_FUN(__glewTbufferMask3DFX) + +#define GLEW_3DFX_tbuffer GLEW_GET_VAR(__GLEW_3DFX_tbuffer) + +#endif /* GL_3DFX_tbuffer */ + +/* -------------------- GL_3DFX_texture_compression_FXT1 ------------------- */ + +#ifndef GL_3DFX_texture_compression_FXT1 +#define GL_3DFX_texture_compression_FXT1 1 + +#define GL_COMPRESSED_RGB_FXT1_3DFX 0x86B0 +#define GL_COMPRESSED_RGBA_FXT1_3DFX 0x86B1 + +#define GLEW_3DFX_texture_compression_FXT1 GLEW_GET_VAR(__GLEW_3DFX_texture_compression_FXT1) + +#endif /* GL_3DFX_texture_compression_FXT1 */ + +/* ------------------------ GL_APPLE_client_storage ------------------------ */ + +#ifndef GL_APPLE_client_storage +#define GL_APPLE_client_storage 1 + +#define GL_UNPACK_CLIENT_STORAGE_APPLE 0x85B2 + +#define GLEW_APPLE_client_storage GLEW_GET_VAR(__GLEW_APPLE_client_storage) + +#endif /* GL_APPLE_client_storage */ + +/* ------------------------- GL_APPLE_element_array ------------------------ */ + +#ifndef GL_APPLE_element_array +#define GL_APPLE_element_array 1 + +#define GL_ELEMENT_ARRAY_APPLE 0x8768 +#define GL_ELEMENT_ARRAY_TYPE_APPLE 0x8769 +#define GL_ELEMENT_ARRAY_POINTER_APPLE 0x876A + +typedef void (GLAPIENTRY * PFNGLDRAWELEMENTARRAYAPPLEPROC) (GLenum mode, GLint first, GLsizei count); +typedef void (GLAPIENTRY * PFNGLDRAWRANGEELEMENTARRAYAPPLEPROC) (GLenum mode, GLuint start, GLuint end, GLint first, GLsizei count); +typedef void (GLAPIENTRY * PFNGLELEMENTPOINTERAPPLEPROC) (GLenum type, const void* pointer); +typedef void (GLAPIENTRY * PFNGLMULTIDRAWELEMENTARRAYAPPLEPROC) (GLenum mode, const GLint* first, const GLsizei *count, GLsizei primcount); +typedef void (GLAPIENTRY * PFNGLMULTIDRAWRANGEELEMENTARRAYAPPLEPROC) (GLenum mode, GLuint start, GLuint end, const GLint* first, const GLsizei *count, GLsizei primcount); + +#define glDrawElementArrayAPPLE GLEW_GET_FUN(__glewDrawElementArrayAPPLE) +#define glDrawRangeElementArrayAPPLE GLEW_GET_FUN(__glewDrawRangeElementArrayAPPLE) +#define glElementPointerAPPLE GLEW_GET_FUN(__glewElementPointerAPPLE) +#define glMultiDrawElementArrayAPPLE GLEW_GET_FUN(__glewMultiDrawElementArrayAPPLE) +#define glMultiDrawRangeElementArrayAPPLE GLEW_GET_FUN(__glewMultiDrawRangeElementArrayAPPLE) + +#define GLEW_APPLE_element_array GLEW_GET_VAR(__GLEW_APPLE_element_array) + +#endif /* GL_APPLE_element_array */ + +/* ----------------------------- GL_APPLE_fence ---------------------------- */ + +#ifndef GL_APPLE_fence +#define GL_APPLE_fence 1 + +#define GL_DRAW_PIXELS_APPLE 0x8A0A +#define GL_FENCE_APPLE 0x8A0B + +typedef void (GLAPIENTRY * PFNGLDELETEFENCESAPPLEPROC) (GLsizei n, const GLuint* fences); +typedef void (GLAPIENTRY * PFNGLFINISHFENCEAPPLEPROC) (GLuint fence); +typedef void (GLAPIENTRY * PFNGLFINISHOBJECTAPPLEPROC) (GLenum object, GLint name); +typedef void (GLAPIENTRY * PFNGLGENFENCESAPPLEPROC) (GLsizei n, GLuint* fences); +typedef GLboolean (GLAPIENTRY * PFNGLISFENCEAPPLEPROC) (GLuint fence); +typedef void (GLAPIENTRY * PFNGLSETFENCEAPPLEPROC) (GLuint fence); +typedef GLboolean (GLAPIENTRY * PFNGLTESTFENCEAPPLEPROC) (GLuint fence); +typedef GLboolean (GLAPIENTRY * PFNGLTESTOBJECTAPPLEPROC) (GLenum object, GLuint name); + +#define glDeleteFencesAPPLE GLEW_GET_FUN(__glewDeleteFencesAPPLE) +#define glFinishFenceAPPLE GLEW_GET_FUN(__glewFinishFenceAPPLE) +#define glFinishObjectAPPLE GLEW_GET_FUN(__glewFinishObjectAPPLE) +#define glGenFencesAPPLE GLEW_GET_FUN(__glewGenFencesAPPLE) +#define glIsFenceAPPLE GLEW_GET_FUN(__glewIsFenceAPPLE) +#define glSetFenceAPPLE GLEW_GET_FUN(__glewSetFenceAPPLE) +#define glTestFenceAPPLE GLEW_GET_FUN(__glewTestFenceAPPLE) +#define glTestObjectAPPLE GLEW_GET_FUN(__glewTestObjectAPPLE) + +#define GLEW_APPLE_fence GLEW_GET_VAR(__GLEW_APPLE_fence) + +#endif /* GL_APPLE_fence */ + +/* ------------------------- GL_APPLE_float_pixels ------------------------- */ + +#ifndef GL_APPLE_float_pixels +#define GL_APPLE_float_pixels 1 + +#define GL_HALF_APPLE 0x140B +#define GL_RGBA_FLOAT32_APPLE 0x8814 +#define GL_RGB_FLOAT32_APPLE 0x8815 +#define GL_ALPHA_FLOAT32_APPLE 0x8816 +#define GL_INTENSITY_FLOAT32_APPLE 0x8817 +#define GL_LUMINANCE_FLOAT32_APPLE 0x8818 +#define GL_LUMINANCE_ALPHA_FLOAT32_APPLE 0x8819 +#define GL_RGBA_FLOAT16_APPLE 0x881A +#define GL_RGB_FLOAT16_APPLE 0x881B +#define GL_ALPHA_FLOAT16_APPLE 0x881C +#define GL_INTENSITY_FLOAT16_APPLE 0x881D +#define GL_LUMINANCE_FLOAT16_APPLE 0x881E +#define GL_LUMINANCE_ALPHA_FLOAT16_APPLE 0x881F +#define GL_COLOR_FLOAT_APPLE 0x8A0F + +#define GLEW_APPLE_float_pixels GLEW_GET_VAR(__GLEW_APPLE_float_pixels) + +#endif /* GL_APPLE_float_pixels */ + +/* ------------------------- GL_APPLE_pixel_buffer ------------------------- */ + +#ifndef GL_APPLE_pixel_buffer +#define GL_APPLE_pixel_buffer 1 + +#define GL_MIN_PBUFFER_VIEWPORT_DIMS_APPLE 0x8A10 + +#define GLEW_APPLE_pixel_buffer GLEW_GET_VAR(__GLEW_APPLE_pixel_buffer) + +#endif /* GL_APPLE_pixel_buffer */ + +/* ------------------------ GL_APPLE_specular_vector ----------------------- */ + +#ifndef GL_APPLE_specular_vector +#define GL_APPLE_specular_vector 1 + +#define GL_LIGHT_MODEL_SPECULAR_VECTOR_APPLE 0x85B0 + +#define GLEW_APPLE_specular_vector GLEW_GET_VAR(__GLEW_APPLE_specular_vector) + +#endif /* GL_APPLE_specular_vector */ + +/* ------------------------- GL_APPLE_texture_range ------------------------ */ + +#ifndef GL_APPLE_texture_range +#define GL_APPLE_texture_range 1 + +#define GL_TEXTURE_RANGE_LENGTH_APPLE 0x85B7 +#define GL_TEXTURE_RANGE_POINTER_APPLE 0x85B8 +#define GL_TEXTURE_STORAGE_HINT_APPLE 0x85BC +#define GL_STORAGE_PRIVATE_APPLE 0x85BD +#define GL_STORAGE_CACHED_APPLE 0x85BE +#define GL_STORAGE_SHARED_APPLE 0x85BF + +typedef void (GLAPIENTRY * PFNGLGETTEXPARAMETERPOINTERVAPPLEPROC) (GLenum target, GLenum pname, GLvoid **params); +typedef void (GLAPIENTRY * PFNGLTEXTURERANGEAPPLEPROC) (GLenum target, GLsizei length, GLvoid *pointer); + +#define glGetTexParameterPointervAPPLE GLEW_GET_FUN(__glewGetTexParameterPointervAPPLE) +#define glTextureRangeAPPLE GLEW_GET_FUN(__glewTextureRangeAPPLE) + +#define GLEW_APPLE_texture_range GLEW_GET_VAR(__GLEW_APPLE_texture_range) + +#endif /* GL_APPLE_texture_range */ + +/* ------------------------ GL_APPLE_transform_hint ------------------------ */ + +#ifndef GL_APPLE_transform_hint +#define GL_APPLE_transform_hint 1 + +#define GL_TRANSFORM_HINT_APPLE 0x85B1 + +#define GLEW_APPLE_transform_hint GLEW_GET_VAR(__GLEW_APPLE_transform_hint) + +#endif /* GL_APPLE_transform_hint */ + +/* ---------------------- GL_APPLE_vertex_array_object --------------------- */ + +#ifndef GL_APPLE_vertex_array_object +#define GL_APPLE_vertex_array_object 1 + +#define GL_VERTEX_ARRAY_BINDING_APPLE 0x85B5 + +typedef void (GLAPIENTRY * PFNGLBINDVERTEXARRAYAPPLEPROC) (GLuint array); +typedef void (GLAPIENTRY * PFNGLDELETEVERTEXARRAYSAPPLEPROC) (GLsizei n, const GLuint* arrays); +typedef void (GLAPIENTRY * PFNGLGENVERTEXARRAYSAPPLEPROC) (GLsizei n, const GLuint* arrays); +typedef GLboolean (GLAPIENTRY * PFNGLISVERTEXARRAYAPPLEPROC) (GLuint array); + +#define glBindVertexArrayAPPLE GLEW_GET_FUN(__glewBindVertexArrayAPPLE) +#define glDeleteVertexArraysAPPLE GLEW_GET_FUN(__glewDeleteVertexArraysAPPLE) +#define glGenVertexArraysAPPLE GLEW_GET_FUN(__glewGenVertexArraysAPPLE) +#define glIsVertexArrayAPPLE GLEW_GET_FUN(__glewIsVertexArrayAPPLE) + +#define GLEW_APPLE_vertex_array_object GLEW_GET_VAR(__GLEW_APPLE_vertex_array_object) + +#endif /* GL_APPLE_vertex_array_object */ + +/* ---------------------- GL_APPLE_vertex_array_range ---------------------- */ + +#ifndef GL_APPLE_vertex_array_range +#define GL_APPLE_vertex_array_range 1 + +#define GL_VERTEX_ARRAY_RANGE_APPLE 0x851D +#define GL_VERTEX_ARRAY_RANGE_LENGTH_APPLE 0x851E +#define GL_VERTEX_ARRAY_STORAGE_HINT_APPLE 0x851F +#define GL_MAX_VERTEX_ARRAY_RANGE_ELEMENT_APPLE 0x8520 +#define GL_VERTEX_ARRAY_RANGE_POINTER_APPLE 0x8521 +#define GL_STORAGE_CACHED_APPLE 0x85BE +#define GL_STORAGE_SHARED_APPLE 0x85BF + +typedef void (GLAPIENTRY * PFNGLFLUSHVERTEXARRAYRANGEAPPLEPROC) (GLsizei length, void* pointer); +typedef void (GLAPIENTRY * PFNGLVERTEXARRAYPARAMETERIAPPLEPROC) (GLenum pname, GLint param); +typedef void (GLAPIENTRY * PFNGLVERTEXARRAYRANGEAPPLEPROC) (GLsizei length, void* pointer); + +#define glFlushVertexArrayRangeAPPLE GLEW_GET_FUN(__glewFlushVertexArrayRangeAPPLE) +#define glVertexArrayParameteriAPPLE GLEW_GET_FUN(__glewVertexArrayParameteriAPPLE) +#define glVertexArrayRangeAPPLE GLEW_GET_FUN(__glewVertexArrayRangeAPPLE) + +#define GLEW_APPLE_vertex_array_range GLEW_GET_VAR(__GLEW_APPLE_vertex_array_range) + +#endif /* GL_APPLE_vertex_array_range */ + +/* --------------------------- GL_APPLE_ycbcr_422 -------------------------- */ + +#ifndef GL_APPLE_ycbcr_422 +#define GL_APPLE_ycbcr_422 1 + +#define GL_YCBCR_422_APPLE 0x85B9 +#define GL_UNSIGNED_SHORT_8_8_APPLE 0x85BA +#define GL_UNSIGNED_SHORT_8_8_REV_APPLE 0x85BB + +#define GLEW_APPLE_ycbcr_422 GLEW_GET_VAR(__GLEW_APPLE_ycbcr_422) + +#endif /* GL_APPLE_ycbcr_422 */ + +/* ----------------------- GL_ARB_color_buffer_float ----------------------- */ + +#ifndef GL_ARB_color_buffer_float +#define GL_ARB_color_buffer_float 1 + +#define GL_RGBA_FLOAT_MODE_ARB 0x8820 +#define GL_CLAMP_VERTEX_COLOR_ARB 0x891A +#define GL_CLAMP_FRAGMENT_COLOR_ARB 0x891B +#define GL_CLAMP_READ_COLOR_ARB 0x891C +#define GL_FIXED_ONLY_ARB 0x891D + +typedef void (GLAPIENTRY * PFNGLCLAMPCOLORARBPROC) (GLenum target, GLenum clamp); + +#define glClampColorARB GLEW_GET_FUN(__glewClampColorARB) + +#define GLEW_ARB_color_buffer_float GLEW_GET_VAR(__GLEW_ARB_color_buffer_float) + +#endif /* GL_ARB_color_buffer_float */ + +/* -------------------------- GL_ARB_depth_texture ------------------------- */ + +#ifndef GL_ARB_depth_texture +#define GL_ARB_depth_texture 1 + +#define GL_DEPTH_COMPONENT16_ARB 0x81A5 +#define GL_DEPTH_COMPONENT24_ARB 0x81A6 +#define GL_DEPTH_COMPONENT32_ARB 0x81A7 +#define GL_TEXTURE_DEPTH_SIZE_ARB 0x884A +#define GL_DEPTH_TEXTURE_MODE_ARB 0x884B + +#define GLEW_ARB_depth_texture GLEW_GET_VAR(__GLEW_ARB_depth_texture) + +#endif /* GL_ARB_depth_texture */ + +/* -------------------------- GL_ARB_draw_buffers -------------------------- */ + +#ifndef GL_ARB_draw_buffers +#define GL_ARB_draw_buffers 1 + +#define GL_MAX_DRAW_BUFFERS_ARB 0x8824 +#define GL_DRAW_BUFFER0_ARB 0x8825 +#define GL_DRAW_BUFFER1_ARB 0x8826 +#define GL_DRAW_BUFFER2_ARB 0x8827 +#define GL_DRAW_BUFFER3_ARB 0x8828 +#define GL_DRAW_BUFFER4_ARB 0x8829 +#define GL_DRAW_BUFFER5_ARB 0x882A +#define GL_DRAW_BUFFER6_ARB 0x882B +#define GL_DRAW_BUFFER7_ARB 0x882C +#define GL_DRAW_BUFFER8_ARB 0x882D +#define GL_DRAW_BUFFER9_ARB 0x882E +#define GL_DRAW_BUFFER10_ARB 0x882F +#define GL_DRAW_BUFFER11_ARB 0x8830 +#define GL_DRAW_BUFFER12_ARB 0x8831 +#define GL_DRAW_BUFFER13_ARB 0x8832 +#define GL_DRAW_BUFFER14_ARB 0x8833 +#define GL_DRAW_BUFFER15_ARB 0x8834 + +typedef void (GLAPIENTRY * PFNGLDRAWBUFFERSARBPROC) (GLsizei n, const GLenum* bufs); + +#define glDrawBuffersARB GLEW_GET_FUN(__glewDrawBuffersARB) + +#define GLEW_ARB_draw_buffers GLEW_GET_VAR(__GLEW_ARB_draw_buffers) + +#endif /* GL_ARB_draw_buffers */ + +/* ------------------------ GL_ARB_fragment_program ------------------------ */ + +#ifndef GL_ARB_fragment_program +#define GL_ARB_fragment_program 1 + +#define GL_FRAGMENT_PROGRAM_ARB 0x8804 +#define GL_PROGRAM_ALU_INSTRUCTIONS_ARB 0x8805 +#define GL_PROGRAM_TEX_INSTRUCTIONS_ARB 0x8806 +#define GL_PROGRAM_TEX_INDIRECTIONS_ARB 0x8807 +#define GL_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB 0x8808 +#define GL_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB 0x8809 +#define GL_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB 0x880A +#define GL_MAX_PROGRAM_ALU_INSTRUCTIONS_ARB 0x880B +#define GL_MAX_PROGRAM_TEX_INSTRUCTIONS_ARB 0x880C +#define GL_MAX_PROGRAM_TEX_INDIRECTIONS_ARB 0x880D +#define GL_MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB 0x880E +#define GL_MAX_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB 0x880F +#define GL_MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB 0x8810 +#define GL_MAX_TEXTURE_COORDS_ARB 0x8871 +#define GL_MAX_TEXTURE_IMAGE_UNITS_ARB 0x8872 + +#define GLEW_ARB_fragment_program GLEW_GET_VAR(__GLEW_ARB_fragment_program) + +#endif /* GL_ARB_fragment_program */ + +/* --------------------- GL_ARB_fragment_program_shadow -------------------- */ + +#ifndef GL_ARB_fragment_program_shadow +#define GL_ARB_fragment_program_shadow 1 + +#define GLEW_ARB_fragment_program_shadow GLEW_GET_VAR(__GLEW_ARB_fragment_program_shadow) + +#endif /* GL_ARB_fragment_program_shadow */ + +/* ------------------------- GL_ARB_fragment_shader ------------------------ */ + +#ifndef GL_ARB_fragment_shader +#define GL_ARB_fragment_shader 1 + +#define GL_FRAGMENT_SHADER_ARB 0x8B30 +#define GL_MAX_FRAGMENT_UNIFORM_COMPONENTS_ARB 0x8B49 +#define GL_FRAGMENT_SHADER_DERIVATIVE_HINT_ARB 0x8B8B + +#define GLEW_ARB_fragment_shader GLEW_GET_VAR(__GLEW_ARB_fragment_shader) + +#endif /* GL_ARB_fragment_shader */ + +/* ------------------------ GL_ARB_half_float_pixel ------------------------ */ + +#ifndef GL_ARB_half_float_pixel +#define GL_ARB_half_float_pixel 1 + +#define GL_HALF_FLOAT_ARB 0x140B + +#define GLEW_ARB_half_float_pixel GLEW_GET_VAR(__GLEW_ARB_half_float_pixel) + +#endif /* GL_ARB_half_float_pixel */ + +/* ----------------------------- GL_ARB_imaging ---------------------------- */ + +#ifndef GL_ARB_imaging +#define GL_ARB_imaging 1 + +#define GL_CONSTANT_COLOR 0x8001 +#define GL_ONE_MINUS_CONSTANT_COLOR 0x8002 +#define GL_CONSTANT_ALPHA 0x8003 +#define GL_ONE_MINUS_CONSTANT_ALPHA 0x8004 +#define GL_BLEND_COLOR 0x8005 +#define GL_FUNC_ADD 0x8006 +#define GL_MIN 0x8007 +#define GL_MAX 0x8008 +#define GL_BLEND_EQUATION 0x8009 +#define GL_FUNC_SUBTRACT 0x800A +#define GL_FUNC_REVERSE_SUBTRACT 0x800B +#define GL_CONVOLUTION_1D 0x8010 +#define GL_CONVOLUTION_2D 0x8011 +#define GL_SEPARABLE_2D 0x8012 +#define GL_CONVOLUTION_BORDER_MODE 0x8013 +#define GL_CONVOLUTION_FILTER_SCALE 0x8014 +#define GL_CONVOLUTION_FILTER_BIAS 0x8015 +#define GL_REDUCE 0x8016 +#define GL_CONVOLUTION_FORMAT 0x8017 +#define GL_CONVOLUTION_WIDTH 0x8018 +#define GL_CONVOLUTION_HEIGHT 0x8019 +#define GL_MAX_CONVOLUTION_WIDTH 0x801A +#define GL_MAX_CONVOLUTION_HEIGHT 0x801B +#define GL_POST_CONVOLUTION_RED_SCALE 0x801C +#define GL_POST_CONVOLUTION_GREEN_SCALE 0x801D +#define GL_POST_CONVOLUTION_BLUE_SCALE 0x801E +#define GL_POST_CONVOLUTION_ALPHA_SCALE 0x801F +#define GL_POST_CONVOLUTION_RED_BIAS 0x8020 +#define GL_POST_CONVOLUTION_GREEN_BIAS 0x8021 +#define GL_POST_CONVOLUTION_BLUE_BIAS 0x8022 +#define GL_POST_CONVOLUTION_ALPHA_BIAS 0x8023 +#define GL_HISTOGRAM 0x8024 +#define GL_PROXY_HISTOGRAM 0x8025 +#define GL_HISTOGRAM_WIDTH 0x8026 +#define GL_HISTOGRAM_FORMAT 0x8027 +#define GL_HISTOGRAM_RED_SIZE 0x8028 +#define GL_HISTOGRAM_GREEN_SIZE 0x8029 +#define GL_HISTOGRAM_BLUE_SIZE 0x802A +#define GL_HISTOGRAM_ALPHA_SIZE 0x802B +#define GL_HISTOGRAM_LUMINANCE_SIZE 0x802C +#define GL_HISTOGRAM_SINK 0x802D +#define GL_MINMAX 0x802E +#define GL_MINMAX_FORMAT 0x802F +#define GL_MINMAX_SINK 0x8030 +#define GL_TABLE_TOO_LARGE 0x8031 +#define GL_COLOR_MATRIX 0x80B1 +#define GL_COLOR_MATRIX_STACK_DEPTH 0x80B2 +#define GL_MAX_COLOR_MATRIX_STACK_DEPTH 0x80B3 +#define GL_POST_COLOR_MATRIX_RED_SCALE 0x80B4 +#define GL_POST_COLOR_MATRIX_GREEN_SCALE 0x80B5 +#define GL_POST_COLOR_MATRIX_BLUE_SCALE 0x80B6 +#define GL_POST_COLOR_MATRIX_ALPHA_SCALE 0x80B7 +#define GL_POST_COLOR_MATRIX_RED_BIAS 0x80B8 +#define GL_POST_COLOR_MATRIX_GREEN_BIAS 0x80B9 +#define GL_POST_COLOR_MATRIX_BLUE_BIAS 0x80BA +#define GL_POST_COLOR_MATRIX_ALPHA_BIAS 0x80BB +#define GL_COLOR_TABLE 0x80D0 +#define GL_POST_CONVOLUTION_COLOR_TABLE 0x80D1 +#define GL_POST_COLOR_MATRIX_COLOR_TABLE 0x80D2 +#define GL_PROXY_COLOR_TABLE 0x80D3 +#define GL_PROXY_POST_CONVOLUTION_COLOR_TABLE 0x80D4 +#define GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE 0x80D5 +#define GL_COLOR_TABLE_SCALE 0x80D6 +#define GL_COLOR_TABLE_BIAS 0x80D7 +#define GL_COLOR_TABLE_FORMAT 0x80D8 +#define GL_COLOR_TABLE_WIDTH 0x80D9 +#define GL_COLOR_TABLE_RED_SIZE 0x80DA +#define GL_COLOR_TABLE_GREEN_SIZE 0x80DB +#define GL_COLOR_TABLE_BLUE_SIZE 0x80DC +#define GL_COLOR_TABLE_ALPHA_SIZE 0x80DD +#define GL_COLOR_TABLE_LUMINANCE_SIZE 0x80DE +#define GL_COLOR_TABLE_INTENSITY_SIZE 0x80DF +#define GL_IGNORE_BORDER 0x8150 +#define GL_CONSTANT_BORDER 0x8151 +#define GL_WRAP_BORDER 0x8152 +#define GL_REPLICATE_BORDER 0x8153 +#define GL_CONVOLUTION_BORDER_COLOR 0x8154 + +typedef void (GLAPIENTRY * PFNGLCOLORSUBTABLEPROC) (GLenum target, GLsizei start, GLsizei count, GLenum format, GLenum type, const GLvoid *data); +typedef void (GLAPIENTRY * PFNGLCOLORTABLEPROC) (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *table); +typedef void (GLAPIENTRY * PFNGLCOLORTABLEPARAMETERFVPROC) (GLenum target, GLenum pname, const GLfloat *params); +typedef void (GLAPIENTRY * PFNGLCOLORTABLEPARAMETERIVPROC) (GLenum target, GLenum pname, const GLint *params); +typedef void (GLAPIENTRY * PFNGLCONVOLUTIONFILTER1DPROC) (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *image); +typedef void (GLAPIENTRY * PFNGLCONVOLUTIONFILTER2DPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *image); +typedef void (GLAPIENTRY * PFNGLCONVOLUTIONPARAMETERFPROC) (GLenum target, GLenum pname, GLfloat params); +typedef void (GLAPIENTRY * PFNGLCONVOLUTIONPARAMETERFVPROC) (GLenum target, GLenum pname, const GLfloat *params); +typedef void (GLAPIENTRY * PFNGLCONVOLUTIONPARAMETERIPROC) (GLenum target, GLenum pname, GLint params); +typedef void (GLAPIENTRY * PFNGLCONVOLUTIONPARAMETERIVPROC) (GLenum target, GLenum pname, const GLint *params); +typedef void (GLAPIENTRY * PFNGLCOPYCOLORSUBTABLEPROC) (GLenum target, GLsizei start, GLint x, GLint y, GLsizei width); +typedef void (GLAPIENTRY * PFNGLCOPYCOLORTABLEPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); +typedef void (GLAPIENTRY * PFNGLCOPYCONVOLUTIONFILTER1DPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); +typedef void (GLAPIENTRY * PFNGLCOPYCONVOLUTIONFILTER2DPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (GLAPIENTRY * PFNGLGETCOLORTABLEPROC) (GLenum target, GLenum format, GLenum type, GLvoid *table); +typedef void (GLAPIENTRY * PFNGLGETCOLORTABLEPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params); +typedef void (GLAPIENTRY * PFNGLGETCOLORTABLEPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (GLAPIENTRY * PFNGLGETCONVOLUTIONFILTERPROC) (GLenum target, GLenum format, GLenum type, GLvoid *image); +typedef void (GLAPIENTRY * PFNGLGETCONVOLUTIONPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params); +typedef void (GLAPIENTRY * PFNGLGETCONVOLUTIONPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (GLAPIENTRY * PFNGLGETHISTOGRAMPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values); +typedef void (GLAPIENTRY * PFNGLGETHISTOGRAMPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params); +typedef void (GLAPIENTRY * PFNGLGETHISTOGRAMPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (GLAPIENTRY * PFNGLGETMINMAXPROC) (GLenum target, GLboolean reset, GLenum format, GLenum types, GLvoid *values); +typedef void (GLAPIENTRY * PFNGLGETMINMAXPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params); +typedef void (GLAPIENTRY * PFNGLGETMINMAXPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (GLAPIENTRY * PFNGLGETSEPARABLEFILTERPROC) (GLenum target, GLenum format, GLenum type, GLvoid *row, GLvoid *column, GLvoid *span); +typedef void (GLAPIENTRY * PFNGLHISTOGRAMPROC) (GLenum target, GLsizei width, GLenum internalformat, GLboolean sink); +typedef void (GLAPIENTRY * PFNGLMINMAXPROC) (GLenum target, GLenum internalformat, GLboolean sink); +typedef void (GLAPIENTRY * PFNGLRESETHISTOGRAMPROC) (GLenum target); +typedef void (GLAPIENTRY * PFNGLRESETMINMAXPROC) (GLenum target); +typedef void (GLAPIENTRY * PFNGLSEPARABLEFILTER2DPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *row, const GLvoid *column); + +#define glColorSubTable GLEW_GET_FUN(__glewColorSubTable) +#define glColorTable GLEW_GET_FUN(__glewColorTable) +#define glColorTableParameterfv GLEW_GET_FUN(__glewColorTableParameterfv) +#define glColorTableParameteriv GLEW_GET_FUN(__glewColorTableParameteriv) +#define glConvolutionFilter1D GLEW_GET_FUN(__glewConvolutionFilter1D) +#define glConvolutionFilter2D GLEW_GET_FUN(__glewConvolutionFilter2D) +#define glConvolutionParameterf GLEW_GET_FUN(__glewConvolutionParameterf) +#define glConvolutionParameterfv GLEW_GET_FUN(__glewConvolutionParameterfv) +#define glConvolutionParameteri GLEW_GET_FUN(__glewConvolutionParameteri) +#define glConvolutionParameteriv GLEW_GET_FUN(__glewConvolutionParameteriv) +#define glCopyColorSubTable GLEW_GET_FUN(__glewCopyColorSubTable) +#define glCopyColorTable GLEW_GET_FUN(__glewCopyColorTable) +#define glCopyConvolutionFilter1D GLEW_GET_FUN(__glewCopyConvolutionFilter1D) +#define glCopyConvolutionFilter2D GLEW_GET_FUN(__glewCopyConvolutionFilter2D) +#define glGetColorTable GLEW_GET_FUN(__glewGetColorTable) +#define glGetColorTableParameterfv GLEW_GET_FUN(__glewGetColorTableParameterfv) +#define glGetColorTableParameteriv GLEW_GET_FUN(__glewGetColorTableParameteriv) +#define glGetConvolutionFilter GLEW_GET_FUN(__glewGetConvolutionFilter) +#define glGetConvolutionParameterfv GLEW_GET_FUN(__glewGetConvolutionParameterfv) +#define glGetConvolutionParameteriv GLEW_GET_FUN(__glewGetConvolutionParameteriv) +#define glGetHistogram GLEW_GET_FUN(__glewGetHistogram) +#define glGetHistogramParameterfv GLEW_GET_FUN(__glewGetHistogramParameterfv) +#define glGetHistogramParameteriv GLEW_GET_FUN(__glewGetHistogramParameteriv) +#define glGetMinmax GLEW_GET_FUN(__glewGetMinmax) +#define glGetMinmaxParameterfv GLEW_GET_FUN(__glewGetMinmaxParameterfv) +#define glGetMinmaxParameteriv GLEW_GET_FUN(__glewGetMinmaxParameteriv) +#define glGetSeparableFilter GLEW_GET_FUN(__glewGetSeparableFilter) +#define glHistogram GLEW_GET_FUN(__glewHistogram) +#define glMinmax GLEW_GET_FUN(__glewMinmax) +#define glResetHistogram GLEW_GET_FUN(__glewResetHistogram) +#define glResetMinmax GLEW_GET_FUN(__glewResetMinmax) +#define glSeparableFilter2D GLEW_GET_FUN(__glewSeparableFilter2D) + +#define GLEW_ARB_imaging GLEW_GET_VAR(__GLEW_ARB_imaging) + +#endif /* GL_ARB_imaging */ + +/* ------------------------- GL_ARB_matrix_palette ------------------------- */ + +#ifndef GL_ARB_matrix_palette +#define GL_ARB_matrix_palette 1 + +#define GL_MATRIX_PALETTE_ARB 0x8840 +#define GL_MAX_MATRIX_PALETTE_STACK_DEPTH_ARB 0x8841 +#define GL_MAX_PALETTE_MATRICES_ARB 0x8842 +#define GL_CURRENT_PALETTE_MATRIX_ARB 0x8843 +#define GL_MATRIX_INDEX_ARRAY_ARB 0x8844 +#define GL_CURRENT_MATRIX_INDEX_ARB 0x8845 +#define GL_MATRIX_INDEX_ARRAY_SIZE_ARB 0x8846 +#define GL_MATRIX_INDEX_ARRAY_TYPE_ARB 0x8847 +#define GL_MATRIX_INDEX_ARRAY_STRIDE_ARB 0x8848 +#define GL_MATRIX_INDEX_ARRAY_POINTER_ARB 0x8849 + +typedef void (GLAPIENTRY * PFNGLCURRENTPALETTEMATRIXARBPROC) (GLint index); +typedef void (GLAPIENTRY * PFNGLMATRIXINDEXPOINTERARBPROC) (GLint size, GLenum type, GLsizei stride, GLvoid *pointer); +typedef void (GLAPIENTRY * PFNGLMATRIXINDEXUBVARBPROC) (GLint size, GLubyte *indices); +typedef void (GLAPIENTRY * PFNGLMATRIXINDEXUIVARBPROC) (GLint size, GLuint *indices); +typedef void (GLAPIENTRY * PFNGLMATRIXINDEXUSVARBPROC) (GLint size, GLushort *indices); + +#define glCurrentPaletteMatrixARB GLEW_GET_FUN(__glewCurrentPaletteMatrixARB) +#define glMatrixIndexPointerARB GLEW_GET_FUN(__glewMatrixIndexPointerARB) +#define glMatrixIndexubvARB GLEW_GET_FUN(__glewMatrixIndexubvARB) +#define glMatrixIndexuivARB GLEW_GET_FUN(__glewMatrixIndexuivARB) +#define glMatrixIndexusvARB GLEW_GET_FUN(__glewMatrixIndexusvARB) + +#define GLEW_ARB_matrix_palette GLEW_GET_VAR(__GLEW_ARB_matrix_palette) + +#endif /* GL_ARB_matrix_palette */ + +/* --------------------------- GL_ARB_multisample -------------------------- */ + +#ifndef GL_ARB_multisample +#define GL_ARB_multisample 1 + +#define GL_MULTISAMPLE_ARB 0x809D +#define GL_SAMPLE_ALPHA_TO_COVERAGE_ARB 0x809E +#define GL_SAMPLE_ALPHA_TO_ONE_ARB 0x809F +#define GL_SAMPLE_COVERAGE_ARB 0x80A0 +#define GL_SAMPLE_BUFFERS_ARB 0x80A8 +#define GL_SAMPLES_ARB 0x80A9 +#define GL_SAMPLE_COVERAGE_VALUE_ARB 0x80AA +#define GL_SAMPLE_COVERAGE_INVERT_ARB 0x80AB +#define GL_MULTISAMPLE_BIT_ARB 0x20000000 + +typedef void (GLAPIENTRY * PFNGLSAMPLECOVERAGEARBPROC) (GLclampf value, GLboolean invert); + +#define glSampleCoverageARB GLEW_GET_FUN(__glewSampleCoverageARB) + +#define GLEW_ARB_multisample GLEW_GET_VAR(__GLEW_ARB_multisample) + +#endif /* GL_ARB_multisample */ + +/* -------------------------- GL_ARB_multitexture -------------------------- */ + +#ifndef GL_ARB_multitexture +#define GL_ARB_multitexture 1 + +#define GL_TEXTURE0_ARB 0x84C0 +#define GL_TEXTURE1_ARB 0x84C1 +#define GL_TEXTURE2_ARB 0x84C2 +#define GL_TEXTURE3_ARB 0x84C3 +#define GL_TEXTURE4_ARB 0x84C4 +#define GL_TEXTURE5_ARB 0x84C5 +#define GL_TEXTURE6_ARB 0x84C6 +#define GL_TEXTURE7_ARB 0x84C7 +#define GL_TEXTURE8_ARB 0x84C8 +#define GL_TEXTURE9_ARB 0x84C9 +#define GL_TEXTURE10_ARB 0x84CA +#define GL_TEXTURE11_ARB 0x84CB +#define GL_TEXTURE12_ARB 0x84CC +#define GL_TEXTURE13_ARB 0x84CD +#define GL_TEXTURE14_ARB 0x84CE +#define GL_TEXTURE15_ARB 0x84CF +#define GL_TEXTURE16_ARB 0x84D0 +#define GL_TEXTURE17_ARB 0x84D1 +#define GL_TEXTURE18_ARB 0x84D2 +#define GL_TEXTURE19_ARB 0x84D3 +#define GL_TEXTURE20_ARB 0x84D4 +#define GL_TEXTURE21_ARB 0x84D5 +#define GL_TEXTURE22_ARB 0x84D6 +#define GL_TEXTURE23_ARB 0x84D7 +#define GL_TEXTURE24_ARB 0x84D8 +#define GL_TEXTURE25_ARB 0x84D9 +#define GL_TEXTURE26_ARB 0x84DA +#define GL_TEXTURE27_ARB 0x84DB +#define GL_TEXTURE28_ARB 0x84DC +#define GL_TEXTURE29_ARB 0x84DD +#define GL_TEXTURE30_ARB 0x84DE +#define GL_TEXTURE31_ARB 0x84DF +#define GL_ACTIVE_TEXTURE_ARB 0x84E0 +#define GL_CLIENT_ACTIVE_TEXTURE_ARB 0x84E1 +#define GL_MAX_TEXTURE_UNITS_ARB 0x84E2 + +typedef void (GLAPIENTRY * PFNGLACTIVETEXTUREARBPROC) (GLenum texture); +typedef void (GLAPIENTRY * PFNGLCLIENTACTIVETEXTUREARBPROC) (GLenum texture); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1DARBPROC) (GLenum target, GLdouble s); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1DVARBPROC) (GLenum target, const GLdouble *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1FARBPROC) (GLenum target, GLfloat s); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1FVARBPROC) (GLenum target, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1IARBPROC) (GLenum target, GLint s); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1IVARBPROC) (GLenum target, const GLint *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1SARBPROC) (GLenum target, GLshort s); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1SVARBPROC) (GLenum target, const GLshort *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2DARBPROC) (GLenum target, GLdouble s, GLdouble t); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2DVARBPROC) (GLenum target, const GLdouble *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2FARBPROC) (GLenum target, GLfloat s, GLfloat t); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2FVARBPROC) (GLenum target, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2IARBPROC) (GLenum target, GLint s, GLint t); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2IVARBPROC) (GLenum target, const GLint *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2SARBPROC) (GLenum target, GLshort s, GLshort t); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2SVARBPROC) (GLenum target, const GLshort *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3DARBPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3DVARBPROC) (GLenum target, const GLdouble *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3FARBPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3FVARBPROC) (GLenum target, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3IARBPROC) (GLenum target, GLint s, GLint t, GLint r); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3IVARBPROC) (GLenum target, const GLint *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3SARBPROC) (GLenum target, GLshort s, GLshort t, GLshort r); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3SVARBPROC) (GLenum target, const GLshort *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4DARBPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4DVARBPROC) (GLenum target, const GLdouble *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4FARBPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4FVARBPROC) (GLenum target, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4IARBPROC) (GLenum target, GLint s, GLint t, GLint r, GLint q); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4IVARBPROC) (GLenum target, const GLint *v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4SARBPROC) (GLenum target, GLshort s, GLshort t, GLshort r, GLshort q); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4SVARBPROC) (GLenum target, const GLshort *v); + +#define glActiveTextureARB GLEW_GET_FUN(__glewActiveTextureARB) +#define glClientActiveTextureARB GLEW_GET_FUN(__glewClientActiveTextureARB) +#define glMultiTexCoord1dARB GLEW_GET_FUN(__glewMultiTexCoord1dARB) +#define glMultiTexCoord1dvARB GLEW_GET_FUN(__glewMultiTexCoord1dvARB) +#define glMultiTexCoord1fARB GLEW_GET_FUN(__glewMultiTexCoord1fARB) +#define glMultiTexCoord1fvARB GLEW_GET_FUN(__glewMultiTexCoord1fvARB) +#define glMultiTexCoord1iARB GLEW_GET_FUN(__glewMultiTexCoord1iARB) +#define glMultiTexCoord1ivARB GLEW_GET_FUN(__glewMultiTexCoord1ivARB) +#define glMultiTexCoord1sARB GLEW_GET_FUN(__glewMultiTexCoord1sARB) +#define glMultiTexCoord1svARB GLEW_GET_FUN(__glewMultiTexCoord1svARB) +#define glMultiTexCoord2dARB GLEW_GET_FUN(__glewMultiTexCoord2dARB) +#define glMultiTexCoord2dvARB GLEW_GET_FUN(__glewMultiTexCoord2dvARB) +#define glMultiTexCoord2fARB GLEW_GET_FUN(__glewMultiTexCoord2fARB) +#define glMultiTexCoord2fvARB GLEW_GET_FUN(__glewMultiTexCoord2fvARB) +#define glMultiTexCoord2iARB GLEW_GET_FUN(__glewMultiTexCoord2iARB) +#define glMultiTexCoord2ivARB GLEW_GET_FUN(__glewMultiTexCoord2ivARB) +#define glMultiTexCoord2sARB GLEW_GET_FUN(__glewMultiTexCoord2sARB) +#define glMultiTexCoord2svARB GLEW_GET_FUN(__glewMultiTexCoord2svARB) +#define glMultiTexCoord3dARB GLEW_GET_FUN(__glewMultiTexCoord3dARB) +#define glMultiTexCoord3dvARB GLEW_GET_FUN(__glewMultiTexCoord3dvARB) +#define glMultiTexCoord3fARB GLEW_GET_FUN(__glewMultiTexCoord3fARB) +#define glMultiTexCoord3fvARB GLEW_GET_FUN(__glewMultiTexCoord3fvARB) +#define glMultiTexCoord3iARB GLEW_GET_FUN(__glewMultiTexCoord3iARB) +#define glMultiTexCoord3ivARB GLEW_GET_FUN(__glewMultiTexCoord3ivARB) +#define glMultiTexCoord3sARB GLEW_GET_FUN(__glewMultiTexCoord3sARB) +#define glMultiTexCoord3svARB GLEW_GET_FUN(__glewMultiTexCoord3svARB) +#define glMultiTexCoord4dARB GLEW_GET_FUN(__glewMultiTexCoord4dARB) +#define glMultiTexCoord4dvARB GLEW_GET_FUN(__glewMultiTexCoord4dvARB) +#define glMultiTexCoord4fARB GLEW_GET_FUN(__glewMultiTexCoord4fARB) +#define glMultiTexCoord4fvARB GLEW_GET_FUN(__glewMultiTexCoord4fvARB) +#define glMultiTexCoord4iARB GLEW_GET_FUN(__glewMultiTexCoord4iARB) +#define glMultiTexCoord4ivARB GLEW_GET_FUN(__glewMultiTexCoord4ivARB) +#define glMultiTexCoord4sARB GLEW_GET_FUN(__glewMultiTexCoord4sARB) +#define glMultiTexCoord4svARB GLEW_GET_FUN(__glewMultiTexCoord4svARB) + +#define GLEW_ARB_multitexture GLEW_GET_VAR(__GLEW_ARB_multitexture) + +#endif /* GL_ARB_multitexture */ + +/* ------------------------- GL_ARB_occlusion_query ------------------------ */ + +#ifndef GL_ARB_occlusion_query +#define GL_ARB_occlusion_query 1 + +#define GL_QUERY_COUNTER_BITS_ARB 0x8864 +#define GL_CURRENT_QUERY_ARB 0x8865 +#define GL_QUERY_RESULT_ARB 0x8866 +#define GL_QUERY_RESULT_AVAILABLE_ARB 0x8867 +#define GL_SAMPLES_PASSED_ARB 0x8914 + +typedef void (GLAPIENTRY * PFNGLBEGINQUERYARBPROC) (GLenum target, GLuint id); +typedef void (GLAPIENTRY * PFNGLDELETEQUERIESARBPROC) (GLsizei n, const GLuint* ids); +typedef void (GLAPIENTRY * PFNGLENDQUERYARBPROC) (GLenum target); +typedef void (GLAPIENTRY * PFNGLGENQUERIESARBPROC) (GLsizei n, GLuint* ids); +typedef void (GLAPIENTRY * PFNGLGETQUERYOBJECTIVARBPROC) (GLuint id, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETQUERYOBJECTUIVARBPROC) (GLuint id, GLenum pname, GLuint* params); +typedef void (GLAPIENTRY * PFNGLGETQUERYIVARBPROC) (GLenum target, GLenum pname, GLint* params); +typedef GLboolean (GLAPIENTRY * PFNGLISQUERYARBPROC) (GLuint id); + +#define glBeginQueryARB GLEW_GET_FUN(__glewBeginQueryARB) +#define glDeleteQueriesARB GLEW_GET_FUN(__glewDeleteQueriesARB) +#define glEndQueryARB GLEW_GET_FUN(__glewEndQueryARB) +#define glGenQueriesARB GLEW_GET_FUN(__glewGenQueriesARB) +#define glGetQueryObjectivARB GLEW_GET_FUN(__glewGetQueryObjectivARB) +#define glGetQueryObjectuivARB GLEW_GET_FUN(__glewGetQueryObjectuivARB) +#define glGetQueryivARB GLEW_GET_FUN(__glewGetQueryivARB) +#define glIsQueryARB GLEW_GET_FUN(__glewIsQueryARB) + +#define GLEW_ARB_occlusion_query GLEW_GET_VAR(__GLEW_ARB_occlusion_query) + +#endif /* GL_ARB_occlusion_query */ + +/* ----------------------- GL_ARB_pixel_buffer_object ---------------------- */ + +#ifndef GL_ARB_pixel_buffer_object +#define GL_ARB_pixel_buffer_object 1 + +#define GL_PIXEL_PACK_BUFFER_ARB 0x88EB +#define GL_PIXEL_UNPACK_BUFFER_ARB 0x88EC +#define GL_PIXEL_PACK_BUFFER_BINDING_ARB 0x88ED +#define GL_PIXEL_UNPACK_BUFFER_BINDING_ARB 0x88EF + +#define GLEW_ARB_pixel_buffer_object GLEW_GET_VAR(__GLEW_ARB_pixel_buffer_object) + +#endif /* GL_ARB_pixel_buffer_object */ + +/* ------------------------ GL_ARB_point_parameters ------------------------ */ + +#ifndef GL_ARB_point_parameters +#define GL_ARB_point_parameters 1 + +#define GL_POINT_SIZE_MIN_ARB 0x8126 +#define GL_POINT_SIZE_MAX_ARB 0x8127 +#define GL_POINT_FADE_THRESHOLD_SIZE_ARB 0x8128 +#define GL_POINT_DISTANCE_ATTENUATION_ARB 0x8129 + +typedef void (GLAPIENTRY * PFNGLPOINTPARAMETERFARBPROC) (GLenum pname, GLfloat param); +typedef void (GLAPIENTRY * PFNGLPOINTPARAMETERFVARBPROC) (GLenum pname, GLfloat* params); + +#define glPointParameterfARB GLEW_GET_FUN(__glewPointParameterfARB) +#define glPointParameterfvARB GLEW_GET_FUN(__glewPointParameterfvARB) + +#define GLEW_ARB_point_parameters GLEW_GET_VAR(__GLEW_ARB_point_parameters) + +#endif /* GL_ARB_point_parameters */ + +/* -------------------------- GL_ARB_point_sprite -------------------------- */ + +#ifndef GL_ARB_point_sprite +#define GL_ARB_point_sprite 1 + +#define GL_POINT_SPRITE_ARB 0x8861 +#define GL_COORD_REPLACE_ARB 0x8862 + +#define GLEW_ARB_point_sprite GLEW_GET_VAR(__GLEW_ARB_point_sprite) + +#endif /* GL_ARB_point_sprite */ + +/* ------------------------- GL_ARB_shader_objects ------------------------- */ + +#ifndef GL_ARB_shader_objects +#define GL_ARB_shader_objects 1 + +#define GL_PROGRAM_OBJECT_ARB 0x8B40 +#define GL_SHADER_OBJECT_ARB 0x8B48 +#define GL_OBJECT_TYPE_ARB 0x8B4E +#define GL_OBJECT_SUBTYPE_ARB 0x8B4F +#define GL_FLOAT_VEC2_ARB 0x8B50 +#define GL_FLOAT_VEC3_ARB 0x8B51 +#define GL_FLOAT_VEC4_ARB 0x8B52 +#define GL_INT_VEC2_ARB 0x8B53 +#define GL_INT_VEC3_ARB 0x8B54 +#define GL_INT_VEC4_ARB 0x8B55 +#define GL_BOOL_ARB 0x8B56 +#define GL_BOOL_VEC2_ARB 0x8B57 +#define GL_BOOL_VEC3_ARB 0x8B58 +#define GL_BOOL_VEC4_ARB 0x8B59 +#define GL_FLOAT_MAT2_ARB 0x8B5A +#define GL_FLOAT_MAT3_ARB 0x8B5B +#define GL_FLOAT_MAT4_ARB 0x8B5C +#define GL_SAMPLER_1D_ARB 0x8B5D +#define GL_SAMPLER_2D_ARB 0x8B5E +#define GL_SAMPLER_3D_ARB 0x8B5F +#define GL_SAMPLER_CUBE_ARB 0x8B60 +#define GL_SAMPLER_1D_SHADOW_ARB 0x8B61 +#define GL_SAMPLER_2D_SHADOW_ARB 0x8B62 +#define GL_SAMPLER_2D_RECT_ARB 0x8B63 +#define GL_SAMPLER_2D_RECT_SHADOW_ARB 0x8B64 +#define GL_OBJECT_DELETE_STATUS_ARB 0x8B80 +#define GL_OBJECT_COMPILE_STATUS_ARB 0x8B81 +#define GL_OBJECT_LINK_STATUS_ARB 0x8B82 +#define GL_OBJECT_VALIDATE_STATUS_ARB 0x8B83 +#define GL_OBJECT_INFO_LOG_LENGTH_ARB 0x8B84 +#define GL_OBJECT_ATTACHED_OBJECTS_ARB 0x8B85 +#define GL_OBJECT_ACTIVE_UNIFORMS_ARB 0x8B86 +#define GL_OBJECT_ACTIVE_UNIFORM_MAX_LENGTH_ARB 0x8B87 +#define GL_OBJECT_SHADER_SOURCE_LENGTH_ARB 0x8B88 + +typedef char GLcharARB; +typedef unsigned int GLhandleARB; + +typedef void (GLAPIENTRY * PFNGLATTACHOBJECTARBPROC) (GLhandleARB containerObj, GLhandleARB obj); +typedef void (GLAPIENTRY * PFNGLCOMPILESHADERARBPROC) (GLhandleARB shaderObj); +typedef GLhandleARB (GLAPIENTRY * PFNGLCREATEPROGRAMOBJECTARBPROC) (void); +typedef GLhandleARB (GLAPIENTRY * PFNGLCREATESHADEROBJECTARBPROC) (GLenum shaderType); +typedef void (GLAPIENTRY * PFNGLDELETEOBJECTARBPROC) (GLhandleARB obj); +typedef void (GLAPIENTRY * PFNGLDETACHOBJECTARBPROC) (GLhandleARB containerObj, GLhandleARB attachedObj); +typedef void (GLAPIENTRY * PFNGLGETACTIVEUNIFORMARBPROC) (GLhandleARB programObj, GLuint index, GLsizei maxLength, GLsizei* length, GLint *size, GLenum *type, GLcharARB *name); +typedef void (GLAPIENTRY * PFNGLGETATTACHEDOBJECTSARBPROC) (GLhandleARB containerObj, GLsizei maxCount, GLsizei* count, GLhandleARB *obj); +typedef GLhandleARB (GLAPIENTRY * PFNGLGETHANDLEARBPROC) (GLenum pname); +typedef void (GLAPIENTRY * PFNGLGETINFOLOGARBPROC) (GLhandleARB obj, GLsizei maxLength, GLsizei* length, GLcharARB *infoLog); +typedef void (GLAPIENTRY * PFNGLGETOBJECTPARAMETERFVARBPROC) (GLhandleARB obj, GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETOBJECTPARAMETERIVARBPROC) (GLhandleARB obj, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETSHADERSOURCEARBPROC) (GLhandleARB obj, GLsizei maxLength, GLsizei* length, GLcharARB *source); +typedef GLint (GLAPIENTRY * PFNGLGETUNIFORMLOCATIONARBPROC) (GLhandleARB programObj, const GLcharARB* name); +typedef void (GLAPIENTRY * PFNGLGETUNIFORMFVARBPROC) (GLhandleARB programObj, GLint location, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETUNIFORMIVARBPROC) (GLhandleARB programObj, GLint location, GLint* params); +typedef void (GLAPIENTRY * PFNGLLINKPROGRAMARBPROC) (GLhandleARB programObj); +typedef void (GLAPIENTRY * PFNGLSHADERSOURCEARBPROC) (GLhandleARB shaderObj, GLsizei count, const GLcharARB ** string, const GLint *length); +typedef void (GLAPIENTRY * PFNGLUNIFORM1FARBPROC) (GLint location, GLfloat v0); +typedef void (GLAPIENTRY * PFNGLUNIFORM1FVARBPROC) (GLint location, GLsizei count, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLUNIFORM1IARBPROC) (GLint location, GLint v0); +typedef void (GLAPIENTRY * PFNGLUNIFORM1IVARBPROC) (GLint location, GLsizei count, const GLint* value); +typedef void (GLAPIENTRY * PFNGLUNIFORM2FARBPROC) (GLint location, GLfloat v0, GLfloat v1); +typedef void (GLAPIENTRY * PFNGLUNIFORM2FVARBPROC) (GLint location, GLsizei count, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLUNIFORM2IARBPROC) (GLint location, GLint v0, GLint v1); +typedef void (GLAPIENTRY * PFNGLUNIFORM2IVARBPROC) (GLint location, GLsizei count, const GLint* value); +typedef void (GLAPIENTRY * PFNGLUNIFORM3FARBPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2); +typedef void (GLAPIENTRY * PFNGLUNIFORM3FVARBPROC) (GLint location, GLsizei count, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLUNIFORM3IARBPROC) (GLint location, GLint v0, GLint v1, GLint v2); +typedef void (GLAPIENTRY * PFNGLUNIFORM3IVARBPROC) (GLint location, GLsizei count, const GLint* value); +typedef void (GLAPIENTRY * PFNGLUNIFORM4FARBPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); +typedef void (GLAPIENTRY * PFNGLUNIFORM4FVARBPROC) (GLint location, GLsizei count, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLUNIFORM4IARBPROC) (GLint location, GLint v0, GLint v1, GLint v2, GLint v3); +typedef void (GLAPIENTRY * PFNGLUNIFORM4IVARBPROC) (GLint location, GLsizei count, const GLint* value); +typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX2FVARBPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX3FVARBPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX4FVARBPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +typedef void (GLAPIENTRY * PFNGLUSEPROGRAMOBJECTARBPROC) (GLhandleARB programObj); +typedef void (GLAPIENTRY * PFNGLVALIDATEPROGRAMARBPROC) (GLhandleARB programObj); + +#define glAttachObjectARB GLEW_GET_FUN(__glewAttachObjectARB) +#define glCompileShaderARB GLEW_GET_FUN(__glewCompileShaderARB) +#define glCreateProgramObjectARB GLEW_GET_FUN(__glewCreateProgramObjectARB) +#define glCreateShaderObjectARB GLEW_GET_FUN(__glewCreateShaderObjectARB) +#define glDeleteObjectARB GLEW_GET_FUN(__glewDeleteObjectARB) +#define glDetachObjectARB GLEW_GET_FUN(__glewDetachObjectARB) +#define glGetActiveUniformARB GLEW_GET_FUN(__glewGetActiveUniformARB) +#define glGetAttachedObjectsARB GLEW_GET_FUN(__glewGetAttachedObjectsARB) +#define glGetHandleARB GLEW_GET_FUN(__glewGetHandleARB) +#define glGetInfoLogARB GLEW_GET_FUN(__glewGetInfoLogARB) +#define glGetObjectParameterfvARB GLEW_GET_FUN(__glewGetObjectParameterfvARB) +#define glGetObjectParameterivARB GLEW_GET_FUN(__glewGetObjectParameterivARB) +#define glGetShaderSourceARB GLEW_GET_FUN(__glewGetShaderSourceARB) +#define glGetUniformLocationARB GLEW_GET_FUN(__glewGetUniformLocationARB) +#define glGetUniformfvARB GLEW_GET_FUN(__glewGetUniformfvARB) +#define glGetUniformivARB GLEW_GET_FUN(__glewGetUniformivARB) +#define glLinkProgramARB GLEW_GET_FUN(__glewLinkProgramARB) +#define glShaderSourceARB GLEW_GET_FUN(__glewShaderSourceARB) +#define glUniform1fARB GLEW_GET_FUN(__glewUniform1fARB) +#define glUniform1fvARB GLEW_GET_FUN(__glewUniform1fvARB) +#define glUniform1iARB GLEW_GET_FUN(__glewUniform1iARB) +#define glUniform1ivARB GLEW_GET_FUN(__glewUniform1ivARB) +#define glUniform2fARB GLEW_GET_FUN(__glewUniform2fARB) +#define glUniform2fvARB GLEW_GET_FUN(__glewUniform2fvARB) +#define glUniform2iARB GLEW_GET_FUN(__glewUniform2iARB) +#define glUniform2ivARB GLEW_GET_FUN(__glewUniform2ivARB) +#define glUniform3fARB GLEW_GET_FUN(__glewUniform3fARB) +#define glUniform3fvARB GLEW_GET_FUN(__glewUniform3fvARB) +#define glUniform3iARB GLEW_GET_FUN(__glewUniform3iARB) +#define glUniform3ivARB GLEW_GET_FUN(__glewUniform3ivARB) +#define glUniform4fARB GLEW_GET_FUN(__glewUniform4fARB) +#define glUniform4fvARB GLEW_GET_FUN(__glewUniform4fvARB) +#define glUniform4iARB GLEW_GET_FUN(__glewUniform4iARB) +#define glUniform4ivARB GLEW_GET_FUN(__glewUniform4ivARB) +#define glUniformMatrix2fvARB GLEW_GET_FUN(__glewUniformMatrix2fvARB) +#define glUniformMatrix3fvARB GLEW_GET_FUN(__glewUniformMatrix3fvARB) +#define glUniformMatrix4fvARB GLEW_GET_FUN(__glewUniformMatrix4fvARB) +#define glUseProgramObjectARB GLEW_GET_FUN(__glewUseProgramObjectARB) +#define glValidateProgramARB GLEW_GET_FUN(__glewValidateProgramARB) + +#define GLEW_ARB_shader_objects GLEW_GET_VAR(__GLEW_ARB_shader_objects) + +#endif /* GL_ARB_shader_objects */ + +/* ---------------------- GL_ARB_shading_language_100 ---------------------- */ + +#ifndef GL_ARB_shading_language_100 +#define GL_ARB_shading_language_100 1 + +#define GL_SHADING_LANGUAGE_VERSION_ARB 0x8B8C + +#define GLEW_ARB_shading_language_100 GLEW_GET_VAR(__GLEW_ARB_shading_language_100) + +#endif /* GL_ARB_shading_language_100 */ + +/* ----------------------------- GL_ARB_shadow ----------------------------- */ + +#ifndef GL_ARB_shadow +#define GL_ARB_shadow 1 + +#define GL_TEXTURE_COMPARE_MODE_ARB 0x884C +#define GL_TEXTURE_COMPARE_FUNC_ARB 0x884D +#define GL_COMPARE_R_TO_TEXTURE_ARB 0x884E + +#define GLEW_ARB_shadow GLEW_GET_VAR(__GLEW_ARB_shadow) + +#endif /* GL_ARB_shadow */ + +/* ------------------------- GL_ARB_shadow_ambient ------------------------- */ + +#ifndef GL_ARB_shadow_ambient +#define GL_ARB_shadow_ambient 1 + +#define GL_TEXTURE_COMPARE_FAIL_VALUE_ARB 0x80BF + +#define GLEW_ARB_shadow_ambient GLEW_GET_VAR(__GLEW_ARB_shadow_ambient) + +#endif /* GL_ARB_shadow_ambient */ + +/* ---------------------- GL_ARB_texture_border_clamp ---------------------- */ + +#ifndef GL_ARB_texture_border_clamp +#define GL_ARB_texture_border_clamp 1 + +#define GL_CLAMP_TO_BORDER_ARB 0x812D + +#define GLEW_ARB_texture_border_clamp GLEW_GET_VAR(__GLEW_ARB_texture_border_clamp) + +#endif /* GL_ARB_texture_border_clamp */ + +/* ----------------------- GL_ARB_texture_compression ---------------------- */ + +#ifndef GL_ARB_texture_compression +#define GL_ARB_texture_compression 1 + +#define GL_COMPRESSED_ALPHA_ARB 0x84E9 +#define GL_COMPRESSED_LUMINANCE_ARB 0x84EA +#define GL_COMPRESSED_LUMINANCE_ALPHA_ARB 0x84EB +#define GL_COMPRESSED_INTENSITY_ARB 0x84EC +#define GL_COMPRESSED_RGB_ARB 0x84ED +#define GL_COMPRESSED_RGBA_ARB 0x84EE +#define GL_TEXTURE_COMPRESSION_HINT_ARB 0x84EF +#define GL_TEXTURE_COMPRESSED_IMAGE_SIZE_ARB 0x86A0 +#define GL_TEXTURE_COMPRESSED_ARB 0x86A1 +#define GL_NUM_COMPRESSED_TEXTURE_FORMATS_ARB 0x86A2 +#define GL_COMPRESSED_TEXTURE_FORMATS_ARB 0x86A3 + +typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXIMAGE1DARBPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const void* data); +typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXIMAGE2DARBPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void* data); +typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXIMAGE3DARBPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void* data); +typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXSUBIMAGE1DARBPROC) (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const void* data); +typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXSUBIMAGE2DARBPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void* data); +typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXSUBIMAGE3DARBPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void* data); +typedef void (GLAPIENTRY * PFNGLGETCOMPRESSEDTEXIMAGEARBPROC) (GLenum target, GLint lod, void* img); + +#define glCompressedTexImage1DARB GLEW_GET_FUN(__glewCompressedTexImage1DARB) +#define glCompressedTexImage2DARB GLEW_GET_FUN(__glewCompressedTexImage2DARB) +#define glCompressedTexImage3DARB GLEW_GET_FUN(__glewCompressedTexImage3DARB) +#define glCompressedTexSubImage1DARB GLEW_GET_FUN(__glewCompressedTexSubImage1DARB) +#define glCompressedTexSubImage2DARB GLEW_GET_FUN(__glewCompressedTexSubImage2DARB) +#define glCompressedTexSubImage3DARB GLEW_GET_FUN(__glewCompressedTexSubImage3DARB) +#define glGetCompressedTexImageARB GLEW_GET_FUN(__glewGetCompressedTexImageARB) + +#define GLEW_ARB_texture_compression GLEW_GET_VAR(__GLEW_ARB_texture_compression) + +#endif /* GL_ARB_texture_compression */ + +/* ------------------------ GL_ARB_texture_cube_map ------------------------ */ + +#ifndef GL_ARB_texture_cube_map +#define GL_ARB_texture_cube_map 1 + +#define GL_NORMAL_MAP_ARB 0x8511 +#define GL_REFLECTION_MAP_ARB 0x8512 +#define GL_TEXTURE_CUBE_MAP_ARB 0x8513 +#define GL_TEXTURE_BINDING_CUBE_MAP_ARB 0x8514 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB 0x8515 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB 0x8516 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB 0x8517 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB 0x8518 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB 0x8519 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB 0x851A +#define GL_PROXY_TEXTURE_CUBE_MAP_ARB 0x851B +#define GL_MAX_CUBE_MAP_TEXTURE_SIZE_ARB 0x851C + +#define GLEW_ARB_texture_cube_map GLEW_GET_VAR(__GLEW_ARB_texture_cube_map) + +#endif /* GL_ARB_texture_cube_map */ + +/* ------------------------- GL_ARB_texture_env_add ------------------------ */ + +#ifndef GL_ARB_texture_env_add +#define GL_ARB_texture_env_add 1 + +#define GLEW_ARB_texture_env_add GLEW_GET_VAR(__GLEW_ARB_texture_env_add) + +#endif /* GL_ARB_texture_env_add */ + +/* ----------------------- GL_ARB_texture_env_combine ---------------------- */ + +#ifndef GL_ARB_texture_env_combine +#define GL_ARB_texture_env_combine 1 + +#define GL_SUBTRACT_ARB 0x84E7 +#define GL_COMBINE_ARB 0x8570 +#define GL_COMBINE_RGB_ARB 0x8571 +#define GL_COMBINE_ALPHA_ARB 0x8572 +#define GL_RGB_SCALE_ARB 0x8573 +#define GL_ADD_SIGNED_ARB 0x8574 +#define GL_INTERPOLATE_ARB 0x8575 +#define GL_CONSTANT_ARB 0x8576 +#define GL_PRIMARY_COLOR_ARB 0x8577 +#define GL_PREVIOUS_ARB 0x8578 +#define GL_SOURCE0_RGB_ARB 0x8580 +#define GL_SOURCE1_RGB_ARB 0x8581 +#define GL_SOURCE2_RGB_ARB 0x8582 +#define GL_SOURCE0_ALPHA_ARB 0x8588 +#define GL_SOURCE1_ALPHA_ARB 0x8589 +#define GL_SOURCE2_ALPHA_ARB 0x858A +#define GL_OPERAND0_RGB_ARB 0x8590 +#define GL_OPERAND1_RGB_ARB 0x8591 +#define GL_OPERAND2_RGB_ARB 0x8592 +#define GL_OPERAND0_ALPHA_ARB 0x8598 +#define GL_OPERAND1_ALPHA_ARB 0x8599 +#define GL_OPERAND2_ALPHA_ARB 0x859A + +#define GLEW_ARB_texture_env_combine GLEW_GET_VAR(__GLEW_ARB_texture_env_combine) + +#endif /* GL_ARB_texture_env_combine */ + +/* ---------------------- GL_ARB_texture_env_crossbar ---------------------- */ + +#ifndef GL_ARB_texture_env_crossbar +#define GL_ARB_texture_env_crossbar 1 + +#define GLEW_ARB_texture_env_crossbar GLEW_GET_VAR(__GLEW_ARB_texture_env_crossbar) + +#endif /* GL_ARB_texture_env_crossbar */ + +/* ------------------------ GL_ARB_texture_env_dot3 ------------------------ */ + +#ifndef GL_ARB_texture_env_dot3 +#define GL_ARB_texture_env_dot3 1 + +#define GL_DOT3_RGB_ARB 0x86AE +#define GL_DOT3_RGBA_ARB 0x86AF + +#define GLEW_ARB_texture_env_dot3 GLEW_GET_VAR(__GLEW_ARB_texture_env_dot3) + +#endif /* GL_ARB_texture_env_dot3 */ + +/* -------------------------- GL_ARB_texture_float ------------------------- */ + +#ifndef GL_ARB_texture_float +#define GL_ARB_texture_float 1 + +#define GL_RGBA32F_ARB 0x8814 +#define GL_RGB32F_ARB 0x8815 +#define GL_ALPHA32F_ARB 0x8816 +#define GL_INTENSITY32F_ARB 0x8817 +#define GL_LUMINANCE32F_ARB 0x8818 +#define GL_LUMINANCE_ALPHA32F_ARB 0x8819 +#define GL_RGBA16F_ARB 0x881A +#define GL_RGB16F_ARB 0x881B +#define GL_ALPHA16F_ARB 0x881C +#define GL_INTENSITY16F_ARB 0x881D +#define GL_LUMINANCE16F_ARB 0x881E +#define GL_LUMINANCE_ALPHA16F_ARB 0x881F +#define GL_TEXTURE_RED_TYPE_ARB 0x8C10 +#define GL_TEXTURE_GREEN_TYPE_ARB 0x8C11 +#define GL_TEXTURE_BLUE_TYPE_ARB 0x8C12 +#define GL_TEXTURE_ALPHA_TYPE_ARB 0x8C13 +#define GL_TEXTURE_LUMINANCE_TYPE_ARB 0x8C14 +#define GL_TEXTURE_INTENSITY_TYPE_ARB 0x8C15 +#define GL_TEXTURE_DEPTH_TYPE_ARB 0x8C16 +#define GL_UNSIGNED_NORMALIZED_ARB 0x8C17 + +#define GLEW_ARB_texture_float GLEW_GET_VAR(__GLEW_ARB_texture_float) + +#endif /* GL_ARB_texture_float */ + +/* --------------------- GL_ARB_texture_mirrored_repeat -------------------- */ + +#ifndef GL_ARB_texture_mirrored_repeat +#define GL_ARB_texture_mirrored_repeat 1 + +#define GL_MIRRORED_REPEAT_ARB 0x8370 + +#define GLEW_ARB_texture_mirrored_repeat GLEW_GET_VAR(__GLEW_ARB_texture_mirrored_repeat) + +#endif /* GL_ARB_texture_mirrored_repeat */ + +/* -------------------- GL_ARB_texture_non_power_of_two -------------------- */ + +#ifndef GL_ARB_texture_non_power_of_two +#define GL_ARB_texture_non_power_of_two 1 + +#define GLEW_ARB_texture_non_power_of_two GLEW_GET_VAR(__GLEW_ARB_texture_non_power_of_two) + +#endif /* GL_ARB_texture_non_power_of_two */ + +/* ------------------------ GL_ARB_texture_rectangle ----------------------- */ + +#ifndef GL_ARB_texture_rectangle +#define GL_ARB_texture_rectangle 1 + +#define GL_TEXTURE_RECTANGLE_ARB 0x84F5 +#define GL_TEXTURE_BINDING_RECTANGLE_ARB 0x84F6 +#define GL_PROXY_TEXTURE_RECTANGLE_ARB 0x84F7 +#define GL_MAX_RECTANGLE_TEXTURE_SIZE_ARB 0x84F8 +#define GL_SAMPLER_2D_RECT_ARB 0x8B63 +#define GL_SAMPLER_2D_RECT_SHADOW_ARB 0x8B64 + +#define GLEW_ARB_texture_rectangle GLEW_GET_VAR(__GLEW_ARB_texture_rectangle) + +#endif /* GL_ARB_texture_rectangle */ + +/* ------------------------ GL_ARB_transpose_matrix ------------------------ */ + +#ifndef GL_ARB_transpose_matrix +#define GL_ARB_transpose_matrix 1 + +#define GL_TRANSPOSE_MODELVIEW_MATRIX_ARB 0x84E3 +#define GL_TRANSPOSE_PROJECTION_MATRIX_ARB 0x84E4 +#define GL_TRANSPOSE_TEXTURE_MATRIX_ARB 0x84E5 +#define GL_TRANSPOSE_COLOR_MATRIX_ARB 0x84E6 + +typedef void (GLAPIENTRY * PFNGLLOADTRANSPOSEMATRIXDARBPROC) (GLdouble m[16]); +typedef void (GLAPIENTRY * PFNGLLOADTRANSPOSEMATRIXFARBPROC) (GLfloat m[16]); +typedef void (GLAPIENTRY * PFNGLMULTTRANSPOSEMATRIXDARBPROC) (GLdouble m[16]); +typedef void (GLAPIENTRY * PFNGLMULTTRANSPOSEMATRIXFARBPROC) (GLfloat m[16]); + +#define glLoadTransposeMatrixdARB GLEW_GET_FUN(__glewLoadTransposeMatrixdARB) +#define glLoadTransposeMatrixfARB GLEW_GET_FUN(__glewLoadTransposeMatrixfARB) +#define glMultTransposeMatrixdARB GLEW_GET_FUN(__glewMultTransposeMatrixdARB) +#define glMultTransposeMatrixfARB GLEW_GET_FUN(__glewMultTransposeMatrixfARB) + +#define GLEW_ARB_transpose_matrix GLEW_GET_VAR(__GLEW_ARB_transpose_matrix) + +#endif /* GL_ARB_transpose_matrix */ + +/* -------------------------- GL_ARB_vertex_blend -------------------------- */ + +#ifndef GL_ARB_vertex_blend +#define GL_ARB_vertex_blend 1 + +#define GL_MODELVIEW0_ARB 0x1700 +#define GL_MODELVIEW1_ARB 0x850A +#define GL_MAX_VERTEX_UNITS_ARB 0x86A4 +#define GL_ACTIVE_VERTEX_UNITS_ARB 0x86A5 +#define GL_WEIGHT_SUM_UNITY_ARB 0x86A6 +#define GL_VERTEX_BLEND_ARB 0x86A7 +#define GL_CURRENT_WEIGHT_ARB 0x86A8 +#define GL_WEIGHT_ARRAY_TYPE_ARB 0x86A9 +#define GL_WEIGHT_ARRAY_STRIDE_ARB 0x86AA +#define GL_WEIGHT_ARRAY_SIZE_ARB 0x86AB +#define GL_WEIGHT_ARRAY_POINTER_ARB 0x86AC +#define GL_WEIGHT_ARRAY_ARB 0x86AD +#define GL_MODELVIEW2_ARB 0x8722 +#define GL_MODELVIEW3_ARB 0x8723 +#define GL_MODELVIEW4_ARB 0x8724 +#define GL_MODELVIEW5_ARB 0x8725 +#define GL_MODELVIEW6_ARB 0x8726 +#define GL_MODELVIEW7_ARB 0x8727 +#define GL_MODELVIEW8_ARB 0x8728 +#define GL_MODELVIEW9_ARB 0x8729 +#define GL_MODELVIEW10_ARB 0x872A +#define GL_MODELVIEW11_ARB 0x872B +#define GL_MODELVIEW12_ARB 0x872C +#define GL_MODELVIEW13_ARB 0x872D +#define GL_MODELVIEW14_ARB 0x872E +#define GL_MODELVIEW15_ARB 0x872F +#define GL_MODELVIEW16_ARB 0x8730 +#define GL_MODELVIEW17_ARB 0x8731 +#define GL_MODELVIEW18_ARB 0x8732 +#define GL_MODELVIEW19_ARB 0x8733 +#define GL_MODELVIEW20_ARB 0x8734 +#define GL_MODELVIEW21_ARB 0x8735 +#define GL_MODELVIEW22_ARB 0x8736 +#define GL_MODELVIEW23_ARB 0x8737 +#define GL_MODELVIEW24_ARB 0x8738 +#define GL_MODELVIEW25_ARB 0x8739 +#define GL_MODELVIEW26_ARB 0x873A +#define GL_MODELVIEW27_ARB 0x873B +#define GL_MODELVIEW28_ARB 0x873C +#define GL_MODELVIEW29_ARB 0x873D +#define GL_MODELVIEW30_ARB 0x873E +#define GL_MODELVIEW31_ARB 0x873F + +typedef void (GLAPIENTRY * PFNGLVERTEXBLENDARBPROC) (GLint count); +typedef void (GLAPIENTRY * PFNGLWEIGHTPOINTERARBPROC) (GLint size, GLenum type, GLsizei stride, GLvoid *pointer); +typedef void (GLAPIENTRY * PFNGLWEIGHTBVARBPROC) (GLint size, GLbyte *weights); +typedef void (GLAPIENTRY * PFNGLWEIGHTDVARBPROC) (GLint size, GLdouble *weights); +typedef void (GLAPIENTRY * PFNGLWEIGHTFVARBPROC) (GLint size, GLfloat *weights); +typedef void (GLAPIENTRY * PFNGLWEIGHTIVARBPROC) (GLint size, GLint *weights); +typedef void (GLAPIENTRY * PFNGLWEIGHTSVARBPROC) (GLint size, GLshort *weights); +typedef void (GLAPIENTRY * PFNGLWEIGHTUBVARBPROC) (GLint size, GLubyte *weights); +typedef void (GLAPIENTRY * PFNGLWEIGHTUIVARBPROC) (GLint size, GLuint *weights); +typedef void (GLAPIENTRY * PFNGLWEIGHTUSVARBPROC) (GLint size, GLushort *weights); + +#define glVertexBlendARB GLEW_GET_FUN(__glewVertexBlendARB) +#define glWeightPointerARB GLEW_GET_FUN(__glewWeightPointerARB) +#define glWeightbvARB GLEW_GET_FUN(__glewWeightbvARB) +#define glWeightdvARB GLEW_GET_FUN(__glewWeightdvARB) +#define glWeightfvARB GLEW_GET_FUN(__glewWeightfvARB) +#define glWeightivARB GLEW_GET_FUN(__glewWeightivARB) +#define glWeightsvARB GLEW_GET_FUN(__glewWeightsvARB) +#define glWeightubvARB GLEW_GET_FUN(__glewWeightubvARB) +#define glWeightuivARB GLEW_GET_FUN(__glewWeightuivARB) +#define glWeightusvARB GLEW_GET_FUN(__glewWeightusvARB) + +#define GLEW_ARB_vertex_blend GLEW_GET_VAR(__GLEW_ARB_vertex_blend) + +#endif /* GL_ARB_vertex_blend */ + +/* ---------------------- GL_ARB_vertex_buffer_object ---------------------- */ + +#ifndef GL_ARB_vertex_buffer_object +#define GL_ARB_vertex_buffer_object 1 + +#define GL_BUFFER_SIZE_ARB 0x8764 +#define GL_BUFFER_USAGE_ARB 0x8765 +#define GL_ARRAY_BUFFER_ARB 0x8892 +#define GL_ELEMENT_ARRAY_BUFFER_ARB 0x8893 +#define GL_ARRAY_BUFFER_BINDING_ARB 0x8894 +#define GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB 0x8895 +#define GL_VERTEX_ARRAY_BUFFER_BINDING_ARB 0x8896 +#define GL_NORMAL_ARRAY_BUFFER_BINDING_ARB 0x8897 +#define GL_COLOR_ARRAY_BUFFER_BINDING_ARB 0x8898 +#define GL_INDEX_ARRAY_BUFFER_BINDING_ARB 0x8899 +#define GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING_ARB 0x889A +#define GL_EDGE_FLAG_ARRAY_BUFFER_BINDING_ARB 0x889B +#define GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING_ARB 0x889C +#define GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING_ARB 0x889D +#define GL_WEIGHT_ARRAY_BUFFER_BINDING_ARB 0x889E +#define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING_ARB 0x889F +#define GL_READ_ONLY_ARB 0x88B8 +#define GL_WRITE_ONLY_ARB 0x88B9 +#define GL_READ_WRITE_ARB 0x88BA +#define GL_BUFFER_ACCESS_ARB 0x88BB +#define GL_BUFFER_MAPPED_ARB 0x88BC +#define GL_BUFFER_MAP_POINTER_ARB 0x88BD +#define GL_STREAM_DRAW_ARB 0x88E0 +#define GL_STREAM_READ_ARB 0x88E1 +#define GL_STREAM_COPY_ARB 0x88E2 +#define GL_STATIC_DRAW_ARB 0x88E4 +#define GL_STATIC_READ_ARB 0x88E5 +#define GL_STATIC_COPY_ARB 0x88E6 +#define GL_DYNAMIC_DRAW_ARB 0x88E8 +#define GL_DYNAMIC_READ_ARB 0x88E9 +#define GL_DYNAMIC_COPY_ARB 0x88EA + +typedef ptrdiff_t GLsizeiptrARB; +typedef ptrdiff_t GLintptrARB; + +typedef void (GLAPIENTRY * PFNGLBINDBUFFERARBPROC) (GLenum target, GLuint buffer); +typedef void (GLAPIENTRY * PFNGLBUFFERDATAARBPROC) (GLenum target, GLsizeiptrARB size, const GLvoid* data, GLenum usage); +typedef void (GLAPIENTRY * PFNGLBUFFERSUBDATAARBPROC) (GLenum target, GLintptrARB offset, GLsizeiptrARB size, const GLvoid* data); +typedef void (GLAPIENTRY * PFNGLDELETEBUFFERSARBPROC) (GLsizei n, const GLuint* buffers); +typedef void (GLAPIENTRY * PFNGLGENBUFFERSARBPROC) (GLsizei n, GLuint* buffers); +typedef void (GLAPIENTRY * PFNGLGETBUFFERPARAMETERIVARBPROC) (GLenum target, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETBUFFERPOINTERVARBPROC) (GLenum target, GLenum pname, GLvoid** params); +typedef void (GLAPIENTRY * PFNGLGETBUFFERSUBDATAARBPROC) (GLenum target, GLintptrARB offset, GLsizeiptrARB size, GLvoid* data); +typedef GLboolean (GLAPIENTRY * PFNGLISBUFFERARBPROC) (GLuint buffer); +typedef GLvoid * (GLAPIENTRY * PFNGLMAPBUFFERARBPROC) (GLenum target, GLenum access); +typedef GLboolean (GLAPIENTRY * PFNGLUNMAPBUFFERARBPROC) (GLenum target); + +#define glBindBufferARB GLEW_GET_FUN(__glewBindBufferARB) +#define glBufferDataARB GLEW_GET_FUN(__glewBufferDataARB) +#define glBufferSubDataARB GLEW_GET_FUN(__glewBufferSubDataARB) +#define glDeleteBuffersARB GLEW_GET_FUN(__glewDeleteBuffersARB) +#define glGenBuffersARB GLEW_GET_FUN(__glewGenBuffersARB) +#define glGetBufferParameterivARB GLEW_GET_FUN(__glewGetBufferParameterivARB) +#define glGetBufferPointervARB GLEW_GET_FUN(__glewGetBufferPointervARB) +#define glGetBufferSubDataARB GLEW_GET_FUN(__glewGetBufferSubDataARB) +#define glIsBufferARB GLEW_GET_FUN(__glewIsBufferARB) +#define glMapBufferARB GLEW_GET_FUN(__glewMapBufferARB) +#define glUnmapBufferARB GLEW_GET_FUN(__glewUnmapBufferARB) + +#define GLEW_ARB_vertex_buffer_object GLEW_GET_VAR(__GLEW_ARB_vertex_buffer_object) + +#endif /* GL_ARB_vertex_buffer_object */ + +/* ------------------------- GL_ARB_vertex_program ------------------------- */ + +#ifndef GL_ARB_vertex_program +#define GL_ARB_vertex_program 1 + +#define GL_COLOR_SUM_ARB 0x8458 +#define GL_VERTEX_PROGRAM_ARB 0x8620 +#define GL_VERTEX_ATTRIB_ARRAY_ENABLED_ARB 0x8622 +#define GL_VERTEX_ATTRIB_ARRAY_SIZE_ARB 0x8623 +#define GL_VERTEX_ATTRIB_ARRAY_STRIDE_ARB 0x8624 +#define GL_VERTEX_ATTRIB_ARRAY_TYPE_ARB 0x8625 +#define GL_CURRENT_VERTEX_ATTRIB_ARB 0x8626 +#define GL_PROGRAM_LENGTH_ARB 0x8627 +#define GL_PROGRAM_STRING_ARB 0x8628 +#define GL_MAX_PROGRAM_MATRIX_STACK_DEPTH_ARB 0x862E +#define GL_MAX_PROGRAM_MATRICES_ARB 0x862F +#define GL_CURRENT_MATRIX_STACK_DEPTH_ARB 0x8640 +#define GL_CURRENT_MATRIX_ARB 0x8641 +#define GL_VERTEX_PROGRAM_POINT_SIZE_ARB 0x8642 +#define GL_VERTEX_PROGRAM_TWO_SIDE_ARB 0x8643 +#define GL_VERTEX_ATTRIB_ARRAY_POINTER_ARB 0x8645 +#define GL_PROGRAM_ERROR_POSITION_ARB 0x864B +#define GL_PROGRAM_BINDING_ARB 0x8677 +#define GL_MAX_VERTEX_ATTRIBS_ARB 0x8869 +#define GL_VERTEX_ATTRIB_ARRAY_NORMALIZED_ARB 0x886A +#define GL_PROGRAM_ERROR_STRING_ARB 0x8874 +#define GL_PROGRAM_FORMAT_ASCII_ARB 0x8875 +#define GL_PROGRAM_FORMAT_ARB 0x8876 +#define GL_PROGRAM_INSTRUCTIONS_ARB 0x88A0 +#define GL_MAX_PROGRAM_INSTRUCTIONS_ARB 0x88A1 +#define GL_PROGRAM_NATIVE_INSTRUCTIONS_ARB 0x88A2 +#define GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB 0x88A3 +#define GL_PROGRAM_TEMPORARIES_ARB 0x88A4 +#define GL_MAX_PROGRAM_TEMPORARIES_ARB 0x88A5 +#define GL_PROGRAM_NATIVE_TEMPORARIES_ARB 0x88A6 +#define GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB 0x88A7 +#define GL_PROGRAM_PARAMETERS_ARB 0x88A8 +#define GL_MAX_PROGRAM_PARAMETERS_ARB 0x88A9 +#define GL_PROGRAM_NATIVE_PARAMETERS_ARB 0x88AA +#define GL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB 0x88AB +#define GL_PROGRAM_ATTRIBS_ARB 0x88AC +#define GL_MAX_PROGRAM_ATTRIBS_ARB 0x88AD +#define GL_PROGRAM_NATIVE_ATTRIBS_ARB 0x88AE +#define GL_MAX_PROGRAM_NATIVE_ATTRIBS_ARB 0x88AF +#define GL_PROGRAM_ADDRESS_REGISTERS_ARB 0x88B0 +#define GL_MAX_PROGRAM_ADDRESS_REGISTERS_ARB 0x88B1 +#define GL_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB 0x88B2 +#define GL_MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB 0x88B3 +#define GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB 0x88B4 +#define GL_MAX_PROGRAM_ENV_PARAMETERS_ARB 0x88B5 +#define GL_PROGRAM_UNDER_NATIVE_LIMITS_ARB 0x88B6 +#define GL_TRANSPOSE_CURRENT_MATRIX_ARB 0x88B7 +#define GL_MATRIX0_ARB 0x88C0 +#define GL_MATRIX1_ARB 0x88C1 +#define GL_MATRIX2_ARB 0x88C2 +#define GL_MATRIX3_ARB 0x88C3 +#define GL_MATRIX4_ARB 0x88C4 +#define GL_MATRIX5_ARB 0x88C5 +#define GL_MATRIX6_ARB 0x88C6 +#define GL_MATRIX7_ARB 0x88C7 +#define GL_MATRIX8_ARB 0x88C8 +#define GL_MATRIX9_ARB 0x88C9 +#define GL_MATRIX10_ARB 0x88CA +#define GL_MATRIX11_ARB 0x88CB +#define GL_MATRIX12_ARB 0x88CC +#define GL_MATRIX13_ARB 0x88CD +#define GL_MATRIX14_ARB 0x88CE +#define GL_MATRIX15_ARB 0x88CF +#define GL_MATRIX16_ARB 0x88D0 +#define GL_MATRIX17_ARB 0x88D1 +#define GL_MATRIX18_ARB 0x88D2 +#define GL_MATRIX19_ARB 0x88D3 +#define GL_MATRIX20_ARB 0x88D4 +#define GL_MATRIX21_ARB 0x88D5 +#define GL_MATRIX22_ARB 0x88D6 +#define GL_MATRIX23_ARB 0x88D7 +#define GL_MATRIX24_ARB 0x88D8 +#define GL_MATRIX25_ARB 0x88D9 +#define GL_MATRIX26_ARB 0x88DA +#define GL_MATRIX27_ARB 0x88DB +#define GL_MATRIX28_ARB 0x88DC +#define GL_MATRIX29_ARB 0x88DD +#define GL_MATRIX30_ARB 0x88DE +#define GL_MATRIX31_ARB 0x88DF + +typedef void (GLAPIENTRY * PFNGLBINDPROGRAMARBPROC) (GLenum target, GLuint program); +typedef void (GLAPIENTRY * PFNGLDELETEPROGRAMSARBPROC) (GLsizei n, const GLuint* programs); +typedef void (GLAPIENTRY * PFNGLDISABLEVERTEXATTRIBARRAYARBPROC) (GLuint index); +typedef void (GLAPIENTRY * PFNGLENABLEVERTEXATTRIBARRAYARBPROC) (GLuint index); +typedef void (GLAPIENTRY * PFNGLGENPROGRAMSARBPROC) (GLsizei n, GLuint* programs); +typedef void (GLAPIENTRY * PFNGLGETPROGRAMENVPARAMETERDVARBPROC) (GLenum target, GLuint index, GLdouble* params); +typedef void (GLAPIENTRY * PFNGLGETPROGRAMENVPARAMETERFVARBPROC) (GLenum target, GLuint index, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETPROGRAMLOCALPARAMETERDVARBPROC) (GLenum target, GLuint index, GLdouble* params); +typedef void (GLAPIENTRY * PFNGLGETPROGRAMLOCALPARAMETERFVARBPROC) (GLenum target, GLuint index, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETPROGRAMSTRINGARBPROC) (GLenum target, GLenum pname, void* string); +typedef void (GLAPIENTRY * PFNGLGETPROGRAMIVARBPROC) (GLenum target, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBPOINTERVARBPROC) (GLuint index, GLenum pname, GLvoid** pointer); +typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBDVARBPROC) (GLuint index, GLenum pname, GLdouble* params); +typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBFVARBPROC) (GLuint index, GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBIVARBPROC) (GLuint index, GLenum pname, GLint* params); +typedef GLboolean (GLAPIENTRY * PFNGLISPROGRAMARBPROC) (GLuint program); +typedef void (GLAPIENTRY * PFNGLPROGRAMENVPARAMETER4DARBPROC) (GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (GLAPIENTRY * PFNGLPROGRAMENVPARAMETER4DVARBPROC) (GLenum target, GLuint index, const GLdouble* params); +typedef void (GLAPIENTRY * PFNGLPROGRAMENVPARAMETER4FARBPROC) (GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (GLAPIENTRY * PFNGLPROGRAMENVPARAMETER4FVARBPROC) (GLenum target, GLuint index, const GLfloat* params); +typedef void (GLAPIENTRY * PFNGLPROGRAMLOCALPARAMETER4DARBPROC) (GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (GLAPIENTRY * PFNGLPROGRAMLOCALPARAMETER4DVARBPROC) (GLenum target, GLuint index, const GLdouble* params); +typedef void (GLAPIENTRY * PFNGLPROGRAMLOCALPARAMETER4FARBPROC) (GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (GLAPIENTRY * PFNGLPROGRAMLOCALPARAMETER4FVARBPROC) (GLenum target, GLuint index, const GLfloat* params); +typedef void (GLAPIENTRY * PFNGLPROGRAMSTRINGARBPROC) (GLenum target, GLenum format, GLsizei len, const void* string); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1DARBPROC) (GLuint index, GLdouble x); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1DVARBPROC) (GLuint index, const GLdouble* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1FARBPROC) (GLuint index, GLfloat x); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1FVARBPROC) (GLuint index, const GLfloat* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1SARBPROC) (GLuint index, GLshort x); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1SVARBPROC) (GLuint index, const GLshort* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2DARBPROC) (GLuint index, GLdouble x, GLdouble y); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2DVARBPROC) (GLuint index, const GLdouble* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2FARBPROC) (GLuint index, GLfloat x, GLfloat y); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2FVARBPROC) (GLuint index, const GLfloat* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2SARBPROC) (GLuint index, GLshort x, GLshort y); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2SVARBPROC) (GLuint index, const GLshort* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3DARBPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3DVARBPROC) (GLuint index, const GLdouble* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3FARBPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3FVARBPROC) (GLuint index, const GLfloat* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3SARBPROC) (GLuint index, GLshort x, GLshort y, GLshort z); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3SVARBPROC) (GLuint index, const GLshort* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4NBVARBPROC) (GLuint index, const GLbyte* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4NIVARBPROC) (GLuint index, const GLint* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4NSVARBPROC) (GLuint index, const GLshort* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4NUBARBPROC) (GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4NUBVARBPROC) (GLuint index, const GLubyte* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4NUIVARBPROC) (GLuint index, const GLuint* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4NUSVARBPROC) (GLuint index, const GLushort* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4BVARBPROC) (GLuint index, const GLbyte* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4DARBPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4DVARBPROC) (GLuint index, const GLdouble* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4FARBPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4FVARBPROC) (GLuint index, const GLfloat* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4IVARBPROC) (GLuint index, const GLint* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4SARBPROC) (GLuint index, GLshort x, GLshort y, GLshort z, GLshort w); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4SVARBPROC) (GLuint index, const GLshort* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4UBVARBPROC) (GLuint index, const GLubyte* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4UIVARBPROC) (GLuint index, const GLuint* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4USVARBPROC) (GLuint index, const GLushort* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBPOINTERARBPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void* pointer); + +#define glBindProgramARB GLEW_GET_FUN(__glewBindProgramARB) +#define glDeleteProgramsARB GLEW_GET_FUN(__glewDeleteProgramsARB) +#define glDisableVertexAttribArrayARB GLEW_GET_FUN(__glewDisableVertexAttribArrayARB) +#define glEnableVertexAttribArrayARB GLEW_GET_FUN(__glewEnableVertexAttribArrayARB) +#define glGenProgramsARB GLEW_GET_FUN(__glewGenProgramsARB) +#define glGetProgramEnvParameterdvARB GLEW_GET_FUN(__glewGetProgramEnvParameterdvARB) +#define glGetProgramEnvParameterfvARB GLEW_GET_FUN(__glewGetProgramEnvParameterfvARB) +#define glGetProgramLocalParameterdvARB GLEW_GET_FUN(__glewGetProgramLocalParameterdvARB) +#define glGetProgramLocalParameterfvARB GLEW_GET_FUN(__glewGetProgramLocalParameterfvARB) +#define glGetProgramStringARB GLEW_GET_FUN(__glewGetProgramStringARB) +#define glGetProgramivARB GLEW_GET_FUN(__glewGetProgramivARB) +#define glGetVertexAttribPointervARB GLEW_GET_FUN(__glewGetVertexAttribPointervARB) +#define glGetVertexAttribdvARB GLEW_GET_FUN(__glewGetVertexAttribdvARB) +#define glGetVertexAttribfvARB GLEW_GET_FUN(__glewGetVertexAttribfvARB) +#define glGetVertexAttribivARB GLEW_GET_FUN(__glewGetVertexAttribivARB) +#define glIsProgramARB GLEW_GET_FUN(__glewIsProgramARB) +#define glProgramEnvParameter4dARB GLEW_GET_FUN(__glewProgramEnvParameter4dARB) +#define glProgramEnvParameter4dvARB GLEW_GET_FUN(__glewProgramEnvParameter4dvARB) +#define glProgramEnvParameter4fARB GLEW_GET_FUN(__glewProgramEnvParameter4fARB) +#define glProgramEnvParameter4fvARB GLEW_GET_FUN(__glewProgramEnvParameter4fvARB) +#define glProgramLocalParameter4dARB GLEW_GET_FUN(__glewProgramLocalParameter4dARB) +#define glProgramLocalParameter4dvARB GLEW_GET_FUN(__glewProgramLocalParameter4dvARB) +#define glProgramLocalParameter4fARB GLEW_GET_FUN(__glewProgramLocalParameter4fARB) +#define glProgramLocalParameter4fvARB GLEW_GET_FUN(__glewProgramLocalParameter4fvARB) +#define glProgramStringARB GLEW_GET_FUN(__glewProgramStringARB) +#define glVertexAttrib1dARB GLEW_GET_FUN(__glewVertexAttrib1dARB) +#define glVertexAttrib1dvARB GLEW_GET_FUN(__glewVertexAttrib1dvARB) +#define glVertexAttrib1fARB GLEW_GET_FUN(__glewVertexAttrib1fARB) +#define glVertexAttrib1fvARB GLEW_GET_FUN(__glewVertexAttrib1fvARB) +#define glVertexAttrib1sARB GLEW_GET_FUN(__glewVertexAttrib1sARB) +#define glVertexAttrib1svARB GLEW_GET_FUN(__glewVertexAttrib1svARB) +#define glVertexAttrib2dARB GLEW_GET_FUN(__glewVertexAttrib2dARB) +#define glVertexAttrib2dvARB GLEW_GET_FUN(__glewVertexAttrib2dvARB) +#define glVertexAttrib2fARB GLEW_GET_FUN(__glewVertexAttrib2fARB) +#define glVertexAttrib2fvARB GLEW_GET_FUN(__glewVertexAttrib2fvARB) +#define glVertexAttrib2sARB GLEW_GET_FUN(__glewVertexAttrib2sARB) +#define glVertexAttrib2svARB GLEW_GET_FUN(__glewVertexAttrib2svARB) +#define glVertexAttrib3dARB GLEW_GET_FUN(__glewVertexAttrib3dARB) +#define glVertexAttrib3dvARB GLEW_GET_FUN(__glewVertexAttrib3dvARB) +#define glVertexAttrib3fARB GLEW_GET_FUN(__glewVertexAttrib3fARB) +#define glVertexAttrib3fvARB GLEW_GET_FUN(__glewVertexAttrib3fvARB) +#define glVertexAttrib3sARB GLEW_GET_FUN(__glewVertexAttrib3sARB) +#define glVertexAttrib3svARB GLEW_GET_FUN(__glewVertexAttrib3svARB) +#define glVertexAttrib4NbvARB GLEW_GET_FUN(__glewVertexAttrib4NbvARB) +#define glVertexAttrib4NivARB GLEW_GET_FUN(__glewVertexAttrib4NivARB) +#define glVertexAttrib4NsvARB GLEW_GET_FUN(__glewVertexAttrib4NsvARB) +#define glVertexAttrib4NubARB GLEW_GET_FUN(__glewVertexAttrib4NubARB) +#define glVertexAttrib4NubvARB GLEW_GET_FUN(__glewVertexAttrib4NubvARB) +#define glVertexAttrib4NuivARB GLEW_GET_FUN(__glewVertexAttrib4NuivARB) +#define glVertexAttrib4NusvARB GLEW_GET_FUN(__glewVertexAttrib4NusvARB) +#define glVertexAttrib4bvARB GLEW_GET_FUN(__glewVertexAttrib4bvARB) +#define glVertexAttrib4dARB GLEW_GET_FUN(__glewVertexAttrib4dARB) +#define glVertexAttrib4dvARB GLEW_GET_FUN(__glewVertexAttrib4dvARB) +#define glVertexAttrib4fARB GLEW_GET_FUN(__glewVertexAttrib4fARB) +#define glVertexAttrib4fvARB GLEW_GET_FUN(__glewVertexAttrib4fvARB) +#define glVertexAttrib4ivARB GLEW_GET_FUN(__glewVertexAttrib4ivARB) +#define glVertexAttrib4sARB GLEW_GET_FUN(__glewVertexAttrib4sARB) +#define glVertexAttrib4svARB GLEW_GET_FUN(__glewVertexAttrib4svARB) +#define glVertexAttrib4ubvARB GLEW_GET_FUN(__glewVertexAttrib4ubvARB) +#define glVertexAttrib4uivARB GLEW_GET_FUN(__glewVertexAttrib4uivARB) +#define glVertexAttrib4usvARB GLEW_GET_FUN(__glewVertexAttrib4usvARB) +#define glVertexAttribPointerARB GLEW_GET_FUN(__glewVertexAttribPointerARB) + +#define GLEW_ARB_vertex_program GLEW_GET_VAR(__GLEW_ARB_vertex_program) + +#endif /* GL_ARB_vertex_program */ + +/* -------------------------- GL_ARB_vertex_shader ------------------------- */ + +#ifndef GL_ARB_vertex_shader +#define GL_ARB_vertex_shader 1 + +#define GL_VERTEX_SHADER_ARB 0x8B31 +#define GL_MAX_VERTEX_UNIFORM_COMPONENTS_ARB 0x8B4A +#define GL_MAX_VARYING_FLOATS_ARB 0x8B4B +#define GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB 0x8B4C +#define GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS_ARB 0x8B4D +#define GL_OBJECT_ACTIVE_ATTRIBUTES_ARB 0x8B89 +#define GL_OBJECT_ACTIVE_ATTRIBUTE_MAX_LENGTH_ARB 0x8B8A + +typedef void (GLAPIENTRY * PFNGLBINDATTRIBLOCATIONARBPROC) (GLhandleARB programObj, GLuint index, const GLcharARB* name); +typedef void (GLAPIENTRY * PFNGLGETACTIVEATTRIBARBPROC) (GLhandleARB programObj, GLuint index, GLsizei maxLength, GLsizei* length, GLint *size, GLenum *type, GLcharARB *name); +typedef GLint (GLAPIENTRY * PFNGLGETATTRIBLOCATIONARBPROC) (GLhandleARB programObj, const GLcharARB* name); + +#define glBindAttribLocationARB GLEW_GET_FUN(__glewBindAttribLocationARB) +#define glGetActiveAttribARB GLEW_GET_FUN(__glewGetActiveAttribARB) +#define glGetAttribLocationARB GLEW_GET_FUN(__glewGetAttribLocationARB) + +#define GLEW_ARB_vertex_shader GLEW_GET_VAR(__GLEW_ARB_vertex_shader) + +#endif /* GL_ARB_vertex_shader */ + +/* --------------------------- GL_ARB_window_pos --------------------------- */ + +#ifndef GL_ARB_window_pos +#define GL_ARB_window_pos 1 + +typedef void (GLAPIENTRY * PFNGLWINDOWPOS2DARBPROC) (GLdouble x, GLdouble y); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS2DVARBPROC) (const GLdouble* p); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS2FARBPROC) (GLfloat x, GLfloat y); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS2FVARBPROC) (const GLfloat* p); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS2IARBPROC) (GLint x, GLint y); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS2IVARBPROC) (const GLint* p); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS2SARBPROC) (GLshort x, GLshort y); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS2SVARBPROC) (const GLshort* p); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS3DARBPROC) (GLdouble x, GLdouble y, GLdouble z); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS3DVARBPROC) (const GLdouble* p); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS3FARBPROC) (GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS3FVARBPROC) (const GLfloat* p); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS3IARBPROC) (GLint x, GLint y, GLint z); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS3IVARBPROC) (const GLint* p); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS3SARBPROC) (GLshort x, GLshort y, GLshort z); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS3SVARBPROC) (const GLshort* p); + +#define glWindowPos2dARB GLEW_GET_FUN(__glewWindowPos2dARB) +#define glWindowPos2dvARB GLEW_GET_FUN(__glewWindowPos2dvARB) +#define glWindowPos2fARB GLEW_GET_FUN(__glewWindowPos2fARB) +#define glWindowPos2fvARB GLEW_GET_FUN(__glewWindowPos2fvARB) +#define glWindowPos2iARB GLEW_GET_FUN(__glewWindowPos2iARB) +#define glWindowPos2ivARB GLEW_GET_FUN(__glewWindowPos2ivARB) +#define glWindowPos2sARB GLEW_GET_FUN(__glewWindowPos2sARB) +#define glWindowPos2svARB GLEW_GET_FUN(__glewWindowPos2svARB) +#define glWindowPos3dARB GLEW_GET_FUN(__glewWindowPos3dARB) +#define glWindowPos3dvARB GLEW_GET_FUN(__glewWindowPos3dvARB) +#define glWindowPos3fARB GLEW_GET_FUN(__glewWindowPos3fARB) +#define glWindowPos3fvARB GLEW_GET_FUN(__glewWindowPos3fvARB) +#define glWindowPos3iARB GLEW_GET_FUN(__glewWindowPos3iARB) +#define glWindowPos3ivARB GLEW_GET_FUN(__glewWindowPos3ivARB) +#define glWindowPos3sARB GLEW_GET_FUN(__glewWindowPos3sARB) +#define glWindowPos3svARB GLEW_GET_FUN(__glewWindowPos3svARB) + +#define GLEW_ARB_window_pos GLEW_GET_VAR(__GLEW_ARB_window_pos) + +#endif /* GL_ARB_window_pos */ + +/* ------------------------- GL_ATIX_point_sprites ------------------------- */ + +#ifndef GL_ATIX_point_sprites +#define GL_ATIX_point_sprites 1 + +#define GLEW_ATIX_point_sprites GLEW_GET_VAR(__GLEW_ATIX_point_sprites) + +#endif /* GL_ATIX_point_sprites */ + +/* ---------------------- GL_ATIX_texture_env_combine3 --------------------- */ + +#ifndef GL_ATIX_texture_env_combine3 +#define GL_ATIX_texture_env_combine3 1 + +#define GL_MODULATE_ADD_ATIX 0x8744 +#define GL_MODULATE_SIGNED_ADD_ATIX 0x8745 +#define GL_MODULATE_SUBTRACT_ATIX 0x8746 + +#define GLEW_ATIX_texture_env_combine3 GLEW_GET_VAR(__GLEW_ATIX_texture_env_combine3) + +#endif /* GL_ATIX_texture_env_combine3 */ + +/* ----------------------- GL_ATIX_texture_env_route ----------------------- */ + +#ifndef GL_ATIX_texture_env_route +#define GL_ATIX_texture_env_route 1 + +#define GL_SECONDARY_COLOR_ATIX 0x8747 +#define GL_TEXTURE_OUTPUT_RGB_ATIX 0x8748 +#define GL_TEXTURE_OUTPUT_ALPHA_ATIX 0x8749 + +#define GLEW_ATIX_texture_env_route GLEW_GET_VAR(__GLEW_ATIX_texture_env_route) + +#endif /* GL_ATIX_texture_env_route */ + +/* ---------------- GL_ATIX_vertex_shader_output_point_size ---------------- */ + +#ifndef GL_ATIX_vertex_shader_output_point_size +#define GL_ATIX_vertex_shader_output_point_size 1 + +#define GL_OUTPUT_POINT_SIZE_ATIX 0x610E + +#define GLEW_ATIX_vertex_shader_output_point_size GLEW_GET_VAR(__GLEW_ATIX_vertex_shader_output_point_size) + +#endif /* GL_ATIX_vertex_shader_output_point_size */ + +/* -------------------------- GL_ATI_draw_buffers -------------------------- */ + +#ifndef GL_ATI_draw_buffers +#define GL_ATI_draw_buffers 1 + +#define GL_MAX_DRAW_BUFFERS_ATI 0x8824 +#define GL_DRAW_BUFFER0_ATI 0x8825 +#define GL_DRAW_BUFFER1_ATI 0x8826 +#define GL_DRAW_BUFFER2_ATI 0x8827 +#define GL_DRAW_BUFFER3_ATI 0x8828 +#define GL_DRAW_BUFFER4_ATI 0x8829 +#define GL_DRAW_BUFFER5_ATI 0x882A +#define GL_DRAW_BUFFER6_ATI 0x882B +#define GL_DRAW_BUFFER7_ATI 0x882C +#define GL_DRAW_BUFFER8_ATI 0x882D +#define GL_DRAW_BUFFER9_ATI 0x882E +#define GL_DRAW_BUFFER10_ATI 0x882F +#define GL_DRAW_BUFFER11_ATI 0x8830 +#define GL_DRAW_BUFFER12_ATI 0x8831 +#define GL_DRAW_BUFFER13_ATI 0x8832 +#define GL_DRAW_BUFFER14_ATI 0x8833 +#define GL_DRAW_BUFFER15_ATI 0x8834 + +typedef void (GLAPIENTRY * PFNGLDRAWBUFFERSATIPROC) (GLsizei n, const GLenum* bufs); + +#define glDrawBuffersATI GLEW_GET_FUN(__glewDrawBuffersATI) + +#define GLEW_ATI_draw_buffers GLEW_GET_VAR(__GLEW_ATI_draw_buffers) + +#endif /* GL_ATI_draw_buffers */ + +/* -------------------------- GL_ATI_element_array ------------------------- */ + +#ifndef GL_ATI_element_array +#define GL_ATI_element_array 1 + +#define GL_ELEMENT_ARRAY_ATI 0x8768 +#define GL_ELEMENT_ARRAY_TYPE_ATI 0x8769 +#define GL_ELEMENT_ARRAY_POINTER_ATI 0x876A + +typedef void (GLAPIENTRY * PFNGLDRAWELEMENTARRAYATIPROC) (GLenum mode, GLsizei count); +typedef void (GLAPIENTRY * PFNGLDRAWRANGEELEMENTARRAYATIPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count); +typedef void (GLAPIENTRY * PFNGLELEMENTPOINTERATIPROC) (GLenum type, const void* pointer); + +#define glDrawElementArrayATI GLEW_GET_FUN(__glewDrawElementArrayATI) +#define glDrawRangeElementArrayATI GLEW_GET_FUN(__glewDrawRangeElementArrayATI) +#define glElementPointerATI GLEW_GET_FUN(__glewElementPointerATI) + +#define GLEW_ATI_element_array GLEW_GET_VAR(__GLEW_ATI_element_array) + +#endif /* GL_ATI_element_array */ + +/* ------------------------- GL_ATI_envmap_bumpmap ------------------------- */ + +#ifndef GL_ATI_envmap_bumpmap +#define GL_ATI_envmap_bumpmap 1 + +#define GL_BUMP_ROT_MATRIX_ATI 0x8775 +#define GL_BUMP_ROT_MATRIX_SIZE_ATI 0x8776 +#define GL_BUMP_NUM_TEX_UNITS_ATI 0x8777 +#define GL_BUMP_TEX_UNITS_ATI 0x8778 +#define GL_DUDV_ATI 0x8779 +#define GL_DU8DV8_ATI 0x877A +#define GL_BUMP_ENVMAP_ATI 0x877B +#define GL_BUMP_TARGET_ATI 0x877C + +typedef void (GLAPIENTRY * PFNGLGETTEXBUMPPARAMETERFVATIPROC) (GLenum pname, GLfloat *param); +typedef void (GLAPIENTRY * PFNGLGETTEXBUMPPARAMETERIVATIPROC) (GLenum pname, GLint *param); +typedef void (GLAPIENTRY * PFNGLTEXBUMPPARAMETERFVATIPROC) (GLenum pname, GLfloat *param); +typedef void (GLAPIENTRY * PFNGLTEXBUMPPARAMETERIVATIPROC) (GLenum pname, GLint *param); + +#define glGetTexBumpParameterfvATI GLEW_GET_FUN(__glewGetTexBumpParameterfvATI) +#define glGetTexBumpParameterivATI GLEW_GET_FUN(__glewGetTexBumpParameterivATI) +#define glTexBumpParameterfvATI GLEW_GET_FUN(__glewTexBumpParameterfvATI) +#define glTexBumpParameterivATI GLEW_GET_FUN(__glewTexBumpParameterivATI) + +#define GLEW_ATI_envmap_bumpmap GLEW_GET_VAR(__GLEW_ATI_envmap_bumpmap) + +#endif /* GL_ATI_envmap_bumpmap */ + +/* ------------------------- GL_ATI_fragment_shader ------------------------ */ + +#ifndef GL_ATI_fragment_shader +#define GL_ATI_fragment_shader 1 + +#define GL_RED_BIT_ATI 0x00000001 +#define GL_2X_BIT_ATI 0x00000001 +#define GL_4X_BIT_ATI 0x00000002 +#define GL_GREEN_BIT_ATI 0x00000002 +#define GL_COMP_BIT_ATI 0x00000002 +#define GL_BLUE_BIT_ATI 0x00000004 +#define GL_8X_BIT_ATI 0x00000004 +#define GL_NEGATE_BIT_ATI 0x00000004 +#define GL_BIAS_BIT_ATI 0x00000008 +#define GL_HALF_BIT_ATI 0x00000008 +#define GL_QUARTER_BIT_ATI 0x00000010 +#define GL_EIGHTH_BIT_ATI 0x00000020 +#define GL_SATURATE_BIT_ATI 0x00000040 +#define GL_FRAGMENT_SHADER_ATI 0x8920 +#define GL_REG_0_ATI 0x8921 +#define GL_REG_1_ATI 0x8922 +#define GL_REG_2_ATI 0x8923 +#define GL_REG_3_ATI 0x8924 +#define GL_REG_4_ATI 0x8925 +#define GL_REG_5_ATI 0x8926 +#define GL_CON_0_ATI 0x8941 +#define GL_CON_1_ATI 0x8942 +#define GL_CON_2_ATI 0x8943 +#define GL_CON_3_ATI 0x8944 +#define GL_CON_4_ATI 0x8945 +#define GL_CON_5_ATI 0x8946 +#define GL_CON_6_ATI 0x8947 +#define GL_CON_7_ATI 0x8948 +#define GL_MOV_ATI 0x8961 +#define GL_ADD_ATI 0x8963 +#define GL_MUL_ATI 0x8964 +#define GL_SUB_ATI 0x8965 +#define GL_DOT3_ATI 0x8966 +#define GL_DOT4_ATI 0x8967 +#define GL_MAD_ATI 0x8968 +#define GL_LERP_ATI 0x8969 +#define GL_CND_ATI 0x896A +#define GL_CND0_ATI 0x896B +#define GL_DOT2_ADD_ATI 0x896C +#define GL_SECONDARY_INTERPOLATOR_ATI 0x896D +#define GL_NUM_FRAGMENT_REGISTERS_ATI 0x896E +#define GL_NUM_FRAGMENT_CONSTANTS_ATI 0x896F +#define GL_NUM_PASSES_ATI 0x8970 +#define GL_NUM_INSTRUCTIONS_PER_PASS_ATI 0x8971 +#define GL_NUM_INSTRUCTIONS_TOTAL_ATI 0x8972 +#define GL_NUM_INPUT_INTERPOLATOR_COMPONENTS_ATI 0x8973 +#define GL_NUM_LOOPBACK_COMPONENTS_ATI 0x8974 +#define GL_COLOR_ALPHA_PAIRING_ATI 0x8975 +#define GL_SWIZZLE_STR_ATI 0x8976 +#define GL_SWIZZLE_STQ_ATI 0x8977 +#define GL_SWIZZLE_STR_DR_ATI 0x8978 +#define GL_SWIZZLE_STQ_DQ_ATI 0x8979 +#define GL_SWIZZLE_STRQ_ATI 0x897A +#define GL_SWIZZLE_STRQ_DQ_ATI 0x897B + +typedef void (GLAPIENTRY * PFNGLALPHAFRAGMENTOP1ATIPROC) (GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod); +typedef void (GLAPIENTRY * PFNGLALPHAFRAGMENTOP2ATIPROC) (GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod); +typedef void (GLAPIENTRY * PFNGLALPHAFRAGMENTOP3ATIPROC) (GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod, GLuint arg3, GLuint arg3Rep, GLuint arg3Mod); +typedef void (GLAPIENTRY * PFNGLBEGINFRAGMENTSHADERATIPROC) (void); +typedef void (GLAPIENTRY * PFNGLBINDFRAGMENTSHADERATIPROC) (GLuint id); +typedef void (GLAPIENTRY * PFNGLCOLORFRAGMENTOP1ATIPROC) (GLenum op, GLuint dst, GLuint dstMask, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod); +typedef void (GLAPIENTRY * PFNGLCOLORFRAGMENTOP2ATIPROC) (GLenum op, GLuint dst, GLuint dstMask, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod); +typedef void (GLAPIENTRY * PFNGLCOLORFRAGMENTOP3ATIPROC) (GLenum op, GLuint dst, GLuint dstMask, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod, GLuint arg3, GLuint arg3Rep, GLuint arg3Mod); +typedef void (GLAPIENTRY * PFNGLDELETEFRAGMENTSHADERATIPROC) (GLuint id); +typedef void (GLAPIENTRY * PFNGLENDFRAGMENTSHADERATIPROC) (void); +typedef GLuint (GLAPIENTRY * PFNGLGENFRAGMENTSHADERSATIPROC) (GLuint range); +typedef void (GLAPIENTRY * PFNGLPASSTEXCOORDATIPROC) (GLuint dst, GLuint coord, GLenum swizzle); +typedef void (GLAPIENTRY * PFNGLSAMPLEMAPATIPROC) (GLuint dst, GLuint interp, GLenum swizzle); +typedef void (GLAPIENTRY * PFNGLSETFRAGMENTSHADERCONSTANTATIPROC) (GLuint dst, const GLfloat* value); + +#define glAlphaFragmentOp1ATI GLEW_GET_FUN(__glewAlphaFragmentOp1ATI) +#define glAlphaFragmentOp2ATI GLEW_GET_FUN(__glewAlphaFragmentOp2ATI) +#define glAlphaFragmentOp3ATI GLEW_GET_FUN(__glewAlphaFragmentOp3ATI) +#define glBeginFragmentShaderATI GLEW_GET_FUN(__glewBeginFragmentShaderATI) +#define glBindFragmentShaderATI GLEW_GET_FUN(__glewBindFragmentShaderATI) +#define glColorFragmentOp1ATI GLEW_GET_FUN(__glewColorFragmentOp1ATI) +#define glColorFragmentOp2ATI GLEW_GET_FUN(__glewColorFragmentOp2ATI) +#define glColorFragmentOp3ATI GLEW_GET_FUN(__glewColorFragmentOp3ATI) +#define glDeleteFragmentShaderATI GLEW_GET_FUN(__glewDeleteFragmentShaderATI) +#define glEndFragmentShaderATI GLEW_GET_FUN(__glewEndFragmentShaderATI) +#define glGenFragmentShadersATI GLEW_GET_FUN(__glewGenFragmentShadersATI) +#define glPassTexCoordATI GLEW_GET_FUN(__glewPassTexCoordATI) +#define glSampleMapATI GLEW_GET_FUN(__glewSampleMapATI) +#define glSetFragmentShaderConstantATI GLEW_GET_FUN(__glewSetFragmentShaderConstantATI) + +#define GLEW_ATI_fragment_shader GLEW_GET_VAR(__GLEW_ATI_fragment_shader) + +#endif /* GL_ATI_fragment_shader */ + +/* ------------------------ GL_ATI_map_object_buffer ----------------------- */ + +#ifndef GL_ATI_map_object_buffer +#define GL_ATI_map_object_buffer 1 + +typedef void* (GLAPIENTRY * PFNGLMAPOBJECTBUFFERATIPROC) (GLuint buffer); +typedef void (GLAPIENTRY * PFNGLUNMAPOBJECTBUFFERATIPROC) (GLuint buffer); + +#define glMapObjectBufferATI GLEW_GET_FUN(__glewMapObjectBufferATI) +#define glUnmapObjectBufferATI GLEW_GET_FUN(__glewUnmapObjectBufferATI) + +#define GLEW_ATI_map_object_buffer GLEW_GET_VAR(__GLEW_ATI_map_object_buffer) + +#endif /* GL_ATI_map_object_buffer */ + +/* -------------------------- GL_ATI_pn_triangles -------------------------- */ + +#ifndef GL_ATI_pn_triangles +#define GL_ATI_pn_triangles 1 + +#define GL_PN_TRIANGLES_ATI 0x87F0 +#define GL_MAX_PN_TRIANGLES_TESSELATION_LEVEL_ATI 0x87F1 +#define GL_PN_TRIANGLES_POINT_MODE_ATI 0x87F2 +#define GL_PN_TRIANGLES_NORMAL_MODE_ATI 0x87F3 +#define GL_PN_TRIANGLES_TESSELATION_LEVEL_ATI 0x87F4 +#define GL_PN_TRIANGLES_POINT_MODE_LINEAR_ATI 0x87F5 +#define GL_PN_TRIANGLES_POINT_MODE_CUBIC_ATI 0x87F6 +#define GL_PN_TRIANGLES_NORMAL_MODE_LINEAR_ATI 0x87F7 +#define GL_PN_TRIANGLES_NORMAL_MODE_QUADRATIC_ATI 0x87F8 + +typedef void (GLAPIENTRY * PFNGLPNTRIANGLESFATIPROC) (GLenum pname, GLfloat param); +typedef void (GLAPIENTRY * PFNGLPNTRIANGLESIATIPROC) (GLenum pname, GLint param); + +#define glPNTrianglesfATI GLEW_GET_FUN(__glPNTrianglewesfATI) +#define glPNTrianglesiATI GLEW_GET_FUN(__glPNTrianglewesiATI) + +#define GLEW_ATI_pn_triangles GLEW_GET_VAR(__GLEW_ATI_pn_triangles) + +#endif /* GL_ATI_pn_triangles */ + +/* ------------------------ GL_ATI_separate_stencil ------------------------ */ + +#ifndef GL_ATI_separate_stencil +#define GL_ATI_separate_stencil 1 + +#define GL_STENCIL_BACK_FUNC_ATI 0x8800 +#define GL_STENCIL_BACK_FAIL_ATI 0x8801 +#define GL_STENCIL_BACK_PASS_DEPTH_FAIL_ATI 0x8802 +#define GL_STENCIL_BACK_PASS_DEPTH_PASS_ATI 0x8803 + +typedef void (GLAPIENTRY * PFNGLSTENCILFUNCSEPARATEATIPROC) (GLenum frontfunc, GLenum backfunc, GLint ref, GLuint mask); +typedef void (GLAPIENTRY * PFNGLSTENCILOPSEPARATEATIPROC) (GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass); + +#define glStencilFuncSeparateATI GLEW_GET_FUN(__glewStencilFuncSeparateATI) +#define glStencilOpSeparateATI GLEW_GET_FUN(__glewStencilOpSeparateATI) + +#define GLEW_ATI_separate_stencil GLEW_GET_VAR(__GLEW_ATI_separate_stencil) + +#endif /* GL_ATI_separate_stencil */ + +/* ---------------------- GL_ATI_text_fragment_shader ---------------------- */ + +#ifndef GL_ATI_text_fragment_shader +#define GL_ATI_text_fragment_shader 1 + +#define GL_TEXT_FRAGMENT_SHADER_ATI 0x8200 + +#define GLEW_ATI_text_fragment_shader GLEW_GET_VAR(__GLEW_ATI_text_fragment_shader) + +#endif /* GL_ATI_text_fragment_shader */ + +/* --------------------- GL_ATI_texture_compression_3dc -------------------- */ + +#ifndef GL_ATI_texture_compression_3dc +#define GL_ATI_texture_compression_3dc 1 + +#define GL_COMPRESSED_RGB_3DC_ATI 0x8837 + +#define GLEW_ATI_texture_compression_3dc GLEW_GET_VAR(__GLEW_ATI_texture_compression_3dc) + +#endif /* GL_ATI_texture_compression_3dc */ + +/* ---------------------- GL_ATI_texture_env_combine3 ---------------------- */ + +#ifndef GL_ATI_texture_env_combine3 +#define GL_ATI_texture_env_combine3 1 + +#define GL_MODULATE_ADD_ATI 0x8744 +#define GL_MODULATE_SIGNED_ADD_ATI 0x8745 +#define GL_MODULATE_SUBTRACT_ATI 0x8746 + +#define GLEW_ATI_texture_env_combine3 GLEW_GET_VAR(__GLEW_ATI_texture_env_combine3) + +#endif /* GL_ATI_texture_env_combine3 */ + +/* -------------------------- GL_ATI_texture_float ------------------------- */ + +#ifndef GL_ATI_texture_float +#define GL_ATI_texture_float 1 + +#define GL_RGBA_FLOAT32_ATI 0x8814 +#define GL_RGB_FLOAT32_ATI 0x8815 +#define GL_ALPHA_FLOAT32_ATI 0x8816 +#define GL_INTENSITY_FLOAT32_ATI 0x8817 +#define GL_LUMINANCE_FLOAT32_ATI 0x8818 +#define GL_LUMINANCE_ALPHA_FLOAT32_ATI 0x8819 +#define GL_RGBA_FLOAT16_ATI 0x881A +#define GL_RGB_FLOAT16_ATI 0x881B +#define GL_ALPHA_FLOAT16_ATI 0x881C +#define GL_INTENSITY_FLOAT16_ATI 0x881D +#define GL_LUMINANCE_FLOAT16_ATI 0x881E +#define GL_LUMINANCE_ALPHA_FLOAT16_ATI 0x881F + +#define GLEW_ATI_texture_float GLEW_GET_VAR(__GLEW_ATI_texture_float) + +#endif /* GL_ATI_texture_float */ + +/* ----------------------- GL_ATI_texture_mirror_once ---------------------- */ + +#ifndef GL_ATI_texture_mirror_once +#define GL_ATI_texture_mirror_once 1 + +#define GL_MIRROR_CLAMP_ATI 0x8742 +#define GL_MIRROR_CLAMP_TO_EDGE_ATI 0x8743 + +#define GLEW_ATI_texture_mirror_once GLEW_GET_VAR(__GLEW_ATI_texture_mirror_once) + +#endif /* GL_ATI_texture_mirror_once */ + +/* ----------------------- GL_ATI_vertex_array_object ---------------------- */ + +#ifndef GL_ATI_vertex_array_object +#define GL_ATI_vertex_array_object 1 + +#define GL_STATIC_ATI 0x8760 +#define GL_DYNAMIC_ATI 0x8761 +#define GL_PRESERVE_ATI 0x8762 +#define GL_DISCARD_ATI 0x8763 +#define GL_OBJECT_BUFFER_SIZE_ATI 0x8764 +#define GL_OBJECT_BUFFER_USAGE_ATI 0x8765 +#define GL_ARRAY_OBJECT_BUFFER_ATI 0x8766 +#define GL_ARRAY_OBJECT_OFFSET_ATI 0x8767 + +typedef void (GLAPIENTRY * PFNGLARRAYOBJECTATIPROC) (GLenum array, GLint size, GLenum type, GLsizei stride, GLuint buffer, GLuint offset); +typedef void (GLAPIENTRY * PFNGLFREEOBJECTBUFFERATIPROC) (GLuint buffer); +typedef void (GLAPIENTRY * PFNGLGETARRAYOBJECTFVATIPROC) (GLenum array, GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETARRAYOBJECTIVATIPROC) (GLenum array, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETOBJECTBUFFERFVATIPROC) (GLuint buffer, GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETOBJECTBUFFERIVATIPROC) (GLuint buffer, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETVARIANTARRAYOBJECTFVATIPROC) (GLuint id, GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETVARIANTARRAYOBJECTIVATIPROC) (GLuint id, GLenum pname, GLint* params); +typedef GLboolean (GLAPIENTRY * PFNGLISOBJECTBUFFERATIPROC) (GLuint buffer); +typedef GLuint (GLAPIENTRY * PFNGLNEWOBJECTBUFFERATIPROC) (GLsizei size, const void* pointer, GLenum usage); +typedef void (GLAPIENTRY * PFNGLUPDATEOBJECTBUFFERATIPROC) (GLuint buffer, GLuint offset, GLsizei size, const void* pointer, GLenum preserve); +typedef void (GLAPIENTRY * PFNGLVARIANTARRAYOBJECTATIPROC) (GLuint id, GLenum type, GLsizei stride, GLuint buffer, GLuint offset); + +#define glArrayObjectATI GLEW_GET_FUN(__glewArrayObjectATI) +#define glFreeObjectBufferATI GLEW_GET_FUN(__glewFreeObjectBufferATI) +#define glGetArrayObjectfvATI GLEW_GET_FUN(__glewGetArrayObjectfvATI) +#define glGetArrayObjectivATI GLEW_GET_FUN(__glewGetArrayObjectivATI) +#define glGetObjectBufferfvATI GLEW_GET_FUN(__glewGetObjectBufferfvATI) +#define glGetObjectBufferivATI GLEW_GET_FUN(__glewGetObjectBufferivATI) +#define glGetVariantArrayObjectfvATI GLEW_GET_FUN(__glewGetVariantArrayObjectfvATI) +#define glGetVariantArrayObjectivATI GLEW_GET_FUN(__glewGetVariantArrayObjectivATI) +#define glIsObjectBufferATI GLEW_GET_FUN(__glewIsObjectBufferATI) +#define glNewObjectBufferATI GLEW_GET_FUN(__glewNewObjectBufferATI) +#define glUpdateObjectBufferATI GLEW_GET_FUN(__glewUpdateObjectBufferATI) +#define glVariantArrayObjectATI GLEW_GET_FUN(__glewVariantArrayObjectATI) + +#define GLEW_ATI_vertex_array_object GLEW_GET_VAR(__GLEW_ATI_vertex_array_object) + +#endif /* GL_ATI_vertex_array_object */ + +/* ------------------- GL_ATI_vertex_attrib_array_object ------------------- */ + +#ifndef GL_ATI_vertex_attrib_array_object +#define GL_ATI_vertex_attrib_array_object 1 + +typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBARRAYOBJECTFVATIPROC) (GLuint index, GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBARRAYOBJECTIVATIPROC) (GLuint index, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBARRAYOBJECTATIPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, GLuint buffer, GLuint offset); + +#define glGetVertexAttribArrayObjectfvATI GLEW_GET_FUN(__glewGetVertexAttribArrayObjectfvATI) +#define glGetVertexAttribArrayObjectivATI GLEW_GET_FUN(__glewGetVertexAttribArrayObjectivATI) +#define glVertexAttribArrayObjectATI GLEW_GET_FUN(__glewVertexAttribArrayObjectATI) + +#define GLEW_ATI_vertex_attrib_array_object GLEW_GET_VAR(__GLEW_ATI_vertex_attrib_array_object) + +#endif /* GL_ATI_vertex_attrib_array_object */ + +/* ------------------------- GL_ATI_vertex_streams ------------------------- */ + +#ifndef GL_ATI_vertex_streams +#define GL_ATI_vertex_streams 1 + +#define GL_MAX_VERTEX_STREAMS_ATI 0x876B +#define GL_VERTEX_SOURCE_ATI 0x876C +#define GL_VERTEX_STREAM0_ATI 0x876D +#define GL_VERTEX_STREAM1_ATI 0x876E +#define GL_VERTEX_STREAM2_ATI 0x876F +#define GL_VERTEX_STREAM3_ATI 0x8770 +#define GL_VERTEX_STREAM4_ATI 0x8771 +#define GL_VERTEX_STREAM5_ATI 0x8772 +#define GL_VERTEX_STREAM6_ATI 0x8773 +#define GL_VERTEX_STREAM7_ATI 0x8774 + +typedef void (GLAPIENTRY * PFNGLCLIENTACTIVEVERTEXSTREAMATIPROC) (GLenum stream); +typedef void (GLAPIENTRY * PFNGLNORMALSTREAM3BATIPROC) (GLenum stream, GLbyte x, GLbyte y, GLbyte z); +typedef void (GLAPIENTRY * PFNGLNORMALSTREAM3BVATIPROC) (GLenum stream, const GLbyte *v); +typedef void (GLAPIENTRY * PFNGLNORMALSTREAM3DATIPROC) (GLenum stream, GLdouble x, GLdouble y, GLdouble z); +typedef void (GLAPIENTRY * PFNGLNORMALSTREAM3DVATIPROC) (GLenum stream, const GLdouble *v); +typedef void (GLAPIENTRY * PFNGLNORMALSTREAM3FATIPROC) (GLenum stream, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLNORMALSTREAM3FVATIPROC) (GLenum stream, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLNORMALSTREAM3IATIPROC) (GLenum stream, GLint x, GLint y, GLint z); +typedef void (GLAPIENTRY * PFNGLNORMALSTREAM3IVATIPROC) (GLenum stream, const GLint *v); +typedef void (GLAPIENTRY * PFNGLNORMALSTREAM3SATIPROC) (GLenum stream, GLshort x, GLshort y, GLshort z); +typedef void (GLAPIENTRY * PFNGLNORMALSTREAM3SVATIPROC) (GLenum stream, const GLshort *v); +typedef void (GLAPIENTRY * PFNGLVERTEXBLENDENVFATIPROC) (GLenum pname, GLfloat param); +typedef void (GLAPIENTRY * PFNGLVERTEXBLENDENVIATIPROC) (GLenum pname, GLint param); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM2DATIPROC) (GLenum stream, GLdouble x, GLdouble y); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM2DVATIPROC) (GLenum stream, const GLdouble *v); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM2FATIPROC) (GLenum stream, GLfloat x, GLfloat y); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM2FVATIPROC) (GLenum stream, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM2IATIPROC) (GLenum stream, GLint x, GLint y); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM2IVATIPROC) (GLenum stream, const GLint *v); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM2SATIPROC) (GLenum stream, GLshort x, GLshort y); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM2SVATIPROC) (GLenum stream, const GLshort *v); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM3DATIPROC) (GLenum stream, GLdouble x, GLdouble y, GLdouble z); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM3DVATIPROC) (GLenum stream, const GLdouble *v); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM3FATIPROC) (GLenum stream, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM3FVATIPROC) (GLenum stream, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM3IATIPROC) (GLenum stream, GLint x, GLint y, GLint z); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM3IVATIPROC) (GLenum stream, const GLint *v); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM3SATIPROC) (GLenum stream, GLshort x, GLshort y, GLshort z); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM3SVATIPROC) (GLenum stream, const GLshort *v); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM4DATIPROC) (GLenum stream, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM4DVATIPROC) (GLenum stream, const GLdouble *v); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM4FATIPROC) (GLenum stream, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM4FVATIPROC) (GLenum stream, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM4IATIPROC) (GLenum stream, GLint x, GLint y, GLint z, GLint w); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM4IVATIPROC) (GLenum stream, const GLint *v); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM4SATIPROC) (GLenum stream, GLshort x, GLshort y, GLshort z, GLshort w); +typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM4SVATIPROC) (GLenum stream, const GLshort *v); + +#define glClientActiveVertexStreamATI GLEW_GET_FUN(__glewClientActiveVertexStreamATI) +#define glNormalStream3bATI GLEW_GET_FUN(__glewNormalStream3bATI) +#define glNormalStream3bvATI GLEW_GET_FUN(__glewNormalStream3bvATI) +#define glNormalStream3dATI GLEW_GET_FUN(__glewNormalStream3dATI) +#define glNormalStream3dvATI GLEW_GET_FUN(__glewNormalStream3dvATI) +#define glNormalStream3fATI GLEW_GET_FUN(__glewNormalStream3fATI) +#define glNormalStream3fvATI GLEW_GET_FUN(__glewNormalStream3fvATI) +#define glNormalStream3iATI GLEW_GET_FUN(__glewNormalStream3iATI) +#define glNormalStream3ivATI GLEW_GET_FUN(__glewNormalStream3ivATI) +#define glNormalStream3sATI GLEW_GET_FUN(__glewNormalStream3sATI) +#define glNormalStream3svATI GLEW_GET_FUN(__glewNormalStream3svATI) +#define glVertexBlendEnvfATI GLEW_GET_FUN(__glewVertexBlendEnvfATI) +#define glVertexBlendEnviATI GLEW_GET_FUN(__glewVertexBlendEnviATI) +#define glVertexStream2dATI GLEW_GET_FUN(__glewVertexStream2dATI) +#define glVertexStream2dvATI GLEW_GET_FUN(__glewVertexStream2dvATI) +#define glVertexStream2fATI GLEW_GET_FUN(__glewVertexStream2fATI) +#define glVertexStream2fvATI GLEW_GET_FUN(__glewVertexStream2fvATI) +#define glVertexStream2iATI GLEW_GET_FUN(__glewVertexStream2iATI) +#define glVertexStream2ivATI GLEW_GET_FUN(__glewVertexStream2ivATI) +#define glVertexStream2sATI GLEW_GET_FUN(__glewVertexStream2sATI) +#define glVertexStream2svATI GLEW_GET_FUN(__glewVertexStream2svATI) +#define glVertexStream3dATI GLEW_GET_FUN(__glewVertexStream3dATI) +#define glVertexStream3dvATI GLEW_GET_FUN(__glewVertexStream3dvATI) +#define glVertexStream3fATI GLEW_GET_FUN(__glewVertexStream3fATI) +#define glVertexStream3fvATI GLEW_GET_FUN(__glewVertexStream3fvATI) +#define glVertexStream3iATI GLEW_GET_FUN(__glewVertexStream3iATI) +#define glVertexStream3ivATI GLEW_GET_FUN(__glewVertexStream3ivATI) +#define glVertexStream3sATI GLEW_GET_FUN(__glewVertexStream3sATI) +#define glVertexStream3svATI GLEW_GET_FUN(__glewVertexStream3svATI) +#define glVertexStream4dATI GLEW_GET_FUN(__glewVertexStream4dATI) +#define glVertexStream4dvATI GLEW_GET_FUN(__glewVertexStream4dvATI) +#define glVertexStream4fATI GLEW_GET_FUN(__glewVertexStream4fATI) +#define glVertexStream4fvATI GLEW_GET_FUN(__glewVertexStream4fvATI) +#define glVertexStream4iATI GLEW_GET_FUN(__glewVertexStream4iATI) +#define glVertexStream4ivATI GLEW_GET_FUN(__glewVertexStream4ivATI) +#define glVertexStream4sATI GLEW_GET_FUN(__glewVertexStream4sATI) +#define glVertexStream4svATI GLEW_GET_FUN(__glewVertexStream4svATI) + +#define GLEW_ATI_vertex_streams GLEW_GET_VAR(__GLEW_ATI_vertex_streams) + +#endif /* GL_ATI_vertex_streams */ + +/* --------------------------- GL_EXT_422_pixels --------------------------- */ + +#ifndef GL_EXT_422_pixels +#define GL_EXT_422_pixels 1 + +#define GL_422_EXT 0x80CC +#define GL_422_REV_EXT 0x80CD +#define GL_422_AVERAGE_EXT 0x80CE +#define GL_422_REV_AVERAGE_EXT 0x80CF + +#define GLEW_EXT_422_pixels GLEW_GET_VAR(__GLEW_EXT_422_pixels) + +#endif /* GL_EXT_422_pixels */ + +/* ---------------------------- GL_EXT_Cg_shader --------------------------- */ + +#ifndef GL_EXT_Cg_shader +#define GL_EXT_Cg_shader 1 + +#define GL_CG_VERTEX_SHADER_EXT 0x890E +#define GL_CG_FRAGMENT_SHADER_EXT 0x890F + +#define GLEW_EXT_Cg_shader GLEW_GET_VAR(__GLEW_EXT_Cg_shader) + +#endif /* GL_EXT_Cg_shader */ + +/* ------------------------------ GL_EXT_abgr ------------------------------ */ + +#ifndef GL_EXT_abgr +#define GL_EXT_abgr 1 + +#define GL_ABGR_EXT 0x8000 + +#define GLEW_EXT_abgr GLEW_GET_VAR(__GLEW_EXT_abgr) + +#endif /* GL_EXT_abgr */ + +/* ------------------------------ GL_EXT_bgra ------------------------------ */ + +#ifndef GL_EXT_bgra +#define GL_EXT_bgra 1 + +#define GL_BGR_EXT 0x80E0 +#define GL_BGRA_EXT 0x80E1 + +#define GLEW_EXT_bgra GLEW_GET_VAR(__GLEW_EXT_bgra) + +#endif /* GL_EXT_bgra */ + +/* --------------------------- GL_EXT_blend_color -------------------------- */ + +#ifndef GL_EXT_blend_color +#define GL_EXT_blend_color 1 + +#define GL_CONSTANT_COLOR_EXT 0x8001 +#define GL_ONE_MINUS_CONSTANT_COLOR_EXT 0x8002 +#define GL_CONSTANT_ALPHA_EXT 0x8003 +#define GL_ONE_MINUS_CONSTANT_ALPHA_EXT 0x8004 +#define GL_BLEND_COLOR_EXT 0x8005 + +typedef void (GLAPIENTRY * PFNGLBLENDCOLOREXTPROC) (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha); + +#define glBlendColorEXT GLEW_GET_FUN(__glewBlendColorEXT) + +#define GLEW_EXT_blend_color GLEW_GET_VAR(__GLEW_EXT_blend_color) + +#endif /* GL_EXT_blend_color */ + +/* --------------------- GL_EXT_blend_equation_separate -------------------- */ + +#ifndef GL_EXT_blend_equation_separate +#define GL_EXT_blend_equation_separate 1 + +#define GL_BLEND_EQUATION_RGB_EXT 0x8009 +#define GL_BLEND_EQUATION_ALPHA_EXT 0x883D + +typedef void (GLAPIENTRY * PFNGLBLENDEQUATIONSEPARATEEXTPROC) (GLenum modeRGB, GLenum modeAlpha); + +#define glBlendEquationSeparateEXT GLEW_GET_FUN(__glewBlendEquationSeparateEXT) + +#define GLEW_EXT_blend_equation_separate GLEW_GET_VAR(__GLEW_EXT_blend_equation_separate) + +#endif /* GL_EXT_blend_equation_separate */ + +/* ----------------------- GL_EXT_blend_func_separate ---------------------- */ + +#ifndef GL_EXT_blend_func_separate +#define GL_EXT_blend_func_separate 1 + +#define GL_BLEND_DST_RGB_EXT 0x80C8 +#define GL_BLEND_SRC_RGB_EXT 0x80C9 +#define GL_BLEND_DST_ALPHA_EXT 0x80CA +#define GL_BLEND_SRC_ALPHA_EXT 0x80CB + +typedef void (GLAPIENTRY * PFNGLBLENDFUNCSEPARATEEXTPROC) (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha); + +#define glBlendFuncSeparateEXT GLEW_GET_FUN(__glewBlendFuncSeparateEXT) + +#define GLEW_EXT_blend_func_separate GLEW_GET_VAR(__GLEW_EXT_blend_func_separate) + +#endif /* GL_EXT_blend_func_separate */ + +/* ------------------------- GL_EXT_blend_logic_op ------------------------- */ + +#ifndef GL_EXT_blend_logic_op +#define GL_EXT_blend_logic_op 1 + +#define GLEW_EXT_blend_logic_op GLEW_GET_VAR(__GLEW_EXT_blend_logic_op) + +#endif /* GL_EXT_blend_logic_op */ + +/* -------------------------- GL_EXT_blend_minmax -------------------------- */ + +#ifndef GL_EXT_blend_minmax +#define GL_EXT_blend_minmax 1 + +#define GL_FUNC_ADD_EXT 0x8006 +#define GL_MIN_EXT 0x8007 +#define GL_MAX_EXT 0x8008 +#define GL_BLEND_EQUATION_EXT 0x8009 + +typedef void (GLAPIENTRY * PFNGLBLENDEQUATIONEXTPROC) (GLenum mode); + +#define glBlendEquationEXT GLEW_GET_FUN(__glewBlendEquationEXT) + +#define GLEW_EXT_blend_minmax GLEW_GET_VAR(__GLEW_EXT_blend_minmax) + +#endif /* GL_EXT_blend_minmax */ + +/* ------------------------- GL_EXT_blend_subtract ------------------------- */ + +#ifndef GL_EXT_blend_subtract +#define GL_EXT_blend_subtract 1 + +#define GL_FUNC_SUBTRACT_EXT 0x800A +#define GL_FUNC_REVERSE_SUBTRACT_EXT 0x800B + +#define GLEW_EXT_blend_subtract GLEW_GET_VAR(__GLEW_EXT_blend_subtract) + +#endif /* GL_EXT_blend_subtract */ + +/* ------------------------ GL_EXT_clip_volume_hint ------------------------ */ + +#ifndef GL_EXT_clip_volume_hint +#define GL_EXT_clip_volume_hint 1 + +#define GL_CLIP_VOLUME_CLIPPING_HINT_EXT 0x80F0 + +#define GLEW_EXT_clip_volume_hint GLEW_GET_VAR(__GLEW_EXT_clip_volume_hint) + +#endif /* GL_EXT_clip_volume_hint */ + +/* ------------------------------ GL_EXT_cmyka ----------------------------- */ + +#ifndef GL_EXT_cmyka +#define GL_EXT_cmyka 1 + +#define GL_CMYK_EXT 0x800C +#define GL_CMYKA_EXT 0x800D +#define GL_PACK_CMYK_HINT_EXT 0x800E +#define GL_UNPACK_CMYK_HINT_EXT 0x800F + +#define GLEW_EXT_cmyka GLEW_GET_VAR(__GLEW_EXT_cmyka) + +#endif /* GL_EXT_cmyka */ + +/* ------------------------- GL_EXT_color_subtable ------------------------- */ + +#ifndef GL_EXT_color_subtable +#define GL_EXT_color_subtable 1 + +typedef void (GLAPIENTRY * PFNGLCOLORSUBTABLEEXTPROC) (GLenum target, GLsizei start, GLsizei count, GLenum format, GLenum type, const void* data); +typedef void (GLAPIENTRY * PFNGLCOPYCOLORSUBTABLEEXTPROC) (GLenum target, GLsizei start, GLint x, GLint y, GLsizei width); + +#define glColorSubTableEXT GLEW_GET_FUN(__glewColorSubTableEXT) +#define glCopyColorSubTableEXT GLEW_GET_FUN(__glewCopyColorSubTableEXT) + +#define GLEW_EXT_color_subtable GLEW_GET_VAR(__GLEW_EXT_color_subtable) + +#endif /* GL_EXT_color_subtable */ + +/* ---------------------- GL_EXT_compiled_vertex_array --------------------- */ + +#ifndef GL_EXT_compiled_vertex_array +#define GL_EXT_compiled_vertex_array 1 + +typedef void (GLAPIENTRY * PFNGLLOCKARRAYSEXTPROC) (GLint first, GLsizei count); +typedef void (GLAPIENTRY * PFNGLUNLOCKARRAYSEXTPROC) (void); + +#define glLockArraysEXT GLEW_GET_FUN(__glewLockArraysEXT) +#define glUnlockArraysEXT GLEW_GET_FUN(__glewUnlockArraysEXT) + +#define GLEW_EXT_compiled_vertex_array GLEW_GET_VAR(__GLEW_EXT_compiled_vertex_array) + +#endif /* GL_EXT_compiled_vertex_array */ + +/* --------------------------- GL_EXT_convolution -------------------------- */ + +#ifndef GL_EXT_convolution +#define GL_EXT_convolution 1 + +#define GL_CONVOLUTION_1D_EXT 0x8010 +#define GL_CONVOLUTION_2D_EXT 0x8011 +#define GL_SEPARABLE_2D_EXT 0x8012 +#define GL_CONVOLUTION_BORDER_MODE_EXT 0x8013 +#define GL_CONVOLUTION_FILTER_SCALE_EXT 0x8014 +#define GL_CONVOLUTION_FILTER_BIAS_EXT 0x8015 +#define GL_REDUCE_EXT 0x8016 +#define GL_CONVOLUTION_FORMAT_EXT 0x8017 +#define GL_CONVOLUTION_WIDTH_EXT 0x8018 +#define GL_CONVOLUTION_HEIGHT_EXT 0x8019 +#define GL_MAX_CONVOLUTION_WIDTH_EXT 0x801A +#define GL_MAX_CONVOLUTION_HEIGHT_EXT 0x801B +#define GL_POST_CONVOLUTION_RED_SCALE_EXT 0x801C +#define GL_POST_CONVOLUTION_GREEN_SCALE_EXT 0x801D +#define GL_POST_CONVOLUTION_BLUE_SCALE_EXT 0x801E +#define GL_POST_CONVOLUTION_ALPHA_SCALE_EXT 0x801F +#define GL_POST_CONVOLUTION_RED_BIAS_EXT 0x8020 +#define GL_POST_CONVOLUTION_GREEN_BIAS_EXT 0x8021 +#define GL_POST_CONVOLUTION_BLUE_BIAS_EXT 0x8022 +#define GL_POST_CONVOLUTION_ALPHA_BIAS_EXT 0x8023 + +typedef void (GLAPIENTRY * PFNGLCONVOLUTIONFILTER1DEXTPROC) (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const void* image); +typedef void (GLAPIENTRY * PFNGLCONVOLUTIONFILTER2DEXTPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const void* image); +typedef void (GLAPIENTRY * PFNGLCONVOLUTIONPARAMETERFEXTPROC) (GLenum target, GLenum pname, GLfloat param); +typedef void (GLAPIENTRY * PFNGLCONVOLUTIONPARAMETERFVEXTPROC) (GLenum target, GLenum pname, const GLfloat* params); +typedef void (GLAPIENTRY * PFNGLCONVOLUTIONPARAMETERIEXTPROC) (GLenum target, GLenum pname, GLint param); +typedef void (GLAPIENTRY * PFNGLCONVOLUTIONPARAMETERIVEXTPROC) (GLenum target, GLenum pname, const GLint* params); +typedef void (GLAPIENTRY * PFNGLCOPYCONVOLUTIONFILTER1DEXTPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); +typedef void (GLAPIENTRY * PFNGLCOPYCONVOLUTIONFILTER2DEXTPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (GLAPIENTRY * PFNGLGETCONVOLUTIONFILTEREXTPROC) (GLenum target, GLenum format, GLenum type, void* image); +typedef void (GLAPIENTRY * PFNGLGETCONVOLUTIONPARAMETERFVEXTPROC) (GLenum target, GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETCONVOLUTIONPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETSEPARABLEFILTEREXTPROC) (GLenum target, GLenum format, GLenum type, void* row, void* column, void* span); +typedef void (GLAPIENTRY * PFNGLSEPARABLEFILTER2DEXTPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const void* row, const void* column); + +#define glConvolutionFilter1DEXT GLEW_GET_FUN(__glewConvolutionFilter1DEXT) +#define glConvolutionFilter2DEXT GLEW_GET_FUN(__glewConvolutionFilter2DEXT) +#define glConvolutionParameterfEXT GLEW_GET_FUN(__glewConvolutionParameterfEXT) +#define glConvolutionParameterfvEXT GLEW_GET_FUN(__glewConvolutionParameterfvEXT) +#define glConvolutionParameteriEXT GLEW_GET_FUN(__glewConvolutionParameteriEXT) +#define glConvolutionParameterivEXT GLEW_GET_FUN(__glewConvolutionParameterivEXT) +#define glCopyConvolutionFilter1DEXT GLEW_GET_FUN(__glewCopyConvolutionFilter1DEXT) +#define glCopyConvolutionFilter2DEXT GLEW_GET_FUN(__glewCopyConvolutionFilter2DEXT) +#define glGetConvolutionFilterEXT GLEW_GET_FUN(__glewGetConvolutionFilterEXT) +#define glGetConvolutionParameterfvEXT GLEW_GET_FUN(__glewGetConvolutionParameterfvEXT) +#define glGetConvolutionParameterivEXT GLEW_GET_FUN(__glewGetConvolutionParameterivEXT) +#define glGetSeparableFilterEXT GLEW_GET_FUN(__glewGetSeparableFilterEXT) +#define glSeparableFilter2DEXT GLEW_GET_FUN(__glewSeparableFilter2DEXT) + +#define GLEW_EXT_convolution GLEW_GET_VAR(__GLEW_EXT_convolution) + +#endif /* GL_EXT_convolution */ + +/* ------------------------ GL_EXT_coordinate_frame ------------------------ */ + +#ifndef GL_EXT_coordinate_frame +#define GL_EXT_coordinate_frame 1 + +#define GL_TANGENT_ARRAY_EXT 0x8439 +#define GL_BINORMAL_ARRAY_EXT 0x843A +#define GL_CURRENT_TANGENT_EXT 0x843B +#define GL_CURRENT_BINORMAL_EXT 0x843C +#define GL_TANGENT_ARRAY_TYPE_EXT 0x843E +#define GL_TANGENT_ARRAY_STRIDE_EXT 0x843F +#define GL_BINORMAL_ARRAY_TYPE_EXT 0x8440 +#define GL_BINORMAL_ARRAY_STRIDE_EXT 0x8441 +#define GL_TANGENT_ARRAY_POINTER_EXT 0x8442 +#define GL_BINORMAL_ARRAY_POINTER_EXT 0x8443 +#define GL_MAP1_TANGENT_EXT 0x8444 +#define GL_MAP2_TANGENT_EXT 0x8445 +#define GL_MAP1_BINORMAL_EXT 0x8446 +#define GL_MAP2_BINORMAL_EXT 0x8447 + +typedef void (GLAPIENTRY * PFNGLBINORMALPOINTEREXTPROC) (GLenum type, GLsizei stride, void* pointer); +typedef void (GLAPIENTRY * PFNGLTANGENTPOINTEREXTPROC) (GLenum type, GLsizei stride, void* pointer); + +#define glBinormalPointerEXT GLEW_GET_FUN(__glewBinormalPointerEXT) +#define glTangentPointerEXT GLEW_GET_FUN(__glewTangentPointerEXT) + +#define GLEW_EXT_coordinate_frame GLEW_GET_VAR(__GLEW_EXT_coordinate_frame) + +#endif /* GL_EXT_coordinate_frame */ + +/* -------------------------- GL_EXT_copy_texture -------------------------- */ + +#ifndef GL_EXT_copy_texture +#define GL_EXT_copy_texture 1 + +typedef void (GLAPIENTRY * PFNGLCOPYTEXIMAGE1DEXTPROC) (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border); +typedef void (GLAPIENTRY * PFNGLCOPYTEXIMAGE2DEXTPROC) (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); +typedef void (GLAPIENTRY * PFNGLCOPYTEXSUBIMAGE1DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width); +typedef void (GLAPIENTRY * PFNGLCOPYTEXSUBIMAGE2DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (GLAPIENTRY * PFNGLCOPYTEXSUBIMAGE3DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); + +#define glCopyTexImage1DEXT GLEW_GET_FUN(__glewCopyTexImage1DEXT) +#define glCopyTexImage2DEXT GLEW_GET_FUN(__glewCopyTexImage2DEXT) +#define glCopyTexSubImage1DEXT GLEW_GET_FUN(__glewCopyTexSubImage1DEXT) +#define glCopyTexSubImage2DEXT GLEW_GET_FUN(__glewCopyTexSubImage2DEXT) +#define glCopyTexSubImage3DEXT GLEW_GET_FUN(__glewCopyTexSubImage3DEXT) + +#define GLEW_EXT_copy_texture GLEW_GET_VAR(__GLEW_EXT_copy_texture) + +#endif /* GL_EXT_copy_texture */ + +/* --------------------------- GL_EXT_cull_vertex -------------------------- */ + +#ifndef GL_EXT_cull_vertex +#define GL_EXT_cull_vertex 1 + +typedef void (GLAPIENTRY * PFNGLCULLPARAMETERDVEXTPROC) (GLenum pname, GLdouble* params); +typedef void (GLAPIENTRY * PFNGLCULLPARAMETERFVEXTPROC) (GLenum pname, GLfloat* params); + +#define glCullParameterdvEXT GLEW_GET_FUN(__glewCullParameterdvEXT) +#define glCullParameterfvEXT GLEW_GET_FUN(__glewCullParameterfvEXT) + +#define GLEW_EXT_cull_vertex GLEW_GET_VAR(__GLEW_EXT_cull_vertex) + +#endif /* GL_EXT_cull_vertex */ + +/* ------------------------ GL_EXT_depth_bounds_test ----------------------- */ + +#ifndef GL_EXT_depth_bounds_test +#define GL_EXT_depth_bounds_test 1 + +#define GL_DEPTH_BOUNDS_TEST_EXT 0x8890 +#define GL_DEPTH_BOUNDS_EXT 0x8891 + +typedef void (GLAPIENTRY * PFNGLDEPTHBOUNDSEXTPROC) (GLclampd zmin, GLclampd zmax); + +#define glDepthBoundsEXT GLEW_GET_FUN(__glewDepthBoundsEXT) + +#define GLEW_EXT_depth_bounds_test GLEW_GET_VAR(__GLEW_EXT_depth_bounds_test) + +#endif /* GL_EXT_depth_bounds_test */ + +/* ----------------------- GL_EXT_draw_range_elements ---------------------- */ + +#ifndef GL_EXT_draw_range_elements +#define GL_EXT_draw_range_elements 1 + +#define GL_MAX_ELEMENTS_VERTICES 0x80E8 +#define GL_MAX_ELEMENTS_INDICES 0x80E9 + +typedef void (GLAPIENTRY * PFNGLDRAWRANGEELEMENTSEXTPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices); + +#define glDrawRangeElementsEXT GLEW_GET_FUN(__glewDrawRangeElementsEXT) + +#define GLEW_EXT_draw_range_elements GLEW_GET_VAR(__GLEW_EXT_draw_range_elements) + +#endif /* GL_EXT_draw_range_elements */ + +/* ---------------------------- GL_EXT_fog_coord --------------------------- */ + +#ifndef GL_EXT_fog_coord +#define GL_EXT_fog_coord 1 + +#define GL_FOG_COORDINATE_SOURCE_EXT 0x8450 +#define GL_FOG_COORDINATE_EXT 0x8451 +#define GL_FRAGMENT_DEPTH_EXT 0x8452 +#define GL_CURRENT_FOG_COORDINATE_EXT 0x8453 +#define GL_FOG_COORDINATE_ARRAY_TYPE_EXT 0x8454 +#define GL_FOG_COORDINATE_ARRAY_STRIDE_EXT 0x8455 +#define GL_FOG_COORDINATE_ARRAY_POINTER_EXT 0x8456 +#define GL_FOG_COORDINATE_ARRAY_EXT 0x8457 + +typedef void (GLAPIENTRY * PFNGLFOGCOORDPOINTEREXTPROC) (GLenum type, GLsizei stride, const GLvoid *pointer); +typedef void (GLAPIENTRY * PFNGLFOGCOORDDEXTPROC) (GLdouble coord); +typedef void (GLAPIENTRY * PFNGLFOGCOORDDVEXTPROC) (const GLdouble *coord); +typedef void (GLAPIENTRY * PFNGLFOGCOORDFEXTPROC) (GLfloat coord); +typedef void (GLAPIENTRY * PFNGLFOGCOORDFVEXTPROC) (const GLfloat *coord); + +#define glFogCoordPointerEXT GLEW_GET_FUN(__glewFogCoordPointerEXT) +#define glFogCoorddEXT GLEW_GET_FUN(__glewFogCoorddEXT) +#define glFogCoorddvEXT GLEW_GET_FUN(__glewFogCoorddvEXT) +#define glFogCoordfEXT GLEW_GET_FUN(__glewFogCoordfEXT) +#define glFogCoordfvEXT GLEW_GET_FUN(__glewFogCoordfvEXT) + +#define GLEW_EXT_fog_coord GLEW_GET_VAR(__GLEW_EXT_fog_coord) + +#endif /* GL_EXT_fog_coord */ + +/* ------------------------ GL_EXT_fragment_lighting ----------------------- */ + +#ifndef GL_EXT_fragment_lighting +#define GL_EXT_fragment_lighting 1 + +#define GL_FRAGMENT_LIGHTING_EXT 0x8400 +#define GL_FRAGMENT_COLOR_MATERIAL_EXT 0x8401 +#define GL_FRAGMENT_COLOR_MATERIAL_FACE_EXT 0x8402 +#define GL_FRAGMENT_COLOR_MATERIAL_PARAMETER_EXT 0x8403 +#define GL_MAX_FRAGMENT_LIGHTS_EXT 0x8404 +#define GL_MAX_ACTIVE_LIGHTS_EXT 0x8405 +#define GL_CURRENT_RASTER_NORMAL_EXT 0x8406 +#define GL_LIGHT_ENV_MODE_EXT 0x8407 +#define GL_FRAGMENT_LIGHT_MODEL_LOCAL_VIEWER_EXT 0x8408 +#define GL_FRAGMENT_LIGHT_MODEL_TWO_SIDE_EXT 0x8409 +#define GL_FRAGMENT_LIGHT_MODEL_AMBIENT_EXT 0x840A +#define GL_FRAGMENT_LIGHT_MODEL_NORMAL_INTERPOLATION_EXT 0x840B +#define GL_FRAGMENT_LIGHT0_EXT 0x840C +#define GL_FRAGMENT_LIGHT7_EXT 0x8413 + +typedef void (GLAPIENTRY * PFNGLFRAGMENTCOLORMATERIALEXTPROC) (GLenum face, GLenum mode); +typedef void (GLAPIENTRY * PFNGLFRAGMENTLIGHTMODELFEXTPROC) (GLenum pname, GLfloat param); +typedef void (GLAPIENTRY * PFNGLFRAGMENTLIGHTMODELFVEXTPROC) (GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLFRAGMENTLIGHTMODELIEXTPROC) (GLenum pname, GLint param); +typedef void (GLAPIENTRY * PFNGLFRAGMENTLIGHTMODELIVEXTPROC) (GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLFRAGMENTLIGHTFEXTPROC) (GLenum light, GLenum pname, GLfloat param); +typedef void (GLAPIENTRY * PFNGLFRAGMENTLIGHTFVEXTPROC) (GLenum light, GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLFRAGMENTLIGHTIEXTPROC) (GLenum light, GLenum pname, GLint param); +typedef void (GLAPIENTRY * PFNGLFRAGMENTLIGHTIVEXTPROC) (GLenum light, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLFRAGMENTMATERIALFEXTPROC) (GLenum face, GLenum pname, const GLfloat param); +typedef void (GLAPIENTRY * PFNGLFRAGMENTMATERIALFVEXTPROC) (GLenum face, GLenum pname, const GLfloat* params); +typedef void (GLAPIENTRY * PFNGLFRAGMENTMATERIALIEXTPROC) (GLenum face, GLenum pname, const GLint param); +typedef void (GLAPIENTRY * PFNGLFRAGMENTMATERIALIVEXTPROC) (GLenum face, GLenum pname, const GLint* params); +typedef void (GLAPIENTRY * PFNGLGETFRAGMENTLIGHTFVEXTPROC) (GLenum light, GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETFRAGMENTLIGHTIVEXTPROC) (GLenum light, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETFRAGMENTMATERIALFVEXTPROC) (GLenum face, GLenum pname, const GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETFRAGMENTMATERIALIVEXTPROC) (GLenum face, GLenum pname, const GLint* params); +typedef void (GLAPIENTRY * PFNGLLIGHTENVIEXTPROC) (GLenum pname, GLint param); + +#define glFragmentColorMaterialEXT GLEW_GET_FUN(__glewFragmentColorMaterialEXT) +#define glFragmentLightModelfEXT GLEW_GET_FUN(__glewFragmentLightModelfEXT) +#define glFragmentLightModelfvEXT GLEW_GET_FUN(__glewFragmentLightModelfvEXT) +#define glFragmentLightModeliEXT GLEW_GET_FUN(__glewFragmentLightModeliEXT) +#define glFragmentLightModelivEXT GLEW_GET_FUN(__glewFragmentLightModelivEXT) +#define glFragmentLightfEXT GLEW_GET_FUN(__glewFragmentLightfEXT) +#define glFragmentLightfvEXT GLEW_GET_FUN(__glewFragmentLightfvEXT) +#define glFragmentLightiEXT GLEW_GET_FUN(__glewFragmentLightiEXT) +#define glFragmentLightivEXT GLEW_GET_FUN(__glewFragmentLightivEXT) +#define glFragmentMaterialfEXT GLEW_GET_FUN(__glewFragmentMaterialfEXT) +#define glFragmentMaterialfvEXT GLEW_GET_FUN(__glewFragmentMaterialfvEXT) +#define glFragmentMaterialiEXT GLEW_GET_FUN(__glewFragmentMaterialiEXT) +#define glFragmentMaterialivEXT GLEW_GET_FUN(__glewFragmentMaterialivEXT) +#define glGetFragmentLightfvEXT GLEW_GET_FUN(__glewGetFragmentLightfvEXT) +#define glGetFragmentLightivEXT GLEW_GET_FUN(__glewGetFragmentLightivEXT) +#define glGetFragmentMaterialfvEXT GLEW_GET_FUN(__glewGetFragmentMaterialfvEXT) +#define glGetFragmentMaterialivEXT GLEW_GET_FUN(__glewGetFragmentMaterialivEXT) +#define glLightEnviEXT GLEW_GET_FUN(__glewLightEnviEXT) + +#define GLEW_EXT_fragment_lighting GLEW_GET_VAR(__GLEW_EXT_fragment_lighting) + +#endif /* GL_EXT_fragment_lighting */ + +/* ------------------------ GL_EXT_framebuffer_blit ------------------------ */ + +#ifndef GL_EXT_framebuffer_blit +#define GL_EXT_framebuffer_blit 1 + +#define GL_DRAW_FRAMEBUFFER_BINDING_EXT 0x8CA6 +#define GL_READ_FRAMEBUFFER_EXT 0x8CA8 +#define GL_DRAW_FRAMEBUFFER_EXT 0x8CA9 +#define GL_READ_FRAMEBUFFER_BINDING_EXT 0x8CAA + +typedef void (GLAPIENTRY * PFNGLBLITFRAMEBUFFEREXTPROC) (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); + +#define glBlitFramebufferEXT GLEW_GET_FUN(__glewBlitFramebufferEXT) + +#define GLEW_EXT_framebuffer_blit GLEW_GET_VAR(__GLEW_EXT_framebuffer_blit) + +#endif /* GL_EXT_framebuffer_blit */ + +/* --------------------- GL_EXT_framebuffer_multisample -------------------- */ + +#ifndef GL_EXT_framebuffer_multisample +#define GL_EXT_framebuffer_multisample 1 + +#define GL_RENDERBUFFER_SAMPLES_EXT 0x8CAB + +typedef void (GLAPIENTRY * PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); + +#define glRenderbufferStorageMultisampleEXT GLEW_GET_FUN(__glewRenderbufferStorageMultisampleEXT) + +#define GLEW_EXT_framebuffer_multisample GLEW_GET_VAR(__GLEW_EXT_framebuffer_multisample) + +#endif /* GL_EXT_framebuffer_multisample */ + +/* ----------------------- GL_EXT_framebuffer_object ----------------------- */ + +#ifndef GL_EXT_framebuffer_object +#define GL_EXT_framebuffer_object 1 + +#define GL_INVALID_FRAMEBUFFER_OPERATION_EXT 0x0506 +#define GL_MAX_RENDERBUFFER_SIZE_EXT 0x84E8 +#define GL_FRAMEBUFFER_BINDING_EXT 0x8CA6 +#define GL_RENDERBUFFER_BINDING_EXT 0x8CA7 +#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT 0x8CD0 +#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT 0x8CD1 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_EXT 0x8CD2 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE_EXT 0x8CD3 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_EXT 0x8CD4 +#define GL_FRAMEBUFFER_COMPLETE_EXT 0x8CD5 +#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT 0x8CD6 +#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT 0x8CD7 +#define GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT 0x8CD9 +#define GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT 0x8CDA +#define GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT 0x8CDB +#define GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT 0x8CDC +#define GL_FRAMEBUFFER_UNSUPPORTED_EXT 0x8CDD +#define GL_MAX_COLOR_ATTACHMENTS_EXT 0x8CDF +#define GL_COLOR_ATTACHMENT0_EXT 0x8CE0 +#define GL_COLOR_ATTACHMENT1_EXT 0x8CE1 +#define GL_COLOR_ATTACHMENT2_EXT 0x8CE2 +#define GL_COLOR_ATTACHMENT3_EXT 0x8CE3 +#define GL_COLOR_ATTACHMENT4_EXT 0x8CE4 +#define GL_COLOR_ATTACHMENT5_EXT 0x8CE5 +#define GL_COLOR_ATTACHMENT6_EXT 0x8CE6 +#define GL_COLOR_ATTACHMENT7_EXT 0x8CE7 +#define GL_COLOR_ATTACHMENT8_EXT 0x8CE8 +#define GL_COLOR_ATTACHMENT9_EXT 0x8CE9 +#define GL_COLOR_ATTACHMENT10_EXT 0x8CEA +#define GL_COLOR_ATTACHMENT11_EXT 0x8CEB +#define GL_COLOR_ATTACHMENT12_EXT 0x8CEC +#define GL_COLOR_ATTACHMENT13_EXT 0x8CED +#define GL_COLOR_ATTACHMENT14_EXT 0x8CEE +#define GL_COLOR_ATTACHMENT15_EXT 0x8CEF +#define GL_DEPTH_ATTACHMENT_EXT 0x8D00 +#define GL_STENCIL_ATTACHMENT_EXT 0x8D20 +#define GL_FRAMEBUFFER_EXT 0x8D40 +#define GL_RENDERBUFFER_EXT 0x8D41 +#define GL_RENDERBUFFER_WIDTH_EXT 0x8D42 +#define GL_RENDERBUFFER_HEIGHT_EXT 0x8D43 +#define GL_RENDERBUFFER_INTERNAL_FORMAT_EXT 0x8D44 +#define GL_STENCIL_INDEX1_EXT 0x8D46 +#define GL_STENCIL_INDEX4_EXT 0x8D47 +#define GL_STENCIL_INDEX8_EXT 0x8D48 +#define GL_STENCIL_INDEX16_EXT 0x8D49 +#define GL_RENDERBUFFER_RED_SIZE_EXT 0x8D50 +#define GL_RENDERBUFFER_GREEN_SIZE_EXT 0x8D51 +#define GL_RENDERBUFFER_BLUE_SIZE_EXT 0x8D52 +#define GL_RENDERBUFFER_ALPHA_SIZE_EXT 0x8D53 +#define GL_RENDERBUFFER_DEPTH_SIZE_EXT 0x8D54 +#define GL_RENDERBUFFER_STENCIL_SIZE_EXT 0x8D55 + +typedef void (GLAPIENTRY * PFNGLBINDFRAMEBUFFEREXTPROC) (GLenum target, GLuint framebuffer); +typedef void (GLAPIENTRY * PFNGLBINDRENDERBUFFEREXTPROC) (GLenum target, GLuint renderbuffer); +typedef GLenum (GLAPIENTRY * PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC) (GLenum target); +typedef void (GLAPIENTRY * PFNGLDELETEFRAMEBUFFERSEXTPROC) (GLsizei n, const GLuint* framebuffers); +typedef void (GLAPIENTRY * PFNGLDELETERENDERBUFFERSEXTPROC) (GLsizei n, const GLuint* renderbuffers); +typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC) (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); +typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTURE1DEXTPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); +typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTURE2DEXTPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); +typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTURE3DEXTPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset); +typedef void (GLAPIENTRY * PFNGLGENFRAMEBUFFERSEXTPROC) (GLsizei n, GLuint* framebuffers); +typedef void (GLAPIENTRY * PFNGLGENRENDERBUFFERSEXTPROC) (GLsizei n, GLuint* renderbuffers); +typedef void (GLAPIENTRY * PFNGLGENERATEMIPMAPEXTPROC) (GLenum target); +typedef void (GLAPIENTRY * PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC) (GLenum target, GLenum attachment, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETRENDERBUFFERPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint* params); +typedef GLboolean (GLAPIENTRY * PFNGLISFRAMEBUFFEREXTPROC) (GLuint framebuffer); +typedef GLboolean (GLAPIENTRY * PFNGLISRENDERBUFFEREXTPROC) (GLuint renderbuffer); +typedef void (GLAPIENTRY * PFNGLRENDERBUFFERSTORAGEEXTPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height); + +#define glBindFramebufferEXT GLEW_GET_FUN(__glewBindFramebufferEXT) +#define glBindRenderbufferEXT GLEW_GET_FUN(__glewBindRenderbufferEXT) +#define glCheckFramebufferStatusEXT GLEW_GET_FUN(__glewCheckFramebufferStatusEXT) +#define glDeleteFramebuffersEXT GLEW_GET_FUN(__glewDeleteFramebuffersEXT) +#define glDeleteRenderbuffersEXT GLEW_GET_FUN(__glewDeleteRenderbuffersEXT) +#define glFramebufferRenderbufferEXT GLEW_GET_FUN(__glewFramebufferRenderbufferEXT) +#define glFramebufferTexture1DEXT GLEW_GET_FUN(__glewFramebufferTexture1DEXT) +#define glFramebufferTexture2DEXT GLEW_GET_FUN(__glewFramebufferTexture2DEXT) +#define glFramebufferTexture3DEXT GLEW_GET_FUN(__glewFramebufferTexture3DEXT) +#define glGenFramebuffersEXT GLEW_GET_FUN(__glewGenFramebuffersEXT) +#define glGenRenderbuffersEXT GLEW_GET_FUN(__glewGenRenderbuffersEXT) +#define glGenerateMipmapEXT GLEW_GET_FUN(__glewGenerateMipmapEXT) +#define glGetFramebufferAttachmentParameterivEXT GLEW_GET_FUN(__glewGetFramebufferAttachmentParameterivEXT) +#define glGetRenderbufferParameterivEXT GLEW_GET_FUN(__glewGetRenderbufferParameterivEXT) +#define glIsFramebufferEXT GLEW_GET_FUN(__glewIsFramebufferEXT) +#define glIsRenderbufferEXT GLEW_GET_FUN(__glewIsRenderbufferEXT) +#define glRenderbufferStorageEXT GLEW_GET_FUN(__glewRenderbufferStorageEXT) + +#define GLEW_EXT_framebuffer_object GLEW_GET_VAR(__GLEW_EXT_framebuffer_object) + +#endif /* GL_EXT_framebuffer_object */ + +/* ---------------------------- GL_EXT_histogram --------------------------- */ + +#ifndef GL_EXT_histogram +#define GL_EXT_histogram 1 + +#define GL_HISTOGRAM_EXT 0x8024 +#define GL_PROXY_HISTOGRAM_EXT 0x8025 +#define GL_HISTOGRAM_WIDTH_EXT 0x8026 +#define GL_HISTOGRAM_FORMAT_EXT 0x8027 +#define GL_HISTOGRAM_RED_SIZE_EXT 0x8028 +#define GL_HISTOGRAM_GREEN_SIZE_EXT 0x8029 +#define GL_HISTOGRAM_BLUE_SIZE_EXT 0x802A +#define GL_HISTOGRAM_ALPHA_SIZE_EXT 0x802B +#define GL_HISTOGRAM_LUMINANCE_SIZE_EXT 0x802C +#define GL_HISTOGRAM_SINK_EXT 0x802D +#define GL_MINMAX_EXT 0x802E +#define GL_MINMAX_FORMAT_EXT 0x802F +#define GL_MINMAX_SINK_EXT 0x8030 + +typedef void (GLAPIENTRY * PFNGLGETHISTOGRAMEXTPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, void* values); +typedef void (GLAPIENTRY * PFNGLGETHISTOGRAMPARAMETERFVEXTPROC) (GLenum target, GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETHISTOGRAMPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETMINMAXEXTPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, void* values); +typedef void (GLAPIENTRY * PFNGLGETMINMAXPARAMETERFVEXTPROC) (GLenum target, GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETMINMAXPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLHISTOGRAMEXTPROC) (GLenum target, GLsizei width, GLenum internalformat, GLboolean sink); +typedef void (GLAPIENTRY * PFNGLMINMAXEXTPROC) (GLenum target, GLenum internalformat, GLboolean sink); +typedef void (GLAPIENTRY * PFNGLRESETHISTOGRAMEXTPROC) (GLenum target); +typedef void (GLAPIENTRY * PFNGLRESETMINMAXEXTPROC) (GLenum target); + +#define glGetHistogramEXT GLEW_GET_FUN(__glewGetHistogramEXT) +#define glGetHistogramParameterfvEXT GLEW_GET_FUN(__glewGetHistogramParameterfvEXT) +#define glGetHistogramParameterivEXT GLEW_GET_FUN(__glewGetHistogramParameterivEXT) +#define glGetMinmaxEXT GLEW_GET_FUN(__glewGetMinmaxEXT) +#define glGetMinmaxParameterfvEXT GLEW_GET_FUN(__glewGetMinmaxParameterfvEXT) +#define glGetMinmaxParameterivEXT GLEW_GET_FUN(__glewGetMinmaxParameterivEXT) +#define glHistogramEXT GLEW_GET_FUN(__glewHistogramEXT) +#define glMinmaxEXT GLEW_GET_FUN(__glewMinmaxEXT) +#define glResetHistogramEXT GLEW_GET_FUN(__glewResetHistogramEXT) +#define glResetMinmaxEXT GLEW_GET_FUN(__glewResetMinmaxEXT) + +#define GLEW_EXT_histogram GLEW_GET_VAR(__GLEW_EXT_histogram) + +#endif /* GL_EXT_histogram */ + +/* ----------------------- GL_EXT_index_array_formats ---------------------- */ + +#ifndef GL_EXT_index_array_formats +#define GL_EXT_index_array_formats 1 + +#define GLEW_EXT_index_array_formats GLEW_GET_VAR(__GLEW_EXT_index_array_formats) + +#endif /* GL_EXT_index_array_formats */ + +/* --------------------------- GL_EXT_index_func --------------------------- */ + +#ifndef GL_EXT_index_func +#define GL_EXT_index_func 1 + +typedef void (GLAPIENTRY * PFNGLINDEXFUNCEXTPROC) (GLenum func, GLfloat ref); + +#define glIndexFuncEXT GLEW_GET_FUN(__glewIndexFuncEXT) + +#define GLEW_EXT_index_func GLEW_GET_VAR(__GLEW_EXT_index_func) + +#endif /* GL_EXT_index_func */ + +/* ------------------------- GL_EXT_index_material ------------------------- */ + +#ifndef GL_EXT_index_material +#define GL_EXT_index_material 1 + +typedef void (GLAPIENTRY * PFNGLINDEXMATERIALEXTPROC) (GLenum face, GLenum mode); + +#define glIndexMaterialEXT GLEW_GET_FUN(__glewIndexMaterialEXT) + +#define GLEW_EXT_index_material GLEW_GET_VAR(__GLEW_EXT_index_material) + +#endif /* GL_EXT_index_material */ + +/* -------------------------- GL_EXT_index_texture ------------------------- */ + +#ifndef GL_EXT_index_texture +#define GL_EXT_index_texture 1 + +#define GLEW_EXT_index_texture GLEW_GET_VAR(__GLEW_EXT_index_texture) + +#endif /* GL_EXT_index_texture */ + +/* -------------------------- GL_EXT_light_texture ------------------------- */ + +#ifndef GL_EXT_light_texture +#define GL_EXT_light_texture 1 + +#define GL_FRAGMENT_MATERIAL_EXT 0x8349 +#define GL_FRAGMENT_NORMAL_EXT 0x834A +#define GL_FRAGMENT_COLOR_EXT 0x834C +#define GL_ATTENUATION_EXT 0x834D +#define GL_SHADOW_ATTENUATION_EXT 0x834E +#define GL_TEXTURE_APPLICATION_MODE_EXT 0x834F +#define GL_TEXTURE_LIGHT_EXT 0x8350 +#define GL_TEXTURE_MATERIAL_FACE_EXT 0x8351 +#define GL_TEXTURE_MATERIAL_PARAMETER_EXT 0x8352 +#define GL_FRAGMENT_DEPTH_EXT 0x8452 + +typedef void (GLAPIENTRY * PFNGLAPPLYTEXTUREEXTPROC) (GLenum mode); +typedef void (GLAPIENTRY * PFNGLTEXTURELIGHTEXTPROC) (GLenum pname); +typedef void (GLAPIENTRY * PFNGLTEXTUREMATERIALEXTPROC) (GLenum face, GLenum mode); + +#define glApplyTextureEXT GLEW_GET_FUN(__glewApplyTextureEXT) +#define glTextureLightEXT GLEW_GET_FUN(__glewTextureLightEXT) +#define glTextureMaterialEXT GLEW_GET_FUN(__glewTextureMaterialEXT) + +#define GLEW_EXT_light_texture GLEW_GET_VAR(__GLEW_EXT_light_texture) + +#endif /* GL_EXT_light_texture */ + +/* ------------------------- GL_EXT_misc_attribute ------------------------- */ + +#ifndef GL_EXT_misc_attribute +#define GL_EXT_misc_attribute 1 + +#define GLEW_EXT_misc_attribute GLEW_GET_VAR(__GLEW_EXT_misc_attribute) + +#endif /* GL_EXT_misc_attribute */ + +/* ------------------------ GL_EXT_multi_draw_arrays ----------------------- */ + +#ifndef GL_EXT_multi_draw_arrays +#define GL_EXT_multi_draw_arrays 1 + +typedef void (GLAPIENTRY * PFNGLMULTIDRAWARRAYSEXTPROC) (GLenum mode, GLint* first, GLsizei *count, GLsizei primcount); +typedef void (GLAPIENTRY * PFNGLMULTIDRAWELEMENTSEXTPROC) (GLenum mode, GLsizei* count, GLenum type, const GLvoid **indices, GLsizei primcount); + +#define glMultiDrawArraysEXT GLEW_GET_FUN(__glewMultiDrawArraysEXT) +#define glMultiDrawElementsEXT GLEW_GET_FUN(__glewMultiDrawElementsEXT) + +#define GLEW_EXT_multi_draw_arrays GLEW_GET_VAR(__GLEW_EXT_multi_draw_arrays) + +#endif /* GL_EXT_multi_draw_arrays */ + +/* --------------------------- GL_EXT_multisample -------------------------- */ + +#ifndef GL_EXT_multisample +#define GL_EXT_multisample 1 + +#define GL_MULTISAMPLE_EXT 0x809D +#define GL_SAMPLE_ALPHA_TO_MASK_EXT 0x809E +#define GL_SAMPLE_ALPHA_TO_ONE_EXT 0x809F +#define GL_SAMPLE_MASK_EXT 0x80A0 +#define GL_1PASS_EXT 0x80A1 +#define GL_2PASS_0_EXT 0x80A2 +#define GL_2PASS_1_EXT 0x80A3 +#define GL_4PASS_0_EXT 0x80A4 +#define GL_4PASS_1_EXT 0x80A5 +#define GL_4PASS_2_EXT 0x80A6 +#define GL_4PASS_3_EXT 0x80A7 +#define GL_SAMPLE_BUFFERS_EXT 0x80A8 +#define GL_SAMPLES_EXT 0x80A9 +#define GL_SAMPLE_MASK_VALUE_EXT 0x80AA +#define GL_SAMPLE_MASK_INVERT_EXT 0x80AB +#define GL_SAMPLE_PATTERN_EXT 0x80AC +#define GL_MULTISAMPLE_BIT_EXT 0x20000000 + +typedef void (GLAPIENTRY * PFNGLSAMPLEMASKEXTPROC) (GLclampf value, GLboolean invert); +typedef void (GLAPIENTRY * PFNGLSAMPLEPATTERNEXTPROC) (GLenum pattern); + +#define glSampleMaskEXT GLEW_GET_FUN(__glewSampleMaskEXT) +#define glSamplePatternEXT GLEW_GET_FUN(__glewSamplePatternEXT) + +#define GLEW_EXT_multisample GLEW_GET_VAR(__GLEW_EXT_multisample) + +#endif /* GL_EXT_multisample */ + +/* ---------------------- GL_EXT_packed_depth_stencil ---------------------- */ + +#ifndef GL_EXT_packed_depth_stencil +#define GL_EXT_packed_depth_stencil 1 + +#define GL_DEPTH_STENCIL_EXT 0x84F9 +#define GL_UNSIGNED_INT_24_8_EXT 0x84FA +#define GL_DEPTH24_STENCIL8_EXT 0x88F0 +#define GL_TEXTURE_STENCIL_SIZE_EXT 0x88F1 + +#define GLEW_EXT_packed_depth_stencil GLEW_GET_VAR(__GLEW_EXT_packed_depth_stencil) + +#endif /* GL_EXT_packed_depth_stencil */ + +/* -------------------------- GL_EXT_packed_pixels ------------------------- */ + +#ifndef GL_EXT_packed_pixels +#define GL_EXT_packed_pixels 1 + +#define GL_UNSIGNED_BYTE_3_3_2_EXT 0x8032 +#define GL_UNSIGNED_SHORT_4_4_4_4_EXT 0x8033 +#define GL_UNSIGNED_SHORT_5_5_5_1_EXT 0x8034 +#define GL_UNSIGNED_INT_8_8_8_8_EXT 0x8035 +#define GL_UNSIGNED_INT_10_10_10_2_EXT 0x8036 + +#define GLEW_EXT_packed_pixels GLEW_GET_VAR(__GLEW_EXT_packed_pixels) + +#endif /* GL_EXT_packed_pixels */ + +/* ------------------------ GL_EXT_paletted_texture ------------------------ */ + +#ifndef GL_EXT_paletted_texture +#define GL_EXT_paletted_texture 1 + +#define GL_TEXTURE_1D 0x0DE0 +#define GL_TEXTURE_2D 0x0DE1 +#define GL_PROXY_TEXTURE_1D 0x8063 +#define GL_PROXY_TEXTURE_2D 0x8064 +#define GL_TEXTURE_3D_EXT 0x806F +#define GL_PROXY_TEXTURE_3D_EXT 0x8070 +#define GL_COLOR_TABLE_FORMAT_EXT 0x80D8 +#define GL_COLOR_TABLE_WIDTH_EXT 0x80D9 +#define GL_COLOR_TABLE_RED_SIZE_EXT 0x80DA +#define GL_COLOR_TABLE_GREEN_SIZE_EXT 0x80DB +#define GL_COLOR_TABLE_BLUE_SIZE_EXT 0x80DC +#define GL_COLOR_TABLE_ALPHA_SIZE_EXT 0x80DD +#define GL_COLOR_TABLE_LUMINANCE_SIZE_EXT 0x80DE +#define GL_COLOR_TABLE_INTENSITY_SIZE_EXT 0x80DF +#define GL_COLOR_INDEX1_EXT 0x80E2 +#define GL_COLOR_INDEX2_EXT 0x80E3 +#define GL_COLOR_INDEX4_EXT 0x80E4 +#define GL_COLOR_INDEX8_EXT 0x80E5 +#define GL_COLOR_INDEX12_EXT 0x80E6 +#define GL_COLOR_INDEX16_EXT 0x80E7 +#define GL_TEXTURE_INDEX_SIZE_EXT 0x80ED +#define GL_TEXTURE_CUBE_MAP_ARB 0x8513 +#define GL_PROXY_TEXTURE_CUBE_MAP_ARB 0x851B + +typedef void (GLAPIENTRY * PFNGLCOLORTABLEEXTPROC) (GLenum target, GLenum internalFormat, GLsizei width, GLenum format, GLenum type, const void* data); +typedef void (GLAPIENTRY * PFNGLGETCOLORTABLEEXTPROC) (GLenum target, GLenum format, GLenum type, void* data); +typedef void (GLAPIENTRY * PFNGLGETCOLORTABLEPARAMETERFVEXTPROC) (GLenum target, GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETCOLORTABLEPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint* params); + +#define glColorTableEXT GLEW_GET_FUN(__glewColorTableEXT) +#define glGetColorTableEXT GLEW_GET_FUN(__glewGetColorTableEXT) +#define glGetColorTableParameterfvEXT GLEW_GET_FUN(__glewGetColorTableParameterfvEXT) +#define glGetColorTableParameterivEXT GLEW_GET_FUN(__glewGetColorTableParameterivEXT) + +#define GLEW_EXT_paletted_texture GLEW_GET_VAR(__GLEW_EXT_paletted_texture) + +#endif /* GL_EXT_paletted_texture */ + +/* ----------------------- GL_EXT_pixel_buffer_object ---------------------- */ + +#ifndef GL_EXT_pixel_buffer_object +#define GL_EXT_pixel_buffer_object 1 + +#define GL_PIXEL_PACK_BUFFER_EXT 0x88EB +#define GL_PIXEL_UNPACK_BUFFER_EXT 0x88EC +#define GL_PIXEL_PACK_BUFFER_BINDING_EXT 0x88ED +#define GL_PIXEL_UNPACK_BUFFER_BINDING_EXT 0x88EF + +#define GLEW_EXT_pixel_buffer_object GLEW_GET_VAR(__GLEW_EXT_pixel_buffer_object) + +#endif /* GL_EXT_pixel_buffer_object */ + +/* ------------------------- GL_EXT_pixel_transform ------------------------ */ + +#ifndef GL_EXT_pixel_transform +#define GL_EXT_pixel_transform 1 + +#define GL_PIXEL_TRANSFORM_2D_EXT 0x8330 +#define GL_PIXEL_MAG_FILTER_EXT 0x8331 +#define GL_PIXEL_MIN_FILTER_EXT 0x8332 +#define GL_PIXEL_CUBIC_WEIGHT_EXT 0x8333 +#define GL_CUBIC_EXT 0x8334 +#define GL_AVERAGE_EXT 0x8335 +#define GL_PIXEL_TRANSFORM_2D_STACK_DEPTH_EXT 0x8336 +#define GL_MAX_PIXEL_TRANSFORM_2D_STACK_DEPTH_EXT 0x8337 +#define GL_PIXEL_TRANSFORM_2D_MATRIX_EXT 0x8338 + +typedef void (GLAPIENTRY * PFNGLGETPIXELTRANSFORMPARAMETERFVEXTPROC) (GLenum target, GLenum pname, const GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETPIXELTRANSFORMPARAMETERIVEXTPROC) (GLenum target, GLenum pname, const GLint* params); +typedef void (GLAPIENTRY * PFNGLPIXELTRANSFORMPARAMETERFEXTPROC) (GLenum target, GLenum pname, const GLfloat param); +typedef void (GLAPIENTRY * PFNGLPIXELTRANSFORMPARAMETERFVEXTPROC) (GLenum target, GLenum pname, const GLfloat* params); +typedef void (GLAPIENTRY * PFNGLPIXELTRANSFORMPARAMETERIEXTPROC) (GLenum target, GLenum pname, const GLint param); +typedef void (GLAPIENTRY * PFNGLPIXELTRANSFORMPARAMETERIVEXTPROC) (GLenum target, GLenum pname, const GLint* params); + +#define glGetPixelTransformParameterfvEXT GLEW_GET_FUN(__glewGetPixelTransformParameterfvEXT) +#define glGetPixelTransformParameterivEXT GLEW_GET_FUN(__glewGetPixelTransformParameterivEXT) +#define glPixelTransformParameterfEXT GLEW_GET_FUN(__glewPixelTransformParameterfEXT) +#define glPixelTransformParameterfvEXT GLEW_GET_FUN(__glewPixelTransformParameterfvEXT) +#define glPixelTransformParameteriEXT GLEW_GET_FUN(__glewPixelTransformParameteriEXT) +#define glPixelTransformParameterivEXT GLEW_GET_FUN(__glewPixelTransformParameterivEXT) + +#define GLEW_EXT_pixel_transform GLEW_GET_VAR(__GLEW_EXT_pixel_transform) + +#endif /* GL_EXT_pixel_transform */ + +/* ------------------- GL_EXT_pixel_transform_color_table ------------------ */ + +#ifndef GL_EXT_pixel_transform_color_table +#define GL_EXT_pixel_transform_color_table 1 + +#define GLEW_EXT_pixel_transform_color_table GLEW_GET_VAR(__GLEW_EXT_pixel_transform_color_table) + +#endif /* GL_EXT_pixel_transform_color_table */ + +/* ------------------------ GL_EXT_point_parameters ------------------------ */ + +#ifndef GL_EXT_point_parameters +#define GL_EXT_point_parameters 1 + +#define GL_POINT_SIZE_MIN_EXT 0x8126 +#define GL_POINT_SIZE_MAX_EXT 0x8127 +#define GL_POINT_FADE_THRESHOLD_SIZE_EXT 0x8128 +#define GL_DISTANCE_ATTENUATION_EXT 0x8129 + +typedef void (GLAPIENTRY * PFNGLPOINTPARAMETERFEXTPROC) (GLenum pname, GLfloat param); +typedef void (GLAPIENTRY * PFNGLPOINTPARAMETERFVEXTPROC) (GLenum pname, GLfloat* params); + +#define glPointParameterfEXT GLEW_GET_FUN(__glewPointParameterfEXT) +#define glPointParameterfvEXT GLEW_GET_FUN(__glewPointParameterfvEXT) + +#define GLEW_EXT_point_parameters GLEW_GET_VAR(__GLEW_EXT_point_parameters) + +#endif /* GL_EXT_point_parameters */ + +/* ------------------------- GL_EXT_polygon_offset ------------------------- */ + +#ifndef GL_EXT_polygon_offset +#define GL_EXT_polygon_offset 1 + +#define GL_POLYGON_OFFSET_EXT 0x8037 +#define GL_POLYGON_OFFSET_FACTOR_EXT 0x8038 +#define GL_POLYGON_OFFSET_BIAS_EXT 0x8039 + +typedef void (GLAPIENTRY * PFNGLPOLYGONOFFSETEXTPROC) (GLfloat factor, GLfloat bias); + +#define glPolygonOffsetEXT GLEW_GET_FUN(__glewPolygonOffsetEXT) + +#define GLEW_EXT_polygon_offset GLEW_GET_VAR(__GLEW_EXT_polygon_offset) + +#endif /* GL_EXT_polygon_offset */ + +/* ------------------------- GL_EXT_rescale_normal ------------------------- */ + +#ifndef GL_EXT_rescale_normal +#define GL_EXT_rescale_normal 1 + +#define GLEW_EXT_rescale_normal GLEW_GET_VAR(__GLEW_EXT_rescale_normal) + +#endif /* GL_EXT_rescale_normal */ + +/* -------------------------- GL_EXT_scene_marker -------------------------- */ + +#ifndef GL_EXT_scene_marker +#define GL_EXT_scene_marker 1 + +typedef void (GLAPIENTRY * PFNGLBEGINSCENEEXTPROC) (void); +typedef void (GLAPIENTRY * PFNGLENDSCENEEXTPROC) (void); + +#define glBeginSceneEXT GLEW_GET_FUN(__glewBeginSceneEXT) +#define glEndSceneEXT GLEW_GET_FUN(__glewEndSceneEXT) + +#define GLEW_EXT_scene_marker GLEW_GET_VAR(__GLEW_EXT_scene_marker) + +#endif /* GL_EXT_scene_marker */ + +/* ------------------------- GL_EXT_secondary_color ------------------------ */ + +#ifndef GL_EXT_secondary_color +#define GL_EXT_secondary_color 1 + +#define GL_COLOR_SUM_EXT 0x8458 +#define GL_CURRENT_SECONDARY_COLOR_EXT 0x8459 +#define GL_SECONDARY_COLOR_ARRAY_SIZE_EXT 0x845A +#define GL_SECONDARY_COLOR_ARRAY_TYPE_EXT 0x845B +#define GL_SECONDARY_COLOR_ARRAY_STRIDE_EXT 0x845C +#define GL_SECONDARY_COLOR_ARRAY_POINTER_EXT 0x845D +#define GL_SECONDARY_COLOR_ARRAY_EXT 0x845E + +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3BEXTPROC) (GLbyte red, GLbyte green, GLbyte blue); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3BVEXTPROC) (const GLbyte *v); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3DEXTPROC) (GLdouble red, GLdouble green, GLdouble blue); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3DVEXTPROC) (const GLdouble *v); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3FEXTPROC) (GLfloat red, GLfloat green, GLfloat blue); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3FVEXTPROC) (const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3IEXTPROC) (GLint red, GLint green, GLint blue); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3IVEXTPROC) (const GLint *v); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3SEXTPROC) (GLshort red, GLshort green, GLshort blue); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3SVEXTPROC) (const GLshort *v); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3UBEXTPROC) (GLubyte red, GLubyte green, GLubyte blue); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3UBVEXTPROC) (const GLubyte *v); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3UIEXTPROC) (GLuint red, GLuint green, GLuint blue); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3UIVEXTPROC) (const GLuint *v); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3USEXTPROC) (GLushort red, GLushort green, GLushort blue); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3USVEXTPROC) (const GLushort *v); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLORPOINTEREXTPROC) (GLint size, GLenum type, GLsizei stride, GLvoid *pointer); + +#define glSecondaryColor3bEXT GLEW_GET_FUN(__glewSecondaryColor3bEXT) +#define glSecondaryColor3bvEXT GLEW_GET_FUN(__glewSecondaryColor3bvEXT) +#define glSecondaryColor3dEXT GLEW_GET_FUN(__glewSecondaryColor3dEXT) +#define glSecondaryColor3dvEXT GLEW_GET_FUN(__glewSecondaryColor3dvEXT) +#define glSecondaryColor3fEXT GLEW_GET_FUN(__glewSecondaryColor3fEXT) +#define glSecondaryColor3fvEXT GLEW_GET_FUN(__glewSecondaryColor3fvEXT) +#define glSecondaryColor3iEXT GLEW_GET_FUN(__glewSecondaryColor3iEXT) +#define glSecondaryColor3ivEXT GLEW_GET_FUN(__glewSecondaryColor3ivEXT) +#define glSecondaryColor3sEXT GLEW_GET_FUN(__glewSecondaryColor3sEXT) +#define glSecondaryColor3svEXT GLEW_GET_FUN(__glewSecondaryColor3svEXT) +#define glSecondaryColor3ubEXT GLEW_GET_FUN(__glewSecondaryColor3ubEXT) +#define glSecondaryColor3ubvEXT GLEW_GET_FUN(__glewSecondaryColor3ubvEXT) +#define glSecondaryColor3uiEXT GLEW_GET_FUN(__glewSecondaryColor3uiEXT) +#define glSecondaryColor3uivEXT GLEW_GET_FUN(__glewSecondaryColor3uivEXT) +#define glSecondaryColor3usEXT GLEW_GET_FUN(__glewSecondaryColor3usEXT) +#define glSecondaryColor3usvEXT GLEW_GET_FUN(__glewSecondaryColor3usvEXT) +#define glSecondaryColorPointerEXT GLEW_GET_FUN(__glewSecondaryColorPointerEXT) + +#define GLEW_EXT_secondary_color GLEW_GET_VAR(__GLEW_EXT_secondary_color) + +#endif /* GL_EXT_secondary_color */ + +/* --------------------- GL_EXT_separate_specular_color -------------------- */ + +#ifndef GL_EXT_separate_specular_color +#define GL_EXT_separate_specular_color 1 + +#define GL_LIGHT_MODEL_COLOR_CONTROL_EXT 0x81F8 +#define GL_SINGLE_COLOR_EXT 0x81F9 +#define GL_SEPARATE_SPECULAR_COLOR_EXT 0x81FA + +#define GLEW_EXT_separate_specular_color GLEW_GET_VAR(__GLEW_EXT_separate_specular_color) + +#endif /* GL_EXT_separate_specular_color */ + +/* -------------------------- GL_EXT_shadow_funcs -------------------------- */ + +#ifndef GL_EXT_shadow_funcs +#define GL_EXT_shadow_funcs 1 + +#define GLEW_EXT_shadow_funcs GLEW_GET_VAR(__GLEW_EXT_shadow_funcs) + +#endif /* GL_EXT_shadow_funcs */ + +/* --------------------- GL_EXT_shared_texture_palette --------------------- */ + +#ifndef GL_EXT_shared_texture_palette +#define GL_EXT_shared_texture_palette 1 + +#define GL_SHARED_TEXTURE_PALETTE_EXT 0x81FB + +#define GLEW_EXT_shared_texture_palette GLEW_GET_VAR(__GLEW_EXT_shared_texture_palette) + +#endif /* GL_EXT_shared_texture_palette */ + +/* ------------------------ GL_EXT_stencil_clear_tag ----------------------- */ + +#ifndef GL_EXT_stencil_clear_tag +#define GL_EXT_stencil_clear_tag 1 + +#define GL_STENCIL_TAG_BITS_EXT 0x88F2 +#define GL_STENCIL_CLEAR_TAG_VALUE_EXT 0x88F3 + +#define GLEW_EXT_stencil_clear_tag GLEW_GET_VAR(__GLEW_EXT_stencil_clear_tag) + +#endif /* GL_EXT_stencil_clear_tag */ + +/* ------------------------ GL_EXT_stencil_two_side ------------------------ */ + +#ifndef GL_EXT_stencil_two_side +#define GL_EXT_stencil_two_side 1 + +#define GL_STENCIL_TEST_TWO_SIDE_EXT 0x8910 +#define GL_ACTIVE_STENCIL_FACE_EXT 0x8911 + +typedef void (GLAPIENTRY * PFNGLACTIVESTENCILFACEEXTPROC) (GLenum face); + +#define glActiveStencilFaceEXT GLEW_GET_FUN(__glewActiveStencilFaceEXT) + +#define GLEW_EXT_stencil_two_side GLEW_GET_VAR(__GLEW_EXT_stencil_two_side) + +#endif /* GL_EXT_stencil_two_side */ + +/* -------------------------- GL_EXT_stencil_wrap -------------------------- */ + +#ifndef GL_EXT_stencil_wrap +#define GL_EXT_stencil_wrap 1 + +#define GL_INCR_WRAP_EXT 0x8507 +#define GL_DECR_WRAP_EXT 0x8508 + +#define GLEW_EXT_stencil_wrap GLEW_GET_VAR(__GLEW_EXT_stencil_wrap) + +#endif /* GL_EXT_stencil_wrap */ + +/* --------------------------- GL_EXT_subtexture --------------------------- */ + +#ifndef GL_EXT_subtexture +#define GL_EXT_subtexture 1 + +typedef void (GLAPIENTRY * PFNGLTEXSUBIMAGE1DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const void* pixels); +typedef void (GLAPIENTRY * PFNGLTEXSUBIMAGE2DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void* pixels); +typedef void (GLAPIENTRY * PFNGLTEXSUBIMAGE3DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void* pixels); + +#define glTexSubImage1DEXT GLEW_GET_FUN(__glewTexSubImage1DEXT) +#define glTexSubImage2DEXT GLEW_GET_FUN(__glewTexSubImage2DEXT) +#define glTexSubImage3DEXT GLEW_GET_FUN(__glewTexSubImage3DEXT) + +#define GLEW_EXT_subtexture GLEW_GET_VAR(__GLEW_EXT_subtexture) + +#endif /* GL_EXT_subtexture */ + +/* ----------------------------- GL_EXT_texture ---------------------------- */ + +#ifndef GL_EXT_texture +#define GL_EXT_texture 1 + +#define GL_ALPHA4_EXT 0x803B +#define GL_ALPHA8_EXT 0x803C +#define GL_ALPHA12_EXT 0x803D +#define GL_ALPHA16_EXT 0x803E +#define GL_LUMINANCE4_EXT 0x803F +#define GL_LUMINANCE8_EXT 0x8040 +#define GL_LUMINANCE12_EXT 0x8041 +#define GL_LUMINANCE16_EXT 0x8042 +#define GL_LUMINANCE4_ALPHA4_EXT 0x8043 +#define GL_LUMINANCE6_ALPHA2_EXT 0x8044 +#define GL_LUMINANCE8_ALPHA8_EXT 0x8045 +#define GL_LUMINANCE12_ALPHA4_EXT 0x8046 +#define GL_LUMINANCE12_ALPHA12_EXT 0x8047 +#define GL_LUMINANCE16_ALPHA16_EXT 0x8048 +#define GL_INTENSITY_EXT 0x8049 +#define GL_INTENSITY4_EXT 0x804A +#define GL_INTENSITY8_EXT 0x804B +#define GL_INTENSITY12_EXT 0x804C +#define GL_INTENSITY16_EXT 0x804D +#define GL_RGB2_EXT 0x804E +#define GL_RGB4_EXT 0x804F +#define GL_RGB5_EXT 0x8050 +#define GL_RGB8_EXT 0x8051 +#define GL_RGB10_EXT 0x8052 +#define GL_RGB12_EXT 0x8053 +#define GL_RGB16_EXT 0x8054 +#define GL_RGBA2_EXT 0x8055 +#define GL_RGBA4_EXT 0x8056 +#define GL_RGB5_A1_EXT 0x8057 +#define GL_RGBA8_EXT 0x8058 +#define GL_RGB10_A2_EXT 0x8059 +#define GL_RGBA12_EXT 0x805A +#define GL_RGBA16_EXT 0x805B +#define GL_TEXTURE_RED_SIZE_EXT 0x805C +#define GL_TEXTURE_GREEN_SIZE_EXT 0x805D +#define GL_TEXTURE_BLUE_SIZE_EXT 0x805E +#define GL_TEXTURE_ALPHA_SIZE_EXT 0x805F +#define GL_TEXTURE_LUMINANCE_SIZE_EXT 0x8060 +#define GL_TEXTURE_INTENSITY_SIZE_EXT 0x8061 +#define GL_REPLACE_EXT 0x8062 +#define GL_PROXY_TEXTURE_1D_EXT 0x8063 +#define GL_PROXY_TEXTURE_2D_EXT 0x8064 + +#define GLEW_EXT_texture GLEW_GET_VAR(__GLEW_EXT_texture) + +#endif /* GL_EXT_texture */ + +/* ---------------------------- GL_EXT_texture3D --------------------------- */ + +#ifndef GL_EXT_texture3D +#define GL_EXT_texture3D 1 + +#define GL_PACK_SKIP_IMAGES_EXT 0x806B +#define GL_PACK_IMAGE_HEIGHT_EXT 0x806C +#define GL_UNPACK_SKIP_IMAGES_EXT 0x806D +#define GL_UNPACK_IMAGE_HEIGHT_EXT 0x806E +#define GL_TEXTURE_3D_EXT 0x806F +#define GL_PROXY_TEXTURE_3D_EXT 0x8070 +#define GL_TEXTURE_DEPTH_EXT 0x8071 +#define GL_TEXTURE_WRAP_R_EXT 0x8072 +#define GL_MAX_3D_TEXTURE_SIZE_EXT 0x8073 + +typedef void (GLAPIENTRY * PFNGLTEXIMAGE3DEXTPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void* pixels); + +#define glTexImage3DEXT GLEW_GET_FUN(__glewTexImage3DEXT) + +#define GLEW_EXT_texture3D GLEW_GET_VAR(__GLEW_EXT_texture3D) + +#endif /* GL_EXT_texture3D */ + +/* -------------------- GL_EXT_texture_compression_dxt1 -------------------- */ + +#ifndef GL_EXT_texture_compression_dxt1 +#define GL_EXT_texture_compression_dxt1 1 + +#define GL_COMPRESSED_RGB_S3TC_DXT1_EXT 0x83F0 +#define GL_COMPRESSED_RGBA_S3TC_DXT1_EXT 0x83F1 + +#define GLEW_EXT_texture_compression_dxt1 GLEW_GET_VAR(__GLEW_EXT_texture_compression_dxt1) + +#endif /* GL_EXT_texture_compression_dxt1 */ + +/* -------------------- GL_EXT_texture_compression_s3tc -------------------- */ + +#ifndef GL_EXT_texture_compression_s3tc +#define GL_EXT_texture_compression_s3tc 1 + +#define GL_COMPRESSED_RGB_S3TC_DXT1_EXT 0x83F0 +#define GL_COMPRESSED_RGBA_S3TC_DXT1_EXT 0x83F1 +#define GL_COMPRESSED_RGBA_S3TC_DXT3_EXT 0x83F2 +#define GL_COMPRESSED_RGBA_S3TC_DXT5_EXT 0x83F3 + +#define GLEW_EXT_texture_compression_s3tc GLEW_GET_VAR(__GLEW_EXT_texture_compression_s3tc) + +#endif /* GL_EXT_texture_compression_s3tc */ + +/* ------------------------ GL_EXT_texture_cube_map ------------------------ */ + +#ifndef GL_EXT_texture_cube_map +#define GL_EXT_texture_cube_map 1 + +#define GL_NORMAL_MAP_EXT 0x8511 +#define GL_REFLECTION_MAP_EXT 0x8512 +#define GL_TEXTURE_CUBE_MAP_EXT 0x8513 +#define GL_TEXTURE_BINDING_CUBE_MAP_EXT 0x8514 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_X_EXT 0x8515 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X_EXT 0x8516 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y_EXT 0x8517 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_EXT 0x8518 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z_EXT 0x8519 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_EXT 0x851A +#define GL_PROXY_TEXTURE_CUBE_MAP_EXT 0x851B +#define GL_MAX_CUBE_MAP_TEXTURE_SIZE_EXT 0x851C + +#define GLEW_EXT_texture_cube_map GLEW_GET_VAR(__GLEW_EXT_texture_cube_map) + +#endif /* GL_EXT_texture_cube_map */ + +/* ----------------------- GL_EXT_texture_edge_clamp ----------------------- */ + +#ifndef GL_EXT_texture_edge_clamp +#define GL_EXT_texture_edge_clamp 1 + +#define GL_CLAMP_TO_EDGE_EXT 0x812F + +#define GLEW_EXT_texture_edge_clamp GLEW_GET_VAR(__GLEW_EXT_texture_edge_clamp) + +#endif /* GL_EXT_texture_edge_clamp */ + +/* --------------------------- GL_EXT_texture_env -------------------------- */ + +#ifndef GL_EXT_texture_env +#define GL_EXT_texture_env 1 + +#define GL_TEXTURE_ENV0_EXT 0 +#define GL_ENV_BLEND_EXT 0 +#define GL_TEXTURE_ENV_SHIFT_EXT 0 +#define GL_ENV_REPLACE_EXT 0 +#define GL_ENV_ADD_EXT 0 +#define GL_ENV_SUBTRACT_EXT 0 +#define GL_TEXTURE_ENV_MODE_ALPHA_EXT 0 +#define GL_ENV_REVERSE_SUBTRACT_EXT 0 +#define GL_ENV_REVERSE_BLEND_EXT 0 +#define GL_ENV_COPY_EXT 0 +#define GL_ENV_MODULATE_EXT 0 + +#define GLEW_EXT_texture_env GLEW_GET_VAR(__GLEW_EXT_texture_env) + +#endif /* GL_EXT_texture_env */ + +/* ------------------------- GL_EXT_texture_env_add ------------------------ */ + +#ifndef GL_EXT_texture_env_add +#define GL_EXT_texture_env_add 1 + +#define GLEW_EXT_texture_env_add GLEW_GET_VAR(__GLEW_EXT_texture_env_add) + +#endif /* GL_EXT_texture_env_add */ + +/* ----------------------- GL_EXT_texture_env_combine ---------------------- */ + +#ifndef GL_EXT_texture_env_combine +#define GL_EXT_texture_env_combine 1 + +#define GL_COMBINE_EXT 0x8570 +#define GL_COMBINE_RGB_EXT 0x8571 +#define GL_COMBINE_ALPHA_EXT 0x8572 +#define GL_RGB_SCALE_EXT 0x8573 +#define GL_ADD_SIGNED_EXT 0x8574 +#define GL_INTERPOLATE_EXT 0x8575 +#define GL_CONSTANT_EXT 0x8576 +#define GL_PRIMARY_COLOR_EXT 0x8577 +#define GL_PREVIOUS_EXT 0x8578 +#define GL_SOURCE0_RGB_EXT 0x8580 +#define GL_SOURCE1_RGB_EXT 0x8581 +#define GL_SOURCE2_RGB_EXT 0x8582 +#define GL_SOURCE0_ALPHA_EXT 0x8588 +#define GL_SOURCE1_ALPHA_EXT 0x8589 +#define GL_SOURCE2_ALPHA_EXT 0x858A +#define GL_OPERAND0_RGB_EXT 0x8590 +#define GL_OPERAND1_RGB_EXT 0x8591 +#define GL_OPERAND2_RGB_EXT 0x8592 +#define GL_OPERAND0_ALPHA_EXT 0x8598 +#define GL_OPERAND1_ALPHA_EXT 0x8599 +#define GL_OPERAND2_ALPHA_EXT 0x859A + +#define GLEW_EXT_texture_env_combine GLEW_GET_VAR(__GLEW_EXT_texture_env_combine) + +#endif /* GL_EXT_texture_env_combine */ + +/* ------------------------ GL_EXT_texture_env_dot3 ------------------------ */ + +#ifndef GL_EXT_texture_env_dot3 +#define GL_EXT_texture_env_dot3 1 + +#define GL_DOT3_RGB_EXT 0x8740 +#define GL_DOT3_RGBA_EXT 0x8741 + +#define GLEW_EXT_texture_env_dot3 GLEW_GET_VAR(__GLEW_EXT_texture_env_dot3) + +#endif /* GL_EXT_texture_env_dot3 */ + +/* ------------------- GL_EXT_texture_filter_anisotropic ------------------- */ + +#ifndef GL_EXT_texture_filter_anisotropic +#define GL_EXT_texture_filter_anisotropic 1 + +#define GL_TEXTURE_MAX_ANISOTROPY_EXT 0x84FE +#define GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT 0x84FF + +#define GLEW_EXT_texture_filter_anisotropic GLEW_GET_VAR(__GLEW_EXT_texture_filter_anisotropic) + +#endif /* GL_EXT_texture_filter_anisotropic */ + +/* ------------------------ GL_EXT_texture_lod_bias ------------------------ */ + +#ifndef GL_EXT_texture_lod_bias +#define GL_EXT_texture_lod_bias 1 + +#define GL_MAX_TEXTURE_LOD_BIAS_EXT 0x84FD +#define GL_TEXTURE_FILTER_CONTROL_EXT 0x8500 +#define GL_TEXTURE_LOD_BIAS_EXT 0x8501 + +#define GLEW_EXT_texture_lod_bias GLEW_GET_VAR(__GLEW_EXT_texture_lod_bias) + +#endif /* GL_EXT_texture_lod_bias */ + +/* ---------------------- GL_EXT_texture_mirror_clamp ---------------------- */ + +#ifndef GL_EXT_texture_mirror_clamp +#define GL_EXT_texture_mirror_clamp 1 + +#define GL_MIRROR_CLAMP_EXT 0x8742 +#define GL_MIRROR_CLAMP_TO_EDGE_EXT 0x8743 +#define GL_MIRROR_CLAMP_TO_BORDER_EXT 0x8912 + +#define GLEW_EXT_texture_mirror_clamp GLEW_GET_VAR(__GLEW_EXT_texture_mirror_clamp) + +#endif /* GL_EXT_texture_mirror_clamp */ + +/* ------------------------- GL_EXT_texture_object ------------------------- */ + +#ifndef GL_EXT_texture_object +#define GL_EXT_texture_object 1 + +#define GL_TEXTURE_PRIORITY_EXT 0x8066 +#define GL_TEXTURE_RESIDENT_EXT 0x8067 +#define GL_TEXTURE_1D_BINDING_EXT 0x8068 +#define GL_TEXTURE_2D_BINDING_EXT 0x8069 +#define GL_TEXTURE_3D_BINDING_EXT 0x806A + +typedef GLboolean (GLAPIENTRY * PFNGLARETEXTURESRESIDENTEXTPROC) (GLsizei n, const GLuint* textures, GLboolean* residences); +typedef void (GLAPIENTRY * PFNGLBINDTEXTUREEXTPROC) (GLenum target, GLuint texture); +typedef void (GLAPIENTRY * PFNGLDELETETEXTURESEXTPROC) (GLsizei n, const GLuint* textures); +typedef void (GLAPIENTRY * PFNGLGENTEXTURESEXTPROC) (GLsizei n, GLuint* textures); +typedef GLboolean (GLAPIENTRY * PFNGLISTEXTUREEXTPROC) (GLuint texture); +typedef void (GLAPIENTRY * PFNGLPRIORITIZETEXTURESEXTPROC) (GLsizei n, const GLuint* textures, const GLclampf* priorities); + +#define glAreTexturesResidentEXT GLEW_GET_FUN(__glewAreTexturesResidentEXT) +#define glBindTextureEXT GLEW_GET_FUN(__glewBindTextureEXT) +#define glDeleteTexturesEXT GLEW_GET_FUN(__glewDeleteTexturesEXT) +#define glGenTexturesEXT GLEW_GET_FUN(__glewGenTexturesEXT) +#define glIsTextureEXT GLEW_GET_FUN(__glewIsTextureEXT) +#define glPrioritizeTexturesEXT GLEW_GET_FUN(__glewPrioritizeTexturesEXT) + +#define GLEW_EXT_texture_object GLEW_GET_VAR(__GLEW_EXT_texture_object) + +#endif /* GL_EXT_texture_object */ + +/* --------------------- GL_EXT_texture_perturb_normal --------------------- */ + +#ifndef GL_EXT_texture_perturb_normal +#define GL_EXT_texture_perturb_normal 1 + +#define GL_PERTURB_EXT 0x85AE +#define GL_TEXTURE_NORMAL_EXT 0x85AF + +typedef void (GLAPIENTRY * PFNGLTEXTURENORMALEXTPROC) (GLenum mode); + +#define glTextureNormalEXT GLEW_GET_FUN(__glewTextureNormalEXT) + +#define GLEW_EXT_texture_perturb_normal GLEW_GET_VAR(__GLEW_EXT_texture_perturb_normal) + +#endif /* GL_EXT_texture_perturb_normal */ + +/* ------------------------ GL_EXT_texture_rectangle ----------------------- */ + +#ifndef GL_EXT_texture_rectangle +#define GL_EXT_texture_rectangle 1 + +#define GL_TEXTURE_RECTANGLE_EXT 0x84F5 +#define GL_TEXTURE_BINDING_RECTANGLE_EXT 0x84F6 +#define GL_PROXY_TEXTURE_RECTANGLE_EXT 0x84F7 +#define GL_MAX_RECTANGLE_TEXTURE_SIZE_EXT 0x84F8 + +#define GLEW_EXT_texture_rectangle GLEW_GET_VAR(__GLEW_EXT_texture_rectangle) + +#endif /* GL_EXT_texture_rectangle */ + +/* -------------------------- GL_EXT_texture_sRGB -------------------------- */ + +#ifndef GL_EXT_texture_sRGB +#define GL_EXT_texture_sRGB 1 + +#define GL_SRGB_EXT 0x8C40 +#define GL_SRGB8_EXT 0x8C41 +#define GL_SRGB_ALPHA_EXT 0x8C42 +#define GL_SRGB8_ALPHA8_EXT 0x8C43 +#define GL_SLUMINANCE_ALPHA_EXT 0x8C44 +#define GL_SLUMINANCE8_ALPHA8_EXT 0x8C45 +#define GL_SLUMINANCE_EXT 0x8C46 +#define GL_SLUMINANCE8_EXT 0x8C47 +#define GL_COMPRESSED_SRGB_EXT 0x8C48 +#define GL_COMPRESSED_SRGB_ALPHA_EXT 0x8C49 +#define GL_COMPRESSED_SLUMINANCE_EXT 0x8C4A +#define GL_COMPRESSED_SLUMINANCE_ALPHA_EXT 0x8C4B +#define GL_COMPRESSED_SRGB_S3TC_DXT1_EXT 0x8C4C +#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT 0x8C4D +#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT 0x8C4E +#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT 0x8C4F + +#define GLEW_EXT_texture_sRGB GLEW_GET_VAR(__GLEW_EXT_texture_sRGB) + +#endif /* GL_EXT_texture_sRGB */ + +/* -------------------------- GL_EXT_vertex_array -------------------------- */ + +#ifndef GL_EXT_vertex_array +#define GL_EXT_vertex_array 1 + +#define GL_DOUBLE_EXT 0x140A +#define GL_VERTEX_ARRAY_EXT 0x8074 +#define GL_NORMAL_ARRAY_EXT 0x8075 +#define GL_COLOR_ARRAY_EXT 0x8076 +#define GL_INDEX_ARRAY_EXT 0x8077 +#define GL_TEXTURE_COORD_ARRAY_EXT 0x8078 +#define GL_EDGE_FLAG_ARRAY_EXT 0x8079 +#define GL_VERTEX_ARRAY_SIZE_EXT 0x807A +#define GL_VERTEX_ARRAY_TYPE_EXT 0x807B +#define GL_VERTEX_ARRAY_STRIDE_EXT 0x807C +#define GL_VERTEX_ARRAY_COUNT_EXT 0x807D +#define GL_NORMAL_ARRAY_TYPE_EXT 0x807E +#define GL_NORMAL_ARRAY_STRIDE_EXT 0x807F +#define GL_NORMAL_ARRAY_COUNT_EXT 0x8080 +#define GL_COLOR_ARRAY_SIZE_EXT 0x8081 +#define GL_COLOR_ARRAY_TYPE_EXT 0x8082 +#define GL_COLOR_ARRAY_STRIDE_EXT 0x8083 +#define GL_COLOR_ARRAY_COUNT_EXT 0x8084 +#define GL_INDEX_ARRAY_TYPE_EXT 0x8085 +#define GL_INDEX_ARRAY_STRIDE_EXT 0x8086 +#define GL_INDEX_ARRAY_COUNT_EXT 0x8087 +#define GL_TEXTURE_COORD_ARRAY_SIZE_EXT 0x8088 +#define GL_TEXTURE_COORD_ARRAY_TYPE_EXT 0x8089 +#define GL_TEXTURE_COORD_ARRAY_STRIDE_EXT 0x808A +#define GL_TEXTURE_COORD_ARRAY_COUNT_EXT 0x808B +#define GL_EDGE_FLAG_ARRAY_STRIDE_EXT 0x808C +#define GL_EDGE_FLAG_ARRAY_COUNT_EXT 0x808D +#define GL_VERTEX_ARRAY_POINTER_EXT 0x808E +#define GL_NORMAL_ARRAY_POINTER_EXT 0x808F +#define GL_COLOR_ARRAY_POINTER_EXT 0x8090 +#define GL_INDEX_ARRAY_POINTER_EXT 0x8091 +#define GL_TEXTURE_COORD_ARRAY_POINTER_EXT 0x8092 +#define GL_EDGE_FLAG_ARRAY_POINTER_EXT 0x8093 + +typedef void (GLAPIENTRY * PFNGLARRAYELEMENTEXTPROC) (GLint i); +typedef void (GLAPIENTRY * PFNGLCOLORPOINTEREXTPROC) (GLint size, GLenum type, GLsizei stride, GLsizei count, const void* pointer); +typedef void (GLAPIENTRY * PFNGLDRAWARRAYSEXTPROC) (GLenum mode, GLint first, GLsizei count); +typedef void (GLAPIENTRY * PFNGLEDGEFLAGPOINTEREXTPROC) (GLsizei stride, GLsizei count, const GLboolean* pointer); +typedef void (GLAPIENTRY * PFNGLGETPOINTERVEXTPROC) (GLenum pname, void** params); +typedef void (GLAPIENTRY * PFNGLINDEXPOINTEREXTPROC) (GLenum type, GLsizei stride, GLsizei count, const void* pointer); +typedef void (GLAPIENTRY * PFNGLNORMALPOINTEREXTPROC) (GLenum type, GLsizei stride, GLsizei count, const void* pointer); +typedef void (GLAPIENTRY * PFNGLTEXCOORDPOINTEREXTPROC) (GLint size, GLenum type, GLsizei stride, GLsizei count, const void* pointer); +typedef void (GLAPIENTRY * PFNGLVERTEXPOINTEREXTPROC) (GLint size, GLenum type, GLsizei stride, GLsizei count, const void* pointer); + +#define glArrayElementEXT GLEW_GET_FUN(__glewArrayElementEXT) +#define glColorPointerEXT GLEW_GET_FUN(__glewColorPointerEXT) +#define glDrawArraysEXT GLEW_GET_FUN(__glewDrawArraysEXT) +#define glEdgeFlagPointerEXT GLEW_GET_FUN(__glewEdgeFlagPointerEXT) +#define glGetPointervEXT GLEW_GET_FUN(__glewGetPointervEXT) +#define glIndexPointerEXT GLEW_GET_FUN(__glewIndexPointerEXT) +#define glNormalPointerEXT GLEW_GET_FUN(__glewNormalPointerEXT) +#define glTexCoordPointerEXT GLEW_GET_FUN(__glewTexCoordPointerEXT) +#define glVertexPointerEXT GLEW_GET_FUN(__glewVertexPointerEXT) + +#define GLEW_EXT_vertex_array GLEW_GET_VAR(__GLEW_EXT_vertex_array) + +#endif /* GL_EXT_vertex_array */ + +/* -------------------------- GL_EXT_vertex_shader ------------------------- */ + +#ifndef GL_EXT_vertex_shader +#define GL_EXT_vertex_shader 1 + +#define GL_VERTEX_SHADER_EXT 0x8780 +#define GL_VERTEX_SHADER_BINDING_EXT 0x8781 +#define GL_OP_INDEX_EXT 0x8782 +#define GL_OP_NEGATE_EXT 0x8783 +#define GL_OP_DOT3_EXT 0x8784 +#define GL_OP_DOT4_EXT 0x8785 +#define GL_OP_MUL_EXT 0x8786 +#define GL_OP_ADD_EXT 0x8787 +#define GL_OP_MADD_EXT 0x8788 +#define GL_OP_FRAC_EXT 0x8789 +#define GL_OP_MAX_EXT 0x878A +#define GL_OP_MIN_EXT 0x878B +#define GL_OP_SET_GE_EXT 0x878C +#define GL_OP_SET_LT_EXT 0x878D +#define GL_OP_CLAMP_EXT 0x878E +#define GL_OP_FLOOR_EXT 0x878F +#define GL_OP_ROUND_EXT 0x8790 +#define GL_OP_EXP_BASE_2_EXT 0x8791 +#define GL_OP_LOG_BASE_2_EXT 0x8792 +#define GL_OP_POWER_EXT 0x8793 +#define GL_OP_RECIP_EXT 0x8794 +#define GL_OP_RECIP_SQRT_EXT 0x8795 +#define GL_OP_SUB_EXT 0x8796 +#define GL_OP_CROSS_PRODUCT_EXT 0x8797 +#define GL_OP_MULTIPLY_MATRIX_EXT 0x8798 +#define GL_OP_MOV_EXT 0x8799 +#define GL_OUTPUT_VERTEX_EXT 0x879A +#define GL_OUTPUT_COLOR0_EXT 0x879B +#define GL_OUTPUT_COLOR1_EXT 0x879C +#define GL_OUTPUT_TEXTURE_COORD0_EXT 0x879D +#define GL_OUTPUT_TEXTURE_COORD1_EXT 0x879E +#define GL_OUTPUT_TEXTURE_COORD2_EXT 0x879F +#define GL_OUTPUT_TEXTURE_COORD3_EXT 0x87A0 +#define GL_OUTPUT_TEXTURE_COORD4_EXT 0x87A1 +#define GL_OUTPUT_TEXTURE_COORD5_EXT 0x87A2 +#define GL_OUTPUT_TEXTURE_COORD6_EXT 0x87A3 +#define GL_OUTPUT_TEXTURE_COORD7_EXT 0x87A4 +#define GL_OUTPUT_TEXTURE_COORD8_EXT 0x87A5 +#define GL_OUTPUT_TEXTURE_COORD9_EXT 0x87A6 +#define GL_OUTPUT_TEXTURE_COORD10_EXT 0x87A7 +#define GL_OUTPUT_TEXTURE_COORD11_EXT 0x87A8 +#define GL_OUTPUT_TEXTURE_COORD12_EXT 0x87A9 +#define GL_OUTPUT_TEXTURE_COORD13_EXT 0x87AA +#define GL_OUTPUT_TEXTURE_COORD14_EXT 0x87AB +#define GL_OUTPUT_TEXTURE_COORD15_EXT 0x87AC +#define GL_OUTPUT_TEXTURE_COORD16_EXT 0x87AD +#define GL_OUTPUT_TEXTURE_COORD17_EXT 0x87AE +#define GL_OUTPUT_TEXTURE_COORD18_EXT 0x87AF +#define GL_OUTPUT_TEXTURE_COORD19_EXT 0x87B0 +#define GL_OUTPUT_TEXTURE_COORD20_EXT 0x87B1 +#define GL_OUTPUT_TEXTURE_COORD21_EXT 0x87B2 +#define GL_OUTPUT_TEXTURE_COORD22_EXT 0x87B3 +#define GL_OUTPUT_TEXTURE_COORD23_EXT 0x87B4 +#define GL_OUTPUT_TEXTURE_COORD24_EXT 0x87B5 +#define GL_OUTPUT_TEXTURE_COORD25_EXT 0x87B6 +#define GL_OUTPUT_TEXTURE_COORD26_EXT 0x87B7 +#define GL_OUTPUT_TEXTURE_COORD27_EXT 0x87B8 +#define GL_OUTPUT_TEXTURE_COORD28_EXT 0x87B9 +#define GL_OUTPUT_TEXTURE_COORD29_EXT 0x87BA +#define GL_OUTPUT_TEXTURE_COORD30_EXT 0x87BB +#define GL_OUTPUT_TEXTURE_COORD31_EXT 0x87BC +#define GL_OUTPUT_FOG_EXT 0x87BD +#define GL_SCALAR_EXT 0x87BE +#define GL_VECTOR_EXT 0x87BF +#define GL_MATRIX_EXT 0x87C0 +#define GL_VARIANT_EXT 0x87C1 +#define GL_INVARIANT_EXT 0x87C2 +#define GL_LOCAL_CONSTANT_EXT 0x87C3 +#define GL_LOCAL_EXT 0x87C4 +#define GL_MAX_VERTEX_SHADER_INSTRUCTIONS_EXT 0x87C5 +#define GL_MAX_VERTEX_SHADER_VARIANTS_EXT 0x87C6 +#define GL_MAX_VERTEX_SHADER_INVARIANTS_EXT 0x87C7 +#define GL_MAX_VERTEX_SHADER_LOCAL_CONSTANTS_EXT 0x87C8 +#define GL_MAX_VERTEX_SHADER_LOCALS_EXT 0x87C9 +#define GL_MAX_OPTIMIZED_VERTEX_SHADER_INSTRUCTIONS_EXT 0x87CA +#define GL_MAX_OPTIMIZED_VERTEX_SHADER_VARIANTS_EXT 0x87CB +#define GL_MAX_OPTIMIZED_VERTEX_SHADER_INVARIANTS_EXT 0x87CC +#define GL_MAX_OPTIMIZED_VERTEX_SHADER_LOCAL_CONSTANTS_EXT 0x87CD +#define GL_MAX_OPTIMIZED_VERTEX_SHADER_LOCALS_EXT 0x87CE +#define GL_VERTEX_SHADER_INSTRUCTIONS_EXT 0x87CF +#define GL_VERTEX_SHADER_VARIANTS_EXT 0x87D0 +#define GL_VERTEX_SHADER_INVARIANTS_EXT 0x87D1 +#define GL_VERTEX_SHADER_LOCAL_CONSTANTS_EXT 0x87D2 +#define GL_VERTEX_SHADER_LOCALS_EXT 0x87D3 +#define GL_VERTEX_SHADER_OPTIMIZED_EXT 0x87D4 +#define GL_X_EXT 0x87D5 +#define GL_Y_EXT 0x87D6 +#define GL_Z_EXT 0x87D7 +#define GL_W_EXT 0x87D8 +#define GL_NEGATIVE_X_EXT 0x87D9 +#define GL_NEGATIVE_Y_EXT 0x87DA +#define GL_NEGATIVE_Z_EXT 0x87DB +#define GL_NEGATIVE_W_EXT 0x87DC +#define GL_ZERO_EXT 0x87DD +#define GL_ONE_EXT 0x87DE +#define GL_NEGATIVE_ONE_EXT 0x87DF +#define GL_NORMALIZED_RANGE_EXT 0x87E0 +#define GL_FULL_RANGE_EXT 0x87E1 +#define GL_CURRENT_VERTEX_EXT 0x87E2 +#define GL_MVP_MATRIX_EXT 0x87E3 +#define GL_VARIANT_VALUE_EXT 0x87E4 +#define GL_VARIANT_DATATYPE_EXT 0x87E5 +#define GL_VARIANT_ARRAY_STRIDE_EXT 0x87E6 +#define GL_VARIANT_ARRAY_TYPE_EXT 0x87E7 +#define GL_VARIANT_ARRAY_EXT 0x87E8 +#define GL_VARIANT_ARRAY_POINTER_EXT 0x87E9 +#define GL_INVARIANT_VALUE_EXT 0x87EA +#define GL_INVARIANT_DATATYPE_EXT 0x87EB +#define GL_LOCAL_CONSTANT_VALUE_EXT 0x87EC +#define GL_LOCAL_CONSTANT_DATATYPE_EXT 0x87ED + +typedef void (GLAPIENTRY * PFNGLBEGINVERTEXSHADEREXTPROC) (void); +typedef GLuint (GLAPIENTRY * PFNGLBINDLIGHTPARAMETEREXTPROC) (GLenum light, GLenum value); +typedef GLuint (GLAPIENTRY * PFNGLBINDMATERIALPARAMETEREXTPROC) (GLenum face, GLenum value); +typedef GLuint (GLAPIENTRY * PFNGLBINDPARAMETEREXTPROC) (GLenum value); +typedef GLuint (GLAPIENTRY * PFNGLBINDTEXGENPARAMETEREXTPROC) (GLenum unit, GLenum coord, GLenum value); +typedef GLuint (GLAPIENTRY * PFNGLBINDTEXTUREUNITPARAMETEREXTPROC) (GLenum unit, GLenum value); +typedef void (GLAPIENTRY * PFNGLBINDVERTEXSHADEREXTPROC) (GLuint id); +typedef void (GLAPIENTRY * PFNGLDELETEVERTEXSHADEREXTPROC) (GLuint id); +typedef void (GLAPIENTRY * PFNGLDISABLEVARIANTCLIENTSTATEEXTPROC) (GLuint id); +typedef void (GLAPIENTRY * PFNGLENABLEVARIANTCLIENTSTATEEXTPROC) (GLuint id); +typedef void (GLAPIENTRY * PFNGLENDVERTEXSHADEREXTPROC) (void); +typedef void (GLAPIENTRY * PFNGLEXTRACTCOMPONENTEXTPROC) (GLuint res, GLuint src, GLuint num); +typedef GLuint (GLAPIENTRY * PFNGLGENSYMBOLSEXTPROC) (GLenum dataType, GLenum storageType, GLenum range, GLuint components); +typedef GLuint (GLAPIENTRY * PFNGLGENVERTEXSHADERSEXTPROC) (GLuint range); +typedef void (GLAPIENTRY * PFNGLGETINVARIANTBOOLEANVEXTPROC) (GLuint id, GLenum value, GLboolean *data); +typedef void (GLAPIENTRY * PFNGLGETINVARIANTFLOATVEXTPROC) (GLuint id, GLenum value, GLfloat *data); +typedef void (GLAPIENTRY * PFNGLGETINVARIANTINTEGERVEXTPROC) (GLuint id, GLenum value, GLint *data); +typedef void (GLAPIENTRY * PFNGLGETLOCALCONSTANTBOOLEANVEXTPROC) (GLuint id, GLenum value, GLboolean *data); +typedef void (GLAPIENTRY * PFNGLGETLOCALCONSTANTFLOATVEXTPROC) (GLuint id, GLenum value, GLfloat *data); +typedef void (GLAPIENTRY * PFNGLGETLOCALCONSTANTINTEGERVEXTPROC) (GLuint id, GLenum value, GLint *data); +typedef void (GLAPIENTRY * PFNGLGETVARIANTBOOLEANVEXTPROC) (GLuint id, GLenum value, GLboolean *data); +typedef void (GLAPIENTRY * PFNGLGETVARIANTFLOATVEXTPROC) (GLuint id, GLenum value, GLfloat *data); +typedef void (GLAPIENTRY * PFNGLGETVARIANTINTEGERVEXTPROC) (GLuint id, GLenum value, GLint *data); +typedef void (GLAPIENTRY * PFNGLGETVARIANTPOINTERVEXTPROC) (GLuint id, GLenum value, GLvoid **data); +typedef void (GLAPIENTRY * PFNGLINSERTCOMPONENTEXTPROC) (GLuint res, GLuint src, GLuint num); +typedef GLboolean (GLAPIENTRY * PFNGLISVARIANTENABLEDEXTPROC) (GLuint id, GLenum cap); +typedef void (GLAPIENTRY * PFNGLSETINVARIANTEXTPROC) (GLuint id, GLenum type, GLvoid *addr); +typedef void (GLAPIENTRY * PFNGLSETLOCALCONSTANTEXTPROC) (GLuint id, GLenum type, GLvoid *addr); +typedef void (GLAPIENTRY * PFNGLSHADEROP1EXTPROC) (GLenum op, GLuint res, GLuint arg1); +typedef void (GLAPIENTRY * PFNGLSHADEROP2EXTPROC) (GLenum op, GLuint res, GLuint arg1, GLuint arg2); +typedef void (GLAPIENTRY * PFNGLSHADEROP3EXTPROC) (GLenum op, GLuint res, GLuint arg1, GLuint arg2, GLuint arg3); +typedef void (GLAPIENTRY * PFNGLSWIZZLEEXTPROC) (GLuint res, GLuint in, GLenum outX, GLenum outY, GLenum outZ, GLenum outW); +typedef void (GLAPIENTRY * PFNGLVARIANTPOINTEREXTPROC) (GLuint id, GLenum type, GLuint stride, GLvoid *addr); +typedef void (GLAPIENTRY * PFNGLVARIANTBVEXTPROC) (GLuint id, GLbyte *addr); +typedef void (GLAPIENTRY * PFNGLVARIANTDVEXTPROC) (GLuint id, GLdouble *addr); +typedef void (GLAPIENTRY * PFNGLVARIANTFVEXTPROC) (GLuint id, GLfloat *addr); +typedef void (GLAPIENTRY * PFNGLVARIANTIVEXTPROC) (GLuint id, GLint *addr); +typedef void (GLAPIENTRY * PFNGLVARIANTSVEXTPROC) (GLuint id, GLshort *addr); +typedef void (GLAPIENTRY * PFNGLVARIANTUBVEXTPROC) (GLuint id, GLubyte *addr); +typedef void (GLAPIENTRY * PFNGLVARIANTUIVEXTPROC) (GLuint id, GLuint *addr); +typedef void (GLAPIENTRY * PFNGLVARIANTUSVEXTPROC) (GLuint id, GLushort *addr); +typedef void (GLAPIENTRY * PFNGLWRITEMASKEXTPROC) (GLuint res, GLuint in, GLenum outX, GLenum outY, GLenum outZ, GLenum outW); + +#define glBeginVertexShaderEXT GLEW_GET_FUN(__glewBeginVertexShaderEXT) +#define glBindLightParameterEXT GLEW_GET_FUN(__glewBindLightParameterEXT) +#define glBindMaterialParameterEXT GLEW_GET_FUN(__glewBindMaterialParameterEXT) +#define glBindParameterEXT GLEW_GET_FUN(__glewBindParameterEXT) +#define glBindTexGenParameterEXT GLEW_GET_FUN(__glewBindTexGenParameterEXT) +#define glBindTextureUnitParameterEXT GLEW_GET_FUN(__glewBindTextureUnitParameterEXT) +#define glBindVertexShaderEXT GLEW_GET_FUN(__glewBindVertexShaderEXT) +#define glDeleteVertexShaderEXT GLEW_GET_FUN(__glewDeleteVertexShaderEXT) +#define glDisableVariantClientStateEXT GLEW_GET_FUN(__glewDisableVariantClientStateEXT) +#define glEnableVariantClientStateEXT GLEW_GET_FUN(__glewEnableVariantClientStateEXT) +#define glEndVertexShaderEXT GLEW_GET_FUN(__glewEndVertexShaderEXT) +#define glExtractComponentEXT GLEW_GET_FUN(__glewExtractComponentEXT) +#define glGenSymbolsEXT GLEW_GET_FUN(__glewGenSymbolsEXT) +#define glGenVertexShadersEXT GLEW_GET_FUN(__glewGenVertexShadersEXT) +#define glGetInvariantBooleanvEXT GLEW_GET_FUN(__glewGetInvariantBooleanvEXT) +#define glGetInvariantFloatvEXT GLEW_GET_FUN(__glewGetInvariantFloatvEXT) +#define glGetInvariantIntegervEXT GLEW_GET_FUN(__glewGetInvariantIntegervEXT) +#define glGetLocalConstantBooleanvEXT GLEW_GET_FUN(__glewGetLocalConstantBooleanvEXT) +#define glGetLocalConstantFloatvEXT GLEW_GET_FUN(__glewGetLocalConstantFloatvEXT) +#define glGetLocalConstantIntegervEXT GLEW_GET_FUN(__glewGetLocalConstantIntegervEXT) +#define glGetVariantBooleanvEXT GLEW_GET_FUN(__glewGetVariantBooleanvEXT) +#define glGetVariantFloatvEXT GLEW_GET_FUN(__glewGetVariantFloatvEXT) +#define glGetVariantIntegervEXT GLEW_GET_FUN(__glewGetVariantIntegervEXT) +#define glGetVariantPointervEXT GLEW_GET_FUN(__glewGetVariantPointervEXT) +#define glInsertComponentEXT GLEW_GET_FUN(__glewInsertComponentEXT) +#define glIsVariantEnabledEXT GLEW_GET_FUN(__glewIsVariantEnabledEXT) +#define glSetInvariantEXT GLEW_GET_FUN(__glewSetInvariantEXT) +#define glSetLocalConstantEXT GLEW_GET_FUN(__glewSetLocalConstantEXT) +#define glShaderOp1EXT GLEW_GET_FUN(__glewShaderOp1EXT) +#define glShaderOp2EXT GLEW_GET_FUN(__glewShaderOp2EXT) +#define glShaderOp3EXT GLEW_GET_FUN(__glewShaderOp3EXT) +#define glSwizzleEXT GLEW_GET_FUN(__glewSwizzleEXT) +#define glVariantPointerEXT GLEW_GET_FUN(__glewVariantPointerEXT) +#define glVariantbvEXT GLEW_GET_FUN(__glewVariantbvEXT) +#define glVariantdvEXT GLEW_GET_FUN(__glewVariantdvEXT) +#define glVariantfvEXT GLEW_GET_FUN(__glewVariantfvEXT) +#define glVariantivEXT GLEW_GET_FUN(__glewVariantivEXT) +#define glVariantsvEXT GLEW_GET_FUN(__glewVariantsvEXT) +#define glVariantubvEXT GLEW_GET_FUN(__glewVariantubvEXT) +#define glVariantuivEXT GLEW_GET_FUN(__glewVariantuivEXT) +#define glVariantusvEXT GLEW_GET_FUN(__glewVariantusvEXT) +#define glWriteMaskEXT GLEW_GET_FUN(__glewWriteMaskEXT) + +#define GLEW_EXT_vertex_shader GLEW_GET_VAR(__GLEW_EXT_vertex_shader) + +#endif /* GL_EXT_vertex_shader */ + +/* ------------------------ GL_EXT_vertex_weighting ------------------------ */ + +#ifndef GL_EXT_vertex_weighting +#define GL_EXT_vertex_weighting 1 + +#define GL_MODELVIEW0_STACK_DEPTH_EXT 0x0BA3 +#define GL_MODELVIEW0_MATRIX_EXT 0x0BA6 +#define GL_MODELVIEW0_EXT 0x1700 +#define GL_MODELVIEW1_STACK_DEPTH_EXT 0x8502 +#define GL_MODELVIEW1_MATRIX_EXT 0x8506 +#define GL_VERTEX_WEIGHTING_EXT 0x8509 +#define GL_MODELVIEW1_EXT 0x850A +#define GL_CURRENT_VERTEX_WEIGHT_EXT 0x850B +#define GL_VERTEX_WEIGHT_ARRAY_EXT 0x850C +#define GL_VERTEX_WEIGHT_ARRAY_SIZE_EXT 0x850D +#define GL_VERTEX_WEIGHT_ARRAY_TYPE_EXT 0x850E +#define GL_VERTEX_WEIGHT_ARRAY_STRIDE_EXT 0x850F +#define GL_VERTEX_WEIGHT_ARRAY_POINTER_EXT 0x8510 + +typedef void (GLAPIENTRY * PFNGLVERTEXWEIGHTPOINTEREXTPROC) (GLint size, GLenum type, GLsizei stride, void* pointer); +typedef void (GLAPIENTRY * PFNGLVERTEXWEIGHTFEXTPROC) (GLfloat weight); +typedef void (GLAPIENTRY * PFNGLVERTEXWEIGHTFVEXTPROC) (GLfloat* weight); + +#define glVertexWeightPointerEXT GLEW_GET_FUN(__glewVertexWeightPointerEXT) +#define glVertexWeightfEXT GLEW_GET_FUN(__glewVertexWeightfEXT) +#define glVertexWeightfvEXT GLEW_GET_FUN(__glewVertexWeightfvEXT) + +#define GLEW_EXT_vertex_weighting GLEW_GET_VAR(__GLEW_EXT_vertex_weighting) + +#endif /* GL_EXT_vertex_weighting */ + +/* ------------------------ GL_GREMEDY_string_marker ----------------------- */ + +#ifndef GL_GREMEDY_string_marker +#define GL_GREMEDY_string_marker 1 + +typedef void (GLAPIENTRY * PFNGLSTRINGMARKERGREMEDYPROC) (GLsizei len, const void* string); + +#define glStringMarkerGREMEDY GLEW_GET_FUN(__glewStringMarkerGREMEDY) + +#define GLEW_GREMEDY_string_marker GLEW_GET_VAR(__GLEW_GREMEDY_string_marker) + +#endif /* GL_GREMEDY_string_marker */ + +/* --------------------- GL_HP_convolution_border_modes -------------------- */ + +#ifndef GL_HP_convolution_border_modes +#define GL_HP_convolution_border_modes 1 + +#define GLEW_HP_convolution_border_modes GLEW_GET_VAR(__GLEW_HP_convolution_border_modes) + +#endif /* GL_HP_convolution_border_modes */ + +/* ------------------------- GL_HP_image_transform ------------------------- */ + +#ifndef GL_HP_image_transform +#define GL_HP_image_transform 1 + +typedef void (GLAPIENTRY * PFNGLGETIMAGETRANSFORMPARAMETERFVHPPROC) (GLenum target, GLenum pname, const GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETIMAGETRANSFORMPARAMETERIVHPPROC) (GLenum target, GLenum pname, const GLint* params); +typedef void (GLAPIENTRY * PFNGLIMAGETRANSFORMPARAMETERFHPPROC) (GLenum target, GLenum pname, const GLfloat param); +typedef void (GLAPIENTRY * PFNGLIMAGETRANSFORMPARAMETERFVHPPROC) (GLenum target, GLenum pname, const GLfloat* params); +typedef void (GLAPIENTRY * PFNGLIMAGETRANSFORMPARAMETERIHPPROC) (GLenum target, GLenum pname, const GLint param); +typedef void (GLAPIENTRY * PFNGLIMAGETRANSFORMPARAMETERIVHPPROC) (GLenum target, GLenum pname, const GLint* params); + +#define glGetImageTransformParameterfvHP GLEW_GET_FUN(__glewGetImageTransformParameterfvHP) +#define glGetImageTransformParameterivHP GLEW_GET_FUN(__glewGetImageTransformParameterivHP) +#define glImageTransformParameterfHP GLEW_GET_FUN(__glewImageTransformParameterfHP) +#define glImageTransformParameterfvHP GLEW_GET_FUN(__glewImageTransformParameterfvHP) +#define glImageTransformParameteriHP GLEW_GET_FUN(__glewImageTransformParameteriHP) +#define glImageTransformParameterivHP GLEW_GET_FUN(__glewImageTransformParameterivHP) + +#define GLEW_HP_image_transform GLEW_GET_VAR(__GLEW_HP_image_transform) + +#endif /* GL_HP_image_transform */ + +/* -------------------------- GL_HP_occlusion_test ------------------------- */ + +#ifndef GL_HP_occlusion_test +#define GL_HP_occlusion_test 1 + +#define GL_OCCLUSION_TEST_HP 0x8165 +#define GL_OCCLUSION_TEST_RESULT_HP 0x8166 + +#define GLEW_HP_occlusion_test GLEW_GET_VAR(__GLEW_HP_occlusion_test) + +#endif /* GL_HP_occlusion_test */ + +/* ------------------------- GL_HP_texture_lighting ------------------------ */ + +#ifndef GL_HP_texture_lighting +#define GL_HP_texture_lighting 1 + +#define GLEW_HP_texture_lighting GLEW_GET_VAR(__GLEW_HP_texture_lighting) + +#endif /* GL_HP_texture_lighting */ + +/* --------------------------- GL_IBM_cull_vertex -------------------------- */ + +#ifndef GL_IBM_cull_vertex +#define GL_IBM_cull_vertex 1 + +#define GL_CULL_VERTEX_IBM 103050 + +#define GLEW_IBM_cull_vertex GLEW_GET_VAR(__GLEW_IBM_cull_vertex) + +#endif /* GL_IBM_cull_vertex */ + +/* ---------------------- GL_IBM_multimode_draw_arrays --------------------- */ + +#ifndef GL_IBM_multimode_draw_arrays +#define GL_IBM_multimode_draw_arrays 1 + +typedef void (GLAPIENTRY * PFNGLMULTIMODEDRAWARRAYSIBMPROC) (const GLenum* mode, const GLint *first, const GLsizei *count, GLsizei primcount, GLint modestride); +typedef void (GLAPIENTRY * PFNGLMULTIMODEDRAWELEMENTSIBMPROC) (const GLenum* mode, const GLsizei *count, GLenum type, const GLvoid * const *indices, GLsizei primcount, GLint modestride); + +#define glMultiModeDrawArraysIBM GLEW_GET_FUN(__glewMultiModeDrawArraysIBM) +#define glMultiModeDrawElementsIBM GLEW_GET_FUN(__glewMultiModeDrawElementsIBM) + +#define GLEW_IBM_multimode_draw_arrays GLEW_GET_VAR(__GLEW_IBM_multimode_draw_arrays) + +#endif /* GL_IBM_multimode_draw_arrays */ + +/* ------------------------- GL_IBM_rasterpos_clip ------------------------- */ + +#ifndef GL_IBM_rasterpos_clip +#define GL_IBM_rasterpos_clip 1 + +#define GL_RASTER_POSITION_UNCLIPPED_IBM 103010 + +#define GLEW_IBM_rasterpos_clip GLEW_GET_VAR(__GLEW_IBM_rasterpos_clip) + +#endif /* GL_IBM_rasterpos_clip */ + +/* --------------------------- GL_IBM_static_data -------------------------- */ + +#ifndef GL_IBM_static_data +#define GL_IBM_static_data 1 + +#define GL_ALL_STATIC_DATA_IBM 103060 +#define GL_STATIC_VERTEX_ARRAY_IBM 103061 + +#define GLEW_IBM_static_data GLEW_GET_VAR(__GLEW_IBM_static_data) + +#endif /* GL_IBM_static_data */ + +/* --------------------- GL_IBM_texture_mirrored_repeat -------------------- */ + +#ifndef GL_IBM_texture_mirrored_repeat +#define GL_IBM_texture_mirrored_repeat 1 + +#define GL_MIRRORED_REPEAT_IBM 0x8370 + +#define GLEW_IBM_texture_mirrored_repeat GLEW_GET_VAR(__GLEW_IBM_texture_mirrored_repeat) + +#endif /* GL_IBM_texture_mirrored_repeat */ + +/* ----------------------- GL_IBM_vertex_array_lists ----------------------- */ + +#ifndef GL_IBM_vertex_array_lists +#define GL_IBM_vertex_array_lists 1 + +#define GL_VERTEX_ARRAY_LIST_IBM 103070 +#define GL_NORMAL_ARRAY_LIST_IBM 103071 +#define GL_COLOR_ARRAY_LIST_IBM 103072 +#define GL_INDEX_ARRAY_LIST_IBM 103073 +#define GL_TEXTURE_COORD_ARRAY_LIST_IBM 103074 +#define GL_EDGE_FLAG_ARRAY_LIST_IBM 103075 +#define GL_FOG_COORDINATE_ARRAY_LIST_IBM 103076 +#define GL_SECONDARY_COLOR_ARRAY_LIST_IBM 103077 +#define GL_VERTEX_ARRAY_LIST_STRIDE_IBM 103080 +#define GL_NORMAL_ARRAY_LIST_STRIDE_IBM 103081 +#define GL_COLOR_ARRAY_LIST_STRIDE_IBM 103082 +#define GL_INDEX_ARRAY_LIST_STRIDE_IBM 103083 +#define GL_TEXTURE_COORD_ARRAY_LIST_STRIDE_IBM 103084 +#define GL_EDGE_FLAG_ARRAY_LIST_STRIDE_IBM 103085 +#define GL_FOG_COORDINATE_ARRAY_LIST_STRIDE_IBM 103086 +#define GL_SECONDARY_COLOR_ARRAY_LIST_STRIDE_IBM 103087 + +typedef void (GLAPIENTRY * PFNGLCOLORPOINTERLISTIBMPROC) (GLint size, GLenum type, GLint stride, const GLvoid ** pointer, GLint ptrstride); +typedef void (GLAPIENTRY * PFNGLEDGEFLAGPOINTERLISTIBMPROC) (GLint stride, const GLboolean ** pointer, GLint ptrstride); +typedef void (GLAPIENTRY * PFNGLFOGCOORDPOINTERLISTIBMPROC) (GLenum type, GLint stride, const GLvoid ** pointer, GLint ptrstride); +typedef void (GLAPIENTRY * PFNGLINDEXPOINTERLISTIBMPROC) (GLenum type, GLint stride, const GLvoid ** pointer, GLint ptrstride); +typedef void (GLAPIENTRY * PFNGLNORMALPOINTERLISTIBMPROC) (GLenum type, GLint stride, const GLvoid ** pointer, GLint ptrstride); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLORPOINTERLISTIBMPROC) (GLint size, GLenum type, GLint stride, const GLvoid ** pointer, GLint ptrstride); +typedef void (GLAPIENTRY * PFNGLTEXCOORDPOINTERLISTIBMPROC) (GLint size, GLenum type, GLint stride, const GLvoid ** pointer, GLint ptrstride); +typedef void (GLAPIENTRY * PFNGLVERTEXPOINTERLISTIBMPROC) (GLint size, GLenum type, GLint stride, const GLvoid ** pointer, GLint ptrstride); + +#define glColorPointerListIBM GLEW_GET_FUN(__glewColorPointerListIBM) +#define glEdgeFlagPointerListIBM GLEW_GET_FUN(__glewEdgeFlagPointerListIBM) +#define glFogCoordPointerListIBM GLEW_GET_FUN(__glewFogCoordPointerListIBM) +#define glIndexPointerListIBM GLEW_GET_FUN(__glewIndexPointerListIBM) +#define glNormalPointerListIBM GLEW_GET_FUN(__glewNormalPointerListIBM) +#define glSecondaryColorPointerListIBM GLEW_GET_FUN(__glewSecondaryColorPointerListIBM) +#define glTexCoordPointerListIBM GLEW_GET_FUN(__glewTexCoordPointerListIBM) +#define glVertexPointerListIBM GLEW_GET_FUN(__glewVertexPointerListIBM) + +#define GLEW_IBM_vertex_array_lists GLEW_GET_VAR(__GLEW_IBM_vertex_array_lists) + +#endif /* GL_IBM_vertex_array_lists */ + +/* -------------------------- GL_INGR_color_clamp -------------------------- */ + +#ifndef GL_INGR_color_clamp +#define GL_INGR_color_clamp 1 + +#define GL_RED_MIN_CLAMP_INGR 0x8560 +#define GL_GREEN_MIN_CLAMP_INGR 0x8561 +#define GL_BLUE_MIN_CLAMP_INGR 0x8562 +#define GL_ALPHA_MIN_CLAMP_INGR 0x8563 +#define GL_RED_MAX_CLAMP_INGR 0x8564 +#define GL_GREEN_MAX_CLAMP_INGR 0x8565 +#define GL_BLUE_MAX_CLAMP_INGR 0x8566 +#define GL_ALPHA_MAX_CLAMP_INGR 0x8567 + +#define GLEW_INGR_color_clamp GLEW_GET_VAR(__GLEW_INGR_color_clamp) + +#endif /* GL_INGR_color_clamp */ + +/* ------------------------- GL_INGR_interlace_read ------------------------ */ + +#ifndef GL_INGR_interlace_read +#define GL_INGR_interlace_read 1 + +#define GL_INTERLACE_READ_INGR 0x8568 + +#define GLEW_INGR_interlace_read GLEW_GET_VAR(__GLEW_INGR_interlace_read) + +#endif /* GL_INGR_interlace_read */ + +/* ------------------------ GL_INTEL_parallel_arrays ----------------------- */ + +#ifndef GL_INTEL_parallel_arrays +#define GL_INTEL_parallel_arrays 1 + +#define GL_PARALLEL_ARRAYS_INTEL 0x83F4 +#define GL_VERTEX_ARRAY_PARALLEL_POINTERS_INTEL 0x83F5 +#define GL_NORMAL_ARRAY_PARALLEL_POINTERS_INTEL 0x83F6 +#define GL_COLOR_ARRAY_PARALLEL_POINTERS_INTEL 0x83F7 +#define GL_TEXTURE_COORD_ARRAY_PARALLEL_POINTERS_INTEL 0x83F8 + +typedef void (GLAPIENTRY * PFNGLCOLORPOINTERVINTELPROC) (GLint size, GLenum type, const void** pointer); +typedef void (GLAPIENTRY * PFNGLNORMALPOINTERVINTELPROC) (GLenum type, const void** pointer); +typedef void (GLAPIENTRY * PFNGLTEXCOORDPOINTERVINTELPROC) (GLint size, GLenum type, const void** pointer); +typedef void (GLAPIENTRY * PFNGLVERTEXPOINTERVINTELPROC) (GLint size, GLenum type, const void** pointer); + +#define glColorPointervINTEL GLEW_GET_FUN(__glewColorPointervINTEL) +#define glNormalPointervINTEL GLEW_GET_FUN(__glewNormalPointervINTEL) +#define glTexCoordPointervINTEL GLEW_GET_FUN(__glewTexCoordPointervINTEL) +#define glVertexPointervINTEL GLEW_GET_FUN(__glewVertexPointervINTEL) + +#define GLEW_INTEL_parallel_arrays GLEW_GET_VAR(__GLEW_INTEL_parallel_arrays) + +#endif /* GL_INTEL_parallel_arrays */ + +/* ------------------------ GL_INTEL_texture_scissor ----------------------- */ + +#ifndef GL_INTEL_texture_scissor +#define GL_INTEL_texture_scissor 1 + +typedef void (GLAPIENTRY * PFNGLTEXSCISSORFUNCINTELPROC) (GLenum target, GLenum lfunc, GLenum hfunc); +typedef void (GLAPIENTRY * PFNGLTEXSCISSORINTELPROC) (GLenum target, GLclampf tlow, GLclampf thigh); + +#define glTexScissorFuncINTEL GLEW_GET_FUN(__glewTexScissorFuncINTEL) +#define glTexScissorINTEL GLEW_GET_FUN(__glewTexScissorINTEL) + +#define GLEW_INTEL_texture_scissor GLEW_GET_VAR(__GLEW_INTEL_texture_scissor) + +#endif /* GL_INTEL_texture_scissor */ + +/* -------------------------- GL_KTX_buffer_region ------------------------- */ + +#ifndef GL_KTX_buffer_region +#define GL_KTX_buffer_region 1 + +#define GL_KTX_FRONT_REGION 0x0 +#define GL_KTX_BACK_REGION 0x1 +#define GL_KTX_Z_REGION 0x2 +#define GL_KTX_STENCIL_REGION 0x3 + +typedef GLuint (GLAPIENTRY * PFNGLBUFFERREGIONENABLEDEXTPROC) (void); +typedef void (GLAPIENTRY * PFNGLDELETEBUFFERREGIONEXTPROC) (GLenum region); +typedef void (GLAPIENTRY * PFNGLDRAWBUFFERREGIONEXTPROC) (GLuint region, GLint x, GLint y, GLsizei width, GLsizei height, GLint xDest, GLint yDest); +typedef GLuint (GLAPIENTRY * PFNGLNEWBUFFERREGIONEXTPROC) (GLenum region); +typedef void (GLAPIENTRY * PFNGLREADBUFFERREGIONEXTPROC) (GLuint region, GLint x, GLint y, GLsizei width, GLsizei height); + +#define glBufferRegionEnabledEXT GLEW_GET_FUN(__glewBufferRegionEnabledEXT) +#define glDeleteBufferRegionEXT GLEW_GET_FUN(__glewDeleteBufferRegionEXT) +#define glDrawBufferRegionEXT GLEW_GET_FUN(__glewDrawBufferRegionEXT) +#define glNewBufferRegionEXT GLEW_GET_FUN(__glewNewBufferRegionEXT) +#define glReadBufferRegionEXT GLEW_GET_FUN(__glewReadBufferRegionEXT) + +#define GLEW_KTX_buffer_region GLEW_GET_VAR(__GLEW_KTX_buffer_region) + +#endif /* GL_KTX_buffer_region */ + +/* ------------------------- GL_MESAX_texture_stack ------------------------ */ + +#ifndef GL_MESAX_texture_stack +#define GL_MESAX_texture_stack 1 + +#define GL_TEXTURE_1D_STACK_MESAX 0x8759 +#define GL_TEXTURE_2D_STACK_MESAX 0x875A +#define GL_PROXY_TEXTURE_1D_STACK_MESAX 0x875B +#define GL_PROXY_TEXTURE_2D_STACK_MESAX 0x875C +#define GL_TEXTURE_1D_STACK_BINDING_MESAX 0x875D +#define GL_TEXTURE_2D_STACK_BINDING_MESAX 0x875E + +#define GLEW_MESAX_texture_stack GLEW_GET_VAR(__GLEW_MESAX_texture_stack) + +#endif /* GL_MESAX_texture_stack */ + +/* -------------------------- GL_MESA_pack_invert -------------------------- */ + +#ifndef GL_MESA_pack_invert +#define GL_MESA_pack_invert 1 + +#define GL_PACK_INVERT_MESA 0x8758 + +#define GLEW_MESA_pack_invert GLEW_GET_VAR(__GLEW_MESA_pack_invert) + +#endif /* GL_MESA_pack_invert */ + +/* ------------------------- GL_MESA_resize_buffers ------------------------ */ + +#ifndef GL_MESA_resize_buffers +#define GL_MESA_resize_buffers 1 + +typedef void (GLAPIENTRY * PFNGLRESIZEBUFFERSMESAPROC) (void); + +#define glResizeBuffersMESA GLEW_GET_FUN(__glewResizeBuffersMESA) + +#define GLEW_MESA_resize_buffers GLEW_GET_VAR(__GLEW_MESA_resize_buffers) + +#endif /* GL_MESA_resize_buffers */ + +/* --------------------------- GL_MESA_window_pos -------------------------- */ + +#ifndef GL_MESA_window_pos +#define GL_MESA_window_pos 1 + +typedef void (GLAPIENTRY * PFNGLWINDOWPOS2DMESAPROC) (GLdouble x, GLdouble y); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS2DVMESAPROC) (const GLdouble* p); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS2FMESAPROC) (GLfloat x, GLfloat y); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS2FVMESAPROC) (const GLfloat* p); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS2IMESAPROC) (GLint x, GLint y); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS2IVMESAPROC) (const GLint* p); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS2SMESAPROC) (GLshort x, GLshort y); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS2SVMESAPROC) (const GLshort* p); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS3DMESAPROC) (GLdouble x, GLdouble y, GLdouble z); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS3DVMESAPROC) (const GLdouble* p); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS3FMESAPROC) (GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS3FVMESAPROC) (const GLfloat* p); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS3IMESAPROC) (GLint x, GLint y, GLint z); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS3IVMESAPROC) (const GLint* p); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS3SMESAPROC) (GLshort x, GLshort y, GLshort z); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS3SVMESAPROC) (const GLshort* p); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS4DMESAPROC) (GLdouble x, GLdouble y, GLdouble z, GLdouble); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS4DVMESAPROC) (const GLdouble* p); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS4FMESAPROC) (GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS4FVMESAPROC) (const GLfloat* p); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS4IMESAPROC) (GLint x, GLint y, GLint z, GLint w); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS4IVMESAPROC) (const GLint* p); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS4SMESAPROC) (GLshort x, GLshort y, GLshort z, GLshort w); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS4SVMESAPROC) (const GLshort* p); + +#define glWindowPos2dMESA GLEW_GET_FUN(__glewWindowPos2dMESA) +#define glWindowPos2dvMESA GLEW_GET_FUN(__glewWindowPos2dvMESA) +#define glWindowPos2fMESA GLEW_GET_FUN(__glewWindowPos2fMESA) +#define glWindowPos2fvMESA GLEW_GET_FUN(__glewWindowPos2fvMESA) +#define glWindowPos2iMESA GLEW_GET_FUN(__glewWindowPos2iMESA) +#define glWindowPos2ivMESA GLEW_GET_FUN(__glewWindowPos2ivMESA) +#define glWindowPos2sMESA GLEW_GET_FUN(__glewWindowPos2sMESA) +#define glWindowPos2svMESA GLEW_GET_FUN(__glewWindowPos2svMESA) +#define glWindowPos3dMESA GLEW_GET_FUN(__glewWindowPos3dMESA) +#define glWindowPos3dvMESA GLEW_GET_FUN(__glewWindowPos3dvMESA) +#define glWindowPos3fMESA GLEW_GET_FUN(__glewWindowPos3fMESA) +#define glWindowPos3fvMESA GLEW_GET_FUN(__glewWindowPos3fvMESA) +#define glWindowPos3iMESA GLEW_GET_FUN(__glewWindowPos3iMESA) +#define glWindowPos3ivMESA GLEW_GET_FUN(__glewWindowPos3ivMESA) +#define glWindowPos3sMESA GLEW_GET_FUN(__glewWindowPos3sMESA) +#define glWindowPos3svMESA GLEW_GET_FUN(__glewWindowPos3svMESA) +#define glWindowPos4dMESA GLEW_GET_FUN(__glewWindowPos4dMESA) +#define glWindowPos4dvMESA GLEW_GET_FUN(__glewWindowPos4dvMESA) +#define glWindowPos4fMESA GLEW_GET_FUN(__glewWindowPos4fMESA) +#define glWindowPos4fvMESA GLEW_GET_FUN(__glewWindowPos4fvMESA) +#define glWindowPos4iMESA GLEW_GET_FUN(__glewWindowPos4iMESA) +#define glWindowPos4ivMESA GLEW_GET_FUN(__glewWindowPos4ivMESA) +#define glWindowPos4sMESA GLEW_GET_FUN(__glewWindowPos4sMESA) +#define glWindowPos4svMESA GLEW_GET_FUN(__glewWindowPos4svMESA) + +#define GLEW_MESA_window_pos GLEW_GET_VAR(__GLEW_MESA_window_pos) + +#endif /* GL_MESA_window_pos */ + +/* ------------------------- GL_MESA_ycbcr_texture ------------------------- */ + +#ifndef GL_MESA_ycbcr_texture +#define GL_MESA_ycbcr_texture 1 + +#define GL_UNSIGNED_SHORT_8_8_MESA 0x85BA +#define GL_UNSIGNED_SHORT_8_8_REV_MESA 0x85BB +#define GL_YCBCR_MESA 0x8757 + +#define GLEW_MESA_ycbcr_texture GLEW_GET_VAR(__GLEW_MESA_ycbcr_texture) + +#endif /* GL_MESA_ycbcr_texture */ + +/* --------------------------- GL_NV_blend_square -------------------------- */ + +#ifndef GL_NV_blend_square +#define GL_NV_blend_square 1 + +#define GLEW_NV_blend_square GLEW_GET_VAR(__GLEW_NV_blend_square) + +#endif /* GL_NV_blend_square */ + +/* ----------------------- GL_NV_copy_depth_to_color ----------------------- */ + +#ifndef GL_NV_copy_depth_to_color +#define GL_NV_copy_depth_to_color 1 + +#define GL_DEPTH_STENCIL_TO_RGBA_NV 0x886E +#define GL_DEPTH_STENCIL_TO_BGRA_NV 0x886F + +#define GLEW_NV_copy_depth_to_color GLEW_GET_VAR(__GLEW_NV_copy_depth_to_color) + +#endif /* GL_NV_copy_depth_to_color */ + +/* --------------------------- GL_NV_depth_clamp --------------------------- */ + +#ifndef GL_NV_depth_clamp +#define GL_NV_depth_clamp 1 + +#define GL_DEPTH_CLAMP_NV 0x864F + +#define GLEW_NV_depth_clamp GLEW_GET_VAR(__GLEW_NV_depth_clamp) + +#endif /* GL_NV_depth_clamp */ + +/* ---------------------------- GL_NV_evaluators --------------------------- */ + +#ifndef GL_NV_evaluators +#define GL_NV_evaluators 1 + +#define GL_EVAL_2D_NV 0x86C0 +#define GL_EVAL_TRIANGULAR_2D_NV 0x86C1 +#define GL_MAP_TESSELLATION_NV 0x86C2 +#define GL_MAP_ATTRIB_U_ORDER_NV 0x86C3 +#define GL_MAP_ATTRIB_V_ORDER_NV 0x86C4 +#define GL_EVAL_FRACTIONAL_TESSELLATION_NV 0x86C5 +#define GL_EVAL_VERTEX_ATTRIB0_NV 0x86C6 +#define GL_EVAL_VERTEX_ATTRIB1_NV 0x86C7 +#define GL_EVAL_VERTEX_ATTRIB2_NV 0x86C8 +#define GL_EVAL_VERTEX_ATTRIB3_NV 0x86C9 +#define GL_EVAL_VERTEX_ATTRIB4_NV 0x86CA +#define GL_EVAL_VERTEX_ATTRIB5_NV 0x86CB +#define GL_EVAL_VERTEX_ATTRIB6_NV 0x86CC +#define GL_EVAL_VERTEX_ATTRIB7_NV 0x86CD +#define GL_EVAL_VERTEX_ATTRIB8_NV 0x86CE +#define GL_EVAL_VERTEX_ATTRIB9_NV 0x86CF +#define GL_EVAL_VERTEX_ATTRIB10_NV 0x86D0 +#define GL_EVAL_VERTEX_ATTRIB11_NV 0x86D1 +#define GL_EVAL_VERTEX_ATTRIB12_NV 0x86D2 +#define GL_EVAL_VERTEX_ATTRIB13_NV 0x86D3 +#define GL_EVAL_VERTEX_ATTRIB14_NV 0x86D4 +#define GL_EVAL_VERTEX_ATTRIB15_NV 0x86D5 +#define GL_MAX_MAP_TESSELLATION_NV 0x86D6 +#define GL_MAX_RATIONAL_EVAL_ORDER_NV 0x86D7 + +typedef void (GLAPIENTRY * PFNGLEVALMAPSNVPROC) (GLenum target, GLenum mode); +typedef void (GLAPIENTRY * PFNGLGETMAPATTRIBPARAMETERFVNVPROC) (GLenum target, GLuint index, GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETMAPATTRIBPARAMETERIVNVPROC) (GLenum target, GLuint index, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETMAPCONTROLPOINTSNVPROC) (GLenum target, GLuint index, GLenum type, GLsizei ustride, GLsizei vstride, GLboolean packed, void* points); +typedef void (GLAPIENTRY * PFNGLGETMAPPARAMETERFVNVPROC) (GLenum target, GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETMAPPARAMETERIVNVPROC) (GLenum target, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLMAPCONTROLPOINTSNVPROC) (GLenum target, GLuint index, GLenum type, GLsizei ustride, GLsizei vstride, GLint uorder, GLint vorder, GLboolean packed, const void* points); +typedef void (GLAPIENTRY * PFNGLMAPPARAMETERFVNVPROC) (GLenum target, GLenum pname, const GLfloat* params); +typedef void (GLAPIENTRY * PFNGLMAPPARAMETERIVNVPROC) (GLenum target, GLenum pname, const GLint* params); + +#define glEvalMapsNV GLEW_GET_FUN(__glewEvalMapsNV) +#define glGetMapAttribParameterfvNV GLEW_GET_FUN(__glewGetMapAttribParameterfvNV) +#define glGetMapAttribParameterivNV GLEW_GET_FUN(__glewGetMapAttribParameterivNV) +#define glGetMapControlPointsNV GLEW_GET_FUN(__glewGetMapControlPointsNV) +#define glGetMapParameterfvNV GLEW_GET_FUN(__glewGetMapParameterfvNV) +#define glGetMapParameterivNV GLEW_GET_FUN(__glewGetMapParameterivNV) +#define glMapControlPointsNV GLEW_GET_FUN(__glewMapControlPointsNV) +#define glMapParameterfvNV GLEW_GET_FUN(__glewMapParameterfvNV) +#define glMapParameterivNV GLEW_GET_FUN(__glewMapParameterivNV) + +#define GLEW_NV_evaluators GLEW_GET_VAR(__GLEW_NV_evaluators) + +#endif /* GL_NV_evaluators */ + +/* ------------------------------ GL_NV_fence ------------------------------ */ + +#ifndef GL_NV_fence +#define GL_NV_fence 1 + +#define GL_ALL_COMPLETED_NV 0x84F2 +#define GL_FENCE_STATUS_NV 0x84F3 +#define GL_FENCE_CONDITION_NV 0x84F4 + +typedef void (GLAPIENTRY * PFNGLDELETEFENCESNVPROC) (GLsizei n, const GLuint* fences); +typedef void (GLAPIENTRY * PFNGLFINISHFENCENVPROC) (GLuint fence); +typedef void (GLAPIENTRY * PFNGLGENFENCESNVPROC) (GLsizei n, GLuint* fences); +typedef void (GLAPIENTRY * PFNGLGETFENCEIVNVPROC) (GLuint fence, GLenum pname, GLint* params); +typedef GLboolean (GLAPIENTRY * PFNGLISFENCENVPROC) (GLuint fence); +typedef void (GLAPIENTRY * PFNGLSETFENCENVPROC) (GLuint fence, GLenum condition); +typedef GLboolean (GLAPIENTRY * PFNGLTESTFENCENVPROC) (GLuint fence); + +#define glDeleteFencesNV GLEW_GET_FUN(__glewDeleteFencesNV) +#define glFinishFenceNV GLEW_GET_FUN(__glewFinishFenceNV) +#define glGenFencesNV GLEW_GET_FUN(__glewGenFencesNV) +#define glGetFenceivNV GLEW_GET_FUN(__glewGetFenceivNV) +#define glIsFenceNV GLEW_GET_FUN(__glewIsFenceNV) +#define glSetFenceNV GLEW_GET_FUN(__glewSetFenceNV) +#define glTestFenceNV GLEW_GET_FUN(__glewTestFenceNV) + +#define GLEW_NV_fence GLEW_GET_VAR(__GLEW_NV_fence) + +#endif /* GL_NV_fence */ + +/* --------------------------- GL_NV_float_buffer -------------------------- */ + +#ifndef GL_NV_float_buffer +#define GL_NV_float_buffer 1 + +#define GL_FLOAT_R_NV 0x8880 +#define GL_FLOAT_RG_NV 0x8881 +#define GL_FLOAT_RGB_NV 0x8882 +#define GL_FLOAT_RGBA_NV 0x8883 +#define GL_FLOAT_R16_NV 0x8884 +#define GL_FLOAT_R32_NV 0x8885 +#define GL_FLOAT_RG16_NV 0x8886 +#define GL_FLOAT_RG32_NV 0x8887 +#define GL_FLOAT_RGB16_NV 0x8888 +#define GL_FLOAT_RGB32_NV 0x8889 +#define GL_FLOAT_RGBA16_NV 0x888A +#define GL_FLOAT_RGBA32_NV 0x888B +#define GL_TEXTURE_FLOAT_COMPONENTS_NV 0x888C +#define GL_FLOAT_CLEAR_COLOR_VALUE_NV 0x888D +#define GL_FLOAT_RGBA_MODE_NV 0x888E + +#define GLEW_NV_float_buffer GLEW_GET_VAR(__GLEW_NV_float_buffer) + +#endif /* GL_NV_float_buffer */ + +/* --------------------------- GL_NV_fog_distance -------------------------- */ + +#ifndef GL_NV_fog_distance +#define GL_NV_fog_distance 1 + +#define GL_FOG_DISTANCE_MODE_NV 0x855A +#define GL_EYE_RADIAL_NV 0x855B +#define GL_EYE_PLANE_ABSOLUTE_NV 0x855C + +#define GLEW_NV_fog_distance GLEW_GET_VAR(__GLEW_NV_fog_distance) + +#endif /* GL_NV_fog_distance */ + +/* ------------------------- GL_NV_fragment_program ------------------------ */ + +#ifndef GL_NV_fragment_program +#define GL_NV_fragment_program 1 + +#define GL_MAX_FRAGMENT_PROGRAM_LOCAL_PARAMETERS_NV 0x8868 +#define GL_FRAGMENT_PROGRAM_NV 0x8870 +#define GL_MAX_TEXTURE_COORDS_NV 0x8871 +#define GL_MAX_TEXTURE_IMAGE_UNITS_NV 0x8872 +#define GL_FRAGMENT_PROGRAM_BINDING_NV 0x8873 +#define GL_PROGRAM_ERROR_STRING_NV 0x8874 + +typedef void (GLAPIENTRY * PFNGLGETPROGRAMNAMEDPARAMETERDVNVPROC) (GLuint id, GLsizei len, const GLubyte* name, GLdouble *params); +typedef void (GLAPIENTRY * PFNGLGETPROGRAMNAMEDPARAMETERFVNVPROC) (GLuint id, GLsizei len, const GLubyte* name, GLfloat *params); +typedef void (GLAPIENTRY * PFNGLPROGRAMNAMEDPARAMETER4DNVPROC) (GLuint id, GLsizei len, const GLubyte* name, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (GLAPIENTRY * PFNGLPROGRAMNAMEDPARAMETER4DVNVPROC) (GLuint id, GLsizei len, const GLubyte* name, const GLdouble v[]); +typedef void (GLAPIENTRY * PFNGLPROGRAMNAMEDPARAMETER4FNVPROC) (GLuint id, GLsizei len, const GLubyte* name, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (GLAPIENTRY * PFNGLPROGRAMNAMEDPARAMETER4FVNVPROC) (GLuint id, GLsizei len, const GLubyte* name, const GLfloat v[]); + +#define glGetProgramNamedParameterdvNV GLEW_GET_FUN(__glewGetProgramNamedParameterdvNV) +#define glGetProgramNamedParameterfvNV GLEW_GET_FUN(__glewGetProgramNamedParameterfvNV) +#define glProgramNamedParameter4dNV GLEW_GET_FUN(__glewProgramNamedParameter4dNV) +#define glProgramNamedParameter4dvNV GLEW_GET_FUN(__glewProgramNamedParameter4dvNV) +#define glProgramNamedParameter4fNV GLEW_GET_FUN(__glewProgramNamedParameter4fNV) +#define glProgramNamedParameter4fvNV GLEW_GET_FUN(__glewProgramNamedParameter4fvNV) + +#define GLEW_NV_fragment_program GLEW_GET_VAR(__GLEW_NV_fragment_program) + +#endif /* GL_NV_fragment_program */ + +/* ------------------------ GL_NV_fragment_program2 ------------------------ */ + +#ifndef GL_NV_fragment_program2 +#define GL_NV_fragment_program2 1 + +#define GL_MAX_PROGRAM_EXEC_INSTRUCTIONS_NV 0x88F4 +#define GL_MAX_PROGRAM_CALL_DEPTH_NV 0x88F5 +#define GL_MAX_PROGRAM_IF_DEPTH_NV 0x88F6 +#define GL_MAX_PROGRAM_LOOP_DEPTH_NV 0x88F7 +#define GL_MAX_PROGRAM_LOOP_COUNT_NV 0x88F8 + +#define GLEW_NV_fragment_program2 GLEW_GET_VAR(__GLEW_NV_fragment_program2) + +#endif /* GL_NV_fragment_program2 */ + +/* --------------------- GL_NV_fragment_program_option --------------------- */ + +#ifndef GL_NV_fragment_program_option +#define GL_NV_fragment_program_option 1 + +#define GLEW_NV_fragment_program_option GLEW_GET_VAR(__GLEW_NV_fragment_program_option) + +#endif /* GL_NV_fragment_program_option */ + +/* ---------------------------- GL_NV_half_float --------------------------- */ + +#ifndef GL_NV_half_float +#define GL_NV_half_float 1 + +#define GL_HALF_FLOAT_NV 0x140B + +typedef unsigned short GLhalf; + +typedef void (GLAPIENTRY * PFNGLCOLOR3HNVPROC) (GLhalf red, GLhalf green, GLhalf blue); +typedef void (GLAPIENTRY * PFNGLCOLOR3HVNVPROC) (const GLhalf* v); +typedef void (GLAPIENTRY * PFNGLCOLOR4HNVPROC) (GLhalf red, GLhalf green, GLhalf blue, GLhalf alpha); +typedef void (GLAPIENTRY * PFNGLCOLOR4HVNVPROC) (const GLhalf* v); +typedef void (GLAPIENTRY * PFNGLFOGCOORDHNVPROC) (GLhalf fog); +typedef void (GLAPIENTRY * PFNGLFOGCOORDHVNVPROC) (const GLhalf* fog); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1HNVPROC) (GLenum target, GLhalf s); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1HVNVPROC) (GLenum target, const GLhalf* v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2HNVPROC) (GLenum target, GLhalf s, GLhalf t); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2HVNVPROC) (GLenum target, const GLhalf* v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3HNVPROC) (GLenum target, GLhalf s, GLhalf t, GLhalf r); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3HVNVPROC) (GLenum target, const GLhalf* v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4HNVPROC) (GLenum target, GLhalf s, GLhalf t, GLhalf r, GLhalf q); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4HVNVPROC) (GLenum target, const GLhalf* v); +typedef void (GLAPIENTRY * PFNGLNORMAL3HNVPROC) (GLhalf nx, GLhalf ny, GLhalf nz); +typedef void (GLAPIENTRY * PFNGLNORMAL3HVNVPROC) (const GLhalf* v); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3HNVPROC) (GLhalf red, GLhalf green, GLhalf blue); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3HVNVPROC) (const GLhalf* v); +typedef void (GLAPIENTRY * PFNGLTEXCOORD1HNVPROC) (GLhalf s); +typedef void (GLAPIENTRY * PFNGLTEXCOORD1HVNVPROC) (const GLhalf* v); +typedef void (GLAPIENTRY * PFNGLTEXCOORD2HNVPROC) (GLhalf s, GLhalf t); +typedef void (GLAPIENTRY * PFNGLTEXCOORD2HVNVPROC) (const GLhalf* v); +typedef void (GLAPIENTRY * PFNGLTEXCOORD3HNVPROC) (GLhalf s, GLhalf t, GLhalf r); +typedef void (GLAPIENTRY * PFNGLTEXCOORD3HVNVPROC) (const GLhalf* v); +typedef void (GLAPIENTRY * PFNGLTEXCOORD4HNVPROC) (GLhalf s, GLhalf t, GLhalf r, GLhalf q); +typedef void (GLAPIENTRY * PFNGLTEXCOORD4HVNVPROC) (const GLhalf* v); +typedef void (GLAPIENTRY * PFNGLVERTEX2HNVPROC) (GLhalf x, GLhalf y); +typedef void (GLAPIENTRY * PFNGLVERTEX2HVNVPROC) (const GLhalf* v); +typedef void (GLAPIENTRY * PFNGLVERTEX3HNVPROC) (GLhalf x, GLhalf y, GLhalf z); +typedef void (GLAPIENTRY * PFNGLVERTEX3HVNVPROC) (const GLhalf* v); +typedef void (GLAPIENTRY * PFNGLVERTEX4HNVPROC) (GLhalf x, GLhalf y, GLhalf z, GLhalf w); +typedef void (GLAPIENTRY * PFNGLVERTEX4HVNVPROC) (const GLhalf* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1HNVPROC) (GLuint index, GLhalf x); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1HVNVPROC) (GLuint index, const GLhalf* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2HNVPROC) (GLuint index, GLhalf x, GLhalf y); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2HVNVPROC) (GLuint index, const GLhalf* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3HNVPROC) (GLuint index, GLhalf x, GLhalf y, GLhalf z); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3HVNVPROC) (GLuint index, const GLhalf* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4HNVPROC) (GLuint index, GLhalf x, GLhalf y, GLhalf z, GLhalf w); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4HVNVPROC) (GLuint index, const GLhalf* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS1HVNVPROC) (GLuint index, GLsizei n, const GLhalf* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS2HVNVPROC) (GLuint index, GLsizei n, const GLhalf* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS3HVNVPROC) (GLuint index, GLsizei n, const GLhalf* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS4HVNVPROC) (GLuint index, GLsizei n, const GLhalf* v); +typedef void (GLAPIENTRY * PFNGLVERTEXWEIGHTHNVPROC) (GLhalf weight); +typedef void (GLAPIENTRY * PFNGLVERTEXWEIGHTHVNVPROC) (const GLhalf* weight); + +#define glColor3hNV GLEW_GET_FUN(__glewColor3hNV) +#define glColor3hvNV GLEW_GET_FUN(__glewColor3hvNV) +#define glColor4hNV GLEW_GET_FUN(__glewColor4hNV) +#define glColor4hvNV GLEW_GET_FUN(__glewColor4hvNV) +#define glFogCoordhNV GLEW_GET_FUN(__glewFogCoordhNV) +#define glFogCoordhvNV GLEW_GET_FUN(__glewFogCoordhvNV) +#define glMultiTexCoord1hNV GLEW_GET_FUN(__glewMultiTexCoord1hNV) +#define glMultiTexCoord1hvNV GLEW_GET_FUN(__glewMultiTexCoord1hvNV) +#define glMultiTexCoord2hNV GLEW_GET_FUN(__glewMultiTexCoord2hNV) +#define glMultiTexCoord2hvNV GLEW_GET_FUN(__glewMultiTexCoord2hvNV) +#define glMultiTexCoord3hNV GLEW_GET_FUN(__glewMultiTexCoord3hNV) +#define glMultiTexCoord3hvNV GLEW_GET_FUN(__glewMultiTexCoord3hvNV) +#define glMultiTexCoord4hNV GLEW_GET_FUN(__glewMultiTexCoord4hNV) +#define glMultiTexCoord4hvNV GLEW_GET_FUN(__glewMultiTexCoord4hvNV) +#define glNormal3hNV GLEW_GET_FUN(__glewNormal3hNV) +#define glNormal3hvNV GLEW_GET_FUN(__glewNormal3hvNV) +#define glSecondaryColor3hNV GLEW_GET_FUN(__glewSecondaryColor3hNV) +#define glSecondaryColor3hvNV GLEW_GET_FUN(__glewSecondaryColor3hvNV) +#define glTexCoord1hNV GLEW_GET_FUN(__glewTexCoord1hNV) +#define glTexCoord1hvNV GLEW_GET_FUN(__glewTexCoord1hvNV) +#define glTexCoord2hNV GLEW_GET_FUN(__glewTexCoord2hNV) +#define glTexCoord2hvNV GLEW_GET_FUN(__glewTexCoord2hvNV) +#define glTexCoord3hNV GLEW_GET_FUN(__glewTexCoord3hNV) +#define glTexCoord3hvNV GLEW_GET_FUN(__glewTexCoord3hvNV) +#define glTexCoord4hNV GLEW_GET_FUN(__glewTexCoord4hNV) +#define glTexCoord4hvNV GLEW_GET_FUN(__glewTexCoord4hvNV) +#define glVertex2hNV GLEW_GET_FUN(__glewVertex2hNV) +#define glVertex2hvNV GLEW_GET_FUN(__glewVertex2hvNV) +#define glVertex3hNV GLEW_GET_FUN(__glewVertex3hNV) +#define glVertex3hvNV GLEW_GET_FUN(__glewVertex3hvNV) +#define glVertex4hNV GLEW_GET_FUN(__glewVertex4hNV) +#define glVertex4hvNV GLEW_GET_FUN(__glewVertex4hvNV) +#define glVertexAttrib1hNV GLEW_GET_FUN(__glewVertexAttrib1hNV) +#define glVertexAttrib1hvNV GLEW_GET_FUN(__glewVertexAttrib1hvNV) +#define glVertexAttrib2hNV GLEW_GET_FUN(__glewVertexAttrib2hNV) +#define glVertexAttrib2hvNV GLEW_GET_FUN(__glewVertexAttrib2hvNV) +#define glVertexAttrib3hNV GLEW_GET_FUN(__glewVertexAttrib3hNV) +#define glVertexAttrib3hvNV GLEW_GET_FUN(__glewVertexAttrib3hvNV) +#define glVertexAttrib4hNV GLEW_GET_FUN(__glewVertexAttrib4hNV) +#define glVertexAttrib4hvNV GLEW_GET_FUN(__glewVertexAttrib4hvNV) +#define glVertexAttribs1hvNV GLEW_GET_FUN(__glewVertexAttribs1hvNV) +#define glVertexAttribs2hvNV GLEW_GET_FUN(__glewVertexAttribs2hvNV) +#define glVertexAttribs3hvNV GLEW_GET_FUN(__glewVertexAttribs3hvNV) +#define glVertexAttribs4hvNV GLEW_GET_FUN(__glewVertexAttribs4hvNV) +#define glVertexWeighthNV GLEW_GET_FUN(__glewVertexWeighthNV) +#define glVertexWeighthvNV GLEW_GET_FUN(__glewVertexWeighthvNV) + +#define GLEW_NV_half_float GLEW_GET_VAR(__GLEW_NV_half_float) + +#endif /* GL_NV_half_float */ + +/* ------------------------ GL_NV_light_max_exponent ----------------------- */ + +#ifndef GL_NV_light_max_exponent +#define GL_NV_light_max_exponent 1 + +#define GL_MAX_SHININESS_NV 0x8504 +#define GL_MAX_SPOT_EXPONENT_NV 0x8505 + +#define GLEW_NV_light_max_exponent GLEW_GET_VAR(__GLEW_NV_light_max_exponent) + +#endif /* GL_NV_light_max_exponent */ + +/* --------------------- GL_NV_multisample_filter_hint --------------------- */ + +#ifndef GL_NV_multisample_filter_hint +#define GL_NV_multisample_filter_hint 1 + +#define GL_MULTISAMPLE_FILTER_HINT_NV 0x8534 + +#define GLEW_NV_multisample_filter_hint GLEW_GET_VAR(__GLEW_NV_multisample_filter_hint) + +#endif /* GL_NV_multisample_filter_hint */ + +/* ------------------------- GL_NV_occlusion_query ------------------------- */ + +#ifndef GL_NV_occlusion_query +#define GL_NV_occlusion_query 1 + +#define GL_PIXEL_COUNTER_BITS_NV 0x8864 +#define GL_CURRENT_OCCLUSION_QUERY_ID_NV 0x8865 +#define GL_PIXEL_COUNT_NV 0x8866 +#define GL_PIXEL_COUNT_AVAILABLE_NV 0x8867 + +typedef void (GLAPIENTRY * PFNGLBEGINOCCLUSIONQUERYNVPROC) (GLuint id); +typedef void (GLAPIENTRY * PFNGLDELETEOCCLUSIONQUERIESNVPROC) (GLsizei n, const GLuint* ids); +typedef void (GLAPIENTRY * PFNGLENDOCCLUSIONQUERYNVPROC) (void); +typedef void (GLAPIENTRY * PFNGLGENOCCLUSIONQUERIESNVPROC) (GLsizei n, GLuint* ids); +typedef void (GLAPIENTRY * PFNGLGETOCCLUSIONQUERYIVNVPROC) (GLuint id, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETOCCLUSIONQUERYUIVNVPROC) (GLuint id, GLenum pname, GLuint* params); +typedef GLboolean (GLAPIENTRY * PFNGLISOCCLUSIONQUERYNVPROC) (GLuint id); + +#define glBeginOcclusionQueryNV GLEW_GET_FUN(__glewBeginOcclusionQueryNV) +#define glDeleteOcclusionQueriesNV GLEW_GET_FUN(__glewDeleteOcclusionQueriesNV) +#define glEndOcclusionQueryNV GLEW_GET_FUN(__glewEndOcclusionQueryNV) +#define glGenOcclusionQueriesNV GLEW_GET_FUN(__glewGenOcclusionQueriesNV) +#define glGetOcclusionQueryivNV GLEW_GET_FUN(__glewGetOcclusionQueryivNV) +#define glGetOcclusionQueryuivNV GLEW_GET_FUN(__glewGetOcclusionQueryuivNV) +#define glIsOcclusionQueryNV GLEW_GET_FUN(__glewIsOcclusionQueryNV) + +#define GLEW_NV_occlusion_query GLEW_GET_VAR(__GLEW_NV_occlusion_query) + +#endif /* GL_NV_occlusion_query */ + +/* ----------------------- GL_NV_packed_depth_stencil ---------------------- */ + +#ifndef GL_NV_packed_depth_stencil +#define GL_NV_packed_depth_stencil 1 + +#define GL_DEPTH_STENCIL_NV 0x84F9 +#define GL_UNSIGNED_INT_24_8_NV 0x84FA + +#define GLEW_NV_packed_depth_stencil GLEW_GET_VAR(__GLEW_NV_packed_depth_stencil) + +#endif /* GL_NV_packed_depth_stencil */ + +/* ------------------------- GL_NV_pixel_data_range ------------------------ */ + +#ifndef GL_NV_pixel_data_range +#define GL_NV_pixel_data_range 1 + +#define GL_WRITE_PIXEL_DATA_RANGE_NV 0x8878 +#define GL_READ_PIXEL_DATA_RANGE_NV 0x8879 +#define GL_WRITE_PIXEL_DATA_RANGE_LENGTH_NV 0x887A +#define GL_READ_PIXEL_DATA_RANGE_LENGTH_NV 0x887B +#define GL_WRITE_PIXEL_DATA_RANGE_POINTER_NV 0x887C +#define GL_READ_PIXEL_DATA_RANGE_POINTER_NV 0x887D + +typedef void (GLAPIENTRY * PFNGLFLUSHPIXELDATARANGENVPROC) (GLenum target); +typedef void (GLAPIENTRY * PFNGLPIXELDATARANGENVPROC) (GLenum target, GLsizei length, void* pointer); + +#define glFlushPixelDataRangeNV GLEW_GET_FUN(__glewFlushPixelDataRangeNV) +#define glPixelDataRangeNV GLEW_GET_FUN(__glewPixelDataRangeNV) + +#define GLEW_NV_pixel_data_range GLEW_GET_VAR(__GLEW_NV_pixel_data_range) + +#endif /* GL_NV_pixel_data_range */ + +/* --------------------------- GL_NV_point_sprite -------------------------- */ + +#ifndef GL_NV_point_sprite +#define GL_NV_point_sprite 1 + +#define GL_POINT_SPRITE_NV 0x8861 +#define GL_COORD_REPLACE_NV 0x8862 +#define GL_POINT_SPRITE_R_MODE_NV 0x8863 + +typedef void (GLAPIENTRY * PFNGLPOINTPARAMETERINVPROC) (GLenum pname, GLint param); +typedef void (GLAPIENTRY * PFNGLPOINTPARAMETERIVNVPROC) (GLenum pname, const GLint* params); + +#define glPointParameteriNV GLEW_GET_FUN(__glewPointParameteriNV) +#define glPointParameterivNV GLEW_GET_FUN(__glewPointParameterivNV) + +#define GLEW_NV_point_sprite GLEW_GET_VAR(__GLEW_NV_point_sprite) + +#endif /* GL_NV_point_sprite */ + +/* ------------------------ GL_NV_primitive_restart ------------------------ */ + +#ifndef GL_NV_primitive_restart +#define GL_NV_primitive_restart 1 + +#define GL_PRIMITIVE_RESTART_NV 0x8558 +#define GL_PRIMITIVE_RESTART_INDEX_NV 0x8559 + +typedef void (GLAPIENTRY * PFNGLPRIMITIVERESTARTINDEXNVPROC) (GLuint index); +typedef void (GLAPIENTRY * PFNGLPRIMITIVERESTARTNVPROC) (void); + +#define glPrimitiveRestartIndexNV GLEW_GET_FUN(__glewPrimitiveRestartIndexNV) +#define glPrimitiveRestartNV GLEW_GET_FUN(__glewPrimitiveRestartNV) + +#define GLEW_NV_primitive_restart GLEW_GET_VAR(__GLEW_NV_primitive_restart) + +#endif /* GL_NV_primitive_restart */ + +/* ------------------------ GL_NV_register_combiners ----------------------- */ + +#ifndef GL_NV_register_combiners +#define GL_NV_register_combiners 1 + +#define GL_REGISTER_COMBINERS_NV 0x8522 +#define GL_VARIABLE_A_NV 0x8523 +#define GL_VARIABLE_B_NV 0x8524 +#define GL_VARIABLE_C_NV 0x8525 +#define GL_VARIABLE_D_NV 0x8526 +#define GL_VARIABLE_E_NV 0x8527 +#define GL_VARIABLE_F_NV 0x8528 +#define GL_VARIABLE_G_NV 0x8529 +#define GL_CONSTANT_COLOR0_NV 0x852A +#define GL_CONSTANT_COLOR1_NV 0x852B +#define GL_PRIMARY_COLOR_NV 0x852C +#define GL_SECONDARY_COLOR_NV 0x852D +#define GL_SPARE0_NV 0x852E +#define GL_SPARE1_NV 0x852F +#define GL_DISCARD_NV 0x8530 +#define GL_E_TIMES_F_NV 0x8531 +#define GL_SPARE0_PLUS_SECONDARY_COLOR_NV 0x8532 +#define GL_UNSIGNED_IDENTITY_NV 0x8536 +#define GL_UNSIGNED_INVERT_NV 0x8537 +#define GL_EXPAND_NORMAL_NV 0x8538 +#define GL_EXPAND_NEGATE_NV 0x8539 +#define GL_HALF_BIAS_NORMAL_NV 0x853A +#define GL_HALF_BIAS_NEGATE_NV 0x853B +#define GL_SIGNED_IDENTITY_NV 0x853C +#define GL_SIGNED_NEGATE_NV 0x853D +#define GL_SCALE_BY_TWO_NV 0x853E +#define GL_SCALE_BY_FOUR_NV 0x853F +#define GL_SCALE_BY_ONE_HALF_NV 0x8540 +#define GL_BIAS_BY_NEGATIVE_ONE_HALF_NV 0x8541 +#define GL_COMBINER_INPUT_NV 0x8542 +#define GL_COMBINER_MAPPING_NV 0x8543 +#define GL_COMBINER_COMPONENT_USAGE_NV 0x8544 +#define GL_COMBINER_AB_DOT_PRODUCT_NV 0x8545 +#define GL_COMBINER_CD_DOT_PRODUCT_NV 0x8546 +#define GL_COMBINER_MUX_SUM_NV 0x8547 +#define GL_COMBINER_SCALE_NV 0x8548 +#define GL_COMBINER_BIAS_NV 0x8549 +#define GL_COMBINER_AB_OUTPUT_NV 0x854A +#define GL_COMBINER_CD_OUTPUT_NV 0x854B +#define GL_COMBINER_SUM_OUTPUT_NV 0x854C +#define GL_MAX_GENERAL_COMBINERS_NV 0x854D +#define GL_NUM_GENERAL_COMBINERS_NV 0x854E +#define GL_COLOR_SUM_CLAMP_NV 0x854F +#define GL_COMBINER0_NV 0x8550 +#define GL_COMBINER1_NV 0x8551 +#define GL_COMBINER2_NV 0x8552 +#define GL_COMBINER3_NV 0x8553 +#define GL_COMBINER4_NV 0x8554 +#define GL_COMBINER5_NV 0x8555 +#define GL_COMBINER6_NV 0x8556 +#define GL_COMBINER7_NV 0x8557 + +typedef void (GLAPIENTRY * PFNGLCOMBINERINPUTNVPROC) (GLenum stage, GLenum portion, GLenum variable, GLenum input, GLenum mapping, GLenum componentUsage); +typedef void (GLAPIENTRY * PFNGLCOMBINEROUTPUTNVPROC) (GLenum stage, GLenum portion, GLenum abOutput, GLenum cdOutput, GLenum sumOutput, GLenum scale, GLenum bias, GLboolean abDotProduct, GLboolean cdDotProduct, GLboolean muxSum); +typedef void (GLAPIENTRY * PFNGLCOMBINERPARAMETERFNVPROC) (GLenum pname, GLfloat param); +typedef void (GLAPIENTRY * PFNGLCOMBINERPARAMETERFVNVPROC) (GLenum pname, const GLfloat* params); +typedef void (GLAPIENTRY * PFNGLCOMBINERPARAMETERINVPROC) (GLenum pname, GLint param); +typedef void (GLAPIENTRY * PFNGLCOMBINERPARAMETERIVNVPROC) (GLenum pname, const GLint* params); +typedef void (GLAPIENTRY * PFNGLFINALCOMBINERINPUTNVPROC) (GLenum variable, GLenum input, GLenum mapping, GLenum componentUsage); +typedef void (GLAPIENTRY * PFNGLGETCOMBINERINPUTPARAMETERFVNVPROC) (GLenum stage, GLenum portion, GLenum variable, GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETCOMBINERINPUTPARAMETERIVNVPROC) (GLenum stage, GLenum portion, GLenum variable, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETCOMBINEROUTPUTPARAMETERFVNVPROC) (GLenum stage, GLenum portion, GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETCOMBINEROUTPUTPARAMETERIVNVPROC) (GLenum stage, GLenum portion, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETFINALCOMBINERINPUTPARAMETERFVNVPROC) (GLenum variable, GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETFINALCOMBINERINPUTPARAMETERIVNVPROC) (GLenum variable, GLenum pname, GLint* params); + +#define glCombinerInputNV GLEW_GET_FUN(__glewCombinerInputNV) +#define glCombinerOutputNV GLEW_GET_FUN(__glewCombinerOutputNV) +#define glCombinerParameterfNV GLEW_GET_FUN(__glewCombinerParameterfNV) +#define glCombinerParameterfvNV GLEW_GET_FUN(__glewCombinerParameterfvNV) +#define glCombinerParameteriNV GLEW_GET_FUN(__glewCombinerParameteriNV) +#define glCombinerParameterivNV GLEW_GET_FUN(__glewCombinerParameterivNV) +#define glFinalCombinerInputNV GLEW_GET_FUN(__glewFinalCombinerInputNV) +#define glGetCombinerInputParameterfvNV GLEW_GET_FUN(__glewGetCombinerInputParameterfvNV) +#define glGetCombinerInputParameterivNV GLEW_GET_FUN(__glewGetCombinerInputParameterivNV) +#define glGetCombinerOutputParameterfvNV GLEW_GET_FUN(__glewGetCombinerOutputParameterfvNV) +#define glGetCombinerOutputParameterivNV GLEW_GET_FUN(__glewGetCombinerOutputParameterivNV) +#define glGetFinalCombinerInputParameterfvNV GLEW_GET_FUN(__glewGetFinalCombinerInputParameterfvNV) +#define glGetFinalCombinerInputParameterivNV GLEW_GET_FUN(__glewGetFinalCombinerInputParameterivNV) + +#define GLEW_NV_register_combiners GLEW_GET_VAR(__GLEW_NV_register_combiners) + +#endif /* GL_NV_register_combiners */ + +/* ----------------------- GL_NV_register_combiners2 ----------------------- */ + +#ifndef GL_NV_register_combiners2 +#define GL_NV_register_combiners2 1 + +#define GL_PER_STAGE_CONSTANTS_NV 0x8535 + +typedef void (GLAPIENTRY * PFNGLCOMBINERSTAGEPARAMETERFVNVPROC) (GLenum stage, GLenum pname, const GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETCOMBINERSTAGEPARAMETERFVNVPROC) (GLenum stage, GLenum pname, GLfloat* params); + +#define glCombinerStageParameterfvNV GLEW_GET_FUN(__glewCombinerStageParameterfvNV) +#define glGetCombinerStageParameterfvNV GLEW_GET_FUN(__glewGetCombinerStageParameterfvNV) + +#define GLEW_NV_register_combiners2 GLEW_GET_VAR(__GLEW_NV_register_combiners2) + +#endif /* GL_NV_register_combiners2 */ + +/* -------------------------- GL_NV_texgen_emboss -------------------------- */ + +#ifndef GL_NV_texgen_emboss +#define GL_NV_texgen_emboss 1 + +#define GL_EMBOSS_LIGHT_NV 0x855D +#define GL_EMBOSS_CONSTANT_NV 0x855E +#define GL_EMBOSS_MAP_NV 0x855F + +#define GLEW_NV_texgen_emboss GLEW_GET_VAR(__GLEW_NV_texgen_emboss) + +#endif /* GL_NV_texgen_emboss */ + +/* ------------------------ GL_NV_texgen_reflection ------------------------ */ + +#ifndef GL_NV_texgen_reflection +#define GL_NV_texgen_reflection 1 + +#define GL_NORMAL_MAP_NV 0x8511 +#define GL_REFLECTION_MAP_NV 0x8512 + +#define GLEW_NV_texgen_reflection GLEW_GET_VAR(__GLEW_NV_texgen_reflection) + +#endif /* GL_NV_texgen_reflection */ + +/* --------------------- GL_NV_texture_compression_vtc --------------------- */ + +#ifndef GL_NV_texture_compression_vtc +#define GL_NV_texture_compression_vtc 1 + +#define GLEW_NV_texture_compression_vtc GLEW_GET_VAR(__GLEW_NV_texture_compression_vtc) + +#endif /* GL_NV_texture_compression_vtc */ + +/* ----------------------- GL_NV_texture_env_combine4 ---------------------- */ + +#ifndef GL_NV_texture_env_combine4 +#define GL_NV_texture_env_combine4 1 + +#define GL_COMBINE4_NV 0x8503 +#define GL_SOURCE3_RGB_NV 0x8583 +#define GL_SOURCE3_ALPHA_NV 0x858B +#define GL_OPERAND3_RGB_NV 0x8593 +#define GL_OPERAND3_ALPHA_NV 0x859B + +#define GLEW_NV_texture_env_combine4 GLEW_GET_VAR(__GLEW_NV_texture_env_combine4) + +#endif /* GL_NV_texture_env_combine4 */ + +/* ---------------------- GL_NV_texture_expand_normal ---------------------- */ + +#ifndef GL_NV_texture_expand_normal +#define GL_NV_texture_expand_normal 1 + +#define GL_TEXTURE_UNSIGNED_REMAP_MODE_NV 0x888F + +#define GLEW_NV_texture_expand_normal GLEW_GET_VAR(__GLEW_NV_texture_expand_normal) + +#endif /* GL_NV_texture_expand_normal */ + +/* ------------------------ GL_NV_texture_rectangle ------------------------ */ + +#ifndef GL_NV_texture_rectangle +#define GL_NV_texture_rectangle 1 + +#define GL_TEXTURE_RECTANGLE_NV 0x84F5 +#define GL_TEXTURE_BINDING_RECTANGLE_NV 0x84F6 +#define GL_PROXY_TEXTURE_RECTANGLE_NV 0x84F7 +#define GL_MAX_RECTANGLE_TEXTURE_SIZE_NV 0x84F8 + +#define GLEW_NV_texture_rectangle GLEW_GET_VAR(__GLEW_NV_texture_rectangle) + +#endif /* GL_NV_texture_rectangle */ + +/* -------------------------- GL_NV_texture_shader ------------------------- */ + +#ifndef GL_NV_texture_shader +#define GL_NV_texture_shader 1 + +#define GL_OFFSET_TEXTURE_RECTANGLE_NV 0x864C +#define GL_OFFSET_TEXTURE_RECTANGLE_SCALE_NV 0x864D +#define GL_DOT_PRODUCT_TEXTURE_RECTANGLE_NV 0x864E +#define GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV 0x86D9 +#define GL_UNSIGNED_INT_S8_S8_8_8_NV 0x86DA +#define GL_UNSIGNED_INT_8_8_S8_S8_REV_NV 0x86DB +#define GL_DSDT_MAG_INTENSITY_NV 0x86DC +#define GL_SHADER_CONSISTENT_NV 0x86DD +#define GL_TEXTURE_SHADER_NV 0x86DE +#define GL_SHADER_OPERATION_NV 0x86DF +#define GL_CULL_MODES_NV 0x86E0 +#define GL_OFFSET_TEXTURE_MATRIX_NV 0x86E1 +#define GL_OFFSET_TEXTURE_SCALE_NV 0x86E2 +#define GL_OFFSET_TEXTURE_BIAS_NV 0x86E3 +#define GL_PREVIOUS_TEXTURE_INPUT_NV 0x86E4 +#define GL_CONST_EYE_NV 0x86E5 +#define GL_PASS_THROUGH_NV 0x86E6 +#define GL_CULL_FRAGMENT_NV 0x86E7 +#define GL_OFFSET_TEXTURE_2D_NV 0x86E8 +#define GL_DEPENDENT_AR_TEXTURE_2D_NV 0x86E9 +#define GL_DEPENDENT_GB_TEXTURE_2D_NV 0x86EA +#define GL_DOT_PRODUCT_NV 0x86EC +#define GL_DOT_PRODUCT_DEPTH_REPLACE_NV 0x86ED +#define GL_DOT_PRODUCT_TEXTURE_2D_NV 0x86EE +#define GL_DOT_PRODUCT_TEXTURE_CUBE_MAP_NV 0x86F0 +#define GL_DOT_PRODUCT_DIFFUSE_CUBE_MAP_NV 0x86F1 +#define GL_DOT_PRODUCT_REFLECT_CUBE_MAP_NV 0x86F2 +#define GL_DOT_PRODUCT_CONST_EYE_REFLECT_CUBE_MAP_NV 0x86F3 +#define GL_HILO_NV 0x86F4 +#define GL_DSDT_NV 0x86F5 +#define GL_DSDT_MAG_NV 0x86F6 +#define GL_DSDT_MAG_VIB_NV 0x86F7 +#define GL_HILO16_NV 0x86F8 +#define GL_SIGNED_HILO_NV 0x86F9 +#define GL_SIGNED_HILO16_NV 0x86FA +#define GL_SIGNED_RGBA_NV 0x86FB +#define GL_SIGNED_RGBA8_NV 0x86FC +#define GL_SIGNED_RGB_NV 0x86FE +#define GL_SIGNED_RGB8_NV 0x86FF +#define GL_SIGNED_LUMINANCE_NV 0x8701 +#define GL_SIGNED_LUMINANCE8_NV 0x8702 +#define GL_SIGNED_LUMINANCE_ALPHA_NV 0x8703 +#define GL_SIGNED_LUMINANCE8_ALPHA8_NV 0x8704 +#define GL_SIGNED_ALPHA_NV 0x8705 +#define GL_SIGNED_ALPHA8_NV 0x8706 +#define GL_SIGNED_INTENSITY_NV 0x8707 +#define GL_SIGNED_INTENSITY8_NV 0x8708 +#define GL_DSDT8_NV 0x8709 +#define GL_DSDT8_MAG8_NV 0x870A +#define GL_DSDT8_MAG8_INTENSITY8_NV 0x870B +#define GL_SIGNED_RGB_UNSIGNED_ALPHA_NV 0x870C +#define GL_SIGNED_RGB8_UNSIGNED_ALPHA8_NV 0x870D +#define GL_HI_SCALE_NV 0x870E +#define GL_LO_SCALE_NV 0x870F +#define GL_DS_SCALE_NV 0x8710 +#define GL_DT_SCALE_NV 0x8711 +#define GL_MAGNITUDE_SCALE_NV 0x8712 +#define GL_VIBRANCE_SCALE_NV 0x8713 +#define GL_HI_BIAS_NV 0x8714 +#define GL_LO_BIAS_NV 0x8715 +#define GL_DS_BIAS_NV 0x8716 +#define GL_DT_BIAS_NV 0x8717 +#define GL_MAGNITUDE_BIAS_NV 0x8718 +#define GL_VIBRANCE_BIAS_NV 0x8719 +#define GL_TEXTURE_BORDER_VALUES_NV 0x871A +#define GL_TEXTURE_HI_SIZE_NV 0x871B +#define GL_TEXTURE_LO_SIZE_NV 0x871C +#define GL_TEXTURE_DS_SIZE_NV 0x871D +#define GL_TEXTURE_DT_SIZE_NV 0x871E +#define GL_TEXTURE_MAG_SIZE_NV 0x871F + +#define GLEW_NV_texture_shader GLEW_GET_VAR(__GLEW_NV_texture_shader) + +#endif /* GL_NV_texture_shader */ + +/* ------------------------- GL_NV_texture_shader2 ------------------------- */ + +#ifndef GL_NV_texture_shader2 +#define GL_NV_texture_shader2 1 + +#define GL_UNSIGNED_INT_S8_S8_8_8_NV 0x86DA +#define GL_UNSIGNED_INT_8_8_S8_S8_REV_NV 0x86DB +#define GL_DSDT_MAG_INTENSITY_NV 0x86DC +#define GL_DOT_PRODUCT_TEXTURE_3D_NV 0x86EF +#define GL_HILO_NV 0x86F4 +#define GL_DSDT_NV 0x86F5 +#define GL_DSDT_MAG_NV 0x86F6 +#define GL_DSDT_MAG_VIB_NV 0x86F7 +#define GL_HILO16_NV 0x86F8 +#define GL_SIGNED_HILO_NV 0x86F9 +#define GL_SIGNED_HILO16_NV 0x86FA +#define GL_SIGNED_RGBA_NV 0x86FB +#define GL_SIGNED_RGBA8_NV 0x86FC +#define GL_SIGNED_RGB_NV 0x86FE +#define GL_SIGNED_RGB8_NV 0x86FF +#define GL_SIGNED_LUMINANCE_NV 0x8701 +#define GL_SIGNED_LUMINANCE8_NV 0x8702 +#define GL_SIGNED_LUMINANCE_ALPHA_NV 0x8703 +#define GL_SIGNED_LUMINANCE8_ALPHA8_NV 0x8704 +#define GL_SIGNED_ALPHA_NV 0x8705 +#define GL_SIGNED_ALPHA8_NV 0x8706 +#define GL_SIGNED_INTENSITY_NV 0x8707 +#define GL_SIGNED_INTENSITY8_NV 0x8708 +#define GL_DSDT8_NV 0x8709 +#define GL_DSDT8_MAG8_NV 0x870A +#define GL_DSDT8_MAG8_INTENSITY8_NV 0x870B +#define GL_SIGNED_RGB_UNSIGNED_ALPHA_NV 0x870C +#define GL_SIGNED_RGB8_UNSIGNED_ALPHA8_NV 0x870D + +#define GLEW_NV_texture_shader2 GLEW_GET_VAR(__GLEW_NV_texture_shader2) + +#endif /* GL_NV_texture_shader2 */ + +/* ------------------------- GL_NV_texture_shader3 ------------------------- */ + +#ifndef GL_NV_texture_shader3 +#define GL_NV_texture_shader3 1 + +#define GL_OFFSET_PROJECTIVE_TEXTURE_2D_NV 0x8850 +#define GL_OFFSET_PROJECTIVE_TEXTURE_2D_SCALE_NV 0x8851 +#define GL_OFFSET_PROJECTIVE_TEXTURE_RECTANGLE_NV 0x8852 +#define GL_OFFSET_PROJECTIVE_TEXTURE_RECTANGLE_SCALE_NV 0x8853 +#define GL_OFFSET_HILO_TEXTURE_2D_NV 0x8854 +#define GL_OFFSET_HILO_TEXTURE_RECTANGLE_NV 0x8855 +#define GL_OFFSET_HILO_PROJECTIVE_TEXTURE_2D_NV 0x8856 +#define GL_OFFSET_HILO_PROJECTIVE_TEXTURE_RECTANGLE_NV 0x8857 +#define GL_DEPENDENT_HILO_TEXTURE_2D_NV 0x8858 +#define GL_DEPENDENT_RGB_TEXTURE_3D_NV 0x8859 +#define GL_DEPENDENT_RGB_TEXTURE_CUBE_MAP_NV 0x885A +#define GL_DOT_PRODUCT_PASS_THROUGH_NV 0x885B +#define GL_DOT_PRODUCT_TEXTURE_1D_NV 0x885C +#define GL_DOT_PRODUCT_AFFINE_DEPTH_REPLACE_NV 0x885D +#define GL_HILO8_NV 0x885E +#define GL_SIGNED_HILO8_NV 0x885F +#define GL_FORCE_BLUE_TO_ONE_NV 0x8860 + +#define GLEW_NV_texture_shader3 GLEW_GET_VAR(__GLEW_NV_texture_shader3) + +#endif /* GL_NV_texture_shader3 */ + +/* ------------------------ GL_NV_vertex_array_range ----------------------- */ + +#ifndef GL_NV_vertex_array_range +#define GL_NV_vertex_array_range 1 + +#define GL_VERTEX_ARRAY_RANGE_NV 0x851D +#define GL_VERTEX_ARRAY_RANGE_LENGTH_NV 0x851E +#define GL_VERTEX_ARRAY_RANGE_VALID_NV 0x851F +#define GL_MAX_VERTEX_ARRAY_RANGE_ELEMENT_NV 0x8520 +#define GL_VERTEX_ARRAY_RANGE_POINTER_NV 0x8521 + +typedef void (GLAPIENTRY * PFNGLFLUSHVERTEXARRAYRANGENVPROC) (void); +typedef void (GLAPIENTRY * PFNGLVERTEXARRAYRANGENVPROC) (GLsizei length, void* pointer); + +#define glFlushVertexArrayRangeNV GLEW_GET_FUN(__glewFlushVertexArrayRangeNV) +#define glVertexArrayRangeNV GLEW_GET_FUN(__glewVertexArrayRangeNV) + +#define GLEW_NV_vertex_array_range GLEW_GET_VAR(__GLEW_NV_vertex_array_range) + +#endif /* GL_NV_vertex_array_range */ + +/* ----------------------- GL_NV_vertex_array_range2 ----------------------- */ + +#ifndef GL_NV_vertex_array_range2 +#define GL_NV_vertex_array_range2 1 + +#define GL_VERTEX_ARRAY_RANGE_WITHOUT_FLUSH_NV 0x8533 + +#define GLEW_NV_vertex_array_range2 GLEW_GET_VAR(__GLEW_NV_vertex_array_range2) + +#endif /* GL_NV_vertex_array_range2 */ + +/* -------------------------- GL_NV_vertex_program ------------------------- */ + +#ifndef GL_NV_vertex_program +#define GL_NV_vertex_program 1 + +#define GL_VERTEX_PROGRAM_NV 0x8620 +#define GL_VERTEX_STATE_PROGRAM_NV 0x8621 +#define GL_ATTRIB_ARRAY_SIZE_NV 0x8623 +#define GL_ATTRIB_ARRAY_STRIDE_NV 0x8624 +#define GL_ATTRIB_ARRAY_TYPE_NV 0x8625 +#define GL_CURRENT_ATTRIB_NV 0x8626 +#define GL_PROGRAM_LENGTH_NV 0x8627 +#define GL_PROGRAM_STRING_NV 0x8628 +#define GL_MODELVIEW_PROJECTION_NV 0x8629 +#define GL_IDENTITY_NV 0x862A +#define GL_INVERSE_NV 0x862B +#define GL_TRANSPOSE_NV 0x862C +#define GL_INVERSE_TRANSPOSE_NV 0x862D +#define GL_MAX_TRACK_MATRIX_STACK_DEPTH_NV 0x862E +#define GL_MAX_TRACK_MATRICES_NV 0x862F +#define GL_MATRIX0_NV 0x8630 +#define GL_MATRIX1_NV 0x8631 +#define GL_MATRIX2_NV 0x8632 +#define GL_MATRIX3_NV 0x8633 +#define GL_MATRIX4_NV 0x8634 +#define GL_MATRIX5_NV 0x8635 +#define GL_MATRIX6_NV 0x8636 +#define GL_MATRIX7_NV 0x8637 +#define GL_CURRENT_MATRIX_STACK_DEPTH_NV 0x8640 +#define GL_CURRENT_MATRIX_NV 0x8641 +#define GL_VERTEX_PROGRAM_POINT_SIZE_NV 0x8642 +#define GL_VERTEX_PROGRAM_TWO_SIDE_NV 0x8643 +#define GL_PROGRAM_PARAMETER_NV 0x8644 +#define GL_ATTRIB_ARRAY_POINTER_NV 0x8645 +#define GL_PROGRAM_TARGET_NV 0x8646 +#define GL_PROGRAM_RESIDENT_NV 0x8647 +#define GL_TRACK_MATRIX_NV 0x8648 +#define GL_TRACK_MATRIX_TRANSFORM_NV 0x8649 +#define GL_VERTEX_PROGRAM_BINDING_NV 0x864A +#define GL_PROGRAM_ERROR_POSITION_NV 0x864B +#define GL_VERTEX_ATTRIB_ARRAY0_NV 0x8650 +#define GL_VERTEX_ATTRIB_ARRAY1_NV 0x8651 +#define GL_VERTEX_ATTRIB_ARRAY2_NV 0x8652 +#define GL_VERTEX_ATTRIB_ARRAY3_NV 0x8653 +#define GL_VERTEX_ATTRIB_ARRAY4_NV 0x8654 +#define GL_VERTEX_ATTRIB_ARRAY5_NV 0x8655 +#define GL_VERTEX_ATTRIB_ARRAY6_NV 0x8656 +#define GL_VERTEX_ATTRIB_ARRAY7_NV 0x8657 +#define GL_VERTEX_ATTRIB_ARRAY8_NV 0x8658 +#define GL_VERTEX_ATTRIB_ARRAY9_NV 0x8659 +#define GL_VERTEX_ATTRIB_ARRAY10_NV 0x865A +#define GL_VERTEX_ATTRIB_ARRAY11_NV 0x865B +#define GL_VERTEX_ATTRIB_ARRAY12_NV 0x865C +#define GL_VERTEX_ATTRIB_ARRAY13_NV 0x865D +#define GL_VERTEX_ATTRIB_ARRAY14_NV 0x865E +#define GL_VERTEX_ATTRIB_ARRAY15_NV 0x865F +#define GL_MAP1_VERTEX_ATTRIB0_4_NV 0x8660 +#define GL_MAP1_VERTEX_ATTRIB1_4_NV 0x8661 +#define GL_MAP1_VERTEX_ATTRIB2_4_NV 0x8662 +#define GL_MAP1_VERTEX_ATTRIB3_4_NV 0x8663 +#define GL_MAP1_VERTEX_ATTRIB4_4_NV 0x8664 +#define GL_MAP1_VERTEX_ATTRIB5_4_NV 0x8665 +#define GL_MAP1_VERTEX_ATTRIB6_4_NV 0x8666 +#define GL_MAP1_VERTEX_ATTRIB7_4_NV 0x8667 +#define GL_MAP1_VERTEX_ATTRIB8_4_NV 0x8668 +#define GL_MAP1_VERTEX_ATTRIB9_4_NV 0x8669 +#define GL_MAP1_VERTEX_ATTRIB10_4_NV 0x866A +#define GL_MAP1_VERTEX_ATTRIB11_4_NV 0x866B +#define GL_MAP1_VERTEX_ATTRIB12_4_NV 0x866C +#define GL_MAP1_VERTEX_ATTRIB13_4_NV 0x866D +#define GL_MAP1_VERTEX_ATTRIB14_4_NV 0x866E +#define GL_MAP1_VERTEX_ATTRIB15_4_NV 0x866F +#define GL_MAP2_VERTEX_ATTRIB0_4_NV 0x8670 +#define GL_MAP2_VERTEX_ATTRIB1_4_NV 0x8671 +#define GL_MAP2_VERTEX_ATTRIB2_4_NV 0x8672 +#define GL_MAP2_VERTEX_ATTRIB3_4_NV 0x8673 +#define GL_MAP2_VERTEX_ATTRIB4_4_NV 0x8674 +#define GL_MAP2_VERTEX_ATTRIB5_4_NV 0x8675 +#define GL_MAP2_VERTEX_ATTRIB6_4_NV 0x8676 +#define GL_MAP2_VERTEX_ATTRIB7_4_NV 0x8677 +#define GL_MAP2_VERTEX_ATTRIB8_4_NV 0x8678 +#define GL_MAP2_VERTEX_ATTRIB9_4_NV 0x8679 +#define GL_MAP2_VERTEX_ATTRIB10_4_NV 0x867A +#define GL_MAP2_VERTEX_ATTRIB11_4_NV 0x867B +#define GL_MAP2_VERTEX_ATTRIB12_4_NV 0x867C +#define GL_MAP2_VERTEX_ATTRIB13_4_NV 0x867D +#define GL_MAP2_VERTEX_ATTRIB14_4_NV 0x867E +#define GL_MAP2_VERTEX_ATTRIB15_4_NV 0x867F + +typedef GLboolean (GLAPIENTRY * PFNGLAREPROGRAMSRESIDENTNVPROC) (GLsizei n, const GLuint* ids, GLboolean *residences); +typedef void (GLAPIENTRY * PFNGLBINDPROGRAMNVPROC) (GLenum target, GLuint id); +typedef void (GLAPIENTRY * PFNGLDELETEPROGRAMSNVPROC) (GLsizei n, const GLuint* ids); +typedef void (GLAPIENTRY * PFNGLEXECUTEPROGRAMNVPROC) (GLenum target, GLuint id, const GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGENPROGRAMSNVPROC) (GLsizei n, GLuint* ids); +typedef void (GLAPIENTRY * PFNGLGETPROGRAMPARAMETERDVNVPROC) (GLenum target, GLuint index, GLenum pname, GLdouble* params); +typedef void (GLAPIENTRY * PFNGLGETPROGRAMPARAMETERFVNVPROC) (GLenum target, GLuint index, GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETPROGRAMSTRINGNVPROC) (GLuint id, GLenum pname, GLubyte* program); +typedef void (GLAPIENTRY * PFNGLGETPROGRAMIVNVPROC) (GLuint id, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETTRACKMATRIXIVNVPROC) (GLenum target, GLuint address, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBPOINTERVNVPROC) (GLuint index, GLenum pname, GLvoid** pointer); +typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBDVNVPROC) (GLuint index, GLenum pname, GLdouble* params); +typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBFVNVPROC) (GLuint index, GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBIVNVPROC) (GLuint index, GLenum pname, GLint* params); +typedef GLboolean (GLAPIENTRY * PFNGLISPROGRAMNVPROC) (GLuint id); +typedef void (GLAPIENTRY * PFNGLLOADPROGRAMNVPROC) (GLenum target, GLuint id, GLsizei len, const GLubyte* program); +typedef void (GLAPIENTRY * PFNGLPROGRAMPARAMETER4DNVPROC) (GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (GLAPIENTRY * PFNGLPROGRAMPARAMETER4DVNVPROC) (GLenum target, GLuint index, const GLdouble* params); +typedef void (GLAPIENTRY * PFNGLPROGRAMPARAMETER4FNVPROC) (GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (GLAPIENTRY * PFNGLPROGRAMPARAMETER4FVNVPROC) (GLenum target, GLuint index, const GLfloat* params); +typedef void (GLAPIENTRY * PFNGLPROGRAMPARAMETERS4DVNVPROC) (GLenum target, GLuint index, GLuint num, const GLdouble* params); +typedef void (GLAPIENTRY * PFNGLPROGRAMPARAMETERS4FVNVPROC) (GLenum target, GLuint index, GLuint num, const GLfloat* params); +typedef void (GLAPIENTRY * PFNGLREQUESTRESIDENTPROGRAMSNVPROC) (GLsizei n, GLuint* ids); +typedef void (GLAPIENTRY * PFNGLTRACKMATRIXNVPROC) (GLenum target, GLuint address, GLenum matrix, GLenum transform); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1DNVPROC) (GLuint index, GLdouble x); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1DVNVPROC) (GLuint index, const GLdouble* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1FNVPROC) (GLuint index, GLfloat x); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1FVNVPROC) (GLuint index, const GLfloat* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1SNVPROC) (GLuint index, GLshort x); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1SVNVPROC) (GLuint index, const GLshort* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2DNVPROC) (GLuint index, GLdouble x, GLdouble y); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2DVNVPROC) (GLuint index, const GLdouble* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2FNVPROC) (GLuint index, GLfloat x, GLfloat y); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2FVNVPROC) (GLuint index, const GLfloat* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2SNVPROC) (GLuint index, GLshort x, GLshort y); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2SVNVPROC) (GLuint index, const GLshort* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3DNVPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3DVNVPROC) (GLuint index, const GLdouble* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3FNVPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3FVNVPROC) (GLuint index, const GLfloat* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3SNVPROC) (GLuint index, GLshort x, GLshort y, GLshort z); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3SVNVPROC) (GLuint index, const GLshort* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4DNVPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4DVNVPROC) (GLuint index, const GLdouble* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4FNVPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4FVNVPROC) (GLuint index, const GLfloat* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4SNVPROC) (GLuint index, GLshort x, GLshort y, GLshort z, GLshort w); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4SVNVPROC) (GLuint index, const GLshort* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4UBNVPROC) (GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4UBVNVPROC) (GLuint index, const GLubyte* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBPOINTERNVPROC) (GLuint index, GLint size, GLenum type, GLsizei stride, const void* pointer); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS1DVNVPROC) (GLuint index, GLsizei n, const GLdouble* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS1FVNVPROC) (GLuint index, GLsizei n, const GLfloat* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS1SVNVPROC) (GLuint index, GLsizei n, const GLshort* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS2DVNVPROC) (GLuint index, GLsizei n, const GLdouble* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS2FVNVPROC) (GLuint index, GLsizei n, const GLfloat* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS2SVNVPROC) (GLuint index, GLsizei n, const GLshort* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS3DVNVPROC) (GLuint index, GLsizei n, const GLdouble* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS3FVNVPROC) (GLuint index, GLsizei n, const GLfloat* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS3SVNVPROC) (GLuint index, GLsizei n, const GLshort* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS4DVNVPROC) (GLuint index, GLsizei n, const GLdouble* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS4FVNVPROC) (GLuint index, GLsizei n, const GLfloat* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS4SVNVPROC) (GLuint index, GLsizei n, const GLshort* v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS4UBVNVPROC) (GLuint index, GLsizei n, const GLubyte* v); + +#define glAreProgramsResidentNV GLEW_GET_FUN(__glewAreProgramsResidentNV) +#define glBindProgramNV GLEW_GET_FUN(__glewBindProgramNV) +#define glDeleteProgramsNV GLEW_GET_FUN(__glewDeleteProgramsNV) +#define glExecuteProgramNV GLEW_GET_FUN(__glewExecuteProgramNV) +#define glGenProgramsNV GLEW_GET_FUN(__glewGenProgramsNV) +#define glGetProgramParameterdvNV GLEW_GET_FUN(__glewGetProgramParameterdvNV) +#define glGetProgramParameterfvNV GLEW_GET_FUN(__glewGetProgramParameterfvNV) +#define glGetProgramStringNV GLEW_GET_FUN(__glewGetProgramStringNV) +#define glGetProgramivNV GLEW_GET_FUN(__glewGetProgramivNV) +#define glGetTrackMatrixivNV GLEW_GET_FUN(__glewGetTrackMatrixivNV) +#define glGetVertexAttribPointervNV GLEW_GET_FUN(__glewGetVertexAttribPointervNV) +#define glGetVertexAttribdvNV GLEW_GET_FUN(__glewGetVertexAttribdvNV) +#define glGetVertexAttribfvNV GLEW_GET_FUN(__glewGetVertexAttribfvNV) +#define glGetVertexAttribivNV GLEW_GET_FUN(__glewGetVertexAttribivNV) +#define glIsProgramNV GLEW_GET_FUN(__glewIsProgramNV) +#define glLoadProgramNV GLEW_GET_FUN(__glewLoadProgramNV) +#define glProgramParameter4dNV GLEW_GET_FUN(__glewProgramParameter4dNV) +#define glProgramParameter4dvNV GLEW_GET_FUN(__glewProgramParameter4dvNV) +#define glProgramParameter4fNV GLEW_GET_FUN(__glewProgramParameter4fNV) +#define glProgramParameter4fvNV GLEW_GET_FUN(__glewProgramParameter4fvNV) +#define glProgramParameters4dvNV GLEW_GET_FUN(__glewProgramParameters4dvNV) +#define glProgramParameters4fvNV GLEW_GET_FUN(__glewProgramParameters4fvNV) +#define glRequestResidentProgramsNV GLEW_GET_FUN(__glewRequestResidentProgramsNV) +#define glTrackMatrixNV GLEW_GET_FUN(__glewTrackMatrixNV) +#define glVertexAttrib1dNV GLEW_GET_FUN(__glewVertexAttrib1dNV) +#define glVertexAttrib1dvNV GLEW_GET_FUN(__glewVertexAttrib1dvNV) +#define glVertexAttrib1fNV GLEW_GET_FUN(__glewVertexAttrib1fNV) +#define glVertexAttrib1fvNV GLEW_GET_FUN(__glewVertexAttrib1fvNV) +#define glVertexAttrib1sNV GLEW_GET_FUN(__glewVertexAttrib1sNV) +#define glVertexAttrib1svNV GLEW_GET_FUN(__glewVertexAttrib1svNV) +#define glVertexAttrib2dNV GLEW_GET_FUN(__glewVertexAttrib2dNV) +#define glVertexAttrib2dvNV GLEW_GET_FUN(__glewVertexAttrib2dvNV) +#define glVertexAttrib2fNV GLEW_GET_FUN(__glewVertexAttrib2fNV) +#define glVertexAttrib2fvNV GLEW_GET_FUN(__glewVertexAttrib2fvNV) +#define glVertexAttrib2sNV GLEW_GET_FUN(__glewVertexAttrib2sNV) +#define glVertexAttrib2svNV GLEW_GET_FUN(__glewVertexAttrib2svNV) +#define glVertexAttrib3dNV GLEW_GET_FUN(__glewVertexAttrib3dNV) +#define glVertexAttrib3dvNV GLEW_GET_FUN(__glewVertexAttrib3dvNV) +#define glVertexAttrib3fNV GLEW_GET_FUN(__glewVertexAttrib3fNV) +#define glVertexAttrib3fvNV GLEW_GET_FUN(__glewVertexAttrib3fvNV) +#define glVertexAttrib3sNV GLEW_GET_FUN(__glewVertexAttrib3sNV) +#define glVertexAttrib3svNV GLEW_GET_FUN(__glewVertexAttrib3svNV) +#define glVertexAttrib4dNV GLEW_GET_FUN(__glewVertexAttrib4dNV) +#define glVertexAttrib4dvNV GLEW_GET_FUN(__glewVertexAttrib4dvNV) +#define glVertexAttrib4fNV GLEW_GET_FUN(__glewVertexAttrib4fNV) +#define glVertexAttrib4fvNV GLEW_GET_FUN(__glewVertexAttrib4fvNV) +#define glVertexAttrib4sNV GLEW_GET_FUN(__glewVertexAttrib4sNV) +#define glVertexAttrib4svNV GLEW_GET_FUN(__glewVertexAttrib4svNV) +#define glVertexAttrib4ubNV GLEW_GET_FUN(__glewVertexAttrib4ubNV) +#define glVertexAttrib4ubvNV GLEW_GET_FUN(__glewVertexAttrib4ubvNV) +#define glVertexAttribPointerNV GLEW_GET_FUN(__glewVertexAttribPointerNV) +#define glVertexAttribs1dvNV GLEW_GET_FUN(__glewVertexAttribs1dvNV) +#define glVertexAttribs1fvNV GLEW_GET_FUN(__glewVertexAttribs1fvNV) +#define glVertexAttribs1svNV GLEW_GET_FUN(__glewVertexAttribs1svNV) +#define glVertexAttribs2dvNV GLEW_GET_FUN(__glewVertexAttribs2dvNV) +#define glVertexAttribs2fvNV GLEW_GET_FUN(__glewVertexAttribs2fvNV) +#define glVertexAttribs2svNV GLEW_GET_FUN(__glewVertexAttribs2svNV) +#define glVertexAttribs3dvNV GLEW_GET_FUN(__glewVertexAttribs3dvNV) +#define glVertexAttribs3fvNV GLEW_GET_FUN(__glewVertexAttribs3fvNV) +#define glVertexAttribs3svNV GLEW_GET_FUN(__glewVertexAttribs3svNV) +#define glVertexAttribs4dvNV GLEW_GET_FUN(__glewVertexAttribs4dvNV) +#define glVertexAttribs4fvNV GLEW_GET_FUN(__glewVertexAttribs4fvNV) +#define glVertexAttribs4svNV GLEW_GET_FUN(__glewVertexAttribs4svNV) +#define glVertexAttribs4ubvNV GLEW_GET_FUN(__glewVertexAttribs4ubvNV) + +#define GLEW_NV_vertex_program GLEW_GET_VAR(__GLEW_NV_vertex_program) + +#endif /* GL_NV_vertex_program */ + +/* ------------------------ GL_NV_vertex_program1_1 ------------------------ */ + +#ifndef GL_NV_vertex_program1_1 +#define GL_NV_vertex_program1_1 1 + +#define GLEW_NV_vertex_program1_1 GLEW_GET_VAR(__GLEW_NV_vertex_program1_1) + +#endif /* GL_NV_vertex_program1_1 */ + +/* ------------------------- GL_NV_vertex_program2 ------------------------- */ + +#ifndef GL_NV_vertex_program2 +#define GL_NV_vertex_program2 1 + +#define GLEW_NV_vertex_program2 GLEW_GET_VAR(__GLEW_NV_vertex_program2) + +#endif /* GL_NV_vertex_program2 */ + +/* ---------------------- GL_NV_vertex_program2_option --------------------- */ + +#ifndef GL_NV_vertex_program2_option +#define GL_NV_vertex_program2_option 1 + +#define GL_MAX_PROGRAM_EXEC_INSTRUCTIONS_NV 0x88F4 +#define GL_MAX_PROGRAM_CALL_DEPTH_NV 0x88F5 + +#define GLEW_NV_vertex_program2_option GLEW_GET_VAR(__GLEW_NV_vertex_program2_option) + +#endif /* GL_NV_vertex_program2_option */ + +/* ------------------------- GL_NV_vertex_program3 ------------------------- */ + +#ifndef GL_NV_vertex_program3 +#define GL_NV_vertex_program3 1 + +#define MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB 0x8B4C + +#define GLEW_NV_vertex_program3 GLEW_GET_VAR(__GLEW_NV_vertex_program3) + +#endif /* GL_NV_vertex_program3 */ + +/* ---------------------------- GL_OML_interlace --------------------------- */ + +#ifndef GL_OML_interlace +#define GL_OML_interlace 1 + +#define GL_INTERLACE_OML 0x8980 +#define GL_INTERLACE_READ_OML 0x8981 + +#define GLEW_OML_interlace GLEW_GET_VAR(__GLEW_OML_interlace) + +#endif /* GL_OML_interlace */ + +/* ---------------------------- GL_OML_resample ---------------------------- */ + +#ifndef GL_OML_resample +#define GL_OML_resample 1 + +#define GL_PACK_RESAMPLE_OML 0x8984 +#define GL_UNPACK_RESAMPLE_OML 0x8985 +#define GL_RESAMPLE_REPLICATE_OML 0x8986 +#define GL_RESAMPLE_ZERO_FILL_OML 0x8987 +#define GL_RESAMPLE_AVERAGE_OML 0x8988 +#define GL_RESAMPLE_DECIMATE_OML 0x8989 + +#define GLEW_OML_resample GLEW_GET_VAR(__GLEW_OML_resample) + +#endif /* GL_OML_resample */ + +/* ---------------------------- GL_OML_subsample --------------------------- */ + +#ifndef GL_OML_subsample +#define GL_OML_subsample 1 + +#define GL_FORMAT_SUBSAMPLE_24_24_OML 0x8982 +#define GL_FORMAT_SUBSAMPLE_244_244_OML 0x8983 + +#define GLEW_OML_subsample GLEW_GET_VAR(__GLEW_OML_subsample) + +#endif /* GL_OML_subsample */ + +/* --------------------------- GL_PGI_misc_hints --------------------------- */ + +#ifndef GL_PGI_misc_hints +#define GL_PGI_misc_hints 1 + +#define GL_PREFER_DOUBLEBUFFER_HINT_PGI 107000 +#define GL_CONSERVE_MEMORY_HINT_PGI 107005 +#define GL_RECLAIM_MEMORY_HINT_PGI 107006 +#define GL_NATIVE_GRAPHICS_HANDLE_PGI 107010 +#define GL_NATIVE_GRAPHICS_BEGIN_HINT_PGI 107011 +#define GL_NATIVE_GRAPHICS_END_HINT_PGI 107012 +#define GL_ALWAYS_FAST_HINT_PGI 107020 +#define GL_ALWAYS_SOFT_HINT_PGI 107021 +#define GL_ALLOW_DRAW_OBJ_HINT_PGI 107022 +#define GL_ALLOW_DRAW_WIN_HINT_PGI 107023 +#define GL_ALLOW_DRAW_FRG_HINT_PGI 107024 +#define GL_ALLOW_DRAW_MEM_HINT_PGI 107025 +#define GL_STRICT_DEPTHFUNC_HINT_PGI 107030 +#define GL_STRICT_LIGHTING_HINT_PGI 107031 +#define GL_STRICT_SCISSOR_HINT_PGI 107032 +#define GL_FULL_STIPPLE_HINT_PGI 107033 +#define GL_CLIP_NEAR_HINT_PGI 107040 +#define GL_CLIP_FAR_HINT_PGI 107041 +#define GL_WIDE_LINE_HINT_PGI 107042 +#define GL_BACK_NORMALS_HINT_PGI 107043 + +#define GLEW_PGI_misc_hints GLEW_GET_VAR(__GLEW_PGI_misc_hints) + +#endif /* GL_PGI_misc_hints */ + +/* -------------------------- GL_PGI_vertex_hints -------------------------- */ + +#ifndef GL_PGI_vertex_hints +#define GL_PGI_vertex_hints 1 + +#define GL_VERTEX23_BIT_PGI 0x00000004 +#define GL_VERTEX4_BIT_PGI 0x00000008 +#define GL_COLOR3_BIT_PGI 0x00010000 +#define GL_COLOR4_BIT_PGI 0x00020000 +#define GL_EDGEFLAG_BIT_PGI 0x00040000 +#define GL_INDEX_BIT_PGI 0x00080000 +#define GL_MAT_AMBIENT_BIT_PGI 0x00100000 +#define GL_VERTEX_DATA_HINT_PGI 107050 +#define GL_VERTEX_CONSISTENT_HINT_PGI 107051 +#define GL_MATERIAL_SIDE_HINT_PGI 107052 +#define GL_MAX_VERTEX_HINT_PGI 107053 +#define GL_MAT_AMBIENT_AND_DIFFUSE_BIT_PGI 0x00200000 +#define GL_MAT_DIFFUSE_BIT_PGI 0x00400000 +#define GL_MAT_EMISSION_BIT_PGI 0x00800000 +#define GL_MAT_COLOR_INDEXES_BIT_PGI 0x01000000 +#define GL_MAT_SHININESS_BIT_PGI 0x02000000 +#define GL_MAT_SPECULAR_BIT_PGI 0x04000000 +#define GL_NORMAL_BIT_PGI 0x08000000 +#define GL_TEXCOORD1_BIT_PGI 0x10000000 +#define GL_TEXCOORD2_BIT_PGI 0x20000000 +#define GL_TEXCOORD3_BIT_PGI 0x40000000 +#define GL_TEXCOORD4_BIT_PGI 0x80000000 + +#define GLEW_PGI_vertex_hints GLEW_GET_VAR(__GLEW_PGI_vertex_hints) + +#endif /* GL_PGI_vertex_hints */ + +/* ----------------------- GL_REND_screen_coordinates ---------------------- */ + +#ifndef GL_REND_screen_coordinates +#define GL_REND_screen_coordinates 1 + +#define GL_SCREEN_COORDINATES_REND 0x8490 +#define GL_INVERTED_SCREEN_W_REND 0x8491 + +#define GLEW_REND_screen_coordinates GLEW_GET_VAR(__GLEW_REND_screen_coordinates) + +#endif /* GL_REND_screen_coordinates */ + +/* ------------------------------- GL_S3_s3tc ------------------------------ */ + +#ifndef GL_S3_s3tc +#define GL_S3_s3tc 1 + +#define GL_RGB_S3TC 0x83A0 +#define GL_RGB4_S3TC 0x83A1 +#define GL_RGBA_S3TC 0x83A2 +#define GL_RGBA4_S3TC 0x83A3 +#define GL_RGBA_DXT5_S3TC 0x83A4 +#define GL_RGBA4_DXT5_S3TC 0x83A5 + +#define GLEW_S3_s3tc GLEW_GET_VAR(__GLEW_S3_s3tc) + +#endif /* GL_S3_s3tc */ + +/* -------------------------- GL_SGIS_color_range -------------------------- */ + +#ifndef GL_SGIS_color_range +#define GL_SGIS_color_range 1 + +#define GL_EXTENDED_RANGE_SGIS 0x85A5 +#define GL_MIN_RED_SGIS 0x85A6 +#define GL_MAX_RED_SGIS 0x85A7 +#define GL_MIN_GREEN_SGIS 0x85A8 +#define GL_MAX_GREEN_SGIS 0x85A9 +#define GL_MIN_BLUE_SGIS 0x85AA +#define GL_MAX_BLUE_SGIS 0x85AB +#define GL_MIN_ALPHA_SGIS 0x85AC +#define GL_MAX_ALPHA_SGIS 0x85AD + +#define GLEW_SGIS_color_range GLEW_GET_VAR(__GLEW_SGIS_color_range) + +#endif /* GL_SGIS_color_range */ + +/* ------------------------- GL_SGIS_detail_texture ------------------------ */ + +#ifndef GL_SGIS_detail_texture +#define GL_SGIS_detail_texture 1 + +typedef void (GLAPIENTRY * PFNGLDETAILTEXFUNCSGISPROC) (GLenum target, GLsizei n, const GLfloat* points); +typedef void (GLAPIENTRY * PFNGLGETDETAILTEXFUNCSGISPROC) (GLenum target, GLfloat* points); + +#define glDetailTexFuncSGIS GLEW_GET_FUN(__glewDetailTexFuncSGIS) +#define glGetDetailTexFuncSGIS GLEW_GET_FUN(__glewGetDetailTexFuncSGIS) + +#define GLEW_SGIS_detail_texture GLEW_GET_VAR(__GLEW_SGIS_detail_texture) + +#endif /* GL_SGIS_detail_texture */ + +/* -------------------------- GL_SGIS_fog_function ------------------------- */ + +#ifndef GL_SGIS_fog_function +#define GL_SGIS_fog_function 1 + +typedef void (GLAPIENTRY * PFNGLFOGFUNCSGISPROC) (GLsizei n, const GLfloat* points); +typedef void (GLAPIENTRY * PFNGLGETFOGFUNCSGISPROC) (GLfloat* points); + +#define glFogFuncSGIS GLEW_GET_FUN(__glewFogFuncSGIS) +#define glGetFogFuncSGIS GLEW_GET_FUN(__glewGetFogFuncSGIS) + +#define GLEW_SGIS_fog_function GLEW_GET_VAR(__GLEW_SGIS_fog_function) + +#endif /* GL_SGIS_fog_function */ + +/* ------------------------ GL_SGIS_generate_mipmap ------------------------ */ + +#ifndef GL_SGIS_generate_mipmap +#define GL_SGIS_generate_mipmap 1 + +#define GL_GENERATE_MIPMAP_SGIS 0x8191 +#define GL_GENERATE_MIPMAP_HINT_SGIS 0x8192 + +#define GLEW_SGIS_generate_mipmap GLEW_GET_VAR(__GLEW_SGIS_generate_mipmap) + +#endif /* GL_SGIS_generate_mipmap */ + +/* -------------------------- GL_SGIS_multisample -------------------------- */ + +#ifndef GL_SGIS_multisample +#define GL_SGIS_multisample 1 + +#define GL_MULTISAMPLE_SGIS 0x809D +#define GL_SAMPLE_ALPHA_TO_MASK_SGIS 0x809E +#define GL_SAMPLE_ALPHA_TO_ONE_SGIS 0x809F +#define GL_SAMPLE_MASK_SGIS 0x80A0 +#define GL_1PASS_SGIS 0x80A1 +#define GL_2PASS_0_SGIS 0x80A2 +#define GL_2PASS_1_SGIS 0x80A3 +#define GL_4PASS_0_SGIS 0x80A4 +#define GL_4PASS_1_SGIS 0x80A5 +#define GL_4PASS_2_SGIS 0x80A6 +#define GL_4PASS_3_SGIS 0x80A7 +#define GL_SAMPLE_BUFFERS_SGIS 0x80A8 +#define GL_SAMPLES_SGIS 0x80A9 +#define GL_SAMPLE_MASK_VALUE_SGIS 0x80AA +#define GL_SAMPLE_MASK_INVERT_SGIS 0x80AB +#define GL_SAMPLE_PATTERN_SGIS 0x80AC +#define GL_MULTISAMPLE_BIT_EXT 0x20000000 + +typedef void (GLAPIENTRY * PFNGLSAMPLEMASKSGISPROC) (GLclampf value, GLboolean invert); +typedef void (GLAPIENTRY * PFNGLSAMPLEPATTERNSGISPROC) (GLenum pattern); + +#define glSampleMaskSGIS GLEW_GET_FUN(__glewSampleMaskSGIS) +#define glSamplePatternSGIS GLEW_GET_FUN(__glewSamplePatternSGIS) + +#define GLEW_SGIS_multisample GLEW_GET_VAR(__GLEW_SGIS_multisample) + +#endif /* GL_SGIS_multisample */ + +/* ------------------------- GL_SGIS_pixel_texture ------------------------- */ + +#ifndef GL_SGIS_pixel_texture +#define GL_SGIS_pixel_texture 1 + +#define GLEW_SGIS_pixel_texture GLEW_GET_VAR(__GLEW_SGIS_pixel_texture) + +#endif /* GL_SGIS_pixel_texture */ + +/* ------------------------ GL_SGIS_sharpen_texture ------------------------ */ + +#ifndef GL_SGIS_sharpen_texture +#define GL_SGIS_sharpen_texture 1 + +typedef void (GLAPIENTRY * PFNGLGETSHARPENTEXFUNCSGISPROC) (GLenum target, GLfloat* points); +typedef void (GLAPIENTRY * PFNGLSHARPENTEXFUNCSGISPROC) (GLenum target, GLsizei n, const GLfloat* points); + +#define glGetSharpenTexFuncSGIS GLEW_GET_FUN(__glewGetSharpenTexFuncSGIS) +#define glSharpenTexFuncSGIS GLEW_GET_FUN(__glewSharpenTexFuncSGIS) + +#define GLEW_SGIS_sharpen_texture GLEW_GET_VAR(__GLEW_SGIS_sharpen_texture) + +#endif /* GL_SGIS_sharpen_texture */ + +/* --------------------------- GL_SGIS_texture4D --------------------------- */ + +#ifndef GL_SGIS_texture4D +#define GL_SGIS_texture4D 1 + +typedef void (GLAPIENTRY * PFNGLTEXIMAGE4DSGISPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLsizei extent, GLint border, GLenum format, GLenum type, const void* pixels); +typedef void (GLAPIENTRY * PFNGLTEXSUBIMAGE4DSGISPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint woffset, GLsizei width, GLsizei height, GLsizei depth, GLsizei extent, GLenum format, GLenum type, const void* pixels); + +#define glTexImage4DSGIS GLEW_GET_FUN(__glewTexImage4DSGIS) +#define glTexSubImage4DSGIS GLEW_GET_FUN(__glewTexSubImage4DSGIS) + +#define GLEW_SGIS_texture4D GLEW_GET_VAR(__GLEW_SGIS_texture4D) + +#endif /* GL_SGIS_texture4D */ + +/* ---------------------- GL_SGIS_texture_border_clamp --------------------- */ + +#ifndef GL_SGIS_texture_border_clamp +#define GL_SGIS_texture_border_clamp 1 + +#define GL_CLAMP_TO_BORDER_SGIS 0x812D + +#define GLEW_SGIS_texture_border_clamp GLEW_GET_VAR(__GLEW_SGIS_texture_border_clamp) + +#endif /* GL_SGIS_texture_border_clamp */ + +/* ----------------------- GL_SGIS_texture_edge_clamp ---------------------- */ + +#ifndef GL_SGIS_texture_edge_clamp +#define GL_SGIS_texture_edge_clamp 1 + +#define GL_CLAMP_TO_EDGE_SGIS 0x812F + +#define GLEW_SGIS_texture_edge_clamp GLEW_GET_VAR(__GLEW_SGIS_texture_edge_clamp) + +#endif /* GL_SGIS_texture_edge_clamp */ + +/* ------------------------ GL_SGIS_texture_filter4 ------------------------ */ + +#ifndef GL_SGIS_texture_filter4 +#define GL_SGIS_texture_filter4 1 + +typedef void (GLAPIENTRY * PFNGLGETTEXFILTERFUNCSGISPROC) (GLenum target, GLenum filter, GLfloat* weights); +typedef void (GLAPIENTRY * PFNGLTEXFILTERFUNCSGISPROC) (GLenum target, GLenum filter, GLsizei n, const GLfloat* weights); + +#define glGetTexFilterFuncSGIS GLEW_GET_FUN(__glewGetTexFilterFuncSGIS) +#define glTexFilterFuncSGIS GLEW_GET_FUN(__glewTexFilterFuncSGIS) + +#define GLEW_SGIS_texture_filter4 GLEW_GET_VAR(__GLEW_SGIS_texture_filter4) + +#endif /* GL_SGIS_texture_filter4 */ + +/* -------------------------- GL_SGIS_texture_lod -------------------------- */ + +#ifndef GL_SGIS_texture_lod +#define GL_SGIS_texture_lod 1 + +#define GL_TEXTURE_MIN_LOD_SGIS 0x813A +#define GL_TEXTURE_MAX_LOD_SGIS 0x813B +#define GL_TEXTURE_BASE_LEVEL_SGIS 0x813C +#define GL_TEXTURE_MAX_LEVEL_SGIS 0x813D + +#define GLEW_SGIS_texture_lod GLEW_GET_VAR(__GLEW_SGIS_texture_lod) + +#endif /* GL_SGIS_texture_lod */ + +/* ------------------------- GL_SGIS_texture_select ------------------------ */ + +#ifndef GL_SGIS_texture_select +#define GL_SGIS_texture_select 1 + +#define GLEW_SGIS_texture_select GLEW_GET_VAR(__GLEW_SGIS_texture_select) + +#endif /* GL_SGIS_texture_select */ + +/* ----------------------------- GL_SGIX_async ----------------------------- */ + +#ifndef GL_SGIX_async +#define GL_SGIX_async 1 + +#define GL_ASYNC_MARKER_SGIX 0x8329 + +typedef void (GLAPIENTRY * PFNGLASYNCMARKERSGIXPROC) (GLuint marker); +typedef void (GLAPIENTRY * PFNGLDELETEASYNCMARKERSSGIXPROC) (GLuint marker, GLsizei range); +typedef GLint (GLAPIENTRY * PFNGLFINISHASYNCSGIXPROC) (GLuint* markerp); +typedef GLuint (GLAPIENTRY * PFNGLGENASYNCMARKERSSGIXPROC) (GLsizei range); +typedef GLboolean (GLAPIENTRY * PFNGLISASYNCMARKERSGIXPROC) (GLuint marker); +typedef GLint (GLAPIENTRY * PFNGLPOLLASYNCSGIXPROC) (GLuint* markerp); + +#define glAsyncMarkerSGIX GLEW_GET_FUN(__glewAsyncMarkerSGIX) +#define glDeleteAsyncMarkersSGIX GLEW_GET_FUN(__glewDeleteAsyncMarkersSGIX) +#define glFinishAsyncSGIX GLEW_GET_FUN(__glewFinishAsyncSGIX) +#define glGenAsyncMarkersSGIX GLEW_GET_FUN(__glewGenAsyncMarkersSGIX) +#define glIsAsyncMarkerSGIX GLEW_GET_FUN(__glewIsAsyncMarkerSGIX) +#define glPollAsyncSGIX GLEW_GET_FUN(__glewPollAsyncSGIX) + +#define GLEW_SGIX_async GLEW_GET_VAR(__GLEW_SGIX_async) + +#endif /* GL_SGIX_async */ + +/* ------------------------ GL_SGIX_async_histogram ------------------------ */ + +#ifndef GL_SGIX_async_histogram +#define GL_SGIX_async_histogram 1 + +#define GL_ASYNC_HISTOGRAM_SGIX 0x832C +#define GL_MAX_ASYNC_HISTOGRAM_SGIX 0x832D + +#define GLEW_SGIX_async_histogram GLEW_GET_VAR(__GLEW_SGIX_async_histogram) + +#endif /* GL_SGIX_async_histogram */ + +/* -------------------------- GL_SGIX_async_pixel -------------------------- */ + +#ifndef GL_SGIX_async_pixel +#define GL_SGIX_async_pixel 1 + +#define GL_ASYNC_TEX_IMAGE_SGIX 0x835C +#define GL_ASYNC_DRAW_PIXELS_SGIX 0x835D +#define GL_ASYNC_READ_PIXELS_SGIX 0x835E +#define GL_MAX_ASYNC_TEX_IMAGE_SGIX 0x835F +#define GL_MAX_ASYNC_DRAW_PIXELS_SGIX 0x8360 +#define GL_MAX_ASYNC_READ_PIXELS_SGIX 0x8361 + +#define GLEW_SGIX_async_pixel GLEW_GET_VAR(__GLEW_SGIX_async_pixel) + +#endif /* GL_SGIX_async_pixel */ + +/* ----------------------- GL_SGIX_blend_alpha_minmax ---------------------- */ + +#ifndef GL_SGIX_blend_alpha_minmax +#define GL_SGIX_blend_alpha_minmax 1 + +#define GL_ALPHA_MIN_SGIX 0x8320 +#define GL_ALPHA_MAX_SGIX 0x8321 + +#define GLEW_SGIX_blend_alpha_minmax GLEW_GET_VAR(__GLEW_SGIX_blend_alpha_minmax) + +#endif /* GL_SGIX_blend_alpha_minmax */ + +/* ---------------------------- GL_SGIX_clipmap ---------------------------- */ + +#ifndef GL_SGIX_clipmap +#define GL_SGIX_clipmap 1 + +#define GLEW_SGIX_clipmap GLEW_GET_VAR(__GLEW_SGIX_clipmap) + +#endif /* GL_SGIX_clipmap */ + +/* ------------------------- GL_SGIX_depth_texture ------------------------- */ + +#ifndef GL_SGIX_depth_texture +#define GL_SGIX_depth_texture 1 + +#define GL_DEPTH_COMPONENT16_SGIX 0x81A5 +#define GL_DEPTH_COMPONENT24_SGIX 0x81A6 +#define GL_DEPTH_COMPONENT32_SGIX 0x81A7 + +#define GLEW_SGIX_depth_texture GLEW_GET_VAR(__GLEW_SGIX_depth_texture) + +#endif /* GL_SGIX_depth_texture */ + +/* -------------------------- GL_SGIX_flush_raster ------------------------- */ + +#ifndef GL_SGIX_flush_raster +#define GL_SGIX_flush_raster 1 + +typedef void (GLAPIENTRY * PFNGLFLUSHRASTERSGIXPROC) (void); + +#define glFlushRasterSGIX GLEW_GET_FUN(__glewFlushRasterSGIX) + +#define GLEW_SGIX_flush_raster GLEW_GET_VAR(__GLEW_SGIX_flush_raster) + +#endif /* GL_SGIX_flush_raster */ + +/* --------------------------- GL_SGIX_fog_offset -------------------------- */ + +#ifndef GL_SGIX_fog_offset +#define GL_SGIX_fog_offset 1 + +#define GL_FOG_OFFSET_SGIX 0x8198 +#define GL_FOG_OFFSET_VALUE_SGIX 0x8199 + +#define GLEW_SGIX_fog_offset GLEW_GET_VAR(__GLEW_SGIX_fog_offset) + +#endif /* GL_SGIX_fog_offset */ + +/* -------------------------- GL_SGIX_fog_texture -------------------------- */ + +#ifndef GL_SGIX_fog_texture +#define GL_SGIX_fog_texture 1 + +#define GL_TEXTURE_FOG_SGIX 0 +#define GL_FOG_PATCHY_FACTOR_SGIX 0 +#define GL_FRAGMENT_FOG_SGIX 0 + +typedef void (GLAPIENTRY * PFNGLTEXTUREFOGSGIXPROC) (GLenum pname); + +#define glTextureFogSGIX GLEW_GET_FUN(__glewTextureFogSGIX) + +#define GLEW_SGIX_fog_texture GLEW_GET_VAR(__GLEW_SGIX_fog_texture) + +#endif /* GL_SGIX_fog_texture */ + +#if 0 +/* ------------------- GL_SGIX_fragment_specular_lighting ------------------ */ + +#ifndef GL_SGIX_fragment_specular_lighting +#define GL_SGIX_fragment_specular_lighting 1 + +typedef void (GLAPIENTRY * PFNGLFRAGMENTCOLORMATERIALSGIXPROC) (GLenum face, GLenum mode); +typedef void (GLAPIENTRY * PFNGLFRAGMENTLIGHTMODELFSGIXPROC) (GLenum pname, GLfloat param); +typedef void (GLAPIENTRY * PFNGLFRAGMENTLIGHTMODELFVSGIXPROC) (GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLFRAGMENTLIGHTMODELISGIXPROC) (GLenum pname, GLint param); +typedef void (GLAPIENTRY * PFNGLFRAGMENTLIGHTMODELIVSGIXPROC) (GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLFRAGMENTLIGHTFSGIXPROC) (GLenum light, GLenum pname, GLfloat param); +typedef void (GLAPIENTRY * PFNGLFRAGMENTLIGHTFVSGIXPROC) (GLenum light, GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLFRAGMENTLIGHTISGIXPROC) (GLenum light, GLenum pname, const GLint param); +typedef void (GLAPIENTRY * PFNGLFRAGMENTLIGHTIVSGIXPROC) (GLenum light, GLenum pname, const GLint* params); +typedef void (GLAPIENTRY * PFNGLFRAGMENTMATERIALFSGIXPROC) (GLenum face, GLenum pname, const GLfloat param); +typedef void (GLAPIENTRY * PFNGLFRAGMENTMATERIALFVSGIXPROC) (GLenum face, GLenum pname, const GLfloat* params); +typedef void (GLAPIENTRY * PFNGLFRAGMENTMATERIALISGIXPROC) (GLenum face, GLenum pname, const GLint param); +typedef void (GLAPIENTRY * PFNGLFRAGMENTMATERIALIVSGIXPROC) (GLenum face, GLenum pname, const GLint* params); +typedef void (GLAPIENTRY * PFNGLGETFRAGMENTLIGHTFVSGIXPROC) (GLenum light, GLenum value, const GLfloat* data); +typedef void (GLAPIENTRY * PFNGLGETFRAGMENTLIGHTIVSGIXPROC) (GLenum light, GLenum value, const GLint* data); +typedef void (GLAPIENTRY * PFNGLGETFRAGMENTMATERIALFVSGIXPROC) (GLenum face, GLenum pname, const GLfloat* data); +typedef void (GLAPIENTRY * PFNGLGETFRAGMENTMATERIALIVSGIXPROC) (GLenum face, GLenum pname, const GLint* data); + +#define glFragmentColorMaterialSGIX GLEW_GET_FUN(__glewFragmentColorMaterialSGIX) +#define glFragmentLightModelfSGIX GLEW_GET_FUN(__glewFragmentLightModelfSGIX) +#define glFragmentLightModelfvSGIX GLEW_GET_FUN(__glewFragmentLightModelfvSGIX) +#define glFragmentLightModeliSGIX GLEW_GET_FUN(__glewFragmentLightModeliSGIX) +#define glFragmentLightModelivSGIX GLEW_GET_FUN(__glewFragmentLightModelivSGIX) +#define glFragmentLightfSGIX GLEW_GET_FUN(__glewFragmentLightfSGIX) +#define glFragmentLightfvSGIX GLEW_GET_FUN(__glewFragmentLightfvSGIX) +#define glFragmentLightiSGIX GLEW_GET_FUN(__glewFragmentLightiSGIX) +#define glFragmentLightivSGIX GLEW_GET_FUN(__glewFragmentLightivSGIX) +#define glFragmentMaterialfSGIX GLEW_GET_FUN(__glewFragmentMaterialfSGIX) +#define glFragmentMaterialfvSGIX GLEW_GET_FUN(__glewFragmentMaterialfvSGIX) +#define glFragmentMaterialiSGIX GLEW_GET_FUN(__glewFragmentMaterialiSGIX) +#define glFragmentMaterialivSGIX GLEW_GET_FUN(__glewFragmentMaterialivSGIX) +#define glGetFragmentLightfvSGIX GLEW_GET_FUN(__glewGetFragmentLightfvSGIX) +#define glGetFragmentLightivSGIX GLEW_GET_FUN(__glewGetFragmentLightivSGIX) +#define glGetFragmentMaterialfvSGIX GLEW_GET_FUN(__glewGetFragmentMaterialfvSGIX) +#define glGetFragmentMaterialivSGIX GLEW_GET_FUN(__glewGetFragmentMaterialivSGIX) + +#define GLEW_SGIX_fragment_specular_lighting GLEW_GET_VAR(__GLEW_SGIX_fragment_specular_lighting) +#endif + +#endif /* GL_SGIX_fragment_specular_lighting */ + +/* --------------------------- GL_SGIX_framezoom --------------------------- */ + +#ifndef GL_SGIX_framezoom +#define GL_SGIX_framezoom 1 + +typedef void (GLAPIENTRY * PFNGLFRAMEZOOMSGIXPROC) (GLint factor); + +#define glFrameZoomSGIX GLEW_GET_FUN(__glewFrameZoomSGIX) + +#define GLEW_SGIX_framezoom GLEW_GET_VAR(__GLEW_SGIX_framezoom) + +#endif /* GL_SGIX_framezoom */ + +/* --------------------------- GL_SGIX_interlace --------------------------- */ + +#ifndef GL_SGIX_interlace +#define GL_SGIX_interlace 1 + +#define GL_INTERLACE_SGIX 0x8094 + +#define GLEW_SGIX_interlace GLEW_GET_VAR(__GLEW_SGIX_interlace) + +#endif /* GL_SGIX_interlace */ + +/* ------------------------- GL_SGIX_ir_instrument1 ------------------------ */ + +#ifndef GL_SGIX_ir_instrument1 +#define GL_SGIX_ir_instrument1 1 + +#define GLEW_SGIX_ir_instrument1 GLEW_GET_VAR(__GLEW_SGIX_ir_instrument1) + +#endif /* GL_SGIX_ir_instrument1 */ + +/* ------------------------- GL_SGIX_list_priority ------------------------- */ + +#ifndef GL_SGIX_list_priority +#define GL_SGIX_list_priority 1 + +#define GLEW_SGIX_list_priority GLEW_GET_VAR(__GLEW_SGIX_list_priority) + +#endif /* GL_SGIX_list_priority */ + +/* ------------------------- GL_SGIX_pixel_texture ------------------------- */ + +#ifndef GL_SGIX_pixel_texture +#define GL_SGIX_pixel_texture 1 + +typedef void (GLAPIENTRY * PFNGLPIXELTEXGENSGIXPROC) (GLenum mode); + +#define glPixelTexGenSGIX GLEW_GET_FUN(__glewPixelTexGenSGIX) + +#define GLEW_SGIX_pixel_texture GLEW_GET_VAR(__GLEW_SGIX_pixel_texture) + +#endif /* GL_SGIX_pixel_texture */ + +/* ----------------------- GL_SGIX_pixel_texture_bits ---------------------- */ + +#ifndef GL_SGIX_pixel_texture_bits +#define GL_SGIX_pixel_texture_bits 1 + +#define GLEW_SGIX_pixel_texture_bits GLEW_GET_VAR(__GLEW_SGIX_pixel_texture_bits) + +#endif /* GL_SGIX_pixel_texture_bits */ + +/* ------------------------ GL_SGIX_reference_plane ------------------------ */ + +#ifndef GL_SGIX_reference_plane +#define GL_SGIX_reference_plane 1 + +typedef void (GLAPIENTRY * PFNGLREFERENCEPLANESGIXPROC) (const GLdouble* equation); + +#define glReferencePlaneSGIX GLEW_GET_FUN(__glewReferencePlaneSGIX) + +#define GLEW_SGIX_reference_plane GLEW_GET_VAR(__GLEW_SGIX_reference_plane) + +#endif /* GL_SGIX_reference_plane */ + +/* ---------------------------- GL_SGIX_resample --------------------------- */ + +#ifndef GL_SGIX_resample +#define GL_SGIX_resample 1 + +#define GL_PACK_RESAMPLE_SGIX 0x842E +#define GL_UNPACK_RESAMPLE_SGIX 0x842F +#define GL_RESAMPLE_DECIMATE_SGIX 0x8430 +#define GL_RESAMPLE_REPLICATE_SGIX 0x8433 +#define GL_RESAMPLE_ZERO_FILL_SGIX 0x8434 + +#define GLEW_SGIX_resample GLEW_GET_VAR(__GLEW_SGIX_resample) + +#endif /* GL_SGIX_resample */ + +/* ----------------------------- GL_SGIX_shadow ---------------------------- */ + +#ifndef GL_SGIX_shadow +#define GL_SGIX_shadow 1 + +#define GL_TEXTURE_COMPARE_SGIX 0x819A +#define GL_TEXTURE_COMPARE_OPERATOR_SGIX 0x819B +#define GL_TEXTURE_LEQUAL_R_SGIX 0x819C +#define GL_TEXTURE_GEQUAL_R_SGIX 0x819D + +#define GLEW_SGIX_shadow GLEW_GET_VAR(__GLEW_SGIX_shadow) + +#endif /* GL_SGIX_shadow */ + +/* ------------------------- GL_SGIX_shadow_ambient ------------------------ */ + +#ifndef GL_SGIX_shadow_ambient +#define GL_SGIX_shadow_ambient 1 + +#define GL_SHADOW_AMBIENT_SGIX 0x80BF + +#define GLEW_SGIX_shadow_ambient GLEW_GET_VAR(__GLEW_SGIX_shadow_ambient) + +#endif /* GL_SGIX_shadow_ambient */ + +/* ----------------------------- GL_SGIX_sprite ---------------------------- */ + +#ifndef GL_SGIX_sprite +#define GL_SGIX_sprite 1 + +typedef void (GLAPIENTRY * PFNGLSPRITEPARAMETERFSGIXPROC) (GLenum pname, GLfloat param); +typedef void (GLAPIENTRY * PFNGLSPRITEPARAMETERFVSGIXPROC) (GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLSPRITEPARAMETERISGIXPROC) (GLenum pname, GLint param); +typedef void (GLAPIENTRY * PFNGLSPRITEPARAMETERIVSGIXPROC) (GLenum pname, GLint* params); + +#define glSpriteParameterfSGIX GLEW_GET_FUN(__glewSpriteParameterfSGIX) +#define glSpriteParameterfvSGIX GLEW_GET_FUN(__glewSpriteParameterfvSGIX) +#define glSpriteParameteriSGIX GLEW_GET_FUN(__glewSpriteParameteriSGIX) +#define glSpriteParameterivSGIX GLEW_GET_FUN(__glewSpriteParameterivSGIX) + +#define GLEW_SGIX_sprite GLEW_GET_VAR(__GLEW_SGIX_sprite) + +#endif /* GL_SGIX_sprite */ + +/* ----------------------- GL_SGIX_tag_sample_buffer ----------------------- */ + +#ifndef GL_SGIX_tag_sample_buffer +#define GL_SGIX_tag_sample_buffer 1 + +typedef void (GLAPIENTRY * PFNGLTAGSAMPLEBUFFERSGIXPROC) (void); + +#define glTagSampleBufferSGIX GLEW_GET_FUN(__glewTagSampleBufferSGIX) + +#define GLEW_SGIX_tag_sample_buffer GLEW_GET_VAR(__GLEW_SGIX_tag_sample_buffer) + +#endif /* GL_SGIX_tag_sample_buffer */ + +/* ------------------------ GL_SGIX_texture_add_env ------------------------ */ + +#ifndef GL_SGIX_texture_add_env +#define GL_SGIX_texture_add_env 1 + +#define GLEW_SGIX_texture_add_env GLEW_GET_VAR(__GLEW_SGIX_texture_add_env) + +#endif /* GL_SGIX_texture_add_env */ + +/* -------------------- GL_SGIX_texture_coordinate_clamp ------------------- */ + +#ifndef GL_SGIX_texture_coordinate_clamp +#define GL_SGIX_texture_coordinate_clamp 1 + +#define GL_TEXTURE_MAX_CLAMP_S_SGIX 0x8369 +#define GL_TEXTURE_MAX_CLAMP_T_SGIX 0x836A +#define GL_TEXTURE_MAX_CLAMP_R_SGIX 0x836B + +#define GLEW_SGIX_texture_coordinate_clamp GLEW_GET_VAR(__GLEW_SGIX_texture_coordinate_clamp) + +#endif /* GL_SGIX_texture_coordinate_clamp */ + +/* ------------------------ GL_SGIX_texture_lod_bias ----------------------- */ + +#ifndef GL_SGIX_texture_lod_bias +#define GL_SGIX_texture_lod_bias 1 + +#define GLEW_SGIX_texture_lod_bias GLEW_GET_VAR(__GLEW_SGIX_texture_lod_bias) + +#endif /* GL_SGIX_texture_lod_bias */ + +/* ---------------------- GL_SGIX_texture_multi_buffer --------------------- */ + +#ifndef GL_SGIX_texture_multi_buffer +#define GL_SGIX_texture_multi_buffer 1 + +#define GL_TEXTURE_MULTI_BUFFER_HINT_SGIX 0x812E + +#define GLEW_SGIX_texture_multi_buffer GLEW_GET_VAR(__GLEW_SGIX_texture_multi_buffer) + +#endif /* GL_SGIX_texture_multi_buffer */ + +/* ------------------------- GL_SGIX_texture_range ------------------------- */ + +#ifndef GL_SGIX_texture_range +#define GL_SGIX_texture_range 1 + +#define GL_RGB_SIGNED_SGIX 0x85E0 +#define GL_RGBA_SIGNED_SGIX 0x85E1 +#define GL_ALPHA_SIGNED_SGIX 0x85E2 +#define GL_LUMINANCE_SIGNED_SGIX 0x85E3 +#define GL_INTENSITY_SIGNED_SGIX 0x85E4 +#define GL_LUMINANCE_ALPHA_SIGNED_SGIX 0x85E5 +#define GL_RGB16_SIGNED_SGIX 0x85E6 +#define GL_RGBA16_SIGNED_SGIX 0x85E7 +#define GL_ALPHA16_SIGNED_SGIX 0x85E8 +#define GL_LUMINANCE16_SIGNED_SGIX 0x85E9 +#define GL_INTENSITY16_SIGNED_SGIX 0x85EA +#define GL_LUMINANCE16_ALPHA16_SIGNED_SGIX 0x85EB +#define GL_RGB_EXTENDED_RANGE_SGIX 0x85EC +#define GL_RGBA_EXTENDED_RANGE_SGIX 0x85ED +#define GL_ALPHA_EXTENDED_RANGE_SGIX 0x85EE +#define GL_LUMINANCE_EXTENDED_RANGE_SGIX 0x85EF +#define GL_INTENSITY_EXTENDED_RANGE_SGIX 0x85F0 +#define GL_LUMINANCE_ALPHA_EXTENDED_RANGE_SGIX 0x85F1 +#define GL_RGB16_EXTENDED_RANGE_SGIX 0x85F2 +#define GL_RGBA16_EXTENDED_RANGE_SGIX 0x85F3 +#define GL_ALPHA16_EXTENDED_RANGE_SGIX 0x85F4 +#define GL_LUMINANCE16_EXTENDED_RANGE_SGIX 0x85F5 +#define GL_INTENSITY16_EXTENDED_RANGE_SGIX 0x85F6 +#define GL_LUMINANCE16_ALPHA16_EXTENDED_RANGE_SGIX 0x85F7 +#define GL_MIN_LUMINANCE_SGIS 0x85F8 +#define GL_MAX_LUMINANCE_SGIS 0x85F9 +#define GL_MIN_INTENSITY_SGIS 0x85FA +#define GL_MAX_INTENSITY_SGIS 0x85FB + +#define GLEW_SGIX_texture_range GLEW_GET_VAR(__GLEW_SGIX_texture_range) + +#endif /* GL_SGIX_texture_range */ + +/* ----------------------- GL_SGIX_texture_scale_bias ---------------------- */ + +#ifndef GL_SGIX_texture_scale_bias +#define GL_SGIX_texture_scale_bias 1 + +#define GL_POST_TEXTURE_FILTER_BIAS_SGIX 0x8179 +#define GL_POST_TEXTURE_FILTER_SCALE_SGIX 0x817A +#define GL_POST_TEXTURE_FILTER_BIAS_RANGE_SGIX 0x817B +#define GL_POST_TEXTURE_FILTER_SCALE_RANGE_SGIX 0x817C + +#define GLEW_SGIX_texture_scale_bias GLEW_GET_VAR(__GLEW_SGIX_texture_scale_bias) + +#endif /* GL_SGIX_texture_scale_bias */ + +/* ------------------------- GL_SGIX_vertex_preclip ------------------------ */ + +#ifndef GL_SGIX_vertex_preclip +#define GL_SGIX_vertex_preclip 1 + +#define GL_VERTEX_PRECLIP_SGIX 0x83EE +#define GL_VERTEX_PRECLIP_HINT_SGIX 0x83EF + +#define GLEW_SGIX_vertex_preclip GLEW_GET_VAR(__GLEW_SGIX_vertex_preclip) + +#endif /* GL_SGIX_vertex_preclip */ + +/* ---------------------- GL_SGIX_vertex_preclip_hint ---------------------- */ + +#ifndef GL_SGIX_vertex_preclip_hint +#define GL_SGIX_vertex_preclip_hint 1 + +#define GL_VERTEX_PRECLIP_SGIX 0x83EE +#define GL_VERTEX_PRECLIP_HINT_SGIX 0x83EF + +#define GLEW_SGIX_vertex_preclip_hint GLEW_GET_VAR(__GLEW_SGIX_vertex_preclip_hint) + +#endif /* GL_SGIX_vertex_preclip_hint */ + +/* ----------------------------- GL_SGIX_ycrcb ----------------------------- */ + +#ifndef GL_SGIX_ycrcb +#define GL_SGIX_ycrcb 1 + +#define GLEW_SGIX_ycrcb GLEW_GET_VAR(__GLEW_SGIX_ycrcb) + +#endif /* GL_SGIX_ycrcb */ + +/* -------------------------- GL_SGI_color_matrix -------------------------- */ + +#ifndef GL_SGI_color_matrix +#define GL_SGI_color_matrix 1 + +#define GL_COLOR_MATRIX_SGI 0x80B1 +#define GL_COLOR_MATRIX_STACK_DEPTH_SGI 0x80B2 +#define GL_MAX_COLOR_MATRIX_STACK_DEPTH_SGI 0x80B3 +#define GL_POST_COLOR_MATRIX_RED_SCALE_SGI 0x80B4 +#define GL_POST_COLOR_MATRIX_GREEN_SCALE_SGI 0x80B5 +#define GL_POST_COLOR_MATRIX_BLUE_SCALE_SGI 0x80B6 +#define GL_POST_COLOR_MATRIX_ALPHA_SCALE_SGI 0x80B7 +#define GL_POST_COLOR_MATRIX_RED_BIAS_SGI 0x80B8 +#define GL_POST_COLOR_MATRIX_GREEN_BIAS_SGI 0x80B9 +#define GL_POST_COLOR_MATRIX_BLUE_BIAS_SGI 0x80BA +#define GL_POST_COLOR_MATRIX_ALPHA_BIAS_SGI 0x80BB + +#define GLEW_SGI_color_matrix GLEW_GET_VAR(__GLEW_SGI_color_matrix) + +#endif /* GL_SGI_color_matrix */ + +/* --------------------------- GL_SGI_color_table -------------------------- */ + +#ifndef GL_SGI_color_table +#define GL_SGI_color_table 1 + +#define GL_COLOR_TABLE_SGI 0x80D0 +#define GL_POST_CONVOLUTION_COLOR_TABLE_SGI 0x80D1 +#define GL_POST_COLOR_MATRIX_COLOR_TABLE_SGI 0x80D2 +#define GL_PROXY_COLOR_TABLE_SGI 0x80D3 +#define GL_PROXY_POST_CONVOLUTION_COLOR_TABLE_SGI 0x80D4 +#define GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE_SGI 0x80D5 +#define GL_COLOR_TABLE_SCALE_SGI 0x80D6 +#define GL_COLOR_TABLE_BIAS_SGI 0x80D7 +#define GL_COLOR_TABLE_FORMAT_SGI 0x80D8 +#define GL_COLOR_TABLE_WIDTH_SGI 0x80D9 +#define GL_COLOR_TABLE_RED_SIZE_SGI 0x80DA +#define GL_COLOR_TABLE_GREEN_SIZE_SGI 0x80DB +#define GL_COLOR_TABLE_BLUE_SIZE_SGI 0x80DC +#define GL_COLOR_TABLE_ALPHA_SIZE_SGI 0x80DD +#define GL_COLOR_TABLE_LUMINANCE_SIZE_SGI 0x80DE +#define GL_COLOR_TABLE_INTENSITY_SIZE_SGI 0x80DF + +typedef void (GLAPIENTRY * PFNGLCOLORTABLEPARAMETERFVSGIPROC) (GLenum target, GLenum pname, const GLfloat* params); +typedef void (GLAPIENTRY * PFNGLCOLORTABLEPARAMETERIVSGIPROC) (GLenum target, GLenum pname, const GLint* params); +typedef void (GLAPIENTRY * PFNGLCOLORTABLESGIPROC) (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const void* table); +typedef void (GLAPIENTRY * PFNGLCOPYCOLORTABLESGIPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); +typedef void (GLAPIENTRY * PFNGLGETCOLORTABLEPARAMETERFVSGIPROC) (GLenum target, GLenum pname, GLfloat* params); +typedef void (GLAPIENTRY * PFNGLGETCOLORTABLEPARAMETERIVSGIPROC) (GLenum target, GLenum pname, GLint* params); +typedef void (GLAPIENTRY * PFNGLGETCOLORTABLESGIPROC) (GLenum target, GLenum format, GLenum type, void* table); + +#define glColorTableParameterfvSGI GLEW_GET_FUN(__glewColorTableParameterfvSGI) +#define glColorTableParameterivSGI GLEW_GET_FUN(__glewColorTableParameterivSGI) +#define glColorTableSGI GLEW_GET_FUN(__glewColorTableSGI) +#define glCopyColorTableSGI GLEW_GET_FUN(__glewCopyColorTableSGI) +#define glGetColorTableParameterfvSGI GLEW_GET_FUN(__glewGetColorTableParameterfvSGI) +#define glGetColorTableParameterivSGI GLEW_GET_FUN(__glewGetColorTableParameterivSGI) +#define glGetColorTableSGI GLEW_GET_FUN(__glewGetColorTableSGI) + +#define GLEW_SGI_color_table GLEW_GET_VAR(__GLEW_SGI_color_table) + +#endif /* GL_SGI_color_table */ + +/* ----------------------- GL_SGI_texture_color_table ---------------------- */ + +#ifndef GL_SGI_texture_color_table +#define GL_SGI_texture_color_table 1 + +#define GL_TEXTURE_COLOR_TABLE_SGI 0x80BC +#define GL_PROXY_TEXTURE_COLOR_TABLE_SGI 0x80BD + +#define GLEW_SGI_texture_color_table GLEW_GET_VAR(__GLEW_SGI_texture_color_table) + +#endif /* GL_SGI_texture_color_table */ + +/* ------------------------- GL_SUNX_constant_data ------------------------- */ + +#ifndef GL_SUNX_constant_data +#define GL_SUNX_constant_data 1 + +#define GL_UNPACK_CONSTANT_DATA_SUNX 0x81D5 +#define GL_TEXTURE_CONSTANT_DATA_SUNX 0x81D6 + +typedef void (GLAPIENTRY * PFNGLFINISHTEXTURESUNXPROC) (void); + +#define glFinishTextureSUNX GLEW_GET_FUN(__glewFinishTextureSUNX) + +#define GLEW_SUNX_constant_data GLEW_GET_VAR(__GLEW_SUNX_constant_data) + +#endif /* GL_SUNX_constant_data */ + +/* -------------------- GL_SUN_convolution_border_modes -------------------- */ + +#ifndef GL_SUN_convolution_border_modes +#define GL_SUN_convolution_border_modes 1 + +#define GL_WRAP_BORDER_SUN 0x81D4 + +#define GLEW_SUN_convolution_border_modes GLEW_GET_VAR(__GLEW_SUN_convolution_border_modes) + +#endif /* GL_SUN_convolution_border_modes */ + +/* -------------------------- GL_SUN_global_alpha -------------------------- */ + +#ifndef GL_SUN_global_alpha +#define GL_SUN_global_alpha 1 + +#define GL_GLOBAL_ALPHA_SUN 0x81D9 +#define GL_GLOBAL_ALPHA_FACTOR_SUN 0x81DA + +typedef void (GLAPIENTRY * PFNGLGLOBALALPHAFACTORBSUNPROC) (GLbyte factor); +typedef void (GLAPIENTRY * PFNGLGLOBALALPHAFACTORDSUNPROC) (GLdouble factor); +typedef void (GLAPIENTRY * PFNGLGLOBALALPHAFACTORFSUNPROC) (GLfloat factor); +typedef void (GLAPIENTRY * PFNGLGLOBALALPHAFACTORISUNPROC) (GLint factor); +typedef void (GLAPIENTRY * PFNGLGLOBALALPHAFACTORSSUNPROC) (GLshort factor); +typedef void (GLAPIENTRY * PFNGLGLOBALALPHAFACTORUBSUNPROC) (GLubyte factor); +typedef void (GLAPIENTRY * PFNGLGLOBALALPHAFACTORUISUNPROC) (GLuint factor); +typedef void (GLAPIENTRY * PFNGLGLOBALALPHAFACTORUSSUNPROC) (GLushort factor); + +#define glGlobalAlphaFactorbSUN GLEW_GET_FUN(__glewGlobalAlphaFactorbSUN) +#define glGlobalAlphaFactordSUN GLEW_GET_FUN(__glewGlobalAlphaFactordSUN) +#define glGlobalAlphaFactorfSUN GLEW_GET_FUN(__glewGlobalAlphaFactorfSUN) +#define glGlobalAlphaFactoriSUN GLEW_GET_FUN(__glewGlobalAlphaFactoriSUN) +#define glGlobalAlphaFactorsSUN GLEW_GET_FUN(__glewGlobalAlphaFactorsSUN) +#define glGlobalAlphaFactorubSUN GLEW_GET_FUN(__glewGlobalAlphaFactorubSUN) +#define glGlobalAlphaFactoruiSUN GLEW_GET_FUN(__glewGlobalAlphaFactoruiSUN) +#define glGlobalAlphaFactorusSUN GLEW_GET_FUN(__glewGlobalAlphaFactorusSUN) + +#define GLEW_SUN_global_alpha GLEW_GET_VAR(__GLEW_SUN_global_alpha) + +#endif /* GL_SUN_global_alpha */ + +/* --------------------------- GL_SUN_mesh_array --------------------------- */ + +#ifndef GL_SUN_mesh_array +#define GL_SUN_mesh_array 1 + +#define GL_QUAD_MESH_SUN 0x8614 +#define GL_TRIANGLE_MESH_SUN 0x8615 + +#define GLEW_SUN_mesh_array GLEW_GET_VAR(__GLEW_SUN_mesh_array) + +#endif /* GL_SUN_mesh_array */ + +/* ------------------------ GL_SUN_read_video_pixels ----------------------- */ + +#ifndef GL_SUN_read_video_pixels +#define GL_SUN_read_video_pixels 1 + +typedef void (GLAPIENTRY * PFNGLREADVIDEOPIXELSSUNPROC) (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels); + +#define glReadVideoPixelsSUN GLEW_GET_FUN(__glewReadVideoPixelsSUN) + +#define GLEW_SUN_read_video_pixels GLEW_GET_VAR(__GLEW_SUN_read_video_pixels) + +#endif /* GL_SUN_read_video_pixels */ + +/* --------------------------- GL_SUN_slice_accum -------------------------- */ + +#ifndef GL_SUN_slice_accum +#define GL_SUN_slice_accum 1 + +#define GL_SLICE_ACCUM_SUN 0x85CC + +#define GLEW_SUN_slice_accum GLEW_GET_VAR(__GLEW_SUN_slice_accum) + +#endif /* GL_SUN_slice_accum */ + +/* -------------------------- GL_SUN_triangle_list ------------------------- */ + +#ifndef GL_SUN_triangle_list +#define GL_SUN_triangle_list 1 + +#define GL_RESTART_SUN 0x01 +#define GL_REPLACE_MIDDLE_SUN 0x02 +#define GL_REPLACE_OLDEST_SUN 0x03 +#define GL_TRIANGLE_LIST_SUN 0x81D7 +#define GL_REPLACEMENT_CODE_SUN 0x81D8 +#define GL_REPLACEMENT_CODE_ARRAY_SUN 0x85C0 +#define GL_REPLACEMENT_CODE_ARRAY_TYPE_SUN 0x85C1 +#define GL_REPLACEMENT_CODE_ARRAY_STRIDE_SUN 0x85C2 +#define GL_REPLACEMENT_CODE_ARRAY_POINTER_SUN 0x85C3 +#define GL_R1UI_V3F_SUN 0x85C4 +#define GL_R1UI_C4UB_V3F_SUN 0x85C5 +#define GL_R1UI_C3F_V3F_SUN 0x85C6 +#define GL_R1UI_N3F_V3F_SUN 0x85C7 +#define GL_R1UI_C4F_N3F_V3F_SUN 0x85C8 +#define GL_R1UI_T2F_V3F_SUN 0x85C9 +#define GL_R1UI_T2F_N3F_V3F_SUN 0x85CA +#define GL_R1UI_T2F_C4F_N3F_V3F_SUN 0x85CB + +typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEPOINTERSUNPROC) (GLenum type, GLsizei stride, const void* pointer); +typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUBSUNPROC) (GLubyte code); +typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUBVSUNPROC) (const GLubyte* code); +typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUISUNPROC) (GLuint code); +typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUIVSUNPROC) (const GLuint* code); +typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUSSUNPROC) (GLushort code); +typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUSVSUNPROC) (const GLushort* code); + +#define glReplacementCodePointerSUN GLEW_GET_FUN(__glewReplacementCodePointerSUN) +#define glReplacementCodeubSUN GLEW_GET_FUN(__glewReplacementCodeubSUN) +#define glReplacementCodeubvSUN GLEW_GET_FUN(__glewReplacementCodeubvSUN) +#define glReplacementCodeuiSUN GLEW_GET_FUN(__glewReplacementCodeuiSUN) +#define glReplacementCodeuivSUN GLEW_GET_FUN(__glewReplacementCodeuivSUN) +#define glReplacementCodeusSUN GLEW_GET_FUN(__glewReplacementCodeusSUN) +#define glReplacementCodeusvSUN GLEW_GET_FUN(__glewReplacementCodeusvSUN) + +#define GLEW_SUN_triangle_list GLEW_GET_VAR(__GLEW_SUN_triangle_list) + +#endif /* GL_SUN_triangle_list */ + +/* ----------------------------- GL_SUN_vertex ----------------------------- */ + +#ifndef GL_SUN_vertex +#define GL_SUN_vertex 1 + +typedef void (GLAPIENTRY * PFNGLCOLOR3FVERTEX3FSUNPROC) (GLfloat r, GLfloat g, GLfloat b, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLCOLOR3FVERTEX3FVSUNPROC) (const GLfloat* c, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLCOLOR4FNORMAL3FVERTEX3FSUNPROC) (GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLCOLOR4FNORMAL3FVERTEX3FVSUNPROC) (const GLfloat* c, const GLfloat *n, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLCOLOR4UBVERTEX2FSUNPROC) (GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y); +typedef void (GLAPIENTRY * PFNGLCOLOR4UBVERTEX2FVSUNPROC) (const GLubyte* c, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLCOLOR4UBVERTEX3FSUNPROC) (GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLCOLOR4UBVERTEX3FVSUNPROC) (const GLubyte* c, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLNORMAL3FVERTEX3FSUNPROC) (GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLNORMAL3FVERTEX3FVSUNPROC) (const GLfloat* n, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUICOLOR3FVERTEX3FSUNPROC) (GLuint rc, GLfloat r, GLfloat g, GLfloat b, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUICOLOR3FVERTEX3FVSUNPROC) (const GLuint* rc, const GLfloat *c, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUICOLOR4FNORMAL3FVERTEX3FSUNPROC) (GLuint rc, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUICOLOR4FNORMAL3FVERTEX3FVSUNPROC) (const GLuint* rc, const GLfloat *c, const GLfloat *n, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUICOLOR4UBVERTEX3FSUNPROC) (GLuint rc, GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUICOLOR4UBVERTEX3FVSUNPROC) (const GLuint* rc, const GLubyte *c, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUINORMAL3FVERTEX3FSUNPROC) (GLuint rc, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUINORMAL3FVERTEX3FVSUNPROC) (const GLuint* rc, const GLfloat *n, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUITEXCOORD2FCOLOR4FNORMAL3FVERTEX3FSUNPROC) (GLuint rc, GLfloat s, GLfloat t, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUITEXCOORD2FCOLOR4FNORMAL3FVERTEX3FVSUNPROC) (const GLuint* rc, const GLfloat *tc, const GLfloat *c, const GLfloat *n, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUITEXCOORD2FNORMAL3FVERTEX3FSUNPROC) (GLuint rc, GLfloat s, GLfloat t, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUITEXCOORD2FNORMAL3FVERTEX3FVSUNPROC) (const GLuint* rc, const GLfloat *tc, const GLfloat *n, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUITEXCOORD2FVERTEX3FSUNPROC) (GLuint rc, GLfloat s, GLfloat t, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUITEXCOORD2FVERTEX3FVSUNPROC) (const GLuint* rc, const GLfloat *tc, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUIVERTEX3FSUNPROC) (GLuint rc, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUIVERTEX3FVSUNPROC) (const GLuint* rc, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLTEXCOORD2FCOLOR3FVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLfloat r, GLfloat g, GLfloat b, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLTEXCOORD2FCOLOR3FVERTEX3FVSUNPROC) (const GLfloat* tc, const GLfloat *c, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLTEXCOORD2FCOLOR4FNORMAL3FVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLTEXCOORD2FCOLOR4FNORMAL3FVERTEX3FVSUNPROC) (const GLfloat* tc, const GLfloat *c, const GLfloat *n, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLTEXCOORD2FCOLOR4UBVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLTEXCOORD2FCOLOR4UBVERTEX3FVSUNPROC) (const GLfloat* tc, const GLubyte *c, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLTEXCOORD2FNORMAL3FVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLTEXCOORD2FNORMAL3FVERTEX3FVSUNPROC) (const GLfloat* tc, const GLfloat *n, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLTEXCOORD2FVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLTEXCOORD2FVERTEX3FVSUNPROC) (const GLfloat* tc, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLTEXCOORD4FCOLOR4FNORMAL3FVERTEX4FSUNPROC) (GLfloat s, GLfloat t, GLfloat p, GLfloat q, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (GLAPIENTRY * PFNGLTEXCOORD4FCOLOR4FNORMAL3FVERTEX4FVSUNPROC) (const GLfloat* tc, const GLfloat *c, const GLfloat *n, const GLfloat *v); +typedef void (GLAPIENTRY * PFNGLTEXCOORD4FVERTEX4FSUNPROC) (GLfloat s, GLfloat t, GLfloat p, GLfloat q, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (GLAPIENTRY * PFNGLTEXCOORD4FVERTEX4FVSUNPROC) (const GLfloat* tc, const GLfloat *v); + +#define glColor3fVertex3fSUN GLEW_GET_FUN(__glewColor3fVertex3fSUN) +#define glColor3fVertex3fvSUN GLEW_GET_FUN(__glewColor3fVertex3fvSUN) +#define glColor4fNormal3fVertex3fSUN GLEW_GET_FUN(__glewColor4fNormal3fVertex3fSUN) +#define glColor4fNormal3fVertex3fvSUN GLEW_GET_FUN(__glewColor4fNormal3fVertex3fvSUN) +#define glColor4ubVertex2fSUN GLEW_GET_FUN(__glewColor4ubVertex2fSUN) +#define glColor4ubVertex2fvSUN GLEW_GET_FUN(__glewColor4ubVertex2fvSUN) +#define glColor4ubVertex3fSUN GLEW_GET_FUN(__glewColor4ubVertex3fSUN) +#define glColor4ubVertex3fvSUN GLEW_GET_FUN(__glewColor4ubVertex3fvSUN) +#define glNormal3fVertex3fSUN GLEW_GET_FUN(__glewNormal3fVertex3fSUN) +#define glNormal3fVertex3fvSUN GLEW_GET_FUN(__glewNormal3fVertex3fvSUN) +#define glReplacementCodeuiColor3fVertex3fSUN GLEW_GET_FUN(__glewReplacementCodeuiColor3fVertex3fSUN) +#define glReplacementCodeuiColor3fVertex3fvSUN GLEW_GET_FUN(__glewReplacementCodeuiColor3fVertex3fvSUN) +#define glReplacementCodeuiColor4fNormal3fVertex3fSUN GLEW_GET_FUN(__glewReplacementCodeuiColor4fNormal3fVertex3fSUN) +#define glReplacementCodeuiColor4fNormal3fVertex3fvSUN GLEW_GET_FUN(__glewReplacementCodeuiColor4fNormal3fVertex3fvSUN) +#define glReplacementCodeuiColor4ubVertex3fSUN GLEW_GET_FUN(__glewReplacementCodeuiColor4ubVertex3fSUN) +#define glReplacementCodeuiColor4ubVertex3fvSUN GLEW_GET_FUN(__glewReplacementCodeuiColor4ubVertex3fvSUN) +#define glReplacementCodeuiNormal3fVertex3fSUN GLEW_GET_FUN(__glewReplacementCodeuiNormal3fVertex3fSUN) +#define glReplacementCodeuiNormal3fVertex3fvSUN GLEW_GET_FUN(__glewReplacementCodeuiNormal3fVertex3fvSUN) +#define glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN GLEW_GET_FUN(__glewReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN) +#define glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN GLEW_GET_FUN(__glewReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN) +#define glReplacementCodeuiTexCoord2fNormal3fVertex3fSUN GLEW_GET_FUN(__glewReplacementCodeuiTexCoord2fNormal3fVertex3fSUN) +#define glReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN GLEW_GET_FUN(__glewReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN) +#define glReplacementCodeuiTexCoord2fVertex3fSUN GLEW_GET_FUN(__glewReplacementCodeuiTexCoord2fVertex3fSUN) +#define glReplacementCodeuiTexCoord2fVertex3fvSUN GLEW_GET_FUN(__glewReplacementCodeuiTexCoord2fVertex3fvSUN) +#define glReplacementCodeuiVertex3fSUN GLEW_GET_FUN(__glewReplacementCodeuiVertex3fSUN) +#define glReplacementCodeuiVertex3fvSUN GLEW_GET_FUN(__glewReplacementCodeuiVertex3fvSUN) +#define glTexCoord2fColor3fVertex3fSUN GLEW_GET_FUN(__glewTexCoord2fColor3fVertex3fSUN) +#define glTexCoord2fColor3fVertex3fvSUN GLEW_GET_FUN(__glewTexCoord2fColor3fVertex3fvSUN) +#define glTexCoord2fColor4fNormal3fVertex3fSUN GLEW_GET_FUN(__glewTexCoord2fColor4fNormal3fVertex3fSUN) +#define glTexCoord2fColor4fNormal3fVertex3fvSUN GLEW_GET_FUN(__glewTexCoord2fColor4fNormal3fVertex3fvSUN) +#define glTexCoord2fColor4ubVertex3fSUN GLEW_GET_FUN(__glewTexCoord2fColor4ubVertex3fSUN) +#define glTexCoord2fColor4ubVertex3fvSUN GLEW_GET_FUN(__glewTexCoord2fColor4ubVertex3fvSUN) +#define glTexCoord2fNormal3fVertex3fSUN GLEW_GET_FUN(__glewTexCoord2fNormal3fVertex3fSUN) +#define glTexCoord2fNormal3fVertex3fvSUN GLEW_GET_FUN(__glewTexCoord2fNormal3fVertex3fvSUN) +#define glTexCoord2fVertex3fSUN GLEW_GET_FUN(__glewTexCoord2fVertex3fSUN) +#define glTexCoord2fVertex3fvSUN GLEW_GET_FUN(__glewTexCoord2fVertex3fvSUN) +#define glTexCoord4fColor4fNormal3fVertex4fSUN GLEW_GET_FUN(__glewTexCoord4fColor4fNormal3fVertex4fSUN) +#define glTexCoord4fColor4fNormal3fVertex4fvSUN GLEW_GET_FUN(__glewTexCoord4fColor4fNormal3fVertex4fvSUN) +#define glTexCoord4fVertex4fSUN GLEW_GET_FUN(__glewTexCoord4fVertex4fSUN) +#define glTexCoord4fVertex4fvSUN GLEW_GET_FUN(__glewTexCoord4fVertex4fvSUN) + +#define GLEW_SUN_vertex GLEW_GET_VAR(__GLEW_SUN_vertex) + +#endif /* GL_SUN_vertex */ + +/* -------------------------- GL_WIN_phong_shading ------------------------- */ + +#ifndef GL_WIN_phong_shading +#define GL_WIN_phong_shading 1 + +#define GL_PHONG_WIN 0x80EA +#define GL_PHONG_HINT_WIN 0x80EB + +#define GLEW_WIN_phong_shading GLEW_GET_VAR(__GLEW_WIN_phong_shading) + +#endif /* GL_WIN_phong_shading */ + +/* -------------------------- GL_WIN_specular_fog -------------------------- */ + +#ifndef GL_WIN_specular_fog +#define GL_WIN_specular_fog 1 + +#define GL_FOG_SPECULAR_TEXTURE_WIN 0x80EC + +#define GLEW_WIN_specular_fog GLEW_GET_VAR(__GLEW_WIN_specular_fog) + +#endif /* GL_WIN_specular_fog */ + +/* ---------------------------- GL_WIN_swap_hint --------------------------- */ + +#ifndef GL_WIN_swap_hint +#define GL_WIN_swap_hint 1 + +typedef void (GLAPIENTRY * PFNGLADDSWAPHINTRECTWINPROC) (GLint x, GLint y, GLsizei width, GLsizei height); + +#define glAddSwapHintRectWIN GLEW_GET_FUN(__glewAddSwapHintRectWIN) + +#define GLEW_WIN_swap_hint GLEW_GET_VAR(__GLEW_WIN_swap_hint) + +#endif /* GL_WIN_swap_hint */ + +/* ------------------------------------------------------------------------- */ + +#if defined(GLEW_MX) && defined(_WIN32) +#define GLEW_FUN_EXPORT +#else +#define GLEW_FUN_EXPORT GLEWAPI +#endif /* GLEW_MX */ + +#if defined(GLEW_MX) +#define GLEW_VAR_EXPORT +#else +#define GLEW_VAR_EXPORT GLEWAPI +#endif /* GLEW_MX */ + +#if defined(GLEW_MX) && defined(_WIN32) +struct GLEWContextStruct +{ +#endif /* GLEW_MX */ + +GLEW_FUN_EXPORT PFNGLCOPYTEXSUBIMAGE3DPROC __glewCopyTexSubImage3D; +GLEW_FUN_EXPORT PFNGLDRAWRANGEELEMENTSPROC __glewDrawRangeElements; +GLEW_FUN_EXPORT PFNGLTEXIMAGE3DPROC __glewTexImage3D; +GLEW_FUN_EXPORT PFNGLTEXSUBIMAGE3DPROC __glewTexSubImage3D; + +GLEW_FUN_EXPORT PFNGLACTIVETEXTUREPROC __glewActiveTexture; +GLEW_FUN_EXPORT PFNGLCLIENTACTIVETEXTUREPROC __glewClientActiveTexture; +GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXIMAGE1DPROC __glewCompressedTexImage1D; +GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXIMAGE2DPROC __glewCompressedTexImage2D; +GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXIMAGE3DPROC __glewCompressedTexImage3D; +GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC __glewCompressedTexSubImage1D; +GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC __glewCompressedTexSubImage2D; +GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC __glewCompressedTexSubImage3D; +GLEW_FUN_EXPORT PFNGLGETCOMPRESSEDTEXIMAGEPROC __glewGetCompressedTexImage; +GLEW_FUN_EXPORT PFNGLLOADTRANSPOSEMATRIXDPROC __glewLoadTransposeMatrixd; +GLEW_FUN_EXPORT PFNGLLOADTRANSPOSEMATRIXFPROC __glewLoadTransposeMatrixf; +GLEW_FUN_EXPORT PFNGLMULTTRANSPOSEMATRIXDPROC __glewMultTransposeMatrixd; +GLEW_FUN_EXPORT PFNGLMULTTRANSPOSEMATRIXFPROC __glewMultTransposeMatrixf; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1DPROC __glewMultiTexCoord1d; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1DVPROC __glewMultiTexCoord1dv; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1FPROC __glewMultiTexCoord1f; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1FVPROC __glewMultiTexCoord1fv; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1IPROC __glewMultiTexCoord1i; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1IVPROC __glewMultiTexCoord1iv; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1SPROC __glewMultiTexCoord1s; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1SVPROC __glewMultiTexCoord1sv; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2DPROC __glewMultiTexCoord2d; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2DVPROC __glewMultiTexCoord2dv; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2FPROC __glewMultiTexCoord2f; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2FVPROC __glewMultiTexCoord2fv; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2IPROC __glewMultiTexCoord2i; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2IVPROC __glewMultiTexCoord2iv; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2SPROC __glewMultiTexCoord2s; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2SVPROC __glewMultiTexCoord2sv; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3DPROC __glewMultiTexCoord3d; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3DVPROC __glewMultiTexCoord3dv; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3FPROC __glewMultiTexCoord3f; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3FVPROC __glewMultiTexCoord3fv; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3IPROC __glewMultiTexCoord3i; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3IVPROC __glewMultiTexCoord3iv; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3SPROC __glewMultiTexCoord3s; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3SVPROC __glewMultiTexCoord3sv; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4DPROC __glewMultiTexCoord4d; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4DVPROC __glewMultiTexCoord4dv; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4FPROC __glewMultiTexCoord4f; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4FVPROC __glewMultiTexCoord4fv; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4IPROC __glewMultiTexCoord4i; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4IVPROC __glewMultiTexCoord4iv; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4SPROC __glewMultiTexCoord4s; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4SVPROC __glewMultiTexCoord4sv; +GLEW_FUN_EXPORT PFNGLSAMPLECOVERAGEPROC __glewSampleCoverage; + +GLEW_FUN_EXPORT PFNGLBLENDCOLORPROC __glewBlendColor; +GLEW_FUN_EXPORT PFNGLBLENDEQUATIONPROC __glewBlendEquation; +GLEW_FUN_EXPORT PFNGLBLENDFUNCSEPARATEPROC __glewBlendFuncSeparate; +GLEW_FUN_EXPORT PFNGLFOGCOORDPOINTERPROC __glewFogCoordPointer; +GLEW_FUN_EXPORT PFNGLFOGCOORDDPROC __glewFogCoordd; +GLEW_FUN_EXPORT PFNGLFOGCOORDDVPROC __glewFogCoorddv; +GLEW_FUN_EXPORT PFNGLFOGCOORDFPROC __glewFogCoordf; +GLEW_FUN_EXPORT PFNGLFOGCOORDFVPROC __glewFogCoordfv; +GLEW_FUN_EXPORT PFNGLMULTIDRAWARRAYSPROC __glewMultiDrawArrays; +GLEW_FUN_EXPORT PFNGLMULTIDRAWELEMENTSPROC __glewMultiDrawElements; +GLEW_FUN_EXPORT PFNGLPOINTPARAMETERFPROC __glewPointParameterf; +GLEW_FUN_EXPORT PFNGLPOINTPARAMETERFVPROC __glewPointParameterfv; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3BPROC __glewSecondaryColor3b; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3BVPROC __glewSecondaryColor3bv; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3DPROC __glewSecondaryColor3d; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3DVPROC __glewSecondaryColor3dv; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3FPROC __glewSecondaryColor3f; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3FVPROC __glewSecondaryColor3fv; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3IPROC __glewSecondaryColor3i; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3IVPROC __glewSecondaryColor3iv; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3SPROC __glewSecondaryColor3s; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3SVPROC __glewSecondaryColor3sv; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3UBPROC __glewSecondaryColor3ub; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3UBVPROC __glewSecondaryColor3ubv; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3UIPROC __glewSecondaryColor3ui; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3UIVPROC __glewSecondaryColor3uiv; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3USPROC __glewSecondaryColor3us; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3USVPROC __glewSecondaryColor3usv; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLORPOINTERPROC __glewSecondaryColorPointer; +GLEW_FUN_EXPORT PFNGLWINDOWPOS2DPROC __glewWindowPos2d; +GLEW_FUN_EXPORT PFNGLWINDOWPOS2DVPROC __glewWindowPos2dv; +GLEW_FUN_EXPORT PFNGLWINDOWPOS2FPROC __glewWindowPos2f; +GLEW_FUN_EXPORT PFNGLWINDOWPOS2FVPROC __glewWindowPos2fv; +GLEW_FUN_EXPORT PFNGLWINDOWPOS2IPROC __glewWindowPos2i; +GLEW_FUN_EXPORT PFNGLWINDOWPOS2IVPROC __glewWindowPos2iv; +GLEW_FUN_EXPORT PFNGLWINDOWPOS2SPROC __glewWindowPos2s; +GLEW_FUN_EXPORT PFNGLWINDOWPOS2SVPROC __glewWindowPos2sv; +GLEW_FUN_EXPORT PFNGLWINDOWPOS3DPROC __glewWindowPos3d; +GLEW_FUN_EXPORT PFNGLWINDOWPOS3DVPROC __glewWindowPos3dv; +GLEW_FUN_EXPORT PFNGLWINDOWPOS3FPROC __glewWindowPos3f; +GLEW_FUN_EXPORT PFNGLWINDOWPOS3FVPROC __glewWindowPos3fv; +GLEW_FUN_EXPORT PFNGLWINDOWPOS3IPROC __glewWindowPos3i; +GLEW_FUN_EXPORT PFNGLWINDOWPOS3IVPROC __glewWindowPos3iv; +GLEW_FUN_EXPORT PFNGLWINDOWPOS3SPROC __glewWindowPos3s; +GLEW_FUN_EXPORT PFNGLWINDOWPOS3SVPROC __glewWindowPos3sv; + +GLEW_FUN_EXPORT PFNGLBEGINQUERYPROC __glewBeginQuery; +GLEW_FUN_EXPORT PFNGLBINDBUFFERPROC __glewBindBuffer; +GLEW_FUN_EXPORT PFNGLBUFFERDATAPROC __glewBufferData; +GLEW_FUN_EXPORT PFNGLBUFFERSUBDATAPROC __glewBufferSubData; +GLEW_FUN_EXPORT PFNGLDELETEBUFFERSPROC __glewDeleteBuffers; +GLEW_FUN_EXPORT PFNGLDELETEQUERIESPROC __glewDeleteQueries; +GLEW_FUN_EXPORT PFNGLENDQUERYPROC __glewEndQuery; +GLEW_FUN_EXPORT PFNGLGENBUFFERSPROC __glewGenBuffers; +GLEW_FUN_EXPORT PFNGLGENQUERIESPROC __glewGenQueries; +GLEW_FUN_EXPORT PFNGLGETBUFFERPARAMETERIVPROC __glewGetBufferParameteriv; +GLEW_FUN_EXPORT PFNGLGETBUFFERPOINTERVPROC __glewGetBufferPointerv; +GLEW_FUN_EXPORT PFNGLGETBUFFERSUBDATAPROC __glewGetBufferSubData; +GLEW_FUN_EXPORT PFNGLGETQUERYOBJECTIVPROC __glewGetQueryObjectiv; +GLEW_FUN_EXPORT PFNGLGETQUERYOBJECTUIVPROC __glewGetQueryObjectuiv; +GLEW_FUN_EXPORT PFNGLGETQUERYIVPROC __glewGetQueryiv; +GLEW_FUN_EXPORT PFNGLISBUFFERPROC __glewIsBuffer; +GLEW_FUN_EXPORT PFNGLISQUERYPROC __glewIsQuery; +GLEW_FUN_EXPORT PFNGLMAPBUFFERPROC __glewMapBuffer; +GLEW_FUN_EXPORT PFNGLUNMAPBUFFERPROC __glewUnmapBuffer; + +GLEW_FUN_EXPORT PFNGLATTACHSHADERPROC __glewAttachShader; +GLEW_FUN_EXPORT PFNGLBINDATTRIBLOCATIONPROC __glewBindAttribLocation; +GLEW_FUN_EXPORT PFNGLBLENDEQUATIONSEPARATEPROC __glewBlendEquationSeparate; +GLEW_FUN_EXPORT PFNGLCOMPILESHADERPROC __glewCompileShader; +GLEW_FUN_EXPORT PFNGLCREATEPROGRAMPROC __glewCreateProgram; +GLEW_FUN_EXPORT PFNGLCREATESHADERPROC __glewCreateShader; +GLEW_FUN_EXPORT PFNGLDELETEPROGRAMPROC __glewDeleteProgram; +GLEW_FUN_EXPORT PFNGLDELETESHADERPROC __glewDeleteShader; +GLEW_FUN_EXPORT PFNGLDETACHSHADERPROC __glewDetachShader; +GLEW_FUN_EXPORT PFNGLDISABLEVERTEXATTRIBARRAYPROC __glewDisableVertexAttribArray; +GLEW_FUN_EXPORT PFNGLDRAWBUFFERSPROC __glewDrawBuffers; +GLEW_FUN_EXPORT PFNGLENABLEVERTEXATTRIBARRAYPROC __glewEnableVertexAttribArray; +GLEW_FUN_EXPORT PFNGLGETACTIVEATTRIBPROC __glewGetActiveAttrib; +GLEW_FUN_EXPORT PFNGLGETACTIVEUNIFORMPROC __glewGetActiveUniform; +GLEW_FUN_EXPORT PFNGLGETATTACHEDSHADERSPROC __glewGetAttachedShaders; +GLEW_FUN_EXPORT PFNGLGETATTRIBLOCATIONPROC __glewGetAttribLocation; +GLEW_FUN_EXPORT PFNGLGETPROGRAMINFOLOGPROC __glewGetProgramInfoLog; +GLEW_FUN_EXPORT PFNGLGETPROGRAMIVPROC __glewGetProgramiv; +GLEW_FUN_EXPORT PFNGLGETSHADERINFOLOGPROC __glewGetShaderInfoLog; +GLEW_FUN_EXPORT PFNGLGETSHADERSOURCEPROC __glewGetShaderSource; +GLEW_FUN_EXPORT PFNGLGETSHADERIVPROC __glewGetShaderiv; +GLEW_FUN_EXPORT PFNGLGETUNIFORMLOCATIONPROC __glewGetUniformLocation; +GLEW_FUN_EXPORT PFNGLGETUNIFORMFVPROC __glewGetUniformfv; +GLEW_FUN_EXPORT PFNGLGETUNIFORMIVPROC __glewGetUniformiv; +GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBPOINTERVPROC __glewGetVertexAttribPointerv; +GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBDVPROC __glewGetVertexAttribdv; +GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBFVPROC __glewGetVertexAttribfv; +GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBIVPROC __glewGetVertexAttribiv; +GLEW_FUN_EXPORT PFNGLISPROGRAMPROC __glewIsProgram; +GLEW_FUN_EXPORT PFNGLISSHADERPROC __glewIsShader; +GLEW_FUN_EXPORT PFNGLLINKPROGRAMPROC __glewLinkProgram; +GLEW_FUN_EXPORT PFNGLSHADERSOURCEPROC __glewShaderSource; +GLEW_FUN_EXPORT PFNGLSTENCILFUNCSEPARATEPROC __glewStencilFuncSeparate; +GLEW_FUN_EXPORT PFNGLSTENCILMASKSEPARATEPROC __glewStencilMaskSeparate; +GLEW_FUN_EXPORT PFNGLSTENCILOPSEPARATEPROC __glewStencilOpSeparate; +GLEW_FUN_EXPORT PFNGLUNIFORM1FPROC __glewUniform1f; +GLEW_FUN_EXPORT PFNGLUNIFORM1FVPROC __glewUniform1fv; +GLEW_FUN_EXPORT PFNGLUNIFORM1IPROC __glewUniform1i; +GLEW_FUN_EXPORT PFNGLUNIFORM1IVPROC __glewUniform1iv; +GLEW_FUN_EXPORT PFNGLUNIFORM2FPROC __glewUniform2f; +GLEW_FUN_EXPORT PFNGLUNIFORM2FVPROC __glewUniform2fv; +GLEW_FUN_EXPORT PFNGLUNIFORM2IPROC __glewUniform2i; +GLEW_FUN_EXPORT PFNGLUNIFORM2IVPROC __glewUniform2iv; +GLEW_FUN_EXPORT PFNGLUNIFORM3FPROC __glewUniform3f; +GLEW_FUN_EXPORT PFNGLUNIFORM3FVPROC __glewUniform3fv; +GLEW_FUN_EXPORT PFNGLUNIFORM3IPROC __glewUniform3i; +GLEW_FUN_EXPORT PFNGLUNIFORM3IVPROC __glewUniform3iv; +GLEW_FUN_EXPORT PFNGLUNIFORM4FPROC __glewUniform4f; +GLEW_FUN_EXPORT PFNGLUNIFORM4FVPROC __glewUniform4fv; +GLEW_FUN_EXPORT PFNGLUNIFORM4IPROC __glewUniform4i; +GLEW_FUN_EXPORT PFNGLUNIFORM4IVPROC __glewUniform4iv; +GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX2FVPROC __glewUniformMatrix2fv; +GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX3FVPROC __glewUniformMatrix3fv; +GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX4FVPROC __glewUniformMatrix4fv; +GLEW_FUN_EXPORT PFNGLUSEPROGRAMPROC __glewUseProgram; +GLEW_FUN_EXPORT PFNGLVALIDATEPROGRAMPROC __glewValidateProgram; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1DPROC __glewVertexAttrib1d; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1DVPROC __glewVertexAttrib1dv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1FPROC __glewVertexAttrib1f; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1FVPROC __glewVertexAttrib1fv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1SPROC __glewVertexAttrib1s; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1SVPROC __glewVertexAttrib1sv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2DPROC __glewVertexAttrib2d; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2DVPROC __glewVertexAttrib2dv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2FPROC __glewVertexAttrib2f; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2FVPROC __glewVertexAttrib2fv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2SPROC __glewVertexAttrib2s; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2SVPROC __glewVertexAttrib2sv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3DPROC __glewVertexAttrib3d; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3DVPROC __glewVertexAttrib3dv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3FPROC __glewVertexAttrib3f; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3FVPROC __glewVertexAttrib3fv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3SPROC __glewVertexAttrib3s; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3SVPROC __glewVertexAttrib3sv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4NBVPROC __glewVertexAttrib4Nbv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4NIVPROC __glewVertexAttrib4Niv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4NSVPROC __glewVertexAttrib4Nsv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4NUBPROC __glewVertexAttrib4Nub; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4NUBVPROC __glewVertexAttrib4Nubv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4NUIVPROC __glewVertexAttrib4Nuiv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4NUSVPROC __glewVertexAttrib4Nusv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4BVPROC __glewVertexAttrib4bv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4DPROC __glewVertexAttrib4d; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4DVPROC __glewVertexAttrib4dv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4FPROC __glewVertexAttrib4f; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4FVPROC __glewVertexAttrib4fv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4IVPROC __glewVertexAttrib4iv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4SPROC __glewVertexAttrib4s; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4SVPROC __glewVertexAttrib4sv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4UBVPROC __glewVertexAttrib4ubv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4UIVPROC __glewVertexAttrib4uiv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4USVPROC __glewVertexAttrib4usv; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBPOINTERPROC __glewVertexAttribPointer; + +GLEW_FUN_EXPORT PFNGLTBUFFERMASK3DFXPROC __glewTbufferMask3DFX; + +GLEW_FUN_EXPORT PFNGLDRAWELEMENTARRAYAPPLEPROC __glewDrawElementArrayAPPLE; +GLEW_FUN_EXPORT PFNGLDRAWRANGEELEMENTARRAYAPPLEPROC __glewDrawRangeElementArrayAPPLE; +GLEW_FUN_EXPORT PFNGLELEMENTPOINTERAPPLEPROC __glewElementPointerAPPLE; +GLEW_FUN_EXPORT PFNGLMULTIDRAWELEMENTARRAYAPPLEPROC __glewMultiDrawElementArrayAPPLE; +GLEW_FUN_EXPORT PFNGLMULTIDRAWRANGEELEMENTARRAYAPPLEPROC __glewMultiDrawRangeElementArrayAPPLE; + +GLEW_FUN_EXPORT PFNGLDELETEFENCESAPPLEPROC __glewDeleteFencesAPPLE; +GLEW_FUN_EXPORT PFNGLFINISHFENCEAPPLEPROC __glewFinishFenceAPPLE; +GLEW_FUN_EXPORT PFNGLFINISHOBJECTAPPLEPROC __glewFinishObjectAPPLE; +GLEW_FUN_EXPORT PFNGLGENFENCESAPPLEPROC __glewGenFencesAPPLE; +GLEW_FUN_EXPORT PFNGLISFENCEAPPLEPROC __glewIsFenceAPPLE; +GLEW_FUN_EXPORT PFNGLSETFENCEAPPLEPROC __glewSetFenceAPPLE; +GLEW_FUN_EXPORT PFNGLTESTFENCEAPPLEPROC __glewTestFenceAPPLE; +GLEW_FUN_EXPORT PFNGLTESTOBJECTAPPLEPROC __glewTestObjectAPPLE; + +GLEW_FUN_EXPORT PFNGLGETTEXPARAMETERPOINTERVAPPLEPROC __glewGetTexParameterPointervAPPLE; +GLEW_FUN_EXPORT PFNGLTEXTURERANGEAPPLEPROC __glewTextureRangeAPPLE; + +GLEW_FUN_EXPORT PFNGLBINDVERTEXARRAYAPPLEPROC __glewBindVertexArrayAPPLE; +GLEW_FUN_EXPORT PFNGLDELETEVERTEXARRAYSAPPLEPROC __glewDeleteVertexArraysAPPLE; +GLEW_FUN_EXPORT PFNGLGENVERTEXARRAYSAPPLEPROC __glewGenVertexArraysAPPLE; +GLEW_FUN_EXPORT PFNGLISVERTEXARRAYAPPLEPROC __glewIsVertexArrayAPPLE; + +GLEW_FUN_EXPORT PFNGLFLUSHVERTEXARRAYRANGEAPPLEPROC __glewFlushVertexArrayRangeAPPLE; +GLEW_FUN_EXPORT PFNGLVERTEXARRAYPARAMETERIAPPLEPROC __glewVertexArrayParameteriAPPLE; +GLEW_FUN_EXPORT PFNGLVERTEXARRAYRANGEAPPLEPROC __glewVertexArrayRangeAPPLE; + +GLEW_FUN_EXPORT PFNGLCLAMPCOLORARBPROC __glewClampColorARB; + +GLEW_FUN_EXPORT PFNGLDRAWBUFFERSARBPROC __glewDrawBuffersARB; + +GLEW_FUN_EXPORT PFNGLCOLORSUBTABLEPROC __glewColorSubTable; +GLEW_FUN_EXPORT PFNGLCOLORTABLEPROC __glewColorTable; +GLEW_FUN_EXPORT PFNGLCOLORTABLEPARAMETERFVPROC __glewColorTableParameterfv; +GLEW_FUN_EXPORT PFNGLCOLORTABLEPARAMETERIVPROC __glewColorTableParameteriv; +GLEW_FUN_EXPORT PFNGLCONVOLUTIONFILTER1DPROC __glewConvolutionFilter1D; +GLEW_FUN_EXPORT PFNGLCONVOLUTIONFILTER2DPROC __glewConvolutionFilter2D; +GLEW_FUN_EXPORT PFNGLCONVOLUTIONPARAMETERFPROC __glewConvolutionParameterf; +GLEW_FUN_EXPORT PFNGLCONVOLUTIONPARAMETERFVPROC __glewConvolutionParameterfv; +GLEW_FUN_EXPORT PFNGLCONVOLUTIONPARAMETERIPROC __glewConvolutionParameteri; +GLEW_FUN_EXPORT PFNGLCONVOLUTIONPARAMETERIVPROC __glewConvolutionParameteriv; +GLEW_FUN_EXPORT PFNGLCOPYCOLORSUBTABLEPROC __glewCopyColorSubTable; +GLEW_FUN_EXPORT PFNGLCOPYCOLORTABLEPROC __glewCopyColorTable; +GLEW_FUN_EXPORT PFNGLCOPYCONVOLUTIONFILTER1DPROC __glewCopyConvolutionFilter1D; +GLEW_FUN_EXPORT PFNGLCOPYCONVOLUTIONFILTER2DPROC __glewCopyConvolutionFilter2D; +GLEW_FUN_EXPORT PFNGLGETCOLORTABLEPROC __glewGetColorTable; +GLEW_FUN_EXPORT PFNGLGETCOLORTABLEPARAMETERFVPROC __glewGetColorTableParameterfv; +GLEW_FUN_EXPORT PFNGLGETCOLORTABLEPARAMETERIVPROC __glewGetColorTableParameteriv; +GLEW_FUN_EXPORT PFNGLGETCONVOLUTIONFILTERPROC __glewGetConvolutionFilter; +GLEW_FUN_EXPORT PFNGLGETCONVOLUTIONPARAMETERFVPROC __glewGetConvolutionParameterfv; +GLEW_FUN_EXPORT PFNGLGETCONVOLUTIONPARAMETERIVPROC __glewGetConvolutionParameteriv; +GLEW_FUN_EXPORT PFNGLGETHISTOGRAMPROC __glewGetHistogram; +GLEW_FUN_EXPORT PFNGLGETHISTOGRAMPARAMETERFVPROC __glewGetHistogramParameterfv; +GLEW_FUN_EXPORT PFNGLGETHISTOGRAMPARAMETERIVPROC __glewGetHistogramParameteriv; +GLEW_FUN_EXPORT PFNGLGETMINMAXPROC __glewGetMinmax; +GLEW_FUN_EXPORT PFNGLGETMINMAXPARAMETERFVPROC __glewGetMinmaxParameterfv; +GLEW_FUN_EXPORT PFNGLGETMINMAXPARAMETERIVPROC __glewGetMinmaxParameteriv; +GLEW_FUN_EXPORT PFNGLGETSEPARABLEFILTERPROC __glewGetSeparableFilter; +GLEW_FUN_EXPORT PFNGLHISTOGRAMPROC __glewHistogram; +GLEW_FUN_EXPORT PFNGLMINMAXPROC __glewMinmax; +GLEW_FUN_EXPORT PFNGLRESETHISTOGRAMPROC __glewResetHistogram; +GLEW_FUN_EXPORT PFNGLRESETMINMAXPROC __glewResetMinmax; +GLEW_FUN_EXPORT PFNGLSEPARABLEFILTER2DPROC __glewSeparableFilter2D; + +GLEW_FUN_EXPORT PFNGLCURRENTPALETTEMATRIXARBPROC __glewCurrentPaletteMatrixARB; +GLEW_FUN_EXPORT PFNGLMATRIXINDEXPOINTERARBPROC __glewMatrixIndexPointerARB; +GLEW_FUN_EXPORT PFNGLMATRIXINDEXUBVARBPROC __glewMatrixIndexubvARB; +GLEW_FUN_EXPORT PFNGLMATRIXINDEXUIVARBPROC __glewMatrixIndexuivARB; +GLEW_FUN_EXPORT PFNGLMATRIXINDEXUSVARBPROC __glewMatrixIndexusvARB; + +GLEW_FUN_EXPORT PFNGLSAMPLECOVERAGEARBPROC __glewSampleCoverageARB; + +GLEW_FUN_EXPORT PFNGLACTIVETEXTUREARBPROC __glewActiveTextureARB; +GLEW_FUN_EXPORT PFNGLCLIENTACTIVETEXTUREARBPROC __glewClientActiveTextureARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1DARBPROC __glewMultiTexCoord1dARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1DVARBPROC __glewMultiTexCoord1dvARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1FARBPROC __glewMultiTexCoord1fARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1FVARBPROC __glewMultiTexCoord1fvARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1IARBPROC __glewMultiTexCoord1iARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1IVARBPROC __glewMultiTexCoord1ivARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1SARBPROC __glewMultiTexCoord1sARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1SVARBPROC __glewMultiTexCoord1svARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2DARBPROC __glewMultiTexCoord2dARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2DVARBPROC __glewMultiTexCoord2dvARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2FARBPROC __glewMultiTexCoord2fARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2FVARBPROC __glewMultiTexCoord2fvARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2IARBPROC __glewMultiTexCoord2iARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2IVARBPROC __glewMultiTexCoord2ivARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2SARBPROC __glewMultiTexCoord2sARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2SVARBPROC __glewMultiTexCoord2svARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3DARBPROC __glewMultiTexCoord3dARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3DVARBPROC __glewMultiTexCoord3dvARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3FARBPROC __glewMultiTexCoord3fARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3FVARBPROC __glewMultiTexCoord3fvARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3IARBPROC __glewMultiTexCoord3iARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3IVARBPROC __glewMultiTexCoord3ivARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3SARBPROC __glewMultiTexCoord3sARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3SVARBPROC __glewMultiTexCoord3svARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4DARBPROC __glewMultiTexCoord4dARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4DVARBPROC __glewMultiTexCoord4dvARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4FARBPROC __glewMultiTexCoord4fARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4FVARBPROC __glewMultiTexCoord4fvARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4IARBPROC __glewMultiTexCoord4iARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4IVARBPROC __glewMultiTexCoord4ivARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4SARBPROC __glewMultiTexCoord4sARB; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4SVARBPROC __glewMultiTexCoord4svARB; + +GLEW_FUN_EXPORT PFNGLBEGINQUERYARBPROC __glewBeginQueryARB; +GLEW_FUN_EXPORT PFNGLDELETEQUERIESARBPROC __glewDeleteQueriesARB; +GLEW_FUN_EXPORT PFNGLENDQUERYARBPROC __glewEndQueryARB; +GLEW_FUN_EXPORT PFNGLGENQUERIESARBPROC __glewGenQueriesARB; +GLEW_FUN_EXPORT PFNGLGETQUERYOBJECTIVARBPROC __glewGetQueryObjectivARB; +GLEW_FUN_EXPORT PFNGLGETQUERYOBJECTUIVARBPROC __glewGetQueryObjectuivARB; +GLEW_FUN_EXPORT PFNGLGETQUERYIVARBPROC __glewGetQueryivARB; +GLEW_FUN_EXPORT PFNGLISQUERYARBPROC __glewIsQueryARB; + +GLEW_FUN_EXPORT PFNGLPOINTPARAMETERFARBPROC __glewPointParameterfARB; +GLEW_FUN_EXPORT PFNGLPOINTPARAMETERFVARBPROC __glewPointParameterfvARB; + +GLEW_FUN_EXPORT PFNGLATTACHOBJECTARBPROC __glewAttachObjectARB; +GLEW_FUN_EXPORT PFNGLCOMPILESHADERARBPROC __glewCompileShaderARB; +GLEW_FUN_EXPORT PFNGLCREATEPROGRAMOBJECTARBPROC __glewCreateProgramObjectARB; +GLEW_FUN_EXPORT PFNGLCREATESHADEROBJECTARBPROC __glewCreateShaderObjectARB; +GLEW_FUN_EXPORT PFNGLDELETEOBJECTARBPROC __glewDeleteObjectARB; +GLEW_FUN_EXPORT PFNGLDETACHOBJECTARBPROC __glewDetachObjectARB; +GLEW_FUN_EXPORT PFNGLGETACTIVEUNIFORMARBPROC __glewGetActiveUniformARB; +GLEW_FUN_EXPORT PFNGLGETATTACHEDOBJECTSARBPROC __glewGetAttachedObjectsARB; +GLEW_FUN_EXPORT PFNGLGETHANDLEARBPROC __glewGetHandleARB; +GLEW_FUN_EXPORT PFNGLGETINFOLOGARBPROC __glewGetInfoLogARB; +GLEW_FUN_EXPORT PFNGLGETOBJECTPARAMETERFVARBPROC __glewGetObjectParameterfvARB; +GLEW_FUN_EXPORT PFNGLGETOBJECTPARAMETERIVARBPROC __glewGetObjectParameterivARB; +GLEW_FUN_EXPORT PFNGLGETSHADERSOURCEARBPROC __glewGetShaderSourceARB; +GLEW_FUN_EXPORT PFNGLGETUNIFORMLOCATIONARBPROC __glewGetUniformLocationARB; +GLEW_FUN_EXPORT PFNGLGETUNIFORMFVARBPROC __glewGetUniformfvARB; +GLEW_FUN_EXPORT PFNGLGETUNIFORMIVARBPROC __glewGetUniformivARB; +GLEW_FUN_EXPORT PFNGLLINKPROGRAMARBPROC __glewLinkProgramARB; +GLEW_FUN_EXPORT PFNGLSHADERSOURCEARBPROC __glewShaderSourceARB; +GLEW_FUN_EXPORT PFNGLUNIFORM1FARBPROC __glewUniform1fARB; +GLEW_FUN_EXPORT PFNGLUNIFORM1FVARBPROC __glewUniform1fvARB; +GLEW_FUN_EXPORT PFNGLUNIFORM1IARBPROC __glewUniform1iARB; +GLEW_FUN_EXPORT PFNGLUNIFORM1IVARBPROC __glewUniform1ivARB; +GLEW_FUN_EXPORT PFNGLUNIFORM2FARBPROC __glewUniform2fARB; +GLEW_FUN_EXPORT PFNGLUNIFORM2FVARBPROC __glewUniform2fvARB; +GLEW_FUN_EXPORT PFNGLUNIFORM2IARBPROC __glewUniform2iARB; +GLEW_FUN_EXPORT PFNGLUNIFORM2IVARBPROC __glewUniform2ivARB; +GLEW_FUN_EXPORT PFNGLUNIFORM3FARBPROC __glewUniform3fARB; +GLEW_FUN_EXPORT PFNGLUNIFORM3FVARBPROC __glewUniform3fvARB; +GLEW_FUN_EXPORT PFNGLUNIFORM3IARBPROC __glewUniform3iARB; +GLEW_FUN_EXPORT PFNGLUNIFORM3IVARBPROC __glewUniform3ivARB; +GLEW_FUN_EXPORT PFNGLUNIFORM4FARBPROC __glewUniform4fARB; +GLEW_FUN_EXPORT PFNGLUNIFORM4FVARBPROC __glewUniform4fvARB; +GLEW_FUN_EXPORT PFNGLUNIFORM4IARBPROC __glewUniform4iARB; +GLEW_FUN_EXPORT PFNGLUNIFORM4IVARBPROC __glewUniform4ivARB; +GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX2FVARBPROC __glewUniformMatrix2fvARB; +GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX3FVARBPROC __glewUniformMatrix3fvARB; +GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX4FVARBPROC __glewUniformMatrix4fvARB; +GLEW_FUN_EXPORT PFNGLUSEPROGRAMOBJECTARBPROC __glewUseProgramObjectARB; +GLEW_FUN_EXPORT PFNGLVALIDATEPROGRAMARBPROC __glewValidateProgramARB; + +GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXIMAGE1DARBPROC __glewCompressedTexImage1DARB; +GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXIMAGE2DARBPROC __glewCompressedTexImage2DARB; +GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXIMAGE3DARBPROC __glewCompressedTexImage3DARB; +GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXSUBIMAGE1DARBPROC __glewCompressedTexSubImage1DARB; +GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXSUBIMAGE2DARBPROC __glewCompressedTexSubImage2DARB; +GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXSUBIMAGE3DARBPROC __glewCompressedTexSubImage3DARB; +GLEW_FUN_EXPORT PFNGLGETCOMPRESSEDTEXIMAGEARBPROC __glewGetCompressedTexImageARB; + +GLEW_FUN_EXPORT PFNGLLOADTRANSPOSEMATRIXDARBPROC __glewLoadTransposeMatrixdARB; +GLEW_FUN_EXPORT PFNGLLOADTRANSPOSEMATRIXFARBPROC __glewLoadTransposeMatrixfARB; +GLEW_FUN_EXPORT PFNGLMULTTRANSPOSEMATRIXDARBPROC __glewMultTransposeMatrixdARB; +GLEW_FUN_EXPORT PFNGLMULTTRANSPOSEMATRIXFARBPROC __glewMultTransposeMatrixfARB; + +GLEW_FUN_EXPORT PFNGLVERTEXBLENDARBPROC __glewVertexBlendARB; +GLEW_FUN_EXPORT PFNGLWEIGHTPOINTERARBPROC __glewWeightPointerARB; +GLEW_FUN_EXPORT PFNGLWEIGHTBVARBPROC __glewWeightbvARB; +GLEW_FUN_EXPORT PFNGLWEIGHTDVARBPROC __glewWeightdvARB; +GLEW_FUN_EXPORT PFNGLWEIGHTFVARBPROC __glewWeightfvARB; +GLEW_FUN_EXPORT PFNGLWEIGHTIVARBPROC __glewWeightivARB; +GLEW_FUN_EXPORT PFNGLWEIGHTSVARBPROC __glewWeightsvARB; +GLEW_FUN_EXPORT PFNGLWEIGHTUBVARBPROC __glewWeightubvARB; +GLEW_FUN_EXPORT PFNGLWEIGHTUIVARBPROC __glewWeightuivARB; +GLEW_FUN_EXPORT PFNGLWEIGHTUSVARBPROC __glewWeightusvARB; + +GLEW_FUN_EXPORT PFNGLBINDBUFFERARBPROC __glewBindBufferARB; +GLEW_FUN_EXPORT PFNGLBUFFERDATAARBPROC __glewBufferDataARB; +GLEW_FUN_EXPORT PFNGLBUFFERSUBDATAARBPROC __glewBufferSubDataARB; +GLEW_FUN_EXPORT PFNGLDELETEBUFFERSARBPROC __glewDeleteBuffersARB; +GLEW_FUN_EXPORT PFNGLGENBUFFERSARBPROC __glewGenBuffersARB; +GLEW_FUN_EXPORT PFNGLGETBUFFERPARAMETERIVARBPROC __glewGetBufferParameterivARB; +GLEW_FUN_EXPORT PFNGLGETBUFFERPOINTERVARBPROC __glewGetBufferPointervARB; +GLEW_FUN_EXPORT PFNGLGETBUFFERSUBDATAARBPROC __glewGetBufferSubDataARB; +GLEW_FUN_EXPORT PFNGLISBUFFERARBPROC __glewIsBufferARB; +GLEW_FUN_EXPORT PFNGLMAPBUFFERARBPROC __glewMapBufferARB; +GLEW_FUN_EXPORT PFNGLUNMAPBUFFERARBPROC __glewUnmapBufferARB; + +GLEW_FUN_EXPORT PFNGLBINDPROGRAMARBPROC __glewBindProgramARB; +GLEW_FUN_EXPORT PFNGLDELETEPROGRAMSARBPROC __glewDeleteProgramsARB; +GLEW_FUN_EXPORT PFNGLDISABLEVERTEXATTRIBARRAYARBPROC __glewDisableVertexAttribArrayARB; +GLEW_FUN_EXPORT PFNGLENABLEVERTEXATTRIBARRAYARBPROC __glewEnableVertexAttribArrayARB; +GLEW_FUN_EXPORT PFNGLGENPROGRAMSARBPROC __glewGenProgramsARB; +GLEW_FUN_EXPORT PFNGLGETPROGRAMENVPARAMETERDVARBPROC __glewGetProgramEnvParameterdvARB; +GLEW_FUN_EXPORT PFNGLGETPROGRAMENVPARAMETERFVARBPROC __glewGetProgramEnvParameterfvARB; +GLEW_FUN_EXPORT PFNGLGETPROGRAMLOCALPARAMETERDVARBPROC __glewGetProgramLocalParameterdvARB; +GLEW_FUN_EXPORT PFNGLGETPROGRAMLOCALPARAMETERFVARBPROC __glewGetProgramLocalParameterfvARB; +GLEW_FUN_EXPORT PFNGLGETPROGRAMSTRINGARBPROC __glewGetProgramStringARB; +GLEW_FUN_EXPORT PFNGLGETPROGRAMIVARBPROC __glewGetProgramivARB; +GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBPOINTERVARBPROC __glewGetVertexAttribPointervARB; +GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBDVARBPROC __glewGetVertexAttribdvARB; +GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBFVARBPROC __glewGetVertexAttribfvARB; +GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBIVARBPROC __glewGetVertexAttribivARB; +GLEW_FUN_EXPORT PFNGLISPROGRAMARBPROC __glewIsProgramARB; +GLEW_FUN_EXPORT PFNGLPROGRAMENVPARAMETER4DARBPROC __glewProgramEnvParameter4dARB; +GLEW_FUN_EXPORT PFNGLPROGRAMENVPARAMETER4DVARBPROC __glewProgramEnvParameter4dvARB; +GLEW_FUN_EXPORT PFNGLPROGRAMENVPARAMETER4FARBPROC __glewProgramEnvParameter4fARB; +GLEW_FUN_EXPORT PFNGLPROGRAMENVPARAMETER4FVARBPROC __glewProgramEnvParameter4fvARB; +GLEW_FUN_EXPORT PFNGLPROGRAMLOCALPARAMETER4DARBPROC __glewProgramLocalParameter4dARB; +GLEW_FUN_EXPORT PFNGLPROGRAMLOCALPARAMETER4DVARBPROC __glewProgramLocalParameter4dvARB; +GLEW_FUN_EXPORT PFNGLPROGRAMLOCALPARAMETER4FARBPROC __glewProgramLocalParameter4fARB; +GLEW_FUN_EXPORT PFNGLPROGRAMLOCALPARAMETER4FVARBPROC __glewProgramLocalParameter4fvARB; +GLEW_FUN_EXPORT PFNGLPROGRAMSTRINGARBPROC __glewProgramStringARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1DARBPROC __glewVertexAttrib1dARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1DVARBPROC __glewVertexAttrib1dvARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1FARBPROC __glewVertexAttrib1fARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1FVARBPROC __glewVertexAttrib1fvARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1SARBPROC __glewVertexAttrib1sARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1SVARBPROC __glewVertexAttrib1svARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2DARBPROC __glewVertexAttrib2dARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2DVARBPROC __glewVertexAttrib2dvARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2FARBPROC __glewVertexAttrib2fARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2FVARBPROC __glewVertexAttrib2fvARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2SARBPROC __glewVertexAttrib2sARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2SVARBPROC __glewVertexAttrib2svARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3DARBPROC __glewVertexAttrib3dARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3DVARBPROC __glewVertexAttrib3dvARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3FARBPROC __glewVertexAttrib3fARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3FVARBPROC __glewVertexAttrib3fvARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3SARBPROC __glewVertexAttrib3sARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3SVARBPROC __glewVertexAttrib3svARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4NBVARBPROC __glewVertexAttrib4NbvARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4NIVARBPROC __glewVertexAttrib4NivARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4NSVARBPROC __glewVertexAttrib4NsvARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4NUBARBPROC __glewVertexAttrib4NubARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4NUBVARBPROC __glewVertexAttrib4NubvARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4NUIVARBPROC __glewVertexAttrib4NuivARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4NUSVARBPROC __glewVertexAttrib4NusvARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4BVARBPROC __glewVertexAttrib4bvARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4DARBPROC __glewVertexAttrib4dARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4DVARBPROC __glewVertexAttrib4dvARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4FARBPROC __glewVertexAttrib4fARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4FVARBPROC __glewVertexAttrib4fvARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4IVARBPROC __glewVertexAttrib4ivARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4SARBPROC __glewVertexAttrib4sARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4SVARBPROC __glewVertexAttrib4svARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4UBVARBPROC __glewVertexAttrib4ubvARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4UIVARBPROC __glewVertexAttrib4uivARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4USVARBPROC __glewVertexAttrib4usvARB; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBPOINTERARBPROC __glewVertexAttribPointerARB; + +GLEW_FUN_EXPORT PFNGLBINDATTRIBLOCATIONARBPROC __glewBindAttribLocationARB; +GLEW_FUN_EXPORT PFNGLGETACTIVEATTRIBARBPROC __glewGetActiveAttribARB; +GLEW_FUN_EXPORT PFNGLGETATTRIBLOCATIONARBPROC __glewGetAttribLocationARB; + +GLEW_FUN_EXPORT PFNGLWINDOWPOS2DARBPROC __glewWindowPos2dARB; +GLEW_FUN_EXPORT PFNGLWINDOWPOS2DVARBPROC __glewWindowPos2dvARB; +GLEW_FUN_EXPORT PFNGLWINDOWPOS2FARBPROC __glewWindowPos2fARB; +GLEW_FUN_EXPORT PFNGLWINDOWPOS2FVARBPROC __glewWindowPos2fvARB; +GLEW_FUN_EXPORT PFNGLWINDOWPOS2IARBPROC __glewWindowPos2iARB; +GLEW_FUN_EXPORT PFNGLWINDOWPOS2IVARBPROC __glewWindowPos2ivARB; +GLEW_FUN_EXPORT PFNGLWINDOWPOS2SARBPROC __glewWindowPos2sARB; +GLEW_FUN_EXPORT PFNGLWINDOWPOS2SVARBPROC __glewWindowPos2svARB; +GLEW_FUN_EXPORT PFNGLWINDOWPOS3DARBPROC __glewWindowPos3dARB; +GLEW_FUN_EXPORT PFNGLWINDOWPOS3DVARBPROC __glewWindowPos3dvARB; +GLEW_FUN_EXPORT PFNGLWINDOWPOS3FARBPROC __glewWindowPos3fARB; +GLEW_FUN_EXPORT PFNGLWINDOWPOS3FVARBPROC __glewWindowPos3fvARB; +GLEW_FUN_EXPORT PFNGLWINDOWPOS3IARBPROC __glewWindowPos3iARB; +GLEW_FUN_EXPORT PFNGLWINDOWPOS3IVARBPROC __glewWindowPos3ivARB; +GLEW_FUN_EXPORT PFNGLWINDOWPOS3SARBPROC __glewWindowPos3sARB; +GLEW_FUN_EXPORT PFNGLWINDOWPOS3SVARBPROC __glewWindowPos3svARB; + +GLEW_FUN_EXPORT PFNGLDRAWBUFFERSATIPROC __glewDrawBuffersATI; + +GLEW_FUN_EXPORT PFNGLDRAWELEMENTARRAYATIPROC __glewDrawElementArrayATI; +GLEW_FUN_EXPORT PFNGLDRAWRANGEELEMENTARRAYATIPROC __glewDrawRangeElementArrayATI; +GLEW_FUN_EXPORT PFNGLELEMENTPOINTERATIPROC __glewElementPointerATI; + +GLEW_FUN_EXPORT PFNGLGETTEXBUMPPARAMETERFVATIPROC __glewGetTexBumpParameterfvATI; +GLEW_FUN_EXPORT PFNGLGETTEXBUMPPARAMETERIVATIPROC __glewGetTexBumpParameterivATI; +GLEW_FUN_EXPORT PFNGLTEXBUMPPARAMETERFVATIPROC __glewTexBumpParameterfvATI; +GLEW_FUN_EXPORT PFNGLTEXBUMPPARAMETERIVATIPROC __glewTexBumpParameterivATI; + +GLEW_FUN_EXPORT PFNGLALPHAFRAGMENTOP1ATIPROC __glewAlphaFragmentOp1ATI; +GLEW_FUN_EXPORT PFNGLALPHAFRAGMENTOP2ATIPROC __glewAlphaFragmentOp2ATI; +GLEW_FUN_EXPORT PFNGLALPHAFRAGMENTOP3ATIPROC __glewAlphaFragmentOp3ATI; +GLEW_FUN_EXPORT PFNGLBEGINFRAGMENTSHADERATIPROC __glewBeginFragmentShaderATI; +GLEW_FUN_EXPORT PFNGLBINDFRAGMENTSHADERATIPROC __glewBindFragmentShaderATI; +GLEW_FUN_EXPORT PFNGLCOLORFRAGMENTOP1ATIPROC __glewColorFragmentOp1ATI; +GLEW_FUN_EXPORT PFNGLCOLORFRAGMENTOP2ATIPROC __glewColorFragmentOp2ATI; +GLEW_FUN_EXPORT PFNGLCOLORFRAGMENTOP3ATIPROC __glewColorFragmentOp3ATI; +GLEW_FUN_EXPORT PFNGLDELETEFRAGMENTSHADERATIPROC __glewDeleteFragmentShaderATI; +GLEW_FUN_EXPORT PFNGLENDFRAGMENTSHADERATIPROC __glewEndFragmentShaderATI; +GLEW_FUN_EXPORT PFNGLGENFRAGMENTSHADERSATIPROC __glewGenFragmentShadersATI; +GLEW_FUN_EXPORT PFNGLPASSTEXCOORDATIPROC __glewPassTexCoordATI; +GLEW_FUN_EXPORT PFNGLSAMPLEMAPATIPROC __glewSampleMapATI; +GLEW_FUN_EXPORT PFNGLSETFRAGMENTSHADERCONSTANTATIPROC __glewSetFragmentShaderConstantATI; + +GLEW_FUN_EXPORT PFNGLMAPOBJECTBUFFERATIPROC __glewMapObjectBufferATI; +GLEW_FUN_EXPORT PFNGLUNMAPOBJECTBUFFERATIPROC __glewUnmapObjectBufferATI; + +GLEW_FUN_EXPORT PFNGLPNTRIANGLESFATIPROC __glPNTrianglewesfATI; +GLEW_FUN_EXPORT PFNGLPNTRIANGLESIATIPROC __glPNTrianglewesiATI; + +GLEW_FUN_EXPORT PFNGLSTENCILFUNCSEPARATEATIPROC __glewStencilFuncSeparateATI; +GLEW_FUN_EXPORT PFNGLSTENCILOPSEPARATEATIPROC __glewStencilOpSeparateATI; + +GLEW_FUN_EXPORT PFNGLARRAYOBJECTATIPROC __glewArrayObjectATI; +GLEW_FUN_EXPORT PFNGLFREEOBJECTBUFFERATIPROC __glewFreeObjectBufferATI; +GLEW_FUN_EXPORT PFNGLGETARRAYOBJECTFVATIPROC __glewGetArrayObjectfvATI; +GLEW_FUN_EXPORT PFNGLGETARRAYOBJECTIVATIPROC __glewGetArrayObjectivATI; +GLEW_FUN_EXPORT PFNGLGETOBJECTBUFFERFVATIPROC __glewGetObjectBufferfvATI; +GLEW_FUN_EXPORT PFNGLGETOBJECTBUFFERIVATIPROC __glewGetObjectBufferivATI; +GLEW_FUN_EXPORT PFNGLGETVARIANTARRAYOBJECTFVATIPROC __glewGetVariantArrayObjectfvATI; +GLEW_FUN_EXPORT PFNGLGETVARIANTARRAYOBJECTIVATIPROC __glewGetVariantArrayObjectivATI; +GLEW_FUN_EXPORT PFNGLISOBJECTBUFFERATIPROC __glewIsObjectBufferATI; +GLEW_FUN_EXPORT PFNGLNEWOBJECTBUFFERATIPROC __glewNewObjectBufferATI; +GLEW_FUN_EXPORT PFNGLUPDATEOBJECTBUFFERATIPROC __glewUpdateObjectBufferATI; +GLEW_FUN_EXPORT PFNGLVARIANTARRAYOBJECTATIPROC __glewVariantArrayObjectATI; + +GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBARRAYOBJECTFVATIPROC __glewGetVertexAttribArrayObjectfvATI; +GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBARRAYOBJECTIVATIPROC __glewGetVertexAttribArrayObjectivATI; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBARRAYOBJECTATIPROC __glewVertexAttribArrayObjectATI; + +GLEW_FUN_EXPORT PFNGLCLIENTACTIVEVERTEXSTREAMATIPROC __glewClientActiveVertexStreamATI; +GLEW_FUN_EXPORT PFNGLNORMALSTREAM3BATIPROC __glewNormalStream3bATI; +GLEW_FUN_EXPORT PFNGLNORMALSTREAM3BVATIPROC __glewNormalStream3bvATI; +GLEW_FUN_EXPORT PFNGLNORMALSTREAM3DATIPROC __glewNormalStream3dATI; +GLEW_FUN_EXPORT PFNGLNORMALSTREAM3DVATIPROC __glewNormalStream3dvATI; +GLEW_FUN_EXPORT PFNGLNORMALSTREAM3FATIPROC __glewNormalStream3fATI; +GLEW_FUN_EXPORT PFNGLNORMALSTREAM3FVATIPROC __glewNormalStream3fvATI; +GLEW_FUN_EXPORT PFNGLNORMALSTREAM3IATIPROC __glewNormalStream3iATI; +GLEW_FUN_EXPORT PFNGLNORMALSTREAM3IVATIPROC __glewNormalStream3ivATI; +GLEW_FUN_EXPORT PFNGLNORMALSTREAM3SATIPROC __glewNormalStream3sATI; +GLEW_FUN_EXPORT PFNGLNORMALSTREAM3SVATIPROC __glewNormalStream3svATI; +GLEW_FUN_EXPORT PFNGLVERTEXBLENDENVFATIPROC __glewVertexBlendEnvfATI; +GLEW_FUN_EXPORT PFNGLVERTEXBLENDENVIATIPROC __glewVertexBlendEnviATI; +GLEW_FUN_EXPORT PFNGLVERTEXSTREAM2DATIPROC __glewVertexStream2dATI; +GLEW_FUN_EXPORT PFNGLVERTEXSTREAM2DVATIPROC __glewVertexStream2dvATI; +GLEW_FUN_EXPORT PFNGLVERTEXSTREAM2FATIPROC __glewVertexStream2fATI; +GLEW_FUN_EXPORT PFNGLVERTEXSTREAM2FVATIPROC __glewVertexStream2fvATI; +GLEW_FUN_EXPORT PFNGLVERTEXSTREAM2IATIPROC __glewVertexStream2iATI; +GLEW_FUN_EXPORT PFNGLVERTEXSTREAM2IVATIPROC __glewVertexStream2ivATI; +GLEW_FUN_EXPORT PFNGLVERTEXSTREAM2SATIPROC __glewVertexStream2sATI; +GLEW_FUN_EXPORT PFNGLVERTEXSTREAM2SVATIPROC __glewVertexStream2svATI; +GLEW_FUN_EXPORT PFNGLVERTEXSTREAM3DATIPROC __glewVertexStream3dATI; +GLEW_FUN_EXPORT PFNGLVERTEXSTREAM3DVATIPROC __glewVertexStream3dvATI; +GLEW_FUN_EXPORT PFNGLVERTEXSTREAM3FATIPROC __glewVertexStream3fATI; +GLEW_FUN_EXPORT PFNGLVERTEXSTREAM3FVATIPROC __glewVertexStream3fvATI; +GLEW_FUN_EXPORT PFNGLVERTEXSTREAM3IATIPROC __glewVertexStream3iATI; +GLEW_FUN_EXPORT PFNGLVERTEXSTREAM3IVATIPROC __glewVertexStream3ivATI; +GLEW_FUN_EXPORT PFNGLVERTEXSTREAM3SATIPROC __glewVertexStream3sATI; +GLEW_FUN_EXPORT PFNGLVERTEXSTREAM3SVATIPROC __glewVertexStream3svATI; +GLEW_FUN_EXPORT PFNGLVERTEXSTREAM4DATIPROC __glewVertexStream4dATI; +GLEW_FUN_EXPORT PFNGLVERTEXSTREAM4DVATIPROC __glewVertexStream4dvATI; +GLEW_FUN_EXPORT PFNGLVERTEXSTREAM4FATIPROC __glewVertexStream4fATI; +GLEW_FUN_EXPORT PFNGLVERTEXSTREAM4FVATIPROC __glewVertexStream4fvATI; +GLEW_FUN_EXPORT PFNGLVERTEXSTREAM4IATIPROC __glewVertexStream4iATI; +GLEW_FUN_EXPORT PFNGLVERTEXSTREAM4IVATIPROC __glewVertexStream4ivATI; +GLEW_FUN_EXPORT PFNGLVERTEXSTREAM4SATIPROC __glewVertexStream4sATI; +GLEW_FUN_EXPORT PFNGLVERTEXSTREAM4SVATIPROC __glewVertexStream4svATI; + +GLEW_FUN_EXPORT PFNGLBLENDCOLOREXTPROC __glewBlendColorEXT; + +GLEW_FUN_EXPORT PFNGLBLENDEQUATIONSEPARATEEXTPROC __glewBlendEquationSeparateEXT; + +GLEW_FUN_EXPORT PFNGLBLENDFUNCSEPARATEEXTPROC __glewBlendFuncSeparateEXT; + +GLEW_FUN_EXPORT PFNGLBLENDEQUATIONEXTPROC __glewBlendEquationEXT; + +GLEW_FUN_EXPORT PFNGLCOLORSUBTABLEEXTPROC __glewColorSubTableEXT; +GLEW_FUN_EXPORT PFNGLCOPYCOLORSUBTABLEEXTPROC __glewCopyColorSubTableEXT; + +GLEW_FUN_EXPORT PFNGLLOCKARRAYSEXTPROC __glewLockArraysEXT; +GLEW_FUN_EXPORT PFNGLUNLOCKARRAYSEXTPROC __glewUnlockArraysEXT; + +GLEW_FUN_EXPORT PFNGLCONVOLUTIONFILTER1DEXTPROC __glewConvolutionFilter1DEXT; +GLEW_FUN_EXPORT PFNGLCONVOLUTIONFILTER2DEXTPROC __glewConvolutionFilter2DEXT; +GLEW_FUN_EXPORT PFNGLCONVOLUTIONPARAMETERFEXTPROC __glewConvolutionParameterfEXT; +GLEW_FUN_EXPORT PFNGLCONVOLUTIONPARAMETERFVEXTPROC __glewConvolutionParameterfvEXT; +GLEW_FUN_EXPORT PFNGLCONVOLUTIONPARAMETERIEXTPROC __glewConvolutionParameteriEXT; +GLEW_FUN_EXPORT PFNGLCONVOLUTIONPARAMETERIVEXTPROC __glewConvolutionParameterivEXT; +GLEW_FUN_EXPORT PFNGLCOPYCONVOLUTIONFILTER1DEXTPROC __glewCopyConvolutionFilter1DEXT; +GLEW_FUN_EXPORT PFNGLCOPYCONVOLUTIONFILTER2DEXTPROC __glewCopyConvolutionFilter2DEXT; +GLEW_FUN_EXPORT PFNGLGETCONVOLUTIONFILTEREXTPROC __glewGetConvolutionFilterEXT; +GLEW_FUN_EXPORT PFNGLGETCONVOLUTIONPARAMETERFVEXTPROC __glewGetConvolutionParameterfvEXT; +GLEW_FUN_EXPORT PFNGLGETCONVOLUTIONPARAMETERIVEXTPROC __glewGetConvolutionParameterivEXT; +GLEW_FUN_EXPORT PFNGLGETSEPARABLEFILTEREXTPROC __glewGetSeparableFilterEXT; +GLEW_FUN_EXPORT PFNGLSEPARABLEFILTER2DEXTPROC __glewSeparableFilter2DEXT; + +GLEW_FUN_EXPORT PFNGLBINORMALPOINTEREXTPROC __glewBinormalPointerEXT; +GLEW_FUN_EXPORT PFNGLTANGENTPOINTEREXTPROC __glewTangentPointerEXT; + +GLEW_FUN_EXPORT PFNGLCOPYTEXIMAGE1DEXTPROC __glewCopyTexImage1DEXT; +GLEW_FUN_EXPORT PFNGLCOPYTEXIMAGE2DEXTPROC __glewCopyTexImage2DEXT; +GLEW_FUN_EXPORT PFNGLCOPYTEXSUBIMAGE1DEXTPROC __glewCopyTexSubImage1DEXT; +GLEW_FUN_EXPORT PFNGLCOPYTEXSUBIMAGE2DEXTPROC __glewCopyTexSubImage2DEXT; +GLEW_FUN_EXPORT PFNGLCOPYTEXSUBIMAGE3DEXTPROC __glewCopyTexSubImage3DEXT; + +GLEW_FUN_EXPORT PFNGLCULLPARAMETERDVEXTPROC __glewCullParameterdvEXT; +GLEW_FUN_EXPORT PFNGLCULLPARAMETERFVEXTPROC __glewCullParameterfvEXT; + +GLEW_FUN_EXPORT PFNGLDEPTHBOUNDSEXTPROC __glewDepthBoundsEXT; + +GLEW_FUN_EXPORT PFNGLDRAWRANGEELEMENTSEXTPROC __glewDrawRangeElementsEXT; + +GLEW_FUN_EXPORT PFNGLFOGCOORDPOINTEREXTPROC __glewFogCoordPointerEXT; +GLEW_FUN_EXPORT PFNGLFOGCOORDDEXTPROC __glewFogCoorddEXT; +GLEW_FUN_EXPORT PFNGLFOGCOORDDVEXTPROC __glewFogCoorddvEXT; +GLEW_FUN_EXPORT PFNGLFOGCOORDFEXTPROC __glewFogCoordfEXT; +GLEW_FUN_EXPORT PFNGLFOGCOORDFVEXTPROC __glewFogCoordfvEXT; + +GLEW_FUN_EXPORT PFNGLFRAGMENTCOLORMATERIALEXTPROC __glewFragmentColorMaterialEXT; +GLEW_FUN_EXPORT PFNGLFRAGMENTLIGHTMODELFEXTPROC __glewFragmentLightModelfEXT; +GLEW_FUN_EXPORT PFNGLFRAGMENTLIGHTMODELFVEXTPROC __glewFragmentLightModelfvEXT; +GLEW_FUN_EXPORT PFNGLFRAGMENTLIGHTMODELIEXTPROC __glewFragmentLightModeliEXT; +GLEW_FUN_EXPORT PFNGLFRAGMENTLIGHTMODELIVEXTPROC __glewFragmentLightModelivEXT; +GLEW_FUN_EXPORT PFNGLFRAGMENTLIGHTFEXTPROC __glewFragmentLightfEXT; +GLEW_FUN_EXPORT PFNGLFRAGMENTLIGHTFVEXTPROC __glewFragmentLightfvEXT; +GLEW_FUN_EXPORT PFNGLFRAGMENTLIGHTIEXTPROC __glewFragmentLightiEXT; +GLEW_FUN_EXPORT PFNGLFRAGMENTLIGHTIVEXTPROC __glewFragmentLightivEXT; +GLEW_FUN_EXPORT PFNGLFRAGMENTMATERIALFEXTPROC __glewFragmentMaterialfEXT; +GLEW_FUN_EXPORT PFNGLFRAGMENTMATERIALFVEXTPROC __glewFragmentMaterialfvEXT; +GLEW_FUN_EXPORT PFNGLFRAGMENTMATERIALIEXTPROC __glewFragmentMaterialiEXT; +GLEW_FUN_EXPORT PFNGLFRAGMENTMATERIALIVEXTPROC __glewFragmentMaterialivEXT; +GLEW_FUN_EXPORT PFNGLGETFRAGMENTLIGHTFVEXTPROC __glewGetFragmentLightfvEXT; +GLEW_FUN_EXPORT PFNGLGETFRAGMENTLIGHTIVEXTPROC __glewGetFragmentLightivEXT; +GLEW_FUN_EXPORT PFNGLGETFRAGMENTMATERIALFVEXTPROC __glewGetFragmentMaterialfvEXT; +GLEW_FUN_EXPORT PFNGLGETFRAGMENTMATERIALIVEXTPROC __glewGetFragmentMaterialivEXT; +GLEW_FUN_EXPORT PFNGLLIGHTENVIEXTPROC __glewLightEnviEXT; + +GLEW_FUN_EXPORT PFNGLBLITFRAMEBUFFEREXTPROC __glewBlitFramebufferEXT; + +GLEW_FUN_EXPORT PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC __glewRenderbufferStorageMultisampleEXT; + +GLEW_FUN_EXPORT PFNGLBINDFRAMEBUFFEREXTPROC __glewBindFramebufferEXT; +GLEW_FUN_EXPORT PFNGLBINDRENDERBUFFEREXTPROC __glewBindRenderbufferEXT; +GLEW_FUN_EXPORT PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC __glewCheckFramebufferStatusEXT; +GLEW_FUN_EXPORT PFNGLDELETEFRAMEBUFFERSEXTPROC __glewDeleteFramebuffersEXT; +GLEW_FUN_EXPORT PFNGLDELETERENDERBUFFERSEXTPROC __glewDeleteRenderbuffersEXT; +GLEW_FUN_EXPORT PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC __glewFramebufferRenderbufferEXT; +GLEW_FUN_EXPORT PFNGLFRAMEBUFFERTEXTURE1DEXTPROC __glewFramebufferTexture1DEXT; +GLEW_FUN_EXPORT PFNGLFRAMEBUFFERTEXTURE2DEXTPROC __glewFramebufferTexture2DEXT; +GLEW_FUN_EXPORT PFNGLFRAMEBUFFERTEXTURE3DEXTPROC __glewFramebufferTexture3DEXT; +GLEW_FUN_EXPORT PFNGLGENFRAMEBUFFERSEXTPROC __glewGenFramebuffersEXT; +GLEW_FUN_EXPORT PFNGLGENRENDERBUFFERSEXTPROC __glewGenRenderbuffersEXT; +GLEW_FUN_EXPORT PFNGLGENERATEMIPMAPEXTPROC __glewGenerateMipmapEXT; +GLEW_FUN_EXPORT PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC __glewGetFramebufferAttachmentParameterivEXT; +GLEW_FUN_EXPORT PFNGLGETRENDERBUFFERPARAMETERIVEXTPROC __glewGetRenderbufferParameterivEXT; +GLEW_FUN_EXPORT PFNGLISFRAMEBUFFEREXTPROC __glewIsFramebufferEXT; +GLEW_FUN_EXPORT PFNGLISRENDERBUFFEREXTPROC __glewIsRenderbufferEXT; +GLEW_FUN_EXPORT PFNGLRENDERBUFFERSTORAGEEXTPROC __glewRenderbufferStorageEXT; + +GLEW_FUN_EXPORT PFNGLGETHISTOGRAMEXTPROC __glewGetHistogramEXT; +GLEW_FUN_EXPORT PFNGLGETHISTOGRAMPARAMETERFVEXTPROC __glewGetHistogramParameterfvEXT; +GLEW_FUN_EXPORT PFNGLGETHISTOGRAMPARAMETERIVEXTPROC __glewGetHistogramParameterivEXT; +GLEW_FUN_EXPORT PFNGLGETMINMAXEXTPROC __glewGetMinmaxEXT; +GLEW_FUN_EXPORT PFNGLGETMINMAXPARAMETERFVEXTPROC __glewGetMinmaxParameterfvEXT; +GLEW_FUN_EXPORT PFNGLGETMINMAXPARAMETERIVEXTPROC __glewGetMinmaxParameterivEXT; +GLEW_FUN_EXPORT PFNGLHISTOGRAMEXTPROC __glewHistogramEXT; +GLEW_FUN_EXPORT PFNGLMINMAXEXTPROC __glewMinmaxEXT; +GLEW_FUN_EXPORT PFNGLRESETHISTOGRAMEXTPROC __glewResetHistogramEXT; +GLEW_FUN_EXPORT PFNGLRESETMINMAXEXTPROC __glewResetMinmaxEXT; + +GLEW_FUN_EXPORT PFNGLINDEXFUNCEXTPROC __glewIndexFuncEXT; + +GLEW_FUN_EXPORT PFNGLINDEXMATERIALEXTPROC __glewIndexMaterialEXT; + +GLEW_FUN_EXPORT PFNGLAPPLYTEXTUREEXTPROC __glewApplyTextureEXT; +GLEW_FUN_EXPORT PFNGLTEXTURELIGHTEXTPROC __glewTextureLightEXT; +GLEW_FUN_EXPORT PFNGLTEXTUREMATERIALEXTPROC __glewTextureMaterialEXT; + +GLEW_FUN_EXPORT PFNGLMULTIDRAWARRAYSEXTPROC __glewMultiDrawArraysEXT; +GLEW_FUN_EXPORT PFNGLMULTIDRAWELEMENTSEXTPROC __glewMultiDrawElementsEXT; + +GLEW_FUN_EXPORT PFNGLSAMPLEMASKEXTPROC __glewSampleMaskEXT; +GLEW_FUN_EXPORT PFNGLSAMPLEPATTERNEXTPROC __glewSamplePatternEXT; + +GLEW_FUN_EXPORT PFNGLCOLORTABLEEXTPROC __glewColorTableEXT; +GLEW_FUN_EXPORT PFNGLGETCOLORTABLEEXTPROC __glewGetColorTableEXT; +GLEW_FUN_EXPORT PFNGLGETCOLORTABLEPARAMETERFVEXTPROC __glewGetColorTableParameterfvEXT; +GLEW_FUN_EXPORT PFNGLGETCOLORTABLEPARAMETERIVEXTPROC __glewGetColorTableParameterivEXT; + +GLEW_FUN_EXPORT PFNGLGETPIXELTRANSFORMPARAMETERFVEXTPROC __glewGetPixelTransformParameterfvEXT; +GLEW_FUN_EXPORT PFNGLGETPIXELTRANSFORMPARAMETERIVEXTPROC __glewGetPixelTransformParameterivEXT; +GLEW_FUN_EXPORT PFNGLPIXELTRANSFORMPARAMETERFEXTPROC __glewPixelTransformParameterfEXT; +GLEW_FUN_EXPORT PFNGLPIXELTRANSFORMPARAMETERFVEXTPROC __glewPixelTransformParameterfvEXT; +GLEW_FUN_EXPORT PFNGLPIXELTRANSFORMPARAMETERIEXTPROC __glewPixelTransformParameteriEXT; +GLEW_FUN_EXPORT PFNGLPIXELTRANSFORMPARAMETERIVEXTPROC __glewPixelTransformParameterivEXT; + +GLEW_FUN_EXPORT PFNGLPOINTPARAMETERFEXTPROC __glewPointParameterfEXT; +GLEW_FUN_EXPORT PFNGLPOINTPARAMETERFVEXTPROC __glewPointParameterfvEXT; + +GLEW_FUN_EXPORT PFNGLPOLYGONOFFSETEXTPROC __glewPolygonOffsetEXT; + +GLEW_FUN_EXPORT PFNGLBEGINSCENEEXTPROC __glewBeginSceneEXT; +GLEW_FUN_EXPORT PFNGLENDSCENEEXTPROC __glewEndSceneEXT; + +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3BEXTPROC __glewSecondaryColor3bEXT; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3BVEXTPROC __glewSecondaryColor3bvEXT; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3DEXTPROC __glewSecondaryColor3dEXT; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3DVEXTPROC __glewSecondaryColor3dvEXT; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3FEXTPROC __glewSecondaryColor3fEXT; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3FVEXTPROC __glewSecondaryColor3fvEXT; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3IEXTPROC __glewSecondaryColor3iEXT; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3IVEXTPROC __glewSecondaryColor3ivEXT; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3SEXTPROC __glewSecondaryColor3sEXT; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3SVEXTPROC __glewSecondaryColor3svEXT; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3UBEXTPROC __glewSecondaryColor3ubEXT; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3UBVEXTPROC __glewSecondaryColor3ubvEXT; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3UIEXTPROC __glewSecondaryColor3uiEXT; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3UIVEXTPROC __glewSecondaryColor3uivEXT; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3USEXTPROC __glewSecondaryColor3usEXT; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3USVEXTPROC __glewSecondaryColor3usvEXT; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLORPOINTEREXTPROC __glewSecondaryColorPointerEXT; + +GLEW_FUN_EXPORT PFNGLACTIVESTENCILFACEEXTPROC __glewActiveStencilFaceEXT; + +GLEW_FUN_EXPORT PFNGLTEXSUBIMAGE1DEXTPROC __glewTexSubImage1DEXT; +GLEW_FUN_EXPORT PFNGLTEXSUBIMAGE2DEXTPROC __glewTexSubImage2DEXT; +GLEW_FUN_EXPORT PFNGLTEXSUBIMAGE3DEXTPROC __glewTexSubImage3DEXT; + +GLEW_FUN_EXPORT PFNGLTEXIMAGE3DEXTPROC __glewTexImage3DEXT; + +GLEW_FUN_EXPORT PFNGLARETEXTURESRESIDENTEXTPROC __glewAreTexturesResidentEXT; +GLEW_FUN_EXPORT PFNGLBINDTEXTUREEXTPROC __glewBindTextureEXT; +GLEW_FUN_EXPORT PFNGLDELETETEXTURESEXTPROC __glewDeleteTexturesEXT; +GLEW_FUN_EXPORT PFNGLGENTEXTURESEXTPROC __glewGenTexturesEXT; +GLEW_FUN_EXPORT PFNGLISTEXTUREEXTPROC __glewIsTextureEXT; +GLEW_FUN_EXPORT PFNGLPRIORITIZETEXTURESEXTPROC __glewPrioritizeTexturesEXT; + +GLEW_FUN_EXPORT PFNGLTEXTURENORMALEXTPROC __glewTextureNormalEXT; + +GLEW_FUN_EXPORT PFNGLARRAYELEMENTEXTPROC __glewArrayElementEXT; +GLEW_FUN_EXPORT PFNGLCOLORPOINTEREXTPROC __glewColorPointerEXT; +GLEW_FUN_EXPORT PFNGLDRAWARRAYSEXTPROC __glewDrawArraysEXT; +GLEW_FUN_EXPORT PFNGLEDGEFLAGPOINTEREXTPROC __glewEdgeFlagPointerEXT; +GLEW_FUN_EXPORT PFNGLGETPOINTERVEXTPROC __glewGetPointervEXT; +GLEW_FUN_EXPORT PFNGLINDEXPOINTEREXTPROC __glewIndexPointerEXT; +GLEW_FUN_EXPORT PFNGLNORMALPOINTEREXTPROC __glewNormalPointerEXT; +GLEW_FUN_EXPORT PFNGLTEXCOORDPOINTEREXTPROC __glewTexCoordPointerEXT; +GLEW_FUN_EXPORT PFNGLVERTEXPOINTEREXTPROC __glewVertexPointerEXT; + +GLEW_FUN_EXPORT PFNGLBEGINVERTEXSHADEREXTPROC __glewBeginVertexShaderEXT; +GLEW_FUN_EXPORT PFNGLBINDLIGHTPARAMETEREXTPROC __glewBindLightParameterEXT; +GLEW_FUN_EXPORT PFNGLBINDMATERIALPARAMETEREXTPROC __glewBindMaterialParameterEXT; +GLEW_FUN_EXPORT PFNGLBINDPARAMETEREXTPROC __glewBindParameterEXT; +GLEW_FUN_EXPORT PFNGLBINDTEXGENPARAMETEREXTPROC __glewBindTexGenParameterEXT; +GLEW_FUN_EXPORT PFNGLBINDTEXTUREUNITPARAMETEREXTPROC __glewBindTextureUnitParameterEXT; +GLEW_FUN_EXPORT PFNGLBINDVERTEXSHADEREXTPROC __glewBindVertexShaderEXT; +GLEW_FUN_EXPORT PFNGLDELETEVERTEXSHADEREXTPROC __glewDeleteVertexShaderEXT; +GLEW_FUN_EXPORT PFNGLDISABLEVARIANTCLIENTSTATEEXTPROC __glewDisableVariantClientStateEXT; +GLEW_FUN_EXPORT PFNGLENABLEVARIANTCLIENTSTATEEXTPROC __glewEnableVariantClientStateEXT; +GLEW_FUN_EXPORT PFNGLENDVERTEXSHADEREXTPROC __glewEndVertexShaderEXT; +GLEW_FUN_EXPORT PFNGLEXTRACTCOMPONENTEXTPROC __glewExtractComponentEXT; +GLEW_FUN_EXPORT PFNGLGENSYMBOLSEXTPROC __glewGenSymbolsEXT; +GLEW_FUN_EXPORT PFNGLGENVERTEXSHADERSEXTPROC __glewGenVertexShadersEXT; +GLEW_FUN_EXPORT PFNGLGETINVARIANTBOOLEANVEXTPROC __glewGetInvariantBooleanvEXT; +GLEW_FUN_EXPORT PFNGLGETINVARIANTFLOATVEXTPROC __glewGetInvariantFloatvEXT; +GLEW_FUN_EXPORT PFNGLGETINVARIANTINTEGERVEXTPROC __glewGetInvariantIntegervEXT; +GLEW_FUN_EXPORT PFNGLGETLOCALCONSTANTBOOLEANVEXTPROC __glewGetLocalConstantBooleanvEXT; +GLEW_FUN_EXPORT PFNGLGETLOCALCONSTANTFLOATVEXTPROC __glewGetLocalConstantFloatvEXT; +GLEW_FUN_EXPORT PFNGLGETLOCALCONSTANTINTEGERVEXTPROC __glewGetLocalConstantIntegervEXT; +GLEW_FUN_EXPORT PFNGLGETVARIANTBOOLEANVEXTPROC __glewGetVariantBooleanvEXT; +GLEW_FUN_EXPORT PFNGLGETVARIANTFLOATVEXTPROC __glewGetVariantFloatvEXT; +GLEW_FUN_EXPORT PFNGLGETVARIANTINTEGERVEXTPROC __glewGetVariantIntegervEXT; +GLEW_FUN_EXPORT PFNGLGETVARIANTPOINTERVEXTPROC __glewGetVariantPointervEXT; +GLEW_FUN_EXPORT PFNGLINSERTCOMPONENTEXTPROC __glewInsertComponentEXT; +GLEW_FUN_EXPORT PFNGLISVARIANTENABLEDEXTPROC __glewIsVariantEnabledEXT; +GLEW_FUN_EXPORT PFNGLSETINVARIANTEXTPROC __glewSetInvariantEXT; +GLEW_FUN_EXPORT PFNGLSETLOCALCONSTANTEXTPROC __glewSetLocalConstantEXT; +GLEW_FUN_EXPORT PFNGLSHADEROP1EXTPROC __glewShaderOp1EXT; +GLEW_FUN_EXPORT PFNGLSHADEROP2EXTPROC __glewShaderOp2EXT; +GLEW_FUN_EXPORT PFNGLSHADEROP3EXTPROC __glewShaderOp3EXT; +GLEW_FUN_EXPORT PFNGLSWIZZLEEXTPROC __glewSwizzleEXT; +GLEW_FUN_EXPORT PFNGLVARIANTPOINTEREXTPROC __glewVariantPointerEXT; +GLEW_FUN_EXPORT PFNGLVARIANTBVEXTPROC __glewVariantbvEXT; +GLEW_FUN_EXPORT PFNGLVARIANTDVEXTPROC __glewVariantdvEXT; +GLEW_FUN_EXPORT PFNGLVARIANTFVEXTPROC __glewVariantfvEXT; +GLEW_FUN_EXPORT PFNGLVARIANTIVEXTPROC __glewVariantivEXT; +GLEW_FUN_EXPORT PFNGLVARIANTSVEXTPROC __glewVariantsvEXT; +GLEW_FUN_EXPORT PFNGLVARIANTUBVEXTPROC __glewVariantubvEXT; +GLEW_FUN_EXPORT PFNGLVARIANTUIVEXTPROC __glewVariantuivEXT; +GLEW_FUN_EXPORT PFNGLVARIANTUSVEXTPROC __glewVariantusvEXT; +GLEW_FUN_EXPORT PFNGLWRITEMASKEXTPROC __glewWriteMaskEXT; + +GLEW_FUN_EXPORT PFNGLVERTEXWEIGHTPOINTEREXTPROC __glewVertexWeightPointerEXT; +GLEW_FUN_EXPORT PFNGLVERTEXWEIGHTFEXTPROC __glewVertexWeightfEXT; +GLEW_FUN_EXPORT PFNGLVERTEXWEIGHTFVEXTPROC __glewVertexWeightfvEXT; + +GLEW_FUN_EXPORT PFNGLSTRINGMARKERGREMEDYPROC __glewStringMarkerGREMEDY; + +GLEW_FUN_EXPORT PFNGLGETIMAGETRANSFORMPARAMETERFVHPPROC __glewGetImageTransformParameterfvHP; +GLEW_FUN_EXPORT PFNGLGETIMAGETRANSFORMPARAMETERIVHPPROC __glewGetImageTransformParameterivHP; +GLEW_FUN_EXPORT PFNGLIMAGETRANSFORMPARAMETERFHPPROC __glewImageTransformParameterfHP; +GLEW_FUN_EXPORT PFNGLIMAGETRANSFORMPARAMETERFVHPPROC __glewImageTransformParameterfvHP; +GLEW_FUN_EXPORT PFNGLIMAGETRANSFORMPARAMETERIHPPROC __glewImageTransformParameteriHP; +GLEW_FUN_EXPORT PFNGLIMAGETRANSFORMPARAMETERIVHPPROC __glewImageTransformParameterivHP; + +GLEW_FUN_EXPORT PFNGLMULTIMODEDRAWARRAYSIBMPROC __glewMultiModeDrawArraysIBM; +GLEW_FUN_EXPORT PFNGLMULTIMODEDRAWELEMENTSIBMPROC __glewMultiModeDrawElementsIBM; + +GLEW_FUN_EXPORT PFNGLCOLORPOINTERLISTIBMPROC __glewColorPointerListIBM; +GLEW_FUN_EXPORT PFNGLEDGEFLAGPOINTERLISTIBMPROC __glewEdgeFlagPointerListIBM; +GLEW_FUN_EXPORT PFNGLFOGCOORDPOINTERLISTIBMPROC __glewFogCoordPointerListIBM; +GLEW_FUN_EXPORT PFNGLINDEXPOINTERLISTIBMPROC __glewIndexPointerListIBM; +GLEW_FUN_EXPORT PFNGLNORMALPOINTERLISTIBMPROC __glewNormalPointerListIBM; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLORPOINTERLISTIBMPROC __glewSecondaryColorPointerListIBM; +GLEW_FUN_EXPORT PFNGLTEXCOORDPOINTERLISTIBMPROC __glewTexCoordPointerListIBM; +GLEW_FUN_EXPORT PFNGLVERTEXPOINTERLISTIBMPROC __glewVertexPointerListIBM; + +GLEW_FUN_EXPORT PFNGLCOLORPOINTERVINTELPROC __glewColorPointervINTEL; +GLEW_FUN_EXPORT PFNGLNORMALPOINTERVINTELPROC __glewNormalPointervINTEL; +GLEW_FUN_EXPORT PFNGLTEXCOORDPOINTERVINTELPROC __glewTexCoordPointervINTEL; +GLEW_FUN_EXPORT PFNGLVERTEXPOINTERVINTELPROC __glewVertexPointervINTEL; + +GLEW_FUN_EXPORT PFNGLTEXSCISSORFUNCINTELPROC __glewTexScissorFuncINTEL; +GLEW_FUN_EXPORT PFNGLTEXSCISSORINTELPROC __glewTexScissorINTEL; + +GLEW_FUN_EXPORT PFNGLBUFFERREGIONENABLEDEXTPROC __glewBufferRegionEnabledEXT; +GLEW_FUN_EXPORT PFNGLDELETEBUFFERREGIONEXTPROC __glewDeleteBufferRegionEXT; +GLEW_FUN_EXPORT PFNGLDRAWBUFFERREGIONEXTPROC __glewDrawBufferRegionEXT; +GLEW_FUN_EXPORT PFNGLNEWBUFFERREGIONEXTPROC __glewNewBufferRegionEXT; +GLEW_FUN_EXPORT PFNGLREADBUFFERREGIONEXTPROC __glewReadBufferRegionEXT; + +GLEW_FUN_EXPORT PFNGLRESIZEBUFFERSMESAPROC __glewResizeBuffersMESA; + +GLEW_FUN_EXPORT PFNGLWINDOWPOS2DMESAPROC __glewWindowPos2dMESA; +GLEW_FUN_EXPORT PFNGLWINDOWPOS2DVMESAPROC __glewWindowPos2dvMESA; +GLEW_FUN_EXPORT PFNGLWINDOWPOS2FMESAPROC __glewWindowPos2fMESA; +GLEW_FUN_EXPORT PFNGLWINDOWPOS2FVMESAPROC __glewWindowPos2fvMESA; +GLEW_FUN_EXPORT PFNGLWINDOWPOS2IMESAPROC __glewWindowPos2iMESA; +GLEW_FUN_EXPORT PFNGLWINDOWPOS2IVMESAPROC __glewWindowPos2ivMESA; +GLEW_FUN_EXPORT PFNGLWINDOWPOS2SMESAPROC __glewWindowPos2sMESA; +GLEW_FUN_EXPORT PFNGLWINDOWPOS2SVMESAPROC __glewWindowPos2svMESA; +GLEW_FUN_EXPORT PFNGLWINDOWPOS3DMESAPROC __glewWindowPos3dMESA; +GLEW_FUN_EXPORT PFNGLWINDOWPOS3DVMESAPROC __glewWindowPos3dvMESA; +GLEW_FUN_EXPORT PFNGLWINDOWPOS3FMESAPROC __glewWindowPos3fMESA; +GLEW_FUN_EXPORT PFNGLWINDOWPOS3FVMESAPROC __glewWindowPos3fvMESA; +GLEW_FUN_EXPORT PFNGLWINDOWPOS3IMESAPROC __glewWindowPos3iMESA; +GLEW_FUN_EXPORT PFNGLWINDOWPOS3IVMESAPROC __glewWindowPos3ivMESA; +GLEW_FUN_EXPORT PFNGLWINDOWPOS3SMESAPROC __glewWindowPos3sMESA; +GLEW_FUN_EXPORT PFNGLWINDOWPOS3SVMESAPROC __glewWindowPos3svMESA; +GLEW_FUN_EXPORT PFNGLWINDOWPOS4DMESAPROC __glewWindowPos4dMESA; +GLEW_FUN_EXPORT PFNGLWINDOWPOS4DVMESAPROC __glewWindowPos4dvMESA; +GLEW_FUN_EXPORT PFNGLWINDOWPOS4FMESAPROC __glewWindowPos4fMESA; +GLEW_FUN_EXPORT PFNGLWINDOWPOS4FVMESAPROC __glewWindowPos4fvMESA; +GLEW_FUN_EXPORT PFNGLWINDOWPOS4IMESAPROC __glewWindowPos4iMESA; +GLEW_FUN_EXPORT PFNGLWINDOWPOS4IVMESAPROC __glewWindowPos4ivMESA; +GLEW_FUN_EXPORT PFNGLWINDOWPOS4SMESAPROC __glewWindowPos4sMESA; +GLEW_FUN_EXPORT PFNGLWINDOWPOS4SVMESAPROC __glewWindowPos4svMESA; + +GLEW_FUN_EXPORT PFNGLEVALMAPSNVPROC __glewEvalMapsNV; +GLEW_FUN_EXPORT PFNGLGETMAPATTRIBPARAMETERFVNVPROC __glewGetMapAttribParameterfvNV; +GLEW_FUN_EXPORT PFNGLGETMAPATTRIBPARAMETERIVNVPROC __glewGetMapAttribParameterivNV; +GLEW_FUN_EXPORT PFNGLGETMAPCONTROLPOINTSNVPROC __glewGetMapControlPointsNV; +GLEW_FUN_EXPORT PFNGLGETMAPPARAMETERFVNVPROC __glewGetMapParameterfvNV; +GLEW_FUN_EXPORT PFNGLGETMAPPARAMETERIVNVPROC __glewGetMapParameterivNV; +GLEW_FUN_EXPORT PFNGLMAPCONTROLPOINTSNVPROC __glewMapControlPointsNV; +GLEW_FUN_EXPORT PFNGLMAPPARAMETERFVNVPROC __glewMapParameterfvNV; +GLEW_FUN_EXPORT PFNGLMAPPARAMETERIVNVPROC __glewMapParameterivNV; + +GLEW_FUN_EXPORT PFNGLDELETEFENCESNVPROC __glewDeleteFencesNV; +GLEW_FUN_EXPORT PFNGLFINISHFENCENVPROC __glewFinishFenceNV; +GLEW_FUN_EXPORT PFNGLGENFENCESNVPROC __glewGenFencesNV; +GLEW_FUN_EXPORT PFNGLGETFENCEIVNVPROC __glewGetFenceivNV; +GLEW_FUN_EXPORT PFNGLISFENCENVPROC __glewIsFenceNV; +GLEW_FUN_EXPORT PFNGLSETFENCENVPROC __glewSetFenceNV; +GLEW_FUN_EXPORT PFNGLTESTFENCENVPROC __glewTestFenceNV; + +GLEW_FUN_EXPORT PFNGLGETPROGRAMNAMEDPARAMETERDVNVPROC __glewGetProgramNamedParameterdvNV; +GLEW_FUN_EXPORT PFNGLGETPROGRAMNAMEDPARAMETERFVNVPROC __glewGetProgramNamedParameterfvNV; +GLEW_FUN_EXPORT PFNGLPROGRAMNAMEDPARAMETER4DNVPROC __glewProgramNamedParameter4dNV; +GLEW_FUN_EXPORT PFNGLPROGRAMNAMEDPARAMETER4DVNVPROC __glewProgramNamedParameter4dvNV; +GLEW_FUN_EXPORT PFNGLPROGRAMNAMEDPARAMETER4FNVPROC __glewProgramNamedParameter4fNV; +GLEW_FUN_EXPORT PFNGLPROGRAMNAMEDPARAMETER4FVNVPROC __glewProgramNamedParameter4fvNV; + +GLEW_FUN_EXPORT PFNGLCOLOR3HNVPROC __glewColor3hNV; +GLEW_FUN_EXPORT PFNGLCOLOR3HVNVPROC __glewColor3hvNV; +GLEW_FUN_EXPORT PFNGLCOLOR4HNVPROC __glewColor4hNV; +GLEW_FUN_EXPORT PFNGLCOLOR4HVNVPROC __glewColor4hvNV; +GLEW_FUN_EXPORT PFNGLFOGCOORDHNVPROC __glewFogCoordhNV; +GLEW_FUN_EXPORT PFNGLFOGCOORDHVNVPROC __glewFogCoordhvNV; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1HNVPROC __glewMultiTexCoord1hNV; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1HVNVPROC __glewMultiTexCoord1hvNV; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2HNVPROC __glewMultiTexCoord2hNV; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2HVNVPROC __glewMultiTexCoord2hvNV; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3HNVPROC __glewMultiTexCoord3hNV; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3HVNVPROC __glewMultiTexCoord3hvNV; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4HNVPROC __glewMultiTexCoord4hNV; +GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4HVNVPROC __glewMultiTexCoord4hvNV; +GLEW_FUN_EXPORT PFNGLNORMAL3HNVPROC __glewNormal3hNV; +GLEW_FUN_EXPORT PFNGLNORMAL3HVNVPROC __glewNormal3hvNV; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3HNVPROC __glewSecondaryColor3hNV; +GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3HVNVPROC __glewSecondaryColor3hvNV; +GLEW_FUN_EXPORT PFNGLTEXCOORD1HNVPROC __glewTexCoord1hNV; +GLEW_FUN_EXPORT PFNGLTEXCOORD1HVNVPROC __glewTexCoord1hvNV; +GLEW_FUN_EXPORT PFNGLTEXCOORD2HNVPROC __glewTexCoord2hNV; +GLEW_FUN_EXPORT PFNGLTEXCOORD2HVNVPROC __glewTexCoord2hvNV; +GLEW_FUN_EXPORT PFNGLTEXCOORD3HNVPROC __glewTexCoord3hNV; +GLEW_FUN_EXPORT PFNGLTEXCOORD3HVNVPROC __glewTexCoord3hvNV; +GLEW_FUN_EXPORT PFNGLTEXCOORD4HNVPROC __glewTexCoord4hNV; +GLEW_FUN_EXPORT PFNGLTEXCOORD4HVNVPROC __glewTexCoord4hvNV; +GLEW_FUN_EXPORT PFNGLVERTEX2HNVPROC __glewVertex2hNV; +GLEW_FUN_EXPORT PFNGLVERTEX2HVNVPROC __glewVertex2hvNV; +GLEW_FUN_EXPORT PFNGLVERTEX3HNVPROC __glewVertex3hNV; +GLEW_FUN_EXPORT PFNGLVERTEX3HVNVPROC __glewVertex3hvNV; +GLEW_FUN_EXPORT PFNGLVERTEX4HNVPROC __glewVertex4hNV; +GLEW_FUN_EXPORT PFNGLVERTEX4HVNVPROC __glewVertex4hvNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1HNVPROC __glewVertexAttrib1hNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1HVNVPROC __glewVertexAttrib1hvNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2HNVPROC __glewVertexAttrib2hNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2HVNVPROC __glewVertexAttrib2hvNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3HNVPROC __glewVertexAttrib3hNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3HVNVPROC __glewVertexAttrib3hvNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4HNVPROC __glewVertexAttrib4hNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4HVNVPROC __glewVertexAttrib4hvNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS1HVNVPROC __glewVertexAttribs1hvNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS2HVNVPROC __glewVertexAttribs2hvNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS3HVNVPROC __glewVertexAttribs3hvNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS4HVNVPROC __glewVertexAttribs4hvNV; +GLEW_FUN_EXPORT PFNGLVERTEXWEIGHTHNVPROC __glewVertexWeighthNV; +GLEW_FUN_EXPORT PFNGLVERTEXWEIGHTHVNVPROC __glewVertexWeighthvNV; + +GLEW_FUN_EXPORT PFNGLBEGINOCCLUSIONQUERYNVPROC __glewBeginOcclusionQueryNV; +GLEW_FUN_EXPORT PFNGLDELETEOCCLUSIONQUERIESNVPROC __glewDeleteOcclusionQueriesNV; +GLEW_FUN_EXPORT PFNGLENDOCCLUSIONQUERYNVPROC __glewEndOcclusionQueryNV; +GLEW_FUN_EXPORT PFNGLGENOCCLUSIONQUERIESNVPROC __glewGenOcclusionQueriesNV; +GLEW_FUN_EXPORT PFNGLGETOCCLUSIONQUERYIVNVPROC __glewGetOcclusionQueryivNV; +GLEW_FUN_EXPORT PFNGLGETOCCLUSIONQUERYUIVNVPROC __glewGetOcclusionQueryuivNV; +GLEW_FUN_EXPORT PFNGLISOCCLUSIONQUERYNVPROC __glewIsOcclusionQueryNV; + +GLEW_FUN_EXPORT PFNGLFLUSHPIXELDATARANGENVPROC __glewFlushPixelDataRangeNV; +GLEW_FUN_EXPORT PFNGLPIXELDATARANGENVPROC __glewPixelDataRangeNV; + +GLEW_FUN_EXPORT PFNGLPOINTPARAMETERINVPROC __glewPointParameteriNV; +GLEW_FUN_EXPORT PFNGLPOINTPARAMETERIVNVPROC __glewPointParameterivNV; + +GLEW_FUN_EXPORT PFNGLPRIMITIVERESTARTINDEXNVPROC __glewPrimitiveRestartIndexNV; +GLEW_FUN_EXPORT PFNGLPRIMITIVERESTARTNVPROC __glewPrimitiveRestartNV; + +GLEW_FUN_EXPORT PFNGLCOMBINERINPUTNVPROC __glewCombinerInputNV; +GLEW_FUN_EXPORT PFNGLCOMBINEROUTPUTNVPROC __glewCombinerOutputNV; +GLEW_FUN_EXPORT PFNGLCOMBINERPARAMETERFNVPROC __glewCombinerParameterfNV; +GLEW_FUN_EXPORT PFNGLCOMBINERPARAMETERFVNVPROC __glewCombinerParameterfvNV; +GLEW_FUN_EXPORT PFNGLCOMBINERPARAMETERINVPROC __glewCombinerParameteriNV; +GLEW_FUN_EXPORT PFNGLCOMBINERPARAMETERIVNVPROC __glewCombinerParameterivNV; +GLEW_FUN_EXPORT PFNGLFINALCOMBINERINPUTNVPROC __glewFinalCombinerInputNV; +GLEW_FUN_EXPORT PFNGLGETCOMBINERINPUTPARAMETERFVNVPROC __glewGetCombinerInputParameterfvNV; +GLEW_FUN_EXPORT PFNGLGETCOMBINERINPUTPARAMETERIVNVPROC __glewGetCombinerInputParameterivNV; +GLEW_FUN_EXPORT PFNGLGETCOMBINEROUTPUTPARAMETERFVNVPROC __glewGetCombinerOutputParameterfvNV; +GLEW_FUN_EXPORT PFNGLGETCOMBINEROUTPUTPARAMETERIVNVPROC __glewGetCombinerOutputParameterivNV; +GLEW_FUN_EXPORT PFNGLGETFINALCOMBINERINPUTPARAMETERFVNVPROC __glewGetFinalCombinerInputParameterfvNV; +GLEW_FUN_EXPORT PFNGLGETFINALCOMBINERINPUTPARAMETERIVNVPROC __glewGetFinalCombinerInputParameterivNV; + +GLEW_FUN_EXPORT PFNGLCOMBINERSTAGEPARAMETERFVNVPROC __glewCombinerStageParameterfvNV; +GLEW_FUN_EXPORT PFNGLGETCOMBINERSTAGEPARAMETERFVNVPROC __glewGetCombinerStageParameterfvNV; + +GLEW_FUN_EXPORT PFNGLFLUSHVERTEXARRAYRANGENVPROC __glewFlushVertexArrayRangeNV; +GLEW_FUN_EXPORT PFNGLVERTEXARRAYRANGENVPROC __glewVertexArrayRangeNV; + +GLEW_FUN_EXPORT PFNGLAREPROGRAMSRESIDENTNVPROC __glewAreProgramsResidentNV; +GLEW_FUN_EXPORT PFNGLBINDPROGRAMNVPROC __glewBindProgramNV; +GLEW_FUN_EXPORT PFNGLDELETEPROGRAMSNVPROC __glewDeleteProgramsNV; +GLEW_FUN_EXPORT PFNGLEXECUTEPROGRAMNVPROC __glewExecuteProgramNV; +GLEW_FUN_EXPORT PFNGLGENPROGRAMSNVPROC __glewGenProgramsNV; +GLEW_FUN_EXPORT PFNGLGETPROGRAMPARAMETERDVNVPROC __glewGetProgramParameterdvNV; +GLEW_FUN_EXPORT PFNGLGETPROGRAMPARAMETERFVNVPROC __glewGetProgramParameterfvNV; +GLEW_FUN_EXPORT PFNGLGETPROGRAMSTRINGNVPROC __glewGetProgramStringNV; +GLEW_FUN_EXPORT PFNGLGETPROGRAMIVNVPROC __glewGetProgramivNV; +GLEW_FUN_EXPORT PFNGLGETTRACKMATRIXIVNVPROC __glewGetTrackMatrixivNV; +GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBPOINTERVNVPROC __glewGetVertexAttribPointervNV; +GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBDVNVPROC __glewGetVertexAttribdvNV; +GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBFVNVPROC __glewGetVertexAttribfvNV; +GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBIVNVPROC __glewGetVertexAttribivNV; +GLEW_FUN_EXPORT PFNGLISPROGRAMNVPROC __glewIsProgramNV; +GLEW_FUN_EXPORT PFNGLLOADPROGRAMNVPROC __glewLoadProgramNV; +GLEW_FUN_EXPORT PFNGLPROGRAMPARAMETER4DNVPROC __glewProgramParameter4dNV; +GLEW_FUN_EXPORT PFNGLPROGRAMPARAMETER4DVNVPROC __glewProgramParameter4dvNV; +GLEW_FUN_EXPORT PFNGLPROGRAMPARAMETER4FNVPROC __glewProgramParameter4fNV; +GLEW_FUN_EXPORT PFNGLPROGRAMPARAMETER4FVNVPROC __glewProgramParameter4fvNV; +GLEW_FUN_EXPORT PFNGLPROGRAMPARAMETERS4DVNVPROC __glewProgramParameters4dvNV; +GLEW_FUN_EXPORT PFNGLPROGRAMPARAMETERS4FVNVPROC __glewProgramParameters4fvNV; +GLEW_FUN_EXPORT PFNGLREQUESTRESIDENTPROGRAMSNVPROC __glewRequestResidentProgramsNV; +GLEW_FUN_EXPORT PFNGLTRACKMATRIXNVPROC __glewTrackMatrixNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1DNVPROC __glewVertexAttrib1dNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1DVNVPROC __glewVertexAttrib1dvNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1FNVPROC __glewVertexAttrib1fNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1FVNVPROC __glewVertexAttrib1fvNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1SNVPROC __glewVertexAttrib1sNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1SVNVPROC __glewVertexAttrib1svNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2DNVPROC __glewVertexAttrib2dNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2DVNVPROC __glewVertexAttrib2dvNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2FNVPROC __glewVertexAttrib2fNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2FVNVPROC __glewVertexAttrib2fvNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2SNVPROC __glewVertexAttrib2sNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2SVNVPROC __glewVertexAttrib2svNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3DNVPROC __glewVertexAttrib3dNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3DVNVPROC __glewVertexAttrib3dvNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3FNVPROC __glewVertexAttrib3fNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3FVNVPROC __glewVertexAttrib3fvNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3SNVPROC __glewVertexAttrib3sNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3SVNVPROC __glewVertexAttrib3svNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4DNVPROC __glewVertexAttrib4dNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4DVNVPROC __glewVertexAttrib4dvNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4FNVPROC __glewVertexAttrib4fNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4FVNVPROC __glewVertexAttrib4fvNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4SNVPROC __glewVertexAttrib4sNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4SVNVPROC __glewVertexAttrib4svNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4UBNVPROC __glewVertexAttrib4ubNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4UBVNVPROC __glewVertexAttrib4ubvNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBPOINTERNVPROC __glewVertexAttribPointerNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS1DVNVPROC __glewVertexAttribs1dvNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS1FVNVPROC __glewVertexAttribs1fvNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS1SVNVPROC __glewVertexAttribs1svNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS2DVNVPROC __glewVertexAttribs2dvNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS2FVNVPROC __glewVertexAttribs2fvNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS2SVNVPROC __glewVertexAttribs2svNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS3DVNVPROC __glewVertexAttribs3dvNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS3FVNVPROC __glewVertexAttribs3fvNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS3SVNVPROC __glewVertexAttribs3svNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS4DVNVPROC __glewVertexAttribs4dvNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS4FVNVPROC __glewVertexAttribs4fvNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS4SVNVPROC __glewVertexAttribs4svNV; +GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS4UBVNVPROC __glewVertexAttribs4ubvNV; + +GLEW_FUN_EXPORT PFNGLDETAILTEXFUNCSGISPROC __glewDetailTexFuncSGIS; +GLEW_FUN_EXPORT PFNGLGETDETAILTEXFUNCSGISPROC __glewGetDetailTexFuncSGIS; + +GLEW_FUN_EXPORT PFNGLFOGFUNCSGISPROC __glewFogFuncSGIS; +GLEW_FUN_EXPORT PFNGLGETFOGFUNCSGISPROC __glewGetFogFuncSGIS; + +GLEW_FUN_EXPORT PFNGLSAMPLEMASKSGISPROC __glewSampleMaskSGIS; +GLEW_FUN_EXPORT PFNGLSAMPLEPATTERNSGISPROC __glewSamplePatternSGIS; + +GLEW_FUN_EXPORT PFNGLGETSHARPENTEXFUNCSGISPROC __glewGetSharpenTexFuncSGIS; +GLEW_FUN_EXPORT PFNGLSHARPENTEXFUNCSGISPROC __glewSharpenTexFuncSGIS; + +GLEW_FUN_EXPORT PFNGLTEXIMAGE4DSGISPROC __glewTexImage4DSGIS; +GLEW_FUN_EXPORT PFNGLTEXSUBIMAGE4DSGISPROC __glewTexSubImage4DSGIS; + +GLEW_FUN_EXPORT PFNGLGETTEXFILTERFUNCSGISPROC __glewGetTexFilterFuncSGIS; +GLEW_FUN_EXPORT PFNGLTEXFILTERFUNCSGISPROC __glewTexFilterFuncSGIS; + +GLEW_FUN_EXPORT PFNGLASYNCMARKERSGIXPROC __glewAsyncMarkerSGIX; +GLEW_FUN_EXPORT PFNGLDELETEASYNCMARKERSSGIXPROC __glewDeleteAsyncMarkersSGIX; +GLEW_FUN_EXPORT PFNGLFINISHASYNCSGIXPROC __glewFinishAsyncSGIX; +GLEW_FUN_EXPORT PFNGLGENASYNCMARKERSSGIXPROC __glewGenAsyncMarkersSGIX; +GLEW_FUN_EXPORT PFNGLISASYNCMARKERSGIXPROC __glewIsAsyncMarkerSGIX; +GLEW_FUN_EXPORT PFNGLPOLLASYNCSGIXPROC __glewPollAsyncSGIX; + +GLEW_FUN_EXPORT PFNGLFLUSHRASTERSGIXPROC __glewFlushRasterSGIX; + +GLEW_FUN_EXPORT PFNGLTEXTUREFOGSGIXPROC __glewTextureFogSGIX; + +#if 0 +GLEW_FUN_EXPORT PFNGLFRAGMENTCOLORMATERIALSGIXPROC __glewFragmentColorMaterialSGIX; +GLEW_FUN_EXPORT PFNGLFRAGMENTLIGHTMODELFSGIXPROC __glewFragmentLightModelfSGIX; +GLEW_FUN_EXPORT PFNGLFRAGMENTLIGHTMODELFVSGIXPROC __glewFragmentLightModelfvSGIX; +GLEW_FUN_EXPORT PFNGLFRAGMENTLIGHTMODELISGIXPROC __glewFragmentLightModeliSGIX; +GLEW_FUN_EXPORT PFNGLFRAGMENTLIGHTMODELIVSGIXPROC __glewFragmentLightModelivSGIX; +GLEW_FUN_EXPORT PFNGLFRAGMENTLIGHTFSGIXPROC __glewFragmentLightfSGIX; +GLEW_FUN_EXPORT PFNGLFRAGMENTLIGHTFVSGIXPROC __glewFragmentLightfvSGIX; +GLEW_FUN_EXPORT PFNGLFRAGMENTLIGHTISGIXPROC __glewFragmentLightiSGIX; +GLEW_FUN_EXPORT PFNGLFRAGMENTLIGHTIVSGIXPROC __glewFragmentLightivSGIX; +GLEW_FUN_EXPORT PFNGLFRAGMENTMATERIALFSGIXPROC __glewFragmentMaterialfSGIX; +GLEW_FUN_EXPORT PFNGLFRAGMENTMATERIALFVSGIXPROC __glewFragmentMaterialfvSGIX; +GLEW_FUN_EXPORT PFNGLFRAGMENTMATERIALISGIXPROC __glewFragmentMaterialiSGIX; +GLEW_FUN_EXPORT PFNGLFRAGMENTMATERIALIVSGIXPROC __glewFragmentMaterialivSGIX; +GLEW_FUN_EXPORT PFNGLGETFRAGMENTLIGHTFVSGIXPROC __glewGetFragmentLightfvSGIX; +GLEW_FUN_EXPORT PFNGLGETFRAGMENTLIGHTIVSGIXPROC __glewGetFragmentLightivSGIX; +GLEW_FUN_EXPORT PFNGLGETFRAGMENTMATERIALFVSGIXPROC __glewGetFragmentMaterialfvSGIX; +GLEW_FUN_EXPORT PFNGLGETFRAGMENTMATERIALIVSGIXPROC __glewGetFragmentMaterialivSGIX; +#endif + +GLEW_FUN_EXPORT PFNGLFRAMEZOOMSGIXPROC __glewFrameZoomSGIX; + +GLEW_FUN_EXPORT PFNGLPIXELTEXGENSGIXPROC __glewPixelTexGenSGIX; + +GLEW_FUN_EXPORT PFNGLREFERENCEPLANESGIXPROC __glewReferencePlaneSGIX; + +GLEW_FUN_EXPORT PFNGLSPRITEPARAMETERFSGIXPROC __glewSpriteParameterfSGIX; +GLEW_FUN_EXPORT PFNGLSPRITEPARAMETERFVSGIXPROC __glewSpriteParameterfvSGIX; +GLEW_FUN_EXPORT PFNGLSPRITEPARAMETERISGIXPROC __glewSpriteParameteriSGIX; +GLEW_FUN_EXPORT PFNGLSPRITEPARAMETERIVSGIXPROC __glewSpriteParameterivSGIX; + +GLEW_FUN_EXPORT PFNGLTAGSAMPLEBUFFERSGIXPROC __glewTagSampleBufferSGIX; + +GLEW_FUN_EXPORT PFNGLCOLORTABLEPARAMETERFVSGIPROC __glewColorTableParameterfvSGI; +GLEW_FUN_EXPORT PFNGLCOLORTABLEPARAMETERIVSGIPROC __glewColorTableParameterivSGI; +GLEW_FUN_EXPORT PFNGLCOLORTABLESGIPROC __glewColorTableSGI; +GLEW_FUN_EXPORT PFNGLCOPYCOLORTABLESGIPROC __glewCopyColorTableSGI; +GLEW_FUN_EXPORT PFNGLGETCOLORTABLEPARAMETERFVSGIPROC __glewGetColorTableParameterfvSGI; +GLEW_FUN_EXPORT PFNGLGETCOLORTABLEPARAMETERIVSGIPROC __glewGetColorTableParameterivSGI; +GLEW_FUN_EXPORT PFNGLGETCOLORTABLESGIPROC __glewGetColorTableSGI; + +GLEW_FUN_EXPORT PFNGLFINISHTEXTURESUNXPROC __glewFinishTextureSUNX; + +GLEW_FUN_EXPORT PFNGLGLOBALALPHAFACTORBSUNPROC __glewGlobalAlphaFactorbSUN; +GLEW_FUN_EXPORT PFNGLGLOBALALPHAFACTORDSUNPROC __glewGlobalAlphaFactordSUN; +GLEW_FUN_EXPORT PFNGLGLOBALALPHAFACTORFSUNPROC __glewGlobalAlphaFactorfSUN; +GLEW_FUN_EXPORT PFNGLGLOBALALPHAFACTORISUNPROC __glewGlobalAlphaFactoriSUN; +GLEW_FUN_EXPORT PFNGLGLOBALALPHAFACTORSSUNPROC __glewGlobalAlphaFactorsSUN; +GLEW_FUN_EXPORT PFNGLGLOBALALPHAFACTORUBSUNPROC __glewGlobalAlphaFactorubSUN; +GLEW_FUN_EXPORT PFNGLGLOBALALPHAFACTORUISUNPROC __glewGlobalAlphaFactoruiSUN; +GLEW_FUN_EXPORT PFNGLGLOBALALPHAFACTORUSSUNPROC __glewGlobalAlphaFactorusSUN; + +GLEW_FUN_EXPORT PFNGLREADVIDEOPIXELSSUNPROC __glewReadVideoPixelsSUN; + +GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEPOINTERSUNPROC __glewReplacementCodePointerSUN; +GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUBSUNPROC __glewReplacementCodeubSUN; +GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUBVSUNPROC __glewReplacementCodeubvSUN; +GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUISUNPROC __glewReplacementCodeuiSUN; +GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUIVSUNPROC __glewReplacementCodeuivSUN; +GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUSSUNPROC __glewReplacementCodeusSUN; +GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUSVSUNPROC __glewReplacementCodeusvSUN; + +GLEW_FUN_EXPORT PFNGLCOLOR3FVERTEX3FSUNPROC __glewColor3fVertex3fSUN; +GLEW_FUN_EXPORT PFNGLCOLOR3FVERTEX3FVSUNPROC __glewColor3fVertex3fvSUN; +GLEW_FUN_EXPORT PFNGLCOLOR4FNORMAL3FVERTEX3FSUNPROC __glewColor4fNormal3fVertex3fSUN; +GLEW_FUN_EXPORT PFNGLCOLOR4FNORMAL3FVERTEX3FVSUNPROC __glewColor4fNormal3fVertex3fvSUN; +GLEW_FUN_EXPORT PFNGLCOLOR4UBVERTEX2FSUNPROC __glewColor4ubVertex2fSUN; +GLEW_FUN_EXPORT PFNGLCOLOR4UBVERTEX2FVSUNPROC __glewColor4ubVertex2fvSUN; +GLEW_FUN_EXPORT PFNGLCOLOR4UBVERTEX3FSUNPROC __glewColor4ubVertex3fSUN; +GLEW_FUN_EXPORT PFNGLCOLOR4UBVERTEX3FVSUNPROC __glewColor4ubVertex3fvSUN; +GLEW_FUN_EXPORT PFNGLNORMAL3FVERTEX3FSUNPROC __glewNormal3fVertex3fSUN; +GLEW_FUN_EXPORT PFNGLNORMAL3FVERTEX3FVSUNPROC __glewNormal3fVertex3fvSUN; +GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUICOLOR3FVERTEX3FSUNPROC __glewReplacementCodeuiColor3fVertex3fSUN; +GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUICOLOR3FVERTEX3FVSUNPROC __glewReplacementCodeuiColor3fVertex3fvSUN; +GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUICOLOR4FNORMAL3FVERTEX3FSUNPROC __glewReplacementCodeuiColor4fNormal3fVertex3fSUN; +GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUICOLOR4FNORMAL3FVERTEX3FVSUNPROC __glewReplacementCodeuiColor4fNormal3fVertex3fvSUN; +GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUICOLOR4UBVERTEX3FSUNPROC __glewReplacementCodeuiColor4ubVertex3fSUN; +GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUICOLOR4UBVERTEX3FVSUNPROC __glewReplacementCodeuiColor4ubVertex3fvSUN; +GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUINORMAL3FVERTEX3FSUNPROC __glewReplacementCodeuiNormal3fVertex3fSUN; +GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUINORMAL3FVERTEX3FVSUNPROC __glewReplacementCodeuiNormal3fVertex3fvSUN; +GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUITEXCOORD2FCOLOR4FNORMAL3FVERTEX3FSUNPROC __glewReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN; +GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUITEXCOORD2FCOLOR4FNORMAL3FVERTEX3FVSUNPROC __glewReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN; +GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUITEXCOORD2FNORMAL3FVERTEX3FSUNPROC __glewReplacementCodeuiTexCoord2fNormal3fVertex3fSUN; +GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUITEXCOORD2FNORMAL3FVERTEX3FVSUNPROC __glewReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN; +GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUITEXCOORD2FVERTEX3FSUNPROC __glewReplacementCodeuiTexCoord2fVertex3fSUN; +GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUITEXCOORD2FVERTEX3FVSUNPROC __glewReplacementCodeuiTexCoord2fVertex3fvSUN; +GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUIVERTEX3FSUNPROC __glewReplacementCodeuiVertex3fSUN; +GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUIVERTEX3FVSUNPROC __glewReplacementCodeuiVertex3fvSUN; +GLEW_FUN_EXPORT PFNGLTEXCOORD2FCOLOR3FVERTEX3FSUNPROC __glewTexCoord2fColor3fVertex3fSUN; +GLEW_FUN_EXPORT PFNGLTEXCOORD2FCOLOR3FVERTEX3FVSUNPROC __glewTexCoord2fColor3fVertex3fvSUN; +GLEW_FUN_EXPORT PFNGLTEXCOORD2FCOLOR4FNORMAL3FVERTEX3FSUNPROC __glewTexCoord2fColor4fNormal3fVertex3fSUN; +GLEW_FUN_EXPORT PFNGLTEXCOORD2FCOLOR4FNORMAL3FVERTEX3FVSUNPROC __glewTexCoord2fColor4fNormal3fVertex3fvSUN; +GLEW_FUN_EXPORT PFNGLTEXCOORD2FCOLOR4UBVERTEX3FSUNPROC __glewTexCoord2fColor4ubVertex3fSUN; +GLEW_FUN_EXPORT PFNGLTEXCOORD2FCOLOR4UBVERTEX3FVSUNPROC __glewTexCoord2fColor4ubVertex3fvSUN; +GLEW_FUN_EXPORT PFNGLTEXCOORD2FNORMAL3FVERTEX3FSUNPROC __glewTexCoord2fNormal3fVertex3fSUN; +GLEW_FUN_EXPORT PFNGLTEXCOORD2FNORMAL3FVERTEX3FVSUNPROC __glewTexCoord2fNormal3fVertex3fvSUN; +GLEW_FUN_EXPORT PFNGLTEXCOORD2FVERTEX3FSUNPROC __glewTexCoord2fVertex3fSUN; +GLEW_FUN_EXPORT PFNGLTEXCOORD2FVERTEX3FVSUNPROC __glewTexCoord2fVertex3fvSUN; +GLEW_FUN_EXPORT PFNGLTEXCOORD4FCOLOR4FNORMAL3FVERTEX4FSUNPROC __glewTexCoord4fColor4fNormal3fVertex4fSUN; +GLEW_FUN_EXPORT PFNGLTEXCOORD4FCOLOR4FNORMAL3FVERTEX4FVSUNPROC __glewTexCoord4fColor4fNormal3fVertex4fvSUN; +GLEW_FUN_EXPORT PFNGLTEXCOORD4FVERTEX4FSUNPROC __glewTexCoord4fVertex4fSUN; +GLEW_FUN_EXPORT PFNGLTEXCOORD4FVERTEX4FVSUNPROC __glewTexCoord4fVertex4fvSUN; + +GLEW_FUN_EXPORT PFNGLADDSWAPHINTRECTWINPROC __glewAddSwapHintRectWIN; + +#if defined(GLEW_MX) && !defined(_WIN32) +struct GLEWContextStruct +{ +#endif /* GLEW_MX */ + +GLEW_VAR_EXPORT GLboolean __GLEW_VERSION_1_1; +GLEW_VAR_EXPORT GLboolean __GLEW_VERSION_1_2; +GLEW_VAR_EXPORT GLboolean __GLEW_VERSION_1_3; +GLEW_VAR_EXPORT GLboolean __GLEW_VERSION_1_4; +GLEW_VAR_EXPORT GLboolean __GLEW_VERSION_1_5; +GLEW_VAR_EXPORT GLboolean __GLEW_VERSION_2_0; +GLEW_VAR_EXPORT GLboolean __GLEW_3DFX_multisample; +GLEW_VAR_EXPORT GLboolean __GLEW_3DFX_tbuffer; +GLEW_VAR_EXPORT GLboolean __GLEW_3DFX_texture_compression_FXT1; +GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_client_storage; +GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_element_array; +GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_fence; +GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_float_pixels; +GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_pixel_buffer; +GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_specular_vector; +GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_texture_range; +GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_transform_hint; +GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_vertex_array_object; +GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_vertex_array_range; +GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_ycbcr_422; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_color_buffer_float; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_depth_texture; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_draw_buffers; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_fragment_program; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_fragment_program_shadow; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_fragment_shader; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_half_float_pixel; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_imaging; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_matrix_palette; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_multisample; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_multitexture; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_occlusion_query; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_pixel_buffer_object; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_point_parameters; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_point_sprite; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_shader_objects; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_shading_language_100; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_shadow; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_shadow_ambient; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_border_clamp; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_compression; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_cube_map; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_env_add; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_env_combine; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_env_crossbar; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_env_dot3; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_float; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_mirrored_repeat; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_non_power_of_two; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_rectangle; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_transpose_matrix; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_vertex_blend; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_vertex_buffer_object; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_vertex_program; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_vertex_shader; +GLEW_VAR_EXPORT GLboolean __GLEW_ARB_window_pos; +GLEW_VAR_EXPORT GLboolean __GLEW_ATIX_point_sprites; +GLEW_VAR_EXPORT GLboolean __GLEW_ATIX_texture_env_combine3; +GLEW_VAR_EXPORT GLboolean __GLEW_ATIX_texture_env_route; +GLEW_VAR_EXPORT GLboolean __GLEW_ATIX_vertex_shader_output_point_size; +GLEW_VAR_EXPORT GLboolean __GLEW_ATI_draw_buffers; +GLEW_VAR_EXPORT GLboolean __GLEW_ATI_element_array; +GLEW_VAR_EXPORT GLboolean __GLEW_ATI_envmap_bumpmap; +GLEW_VAR_EXPORT GLboolean __GLEW_ATI_fragment_shader; +GLEW_VAR_EXPORT GLboolean __GLEW_ATI_map_object_buffer; +GLEW_VAR_EXPORT GLboolean __GLEW_ATI_pn_triangles; +GLEW_VAR_EXPORT GLboolean __GLEW_ATI_separate_stencil; +GLEW_VAR_EXPORT GLboolean __GLEW_ATI_text_fragment_shader; +GLEW_VAR_EXPORT GLboolean __GLEW_ATI_texture_compression_3dc; +GLEW_VAR_EXPORT GLboolean __GLEW_ATI_texture_env_combine3; +GLEW_VAR_EXPORT GLboolean __GLEW_ATI_texture_float; +GLEW_VAR_EXPORT GLboolean __GLEW_ATI_texture_mirror_once; +GLEW_VAR_EXPORT GLboolean __GLEW_ATI_vertex_array_object; +GLEW_VAR_EXPORT GLboolean __GLEW_ATI_vertex_attrib_array_object; +GLEW_VAR_EXPORT GLboolean __GLEW_ATI_vertex_streams; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_422_pixels; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_Cg_shader; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_abgr; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_bgra; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_blend_color; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_blend_equation_separate; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_blend_func_separate; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_blend_logic_op; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_blend_minmax; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_blend_subtract; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_clip_volume_hint; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_cmyka; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_color_subtable; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_compiled_vertex_array; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_convolution; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_coordinate_frame; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_copy_texture; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_cull_vertex; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_depth_bounds_test; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_draw_range_elements; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_fog_coord; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_fragment_lighting; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_framebuffer_blit; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_framebuffer_multisample; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_framebuffer_object; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_histogram; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_index_array_formats; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_index_func; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_index_material; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_index_texture; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_light_texture; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_misc_attribute; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_multi_draw_arrays; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_multisample; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_packed_depth_stencil; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_packed_pixels; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_paletted_texture; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_pixel_buffer_object; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_pixel_transform; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_pixel_transform_color_table; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_point_parameters; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_polygon_offset; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_rescale_normal; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_scene_marker; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_secondary_color; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_separate_specular_color; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_shadow_funcs; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_shared_texture_palette; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_stencil_clear_tag; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_stencil_two_side; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_stencil_wrap; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_subtexture; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture3D; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_compression_dxt1; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_compression_s3tc; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_cube_map; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_edge_clamp; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_env; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_env_add; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_env_combine; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_env_dot3; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_filter_anisotropic; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_lod_bias; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_mirror_clamp; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_object; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_perturb_normal; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_rectangle; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_sRGB; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_vertex_array; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_vertex_shader; +GLEW_VAR_EXPORT GLboolean __GLEW_EXT_vertex_weighting; +GLEW_VAR_EXPORT GLboolean __GLEW_GREMEDY_string_marker; +GLEW_VAR_EXPORT GLboolean __GLEW_HP_convolution_border_modes; +GLEW_VAR_EXPORT GLboolean __GLEW_HP_image_transform; +GLEW_VAR_EXPORT GLboolean __GLEW_HP_occlusion_test; +GLEW_VAR_EXPORT GLboolean __GLEW_HP_texture_lighting; +GLEW_VAR_EXPORT GLboolean __GLEW_IBM_cull_vertex; +GLEW_VAR_EXPORT GLboolean __GLEW_IBM_multimode_draw_arrays; +GLEW_VAR_EXPORT GLboolean __GLEW_IBM_rasterpos_clip; +GLEW_VAR_EXPORT GLboolean __GLEW_IBM_static_data; +GLEW_VAR_EXPORT GLboolean __GLEW_IBM_texture_mirrored_repeat; +GLEW_VAR_EXPORT GLboolean __GLEW_IBM_vertex_array_lists; +GLEW_VAR_EXPORT GLboolean __GLEW_INGR_color_clamp; +GLEW_VAR_EXPORT GLboolean __GLEW_INGR_interlace_read; +GLEW_VAR_EXPORT GLboolean __GLEW_INTEL_parallel_arrays; +GLEW_VAR_EXPORT GLboolean __GLEW_INTEL_texture_scissor; +GLEW_VAR_EXPORT GLboolean __GLEW_KTX_buffer_region; +GLEW_VAR_EXPORT GLboolean __GLEW_MESAX_texture_stack; +GLEW_VAR_EXPORT GLboolean __GLEW_MESA_pack_invert; +GLEW_VAR_EXPORT GLboolean __GLEW_MESA_resize_buffers; +GLEW_VAR_EXPORT GLboolean __GLEW_MESA_window_pos; +GLEW_VAR_EXPORT GLboolean __GLEW_MESA_ycbcr_texture; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_blend_square; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_copy_depth_to_color; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_depth_clamp; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_evaluators; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_fence; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_float_buffer; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_fog_distance; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_fragment_program; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_fragment_program2; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_fragment_program_option; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_half_float; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_light_max_exponent; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_multisample_filter_hint; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_occlusion_query; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_packed_depth_stencil; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_pixel_data_range; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_point_sprite; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_primitive_restart; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_register_combiners; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_register_combiners2; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_texgen_emboss; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_texgen_reflection; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_texture_compression_vtc; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_texture_env_combine4; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_texture_expand_normal; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_texture_rectangle; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_texture_shader; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_texture_shader2; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_texture_shader3; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_vertex_array_range; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_vertex_array_range2; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_vertex_program; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_vertex_program1_1; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_vertex_program2; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_vertex_program2_option; +GLEW_VAR_EXPORT GLboolean __GLEW_NV_vertex_program3; +GLEW_VAR_EXPORT GLboolean __GLEW_OML_interlace; +GLEW_VAR_EXPORT GLboolean __GLEW_OML_resample; +GLEW_VAR_EXPORT GLboolean __GLEW_OML_subsample; +GLEW_VAR_EXPORT GLboolean __GLEW_PGI_misc_hints; +GLEW_VAR_EXPORT GLboolean __GLEW_PGI_vertex_hints; +GLEW_VAR_EXPORT GLboolean __GLEW_REND_screen_coordinates; +GLEW_VAR_EXPORT GLboolean __GLEW_S3_s3tc; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIS_color_range; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIS_detail_texture; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIS_fog_function; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIS_generate_mipmap; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIS_multisample; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIS_pixel_texture; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIS_sharpen_texture; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIS_texture4D; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIS_texture_border_clamp; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIS_texture_edge_clamp; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIS_texture_filter4; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIS_texture_lod; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIS_texture_select; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_async; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_async_histogram; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_async_pixel; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_blend_alpha_minmax; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_clipmap; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_depth_texture; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_flush_raster; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_fog_offset; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_fog_texture; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_fragment_specular_lighting; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_framezoom; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_interlace; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_ir_instrument1; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_list_priority; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_pixel_texture; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_pixel_texture_bits; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_reference_plane; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_resample; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_shadow; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_shadow_ambient; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_sprite; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_tag_sample_buffer; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_texture_add_env; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_texture_coordinate_clamp; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_texture_lod_bias; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_texture_multi_buffer; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_texture_range; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_texture_scale_bias; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_vertex_preclip; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_vertex_preclip_hint; +GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_ycrcb; +GLEW_VAR_EXPORT GLboolean __GLEW_SGI_color_matrix; +GLEW_VAR_EXPORT GLboolean __GLEW_SGI_color_table; +GLEW_VAR_EXPORT GLboolean __GLEW_SGI_texture_color_table; +GLEW_VAR_EXPORT GLboolean __GLEW_SUNX_constant_data; +GLEW_VAR_EXPORT GLboolean __GLEW_SUN_convolution_border_modes; +GLEW_VAR_EXPORT GLboolean __GLEW_SUN_global_alpha; +GLEW_VAR_EXPORT GLboolean __GLEW_SUN_mesh_array; +GLEW_VAR_EXPORT GLboolean __GLEW_SUN_read_video_pixels; +GLEW_VAR_EXPORT GLboolean __GLEW_SUN_slice_accum; +GLEW_VAR_EXPORT GLboolean __GLEW_SUN_triangle_list; +GLEW_VAR_EXPORT GLboolean __GLEW_SUN_vertex; +GLEW_VAR_EXPORT GLboolean __GLEW_WIN_phong_shading; +GLEW_VAR_EXPORT GLboolean __GLEW_WIN_specular_fog; +GLEW_VAR_EXPORT GLboolean __GLEW_WIN_swap_hint; + +#ifdef GLEW_MX +}; /* GLEWContextStruct */ +#endif /* GLEW_MX */ + +/* ------------------------------------------------------------------------- */ + +/* error codes */ +#define GLEW_OK 0 +#define GLEW_NO_ERROR 0 +#define GLEW_ERROR_NO_GL_VERSION 1 /* missing GL version */ +#define GLEW_ERROR_GL_VERSION_10_ONLY 2 /* GL 1.1 and up are not supported */ +#define GLEW_ERROR_GLX_VERSION_11_ONLY 3 /* GLX 1.2 and up are not supported */ + +/* string codes */ +#define GLEW_VERSION 1 + +/* API */ +#ifdef GLEW_MX + +typedef struct GLEWContextStruct GLEWContext; +GLEWAPI GLenum glewContextInit (GLEWContext* ctx); +GLEWAPI GLboolean glewContextIsSupported (GLEWContext* ctx, const char* name); + +#define glewInit() glewContextInit(glewGetContext()) +#define glewIsSupported(x) glewContextIsSupported(glewGetContext(), x) +#define glewIsExtensionSupported(x) glewIsSupported(x) + +#ifdef _WIN32 +# define GLEW_GET_VAR(x) glewGetContext()->x +# define GLEW_GET_FUN(x) glewGetContext()->x +#else +# define GLEW_GET_VAR(x) glewGetContext()->x +# define GLEW_GET_FUN(x) x +#endif + +#else /* GLEW_MX */ + +GLEWAPI GLenum glewInit (); +GLEWAPI GLboolean glewIsSupported (const char* name); +#define glewIsExtensionSupported(x) glewIsSupported(x) + +#define GLEW_GET_VAR(x) x +#define GLEW_GET_FUN(x) x + +#endif /* GLEW_MX */ + +GLEWAPI GLboolean glewExperimental; +GLEWAPI GLboolean glewGetExtension (const char* name); +GLEWAPI const GLubyte* glewGetErrorString (GLenum error); +GLEWAPI const GLubyte* glewGetString (GLenum name); + +#ifdef __cplusplus +} +#endif + +#ifdef GLEW_APIENTRY_DEFINED +#undef GLEW_APIENTRY_DEFINED +#undef APIENTRY +#undef GLAPIENTRY +#endif + +#ifdef GLEW_CALLBACK_DEFINED +#undef GLEW_CALLBACK_DEFINED +#undef CALLBACK +#endif + +#ifdef GLEW_WINGDIAPI_DEFINED +#undef GLEW_WINGDIAPI_DEFINED +#undef WINGDIAPI +#endif + +#undef GLAPI +/* #undef GLEWAPI */ + +#endif /* __glew_h__ */ diff --git a/extern/glew/include/GL/glxew.h b/extern/glew/include/GL/glxew.h new file mode 100644 index 00000000000..d21397aeed4 --- /dev/null +++ b/extern/glew/include/GL/glxew.h @@ -0,0 +1,1062 @@ +/* +** The OpenGL Extension Wrangler Library +** Copyright (C) 2002-2006, Milan Ikits +** Copyright (C) 2002-2006, Marcelo E. Magallon +** Copyright (C) 2002, Lev Povalahev +** 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. +** * The name of the author 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. +*/ + +/* +** The contents of this file are subject to the GLX Public License Version 1.0 +** (the "License"). You may not use this file except in compliance with the +** License. You may obtain a copy of the License at Silicon Graphics, Inc., +** attn: Legal Services, 2011 N. Shoreline Blvd., Mountain View, CA 94043 +** or at http://www.sgi.com/software/opensource/glx/license.html. +** +** Software distributed under the License is distributed on an "AS IS" +** basis. ALL WARRANTIES ARE DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY +** IMPLIED WARRANTIES OF MERCHANTABILITY, OF FITNESS FOR A PARTICULAR +** PURPOSE OR OF NON- INFRINGEMENT. See the License for the specific +** language governing rights and limitations under the License. +** +** The Original Software is GLX version 1.2 source code, released February, +** 1999. The developer of the Original Software is Silicon Graphics, Inc. +** Those portions of the Subject Software created by Silicon Graphics, Inc. +** are Copyright (c) 1991-9 Silicon Graphics, Inc. All Rights Reserved. +*/ + +#ifndef __glxew_h__ +#define __glxew_h__ +#define __GLXEW_H__ + +#ifdef __glxext_h_ +#error glxext.h included before glxew.h +#endif + +#define __glxext_h_ +#define __GLX_glx_h__ + +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* ---------------------------- GLX_VERSION_1_0 --------------------------- */ + +#ifndef GLX_VERSION_1_0 +#define GLX_VERSION_1_0 1 + +#define GLX_USE_GL 1 +#define GLX_BUFFER_SIZE 2 +#define GLX_LEVEL 3 +#define GLX_RGBA 4 +#define GLX_DOUBLEBUFFER 5 +#define GLX_STEREO 6 +#define GLX_AUX_BUFFERS 7 +#define GLX_RED_SIZE 8 +#define GLX_GREEN_SIZE 9 +#define GLX_BLUE_SIZE 10 +#define GLX_ALPHA_SIZE 11 +#define GLX_DEPTH_SIZE 12 +#define GLX_STENCIL_SIZE 13 +#define GLX_ACCUM_RED_SIZE 14 +#define GLX_ACCUM_GREEN_SIZE 15 +#define GLX_ACCUM_BLUE_SIZE 16 +#define GLX_ACCUM_ALPHA_SIZE 17 +#define GLX_BAD_SCREEN 1 +#define GLX_BAD_ATTRIBUTE 2 +#define GLX_NO_EXTENSION 3 +#define GLX_BAD_VISUAL 4 +#define GLX_BAD_CONTEXT 5 +#define GLX_BAD_VALUE 6 +#define GLX_BAD_ENUM 7 + +typedef XID GLXDrawable; +typedef XID GLXPixmap; +typedef struct __GLXcontextRec *GLXContext; + +extern Bool glXQueryExtension (Display *dpy, int *errorBase, int *eventBase); +extern Bool glXQueryVersion (Display *dpy, int *major, int *minor); +extern int glXGetConfig (Display *dpy, XVisualInfo *vis, int attrib, int *value); +extern XVisualInfo* glXChooseVisual (Display *dpy, int screen, int *attribList); +extern GLXPixmap glXCreateGLXPixmap (Display *dpy, XVisualInfo *vis, Pixmap pixmap); +extern void glXDestroyGLXPixmap (Display *dpy, GLXPixmap pix); +extern GLXContext glXCreateContext (Display *dpy, XVisualInfo *vis, GLXContext shareList, Bool direct); +extern void glXDestroyContext (Display *dpy, GLXContext ctx); +extern Bool glXIsDirect (Display *dpy, GLXContext ctx); +extern void glXCopyContext (Display *dpy, GLXContext src, GLXContext dst, GLuint mask); +extern Bool glXMakeCurrent (Display *dpy, GLXDrawable drawable, GLXContext ctx); +extern GLXContext glXGetCurrentContext (void); +extern GLXDrawable glXGetCurrentDrawable (void); +extern void glXWaitGL (void); +extern void glXWaitX (void); +extern void glXSwapBuffers (Display *dpy, GLXDrawable drawable); +extern void glXUseXFont (Font font, int first, int count, int listBase); + +#define GLXEW_VERSION_1_0 GLXEW_GET_VAR(__GLXEW_VERSION_1_0) + +#endif /* GLX_VERSION_1_0 */ + +/* ---------------------------- GLX_VERSION_1_1 --------------------------- */ + +#ifndef GLX_VERSION_1_1 +#define GLX_VERSION_1_1 + +#define GLX_VENDOR 0x1 +#define GLX_VERSION 0x2 +#define GLX_EXTENSIONS 0x3 + +extern const char* glXQueryExtensionsString (Display *dpy, int screen); +extern const char* glXGetClientString (Display *dpy, int name); +extern const char* glXQueryServerString (Display *dpy, int screen, int name); + +#define GLXEW_VERSION_1_1 GLXEW_GET_VAR(__GLXEW_VERSION_1_1) + +#endif /* GLX_VERSION_1_1 */ + +/* ---------------------------- GLX_VERSION_1_2 ---------------------------- */ + +#ifndef GLX_VERSION_1_2 +#define GLX_VERSION_1_2 1 + +typedef Display* ( * PFNGLXGETCURRENTDISPLAYPROC) (void); + +#define glXGetCurrentDisplay GLXEW_GET_FUN(__glewXGetCurrentDisplay) + +#define GLXEW_VERSION_1_2 GLXEW_GET_VAR(__GLXEW_VERSION_1_2) + +#endif /* GLX_VERSION_1_2 */ + +/* ---------------------------- GLX_VERSION_1_3 ---------------------------- */ + +#ifndef GLX_VERSION_1_3 +#define GLX_VERSION_1_3 1 + +#define GLX_RGBA_BIT 0x00000001 +#define GLX_FRONT_LEFT_BUFFER_BIT 0x00000001 +#define GLX_WINDOW_BIT 0x00000001 +#define GLX_COLOR_INDEX_BIT 0x00000002 +#define GLX_PIXMAP_BIT 0x00000002 +#define GLX_FRONT_RIGHT_BUFFER_BIT 0x00000002 +#define GLX_BACK_LEFT_BUFFER_BIT 0x00000004 +#define GLX_PBUFFER_BIT 0x00000004 +#define GLX_BACK_RIGHT_BUFFER_BIT 0x00000008 +#define GLX_AUX_BUFFERS_BIT 0x00000010 +#define GLX_CONFIG_CAVEAT 0x20 +#define GLX_DEPTH_BUFFER_BIT 0x00000020 +#define GLX_X_VISUAL_TYPE 0x22 +#define GLX_TRANSPARENT_TYPE 0x23 +#define GLX_TRANSPARENT_INDEX_VALUE 0x24 +#define GLX_TRANSPARENT_RED_VALUE 0x25 +#define GLX_TRANSPARENT_GREEN_VALUE 0x26 +#define GLX_TRANSPARENT_BLUE_VALUE 0x27 +#define GLX_TRANSPARENT_ALPHA_VALUE 0x28 +#define GLX_STENCIL_BUFFER_BIT 0x00000040 +#define GLX_ACCUM_BUFFER_BIT 0x00000080 +#define GLX_NONE 0x8000 +#define GLX_SLOW_CONFIG 0x8001 +#define GLX_TRUE_COLOR 0x8002 +#define GLX_DIRECT_COLOR 0x8003 +#define GLX_PSEUDO_COLOR 0x8004 +#define GLX_STATIC_COLOR 0x8005 +#define GLX_GRAY_SCALE 0x8006 +#define GLX_STATIC_GRAY 0x8007 +#define GLX_TRANSPARENT_RGB 0x8008 +#define GLX_TRANSPARENT_INDEX 0x8009 +#define GLX_VISUAL_ID 0x800B +#define GLX_SCREEN 0x800C +#define GLX_NON_CONFORMANT_CONFIG 0x800D +#define GLX_DRAWABLE_TYPE 0x8010 +#define GLX_RENDER_TYPE 0x8011 +#define GLX_X_RENDERABLE 0x8012 +#define GLX_FBCONFIG_ID 0x8013 +#define GLX_RGBA_TYPE 0x8014 +#define GLX_COLOR_INDEX_TYPE 0x8015 +#define GLX_MAX_PBUFFER_WIDTH 0x8016 +#define GLX_MAX_PBUFFER_HEIGHT 0x8017 +#define GLX_MAX_PBUFFER_PIXELS 0x8018 +#define GLX_PRESERVED_CONTENTS 0x801B +#define GLX_LARGEST_PBUFFER 0x801C +#define GLX_WIDTH 0x801D +#define GLX_HEIGHT 0x801E +#define GLX_EVENT_MASK 0x801F +#define GLX_DAMAGED 0x8020 +#define GLX_SAVED 0x8021 +#define GLX_WINDOW 0x8022 +#define GLX_PBUFFER 0x8023 +#define GLX_PBUFFER_HEIGHT 0x8040 +#define GLX_PBUFFER_WIDTH 0x8041 +#define GLX_PBUFFER_CLOBBER_MASK 0x08000000 +#define GLX_DONT_CARE 0xFFFFFFFF + +typedef XID GLXFBConfigID; +typedef XID GLXWindow; +typedef XID GLXPbuffer; +typedef struct __GLXFBConfigRec *GLXFBConfig; +typedef struct { int event_type; int draw_type; unsigned long serial; Bool send_event; Display *display; GLXDrawable drawable; unsigned int buffer_mask; unsigned int aux_buffer; int x, y; int width, height; int count; } GLXPbufferClobberEvent; +typedef union __GLXEvent { GLXPbufferClobberEvent glxpbufferclobber; long pad[24]; } GLXEvent; + +typedef GLXFBConfig* ( * PFNGLXCHOOSEFBCONFIGPROC) (Display *dpy, int screen, const int *attrib_list, int *nelements); +typedef GLXContext ( * PFNGLXCREATENEWCONTEXTPROC) (Display *dpy, GLXFBConfig config, int render_type, GLXContext share_list, Bool direct); +typedef GLXPbuffer ( * PFNGLXCREATEPBUFFERPROC) (Display *dpy, GLXFBConfig config, const int *attrib_list); +typedef GLXPixmap ( * PFNGLXCREATEPIXMAPPROC) (Display *dpy, GLXFBConfig config, Pixmap pixmap, const int *attrib_list); +typedef GLXWindow ( * PFNGLXCREATEWINDOWPROC) (Display *dpy, GLXFBConfig config, Window win, const int *attrib_list); +typedef void ( * PFNGLXDESTROYPBUFFERPROC) (Display *dpy, GLXPbuffer pbuf); +typedef void ( * PFNGLXDESTROYPIXMAPPROC) (Display *dpy, GLXPixmap pixmap); +typedef void ( * PFNGLXDESTROYWINDOWPROC) (Display *dpy, GLXWindow win); +typedef GLXDrawable ( * PFNGLXGETCURRENTREADDRAWABLEPROC) (void); +typedef int ( * PFNGLXGETFBCONFIGATTRIBPROC) (Display *dpy, GLXFBConfig config, int attribute, int *value); +typedef GLXFBConfig* ( * PFNGLXGETFBCONFIGSPROC) (Display *dpy, int screen, int *nelements); +typedef void ( * PFNGLXGETSELECTEDEVENTPROC) (Display *dpy, GLXDrawable draw, unsigned long *event_mask); +typedef XVisualInfo* ( * PFNGLXGETVISUALFROMFBCONFIGPROC) (Display *dpy, GLXFBConfig config); +typedef Bool ( * PFNGLXMAKECONTEXTCURRENTPROC) (Display *display, GLXDrawable draw, GLXDrawable read, GLXContext ctx); +typedef int ( * PFNGLXQUERYCONTEXTPROC) (Display *dpy, GLXContext ctx, int attribute, int *value); +typedef void ( * PFNGLXQUERYDRAWABLEPROC) (Display *dpy, GLXDrawable draw, int attribute, unsigned int *value); +typedef void ( * PFNGLXSELECTEVENTPROC) (Display *dpy, GLXDrawable draw, unsigned long event_mask); + +#define glXChooseFBConfig GLXEW_GET_FUN(__glewXChooseFBConfig) +#define glXCreateNewContext GLXEW_GET_FUN(__glewXCreateNewContext) +#define glXCreatePbuffer GLXEW_GET_FUN(__glewXCreatePbuffer) +#define glXCreatePixmap GLXEW_GET_FUN(__glewXCreatePixmap) +#define glXCreateWindow GLXEW_GET_FUN(__glewXCreateWindow) +#define glXDestroyPbuffer GLXEW_GET_FUN(__glewXDestroyPbuffer) +#define glXDestroyPixmap GLXEW_GET_FUN(__glewXDestroyPixmap) +#define glXDestroyWindow GLXEW_GET_FUN(__glewXDestroyWindow) +#define glXGetCurrentReadDrawable GLXEW_GET_FUN(__glewXGetCurrentReadDrawable) +#define glXGetFBConfigAttrib GLXEW_GET_FUN(__glewXGetFBConfigAttrib) +#define glXGetFBConfigs GLXEW_GET_FUN(__glewXGetFBConfigs) +#define glXGetSelectedEvent GLXEW_GET_FUN(__glewXGetSelectedEvent) +#define glXGetVisualFromFBConfig GLXEW_GET_FUN(__glewXGetVisualFromFBConfig) +#define glXMakeContextCurrent GLXEW_GET_FUN(__glewXMakeContextCurrent) +#define glXQueryContext GLXEW_GET_FUN(__glewXQueryContext) +#define glXQueryDrawable GLXEW_GET_FUN(__glewXQueryDrawable) +#define glXSelectEvent GLXEW_GET_FUN(__glewXSelectEvent) + +#define GLXEW_VERSION_1_3 GLXEW_GET_VAR(__GLXEW_VERSION_1_3) + +#endif /* GLX_VERSION_1_3 */ + +/* ---------------------------- GLX_VERSION_1_4 ---------------------------- */ + +#ifndef GLX_VERSION_1_4 +#define GLX_VERSION_1_4 1 + +#define GLX_SAMPLE_BUFFERS 100000 +#define GLX_SAMPLES 100001 + +extern void ( * glXGetProcAddress (const GLubyte *procName)) (void); + +#define GLXEW_VERSION_1_4 GLXEW_GET_VAR(__GLXEW_VERSION_1_4) + +#endif /* GLX_VERSION_1_4 */ + +/* -------------------------- GLX_3DFX_multisample ------------------------- */ + +#ifndef GLX_3DFX_multisample +#define GLX_3DFX_multisample 1 + +#define GLX_SAMPLE_BUFFERS_3DFX 0x8050 +#define GLX_SAMPLES_3DFX 0x8051 + +#define GLXEW_3DFX_multisample GLXEW_GET_VAR(__GLXEW_3DFX_multisample) + +#endif /* GLX_3DFX_multisample */ + +/* ------------------------- GLX_ARB_fbconfig_float ------------------------ */ + +#ifndef GLX_ARB_fbconfig_float +#define GLX_ARB_fbconfig_float 1 + +#define GLX_RGBA_FLOAT_BIT 0x00000004 +#define GLX_RGBA_FLOAT_TYPE 0x20B9 + +#define GLXEW_ARB_fbconfig_float GLXEW_GET_VAR(__GLXEW_ARB_fbconfig_float) + +#endif /* GLX_ARB_fbconfig_float */ + +/* ------------------------ GLX_ARB_get_proc_address ----------------------- */ + +#ifndef GLX_ARB_get_proc_address +#define GLX_ARB_get_proc_address 1 + +extern void ( * glXGetProcAddressARB (const GLubyte *procName)) (void); + +#define GLXEW_ARB_get_proc_address GLXEW_GET_VAR(__GLXEW_ARB_get_proc_address) + +#endif /* GLX_ARB_get_proc_address */ + +/* -------------------------- GLX_ARB_multisample -------------------------- */ + +#ifndef GLX_ARB_multisample +#define GLX_ARB_multisample 1 + +#define GLX_SAMPLE_BUFFERS_ARB 100000 +#define GLX_SAMPLES_ARB 100001 + +#define GLXEW_ARB_multisample GLXEW_GET_VAR(__GLXEW_ARB_multisample) + +#endif /* GLX_ARB_multisample */ + +/* ----------------------- GLX_ATI_pixel_format_float ---------------------- */ + +#ifndef GLX_ATI_pixel_format_float +#define GLX_ATI_pixel_format_float 1 + +#define GLX_RGBA_FLOAT_ATI_BIT 0x00000100 + +#define GLXEW_ATI_pixel_format_float GLXEW_GET_VAR(__GLXEW_ATI_pixel_format_float) + +#endif /* GLX_ATI_pixel_format_float */ + +/* ------------------------- GLX_ATI_render_texture ------------------------ */ + +#ifndef GLX_ATI_render_texture +#define GLX_ATI_render_texture 1 + +#define GLX_BIND_TO_TEXTURE_RGB_ATI 0x9800 +#define GLX_BIND_TO_TEXTURE_RGBA_ATI 0x9801 +#define GLX_TEXTURE_FORMAT_ATI 0x9802 +#define GLX_TEXTURE_TARGET_ATI 0x9803 +#define GLX_MIPMAP_TEXTURE_ATI 0x9804 +#define GLX_TEXTURE_RGB_ATI 0x9805 +#define GLX_TEXTURE_RGBA_ATI 0x9806 +#define GLX_NO_TEXTURE_ATI 0x9807 +#define GLX_TEXTURE_CUBE_MAP_ATI 0x9808 +#define GLX_TEXTURE_1D_ATI 0x9809 +#define GLX_TEXTURE_2D_ATI 0x980A +#define GLX_MIPMAP_LEVEL_ATI 0x980B +#define GLX_CUBE_MAP_FACE_ATI 0x980C +#define GLX_TEXTURE_CUBE_MAP_POSITIVE_X_ATI 0x980D +#define GLX_TEXTURE_CUBE_MAP_NEGATIVE_X_ATI 0x980E +#define GLX_TEXTURE_CUBE_MAP_POSITIVE_Y_ATI 0x980F +#define GLX_TEXTURE_CUBE_MAP_NEGATIVE_Y_ATI 0x9810 +#define GLX_TEXTURE_CUBE_MAP_POSITIVE_Z_ATI 0x9811 +#define GLX_TEXTURE_CUBE_MAP_NEGATIVE_Z_ATI 0x9812 +#define GLX_FRONT_LEFT_ATI 0x9813 +#define GLX_FRONT_RIGHT_ATI 0x9814 +#define GLX_BACK_LEFT_ATI 0x9815 +#define GLX_BACK_RIGHT_ATI 0x9816 +#define GLX_AUX0_ATI 0x9817 +#define GLX_AUX1_ATI 0x9818 +#define GLX_AUX2_ATI 0x9819 +#define GLX_AUX3_ATI 0x981A +#define GLX_AUX4_ATI 0x981B +#define GLX_AUX5_ATI 0x981C +#define GLX_AUX6_ATI 0x981D +#define GLX_AUX7_ATI 0x981E +#define GLX_AUX8_ATI 0x981F +#define GLX_AUX9_ATI 0x9820 +#define GLX_BIND_TO_TEXTURE_LUMINANCE_ATI 0x9821 +#define GLX_BIND_TO_TEXTURE_INTENSITY_ATI 0x9822 + +typedef void ( * PFNGLXBINDTEXIMAGEATIPROC) (Display *dpy, GLXPbuffer pbuf, int buffer); +typedef void ( * PFNGLXDRAWABLEATTRIBATIPROC) (Display *dpy, GLXDrawable draw, const int *attrib_list); +typedef void ( * PFNGLXRELEASETEXIMAGEATIPROC) (Display *dpy, GLXPbuffer pbuf, int buffer); + +#define glXBindTexImageATI GLXEW_GET_FUN(__glewXBindTexImageATI) +#define glXDrawableAttribATI GLXEW_GET_FUN(__glewXDrawableAttribATI) +#define glXReleaseTexImageATI GLXEW_GET_FUN(__glewXReleaseTexImageATI) + +#define GLXEW_ATI_render_texture GLXEW_GET_VAR(__GLXEW_ATI_render_texture) + +#endif /* GLX_ATI_render_texture */ + +/* ------------------------- GLX_EXT_import_context ------------------------ */ + +#ifndef GLX_EXT_import_context +#define GLX_EXT_import_context 1 + +#define GLX_SHARE_CONTEXT_EXT 0x800A +#define GLX_VISUAL_ID_EXT 0x800B +#define GLX_SCREEN_EXT 0x800C + +typedef XID GLXContextID; + +typedef void ( * PFNGLXFREECONTEXTEXTPROC) (Display* dpy, GLXContext context); +typedef GLXContextID ( * PFNGLXGETCONTEXTIDEXTPROC) (const GLXContext context); +typedef GLXContext ( * PFNGLXIMPORTCONTEXTEXTPROC) (Display* dpy, GLXContextID contextID); +typedef int ( * PFNGLXQUERYCONTEXTINFOEXTPROC) (Display* dpy, GLXContext context, int attribute,int *value); + +#define glXFreeContextEXT GLXEW_GET_FUN(__glewXFreeContextEXT) +#define glXGetContextIDEXT GLXEW_GET_FUN(__glewXGetContextIDEXT) +#define glXImportContextEXT GLXEW_GET_FUN(__glewXImportContextEXT) +#define glXQueryContextInfoEXT GLXEW_GET_FUN(__glewXQueryContextInfoEXT) + +#define GLXEW_EXT_import_context GLXEW_GET_VAR(__GLXEW_EXT_import_context) + +#endif /* GLX_EXT_import_context */ + +/* -------------------------- GLX_EXT_scene_marker ------------------------- */ + +#ifndef GLX_EXT_scene_marker +#define GLX_EXT_scene_marker 1 + +#define GLXEW_EXT_scene_marker GLXEW_GET_VAR(__GLXEW_EXT_scene_marker) + +#endif /* GLX_EXT_scene_marker */ + +/* -------------------------- GLX_EXT_visual_info -------------------------- */ + +#ifndef GLX_EXT_visual_info +#define GLX_EXT_visual_info 1 + +#define GLX_X_VISUAL_TYPE_EXT 0x22 +#define GLX_TRANSPARENT_TYPE_EXT 0x23 +#define GLX_TRANSPARENT_INDEX_VALUE_EXT 0x24 +#define GLX_TRANSPARENT_RED_VALUE_EXT 0x25 +#define GLX_TRANSPARENT_GREEN_VALUE_EXT 0x26 +#define GLX_TRANSPARENT_BLUE_VALUE_EXT 0x27 +#define GLX_TRANSPARENT_ALPHA_VALUE_EXT 0x28 +#define GLX_NONE_EXT 0x8000 +#define GLX_TRUE_COLOR_EXT 0x8002 +#define GLX_DIRECT_COLOR_EXT 0x8003 +#define GLX_PSEUDO_COLOR_EXT 0x8004 +#define GLX_STATIC_COLOR_EXT 0x8005 +#define GLX_GRAY_SCALE_EXT 0x8006 +#define GLX_STATIC_GRAY_EXT 0x8007 +#define GLX_TRANSPARENT_RGB_EXT 0x8008 +#define GLX_TRANSPARENT_INDEX_EXT 0x8009 + +#define GLXEW_EXT_visual_info GLXEW_GET_VAR(__GLXEW_EXT_visual_info) + +#endif /* GLX_EXT_visual_info */ + +/* ------------------------- GLX_EXT_visual_rating ------------------------- */ + +#ifndef GLX_EXT_visual_rating +#define GLX_EXT_visual_rating 1 + +#define GLX_VISUAL_CAVEAT_EXT 0x20 +#define GLX_SLOW_VISUAL_EXT 0x8001 +#define GLX_NON_CONFORMANT_VISUAL_EXT 0x800D + +#define GLXEW_EXT_visual_rating GLXEW_GET_VAR(__GLXEW_EXT_visual_rating) + +#endif /* GLX_EXT_visual_rating */ + +/* -------------------------- GLX_MESA_agp_offset -------------------------- */ + +#ifndef GLX_MESA_agp_offset +#define GLX_MESA_agp_offset 1 + +typedef unsigned int ( * PFNGLXGETAGPOFFSETMESAPROC) (const void* pointer); + +#define glXGetAGPOffsetMESA GLXEW_GET_FUN(__glewXGetAGPOffsetMESA) + +#define GLXEW_MESA_agp_offset GLXEW_GET_VAR(__GLXEW_MESA_agp_offset) + +#endif /* GLX_MESA_agp_offset */ + +/* ------------------------ GLX_MESA_copy_sub_buffer ----------------------- */ + +#ifndef GLX_MESA_copy_sub_buffer +#define GLX_MESA_copy_sub_buffer 1 + +typedef void ( * PFNGLXCOPYSUBBUFFERMESAPROC) (Display* dpy, GLXDrawable drawable, int x, int y, int width, int height); + +#define glXCopySubBufferMESA GLXEW_GET_FUN(__glewXCopySubBufferMESA) + +#define GLXEW_MESA_copy_sub_buffer GLXEW_GET_VAR(__GLXEW_MESA_copy_sub_buffer) + +#endif /* GLX_MESA_copy_sub_buffer */ + +/* ------------------------ GLX_MESA_pixmap_colormap ----------------------- */ + +#ifndef GLX_MESA_pixmap_colormap +#define GLX_MESA_pixmap_colormap 1 + +typedef GLXPixmap ( * PFNGLXCREATEGLXPIXMAPMESAPROC) (Display* dpy, XVisualInfo *visual, Pixmap pixmap, Colormap cmap); + +#define glXCreateGLXPixmapMESA GLXEW_GET_FUN(__glewXCreateGLXPixmapMESA) + +#define GLXEW_MESA_pixmap_colormap GLXEW_GET_VAR(__GLXEW_MESA_pixmap_colormap) + +#endif /* GLX_MESA_pixmap_colormap */ + +/* ------------------------ GLX_MESA_release_buffers ----------------------- */ + +#ifndef GLX_MESA_release_buffers +#define GLX_MESA_release_buffers 1 + +typedef Bool ( * PFNGLXRELEASEBUFFERSMESAPROC) (Display* dpy, GLXDrawable d); + +#define glXReleaseBuffersMESA GLXEW_GET_FUN(__glewXReleaseBuffersMESA) + +#define GLXEW_MESA_release_buffers GLXEW_GET_VAR(__GLXEW_MESA_release_buffers) + +#endif /* GLX_MESA_release_buffers */ + +/* ------------------------- GLX_MESA_set_3dfx_mode ------------------------ */ + +#ifndef GLX_MESA_set_3dfx_mode +#define GLX_MESA_set_3dfx_mode 1 + +#define GLX_3DFX_WINDOW_MODE_MESA 0x1 +#define GLX_3DFX_FULLSCREEN_MODE_MESA 0x2 + +typedef GLboolean ( * PFNGLXSET3DFXMODEMESAPROC) (GLint mode); + +#define glXSet3DfxModeMESA GLXEW_GET_FUN(__glewXSet3DfxModeMESA) + +#define GLXEW_MESA_set_3dfx_mode GLXEW_GET_VAR(__GLXEW_MESA_set_3dfx_mode) + +#endif /* GLX_MESA_set_3dfx_mode */ + +/* -------------------------- GLX_NV_float_buffer -------------------------- */ + +#ifndef GLX_NV_float_buffer +#define GLX_NV_float_buffer 1 + +#define GLX_FLOAT_COMPONENTS_NV 0x20B0 + +#define GLXEW_NV_float_buffer GLXEW_GET_VAR(__GLXEW_NV_float_buffer) + +#endif /* GLX_NV_float_buffer */ + +/* ----------------------- GLX_NV_vertex_array_range ----------------------- */ + +#ifndef GLX_NV_vertex_array_range +#define GLX_NV_vertex_array_range 1 + +typedef void * ( * PFNGLXALLOCATEMEMORYNVPROC) (GLsizei size, GLfloat readFrequency, GLfloat writeFrequency, GLfloat priority); +typedef void ( * PFNGLXFREEMEMORYNVPROC) (void *pointer); + +#define glXAllocateMemoryNV GLXEW_GET_FUN(__glewXAllocateMemoryNV) +#define glXFreeMemoryNV GLXEW_GET_FUN(__glewXFreeMemoryNV) + +#define GLXEW_NV_vertex_array_range GLXEW_GET_VAR(__GLXEW_NV_vertex_array_range) + +#endif /* GLX_NV_vertex_array_range */ + +/* -------------------------- GLX_OML_swap_method -------------------------- */ + +#ifndef GLX_OML_swap_method +#define GLX_OML_swap_method 1 + +#define GLX_SWAP_METHOD_OML 0x8060 +#define GLX_SWAP_EXCHANGE_OML 0x8061 +#define GLX_SWAP_COPY_OML 0x8062 +#define GLX_SWAP_UNDEFINED_OML 0x8063 + +#define GLXEW_OML_swap_method GLXEW_GET_VAR(__GLXEW_OML_swap_method) + +#endif /* GLX_OML_swap_method */ + +/* -------------------------- GLX_OML_sync_control ------------------------- */ + +#if !defined(GLX_OML_sync_control) && defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) +#include +#define GLX_OML_sync_control 1 + +typedef Bool ( * PFNGLXGETMSCRATEOMLPROC) (Display* dpy, GLXDrawable drawable, int32_t* numerator, int32_t* denominator); +typedef Bool ( * PFNGLXGETSYNCVALUESOMLPROC) (Display* dpy, GLXDrawable drawable, int64_t* ust, int64_t* msc, int64_t* sbc); +typedef int64_t ( * PFNGLXSWAPBUFFERSMSCOMLPROC) (Display* dpy, GLXDrawable drawable, int64_t target_msc, int64_t divisor, int64_t remainder); +typedef Bool ( * PFNGLXWAITFORMSCOMLPROC) (Display* dpy, GLXDrawable drawable, int64_t target_msc, int64_t divisor, int64_t remainder, int64_t* ust, int64_t* msc, int64_t* sbc); +typedef Bool ( * PFNGLXWAITFORSBCOMLPROC) (Display* dpy, GLXDrawable drawable, int64_t target_sbc, int64_t* ust, int64_t* msc, int64_t* sbc); + +#define glXGetMscRateOML GLXEW_GET_FUN(__glewXGetMscRateOML) +#define glXGetSyncValuesOML GLXEW_GET_FUN(__glewXGetSyncValuesOML) +#define glXSwapBuffersMscOML GLXEW_GET_FUN(__glewXSwapBuffersMscOML) +#define glXWaitForMscOML GLXEW_GET_FUN(__glewXWaitForMscOML) +#define glXWaitForSbcOML GLXEW_GET_FUN(__glewXWaitForSbcOML) + +#define GLXEW_OML_sync_control GLXEW_GET_VAR(__GLXEW_OML_sync_control) + +#endif /* GLX_OML_sync_control */ + +/* ------------------------ GLX_SGIS_blended_overlay ----------------------- */ + +#ifndef GLX_SGIS_blended_overlay +#define GLX_SGIS_blended_overlay 1 + +#define GLX_BLENDED_RGBA_SGIS 0x8025 + +#define GLXEW_SGIS_blended_overlay GLXEW_GET_VAR(__GLXEW_SGIS_blended_overlay) + +#endif /* GLX_SGIS_blended_overlay */ + +/* -------------------------- GLX_SGIS_color_range ------------------------- */ + +#ifndef GLX_SGIS_color_range +#define GLX_SGIS_color_range 1 + +#define GLX_MIN_RED_SGIS 0 +#define GLX_MAX_GREEN_SGIS 0 +#define GLX_MIN_BLUE_SGIS 0 +#define GLX_MAX_ALPHA_SGIS 0 +#define GLX_MIN_GREEN_SGIS 0 +#define GLX_MIN_ALPHA_SGIS 0 +#define GLX_MAX_RED_SGIS 0 +#define GLX_EXTENDED_RANGE_SGIS 0 +#define GLX_MAX_BLUE_SGIS 0 + +#define GLXEW_SGIS_color_range GLXEW_GET_VAR(__GLXEW_SGIS_color_range) + +#endif /* GLX_SGIS_color_range */ + +/* -------------------------- GLX_SGIS_multisample ------------------------- */ + +#ifndef GLX_SGIS_multisample +#define GLX_SGIS_multisample 1 + +#define GLX_SAMPLE_BUFFERS_SGIS 100000 +#define GLX_SAMPLES_SGIS 100001 + +#define GLXEW_SGIS_multisample GLXEW_GET_VAR(__GLXEW_SGIS_multisample) + +#endif /* GLX_SGIS_multisample */ + +/* ---------------------- GLX_SGIS_shared_multisample ---------------------- */ + +#ifndef GLX_SGIS_shared_multisample +#define GLX_SGIS_shared_multisample 1 + +#define GLX_MULTISAMPLE_SUB_RECT_WIDTH_SGIS 0x8026 +#define GLX_MULTISAMPLE_SUB_RECT_HEIGHT_SGIS 0x8027 + +#define GLXEW_SGIS_shared_multisample GLXEW_GET_VAR(__GLXEW_SGIS_shared_multisample) + +#endif /* GLX_SGIS_shared_multisample */ + +/* --------------------------- GLX_SGIX_fbconfig --------------------------- */ + +#ifndef GLX_SGIX_fbconfig +#define GLX_SGIX_fbconfig 1 + +#define GLX_WINDOW_BIT_SGIX 0x00000001 +#define GLX_RGBA_BIT_SGIX 0x00000001 +#define GLX_PIXMAP_BIT_SGIX 0x00000002 +#define GLX_COLOR_INDEX_BIT_SGIX 0x00000002 +#define GLX_SCREEN_EXT 0x800C +#define GLX_DRAWABLE_TYPE_SGIX 0x8010 +#define GLX_RENDER_TYPE_SGIX 0x8011 +#define GLX_X_RENDERABLE_SGIX 0x8012 +#define GLX_FBCONFIG_ID_SGIX 0x8013 +#define GLX_RGBA_TYPE_SGIX 0x8014 +#define GLX_COLOR_INDEX_TYPE_SGIX 0x8015 + +typedef XID GLXFBConfigIDSGIX; +typedef struct __GLXFBConfigRec *GLXFBConfigSGIX; + +typedef GLXFBConfigSGIX* ( * PFNGLXCHOOSEFBCONFIGSGIXPROC) (Display *dpy, int screen, const int *attrib_list, int *nelements); +typedef GLXContext ( * PFNGLXCREATECONTEXTWITHCONFIGSGIXPROC) (Display* dpy, GLXFBConfig config, int render_type, GLXContext share_list, Bool direct); +typedef GLXPixmap ( * PFNGLXCREATEGLXPIXMAPWITHCONFIGSGIXPROC) (Display* dpy, GLXFBConfig config, Pixmap pixmap); +typedef int ( * PFNGLXGETFBCONFIGATTRIBSGIXPROC) (Display* dpy, GLXFBConfigSGIX config, int attribute, int *value); +typedef GLXFBConfigSGIX ( * PFNGLXGETFBCONFIGFROMVISUALSGIXPROC) (Display* dpy, XVisualInfo *vis); +typedef XVisualInfo* ( * PFNGLXGETVISUALFROMFBCONFIGSGIXPROC) (Display *dpy, GLXFBConfig config); + +#define glXChooseFBConfigSGIX GLXEW_GET_FUN(__glewXChooseFBConfigSGIX) +#define glXCreateContextWithConfigSGIX GLXEW_GET_FUN(__glewXCreateContextWithConfigSGIX) +#define glXCreateGLXPixmapWithConfigSGIX GLXEW_GET_FUN(__glewXCreateGLXPixmapWithConfigSGIX) +#define glXGetFBConfigAttribSGIX GLXEW_GET_FUN(__glewXGetFBConfigAttribSGIX) +#define glXGetFBConfigFromVisualSGIX GLXEW_GET_FUN(__glewXGetFBConfigFromVisualSGIX) +#define glXGetVisualFromFBConfigSGIX GLXEW_GET_FUN(__glewXGetVisualFromFBConfigSGIX) + +#define GLXEW_SGIX_fbconfig GLXEW_GET_VAR(__GLXEW_SGIX_fbconfig) + +#endif /* GLX_SGIX_fbconfig */ + +/* ---------------------------- GLX_SGIX_pbuffer --------------------------- */ + +#ifndef GLX_SGIX_pbuffer +#define GLX_SGIX_pbuffer 1 + +#define GLX_FRONT_LEFT_BUFFER_BIT_SGIX 0x00000001 +#define GLX_FRONT_RIGHT_BUFFER_BIT_SGIX 0x00000002 +#define GLX_PBUFFER_BIT_SGIX 0x00000004 +#define GLX_BACK_LEFT_BUFFER_BIT_SGIX 0x00000004 +#define GLX_BACK_RIGHT_BUFFER_BIT_SGIX 0x00000008 +#define GLX_AUX_BUFFERS_BIT_SGIX 0x00000010 +#define GLX_DEPTH_BUFFER_BIT_SGIX 0x00000020 +#define GLX_STENCIL_BUFFER_BIT_SGIX 0x00000040 +#define GLX_ACCUM_BUFFER_BIT_SGIX 0x00000080 +#define GLX_SAMPLE_BUFFERS_BIT_SGIX 0x00000100 +#define GLX_MAX_PBUFFER_WIDTH_SGIX 0x8016 +#define GLX_MAX_PBUFFER_HEIGHT_SGIX 0x8017 +#define GLX_MAX_PBUFFER_PIXELS_SGIX 0x8018 +#define GLX_OPTIMAL_PBUFFER_WIDTH_SGIX 0x8019 +#define GLX_OPTIMAL_PBUFFER_HEIGHT_SGIX 0x801A +#define GLX_PRESERVED_CONTENTS_SGIX 0x801B +#define GLX_LARGEST_PBUFFER_SGIX 0x801C +#define GLX_WIDTH_SGIX 0x801D +#define GLX_HEIGHT_SGIX 0x801E +#define GLX_EVENT_MASK_SGIX 0x801F +#define GLX_DAMAGED_SGIX 0x8020 +#define GLX_SAVED_SGIX 0x8021 +#define GLX_WINDOW_SGIX 0x8022 +#define GLX_PBUFFER_SGIX 0x8023 +#define GLX_BUFFER_CLOBBER_MASK_SGIX 0x08000000 + +typedef XID GLXPbufferSGIX; +typedef struct { int type; unsigned long serial; Bool send_event; Display *display; GLXDrawable drawable; int event_type; int draw_type; unsigned int mask; int x, y; int width, height; int count; } GLXBufferClobberEventSGIX; + +typedef GLXPbuffer ( * PFNGLXCREATEGLXPBUFFERSGIXPROC) (Display* dpy, GLXFBConfig config, unsigned int width, unsigned int height, int *attrib_list); +typedef void ( * PFNGLXDESTROYGLXPBUFFERSGIXPROC) (Display* dpy, GLXPbuffer pbuf); +typedef void ( * PFNGLXGETSELECTEDEVENTSGIXPROC) (Display* dpy, GLXDrawable drawable, unsigned long *mask); +typedef void ( * PFNGLXQUERYGLXPBUFFERSGIXPROC) (Display* dpy, GLXPbuffer pbuf, int attribute, unsigned int *value); +typedef void ( * PFNGLXSELECTEVENTSGIXPROC) (Display* dpy, GLXDrawable drawable, unsigned long mask); + +#define glXCreateGLXPbufferSGIX GLXEW_GET_FUN(__glewXCreateGLXPbufferSGIX) +#define glXDestroyGLXPbufferSGIX GLXEW_GET_FUN(__glewXDestroyGLXPbufferSGIX) +#define glXGetSelectedEventSGIX GLXEW_GET_FUN(__glewXGetSelectedEventSGIX) +#define glXQueryGLXPbufferSGIX GLXEW_GET_FUN(__glewXQueryGLXPbufferSGIX) +#define glXSelectEventSGIX GLXEW_GET_FUN(__glewXSelectEventSGIX) + +#define GLXEW_SGIX_pbuffer GLXEW_GET_VAR(__GLXEW_SGIX_pbuffer) + +#endif /* GLX_SGIX_pbuffer */ + +/* ------------------------- GLX_SGIX_swap_barrier ------------------------- */ + +#ifndef GLX_SGIX_swap_barrier +#define GLX_SGIX_swap_barrier 1 + +typedef void ( * PFNGLXBINDSWAPBARRIERSGIXPROC) (Display *dpy, GLXDrawable drawable, int barrier); +typedef Bool ( * PFNGLXQUERYMAXSWAPBARRIERSSGIXPROC) (Display *dpy, int screen, int *max); + +#define glXBindSwapBarrierSGIX GLXEW_GET_FUN(__glewXBindSwapBarrierSGIX) +#define glXQueryMaxSwapBarriersSGIX GLXEW_GET_FUN(__glewXQueryMaxSwapBarriersSGIX) + +#define GLXEW_SGIX_swap_barrier GLXEW_GET_VAR(__GLXEW_SGIX_swap_barrier) + +#endif /* GLX_SGIX_swap_barrier */ + +/* -------------------------- GLX_SGIX_swap_group -------------------------- */ + +#ifndef GLX_SGIX_swap_group +#define GLX_SGIX_swap_group 1 + +typedef void ( * PFNGLXJOINSWAPGROUPSGIXPROC) (Display *dpy, GLXDrawable drawable, GLXDrawable member); + +#define glXJoinSwapGroupSGIX GLXEW_GET_FUN(__glewXJoinSwapGroupSGIX) + +#define GLXEW_SGIX_swap_group GLXEW_GET_VAR(__GLXEW_SGIX_swap_group) + +#endif /* GLX_SGIX_swap_group */ + +/* ------------------------- GLX_SGIX_video_resize ------------------------- */ + +#ifndef GLX_SGIX_video_resize +#define GLX_SGIX_video_resize 1 + +#define GLX_SYNC_FRAME_SGIX 0x00000000 +#define GLX_SYNC_SWAP_SGIX 0x00000001 + +typedef int ( * PFNGLXBINDCHANNELTOWINDOWSGIXPROC) (Display* display, int screen, int channel, Window window); +typedef int ( * PFNGLXCHANNELRECTSGIXPROC) (Display* display, int screen, int channel, int x, int y, int w, int h); +typedef int ( * PFNGLXCHANNELRECTSYNCSGIXPROC) (Display* display, int screen, int channel, GLenum synctype); +typedef int ( * PFNGLXQUERYCHANNELDELTASSGIXPROC) (Display* display, int screen, int channel, int *x, int *y, int *w, int *h); +typedef int ( * PFNGLXQUERYCHANNELRECTSGIXPROC) (Display* display, int screen, int channel, int *dx, int *dy, int *dw, int *dh); + +#define glXBindChannelToWindowSGIX GLXEW_GET_FUN(__glewXBindChannelToWindowSGIX) +#define glXChannelRectSGIX GLXEW_GET_FUN(__glewXChannelRectSGIX) +#define glXChannelRectSyncSGIX GLXEW_GET_FUN(__glewXChannelRectSyncSGIX) +#define glXQueryChannelDeltasSGIX GLXEW_GET_FUN(__glewXQueryChannelDeltasSGIX) +#define glXQueryChannelRectSGIX GLXEW_GET_FUN(__glewXQueryChannelRectSGIX) + +#define GLXEW_SGIX_video_resize GLXEW_GET_VAR(__GLXEW_SGIX_video_resize) + +#endif /* GLX_SGIX_video_resize */ + +/* ---------------------- GLX_SGIX_visual_select_group --------------------- */ + +#ifndef GLX_SGIX_visual_select_group +#define GLX_SGIX_visual_select_group 1 + +#define GLX_VISUAL_SELECT_GROUP_SGIX 0x8028 + +#define GLXEW_SGIX_visual_select_group GLXEW_GET_VAR(__GLXEW_SGIX_visual_select_group) + +#endif /* GLX_SGIX_visual_select_group */ + +/* ---------------------------- GLX_SGI_cushion ---------------------------- */ + +#ifndef GLX_SGI_cushion +#define GLX_SGI_cushion 1 + +typedef void ( * PFNGLXCUSHIONSGIPROC) (Display* dpy, Window window, float cushion); + +#define glXCushionSGI GLXEW_GET_FUN(__glewXCushionSGI) + +#define GLXEW_SGI_cushion GLXEW_GET_VAR(__GLXEW_SGI_cushion) + +#endif /* GLX_SGI_cushion */ + +/* ----------------------- GLX_SGI_make_current_read ----------------------- */ + +#ifndef GLX_SGI_make_current_read +#define GLX_SGI_make_current_read 1 + +typedef GLXDrawable ( * PFNGLXGETCURRENTREADDRAWABLESGIPROC) (void); +typedef Bool ( * PFNGLXMAKECURRENTREADSGIPROC) (Display* dpy, GLXDrawable draw, GLXDrawable read, GLXContext ctx); + +#define glXGetCurrentReadDrawableSGI GLXEW_GET_FUN(__glewXGetCurrentReadDrawableSGI) +#define glXMakeCurrentReadSGI GLXEW_GET_FUN(__glewXMakeCurrentReadSGI) + +#define GLXEW_SGI_make_current_read GLXEW_GET_VAR(__GLXEW_SGI_make_current_read) + +#endif /* GLX_SGI_make_current_read */ + +/* -------------------------- GLX_SGI_swap_control ------------------------- */ + +#ifndef GLX_SGI_swap_control +#define GLX_SGI_swap_control 1 + +typedef int ( * PFNGLXSWAPINTERVALSGIPROC) (int interval); + +#define glXSwapIntervalSGI GLXEW_GET_FUN(__glewXSwapIntervalSGI) + +#define GLXEW_SGI_swap_control GLXEW_GET_VAR(__GLXEW_SGI_swap_control) + +#endif /* GLX_SGI_swap_control */ + +/* --------------------------- GLX_SGI_video_sync -------------------------- */ + +#ifndef GLX_SGI_video_sync +#define GLX_SGI_video_sync 1 + +typedef int ( * PFNGLXGETVIDEOSYNCSGIPROC) (uint* count); +typedef int ( * PFNGLXWAITVIDEOSYNCSGIPROC) (int divisor, int remainder, unsigned int* count); + +#define glXGetVideoSyncSGI GLXEW_GET_FUN(__glewXGetVideoSyncSGI) +#define glXWaitVideoSyncSGI GLXEW_GET_FUN(__glewXWaitVideoSyncSGI) + +#define GLXEW_SGI_video_sync GLXEW_GET_VAR(__GLXEW_SGI_video_sync) + +#endif /* GLX_SGI_video_sync */ + +/* --------------------- GLX_SUN_get_transparent_index --------------------- */ + +#ifndef GLX_SUN_get_transparent_index +#define GLX_SUN_get_transparent_index 1 + +typedef Status ( * PFNGLXGETTRANSPARENTINDEXSUNPROC) (Display* dpy, Window overlay, Window underlay, unsigned long *pTransparentIndex); + +#define glXGetTransparentIndexSUN GLXEW_GET_FUN(__glewXGetTransparentIndexSUN) + +#define GLXEW_SUN_get_transparent_index GLXEW_GET_VAR(__GLXEW_SUN_get_transparent_index) + +#endif /* GLX_SUN_get_transparent_index */ + +/* -------------------------- GLX_SUN_video_resize ------------------------- */ + +#ifndef GLX_SUN_video_resize +#define GLX_SUN_video_resize 1 + +#define GLX_VIDEO_RESIZE_SUN 0x8171 +#define GL_VIDEO_RESIZE_COMPENSATION_SUN 0x85CD + +typedef int ( * PFNGLXGETVIDEORESIZESUNPROC) (Display* display, GLXDrawable window, float* factor); +typedef int ( * PFNGLXVIDEORESIZESUNPROC) (Display* display, GLXDrawable window, float factor); + +#define glXGetVideoResizeSUN GLXEW_GET_FUN(__glewXGetVideoResizeSUN) +#define glXVideoResizeSUN GLXEW_GET_FUN(__glewXVideoResizeSUN) + +#define GLXEW_SUN_video_resize GLXEW_GET_VAR(__GLXEW_SUN_video_resize) + +#endif /* GLX_SUN_video_resize */ + +/* ------------------------------------------------------------------------- */ + +#ifdef GLEW_MX +#define GLXEW_EXPORT +#else +#define GLXEW_EXPORT extern +#endif /* GLEW_MX */ + +extern PFNGLXGETCURRENTDISPLAYPROC __glewXGetCurrentDisplay; + +extern PFNGLXCHOOSEFBCONFIGPROC __glewXChooseFBConfig; +extern PFNGLXCREATENEWCONTEXTPROC __glewXCreateNewContext; +extern PFNGLXCREATEPBUFFERPROC __glewXCreatePbuffer; +extern PFNGLXCREATEPIXMAPPROC __glewXCreatePixmap; +extern PFNGLXCREATEWINDOWPROC __glewXCreateWindow; +extern PFNGLXDESTROYPBUFFERPROC __glewXDestroyPbuffer; +extern PFNGLXDESTROYPIXMAPPROC __glewXDestroyPixmap; +extern PFNGLXDESTROYWINDOWPROC __glewXDestroyWindow; +extern PFNGLXGETCURRENTREADDRAWABLEPROC __glewXGetCurrentReadDrawable; +extern PFNGLXGETFBCONFIGATTRIBPROC __glewXGetFBConfigAttrib; +extern PFNGLXGETFBCONFIGSPROC __glewXGetFBConfigs; +extern PFNGLXGETSELECTEDEVENTPROC __glewXGetSelectedEvent; +extern PFNGLXGETVISUALFROMFBCONFIGPROC __glewXGetVisualFromFBConfig; +extern PFNGLXMAKECONTEXTCURRENTPROC __glewXMakeContextCurrent; +extern PFNGLXQUERYCONTEXTPROC __glewXQueryContext; +extern PFNGLXQUERYDRAWABLEPROC __glewXQueryDrawable; +extern PFNGLXSELECTEVENTPROC __glewXSelectEvent; + +extern PFNGLXBINDTEXIMAGEATIPROC __glewXBindTexImageATI; +extern PFNGLXDRAWABLEATTRIBATIPROC __glewXDrawableAttribATI; +extern PFNGLXRELEASETEXIMAGEATIPROC __glewXReleaseTexImageATI; + +extern PFNGLXFREECONTEXTEXTPROC __glewXFreeContextEXT; +extern PFNGLXGETCONTEXTIDEXTPROC __glewXGetContextIDEXT; +extern PFNGLXIMPORTCONTEXTEXTPROC __glewXImportContextEXT; +extern PFNGLXQUERYCONTEXTINFOEXTPROC __glewXQueryContextInfoEXT; + +extern PFNGLXGETAGPOFFSETMESAPROC __glewXGetAGPOffsetMESA; + +extern PFNGLXCOPYSUBBUFFERMESAPROC __glewXCopySubBufferMESA; + +extern PFNGLXCREATEGLXPIXMAPMESAPROC __glewXCreateGLXPixmapMESA; + +extern PFNGLXRELEASEBUFFERSMESAPROC __glewXReleaseBuffersMESA; + +extern PFNGLXSET3DFXMODEMESAPROC __glewXSet3DfxModeMESA; + +extern PFNGLXALLOCATEMEMORYNVPROC __glewXAllocateMemoryNV; +extern PFNGLXFREEMEMORYNVPROC __glewXFreeMemoryNV; + +#ifdef GLX_OML_sync_control +extern PFNGLXGETMSCRATEOMLPROC __glewXGetMscRateOML; +extern PFNGLXGETSYNCVALUESOMLPROC __glewXGetSyncValuesOML; +extern PFNGLXSWAPBUFFERSMSCOMLPROC __glewXSwapBuffersMscOML; +extern PFNGLXWAITFORMSCOMLPROC __glewXWaitForMscOML; +extern PFNGLXWAITFORSBCOMLPROC __glewXWaitForSbcOML; +#endif + +extern PFNGLXCHOOSEFBCONFIGSGIXPROC __glewXChooseFBConfigSGIX; +extern PFNGLXCREATECONTEXTWITHCONFIGSGIXPROC __glewXCreateContextWithConfigSGIX; +extern PFNGLXCREATEGLXPIXMAPWITHCONFIGSGIXPROC __glewXCreateGLXPixmapWithConfigSGIX; +extern PFNGLXGETFBCONFIGATTRIBSGIXPROC __glewXGetFBConfigAttribSGIX; +extern PFNGLXGETFBCONFIGFROMVISUALSGIXPROC __glewXGetFBConfigFromVisualSGIX; +extern PFNGLXGETVISUALFROMFBCONFIGSGIXPROC __glewXGetVisualFromFBConfigSGIX; + +extern PFNGLXCREATEGLXPBUFFERSGIXPROC __glewXCreateGLXPbufferSGIX; +extern PFNGLXDESTROYGLXPBUFFERSGIXPROC __glewXDestroyGLXPbufferSGIX; +extern PFNGLXGETSELECTEDEVENTSGIXPROC __glewXGetSelectedEventSGIX; +extern PFNGLXQUERYGLXPBUFFERSGIXPROC __glewXQueryGLXPbufferSGIX; +extern PFNGLXSELECTEVENTSGIXPROC __glewXSelectEventSGIX; + +extern PFNGLXBINDSWAPBARRIERSGIXPROC __glewXBindSwapBarrierSGIX; +extern PFNGLXQUERYMAXSWAPBARRIERSSGIXPROC __glewXQueryMaxSwapBarriersSGIX; + +extern PFNGLXJOINSWAPGROUPSGIXPROC __glewXJoinSwapGroupSGIX; + +extern PFNGLXBINDCHANNELTOWINDOWSGIXPROC __glewXBindChannelToWindowSGIX; +extern PFNGLXCHANNELRECTSGIXPROC __glewXChannelRectSGIX; +extern PFNGLXCHANNELRECTSYNCSGIXPROC __glewXChannelRectSyncSGIX; +extern PFNGLXQUERYCHANNELDELTASSGIXPROC __glewXQueryChannelDeltasSGIX; +extern PFNGLXQUERYCHANNELRECTSGIXPROC __glewXQueryChannelRectSGIX; + +extern PFNGLXCUSHIONSGIPROC __glewXCushionSGI; + +extern PFNGLXGETCURRENTREADDRAWABLESGIPROC __glewXGetCurrentReadDrawableSGI; +extern PFNGLXMAKECURRENTREADSGIPROC __glewXMakeCurrentReadSGI; + +extern PFNGLXSWAPINTERVALSGIPROC __glewXSwapIntervalSGI; + +extern PFNGLXGETVIDEOSYNCSGIPROC __glewXGetVideoSyncSGI; +extern PFNGLXWAITVIDEOSYNCSGIPROC __glewXWaitVideoSyncSGI; + +extern PFNGLXGETTRANSPARENTINDEXSUNPROC __glewXGetTransparentIndexSUN; + +extern PFNGLXGETVIDEORESIZESUNPROC __glewXGetVideoResizeSUN; +extern PFNGLXVIDEORESIZESUNPROC __glewXVideoResizeSUN; + +#if defined(GLEW_MX) +struct GLXEWContextStruct +{ +#endif /* GLEW_MX */ + +GLXEW_EXPORT GLboolean __GLXEW_VERSION_1_0; +GLXEW_EXPORT GLboolean __GLXEW_VERSION_1_1; +GLXEW_EXPORT GLboolean __GLXEW_VERSION_1_2; +GLXEW_EXPORT GLboolean __GLXEW_VERSION_1_3; +GLXEW_EXPORT GLboolean __GLXEW_VERSION_1_4; +GLXEW_EXPORT GLboolean __GLXEW_3DFX_multisample; +GLXEW_EXPORT GLboolean __GLXEW_ARB_fbconfig_float; +GLXEW_EXPORT GLboolean __GLXEW_ARB_get_proc_address; +GLXEW_EXPORT GLboolean __GLXEW_ARB_multisample; +GLXEW_EXPORT GLboolean __GLXEW_ATI_pixel_format_float; +GLXEW_EXPORT GLboolean __GLXEW_ATI_render_texture; +GLXEW_EXPORT GLboolean __GLXEW_EXT_import_context; +GLXEW_EXPORT GLboolean __GLXEW_EXT_scene_marker; +GLXEW_EXPORT GLboolean __GLXEW_EXT_visual_info; +GLXEW_EXPORT GLboolean __GLXEW_EXT_visual_rating; +GLXEW_EXPORT GLboolean __GLXEW_MESA_agp_offset; +GLXEW_EXPORT GLboolean __GLXEW_MESA_copy_sub_buffer; +GLXEW_EXPORT GLboolean __GLXEW_MESA_pixmap_colormap; +GLXEW_EXPORT GLboolean __GLXEW_MESA_release_buffers; +GLXEW_EXPORT GLboolean __GLXEW_MESA_set_3dfx_mode; +GLXEW_EXPORT GLboolean __GLXEW_NV_float_buffer; +GLXEW_EXPORT GLboolean __GLXEW_NV_vertex_array_range; +GLXEW_EXPORT GLboolean __GLXEW_OML_swap_method; +GLXEW_EXPORT GLboolean __GLXEW_OML_sync_control; +GLXEW_EXPORT GLboolean __GLXEW_SGIS_blended_overlay; +GLXEW_EXPORT GLboolean __GLXEW_SGIS_color_range; +GLXEW_EXPORT GLboolean __GLXEW_SGIS_multisample; +GLXEW_EXPORT GLboolean __GLXEW_SGIS_shared_multisample; +GLXEW_EXPORT GLboolean __GLXEW_SGIX_fbconfig; +GLXEW_EXPORT GLboolean __GLXEW_SGIX_pbuffer; +GLXEW_EXPORT GLboolean __GLXEW_SGIX_swap_barrier; +GLXEW_EXPORT GLboolean __GLXEW_SGIX_swap_group; +GLXEW_EXPORT GLboolean __GLXEW_SGIX_video_resize; +GLXEW_EXPORT GLboolean __GLXEW_SGIX_visual_select_group; +GLXEW_EXPORT GLboolean __GLXEW_SGI_cushion; +GLXEW_EXPORT GLboolean __GLXEW_SGI_make_current_read; +GLXEW_EXPORT GLboolean __GLXEW_SGI_swap_control; +GLXEW_EXPORT GLboolean __GLXEW_SGI_video_sync; +GLXEW_EXPORT GLboolean __GLXEW_SUN_get_transparent_index; +GLXEW_EXPORT GLboolean __GLXEW_SUN_video_resize; + +#ifdef GLEW_MX +}; /* GLXEWContextStruct */ +#endif /* GLEW_MX */ + +/* ------------------------------------------------------------------------ */ + +#ifdef GLEW_MX + +typedef struct GLXEWContextStruct GLXEWContext; +extern GLenum glxewContextInit (GLXEWContext* ctx); +extern GLboolean glxewContextIsSupported (GLXEWContext* ctx, const char* name); + +#define glxewInit() glxewContextInit(glxewGetContext()) +#define glxewIsSupported(x) glxewContextIsSupported(glxewGetContext(), x) + +#define GLXEW_GET_VAR(x) glxewGetContext()->x +#define GLXEW_GET_FUN(x) x + +#else /* GLEW_MX */ + +#define GLXEW_GET_VAR(x) x +#define GLXEW_GET_FUN(x) x + +extern GLboolean glxewIsSupported (const char* name); + +#endif /* GLEW_MX */ + +extern GLboolean glxewGetExtension (const char* name); + +#ifdef __cplusplus +} +#endif + +#endif /* __glxew_h__ */ diff --git a/extern/glew/include/GL/wglew.h b/extern/glew/include/GL/wglew.h new file mode 100644 index 00000000000..febb1d07399 --- /dev/null +++ b/extern/glew/include/GL/wglew.h @@ -0,0 +1,934 @@ +/* +** The OpenGL Extension Wrangler Library +** Copyright (C) 2002-2006, Milan Ikits +** Copyright (C) 2002-2006, Marcelo E. Magallon +** Copyright (C) 2002, Lev Povalahev +** 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. +** * The name of the author 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. +*/ + +#ifndef __wglew_h__ +#define __wglew_h__ +#define __WGLEW_H__ + +#ifdef __wglext_h_ +#error wglext.h included before wglew.h +#endif + +#define __wglext_h_ + +#if !defined(APIENTRY) && !defined(__CYGWIN__) +# ifndef WIN32_LEAN_AND_MEAN +# define WIN32_LEAN_AND_MEAN 1 +# endif +#include +#endif + +/* + * GLEW_STATIC needs to be set when using the static version. + * GLEW_BUILD is set when building the DLL version. + */ +#ifdef GLEW_STATIC +# define GLEWAPI extern +#else +# ifdef GLEW_BUILD +# define GLEWAPI extern __declspec(dllexport) +# else +# define GLEWAPI extern __declspec(dllimport) +# endif +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/* -------------------------- WGL_3DFX_multisample ------------------------- */ + +#ifndef WGL_3DFX_multisample +#define WGL_3DFX_multisample 1 + +#define WGL_SAMPLE_BUFFERS_3DFX 0x2060 +#define WGL_SAMPLES_3DFX 0x2061 + +#define WGLEW_3DFX_multisample WGLEW_GET_VAR(__WGLEW_3DFX_multisample) + +#endif /* WGL_3DFX_multisample */ + +/* ------------------------- WGL_3DL_stereo_control ------------------------ */ + +#ifndef WGL_3DL_stereo_control +#define WGL_3DL_stereo_control 1 + +#define WGL_STEREO_EMITTER_ENABLE_3DL 0x2055 +#define WGL_STEREO_EMITTER_DISABLE_3DL 0x2056 +#define WGL_STEREO_POLARITY_NORMAL_3DL 0x2057 +#define WGL_STEREO_POLARITY_INVERT_3DL 0x2058 + +typedef BOOL (WINAPI * PFNWGLSETSTEREOEMITTERSTATE3DLPROC) (HDC hDC, UINT uState); + +#define wglSetStereoEmitterState3DL WGLEW_GET_FUN(__wglewSetStereoEmitterState3DL) + +#define WGLEW_3DL_stereo_control WGLEW_GET_VAR(__WGLEW_3DL_stereo_control) + +#endif /* WGL_3DL_stereo_control */ + +/* ------------------------- WGL_ARB_buffer_region ------------------------- */ + +#ifndef WGL_ARB_buffer_region +#define WGL_ARB_buffer_region 1 + +#define WGL_FRONT_COLOR_BUFFER_BIT_ARB 0x00000001 +#define WGL_BACK_COLOR_BUFFER_BIT_ARB 0x00000002 +#define WGL_DEPTH_BUFFER_BIT_ARB 0x00000004 +#define WGL_STENCIL_BUFFER_BIT_ARB 0x00000008 + +typedef HANDLE (WINAPI * PFNWGLCREATEBUFFERREGIONARBPROC) (HDC hDC, int iLayerPlane, UINT uType); +typedef VOID (WINAPI * PFNWGLDELETEBUFFERREGIONARBPROC) (HANDLE hRegion); +typedef BOOL (WINAPI * PFNWGLRESTOREBUFFERREGIONARBPROC) (HANDLE hRegion, int x, int y, int width, int height, int xSrc, int ySrc); +typedef BOOL (WINAPI * PFNWGLSAVEBUFFERREGIONARBPROC) (HANDLE hRegion, int x, int y, int width, int height); + +#define wglCreateBufferRegionARB WGLEW_GET_FUN(__wglewCreateBufferRegionARB) +#define wglDeleteBufferRegionARB WGLEW_GET_FUN(__wglewDeleteBufferRegionARB) +#define wglRestoreBufferRegionARB WGLEW_GET_FUN(__wglewRestoreBufferRegionARB) +#define wglSaveBufferRegionARB WGLEW_GET_FUN(__wglewSaveBufferRegionARB) + +#define WGLEW_ARB_buffer_region WGLEW_GET_VAR(__WGLEW_ARB_buffer_region) + +#endif /* WGL_ARB_buffer_region */ + +/* ----------------------- WGL_ARB_extensions_string ----------------------- */ + +#ifndef WGL_ARB_extensions_string +#define WGL_ARB_extensions_string 1 + +typedef const char* (WINAPI * PFNWGLGETEXTENSIONSSTRINGARBPROC) (HDC hdc); + +#define wglGetExtensionsStringARB WGLEW_GET_FUN(__wglewGetExtensionsStringARB) + +#define WGLEW_ARB_extensions_string WGLEW_GET_VAR(__WGLEW_ARB_extensions_string) + +#endif /* WGL_ARB_extensions_string */ + +/* ----------------------- WGL_ARB_make_current_read ----------------------- */ + +#ifndef WGL_ARB_make_current_read +#define WGL_ARB_make_current_read 1 + +typedef HDC (WINAPI * PFNWGLGETCURRENTREADDCARBPROC) (VOID); +typedef BOOL (WINAPI * PFNWGLMAKECONTEXTCURRENTARBPROC) (HDC hDrawDC, HDC hReadDC, HGLRC hglrc); + +#define wglGetCurrentReadDCARB WGLEW_GET_FUN(__wglewGetCurrentReadDCARB) +#define wglMakeContextCurrentARB WGLEW_GET_FUN(__wglewMakeContextCurrentARB) + +#define WGLEW_ARB_make_current_read WGLEW_GET_VAR(__WGLEW_ARB_make_current_read) + +#endif /* WGL_ARB_make_current_read */ + +/* -------------------------- WGL_ARB_multisample -------------------------- */ + +#ifndef WGL_ARB_multisample +#define WGL_ARB_multisample 1 + +#define WGL_SAMPLE_BUFFERS_ARB 0x2041 +#define WGL_SAMPLES_ARB 0x2042 + +#define WGLEW_ARB_multisample WGLEW_GET_VAR(__WGLEW_ARB_multisample) + +#endif /* WGL_ARB_multisample */ + +/* ---------------------------- WGL_ARB_pbuffer ---------------------------- */ + +#ifndef WGL_ARB_pbuffer +#define WGL_ARB_pbuffer 1 + +#define WGL_DRAW_TO_PBUFFER_ARB 0x202D +#define WGL_MAX_PBUFFER_PIXELS_ARB 0x202E +#define WGL_MAX_PBUFFER_WIDTH_ARB 0x202F +#define WGL_MAX_PBUFFER_HEIGHT_ARB 0x2030 +#define WGL_PBUFFER_LARGEST_ARB 0x2033 +#define WGL_PBUFFER_WIDTH_ARB 0x2034 +#define WGL_PBUFFER_HEIGHT_ARB 0x2035 +#define WGL_PBUFFER_LOST_ARB 0x2036 + +DECLARE_HANDLE(HPBUFFERARB); + +typedef HPBUFFERARB (WINAPI * PFNWGLCREATEPBUFFERARBPROC) (HDC hDC, int iPixelFormat, int iWidth, int iHeight, const int* piAttribList); +typedef BOOL (WINAPI * PFNWGLDESTROYPBUFFERARBPROC) (HPBUFFERARB hPbuffer); +typedef HDC (WINAPI * PFNWGLGETPBUFFERDCARBPROC) (HPBUFFERARB hPbuffer); +typedef BOOL (WINAPI * PFNWGLQUERYPBUFFERARBPROC) (HPBUFFERARB hPbuffer, int iAttribute, int* piValue); +typedef int (WINAPI * PFNWGLRELEASEPBUFFERDCARBPROC) (HPBUFFERARB hPbuffer, HDC hDC); + +#define wglCreatePbufferARB WGLEW_GET_FUN(__wglewCreatePbufferARB) +#define wglDestroyPbufferARB WGLEW_GET_FUN(__wglewDestroyPbufferARB) +#define wglGetPbufferDCARB WGLEW_GET_FUN(__wglewGetPbufferDCARB) +#define wglQueryPbufferARB WGLEW_GET_FUN(__wglewQueryPbufferARB) +#define wglReleasePbufferDCARB WGLEW_GET_FUN(__wglewReleasePbufferDCARB) + +#define WGLEW_ARB_pbuffer WGLEW_GET_VAR(__WGLEW_ARB_pbuffer) + +#endif /* WGL_ARB_pbuffer */ + +/* -------------------------- WGL_ARB_pixel_format ------------------------- */ + +#ifndef WGL_ARB_pixel_format +#define WGL_ARB_pixel_format 1 + +#define WGL_NUMBER_PIXEL_FORMATS_ARB 0x2000 +#define WGL_DRAW_TO_WINDOW_ARB 0x2001 +#define WGL_DRAW_TO_BITMAP_ARB 0x2002 +#define WGL_ACCELERATION_ARB 0x2003 +#define WGL_NEED_PALETTE_ARB 0x2004 +#define WGL_NEED_SYSTEM_PALETTE_ARB 0x2005 +#define WGL_SWAP_LAYER_BUFFERS_ARB 0x2006 +#define WGL_SWAP_METHOD_ARB 0x2007 +#define WGL_NUMBER_OVERLAYS_ARB 0x2008 +#define WGL_NUMBER_UNDERLAYS_ARB 0x2009 +#define WGL_TRANSPARENT_ARB 0x200A +#define WGL_SHARE_DEPTH_ARB 0x200C +#define WGL_SHARE_STENCIL_ARB 0x200D +#define WGL_SHARE_ACCUM_ARB 0x200E +#define WGL_SUPPORT_GDI_ARB 0x200F +#define WGL_SUPPORT_OPENGL_ARB 0x2010 +#define WGL_DOUBLE_BUFFER_ARB 0x2011 +#define WGL_STEREO_ARB 0x2012 +#define WGL_PIXEL_TYPE_ARB 0x2013 +#define WGL_COLOR_BITS_ARB 0x2014 +#define WGL_RED_BITS_ARB 0x2015 +#define WGL_RED_SHIFT_ARB 0x2016 +#define WGL_GREEN_BITS_ARB 0x2017 +#define WGL_GREEN_SHIFT_ARB 0x2018 +#define WGL_BLUE_BITS_ARB 0x2019 +#define WGL_BLUE_SHIFT_ARB 0x201A +#define WGL_ALPHA_BITS_ARB 0x201B +#define WGL_ALPHA_SHIFT_ARB 0x201C +#define WGL_ACCUM_BITS_ARB 0x201D +#define WGL_ACCUM_RED_BITS_ARB 0x201E +#define WGL_ACCUM_GREEN_BITS_ARB 0x201F +#define WGL_ACCUM_BLUE_BITS_ARB 0x2020 +#define WGL_ACCUM_ALPHA_BITS_ARB 0x2021 +#define WGL_DEPTH_BITS_ARB 0x2022 +#define WGL_STENCIL_BITS_ARB 0x2023 +#define WGL_AUX_BUFFERS_ARB 0x2024 +#define WGL_NO_ACCELERATION_ARB 0x2025 +#define WGL_GENERIC_ACCELERATION_ARB 0x2026 +#define WGL_FULL_ACCELERATION_ARB 0x2027 +#define WGL_SWAP_EXCHANGE_ARB 0x2028 +#define WGL_SWAP_COPY_ARB 0x2029 +#define WGL_SWAP_UNDEFINED_ARB 0x202A +#define WGL_TYPE_RGBA_ARB 0x202B +#define WGL_TYPE_COLORINDEX_ARB 0x202C +#define WGL_TRANSPARENT_RED_VALUE_ARB 0x2037 +#define WGL_TRANSPARENT_GREEN_VALUE_ARB 0x2038 +#define WGL_TRANSPARENT_BLUE_VALUE_ARB 0x2039 +#define WGL_TRANSPARENT_ALPHA_VALUE_ARB 0x203A +#define WGL_TRANSPARENT_INDEX_VALUE_ARB 0x203B + +typedef BOOL (WINAPI * PFNWGLCHOOSEPIXELFORMATARBPROC) (HDC hdc, const int* piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats); +typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBFVARBPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int* piAttributes, FLOAT *pfValues); +typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBIVARBPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int* piAttributes, int *piValues); + +#define wglChoosePixelFormatARB WGLEW_GET_FUN(__wglewChoosePixelFormatARB) +#define wglGetPixelFormatAttribfvARB WGLEW_GET_FUN(__wglewGetPixelFormatAttribfvARB) +#define wglGetPixelFormatAttribivARB WGLEW_GET_FUN(__wglewGetPixelFormatAttribivARB) + +#define WGLEW_ARB_pixel_format WGLEW_GET_VAR(__WGLEW_ARB_pixel_format) + +#endif /* WGL_ARB_pixel_format */ + +/* ----------------------- WGL_ARB_pixel_format_float ---------------------- */ + +#ifndef WGL_ARB_pixel_format_float +#define WGL_ARB_pixel_format_float 1 + +#define WGL_TYPE_RGBA_FLOAT_ARB 0x21A0 + +#define WGLEW_ARB_pixel_format_float WGLEW_GET_VAR(__WGLEW_ARB_pixel_format_float) + +#endif /* WGL_ARB_pixel_format_float */ + +/* ------------------------- WGL_ARB_render_texture ------------------------ */ + +#ifndef WGL_ARB_render_texture +#define WGL_ARB_render_texture 1 + +#define WGL_BIND_TO_TEXTURE_RGB_ARB 0x2070 +#define WGL_BIND_TO_TEXTURE_RGBA_ARB 0x2071 +#define WGL_TEXTURE_FORMAT_ARB 0x2072 +#define WGL_TEXTURE_TARGET_ARB 0x2073 +#define WGL_MIPMAP_TEXTURE_ARB 0x2074 +#define WGL_TEXTURE_RGB_ARB 0x2075 +#define WGL_TEXTURE_RGBA_ARB 0x2076 +#define WGL_NO_TEXTURE_ARB 0x2077 +#define WGL_TEXTURE_CUBE_MAP_ARB 0x2078 +#define WGL_TEXTURE_1D_ARB 0x2079 +#define WGL_TEXTURE_2D_ARB 0x207A +#define WGL_MIPMAP_LEVEL_ARB 0x207B +#define WGL_CUBE_MAP_FACE_ARB 0x207C +#define WGL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB 0x207D +#define WGL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB 0x207E +#define WGL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB 0x207F +#define WGL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB 0x2080 +#define WGL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB 0x2081 +#define WGL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB 0x2082 +#define WGL_FRONT_LEFT_ARB 0x2083 +#define WGL_FRONT_RIGHT_ARB 0x2084 +#define WGL_BACK_LEFT_ARB 0x2085 +#define WGL_BACK_RIGHT_ARB 0x2086 +#define WGL_AUX0_ARB 0x2087 +#define WGL_AUX1_ARB 0x2088 +#define WGL_AUX2_ARB 0x2089 +#define WGL_AUX3_ARB 0x208A +#define WGL_AUX4_ARB 0x208B +#define WGL_AUX5_ARB 0x208C +#define WGL_AUX6_ARB 0x208D +#define WGL_AUX7_ARB 0x208E +#define WGL_AUX8_ARB 0x208F +#define WGL_AUX9_ARB 0x2090 + +typedef BOOL (WINAPI * PFNWGLBINDTEXIMAGEARBPROC) (HPBUFFERARB hPbuffer, int iBuffer); +typedef BOOL (WINAPI * PFNWGLRELEASETEXIMAGEARBPROC) (HPBUFFERARB hPbuffer, int iBuffer); +typedef BOOL (WINAPI * PFNWGLSETPBUFFERATTRIBARBPROC) (HPBUFFERARB hPbuffer, const int* piAttribList); + +#define wglBindTexImageARB WGLEW_GET_FUN(__wglewBindTexImageARB) +#define wglReleaseTexImageARB WGLEW_GET_FUN(__wglewReleaseTexImageARB) +#define wglSetPbufferAttribARB WGLEW_GET_FUN(__wglewSetPbufferAttribARB) + +#define WGLEW_ARB_render_texture WGLEW_GET_VAR(__WGLEW_ARB_render_texture) + +#endif /* WGL_ARB_render_texture */ + +/* ----------------------- WGL_ATI_pixel_format_float ---------------------- */ + +#ifndef WGL_ATI_pixel_format_float +#define WGL_ATI_pixel_format_float 1 + +#define WGL_TYPE_RGBA_FLOAT_ATI 0x21A0 +#define GL_RGBA_FLOAT_MODE_ATI 0x8820 +#define GL_COLOR_CLEAR_UNCLAMPED_VALUE_ATI 0x8835 + +#define WGLEW_ATI_pixel_format_float WGLEW_GET_VAR(__WGLEW_ATI_pixel_format_float) + +#endif /* WGL_ATI_pixel_format_float */ + +/* -------------------- WGL_ATI_render_texture_rectangle ------------------- */ + +#ifndef WGL_ATI_render_texture_rectangle +#define WGL_ATI_render_texture_rectangle 1 + +#define WGL_TEXTURE_RECTANGLE_ATI 0x21A5 + +#define WGLEW_ATI_render_texture_rectangle WGLEW_GET_VAR(__WGLEW_ATI_render_texture_rectangle) + +#endif /* WGL_ATI_render_texture_rectangle */ + +/* -------------------------- WGL_EXT_depth_float -------------------------- */ + +#ifndef WGL_EXT_depth_float +#define WGL_EXT_depth_float 1 + +#define WGL_DEPTH_FLOAT_EXT 0x2040 + +#define WGLEW_EXT_depth_float WGLEW_GET_VAR(__WGLEW_EXT_depth_float) + +#endif /* WGL_EXT_depth_float */ + +/* ---------------------- WGL_EXT_display_color_table ---------------------- */ + +#ifndef WGL_EXT_display_color_table +#define WGL_EXT_display_color_table 1 + +typedef GLboolean (WINAPI * PFNWGLBINDDISPLAYCOLORTABLEEXTPROC) (GLushort id); +typedef GLboolean (WINAPI * PFNWGLCREATEDISPLAYCOLORTABLEEXTPROC) (GLushort id); +typedef void (WINAPI * PFNWGLDESTROYDISPLAYCOLORTABLEEXTPROC) (GLushort id); +typedef GLboolean (WINAPI * PFNWGLLOADDISPLAYCOLORTABLEEXTPROC) (GLushort* table, GLuint length); + +#define wglBindDisplayColorTableEXT WGLEW_GET_FUN(__wglewBindDisplayColorTableEXT) +#define wglCreateDisplayColorTableEXT WGLEW_GET_FUN(__wglewCreateDisplayColorTableEXT) +#define wglDestroyDisplayColorTableEXT WGLEW_GET_FUN(__wglewDestroyDisplayColorTableEXT) +#define wglLoadDisplayColorTableEXT WGLEW_GET_FUN(__wglewLoadDisplayColorTableEXT) + +#define WGLEW_EXT_display_color_table WGLEW_GET_VAR(__WGLEW_EXT_display_color_table) + +#endif /* WGL_EXT_display_color_table */ + +/* ----------------------- WGL_EXT_extensions_string ----------------------- */ + +#ifndef WGL_EXT_extensions_string +#define WGL_EXT_extensions_string 1 + +typedef const char* (WINAPI * PFNWGLGETEXTENSIONSSTRINGEXTPROC) (void); + +#define wglGetExtensionsStringEXT WGLEW_GET_FUN(__wglewGetExtensionsStringEXT) + +#define WGLEW_EXT_extensions_string WGLEW_GET_VAR(__WGLEW_EXT_extensions_string) + +#endif /* WGL_EXT_extensions_string */ + +/* ----------------------- WGL_EXT_make_current_read ----------------------- */ + +#ifndef WGL_EXT_make_current_read +#define WGL_EXT_make_current_read 1 + +typedef HDC (WINAPI * PFNWGLGETCURRENTREADDCEXTPROC) (VOID); +typedef BOOL (WINAPI * PFNWGLMAKECONTEXTCURRENTEXTPROC) (HDC hDrawDC, HDC hReadDC, HGLRC hglrc); + +#define wglGetCurrentReadDCEXT WGLEW_GET_FUN(__wglewGetCurrentReadDCEXT) +#define wglMakeContextCurrentEXT WGLEW_GET_FUN(__wglewMakeContextCurrentEXT) + +#define WGLEW_EXT_make_current_read WGLEW_GET_VAR(__WGLEW_EXT_make_current_read) + +#endif /* WGL_EXT_make_current_read */ + +/* -------------------------- WGL_EXT_multisample -------------------------- */ + +#ifndef WGL_EXT_multisample +#define WGL_EXT_multisample 1 + +#define WGL_SAMPLE_BUFFERS_EXT 0x2041 +#define WGL_SAMPLES_EXT 0x2042 + +#define WGLEW_EXT_multisample WGLEW_GET_VAR(__WGLEW_EXT_multisample) + +#endif /* WGL_EXT_multisample */ + +/* ---------------------------- WGL_EXT_pbuffer ---------------------------- */ + +#ifndef WGL_EXT_pbuffer +#define WGL_EXT_pbuffer 1 + +#define WGL_DRAW_TO_PBUFFER_EXT 0x202D +#define WGL_MAX_PBUFFER_PIXELS_EXT 0x202E +#define WGL_MAX_PBUFFER_WIDTH_EXT 0x202F +#define WGL_MAX_PBUFFER_HEIGHT_EXT 0x2030 +#define WGL_OPTIMAL_PBUFFER_WIDTH_EXT 0x2031 +#define WGL_OPTIMAL_PBUFFER_HEIGHT_EXT 0x2032 +#define WGL_PBUFFER_LARGEST_EXT 0x2033 +#define WGL_PBUFFER_WIDTH_EXT 0x2034 +#define WGL_PBUFFER_HEIGHT_EXT 0x2035 + +DECLARE_HANDLE(HPBUFFEREXT); + +typedef HPBUFFEREXT (WINAPI * PFNWGLCREATEPBUFFEREXTPROC) (HDC hDC, int iPixelFormat, int iWidth, int iHeight, const int* piAttribList); +typedef BOOL (WINAPI * PFNWGLDESTROYPBUFFEREXTPROC) (HPBUFFEREXT hPbuffer); +typedef HDC (WINAPI * PFNWGLGETPBUFFERDCEXTPROC) (HPBUFFEREXT hPbuffer); +typedef BOOL (WINAPI * PFNWGLQUERYPBUFFEREXTPROC) (HPBUFFEREXT hPbuffer, int iAttribute, int* piValue); +typedef int (WINAPI * PFNWGLRELEASEPBUFFERDCEXTPROC) (HPBUFFEREXT hPbuffer, HDC hDC); + +#define wglCreatePbufferEXT WGLEW_GET_FUN(__wglewCreatePbufferEXT) +#define wglDestroyPbufferEXT WGLEW_GET_FUN(__wglewDestroyPbufferEXT) +#define wglGetPbufferDCEXT WGLEW_GET_FUN(__wglewGetPbufferDCEXT) +#define wglQueryPbufferEXT WGLEW_GET_FUN(__wglewQueryPbufferEXT) +#define wglReleasePbufferDCEXT WGLEW_GET_FUN(__wglewReleasePbufferDCEXT) + +#define WGLEW_EXT_pbuffer WGLEW_GET_VAR(__WGLEW_EXT_pbuffer) + +#endif /* WGL_EXT_pbuffer */ + +/* -------------------------- WGL_EXT_pixel_format ------------------------- */ + +#ifndef WGL_EXT_pixel_format +#define WGL_EXT_pixel_format 1 + +#define WGL_NUMBER_PIXEL_FORMATS_EXT 0x2000 +#define WGL_DRAW_TO_WINDOW_EXT 0x2001 +#define WGL_DRAW_TO_BITMAP_EXT 0x2002 +#define WGL_ACCELERATION_EXT 0x2003 +#define WGL_NEED_PALETTE_EXT 0x2004 +#define WGL_NEED_SYSTEM_PALETTE_EXT 0x2005 +#define WGL_SWAP_LAYER_BUFFERS_EXT 0x2006 +#define WGL_SWAP_METHOD_EXT 0x2007 +#define WGL_NUMBER_OVERLAYS_EXT 0x2008 +#define WGL_NUMBER_UNDERLAYS_EXT 0x2009 +#define WGL_TRANSPARENT_EXT 0x200A +#define WGL_TRANSPARENT_VALUE_EXT 0x200B +#define WGL_SHARE_DEPTH_EXT 0x200C +#define WGL_SHARE_STENCIL_EXT 0x200D +#define WGL_SHARE_ACCUM_EXT 0x200E +#define WGL_SUPPORT_GDI_EXT 0x200F +#define WGL_SUPPORT_OPENGL_EXT 0x2010 +#define WGL_DOUBLE_BUFFER_EXT 0x2011 +#define WGL_STEREO_EXT 0x2012 +#define WGL_PIXEL_TYPE_EXT 0x2013 +#define WGL_COLOR_BITS_EXT 0x2014 +#define WGL_RED_BITS_EXT 0x2015 +#define WGL_RED_SHIFT_EXT 0x2016 +#define WGL_GREEN_BITS_EXT 0x2017 +#define WGL_GREEN_SHIFT_EXT 0x2018 +#define WGL_BLUE_BITS_EXT 0x2019 +#define WGL_BLUE_SHIFT_EXT 0x201A +#define WGL_ALPHA_BITS_EXT 0x201B +#define WGL_ALPHA_SHIFT_EXT 0x201C +#define WGL_ACCUM_BITS_EXT 0x201D +#define WGL_ACCUM_RED_BITS_EXT 0x201E +#define WGL_ACCUM_GREEN_BITS_EXT 0x201F +#define WGL_ACCUM_BLUE_BITS_EXT 0x2020 +#define WGL_ACCUM_ALPHA_BITS_EXT 0x2021 +#define WGL_DEPTH_BITS_EXT 0x2022 +#define WGL_STENCIL_BITS_EXT 0x2023 +#define WGL_AUX_BUFFERS_EXT 0x2024 +#define WGL_NO_ACCELERATION_EXT 0x2025 +#define WGL_GENERIC_ACCELERATION_EXT 0x2026 +#define WGL_FULL_ACCELERATION_EXT 0x2027 +#define WGL_SWAP_EXCHANGE_EXT 0x2028 +#define WGL_SWAP_COPY_EXT 0x2029 +#define WGL_SWAP_UNDEFINED_EXT 0x202A +#define WGL_TYPE_RGBA_EXT 0x202B +#define WGL_TYPE_COLORINDEX_EXT 0x202C + +typedef BOOL (WINAPI * PFNWGLCHOOSEPIXELFORMATEXTPROC) (HDC hdc, const int* piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats); +typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBFVEXTPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, int* piAttributes, FLOAT *pfValues); +typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBIVEXTPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, int* piAttributes, int *piValues); + +#define wglChoosePixelFormatEXT WGLEW_GET_FUN(__wglewChoosePixelFormatEXT) +#define wglGetPixelFormatAttribfvEXT WGLEW_GET_FUN(__wglewGetPixelFormatAttribfvEXT) +#define wglGetPixelFormatAttribivEXT WGLEW_GET_FUN(__wglewGetPixelFormatAttribivEXT) + +#define WGLEW_EXT_pixel_format WGLEW_GET_VAR(__WGLEW_EXT_pixel_format) + +#endif /* WGL_EXT_pixel_format */ + +/* -------------------------- WGL_EXT_swap_control ------------------------- */ + +#ifndef WGL_EXT_swap_control +#define WGL_EXT_swap_control 1 + +typedef int (WINAPI * PFNWGLGETSWAPINTERVALEXTPROC) (void); +typedef BOOL (WINAPI * PFNWGLSWAPINTERVALEXTPROC) (int interval); + +#define wglGetSwapIntervalEXT WGLEW_GET_FUN(__wglewGetSwapIntervalEXT) +#define wglSwapIntervalEXT WGLEW_GET_FUN(__wglewSwapIntervalEXT) + +#define WGLEW_EXT_swap_control WGLEW_GET_VAR(__WGLEW_EXT_swap_control) + +#endif /* WGL_EXT_swap_control */ + +/* --------------------- WGL_I3D_digital_video_control --------------------- */ + +#ifndef WGL_I3D_digital_video_control +#define WGL_I3D_digital_video_control 1 + +#define WGL_DIGITAL_VIDEO_CURSOR_ALPHA_FRAMEBUFFER_I3D 0x2050 +#define WGL_DIGITAL_VIDEO_CURSOR_ALPHA_VALUE_I3D 0x2051 +#define WGL_DIGITAL_VIDEO_CURSOR_INCLUDED_I3D 0x2052 +#define WGL_DIGITAL_VIDEO_GAMMA_CORRECTED_I3D 0x2053 + +typedef BOOL (WINAPI * PFNWGLGETDIGITALVIDEOPARAMETERSI3DPROC) (HDC hDC, int iAttribute, int* piValue); +typedef BOOL (WINAPI * PFNWGLSETDIGITALVIDEOPARAMETERSI3DPROC) (HDC hDC, int iAttribute, const int* piValue); + +#define wglGetDigitalVideoParametersI3D WGLEW_GET_FUN(__wglewGetDigitalVideoParametersI3D) +#define wglSetDigitalVideoParametersI3D WGLEW_GET_FUN(__wglewSetDigitalVideoParametersI3D) + +#define WGLEW_I3D_digital_video_control WGLEW_GET_VAR(__WGLEW_I3D_digital_video_control) + +#endif /* WGL_I3D_digital_video_control */ + +/* ----------------------------- WGL_I3D_gamma ----------------------------- */ + +#ifndef WGL_I3D_gamma +#define WGL_I3D_gamma 1 + +#define WGL_GAMMA_TABLE_SIZE_I3D 0x204E +#define WGL_GAMMA_EXCLUDE_DESKTOP_I3D 0x204F + +typedef BOOL (WINAPI * PFNWGLGETGAMMATABLEI3DPROC) (HDC hDC, int iEntries, USHORT* puRed, USHORT *puGreen, USHORT *puBlue); +typedef BOOL (WINAPI * PFNWGLGETGAMMATABLEPARAMETERSI3DPROC) (HDC hDC, int iAttribute, int* piValue); +typedef BOOL (WINAPI * PFNWGLSETGAMMATABLEI3DPROC) (HDC hDC, int iEntries, const USHORT* puRed, const USHORT *puGreen, const USHORT *puBlue); +typedef BOOL (WINAPI * PFNWGLSETGAMMATABLEPARAMETERSI3DPROC) (HDC hDC, int iAttribute, const int* piValue); + +#define wglGetGammaTableI3D WGLEW_GET_FUN(__wglewGetGammaTableI3D) +#define wglGetGammaTableParametersI3D WGLEW_GET_FUN(__wglewGetGammaTableParametersI3D) +#define wglSetGammaTableI3D WGLEW_GET_FUN(__wglewSetGammaTableI3D) +#define wglSetGammaTableParametersI3D WGLEW_GET_FUN(__wglewSetGammaTableParametersI3D) + +#define WGLEW_I3D_gamma WGLEW_GET_VAR(__WGLEW_I3D_gamma) + +#endif /* WGL_I3D_gamma */ + +/* ---------------------------- WGL_I3D_genlock ---------------------------- */ + +#ifndef WGL_I3D_genlock +#define WGL_I3D_genlock 1 + +#define WGL_GENLOCK_SOURCE_MULTIVIEW_I3D 0x2044 +#define WGL_GENLOCK_SOURCE_EXTERNAL_SYNC_I3D 0x2045 +#define WGL_GENLOCK_SOURCE_EXTERNAL_FIELD_I3D 0x2046 +#define WGL_GENLOCK_SOURCE_EXTERNAL_TTL_I3D 0x2047 +#define WGL_GENLOCK_SOURCE_DIGITAL_SYNC_I3D 0x2048 +#define WGL_GENLOCK_SOURCE_DIGITAL_FIELD_I3D 0x2049 +#define WGL_GENLOCK_SOURCE_EDGE_FALLING_I3D 0x204A +#define WGL_GENLOCK_SOURCE_EDGE_RISING_I3D 0x204B +#define WGL_GENLOCK_SOURCE_EDGE_BOTH_I3D 0x204C + +typedef BOOL (WINAPI * PFNWGLDISABLEGENLOCKI3DPROC) (HDC hDC); +typedef BOOL (WINAPI * PFNWGLENABLEGENLOCKI3DPROC) (HDC hDC); +typedef BOOL (WINAPI * PFNWGLGENLOCKSAMPLERATEI3DPROC) (HDC hDC, UINT uRate); +typedef BOOL (WINAPI * PFNWGLGENLOCKSOURCEDELAYI3DPROC) (HDC hDC, UINT uDelay); +typedef BOOL (WINAPI * PFNWGLGENLOCKSOURCEEDGEI3DPROC) (HDC hDC, UINT uEdge); +typedef BOOL (WINAPI * PFNWGLGENLOCKSOURCEI3DPROC) (HDC hDC, UINT uSource); +typedef BOOL (WINAPI * PFNWGLGETGENLOCKSAMPLERATEI3DPROC) (HDC hDC, UINT* uRate); +typedef BOOL (WINAPI * PFNWGLGETGENLOCKSOURCEDELAYI3DPROC) (HDC hDC, UINT* uDelay); +typedef BOOL (WINAPI * PFNWGLGETGENLOCKSOURCEEDGEI3DPROC) (HDC hDC, UINT* uEdge); +typedef BOOL (WINAPI * PFNWGLGETGENLOCKSOURCEI3DPROC) (HDC hDC, UINT* uSource); +typedef BOOL (WINAPI * PFNWGLISENABLEDGENLOCKI3DPROC) (HDC hDC, BOOL* pFlag); +typedef BOOL (WINAPI * PFNWGLQUERYGENLOCKMAXSOURCEDELAYI3DPROC) (HDC hDC, UINT* uMaxLineDelay, UINT *uMaxPixelDelay); + +#define wglDisableGenlockI3D WGLEW_GET_FUN(__wglewDisableGenlockI3D) +#define wglEnableGenlockI3D WGLEW_GET_FUN(__wglewEnableGenlockI3D) +#define wglGenlockSampleRateI3D WGLEW_GET_FUN(__wglewGenlockSampleRateI3D) +#define wglGenlockSourceDelayI3D WGLEW_GET_FUN(__wglewGenlockSourceDelayI3D) +#define wglGenlockSourceEdgeI3D WGLEW_GET_FUN(__wglewGenlockSourceEdgeI3D) +#define wglGenlockSourceI3D WGLEW_GET_FUN(__wglewGenlockSourceI3D) +#define wglGetGenlockSampleRateI3D WGLEW_GET_FUN(__wglewGetGenlockSampleRateI3D) +#define wglGetGenlockSourceDelayI3D WGLEW_GET_FUN(__wglewGetGenlockSourceDelayI3D) +#define wglGetGenlockSourceEdgeI3D WGLEW_GET_FUN(__wglewGetGenlockSourceEdgeI3D) +#define wglGetGenlockSourceI3D WGLEW_GET_FUN(__wglewGetGenlockSourceI3D) +#define wglIsEnabledGenlockI3D WGLEW_GET_FUN(__wglewIsEnabledGenlockI3D) +#define wglQueryGenlockMaxSourceDelayI3D WGLEW_GET_FUN(__wglewQueryGenlockMaxSourceDelayI3D) + +#define WGLEW_I3D_genlock WGLEW_GET_VAR(__WGLEW_I3D_genlock) + +#endif /* WGL_I3D_genlock */ + +/* -------------------------- WGL_I3D_image_buffer ------------------------- */ + +#ifndef WGL_I3D_image_buffer +#define WGL_I3D_image_buffer 1 + +#define WGL_IMAGE_BUFFER_MIN_ACCESS_I3D 0x00000001 +#define WGL_IMAGE_BUFFER_LOCK_I3D 0x00000002 + +typedef BOOL (WINAPI * PFNWGLASSOCIATEIMAGEBUFFEREVENTSI3DPROC) (HDC hdc, HANDLE* pEvent, LPVOID *pAddress, DWORD *pSize, UINT count); +typedef LPVOID (WINAPI * PFNWGLCREATEIMAGEBUFFERI3DPROC) (HDC hDC, DWORD dwSize, UINT uFlags); +typedef BOOL (WINAPI * PFNWGLDESTROYIMAGEBUFFERI3DPROC) (HDC hDC, LPVOID pAddress); +typedef BOOL (WINAPI * PFNWGLRELEASEIMAGEBUFFEREVENTSI3DPROC) (HDC hdc, LPVOID* pAddress, UINT count); + +#define wglAssociateImageBufferEventsI3D WGLEW_GET_FUN(__wglewAssociateImageBufferEventsI3D) +#define wglCreateImageBufferI3D WGLEW_GET_FUN(__wglewCreateImageBufferI3D) +#define wglDestroyImageBufferI3D WGLEW_GET_FUN(__wglewDestroyImageBufferI3D) +#define wglReleaseImageBufferEventsI3D WGLEW_GET_FUN(__wglewReleaseImageBufferEventsI3D) + +#define WGLEW_I3D_image_buffer WGLEW_GET_VAR(__WGLEW_I3D_image_buffer) + +#endif /* WGL_I3D_image_buffer */ + +/* ------------------------ WGL_I3D_swap_frame_lock ------------------------ */ + +#ifndef WGL_I3D_swap_frame_lock +#define WGL_I3D_swap_frame_lock 1 + +typedef BOOL (WINAPI * PFNWGLDISABLEFRAMELOCKI3DPROC) (VOID); +typedef BOOL (WINAPI * PFNWGLENABLEFRAMELOCKI3DPROC) (VOID); +typedef BOOL (WINAPI * PFNWGLISENABLEDFRAMELOCKI3DPROC) (BOOL* pFlag); +typedef BOOL (WINAPI * PFNWGLQUERYFRAMELOCKMASTERI3DPROC) (BOOL* pFlag); + +#define wglDisableFrameLockI3D WGLEW_GET_FUN(__wglewDisableFrameLockI3D) +#define wglEnableFrameLockI3D WGLEW_GET_FUN(__wglewEnableFrameLockI3D) +#define wglIsEnabledFrameLockI3D WGLEW_GET_FUN(__wglewIsEnabledFrameLockI3D) +#define wglQueryFrameLockMasterI3D WGLEW_GET_FUN(__wglewQueryFrameLockMasterI3D) + +#define WGLEW_I3D_swap_frame_lock WGLEW_GET_VAR(__WGLEW_I3D_swap_frame_lock) + +#endif /* WGL_I3D_swap_frame_lock */ + +/* ------------------------ WGL_I3D_swap_frame_usage ----------------------- */ + +#ifndef WGL_I3D_swap_frame_usage +#define WGL_I3D_swap_frame_usage 1 + +typedef BOOL (WINAPI * PFNWGLBEGINFRAMETRACKINGI3DPROC) (void); +typedef BOOL (WINAPI * PFNWGLENDFRAMETRACKINGI3DPROC) (void); +typedef BOOL (WINAPI * PFNWGLGETFRAMEUSAGEI3DPROC) (float* pUsage); +typedef BOOL (WINAPI * PFNWGLQUERYFRAMETRACKINGI3DPROC) (DWORD* pFrameCount, DWORD *pMissedFrames, float *pLastMissedUsage); + +#define wglBeginFrameTrackingI3D WGLEW_GET_FUN(__wglewBeginFrameTrackingI3D) +#define wglEndFrameTrackingI3D WGLEW_GET_FUN(__wglewEndFrameTrackingI3D) +#define wglGetFrameUsageI3D WGLEW_GET_FUN(__wglewGetFrameUsageI3D) +#define wglQueryFrameTrackingI3D WGLEW_GET_FUN(__wglewQueryFrameTrackingI3D) + +#define WGLEW_I3D_swap_frame_usage WGLEW_GET_VAR(__WGLEW_I3D_swap_frame_usage) + +#endif /* WGL_I3D_swap_frame_usage */ + +/* -------------------------- WGL_NV_float_buffer -------------------------- */ + +#ifndef WGL_NV_float_buffer +#define WGL_NV_float_buffer 1 + +#define WGL_FLOAT_COMPONENTS_NV 0x20B0 +#define WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_R_NV 0x20B1 +#define WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RG_NV 0x20B2 +#define WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RGB_NV 0x20B3 +#define WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RGBA_NV 0x20B4 +#define WGL_TEXTURE_FLOAT_R_NV 0x20B5 +#define WGL_TEXTURE_FLOAT_RG_NV 0x20B6 +#define WGL_TEXTURE_FLOAT_RGB_NV 0x20B7 +#define WGL_TEXTURE_FLOAT_RGBA_NV 0x20B8 + +#define WGLEW_NV_float_buffer WGLEW_GET_VAR(__WGLEW_NV_float_buffer) + +#endif /* WGL_NV_float_buffer */ + +/* ---------------------- WGL_NV_render_depth_texture ---------------------- */ + +#ifndef WGL_NV_render_depth_texture +#define WGL_NV_render_depth_texture 1 + +#define WGL_NO_TEXTURE_ARB 0x2077 +#define WGL_BIND_TO_TEXTURE_DEPTH_NV 0x20A3 +#define WGL_BIND_TO_TEXTURE_RECTANGLE_DEPTH_NV 0x20A4 +#define WGL_DEPTH_TEXTURE_FORMAT_NV 0x20A5 +#define WGL_TEXTURE_DEPTH_COMPONENT_NV 0x20A6 +#define WGL_DEPTH_COMPONENT_NV 0x20A7 + +#define WGLEW_NV_render_depth_texture WGLEW_GET_VAR(__WGLEW_NV_render_depth_texture) + +#endif /* WGL_NV_render_depth_texture */ + +/* -------------------- WGL_NV_render_texture_rectangle -------------------- */ + +#ifndef WGL_NV_render_texture_rectangle +#define WGL_NV_render_texture_rectangle 1 + +#define WGL_BIND_TO_TEXTURE_RECTANGLE_RGB_NV 0x20A0 +#define WGL_BIND_TO_TEXTURE_RECTANGLE_RGBA_NV 0x20A1 +#define WGL_TEXTURE_RECTANGLE_NV 0x20A2 + +#define WGLEW_NV_render_texture_rectangle WGLEW_GET_VAR(__WGLEW_NV_render_texture_rectangle) + +#endif /* WGL_NV_render_texture_rectangle */ + +/* ----------------------- WGL_NV_vertex_array_range ----------------------- */ + +#ifndef WGL_NV_vertex_array_range +#define WGL_NV_vertex_array_range 1 + +typedef void * (WINAPI * PFNWGLALLOCATEMEMORYNVPROC) (GLsizei size, GLfloat readFrequency, GLfloat writeFrequency, GLfloat priority); +typedef void (WINAPI * PFNWGLFREEMEMORYNVPROC) (void *pointer); + +#define wglAllocateMemoryNV WGLEW_GET_FUN(__wglewAllocateMemoryNV) +#define wglFreeMemoryNV WGLEW_GET_FUN(__wglewFreeMemoryNV) + +#define WGLEW_NV_vertex_array_range WGLEW_GET_VAR(__WGLEW_NV_vertex_array_range) + +#endif /* WGL_NV_vertex_array_range */ + +/* -------------------------- WGL_OML_sync_control ------------------------- */ + +#ifndef WGL_OML_sync_control +#define WGL_OML_sync_control 1 + +typedef BOOL (WINAPI * PFNWGLGETMSCRATEOMLPROC) (HDC hdc, INT32* numerator, INT32 *denominator); +typedef BOOL (WINAPI * PFNWGLGETSYNCVALUESOMLPROC) (HDC hdc, INT64* ust, INT64 *msc, INT64 *sbc); +typedef INT64 (WINAPI * PFNWGLSWAPBUFFERSMSCOMLPROC) (HDC hdc, INT64 target_msc, INT64 divisor, INT64 remainder); +typedef INT64 (WINAPI * PFNWGLSWAPLAYERBUFFERSMSCOMLPROC) (HDC hdc, INT fuPlanes, INT64 target_msc, INT64 divisor, INT64 remainder); +typedef BOOL (WINAPI * PFNWGLWAITFORMSCOMLPROC) (HDC hdc, INT64 target_msc, INT64 divisor, INT64 remainder, INT64* ust, INT64 *msc, INT64 *sbc); +typedef BOOL (WINAPI * PFNWGLWAITFORSBCOMLPROC) (HDC hdc, INT64 target_sbc, INT64* ust, INT64 *msc, INT64 *sbc); + +#define wglGetMscRateOML WGLEW_GET_FUN(__wglewGetMscRateOML) +#define wglGetSyncValuesOML WGLEW_GET_FUN(__wglewGetSyncValuesOML) +#define wglSwapBuffersMscOML WGLEW_GET_FUN(__wglewSwapBuffersMscOML) +#define wglSwapLayerBuffersMscOML WGLEW_GET_FUN(__wglewSwapLayerBuffersMscOML) +#define wglWaitForMscOML WGLEW_GET_FUN(__wglewWaitForMscOML) +#define wglWaitForSbcOML WGLEW_GET_FUN(__wglewWaitForSbcOML) + +#define WGLEW_OML_sync_control WGLEW_GET_VAR(__WGLEW_OML_sync_control) + +#endif /* WGL_OML_sync_control */ + +/* ------------------------------------------------------------------------- */ + +#ifdef GLEW_MX +#define WGLEW_EXPORT +#else +#define WGLEW_EXPORT GLEWAPI +#endif /* GLEW_MX */ + +#ifdef GLEW_MX +struct WGLEWContextStruct +{ +#endif /* GLEW_MX */ + +WGLEW_EXPORT PFNWGLSETSTEREOEMITTERSTATE3DLPROC __wglewSetStereoEmitterState3DL; + +WGLEW_EXPORT PFNWGLCREATEBUFFERREGIONARBPROC __wglewCreateBufferRegionARB; +WGLEW_EXPORT PFNWGLDELETEBUFFERREGIONARBPROC __wglewDeleteBufferRegionARB; +WGLEW_EXPORT PFNWGLRESTOREBUFFERREGIONARBPROC __wglewRestoreBufferRegionARB; +WGLEW_EXPORT PFNWGLSAVEBUFFERREGIONARBPROC __wglewSaveBufferRegionARB; + +WGLEW_EXPORT PFNWGLGETEXTENSIONSSTRINGARBPROC __wglewGetExtensionsStringARB; + +WGLEW_EXPORT PFNWGLGETCURRENTREADDCARBPROC __wglewGetCurrentReadDCARB; +WGLEW_EXPORT PFNWGLMAKECONTEXTCURRENTARBPROC __wglewMakeContextCurrentARB; + +WGLEW_EXPORT PFNWGLCREATEPBUFFERARBPROC __wglewCreatePbufferARB; +WGLEW_EXPORT PFNWGLDESTROYPBUFFERARBPROC __wglewDestroyPbufferARB; +WGLEW_EXPORT PFNWGLGETPBUFFERDCARBPROC __wglewGetPbufferDCARB; +WGLEW_EXPORT PFNWGLQUERYPBUFFERARBPROC __wglewQueryPbufferARB; +WGLEW_EXPORT PFNWGLRELEASEPBUFFERDCARBPROC __wglewReleasePbufferDCARB; + +WGLEW_EXPORT PFNWGLCHOOSEPIXELFORMATARBPROC __wglewChoosePixelFormatARB; +WGLEW_EXPORT PFNWGLGETPIXELFORMATATTRIBFVARBPROC __wglewGetPixelFormatAttribfvARB; +WGLEW_EXPORT PFNWGLGETPIXELFORMATATTRIBIVARBPROC __wglewGetPixelFormatAttribivARB; + +WGLEW_EXPORT PFNWGLBINDTEXIMAGEARBPROC __wglewBindTexImageARB; +WGLEW_EXPORT PFNWGLRELEASETEXIMAGEARBPROC __wglewReleaseTexImageARB; +WGLEW_EXPORT PFNWGLSETPBUFFERATTRIBARBPROC __wglewSetPbufferAttribARB; + +WGLEW_EXPORT PFNWGLBINDDISPLAYCOLORTABLEEXTPROC __wglewBindDisplayColorTableEXT; +WGLEW_EXPORT PFNWGLCREATEDISPLAYCOLORTABLEEXTPROC __wglewCreateDisplayColorTableEXT; +WGLEW_EXPORT PFNWGLDESTROYDISPLAYCOLORTABLEEXTPROC __wglewDestroyDisplayColorTableEXT; +WGLEW_EXPORT PFNWGLLOADDISPLAYCOLORTABLEEXTPROC __wglewLoadDisplayColorTableEXT; + +WGLEW_EXPORT PFNWGLGETEXTENSIONSSTRINGEXTPROC __wglewGetExtensionsStringEXT; + +WGLEW_EXPORT PFNWGLGETCURRENTREADDCEXTPROC __wglewGetCurrentReadDCEXT; +WGLEW_EXPORT PFNWGLMAKECONTEXTCURRENTEXTPROC __wglewMakeContextCurrentEXT; + +WGLEW_EXPORT PFNWGLCREATEPBUFFEREXTPROC __wglewCreatePbufferEXT; +WGLEW_EXPORT PFNWGLDESTROYPBUFFEREXTPROC __wglewDestroyPbufferEXT; +WGLEW_EXPORT PFNWGLGETPBUFFERDCEXTPROC __wglewGetPbufferDCEXT; +WGLEW_EXPORT PFNWGLQUERYPBUFFEREXTPROC __wglewQueryPbufferEXT; +WGLEW_EXPORT PFNWGLRELEASEPBUFFERDCEXTPROC __wglewReleasePbufferDCEXT; + +WGLEW_EXPORT PFNWGLCHOOSEPIXELFORMATEXTPROC __wglewChoosePixelFormatEXT; +WGLEW_EXPORT PFNWGLGETPIXELFORMATATTRIBFVEXTPROC __wglewGetPixelFormatAttribfvEXT; +WGLEW_EXPORT PFNWGLGETPIXELFORMATATTRIBIVEXTPROC __wglewGetPixelFormatAttribivEXT; + +WGLEW_EXPORT PFNWGLGETSWAPINTERVALEXTPROC __wglewGetSwapIntervalEXT; +WGLEW_EXPORT PFNWGLSWAPINTERVALEXTPROC __wglewSwapIntervalEXT; + +WGLEW_EXPORT PFNWGLGETDIGITALVIDEOPARAMETERSI3DPROC __wglewGetDigitalVideoParametersI3D; +WGLEW_EXPORT PFNWGLSETDIGITALVIDEOPARAMETERSI3DPROC __wglewSetDigitalVideoParametersI3D; + +WGLEW_EXPORT PFNWGLGETGAMMATABLEI3DPROC __wglewGetGammaTableI3D; +WGLEW_EXPORT PFNWGLGETGAMMATABLEPARAMETERSI3DPROC __wglewGetGammaTableParametersI3D; +WGLEW_EXPORT PFNWGLSETGAMMATABLEI3DPROC __wglewSetGammaTableI3D; +WGLEW_EXPORT PFNWGLSETGAMMATABLEPARAMETERSI3DPROC __wglewSetGammaTableParametersI3D; + +WGLEW_EXPORT PFNWGLDISABLEGENLOCKI3DPROC __wglewDisableGenlockI3D; +WGLEW_EXPORT PFNWGLENABLEGENLOCKI3DPROC __wglewEnableGenlockI3D; +WGLEW_EXPORT PFNWGLGENLOCKSAMPLERATEI3DPROC __wglewGenlockSampleRateI3D; +WGLEW_EXPORT PFNWGLGENLOCKSOURCEDELAYI3DPROC __wglewGenlockSourceDelayI3D; +WGLEW_EXPORT PFNWGLGENLOCKSOURCEEDGEI3DPROC __wglewGenlockSourceEdgeI3D; +WGLEW_EXPORT PFNWGLGENLOCKSOURCEI3DPROC __wglewGenlockSourceI3D; +WGLEW_EXPORT PFNWGLGETGENLOCKSAMPLERATEI3DPROC __wglewGetGenlockSampleRateI3D; +WGLEW_EXPORT PFNWGLGETGENLOCKSOURCEDELAYI3DPROC __wglewGetGenlockSourceDelayI3D; +WGLEW_EXPORT PFNWGLGETGENLOCKSOURCEEDGEI3DPROC __wglewGetGenlockSourceEdgeI3D; +WGLEW_EXPORT PFNWGLGETGENLOCKSOURCEI3DPROC __wglewGetGenlockSourceI3D; +WGLEW_EXPORT PFNWGLISENABLEDGENLOCKI3DPROC __wglewIsEnabledGenlockI3D; +WGLEW_EXPORT PFNWGLQUERYGENLOCKMAXSOURCEDELAYI3DPROC __wglewQueryGenlockMaxSourceDelayI3D; + +WGLEW_EXPORT PFNWGLASSOCIATEIMAGEBUFFEREVENTSI3DPROC __wglewAssociateImageBufferEventsI3D; +WGLEW_EXPORT PFNWGLCREATEIMAGEBUFFERI3DPROC __wglewCreateImageBufferI3D; +WGLEW_EXPORT PFNWGLDESTROYIMAGEBUFFERI3DPROC __wglewDestroyImageBufferI3D; +WGLEW_EXPORT PFNWGLRELEASEIMAGEBUFFEREVENTSI3DPROC __wglewReleaseImageBufferEventsI3D; + +WGLEW_EXPORT PFNWGLDISABLEFRAMELOCKI3DPROC __wglewDisableFrameLockI3D; +WGLEW_EXPORT PFNWGLENABLEFRAMELOCKI3DPROC __wglewEnableFrameLockI3D; +WGLEW_EXPORT PFNWGLISENABLEDFRAMELOCKI3DPROC __wglewIsEnabledFrameLockI3D; +WGLEW_EXPORT PFNWGLQUERYFRAMELOCKMASTERI3DPROC __wglewQueryFrameLockMasterI3D; + +WGLEW_EXPORT PFNWGLBEGINFRAMETRACKINGI3DPROC __wglewBeginFrameTrackingI3D; +WGLEW_EXPORT PFNWGLENDFRAMETRACKINGI3DPROC __wglewEndFrameTrackingI3D; +WGLEW_EXPORT PFNWGLGETFRAMEUSAGEI3DPROC __wglewGetFrameUsageI3D; +WGLEW_EXPORT PFNWGLQUERYFRAMETRACKINGI3DPROC __wglewQueryFrameTrackingI3D; + +WGLEW_EXPORT PFNWGLALLOCATEMEMORYNVPROC __wglewAllocateMemoryNV; +WGLEW_EXPORT PFNWGLFREEMEMORYNVPROC __wglewFreeMemoryNV; + +WGLEW_EXPORT PFNWGLGETMSCRATEOMLPROC __wglewGetMscRateOML; +WGLEW_EXPORT PFNWGLGETSYNCVALUESOMLPROC __wglewGetSyncValuesOML; +WGLEW_EXPORT PFNWGLSWAPBUFFERSMSCOMLPROC __wglewSwapBuffersMscOML; +WGLEW_EXPORT PFNWGLSWAPLAYERBUFFERSMSCOMLPROC __wglewSwapLayerBuffersMscOML; +WGLEW_EXPORT PFNWGLWAITFORMSCOMLPROC __wglewWaitForMscOML; +WGLEW_EXPORT PFNWGLWAITFORSBCOMLPROC __wglewWaitForSbcOML; +WGLEW_EXPORT GLboolean __WGLEW_3DFX_multisample; +WGLEW_EXPORT GLboolean __WGLEW_3DL_stereo_control; +WGLEW_EXPORT GLboolean __WGLEW_ARB_buffer_region; +WGLEW_EXPORT GLboolean __WGLEW_ARB_extensions_string; +WGLEW_EXPORT GLboolean __WGLEW_ARB_make_current_read; +WGLEW_EXPORT GLboolean __WGLEW_ARB_multisample; +WGLEW_EXPORT GLboolean __WGLEW_ARB_pbuffer; +WGLEW_EXPORT GLboolean __WGLEW_ARB_pixel_format; +WGLEW_EXPORT GLboolean __WGLEW_ARB_pixel_format_float; +WGLEW_EXPORT GLboolean __WGLEW_ARB_render_texture; +WGLEW_EXPORT GLboolean __WGLEW_ATI_pixel_format_float; +WGLEW_EXPORT GLboolean __WGLEW_ATI_render_texture_rectangle; +WGLEW_EXPORT GLboolean __WGLEW_EXT_depth_float; +WGLEW_EXPORT GLboolean __WGLEW_EXT_display_color_table; +WGLEW_EXPORT GLboolean __WGLEW_EXT_extensions_string; +WGLEW_EXPORT GLboolean __WGLEW_EXT_make_current_read; +WGLEW_EXPORT GLboolean __WGLEW_EXT_multisample; +WGLEW_EXPORT GLboolean __WGLEW_EXT_pbuffer; +WGLEW_EXPORT GLboolean __WGLEW_EXT_pixel_format; +WGLEW_EXPORT GLboolean __WGLEW_EXT_swap_control; +WGLEW_EXPORT GLboolean __WGLEW_I3D_digital_video_control; +WGLEW_EXPORT GLboolean __WGLEW_I3D_gamma; +WGLEW_EXPORT GLboolean __WGLEW_I3D_genlock; +WGLEW_EXPORT GLboolean __WGLEW_I3D_image_buffer; +WGLEW_EXPORT GLboolean __WGLEW_I3D_swap_frame_lock; +WGLEW_EXPORT GLboolean __WGLEW_I3D_swap_frame_usage; +WGLEW_EXPORT GLboolean __WGLEW_NV_float_buffer; +WGLEW_EXPORT GLboolean __WGLEW_NV_render_depth_texture; +WGLEW_EXPORT GLboolean __WGLEW_NV_render_texture_rectangle; +WGLEW_EXPORT GLboolean __WGLEW_NV_vertex_array_range; +WGLEW_EXPORT GLboolean __WGLEW_OML_sync_control; + +#ifdef GLEW_MX +}; /* WGLEWContextStruct */ +#endif /* GLEW_MX */ + +/* ------------------------------------------------------------------------- */ + +#ifdef GLEW_MX + +typedef struct WGLEWContextStruct WGLEWContext; +GLEWAPI GLenum wglewContextInit (WGLEWContext* ctx); +GLEWAPI GLboolean wglewContextIsSupported (WGLEWContext* ctx, const char* name); + +#define wglewInit() wglewContextInit(wglewGetContext()) +#define wglewIsSupported(x) wglewContextIsSupported(wglewGetContext(), x) + +#define WGLEW_GET_VAR(x) wglewGetContext()->x +#define WGLEW_GET_FUN(x) wglewGetContext()->x + +#else /* GLEW_MX */ + +#define WGLEW_GET_VAR(x) x +#define WGLEW_GET_FUN(x) x + +GLEWAPI GLboolean wglewIsSupported (const char* name); + +#endif /* GLEW_MX */ + +GLEWAPI GLboolean wglewGetExtension (const char* name); + +#ifdef __cplusplus +} +#endif + +#undef GLEWAPI + +#endif /* __wglew_h__ */ diff --git a/extern/glew/src/Makefile b/extern/glew/src/Makefile new file mode 100644 index 00000000000..55cc7cfccad --- /dev/null +++ b/extern/glew/src/Makefile @@ -0,0 +1,56 @@ +# +# $Id$ +# +# ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. The Blender +# Foundation also sells licenses for use in proprietary software under +# the Blender License. See http://www.blender.org/BL/ for information +# about this. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): none yet. +# +# ***** END GPL/BL DUAL LICENSE BLOCK ***** +# +# + +LIBNAME = glew +DIR = $(OCGDIR)/extern/$(LIBNAME) + +CCFLAGS += $(LEVEL_1_CPP_WARNINGS) + +CPPFLAGS += -I../include + +CSRCS = glew.c +CCSRCS = +include nan_compile.mk + +install: all debug + @[ -d $(NAN_GLEW) ] || mkdir -p $(NAN_GLEW) + @[ -d $(NAN_GLEW)/include/GL ] || mkdir -p $(NAN_GLEW)/include/GL + @[ -d $(NAN_GLEW)/lib ] || mkdir -p $(NAN_GLEW)/lib + @[ -d $(NAN_GLEW)/lib/debug ] || mkdir -p $(NAN_GLEW)/lib/debug + @$(NANBLENDERHOME)/intern/tools/cpifdiff.sh $(DIR)/lib$(LIBNAME).a $(NAN_GLEW)/lib/ +ifeq ($(OS),darwin) + ranlib $(NAN_GLEW)/lib/lib$(LIBNAME).a + ranlib $(NAN_GLEW)/lib/lib$(LIBNAME).a +endif + @$(NANBLENDERHOME)/intern/tools/cpifdiff.sh ../include/GL/*.h $(NAN_GLEW)/include/GL + diff --git a/extern/glew/src/glew.c b/extern/glew/src/glew.c new file mode 100644 index 00000000000..593f0e58f7c --- /dev/null +++ b/extern/glew/src/glew.c @@ -0,0 +1,9756 @@ +/* +** The OpenGL Extension Wrangler Library +** Copyright (C) 2002-2006, Milan Ikits +** Copyright (C) 2002-2006, Marcelo E. Magallon +** Copyright (C) 2002, Lev Povalahev +** 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. +** * The name of the author 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. +*/ + +#include +#if defined(_WIN32) +# include +#elif !defined(__APPLE__) || defined(GLEW_APPLE_GLX) +# include +#endif + +/* + * Define glewGetContext and related helper macros. + */ +#ifdef GLEW_MX +# define glewGetContext() ctx +# ifdef _WIN32 +# define GLEW_CONTEXT_ARG_DEF_INIT GLEWContext* ctx +# define GLEW_CONTEXT_ARG_VAR_INIT ctx +# define wglewGetContext() ctx +# define WGLEW_CONTEXT_ARG_DEF_INIT WGLEWContext* ctx +# define WGLEW_CONTEXT_ARG_DEF_LIST WGLEWContext* ctx +# else /* _WIN32 */ +# define GLEW_CONTEXT_ARG_DEF_INIT void +# define GLEW_CONTEXT_ARG_VAR_INIT +# define glxewGetContext() ctx +# define GLXEW_CONTEXT_ARG_DEF_INIT void +# define GLXEW_CONTEXT_ARG_DEF_LIST GLXEWContext* ctx +# endif /* _WIN32 */ +# define GLEW_CONTEXT_ARG_DEF_LIST GLEWContext* ctx +#else /* GLEW_MX */ +# define GLEW_CONTEXT_ARG_DEF_INIT void +# define GLEW_CONTEXT_ARG_VAR_INIT +# define GLEW_CONTEXT_ARG_DEF_LIST void +# define WGLEW_CONTEXT_ARG_DEF_INIT void +# define WGLEW_CONTEXT_ARG_DEF_LIST void +# define GLXEW_CONTEXT_ARG_DEF_INIT void +# define GLXEW_CONTEXT_ARG_DEF_LIST void +#endif /* GLEW_MX */ + +#if defined(__APPLE__) +#include +#include +#include + +void* NSGLGetProcAddress (const GLubyte *name) +{ + NSSymbol symbol; + char* symbolName; + /* prepend a '_' for the Unix C symbol mangling convention */ + symbolName = malloc(strlen((const char*)name) + 2); + strcpy(symbolName+1, (const char*)name); + symbolName[0] = '_'; + symbol = NULL; + if (NSIsSymbolNameDefined(symbolName)) + symbol = NSLookupAndBindSymbol(symbolName); + free(symbolName); + return symbol ? NSAddressOfSymbol(symbol) : NULL; +} +#endif /* __APPLE__ */ + +#if defined(__sgi) || defined (__sun) +#include +#include +#include + +void* dlGetProcAddress (const GLubyte* name) +{ + static void* h = NULL; + static void* gpa; + + if (h == NULL) + { + if ((h = dlopen(NULL, RTLD_LAZY | RTLD_LOCAL)) == NULL) return NULL; + gpa = dlsym(h, "glXGetProcAddress"); + } + + if (gpa != NULL) + return ((void*(*)(const GLubyte*))gpa)(name); + else + return dlsym(h, (const char*)name); +} +#endif /* __sgi || __sun */ + +/* + * Define glewGetProcAddress. + */ +#if defined(_WIN32) +# define glewGetProcAddress(name) wglGetProcAddress((LPCSTR)name) +#else +# if defined(__APPLE__) +# define glewGetProcAddress(name) NSGLGetProcAddress(name) +# else +# if defined(__sgi) || defined(__sun) +# define glewGetProcAddress(name) dlGetProcAddress(name) +# else /* __linux */ +# define glewGetProcAddress(name) (*glXGetProcAddressARB)(name) +# endif +# endif +#endif + +/* + * GLEW, just like OpenGL or GLU, does not rely on the standard C library. + * These functions implement the functionality required in this file. + */ + +static GLuint _glewStrLen (const GLubyte* s) +{ + GLuint i=0; + if (s == NULL) return 0; + while (s[i] != '\0') i++; + return i; +} + +static GLuint _glewStrCLen (const GLubyte* s, GLubyte c) +{ + GLuint i=0; + if (s == NULL) return 0; + while (s[i] != '\0' && s[i] != c) i++; + return s[i] == c ? i : 0; +} + +static GLboolean _glewStrSame (const GLubyte* a, const GLubyte* b, GLuint n) +{ + GLuint i=0; + if(a == NULL || b == NULL) + return (a == NULL && b == NULL && n == 0) ? GL_TRUE : GL_FALSE; + while (i < n && a[i] != '\0' && b[i] != '\0' && a[i] == b[i]) i++; + return i == n ? GL_TRUE : GL_FALSE; +} + +static GLboolean _glewStrSame1 (GLubyte** a, GLuint* na, const GLubyte* b, GLuint nb) +{ + while (*na > 0 && (**a == ' ' || **a == '\n' || **a == '\r' || **a == '\t')) + { + (*a)++; + (*na)--; + } + if(*na >= nb) + { + GLuint i=0; + while (i < nb && (*a)+i != NULL && b+i != NULL && (*a)[i] == b[i]) i++; + if(i == nb) + { + *a = *a + nb; + *na = *na - nb; + return GL_TRUE; + } + } + return GL_FALSE; +} + +static GLboolean _glewStrSame2 (GLubyte** a, GLuint* na, const GLubyte* b, GLuint nb) +{ + if(*na >= nb) + { + GLuint i=0; + while (i < nb && (*a)+i != NULL && b+i != NULL && (*a)[i] == b[i]) i++; + if(i == nb) + { + *a = *a + nb; + *na = *na - nb; + return GL_TRUE; + } + } + return GL_FALSE; +} + +static GLboolean _glewStrSame3 (GLubyte** a, GLuint* na, const GLubyte* b, GLuint nb) +{ + if(*na >= nb) + { + GLuint i=0; + while (i < nb && (*a)+i != NULL && b+i != NULL && (*a)[i] == b[i]) i++; + if (i == nb && (*na == nb || (*a)[i] == ' ' || (*a)[i] == '\n' || (*a)[i] == '\r' || (*a)[i] == '\t')) + { + *a = *a + nb; + *na = *na - nb; + return GL_TRUE; + } + } + return GL_FALSE; +} + +#if !defined(_WIN32) || !defined(GLEW_MX) + +PFNGLCOPYTEXSUBIMAGE3DPROC __glewCopyTexSubImage3D = NULL; +PFNGLDRAWRANGEELEMENTSPROC __glewDrawRangeElements = NULL; +PFNGLTEXIMAGE3DPROC __glewTexImage3D = NULL; +PFNGLTEXSUBIMAGE3DPROC __glewTexSubImage3D = NULL; + +PFNGLACTIVETEXTUREPROC __glewActiveTexture = NULL; +PFNGLCLIENTACTIVETEXTUREPROC __glewClientActiveTexture = NULL; +PFNGLCOMPRESSEDTEXIMAGE1DPROC __glewCompressedTexImage1D = NULL; +PFNGLCOMPRESSEDTEXIMAGE2DPROC __glewCompressedTexImage2D = NULL; +PFNGLCOMPRESSEDTEXIMAGE3DPROC __glewCompressedTexImage3D = NULL; +PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC __glewCompressedTexSubImage1D = NULL; +PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC __glewCompressedTexSubImage2D = NULL; +PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC __glewCompressedTexSubImage3D = NULL; +PFNGLGETCOMPRESSEDTEXIMAGEPROC __glewGetCompressedTexImage = NULL; +PFNGLLOADTRANSPOSEMATRIXDPROC __glewLoadTransposeMatrixd = NULL; +PFNGLLOADTRANSPOSEMATRIXFPROC __glewLoadTransposeMatrixf = NULL; +PFNGLMULTTRANSPOSEMATRIXDPROC __glewMultTransposeMatrixd = NULL; +PFNGLMULTTRANSPOSEMATRIXFPROC __glewMultTransposeMatrixf = NULL; +PFNGLMULTITEXCOORD1DPROC __glewMultiTexCoord1d = NULL; +PFNGLMULTITEXCOORD1DVPROC __glewMultiTexCoord1dv = NULL; +PFNGLMULTITEXCOORD1FPROC __glewMultiTexCoord1f = NULL; +PFNGLMULTITEXCOORD1FVPROC __glewMultiTexCoord1fv = NULL; +PFNGLMULTITEXCOORD1IPROC __glewMultiTexCoord1i = NULL; +PFNGLMULTITEXCOORD1IVPROC __glewMultiTexCoord1iv = NULL; +PFNGLMULTITEXCOORD1SPROC __glewMultiTexCoord1s = NULL; +PFNGLMULTITEXCOORD1SVPROC __glewMultiTexCoord1sv = NULL; +PFNGLMULTITEXCOORD2DPROC __glewMultiTexCoord2d = NULL; +PFNGLMULTITEXCOORD2DVPROC __glewMultiTexCoord2dv = NULL; +PFNGLMULTITEXCOORD2FPROC __glewMultiTexCoord2f = NULL; +PFNGLMULTITEXCOORD2FVPROC __glewMultiTexCoord2fv = NULL; +PFNGLMULTITEXCOORD2IPROC __glewMultiTexCoord2i = NULL; +PFNGLMULTITEXCOORD2IVPROC __glewMultiTexCoord2iv = NULL; +PFNGLMULTITEXCOORD2SPROC __glewMultiTexCoord2s = NULL; +PFNGLMULTITEXCOORD2SVPROC __glewMultiTexCoord2sv = NULL; +PFNGLMULTITEXCOORD3DPROC __glewMultiTexCoord3d = NULL; +PFNGLMULTITEXCOORD3DVPROC __glewMultiTexCoord3dv = NULL; +PFNGLMULTITEXCOORD3FPROC __glewMultiTexCoord3f = NULL; +PFNGLMULTITEXCOORD3FVPROC __glewMultiTexCoord3fv = NULL; +PFNGLMULTITEXCOORD3IPROC __glewMultiTexCoord3i = NULL; +PFNGLMULTITEXCOORD3IVPROC __glewMultiTexCoord3iv = NULL; +PFNGLMULTITEXCOORD3SPROC __glewMultiTexCoord3s = NULL; +PFNGLMULTITEXCOORD3SVPROC __glewMultiTexCoord3sv = NULL; +PFNGLMULTITEXCOORD4DPROC __glewMultiTexCoord4d = NULL; +PFNGLMULTITEXCOORD4DVPROC __glewMultiTexCoord4dv = NULL; +PFNGLMULTITEXCOORD4FPROC __glewMultiTexCoord4f = NULL; +PFNGLMULTITEXCOORD4FVPROC __glewMultiTexCoord4fv = NULL; +PFNGLMULTITEXCOORD4IPROC __glewMultiTexCoord4i = NULL; +PFNGLMULTITEXCOORD4IVPROC __glewMultiTexCoord4iv = NULL; +PFNGLMULTITEXCOORD4SPROC __glewMultiTexCoord4s = NULL; +PFNGLMULTITEXCOORD4SVPROC __glewMultiTexCoord4sv = NULL; +PFNGLSAMPLECOVERAGEPROC __glewSampleCoverage = NULL; + +PFNGLBLENDCOLORPROC __glewBlendColor = NULL; +PFNGLBLENDEQUATIONPROC __glewBlendEquation = NULL; +PFNGLBLENDFUNCSEPARATEPROC __glewBlendFuncSeparate = NULL; +PFNGLFOGCOORDPOINTERPROC __glewFogCoordPointer = NULL; +PFNGLFOGCOORDDPROC __glewFogCoordd = NULL; +PFNGLFOGCOORDDVPROC __glewFogCoorddv = NULL; +PFNGLFOGCOORDFPROC __glewFogCoordf = NULL; +PFNGLFOGCOORDFVPROC __glewFogCoordfv = NULL; +PFNGLMULTIDRAWARRAYSPROC __glewMultiDrawArrays = NULL; +PFNGLMULTIDRAWELEMENTSPROC __glewMultiDrawElements = NULL; +PFNGLPOINTPARAMETERFPROC __glewPointParameterf = NULL; +PFNGLPOINTPARAMETERFVPROC __glewPointParameterfv = NULL; +PFNGLSECONDARYCOLOR3BPROC __glewSecondaryColor3b = NULL; +PFNGLSECONDARYCOLOR3BVPROC __glewSecondaryColor3bv = NULL; +PFNGLSECONDARYCOLOR3DPROC __glewSecondaryColor3d = NULL; +PFNGLSECONDARYCOLOR3DVPROC __glewSecondaryColor3dv = NULL; +PFNGLSECONDARYCOLOR3FPROC __glewSecondaryColor3f = NULL; +PFNGLSECONDARYCOLOR3FVPROC __glewSecondaryColor3fv = NULL; +PFNGLSECONDARYCOLOR3IPROC __glewSecondaryColor3i = NULL; +PFNGLSECONDARYCOLOR3IVPROC __glewSecondaryColor3iv = NULL; +PFNGLSECONDARYCOLOR3SPROC __glewSecondaryColor3s = NULL; +PFNGLSECONDARYCOLOR3SVPROC __glewSecondaryColor3sv = NULL; +PFNGLSECONDARYCOLOR3UBPROC __glewSecondaryColor3ub = NULL; +PFNGLSECONDARYCOLOR3UBVPROC __glewSecondaryColor3ubv = NULL; +PFNGLSECONDARYCOLOR3UIPROC __glewSecondaryColor3ui = NULL; +PFNGLSECONDARYCOLOR3UIVPROC __glewSecondaryColor3uiv = NULL; +PFNGLSECONDARYCOLOR3USPROC __glewSecondaryColor3us = NULL; +PFNGLSECONDARYCOLOR3USVPROC __glewSecondaryColor3usv = NULL; +PFNGLSECONDARYCOLORPOINTERPROC __glewSecondaryColorPointer = NULL; +PFNGLWINDOWPOS2DPROC __glewWindowPos2d = NULL; +PFNGLWINDOWPOS2DVPROC __glewWindowPos2dv = NULL; +PFNGLWINDOWPOS2FPROC __glewWindowPos2f = NULL; +PFNGLWINDOWPOS2FVPROC __glewWindowPos2fv = NULL; +PFNGLWINDOWPOS2IPROC __glewWindowPos2i = NULL; +PFNGLWINDOWPOS2IVPROC __glewWindowPos2iv = NULL; +PFNGLWINDOWPOS2SPROC __glewWindowPos2s = NULL; +PFNGLWINDOWPOS2SVPROC __glewWindowPos2sv = NULL; +PFNGLWINDOWPOS3DPROC __glewWindowPos3d = NULL; +PFNGLWINDOWPOS3DVPROC __glewWindowPos3dv = NULL; +PFNGLWINDOWPOS3FPROC __glewWindowPos3f = NULL; +PFNGLWINDOWPOS3FVPROC __glewWindowPos3fv = NULL; +PFNGLWINDOWPOS3IPROC __glewWindowPos3i = NULL; +PFNGLWINDOWPOS3IVPROC __glewWindowPos3iv = NULL; +PFNGLWINDOWPOS3SPROC __glewWindowPos3s = NULL; +PFNGLWINDOWPOS3SVPROC __glewWindowPos3sv = NULL; + +PFNGLBEGINQUERYPROC __glewBeginQuery = NULL; +PFNGLBINDBUFFERPROC __glewBindBuffer = NULL; +PFNGLBUFFERDATAPROC __glewBufferData = NULL; +PFNGLBUFFERSUBDATAPROC __glewBufferSubData = NULL; +PFNGLDELETEBUFFERSPROC __glewDeleteBuffers = NULL; +PFNGLDELETEQUERIESPROC __glewDeleteQueries = NULL; +PFNGLENDQUERYPROC __glewEndQuery = NULL; +PFNGLGENBUFFERSPROC __glewGenBuffers = NULL; +PFNGLGENQUERIESPROC __glewGenQueries = NULL; +PFNGLGETBUFFERPARAMETERIVPROC __glewGetBufferParameteriv = NULL; +PFNGLGETBUFFERPOINTERVPROC __glewGetBufferPointerv = NULL; +PFNGLGETBUFFERSUBDATAPROC __glewGetBufferSubData = NULL; +PFNGLGETQUERYOBJECTIVPROC __glewGetQueryObjectiv = NULL; +PFNGLGETQUERYOBJECTUIVPROC __glewGetQueryObjectuiv = NULL; +PFNGLGETQUERYIVPROC __glewGetQueryiv = NULL; +PFNGLISBUFFERPROC __glewIsBuffer = NULL; +PFNGLISQUERYPROC __glewIsQuery = NULL; +PFNGLMAPBUFFERPROC __glewMapBuffer = NULL; +PFNGLUNMAPBUFFERPROC __glewUnmapBuffer = NULL; + +PFNGLATTACHSHADERPROC __glewAttachShader = NULL; +PFNGLBINDATTRIBLOCATIONPROC __glewBindAttribLocation = NULL; +PFNGLBLENDEQUATIONSEPARATEPROC __glewBlendEquationSeparate = NULL; +PFNGLCOMPILESHADERPROC __glewCompileShader = NULL; +PFNGLCREATEPROGRAMPROC __glewCreateProgram = NULL; +PFNGLCREATESHADERPROC __glewCreateShader = NULL; +PFNGLDELETEPROGRAMPROC __glewDeleteProgram = NULL; +PFNGLDELETESHADERPROC __glewDeleteShader = NULL; +PFNGLDETACHSHADERPROC __glewDetachShader = NULL; +PFNGLDISABLEVERTEXATTRIBARRAYPROC __glewDisableVertexAttribArray = NULL; +PFNGLDRAWBUFFERSPROC __glewDrawBuffers = NULL; +PFNGLENABLEVERTEXATTRIBARRAYPROC __glewEnableVertexAttribArray = NULL; +PFNGLGETACTIVEATTRIBPROC __glewGetActiveAttrib = NULL; +PFNGLGETACTIVEUNIFORMPROC __glewGetActiveUniform = NULL; +PFNGLGETATTACHEDSHADERSPROC __glewGetAttachedShaders = NULL; +PFNGLGETATTRIBLOCATIONPROC __glewGetAttribLocation = NULL; +PFNGLGETPROGRAMINFOLOGPROC __glewGetProgramInfoLog = NULL; +PFNGLGETPROGRAMIVPROC __glewGetProgramiv = NULL; +PFNGLGETSHADERINFOLOGPROC __glewGetShaderInfoLog = NULL; +PFNGLGETSHADERSOURCEPROC __glewGetShaderSource = NULL; +PFNGLGETSHADERIVPROC __glewGetShaderiv = NULL; +PFNGLGETUNIFORMLOCATIONPROC __glewGetUniformLocation = NULL; +PFNGLGETUNIFORMFVPROC __glewGetUniformfv = NULL; +PFNGLGETUNIFORMIVPROC __glewGetUniformiv = NULL; +PFNGLGETVERTEXATTRIBPOINTERVPROC __glewGetVertexAttribPointerv = NULL; +PFNGLGETVERTEXATTRIBDVPROC __glewGetVertexAttribdv = NULL; +PFNGLGETVERTEXATTRIBFVPROC __glewGetVertexAttribfv = NULL; +PFNGLGETVERTEXATTRIBIVPROC __glewGetVertexAttribiv = NULL; +PFNGLISPROGRAMPROC __glewIsProgram = NULL; +PFNGLISSHADERPROC __glewIsShader = NULL; +PFNGLLINKPROGRAMPROC __glewLinkProgram = NULL; +PFNGLSHADERSOURCEPROC __glewShaderSource = NULL; +PFNGLSTENCILFUNCSEPARATEPROC __glewStencilFuncSeparate = NULL; +PFNGLSTENCILMASKSEPARATEPROC __glewStencilMaskSeparate = NULL; +PFNGLSTENCILOPSEPARATEPROC __glewStencilOpSeparate = NULL; +PFNGLUNIFORM1FPROC __glewUniform1f = NULL; +PFNGLUNIFORM1FVPROC __glewUniform1fv = NULL; +PFNGLUNIFORM1IPROC __glewUniform1i = NULL; +PFNGLUNIFORM1IVPROC __glewUniform1iv = NULL; +PFNGLUNIFORM2FPROC __glewUniform2f = NULL; +PFNGLUNIFORM2FVPROC __glewUniform2fv = NULL; +PFNGLUNIFORM2IPROC __glewUniform2i = NULL; +PFNGLUNIFORM2IVPROC __glewUniform2iv = NULL; +PFNGLUNIFORM3FPROC __glewUniform3f = NULL; +PFNGLUNIFORM3FVPROC __glewUniform3fv = NULL; +PFNGLUNIFORM3IPROC __glewUniform3i = NULL; +PFNGLUNIFORM3IVPROC __glewUniform3iv = NULL; +PFNGLUNIFORM4FPROC __glewUniform4f = NULL; +PFNGLUNIFORM4FVPROC __glewUniform4fv = NULL; +PFNGLUNIFORM4IPROC __glewUniform4i = NULL; +PFNGLUNIFORM4IVPROC __glewUniform4iv = NULL; +PFNGLUNIFORMMATRIX2FVPROC __glewUniformMatrix2fv = NULL; +PFNGLUNIFORMMATRIX3FVPROC __glewUniformMatrix3fv = NULL; +PFNGLUNIFORMMATRIX4FVPROC __glewUniformMatrix4fv = NULL; +PFNGLUSEPROGRAMPROC __glewUseProgram = NULL; +PFNGLVALIDATEPROGRAMPROC __glewValidateProgram = NULL; +PFNGLVERTEXATTRIB1DPROC __glewVertexAttrib1d = NULL; +PFNGLVERTEXATTRIB1DVPROC __glewVertexAttrib1dv = NULL; +PFNGLVERTEXATTRIB1FPROC __glewVertexAttrib1f = NULL; +PFNGLVERTEXATTRIB1FVPROC __glewVertexAttrib1fv = NULL; +PFNGLVERTEXATTRIB1SPROC __glewVertexAttrib1s = NULL; +PFNGLVERTEXATTRIB1SVPROC __glewVertexAttrib1sv = NULL; +PFNGLVERTEXATTRIB2DPROC __glewVertexAttrib2d = NULL; +PFNGLVERTEXATTRIB2DVPROC __glewVertexAttrib2dv = NULL; +PFNGLVERTEXATTRIB2FPROC __glewVertexAttrib2f = NULL; +PFNGLVERTEXATTRIB2FVPROC __glewVertexAttrib2fv = NULL; +PFNGLVERTEXATTRIB2SPROC __glewVertexAttrib2s = NULL; +PFNGLVERTEXATTRIB2SVPROC __glewVertexAttrib2sv = NULL; +PFNGLVERTEXATTRIB3DPROC __glewVertexAttrib3d = NULL; +PFNGLVERTEXATTRIB3DVPROC __glewVertexAttrib3dv = NULL; +PFNGLVERTEXATTRIB3FPROC __glewVertexAttrib3f = NULL; +PFNGLVERTEXATTRIB3FVPROC __glewVertexAttrib3fv = NULL; +PFNGLVERTEXATTRIB3SPROC __glewVertexAttrib3s = NULL; +PFNGLVERTEXATTRIB3SVPROC __glewVertexAttrib3sv = NULL; +PFNGLVERTEXATTRIB4NBVPROC __glewVertexAttrib4Nbv = NULL; +PFNGLVERTEXATTRIB4NIVPROC __glewVertexAttrib4Niv = NULL; +PFNGLVERTEXATTRIB4NSVPROC __glewVertexAttrib4Nsv = NULL; +PFNGLVERTEXATTRIB4NUBPROC __glewVertexAttrib4Nub = NULL; +PFNGLVERTEXATTRIB4NUBVPROC __glewVertexAttrib4Nubv = NULL; +PFNGLVERTEXATTRIB4NUIVPROC __glewVertexAttrib4Nuiv = NULL; +PFNGLVERTEXATTRIB4NUSVPROC __glewVertexAttrib4Nusv = NULL; +PFNGLVERTEXATTRIB4BVPROC __glewVertexAttrib4bv = NULL; +PFNGLVERTEXATTRIB4DPROC __glewVertexAttrib4d = NULL; +PFNGLVERTEXATTRIB4DVPROC __glewVertexAttrib4dv = NULL; +PFNGLVERTEXATTRIB4FPROC __glewVertexAttrib4f = NULL; +PFNGLVERTEXATTRIB4FVPROC __glewVertexAttrib4fv = NULL; +PFNGLVERTEXATTRIB4IVPROC __glewVertexAttrib4iv = NULL; +PFNGLVERTEXATTRIB4SPROC __glewVertexAttrib4s = NULL; +PFNGLVERTEXATTRIB4SVPROC __glewVertexAttrib4sv = NULL; +PFNGLVERTEXATTRIB4UBVPROC __glewVertexAttrib4ubv = NULL; +PFNGLVERTEXATTRIB4UIVPROC __glewVertexAttrib4uiv = NULL; +PFNGLVERTEXATTRIB4USVPROC __glewVertexAttrib4usv = NULL; +PFNGLVERTEXATTRIBPOINTERPROC __glewVertexAttribPointer = NULL; + +PFNGLTBUFFERMASK3DFXPROC __glewTbufferMask3DFX = NULL; + +PFNGLDRAWELEMENTARRAYAPPLEPROC __glewDrawElementArrayAPPLE = NULL; +PFNGLDRAWRANGEELEMENTARRAYAPPLEPROC __glewDrawRangeElementArrayAPPLE = NULL; +PFNGLELEMENTPOINTERAPPLEPROC __glewElementPointerAPPLE = NULL; +PFNGLMULTIDRAWELEMENTARRAYAPPLEPROC __glewMultiDrawElementArrayAPPLE = NULL; +PFNGLMULTIDRAWRANGEELEMENTARRAYAPPLEPROC __glewMultiDrawRangeElementArrayAPPLE = NULL; + +PFNGLDELETEFENCESAPPLEPROC __glewDeleteFencesAPPLE = NULL; +PFNGLFINISHFENCEAPPLEPROC __glewFinishFenceAPPLE = NULL; +PFNGLFINISHOBJECTAPPLEPROC __glewFinishObjectAPPLE = NULL; +PFNGLGENFENCESAPPLEPROC __glewGenFencesAPPLE = NULL; +PFNGLISFENCEAPPLEPROC __glewIsFenceAPPLE = NULL; +PFNGLSETFENCEAPPLEPROC __glewSetFenceAPPLE = NULL; +PFNGLTESTFENCEAPPLEPROC __glewTestFenceAPPLE = NULL; +PFNGLTESTOBJECTAPPLEPROC __glewTestObjectAPPLE = NULL; + +PFNGLGETTEXPARAMETERPOINTERVAPPLEPROC __glewGetTexParameterPointervAPPLE = NULL; +PFNGLTEXTURERANGEAPPLEPROC __glewTextureRangeAPPLE = NULL; + +PFNGLBINDVERTEXARRAYAPPLEPROC __glewBindVertexArrayAPPLE = NULL; +PFNGLDELETEVERTEXARRAYSAPPLEPROC __glewDeleteVertexArraysAPPLE = NULL; +PFNGLGENVERTEXARRAYSAPPLEPROC __glewGenVertexArraysAPPLE = NULL; +PFNGLISVERTEXARRAYAPPLEPROC __glewIsVertexArrayAPPLE = NULL; + +PFNGLFLUSHVERTEXARRAYRANGEAPPLEPROC __glewFlushVertexArrayRangeAPPLE = NULL; +PFNGLVERTEXARRAYPARAMETERIAPPLEPROC __glewVertexArrayParameteriAPPLE = NULL; +PFNGLVERTEXARRAYRANGEAPPLEPROC __glewVertexArrayRangeAPPLE = NULL; + +PFNGLCLAMPCOLORARBPROC __glewClampColorARB = NULL; + +PFNGLDRAWBUFFERSARBPROC __glewDrawBuffersARB = NULL; + +PFNGLCOLORSUBTABLEPROC __glewColorSubTable = NULL; +PFNGLCOLORTABLEPROC __glewColorTable = NULL; +PFNGLCOLORTABLEPARAMETERFVPROC __glewColorTableParameterfv = NULL; +PFNGLCOLORTABLEPARAMETERIVPROC __glewColorTableParameteriv = NULL; +PFNGLCONVOLUTIONFILTER1DPROC __glewConvolutionFilter1D = NULL; +PFNGLCONVOLUTIONFILTER2DPROC __glewConvolutionFilter2D = NULL; +PFNGLCONVOLUTIONPARAMETERFPROC __glewConvolutionParameterf = NULL; +PFNGLCONVOLUTIONPARAMETERFVPROC __glewConvolutionParameterfv = NULL; +PFNGLCONVOLUTIONPARAMETERIPROC __glewConvolutionParameteri = NULL; +PFNGLCONVOLUTIONPARAMETERIVPROC __glewConvolutionParameteriv = NULL; +PFNGLCOPYCOLORSUBTABLEPROC __glewCopyColorSubTable = NULL; +PFNGLCOPYCOLORTABLEPROC __glewCopyColorTable = NULL; +PFNGLCOPYCONVOLUTIONFILTER1DPROC __glewCopyConvolutionFilter1D = NULL; +PFNGLCOPYCONVOLUTIONFILTER2DPROC __glewCopyConvolutionFilter2D = NULL; +PFNGLGETCOLORTABLEPROC __glewGetColorTable = NULL; +PFNGLGETCOLORTABLEPARAMETERFVPROC __glewGetColorTableParameterfv = NULL; +PFNGLGETCOLORTABLEPARAMETERIVPROC __glewGetColorTableParameteriv = NULL; +PFNGLGETCONVOLUTIONFILTERPROC __glewGetConvolutionFilter = NULL; +PFNGLGETCONVOLUTIONPARAMETERFVPROC __glewGetConvolutionParameterfv = NULL; +PFNGLGETCONVOLUTIONPARAMETERIVPROC __glewGetConvolutionParameteriv = NULL; +PFNGLGETHISTOGRAMPROC __glewGetHistogram = NULL; +PFNGLGETHISTOGRAMPARAMETERFVPROC __glewGetHistogramParameterfv = NULL; +PFNGLGETHISTOGRAMPARAMETERIVPROC __glewGetHistogramParameteriv = NULL; +PFNGLGETMINMAXPROC __glewGetMinmax = NULL; +PFNGLGETMINMAXPARAMETERFVPROC __glewGetMinmaxParameterfv = NULL; +PFNGLGETMINMAXPARAMETERIVPROC __glewGetMinmaxParameteriv = NULL; +PFNGLGETSEPARABLEFILTERPROC __glewGetSeparableFilter = NULL; +PFNGLHISTOGRAMPROC __glewHistogram = NULL; +PFNGLMINMAXPROC __glewMinmax = NULL; +PFNGLRESETHISTOGRAMPROC __glewResetHistogram = NULL; +PFNGLRESETMINMAXPROC __glewResetMinmax = NULL; +PFNGLSEPARABLEFILTER2DPROC __glewSeparableFilter2D = NULL; + +PFNGLCURRENTPALETTEMATRIXARBPROC __glewCurrentPaletteMatrixARB = NULL; +PFNGLMATRIXINDEXPOINTERARBPROC __glewMatrixIndexPointerARB = NULL; +PFNGLMATRIXINDEXUBVARBPROC __glewMatrixIndexubvARB = NULL; +PFNGLMATRIXINDEXUIVARBPROC __glewMatrixIndexuivARB = NULL; +PFNGLMATRIXINDEXUSVARBPROC __glewMatrixIndexusvARB = NULL; + +PFNGLSAMPLECOVERAGEARBPROC __glewSampleCoverageARB = NULL; + +PFNGLACTIVETEXTUREARBPROC __glewActiveTextureARB = NULL; +PFNGLCLIENTACTIVETEXTUREARBPROC __glewClientActiveTextureARB = NULL; +PFNGLMULTITEXCOORD1DARBPROC __glewMultiTexCoord1dARB = NULL; +PFNGLMULTITEXCOORD1DVARBPROC __glewMultiTexCoord1dvARB = NULL; +PFNGLMULTITEXCOORD1FARBPROC __glewMultiTexCoord1fARB = NULL; +PFNGLMULTITEXCOORD1FVARBPROC __glewMultiTexCoord1fvARB = NULL; +PFNGLMULTITEXCOORD1IARBPROC __glewMultiTexCoord1iARB = NULL; +PFNGLMULTITEXCOORD1IVARBPROC __glewMultiTexCoord1ivARB = NULL; +PFNGLMULTITEXCOORD1SARBPROC __glewMultiTexCoord1sARB = NULL; +PFNGLMULTITEXCOORD1SVARBPROC __glewMultiTexCoord1svARB = NULL; +PFNGLMULTITEXCOORD2DARBPROC __glewMultiTexCoord2dARB = NULL; +PFNGLMULTITEXCOORD2DVARBPROC __glewMultiTexCoord2dvARB = NULL; +PFNGLMULTITEXCOORD2FARBPROC __glewMultiTexCoord2fARB = NULL; +PFNGLMULTITEXCOORD2FVARBPROC __glewMultiTexCoord2fvARB = NULL; +PFNGLMULTITEXCOORD2IARBPROC __glewMultiTexCoord2iARB = NULL; +PFNGLMULTITEXCOORD2IVARBPROC __glewMultiTexCoord2ivARB = NULL; +PFNGLMULTITEXCOORD2SARBPROC __glewMultiTexCoord2sARB = NULL; +PFNGLMULTITEXCOORD2SVARBPROC __glewMultiTexCoord2svARB = NULL; +PFNGLMULTITEXCOORD3DARBPROC __glewMultiTexCoord3dARB = NULL; +PFNGLMULTITEXCOORD3DVARBPROC __glewMultiTexCoord3dvARB = NULL; +PFNGLMULTITEXCOORD3FARBPROC __glewMultiTexCoord3fARB = NULL; +PFNGLMULTITEXCOORD3FVARBPROC __glewMultiTexCoord3fvARB = NULL; +PFNGLMULTITEXCOORD3IARBPROC __glewMultiTexCoord3iARB = NULL; +PFNGLMULTITEXCOORD3IVARBPROC __glewMultiTexCoord3ivARB = NULL; +PFNGLMULTITEXCOORD3SARBPROC __glewMultiTexCoord3sARB = NULL; +PFNGLMULTITEXCOORD3SVARBPROC __glewMultiTexCoord3svARB = NULL; +PFNGLMULTITEXCOORD4DARBPROC __glewMultiTexCoord4dARB = NULL; +PFNGLMULTITEXCOORD4DVARBPROC __glewMultiTexCoord4dvARB = NULL; +PFNGLMULTITEXCOORD4FARBPROC __glewMultiTexCoord4fARB = NULL; +PFNGLMULTITEXCOORD4FVARBPROC __glewMultiTexCoord4fvARB = NULL; +PFNGLMULTITEXCOORD4IARBPROC __glewMultiTexCoord4iARB = NULL; +PFNGLMULTITEXCOORD4IVARBPROC __glewMultiTexCoord4ivARB = NULL; +PFNGLMULTITEXCOORD4SARBPROC __glewMultiTexCoord4sARB = NULL; +PFNGLMULTITEXCOORD4SVARBPROC __glewMultiTexCoord4svARB = NULL; + +PFNGLBEGINQUERYARBPROC __glewBeginQueryARB = NULL; +PFNGLDELETEQUERIESARBPROC __glewDeleteQueriesARB = NULL; +PFNGLENDQUERYARBPROC __glewEndQueryARB = NULL; +PFNGLGENQUERIESARBPROC __glewGenQueriesARB = NULL; +PFNGLGETQUERYOBJECTIVARBPROC __glewGetQueryObjectivARB = NULL; +PFNGLGETQUERYOBJECTUIVARBPROC __glewGetQueryObjectuivARB = NULL; +PFNGLGETQUERYIVARBPROC __glewGetQueryivARB = NULL; +PFNGLISQUERYARBPROC __glewIsQueryARB = NULL; + +PFNGLPOINTPARAMETERFARBPROC __glewPointParameterfARB = NULL; +PFNGLPOINTPARAMETERFVARBPROC __glewPointParameterfvARB = NULL; + +PFNGLATTACHOBJECTARBPROC __glewAttachObjectARB = NULL; +PFNGLCOMPILESHADERARBPROC __glewCompileShaderARB = NULL; +PFNGLCREATEPROGRAMOBJECTARBPROC __glewCreateProgramObjectARB = NULL; +PFNGLCREATESHADEROBJECTARBPROC __glewCreateShaderObjectARB = NULL; +PFNGLDELETEOBJECTARBPROC __glewDeleteObjectARB = NULL; +PFNGLDETACHOBJECTARBPROC __glewDetachObjectARB = NULL; +PFNGLGETACTIVEUNIFORMARBPROC __glewGetActiveUniformARB = NULL; +PFNGLGETATTACHEDOBJECTSARBPROC __glewGetAttachedObjectsARB = NULL; +PFNGLGETHANDLEARBPROC __glewGetHandleARB = NULL; +PFNGLGETINFOLOGARBPROC __glewGetInfoLogARB = NULL; +PFNGLGETOBJECTPARAMETERFVARBPROC __glewGetObjectParameterfvARB = NULL; +PFNGLGETOBJECTPARAMETERIVARBPROC __glewGetObjectParameterivARB = NULL; +PFNGLGETSHADERSOURCEARBPROC __glewGetShaderSourceARB = NULL; +PFNGLGETUNIFORMLOCATIONARBPROC __glewGetUniformLocationARB = NULL; +PFNGLGETUNIFORMFVARBPROC __glewGetUniformfvARB = NULL; +PFNGLGETUNIFORMIVARBPROC __glewGetUniformivARB = NULL; +PFNGLLINKPROGRAMARBPROC __glewLinkProgramARB = NULL; +PFNGLSHADERSOURCEARBPROC __glewShaderSourceARB = NULL; +PFNGLUNIFORM1FARBPROC __glewUniform1fARB = NULL; +PFNGLUNIFORM1FVARBPROC __glewUniform1fvARB = NULL; +PFNGLUNIFORM1IARBPROC __glewUniform1iARB = NULL; +PFNGLUNIFORM1IVARBPROC __glewUniform1ivARB = NULL; +PFNGLUNIFORM2FARBPROC __glewUniform2fARB = NULL; +PFNGLUNIFORM2FVARBPROC __glewUniform2fvARB = NULL; +PFNGLUNIFORM2IARBPROC __glewUniform2iARB = NULL; +PFNGLUNIFORM2IVARBPROC __glewUniform2ivARB = NULL; +PFNGLUNIFORM3FARBPROC __glewUniform3fARB = NULL; +PFNGLUNIFORM3FVARBPROC __glewUniform3fvARB = NULL; +PFNGLUNIFORM3IARBPROC __glewUniform3iARB = NULL; +PFNGLUNIFORM3IVARBPROC __glewUniform3ivARB = NULL; +PFNGLUNIFORM4FARBPROC __glewUniform4fARB = NULL; +PFNGLUNIFORM4FVARBPROC __glewUniform4fvARB = NULL; +PFNGLUNIFORM4IARBPROC __glewUniform4iARB = NULL; +PFNGLUNIFORM4IVARBPROC __glewUniform4ivARB = NULL; +PFNGLUNIFORMMATRIX2FVARBPROC __glewUniformMatrix2fvARB = NULL; +PFNGLUNIFORMMATRIX3FVARBPROC __glewUniformMatrix3fvARB = NULL; +PFNGLUNIFORMMATRIX4FVARBPROC __glewUniformMatrix4fvARB = NULL; +PFNGLUSEPROGRAMOBJECTARBPROC __glewUseProgramObjectARB = NULL; +PFNGLVALIDATEPROGRAMARBPROC __glewValidateProgramARB = NULL; + +PFNGLCOMPRESSEDTEXIMAGE1DARBPROC __glewCompressedTexImage1DARB = NULL; +PFNGLCOMPRESSEDTEXIMAGE2DARBPROC __glewCompressedTexImage2DARB = NULL; +PFNGLCOMPRESSEDTEXIMAGE3DARBPROC __glewCompressedTexImage3DARB = NULL; +PFNGLCOMPRESSEDTEXSUBIMAGE1DARBPROC __glewCompressedTexSubImage1DARB = NULL; +PFNGLCOMPRESSEDTEXSUBIMAGE2DARBPROC __glewCompressedTexSubImage2DARB = NULL; +PFNGLCOMPRESSEDTEXSUBIMAGE3DARBPROC __glewCompressedTexSubImage3DARB = NULL; +PFNGLGETCOMPRESSEDTEXIMAGEARBPROC __glewGetCompressedTexImageARB = NULL; + +PFNGLLOADTRANSPOSEMATRIXDARBPROC __glewLoadTransposeMatrixdARB = NULL; +PFNGLLOADTRANSPOSEMATRIXFARBPROC __glewLoadTransposeMatrixfARB = NULL; +PFNGLMULTTRANSPOSEMATRIXDARBPROC __glewMultTransposeMatrixdARB = NULL; +PFNGLMULTTRANSPOSEMATRIXFARBPROC __glewMultTransposeMatrixfARB = NULL; + +PFNGLVERTEXBLENDARBPROC __glewVertexBlendARB = NULL; +PFNGLWEIGHTPOINTERARBPROC __glewWeightPointerARB = NULL; +PFNGLWEIGHTBVARBPROC __glewWeightbvARB = NULL; +PFNGLWEIGHTDVARBPROC __glewWeightdvARB = NULL; +PFNGLWEIGHTFVARBPROC __glewWeightfvARB = NULL; +PFNGLWEIGHTIVARBPROC __glewWeightivARB = NULL; +PFNGLWEIGHTSVARBPROC __glewWeightsvARB = NULL; +PFNGLWEIGHTUBVARBPROC __glewWeightubvARB = NULL; +PFNGLWEIGHTUIVARBPROC __glewWeightuivARB = NULL; +PFNGLWEIGHTUSVARBPROC __glewWeightusvARB = NULL; + +PFNGLBINDBUFFERARBPROC __glewBindBufferARB = NULL; +PFNGLBUFFERDATAARBPROC __glewBufferDataARB = NULL; +PFNGLBUFFERSUBDATAARBPROC __glewBufferSubDataARB = NULL; +PFNGLDELETEBUFFERSARBPROC __glewDeleteBuffersARB = NULL; +PFNGLGENBUFFERSARBPROC __glewGenBuffersARB = NULL; +PFNGLGETBUFFERPARAMETERIVARBPROC __glewGetBufferParameterivARB = NULL; +PFNGLGETBUFFERPOINTERVARBPROC __glewGetBufferPointervARB = NULL; +PFNGLGETBUFFERSUBDATAARBPROC __glewGetBufferSubDataARB = NULL; +PFNGLISBUFFERARBPROC __glewIsBufferARB = NULL; +PFNGLMAPBUFFERARBPROC __glewMapBufferARB = NULL; +PFNGLUNMAPBUFFERARBPROC __glewUnmapBufferARB = NULL; + +PFNGLBINDPROGRAMARBPROC __glewBindProgramARB = NULL; +PFNGLDELETEPROGRAMSARBPROC __glewDeleteProgramsARB = NULL; +PFNGLDISABLEVERTEXATTRIBARRAYARBPROC __glewDisableVertexAttribArrayARB = NULL; +PFNGLENABLEVERTEXATTRIBARRAYARBPROC __glewEnableVertexAttribArrayARB = NULL; +PFNGLGENPROGRAMSARBPROC __glewGenProgramsARB = NULL; +PFNGLGETPROGRAMENVPARAMETERDVARBPROC __glewGetProgramEnvParameterdvARB = NULL; +PFNGLGETPROGRAMENVPARAMETERFVARBPROC __glewGetProgramEnvParameterfvARB = NULL; +PFNGLGETPROGRAMLOCALPARAMETERDVARBPROC __glewGetProgramLocalParameterdvARB = NULL; +PFNGLGETPROGRAMLOCALPARAMETERFVARBPROC __glewGetProgramLocalParameterfvARB = NULL; +PFNGLGETPROGRAMSTRINGARBPROC __glewGetProgramStringARB = NULL; +PFNGLGETPROGRAMIVARBPROC __glewGetProgramivARB = NULL; +PFNGLGETVERTEXATTRIBPOINTERVARBPROC __glewGetVertexAttribPointervARB = NULL; +PFNGLGETVERTEXATTRIBDVARBPROC __glewGetVertexAttribdvARB = NULL; +PFNGLGETVERTEXATTRIBFVARBPROC __glewGetVertexAttribfvARB = NULL; +PFNGLGETVERTEXATTRIBIVARBPROC __glewGetVertexAttribivARB = NULL; +PFNGLISPROGRAMARBPROC __glewIsProgramARB = NULL; +PFNGLPROGRAMENVPARAMETER4DARBPROC __glewProgramEnvParameter4dARB = NULL; +PFNGLPROGRAMENVPARAMETER4DVARBPROC __glewProgramEnvParameter4dvARB = NULL; +PFNGLPROGRAMENVPARAMETER4FARBPROC __glewProgramEnvParameter4fARB = NULL; +PFNGLPROGRAMENVPARAMETER4FVARBPROC __glewProgramEnvParameter4fvARB = NULL; +PFNGLPROGRAMLOCALPARAMETER4DARBPROC __glewProgramLocalParameter4dARB = NULL; +PFNGLPROGRAMLOCALPARAMETER4DVARBPROC __glewProgramLocalParameter4dvARB = NULL; +PFNGLPROGRAMLOCALPARAMETER4FARBPROC __glewProgramLocalParameter4fARB = NULL; +PFNGLPROGRAMLOCALPARAMETER4FVARBPROC __glewProgramLocalParameter4fvARB = NULL; +PFNGLPROGRAMSTRINGARBPROC __glewProgramStringARB = NULL; +PFNGLVERTEXATTRIB1DARBPROC __glewVertexAttrib1dARB = NULL; +PFNGLVERTEXATTRIB1DVARBPROC __glewVertexAttrib1dvARB = NULL; +PFNGLVERTEXATTRIB1FARBPROC __glewVertexAttrib1fARB = NULL; +PFNGLVERTEXATTRIB1FVARBPROC __glewVertexAttrib1fvARB = NULL; +PFNGLVERTEXATTRIB1SARBPROC __glewVertexAttrib1sARB = NULL; +PFNGLVERTEXATTRIB1SVARBPROC __glewVertexAttrib1svARB = NULL; +PFNGLVERTEXATTRIB2DARBPROC __glewVertexAttrib2dARB = NULL; +PFNGLVERTEXATTRIB2DVARBPROC __glewVertexAttrib2dvARB = NULL; +PFNGLVERTEXATTRIB2FARBPROC __glewVertexAttrib2fARB = NULL; +PFNGLVERTEXATTRIB2FVARBPROC __glewVertexAttrib2fvARB = NULL; +PFNGLVERTEXATTRIB2SARBPROC __glewVertexAttrib2sARB = NULL; +PFNGLVERTEXATTRIB2SVARBPROC __glewVertexAttrib2svARB = NULL; +PFNGLVERTEXATTRIB3DARBPROC __glewVertexAttrib3dARB = NULL; +PFNGLVERTEXATTRIB3DVARBPROC __glewVertexAttrib3dvARB = NULL; +PFNGLVERTEXATTRIB3FARBPROC __glewVertexAttrib3fARB = NULL; +PFNGLVERTEXATTRIB3FVARBPROC __glewVertexAttrib3fvARB = NULL; +PFNGLVERTEXATTRIB3SARBPROC __glewVertexAttrib3sARB = NULL; +PFNGLVERTEXATTRIB3SVARBPROC __glewVertexAttrib3svARB = NULL; +PFNGLVERTEXATTRIB4NBVARBPROC __glewVertexAttrib4NbvARB = NULL; +PFNGLVERTEXATTRIB4NIVARBPROC __glewVertexAttrib4NivARB = NULL; +PFNGLVERTEXATTRIB4NSVARBPROC __glewVertexAttrib4NsvARB = NULL; +PFNGLVERTEXATTRIB4NUBARBPROC __glewVertexAttrib4NubARB = NULL; +PFNGLVERTEXATTRIB4NUBVARBPROC __glewVertexAttrib4NubvARB = NULL; +PFNGLVERTEXATTRIB4NUIVARBPROC __glewVertexAttrib4NuivARB = NULL; +PFNGLVERTEXATTRIB4NUSVARBPROC __glewVertexAttrib4NusvARB = NULL; +PFNGLVERTEXATTRIB4BVARBPROC __glewVertexAttrib4bvARB = NULL; +PFNGLVERTEXATTRIB4DARBPROC __glewVertexAttrib4dARB = NULL; +PFNGLVERTEXATTRIB4DVARBPROC __glewVertexAttrib4dvARB = NULL; +PFNGLVERTEXATTRIB4FARBPROC __glewVertexAttrib4fARB = NULL; +PFNGLVERTEXATTRIB4FVARBPROC __glewVertexAttrib4fvARB = NULL; +PFNGLVERTEXATTRIB4IVARBPROC __glewVertexAttrib4ivARB = NULL; +PFNGLVERTEXATTRIB4SARBPROC __glewVertexAttrib4sARB = NULL; +PFNGLVERTEXATTRIB4SVARBPROC __glewVertexAttrib4svARB = NULL; +PFNGLVERTEXATTRIB4UBVARBPROC __glewVertexAttrib4ubvARB = NULL; +PFNGLVERTEXATTRIB4UIVARBPROC __glewVertexAttrib4uivARB = NULL; +PFNGLVERTEXATTRIB4USVARBPROC __glewVertexAttrib4usvARB = NULL; +PFNGLVERTEXATTRIBPOINTERARBPROC __glewVertexAttribPointerARB = NULL; + +PFNGLBINDATTRIBLOCATIONARBPROC __glewBindAttribLocationARB = NULL; +PFNGLGETACTIVEATTRIBARBPROC __glewGetActiveAttribARB = NULL; +PFNGLGETATTRIBLOCATIONARBPROC __glewGetAttribLocationARB = NULL; + +PFNGLWINDOWPOS2DARBPROC __glewWindowPos2dARB = NULL; +PFNGLWINDOWPOS2DVARBPROC __glewWindowPos2dvARB = NULL; +PFNGLWINDOWPOS2FARBPROC __glewWindowPos2fARB = NULL; +PFNGLWINDOWPOS2FVARBPROC __glewWindowPos2fvARB = NULL; +PFNGLWINDOWPOS2IARBPROC __glewWindowPos2iARB = NULL; +PFNGLWINDOWPOS2IVARBPROC __glewWindowPos2ivARB = NULL; +PFNGLWINDOWPOS2SARBPROC __glewWindowPos2sARB = NULL; +PFNGLWINDOWPOS2SVARBPROC __glewWindowPos2svARB = NULL; +PFNGLWINDOWPOS3DARBPROC __glewWindowPos3dARB = NULL; +PFNGLWINDOWPOS3DVARBPROC __glewWindowPos3dvARB = NULL; +PFNGLWINDOWPOS3FARBPROC __glewWindowPos3fARB = NULL; +PFNGLWINDOWPOS3FVARBPROC __glewWindowPos3fvARB = NULL; +PFNGLWINDOWPOS3IARBPROC __glewWindowPos3iARB = NULL; +PFNGLWINDOWPOS3IVARBPROC __glewWindowPos3ivARB = NULL; +PFNGLWINDOWPOS3SARBPROC __glewWindowPos3sARB = NULL; +PFNGLWINDOWPOS3SVARBPROC __glewWindowPos3svARB = NULL; + +PFNGLDRAWBUFFERSATIPROC __glewDrawBuffersATI = NULL; + +PFNGLDRAWELEMENTARRAYATIPROC __glewDrawElementArrayATI = NULL; +PFNGLDRAWRANGEELEMENTARRAYATIPROC __glewDrawRangeElementArrayATI = NULL; +PFNGLELEMENTPOINTERATIPROC __glewElementPointerATI = NULL; + +PFNGLGETTEXBUMPPARAMETERFVATIPROC __glewGetTexBumpParameterfvATI = NULL; +PFNGLGETTEXBUMPPARAMETERIVATIPROC __glewGetTexBumpParameterivATI = NULL; +PFNGLTEXBUMPPARAMETERFVATIPROC __glewTexBumpParameterfvATI = NULL; +PFNGLTEXBUMPPARAMETERIVATIPROC __glewTexBumpParameterivATI = NULL; + +PFNGLALPHAFRAGMENTOP1ATIPROC __glewAlphaFragmentOp1ATI = NULL; +PFNGLALPHAFRAGMENTOP2ATIPROC __glewAlphaFragmentOp2ATI = NULL; +PFNGLALPHAFRAGMENTOP3ATIPROC __glewAlphaFragmentOp3ATI = NULL; +PFNGLBEGINFRAGMENTSHADERATIPROC __glewBeginFragmentShaderATI = NULL; +PFNGLBINDFRAGMENTSHADERATIPROC __glewBindFragmentShaderATI = NULL; +PFNGLCOLORFRAGMENTOP1ATIPROC __glewColorFragmentOp1ATI = NULL; +PFNGLCOLORFRAGMENTOP2ATIPROC __glewColorFragmentOp2ATI = NULL; +PFNGLCOLORFRAGMENTOP3ATIPROC __glewColorFragmentOp3ATI = NULL; +PFNGLDELETEFRAGMENTSHADERATIPROC __glewDeleteFragmentShaderATI = NULL; +PFNGLENDFRAGMENTSHADERATIPROC __glewEndFragmentShaderATI = NULL; +PFNGLGENFRAGMENTSHADERSATIPROC __glewGenFragmentShadersATI = NULL; +PFNGLPASSTEXCOORDATIPROC __glewPassTexCoordATI = NULL; +PFNGLSAMPLEMAPATIPROC __glewSampleMapATI = NULL; +PFNGLSETFRAGMENTSHADERCONSTANTATIPROC __glewSetFragmentShaderConstantATI = NULL; + +PFNGLMAPOBJECTBUFFERATIPROC __glewMapObjectBufferATI = NULL; +PFNGLUNMAPOBJECTBUFFERATIPROC __glewUnmapObjectBufferATI = NULL; + +PFNGLPNTRIANGLESFATIPROC __glPNTrianglewesfATI = NULL; +PFNGLPNTRIANGLESIATIPROC __glPNTrianglewesiATI = NULL; + +PFNGLSTENCILFUNCSEPARATEATIPROC __glewStencilFuncSeparateATI = NULL; +PFNGLSTENCILOPSEPARATEATIPROC __glewStencilOpSeparateATI = NULL; + +PFNGLARRAYOBJECTATIPROC __glewArrayObjectATI = NULL; +PFNGLFREEOBJECTBUFFERATIPROC __glewFreeObjectBufferATI = NULL; +PFNGLGETARRAYOBJECTFVATIPROC __glewGetArrayObjectfvATI = NULL; +PFNGLGETARRAYOBJECTIVATIPROC __glewGetArrayObjectivATI = NULL; +PFNGLGETOBJECTBUFFERFVATIPROC __glewGetObjectBufferfvATI = NULL; +PFNGLGETOBJECTBUFFERIVATIPROC __glewGetObjectBufferivATI = NULL; +PFNGLGETVARIANTARRAYOBJECTFVATIPROC __glewGetVariantArrayObjectfvATI = NULL; +PFNGLGETVARIANTARRAYOBJECTIVATIPROC __glewGetVariantArrayObjectivATI = NULL; +PFNGLISOBJECTBUFFERATIPROC __glewIsObjectBufferATI = NULL; +PFNGLNEWOBJECTBUFFERATIPROC __glewNewObjectBufferATI = NULL; +PFNGLUPDATEOBJECTBUFFERATIPROC __glewUpdateObjectBufferATI = NULL; +PFNGLVARIANTARRAYOBJECTATIPROC __glewVariantArrayObjectATI = NULL; + +PFNGLGETVERTEXATTRIBARRAYOBJECTFVATIPROC __glewGetVertexAttribArrayObjectfvATI = NULL; +PFNGLGETVERTEXATTRIBARRAYOBJECTIVATIPROC __glewGetVertexAttribArrayObjectivATI = NULL; +PFNGLVERTEXATTRIBARRAYOBJECTATIPROC __glewVertexAttribArrayObjectATI = NULL; + +PFNGLCLIENTACTIVEVERTEXSTREAMATIPROC __glewClientActiveVertexStreamATI = NULL; +PFNGLNORMALSTREAM3BATIPROC __glewNormalStream3bATI = NULL; +PFNGLNORMALSTREAM3BVATIPROC __glewNormalStream3bvATI = NULL; +PFNGLNORMALSTREAM3DATIPROC __glewNormalStream3dATI = NULL; +PFNGLNORMALSTREAM3DVATIPROC __glewNormalStream3dvATI = NULL; +PFNGLNORMALSTREAM3FATIPROC __glewNormalStream3fATI = NULL; +PFNGLNORMALSTREAM3FVATIPROC __glewNormalStream3fvATI = NULL; +PFNGLNORMALSTREAM3IATIPROC __glewNormalStream3iATI = NULL; +PFNGLNORMALSTREAM3IVATIPROC __glewNormalStream3ivATI = NULL; +PFNGLNORMALSTREAM3SATIPROC __glewNormalStream3sATI = NULL; +PFNGLNORMALSTREAM3SVATIPROC __glewNormalStream3svATI = NULL; +PFNGLVERTEXBLENDENVFATIPROC __glewVertexBlendEnvfATI = NULL; +PFNGLVERTEXBLENDENVIATIPROC __glewVertexBlendEnviATI = NULL; +PFNGLVERTEXSTREAM2DATIPROC __glewVertexStream2dATI = NULL; +PFNGLVERTEXSTREAM2DVATIPROC __glewVertexStream2dvATI = NULL; +PFNGLVERTEXSTREAM2FATIPROC __glewVertexStream2fATI = NULL; +PFNGLVERTEXSTREAM2FVATIPROC __glewVertexStream2fvATI = NULL; +PFNGLVERTEXSTREAM2IATIPROC __glewVertexStream2iATI = NULL; +PFNGLVERTEXSTREAM2IVATIPROC __glewVertexStream2ivATI = NULL; +PFNGLVERTEXSTREAM2SATIPROC __glewVertexStream2sATI = NULL; +PFNGLVERTEXSTREAM2SVATIPROC __glewVertexStream2svATI = NULL; +PFNGLVERTEXSTREAM3DATIPROC __glewVertexStream3dATI = NULL; +PFNGLVERTEXSTREAM3DVATIPROC __glewVertexStream3dvATI = NULL; +PFNGLVERTEXSTREAM3FATIPROC __glewVertexStream3fATI = NULL; +PFNGLVERTEXSTREAM3FVATIPROC __glewVertexStream3fvATI = NULL; +PFNGLVERTEXSTREAM3IATIPROC __glewVertexStream3iATI = NULL; +PFNGLVERTEXSTREAM3IVATIPROC __glewVertexStream3ivATI = NULL; +PFNGLVERTEXSTREAM3SATIPROC __glewVertexStream3sATI = NULL; +PFNGLVERTEXSTREAM3SVATIPROC __glewVertexStream3svATI = NULL; +PFNGLVERTEXSTREAM4DATIPROC __glewVertexStream4dATI = NULL; +PFNGLVERTEXSTREAM4DVATIPROC __glewVertexStream4dvATI = NULL; +PFNGLVERTEXSTREAM4FATIPROC __glewVertexStream4fATI = NULL; +PFNGLVERTEXSTREAM4FVATIPROC __glewVertexStream4fvATI = NULL; +PFNGLVERTEXSTREAM4IATIPROC __glewVertexStream4iATI = NULL; +PFNGLVERTEXSTREAM4IVATIPROC __glewVertexStream4ivATI = NULL; +PFNGLVERTEXSTREAM4SATIPROC __glewVertexStream4sATI = NULL; +PFNGLVERTEXSTREAM4SVATIPROC __glewVertexStream4svATI = NULL; + +PFNGLBLENDCOLOREXTPROC __glewBlendColorEXT = NULL; + +PFNGLBLENDEQUATIONSEPARATEEXTPROC __glewBlendEquationSeparateEXT = NULL; + +PFNGLBLENDFUNCSEPARATEEXTPROC __glewBlendFuncSeparateEXT = NULL; + +PFNGLBLENDEQUATIONEXTPROC __glewBlendEquationEXT = NULL; + +PFNGLCOLORSUBTABLEEXTPROC __glewColorSubTableEXT = NULL; +PFNGLCOPYCOLORSUBTABLEEXTPROC __glewCopyColorSubTableEXT = NULL; + +PFNGLLOCKARRAYSEXTPROC __glewLockArraysEXT = NULL; +PFNGLUNLOCKARRAYSEXTPROC __glewUnlockArraysEXT = NULL; + +PFNGLCONVOLUTIONFILTER1DEXTPROC __glewConvolutionFilter1DEXT = NULL; +PFNGLCONVOLUTIONFILTER2DEXTPROC __glewConvolutionFilter2DEXT = NULL; +PFNGLCONVOLUTIONPARAMETERFEXTPROC __glewConvolutionParameterfEXT = NULL; +PFNGLCONVOLUTIONPARAMETERFVEXTPROC __glewConvolutionParameterfvEXT = NULL; +PFNGLCONVOLUTIONPARAMETERIEXTPROC __glewConvolutionParameteriEXT = NULL; +PFNGLCONVOLUTIONPARAMETERIVEXTPROC __glewConvolutionParameterivEXT = NULL; +PFNGLCOPYCONVOLUTIONFILTER1DEXTPROC __glewCopyConvolutionFilter1DEXT = NULL; +PFNGLCOPYCONVOLUTIONFILTER2DEXTPROC __glewCopyConvolutionFilter2DEXT = NULL; +PFNGLGETCONVOLUTIONFILTEREXTPROC __glewGetConvolutionFilterEXT = NULL; +PFNGLGETCONVOLUTIONPARAMETERFVEXTPROC __glewGetConvolutionParameterfvEXT = NULL; +PFNGLGETCONVOLUTIONPARAMETERIVEXTPROC __glewGetConvolutionParameterivEXT = NULL; +PFNGLGETSEPARABLEFILTEREXTPROC __glewGetSeparableFilterEXT = NULL; +PFNGLSEPARABLEFILTER2DEXTPROC __glewSeparableFilter2DEXT = NULL; + +PFNGLBINORMALPOINTEREXTPROC __glewBinormalPointerEXT = NULL; +PFNGLTANGENTPOINTEREXTPROC __glewTangentPointerEXT = NULL; + +PFNGLCOPYTEXIMAGE1DEXTPROC __glewCopyTexImage1DEXT = NULL; +PFNGLCOPYTEXIMAGE2DEXTPROC __glewCopyTexImage2DEXT = NULL; +PFNGLCOPYTEXSUBIMAGE1DEXTPROC __glewCopyTexSubImage1DEXT = NULL; +PFNGLCOPYTEXSUBIMAGE2DEXTPROC __glewCopyTexSubImage2DEXT = NULL; +PFNGLCOPYTEXSUBIMAGE3DEXTPROC __glewCopyTexSubImage3DEXT = NULL; + +PFNGLCULLPARAMETERDVEXTPROC __glewCullParameterdvEXT = NULL; +PFNGLCULLPARAMETERFVEXTPROC __glewCullParameterfvEXT = NULL; + +PFNGLDEPTHBOUNDSEXTPROC __glewDepthBoundsEXT = NULL; + +PFNGLDRAWRANGEELEMENTSEXTPROC __glewDrawRangeElementsEXT = NULL; + +PFNGLFOGCOORDPOINTEREXTPROC __glewFogCoordPointerEXT = NULL; +PFNGLFOGCOORDDEXTPROC __glewFogCoorddEXT = NULL; +PFNGLFOGCOORDDVEXTPROC __glewFogCoorddvEXT = NULL; +PFNGLFOGCOORDFEXTPROC __glewFogCoordfEXT = NULL; +PFNGLFOGCOORDFVEXTPROC __glewFogCoordfvEXT = NULL; + +PFNGLFRAGMENTCOLORMATERIALEXTPROC __glewFragmentColorMaterialEXT = NULL; +PFNGLFRAGMENTLIGHTMODELFEXTPROC __glewFragmentLightModelfEXT = NULL; +PFNGLFRAGMENTLIGHTMODELFVEXTPROC __glewFragmentLightModelfvEXT = NULL; +PFNGLFRAGMENTLIGHTMODELIEXTPROC __glewFragmentLightModeliEXT = NULL; +PFNGLFRAGMENTLIGHTMODELIVEXTPROC __glewFragmentLightModelivEXT = NULL; +PFNGLFRAGMENTLIGHTFEXTPROC __glewFragmentLightfEXT = NULL; +PFNGLFRAGMENTLIGHTFVEXTPROC __glewFragmentLightfvEXT = NULL; +PFNGLFRAGMENTLIGHTIEXTPROC __glewFragmentLightiEXT = NULL; +PFNGLFRAGMENTLIGHTIVEXTPROC __glewFragmentLightivEXT = NULL; +PFNGLFRAGMENTMATERIALFEXTPROC __glewFragmentMaterialfEXT = NULL; +PFNGLFRAGMENTMATERIALFVEXTPROC __glewFragmentMaterialfvEXT = NULL; +PFNGLFRAGMENTMATERIALIEXTPROC __glewFragmentMaterialiEXT = NULL; +PFNGLFRAGMENTMATERIALIVEXTPROC __glewFragmentMaterialivEXT = NULL; +PFNGLGETFRAGMENTLIGHTFVEXTPROC __glewGetFragmentLightfvEXT = NULL; +PFNGLGETFRAGMENTLIGHTIVEXTPROC __glewGetFragmentLightivEXT = NULL; +PFNGLGETFRAGMENTMATERIALFVEXTPROC __glewGetFragmentMaterialfvEXT = NULL; +PFNGLGETFRAGMENTMATERIALIVEXTPROC __glewGetFragmentMaterialivEXT = NULL; +PFNGLLIGHTENVIEXTPROC __glewLightEnviEXT = NULL; + +PFNGLBLITFRAMEBUFFEREXTPROC __glewBlitFramebufferEXT = NULL; + +PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC __glewRenderbufferStorageMultisampleEXT = NULL; + +PFNGLBINDFRAMEBUFFEREXTPROC __glewBindFramebufferEXT = NULL; +PFNGLBINDRENDERBUFFEREXTPROC __glewBindRenderbufferEXT = NULL; +PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC __glewCheckFramebufferStatusEXT = NULL; +PFNGLDELETEFRAMEBUFFERSEXTPROC __glewDeleteFramebuffersEXT = NULL; +PFNGLDELETERENDERBUFFERSEXTPROC __glewDeleteRenderbuffersEXT = NULL; +PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC __glewFramebufferRenderbufferEXT = NULL; +PFNGLFRAMEBUFFERTEXTURE1DEXTPROC __glewFramebufferTexture1DEXT = NULL; +PFNGLFRAMEBUFFERTEXTURE2DEXTPROC __glewFramebufferTexture2DEXT = NULL; +PFNGLFRAMEBUFFERTEXTURE3DEXTPROC __glewFramebufferTexture3DEXT = NULL; +PFNGLGENFRAMEBUFFERSEXTPROC __glewGenFramebuffersEXT = NULL; +PFNGLGENRENDERBUFFERSEXTPROC __glewGenRenderbuffersEXT = NULL; +PFNGLGENERATEMIPMAPEXTPROC __glewGenerateMipmapEXT = NULL; +PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC __glewGetFramebufferAttachmentParameterivEXT = NULL; +PFNGLGETRENDERBUFFERPARAMETERIVEXTPROC __glewGetRenderbufferParameterivEXT = NULL; +PFNGLISFRAMEBUFFEREXTPROC __glewIsFramebufferEXT = NULL; +PFNGLISRENDERBUFFEREXTPROC __glewIsRenderbufferEXT = NULL; +PFNGLRENDERBUFFERSTORAGEEXTPROC __glewRenderbufferStorageEXT = NULL; + +PFNGLGETHISTOGRAMEXTPROC __glewGetHistogramEXT = NULL; +PFNGLGETHISTOGRAMPARAMETERFVEXTPROC __glewGetHistogramParameterfvEXT = NULL; +PFNGLGETHISTOGRAMPARAMETERIVEXTPROC __glewGetHistogramParameterivEXT = NULL; +PFNGLGETMINMAXEXTPROC __glewGetMinmaxEXT = NULL; +PFNGLGETMINMAXPARAMETERFVEXTPROC __glewGetMinmaxParameterfvEXT = NULL; +PFNGLGETMINMAXPARAMETERIVEXTPROC __glewGetMinmaxParameterivEXT = NULL; +PFNGLHISTOGRAMEXTPROC __glewHistogramEXT = NULL; +PFNGLMINMAXEXTPROC __glewMinmaxEXT = NULL; +PFNGLRESETHISTOGRAMEXTPROC __glewResetHistogramEXT = NULL; +PFNGLRESETMINMAXEXTPROC __glewResetMinmaxEXT = NULL; + +PFNGLINDEXFUNCEXTPROC __glewIndexFuncEXT = NULL; + +PFNGLINDEXMATERIALEXTPROC __glewIndexMaterialEXT = NULL; + +PFNGLAPPLYTEXTUREEXTPROC __glewApplyTextureEXT = NULL; +PFNGLTEXTURELIGHTEXTPROC __glewTextureLightEXT = NULL; +PFNGLTEXTUREMATERIALEXTPROC __glewTextureMaterialEXT = NULL; + +PFNGLMULTIDRAWARRAYSEXTPROC __glewMultiDrawArraysEXT = NULL; +PFNGLMULTIDRAWELEMENTSEXTPROC __glewMultiDrawElementsEXT = NULL; + +PFNGLSAMPLEMASKEXTPROC __glewSampleMaskEXT = NULL; +PFNGLSAMPLEPATTERNEXTPROC __glewSamplePatternEXT = NULL; + +PFNGLCOLORTABLEEXTPROC __glewColorTableEXT = NULL; +PFNGLGETCOLORTABLEEXTPROC __glewGetColorTableEXT = NULL; +PFNGLGETCOLORTABLEPARAMETERFVEXTPROC __glewGetColorTableParameterfvEXT = NULL; +PFNGLGETCOLORTABLEPARAMETERIVEXTPROC __glewGetColorTableParameterivEXT = NULL; + +PFNGLGETPIXELTRANSFORMPARAMETERFVEXTPROC __glewGetPixelTransformParameterfvEXT = NULL; +PFNGLGETPIXELTRANSFORMPARAMETERIVEXTPROC __glewGetPixelTransformParameterivEXT = NULL; +PFNGLPIXELTRANSFORMPARAMETERFEXTPROC __glewPixelTransformParameterfEXT = NULL; +PFNGLPIXELTRANSFORMPARAMETERFVEXTPROC __glewPixelTransformParameterfvEXT = NULL; +PFNGLPIXELTRANSFORMPARAMETERIEXTPROC __glewPixelTransformParameteriEXT = NULL; +PFNGLPIXELTRANSFORMPARAMETERIVEXTPROC __glewPixelTransformParameterivEXT = NULL; + +PFNGLPOINTPARAMETERFEXTPROC __glewPointParameterfEXT = NULL; +PFNGLPOINTPARAMETERFVEXTPROC __glewPointParameterfvEXT = NULL; + +PFNGLPOLYGONOFFSETEXTPROC __glewPolygonOffsetEXT = NULL; + +PFNGLBEGINSCENEEXTPROC __glewBeginSceneEXT = NULL; +PFNGLENDSCENEEXTPROC __glewEndSceneEXT = NULL; + +PFNGLSECONDARYCOLOR3BEXTPROC __glewSecondaryColor3bEXT = NULL; +PFNGLSECONDARYCOLOR3BVEXTPROC __glewSecondaryColor3bvEXT = NULL; +PFNGLSECONDARYCOLOR3DEXTPROC __glewSecondaryColor3dEXT = NULL; +PFNGLSECONDARYCOLOR3DVEXTPROC __glewSecondaryColor3dvEXT = NULL; +PFNGLSECONDARYCOLOR3FEXTPROC __glewSecondaryColor3fEXT = NULL; +PFNGLSECONDARYCOLOR3FVEXTPROC __glewSecondaryColor3fvEXT = NULL; +PFNGLSECONDARYCOLOR3IEXTPROC __glewSecondaryColor3iEXT = NULL; +PFNGLSECONDARYCOLOR3IVEXTPROC __glewSecondaryColor3ivEXT = NULL; +PFNGLSECONDARYCOLOR3SEXTPROC __glewSecondaryColor3sEXT = NULL; +PFNGLSECONDARYCOLOR3SVEXTPROC __glewSecondaryColor3svEXT = NULL; +PFNGLSECONDARYCOLOR3UBEXTPROC __glewSecondaryColor3ubEXT = NULL; +PFNGLSECONDARYCOLOR3UBVEXTPROC __glewSecondaryColor3ubvEXT = NULL; +PFNGLSECONDARYCOLOR3UIEXTPROC __glewSecondaryColor3uiEXT = NULL; +PFNGLSECONDARYCOLOR3UIVEXTPROC __glewSecondaryColor3uivEXT = NULL; +PFNGLSECONDARYCOLOR3USEXTPROC __glewSecondaryColor3usEXT = NULL; +PFNGLSECONDARYCOLOR3USVEXTPROC __glewSecondaryColor3usvEXT = NULL; +PFNGLSECONDARYCOLORPOINTEREXTPROC __glewSecondaryColorPointerEXT = NULL; + +PFNGLACTIVESTENCILFACEEXTPROC __glewActiveStencilFaceEXT = NULL; + +PFNGLTEXSUBIMAGE1DEXTPROC __glewTexSubImage1DEXT = NULL; +PFNGLTEXSUBIMAGE2DEXTPROC __glewTexSubImage2DEXT = NULL; +PFNGLTEXSUBIMAGE3DEXTPROC __glewTexSubImage3DEXT = NULL; + +PFNGLTEXIMAGE3DEXTPROC __glewTexImage3DEXT = NULL; + +PFNGLARETEXTURESRESIDENTEXTPROC __glewAreTexturesResidentEXT = NULL; +PFNGLBINDTEXTUREEXTPROC __glewBindTextureEXT = NULL; +PFNGLDELETETEXTURESEXTPROC __glewDeleteTexturesEXT = NULL; +PFNGLGENTEXTURESEXTPROC __glewGenTexturesEXT = NULL; +PFNGLISTEXTUREEXTPROC __glewIsTextureEXT = NULL; +PFNGLPRIORITIZETEXTURESEXTPROC __glewPrioritizeTexturesEXT = NULL; + +PFNGLTEXTURENORMALEXTPROC __glewTextureNormalEXT = NULL; + +PFNGLARRAYELEMENTEXTPROC __glewArrayElementEXT = NULL; +PFNGLCOLORPOINTEREXTPROC __glewColorPointerEXT = NULL; +PFNGLDRAWARRAYSEXTPROC __glewDrawArraysEXT = NULL; +PFNGLEDGEFLAGPOINTEREXTPROC __glewEdgeFlagPointerEXT = NULL; +PFNGLGETPOINTERVEXTPROC __glewGetPointervEXT = NULL; +PFNGLINDEXPOINTEREXTPROC __glewIndexPointerEXT = NULL; +PFNGLNORMALPOINTEREXTPROC __glewNormalPointerEXT = NULL; +PFNGLTEXCOORDPOINTEREXTPROC __glewTexCoordPointerEXT = NULL; +PFNGLVERTEXPOINTEREXTPROC __glewVertexPointerEXT = NULL; + +PFNGLBEGINVERTEXSHADEREXTPROC __glewBeginVertexShaderEXT = NULL; +PFNGLBINDLIGHTPARAMETEREXTPROC __glewBindLightParameterEXT = NULL; +PFNGLBINDMATERIALPARAMETEREXTPROC __glewBindMaterialParameterEXT = NULL; +PFNGLBINDPARAMETEREXTPROC __glewBindParameterEXT = NULL; +PFNGLBINDTEXGENPARAMETEREXTPROC __glewBindTexGenParameterEXT = NULL; +PFNGLBINDTEXTUREUNITPARAMETEREXTPROC __glewBindTextureUnitParameterEXT = NULL; +PFNGLBINDVERTEXSHADEREXTPROC __glewBindVertexShaderEXT = NULL; +PFNGLDELETEVERTEXSHADEREXTPROC __glewDeleteVertexShaderEXT = NULL; +PFNGLDISABLEVARIANTCLIENTSTATEEXTPROC __glewDisableVariantClientStateEXT = NULL; +PFNGLENABLEVARIANTCLIENTSTATEEXTPROC __glewEnableVariantClientStateEXT = NULL; +PFNGLENDVERTEXSHADEREXTPROC __glewEndVertexShaderEXT = NULL; +PFNGLEXTRACTCOMPONENTEXTPROC __glewExtractComponentEXT = NULL; +PFNGLGENSYMBOLSEXTPROC __glewGenSymbolsEXT = NULL; +PFNGLGENVERTEXSHADERSEXTPROC __glewGenVertexShadersEXT = NULL; +PFNGLGETINVARIANTBOOLEANVEXTPROC __glewGetInvariantBooleanvEXT = NULL; +PFNGLGETINVARIANTFLOATVEXTPROC __glewGetInvariantFloatvEXT = NULL; +PFNGLGETINVARIANTINTEGERVEXTPROC __glewGetInvariantIntegervEXT = NULL; +PFNGLGETLOCALCONSTANTBOOLEANVEXTPROC __glewGetLocalConstantBooleanvEXT = NULL; +PFNGLGETLOCALCONSTANTFLOATVEXTPROC __glewGetLocalConstantFloatvEXT = NULL; +PFNGLGETLOCALCONSTANTINTEGERVEXTPROC __glewGetLocalConstantIntegervEXT = NULL; +PFNGLGETVARIANTBOOLEANVEXTPROC __glewGetVariantBooleanvEXT = NULL; +PFNGLGETVARIANTFLOATVEXTPROC __glewGetVariantFloatvEXT = NULL; +PFNGLGETVARIANTINTEGERVEXTPROC __glewGetVariantIntegervEXT = NULL; +PFNGLGETVARIANTPOINTERVEXTPROC __glewGetVariantPointervEXT = NULL; +PFNGLINSERTCOMPONENTEXTPROC __glewInsertComponentEXT = NULL; +PFNGLISVARIANTENABLEDEXTPROC __glewIsVariantEnabledEXT = NULL; +PFNGLSETINVARIANTEXTPROC __glewSetInvariantEXT = NULL; +PFNGLSETLOCALCONSTANTEXTPROC __glewSetLocalConstantEXT = NULL; +PFNGLSHADEROP1EXTPROC __glewShaderOp1EXT = NULL; +PFNGLSHADEROP2EXTPROC __glewShaderOp2EXT = NULL; +PFNGLSHADEROP3EXTPROC __glewShaderOp3EXT = NULL; +PFNGLSWIZZLEEXTPROC __glewSwizzleEXT = NULL; +PFNGLVARIANTPOINTEREXTPROC __glewVariantPointerEXT = NULL; +PFNGLVARIANTBVEXTPROC __glewVariantbvEXT = NULL; +PFNGLVARIANTDVEXTPROC __glewVariantdvEXT = NULL; +PFNGLVARIANTFVEXTPROC __glewVariantfvEXT = NULL; +PFNGLVARIANTIVEXTPROC __glewVariantivEXT = NULL; +PFNGLVARIANTSVEXTPROC __glewVariantsvEXT = NULL; +PFNGLVARIANTUBVEXTPROC __glewVariantubvEXT = NULL; +PFNGLVARIANTUIVEXTPROC __glewVariantuivEXT = NULL; +PFNGLVARIANTUSVEXTPROC __glewVariantusvEXT = NULL; +PFNGLWRITEMASKEXTPROC __glewWriteMaskEXT = NULL; + +PFNGLVERTEXWEIGHTPOINTEREXTPROC __glewVertexWeightPointerEXT = NULL; +PFNGLVERTEXWEIGHTFEXTPROC __glewVertexWeightfEXT = NULL; +PFNGLVERTEXWEIGHTFVEXTPROC __glewVertexWeightfvEXT = NULL; + +PFNGLSTRINGMARKERGREMEDYPROC __glewStringMarkerGREMEDY = NULL; + +PFNGLGETIMAGETRANSFORMPARAMETERFVHPPROC __glewGetImageTransformParameterfvHP = NULL; +PFNGLGETIMAGETRANSFORMPARAMETERIVHPPROC __glewGetImageTransformParameterivHP = NULL; +PFNGLIMAGETRANSFORMPARAMETERFHPPROC __glewImageTransformParameterfHP = NULL; +PFNGLIMAGETRANSFORMPARAMETERFVHPPROC __glewImageTransformParameterfvHP = NULL; +PFNGLIMAGETRANSFORMPARAMETERIHPPROC __glewImageTransformParameteriHP = NULL; +PFNGLIMAGETRANSFORMPARAMETERIVHPPROC __glewImageTransformParameterivHP = NULL; + +PFNGLMULTIMODEDRAWARRAYSIBMPROC __glewMultiModeDrawArraysIBM = NULL; +PFNGLMULTIMODEDRAWELEMENTSIBMPROC __glewMultiModeDrawElementsIBM = NULL; + +PFNGLCOLORPOINTERLISTIBMPROC __glewColorPointerListIBM = NULL; +PFNGLEDGEFLAGPOINTERLISTIBMPROC __glewEdgeFlagPointerListIBM = NULL; +PFNGLFOGCOORDPOINTERLISTIBMPROC __glewFogCoordPointerListIBM = NULL; +PFNGLINDEXPOINTERLISTIBMPROC __glewIndexPointerListIBM = NULL; +PFNGLNORMALPOINTERLISTIBMPROC __glewNormalPointerListIBM = NULL; +PFNGLSECONDARYCOLORPOINTERLISTIBMPROC __glewSecondaryColorPointerListIBM = NULL; +PFNGLTEXCOORDPOINTERLISTIBMPROC __glewTexCoordPointerListIBM = NULL; +PFNGLVERTEXPOINTERLISTIBMPROC __glewVertexPointerListIBM = NULL; + +PFNGLCOLORPOINTERVINTELPROC __glewColorPointervINTEL = NULL; +PFNGLNORMALPOINTERVINTELPROC __glewNormalPointervINTEL = NULL; +PFNGLTEXCOORDPOINTERVINTELPROC __glewTexCoordPointervINTEL = NULL; +PFNGLVERTEXPOINTERVINTELPROC __glewVertexPointervINTEL = NULL; + +PFNGLTEXSCISSORFUNCINTELPROC __glewTexScissorFuncINTEL = NULL; +PFNGLTEXSCISSORINTELPROC __glewTexScissorINTEL = NULL; + +PFNGLBUFFERREGIONENABLEDEXTPROC __glewBufferRegionEnabledEXT = NULL; +PFNGLDELETEBUFFERREGIONEXTPROC __glewDeleteBufferRegionEXT = NULL; +PFNGLDRAWBUFFERREGIONEXTPROC __glewDrawBufferRegionEXT = NULL; +PFNGLNEWBUFFERREGIONEXTPROC __glewNewBufferRegionEXT = NULL; +PFNGLREADBUFFERREGIONEXTPROC __glewReadBufferRegionEXT = NULL; + +PFNGLRESIZEBUFFERSMESAPROC __glewResizeBuffersMESA = NULL; + +PFNGLWINDOWPOS2DMESAPROC __glewWindowPos2dMESA = NULL; +PFNGLWINDOWPOS2DVMESAPROC __glewWindowPos2dvMESA = NULL; +PFNGLWINDOWPOS2FMESAPROC __glewWindowPos2fMESA = NULL; +PFNGLWINDOWPOS2FVMESAPROC __glewWindowPos2fvMESA = NULL; +PFNGLWINDOWPOS2IMESAPROC __glewWindowPos2iMESA = NULL; +PFNGLWINDOWPOS2IVMESAPROC __glewWindowPos2ivMESA = NULL; +PFNGLWINDOWPOS2SMESAPROC __glewWindowPos2sMESA = NULL; +PFNGLWINDOWPOS2SVMESAPROC __glewWindowPos2svMESA = NULL; +PFNGLWINDOWPOS3DMESAPROC __glewWindowPos3dMESA = NULL; +PFNGLWINDOWPOS3DVMESAPROC __glewWindowPos3dvMESA = NULL; +PFNGLWINDOWPOS3FMESAPROC __glewWindowPos3fMESA = NULL; +PFNGLWINDOWPOS3FVMESAPROC __glewWindowPos3fvMESA = NULL; +PFNGLWINDOWPOS3IMESAPROC __glewWindowPos3iMESA = NULL; +PFNGLWINDOWPOS3IVMESAPROC __glewWindowPos3ivMESA = NULL; +PFNGLWINDOWPOS3SMESAPROC __glewWindowPos3sMESA = NULL; +PFNGLWINDOWPOS3SVMESAPROC __glewWindowPos3svMESA = NULL; +PFNGLWINDOWPOS4DMESAPROC __glewWindowPos4dMESA = NULL; +PFNGLWINDOWPOS4DVMESAPROC __glewWindowPos4dvMESA = NULL; +PFNGLWINDOWPOS4FMESAPROC __glewWindowPos4fMESA = NULL; +PFNGLWINDOWPOS4FVMESAPROC __glewWindowPos4fvMESA = NULL; +PFNGLWINDOWPOS4IMESAPROC __glewWindowPos4iMESA = NULL; +PFNGLWINDOWPOS4IVMESAPROC __glewWindowPos4ivMESA = NULL; +PFNGLWINDOWPOS4SMESAPROC __glewWindowPos4sMESA = NULL; +PFNGLWINDOWPOS4SVMESAPROC __glewWindowPos4svMESA = NULL; + +PFNGLEVALMAPSNVPROC __glewEvalMapsNV = NULL; +PFNGLGETMAPATTRIBPARAMETERFVNVPROC __glewGetMapAttribParameterfvNV = NULL; +PFNGLGETMAPATTRIBPARAMETERIVNVPROC __glewGetMapAttribParameterivNV = NULL; +PFNGLGETMAPCONTROLPOINTSNVPROC __glewGetMapControlPointsNV = NULL; +PFNGLGETMAPPARAMETERFVNVPROC __glewGetMapParameterfvNV = NULL; +PFNGLGETMAPPARAMETERIVNVPROC __glewGetMapParameterivNV = NULL; +PFNGLMAPCONTROLPOINTSNVPROC __glewMapControlPointsNV = NULL; +PFNGLMAPPARAMETERFVNVPROC __glewMapParameterfvNV = NULL; +PFNGLMAPPARAMETERIVNVPROC __glewMapParameterivNV = NULL; + +PFNGLDELETEFENCESNVPROC __glewDeleteFencesNV = NULL; +PFNGLFINISHFENCENVPROC __glewFinishFenceNV = NULL; +PFNGLGENFENCESNVPROC __glewGenFencesNV = NULL; +PFNGLGETFENCEIVNVPROC __glewGetFenceivNV = NULL; +PFNGLISFENCENVPROC __glewIsFenceNV = NULL; +PFNGLSETFENCENVPROC __glewSetFenceNV = NULL; +PFNGLTESTFENCENVPROC __glewTestFenceNV = NULL; + +PFNGLGETPROGRAMNAMEDPARAMETERDVNVPROC __glewGetProgramNamedParameterdvNV = NULL; +PFNGLGETPROGRAMNAMEDPARAMETERFVNVPROC __glewGetProgramNamedParameterfvNV = NULL; +PFNGLPROGRAMNAMEDPARAMETER4DNVPROC __glewProgramNamedParameter4dNV = NULL; +PFNGLPROGRAMNAMEDPARAMETER4DVNVPROC __glewProgramNamedParameter4dvNV = NULL; +PFNGLPROGRAMNAMEDPARAMETER4FNVPROC __glewProgramNamedParameter4fNV = NULL; +PFNGLPROGRAMNAMEDPARAMETER4FVNVPROC __glewProgramNamedParameter4fvNV = NULL; + +PFNGLCOLOR3HNVPROC __glewColor3hNV = NULL; +PFNGLCOLOR3HVNVPROC __glewColor3hvNV = NULL; +PFNGLCOLOR4HNVPROC __glewColor4hNV = NULL; +PFNGLCOLOR4HVNVPROC __glewColor4hvNV = NULL; +PFNGLFOGCOORDHNVPROC __glewFogCoordhNV = NULL; +PFNGLFOGCOORDHVNVPROC __glewFogCoordhvNV = NULL; +PFNGLMULTITEXCOORD1HNVPROC __glewMultiTexCoord1hNV = NULL; +PFNGLMULTITEXCOORD1HVNVPROC __glewMultiTexCoord1hvNV = NULL; +PFNGLMULTITEXCOORD2HNVPROC __glewMultiTexCoord2hNV = NULL; +PFNGLMULTITEXCOORD2HVNVPROC __glewMultiTexCoord2hvNV = NULL; +PFNGLMULTITEXCOORD3HNVPROC __glewMultiTexCoord3hNV = NULL; +PFNGLMULTITEXCOORD3HVNVPROC __glewMultiTexCoord3hvNV = NULL; +PFNGLMULTITEXCOORD4HNVPROC __glewMultiTexCoord4hNV = NULL; +PFNGLMULTITEXCOORD4HVNVPROC __glewMultiTexCoord4hvNV = NULL; +PFNGLNORMAL3HNVPROC __glewNormal3hNV = NULL; +PFNGLNORMAL3HVNVPROC __glewNormal3hvNV = NULL; +PFNGLSECONDARYCOLOR3HNVPROC __glewSecondaryColor3hNV = NULL; +PFNGLSECONDARYCOLOR3HVNVPROC __glewSecondaryColor3hvNV = NULL; +PFNGLTEXCOORD1HNVPROC __glewTexCoord1hNV = NULL; +PFNGLTEXCOORD1HVNVPROC __glewTexCoord1hvNV = NULL; +PFNGLTEXCOORD2HNVPROC __glewTexCoord2hNV = NULL; +PFNGLTEXCOORD2HVNVPROC __glewTexCoord2hvNV = NULL; +PFNGLTEXCOORD3HNVPROC __glewTexCoord3hNV = NULL; +PFNGLTEXCOORD3HVNVPROC __glewTexCoord3hvNV = NULL; +PFNGLTEXCOORD4HNVPROC __glewTexCoord4hNV = NULL; +PFNGLTEXCOORD4HVNVPROC __glewTexCoord4hvNV = NULL; +PFNGLVERTEX2HNVPROC __glewVertex2hNV = NULL; +PFNGLVERTEX2HVNVPROC __glewVertex2hvNV = NULL; +PFNGLVERTEX3HNVPROC __glewVertex3hNV = NULL; +PFNGLVERTEX3HVNVPROC __glewVertex3hvNV = NULL; +PFNGLVERTEX4HNVPROC __glewVertex4hNV = NULL; +PFNGLVERTEX4HVNVPROC __glewVertex4hvNV = NULL; +PFNGLVERTEXATTRIB1HNVPROC __glewVertexAttrib1hNV = NULL; +PFNGLVERTEXATTRIB1HVNVPROC __glewVertexAttrib1hvNV = NULL; +PFNGLVERTEXATTRIB2HNVPROC __glewVertexAttrib2hNV = NULL; +PFNGLVERTEXATTRIB2HVNVPROC __glewVertexAttrib2hvNV = NULL; +PFNGLVERTEXATTRIB3HNVPROC __glewVertexAttrib3hNV = NULL; +PFNGLVERTEXATTRIB3HVNVPROC __glewVertexAttrib3hvNV = NULL; +PFNGLVERTEXATTRIB4HNVPROC __glewVertexAttrib4hNV = NULL; +PFNGLVERTEXATTRIB4HVNVPROC __glewVertexAttrib4hvNV = NULL; +PFNGLVERTEXATTRIBS1HVNVPROC __glewVertexAttribs1hvNV = NULL; +PFNGLVERTEXATTRIBS2HVNVPROC __glewVertexAttribs2hvNV = NULL; +PFNGLVERTEXATTRIBS3HVNVPROC __glewVertexAttribs3hvNV = NULL; +PFNGLVERTEXATTRIBS4HVNVPROC __glewVertexAttribs4hvNV = NULL; +PFNGLVERTEXWEIGHTHNVPROC __glewVertexWeighthNV = NULL; +PFNGLVERTEXWEIGHTHVNVPROC __glewVertexWeighthvNV = NULL; + +PFNGLBEGINOCCLUSIONQUERYNVPROC __glewBeginOcclusionQueryNV = NULL; +PFNGLDELETEOCCLUSIONQUERIESNVPROC __glewDeleteOcclusionQueriesNV = NULL; +PFNGLENDOCCLUSIONQUERYNVPROC __glewEndOcclusionQueryNV = NULL; +PFNGLGENOCCLUSIONQUERIESNVPROC __glewGenOcclusionQueriesNV = NULL; +PFNGLGETOCCLUSIONQUERYIVNVPROC __glewGetOcclusionQueryivNV = NULL; +PFNGLGETOCCLUSIONQUERYUIVNVPROC __glewGetOcclusionQueryuivNV = NULL; +PFNGLISOCCLUSIONQUERYNVPROC __glewIsOcclusionQueryNV = NULL; + +PFNGLFLUSHPIXELDATARANGENVPROC __glewFlushPixelDataRangeNV = NULL; +PFNGLPIXELDATARANGENVPROC __glewPixelDataRangeNV = NULL; + +PFNGLPOINTPARAMETERINVPROC __glewPointParameteriNV = NULL; +PFNGLPOINTPARAMETERIVNVPROC __glewPointParameterivNV = NULL; + +PFNGLPRIMITIVERESTARTINDEXNVPROC __glewPrimitiveRestartIndexNV = NULL; +PFNGLPRIMITIVERESTARTNVPROC __glewPrimitiveRestartNV = NULL; + +PFNGLCOMBINERINPUTNVPROC __glewCombinerInputNV = NULL; +PFNGLCOMBINEROUTPUTNVPROC __glewCombinerOutputNV = NULL; +PFNGLCOMBINERPARAMETERFNVPROC __glewCombinerParameterfNV = NULL; +PFNGLCOMBINERPARAMETERFVNVPROC __glewCombinerParameterfvNV = NULL; +PFNGLCOMBINERPARAMETERINVPROC __glewCombinerParameteriNV = NULL; +PFNGLCOMBINERPARAMETERIVNVPROC __glewCombinerParameterivNV = NULL; +PFNGLFINALCOMBINERINPUTNVPROC __glewFinalCombinerInputNV = NULL; +PFNGLGETCOMBINERINPUTPARAMETERFVNVPROC __glewGetCombinerInputParameterfvNV = NULL; +PFNGLGETCOMBINERINPUTPARAMETERIVNVPROC __glewGetCombinerInputParameterivNV = NULL; +PFNGLGETCOMBINEROUTPUTPARAMETERFVNVPROC __glewGetCombinerOutputParameterfvNV = NULL; +PFNGLGETCOMBINEROUTPUTPARAMETERIVNVPROC __glewGetCombinerOutputParameterivNV = NULL; +PFNGLGETFINALCOMBINERINPUTPARAMETERFVNVPROC __glewGetFinalCombinerInputParameterfvNV = NULL; +PFNGLGETFINALCOMBINERINPUTPARAMETERIVNVPROC __glewGetFinalCombinerInputParameterivNV = NULL; + +PFNGLCOMBINERSTAGEPARAMETERFVNVPROC __glewCombinerStageParameterfvNV = NULL; +PFNGLGETCOMBINERSTAGEPARAMETERFVNVPROC __glewGetCombinerStageParameterfvNV = NULL; + +PFNGLFLUSHVERTEXARRAYRANGENVPROC __glewFlushVertexArrayRangeNV = NULL; +PFNGLVERTEXARRAYRANGENVPROC __glewVertexArrayRangeNV = NULL; + +PFNGLAREPROGRAMSRESIDENTNVPROC __glewAreProgramsResidentNV = NULL; +PFNGLBINDPROGRAMNVPROC __glewBindProgramNV = NULL; +PFNGLDELETEPROGRAMSNVPROC __glewDeleteProgramsNV = NULL; +PFNGLEXECUTEPROGRAMNVPROC __glewExecuteProgramNV = NULL; +PFNGLGENPROGRAMSNVPROC __glewGenProgramsNV = NULL; +PFNGLGETPROGRAMPARAMETERDVNVPROC __glewGetProgramParameterdvNV = NULL; +PFNGLGETPROGRAMPARAMETERFVNVPROC __glewGetProgramParameterfvNV = NULL; +PFNGLGETPROGRAMSTRINGNVPROC __glewGetProgramStringNV = NULL; +PFNGLGETPROGRAMIVNVPROC __glewGetProgramivNV = NULL; +PFNGLGETTRACKMATRIXIVNVPROC __glewGetTrackMatrixivNV = NULL; +PFNGLGETVERTEXATTRIBPOINTERVNVPROC __glewGetVertexAttribPointervNV = NULL; +PFNGLGETVERTEXATTRIBDVNVPROC __glewGetVertexAttribdvNV = NULL; +PFNGLGETVERTEXATTRIBFVNVPROC __glewGetVertexAttribfvNV = NULL; +PFNGLGETVERTEXATTRIBIVNVPROC __glewGetVertexAttribivNV = NULL; +PFNGLISPROGRAMNVPROC __glewIsProgramNV = NULL; +PFNGLLOADPROGRAMNVPROC __glewLoadProgramNV = NULL; +PFNGLPROGRAMPARAMETER4DNVPROC __glewProgramParameter4dNV = NULL; +PFNGLPROGRAMPARAMETER4DVNVPROC __glewProgramParameter4dvNV = NULL; +PFNGLPROGRAMPARAMETER4FNVPROC __glewProgramParameter4fNV = NULL; +PFNGLPROGRAMPARAMETER4FVNVPROC __glewProgramParameter4fvNV = NULL; +PFNGLPROGRAMPARAMETERS4DVNVPROC __glewProgramParameters4dvNV = NULL; +PFNGLPROGRAMPARAMETERS4FVNVPROC __glewProgramParameters4fvNV = NULL; +PFNGLREQUESTRESIDENTPROGRAMSNVPROC __glewRequestResidentProgramsNV = NULL; +PFNGLTRACKMATRIXNVPROC __glewTrackMatrixNV = NULL; +PFNGLVERTEXATTRIB1DNVPROC __glewVertexAttrib1dNV = NULL; +PFNGLVERTEXATTRIB1DVNVPROC __glewVertexAttrib1dvNV = NULL; +PFNGLVERTEXATTRIB1FNVPROC __glewVertexAttrib1fNV = NULL; +PFNGLVERTEXATTRIB1FVNVPROC __glewVertexAttrib1fvNV = NULL; +PFNGLVERTEXATTRIB1SNVPROC __glewVertexAttrib1sNV = NULL; +PFNGLVERTEXATTRIB1SVNVPROC __glewVertexAttrib1svNV = NULL; +PFNGLVERTEXATTRIB2DNVPROC __glewVertexAttrib2dNV = NULL; +PFNGLVERTEXATTRIB2DVNVPROC __glewVertexAttrib2dvNV = NULL; +PFNGLVERTEXATTRIB2FNVPROC __glewVertexAttrib2fNV = NULL; +PFNGLVERTEXATTRIB2FVNVPROC __glewVertexAttrib2fvNV = NULL; +PFNGLVERTEXATTRIB2SNVPROC __glewVertexAttrib2sNV = NULL; +PFNGLVERTEXATTRIB2SVNVPROC __glewVertexAttrib2svNV = NULL; +PFNGLVERTEXATTRIB3DNVPROC __glewVertexAttrib3dNV = NULL; +PFNGLVERTEXATTRIB3DVNVPROC __glewVertexAttrib3dvNV = NULL; +PFNGLVERTEXATTRIB3FNVPROC __glewVertexAttrib3fNV = NULL; +PFNGLVERTEXATTRIB3FVNVPROC __glewVertexAttrib3fvNV = NULL; +PFNGLVERTEXATTRIB3SNVPROC __glewVertexAttrib3sNV = NULL; +PFNGLVERTEXATTRIB3SVNVPROC __glewVertexAttrib3svNV = NULL; +PFNGLVERTEXATTRIB4DNVPROC __glewVertexAttrib4dNV = NULL; +PFNGLVERTEXATTRIB4DVNVPROC __glewVertexAttrib4dvNV = NULL; +PFNGLVERTEXATTRIB4FNVPROC __glewVertexAttrib4fNV = NULL; +PFNGLVERTEXATTRIB4FVNVPROC __glewVertexAttrib4fvNV = NULL; +PFNGLVERTEXATTRIB4SNVPROC __glewVertexAttrib4sNV = NULL; +PFNGLVERTEXATTRIB4SVNVPROC __glewVertexAttrib4svNV = NULL; +PFNGLVERTEXATTRIB4UBNVPROC __glewVertexAttrib4ubNV = NULL; +PFNGLVERTEXATTRIB4UBVNVPROC __glewVertexAttrib4ubvNV = NULL; +PFNGLVERTEXATTRIBPOINTERNVPROC __glewVertexAttribPointerNV = NULL; +PFNGLVERTEXATTRIBS1DVNVPROC __glewVertexAttribs1dvNV = NULL; +PFNGLVERTEXATTRIBS1FVNVPROC __glewVertexAttribs1fvNV = NULL; +PFNGLVERTEXATTRIBS1SVNVPROC __glewVertexAttribs1svNV = NULL; +PFNGLVERTEXATTRIBS2DVNVPROC __glewVertexAttribs2dvNV = NULL; +PFNGLVERTEXATTRIBS2FVNVPROC __glewVertexAttribs2fvNV = NULL; +PFNGLVERTEXATTRIBS2SVNVPROC __glewVertexAttribs2svNV = NULL; +PFNGLVERTEXATTRIBS3DVNVPROC __glewVertexAttribs3dvNV = NULL; +PFNGLVERTEXATTRIBS3FVNVPROC __glewVertexAttribs3fvNV = NULL; +PFNGLVERTEXATTRIBS3SVNVPROC __glewVertexAttribs3svNV = NULL; +PFNGLVERTEXATTRIBS4DVNVPROC __glewVertexAttribs4dvNV = NULL; +PFNGLVERTEXATTRIBS4FVNVPROC __glewVertexAttribs4fvNV = NULL; +PFNGLVERTEXATTRIBS4SVNVPROC __glewVertexAttribs4svNV = NULL; +PFNGLVERTEXATTRIBS4UBVNVPROC __glewVertexAttribs4ubvNV = NULL; + +PFNGLDETAILTEXFUNCSGISPROC __glewDetailTexFuncSGIS = NULL; +PFNGLGETDETAILTEXFUNCSGISPROC __glewGetDetailTexFuncSGIS = NULL; + +PFNGLFOGFUNCSGISPROC __glewFogFuncSGIS = NULL; +PFNGLGETFOGFUNCSGISPROC __glewGetFogFuncSGIS = NULL; + +PFNGLSAMPLEMASKSGISPROC __glewSampleMaskSGIS = NULL; +PFNGLSAMPLEPATTERNSGISPROC __glewSamplePatternSGIS = NULL; + +PFNGLGETSHARPENTEXFUNCSGISPROC __glewGetSharpenTexFuncSGIS = NULL; +PFNGLSHARPENTEXFUNCSGISPROC __glewSharpenTexFuncSGIS = NULL; + +PFNGLTEXIMAGE4DSGISPROC __glewTexImage4DSGIS = NULL; +PFNGLTEXSUBIMAGE4DSGISPROC __glewTexSubImage4DSGIS = NULL; + +PFNGLGETTEXFILTERFUNCSGISPROC __glewGetTexFilterFuncSGIS = NULL; +PFNGLTEXFILTERFUNCSGISPROC __glewTexFilterFuncSGIS = NULL; + +PFNGLASYNCMARKERSGIXPROC __glewAsyncMarkerSGIX = NULL; +PFNGLDELETEASYNCMARKERSSGIXPROC __glewDeleteAsyncMarkersSGIX = NULL; +PFNGLFINISHASYNCSGIXPROC __glewFinishAsyncSGIX = NULL; +PFNGLGENASYNCMARKERSSGIXPROC __glewGenAsyncMarkersSGIX = NULL; +PFNGLISASYNCMARKERSGIXPROC __glewIsAsyncMarkerSGIX = NULL; +PFNGLPOLLASYNCSGIXPROC __glewPollAsyncSGIX = NULL; + +PFNGLFLUSHRASTERSGIXPROC __glewFlushRasterSGIX = NULL; + +PFNGLTEXTUREFOGSGIXPROC __glewTextureFogSGIX = NULL; + +#if 0 +PFNGLFRAGMENTCOLORMATERIALSGIXPROC __glewFragmentColorMaterialSGIX = NULL; +PFNGLFRAGMENTLIGHTMODELFSGIXPROC __glewFragmentLightModelfSGIX = NULL; +PFNGLFRAGMENTLIGHTMODELFVSGIXPROC __glewFragmentLightModelfvSGIX = NULL; +PFNGLFRAGMENTLIGHTMODELISGIXPROC __glewFragmentLightModeliSGIX = NULL; +PFNGLFRAGMENTLIGHTMODELIVSGIXPROC __glewFragmentLightModelivSGIX = NULL; +PFNGLFRAGMENTLIGHTFSGIXPROC __glewFragmentLightfSGIX = NULL; +PFNGLFRAGMENTLIGHTFVSGIXPROC __glewFragmentLightfvSGIX = NULL; +PFNGLFRAGMENTLIGHTISGIXPROC __glewFragmentLightiSGIX = NULL; +PFNGLFRAGMENTLIGHTIVSGIXPROC __glewFragmentLightivSGIX = NULL; +PFNGLFRAGMENTMATERIALFSGIXPROC __glewFragmentMaterialfSGIX = NULL; +PFNGLFRAGMENTMATERIALFVSGIXPROC __glewFragmentMaterialfvSGIX = NULL; +PFNGLFRAGMENTMATERIALISGIXPROC __glewFragmentMaterialiSGIX = NULL; +PFNGLFRAGMENTMATERIALIVSGIXPROC __glewFragmentMaterialivSGIX = NULL; +PFNGLGETFRAGMENTLIGHTFVSGIXPROC __glewGetFragmentLightfvSGIX = NULL; +PFNGLGETFRAGMENTLIGHTIVSGIXPROC __glewGetFragmentLightivSGIX = NULL; +PFNGLGETFRAGMENTMATERIALFVSGIXPROC __glewGetFragmentMaterialfvSGIX = NULL; +PFNGLGETFRAGMENTMATERIALIVSGIXPROC __glewGetFragmentMaterialivSGIX = NULL; +#endif + +PFNGLFRAMEZOOMSGIXPROC __glewFrameZoomSGIX = NULL; + +PFNGLPIXELTEXGENSGIXPROC __glewPixelTexGenSGIX = NULL; + +PFNGLREFERENCEPLANESGIXPROC __glewReferencePlaneSGIX = NULL; + +PFNGLSPRITEPARAMETERFSGIXPROC __glewSpriteParameterfSGIX = NULL; +PFNGLSPRITEPARAMETERFVSGIXPROC __glewSpriteParameterfvSGIX = NULL; +PFNGLSPRITEPARAMETERISGIXPROC __glewSpriteParameteriSGIX = NULL; +PFNGLSPRITEPARAMETERIVSGIXPROC __glewSpriteParameterivSGIX = NULL; + +PFNGLTAGSAMPLEBUFFERSGIXPROC __glewTagSampleBufferSGIX = NULL; + +PFNGLCOLORTABLEPARAMETERFVSGIPROC __glewColorTableParameterfvSGI = NULL; +PFNGLCOLORTABLEPARAMETERIVSGIPROC __glewColorTableParameterivSGI = NULL; +PFNGLCOLORTABLESGIPROC __glewColorTableSGI = NULL; +PFNGLCOPYCOLORTABLESGIPROC __glewCopyColorTableSGI = NULL; +PFNGLGETCOLORTABLEPARAMETERFVSGIPROC __glewGetColorTableParameterfvSGI = NULL; +PFNGLGETCOLORTABLEPARAMETERIVSGIPROC __glewGetColorTableParameterivSGI = NULL; +PFNGLGETCOLORTABLESGIPROC __glewGetColorTableSGI = NULL; + +PFNGLFINISHTEXTURESUNXPROC __glewFinishTextureSUNX = NULL; + +PFNGLGLOBALALPHAFACTORBSUNPROC __glewGlobalAlphaFactorbSUN = NULL; +PFNGLGLOBALALPHAFACTORDSUNPROC __glewGlobalAlphaFactordSUN = NULL; +PFNGLGLOBALALPHAFACTORFSUNPROC __glewGlobalAlphaFactorfSUN = NULL; +PFNGLGLOBALALPHAFACTORISUNPROC __glewGlobalAlphaFactoriSUN = NULL; +PFNGLGLOBALALPHAFACTORSSUNPROC __glewGlobalAlphaFactorsSUN = NULL; +PFNGLGLOBALALPHAFACTORUBSUNPROC __glewGlobalAlphaFactorubSUN = NULL; +PFNGLGLOBALALPHAFACTORUISUNPROC __glewGlobalAlphaFactoruiSUN = NULL; +PFNGLGLOBALALPHAFACTORUSSUNPROC __glewGlobalAlphaFactorusSUN = NULL; + +PFNGLREADVIDEOPIXELSSUNPROC __glewReadVideoPixelsSUN = NULL; + +PFNGLREPLACEMENTCODEPOINTERSUNPROC __glewReplacementCodePointerSUN = NULL; +PFNGLREPLACEMENTCODEUBSUNPROC __glewReplacementCodeubSUN = NULL; +PFNGLREPLACEMENTCODEUBVSUNPROC __glewReplacementCodeubvSUN = NULL; +PFNGLREPLACEMENTCODEUISUNPROC __glewReplacementCodeuiSUN = NULL; +PFNGLREPLACEMENTCODEUIVSUNPROC __glewReplacementCodeuivSUN = NULL; +PFNGLREPLACEMENTCODEUSSUNPROC __glewReplacementCodeusSUN = NULL; +PFNGLREPLACEMENTCODEUSVSUNPROC __glewReplacementCodeusvSUN = NULL; + +PFNGLCOLOR3FVERTEX3FSUNPROC __glewColor3fVertex3fSUN = NULL; +PFNGLCOLOR3FVERTEX3FVSUNPROC __glewColor3fVertex3fvSUN = NULL; +PFNGLCOLOR4FNORMAL3FVERTEX3FSUNPROC __glewColor4fNormal3fVertex3fSUN = NULL; +PFNGLCOLOR4FNORMAL3FVERTEX3FVSUNPROC __glewColor4fNormal3fVertex3fvSUN = NULL; +PFNGLCOLOR4UBVERTEX2FSUNPROC __glewColor4ubVertex2fSUN = NULL; +PFNGLCOLOR4UBVERTEX2FVSUNPROC __glewColor4ubVertex2fvSUN = NULL; +PFNGLCOLOR4UBVERTEX3FSUNPROC __glewColor4ubVertex3fSUN = NULL; +PFNGLCOLOR4UBVERTEX3FVSUNPROC __glewColor4ubVertex3fvSUN = NULL; +PFNGLNORMAL3FVERTEX3FSUNPROC __glewNormal3fVertex3fSUN = NULL; +PFNGLNORMAL3FVERTEX3FVSUNPROC __glewNormal3fVertex3fvSUN = NULL; +PFNGLREPLACEMENTCODEUICOLOR3FVERTEX3FSUNPROC __glewReplacementCodeuiColor3fVertex3fSUN = NULL; +PFNGLREPLACEMENTCODEUICOLOR3FVERTEX3FVSUNPROC __glewReplacementCodeuiColor3fVertex3fvSUN = NULL; +PFNGLREPLACEMENTCODEUICOLOR4FNORMAL3FVERTEX3FSUNPROC __glewReplacementCodeuiColor4fNormal3fVertex3fSUN = NULL; +PFNGLREPLACEMENTCODEUICOLOR4FNORMAL3FVERTEX3FVSUNPROC __glewReplacementCodeuiColor4fNormal3fVertex3fvSUN = NULL; +PFNGLREPLACEMENTCODEUICOLOR4UBVERTEX3FSUNPROC __glewReplacementCodeuiColor4ubVertex3fSUN = NULL; +PFNGLREPLACEMENTCODEUICOLOR4UBVERTEX3FVSUNPROC __glewReplacementCodeuiColor4ubVertex3fvSUN = NULL; +PFNGLREPLACEMENTCODEUINORMAL3FVERTEX3FSUNPROC __glewReplacementCodeuiNormal3fVertex3fSUN = NULL; +PFNGLREPLACEMENTCODEUINORMAL3FVERTEX3FVSUNPROC __glewReplacementCodeuiNormal3fVertex3fvSUN = NULL; +PFNGLREPLACEMENTCODEUITEXCOORD2FCOLOR4FNORMAL3FVERTEX3FSUNPROC __glewReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN = NULL; +PFNGLREPLACEMENTCODEUITEXCOORD2FCOLOR4FNORMAL3FVERTEX3FVSUNPROC __glewReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN = NULL; +PFNGLREPLACEMENTCODEUITEXCOORD2FNORMAL3FVERTEX3FSUNPROC __glewReplacementCodeuiTexCoord2fNormal3fVertex3fSUN = NULL; +PFNGLREPLACEMENTCODEUITEXCOORD2FNORMAL3FVERTEX3FVSUNPROC __glewReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN = NULL; +PFNGLREPLACEMENTCODEUITEXCOORD2FVERTEX3FSUNPROC __glewReplacementCodeuiTexCoord2fVertex3fSUN = NULL; +PFNGLREPLACEMENTCODEUITEXCOORD2FVERTEX3FVSUNPROC __glewReplacementCodeuiTexCoord2fVertex3fvSUN = NULL; +PFNGLREPLACEMENTCODEUIVERTEX3FSUNPROC __glewReplacementCodeuiVertex3fSUN = NULL; +PFNGLREPLACEMENTCODEUIVERTEX3FVSUNPROC __glewReplacementCodeuiVertex3fvSUN = NULL; +PFNGLTEXCOORD2FCOLOR3FVERTEX3FSUNPROC __glewTexCoord2fColor3fVertex3fSUN = NULL; +PFNGLTEXCOORD2FCOLOR3FVERTEX3FVSUNPROC __glewTexCoord2fColor3fVertex3fvSUN = NULL; +PFNGLTEXCOORD2FCOLOR4FNORMAL3FVERTEX3FSUNPROC __glewTexCoord2fColor4fNormal3fVertex3fSUN = NULL; +PFNGLTEXCOORD2FCOLOR4FNORMAL3FVERTEX3FVSUNPROC __glewTexCoord2fColor4fNormal3fVertex3fvSUN = NULL; +PFNGLTEXCOORD2FCOLOR4UBVERTEX3FSUNPROC __glewTexCoord2fColor4ubVertex3fSUN = NULL; +PFNGLTEXCOORD2FCOLOR4UBVERTEX3FVSUNPROC __glewTexCoord2fColor4ubVertex3fvSUN = NULL; +PFNGLTEXCOORD2FNORMAL3FVERTEX3FSUNPROC __glewTexCoord2fNormal3fVertex3fSUN = NULL; +PFNGLTEXCOORD2FNORMAL3FVERTEX3FVSUNPROC __glewTexCoord2fNormal3fVertex3fvSUN = NULL; +PFNGLTEXCOORD2FVERTEX3FSUNPROC __glewTexCoord2fVertex3fSUN = NULL; +PFNGLTEXCOORD2FVERTEX3FVSUNPROC __glewTexCoord2fVertex3fvSUN = NULL; +PFNGLTEXCOORD4FCOLOR4FNORMAL3FVERTEX4FSUNPROC __glewTexCoord4fColor4fNormal3fVertex4fSUN = NULL; +PFNGLTEXCOORD4FCOLOR4FNORMAL3FVERTEX4FVSUNPROC __glewTexCoord4fColor4fNormal3fVertex4fvSUN = NULL; +PFNGLTEXCOORD4FVERTEX4FSUNPROC __glewTexCoord4fVertex4fSUN = NULL; +PFNGLTEXCOORD4FVERTEX4FVSUNPROC __glewTexCoord4fVertex4fvSUN = NULL; + +PFNGLADDSWAPHINTRECTWINPROC __glewAddSwapHintRectWIN = NULL; + +#endif /* !WIN32 || !GLEW_MX */ + +#if !defined(GLEW_MX) + +GLboolean __GLEW_VERSION_1_1 = GL_FALSE; +GLboolean __GLEW_VERSION_1_2 = GL_FALSE; +GLboolean __GLEW_VERSION_1_3 = GL_FALSE; +GLboolean __GLEW_VERSION_1_4 = GL_FALSE; +GLboolean __GLEW_VERSION_1_5 = GL_FALSE; +GLboolean __GLEW_VERSION_2_0 = GL_FALSE; +GLboolean __GLEW_3DFX_multisample = GL_FALSE; +GLboolean __GLEW_3DFX_tbuffer = GL_FALSE; +GLboolean __GLEW_3DFX_texture_compression_FXT1 = GL_FALSE; +GLboolean __GLEW_APPLE_client_storage = GL_FALSE; +GLboolean __GLEW_APPLE_element_array = GL_FALSE; +GLboolean __GLEW_APPLE_fence = GL_FALSE; +GLboolean __GLEW_APPLE_float_pixels = GL_FALSE; +GLboolean __GLEW_APPLE_pixel_buffer = GL_FALSE; +GLboolean __GLEW_APPLE_specular_vector = GL_FALSE; +GLboolean __GLEW_APPLE_texture_range = GL_FALSE; +GLboolean __GLEW_APPLE_transform_hint = GL_FALSE; +GLboolean __GLEW_APPLE_vertex_array_object = GL_FALSE; +GLboolean __GLEW_APPLE_vertex_array_range = GL_FALSE; +GLboolean __GLEW_APPLE_ycbcr_422 = GL_FALSE; +GLboolean __GLEW_ARB_color_buffer_float = GL_FALSE; +GLboolean __GLEW_ARB_depth_texture = GL_FALSE; +GLboolean __GLEW_ARB_draw_buffers = GL_FALSE; +GLboolean __GLEW_ARB_fragment_program = GL_FALSE; +GLboolean __GLEW_ARB_fragment_program_shadow = GL_FALSE; +GLboolean __GLEW_ARB_fragment_shader = GL_FALSE; +GLboolean __GLEW_ARB_half_float_pixel = GL_FALSE; +GLboolean __GLEW_ARB_imaging = GL_FALSE; +GLboolean __GLEW_ARB_matrix_palette = GL_FALSE; +GLboolean __GLEW_ARB_multisample = GL_FALSE; +GLboolean __GLEW_ARB_multitexture = GL_FALSE; +GLboolean __GLEW_ARB_occlusion_query = GL_FALSE; +GLboolean __GLEW_ARB_pixel_buffer_object = GL_FALSE; +GLboolean __GLEW_ARB_point_parameters = GL_FALSE; +GLboolean __GLEW_ARB_point_sprite = GL_FALSE; +GLboolean __GLEW_ARB_shader_objects = GL_FALSE; +GLboolean __GLEW_ARB_shading_language_100 = GL_FALSE; +GLboolean __GLEW_ARB_shadow = GL_FALSE; +GLboolean __GLEW_ARB_shadow_ambient = GL_FALSE; +GLboolean __GLEW_ARB_texture_border_clamp = GL_FALSE; +GLboolean __GLEW_ARB_texture_compression = GL_FALSE; +GLboolean __GLEW_ARB_texture_cube_map = GL_FALSE; +GLboolean __GLEW_ARB_texture_env_add = GL_FALSE; +GLboolean __GLEW_ARB_texture_env_combine = GL_FALSE; +GLboolean __GLEW_ARB_texture_env_crossbar = GL_FALSE; +GLboolean __GLEW_ARB_texture_env_dot3 = GL_FALSE; +GLboolean __GLEW_ARB_texture_float = GL_FALSE; +GLboolean __GLEW_ARB_texture_mirrored_repeat = GL_FALSE; +GLboolean __GLEW_ARB_texture_non_power_of_two = GL_FALSE; +GLboolean __GLEW_ARB_texture_rectangle = GL_FALSE; +GLboolean __GLEW_ARB_transpose_matrix = GL_FALSE; +GLboolean __GLEW_ARB_vertex_blend = GL_FALSE; +GLboolean __GLEW_ARB_vertex_buffer_object = GL_FALSE; +GLboolean __GLEW_ARB_vertex_program = GL_FALSE; +GLboolean __GLEW_ARB_vertex_shader = GL_FALSE; +GLboolean __GLEW_ARB_window_pos = GL_FALSE; +GLboolean __GLEW_ATIX_point_sprites = GL_FALSE; +GLboolean __GLEW_ATIX_texture_env_combine3 = GL_FALSE; +GLboolean __GLEW_ATIX_texture_env_route = GL_FALSE; +GLboolean __GLEW_ATIX_vertex_shader_output_point_size = GL_FALSE; +GLboolean __GLEW_ATI_draw_buffers = GL_FALSE; +GLboolean __GLEW_ATI_element_array = GL_FALSE; +GLboolean __GLEW_ATI_envmap_bumpmap = GL_FALSE; +GLboolean __GLEW_ATI_fragment_shader = GL_FALSE; +GLboolean __GLEW_ATI_map_object_buffer = GL_FALSE; +GLboolean __GLEW_ATI_pn_triangles = GL_FALSE; +GLboolean __GLEW_ATI_separate_stencil = GL_FALSE; +GLboolean __GLEW_ATI_text_fragment_shader = GL_FALSE; +GLboolean __GLEW_ATI_texture_compression_3dc = GL_FALSE; +GLboolean __GLEW_ATI_texture_env_combine3 = GL_FALSE; +GLboolean __GLEW_ATI_texture_float = GL_FALSE; +GLboolean __GLEW_ATI_texture_mirror_once = GL_FALSE; +GLboolean __GLEW_ATI_vertex_array_object = GL_FALSE; +GLboolean __GLEW_ATI_vertex_attrib_array_object = GL_FALSE; +GLboolean __GLEW_ATI_vertex_streams = GL_FALSE; +GLboolean __GLEW_EXT_422_pixels = GL_FALSE; +GLboolean __GLEW_EXT_Cg_shader = GL_FALSE; +GLboolean __GLEW_EXT_abgr = GL_FALSE; +GLboolean __GLEW_EXT_bgra = GL_FALSE; +GLboolean __GLEW_EXT_blend_color = GL_FALSE; +GLboolean __GLEW_EXT_blend_equation_separate = GL_FALSE; +GLboolean __GLEW_EXT_blend_func_separate = GL_FALSE; +GLboolean __GLEW_EXT_blend_logic_op = GL_FALSE; +GLboolean __GLEW_EXT_blend_minmax = GL_FALSE; +GLboolean __GLEW_EXT_blend_subtract = GL_FALSE; +GLboolean __GLEW_EXT_clip_volume_hint = GL_FALSE; +GLboolean __GLEW_EXT_cmyka = GL_FALSE; +GLboolean __GLEW_EXT_color_subtable = GL_FALSE; +GLboolean __GLEW_EXT_compiled_vertex_array = GL_FALSE; +GLboolean __GLEW_EXT_convolution = GL_FALSE; +GLboolean __GLEW_EXT_coordinate_frame = GL_FALSE; +GLboolean __GLEW_EXT_copy_texture = GL_FALSE; +GLboolean __GLEW_EXT_cull_vertex = GL_FALSE; +GLboolean __GLEW_EXT_depth_bounds_test = GL_FALSE; +GLboolean __GLEW_EXT_draw_range_elements = GL_FALSE; +GLboolean __GLEW_EXT_fog_coord = GL_FALSE; +GLboolean __GLEW_EXT_fragment_lighting = GL_FALSE; +GLboolean __GLEW_EXT_framebuffer_blit = GL_FALSE; +GLboolean __GLEW_EXT_framebuffer_multisample = GL_FALSE; +GLboolean __GLEW_EXT_framebuffer_object = GL_FALSE; +GLboolean __GLEW_EXT_histogram = GL_FALSE; +GLboolean __GLEW_EXT_index_array_formats = GL_FALSE; +GLboolean __GLEW_EXT_index_func = GL_FALSE; +GLboolean __GLEW_EXT_index_material = GL_FALSE; +GLboolean __GLEW_EXT_index_texture = GL_FALSE; +GLboolean __GLEW_EXT_light_texture = GL_FALSE; +GLboolean __GLEW_EXT_misc_attribute = GL_FALSE; +GLboolean __GLEW_EXT_multi_draw_arrays = GL_FALSE; +GLboolean __GLEW_EXT_multisample = GL_FALSE; +GLboolean __GLEW_EXT_packed_depth_stencil = GL_FALSE; +GLboolean __GLEW_EXT_packed_pixels = GL_FALSE; +GLboolean __GLEW_EXT_paletted_texture = GL_FALSE; +GLboolean __GLEW_EXT_pixel_buffer_object = GL_FALSE; +GLboolean __GLEW_EXT_pixel_transform = GL_FALSE; +GLboolean __GLEW_EXT_pixel_transform_color_table = GL_FALSE; +GLboolean __GLEW_EXT_point_parameters = GL_FALSE; +GLboolean __GLEW_EXT_polygon_offset = GL_FALSE; +GLboolean __GLEW_EXT_rescale_normal = GL_FALSE; +GLboolean __GLEW_EXT_scene_marker = GL_FALSE; +GLboolean __GLEW_EXT_secondary_color = GL_FALSE; +GLboolean __GLEW_EXT_separate_specular_color = GL_FALSE; +GLboolean __GLEW_EXT_shadow_funcs = GL_FALSE; +GLboolean __GLEW_EXT_shared_texture_palette = GL_FALSE; +GLboolean __GLEW_EXT_stencil_clear_tag = GL_FALSE; +GLboolean __GLEW_EXT_stencil_two_side = GL_FALSE; +GLboolean __GLEW_EXT_stencil_wrap = GL_FALSE; +GLboolean __GLEW_EXT_subtexture = GL_FALSE; +GLboolean __GLEW_EXT_texture = GL_FALSE; +GLboolean __GLEW_EXT_texture3D = GL_FALSE; +GLboolean __GLEW_EXT_texture_compression_dxt1 = GL_FALSE; +GLboolean __GLEW_EXT_texture_compression_s3tc = GL_FALSE; +GLboolean __GLEW_EXT_texture_cube_map = GL_FALSE; +GLboolean __GLEW_EXT_texture_edge_clamp = GL_FALSE; +GLboolean __GLEW_EXT_texture_env = GL_FALSE; +GLboolean __GLEW_EXT_texture_env_add = GL_FALSE; +GLboolean __GLEW_EXT_texture_env_combine = GL_FALSE; +GLboolean __GLEW_EXT_texture_env_dot3 = GL_FALSE; +GLboolean __GLEW_EXT_texture_filter_anisotropic = GL_FALSE; +GLboolean __GLEW_EXT_texture_lod_bias = GL_FALSE; +GLboolean __GLEW_EXT_texture_mirror_clamp = GL_FALSE; +GLboolean __GLEW_EXT_texture_object = GL_FALSE; +GLboolean __GLEW_EXT_texture_perturb_normal = GL_FALSE; +GLboolean __GLEW_EXT_texture_rectangle = GL_FALSE; +GLboolean __GLEW_EXT_texture_sRGB = GL_FALSE; +GLboolean __GLEW_EXT_vertex_array = GL_FALSE; +GLboolean __GLEW_EXT_vertex_shader = GL_FALSE; +GLboolean __GLEW_EXT_vertex_weighting = GL_FALSE; +GLboolean __GLEW_GREMEDY_string_marker = GL_FALSE; +GLboolean __GLEW_HP_convolution_border_modes = GL_FALSE; +GLboolean __GLEW_HP_image_transform = GL_FALSE; +GLboolean __GLEW_HP_occlusion_test = GL_FALSE; +GLboolean __GLEW_HP_texture_lighting = GL_FALSE; +GLboolean __GLEW_IBM_cull_vertex = GL_FALSE; +GLboolean __GLEW_IBM_multimode_draw_arrays = GL_FALSE; +GLboolean __GLEW_IBM_rasterpos_clip = GL_FALSE; +GLboolean __GLEW_IBM_static_data = GL_FALSE; +GLboolean __GLEW_IBM_texture_mirrored_repeat = GL_FALSE; +GLboolean __GLEW_IBM_vertex_array_lists = GL_FALSE; +GLboolean __GLEW_INGR_color_clamp = GL_FALSE; +GLboolean __GLEW_INGR_interlace_read = GL_FALSE; +GLboolean __GLEW_INTEL_parallel_arrays = GL_FALSE; +GLboolean __GLEW_INTEL_texture_scissor = GL_FALSE; +GLboolean __GLEW_KTX_buffer_region = GL_FALSE; +GLboolean __GLEW_MESAX_texture_stack = GL_FALSE; +GLboolean __GLEW_MESA_pack_invert = GL_FALSE; +GLboolean __GLEW_MESA_resize_buffers = GL_FALSE; +GLboolean __GLEW_MESA_window_pos = GL_FALSE; +GLboolean __GLEW_MESA_ycbcr_texture = GL_FALSE; +GLboolean __GLEW_NV_blend_square = GL_FALSE; +GLboolean __GLEW_NV_copy_depth_to_color = GL_FALSE; +GLboolean __GLEW_NV_depth_clamp = GL_FALSE; +GLboolean __GLEW_NV_evaluators = GL_FALSE; +GLboolean __GLEW_NV_fence = GL_FALSE; +GLboolean __GLEW_NV_float_buffer = GL_FALSE; +GLboolean __GLEW_NV_fog_distance = GL_FALSE; +GLboolean __GLEW_NV_fragment_program = GL_FALSE; +GLboolean __GLEW_NV_fragment_program2 = GL_FALSE; +GLboolean __GLEW_NV_fragment_program_option = GL_FALSE; +GLboolean __GLEW_NV_half_float = GL_FALSE; +GLboolean __GLEW_NV_light_max_exponent = GL_FALSE; +GLboolean __GLEW_NV_multisample_filter_hint = GL_FALSE; +GLboolean __GLEW_NV_occlusion_query = GL_FALSE; +GLboolean __GLEW_NV_packed_depth_stencil = GL_FALSE; +GLboolean __GLEW_NV_pixel_data_range = GL_FALSE; +GLboolean __GLEW_NV_point_sprite = GL_FALSE; +GLboolean __GLEW_NV_primitive_restart = GL_FALSE; +GLboolean __GLEW_NV_register_combiners = GL_FALSE; +GLboolean __GLEW_NV_register_combiners2 = GL_FALSE; +GLboolean __GLEW_NV_texgen_emboss = GL_FALSE; +GLboolean __GLEW_NV_texgen_reflection = GL_FALSE; +GLboolean __GLEW_NV_texture_compression_vtc = GL_FALSE; +GLboolean __GLEW_NV_texture_env_combine4 = GL_FALSE; +GLboolean __GLEW_NV_texture_expand_normal = GL_FALSE; +GLboolean __GLEW_NV_texture_rectangle = GL_FALSE; +GLboolean __GLEW_NV_texture_shader = GL_FALSE; +GLboolean __GLEW_NV_texture_shader2 = GL_FALSE; +GLboolean __GLEW_NV_texture_shader3 = GL_FALSE; +GLboolean __GLEW_NV_vertex_array_range = GL_FALSE; +GLboolean __GLEW_NV_vertex_array_range2 = GL_FALSE; +GLboolean __GLEW_NV_vertex_program = GL_FALSE; +GLboolean __GLEW_NV_vertex_program1_1 = GL_FALSE; +GLboolean __GLEW_NV_vertex_program2 = GL_FALSE; +GLboolean __GLEW_NV_vertex_program2_option = GL_FALSE; +GLboolean __GLEW_NV_vertex_program3 = GL_FALSE; +GLboolean __GLEW_OML_interlace = GL_FALSE; +GLboolean __GLEW_OML_resample = GL_FALSE; +GLboolean __GLEW_OML_subsample = GL_FALSE; +GLboolean __GLEW_PGI_misc_hints = GL_FALSE; +GLboolean __GLEW_PGI_vertex_hints = GL_FALSE; +GLboolean __GLEW_REND_screen_coordinates = GL_FALSE; +GLboolean __GLEW_S3_s3tc = GL_FALSE; +GLboolean __GLEW_SGIS_color_range = GL_FALSE; +GLboolean __GLEW_SGIS_detail_texture = GL_FALSE; +GLboolean __GLEW_SGIS_fog_function = GL_FALSE; +GLboolean __GLEW_SGIS_generate_mipmap = GL_FALSE; +GLboolean __GLEW_SGIS_multisample = GL_FALSE; +GLboolean __GLEW_SGIS_pixel_texture = GL_FALSE; +GLboolean __GLEW_SGIS_sharpen_texture = GL_FALSE; +GLboolean __GLEW_SGIS_texture4D = GL_FALSE; +GLboolean __GLEW_SGIS_texture_border_clamp = GL_FALSE; +GLboolean __GLEW_SGIS_texture_edge_clamp = GL_FALSE; +GLboolean __GLEW_SGIS_texture_filter4 = GL_FALSE; +GLboolean __GLEW_SGIS_texture_lod = GL_FALSE; +GLboolean __GLEW_SGIS_texture_select = GL_FALSE; +GLboolean __GLEW_SGIX_async = GL_FALSE; +GLboolean __GLEW_SGIX_async_histogram = GL_FALSE; +GLboolean __GLEW_SGIX_async_pixel = GL_FALSE; +GLboolean __GLEW_SGIX_blend_alpha_minmax = GL_FALSE; +GLboolean __GLEW_SGIX_clipmap = GL_FALSE; +GLboolean __GLEW_SGIX_depth_texture = GL_FALSE; +GLboolean __GLEW_SGIX_flush_raster = GL_FALSE; +GLboolean __GLEW_SGIX_fog_offset = GL_FALSE; +GLboolean __GLEW_SGIX_fog_texture = GL_FALSE; +GLboolean __GLEW_SGIX_fragment_specular_lighting = GL_FALSE; +GLboolean __GLEW_SGIX_framezoom = GL_FALSE; +GLboolean __GLEW_SGIX_interlace = GL_FALSE; +GLboolean __GLEW_SGIX_ir_instrument1 = GL_FALSE; +GLboolean __GLEW_SGIX_list_priority = GL_FALSE; +GLboolean __GLEW_SGIX_pixel_texture = GL_FALSE; +GLboolean __GLEW_SGIX_pixel_texture_bits = GL_FALSE; +GLboolean __GLEW_SGIX_reference_plane = GL_FALSE; +GLboolean __GLEW_SGIX_resample = GL_FALSE; +GLboolean __GLEW_SGIX_shadow = GL_FALSE; +GLboolean __GLEW_SGIX_shadow_ambient = GL_FALSE; +GLboolean __GLEW_SGIX_sprite = GL_FALSE; +GLboolean __GLEW_SGIX_tag_sample_buffer = GL_FALSE; +GLboolean __GLEW_SGIX_texture_add_env = GL_FALSE; +GLboolean __GLEW_SGIX_texture_coordinate_clamp = GL_FALSE; +GLboolean __GLEW_SGIX_texture_lod_bias = GL_FALSE; +GLboolean __GLEW_SGIX_texture_multi_buffer = GL_FALSE; +GLboolean __GLEW_SGIX_texture_range = GL_FALSE; +GLboolean __GLEW_SGIX_texture_scale_bias = GL_FALSE; +GLboolean __GLEW_SGIX_vertex_preclip = GL_FALSE; +GLboolean __GLEW_SGIX_vertex_preclip_hint = GL_FALSE; +GLboolean __GLEW_SGIX_ycrcb = GL_FALSE; +GLboolean __GLEW_SGI_color_matrix = GL_FALSE; +GLboolean __GLEW_SGI_color_table = GL_FALSE; +GLboolean __GLEW_SGI_texture_color_table = GL_FALSE; +GLboolean __GLEW_SUNX_constant_data = GL_FALSE; +GLboolean __GLEW_SUN_convolution_border_modes = GL_FALSE; +GLboolean __GLEW_SUN_global_alpha = GL_FALSE; +GLboolean __GLEW_SUN_mesh_array = GL_FALSE; +GLboolean __GLEW_SUN_read_video_pixels = GL_FALSE; +GLboolean __GLEW_SUN_slice_accum = GL_FALSE; +GLboolean __GLEW_SUN_triangle_list = GL_FALSE; +GLboolean __GLEW_SUN_vertex = GL_FALSE; +GLboolean __GLEW_WIN_phong_shading = GL_FALSE; +GLboolean __GLEW_WIN_specular_fog = GL_FALSE; +GLboolean __GLEW_WIN_swap_hint = GL_FALSE; + +#endif /* !GLEW_MX */ + +#ifdef GL_VERSION_1_2 + +static GLboolean _glewInit_GL_VERSION_1_2 (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glCopyTexSubImage3D = (PFNGLCOPYTEXSUBIMAGE3DPROC)glewGetProcAddress((const GLubyte*)"glCopyTexSubImage3D")) == NULL) || r; + r = ((glDrawRangeElements = (PFNGLDRAWRANGEELEMENTSPROC)glewGetProcAddress((const GLubyte*)"glDrawRangeElements")) == NULL) || r; + r = ((glTexImage3D = (PFNGLTEXIMAGE3DPROC)glewGetProcAddress((const GLubyte*)"glTexImage3D")) == NULL) || r; + r = ((glTexSubImage3D = (PFNGLTEXSUBIMAGE3DPROC)glewGetProcAddress((const GLubyte*)"glTexSubImage3D")) == NULL) || r; + + return r; +} + +#endif /* GL_VERSION_1_2 */ + +#ifdef GL_VERSION_1_3 + +static GLboolean _glewInit_GL_VERSION_1_3 (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glActiveTexture = (PFNGLACTIVETEXTUREPROC)glewGetProcAddress((const GLubyte*)"glActiveTexture")) == NULL) || r; + r = ((glClientActiveTexture = (PFNGLCLIENTACTIVETEXTUREPROC)glewGetProcAddress((const GLubyte*)"glClientActiveTexture")) == NULL) || r; + r = ((glCompressedTexImage1D = (PFNGLCOMPRESSEDTEXIMAGE1DPROC)glewGetProcAddress((const GLubyte*)"glCompressedTexImage1D")) == NULL) || r; + r = ((glCompressedTexImage2D = (PFNGLCOMPRESSEDTEXIMAGE2DPROC)glewGetProcAddress((const GLubyte*)"glCompressedTexImage2D")) == NULL) || r; + r = ((glCompressedTexImage3D = (PFNGLCOMPRESSEDTEXIMAGE3DPROC)glewGetProcAddress((const GLubyte*)"glCompressedTexImage3D")) == NULL) || r; + r = ((glCompressedTexSubImage1D = (PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC)glewGetProcAddress((const GLubyte*)"glCompressedTexSubImage1D")) == NULL) || r; + r = ((glCompressedTexSubImage2D = (PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC)glewGetProcAddress((const GLubyte*)"glCompressedTexSubImage2D")) == NULL) || r; + r = ((glCompressedTexSubImage3D = (PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC)glewGetProcAddress((const GLubyte*)"glCompressedTexSubImage3D")) == NULL) || r; + r = ((glGetCompressedTexImage = (PFNGLGETCOMPRESSEDTEXIMAGEPROC)glewGetProcAddress((const GLubyte*)"glGetCompressedTexImage")) == NULL) || r; + r = ((glLoadTransposeMatrixd = (PFNGLLOADTRANSPOSEMATRIXDPROC)glewGetProcAddress((const GLubyte*)"glLoadTransposeMatrixd")) == NULL) || r; + r = ((glLoadTransposeMatrixf = (PFNGLLOADTRANSPOSEMATRIXFPROC)glewGetProcAddress((const GLubyte*)"glLoadTransposeMatrixf")) == NULL) || r; + r = ((glMultTransposeMatrixd = (PFNGLMULTTRANSPOSEMATRIXDPROC)glewGetProcAddress((const GLubyte*)"glMultTransposeMatrixd")) == NULL) || r; + r = ((glMultTransposeMatrixf = (PFNGLMULTTRANSPOSEMATRIXFPROC)glewGetProcAddress((const GLubyte*)"glMultTransposeMatrixf")) == NULL) || r; + r = ((glMultiTexCoord1d = (PFNGLMULTITEXCOORD1DPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord1d")) == NULL) || r; + r = ((glMultiTexCoord1dv = (PFNGLMULTITEXCOORD1DVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord1dv")) == NULL) || r; + r = ((glMultiTexCoord1f = (PFNGLMULTITEXCOORD1FPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord1f")) == NULL) || r; + r = ((glMultiTexCoord1fv = (PFNGLMULTITEXCOORD1FVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord1fv")) == NULL) || r; + r = ((glMultiTexCoord1i = (PFNGLMULTITEXCOORD1IPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord1i")) == NULL) || r; + r = ((glMultiTexCoord1iv = (PFNGLMULTITEXCOORD1IVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord1iv")) == NULL) || r; + r = ((glMultiTexCoord1s = (PFNGLMULTITEXCOORD1SPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord1s")) == NULL) || r; + r = ((glMultiTexCoord1sv = (PFNGLMULTITEXCOORD1SVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord1sv")) == NULL) || r; + r = ((glMultiTexCoord2d = (PFNGLMULTITEXCOORD2DPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord2d")) == NULL) || r; + r = ((glMultiTexCoord2dv = (PFNGLMULTITEXCOORD2DVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord2dv")) == NULL) || r; + r = ((glMultiTexCoord2f = (PFNGLMULTITEXCOORD2FPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord2f")) == NULL) || r; + r = ((glMultiTexCoord2fv = (PFNGLMULTITEXCOORD2FVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord2fv")) == NULL) || r; + r = ((glMultiTexCoord2i = (PFNGLMULTITEXCOORD2IPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord2i")) == NULL) || r; + r = ((glMultiTexCoord2iv = (PFNGLMULTITEXCOORD2IVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord2iv")) == NULL) || r; + r = ((glMultiTexCoord2s = (PFNGLMULTITEXCOORD2SPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord2s")) == NULL) || r; + r = ((glMultiTexCoord2sv = (PFNGLMULTITEXCOORD2SVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord2sv")) == NULL) || r; + r = ((glMultiTexCoord3d = (PFNGLMULTITEXCOORD3DPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord3d")) == NULL) || r; + r = ((glMultiTexCoord3dv = (PFNGLMULTITEXCOORD3DVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord3dv")) == NULL) || r; + r = ((glMultiTexCoord3f = (PFNGLMULTITEXCOORD3FPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord3f")) == NULL) || r; + r = ((glMultiTexCoord3fv = (PFNGLMULTITEXCOORD3FVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord3fv")) == NULL) || r; + r = ((glMultiTexCoord3i = (PFNGLMULTITEXCOORD3IPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord3i")) == NULL) || r; + r = ((glMultiTexCoord3iv = (PFNGLMULTITEXCOORD3IVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord3iv")) == NULL) || r; + r = ((glMultiTexCoord3s = (PFNGLMULTITEXCOORD3SPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord3s")) == NULL) || r; + r = ((glMultiTexCoord3sv = (PFNGLMULTITEXCOORD3SVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord3sv")) == NULL) || r; + r = ((glMultiTexCoord4d = (PFNGLMULTITEXCOORD4DPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord4d")) == NULL) || r; + r = ((glMultiTexCoord4dv = (PFNGLMULTITEXCOORD4DVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord4dv")) == NULL) || r; + r = ((glMultiTexCoord4f = (PFNGLMULTITEXCOORD4FPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord4f")) == NULL) || r; + r = ((glMultiTexCoord4fv = (PFNGLMULTITEXCOORD4FVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord4fv")) == NULL) || r; + r = ((glMultiTexCoord4i = (PFNGLMULTITEXCOORD4IPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord4i")) == NULL) || r; + r = ((glMultiTexCoord4iv = (PFNGLMULTITEXCOORD4IVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord4iv")) == NULL) || r; + r = ((glMultiTexCoord4s = (PFNGLMULTITEXCOORD4SPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord4s")) == NULL) || r; + r = ((glMultiTexCoord4sv = (PFNGLMULTITEXCOORD4SVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord4sv")) == NULL) || r; + r = ((glSampleCoverage = (PFNGLSAMPLECOVERAGEPROC)glewGetProcAddress((const GLubyte*)"glSampleCoverage")) == NULL) || r; + + return r; +} + +#endif /* GL_VERSION_1_3 */ + +#ifdef GL_VERSION_1_4 + +static GLboolean _glewInit_GL_VERSION_1_4 (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glBlendColor = (PFNGLBLENDCOLORPROC)glewGetProcAddress((const GLubyte*)"glBlendColor")) == NULL) || r; + r = ((glBlendEquation = (PFNGLBLENDEQUATIONPROC)glewGetProcAddress((const GLubyte*)"glBlendEquation")) == NULL) || r; + r = ((glBlendFuncSeparate = (PFNGLBLENDFUNCSEPARATEPROC)glewGetProcAddress((const GLubyte*)"glBlendFuncSeparate")) == NULL) || r; + r = ((glFogCoordPointer = (PFNGLFOGCOORDPOINTERPROC)glewGetProcAddress((const GLubyte*)"glFogCoordPointer")) == NULL) || r; + r = ((glFogCoordd = (PFNGLFOGCOORDDPROC)glewGetProcAddress((const GLubyte*)"glFogCoordd")) == NULL) || r; + r = ((glFogCoorddv = (PFNGLFOGCOORDDVPROC)glewGetProcAddress((const GLubyte*)"glFogCoorddv")) == NULL) || r; + r = ((glFogCoordf = (PFNGLFOGCOORDFPROC)glewGetProcAddress((const GLubyte*)"glFogCoordf")) == NULL) || r; + r = ((glFogCoordfv = (PFNGLFOGCOORDFVPROC)glewGetProcAddress((const GLubyte*)"glFogCoordfv")) == NULL) || r; + r = ((glMultiDrawArrays = (PFNGLMULTIDRAWARRAYSPROC)glewGetProcAddress((const GLubyte*)"glMultiDrawArrays")) == NULL) || r; + r = ((glMultiDrawElements = (PFNGLMULTIDRAWELEMENTSPROC)glewGetProcAddress((const GLubyte*)"glMultiDrawElements")) == NULL) || r; + r = ((glPointParameterf = (PFNGLPOINTPARAMETERFPROC)glewGetProcAddress((const GLubyte*)"glPointParameterf")) == NULL) || r; + r = ((glPointParameterfv = (PFNGLPOINTPARAMETERFVPROC)glewGetProcAddress((const GLubyte*)"glPointParameterfv")) == NULL) || r; + r = ((glSecondaryColor3b = (PFNGLSECONDARYCOLOR3BPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3b")) == NULL) || r; + r = ((glSecondaryColor3bv = (PFNGLSECONDARYCOLOR3BVPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3bv")) == NULL) || r; + r = ((glSecondaryColor3d = (PFNGLSECONDARYCOLOR3DPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3d")) == NULL) || r; + r = ((glSecondaryColor3dv = (PFNGLSECONDARYCOLOR3DVPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3dv")) == NULL) || r; + r = ((glSecondaryColor3f = (PFNGLSECONDARYCOLOR3FPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3f")) == NULL) || r; + r = ((glSecondaryColor3fv = (PFNGLSECONDARYCOLOR3FVPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3fv")) == NULL) || r; + r = ((glSecondaryColor3i = (PFNGLSECONDARYCOLOR3IPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3i")) == NULL) || r; + r = ((glSecondaryColor3iv = (PFNGLSECONDARYCOLOR3IVPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3iv")) == NULL) || r; + r = ((glSecondaryColor3s = (PFNGLSECONDARYCOLOR3SPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3s")) == NULL) || r; + r = ((glSecondaryColor3sv = (PFNGLSECONDARYCOLOR3SVPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3sv")) == NULL) || r; + r = ((glSecondaryColor3ub = (PFNGLSECONDARYCOLOR3UBPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3ub")) == NULL) || r; + r = ((glSecondaryColor3ubv = (PFNGLSECONDARYCOLOR3UBVPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3ubv")) == NULL) || r; + r = ((glSecondaryColor3ui = (PFNGLSECONDARYCOLOR3UIPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3ui")) == NULL) || r; + r = ((glSecondaryColor3uiv = (PFNGLSECONDARYCOLOR3UIVPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3uiv")) == NULL) || r; + r = ((glSecondaryColor3us = (PFNGLSECONDARYCOLOR3USPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3us")) == NULL) || r; + r = ((glSecondaryColor3usv = (PFNGLSECONDARYCOLOR3USVPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3usv")) == NULL) || r; + r = ((glSecondaryColorPointer = (PFNGLSECONDARYCOLORPOINTERPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColorPointer")) == NULL) || r; + r = ((glWindowPos2d = (PFNGLWINDOWPOS2DPROC)glewGetProcAddress((const GLubyte*)"glWindowPos2d")) == NULL) || r; + r = ((glWindowPos2dv = (PFNGLWINDOWPOS2DVPROC)glewGetProcAddress((const GLubyte*)"glWindowPos2dv")) == NULL) || r; + r = ((glWindowPos2f = (PFNGLWINDOWPOS2FPROC)glewGetProcAddress((const GLubyte*)"glWindowPos2f")) == NULL) || r; + r = ((glWindowPos2fv = (PFNGLWINDOWPOS2FVPROC)glewGetProcAddress((const GLubyte*)"glWindowPos2fv")) == NULL) || r; + r = ((glWindowPos2i = (PFNGLWINDOWPOS2IPROC)glewGetProcAddress((const GLubyte*)"glWindowPos2i")) == NULL) || r; + r = ((glWindowPos2iv = (PFNGLWINDOWPOS2IVPROC)glewGetProcAddress((const GLubyte*)"glWindowPos2iv")) == NULL) || r; + r = ((glWindowPos2s = (PFNGLWINDOWPOS2SPROC)glewGetProcAddress((const GLubyte*)"glWindowPos2s")) == NULL) || r; + r = ((glWindowPos2sv = (PFNGLWINDOWPOS2SVPROC)glewGetProcAddress((const GLubyte*)"glWindowPos2sv")) == NULL) || r; + r = ((glWindowPos3d = (PFNGLWINDOWPOS3DPROC)glewGetProcAddress((const GLubyte*)"glWindowPos3d")) == NULL) || r; + r = ((glWindowPos3dv = (PFNGLWINDOWPOS3DVPROC)glewGetProcAddress((const GLubyte*)"glWindowPos3dv")) == NULL) || r; + r = ((glWindowPos3f = (PFNGLWINDOWPOS3FPROC)glewGetProcAddress((const GLubyte*)"glWindowPos3f")) == NULL) || r; + r = ((glWindowPos3fv = (PFNGLWINDOWPOS3FVPROC)glewGetProcAddress((const GLubyte*)"glWindowPos3fv")) == NULL) || r; + r = ((glWindowPos3i = (PFNGLWINDOWPOS3IPROC)glewGetProcAddress((const GLubyte*)"glWindowPos3i")) == NULL) || r; + r = ((glWindowPos3iv = (PFNGLWINDOWPOS3IVPROC)glewGetProcAddress((const GLubyte*)"glWindowPos3iv")) == NULL) || r; + r = ((glWindowPos3s = (PFNGLWINDOWPOS3SPROC)glewGetProcAddress((const GLubyte*)"glWindowPos3s")) == NULL) || r; + r = ((glWindowPos3sv = (PFNGLWINDOWPOS3SVPROC)glewGetProcAddress((const GLubyte*)"glWindowPos3sv")) == NULL) || r; + + return r; +} + +#endif /* GL_VERSION_1_4 */ + +#ifdef GL_VERSION_1_5 + +static GLboolean _glewInit_GL_VERSION_1_5 (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glBeginQuery = (PFNGLBEGINQUERYPROC)glewGetProcAddress((const GLubyte*)"glBeginQuery")) == NULL) || r; + r = ((glBindBuffer = (PFNGLBINDBUFFERPROC)glewGetProcAddress((const GLubyte*)"glBindBuffer")) == NULL) || r; + r = ((glBufferData = (PFNGLBUFFERDATAPROC)glewGetProcAddress((const GLubyte*)"glBufferData")) == NULL) || r; + r = ((glBufferSubData = (PFNGLBUFFERSUBDATAPROC)glewGetProcAddress((const GLubyte*)"glBufferSubData")) == NULL) || r; + r = ((glDeleteBuffers = (PFNGLDELETEBUFFERSPROC)glewGetProcAddress((const GLubyte*)"glDeleteBuffers")) == NULL) || r; + r = ((glDeleteQueries = (PFNGLDELETEQUERIESPROC)glewGetProcAddress((const GLubyte*)"glDeleteQueries")) == NULL) || r; + r = ((glEndQuery = (PFNGLENDQUERYPROC)glewGetProcAddress((const GLubyte*)"glEndQuery")) == NULL) || r; + r = ((glGenBuffers = (PFNGLGENBUFFERSPROC)glewGetProcAddress((const GLubyte*)"glGenBuffers")) == NULL) || r; + r = ((glGenQueries = (PFNGLGENQUERIESPROC)glewGetProcAddress((const GLubyte*)"glGenQueries")) == NULL) || r; + r = ((glGetBufferParameteriv = (PFNGLGETBUFFERPARAMETERIVPROC)glewGetProcAddress((const GLubyte*)"glGetBufferParameteriv")) == NULL) || r; + r = ((glGetBufferPointerv = (PFNGLGETBUFFERPOINTERVPROC)glewGetProcAddress((const GLubyte*)"glGetBufferPointerv")) == NULL) || r; + r = ((glGetBufferSubData = (PFNGLGETBUFFERSUBDATAPROC)glewGetProcAddress((const GLubyte*)"glGetBufferSubData")) == NULL) || r; + r = ((glGetQueryObjectiv = (PFNGLGETQUERYOBJECTIVPROC)glewGetProcAddress((const GLubyte*)"glGetQueryObjectiv")) == NULL) || r; + r = ((glGetQueryObjectuiv = (PFNGLGETQUERYOBJECTUIVPROC)glewGetProcAddress((const GLubyte*)"glGetQueryObjectuiv")) == NULL) || r; + r = ((glGetQueryiv = (PFNGLGETQUERYIVPROC)glewGetProcAddress((const GLubyte*)"glGetQueryiv")) == NULL) || r; + r = ((glIsBuffer = (PFNGLISBUFFERPROC)glewGetProcAddress((const GLubyte*)"glIsBuffer")) == NULL) || r; + r = ((glIsQuery = (PFNGLISQUERYPROC)glewGetProcAddress((const GLubyte*)"glIsQuery")) == NULL) || r; + r = ((glMapBuffer = (PFNGLMAPBUFFERPROC)glewGetProcAddress((const GLubyte*)"glMapBuffer")) == NULL) || r; + r = ((glUnmapBuffer = (PFNGLUNMAPBUFFERPROC)glewGetProcAddress((const GLubyte*)"glUnmapBuffer")) == NULL) || r; + + return r; +} + +#endif /* GL_VERSION_1_5 */ + +#ifdef GL_VERSION_2_0 + +static GLboolean _glewInit_GL_VERSION_2_0 (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glAttachShader = (PFNGLATTACHSHADERPROC)glewGetProcAddress((const GLubyte*)"glAttachShader")) == NULL) || r; + r = ((glBindAttribLocation = (PFNGLBINDATTRIBLOCATIONPROC)glewGetProcAddress((const GLubyte*)"glBindAttribLocation")) == NULL) || r; + r = ((glBlendEquationSeparate = (PFNGLBLENDEQUATIONSEPARATEPROC)glewGetProcAddress((const GLubyte*)"glBlendEquationSeparate")) == NULL) || r; + r = ((glCompileShader = (PFNGLCOMPILESHADERPROC)glewGetProcAddress((const GLubyte*)"glCompileShader")) == NULL) || r; + r = ((glCreateProgram = (PFNGLCREATEPROGRAMPROC)glewGetProcAddress((const GLubyte*)"glCreateProgram")) == NULL) || r; + r = ((glCreateShader = (PFNGLCREATESHADERPROC)glewGetProcAddress((const GLubyte*)"glCreateShader")) == NULL) || r; + r = ((glDeleteProgram = (PFNGLDELETEPROGRAMPROC)glewGetProcAddress((const GLubyte*)"glDeleteProgram")) == NULL) || r; + r = ((glDeleteShader = (PFNGLDELETESHADERPROC)glewGetProcAddress((const GLubyte*)"glDeleteShader")) == NULL) || r; + r = ((glDetachShader = (PFNGLDETACHSHADERPROC)glewGetProcAddress((const GLubyte*)"glDetachShader")) == NULL) || r; + r = ((glDisableVertexAttribArray = (PFNGLDISABLEVERTEXATTRIBARRAYPROC)glewGetProcAddress((const GLubyte*)"glDisableVertexAttribArray")) == NULL) || r; + r = ((glDrawBuffers = (PFNGLDRAWBUFFERSPROC)glewGetProcAddress((const GLubyte*)"glDrawBuffers")) == NULL) || r; + r = ((glEnableVertexAttribArray = (PFNGLENABLEVERTEXATTRIBARRAYPROC)glewGetProcAddress((const GLubyte*)"glEnableVertexAttribArray")) == NULL) || r; + r = ((glGetActiveAttrib = (PFNGLGETACTIVEATTRIBPROC)glewGetProcAddress((const GLubyte*)"glGetActiveAttrib")) == NULL) || r; + r = ((glGetActiveUniform = (PFNGLGETACTIVEUNIFORMPROC)glewGetProcAddress((const GLubyte*)"glGetActiveUniform")) == NULL) || r; + r = ((glGetAttachedShaders = (PFNGLGETATTACHEDSHADERSPROC)glewGetProcAddress((const GLubyte*)"glGetAttachedShaders")) == NULL) || r; + r = ((glGetAttribLocation = (PFNGLGETATTRIBLOCATIONPROC)glewGetProcAddress((const GLubyte*)"glGetAttribLocation")) == NULL) || r; + r = ((glGetProgramInfoLog = (PFNGLGETPROGRAMINFOLOGPROC)glewGetProcAddress((const GLubyte*)"glGetProgramInfoLog")) == NULL) || r; + r = ((glGetProgramiv = (PFNGLGETPROGRAMIVPROC)glewGetProcAddress((const GLubyte*)"glGetProgramiv")) == NULL) || r; + r = ((glGetShaderInfoLog = (PFNGLGETSHADERINFOLOGPROC)glewGetProcAddress((const GLubyte*)"glGetShaderInfoLog")) == NULL) || r; + r = ((glGetShaderSource = (PFNGLGETSHADERSOURCEPROC)glewGetProcAddress((const GLubyte*)"glGetShaderSource")) == NULL) || r; + r = ((glGetShaderiv = (PFNGLGETSHADERIVPROC)glewGetProcAddress((const GLubyte*)"glGetShaderiv")) == NULL) || r; + r = ((glGetUniformLocation = (PFNGLGETUNIFORMLOCATIONPROC)glewGetProcAddress((const GLubyte*)"glGetUniformLocation")) == NULL) || r; + r = ((glGetUniformfv = (PFNGLGETUNIFORMFVPROC)glewGetProcAddress((const GLubyte*)"glGetUniformfv")) == NULL) || r; + r = ((glGetUniformiv = (PFNGLGETUNIFORMIVPROC)glewGetProcAddress((const GLubyte*)"glGetUniformiv")) == NULL) || r; + r = ((glGetVertexAttribPointerv = (PFNGLGETVERTEXATTRIBPOINTERVPROC)glewGetProcAddress((const GLubyte*)"glGetVertexAttribPointerv")) == NULL) || r; + r = ((glGetVertexAttribdv = (PFNGLGETVERTEXATTRIBDVPROC)glewGetProcAddress((const GLubyte*)"glGetVertexAttribdv")) == NULL) || r; + r = ((glGetVertexAttribfv = (PFNGLGETVERTEXATTRIBFVPROC)glewGetProcAddress((const GLubyte*)"glGetVertexAttribfv")) == NULL) || r; + r = ((glGetVertexAttribiv = (PFNGLGETVERTEXATTRIBIVPROC)glewGetProcAddress((const GLubyte*)"glGetVertexAttribiv")) == NULL) || r; + r = ((glIsProgram = (PFNGLISPROGRAMPROC)glewGetProcAddress((const GLubyte*)"glIsProgram")) == NULL) || r; + r = ((glIsShader = (PFNGLISSHADERPROC)glewGetProcAddress((const GLubyte*)"glIsShader")) == NULL) || r; + r = ((glLinkProgram = (PFNGLLINKPROGRAMPROC)glewGetProcAddress((const GLubyte*)"glLinkProgram")) == NULL) || r; + r = ((glShaderSource = (PFNGLSHADERSOURCEPROC)glewGetProcAddress((const GLubyte*)"glShaderSource")) == NULL) || r; + r = ((glStencilFuncSeparate = (PFNGLSTENCILFUNCSEPARATEPROC)glewGetProcAddress((const GLubyte*)"glStencilFuncSeparate")) == NULL) || r; + r = ((glStencilMaskSeparate = (PFNGLSTENCILMASKSEPARATEPROC)glewGetProcAddress((const GLubyte*)"glStencilMaskSeparate")) == NULL) || r; + r = ((glStencilOpSeparate = (PFNGLSTENCILOPSEPARATEPROC)glewGetProcAddress((const GLubyte*)"glStencilOpSeparate")) == NULL) || r; + r = ((glUniform1f = (PFNGLUNIFORM1FPROC)glewGetProcAddress((const GLubyte*)"glUniform1f")) == NULL) || r; + r = ((glUniform1fv = (PFNGLUNIFORM1FVPROC)glewGetProcAddress((const GLubyte*)"glUniform1fv")) == NULL) || r; + r = ((glUniform1i = (PFNGLUNIFORM1IPROC)glewGetProcAddress((const GLubyte*)"glUniform1i")) == NULL) || r; + r = ((glUniform1iv = (PFNGLUNIFORM1IVPROC)glewGetProcAddress((const GLubyte*)"glUniform1iv")) == NULL) || r; + r = ((glUniform2f = (PFNGLUNIFORM2FPROC)glewGetProcAddress((const GLubyte*)"glUniform2f")) == NULL) || r; + r = ((glUniform2fv = (PFNGLUNIFORM2FVPROC)glewGetProcAddress((const GLubyte*)"glUniform2fv")) == NULL) || r; + r = ((glUniform2i = (PFNGLUNIFORM2IPROC)glewGetProcAddress((const GLubyte*)"glUniform2i")) == NULL) || r; + r = ((glUniform2iv = (PFNGLUNIFORM2IVPROC)glewGetProcAddress((const GLubyte*)"glUniform2iv")) == NULL) || r; + r = ((glUniform3f = (PFNGLUNIFORM3FPROC)glewGetProcAddress((const GLubyte*)"glUniform3f")) == NULL) || r; + r = ((glUniform3fv = (PFNGLUNIFORM3FVPROC)glewGetProcAddress((const GLubyte*)"glUniform3fv")) == NULL) || r; + r = ((glUniform3i = (PFNGLUNIFORM3IPROC)glewGetProcAddress((const GLubyte*)"glUniform3i")) == NULL) || r; + r = ((glUniform3iv = (PFNGLUNIFORM3IVPROC)glewGetProcAddress((const GLubyte*)"glUniform3iv")) == NULL) || r; + r = ((glUniform4f = (PFNGLUNIFORM4FPROC)glewGetProcAddress((const GLubyte*)"glUniform4f")) == NULL) || r; + r = ((glUniform4fv = (PFNGLUNIFORM4FVPROC)glewGetProcAddress((const GLubyte*)"glUniform4fv")) == NULL) || r; + r = ((glUniform4i = (PFNGLUNIFORM4IPROC)glewGetProcAddress((const GLubyte*)"glUniform4i")) == NULL) || r; + r = ((glUniform4iv = (PFNGLUNIFORM4IVPROC)glewGetProcAddress((const GLubyte*)"glUniform4iv")) == NULL) || r; + r = ((glUniformMatrix2fv = (PFNGLUNIFORMMATRIX2FVPROC)glewGetProcAddress((const GLubyte*)"glUniformMatrix2fv")) == NULL) || r; + r = ((glUniformMatrix3fv = (PFNGLUNIFORMMATRIX3FVPROC)glewGetProcAddress((const GLubyte*)"glUniformMatrix3fv")) == NULL) || r; + r = ((glUniformMatrix4fv = (PFNGLUNIFORMMATRIX4FVPROC)glewGetProcAddress((const GLubyte*)"glUniformMatrix4fv")) == NULL) || r; + r = ((glUseProgram = (PFNGLUSEPROGRAMPROC)glewGetProcAddress((const GLubyte*)"glUseProgram")) == NULL) || r; + r = ((glValidateProgram = (PFNGLVALIDATEPROGRAMPROC)glewGetProcAddress((const GLubyte*)"glValidateProgram")) == NULL) || r; + r = ((glVertexAttrib1d = (PFNGLVERTEXATTRIB1DPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib1d")) == NULL) || r; + r = ((glVertexAttrib1dv = (PFNGLVERTEXATTRIB1DVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib1dv")) == NULL) || r; + r = ((glVertexAttrib1f = (PFNGLVERTEXATTRIB1FPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib1f")) == NULL) || r; + r = ((glVertexAttrib1fv = (PFNGLVERTEXATTRIB1FVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib1fv")) == NULL) || r; + r = ((glVertexAttrib1s = (PFNGLVERTEXATTRIB1SPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib1s")) == NULL) || r; + r = ((glVertexAttrib1sv = (PFNGLVERTEXATTRIB1SVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib1sv")) == NULL) || r; + r = ((glVertexAttrib2d = (PFNGLVERTEXATTRIB2DPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib2d")) == NULL) || r; + r = ((glVertexAttrib2dv = (PFNGLVERTEXATTRIB2DVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib2dv")) == NULL) || r; + r = ((glVertexAttrib2f = (PFNGLVERTEXATTRIB2FPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib2f")) == NULL) || r; + r = ((glVertexAttrib2fv = (PFNGLVERTEXATTRIB2FVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib2fv")) == NULL) || r; + r = ((glVertexAttrib2s = (PFNGLVERTEXATTRIB2SPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib2s")) == NULL) || r; + r = ((glVertexAttrib2sv = (PFNGLVERTEXATTRIB2SVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib2sv")) == NULL) || r; + r = ((glVertexAttrib3d = (PFNGLVERTEXATTRIB3DPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib3d")) == NULL) || r; + r = ((glVertexAttrib3dv = (PFNGLVERTEXATTRIB3DVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib3dv")) == NULL) || r; + r = ((glVertexAttrib3f = (PFNGLVERTEXATTRIB3FPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib3f")) == NULL) || r; + r = ((glVertexAttrib3fv = (PFNGLVERTEXATTRIB3FVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib3fv")) == NULL) || r; + r = ((glVertexAttrib3s = (PFNGLVERTEXATTRIB3SPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib3s")) == NULL) || r; + r = ((glVertexAttrib3sv = (PFNGLVERTEXATTRIB3SVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib3sv")) == NULL) || r; + r = ((glVertexAttrib4Nbv = (PFNGLVERTEXATTRIB4NBVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4Nbv")) == NULL) || r; + r = ((glVertexAttrib4Niv = (PFNGLVERTEXATTRIB4NIVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4Niv")) == NULL) || r; + r = ((glVertexAttrib4Nsv = (PFNGLVERTEXATTRIB4NSVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4Nsv")) == NULL) || r; + r = ((glVertexAttrib4Nub = (PFNGLVERTEXATTRIB4NUBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4Nub")) == NULL) || r; + r = ((glVertexAttrib4Nubv = (PFNGLVERTEXATTRIB4NUBVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4Nubv")) == NULL) || r; + r = ((glVertexAttrib4Nuiv = (PFNGLVERTEXATTRIB4NUIVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4Nuiv")) == NULL) || r; + r = ((glVertexAttrib4Nusv = (PFNGLVERTEXATTRIB4NUSVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4Nusv")) == NULL) || r; + r = ((glVertexAttrib4bv = (PFNGLVERTEXATTRIB4BVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4bv")) == NULL) || r; + r = ((glVertexAttrib4d = (PFNGLVERTEXATTRIB4DPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4d")) == NULL) || r; + r = ((glVertexAttrib4dv = (PFNGLVERTEXATTRIB4DVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4dv")) == NULL) || r; + r = ((glVertexAttrib4f = (PFNGLVERTEXATTRIB4FPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4f")) == NULL) || r; + r = ((glVertexAttrib4fv = (PFNGLVERTEXATTRIB4FVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4fv")) == NULL) || r; + r = ((glVertexAttrib4iv = (PFNGLVERTEXATTRIB4IVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4iv")) == NULL) || r; + r = ((glVertexAttrib4s = (PFNGLVERTEXATTRIB4SPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4s")) == NULL) || r; + r = ((glVertexAttrib4sv = (PFNGLVERTEXATTRIB4SVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4sv")) == NULL) || r; + r = ((glVertexAttrib4ubv = (PFNGLVERTEXATTRIB4UBVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4ubv")) == NULL) || r; + r = ((glVertexAttrib4uiv = (PFNGLVERTEXATTRIB4UIVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4uiv")) == NULL) || r; + r = ((glVertexAttrib4usv = (PFNGLVERTEXATTRIB4USVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4usv")) == NULL) || r; + r = ((glVertexAttribPointer = (PFNGLVERTEXATTRIBPOINTERPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribPointer")) == NULL) || r; + + return r; +} + +#endif /* GL_VERSION_2_0 */ + +#ifdef GL_3DFX_multisample + +#endif /* GL_3DFX_multisample */ + +#ifdef GL_3DFX_tbuffer + +static GLboolean _glewInit_GL_3DFX_tbuffer (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glTbufferMask3DFX = (PFNGLTBUFFERMASK3DFXPROC)glewGetProcAddress((const GLubyte*)"glTbufferMask3DFX")) == NULL) || r; + + return r; +} + +#endif /* GL_3DFX_tbuffer */ + +#ifdef GL_3DFX_texture_compression_FXT1 + +#endif /* GL_3DFX_texture_compression_FXT1 */ + +#ifdef GL_APPLE_client_storage + +#endif /* GL_APPLE_client_storage */ + +#ifdef GL_APPLE_element_array + +static GLboolean _glewInit_GL_APPLE_element_array (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glDrawElementArrayAPPLE = (PFNGLDRAWELEMENTARRAYAPPLEPROC)glewGetProcAddress((const GLubyte*)"glDrawElementArrayAPPLE")) == NULL) || r; + r = ((glDrawRangeElementArrayAPPLE = (PFNGLDRAWRANGEELEMENTARRAYAPPLEPROC)glewGetProcAddress((const GLubyte*)"glDrawRangeElementArrayAPPLE")) == NULL) || r; + r = ((glElementPointerAPPLE = (PFNGLELEMENTPOINTERAPPLEPROC)glewGetProcAddress((const GLubyte*)"glElementPointerAPPLE")) == NULL) || r; + r = ((glMultiDrawElementArrayAPPLE = (PFNGLMULTIDRAWELEMENTARRAYAPPLEPROC)glewGetProcAddress((const GLubyte*)"glMultiDrawElementArrayAPPLE")) == NULL) || r; + r = ((glMultiDrawRangeElementArrayAPPLE = (PFNGLMULTIDRAWRANGEELEMENTARRAYAPPLEPROC)glewGetProcAddress((const GLubyte*)"glMultiDrawRangeElementArrayAPPLE")) == NULL) || r; + + return r; +} + +#endif /* GL_APPLE_element_array */ + +#ifdef GL_APPLE_fence + +static GLboolean _glewInit_GL_APPLE_fence (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glDeleteFencesAPPLE = (PFNGLDELETEFENCESAPPLEPROC)glewGetProcAddress((const GLubyte*)"glDeleteFencesAPPLE")) == NULL) || r; + r = ((glFinishFenceAPPLE = (PFNGLFINISHFENCEAPPLEPROC)glewGetProcAddress((const GLubyte*)"glFinishFenceAPPLE")) == NULL) || r; + r = ((glFinishObjectAPPLE = (PFNGLFINISHOBJECTAPPLEPROC)glewGetProcAddress((const GLubyte*)"glFinishObjectAPPLE")) == NULL) || r; + r = ((glGenFencesAPPLE = (PFNGLGENFENCESAPPLEPROC)glewGetProcAddress((const GLubyte*)"glGenFencesAPPLE")) == NULL) || r; + r = ((glIsFenceAPPLE = (PFNGLISFENCEAPPLEPROC)glewGetProcAddress((const GLubyte*)"glIsFenceAPPLE")) == NULL) || r; + r = ((glSetFenceAPPLE = (PFNGLSETFENCEAPPLEPROC)glewGetProcAddress((const GLubyte*)"glSetFenceAPPLE")) == NULL) || r; + r = ((glTestFenceAPPLE = (PFNGLTESTFENCEAPPLEPROC)glewGetProcAddress((const GLubyte*)"glTestFenceAPPLE")) == NULL) || r; + r = ((glTestObjectAPPLE = (PFNGLTESTOBJECTAPPLEPROC)glewGetProcAddress((const GLubyte*)"glTestObjectAPPLE")) == NULL) || r; + + return r; +} + +#endif /* GL_APPLE_fence */ + +#ifdef GL_APPLE_float_pixels + +#endif /* GL_APPLE_float_pixels */ + +#ifdef GL_APPLE_pixel_buffer + +#endif /* GL_APPLE_pixel_buffer */ + +#ifdef GL_APPLE_specular_vector + +#endif /* GL_APPLE_specular_vector */ + +#ifdef GL_APPLE_texture_range + +static GLboolean _glewInit_GL_APPLE_texture_range (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glGetTexParameterPointervAPPLE = (PFNGLGETTEXPARAMETERPOINTERVAPPLEPROC)glewGetProcAddress((const GLubyte*)"glGetTexParameterPointervAPPLE")) == NULL) || r; + r = ((glTextureRangeAPPLE = (PFNGLTEXTURERANGEAPPLEPROC)glewGetProcAddress((const GLubyte*)"glTextureRangeAPPLE")) == NULL) || r; + + return r; +} + +#endif /* GL_APPLE_texture_range */ + +#ifdef GL_APPLE_transform_hint + +#endif /* GL_APPLE_transform_hint */ + +#ifdef GL_APPLE_vertex_array_object + +static GLboolean _glewInit_GL_APPLE_vertex_array_object (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glBindVertexArrayAPPLE = (PFNGLBINDVERTEXARRAYAPPLEPROC)glewGetProcAddress((const GLubyte*)"glBindVertexArrayAPPLE")) == NULL) || r; + r = ((glDeleteVertexArraysAPPLE = (PFNGLDELETEVERTEXARRAYSAPPLEPROC)glewGetProcAddress((const GLubyte*)"glDeleteVertexArraysAPPLE")) == NULL) || r; + r = ((glGenVertexArraysAPPLE = (PFNGLGENVERTEXARRAYSAPPLEPROC)glewGetProcAddress((const GLubyte*)"glGenVertexArraysAPPLE")) == NULL) || r; + r = ((glIsVertexArrayAPPLE = (PFNGLISVERTEXARRAYAPPLEPROC)glewGetProcAddress((const GLubyte*)"glIsVertexArrayAPPLE")) == NULL) || r; + + return r; +} + +#endif /* GL_APPLE_vertex_array_object */ + +#ifdef GL_APPLE_vertex_array_range + +static GLboolean _glewInit_GL_APPLE_vertex_array_range (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glFlushVertexArrayRangeAPPLE = (PFNGLFLUSHVERTEXARRAYRANGEAPPLEPROC)glewGetProcAddress((const GLubyte*)"glFlushVertexArrayRangeAPPLE")) == NULL) || r; + r = ((glVertexArrayParameteriAPPLE = (PFNGLVERTEXARRAYPARAMETERIAPPLEPROC)glewGetProcAddress((const GLubyte*)"glVertexArrayParameteriAPPLE")) == NULL) || r; + r = ((glVertexArrayRangeAPPLE = (PFNGLVERTEXARRAYRANGEAPPLEPROC)glewGetProcAddress((const GLubyte*)"glVertexArrayRangeAPPLE")) == NULL) || r; + + return r; +} + +#endif /* GL_APPLE_vertex_array_range */ + +#ifdef GL_APPLE_ycbcr_422 + +#endif /* GL_APPLE_ycbcr_422 */ + +#ifdef GL_ARB_color_buffer_float + +static GLboolean _glewInit_GL_ARB_color_buffer_float (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glClampColorARB = (PFNGLCLAMPCOLORARBPROC)glewGetProcAddress((const GLubyte*)"glClampColorARB")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_color_buffer_float */ + +#ifdef GL_ARB_depth_texture + +#endif /* GL_ARB_depth_texture */ + +#ifdef GL_ARB_draw_buffers + +static GLboolean _glewInit_GL_ARB_draw_buffers (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glDrawBuffersARB = (PFNGLDRAWBUFFERSARBPROC)glewGetProcAddress((const GLubyte*)"glDrawBuffersARB")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_draw_buffers */ + +#ifdef GL_ARB_fragment_program + +#endif /* GL_ARB_fragment_program */ + +#ifdef GL_ARB_fragment_program_shadow + +#endif /* GL_ARB_fragment_program_shadow */ + +#ifdef GL_ARB_fragment_shader + +#endif /* GL_ARB_fragment_shader */ + +#ifdef GL_ARB_half_float_pixel + +#endif /* GL_ARB_half_float_pixel */ + +#ifdef GL_ARB_imaging + +static GLboolean _glewInit_GL_ARB_imaging (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glBlendEquation = (PFNGLBLENDEQUATIONPROC)glewGetProcAddress((const GLubyte*)"glBlendEquation")) == NULL) || r; + r = ((glColorSubTable = (PFNGLCOLORSUBTABLEPROC)glewGetProcAddress((const GLubyte*)"glColorSubTable")) == NULL) || r; + r = ((glColorTable = (PFNGLCOLORTABLEPROC)glewGetProcAddress((const GLubyte*)"glColorTable")) == NULL) || r; + r = ((glColorTableParameterfv = (PFNGLCOLORTABLEPARAMETERFVPROC)glewGetProcAddress((const GLubyte*)"glColorTableParameterfv")) == NULL) || r; + r = ((glColorTableParameteriv = (PFNGLCOLORTABLEPARAMETERIVPROC)glewGetProcAddress((const GLubyte*)"glColorTableParameteriv")) == NULL) || r; + r = ((glConvolutionFilter1D = (PFNGLCONVOLUTIONFILTER1DPROC)glewGetProcAddress((const GLubyte*)"glConvolutionFilter1D")) == NULL) || r; + r = ((glConvolutionFilter2D = (PFNGLCONVOLUTIONFILTER2DPROC)glewGetProcAddress((const GLubyte*)"glConvolutionFilter2D")) == NULL) || r; + r = ((glConvolutionParameterf = (PFNGLCONVOLUTIONPARAMETERFPROC)glewGetProcAddress((const GLubyte*)"glConvolutionParameterf")) == NULL) || r; + r = ((glConvolutionParameterfv = (PFNGLCONVOLUTIONPARAMETERFVPROC)glewGetProcAddress((const GLubyte*)"glConvolutionParameterfv")) == NULL) || r; + r = ((glConvolutionParameteri = (PFNGLCONVOLUTIONPARAMETERIPROC)glewGetProcAddress((const GLubyte*)"glConvolutionParameteri")) == NULL) || r; + r = ((glConvolutionParameteriv = (PFNGLCONVOLUTIONPARAMETERIVPROC)glewGetProcAddress((const GLubyte*)"glConvolutionParameteriv")) == NULL) || r; + r = ((glCopyColorSubTable = (PFNGLCOPYCOLORSUBTABLEPROC)glewGetProcAddress((const GLubyte*)"glCopyColorSubTable")) == NULL) || r; + r = ((glCopyColorTable = (PFNGLCOPYCOLORTABLEPROC)glewGetProcAddress((const GLubyte*)"glCopyColorTable")) == NULL) || r; + r = ((glCopyConvolutionFilter1D = (PFNGLCOPYCONVOLUTIONFILTER1DPROC)glewGetProcAddress((const GLubyte*)"glCopyConvolutionFilter1D")) == NULL) || r; + r = ((glCopyConvolutionFilter2D = (PFNGLCOPYCONVOLUTIONFILTER2DPROC)glewGetProcAddress((const GLubyte*)"glCopyConvolutionFilter2D")) == NULL) || r; + r = ((glGetColorTable = (PFNGLGETCOLORTABLEPROC)glewGetProcAddress((const GLubyte*)"glGetColorTable")) == NULL) || r; + r = ((glGetColorTableParameterfv = (PFNGLGETCOLORTABLEPARAMETERFVPROC)glewGetProcAddress((const GLubyte*)"glGetColorTableParameterfv")) == NULL) || r; + r = ((glGetColorTableParameteriv = (PFNGLGETCOLORTABLEPARAMETERIVPROC)glewGetProcAddress((const GLubyte*)"glGetColorTableParameteriv")) == NULL) || r; + r = ((glGetConvolutionFilter = (PFNGLGETCONVOLUTIONFILTERPROC)glewGetProcAddress((const GLubyte*)"glGetConvolutionFilter")) == NULL) || r; + r = ((glGetConvolutionParameterfv = (PFNGLGETCONVOLUTIONPARAMETERFVPROC)glewGetProcAddress((const GLubyte*)"glGetConvolutionParameterfv")) == NULL) || r; + r = ((glGetConvolutionParameteriv = (PFNGLGETCONVOLUTIONPARAMETERIVPROC)glewGetProcAddress((const GLubyte*)"glGetConvolutionParameteriv")) == NULL) || r; + r = ((glGetHistogram = (PFNGLGETHISTOGRAMPROC)glewGetProcAddress((const GLubyte*)"glGetHistogram")) == NULL) || r; + r = ((glGetHistogramParameterfv = (PFNGLGETHISTOGRAMPARAMETERFVPROC)glewGetProcAddress((const GLubyte*)"glGetHistogramParameterfv")) == NULL) || r; + r = ((glGetHistogramParameteriv = (PFNGLGETHISTOGRAMPARAMETERIVPROC)glewGetProcAddress((const GLubyte*)"glGetHistogramParameteriv")) == NULL) || r; + r = ((glGetMinmax = (PFNGLGETMINMAXPROC)glewGetProcAddress((const GLubyte*)"glGetMinmax")) == NULL) || r; + r = ((glGetMinmaxParameterfv = (PFNGLGETMINMAXPARAMETERFVPROC)glewGetProcAddress((const GLubyte*)"glGetMinmaxParameterfv")) == NULL) || r; + r = ((glGetMinmaxParameteriv = (PFNGLGETMINMAXPARAMETERIVPROC)glewGetProcAddress((const GLubyte*)"glGetMinmaxParameteriv")) == NULL) || r; + r = ((glGetSeparableFilter = (PFNGLGETSEPARABLEFILTERPROC)glewGetProcAddress((const GLubyte*)"glGetSeparableFilter")) == NULL) || r; + r = ((glHistogram = (PFNGLHISTOGRAMPROC)glewGetProcAddress((const GLubyte*)"glHistogram")) == NULL) || r; + r = ((glMinmax = (PFNGLMINMAXPROC)glewGetProcAddress((const GLubyte*)"glMinmax")) == NULL) || r; + r = ((glResetHistogram = (PFNGLRESETHISTOGRAMPROC)glewGetProcAddress((const GLubyte*)"glResetHistogram")) == NULL) || r; + r = ((glResetMinmax = (PFNGLRESETMINMAXPROC)glewGetProcAddress((const GLubyte*)"glResetMinmax")) == NULL) || r; + r = ((glSeparableFilter2D = (PFNGLSEPARABLEFILTER2DPROC)glewGetProcAddress((const GLubyte*)"glSeparableFilter2D")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_imaging */ + +#ifdef GL_ARB_matrix_palette + +static GLboolean _glewInit_GL_ARB_matrix_palette (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glCurrentPaletteMatrixARB = (PFNGLCURRENTPALETTEMATRIXARBPROC)glewGetProcAddress((const GLubyte*)"glCurrentPaletteMatrixARB")) == NULL) || r; + r = ((glMatrixIndexPointerARB = (PFNGLMATRIXINDEXPOINTERARBPROC)glewGetProcAddress((const GLubyte*)"glMatrixIndexPointerARB")) == NULL) || r; + r = ((glMatrixIndexubvARB = (PFNGLMATRIXINDEXUBVARBPROC)glewGetProcAddress((const GLubyte*)"glMatrixIndexubvARB")) == NULL) || r; + r = ((glMatrixIndexuivARB = (PFNGLMATRIXINDEXUIVARBPROC)glewGetProcAddress((const GLubyte*)"glMatrixIndexuivARB")) == NULL) || r; + r = ((glMatrixIndexusvARB = (PFNGLMATRIXINDEXUSVARBPROC)glewGetProcAddress((const GLubyte*)"glMatrixIndexusvARB")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_matrix_palette */ + +#ifdef GL_ARB_multisample + +static GLboolean _glewInit_GL_ARB_multisample (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glSampleCoverageARB = (PFNGLSAMPLECOVERAGEARBPROC)glewGetProcAddress((const GLubyte*)"glSampleCoverageARB")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_multisample */ + +#ifdef GL_ARB_multitexture + +static GLboolean _glewInit_GL_ARB_multitexture (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glActiveTextureARB = (PFNGLACTIVETEXTUREARBPROC)glewGetProcAddress((const GLubyte*)"glActiveTextureARB")) == NULL) || r; + r = ((glClientActiveTextureARB = (PFNGLCLIENTACTIVETEXTUREARBPROC)glewGetProcAddress((const GLubyte*)"glClientActiveTextureARB")) == NULL) || r; + r = ((glMultiTexCoord1dARB = (PFNGLMULTITEXCOORD1DARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord1dARB")) == NULL) || r; + r = ((glMultiTexCoord1dvARB = (PFNGLMULTITEXCOORD1DVARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord1dvARB")) == NULL) || r; + r = ((glMultiTexCoord1fARB = (PFNGLMULTITEXCOORD1FARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord1fARB")) == NULL) || r; + r = ((glMultiTexCoord1fvARB = (PFNGLMULTITEXCOORD1FVARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord1fvARB")) == NULL) || r; + r = ((glMultiTexCoord1iARB = (PFNGLMULTITEXCOORD1IARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord1iARB")) == NULL) || r; + r = ((glMultiTexCoord1ivARB = (PFNGLMULTITEXCOORD1IVARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord1ivARB")) == NULL) || r; + r = ((glMultiTexCoord1sARB = (PFNGLMULTITEXCOORD1SARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord1sARB")) == NULL) || r; + r = ((glMultiTexCoord1svARB = (PFNGLMULTITEXCOORD1SVARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord1svARB")) == NULL) || r; + r = ((glMultiTexCoord2dARB = (PFNGLMULTITEXCOORD2DARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord2dARB")) == NULL) || r; + r = ((glMultiTexCoord2dvARB = (PFNGLMULTITEXCOORD2DVARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord2dvARB")) == NULL) || r; + r = ((glMultiTexCoord2fARB = (PFNGLMULTITEXCOORD2FARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord2fARB")) == NULL) || r; + r = ((glMultiTexCoord2fvARB = (PFNGLMULTITEXCOORD2FVARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord2fvARB")) == NULL) || r; + r = ((glMultiTexCoord2iARB = (PFNGLMULTITEXCOORD2IARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord2iARB")) == NULL) || r; + r = ((glMultiTexCoord2ivARB = (PFNGLMULTITEXCOORD2IVARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord2ivARB")) == NULL) || r; + r = ((glMultiTexCoord2sARB = (PFNGLMULTITEXCOORD2SARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord2sARB")) == NULL) || r; + r = ((glMultiTexCoord2svARB = (PFNGLMULTITEXCOORD2SVARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord2svARB")) == NULL) || r; + r = ((glMultiTexCoord3dARB = (PFNGLMULTITEXCOORD3DARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord3dARB")) == NULL) || r; + r = ((glMultiTexCoord3dvARB = (PFNGLMULTITEXCOORD3DVARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord3dvARB")) == NULL) || r; + r = ((glMultiTexCoord3fARB = (PFNGLMULTITEXCOORD3FARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord3fARB")) == NULL) || r; + r = ((glMultiTexCoord3fvARB = (PFNGLMULTITEXCOORD3FVARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord3fvARB")) == NULL) || r; + r = ((glMultiTexCoord3iARB = (PFNGLMULTITEXCOORD3IARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord3iARB")) == NULL) || r; + r = ((glMultiTexCoord3ivARB = (PFNGLMULTITEXCOORD3IVARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord3ivARB")) == NULL) || r; + r = ((glMultiTexCoord3sARB = (PFNGLMULTITEXCOORD3SARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord3sARB")) == NULL) || r; + r = ((glMultiTexCoord3svARB = (PFNGLMULTITEXCOORD3SVARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord3svARB")) == NULL) || r; + r = ((glMultiTexCoord4dARB = (PFNGLMULTITEXCOORD4DARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord4dARB")) == NULL) || r; + r = ((glMultiTexCoord4dvARB = (PFNGLMULTITEXCOORD4DVARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord4dvARB")) == NULL) || r; + r = ((glMultiTexCoord4fARB = (PFNGLMULTITEXCOORD4FARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord4fARB")) == NULL) || r; + r = ((glMultiTexCoord4fvARB = (PFNGLMULTITEXCOORD4FVARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord4fvARB")) == NULL) || r; + r = ((glMultiTexCoord4iARB = (PFNGLMULTITEXCOORD4IARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord4iARB")) == NULL) || r; + r = ((glMultiTexCoord4ivARB = (PFNGLMULTITEXCOORD4IVARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord4ivARB")) == NULL) || r; + r = ((glMultiTexCoord4sARB = (PFNGLMULTITEXCOORD4SARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord4sARB")) == NULL) || r; + r = ((glMultiTexCoord4svARB = (PFNGLMULTITEXCOORD4SVARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord4svARB")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_multitexture */ + +#ifdef GL_ARB_occlusion_query + +static GLboolean _glewInit_GL_ARB_occlusion_query (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glBeginQueryARB = (PFNGLBEGINQUERYARBPROC)glewGetProcAddress((const GLubyte*)"glBeginQueryARB")) == NULL) || r; + r = ((glDeleteQueriesARB = (PFNGLDELETEQUERIESARBPROC)glewGetProcAddress((const GLubyte*)"glDeleteQueriesARB")) == NULL) || r; + r = ((glEndQueryARB = (PFNGLENDQUERYARBPROC)glewGetProcAddress((const GLubyte*)"glEndQueryARB")) == NULL) || r; + r = ((glGenQueriesARB = (PFNGLGENQUERIESARBPROC)glewGetProcAddress((const GLubyte*)"glGenQueriesARB")) == NULL) || r; + r = ((glGetQueryObjectivARB = (PFNGLGETQUERYOBJECTIVARBPROC)glewGetProcAddress((const GLubyte*)"glGetQueryObjectivARB")) == NULL) || r; + r = ((glGetQueryObjectuivARB = (PFNGLGETQUERYOBJECTUIVARBPROC)glewGetProcAddress((const GLubyte*)"glGetQueryObjectuivARB")) == NULL) || r; + r = ((glGetQueryivARB = (PFNGLGETQUERYIVARBPROC)glewGetProcAddress((const GLubyte*)"glGetQueryivARB")) == NULL) || r; + r = ((glIsQueryARB = (PFNGLISQUERYARBPROC)glewGetProcAddress((const GLubyte*)"glIsQueryARB")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_occlusion_query */ + +#ifdef GL_ARB_pixel_buffer_object + +#endif /* GL_ARB_pixel_buffer_object */ + +#ifdef GL_ARB_point_parameters + +static GLboolean _glewInit_GL_ARB_point_parameters (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glPointParameterfARB = (PFNGLPOINTPARAMETERFARBPROC)glewGetProcAddress((const GLubyte*)"glPointParameterfARB")) == NULL) || r; + r = ((glPointParameterfvARB = (PFNGLPOINTPARAMETERFVARBPROC)glewGetProcAddress((const GLubyte*)"glPointParameterfvARB")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_point_parameters */ + +#ifdef GL_ARB_point_sprite + +#endif /* GL_ARB_point_sprite */ + +#ifdef GL_ARB_shader_objects + +static GLboolean _glewInit_GL_ARB_shader_objects (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glAttachObjectARB = (PFNGLATTACHOBJECTARBPROC)glewGetProcAddress((const GLubyte*)"glAttachObjectARB")) == NULL) || r; + r = ((glCompileShaderARB = (PFNGLCOMPILESHADERARBPROC)glewGetProcAddress((const GLubyte*)"glCompileShaderARB")) == NULL) || r; + r = ((glCreateProgramObjectARB = (PFNGLCREATEPROGRAMOBJECTARBPROC)glewGetProcAddress((const GLubyte*)"glCreateProgramObjectARB")) == NULL) || r; + r = ((glCreateShaderObjectARB = (PFNGLCREATESHADEROBJECTARBPROC)glewGetProcAddress((const GLubyte*)"glCreateShaderObjectARB")) == NULL) || r; + r = ((glDeleteObjectARB = (PFNGLDELETEOBJECTARBPROC)glewGetProcAddress((const GLubyte*)"glDeleteObjectARB")) == NULL) || r; + r = ((glDetachObjectARB = (PFNGLDETACHOBJECTARBPROC)glewGetProcAddress((const GLubyte*)"glDetachObjectARB")) == NULL) || r; + r = ((glGetActiveUniformARB = (PFNGLGETACTIVEUNIFORMARBPROC)glewGetProcAddress((const GLubyte*)"glGetActiveUniformARB")) == NULL) || r; + r = ((glGetAttachedObjectsARB = (PFNGLGETATTACHEDOBJECTSARBPROC)glewGetProcAddress((const GLubyte*)"glGetAttachedObjectsARB")) == NULL) || r; + r = ((glGetHandleARB = (PFNGLGETHANDLEARBPROC)glewGetProcAddress((const GLubyte*)"glGetHandleARB")) == NULL) || r; + r = ((glGetInfoLogARB = (PFNGLGETINFOLOGARBPROC)glewGetProcAddress((const GLubyte*)"glGetInfoLogARB")) == NULL) || r; + r = ((glGetObjectParameterfvARB = (PFNGLGETOBJECTPARAMETERFVARBPROC)glewGetProcAddress((const GLubyte*)"glGetObjectParameterfvARB")) == NULL) || r; + r = ((glGetObjectParameterivARB = (PFNGLGETOBJECTPARAMETERIVARBPROC)glewGetProcAddress((const GLubyte*)"glGetObjectParameterivARB")) == NULL) || r; + r = ((glGetShaderSourceARB = (PFNGLGETSHADERSOURCEARBPROC)glewGetProcAddress((const GLubyte*)"glGetShaderSourceARB")) == NULL) || r; + r = ((glGetUniformLocationARB = (PFNGLGETUNIFORMLOCATIONARBPROC)glewGetProcAddress((const GLubyte*)"glGetUniformLocationARB")) == NULL) || r; + r = ((glGetUniformfvARB = (PFNGLGETUNIFORMFVARBPROC)glewGetProcAddress((const GLubyte*)"glGetUniformfvARB")) == NULL) || r; + r = ((glGetUniformivARB = (PFNGLGETUNIFORMIVARBPROC)glewGetProcAddress((const GLubyte*)"glGetUniformivARB")) == NULL) || r; + r = ((glLinkProgramARB = (PFNGLLINKPROGRAMARBPROC)glewGetProcAddress((const GLubyte*)"glLinkProgramARB")) == NULL) || r; + r = ((glShaderSourceARB = (PFNGLSHADERSOURCEARBPROC)glewGetProcAddress((const GLubyte*)"glShaderSourceARB")) == NULL) || r; + r = ((glUniform1fARB = (PFNGLUNIFORM1FARBPROC)glewGetProcAddress((const GLubyte*)"glUniform1fARB")) == NULL) || r; + r = ((glUniform1fvARB = (PFNGLUNIFORM1FVARBPROC)glewGetProcAddress((const GLubyte*)"glUniform1fvARB")) == NULL) || r; + r = ((glUniform1iARB = (PFNGLUNIFORM1IARBPROC)glewGetProcAddress((const GLubyte*)"glUniform1iARB")) == NULL) || r; + r = ((glUniform1ivARB = (PFNGLUNIFORM1IVARBPROC)glewGetProcAddress((const GLubyte*)"glUniform1ivARB")) == NULL) || r; + r = ((glUniform2fARB = (PFNGLUNIFORM2FARBPROC)glewGetProcAddress((const GLubyte*)"glUniform2fARB")) == NULL) || r; + r = ((glUniform2fvARB = (PFNGLUNIFORM2FVARBPROC)glewGetProcAddress((const GLubyte*)"glUniform2fvARB")) == NULL) || r; + r = ((glUniform2iARB = (PFNGLUNIFORM2IARBPROC)glewGetProcAddress((const GLubyte*)"glUniform2iARB")) == NULL) || r; + r = ((glUniform2ivARB = (PFNGLUNIFORM2IVARBPROC)glewGetProcAddress((const GLubyte*)"glUniform2ivARB")) == NULL) || r; + r = ((glUniform3fARB = (PFNGLUNIFORM3FARBPROC)glewGetProcAddress((const GLubyte*)"glUniform3fARB")) == NULL) || r; + r = ((glUniform3fvARB = (PFNGLUNIFORM3FVARBPROC)glewGetProcAddress((const GLubyte*)"glUniform3fvARB")) == NULL) || r; + r = ((glUniform3iARB = (PFNGLUNIFORM3IARBPROC)glewGetProcAddress((const GLubyte*)"glUniform3iARB")) == NULL) || r; + r = ((glUniform3ivARB = (PFNGLUNIFORM3IVARBPROC)glewGetProcAddress((const GLubyte*)"glUniform3ivARB")) == NULL) || r; + r = ((glUniform4fARB = (PFNGLUNIFORM4FARBPROC)glewGetProcAddress((const GLubyte*)"glUniform4fARB")) == NULL) || r; + r = ((glUniform4fvARB = (PFNGLUNIFORM4FVARBPROC)glewGetProcAddress((const GLubyte*)"glUniform4fvARB")) == NULL) || r; + r = ((glUniform4iARB = (PFNGLUNIFORM4IARBPROC)glewGetProcAddress((const GLubyte*)"glUniform4iARB")) == NULL) || r; + r = ((glUniform4ivARB = (PFNGLUNIFORM4IVARBPROC)glewGetProcAddress((const GLubyte*)"glUniform4ivARB")) == NULL) || r; + r = ((glUniformMatrix2fvARB = (PFNGLUNIFORMMATRIX2FVARBPROC)glewGetProcAddress((const GLubyte*)"glUniformMatrix2fvARB")) == NULL) || r; + r = ((glUniformMatrix3fvARB = (PFNGLUNIFORMMATRIX3FVARBPROC)glewGetProcAddress((const GLubyte*)"glUniformMatrix3fvARB")) == NULL) || r; + r = ((glUniformMatrix4fvARB = (PFNGLUNIFORMMATRIX4FVARBPROC)glewGetProcAddress((const GLubyte*)"glUniformMatrix4fvARB")) == NULL) || r; + r = ((glUseProgramObjectARB = (PFNGLUSEPROGRAMOBJECTARBPROC)glewGetProcAddress((const GLubyte*)"glUseProgramObjectARB")) == NULL) || r; + r = ((glValidateProgramARB = (PFNGLVALIDATEPROGRAMARBPROC)glewGetProcAddress((const GLubyte*)"glValidateProgramARB")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_shader_objects */ + +#ifdef GL_ARB_shading_language_100 + +#endif /* GL_ARB_shading_language_100 */ + +#ifdef GL_ARB_shadow + +#endif /* GL_ARB_shadow */ + +#ifdef GL_ARB_shadow_ambient + +#endif /* GL_ARB_shadow_ambient */ + +#ifdef GL_ARB_texture_border_clamp + +#endif /* GL_ARB_texture_border_clamp */ + +#ifdef GL_ARB_texture_compression + +static GLboolean _glewInit_GL_ARB_texture_compression (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glCompressedTexImage1DARB = (PFNGLCOMPRESSEDTEXIMAGE1DARBPROC)glewGetProcAddress((const GLubyte*)"glCompressedTexImage1DARB")) == NULL) || r; + r = ((glCompressedTexImage2DARB = (PFNGLCOMPRESSEDTEXIMAGE2DARBPROC)glewGetProcAddress((const GLubyte*)"glCompressedTexImage2DARB")) == NULL) || r; + r = ((glCompressedTexImage3DARB = (PFNGLCOMPRESSEDTEXIMAGE3DARBPROC)glewGetProcAddress((const GLubyte*)"glCompressedTexImage3DARB")) == NULL) || r; + r = ((glCompressedTexSubImage1DARB = (PFNGLCOMPRESSEDTEXSUBIMAGE1DARBPROC)glewGetProcAddress((const GLubyte*)"glCompressedTexSubImage1DARB")) == NULL) || r; + r = ((glCompressedTexSubImage2DARB = (PFNGLCOMPRESSEDTEXSUBIMAGE2DARBPROC)glewGetProcAddress((const GLubyte*)"glCompressedTexSubImage2DARB")) == NULL) || r; + r = ((glCompressedTexSubImage3DARB = (PFNGLCOMPRESSEDTEXSUBIMAGE3DARBPROC)glewGetProcAddress((const GLubyte*)"glCompressedTexSubImage3DARB")) == NULL) || r; + r = ((glGetCompressedTexImageARB = (PFNGLGETCOMPRESSEDTEXIMAGEARBPROC)glewGetProcAddress((const GLubyte*)"glGetCompressedTexImageARB")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_texture_compression */ + +#ifdef GL_ARB_texture_cube_map + +#endif /* GL_ARB_texture_cube_map */ + +#ifdef GL_ARB_texture_env_add + +#endif /* GL_ARB_texture_env_add */ + +#ifdef GL_ARB_texture_env_combine + +#endif /* GL_ARB_texture_env_combine */ + +#ifdef GL_ARB_texture_env_crossbar + +#endif /* GL_ARB_texture_env_crossbar */ + +#ifdef GL_ARB_texture_env_dot3 + +#endif /* GL_ARB_texture_env_dot3 */ + +#ifdef GL_ARB_texture_float + +#endif /* GL_ARB_texture_float */ + +#ifdef GL_ARB_texture_mirrored_repeat + +#endif /* GL_ARB_texture_mirrored_repeat */ + +#ifdef GL_ARB_texture_non_power_of_two + +#endif /* GL_ARB_texture_non_power_of_two */ + +#ifdef GL_ARB_texture_rectangle + +#endif /* GL_ARB_texture_rectangle */ + +#ifdef GL_ARB_transpose_matrix + +static GLboolean _glewInit_GL_ARB_transpose_matrix (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glLoadTransposeMatrixdARB = (PFNGLLOADTRANSPOSEMATRIXDARBPROC)glewGetProcAddress((const GLubyte*)"glLoadTransposeMatrixdARB")) == NULL) || r; + r = ((glLoadTransposeMatrixfARB = (PFNGLLOADTRANSPOSEMATRIXFARBPROC)glewGetProcAddress((const GLubyte*)"glLoadTransposeMatrixfARB")) == NULL) || r; + r = ((glMultTransposeMatrixdARB = (PFNGLMULTTRANSPOSEMATRIXDARBPROC)glewGetProcAddress((const GLubyte*)"glMultTransposeMatrixdARB")) == NULL) || r; + r = ((glMultTransposeMatrixfARB = (PFNGLMULTTRANSPOSEMATRIXFARBPROC)glewGetProcAddress((const GLubyte*)"glMultTransposeMatrixfARB")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_transpose_matrix */ + +#ifdef GL_ARB_vertex_blend + +static GLboolean _glewInit_GL_ARB_vertex_blend (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glVertexBlendARB = (PFNGLVERTEXBLENDARBPROC)glewGetProcAddress((const GLubyte*)"glVertexBlendARB")) == NULL) || r; + r = ((glWeightPointerARB = (PFNGLWEIGHTPOINTERARBPROC)glewGetProcAddress((const GLubyte*)"glWeightPointerARB")) == NULL) || r; + r = ((glWeightbvARB = (PFNGLWEIGHTBVARBPROC)glewGetProcAddress((const GLubyte*)"glWeightbvARB")) == NULL) || r; + r = ((glWeightdvARB = (PFNGLWEIGHTDVARBPROC)glewGetProcAddress((const GLubyte*)"glWeightdvARB")) == NULL) || r; + r = ((glWeightfvARB = (PFNGLWEIGHTFVARBPROC)glewGetProcAddress((const GLubyte*)"glWeightfvARB")) == NULL) || r; + r = ((glWeightivARB = (PFNGLWEIGHTIVARBPROC)glewGetProcAddress((const GLubyte*)"glWeightivARB")) == NULL) || r; + r = ((glWeightsvARB = (PFNGLWEIGHTSVARBPROC)glewGetProcAddress((const GLubyte*)"glWeightsvARB")) == NULL) || r; + r = ((glWeightubvARB = (PFNGLWEIGHTUBVARBPROC)glewGetProcAddress((const GLubyte*)"glWeightubvARB")) == NULL) || r; + r = ((glWeightuivARB = (PFNGLWEIGHTUIVARBPROC)glewGetProcAddress((const GLubyte*)"glWeightuivARB")) == NULL) || r; + r = ((glWeightusvARB = (PFNGLWEIGHTUSVARBPROC)glewGetProcAddress((const GLubyte*)"glWeightusvARB")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_vertex_blend */ + +#ifdef GL_ARB_vertex_buffer_object + +static GLboolean _glewInit_GL_ARB_vertex_buffer_object (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glBindBufferARB = (PFNGLBINDBUFFERARBPROC)glewGetProcAddress((const GLubyte*)"glBindBufferARB")) == NULL) || r; + r = ((glBufferDataARB = (PFNGLBUFFERDATAARBPROC)glewGetProcAddress((const GLubyte*)"glBufferDataARB")) == NULL) || r; + r = ((glBufferSubDataARB = (PFNGLBUFFERSUBDATAARBPROC)glewGetProcAddress((const GLubyte*)"glBufferSubDataARB")) == NULL) || r; + r = ((glDeleteBuffersARB = (PFNGLDELETEBUFFERSARBPROC)glewGetProcAddress((const GLubyte*)"glDeleteBuffersARB")) == NULL) || r; + r = ((glGenBuffersARB = (PFNGLGENBUFFERSARBPROC)glewGetProcAddress((const GLubyte*)"glGenBuffersARB")) == NULL) || r; + r = ((glGetBufferParameterivARB = (PFNGLGETBUFFERPARAMETERIVARBPROC)glewGetProcAddress((const GLubyte*)"glGetBufferParameterivARB")) == NULL) || r; + r = ((glGetBufferPointervARB = (PFNGLGETBUFFERPOINTERVARBPROC)glewGetProcAddress((const GLubyte*)"glGetBufferPointervARB")) == NULL) || r; + r = ((glGetBufferSubDataARB = (PFNGLGETBUFFERSUBDATAARBPROC)glewGetProcAddress((const GLubyte*)"glGetBufferSubDataARB")) == NULL) || r; + r = ((glIsBufferARB = (PFNGLISBUFFERARBPROC)glewGetProcAddress((const GLubyte*)"glIsBufferARB")) == NULL) || r; + r = ((glMapBufferARB = (PFNGLMAPBUFFERARBPROC)glewGetProcAddress((const GLubyte*)"glMapBufferARB")) == NULL) || r; + r = ((glUnmapBufferARB = (PFNGLUNMAPBUFFERARBPROC)glewGetProcAddress((const GLubyte*)"glUnmapBufferARB")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_vertex_buffer_object */ + +#ifdef GL_ARB_vertex_program + +static GLboolean _glewInit_GL_ARB_vertex_program (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glBindProgramARB = (PFNGLBINDPROGRAMARBPROC)glewGetProcAddress((const GLubyte*)"glBindProgramARB")) == NULL) || r; + r = ((glDeleteProgramsARB = (PFNGLDELETEPROGRAMSARBPROC)glewGetProcAddress((const GLubyte*)"glDeleteProgramsARB")) == NULL) || r; + r = ((glDisableVertexAttribArrayARB = (PFNGLDISABLEVERTEXATTRIBARRAYARBPROC)glewGetProcAddress((const GLubyte*)"glDisableVertexAttribArrayARB")) == NULL) || r; + r = ((glEnableVertexAttribArrayARB = (PFNGLENABLEVERTEXATTRIBARRAYARBPROC)glewGetProcAddress((const GLubyte*)"glEnableVertexAttribArrayARB")) == NULL) || r; + r = ((glGenProgramsARB = (PFNGLGENPROGRAMSARBPROC)glewGetProcAddress((const GLubyte*)"glGenProgramsARB")) == NULL) || r; + r = ((glGetProgramEnvParameterdvARB = (PFNGLGETPROGRAMENVPARAMETERDVARBPROC)glewGetProcAddress((const GLubyte*)"glGetProgramEnvParameterdvARB")) == NULL) || r; + r = ((glGetProgramEnvParameterfvARB = (PFNGLGETPROGRAMENVPARAMETERFVARBPROC)glewGetProcAddress((const GLubyte*)"glGetProgramEnvParameterfvARB")) == NULL) || r; + r = ((glGetProgramLocalParameterdvARB = (PFNGLGETPROGRAMLOCALPARAMETERDVARBPROC)glewGetProcAddress((const GLubyte*)"glGetProgramLocalParameterdvARB")) == NULL) || r; + r = ((glGetProgramLocalParameterfvARB = (PFNGLGETPROGRAMLOCALPARAMETERFVARBPROC)glewGetProcAddress((const GLubyte*)"glGetProgramLocalParameterfvARB")) == NULL) || r; + r = ((glGetProgramStringARB = (PFNGLGETPROGRAMSTRINGARBPROC)glewGetProcAddress((const GLubyte*)"glGetProgramStringARB")) == NULL) || r; + r = ((glGetProgramivARB = (PFNGLGETPROGRAMIVARBPROC)glewGetProcAddress((const GLubyte*)"glGetProgramivARB")) == NULL) || r; + r = ((glGetVertexAttribPointervARB = (PFNGLGETVERTEXATTRIBPOINTERVARBPROC)glewGetProcAddress((const GLubyte*)"glGetVertexAttribPointervARB")) == NULL) || r; + r = ((glGetVertexAttribdvARB = (PFNGLGETVERTEXATTRIBDVARBPROC)glewGetProcAddress((const GLubyte*)"glGetVertexAttribdvARB")) == NULL) || r; + r = ((glGetVertexAttribfvARB = (PFNGLGETVERTEXATTRIBFVARBPROC)glewGetProcAddress((const GLubyte*)"glGetVertexAttribfvARB")) == NULL) || r; + r = ((glGetVertexAttribivARB = (PFNGLGETVERTEXATTRIBIVARBPROC)glewGetProcAddress((const GLubyte*)"glGetVertexAttribivARB")) == NULL) || r; + r = ((glIsProgramARB = (PFNGLISPROGRAMARBPROC)glewGetProcAddress((const GLubyte*)"glIsProgramARB")) == NULL) || r; + r = ((glProgramEnvParameter4dARB = (PFNGLPROGRAMENVPARAMETER4DARBPROC)glewGetProcAddress((const GLubyte*)"glProgramEnvParameter4dARB")) == NULL) || r; + r = ((glProgramEnvParameter4dvARB = (PFNGLPROGRAMENVPARAMETER4DVARBPROC)glewGetProcAddress((const GLubyte*)"glProgramEnvParameter4dvARB")) == NULL) || r; + r = ((glProgramEnvParameter4fARB = (PFNGLPROGRAMENVPARAMETER4FARBPROC)glewGetProcAddress((const GLubyte*)"glProgramEnvParameter4fARB")) == NULL) || r; + r = ((glProgramEnvParameter4fvARB = (PFNGLPROGRAMENVPARAMETER4FVARBPROC)glewGetProcAddress((const GLubyte*)"glProgramEnvParameter4fvARB")) == NULL) || r; + r = ((glProgramLocalParameter4dARB = (PFNGLPROGRAMLOCALPARAMETER4DARBPROC)glewGetProcAddress((const GLubyte*)"glProgramLocalParameter4dARB")) == NULL) || r; + r = ((glProgramLocalParameter4dvARB = (PFNGLPROGRAMLOCALPARAMETER4DVARBPROC)glewGetProcAddress((const GLubyte*)"glProgramLocalParameter4dvARB")) == NULL) || r; + r = ((glProgramLocalParameter4fARB = (PFNGLPROGRAMLOCALPARAMETER4FARBPROC)glewGetProcAddress((const GLubyte*)"glProgramLocalParameter4fARB")) == NULL) || r; + r = ((glProgramLocalParameter4fvARB = (PFNGLPROGRAMLOCALPARAMETER4FVARBPROC)glewGetProcAddress((const GLubyte*)"glProgramLocalParameter4fvARB")) == NULL) || r; + r = ((glProgramStringARB = (PFNGLPROGRAMSTRINGARBPROC)glewGetProcAddress((const GLubyte*)"glProgramStringARB")) == NULL) || r; + r = ((glVertexAttrib1dARB = (PFNGLVERTEXATTRIB1DARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib1dARB")) == NULL) || r; + r = ((glVertexAttrib1dvARB = (PFNGLVERTEXATTRIB1DVARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib1dvARB")) == NULL) || r; + r = ((glVertexAttrib1fARB = (PFNGLVERTEXATTRIB1FARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib1fARB")) == NULL) || r; + r = ((glVertexAttrib1fvARB = (PFNGLVERTEXATTRIB1FVARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib1fvARB")) == NULL) || r; + r = ((glVertexAttrib1sARB = (PFNGLVERTEXATTRIB1SARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib1sARB")) == NULL) || r; + r = ((glVertexAttrib1svARB = (PFNGLVERTEXATTRIB1SVARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib1svARB")) == NULL) || r; + r = ((glVertexAttrib2dARB = (PFNGLVERTEXATTRIB2DARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib2dARB")) == NULL) || r; + r = ((glVertexAttrib2dvARB = (PFNGLVERTEXATTRIB2DVARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib2dvARB")) == NULL) || r; + r = ((glVertexAttrib2fARB = (PFNGLVERTEXATTRIB2FARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib2fARB")) == NULL) || r; + r = ((glVertexAttrib2fvARB = (PFNGLVERTEXATTRIB2FVARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib2fvARB")) == NULL) || r; + r = ((glVertexAttrib2sARB = (PFNGLVERTEXATTRIB2SARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib2sARB")) == NULL) || r; + r = ((glVertexAttrib2svARB = (PFNGLVERTEXATTRIB2SVARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib2svARB")) == NULL) || r; + r = ((glVertexAttrib3dARB = (PFNGLVERTEXATTRIB3DARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib3dARB")) == NULL) || r; + r = ((glVertexAttrib3dvARB = (PFNGLVERTEXATTRIB3DVARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib3dvARB")) == NULL) || r; + r = ((glVertexAttrib3fARB = (PFNGLVERTEXATTRIB3FARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib3fARB")) == NULL) || r; + r = ((glVertexAttrib3fvARB = (PFNGLVERTEXATTRIB3FVARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib3fvARB")) == NULL) || r; + r = ((glVertexAttrib3sARB = (PFNGLVERTEXATTRIB3SARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib3sARB")) == NULL) || r; + r = ((glVertexAttrib3svARB = (PFNGLVERTEXATTRIB3SVARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib3svARB")) == NULL) || r; + r = ((glVertexAttrib4NbvARB = (PFNGLVERTEXATTRIB4NBVARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4NbvARB")) == NULL) || r; + r = ((glVertexAttrib4NivARB = (PFNGLVERTEXATTRIB4NIVARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4NivARB")) == NULL) || r; + r = ((glVertexAttrib4NsvARB = (PFNGLVERTEXATTRIB4NSVARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4NsvARB")) == NULL) || r; + r = ((glVertexAttrib4NubARB = (PFNGLVERTEXATTRIB4NUBARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4NubARB")) == NULL) || r; + r = ((glVertexAttrib4NubvARB = (PFNGLVERTEXATTRIB4NUBVARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4NubvARB")) == NULL) || r; + r = ((glVertexAttrib4NuivARB = (PFNGLVERTEXATTRIB4NUIVARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4NuivARB")) == NULL) || r; + r = ((glVertexAttrib4NusvARB = (PFNGLVERTEXATTRIB4NUSVARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4NusvARB")) == NULL) || r; + r = ((glVertexAttrib4bvARB = (PFNGLVERTEXATTRIB4BVARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4bvARB")) == NULL) || r; + r = ((glVertexAttrib4dARB = (PFNGLVERTEXATTRIB4DARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4dARB")) == NULL) || r; + r = ((glVertexAttrib4dvARB = (PFNGLVERTEXATTRIB4DVARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4dvARB")) == NULL) || r; + r = ((glVertexAttrib4fARB = (PFNGLVERTEXATTRIB4FARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4fARB")) == NULL) || r; + r = ((glVertexAttrib4fvARB = (PFNGLVERTEXATTRIB4FVARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4fvARB")) == NULL) || r; + r = ((glVertexAttrib4ivARB = (PFNGLVERTEXATTRIB4IVARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4ivARB")) == NULL) || r; + r = ((glVertexAttrib4sARB = (PFNGLVERTEXATTRIB4SARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4sARB")) == NULL) || r; + r = ((glVertexAttrib4svARB = (PFNGLVERTEXATTRIB4SVARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4svARB")) == NULL) || r; + r = ((glVertexAttrib4ubvARB = (PFNGLVERTEXATTRIB4UBVARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4ubvARB")) == NULL) || r; + r = ((glVertexAttrib4uivARB = (PFNGLVERTEXATTRIB4UIVARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4uivARB")) == NULL) || r; + r = ((glVertexAttrib4usvARB = (PFNGLVERTEXATTRIB4USVARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4usvARB")) == NULL) || r; + r = ((glVertexAttribPointerARB = (PFNGLVERTEXATTRIBPOINTERARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribPointerARB")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_vertex_program */ + +#ifdef GL_ARB_vertex_shader + +static GLboolean _glewInit_GL_ARB_vertex_shader (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glBindAttribLocationARB = (PFNGLBINDATTRIBLOCATIONARBPROC)glewGetProcAddress((const GLubyte*)"glBindAttribLocationARB")) == NULL) || r; + r = ((glGetActiveAttribARB = (PFNGLGETACTIVEATTRIBARBPROC)glewGetProcAddress((const GLubyte*)"glGetActiveAttribARB")) == NULL) || r; + r = ((glGetAttribLocationARB = (PFNGLGETATTRIBLOCATIONARBPROC)glewGetProcAddress((const GLubyte*)"glGetAttribLocationARB")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_vertex_shader */ + +#ifdef GL_ARB_window_pos + +static GLboolean _glewInit_GL_ARB_window_pos (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glWindowPos2dARB = (PFNGLWINDOWPOS2DARBPROC)glewGetProcAddress((const GLubyte*)"glWindowPos2dARB")) == NULL) || r; + r = ((glWindowPos2dvARB = (PFNGLWINDOWPOS2DVARBPROC)glewGetProcAddress((const GLubyte*)"glWindowPos2dvARB")) == NULL) || r; + r = ((glWindowPos2fARB = (PFNGLWINDOWPOS2FARBPROC)glewGetProcAddress((const GLubyte*)"glWindowPos2fARB")) == NULL) || r; + r = ((glWindowPos2fvARB = (PFNGLWINDOWPOS2FVARBPROC)glewGetProcAddress((const GLubyte*)"glWindowPos2fvARB")) == NULL) || r; + r = ((glWindowPos2iARB = (PFNGLWINDOWPOS2IARBPROC)glewGetProcAddress((const GLubyte*)"glWindowPos2iARB")) == NULL) || r; + r = ((glWindowPos2ivARB = (PFNGLWINDOWPOS2IVARBPROC)glewGetProcAddress((const GLubyte*)"glWindowPos2ivARB")) == NULL) || r; + r = ((glWindowPos2sARB = (PFNGLWINDOWPOS2SARBPROC)glewGetProcAddress((const GLubyte*)"glWindowPos2sARB")) == NULL) || r; + r = ((glWindowPos2svARB = (PFNGLWINDOWPOS2SVARBPROC)glewGetProcAddress((const GLubyte*)"glWindowPos2svARB")) == NULL) || r; + r = ((glWindowPos3dARB = (PFNGLWINDOWPOS3DARBPROC)glewGetProcAddress((const GLubyte*)"glWindowPos3dARB")) == NULL) || r; + r = ((glWindowPos3dvARB = (PFNGLWINDOWPOS3DVARBPROC)glewGetProcAddress((const GLubyte*)"glWindowPos3dvARB")) == NULL) || r; + r = ((glWindowPos3fARB = (PFNGLWINDOWPOS3FARBPROC)glewGetProcAddress((const GLubyte*)"glWindowPos3fARB")) == NULL) || r; + r = ((glWindowPos3fvARB = (PFNGLWINDOWPOS3FVARBPROC)glewGetProcAddress((const GLubyte*)"glWindowPos3fvARB")) == NULL) || r; + r = ((glWindowPos3iARB = (PFNGLWINDOWPOS3IARBPROC)glewGetProcAddress((const GLubyte*)"glWindowPos3iARB")) == NULL) || r; + r = ((glWindowPos3ivARB = (PFNGLWINDOWPOS3IVARBPROC)glewGetProcAddress((const GLubyte*)"glWindowPos3ivARB")) == NULL) || r; + r = ((glWindowPos3sARB = (PFNGLWINDOWPOS3SARBPROC)glewGetProcAddress((const GLubyte*)"glWindowPos3sARB")) == NULL) || r; + r = ((glWindowPos3svARB = (PFNGLWINDOWPOS3SVARBPROC)glewGetProcAddress((const GLubyte*)"glWindowPos3svARB")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_window_pos */ + +#ifdef GL_ATIX_point_sprites + +#endif /* GL_ATIX_point_sprites */ + +#ifdef GL_ATIX_texture_env_combine3 + +#endif /* GL_ATIX_texture_env_combine3 */ + +#ifdef GL_ATIX_texture_env_route + +#endif /* GL_ATIX_texture_env_route */ + +#ifdef GL_ATIX_vertex_shader_output_point_size + +#endif /* GL_ATIX_vertex_shader_output_point_size */ + +#ifdef GL_ATI_draw_buffers + +static GLboolean _glewInit_GL_ATI_draw_buffers (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glDrawBuffersATI = (PFNGLDRAWBUFFERSATIPROC)glewGetProcAddress((const GLubyte*)"glDrawBuffersATI")) == NULL) || r; + + return r; +} + +#endif /* GL_ATI_draw_buffers */ + +#ifdef GL_ATI_element_array + +static GLboolean _glewInit_GL_ATI_element_array (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glDrawElementArrayATI = (PFNGLDRAWELEMENTARRAYATIPROC)glewGetProcAddress((const GLubyte*)"glDrawElementArrayATI")) == NULL) || r; + r = ((glDrawRangeElementArrayATI = (PFNGLDRAWRANGEELEMENTARRAYATIPROC)glewGetProcAddress((const GLubyte*)"glDrawRangeElementArrayATI")) == NULL) || r; + r = ((glElementPointerATI = (PFNGLELEMENTPOINTERATIPROC)glewGetProcAddress((const GLubyte*)"glElementPointerATI")) == NULL) || r; + + return r; +} + +#endif /* GL_ATI_element_array */ + +#ifdef GL_ATI_envmap_bumpmap + +static GLboolean _glewInit_GL_ATI_envmap_bumpmap (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glGetTexBumpParameterfvATI = (PFNGLGETTEXBUMPPARAMETERFVATIPROC)glewGetProcAddress((const GLubyte*)"glGetTexBumpParameterfvATI")) == NULL) || r; + r = ((glGetTexBumpParameterivATI = (PFNGLGETTEXBUMPPARAMETERIVATIPROC)glewGetProcAddress((const GLubyte*)"glGetTexBumpParameterivATI")) == NULL) || r; + r = ((glTexBumpParameterfvATI = (PFNGLTEXBUMPPARAMETERFVATIPROC)glewGetProcAddress((const GLubyte*)"glTexBumpParameterfvATI")) == NULL) || r; + r = ((glTexBumpParameterivATI = (PFNGLTEXBUMPPARAMETERIVATIPROC)glewGetProcAddress((const GLubyte*)"glTexBumpParameterivATI")) == NULL) || r; + + return r; +} + +#endif /* GL_ATI_envmap_bumpmap */ + +#ifdef GL_ATI_fragment_shader + +static GLboolean _glewInit_GL_ATI_fragment_shader (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glAlphaFragmentOp1ATI = (PFNGLALPHAFRAGMENTOP1ATIPROC)glewGetProcAddress((const GLubyte*)"glAlphaFragmentOp1ATI")) == NULL) || r; + r = ((glAlphaFragmentOp2ATI = (PFNGLALPHAFRAGMENTOP2ATIPROC)glewGetProcAddress((const GLubyte*)"glAlphaFragmentOp2ATI")) == NULL) || r; + r = ((glAlphaFragmentOp3ATI = (PFNGLALPHAFRAGMENTOP3ATIPROC)glewGetProcAddress((const GLubyte*)"glAlphaFragmentOp3ATI")) == NULL) || r; + r = ((glBeginFragmentShaderATI = (PFNGLBEGINFRAGMENTSHADERATIPROC)glewGetProcAddress((const GLubyte*)"glBeginFragmentShaderATI")) == NULL) || r; + r = ((glBindFragmentShaderATI = (PFNGLBINDFRAGMENTSHADERATIPROC)glewGetProcAddress((const GLubyte*)"glBindFragmentShaderATI")) == NULL) || r; + r = ((glColorFragmentOp1ATI = (PFNGLCOLORFRAGMENTOP1ATIPROC)glewGetProcAddress((const GLubyte*)"glColorFragmentOp1ATI")) == NULL) || r; + r = ((glColorFragmentOp2ATI = (PFNGLCOLORFRAGMENTOP2ATIPROC)glewGetProcAddress((const GLubyte*)"glColorFragmentOp2ATI")) == NULL) || r; + r = ((glColorFragmentOp3ATI = (PFNGLCOLORFRAGMENTOP3ATIPROC)glewGetProcAddress((const GLubyte*)"glColorFragmentOp3ATI")) == NULL) || r; + r = ((glDeleteFragmentShaderATI = (PFNGLDELETEFRAGMENTSHADERATIPROC)glewGetProcAddress((const GLubyte*)"glDeleteFragmentShaderATI")) == NULL) || r; + r = ((glEndFragmentShaderATI = (PFNGLENDFRAGMENTSHADERATIPROC)glewGetProcAddress((const GLubyte*)"glEndFragmentShaderATI")) == NULL) || r; + r = ((glGenFragmentShadersATI = (PFNGLGENFRAGMENTSHADERSATIPROC)glewGetProcAddress((const GLubyte*)"glGenFragmentShadersATI")) == NULL) || r; + r = ((glPassTexCoordATI = (PFNGLPASSTEXCOORDATIPROC)glewGetProcAddress((const GLubyte*)"glPassTexCoordATI")) == NULL) || r; + r = ((glSampleMapATI = (PFNGLSAMPLEMAPATIPROC)glewGetProcAddress((const GLubyte*)"glSampleMapATI")) == NULL) || r; + r = ((glSetFragmentShaderConstantATI = (PFNGLSETFRAGMENTSHADERCONSTANTATIPROC)glewGetProcAddress((const GLubyte*)"glSetFragmentShaderConstantATI")) == NULL) || r; + + return r; +} + +#endif /* GL_ATI_fragment_shader */ + +#ifdef GL_ATI_map_object_buffer + +static GLboolean _glewInit_GL_ATI_map_object_buffer (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glMapObjectBufferATI = (PFNGLMAPOBJECTBUFFERATIPROC)glewGetProcAddress((const GLubyte*)"glMapObjectBufferATI")) == NULL) || r; + r = ((glUnmapObjectBufferATI = (PFNGLUNMAPOBJECTBUFFERATIPROC)glewGetProcAddress((const GLubyte*)"glUnmapObjectBufferATI")) == NULL) || r; + + return r; +} + +#endif /* GL_ATI_map_object_buffer */ + +#ifdef GL_ATI_pn_triangles + +static GLboolean _glewInit_GL_ATI_pn_triangles (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glPNTrianglesfATI = (PFNGLPNTRIANGLESFATIPROC)glewGetProcAddress((const GLubyte*)"glPNTrianglesfATI")) == NULL) || r; + r = ((glPNTrianglesiATI = (PFNGLPNTRIANGLESIATIPROC)glewGetProcAddress((const GLubyte*)"glPNTrianglesiATI")) == NULL) || r; + + return r; +} + +#endif /* GL_ATI_pn_triangles */ + +#ifdef GL_ATI_separate_stencil + +static GLboolean _glewInit_GL_ATI_separate_stencil (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glStencilFuncSeparateATI = (PFNGLSTENCILFUNCSEPARATEATIPROC)glewGetProcAddress((const GLubyte*)"glStencilFuncSeparateATI")) == NULL) || r; + r = ((glStencilOpSeparateATI = (PFNGLSTENCILOPSEPARATEATIPROC)glewGetProcAddress((const GLubyte*)"glStencilOpSeparateATI")) == NULL) || r; + + return r; +} + +#endif /* GL_ATI_separate_stencil */ + +#ifdef GL_ATI_text_fragment_shader + +#endif /* GL_ATI_text_fragment_shader */ + +#ifdef GL_ATI_texture_compression_3dc + +#endif /* GL_ATI_texture_compression_3dc */ + +#ifdef GL_ATI_texture_env_combine3 + +#endif /* GL_ATI_texture_env_combine3 */ + +#ifdef GL_ATI_texture_float + +#endif /* GL_ATI_texture_float */ + +#ifdef GL_ATI_texture_mirror_once + +#endif /* GL_ATI_texture_mirror_once */ + +#ifdef GL_ATI_vertex_array_object + +static GLboolean _glewInit_GL_ATI_vertex_array_object (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glArrayObjectATI = (PFNGLARRAYOBJECTATIPROC)glewGetProcAddress((const GLubyte*)"glArrayObjectATI")) == NULL) || r; + r = ((glFreeObjectBufferATI = (PFNGLFREEOBJECTBUFFERATIPROC)glewGetProcAddress((const GLubyte*)"glFreeObjectBufferATI")) == NULL) || r; + r = ((glGetArrayObjectfvATI = (PFNGLGETARRAYOBJECTFVATIPROC)glewGetProcAddress((const GLubyte*)"glGetArrayObjectfvATI")) == NULL) || r; + r = ((glGetArrayObjectivATI = (PFNGLGETARRAYOBJECTIVATIPROC)glewGetProcAddress((const GLubyte*)"glGetArrayObjectivATI")) == NULL) || r; + r = ((glGetObjectBufferfvATI = (PFNGLGETOBJECTBUFFERFVATIPROC)glewGetProcAddress((const GLubyte*)"glGetObjectBufferfvATI")) == NULL) || r; + r = ((glGetObjectBufferivATI = (PFNGLGETOBJECTBUFFERIVATIPROC)glewGetProcAddress((const GLubyte*)"glGetObjectBufferivATI")) == NULL) || r; + r = ((glGetVariantArrayObjectfvATI = (PFNGLGETVARIANTARRAYOBJECTFVATIPROC)glewGetProcAddress((const GLubyte*)"glGetVariantArrayObjectfvATI")) == NULL) || r; + r = ((glGetVariantArrayObjectivATI = (PFNGLGETVARIANTARRAYOBJECTIVATIPROC)glewGetProcAddress((const GLubyte*)"glGetVariantArrayObjectivATI")) == NULL) || r; + r = ((glIsObjectBufferATI = (PFNGLISOBJECTBUFFERATIPROC)glewGetProcAddress((const GLubyte*)"glIsObjectBufferATI")) == NULL) || r; + r = ((glNewObjectBufferATI = (PFNGLNEWOBJECTBUFFERATIPROC)glewGetProcAddress((const GLubyte*)"glNewObjectBufferATI")) == NULL) || r; + r = ((glUpdateObjectBufferATI = (PFNGLUPDATEOBJECTBUFFERATIPROC)glewGetProcAddress((const GLubyte*)"glUpdateObjectBufferATI")) == NULL) || r; + r = ((glVariantArrayObjectATI = (PFNGLVARIANTARRAYOBJECTATIPROC)glewGetProcAddress((const GLubyte*)"glVariantArrayObjectATI")) == NULL) || r; + + return r; +} + +#endif /* GL_ATI_vertex_array_object */ + +#ifdef GL_ATI_vertex_attrib_array_object + +static GLboolean _glewInit_GL_ATI_vertex_attrib_array_object (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glGetVertexAttribArrayObjectfvATI = (PFNGLGETVERTEXATTRIBARRAYOBJECTFVATIPROC)glewGetProcAddress((const GLubyte*)"glGetVertexAttribArrayObjectfvATI")) == NULL) || r; + r = ((glGetVertexAttribArrayObjectivATI = (PFNGLGETVERTEXATTRIBARRAYOBJECTIVATIPROC)glewGetProcAddress((const GLubyte*)"glGetVertexAttribArrayObjectivATI")) == NULL) || r; + r = ((glVertexAttribArrayObjectATI = (PFNGLVERTEXATTRIBARRAYOBJECTATIPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribArrayObjectATI")) == NULL) || r; + + return r; +} + +#endif /* GL_ATI_vertex_attrib_array_object */ + +#ifdef GL_ATI_vertex_streams + +static GLboolean _glewInit_GL_ATI_vertex_streams (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glClientActiveVertexStreamATI = (PFNGLCLIENTACTIVEVERTEXSTREAMATIPROC)glewGetProcAddress((const GLubyte*)"glClientActiveVertexStreamATI")) == NULL) || r; + r = ((glNormalStream3bATI = (PFNGLNORMALSTREAM3BATIPROC)glewGetProcAddress((const GLubyte*)"glNormalStream3bATI")) == NULL) || r; + r = ((glNormalStream3bvATI = (PFNGLNORMALSTREAM3BVATIPROC)glewGetProcAddress((const GLubyte*)"glNormalStream3bvATI")) == NULL) || r; + r = ((glNormalStream3dATI = (PFNGLNORMALSTREAM3DATIPROC)glewGetProcAddress((const GLubyte*)"glNormalStream3dATI")) == NULL) || r; + r = ((glNormalStream3dvATI = (PFNGLNORMALSTREAM3DVATIPROC)glewGetProcAddress((const GLubyte*)"glNormalStream3dvATI")) == NULL) || r; + r = ((glNormalStream3fATI = (PFNGLNORMALSTREAM3FATIPROC)glewGetProcAddress((const GLubyte*)"glNormalStream3fATI")) == NULL) || r; + r = ((glNormalStream3fvATI = (PFNGLNORMALSTREAM3FVATIPROC)glewGetProcAddress((const GLubyte*)"glNormalStream3fvATI")) == NULL) || r; + r = ((glNormalStream3iATI = (PFNGLNORMALSTREAM3IATIPROC)glewGetProcAddress((const GLubyte*)"glNormalStream3iATI")) == NULL) || r; + r = ((glNormalStream3ivATI = (PFNGLNORMALSTREAM3IVATIPROC)glewGetProcAddress((const GLubyte*)"glNormalStream3ivATI")) == NULL) || r; + r = ((glNormalStream3sATI = (PFNGLNORMALSTREAM3SATIPROC)glewGetProcAddress((const GLubyte*)"glNormalStream3sATI")) == NULL) || r; + r = ((glNormalStream3svATI = (PFNGLNORMALSTREAM3SVATIPROC)glewGetProcAddress((const GLubyte*)"glNormalStream3svATI")) == NULL) || r; + r = ((glVertexBlendEnvfATI = (PFNGLVERTEXBLENDENVFATIPROC)glewGetProcAddress((const GLubyte*)"glVertexBlendEnvfATI")) == NULL) || r; + r = ((glVertexBlendEnviATI = (PFNGLVERTEXBLENDENVIATIPROC)glewGetProcAddress((const GLubyte*)"glVertexBlendEnviATI")) == NULL) || r; + r = ((glVertexStream2dATI = (PFNGLVERTEXSTREAM2DATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream2dATI")) == NULL) || r; + r = ((glVertexStream2dvATI = (PFNGLVERTEXSTREAM2DVATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream2dvATI")) == NULL) || r; + r = ((glVertexStream2fATI = (PFNGLVERTEXSTREAM2FATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream2fATI")) == NULL) || r; + r = ((glVertexStream2fvATI = (PFNGLVERTEXSTREAM2FVATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream2fvATI")) == NULL) || r; + r = ((glVertexStream2iATI = (PFNGLVERTEXSTREAM2IATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream2iATI")) == NULL) || r; + r = ((glVertexStream2ivATI = (PFNGLVERTEXSTREAM2IVATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream2ivATI")) == NULL) || r; + r = ((glVertexStream2sATI = (PFNGLVERTEXSTREAM2SATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream2sATI")) == NULL) || r; + r = ((glVertexStream2svATI = (PFNGLVERTEXSTREAM2SVATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream2svATI")) == NULL) || r; + r = ((glVertexStream3dATI = (PFNGLVERTEXSTREAM3DATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream3dATI")) == NULL) || r; + r = ((glVertexStream3dvATI = (PFNGLVERTEXSTREAM3DVATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream3dvATI")) == NULL) || r; + r = ((glVertexStream3fATI = (PFNGLVERTEXSTREAM3FATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream3fATI")) == NULL) || r; + r = ((glVertexStream3fvATI = (PFNGLVERTEXSTREAM3FVATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream3fvATI")) == NULL) || r; + r = ((glVertexStream3iATI = (PFNGLVERTEXSTREAM3IATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream3iATI")) == NULL) || r; + r = ((glVertexStream3ivATI = (PFNGLVERTEXSTREAM3IVATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream3ivATI")) == NULL) || r; + r = ((glVertexStream3sATI = (PFNGLVERTEXSTREAM3SATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream3sATI")) == NULL) || r; + r = ((glVertexStream3svATI = (PFNGLVERTEXSTREAM3SVATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream3svATI")) == NULL) || r; + r = ((glVertexStream4dATI = (PFNGLVERTEXSTREAM4DATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream4dATI")) == NULL) || r; + r = ((glVertexStream4dvATI = (PFNGLVERTEXSTREAM4DVATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream4dvATI")) == NULL) || r; + r = ((glVertexStream4fATI = (PFNGLVERTEXSTREAM4FATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream4fATI")) == NULL) || r; + r = ((glVertexStream4fvATI = (PFNGLVERTEXSTREAM4FVATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream4fvATI")) == NULL) || r; + r = ((glVertexStream4iATI = (PFNGLVERTEXSTREAM4IATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream4iATI")) == NULL) || r; + r = ((glVertexStream4ivATI = (PFNGLVERTEXSTREAM4IVATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream4ivATI")) == NULL) || r; + r = ((glVertexStream4sATI = (PFNGLVERTEXSTREAM4SATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream4sATI")) == NULL) || r; + r = ((glVertexStream4svATI = (PFNGLVERTEXSTREAM4SVATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream4svATI")) == NULL) || r; + + return r; +} + +#endif /* GL_ATI_vertex_streams */ + +#ifdef GL_EXT_422_pixels + +#endif /* GL_EXT_422_pixels */ + +#ifdef GL_EXT_Cg_shader + +#endif /* GL_EXT_Cg_shader */ + +#ifdef GL_EXT_abgr + +#endif /* GL_EXT_abgr */ + +#ifdef GL_EXT_bgra + +#endif /* GL_EXT_bgra */ + +#ifdef GL_EXT_blend_color + +static GLboolean _glewInit_GL_EXT_blend_color (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glBlendColorEXT = (PFNGLBLENDCOLOREXTPROC)glewGetProcAddress((const GLubyte*)"glBlendColorEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_blend_color */ + +#ifdef GL_EXT_blend_equation_separate + +static GLboolean _glewInit_GL_EXT_blend_equation_separate (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glBlendEquationSeparateEXT = (PFNGLBLENDEQUATIONSEPARATEEXTPROC)glewGetProcAddress((const GLubyte*)"glBlendEquationSeparateEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_blend_equation_separate */ + +#ifdef GL_EXT_blend_func_separate + +static GLboolean _glewInit_GL_EXT_blend_func_separate (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glBlendFuncSeparateEXT = (PFNGLBLENDFUNCSEPARATEEXTPROC)glewGetProcAddress((const GLubyte*)"glBlendFuncSeparateEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_blend_func_separate */ + +#ifdef GL_EXT_blend_logic_op + +#endif /* GL_EXT_blend_logic_op */ + +#ifdef GL_EXT_blend_minmax + +static GLboolean _glewInit_GL_EXT_blend_minmax (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glBlendEquationEXT = (PFNGLBLENDEQUATIONEXTPROC)glewGetProcAddress((const GLubyte*)"glBlendEquationEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_blend_minmax */ + +#ifdef GL_EXT_blend_subtract + +#endif /* GL_EXT_blend_subtract */ + +#ifdef GL_EXT_clip_volume_hint + +#endif /* GL_EXT_clip_volume_hint */ + +#ifdef GL_EXT_cmyka + +#endif /* GL_EXT_cmyka */ + +#ifdef GL_EXT_color_subtable + +static GLboolean _glewInit_GL_EXT_color_subtable (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glColorSubTableEXT = (PFNGLCOLORSUBTABLEEXTPROC)glewGetProcAddress((const GLubyte*)"glColorSubTableEXT")) == NULL) || r; + r = ((glCopyColorSubTableEXT = (PFNGLCOPYCOLORSUBTABLEEXTPROC)glewGetProcAddress((const GLubyte*)"glCopyColorSubTableEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_color_subtable */ + +#ifdef GL_EXT_compiled_vertex_array + +static GLboolean _glewInit_GL_EXT_compiled_vertex_array (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glLockArraysEXT = (PFNGLLOCKARRAYSEXTPROC)glewGetProcAddress((const GLubyte*)"glLockArraysEXT")) == NULL) || r; + r = ((glUnlockArraysEXT = (PFNGLUNLOCKARRAYSEXTPROC)glewGetProcAddress((const GLubyte*)"glUnlockArraysEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_compiled_vertex_array */ + +#ifdef GL_EXT_convolution + +static GLboolean _glewInit_GL_EXT_convolution (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glConvolutionFilter1DEXT = (PFNGLCONVOLUTIONFILTER1DEXTPROC)glewGetProcAddress((const GLubyte*)"glConvolutionFilter1DEXT")) == NULL) || r; + r = ((glConvolutionFilter2DEXT = (PFNGLCONVOLUTIONFILTER2DEXTPROC)glewGetProcAddress((const GLubyte*)"glConvolutionFilter2DEXT")) == NULL) || r; + r = ((glConvolutionParameterfEXT = (PFNGLCONVOLUTIONPARAMETERFEXTPROC)glewGetProcAddress((const GLubyte*)"glConvolutionParameterfEXT")) == NULL) || r; + r = ((glConvolutionParameterfvEXT = (PFNGLCONVOLUTIONPARAMETERFVEXTPROC)glewGetProcAddress((const GLubyte*)"glConvolutionParameterfvEXT")) == NULL) || r; + r = ((glConvolutionParameteriEXT = (PFNGLCONVOLUTIONPARAMETERIEXTPROC)glewGetProcAddress((const GLubyte*)"glConvolutionParameteriEXT")) == NULL) || r; + r = ((glConvolutionParameterivEXT = (PFNGLCONVOLUTIONPARAMETERIVEXTPROC)glewGetProcAddress((const GLubyte*)"glConvolutionParameterivEXT")) == NULL) || r; + r = ((glCopyConvolutionFilter1DEXT = (PFNGLCOPYCONVOLUTIONFILTER1DEXTPROC)glewGetProcAddress((const GLubyte*)"glCopyConvolutionFilter1DEXT")) == NULL) || r; + r = ((glCopyConvolutionFilter2DEXT = (PFNGLCOPYCONVOLUTIONFILTER2DEXTPROC)glewGetProcAddress((const GLubyte*)"glCopyConvolutionFilter2DEXT")) == NULL) || r; + r = ((glGetConvolutionFilterEXT = (PFNGLGETCONVOLUTIONFILTEREXTPROC)glewGetProcAddress((const GLubyte*)"glGetConvolutionFilterEXT")) == NULL) || r; + r = ((glGetConvolutionParameterfvEXT = (PFNGLGETCONVOLUTIONPARAMETERFVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetConvolutionParameterfvEXT")) == NULL) || r; + r = ((glGetConvolutionParameterivEXT = (PFNGLGETCONVOLUTIONPARAMETERIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetConvolutionParameterivEXT")) == NULL) || r; + r = ((glGetSeparableFilterEXT = (PFNGLGETSEPARABLEFILTEREXTPROC)glewGetProcAddress((const GLubyte*)"glGetSeparableFilterEXT")) == NULL) || r; + r = ((glSeparableFilter2DEXT = (PFNGLSEPARABLEFILTER2DEXTPROC)glewGetProcAddress((const GLubyte*)"glSeparableFilter2DEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_convolution */ + +#ifdef GL_EXT_coordinate_frame + +static GLboolean _glewInit_GL_EXT_coordinate_frame (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glBinormalPointerEXT = (PFNGLBINORMALPOINTEREXTPROC)glewGetProcAddress((const GLubyte*)"glBinormalPointerEXT")) == NULL) || r; + r = ((glTangentPointerEXT = (PFNGLTANGENTPOINTEREXTPROC)glewGetProcAddress((const GLubyte*)"glTangentPointerEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_coordinate_frame */ + +#ifdef GL_EXT_copy_texture + +static GLboolean _glewInit_GL_EXT_copy_texture (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glCopyTexImage1DEXT = (PFNGLCOPYTEXIMAGE1DEXTPROC)glewGetProcAddress((const GLubyte*)"glCopyTexImage1DEXT")) == NULL) || r; + r = ((glCopyTexImage2DEXT = (PFNGLCOPYTEXIMAGE2DEXTPROC)glewGetProcAddress((const GLubyte*)"glCopyTexImage2DEXT")) == NULL) || r; + r = ((glCopyTexSubImage1DEXT = (PFNGLCOPYTEXSUBIMAGE1DEXTPROC)glewGetProcAddress((const GLubyte*)"glCopyTexSubImage1DEXT")) == NULL) || r; + r = ((glCopyTexSubImage2DEXT = (PFNGLCOPYTEXSUBIMAGE2DEXTPROC)glewGetProcAddress((const GLubyte*)"glCopyTexSubImage2DEXT")) == NULL) || r; + r = ((glCopyTexSubImage3DEXT = (PFNGLCOPYTEXSUBIMAGE3DEXTPROC)glewGetProcAddress((const GLubyte*)"glCopyTexSubImage3DEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_copy_texture */ + +#ifdef GL_EXT_cull_vertex + +static GLboolean _glewInit_GL_EXT_cull_vertex (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glCullParameterdvEXT = (PFNGLCULLPARAMETERDVEXTPROC)glewGetProcAddress((const GLubyte*)"glCullParameterdvEXT")) == NULL) || r; + r = ((glCullParameterfvEXT = (PFNGLCULLPARAMETERFVEXTPROC)glewGetProcAddress((const GLubyte*)"glCullParameterfvEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_cull_vertex */ + +#ifdef GL_EXT_depth_bounds_test + +static GLboolean _glewInit_GL_EXT_depth_bounds_test (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glDepthBoundsEXT = (PFNGLDEPTHBOUNDSEXTPROC)glewGetProcAddress((const GLubyte*)"glDepthBoundsEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_depth_bounds_test */ + +#ifdef GL_EXT_draw_range_elements + +static GLboolean _glewInit_GL_EXT_draw_range_elements (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glDrawRangeElementsEXT = (PFNGLDRAWRANGEELEMENTSEXTPROC)glewGetProcAddress((const GLubyte*)"glDrawRangeElementsEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_draw_range_elements */ + +#ifdef GL_EXT_fog_coord + +static GLboolean _glewInit_GL_EXT_fog_coord (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glFogCoordPointerEXT = (PFNGLFOGCOORDPOINTEREXTPROC)glewGetProcAddress((const GLubyte*)"glFogCoordPointerEXT")) == NULL) || r; + r = ((glFogCoorddEXT = (PFNGLFOGCOORDDEXTPROC)glewGetProcAddress((const GLubyte*)"glFogCoorddEXT")) == NULL) || r; + r = ((glFogCoorddvEXT = (PFNGLFOGCOORDDVEXTPROC)glewGetProcAddress((const GLubyte*)"glFogCoorddvEXT")) == NULL) || r; + r = ((glFogCoordfEXT = (PFNGLFOGCOORDFEXTPROC)glewGetProcAddress((const GLubyte*)"glFogCoordfEXT")) == NULL) || r; + r = ((glFogCoordfvEXT = (PFNGLFOGCOORDFVEXTPROC)glewGetProcAddress((const GLubyte*)"glFogCoordfvEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_fog_coord */ + +#ifdef GL_EXT_fragment_lighting + +static GLboolean _glewInit_GL_EXT_fragment_lighting (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glFragmentColorMaterialEXT = (PFNGLFRAGMENTCOLORMATERIALEXTPROC)glewGetProcAddress((const GLubyte*)"glFragmentColorMaterialEXT")) == NULL) || r; + r = ((glFragmentLightModelfEXT = (PFNGLFRAGMENTLIGHTMODELFEXTPROC)glewGetProcAddress((const GLubyte*)"glFragmentLightModelfEXT")) == NULL) || r; + r = ((glFragmentLightModelfvEXT = (PFNGLFRAGMENTLIGHTMODELFVEXTPROC)glewGetProcAddress((const GLubyte*)"glFragmentLightModelfvEXT")) == NULL) || r; + r = ((glFragmentLightModeliEXT = (PFNGLFRAGMENTLIGHTMODELIEXTPROC)glewGetProcAddress((const GLubyte*)"glFragmentLightModeliEXT")) == NULL) || r; + r = ((glFragmentLightModelivEXT = (PFNGLFRAGMENTLIGHTMODELIVEXTPROC)glewGetProcAddress((const GLubyte*)"glFragmentLightModelivEXT")) == NULL) || r; + r = ((glFragmentLightfEXT = (PFNGLFRAGMENTLIGHTFEXTPROC)glewGetProcAddress((const GLubyte*)"glFragmentLightfEXT")) == NULL) || r; + r = ((glFragmentLightfvEXT = (PFNGLFRAGMENTLIGHTFVEXTPROC)glewGetProcAddress((const GLubyte*)"glFragmentLightfvEXT")) == NULL) || r; + r = ((glFragmentLightiEXT = (PFNGLFRAGMENTLIGHTIEXTPROC)glewGetProcAddress((const GLubyte*)"glFragmentLightiEXT")) == NULL) || r; + r = ((glFragmentLightivEXT = (PFNGLFRAGMENTLIGHTIVEXTPROC)glewGetProcAddress((const GLubyte*)"glFragmentLightivEXT")) == NULL) || r; + r = ((glFragmentMaterialfEXT = (PFNGLFRAGMENTMATERIALFEXTPROC)glewGetProcAddress((const GLubyte*)"glFragmentMaterialfEXT")) == NULL) || r; + r = ((glFragmentMaterialfvEXT = (PFNGLFRAGMENTMATERIALFVEXTPROC)glewGetProcAddress((const GLubyte*)"glFragmentMaterialfvEXT")) == NULL) || r; + r = ((glFragmentMaterialiEXT = (PFNGLFRAGMENTMATERIALIEXTPROC)glewGetProcAddress((const GLubyte*)"glFragmentMaterialiEXT")) == NULL) || r; + r = ((glFragmentMaterialivEXT = (PFNGLFRAGMENTMATERIALIVEXTPROC)glewGetProcAddress((const GLubyte*)"glFragmentMaterialivEXT")) == NULL) || r; + r = ((glGetFragmentLightfvEXT = (PFNGLGETFRAGMENTLIGHTFVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetFragmentLightfvEXT")) == NULL) || r; + r = ((glGetFragmentLightivEXT = (PFNGLGETFRAGMENTLIGHTIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetFragmentLightivEXT")) == NULL) || r; + r = ((glGetFragmentMaterialfvEXT = (PFNGLGETFRAGMENTMATERIALFVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetFragmentMaterialfvEXT")) == NULL) || r; + r = ((glGetFragmentMaterialivEXT = (PFNGLGETFRAGMENTMATERIALIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetFragmentMaterialivEXT")) == NULL) || r; + r = ((glLightEnviEXT = (PFNGLLIGHTENVIEXTPROC)glewGetProcAddress((const GLubyte*)"glLightEnviEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_fragment_lighting */ + +#ifdef GL_EXT_framebuffer_blit + +static GLboolean _glewInit_GL_EXT_framebuffer_blit (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glBlitFramebufferEXT = (PFNGLBLITFRAMEBUFFEREXTPROC)glewGetProcAddress((const GLubyte*)"glBlitFramebufferEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_framebuffer_blit */ + +#ifdef GL_EXT_framebuffer_multisample + +static GLboolean _glewInit_GL_EXT_framebuffer_multisample (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glRenderbufferStorageMultisampleEXT = (PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC)glewGetProcAddress((const GLubyte*)"glRenderbufferStorageMultisampleEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_framebuffer_multisample */ + +#ifdef GL_EXT_framebuffer_object + +static GLboolean _glewInit_GL_EXT_framebuffer_object (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glBindFramebufferEXT = (PFNGLBINDFRAMEBUFFEREXTPROC)glewGetProcAddress((const GLubyte*)"glBindFramebufferEXT")) == NULL) || r; + r = ((glBindRenderbufferEXT = (PFNGLBINDRENDERBUFFEREXTPROC)glewGetProcAddress((const GLubyte*)"glBindRenderbufferEXT")) == NULL) || r; + r = ((glCheckFramebufferStatusEXT = (PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC)glewGetProcAddress((const GLubyte*)"glCheckFramebufferStatusEXT")) == NULL) || r; + r = ((glDeleteFramebuffersEXT = (PFNGLDELETEFRAMEBUFFERSEXTPROC)glewGetProcAddress((const GLubyte*)"glDeleteFramebuffersEXT")) == NULL) || r; + r = ((glDeleteRenderbuffersEXT = (PFNGLDELETERENDERBUFFERSEXTPROC)glewGetProcAddress((const GLubyte*)"glDeleteRenderbuffersEXT")) == NULL) || r; + r = ((glFramebufferRenderbufferEXT = (PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC)glewGetProcAddress((const GLubyte*)"glFramebufferRenderbufferEXT")) == NULL) || r; + r = ((glFramebufferTexture1DEXT = (PFNGLFRAMEBUFFERTEXTURE1DEXTPROC)glewGetProcAddress((const GLubyte*)"glFramebufferTexture1DEXT")) == NULL) || r; + r = ((glFramebufferTexture2DEXT = (PFNGLFRAMEBUFFERTEXTURE2DEXTPROC)glewGetProcAddress((const GLubyte*)"glFramebufferTexture2DEXT")) == NULL) || r; + r = ((glFramebufferTexture3DEXT = (PFNGLFRAMEBUFFERTEXTURE3DEXTPROC)glewGetProcAddress((const GLubyte*)"glFramebufferTexture3DEXT")) == NULL) || r; + r = ((glGenFramebuffersEXT = (PFNGLGENFRAMEBUFFERSEXTPROC)glewGetProcAddress((const GLubyte*)"glGenFramebuffersEXT")) == NULL) || r; + r = ((glGenRenderbuffersEXT = (PFNGLGENRENDERBUFFERSEXTPROC)glewGetProcAddress((const GLubyte*)"glGenRenderbuffersEXT")) == NULL) || r; + r = ((glGenerateMipmapEXT = (PFNGLGENERATEMIPMAPEXTPROC)glewGetProcAddress((const GLubyte*)"glGenerateMipmapEXT")) == NULL) || r; + r = ((glGetFramebufferAttachmentParameterivEXT = (PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetFramebufferAttachmentParameterivEXT")) == NULL) || r; + r = ((glGetRenderbufferParameterivEXT = (PFNGLGETRENDERBUFFERPARAMETERIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetRenderbufferParameterivEXT")) == NULL) || r; + r = ((glIsFramebufferEXT = (PFNGLISFRAMEBUFFEREXTPROC)glewGetProcAddress((const GLubyte*)"glIsFramebufferEXT")) == NULL) || r; + r = ((glIsRenderbufferEXT = (PFNGLISRENDERBUFFEREXTPROC)glewGetProcAddress((const GLubyte*)"glIsRenderbufferEXT")) == NULL) || r; + r = ((glRenderbufferStorageEXT = (PFNGLRENDERBUFFERSTORAGEEXTPROC)glewGetProcAddress((const GLubyte*)"glRenderbufferStorageEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_framebuffer_object */ + +#ifdef GL_EXT_histogram + +static GLboolean _glewInit_GL_EXT_histogram (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glGetHistogramEXT = (PFNGLGETHISTOGRAMEXTPROC)glewGetProcAddress((const GLubyte*)"glGetHistogramEXT")) == NULL) || r; + r = ((glGetHistogramParameterfvEXT = (PFNGLGETHISTOGRAMPARAMETERFVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetHistogramParameterfvEXT")) == NULL) || r; + r = ((glGetHistogramParameterivEXT = (PFNGLGETHISTOGRAMPARAMETERIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetHistogramParameterivEXT")) == NULL) || r; + r = ((glGetMinmaxEXT = (PFNGLGETMINMAXEXTPROC)glewGetProcAddress((const GLubyte*)"glGetMinmaxEXT")) == NULL) || r; + r = ((glGetMinmaxParameterfvEXT = (PFNGLGETMINMAXPARAMETERFVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetMinmaxParameterfvEXT")) == NULL) || r; + r = ((glGetMinmaxParameterivEXT = (PFNGLGETMINMAXPARAMETERIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetMinmaxParameterivEXT")) == NULL) || r; + r = ((glHistogramEXT = (PFNGLHISTOGRAMEXTPROC)glewGetProcAddress((const GLubyte*)"glHistogramEXT")) == NULL) || r; + r = ((glMinmaxEXT = (PFNGLMINMAXEXTPROC)glewGetProcAddress((const GLubyte*)"glMinmaxEXT")) == NULL) || r; + r = ((glResetHistogramEXT = (PFNGLRESETHISTOGRAMEXTPROC)glewGetProcAddress((const GLubyte*)"glResetHistogramEXT")) == NULL) || r; + r = ((glResetMinmaxEXT = (PFNGLRESETMINMAXEXTPROC)glewGetProcAddress((const GLubyte*)"glResetMinmaxEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_histogram */ + +#ifdef GL_EXT_index_array_formats + +#endif /* GL_EXT_index_array_formats */ + +#ifdef GL_EXT_index_func + +static GLboolean _glewInit_GL_EXT_index_func (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glIndexFuncEXT = (PFNGLINDEXFUNCEXTPROC)glewGetProcAddress((const GLubyte*)"glIndexFuncEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_index_func */ + +#ifdef GL_EXT_index_material + +static GLboolean _glewInit_GL_EXT_index_material (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glIndexMaterialEXT = (PFNGLINDEXMATERIALEXTPROC)glewGetProcAddress((const GLubyte*)"glIndexMaterialEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_index_material */ + +#ifdef GL_EXT_index_texture + +#endif /* GL_EXT_index_texture */ + +#ifdef GL_EXT_light_texture + +static GLboolean _glewInit_GL_EXT_light_texture (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glApplyTextureEXT = (PFNGLAPPLYTEXTUREEXTPROC)glewGetProcAddress((const GLubyte*)"glApplyTextureEXT")) == NULL) || r; + r = ((glTextureLightEXT = (PFNGLTEXTURELIGHTEXTPROC)glewGetProcAddress((const GLubyte*)"glTextureLightEXT")) == NULL) || r; + r = ((glTextureMaterialEXT = (PFNGLTEXTUREMATERIALEXTPROC)glewGetProcAddress((const GLubyte*)"glTextureMaterialEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_light_texture */ + +#ifdef GL_EXT_misc_attribute + +#endif /* GL_EXT_misc_attribute */ + +#ifdef GL_EXT_multi_draw_arrays + +static GLboolean _glewInit_GL_EXT_multi_draw_arrays (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glMultiDrawArraysEXT = (PFNGLMULTIDRAWARRAYSEXTPROC)glewGetProcAddress((const GLubyte*)"glMultiDrawArraysEXT")) == NULL) || r; + r = ((glMultiDrawElementsEXT = (PFNGLMULTIDRAWELEMENTSEXTPROC)glewGetProcAddress((const GLubyte*)"glMultiDrawElementsEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_multi_draw_arrays */ + +#ifdef GL_EXT_multisample + +static GLboolean _glewInit_GL_EXT_multisample (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glSampleMaskEXT = (PFNGLSAMPLEMASKEXTPROC)glewGetProcAddress((const GLubyte*)"glSampleMaskEXT")) == NULL) || r; + r = ((glSamplePatternEXT = (PFNGLSAMPLEPATTERNEXTPROC)glewGetProcAddress((const GLubyte*)"glSamplePatternEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_multisample */ + +#ifdef GL_EXT_packed_depth_stencil + +#endif /* GL_EXT_packed_depth_stencil */ + +#ifdef GL_EXT_packed_pixels + +#endif /* GL_EXT_packed_pixels */ + +#ifdef GL_EXT_paletted_texture + +static GLboolean _glewInit_GL_EXT_paletted_texture (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glColorTableEXT = (PFNGLCOLORTABLEEXTPROC)glewGetProcAddress((const GLubyte*)"glColorTableEXT")) == NULL) || r; + r = ((glGetColorTableEXT = (PFNGLGETCOLORTABLEEXTPROC)glewGetProcAddress((const GLubyte*)"glGetColorTableEXT")) == NULL) || r; + r = ((glGetColorTableParameterfvEXT = (PFNGLGETCOLORTABLEPARAMETERFVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetColorTableParameterfvEXT")) == NULL) || r; + r = ((glGetColorTableParameterivEXT = (PFNGLGETCOLORTABLEPARAMETERIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetColorTableParameterivEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_paletted_texture */ + +#ifdef GL_EXT_pixel_buffer_object + +#endif /* GL_EXT_pixel_buffer_object */ + +#ifdef GL_EXT_pixel_transform + +static GLboolean _glewInit_GL_EXT_pixel_transform (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glGetPixelTransformParameterfvEXT = (PFNGLGETPIXELTRANSFORMPARAMETERFVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetPixelTransformParameterfvEXT")) == NULL) || r; + r = ((glGetPixelTransformParameterivEXT = (PFNGLGETPIXELTRANSFORMPARAMETERIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetPixelTransformParameterivEXT")) == NULL) || r; + r = ((glPixelTransformParameterfEXT = (PFNGLPIXELTRANSFORMPARAMETERFEXTPROC)glewGetProcAddress((const GLubyte*)"glPixelTransformParameterfEXT")) == NULL) || r; + r = ((glPixelTransformParameterfvEXT = (PFNGLPIXELTRANSFORMPARAMETERFVEXTPROC)glewGetProcAddress((const GLubyte*)"glPixelTransformParameterfvEXT")) == NULL) || r; + r = ((glPixelTransformParameteriEXT = (PFNGLPIXELTRANSFORMPARAMETERIEXTPROC)glewGetProcAddress((const GLubyte*)"glPixelTransformParameteriEXT")) == NULL) || r; + r = ((glPixelTransformParameterivEXT = (PFNGLPIXELTRANSFORMPARAMETERIVEXTPROC)glewGetProcAddress((const GLubyte*)"glPixelTransformParameterivEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_pixel_transform */ + +#ifdef GL_EXT_pixel_transform_color_table + +#endif /* GL_EXT_pixel_transform_color_table */ + +#ifdef GL_EXT_point_parameters + +static GLboolean _glewInit_GL_EXT_point_parameters (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glPointParameterfEXT = (PFNGLPOINTPARAMETERFEXTPROC)glewGetProcAddress((const GLubyte*)"glPointParameterfEXT")) == NULL) || r; + r = ((glPointParameterfvEXT = (PFNGLPOINTPARAMETERFVEXTPROC)glewGetProcAddress((const GLubyte*)"glPointParameterfvEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_point_parameters */ + +#ifdef GL_EXT_polygon_offset + +static GLboolean _glewInit_GL_EXT_polygon_offset (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glPolygonOffsetEXT = (PFNGLPOLYGONOFFSETEXTPROC)glewGetProcAddress((const GLubyte*)"glPolygonOffsetEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_polygon_offset */ + +#ifdef GL_EXT_rescale_normal + +#endif /* GL_EXT_rescale_normal */ + +#ifdef GL_EXT_scene_marker + +static GLboolean _glewInit_GL_EXT_scene_marker (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glBeginSceneEXT = (PFNGLBEGINSCENEEXTPROC)glewGetProcAddress((const GLubyte*)"glBeginSceneEXT")) == NULL) || r; + r = ((glEndSceneEXT = (PFNGLENDSCENEEXTPROC)glewGetProcAddress((const GLubyte*)"glEndSceneEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_scene_marker */ + +#ifdef GL_EXT_secondary_color + +static GLboolean _glewInit_GL_EXT_secondary_color (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glSecondaryColor3bEXT = (PFNGLSECONDARYCOLOR3BEXTPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3bEXT")) == NULL) || r; + r = ((glSecondaryColor3bvEXT = (PFNGLSECONDARYCOLOR3BVEXTPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3bvEXT")) == NULL) || r; + r = ((glSecondaryColor3dEXT = (PFNGLSECONDARYCOLOR3DEXTPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3dEXT")) == NULL) || r; + r = ((glSecondaryColor3dvEXT = (PFNGLSECONDARYCOLOR3DVEXTPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3dvEXT")) == NULL) || r; + r = ((glSecondaryColor3fEXT = (PFNGLSECONDARYCOLOR3FEXTPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3fEXT")) == NULL) || r; + r = ((glSecondaryColor3fvEXT = (PFNGLSECONDARYCOLOR3FVEXTPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3fvEXT")) == NULL) || r; + r = ((glSecondaryColor3iEXT = (PFNGLSECONDARYCOLOR3IEXTPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3iEXT")) == NULL) || r; + r = ((glSecondaryColor3ivEXT = (PFNGLSECONDARYCOLOR3IVEXTPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3ivEXT")) == NULL) || r; + r = ((glSecondaryColor3sEXT = (PFNGLSECONDARYCOLOR3SEXTPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3sEXT")) == NULL) || r; + r = ((glSecondaryColor3svEXT = (PFNGLSECONDARYCOLOR3SVEXTPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3svEXT")) == NULL) || r; + r = ((glSecondaryColor3ubEXT = (PFNGLSECONDARYCOLOR3UBEXTPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3ubEXT")) == NULL) || r; + r = ((glSecondaryColor3ubvEXT = (PFNGLSECONDARYCOLOR3UBVEXTPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3ubvEXT")) == NULL) || r; + r = ((glSecondaryColor3uiEXT = (PFNGLSECONDARYCOLOR3UIEXTPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3uiEXT")) == NULL) || r; + r = ((glSecondaryColor3uivEXT = (PFNGLSECONDARYCOLOR3UIVEXTPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3uivEXT")) == NULL) || r; + r = ((glSecondaryColor3usEXT = (PFNGLSECONDARYCOLOR3USEXTPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3usEXT")) == NULL) || r; + r = ((glSecondaryColor3usvEXT = (PFNGLSECONDARYCOLOR3USVEXTPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3usvEXT")) == NULL) || r; + r = ((glSecondaryColorPointerEXT = (PFNGLSECONDARYCOLORPOINTEREXTPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColorPointerEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_secondary_color */ + +#ifdef GL_EXT_separate_specular_color + +#endif /* GL_EXT_separate_specular_color */ + +#ifdef GL_EXT_shadow_funcs + +#endif /* GL_EXT_shadow_funcs */ + +#ifdef GL_EXT_shared_texture_palette + +#endif /* GL_EXT_shared_texture_palette */ + +#ifdef GL_EXT_stencil_clear_tag + +#endif /* GL_EXT_stencil_clear_tag */ + +#ifdef GL_EXT_stencil_two_side + +static GLboolean _glewInit_GL_EXT_stencil_two_side (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glActiveStencilFaceEXT = (PFNGLACTIVESTENCILFACEEXTPROC)glewGetProcAddress((const GLubyte*)"glActiveStencilFaceEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_stencil_two_side */ + +#ifdef GL_EXT_stencil_wrap + +#endif /* GL_EXT_stencil_wrap */ + +#ifdef GL_EXT_subtexture + +static GLboolean _glewInit_GL_EXT_subtexture (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glTexSubImage1DEXT = (PFNGLTEXSUBIMAGE1DEXTPROC)glewGetProcAddress((const GLubyte*)"glTexSubImage1DEXT")) == NULL) || r; + r = ((glTexSubImage2DEXT = (PFNGLTEXSUBIMAGE2DEXTPROC)glewGetProcAddress((const GLubyte*)"glTexSubImage2DEXT")) == NULL) || r; + r = ((glTexSubImage3DEXT = (PFNGLTEXSUBIMAGE3DEXTPROC)glewGetProcAddress((const GLubyte*)"glTexSubImage3DEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_subtexture */ + +#ifdef GL_EXT_texture + +#endif /* GL_EXT_texture */ + +#ifdef GL_EXT_texture3D + +static GLboolean _glewInit_GL_EXT_texture3D (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glTexImage3DEXT = (PFNGLTEXIMAGE3DEXTPROC)glewGetProcAddress((const GLubyte*)"glTexImage3DEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_texture3D */ + +#ifdef GL_EXT_texture_compression_dxt1 + +#endif /* GL_EXT_texture_compression_dxt1 */ + +#ifdef GL_EXT_texture_compression_s3tc + +#endif /* GL_EXT_texture_compression_s3tc */ + +#ifdef GL_EXT_texture_cube_map + +#endif /* GL_EXT_texture_cube_map */ + +#ifdef GL_EXT_texture_edge_clamp + +#endif /* GL_EXT_texture_edge_clamp */ + +#ifdef GL_EXT_texture_env + +#endif /* GL_EXT_texture_env */ + +#ifdef GL_EXT_texture_env_add + +#endif /* GL_EXT_texture_env_add */ + +#ifdef GL_EXT_texture_env_combine + +#endif /* GL_EXT_texture_env_combine */ + +#ifdef GL_EXT_texture_env_dot3 + +#endif /* GL_EXT_texture_env_dot3 */ + +#ifdef GL_EXT_texture_filter_anisotropic + +#endif /* GL_EXT_texture_filter_anisotropic */ + +#ifdef GL_EXT_texture_lod_bias + +#endif /* GL_EXT_texture_lod_bias */ + +#ifdef GL_EXT_texture_mirror_clamp + +#endif /* GL_EXT_texture_mirror_clamp */ + +#ifdef GL_EXT_texture_object + +static GLboolean _glewInit_GL_EXT_texture_object (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glAreTexturesResidentEXT = (PFNGLARETEXTURESRESIDENTEXTPROC)glewGetProcAddress((const GLubyte*)"glAreTexturesResidentEXT")) == NULL) || r; + r = ((glBindTextureEXT = (PFNGLBINDTEXTUREEXTPROC)glewGetProcAddress((const GLubyte*)"glBindTextureEXT")) == NULL) || r; + r = ((glDeleteTexturesEXT = (PFNGLDELETETEXTURESEXTPROC)glewGetProcAddress((const GLubyte*)"glDeleteTexturesEXT")) == NULL) || r; + r = ((glGenTexturesEXT = (PFNGLGENTEXTURESEXTPROC)glewGetProcAddress((const GLubyte*)"glGenTexturesEXT")) == NULL) || r; + r = ((glIsTextureEXT = (PFNGLISTEXTUREEXTPROC)glewGetProcAddress((const GLubyte*)"glIsTextureEXT")) == NULL) || r; + r = ((glPrioritizeTexturesEXT = (PFNGLPRIORITIZETEXTURESEXTPROC)glewGetProcAddress((const GLubyte*)"glPrioritizeTexturesEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_texture_object */ + +#ifdef GL_EXT_texture_perturb_normal + +static GLboolean _glewInit_GL_EXT_texture_perturb_normal (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glTextureNormalEXT = (PFNGLTEXTURENORMALEXTPROC)glewGetProcAddress((const GLubyte*)"glTextureNormalEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_texture_perturb_normal */ + +#ifdef GL_EXT_texture_rectangle + +#endif /* GL_EXT_texture_rectangle */ + +#ifdef GL_EXT_texture_sRGB + +#endif /* GL_EXT_texture_sRGB */ + +#ifdef GL_EXT_vertex_array + +static GLboolean _glewInit_GL_EXT_vertex_array (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glArrayElementEXT = (PFNGLARRAYELEMENTEXTPROC)glewGetProcAddress((const GLubyte*)"glArrayElementEXT")) == NULL) || r; + r = ((glColorPointerEXT = (PFNGLCOLORPOINTEREXTPROC)glewGetProcAddress((const GLubyte*)"glColorPointerEXT")) == NULL) || r; + r = ((glDrawArraysEXT = (PFNGLDRAWARRAYSEXTPROC)glewGetProcAddress((const GLubyte*)"glDrawArraysEXT")) == NULL) || r; + r = ((glEdgeFlagPointerEXT = (PFNGLEDGEFLAGPOINTEREXTPROC)glewGetProcAddress((const GLubyte*)"glEdgeFlagPointerEXT")) == NULL) || r; + r = ((glGetPointervEXT = (PFNGLGETPOINTERVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetPointervEXT")) == NULL) || r; + r = ((glIndexPointerEXT = (PFNGLINDEXPOINTEREXTPROC)glewGetProcAddress((const GLubyte*)"glIndexPointerEXT")) == NULL) || r; + r = ((glNormalPointerEXT = (PFNGLNORMALPOINTEREXTPROC)glewGetProcAddress((const GLubyte*)"glNormalPointerEXT")) == NULL) || r; + r = ((glTexCoordPointerEXT = (PFNGLTEXCOORDPOINTEREXTPROC)glewGetProcAddress((const GLubyte*)"glTexCoordPointerEXT")) == NULL) || r; + r = ((glVertexPointerEXT = (PFNGLVERTEXPOINTEREXTPROC)glewGetProcAddress((const GLubyte*)"glVertexPointerEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_vertex_array */ + +#ifdef GL_EXT_vertex_shader + +static GLboolean _glewInit_GL_EXT_vertex_shader (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glBeginVertexShaderEXT = (PFNGLBEGINVERTEXSHADEREXTPROC)glewGetProcAddress((const GLubyte*)"glBeginVertexShaderEXT")) == NULL) || r; + r = ((glBindLightParameterEXT = (PFNGLBINDLIGHTPARAMETEREXTPROC)glewGetProcAddress((const GLubyte*)"glBindLightParameterEXT")) == NULL) || r; + r = ((glBindMaterialParameterEXT = (PFNGLBINDMATERIALPARAMETEREXTPROC)glewGetProcAddress((const GLubyte*)"glBindMaterialParameterEXT")) == NULL) || r; + r = ((glBindParameterEXT = (PFNGLBINDPARAMETEREXTPROC)glewGetProcAddress((const GLubyte*)"glBindParameterEXT")) == NULL) || r; + r = ((glBindTexGenParameterEXT = (PFNGLBINDTEXGENPARAMETEREXTPROC)glewGetProcAddress((const GLubyte*)"glBindTexGenParameterEXT")) == NULL) || r; + r = ((glBindTextureUnitParameterEXT = (PFNGLBINDTEXTUREUNITPARAMETEREXTPROC)glewGetProcAddress((const GLubyte*)"glBindTextureUnitParameterEXT")) == NULL) || r; + r = ((glBindVertexShaderEXT = (PFNGLBINDVERTEXSHADEREXTPROC)glewGetProcAddress((const GLubyte*)"glBindVertexShaderEXT")) == NULL) || r; + r = ((glDeleteVertexShaderEXT = (PFNGLDELETEVERTEXSHADEREXTPROC)glewGetProcAddress((const GLubyte*)"glDeleteVertexShaderEXT")) == NULL) || r; + r = ((glDisableVariantClientStateEXT = (PFNGLDISABLEVARIANTCLIENTSTATEEXTPROC)glewGetProcAddress((const GLubyte*)"glDisableVariantClientStateEXT")) == NULL) || r; + r = ((glEnableVariantClientStateEXT = (PFNGLENABLEVARIANTCLIENTSTATEEXTPROC)glewGetProcAddress((const GLubyte*)"glEnableVariantClientStateEXT")) == NULL) || r; + r = ((glEndVertexShaderEXT = (PFNGLENDVERTEXSHADEREXTPROC)glewGetProcAddress((const GLubyte*)"glEndVertexShaderEXT")) == NULL) || r; + r = ((glExtractComponentEXT = (PFNGLEXTRACTCOMPONENTEXTPROC)glewGetProcAddress((const GLubyte*)"glExtractComponentEXT")) == NULL) || r; + r = ((glGenSymbolsEXT = (PFNGLGENSYMBOLSEXTPROC)glewGetProcAddress((const GLubyte*)"glGenSymbolsEXT")) == NULL) || r; + r = ((glGenVertexShadersEXT = (PFNGLGENVERTEXSHADERSEXTPROC)glewGetProcAddress((const GLubyte*)"glGenVertexShadersEXT")) == NULL) || r; + r = ((glGetInvariantBooleanvEXT = (PFNGLGETINVARIANTBOOLEANVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetInvariantBooleanvEXT")) == NULL) || r; + r = ((glGetInvariantFloatvEXT = (PFNGLGETINVARIANTFLOATVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetInvariantFloatvEXT")) == NULL) || r; + r = ((glGetInvariantIntegervEXT = (PFNGLGETINVARIANTINTEGERVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetInvariantIntegervEXT")) == NULL) || r; + r = ((glGetLocalConstantBooleanvEXT = (PFNGLGETLOCALCONSTANTBOOLEANVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetLocalConstantBooleanvEXT")) == NULL) || r; + r = ((glGetLocalConstantFloatvEXT = (PFNGLGETLOCALCONSTANTFLOATVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetLocalConstantFloatvEXT")) == NULL) || r; + r = ((glGetLocalConstantIntegervEXT = (PFNGLGETLOCALCONSTANTINTEGERVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetLocalConstantIntegervEXT")) == NULL) || r; + r = ((glGetVariantBooleanvEXT = (PFNGLGETVARIANTBOOLEANVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetVariantBooleanvEXT")) == NULL) || r; + r = ((glGetVariantFloatvEXT = (PFNGLGETVARIANTFLOATVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetVariantFloatvEXT")) == NULL) || r; + r = ((glGetVariantIntegervEXT = (PFNGLGETVARIANTINTEGERVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetVariantIntegervEXT")) == NULL) || r; + r = ((glGetVariantPointervEXT = (PFNGLGETVARIANTPOINTERVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetVariantPointervEXT")) == NULL) || r; + r = ((glInsertComponentEXT = (PFNGLINSERTCOMPONENTEXTPROC)glewGetProcAddress((const GLubyte*)"glInsertComponentEXT")) == NULL) || r; + r = ((glIsVariantEnabledEXT = (PFNGLISVARIANTENABLEDEXTPROC)glewGetProcAddress((const GLubyte*)"glIsVariantEnabledEXT")) == NULL) || r; + r = ((glSetInvariantEXT = (PFNGLSETINVARIANTEXTPROC)glewGetProcAddress((const GLubyte*)"glSetInvariantEXT")) == NULL) || r; + r = ((glSetLocalConstantEXT = (PFNGLSETLOCALCONSTANTEXTPROC)glewGetProcAddress((const GLubyte*)"glSetLocalConstantEXT")) == NULL) || r; + r = ((glShaderOp1EXT = (PFNGLSHADEROP1EXTPROC)glewGetProcAddress((const GLubyte*)"glShaderOp1EXT")) == NULL) || r; + r = ((glShaderOp2EXT = (PFNGLSHADEROP2EXTPROC)glewGetProcAddress((const GLubyte*)"glShaderOp2EXT")) == NULL) || r; + r = ((glShaderOp3EXT = (PFNGLSHADEROP3EXTPROC)glewGetProcAddress((const GLubyte*)"glShaderOp3EXT")) == NULL) || r; + r = ((glSwizzleEXT = (PFNGLSWIZZLEEXTPROC)glewGetProcAddress((const GLubyte*)"glSwizzleEXT")) == NULL) || r; + r = ((glVariantPointerEXT = (PFNGLVARIANTPOINTEREXTPROC)glewGetProcAddress((const GLubyte*)"glVariantPointerEXT")) == NULL) || r; + r = ((glVariantbvEXT = (PFNGLVARIANTBVEXTPROC)glewGetProcAddress((const GLubyte*)"glVariantbvEXT")) == NULL) || r; + r = ((glVariantdvEXT = (PFNGLVARIANTDVEXTPROC)glewGetProcAddress((const GLubyte*)"glVariantdvEXT")) == NULL) || r; + r = ((glVariantfvEXT = (PFNGLVARIANTFVEXTPROC)glewGetProcAddress((const GLubyte*)"glVariantfvEXT")) == NULL) || r; + r = ((glVariantivEXT = (PFNGLVARIANTIVEXTPROC)glewGetProcAddress((const GLubyte*)"glVariantivEXT")) == NULL) || r; + r = ((glVariantsvEXT = (PFNGLVARIANTSVEXTPROC)glewGetProcAddress((const GLubyte*)"glVariantsvEXT")) == NULL) || r; + r = ((glVariantubvEXT = (PFNGLVARIANTUBVEXTPROC)glewGetProcAddress((const GLubyte*)"glVariantubvEXT")) == NULL) || r; + r = ((glVariantuivEXT = (PFNGLVARIANTUIVEXTPROC)glewGetProcAddress((const GLubyte*)"glVariantuivEXT")) == NULL) || r; + r = ((glVariantusvEXT = (PFNGLVARIANTUSVEXTPROC)glewGetProcAddress((const GLubyte*)"glVariantusvEXT")) == NULL) || r; + r = ((glWriteMaskEXT = (PFNGLWRITEMASKEXTPROC)glewGetProcAddress((const GLubyte*)"glWriteMaskEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_vertex_shader */ + +#ifdef GL_EXT_vertex_weighting + +static GLboolean _glewInit_GL_EXT_vertex_weighting (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glVertexWeightPointerEXT = (PFNGLVERTEXWEIGHTPOINTEREXTPROC)glewGetProcAddress((const GLubyte*)"glVertexWeightPointerEXT")) == NULL) || r; + r = ((glVertexWeightfEXT = (PFNGLVERTEXWEIGHTFEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexWeightfEXT")) == NULL) || r; + r = ((glVertexWeightfvEXT = (PFNGLVERTEXWEIGHTFVEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexWeightfvEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_vertex_weighting */ + +#ifdef GL_GREMEDY_string_marker + +static GLboolean _glewInit_GL_GREMEDY_string_marker (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glStringMarkerGREMEDY = (PFNGLSTRINGMARKERGREMEDYPROC)glewGetProcAddress((const GLubyte*)"glStringMarkerGREMEDY")) == NULL) || r; + + return r; +} + +#endif /* GL_GREMEDY_string_marker */ + +#ifdef GL_HP_convolution_border_modes + +#endif /* GL_HP_convolution_border_modes */ + +#ifdef GL_HP_image_transform + +static GLboolean _glewInit_GL_HP_image_transform (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glGetImageTransformParameterfvHP = (PFNGLGETIMAGETRANSFORMPARAMETERFVHPPROC)glewGetProcAddress((const GLubyte*)"glGetImageTransformParameterfvHP")) == NULL) || r; + r = ((glGetImageTransformParameterivHP = (PFNGLGETIMAGETRANSFORMPARAMETERIVHPPROC)glewGetProcAddress((const GLubyte*)"glGetImageTransformParameterivHP")) == NULL) || r; + r = ((glImageTransformParameterfHP = (PFNGLIMAGETRANSFORMPARAMETERFHPPROC)glewGetProcAddress((const GLubyte*)"glImageTransformParameterfHP")) == NULL) || r; + r = ((glImageTransformParameterfvHP = (PFNGLIMAGETRANSFORMPARAMETERFVHPPROC)glewGetProcAddress((const GLubyte*)"glImageTransformParameterfvHP")) == NULL) || r; + r = ((glImageTransformParameteriHP = (PFNGLIMAGETRANSFORMPARAMETERIHPPROC)glewGetProcAddress((const GLubyte*)"glImageTransformParameteriHP")) == NULL) || r; + r = ((glImageTransformParameterivHP = (PFNGLIMAGETRANSFORMPARAMETERIVHPPROC)glewGetProcAddress((const GLubyte*)"glImageTransformParameterivHP")) == NULL) || r; + + return r; +} + +#endif /* GL_HP_image_transform */ + +#ifdef GL_HP_occlusion_test + +#endif /* GL_HP_occlusion_test */ + +#ifdef GL_HP_texture_lighting + +#endif /* GL_HP_texture_lighting */ + +#ifdef GL_IBM_cull_vertex + +#endif /* GL_IBM_cull_vertex */ + +#ifdef GL_IBM_multimode_draw_arrays + +static GLboolean _glewInit_GL_IBM_multimode_draw_arrays (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glMultiModeDrawArraysIBM = (PFNGLMULTIMODEDRAWARRAYSIBMPROC)glewGetProcAddress((const GLubyte*)"glMultiModeDrawArraysIBM")) == NULL) || r; + r = ((glMultiModeDrawElementsIBM = (PFNGLMULTIMODEDRAWELEMENTSIBMPROC)glewGetProcAddress((const GLubyte*)"glMultiModeDrawElementsIBM")) == NULL) || r; + + return r; +} + +#endif /* GL_IBM_multimode_draw_arrays */ + +#ifdef GL_IBM_rasterpos_clip + +#endif /* GL_IBM_rasterpos_clip */ + +#ifdef GL_IBM_static_data + +#endif /* GL_IBM_static_data */ + +#ifdef GL_IBM_texture_mirrored_repeat + +#endif /* GL_IBM_texture_mirrored_repeat */ + +#ifdef GL_IBM_vertex_array_lists + +static GLboolean _glewInit_GL_IBM_vertex_array_lists (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glColorPointerListIBM = (PFNGLCOLORPOINTERLISTIBMPROC)glewGetProcAddress((const GLubyte*)"glColorPointerListIBM")) == NULL) || r; + r = ((glEdgeFlagPointerListIBM = (PFNGLEDGEFLAGPOINTERLISTIBMPROC)glewGetProcAddress((const GLubyte*)"glEdgeFlagPointerListIBM")) == NULL) || r; + r = ((glFogCoordPointerListIBM = (PFNGLFOGCOORDPOINTERLISTIBMPROC)glewGetProcAddress((const GLubyte*)"glFogCoordPointerListIBM")) == NULL) || r; + r = ((glIndexPointerListIBM = (PFNGLINDEXPOINTERLISTIBMPROC)glewGetProcAddress((const GLubyte*)"glIndexPointerListIBM")) == NULL) || r; + r = ((glNormalPointerListIBM = (PFNGLNORMALPOINTERLISTIBMPROC)glewGetProcAddress((const GLubyte*)"glNormalPointerListIBM")) == NULL) || r; + r = ((glSecondaryColorPointerListIBM = (PFNGLSECONDARYCOLORPOINTERLISTIBMPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColorPointerListIBM")) == NULL) || r; + r = ((glTexCoordPointerListIBM = (PFNGLTEXCOORDPOINTERLISTIBMPROC)glewGetProcAddress((const GLubyte*)"glTexCoordPointerListIBM")) == NULL) || r; + r = ((glVertexPointerListIBM = (PFNGLVERTEXPOINTERLISTIBMPROC)glewGetProcAddress((const GLubyte*)"glVertexPointerListIBM")) == NULL) || r; + + return r; +} + +#endif /* GL_IBM_vertex_array_lists */ + +#ifdef GL_INGR_color_clamp + +#endif /* GL_INGR_color_clamp */ + +#ifdef GL_INGR_interlace_read + +#endif /* GL_INGR_interlace_read */ + +#ifdef GL_INTEL_parallel_arrays + +static GLboolean _glewInit_GL_INTEL_parallel_arrays (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glColorPointervINTEL = (PFNGLCOLORPOINTERVINTELPROC)glewGetProcAddress((const GLubyte*)"glColorPointervINTEL")) == NULL) || r; + r = ((glNormalPointervINTEL = (PFNGLNORMALPOINTERVINTELPROC)glewGetProcAddress((const GLubyte*)"glNormalPointervINTEL")) == NULL) || r; + r = ((glTexCoordPointervINTEL = (PFNGLTEXCOORDPOINTERVINTELPROC)glewGetProcAddress((const GLubyte*)"glTexCoordPointervINTEL")) == NULL) || r; + r = ((glVertexPointervINTEL = (PFNGLVERTEXPOINTERVINTELPROC)glewGetProcAddress((const GLubyte*)"glVertexPointervINTEL")) == NULL) || r; + + return r; +} + +#endif /* GL_INTEL_parallel_arrays */ + +#ifdef GL_INTEL_texture_scissor + +static GLboolean _glewInit_GL_INTEL_texture_scissor (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glTexScissorFuncINTEL = (PFNGLTEXSCISSORFUNCINTELPROC)glewGetProcAddress((const GLubyte*)"glTexScissorFuncINTEL")) == NULL) || r; + r = ((glTexScissorINTEL = (PFNGLTEXSCISSORINTELPROC)glewGetProcAddress((const GLubyte*)"glTexScissorINTEL")) == NULL) || r; + + return r; +} + +#endif /* GL_INTEL_texture_scissor */ + +#ifdef GL_KTX_buffer_region + +static GLboolean _glewInit_GL_KTX_buffer_region (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glBufferRegionEnabledEXT = (PFNGLBUFFERREGIONENABLEDEXTPROC)glewGetProcAddress((const GLubyte*)"glBufferRegionEnabledEXT")) == NULL) || r; + r = ((glDeleteBufferRegionEXT = (PFNGLDELETEBUFFERREGIONEXTPROC)glewGetProcAddress((const GLubyte*)"glDeleteBufferRegionEXT")) == NULL) || r; + r = ((glDrawBufferRegionEXT = (PFNGLDRAWBUFFERREGIONEXTPROC)glewGetProcAddress((const GLubyte*)"glDrawBufferRegionEXT")) == NULL) || r; + r = ((glNewBufferRegionEXT = (PFNGLNEWBUFFERREGIONEXTPROC)glewGetProcAddress((const GLubyte*)"glNewBufferRegionEXT")) == NULL) || r; + r = ((glReadBufferRegionEXT = (PFNGLREADBUFFERREGIONEXTPROC)glewGetProcAddress((const GLubyte*)"glReadBufferRegionEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_KTX_buffer_region */ + +#ifdef GL_MESAX_texture_stack + +#endif /* GL_MESAX_texture_stack */ + +#ifdef GL_MESA_pack_invert + +#endif /* GL_MESA_pack_invert */ + +#ifdef GL_MESA_resize_buffers + +static GLboolean _glewInit_GL_MESA_resize_buffers (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glResizeBuffersMESA = (PFNGLRESIZEBUFFERSMESAPROC)glewGetProcAddress((const GLubyte*)"glResizeBuffersMESA")) == NULL) || r; + + return r; +} + +#endif /* GL_MESA_resize_buffers */ + +#ifdef GL_MESA_window_pos + +static GLboolean _glewInit_GL_MESA_window_pos (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glWindowPos2dMESA = (PFNGLWINDOWPOS2DMESAPROC)glewGetProcAddress((const GLubyte*)"glWindowPos2dMESA")) == NULL) || r; + r = ((glWindowPos2dvMESA = (PFNGLWINDOWPOS2DVMESAPROC)glewGetProcAddress((const GLubyte*)"glWindowPos2dvMESA")) == NULL) || r; + r = ((glWindowPos2fMESA = (PFNGLWINDOWPOS2FMESAPROC)glewGetProcAddress((const GLubyte*)"glWindowPos2fMESA")) == NULL) || r; + r = ((glWindowPos2fvMESA = (PFNGLWINDOWPOS2FVMESAPROC)glewGetProcAddress((const GLubyte*)"glWindowPos2fvMESA")) == NULL) || r; + r = ((glWindowPos2iMESA = (PFNGLWINDOWPOS2IMESAPROC)glewGetProcAddress((const GLubyte*)"glWindowPos2iMESA")) == NULL) || r; + r = ((glWindowPos2ivMESA = (PFNGLWINDOWPOS2IVMESAPROC)glewGetProcAddress((const GLubyte*)"glWindowPos2ivMESA")) == NULL) || r; + r = ((glWindowPos2sMESA = (PFNGLWINDOWPOS2SMESAPROC)glewGetProcAddress((const GLubyte*)"glWindowPos2sMESA")) == NULL) || r; + r = ((glWindowPos2svMESA = (PFNGLWINDOWPOS2SVMESAPROC)glewGetProcAddress((const GLubyte*)"glWindowPos2svMESA")) == NULL) || r; + r = ((glWindowPos3dMESA = (PFNGLWINDOWPOS3DMESAPROC)glewGetProcAddress((const GLubyte*)"glWindowPos3dMESA")) == NULL) || r; + r = ((glWindowPos3dvMESA = (PFNGLWINDOWPOS3DVMESAPROC)glewGetProcAddress((const GLubyte*)"glWindowPos3dvMESA")) == NULL) || r; + r = ((glWindowPos3fMESA = (PFNGLWINDOWPOS3FMESAPROC)glewGetProcAddress((const GLubyte*)"glWindowPos3fMESA")) == NULL) || r; + r = ((glWindowPos3fvMESA = (PFNGLWINDOWPOS3FVMESAPROC)glewGetProcAddress((const GLubyte*)"glWindowPos3fvMESA")) == NULL) || r; + r = ((glWindowPos3iMESA = (PFNGLWINDOWPOS3IMESAPROC)glewGetProcAddress((const GLubyte*)"glWindowPos3iMESA")) == NULL) || r; + r = ((glWindowPos3ivMESA = (PFNGLWINDOWPOS3IVMESAPROC)glewGetProcAddress((const GLubyte*)"glWindowPos3ivMESA")) == NULL) || r; + r = ((glWindowPos3sMESA = (PFNGLWINDOWPOS3SMESAPROC)glewGetProcAddress((const GLubyte*)"glWindowPos3sMESA")) == NULL) || r; + r = ((glWindowPos3svMESA = (PFNGLWINDOWPOS3SVMESAPROC)glewGetProcAddress((const GLubyte*)"glWindowPos3svMESA")) == NULL) || r; + r = ((glWindowPos4dMESA = (PFNGLWINDOWPOS4DMESAPROC)glewGetProcAddress((const GLubyte*)"glWindowPos4dMESA")) == NULL) || r; + r = ((glWindowPos4dvMESA = (PFNGLWINDOWPOS4DVMESAPROC)glewGetProcAddress((const GLubyte*)"glWindowPos4dvMESA")) == NULL) || r; + r = ((glWindowPos4fMESA = (PFNGLWINDOWPOS4FMESAPROC)glewGetProcAddress((const GLubyte*)"glWindowPos4fMESA")) == NULL) || r; + r = ((glWindowPos4fvMESA = (PFNGLWINDOWPOS4FVMESAPROC)glewGetProcAddress((const GLubyte*)"glWindowPos4fvMESA")) == NULL) || r; + r = ((glWindowPos4iMESA = (PFNGLWINDOWPOS4IMESAPROC)glewGetProcAddress((const GLubyte*)"glWindowPos4iMESA")) == NULL) || r; + r = ((glWindowPos4ivMESA = (PFNGLWINDOWPOS4IVMESAPROC)glewGetProcAddress((const GLubyte*)"glWindowPos4ivMESA")) == NULL) || r; + r = ((glWindowPos4sMESA = (PFNGLWINDOWPOS4SMESAPROC)glewGetProcAddress((const GLubyte*)"glWindowPos4sMESA")) == NULL) || r; + r = ((glWindowPos4svMESA = (PFNGLWINDOWPOS4SVMESAPROC)glewGetProcAddress((const GLubyte*)"glWindowPos4svMESA")) == NULL) || r; + + return r; +} + +#endif /* GL_MESA_window_pos */ + +#ifdef GL_MESA_ycbcr_texture + +#endif /* GL_MESA_ycbcr_texture */ + +#ifdef GL_NV_blend_square + +#endif /* GL_NV_blend_square */ + +#ifdef GL_NV_copy_depth_to_color + +#endif /* GL_NV_copy_depth_to_color */ + +#ifdef GL_NV_depth_clamp + +#endif /* GL_NV_depth_clamp */ + +#ifdef GL_NV_evaluators + +static GLboolean _glewInit_GL_NV_evaluators (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glEvalMapsNV = (PFNGLEVALMAPSNVPROC)glewGetProcAddress((const GLubyte*)"glEvalMapsNV")) == NULL) || r; + r = ((glGetMapAttribParameterfvNV = (PFNGLGETMAPATTRIBPARAMETERFVNVPROC)glewGetProcAddress((const GLubyte*)"glGetMapAttribParameterfvNV")) == NULL) || r; + r = ((glGetMapAttribParameterivNV = (PFNGLGETMAPATTRIBPARAMETERIVNVPROC)glewGetProcAddress((const GLubyte*)"glGetMapAttribParameterivNV")) == NULL) || r; + r = ((glGetMapControlPointsNV = (PFNGLGETMAPCONTROLPOINTSNVPROC)glewGetProcAddress((const GLubyte*)"glGetMapControlPointsNV")) == NULL) || r; + r = ((glGetMapParameterfvNV = (PFNGLGETMAPPARAMETERFVNVPROC)glewGetProcAddress((const GLubyte*)"glGetMapParameterfvNV")) == NULL) || r; + r = ((glGetMapParameterivNV = (PFNGLGETMAPPARAMETERIVNVPROC)glewGetProcAddress((const GLubyte*)"glGetMapParameterivNV")) == NULL) || r; + r = ((glMapControlPointsNV = (PFNGLMAPCONTROLPOINTSNVPROC)glewGetProcAddress((const GLubyte*)"glMapControlPointsNV")) == NULL) || r; + r = ((glMapParameterfvNV = (PFNGLMAPPARAMETERFVNVPROC)glewGetProcAddress((const GLubyte*)"glMapParameterfvNV")) == NULL) || r; + r = ((glMapParameterivNV = (PFNGLMAPPARAMETERIVNVPROC)glewGetProcAddress((const GLubyte*)"glMapParameterivNV")) == NULL) || r; + + return r; +} + +#endif /* GL_NV_evaluators */ + +#ifdef GL_NV_fence + +static GLboolean _glewInit_GL_NV_fence (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glDeleteFencesNV = (PFNGLDELETEFENCESNVPROC)glewGetProcAddress((const GLubyte*)"glDeleteFencesNV")) == NULL) || r; + r = ((glFinishFenceNV = (PFNGLFINISHFENCENVPROC)glewGetProcAddress((const GLubyte*)"glFinishFenceNV")) == NULL) || r; + r = ((glGenFencesNV = (PFNGLGENFENCESNVPROC)glewGetProcAddress((const GLubyte*)"glGenFencesNV")) == NULL) || r; + r = ((glGetFenceivNV = (PFNGLGETFENCEIVNVPROC)glewGetProcAddress((const GLubyte*)"glGetFenceivNV")) == NULL) || r; + r = ((glIsFenceNV = (PFNGLISFENCENVPROC)glewGetProcAddress((const GLubyte*)"glIsFenceNV")) == NULL) || r; + r = ((glSetFenceNV = (PFNGLSETFENCENVPROC)glewGetProcAddress((const GLubyte*)"glSetFenceNV")) == NULL) || r; + r = ((glTestFenceNV = (PFNGLTESTFENCENVPROC)glewGetProcAddress((const GLubyte*)"glTestFenceNV")) == NULL) || r; + + return r; +} + +#endif /* GL_NV_fence */ + +#ifdef GL_NV_float_buffer + +#endif /* GL_NV_float_buffer */ + +#ifdef GL_NV_fog_distance + +#endif /* GL_NV_fog_distance */ + +#ifdef GL_NV_fragment_program + +static GLboolean _glewInit_GL_NV_fragment_program (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glGetProgramNamedParameterdvNV = (PFNGLGETPROGRAMNAMEDPARAMETERDVNVPROC)glewGetProcAddress((const GLubyte*)"glGetProgramNamedParameterdvNV")) == NULL) || r; + r = ((glGetProgramNamedParameterfvNV = (PFNGLGETPROGRAMNAMEDPARAMETERFVNVPROC)glewGetProcAddress((const GLubyte*)"glGetProgramNamedParameterfvNV")) == NULL) || r; + r = ((glProgramNamedParameter4dNV = (PFNGLPROGRAMNAMEDPARAMETER4DNVPROC)glewGetProcAddress((const GLubyte*)"glProgramNamedParameter4dNV")) == NULL) || r; + r = ((glProgramNamedParameter4dvNV = (PFNGLPROGRAMNAMEDPARAMETER4DVNVPROC)glewGetProcAddress((const GLubyte*)"glProgramNamedParameter4dvNV")) == NULL) || r; + r = ((glProgramNamedParameter4fNV = (PFNGLPROGRAMNAMEDPARAMETER4FNVPROC)glewGetProcAddress((const GLubyte*)"glProgramNamedParameter4fNV")) == NULL) || r; + r = ((glProgramNamedParameter4fvNV = (PFNGLPROGRAMNAMEDPARAMETER4FVNVPROC)glewGetProcAddress((const GLubyte*)"glProgramNamedParameter4fvNV")) == NULL) || r; + + return r; +} + +#endif /* GL_NV_fragment_program */ + +#ifdef GL_NV_fragment_program2 + +#endif /* GL_NV_fragment_program2 */ + +#ifdef GL_NV_fragment_program_option + +#endif /* GL_NV_fragment_program_option */ + +#ifdef GL_NV_half_float + +static GLboolean _glewInit_GL_NV_half_float (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glColor3hNV = (PFNGLCOLOR3HNVPROC)glewGetProcAddress((const GLubyte*)"glColor3hNV")) == NULL) || r; + r = ((glColor3hvNV = (PFNGLCOLOR3HVNVPROC)glewGetProcAddress((const GLubyte*)"glColor3hvNV")) == NULL) || r; + r = ((glColor4hNV = (PFNGLCOLOR4HNVPROC)glewGetProcAddress((const GLubyte*)"glColor4hNV")) == NULL) || r; + r = ((glColor4hvNV = (PFNGLCOLOR4HVNVPROC)glewGetProcAddress((const GLubyte*)"glColor4hvNV")) == NULL) || r; + r = ((glFogCoordhNV = (PFNGLFOGCOORDHNVPROC)glewGetProcAddress((const GLubyte*)"glFogCoordhNV")) == NULL) || r; + r = ((glFogCoordhvNV = (PFNGLFOGCOORDHVNVPROC)glewGetProcAddress((const GLubyte*)"glFogCoordhvNV")) == NULL) || r; + r = ((glMultiTexCoord1hNV = (PFNGLMULTITEXCOORD1HNVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord1hNV")) == NULL) || r; + r = ((glMultiTexCoord1hvNV = (PFNGLMULTITEXCOORD1HVNVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord1hvNV")) == NULL) || r; + r = ((glMultiTexCoord2hNV = (PFNGLMULTITEXCOORD2HNVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord2hNV")) == NULL) || r; + r = ((glMultiTexCoord2hvNV = (PFNGLMULTITEXCOORD2HVNVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord2hvNV")) == NULL) || r; + r = ((glMultiTexCoord3hNV = (PFNGLMULTITEXCOORD3HNVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord3hNV")) == NULL) || r; + r = ((glMultiTexCoord3hvNV = (PFNGLMULTITEXCOORD3HVNVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord3hvNV")) == NULL) || r; + r = ((glMultiTexCoord4hNV = (PFNGLMULTITEXCOORD4HNVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord4hNV")) == NULL) || r; + r = ((glMultiTexCoord4hvNV = (PFNGLMULTITEXCOORD4HVNVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord4hvNV")) == NULL) || r; + r = ((glNormal3hNV = (PFNGLNORMAL3HNVPROC)glewGetProcAddress((const GLubyte*)"glNormal3hNV")) == NULL) || r; + r = ((glNormal3hvNV = (PFNGLNORMAL3HVNVPROC)glewGetProcAddress((const GLubyte*)"glNormal3hvNV")) == NULL) || r; + r = ((glSecondaryColor3hNV = (PFNGLSECONDARYCOLOR3HNVPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3hNV")) == NULL) || r; + r = ((glSecondaryColor3hvNV = (PFNGLSECONDARYCOLOR3HVNVPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3hvNV")) == NULL) || r; + r = ((glTexCoord1hNV = (PFNGLTEXCOORD1HNVPROC)glewGetProcAddress((const GLubyte*)"glTexCoord1hNV")) == NULL) || r; + r = ((glTexCoord1hvNV = (PFNGLTEXCOORD1HVNVPROC)glewGetProcAddress((const GLubyte*)"glTexCoord1hvNV")) == NULL) || r; + r = ((glTexCoord2hNV = (PFNGLTEXCOORD2HNVPROC)glewGetProcAddress((const GLubyte*)"glTexCoord2hNV")) == NULL) || r; + r = ((glTexCoord2hvNV = (PFNGLTEXCOORD2HVNVPROC)glewGetProcAddress((const GLubyte*)"glTexCoord2hvNV")) == NULL) || r; + r = ((glTexCoord3hNV = (PFNGLTEXCOORD3HNVPROC)glewGetProcAddress((const GLubyte*)"glTexCoord3hNV")) == NULL) || r; + r = ((glTexCoord3hvNV = (PFNGLTEXCOORD3HVNVPROC)glewGetProcAddress((const GLubyte*)"glTexCoord3hvNV")) == NULL) || r; + r = ((glTexCoord4hNV = (PFNGLTEXCOORD4HNVPROC)glewGetProcAddress((const GLubyte*)"glTexCoord4hNV")) == NULL) || r; + r = ((glTexCoord4hvNV = (PFNGLTEXCOORD4HVNVPROC)glewGetProcAddress((const GLubyte*)"glTexCoord4hvNV")) == NULL) || r; + r = ((glVertex2hNV = (PFNGLVERTEX2HNVPROC)glewGetProcAddress((const GLubyte*)"glVertex2hNV")) == NULL) || r; + r = ((glVertex2hvNV = (PFNGLVERTEX2HVNVPROC)glewGetProcAddress((const GLubyte*)"glVertex2hvNV")) == NULL) || r; + r = ((glVertex3hNV = (PFNGLVERTEX3HNVPROC)glewGetProcAddress((const GLubyte*)"glVertex3hNV")) == NULL) || r; + r = ((glVertex3hvNV = (PFNGLVERTEX3HVNVPROC)glewGetProcAddress((const GLubyte*)"glVertex3hvNV")) == NULL) || r; + r = ((glVertex4hNV = (PFNGLVERTEX4HNVPROC)glewGetProcAddress((const GLubyte*)"glVertex4hNV")) == NULL) || r; + r = ((glVertex4hvNV = (PFNGLVERTEX4HVNVPROC)glewGetProcAddress((const GLubyte*)"glVertex4hvNV")) == NULL) || r; + r = ((glVertexAttrib1hNV = (PFNGLVERTEXATTRIB1HNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib1hNV")) == NULL) || r; + r = ((glVertexAttrib1hvNV = (PFNGLVERTEXATTRIB1HVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib1hvNV")) == NULL) || r; + r = ((glVertexAttrib2hNV = (PFNGLVERTEXATTRIB2HNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib2hNV")) == NULL) || r; + r = ((glVertexAttrib2hvNV = (PFNGLVERTEXATTRIB2HVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib2hvNV")) == NULL) || r; + r = ((glVertexAttrib3hNV = (PFNGLVERTEXATTRIB3HNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib3hNV")) == NULL) || r; + r = ((glVertexAttrib3hvNV = (PFNGLVERTEXATTRIB3HVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib3hvNV")) == NULL) || r; + r = ((glVertexAttrib4hNV = (PFNGLVERTEXATTRIB4HNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4hNV")) == NULL) || r; + r = ((glVertexAttrib4hvNV = (PFNGLVERTEXATTRIB4HVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4hvNV")) == NULL) || r; + r = ((glVertexAttribs1hvNV = (PFNGLVERTEXATTRIBS1HVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribs1hvNV")) == NULL) || r; + r = ((glVertexAttribs2hvNV = (PFNGLVERTEXATTRIBS2HVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribs2hvNV")) == NULL) || r; + r = ((glVertexAttribs3hvNV = (PFNGLVERTEXATTRIBS3HVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribs3hvNV")) == NULL) || r; + r = ((glVertexAttribs4hvNV = (PFNGLVERTEXATTRIBS4HVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribs4hvNV")) == NULL) || r; + r = ((glVertexWeighthNV = (PFNGLVERTEXWEIGHTHNVPROC)glewGetProcAddress((const GLubyte*)"glVertexWeighthNV")) == NULL) || r; + r = ((glVertexWeighthvNV = (PFNGLVERTEXWEIGHTHVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexWeighthvNV")) == NULL) || r; + + return r; +} + +#endif /* GL_NV_half_float */ + +#ifdef GL_NV_light_max_exponent + +#endif /* GL_NV_light_max_exponent */ + +#ifdef GL_NV_multisample_filter_hint + +#endif /* GL_NV_multisample_filter_hint */ + +#ifdef GL_NV_occlusion_query + +static GLboolean _glewInit_GL_NV_occlusion_query (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glBeginOcclusionQueryNV = (PFNGLBEGINOCCLUSIONQUERYNVPROC)glewGetProcAddress((const GLubyte*)"glBeginOcclusionQueryNV")) == NULL) || r; + r = ((glDeleteOcclusionQueriesNV = (PFNGLDELETEOCCLUSIONQUERIESNVPROC)glewGetProcAddress((const GLubyte*)"glDeleteOcclusionQueriesNV")) == NULL) || r; + r = ((glEndOcclusionQueryNV = (PFNGLENDOCCLUSIONQUERYNVPROC)glewGetProcAddress((const GLubyte*)"glEndOcclusionQueryNV")) == NULL) || r; + r = ((glGenOcclusionQueriesNV = (PFNGLGENOCCLUSIONQUERIESNVPROC)glewGetProcAddress((const GLubyte*)"glGenOcclusionQueriesNV")) == NULL) || r; + r = ((glGetOcclusionQueryivNV = (PFNGLGETOCCLUSIONQUERYIVNVPROC)glewGetProcAddress((const GLubyte*)"glGetOcclusionQueryivNV")) == NULL) || r; + r = ((glGetOcclusionQueryuivNV = (PFNGLGETOCCLUSIONQUERYUIVNVPROC)glewGetProcAddress((const GLubyte*)"glGetOcclusionQueryuivNV")) == NULL) || r; + r = ((glIsOcclusionQueryNV = (PFNGLISOCCLUSIONQUERYNVPROC)glewGetProcAddress((const GLubyte*)"glIsOcclusionQueryNV")) == NULL) || r; + + return r; +} + +#endif /* GL_NV_occlusion_query */ + +#ifdef GL_NV_packed_depth_stencil + +#endif /* GL_NV_packed_depth_stencil */ + +#ifdef GL_NV_pixel_data_range + +static GLboolean _glewInit_GL_NV_pixel_data_range (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glFlushPixelDataRangeNV = (PFNGLFLUSHPIXELDATARANGENVPROC)glewGetProcAddress((const GLubyte*)"glFlushPixelDataRangeNV")) == NULL) || r; + r = ((glPixelDataRangeNV = (PFNGLPIXELDATARANGENVPROC)glewGetProcAddress((const GLubyte*)"glPixelDataRangeNV")) == NULL) || r; + + return r; +} + +#endif /* GL_NV_pixel_data_range */ + +#ifdef GL_NV_point_sprite + +static GLboolean _glewInit_GL_NV_point_sprite (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glPointParameteriNV = (PFNGLPOINTPARAMETERINVPROC)glewGetProcAddress((const GLubyte*)"glPointParameteriNV")) == NULL) || r; + r = ((glPointParameterivNV = (PFNGLPOINTPARAMETERIVNVPROC)glewGetProcAddress((const GLubyte*)"glPointParameterivNV")) == NULL) || r; + + return r; +} + +#endif /* GL_NV_point_sprite */ + +#ifdef GL_NV_primitive_restart + +static GLboolean _glewInit_GL_NV_primitive_restart (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glPrimitiveRestartIndexNV = (PFNGLPRIMITIVERESTARTINDEXNVPROC)glewGetProcAddress((const GLubyte*)"glPrimitiveRestartIndexNV")) == NULL) || r; + r = ((glPrimitiveRestartNV = (PFNGLPRIMITIVERESTARTNVPROC)glewGetProcAddress((const GLubyte*)"glPrimitiveRestartNV")) == NULL) || r; + + return r; +} + +#endif /* GL_NV_primitive_restart */ + +#ifdef GL_NV_register_combiners + +static GLboolean _glewInit_GL_NV_register_combiners (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glCombinerInputNV = (PFNGLCOMBINERINPUTNVPROC)glewGetProcAddress((const GLubyte*)"glCombinerInputNV")) == NULL) || r; + r = ((glCombinerOutputNV = (PFNGLCOMBINEROUTPUTNVPROC)glewGetProcAddress((const GLubyte*)"glCombinerOutputNV")) == NULL) || r; + r = ((glCombinerParameterfNV = (PFNGLCOMBINERPARAMETERFNVPROC)glewGetProcAddress((const GLubyte*)"glCombinerParameterfNV")) == NULL) || r; + r = ((glCombinerParameterfvNV = (PFNGLCOMBINERPARAMETERFVNVPROC)glewGetProcAddress((const GLubyte*)"glCombinerParameterfvNV")) == NULL) || r; + r = ((glCombinerParameteriNV = (PFNGLCOMBINERPARAMETERINVPROC)glewGetProcAddress((const GLubyte*)"glCombinerParameteriNV")) == NULL) || r; + r = ((glCombinerParameterivNV = (PFNGLCOMBINERPARAMETERIVNVPROC)glewGetProcAddress((const GLubyte*)"glCombinerParameterivNV")) == NULL) || r; + r = ((glFinalCombinerInputNV = (PFNGLFINALCOMBINERINPUTNVPROC)glewGetProcAddress((const GLubyte*)"glFinalCombinerInputNV")) == NULL) || r; + r = ((glGetCombinerInputParameterfvNV = (PFNGLGETCOMBINERINPUTPARAMETERFVNVPROC)glewGetProcAddress((const GLubyte*)"glGetCombinerInputParameterfvNV")) == NULL) || r; + r = ((glGetCombinerInputParameterivNV = (PFNGLGETCOMBINERINPUTPARAMETERIVNVPROC)glewGetProcAddress((const GLubyte*)"glGetCombinerInputParameterivNV")) == NULL) || r; + r = ((glGetCombinerOutputParameterfvNV = (PFNGLGETCOMBINEROUTPUTPARAMETERFVNVPROC)glewGetProcAddress((const GLubyte*)"glGetCombinerOutputParameterfvNV")) == NULL) || r; + r = ((glGetCombinerOutputParameterivNV = (PFNGLGETCOMBINEROUTPUTPARAMETERIVNVPROC)glewGetProcAddress((const GLubyte*)"glGetCombinerOutputParameterivNV")) == NULL) || r; + r = ((glGetFinalCombinerInputParameterfvNV = (PFNGLGETFINALCOMBINERINPUTPARAMETERFVNVPROC)glewGetProcAddress((const GLubyte*)"glGetFinalCombinerInputParameterfvNV")) == NULL) || r; + r = ((glGetFinalCombinerInputParameterivNV = (PFNGLGETFINALCOMBINERINPUTPARAMETERIVNVPROC)glewGetProcAddress((const GLubyte*)"glGetFinalCombinerInputParameterivNV")) == NULL) || r; + + return r; +} + +#endif /* GL_NV_register_combiners */ + +#ifdef GL_NV_register_combiners2 + +static GLboolean _glewInit_GL_NV_register_combiners2 (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glCombinerStageParameterfvNV = (PFNGLCOMBINERSTAGEPARAMETERFVNVPROC)glewGetProcAddress((const GLubyte*)"glCombinerStageParameterfvNV")) == NULL) || r; + r = ((glGetCombinerStageParameterfvNV = (PFNGLGETCOMBINERSTAGEPARAMETERFVNVPROC)glewGetProcAddress((const GLubyte*)"glGetCombinerStageParameterfvNV")) == NULL) || r; + + return r; +} + +#endif /* GL_NV_register_combiners2 */ + +#ifdef GL_NV_texgen_emboss + +#endif /* GL_NV_texgen_emboss */ + +#ifdef GL_NV_texgen_reflection + +#endif /* GL_NV_texgen_reflection */ + +#ifdef GL_NV_texture_compression_vtc + +#endif /* GL_NV_texture_compression_vtc */ + +#ifdef GL_NV_texture_env_combine4 + +#endif /* GL_NV_texture_env_combine4 */ + +#ifdef GL_NV_texture_expand_normal + +#endif /* GL_NV_texture_expand_normal */ + +#ifdef GL_NV_texture_rectangle + +#endif /* GL_NV_texture_rectangle */ + +#ifdef GL_NV_texture_shader + +#endif /* GL_NV_texture_shader */ + +#ifdef GL_NV_texture_shader2 + +#endif /* GL_NV_texture_shader2 */ + +#ifdef GL_NV_texture_shader3 + +#endif /* GL_NV_texture_shader3 */ + +#ifdef GL_NV_vertex_array_range + +static GLboolean _glewInit_GL_NV_vertex_array_range (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glFlushVertexArrayRangeNV = (PFNGLFLUSHVERTEXARRAYRANGENVPROC)glewGetProcAddress((const GLubyte*)"glFlushVertexArrayRangeNV")) == NULL) || r; + r = ((glVertexArrayRangeNV = (PFNGLVERTEXARRAYRANGENVPROC)glewGetProcAddress((const GLubyte*)"glVertexArrayRangeNV")) == NULL) || r; + + return r; +} + +#endif /* GL_NV_vertex_array_range */ + +#ifdef GL_NV_vertex_array_range2 + +#endif /* GL_NV_vertex_array_range2 */ + +#ifdef GL_NV_vertex_program + +static GLboolean _glewInit_GL_NV_vertex_program (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glAreProgramsResidentNV = (PFNGLAREPROGRAMSRESIDENTNVPROC)glewGetProcAddress((const GLubyte*)"glAreProgramsResidentNV")) == NULL) || r; + r = ((glBindProgramNV = (PFNGLBINDPROGRAMNVPROC)glewGetProcAddress((const GLubyte*)"glBindProgramNV")) == NULL) || r; + r = ((glDeleteProgramsNV = (PFNGLDELETEPROGRAMSNVPROC)glewGetProcAddress((const GLubyte*)"glDeleteProgramsNV")) == NULL) || r; + r = ((glExecuteProgramNV = (PFNGLEXECUTEPROGRAMNVPROC)glewGetProcAddress((const GLubyte*)"glExecuteProgramNV")) == NULL) || r; + r = ((glGenProgramsNV = (PFNGLGENPROGRAMSNVPROC)glewGetProcAddress((const GLubyte*)"glGenProgramsNV")) == NULL) || r; + r = ((glGetProgramParameterdvNV = (PFNGLGETPROGRAMPARAMETERDVNVPROC)glewGetProcAddress((const GLubyte*)"glGetProgramParameterdvNV")) == NULL) || r; + r = ((glGetProgramParameterfvNV = (PFNGLGETPROGRAMPARAMETERFVNVPROC)glewGetProcAddress((const GLubyte*)"glGetProgramParameterfvNV")) == NULL) || r; + r = ((glGetProgramStringNV = (PFNGLGETPROGRAMSTRINGNVPROC)glewGetProcAddress((const GLubyte*)"glGetProgramStringNV")) == NULL) || r; + r = ((glGetProgramivNV = (PFNGLGETPROGRAMIVNVPROC)glewGetProcAddress((const GLubyte*)"glGetProgramivNV")) == NULL) || r; + r = ((glGetTrackMatrixivNV = (PFNGLGETTRACKMATRIXIVNVPROC)glewGetProcAddress((const GLubyte*)"glGetTrackMatrixivNV")) == NULL) || r; + r = ((glGetVertexAttribPointervNV = (PFNGLGETVERTEXATTRIBPOINTERVNVPROC)glewGetProcAddress((const GLubyte*)"glGetVertexAttribPointervNV")) == NULL) || r; + r = ((glGetVertexAttribdvNV = (PFNGLGETVERTEXATTRIBDVNVPROC)glewGetProcAddress((const GLubyte*)"glGetVertexAttribdvNV")) == NULL) || r; + r = ((glGetVertexAttribfvNV = (PFNGLGETVERTEXATTRIBFVNVPROC)glewGetProcAddress((const GLubyte*)"glGetVertexAttribfvNV")) == NULL) || r; + r = ((glGetVertexAttribivNV = (PFNGLGETVERTEXATTRIBIVNVPROC)glewGetProcAddress((const GLubyte*)"glGetVertexAttribivNV")) == NULL) || r; + r = ((glIsProgramNV = (PFNGLISPROGRAMNVPROC)glewGetProcAddress((const GLubyte*)"glIsProgramNV")) == NULL) || r; + r = ((glLoadProgramNV = (PFNGLLOADPROGRAMNVPROC)glewGetProcAddress((const GLubyte*)"glLoadProgramNV")) == NULL) || r; + r = ((glProgramParameter4dNV = (PFNGLPROGRAMPARAMETER4DNVPROC)glewGetProcAddress((const GLubyte*)"glProgramParameter4dNV")) == NULL) || r; + r = ((glProgramParameter4dvNV = (PFNGLPROGRAMPARAMETER4DVNVPROC)glewGetProcAddress((const GLubyte*)"glProgramParameter4dvNV")) == NULL) || r; + r = ((glProgramParameter4fNV = (PFNGLPROGRAMPARAMETER4FNVPROC)glewGetProcAddress((const GLubyte*)"glProgramParameter4fNV")) == NULL) || r; + r = ((glProgramParameter4fvNV = (PFNGLPROGRAMPARAMETER4FVNVPROC)glewGetProcAddress((const GLubyte*)"glProgramParameter4fvNV")) == NULL) || r; + r = ((glProgramParameters4dvNV = (PFNGLPROGRAMPARAMETERS4DVNVPROC)glewGetProcAddress((const GLubyte*)"glProgramParameters4dvNV")) == NULL) || r; + r = ((glProgramParameters4fvNV = (PFNGLPROGRAMPARAMETERS4FVNVPROC)glewGetProcAddress((const GLubyte*)"glProgramParameters4fvNV")) == NULL) || r; + r = ((glRequestResidentProgramsNV = (PFNGLREQUESTRESIDENTPROGRAMSNVPROC)glewGetProcAddress((const GLubyte*)"glRequestResidentProgramsNV")) == NULL) || r; + r = ((glTrackMatrixNV = (PFNGLTRACKMATRIXNVPROC)glewGetProcAddress((const GLubyte*)"glTrackMatrixNV")) == NULL) || r; + r = ((glVertexAttrib1dNV = (PFNGLVERTEXATTRIB1DNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib1dNV")) == NULL) || r; + r = ((glVertexAttrib1dvNV = (PFNGLVERTEXATTRIB1DVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib1dvNV")) == NULL) || r; + r = ((glVertexAttrib1fNV = (PFNGLVERTEXATTRIB1FNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib1fNV")) == NULL) || r; + r = ((glVertexAttrib1fvNV = (PFNGLVERTEXATTRIB1FVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib1fvNV")) == NULL) || r; + r = ((glVertexAttrib1sNV = (PFNGLVERTEXATTRIB1SNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib1sNV")) == NULL) || r; + r = ((glVertexAttrib1svNV = (PFNGLVERTEXATTRIB1SVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib1svNV")) == NULL) || r; + r = ((glVertexAttrib2dNV = (PFNGLVERTEXATTRIB2DNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib2dNV")) == NULL) || r; + r = ((glVertexAttrib2dvNV = (PFNGLVERTEXATTRIB2DVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib2dvNV")) == NULL) || r; + r = ((glVertexAttrib2fNV = (PFNGLVERTEXATTRIB2FNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib2fNV")) == NULL) || r; + r = ((glVertexAttrib2fvNV = (PFNGLVERTEXATTRIB2FVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib2fvNV")) == NULL) || r; + r = ((glVertexAttrib2sNV = (PFNGLVERTEXATTRIB2SNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib2sNV")) == NULL) || r; + r = ((glVertexAttrib2svNV = (PFNGLVERTEXATTRIB2SVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib2svNV")) == NULL) || r; + r = ((glVertexAttrib3dNV = (PFNGLVERTEXATTRIB3DNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib3dNV")) == NULL) || r; + r = ((glVertexAttrib3dvNV = (PFNGLVERTEXATTRIB3DVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib3dvNV")) == NULL) || r; + r = ((glVertexAttrib3fNV = (PFNGLVERTEXATTRIB3FNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib3fNV")) == NULL) || r; + r = ((glVertexAttrib3fvNV = (PFNGLVERTEXATTRIB3FVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib3fvNV")) == NULL) || r; + r = ((glVertexAttrib3sNV = (PFNGLVERTEXATTRIB3SNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib3sNV")) == NULL) || r; + r = ((glVertexAttrib3svNV = (PFNGLVERTEXATTRIB3SVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib3svNV")) == NULL) || r; + r = ((glVertexAttrib4dNV = (PFNGLVERTEXATTRIB4DNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4dNV")) == NULL) || r; + r = ((glVertexAttrib4dvNV = (PFNGLVERTEXATTRIB4DVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4dvNV")) == NULL) || r; + r = ((glVertexAttrib4fNV = (PFNGLVERTEXATTRIB4FNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4fNV")) == NULL) || r; + r = ((glVertexAttrib4fvNV = (PFNGLVERTEXATTRIB4FVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4fvNV")) == NULL) || r; + r = ((glVertexAttrib4sNV = (PFNGLVERTEXATTRIB4SNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4sNV")) == NULL) || r; + r = ((glVertexAttrib4svNV = (PFNGLVERTEXATTRIB4SVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4svNV")) == NULL) || r; + r = ((glVertexAttrib4ubNV = (PFNGLVERTEXATTRIB4UBNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4ubNV")) == NULL) || r; + r = ((glVertexAttrib4ubvNV = (PFNGLVERTEXATTRIB4UBVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4ubvNV")) == NULL) || r; + r = ((glVertexAttribPointerNV = (PFNGLVERTEXATTRIBPOINTERNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribPointerNV")) == NULL) || r; + r = ((glVertexAttribs1dvNV = (PFNGLVERTEXATTRIBS1DVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribs1dvNV")) == NULL) || r; + r = ((glVertexAttribs1fvNV = (PFNGLVERTEXATTRIBS1FVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribs1fvNV")) == NULL) || r; + r = ((glVertexAttribs1svNV = (PFNGLVERTEXATTRIBS1SVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribs1svNV")) == NULL) || r; + r = ((glVertexAttribs2dvNV = (PFNGLVERTEXATTRIBS2DVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribs2dvNV")) == NULL) || r; + r = ((glVertexAttribs2fvNV = (PFNGLVERTEXATTRIBS2FVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribs2fvNV")) == NULL) || r; + r = ((glVertexAttribs2svNV = (PFNGLVERTEXATTRIBS2SVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribs2svNV")) == NULL) || r; + r = ((glVertexAttribs3dvNV = (PFNGLVERTEXATTRIBS3DVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribs3dvNV")) == NULL) || r; + r = ((glVertexAttribs3fvNV = (PFNGLVERTEXATTRIBS3FVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribs3fvNV")) == NULL) || r; + r = ((glVertexAttribs3svNV = (PFNGLVERTEXATTRIBS3SVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribs3svNV")) == NULL) || r; + r = ((glVertexAttribs4dvNV = (PFNGLVERTEXATTRIBS4DVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribs4dvNV")) == NULL) || r; + r = ((glVertexAttribs4fvNV = (PFNGLVERTEXATTRIBS4FVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribs4fvNV")) == NULL) || r; + r = ((glVertexAttribs4svNV = (PFNGLVERTEXATTRIBS4SVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribs4svNV")) == NULL) || r; + r = ((glVertexAttribs4ubvNV = (PFNGLVERTEXATTRIBS4UBVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribs4ubvNV")) == NULL) || r; + + return r; +} + +#endif /* GL_NV_vertex_program */ + +#ifdef GL_NV_vertex_program1_1 + +#endif /* GL_NV_vertex_program1_1 */ + +#ifdef GL_NV_vertex_program2 + +#endif /* GL_NV_vertex_program2 */ + +#ifdef GL_NV_vertex_program2_option + +#endif /* GL_NV_vertex_program2_option */ + +#ifdef GL_NV_vertex_program3 + +#endif /* GL_NV_vertex_program3 */ + +#ifdef GL_OML_interlace + +#endif /* GL_OML_interlace */ + +#ifdef GL_OML_resample + +#endif /* GL_OML_resample */ + +#ifdef GL_OML_subsample + +#endif /* GL_OML_subsample */ + +#ifdef GL_PGI_misc_hints + +#endif /* GL_PGI_misc_hints */ + +#ifdef GL_PGI_vertex_hints + +#endif /* GL_PGI_vertex_hints */ + +#ifdef GL_REND_screen_coordinates + +#endif /* GL_REND_screen_coordinates */ + +#ifdef GL_S3_s3tc + +#endif /* GL_S3_s3tc */ + +#ifdef GL_SGIS_color_range + +#endif /* GL_SGIS_color_range */ + +#ifdef GL_SGIS_detail_texture + +static GLboolean _glewInit_GL_SGIS_detail_texture (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glDetailTexFuncSGIS = (PFNGLDETAILTEXFUNCSGISPROC)glewGetProcAddress((const GLubyte*)"glDetailTexFuncSGIS")) == NULL) || r; + r = ((glGetDetailTexFuncSGIS = (PFNGLGETDETAILTEXFUNCSGISPROC)glewGetProcAddress((const GLubyte*)"glGetDetailTexFuncSGIS")) == NULL) || r; + + return r; +} + +#endif /* GL_SGIS_detail_texture */ + +#ifdef GL_SGIS_fog_function + +static GLboolean _glewInit_GL_SGIS_fog_function (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glFogFuncSGIS = (PFNGLFOGFUNCSGISPROC)glewGetProcAddress((const GLubyte*)"glFogFuncSGIS")) == NULL) || r; + r = ((glGetFogFuncSGIS = (PFNGLGETFOGFUNCSGISPROC)glewGetProcAddress((const GLubyte*)"glGetFogFuncSGIS")) == NULL) || r; + + return r; +} + +#endif /* GL_SGIS_fog_function */ + +#ifdef GL_SGIS_generate_mipmap + +#endif /* GL_SGIS_generate_mipmap */ + +#ifdef GL_SGIS_multisample + +static GLboolean _glewInit_GL_SGIS_multisample (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glSampleMaskSGIS = (PFNGLSAMPLEMASKSGISPROC)glewGetProcAddress((const GLubyte*)"glSampleMaskSGIS")) == NULL) || r; + r = ((glSamplePatternSGIS = (PFNGLSAMPLEPATTERNSGISPROC)glewGetProcAddress((const GLubyte*)"glSamplePatternSGIS")) == NULL) || r; + + return r; +} + +#endif /* GL_SGIS_multisample */ + +#ifdef GL_SGIS_pixel_texture + +#endif /* GL_SGIS_pixel_texture */ + +#ifdef GL_SGIS_sharpen_texture + +static GLboolean _glewInit_GL_SGIS_sharpen_texture (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glGetSharpenTexFuncSGIS = (PFNGLGETSHARPENTEXFUNCSGISPROC)glewGetProcAddress((const GLubyte*)"glGetSharpenTexFuncSGIS")) == NULL) || r; + r = ((glSharpenTexFuncSGIS = (PFNGLSHARPENTEXFUNCSGISPROC)glewGetProcAddress((const GLubyte*)"glSharpenTexFuncSGIS")) == NULL) || r; + + return r; +} + +#endif /* GL_SGIS_sharpen_texture */ + +#ifdef GL_SGIS_texture4D + +static GLboolean _glewInit_GL_SGIS_texture4D (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glTexImage4DSGIS = (PFNGLTEXIMAGE4DSGISPROC)glewGetProcAddress((const GLubyte*)"glTexImage4DSGIS")) == NULL) || r; + r = ((glTexSubImage4DSGIS = (PFNGLTEXSUBIMAGE4DSGISPROC)glewGetProcAddress((const GLubyte*)"glTexSubImage4DSGIS")) == NULL) || r; + + return r; +} + +#endif /* GL_SGIS_texture4D */ + +#ifdef GL_SGIS_texture_border_clamp + +#endif /* GL_SGIS_texture_border_clamp */ + +#ifdef GL_SGIS_texture_edge_clamp + +#endif /* GL_SGIS_texture_edge_clamp */ + +#ifdef GL_SGIS_texture_filter4 + +static GLboolean _glewInit_GL_SGIS_texture_filter4 (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glGetTexFilterFuncSGIS = (PFNGLGETTEXFILTERFUNCSGISPROC)glewGetProcAddress((const GLubyte*)"glGetTexFilterFuncSGIS")) == NULL) || r; + r = ((glTexFilterFuncSGIS = (PFNGLTEXFILTERFUNCSGISPROC)glewGetProcAddress((const GLubyte*)"glTexFilterFuncSGIS")) == NULL) || r; + + return r; +} + +#endif /* GL_SGIS_texture_filter4 */ + +#ifdef GL_SGIS_texture_lod + +#endif /* GL_SGIS_texture_lod */ + +#ifdef GL_SGIS_texture_select + +#endif /* GL_SGIS_texture_select */ + +#ifdef GL_SGIX_async + +static GLboolean _glewInit_GL_SGIX_async (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glAsyncMarkerSGIX = (PFNGLASYNCMARKERSGIXPROC)glewGetProcAddress((const GLubyte*)"glAsyncMarkerSGIX")) == NULL) || r; + r = ((glDeleteAsyncMarkersSGIX = (PFNGLDELETEASYNCMARKERSSGIXPROC)glewGetProcAddress((const GLubyte*)"glDeleteAsyncMarkersSGIX")) == NULL) || r; + r = ((glFinishAsyncSGIX = (PFNGLFINISHASYNCSGIXPROC)glewGetProcAddress((const GLubyte*)"glFinishAsyncSGIX")) == NULL) || r; + r = ((glGenAsyncMarkersSGIX = (PFNGLGENASYNCMARKERSSGIXPROC)glewGetProcAddress((const GLubyte*)"glGenAsyncMarkersSGIX")) == NULL) || r; + r = ((glIsAsyncMarkerSGIX = (PFNGLISASYNCMARKERSGIXPROC)glewGetProcAddress((const GLubyte*)"glIsAsyncMarkerSGIX")) == NULL) || r; + r = ((glPollAsyncSGIX = (PFNGLPOLLASYNCSGIXPROC)glewGetProcAddress((const GLubyte*)"glPollAsyncSGIX")) == NULL) || r; + + return r; +} + +#endif /* GL_SGIX_async */ + +#ifdef GL_SGIX_async_histogram + +#endif /* GL_SGIX_async_histogram */ + +#ifdef GL_SGIX_async_pixel + +#endif /* GL_SGIX_async_pixel */ + +#ifdef GL_SGIX_blend_alpha_minmax + +#endif /* GL_SGIX_blend_alpha_minmax */ + +#ifdef GL_SGIX_clipmap + +#endif /* GL_SGIX_clipmap */ + +#ifdef GL_SGIX_depth_texture + +#endif /* GL_SGIX_depth_texture */ + +#ifdef GL_SGIX_flush_raster + +static GLboolean _glewInit_GL_SGIX_flush_raster (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glFlushRasterSGIX = (PFNGLFLUSHRASTERSGIXPROC)glewGetProcAddress((const GLubyte*)"glFlushRasterSGIX")) == NULL) || r; + + return r; +} + +#endif /* GL_SGIX_flush_raster */ + +#ifdef GL_SGIX_fog_offset + +#endif /* GL_SGIX_fog_offset */ + +#ifdef GL_SGIX_fog_texture + +static GLboolean _glewInit_GL_SGIX_fog_texture (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glTextureFogSGIX = (PFNGLTEXTUREFOGSGIXPROC)glewGetProcAddress((const GLubyte*)"glTextureFogSGIX")) == NULL) || r; + + return r; +} + +#endif /* GL_SGIX_fog_texture */ + +#ifdef GL_SGIX_fragment_specular_lighting + +static GLboolean _glewInit_GL_SGIX_fragment_specular_lighting (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + +#if 0 + r = ((glFragmentColorMaterialSGIX = (PFNGLFRAGMENTCOLORMATERIALSGIXPROC)glewGetProcAddress((const GLubyte*)"glFragmentColorMaterialSGIX")) == NULL) || r; + r = ((glFragmentLightModelfSGIX = (PFNGLFRAGMENTLIGHTMODELFSGIXPROC)glewGetProcAddress((const GLubyte*)"glFragmentLightModelfSGIX")) == NULL) || r; + r = ((glFragmentLightModelfvSGIX = (PFNGLFRAGMENTLIGHTMODELFVSGIXPROC)glewGetProcAddress((const GLubyte*)"glFragmentLightModelfvSGIX")) == NULL) || r; + r = ((glFragmentLightModeliSGIX = (PFNGLFRAGMENTLIGHTMODELISGIXPROC)glewGetProcAddress((const GLubyte*)"glFragmentLightModeliSGIX")) == NULL) || r; + r = ((glFragmentLightModelivSGIX = (PFNGLFRAGMENTLIGHTMODELIVSGIXPROC)glewGetProcAddress((const GLubyte*)"glFragmentLightModelivSGIX")) == NULL) || r; + r = ((glFragmentLightfSGIX = (PFNGLFRAGMENTLIGHTFSGIXPROC)glewGetProcAddress((const GLubyte*)"glFragmentLightfSGIX")) == NULL) || r; + r = ((glFragmentLightfvSGIX = (PFNGLFRAGMENTLIGHTFVSGIXPROC)glewGetProcAddress((const GLubyte*)"glFragmentLightfvSGIX")) == NULL) || r; + r = ((glFragmentLightiSGIX = (PFNGLFRAGMENTLIGHTISGIXPROC)glewGetProcAddress((const GLubyte*)"glFragmentLightiSGIX")) == NULL) || r; + r = ((glFragmentLightivSGIX = (PFNGLFRAGMENTLIGHTIVSGIXPROC)glewGetProcAddress((const GLubyte*)"glFragmentLightivSGIX")) == NULL) || r; + r = ((glFragmentMaterialfSGIX = (PFNGLFRAGMENTMATERIALFSGIXPROC)glewGetProcAddress((const GLubyte*)"glFragmentMaterialfSGIX")) == NULL) || r; + r = ((glFragmentMaterialfvSGIX = (PFNGLFRAGMENTMATERIALFVSGIXPROC)glewGetProcAddress((const GLubyte*)"glFragmentMaterialfvSGIX")) == NULL) || r; + r = ((glFragmentMaterialiSGIX = (PFNGLFRAGMENTMATERIALISGIXPROC)glewGetProcAddress((const GLubyte*)"glFragmentMaterialiSGIX")) == NULL) || r; + r = ((glFragmentMaterialivSGIX = (PFNGLFRAGMENTMATERIALIVSGIXPROC)glewGetProcAddress((const GLubyte*)"glFragmentMaterialivSGIX")) == NULL) || r; + r = ((glGetFragmentLightfvSGIX = (PFNGLGETFRAGMENTLIGHTFVSGIXPROC)glewGetProcAddress((const GLubyte*)"glGetFragmentLightfvSGIX")) == NULL) || r; + r = ((glGetFragmentLightivSGIX = (PFNGLGETFRAGMENTLIGHTIVSGIXPROC)glewGetProcAddress((const GLubyte*)"glGetFragmentLightivSGIX")) == NULL) || r; + r = ((glGetFragmentMaterialfvSGIX = (PFNGLGETFRAGMENTMATERIALFVSGIXPROC)glewGetProcAddress((const GLubyte*)"glGetFragmentMaterialfvSGIX")) == NULL) || r; + r = ((glGetFragmentMaterialivSGIX = (PFNGLGETFRAGMENTMATERIALIVSGIXPROC)glewGetProcAddress((const GLubyte*)"glGetFragmentMaterialivSGIX")) == NULL) || r; +#endif + + return r; +} + +#endif /* GL_SGIX_fragment_specular_lighting */ + +#ifdef GL_SGIX_framezoom + +static GLboolean _glewInit_GL_SGIX_framezoom (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glFrameZoomSGIX = (PFNGLFRAMEZOOMSGIXPROC)glewGetProcAddress((const GLubyte*)"glFrameZoomSGIX")) == NULL) || r; + + return r; +} + +#endif /* GL_SGIX_framezoom */ + +#ifdef GL_SGIX_interlace + +#endif /* GL_SGIX_interlace */ + +#ifdef GL_SGIX_ir_instrument1 + +#endif /* GL_SGIX_ir_instrument1 */ + +#ifdef GL_SGIX_list_priority + +#endif /* GL_SGIX_list_priority */ + +#ifdef GL_SGIX_pixel_texture + +static GLboolean _glewInit_GL_SGIX_pixel_texture (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glPixelTexGenSGIX = (PFNGLPIXELTEXGENSGIXPROC)glewGetProcAddress((const GLubyte*)"glPixelTexGenSGIX")) == NULL) || r; + + return r; +} + +#endif /* GL_SGIX_pixel_texture */ + +#ifdef GL_SGIX_pixel_texture_bits + +#endif /* GL_SGIX_pixel_texture_bits */ + +#ifdef GL_SGIX_reference_plane + +static GLboolean _glewInit_GL_SGIX_reference_plane (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glReferencePlaneSGIX = (PFNGLREFERENCEPLANESGIXPROC)glewGetProcAddress((const GLubyte*)"glReferencePlaneSGIX")) == NULL) || r; + + return r; +} + +#endif /* GL_SGIX_reference_plane */ + +#ifdef GL_SGIX_resample + +#endif /* GL_SGIX_resample */ + +#ifdef GL_SGIX_shadow + +#endif /* GL_SGIX_shadow */ + +#ifdef GL_SGIX_shadow_ambient + +#endif /* GL_SGIX_shadow_ambient */ + +#ifdef GL_SGIX_sprite + +static GLboolean _glewInit_GL_SGIX_sprite (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glSpriteParameterfSGIX = (PFNGLSPRITEPARAMETERFSGIXPROC)glewGetProcAddress((const GLubyte*)"glSpriteParameterfSGIX")) == NULL) || r; + r = ((glSpriteParameterfvSGIX = (PFNGLSPRITEPARAMETERFVSGIXPROC)glewGetProcAddress((const GLubyte*)"glSpriteParameterfvSGIX")) == NULL) || r; + r = ((glSpriteParameteriSGIX = (PFNGLSPRITEPARAMETERISGIXPROC)glewGetProcAddress((const GLubyte*)"glSpriteParameteriSGIX")) == NULL) || r; + r = ((glSpriteParameterivSGIX = (PFNGLSPRITEPARAMETERIVSGIXPROC)glewGetProcAddress((const GLubyte*)"glSpriteParameterivSGIX")) == NULL) || r; + + return r; +} + +#endif /* GL_SGIX_sprite */ + +#ifdef GL_SGIX_tag_sample_buffer + +static GLboolean _glewInit_GL_SGIX_tag_sample_buffer (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glTagSampleBufferSGIX = (PFNGLTAGSAMPLEBUFFERSGIXPROC)glewGetProcAddress((const GLubyte*)"glTagSampleBufferSGIX")) == NULL) || r; + + return r; +} + +#endif /* GL_SGIX_tag_sample_buffer */ + +#ifdef GL_SGIX_texture_add_env + +#endif /* GL_SGIX_texture_add_env */ + +#ifdef GL_SGIX_texture_coordinate_clamp + +#endif /* GL_SGIX_texture_coordinate_clamp */ + +#ifdef GL_SGIX_texture_lod_bias + +#endif /* GL_SGIX_texture_lod_bias */ + +#ifdef GL_SGIX_texture_multi_buffer + +#endif /* GL_SGIX_texture_multi_buffer */ + +#ifdef GL_SGIX_texture_range + +#endif /* GL_SGIX_texture_range */ + +#ifdef GL_SGIX_texture_scale_bias + +#endif /* GL_SGIX_texture_scale_bias */ + +#ifdef GL_SGIX_vertex_preclip + +#endif /* GL_SGIX_vertex_preclip */ + +#ifdef GL_SGIX_vertex_preclip_hint + +#endif /* GL_SGIX_vertex_preclip_hint */ + +#ifdef GL_SGIX_ycrcb + +#endif /* GL_SGIX_ycrcb */ + +#ifdef GL_SGI_color_matrix + +#endif /* GL_SGI_color_matrix */ + +#ifdef GL_SGI_color_table + +static GLboolean _glewInit_GL_SGI_color_table (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glColorTableParameterfvSGI = (PFNGLCOLORTABLEPARAMETERFVSGIPROC)glewGetProcAddress((const GLubyte*)"glColorTableParameterfvSGI")) == NULL) || r; + r = ((glColorTableParameterivSGI = (PFNGLCOLORTABLEPARAMETERIVSGIPROC)glewGetProcAddress((const GLubyte*)"glColorTableParameterivSGI")) == NULL) || r; + r = ((glColorTableSGI = (PFNGLCOLORTABLESGIPROC)glewGetProcAddress((const GLubyte*)"glColorTableSGI")) == NULL) || r; + r = ((glCopyColorTableSGI = (PFNGLCOPYCOLORTABLESGIPROC)glewGetProcAddress((const GLubyte*)"glCopyColorTableSGI")) == NULL) || r; + r = ((glGetColorTableParameterfvSGI = (PFNGLGETCOLORTABLEPARAMETERFVSGIPROC)glewGetProcAddress((const GLubyte*)"glGetColorTableParameterfvSGI")) == NULL) || r; + r = ((glGetColorTableParameterivSGI = (PFNGLGETCOLORTABLEPARAMETERIVSGIPROC)glewGetProcAddress((const GLubyte*)"glGetColorTableParameterivSGI")) == NULL) || r; + r = ((glGetColorTableSGI = (PFNGLGETCOLORTABLESGIPROC)glewGetProcAddress((const GLubyte*)"glGetColorTableSGI")) == NULL) || r; + + return r; +} + +#endif /* GL_SGI_color_table */ + +#ifdef GL_SGI_texture_color_table + +#endif /* GL_SGI_texture_color_table */ + +#ifdef GL_SUNX_constant_data + +static GLboolean _glewInit_GL_SUNX_constant_data (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glFinishTextureSUNX = (PFNGLFINISHTEXTURESUNXPROC)glewGetProcAddress((const GLubyte*)"glFinishTextureSUNX")) == NULL) || r; + + return r; +} + +#endif /* GL_SUNX_constant_data */ + +#ifdef GL_SUN_convolution_border_modes + +#endif /* GL_SUN_convolution_border_modes */ + +#ifdef GL_SUN_global_alpha + +static GLboolean _glewInit_GL_SUN_global_alpha (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glGlobalAlphaFactorbSUN = (PFNGLGLOBALALPHAFACTORBSUNPROC)glewGetProcAddress((const GLubyte*)"glGlobalAlphaFactorbSUN")) == NULL) || r; + r = ((glGlobalAlphaFactordSUN = (PFNGLGLOBALALPHAFACTORDSUNPROC)glewGetProcAddress((const GLubyte*)"glGlobalAlphaFactordSUN")) == NULL) || r; + r = ((glGlobalAlphaFactorfSUN = (PFNGLGLOBALALPHAFACTORFSUNPROC)glewGetProcAddress((const GLubyte*)"glGlobalAlphaFactorfSUN")) == NULL) || r; + r = ((glGlobalAlphaFactoriSUN = (PFNGLGLOBALALPHAFACTORISUNPROC)glewGetProcAddress((const GLubyte*)"glGlobalAlphaFactoriSUN")) == NULL) || r; + r = ((glGlobalAlphaFactorsSUN = (PFNGLGLOBALALPHAFACTORSSUNPROC)glewGetProcAddress((const GLubyte*)"glGlobalAlphaFactorsSUN")) == NULL) || r; + r = ((glGlobalAlphaFactorubSUN = (PFNGLGLOBALALPHAFACTORUBSUNPROC)glewGetProcAddress((const GLubyte*)"glGlobalAlphaFactorubSUN")) == NULL) || r; + r = ((glGlobalAlphaFactoruiSUN = (PFNGLGLOBALALPHAFACTORUISUNPROC)glewGetProcAddress((const GLubyte*)"glGlobalAlphaFactoruiSUN")) == NULL) || r; + r = ((glGlobalAlphaFactorusSUN = (PFNGLGLOBALALPHAFACTORUSSUNPROC)glewGetProcAddress((const GLubyte*)"glGlobalAlphaFactorusSUN")) == NULL) || r; + + return r; +} + +#endif /* GL_SUN_global_alpha */ + +#ifdef GL_SUN_mesh_array + +#endif /* GL_SUN_mesh_array */ + +#ifdef GL_SUN_read_video_pixels + +static GLboolean _glewInit_GL_SUN_read_video_pixels (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glReadVideoPixelsSUN = (PFNGLREADVIDEOPIXELSSUNPROC)glewGetProcAddress((const GLubyte*)"glReadVideoPixelsSUN")) == NULL) || r; + + return r; +} + +#endif /* GL_SUN_read_video_pixels */ + +#ifdef GL_SUN_slice_accum + +#endif /* GL_SUN_slice_accum */ + +#ifdef GL_SUN_triangle_list + +static GLboolean _glewInit_GL_SUN_triangle_list (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glReplacementCodePointerSUN = (PFNGLREPLACEMENTCODEPOINTERSUNPROC)glewGetProcAddress((const GLubyte*)"glReplacementCodePointerSUN")) == NULL) || r; + r = ((glReplacementCodeubSUN = (PFNGLREPLACEMENTCODEUBSUNPROC)glewGetProcAddress((const GLubyte*)"glReplacementCodeubSUN")) == NULL) || r; + r = ((glReplacementCodeubvSUN = (PFNGLREPLACEMENTCODEUBVSUNPROC)glewGetProcAddress((const GLubyte*)"glReplacementCodeubvSUN")) == NULL) || r; + r = ((glReplacementCodeuiSUN = (PFNGLREPLACEMENTCODEUISUNPROC)glewGetProcAddress((const GLubyte*)"glReplacementCodeuiSUN")) == NULL) || r; + r = ((glReplacementCodeuivSUN = (PFNGLREPLACEMENTCODEUIVSUNPROC)glewGetProcAddress((const GLubyte*)"glReplacementCodeuivSUN")) == NULL) || r; + r = ((glReplacementCodeusSUN = (PFNGLREPLACEMENTCODEUSSUNPROC)glewGetProcAddress((const GLubyte*)"glReplacementCodeusSUN")) == NULL) || r; + r = ((glReplacementCodeusvSUN = (PFNGLREPLACEMENTCODEUSVSUNPROC)glewGetProcAddress((const GLubyte*)"glReplacementCodeusvSUN")) == NULL) || r; + + return r; +} + +#endif /* GL_SUN_triangle_list */ + +#ifdef GL_SUN_vertex + +static GLboolean _glewInit_GL_SUN_vertex (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glColor3fVertex3fSUN = (PFNGLCOLOR3FVERTEX3FSUNPROC)glewGetProcAddress((const GLubyte*)"glColor3fVertex3fSUN")) == NULL) || r; + r = ((glColor3fVertex3fvSUN = (PFNGLCOLOR3FVERTEX3FVSUNPROC)glewGetProcAddress((const GLubyte*)"glColor3fVertex3fvSUN")) == NULL) || r; + r = ((glColor4fNormal3fVertex3fSUN = (PFNGLCOLOR4FNORMAL3FVERTEX3FSUNPROC)glewGetProcAddress((const GLubyte*)"glColor4fNormal3fVertex3fSUN")) == NULL) || r; + r = ((glColor4fNormal3fVertex3fvSUN = (PFNGLCOLOR4FNORMAL3FVERTEX3FVSUNPROC)glewGetProcAddress((const GLubyte*)"glColor4fNormal3fVertex3fvSUN")) == NULL) || r; + r = ((glColor4ubVertex2fSUN = (PFNGLCOLOR4UBVERTEX2FSUNPROC)glewGetProcAddress((const GLubyte*)"glColor4ubVertex2fSUN")) == NULL) || r; + r = ((glColor4ubVertex2fvSUN = (PFNGLCOLOR4UBVERTEX2FVSUNPROC)glewGetProcAddress((const GLubyte*)"glColor4ubVertex2fvSUN")) == NULL) || r; + r = ((glColor4ubVertex3fSUN = (PFNGLCOLOR4UBVERTEX3FSUNPROC)glewGetProcAddress((const GLubyte*)"glColor4ubVertex3fSUN")) == NULL) || r; + r = ((glColor4ubVertex3fvSUN = (PFNGLCOLOR4UBVERTEX3FVSUNPROC)glewGetProcAddress((const GLubyte*)"glColor4ubVertex3fvSUN")) == NULL) || r; + r = ((glNormal3fVertex3fSUN = (PFNGLNORMAL3FVERTEX3FSUNPROC)glewGetProcAddress((const GLubyte*)"glNormal3fVertex3fSUN")) == NULL) || r; + r = ((glNormal3fVertex3fvSUN = (PFNGLNORMAL3FVERTEX3FVSUNPROC)glewGetProcAddress((const GLubyte*)"glNormal3fVertex3fvSUN")) == NULL) || r; + r = ((glReplacementCodeuiColor3fVertex3fSUN = (PFNGLREPLACEMENTCODEUICOLOR3FVERTEX3FSUNPROC)glewGetProcAddress((const GLubyte*)"glReplacementCodeuiColor3fVertex3fSUN")) == NULL) || r; + r = ((glReplacementCodeuiColor3fVertex3fvSUN = (PFNGLREPLACEMENTCODEUICOLOR3FVERTEX3FVSUNPROC)glewGetProcAddress((const GLubyte*)"glReplacementCodeuiColor3fVertex3fvSUN")) == NULL) || r; + r = ((glReplacementCodeuiColor4fNormal3fVertex3fSUN = (PFNGLREPLACEMENTCODEUICOLOR4FNORMAL3FVERTEX3FSUNPROC)glewGetProcAddress((const GLubyte*)"glReplacementCodeuiColor4fNormal3fVertex3fSUN")) == NULL) || r; + r = ((glReplacementCodeuiColor4fNormal3fVertex3fvSUN = (PFNGLREPLACEMENTCODEUICOLOR4FNORMAL3FVERTEX3FVSUNPROC)glewGetProcAddress((const GLubyte*)"glReplacementCodeuiColor4fNormal3fVertex3fvSUN")) == NULL) || r; + r = ((glReplacementCodeuiColor4ubVertex3fSUN = (PFNGLREPLACEMENTCODEUICOLOR4UBVERTEX3FSUNPROC)glewGetProcAddress((const GLubyte*)"glReplacementCodeuiColor4ubVertex3fSUN")) == NULL) || r; + r = ((glReplacementCodeuiColor4ubVertex3fvSUN = (PFNGLREPLACEMENTCODEUICOLOR4UBVERTEX3FVSUNPROC)glewGetProcAddress((const GLubyte*)"glReplacementCodeuiColor4ubVertex3fvSUN")) == NULL) || r; + r = ((glReplacementCodeuiNormal3fVertex3fSUN = (PFNGLREPLACEMENTCODEUINORMAL3FVERTEX3FSUNPROC)glewGetProcAddress((const GLubyte*)"glReplacementCodeuiNormal3fVertex3fSUN")) == NULL) || r; + r = ((glReplacementCodeuiNormal3fVertex3fvSUN = (PFNGLREPLACEMENTCODEUINORMAL3FVERTEX3FVSUNPROC)glewGetProcAddress((const GLubyte*)"glReplacementCodeuiNormal3fVertex3fvSUN")) == NULL) || r; + r = ((glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN = (PFNGLREPLACEMENTCODEUITEXCOORD2FCOLOR4FNORMAL3FVERTEX3FSUNPROC)glewGetProcAddress((const GLubyte*)"glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN")) == NULL) || r; + r = ((glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN = (PFNGLREPLACEMENTCODEUITEXCOORD2FCOLOR4FNORMAL3FVERTEX3FVSUNPROC)glewGetProcAddress((const GLubyte*)"glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN")) == NULL) || r; + r = ((glReplacementCodeuiTexCoord2fNormal3fVertex3fSUN = (PFNGLREPLACEMENTCODEUITEXCOORD2FNORMAL3FVERTEX3FSUNPROC)glewGetProcAddress((const GLubyte*)"glReplacementCodeuiTexCoord2fNormal3fVertex3fSUN")) == NULL) || r; + r = ((glReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN = (PFNGLREPLACEMENTCODEUITEXCOORD2FNORMAL3FVERTEX3FVSUNPROC)glewGetProcAddress((const GLubyte*)"glReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN")) == NULL) || r; + r = ((glReplacementCodeuiTexCoord2fVertex3fSUN = (PFNGLREPLACEMENTCODEUITEXCOORD2FVERTEX3FSUNPROC)glewGetProcAddress((const GLubyte*)"glReplacementCodeuiTexCoord2fVertex3fSUN")) == NULL) || r; + r = ((glReplacementCodeuiTexCoord2fVertex3fvSUN = (PFNGLREPLACEMENTCODEUITEXCOORD2FVERTEX3FVSUNPROC)glewGetProcAddress((const GLubyte*)"glReplacementCodeuiTexCoord2fVertex3fvSUN")) == NULL) || r; + r = ((glReplacementCodeuiVertex3fSUN = (PFNGLREPLACEMENTCODEUIVERTEX3FSUNPROC)glewGetProcAddress((const GLubyte*)"glReplacementCodeuiVertex3fSUN")) == NULL) || r; + r = ((glReplacementCodeuiVertex3fvSUN = (PFNGLREPLACEMENTCODEUIVERTEX3FVSUNPROC)glewGetProcAddress((const GLubyte*)"glReplacementCodeuiVertex3fvSUN")) == NULL) || r; + r = ((glTexCoord2fColor3fVertex3fSUN = (PFNGLTEXCOORD2FCOLOR3FVERTEX3FSUNPROC)glewGetProcAddress((const GLubyte*)"glTexCoord2fColor3fVertex3fSUN")) == NULL) || r; + r = ((glTexCoord2fColor3fVertex3fvSUN = (PFNGLTEXCOORD2FCOLOR3FVERTEX3FVSUNPROC)glewGetProcAddress((const GLubyte*)"glTexCoord2fColor3fVertex3fvSUN")) == NULL) || r; + r = ((glTexCoord2fColor4fNormal3fVertex3fSUN = (PFNGLTEXCOORD2FCOLOR4FNORMAL3FVERTEX3FSUNPROC)glewGetProcAddress((const GLubyte*)"glTexCoord2fColor4fNormal3fVertex3fSUN")) == NULL) || r; + r = ((glTexCoord2fColor4fNormal3fVertex3fvSUN = (PFNGLTEXCOORD2FCOLOR4FNORMAL3FVERTEX3FVSUNPROC)glewGetProcAddress((const GLubyte*)"glTexCoord2fColor4fNormal3fVertex3fvSUN")) == NULL) || r; + r = ((glTexCoord2fColor4ubVertex3fSUN = (PFNGLTEXCOORD2FCOLOR4UBVERTEX3FSUNPROC)glewGetProcAddress((const GLubyte*)"glTexCoord2fColor4ubVertex3fSUN")) == NULL) || r; + r = ((glTexCoord2fColor4ubVertex3fvSUN = (PFNGLTEXCOORD2FCOLOR4UBVERTEX3FVSUNPROC)glewGetProcAddress((const GLubyte*)"glTexCoord2fColor4ubVertex3fvSUN")) == NULL) || r; + r = ((glTexCoord2fNormal3fVertex3fSUN = (PFNGLTEXCOORD2FNORMAL3FVERTEX3FSUNPROC)glewGetProcAddress((const GLubyte*)"glTexCoord2fNormal3fVertex3fSUN")) == NULL) || r; + r = ((glTexCoord2fNormal3fVertex3fvSUN = (PFNGLTEXCOORD2FNORMAL3FVERTEX3FVSUNPROC)glewGetProcAddress((const GLubyte*)"glTexCoord2fNormal3fVertex3fvSUN")) == NULL) || r; + r = ((glTexCoord2fVertex3fSUN = (PFNGLTEXCOORD2FVERTEX3FSUNPROC)glewGetProcAddress((const GLubyte*)"glTexCoord2fVertex3fSUN")) == NULL) || r; + r = ((glTexCoord2fVertex3fvSUN = (PFNGLTEXCOORD2FVERTEX3FVSUNPROC)glewGetProcAddress((const GLubyte*)"glTexCoord2fVertex3fvSUN")) == NULL) || r; + r = ((glTexCoord4fColor4fNormal3fVertex4fSUN = (PFNGLTEXCOORD4FCOLOR4FNORMAL3FVERTEX4FSUNPROC)glewGetProcAddress((const GLubyte*)"glTexCoord4fColor4fNormal3fVertex4fSUN")) == NULL) || r; + r = ((glTexCoord4fColor4fNormal3fVertex4fvSUN = (PFNGLTEXCOORD4FCOLOR4FNORMAL3FVERTEX4FVSUNPROC)glewGetProcAddress((const GLubyte*)"glTexCoord4fColor4fNormal3fVertex4fvSUN")) == NULL) || r; + r = ((glTexCoord4fVertex4fSUN = (PFNGLTEXCOORD4FVERTEX4FSUNPROC)glewGetProcAddress((const GLubyte*)"glTexCoord4fVertex4fSUN")) == NULL) || r; + r = ((glTexCoord4fVertex4fvSUN = (PFNGLTEXCOORD4FVERTEX4FVSUNPROC)glewGetProcAddress((const GLubyte*)"glTexCoord4fVertex4fvSUN")) == NULL) || r; + + return r; +} + +#endif /* GL_SUN_vertex */ + +#ifdef GL_WIN_phong_shading + +#endif /* GL_WIN_phong_shading */ + +#ifdef GL_WIN_specular_fog + +#endif /* GL_WIN_specular_fog */ + +#ifdef GL_WIN_swap_hint + +static GLboolean _glewInit_GL_WIN_swap_hint (GLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glAddSwapHintRectWIN = (PFNGLADDSWAPHINTRECTWINPROC)glewGetProcAddress((const GLubyte*)"glAddSwapHintRectWIN")) == NULL) || r; + + return r; +} + +#endif /* GL_WIN_swap_hint */ + +/* ------------------------------------------------------------------------- */ + +/* + * Search for name in the extensions string. Use of strstr() + * is not sufficient because extension names can be prefixes of + * other extension names. Could use strtok() but the constant + * string returned by glGetString might be in read-only memory. + */ +GLboolean glewGetExtension (const char* name) +{ + GLubyte* p; + GLubyte* end; + GLuint len = _glewStrLen((const GLubyte*)name); + p = (GLubyte*)glGetString(GL_EXTENSIONS); + if (0 == p) return GL_FALSE; + end = p + _glewStrLen(p); + while (p < end) + { + GLuint n = _glewStrCLen(p, ' '); + if (len == n && _glewStrSame((const GLubyte*)name, p, n)) return GL_TRUE; + p += n+1; + } + return GL_FALSE; +} + +/* ------------------------------------------------------------------------- */ + +#ifndef GLEW_MX +static +#endif +GLenum glewContextInit (GLEW_CONTEXT_ARG_DEF_LIST) +{ + const GLubyte* s; + GLuint dot, major, minor; + /* query opengl version */ + s = glGetString(GL_VERSION); + dot = _glewStrCLen(s, '.'); + major = dot-1; + minor = dot+1; + if (dot == 0 || s[minor] == '\0') + return GLEW_ERROR_NO_GL_VERSION; + if (s[major] == '1' && s[minor] == '0') + { + return GLEW_ERROR_GL_VERSION_10_ONLY; + } + else + { + if (s[major] >= '2') + { + GLEW_VERSION_1_1 = GL_TRUE; + GLEW_VERSION_1_2 = GL_TRUE; + GLEW_VERSION_1_3 = GL_TRUE; + GLEW_VERSION_1_4 = GL_TRUE; + GLEW_VERSION_1_5 = GL_TRUE; + GLEW_VERSION_2_0 = GL_TRUE; + } + else + { + if (s[minor] >= '5') + { + GLEW_VERSION_1_1 = GL_TRUE; + GLEW_VERSION_1_2 = GL_TRUE; + GLEW_VERSION_1_3 = GL_TRUE; + GLEW_VERSION_1_4 = GL_TRUE; + GLEW_VERSION_1_5 = GL_TRUE; + GLEW_VERSION_2_0 = GL_FALSE; + } + if (s[minor] == '4') + { + GLEW_VERSION_1_1 = GL_TRUE; + GLEW_VERSION_1_2 = GL_TRUE; + GLEW_VERSION_1_3 = GL_TRUE; + GLEW_VERSION_1_4 = GL_TRUE; + GLEW_VERSION_1_5 = GL_FALSE; + GLEW_VERSION_2_0 = GL_FALSE; + } + if (s[minor] == '3') + { + GLEW_VERSION_1_1 = GL_TRUE; + GLEW_VERSION_1_2 = GL_TRUE; + GLEW_VERSION_1_3 = GL_TRUE; + GLEW_VERSION_1_4 = GL_FALSE; + GLEW_VERSION_1_5 = GL_FALSE; + GLEW_VERSION_2_0 = GL_FALSE; + } + if (s[minor] == '2') + { + GLEW_VERSION_1_1 = GL_TRUE; + GLEW_VERSION_1_2 = GL_TRUE; + GLEW_VERSION_1_3 = GL_FALSE; + GLEW_VERSION_1_4 = GL_FALSE; + GLEW_VERSION_1_5 = GL_FALSE; + GLEW_VERSION_2_0 = GL_FALSE; + } + if (s[minor] < '2') + { + GLEW_VERSION_1_1 = GL_TRUE; + GLEW_VERSION_1_2 = GL_FALSE; + GLEW_VERSION_1_3 = GL_FALSE; + GLEW_VERSION_1_4 = GL_FALSE; + GLEW_VERSION_1_5 = GL_FALSE; + GLEW_VERSION_2_0 = GL_FALSE; + } + } + } + /* initialize extensions */ +#ifdef GL_VERSION_1_2 + if (glewExperimental || GLEW_VERSION_1_2) GLEW_VERSION_1_2 = !_glewInit_GL_VERSION_1_2(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_VERSION_1_2 */ +#ifdef GL_VERSION_1_3 + if (glewExperimental || GLEW_VERSION_1_3) GLEW_VERSION_1_3 = !_glewInit_GL_VERSION_1_3(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_VERSION_1_3 */ +#ifdef GL_VERSION_1_4 + if (glewExperimental || GLEW_VERSION_1_4) GLEW_VERSION_1_4 = !_glewInit_GL_VERSION_1_4(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_VERSION_1_4 */ +#ifdef GL_VERSION_1_5 + if (glewExperimental || GLEW_VERSION_1_5) GLEW_VERSION_1_5 = !_glewInit_GL_VERSION_1_5(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_VERSION_1_5 */ +#ifdef GL_VERSION_2_0 + if (glewExperimental || GLEW_VERSION_2_0) GLEW_VERSION_2_0 = !_glewInit_GL_VERSION_2_0(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_VERSION_2_0 */ +#ifdef GL_3DFX_multisample + GLEW_3DFX_multisample = glewGetExtension("GL_3DFX_multisample"); +#endif /* GL_3DFX_multisample */ +#ifdef GL_3DFX_tbuffer + GLEW_3DFX_tbuffer = glewGetExtension("GL_3DFX_tbuffer"); + if (glewExperimental || GLEW_3DFX_tbuffer) GLEW_3DFX_tbuffer = !_glewInit_GL_3DFX_tbuffer(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_3DFX_tbuffer */ +#ifdef GL_3DFX_texture_compression_FXT1 + GLEW_3DFX_texture_compression_FXT1 = glewGetExtension("GL_3DFX_texture_compression_FXT1"); +#endif /* GL_3DFX_texture_compression_FXT1 */ +#ifdef GL_APPLE_client_storage + GLEW_APPLE_client_storage = glewGetExtension("GL_APPLE_client_storage"); +#endif /* GL_APPLE_client_storage */ +#ifdef GL_APPLE_element_array + GLEW_APPLE_element_array = glewGetExtension("GL_APPLE_element_array"); + if (glewExperimental || GLEW_APPLE_element_array) GLEW_APPLE_element_array = !_glewInit_GL_APPLE_element_array(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_APPLE_element_array */ +#ifdef GL_APPLE_fence + GLEW_APPLE_fence = glewGetExtension("GL_APPLE_fence"); + if (glewExperimental || GLEW_APPLE_fence) GLEW_APPLE_fence = !_glewInit_GL_APPLE_fence(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_APPLE_fence */ +#ifdef GL_APPLE_float_pixels + GLEW_APPLE_float_pixels = glewGetExtension("GL_APPLE_float_pixels"); +#endif /* GL_APPLE_float_pixels */ +#ifdef GL_APPLE_pixel_buffer + GLEW_APPLE_pixel_buffer = glewGetExtension("GL_APPLE_pixel_buffer"); +#endif /* GL_APPLE_pixel_buffer */ +#ifdef GL_APPLE_specular_vector + GLEW_APPLE_specular_vector = glewGetExtension("GL_APPLE_specular_vector"); +#endif /* GL_APPLE_specular_vector */ +#ifdef GL_APPLE_texture_range + GLEW_APPLE_texture_range = glewGetExtension("GL_APPLE_texture_range"); + if (glewExperimental || GLEW_APPLE_texture_range) GLEW_APPLE_texture_range = !_glewInit_GL_APPLE_texture_range(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_APPLE_texture_range */ +#ifdef GL_APPLE_transform_hint + GLEW_APPLE_transform_hint = glewGetExtension("GL_APPLE_transform_hint"); +#endif /* GL_APPLE_transform_hint */ +#ifdef GL_APPLE_vertex_array_object + GLEW_APPLE_vertex_array_object = glewGetExtension("GL_APPLE_vertex_array_object"); + if (glewExperimental || GLEW_APPLE_vertex_array_object) GLEW_APPLE_vertex_array_object = !_glewInit_GL_APPLE_vertex_array_object(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_APPLE_vertex_array_object */ +#ifdef GL_APPLE_vertex_array_range + GLEW_APPLE_vertex_array_range = glewGetExtension("GL_APPLE_vertex_array_range"); + if (glewExperimental || GLEW_APPLE_vertex_array_range) GLEW_APPLE_vertex_array_range = !_glewInit_GL_APPLE_vertex_array_range(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_APPLE_vertex_array_range */ +#ifdef GL_APPLE_ycbcr_422 + GLEW_APPLE_ycbcr_422 = glewGetExtension("GL_APPLE_ycbcr_422"); +#endif /* GL_APPLE_ycbcr_422 */ +#ifdef GL_ARB_color_buffer_float + GLEW_ARB_color_buffer_float = glewGetExtension("GL_ARB_color_buffer_float"); + if (glewExperimental || GLEW_ARB_color_buffer_float) GLEW_ARB_color_buffer_float = !_glewInit_GL_ARB_color_buffer_float(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ARB_color_buffer_float */ +#ifdef GL_ARB_depth_texture + GLEW_ARB_depth_texture = glewGetExtension("GL_ARB_depth_texture"); +#endif /* GL_ARB_depth_texture */ +#ifdef GL_ARB_draw_buffers + GLEW_ARB_draw_buffers = glewGetExtension("GL_ARB_draw_buffers"); + if (glewExperimental || GLEW_ARB_draw_buffers) GLEW_ARB_draw_buffers = !_glewInit_GL_ARB_draw_buffers(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ARB_draw_buffers */ +#ifdef GL_ARB_fragment_program + GLEW_ARB_fragment_program = glewGetExtension("GL_ARB_fragment_program"); +#endif /* GL_ARB_fragment_program */ +#ifdef GL_ARB_fragment_program_shadow + GLEW_ARB_fragment_program_shadow = glewGetExtension("GL_ARB_fragment_program_shadow"); +#endif /* GL_ARB_fragment_program_shadow */ +#ifdef GL_ARB_fragment_shader + GLEW_ARB_fragment_shader = glewGetExtension("GL_ARB_fragment_shader"); +#endif /* GL_ARB_fragment_shader */ +#ifdef GL_ARB_half_float_pixel + GLEW_ARB_half_float_pixel = glewGetExtension("GL_ARB_half_float_pixel"); +#endif /* GL_ARB_half_float_pixel */ +#ifdef GL_ARB_imaging + GLEW_ARB_imaging = glewGetExtension("GL_ARB_imaging"); + if (glewExperimental || GLEW_ARB_imaging) GLEW_ARB_imaging = !_glewInit_GL_ARB_imaging(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ARB_imaging */ +#ifdef GL_ARB_matrix_palette + GLEW_ARB_matrix_palette = glewGetExtension("GL_ARB_matrix_palette"); + if (glewExperimental || GLEW_ARB_matrix_palette) GLEW_ARB_matrix_palette = !_glewInit_GL_ARB_matrix_palette(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ARB_matrix_palette */ +#ifdef GL_ARB_multisample + GLEW_ARB_multisample = glewGetExtension("GL_ARB_multisample"); + if (glewExperimental || GLEW_ARB_multisample) GLEW_ARB_multisample = !_glewInit_GL_ARB_multisample(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ARB_multisample */ +#ifdef GL_ARB_multitexture + GLEW_ARB_multitexture = glewGetExtension("GL_ARB_multitexture"); + if (glewExperimental || GLEW_ARB_multitexture) GLEW_ARB_multitexture = !_glewInit_GL_ARB_multitexture(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ARB_multitexture */ +#ifdef GL_ARB_occlusion_query + GLEW_ARB_occlusion_query = glewGetExtension("GL_ARB_occlusion_query"); + if (glewExperimental || GLEW_ARB_occlusion_query) GLEW_ARB_occlusion_query = !_glewInit_GL_ARB_occlusion_query(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ARB_occlusion_query */ +#ifdef GL_ARB_pixel_buffer_object + GLEW_ARB_pixel_buffer_object = glewGetExtension("GL_ARB_pixel_buffer_object"); +#endif /* GL_ARB_pixel_buffer_object */ +#ifdef GL_ARB_point_parameters + GLEW_ARB_point_parameters = glewGetExtension("GL_ARB_point_parameters"); + if (glewExperimental || GLEW_ARB_point_parameters) GLEW_ARB_point_parameters = !_glewInit_GL_ARB_point_parameters(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ARB_point_parameters */ +#ifdef GL_ARB_point_sprite + GLEW_ARB_point_sprite = glewGetExtension("GL_ARB_point_sprite"); +#endif /* GL_ARB_point_sprite */ +#ifdef GL_ARB_shader_objects + GLEW_ARB_shader_objects = glewGetExtension("GL_ARB_shader_objects"); + if (glewExperimental || GLEW_ARB_shader_objects) GLEW_ARB_shader_objects = !_glewInit_GL_ARB_shader_objects(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ARB_shader_objects */ +#ifdef GL_ARB_shading_language_100 + GLEW_ARB_shading_language_100 = glewGetExtension("GL_ARB_shading_language_100"); +#endif /* GL_ARB_shading_language_100 */ +#ifdef GL_ARB_shadow + GLEW_ARB_shadow = glewGetExtension("GL_ARB_shadow"); +#endif /* GL_ARB_shadow */ +#ifdef GL_ARB_shadow_ambient + GLEW_ARB_shadow_ambient = glewGetExtension("GL_ARB_shadow_ambient"); +#endif /* GL_ARB_shadow_ambient */ +#ifdef GL_ARB_texture_border_clamp + GLEW_ARB_texture_border_clamp = glewGetExtension("GL_ARB_texture_border_clamp"); +#endif /* GL_ARB_texture_border_clamp */ +#ifdef GL_ARB_texture_compression + GLEW_ARB_texture_compression = glewGetExtension("GL_ARB_texture_compression"); + if (glewExperimental || GLEW_ARB_texture_compression) GLEW_ARB_texture_compression = !_glewInit_GL_ARB_texture_compression(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ARB_texture_compression */ +#ifdef GL_ARB_texture_cube_map + GLEW_ARB_texture_cube_map = glewGetExtension("GL_ARB_texture_cube_map"); +#endif /* GL_ARB_texture_cube_map */ +#ifdef GL_ARB_texture_env_add + GLEW_ARB_texture_env_add = glewGetExtension("GL_ARB_texture_env_add"); +#endif /* GL_ARB_texture_env_add */ +#ifdef GL_ARB_texture_env_combine + GLEW_ARB_texture_env_combine = glewGetExtension("GL_ARB_texture_env_combine"); +#endif /* GL_ARB_texture_env_combine */ +#ifdef GL_ARB_texture_env_crossbar + GLEW_ARB_texture_env_crossbar = glewGetExtension("GL_ARB_texture_env_crossbar"); +#endif /* GL_ARB_texture_env_crossbar */ +#ifdef GL_ARB_texture_env_dot3 + GLEW_ARB_texture_env_dot3 = glewGetExtension("GL_ARB_texture_env_dot3"); +#endif /* GL_ARB_texture_env_dot3 */ +#ifdef GL_ARB_texture_float + GLEW_ARB_texture_float = glewGetExtension("GL_ARB_texture_float"); +#endif /* GL_ARB_texture_float */ +#ifdef GL_ARB_texture_mirrored_repeat + GLEW_ARB_texture_mirrored_repeat = glewGetExtension("GL_ARB_texture_mirrored_repeat"); +#endif /* GL_ARB_texture_mirrored_repeat */ +#ifdef GL_ARB_texture_non_power_of_two + GLEW_ARB_texture_non_power_of_two = glewGetExtension("GL_ARB_texture_non_power_of_two"); +#endif /* GL_ARB_texture_non_power_of_two */ +#ifdef GL_ARB_texture_rectangle + GLEW_ARB_texture_rectangle = glewGetExtension("GL_ARB_texture_rectangle"); +#endif /* GL_ARB_texture_rectangle */ +#ifdef GL_ARB_transpose_matrix + GLEW_ARB_transpose_matrix = glewGetExtension("GL_ARB_transpose_matrix"); + if (glewExperimental || GLEW_ARB_transpose_matrix) GLEW_ARB_transpose_matrix = !_glewInit_GL_ARB_transpose_matrix(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ARB_transpose_matrix */ +#ifdef GL_ARB_vertex_blend + GLEW_ARB_vertex_blend = glewGetExtension("GL_ARB_vertex_blend"); + if (glewExperimental || GLEW_ARB_vertex_blend) GLEW_ARB_vertex_blend = !_glewInit_GL_ARB_vertex_blend(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ARB_vertex_blend */ +#ifdef GL_ARB_vertex_buffer_object + GLEW_ARB_vertex_buffer_object = glewGetExtension("GL_ARB_vertex_buffer_object"); + if (glewExperimental || GLEW_ARB_vertex_buffer_object) GLEW_ARB_vertex_buffer_object = !_glewInit_GL_ARB_vertex_buffer_object(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ARB_vertex_buffer_object */ +#ifdef GL_ARB_vertex_program + GLEW_ARB_vertex_program = glewGetExtension("GL_ARB_vertex_program"); + if (glewExperimental || GLEW_ARB_vertex_program) GLEW_ARB_vertex_program = !_glewInit_GL_ARB_vertex_program(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ARB_vertex_program */ +#ifdef GL_ARB_vertex_shader + GLEW_ARB_vertex_shader = glewGetExtension("GL_ARB_vertex_shader"); + if (glewExperimental || GLEW_ARB_vertex_shader) { GLEW_ARB_vertex_shader = !_glewInit_GL_ARB_vertex_shader(GLEW_CONTEXT_ARG_VAR_INIT); _glewInit_GL_ARB_vertex_program(GLEW_CONTEXT_ARG_VAR_INIT); } +#endif /* GL_ARB_vertex_shader */ +#ifdef GL_ARB_window_pos + GLEW_ARB_window_pos = glewGetExtension("GL_ARB_window_pos"); + if (glewExperimental || GLEW_ARB_window_pos) GLEW_ARB_window_pos = !_glewInit_GL_ARB_window_pos(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ARB_window_pos */ +#ifdef GL_ATIX_point_sprites + GLEW_ATIX_point_sprites = glewGetExtension("GL_ATIX_point_sprites"); +#endif /* GL_ATIX_point_sprites */ +#ifdef GL_ATIX_texture_env_combine3 + GLEW_ATIX_texture_env_combine3 = glewGetExtension("GL_ATIX_texture_env_combine3"); +#endif /* GL_ATIX_texture_env_combine3 */ +#ifdef GL_ATIX_texture_env_route + GLEW_ATIX_texture_env_route = glewGetExtension("GL_ATIX_texture_env_route"); +#endif /* GL_ATIX_texture_env_route */ +#ifdef GL_ATIX_vertex_shader_output_point_size + GLEW_ATIX_vertex_shader_output_point_size = glewGetExtension("GL_ATIX_vertex_shader_output_point_size"); +#endif /* GL_ATIX_vertex_shader_output_point_size */ +#ifdef GL_ATI_draw_buffers + GLEW_ATI_draw_buffers = glewGetExtension("GL_ATI_draw_buffers"); + if (glewExperimental || GLEW_ATI_draw_buffers) GLEW_ATI_draw_buffers = !_glewInit_GL_ATI_draw_buffers(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ATI_draw_buffers */ +#ifdef GL_ATI_element_array + GLEW_ATI_element_array = glewGetExtension("GL_ATI_element_array"); + if (glewExperimental || GLEW_ATI_element_array) GLEW_ATI_element_array = !_glewInit_GL_ATI_element_array(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ATI_element_array */ +#ifdef GL_ATI_envmap_bumpmap + GLEW_ATI_envmap_bumpmap = glewGetExtension("GL_ATI_envmap_bumpmap"); + if (glewExperimental || GLEW_ATI_envmap_bumpmap) GLEW_ATI_envmap_bumpmap = !_glewInit_GL_ATI_envmap_bumpmap(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ATI_envmap_bumpmap */ +#ifdef GL_ATI_fragment_shader + GLEW_ATI_fragment_shader = glewGetExtension("GL_ATI_fragment_shader"); + if (glewExperimental || GLEW_ATI_fragment_shader) GLEW_ATI_fragment_shader = !_glewInit_GL_ATI_fragment_shader(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ATI_fragment_shader */ +#ifdef GL_ATI_map_object_buffer + GLEW_ATI_map_object_buffer = glewGetExtension("GL_ATI_map_object_buffer"); + if (glewExperimental || GLEW_ATI_map_object_buffer) GLEW_ATI_map_object_buffer = !_glewInit_GL_ATI_map_object_buffer(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ATI_map_object_buffer */ +#ifdef GL_ATI_pn_triangles + GLEW_ATI_pn_triangles = glewGetExtension("GL_ATI_pn_triangles"); + if (glewExperimental || GLEW_ATI_pn_triangles) GLEW_ATI_pn_triangles = !_glewInit_GL_ATI_pn_triangles(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ATI_pn_triangles */ +#ifdef GL_ATI_separate_stencil + GLEW_ATI_separate_stencil = glewGetExtension("GL_ATI_separate_stencil"); + if (glewExperimental || GLEW_ATI_separate_stencil) GLEW_ATI_separate_stencil = !_glewInit_GL_ATI_separate_stencil(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ATI_separate_stencil */ +#ifdef GL_ATI_text_fragment_shader + GLEW_ATI_text_fragment_shader = glewGetExtension("GL_ATI_text_fragment_shader"); +#endif /* GL_ATI_text_fragment_shader */ +#ifdef GL_ATI_texture_compression_3dc + GLEW_ATI_texture_compression_3dc = glewGetExtension("GL_ATI_texture_compression_3dc"); +#endif /* GL_ATI_texture_compression_3dc */ +#ifdef GL_ATI_texture_env_combine3 + GLEW_ATI_texture_env_combine3 = glewGetExtension("GL_ATI_texture_env_combine3"); +#endif /* GL_ATI_texture_env_combine3 */ +#ifdef GL_ATI_texture_float + GLEW_ATI_texture_float = glewGetExtension("GL_ATI_texture_float"); +#endif /* GL_ATI_texture_float */ +#ifdef GL_ATI_texture_mirror_once + GLEW_ATI_texture_mirror_once = glewGetExtension("GL_ATI_texture_mirror_once"); +#endif /* GL_ATI_texture_mirror_once */ +#ifdef GL_ATI_vertex_array_object + GLEW_ATI_vertex_array_object = glewGetExtension("GL_ATI_vertex_array_object"); + if (glewExperimental || GLEW_ATI_vertex_array_object) GLEW_ATI_vertex_array_object = !_glewInit_GL_ATI_vertex_array_object(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ATI_vertex_array_object */ +#ifdef GL_ATI_vertex_attrib_array_object + GLEW_ATI_vertex_attrib_array_object = glewGetExtension("GL_ATI_vertex_attrib_array_object"); + if (glewExperimental || GLEW_ATI_vertex_attrib_array_object) GLEW_ATI_vertex_attrib_array_object = !_glewInit_GL_ATI_vertex_attrib_array_object(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ATI_vertex_attrib_array_object */ +#ifdef GL_ATI_vertex_streams + GLEW_ATI_vertex_streams = glewGetExtension("GL_ATI_vertex_streams"); + if (glewExperimental || GLEW_ATI_vertex_streams) GLEW_ATI_vertex_streams = !_glewInit_GL_ATI_vertex_streams(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ATI_vertex_streams */ +#ifdef GL_EXT_422_pixels + GLEW_EXT_422_pixels = glewGetExtension("GL_EXT_422_pixels"); +#endif /* GL_EXT_422_pixels */ +#ifdef GL_EXT_Cg_shader + GLEW_EXT_Cg_shader = glewGetExtension("GL_EXT_Cg_shader"); +#endif /* GL_EXT_Cg_shader */ +#ifdef GL_EXT_abgr + GLEW_EXT_abgr = glewGetExtension("GL_EXT_abgr"); +#endif /* GL_EXT_abgr */ +#ifdef GL_EXT_bgra + GLEW_EXT_bgra = glewGetExtension("GL_EXT_bgra"); +#endif /* GL_EXT_bgra */ +#ifdef GL_EXT_blend_color + GLEW_EXT_blend_color = glewGetExtension("GL_EXT_blend_color"); + if (glewExperimental || GLEW_EXT_blend_color) GLEW_EXT_blend_color = !_glewInit_GL_EXT_blend_color(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_blend_color */ +#ifdef GL_EXT_blend_equation_separate + GLEW_EXT_blend_equation_separate = glewGetExtension("GL_EXT_blend_equation_separate"); + if (glewExperimental || GLEW_EXT_blend_equation_separate) GLEW_EXT_blend_equation_separate = !_glewInit_GL_EXT_blend_equation_separate(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_blend_equation_separate */ +#ifdef GL_EXT_blend_func_separate + GLEW_EXT_blend_func_separate = glewGetExtension("GL_EXT_blend_func_separate"); + if (glewExperimental || GLEW_EXT_blend_func_separate) GLEW_EXT_blend_func_separate = !_glewInit_GL_EXT_blend_func_separate(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_blend_func_separate */ +#ifdef GL_EXT_blend_logic_op + GLEW_EXT_blend_logic_op = glewGetExtension("GL_EXT_blend_logic_op"); +#endif /* GL_EXT_blend_logic_op */ +#ifdef GL_EXT_blend_minmax + GLEW_EXT_blend_minmax = glewGetExtension("GL_EXT_blend_minmax"); + if (glewExperimental || GLEW_EXT_blend_minmax) GLEW_EXT_blend_minmax = !_glewInit_GL_EXT_blend_minmax(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_blend_minmax */ +#ifdef GL_EXT_blend_subtract + GLEW_EXT_blend_subtract = glewGetExtension("GL_EXT_blend_subtract"); +#endif /* GL_EXT_blend_subtract */ +#ifdef GL_EXT_clip_volume_hint + GLEW_EXT_clip_volume_hint = glewGetExtension("GL_EXT_clip_volume_hint"); +#endif /* GL_EXT_clip_volume_hint */ +#ifdef GL_EXT_cmyka + GLEW_EXT_cmyka = glewGetExtension("GL_EXT_cmyka"); +#endif /* GL_EXT_cmyka */ +#ifdef GL_EXT_color_subtable + GLEW_EXT_color_subtable = glewGetExtension("GL_EXT_color_subtable"); + if (glewExperimental || GLEW_EXT_color_subtable) GLEW_EXT_color_subtable = !_glewInit_GL_EXT_color_subtable(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_color_subtable */ +#ifdef GL_EXT_compiled_vertex_array + GLEW_EXT_compiled_vertex_array = glewGetExtension("GL_EXT_compiled_vertex_array"); + if (glewExperimental || GLEW_EXT_compiled_vertex_array) GLEW_EXT_compiled_vertex_array = !_glewInit_GL_EXT_compiled_vertex_array(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_compiled_vertex_array */ +#ifdef GL_EXT_convolution + GLEW_EXT_convolution = glewGetExtension("GL_EXT_convolution"); + if (glewExperimental || GLEW_EXT_convolution) GLEW_EXT_convolution = !_glewInit_GL_EXT_convolution(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_convolution */ +#ifdef GL_EXT_coordinate_frame + GLEW_EXT_coordinate_frame = glewGetExtension("GL_EXT_coordinate_frame"); + if (glewExperimental || GLEW_EXT_coordinate_frame) GLEW_EXT_coordinate_frame = !_glewInit_GL_EXT_coordinate_frame(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_coordinate_frame */ +#ifdef GL_EXT_copy_texture + GLEW_EXT_copy_texture = glewGetExtension("GL_EXT_copy_texture"); + if (glewExperimental || GLEW_EXT_copy_texture) GLEW_EXT_copy_texture = !_glewInit_GL_EXT_copy_texture(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_copy_texture */ +#ifdef GL_EXT_cull_vertex + GLEW_EXT_cull_vertex = glewGetExtension("GL_EXT_cull_vertex"); + if (glewExperimental || GLEW_EXT_cull_vertex) GLEW_EXT_cull_vertex = !_glewInit_GL_EXT_cull_vertex(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_cull_vertex */ +#ifdef GL_EXT_depth_bounds_test + GLEW_EXT_depth_bounds_test = glewGetExtension("GL_EXT_depth_bounds_test"); + if (glewExperimental || GLEW_EXT_depth_bounds_test) GLEW_EXT_depth_bounds_test = !_glewInit_GL_EXT_depth_bounds_test(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_depth_bounds_test */ +#ifdef GL_EXT_draw_range_elements + GLEW_EXT_draw_range_elements = glewGetExtension("GL_EXT_draw_range_elements"); + if (glewExperimental || GLEW_EXT_draw_range_elements) GLEW_EXT_draw_range_elements = !_glewInit_GL_EXT_draw_range_elements(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_draw_range_elements */ +#ifdef GL_EXT_fog_coord + GLEW_EXT_fog_coord = glewGetExtension("GL_EXT_fog_coord"); + if (glewExperimental || GLEW_EXT_fog_coord) GLEW_EXT_fog_coord = !_glewInit_GL_EXT_fog_coord(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_fog_coord */ +#ifdef GL_EXT_fragment_lighting + GLEW_EXT_fragment_lighting = glewGetExtension("GL_EXT_fragment_lighting"); + if (glewExperimental || GLEW_EXT_fragment_lighting) GLEW_EXT_fragment_lighting = !_glewInit_GL_EXT_fragment_lighting(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_fragment_lighting */ +#ifdef GL_EXT_framebuffer_blit + GLEW_EXT_framebuffer_blit = glewGetExtension("GL_EXT_framebuffer_blit"); + if (glewExperimental || GLEW_EXT_framebuffer_blit) GLEW_EXT_framebuffer_blit = !_glewInit_GL_EXT_framebuffer_blit(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_framebuffer_blit */ +#ifdef GL_EXT_framebuffer_multisample + GLEW_EXT_framebuffer_multisample = glewGetExtension("GL_EXT_framebuffer_multisample"); + if (glewExperimental || GLEW_EXT_framebuffer_multisample) GLEW_EXT_framebuffer_multisample = !_glewInit_GL_EXT_framebuffer_multisample(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_framebuffer_multisample */ +#ifdef GL_EXT_framebuffer_object + GLEW_EXT_framebuffer_object = glewGetExtension("GL_EXT_framebuffer_object"); + if (glewExperimental || GLEW_EXT_framebuffer_object) GLEW_EXT_framebuffer_object = !_glewInit_GL_EXT_framebuffer_object(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_framebuffer_object */ +#ifdef GL_EXT_histogram + GLEW_EXT_histogram = glewGetExtension("GL_EXT_histogram"); + if (glewExperimental || GLEW_EXT_histogram) GLEW_EXT_histogram = !_glewInit_GL_EXT_histogram(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_histogram */ +#ifdef GL_EXT_index_array_formats + GLEW_EXT_index_array_formats = glewGetExtension("GL_EXT_index_array_formats"); +#endif /* GL_EXT_index_array_formats */ +#ifdef GL_EXT_index_func + GLEW_EXT_index_func = glewGetExtension("GL_EXT_index_func"); + if (glewExperimental || GLEW_EXT_index_func) GLEW_EXT_index_func = !_glewInit_GL_EXT_index_func(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_index_func */ +#ifdef GL_EXT_index_material + GLEW_EXT_index_material = glewGetExtension("GL_EXT_index_material"); + if (glewExperimental || GLEW_EXT_index_material) GLEW_EXT_index_material = !_glewInit_GL_EXT_index_material(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_index_material */ +#ifdef GL_EXT_index_texture + GLEW_EXT_index_texture = glewGetExtension("GL_EXT_index_texture"); +#endif /* GL_EXT_index_texture */ +#ifdef GL_EXT_light_texture + GLEW_EXT_light_texture = glewGetExtension("GL_EXT_light_texture"); + if (glewExperimental || GLEW_EXT_light_texture) GLEW_EXT_light_texture = !_glewInit_GL_EXT_light_texture(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_light_texture */ +#ifdef GL_EXT_misc_attribute + GLEW_EXT_misc_attribute = glewGetExtension("GL_EXT_misc_attribute"); +#endif /* GL_EXT_misc_attribute */ +#ifdef GL_EXT_multi_draw_arrays + GLEW_EXT_multi_draw_arrays = glewGetExtension("GL_EXT_multi_draw_arrays"); + if (glewExperimental || GLEW_EXT_multi_draw_arrays) GLEW_EXT_multi_draw_arrays = !_glewInit_GL_EXT_multi_draw_arrays(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_multi_draw_arrays */ +#ifdef GL_EXT_multisample + GLEW_EXT_multisample = glewGetExtension("GL_EXT_multisample"); + if (glewExperimental || GLEW_EXT_multisample) GLEW_EXT_multisample = !_glewInit_GL_EXT_multisample(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_multisample */ +#ifdef GL_EXT_packed_depth_stencil + GLEW_EXT_packed_depth_stencil = glewGetExtension("GL_EXT_packed_depth_stencil"); +#endif /* GL_EXT_packed_depth_stencil */ +#ifdef GL_EXT_packed_pixels + GLEW_EXT_packed_pixels = glewGetExtension("GL_EXT_packed_pixels"); +#endif /* GL_EXT_packed_pixels */ +#ifdef GL_EXT_paletted_texture + GLEW_EXT_paletted_texture = glewGetExtension("GL_EXT_paletted_texture"); + if (glewExperimental || GLEW_EXT_paletted_texture) GLEW_EXT_paletted_texture = !_glewInit_GL_EXT_paletted_texture(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_paletted_texture */ +#ifdef GL_EXT_pixel_buffer_object + GLEW_EXT_pixel_buffer_object = glewGetExtension("GL_EXT_pixel_buffer_object"); +#endif /* GL_EXT_pixel_buffer_object */ +#ifdef GL_EXT_pixel_transform + GLEW_EXT_pixel_transform = glewGetExtension("GL_EXT_pixel_transform"); + if (glewExperimental || GLEW_EXT_pixel_transform) GLEW_EXT_pixel_transform = !_glewInit_GL_EXT_pixel_transform(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_pixel_transform */ +#ifdef GL_EXT_pixel_transform_color_table + GLEW_EXT_pixel_transform_color_table = glewGetExtension("GL_EXT_pixel_transform_color_table"); +#endif /* GL_EXT_pixel_transform_color_table */ +#ifdef GL_EXT_point_parameters + GLEW_EXT_point_parameters = glewGetExtension("GL_EXT_point_parameters"); + if (glewExperimental || GLEW_EXT_point_parameters) GLEW_EXT_point_parameters = !_glewInit_GL_EXT_point_parameters(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_point_parameters */ +#ifdef GL_EXT_polygon_offset + GLEW_EXT_polygon_offset = glewGetExtension("GL_EXT_polygon_offset"); + if (glewExperimental || GLEW_EXT_polygon_offset) GLEW_EXT_polygon_offset = !_glewInit_GL_EXT_polygon_offset(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_polygon_offset */ +#ifdef GL_EXT_rescale_normal + GLEW_EXT_rescale_normal = glewGetExtension("GL_EXT_rescale_normal"); +#endif /* GL_EXT_rescale_normal */ +#ifdef GL_EXT_scene_marker + GLEW_EXT_scene_marker = glewGetExtension("GL_EXT_scene_marker"); + if (glewExperimental || GLEW_EXT_scene_marker) GLEW_EXT_scene_marker = !_glewInit_GL_EXT_scene_marker(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_scene_marker */ +#ifdef GL_EXT_secondary_color + GLEW_EXT_secondary_color = glewGetExtension("GL_EXT_secondary_color"); + if (glewExperimental || GLEW_EXT_secondary_color) GLEW_EXT_secondary_color = !_glewInit_GL_EXT_secondary_color(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_secondary_color */ +#ifdef GL_EXT_separate_specular_color + GLEW_EXT_separate_specular_color = glewGetExtension("GL_EXT_separate_specular_color"); +#endif /* GL_EXT_separate_specular_color */ +#ifdef GL_EXT_shadow_funcs + GLEW_EXT_shadow_funcs = glewGetExtension("GL_EXT_shadow_funcs"); +#endif /* GL_EXT_shadow_funcs */ +#ifdef GL_EXT_shared_texture_palette + GLEW_EXT_shared_texture_palette = glewGetExtension("GL_EXT_shared_texture_palette"); +#endif /* GL_EXT_shared_texture_palette */ +#ifdef GL_EXT_stencil_clear_tag + GLEW_EXT_stencil_clear_tag = glewGetExtension("GL_EXT_stencil_clear_tag"); +#endif /* GL_EXT_stencil_clear_tag */ +#ifdef GL_EXT_stencil_two_side + GLEW_EXT_stencil_two_side = glewGetExtension("GL_EXT_stencil_two_side"); + if (glewExperimental || GLEW_EXT_stencil_two_side) GLEW_EXT_stencil_two_side = !_glewInit_GL_EXT_stencil_two_side(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_stencil_two_side */ +#ifdef GL_EXT_stencil_wrap + GLEW_EXT_stencil_wrap = glewGetExtension("GL_EXT_stencil_wrap"); +#endif /* GL_EXT_stencil_wrap */ +#ifdef GL_EXT_subtexture + GLEW_EXT_subtexture = glewGetExtension("GL_EXT_subtexture"); + if (glewExperimental || GLEW_EXT_subtexture) GLEW_EXT_subtexture = !_glewInit_GL_EXT_subtexture(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_subtexture */ +#ifdef GL_EXT_texture + GLEW_EXT_texture = glewGetExtension("GL_EXT_texture"); +#endif /* GL_EXT_texture */ +#ifdef GL_EXT_texture3D + GLEW_EXT_texture3D = glewGetExtension("GL_EXT_texture3D"); + if (glewExperimental || GLEW_EXT_texture3D) GLEW_EXT_texture3D = !_glewInit_GL_EXT_texture3D(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_texture3D */ +#ifdef GL_EXT_texture_compression_dxt1 + GLEW_EXT_texture_compression_dxt1 = glewGetExtension("GL_EXT_texture_compression_dxt1"); +#endif /* GL_EXT_texture_compression_dxt1 */ +#ifdef GL_EXT_texture_compression_s3tc + GLEW_EXT_texture_compression_s3tc = glewGetExtension("GL_EXT_texture_compression_s3tc"); +#endif /* GL_EXT_texture_compression_s3tc */ +#ifdef GL_EXT_texture_cube_map + GLEW_EXT_texture_cube_map = glewGetExtension("GL_EXT_texture_cube_map"); +#endif /* GL_EXT_texture_cube_map */ +#ifdef GL_EXT_texture_edge_clamp + GLEW_EXT_texture_edge_clamp = glewGetExtension("GL_EXT_texture_edge_clamp"); +#endif /* GL_EXT_texture_edge_clamp */ +#ifdef GL_EXT_texture_env + GLEW_EXT_texture_env = glewGetExtension("GL_EXT_texture_env"); +#endif /* GL_EXT_texture_env */ +#ifdef GL_EXT_texture_env_add + GLEW_EXT_texture_env_add = glewGetExtension("GL_EXT_texture_env_add"); +#endif /* GL_EXT_texture_env_add */ +#ifdef GL_EXT_texture_env_combine + GLEW_EXT_texture_env_combine = glewGetExtension("GL_EXT_texture_env_combine"); +#endif /* GL_EXT_texture_env_combine */ +#ifdef GL_EXT_texture_env_dot3 + GLEW_EXT_texture_env_dot3 = glewGetExtension("GL_EXT_texture_env_dot3"); +#endif /* GL_EXT_texture_env_dot3 */ +#ifdef GL_EXT_texture_filter_anisotropic + GLEW_EXT_texture_filter_anisotropic = glewGetExtension("GL_EXT_texture_filter_anisotropic"); +#endif /* GL_EXT_texture_filter_anisotropic */ +#ifdef GL_EXT_texture_lod_bias + GLEW_EXT_texture_lod_bias = glewGetExtension("GL_EXT_texture_lod_bias"); +#endif /* GL_EXT_texture_lod_bias */ +#ifdef GL_EXT_texture_mirror_clamp + GLEW_EXT_texture_mirror_clamp = glewGetExtension("GL_EXT_texture_mirror_clamp"); +#endif /* GL_EXT_texture_mirror_clamp */ +#ifdef GL_EXT_texture_object + GLEW_EXT_texture_object = glewGetExtension("GL_EXT_texture_object"); + if (glewExperimental || GLEW_EXT_texture_object) GLEW_EXT_texture_object = !_glewInit_GL_EXT_texture_object(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_texture_object */ +#ifdef GL_EXT_texture_perturb_normal + GLEW_EXT_texture_perturb_normal = glewGetExtension("GL_EXT_texture_perturb_normal"); + if (glewExperimental || GLEW_EXT_texture_perturb_normal) GLEW_EXT_texture_perturb_normal = !_glewInit_GL_EXT_texture_perturb_normal(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_texture_perturb_normal */ +#ifdef GL_EXT_texture_rectangle + GLEW_EXT_texture_rectangle = glewGetExtension("GL_EXT_texture_rectangle"); +#endif /* GL_EXT_texture_rectangle */ +#ifdef GL_EXT_texture_sRGB + GLEW_EXT_texture_sRGB = glewGetExtension("GL_EXT_texture_sRGB"); +#endif /* GL_EXT_texture_sRGB */ +#ifdef GL_EXT_vertex_array + GLEW_EXT_vertex_array = glewGetExtension("GL_EXT_vertex_array"); + if (glewExperimental || GLEW_EXT_vertex_array) GLEW_EXT_vertex_array = !_glewInit_GL_EXT_vertex_array(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_vertex_array */ +#ifdef GL_EXT_vertex_shader + GLEW_EXT_vertex_shader = glewGetExtension("GL_EXT_vertex_shader"); + if (glewExperimental || GLEW_EXT_vertex_shader) GLEW_EXT_vertex_shader = !_glewInit_GL_EXT_vertex_shader(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_vertex_shader */ +#ifdef GL_EXT_vertex_weighting + GLEW_EXT_vertex_weighting = glewGetExtension("GL_EXT_vertex_weighting"); + if (glewExperimental || GLEW_EXT_vertex_weighting) GLEW_EXT_vertex_weighting = !_glewInit_GL_EXT_vertex_weighting(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_vertex_weighting */ +#ifdef GL_GREMEDY_string_marker + GLEW_GREMEDY_string_marker = glewGetExtension("GL_GREMEDY_string_marker"); + if (glewExperimental || GLEW_GREMEDY_string_marker) GLEW_GREMEDY_string_marker = !_glewInit_GL_GREMEDY_string_marker(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_GREMEDY_string_marker */ +#ifdef GL_HP_convolution_border_modes + GLEW_HP_convolution_border_modes = glewGetExtension("GL_HP_convolution_border_modes"); +#endif /* GL_HP_convolution_border_modes */ +#ifdef GL_HP_image_transform + GLEW_HP_image_transform = glewGetExtension("GL_HP_image_transform"); + if (glewExperimental || GLEW_HP_image_transform) GLEW_HP_image_transform = !_glewInit_GL_HP_image_transform(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_HP_image_transform */ +#ifdef GL_HP_occlusion_test + GLEW_HP_occlusion_test = glewGetExtension("GL_HP_occlusion_test"); +#endif /* GL_HP_occlusion_test */ +#ifdef GL_HP_texture_lighting + GLEW_HP_texture_lighting = glewGetExtension("GL_HP_texture_lighting"); +#endif /* GL_HP_texture_lighting */ +#ifdef GL_IBM_cull_vertex + GLEW_IBM_cull_vertex = glewGetExtension("GL_IBM_cull_vertex"); +#endif /* GL_IBM_cull_vertex */ +#ifdef GL_IBM_multimode_draw_arrays + GLEW_IBM_multimode_draw_arrays = glewGetExtension("GL_IBM_multimode_draw_arrays"); + if (glewExperimental || GLEW_IBM_multimode_draw_arrays) GLEW_IBM_multimode_draw_arrays = !_glewInit_GL_IBM_multimode_draw_arrays(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_IBM_multimode_draw_arrays */ +#ifdef GL_IBM_rasterpos_clip + GLEW_IBM_rasterpos_clip = glewGetExtension("GL_IBM_rasterpos_clip"); +#endif /* GL_IBM_rasterpos_clip */ +#ifdef GL_IBM_static_data + GLEW_IBM_static_data = glewGetExtension("GL_IBM_static_data"); +#endif /* GL_IBM_static_data */ +#ifdef GL_IBM_texture_mirrored_repeat + GLEW_IBM_texture_mirrored_repeat = glewGetExtension("GL_IBM_texture_mirrored_repeat"); +#endif /* GL_IBM_texture_mirrored_repeat */ +#ifdef GL_IBM_vertex_array_lists + GLEW_IBM_vertex_array_lists = glewGetExtension("GL_IBM_vertex_array_lists"); + if (glewExperimental || GLEW_IBM_vertex_array_lists) GLEW_IBM_vertex_array_lists = !_glewInit_GL_IBM_vertex_array_lists(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_IBM_vertex_array_lists */ +#ifdef GL_INGR_color_clamp + GLEW_INGR_color_clamp = glewGetExtension("GL_INGR_color_clamp"); +#endif /* GL_INGR_color_clamp */ +#ifdef GL_INGR_interlace_read + GLEW_INGR_interlace_read = glewGetExtension("GL_INGR_interlace_read"); +#endif /* GL_INGR_interlace_read */ +#ifdef GL_INTEL_parallel_arrays + GLEW_INTEL_parallel_arrays = glewGetExtension("GL_INTEL_parallel_arrays"); + if (glewExperimental || GLEW_INTEL_parallel_arrays) GLEW_INTEL_parallel_arrays = !_glewInit_GL_INTEL_parallel_arrays(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_INTEL_parallel_arrays */ +#ifdef GL_INTEL_texture_scissor + GLEW_INTEL_texture_scissor = glewGetExtension("GL_INTEL_texture_scissor"); + if (glewExperimental || GLEW_INTEL_texture_scissor) GLEW_INTEL_texture_scissor = !_glewInit_GL_INTEL_texture_scissor(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_INTEL_texture_scissor */ +#ifdef GL_KTX_buffer_region + GLEW_KTX_buffer_region = glewGetExtension("GL_KTX_buffer_region"); + if (glewExperimental || GLEW_KTX_buffer_region) GLEW_KTX_buffer_region = !_glewInit_GL_KTX_buffer_region(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_KTX_buffer_region */ +#ifdef GL_MESAX_texture_stack + GLEW_MESAX_texture_stack = glewGetExtension("GL_MESAX_texture_stack"); +#endif /* GL_MESAX_texture_stack */ +#ifdef GL_MESA_pack_invert + GLEW_MESA_pack_invert = glewGetExtension("GL_MESA_pack_invert"); +#endif /* GL_MESA_pack_invert */ +#ifdef GL_MESA_resize_buffers + GLEW_MESA_resize_buffers = glewGetExtension("GL_MESA_resize_buffers"); + if (glewExperimental || GLEW_MESA_resize_buffers) GLEW_MESA_resize_buffers = !_glewInit_GL_MESA_resize_buffers(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_MESA_resize_buffers */ +#ifdef GL_MESA_window_pos + GLEW_MESA_window_pos = glewGetExtension("GL_MESA_window_pos"); + if (glewExperimental || GLEW_MESA_window_pos) GLEW_MESA_window_pos = !_glewInit_GL_MESA_window_pos(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_MESA_window_pos */ +#ifdef GL_MESA_ycbcr_texture + GLEW_MESA_ycbcr_texture = glewGetExtension("GL_MESA_ycbcr_texture"); +#endif /* GL_MESA_ycbcr_texture */ +#ifdef GL_NV_blend_square + GLEW_NV_blend_square = glewGetExtension("GL_NV_blend_square"); +#endif /* GL_NV_blend_square */ +#ifdef GL_NV_copy_depth_to_color + GLEW_NV_copy_depth_to_color = glewGetExtension("GL_NV_copy_depth_to_color"); +#endif /* GL_NV_copy_depth_to_color */ +#ifdef GL_NV_depth_clamp + GLEW_NV_depth_clamp = glewGetExtension("GL_NV_depth_clamp"); +#endif /* GL_NV_depth_clamp */ +#ifdef GL_NV_evaluators + GLEW_NV_evaluators = glewGetExtension("GL_NV_evaluators"); + if (glewExperimental || GLEW_NV_evaluators) GLEW_NV_evaluators = !_glewInit_GL_NV_evaluators(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_NV_evaluators */ +#ifdef GL_NV_fence + GLEW_NV_fence = glewGetExtension("GL_NV_fence"); + if (glewExperimental || GLEW_NV_fence) GLEW_NV_fence = !_glewInit_GL_NV_fence(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_NV_fence */ +#ifdef GL_NV_float_buffer + GLEW_NV_float_buffer = glewGetExtension("GL_NV_float_buffer"); +#endif /* GL_NV_float_buffer */ +#ifdef GL_NV_fog_distance + GLEW_NV_fog_distance = glewGetExtension("GL_NV_fog_distance"); +#endif /* GL_NV_fog_distance */ +#ifdef GL_NV_fragment_program + GLEW_NV_fragment_program = glewGetExtension("GL_NV_fragment_program"); + if (glewExperimental || GLEW_NV_fragment_program) GLEW_NV_fragment_program = !_glewInit_GL_NV_fragment_program(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_NV_fragment_program */ +#ifdef GL_NV_fragment_program2 + GLEW_NV_fragment_program2 = glewGetExtension("GL_NV_fragment_program2"); +#endif /* GL_NV_fragment_program2 */ +#ifdef GL_NV_fragment_program_option + GLEW_NV_fragment_program_option = glewGetExtension("GL_NV_fragment_program_option"); +#endif /* GL_NV_fragment_program_option */ +#ifdef GL_NV_half_float + GLEW_NV_half_float = glewGetExtension("GL_NV_half_float"); + if (glewExperimental || GLEW_NV_half_float) GLEW_NV_half_float = !_glewInit_GL_NV_half_float(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_NV_half_float */ +#ifdef GL_NV_light_max_exponent + GLEW_NV_light_max_exponent = glewGetExtension("GL_NV_light_max_exponent"); +#endif /* GL_NV_light_max_exponent */ +#ifdef GL_NV_multisample_filter_hint + GLEW_NV_multisample_filter_hint = glewGetExtension("GL_NV_multisample_filter_hint"); +#endif /* GL_NV_multisample_filter_hint */ +#ifdef GL_NV_occlusion_query + GLEW_NV_occlusion_query = glewGetExtension("GL_NV_occlusion_query"); + if (glewExperimental || GLEW_NV_occlusion_query) GLEW_NV_occlusion_query = !_glewInit_GL_NV_occlusion_query(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_NV_occlusion_query */ +#ifdef GL_NV_packed_depth_stencil + GLEW_NV_packed_depth_stencil = glewGetExtension("GL_NV_packed_depth_stencil"); +#endif /* GL_NV_packed_depth_stencil */ +#ifdef GL_NV_pixel_data_range + GLEW_NV_pixel_data_range = glewGetExtension("GL_NV_pixel_data_range"); + if (glewExperimental || GLEW_NV_pixel_data_range) GLEW_NV_pixel_data_range = !_glewInit_GL_NV_pixel_data_range(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_NV_pixel_data_range */ +#ifdef GL_NV_point_sprite + GLEW_NV_point_sprite = glewGetExtension("GL_NV_point_sprite"); + if (glewExperimental || GLEW_NV_point_sprite) GLEW_NV_point_sprite = !_glewInit_GL_NV_point_sprite(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_NV_point_sprite */ +#ifdef GL_NV_primitive_restart + GLEW_NV_primitive_restart = glewGetExtension("GL_NV_primitive_restart"); + if (glewExperimental || GLEW_NV_primitive_restart) GLEW_NV_primitive_restart = !_glewInit_GL_NV_primitive_restart(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_NV_primitive_restart */ +#ifdef GL_NV_register_combiners + GLEW_NV_register_combiners = glewGetExtension("GL_NV_register_combiners"); + if (glewExperimental || GLEW_NV_register_combiners) GLEW_NV_register_combiners = !_glewInit_GL_NV_register_combiners(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_NV_register_combiners */ +#ifdef GL_NV_register_combiners2 + GLEW_NV_register_combiners2 = glewGetExtension("GL_NV_register_combiners2"); + if (glewExperimental || GLEW_NV_register_combiners2) GLEW_NV_register_combiners2 = !_glewInit_GL_NV_register_combiners2(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_NV_register_combiners2 */ +#ifdef GL_NV_texgen_emboss + GLEW_NV_texgen_emboss = glewGetExtension("GL_NV_texgen_emboss"); +#endif /* GL_NV_texgen_emboss */ +#ifdef GL_NV_texgen_reflection + GLEW_NV_texgen_reflection = glewGetExtension("GL_NV_texgen_reflection"); +#endif /* GL_NV_texgen_reflection */ +#ifdef GL_NV_texture_compression_vtc + GLEW_NV_texture_compression_vtc = glewGetExtension("GL_NV_texture_compression_vtc"); +#endif /* GL_NV_texture_compression_vtc */ +#ifdef GL_NV_texture_env_combine4 + GLEW_NV_texture_env_combine4 = glewGetExtension("GL_NV_texture_env_combine4"); +#endif /* GL_NV_texture_env_combine4 */ +#ifdef GL_NV_texture_expand_normal + GLEW_NV_texture_expand_normal = glewGetExtension("GL_NV_texture_expand_normal"); +#endif /* GL_NV_texture_expand_normal */ +#ifdef GL_NV_texture_rectangle + GLEW_NV_texture_rectangle = glewGetExtension("GL_NV_texture_rectangle"); +#endif /* GL_NV_texture_rectangle */ +#ifdef GL_NV_texture_shader + GLEW_NV_texture_shader = glewGetExtension("GL_NV_texture_shader"); +#endif /* GL_NV_texture_shader */ +#ifdef GL_NV_texture_shader2 + GLEW_NV_texture_shader2 = glewGetExtension("GL_NV_texture_shader2"); +#endif /* GL_NV_texture_shader2 */ +#ifdef GL_NV_texture_shader3 + GLEW_NV_texture_shader3 = glewGetExtension("GL_NV_texture_shader3"); +#endif /* GL_NV_texture_shader3 */ +#ifdef GL_NV_vertex_array_range + GLEW_NV_vertex_array_range = glewGetExtension("GL_NV_vertex_array_range"); + if (glewExperimental || GLEW_NV_vertex_array_range) GLEW_NV_vertex_array_range = !_glewInit_GL_NV_vertex_array_range(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_NV_vertex_array_range */ +#ifdef GL_NV_vertex_array_range2 + GLEW_NV_vertex_array_range2 = glewGetExtension("GL_NV_vertex_array_range2"); +#endif /* GL_NV_vertex_array_range2 */ +#ifdef GL_NV_vertex_program + GLEW_NV_vertex_program = glewGetExtension("GL_NV_vertex_program"); + if (glewExperimental || GLEW_NV_vertex_program) GLEW_NV_vertex_program = !_glewInit_GL_NV_vertex_program(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_NV_vertex_program */ +#ifdef GL_NV_vertex_program1_1 + GLEW_NV_vertex_program1_1 = glewGetExtension("GL_NV_vertex_program1_1"); +#endif /* GL_NV_vertex_program1_1 */ +#ifdef GL_NV_vertex_program2 + GLEW_NV_vertex_program2 = glewGetExtension("GL_NV_vertex_program2"); +#endif /* GL_NV_vertex_program2 */ +#ifdef GL_NV_vertex_program2_option + GLEW_NV_vertex_program2_option = glewGetExtension("GL_NV_vertex_program2_option"); +#endif /* GL_NV_vertex_program2_option */ +#ifdef GL_NV_vertex_program3 + GLEW_NV_vertex_program3 = glewGetExtension("GL_NV_vertex_program3"); +#endif /* GL_NV_vertex_program3 */ +#ifdef GL_OML_interlace + GLEW_OML_interlace = glewGetExtension("GL_OML_interlace"); +#endif /* GL_OML_interlace */ +#ifdef GL_OML_resample + GLEW_OML_resample = glewGetExtension("GL_OML_resample"); +#endif /* GL_OML_resample */ +#ifdef GL_OML_subsample + GLEW_OML_subsample = glewGetExtension("GL_OML_subsample"); +#endif /* GL_OML_subsample */ +#ifdef GL_PGI_misc_hints + GLEW_PGI_misc_hints = glewGetExtension("GL_PGI_misc_hints"); +#endif /* GL_PGI_misc_hints */ +#ifdef GL_PGI_vertex_hints + GLEW_PGI_vertex_hints = glewGetExtension("GL_PGI_vertex_hints"); +#endif /* GL_PGI_vertex_hints */ +#ifdef GL_REND_screen_coordinates + GLEW_REND_screen_coordinates = glewGetExtension("GL_REND_screen_coordinates"); +#endif /* GL_REND_screen_coordinates */ +#ifdef GL_S3_s3tc + GLEW_S3_s3tc = glewGetExtension("GL_S3_s3tc"); +#endif /* GL_S3_s3tc */ +#ifdef GL_SGIS_color_range + GLEW_SGIS_color_range = glewGetExtension("GL_SGIS_color_range"); +#endif /* GL_SGIS_color_range */ +#ifdef GL_SGIS_detail_texture + GLEW_SGIS_detail_texture = glewGetExtension("GL_SGIS_detail_texture"); + if (glewExperimental || GLEW_SGIS_detail_texture) GLEW_SGIS_detail_texture = !_glewInit_GL_SGIS_detail_texture(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_SGIS_detail_texture */ +#ifdef GL_SGIS_fog_function + GLEW_SGIS_fog_function = glewGetExtension("GL_SGIS_fog_function"); + if (glewExperimental || GLEW_SGIS_fog_function) GLEW_SGIS_fog_function = !_glewInit_GL_SGIS_fog_function(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_SGIS_fog_function */ +#ifdef GL_SGIS_generate_mipmap + GLEW_SGIS_generate_mipmap = glewGetExtension("GL_SGIS_generate_mipmap"); +#endif /* GL_SGIS_generate_mipmap */ +#ifdef GL_SGIS_multisample + GLEW_SGIS_multisample = glewGetExtension("GL_SGIS_multisample"); + if (glewExperimental || GLEW_SGIS_multisample) GLEW_SGIS_multisample = !_glewInit_GL_SGIS_multisample(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_SGIS_multisample */ +#ifdef GL_SGIS_pixel_texture + GLEW_SGIS_pixel_texture = glewGetExtension("GL_SGIS_pixel_texture"); +#endif /* GL_SGIS_pixel_texture */ +#ifdef GL_SGIS_sharpen_texture + GLEW_SGIS_sharpen_texture = glewGetExtension("GL_SGIS_sharpen_texture"); + if (glewExperimental || GLEW_SGIS_sharpen_texture) GLEW_SGIS_sharpen_texture = !_glewInit_GL_SGIS_sharpen_texture(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_SGIS_sharpen_texture */ +#ifdef GL_SGIS_texture4D + GLEW_SGIS_texture4D = glewGetExtension("GL_SGIS_texture4D"); + if (glewExperimental || GLEW_SGIS_texture4D) GLEW_SGIS_texture4D = !_glewInit_GL_SGIS_texture4D(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_SGIS_texture4D */ +#ifdef GL_SGIS_texture_border_clamp + GLEW_SGIS_texture_border_clamp = glewGetExtension("GL_SGIS_texture_border_clamp"); +#endif /* GL_SGIS_texture_border_clamp */ +#ifdef GL_SGIS_texture_edge_clamp + GLEW_SGIS_texture_edge_clamp = glewGetExtension("GL_SGIS_texture_edge_clamp"); +#endif /* GL_SGIS_texture_edge_clamp */ +#ifdef GL_SGIS_texture_filter4 + GLEW_SGIS_texture_filter4 = glewGetExtension("GL_SGIS_texture_filter4"); + if (glewExperimental || GLEW_SGIS_texture_filter4) GLEW_SGIS_texture_filter4 = !_glewInit_GL_SGIS_texture_filter4(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_SGIS_texture_filter4 */ +#ifdef GL_SGIS_texture_lod + GLEW_SGIS_texture_lod = glewGetExtension("GL_SGIS_texture_lod"); +#endif /* GL_SGIS_texture_lod */ +#ifdef GL_SGIS_texture_select + GLEW_SGIS_texture_select = glewGetExtension("GL_SGIS_texture_select"); +#endif /* GL_SGIS_texture_select */ +#ifdef GL_SGIX_async + GLEW_SGIX_async = glewGetExtension("GL_SGIX_async"); + if (glewExperimental || GLEW_SGIX_async) GLEW_SGIX_async = !_glewInit_GL_SGIX_async(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_SGIX_async */ +#ifdef GL_SGIX_async_histogram + GLEW_SGIX_async_histogram = glewGetExtension("GL_SGIX_async_histogram"); +#endif /* GL_SGIX_async_histogram */ +#ifdef GL_SGIX_async_pixel + GLEW_SGIX_async_pixel = glewGetExtension("GL_SGIX_async_pixel"); +#endif /* GL_SGIX_async_pixel */ +#ifdef GL_SGIX_blend_alpha_minmax + GLEW_SGIX_blend_alpha_minmax = glewGetExtension("GL_SGIX_blend_alpha_minmax"); +#endif /* GL_SGIX_blend_alpha_minmax */ +#ifdef GL_SGIX_clipmap + GLEW_SGIX_clipmap = glewGetExtension("GL_SGIX_clipmap"); +#endif /* GL_SGIX_clipmap */ +#ifdef GL_SGIX_depth_texture + GLEW_SGIX_depth_texture = glewGetExtension("GL_SGIX_depth_texture"); +#endif /* GL_SGIX_depth_texture */ +#ifdef GL_SGIX_flush_raster + GLEW_SGIX_flush_raster = glewGetExtension("GL_SGIX_flush_raster"); + if (glewExperimental || GLEW_SGIX_flush_raster) GLEW_SGIX_flush_raster = !_glewInit_GL_SGIX_flush_raster(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_SGIX_flush_raster */ +#ifdef GL_SGIX_fog_offset + GLEW_SGIX_fog_offset = glewGetExtension("GL_SGIX_fog_offset"); +#endif /* GL_SGIX_fog_offset */ +#ifdef GL_SGIX_fog_texture + GLEW_SGIX_fog_texture = glewGetExtension("GL_SGIX_fog_texture"); + if (glewExperimental || GLEW_SGIX_fog_texture) GLEW_SGIX_fog_texture = !_glewInit_GL_SGIX_fog_texture(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_SGIX_fog_texture */ +#ifdef GL_SGIX_fragment_specular_lighting + GLEW_SGIX_fragment_specular_lighting = glewGetExtension("GL_SGIX_fragment_specular_lighting"); + if (glewExperimental || GLEW_SGIX_fragment_specular_lighting) GLEW_SGIX_fragment_specular_lighting = !_glewInit_GL_SGIX_fragment_specular_lighting(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_SGIX_fragment_specular_lighting */ +#ifdef GL_SGIX_framezoom + GLEW_SGIX_framezoom = glewGetExtension("GL_SGIX_framezoom"); + if (glewExperimental || GLEW_SGIX_framezoom) GLEW_SGIX_framezoom = !_glewInit_GL_SGIX_framezoom(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_SGIX_framezoom */ +#ifdef GL_SGIX_interlace + GLEW_SGIX_interlace = glewGetExtension("GL_SGIX_interlace"); +#endif /* GL_SGIX_interlace */ +#ifdef GL_SGIX_ir_instrument1 + GLEW_SGIX_ir_instrument1 = glewGetExtension("GL_SGIX_ir_instrument1"); +#endif /* GL_SGIX_ir_instrument1 */ +#ifdef GL_SGIX_list_priority + GLEW_SGIX_list_priority = glewGetExtension("GL_SGIX_list_priority"); +#endif /* GL_SGIX_list_priority */ +#ifdef GL_SGIX_pixel_texture + GLEW_SGIX_pixel_texture = glewGetExtension("GL_SGIX_pixel_texture"); + if (glewExperimental || GLEW_SGIX_pixel_texture) GLEW_SGIX_pixel_texture = !_glewInit_GL_SGIX_pixel_texture(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_SGIX_pixel_texture */ +#ifdef GL_SGIX_pixel_texture_bits + GLEW_SGIX_pixel_texture_bits = glewGetExtension("GL_SGIX_pixel_texture_bits"); +#endif /* GL_SGIX_pixel_texture_bits */ +#ifdef GL_SGIX_reference_plane + GLEW_SGIX_reference_plane = glewGetExtension("GL_SGIX_reference_plane"); + if (glewExperimental || GLEW_SGIX_reference_plane) GLEW_SGIX_reference_plane = !_glewInit_GL_SGIX_reference_plane(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_SGIX_reference_plane */ +#ifdef GL_SGIX_resample + GLEW_SGIX_resample = glewGetExtension("GL_SGIX_resample"); +#endif /* GL_SGIX_resample */ +#ifdef GL_SGIX_shadow + GLEW_SGIX_shadow = glewGetExtension("GL_SGIX_shadow"); +#endif /* GL_SGIX_shadow */ +#ifdef GL_SGIX_shadow_ambient + GLEW_SGIX_shadow_ambient = glewGetExtension("GL_SGIX_shadow_ambient"); +#endif /* GL_SGIX_shadow_ambient */ +#ifdef GL_SGIX_sprite + GLEW_SGIX_sprite = glewGetExtension("GL_SGIX_sprite"); + if (glewExperimental || GLEW_SGIX_sprite) GLEW_SGIX_sprite = !_glewInit_GL_SGIX_sprite(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_SGIX_sprite */ +#ifdef GL_SGIX_tag_sample_buffer + GLEW_SGIX_tag_sample_buffer = glewGetExtension("GL_SGIX_tag_sample_buffer"); + if (glewExperimental || GLEW_SGIX_tag_sample_buffer) GLEW_SGIX_tag_sample_buffer = !_glewInit_GL_SGIX_tag_sample_buffer(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_SGIX_tag_sample_buffer */ +#ifdef GL_SGIX_texture_add_env + GLEW_SGIX_texture_add_env = glewGetExtension("GL_SGIX_texture_add_env"); +#endif /* GL_SGIX_texture_add_env */ +#ifdef GL_SGIX_texture_coordinate_clamp + GLEW_SGIX_texture_coordinate_clamp = glewGetExtension("GL_SGIX_texture_coordinate_clamp"); +#endif /* GL_SGIX_texture_coordinate_clamp */ +#ifdef GL_SGIX_texture_lod_bias + GLEW_SGIX_texture_lod_bias = glewGetExtension("GL_SGIX_texture_lod_bias"); +#endif /* GL_SGIX_texture_lod_bias */ +#ifdef GL_SGIX_texture_multi_buffer + GLEW_SGIX_texture_multi_buffer = glewGetExtension("GL_SGIX_texture_multi_buffer"); +#endif /* GL_SGIX_texture_multi_buffer */ +#ifdef GL_SGIX_texture_range + GLEW_SGIX_texture_range = glewGetExtension("GL_SGIX_texture_range"); +#endif /* GL_SGIX_texture_range */ +#ifdef GL_SGIX_texture_scale_bias + GLEW_SGIX_texture_scale_bias = glewGetExtension("GL_SGIX_texture_scale_bias"); +#endif /* GL_SGIX_texture_scale_bias */ +#ifdef GL_SGIX_vertex_preclip + GLEW_SGIX_vertex_preclip = glewGetExtension("GL_SGIX_vertex_preclip"); +#endif /* GL_SGIX_vertex_preclip */ +#ifdef GL_SGIX_vertex_preclip_hint + GLEW_SGIX_vertex_preclip_hint = glewGetExtension("GL_SGIX_vertex_preclip_hint"); +#endif /* GL_SGIX_vertex_preclip_hint */ +#ifdef GL_SGIX_ycrcb + GLEW_SGIX_ycrcb = glewGetExtension("GL_SGIX_ycrcb"); +#endif /* GL_SGIX_ycrcb */ +#ifdef GL_SGI_color_matrix + GLEW_SGI_color_matrix = glewGetExtension("GL_SGI_color_matrix"); +#endif /* GL_SGI_color_matrix */ +#ifdef GL_SGI_color_table + GLEW_SGI_color_table = glewGetExtension("GL_SGI_color_table"); + if (glewExperimental || GLEW_SGI_color_table) GLEW_SGI_color_table = !_glewInit_GL_SGI_color_table(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_SGI_color_table */ +#ifdef GL_SGI_texture_color_table + GLEW_SGI_texture_color_table = glewGetExtension("GL_SGI_texture_color_table"); +#endif /* GL_SGI_texture_color_table */ +#ifdef GL_SUNX_constant_data + GLEW_SUNX_constant_data = glewGetExtension("GL_SUNX_constant_data"); + if (glewExperimental || GLEW_SUNX_constant_data) GLEW_SUNX_constant_data = !_glewInit_GL_SUNX_constant_data(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_SUNX_constant_data */ +#ifdef GL_SUN_convolution_border_modes + GLEW_SUN_convolution_border_modes = glewGetExtension("GL_SUN_convolution_border_modes"); +#endif /* GL_SUN_convolution_border_modes */ +#ifdef GL_SUN_global_alpha + GLEW_SUN_global_alpha = glewGetExtension("GL_SUN_global_alpha"); + if (glewExperimental || GLEW_SUN_global_alpha) GLEW_SUN_global_alpha = !_glewInit_GL_SUN_global_alpha(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_SUN_global_alpha */ +#ifdef GL_SUN_mesh_array + GLEW_SUN_mesh_array = glewGetExtension("GL_SUN_mesh_array"); +#endif /* GL_SUN_mesh_array */ +#ifdef GL_SUN_read_video_pixels + GLEW_SUN_read_video_pixels = glewGetExtension("GL_SUN_read_video_pixels"); + if (glewExperimental || GLEW_SUN_read_video_pixels) GLEW_SUN_read_video_pixels = !_glewInit_GL_SUN_read_video_pixels(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_SUN_read_video_pixels */ +#ifdef GL_SUN_slice_accum + GLEW_SUN_slice_accum = glewGetExtension("GL_SUN_slice_accum"); +#endif /* GL_SUN_slice_accum */ +#ifdef GL_SUN_triangle_list + GLEW_SUN_triangle_list = glewGetExtension("GL_SUN_triangle_list"); + if (glewExperimental || GLEW_SUN_triangle_list) GLEW_SUN_triangle_list = !_glewInit_GL_SUN_triangle_list(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_SUN_triangle_list */ +#ifdef GL_SUN_vertex + GLEW_SUN_vertex = glewGetExtension("GL_SUN_vertex"); + if (glewExperimental || GLEW_SUN_vertex) GLEW_SUN_vertex = !_glewInit_GL_SUN_vertex(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_SUN_vertex */ +#ifdef GL_WIN_phong_shading + GLEW_WIN_phong_shading = glewGetExtension("GL_WIN_phong_shading"); +#endif /* GL_WIN_phong_shading */ +#ifdef GL_WIN_specular_fog + GLEW_WIN_specular_fog = glewGetExtension("GL_WIN_specular_fog"); +#endif /* GL_WIN_specular_fog */ +#ifdef GL_WIN_swap_hint + GLEW_WIN_swap_hint = glewGetExtension("GL_WIN_swap_hint"); + if (glewExperimental || GLEW_WIN_swap_hint) GLEW_WIN_swap_hint = !_glewInit_GL_WIN_swap_hint(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_WIN_swap_hint */ + + return GLEW_OK; +} + + +#if defined(_WIN32) + +#if !defined(GLEW_MX) + +PFNWGLSETSTEREOEMITTERSTATE3DLPROC __wglewSetStereoEmitterState3DL = NULL; + +PFNWGLCREATEBUFFERREGIONARBPROC __wglewCreateBufferRegionARB = NULL; +PFNWGLDELETEBUFFERREGIONARBPROC __wglewDeleteBufferRegionARB = NULL; +PFNWGLRESTOREBUFFERREGIONARBPROC __wglewRestoreBufferRegionARB = NULL; +PFNWGLSAVEBUFFERREGIONARBPROC __wglewSaveBufferRegionARB = NULL; + +PFNWGLGETEXTENSIONSSTRINGARBPROC __wglewGetExtensionsStringARB = NULL; + +PFNWGLGETCURRENTREADDCARBPROC __wglewGetCurrentReadDCARB = NULL; +PFNWGLMAKECONTEXTCURRENTARBPROC __wglewMakeContextCurrentARB = NULL; + +PFNWGLCREATEPBUFFERARBPROC __wglewCreatePbufferARB = NULL; +PFNWGLDESTROYPBUFFERARBPROC __wglewDestroyPbufferARB = NULL; +PFNWGLGETPBUFFERDCARBPROC __wglewGetPbufferDCARB = NULL; +PFNWGLQUERYPBUFFERARBPROC __wglewQueryPbufferARB = NULL; +PFNWGLRELEASEPBUFFERDCARBPROC __wglewReleasePbufferDCARB = NULL; + +PFNWGLCHOOSEPIXELFORMATARBPROC __wglewChoosePixelFormatARB = NULL; +PFNWGLGETPIXELFORMATATTRIBFVARBPROC __wglewGetPixelFormatAttribfvARB = NULL; +PFNWGLGETPIXELFORMATATTRIBIVARBPROC __wglewGetPixelFormatAttribivARB = NULL; + +PFNWGLBINDTEXIMAGEARBPROC __wglewBindTexImageARB = NULL; +PFNWGLRELEASETEXIMAGEARBPROC __wglewReleaseTexImageARB = NULL; +PFNWGLSETPBUFFERATTRIBARBPROC __wglewSetPbufferAttribARB = NULL; + +PFNWGLBINDDISPLAYCOLORTABLEEXTPROC __wglewBindDisplayColorTableEXT = NULL; +PFNWGLCREATEDISPLAYCOLORTABLEEXTPROC __wglewCreateDisplayColorTableEXT = NULL; +PFNWGLDESTROYDISPLAYCOLORTABLEEXTPROC __wglewDestroyDisplayColorTableEXT = NULL; +PFNWGLLOADDISPLAYCOLORTABLEEXTPROC __wglewLoadDisplayColorTableEXT = NULL; + +PFNWGLGETEXTENSIONSSTRINGEXTPROC __wglewGetExtensionsStringEXT = NULL; + +PFNWGLGETCURRENTREADDCEXTPROC __wglewGetCurrentReadDCEXT = NULL; +PFNWGLMAKECONTEXTCURRENTEXTPROC __wglewMakeContextCurrentEXT = NULL; + +PFNWGLCREATEPBUFFEREXTPROC __wglewCreatePbufferEXT = NULL; +PFNWGLDESTROYPBUFFEREXTPROC __wglewDestroyPbufferEXT = NULL; +PFNWGLGETPBUFFERDCEXTPROC __wglewGetPbufferDCEXT = NULL; +PFNWGLQUERYPBUFFEREXTPROC __wglewQueryPbufferEXT = NULL; +PFNWGLRELEASEPBUFFERDCEXTPROC __wglewReleasePbufferDCEXT = NULL; + +PFNWGLCHOOSEPIXELFORMATEXTPROC __wglewChoosePixelFormatEXT = NULL; +PFNWGLGETPIXELFORMATATTRIBFVEXTPROC __wglewGetPixelFormatAttribfvEXT = NULL; +PFNWGLGETPIXELFORMATATTRIBIVEXTPROC __wglewGetPixelFormatAttribivEXT = NULL; + +PFNWGLGETSWAPINTERVALEXTPROC __wglewGetSwapIntervalEXT = NULL; +PFNWGLSWAPINTERVALEXTPROC __wglewSwapIntervalEXT = NULL; + +PFNWGLGETDIGITALVIDEOPARAMETERSI3DPROC __wglewGetDigitalVideoParametersI3D = NULL; +PFNWGLSETDIGITALVIDEOPARAMETERSI3DPROC __wglewSetDigitalVideoParametersI3D = NULL; + +PFNWGLGETGAMMATABLEI3DPROC __wglewGetGammaTableI3D = NULL; +PFNWGLGETGAMMATABLEPARAMETERSI3DPROC __wglewGetGammaTableParametersI3D = NULL; +PFNWGLSETGAMMATABLEI3DPROC __wglewSetGammaTableI3D = NULL; +PFNWGLSETGAMMATABLEPARAMETERSI3DPROC __wglewSetGammaTableParametersI3D = NULL; + +PFNWGLDISABLEGENLOCKI3DPROC __wglewDisableGenlockI3D = NULL; +PFNWGLENABLEGENLOCKI3DPROC __wglewEnableGenlockI3D = NULL; +PFNWGLGENLOCKSAMPLERATEI3DPROC __wglewGenlockSampleRateI3D = NULL; +PFNWGLGENLOCKSOURCEDELAYI3DPROC __wglewGenlockSourceDelayI3D = NULL; +PFNWGLGENLOCKSOURCEEDGEI3DPROC __wglewGenlockSourceEdgeI3D = NULL; +PFNWGLGENLOCKSOURCEI3DPROC __wglewGenlockSourceI3D = NULL; +PFNWGLGETGENLOCKSAMPLERATEI3DPROC __wglewGetGenlockSampleRateI3D = NULL; +PFNWGLGETGENLOCKSOURCEDELAYI3DPROC __wglewGetGenlockSourceDelayI3D = NULL; +PFNWGLGETGENLOCKSOURCEEDGEI3DPROC __wglewGetGenlockSourceEdgeI3D = NULL; +PFNWGLGETGENLOCKSOURCEI3DPROC __wglewGetGenlockSourceI3D = NULL; +PFNWGLISENABLEDGENLOCKI3DPROC __wglewIsEnabledGenlockI3D = NULL; +PFNWGLQUERYGENLOCKMAXSOURCEDELAYI3DPROC __wglewQueryGenlockMaxSourceDelayI3D = NULL; + +PFNWGLASSOCIATEIMAGEBUFFEREVENTSI3DPROC __wglewAssociateImageBufferEventsI3D = NULL; +PFNWGLCREATEIMAGEBUFFERI3DPROC __wglewCreateImageBufferI3D = NULL; +PFNWGLDESTROYIMAGEBUFFERI3DPROC __wglewDestroyImageBufferI3D = NULL; +PFNWGLRELEASEIMAGEBUFFEREVENTSI3DPROC __wglewReleaseImageBufferEventsI3D = NULL; + +PFNWGLDISABLEFRAMELOCKI3DPROC __wglewDisableFrameLockI3D = NULL; +PFNWGLENABLEFRAMELOCKI3DPROC __wglewEnableFrameLockI3D = NULL; +PFNWGLISENABLEDFRAMELOCKI3DPROC __wglewIsEnabledFrameLockI3D = NULL; +PFNWGLQUERYFRAMELOCKMASTERI3DPROC __wglewQueryFrameLockMasterI3D = NULL; + +PFNWGLBEGINFRAMETRACKINGI3DPROC __wglewBeginFrameTrackingI3D = NULL; +PFNWGLENDFRAMETRACKINGI3DPROC __wglewEndFrameTrackingI3D = NULL; +PFNWGLGETFRAMEUSAGEI3DPROC __wglewGetFrameUsageI3D = NULL; +PFNWGLQUERYFRAMETRACKINGI3DPROC __wglewQueryFrameTrackingI3D = NULL; + +PFNWGLALLOCATEMEMORYNVPROC __wglewAllocateMemoryNV = NULL; +PFNWGLFREEMEMORYNVPROC __wglewFreeMemoryNV = NULL; + +PFNWGLGETMSCRATEOMLPROC __wglewGetMscRateOML = NULL; +PFNWGLGETSYNCVALUESOMLPROC __wglewGetSyncValuesOML = NULL; +PFNWGLSWAPBUFFERSMSCOMLPROC __wglewSwapBuffersMscOML = NULL; +PFNWGLSWAPLAYERBUFFERSMSCOMLPROC __wglewSwapLayerBuffersMscOML = NULL; +PFNWGLWAITFORMSCOMLPROC __wglewWaitForMscOML = NULL; +PFNWGLWAITFORSBCOMLPROC __wglewWaitForSbcOML = NULL; +GLboolean __WGLEW_3DFX_multisample = GL_FALSE; +GLboolean __WGLEW_3DL_stereo_control = GL_FALSE; +GLboolean __WGLEW_ARB_buffer_region = GL_FALSE; +GLboolean __WGLEW_ARB_extensions_string = GL_FALSE; +GLboolean __WGLEW_ARB_make_current_read = GL_FALSE; +GLboolean __WGLEW_ARB_multisample = GL_FALSE; +GLboolean __WGLEW_ARB_pbuffer = GL_FALSE; +GLboolean __WGLEW_ARB_pixel_format = GL_FALSE; +GLboolean __WGLEW_ARB_pixel_format_float = GL_FALSE; +GLboolean __WGLEW_ARB_render_texture = GL_FALSE; +GLboolean __WGLEW_ATI_pixel_format_float = GL_FALSE; +GLboolean __WGLEW_ATI_render_texture_rectangle = GL_FALSE; +GLboolean __WGLEW_EXT_depth_float = GL_FALSE; +GLboolean __WGLEW_EXT_display_color_table = GL_FALSE; +GLboolean __WGLEW_EXT_extensions_string = GL_FALSE; +GLboolean __WGLEW_EXT_make_current_read = GL_FALSE; +GLboolean __WGLEW_EXT_multisample = GL_FALSE; +GLboolean __WGLEW_EXT_pbuffer = GL_FALSE; +GLboolean __WGLEW_EXT_pixel_format = GL_FALSE; +GLboolean __WGLEW_EXT_swap_control = GL_FALSE; +GLboolean __WGLEW_I3D_digital_video_control = GL_FALSE; +GLboolean __WGLEW_I3D_gamma = GL_FALSE; +GLboolean __WGLEW_I3D_genlock = GL_FALSE; +GLboolean __WGLEW_I3D_image_buffer = GL_FALSE; +GLboolean __WGLEW_I3D_swap_frame_lock = GL_FALSE; +GLboolean __WGLEW_I3D_swap_frame_usage = GL_FALSE; +GLboolean __WGLEW_NV_float_buffer = GL_FALSE; +GLboolean __WGLEW_NV_render_depth_texture = GL_FALSE; +GLboolean __WGLEW_NV_render_texture_rectangle = GL_FALSE; +GLboolean __WGLEW_NV_vertex_array_range = GL_FALSE; +GLboolean __WGLEW_OML_sync_control = GL_FALSE; + +#endif /* !GLEW_MX */ + +#ifdef WGL_3DFX_multisample + +#endif /* WGL_3DFX_multisample */ + +#ifdef WGL_3DL_stereo_control + +static GLboolean _glewInit_WGL_3DL_stereo_control (WGLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((wglSetStereoEmitterState3DL = (PFNWGLSETSTEREOEMITTERSTATE3DLPROC)glewGetProcAddress((const GLubyte*)"wglSetStereoEmitterState3DL")) == NULL) || r; + + return r; +} + +#endif /* WGL_3DL_stereo_control */ + +#ifdef WGL_ARB_buffer_region + +static GLboolean _glewInit_WGL_ARB_buffer_region (WGLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((wglCreateBufferRegionARB = (PFNWGLCREATEBUFFERREGIONARBPROC)glewGetProcAddress((const GLubyte*)"wglCreateBufferRegionARB")) == NULL) || r; + r = ((wglDeleteBufferRegionARB = (PFNWGLDELETEBUFFERREGIONARBPROC)glewGetProcAddress((const GLubyte*)"wglDeleteBufferRegionARB")) == NULL) || r; + r = ((wglRestoreBufferRegionARB = (PFNWGLRESTOREBUFFERREGIONARBPROC)glewGetProcAddress((const GLubyte*)"wglRestoreBufferRegionARB")) == NULL) || r; + r = ((wglSaveBufferRegionARB = (PFNWGLSAVEBUFFERREGIONARBPROC)glewGetProcAddress((const GLubyte*)"wglSaveBufferRegionARB")) == NULL) || r; + + return r; +} + +#endif /* WGL_ARB_buffer_region */ + +#ifdef WGL_ARB_extensions_string + +static GLboolean _glewInit_WGL_ARB_extensions_string (WGLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((wglGetExtensionsStringARB = (PFNWGLGETEXTENSIONSSTRINGARBPROC)glewGetProcAddress((const GLubyte*)"wglGetExtensionsStringARB")) == NULL) || r; + + return r; +} + +#endif /* WGL_ARB_extensions_string */ + +#ifdef WGL_ARB_make_current_read + +static GLboolean _glewInit_WGL_ARB_make_current_read (WGLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((wglGetCurrentReadDCARB = (PFNWGLGETCURRENTREADDCARBPROC)glewGetProcAddress((const GLubyte*)"wglGetCurrentReadDCARB")) == NULL) || r; + r = ((wglMakeContextCurrentARB = (PFNWGLMAKECONTEXTCURRENTARBPROC)glewGetProcAddress((const GLubyte*)"wglMakeContextCurrentARB")) == NULL) || r; + + return r; +} + +#endif /* WGL_ARB_make_current_read */ + +#ifdef WGL_ARB_multisample + +#endif /* WGL_ARB_multisample */ + +#ifdef WGL_ARB_pbuffer + +static GLboolean _glewInit_WGL_ARB_pbuffer (WGLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((wglCreatePbufferARB = (PFNWGLCREATEPBUFFERARBPROC)glewGetProcAddress((const GLubyte*)"wglCreatePbufferARB")) == NULL) || r; + r = ((wglDestroyPbufferARB = (PFNWGLDESTROYPBUFFERARBPROC)glewGetProcAddress((const GLubyte*)"wglDestroyPbufferARB")) == NULL) || r; + r = ((wglGetPbufferDCARB = (PFNWGLGETPBUFFERDCARBPROC)glewGetProcAddress((const GLubyte*)"wglGetPbufferDCARB")) == NULL) || r; + r = ((wglQueryPbufferARB = (PFNWGLQUERYPBUFFERARBPROC)glewGetProcAddress((const GLubyte*)"wglQueryPbufferARB")) == NULL) || r; + r = ((wglReleasePbufferDCARB = (PFNWGLRELEASEPBUFFERDCARBPROC)glewGetProcAddress((const GLubyte*)"wglReleasePbufferDCARB")) == NULL) || r; + + return r; +} + +#endif /* WGL_ARB_pbuffer */ + +#ifdef WGL_ARB_pixel_format + +static GLboolean _glewInit_WGL_ARB_pixel_format (WGLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((wglChoosePixelFormatARB = (PFNWGLCHOOSEPIXELFORMATARBPROC)glewGetProcAddress((const GLubyte*)"wglChoosePixelFormatARB")) == NULL) || r; + r = ((wglGetPixelFormatAttribfvARB = (PFNWGLGETPIXELFORMATATTRIBFVARBPROC)glewGetProcAddress((const GLubyte*)"wglGetPixelFormatAttribfvARB")) == NULL) || r; + r = ((wglGetPixelFormatAttribivARB = (PFNWGLGETPIXELFORMATATTRIBIVARBPROC)glewGetProcAddress((const GLubyte*)"wglGetPixelFormatAttribivARB")) == NULL) || r; + + return r; +} + +#endif /* WGL_ARB_pixel_format */ + +#ifdef WGL_ARB_pixel_format_float + +#endif /* WGL_ARB_pixel_format_float */ + +#ifdef WGL_ARB_render_texture + +static GLboolean _glewInit_WGL_ARB_render_texture (WGLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((wglBindTexImageARB = (PFNWGLBINDTEXIMAGEARBPROC)glewGetProcAddress((const GLubyte*)"wglBindTexImageARB")) == NULL) || r; + r = ((wglReleaseTexImageARB = (PFNWGLRELEASETEXIMAGEARBPROC)glewGetProcAddress((const GLubyte*)"wglReleaseTexImageARB")) == NULL) || r; + r = ((wglSetPbufferAttribARB = (PFNWGLSETPBUFFERATTRIBARBPROC)glewGetProcAddress((const GLubyte*)"wglSetPbufferAttribARB")) == NULL) || r; + + return r; +} + +#endif /* WGL_ARB_render_texture */ + +#ifdef WGL_ATI_pixel_format_float + +#endif /* WGL_ATI_pixel_format_float */ + +#ifdef WGL_ATI_render_texture_rectangle + +#endif /* WGL_ATI_render_texture_rectangle */ + +#ifdef WGL_EXT_depth_float + +#endif /* WGL_EXT_depth_float */ + +#ifdef WGL_EXT_display_color_table + +static GLboolean _glewInit_WGL_EXT_display_color_table (WGLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((wglBindDisplayColorTableEXT = (PFNWGLBINDDISPLAYCOLORTABLEEXTPROC)glewGetProcAddress((const GLubyte*)"wglBindDisplayColorTableEXT")) == NULL) || r; + r = ((wglCreateDisplayColorTableEXT = (PFNWGLCREATEDISPLAYCOLORTABLEEXTPROC)glewGetProcAddress((const GLubyte*)"wglCreateDisplayColorTableEXT")) == NULL) || r; + r = ((wglDestroyDisplayColorTableEXT = (PFNWGLDESTROYDISPLAYCOLORTABLEEXTPROC)glewGetProcAddress((const GLubyte*)"wglDestroyDisplayColorTableEXT")) == NULL) || r; + r = ((wglLoadDisplayColorTableEXT = (PFNWGLLOADDISPLAYCOLORTABLEEXTPROC)glewGetProcAddress((const GLubyte*)"wglLoadDisplayColorTableEXT")) == NULL) || r; + + return r; +} + +#endif /* WGL_EXT_display_color_table */ + +#ifdef WGL_EXT_extensions_string + +static GLboolean _glewInit_WGL_EXT_extensions_string (WGLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((wglGetExtensionsStringEXT = (PFNWGLGETEXTENSIONSSTRINGEXTPROC)glewGetProcAddress((const GLubyte*)"wglGetExtensionsStringEXT")) == NULL) || r; + + return r; +} + +#endif /* WGL_EXT_extensions_string */ + +#ifdef WGL_EXT_make_current_read + +static GLboolean _glewInit_WGL_EXT_make_current_read (WGLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((wglGetCurrentReadDCEXT = (PFNWGLGETCURRENTREADDCEXTPROC)glewGetProcAddress((const GLubyte*)"wglGetCurrentReadDCEXT")) == NULL) || r; + r = ((wglMakeContextCurrentEXT = (PFNWGLMAKECONTEXTCURRENTEXTPROC)glewGetProcAddress((const GLubyte*)"wglMakeContextCurrentEXT")) == NULL) || r; + + return r; +} + +#endif /* WGL_EXT_make_current_read */ + +#ifdef WGL_EXT_multisample + +#endif /* WGL_EXT_multisample */ + +#ifdef WGL_EXT_pbuffer + +static GLboolean _glewInit_WGL_EXT_pbuffer (WGLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((wglCreatePbufferEXT = (PFNWGLCREATEPBUFFEREXTPROC)glewGetProcAddress((const GLubyte*)"wglCreatePbufferEXT")) == NULL) || r; + r = ((wglDestroyPbufferEXT = (PFNWGLDESTROYPBUFFEREXTPROC)glewGetProcAddress((const GLubyte*)"wglDestroyPbufferEXT")) == NULL) || r; + r = ((wglGetPbufferDCEXT = (PFNWGLGETPBUFFERDCEXTPROC)glewGetProcAddress((const GLubyte*)"wglGetPbufferDCEXT")) == NULL) || r; + r = ((wglQueryPbufferEXT = (PFNWGLQUERYPBUFFEREXTPROC)glewGetProcAddress((const GLubyte*)"wglQueryPbufferEXT")) == NULL) || r; + r = ((wglReleasePbufferDCEXT = (PFNWGLRELEASEPBUFFERDCEXTPROC)glewGetProcAddress((const GLubyte*)"wglReleasePbufferDCEXT")) == NULL) || r; + + return r; +} + +#endif /* WGL_EXT_pbuffer */ + +#ifdef WGL_EXT_pixel_format + +static GLboolean _glewInit_WGL_EXT_pixel_format (WGLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((wglChoosePixelFormatEXT = (PFNWGLCHOOSEPIXELFORMATEXTPROC)glewGetProcAddress((const GLubyte*)"wglChoosePixelFormatEXT")) == NULL) || r; + r = ((wglGetPixelFormatAttribfvEXT = (PFNWGLGETPIXELFORMATATTRIBFVEXTPROC)glewGetProcAddress((const GLubyte*)"wglGetPixelFormatAttribfvEXT")) == NULL) || r; + r = ((wglGetPixelFormatAttribivEXT = (PFNWGLGETPIXELFORMATATTRIBIVEXTPROC)glewGetProcAddress((const GLubyte*)"wglGetPixelFormatAttribivEXT")) == NULL) || r; + + return r; +} + +#endif /* WGL_EXT_pixel_format */ + +#ifdef WGL_EXT_swap_control + +static GLboolean _glewInit_WGL_EXT_swap_control (WGLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((wglGetSwapIntervalEXT = (PFNWGLGETSWAPINTERVALEXTPROC)glewGetProcAddress((const GLubyte*)"wglGetSwapIntervalEXT")) == NULL) || r; + r = ((wglSwapIntervalEXT = (PFNWGLSWAPINTERVALEXTPROC)glewGetProcAddress((const GLubyte*)"wglSwapIntervalEXT")) == NULL) || r; + + return r; +} + +#endif /* WGL_EXT_swap_control */ + +#ifdef WGL_I3D_digital_video_control + +static GLboolean _glewInit_WGL_I3D_digital_video_control (WGLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((wglGetDigitalVideoParametersI3D = (PFNWGLGETDIGITALVIDEOPARAMETERSI3DPROC)glewGetProcAddress((const GLubyte*)"wglGetDigitalVideoParametersI3D")) == NULL) || r; + r = ((wglSetDigitalVideoParametersI3D = (PFNWGLSETDIGITALVIDEOPARAMETERSI3DPROC)glewGetProcAddress((const GLubyte*)"wglSetDigitalVideoParametersI3D")) == NULL) || r; + + return r; +} + +#endif /* WGL_I3D_digital_video_control */ + +#ifdef WGL_I3D_gamma + +static GLboolean _glewInit_WGL_I3D_gamma (WGLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((wglGetGammaTableI3D = (PFNWGLGETGAMMATABLEI3DPROC)glewGetProcAddress((const GLubyte*)"wglGetGammaTableI3D")) == NULL) || r; + r = ((wglGetGammaTableParametersI3D = (PFNWGLGETGAMMATABLEPARAMETERSI3DPROC)glewGetProcAddress((const GLubyte*)"wglGetGammaTableParametersI3D")) == NULL) || r; + r = ((wglSetGammaTableI3D = (PFNWGLSETGAMMATABLEI3DPROC)glewGetProcAddress((const GLubyte*)"wglSetGammaTableI3D")) == NULL) || r; + r = ((wglSetGammaTableParametersI3D = (PFNWGLSETGAMMATABLEPARAMETERSI3DPROC)glewGetProcAddress((const GLubyte*)"wglSetGammaTableParametersI3D")) == NULL) || r; + + return r; +} + +#endif /* WGL_I3D_gamma */ + +#ifdef WGL_I3D_genlock + +static GLboolean _glewInit_WGL_I3D_genlock (WGLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((wglDisableGenlockI3D = (PFNWGLDISABLEGENLOCKI3DPROC)glewGetProcAddress((const GLubyte*)"wglDisableGenlockI3D")) == NULL) || r; + r = ((wglEnableGenlockI3D = (PFNWGLENABLEGENLOCKI3DPROC)glewGetProcAddress((const GLubyte*)"wglEnableGenlockI3D")) == NULL) || r; + r = ((wglGenlockSampleRateI3D = (PFNWGLGENLOCKSAMPLERATEI3DPROC)glewGetProcAddress((const GLubyte*)"wglGenlockSampleRateI3D")) == NULL) || r; + r = ((wglGenlockSourceDelayI3D = (PFNWGLGENLOCKSOURCEDELAYI3DPROC)glewGetProcAddress((const GLubyte*)"wglGenlockSourceDelayI3D")) == NULL) || r; + r = ((wglGenlockSourceEdgeI3D = (PFNWGLGENLOCKSOURCEEDGEI3DPROC)glewGetProcAddress((const GLubyte*)"wglGenlockSourceEdgeI3D")) == NULL) || r; + r = ((wglGenlockSourceI3D = (PFNWGLGENLOCKSOURCEI3DPROC)glewGetProcAddress((const GLubyte*)"wglGenlockSourceI3D")) == NULL) || r; + r = ((wglGetGenlockSampleRateI3D = (PFNWGLGETGENLOCKSAMPLERATEI3DPROC)glewGetProcAddress((const GLubyte*)"wglGetGenlockSampleRateI3D")) == NULL) || r; + r = ((wglGetGenlockSourceDelayI3D = (PFNWGLGETGENLOCKSOURCEDELAYI3DPROC)glewGetProcAddress((const GLubyte*)"wglGetGenlockSourceDelayI3D")) == NULL) || r; + r = ((wglGetGenlockSourceEdgeI3D = (PFNWGLGETGENLOCKSOURCEEDGEI3DPROC)glewGetProcAddress((const GLubyte*)"wglGetGenlockSourceEdgeI3D")) == NULL) || r; + r = ((wglGetGenlockSourceI3D = (PFNWGLGETGENLOCKSOURCEI3DPROC)glewGetProcAddress((const GLubyte*)"wglGetGenlockSourceI3D")) == NULL) || r; + r = ((wglIsEnabledGenlockI3D = (PFNWGLISENABLEDGENLOCKI3DPROC)glewGetProcAddress((const GLubyte*)"wglIsEnabledGenlockI3D")) == NULL) || r; + r = ((wglQueryGenlockMaxSourceDelayI3D = (PFNWGLQUERYGENLOCKMAXSOURCEDELAYI3DPROC)glewGetProcAddress((const GLubyte*)"wglQueryGenlockMaxSourceDelayI3D")) == NULL) || r; + + return r; +} + +#endif /* WGL_I3D_genlock */ + +#ifdef WGL_I3D_image_buffer + +static GLboolean _glewInit_WGL_I3D_image_buffer (WGLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((wglAssociateImageBufferEventsI3D = (PFNWGLASSOCIATEIMAGEBUFFEREVENTSI3DPROC)glewGetProcAddress((const GLubyte*)"wglAssociateImageBufferEventsI3D")) == NULL) || r; + r = ((wglCreateImageBufferI3D = (PFNWGLCREATEIMAGEBUFFERI3DPROC)glewGetProcAddress((const GLubyte*)"wglCreateImageBufferI3D")) == NULL) || r; + r = ((wglDestroyImageBufferI3D = (PFNWGLDESTROYIMAGEBUFFERI3DPROC)glewGetProcAddress((const GLubyte*)"wglDestroyImageBufferI3D")) == NULL) || r; + r = ((wglReleaseImageBufferEventsI3D = (PFNWGLRELEASEIMAGEBUFFEREVENTSI3DPROC)glewGetProcAddress((const GLubyte*)"wglReleaseImageBufferEventsI3D")) == NULL) || r; + + return r; +} + +#endif /* WGL_I3D_image_buffer */ + +#ifdef WGL_I3D_swap_frame_lock + +static GLboolean _glewInit_WGL_I3D_swap_frame_lock (WGLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((wglDisableFrameLockI3D = (PFNWGLDISABLEFRAMELOCKI3DPROC)glewGetProcAddress((const GLubyte*)"wglDisableFrameLockI3D")) == NULL) || r; + r = ((wglEnableFrameLockI3D = (PFNWGLENABLEFRAMELOCKI3DPROC)glewGetProcAddress((const GLubyte*)"wglEnableFrameLockI3D")) == NULL) || r; + r = ((wglIsEnabledFrameLockI3D = (PFNWGLISENABLEDFRAMELOCKI3DPROC)glewGetProcAddress((const GLubyte*)"wglIsEnabledFrameLockI3D")) == NULL) || r; + r = ((wglQueryFrameLockMasterI3D = (PFNWGLQUERYFRAMELOCKMASTERI3DPROC)glewGetProcAddress((const GLubyte*)"wglQueryFrameLockMasterI3D")) == NULL) || r; + + return r; +} + +#endif /* WGL_I3D_swap_frame_lock */ + +#ifdef WGL_I3D_swap_frame_usage + +static GLboolean _glewInit_WGL_I3D_swap_frame_usage (WGLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((wglBeginFrameTrackingI3D = (PFNWGLBEGINFRAMETRACKINGI3DPROC)glewGetProcAddress((const GLubyte*)"wglBeginFrameTrackingI3D")) == NULL) || r; + r = ((wglEndFrameTrackingI3D = (PFNWGLENDFRAMETRACKINGI3DPROC)glewGetProcAddress((const GLubyte*)"wglEndFrameTrackingI3D")) == NULL) || r; + r = ((wglGetFrameUsageI3D = (PFNWGLGETFRAMEUSAGEI3DPROC)glewGetProcAddress((const GLubyte*)"wglGetFrameUsageI3D")) == NULL) || r; + r = ((wglQueryFrameTrackingI3D = (PFNWGLQUERYFRAMETRACKINGI3DPROC)glewGetProcAddress((const GLubyte*)"wglQueryFrameTrackingI3D")) == NULL) || r; + + return r; +} + +#endif /* WGL_I3D_swap_frame_usage */ + +#ifdef WGL_NV_float_buffer + +#endif /* WGL_NV_float_buffer */ + +#ifdef WGL_NV_render_depth_texture + +#endif /* WGL_NV_render_depth_texture */ + +#ifdef WGL_NV_render_texture_rectangle + +#endif /* WGL_NV_render_texture_rectangle */ + +#ifdef WGL_NV_vertex_array_range + +static GLboolean _glewInit_WGL_NV_vertex_array_range (WGLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((wglAllocateMemoryNV = (PFNWGLALLOCATEMEMORYNVPROC)glewGetProcAddress((const GLubyte*)"wglAllocateMemoryNV")) == NULL) || r; + r = ((wglFreeMemoryNV = (PFNWGLFREEMEMORYNVPROC)glewGetProcAddress((const GLubyte*)"wglFreeMemoryNV")) == NULL) || r; + + return r; +} + +#endif /* WGL_NV_vertex_array_range */ + +#ifdef WGL_OML_sync_control + +static GLboolean _glewInit_WGL_OML_sync_control (WGLEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((wglGetMscRateOML = (PFNWGLGETMSCRATEOMLPROC)glewGetProcAddress((const GLubyte*)"wglGetMscRateOML")) == NULL) || r; + r = ((wglGetSyncValuesOML = (PFNWGLGETSYNCVALUESOMLPROC)glewGetProcAddress((const GLubyte*)"wglGetSyncValuesOML")) == NULL) || r; + r = ((wglSwapBuffersMscOML = (PFNWGLSWAPBUFFERSMSCOMLPROC)glewGetProcAddress((const GLubyte*)"wglSwapBuffersMscOML")) == NULL) || r; + r = ((wglSwapLayerBuffersMscOML = (PFNWGLSWAPLAYERBUFFERSMSCOMLPROC)glewGetProcAddress((const GLubyte*)"wglSwapLayerBuffersMscOML")) == NULL) || r; + r = ((wglWaitForMscOML = (PFNWGLWAITFORMSCOMLPROC)glewGetProcAddress((const GLubyte*)"wglWaitForMscOML")) == NULL) || r; + r = ((wglWaitForSbcOML = (PFNWGLWAITFORSBCOMLPROC)glewGetProcAddress((const GLubyte*)"wglWaitForSbcOML")) == NULL) || r; + + return r; +} + +#endif /* WGL_OML_sync_control */ + +/* ------------------------------------------------------------------------- */ + +static PFNWGLGETEXTENSIONSSTRINGARBPROC _wglewGetExtensionsStringARB = NULL; +static PFNWGLGETEXTENSIONSSTRINGEXTPROC _wglewGetExtensionsStringEXT = NULL; + +GLboolean wglewGetExtension (const char* name) +{ + GLubyte* p; + GLubyte* end; + GLuint len = _glewStrLen((const GLubyte*)name); + if (_wglewGetExtensionsStringARB == NULL) + if (_wglewGetExtensionsStringEXT == NULL) + return GL_FALSE; + else + p = (GLubyte*)_wglewGetExtensionsStringEXT(); + else + p = (GLubyte*)_wglewGetExtensionsStringARB(wglGetCurrentDC()); + if (0 == p) return GL_FALSE; + end = p + _glewStrLen(p); + while (p < end) + { + GLuint n = _glewStrCLen(p, ' '); + if (len == n && _glewStrSame((const GLubyte*)name, p, n)) return GL_TRUE; + p += n+1; + } + return GL_FALSE; +} + +GLenum wglewContextInit (WGLEW_CONTEXT_ARG_DEF_LIST) +{ + GLboolean crippled; + /* find wgl extension string query functions */ + if (_wglewGetExtensionsStringARB == NULL) + _wglewGetExtensionsStringARB = (PFNWGLGETEXTENSIONSSTRINGARBPROC)glewGetProcAddress((const GLubyte*)"wglGetExtensionsStringARB"); + if (_wglewGetExtensionsStringEXT == NULL) + _wglewGetExtensionsStringEXT = (PFNWGLGETEXTENSIONSSTRINGEXTPROC)glewGetProcAddress((const GLubyte*)"wglGetExtensionsStringEXT"); + /* initialize extensions */ + crippled = _wglewGetExtensionsStringARB == NULL && _wglewGetExtensionsStringEXT == NULL; +#ifdef WGL_3DFX_multisample + WGLEW_3DFX_multisample = wglewGetExtension("WGL_3DFX_multisample"); +#endif /* WGL_3DFX_multisample */ +#ifdef WGL_3DL_stereo_control + WGLEW_3DL_stereo_control = wglewGetExtension("WGL_3DL_stereo_control"); + if (glewExperimental || WGLEW_3DL_stereo_control|| crippled) WGLEW_3DL_stereo_control= !_glewInit_WGL_3DL_stereo_control(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* WGL_3DL_stereo_control */ +#ifdef WGL_ARB_buffer_region + WGLEW_ARB_buffer_region = wglewGetExtension("WGL_ARB_buffer_region"); + if (glewExperimental || WGLEW_ARB_buffer_region|| crippled) WGLEW_ARB_buffer_region= !_glewInit_WGL_ARB_buffer_region(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* WGL_ARB_buffer_region */ +#ifdef WGL_ARB_extensions_string + WGLEW_ARB_extensions_string = wglewGetExtension("WGL_ARB_extensions_string"); + if (glewExperimental || WGLEW_ARB_extensions_string|| crippled) WGLEW_ARB_extensions_string= !_glewInit_WGL_ARB_extensions_string(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* WGL_ARB_extensions_string */ +#ifdef WGL_ARB_make_current_read + WGLEW_ARB_make_current_read = wglewGetExtension("WGL_ARB_make_current_read"); + if (glewExperimental || WGLEW_ARB_make_current_read|| crippled) WGLEW_ARB_make_current_read= !_glewInit_WGL_ARB_make_current_read(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* WGL_ARB_make_current_read */ +#ifdef WGL_ARB_multisample + WGLEW_ARB_multisample = wglewGetExtension("WGL_ARB_multisample"); +#endif /* WGL_ARB_multisample */ +#ifdef WGL_ARB_pbuffer + WGLEW_ARB_pbuffer = wglewGetExtension("WGL_ARB_pbuffer"); + if (glewExperimental || WGLEW_ARB_pbuffer|| crippled) WGLEW_ARB_pbuffer= !_glewInit_WGL_ARB_pbuffer(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* WGL_ARB_pbuffer */ +#ifdef WGL_ARB_pixel_format + WGLEW_ARB_pixel_format = wglewGetExtension("WGL_ARB_pixel_format"); + if (glewExperimental || WGLEW_ARB_pixel_format|| crippled) WGLEW_ARB_pixel_format= !_glewInit_WGL_ARB_pixel_format(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* WGL_ARB_pixel_format */ +#ifdef WGL_ARB_pixel_format_float + WGLEW_ARB_pixel_format_float = wglewGetExtension("WGL_ARB_pixel_format_float"); +#endif /* WGL_ARB_pixel_format_float */ +#ifdef WGL_ARB_render_texture + WGLEW_ARB_render_texture = wglewGetExtension("WGL_ARB_render_texture"); + if (glewExperimental || WGLEW_ARB_render_texture|| crippled) WGLEW_ARB_render_texture= !_glewInit_WGL_ARB_render_texture(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* WGL_ARB_render_texture */ +#ifdef WGL_ATI_pixel_format_float + WGLEW_ATI_pixel_format_float = wglewGetExtension("WGL_ATI_pixel_format_float"); +#endif /* WGL_ATI_pixel_format_float */ +#ifdef WGL_ATI_render_texture_rectangle + WGLEW_ATI_render_texture_rectangle = wglewGetExtension("WGL_ATI_render_texture_rectangle"); +#endif /* WGL_ATI_render_texture_rectangle */ +#ifdef WGL_EXT_depth_float + WGLEW_EXT_depth_float = wglewGetExtension("WGL_EXT_depth_float"); +#endif /* WGL_EXT_depth_float */ +#ifdef WGL_EXT_display_color_table + WGLEW_EXT_display_color_table = wglewGetExtension("WGL_EXT_display_color_table"); + if (glewExperimental || WGLEW_EXT_display_color_table|| crippled) WGLEW_EXT_display_color_table= !_glewInit_WGL_EXT_display_color_table(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* WGL_EXT_display_color_table */ +#ifdef WGL_EXT_extensions_string + WGLEW_EXT_extensions_string = wglewGetExtension("WGL_EXT_extensions_string"); + if (glewExperimental || WGLEW_EXT_extensions_string|| crippled) WGLEW_EXT_extensions_string= !_glewInit_WGL_EXT_extensions_string(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* WGL_EXT_extensions_string */ +#ifdef WGL_EXT_make_current_read + WGLEW_EXT_make_current_read = wglewGetExtension("WGL_EXT_make_current_read"); + if (glewExperimental || WGLEW_EXT_make_current_read|| crippled) WGLEW_EXT_make_current_read= !_glewInit_WGL_EXT_make_current_read(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* WGL_EXT_make_current_read */ +#ifdef WGL_EXT_multisample + WGLEW_EXT_multisample = wglewGetExtension("WGL_EXT_multisample"); +#endif /* WGL_EXT_multisample */ +#ifdef WGL_EXT_pbuffer + WGLEW_EXT_pbuffer = wglewGetExtension("WGL_EXT_pbuffer"); + if (glewExperimental || WGLEW_EXT_pbuffer|| crippled) WGLEW_EXT_pbuffer= !_glewInit_WGL_EXT_pbuffer(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* WGL_EXT_pbuffer */ +#ifdef WGL_EXT_pixel_format + WGLEW_EXT_pixel_format = wglewGetExtension("WGL_EXT_pixel_format"); + if (glewExperimental || WGLEW_EXT_pixel_format|| crippled) WGLEW_EXT_pixel_format= !_glewInit_WGL_EXT_pixel_format(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* WGL_EXT_pixel_format */ +#ifdef WGL_EXT_swap_control + WGLEW_EXT_swap_control = wglewGetExtension("WGL_EXT_swap_control"); + if (glewExperimental || WGLEW_EXT_swap_control|| crippled) WGLEW_EXT_swap_control= !_glewInit_WGL_EXT_swap_control(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* WGL_EXT_swap_control */ +#ifdef WGL_I3D_digital_video_control + WGLEW_I3D_digital_video_control = wglewGetExtension("WGL_I3D_digital_video_control"); + if (glewExperimental || WGLEW_I3D_digital_video_control|| crippled) WGLEW_I3D_digital_video_control= !_glewInit_WGL_I3D_digital_video_control(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* WGL_I3D_digital_video_control */ +#ifdef WGL_I3D_gamma + WGLEW_I3D_gamma = wglewGetExtension("WGL_I3D_gamma"); + if (glewExperimental || WGLEW_I3D_gamma|| crippled) WGLEW_I3D_gamma= !_glewInit_WGL_I3D_gamma(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* WGL_I3D_gamma */ +#ifdef WGL_I3D_genlock + WGLEW_I3D_genlock = wglewGetExtension("WGL_I3D_genlock"); + if (glewExperimental || WGLEW_I3D_genlock|| crippled) WGLEW_I3D_genlock= !_glewInit_WGL_I3D_genlock(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* WGL_I3D_genlock */ +#ifdef WGL_I3D_image_buffer + WGLEW_I3D_image_buffer = wglewGetExtension("WGL_I3D_image_buffer"); + if (glewExperimental || WGLEW_I3D_image_buffer|| crippled) WGLEW_I3D_image_buffer= !_glewInit_WGL_I3D_image_buffer(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* WGL_I3D_image_buffer */ +#ifdef WGL_I3D_swap_frame_lock + WGLEW_I3D_swap_frame_lock = wglewGetExtension("WGL_I3D_swap_frame_lock"); + if (glewExperimental || WGLEW_I3D_swap_frame_lock|| crippled) WGLEW_I3D_swap_frame_lock= !_glewInit_WGL_I3D_swap_frame_lock(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* WGL_I3D_swap_frame_lock */ +#ifdef WGL_I3D_swap_frame_usage + WGLEW_I3D_swap_frame_usage = wglewGetExtension("WGL_I3D_swap_frame_usage"); + if (glewExperimental || WGLEW_I3D_swap_frame_usage|| crippled) WGLEW_I3D_swap_frame_usage= !_glewInit_WGL_I3D_swap_frame_usage(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* WGL_I3D_swap_frame_usage */ +#ifdef WGL_NV_float_buffer + WGLEW_NV_float_buffer = wglewGetExtension("WGL_NV_float_buffer"); +#endif /* WGL_NV_float_buffer */ +#ifdef WGL_NV_render_depth_texture + WGLEW_NV_render_depth_texture = wglewGetExtension("WGL_NV_render_depth_texture"); +#endif /* WGL_NV_render_depth_texture */ +#ifdef WGL_NV_render_texture_rectangle + WGLEW_NV_render_texture_rectangle = wglewGetExtension("WGL_NV_render_texture_rectangle"); +#endif /* WGL_NV_render_texture_rectangle */ +#ifdef WGL_NV_vertex_array_range + WGLEW_NV_vertex_array_range = wglewGetExtension("WGL_NV_vertex_array_range"); + if (glewExperimental || WGLEW_NV_vertex_array_range|| crippled) WGLEW_NV_vertex_array_range= !_glewInit_WGL_NV_vertex_array_range(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* WGL_NV_vertex_array_range */ +#ifdef WGL_OML_sync_control + WGLEW_OML_sync_control = wglewGetExtension("WGL_OML_sync_control"); + if (glewExperimental || WGLEW_OML_sync_control|| crippled) WGLEW_OML_sync_control= !_glewInit_WGL_OML_sync_control(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* WGL_OML_sync_control */ + + return GLEW_OK; +} + +#elif !defined(__APPLE__) || defined(GLEW_APPLE_GLX) + +PFNGLXGETCURRENTDISPLAYPROC __glewXGetCurrentDisplay = NULL; + +PFNGLXCHOOSEFBCONFIGPROC __glewXChooseFBConfig = NULL; +PFNGLXCREATENEWCONTEXTPROC __glewXCreateNewContext = NULL; +PFNGLXCREATEPBUFFERPROC __glewXCreatePbuffer = NULL; +PFNGLXCREATEPIXMAPPROC __glewXCreatePixmap = NULL; +PFNGLXCREATEWINDOWPROC __glewXCreateWindow = NULL; +PFNGLXDESTROYPBUFFERPROC __glewXDestroyPbuffer = NULL; +PFNGLXDESTROYPIXMAPPROC __glewXDestroyPixmap = NULL; +PFNGLXDESTROYWINDOWPROC __glewXDestroyWindow = NULL; +PFNGLXGETCURRENTREADDRAWABLEPROC __glewXGetCurrentReadDrawable = NULL; +PFNGLXGETFBCONFIGATTRIBPROC __glewXGetFBConfigAttrib = NULL; +PFNGLXGETFBCONFIGSPROC __glewXGetFBConfigs = NULL; +PFNGLXGETSELECTEDEVENTPROC __glewXGetSelectedEvent = NULL; +PFNGLXGETVISUALFROMFBCONFIGPROC __glewXGetVisualFromFBConfig = NULL; +PFNGLXMAKECONTEXTCURRENTPROC __glewXMakeContextCurrent = NULL; +PFNGLXQUERYCONTEXTPROC __glewXQueryContext = NULL; +PFNGLXQUERYDRAWABLEPROC __glewXQueryDrawable = NULL; +PFNGLXSELECTEVENTPROC __glewXSelectEvent = NULL; + +PFNGLXBINDTEXIMAGEATIPROC __glewXBindTexImageATI = NULL; +PFNGLXDRAWABLEATTRIBATIPROC __glewXDrawableAttribATI = NULL; +PFNGLXRELEASETEXIMAGEATIPROC __glewXReleaseTexImageATI = NULL; + +PFNGLXFREECONTEXTEXTPROC __glewXFreeContextEXT = NULL; +PFNGLXGETCONTEXTIDEXTPROC __glewXGetContextIDEXT = NULL; +PFNGLXIMPORTCONTEXTEXTPROC __glewXImportContextEXT = NULL; +PFNGLXQUERYCONTEXTINFOEXTPROC __glewXQueryContextInfoEXT = NULL; + +PFNGLXGETAGPOFFSETMESAPROC __glewXGetAGPOffsetMESA = NULL; + +PFNGLXCOPYSUBBUFFERMESAPROC __glewXCopySubBufferMESA = NULL; + +PFNGLXCREATEGLXPIXMAPMESAPROC __glewXCreateGLXPixmapMESA = NULL; + +PFNGLXRELEASEBUFFERSMESAPROC __glewXReleaseBuffersMESA = NULL; + +PFNGLXSET3DFXMODEMESAPROC __glewXSet3DfxModeMESA = NULL; + +PFNGLXALLOCATEMEMORYNVPROC __glewXAllocateMemoryNV = NULL; +PFNGLXFREEMEMORYNVPROC __glewXFreeMemoryNV = NULL; + +#ifdef GLX_OML_sync_control +PFNGLXGETMSCRATEOMLPROC __glewXGetMscRateOML = NULL; +PFNGLXGETSYNCVALUESOMLPROC __glewXGetSyncValuesOML = NULL; +PFNGLXSWAPBUFFERSMSCOMLPROC __glewXSwapBuffersMscOML = NULL; +PFNGLXWAITFORMSCOMLPROC __glewXWaitForMscOML = NULL; +PFNGLXWAITFORSBCOMLPROC __glewXWaitForSbcOML = NULL; +#endif + +PFNGLXCHOOSEFBCONFIGSGIXPROC __glewXChooseFBConfigSGIX = NULL; +PFNGLXCREATECONTEXTWITHCONFIGSGIXPROC __glewXCreateContextWithConfigSGIX = NULL; +PFNGLXCREATEGLXPIXMAPWITHCONFIGSGIXPROC __glewXCreateGLXPixmapWithConfigSGIX = NULL; +PFNGLXGETFBCONFIGATTRIBSGIXPROC __glewXGetFBConfigAttribSGIX = NULL; +PFNGLXGETFBCONFIGFROMVISUALSGIXPROC __glewXGetFBConfigFromVisualSGIX = NULL; +PFNGLXGETVISUALFROMFBCONFIGSGIXPROC __glewXGetVisualFromFBConfigSGIX = NULL; + +PFNGLXCREATEGLXPBUFFERSGIXPROC __glewXCreateGLXPbufferSGIX = NULL; +PFNGLXDESTROYGLXPBUFFERSGIXPROC __glewXDestroyGLXPbufferSGIX = NULL; +PFNGLXGETSELECTEDEVENTSGIXPROC __glewXGetSelectedEventSGIX = NULL; +PFNGLXQUERYGLXPBUFFERSGIXPROC __glewXQueryGLXPbufferSGIX = NULL; +PFNGLXSELECTEVENTSGIXPROC __glewXSelectEventSGIX = NULL; + +PFNGLXBINDSWAPBARRIERSGIXPROC __glewXBindSwapBarrierSGIX = NULL; +PFNGLXQUERYMAXSWAPBARRIERSSGIXPROC __glewXQueryMaxSwapBarriersSGIX = NULL; + +PFNGLXJOINSWAPGROUPSGIXPROC __glewXJoinSwapGroupSGIX = NULL; + +PFNGLXBINDCHANNELTOWINDOWSGIXPROC __glewXBindChannelToWindowSGIX = NULL; +PFNGLXCHANNELRECTSGIXPROC __glewXChannelRectSGIX = NULL; +PFNGLXCHANNELRECTSYNCSGIXPROC __glewXChannelRectSyncSGIX = NULL; +PFNGLXQUERYCHANNELDELTASSGIXPROC __glewXQueryChannelDeltasSGIX = NULL; +PFNGLXQUERYCHANNELRECTSGIXPROC __glewXQueryChannelRectSGIX = NULL; + +PFNGLXCUSHIONSGIPROC __glewXCushionSGI = NULL; + +PFNGLXGETCURRENTREADDRAWABLESGIPROC __glewXGetCurrentReadDrawableSGI = NULL; +PFNGLXMAKECURRENTREADSGIPROC __glewXMakeCurrentReadSGI = NULL; + +PFNGLXSWAPINTERVALSGIPROC __glewXSwapIntervalSGI = NULL; + +PFNGLXGETVIDEOSYNCSGIPROC __glewXGetVideoSyncSGI = NULL; +PFNGLXWAITVIDEOSYNCSGIPROC __glewXWaitVideoSyncSGI = NULL; + +PFNGLXGETTRANSPARENTINDEXSUNPROC __glewXGetTransparentIndexSUN = NULL; + +PFNGLXGETVIDEORESIZESUNPROC __glewXGetVideoResizeSUN = NULL; +PFNGLXVIDEORESIZESUNPROC __glewXVideoResizeSUN = NULL; + +#if !defined(GLEW_MX) + +GLboolean __GLXEW_VERSION_1_0 = GL_FALSE; +GLboolean __GLXEW_VERSION_1_1 = GL_FALSE; +GLboolean __GLXEW_VERSION_1_2 = GL_FALSE; +GLboolean __GLXEW_VERSION_1_3 = GL_FALSE; +GLboolean __GLXEW_VERSION_1_4 = GL_FALSE; +GLboolean __GLXEW_3DFX_multisample = GL_FALSE; +GLboolean __GLXEW_ARB_fbconfig_float = GL_FALSE; +GLboolean __GLXEW_ARB_get_proc_address = GL_FALSE; +GLboolean __GLXEW_ARB_multisample = GL_FALSE; +GLboolean __GLXEW_ATI_pixel_format_float = GL_FALSE; +GLboolean __GLXEW_ATI_render_texture = GL_FALSE; +GLboolean __GLXEW_EXT_import_context = GL_FALSE; +GLboolean __GLXEW_EXT_scene_marker = GL_FALSE; +GLboolean __GLXEW_EXT_visual_info = GL_FALSE; +GLboolean __GLXEW_EXT_visual_rating = GL_FALSE; +GLboolean __GLXEW_MESA_agp_offset = GL_FALSE; +GLboolean __GLXEW_MESA_copy_sub_buffer = GL_FALSE; +GLboolean __GLXEW_MESA_pixmap_colormap = GL_FALSE; +GLboolean __GLXEW_MESA_release_buffers = GL_FALSE; +GLboolean __GLXEW_MESA_set_3dfx_mode = GL_FALSE; +GLboolean __GLXEW_NV_float_buffer = GL_FALSE; +GLboolean __GLXEW_NV_vertex_array_range = GL_FALSE; +GLboolean __GLXEW_OML_swap_method = GL_FALSE; +#ifdef GLX_OML_sync_control +GLboolean __GLXEW_OML_sync_control = GL_FALSE; +#endif +GLboolean __GLXEW_SGIS_blended_overlay = GL_FALSE; +GLboolean __GLXEW_SGIS_color_range = GL_FALSE; +GLboolean __GLXEW_SGIS_multisample = GL_FALSE; +GLboolean __GLXEW_SGIS_shared_multisample = GL_FALSE; +GLboolean __GLXEW_SGIX_fbconfig = GL_FALSE; +GLboolean __GLXEW_SGIX_pbuffer = GL_FALSE; +GLboolean __GLXEW_SGIX_swap_barrier = GL_FALSE; +GLboolean __GLXEW_SGIX_swap_group = GL_FALSE; +GLboolean __GLXEW_SGIX_video_resize = GL_FALSE; +GLboolean __GLXEW_SGIX_visual_select_group = GL_FALSE; +GLboolean __GLXEW_SGI_cushion = GL_FALSE; +GLboolean __GLXEW_SGI_make_current_read = GL_FALSE; +GLboolean __GLXEW_SGI_swap_control = GL_FALSE; +GLboolean __GLXEW_SGI_video_sync = GL_FALSE; +GLboolean __GLXEW_SUN_get_transparent_index = GL_FALSE; +GLboolean __GLXEW_SUN_video_resize = GL_FALSE; + +#endif /* !GLEW_MX */ + +#ifdef GLX_VERSION_1_2 + +static GLboolean _glewInit_GLX_VERSION_1_2 (GLXEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glXGetCurrentDisplay = (PFNGLXGETCURRENTDISPLAYPROC)glewGetProcAddress((const GLubyte*)"glXGetCurrentDisplay")) == NULL) || r; + + return r; +} + +#endif /* GLX_VERSION_1_2 */ + +#ifdef GLX_VERSION_1_3 + +static GLboolean _glewInit_GLX_VERSION_1_3 (GLXEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glXChooseFBConfig = (PFNGLXCHOOSEFBCONFIGPROC)glewGetProcAddress((const GLubyte*)"glXChooseFBConfig")) == NULL) || r; + r = ((glXCreateNewContext = (PFNGLXCREATENEWCONTEXTPROC)glewGetProcAddress((const GLubyte*)"glXCreateNewContext")) == NULL) || r; + r = ((glXCreatePbuffer = (PFNGLXCREATEPBUFFERPROC)glewGetProcAddress((const GLubyte*)"glXCreatePbuffer")) == NULL) || r; + r = ((glXCreatePixmap = (PFNGLXCREATEPIXMAPPROC)glewGetProcAddress((const GLubyte*)"glXCreatePixmap")) == NULL) || r; + r = ((glXCreateWindow = (PFNGLXCREATEWINDOWPROC)glewGetProcAddress((const GLubyte*)"glXCreateWindow")) == NULL) || r; + r = ((glXDestroyPbuffer = (PFNGLXDESTROYPBUFFERPROC)glewGetProcAddress((const GLubyte*)"glXDestroyPbuffer")) == NULL) || r; + r = ((glXDestroyPixmap = (PFNGLXDESTROYPIXMAPPROC)glewGetProcAddress((const GLubyte*)"glXDestroyPixmap")) == NULL) || r; + r = ((glXDestroyWindow = (PFNGLXDESTROYWINDOWPROC)glewGetProcAddress((const GLubyte*)"glXDestroyWindow")) == NULL) || r; + r = ((glXGetCurrentReadDrawable = (PFNGLXGETCURRENTREADDRAWABLEPROC)glewGetProcAddress((const GLubyte*)"glXGetCurrentReadDrawable")) == NULL) || r; + r = ((glXGetFBConfigAttrib = (PFNGLXGETFBCONFIGATTRIBPROC)glewGetProcAddress((const GLubyte*)"glXGetFBConfigAttrib")) == NULL) || r; + r = ((glXGetFBConfigs = (PFNGLXGETFBCONFIGSPROC)glewGetProcAddress((const GLubyte*)"glXGetFBConfigs")) == NULL) || r; + r = ((glXGetSelectedEvent = (PFNGLXGETSELECTEDEVENTPROC)glewGetProcAddress((const GLubyte*)"glXGetSelectedEvent")) == NULL) || r; + r = ((glXGetVisualFromFBConfig = (PFNGLXGETVISUALFROMFBCONFIGPROC)glewGetProcAddress((const GLubyte*)"glXGetVisualFromFBConfig")) == NULL) || r; + r = ((glXMakeContextCurrent = (PFNGLXMAKECONTEXTCURRENTPROC)glewGetProcAddress((const GLubyte*)"glXMakeContextCurrent")) == NULL) || r; + r = ((glXQueryContext = (PFNGLXQUERYCONTEXTPROC)glewGetProcAddress((const GLubyte*)"glXQueryContext")) == NULL) || r; + r = ((glXQueryDrawable = (PFNGLXQUERYDRAWABLEPROC)glewGetProcAddress((const GLubyte*)"glXQueryDrawable")) == NULL) || r; + r = ((glXSelectEvent = (PFNGLXSELECTEVENTPROC)glewGetProcAddress((const GLubyte*)"glXSelectEvent")) == NULL) || r; + + return r; +} + +#endif /* GLX_VERSION_1_3 */ + +#ifdef GLX_VERSION_1_4 + +#endif /* GLX_VERSION_1_4 */ + +#ifdef GLX_3DFX_multisample + +#endif /* GLX_3DFX_multisample */ + +#ifdef GLX_ARB_fbconfig_float + +#endif /* GLX_ARB_fbconfig_float */ + +#ifdef GLX_ARB_get_proc_address + +#endif /* GLX_ARB_get_proc_address */ + +#ifdef GLX_ARB_multisample + +#endif /* GLX_ARB_multisample */ + +#ifdef GLX_ATI_pixel_format_float + +#endif /* GLX_ATI_pixel_format_float */ + +#ifdef GLX_ATI_render_texture + +static GLboolean _glewInit_GLX_ATI_render_texture (GLXEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glXBindTexImageATI = (PFNGLXBINDTEXIMAGEATIPROC)glewGetProcAddress((const GLubyte*)"glXBindTexImageATI")) == NULL) || r; + r = ((glXDrawableAttribATI = (PFNGLXDRAWABLEATTRIBATIPROC)glewGetProcAddress((const GLubyte*)"glXDrawableAttribATI")) == NULL) || r; + r = ((glXReleaseTexImageATI = (PFNGLXRELEASETEXIMAGEATIPROC)glewGetProcAddress((const GLubyte*)"glXReleaseTexImageATI")) == NULL) || r; + + return r; +} + +#endif /* GLX_ATI_render_texture */ + +#ifdef GLX_EXT_import_context + +static GLboolean _glewInit_GLX_EXT_import_context (GLXEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glXFreeContextEXT = (PFNGLXFREECONTEXTEXTPROC)glewGetProcAddress((const GLubyte*)"glXFreeContextEXT")) == NULL) || r; + r = ((glXGetContextIDEXT = (PFNGLXGETCONTEXTIDEXTPROC)glewGetProcAddress((const GLubyte*)"glXGetContextIDEXT")) == NULL) || r; + r = ((glXImportContextEXT = (PFNGLXIMPORTCONTEXTEXTPROC)glewGetProcAddress((const GLubyte*)"glXImportContextEXT")) == NULL) || r; + r = ((glXQueryContextInfoEXT = (PFNGLXQUERYCONTEXTINFOEXTPROC)glewGetProcAddress((const GLubyte*)"glXQueryContextInfoEXT")) == NULL) || r; + + return r; +} + +#endif /* GLX_EXT_import_context */ + +#ifdef GLX_EXT_scene_marker + +#endif /* GLX_EXT_scene_marker */ + +#ifdef GLX_EXT_visual_info + +#endif /* GLX_EXT_visual_info */ + +#ifdef GLX_EXT_visual_rating + +#endif /* GLX_EXT_visual_rating */ + +#ifdef GLX_MESA_agp_offset + +static GLboolean _glewInit_GLX_MESA_agp_offset (GLXEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glXGetAGPOffsetMESA = (PFNGLXGETAGPOFFSETMESAPROC)glewGetProcAddress((const GLubyte*)"glXGetAGPOffsetMESA")) == NULL) || r; + + return r; +} + +#endif /* GLX_MESA_agp_offset */ + +#ifdef GLX_MESA_copy_sub_buffer + +static GLboolean _glewInit_GLX_MESA_copy_sub_buffer (GLXEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glXCopySubBufferMESA = (PFNGLXCOPYSUBBUFFERMESAPROC)glewGetProcAddress((const GLubyte*)"glXCopySubBufferMESA")) == NULL) || r; + + return r; +} + +#endif /* GLX_MESA_copy_sub_buffer */ + +#ifdef GLX_MESA_pixmap_colormap + +static GLboolean _glewInit_GLX_MESA_pixmap_colormap (GLXEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glXCreateGLXPixmapMESA = (PFNGLXCREATEGLXPIXMAPMESAPROC)glewGetProcAddress((const GLubyte*)"glXCreateGLXPixmapMESA")) == NULL) || r; + + return r; +} + +#endif /* GLX_MESA_pixmap_colormap */ + +#ifdef GLX_MESA_release_buffers + +static GLboolean _glewInit_GLX_MESA_release_buffers (GLXEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glXReleaseBuffersMESA = (PFNGLXRELEASEBUFFERSMESAPROC)glewGetProcAddress((const GLubyte*)"glXReleaseBuffersMESA")) == NULL) || r; + + return r; +} + +#endif /* GLX_MESA_release_buffers */ + +#ifdef GLX_MESA_set_3dfx_mode + +static GLboolean _glewInit_GLX_MESA_set_3dfx_mode (GLXEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glXSet3DfxModeMESA = (PFNGLXSET3DFXMODEMESAPROC)glewGetProcAddress((const GLubyte*)"glXSet3DfxModeMESA")) == NULL) || r; + + return r; +} + +#endif /* GLX_MESA_set_3dfx_mode */ + +#ifdef GLX_NV_float_buffer + +#endif /* GLX_NV_float_buffer */ + +#ifdef GLX_NV_vertex_array_range + +static GLboolean _glewInit_GLX_NV_vertex_array_range (GLXEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glXAllocateMemoryNV = (PFNGLXALLOCATEMEMORYNVPROC)glewGetProcAddress((const GLubyte*)"glXAllocateMemoryNV")) == NULL) || r; + r = ((glXFreeMemoryNV = (PFNGLXFREEMEMORYNVPROC)glewGetProcAddress((const GLubyte*)"glXFreeMemoryNV")) == NULL) || r; + + return r; +} + +#endif /* GLX_NV_vertex_array_range */ + +#ifdef GLX_OML_swap_method + +#endif /* GLX_OML_swap_method */ + +#if defined(GLX_OML_sync_control) && defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) +#include + +static GLboolean _glewInit_GLX_OML_sync_control (GLXEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glXGetMscRateOML = (PFNGLXGETMSCRATEOMLPROC)glewGetProcAddress((const GLubyte*)"glXGetMscRateOML")) == NULL) || r; + r = ((glXGetSyncValuesOML = (PFNGLXGETSYNCVALUESOMLPROC)glewGetProcAddress((const GLubyte*)"glXGetSyncValuesOML")) == NULL) || r; + r = ((glXSwapBuffersMscOML = (PFNGLXSWAPBUFFERSMSCOMLPROC)glewGetProcAddress((const GLubyte*)"glXSwapBuffersMscOML")) == NULL) || r; + r = ((glXWaitForMscOML = (PFNGLXWAITFORMSCOMLPROC)glewGetProcAddress((const GLubyte*)"glXWaitForMscOML")) == NULL) || r; + r = ((glXWaitForSbcOML = (PFNGLXWAITFORSBCOMLPROC)glewGetProcAddress((const GLubyte*)"glXWaitForSbcOML")) == NULL) || r; + + return r; +} + +#endif /* GLX_OML_sync_control */ + +#ifdef GLX_SGIS_blended_overlay + +#endif /* GLX_SGIS_blended_overlay */ + +#ifdef GLX_SGIS_color_range + +#endif /* GLX_SGIS_color_range */ + +#ifdef GLX_SGIS_multisample + +#endif /* GLX_SGIS_multisample */ + +#ifdef GLX_SGIS_shared_multisample + +#endif /* GLX_SGIS_shared_multisample */ + +#ifdef GLX_SGIX_fbconfig + +static GLboolean _glewInit_GLX_SGIX_fbconfig (GLXEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glXChooseFBConfigSGIX = (PFNGLXCHOOSEFBCONFIGSGIXPROC)glewGetProcAddress((const GLubyte*)"glXChooseFBConfigSGIX")) == NULL) || r; + r = ((glXCreateContextWithConfigSGIX = (PFNGLXCREATECONTEXTWITHCONFIGSGIXPROC)glewGetProcAddress((const GLubyte*)"glXCreateContextWithConfigSGIX")) == NULL) || r; + r = ((glXCreateGLXPixmapWithConfigSGIX = (PFNGLXCREATEGLXPIXMAPWITHCONFIGSGIXPROC)glewGetProcAddress((const GLubyte*)"glXCreateGLXPixmapWithConfigSGIX")) == NULL) || r; + r = ((glXGetFBConfigAttribSGIX = (PFNGLXGETFBCONFIGATTRIBSGIXPROC)glewGetProcAddress((const GLubyte*)"glXGetFBConfigAttribSGIX")) == NULL) || r; + r = ((glXGetFBConfigFromVisualSGIX = (PFNGLXGETFBCONFIGFROMVISUALSGIXPROC)glewGetProcAddress((const GLubyte*)"glXGetFBConfigFromVisualSGIX")) == NULL) || r; + r = ((glXGetVisualFromFBConfigSGIX = (PFNGLXGETVISUALFROMFBCONFIGSGIXPROC)glewGetProcAddress((const GLubyte*)"glXGetVisualFromFBConfigSGIX")) == NULL) || r; + + return r; +} + +#endif /* GLX_SGIX_fbconfig */ + +#ifdef GLX_SGIX_pbuffer + +static GLboolean _glewInit_GLX_SGIX_pbuffer (GLXEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glXCreateGLXPbufferSGIX = (PFNGLXCREATEGLXPBUFFERSGIXPROC)glewGetProcAddress((const GLubyte*)"glXCreateGLXPbufferSGIX")) == NULL) || r; + r = ((glXDestroyGLXPbufferSGIX = (PFNGLXDESTROYGLXPBUFFERSGIXPROC)glewGetProcAddress((const GLubyte*)"glXDestroyGLXPbufferSGIX")) == NULL) || r; + r = ((glXGetSelectedEventSGIX = (PFNGLXGETSELECTEDEVENTSGIXPROC)glewGetProcAddress((const GLubyte*)"glXGetSelectedEventSGIX")) == NULL) || r; + r = ((glXQueryGLXPbufferSGIX = (PFNGLXQUERYGLXPBUFFERSGIXPROC)glewGetProcAddress((const GLubyte*)"glXQueryGLXPbufferSGIX")) == NULL) || r; + r = ((glXSelectEventSGIX = (PFNGLXSELECTEVENTSGIXPROC)glewGetProcAddress((const GLubyte*)"glXSelectEventSGIX")) == NULL) || r; + + return r; +} + +#endif /* GLX_SGIX_pbuffer */ + +#ifdef GLX_SGIX_swap_barrier + +static GLboolean _glewInit_GLX_SGIX_swap_barrier (GLXEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glXBindSwapBarrierSGIX = (PFNGLXBINDSWAPBARRIERSGIXPROC)glewGetProcAddress((const GLubyte*)"glXBindSwapBarrierSGIX")) == NULL) || r; + r = ((glXQueryMaxSwapBarriersSGIX = (PFNGLXQUERYMAXSWAPBARRIERSSGIXPROC)glewGetProcAddress((const GLubyte*)"glXQueryMaxSwapBarriersSGIX")) == NULL) || r; + + return r; +} + +#endif /* GLX_SGIX_swap_barrier */ + +#ifdef GLX_SGIX_swap_group + +static GLboolean _glewInit_GLX_SGIX_swap_group (GLXEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glXJoinSwapGroupSGIX = (PFNGLXJOINSWAPGROUPSGIXPROC)glewGetProcAddress((const GLubyte*)"glXJoinSwapGroupSGIX")) == NULL) || r; + + return r; +} + +#endif /* GLX_SGIX_swap_group */ + +#ifdef GLX_SGIX_video_resize + +static GLboolean _glewInit_GLX_SGIX_video_resize (GLXEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glXBindChannelToWindowSGIX = (PFNGLXBINDCHANNELTOWINDOWSGIXPROC)glewGetProcAddress((const GLubyte*)"glXBindChannelToWindowSGIX")) == NULL) || r; + r = ((glXChannelRectSGIX = (PFNGLXCHANNELRECTSGIXPROC)glewGetProcAddress((const GLubyte*)"glXChannelRectSGIX")) == NULL) || r; + r = ((glXChannelRectSyncSGIX = (PFNGLXCHANNELRECTSYNCSGIXPROC)glewGetProcAddress((const GLubyte*)"glXChannelRectSyncSGIX")) == NULL) || r; + r = ((glXQueryChannelDeltasSGIX = (PFNGLXQUERYCHANNELDELTASSGIXPROC)glewGetProcAddress((const GLubyte*)"glXQueryChannelDeltasSGIX")) == NULL) || r; + r = ((glXQueryChannelRectSGIX = (PFNGLXQUERYCHANNELRECTSGIXPROC)glewGetProcAddress((const GLubyte*)"glXQueryChannelRectSGIX")) == NULL) || r; + + return r; +} + +#endif /* GLX_SGIX_video_resize */ + +#ifdef GLX_SGIX_visual_select_group + +#endif /* GLX_SGIX_visual_select_group */ + +#ifdef GLX_SGI_cushion + +static GLboolean _glewInit_GLX_SGI_cushion (GLXEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glXCushionSGI = (PFNGLXCUSHIONSGIPROC)glewGetProcAddress((const GLubyte*)"glXCushionSGI")) == NULL) || r; + + return r; +} + +#endif /* GLX_SGI_cushion */ + +#ifdef GLX_SGI_make_current_read + +static GLboolean _glewInit_GLX_SGI_make_current_read (GLXEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glXGetCurrentReadDrawableSGI = (PFNGLXGETCURRENTREADDRAWABLESGIPROC)glewGetProcAddress((const GLubyte*)"glXGetCurrentReadDrawableSGI")) == NULL) || r; + r = ((glXMakeCurrentReadSGI = (PFNGLXMAKECURRENTREADSGIPROC)glewGetProcAddress((const GLubyte*)"glXMakeCurrentReadSGI")) == NULL) || r; + + return r; +} + +#endif /* GLX_SGI_make_current_read */ + +#ifdef GLX_SGI_swap_control + +static GLboolean _glewInit_GLX_SGI_swap_control (GLXEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glXSwapIntervalSGI = (PFNGLXSWAPINTERVALSGIPROC)glewGetProcAddress((const GLubyte*)"glXSwapIntervalSGI")) == NULL) || r; + + return r; +} + +#endif /* GLX_SGI_swap_control */ + +#ifdef GLX_SGI_video_sync + +static GLboolean _glewInit_GLX_SGI_video_sync (GLXEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glXGetVideoSyncSGI = (PFNGLXGETVIDEOSYNCSGIPROC)glewGetProcAddress((const GLubyte*)"glXGetVideoSyncSGI")) == NULL) || r; + r = ((glXWaitVideoSyncSGI = (PFNGLXWAITVIDEOSYNCSGIPROC)glewGetProcAddress((const GLubyte*)"glXWaitVideoSyncSGI")) == NULL) || r; + + return r; +} + +#endif /* GLX_SGI_video_sync */ + +#ifdef GLX_SUN_get_transparent_index + +static GLboolean _glewInit_GLX_SUN_get_transparent_index (GLXEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glXGetTransparentIndexSUN = (PFNGLXGETTRANSPARENTINDEXSUNPROC)glewGetProcAddress((const GLubyte*)"glXGetTransparentIndexSUN")) == NULL) || r; + + return r; +} + +#endif /* GLX_SUN_get_transparent_index */ + +#ifdef GLX_SUN_video_resize + +static GLboolean _glewInit_GLX_SUN_video_resize (GLXEW_CONTEXT_ARG_DEF_INIT) +{ + GLboolean r = GL_FALSE; + + r = ((glXGetVideoResizeSUN = (PFNGLXGETVIDEORESIZESUNPROC)glewGetProcAddress((const GLubyte*)"glXGetVideoResizeSUN")) == NULL) || r; + r = ((glXVideoResizeSUN = (PFNGLXVIDEORESIZESUNPROC)glewGetProcAddress((const GLubyte*)"glXVideoResizeSUN")) == NULL) || r; + + return r; +} + +#endif /* GLX_SUN_video_resize */ + +/* ------------------------------------------------------------------------ */ + +GLboolean glxewGetExtension (const char* name) +{ + GLubyte* p; + GLubyte* end; + GLuint len = _glewStrLen((const GLubyte*)name); +/* if (glXQueryExtensionsString == NULL || glXGetCurrentDisplay == NULL) return GL_FALSE; */ +/* p = (GLubyte*)glXQueryExtensionsString(glXGetCurrentDisplay(), DefaultScreen(glXGetCurrentDisplay())); */ + if (glXGetClientString == NULL || glXGetCurrentDisplay == NULL) return GL_FALSE; + p = (GLubyte*)glXGetClientString(glXGetCurrentDisplay(), GLX_EXTENSIONS); + if (0 == p) return GL_FALSE; + end = p + _glewStrLen(p); + while (p < end) + { + GLuint n = _glewStrCLen(p, ' '); + if (len == n && _glewStrSame((const GLubyte*)name, p, n)) return GL_TRUE; + p += n+1; + } + return GL_FALSE; +} + +GLenum glxewContextInit (GLXEW_CONTEXT_ARG_DEF_LIST) +{ + int major, minor; + /* initialize core GLX 1.2 */ + if (_glewInit_GLX_VERSION_1_2(GLEW_CONTEXT_ARG_VAR_INIT)) return GLEW_ERROR_GLX_VERSION_11_ONLY; + /* initialize flags */ + GLXEW_VERSION_1_0 = GL_TRUE; + GLXEW_VERSION_1_1 = GL_TRUE; + GLXEW_VERSION_1_2 = GL_TRUE; + GLXEW_VERSION_1_3 = GL_TRUE; + GLXEW_VERSION_1_4 = GL_TRUE; + /* query GLX version */ + glXQueryVersion(glXGetCurrentDisplay(), &major, &minor); + if (major == 1 && minor <= 3) + { + switch (minor) + { + case 3: + GLXEW_VERSION_1_4 = GL_FALSE; + break; + case 2: + GLXEW_VERSION_1_4 = GL_FALSE; + GLXEW_VERSION_1_3 = GL_FALSE; + break; + default: + return GLEW_ERROR_GLX_VERSION_11_ONLY; + break; + } + } + /* initialize extensions */ +#ifdef GLX_VERSION_1_3 + if (glewExperimental || GLXEW_VERSION_1_3) GLXEW_VERSION_1_3 = !_glewInit_GLX_VERSION_1_3(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GLX_VERSION_1_3 */ +#ifdef GLX_3DFX_multisample + GLXEW_3DFX_multisample = glxewGetExtension("GLX_3DFX_multisample"); +#endif /* GLX_3DFX_multisample */ +#ifdef GLX_ARB_fbconfig_float + GLXEW_ARB_fbconfig_float = glxewGetExtension("GLX_ARB_fbconfig_float"); +#endif /* GLX_ARB_fbconfig_float */ +#ifdef GLX_ARB_get_proc_address + GLXEW_ARB_get_proc_address = glxewGetExtension("GLX_ARB_get_proc_address"); +#endif /* GLX_ARB_get_proc_address */ +#ifdef GLX_ARB_multisample + GLXEW_ARB_multisample = glxewGetExtension("GLX_ARB_multisample"); +#endif /* GLX_ARB_multisample */ +#ifdef GLX_ATI_pixel_format_float + GLXEW_ATI_pixel_format_float = glxewGetExtension("GLX_ATI_pixel_format_float"); +#endif /* GLX_ATI_pixel_format_float */ +#ifdef GLX_ATI_render_texture + GLXEW_ATI_render_texture = glxewGetExtension("GLX_ATI_render_texture"); + if (glewExperimental || GLXEW_ATI_render_texture) GLXEW_ATI_render_texture = !_glewInit_GLX_ATI_render_texture(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GLX_ATI_render_texture */ +#ifdef GLX_EXT_import_context + GLXEW_EXT_import_context = glxewGetExtension("GLX_EXT_import_context"); + if (glewExperimental || GLXEW_EXT_import_context) GLXEW_EXT_import_context = !_glewInit_GLX_EXT_import_context(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GLX_EXT_import_context */ +#ifdef GLX_EXT_scene_marker + GLXEW_EXT_scene_marker = glxewGetExtension("GLX_EXT_scene_marker"); +#endif /* GLX_EXT_scene_marker */ +#ifdef GLX_EXT_visual_info + GLXEW_EXT_visual_info = glxewGetExtension("GLX_EXT_visual_info"); +#endif /* GLX_EXT_visual_info */ +#ifdef GLX_EXT_visual_rating + GLXEW_EXT_visual_rating = glxewGetExtension("GLX_EXT_visual_rating"); +#endif /* GLX_EXT_visual_rating */ +#ifdef GLX_MESA_agp_offset + GLXEW_MESA_agp_offset = glxewGetExtension("GLX_MESA_agp_offset"); + if (glewExperimental || GLXEW_MESA_agp_offset) GLXEW_MESA_agp_offset = !_glewInit_GLX_MESA_agp_offset(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GLX_MESA_agp_offset */ +#ifdef GLX_MESA_copy_sub_buffer + GLXEW_MESA_copy_sub_buffer = glxewGetExtension("GLX_MESA_copy_sub_buffer"); + if (glewExperimental || GLXEW_MESA_copy_sub_buffer) GLXEW_MESA_copy_sub_buffer = !_glewInit_GLX_MESA_copy_sub_buffer(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GLX_MESA_copy_sub_buffer */ +#ifdef GLX_MESA_pixmap_colormap + GLXEW_MESA_pixmap_colormap = glxewGetExtension("GLX_MESA_pixmap_colormap"); + if (glewExperimental || GLXEW_MESA_pixmap_colormap) GLXEW_MESA_pixmap_colormap = !_glewInit_GLX_MESA_pixmap_colormap(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GLX_MESA_pixmap_colormap */ +#ifdef GLX_MESA_release_buffers + GLXEW_MESA_release_buffers = glxewGetExtension("GLX_MESA_release_buffers"); + if (glewExperimental || GLXEW_MESA_release_buffers) GLXEW_MESA_release_buffers = !_glewInit_GLX_MESA_release_buffers(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GLX_MESA_release_buffers */ +#ifdef GLX_MESA_set_3dfx_mode + GLXEW_MESA_set_3dfx_mode = glxewGetExtension("GLX_MESA_set_3dfx_mode"); + if (glewExperimental || GLXEW_MESA_set_3dfx_mode) GLXEW_MESA_set_3dfx_mode = !_glewInit_GLX_MESA_set_3dfx_mode(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GLX_MESA_set_3dfx_mode */ +#ifdef GLX_NV_float_buffer + GLXEW_NV_float_buffer = glxewGetExtension("GLX_NV_float_buffer"); +#endif /* GLX_NV_float_buffer */ +#ifdef GLX_NV_vertex_array_range + GLXEW_NV_vertex_array_range = glxewGetExtension("GLX_NV_vertex_array_range"); + if (glewExperimental || GLXEW_NV_vertex_array_range) GLXEW_NV_vertex_array_range = !_glewInit_GLX_NV_vertex_array_range(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GLX_NV_vertex_array_range */ +#ifdef GLX_OML_swap_method + GLXEW_OML_swap_method = glxewGetExtension("GLX_OML_swap_method"); +#endif /* GLX_OML_swap_method */ +#if defined(GLX_OML_sync_control) && defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) +#include + GLXEW_OML_sync_control = glxewGetExtension("GLX_OML_sync_control"); + if (glewExperimental || GLXEW_OML_sync_control) GLXEW_OML_sync_control = !_glewInit_GLX_OML_sync_control(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GLX_OML_sync_control */ +#ifdef GLX_SGIS_blended_overlay + GLXEW_SGIS_blended_overlay = glxewGetExtension("GLX_SGIS_blended_overlay"); +#endif /* GLX_SGIS_blended_overlay */ +#ifdef GLX_SGIS_color_range + GLXEW_SGIS_color_range = glxewGetExtension("GLX_SGIS_color_range"); +#endif /* GLX_SGIS_color_range */ +#ifdef GLX_SGIS_multisample + GLXEW_SGIS_multisample = glxewGetExtension("GLX_SGIS_multisample"); +#endif /* GLX_SGIS_multisample */ +#ifdef GLX_SGIS_shared_multisample + GLXEW_SGIS_shared_multisample = glxewGetExtension("GLX_SGIS_shared_multisample"); +#endif /* GLX_SGIS_shared_multisample */ +#ifdef GLX_SGIX_fbconfig + GLXEW_SGIX_fbconfig = glxewGetExtension("GLX_SGIX_fbconfig"); + if (glewExperimental || GLXEW_SGIX_fbconfig) GLXEW_SGIX_fbconfig = !_glewInit_GLX_SGIX_fbconfig(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GLX_SGIX_fbconfig */ +#ifdef GLX_SGIX_pbuffer + GLXEW_SGIX_pbuffer = glxewGetExtension("GLX_SGIX_pbuffer"); + if (glewExperimental || GLXEW_SGIX_pbuffer) GLXEW_SGIX_pbuffer = !_glewInit_GLX_SGIX_pbuffer(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GLX_SGIX_pbuffer */ +#ifdef GLX_SGIX_swap_barrier + GLXEW_SGIX_swap_barrier = glxewGetExtension("GLX_SGIX_swap_barrier"); + if (glewExperimental || GLXEW_SGIX_swap_barrier) GLXEW_SGIX_swap_barrier = !_glewInit_GLX_SGIX_swap_barrier(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GLX_SGIX_swap_barrier */ +#ifdef GLX_SGIX_swap_group + GLXEW_SGIX_swap_group = glxewGetExtension("GLX_SGIX_swap_group"); + if (glewExperimental || GLXEW_SGIX_swap_group) GLXEW_SGIX_swap_group = !_glewInit_GLX_SGIX_swap_group(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GLX_SGIX_swap_group */ +#ifdef GLX_SGIX_video_resize + GLXEW_SGIX_video_resize = glxewGetExtension("GLX_SGIX_video_resize"); + if (glewExperimental || GLXEW_SGIX_video_resize) GLXEW_SGIX_video_resize = !_glewInit_GLX_SGIX_video_resize(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GLX_SGIX_video_resize */ +#ifdef GLX_SGIX_visual_select_group + GLXEW_SGIX_visual_select_group = glxewGetExtension("GLX_SGIX_visual_select_group"); +#endif /* GLX_SGIX_visual_select_group */ +#ifdef GLX_SGI_cushion + GLXEW_SGI_cushion = glxewGetExtension("GLX_SGI_cushion"); + if (glewExperimental || GLXEW_SGI_cushion) GLXEW_SGI_cushion = !_glewInit_GLX_SGI_cushion(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GLX_SGI_cushion */ +#ifdef GLX_SGI_make_current_read + GLXEW_SGI_make_current_read = glxewGetExtension("GLX_SGI_make_current_read"); + if (glewExperimental || GLXEW_SGI_make_current_read) GLXEW_SGI_make_current_read = !_glewInit_GLX_SGI_make_current_read(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GLX_SGI_make_current_read */ +#ifdef GLX_SGI_swap_control + GLXEW_SGI_swap_control = glxewGetExtension("GLX_SGI_swap_control"); + if (glewExperimental || GLXEW_SGI_swap_control) GLXEW_SGI_swap_control = !_glewInit_GLX_SGI_swap_control(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GLX_SGI_swap_control */ +#ifdef GLX_SGI_video_sync + GLXEW_SGI_video_sync = glxewGetExtension("GLX_SGI_video_sync"); + if (glewExperimental || GLXEW_SGI_video_sync) GLXEW_SGI_video_sync = !_glewInit_GLX_SGI_video_sync(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GLX_SGI_video_sync */ +#ifdef GLX_SUN_get_transparent_index + GLXEW_SUN_get_transparent_index = glxewGetExtension("GLX_SUN_get_transparent_index"); + if (glewExperimental || GLXEW_SUN_get_transparent_index) GLXEW_SUN_get_transparent_index = !_glewInit_GLX_SUN_get_transparent_index(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GLX_SUN_get_transparent_index */ +#ifdef GLX_SUN_video_resize + GLXEW_SUN_video_resize = glxewGetExtension("GLX_SUN_video_resize"); + if (glewExperimental || GLXEW_SUN_video_resize) GLXEW_SUN_video_resize = !_glewInit_GLX_SUN_video_resize(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GLX_SUN_video_resize */ + + return GLEW_OK; +} + +#endif /* !__APPLE__ || GLEW_APPLE_GLX */ + +/* ------------------------------------------------------------------------ */ + +const GLubyte* glewGetErrorString (GLenum error) +{ + static const GLubyte* _glewErrorString[] = + { + (const GLubyte*)"No error", + (const GLubyte*)"Missing GL version", + (const GLubyte*)"GL 1.1 and up are not supported", + (const GLubyte*)"GLX 1.2 and up are not supported", + (const GLubyte*)"Unknown error" + }; + const int max_error = sizeof(_glewErrorString)/sizeof(*_glewErrorString) - 1; + return _glewErrorString[(int)error > max_error ? max_error : (int)error]; +} + +const GLubyte* glewGetString (GLenum name) +{ + static const GLubyte* _glewString[] = + { + (const GLubyte*)NULL, + (const GLubyte*)"1.3.4" + }; + const int max_string = sizeof(_glewString)/sizeof(*_glewString) - 1; + return _glewString[(int)name > max_string ? 0 : (int)name]; +} + +/* ------------------------------------------------------------------------ */ + +GLboolean glewExperimental = GL_FALSE; + +#if !defined(GLEW_MX) + +#if defined(_WIN32) +extern GLenum wglewContextInit (void); +#elif !defined(__APPLE__) || defined(GLEW_APPLE_GLX) /* _UNIX */ +extern GLenum glxewContextInit (void); +#endif /* _WIN32 */ + +GLenum glewInit () +{ + GLenum r; + if ( (r = glewContextInit()) ) return r; +#if defined(_WIN32) + return wglewContextInit(); +#elif !defined(__APPLE__) || defined(GLEW_APPLE_GLX) /* _UNIX */ + return glxewContextInit(); +#else + return r; +#endif /* _WIN32 */ +} + +#endif /* !GLEW_MX */ +#ifdef GLEW_MX +GLboolean glewContextIsSupported (GLEWContext* ctx, const char* name) +#else +GLboolean glewIsSupported (const char* name) +#endif +{ + GLubyte* pos = (GLubyte*)name; + GLuint len = _glewStrLen(pos); + GLboolean ret = GL_TRUE; + while (ret && len > 0) + { + if (_glewStrSame1(&pos, &len, (const GLubyte*)"GL_", 3)) + { + if (_glewStrSame2(&pos, &len, (const GLubyte*)"VERSION_", 8)) + { +#ifdef GL_VERSION_1_2 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"1_2", 3)) + { + ret = GLEW_VERSION_1_2; + continue; + } +#endif +#ifdef GL_VERSION_1_3 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"1_3", 3)) + { + ret = GLEW_VERSION_1_3; + continue; + } +#endif +#ifdef GL_VERSION_1_4 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"1_4", 3)) + { + ret = GLEW_VERSION_1_4; + continue; + } +#endif +#ifdef GL_VERSION_1_5 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"1_5", 3)) + { + ret = GLEW_VERSION_1_5; + continue; + } +#endif +#ifdef GL_VERSION_2_0 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"2_0", 3)) + { + ret = GLEW_VERSION_2_0; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"3DFX_", 5)) + { +#ifdef GL_3DFX_multisample + if (_glewStrSame3(&pos, &len, (const GLubyte*)"multisample", 11)) + { + ret = GLEW_3DFX_multisample; + continue; + } +#endif +#ifdef GL_3DFX_tbuffer + if (_glewStrSame3(&pos, &len, (const GLubyte*)"tbuffer", 7)) + { + ret = GLEW_3DFX_tbuffer; + continue; + } +#endif +#ifdef GL_3DFX_texture_compression_FXT1 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_compression_FXT1", 24)) + { + ret = GLEW_3DFX_texture_compression_FXT1; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"APPLE_", 6)) + { +#ifdef GL_APPLE_client_storage + if (_glewStrSame3(&pos, &len, (const GLubyte*)"client_storage", 14)) + { + ret = GLEW_APPLE_client_storage; + continue; + } +#endif +#ifdef GL_APPLE_element_array + if (_glewStrSame3(&pos, &len, (const GLubyte*)"element_array", 13)) + { + ret = GLEW_APPLE_element_array; + continue; + } +#endif +#ifdef GL_APPLE_fence + if (_glewStrSame3(&pos, &len, (const GLubyte*)"fence", 5)) + { + ret = GLEW_APPLE_fence; + continue; + } +#endif +#ifdef GL_APPLE_float_pixels + if (_glewStrSame3(&pos, &len, (const GLubyte*)"float_pixels", 12)) + { + ret = GLEW_APPLE_float_pixels; + continue; + } +#endif +#ifdef GL_APPLE_pixel_buffer + if (_glewStrSame3(&pos, &len, (const GLubyte*)"pixel_buffer", 12)) + { + ret = GLEW_APPLE_pixel_buffer; + continue; + } +#endif +#ifdef GL_APPLE_specular_vector + if (_glewStrSame3(&pos, &len, (const GLubyte*)"specular_vector", 15)) + { + ret = GLEW_APPLE_specular_vector; + continue; + } +#endif +#ifdef GL_APPLE_texture_range + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_range", 13)) + { + ret = GLEW_APPLE_texture_range; + continue; + } +#endif +#ifdef GL_APPLE_transform_hint + if (_glewStrSame3(&pos, &len, (const GLubyte*)"transform_hint", 14)) + { + ret = GLEW_APPLE_transform_hint; + continue; + } +#endif +#ifdef GL_APPLE_vertex_array_object + if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_array_object", 19)) + { + ret = GLEW_APPLE_vertex_array_object; + continue; + } +#endif +#ifdef GL_APPLE_vertex_array_range + if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_array_range", 18)) + { + ret = GLEW_APPLE_vertex_array_range; + continue; + } +#endif +#ifdef GL_APPLE_ycbcr_422 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"ycbcr_422", 9)) + { + ret = GLEW_APPLE_ycbcr_422; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"ARB_", 4)) + { +#ifdef GL_ARB_color_buffer_float + if (_glewStrSame3(&pos, &len, (const GLubyte*)"color_buffer_float", 18)) + { + ret = GLEW_ARB_color_buffer_float; + continue; + } +#endif +#ifdef GL_ARB_depth_texture + if (_glewStrSame3(&pos, &len, (const GLubyte*)"depth_texture", 13)) + { + ret = GLEW_ARB_depth_texture; + continue; + } +#endif +#ifdef GL_ARB_draw_buffers + if (_glewStrSame3(&pos, &len, (const GLubyte*)"draw_buffers", 12)) + { + ret = GLEW_ARB_draw_buffers; + continue; + } +#endif +#ifdef GL_ARB_fragment_program + if (_glewStrSame3(&pos, &len, (const GLubyte*)"fragment_program", 16)) + { + ret = GLEW_ARB_fragment_program; + continue; + } +#endif +#ifdef GL_ARB_fragment_program_shadow + if (_glewStrSame3(&pos, &len, (const GLubyte*)"fragment_program_shadow", 23)) + { + ret = GLEW_ARB_fragment_program_shadow; + continue; + } +#endif +#ifdef GL_ARB_fragment_shader + if (_glewStrSame3(&pos, &len, (const GLubyte*)"fragment_shader", 15)) + { + ret = GLEW_ARB_fragment_shader; + continue; + } +#endif +#ifdef GL_ARB_half_float_pixel + if (_glewStrSame3(&pos, &len, (const GLubyte*)"half_float_pixel", 16)) + { + ret = GLEW_ARB_half_float_pixel; + continue; + } +#endif +#ifdef GL_ARB_imaging + if (_glewStrSame3(&pos, &len, (const GLubyte*)"imaging", 7)) + { + ret = GLEW_ARB_imaging; + continue; + } +#endif +#ifdef GL_ARB_matrix_palette + if (_glewStrSame3(&pos, &len, (const GLubyte*)"matrix_palette", 14)) + { + ret = GLEW_ARB_matrix_palette; + continue; + } +#endif +#ifdef GL_ARB_multisample + if (_glewStrSame3(&pos, &len, (const GLubyte*)"multisample", 11)) + { + ret = GLEW_ARB_multisample; + continue; + } +#endif +#ifdef GL_ARB_multitexture + if (_glewStrSame3(&pos, &len, (const GLubyte*)"multitexture", 12)) + { + ret = GLEW_ARB_multitexture; + continue; + } +#endif +#ifdef GL_ARB_occlusion_query + if (_glewStrSame3(&pos, &len, (const GLubyte*)"occlusion_query", 15)) + { + ret = GLEW_ARB_occlusion_query; + continue; + } +#endif +#ifdef GL_ARB_pixel_buffer_object + if (_glewStrSame3(&pos, &len, (const GLubyte*)"pixel_buffer_object", 19)) + { + ret = GLEW_ARB_pixel_buffer_object; + continue; + } +#endif +#ifdef GL_ARB_point_parameters + if (_glewStrSame3(&pos, &len, (const GLubyte*)"point_parameters", 16)) + { + ret = GLEW_ARB_point_parameters; + continue; + } +#endif +#ifdef GL_ARB_point_sprite + if (_glewStrSame3(&pos, &len, (const GLubyte*)"point_sprite", 12)) + { + ret = GLEW_ARB_point_sprite; + continue; + } +#endif +#ifdef GL_ARB_shader_objects + if (_glewStrSame3(&pos, &len, (const GLubyte*)"shader_objects", 14)) + { + ret = GLEW_ARB_shader_objects; + continue; + } +#endif +#ifdef GL_ARB_shading_language_100 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"shading_language_100", 20)) + { + ret = GLEW_ARB_shading_language_100; + continue; + } +#endif +#ifdef GL_ARB_shadow + if (_glewStrSame3(&pos, &len, (const GLubyte*)"shadow", 6)) + { + ret = GLEW_ARB_shadow; + continue; + } +#endif +#ifdef GL_ARB_shadow_ambient + if (_glewStrSame3(&pos, &len, (const GLubyte*)"shadow_ambient", 14)) + { + ret = GLEW_ARB_shadow_ambient; + continue; + } +#endif +#ifdef GL_ARB_texture_border_clamp + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_border_clamp", 20)) + { + ret = GLEW_ARB_texture_border_clamp; + continue; + } +#endif +#ifdef GL_ARB_texture_compression + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_compression", 19)) + { + ret = GLEW_ARB_texture_compression; + continue; + } +#endif +#ifdef GL_ARB_texture_cube_map + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_cube_map", 16)) + { + ret = GLEW_ARB_texture_cube_map; + continue; + } +#endif +#ifdef GL_ARB_texture_env_add + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_env_add", 15)) + { + ret = GLEW_ARB_texture_env_add; + continue; + } +#endif +#ifdef GL_ARB_texture_env_combine + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_env_combine", 19)) + { + ret = GLEW_ARB_texture_env_combine; + continue; + } +#endif +#ifdef GL_ARB_texture_env_crossbar + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_env_crossbar", 20)) + { + ret = GLEW_ARB_texture_env_crossbar; + continue; + } +#endif +#ifdef GL_ARB_texture_env_dot3 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_env_dot3", 16)) + { + ret = GLEW_ARB_texture_env_dot3; + continue; + } +#endif +#ifdef GL_ARB_texture_float + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_float", 13)) + { + ret = GLEW_ARB_texture_float; + continue; + } +#endif +#ifdef GL_ARB_texture_mirrored_repeat + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_mirrored_repeat", 23)) + { + ret = GLEW_ARB_texture_mirrored_repeat; + continue; + } +#endif +#ifdef GL_ARB_texture_non_power_of_two + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_non_power_of_two", 24)) + { + ret = GLEW_ARB_texture_non_power_of_two; + continue; + } +#endif +#ifdef GL_ARB_texture_rectangle + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_rectangle", 17)) + { + ret = GLEW_ARB_texture_rectangle; + continue; + } +#endif +#ifdef GL_ARB_transpose_matrix + if (_glewStrSame3(&pos, &len, (const GLubyte*)"transpose_matrix", 16)) + { + ret = GLEW_ARB_transpose_matrix; + continue; + } +#endif +#ifdef GL_ARB_vertex_blend + if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_blend", 12)) + { + ret = GLEW_ARB_vertex_blend; + continue; + } +#endif +#ifdef GL_ARB_vertex_buffer_object + if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_buffer_object", 20)) + { + ret = GLEW_ARB_vertex_buffer_object; + continue; + } +#endif +#ifdef GL_ARB_vertex_program + if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_program", 14)) + { + ret = GLEW_ARB_vertex_program; + continue; + } +#endif +#ifdef GL_ARB_vertex_shader + if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_shader", 13)) + { + ret = GLEW_ARB_vertex_shader; + continue; + } +#endif +#ifdef GL_ARB_window_pos + if (_glewStrSame3(&pos, &len, (const GLubyte*)"window_pos", 10)) + { + ret = GLEW_ARB_window_pos; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"ATIX_", 5)) + { +#ifdef GL_ATIX_point_sprites + if (_glewStrSame3(&pos, &len, (const GLubyte*)"point_sprites", 13)) + { + ret = GLEW_ATIX_point_sprites; + continue; + } +#endif +#ifdef GL_ATIX_texture_env_combine3 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_env_combine3", 20)) + { + ret = GLEW_ATIX_texture_env_combine3; + continue; + } +#endif +#ifdef GL_ATIX_texture_env_route + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_env_route", 17)) + { + ret = GLEW_ATIX_texture_env_route; + continue; + } +#endif +#ifdef GL_ATIX_vertex_shader_output_point_size + if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_shader_output_point_size", 31)) + { + ret = GLEW_ATIX_vertex_shader_output_point_size; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"ATI_", 4)) + { +#ifdef GL_ATI_draw_buffers + if (_glewStrSame3(&pos, &len, (const GLubyte*)"draw_buffers", 12)) + { + ret = GLEW_ATI_draw_buffers; + continue; + } +#endif +#ifdef GL_ATI_element_array + if (_glewStrSame3(&pos, &len, (const GLubyte*)"element_array", 13)) + { + ret = GLEW_ATI_element_array; + continue; + } +#endif +#ifdef GL_ATI_envmap_bumpmap + if (_glewStrSame3(&pos, &len, (const GLubyte*)"envmap_bumpmap", 14)) + { + ret = GLEW_ATI_envmap_bumpmap; + continue; + } +#endif +#ifdef GL_ATI_fragment_shader + if (_glewStrSame3(&pos, &len, (const GLubyte*)"fragment_shader", 15)) + { + ret = GLEW_ATI_fragment_shader; + continue; + } +#endif +#ifdef GL_ATI_map_object_buffer + if (_glewStrSame3(&pos, &len, (const GLubyte*)"map_object_buffer", 17)) + { + ret = GLEW_ATI_map_object_buffer; + continue; + } +#endif +#ifdef GL_ATI_pn_triangles + if (_glewStrSame3(&pos, &len, (const GLubyte*)"pn_triangles", 12)) + { + ret = GLEW_ATI_pn_triangles; + continue; + } +#endif +#ifdef GL_ATI_separate_stencil + if (_glewStrSame3(&pos, &len, (const GLubyte*)"separate_stencil", 16)) + { + ret = GLEW_ATI_separate_stencil; + continue; + } +#endif +#ifdef GL_ATI_text_fragment_shader + if (_glewStrSame3(&pos, &len, (const GLubyte*)"text_fragment_shader", 20)) + { + ret = GLEW_ATI_text_fragment_shader; + continue; + } +#endif +#ifdef GL_ATI_texture_compression_3dc + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_compression_3dc", 23)) + { + ret = GLEW_ATI_texture_compression_3dc; + continue; + } +#endif +#ifdef GL_ATI_texture_env_combine3 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_env_combine3", 20)) + { + ret = GLEW_ATI_texture_env_combine3; + continue; + } +#endif +#ifdef GL_ATI_texture_float + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_float", 13)) + { + ret = GLEW_ATI_texture_float; + continue; + } +#endif +#ifdef GL_ATI_texture_mirror_once + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_mirror_once", 19)) + { + ret = GLEW_ATI_texture_mirror_once; + continue; + } +#endif +#ifdef GL_ATI_vertex_array_object + if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_array_object", 19)) + { + ret = GLEW_ATI_vertex_array_object; + continue; + } +#endif +#ifdef GL_ATI_vertex_attrib_array_object + if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_attrib_array_object", 26)) + { + ret = GLEW_ATI_vertex_attrib_array_object; + continue; + } +#endif +#ifdef GL_ATI_vertex_streams + if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_streams", 14)) + { + ret = GLEW_ATI_vertex_streams; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"EXT_", 4)) + { +#ifdef GL_EXT_422_pixels + if (_glewStrSame3(&pos, &len, (const GLubyte*)"422_pixels", 10)) + { + ret = GLEW_EXT_422_pixels; + continue; + } +#endif +#ifdef GL_EXT_Cg_shader + if (_glewStrSame3(&pos, &len, (const GLubyte*)"Cg_shader", 9)) + { + ret = GLEW_EXT_Cg_shader; + continue; + } +#endif +#ifdef GL_EXT_abgr + if (_glewStrSame3(&pos, &len, (const GLubyte*)"abgr", 4)) + { + ret = GLEW_EXT_abgr; + continue; + } +#endif +#ifdef GL_EXT_bgra + if (_glewStrSame3(&pos, &len, (const GLubyte*)"bgra", 4)) + { + ret = GLEW_EXT_bgra; + continue; + } +#endif +#ifdef GL_EXT_blend_color + if (_glewStrSame3(&pos, &len, (const GLubyte*)"blend_color", 11)) + { + ret = GLEW_EXT_blend_color; + continue; + } +#endif +#ifdef GL_EXT_blend_equation_separate + if (_glewStrSame3(&pos, &len, (const GLubyte*)"blend_equation_separate", 23)) + { + ret = GLEW_EXT_blend_equation_separate; + continue; + } +#endif +#ifdef GL_EXT_blend_func_separate + if (_glewStrSame3(&pos, &len, (const GLubyte*)"blend_func_separate", 19)) + { + ret = GLEW_EXT_blend_func_separate; + continue; + } +#endif +#ifdef GL_EXT_blend_logic_op + if (_glewStrSame3(&pos, &len, (const GLubyte*)"blend_logic_op", 14)) + { + ret = GLEW_EXT_blend_logic_op; + continue; + } +#endif +#ifdef GL_EXT_blend_minmax + if (_glewStrSame3(&pos, &len, (const GLubyte*)"blend_minmax", 12)) + { + ret = GLEW_EXT_blend_minmax; + continue; + } +#endif +#ifdef GL_EXT_blend_subtract + if (_glewStrSame3(&pos, &len, (const GLubyte*)"blend_subtract", 14)) + { + ret = GLEW_EXT_blend_subtract; + continue; + } +#endif +#ifdef GL_EXT_clip_volume_hint + if (_glewStrSame3(&pos, &len, (const GLubyte*)"clip_volume_hint", 16)) + { + ret = GLEW_EXT_clip_volume_hint; + continue; + } +#endif +#ifdef GL_EXT_cmyka + if (_glewStrSame3(&pos, &len, (const GLubyte*)"cmyka", 5)) + { + ret = GLEW_EXT_cmyka; + continue; + } +#endif +#ifdef GL_EXT_color_subtable + if (_glewStrSame3(&pos, &len, (const GLubyte*)"color_subtable", 14)) + { + ret = GLEW_EXT_color_subtable; + continue; + } +#endif +#ifdef GL_EXT_compiled_vertex_array + if (_glewStrSame3(&pos, &len, (const GLubyte*)"compiled_vertex_array", 21)) + { + ret = GLEW_EXT_compiled_vertex_array; + continue; + } +#endif +#ifdef GL_EXT_convolution + if (_glewStrSame3(&pos, &len, (const GLubyte*)"convolution", 11)) + { + ret = GLEW_EXT_convolution; + continue; + } +#endif +#ifdef GL_EXT_coordinate_frame + if (_glewStrSame3(&pos, &len, (const GLubyte*)"coordinate_frame", 16)) + { + ret = GLEW_EXT_coordinate_frame; + continue; + } +#endif +#ifdef GL_EXT_copy_texture + if (_glewStrSame3(&pos, &len, (const GLubyte*)"copy_texture", 12)) + { + ret = GLEW_EXT_copy_texture; + continue; + } +#endif +#ifdef GL_EXT_cull_vertex + if (_glewStrSame3(&pos, &len, (const GLubyte*)"cull_vertex", 11)) + { + ret = GLEW_EXT_cull_vertex; + continue; + } +#endif +#ifdef GL_EXT_depth_bounds_test + if (_glewStrSame3(&pos, &len, (const GLubyte*)"depth_bounds_test", 17)) + { + ret = GLEW_EXT_depth_bounds_test; + continue; + } +#endif +#ifdef GL_EXT_draw_range_elements + if (_glewStrSame3(&pos, &len, (const GLubyte*)"draw_range_elements", 19)) + { + ret = GLEW_EXT_draw_range_elements; + continue; + } +#endif +#ifdef GL_EXT_fog_coord + if (_glewStrSame3(&pos, &len, (const GLubyte*)"fog_coord", 9)) + { + ret = GLEW_EXT_fog_coord; + continue; + } +#endif +#ifdef GL_EXT_fragment_lighting + if (_glewStrSame3(&pos, &len, (const GLubyte*)"fragment_lighting", 17)) + { + ret = GLEW_EXT_fragment_lighting; + continue; + } +#endif +#ifdef GL_EXT_framebuffer_blit + if (_glewStrSame3(&pos, &len, (const GLubyte*)"framebuffer_blit", 16)) + { + ret = GLEW_EXT_framebuffer_blit; + continue; + } +#endif +#ifdef GL_EXT_framebuffer_multisample + if (_glewStrSame3(&pos, &len, (const GLubyte*)"framebuffer_multisample", 23)) + { + ret = GLEW_EXT_framebuffer_multisample; + continue; + } +#endif +#ifdef GL_EXT_framebuffer_object + if (_glewStrSame3(&pos, &len, (const GLubyte*)"framebuffer_object", 18)) + { + ret = GLEW_EXT_framebuffer_object; + continue; + } +#endif +#ifdef GL_EXT_histogram + if (_glewStrSame3(&pos, &len, (const GLubyte*)"histogram", 9)) + { + ret = GLEW_EXT_histogram; + continue; + } +#endif +#ifdef GL_EXT_index_array_formats + if (_glewStrSame3(&pos, &len, (const GLubyte*)"index_array_formats", 19)) + { + ret = GLEW_EXT_index_array_formats; + continue; + } +#endif +#ifdef GL_EXT_index_func + if (_glewStrSame3(&pos, &len, (const GLubyte*)"index_func", 10)) + { + ret = GLEW_EXT_index_func; + continue; + } +#endif +#ifdef GL_EXT_index_material + if (_glewStrSame3(&pos, &len, (const GLubyte*)"index_material", 14)) + { + ret = GLEW_EXT_index_material; + continue; + } +#endif +#ifdef GL_EXT_index_texture + if (_glewStrSame3(&pos, &len, (const GLubyte*)"index_texture", 13)) + { + ret = GLEW_EXT_index_texture; + continue; + } +#endif +#ifdef GL_EXT_light_texture + if (_glewStrSame3(&pos, &len, (const GLubyte*)"light_texture", 13)) + { + ret = GLEW_EXT_light_texture; + continue; + } +#endif +#ifdef GL_EXT_misc_attribute + if (_glewStrSame3(&pos, &len, (const GLubyte*)"misc_attribute", 14)) + { + ret = GLEW_EXT_misc_attribute; + continue; + } +#endif +#ifdef GL_EXT_multi_draw_arrays + if (_glewStrSame3(&pos, &len, (const GLubyte*)"multi_draw_arrays", 17)) + { + ret = GLEW_EXT_multi_draw_arrays; + continue; + } +#endif +#ifdef GL_EXT_multisample + if (_glewStrSame3(&pos, &len, (const GLubyte*)"multisample", 11)) + { + ret = GLEW_EXT_multisample; + continue; + } +#endif +#ifdef GL_EXT_packed_depth_stencil + if (_glewStrSame3(&pos, &len, (const GLubyte*)"packed_depth_stencil", 20)) + { + ret = GLEW_EXT_packed_depth_stencil; + continue; + } +#endif +#ifdef GL_EXT_packed_pixels + if (_glewStrSame3(&pos, &len, (const GLubyte*)"packed_pixels", 13)) + { + ret = GLEW_EXT_packed_pixels; + continue; + } +#endif +#ifdef GL_EXT_paletted_texture + if (_glewStrSame3(&pos, &len, (const GLubyte*)"paletted_texture", 16)) + { + ret = GLEW_EXT_paletted_texture; + continue; + } +#endif +#ifdef GL_EXT_pixel_buffer_object + if (_glewStrSame3(&pos, &len, (const GLubyte*)"pixel_buffer_object", 19)) + { + ret = GLEW_EXT_pixel_buffer_object; + continue; + } +#endif +#ifdef GL_EXT_pixel_transform + if (_glewStrSame3(&pos, &len, (const GLubyte*)"pixel_transform", 15)) + { + ret = GLEW_EXT_pixel_transform; + continue; + } +#endif +#ifdef GL_EXT_pixel_transform_color_table + if (_glewStrSame3(&pos, &len, (const GLubyte*)"pixel_transform_color_table", 27)) + { + ret = GLEW_EXT_pixel_transform_color_table; + continue; + } +#endif +#ifdef GL_EXT_point_parameters + if (_glewStrSame3(&pos, &len, (const GLubyte*)"point_parameters", 16)) + { + ret = GLEW_EXT_point_parameters; + continue; + } +#endif +#ifdef GL_EXT_polygon_offset + if (_glewStrSame3(&pos, &len, (const GLubyte*)"polygon_offset", 14)) + { + ret = GLEW_EXT_polygon_offset; + continue; + } +#endif +#ifdef GL_EXT_rescale_normal + if (_glewStrSame3(&pos, &len, (const GLubyte*)"rescale_normal", 14)) + { + ret = GLEW_EXT_rescale_normal; + continue; + } +#endif +#ifdef GL_EXT_scene_marker + if (_glewStrSame3(&pos, &len, (const GLubyte*)"scene_marker", 12)) + { + ret = GLEW_EXT_scene_marker; + continue; + } +#endif +#ifdef GL_EXT_secondary_color + if (_glewStrSame3(&pos, &len, (const GLubyte*)"secondary_color", 15)) + { + ret = GLEW_EXT_secondary_color; + continue; + } +#endif +#ifdef GL_EXT_separate_specular_color + if (_glewStrSame3(&pos, &len, (const GLubyte*)"separate_specular_color", 23)) + { + ret = GLEW_EXT_separate_specular_color; + continue; + } +#endif +#ifdef GL_EXT_shadow_funcs + if (_glewStrSame3(&pos, &len, (const GLubyte*)"shadow_funcs", 12)) + { + ret = GLEW_EXT_shadow_funcs; + continue; + } +#endif +#ifdef GL_EXT_shared_texture_palette + if (_glewStrSame3(&pos, &len, (const GLubyte*)"shared_texture_palette", 22)) + { + ret = GLEW_EXT_shared_texture_palette; + continue; + } +#endif +#ifdef GL_EXT_stencil_clear_tag + if (_glewStrSame3(&pos, &len, (const GLubyte*)"stencil_clear_tag", 17)) + { + ret = GLEW_EXT_stencil_clear_tag; + continue; + } +#endif +#ifdef GL_EXT_stencil_two_side + if (_glewStrSame3(&pos, &len, (const GLubyte*)"stencil_two_side", 16)) + { + ret = GLEW_EXT_stencil_two_side; + continue; + } +#endif +#ifdef GL_EXT_stencil_wrap + if (_glewStrSame3(&pos, &len, (const GLubyte*)"stencil_wrap", 12)) + { + ret = GLEW_EXT_stencil_wrap; + continue; + } +#endif +#ifdef GL_EXT_subtexture + if (_glewStrSame3(&pos, &len, (const GLubyte*)"subtexture", 10)) + { + ret = GLEW_EXT_subtexture; + continue; + } +#endif +#ifdef GL_EXT_texture + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture", 7)) + { + ret = GLEW_EXT_texture; + continue; + } +#endif +#ifdef GL_EXT_texture3D + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture3D", 9)) + { + ret = GLEW_EXT_texture3D; + continue; + } +#endif +#ifdef GL_EXT_texture_compression_dxt1 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_compression_dxt1", 24)) + { + ret = GLEW_EXT_texture_compression_dxt1; + continue; + } +#endif +#ifdef GL_EXT_texture_compression_s3tc + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_compression_s3tc", 24)) + { + ret = GLEW_EXT_texture_compression_s3tc; + continue; + } +#endif +#ifdef GL_EXT_texture_cube_map + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_cube_map", 16)) + { + ret = GLEW_EXT_texture_cube_map; + continue; + } +#endif +#ifdef GL_EXT_texture_edge_clamp + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_edge_clamp", 18)) + { + ret = GLEW_EXT_texture_edge_clamp; + continue; + } +#endif +#ifdef GL_EXT_texture_env + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_env", 11)) + { + ret = GLEW_EXT_texture_env; + continue; + } +#endif +#ifdef GL_EXT_texture_env_add + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_env_add", 15)) + { + ret = GLEW_EXT_texture_env_add; + continue; + } +#endif +#ifdef GL_EXT_texture_env_combine + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_env_combine", 19)) + { + ret = GLEW_EXT_texture_env_combine; + continue; + } +#endif +#ifdef GL_EXT_texture_env_dot3 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_env_dot3", 16)) + { + ret = GLEW_EXT_texture_env_dot3; + continue; + } +#endif +#ifdef GL_EXT_texture_filter_anisotropic + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_filter_anisotropic", 26)) + { + ret = GLEW_EXT_texture_filter_anisotropic; + continue; + } +#endif +#ifdef GL_EXT_texture_lod_bias + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_lod_bias", 16)) + { + ret = GLEW_EXT_texture_lod_bias; + continue; + } +#endif +#ifdef GL_EXT_texture_mirror_clamp + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_mirror_clamp", 20)) + { + ret = GLEW_EXT_texture_mirror_clamp; + continue; + } +#endif +#ifdef GL_EXT_texture_object + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_object", 14)) + { + ret = GLEW_EXT_texture_object; + continue; + } +#endif +#ifdef GL_EXT_texture_perturb_normal + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_perturb_normal", 22)) + { + ret = GLEW_EXT_texture_perturb_normal; + continue; + } +#endif +#ifdef GL_EXT_texture_rectangle + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_rectangle", 17)) + { + ret = GLEW_EXT_texture_rectangle; + continue; + } +#endif +#ifdef GL_EXT_texture_sRGB + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_sRGB", 12)) + { + ret = GLEW_EXT_texture_sRGB; + continue; + } +#endif +#ifdef GL_EXT_vertex_array + if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_array", 12)) + { + ret = GLEW_EXT_vertex_array; + continue; + } +#endif +#ifdef GL_EXT_vertex_shader + if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_shader", 13)) + { + ret = GLEW_EXT_vertex_shader; + continue; + } +#endif +#ifdef GL_EXT_vertex_weighting + if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_weighting", 16)) + { + ret = GLEW_EXT_vertex_weighting; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"GREMEDY_", 8)) + { +#ifdef GL_GREMEDY_string_marker + if (_glewStrSame3(&pos, &len, (const GLubyte*)"string_marker", 13)) + { + ret = GLEW_GREMEDY_string_marker; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"HP_", 3)) + { +#ifdef GL_HP_convolution_border_modes + if (_glewStrSame3(&pos, &len, (const GLubyte*)"convolution_border_modes", 24)) + { + ret = GLEW_HP_convolution_border_modes; + continue; + } +#endif +#ifdef GL_HP_image_transform + if (_glewStrSame3(&pos, &len, (const GLubyte*)"image_transform", 15)) + { + ret = GLEW_HP_image_transform; + continue; + } +#endif +#ifdef GL_HP_occlusion_test + if (_glewStrSame3(&pos, &len, (const GLubyte*)"occlusion_test", 14)) + { + ret = GLEW_HP_occlusion_test; + continue; + } +#endif +#ifdef GL_HP_texture_lighting + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_lighting", 16)) + { + ret = GLEW_HP_texture_lighting; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"IBM_", 4)) + { +#ifdef GL_IBM_cull_vertex + if (_glewStrSame3(&pos, &len, (const GLubyte*)"cull_vertex", 11)) + { + ret = GLEW_IBM_cull_vertex; + continue; + } +#endif +#ifdef GL_IBM_multimode_draw_arrays + if (_glewStrSame3(&pos, &len, (const GLubyte*)"multimode_draw_arrays", 21)) + { + ret = GLEW_IBM_multimode_draw_arrays; + continue; + } +#endif +#ifdef GL_IBM_rasterpos_clip + if (_glewStrSame3(&pos, &len, (const GLubyte*)"rasterpos_clip", 14)) + { + ret = GLEW_IBM_rasterpos_clip; + continue; + } +#endif +#ifdef GL_IBM_static_data + if (_glewStrSame3(&pos, &len, (const GLubyte*)"static_data", 11)) + { + ret = GLEW_IBM_static_data; + continue; + } +#endif +#ifdef GL_IBM_texture_mirrored_repeat + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_mirrored_repeat", 23)) + { + ret = GLEW_IBM_texture_mirrored_repeat; + continue; + } +#endif +#ifdef GL_IBM_vertex_array_lists + if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_array_lists", 18)) + { + ret = GLEW_IBM_vertex_array_lists; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"INGR_", 5)) + { +#ifdef GL_INGR_color_clamp + if (_glewStrSame3(&pos, &len, (const GLubyte*)"color_clamp", 11)) + { + ret = GLEW_INGR_color_clamp; + continue; + } +#endif +#ifdef GL_INGR_interlace_read + if (_glewStrSame3(&pos, &len, (const GLubyte*)"interlace_read", 14)) + { + ret = GLEW_INGR_interlace_read; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"INTEL_", 6)) + { +#ifdef GL_INTEL_parallel_arrays + if (_glewStrSame3(&pos, &len, (const GLubyte*)"parallel_arrays", 15)) + { + ret = GLEW_INTEL_parallel_arrays; + continue; + } +#endif +#ifdef GL_INTEL_texture_scissor + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_scissor", 15)) + { + ret = GLEW_INTEL_texture_scissor; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"KTX_", 4)) + { +#ifdef GL_KTX_buffer_region + if (_glewStrSame3(&pos, &len, (const GLubyte*)"buffer_region", 13)) + { + ret = GLEW_KTX_buffer_region; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"MESAX_", 6)) + { +#ifdef GL_MESAX_texture_stack + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_stack", 13)) + { + ret = GLEW_MESAX_texture_stack; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"MESA_", 5)) + { +#ifdef GL_MESA_pack_invert + if (_glewStrSame3(&pos, &len, (const GLubyte*)"pack_invert", 11)) + { + ret = GLEW_MESA_pack_invert; + continue; + } +#endif +#ifdef GL_MESA_resize_buffers + if (_glewStrSame3(&pos, &len, (const GLubyte*)"resize_buffers", 14)) + { + ret = GLEW_MESA_resize_buffers; + continue; + } +#endif +#ifdef GL_MESA_window_pos + if (_glewStrSame3(&pos, &len, (const GLubyte*)"window_pos", 10)) + { + ret = GLEW_MESA_window_pos; + continue; + } +#endif +#ifdef GL_MESA_ycbcr_texture + if (_glewStrSame3(&pos, &len, (const GLubyte*)"ycbcr_texture", 13)) + { + ret = GLEW_MESA_ycbcr_texture; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"NV_", 3)) + { +#ifdef GL_NV_blend_square + if (_glewStrSame3(&pos, &len, (const GLubyte*)"blend_square", 12)) + { + ret = GLEW_NV_blend_square; + continue; + } +#endif +#ifdef GL_NV_copy_depth_to_color + if (_glewStrSame3(&pos, &len, (const GLubyte*)"copy_depth_to_color", 19)) + { + ret = GLEW_NV_copy_depth_to_color; + continue; + } +#endif +#ifdef GL_NV_depth_clamp + if (_glewStrSame3(&pos, &len, (const GLubyte*)"depth_clamp", 11)) + { + ret = GLEW_NV_depth_clamp; + continue; + } +#endif +#ifdef GL_NV_evaluators + if (_glewStrSame3(&pos, &len, (const GLubyte*)"evaluators", 10)) + { + ret = GLEW_NV_evaluators; + continue; + } +#endif +#ifdef GL_NV_fence + if (_glewStrSame3(&pos, &len, (const GLubyte*)"fence", 5)) + { + ret = GLEW_NV_fence; + continue; + } +#endif +#ifdef GL_NV_float_buffer + if (_glewStrSame3(&pos, &len, (const GLubyte*)"float_buffer", 12)) + { + ret = GLEW_NV_float_buffer; + continue; + } +#endif +#ifdef GL_NV_fog_distance + if (_glewStrSame3(&pos, &len, (const GLubyte*)"fog_distance", 12)) + { + ret = GLEW_NV_fog_distance; + continue; + } +#endif +#ifdef GL_NV_fragment_program + if (_glewStrSame3(&pos, &len, (const GLubyte*)"fragment_program", 16)) + { + ret = GLEW_NV_fragment_program; + continue; + } +#endif +#ifdef GL_NV_fragment_program2 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"fragment_program2", 17)) + { + ret = GLEW_NV_fragment_program2; + continue; + } +#endif +#ifdef GL_NV_fragment_program_option + if (_glewStrSame3(&pos, &len, (const GLubyte*)"fragment_program_option", 23)) + { + ret = GLEW_NV_fragment_program_option; + continue; + } +#endif +#ifdef GL_NV_half_float + if (_glewStrSame3(&pos, &len, (const GLubyte*)"half_float", 10)) + { + ret = GLEW_NV_half_float; + continue; + } +#endif +#ifdef GL_NV_light_max_exponent + if (_glewStrSame3(&pos, &len, (const GLubyte*)"light_max_exponent", 18)) + { + ret = GLEW_NV_light_max_exponent; + continue; + } +#endif +#ifdef GL_NV_multisample_filter_hint + if (_glewStrSame3(&pos, &len, (const GLubyte*)"multisample_filter_hint", 23)) + { + ret = GLEW_NV_multisample_filter_hint; + continue; + } +#endif +#ifdef GL_NV_occlusion_query + if (_glewStrSame3(&pos, &len, (const GLubyte*)"occlusion_query", 15)) + { + ret = GLEW_NV_occlusion_query; + continue; + } +#endif +#ifdef GL_NV_packed_depth_stencil + if (_glewStrSame3(&pos, &len, (const GLubyte*)"packed_depth_stencil", 20)) + { + ret = GLEW_NV_packed_depth_stencil; + continue; + } +#endif +#ifdef GL_NV_pixel_data_range + if (_glewStrSame3(&pos, &len, (const GLubyte*)"pixel_data_range", 16)) + { + ret = GLEW_NV_pixel_data_range; + continue; + } +#endif +#ifdef GL_NV_point_sprite + if (_glewStrSame3(&pos, &len, (const GLubyte*)"point_sprite", 12)) + { + ret = GLEW_NV_point_sprite; + continue; + } +#endif +#ifdef GL_NV_primitive_restart + if (_glewStrSame3(&pos, &len, (const GLubyte*)"primitive_restart", 17)) + { + ret = GLEW_NV_primitive_restart; + continue; + } +#endif +#ifdef GL_NV_register_combiners + if (_glewStrSame3(&pos, &len, (const GLubyte*)"register_combiners", 18)) + { + ret = GLEW_NV_register_combiners; + continue; + } +#endif +#ifdef GL_NV_register_combiners2 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"register_combiners2", 19)) + { + ret = GLEW_NV_register_combiners2; + continue; + } +#endif +#ifdef GL_NV_texgen_emboss + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texgen_emboss", 13)) + { + ret = GLEW_NV_texgen_emboss; + continue; + } +#endif +#ifdef GL_NV_texgen_reflection + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texgen_reflection", 17)) + { + ret = GLEW_NV_texgen_reflection; + continue; + } +#endif +#ifdef GL_NV_texture_compression_vtc + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_compression_vtc", 23)) + { + ret = GLEW_NV_texture_compression_vtc; + continue; + } +#endif +#ifdef GL_NV_texture_env_combine4 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_env_combine4", 20)) + { + ret = GLEW_NV_texture_env_combine4; + continue; + } +#endif +#ifdef GL_NV_texture_expand_normal + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_expand_normal", 21)) + { + ret = GLEW_NV_texture_expand_normal; + continue; + } +#endif +#ifdef GL_NV_texture_rectangle + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_rectangle", 17)) + { + ret = GLEW_NV_texture_rectangle; + continue; + } +#endif +#ifdef GL_NV_texture_shader + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_shader", 14)) + { + ret = GLEW_NV_texture_shader; + continue; + } +#endif +#ifdef GL_NV_texture_shader2 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_shader2", 15)) + { + ret = GLEW_NV_texture_shader2; + continue; + } +#endif +#ifdef GL_NV_texture_shader3 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_shader3", 15)) + { + ret = GLEW_NV_texture_shader3; + continue; + } +#endif +#ifdef GL_NV_vertex_array_range + if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_array_range", 18)) + { + ret = GLEW_NV_vertex_array_range; + continue; + } +#endif +#ifdef GL_NV_vertex_array_range2 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_array_range2", 19)) + { + ret = GLEW_NV_vertex_array_range2; + continue; + } +#endif +#ifdef GL_NV_vertex_program + if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_program", 14)) + { + ret = GLEW_NV_vertex_program; + continue; + } +#endif +#ifdef GL_NV_vertex_program1_1 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_program1_1", 17)) + { + ret = GLEW_NV_vertex_program1_1; + continue; + } +#endif +#ifdef GL_NV_vertex_program2 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_program2", 15)) + { + ret = GLEW_NV_vertex_program2; + continue; + } +#endif +#ifdef GL_NV_vertex_program2_option + if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_program2_option", 22)) + { + ret = GLEW_NV_vertex_program2_option; + continue; + } +#endif +#ifdef GL_NV_vertex_program3 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_program3", 15)) + { + ret = GLEW_NV_vertex_program3; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"OML_", 4)) + { +#ifdef GL_OML_interlace + if (_glewStrSame3(&pos, &len, (const GLubyte*)"interlace", 9)) + { + ret = GLEW_OML_interlace; + continue; + } +#endif +#ifdef GL_OML_resample + if (_glewStrSame3(&pos, &len, (const GLubyte*)"resample", 8)) + { + ret = GLEW_OML_resample; + continue; + } +#endif +#ifdef GL_OML_subsample + if (_glewStrSame3(&pos, &len, (const GLubyte*)"subsample", 9)) + { + ret = GLEW_OML_subsample; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"PGI_", 4)) + { +#ifdef GL_PGI_misc_hints + if (_glewStrSame3(&pos, &len, (const GLubyte*)"misc_hints", 10)) + { + ret = GLEW_PGI_misc_hints; + continue; + } +#endif +#ifdef GL_PGI_vertex_hints + if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_hints", 12)) + { + ret = GLEW_PGI_vertex_hints; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"REND_", 5)) + { +#ifdef GL_REND_screen_coordinates + if (_glewStrSame3(&pos, &len, (const GLubyte*)"screen_coordinates", 18)) + { + ret = GLEW_REND_screen_coordinates; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"S3_", 3)) + { +#ifdef GL_S3_s3tc + if (_glewStrSame3(&pos, &len, (const GLubyte*)"s3tc", 4)) + { + ret = GLEW_S3_s3tc; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"SGIS_", 5)) + { +#ifdef GL_SGIS_color_range + if (_glewStrSame3(&pos, &len, (const GLubyte*)"color_range", 11)) + { + ret = GLEW_SGIS_color_range; + continue; + } +#endif +#ifdef GL_SGIS_detail_texture + if (_glewStrSame3(&pos, &len, (const GLubyte*)"detail_texture", 14)) + { + ret = GLEW_SGIS_detail_texture; + continue; + } +#endif +#ifdef GL_SGIS_fog_function + if (_glewStrSame3(&pos, &len, (const GLubyte*)"fog_function", 12)) + { + ret = GLEW_SGIS_fog_function; + continue; + } +#endif +#ifdef GL_SGIS_generate_mipmap + if (_glewStrSame3(&pos, &len, (const GLubyte*)"generate_mipmap", 15)) + { + ret = GLEW_SGIS_generate_mipmap; + continue; + } +#endif +#ifdef GL_SGIS_multisample + if (_glewStrSame3(&pos, &len, (const GLubyte*)"multisample", 11)) + { + ret = GLEW_SGIS_multisample; + continue; + } +#endif +#ifdef GL_SGIS_pixel_texture + if (_glewStrSame3(&pos, &len, (const GLubyte*)"pixel_texture", 13)) + { + ret = GLEW_SGIS_pixel_texture; + continue; + } +#endif +#ifdef GL_SGIS_sharpen_texture + if (_glewStrSame3(&pos, &len, (const GLubyte*)"sharpen_texture", 15)) + { + ret = GLEW_SGIS_sharpen_texture; + continue; + } +#endif +#ifdef GL_SGIS_texture4D + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture4D", 9)) + { + ret = GLEW_SGIS_texture4D; + continue; + } +#endif +#ifdef GL_SGIS_texture_border_clamp + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_border_clamp", 20)) + { + ret = GLEW_SGIS_texture_border_clamp; + continue; + } +#endif +#ifdef GL_SGIS_texture_edge_clamp + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_edge_clamp", 18)) + { + ret = GLEW_SGIS_texture_edge_clamp; + continue; + } +#endif +#ifdef GL_SGIS_texture_filter4 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_filter4", 15)) + { + ret = GLEW_SGIS_texture_filter4; + continue; + } +#endif +#ifdef GL_SGIS_texture_lod + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_lod", 11)) + { + ret = GLEW_SGIS_texture_lod; + continue; + } +#endif +#ifdef GL_SGIS_texture_select + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_select", 14)) + { + ret = GLEW_SGIS_texture_select; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"SGIX_", 5)) + { +#ifdef GL_SGIX_async + if (_glewStrSame3(&pos, &len, (const GLubyte*)"async", 5)) + { + ret = GLEW_SGIX_async; + continue; + } +#endif +#ifdef GL_SGIX_async_histogram + if (_glewStrSame3(&pos, &len, (const GLubyte*)"async_histogram", 15)) + { + ret = GLEW_SGIX_async_histogram; + continue; + } +#endif +#ifdef GL_SGIX_async_pixel + if (_glewStrSame3(&pos, &len, (const GLubyte*)"async_pixel", 11)) + { + ret = GLEW_SGIX_async_pixel; + continue; + } +#endif +#ifdef GL_SGIX_blend_alpha_minmax + if (_glewStrSame3(&pos, &len, (const GLubyte*)"blend_alpha_minmax", 18)) + { + ret = GLEW_SGIX_blend_alpha_minmax; + continue; + } +#endif +#ifdef GL_SGIX_clipmap + if (_glewStrSame3(&pos, &len, (const GLubyte*)"clipmap", 7)) + { + ret = GLEW_SGIX_clipmap; + continue; + } +#endif +#ifdef GL_SGIX_depth_texture + if (_glewStrSame3(&pos, &len, (const GLubyte*)"depth_texture", 13)) + { + ret = GLEW_SGIX_depth_texture; + continue; + } +#endif +#ifdef GL_SGIX_flush_raster + if (_glewStrSame3(&pos, &len, (const GLubyte*)"flush_raster", 12)) + { + ret = GLEW_SGIX_flush_raster; + continue; + } +#endif +#ifdef GL_SGIX_fog_offset + if (_glewStrSame3(&pos, &len, (const GLubyte*)"fog_offset", 10)) + { + ret = GLEW_SGIX_fog_offset; + continue; + } +#endif +#ifdef GL_SGIX_fog_texture + if (_glewStrSame3(&pos, &len, (const GLubyte*)"fog_texture", 11)) + { + ret = GLEW_SGIX_fog_texture; + continue; + } +#endif +#ifdef GL_SGIX_fragment_specular_lighting + if (_glewStrSame3(&pos, &len, (const GLubyte*)"fragment_specular_lighting", 26)) + { + ret = GLEW_SGIX_fragment_specular_lighting; + continue; + } +#endif +#ifdef GL_SGIX_framezoom + if (_glewStrSame3(&pos, &len, (const GLubyte*)"framezoom", 9)) + { + ret = GLEW_SGIX_framezoom; + continue; + } +#endif +#ifdef GL_SGIX_interlace + if (_glewStrSame3(&pos, &len, (const GLubyte*)"interlace", 9)) + { + ret = GLEW_SGIX_interlace; + continue; + } +#endif +#ifdef GL_SGIX_ir_instrument1 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"ir_instrument1", 14)) + { + ret = GLEW_SGIX_ir_instrument1; + continue; + } +#endif +#ifdef GL_SGIX_list_priority + if (_glewStrSame3(&pos, &len, (const GLubyte*)"list_priority", 13)) + { + ret = GLEW_SGIX_list_priority; + continue; + } +#endif +#ifdef GL_SGIX_pixel_texture + if (_glewStrSame3(&pos, &len, (const GLubyte*)"pixel_texture", 13)) + { + ret = GLEW_SGIX_pixel_texture; + continue; + } +#endif +#ifdef GL_SGIX_pixel_texture_bits + if (_glewStrSame3(&pos, &len, (const GLubyte*)"pixel_texture_bits", 18)) + { + ret = GLEW_SGIX_pixel_texture_bits; + continue; + } +#endif +#ifdef GL_SGIX_reference_plane + if (_glewStrSame3(&pos, &len, (const GLubyte*)"reference_plane", 15)) + { + ret = GLEW_SGIX_reference_plane; + continue; + } +#endif +#ifdef GL_SGIX_resample + if (_glewStrSame3(&pos, &len, (const GLubyte*)"resample", 8)) + { + ret = GLEW_SGIX_resample; + continue; + } +#endif +#ifdef GL_SGIX_shadow + if (_glewStrSame3(&pos, &len, (const GLubyte*)"shadow", 6)) + { + ret = GLEW_SGIX_shadow; + continue; + } +#endif +#ifdef GL_SGIX_shadow_ambient + if (_glewStrSame3(&pos, &len, (const GLubyte*)"shadow_ambient", 14)) + { + ret = GLEW_SGIX_shadow_ambient; + continue; + } +#endif +#ifdef GL_SGIX_sprite + if (_glewStrSame3(&pos, &len, (const GLubyte*)"sprite", 6)) + { + ret = GLEW_SGIX_sprite; + continue; + } +#endif +#ifdef GL_SGIX_tag_sample_buffer + if (_glewStrSame3(&pos, &len, (const GLubyte*)"tag_sample_buffer", 17)) + { + ret = GLEW_SGIX_tag_sample_buffer; + continue; + } +#endif +#ifdef GL_SGIX_texture_add_env + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_add_env", 15)) + { + ret = GLEW_SGIX_texture_add_env; + continue; + } +#endif +#ifdef GL_SGIX_texture_coordinate_clamp + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_coordinate_clamp", 24)) + { + ret = GLEW_SGIX_texture_coordinate_clamp; + continue; + } +#endif +#ifdef GL_SGIX_texture_lod_bias + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_lod_bias", 16)) + { + ret = GLEW_SGIX_texture_lod_bias; + continue; + } +#endif +#ifdef GL_SGIX_texture_multi_buffer + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_multi_buffer", 20)) + { + ret = GLEW_SGIX_texture_multi_buffer; + continue; + } +#endif +#ifdef GL_SGIX_texture_range + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_range", 13)) + { + ret = GLEW_SGIX_texture_range; + continue; + } +#endif +#ifdef GL_SGIX_texture_scale_bias + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_scale_bias", 18)) + { + ret = GLEW_SGIX_texture_scale_bias; + continue; + } +#endif +#ifdef GL_SGIX_vertex_preclip + if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_preclip", 14)) + { + ret = GLEW_SGIX_vertex_preclip; + continue; + } +#endif +#ifdef GL_SGIX_vertex_preclip_hint + if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_preclip_hint", 19)) + { + ret = GLEW_SGIX_vertex_preclip_hint; + continue; + } +#endif +#ifdef GL_SGIX_ycrcb + if (_glewStrSame3(&pos, &len, (const GLubyte*)"ycrcb", 5)) + { + ret = GLEW_SGIX_ycrcb; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"SGI_", 4)) + { +#ifdef GL_SGI_color_matrix + if (_glewStrSame3(&pos, &len, (const GLubyte*)"color_matrix", 12)) + { + ret = GLEW_SGI_color_matrix; + continue; + } +#endif +#ifdef GL_SGI_color_table + if (_glewStrSame3(&pos, &len, (const GLubyte*)"color_table", 11)) + { + ret = GLEW_SGI_color_table; + continue; + } +#endif +#ifdef GL_SGI_texture_color_table + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_color_table", 19)) + { + ret = GLEW_SGI_texture_color_table; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"SUNX_", 5)) + { +#ifdef GL_SUNX_constant_data + if (_glewStrSame3(&pos, &len, (const GLubyte*)"constant_data", 13)) + { + ret = GLEW_SUNX_constant_data; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"SUN_", 4)) + { +#ifdef GL_SUN_convolution_border_modes + if (_glewStrSame3(&pos, &len, (const GLubyte*)"convolution_border_modes", 24)) + { + ret = GLEW_SUN_convolution_border_modes; + continue; + } +#endif +#ifdef GL_SUN_global_alpha + if (_glewStrSame3(&pos, &len, (const GLubyte*)"global_alpha", 12)) + { + ret = GLEW_SUN_global_alpha; + continue; + } +#endif +#ifdef GL_SUN_mesh_array + if (_glewStrSame3(&pos, &len, (const GLubyte*)"mesh_array", 10)) + { + ret = GLEW_SUN_mesh_array; + continue; + } +#endif +#ifdef GL_SUN_read_video_pixels + if (_glewStrSame3(&pos, &len, (const GLubyte*)"read_video_pixels", 17)) + { + ret = GLEW_SUN_read_video_pixels; + continue; + } +#endif +#ifdef GL_SUN_slice_accum + if (_glewStrSame3(&pos, &len, (const GLubyte*)"slice_accum", 11)) + { + ret = GLEW_SUN_slice_accum; + continue; + } +#endif +#ifdef GL_SUN_triangle_list + if (_glewStrSame3(&pos, &len, (const GLubyte*)"triangle_list", 13)) + { + ret = GLEW_SUN_triangle_list; + continue; + } +#endif +#ifdef GL_SUN_vertex + if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex", 6)) + { + ret = GLEW_SUN_vertex; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"WIN_", 4)) + { +#ifdef GL_WIN_phong_shading + if (_glewStrSame3(&pos, &len, (const GLubyte*)"phong_shading", 13)) + { + ret = GLEW_WIN_phong_shading; + continue; + } +#endif +#ifdef GL_WIN_specular_fog + if (_glewStrSame3(&pos, &len, (const GLubyte*)"specular_fog", 12)) + { + ret = GLEW_WIN_specular_fog; + continue; + } +#endif +#ifdef GL_WIN_swap_hint + if (_glewStrSame3(&pos, &len, (const GLubyte*)"swap_hint", 9)) + { + ret = GLEW_WIN_swap_hint; + continue; + } +#endif + } + } + ret = (len == 0); + } + return ret; +} + +#if defined(_WIN32) + +#if defined(GLEW_MX) +GLboolean wglewContextIsSupported (WGLEWContext* ctx, const char* name) +#else +GLboolean wglewIsSupported (const char* name) +#endif +{ + GLubyte* pos = (GLubyte*)name; + GLuint len = _glewStrLen(pos); + GLboolean ret = GL_TRUE; + while (ret && len > 0) + { + if (_glewStrSame1(&pos, &len, (const GLubyte*)"WGL_", 4)) + { + if (_glewStrSame2(&pos, &len, (const GLubyte*)"3DFX_", 5)) + { +#ifdef WGL_3DFX_multisample + if (_glewStrSame3(&pos, &len, (const GLubyte*)"multisample", 11)) + { + ret = WGLEW_3DFX_multisample; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"3DL_", 4)) + { +#ifdef WGL_3DL_stereo_control + if (_glewStrSame3(&pos, &len, (const GLubyte*)"stereo_control", 14)) + { + ret = WGLEW_3DL_stereo_control; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"ARB_", 4)) + { +#ifdef WGL_ARB_buffer_region + if (_glewStrSame3(&pos, &len, (const GLubyte*)"buffer_region", 13)) + { + ret = WGLEW_ARB_buffer_region; + continue; + } +#endif +#ifdef WGL_ARB_extensions_string + if (_glewStrSame3(&pos, &len, (const GLubyte*)"extensions_string", 17)) + { + ret = WGLEW_ARB_extensions_string; + continue; + } +#endif +#ifdef WGL_ARB_make_current_read + if (_glewStrSame3(&pos, &len, (const GLubyte*)"make_current_read", 17)) + { + ret = WGLEW_ARB_make_current_read; + continue; + } +#endif +#ifdef WGL_ARB_multisample + if (_glewStrSame3(&pos, &len, (const GLubyte*)"multisample", 11)) + { + ret = WGLEW_ARB_multisample; + continue; + } +#endif +#ifdef WGL_ARB_pbuffer + if (_glewStrSame3(&pos, &len, (const GLubyte*)"pbuffer", 7)) + { + ret = WGLEW_ARB_pbuffer; + continue; + } +#endif +#ifdef WGL_ARB_pixel_format + if (_glewStrSame3(&pos, &len, (const GLubyte*)"pixel_format", 12)) + { + ret = WGLEW_ARB_pixel_format; + continue; + } +#endif +#ifdef WGL_ARB_pixel_format_float + if (_glewStrSame3(&pos, &len, (const GLubyte*)"pixel_format_float", 18)) + { + ret = WGLEW_ARB_pixel_format_float; + continue; + } +#endif +#ifdef WGL_ARB_render_texture + if (_glewStrSame3(&pos, &len, (const GLubyte*)"render_texture", 14)) + { + ret = WGLEW_ARB_render_texture; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"ATI_", 4)) + { +#ifdef WGL_ATI_pixel_format_float + if (_glewStrSame3(&pos, &len, (const GLubyte*)"pixel_format_float", 18)) + { + ret = WGLEW_ATI_pixel_format_float; + continue; + } +#endif +#ifdef WGL_ATI_render_texture_rectangle + if (_glewStrSame3(&pos, &len, (const GLubyte*)"render_texture_rectangle", 24)) + { + ret = WGLEW_ATI_render_texture_rectangle; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"EXT_", 4)) + { +#ifdef WGL_EXT_depth_float + if (_glewStrSame3(&pos, &len, (const GLubyte*)"depth_float", 11)) + { + ret = WGLEW_EXT_depth_float; + continue; + } +#endif +#ifdef WGL_EXT_display_color_table + if (_glewStrSame3(&pos, &len, (const GLubyte*)"display_color_table", 19)) + { + ret = WGLEW_EXT_display_color_table; + continue; + } +#endif +#ifdef WGL_EXT_extensions_string + if (_glewStrSame3(&pos, &len, (const GLubyte*)"extensions_string", 17)) + { + ret = WGLEW_EXT_extensions_string; + continue; + } +#endif +#ifdef WGL_EXT_make_current_read + if (_glewStrSame3(&pos, &len, (const GLubyte*)"make_current_read", 17)) + { + ret = WGLEW_EXT_make_current_read; + continue; + } +#endif +#ifdef WGL_EXT_multisample + if (_glewStrSame3(&pos, &len, (const GLubyte*)"multisample", 11)) + { + ret = WGLEW_EXT_multisample; + continue; + } +#endif +#ifdef WGL_EXT_pbuffer + if (_glewStrSame3(&pos, &len, (const GLubyte*)"pbuffer", 7)) + { + ret = WGLEW_EXT_pbuffer; + continue; + } +#endif +#ifdef WGL_EXT_pixel_format + if (_glewStrSame3(&pos, &len, (const GLubyte*)"pixel_format", 12)) + { + ret = WGLEW_EXT_pixel_format; + continue; + } +#endif +#ifdef WGL_EXT_swap_control + if (_glewStrSame3(&pos, &len, (const GLubyte*)"swap_control", 12)) + { + ret = WGLEW_EXT_swap_control; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"I3D_", 4)) + { +#ifdef WGL_I3D_digital_video_control + if (_glewStrSame3(&pos, &len, (const GLubyte*)"digital_video_control", 21)) + { + ret = WGLEW_I3D_digital_video_control; + continue; + } +#endif +#ifdef WGL_I3D_gamma + if (_glewStrSame3(&pos, &len, (const GLubyte*)"gamma", 5)) + { + ret = WGLEW_I3D_gamma; + continue; + } +#endif +#ifdef WGL_I3D_genlock + if (_glewStrSame3(&pos, &len, (const GLubyte*)"genlock", 7)) + { + ret = WGLEW_I3D_genlock; + continue; + } +#endif +#ifdef WGL_I3D_image_buffer + if (_glewStrSame3(&pos, &len, (const GLubyte*)"image_buffer", 12)) + { + ret = WGLEW_I3D_image_buffer; + continue; + } +#endif +#ifdef WGL_I3D_swap_frame_lock + if (_glewStrSame3(&pos, &len, (const GLubyte*)"swap_frame_lock", 15)) + { + ret = WGLEW_I3D_swap_frame_lock; + continue; + } +#endif +#ifdef WGL_I3D_swap_frame_usage + if (_glewStrSame3(&pos, &len, (const GLubyte*)"swap_frame_usage", 16)) + { + ret = WGLEW_I3D_swap_frame_usage; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"NV_", 3)) + { +#ifdef WGL_NV_float_buffer + if (_glewStrSame3(&pos, &len, (const GLubyte*)"float_buffer", 12)) + { + ret = WGLEW_NV_float_buffer; + continue; + } +#endif +#ifdef WGL_NV_render_depth_texture + if (_glewStrSame3(&pos, &len, (const GLubyte*)"render_depth_texture", 20)) + { + ret = WGLEW_NV_render_depth_texture; + continue; + } +#endif +#ifdef WGL_NV_render_texture_rectangle + if (_glewStrSame3(&pos, &len, (const GLubyte*)"render_texture_rectangle", 24)) + { + ret = WGLEW_NV_render_texture_rectangle; + continue; + } +#endif +#ifdef WGL_NV_vertex_array_range + if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_array_range", 18)) + { + ret = WGLEW_NV_vertex_array_range; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"OML_", 4)) + { +#ifdef WGL_OML_sync_control + if (_glewStrSame3(&pos, &len, (const GLubyte*)"sync_control", 12)) + { + ret = WGLEW_OML_sync_control; + continue; + } +#endif + } + } + ret = (len == 0); + } + return ret; +} + +#elif !defined(__APPLE__) || defined(GLEW_APPLE_GLX) + +#if defined(GLEW_MX) +GLboolean glxewContextIsSupported (GLXEWContext* ctx, const char* name) +#else +GLboolean glxewIsSupported (const char* name) +#endif +{ + GLubyte* pos = (GLubyte*)name; + GLuint len = _glewStrLen(pos); + GLboolean ret = GL_TRUE; + while (ret && len > 0) + { + if(_glewStrSame1(&pos, &len, (const GLubyte*)"GLX_", 4)) + { + if (_glewStrSame2(&pos, &len, (const GLubyte*)"VERSION_", 8)) + { +#ifdef GLX_VERSION_1_2 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"1_2", 3)) + { + ret = GLXEW_VERSION_1_2; + continue; + } +#endif +#ifdef GLX_VERSION_1_3 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"1_3", 3)) + { + ret = GLXEW_VERSION_1_3; + continue; + } +#endif +#ifdef GLX_VERSION_1_4 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"1_4", 3)) + { + ret = GLXEW_VERSION_1_4; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"3DFX_", 5)) + { +#ifdef GLX_3DFX_multisample + if (_glewStrSame3(&pos, &len, (const GLubyte*)"multisample", 11)) + { + ret = GLXEW_3DFX_multisample; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"ARB_", 4)) + { +#ifdef GLX_ARB_fbconfig_float + if (_glewStrSame3(&pos, &len, (const GLubyte*)"fbconfig_float", 14)) + { + ret = GLXEW_ARB_fbconfig_float; + continue; + } +#endif +#ifdef GLX_ARB_get_proc_address + if (_glewStrSame3(&pos, &len, (const GLubyte*)"get_proc_address", 16)) + { + ret = GLXEW_ARB_get_proc_address; + continue; + } +#endif +#ifdef GLX_ARB_multisample + if (_glewStrSame3(&pos, &len, (const GLubyte*)"multisample", 11)) + { + ret = GLXEW_ARB_multisample; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"ATI_", 4)) + { +#ifdef GLX_ATI_pixel_format_float + if (_glewStrSame3(&pos, &len, (const GLubyte*)"pixel_format_float", 18)) + { + ret = GLXEW_ATI_pixel_format_float; + continue; + } +#endif +#ifdef GLX_ATI_render_texture + if (_glewStrSame3(&pos, &len, (const GLubyte*)"render_texture", 14)) + { + ret = GLXEW_ATI_render_texture; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"EXT_", 4)) + { +#ifdef GLX_EXT_import_context + if (_glewStrSame3(&pos, &len, (const GLubyte*)"import_context", 14)) + { + ret = GLXEW_EXT_import_context; + continue; + } +#endif +#ifdef GLX_EXT_scene_marker + if (_glewStrSame3(&pos, &len, (const GLubyte*)"scene_marker", 12)) + { + ret = GLXEW_EXT_scene_marker; + continue; + } +#endif +#ifdef GLX_EXT_visual_info + if (_glewStrSame3(&pos, &len, (const GLubyte*)"visual_info", 11)) + { + ret = GLXEW_EXT_visual_info; + continue; + } +#endif +#ifdef GLX_EXT_visual_rating + if (_glewStrSame3(&pos, &len, (const GLubyte*)"visual_rating", 13)) + { + ret = GLXEW_EXT_visual_rating; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"MESA_", 5)) + { +#ifdef GLX_MESA_agp_offset + if (_glewStrSame3(&pos, &len, (const GLubyte*)"agp_offset", 10)) + { + ret = GLXEW_MESA_agp_offset; + continue; + } +#endif +#ifdef GLX_MESA_copy_sub_buffer + if (_glewStrSame3(&pos, &len, (const GLubyte*)"copy_sub_buffer", 15)) + { + ret = GLXEW_MESA_copy_sub_buffer; + continue; + } +#endif +#ifdef GLX_MESA_pixmap_colormap + if (_glewStrSame3(&pos, &len, (const GLubyte*)"pixmap_colormap", 15)) + { + ret = GLXEW_MESA_pixmap_colormap; + continue; + } +#endif +#ifdef GLX_MESA_release_buffers + if (_glewStrSame3(&pos, &len, (const GLubyte*)"release_buffers", 15)) + { + ret = GLXEW_MESA_release_buffers; + continue; + } +#endif +#ifdef GLX_MESA_set_3dfx_mode + if (_glewStrSame3(&pos, &len, (const GLubyte*)"set_3dfx_mode", 13)) + { + ret = GLXEW_MESA_set_3dfx_mode; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"NV_", 3)) + { +#ifdef GLX_NV_float_buffer + if (_glewStrSame3(&pos, &len, (const GLubyte*)"float_buffer", 12)) + { + ret = GLXEW_NV_float_buffer; + continue; + } +#endif +#ifdef GLX_NV_vertex_array_range + if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_array_range", 18)) + { + ret = GLXEW_NV_vertex_array_range; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"OML_", 4)) + { +#ifdef GLX_OML_swap_method + if (_glewStrSame3(&pos, &len, (const GLubyte*)"swap_method", 11)) + { + ret = GLXEW_OML_swap_method; + continue; + } +#endif +#if defined(GLX_OML_sync_control) && defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) +#include + if (_glewStrSame3(&pos, &len, (const GLubyte*)"sync_control", 12)) + { + ret = GLXEW_OML_sync_control; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"SGIS_", 5)) + { +#ifdef GLX_SGIS_blended_overlay + if (_glewStrSame3(&pos, &len, (const GLubyte*)"blended_overlay", 15)) + { + ret = GLXEW_SGIS_blended_overlay; + continue; + } +#endif +#ifdef GLX_SGIS_color_range + if (_glewStrSame3(&pos, &len, (const GLubyte*)"color_range", 11)) + { + ret = GLXEW_SGIS_color_range; + continue; + } +#endif +#ifdef GLX_SGIS_multisample + if (_glewStrSame3(&pos, &len, (const GLubyte*)"multisample", 11)) + { + ret = GLXEW_SGIS_multisample; + continue; + } +#endif +#ifdef GLX_SGIS_shared_multisample + if (_glewStrSame3(&pos, &len, (const GLubyte*)"shared_multisample", 18)) + { + ret = GLXEW_SGIS_shared_multisample; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"SGIX_", 5)) + { +#ifdef GLX_SGIX_fbconfig + if (_glewStrSame3(&pos, &len, (const GLubyte*)"fbconfig", 8)) + { + ret = GLXEW_SGIX_fbconfig; + continue; + } +#endif +#ifdef GLX_SGIX_pbuffer + if (_glewStrSame3(&pos, &len, (const GLubyte*)"pbuffer", 7)) + { + ret = GLXEW_SGIX_pbuffer; + continue; + } +#endif +#ifdef GLX_SGIX_swap_barrier + if (_glewStrSame3(&pos, &len, (const GLubyte*)"swap_barrier", 12)) + { + ret = GLXEW_SGIX_swap_barrier; + continue; + } +#endif +#ifdef GLX_SGIX_swap_group + if (_glewStrSame3(&pos, &len, (const GLubyte*)"swap_group", 10)) + { + ret = GLXEW_SGIX_swap_group; + continue; + } +#endif +#ifdef GLX_SGIX_video_resize + if (_glewStrSame3(&pos, &len, (const GLubyte*)"video_resize", 12)) + { + ret = GLXEW_SGIX_video_resize; + continue; + } +#endif +#ifdef GLX_SGIX_visual_select_group + if (_glewStrSame3(&pos, &len, (const GLubyte*)"visual_select_group", 19)) + { + ret = GLXEW_SGIX_visual_select_group; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"SGI_", 4)) + { +#ifdef GLX_SGI_cushion + if (_glewStrSame3(&pos, &len, (const GLubyte*)"cushion", 7)) + { + ret = GLXEW_SGI_cushion; + continue; + } +#endif +#ifdef GLX_SGI_make_current_read + if (_glewStrSame3(&pos, &len, (const GLubyte*)"make_current_read", 17)) + { + ret = GLXEW_SGI_make_current_read; + continue; + } +#endif +#ifdef GLX_SGI_swap_control + if (_glewStrSame3(&pos, &len, (const GLubyte*)"swap_control", 12)) + { + ret = GLXEW_SGI_swap_control; + continue; + } +#endif +#ifdef GLX_SGI_video_sync + if (_glewStrSame3(&pos, &len, (const GLubyte*)"video_sync", 10)) + { + ret = GLXEW_SGI_video_sync; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"SUN_", 4)) + { +#ifdef GLX_SUN_get_transparent_index + if (_glewStrSame3(&pos, &len, (const GLubyte*)"get_transparent_index", 21)) + { + ret = GLXEW_SUN_get_transparent_index; + continue; + } +#endif +#ifdef GLX_SUN_video_resize + if (_glewStrSame3(&pos, &len, (const GLubyte*)"video_resize", 12)) + { + ret = GLXEW_SUN_video_resize; + continue; + } +#endif + } + } + ret = (len == 0); + } + return ret; +} + +#endif /* _WIN32 */ diff --git a/source/Makefile b/source/Makefile index 5ebff3bbbf5..d06962cbe3f 100644 --- a/source/Makefile +++ b/source/Makefile @@ -157,6 +157,7 @@ COMLIB += $(NAN_BMFONT)/lib/$(DEBUG_DIR)libbmfont.a COMLIB += $(NAN_PNG)/lib/libpng.a COMLIB += $(OCGDIR)/blender/yafray/$(DEBUG_DIR)libyafrayexport.a COMLIB += $(OCGDIR)/blender/blenlib/$(DEBUG_DIR)libblenlib.a +COMLIB += $(NAN_GLEW)/lib/libglew.a ifeq ($(WITH_QUICKTIME), true) COMLIB += $(OCGDIR)/blender/blenderqt/$(DEBUG_DIR)libblenderqt.a diff --git a/source/blender/src/CMakeLists.txt b/source/blender/src/CMakeLists.txt index d6874cdd4db..342579fb3b0 100644 --- a/source/blender/src/CMakeLists.txt +++ b/source/blender/src/CMakeLists.txt @@ -35,7 +35,7 @@ SET(INC ../../kernel/gen_system ../../../intern/SoundSystem ../readstreamglue ../quicktime ../../../intern/elbeem/extern ../../../intern/ghost ../../../intern/opennl/extern - ../nodes + ../nodes ../../../extern/glew/include ${PYTHON_INC} ${SDL_INC} ) diff --git a/source/blender/src/Makefile b/source/blender/src/Makefile index c1c0ef8b1f2..001efc58b5d 100644 --- a/source/blender/src/Makefile +++ b/source/blender/src/Makefile @@ -143,4 +143,5 @@ ifeq ($(NAN_TWEAK_MODE), true) CPPFLAGS += -DTWEAK_MODE endif +CPPFLAGS += -I$(NAN_GLEW)/include CPPFLAGS += -I$(OPENGL_HEADERS) diff --git a/source/blender/src/SConscript b/source/blender/src/SConscript index f466798c40c..229cc87ef37 100644 --- a/source/blender/src/SConscript +++ b/source/blender/src/SConscript @@ -26,7 +26,7 @@ incs += ' #/intern/bsp/extern ../radiosity/extern/include' incs += ' #/intern/decimation/extern ../blenloader ../python' incs += ' ../../kernel/gen_system #/intern/SoundSystem ../readstreamglue ../nodes' incs += ' ../quicktime #/intern/elbeem/extern' -incs += ' #/intern/ghost #/intern/opennl/extern' +incs += ' #/intern/ghost #/intern/opennl/extern #/extern/glew/include' incs += ' ' + env['BF_PYTHON_INC'] diff --git a/source/blender/src/usiblender.c b/source/blender/src/usiblender.c index 5ac8e186b68..2a4672e3052 100644 --- a/source/blender/src/usiblender.c +++ b/source/blender/src/usiblender.c @@ -1038,6 +1038,7 @@ void BIF_init(void) BIF_filelist_init_icons(); init_gl_stuff(); /* drawview.c, after homefile */ + glewInit(); readBlog(); BLI_strncpy(G.lib, G.sce, FILE_MAX); } diff --git a/source/creator/CMakeLists.txt b/source/creator/CMakeLists.txt index 05c58a258ec..d17b94c631d 100644 --- a/source/creator/CMakeLists.txt +++ b/source/creator/CMakeLists.txt @@ -259,6 +259,7 @@ IF(UNIX) blender_python bf_quicktime extern_binreloc + extern_glew ) FOREACH(SORTLIB ${BLENDER_SORTED_LIBS}) diff --git a/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp b/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp index eb575c70ad7..06aa0609ad9 100644 --- a/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp +++ b/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp @@ -40,9 +40,7 @@ #pragma warning (disable:4786) #endif -#ifdef __APPLE__ -#define GL_GLEXT_LEGACY 1 -#endif +#include "GL/glew.h" #include "KX_BlenderGL.h" #include "KX_BlenderCanvas.h" @@ -57,10 +55,10 @@ #include "KX_PythonInit.h" #include "KX_PyConstraintBinding.h" +#include "RAS_GLExtensionManager.h" #include "RAS_OpenGLRasterizer.h" #include "RAS_VAOpenGLRasterizer.h" #include "RAS_ListRasterizer.h" -#include "RAS_GLExtensionManager.h" #include "NG_LoopBackNetworkDeviceInterface.h" #include "SND_DeviceManager.h" @@ -142,12 +140,12 @@ extern "C" void StartKetsjiShell(struct ScrArea *area, // so we can safely run Python code and API calls PyGILState_STATE gilstate = PyGILState_Ensure(); - bgl::InitExtensions(1); - + bgl::InitExtensions(true); + do { View3D *v3d= (View3D*) area->spacedata.first; - + // get some preferences SYS_SystemHandle syshandle = SYS_GetSystem(); bool properties = (SYS_GetCommandLineInt(syshandle, "show_properties", 0) != 0); @@ -156,22 +154,10 @@ extern "C" void StartKetsjiShell(struct ScrArea *area, bool frameRate = (SYS_GetCommandLineInt(syshandle, "show_framerate", 0) != 0); bool game2ipo = (SYS_GetCommandLineInt(syshandle, "game2ipo", 0) != 0); bool displaylists = (SYS_GetCommandLineInt(syshandle, "displaylists", 0) != 0); - bool usemat = false; - - #if defined(GL_ARB_multitexture) && defined(WITH_GLEXT) - if (!getenv("WITHOUT_GLEXT")) { - if(bgl::RAS_EXT_support._ARB_multitexture && bgl::QueryVersion(1, 1)) { - usemat = (SYS_GetCommandLineInt(syshandle, "blender_material", 0) != 0); - int unitmax=0; - glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, (GLint*)&unitmax); - bgl::max_texture_units = MAXTEX>unitmax?unitmax:MAXTEX; - //std::cout << "using(" << bgl::max_texture_units << ") of(" << unitmax << ") texture units." << std::endl; - } else { - bgl::max_texture_units = 0; - } - } - #endif + bool usemat = false, useglslmat = false; + if(GLEW_ARB_multitexture && GLEW_VERSION_1_1) + usemat = (SYS_GetCommandLineInt(syshandle, "blender_material", 0) != 0); // create the canvas, rasterizer and rendertools RAS_ICanvas* canvas = new KX_BlenderCanvas(area); @@ -186,12 +172,12 @@ extern "C" void StartKetsjiShell(struct ScrArea *area, bool lock_arrays = (displaylists && useVertexArrays); if(displaylists){ - if (useVertexArrays) { + if (useVertexArrays) rasterizer = new RAS_ListRasterizer(canvas, true, lock_arrays); - } else { + else rasterizer = new RAS_ListRasterizer(canvas); - } - } else if (useVertexArrays && bgl::QueryVersion(1, 1)) + } + else if (useVertexArrays && GLEW_VERSION_1_1) rasterizer = new RAS_VAOpenGLRasterizer(canvas, lock_arrays); else rasterizer = new RAS_OpenGLRasterizer(canvas); @@ -338,6 +324,8 @@ extern "C" void StartKetsjiShell(struct ScrArea *area, if(usemat) sceneconverter->SetMaterials(true); + if(useglslmat) + sceneconverter->SetGLSLMaterials(true); KX_Scene* startscene = new KX_Scene(keyboarddevice, mousedevice, @@ -504,7 +492,7 @@ extern "C" void StartKetsjiShellSimulation(struct ScrArea *area, // so we can safely run Python code and API calls PyGILState_STATE gilstate = PyGILState_Ensure(); - bgl::InitExtensions(1); + bgl::InitExtensions(true); do { @@ -533,7 +521,7 @@ extern "C" void StartKetsjiShellSimulation(struct ScrArea *area, if(displaylists && !useVertexArrays) rasterizer = new RAS_ListRasterizer(canvas); - else if (useVertexArrays && bgl::QueryVersion(1, 1)) + else if (useVertexArrays && GLEW_VERSION_1_1) rasterizer = new RAS_VAOpenGLRasterizer(canvas, lock_arrays); else rasterizer = new RAS_OpenGLRasterizer(canvas); diff --git a/source/gameengine/BlenderRoutines/CMakeLists.txt b/source/gameengine/BlenderRoutines/CMakeLists.txt index 764be732343..1d72fb9cde1 100644 --- a/source/gameengine/BlenderRoutines/CMakeLists.txt +++ b/source/gameengine/BlenderRoutines/CMakeLists.txt @@ -33,6 +33,7 @@ SET(INC ../../../source/blender/blenloader ../../../extern/bullet2/src ../../../extern/solid + ../../../extern/glew/include ${PYTHON_INC} ) diff --git a/source/gameengine/BlenderRoutines/KX_BlenderCanvas.h b/source/gameengine/BlenderRoutines/KX_BlenderCanvas.h index f9ff8f61b97..b155d39e149 100644 --- a/source/gameengine/BlenderRoutines/KX_BlenderCanvas.h +++ b/source/gameengine/BlenderRoutines/KX_BlenderCanvas.h @@ -32,12 +32,8 @@ #ifdef WIN32 #include #endif -#ifdef __APPLE__ -# define GL_GLEXT_LEGACY 1 -#include -#else -#include -#endif + +#include "GL/glew.h" #include "RAS_ICanvas.h" #include "RAS_Rect.h" diff --git a/source/gameengine/BlenderRoutines/KX_BlenderGL.cpp b/source/gameengine/BlenderRoutines/KX_BlenderGL.cpp index 2a5cc14018f..230d6b262c6 100644 --- a/source/gameengine/BlenderRoutines/KX_BlenderGL.cpp +++ b/source/gameengine/BlenderRoutines/KX_BlenderGL.cpp @@ -44,21 +44,9 @@ #include "BMF_Api.h" +#include "GL/glew.h" +#include "BIF_gl.h" -#ifdef __APPLE__ -#define GL_GLEXT_LEGACY 1 -#include -#include -#else -#include -#if defined(__sun__) && !defined(__sparc__) -#include -#else -#include -#endif -#endif -#include "RAS_OpenGLRasterizer/RAS_GLExtensionManager.h" -#include "RAS_OpenGLRasterizer/ARB_multitexture.h" #include "BL_Material.h" // MAXTEX /* Data types encoding the game world: */ @@ -77,7 +65,6 @@ #include "BKE_bmfont.h" #include "BKE_image.h" -#include "BIF_gl.h" extern "C" { #include "BDR_drawmesh.h" #include "BIF_mywindow.h" @@ -88,12 +75,6 @@ extern "C" { /* end of blender block */ -#ifdef __APPLE__ -#include -#else -#include -#endif - /* was in drawmesh.c */ void spack(unsigned int ucol) { @@ -194,28 +175,19 @@ void DisableForText() glDisable(GL_LIGHTING); glDisable(GL_COLOR_MATERIAL); } -#if defined(GL_ARB_multitexture) && defined(WITH_GLEXT) - if (!getenv("WITHOUT_GLEXT")) { - for(int i=0; i -#endif //WIN32 -#ifdef __APPLE__ -#define GL_GLEXT_LEGACY 1 -#include -#else -#include -#endif +#include "GL/glew.h" #include "RAS_IRenderTools.h" #include "RAS_IRasterizer.h" @@ -317,7 +308,7 @@ void KX_BlenderRenderTools::EnableOpenGLLights() glEnable(GL_COLOR_MATERIAL); glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE); glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, true); - if (bgl::QueryExtension(bgl::_GL_EXT_separate_specular_color) || bgl::QueryVersion(1, 2)) + if (GLEW_EXT_separate_specular_color || GLEW_VERSION_1_2) glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR); } diff --git a/source/gameengine/BlenderRoutines/Makefile b/source/gameengine/BlenderRoutines/Makefile index 64a17f44a84..a7394158a20 100644 --- a/source/gameengine/BlenderRoutines/Makefile +++ b/source/gameengine/BlenderRoutines/Makefile @@ -35,7 +35,6 @@ include nan_compile.mk CCFLAGS += $(LEVEL_1_CPP_WARNINGS) -CPPFLAGS += -I$(OPENGL_HEADERS) CPPFLAGS += -I$(NAN_SUMO)/include -I$(NAN_SOLID)/include CPPFLAGS += -I$(NAN_SOLID) CPPFLAGS += -I$(NAN_STRING)/include @@ -43,6 +42,8 @@ CPPFLAGS += -I$(NAN_MOTO)/include CPPFLAGS += -I$(NAN_BMFONT)/include CPPFLAGS += -I$(NAN_FUZZICS)/include CPPFLAGS += -I$(NAN_SOUNDSYSTEM)/include +CPPFLAGS += -I$(NAN_GLEW)/include +CPPFLAGS += -I$(OPENGL_HEADERS) # because of kernel dependency on makesdna CPPFLAGS += -I../../blender/makesdna CPPFLAGS += -I../../blender/include diff --git a/source/gameengine/BlenderRoutines/SConscript b/source/gameengine/BlenderRoutines/SConscript index 95e1da2d470..327f4798e04 100644 --- a/source/gameengine/BlenderRoutines/SConscript +++ b/source/gameengine/BlenderRoutines/SConscript @@ -15,6 +15,7 @@ incs += ' #source/gameengine/SceneGraph #source/gameengine/Physics/common' incs += ' #source/gameengine/Physics/Bullet #source/gameengine/Physics/Sumo' incs += ' #source/gameengine/Physics/Sumo/Fuzzics/include #source/gameengine/Network/LoopBackNetwork' incs += ' #intern/SoundSystem #source/blender/misc #source/blender/blenloader' +incs += ' #extern/glew/include' incs += ' ' + env['BF_PYTHON_INC'] incs += ' ' + env['BF_SOLID_INC'] diff --git a/source/gameengine/BlenderRoutines/mac_compat_glext.h b/source/gameengine/BlenderRoutines/mac_compat_glext.h deleted file mode 100644 index 0ec676963b1..00000000000 --- a/source/gameengine/BlenderRoutines/mac_compat_glext.h +++ /dev/null @@ -1,132 +0,0 @@ -#ifndef __mac_compat_glext_h_ -#define __mac_compat_glext_h_ - - -#ifdef __cplusplus -extern "C" { -#endif - -#define APIENTRYP * -# define GL_GLEXT_LEGACY 1 -# include - -//#if GL_ARB_shader_objects -typedef char GLcharARB; -typedef void *GLhandleARB; -//#endif - -//#if GL_ARB_vertex_buffer_object -typedef long GLintptrARB; -typedef long GLsizeiptrARB; -//#endif - - -// GL_ARB_multitexture -typedef void (APIENTRYP PFNGLACTIVETEXTUREARBPROC) (GLenum texture); -typedef void (APIENTRYP PFNGLCLIENTACTIVETEXTUREARBPROC) (GLenum texture); -typedef void (APIENTRYP PFNGLMULTITEXCOORD1DARBPROC) (GLenum target, GLdouble s); -typedef void (APIENTRYP PFNGLMULTITEXCOORD1DVARBPROC) (GLenum target, const GLdouble *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD1FARBPROC) (GLenum target, GLfloat s); -typedef void (APIENTRYP PFNGLMULTITEXCOORD1FVARBPROC) (GLenum target, const GLfloat *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD1IARBPROC) (GLenum target, GLint s); -typedef void (APIENTRYP PFNGLMULTITEXCOORD1IVARBPROC) (GLenum target, const GLint *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD1SARBPROC) (GLenum target, GLshort s); -typedef void (APIENTRYP PFNGLMULTITEXCOORD1SVARBPROC) (GLenum target, const GLshort *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD2DARBPROC) (GLenum target, GLdouble s, GLdouble t); -typedef void (APIENTRYP PFNGLMULTITEXCOORD2DVARBPROC) (GLenum target, const GLdouble *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD2FARBPROC) (GLenum target, GLfloat s, GLfloat t); -typedef void (APIENTRYP PFNGLMULTITEXCOORD2FVARBPROC) (GLenum target, const GLfloat *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD2IARBPROC) (GLenum target, GLint s, GLint t); -typedef void (APIENTRYP PFNGLMULTITEXCOORD2IVARBPROC) (GLenum target, const GLint *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD2SARBPROC) (GLenum target, GLshort s, GLshort t); -typedef void (APIENTRYP PFNGLMULTITEXCOORD2SVARBPROC) (GLenum target, const GLshort *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD3DARBPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r); -typedef void (APIENTRYP PFNGLMULTITEXCOORD3DVARBPROC) (GLenum target, const GLdouble *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD3FARBPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r); -typedef void (APIENTRYP PFNGLMULTITEXCOORD3FVARBPROC) (GLenum target, const GLfloat *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD3IARBPROC) (GLenum target, GLint s, GLint t, GLint r); -typedef void (APIENTRYP PFNGLMULTITEXCOORD3IVARBPROC) (GLenum target, const GLint *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD3SARBPROC) (GLenum target, GLshort s, GLshort t, GLshort r); -typedef void (APIENTRYP PFNGLMULTITEXCOORD3SVARBPROC) (GLenum target, const GLshort *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD4DARBPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q); -typedef void (APIENTRYP PFNGLMULTITEXCOORD4DVARBPROC) (GLenum target, const GLdouble *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD4FARBPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q); -typedef void (APIENTRYP PFNGLMULTITEXCOORD4FVARBPROC) (GLenum target, const GLfloat *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD4IARBPROC) (GLenum target, GLint s, GLint t, GLint r, GLint q); -typedef void (APIENTRYP PFNGLMULTITEXCOORD4IVARBPROC) (GLenum target, const GLint *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD4SARBPROC) (GLenum target, GLshort s, GLshort t, GLshort r, GLshort q); -typedef void (APIENTRYP PFNGLMULTITEXCOORD4SVARBPROC) (GLenum target, const GLshort *v); - -//GL_ARB_shader_objects -typedef void (APIENTRYP PFNGLDELETEOBJECTARBPROC) (unsigned int obj); -typedef unsigned int (APIENTRYP PFNGLGETHANDLEARBPROC) (GLenum pname); -typedef void (APIENTRYP PFNGLDETACHOBJECTARBPROC) (unsigned int containerObj, unsigned int attachedObj); -typedef unsigned int (APIENTRYP PFNGLCREATESHADEROBJECTARBPROC) (GLenum shaderType); -typedef void (APIENTRYP PFNGLSHADERSOURCEARBPROC) (unsigned int shaderObj, GLsizei count, const GLcharARB* *string, const GLint *length); -typedef void (APIENTRYP PFNGLCOMPILESHADERARBPROC) (unsigned int shaderObj); -typedef unsigned int (APIENTRYP PFNGLCREATEPROGRAMOBJECTARBPROC) (void); -typedef void (APIENTRYP PFNGLATTACHOBJECTARBPROC) (unsigned int containerObj, unsigned int obj); -typedef void (APIENTRYP PFNGLLINKPROGRAMARBPROC) (unsigned int programObj); -typedef void (APIENTRYP PFNGLUSEPROGRAMOBJECTARBPROC) (unsigned int programObj); -typedef void (APIENTRYP PFNGLVALIDATEPROGRAMARBPROC) (unsigned int programObj); -typedef void (APIENTRYP PFNGLUNIFORM1FARBPROC) (GLint location, GLfloat v0); -typedef void (APIENTRYP PFNGLUNIFORM2FARBPROC) (GLint location, GLfloat v0, GLfloat v1); -typedef void (APIENTRYP PFNGLUNIFORM3FARBPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2); -typedef void (APIENTRYP PFNGLUNIFORM4FARBPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); -typedef void (APIENTRYP PFNGLUNIFORM1IARBPROC) (GLint location, GLint v0); -typedef void (APIENTRYP PFNGLUNIFORM2IARBPROC) (GLint location, GLint v0, GLint v1); -typedef void (APIENTRYP PFNGLUNIFORM3IARBPROC) (GLint location, GLint v0, GLint v1, GLint v2); -typedef void (APIENTRYP PFNGLUNIFORM4IARBPROC) (GLint location, GLint v0, GLint v1, GLint v2, GLint v3); -typedef void (APIENTRYP PFNGLUNIFORM1FVARBPROC) (GLint location, GLsizei count, const GLfloat *value); -typedef void (APIENTRYP PFNGLUNIFORM2FVARBPROC) (GLint location, GLsizei count, const GLfloat *value); -typedef void (APIENTRYP PFNGLUNIFORM3FVARBPROC) (GLint location, GLsizei count, const GLfloat *value); -typedef void (APIENTRYP PFNGLUNIFORM4FVARBPROC) (GLint location, GLsizei count, const GLfloat *value); -typedef void (APIENTRYP PFNGLUNIFORM1IVARBPROC) (GLint location, GLsizei count, const GLint *value); -typedef void (APIENTRYP PFNGLUNIFORM2IVARBPROC) (GLint location, GLsizei count, const GLint *value); -typedef void (APIENTRYP PFNGLUNIFORM3IVARBPROC) (GLint location, GLsizei count, const GLint *value); -typedef void (APIENTRYP PFNGLUNIFORM4IVARBPROC) (GLint location, GLsizei count, const GLint *value); -typedef void (APIENTRYP PFNGLUNIFORMMATRIX2FVARBPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -typedef void (APIENTRYP PFNGLUNIFORMMATRIX3FVARBPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -typedef void (APIENTRYP PFNGLUNIFORMMATRIX4FVARBPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -typedef void (APIENTRYP PFNGLGETOBJECTPARAMETERFVARBPROC) (unsigned int obj, GLenum pname, GLfloat *params); -typedef void (APIENTRYP PFNGLGETOBJECTPARAMETERIVARBPROC) (unsigned int obj, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETINFOLOGARBPROC) (unsigned int obj, GLsizei maxLength, GLsizei *length, void *infoLog); -typedef void (APIENTRYP PFNGLGETATTACHEDOBJECTSARBPROC) (unsigned int containerObj, GLsizei maxCount, GLsizei *count, unsigned int *obj); -typedef GLint (APIENTRYP PFNGLGETUNIFORMLOCATIONARBPROC) (unsigned int programObj, const void *name); -typedef void (APIENTRYP PFNGLGETACTIVEUNIFORMARBPROC) (unsigned int programObj, GLuint index, GLsizei maxLength, GLsizei *length, GLint *size, GLenum *type, GLcharARB *name); -typedef void (APIENTRYP PFNGLGETUNIFORMFVARBPROC) (unsigned int programObj, GLint location, GLfloat *params); -typedef void (APIENTRYP PFNGLGETUNIFORMIVARBPROC) (unsigned int programObj, GLint location, GLint *params); -typedef void (APIENTRYP PFNGLGETSHADERSOURCEARBPROC) (unsigned int obj, GLsizei maxLength, GLsizei *length, void *source); - - -//GL_ARB_vertex_shader -typedef void (APIENTRYP PFNGLBINDATTRIBLOCATIONARBPROC) (unsigned int programObj, GLuint index, const GLcharARB *name); -typedef void (APIENTRYP PFNGLGETACTIVEATTRIBARBPROC) (unsigned int programObj, GLuint index, GLsizei maxLength, GLsizei *length, GLint *size, GLenum *type, GLcharARB *name); -typedef GLint (APIENTRYP PFNGLGETATTRIBLOCATIONARBPROC) (unsigned int programObj, const GLcharARB *name); - - -//GL_ARB_vertex_program -typedef void (APIENTRYP PFNGLVERTEXATTRIB1FARBPROC) (GLuint index, GLfloat x); -typedef void (APIENTRYP PFNGLVERTEXATTRIB1FVARBPROC) (GLuint index, const GLfloat *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB2FARBPROC) (GLuint index, GLfloat x, GLfloat y); -typedef void (APIENTRYP PFNGLVERTEXATTRIB2FVARBPROC) (GLuint index, const GLfloat *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB3FARBPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z); -typedef void (APIENTRYP PFNGLVERTEXATTRIB3FVARBPROC) (GLuint index, const GLfloat *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4FARBPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4FVARBPROC) (GLuint index, const GLfloat *v); -typedef void (APIENTRYP PFNGLGETPROGRAMSTRINGARBPROC) (GLenum target, GLenum pname, GLvoid *string); -typedef void (APIENTRYP PFNGLGETVERTEXATTRIBDVARBPROC) (GLuint index, GLenum pname, GLdouble *params); -typedef void (APIENTRYP PFNGLGETVERTEXATTRIBFVARBPROC) (GLuint index, GLenum pname, GLfloat *params); -typedef void (APIENTRYP PFNGLGETVERTEXATTRIBIVARBPROC) (GLuint index, GLenum pname, GLint *params); - -#define GL_FRAGMENT_SHADER 0x8B30 -#define GL_COMPILE_STATUS 0x8B81 -#define GL_LINK_STATUS 0x8B82 -#define GL_VALIDATE_STATUS 0x8B83 - - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/source/gameengine/Converter/BL_ArmatureObject.cpp b/source/gameengine/Converter/BL_ArmatureObject.cpp index d4712efda9e..f73d5b42a01 100644 --- a/source/gameengine/Converter/BL_ArmatureObject.cpp +++ b/source/gameengine/Converter/BL_ArmatureObject.cpp @@ -144,7 +144,7 @@ void BL_ArmatureObject::GetPose(bPose **pose) { /* If the caller supplies a null pose, create a new one. */ /* Otherwise, copy the armature's pose channels into the caller-supplied pose */ - + if (!*pose) { /* probably not to good of an idea to duplicate everying, but it clears up diff --git a/source/gameengine/Converter/BL_BlenderDataConversion.cpp b/source/gameengine/Converter/BL_BlenderDataConversion.cpp index cb981f55c5a..0ad9258bcc0 100644 --- a/source/gameengine/Converter/BL_BlenderDataConversion.cpp +++ b/source/gameengine/Converter/BL_BlenderDataConversion.cpp @@ -510,6 +510,7 @@ BL_Material* ConvertMaterial( } } } + // above one tex the switches here // are not used switch(valid_index) { @@ -588,6 +589,9 @@ BL_Material* ConvertMaterial( MT_Point2 uv[4]; MT_Point2 uv2[4]; + uv[0]= uv[1]= uv[2]= uv[3]= MT_Point2(0.0f, 0.0f); + uv2[0]= uv2[1]= uv2[2]= uv2[3]= MT_Point2(0.0f, 0.0f); + if( validface ) { material->ras_mode |= !( @@ -731,14 +735,14 @@ static MT_Vector4* BL_ComputeMeshTangentSpace(Mesh* mesh) MT_Vector3 *tan1 = new MT_Vector3[mesh->totvert]; MT_Vector3 *tan2 = new MT_Vector3[mesh->totvert]; - unsigned int v; + int v; for (v = 0; v < mesh->totvert; v++) { tan1[v] = MT_Vector3(0.0, 0.0, 0.0); tan2[v] = MT_Vector3(0.0, 0.0, 0.0); } - for (unsigned int p = 0; p < mesh->totface; p++, mface++, tface++) + for (int p = 0; p < mesh->totface; p++, mface++, tface++) { MT_Vector3 v1(mesh->mvert[mface->v1].co), v2(mesh->mvert[mface->v2].co), @@ -830,9 +834,10 @@ RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, RAS_IRenderTools* } } - meshobj->SetName(mesh->id.name); meshobj->m_xyz_index_to_vertex_index_mapping.resize(mesh->totvert); + if(skinMesh) + ((BL_SkinMeshObject*)meshobj)->m_mvert_to_dvert_mapping.resize(mesh->totvert); for (int f=0;ftotface;f++,mface++) { @@ -882,7 +887,7 @@ RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, RAS_IRenderTools* Material* ma = 0; bool polyvisible = true; RAS_IPolyMaterial* polymat = NULL; - BL_Material *bl_mat; + BL_Material *bl_mat = NULL; if(converter->GetMaterials()) { @@ -892,6 +897,7 @@ RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, RAS_IRenderTools* ma = give_current_material(blenderobj, 1); bl_mat = ConvertMaterial(mesh, ma, tface, mface, mmcol, lightlayer, blenderobj, layers); + bl_mat->glslmat = converter->GetGLSLMaterials(); // set the index were dealing with bl_mat->material_index = (int)mface->mat_nr; @@ -1066,19 +1072,19 @@ RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, RAS_IRenderTools* d3=((BL_SkinMeshObject*)meshobj)->FindOrAddDeform(vtxarray, mface->v3, &mesh->dvert[mface->v3], polymat); if (nverts==4) d4=((BL_SkinMeshObject*)meshobj)->FindOrAddDeform(vtxarray, mface->v4, &mesh->dvert[mface->v4], polymat); - poly->SetVertex(0,((BL_SkinMeshObject*)meshobj)->FindOrAddVertex(vtxarray,pt0,uv0,uv20,tan0,rgb0,no0,d1,flat, polymat)); - poly->SetVertex(1,((BL_SkinMeshObject*)meshobj)->FindOrAddVertex(vtxarray,pt1,uv1,uv21,tan1,rgb1,no1,d2,flat, polymat)); - poly->SetVertex(2,((BL_SkinMeshObject*)meshobj)->FindOrAddVertex(vtxarray,pt2,uv2,uv22,tan2,rgb2,no2,d3,flat, polymat)); + poly->SetVertex(0,((BL_SkinMeshObject*)meshobj)->FindOrAddVertex(vtxarray,pt0,uv0,uv20,tan0,rgb0,no0,d1,flat,polymat,mface->v1)); + poly->SetVertex(1,((BL_SkinMeshObject*)meshobj)->FindOrAddVertex(vtxarray,pt1,uv1,uv21,tan1,rgb1,no1,d2,flat,polymat,mface->v2)); + poly->SetVertex(2,((BL_SkinMeshObject*)meshobj)->FindOrAddVertex(vtxarray,pt2,uv2,uv22,tan2,rgb2,no2,d3,flat,polymat,mface->v3)); if (nverts==4) - poly->SetVertex(3,((BL_SkinMeshObject*)meshobj)->FindOrAddVertex(vtxarray,pt3,uv3,uv23,tan3,rgb3,no3,d4, flat,polymat)); + poly->SetVertex(3,((BL_SkinMeshObject*)meshobj)->FindOrAddVertex(vtxarray,pt3,uv3,uv23,tan3,rgb3,no3,d4,flat,polymat,mface->v4)); } else { - poly->SetVertex(0,meshobj->FindOrAddVertex(vtxarray,pt0,uv0,uv20,tan0,rgb0,no0,polymat,mface->v1)); - poly->SetVertex(1,meshobj->FindOrAddVertex(vtxarray,pt1,uv1,uv21,tan1,rgb1,no1,polymat,mface->v2)); - poly->SetVertex(2,meshobj->FindOrAddVertex(vtxarray,pt2,uv2,uv22,tan2,rgb2,no2,polymat,mface->v3)); + poly->SetVertex(0,meshobj->FindOrAddVertex(vtxarray,pt0,uv0,uv20,tan0,rgb0,no0,false,polymat,mface->v1)); + poly->SetVertex(1,meshobj->FindOrAddVertex(vtxarray,pt1,uv1,uv21,tan1,rgb1,no1,false,polymat,mface->v2)); + poly->SetVertex(2,meshobj->FindOrAddVertex(vtxarray,pt2,uv2,uv22,tan2,rgb2,no2,false,polymat,mface->v3)); if (nverts==4) - poly->SetVertex(3,meshobj->FindOrAddVertex(vtxarray,pt3,uv3,uv23,tan3,rgb3,no3,polymat,mface->v4)); + poly->SetVertex(3,meshobj->FindOrAddVertex(vtxarray,pt3,uv3,uv23,tan3,rgb3,no3,false,polymat,mface->v4)); } meshobj->AddPolygon(poly); if (poly->IsCollider()) @@ -1116,6 +1122,9 @@ RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, RAS_IRenderTools* layer.face++; } } + meshobj->m_xyz_index_to_vertex_index_mapping.clear(); + if(skinMesh) + ((BL_SkinMeshObject*)meshobj)->m_mvert_to_dvert_mapping.clear(); meshobj->UpdateMaterialList(); // pre calculate texture generation diff --git a/source/gameengine/Converter/BL_MeshDeformer.cpp b/source/gameengine/Converter/BL_MeshDeformer.cpp index ab31179b047..85ba894f9a5 100644 --- a/source/gameengine/Converter/BL_MeshDeformer.cpp +++ b/source/gameengine/Converter/BL_MeshDeformer.cpp @@ -43,27 +43,25 @@ #include "BL_SkinMeshObject.h" #include "DNA_mesh_types.h" #include "DNA_meshdata_types.h" -#include "BLI_arithb.h" #include "GEN_Map.h" #include "STR_HashedString.h" - bool BL_MeshDeformer::Apply(RAS_IPolyMaterial *mat) { size_t i, j, index; vecVertexArray array; vecIndexArrays mvarray; vecIndexArrays diarray; - + RAS_TexVert *tv; MVert *mvert; - + // For each material array = m_pMeshObject->GetVertexCache(mat); mvarray = m_pMeshObject->GetMVertCache(mat); diarray = m_pMeshObject->GetDIndexCache(mat); - + // For each array for (i=0; itotvert; v++){ - m_transnors[v]=MT_Point3(0,0,0); - } - - /* Find the face normals */ - for (f = 0; ftotface; f++){ - // Make new face normal based on the transverts - MFace *mf= &((MFace*)m_bmesh->mface)[f]; - - if (mf->v3) { - for (int vl=0; vl<3; vl++){ - co1[vl]=m_transverts[mf->v1][vl]; - co2[vl]=m_transverts[mf->v2][vl]; - co3[vl]=m_transverts[mf->v3][vl]; - if (mf->v4) - co4[vl]=m_transverts[mf->v4][vl]; + vecIndexArrays indexarrays; + vecIndexArrays mvarrays; + vecIndexArrays diarrays; + vecVertexArray vertexarrays; + size_t i, j; + + /* set vertex normals to zero */ + for (i=0; i<(size_t)m_bmesh->totvert; i++) + m_transnors[i] = MT_Vector3(0.0f, 0.0f, 0.0f); + + /* add face normals to vertices. */ + for(RAS_MaterialBucket::Set::iterator mit = m_pMeshObject->GetFirstMaterial(); + mit != m_pMeshObject->GetLastMaterial(); ++ mit) { + RAS_IPolyMaterial *mat = (*mit)->GetPolyMaterial(); + + indexarrays = m_pMeshObject->GetIndexCache(mat); + vertexarrays = m_pMeshObject->GetVertexCache(mat); + diarrays = m_pMeshObject->GetDIndexCache(mat); + mvarrays = m_pMeshObject->GetMVertCache(mat); + + for (i=0; iUsesTriangles()? 3: 4; + + for(j=0; jv4) - CalcNormFloat4(co1, co2, co3, co4, fnor); - else - CalcNormFloat(co1, co2, co3, fnor); - - /* Decide which normals are affected by this face's normal */ - m_transnors[mf->v1]+=MT_Point3(fnor); - m_transnors[mf->v2]+=MT_Point3(fnor); - m_transnors[mf->v3]+=MT_Point3(fnor); - if (mf->v4) - m_transnors[mf->v4]+=MT_Point3(fnor); } } - - for (v =0; vtotvert; v++){ -// float nor[3]; - m_transnors[v]=m_transnors[v].safe_normalized(); -// nor[0]=m_transnors[v][0]; -// nor[1]=m_transnors[v][1]; -// nor[2]=m_transnors[v][2]; - - }; + /* assign smooth vertex normals */ + for(RAS_MaterialBucket::Set::iterator mit = m_pMeshObject->GetFirstMaterial(); + mit != m_pMeshObject->GetLastMaterial(); ++ mit) { + RAS_IPolyMaterial *mat = (*mit)->GetPolyMaterial(); + + vertexarrays = m_pMeshObject->GetVertexCache(mat); + diarrays = m_pMeshObject->GetDIndexCache(mat); + mvarrays = m_pMeshObject->GetMVertCache(mat); + + for (i=0; itotvert+m_bmesh->totface){ + if (m_tvtot!=m_bmesh->totvert+m_bmesh->totface) { if (m_transverts) - delete []m_transverts; + delete [] m_transverts; if (m_transnors) - delete []m_transnors; + delete [] m_transnors; - m_transnors =new MT_Point3[m_bmesh->totvert+m_bmesh->totface]; m_transverts=new float[(sizeof(*m_transverts)*m_bmesh->totvert)][3]; + m_transnors=new MT_Vector3[m_bmesh->totvert]; m_tvtot = m_bmesh->totvert; } } diff --git a/source/gameengine/Converter/BL_MeshDeformer.h b/source/gameengine/Converter/BL_MeshDeformer.h index a6be11d786e..88dc2500859 100644 --- a/source/gameengine/Converter/BL_MeshDeformer.h +++ b/source/gameengine/Converter/BL_MeshDeformer.h @@ -48,9 +48,9 @@ public: BL_MeshDeformer(struct Object* obj, class BL_SkinMeshObject *meshobj ): m_pMeshObject(meshobj), m_bmesh((struct Mesh*)(obj->data)), + m_transverts(0), + m_transnors(0), m_objMesh(obj), - m_transnors(NULL), - m_transverts(NULL), m_tvtot(0) {}; virtual ~BL_MeshDeformer(); @@ -62,12 +62,11 @@ public: protected: class BL_SkinMeshObject* m_pMeshObject; struct Mesh* m_bmesh; - MT_Point3* m_transnors; - //MT_Point3* m_transverts; // this is so m_transverts doesn't need to be converted // before deformation float (*m_transverts)[3]; + MT_Vector3* m_transnors; struct Object* m_objMesh; // -- int m_tvtot; diff --git a/source/gameengine/Converter/BL_SkinDeformer.cpp b/source/gameengine/Converter/BL_SkinDeformer.cpp index 14faa3317d0..0f884674c09 100644 --- a/source/gameengine/Converter/BL_SkinDeformer.cpp +++ b/source/gameengine/Converter/BL_SkinDeformer.cpp @@ -57,7 +57,6 @@ extern "C"{ #define __NLA_DEFNORMALS //#undef __NLA_DEFNORMALS - BL_SkinDeformer::BL_SkinDeformer( struct Object *bmeshobj_old, // Blender object that owns the new mesh struct Object *bmeshobj_new, // Blender object that owns the original mesh @@ -87,25 +86,15 @@ BL_SkinDeformer::~BL_SkinDeformer() Mat4CpyMat4(m_objMesh->obmat, m_obmat); } -/* XXX note, this __NLA_OLDDEFORM define seems to be obsolete */ - bool BL_SkinDeformer::Apply(RAS_IPolyMaterial *mat) { size_t i, j, index; vecVertexArray array; -#ifdef __NLA_OLDDEFORM - vecMVertArray mvarray; -#else vecIndexArrays mvarray; -#endif vecMDVertArray dvarray; vecIndexArrays diarray; RAS_TexVert *tv; -#ifdef __NLA_OLDDEFORM - MVert *mvert; - MDeformVert *dvert; -#endif MT_Point3 pt; // float co[3]; @@ -115,48 +104,24 @@ bool BL_SkinDeformer::Apply(RAS_IPolyMaterial *mat) Update(); array = m_pMeshObject->GetVertexCache(mat); -#ifdef __NLA_OLDDEFORM - dvarray = m_pMeshObject->GetDVertCache(mat); -#endif mvarray = m_pMeshObject->GetMVertCache(mat); diarray = m_pMeshObject->GetDIndexCache(mat); - // For each array - for (i=0; isize(); j++){ + for (j=0; jsize(); j++) { tv = &((*array[i])[j]); index = ((*diarray[i])[j]); -#ifdef __NLA_OLDDEFORM - pt = tv->xyz(); - mvert = ((*mvarray[i])[index]); - dvert = ((*dvarray[i])[index]); -#endif // Copy the untransformed data from the original mvert -#ifdef __NLA_OLDDEFORM - co[0]=mvert->co[0]; - co[1]=mvert->co[1]; - co[2]=mvert->co[2]; - - // Do the deformation -/* XXX note, doesnt exist anymore */ -// GB_calc_armature_deform(co, dvert); - tv->SetXYZ(co); -#else // Set the data tv->SetXYZ(m_transverts[((*mvarray[i])[index])]); -#ifdef __NLA_DEFNORMALS - - tv->SetNormal(m_transnors[((*mvarray[i])[index])]); -#endif -#endif } } - + return true; } @@ -197,7 +162,9 @@ void BL_SkinDeformer::Update(void) VECCOPY(m_transverts[v], m_bmesh->mvert[v].co); armature_deform_verts( par_arma, m_objMesh, NULL, m_transverts, NULL, m_bmesh->totvert, ARM_DEF_VGROUP, NULL, NULL ); +#ifdef __NLA_DEFNORMALS RecalcNormals(); +#endif /* Update the current frame */ m_lastUpdate=m_armobj->GetLastFrame(); diff --git a/source/gameengine/Converter/BL_SkinDeformer.h b/source/gameengine/Converter/BL_SkinDeformer.h index e130dc15dbf..79f6453a25d 100644 --- a/source/gameengine/Converter/BL_SkinDeformer.h +++ b/source/gameengine/Converter/BL_SkinDeformer.h @@ -69,8 +69,8 @@ public: m_armobj(arma), m_lastUpdate(-1), m_defbase(&bmeshobj->defbase), - m_releaseobject(false), - m_restoremat(false) + m_restoremat(false), + m_releaseobject(false) { }; diff --git a/source/gameengine/Converter/BL_SkinMeshObject.cpp b/source/gameengine/Converter/BL_SkinMeshObject.cpp index 8bc78c7f757..69feb72f5dc 100644 --- a/source/gameengine/Converter/BL_SkinMeshObject.cpp +++ b/source/gameengine/Converter/BL_SkinMeshObject.cpp @@ -53,23 +53,27 @@ void BL_SkinMeshObject::AddPolygon(RAS_Polygon* poly) RAS_MeshObject::AddPolygon(poly); } -#ifdef __NLA_OLDDEFORM -int BL_SkinMeshObject::FindOrAddDeform(int vtxarray, struct MVert *mv, struct MDeformVert *dv, RAS_IPolyMaterial* mat) -#else int BL_SkinMeshObject::FindOrAddDeform(unsigned int vtxarray, unsigned int mv, struct MDeformVert *dv, RAS_IPolyMaterial* mat) -#endif { BL_SkinArrayOptimizer* ao = (BL_SkinArrayOptimizer*)GetArrayOptimizer(mat);//*(m_matVertexArrays[*mat]); int numvert = ao->m_MvertArrayCache1[vtxarray]->size(); - + /* Check to see if this has already been pushed */ - for (unsigned int i=0; im_MvertArrayCache1[vtxarray]->size(); i++){ - if (mv == (*ao->m_MvertArrayCache1[vtxarray])[i]) - return i; + for (vector::iterator it = m_mvert_to_dvert_mapping[mv].begin(); + it != m_mvert_to_dvert_mapping[mv].end(); + it++) + { + if(it->mat == mat) + return it->index; } ao->m_MvertArrayCache1[vtxarray]->push_back(mv); ao->m_DvertArrayCache1[vtxarray]->push_back(dv); + + BL_MDVertMap mdmap; + mdmap.mat = mat; + mdmap.index = numvert; + m_mvert_to_dvert_mapping[mv].push_back(mdmap); return numvert; }; @@ -105,11 +109,7 @@ int BL_SkinMeshObject::FindVertexArray(int numverts,RAS_IPolyMaterial* polymat) KX_IndexArray *ia = new KX_IndexArray(); ao->m_IndexArrayCache1.push_back(ia); -#ifdef __NLA_OLDDEFORM - BL_MVertArray *bva = new BL_MVertArray(); -#else KX_IndexArray *bva = new KX_IndexArray(); -#endif ao->m_MvertArrayCache1.push_back(bva); BL_DeformVertArray *dva = new BL_DeformVertArray(); diff --git a/source/gameengine/Converter/BL_SkinMeshObject.h b/source/gameengine/Converter/BL_SkinMeshObject.h index 0ca7428c0f0..2422d4cd4c9 100644 --- a/source/gameengine/Converter/BL_SkinMeshObject.h +++ b/source/gameengine/Converter/BL_SkinMeshObject.h @@ -106,6 +106,9 @@ class BL_SkinMeshObject : public RAS_MeshObject protected: public: + struct BL_MDVertMap { RAS_IPolyMaterial *mat; int index; }; + vector > m_mvert_to_dvert_mapping; + void Bucketize(double* oglmatrix,void* clientobj,bool useObjectColor,const MT_Vector4& rgbavec); // void Bucketize(double* oglmatrix,void* clientobj,bool useObjectColor,const MT_Vector4& rgbavec,class RAS_BucketManager* bucketmgr); @@ -139,37 +142,17 @@ public: const MT_Point2& uv2, const MT_Vector4& tangent, const unsigned int rgbacolor, - const MT_Vector3& normal, int defnr, bool flat, RAS_IPolyMaterial* mat) + const MT_Vector3& normal, int defnr, bool flat, RAS_IPolyMaterial* mat, int origindex) { - RAS_TexVert tempvert(xyz,uv,uv2, tangent,rgbacolor,normal,flat ? TV_CALCFACENORMAL : 0); - - // KX_ArrayOptimizer* ao = GetArrayOptimizer(mat);//*(m_matVertexArrays[*mat]); - BL_SkinArrayOptimizer* ao = (BL_SkinArrayOptimizer*)GetArrayOptimizer(mat);//*(m_matVertexArrays[*mat]); - - int numverts = ao->m_VertexArrayCache1[vtxarray]->size();//m_VertexArrayCount[vtxarray]; - - int index=-1; - - for (int i=0;im_VertexArrayCache1[vtxarray])[i]; - if (tempvert.closeTo(&vtx)) - { - index = i; - break; - } - - } - if (index >= 0) - return index; - - // no vertex found, add one - ao->m_VertexArrayCache1[vtxarray]->push_back(tempvert); - ao->m_DIndexArrayCache1[vtxarray]->push_back(defnr); - - return numverts; - - + BL_SkinArrayOptimizer* ao = (BL_SkinArrayOptimizer*)GetArrayOptimizer(mat); + int numverts = ao->m_VertexArrayCache1[vtxarray]->size(); + int index = RAS_MeshObject::FindOrAddVertex(vtxarray, xyz, uv, uv2, tangent, rgbacolor, normal, flat, mat, origindex); + + /* this means a new vertex was added, so we add the defnr too */ + if(index == numverts) + ao->m_DIndexArrayCache1[vtxarray]->push_back(defnr); + + return index; } }; diff --git a/source/gameengine/Converter/KX_BlenderSceneConverter.cpp b/source/gameengine/Converter/KX_BlenderSceneConverter.cpp index 8640e69102b..de91bce2ab1 100644 --- a/source/gameengine/Converter/KX_BlenderSceneConverter.cpp +++ b/source/gameengine/Converter/KX_BlenderSceneConverter.cpp @@ -100,7 +100,8 @@ KX_BlenderSceneConverter::KX_BlenderSceneConverter( m_sipo(sipo), m_ketsjiEngine(engine), m_alwaysUseExpandFraming(false), - m_usemat(false) + m_usemat(false), + m_useglslmat(false) { m_newfilename = ""; } @@ -449,6 +450,13 @@ void KX_BlenderSceneConverter::RemoveScene(KX_Scene *scene) void KX_BlenderSceneConverter::SetMaterials(bool val) { m_usemat = val; + m_useglslmat = false; +} + +void KX_BlenderSceneConverter::SetGLSLMaterials(bool val) +{ + m_usemat = val; + m_useglslmat = val; } bool KX_BlenderSceneConverter::GetMaterials() @@ -456,6 +464,10 @@ bool KX_BlenderSceneConverter::GetMaterials() return m_usemat; } +bool KX_BlenderSceneConverter::GetGLSLMaterials() +{ + return m_useglslmat; +} void KX_BlenderSceneConverter::RegisterBlenderMaterial(BL_Material *mat) { diff --git a/source/gameengine/Converter/KX_BlenderSceneConverter.h b/source/gameengine/Converter/KX_BlenderSceneConverter.h index a45d7396875..e5d6ccc5caf 100644 --- a/source/gameengine/Converter/KX_BlenderSceneConverter.h +++ b/source/gameengine/Converter/KX_BlenderSceneConverter.h @@ -75,6 +75,7 @@ class KX_BlenderSceneConverter : public KX_ISceneConverter class KX_Scene* m_currentScene; // Scene being converted bool m_alwaysUseExpandFraming; bool m_usemat; + bool m_useglslmat; void localDel_ipoCurve ( IpoCurve * icu ,struct SpaceIpo* sipo); // struct Ipo* findIpoForName(char* objName); @@ -146,6 +147,10 @@ public: virtual void SetMaterials(bool val); virtual bool GetMaterials(); + // use blender glsl materials + virtual void SetGLSLMaterials(bool val); + virtual bool GetGLSLMaterials(); + }; #endif //__KX_BLENDERSCENECONVERTER_H diff --git a/source/gameengine/GamePlayer/common/CMakeLists.txt b/source/gameengine/GamePlayer/common/CMakeLists.txt index 29cdcd640f5..e26f8b9d69a 100644 --- a/source/gameengine/GamePlayer/common/CMakeLists.txt +++ b/source/gameengine/GamePlayer/common/CMakeLists.txt @@ -69,6 +69,7 @@ SET(INC ../../../../source/gameengine/GamePlayer/ghost ../../../../source/blender/misc ../../../../source/blender/blenloader + ../../../../extern/glew/include ${PYTHON_INC} ${SOLID_INC} ${PNG_INC} diff --git a/source/gameengine/GamePlayer/common/GPC_Canvas.h b/source/gameengine/GamePlayer/common/GPC_Canvas.h index bd66c865988..f82166dfa88 100644 --- a/source/gameengine/GamePlayer/common/GPC_Canvas.h +++ b/source/gameengine/GamePlayer/common/GPC_Canvas.h @@ -33,18 +33,12 @@ #include "RAS_ICanvas.h" #include "RAS_Rect.h" -#if defined(WIN32) || defined(__APPLE__) - #ifdef WIN32 - #pragma warning (disable:4786) // suppress stl-MSVC debug info warning - #include - #include - #else // WIN32 - // __APPLE__ is defined - #include - #endif // WIN32 -#else //defined(WIN32) || defined(__APPLE__) - #include -#endif //defined(WIN32) || defined(__APPLE__) +#ifdef WIN32 + #pragma warning (disable:4786) // suppress stl-MSVC debug info warning + #include +#endif // WIN32 + +#include "GL/glew.h" #include diff --git a/source/gameengine/GamePlayer/common/GPC_PolygonMaterial.cpp b/source/gameengine/GamePlayer/common/GPC_PolygonMaterial.cpp index c2f15aefe16..b1e2b5af0e6 100644 --- a/source/gameengine/GamePlayer/common/GPC_PolygonMaterial.cpp +++ b/source/gameengine/GamePlayer/common/GPC_PolygonMaterial.cpp @@ -31,23 +31,7 @@ #include #endif -#ifdef WIN32 -#include -#endif // WIN32 -#ifdef __APPLE__ -#define GL_GLEXT_LEGACY 1 -#include -#include -#else -#include -#if defined(__sun__) && !defined(__sparc__) -#include -#else -#include -#endif -#endif - - +#include "GL/glew.h" #include "GPC_PolygonMaterial.h" #include "MT_Vector3.h" @@ -88,7 +72,6 @@ static int fDoMipMap = 1; static int fLinearMipMap=1; static int fAlphamode= -1; -using namespace bgl; /* (n&(n-1)) zeros the least significant bit of n */ static int is_pow2(int num) { return ((num)&(num-1))==0; diff --git a/source/gameengine/GamePlayer/common/GPC_RenderTools.cpp b/source/gameengine/GamePlayer/common/GPC_RenderTools.cpp index 885981a2898..44eeccedbd1 100644 --- a/source/gameengine/GamePlayer/common/GPC_RenderTools.cpp +++ b/source/gameengine/GamePlayer/common/GPC_RenderTools.cpp @@ -34,12 +34,8 @@ #include #endif -#ifdef __APPLE__ -#define GL_GLEXT_LEGACY 1 -#include -#else -#include -#endif +#include "GL/glew.h" + #include #include "GPC_RenderTools.h" @@ -137,10 +133,6 @@ int GPC_RenderTools::ProcessLighting(int layer) { if (m_clientobject) { - if (layer == RAS_LIGHT_OBJECT_LAYER) - { - layer = static_cast(m_clientobject)->GetLayer(); - } if (applyLights(layer)) { EnableOpenGLLights(); @@ -160,7 +152,7 @@ void GPC_RenderTools::EnableOpenGLLights() glEnable(GL_LIGHTING); glEnable(GL_COLOR_MATERIAL); glColorMaterial(GL_FRONT_AND_BACK,GL_DIFFUSE); - if (bgl::QueryExtension(bgl::_GL_EXT_separate_specular_color) || bgl::QueryVersion(1, 2)) + if (GLEW_EXT_separate_specular_color || GLEW_VERSION_1_2) glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR); } diff --git a/source/gameengine/GamePlayer/common/GPC_RenderTools.h b/source/gameengine/GamePlayer/common/GPC_RenderTools.h index ee0212da643..f7230cb0865 100644 --- a/source/gameengine/GamePlayer/common/GPC_RenderTools.h +++ b/source/gameengine/GamePlayer/common/GPC_RenderTools.h @@ -30,18 +30,11 @@ #ifndef __GPC_RENDERTOOLS_H #define __GPC_RENDERTOOLS_H -#if defined(WIN32) || defined(__APPLE__) - #ifdef WIN32 - #include - #include - #else // WIN32 - // __APPLE__ is defined - #include - #endif // WIN32 -#else //defined(WIN32) || defined(__APPLE__) - #include -#endif //defined(WIN32) || defined(__APPLE__) +#ifdef WIN32 + #include +#endif // WIN32 +#include "GL/glew.h" #include "RAS_IRenderTools.h" diff --git a/source/gameengine/GamePlayer/common/Makefile b/source/gameengine/GamePlayer/common/Makefile index 508dee18755..19d792ddbdb 100644 --- a/source/gameengine/GamePlayer/common/Makefile +++ b/source/gameengine/GamePlayer/common/Makefile @@ -35,6 +35,7 @@ include nan_compile.mk CCFLAGS += $(LEVEL_1_CPP_WARNINGS) +CPPFLAGS += -I$(NAN_GLEW)/include CPPFLAGS += -I$(OPENGL_HEADERS) CPPFLAGS += -I../../../blender/blenkernel diff --git a/source/gameengine/GamePlayer/common/SConscript b/source/gameengine/GamePlayer/common/SConscript index 6ff3ae10735..3b2367d2592 100644 --- a/source/gameengine/GamePlayer/common/SConscript +++ b/source/gameengine/GamePlayer/common/SConscript @@ -45,7 +45,8 @@ incs = ['.', '#source/gameengine/Network/LoopBackNetwork', '#source/gameengine/GamePlayer/ghost', '#source/blender/misc', - '#source/blender/blenloader'] + '#source/blender/blenloader', + '#extern/glew/include'] #This is all plugin stuff! #if sys.platform=='win32': diff --git a/source/gameengine/GamePlayer/ghost/CMakeLists.txt b/source/gameengine/GamePlayer/ghost/CMakeLists.txt index 3d17cd2cfdd..d9f0675001f 100644 --- a/source/gameengine/GamePlayer/ghost/CMakeLists.txt +++ b/source/gameengine/GamePlayer/ghost/CMakeLists.txt @@ -65,6 +65,7 @@ SET(INC ../../../../source/blender/misc ../../../../source/blender/blenloader ../../../../extern/solid + ../../../../extern/glew/include ${PYTHON_INC} ) diff --git a/source/gameengine/GamePlayer/ghost/GPG_Application.cpp b/source/gameengine/GamePlayer/ghost/GPG_Application.cpp index dfd15227501..c4cf698d5ee 100644 --- a/source/gameengine/GamePlayer/ghost/GPG_Application.cpp +++ b/source/gameengine/GamePlayer/ghost/GPG_Application.cpp @@ -37,18 +37,7 @@ #include #endif -#ifdef __APPLE__ -#define GL_GLEXT_LEGACY 1 -#include -#include -#else -#include -#if defined(__sun__) && !defined(__sparc__) -#include -#else -#include -#endif -#endif +#include "GL/glew.h" #include "GPG_Application.h" @@ -134,7 +123,8 @@ GPG_Application::GPG_Application(GHOST_ISystem* system, struct Main* maggie, STR m_sceneconverter(0), m_networkdevice(0), m_audiodevice(0), - m_blendermat(0) + m_blendermat(0), + m_blenderglslmat(0) { fSystem = system; } @@ -487,7 +477,8 @@ bool GPG_Application::initEngine(GHOST_IWindow* window, const int stereoMode) { if (!m_engineInitialized) { - bgl::InitExtensions(1); + glewInit(); + bgl::InitExtensions(true); // get and set the preferences SYS_SystemHandle syshandle = SYS_GetSystem(); @@ -508,26 +499,10 @@ bool GPG_Application::initEngine(GHOST_IWindow* window, const int stereoMode) bool useVertexArrays = SYS_GetCommandLineInt(syshandle,"vertexarrays",1) != 0; bool useLists = (SYS_GetCommandLineInt(syshandle, "displaylists", G.fileflags & G_FILE_DIAPLAY_LISTS) != 0); -#if defined(GL_ARB_multitexture) && defined(WITH_GLEXT) - if (!getenv("WITHOUT_GLEXT")) { + if(GLEW_ARB_multitexture && GLEW_VERSION_1_1) { int gameflag =(G.fileflags & G_FILE_GAME_MAT); - - if(bgl::RAS_EXT_support._ARB_multitexture && bgl::QueryVersion(1, 1)) { - m_blendermat = (SYS_GetCommandLineInt(syshandle, "blender_material", gameflag) != 0); - int unitmax=0; - glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, (GLint*)&unitmax); - bgl::max_texture_units = MAXTEX>unitmax?unitmax:MAXTEX; - //std::cout << "using(" << bgl::max_texture_units << ") of(" << unitmax << ") texture units." << std::endl; - } else { - bgl::max_texture_units = 0; - } - } else { - m_blendermat=0; + m_blendermat = (SYS_GetCommandLineInt(syshandle, "blender_material", gameflag) != 0); } -#else - m_blendermat=0; -#endif//GL_ARB_multitexture - // ---------------------------------- // create the canvas, rasterizer and rendertools m_canvas = new GPG_Canvas(window); @@ -545,7 +520,7 @@ bool GPG_Application::initEngine(GHOST_IWindow* window, const int stereoMode) } else { m_rasterizer = new RAS_ListRasterizer(m_canvas); } - else if (useVertexArrays && bgl::QueryVersion(1, 1)) + else if (useVertexArrays && GLEW_VERSION_1_1) m_rasterizer = new RAS_VAOpenGLRasterizer(m_canvas); else m_rasterizer = new RAS_OpenGLRasterizer(m_canvas); @@ -655,6 +630,8 @@ bool GPG_Application::startEngine(void) // sceneconverter->SetAlwaysUseExpandFraming(true); if(m_blendermat) m_sceneconverter->SetMaterials(true); + if(m_blenderglslmat) + m_sceneconverter->SetGLSLMaterials(true); KX_Scene* startscene = new KX_Scene(m_keyboard, m_mouse, diff --git a/source/gameengine/GamePlayer/ghost/GPG_Application.h b/source/gameengine/GamePlayer/ghost/GPG_Application.h index 024ca1dbf32..17f5add8b19 100644 --- a/source/gameengine/GamePlayer/ghost/GPG_Application.h +++ b/source/gameengine/GamePlayer/ghost/GPG_Application.h @@ -141,6 +141,7 @@ protected: SND_IAudioDevice* m_audiodevice; bool m_blendermat; + bool m_blenderglslmat; }; diff --git a/source/gameengine/GamePlayer/ghost/Makefile b/source/gameengine/GamePlayer/ghost/Makefile index d5aae181396..13940ac3fc8 100644 --- a/source/gameengine/GamePlayer/ghost/Makefile +++ b/source/gameengine/GamePlayer/ghost/Makefile @@ -36,6 +36,7 @@ include nan_compile.mk CCFLAGS += $(LEVEL_1_CPP_WARNINGS) # OpenGL header files +CPPFLAGS += -I$(NAN_GLEW)/include CPPFLAGS += -I$(OPENGL_HEADERS) CPPFLAGS += -I$(NAN_STRING)/include CPPFLAGS += -I$(NAN_BMFONT)/include diff --git a/source/gameengine/GamePlayer/ghost/SConscript b/source/gameengine/GamePlayer/ghost/SConscript index bd37777031e..f3cce6c7443 100644 --- a/source/gameengine/GamePlayer/ghost/SConscript +++ b/source/gameengine/GamePlayer/ghost/SConscript @@ -39,7 +39,8 @@ incs = ['.', '#source/gameengine/Network/LoopBackNetwork', '#source/gameengine/GamePlayer/common', '#source/blender/misc', - '#source/blender/blenloader'] + '#source/blender/blenloader', + '#extern/glew/include'] incs += Split(env['BF_PYTHON_INC']) incs += Split(env['BF_SOLID_INC']) diff --git a/source/gameengine/Ketsji/BL_BlenderShader.cpp b/source/gameengine/Ketsji/BL_BlenderShader.cpp new file mode 100644 index 00000000000..06e012123b1 --- /dev/null +++ b/source/gameengine/Ketsji/BL_BlenderShader.cpp @@ -0,0 +1,149 @@ + +#include "DNA_customdata_types.h" + +#include "BL_BlenderShader.h" + +#if 0 +#include "GPU_extensions.h" +#include "GPU_material.h" +#endif + +#include "RAS_MeshObject.h" +#include "RAS_IRasterizer.h" + +const bool BL_BlenderShader::Ok()const +{ +#if 0 + return (mGPUMat != 0); +#endif + + return false; +} + +BL_BlenderShader::BL_BlenderShader(struct Material *ma) +: +#if 0 + mGPUMat(0), +#endif + mBound(false) +{ +#if 0 + if(ma) + mGPUMat = GPU_material_from_blender(ma, GPU_PROFILE_DERIVEDMESH); +#endif +} + +BL_BlenderShader::~BL_BlenderShader() +{ +#if 0 + if(mGPUMat) { + GPU_material_unbind(mGPUMat); + mGPUMat = 0; + } +#endif +} + +void BL_BlenderShader::ApplyShader() +{ +} + +void BL_BlenderShader::SetProg(bool enable) +{ +#if 0 + if(mGPUMat) { + if(enable) { + GPU_material_bind(mGPUMat); + mBound = true; + } + else { + GPU_material_unbind(mGPUMat); + mBound = false; + } + } +#endif +} + +int BL_BlenderShader::GetAttribNum() +{ +#if 0 + GPUVertexAttribs attribs; + int i, enabled = 0; + + if(!mGPUMat) + return enabled; + + GPU_material_vertex_attributes(mGPUMat, &attribs); + + for(i = 0; i < attribs.totlayer; i++) + if(attribs.layer[i].glindex+1 > enabled) + enabled= attribs.layer[i].glindex+1; + + if(enabled > BL_MAX_ATTRIB) + enabled = BL_MAX_ATTRIB; + + return enabled; +#endif + + return 0; +} + +void BL_BlenderShader::SetTexCoords(RAS_IRasterizer* ras) +{ +#if 0 + GPUVertexAttribs attribs; + int i, attrib_num; + + if(!mGPUMat) + return; + + if(ras->GetDrawingMode() == RAS_IRasterizer::KX_TEXTURED) { + GPU_material_vertex_attributes(mGPUMat, &attribs); + attrib_num = GetAttribNum(); + + ras->SetTexCoordNum(0); + ras->SetAttribNum(attrib_num); + for(i=0; iSetAttrib(RAS_IRasterizer::RAS_TEXCO_DISABLE, i); + + for(i = 0; i < attribs.totlayer; i++) { + if(attribs.layer[i].glindex > attrib_num) + continue; + + if(attribs.layer[i].type == CD_MTFACE) + ras->SetAttrib(RAS_IRasterizer::RAS_TEXCO_UV1, attribs.layer[i].glindex); + else if(attribs.layer[i].type == CD_TANGENT) + ras->SetAttrib(RAS_IRasterizer::RAS_TEXTANGENT, attribs.layer[i].glindex); + else if(attribs.layer[i].type == CD_ORCO) + ras->SetAttrib(RAS_IRasterizer::RAS_TEXCO_ORCO, attribs.layer[i].glindex); + else if(attribs.layer[i].type == CD_NORMAL) + ras->SetAttrib(RAS_IRasterizer::RAS_TEXCO_NORM, attribs.layer[i].glindex); + } + + ras->EnableTextures(true); + } + else + ras->EnableTextures(false); +#endif +} + +void BL_BlenderShader::Update( const KX_MeshSlot & ms, RAS_IRasterizer* rasty ) +{ +#if 0 + float obmat[4][4], viewmat[4][4]; + + if(!mGPUMat || !mBound) + return; + + MT_Matrix4x4 model; + model.setValue(ms.m_OpenGLMatrix); + MT_Matrix4x4 view; + rasty->GetViewMatrix(view); + + model.getValue((float*)obmat); + view.getValue((float*)viewmat); + + GPU_material_bind_uniforms(mGPUMat, obmat, viewmat); +#endif +} + +// eof diff --git a/source/gameengine/Ketsji/BL_BlenderShader.h b/source/gameengine/Ketsji/BL_BlenderShader.h new file mode 100644 index 00000000000..4cab0e644c3 --- /dev/null +++ b/source/gameengine/Ketsji/BL_BlenderShader.h @@ -0,0 +1,44 @@ + +#ifndef __BL_GPUSHADER_H__ +#define __BL_GPUSHADER_H__ + +#if 0 +#include "GPU_material.h" +#endif + +#include "MT_Matrix4x4.h" +#include "MT_Matrix3x3.h" +#include "MT_Tuple2.h" +#include "MT_Tuple3.h" +#include "MT_Tuple4.h" + +struct Material; + +#define BL_MAX_ATTRIB 16 + +/** + * BL_BlenderShader + * Blender GPU shader material + */ +class BL_BlenderShader +{ +private: +#if 0 + GPUMaterial *mGPUMat; +#endif + bool mBound; + +public: + BL_BlenderShader(struct Material *ma); + virtual ~BL_BlenderShader(); + + const bool Ok()const; + void SetProg(bool enable); + + void ApplyShader(); + void SetTexCoords(class RAS_IRasterizer* ras); + int GetAttribNum(); + void Update(const class KX_MeshSlot & ms, class RAS_IRasterizer* rasty); +}; + +#endif//__BL_GPUSHADER_H__ diff --git a/source/gameengine/Ketsji/BL_Material.cpp b/source/gameengine/Ketsji/BL_Material.cpp index 7ed2da590a9..f5312ccd023 100644 --- a/source/gameengine/Ketsji/BL_Material.cpp +++ b/source/gameengine/Ketsji/BL_Material.cpp @@ -34,6 +34,7 @@ BL_Material::BL_Material() rgb[3] = 0; IdMode = 0; ras_mode = 0; + glslmat = 0; tile = 0; matname = "NoMaterial"; matcolor[0] = 0.5f; diff --git a/source/gameengine/Ketsji/BL_Material.h b/source/gameengine/Ketsji/BL_Material.h index 8be91316237..ddb6662830a 100644 --- a/source/gameengine/Ketsji/BL_Material.h +++ b/source/gameengine/Ketsji/BL_Material.h @@ -20,7 +20,7 @@ struct EnvMap; although the more you add the slower the search time will be. we will go for three, which should be enough */ -#define MAXTEX 3//match in RAS_TexVert & RAS_OpenGLRasterizer +#define MAXTEX 3 //match in RAS_TexVert & RAS_OpenGLRasterizer // different mapping modes class BL_Mapping @@ -47,6 +47,7 @@ public: int IdMode; unsigned int ras_mode; + bool glslmat; STR_String texname[MAXTEX]; unsigned int flag[MAXTEX]; diff --git a/source/gameengine/Ketsji/BL_Shader.cpp b/source/gameengine/Ketsji/BL_Shader.cpp index 105a87e767b..15350db6650 100644 --- a/source/gameengine/Ketsji/BL_Shader.cpp +++ b/source/gameengine/Ketsji/BL_Shader.cpp @@ -1,21 +1,5 @@ - -#ifdef WIN32 -#include -#endif // WIN32 -#ifdef __APPLE__ -#define GL_GLEXT_LEGACY 1 -#include -#include -#else -#include -/* #if defined(__sun__) && !defined(__sparc__) -#include -#else -*/ -#include -/* #endif */ -#endif +#include "GL/glew.h" #include #include "BL_Shader.h" @@ -31,7 +15,6 @@ #include "RAS_MeshObject.h" #include "RAS_IRasterizer.h" -//using namespace bgl; #define spit(x) std::cout << x << std::endl; #define SORT_UNIFORMS 1 @@ -46,7 +29,7 @@ BL_Uniform::BL_Uniform(int data_size) mDataLen(data_size) { #ifdef SORT_UNIFORMS - MT_assert(mDataLen <= UNIFORM_MAX_LEN); + MT_assert((int)mDataLen <= UNIFORM_MAX_LEN); mData = (void*)MEM_mallocN(mDataLen, "shader-uniform-alloc"); #endif } @@ -63,7 +46,6 @@ BL_Uniform::~BL_Uniform() void BL_Uniform::Apply(class BL_Shader *shader) { -#ifdef GL_ARB_shader_objects #ifdef SORT_UNIFORMS MT_assert(mType > UNI_NONE && mType < UNI_MAX && mData); @@ -74,48 +56,47 @@ void BL_Uniform::Apply(class BL_Shader *shader) { case UNI_FLOAT: { float *f = (float*)mData; - bgl::blUniform1fARB(mLoc,(GLfloat)*f); + glUniform1fARB(mLoc,(GLfloat)*f); }break; case UNI_INT: { int *f = (int*)mData; - bgl::blUniform1iARB(mLoc, (GLint)*f); + glUniform1iARB(mLoc, (GLint)*f); }break; case UNI_FLOAT2: { float *f = (float*)mData; - bgl::blUniform2fvARB(mLoc,1, (GLfloat*)f); + glUniform2fvARB(mLoc,1, (GLfloat*)f); }break; case UNI_FLOAT3: { float *f = (float*)mData; - bgl::blUniform3fvARB(mLoc,1,(GLfloat*)f); + glUniform3fvARB(mLoc,1,(GLfloat*)f); }break; case UNI_FLOAT4: { float *f = (float*)mData; - bgl::blUniform4fvARB(mLoc,1,(GLfloat*)f); + glUniform4fvARB(mLoc,1,(GLfloat*)f); }break; case UNI_INT2: { int *f = (int*)mData; - bgl::blUniform2ivARB(mLoc,1,(GLint*)f); + glUniform2ivARB(mLoc,1,(GLint*)f); }break; case UNI_INT3: { int *f = (int*)mData; - bgl::blUniform3ivARB(mLoc,1,(GLint*)f); + glUniform3ivARB(mLoc,1,(GLint*)f); }break; case UNI_INT4: { int *f = (int*)mData; - bgl::blUniform4ivARB(mLoc,1,(GLint*)f); + glUniform4ivARB(mLoc,1,(GLint*)f); }break; case UNI_MAT4: { float *f = (float*)mData; - bgl::blUniformMatrix4fvARB(mLoc, 1, mTranspose?GL_TRUE:GL_FALSE,(GLfloat*)f); + glUniformMatrix4fvARB(mLoc, 1, mTranspose?GL_TRUE:GL_FALSE,(GLfloat*)f); }break; case UNI_MAT3: { float *f = (float*)mData; - bgl::blUniformMatrix3fvARB(mLoc, 1, mTranspose?GL_TRUE:GL_FALSE,(GLfloat*)f); + glUniformMatrix3fvARB(mLoc, 1, mTranspose?GL_TRUE:GL_FALSE,(GLfloat*)f); }break; } mDirty = false; #endif -#endif } void BL_Uniform::SetData(int location, int type,bool transpose) @@ -144,17 +125,14 @@ BL_Shader::BL_Shader(PyTypeObject *T) mError(0), mDirty(true) { - // if !RAS_EXT_support._ARB_shader_objects this class will not be used + // if !GLEW_ARB_shader_objects this class will not be used //for (int i=0; i 0 && vertlen < MAX_LOG_LEN){ logInf = (char*)MEM_mallocN(vertlen, "vert-log"); - bgl::blGetInfoLogARB(tmpVert, vertlen, (GLsizei*)&char_len, logInf); + glGetInfoLogARB(tmpVert, vertlen, (GLsizei*)&char_len, logInf); if(char_len >0) { spit("---- Vertex Shader Error ----"); spit(logInf); @@ -308,20 +283,20 @@ bool BL_Shader::LinkProgram() logInf=0; } // check for compile errors - bgl::blGetObjectParameterivARB(tmpVert, GL_OBJECT_COMPILE_STATUS_ARB,(GLint*)&vertstatus); + glGetObjectParameterivARB(tmpVert, GL_OBJECT_COMPILE_STATUS_ARB,(GLint*)&vertstatus); if(!vertstatus) { spit("---- Vertex shader failed to compile ----"); goto programError; } // -- fragment shader ---------------- - tmpFrag = bgl::blCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB); - bgl::blShaderSourceARB(tmpFrag, 1,(const char**)&fragProg, 0); - bgl::blCompileShaderARB(tmpFrag); - bgl::blGetObjectParameterivARB(tmpFrag, GL_OBJECT_INFO_LOG_LENGTH_ARB, (GLint*) &fraglen); + tmpFrag = glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB); + glShaderSourceARB(tmpFrag, 1,(const char**)&fragProg, 0); + glCompileShaderARB(tmpFrag); + glGetObjectParameterivARB(tmpFrag, GL_OBJECT_INFO_LOG_LENGTH_ARB, (GLint*) &fraglen); if(fraglen >0 && fraglen < MAX_LOG_LEN){ logInf = (char*)MEM_mallocN(fraglen, "frag-log"); - bgl::blGetInfoLogARB(tmpFrag, fraglen,(GLsizei*) &char_len, logInf); + glGetInfoLogARB(tmpFrag, fraglen,(GLsizei*) &char_len, logInf); if(char_len >0) { spit("---- Fragment Shader Error ----"); spit(logInf); @@ -330,7 +305,7 @@ bool BL_Shader::LinkProgram() logInf=0; } - bgl::blGetObjectParameterivARB(tmpFrag, GL_OBJECT_COMPILE_STATUS_ARB, (GLint*) &fragstatus); + glGetObjectParameterivARB(tmpFrag, GL_OBJECT_COMPILE_STATUS_ARB, (GLint*) &fragstatus); if(!fragstatus){ spit("---- Fragment shader failed to compile ----"); goto programError; @@ -339,17 +314,17 @@ bool BL_Shader::LinkProgram() // -- program ------------------------ // set compiled vert/frag shader & link - tmpProg = bgl::blCreateProgramObjectARB(); - bgl::blAttachObjectARB(tmpProg, tmpVert); - bgl::blAttachObjectARB(tmpProg, tmpFrag); - bgl::blLinkProgramARB(tmpProg); - bgl::blGetObjectParameterivARB(tmpProg, GL_OBJECT_INFO_LOG_LENGTH_ARB, (GLint*) &proglen); - bgl::blGetObjectParameterivARB(tmpProg, GL_OBJECT_LINK_STATUS_ARB, (GLint*) &progstatus); + tmpProg = glCreateProgramObjectARB(); + glAttachObjectARB(tmpProg, tmpVert); + glAttachObjectARB(tmpProg, tmpFrag); + glLinkProgramARB(tmpProg); + glGetObjectParameterivARB(tmpProg, GL_OBJECT_INFO_LOG_LENGTH_ARB, (GLint*) &proglen); + glGetObjectParameterivARB(tmpProg, GL_OBJECT_LINK_STATUS_ARB, (GLint*) &progstatus); if(proglen > 0 && proglen < MAX_LOG_LEN) { logInf = (char*)MEM_mallocN(proglen, "prog-log"); - bgl::blGetInfoLogARB(tmpProg, proglen, (GLsizei*)&char_len, logInf); + glGetInfoLogARB(tmpProg, proglen, (GLsizei*)&char_len, logInf); if(char_len >0) { spit("---- GLSL Program ----"); spit(logInf); @@ -365,24 +340,24 @@ bool BL_Shader::LinkProgram() // set mShader = tmpProg; - bgl::blDeleteObjectARB(tmpVert); - bgl::blDeleteObjectARB(tmpFrag); + glDeleteObjectARB(tmpVert); + glDeleteObjectARB(tmpFrag); mOk = 1; mError = 0; return true; programError: if(tmpVert) { - bgl::blDeleteObjectARB(tmpVert); + glDeleteObjectARB(tmpVert); tmpVert=0; } if(tmpFrag) { - bgl::blDeleteObjectARB(tmpFrag); + glDeleteObjectARB(tmpFrag); tmpFrag=0; } if(tmpProg) { - bgl::blDeleteObjectARB(tmpProg); + glDeleteObjectARB(tmpProg); tmpProg=0; } @@ -390,9 +365,6 @@ programError: mUse = 0; mError = 1; return false; -#else - return false; -#endif//GL_ARB_shader_objects } const char *BL_Shader::GetVertPtr() @@ -428,15 +400,13 @@ unsigned int BL_Shader::GetProg() void BL_Shader::SetSampler(int loc, int unit) { -#ifdef GL_ARB_shader_objects - if( RAS_EXT_support._ARB_fragment_shader && - RAS_EXT_support._ARB_vertex_shader && - RAS_EXT_support._ARB_shader_objects + if( GLEW_ARB_fragment_shader && + GLEW_ARB_vertex_shader && + GLEW_ARB_shader_objects ) { - bgl::blUniform1iARB(loc, unit); + glUniform1iARB(loc, unit); } -#endif } // //void BL_Shader::InitializeSampler(int unit, BL_Texture* texture) @@ -449,31 +419,28 @@ void BL_Shader::SetSampler(int loc, int unit) void BL_Shader::SetProg(bool enable) { -#ifdef GL_ARB_shader_objects - if( RAS_EXT_support._ARB_fragment_shader && - RAS_EXT_support._ARB_vertex_shader && - RAS_EXT_support._ARB_shader_objects + if( GLEW_ARB_fragment_shader && + GLEW_ARB_vertex_shader && + GLEW_ARB_shader_objects ) { if( mShader != 0 && mOk && enable) { - bgl::blUseProgramObjectARB(mShader); + glUseProgramObjectARB(mShader); } else { - bgl::blUseProgramObjectARB(0); + glUseProgramObjectARB(0); } } -#endif } void BL_Shader::Update( const KX_MeshSlot & ms, RAS_IRasterizer* rasty ) { -#ifdef GL_ARB_shader_objects if(!Ok() || !mPreDef.size()) return; - if( RAS_EXT_support._ARB_fragment_shader && - RAS_EXT_support._ARB_vertex_shader && - RAS_EXT_support._ARB_shader_objects + if( GLEW_ARB_fragment_shader && + GLEW_ARB_vertex_shader && + GLEW_ARB_shader_objects ) { MT_Matrix4x4 model; @@ -578,210 +545,185 @@ void BL_Shader::Update( const KX_MeshSlot & ms, RAS_IRasterizer* rasty ) } } } -#endif } int BL_Shader::GetAttribLocation(const STR_String& name) { -#ifdef GL_ARB_shader_objects - if( RAS_EXT_support._ARB_fragment_shader && - RAS_EXT_support._ARB_vertex_shader && - RAS_EXT_support._ARB_shader_objects + if( GLEW_ARB_fragment_shader && + GLEW_ARB_vertex_shader && + GLEW_ARB_shader_objects ) { - return bgl::blGetAttribLocationARB(mShader, name.ReadPtr()); + return glGetAttribLocationARB(mShader, name.ReadPtr()); } -#endif + return -1; } void BL_Shader::BindAttribute(const STR_String& attr, int loc) { -#ifdef GL_ARB_shader_objects - if( RAS_EXT_support._ARB_fragment_shader && - RAS_EXT_support._ARB_vertex_shader && - RAS_EXT_support._ARB_shader_objects + if( GLEW_ARB_fragment_shader && + GLEW_ARB_vertex_shader && + GLEW_ARB_shader_objects ) { - bgl::blBindAttribLocationARB(mShader, loc, attr.ReadPtr()); + glBindAttribLocationARB(mShader, loc, attr.ReadPtr()); } -#endif } int BL_Shader::GetUniformLocation(const STR_String& name) { -#ifdef GL_ARB_shader_objects - if( RAS_EXT_support._ARB_fragment_shader && - RAS_EXT_support._ARB_vertex_shader && - RAS_EXT_support._ARB_shader_objects + if( GLEW_ARB_fragment_shader && + GLEW_ARB_vertex_shader && + GLEW_ARB_shader_objects ) { MT_assert(mShader!=0); - int location = bgl::blGetUniformLocationARB(mShader, name.ReadPtr()); + int location = glGetUniformLocationARB(mShader, name.ReadPtr()); if(location == -1) spit("Invalid uniform value: " << name.ReadPtr() << "."); return location; } -#endif + return -1; } void BL_Shader::SetUniform(int uniform, const MT_Tuple2& vec) { -#ifdef GL_ARB_shader_objects - if( RAS_EXT_support._ARB_fragment_shader && - RAS_EXT_support._ARB_vertex_shader && - RAS_EXT_support._ARB_shader_objects + if( GLEW_ARB_fragment_shader && + GLEW_ARB_vertex_shader && + GLEW_ARB_shader_objects ) { float value[2]; vec.getValue(value); - bgl::blUniform2fvARB(uniform, 1, value); + glUniform2fvARB(uniform, 1, value); } -#endif } void BL_Shader::SetUniform(int uniform, const MT_Tuple3& vec) { -#ifdef GL_ARB_shader_objects - if( RAS_EXT_support._ARB_fragment_shader && - RAS_EXT_support._ARB_vertex_shader && - RAS_EXT_support._ARB_shader_objects + if( GLEW_ARB_fragment_shader && + GLEW_ARB_vertex_shader && + GLEW_ARB_shader_objects ) { float value[3]; vec.getValue(value); - bgl::blUniform3fvARB(uniform, 1, value); + glUniform3fvARB(uniform, 1, value); } -#endif } void BL_Shader::SetUniform(int uniform, const MT_Tuple4& vec) { -#ifdef GL_ARB_shader_objects - if( RAS_EXT_support._ARB_fragment_shader && - RAS_EXT_support._ARB_vertex_shader && - RAS_EXT_support._ARB_shader_objects + if( GLEW_ARB_fragment_shader && + GLEW_ARB_vertex_shader && + GLEW_ARB_shader_objects ) { float value[4]; vec.getValue(value); - bgl::blUniform4fvARB(uniform, 1, value); + glUniform4fvARB(uniform, 1, value); } -#endif } void BL_Shader::SetUniform(int uniform, const unsigned int& val) { -#ifdef GL_ARB_shader_objects - if( RAS_EXT_support._ARB_fragment_shader && - RAS_EXT_support._ARB_vertex_shader && - RAS_EXT_support._ARB_shader_objects + if( GLEW_ARB_fragment_shader && + GLEW_ARB_vertex_shader && + GLEW_ARB_shader_objects ) { - bgl::blUniform1iARB(uniform, val); + glUniform1iARB(uniform, val); } -#endif } void BL_Shader::SetUniform(int uniform, const int val) { -#ifdef GL_ARB_shader_objects - if( RAS_EXT_support._ARB_fragment_shader && - RAS_EXT_support._ARB_vertex_shader && - RAS_EXT_support._ARB_shader_objects + if( GLEW_ARB_fragment_shader && + GLEW_ARB_vertex_shader && + GLEW_ARB_shader_objects ) { - bgl::blUniform1iARB(uniform, val); + glUniform1iARB(uniform, val); } -#endif } void BL_Shader::SetUniform(int uniform, const float& val) { -#ifdef GL_ARB_shader_objects - if( RAS_EXT_support._ARB_fragment_shader && - RAS_EXT_support._ARB_vertex_shader && - RAS_EXT_support._ARB_shader_objects + if( GLEW_ARB_fragment_shader && + GLEW_ARB_vertex_shader && + GLEW_ARB_shader_objects ) { - bgl::blUniform1fARB(uniform, val); + glUniform1fARB(uniform, val); } -#endif } void BL_Shader::SetUniform(int uniform, const MT_Matrix4x4& vec, bool transpose) { -#ifdef GL_ARB_shader_objects - if( RAS_EXT_support._ARB_fragment_shader && - RAS_EXT_support._ARB_vertex_shader && - RAS_EXT_support._ARB_shader_objects + if( GLEW_ARB_fragment_shader && + GLEW_ARB_vertex_shader && + GLEW_ARB_shader_objects ) { float value[16]; vec.getValue(value); - bgl::blUniformMatrix4fvARB(uniform, 1, transpose?GL_TRUE:GL_FALSE, value); + glUniformMatrix4fvARB(uniform, 1, transpose?GL_TRUE:GL_FALSE, value); } -#endif } void BL_Shader::SetUniform(int uniform, const MT_Matrix3x3& vec, bool transpose) { -#ifdef GL_ARB_shader_objects - if( RAS_EXT_support._ARB_fragment_shader && - RAS_EXT_support._ARB_vertex_shader && - RAS_EXT_support._ARB_shader_objects + if( GLEW_ARB_fragment_shader && + GLEW_ARB_vertex_shader && + GLEW_ARB_shader_objects ) { float value[9]; value[0] = (float)vec[0][0]; value[1] = (float)vec[1][0]; value[2] = (float)vec[2][0]; value[3] = (float)vec[0][1]; value[4] = (float)vec[1][1]; value[5] = (float)vec[2][1]; value[6] = (float)vec[0][2]; value[7] = (float)vec[1][2]; value[7] = (float)vec[2][2]; - bgl::blUniformMatrix3fvARB(uniform, 1, transpose?GL_TRUE:GL_FALSE, value); + glUniformMatrix3fvARB(uniform, 1, transpose?GL_TRUE:GL_FALSE, value); } -#endif } void BL_Shader::SetUniform(int uniform, const float* val, int len) { -#ifdef GL_ARB_shader_objects - if( RAS_EXT_support._ARB_fragment_shader && - RAS_EXT_support._ARB_vertex_shader && - RAS_EXT_support._ARB_shader_objects + if( GLEW_ARB_fragment_shader && + GLEW_ARB_vertex_shader && + GLEW_ARB_shader_objects ) { if(len == 2) - bgl::blUniform2fvARB(uniform, 1,(GLfloat*)val); + glUniform2fvARB(uniform, 1,(GLfloat*)val); else if (len == 3) - bgl::blUniform3fvARB(uniform, 1,(GLfloat*)val); + glUniform3fvARB(uniform, 1,(GLfloat*)val); else if (len == 4) - bgl::blUniform4fvARB(uniform, 1,(GLfloat*)val); + glUniform4fvARB(uniform, 1,(GLfloat*)val); else MT_assert(0); } -#endif } void BL_Shader::SetUniform(int uniform, const int* val, int len) { -#ifdef GL_ARB_shader_objects - if( RAS_EXT_support._ARB_fragment_shader && - RAS_EXT_support._ARB_vertex_shader && - RAS_EXT_support._ARB_shader_objects + if( GLEW_ARB_fragment_shader && + GLEW_ARB_vertex_shader && + GLEW_ARB_shader_objects ) { if(len == 2) - bgl::blUniform2ivARB(uniform, 1, (GLint*)val); + glUniform2ivARB(uniform, 1, (GLint*)val); else if (len == 3) - bgl::blUniform3ivARB(uniform, 1, (GLint*)val); + glUniform3ivARB(uniform, 1, (GLint*)val); else if (len == 4) - bgl::blUniform4ivARB(uniform, 1, (GLint*)val); + glUniform4ivARB(uniform, 1, (GLint*)val); else MT_assert(0); } -#endif } @@ -849,7 +791,6 @@ PyParentObject BL_Shader::Parents[] = { KX_PYMETHODDEF_DOC( BL_Shader, setSource," setSource(vertexProgram, fragmentProgram)" ) { -#ifdef GL_ARB_shader_objects if(mShader !=0 && mOk ) { // already set... @@ -862,7 +803,7 @@ KX_PYMETHODDEF_DOC( BL_Shader, setSource," setSource(vertexProgram, fragmentProg vertProg = v; fragProg = f; if( LinkProgram() ) { - bgl::blUseProgramObjectARB( mShader ); + glUseProgramObjectARB( mShader ); mUse = apply!=0; Py_Return; } @@ -871,24 +812,19 @@ KX_PYMETHODDEF_DOC( BL_Shader, setSource," setSource(vertexProgram, fragmentProg mUse = 0; Py_Return; } - return NULL; -#else Py_Return; -#endif } KX_PYMETHODDEF_DOC( BL_Shader, delSource, "delSource( )" ) { -#ifdef GL_ARB_shader_objects ClearUniforms(); - bgl::blUseProgramObjectARB(0); + glUseProgramObjectARB(0); - bgl::blDeleteObjectARB(mShader); + glDeleteObjectARB(mShader); mShader = 0; mOk = 0; mUse = 0; -#endif Py_Return; } @@ -909,7 +845,6 @@ KX_PYMETHODDEF_DOC( BL_Shader, getFragmentProg ,"getFragmentProg( )" ) KX_PYMETHODDEF_DOC( BL_Shader, validate, "validate()") { -#ifdef GL_ARB_shader_objects if(mError) { Py_INCREF(Py_None); return Py_None; @@ -919,15 +854,15 @@ KX_PYMETHODDEF_DOC( BL_Shader, validate, "validate()") return NULL; } int stat = 0; - bgl::blValidateProgramARB(mShader); - bgl::blGetObjectParameterivARB(mShader, GL_OBJECT_VALIDATE_STATUS_ARB,(GLint*) &stat); + glValidateProgramARB(mShader); + glGetObjectParameterivARB(mShader, GL_OBJECT_VALIDATE_STATUS_ARB,(GLint*) &stat); if(stat > 0 && stat < MAX_LOG_LEN) { int char_len=0; char *logInf = (char*)MEM_mallocN(stat, "validate-log"); - bgl::blGetInfoLogARB(mShader, stat,(GLsizei*) &char_len, logInf); + glGetInfoLogARB(mShader, stat,(GLsizei*) &char_len, logInf); if(char_len >0) { spit("---- GLSL Validation ----"); spit(logInf); @@ -935,7 +870,6 @@ KX_PYMETHODDEF_DOC( BL_Shader, validate, "validate()") MEM_freeN(logInf); logInf=0; } -#endif//GL_ARB_shader_objects Py_Return; } @@ -1412,7 +1346,6 @@ KX_PYMETHODDEF_DOC( BL_Shader, setUniformMatrix3, KX_PYMETHODDEF_DOC( BL_Shader, setAttrib, "setAttrib(enum)" ) { -#ifdef GL_ARB_shader_objects if(mError) { Py_INCREF(Py_None); return Py_None; @@ -1424,11 +1357,10 @@ KX_PYMETHODDEF_DOC( BL_Shader, setAttrib, "setAttrib(enum)" ) return NULL; } mAttr=SHD_TANGENT; - bgl::blUseProgramObjectARB(mShader); - bgl::blBindAttribLocationARB(mShader, mAttr, "Tangent"); + glUseProgramObjectARB(mShader); + glBindAttribLocationARB(mShader, mAttr, "Tangent"); Py_Return; } -#endif return NULL; } diff --git a/source/gameengine/Ketsji/BL_Texture.cpp b/source/gameengine/Ketsji/BL_Texture.cpp index 687b1af957d..f24ef4322f0 100644 --- a/source/gameengine/Ketsji/BL_Texture.cpp +++ b/source/gameengine/Ketsji/BL_Texture.cpp @@ -1,19 +1,6 @@ // ------------------------------------ -#ifdef WIN32 -#include -#endif // WIN32 -#ifdef __APPLE__ -#define GL_GLEXT_LEGACY 1 -#include -#include -#else -#include -/* #if defined(__sun__) && !defined(__sparc__) -#include -#else */ -#include -/* #endif */ -#endif + +#include "GL/glew.h" #include #include @@ -30,15 +17,11 @@ #include "BLI_blenlib.h" #include "RAS_OpenGLRasterizer/RAS_GLExtensionManager.h" -#include "RAS_OpenGLRasterizer/ARB_multitexture.h" #include "RAS_ICanvas.h" #include "RAS_Rect.h" #include "KX_GameObject.h" - -using namespace bgl; - #define spit(x) std::cout << x << std::endl; #include "MEM_guardedalloc.h" @@ -220,9 +203,7 @@ void BL_Texture::InitNonPow2Tex(unsigned int *pix,int x,int y,bool mipmap) bool BL_Texture::InitCubeMap(int unit, EnvMap *cubemap) { -#ifdef GL_ARB_texture_cube_map - - if (!RAS_EXT_support._ARB_texture_cube_map) + if (!GLEW_ARB_texture_cube_map) { spit("cubemaps not supported"); mOk = false; @@ -312,9 +293,8 @@ bool BL_Texture::InitCubeMap(int unit, EnvMap *cubemap) glTexParameteri( GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); glTexParameteri( GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE ); glTexParameteri( GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE ); - #ifdef GL_VERSION_1_2 - glTexParameteri( GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE ); - #endif + if(GLEW_VERSION_1_2) + glTexParameteri( GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE ); if (needs_split) my_free_envmapdata(cubemap); @@ -326,13 +306,6 @@ bool BL_Texture::InitCubeMap(int unit, EnvMap *cubemap) mOk = IsValid(); return mOk; - -#else - - mOk = false; - return mOk; - -#endif//GL_ARB_texture_cube_map } bool BL_Texture::IsValid() @@ -362,58 +335,40 @@ int BL_Texture::GetMaxUnits() { GLint unit=0; -#if defined(GL_ARB_multitexture) && defined(WITH_GLEXT) - if (!getenv("WITHOUT_GLEXT")) { - if(RAS_EXT_support._ARB_multitexture) { - glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, &unit); - return (MAXTEX>=unit?unit:MAXTEX); - } + if(GLEW_ARB_multitexture) { + glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, &unit); + return (MAXTEX>=unit?unit:MAXTEX); } -#endif + return 0; } void BL_Texture::ActivateFirst() { -#if defined(GL_ARB_multitexture) && defined(WITH_GLEXT) - if (!getenv("WITHOUT_GLEXT")) { - if(RAS_EXT_support._ARB_multitexture) - bgl::blActiveTextureARB(GL_TEXTURE0_ARB); - } -#endif + if(GLEW_ARB_multitexture) + glActiveTextureARB(GL_TEXTURE0_ARB); } void BL_Texture::ActivateUnit(int unit) { -#if defined(GL_ARB_multitexture) && defined(WITH_GLEXT) - if (!getenv("WITHOUT_GLEXT")) { - if(RAS_EXT_support._ARB_multitexture) - if(unit <= MAXTEX) - bgl::blActiveTextureARB(GL_TEXTURE0_ARB+unit); - } -#endif + if(GLEW_ARB_multitexture) + if(unit <= MAXTEX) + glActiveTextureARB(GL_TEXTURE0_ARB+unit); } void BL_Texture::DisableUnit() { -#if defined(GL_ARB_multitexture) && defined(WITH_GLEXT) - if (!getenv("WITHOUT_GLEXT")) { - if(RAS_EXT_support._ARB_multitexture) - bgl::blActiveTextureARB(GL_TEXTURE0_ARB+mUnit); - } -#endif - + if(GLEW_ARB_multitexture) + glActiveTextureARB(GL_TEXTURE0_ARB+mUnit); glMatrixMode(GL_TEXTURE); glLoadIdentity(); glMatrixMode(GL_MODELVIEW); - #ifdef GL_ARB_texture_cube_map - if(RAS_EXT_support._ARB_texture_cube_map && glIsEnabled(GL_TEXTURE_CUBE_MAP_ARB)) + if(GLEW_ARB_texture_cube_map && glIsEnabled(GL_TEXTURE_CUBE_MAP_ARB)) glDisable(GL_TEXTURE_CUBE_MAP_ARB); else - #endif { if (glIsEnabled(GL_TEXTURE_2D)) glDisable(GL_TEXTURE_2D); @@ -429,56 +384,45 @@ void BL_Texture::DisableUnit() void BL_Texture::DisableAllTextures() { -#if defined(GL_ARB_multitexture) && defined(WITH_GLEXT) - if (!getenv("WITHOUT_GLEXT")) { - glDisable(GL_BLEND); - for(int i=0; i #endif -#ifdef WIN32 -#include -#endif // WIN32 -#ifdef __APPLE__ -#define GL_GLEXT_LEGACY 1 -#include -#include -#else -#include -/* #if defined(__sun__) && !defined(__sparc__) -#include -#else -*/ -#include -/* #endif */ -#endif +#include "GL/glew.h" #include "KX_BlenderMaterial.h" #include "BL_Material.h" @@ -37,7 +22,6 @@ #include "RAS_MeshObject.h" #include "RAS_IRasterizer.h" #include "RAS_OpenGLRasterizer/RAS_GLExtensionManager.h" -#include "RAS_OpenGLRasterizer/ARB_multitexture.h" extern "C" { #include "BDR_drawmesh.h" @@ -52,7 +36,6 @@ extern "C" { #include "DNA_meshdata_types.h" #include "BKE_mesh.h" // ------------------------------------ -using namespace bgl; #define spit(x) std::cout << x << std::endl; //static PyObject *gTextureDict = 0; @@ -81,6 +64,7 @@ KX_BlenderMaterial::KX_BlenderMaterial( ), mMaterial(data), mShader(0), + mBlenderShader(0), mScene(scene), mUserDefBlend(0), mModified(0), @@ -100,9 +84,6 @@ KX_BlenderMaterial::KX_BlenderMaterial( int max = BL_Texture::GetMaxUnits(); mMaterial->num_enabled = enabled>=max?max:enabled; - // base class - m_enabled = mMaterial->num_enabled; - // test the sum of the various modes for equality // so we can ether accept or reject this material // as being equal, this is rather important to @@ -144,25 +125,30 @@ void KX_BlenderMaterial::OnConstruction() if (mConstructed) // when material are reused between objects return; - - // for each unique material... - int i; - for(i=0; inum_enabled; i++) { - if( mMaterial->mapping[i].mapping & USEENV ) { - if(!RAS_EXT_support._ARB_texture_cube_map) { - spit("CubeMap textures not supported"); - continue; - } - if(!mTextures[i].InitCubeMap(i, mMaterial->cubemap[i] ) ) - spit("unable to initialize image("<matname<< ", image will not be available"); - } - else { - if( mMaterial->img[i] ) { - if( ! mTextures[i].InitFromImage(i, mMaterial->img[i], (mMaterial->flag[i] &MIPMAP)!=0 )) + if(mMaterial->glslmat) { + SetBlenderGLSLShader(); + } + else { + // for each unique material... + int i; + for(i=0; inum_enabled; i++) { + if( mMaterial->mapping[i].mapping & USEENV ) { + if(!GLEW_ARB_texture_cube_map) { + spit("CubeMap textures not supported"); + continue; + } + if(!mTextures[i].InitCubeMap(i, mMaterial->cubemap[i] ) ) spit("unable to initialize image("<matname<< ", image will not be available"); + mMaterial->matname<< ", image will not be available"); + } + + else { + if( mMaterial->img[i] ) { + if( ! mTextures[i].InitFromImage(i, mMaterial->img[i], (mMaterial->flag[i] &MIPMAP)!=0 )) + spit("unable to initialize image("<matname<< ", image will not be available"); + } } } } @@ -176,11 +162,17 @@ void KX_BlenderMaterial::OnExit() if( mShader ) { //note, the shader here is allocated, per unique material //and this function is called per face - mShader->SetProg(0); + mShader->SetProg(false); delete mShader; mShader = 0; } + if( mBlenderShader ) { + mBlenderShader->SetProg(false); + delete mBlenderShader; + mBlenderShader = 0; + } + BL_Texture::ActivateFirst(); for(int i=0; inum_enabled; i++) { BL_Texture::ActivateUnit(i); @@ -195,7 +187,7 @@ void KX_BlenderMaterial::OnExit() void KX_BlenderMaterial::setShaderData( bool enable, RAS_IRasterizer *ras) { - MT_assert(RAS_EXT_support._ARB_shader_objects && mShader); + MT_assert(GLEW_ARB_shader_objects && mShader); int i; if( !enable || !mShader->Ok() ) { @@ -229,10 +221,23 @@ void KX_BlenderMaterial::setShaderData( bool enable, RAS_IRasterizer *ras) } } +void KX_BlenderMaterial::setBlenderShaderData( bool enable, RAS_IRasterizer *ras) +{ + if( !enable || !mBlenderShader->Ok() ) { + // frame cleanup. + mBlenderShader->SetProg(false); + BL_Texture::DisableAllTextures(); + return; + } + + BL_Texture::DisableAllTextures(); + mBlenderShader->SetProg(true); + mBlenderShader->ApplyShader(); +} void KX_BlenderMaterial::setTexData( bool enable, RAS_IRasterizer *ras) { - if(RAS_EXT_support._ARB_shader_objects && mShader) + if(GLEW_ARB_shader_objects && mShader) mShader->SetProg(false); BL_Texture::DisableAllTextures(); @@ -301,14 +306,10 @@ KX_BlenderMaterial::ActivatShaders( cachingInfo = GetCachingInfo(); - if (rasty->GetDrawingMode() == RAS_IRasterizer::KX_TEXTURED ) { + if(rasty->GetDrawingMode() == RAS_IRasterizer::KX_TEXTURED) tmp->setShaderData( true, rasty); - rasty->EnableTextures(true); - } - else { + else tmp->setShaderData( false, rasty); - rasty->EnableTextures(false); - } if(mMaterial->mode & RAS_IRasterizer::KX_TWOSIDE) rasty->SetCullFace(false); @@ -330,24 +331,28 @@ KX_BlenderMaterial::ActivatShaders( } void -KX_BlenderMaterial::ActivateMat( - RAS_IRasterizer* rasty, - TCachingInfo& cachingInfo - )const +KX_BlenderMaterial::ActivateBlenderShaders( + RAS_IRasterizer* rasty, + TCachingInfo& cachingInfo)const { KX_BlenderMaterial *tmp = const_cast(this); + + // reset... + if(tmp->mMaterial->IsShared()) + cachingInfo =0; + if (GetCachingInfo() != cachingInfo) { - if (!cachingInfo) - tmp->setTexData( false,rasty ); + if (!cachingInfo) + tmp->setBlenderShaderData(false, rasty); cachingInfo = GetCachingInfo(); - - if (rasty->GetDrawingMode() == RAS_IRasterizer::KX_TEXTURED) { - tmp->setTexData( true,rasty ); + + if(rasty->GetDrawingMode() == RAS_IRasterizer::KX_TEXTURED) { + tmp->setBlenderShaderData(true, rasty); rasty->EnableTextures(true); } - else{ - tmp->setTexData( false,rasty); + else { + tmp->setBlenderShaderData(false, rasty); rasty->EnableTextures(false); } @@ -365,11 +370,48 @@ KX_BlenderMaterial::ActivateMat( else rasty->SetLines(false); } + + ActivatGLMaterials(rasty); + mBlenderShader->SetTexCoords(rasty); +} + +void +KX_BlenderMaterial::ActivateMat( + RAS_IRasterizer* rasty, + TCachingInfo& cachingInfo + )const +{ + KX_BlenderMaterial *tmp = const_cast(this); + if (GetCachingInfo() != cachingInfo) { + if (!cachingInfo) + tmp->setTexData( false,rasty ); + + cachingInfo = GetCachingInfo(); + + if (rasty->GetDrawingMode() == RAS_IRasterizer::KX_TEXTURED) + tmp->setTexData( true,rasty ); + else + tmp->setTexData( false,rasty); + + if(mMaterial->mode & RAS_IRasterizer::KX_TWOSIDE) + rasty->SetCullFace(false); + else + rasty->SetCullFace(true); + + if (((mMaterial->ras_mode &WIRE)!=0) || mMaterial->mode & RAS_IRasterizer::KX_LINES) + { + if((mMaterial->ras_mode &WIRE)!=0) + rasty->SetCullFace(false); + rasty->SetLines(true); + } + else + rasty->SetLines(false); + } + ActivatGLMaterials(rasty); ActivateTexGen(rasty); } - bool KX_BlenderMaterial::Activate( RAS_IRasterizer* rasty, @@ -377,7 +419,7 @@ KX_BlenderMaterial::Activate( )const { bool dopass = false; - if( RAS_EXT_support._ARB_shader_objects && ( mShader && mShader->Ok() ) ) { + if( GLEW_ARB_shader_objects && ( mShader && mShader->Ok() ) ) { if( (mPass++) < mShader->getNumPass() ) { ActivatShaders(rasty, cachingInfo); dopass = true; @@ -390,6 +432,18 @@ KX_BlenderMaterial::Activate( return dopass; } } + else if( GLEW_ARB_shader_objects && ( mBlenderShader && mBlenderShader->Ok() ) ) { + if( (mPass++) == 0 ) { + ActivateBlenderShaders(rasty, cachingInfo); + dopass = true; + return dopass; + } + else { + mPass = 0; + dopass = false; + return dopass; + } + } else { switch (mPass++) { @@ -408,34 +462,39 @@ KX_BlenderMaterial::Activate( void KX_BlenderMaterial::ActivateMeshSlot(const KX_MeshSlot & ms, RAS_IRasterizer* rasty) const { - if(mShader && RAS_EXT_support._ARB_shader_objects) + if(mShader && GLEW_ARB_shader_objects) mShader->Update(ms, rasty); + if(mBlenderShader && GLEW_ARB_shader_objects) + mBlenderShader->Update(ms, rasty); } void KX_BlenderMaterial::ActivatGLMaterials( RAS_IRasterizer* rasty )const { - rasty->SetSpecularity( - mMaterial->speccolor[0]*mMaterial->spec_f, - mMaterial->speccolor[1]*mMaterial->spec_f, - mMaterial->speccolor[2]*mMaterial->spec_f, - mMaterial->spec_f - ); + if(!mBlenderShader) { + rasty->SetSpecularity( + mMaterial->speccolor[0]*mMaterial->spec_f, + mMaterial->speccolor[1]*mMaterial->spec_f, + mMaterial->speccolor[2]*mMaterial->spec_f, + mMaterial->spec_f + ); - rasty->SetShinyness( mMaterial->hard ); + rasty->SetShinyness( mMaterial->hard ); - rasty->SetDiffuse( - mMaterial->matcolor[0]*mMaterial->ref+mMaterial->emit, - mMaterial->matcolor[1]*mMaterial->ref+mMaterial->emit, - mMaterial->matcolor[2]*mMaterial->ref+mMaterial->emit, - 1.0f); + rasty->SetDiffuse( + mMaterial->matcolor[0]*mMaterial->ref+mMaterial->emit, + mMaterial->matcolor[1]*mMaterial->ref+mMaterial->emit, + mMaterial->matcolor[2]*mMaterial->ref+mMaterial->emit, + 1.0f); - rasty->SetEmissive( - mMaterial->matcolor[0]*mMaterial->emit, - mMaterial->matcolor[1]*mMaterial->emit, - mMaterial->matcolor[2]*mMaterial->emit, - 1.0 ); + rasty->SetEmissive( + mMaterial->matcolor[0]*mMaterial->emit, + mMaterial->matcolor[1]*mMaterial->emit, + mMaterial->matcolor[2]*mMaterial->emit, + 1.0 ); + + rasty->SetAmbient(mMaterial->amb); + } - rasty->SetAmbient(mMaterial->amb); if (mMaterial->material) rasty->SetPolygonOffset(-mMaterial->material->zoffs, 0.0); } @@ -443,34 +502,46 @@ void KX_BlenderMaterial::ActivatGLMaterials( RAS_IRasterizer* rasty )const void KX_BlenderMaterial::ActivateTexGen(RAS_IRasterizer *ras) const { - if(mShader && RAS_EXT_support._ARB_shader_objects) - if(mShader->GetAttribute() == BL_Shader::SHD_TANGENT) - ras->SetAttrib(RAS_IRasterizer::RAS_TEXTANGENT); - - for(int i=0; inum_enabled; i++) { - int mode = mMaterial->mapping[i].mapping; - - if (mode &USECUSTOMUV) - { - STR_String str = mMaterial->mapping[i].uvCoName; - if (!str.IsEmpty()) - ras->SetTexCoords(RAS_IRasterizer::RAS_TEXCO_UV2, i); - continue; + if(ras->GetDrawingMode() == RAS_IRasterizer::KX_TEXTURED) { + ras->SetAttribNum(0); + if(mShader && GLEW_ARB_shader_objects) { + if(mShader->GetAttribute() == BL_Shader::SHD_TANGENT) { + ras->SetAttrib(RAS_IRasterizer::RAS_TEXTANGENT, 1); + ras->SetAttribNum(2); + } } - if( mode &(USEREFL|USEOBJ)) - ras->SetTexCoords(RAS_IRasterizer::RAS_TEXCO_GEN, i); - else if(mode &USEORCO) - ras->SetTexCoords(RAS_IRasterizer::RAS_TEXCO_ORCO, i); - else if(mode &USENORM) - ras->SetTexCoords(RAS_IRasterizer::RAS_TEXCO_NORM, i); - else if(mode &USEUV) - ras->SetTexCoords(RAS_IRasterizer::RAS_TEXCO_UV1, i); - else if(mode &USETANG) - ras->SetTexCoords(RAS_IRasterizer::RAS_TEXTANGENT, i); - else - ras->SetTexCoords(RAS_IRasterizer::RAS_TEXCO_DISABLE, i); + ras->SetTexCoordNum(mMaterial->num_enabled); + + for(int i=0; inum_enabled; i++) { + int mode = mMaterial->mapping[i].mapping; + + if (mode &USECUSTOMUV) + { + STR_String str = mMaterial->mapping[i].uvCoName; + if (!str.IsEmpty()) + ras->SetTexCoord(RAS_IRasterizer::RAS_TEXCO_UV2, i); + continue; + } + + if( mode &(USEREFL|USEOBJ)) + ras->SetTexCoord(RAS_IRasterizer::RAS_TEXCO_GEN, i); + else if(mode &USEORCO) + ras->SetTexCoord(RAS_IRasterizer::RAS_TEXCO_ORCO, i); + else if(mode &USENORM) + ras->SetTexCoord(RAS_IRasterizer::RAS_TEXCO_NORM, i); + else if(mode &USEUV) + ras->SetTexCoord(RAS_IRasterizer::RAS_TEXCO_UV1, i); + else if(mode &USETANG) + ras->SetTexCoord(RAS_IRasterizer::RAS_TEXTANGENT, i); + else + ras->SetTexCoord(RAS_IRasterizer::RAS_TEXCO_DISABLE, i); + } + + ras->EnableTextures(true); } + else + ras->EnableTextures(false); } bool KX_BlenderMaterial::setDefaultBlending() @@ -503,8 +574,7 @@ void KX_BlenderMaterial::setTexMatrixData(int i) glMatrixMode(GL_TEXTURE); glLoadIdentity(); -#ifdef GL_ARB_texture_cube_map - if( RAS_EXT_support._ARB_texture_cube_map && + if( GLEW_ARB_texture_cube_map && mTextures[i].GetTextureType() == GL_TEXTURE_CUBE_MAP_ARB && mMaterial->mapping[i].mapping & USEREFL) { glScalef( @@ -514,7 +584,6 @@ void KX_BlenderMaterial::setTexMatrixData(int i) ); } else -#endif { glScalef( mMaterial->mapping[i].scale[0], @@ -663,28 +732,23 @@ int KX_BlenderMaterial::_setattr(const STR_String& attr, PyObject *pyvalue) KX_PYMETHODDEF_DOC( KX_BlenderMaterial, getShader , "getShader()") { -#ifdef GL_ARB_fragment_shader - if( !RAS_EXT_support._ARB_fragment_shader) { + if( !GLEW_ARB_fragment_shader) { if(!mModified) spit("Fragment shaders not supported"); mModified = true; Py_Return; } -#endif -#ifdef GL_ARB_vertex_shader - if( !RAS_EXT_support._ARB_vertex_shader) { + if( !GLEW_ARB_vertex_shader) { if(!mModified) spit("Vertex shaders not supported"); mModified = true; Py_Return; } -#endif -#ifdef GL_ARB_shader_objects - if(!RAS_EXT_support._ARB_shader_objects) { + if(!GLEW_ARB_shader_objects) { if(!mModified) spit("GLSL not supported"); mModified = true; @@ -723,13 +787,20 @@ KX_PYMETHODDEF_DOC( KX_BlenderMaterial, getShader , "getShader()") } PyErr_Format(PyExc_ValueError, "GLSL Error"); return NULL; - -#else - Py_Return; -#endif//GL_ARB_shader_objects } +void KX_BlenderMaterial::SetBlenderGLSLShader(void) +{ + if(!mBlenderShader) + mBlenderShader = new BL_BlenderShader(mMaterial->material); + + if(!mBlenderShader->Ok()) { + delete mBlenderShader; + mBlenderShader = 0; + } +} + KX_PYMETHODDEF_DOC( KX_BlenderMaterial, getMaterialIndex, "getMaterialIndex()") { return PyInt_FromLong( mMaterial->material_index ); diff --git a/source/gameengine/Ketsji/KX_BlenderMaterial.h b/source/gameengine/Ketsji/KX_BlenderMaterial.h index b9d48199520..62e96b71937 100644 --- a/source/gameengine/Ketsji/KX_BlenderMaterial.h +++ b/source/gameengine/Ketsji/KX_BlenderMaterial.h @@ -8,6 +8,7 @@ #include "BL_Material.h" #include "BL_Texture.h" #include "BL_Shader.h" +#include "BL_BlenderShader.h" #include "PyObjectPlus.h" @@ -60,6 +61,10 @@ public: TCachingInfo& cachingInfo )const; + void ActivateBlenderShaders( + RAS_IRasterizer* rasty, + TCachingInfo& cachingInfo + )const; MTFace* GetMTFace(void) const; unsigned int* GetMCol(void) const; @@ -86,8 +91,9 @@ public: // pre calculate to avoid pops/lag at startup virtual void OnConstruction( ); private: - BL_Material* mMaterial; - BL_Shader* mShader; + BL_Material* mMaterial; + BL_Shader* mShader; + BL_BlenderShader* mBlenderShader; KX_Scene* mScene; BL_Texture mTextures[MAXTEX]; // texture array bool mUserDefBlend; @@ -95,12 +101,15 @@ private: bool mModified; bool mConstructed; // if false, don't clean on exit + void SetBlenderGLSLShader(); + void ActivatGLMaterials( RAS_IRasterizer* rasty )const; void ActivateTexGen( RAS_IRasterizer *ras ) const; // message centers void setTexData( bool enable,RAS_IRasterizer *ras); + void setBlenderShaderData( bool enable, RAS_IRasterizer *ras); void setShaderData( bool enable, RAS_IRasterizer *ras); bool setDefaultBlending(); diff --git a/source/gameengine/Ketsji/KX_GameObject.cpp b/source/gameengine/Ketsji/KX_GameObject.cpp index 6fde94fec53..5698c106b17 100644 --- a/source/gameengine/Ketsji/KX_GameObject.cpp +++ b/source/gameengine/Ketsji/KX_GameObject.cpp @@ -81,8 +81,8 @@ KX_GameObject::KX_GameObject( m_bVisible(true), m_pPhysicsController1(NULL), m_pPhysicsEnvironment(NULL), - m_isDeformable(false), - m_pHitObject(NULL) + m_pHitObject(NULL), + m_isDeformable(false) { m_ignore_activity_culling = false; m_pClient_info = new KX_ClientObjectInfo(this, KX_ClientObjectInfo::ACTOR); diff --git a/source/gameengine/Ketsji/KX_ISceneConverter.h b/source/gameengine/Ketsji/KX_ISceneConverter.h index bba289bf891..f069048cd3d 100644 --- a/source/gameengine/Ketsji/KX_ISceneConverter.h +++ b/source/gameengine/Ketsji/KX_ISceneConverter.h @@ -74,6 +74,9 @@ public: virtual void SetMaterials(bool val) =0; virtual bool GetMaterials()=0; + // use blender glsl materials + virtual void SetGLSLMaterials(bool val) =0; + virtual bool GetGLSLMaterials()=0; }; #endif //__KX_ISCENECONVERTER_H diff --git a/source/gameengine/Ketsji/KX_PythonInit.cpp b/source/gameengine/Ketsji/KX_PythonInit.cpp index a80a7f04e8f..0831788009d 100644 --- a/source/gameengine/Ketsji/KX_PythonInit.cpp +++ b/source/gameengine/Ketsji/KX_PythonInit.cpp @@ -28,25 +28,7 @@ * Initialize Python thingies. */ -#ifdef HAVE_CONFIG_H -#include -#endif - -#ifdef WIN32 -#include -#endif // WIN32 -#ifdef __APPLE__ -#define GL_GLEXT_LEGACY 1 -#include -#include -#else -#include -/* #if defined(__sun__) && !defined(__sparc__) -#include -#else */ -#include -/* #endif */ -#endif +#include "GL/glew.h" #include @@ -310,17 +292,13 @@ static PyObject* gPyGetCurrentScene(PyObject* self, static PyObject *pyPrintExt(PyObject *,PyObject *,PyObject *) { #define pprint(x) std::cout << x << std::endl; - bgl::BL_EXTInfo ext = bgl::RAS_EXT_support; bool count=0; bool support=0; pprint("Supported Extensions..."); -#ifdef GL_ARB_shader_objects - pprint(" GL_ARB_shader_objects supported? "<< (ext._ARB_shader_objects?"yes.":"no.")); + pprint(" GL_ARB_shader_objects supported? "<< (GLEW_ARB_shader_objects?"yes.":"no.")); count = 1; -#endif -#ifdef GL_ARB_vertex_shader - support= ext._ARB_vertex_shader; + support= GLEW_ARB_vertex_shader; pprint(" GL_ARB_vertex_shader supported? "<< (support?"yes.":"no.")); count = 1; if(support){ @@ -339,9 +317,8 @@ static PyObject *pyPrintExt(PyObject *,PyObject *,PyObject *) pprint(" Max combined texture units." << max); pprint(""); } -#endif -#ifdef GL_ARB_fragment_shader - support=ext._ARB_fragment_shader; + + support=GLEW_ARB_fragment_shader; pprint(" GL_ARB_fragment_shader supported? "<< (support?"yes.":"no.")); count = 1; if(support){ @@ -351,9 +328,8 @@ static PyObject *pyPrintExt(PyObject *,PyObject *,PyObject *) pprint(" Max uniform components." << max); pprint(""); } -#endif -#ifdef GL_ARB_texture_cube_map - support = ext._ARB_texture_cube_map; + + support = GLEW_ARB_texture_cube_map; pprint(" GL_ARB_texture_cube_map supported? "<< (support?"yes.":"no.")); count = 1; if(support){ @@ -363,25 +339,21 @@ static PyObject *pyPrintExt(PyObject *,PyObject *,PyObject *) pprint(" Max cubemap size." << size); pprint(""); } -#endif -#if defined(GL_ARB_multitexture) && defined(WITH_GLEXT) - if (!getenv("WITHOUT_GLEXT")) { - support = ext._ARB_multitexture; - count = 1; - pprint(" GL_ARB_multitexture supported? "<< (support?"yes.":"no.")); - if(support){ - pprint(" ----------Details----------"); - int units=0; - glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, (GLint*)&units); - pprint(" Max texture units available. " << units); - pprint(""); - } - } -#endif -#ifdef GL_ARB_texture_env_combine - pprint(" GL_ARB_texture_env_combine supported? "<< (ext._ARB_texture_env_combine?"yes.":"no.")); + + support = GLEW_ARB_multitexture; count = 1; -#endif + pprint(" GL_ARB_multitexture supported? "<< (support?"yes.":"no.")); + if(support){ + pprint(" ----------Details----------"); + int units=0; + glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, (GLint*)&units); + pprint(" Max texture units available. " << units); + pprint(""); + } + + pprint(" GL_ARB_texture_env_combine supported? "<< (GLEW_ARB_texture_env_combine?"yes.":"no.")); + count = 1; + if(!count) pprint("No extenstions are used in this build"); diff --git a/source/gameengine/Ketsji/Makefile b/source/gameengine/Ketsji/Makefile index e6e541d0931..47a4855b00c 100644 --- a/source/gameengine/Ketsji/Makefile +++ b/source/gameengine/Ketsji/Makefile @@ -36,6 +36,7 @@ include nan_compile.mk CCFLAGS += $(LEVEL_1_CPP_WARNINGS) CPPFLAGS += $(OGL_CPPFLAGS) +CPPFLAGS += -I$(NAN_GLEW)/include CPPFLAGS += -I$(OPENGL_HEADERS) CPPFLAGS += -I$(NAN_PYTHON)/include/python$(NAN_PYTHON_VERSION) -I../../blender/python CPPFLAGS += -I$(NAN_STRING)/include diff --git a/source/gameengine/Ketsji/SConscript b/source/gameengine/Ketsji/SConscript index c7c80345796..fdac5a71071 100644 --- a/source/gameengine/Ketsji/SConscript +++ b/source/gameengine/Ketsji/SConscript @@ -18,7 +18,7 @@ incs += ' #source/gameengine/SceneGraph #source/gameengine/Physics/common #sourc incs += ' #source/gameengine/Physics/BlOde #source/gameengine/Physics/Dummy' incs += ' #source/gameengine/Physics/Sumo #source/gameengine/Physics/Sumo/include' incs += ' #source/gameengine/Physics/Sumo/Fuzzics/include #source/gameengine/Network/LoopBackNetwork' -incs += ' #source/blender/misc #source/blender/blenloader' +incs += ' #source/blender/misc #source/blender/blenloader #extern/glew/include' cflags = [] if env['OURPLATFORM'] == 'win32-vc': diff --git a/source/gameengine/Rasterizer/CMakeLists.txt b/source/gameengine/Rasterizer/CMakeLists.txt index e604fe0e133..18a755afefd 100644 --- a/source/gameengine/Rasterizer/CMakeLists.txt +++ b/source/gameengine/Rasterizer/CMakeLists.txt @@ -31,6 +31,7 @@ SET(INC ../../../source/kernel/gen_system ../../../intern/string ../../../intern/moto/include + ../../../extern/glew/include ) BLENDERLIB(bf_rasterizer "${SRC}" "${INC}") diff --git a/source/gameengine/Rasterizer/Makefile b/source/gameengine/Rasterizer/Makefile index d544056e8ae..1ca3e3b0283 100644 --- a/source/gameengine/Rasterizer/Makefile +++ b/source/gameengine/Rasterizer/Makefile @@ -35,6 +35,7 @@ include nan_compile.mk CCFLAGS += $(LEVEL_1_CPP_WARNINGS) +CPPFLAGS += -I$(NAN_GLEW)/include CPPFLAGS += -I$(OPENGL_HEADERS) CPPFLAGS += -I$(NAN_STRING)/include CPPFLAGS += -I$(NAN_MOTO)/include diff --git a/source/gameengine/Rasterizer/RAS_2DFilterManager.cpp b/source/gameengine/Rasterizer/RAS_2DFilterManager.cpp index 80d6d55df25..291890a8dde 100644 --- a/source/gameengine/Rasterizer/RAS_2DFilterManager.cpp +++ b/source/gameengine/Rasterizer/RAS_2DFilterManager.cpp @@ -46,18 +46,7 @@ #include "RAS_2DFilterManager.h" #include -#ifdef WIN32 -// OpenGL gl.h needs 'windows.h' on windows platforms -#include -#endif //WIN32 -#ifdef __APPLE__ -#define GL_GLEXT_LEGACY 1 -#include -#else -#include -#endif - -#include "RAS_OpenGLRasterizer/RAS_GLExtensionManager.h" +#include "GL/glew.h" #ifdef HAVE_CONFIG_H #include @@ -69,7 +58,7 @@ texturewidth(-1), textureheight(-1), canvaswidth(-1), canvasheight(-1), numberoffilters(0),texname(-1) { - isshadersupported = bgl::QueryVersion(2,0); + isshadersupported = GLEW_VERSION_2_0; if(!isshadersupported) { std::cout<<"shaders not supported!" << std::endl; @@ -93,14 +82,14 @@ unsigned int RAS_2DFilterManager::CreateShaderProgram(char* shadersource) { GLuint program = 0; #if defined(GL_ARB_shader_objects) && defined(WITH_GLEXT) - GLuint fShader = bgl::blCreateShaderObjectARB(GL_FRAGMENT_SHADER); + GLuint fShader = glCreateShaderObjectARB(GL_FRAGMENT_SHADER); GLint success; - bgl::blShaderSourceARB(fShader, 1, (const char**)&shadersource, NULL); + glShaderSourceARB(fShader, 1, (const char**)&shadersource, NULL); - bgl::blCompileShaderARB(fShader); + glCompileShaderARB(fShader); - bgl::blGetObjectParameterivARB(fShader, GL_COMPILE_STATUS, &success); + glGetObjectParameterivARB(fShader, GL_COMPILE_STATUS, &success); if(!success) { /*Shader Comile Error*/ @@ -108,11 +97,11 @@ unsigned int RAS_2DFilterManager::CreateShaderProgram(char* shadersource) return 0; } - program = bgl::blCreateProgramObjectARB(); - bgl::blAttachObjectARB(program, fShader); + program = glCreateProgramObjectARB(); + glAttachObjectARB(program, fShader); - bgl::blLinkProgramARB(program); - bgl::blGetObjectParameterivARB(program, GL_LINK_STATUS, &success); + glLinkProgramARB(program); + glGetObjectParameterivARB(program, GL_LINK_STATUS, &success); if (!success) { /*Program Link Error*/ @@ -120,8 +109,8 @@ unsigned int RAS_2DFilterManager::CreateShaderProgram(char* shadersource) return 0; } - bgl::blValidateProgramARB(program); - bgl::blGetObjectParameterivARB(program, GL_VALIDATE_STATUS, &success); + glValidateProgramARB(program); + glGetObjectParameterivARB(program, GL_VALIDATE_STATUS, &success); if (!success) { /*Program Validation Error*/ @@ -164,30 +153,30 @@ void RAS_2DFilterManager::StartShaderProgram(unsigned int shaderprogram) { #if defined(GL_ARB_shader_objects) && defined(WITH_GLEXT) GLint uniformLoc; - bgl::blUseProgramObjectARB(shaderprogram); - uniformLoc = bgl::blGetUniformLocationARB(shaderprogram, "bgl_RenderedTexture"); - bgl::blActiveTextureARB(GL_TEXTURE0); + glUseProgramObjectARB(shaderprogram); + uniformLoc = glGetUniformLocationARB(shaderprogram, "bgl_RenderedTexture"); + glActiveTextureARB(GL_TEXTURE0); //glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, texname); if (uniformLoc != -1) { - bgl::blUniform1iARB(uniformLoc, 0); + glUniform1iARB(uniformLoc, 0); } - uniformLoc = bgl::blGetUniformLocationARB(shaderprogram, "bgl_TextureCoordinateOffset"); + uniformLoc = glGetUniformLocationARB(shaderprogram, "bgl_TextureCoordinateOffset"); if (uniformLoc != -1) { - bgl::blUniform2fvARB(uniformLoc, 9, textureoffsets); + glUniform2fvARB(uniformLoc, 9, textureoffsets); } - uniformLoc = bgl::blGetUniformLocationARB(shaderprogram, "bgl_RenderedTextureWidth"); + uniformLoc = glGetUniformLocationARB(shaderprogram, "bgl_RenderedTextureWidth"); if (uniformLoc != -1) { - bgl::blUniform1fARB(uniformLoc,texturewidth); + glUniform1fARB(uniformLoc,texturewidth); } - uniformLoc = bgl::blGetUniformLocationARB(shaderprogram, "bgl_RenderedTextureHeight"); + uniformLoc = glGetUniformLocationARB(shaderprogram, "bgl_RenderedTextureHeight"); if (uniformLoc != -1) { - bgl::blUniform1fARB(uniformLoc,textureheight); + glUniform1fARB(uniformLoc,textureheight); } #endif } @@ -195,7 +184,7 @@ void RAS_2DFilterManager::StartShaderProgram(unsigned int shaderprogram) void RAS_2DFilterManager::EndShaderProgram() { #if defined(GL_ARB_shader_objects) && defined(WITH_GLEXT) - bgl::blUseProgramObjectARB(0); + glUseProgramObjectARB(0); #endif } @@ -325,7 +314,7 @@ void RAS_2DFilterManager::EnableFilter(RAS_2DFILTER_MODE mode, int pass, STR_Str if(mode == RAS_2DFILTER_NOFILTER) { if(m_filters[pass]) - bgl::blDeleteObjectARB(m_filters[pass]); + glDeleteObjectARB(m_filters[pass]); m_enabled[pass] = 0; m_filters[pass] = 0; return; @@ -334,7 +323,7 @@ void RAS_2DFilterManager::EnableFilter(RAS_2DFILTER_MODE mode, int pass, STR_Str if(mode == RAS_2DFILTER_CUSTOMFILTER) { if(m_filters[pass]) - bgl::blDeleteObjectARB(m_filters[pass]); + glDeleteObjectARB(m_filters[pass]); m_filters[pass] = CreateShaderProgram(text.Ptr()); m_enabled[pass] = 1; return; @@ -343,7 +332,7 @@ void RAS_2DFilterManager::EnableFilter(RAS_2DFILTER_MODE mode, int pass, STR_Str if(mode>=RAS_2DFILTER_MOTIONBLUR && mode<=RAS_2DFILTER_INVERT) { if(m_filters[pass]) - bgl::blDeleteObjectARB(m_filters[pass]); + glDeleteObjectARB(m_filters[pass]); m_filters[pass] = CreateShaderProgram(mode); m_enabled[pass] = 1; } diff --git a/source/gameengine/Rasterizer/RAS_CameraData.h b/source/gameengine/Rasterizer/RAS_CameraData.h index 6aa9b34962b..0327a3f4763 100644 --- a/source/gameengine/Rasterizer/RAS_CameraData.h +++ b/source/gameengine/Rasterizer/RAS_CameraData.h @@ -49,12 +49,12 @@ struct RAS_CameraData m_clipstart(clipstart), m_clipend(clipend), m_perspective(perspective), - m_focallength(focallength), m_viewport(viewport), m_viewportleft(viewportleft), m_viewportbottom(viewportbottom), m_viewportright(viewportright), - m_viewporttop(viewporttop) + m_viewporttop(viewporttop), + m_focallength(focallength) { } }; diff --git a/source/gameengine/Rasterizer/RAS_IPolygonMaterial.cpp b/source/gameengine/Rasterizer/RAS_IPolygonMaterial.cpp index 61860c4c405..bff98abe058 100644 --- a/source/gameengine/Rasterizer/RAS_IPolygonMaterial.cpp +++ b/source/gameengine/Rasterizer/RAS_IPolygonMaterial.cpp @@ -56,7 +56,6 @@ RAS_IPolyMaterial::RAS_IPolyMaterial(const STR_String& texname, m_bIsTriangle(bIsTriangle), m_polymatid(m_newpolymatid++), m_flag(0), - m_enabled(0), m_multimode(0) { m_shininess = 35.0; @@ -148,10 +147,5 @@ const unsigned int RAS_IPolyMaterial::GetFlag() const { return m_flag; } -const unsigned int RAS_IPolyMaterial::GetEnabled() const -{ - return m_enabled; -} - unsigned int RAS_IPolyMaterial::m_newpolymatid = 0; diff --git a/source/gameengine/Rasterizer/RAS_IPolygonMaterial.h b/source/gameengine/Rasterizer/RAS_IPolygonMaterial.h index 3284ddb7ddd..09824f6975c 100644 --- a/source/gameengine/Rasterizer/RAS_IPolygonMaterial.h +++ b/source/gameengine/Rasterizer/RAS_IPolygonMaterial.h @@ -77,7 +77,6 @@ protected: // will move... unsigned int m_flag;//MaterialProps - unsigned int m_enabled;// enabled for this mat int m_multimode; // sum of values public: @@ -141,7 +140,6 @@ public: const STR_String& GetMaterialName() const; const STR_String& GetTextureName() const; const unsigned int GetFlag() const; - const unsigned int GetEnabled() const; /* * PreCalculate texture gen diff --git a/source/gameengine/Rasterizer/RAS_IRasterizer.h b/source/gameengine/Rasterizer/RAS_IRasterizer.h index 18a7f261c94..dbedc492afa 100644 --- a/source/gameengine/Rasterizer/RAS_IRasterizer.h +++ b/source/gameengine/Rasterizer/RAS_IRasterizer.h @@ -213,17 +213,7 @@ public: bool useObjectColor, const MT_Vector4& rgbacolor, class KX_ListSlot** slot)=0; - /** - * @copydoc IndexPrimitives - * IndexPrimitivesEx will renormalize faces if @param vertexarrays[i].getFlag() & TV_CALCFACENORMAL - */ - virtual void IndexPrimitives_Ex( const vecVertexArray& vertexarrays, - const vecIndexArrays & indexarrays, - int mode, - class RAS_IPolyMaterial* polymat, - class RAS_IRenderTools* rendertools, - bool useObjectColor, - const MT_Vector4& rgbacolor)=0; + /** * IndexPrimitives_3DText will render text into the polygons. * The text to be rendered is from @param rendertools client object's text property. @@ -246,16 +236,6 @@ public: const MT_Vector4& rgbacolor, class KX_ListSlot** slot)=0; - virtual void IndexPrimitivesMulti_Ex( - const vecVertexArray& vertexarrays, - const vecIndexArrays & indexarrays, - int mode, - class RAS_IPolyMaterial* polymat, - class RAS_IRenderTools* rendertools, - bool useObjectColor, - const MT_Vector4& rgbacolor)=0; - - virtual void SetProjectionMatrix(MT_CmMatrix4x4 & mat)=0; /* This one should become our final version, methinks. */ /** @@ -389,8 +369,11 @@ public: virtual void DrawDebugLine(const MT_Vector3& from,const MT_Vector3& to,const MT_Vector3& color)=0; - virtual void SetTexCoords(TexCoGen coords, int unit) = 0; - virtual void SetAttrib(int type) = 0; + + virtual void SetTexCoordNum(int num) = 0; + virtual void SetAttribNum(int num) = 0; + virtual void SetTexCoord(TexCoGen coords, int unit) = 0; + virtual void SetAttrib(TexCoGen coords, int unit) = 0; virtual void GetViewMatrix(MT_Matrix4x4 &mat) const = 0; virtual bool QueryLists(){return false;} diff --git a/source/gameengine/Rasterizer/RAS_MaterialBucket.cpp b/source/gameengine/Rasterizer/RAS_MaterialBucket.cpp index 96ce220ae4d..1beade7acf7 100644 --- a/source/gameengine/Rasterizer/RAS_MaterialBucket.cpp +++ b/source/gameengine/Rasterizer/RAS_MaterialBucket.cpp @@ -177,7 +177,6 @@ bool RAS_MaterialBucket::ActivateMaterial(const MT_Transform& cameratrans, RAS_I bool dolights = false; const unsigned int flag = m_material->GetFlag(); - if( flag & RAS_BLENDERMAT) dolights = (flag &RAS_MULTILIGHT)!=0; else @@ -237,11 +236,10 @@ void RAS_MaterialBucket::RenderMeshSlot(const MT_Transform& cameratrans, RAS_IRa rendertools, // needed for textprinting on polys ms.m_bObjectColor, ms.m_RGBAcolor); - } // for using glMultiTexCoord - else if(m_material->GetFlag() & RAS_MULTITEX ) + else if((m_material->GetFlag() & RAS_MULTITEX)) { rasty->IndexPrimitivesMulti( ms.m_mesh->GetVertexCache(m_material), @@ -251,37 +249,10 @@ void RAS_MaterialBucket::RenderMeshSlot(const MT_Transform& cameratrans, RAS_IRa rendertools, ms.m_bObjectColor, ms.m_RGBAcolor, - &ms.m_DisplayList + (ms.m_pDeformer)? 0: &ms.m_DisplayList ); } - // for using glMultiTexCoord on deformer - else if(m_material->GetFlag() & RAS_DEFMULTI ) - { - rasty->IndexPrimitivesMulti_Ex( - ms.m_mesh->GetVertexCache(m_material), - ms.m_mesh->GetIndexCache(m_material), - drawmode, - m_material, - rendertools, - ms.m_bObjectColor, - ms.m_RGBAcolor - ); - } - - // Use the (slower) IndexPrimitives_Ex which can recalc face normals & such - // for deformed objects - eventually should be extended to recalc ALL normals - else if (ms.m_pDeformer){ - rasty->IndexPrimitives_Ex( - ms.m_mesh->GetVertexCache(m_material), - ms.m_mesh->GetIndexCache(m_material), - drawmode, - m_material, - rendertools, // needed for textprinting on polys - ms.m_bObjectColor, - ms.m_RGBAcolor - ); - } // Use the normal IndexPrimitives else { @@ -293,7 +264,7 @@ void RAS_MaterialBucket::RenderMeshSlot(const MT_Transform& cameratrans, RAS_IRa rendertools, // needed for textprinting on polys ms.m_bObjectColor, ms.m_RGBAcolor, - &ms.m_DisplayList + (ms.m_pDeformer)? 0: &ms.m_DisplayList ); } @@ -316,14 +287,14 @@ void RAS_MaterialBucket::Render(const MT_Transform& cameratrans, //rasty->SetMaterial(*m_material); - int drawmode; for (T_MeshSlotList::const_iterator it = m_meshSlots.begin(); ! (it == m_meshSlots.end()); ++it) { rendertools->SetClientObject((*it).m_clientObj); - while (ActivateMaterial(cameratrans, rasty, rendertools, drawmode)) + while (ActivateMaterial(cameratrans, rasty, rendertools, drawmode)) { RenderMeshSlot(cameratrans, rasty, rendertools, *it, drawmode); + } } // to reset the eventual GL_CW mode rendertools->SetClientObject(NULL); diff --git a/source/gameengine/Rasterizer/RAS_MeshObject.cpp b/source/gameengine/Rasterizer/RAS_MeshObject.cpp index e4b654343e7..db74110ceea 100644 --- a/source/gameengine/Rasterizer/RAS_MeshObject.cpp +++ b/source/gameengine/Rasterizer/RAS_MeshObject.cpp @@ -256,27 +256,30 @@ int RAS_MeshObject::FindOrAddVertex(int vtxarray, const MT_Vector4& tangent, const unsigned int rgbacolor, const MT_Vector3& normal, + bool flat, RAS_IPolyMaterial* mat, int orgindex) { KX_ArrayOptimizer* ao = GetArrayOptimizer(mat);//*(m_matVertexArrays[*mat]); int numverts = ao->m_VertexArrayCache1[vtxarray]->size();//m_VertexArrayCount[vtxarray]; - RAS_TexVert newvert(xyz,uv,uv2,tangent,rgbacolor,normal, 0); + RAS_TexVert newvert(xyz,uv,uv2,tangent,rgbacolor,normal, flat? TV_CALCFACENORMAL: 0); + #define KX_FIND_SHARED_VERTICES #ifdef KX_FIND_SHARED_VERTICES - - for (std::vector::iterator it = m_xyz_index_to_vertex_index_mapping[orgindex].begin(); - it != m_xyz_index_to_vertex_index_mapping[orgindex].end(); - it++) - { - if ((*it).m_arrayindex1 == ao->m_index1 && - (*it).m_array == vtxarray && - *(*it).m_matid == *mat && - (*ao->m_VertexArrayCache1[vtxarray])[(*it).m_index].closeTo(&newvert) - ) + if(!flat) { + for (std::vector::iterator it = m_xyz_index_to_vertex_index_mapping[orgindex].begin(); + it != m_xyz_index_to_vertex_index_mapping[orgindex].end(); + it++) { - return (*it).m_index; + if ((*it).m_arrayindex1 == ao->m_index1 && + (*it).m_array == vtxarray && + *(*it).m_matid == *mat && + (*ao->m_VertexArrayCache1[vtxarray])[(*it).m_index].closeTo(&newvert) + ) + { + return (*it).m_index; + } } } #endif // KX_FIND_SHARED_VERTICES diff --git a/source/gameengine/Rasterizer/RAS_MeshObject.h b/source/gameengine/Rasterizer/RAS_MeshObject.h index 89c472cd0d4..d8e7a3391aa 100644 --- a/source/gameengine/Rasterizer/RAS_MeshObject.h +++ b/source/gameengine/Rasterizer/RAS_MeshObject.h @@ -238,6 +238,7 @@ public: const MT_Vector4& tangent, const unsigned int rgbacolor, const MT_Vector3& normal, + bool flat, RAS_IPolyMaterial* mat, int orgindex ); diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/ARB_multitexture.h b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/ARB_multitexture.h deleted file mode 100644 index a2f27ce3361..00000000000 --- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/ARB_multitexture.h +++ /dev/null @@ -1,150 +0,0 @@ -#ifndef __ARB_MULTITEXTURE_H__ -#define __ARB_MULTITEXTURE_H__ - -/* -*/ - -/* ---------------------------------------------------------------------------- - GL_ARB_multitexture ----------------------------------------------------------------------------- */ -#ifdef GL_ARB_multitexture - #define GL_TEXTURE0_ARB 0x84C0 - #define GL_TEXTURE1_ARB 0x84C1 - #define GL_TEXTURE2_ARB 0x84C2 - #define GL_TEXTURE3_ARB 0x84C3 - #define GL_TEXTURE4_ARB 0x84C4 - #define GL_TEXTURE5_ARB 0x84C5 - #define GL_TEXTURE6_ARB 0x84C6 - #define GL_TEXTURE7_ARB 0x84C7 - #define GL_TEXTURE8_ARB 0x84C8 - #define GL_TEXTURE9_ARB 0x84C9 - #define GL_TEXTURE10_ARB 0x84CA - #define GL_ACTIVE_TEXTURE_ARB 0x84E0 - #define GL_CLIENT_ACTIVE_TEXTURE_ARB 0x84E1 - #define GL_MAX_TEXTURE_UNITS_ARB 0x84E2 -#endif - - -/* ---------------------------------------------------------------------------- - GL_ARB_texture_env_combine ----------------------------------------------------------------------------- */ -#ifdef GL_ARB_texture_env_combine - #define GL_COMBINE_ARB 0x8570 - #define GL_COMBINE_RGB_ARB 0x8571 - #define GL_COMBINE_ALPHA_ARB 0x8572 - #define GL_SOURCE0_RGB_ARB 0x8580 - #define GL_SOURCE1_RGB_ARB 0x8581 - #define GL_SOURCE2_RGB_ARB 0x8582 - #define GL_SOURCE0_ALPHA_ARB 0x8588 - #define GL_SOURCE1_ALPHA_ARB 0x8589 - #define GL_SOURCE2_ALPHA_ARB 0x858A - #define GL_OPERAND0_RGB_ARB 0x8590 - #define GL_OPERAND1_RGB_ARB 0x8591 - #define GL_OPERAND2_RGB_ARB 0x8592 - #define GL_OPERAND0_ALPHA_ARB 0x8598 - #define GL_OPERAND1_ALPHA_ARB 0x8599 - #define GL_OPERAND2_ALPHA_ARB 0x859A - #define GL_RGB_SCALE_ARB 0x8573 - #define GL_ADD_SIGNED_ARB 0x8574 - #define GL_INTERPOLATE_ARB 0x8575 - #define GL_SUBTRACT_ARB 0x84E7 - #define GL_CONSTANT_ARB 0x8576 - #define GL_PRIMARY_COLOR_ARB 0x8577 - #define GL_PREVIOUS_ARB 0x8578 -#endif - -/* ---------------------------------------------------------------------------- - GL_ARB_texture_cube_map ----------------------------------------------------------------------------- */ -#ifdef GL_ARB_texture_cube_map - #define GL_NORMAL_MAP_ARB 0x8511 - #define GL_REFLECTION_MAP_ARB 0x8512 - #define GL_TEXTURE_CUBE_MAP_ARB 0x8513 - #define GL_TEXTURE_BINDING_CUBE_MAP_ARB 0x8514 - #define GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB 0x8515 - #define GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB 0x8516 - #define GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB 0x8517 - #define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB 0x8518 - #define GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB 0x8519 - #define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB 0x851A - #define GL_PROXY_TEXTURE_CUBE_MAP_ARB 0x851B - #define GL_MAX_CUBE_MAP_TEXTURE_SIZE_ARB 0x851C -#endif - -/* ---------------------------------------------------------------------------- - GL_ARB_shader_objects ----------------------------------------------------------------------------- */ -#ifdef GL_ARB_shader_objects - #define GL_PROGRAM_OBJECT_ARB 0x8B40 - #define GL_SHADER_OBJECT_ARB 0x8B48 - #define GL_OBJECT_TYPE_ARB 0x8B4E - #define GL_OBJECT_SUBTYPE_ARB 0x8B4F - #define GL_FLOAT_VEC2_ARB 0x8B50 - #define GL_FLOAT_VEC3_ARB 0x8B51 - #define GL_FLOAT_VEC4_ARB 0x8B52 - #define GL_INT_VEC2_ARB 0x8B53 - #define GL_INT_VEC3_ARB 0x8B54 - #define GL_INT_VEC4_ARB 0x8B55 - #define GL_BOOL_ARB 0x8B56 - #define GL_BOOL_VEC2_ARB 0x8B57 - #define GL_BOOL_VEC3_ARB 0x8B58 - #define GL_BOOL_VEC4_ARB 0x8B59 - #define GL_FLOAT_MAT2_ARB 0x8B5A - #define GL_FLOAT_MAT3_ARB 0x8B5B - #define GL_FLOAT_MAT4_ARB 0x8B5C - #define GL_SAMPLER_1D_ARB 0x8B5D - #define GL_SAMPLER_2D_ARB 0x8B5E - #define GL_SAMPLER_3D_ARB 0x8B5F - #define GL_SAMPLER_CUBE_ARB 0x8B60 - #define GL_SAMPLER_1D_SHADOW_ARB 0x8B61 - #define GL_SAMPLER_2D_SHADOW_ARB 0x8B62 - #define GL_SAMPLER_2D_RECT_ARB 0x8B63 - #define GL_SAMPLER_2D_RECT_SHADOW_ARB 0x8B64 - #define GL_OBJECT_DELETE_STATUS_ARB 0x8B80 - #define GL_OBJECT_COMPILE_STATUS_ARB 0x8B81 - #define GL_OBJECT_LINK_STATUS_ARB 0x8B82 - #define GL_OBJECT_VALIDATE_STATUS_ARB 0x8B83 - #define GL_OBJECT_INFO_LOG_LENGTH_ARB 0x8B84 - #define GL_OBJECT_ATTACHED_OBJECTS_ARB 0x8B85 - #define GL_OBJECT_ACTIVE_UNIFORMS_ARB 0x8B86 - #define GL_OBJECT_ACTIVE_UNIFORM_MAX_LENGTH_ARB 0x8B87 - #define GL_OBJECT_SHADER_SOURCE_LENGTH_ARB 0x8B88 -#endif - -/* ---------------------------------------------------------------------------- - GL_ARB_vertex_shader ----------------------------------------------------------------------------- */ -#ifdef GL_ARB_vertex_shader - #define GL_VERTEX_SHADER_ARB 0x8B31 - #define GL_MAX_VERTEX_UNIFORM_COMPONENTS_ARB 0x8B4A - #define GL_MAX_VARYING_FLOATS_ARB 0x8B4B - #define GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB 0x8B4C - #define GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS_ARB 0x8B4D - #define GL_OBJECT_ACTIVE_ATTRIBUTES_ARB 0x8B89 - #define GL_OBJECT_ACTIVE_ATTRIBUTE_MAX_LENGTH_ARB 0x8B8A -#endif - - -/* ---------------------------------------------------------------------------- - GL_ARB_fragment_shader ----------------------------------------------------------------------------- */ -#ifdef GL_ARB_fragment_shader - #define GL_FRAGMENT_SHADER_ARB 0x8B30 - #define GL_MAX_FRAGMENT_UNIFORM_COMPONENTS_ARB 0x8B49 - #define GL_FRAGMENT_SHADER_DERIVATIVE_HINT_ARB 0x8B8B -#endif - - -/* ---------------------------------------------------------------------------- - GL_ARB_depth_texture ----------------------------------------------------------------------------- */ -#ifndef GL_ARB_depth_texture - #define GL_DEPTH_COMPONENT16_ARB 0x81A5 - #define GL_DEPTH_COMPONENT24_ARB 0x81A6 - #define GL_DEPTH_COMPONENT32_ARB 0x81A7 - #define GL_TEXTURE_DEPTH_SIZE_ARB 0x884A - #define GL_DEPTH_TEXTURE_MODE_ARB 0x884B -#endif - - -#endif//__ARB_MULTITEXTURE_H__ diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/CMakeLists.txt b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/CMakeLists.txt index 5153834899b..2a6d64ecc73 100644 --- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/CMakeLists.txt +++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/CMakeLists.txt @@ -31,6 +31,7 @@ SET(INC ../../../../intern/string ../../../../intern/moto/include ../../../../source/gameengine/Rasterizer + ../../../../extern/glew/include ) BLENDERLIB(bf_oglrasterizer "${SRC}" "${INC}") diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/EXT_separate_specular_color.h b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/EXT_separate_specular_color.h deleted file mode 100644 index 5a9d8f32a87..00000000000 --- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/EXT_separate_specular_color.h +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef GL_EXT_separate_specular_color -#define GL_EXT_separate_specular_color 1 -#define GL_LIGHT_MODEL_COLOR_CONTROL_EXT 0x81F8 -#define GL_SINGLE_COLOR_EXT 0x81F9 -#define GL_SEPARATE_SPECULAR_COLOR_EXT 0x81FA -#endif - -#ifndef GL_VERSION_1_2 -#define GL_LIGHT_MODEL_COLOR_CONTROL 0x81F8 -#define GL_SINGLE_COLOR 0x81F9 -#define GL_SEPARATE_SPECULAR_COLOR 0x81FA -#endif diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/Makefile b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/Makefile index 1a88c51dc25..f01978b8eb1 100644 --- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/Makefile +++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/Makefile @@ -36,6 +36,7 @@ include nan_compile.mk CCFLAGS += $(LEVEL_1_CPP_WARNINGS) +CPPFLAGS += -I$(NAN_GLEW)/include CPPFLAGS += -I$(OPENGL_HEADERS) CPPFLAGS += -I$(NAN_STRING)/include CPPFLAGS += -I$(NAN_MOTO)/include diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_GLExtensionManager.cpp b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_GLExtensionManager.cpp index 81a7ccb7a5d..d241bd1ee31 100644 --- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_GLExtensionManager.cpp +++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_GLExtensionManager.cpp @@ -25,665 +25,43 @@ * * ***** END GPL LICENSE BLOCK ***** */ -/* - The extension manager's job is to link at runtime OpenGL extension - functions. - Since the various platform have different methods of finding a fn - pointer, this file attempts to encapsulate all that, so it gets a - little messy. Hopefully we can -*/ -#ifdef HAVE_CONFIG_H -#include -#endif - -#ifdef WIN32 -# include - -# include - -#elif defined(__APPLE__) -# include -# define GL_GLEXT_LEGACY 1 -# include - -#else /* UNIX */ -# include -# include - -# include -#endif - -#include #include -#include -#include -#include - -#include "STR_String.h" #include "RAS_GLExtensionManager.h" -/* ----------------------------------------------------------------------------- - - Platform specific functions section. - - Required Functions: - static void bglInitEntryPoints (void) -- Loads the GL library - static void bglDeallocEntryPoints (void) -- Frees the GL library - static void *bglGetProcAddress(const GLubyte* entry) -- Finds the address of - the GL function entry - -*/ -#if defined(BGL_NO_EXTENSIONS) -static void bglInitEntryPoints (void) {} -static void bglDeallocEntryPoints (void) {} - -static void *bglGetProcAddress(const GLubyte* entry) -{ - /* No Extensions! */ - return NULL; -} -#elif defined(__APPLE__) -/* http://developer.apple.com/qa/qa2001/qa1188.html */ -CFBundleRef gBundleRefOpenGL = NULL; - -// ------------------------- - -static OSStatus bglInitEntryPoints (void) -{ - OSStatus err = noErr; - const Str255 frameworkName = "\pOpenGL.framework"; - FSRefParam fileRefParam; - FSRef fileRef; - CFURLRef bundleURLOpenGL; - - memset(&fileRefParam, 0, sizeof(fileRefParam)); - memset(&fileRef, 0, sizeof(fileRef)); - - fileRefParam.ioNamePtr = frameworkName; - fileRefParam.newRef = &fileRef; - - // Frameworks directory/folder - err = FindFolder (kSystemDomain, kFrameworksFolderType, false, - &fileRefParam.ioVRefNum, (SInt32*)&fileRefParam.ioDirID); - if (noErr != err) { - DebugStr ((unsigned char *)"\pCould not find frameworks folder"); - return err; - } - err = PBMakeFSRefSync (&fileRefParam); // make FSRef for folder - if (noErr != err) { - DebugStr ((unsigned char *)"\pCould make FSref to frameworks folder"); - return err; - } - // create URL to folder - bundleURLOpenGL = CFURLCreateFromFSRef (kCFAllocatorDefault, - &fileRef); - if (!bundleURLOpenGL) { - DebugStr ((unsigned char *)"\pCould create OpenGL Framework bundle URL"); - return paramErr; - } - // create ref to GL's bundle - gBundleRefOpenGL = CFBundleCreate (kCFAllocatorDefault, - bundleURLOpenGL); - if (!gBundleRefOpenGL) { - DebugStr ((unsigned char *)"\pCould not create OpenGL Framework bundle"); - return paramErr; - } - CFRelease (bundleURLOpenGL); // release created bundle - // if the code was successfully loaded, look for our function. - if (!CFBundleLoadExecutable (gBundleRefOpenGL)) { - DebugStr ((unsigned char *)"\pCould not load MachO executable"); - return paramErr; - } - return err; -} - -// ------------------------- - -static void bglDeallocEntryPoints (void) -{ - if (gBundleRefOpenGL != NULL) { - // unload the bundle's code. - CFBundleUnloadExecutable (gBundleRefOpenGL); - CFRelease (gBundleRefOpenGL); - gBundleRefOpenGL = NULL; - } -} - -// ------------------------- - -/*unused*/ -static void * bglGetProcAddress (const GLubyte * pszProc) -{ - if (!gBundleRefOpenGL) - return NULL; - - return CFBundleGetFunctionPointerForName (gBundleRefOpenGL, - CFStringCreateWithCStringNoCopy (NULL, - (const char *) pszProc, CFStringGetSystemEncoding (), NULL)); -} -#elif defined(GLX_ARB_get_proc_address) -/* Not all glx.h define PFNGLXGETPROCADDRESSARBPROC ! - We define our own if needed. */ -#ifdef HAVE_PFNGLXGETPROCADDRESSARBPROC -#define PFNBGLXGETPROCADDRESSARBPROC PFNGLXGETPROCADDRESSARBPROC -#else -typedef void (*(*PFNBGLXGETPROCADDRESSARBPROC)(const GLubyte *procname))(); -#endif - -void *_getProcAddress(const GLubyte *procName) { return NULL; } -PFNBGLXGETPROCADDRESSARBPROC bglGetProcAddress; - - -//weird bug related to combination of pthreads,libGL and dlopen -//cannot call dlclose in such environment, causes crashes -//so try to keep a global handle to libGL -void* libGL = 0; - -static void bglInitEntryPoints (void) -{ - Display *dpy = glXGetCurrentDisplay(); - std::vector Xextensions = STR_String(glXQueryExtensionsString(dpy, DefaultScreen(dpy))).Explode(' '); - if (std::find(Xextensions.begin(), Xextensions.end(), "GLX_ARB_get_proc_address") != Xextensions.end()) - { - if (!libGL) - { - libGL = dlopen("libGL.so", RTLD_LAZY|RTLD_GLOBAL); - if (libGL) - bglGetProcAddress = (PFNBGLXGETPROCADDRESSARBPROC) (dlsym(libGL, "glXGetProcAddressARB")); - else - std::cout << "Error: " << dlerror() << std::endl; - - // dlclose(libGL); - if (!bglGetProcAddress) - bglGetProcAddress = (PFNBGLXGETPROCADDRESSARBPROC) _getProcAddress; - - // -- - if(!bglGetProcAddress) - std::cout << "Error: unable to find _getProcAddress in libGL" << std::endl; - } - } -} - -static void bglDeallocEntryPoints (void) {} - -#elif defined(WIN32) -static void bglInitEntryPoints (void) {} -static void bglDeallocEntryPoints (void) {} - -#define bglGetProcAddress(entry) wglGetProcAddress((LPCSTR) entry) - -#else /* Unknown Platform - disable extensions */ -static void bglInitEntryPoints (void) {} -static void bglDeallocEntryPoints (void) {} - -static void *bglGetProcAddress(const GLubyte* entry) -{ - /* No Extensions! */ - return NULL; -} - -#endif /* End Platform Specific */ - -/* ----------------------------------------------------------------------------- - - GL Extension Manager. -*/ - /* Bit array of available extensions */ -static std::bitset enabled_extensions; -static std::vector extensions; -static int m_debug; - -static void LinkExtensions(); - -static void EnableExtension(bgl::ExtensionName name) -{ - unsigned int num = (unsigned int) name; - if (num < bgl::NUM_EXTENSIONS) - enabled_extensions.set(num); -} - - -static bool QueryExtension(STR_String extension_name) -{ - return std::find(extensions.begin(), extensions.end(), extension_name) != extensions.end(); -} - namespace bgl { - -void InitExtensions(int debug) -{ - m_debug = debug; - bglInitEntryPoints (); //init bundle - EnableExtension(_BGL_TEST); - LinkExtensions(); - bglDeallocEntryPoints(); -} - -bool QueryExtension(ExtensionName name) -{ - unsigned int num = (unsigned int) name; - if (num < NUM_EXTENSIONS) - return enabled_extensions[num]; - - return false; -} - -bool QueryVersion(int major, int minor) -{ - static int gl_major = 0; - static int gl_minor = 0; - - if (gl_major == 0) + void InitExtensions(bool debug) { - const char *gl_version_str = (const char *) glGetString(GL_VERSION); - if (!gl_version_str) - return false; - STR_String gl_version = STR_String(gl_version_str); - int i = gl_version.Find('.'); - gl_major = gl_version.Left(i).ToInt(); - gl_minor = gl_version.Mid(i+1, gl_version.FindOneOf(". ", i+1) - i - 1).ToInt(); - - static bool doQueryVersion = m_debug; - if (doQueryVersion) - { - doQueryVersion = false; - std::cout << "GL_VERSION: " << gl_major << "." << gl_minor << " (" << gl_version << ")" << std::endl; - } - } - - if (gl_major > major) - return true; - - if (gl_major == major && gl_minor >= minor) - return true; + static bool firsttime = true; - return false; -} + if(firsttime) { + firsttime = false; - -/******************************************************************************* -1. Extension function entry points go here - -Need to #ifdef (compile time test for extension) -Add null functions if appropriate - -Some extensions have been incorporated into the core GL, eg Multitexture was -added in GL v1.1. If Blender calls one of these functions before they are -linked, it will crash. Even worse, if Blender *indirectly* calls one of these -functions, (ie the GL implementation calls them itself) Blender will crash. - -We fix this by adding them to the bgl namespace - the functions are now -private to the gameengine. Code can transparently use extensions by adding: - -using namespace bgl; - -to their source. Cunning like a weasel. - - ******************************************************************************/ - -#if defined(PFNGLPNTRIANGLESIATIPROC) -PFNGLPNTRIANGLESIATIPROC glPNTrianglesiATI; -PFNGLPNTRIANGLESFATIPROC glPNTrianglesfATI; -#endif - -BL_EXTInfo RAS_EXT_support; - -#ifdef GL_ARB_multitexture -int max_texture_units = 2; -PFNGLACTIVETEXTUREARBPROC blActiveTextureARB; -PFNGLCLIENTACTIVETEXTUREARBPROC blClientActiveTextureARB; -PFNGLMULTITEXCOORD1DARBPROC blMultiTexCoord1dARB; -PFNGLMULTITEXCOORD1DVARBPROC blMultiTexCoord1dvARB; -PFNGLMULTITEXCOORD1FARBPROC blMultiTexCoord1fARB; -PFNGLMULTITEXCOORD1FVARBPROC blMultiTexCoord1fvARB; -PFNGLMULTITEXCOORD1IARBPROC blMultiTexCoord1iARB; -PFNGLMULTITEXCOORD1IVARBPROC blMultiTexCoord1ivARB; -PFNGLMULTITEXCOORD1SARBPROC blMultiTexCoord1sARB; -PFNGLMULTITEXCOORD1SVARBPROC blMultiTexCoord1svARB; -PFNGLMULTITEXCOORD2DARBPROC blMultiTexCoord2dARB; -PFNGLMULTITEXCOORD2DVARBPROC blMultiTexCoord2dvARB; -PFNGLMULTITEXCOORD2FARBPROC blMultiTexCoord2fARB; -PFNGLMULTITEXCOORD2FVARBPROC blMultiTexCoord2fvARB; -PFNGLMULTITEXCOORD2IARBPROC blMultiTexCoord2iARB; -PFNGLMULTITEXCOORD2IVARBPROC blMultiTexCoord2ivARB; -PFNGLMULTITEXCOORD2SARBPROC blMultiTexCoord2sARB; -PFNGLMULTITEXCOORD2SVARBPROC blMultiTexCoord2svARB; -PFNGLMULTITEXCOORD3DARBPROC blMultiTexCoord3dARB; -PFNGLMULTITEXCOORD3DVARBPROC blMultiTexCoord3dvARB; -PFNGLMULTITEXCOORD3FARBPROC blMultiTexCoord3fARB; -PFNGLMULTITEXCOORD3FVARBPROC blMultiTexCoord3fvARB; -PFNGLMULTITEXCOORD3IARBPROC blMultiTexCoord3iARB; -PFNGLMULTITEXCOORD3IVARBPROC blMultiTexCoord3ivARB; -PFNGLMULTITEXCOORD3SARBPROC blMultiTexCoord3sARB; -PFNGLMULTITEXCOORD3SVARBPROC blMultiTexCoord3svARB; -PFNGLMULTITEXCOORD4DARBPROC blMultiTexCoord4dARB; -PFNGLMULTITEXCOORD4DVARBPROC blMultiTexCoord4dvARB; -PFNGLMULTITEXCOORD4FARBPROC blMultiTexCoord4fARB; -PFNGLMULTITEXCOORD4FVARBPROC blMultiTexCoord4fvARB; -PFNGLMULTITEXCOORD4IARBPROC blMultiTexCoord4iARB; -PFNGLMULTITEXCOORD4IVARBPROC blMultiTexCoord4ivARB; -PFNGLMULTITEXCOORD4SARBPROC blMultiTexCoord4sARB; -PFNGLMULTITEXCOORD4SVARBPROC blMultiTexCoord4svARB; -#endif - -#ifdef GL_ARB_shader_objects - PFNGLDELETEOBJECTARBPROC blDeleteObjectARB; - PFNGLGETHANDLEARBPROC blGetHandleARB; - PFNGLDETACHOBJECTARBPROC blDetachObjectARB; - PFNGLCREATESHADEROBJECTARBPROC blCreateShaderObjectARB; - PFNGLSHADERSOURCEARBPROC blShaderSourceARB; - PFNGLCOMPILESHADERARBPROC blCompileShaderARB; - PFNGLCREATEPROGRAMOBJECTARBPROC blCreateProgramObjectARB; - PFNGLATTACHOBJECTARBPROC blAttachObjectARB; - PFNGLLINKPROGRAMARBPROC blLinkProgramARB; - PFNGLUSEPROGRAMOBJECTARBPROC blUseProgramObjectARB; - PFNGLVALIDATEPROGRAMARBPROC blValidateProgramARB; - PFNGLUNIFORM1FARBPROC blUniform1fARB; - PFNGLUNIFORM2FARBPROC blUniform2fARB; - PFNGLUNIFORM3FARBPROC blUniform3fARB; - PFNGLUNIFORM4FARBPROC blUniform4fARB; - PFNGLUNIFORM1IARBPROC blUniform1iARB; - PFNGLUNIFORM2IARBPROC blUniform2iARB; - PFNGLUNIFORM3IARBPROC blUniform3iARB; - PFNGLUNIFORM4IARBPROC blUniform4iARB; - PFNGLUNIFORM1FVARBPROC blUniform1fvARB; - PFNGLUNIFORM2FVARBPROC blUniform2fvARB; - PFNGLUNIFORM3FVARBPROC blUniform3fvARB; - PFNGLUNIFORM4FVARBPROC blUniform4fvARB; - PFNGLUNIFORM1IVARBPROC blUniform1ivARB; - PFNGLUNIFORM2IVARBPROC blUniform2ivARB; - PFNGLUNIFORM3IVARBPROC blUniform3ivARB; - PFNGLUNIFORM4IVARBPROC blUniform4ivARB; - PFNGLUNIFORMMATRIX2FVARBPROC blUniformMatrix2fvARB; - PFNGLUNIFORMMATRIX3FVARBPROC blUniformMatrix3fvARB; - PFNGLUNIFORMMATRIX4FVARBPROC blUniformMatrix4fvARB; - PFNGLGETOBJECTPARAMETERFVARBPROC blGetObjectParameterfvARB; - PFNGLGETOBJECTPARAMETERIVARBPROC blGetObjectParameterivARB; - PFNGLGETINFOLOGARBPROC blGetInfoLogARB; - PFNGLGETATTACHEDOBJECTSARBPROC blGetAttachedObjectsARB; - PFNGLGETUNIFORMLOCATIONARBPROC blGetUniformLocationARB; - PFNGLGETACTIVEUNIFORMARBPROC blGetActiveUniformARB; - PFNGLGETUNIFORMFVARBPROC blGetUniformfvARB; - PFNGLGETUNIFORMIVARBPROC blGetUniformivARB; - PFNGLGETSHADERSOURCEARBPROC blGetShaderSourceARB; -#endif - -#ifdef GL_ARB_vertex_shader -PFNGLBINDATTRIBLOCATIONARBPROC blBindAttribLocationARB; -PFNGLGETACTIVEATTRIBARBPROC blGetActiveAttribARB; -PFNGLGETATTRIBLOCATIONARBPROC blGetAttribLocationARB; -#endif - -#ifdef GL_ARB_vertex_program - PFNGLVERTEXATTRIB1FARBPROC blVertexAttrib1fARB; - PFNGLVERTEXATTRIB1FVARBPROC blVertexAttrib1fvARB; - PFNGLVERTEXATTRIB2FARBPROC blVertexAttrib2fARB; - PFNGLVERTEXATTRIB2FVARBPROC blVertexAttrib2fvARB; - PFNGLVERTEXATTRIB3FARBPROC blVertexAttrib3fARB; - PFNGLVERTEXATTRIB3FVARBPROC blVertexAttrib3fvARB; - PFNGLVERTEXATTRIB4FARBPROC blVertexAttrib4fARB; - PFNGLVERTEXATTRIB4FVARBPROC blVertexAttrib4fvARB; - PFNGLGETPROGRAMSTRINGARBPROC blGetProgramStringARB; - PFNGLGETVERTEXATTRIBDVARBPROC blGetVertexAttribdvARB; - PFNGLGETVERTEXATTRIBFVARBPROC blGetVertexAttribfvARB; - PFNGLGETVERTEXATTRIBIVARBPROC blGetVertexAttribivARB; -#endif - - /* -#ifdef GL_EXT_compiled_vertex_array - PFNGLLOCKARRAYSEXTPROC blLockArraysEXT; - PFNGLUNLOCKARRAYSEXTPROC blUnlockArraysEXT; -#endif -*/ - -} // namespace bgl - -using namespace bgl; -/******************************************************************************* -2. Query extension functions here - -Need to #ifdef (compile time test for extension) -Use QueryExtension("GL_EXT_name") to test at runtime. -Use bglGetProcAddress to find entry point -Use EnableExtension(_GL_EXT_...) to allow Blender to use the extension. - - ******************************************************************************/ -static void LinkExtensions() -{ - static bool doDebugMessages = m_debug; - extensions = STR_String((const char *) glGetString(GL_EXTENSIONS)).Explode(' '); - RAS_EXT_support = BL_EXTInfo(); - -#if defined(PFNGLPNTRIANGLESIATIPROC) - if (QueryExtension("GL_ATI_pn_triangles")) - { - glPNTrianglesiATI = reinterpret_cast(bglGetProcAddress((const GLubyte *) "glPNTrianglesiATI")); - glPNTrianglesfATI = reinterpret_cast(bglGetProcAddress((const GLubyte *) "glPNTrianglesfATI")); - if (glPNTrianglesiATI && glPNTrianglesfATI) { - EnableExtension(_GL_ATI_pn_triangles); - if (doDebugMessages) - std::cout << "Enabled GL_ATI_pn_triangles" << std::endl; - } else { - std::cout << "ERROR: GL_ATI_pn_triangles implementation is broken!" << std::endl; - } - } -#endif - -#ifdef GL_ARB_texture_env_combine - if (QueryExtension("GL_ARB_texture_env_combine")) - { - EnableExtension(_GL_ARB_texture_env_combine); - RAS_EXT_support._ARB_texture_env_combine = 1; - if (doDebugMessages) - { - std::cout << "Detected GL_ARB_texture_env_combine" << std::endl; - } - } -#endif - -#ifdef GL_ARB_texture_cube_map - if (QueryExtension("GL_ARB_texture_cube_map")) - { - EnableExtension(_GL_ARB_texture_cube_map); - RAS_EXT_support._ARB_texture_cube_map = 1; - if (doDebugMessages) - std::cout << "Detected GL_ARB_texture_cube_map" << std::endl; - } -#endif - -#if defined(GL_ARB_multitexture) && defined(WITH_GLEXT) - if (!getenv("WITHOUT_GLEXT")) { - if (QueryExtension("GL_ARB_multitexture")) { - bgl::blActiveTextureARB = reinterpret_cast(bglGetProcAddress((const GLubyte *) "glActiveTextureARB")); - bgl::blClientActiveTextureARB = reinterpret_cast(bglGetProcAddress((const GLubyte *) "glClientActiveTextureARB")); - bgl::blMultiTexCoord1dARB = reinterpret_cast(bglGetProcAddress((const GLubyte *) "glMultiTexCoord1dARB")); - bgl::blMultiTexCoord1dvARB = reinterpret_cast(bglGetProcAddress((const GLubyte *) "glMultiTexCoord1dvARB")); - bgl::blMultiTexCoord1fARB = reinterpret_cast(bglGetProcAddress((const GLubyte *) "glMultiTexCoord1fARB")); - bgl::blMultiTexCoord1fvARB = reinterpret_cast(bglGetProcAddress((const GLubyte *) "glMultiTexCoord1fvARB")); - bgl::blMultiTexCoord1iARB = reinterpret_cast(bglGetProcAddress((const GLubyte *) "glMultiTexCoord1iARB")); - bgl::blMultiTexCoord1ivARB = reinterpret_cast(bglGetProcAddress((const GLubyte *) "glMultiTexCoord1ivARB")); - bgl::blMultiTexCoord1sARB = reinterpret_cast(bglGetProcAddress((const GLubyte *) "glMultiTexCoord1sARB")); - bgl::blMultiTexCoord1svARB = reinterpret_cast(bglGetProcAddress((const GLubyte *) "glMultiTexCoord1svARB")); - bgl::blMultiTexCoord2dARB = reinterpret_cast(bglGetProcAddress((const GLubyte *) "glMultiTexCoord2dARB")); - bgl::blMultiTexCoord2dvARB = reinterpret_cast(bglGetProcAddress((const GLubyte *) "glMultiTexCoord2dvARB")); - bgl::blMultiTexCoord2fARB = reinterpret_cast(bglGetProcAddress((const GLubyte *) "glMultiTexCoord2fARB")); - bgl::blMultiTexCoord2fvARB = reinterpret_cast(bglGetProcAddress((const GLubyte *) "glMultiTexCoord2fvARB")); - bgl::blMultiTexCoord2iARB = reinterpret_cast(bglGetProcAddress((const GLubyte *) "glMultiTexCoord2iARB")); - bgl::blMultiTexCoord2ivARB = reinterpret_cast(bglGetProcAddress((const GLubyte *) "glMultiTexCoord2ivARB")); - bgl::blMultiTexCoord2sARB = reinterpret_cast(bglGetProcAddress((const GLubyte *) "glMultiTexCoord2sARB")); - bgl::blMultiTexCoord2svARB = reinterpret_cast(bglGetProcAddress((const GLubyte *) "glMultiTexCoord2svARB")); - bgl::blMultiTexCoord3dARB = reinterpret_cast(bglGetProcAddress((const GLubyte *) "glMultiTexCoord3dARB")); - bgl::blMultiTexCoord3dvARB = reinterpret_cast(bglGetProcAddress((const GLubyte *) "glMultiTexCoord3dvARB")); - bgl::blMultiTexCoord3fARB = reinterpret_cast(bglGetProcAddress((const GLubyte *) "glMultiTexCoord3fARB")); - bgl::blMultiTexCoord3fvARB = reinterpret_cast(bglGetProcAddress((const GLubyte *) "glMultiTexCoord3fvARB")); - bgl::blMultiTexCoord3iARB = reinterpret_cast(bglGetProcAddress((const GLubyte *) "glMultiTexCoord3iARB")); - bgl::blMultiTexCoord3ivARB = reinterpret_cast(bglGetProcAddress((const GLubyte *) "glMultiTexCoord3ivARB")); - bgl::blMultiTexCoord3sARB = reinterpret_cast(bglGetProcAddress((const GLubyte *) "glMultiTexCoord3sARB")); - bgl::blMultiTexCoord3svARB = reinterpret_cast(bglGetProcAddress((const GLubyte *) "glMultiTexCoord3svARB")); - bgl::blMultiTexCoord4dARB = reinterpret_cast(bglGetProcAddress((const GLubyte *) "glMultiTexCoord4dARB")); - bgl::blMultiTexCoord4dvARB = reinterpret_cast(bglGetProcAddress((const GLubyte *) "glMultiTexCoord4dvARB")); - bgl::blMultiTexCoord4fARB = reinterpret_cast(bglGetProcAddress((const GLubyte *) "glMultiTexCoord4fARB")); - bgl::blMultiTexCoord4fvARB = reinterpret_cast(bglGetProcAddress((const GLubyte *) "glMultiTexCoord4fvARB")); - bgl::blMultiTexCoord4iARB = reinterpret_cast(bglGetProcAddress((const GLubyte *) "glMultiTexCoord4iARB")); - bgl::blMultiTexCoord4ivARB = reinterpret_cast(bglGetProcAddress((const GLubyte *) "glMultiTexCoord4ivARB")); - bgl::blMultiTexCoord4sARB = reinterpret_cast(bglGetProcAddress((const GLubyte *) "glMultiTexCoord4sARB")); - bgl::blMultiTexCoord4svARB = reinterpret_cast(bglGetProcAddress((const GLubyte *) "glMultiTexCoord4svARB")); - if (bgl::blActiveTextureARB && bgl::blClientActiveTextureARB && bgl::blMultiTexCoord1dARB && bgl::blMultiTexCoord1dvARB && bgl::blMultiTexCoord1fARB && bgl::blMultiTexCoord1fvARB && bgl::blMultiTexCoord1iARB && bgl::blMultiTexCoord1ivARB && bgl::blMultiTexCoord1sARB && bgl::blMultiTexCoord1svARB && bgl::blMultiTexCoord2dARB && bgl::blMultiTexCoord2dvARB && bgl::blMultiTexCoord2fARB && bgl::blMultiTexCoord2fvARB && bgl::blMultiTexCoord2iARB && bgl::blMultiTexCoord2ivARB && bgl::blMultiTexCoord2sARB && bgl::blMultiTexCoord2svARB && bgl::blMultiTexCoord3dARB && bgl::blMultiTexCoord3dvARB && bgl::blMultiTexCoord3fARB && bgl::blMultiTexCoord3fvARB && bgl::blMultiTexCoord3iARB && bgl::blMultiTexCoord3ivARB && bgl::blMultiTexCoord3sARB && bgl::blMultiTexCoord3svARB && bgl::blMultiTexCoord4dARB && bgl::blMultiTexCoord4dvARB && bgl::blMultiTexCoord4fARB && bgl::blMultiTexCoord4fvARB && bgl::blMultiTexCoord4iARB && bgl::blMultiTexCoord4ivARB && bgl::blMultiTexCoord4sARB && bgl::blMultiTexCoord4svARB) { - EnableExtension(_GL_ARB_multitexture); - RAS_EXT_support._ARB_multitexture = 1; - if (doDebugMessages) - std::cout << "Enabled GL_ARB_multitexture" << std::endl; - } else { - std::cout << "ERROR: GL_ARB_multitexture implementation is broken!" << std::endl; + if(debug) { + if(GLEW_ATI_pn_triangles) + std::cout << "Enabled GL_ATI_pn_triangles" << std::endl; + if(GLEW_ARB_texture_env_combine) + std::cout << "Detected GL_ARB_texture_env_combine" << std::endl; + if(GLEW_ARB_texture_cube_map) + std::cout << "Detected GL_ARB_texture_cube_map" << std::endl; + if(GLEW_ARB_multitexture) + std::cout << "Detected GL_ARB_multitexture" << std::endl; + if(GLEW_ARB_shader_objects) + std::cout << "Detected GL_ARB_shader_objects" << std::endl; + if(GLEW_ARB_vertex_shader) + std::cout << "Detected GL_ARB_vertex_shader" << std::endl; + if(GLEW_ARB_fragment_shader) + std::cout << "Detected GL_ARB_fragment_shader" << std::endl; + if(GLEW_ARB_vertex_program) + std::cout << "Detected GL_ARB_vertex_program" << std::endl; + if(GLEW_ARB_depth_texture) + std::cout << "Detected GL_ARB_depth_texture" << std::endl; + if(GLEW_EXT_separate_specular_color) + std::cout << "Detected GL_EXT_separate_specular_color" << std::endl; } } } -#endif - -#if GL_ARB_shader_objects - if (QueryExtension("GL_ARB_shader_objects")) - { - bgl::blDeleteObjectARB = reinterpret_cast(bglGetProcAddress((const GLubyte *) "glDeleteObjectARB")); - bgl::blGetHandleARB = reinterpret_cast(bglGetProcAddress((const GLubyte *) "glGetHandleARB")); - bgl::blDetachObjectARB = reinterpret_cast(bglGetProcAddress((const GLubyte *) "glDetachObjectARB")); - bgl::blCreateShaderObjectARB = reinterpret_cast(bglGetProcAddress((const GLubyte *) "glCreateShaderObjectARB")); - bgl::blShaderSourceARB = reinterpret_cast(bglGetProcAddress((const GLubyte *) "glShaderSourceARB")); - bgl::blCompileShaderARB = reinterpret_cast(bglGetProcAddress((const GLubyte *) "glCompileShaderARB")); - bgl::blCreateProgramObjectARB = reinterpret_cast(bglGetProcAddress((const GLubyte *) "glCreateProgramObjectARB")); - bgl::blAttachObjectARB = reinterpret_cast(bglGetProcAddress((const GLubyte *) "glAttachObjectARB")); - bgl::blLinkProgramARB = reinterpret_cast(bglGetProcAddress((const GLubyte *) "glLinkProgramARB")); - bgl::blUseProgramObjectARB = reinterpret_cast(bglGetProcAddress((const GLubyte *) "glUseProgramObjectARB")); - bgl::blValidateProgramARB = reinterpret_cast(bglGetProcAddress((const GLubyte *) "glValidateProgramARB")); - bgl::blUniform1fARB = reinterpret_cast(bglGetProcAddress((const GLubyte *) "glUniform1fARB")); - bgl::blUniform2fARB = reinterpret_cast(bglGetProcAddress((const GLubyte *) "glUniform2fARB")); - bgl::blUniform3fARB = reinterpret_cast(bglGetProcAddress((const GLubyte *) "glUniform3fARB")); - bgl::blUniform4fARB = reinterpret_cast(bglGetProcAddress((const GLubyte *) "glUniform4fARB")); - bgl::blUniform1iARB = reinterpret_cast(bglGetProcAddress((const GLubyte *) "glUniform1iARB")); - bgl::blUniform2iARB = reinterpret_cast(bglGetProcAddress((const GLubyte *) "glUniform2iARB")); - bgl::blUniform3iARB = reinterpret_cast(bglGetProcAddress((const GLubyte *) "glUniform3iARB")); - bgl::blUniform4iARB = reinterpret_cast(bglGetProcAddress((const GLubyte *) "glUniform4iARB")); - bgl::blUniform1fvARB = reinterpret_cast(bglGetProcAddress((const GLubyte *) "glUniform1fvARB")); - bgl::blUniform2fvARB = reinterpret_cast(bglGetProcAddress((const GLubyte *) "glUniform2fvARB")); - bgl::blUniform3fvARB = reinterpret_cast(bglGetProcAddress((const GLubyte *) "glUniform3fvARB")); - bgl::blUniform4fvARB = reinterpret_cast(bglGetProcAddress((const GLubyte *) "glUniform4fvARB")); - bgl::blUniform1ivARB = reinterpret_cast(bglGetProcAddress((const GLubyte *) "glUniform1ivARB")); - bgl::blUniform2ivARB = reinterpret_cast(bglGetProcAddress((const GLubyte *) "glUniform2ivARB")); - bgl::blUniform3ivARB = reinterpret_cast(bglGetProcAddress((const GLubyte *) "glUniform3ivARB")); - bgl::blUniform4ivARB = reinterpret_cast(bglGetProcAddress((const GLubyte *) "glUniform4ivARB")); - bgl::blUniformMatrix2fvARB = reinterpret_cast(bglGetProcAddress((const GLubyte *) "glUniformMatrix2fvARB")); - bgl::blUniformMatrix3fvARB = reinterpret_cast(bglGetProcAddress((const GLubyte *) "glUniformMatrix3fvARB")); - bgl::blUniformMatrix4fvARB = reinterpret_cast(bglGetProcAddress((const GLubyte *) "glUniformMatrix4fvARB")); - bgl::blGetObjectParameterfvARB = reinterpret_cast(bglGetProcAddress((const GLubyte *) "glGetObjectParameterfvARB")); - bgl::blGetObjectParameterivARB = reinterpret_cast(bglGetProcAddress((const GLubyte *) "glGetObjectParameterivARB")); - bgl::blGetInfoLogARB = reinterpret_cast(bglGetProcAddress((const GLubyte *) "glGetInfoLogARB")); - bgl::blGetAttachedObjectsARB = reinterpret_cast(bglGetProcAddress((const GLubyte *) "glGetAttachedObjectsARB")); - bgl::blGetUniformLocationARB = reinterpret_cast(bglGetProcAddress((const GLubyte *) "glGetUniformLocationARB")); - bgl::blGetActiveUniformARB = reinterpret_cast(bglGetProcAddress((const GLubyte *) "glGetActiveUniformARB")); - bgl::blGetUniformfvARB = reinterpret_cast(bglGetProcAddress((const GLubyte *) "glGetUniformfvARB")); - bgl::blGetUniformivARB = reinterpret_cast(bglGetProcAddress((const GLubyte *) "glGetUniformivARB")); - bgl::blGetShaderSourceARB = reinterpret_cast(bglGetProcAddress((const GLubyte *) "glGetShaderSourceARB")); - if (bgl::blDeleteObjectARB && bgl::blGetHandleARB && bgl::blDetachObjectARB && bgl::blCreateShaderObjectARB && bgl::blShaderSourceARB && bgl::blCompileShaderARB && bgl::blCreateProgramObjectARB && bgl::blAttachObjectARB && bgl::blLinkProgramARB && bgl::blUseProgramObjectARB && bgl::blValidateProgramARB && bgl::blUniform1fARB && bgl::blUniform2fARB && bgl::blUniform3fARB && bgl::blUniform4fARB && bgl::blUniform1iARB && bgl::blUniform2iARB && bgl::blUniform3iARB && bgl::blUniform4iARB && bgl::blUniform1fvARB && bgl::blUniform2fvARB && bgl::blUniform3fvARB && bgl::blUniform4fvARB && bgl::blUniform1ivARB && bgl::blUniform2ivARB && bgl::blUniform3ivARB && bgl::blUniform4ivARB && bgl::blUniformMatrix2fvARB && bgl::blUniformMatrix3fvARB && bgl::blUniformMatrix4fvARB && bgl::blGetObjectParameterfvARB && bgl::blGetObjectParameterivARB && bgl::blGetInfoLogARB && bgl::blGetAttachedObjectsARB && bgl::blGetUniformLocationARB && bgl::blGetActiveUniformARB && bgl::blGetUniformfvARB && bgl::blGetUniformivARB && bgl::blGetShaderSourceARB) { - EnableExtension(_GL_ARB_shader_objects); - RAS_EXT_support._ARB_shader_objects =1; - if (doDebugMessages) - std::cout << "Enabled GL_ARB_shader_objects" << std::endl; - } else { - std::cout << "ERROR: GL_ARB_shader_objects implementation is broken!" << std::endl; - } - } -#endif - -#if GL_ARB_vertex_shader - if (QueryExtension("GL_ARB_vertex_shader")) - { - bgl::blBindAttribLocationARB = reinterpret_cast(bglGetProcAddress((const GLubyte *) "glBindAttribLocationARB")); - bgl::blGetActiveAttribARB = reinterpret_cast(bglGetProcAddress((const GLubyte *) "glGetActiveAttribARB")); - bgl::blGetAttribLocationARB = reinterpret_cast(bglGetProcAddress((const GLubyte *) "glGetAttribLocationARB")); - if (bgl::blBindAttribLocationARB && bgl::blGetActiveAttribARB && bgl::blGetAttribLocationARB) { - EnableExtension(_GL_ARB_vertex_shader); - RAS_EXT_support._ARB_vertex_shader = 1; - if (doDebugMessages) - std::cout << "Enabled GL_ARB_vertex_shader" << std::endl; - } else { - std::cout << "ERROR: GL_ARB_vertex_shader implementation is broken!" << std::endl; - } - } -#endif - -#ifdef GL_ARB_fragment_shader - if (QueryExtension("GL_ARB_fragment_shader")) - { - EnableExtension(_GL_ARB_fragment_shader); - RAS_EXT_support._ARB_fragment_shader = 1; - if (doDebugMessages) - std::cout << "Detected GL_ARB_fragment_shader" << std::endl; - } -#endif - -#if defined(GL_ARB_vertex_program) - if (QueryExtension("GL_ARB_vertex_program")) - { - bgl::blVertexAttrib1fARB = reinterpret_cast(bglGetProcAddress((const GLubyte *) "glVertexAttrib1fARB")); - bgl::blVertexAttrib1fvARB = reinterpret_cast(bglGetProcAddress((const GLubyte *) "glVertexAttrib1fvARB")); - bgl::blVertexAttrib2fARB = reinterpret_cast(bglGetProcAddress((const GLubyte *) "glVertexAttrib2fARB")); - bgl::blVertexAttrib2fvARB = reinterpret_cast(bglGetProcAddress((const GLubyte *) "glVertexAttrib2fvARB")); - bgl::blVertexAttrib3fARB = reinterpret_cast(bglGetProcAddress((const GLubyte *) "glVertexAttrib3fARB")); - bgl::blVertexAttrib3fvARB = reinterpret_cast(bglGetProcAddress((const GLubyte *) "glVertexAttrib3fvARB")); - bgl::blVertexAttrib4fARB = reinterpret_cast(bglGetProcAddress((const GLubyte *) "glVertexAttrib4fARB")); - bgl::blVertexAttrib4fvARB = reinterpret_cast(bglGetProcAddress((const GLubyte *) "glVertexAttrib4fvARB")); - bgl::blGetVertexAttribdvARB = reinterpret_cast(bglGetProcAddress((const GLubyte *) "glGetVertexAttribdvARB")); - bgl::blGetVertexAttribfvARB = reinterpret_cast(bglGetProcAddress((const GLubyte *) "glGetVertexAttribfvARB")); - bgl::blGetVertexAttribivARB = reinterpret_cast(bglGetProcAddress((const GLubyte *) "glGetVertexAttribivARB")); - if (bgl::blVertexAttrib1fARB && bgl::blVertexAttrib1fvARB && bgl::blVertexAttrib2fARB && bgl::blVertexAttrib2fvARB && bgl::blVertexAttrib3fARB && bgl::blVertexAttrib3fvARB && bgl::blGetVertexAttribdvARB) { - EnableExtension(_GL_ARB_vertex_program); - RAS_EXT_support._ARB_vertex_program = 1; - if (doDebugMessages) - std::cout << "Enabled GL_ARB_vertex_program" << std::endl; - } else { - std::cout << "ERROR: GL_ARB_vertex_program implementation is broken!" << std::endl; - } - } -#endif - - -#ifdef GL_ARB_depth_texture - if (QueryExtension("GL_ARB_depth_texture")) - { - EnableExtension(_GL_ARB_depth_texture); - RAS_EXT_support._ARB_depth_texture = 1; - if (doDebugMessages) - { - std::cout << "Detected GL_ARB_depth_texture" << std::endl; - } - } -#endif -/* -#ifdef GL_EXT_compiled_vertex_array - if (QueryExtension("GL_EXT_compiled_vertex_array")) - { - blLockArraysEXT = reinterpret_cast(bglGetProcAddress((const GLubyte *) "glLockArraysEXT")); - blUnlockArraysEXT = reinterpret_cast(bglGetProcAddress((const GLubyte *) "glUnlockArraysEXT")); - if (blLockArraysEXT && blUnlockArraysEXT) { - EnableExtension(_GL_EXT_compiled_vertex_array); - RAS_EXT_support._EXT_compiled_vertex_array = 1; - if (doDebugMessages) - std::cout << "Enabled GL_EXT_compiled_vertex_array" << std::endl; - } else { - std::cout << "ERROR: GL_EXT_compiled_vertex_array implementation is broken!" << std::endl; - } - } -#endif -*/ - if (QueryExtension("GL_EXT_separate_specular_color")) - { - EnableExtension(_GL_EXT_separate_specular_color); - if (doDebugMessages) - std::cout << "Detected GL_EXT_separate_specular_color" << std::endl; - } - - doDebugMessages = false; -} +} // namespace bgl diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_GLExtensionManager.h b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_GLExtensionManager.h index 3e24ee204a1..2265becbdad 100644 --- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_GLExtensionManager.h +++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_GLExtensionManager.h @@ -29,513 +29,14 @@ #ifndef __RAS_GLEXTENSIONMANAGER_H__ #define __RAS_GLEXTENSIONMANAGER_H__ +#include "GL/glew.h" -#ifdef WIN32 -# include -# include +/* Note: this used to have a lot more code, but now extension handling + * is done by GLEW, so it does mostly debug stuff */ -#elif defined(__APPLE__) -# define GL_GLEXT_LEGACY 1 -# include -# include - -#else /* UNIX */ -# define __glext_h_ -# include -# include -# undef GL_ARB_multitexture // (ubuntu) -# undef __glext_h_ -#endif - -#ifdef WITH_GLEXT -#ifdef WIN32 -# include -#elif defined(__APPLE__) -# include "mac_compat_glext.h" -# include -#else -# include -#endif -#endif - -#ifdef __sgi -# undef GL_ARB_vertex_program -#endif - -#include "EXT_separate_specular_color.h" -#include "ARB_multitexture.h" namespace bgl { - /** - * This is a list of all registered OpenGL extensions. - * It is available from: - * http://oss.sgi.com/projects/ogl-sample/registry/ - */ - typedef enum { - /* ARB Extensions */ - _GL_ARB_imaging, - _GL_ARB_multitexture , - _GLX_ARB_get_proc_address , - _GL_ARB_transpose_matrix , - _WGL_ARB_buffer_region , - _GL_ARB_multisample , - _GL_ARB_texture_env_add , - _GL_ARB_texture_cube_map , - _WGL_ARB_extensions_string , - _WGL_ARB_pixel_format , - _WGL_ARB_make_current_read , - _WGL_ARB_pbuffer , - _GL_ARB_texture_compression , - _GL_ARB_texture_border_clamp , - _GL_ARB_point_parameters , - _GL_ARB_vertex_blend , - _GL_ARB_matrix_palette , - _GL_ARB_texture_env_combine , - _GL_ARB_texture_env_crossbar , - _GL_ARB_texture_env_dot3 , - _WGL_ARB_render_texture , - _GL_ARB_texture_mirrored_repeat , - _GL_ARB_depth_texture , - _GL_ARB_shadow , - _GL_ARB_shadow_ambient , - _GL_ARB_window_pos , - _GL_ARB_vertex_program , - _GL_ARB_fragment_program , - _GL_ARB_vertex_buffer_object , - _GL_ARB_occlusion_query , - _GL_ARB_shader_objects , - _GL_ARB_vertex_shader , - _GL_ARB_fragment_shader , - _GL_ARB_shading_language_100 , - _GL_ARB_texture_non_power_of_two , - _GL_ARB_point_sprite , - _GL_ARB_fragment_program_shadow , - - /* Non ARB Extensions */ - _GL_EXT_abgr , - _GL_EXT_blend_color , - _GL_EXT_polygon_offset , - _GL_EXT_texture , - _GL_EXT_texture3D , - _GL_SGIS_texture_filter4 , - _GL_EXT_subtexture , - _GL_EXT_copy_texture , - _GL_EXT_histogram , - _GL_EXT_convolution , - _GL_SGI_color_matrix , - _GL_SGI_color_table , - _GL_SGIS_pixel_texture , - _GL_SGIS_texture4D , - _GL_SGI_texture_color_table , - _GL_EXT_cmyka , - _GL_EXT_texture_object , - _GL_SGIS_detail_texture , - _GL_SGIS_sharpen_texture , - _GL_EXT_packed_pixels , - _GL_SGIS_texture_lod , - _GL_SGIS_multisample , - _GL_EXT_rescale_normal , - _GLX_EXT_visual_info , - _GL_EXT_vertex_array , - _GL_EXT_misc_attribute , - _GL_SGIS_generate_mipmap , - _GL_SGIX_clipmap , - _GL_SGIX_shadow , - _GL_SGIS_texture_edge_clamp , - _GL_SGIS_texture_border_clamp , - _GL_EXT_blend_minmax , - _GL_EXT_blend_subtract , - _GL_EXT_blend_logic_op , - _GLX_SGI_swap_control , - _GLX_SGI_video_sync , - _GLX_SGI_make_current_read , - _GLX_SGIX_video_source , - _GLX_EXT_visual_rating , - _GL_SGIX_interlace , - _GLX_EXT_import_context , - _GLX_SGIX_fbconfig , - _GLX_SGIX_pbuffer , - _GL_SGIS_texture_select , - _GL_SGIX_sprite , - _GL_SGIX_texture_multi_buffer , - _GL_EXT_point_parameters , - _GL_SGIX_instruments , - _GL_SGIX_texture_scale_bias , - _GL_SGIX_framezoom , - _GL_SGIX_tag_sample_buffer , - _GL_SGIX_reference_plane , - _GL_SGIX_flush_raster , - _GLX_SGI_cushion , - _GL_SGIX_depth_texture , - _GL_SGIS_fog_function , - _GL_SGIX_fog_offset , - _GL_HP_image_transform , - _GL_HP_convolution_border_modes , - _GL_SGIX_texture_add_env , - _GL_EXT_color_subtable , - _GLU_EXT_object_space_tess , - _GL_PGI_vertex_hints , - _GL_PGI_misc_hints , - _GL_EXT_paletted_texture , - _GL_EXT_clip_volume_hint , - _GL_SGIX_list_priority , - _GL_SGIX_ir_instrument1 , - _GLX_SGIX_video_resize , - _GL_SGIX_texture_lod_bias , - _GLU_SGI_filter4_parameters , - _GLX_SGIX_dm_buffer , - _GL_SGIX_shadow_ambient , - _GLX_SGIX_swap_group , - _GLX_SGIX_swap_barrier , - _GL_EXT_index_texture , - _GL_EXT_index_material , - _GL_EXT_index_func , - _GL_EXT_index_array_formats , - _GL_EXT_compiled_vertex_array , - _GL_EXT_cull_vertex , - _GLU_EXT_nurbs_tessellator , - _GL_SGIX_ycrcb , - _GL_EXT_fragment_lighting , - _GL_IBM_rasterpos_clip , - _GL_HP_texture_lighting , - _GL_EXT_draw_range_elements , - _GL_WIN_phong_shading , - _GL_WIN_specular_fog , - _GLX_SGIS_color_range , - _GL_EXT_light_texture , - _GL_SGIX_blend_alpha_minmax , - _GL_EXT_scene_marker , - _GL_SGIX_pixel_texture_bits , - _GL_EXT_bgra , - _GL_SGIX_async , - _GL_SGIX_async_pixel , - _GL_SGIX_async_histogram , - _GL_INTEL_texture_scissor , - _GL_INTEL_parallel_arrays , - _GL_HP_occlusion_test , - _GL_EXT_pixel_transform , - _GL_EXT_pixel_transform_color_table , - _GL_EXT_shared_texture_palette , - _GLX_SGIS_blended_overlay , - _GL_EXT_separate_specular_color , - _GL_EXT_secondary_color , - _GL_EXT_texture_env , - _GL_EXT_texture_perturb_normal , - _GL_EXT_multi_draw_arrays , - _GL_EXT_fog_coord , - _GL_REND_screen_coordinates , - _GL_EXT_coordinate_frame , - _GL_EXT_texture_env_combine , - _GL_APPLE_specular_vector , - _GL_SGIX_pixel_texture , - _GL_APPLE_transform_hint , - _GL_SUNX_constant_data , - _GL_SUN_global_alpha , - _GL_SUN_triangle_list , - _GL_SUN_vertex , - _WGL_EXT_display_color_table , - _WGL_EXT_extensions_string , - _WGL_EXT_make_current_read , - _WGL_EXT_pixel_format , - _WGL_EXT_pbuffer , - _WGL_EXT_swap_control , - _GL_EXT_blend_func_separate , - _GL_INGR_color_clamp , - _GL_INGR_interlace_read , - _GL_EXT_stencil_wrap , - _WGL_EXT_depth_float , - _GL_EXT_422_pixels , - _GL_NV_texgen_reflection , - _GL_SGIX_texture_range , - _GL_SUN_convolution_border_modes , - _GLX_SUN_get_transparent_index , - _GL_EXT_texture_env_add , - _GL_EXT_texture_lod_bias , - _GL_EXT_texture_filter_anisotropic , - _GL_EXT_vertex_weighting , - _GL_NV_light_max_exponent , - _GL_NV_vertex_array_range , - _GL_NV_register_combiners , - _GL_NV_fog_distance , - _GL_NV_texgen_emboss , - _GL_NV_blend_square , - _GL_NV_texture_env_combine4 , - _GL_MESA_resize_buffers , - _GL_MESA_window_pos , - _GL_EXT_texture_compression_s3tc , - _GL_IBM_cull_vertex , - _GL_IBM_multimode_draw_arrays , - _GL_IBM_vertex_array_lists , - _GL_3DFX_texture_compression_FXT1 , - _GL_3DFX_multisample , - _GL_3DFX_tbuffer , - _WGL_EXT_multisample , - _GL_SGIX_vertex_preclip , - _GL_SGIX_resample , - _GL_SGIS_texture_color_mask , - _GLX_MESA_copy_sub_buffer , - _GLX_MESA_pixmap_colormap , - _GLX_MESA_release_buffers , - _GLX_MESA_set_3dfx_mode , - _GL_EXT_texture_env_dot3 , - _GL_ATI_texture_mirror_once , - _GL_NV_fence , - _GL_IBM_static_data , - _GL_IBM_texture_mirrored_repeat , - _GL_NV_evaluators , - _GL_NV_packed_depth_stencil , - _GL_NV_register_combiners2 , - _GL_NV_texture_compression_vtc , - _GL_NV_texture_rectangle , - _GL_NV_texture_shader , - _GL_NV_texture_shader2 , - _GL_NV_vertex_array_range2 , - _GL_NV_vertex_program , - _GLX_SGIX_visual_select_group , - _GL_SGIX_texture_coordinate_clamp , - _GLX_OML_swap_method , - _GLX_OML_sync_control , - _GL_OML_interlace , - _GL_OML_subsample , - _GL_OML_resample , - _WGL_OML_sync_control , - _GL_NV_copy_depth_to_color , - _GL_ATI_envmap_bumpmap , - _GL_ATI_fragment_shader , - _GL_ATI_pn_triangles , - _GL_ATI_vertex_array_object , - _GL_EXT_vertex_shader , - _GL_ATI_vertex_streams , - _WGL_I3D_digital_video_control , - _WGL_I3D_gamma , - _WGL_I3D_genlock , - _WGL_I3D_image_buffer , - _WGL_I3D_swap_frame_lock , - _WGL_I3D_swap_frame_usage , - _GL_ATI_element_array , - _GL_SUN_mesh_array , - _GL_SUN_slice_accum , - _GL_NV_multisample_filter_hint , - _GL_NV_depth_clamp , - _GL_NV_occlusion_query , - _GL_NV_point_sprite , - _WGL_NV_render_depth_texture , - _WGL_NV_render_texture_rectangle , - _GL_NV_texture_shader3 , - _GL_NV_vertex_program1_1 , - _GL_EXT_shadow_funcs , - _GL_EXT_stencil_two_side , - _GL_ATI_text_fragment_shader , - _GL_APPLE_client_storage , - _GL_APPLE_element_array , - _GL_APPLE_fence , - _GL_APPLE_vertex_array_object , - _GL_APPLE_vertex_array_range , - _GL_APPLE_ycbcr_422 , - _GL_S3_s3tc , - _GL_ATI_draw_buffers , - _WGL_ATI_pixel_format_float , - _GL_ATI_texture_env_combine3 , - _GL_ATI_texture_float , - _GL_NV_float_buffer , - _GL_NV_fragment_program , - _GL_NV_half_float , - _GL_NV_pixel_data_range , - _GL_NV_primitive_restart , - _GL_NV_texture_expand_normal , - _GL_NV_vertex_program2 , - _GL_ATI_map_object_buffer , - _GL_ATI_separate_stencil , - _GL_ATI_vertex_attrib_array_object , - _GL_OES_byte_coordinates , - _GL_OES_fixed_point , - _GL_OES_single_precision , - _GL_OES_compressed_paletted_texture , - _GL_OES_read_format , - _GL_OES_query_matrix , - _GL_EXT_depth_bounds_test , - _GL_EXT_texture_mirror_clamp , - _GL_EXT_blend_equation_separate , - _GL_MESA_pack_invert , - _GL_MESA_ycbcr_texture, - - /* Finished */ - _BGL_TEST, - NUM_EXTENSIONS - } ExtensionName; - - /** - * Checks at runtime whether OpenGL supports the named extension. - * Returns true if OpenGL supports the given extension. - * - * @param name The extension name to check. - */ - bool QueryExtension(ExtensionName name); - /** - * Checks the OpenGL version. - * Returns true if OpenGL is at least the given version. - * - * @param major The major version required - * @param minor The minor version required - */ - bool QueryVersion(int major, int minor); - /** - * This will dynamically link all runtime supported extensions into - * the binary. - * - * @param debug Enable debug printing. This will print debugging info - * when extensions are loaded. - */ - void InitExtensions(int debug); - -#if defined(PFNGLPNTRIANGLESIATIPROC) -extern PFNGLPNTRIANGLESIATIPROC blPNTrianglesiATI; -extern PFNGLPNTRIANGLESFATIPROC blPNTrianglesfATI; -#endif - - -// quick runtime checks -typedef struct BL_EXTInfo -{ - BL_EXTInfo(): - _ARB_multitexture(0), - _ARB_texture_env_combine(0), - _EXT_blend_color(0), - _ARB_texture_cube_map(0), - _ARB_shader_objects(0), - _ARB_vertex_shader(0), - _ARB_fragment_shader(0), - _EXT_texture3D(0), - _ARB_vertex_program(0), - _ARB_depth_texture(0), - _EXT_compiled_vertex_array(0) - { - // - } - bool _ARB_multitexture; - bool _ARB_texture_env_combine; - bool _EXT_blend_color; - bool _ARB_texture_cube_map; - bool _ARB_shader_objects; - bool _ARB_vertex_shader; - bool _ARB_fragment_shader; - bool _EXT_texture3D; - bool _ARB_vertex_program; - bool _ARB_depth_texture; - bool _EXT_compiled_vertex_array; -}BL_EXTInfo; - -extern BL_EXTInfo RAS_EXT_support; - -#ifdef GL_ARB_multitexture // defined in glext.h now... -extern int max_texture_units; -extern PFNGLACTIVETEXTUREARBPROC blActiveTextureARB; -extern PFNGLCLIENTACTIVETEXTUREARBPROC blClientActiveTextureARB; -extern PFNGLMULTITEXCOORD1DARBPROC blMultiTexCoord1dARB; -extern PFNGLMULTITEXCOORD1DVARBPROC blMultiTexCoord1dvARB; -extern PFNGLMULTITEXCOORD1FARBPROC blMultiTexCoord1fARB; -extern PFNGLMULTITEXCOORD1FVARBPROC blMultiTexCoord1fvARB; -extern PFNGLMULTITEXCOORD1IARBPROC blMultiTexCoord1iARB; -extern PFNGLMULTITEXCOORD1IVARBPROC blMultiTexCoord1ivARB; -extern PFNGLMULTITEXCOORD1SARBPROC blMultiTexCoord1sARB; -extern PFNGLMULTITEXCOORD1SVARBPROC blMultiTexCoord1svARB; -extern PFNGLMULTITEXCOORD2DARBPROC blMultiTexCoord2dARB; -extern PFNGLMULTITEXCOORD2DVARBPROC blMultiTexCoord2dvARB; -extern PFNGLMULTITEXCOORD2FARBPROC blMultiTexCoord2fARB; -extern PFNGLMULTITEXCOORD2FVARBPROC blMultiTexCoord2fvARB; -extern PFNGLMULTITEXCOORD2IARBPROC blMultiTexCoord2iARB; -extern PFNGLMULTITEXCOORD2IVARBPROC blMultiTexCoord2ivARB; -extern PFNGLMULTITEXCOORD2SARBPROC blMultiTexCoord2sARB; -extern PFNGLMULTITEXCOORD2SVARBPROC blMultiTexCoord2svARB; -extern PFNGLMULTITEXCOORD3DARBPROC blMultiTexCoord3dARB; -extern PFNGLMULTITEXCOORD3DVARBPROC blMultiTexCoord3dvARB; -extern PFNGLMULTITEXCOORD3FARBPROC blMultiTexCoord3fARB; -extern PFNGLMULTITEXCOORD3FVARBPROC blMultiTexCoord3fvARB; -extern PFNGLMULTITEXCOORD3IARBPROC blMultiTexCoord3iARB; -extern PFNGLMULTITEXCOORD3IVARBPROC blMultiTexCoord3ivARB; -extern PFNGLMULTITEXCOORD3SARBPROC blMultiTexCoord3sARB; -extern PFNGLMULTITEXCOORD3SVARBPROC blMultiTexCoord3svARB; -extern PFNGLMULTITEXCOORD4DARBPROC blMultiTexCoord4dARB; -extern PFNGLMULTITEXCOORD4DVARBPROC blMultiTexCoord4dvARB; -extern PFNGLMULTITEXCOORD4FARBPROC blMultiTexCoord4fARB; -extern PFNGLMULTITEXCOORD4FVARBPROC blMultiTexCoord4fvARB; -extern PFNGLMULTITEXCOORD4IARBPROC blMultiTexCoord4iARB; -extern PFNGLMULTITEXCOORD4IVARBPROC blMultiTexCoord4ivARB; -extern PFNGLMULTITEXCOORD4SARBPROC blMultiTexCoord4sARB; -extern PFNGLMULTITEXCOORD4SVARBPROC blMultiTexCoord4svARB; -#endif - - -#ifdef GL_ARB_shader_objects -extern PFNGLDELETEOBJECTARBPROC blDeleteObjectARB; -extern PFNGLGETHANDLEARBPROC blGetHandleARB; -extern PFNGLDETACHOBJECTARBPROC blDetachObjectARB; -extern PFNGLCREATESHADEROBJECTARBPROC blCreateShaderObjectARB; -extern PFNGLSHADERSOURCEARBPROC blShaderSourceARB; -extern PFNGLCOMPILESHADERARBPROC blCompileShaderARB; -extern PFNGLCREATEPROGRAMOBJECTARBPROC blCreateProgramObjectARB; -extern PFNGLATTACHOBJECTARBPROC blAttachObjectARB; -extern PFNGLLINKPROGRAMARBPROC blLinkProgramARB; -extern PFNGLUSEPROGRAMOBJECTARBPROC blUseProgramObjectARB; -extern PFNGLVALIDATEPROGRAMARBPROC blValidateProgramARB; -extern PFNGLUNIFORM1FARBPROC blUniform1fARB; -extern PFNGLUNIFORM2FARBPROC blUniform2fARB; -extern PFNGLUNIFORM3FARBPROC blUniform3fARB; -extern PFNGLUNIFORM4FARBPROC blUniform4fARB; -extern PFNGLUNIFORM1IARBPROC blUniform1iARB; -extern PFNGLUNIFORM2IARBPROC blUniform2iARB; -extern PFNGLUNIFORM3IARBPROC blUniform3iARB; -extern PFNGLUNIFORM4IARBPROC blUniform4iARB; -extern PFNGLUNIFORM1FVARBPROC blUniform1fvARB; -extern PFNGLUNIFORM2FVARBPROC blUniform2fvARB; -extern PFNGLUNIFORM3FVARBPROC blUniform3fvARB; -extern PFNGLUNIFORM4FVARBPROC blUniform4fvARB; -extern PFNGLUNIFORM1IVARBPROC blUniform1ivARB; -extern PFNGLUNIFORM2IVARBPROC blUniform2ivARB; -extern PFNGLUNIFORM3IVARBPROC blUniform3ivARB; -extern PFNGLUNIFORM4IVARBPROC blUniform4ivARB; -extern PFNGLUNIFORMMATRIX2FVARBPROC blUniformMatrix2fvARB; -extern PFNGLUNIFORMMATRIX3FVARBPROC blUniformMatrix3fvARB; -extern PFNGLUNIFORMMATRIX4FVARBPROC blUniformMatrix4fvARB; -extern PFNGLGETOBJECTPARAMETERFVARBPROC blGetObjectParameterfvARB; -extern PFNGLGETOBJECTPARAMETERIVARBPROC blGetObjectParameterivARB; -extern PFNGLGETINFOLOGARBPROC blGetInfoLogARB; -extern PFNGLGETATTACHEDOBJECTSARBPROC blGetAttachedObjectsARB; -extern PFNGLGETUNIFORMLOCATIONARBPROC blGetUniformLocationARB; -extern PFNGLGETACTIVEUNIFORMARBPROC blGetActiveUniformARB; -extern PFNGLGETUNIFORMFVARBPROC blGetUniformfvARB; -extern PFNGLGETUNIFORMIVARBPROC blGetUniformivARB; -extern PFNGLGETSHADERSOURCEARBPROC blGetShaderSourceARB; -#endif - -#ifdef GL_ARB_vertex_shader -extern PFNGLBINDATTRIBLOCATIONARBPROC blBindAttribLocationARB; -extern PFNGLGETACTIVEATTRIBARBPROC blGetActiveAttribARB; -extern PFNGLGETATTRIBLOCATIONARBPROC blGetAttribLocationARB; -#endif - -#ifdef GL_ARB_vertex_program -extern PFNGLVERTEXATTRIB1FARBPROC blVertexAttrib1fARB; -extern PFNGLVERTEXATTRIB1FVARBPROC blVertexAttrib1fvARB; -extern PFNGLVERTEXATTRIB2FARBPROC blVertexAttrib2fARB; -extern PFNGLVERTEXATTRIB2FVARBPROC blVertexAttrib2fvARB; -extern PFNGLVERTEXATTRIB3FARBPROC blVertexAttrib3fARB; -extern PFNGLVERTEXATTRIB3FVARBPROC blVertexAttrib3fvARB; -extern PFNGLVERTEXATTRIB4FARBPROC blVertexAttrib4fARB; -extern PFNGLVERTEXATTRIB4FVARBPROC blVertexAttrib4fvARB; -extern PFNGLGETPROGRAMSTRINGARBPROC blGetProgramStringARB; -extern PFNGLGETVERTEXATTRIBDVARBPROC blGetVertexAttribdvARB; -extern PFNGLGETVERTEXATTRIBFVARBPROC blGetVertexAttribfvARB; -extern PFNGLGETVERTEXATTRIBIVARBPROC blGetVertexAttribivARB; -#endif - -/* -#ifdef GL_EXT_compiled_vertex_array -extern PFNGLLOCKARRAYSEXTPROC blLockArraysEXT; -extern PFNGLUNLOCKARRAYSEXTPROC blUnlockArraysEXT; -#endif -*/ + void InitExtensions(bool debug); } /* namespace bgl */ - #endif /* __RAS_GLEXTENSIONMANAGER_H__ */ diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_ListRasterizer.cpp b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_ListRasterizer.cpp index afa98fdb274..39080b80492 100644 --- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_ListRasterizer.cpp +++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_ListRasterizer.cpp @@ -6,15 +6,10 @@ #ifdef WIN32 #include #endif // WIN32 -#ifdef __APPLE__ -#define GL_GLEXT_LEGACY 1 -#include -#else -#include -#endif + +#include "GL/glew.h" #include "RAS_TexVert.h" -#include "RAS_GLExtensionManager.h" #include "MT_assert.h" //#ifndef NDEBUG @@ -27,8 +22,8 @@ RAS_ListSlot::RAS_ListSlot(RAS_ListRasterizer* rasty) : KX_ListSlot(), - m_flag(LIST_MODIFY|LIST_CREATE), m_list(0), + m_flag(LIST_MODIFY|LIST_CREATE), m_rasty(rasty) { } @@ -176,7 +171,7 @@ void RAS_ListRasterizer::IndexPrimitives( RAS_ListSlot* localSlot =0; // useObjectColor(are we updating every frame?) - if(!useObjectColor) { + if(!useObjectColor && slot) { localSlot = FindOrAdd(vertexarrays, slot); localSlot->DrawList(); if(localSlot->End()) { @@ -203,7 +198,7 @@ void RAS_ListRasterizer::IndexPrimitives( ); } - if(!useObjectColor) { + if(!useObjectColor && slot) { localSlot->EndList(); *slot = localSlot; } @@ -223,7 +218,7 @@ void RAS_ListRasterizer::IndexPrimitivesMulti( RAS_ListSlot* localSlot =0; // useObjectColor(are we updating every frame?) - if(!useObjectColor) { + if(!useObjectColor && slot) { localSlot = FindOrAdd(vertexarrays, slot); localSlot->DrawList(); @@ -251,7 +246,7 @@ void RAS_ListRasterizer::IndexPrimitivesMulti( ); } - if(!useObjectColor) { + if(!useObjectColor && slot) { localSlot->EndList(); *slot = localSlot; } diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp index f99121e5b7c..d3c0426de86 100644 --- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp +++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp @@ -31,33 +31,13 @@ #include "RAS_OpenGLRasterizer.h" -#ifdef HAVE_CONFIG_H -#include -#endif - -#ifdef WIN32 -#include -#endif // WIN32 -#ifdef __APPLE__ -#define GL_GLEXT_LEGACY 1 -#include -#include -#else -#include -#if defined(__sun__) && !defined(__sparc__) -#include -#else -#include -#endif -#endif +#include "GL/glew.h" #include "RAS_Rect.h" #include "RAS_TexVert.h" #include "MT_CmMatrix4x4.h" #include "RAS_IRenderTools.h" // rendering text -#include "RAS_GLExtensionManager.h" - /** * 32x32 bit masks for vinterlace stereo mode */ @@ -83,10 +63,11 @@ RAS_OpenGLRasterizer::RAS_OpenGLRasterizer(RAS_ICanvas* canvas) m_focallength(0.0), m_setfocallength(false), m_noOfScanlines(32), - m_useTang(false), - m_materialCachingInfo(0), m_motionblur(0), - m_motionblurvalue(-1.0) + m_motionblurvalue(-1.0), + m_texco_num(0), + m_attrib_num(0), + m_materialCachingInfo(0) { m_viewmatrix.Identity(); @@ -335,7 +316,7 @@ void RAS_OpenGLRasterizer::Exit() glDisable(GL_POLYGON_STIPPLE); glDisable(GL_LIGHTING); - if (bgl::QueryExtension(bgl::_GL_EXT_separate_specular_color) || bgl::QueryVersion(1, 2)) + if (GLEW_EXT_separate_specular_color || GLEW_VERSION_1_2) glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SINGLE_COLOR); EndFrame(); @@ -802,277 +783,6 @@ void RAS_OpenGLRasterizer::IndexPrimitives(const vecVertexArray & vertexarrays, } -void RAS_OpenGLRasterizer::IndexPrimitives_Ex(const vecVertexArray & vertexarrays, - const vecIndexArrays & indexarrays, - int mode, - class RAS_IPolyMaterial* polymat, - class RAS_IRenderTools* rendertools, - bool useObjectColor, - const MT_Vector4& rgbacolor - ) -{ - bool recalc; - GLenum drawmode; - switch (mode) - { - case 0: - drawmode = GL_TRIANGLES; - break; - case 1: - drawmode = GL_LINES; - break; - case 2: - drawmode = GL_QUADS; - break; - default: - drawmode = GL_LINES; - break; - } - - const RAS_TexVert* vertexarray ; - unsigned int numindices,vt; - - for (vt=0;vt RAS_MAX_TEXCO) + m_texco_num = RAS_MAX_TEXCO; +} + +void RAS_OpenGLRasterizer::SetAttribNum(int num) +{ + m_attrib_num = num; + if(m_attrib_num > RAS_MAX_ATTRIB) + m_attrib_num = RAS_MAX_ATTRIB; +} + +void RAS_OpenGLRasterizer::SetTexCoord(TexCoGen coords, int unit) { // this changes from material to material - if(unit < RAS_MAX) + if(unit < RAS_MAX_TEXCO) m_texco[unit] = coords; } -void RAS_OpenGLRasterizer::SetAttrib(int type) +void RAS_OpenGLRasterizer::SetAttrib(TexCoGen coords, int unit) { - if(type == RAS_TEXTANGENT) m_useTang=true; + // this changes from material to material + if(unit < RAS_MAX_ATTRIB) + m_attrib[unit] = coords; } -void RAS_OpenGLRasterizer::TexCoord(const RAS_TexVert &tv, int enabled) +void RAS_OpenGLRasterizer::TexCoord(const RAS_TexVert &tv) { -#if defined(GL_ARB_multitexture) && defined(WITH_GLEXT) - if (!getenv("WITHOUT_GLEXT")) { - if(bgl::RAS_EXT_support._ARB_multitexture) { - for(int unit=0; unitGetEnabled(); - - if (!numindices) - break; - - int vindex=0; - switch (mode) { - case 1: + glBegin(GL_QUADS); + vindex=0; + if (useObjectColor) { - glBegin(GL_LINES); - vindex=0; - for (unsigned int i=0;iGetEnabled(); - - if (!numindices) - continue; - - int vindex=0; - switch (mode) { - case 1: + glBegin(GL_TRIANGLES); + vindex=0; + if (useObjectColor) { - glBegin(GL_LINES); - vindex=0; - for (unsigned int i=0;i m_debugLines; - virtual void SetTexCoords(TexCoGen coords,int enabled); - virtual void SetAttrib(int type); - void TexCoord(const RAS_TexVert &tv, int unit); + virtual void SetTexCoordNum(int num); + virtual void SetAttribNum(int num); + virtual void SetTexCoord(TexCoGen coords, int unit); + virtual void SetAttrib(TexCoGen coords, int unit); + + void TexCoord(const RAS_TexVert &tv); virtual void GetViewMatrix(MT_Matrix4x4 &mat) const; void Tangent(const RAS_TexVert& v1, diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_VAOpenGLRasterizer.cpp b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_VAOpenGLRasterizer.cpp index ddfcc3f3f9d..67c72aacdcf 100644 --- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_VAOpenGLRasterizer.cpp +++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_VAOpenGLRasterizer.cpp @@ -32,34 +32,21 @@ #include "RAS_VAOpenGLRasterizer.h" #include -#ifdef WIN32 -#include -#endif // WIN32 -#ifdef __APPLE__ -#define GL_GLEXT_LEGACY 1 -#include -#else -#include -#endif +#include "GL/glew.h" #include "STR_String.h" #include "RAS_TexVert.h" #include "MT_CmMatrix4x4.h" #include "RAS_IRenderTools.h" // rendering text - -#include "RAS_GLExtensionManager.h" - -using namespace bgl; - RAS_VAOpenGLRasterizer::RAS_VAOpenGLRasterizer(RAS_ICanvas* canvas, bool lock) : RAS_OpenGLRasterizer(canvas), - m_Lock(lock && RAS_EXT_support._EXT_compiled_vertex_array) + m_Lock(lock && GLEW_EXT_compiled_vertex_array), + m_last_texco_num(0), + m_last_attrib_num(0) { } - - RAS_VAOpenGLRasterizer::~RAS_VAOpenGLRasterizer() { } @@ -82,53 +69,36 @@ bool RAS_VAOpenGLRasterizer::Init(void) return result; } - - void RAS_VAOpenGLRasterizer::SetDrawingMode(int drawingmode) { m_drawingmode = drawingmode; - switch (m_drawingmode) + switch (m_drawingmode) { - case KX_BOUNDINGBOX: - { - } - case KX_WIREFRAME: - { + case KX_BOUNDINGBOX: + case KX_WIREFRAME: glDisable (GL_CULL_FACE); break; - } - case KX_TEXTURED: - { - } - case KX_SHADED: - { + case KX_TEXTURED: + case KX_SHADED: glEnableClientState(GL_COLOR_ARRAY); - } - case KX_SOLID: - { + case KX_SOLID: + break; + default: break; - } - default: - { - } } } - - void RAS_VAOpenGLRasterizer::Exit() { glDisableClientState(GL_VERTEX_ARRAY); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); glDisableClientState(GL_COLOR_ARRAY); glDisableClientState(GL_NORMAL_ARRAY); + EnableTextures(false); RAS_OpenGLRasterizer::Exit(); } - - void RAS_VAOpenGLRasterizer::IndexPrimitives( const vecVertexArray& vertexarrays, const vecIndexArrays & indexarrays, int mode, @@ -142,24 +112,16 @@ void RAS_VAOpenGLRasterizer::IndexPrimitives( const vecVertexArray& vertexarrays GLenum drawmode; switch (mode) { - case 0: - { - drawmode = GL_TRIANGLES; - break; - } - case 2: - { - drawmode = GL_QUADS; - break; - } - case 1: //lines - { - } - default: - { - drawmode = GL_LINES; - break; - } + case 0: + drawmode = GL_TRIANGLES; + break; + case 2: + drawmode = GL_QUADS; + break; + case 1: //lines + default: + drawmode = GL_LINES; + break; } const RAS_TexVert* vertexarray; unsigned int numindices, vt; @@ -208,7 +170,6 @@ void RAS_VAOpenGLRasterizer::IndexPrimitives( const vecVertexArray& vertexarrays } } - void RAS_VAOpenGLRasterizer::IndexPrimitivesMulti( const vecVertexArray& vertexarrays, const vecIndexArrays & indexarrays, int mode, @@ -222,28 +183,19 @@ void RAS_VAOpenGLRasterizer::IndexPrimitivesMulti( const vecVertexArray& vertexa GLenum drawmode; switch (mode) { - case 0: - { - drawmode = GL_TRIANGLES; - break; - } - case 2: - { - drawmode = GL_QUADS; - break; - } - case 1: //lines - { - } - default: - { - drawmode = GL_LINES; - break; - } + case 0: + drawmode = GL_TRIANGLES; + break; + case 2: + drawmode = GL_QUADS; + break; + case 1: //lines + default: + drawmode = GL_LINES; + break; } const RAS_TexVert* vertexarray; unsigned int numindices, vt; - const unsigned int enabled = polymat->GetEnabled(); if (drawmode != GL_LINES) { @@ -251,7 +203,8 @@ void RAS_VAOpenGLRasterizer::IndexPrimitivesMulti( const vecVertexArray& vertexa { glDisableClientState(GL_COLOR_ARRAY); glColor4d(rgbacolor[0], rgbacolor[1], rgbacolor[2], rgbacolor[3]); - } else + } + else { glColor4d(0,0,0,1.0); glEnableClientState(GL_COLOR_ARRAY); @@ -271,11 +224,10 @@ void RAS_VAOpenGLRasterizer::IndexPrimitivesMulti( const vecVertexArray& vertexa if (!numindices) continue; - - glVertexPointer(3,GL_FLOAT,vtxstride,vertexarray->getLocalXYZ()); - TexCoordPtr(vertexarray, enabled); - //glTexCoordPointer(2,GL_FLOAT,vtxstride,vertexarray->getUV1()); + glVertexPointer(3,GL_FLOAT,vtxstride,vertexarray->getLocalXYZ()); + TexCoordPtr(vertexarray); + glColorPointer(4,GL_UNSIGNED_BYTE,vtxstride,vertexarray->getRGBA()); glNormalPointer(GL_FLOAT,vtxstride,vertexarray->getNormal()); @@ -290,62 +242,146 @@ void RAS_VAOpenGLRasterizer::IndexPrimitivesMulti( const vecVertexArray& vertexa } } -void RAS_VAOpenGLRasterizer::TexCoordPtr(const RAS_TexVert *tv, int enabled) +void RAS_VAOpenGLRasterizer::TexCoordPtr(const RAS_TexVert *tv) { -#if defined(GL_ARB_multitexture) && defined(WITH_GLEXT) - if (!getenv("WITHOUT_GLEXT")) { - if(bgl::RAS_EXT_support._ARB_multitexture) - { - for(int unit=0; unitgetFlag() & TV_2NDUV && (int)tv->getUnit() == unit) { glEnableClientState(GL_TEXTURE_COORD_ARRAY); - if( tv->getFlag() & TV_2NDUV && tv->getUnit() == unit ) { - glTexCoordPointer(2, GL_FLOAT, sizeof(RAS_TexVert), tv->getUV2()); - continue; - } - switch(m_texco[unit]) - { - case RAS_TEXCO_DISABLE: - case RAS_TEXCO_OBJECT: - case RAS_TEXCO_GEN: - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - break; - case RAS_TEXCO_ORCO: - case RAS_TEXCO_GLOB: - glTexCoordPointer(3, GL_FLOAT, sizeof(RAS_TexVert),tv->getLocalXYZ()); - break; - case RAS_TEXCO_UV1: - glTexCoordPointer(2, GL_FLOAT, sizeof(RAS_TexVert),tv->getUV1()); - break; - case RAS_TEXCO_NORM: - glTexCoordPointer(3, GL_FLOAT, sizeof(RAS_TexVert),tv->getNormal()); - break; - case RAS_TEXTANGENT: - glTexCoordPointer(4, GL_FLOAT, sizeof(RAS_TexVert),tv->getTangent()); - break; - case RAS_TEXCO_UV2: - glTexCoordPointer(2, GL_FLOAT, sizeof(RAS_TexVert),tv->getUV2()); - break; - } + glTexCoordPointer(2, GL_FLOAT, sizeof(RAS_TexVert), tv->getUV2()); + continue; + } + switch(m_texco[unit]) + { + case RAS_TEXCO_ORCO: + case RAS_TEXCO_GLOB: + glTexCoordPointer(3, GL_FLOAT, sizeof(RAS_TexVert),tv->getLocalXYZ()); + break; + case RAS_TEXCO_UV1: + glTexCoordPointer(2, GL_FLOAT, sizeof(RAS_TexVert),tv->getUV1()); + break; + case RAS_TEXCO_NORM: + glTexCoordPointer(3, GL_FLOAT, sizeof(RAS_TexVert),tv->getNormal()); + break; + case RAS_TEXTANGENT: + glTexCoordPointer(4, GL_FLOAT, sizeof(RAS_TexVert),tv->getTangent()); + break; + case RAS_TEXCO_UV2: + glTexCoordPointer(2, GL_FLOAT, sizeof(RAS_TexVert),tv->getUV2()); + break; + default: + break; } } - -#ifdef GL_ARB_vertex_program - if(m_useTang && bgl::RAS_EXT_support._ARB_vertex_program) - bgl::blVertexAttrib4fvARB(1/*tangent*/, tv->getTangent()); -#endif } -#endif -} + if(GLEW_ARB_vertex_program) { + for(unit=0; unitgetLocalXYZ()); + break; + case RAS_TEXCO_UV1: + glVertexAttribPointer(unit, 2, GL_FLOAT, GL_FALSE, sizeof(RAS_TexVert), tv->getUV1()); + break; + case RAS_TEXCO_NORM: + glVertexAttribPointer(unit, 3, GL_FLOAT, GL_FALSE, sizeof(RAS_TexVert), tv->getNormal()); + break; + case RAS_TEXTANGENT: + glVertexAttribPointer(unit, 4, GL_FLOAT, GL_FALSE, sizeof(RAS_TexVert), tv->getTangent()); + break; + case RAS_TEXCO_UV2: + glVertexAttribPointer(unit, 2, GL_FLOAT, GL_FALSE, sizeof(RAS_TexVert), tv->getUV2()); + break; + default: + break; + } + } + } +} void RAS_VAOpenGLRasterizer::EnableTextures(bool enable) { - if (enable) - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - else - glDisableClientState(GL_TEXTURE_COORD_ARRAY); + TexCoGen *texco, *attrib; + int unit, texco_num, attrib_num; + + /* disable previously enabled texture coordinates and attributes. ideally + * this shouldn't be necessary .. */ + if(enable) + EnableTextures(false); + + /* we cache last texcoords and attribs to ensure we disable the ones that + * were actually last set */ + if(enable) { + texco = m_texco; + texco_num = m_texco_num; + attrib = m_attrib; + attrib_num = m_attrib_num; + + memcpy(m_last_texco, m_texco, sizeof(TexCoGen)*m_texco_num); + m_last_texco_num = m_texco_num; + memcpy(m_last_attrib, m_attrib, sizeof(TexCoGen)*m_attrib_num); + m_last_attrib_num = m_attrib_num; + } + else { + texco = m_last_texco; + texco_num = m_last_texco_num; + attrib = m_last_attrib; + attrib_num = m_last_attrib_num; + } + + if(GLEW_ARB_multitexture) { + for(unit=0; unit tmp -# Code can be copied & pasted from tmp to GL_ExtensionManager.cpp. -# -# glext.h is available here: http://oss.sgi.com/projects/ogl-sample/ABI/glext.h -# - -from sys import stdin -import string, re - -glext_h = string.split(stdin.read(), '\n') - -# These extensions have been incorporated into the core GL or been superceded. -# Code will not be generated for these extensions -blacklist = [ - "GL_EXT_multisample", - "GL_INGR_blend_func_separate", - "GL_SGIX_fragment_lighting", - "GL_SGIX_polynomial_ffd", - "GL_SGIS_point_parameters", - "GL_EXT_texture_object", - "GL_EXT_subtexture", - "GL_EXT_copy_texture", - "GL_EXT_vertex_array", - "GL_EXT_point_parameters", - "GL_EXT_blend_color", - "GL_EXT_polygon_offset", - "GL_EXT_texture"] - -# Only code for these extensions will be generated. Extensions on both the -# blacklist & whitelist will not have code generated. -# This list is from http://oss.sgi.com/projects/ogl-sample/registry/ at 14-Mar-04 -whitelist = [ - # ARB Extensions - "GL_ARB_multitexture", - "GLX_ARB_get_proc_address", - "GL_ARB_transpose_matrix", - "WGL_ARB_buffer_region", - "GL_ARB_multisample", - "GL_ARB_texture_env_add", - "GL_ARB_texture_cube_map", - "WGL_ARB_extensions_string", - "WGL_ARB_pixel_format", - "WGL_ARB_make_current_read", - "WGL_ARB_pbuffer", - "GL_ARB_texture_compression", - "GL_ARB_texture_border_clamp", - "GL_ARB_point_parameters", - "GL_ARB_vertex_blend", - "GL_ARB_matrix_palette", - "GL_ARB_texture_env_combine", - "GL_ARB_texture_env_crossbar", - "GL_ARB_texture_env_dot3", - "WGL_ARB_render_texture", - "GL_ARB_texture_mirrored_repeat", - "GL_ARB_depth_texture", - "GL_ARB_shadow", - "GL_ARB_shadow_ambient", - "GL_ARB_window_pos", - "GL_ARB_vertex_program", - "GL_ARB_fragment_program", - "GL_ARB_vertex_buffer_object", - "GL_ARB_occlusion_query", - "GL_ARB_shader_objects", - "GL_ARB_vertex_shader", - "GL_ARB_fragment_shader", - "GL_ARB_shading_language_100", - "GL_ARB_texture_non_power_of_two", - "GL_ARB_point_sprite", - "GL_ARB_fragment_program_shadow", - - # Non ARB Extensions - "GL_EXT_abgr", - "GL_EXT_blend_color", - "GL_EXT_polygon_offset", - "GL_EXT_texture", - "GL_EXT_texture3D", - "GL_SGIS_texture_filter4", - "GL_EXT_subtexture", - "GL_EXT_copy_texture", - "GL_EXT_histogram", - "GL_EXT_convolution", - "GL_SGI_color_matrix", - "GL_SGI_color_table", - "GL_SGIS_pixel_texture", - "GL_SGIS_texture4D", - "GL_SGI_texture_color_table", - "GL_EXT_cmyka", - "GL_EXT_texture_object", - "GL_SGIS_detail_texture", - "GL_SGIS_sharpen_texture", - "GL_EXT_packed_pixels", - "GL_SGIS_texture_lod", - "GL_SGIS_multisample", - "GL_EXT_rescale_normal", - "GLX_EXT_visual_info", - "GL_EXT_vertex_array", - "GL_EXT_misc_attribute", - "GL_SGIS_generate_mipmap", - "GL_SGIX_clipmap", - "GL_SGIX_shadow", - "GL_SGIS_texture_edge_clamp", - "GL_SGIS_texture_border_clamp", - "GL_EXT_blend_minmax", - "GL_EXT_blend_subtract", - "GL_EXT_blend_logic_op", - "GLX_SGI_swap_control", - "GLX_SGI_video_sync", - "GLX_SGI_make_current_read", - "GLX_SGIX_video_source", - "GLX_EXT_visual_rating", - "GL_SGIX_interlace", - "GLX_EXT_import_context", - "GLX_SGIX_fbconfig", - "GLX_SGIX_pbuffer", - "GL_SGIS_texture_select", - "GL_SGIX_sprite", - "GL_SGIX_texture_multi_buffer", - "GL_EXT_point_parameters", - "GL_SGIX_instruments", - "GL_SGIX_texture_scale_bias", - "GL_SGIX_framezoom", - "GL_SGIX_tag_sample_buffer", - "GL_SGIX_reference_plane", - "GL_SGIX_flush_raster", - "GLX_SGI_cushion", - "GL_SGIX_depth_texture", - "GL_SGIS_fog_function", - "GL_SGIX_fog_offset", - "GL_HP_image_transform", - "GL_HP_convolution_border_modes", - "GL_SGIX_texture_add_env", - "GL_EXT_color_subtable", - "GLU_EXT_object_space_tess", - "GL_PGI_vertex_hints", - "GL_PGI_misc_hints", - "GL_EXT_paletted_texture", - "GL_EXT_clip_volume_hint", - "GL_SGIX_list_priority", - "GL_SGIX_ir_instrument1", - "GLX_SGIX_video_resize", - "GL_SGIX_texture_lod_bias", - "GLU_SGI_filter4_parameters", - "GLX_SGIX_dm_buffer", - "GL_SGIX_shadow_ambient", - "GLX_SGIX_swap_group", - "GLX_SGIX_swap_barrier", - "GL_EXT_index_texture", - "GL_EXT_index_material", - "GL_EXT_index_func", - "GL_EXT_index_array_formats", - "GL_EXT_compiled_vertex_array", - "GL_EXT_cull_vertex", - "GLU_EXT_nurbs_tessellator", - "GL_SGIX_ycrcb", - "GL_EXT_fragment_lighting", - "GL_IBM_rasterpos_clip", - "GL_HP_texture_lighting", - "GL_EXT_draw_range_elements", - "GL_WIN_phong_shading", - "GL_WIN_specular_fog", - "GLX_SGIS_color_range", - "GL_EXT_light_texture", - "GL_SGIX_blend_alpha_minmax", - "GL_EXT_scene_marker", - "GL_SGIX_pixel_texture_bits", - "GL_EXT_bgra", - "GL_SGIX_async", - "GL_SGIX_async_pixel", - "GL_SGIX_async_histogram", - "GL_INTEL_texture_scissor", - "GL_INTEL_parallel_arrays", - "GL_HP_occlusion_test", - "GL_EXT_pixel_transform", - "GL_EXT_pixel_transform_color_table", - "GL_EXT_shared_texture_palette", - "GLX_SGIS_blended_overlay", - "GL_EXT_separate_specular_color", - "GL_EXT_secondary_color", - "GL_EXT_texture_env", - "GL_EXT_texture_perturb_normal", - "GL_EXT_multi_draw_arrays", - "GL_EXT_fog_coord", - "GL_REND_screen_coordinates", - "GL_EXT_coordinate_frame", - "GL_EXT_texture_env_combine", - "GL_APPLE_specular_vector", - "GL_SGIX_pixel_texture", - "GL_APPLE_transform_hint", - "GL_SUNX_constant_data", - "GL_SUN_global_alpha", - "GL_SUN_triangle_list", - "GL_SUN_vertex", - "WGL_EXT_display_color_table", - "WGL_EXT_extensions_string", - "WGL_EXT_make_current_read", - "WGL_EXT_pixel_format", - "WGL_EXT_pbuffer", - "WGL_EXT_swap_control", - "GL_EXT_blend_func_separate", - "GL_INGR_color_clamp", - "GL_INGR_interlace_read", - "GL_EXT_stencil_wrap", - "WGL_EXT_depth_float", - "GL_EXT_422_pixels", - "GL_NV_texgen_reflection", - "GL_SGIX_texture_range", - "GL_SUN_convolution_border_modes", - "GLX_SUN_get_transparent_index", - "GL_EXT_texture_env_add", - "GL_EXT_texture_lod_bias", - "GL_EXT_texture_filter_anisotropic", - "GL_EXT_vertex_weighting", - "GL_NV_light_max_exponent", - "GL_NV_vertex_array_range", - "GL_NV_register_combiners", - "GL_NV_fog_distance", - "GL_NV_texgen_emboss", - "GL_NV_blend_square", - "GL_NV_texture_env_combine4", - "GL_MESA_resize_buffers", - "GL_MESA_window_pos", - "GL_EXT_texture_compression_s3tc", - "GL_IBM_cull_vertex", - "GL_IBM_multimode_draw_arrays", - "GL_IBM_vertex_array_lists", - "GL_3DFX_texture_compression_FXT1", - "GL_3DFX_multisample", - "GL_3DFX_tbuffer", - "WGL_EXT_multisample", - "GL_SGIX_vertex_preclip", - "GL_SGIX_resample", - "GL_SGIS_texture_color_mask", - "GLX_MESA_copy_sub_buffer", - "GLX_MESA_pixmap_colormap", - "GLX_MESA_release_buffers", - "GLX_MESA_set_3dfx_mode", - "GL_EXT_texture_env_dot3", - "GL_ATI_texture_mirror_once", - "GL_NV_fence", - "GL_IBM_static_data", - "GL_IBM_texture_mirrored_repeat", - "GL_NV_evaluators", - "GL_NV_packed_depth_stencil", - "GL_NV_register_combiners2", - "GL_NV_texture_compression_vtc", - "GL_NV_texture_rectangle", - "GL_NV_texture_shader", - "GL_NV_texture_shader2", - "GL_NV_vertex_array_range2", - "GL_NV_vertex_program", - "GLX_SGIX_visual_select_group", - "GL_SGIX_texture_coordinate_clamp", - "GLX_OML_swap_method", - "GLX_OML_sync_control", - "GL_OML_interlace", - "GL_OML_subsample", - "GL_OML_resample", - "WGL_OML_sync_control", - "GL_NV_copy_depth_to_color", - "GL_ATI_envmap_bumpmap", - "GL_ATI_fragment_shader", - "GL_ATI_pn_triangles", - "GL_ATI_vertex_array_object", - "GL_EXT_vertex_shader", - "GL_ATI_vertex_streams", - "WGL_I3D_digital_video_control", - "WGL_I3D_gamma", - "WGL_I3D_genlock", - "WGL_I3D_image_buffer", - "WGL_I3D_swap_frame_lock", - "WGL_I3D_swap_frame_usage", - "GL_ATI_element_array", - "GL_SUN_mesh_array", - "GL_SUN_slice_accum", - "GL_NV_multisample_filter_hint", - "GL_NV_depth_clamp", - "GL_NV_occlusion_query", - "GL_NV_point_sprite", - "WGL_NV_render_depth_texture", - "WGL_NV_render_texture_rectangle", - "GL_NV_texture_shader3", - "GL_NV_vertex_program1_1", - "GL_EXT_shadow_funcs", - "GL_EXT_stencil_two_side", - "GL_ATI_text_fragment_shader", - "GL_APPLE_client_storage", - "GL_APPLE_element_array", - "GL_APPLE_fence", - "GL_APPLE_vertex_array_object", - "GL_APPLE_vertex_array_range", - "GL_APPLE_ycbcr_422", - "GL_S3_s3tc", - "GL_ATI_draw_buffers", - "WGL_ATI_pixel_format_float", - "GL_ATI_texture_env_combine3", - "GL_ATI_texture_float", - "GL_NV_float_buffer", - "GL_NV_fragment_program", - "GL_NV_half_float", - "GL_NV_pixel_data_range", - "GL_NV_primitive_restart", - "GL_NV_texture_expand_normal", - "GL_NV_vertex_program2", - "GL_ATI_map_object_buffer", - "GL_ATI_separate_stencil", - "GL_ATI_vertex_attrib_array_object", - "GL_OES_byte_coordinates", - "GL_OES_fixed_point", - "GL_OES_single_precision", - "GL_OES_compressed_paletted_texture", - "GL_OES_read_format", - "GL_OES_query_matrix", - "GL_EXT_depth_bounds_test", - "GL_EXT_texture_mirror_clamp", - "GL_EXT_blend_equation_separate", - "GL_MESA_pack_invert", - "GL_MESA_ycbcr_texture"] - -""" -Example code output: -#ifdef GL_EXT_compiled_vertex_array - if (QueryExtension("GL_EXT_compiled_vertex_array")) - { - glUnlockArraysEXT = reinterpret_cast(bglGetProcAddress((const GLubyte *) "glUnlockArraysEXT")); - glLockArraysEXT = reinterpret_cast(bglGetProcAddress((const GLubyte *) "glLockArraysEXT")); - if (glUnlockArraysEXT && glLockArraysEXT) - { - EnableExtension(_GL_EXT_compiled_vertex_array); - if (doDebugMessages) - std::cout << "Detected GL_EXT_compiled_vertex_array" << std::endl; - } else { - std::cout << "ERROR: GL_EXT_compiled_vertex_array implementation is broken!" << std::endl; - } - } -#endif -""" -def writeext(ext, fnlist): - if (find(blacklist, ext)): - return - if (len(fnlist) == 0): - # This extension has no functions to detect - don't need to wrap in - # #ifdef GL_extension names - print "\tif (QueryExtension(\"" + ext + "\"))" - print "\t{" - print "\t\tEnableExtension(_" + ext + ");" - print "\t\tif (doDebugMessages)" - print "\t\t\tstd::cout << \"Detected " + ext + "\" << std::endl;" - print "\t}" - print - return - print "#if defined(" + ext + ")" - print "\tif (QueryExtension(\"" + ext + "\"))" - print "\t{" - for fn in fnlist: - print "\t\t" + fn[0] + " = reinterpret_cast<" + fn[1] + ">(bglGetProcAddress((const GLubyte *) \"" + fn[0] + "\"));" - errcheck = "" - for fn in fnlist: - if (errcheck == ""): - errcheck = fn[0] - else: - errcheck = errcheck + " && " + fn[0] - print "\t\tif (" + errcheck + ") {" - print "\t\t\tEnableExtension(_" + ext + ");" - print "\t\t\tif (doDebugMessages)" - print "\t\t\t\tstd::cout << \"Enabled " + ext + "\" << std::endl;" - print "\t\t} else {" - print "\t\t\tstd::cout << \"ERROR: " + ext + " implementation is broken!\" << std::endl;" - print "\t\t}" - print "\t}" - print "#endif" - print - -""" -Example Output: -#if defined(GL_EXT_compiled_vertex_array) -PFNGLLOCKARRAYSEXTPROC glLockArraysEXT; -PFNGLUNLOCKARRAYSEXTPROC glUnlockArraysEXT; -#endif -""" -def writeproto(ext, fnlist): - if (find(blacklist, ext) or not find(whitelist, ext)): - return - print "#if defined(" + ext + ")" - for fn in fnlist: - print fn[1] + " " + fn[0] + ";" - print "#endif" - print - -""" -#ifdef GL_EXT_compiled_vertex_array -extern PFNGLLOCKARRAYSEXTPROC glLockArraysEXT; -extern PFNGLUNLOCKARRAYSEXTPROC glUnlockArraysEXT; -#endif -""" -def writeheader(ext, fnlisti): - if (find(blacklist, ext) or not find(whitelist, ext)): - return - print "#if defined(" + ext + ")" - for fn in fnlist: - print "extern " + fn[1] + " " + fn[0] + ";" - print "#endif" - print - -def find(l, x): - for i in l: - if (i == x): - return 1 - return 0 - - -# Write Prototypes -ext = "" -fns = [] -fnlist = [] -ifdef = 0 -for i in glext_h: - line = re.search('^#ifn?def', i) - if (line): - ifdef = ifdef + 1 - - line = re.search('^#ifndef (GL_.*)', i) - if (line): - if (not re.search('GL_VERSION.*', line.group(1)) and find(whitelist, line.group(1))): - ext = line.group(1) - - line = re.search('^#endif', i) - if (line): - ifdef = ifdef - 1 - if (ifdef == 0 and ext != ""): - writeproto(ext, fnlist) - ext = "" - fns = [] - fnlist = [] - if (ext != ""): - line = re.search('.* (gl.*) \(.*\);', i) - if (line): - fns += [line.group(1)] - line = re.search('.*PFN(.*)PROC.*', i) - if (line): - for j in fns: - if (string.lower(line.group(1)) == string.lower(j)): - fnlist += [(j, "PFN" + line.group(1) + "PROC")] - -# Write link code -ext = "" -fns = [] -fnlist = [] -ifdef = 0 -for i in glext_h: - line = re.search('^#ifn?def', i) - if (line): - ifdef = ifdef + 1 - - line = re.search('^#ifndef (GL_.*)', i) - if (line): - if (not re.search('GL_VERSION.*', line.group(1)) and find(whitelist, line.group(1))): - ext = line.group(1) - - line = re.search('^#endif', i) - if (line): - ifdef = ifdef - 1 - if (ifdef == 0 and ext != ""): - writeext(ext, fnlist) - ext = "" - fns = [] - fnlist = [] - if (ext != ""): - line = re.search('.* (gl.*) \(.*\);', i) - if (line): - fns += [line.group(1)] - line = re.search('.*PFN(.*)PROC.*', i) - if (line): - for j in fns: - if (string.lower(line.group(1)) == string.lower(j)): - fnlist += [(j, "PFN" + line.group(1) + "PROC")] - -# Write header code -ext = "" -fns = [] -fnlist = [] -ifdef = 0 -for i in glext_h: - line = re.search('^#ifn?def', i) - if (line): - ifdef = ifdef + 1 - - line = re.search('^#ifndef (GL_.*)', i) - if (line): - if (not re.search('GL_VERSION.*', line.group(1)) and find(whitelist, line.group(1))): - ext = line.group(1) - - line = re.search('^#endif', i) - if (line): - ifdef = ifdef - 1 - if (ifdef == 0 and ext != ""): - writeheader(ext, fnlist) - ext = "" - fns = [] - fnlist = [] - if (ext != ""): - line = re.search('.* (gl.*) \(.*\);', i) - if (line): - fns += [line.group(1)] - line = re.search('.*PFN(.*)PROC.*', i) - if (line): - for j in fns: - if (string.lower(line.group(1)) == string.lower(j)): - fnlist += [(j, "PFN" + line.group(1) + "PROC")] - -# Write Python link code -ext = "" -extensions = [] -fns = [] -defines = [] -ifdef = 0 -for i in glext_h: - line = re.search('^#ifn?def', i) - if (line): - ifdef = ifdef + 1 - - line = re.search('^#ifndef (GL_.*)', i) - if (line): - if (not re.search('GL_VERSION.*', line.group(1)) and find(whitelist, line.group(1))): - ext = line.group(1) - - line = re.search('^#endif', i) - if (line): - ifdef = ifdef - 1 - if (ifdef == 0 and ext != ""): - done = 0 - for e in range(len(extensions)): - if extensions[e][0] == ext: - extensions[e] = (ext, defines + extensions[e][1], fns + extensions[e][2]) - done = 1 - if not done: - extensions = extensions + [(ext, defines, fns)] - ext = "" - fns = [] - defines = [] - if (ext != ""): - line = re.search('#define +(GL.*) +(0x.*)', i) # #define GL_ONE_MINUS_CONSTANT_COLOR 0x8002 - if (line): - defines += [(line.group(1), line.group(2))] - - line = re.search('(.* )(gl.*)(\(.*\));', i) # GLAPI void APIENTRY glMultiTexCoord2f (GLenum, GLfloat, GLfloat); - if (line): - fns += [(line.group(1), line.group(2), line.group(3))] - -for ext in extensions: - if (find(blacklist, ext[0]) or not find(whitelist, ext[0])): - continue - print "#if defined(" + ext[0] + ")" - for fn in ext[2]: - line = re.search('gl(.*)', fn[1]) - # BGL_Wrap(2, RasterPos2f, void, (GLfloat, GLfloat)) - rtype = "" - for r in string.split(fn[0]): - if r != "GLAPI" and r != "APIENTRY": - rtype = rtype + " " + r - params = "" - for p in string.split(fn[2], ','): - pline = re.search('(.*) \*', p) - if (pline): - p = pline.group(1) + "P" - if params == "": - params = p - else: - params = params + "," + p - if not params[-1] == ")": - params = params + ")" - print "BGL_Wrap(" + str(len(string.split(fn[2], ','))) + ", " + line.group(1) + ",\t" + rtype + ",\t" + params + ")" - print "#endif" - print - -for ext in extensions: - if (find(blacklist, ext[0]) or not find(whitelist, ext[0])): - continue - print 'PyDict_SetItemString(dict, "' + ext[0] + '", PyInt_FromLong(_' + ext[0] + '))' - print "#if defined(" + ext[0] + ")" - print "if (bglQueryExtension(_" + ext[0] + ")) {" - if len(ext[2]) > 0: - for fn in ext[2]: - line = re.search('gl(.*)', fn[1]) - # MethodDef(Vertex3iv), - print " BGL_AddMethod(" + line.group(1) + ");" - print - - for define in ext[1]: - print " BGL_AddConst(" + define[0] + ");" - print - - print "}" - print "#endif" - print diff --git a/source/gameengine/Rasterizer/SConscript b/source/gameengine/Rasterizer/SConscript index ff79a5d97b8..f077833b850 100644 --- a/source/gameengine/Rasterizer/SConscript +++ b/source/gameengine/Rasterizer/SConscript @@ -7,7 +7,7 @@ if env['WITH_BF_GLEXT'] == 1: env['CPPFLAGS'].append('-DWITH_GLEXT') -incs = '. #source/kernel/gen_system #intern/string #intern/moto/include #source/gameengine/BlenderRoutines' +incs = '. #source/kernel/gen_system #intern/string #intern/moto/include #source/gameengine/BlenderRoutines #extern/glew/include' if env['OURPLATFORM']=='win32-vc': cflags = [] diff --git a/source/nan_definitions.mk b/source/nan_definitions.mk index e19d10dba64..9c1a28de999 100644 --- a/source/nan_definitions.mk +++ b/source/nan_definitions.mk @@ -98,6 +98,7 @@ endif export NAN_OPENNL ?= $(LCGDIR)/opennl export NAN_ELBEEM ?= $(LCGDIR)/elbeem export NAN_SUPERLU ?= $(LCGDIR)/superlu + export NAN_GLEW ?= $(LCGDIR)/glew ifeq ($(FREE_WINDOWS), true) export NAN_FTGL ?= $(LCGDIR)/gcc/ftgl export NAN_FFMPEG ?= $(LCGDIR)/gcc/ffmpeg From b4c123c275172eb4f8477ea90c3f68d61565483b Mon Sep 17 00:00:00 2001 From: Martin Poirier Date: Tue, 17 Jun 2008 21:17:11 +0000 Subject: [PATCH 218/246] [#14400] Crash on grab/move on axis when nothing selected (patch included) I used a different fix than the included patch, but that was a pretty nasty crasher (only crash on menu/toolbox, not hotkeys). --- source/blender/src/transform_constraints.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/source/blender/src/transform_constraints.c b/source/blender/src/transform_constraints.c index 769ebd2ea97..2d01c2303fc 100644 --- a/source/blender/src/transform_constraints.c +++ b/source/blender/src/transform_constraints.c @@ -550,6 +550,10 @@ void setUserConstraint(TransInfo *t, int mode, const char ftext[]) { void BIF_setLocalLockConstraint(char axis, char *text) { TransInfo *t = BIF_GetTransInfo(); + if (t->total == 0) { + return; + } + switch (axis) { case 'x': setLocalConstraint(t, (CON_AXIS1|CON_AXIS2), text); @@ -566,6 +570,10 @@ void BIF_setLocalLockConstraint(char axis, char *text) { void BIF_setLocalAxisConstraint(char axis, char *text) { TransInfo *t = BIF_GetTransInfo(); + if (t->total == 0) { + return; + } + switch (axis) { case 'X': setLocalConstraint(t, CON_AXIS0, text); @@ -584,6 +592,10 @@ void BIF_setSingleAxisConstraint(float vec[3], char *text) { TransInfo *t = BIF_GetTransInfo(); float space[3][3], v[3]; + if (t->total == 0) { + return; + } + VECCOPY(space[0], vec); v[0] = vec[2]; @@ -622,6 +634,10 @@ void BIF_setDualAxisConstraint(float vec1[3], float vec2[3], char *text) { TransInfo *t = BIF_GetTransInfo(); float space[3][3]; + if (t->total == 0) { + return; + } + VECCOPY(space[0], vec1); VECCOPY(space[1], vec2); Crossf(space[2], space[0], space[1]); From 2bece8dcb5104bc95149b0c40723f1dc855d6b29 Mon Sep 17 00:00:00 2001 From: Benoit Bolsee Date: Wed, 18 Jun 2008 06:46:49 +0000 Subject: [PATCH 219/246] BGE Patch: Add Shape Action support and update MSCV_7 project file for glew. Shape Action are now supported in the BGE. A new type of actuator "Shape Action" is available on mesh objects. It can be combined with Action actuator on parent armature. Only relative keys are supported. All the usual action options are available: type, blending, priority, Python API. Only actions with shape channels should be specified of course, otherwise the actuator has no effect. Shape action will still work after a mesh replacement provided that the new mesh has compatible shape keys. --- extern/glew/make/msvc_7_0/glew_vc7.vcproj | 146 ++++ extern/make/msvc_7_0/extern.sln | 65 ++ projectfiles_vc7/blender/blender.vcproj | 4 +- .../blenderhook/KX_blenderhook.vcproj | 4 +- .../gameengine/converter/KX_converter.vcproj | 12 + .../gameplayer/common/GP_common.vcproj | 4 +- .../gameplayer/ghost/GP_ghost.vcproj | 8 +- .../gameengine/ketsji/KX_ketsji.vcproj | 18 +- .../rasterizer/RAS_rasterizer.vcproj | 12 +- .../RAS_openglrasterizer.vcproj | 21 +- source/blender/blenkernel/BKE_action.h | 5 + source/blender/blenkernel/BKE_key.h | 11 + source/blender/blenkernel/intern/action.c | 7 +- source/blender/blenkernel/intern/key.c | 2 +- source/blender/blenkernel/intern/sca.c | 1 + source/blender/blenloader/intern/readfile.c | 8 + source/blender/blenloader/intern/writefile.c | 1 + source/blender/makesdna/DNA_actuator_types.h | 1 + source/blender/src/buttons_logic.c | 12 + .../Converter/BL_BlenderDataConversion.cpp | 37 +- .../Converter/BL_DeformableGameObject.cpp | 47 ++ .../Converter/BL_DeformableGameObject.h | 40 +- .../gameengine/Converter/BL_MeshDeformer.cpp | 2 +- source/gameengine/Converter/BL_MeshDeformer.h | 4 +- .../Converter/BL_ShapeActionActuator.cpp | 797 ++++++++++++++++++ .../Converter/BL_ShapeActionActuator.h | 133 +++ .../gameengine/Converter/BL_ShapeDeformer.cpp | 125 +++ .../gameengine/Converter/BL_ShapeDeformer.h | 93 ++ .../gameengine/Converter/BL_SkinDeformer.cpp | 50 +- source/gameengine/Converter/BL_SkinDeformer.h | 35 +- .../Converter/BL_SkinMeshObject.cpp | 58 ++ .../gameengine/Converter/BL_SkinMeshObject.h | 36 +- .../Converter/KX_ConvertActuators.cpp | 25 + source/gameengine/GameLogic/SCA_IObject.h | 2 +- source/gameengine/Ketsji/KX_GameObject.cpp | 1 + source/gameengine/Ketsji/KX_GameObject.h | 17 +- source/gameengine/Ketsji/KX_Scene.cpp | 128 +-- source/gameengine/Rasterizer/RAS_Deformer.h | 2 +- .../gameengine/Rasterizer/RAS_MeshObject.cpp | 5 +- source/gameengine/Rasterizer/RAS_MeshObject.h | 5 +- 40 files changed, 1824 insertions(+), 160 deletions(-) create mode 100644 extern/glew/make/msvc_7_0/glew_vc7.vcproj create mode 100644 source/gameengine/Converter/BL_ShapeActionActuator.cpp create mode 100644 source/gameengine/Converter/BL_ShapeActionActuator.h create mode 100644 source/gameengine/Converter/BL_ShapeDeformer.cpp create mode 100644 source/gameengine/Converter/BL_ShapeDeformer.h diff --git a/extern/glew/make/msvc_7_0/glew_vc7.vcproj b/extern/glew/make/msvc_7_0/glew_vc7.vcproj new file mode 100644 index 00000000000..a8141587350 --- /dev/null +++ b/extern/glew/make/msvc_7_0/glew_vc7.vcproj @@ -0,0 +1,146 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/extern/make/msvc_7_0/extern.sln b/extern/make/msvc_7_0/extern.sln index afc88ddda8e..e4bc550f503 100644 --- a/extern/make/msvc_7_0/extern.sln +++ b/extern/make/msvc_7_0/extern.sln @@ -8,6 +8,7 @@ EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "solid", "..\..\solid\make\msvc_7_0\solid.vcproj", "{D696C86B-0B53-4471-A50D-5B983A6FA4AD}" ProjectSection(ProjectDependencies) = postProject {6461F05D-4698-47AB-A8E8-1CA2ACC9948B} = {6461F05D-4698-47AB-A8E8-1CA2ACC9948B} + {BAC615B0-F1AF-418B-8D23-A10FD8870D6A} = {BAC615B0-F1AF-418B-8D23-A10FD8870D6A} {0112CAD5-3584-412A-A2E5-1315A00437B4} = {0112CAD5-3584-412A-A2E5-1315A00437B4} {B83C6BED-11EC-46C8-AFFA-121EEDE94373} = {B83C6BED-11EC-46C8-AFFA-121EEDE94373} {524264F4-DF21-4B79-847F-E7CA643ECD0B} = {524264F4-DF21-4B79-847F-E7CA643ECD0B} @@ -46,6 +47,10 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "bullet2", "..\..\bullet2\ma ProjectSection(ProjectDependencies) = postProject EndProjectSection EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "glew", "..\..\glew\make\msvc_7_0\glew_vc7.vcproj", "{BAC615B0-F1AF-418B-8D23-A10FD8870D6A}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject Global GlobalSection(SolutionConfiguration) = preSolution 3D Plugin Debug = 3D Plugin Debug @@ -54,6 +59,10 @@ Global Blender Release = Blender Release BlenderPlayer Debug = BlenderPlayer Debug BlenderPlayer Release = BlenderPlayer Release + Debug = Debug + Release = Release + EndGlobalSection + GlobalSection(ProjectDependencies) = postSolution EndGlobalSection GlobalSection(ProjectConfiguration) = postSolution {9C71A793-C177-4CAB-8EC5-923D500B39F8}.3D Plugin Debug.ActiveCfg = 3D Plugin Debug|Win32 @@ -68,6 +77,10 @@ Global {9C71A793-C177-4CAB-8EC5-923D500B39F8}.BlenderPlayer Debug.Build.0 = Blender Release|Win32 {9C71A793-C177-4CAB-8EC5-923D500B39F8}.BlenderPlayer Release.ActiveCfg = Blender Release|Win32 {9C71A793-C177-4CAB-8EC5-923D500B39F8}.BlenderPlayer Release.Build.0 = Blender Release|Win32 + {9C71A793-C177-4CAB-8EC5-923D500B39F8}.Debug.ActiveCfg = 3D Plugin Debug|Win32 + {9C71A793-C177-4CAB-8EC5-923D500B39F8}.Debug.Build.0 = 3D Plugin Debug|Win32 + {9C71A793-C177-4CAB-8EC5-923D500B39F8}.Release.ActiveCfg = 3D Plugin Release|Win32 + {9C71A793-C177-4CAB-8EC5-923D500B39F8}.Release.Build.0 = 3D Plugin Release|Win32 {D696C86B-0B53-4471-A50D-5B983A6FA4AD}.3D Plugin Debug.ActiveCfg = 3D Plugin Debug|Win32 {D696C86B-0B53-4471-A50D-5B983A6FA4AD}.3D Plugin Debug.Build.0 = 3D Plugin Debug|Win32 {D696C86B-0B53-4471-A50D-5B983A6FA4AD}.3D Plugin Release.ActiveCfg = 3D Plugin Release|Win32 @@ -80,6 +93,10 @@ Global {D696C86B-0B53-4471-A50D-5B983A6FA4AD}.BlenderPlayer Debug.Build.0 = Blender Release|Win32 {D696C86B-0B53-4471-A50D-5B983A6FA4AD}.BlenderPlayer Release.ActiveCfg = Blender Release|Win32 {D696C86B-0B53-4471-A50D-5B983A6FA4AD}.BlenderPlayer Release.Build.0 = Blender Release|Win32 + {D696C86B-0B53-4471-A50D-5B983A6FA4AD}.Debug.ActiveCfg = 3D Plugin Debug|Win32 + {D696C86B-0B53-4471-A50D-5B983A6FA4AD}.Debug.Build.0 = 3D Plugin Debug|Win32 + {D696C86B-0B53-4471-A50D-5B983A6FA4AD}.Release.ActiveCfg = 3D Plugin Release|Win32 + {D696C86B-0B53-4471-A50D-5B983A6FA4AD}.Release.Build.0 = 3D Plugin Release|Win32 {6461F05D-4698-47AB-A8E8-1CA2ACC9948B}.3D Plugin Debug.ActiveCfg = 3D Plugin Debug|Win32 {6461F05D-4698-47AB-A8E8-1CA2ACC9948B}.3D Plugin Debug.Build.0 = 3D Plugin Debug|Win32 {6461F05D-4698-47AB-A8E8-1CA2ACC9948B}.3D Plugin Release.ActiveCfg = 3D Plugin Release|Win32 @@ -92,6 +109,10 @@ Global {6461F05D-4698-47AB-A8E8-1CA2ACC9948B}.BlenderPlayer Debug.Build.0 = Blender Debug|Win32 {6461F05D-4698-47AB-A8E8-1CA2ACC9948B}.BlenderPlayer Release.ActiveCfg = Blender Debug|Win32 {6461F05D-4698-47AB-A8E8-1CA2ACC9948B}.BlenderPlayer Release.Build.0 = Blender Debug|Win32 + {6461F05D-4698-47AB-A8E8-1CA2ACC9948B}.Debug.ActiveCfg = 3D Plugin Debug|Win32 + {6461F05D-4698-47AB-A8E8-1CA2ACC9948B}.Debug.Build.0 = 3D Plugin Debug|Win32 + {6461F05D-4698-47AB-A8E8-1CA2ACC9948B}.Release.ActiveCfg = 3D Plugin Release|Win32 + {6461F05D-4698-47AB-A8E8-1CA2ACC9948B}.Release.Build.0 = 3D Plugin Release|Win32 {524264F4-DF21-4B79-847F-E7CA643ECD0B}.3D Plugin Debug.ActiveCfg = 3D Plugin Debug|Win32 {524264F4-DF21-4B79-847F-E7CA643ECD0B}.3D Plugin Debug.Build.0 = 3D Plugin Debug|Win32 {524264F4-DF21-4B79-847F-E7CA643ECD0B}.3D Plugin Release.ActiveCfg = 3D Plugin Release|Win32 @@ -104,6 +125,10 @@ Global {524264F4-DF21-4B79-847F-E7CA643ECD0B}.BlenderPlayer Debug.Build.0 = Blender Release|Win32 {524264F4-DF21-4B79-847F-E7CA643ECD0B}.BlenderPlayer Release.ActiveCfg = Blender Release|Win32 {524264F4-DF21-4B79-847F-E7CA643ECD0B}.BlenderPlayer Release.Build.0 = Blender Release|Win32 + {524264F4-DF21-4B79-847F-E7CA643ECD0B}.Debug.ActiveCfg = 3D Plugin Debug|Win32 + {524264F4-DF21-4B79-847F-E7CA643ECD0B}.Debug.Build.0 = 3D Plugin Debug|Win32 + {524264F4-DF21-4B79-847F-E7CA643ECD0B}.Release.ActiveCfg = 3D Plugin Release|Win32 + {524264F4-DF21-4B79-847F-E7CA643ECD0B}.Release.Build.0 = 3D Plugin Release|Win32 {B83C6BED-11EC-46C8-AFFA-121EEDE94373}.3D Plugin Debug.ActiveCfg = 3D Plugin Debug|Win32 {B83C6BED-11EC-46C8-AFFA-121EEDE94373}.3D Plugin Debug.Build.0 = 3D Plugin Debug|Win32 {B83C6BED-11EC-46C8-AFFA-121EEDE94373}.3D Plugin Release.ActiveCfg = 3D Plugin Release|Win32 @@ -116,6 +141,10 @@ Global {B83C6BED-11EC-46C8-AFFA-121EEDE94373}.BlenderPlayer Debug.Build.0 = Blender Debug|Win32 {B83C6BED-11EC-46C8-AFFA-121EEDE94373}.BlenderPlayer Release.ActiveCfg = Blender Debug|Win32 {B83C6BED-11EC-46C8-AFFA-121EEDE94373}.BlenderPlayer Release.Build.0 = Blender Debug|Win32 + {B83C6BED-11EC-46C8-AFFA-121EEDE94373}.Debug.ActiveCfg = 3D Plugin Debug|Win32 + {B83C6BED-11EC-46C8-AFFA-121EEDE94373}.Debug.Build.0 = 3D Plugin Debug|Win32 + {B83C6BED-11EC-46C8-AFFA-121EEDE94373}.Release.ActiveCfg = 3D Plugin Release|Win32 + {B83C6BED-11EC-46C8-AFFA-121EEDE94373}.Release.Build.0 = 3D Plugin Release|Win32 {0112CAD5-3584-412A-A2E5-1315A00437B4}.3D Plugin Debug.ActiveCfg = 3D Plugin Debug|Win32 {0112CAD5-3584-412A-A2E5-1315A00437B4}.3D Plugin Debug.Build.0 = 3D Plugin Debug|Win32 {0112CAD5-3584-412A-A2E5-1315A00437B4}.3D Plugin Release.ActiveCfg = 3D Plugin Release|Win32 @@ -128,6 +157,10 @@ Global {0112CAD5-3584-412A-A2E5-1315A00437B4}.BlenderPlayer Debug.Build.0 = Blender Debug|Win32 {0112CAD5-3584-412A-A2E5-1315A00437B4}.BlenderPlayer Release.ActiveCfg = Blender Debug|Win32 {0112CAD5-3584-412A-A2E5-1315A00437B4}.BlenderPlayer Release.Build.0 = Blender Debug|Win32 + {0112CAD5-3584-412A-A2E5-1315A00437B4}.Debug.ActiveCfg = 3D Plugin Debug|Win32 + {0112CAD5-3584-412A-A2E5-1315A00437B4}.Debug.Build.0 = 3D Plugin Debug|Win32 + {0112CAD5-3584-412A-A2E5-1315A00437B4}.Release.ActiveCfg = 3D Plugin Release|Win32 + {0112CAD5-3584-412A-A2E5-1315A00437B4}.Release.Build.0 = 3D Plugin Release|Win32 {F9850C15-FF0A-429E-9D47-89FB433C9BD8}.3D Plugin Debug.ActiveCfg = 3D Plugin Debug|Win32 {F9850C15-FF0A-429E-9D47-89FB433C9BD8}.3D Plugin Debug.Build.0 = 3D Plugin Debug|Win32 {F9850C15-FF0A-429E-9D47-89FB433C9BD8}.3D Plugin Release.ActiveCfg = 3D Plugin Release|Win32 @@ -140,6 +173,10 @@ Global {F9850C15-FF0A-429E-9D47-89FB433C9BD8}.BlenderPlayer Debug.Build.0 = Blender Release|Win32 {F9850C15-FF0A-429E-9D47-89FB433C9BD8}.BlenderPlayer Release.ActiveCfg = Blender Release|Win32 {F9850C15-FF0A-429E-9D47-89FB433C9BD8}.BlenderPlayer Release.Build.0 = Blender Release|Win32 + {F9850C15-FF0A-429E-9D47-89FB433C9BD8}.Debug.ActiveCfg = 3D Plugin Debug|Win32 + {F9850C15-FF0A-429E-9D47-89FB433C9BD8}.Debug.Build.0 = 3D Plugin Debug|Win32 + {F9850C15-FF0A-429E-9D47-89FB433C9BD8}.Release.ActiveCfg = 3D Plugin Release|Win32 + {F9850C15-FF0A-429E-9D47-89FB433C9BD8}.Release.Build.0 = 3D Plugin Release|Win32 {F9850C15-FF0A-429E-9D47-89FB433C9BD8}.3D Plugin Debug.ActiveCfg = 3D Plugin Debug|Win32 {F9850C15-FF0A-429E-9D47-89FB433C9BD8}.3D Plugin Debug.Build.0 = 3D Plugin Debug|Win32 {F9850C15-FF0A-429E-9D47-89FB433C9BD8}.3D Plugin Release.ActiveCfg = 3D Plugin Release|Win32 @@ -152,6 +189,10 @@ Global {F9850C15-FF0A-429E-9D47-89FB433C9BD8}.BlenderPlayer Debug.Build.0 = Blender Release|Win32 {F9850C15-FF0A-429E-9D47-89FB433C9BD8}.BlenderPlayer Release.ActiveCfg = Blender Release|Win32 {F9850C15-FF0A-429E-9D47-89FB433C9BD8}.BlenderPlayer Release.Build.0 = Blender Release|Win32 + {F9850C15-FF0A-429E-9D47-89FB433C9BD8}.Debug.ActiveCfg = 3D Plugin Debug|Win32 + {F9850C15-FF0A-429E-9D47-89FB433C9BD8}.Debug.Build.0 = 3D Plugin Debug|Win32 + {F9850C15-FF0A-429E-9D47-89FB433C9BD8}.Release.ActiveCfg = 3D Plugin Release|Win32 + {F9850C15-FF0A-429E-9D47-89FB433C9BD8}.Release.Build.0 = 3D Plugin Release|Win32 {FC752464-F413-4D4F-842D-A5D3AA0E6A3D}.3D Plugin Debug.ActiveCfg = 3D Plugin Debug|Win32 {FC752464-F413-4D4F-842D-A5D3AA0E6A3D}.3D Plugin Release.ActiveCfg = 3D Plugin Release|Win32 {FC752464-F413-4D4F-842D-A5D3AA0E6A3D}.Blender Debug.ActiveCfg = Blender Debug|Win32 @@ -160,6 +201,10 @@ Global {FC752464-F413-4D4F-842D-A5D3AA0E6A3D}.Blender Release.Build.0 = Blender Release|Win32 {FC752464-F413-4D4F-842D-A5D3AA0E6A3D}.BlenderPlayer Debug.ActiveCfg = BlenderPlayer Debug|Win32 {FC752464-F413-4D4F-842D-A5D3AA0E6A3D}.BlenderPlayer Release.ActiveCfg = BlenderPlayer Release|Win32 + {FC752464-F413-4D4F-842D-A5D3AA0E6A3D}.Debug.ActiveCfg = BlenderPlayer Debug|Win32 + {FC752464-F413-4D4F-842D-A5D3AA0E6A3D}.Debug.Build.0 = BlenderPlayer Debug|Win32 + {FC752464-F413-4D4F-842D-A5D3AA0E6A3D}.Release.ActiveCfg = BlenderPlayer Release|Win32 + {FC752464-F413-4D4F-842D-A5D3AA0E6A3D}.Release.Build.0 = BlenderPlayer Release|Win32 {FFD3C64A-30E2-4BC7-BC8F-51818C320400}.3D Plugin Debug.ActiveCfg = 3D Plugin Debug|Win32 {FFD3C64A-30E2-4BC7-BC8F-51818C320400}.3D Plugin Debug.Build.0 = 3D Plugin Debug|Win32 {FFD3C64A-30E2-4BC7-BC8F-51818C320400}.3D Plugin Release.ActiveCfg = 3D Plugin Release|Win32 @@ -172,6 +217,26 @@ Global {FFD3C64A-30E2-4BC7-BC8F-51818C320400}.BlenderPlayer Debug.Build.0 = Blender Release|Win32 {FFD3C64A-30E2-4BC7-BC8F-51818C320400}.BlenderPlayer Release.ActiveCfg = Blender Release|Win32 {FFD3C64A-30E2-4BC7-BC8F-51818C320400}.BlenderPlayer Release.Build.0 = Blender Release|Win32 + {FFD3C64A-30E2-4BC7-BC8F-51818C320400}.Debug.ActiveCfg = 3D Plugin Debug|Win32 + {FFD3C64A-30E2-4BC7-BC8F-51818C320400}.Debug.Build.0 = 3D Plugin Debug|Win32 + {FFD3C64A-30E2-4BC7-BC8F-51818C320400}.Release.ActiveCfg = 3D Plugin Release|Win32 + {FFD3C64A-30E2-4BC7-BC8F-51818C320400}.Release.Build.0 = 3D Plugin Release|Win32 + {BAC615B0-F1AF-418B-8D23-A10FD8870D6A}.3D Plugin Debug.ActiveCfg = Blender Release|Win32 + {BAC615B0-F1AF-418B-8D23-A10FD8870D6A}.3D Plugin Debug.Build.0 = Blender Release|Win32 + {BAC615B0-F1AF-418B-8D23-A10FD8870D6A}.3D Plugin Release.ActiveCfg = Blender Release|Win32 + {BAC615B0-F1AF-418B-8D23-A10FD8870D6A}.3D Plugin Release.Build.0 = Blender Release|Win32 + {BAC615B0-F1AF-418B-8D23-A10FD8870D6A}.Blender Debug.ActiveCfg = Blender Debug|Win32 + {BAC615B0-F1AF-418B-8D23-A10FD8870D6A}.Blender Debug.Build.0 = Blender Debug|Win32 + {BAC615B0-F1AF-418B-8D23-A10FD8870D6A}.Blender Release.ActiveCfg = Blender Release|Win32 + {BAC615B0-F1AF-418B-8D23-A10FD8870D6A}.Blender Release.Build.0 = Blender Release|Win32 + {BAC615B0-F1AF-418B-8D23-A10FD8870D6A}.BlenderPlayer Debug.ActiveCfg = Blender Release|Win32 + {BAC615B0-F1AF-418B-8D23-A10FD8870D6A}.BlenderPlayer Debug.Build.0 = Blender Release|Win32 + {BAC615B0-F1AF-418B-8D23-A10FD8870D6A}.BlenderPlayer Release.ActiveCfg = Blender Release|Win32 + {BAC615B0-F1AF-418B-8D23-A10FD8870D6A}.BlenderPlayer Release.Build.0 = Blender Release|Win32 + {BAC615B0-F1AF-418B-8D23-A10FD8870D6A}.Debug.ActiveCfg = Blender Debug|Win32 + {BAC615B0-F1AF-418B-8D23-A10FD8870D6A}.Debug.Build.0 = Blender Debug|Win32 + {BAC615B0-F1AF-418B-8D23-A10FD8870D6A}.Release.ActiveCfg = Blender Release|Win32 + {BAC615B0-F1AF-418B-8D23-A10FD8870D6A}.Release.Build.0 = Blender Release|Win32 EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution EndGlobalSection diff --git a/projectfiles_vc7/blender/blender.vcproj b/projectfiles_vc7/blender/blender.vcproj index 2f73bfefd27..6372a2f73f5 100644 --- a/projectfiles_vc7/blender/blender.vcproj +++ b/projectfiles_vc7/blender/blender.vcproj @@ -41,7 +41,7 @@ + + + + @@ -396,6 +402,12 @@ + + + + diff --git a/projectfiles_vc7/gameengine/gameplayer/common/GP_common.vcproj b/projectfiles_vc7/gameengine/gameplayer/common/GP_common.vcproj index cba8b1558c9..223a1187347 100644 --- a/projectfiles_vc7/gameengine/gameplayer/common/GP_common.vcproj +++ b/projectfiles_vc7/gameengine/gameplayer/common/GP_common.vcproj @@ -124,7 +124,7 @@ + + @@ -539,6 +542,9 @@ + + diff --git a/projectfiles_vc7/gameengine/rasterizer/RAS_rasterizer.vcproj b/projectfiles_vc7/gameengine/rasterizer/RAS_rasterizer.vcproj index 40a92a5c181..31520b06546 100644 --- a/projectfiles_vc7/gameengine/rasterizer/RAS_rasterizer.vcproj +++ b/projectfiles_vc7/gameengine/rasterizer/RAS_rasterizer.vcproj @@ -21,7 +21,7 @@ - - - - - - diff --git a/source/blender/blenkernel/BKE_action.h b/source/blender/blenkernel/BKE_action.h index b5e34444d13..716eac81b55 100644 --- a/source/blender/blenkernel/BKE_action.h +++ b/source/blender/blenkernel/BKE_action.h @@ -44,6 +44,7 @@ struct bActionChannel; struct bPose; struct bPoseChannel; struct Object; +struct ID; /* Kernel prototypes */ #ifdef __cplusplus @@ -157,6 +158,10 @@ void rest_pose(struct bPose *pose); float get_action_frame(struct Object *ob, float cframe); /* map strip time to global time (frame nr) */ float get_action_frame_inv(struct Object *ob, float cframe); +/* builds a list of NlaIpoChannel with ipo values to write in datablock */ +void extract_ipochannels_from_action(ListBase *lb, struct ID *id, struct bAction *act, char *name, float ctime); +/* write values returned by extract_ipochannels_from_action, returns the number of value written */ +int execute_ipochannels(ListBase *lb); #ifdef __cplusplus }; diff --git a/source/blender/blenkernel/BKE_key.h b/source/blender/blenkernel/BKE_key.h index a6871aa837f..faf8692b89a 100644 --- a/source/blender/blenkernel/BKE_key.h +++ b/source/blender/blenkernel/BKE_key.h @@ -40,6 +40,11 @@ struct Object; struct Lattice; struct Mesh; +/* Kernel prototypes */ +#ifdef __cplusplus +extern "C" { +#endif + void free_key(struct Key *sc); struct Key *add_key(struct ID *id); struct Key *copy_key(struct Key *key); @@ -57,6 +62,12 @@ int do_ob_key(struct Object *ob); struct Key *ob_get_key(struct Object *ob); struct KeyBlock *ob_get_keyblock(struct Object *ob); struct KeyBlock *key_get_keyblock(struct Key *key, int index); +// needed for the GE +void do_rel_key(int start, int end, int tot, char *basispoin, struct Key *key, int mode); + +#ifdef __cplusplus +}; +#endif #endif diff --git a/source/blender/blenkernel/intern/action.c b/source/blender/blenkernel/intern/action.c index 4860c65f06c..05f2e69fce1 100644 --- a/source/blender/blenkernel/intern/action.c +++ b/source/blender/blenkernel/intern/action.c @@ -860,7 +860,7 @@ typedef struct NlaIpoChannel { int type; } NlaIpoChannel; -static void extract_ipochannels_from_action(ListBase *lb, ID *id, bAction *act, char *name, float ctime) +void extract_ipochannels_from_action(ListBase *lb, ID *id, bAction *act, char *name, float ctime) { bActionChannel *achan= get_action_channel(act, name); IpoCurve *icu; @@ -953,15 +953,18 @@ static void blend_ipochannels(ListBase *dst, ListBase *src, float srcweight, int } } -static void execute_ipochannels(ListBase *lb) +int execute_ipochannels(ListBase *lb) { NlaIpoChannel *nic; + int count = 0; for(nic= lb->first; nic; nic= nic->next) { if(nic->poin) { write_ipo_poin(nic->poin, nic->type, nic->val); + count++; } } + return count; } /* nla timing */ diff --git a/source/blender/blenkernel/intern/key.c b/source/blender/blenkernel/intern/key.c index 3b4e562a87a..dd6c7ddacd2 100644 --- a/source/blender/blenkernel/intern/key.c +++ b/source/blender/blenkernel/intern/key.c @@ -630,7 +630,7 @@ void cp_cu_key(Curve *cu, KeyBlock *kb, int start, int end) } -static void do_rel_key(int start, int end, int tot, char *basispoin, Key *key, int mode) +void do_rel_key(int start, int end, int tot, char *basispoin, Key *key, int mode) { KeyBlock *kb; int *ofsp, ofs[3], elemsize, b; diff --git a/source/blender/blenkernel/intern/sca.c b/source/blender/blenkernel/intern/sca.c index 86e395b3770..92544f19721 100644 --- a/source/blender/blenkernel/intern/sca.c +++ b/source/blender/blenkernel/intern/sca.c @@ -411,6 +411,7 @@ void init_actuator(bActuator *act) switch(act->type) { #ifdef __NLA case ACT_ACTION: + case ACT_SHAPEACTION: act->data= MEM_callocN(sizeof(bActionActuator), "actionact"); break; #endif diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 7d0dd9e41c1..fa7cbb06139 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -2991,6 +2991,10 @@ static void lib_link_object(FileData *fd, Main *main) bActionActuator *aa= act->data; aa->act= newlibadr(fd, ob->id.lib, aa->act); } + else if(act->type==ACT_SHAPEACTION) { + bActionActuator *aa= act->data; + aa->act= newlibadr(fd, ob->id.lib, aa->act); + } else if(act->type==ACT_PROPERTY) { bPropertyActuator *pa= act->data; pa->ob= newlibadr(fd, ob->id.lib, pa->ob); @@ -8399,6 +8403,10 @@ static void expand_object(FileData *fd, Main *mainvar, Object *ob) bActionActuator *aa= act->data; expand_doit(fd, mainvar, aa->act); } + else if(act->type==ACT_SHAPEACTION) { + bActionActuator *aa= act->data; + expand_doit(fd, mainvar, aa->act); + } else if(act->type==ACT_PROPERTY) { bPropertyActuator *pa= act->data; expand_doit(fd, mainvar, pa->ob); diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c index b4a9f225470..2595b95bbf0 100644 --- a/source/blender/blenloader/intern/writefile.c +++ b/source/blender/blenloader/intern/writefile.c @@ -664,6 +664,7 @@ static void write_actuators(WriteData *wd, ListBase *lb) switch(act->type) { case ACT_ACTION: + case ACT_SHAPEACTION: writestruct(wd, DATA, "bActionActuator", 1, act->data); break; case ACT_SOUND: diff --git a/source/blender/makesdna/DNA_actuator_types.h b/source/blender/makesdna/DNA_actuator_types.h index e34b376737a..a326f5b01d6 100644 --- a/source/blender/makesdna/DNA_actuator_types.h +++ b/source/blender/makesdna/DNA_actuator_types.h @@ -278,6 +278,7 @@ typedef struct FreeCamera { #define ACT_VISIBILITY 18 #define ACT_2DFILTER 19 #define ACT_PARENT 20 +#define ACT_SHAPEACTION 21 /* actuator flag */ #define ACT_SHOW 1 diff --git a/source/blender/src/buttons_logic.c b/source/blender/src/buttons_logic.c index 27caedf0cdd..59fedf04e30 100644 --- a/source/blender/src/buttons_logic.c +++ b/source/blender/src/buttons_logic.c @@ -677,6 +677,8 @@ static char *controller_pup(void) static char *actuator_name(int type) { switch (type) { + case ACT_SHAPEACTION: + return "Shape Action"; case ACT_ACTION: return "Action"; case ACT_OBJECT: @@ -732,6 +734,14 @@ static char *actuator_pup(Object *owner) "|Scene %x11|Random %x13|Message %x14|CD %x16|Game %x17" "|Visibility %x18|2D Filter %x19|Parent %x20"; break; + + case OB_MESH: + return "Actuators %t|Shape Action %x21|Motion %x0|Constraint %x9|Ipo %x1" + "|Camera %x3|Sound %x5|Property %x6|Edit Object %x10" + "|Scene %x11|Random %x13|Message %x14|CD %x16|Game %x17" + "|Visibility %x18|2D Filter %x19|Parent %x20"; + break; + default: return "Actuators %t|Motion %x0|Constraint %x9|Ipo %x1" "|Camera %x3|Sound %x5|Property %x6|Edit Object %x10" @@ -1433,6 +1443,7 @@ static int get_col_actuator(int type) { switch(type) { case ACT_ACTION: return TH_BUT_ACTION; + case ACT_SHAPEACTION: return TH_BUT_ACTION; case ACT_OBJECT: return TH_BUT_NEUTRAL; case ACT_IPO: return TH_BUT_SETTING; case ACT_PROPERTY: return TH_BUT_SETTING1; @@ -1541,6 +1552,7 @@ static short draw_actuatorbuttons(bActuator *act, uiBlock *block, short xco, sho break; } case ACT_ACTION: + case ACT_SHAPEACTION: { /* DrawAct */ #ifdef __NLA_ACTION_BY_MOTION_ACTUATOR diff --git a/source/gameengine/Converter/BL_BlenderDataConversion.cpp b/source/gameengine/Converter/BL_BlenderDataConversion.cpp index 0ad9258bcc0..32946267202 100644 --- a/source/gameengine/Converter/BL_BlenderDataConversion.cpp +++ b/source/gameengine/Converter/BL_BlenderDataConversion.cpp @@ -90,6 +90,7 @@ #include "BKE_object.h" #include "BKE_scene.h" #include "BL_SkinMeshObject.h" +#include "BL_ShapeDeformer.h" #include "BL_SkinDeformer.h" #include "BL_MeshDeformer.h" //#include "BL_ArmatureController.h" @@ -223,15 +224,16 @@ static unsigned int KX_Mcol2uint_new(MCol col) static void SetDefaultFaceType(Scene* scene) { default_face_mode = TF_DYNAMIC; - Base *base = static_cast(scene->base.first); - while(base) + Scene *sce; + Base *base; + + for(SETLOOPER(scene,base)) { if (base->object->type == OB_LAMP) { default_face_mode = TF_DYNAMIC|TF_LIGHT; return; } - base = base->next; } } @@ -800,12 +802,12 @@ RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, RAS_IRenderTools* // Determine if we need to make a skinned mesh - if (mesh->dvert){ - meshobj = new BL_SkinMeshObject(lightlayer); + if (mesh->dvert || mesh->key){ + meshobj = new BL_SkinMeshObject(mesh, lightlayer); skinMesh = true; } else { - meshobj = new RAS_MeshObject(lightlayer); + meshobj = new RAS_MeshObject(mesh, lightlayer); } MT_Vector4 *tangent = 0; if (tface) @@ -1644,7 +1646,7 @@ static KX_GameObject *gameobject_from_blenderobject( // needed for python scripting kxscene->GetLogicManager()->RegisterMeshName(meshobj->GetName(),meshobj); - gameobj = new BL_DeformableGameObject(kxscene,KX_Scene::m_callbacks); + gameobj = new BL_DeformableGameObject(ob,kxscene,KX_Scene::m_callbacks); // set transformation gameobj->AddMesh(meshobj); @@ -1655,12 +1657,24 @@ static KX_GameObject *gameobject_from_blenderobject( ((ob->gameflag2 & OB_NEVER_DO_ACTIVITY_CULLING)!=0); gameobj->SetIgnoreActivityCulling(ignoreActivityCulling); - // If this is a skin object, make Skin Controller - if (ob->parent && ob->parent->type == OB_ARMATURE && ob->partype==PARSKEL && ((Mesh*)ob->data)->dvert){ + // two options exists for deform: shape keys and armature + // only support relative shape key + bool bHasShapeKey = mesh->key != NULL && mesh->key->type==KEY_RELATIVE; + bool bHasDvert = mesh->dvert != NULL; + bool bHasArmature = (ob->parent && ob->parent->type == OB_ARMATURE && ob->partype==PARSKEL && bHasDvert); + + if (bHasShapeKey) { + // not that we can have shape keys without dvert! + BL_ShapeDeformer *dcont = new BL_ShapeDeformer((BL_DeformableGameObject*)gameobj, + ob, (BL_SkinMeshObject*)meshobj); + ((BL_DeformableGameObject*)gameobj)->m_pDeformer = dcont; + } else if (bHasArmature) { BL_SkinDeformer *dcont = new BL_SkinDeformer(ob, (BL_SkinMeshObject*)meshobj ); ((BL_DeformableGameObject*)gameobj)->m_pDeformer = dcont; - } - else if (((Mesh*)ob->data)->dvert){ + } else if (bHasDvert) { + // this case correspond to a mesh that can potentially deform but not with the + // object to which it is attached for the moment. A skin mesh was created in + // BL_ConvertMesh() so must create a deformer too! BL_MeshDeformer *dcont = new BL_MeshDeformer(ob, (BL_SkinMeshObject*)meshobj ); ((BL_DeformableGameObject*)gameobj)->m_pDeformer = dcont; } @@ -1696,6 +1710,7 @@ static KX_GameObject *gameobject_from_blenderobject( { gameobj->SetPhysicsEnvironment(kxscene->GetPhysicsEnvironment()); gameobj->SetLayer(ob->lay); + gameobj->SetBlenderObject(ob); } return gameobj; } diff --git a/source/gameengine/Converter/BL_DeformableGameObject.cpp b/source/gameengine/Converter/BL_DeformableGameObject.cpp index 68a2e41ca47..d23274324ee 100644 --- a/source/gameengine/Converter/BL_DeformableGameObject.cpp +++ b/source/gameengine/Converter/BL_DeformableGameObject.cpp @@ -28,6 +28,8 @@ */ #include "BL_DeformableGameObject.h" +#include "BL_ShapeDeformer.h" +#include "BL_ShapeActionActuator.h" #ifdef HAVE_CONFIG_H #include @@ -60,3 +62,48 @@ CValue* BL_DeformableGameObject::GetReplica() ProcessReplica(replica); return replica; } + +bool BL_DeformableGameObject::SetActiveAction(BL_ShapeActionActuator *act, short priority, double curtime) +{ + if (curtime != m_lastframe){ + m_activePriority = 9999; + m_lastframe= curtime; + m_activeAct = NULL; + } + + if (priority<=m_activePriority) + { + if (m_activeAct && (m_activeAct!=act)) + m_activeAct->SetBlendTime(0.0f); /* Reset the blend timer */ + m_activeAct = act; + m_activePriority = priority; + m_lastframe = curtime; + + return true; + } + else{ + act->SetBlendTime(0.0f); + return false; + } +} + +bool BL_DeformableGameObject::GetShape(vector &shape) +{ + shape.clear(); + if (m_pDeformer) + { + Mesh* mesh = ((BL_MeshDeformer*)m_pDeformer)->GetMesh(); + // this check is normally superfluous: a shape deformer can only be created if the mesh + // has relative keys + if (mesh && mesh->key && mesh->key->type==KEY_RELATIVE) + { + KeyBlock *kb; + for (kb = (KeyBlock*)mesh->key->block.first; kb; kb = (KeyBlock*)kb->next) + { + shape.push_back(kb->curval); + } + } + } + return !shape.empty(); +} + diff --git a/source/gameengine/Converter/BL_DeformableGameObject.h b/source/gameengine/Converter/BL_DeformableGameObject.h index d943cc7388a..57a404ad72b 100644 --- a/source/gameengine/Converter/BL_DeformableGameObject.h +++ b/source/gameengine/Converter/BL_DeformableGameObject.h @@ -34,15 +34,28 @@ #pragma warning (disable:4786) // get rid of stupid stl-visual compiler debug warning #endif //WIN32 +#include "DNA_mesh_types.h" #include "KX_GameObject.h" -#include "RAS_Deformer.h" +#include "BL_MeshDeformer.h" +#include + +class BL_ShapeActionActuator; +struct Key; class BL_DeformableGameObject : public KX_GameObject { public: - RAS_Deformer *m_pDeformer; CValue* GetReplica(); + + double GetLastFrame () + { + return m_lastframe; + } + Object* GetBlendObject() + { + return m_blendobj; + } virtual void Relink(GEN_Map*map) { if (m_pDeformer) @@ -50,13 +63,32 @@ public: }; void ProcessReplica(KX_GameObject* replica); - BL_DeformableGameObject(void* sgReplicationInfo, SG_Callbacks callbacks) : + BL_DeformableGameObject(Object* blendobj, void* sgReplicationInfo, SG_Callbacks callbacks) : KX_GameObject(sgReplicationInfo,callbacks), - m_pDeformer(NULL) + m_pDeformer(NULL), + m_activeAct(NULL), + m_lastframe(0.), + m_blendobj(blendobj), + m_activePriority(9999) { m_isDeformable = true; }; virtual ~BL_DeformableGameObject(); + bool SetActiveAction(class BL_ShapeActionActuator *act, short priority, double curtime); + + bool GetShape(vector &shape); + Key* GetKey() + { + return (m_pDeformer) ? ((BL_MeshDeformer*)m_pDeformer)->GetMesh()->key : NULL; + } + +public: + RAS_Deformer *m_pDeformer; +protected: + class BL_ShapeActionActuator *m_activeAct; + double m_lastframe; + Object* m_blendobj; + short m_activePriority; }; diff --git a/source/gameengine/Converter/BL_MeshDeformer.cpp b/source/gameengine/Converter/BL_MeshDeformer.cpp index 85ba894f9a5..212827a660f 100644 --- a/source/gameengine/Converter/BL_MeshDeformer.cpp +++ b/source/gameengine/Converter/BL_MeshDeformer.cpp @@ -198,7 +198,7 @@ void BL_MeshDeformer::RecalcNormals() void BL_MeshDeformer::VerifyStorage() { /* Ensure that we have the right number of verts assigned */ - if (m_tvtot!=m_bmesh->totvert+m_bmesh->totface) { + if (m_tvtot!=m_bmesh->totvert){ if (m_transverts) delete [] m_transverts; if (m_transnors) diff --git a/source/gameengine/Converter/BL_MeshDeformer.h b/source/gameengine/Converter/BL_MeshDeformer.h index 88dc2500859..8d8b56b1eed 100644 --- a/source/gameengine/Converter/BL_MeshDeformer.h +++ b/source/gameengine/Converter/BL_MeshDeformer.h @@ -32,6 +32,7 @@ #include "RAS_Deformer.h" #include "DNA_object_types.h" +#include "DNA_key_types.h" #include "MT_Point3.h" #include @@ -56,8 +57,9 @@ public: virtual ~BL_MeshDeformer(); virtual void SetSimulatedTime(double time){}; virtual bool Apply(class RAS_IPolyMaterial *mat); - virtual void Update(void){}; + virtual bool Update(void){ return false; }; virtual RAS_Deformer* GetReplica(){return NULL;}; + struct Mesh* GetMesh() { return m_bmesh; }; // virtual void InitDeform(double time){}; protected: class BL_SkinMeshObject* m_pMeshObject; diff --git a/source/gameengine/Converter/BL_ShapeActionActuator.cpp b/source/gameengine/Converter/BL_ShapeActionActuator.cpp new file mode 100644 index 00000000000..3e1369e1e9f --- /dev/null +++ b/source/gameengine/Converter/BL_ShapeActionActuator.cpp @@ -0,0 +1,797 @@ +/** +* $Id: BL_ShapeActionActuator.cpp 14444 2008-04-16 22:40:48Z hos $ +* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL LICENSE BLOCK ***** +*/ + +#if defined (__sgi) +#include +#else +#include +#endif + +#include "SCA_LogicManager.h" +#include "BL_ShapeActionActuator.h" +#include "BL_ActionActuator.h" +#include "BL_ShapeDeformer.h" +#include "KX_GameObject.h" +#include "STR_HashedString.h" +#include "DNA_action_types.h" +#include "DNA_nla_types.h" +#include "DNA_actuator_types.h" +#include "BKE_action.h" +#include "DNA_armature_types.h" +#include "MEM_guardedalloc.h" +#include "BLI_blenlib.h" +#include "BLI_arithb.h" +#include "MT_Matrix4x4.h" +#include "BKE_utildefines.h" + +#ifdef HAVE_CONFIG_H +#include +#endif + +BL_ShapeActionActuator::~BL_ShapeActionActuator() +{ +} + +void BL_ShapeActionActuator::ProcessReplica() +{ + m_localtime=m_startframe; + m_lastUpdate=-1; +} + +void BL_ShapeActionActuator::SetBlendTime (float newtime) +{ + m_blendframe = newtime; +} + +CValue* BL_ShapeActionActuator::GetReplica() +{ + BL_ShapeActionActuator* replica = new BL_ShapeActionActuator(*this);//m_float,GetName()); + replica->ProcessReplica(); + + // this will copy properties and so on... + CValue::AddDataToReplica(replica); + return replica; +} + +bool BL_ShapeActionActuator::ClampLocalTime() +{ + if (m_startframe < m_endframe) { + if (m_localtime < m_startframe) + { + m_localtime = m_startframe; + return true; + } + else if (m_localtime > m_endframe) + { + m_localtime = m_endframe; + return true; + } + } else { + if (m_localtime > m_startframe) + { + m_localtime = m_startframe; + return true; + } + else if (m_localtime < m_endframe) + { + m_localtime = m_endframe; + return true; + } + } + return false; +} + +void BL_ShapeActionActuator::SetStartTime(float curtime) +{ + float direction = m_startframe < m_endframe ? 1.0 : -1.0; + + if (!(m_flag & ACT_FLAG_REVERSE)) + m_starttime = curtime - direction*(m_localtime - m_startframe)/KX_KetsjiEngine::GetAnimFrameRate(); + else + m_starttime = curtime - direction*(m_endframe - m_localtime)/KX_KetsjiEngine::GetAnimFrameRate(); +} + +void BL_ShapeActionActuator::SetLocalTime(float curtime) +{ + float delta_time = (curtime - m_starttime)*KX_KetsjiEngine::GetAnimFrameRate(); + + if (m_endframe < m_startframe) + delta_time = -delta_time; + + if (!(m_flag & ACT_FLAG_REVERSE)) + m_localtime = m_startframe + delta_time; + else + m_localtime = m_endframe - delta_time; +} + +void BL_ShapeActionActuator::BlendShape(Key* key, float srcweight) +{ + vector::const_iterator it; + float dstweight; + int i; + KeyBlock *kb; + + dstweight = 1.0F - srcweight; + + for (it=m_blendshape.begin(), kb = (KeyBlock*)key->block.first; + kb && it != m_blendshape.end(); + kb = (KeyBlock*)kb->next, it++) { + kb->curval = kb->curval * dstweight + (*it) * srcweight; + } +} + +bool BL_ShapeActionActuator::Update(double curtime, bool frame) +{ + bool bNegativeEvent = false; + bool bPositiveEvent = false; + bool keepgoing = true; + bool wrap = false; + bool apply=true; + int priority; + float newweight; + + // result = true if animation has to be continued, false if animation stops + // maybe there are events for us in the queue ! + if (frame) + { + for (vector::iterator i=m_events.begin(); !(i==m_events.end());i++) + { + if ((*i)->GetNumber() == 0.0f) + bNegativeEvent = true; + else + bPositiveEvent= true; + (*i)->Release(); + + } + m_events.clear(); + + if (bPositiveEvent) + m_flag |= ACT_FLAG_ACTIVE; + + if (bNegativeEvent) + { + if (!(m_flag & ACT_FLAG_ACTIVE)) + return false; + m_flag &= ~ACT_FLAG_ACTIVE; + } + } + + /* This action can only be attached to a deform object */ + BL_DeformableGameObject *obj = (BL_DeformableGameObject*)GetParent(); + float length = m_endframe - m_startframe; + + priority = m_priority; + + /* Determine pre-incrementation behaviour and set appropriate flags */ + switch (m_playtype){ + case ACT_ACTION_MOTION: + if (bNegativeEvent){ + keepgoing=false; + apply=false; + }; + break; + case ACT_ACTION_FROM_PROP: + if (bNegativeEvent){ + apply=false; + keepgoing=false; + } + break; + case ACT_ACTION_LOOP_END: + if (bPositiveEvent){ + if (!(m_flag & ACT_FLAG_LOCKINPUT)){ + m_flag &= ~ACT_FLAG_KEYUP; + m_flag &= ~ACT_FLAG_REVERSE; + m_flag |= ACT_FLAG_LOCKINPUT; + m_localtime = m_startframe; + m_starttime = curtime; + } + } + if (bNegativeEvent){ + m_flag |= ACT_FLAG_KEYUP; + } + break; + case ACT_ACTION_LOOP_STOP: + if (bPositiveEvent){ + if (!(m_flag & ACT_FLAG_LOCKINPUT)){ + m_flag &= ~ACT_FLAG_REVERSE; + m_flag &= ~ACT_FLAG_KEYUP; + m_flag |= ACT_FLAG_LOCKINPUT; + SetStartTime(curtime); + } + } + if (bNegativeEvent){ + m_flag |= ACT_FLAG_KEYUP; + m_flag &= ~ACT_FLAG_LOCKINPUT; + keepgoing=false; + apply=false; + } + break; + case ACT_ACTION_FLIPPER: + if (bPositiveEvent){ + if (!(m_flag & ACT_FLAG_LOCKINPUT)){ + m_flag &= ~ACT_FLAG_REVERSE; + m_flag |= ACT_FLAG_LOCKINPUT; + SetStartTime(curtime); + } + } + else if (bNegativeEvent){ + m_flag |= ACT_FLAG_REVERSE; + m_flag &= ~ACT_FLAG_LOCKINPUT; + SetStartTime(curtime); + } + break; + case ACT_ACTION_PLAY: + if (bPositiveEvent){ + if (!(m_flag & ACT_FLAG_LOCKINPUT)){ + m_flag &= ~ACT_FLAG_REVERSE; + m_localtime = m_starttime; + m_starttime = curtime; + m_flag |= ACT_FLAG_LOCKINPUT; + } + } + break; + default: + break; + } + + /* Perform increment */ + if (keepgoing){ + if (m_playtype == ACT_ACTION_MOTION){ + MT_Point3 newpos; + MT_Point3 deltapos; + + newpos = obj->NodeGetWorldPosition(); + + /* Find displacement */ + deltapos = newpos-m_lastpos; + m_localtime += (length/m_stridelength) * deltapos.length(); + m_lastpos = newpos; + } + else{ + SetLocalTime(curtime); + } + } + + /* Check if a wrapping response is needed */ + if (length){ + if (m_localtime < m_startframe || m_localtime > m_endframe) + { + m_localtime = m_startframe + fmod(m_localtime, length); + wrap = true; + } + } + else + m_localtime = m_startframe; + + /* Perform post-increment tasks */ + switch (m_playtype){ + case ACT_ACTION_FROM_PROP: + { + CValue* propval = GetParent()->GetProperty(m_propname); + if (propval) + m_localtime = propval->GetNumber(); + + if (bNegativeEvent){ + keepgoing=false; + } + } + break; + case ACT_ACTION_MOTION: + break; + case ACT_ACTION_LOOP_STOP: + break; + case ACT_ACTION_FLIPPER: + if (wrap){ + if (!(m_flag & ACT_FLAG_REVERSE)){ + m_localtime=m_endframe; + //keepgoing = false; + } + else { + m_localtime=m_startframe; + keepgoing = false; + } + } + break; + case ACT_ACTION_LOOP_END: + if (wrap){ + if (m_flag & ACT_FLAG_KEYUP){ + keepgoing = false; + m_localtime = m_endframe; + m_flag &= ~ACT_FLAG_LOCKINPUT; + } + SetStartTime(curtime); + } + break; + case ACT_ACTION_PLAY: + if (wrap){ + m_localtime = m_endframe; + keepgoing = false; + m_flag &= ~ACT_FLAG_LOCKINPUT; + } + break; + default: + keepgoing = false; + break; + } + + + if (bNegativeEvent) + m_blendframe=0.0f; + + /* Apply the pose if necessary*/ + if (apply) { + + /* Priority test */ + if (obj->SetActiveAction(this, priority, curtime)){ + Key *key = obj->GetKey(); + + if (!key) { + // this could happen if the mesh was changed in the middle of an action + // and the new mesh has no key, stop the action + keepgoing = false; + } + else { + ListBase tchanbase= {NULL, NULL}; + + if (m_blendin && m_blendframe==0.0f){ + // this is the start of the blending, remember the startup shape + obj->GetShape(m_blendshape); + m_blendstart = curtime; + } + // only interested in shape channel + extract_ipochannels_from_action(&tchanbase, &key->id, m_action, "Shape", m_localtime); + + if (!execute_ipochannels(&tchanbase)) { + // no update, this is possible if action does not match the keys, stop the action + keepgoing = false; + } + else { + // the key have changed, apply blending if needed + if (m_blendin && (m_blendframem_blendin) + m_blendframe = m_blendin; + } + m_lastUpdate = m_localtime; + } + BLI_freelistN(&tchanbase); + } + } + else{ + m_blendframe = 0.0f; + } + } + + if (!keepgoing){ + m_blendframe = 0.0f; + } + return keepgoing; +}; + +/* ------------------------------------------------------------------------- */ +/* Python functions */ +/* ------------------------------------------------------------------------- */ + +/* Integration hooks ------------------------------------------------------- */ + +PyTypeObject BL_ShapeActionActuator::Type = { + PyObject_HEAD_INIT(&PyType_Type) + 0, + "BL_ShapeActionActuator", + sizeof(BL_ShapeActionActuator), + 0, + PyDestructor, + 0, + __getattr, + __setattr, + 0, //&MyPyCompare, + __repr, + 0, //&cvalue_as_number, + 0, + 0, + 0, + 0 +}; + +PyParentObject BL_ShapeActionActuator::Parents[] = { + &BL_ShapeActionActuator::Type, + &SCA_IActuator::Type, + &SCA_ILogicBrick::Type, + &CValue::Type, + NULL +}; + +PyMethodDef BL_ShapeActionActuator::Methods[] = { + {"setAction", (PyCFunction) BL_ShapeActionActuator::sPySetAction, METH_VARARGS, SetAction_doc}, + {"setStart", (PyCFunction) BL_ShapeActionActuator::sPySetStart, METH_VARARGS, SetStart_doc}, + {"setEnd", (PyCFunction) BL_ShapeActionActuator::sPySetEnd, METH_VARARGS, SetEnd_doc}, + {"setBlendin", (PyCFunction) BL_ShapeActionActuator::sPySetBlendin, METH_VARARGS, SetBlendin_doc}, + {"setPriority", (PyCFunction) BL_ShapeActionActuator::sPySetPriority, METH_VARARGS, SetPriority_doc}, + {"setFrame", (PyCFunction) BL_ShapeActionActuator::sPySetFrame, METH_VARARGS, SetFrame_doc}, + {"setProperty", (PyCFunction) BL_ShapeActionActuator::sPySetProperty, METH_VARARGS, SetProperty_doc}, + {"setBlendtime", (PyCFunction) BL_ShapeActionActuator::sPySetBlendtime, METH_VARARGS, SetBlendtime_doc}, + + {"getAction", (PyCFunction) BL_ShapeActionActuator::sPyGetAction, METH_VARARGS, GetAction_doc}, + {"getStart", (PyCFunction) BL_ShapeActionActuator::sPyGetStart, METH_VARARGS, GetStart_doc}, + {"getEnd", (PyCFunction) BL_ShapeActionActuator::sPyGetEnd, METH_VARARGS, GetEnd_doc}, + {"getBlendin", (PyCFunction) BL_ShapeActionActuator::sPyGetBlendin, METH_VARARGS, GetBlendin_doc}, + {"getPriority", (PyCFunction) BL_ShapeActionActuator::sPyGetPriority, METH_VARARGS, GetPriority_doc}, + {"getFrame", (PyCFunction) BL_ShapeActionActuator::sPyGetFrame, METH_VARARGS, GetFrame_doc}, + {"getProperty", (PyCFunction) BL_ShapeActionActuator::sPyGetProperty, METH_VARARGS, GetProperty_doc}, + {"getType", (PyCFunction) BL_ShapeActionActuator::sPyGetType, METH_VARARGS, GetType_doc}, + {"setType", (PyCFunction) BL_ShapeActionActuator::sPySetType, METH_VARARGS, SetType_doc}, + {NULL,NULL} //Sentinel +}; + +PyObject* BL_ShapeActionActuator::_getattr(const STR_String& attr) { + _getattr_up(SCA_IActuator); +} + +/* setStart */ +char BL_ShapeActionActuator::GetAction_doc[] = +"getAction()\n" +"\tReturns a string containing the name of the current action.\n"; + +PyObject* BL_ShapeActionActuator::PyGetAction(PyObject* self, + PyObject* args, + PyObject* kwds) { + PyObject *result; + + if (m_action){ + result = Py_BuildValue("s", m_action->id.name+2); + } + else{ + Py_INCREF(Py_None); + result = Py_None; + } + + return result; +} + +/* getProperty */ +char BL_ShapeActionActuator::GetProperty_doc[] = +"getProperty()\n" +"\tReturns the name of the property to be used in FromProp mode.\n"; + +PyObject* BL_ShapeActionActuator::PyGetProperty(PyObject* self, + PyObject* args, + PyObject* kwds) { + PyObject *result; + + result = Py_BuildValue("s", (const char *)m_propname); + + return result; +} + +/* getFrame */ +char BL_ShapeActionActuator::GetFrame_doc[] = +"getFrame()\n" +"\tReturns the current frame number.\n"; + +PyObject* BL_ShapeActionActuator::PyGetFrame(PyObject* self, + PyObject* args, + PyObject* kwds) { + PyObject *result; + + result = Py_BuildValue("f", m_localtime); + + return result; +} + +/* getEnd */ +char BL_ShapeActionActuator::GetEnd_doc[] = +"getEnd()\n" +"\tReturns the last frame of the action.\n"; + +PyObject* BL_ShapeActionActuator::PyGetEnd(PyObject* self, + PyObject* args, + PyObject* kwds) { + PyObject *result; + + result = Py_BuildValue("f", m_endframe); + + return result; +} + +/* getStart */ +char BL_ShapeActionActuator::GetStart_doc[] = +"getStart()\n" +"\tReturns the starting frame of the action.\n"; + +PyObject* BL_ShapeActionActuator::PyGetStart(PyObject* self, + PyObject* args, + PyObject* kwds) { + PyObject *result; + + result = Py_BuildValue("f", m_startframe); + + return result; +} + +/* getBlendin */ +char BL_ShapeActionActuator::GetBlendin_doc[] = +"getBlendin()\n" +"\tReturns the number of interpolation animation frames to be\n" +"\tgenerated when this actuator is triggered.\n"; + +PyObject* BL_ShapeActionActuator::PyGetBlendin(PyObject* self, + PyObject* args, + PyObject* kwds) { + PyObject *result; + + result = Py_BuildValue("f", m_blendin); + + return result; +} + +/* getPriority */ +char BL_ShapeActionActuator::GetPriority_doc[] = +"getPriority()\n" +"\tReturns the priority for this actuator. Actuators with lower\n" +"\tPriority numbers will override actuators with higher numbers.\n"; + +PyObject* BL_ShapeActionActuator::PyGetPriority(PyObject* self, + PyObject* args, + PyObject* kwds) { + PyObject *result; + + result = Py_BuildValue("i", m_priority); + + return result; +} + +/* setAction */ +char BL_ShapeActionActuator::SetAction_doc[] = +"setAction(action, (reset))\n" +"\t - action : The name of the action to set as the current action.\n" +"\t Should be an action with Shape channels.\n" +"\t - reset : Optional parameter indicating whether to reset the\n" +"\t blend timer or not. A value of 1 indicates that the\n" +"\t timer should be reset. A value of 0 will leave it\n" +"\t unchanged. If reset is not specified, the timer will" +"\t be reset.\n"; + +PyObject* BL_ShapeActionActuator::PySetAction(PyObject* self, + PyObject* args, + PyObject* kwds) { + char *string; + int reset = 1; + + if (PyArg_ParseTuple(args,"s|i",&string, &reset)) + { + bAction *action; + + action = (bAction*)SCA_ILogicBrick::m_sCurrentLogicManager->GetActionByName(STR_String(string)); + + if (!action){ + /* NOTE! Throw an exception or something */ + // printf ("setAction failed: Action not found\n", string); + } + else{ + m_action=action; + if (reset) + m_blendframe = 0.f; + } + } + + Py_INCREF(Py_None); + return Py_None; +} + +/* setStart */ +char BL_ShapeActionActuator::SetStart_doc[] = +"setStart(start)\n" +"\t - start : Specifies the starting frame of the animation.\n"; + +PyObject* BL_ShapeActionActuator::PySetStart(PyObject* self, + PyObject* args, + PyObject* kwds) { + float start; + + if (PyArg_ParseTuple(args,"f",&start)) + { + m_startframe = start; + } + + Py_INCREF(Py_None); + return Py_None; +} + +/* setEnd */ +char BL_ShapeActionActuator::SetEnd_doc[] = +"setEnd(end)\n" +"\t - end : Specifies the ending frame of the animation.\n"; + +PyObject* BL_ShapeActionActuator::PySetEnd(PyObject* self, + PyObject* args, + PyObject* kwds) { + float end; + + if (PyArg_ParseTuple(args,"f",&end)) + { + m_endframe = end; + } + + Py_INCREF(Py_None); + return Py_None; +} + +/* setBlendin */ +char BL_ShapeActionActuator::SetBlendin_doc[] = +"setBlendin(blendin)\n" +"\t - blendin : Specifies the number of frames of animation to generate\n" +"\t when making transitions between actions.\n"; + +PyObject* BL_ShapeActionActuator::PySetBlendin(PyObject* self, + PyObject* args, + PyObject* kwds) { + float blendin; + + if (PyArg_ParseTuple(args,"f",&blendin)) + { + m_blendin = blendin; + } + + Py_INCREF(Py_None); + return Py_None; +} + +/* setBlendtime */ +char BL_ShapeActionActuator::SetBlendtime_doc[] = +"setBlendtime(blendtime)\n" +"\t - blendtime : Allows the script to directly modify the internal timer\n" +"\t used when generating transitions between actions. This\n" +"\t parameter must be in the range from 0.0 to 1.0.\n"; + +PyObject* BL_ShapeActionActuator::PySetBlendtime(PyObject* self, + PyObject* args, + PyObject* kwds) { + float blendframe; + + if (PyArg_ParseTuple(args,"f",&blendframe)) + { + m_blendframe = blendframe * m_blendin; + if (m_blendframe<0.f) + m_blendframe = 0.f; + if (m_blendframe>m_blendin) + m_blendframe = m_blendin; + } + + Py_INCREF(Py_None); + return Py_None; +} + +/* setPriority */ +char BL_ShapeActionActuator::SetPriority_doc[] = +"setPriority(priority)\n" +"\t - priority : Specifies the new priority. Actuators will lower\n" +"\t priority numbers will override actuators with higher\n" +"\t numbers.\n"; + +PyObject* BL_ShapeActionActuator::PySetPriority(PyObject* self, + PyObject* args, + PyObject* kwds) { + int priority; + + if (PyArg_ParseTuple(args,"i",&priority)) + { + m_priority = priority; + } + + Py_INCREF(Py_None); + return Py_None; +} + +/* setFrame */ +char BL_ShapeActionActuator::SetFrame_doc[] = +"setFrame(frame)\n" +"\t - frame : Specifies the new current frame for the animation\n"; + +PyObject* BL_ShapeActionActuator::PySetFrame(PyObject* self, + PyObject* args, + PyObject* kwds) { + float frame; + + if (PyArg_ParseTuple(args,"f",&frame)) + { + m_localtime = frame; + if (m_localtimem_endframe) + m_localtime=m_endframe; + } + + Py_INCREF(Py_None); + return Py_None; +} + +/* setProperty */ +char BL_ShapeActionActuator::SetProperty_doc[] = +"setProperty(prop)\n" +"\t - prop : A string specifying the property name to be used in\n" +"\t FromProp playback mode.\n"; + +PyObject* BL_ShapeActionActuator::PySetProperty(PyObject* self, + PyObject* args, + PyObject* kwds) { + char *string; + + if (PyArg_ParseTuple(args,"s",&string)) + { + m_propname = string; + } + + Py_INCREF(Py_None); + return Py_None; +} + +/* getType */ +char BL_ShapeActionActuator::GetType_doc[] = +"getType()\n" +"\tReturns the operation mode of the actuator.\n"; +PyObject* BL_ShapeActionActuator::PyGetType(PyObject* self, + PyObject* args, + PyObject* kwds) { + return Py_BuildValue("h", m_playtype); +} + +/* setType */ +char BL_ShapeActionActuator::SetType_doc[] = +"setType(mode)\n" +"\t - mode: Play (0), Flipper (2), LoopStop (3), LoopEnd (4) or Property (6)\n" +"\tSet the operation mode of the actuator.\n"; +PyObject* BL_ShapeActionActuator::PySetType(PyObject* self, + PyObject* args, + PyObject* kwds) { + short typeArg; + + if (!PyArg_ParseTuple(args, "h", &typeArg)) { + return NULL; + } + + switch (typeArg) { + case ACT_ACTION_PLAY: + case ACT_ACTION_FLIPPER: + case ACT_ACTION_LOOP_STOP: + case ACT_ACTION_LOOP_END: + case ACT_ACTION_FROM_PROP: + m_playtype = typeArg; + break; + default: + printf("Invalid type for action actuator: %d\n", typeArg); /* error */ + } + + Py_Return; +} + diff --git a/source/gameengine/Converter/BL_ShapeActionActuator.h b/source/gameengine/Converter/BL_ShapeActionActuator.h new file mode 100644 index 00000000000..c4236a5208e --- /dev/null +++ b/source/gameengine/Converter/BL_ShapeActionActuator.h @@ -0,0 +1,133 @@ +/** + * $Id: BL_ShapeActionActuator.h 14444 2008-04-16 22:40:48Z hos $ + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#ifndef BL_SHAPEACTIONACTUATOR +#define BL_SHAPEACTIONACTUATOR + +#include "GEN_HashedPtr.h" +#include "SCA_IActuator.h" +#include "MT_Point3.h" +#include + +struct Key; +class BL_ShapeActionActuator : public SCA_IActuator +{ +public: + Py_Header; + BL_ShapeActionActuator(SCA_IObject* gameobj, + const STR_String& propname, + float starttime, + float endtime, + struct bAction *action, + short playtype, + short blendin, + short priority, + float stride, + PyTypeObject* T=&Type) + : SCA_IActuator(gameobj,T), + + m_lastpos(0, 0, 0), + m_blendframe(0), + m_flag(0), + m_startframe (starttime), + m_endframe(endtime) , + m_starttime(0), + m_localtime(starttime), + m_lastUpdate(-1), + m_blendin(blendin), + m_blendstart(0), + m_stridelength(stride), + m_playtype(playtype), + m_priority(priority), + m_action(action), + m_propname(propname) + { + }; + virtual ~BL_ShapeActionActuator(); + virtual bool Update(double curtime, bool frame); + virtual CValue* GetReplica(); + virtual void ProcessReplica(); + + void SetBlendTime (float newtime); + void BlendShape(struct Key* key, float weigth); + + KX_PYMETHOD_DOC(BL_ShapeActionActuator,SetAction); + KX_PYMETHOD_DOC(BL_ShapeActionActuator,SetBlendin); + KX_PYMETHOD_DOC(BL_ShapeActionActuator,SetPriority); + KX_PYMETHOD_DOC(BL_ShapeActionActuator,SetStart); + KX_PYMETHOD_DOC(BL_ShapeActionActuator,SetEnd); + KX_PYMETHOD_DOC(BL_ShapeActionActuator,SetFrame); + KX_PYMETHOD_DOC(BL_ShapeActionActuator,SetProperty); + KX_PYMETHOD_DOC(BL_ShapeActionActuator,SetBlendtime); + KX_PYMETHOD_DOC(BL_ShapeActionActuator,SetChannel); + + KX_PYMETHOD_DOC(BL_ShapeActionActuator,GetAction); + KX_PYMETHOD_DOC(BL_ShapeActionActuator,GetBlendin); + KX_PYMETHOD_DOC(BL_ShapeActionActuator,GetPriority); + KX_PYMETHOD_DOC(BL_ShapeActionActuator,GetStart); + KX_PYMETHOD_DOC(BL_ShapeActionActuator,GetEnd); + KX_PYMETHOD_DOC(BL_ShapeActionActuator,GetFrame); + KX_PYMETHOD_DOC(BL_ShapeActionActuator,GetProperty); +// KX_PYMETHOD(BL_ActionActuator,GetChannel); + KX_PYMETHOD_DOC(BL_ShapeActionActuator,GetType); + KX_PYMETHOD_DOC(BL_ShapeActionActuator,SetType); + + virtual PyObject* _getattr(const STR_String& attr); + +protected: + + void SetStartTime(float curtime); + void SetLocalTime(float curtime); + bool ClampLocalTime(); + + MT_Point3 m_lastpos; + float m_blendframe; + int m_flag; + /** The frame this action starts */ + float m_startframe; + /** The frame this action ends */ + float m_endframe; + /** The time this action started */ + float m_starttime; + /** The current time of the action */ + float m_localtime; + + float m_lastUpdate; + float m_blendin; + float m_blendstart; + float m_stridelength; + short m_playtype; + short m_priority; + struct bAction *m_action; + STR_String m_propname; + vector m_blendshape; +}; + +#endif + diff --git a/source/gameengine/Converter/BL_ShapeDeformer.cpp b/source/gameengine/Converter/BL_ShapeDeformer.cpp new file mode 100644 index 00000000000..54b1041c328 --- /dev/null +++ b/source/gameengine/Converter/BL_ShapeDeformer.cpp @@ -0,0 +1,125 @@ +/** + * $Id: BL_ShapeDeformer.cpp 14444 2008-04-16 22:40:48Z hos $ + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#ifdef WIN32 +#pragma warning (disable : 4786) +#endif //WIN32 + +#include "MEM_guardedalloc.h" +#include "BL_ShapeDeformer.h" +#include "GEN_Map.h" +#include "STR_HashedString.h" +#include "RAS_IPolygonMaterial.h" +#include "BL_SkinMeshObject.h" + +//#include "BL_ArmatureController.h" +#include "DNA_armature_types.h" +#include "DNA_action_types.h" +#include "DNA_key_types.h" +#include "DNA_mesh_types.h" +#include "DNA_meshdata_types.h" +#include "BKE_armature.h" +#include "BKE_action.h" +#include "BKE_key.h" +#include "MT_Point3.h" + +extern "C"{ + #include "BKE_lattice.h" +} + #include "BKE_utildefines.h" + +#include "BLI_blenlib.h" +#include "BLI_arithb.h" + +#define __NLA_DEFNORMALS +//#undef __NLA_DEFNORMALS + + +BL_ShapeDeformer::~BL_ShapeDeformer() +{ +}; + +RAS_Deformer *BL_ShapeDeformer::GetReplica() +{ + BL_ShapeDeformer *result; + + result = new BL_ShapeDeformer(*this); + result->ProcessReplica(); + return result; +} + +void BL_ShapeDeformer::ProcessReplica() +{ +} + +bool BL_ShapeDeformer::Update(void) +{ + bool bShapeUpdate = false; + bool bSkinUpdate = false; + + /* See if the object shape has changed */ + if (m_lastShapeUpdate != m_gameobj->GetLastFrame()) { + /* the key coefficient have been set already, we just need to blend the keys */ + Object* blendobj = m_gameobj->GetBlendObject(); + + // make sure the vertex weight cache is in line with this object + m_pMeshObject->CheckWeightCache(blendobj); + + /* we will blend the key directly in mvert array: it is used by armature as the start position */ + do_rel_key(0, m_bmesh->totvert, m_bmesh->totvert, (char *)m_bmesh->mvert->co, m_bmesh->key, 0); + + // Don't release the weight array as in Blender, it will most likely be reusable on next frame + // The weight array are ultimately deleted when the skin mesh is destroyed + + /* Update the current frame */ + m_lastShapeUpdate=m_gameobj->GetLastFrame(); + + // As we have changed, the mesh, the skin deformer must update as well. + // This will force the update + BL_SkinDeformer::ForceUpdate(); + bShapeUpdate = true; + } + // check for armature deform + bSkinUpdate = BL_SkinDeformer::Update(); + + if (!bSkinUpdate && bShapeUpdate) { + // this means that there is no armature, we still need to copy the vertex to m_transverts + // and update the normal (was not done after shape key calculation) + + /* store verts locally */ + VerifyStorage(); + + for (int v =0; vtotvert; v++) + VECCOPY(m_transverts[v], m_bmesh->mvert[v].co); + + RecalcNormals(); + bSkinUpdate = true; + } + return bSkinUpdate; +} diff --git a/source/gameengine/Converter/BL_ShapeDeformer.h b/source/gameengine/Converter/BL_ShapeDeformer.h new file mode 100644 index 00000000000..920eae86b7e --- /dev/null +++ b/source/gameengine/Converter/BL_ShapeDeformer.h @@ -0,0 +1,93 @@ +/** + * $Id: BL_SkinDeformer.h 14444 2008-04-16 22:40:48Z hos $ + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#ifndef BL_SHAPEDEFORMER +#define BL_SHAPEDEFORMER + +#ifdef WIN32 +#pragma warning (disable:4786) // get rid of stupid stl-visual compiler debug warning +#endif //WIN32 + +#include "BL_SkinDeformer.h" +#include "BL_DeformableGameObject.h" +#include + + +class BL_ShapeDeformer : public BL_SkinDeformer +{ +public: + virtual void Relink(GEN_Map*map) + { + void **h_obj = (*map)[m_gameobj]; + if (h_obj){ + m_gameobj = (BL_DeformableGameObject*)(*h_obj); + } + else + m_gameobj=NULL; + // relink the underlying skin deformer + BL_SkinDeformer::Relink(map); + }; + BL_ShapeDeformer(BL_DeformableGameObject *gameobj, + Object *bmeshobj, + BL_SkinMeshObject *mesh) + : + BL_SkinDeformer(bmeshobj, mesh), + m_lastShapeUpdate(-1), + m_gameobj(gameobj) + { + }; + + /* this second constructor is needed for making a mesh deformable on the fly. */ + BL_ShapeDeformer(BL_DeformableGameObject *gameobj, + struct Object *bmeshobj_old, + struct Object *bmeshobj_new, + class BL_SkinMeshObject *mesh, + bool release_object, + BL_ArmatureObject* arma = NULL) + : + BL_SkinDeformer(bmeshobj_old, bmeshobj_new, mesh, release_object, arma), + m_lastShapeUpdate(-1), + m_gameobj(gameobj) + { + }; + + virtual void ProcessReplica(); + virtual RAS_Deformer *GetReplica(); + virtual ~BL_ShapeDeformer(); + + bool Update (void); + +protected: + double m_lastShapeUpdate; + BL_DeformableGameObject* m_gameobj; + +}; + +#endif + diff --git a/source/gameengine/Converter/BL_SkinDeformer.cpp b/source/gameengine/Converter/BL_SkinDeformer.cpp index 0f884674c09..78fc73f21a1 100644 --- a/source/gameengine/Converter/BL_SkinDeformer.cpp +++ b/source/gameengine/Converter/BL_SkinDeformer.cpp @@ -57,6 +57,19 @@ extern "C"{ #define __NLA_DEFNORMALS //#undef __NLA_DEFNORMALS +BL_SkinDeformer::BL_SkinDeformer(struct Object *bmeshobj, + class BL_SkinMeshObject *mesh, + BL_ArmatureObject* arma) + : // + BL_MeshDeformer(bmeshobj, mesh), + m_armobj(arma), + m_lastArmaUpdate(-1), + m_defbase(&bmeshobj->defbase), + m_releaseobject(false) +{ + Mat4CpyMat4(m_obmat, bmeshobj->obmat); +}; + BL_SkinDeformer::BL_SkinDeformer( struct Object *bmeshobj_old, // Blender object that owns the new mesh struct Object *bmeshobj_new, // Blender object that owns the original mesh @@ -65,25 +78,22 @@ BL_SkinDeformer::BL_SkinDeformer( BL_ArmatureObject* arma) : BL_MeshDeformer(bmeshobj_old, mesh), m_armobj(arma), - m_lastUpdate(-1), + m_lastArmaUpdate(-1), m_defbase(&bmeshobj_old->defbase), m_releaseobject(release_object) { - Mat4CpyMat4(m_obmat, bmeshobj_old->obmat); - m_restoremat = true; // this is needed to ensure correct deformation of mesh: // the deformation is done with Blender's armature_deform_verts() function // that takes an object as parameter and not a mesh. The object matrice is used - // in the calculation, so we must force the same matrice to simulate a pure replacement of mesh - Mat4CpyMat4(bmeshobj_old->obmat, bmeshobj_new->obmat); + // in the calculation, so we must use the matrix of the original object to + // simulate a pure replacement of the mesh. + Mat4CpyMat4(m_obmat, bmeshobj_new->obmat); } BL_SkinDeformer::~BL_SkinDeformer() { if(m_releaseobject && m_armobj) m_armobj->Release(); - if (m_restoremat) - Mat4CpyMat4(m_objMesh->obmat, m_obmat); } bool BL_SkinDeformer::Apply(RAS_IPolyMaterial *mat) @@ -98,15 +108,13 @@ bool BL_SkinDeformer::Apply(RAS_IPolyMaterial *mat) MT_Point3 pt; // float co[3]; - if (!m_armobj) + if (!Update()) + // no need to update the cache return false; - Update(); - array = m_pMeshObject->GetVertexCache(mat); mvarray = m_pMeshObject->GetMVertCache(mat); diarray = m_pMeshObject->GetDIndexCache(mat); - // For each array for (i=0; iGetLastFrame()){ + if (m_armobj && m_lastArmaUpdate!=m_armobj->GetLastFrame()){ + float obmat[4][4]; // the original object matrice /* Do all of the posing necessary */ m_armobj->ApplyPose(); @@ -161,14 +170,27 @@ void BL_SkinDeformer::Update(void) for (int v =0; vtotvert; v++) VECCOPY(m_transverts[v], m_bmesh->mvert[v].co); + // save matrix first + Mat4CpyMat4(obmat, m_objMesh->obmat); + // set reference matrix + Mat4CpyMat4(m_objMesh->obmat, m_obmat); + armature_deform_verts( par_arma, m_objMesh, NULL, m_transverts, NULL, m_bmesh->totvert, ARM_DEF_VGROUP, NULL, NULL ); + + // restore matrix + Mat4CpyMat4(m_objMesh->obmat, obmat); + #ifdef __NLA_DEFNORMALS RecalcNormals(); #endif /* Update the current frame */ - m_lastUpdate=m_armobj->GetLastFrame(); + m_lastArmaUpdate=m_armobj->GetLastFrame(); + + /* indicate that the m_transverts and normals are up to date */ + return true; } + return false; } /* XXX note: I propose to drop this function */ diff --git a/source/gameengine/Converter/BL_SkinDeformer.h b/source/gameengine/Converter/BL_SkinDeformer.h index 79f6453a25d..603e716fb1e 100644 --- a/source/gameengine/Converter/BL_SkinDeformer.h +++ b/source/gameengine/Converter/BL_SkinDeformer.h @@ -52,27 +52,20 @@ public: // void SetArmatureController (BL_ArmatureController *cont); virtual void Relink(GEN_Map*map) { - void **h_obj = (*map)[m_armobj]; - if (h_obj){ - SetArmature( (BL_ArmatureObject*)(*h_obj) ); + if (m_armobj){ + void **h_obj = (*map)[m_armobj]; + if (h_obj){ + SetArmature( (BL_ArmatureObject*)(*h_obj) ); + } + else + m_armobj=NULL; } - else - m_armobj=NULL; } void SetArmature (class BL_ArmatureObject *armobj); BL_SkinDeformer(struct Object *bmeshobj, class BL_SkinMeshObject *mesh, - BL_ArmatureObject* arma = NULL) - : // - BL_MeshDeformer(bmeshobj, mesh), - m_armobj(arma), - m_lastUpdate(-1), - m_defbase(&bmeshobj->defbase), - m_restoremat(false), - m_releaseobject(false) - { - }; + BL_ArmatureObject* arma = NULL); /* this second constructor is needed for making a mesh deformable on the fly. */ BL_SkinDeformer(struct Object *bmeshobj_old, @@ -84,16 +77,20 @@ public: virtual void ProcessReplica(); virtual RAS_Deformer *GetReplica(); virtual ~BL_SkinDeformer(); - void Update (void); + bool Update (void); bool Apply (class RAS_IPolyMaterial *polymat); + void ForceUpdate() + { + m_lastArmaUpdate = -1.0; + }; + protected: BL_ArmatureObject* m_armobj; // Our parent object float m_time; - double m_lastUpdate; + double m_lastArmaUpdate; ListBase* m_defbase; - float m_obmat[4][4]; // the original object matrice in case of dynamic mesh replacement - bool m_restoremat; + float m_obmat[4][4]; // the reference matrix for skeleton deform bool m_releaseobject; }; diff --git a/source/gameengine/Converter/BL_SkinMeshObject.cpp b/source/gameengine/Converter/BL_SkinMeshObject.cpp index 69feb72f5dc..9d3702b53a2 100644 --- a/source/gameengine/Converter/BL_SkinMeshObject.cpp +++ b/source/gameengine/Converter/BL_SkinMeshObject.cpp @@ -150,5 +150,63 @@ void BL_SkinMeshObject::Bucketize(double* oglmatrix,void* clientobj,bool useObje } +static get_def_index(Object* ob, const char* vgroup) +{ + bDeformGroup *curdef; + int index = 0; + + for (curdef = (bDeformGroup*)ob->defbase.first; curdef; curdef=(bDeformGroup*)curdef->next, index++) + if (!strcmp(curdef->name, vgroup)) + return index; + return -1; +} + +void BL_SkinMeshObject::CheckWeightCache(Object* obj) +{ + KeyBlock *kb; + int kbindex, defindex; + MDeformVert *dvert= NULL; + int totvert, i, j; + float *weights; + + if (!m_mesh->key) + return; + + for(kbindex=0, kb= (KeyBlock*)m_mesh->key->block.first; kb; kb= (KeyBlock*)kb->next, kbindex++) + { + // first check the cases where the weight must be cleared + if (kb->vgroup[0] == 0 || + m_mesh->dvert == NULL || + (defindex = get_def_index(obj, kb->vgroup)) == -1) { + if (kb->weights) { + MEM_freeN(kb->weights); + kb->weights = NULL; + } + m_cacheWeightIndex[kbindex] = -1; + } else if (m_cacheWeightIndex[kbindex] != defindex) { + // a weight array is required but the cache is not matching + if (kb->weights) { + MEM_freeN(kb->weights); + kb->weights = NULL; + } + + dvert= m_mesh->dvert; + totvert= m_mesh->totvert; + + weights= (float*)MEM_callocN(totvert*sizeof(float), "weights"); + + for (i=0; i < totvert; i++, dvert++) { + for(j=0; jtotweight; j++) { + if (dvert->dw[j].def_nr == defindex) { + weights[i]= dvert->dw[j].weight; + break; + } + } + } + kb->weights = weights; + m_cacheWeightIndex[kbindex] = defindex; + } + } +} diff --git a/source/gameengine/Converter/BL_SkinMeshObject.h b/source/gameengine/Converter/BL_SkinMeshObject.h index 2422d4cd4c9..cc2b8de600e 100644 --- a/source/gameengine/Converter/BL_SkinMeshObject.h +++ b/source/gameengine/Converter/BL_SkinMeshObject.h @@ -33,7 +33,7 @@ #ifdef WIN32 #pragma warning (disable:4786) // get rid of stupid stl-visual compiler debug warning #endif //WIN32 - +#include "MEM_guardedalloc.h" #include "RAS_MeshObject.h" #include "RAS_Deformer.h" #include "RAS_IPolygonMaterial.h" @@ -41,6 +41,7 @@ #include "BL_MeshDeformer.h" #include "DNA_mesh_types.h" +#include "DNA_key_types.h" #include "DNA_meshdata_types.h" typedef vector BL_MVertArray; @@ -105,6 +106,8 @@ class BL_SkinMeshObject : public RAS_MeshObject } protected: + vector m_cacheWeightIndex; + public: struct BL_MDVertMap { RAS_IPolyMaterial *mat; int index; }; vector > m_mvert_to_dvert_mapping; @@ -113,10 +116,33 @@ public: // void Bucketize(double* oglmatrix,void* clientobj,bool useObjectColor,const MT_Vector4& rgbavec,class RAS_BucketManager* bucketmgr); int FindVertexArray(int numverts,RAS_IPolyMaterial* polymat); - BL_SkinMeshObject(int lightlayer) : RAS_MeshObject (lightlayer) - { m_class = 1;}; + BL_SkinMeshObject(Mesh* mesh, int lightlayer) : RAS_MeshObject (mesh, lightlayer) + { + m_class = 1; + if (m_mesh && m_mesh->key) + { + KeyBlock *kb; + int count=0; + // initialize weight cache for shape objects + // count how many keys in this mesh + for(kb= (KeyBlock*)m_mesh->key->block.first; kb; kb= (KeyBlock*)kb->next) + count++; + m_cacheWeightIndex.resize(count,-1); + } + }; - virtual ~BL_SkinMeshObject(){ + virtual ~BL_SkinMeshObject() + { + if (m_mesh && m_mesh->key) + { + KeyBlock *kb; + // remove the weight cache to avoid memory leak + for(kb= (KeyBlock*)m_mesh->key->block.first; kb; kb= (KeyBlock*)kb->next) { + if(kb->weights) + MEM_freeN(kb->weights); + kb->weights= NULL; + } + } }; const vecIndexArrays& GetDIndexCache (RAS_IPolyMaterial* mat) @@ -154,6 +180,8 @@ public: return index; } + // for shape keys, + void CheckWeightCache(struct Object* obj); }; diff --git a/source/gameengine/Converter/KX_ConvertActuators.cpp b/source/gameengine/Converter/KX_ConvertActuators.cpp index 6b594e2e70b..f219c3a1472 100644 --- a/source/gameengine/Converter/KX_ConvertActuators.cpp +++ b/source/gameengine/Converter/KX_ConvertActuators.cpp @@ -84,6 +84,7 @@ #include "DNA_actuator_types.h" #include "DNA_packedFile_types.h" #include "BL_ActionActuator.h" +#include "BL_ShapeActionActuator.h" /* end of blender include block */ #include "BL_BlenderDataConversion.h" @@ -195,6 +196,30 @@ void BL_ConvertActuators(char* maggiename, else printf ("Discarded action actuator from non-armature object [%s]\n", blenderobject->id.name+2); } + case ACT_SHAPEACTION: + { + if (blenderobject->type==OB_MESH){ + bActionActuator* actact = (bActionActuator*) bact->data; + STR_String propname = (actact->name ? actact->name : ""); + + BL_ShapeActionActuator* tmpbaseact = new BL_ShapeActionActuator( + gameobj, + propname, + actact->sta, + actact->end, + actact->act, + actact->type, // + 1, because Blender starts to count at zero, + actact->blendin, + actact->priority, + actact->stridelength + // Ketsji at 1, because zero is reserved for "NoDef" + ); + baseact= tmpbaseact; + break; + } + else + printf ("Discarded shape action actuator from non-mesh object [%s]\n", blenderobject->id.name+2); + } case ACT_IPO: { bIpoActuator* ipoact = (bIpoActuator*) bact->data; diff --git a/source/gameengine/GameLogic/SCA_IObject.h b/source/gameengine/GameLogic/SCA_IObject.h index 4b0fc741b8f..e8251e0ceaa 100644 --- a/source/gameengine/GameLogic/SCA_IObject.h +++ b/source/gameengine/GameLogic/SCA_IObject.h @@ -120,7 +120,7 @@ public: virtual int GetGameObjectType() {return -1;} typedef enum ObjectTypes { - OBJ_ARMATURE=0 + OBJ_ARMATURE=0, }ObjectTypes; }; diff --git a/source/gameengine/Ketsji/KX_GameObject.cpp b/source/gameengine/Ketsji/KX_GameObject.cpp index 5698c106b17..88b936aafd5 100644 --- a/source/gameengine/Ketsji/KX_GameObject.cpp +++ b/source/gameengine/Ketsji/KX_GameObject.cpp @@ -78,6 +78,7 @@ KX_GameObject::KX_GameObject( m_bSuspendDynamics(false), m_bUseObjectColor(false), m_bIsNegativeScaling(false), + m_pBlenderObject(NULL), m_bVisible(true), m_pPhysicsController1(NULL), m_pPhysicsEnvironment(NULL), diff --git a/source/gameengine/Ketsji/KX_GameObject.h b/source/gameengine/Ketsji/KX_GameObject.h index 8a90ec1463a..63a660617c4 100644 --- a/source/gameengine/Ketsji/KX_GameObject.h +++ b/source/gameengine/Ketsji/KX_GameObject.h @@ -55,7 +55,7 @@ struct KX_ClientObjectInfo; class RAS_MeshObject; class KX_IPhysicsController; class PHY_IPhysicsEnvironment; - +struct Object; /** * KX_GameObject is the main class for dynamic objects. @@ -71,6 +71,7 @@ protected: STR_String m_text; int m_layer; std::vector m_meshes; + struct Object* m_pBlenderObject; bool m_bSuspendDynamics; bool m_bUseObjectColor; @@ -359,6 +360,20 @@ public: return m_pSGNode; } + /** + * @section blender object accessor functions. + */ + + struct Object* GetBlenderObject( ) + { + return m_pBlenderObject; + } + + void SetBlenderObject( struct Object* obj) + { + m_pBlenderObject = obj; + } + /** * Set the Scene graph node for this game object. * warning - it is your responsibility to make sure diff --git a/source/gameengine/Ketsji/KX_Scene.cpp b/source/gameengine/Ketsji/KX_Scene.cpp index e4054e07475..fff33ca82fd 100644 --- a/source/gameengine/Ketsji/KX_Scene.cpp +++ b/source/gameengine/Ketsji/KX_Scene.cpp @@ -74,7 +74,7 @@ #include "KX_IPhysicsController.h" #include "KX_BlenderSceneConverter.h" -#include "BL_SkinDeformer.h" +#include "BL_ShapeDeformer.h" #include "BL_DeformableGameObject.h" // to get USE_BULLET! @@ -809,67 +809,80 @@ int KX_Scene::NewRemoveObject(class CValue* gameobj) -void KX_Scene::ReplaceMesh(class CValue* gameobj,void* meshobj) +void KX_Scene::ReplaceMesh(class CValue* obj,void* meshobj) { - KX_GameObject* newobj = static_cast(gameobj); + KX_GameObject* gameobj = static_cast(obj); RAS_MeshObject* mesh = static_cast(meshobj); - const STR_String origMeshName = newobj->GetMesh(0)->GetName(); - - if( !newobj || !mesh ) + if(!gameobj || !mesh) { std::cout << "warning: invalid object, mesh will not be replaced" << std::endl; return; } - newobj->RemoveMeshes(); - newobj->AddMesh(mesh); - - bool isDeformer = (newobj->m_isDeformable && mesh->m_class == 1); - if(isDeformer) - { - /* FindBlendObjByGameObj() can return 0... - In the case of 0 here, - the replicated object that is calling this function - is some how not in the map. (which is strange because it's added) - So we will search the map by the first mesh name - to try to locate it there. If its still not found - spit some message rather than crash - */ - Object* blendobj = static_cast(m_logicmgr->FindBlendObjByGameObj(newobj)); - Object* oldblendobj = static_cast(m_logicmgr->FindBlendObjByGameMeshName(mesh->GetName())); + gameobj->RemoveMeshes(); + gameobj->AddMesh(mesh); - bool parSkin = blendobj && blendobj->parent && blendobj->parent->type == OB_ARMATURE && blendobj->partype==PARSKEL; - bool releaseParent = true; - KX_GameObject* parentobj = newobj->GetParent(); - - - // lookup by mesh name if blendobj is 0 - if( !blendobj && parentobj ) + if (gameobj->m_isDeformable) + { + BL_DeformableGameObject* newobj = static_cast( gameobj ); + + if (newobj->m_pDeformer) { - blendobj = static_cast(m_logicmgr->FindBlendObjByGameMeshName(origMeshName)); - - // replace the mesh on the parent armature - if( blendobj ) - parSkin = parentobj->GetGameObjectType() == SCA_IObject::OBJ_ARMATURE; - - // can't do it - else - std::cout << "warning: child object for " << parentobj->GetName().ReadPtr() - << " not found, and can't create!" << std::endl; + delete newobj->m_pDeformer; + newobj->m_pDeformer = NULL; } - if( blendobj && oldblendobj ) + if (mesh->m_class == 1) { - isDeformer = (static_cast(blendobj->data)->dvert != 0); - BL_DeformableGameObject* deformIter =0; + // we must create a new deformer but which one? + KX_GameObject* parentobj = newobj->GetParent(); + // this always return the original game object (also for replicate) + Object* blendobj = newobj->GetBlenderObject(); + // object that owns the new mesh + Object* oldblendobj = static_cast(m_logicmgr->FindBlendObjByGameMeshName(mesh->GetName())); + Mesh* blendmesh = mesh->GetMesh(); - // armature parent - if( parSkin && isDeformer ) + bool bHasShapeKey = blendmesh->key != NULL && blendmesh->key->type==KEY_RELATIVE; + bool bHasDvert = blendmesh->dvert != NULL; + bool bHasArmature = + parentobj && // current parent is armature + parentobj->GetGameObjectType() == SCA_IObject::OBJ_ARMATURE && + oldblendobj && // needed for mesh deform + blendobj->parent && // original object had armature (not sure this test is needed) + blendobj->parent->type == OB_ARMATURE && + blendobj->partype==PARSKEL && + blendmesh->dvert!=NULL; // mesh has vertex group + bool releaseParent = true; + + if (bHasShapeKey) + { + BL_ShapeDeformer* shapeDeformer; + if (bHasArmature) + { + shapeDeformer = new BL_ShapeDeformer( + newobj, + oldblendobj, blendobj, + static_cast(mesh), + true, + static_cast( parentobj ) + ); + releaseParent= false; + } + else + { + shapeDeformer = new BL_ShapeDeformer( + newobj, + oldblendobj, blendobj, + static_cast(mesh), + false, + NULL + ); + } + newobj->m_pDeformer = shapeDeformer; + } + else if (bHasArmature) { - deformIter = static_cast( newobj ); - delete deformIter->m_pDeformer; - BL_SkinDeformer* skinDeformer = new BL_SkinDeformer( oldblendobj, blendobj, static_cast(mesh), @@ -877,27 +890,22 @@ void KX_Scene::ReplaceMesh(class CValue* gameobj,void* meshobj) static_cast( parentobj ) ); releaseParent= false; - deformIter->m_pDeformer = skinDeformer; + newobj->m_pDeformer = skinDeformer; } - - // normal deformer - if( !parSkin && isDeformer) + else if (bHasDvert) { - deformIter = static_cast( newobj ); - delete deformIter->m_pDeformer; - BL_MeshDeformer* meshdeformer = new BL_MeshDeformer( oldblendobj, static_cast(mesh) ); - - deformIter->m_pDeformer = meshdeformer; + newobj->m_pDeformer = meshdeformer; } + + // release parent reference if its not being used + if( releaseParent && parentobj) + parentobj->Release(); } - // release parent reference if its not being used - if( releaseParent && parentobj) - parentobj->Release(); } - newobj->Bucketize(); + gameobj->Bucketize(); } diff --git a/source/gameengine/Rasterizer/RAS_Deformer.h b/source/gameengine/Rasterizer/RAS_Deformer.h index bea68e203a9..4e8484ab880 100644 --- a/source/gameengine/Rasterizer/RAS_Deformer.h +++ b/source/gameengine/Rasterizer/RAS_Deformer.h @@ -43,7 +43,7 @@ public: virtual ~RAS_Deformer(){}; virtual void Relink(GEN_Map*map)=0; virtual bool Apply(class RAS_IPolyMaterial *polymat)=0; - virtual void Update(void)=0; + virtual bool Update(void)=0; virtual RAS_Deformer *GetReplica()=0; protected: class RAS_MeshObject *m_pMesh; diff --git a/source/gameengine/Rasterizer/RAS_MeshObject.cpp b/source/gameengine/Rasterizer/RAS_MeshObject.cpp index db74110ceea..d7ab88a6b06 100644 --- a/source/gameengine/Rasterizer/RAS_MeshObject.cpp +++ b/source/gameengine/Rasterizer/RAS_MeshObject.cpp @@ -63,12 +63,13 @@ KX_ArrayOptimizer::~KX_ArrayOptimizer() -RAS_MeshObject::RAS_MeshObject(int lightlayer) +RAS_MeshObject::RAS_MeshObject(Mesh* mesh, int lightlayer) : m_bModified(true), m_lightlayer(lightlayer), m_zsort(false), m_MeshMod(true), - m_class(0) + m_class(0), + m_mesh(mesh) { } diff --git a/source/gameengine/Rasterizer/RAS_MeshObject.h b/source/gameengine/Rasterizer/RAS_MeshObject.h index d8e7a3391aa..d9aa133efb2 100644 --- a/source/gameengine/Rasterizer/RAS_MeshObject.h +++ b/source/gameengine/Rasterizer/RAS_MeshObject.h @@ -43,6 +43,7 @@ #include "GEN_HashedPtr.h" +struct Mesh; /** * This class holds an array of vertices and indicies. */ @@ -144,9 +145,10 @@ protected: GEN_Map m_matVertexArrayS; RAS_MaterialBucket::Set m_materials; + Mesh* m_mesh; public: // for now, meshes need to be in a certain layer (to avoid sorting on lights in realtime) - RAS_MeshObject(int lightlayer); + RAS_MeshObject(Mesh* mesh, int lightlayer); virtual ~RAS_MeshObject(); vector m_sortedMaterials; @@ -258,6 +260,7 @@ public: bool MeshModified(); void SetMeshModified(bool v){m_MeshMod = v;} + Mesh* GetMesh() { return m_mesh; } }; From 48c7c9d957896b0f3faa10c72cc86a55b5c39b88 Mon Sep 17 00:00:00 2001 From: Benoit Bolsee Date: Wed, 18 Jun 2008 07:03:47 +0000 Subject: [PATCH 220/246] Forgot to set Id property on new shape action files --- source/gameengine/Converter/BL_ShapeActionActuator.cpp | 2 +- source/gameengine/Converter/BL_ShapeActionActuator.h | 2 +- source/gameengine/Converter/BL_ShapeDeformer.cpp | 2 +- source/gameengine/Converter/BL_ShapeDeformer.h | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/source/gameengine/Converter/BL_ShapeActionActuator.cpp b/source/gameengine/Converter/BL_ShapeActionActuator.cpp index 3e1369e1e9f..58d46d76e5b 100644 --- a/source/gameengine/Converter/BL_ShapeActionActuator.cpp +++ b/source/gameengine/Converter/BL_ShapeActionActuator.cpp @@ -1,5 +1,5 @@ /** -* $Id: BL_ShapeActionActuator.cpp 14444 2008-04-16 22:40:48Z hos $ +* $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** * diff --git a/source/gameengine/Converter/BL_ShapeActionActuator.h b/source/gameengine/Converter/BL_ShapeActionActuator.h index c4236a5208e..434a62a1233 100644 --- a/source/gameengine/Converter/BL_ShapeActionActuator.h +++ b/source/gameengine/Converter/BL_ShapeActionActuator.h @@ -1,5 +1,5 @@ /** - * $Id: BL_ShapeActionActuator.h 14444 2008-04-16 22:40:48Z hos $ + * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** * diff --git a/source/gameengine/Converter/BL_ShapeDeformer.cpp b/source/gameengine/Converter/BL_ShapeDeformer.cpp index 54b1041c328..b8a589c295a 100644 --- a/source/gameengine/Converter/BL_ShapeDeformer.cpp +++ b/source/gameengine/Converter/BL_ShapeDeformer.cpp @@ -1,5 +1,5 @@ /** - * $Id: BL_ShapeDeformer.cpp 14444 2008-04-16 22:40:48Z hos $ + * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** * diff --git a/source/gameengine/Converter/BL_ShapeDeformer.h b/source/gameengine/Converter/BL_ShapeDeformer.h index 920eae86b7e..9bbdde3fb2c 100644 --- a/source/gameengine/Converter/BL_ShapeDeformer.h +++ b/source/gameengine/Converter/BL_ShapeDeformer.h @@ -1,5 +1,5 @@ /** - * $Id: BL_SkinDeformer.h 14444 2008-04-16 22:40:48Z hos $ + * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** * From d39154bb50571c07fa5f2425261f123034b0b1c1 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 18 Jun 2008 09:06:51 +0000 Subject: [PATCH 221/246] bugfix, BGE, use vec.safe_normalized() rather then vec.normalized() because in some cases the ray_cast sensor could crash blender. --- source/gameengine/Ketsji/KX_RayCast.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/gameengine/Ketsji/KX_RayCast.cpp b/source/gameengine/Ketsji/KX_RayCast.cpp index b88741625b6..89e2d645d54 100644 --- a/source/gameengine/Ketsji/KX_RayCast.cpp +++ b/source/gameengine/Ketsji/KX_RayCast.cpp @@ -49,7 +49,7 @@ bool KX_RayCast::RayTest(KX_IPhysicsController* ignore_controller, PHY_IPhysicsE // // returns true if an object was found, false if not. MT_Point3 frompoint(_frompoint); - const MT_Vector3 todir( (topoint - frompoint).normalized() ); + const MT_Vector3 todir( (topoint - frompoint).safe_normalized() ); PHY_IPhysicsController* hit_controller; PHY__Vector3 phy_pos; From 5cd4b6ac90da5e01da3d758480a404c1562cb792 Mon Sep 17 00:00:00 2001 From: Jiri Hnidek Date: Wed, 18 Jun 2008 09:52:31 +0000 Subject: [PATCH 222/246] Small fix to be able to compile Blender. --- source/gameengine/Converter/BL_SkinMeshObject.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/gameengine/Converter/BL_SkinMeshObject.cpp b/source/gameengine/Converter/BL_SkinMeshObject.cpp index 9d3702b53a2..49492923c7c 100644 --- a/source/gameengine/Converter/BL_SkinMeshObject.cpp +++ b/source/gameengine/Converter/BL_SkinMeshObject.cpp @@ -150,7 +150,7 @@ void BL_SkinMeshObject::Bucketize(double* oglmatrix,void* clientobj,bool useObje } -static get_def_index(Object* ob, const char* vgroup) +static int get_def_index(Object* ob, const char* vgroup) { bDeformGroup *curdef; int index = 0; From 3f488f4d7092f8636a7af7860bd9c134f92baecf Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Wed, 18 Jun 2008 10:30:14 +0000 Subject: [PATCH 223/246] * Fix for a crash in game engine vertex array drawing with texfaces. * For 2D filters, don't require opengl 2.0 but just the extensions, so it works on computers without full 2.0 support too. * In debug mode, don't print memory statistics for preview render. --- .../render/intern/source/convertblender.c | 2 +- .../Rasterizer/RAS_2DFilterManager.cpp | 17 ++++++---------- .../RAS_VAOpenGLRasterizer.cpp | 20 +++++++++++++++++-- 3 files changed, 25 insertions(+), 14 deletions(-) diff --git a/source/blender/render/intern/source/convertblender.c b/source/blender/render/intern/source/convertblender.c index 89a0a5ba7cb..796a99ca796 100644 --- a/source/blender/render/intern/source/convertblender.c +++ b/source/blender/render/intern/source/convertblender.c @@ -4434,7 +4434,7 @@ void RE_Database_Free(Render *re) LampRen *lar; /* statistics for debugging render memory usage */ - if(G.f & G_DEBUG) { + if((G.f & G_DEBUG) && (G.rendering)) { if((re->r.scemode & R_PREVIEWBUTS)==0) { BKE_image_print_memlist(); MEM_printmemlist_stats(); diff --git a/source/gameengine/Rasterizer/RAS_2DFilterManager.cpp b/source/gameengine/Rasterizer/RAS_2DFilterManager.cpp index 291890a8dde..e9ab4ccca8d 100644 --- a/source/gameengine/Rasterizer/RAS_2DFilterManager.cpp +++ b/source/gameengine/Rasterizer/RAS_2DFilterManager.cpp @@ -54,11 +54,13 @@ RAS_2DFilterManager::RAS_2DFilterManager(): -texturewidth(-1), textureheight(-1), +texname(-1), texturewidth(-1), textureheight(-1), canvaswidth(-1), canvasheight(-1), -numberoffilters(0),texname(-1) +numberoffilters(0) { - isshadersupported = GLEW_VERSION_2_0; + isshadersupported = GLEW_ARB_shader_objects && + GLEW_ARB_fragment_shader && GLEW_ARB_multitexture; + if(!isshadersupported) { std::cout<<"shaders not supported!" << std::endl; @@ -81,7 +83,6 @@ RAS_2DFilterManager::~RAS_2DFilterManager() unsigned int RAS_2DFilterManager::CreateShaderProgram(char* shadersource) { GLuint program = 0; -#if defined(GL_ARB_shader_objects) && defined(WITH_GLEXT) GLuint fShader = glCreateShaderObjectARB(GL_FRAGMENT_SHADER); GLint success; @@ -117,7 +118,7 @@ unsigned int RAS_2DFilterManager::CreateShaderProgram(char* shadersource) std::cout << "2dFilters - Shader program validation error" << std::endl; return 0; } -#endif + return program; } @@ -151,7 +152,6 @@ unsigned int RAS_2DFilterManager::CreateShaderProgram(int filtermode) void RAS_2DFilterManager::StartShaderProgram(unsigned int shaderprogram) { -#if defined(GL_ARB_shader_objects) && defined(WITH_GLEXT) GLint uniformLoc; glUseProgramObjectARB(shaderprogram); uniformLoc = glGetUniformLocationARB(shaderprogram, "bgl_RenderedTexture"); @@ -178,14 +178,11 @@ void RAS_2DFilterManager::StartShaderProgram(unsigned int shaderprogram) { glUniform1fARB(uniformLoc,textureheight); } -#endif } void RAS_2DFilterManager::EndShaderProgram() { -#if defined(GL_ARB_shader_objects) && defined(WITH_GLEXT) glUseProgramObjectARB(0); -#endif } void RAS_2DFilterManager::SetupTexture() @@ -295,7 +292,6 @@ void RAS_2DFilterManager::EnableFilter(RAS_2DFILTER_MODE mode, int pass, STR_Str { if(!isshadersupported) return; -#if defined(GL_ARB_shader_objects) && defined(WITH_GLEXT) if(pass<0 || pass>=MAX_RENDER_PASS) return; @@ -336,5 +332,4 @@ void RAS_2DFilterManager::EnableFilter(RAS_2DFILTER_MODE mode, int pass, STR_Str m_filters[pass] = CreateShaderProgram(mode); m_enabled[pass] = 1; } -#endif } diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_VAOpenGLRasterizer.cpp b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_VAOpenGLRasterizer.cpp index 67c72aacdcf..ce76318c2ce 100644 --- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_VAOpenGLRasterizer.cpp +++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_VAOpenGLRasterizer.cpp @@ -142,6 +142,9 @@ void RAS_VAOpenGLRasterizer::IndexPrimitives( const vecVertexArray& vertexarrays glColor3d(0,0,0); } + EnableTextures(false); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + // use glDrawElements to draw each vertexarray for (vt=0;vt Date: Wed, 18 Jun 2008 15:22:42 +0000 Subject: [PATCH 224/246] Patch #8882 - Falloff in the wave modifier This patch adds the ability to specify a falloff radius in the Wave modifier. Currently only linear falloff is supported. Thanks to Michael Fox for the patch! --- source/blender/blenkernel/intern/modifier.c | 38 ++++++++++++++++---- source/blender/makesdna/DNA_modifier_types.h | 5 +-- source/blender/src/buttons_editing.c | 6 ++-- 3 files changed, 39 insertions(+), 10 deletions(-) diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c index 861534deb80..eceab9f32d8 100644 --- a/source/blender/blenkernel/intern/modifier.c +++ b/source/blender/blenkernel/intern/modifier.c @@ -4525,13 +4525,13 @@ static void castModifier_deformVertsEM( /* Wave */ -static void waveModifier_initData(ModifierData *md) +static void waveModifier_initData(ModifierData *md) { WaveModifierData *wmd = (WaveModifierData*) md; // whadya know, moved here from Iraq - + wmd->flag |= (MOD_WAVE_X | MOD_WAVE_Y | MOD_WAVE_CYCL | MOD_WAVE_NORM_X | MOD_WAVE_NORM_Y | MOD_WAVE_NORM_Z); - + wmd->objectcenter = NULL; wmd->texture = NULL; wmd->map_object = NULL; @@ -4541,6 +4541,7 @@ static void waveModifier_initData(ModifierData *md) wmd->narrow= 1.5f; wmd->lifetime= 0.0f; wmd->damp= 10.0f; + wmd->falloff= 0.0f; wmd->texmapping = MOD_WAV_MAP_LOCAL; wmd->defgrp_name[0] = 0; } @@ -4560,6 +4561,7 @@ static void waveModifier_copyData(ModifierData *md, ModifierData *target) twmd->starty = wmd->starty; twmd->timeoffs = wmd->timeoffs; twmd->width = wmd->width; + twmd->falloff = wmd->falloff; twmd->objectcenter = wmd->objectcenter; twmd->texture = wmd->texture; twmd->map_object = wmd->map_object; @@ -4770,7 +4772,7 @@ static void waveModifier_do( if(x > wmd->lifetime) { lifefac = x - wmd->lifetime; - + if(lifefac > wmd->damp) lifefac = 0.0; else lifefac = (float)(wmd->height * (1.0 - sqrt(lifefac / wmd->damp))); @@ -4791,6 +4793,8 @@ static void waveModifier_do( float x = co[0] - wmd->startx; float y = co[1] - wmd->starty; float amplit= 0.0f; + float dist = 0.0f; + float falloff_fac = 0.0f; TexResult texres; MDeformWeight *def_weight = NULL; @@ -4813,14 +4817,29 @@ static void waveModifier_do( get_texture_value(wmd->texture, tex_co[i], &texres); } + /*get dist*/ + if(wmd->flag & MOD_WAVE_X) { + if(wmd->flag & MOD_WAVE_Y){ + dist = (float)sqrt(x*x + y*y); + } + else{ + dist = fabs(x); + } + } + else if(wmd->flag & MOD_WAVE_Y) { + dist = fabs(y); + } + + falloff_fac = (1.0-(dist / wmd->falloff)); + CLAMP(falloff_fac,0,1); if(wmd->flag & MOD_WAVE_X) { if(wmd->flag & MOD_WAVE_Y) amplit = (float)sqrt(x*x + y*y); else amplit = x; } - else if(wmd->flag & MOD_WAVE_Y) + else if(wmd->flag & MOD_WAVE_Y) amplit= y; - + /* this way it makes nice circles */ amplit -= (ctime - wmd->timeoffs) * wmd->speed; @@ -4833,12 +4852,19 @@ static void waveModifier_do( if(amplit > -wmd->width && amplit < wmd->width) { amplit = amplit * wmd->narrow; amplit = (float)(1.0 / exp(amplit * amplit) - minfac); + + /*apply texture*/ if(wmd->texture) amplit = amplit * texres.tin; + /*apply weight*/ if(def_weight) amplit = amplit * def_weight->weight; + /*apply falloff*/ + if (wmd->falloff > 0) + amplit = amplit * falloff_fac; + if(mvert) { /* move along normals */ if(wmd->flag & MOD_WAVE_NORM_X) { diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h index 8c1df1450e8..a44d9793062 100644 --- a/source/blender/makesdna/DNA_modifier_types.h +++ b/source/blender/makesdna/DNA_modifier_types.h @@ -329,13 +329,14 @@ typedef struct WaveModifierData { short flag, pad; float startx, starty, height, width; - float narrow, speed, damp; + float narrow, speed, damp, falloff; int texmapping, uvlayer_tmp; char uvlayer_name[32]; - + float timeoffs, lifetime; + float pad1; } WaveModifierData; typedef struct ArmatureModifierData { diff --git a/source/blender/src/buttons_editing.c b/source/blender/src/buttons_editing.c index caa1f2195e2..88b72e5f514 100644 --- a/source/blender/src/buttons_editing.c +++ b/source/blender/src/buttons_editing.c @@ -1792,7 +1792,7 @@ static void draw_modifier(uiBlock *block, Object *ob, ModifierData *md, int *xco height = 143; } else if (md->type==eModifierType_Wave) { WaveModifierData *wmd = (WaveModifierData *)md; - height = 294; + height = 315; if(wmd->texmapping == MOD_WAV_MAP_OBJECT || wmd->texmapping == MOD_WAV_MAP_UV) height += 19; @@ -2154,6 +2154,8 @@ static void draw_modifier(uiBlock *block, Object *ob, ModifierData *md, int *xco uiDefButF(block, NUM, B_MODIFIER_RECALC, "Time end:", lx,(cy-=19),buttonWidth,19, &wmd->timeoffs, -MAXFRAMEF, MAXFRAMEF, 100, 0, "Specify ending frame of the wave"); uiDefButF(block, NUM, B_MODIFIER_RECALC, "Lifetime:", lx,(cy-=19),buttonWidth,19, &wmd->lifetime, -MAXFRAMEF, MAXFRAMEF, 100, 0, "Specify the lifespan of the wave"); uiDefButF(block, NUM, B_MODIFIER_RECALC, "Damptime:", lx,(cy-=19),buttonWidth,19, &wmd->damp, -MAXFRAMEF, MAXFRAMEF, 100, 0, "Specify the dampingtime of the wave"); + uiDefButF(block, NUM, B_MODIFIER_RECALC, "Falloff:", lx,(cy-=19),buttonWidth,19, &wmd->falloff, 0, 100, 100, 0, "Specify the falloff radius of the waves"); + cy -= 9; uiBlockBeginAlign(block); uiDefButF(block, NUM, B_MODIFIER_RECALC, "Sta x:", lx,(cy-=19),113,19, &wmd->startx, -100.0, 100.0, 100, 0, "Starting position for the X axis"); @@ -2190,7 +2192,7 @@ static void draw_modifier(uiBlock *block, Object *ob, ModifierData *md, int *xco &wmd->map_object, "Object to get texture coordinates from"); } - cy -= 9; + cy -= 9; uiBlockBeginAlign(block); uiDefButF(block, NUMSLI, B_MODIFIER_RECALC, "Speed:", lx,(cy-=19),220,19, &wmd->speed, -2.0, 2.0, 0, 0, "Specify the wave speed"); uiDefButF(block, NUMSLI, B_MODIFIER_RECALC, "Height:", lx,(cy-=19),220,19, &wmd->height, -2.0, 2.0, 0, 0, "Specify the amplitude of the wave"); From 1c1f81914c37d3021fe7555277523bf23385add0 Mon Sep 17 00:00:00 2001 From: Chris Want Date: Wed, 18 Jun 2008 17:13:33 +0000 Subject: [PATCH 225/246] == VRML97 export == Patch #10569 from Michalis Kamburelis (sorry for the delay). This patch adds a popup menu that lets the user choose whether they want to export selected, whether thay wanted to export compressed, and whether they want to export the file from blender's "Z up" coordinates to VRML's "Y up". I'm not too crazy about the caching to disk of these options via GetRegistry/SetRegistry, but since this seems to occur in many of the other export scripts I'll leave it as is. --- release/scripts/vrml97_export.py | 72 ++++++++++++++++++++++---------- 1 file changed, 51 insertions(+), 21 deletions(-) diff --git a/release/scripts/vrml97_export.py b/release/scripts/vrml97_export.py index eb3be80c99c..f66f2bc6136 100644 --- a/release/scripts/vrml97_export.py +++ b/release/scripts/vrml97_export.py @@ -3,9 +3,6 @@ Name: 'VRML97 (.wrl)...' Blender: 241 Group: 'Export' -Submenu: 'All Objects...' all -Submenu: 'All Objects compressed...' comp -Submenu: 'Selected Objects...' selected Tooltip: 'Export to VRML97 file (.wrl)' """ @@ -55,7 +52,7 @@ want to export only selected or all relevant objects. import Blender from Blender import Object, Mesh, Lamp, Draw, BGL, \ - Image, Text, sys, Mathutils + Image, Text, sys, Mathutils, Registry from Blender.Scene import Render import math @@ -70,8 +67,9 @@ worldmat = Blender.Texture.Get() filename = Blender.Get('filename') _safeOverwrite = True extension = '' -ARG='' +# Matrices below are used only when export_rotate_z_to_y.val: +# # Blender is Z up, VRML is Y up, both are right hand coordinate # systems, so to go from Blender coords to VRML coords we rotate # by 90 degrees around the X axis. In matrix notation, we have a @@ -633,8 +631,9 @@ class VRML2Export: meshVertexList = me.verts for vertex in meshVertexList: - blenvert = Mathutils.Vector(vertex.co) - vrmlvert = M_blen2vrml * blenvert + vrmlvert = blenvert = Mathutils.Vector(vertex.co) + if export_rotate_z_to_y.val: + vrmlvert = M_blen2vrml * vrmlvert self.writeUnindented("%s %s %s\n " % \ (vrmlvert[0], \ vrmlvert[1], \ @@ -1016,7 +1015,10 @@ class VRML2Export: return ob_matrix = Mathutils.Matrix(ob.getMatrix('worldspace')) - matrix = M_blen2vrml * ob_matrix * M_vrml2blen + if export_rotate_z_to_y.val: + matrix = M_blen2vrml * ob_matrix * M_vrml2blen + else: + matrix = ob_matrix e = matrix.rotationPart().toEuler() v = matrix.translationPart() @@ -1089,7 +1091,7 @@ class VRML2Export: self.writeFog() self.proto = 0 allObj = [] - if ARG == 'selected': + if export_selection_only.val: allObj = list(scene.objects.context) else: allObj = list(scene.objects) @@ -1098,7 +1100,7 @@ class VRML2Export: for thisObj in allObj: self.writeObject(thisObj) - if ARG != 'selected': + if not export_selection_only.val: self.writeScript() self.cleanup() @@ -1213,26 +1215,54 @@ def select_file(filename): wrlexport=VRML2Export(filename) wrlexport.export(scene, world, worldmat) +######################################################### +# UI and Registry utilities +######################################################### + +export_selection_only = Draw.Create(0) +export_rotate_z_to_y = Draw.Create(1) +export_compressed = Draw.Create(0) + +def save_to_registry(): + d = {} + d['selection_only'] = export_selection_only.val + d['rotate_z_to_y'] = export_rotate_z_to_y.val + d['compressed'] = export_compressed.val + Registry.SetKey('vrml97_export', d, True) + +def load_from_registry(): + d = Registry.GetKey('vrml97_export', True) + if d: + try: + export_selection_only.val = d['selection_only'] + export_rotate_z_to_y.val = d['rotate_z_to_y'] + export_compressed.val = d['compressed'] + except: save_to_registry() # If data is not valid, rewrite it. + +def show_popup(): + pup_block = [ + ('Selection Only', export_selection_only, 'Only export objects in visible selection. Else export whole scene.'), + ('Rotate +Z to +Y', export_rotate_z_to_y, 'Rotate such that +Z axis (Blender up) becomes +Y (VRML up).'), + ('Compress', export_compressed, 'Generate a .wrz file (normal VRML compressed by gzip).') + ] + return Draw.PupBlock('Export VRML 97...', pup_block) ######################################################### # main routine ######################################################### -try: - ARG = __script__['arg'] # user selected argument -except: - print "older version" +load_from_registry() -if Blender.Get('version') < 235: - print "Warning: VRML97 export failed, wrong blender version!" - print " You aren't running blender version 2.35 or greater" - print " download a newer version from http://blender3d.org/" -else: - if ARG == 'comp': +# Note that show_popup must be done before Blender.Window.FileSelector, +# because export_compressed affects the suggested extension of resulting +# file. + +if show_popup(): + save_to_registry() + if export_compressed.val: extension=".wrz" from gzip import * else: extension=".wrl" Blender.Window.FileSelector(select_file, "Export VRML97", \ sys.makename(ext=extension)) - From 4ed60f45759a930412f7d480a635f688e32627c3 Mon Sep 17 00:00:00 2001 From: Chris Want Date: Wed, 18 Jun 2008 19:58:05 +0000 Subject: [PATCH 226/246] == VRML97 export == Don't export vertex colors if a mesh doesn't have any (even if a texface has 'shared cols' set). --- release/scripts/vrml97_export.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/release/scripts/vrml97_export.py b/release/scripts/vrml97_export.py index f66f2bc6136..80810dddf75 100644 --- a/release/scripts/vrml97_export.py +++ b/release/scripts/vrml97_export.py @@ -454,6 +454,8 @@ class VRML2Export: if mat: if (mat.mode & Blender.Material.Modes['VCOL_PAINT']): self.vcolors = 1 + else: + self.vcolors = 0 # check if object is wireframe only if ob.drawType == Blender.Object.DrawTypes.WIRE: From fd8e873e012072011846b34a233d149ca5d3bb80 Mon Sep 17 00:00:00 2001 From: Chris Want Date: Wed, 18 Jun 2008 21:16:29 +0000 Subject: [PATCH 227/246] == VRML97 exporter == Faulty indentation of a line sometimes caused a bunch of empty lines to be printed into the TextureCoordinate and texCoodIndex fields (benign error, just ugly). --- release/scripts/vrml97_export.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/release/scripts/vrml97_export.py b/release/scripts/vrml97_export.py index 80810dddf75..b28c7f5bbdc 100644 --- a/release/scripts/vrml97_export.py +++ b/release/scripts/vrml97_export.py @@ -731,8 +731,8 @@ class VRML2Export: round(uv[1], self.tp)) j=j+1 indexStr += "-1" - texIndexList.append(indexStr) - texCoordList.append(coordStr) + texIndexList.append(indexStr) + texCoordList.append(coordStr) self.writeIndented("texCoord TextureCoordinate {\n", 1) self.writeIndented("point [\n", 1) From df8a3882c6dbaa201c586419d9720162c4805fdf Mon Sep 17 00:00:00 2001 From: Benoit Bolsee Date: Wed, 18 Jun 2008 21:22:17 +0000 Subject: [PATCH 228/246] BGE patch #13625: getLinearVelocity() rewrite to use only vector and matrix operations --- source/gameengine/Ketsji/KX_GameObject.cpp | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/source/gameengine/Ketsji/KX_GameObject.cpp b/source/gameengine/Ketsji/KX_GameObject.cpp index 88b936aafd5..eaa6564ba84 100644 --- a/source/gameengine/Ketsji/KX_GameObject.cpp +++ b/source/gameengine/Ketsji/KX_GameObject.cpp @@ -646,8 +646,8 @@ void KX_GameObject::AlignAxisToVect(const MT_Vector3& dir, int axis) MT_Vector3 KX_GameObject::GetLinearVelocity(bool local) { - MT_Vector3 velocity(0.0,0.0,0.0); - MT_Matrix3x3 ori, locvel; + MT_Vector3 velocity(0.0,0.0,0.0), locvel; + MT_Matrix3x3 ori; int i, j; if (m_pPhysicsController1) { @@ -657,11 +657,8 @@ MT_Vector3 KX_GameObject::GetLinearVelocity(bool local) { ori = GetSGNode()->GetWorldOrientation(); - for(i=0; i < 3; i++) - for(j=0; j < 3; j++) - locvel[i][j]= velocity[i]*ori[i][j]; - for(i=0; i < 3; i++) - velocity[i] = locvel[0][i] + locvel[1][i] + locvel[2][i]; + locvel = velocity * ori; + return locvel; } } return velocity; From d6c8d2f701b9c2adb0707e2c46e79c9d3d144d9d Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Thu, 19 Jun 2008 13:41:06 +0000 Subject: [PATCH 229/246] Just make gcc compiler happy (stupid harmless warning) --- source/blender/src/transform_snap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/src/transform_snap.c b/source/blender/src/transform_snap.c index 405b512bb5d..295cfa4574c 100644 --- a/source/blender/src/transform_snap.c +++ b/source/blender/src/transform_snap.c @@ -902,7 +902,7 @@ int snapDerivedMesh(Object *ob, DerivedMesh *dm, float obmat[][4], float ray_sta if (test == 1) { MVert *verts = dm->getVertArray(dm); MFace *faces = dm->getFaceArray(dm); - int *index_array; + int *index_array = NULL; int index = 0; int i; From de7619991c73bdc93294c8ff892e9df92e0f681d Mon Sep 17 00:00:00 2001 From: Benoit Bolsee Date: Thu, 19 Jun 2008 14:40:46 +0000 Subject: [PATCH 230/246] BGE bug fix for new shape action: mesh with multiple materials did not deform properly --- source/gameengine/Converter/BL_ShapeDeformer.cpp | 2 ++ source/gameengine/Converter/BL_SkinDeformer.cpp | 4 +--- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/source/gameengine/Converter/BL_ShapeDeformer.cpp b/source/gameengine/Converter/BL_ShapeDeformer.cpp index b8a589c295a..3ae634905b9 100644 --- a/source/gameengine/Converter/BL_ShapeDeformer.cpp +++ b/source/gameengine/Converter/BL_ShapeDeformer.cpp @@ -118,7 +118,9 @@ bool BL_ShapeDeformer::Update(void) for (int v =0; vtotvert; v++) VECCOPY(m_transverts[v], m_bmesh->mvert[v].co); +#ifdef __NLA_DEFNORMALS RecalcNormals(); +#endif bSkinUpdate = true; } return bSkinUpdate; diff --git a/source/gameengine/Converter/BL_SkinDeformer.cpp b/source/gameengine/Converter/BL_SkinDeformer.cpp index 78fc73f21a1..1015221c392 100644 --- a/source/gameengine/Converter/BL_SkinDeformer.cpp +++ b/source/gameengine/Converter/BL_SkinDeformer.cpp @@ -108,9 +108,7 @@ bool BL_SkinDeformer::Apply(RAS_IPolyMaterial *mat) MT_Point3 pt; // float co[3]; - if (!Update()) - // no need to update the cache - return false; + Update(); array = m_pMeshObject->GetVertexCache(mat); mvarray = m_pMeshObject->GetMVertCache(mat); From a1e78a0cca624061929eb3bae4420be5c16fd540 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 20 Jun 2008 20:54:29 +0000 Subject: [PATCH 231/246] * Documented that get/setOrientation use an inverted rotation matrix * OB prefix is needed when specifying the object for the Message Actuator, this is very bad since other object fields in the BGE dont need this prefix - a real fix would need do_versions to keep old files running. * RotationMatrix was all nans if the rotation vector axis was 0,0,0, Changed so in this case just return a matrix that doesn't rotate anything, spent some angry hours to find these issues, maybe this will save others the hassle ;) --- source/blender/python/api2_2x/Mathutils.c | 49 +++++++++++++---------- source/blender/src/buttons_logic.c | 2 +- source/gameengine/PyDoc/KX_GameObject.py | 4 +- 3 files changed, 30 insertions(+), 25 deletions(-) diff --git a/source/blender/python/api2_2x/Mathutils.c b/source/blender/python/api2_2x/Mathutils.c index e63fc5ef38f..87ac3e3e6ba 100644 --- a/source/blender/python/api2_2x/Mathutils.c +++ b/source/blender/python/api2_2x/Mathutils.c @@ -725,28 +725,33 @@ PyObject *M_Mathutils_RotationMatrix(PyObject * self, PyObject * args) vec->vec[0] /= norm; vec->vec[1] /= norm; vec->vec[2] /= norm; - - //create matrix - cosAngle = (float) cos(angle); - sinAngle = (float) sin(angle); - mat[0] = ((vec->vec[0] * vec->vec[0]) * (1 - cosAngle)) + - cosAngle; - mat[1] = ((vec->vec[0] * vec->vec[1]) * (1 - cosAngle)) + - (vec->vec[2] * sinAngle); - mat[2] = ((vec->vec[0] * vec->vec[2]) * (1 - cosAngle)) - - (vec->vec[1] * sinAngle); - mat[3] = ((vec->vec[0] * vec->vec[1]) * (1 - cosAngle)) - - (vec->vec[2] * sinAngle); - mat[4] = ((vec->vec[1] * vec->vec[1]) * (1 - cosAngle)) + - cosAngle; - mat[5] = ((vec->vec[1] * vec->vec[2]) * (1 - cosAngle)) + - (vec->vec[0] * sinAngle); - mat[6] = ((vec->vec[0] * vec->vec[2]) * (1 - cosAngle)) + - (vec->vec[1] * sinAngle); - mat[7] = ((vec->vec[1] * vec->vec[2]) * (1 - cosAngle)) - - (vec->vec[0] * sinAngle); - mat[8] = ((vec->vec[2] * vec->vec[2]) * (1 - cosAngle)) + - cosAngle; + + if (isnan(vec->vec[0]) || isnan(vec->vec[1]) || isnan(vec->vec[2])) { + /* zero length vector, return an identity matrix, could also return an error */ + mat[0]= mat[4] = mat[8] = 1.0f; + } else { + /* create matrix */ + cosAngle = (float) cos(angle); + sinAngle = (float) sin(angle); + mat[0] = ((vec->vec[0] * vec->vec[0]) * (1 - cosAngle)) + + cosAngle; + mat[1] = ((vec->vec[0] * vec->vec[1]) * (1 - cosAngle)) + + (vec->vec[2] * sinAngle); + mat[2] = ((vec->vec[0] * vec->vec[2]) * (1 - cosAngle)) - + (vec->vec[1] * sinAngle); + mat[3] = ((vec->vec[0] * vec->vec[1]) * (1 - cosAngle)) - + (vec->vec[2] * sinAngle); + mat[4] = ((vec->vec[1] * vec->vec[1]) * (1 - cosAngle)) + + cosAngle; + mat[5] = ((vec->vec[1] * vec->vec[2]) * (1 - cosAngle)) + + (vec->vec[0] * sinAngle); + mat[6] = ((vec->vec[0] * vec->vec[2]) * (1 - cosAngle)) + + (vec->vec[1] * sinAngle); + mat[7] = ((vec->vec[1] * vec->vec[2]) * (1 - cosAngle)) - + (vec->vec[0] * sinAngle); + mat[8] = ((vec->vec[2] * vec->vec[2]) * (1 - cosAngle)) + + cosAngle; + } } else { return EXPP_ReturnPyObjError(PyExc_AttributeError, "Mathutils.RotationMatrix(): unrecognizable axis of rotation type - expected x,y,z or r\n"); diff --git a/source/blender/src/buttons_logic.c b/source/blender/src/buttons_logic.c index 59fedf04e30..b6877b2e2b7 100644 --- a/source/blender/src/buttons_logic.c +++ b/source/blender/src/buttons_logic.c @@ -2149,7 +2149,7 @@ static short draw_actuatorbuttons(bActuator *act, uiBlock *block, short xco, sho uiDefBut(block, TEX, 1, "To: ", (xco+10), (yco-(myline++*24)), (width-20), 19, &ma->toPropName, 0, 31, 0, 0, - "Optional send message to objects with this name only" + "Optional send message to objects with this name only (Prefix name with OB)" ", or empty to broadcast"); #endif diff --git a/source/gameengine/PyDoc/KX_GameObject.py b/source/gameengine/PyDoc/KX_GameObject.py index 678df59e4a9..ff55f975543 100644 --- a/source/gameengine/PyDoc/KX_GameObject.py +++ b/source/gameengine/PyDoc/KX_GameObject.py @@ -50,7 +50,7 @@ class KX_GameObject: """ Sets the game object's orientation. - @type orn: 3x3 rotation matrix, or Quaternion. + @type orn: 3x3 inverted rotation matrix, or Quaternion. @param orn: a rotation matrix specifying the new rotation. """ def alignAxisToVect(vect, axis): @@ -69,7 +69,7 @@ class KX_GameObject: """ Gets the game object's orientation. - @rtype: 3x3 rotation matrix + @rtype: 3x3 inverted rotation matrix @return: The game object's rotation matrix """ def getLinearVelocity(local): From 86d227367b4cdfa839582077e919e64bf6cf1c8d Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Sun, 22 Jun 2008 01:31:29 +0000 Subject: [PATCH 232/246] Bugfix: Update-automatically option in IPO-Editor now updates objects using the active IPO-block as their ObAction when transforming keyframes. --- source/blender/src/transform_generics.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/source/blender/src/transform_generics.c b/source/blender/src/transform_generics.c index eaa4a1d0ecf..6cb7a34d1bc 100644 --- a/source/blender/src/transform_generics.c +++ b/source/blender/src/transform_generics.c @@ -325,7 +325,7 @@ void recalcData(TransInfo *t) else { for (base=G.scene->base.first; base; base=base->next) { /* recalculate scale of selected nla-strips */ - if (base->object->nlastrips.first) { + if (base->object && base->object->nlastrips.first) { Object *bob= base->object; bActionStrip *strip; @@ -398,8 +398,15 @@ void recalcData(TransInfo *t) } } else if(G.sipo->blocktype==ID_OB) { + Object *ob= OBACT; Base *base= FIRSTBASE; + /* only if this if active object has this ipo in an action (assumes that current ipo is in action) */ + if ((ob) && (ob->ipoflag & OB_ACTION_OB) && (G.sipo->pin==0)) { + ob->ctime= -1234567.0f; + DAG_object_flush_update(G.scene, ob, OB_RECALC_OB); + } + while(base) { if(base->object->ipo==G.sipo->ipo) { do_ob_ipo(base->object); From 1ee7a20b93ee3c640b119e1a650e49dcb0f97de9 Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Sun, 22 Jun 2008 01:56:11 +0000 Subject: [PATCH 233/246] Compiler warning fixes (part 1 or 2) --- source/blender/blenkernel/intern/modifier.c | 74 ++++++++++----------- source/blender/include/BIF_oops.h | 2 + source/blender/src/oops.c | 1 - 3 files changed, 39 insertions(+), 38 deletions(-) diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c index eceab9f32d8..a0841bb9f03 100644 --- a/source/blender/blenkernel/intern/modifier.c +++ b/source/blender/blenkernel/intern/modifier.c @@ -1422,10 +1422,10 @@ void vertgroup_flip_name (char *name, int strip_number) } static DerivedMesh *doMirrorOnAxis(MirrorModifierData *mmd, - Object *ob, - DerivedMesh *dm, - int initFlags, - int axis) + Object *ob, + DerivedMesh *dm, + int initFlags, + int axis) { int i; float tolerance = mmd->tolerance; @@ -1434,7 +1434,7 @@ static DerivedMesh *doMirrorOnAxis(MirrorModifierData *mmd, int maxVerts = dm->getNumVerts(dm); int maxEdges = dm->getNumEdges(dm); int maxFaces = dm->getNumFaces(dm); - int vector_size, j, a, b; + int vector_size=0, j, a, b; bDeformGroup *def, *defb; bDeformGroup **vector_def = NULL; int (*indexMap)[2]; @@ -1463,7 +1463,7 @@ static DerivedMesh *doMirrorOnAxis(MirrorModifierData *mmd, if (mmd->mirror_ob) { float obinv[4][4]; - + Mat4Invert(obinv, mmd->mirror_ob->obmat); Mat4MulMat4(mtx, ob->obmat, obinv); Mat4Invert(imtx, mtx); @@ -1474,16 +1474,16 @@ static DerivedMesh *doMirrorOnAxis(MirrorModifierData *mmd, MVert *mv = CDDM_get_vert(result, numVerts); int isShared; float co[3]; - + dm->getVert(dm, i, &inMV); - + VecCopyf(co, inMV.co); - + if (mmd->mirror_ob) { VecMat4MulVecfl(co, mtx, co); } isShared = ABS(co[axis])<=tolerance; - + /* Because the topology result (# of vertices) must be the same if * the mesh data is overridden by vertex cos, have to calc sharedness * based on original coordinates. This is why we test before copy. @@ -1491,10 +1491,10 @@ static DerivedMesh *doMirrorOnAxis(MirrorModifierData *mmd, DM_copy_vert_data(dm, result, i, numVerts, 1); *mv = inMV; numVerts++; - + indexMap[i][0] = numVerts - 1; indexMap[i][1] = !isShared; - + if(isShared) { co[axis] = 0; if (mmd->mirror_ob) { @@ -1506,33 +1506,33 @@ static DerivedMesh *doMirrorOnAxis(MirrorModifierData *mmd, } else { MVert *mv2 = CDDM_get_vert(result, numVerts); MDeformVert *dvert = NULL; - + DM_copy_vert_data(dm, result, i, numVerts, 1); *mv2 = *mv; - + co[axis] = -co[axis]; if (mmd->mirror_ob) { VecMat4MulVecfl(co, imtx, co); } VecCopyf(mv2->co, co); - + if (mmd->flag & MOD_MIR_VGROUP){ dvert = DM_get_vert_data(result, numVerts, CD_MDEFORMVERT); - + if (dvert) { for(j = 0; j < dvert[0].totweight; ++j) { char tmpname[32]; - + if(dvert->dw[j].def_nr < 0 || dvert->dw[j].def_nr >= vector_size) continue; - + def = vector_def[dvert->dw[j].def_nr]; strcpy(tmpname, def->name); vertgroup_flip_name(tmpname,0); - + for(b = 0, defb = ob->defbase.first; defb; defb = defb->next, b++) { @@ -1545,7 +1545,7 @@ static DerivedMesh *doMirrorOnAxis(MirrorModifierData *mmd, } } } - + numVerts++; } } @@ -1553,25 +1553,25 @@ static DerivedMesh *doMirrorOnAxis(MirrorModifierData *mmd, for(i = 0; i < maxEdges; i++) { MEdge inMED; MEdge *med = CDDM_get_edge(result, numEdges); - + dm->getEdge(dm, i, &inMED); - + DM_copy_edge_data(dm, result, i, numEdges, 1); *med = inMED; numEdges++; - + med->v1 = indexMap[inMED.v1][0]; med->v2 = indexMap[inMED.v2][0]; if(initFlags) med->flag |= ME_EDGEDRAW | ME_EDGERENDER; - + if(indexMap[inMED.v1][1] || indexMap[inMED.v2][1]) { MEdge *med2 = CDDM_get_edge(result, numEdges); - + DM_copy_edge_data(dm, result, i, numEdges, 1); *med2 = *med; numEdges++; - + med2->v1 += indexMap[inMED.v1][1]; med2->v2 += indexMap[inMED.v2][1]; } @@ -1580,13 +1580,13 @@ static DerivedMesh *doMirrorOnAxis(MirrorModifierData *mmd, for(i = 0; i < maxFaces; i++) { MFace inMF; MFace *mf = CDDM_get_face(result, numFaces); - + dm->getFace(dm, i, &inMF); - + DM_copy_face_data(dm, result, i, numFaces, 1); *mf = inMF; numFaces++; - + mf->v1 = indexMap[inMF.v1][0]; mf->v2 = indexMap[inMF.v2][0]; mf->v3 = indexMap[inMF.v3][0]; @@ -1598,15 +1598,15 @@ static DerivedMesh *doMirrorOnAxis(MirrorModifierData *mmd, || (mf->v4 && indexMap[inMF.v4][1])) { MFace *mf2 = CDDM_get_face(result, numFaces); static int corner_indices[4] = {2, 1, 0, 3}; - + DM_copy_face_data(dm, result, i, numFaces, 1); *mf2 = *mf; - + mf2->v1 += indexMap[inMF.v1][1]; mf2->v2 += indexMap[inMF.v2][1]; mf2->v3 += indexMap[inMF.v3][1]; if(inMF.v4) mf2->v4 += indexMap[inMF.v4][1]; - + /* mirror UVs if enabled */ if(mmd->flag & (MOD_MIR_MIRROR_U | MOD_MIR_MIRROR_V)) { MTFace *tf = result->getFaceData(result, numFaces, CD_MTFACE); @@ -1620,14 +1620,14 @@ static DerivedMesh *doMirrorOnAxis(MirrorModifierData *mmd, } } } - + /* Flip face normal */ SWAP(int, mf2->v1, mf2->v3); DM_swap_face_data(result, numFaces, corner_indices); - + test_index_face(mf2, &result->faceData, numFaces, inMF.v4?4:3); numFaces++; - } + } } if (vector_def) MEM_freeN(vector_def); @@ -1642,8 +1642,8 @@ static DerivedMesh *doMirrorOnAxis(MirrorModifierData *mmd, } static DerivedMesh *mirrorModifier__doMirror(MirrorModifierData *mmd, - Object *ob, DerivedMesh *dm, - int initFlags) + Object *ob, DerivedMesh *dm, + int initFlags) { DerivedMesh *result = dm; diff --git a/source/blender/include/BIF_oops.h b/source/blender/include/BIF_oops.h index adeac4f3871..2375a918d0e 100644 --- a/source/blender/include/BIF_oops.h +++ b/source/blender/include/BIF_oops.h @@ -43,6 +43,8 @@ struct Camera; struct Texture; struct Lattice; struct bArmature; +struct Tex; + void add_curve_oopslinks(struct Curve *cu, struct Oops *oops, short flag); void add_from_link(struct Oops *from, struct Oops *oops); void add_material_oopslinks(struct Material *ma, struct Oops *oops, short flag); diff --git a/source/blender/src/oops.c b/source/blender/src/oops.c index 99645b5e71f..51d83eff3e6 100644 --- a/source/blender/src/oops.c +++ b/source/blender/src/oops.c @@ -1153,7 +1153,6 @@ void build_oops() } } else if(type==ID_AR && G.soops->visiflag & OOPS_AR) { - bArmature *ar= ob->data; oops= add_test_oops(ob->data); } } From 5372def2b069699809cf9439381b03364137adb5 Mon Sep 17 00:00:00 2001 From: Benoit Bolsee Date: Sun, 22 Jun 2008 14:23:57 +0000 Subject: [PATCH 234/246] BGE patch: add state engine support in the logic bricks. This patch introduces a simple state engine system with the logic bricks. This system features full backward compatibility, multiple active states, multiple state transitions, automatic disabling of sensor and actuators, full GUI support and selective display of sensors and actuators. Note: Python API is available but not documented yet. It will be added asap. State internals =============== The state system is object based. The current state mask is stored in the object as a 32 bit value; each bit set in the mask is an active state. The controllers have a state mask too but only one bit can be set: a controller belongs to a single state. The game engine will only execute controllers that belong to active states. Sensors and actuators don't have a state mask but are effectively attached to states via their links to the controllers. Sensors and actuators can be connected to more than one state. When a controller becomes inactive because of a state change, its links to sensors and actuators are temporarily broken (until the state becomes active again). If an actuator gets isolated, i.e all the links to controllers are broken, it is automatically disabled. If a sensor gets isolated, the game engine will stop calling it to save CPU. It will also reset the sensor internal state so that it can react as if the game just started when it gets reconnected to an active controller. For example, an Always sensor in no pulse mode that is connected to a single state (i.e connected to one or more controllers of a single state) will generate a pulse each time the state becomes active. This feature is not available on all sensors, see the notes below. GUI === This system system is fully configurable through the GUI: the object state mask is visible under the object bar in the controller's colum as an array of buttons just like the 3D view layer mask. Click on a state bit to only display the controllers of that state. You can select more than one state with SHIFT-click. The All button sets all the bits so that you can see all the controllers of the object. The Ini button sets the state mask back to the object default state. You can change the default state of object by first selecting the desired state mask and storing using the menu under the State button. If you define a default state mask, it will be loaded into the object state make when you load the blend file or when you run the game under the blenderplayer. However, when you run the game under Blender, the current selected state mask will be used as the startup state for the object. This allows you to test specific state during the game design. The controller display the state they belong to with a new button in the controller header. When you add a new controller, it is added by default in the lowest enabled state. You can change the controller state by clicking on the button and selecting another state. If more than one state is enabled in the object state mask, controllers are grouped by state for more readibility. The new Sta button in the sensor and actuator column header allows you to display only the sensors and actuators that are linked to visible controllers. A new state actuator is available to modify the state during the game. It defines a bit mask and the operation to apply on the current object state mask: Cpy: the bit mask is copied to the object state mask. Add: the bits that set in the bit mask will be turned on in the object state mask. Sub: the bits that set in the bit mask will be turned off in the object state mask. Inv: the bits that set in the bit mask will be inverted in the objecyy state mask. Notes ===== - Although states have no name, a simply convention consists in using the name of the first controller of the state as the state name. The GUI will support that convention by displaying as a hint the name of the first controller of the state when you move the mouse over a state bit of the object state mask or of the state actuator bit mask. - Each object has a state mask and each object can have a state engine but if several objects are part of a logical group, it is recommended to put the state engine only in the main object and to link the controllers of that object to the sensors and actuators of the different objects. - When loading an old blend file, the state mask of all objects and controllers are initialized to 1 so that all the controllers belong to this single state. This ensures backward compatibility with existing game. - When the state actuator is activated at the same time as other actuators, these actuators are guaranteed to execute before being eventually disabled due to the state change. This is useful for example to send a message or update a property at the time of changing the state. - Sensors that depend on underlying resource won't reset fully when they are isolated. By the time they are acticated again, they will behave as follow: * keyboard sensor: keys already pressed won't be detected. The keyboard sensor is only sensitive to new key press. * collision sensor: objects already colliding won't be detected. Only new collisions are detected. * near and radar sensor: same as collision sensor. --- .../gameengine/ketsji/KX_ketsji.vcproj | 6 + source/blender/blenkernel/intern/sca.c | 3 + source/blender/blenloader/intern/readfile.c | 12 + source/blender/blenloader/intern/writefile.c | 3 + source/blender/include/BIF_butspace.h | 2 + source/blender/include/BIF_interface.h | 1 + source/blender/include/butspace.h | 4 + source/blender/makesdna/DNA_actuator_types.h | 8 + .../blender/makesdna/DNA_controller_types.h | 3 +- source/blender/makesdna/DNA_object_types.h | 6 +- source/blender/makesdna/DNA_sensor_types.h | 1 + source/blender/src/buttons_logic.c | 640 +++++++++++++----- source/blender/src/interface.c | 4 + .../Converter/BL_BlenderDataConversion.cpp | 8 + .../Converter/KX_ConvertActuators.cpp | 15 +- .../Converter/KX_ConvertControllers.cpp | 1 + .../gameengine/GameLogic/SCA_AlwaysSensor.cpp | 7 +- .../gameengine/GameLogic/SCA_AlwaysSensor.h | 2 + source/gameengine/GameLogic/SCA_IActuator.cpp | 10 + source/gameengine/GameLogic/SCA_IActuator.h | 7 + .../gameengine/GameLogic/SCA_IController.cpp | 97 ++- source/gameengine/GameLogic/SCA_IController.h | 4 + source/gameengine/GameLogic/SCA_IObject.cpp | 13 +- source/gameengine/GameLogic/SCA_IObject.h | 19 +- source/gameengine/GameLogic/SCA_ISensor.cpp | 23 +- source/gameengine/GameLogic/SCA_ISensor.h | 10 + .../GameLogic/SCA_JoystickSensor.cpp | 6 +- .../gameengine/GameLogic/SCA_JoystickSensor.h | 1 + .../GameLogic/SCA_KeyboardSensor.cpp | 11 +- .../gameengine/GameLogic/SCA_KeyboardSensor.h | 2 + .../gameengine/GameLogic/SCA_LogicManager.cpp | 20 +- .../gameengine/GameLogic/SCA_MouseSensor.cpp | 6 +- source/gameengine/GameLogic/SCA_MouseSensor.h | 2 +- .../GameLogic/SCA_PropertySensor.cpp | 6 +- .../gameengine/GameLogic/SCA_PropertySensor.h | 1 + .../gameengine/GameLogic/SCA_RandomSensor.cpp | 16 +- .../gameengine/GameLogic/SCA_RandomSensor.h | 1 + .../KXNetwork/KX_NetworkMessageSensor.cpp | 7 +- .../KXNetwork/KX_NetworkMessageSensor.h | 1 + .../gameengine/Ketsji/KX_MouseFocusSensor.cpp | 5 +- .../gameengine/Ketsji/KX_MouseFocusSensor.h | 1 + source/gameengine/Ketsji/KX_RadarSensor.cpp | 1 - source/gameengine/Ketsji/KX_RaySensor.cpp | 14 +- source/gameengine/Ketsji/KX_RaySensor.h | 1 + source/gameengine/Ketsji/KX_Scene.cpp | 2 - source/gameengine/Ketsji/KX_StateActuator.cpp | 207 ++++++ source/gameengine/Ketsji/KX_StateActuator.h | 83 +++ source/gameengine/Ketsji/KX_TouchSensor.cpp | 14 +- source/gameengine/Ketsji/KX_TouchSensor.h | 1 + 49 files changed, 1119 insertions(+), 199 deletions(-) create mode 100644 source/gameengine/Ketsji/KX_StateActuator.cpp create mode 100644 source/gameengine/Ketsji/KX_StateActuator.h diff --git a/projectfiles_vc7/gameengine/ketsji/KX_ketsji.vcproj b/projectfiles_vc7/gameengine/ketsji/KX_ketsji.vcproj index c8173750bdc..af0ba74497a 100644 --- a/projectfiles_vc7/gameengine/ketsji/KX_ketsji.vcproj +++ b/projectfiles_vc7/gameengine/ketsji/KX_ketsji.vcproj @@ -474,6 +474,9 @@ + + @@ -695,6 +698,9 @@ + + diff --git a/source/blender/blenkernel/intern/sca.c b/source/blender/blenkernel/intern/sca.c index 92544f19721..16ca5d7542d 100644 --- a/source/blender/blenkernel/intern/sca.c +++ b/source/blender/blenkernel/intern/sca.c @@ -465,6 +465,9 @@ void init_actuator(bActuator *act) case ACT_PARENT: act->data = MEM_callocN(sizeof( bParentActuator ), "parent act"); break; + case ACT_STATE: + act->data = MEM_callocN(sizeof( bStateActuator ), "state act"); + break; default: ; /* this is very severe... I cannot make any memory for this */ /* logic brick... */ diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index fa7cbb06139..9cfce5e34fa 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -3011,6 +3011,9 @@ static void lib_link_object(FileData *fd, Main *main) bParentActuator *parenta = act->data; parenta->ob = newlibadr(fd, ob->id.lib, parenta->ob); } + else if(act->type==ACT_STATE) { + /* bStateActuator *statea = act->data; */ + } act= act->next; } @@ -3307,11 +3310,19 @@ static void direct_link_object(FileData *fd, Object *ob) direct_link_constraints(fd, &ob->constraints); link_glob_list(fd, &ob->controllers); + if (ob->init_state) { + /* if a known first state is specified, set it so that the game will start ok */ + ob->state = ob->init_state; + } else if (!ob->state) { + ob->state = 1; + } cont= ob->controllers.first; while(cont) { cont->data= newdataadr(fd, cont->data); cont->links= newdataadr(fd, cont->links); test_pointer_array(fd, (void **)&cont->links); + if (cont->state_mask == 0) + cont->state_mask = 1; cont= cont->next; } @@ -7635,6 +7646,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main) } } + /* WATCH IT!!!: pointers from libdata have not been converted yet here! */ /* WATCH IT 2!: Userdef struct init has to be in src/usiblender.c! */ diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c index 2595b95bbf0..9f28e13ff7b 100644 --- a/source/blender/blenloader/intern/writefile.c +++ b/source/blender/blenloader/intern/writefile.c @@ -715,6 +715,9 @@ static void write_actuators(WriteData *wd, ListBase *lb) case ACT_PARENT: writestruct(wd, DATA, "bParentActuator", 1, act->data); break; + case ACT_STATE: + writestruct(wd, DATA, "bStateActuator", 1, act->data); + break; default: ; /* error: don't know how to write this file */ } diff --git a/source/blender/include/BIF_butspace.h b/source/blender/include/BIF_butspace.h index cbbd8013c82..f0b37814947 100644 --- a/source/blender/include/BIF_butspace.h +++ b/source/blender/include/BIF_butspace.h @@ -99,6 +99,8 @@ extern void validate_editbonebutton_cb(void *bonev, void *namev); #define BUTS_ACT_SEL 64 #define BUTS_ACT_ACT 128 #define BUTS_ACT_LINK 256 +#define BUTS_SENS_STATE 512 +#define BUTS_ACT_STATE 1024 /* buttons grid */ diff --git a/source/blender/include/BIF_interface.h b/source/blender/include/BIF_interface.h index fbd4e4ecd91..3da4466d4d3 100644 --- a/source/blender/include/BIF_interface.h +++ b/source/blender/include/BIF_interface.h @@ -185,6 +185,7 @@ void uiDrawBlock(struct uiBlock *block); void uiGetMouse(int win, short *adr); void uiComposeLinks(uiBlock *block); void uiSetButLock(int val, char *lockstr); +uiBut *uiFindInlink(uiBlock *block, void *poin); void uiClearButLock(void); int uiDoBlocks(struct ListBase *lb, int event, int movemouse_quit); void uiSetCurFont(uiBlock *block, int index); diff --git a/source/blender/include/butspace.h b/source/blender/include/butspace.h index 7571d64be91..c0542e3f34c 100644 --- a/source/blender/include/butspace.h +++ b/source/blender/include/butspace.h @@ -52,6 +52,8 @@ struct Image; #define BUTS_ACT_SEL 64 #define BUTS_ACT_ACT 128 #define BUTS_ACT_LINK 256 +#define BUTS_SENS_STATE 512 +#define BUTS_ACT_STATE 1024 /* internal */ @@ -583,6 +585,8 @@ void curvemap_buttons(struct uiBlock *block, struct CurveMapping *cumap, char la #define B_SETACTOR 2715 #define B_SETMAINACTOR 2716 #define B_SETDYNA 2717 +#define B_SET_STATE_BIT 2718 +#define B_INIT_STATE_BIT 2719 /* *********************** */ #define B_FPAINTBUTS 2900 diff --git a/source/blender/makesdna/DNA_actuator_types.h b/source/blender/makesdna/DNA_actuator_types.h index a326f5b01d6..417ba540e2c 100644 --- a/source/blender/makesdna/DNA_actuator_types.h +++ b/source/blender/makesdna/DNA_actuator_types.h @@ -208,6 +208,11 @@ typedef struct bParentActuator { struct Object *ob; } bParentActuator; +typedef struct bStateActuator { + int type; /* 0=Set, 1=Add, 2=Rem, 3=Chg */ + unsigned int mask; /* the bits to change */ +} bStateActuator; + typedef struct bActuator { struct bActuator *next, *prev, *mynew; short type; @@ -279,11 +284,14 @@ typedef struct FreeCamera { #define ACT_2DFILTER 19 #define ACT_PARENT 20 #define ACT_SHAPEACTION 21 +#define ACT_STATE 22 /* actuator flag */ #define ACT_SHOW 1 #define ACT_DEL 2 #define ACT_NEW 4 +#define ACT_LINKED 8 +#define ACT_VISIBLE 16 /* link codes */ #define LINK_SENSOR 0 diff --git a/source/blender/makesdna/DNA_controller_types.h b/source/blender/makesdna/DNA_controller_types.h index 95c9b0d0cf7..cc9215e7d14 100644 --- a/source/blender/makesdna/DNA_controller_types.h +++ b/source/blender/makesdna/DNA_controller_types.h @@ -57,7 +57,7 @@ typedef struct bController { struct bSensor **slinks; short val, valo; - int pad5; + unsigned int state_mask; } bController; @@ -71,6 +71,7 @@ typedef struct bController { #define CONT_SHOW 1 #define CONT_DEL 2 #define CONT_NEW 4 +#define CONT_MASK 8 #endif diff --git a/source/blender/makesdna/DNA_object_types.h b/source/blender/makesdna/DNA_object_types.h index 83168248b9a..c4e8cb4925b 100644 --- a/source/blender/makesdna/DNA_object_types.h +++ b/source/blender/makesdna/DNA_object_types.h @@ -216,7 +216,9 @@ typedef struct Object { struct DerivedMesh *derivedDeform, *derivedFinal; int lastDataMask; /* the custom data layer mask that was last used to calculate derivedDeform and derivedFinal */ - int pad; + unsigned int state; /* bit masks of game controllers that are active */ + unsigned int init_state; /* bit masks of initial state as recorded by the users */ + int pad2; /*#ifdef WITH_VERSE*/ void *vnode; /* pointer at object VerseNode */ @@ -440,6 +442,8 @@ extern Object workob; #define OB_ADDCONT 512 #define OB_ADDACT 1024 #define OB_SHOWCONT 2048 +#define OB_SETSTBIT 4096 +#define OB_INITSTBIT 8192 /* ob->restrictflag */ #define OB_RESTRICT_VIEW 1 diff --git a/source/blender/makesdna/DNA_sensor_types.h b/source/blender/makesdna/DNA_sensor_types.h index 90e2b8f9f41..3fd57a85349 100644 --- a/source/blender/makesdna/DNA_sensor_types.h +++ b/source/blender/makesdna/DNA_sensor_types.h @@ -202,6 +202,7 @@ typedef struct bJoystickSensor { #define SENS_DEL 2 #define SENS_NEW 4 #define SENS_NOT 8 +#define SENS_VISIBLE 16 /* sensor->pulse */ #define SENS_PULSE_CONT 0 diff --git a/source/blender/src/buttons_logic.c b/source/blender/src/buttons_logic.c index b6877b2e2b7..c4fc17bc4d0 100644 --- a/source/blender/src/buttons_logic.c +++ b/source/blender/src/buttons_logic.c @@ -88,6 +88,7 @@ #include "mydevice.h" #include "nla.h" /* For __NLA : Important, do not remove */ #include "butspace.h" // own module +#include "interface.h" /* internals */ void buttons_enji(uiBlock *, Object *); @@ -228,7 +229,7 @@ static void sca_move_sensor(void *datav, void *data2_unused) bSensor *sens_to_delete= datav; int val; Base *base; - bSensor *sens; + bSensor *sens, *tmp; val= pupmenu("Move up%x1|Move down %x2"); @@ -245,12 +246,24 @@ static void sca_move_sensor(void *datav, void *data2_unused) if(sens) { if( val==1 && sens->prev) { - BLI_remlink(&base->object->sensors, sens); - BLI_insertlinkbefore(&base->object->sensors, sens->prev, sens); + for (tmp=sens->prev; tmp; tmp=tmp->prev) { + if (tmp->flag & SENS_VISIBLE) + break; + } + if (tmp) { + BLI_remlink(&base->object->sensors, sens); + BLI_insertlinkbefore(&base->object->sensors, tmp, sens); + } } else if( val==2 && sens->next) { - BLI_remlink(&base->object->sensors, sens); - BLI_insertlink(&base->object->sensors, sens->next, sens); + for (tmp=sens->next; tmp; tmp=tmp->next) { + if (tmp->flag & SENS_VISIBLE) + break; + } + if (tmp) { + BLI_remlink(&base->object->sensors, sens); + BLI_insertlink(&base->object->sensors, tmp, sens); + } } BIF_undo_push("Move sensor"); allqueue(REDRAWBUTSLOGIC, 0); @@ -267,7 +280,7 @@ static void sca_move_controller(void *datav, void *data2_unused) bController *controller_to_del= datav; int val; Base *base; - bController *cont; + bController *cont, *tmp; val= pupmenu("Move up%x1|Move down %x2"); @@ -284,12 +297,27 @@ static void sca_move_controller(void *datav, void *data2_unused) if(cont) { if( val==1 && cont->prev) { - BLI_remlink(&base->object->controllers, cont); - BLI_insertlinkbefore(&base->object->controllers, cont->prev, cont); + /* locate the controller that has the same state mask but is earlier in the list */ + tmp = cont->prev; + while(tmp) { + if(tmp->state_mask & cont->state_mask) + break; + tmp = tmp->prev; + } + if (tmp) { + BLI_remlink(&base->object->controllers, cont); + BLI_insertlinkbefore(&base->object->controllers, tmp, cont); + } } else if( val==2 && cont->next) { + tmp = cont->next; + while(tmp) { + if(tmp->state_mask & cont->state_mask) + break; + tmp = tmp->next; + } BLI_remlink(&base->object->controllers, cont); - BLI_insertlink(&base->object->controllers, cont->next, cont); + BLI_insertlink(&base->object->controllers, tmp, cont); } BIF_undo_push("Move controller"); allqueue(REDRAWBUTSLOGIC, 0); @@ -306,7 +334,7 @@ static void sca_move_actuator(void *datav, void *data2_unused) bActuator *actuator_to_move= datav; int val; Base *base; - bActuator *act; + bActuator *act, *tmp; val= pupmenu("Move up%x1|Move down %x2"); @@ -323,12 +351,25 @@ static void sca_move_actuator(void *datav, void *data2_unused) if(act) { if( val==1 && act->prev) { - BLI_remlink(&base->object->actuators, act); - BLI_insertlinkbefore(&base->object->actuators, act->prev, act); + /* locate the first visible actuators before this one */ + for (tmp = act->prev; tmp; tmp=tmp->prev) { + if (tmp->flag & ACT_VISIBLE) + break; + } + if (tmp) { + BLI_remlink(&base->object->actuators, act); + BLI_insertlinkbefore(&base->object->actuators, tmp, act); + } } else if( val==2 && act->next) { - BLI_remlink(&base->object->actuators, act); - BLI_insertlink(&base->object->actuators, act->next, act); + for (tmp=act->next; tmp; tmp=tmp->next) { + if (tmp->flag & ACT_VISIBLE) + break; + } + if (tmp) { + BLI_remlink(&base->object->actuators, act); + BLI_insertlink(&base->object->actuators, tmp, act); + } } BIF_undo_push("Move actuator"); allqueue(REDRAWBUTSLOGIC, 0); @@ -348,7 +389,7 @@ void do_logic_buts(unsigned short event) bActuator *act; Base *base; Object *ob; - int didit; + int didit, bit; ob= OBACT; if(ob==0) return; @@ -462,6 +503,18 @@ void do_logic_buts(unsigned short event) make_unique_prop_names(cont->name); base->object->scaflag |= OB_SHOWCONT; BLI_addtail(&(base->object->controllers), cont); + /* set the controller state mask from the current object state. + A controller is always in a single state, so select the lowest bit set + from the object state */ + for (bit=0; bit<32; bit++) { + if (base->object->state & (1<state_mask = (1<state_mask == 0) { + /* shouldn't happen, object state is never 0 */ + cont->state_mask = 1; + } } base= base->next; } @@ -469,6 +522,32 @@ void do_logic_buts(unsigned short event) allqueue(REDRAWBUTSLOGIC, 0); break; + case B_SET_STATE_BIT: + base= FIRSTBASE; + while(base) { + if(base->object->scaflag & OB_SETSTBIT) { + base->object->scaflag &= ~OB_SETSTBIT; + base->object->state = 0x3FFFFFFF; + } + base= base->next; + } + allqueue(REDRAWBUTSLOGIC, 0); + break; + + case B_INIT_STATE_BIT: + base= FIRSTBASE; + while(base) { + if(base->object->scaflag & OB_INITSTBIT) { + base->object->scaflag &= ~OB_INITSTBIT; + base->object->state = base->object->init_state; + if (!base->object->state) + base->object->state = 1; + } + base= base->next; + } + allqueue(REDRAWBUTSLOGIC, 0); + break; + case B_CHANGE_CONT: base= FIRSTBASE; while(base) { @@ -505,7 +584,7 @@ void do_logic_buts(unsigned short event) BIF_undo_push("Delete controller"); allqueue(REDRAWBUTSLOGIC, 0); break; - + case B_ADD_ACT: base= FIRSTBASE; while(base) { @@ -717,6 +796,8 @@ static char *actuator_name(int type) return "2D Filter"; case ACT_PARENT: return "Parent"; + case ACT_STATE: + return "State"; } return "unknown"; } @@ -732,21 +813,21 @@ static char *actuator_pup(Object *owner) return "Actuators %t|Action %x15|Motion %x0|Constraint %x9|Ipo %x1" "|Camera %x3|Sound %x5|Property %x6|Edit Object %x10" "|Scene %x11|Random %x13|Message %x14|CD %x16|Game %x17" - "|Visibility %x18|2D Filter %x19|Parent %x20"; + "|Visibility %x18|2D Filter %x19|Parent %x20|State %x22"; break; case OB_MESH: return "Actuators %t|Shape Action %x21|Motion %x0|Constraint %x9|Ipo %x1" "|Camera %x3|Sound %x5|Property %x6|Edit Object %x10" "|Scene %x11|Random %x13|Message %x14|CD %x16|Game %x17" - "|Visibility %x18|2D Filter %x19|Parent %x20"; + "|Visibility %x18|2D Filter %x19|Parent %x20|State %x22"; break; default: return "Actuators %t|Motion %x0|Constraint %x9|Ipo %x1" "|Camera %x3|Sound %x5|Property %x6|Edit Object %x10" "|Scene %x11|Random %x13|Message %x14|CD %x16|Game %x17" - "|Visibility %x18|2D Filter %x19|Parent %x20"; + "|Visibility %x18|2D Filter %x19|Parent %x20|State %x22"; } } @@ -815,7 +896,8 @@ static ID **get_selected_and_linked_obs(short *count, short scavisflag) if(scavisflag & BUTS_ACT_ACT) OBACT->scavisflag |= OB_VIS_ACT; } - if(scavisflag & (BUTS_SENS_LINK|BUTS_CONT_LINK|BUTS_ACT_LINK)) { + /* BUTS_XXX_STATE are similar to BUTS_XXX_LINK for selecting the object */ + if(scavisflag & (BUTS_SENS_LINK|BUTS_CONT_LINK|BUTS_ACT_LINK|BUTS_SENS_STATE|BUTS_ACT_STATE)) { doit= 1; while(doit) { doit= 0; @@ -824,7 +906,7 @@ static ID **get_selected_and_linked_obs(short *count, short scavisflag) while(ob) { /* 1st case: select sensor when controller selected */ - if((scavisflag & BUTS_SENS_LINK) && (ob->scavisflag & OB_VIS_SENS)==0) { + if((scavisflag & (BUTS_SENS_LINK|BUTS_SENS_STATE)) && (ob->scavisflag & OB_VIS_SENS)==0) { sens= ob->sensors.first; while(sens) { for(a=0; atotlinks; a++) { @@ -879,7 +961,7 @@ static ID **get_selected_and_linked_obs(short *count, short scavisflag) } /* 4th case: select actuator when controller selected */ - if( (scavisflag & BUTS_ACT_LINK) && (ob->scavisflag & OB_VIS_CONT)) { + if( (scavisflag & (BUTS_ACT_LINK|BUTS_ACT_STATE)) && (ob->scavisflag & OB_VIS_CONT)) { cont= ob->controllers.first; while(cont) { for(a=0; atotlinks; a++) { @@ -1458,6 +1540,7 @@ static int get_col_actuator(int type) case ACT_GAME: return TH_BUT_SETTING2; case ACT_VISIBILITY: return TH_BUT_NUM; case ACT_CONSTRAINT: return TH_BUT_ACTION; + case ACT_STATE: return TH_BUT_SETTING2; default: return TH_BUT_NEUTRAL; } } @@ -1468,7 +1551,23 @@ static void set_col_actuator(int item, int medium) } -static short draw_actuatorbuttons(bActuator *act, uiBlock *block, short xco, short yco, short width) +char *get_state_name(Object *ob, short bit) +{ + bController *cont; + unsigned int mask; + + mask = (1<controllers.first; + while (cont) { + if (cont->state_mask & mask) { + return cont->name; + } + cont = cont->next; + } + return (char*)""; +} + +static short draw_actuatorbuttons(Object *ob, bActuator *act, uiBlock *block, short xco, short yco, short width) { bSoundActuator *sa = NULL; bCDActuator *cda = NULL; @@ -1487,11 +1586,12 @@ static short draw_actuatorbuttons(bActuator *act, uiBlock *block, short xco, sho bVisibilityActuator *visAct = NULL; bTwoDFilterActuator *tdfa = NULL; bParentActuator *parAct = NULL; + bStateActuator *staAct = NULL; float *fp; short ysize = 0, wval; - char *str; - int myline; + char *str, name[32]; + int myline, stbit; /* yco is at the top of the rect, draw downwards */ uiBlockSetEmboss(block, UI_EMBOSSM); @@ -2022,6 +2122,37 @@ static short draw_actuatorbuttons(bActuator *act, uiBlock *block, short xco, sho break; + case ACT_STATE: + ysize = 34; + + glRects(xco, yco-ysize, xco+width, yco); + uiEmboss((float)xco, + (float)yco-ysize, (float)xco+width, (float)yco, 1); + + staAct = act->data; + + str= "Operation %t|Cpy %x0|Add %x1|Sub %x2|Inv %x3"; + + uiDefButI(block, MENU, B_REDR, str, + xco + 10, yco - 24, 65, 19, &staAct->type, + 0.0, 0.0, 0, 0, + "Select the bit operation on object state mask"); + + for (wval=0; wval<15; wval+=5) { + uiBlockBeginAlign(block); + for (stbit=0; stbit<5; stbit++) { + uiDefButBitI(block, TOG, (1<<(stbit+wval)), 0, "", (short)(xco+85+12*stbit+13*wval), yco-17, 12, 12, (int *)&(staAct->mask), 0, 0, 0, 0, get_state_name(ob, (short)(wval+stbit))); + } + for (stbit=0; stbit<5; stbit++) { + uiDefButBitI(block, TOG, (1<<(stbit+wval+15)), 0, "", (short)(xco+85+12*stbit+13*wval), yco-29, 12, 12, (int *)&(staAct->mask), 0, 0, 0, 0, get_state_name(ob, (short)(wval+stbit+15))); + } + } + uiBlockEndAlign(block); + + yco-= ysize; + + break; + case ACT_RANDOM: ysize = 69; @@ -2596,6 +2727,120 @@ void buttons_bullet(uiBlock *block, Object *ob) uiBlockEndAlign(block); } +static void check_object_state(void *arg1_but, void *arg2_mask) +{ + unsigned int *cont_mask = arg2_mask; + uiBut *but = arg1_but; + + if (*cont_mask == 0 || !(G.qual & LR_SHIFTKEY)) + *cont_mask = (1<retval); + but->retval = B_REDR; +} + +static void check_controller_state_mask(void *arg1_but, void *arg2_mask) +{ + unsigned int *cont_mask = arg2_mask; + uiBut *but = arg1_but; + + /* a controller is always in a single state */ + *cont_mask = (1<retval); + but->retval = B_REDR; +} + +static int first_bit(unsigned int mask) +{ + int bit; + + for (bit=0; bit<32; bit++) { + if (mask & (1<uiblocks, "Controller state mask", UI_EMBOSS, UI_HELV, curarea->win); + + /* use this for a fake extra empy space around the buttons */ + uiDefBut(block, LABEL, 0, "", -5, -5, 200, 34, NULL, 0, 0, 0, 0, ""); + + for (offset=0; offset<15; offset+=5) { + uiBlockBeginAlign(block); + for (stbit=0; stbit<5; stbit++) { + but = uiDefButBitI(block, TOG, (1<<(stbit+offset)), (stbit+offset), "", (short)(xco+12*stbit+13*offset), yco, 12, 12, (int *)&(cont->state_mask), 0, 0, 0, 0, ""); + uiButSetFunc(but, check_controller_state_mask, but, &(cont->state_mask)); + } + for (stbit=0; stbit<5; stbit++) { + but = uiDefButBitI(block, TOG, (1<<(stbit+offset+15)), (stbit+offset+15), "", (short)(xco+12*stbit+13*offset), yco-12, 12, 12, (int *)&(cont->state_mask), 0, 0, 0, 0, ""); + uiButSetFunc(but, check_controller_state_mask, but, &(cont->state_mask)); + } + } + uiBlockEndAlign(block); + + uiBlockSetDirection(block, UI_TOP); + + return block; +} + +static void do_object_state_menu(void *arg, int event) +{ + Object *ob = arg; + + switch (event) { + case 0: + ob->state = 0x3FFFFFFF; + break; + case 1: + ob->state = ob->init_state; + if (!ob->state) + ob->state = 1; + break; + case 2: + ob->init_state = ob->state; + break; + } + allqueue(REDRAWBUTSLOGIC, 0); +} + +static uiBlock *object_state_mask_menu(void *arg_obj) +{ + uiBlock *block; + uiBut *but; + short xco = 0; + + block= uiNewBlock(&curarea->uiblocks, "obstatemenu", UI_EMBOSSP, UI_HELV, curarea->win); + uiBlockSetButmFunc(block, do_object_state_menu, arg_obj); + + uiDefBut(block, BUTM, 1, "Set all bits", 0, (short)(xco-=20), 160, 19, NULL, 0.0, 0.0, 1, 0, ""); + uiDefBut(block, BUTM, 1, "Recall init state", 0, (short)(xco-=20), 160, 19, NULL, 0.0, 0.0, 1, 1, ""); + uiDefBut(block, SEPR, 0, "", 0, (short)(xco-=6), 160, 6, NULL, 0.0, 0.0, 0, 0, ""); + uiDefBut(block, BUTM, 1, "Store init state", 0, (short)(xco-=20), 160, 19, NULL, 0.0, 0.0, 1, 2, ""); + + uiBlockSetDirection(block, UI_TOP); + return block; +} + +static int is_sensor_linked(uiBlock *block, bSensor *sens) +{ + bController *cont; + int i, count; + + for (count=0, i=0; itotlinks; i++) { + cont = sens->links[i]; + if (uiFindInlink(block, cont) != NULL) + return 1; + } + return 0; +} + /* never used, see CVS 1.134 for the code */ /* static FreeCamera *new_freecamera(void) */ @@ -2614,7 +2859,7 @@ void logic_buts(void) uiBlock *block; uiBut *but; World *wrld; - int a; + int a, iact, stbit, offset; short xco, yco, count, width, ycoo; char *pupstr, name[32]; @@ -2686,78 +2931,27 @@ void logic_buts(void) uiClearButLock(); idar= get_selected_and_linked_obs(&count, G.buts->scaflag); - - /* ******************************* */ - xco= 375; yco= 170; width= 230; - uiBlockSetEmboss(block, UI_EMBOSSP); - uiDefBlockBut(block, sensor_menu, NULL, "Sensors", xco-10, yco+35, 80, 19, ""); - uiBlockSetEmboss(block, UI_EMBOSS); - - uiBlockBeginAlign(block); - uiDefButBitS(block, TOG, BUTS_SENS_SEL, B_REDR, "Sel", xco+110, yco+35, (width-100)/3, 19, &G.buts->scaflag, 0, 0, 0, 0, "Show all selected Objects"); - uiDefButBitS(block, TOG, BUTS_SENS_ACT, B_REDR, "Act", xco+110+(width-100)/3, yco+35, (width-100)/3, 19, &G.buts->scaflag, 0, 0, 0, 0, "Show active Object"); - uiDefButBitS(block, TOG, BUTS_SENS_LINK, B_REDR, "Link", xco+110+2*(width-100)/3, yco+35, (width-100)/3, 19, &G.buts->scaflag, 0, 0, 0, 0, "Show linked Objects to Controller"); - uiBlockEndAlign(block); - + /* clean ACT_LINKED and ACT_VISIBLE of all potentially visible actuators so that + we can determine which is actually linked/visible */ for(a=0; ascavisflag & OB_VIS_SENS) == 0) continue; - - /* presume it is only objects for now */ - uiBlockSetEmboss(block, UI_EMBOSS); - uiBlockBeginAlign(block); - if(ob->sensors.first) uiSetCurFont(block, UI_HELVB); - uiDefButBitS(block, TOG, OB_SHOWSENS, B_REDR, ob->id.name+2,(short)(xco-10), yco, (short)(width-30), 19, &ob->scaflag, 0, 31, 0, 0, "Object name, click to show/hide sensors"); - if(ob->sensors.first) uiSetCurFont(block, UI_HELV); - uiDefButBitS(block, TOG, OB_ADDSENS, B_ADD_SENS, "Add",(short)(xco+width-40), yco, 50, 19, &ob->scaflag, 0, 0, 0, 0, "Add a new Sensor"); - uiBlockEndAlign(block); - yco-=20; - - if(ob->scaflag & OB_SHOWSENS) { - - sens= ob->sensors.first; - while(sens) { - uiBlockSetEmboss(block, UI_EMBOSSM); - uiDefIconButBitS(block, TOG, SENS_DEL, B_DEL_SENS, ICON_X, xco, yco, 22, 19, &sens->flag, 0, 0, 0, 0, "Delete Sensor"); - uiDefIconButBitS(block, ICONTOG, SENS_SHOW, B_REDR, ICON_RIGHTARROW, (short)(xco+width-22), yco, 22, 19, &sens->flag, 0, 0, 0, 0, "Sensor settings"); - - ycoo= yco; - if(sens->flag & SENS_SHOW) - { - uiDefButS(block, MENU, B_CHANGE_SENS, sensor_pup(), (short)(xco+22), yco, 100, 19, &sens->type, 0, 0, 0, 0, "Sensor type"); - but= uiDefBut(block, TEX, 1, "", (short)(xco+122), yco, (short)(width-144), 19, sens->name, 0, 31, 0, 0, "Sensor name"); - uiButSetFunc(but, make_unique_prop_names_cb, sens->name, (void*) 0); - - sens->otype= sens->type; - yco= draw_sensorbuttons(sens, block, xco, yco, width,ob->id.name); - if(yco-6 < ycoo) ycoo= (yco+ycoo-20)/2; - } - else { - set_col_sensor(sens->type, 1); - glRecti(xco+22, yco, xco+width-22,yco+19); - but= uiDefBut(block, LABEL, 0, sensor_name(sens->type), (short)(xco+22), yco, 100, 19, sens, 0, 0, 0, 0, ""); - uiButSetFunc(but, sca_move_sensor, sens, NULL); - but= uiDefBut(block, LABEL, 0, sens->name, (short)(xco+122), yco, (short)(width-144), 19, sens, 0, 31, 0, 0, ""); - uiButSetFunc(but, sca_move_sensor, sens, NULL); - } - - but= uiDefIconBut(block, LINK, 0, ICON_LINK, (short)(xco+width), ycoo, 19, 19, NULL, 0, 0, 0, 0, ""); - uiSetButLink(but, NULL, (void ***)&(sens->links), &sens->totlinks, LINK_SENSOR, LINK_CONTROLLER); - - yco-=20; - - sens= sens->next; - } - yco-= 6; + act= ob->actuators.first; + while(act) { + act->flag &= ~(ACT_LINKED|ACT_VISIBLE); + act = act->next; + } + /* same for sensors */ + sens= ob->sensors.first; + while(sens) { + sens->flag &= ~(SENS_VISIBLE); + sens = sens->next; } } - + + /* start with the controller because we need to know which one is visible */ /* ******************************* */ - xco= 675; yco= 170; width= 230; + xco= 695; yco= 170; width= 275; uiBlockSetEmboss(block, UI_EMBOSSP); uiDefBlockBut(block, controller_menu, NULL, "Controllers", xco-10, yco+35, 100, 19, ""); @@ -2785,59 +2979,193 @@ void logic_buts(void) if(ob->controllers.first) uiSetCurFont(block, UI_HELV); uiDefButBitS(block, TOG, OB_ADDCONT, B_ADD_CONT, "Add",(short)(xco+width-40), yco, 50, 19, &ob->scaflag, 0, 0, 0, 0, "Add a new Controller"); uiBlockEndAlign(block); - yco-=20; + yco-=17; + /* mark all actuators linked to these controllers */ + /* note that some of these actuators could be from objects that are not in the display list. + It's ok because those actuators will not be displayed here */ + cont= ob->controllers.first; + while(cont) { + for (iact=0; iacttotlinks; iact++) { + act = cont->links[iact]; + act->flag |= ACT_LINKED; + } + cont = cont->next; + } + if(ob->scaflag & OB_SHOWCONT) { - - cont= ob->controllers.first; - while(cont) { - uiBlockSetEmboss(block, UI_EMBOSSM); - uiDefIconButBitS(block, TOG, CONT_DEL, B_DEL_CONT, ICON_X, xco, yco, 22, 19, &cont->flag, 0, 0, 0, 0, "Delete Controller"); - uiDefIconButBitS(block, ICONTOG, CONT_SHOW, B_REDR, ICON_RIGHTARROW, (short)(xco+width-22), yco, 22, 19, &cont->flag, 0, 0, 0, 0, "Controller settings"); - - if(cont->flag & CONT_SHOW) { - cont->otype= cont->type; - uiDefButS(block, MENU, B_CHANGE_CONT, controller_pup(),(short)(xco+22), yco, 100, 19, &cont->type, 0, 0, 0, 0, "Controller type"); - but= uiDefBut(block, TEX, 1, "", (short)(xco+122), yco, (short)(width-144), 19, cont->name, 0, 31, 0, 0, "Controller name"); - uiButSetFunc(but, make_unique_prop_names_cb, cont->name, (void*) 0); - - ycoo= yco; - yco= draw_controllerbuttons(cont, block, xco, yco, width); - if(yco-6 < ycoo) ycoo= (yco+ycoo-20)/2; + + /* first show the state */ + uiBlockSetEmboss(block, UI_EMBOSSP); + uiDefBlockBut(block, object_state_mask_menu, ob, "State", (short)(xco-10), (short)(yco-10), 40, 19, "Object state menu: store and retrieve initial state"); + uiBlockSetEmboss(block, UI_EMBOSS); + if (!ob->state) + ob->state = 1; + for (offset=0; offset<15; offset+=5) { + uiBlockBeginAlign(block); + for (stbit=0; stbit<5; stbit++) { + but = uiDefButBitI(block, TOG, 1<<(stbit+offset), stbit+offset, "", (short)(xco+35+12*stbit+13*offset), yco, 12, 12, (int *)&(ob->state), 0, 0, 0, 0, get_state_name(ob, (short)(stbit+offset))); + uiButSetFunc(but, check_object_state, but, &(ob->state)); } - else { - cpack(0x999999); - glRecti(xco+22, yco, xco+width-22,yco+19); - but= uiDefBut(block, LABEL, 0, controller_name(cont->type), (short)(xco+22), yco, 100, 19, cont, 0, 0, 0, 0, "Controller type"); - uiButSetFunc(but, sca_move_controller, cont, NULL); - but= uiDefBut(block, LABEL, 0, cont->name,(short)(xco+122), yco,(short)(width-144), 19, cont, 0, 0, 0, 0, "Controller name"); - uiButSetFunc(but, sca_move_controller, cont, NULL); - ycoo= yco; + for (stbit=0; stbit<5; stbit++) { + but = uiDefButBitI(block, TOG, 1<<(stbit+offset+15), stbit+offset+15, "", (short)(xco+35+12*stbit+13*offset), yco-12, 12, 12, (int *)&(ob->state), 0, 0, 0, 0, get_state_name(ob, (short)(stbit+offset+15))); + uiButSetFunc(but, check_object_state, but, &(ob->state)); } + } + uiBlockBeginAlign(block); + uiDefButBitS(block, TOG, OB_SETSTBIT, B_SET_STATE_BIT, "All",(short)(xco+235), yco-10, 25, 19, &ob->scaflag, 0, 0, 0, 0, "Set all state bits"); + uiDefButBitS(block, TOG, OB_INITSTBIT, B_INIT_STATE_BIT, "Ini",(short)(xco+260), yco-10, 25, 19, &ob->scaflag, 0, 0, 0, 0, "Set the initial state"); + uiBlockEndAlign(block); + + yco-=35; - but= uiDefIconBut(block, LINK, 0, ICON_LINK, (short)(xco+width), ycoo, 19, 19, NULL, 0, 0, 0, 0, ""); - uiSetButLink(but, NULL, (void ***)&(cont->links), &cont->totlinks, LINK_CONTROLLER, LINK_ACTUATOR); - - uiDefIconBut(block, INLINK, 0, ICON_INLINK,(short)(xco-19), ycoo, 19, 19, cont, LINK_CONTROLLER, 0, 0, 0, ""); - - yco-=20; + /* display only the controllers that match the current state */ + offset = 0; + for (stbit=0; stbit<32; stbit++) { + if (!(ob->state & (1<controllers.first; + while(cont) { + if (cont->state_mask & (1<totlinks; iact++) { + act = cont->links[iact]; + act->flag |= ACT_VISIBLE; + } + uiBlockSetEmboss(block, UI_EMBOSSM); + uiDefIconButBitS(block, TOG, CONT_DEL, B_DEL_CONT, ICON_X, xco, yco, 22, 19, &cont->flag, 0, 0, 0, 0, "Delete Controller"); + uiDefIconButBitS(block, ICONTOG, CONT_SHOW, B_REDR, ICON_RIGHTARROW, (short)(xco+width-22), yco, 22, 19, &cont->flag, 0, 0, 0, 0, "Controller settings"); + uiBlockSetEmboss(block, UI_EMBOSSP); + sprintf(name, "%d", first_bit(cont->state_mask)+1); + uiDefBlockBut(block, controller_state_mask_menu, cont, name, (short)(xco+width-44), yco, 22, 19, "Set controller state mask"); + uiBlockSetEmboss(block, UI_EMBOSSM); - cont= cont->next; + if(cont->flag & CONT_SHOW) { + cont->otype= cont->type; + uiDefButS(block, MENU, B_CHANGE_CONT, controller_pup(),(short)(xco+22), yco, 100, 19, &cont->type, 0, 0, 0, 0, "Controller type"); + but= uiDefBut(block, TEX, 1, "", (short)(xco+122), yco, (short)(width-166), 19, cont->name, 0, 31, 0, 0, "Controller name"); + uiButSetFunc(but, make_unique_prop_names_cb, cont->name, (void*) 0); + + ycoo= yco; + yco= draw_controllerbuttons(cont, block, xco, yco, width); + if(yco-6 < ycoo) ycoo= (yco+ycoo-20)/2; + } + else { + cpack(0x999999); + glRecti(xco+22, yco, xco+width-22,yco+19); + but= uiDefBut(block, LABEL, 0, controller_name(cont->type), (short)(xco+22), yco, 100, 19, cont, 0, 0, 0, 0, "Controller type"); + uiButSetFunc(but, sca_move_controller, cont, NULL); + but= uiDefBut(block, LABEL, 0, cont->name,(short)(xco+122), yco,(short)(width-166), 19, cont, 0, 0, 0, 0, "Controller name"); + uiButSetFunc(but, sca_move_controller, cont, NULL); + ycoo= yco; + } + + but= uiDefIconBut(block, LINK, 0, ICON_LINK, (short)(xco+width), ycoo, 19, 19, NULL, 0, 0, 0, 0, ""); + uiSetButLink(but, NULL, (void ***)&(cont->links), &cont->totlinks, LINK_CONTROLLER, LINK_ACTUATOR); + + uiDefIconBut(block, INLINK, 0, ICON_INLINK,(short)(xco-19), ycoo, 19, 19, cont, LINK_CONTROLLER, 0, 0, 0, ""); + /* offset is >0 if at least one controller was displayed */ + offset++; + yco-=20; + } + cont= cont->next; + } + } yco-= 6; } } /* ******************************* */ - xco= 985; yco= 170; width= 280; + xco= 375; yco= 170; width= 250; + + uiBlockSetEmboss(block, UI_EMBOSSP); + uiDefBlockBut(block, sensor_menu, NULL, "Sensors", xco-10, yco+35, 70, 19, ""); + uiBlockSetEmboss(block, UI_EMBOSS); + + uiBlockBeginAlign(block); + uiDefButBitS(block, TOG, BUTS_SENS_SEL, B_REDR, "Sel", xco+80, yco+35, (width-70)/4, 19, &G.buts->scaflag, 0, 0, 0, 0, "Show all selected Objects"); + uiDefButBitS(block, TOG, BUTS_SENS_ACT, B_REDR, "Act", xco+80+(width-70)/4, yco+35, (width-70)/4, 19, &G.buts->scaflag, 0, 0, 0, 0, "Show active Object"); + uiDefButBitS(block, TOG, BUTS_SENS_LINK, B_REDR, "Link", xco+80+2*(width-70)/4, yco+35, (width-70)/4, 19, &G.buts->scaflag, 0, 0, 0, 0, "Show linked Objects to Controller"); + uiDefButBitS(block, TOG, BUTS_SENS_STATE, B_REDR, "Sta", xco+80+3*(width-70)/4, yco+35, (width-70)/4, 19, &G.buts->scaflag, 0, 0, 0, 0, "Show only sensors connected to active states"); + uiBlockEndAlign(block); + + for(a=0; ascavisflag & OB_VIS_SENS) == 0) continue; + + /* presume it is only objects for now */ + uiBlockSetEmboss(block, UI_EMBOSS); + uiBlockBeginAlign(block); + if(ob->sensors.first) uiSetCurFont(block, UI_HELVB); + uiDefButBitS(block, TOG, OB_SHOWSENS, B_REDR, ob->id.name+2,(short)(xco-10), yco, (short)(width-30), 19, &ob->scaflag, 0, 31, 0, 0, "Object name, click to show/hide sensors"); + if(ob->sensors.first) uiSetCurFont(block, UI_HELV); + uiDefButBitS(block, TOG, OB_ADDSENS, B_ADD_SENS, "Add",(short)(xco+width-40), yco, 50, 19, &ob->scaflag, 0, 0, 0, 0, "Add a new Sensor"); + uiBlockEndAlign(block); + yco-=20; + + if(ob->scaflag & OB_SHOWSENS) { + + sens= ob->sensors.first; + while(sens) { + if (!(G.buts->scaflag & BUTS_SENS_STATE) || + sens->totlinks == 0 || /* always display sensor without links so that is can be edited */ + is_sensor_linked(block, sens)) { + sens->flag |= SENS_VISIBLE; + uiBlockSetEmboss(block, UI_EMBOSSM); + uiDefIconButBitS(block, TOG, SENS_DEL, B_DEL_SENS, ICON_X, xco, yco, 22, 19, &sens->flag, 0, 0, 0, 0, "Delete Sensor"); + uiDefIconButBitS(block, ICONTOG, SENS_SHOW, B_REDR, ICON_RIGHTARROW, (short)(xco+width-22), yco, 22, 19, &sens->flag, 0, 0, 0, 0, "Sensor settings"); + + ycoo= yco; + if(sens->flag & SENS_SHOW) + { + uiDefButS(block, MENU, B_CHANGE_SENS, sensor_pup(), (short)(xco+22), yco, 100, 19, &sens->type, 0, 0, 0, 0, "Sensor type"); + but= uiDefBut(block, TEX, 1, "", (short)(xco+122), yco, (short)(width-144), 19, sens->name, 0, 31, 0, 0, "Sensor name"); + uiButSetFunc(but, make_unique_prop_names_cb, sens->name, (void*) 0); + + sens->otype= sens->type; + yco= draw_sensorbuttons(sens, block, xco, yco, width,ob->id.name); + if(yco-6 < ycoo) ycoo= (yco+ycoo-20)/2; + } + else { + set_col_sensor(sens->type, 1); + glRecti(xco+22, yco, xco+width-22,yco+19); + but= uiDefBut(block, LABEL, 0, sensor_name(sens->type), (short)(xco+22), yco, 100, 19, sens, 0, 0, 0, 0, ""); + uiButSetFunc(but, sca_move_sensor, sens, NULL); + but= uiDefBut(block, LABEL, 0, sens->name, (short)(xco+122), yco, (short)(width-144), 19, sens, 0, 31, 0, 0, ""); + uiButSetFunc(but, sca_move_sensor, sens, NULL); + } + + but= uiDefIconBut(block, LINK, 0, ICON_LINK, (short)(xco+width), ycoo, 19, 19, NULL, 0, 0, 0, 0, ""); + uiSetButLink(but, NULL, (void ***)&(sens->links), &sens->totlinks, LINK_SENSOR, LINK_CONTROLLER); + + yco-=20; + } + sens= sens->next; + } + yco-= 6; + } + } + + /* ******************************* */ + xco= 1040; yco= 170; width= 280; uiBlockSetEmboss(block, UI_EMBOSSP); - uiDefBlockBut(block, actuator_menu, NULL, "Actuators", xco-10, yco+35, 100, 19, ""); + uiDefBlockBut(block, actuator_menu, NULL, "Actuators", xco-10, yco+35, 90, 19, ""); uiBlockSetEmboss(block, UI_EMBOSS); uiBlockBeginAlign(block); - uiDefButBitS(block, TOG, BUTS_ACT_SEL, B_REDR, "Sel", xco+110, yco+35, (width-110)/3, 19, &G.buts->scaflag, 0, 0, 0, 0, "Show all selected Objects"); - uiDefButBitS(block, TOG, BUTS_ACT_ACT, B_REDR, "Act", xco+110+(width-110)/3, yco+35, (width-110)/3, 19, &G.buts->scaflag, 0, 0, 0, 0, "Show active Object"); - uiDefButBitS(block, TOG, BUTS_ACT_LINK, B_REDR, "Link", xco+110+2*(width-110)/3, yco+35, (width-110)/3, 19, &G.buts->scaflag, 0, 0, 0, 0, "Show linked Objects to Controller"); + uiDefButBitS(block, TOG, BUTS_ACT_SEL, B_REDR, "Sel", xco+110, yco+35, (width-100)/4, 19, &G.buts->scaflag, 0, 0, 0, 0, "Show all selected Objects"); + uiDefButBitS(block, TOG, BUTS_ACT_ACT, B_REDR, "Act", xco+110+(width-100)/4, yco+35, (width-100)/4, 19, &G.buts->scaflag, 0, 0, 0, 0, "Show active Object"); + uiDefButBitS(block, TOG, BUTS_ACT_LINK, B_REDR, "Link", xco+110+2*(width-100)/4, yco+35, (width-100)/4, 19, &G.buts->scaflag, 0, 0, 0, 0, "Show linked Objects to Controller"); + uiDefButBitS(block, TOG, BUTS_ACT_STATE, B_REDR, "Sta", xco+110+3*(width-100)/4, yco+35, (width-100)/4, 19, &G.buts->scaflag, 0, 0, 0, 0, "Show only actuators connected to active states"); uiBlockEndAlign(block); for(a=0; aactuators.first; while(act) { - uiBlockSetEmboss(block, UI_EMBOSSM); - uiDefIconButBitS(block, TOG, ACT_DEL, B_DEL_ACT, ICON_X, xco, yco, 22, 19, &act->flag, 0, 0, 0, 0, "Delete Actuator"); - uiDefIconButBitS(block, ICONTOG, ACT_SHOW, B_REDR, ICON_RIGHTARROW, (short)(xco+width-22), yco, 22, 19, &act->flag, 0, 0, 0, 0, "Actuator settings"); + if (!(G.buts->scaflag & BUTS_ACT_STATE) || + !(act->flag & ACT_LINKED) || /* always display actuators without links so that is can be edited */ + (act->flag & ACT_VISIBLE)) { /* this actuator has visible connection, display it */ + act->flag |= ACT_VISIBLE; /* mark the actuator as visible to help implementing the up/down action */ + uiBlockSetEmboss(block, UI_EMBOSSM); + uiDefIconButBitS(block, TOG, ACT_DEL, B_DEL_ACT, ICON_X, xco, yco, 22, 19, &act->flag, 0, 0, 0, 0, "Delete Actuator"); + uiDefIconButBitS(block, ICONTOG, ACT_SHOW, B_REDR, ICON_RIGHTARROW, (short)(xco+width-22), yco, 22, 19, &act->flag, 0, 0, 0, 0, "Actuator settings"); - if(act->flag & ACT_SHOW) { - act->otype= act->type; - uiDefButS(block, MENU, B_CHANGE_ACT, actuator_pup(ob), (short)(xco+22), yco, 100, 19, &act->type, 0, 0, 0, 0, "Actuator type"); - but= uiDefBut(block, TEX, 1, "", (short)(xco+122), yco, (short)(width-144), 19, act->name, 0, 31, 0, 0, "Actuator name"); - uiButSetFunc(but, make_unique_prop_names_cb, act->name, (void*) 0); + if(act->flag & ACT_SHOW) { + act->otype= act->type; + uiDefButS(block, MENU, B_CHANGE_ACT, actuator_pup(ob), (short)(xco+22), yco, 100, 19, &act->type, 0, 0, 0, 0, "Actuator type"); + but= uiDefBut(block, TEX, 1, "", (short)(xco+122), yco, (short)(width-144), 19, act->name, 0, 31, 0, 0, "Actuator name"); + uiButSetFunc(but, make_unique_prop_names_cb, act->name, (void*) 0); - ycoo= yco; - yco= draw_actuatorbuttons(act, block, xco, yco, width); - if(yco-6 < ycoo) ycoo= (yco+ycoo-20)/2; + ycoo= yco; + yco= draw_actuatorbuttons(ob, act, block, xco, yco, width); + if(yco-6 < ycoo) ycoo= (yco+ycoo-20)/2; + } + else { + set_col_actuator(act->type, 1); + glRecti((short)(xco+22), yco, (short)(xco+width-22),(short)(yco+19)); + but= uiDefBut(block, LABEL, 0, actuator_name(act->type), (short)(xco+22), yco, 100, 19, act, 0, 0, 0, 0, "Actuator type"); + uiButSetFunc(but, sca_move_actuator, act, NULL); + but= uiDefBut(block, LABEL, 0, act->name, (short)(xco+122), yco, (short)(width-144), 19, act, 0, 0, 0, 0, "Actuator name"); + uiButSetFunc(but, sca_move_actuator, act, NULL); + ycoo= yco; + } + + uiDefIconBut(block, INLINK, 0, ICON_INLINK,(short)(xco-19), ycoo, 19, 19, act, LINK_ACTUATOR, 0, 0, 0, ""); + + yco-=20; } - else { - set_col_actuator(act->type, 1); - glRecti((short)(xco+22), yco, (short)(xco+width-22),(short)(yco+19)); - but= uiDefBut(block, LABEL, 0, actuator_name(act->type), (short)(xco+22), yco, 100, 19, act, 0, 0, 0, 0, "Actuator type"); - uiButSetFunc(but, sca_move_actuator, act, NULL); - but= uiDefBut(block, LABEL, 0, act->name, (short)(xco+122), yco, (short)(width-144), 19, act, 0, 0, 0, 0, "Actuator name"); - uiButSetFunc(but, sca_move_actuator, act, NULL); - ycoo= yco; - } - - uiDefIconBut(block, INLINK, 0, ICON_INLINK,(short)(xco-19), ycoo, 19, 19, act, LINK_ACTUATOR, 0, 0, 0, ""); - - yco-=20; - act= act->next; } yco-= 6; diff --git a/source/blender/src/interface.c b/source/blender/src/interface.c index 6582866d9a1..4fbf92d646e 100644 --- a/source/blender/src/interface.c +++ b/source/blender/src/interface.c @@ -2797,6 +2797,10 @@ static void ui_add_link_line(ListBase *listb, uiBut *but, uiBut *bt) line->to= bt; } +uiBut *uiFindInlink(uiBlock *block, void *poin) +{ + return ui_find_inlink(block, poin); +} void uiComposeLinks(uiBlock *block) { diff --git a/source/gameengine/Converter/BL_BlenderDataConversion.cpp b/source/gameengine/Converter/BL_BlenderDataConversion.cpp index 32946267202..21c18634e21 100644 --- a/source/gameengine/Converter/BL_BlenderDataConversion.cpp +++ b/source/gameengine/Converter/BL_BlenderDataConversion.cpp @@ -2324,6 +2324,14 @@ void BL_ConvertBlenderObjects(struct Main* maggie, bool isInActiveLayer = (blenderobj->lay & activeLayerBitInfo)!=0; BL_ConvertSensors(blenderobj,gameobj,logicmgr,kxscene,keydev,executePriority,activeLayerBitInfo,isInActiveLayer,canvas,converter); } + // apply the initial state to controllers + for ( i=0;iGetCount();i++) + { + KX_GameObject* gameobj = static_cast(logicbrick_conversionlist->GetValue(i)); + struct Object* blenderobj = converter->FindBlenderObject(gameobj); + gameobj->SetState(blenderobj->state); + } + #endif //CONVERT_LOGIC logicbrick_conversionlist->Release(); diff --git a/source/gameengine/Converter/KX_ConvertActuators.cpp b/source/gameengine/Converter/KX_ConvertActuators.cpp index f219c3a1472..c02c2a29595 100644 --- a/source/gameengine/Converter/KX_ConvertActuators.cpp +++ b/source/gameengine/Converter/KX_ConvertActuators.cpp @@ -56,6 +56,7 @@ #include "KX_ConstraintActuator.h" #include "KX_CameraActuator.h" #include "KX_GameActuator.h" +#include "KX_StateActuator.h" #include "KX_VisibilityActuator.h" #include "KX_SCA_AddObjectActuator.h" #include "KX_SCA_EndObjectActuator.h" @@ -857,7 +858,19 @@ void BL_ConvertActuators(char* maggiename, baseact = tmp_vis_act; } break; - + + case ACT_STATE: + { + bStateActuator *sta_act = (bStateActuator *) bact->data; + KX_StateActuator * tmp_sta_act = NULL; + + tmp_sta_act = + new KX_StateActuator(gameobj, sta_act->type, sta_act->mask); + + baseact = tmp_sta_act; + } + break; + case ACT_2DFILTER: { bTwoDFilterActuator *_2dfilter = (bTwoDFilterActuator*) bact->data; diff --git a/source/gameengine/Converter/KX_ConvertControllers.cpp b/source/gameengine/Converter/KX_ConvertControllers.cpp index a26cfa95b6d..179dd9f8478 100644 --- a/source/gameengine/Converter/KX_ConvertControllers.cpp +++ b/source/gameengine/Converter/KX_ConvertControllers.cpp @@ -161,6 +161,7 @@ void BL_ConvertControllers( if (gamecontroller) { gamecontroller->SetExecutePriority(executePriority++); + gamecontroller->SetState(bcontr->state_mask); STR_String uniquename = bcontr->name; uniquename += "#CONTR#"; uniqueint++; diff --git a/source/gameengine/GameLogic/SCA_AlwaysSensor.cpp b/source/gameengine/GameLogic/SCA_AlwaysSensor.cpp index 67df5d091ab..f9fbf2387c4 100644 --- a/source/gameengine/GameLogic/SCA_AlwaysSensor.cpp +++ b/source/gameengine/GameLogic/SCA_AlwaysSensor.cpp @@ -53,10 +53,13 @@ SCA_AlwaysSensor::SCA_AlwaysSensor(class SCA_EventManager* eventmgr, : SCA_ISensor(gameobj,eventmgr, T) { //SetDrawColor(255,0,0); - m_alwaysresult = true; + Init(); } - +void SCA_AlwaysSensor::Init() +{ + m_alwaysresult = true; +} SCA_AlwaysSensor::~SCA_AlwaysSensor() { diff --git a/source/gameengine/GameLogic/SCA_AlwaysSensor.h b/source/gameengine/GameLogic/SCA_AlwaysSensor.h index 474ed025432..8bf2a8aa98e 100644 --- a/source/gameengine/GameLogic/SCA_AlwaysSensor.h +++ b/source/gameengine/GameLogic/SCA_AlwaysSensor.h @@ -45,6 +45,8 @@ public: virtual CValue* GetReplica(); virtual bool Evaluate(CValue* event); virtual bool IsPositiveTrigger(); + virtual void Init(); + /* --------------------------------------------------------------------- */ /* Python interface ---------------------------------------------------- */ diff --git a/source/gameengine/GameLogic/SCA_IActuator.cpp b/source/gameengine/GameLogic/SCA_IActuator.cpp index 568d0eb4a89..eeca2d7b44c 100644 --- a/source/gameengine/GameLogic/SCA_IActuator.cpp +++ b/source/gameengine/GameLogic/SCA_IActuator.cpp @@ -36,6 +36,7 @@ using namespace std; SCA_IActuator::SCA_IActuator(SCA_IObject* gameobj, PyTypeObject* T) : + m_links(0), SCA_ILogicBrick(gameobj,T) { // nothing to do @@ -109,3 +110,12 @@ SCA_IActuator::~SCA_IActuator() RemoveAllEvents(); } +void SCA_IActuator::DecLink() +{ + m_links--; + if (m_links < 0) + { + printf("Warning: actuator %s has negative m_links: %d\n", m_name.Ptr(), m_links); + m_links = 0; + } +} diff --git a/source/gameengine/GameLogic/SCA_IActuator.h b/source/gameengine/GameLogic/SCA_IActuator.h index b802aa4b298..774b27c5ad4 100644 --- a/source/gameengine/GameLogic/SCA_IActuator.h +++ b/source/gameengine/GameLogic/SCA_IActuator.h @@ -34,8 +34,11 @@ class SCA_IActuator : public SCA_ILogicBrick { + friend class SCA_LogicManager; protected: std::vector m_events; + int m_links; // number of active links to controllers + // when 0, the actuator is automatically stopped void RemoveAllEvents(); public: @@ -83,6 +86,10 @@ public: */ bool IsNegativeEvent() const; virtual ~SCA_IActuator(); + + void IncLink() { m_links++; } + void DecLink(); + bool IsNoLink() const { return !m_links; } }; #endif //__KX_IACTUATOR diff --git a/source/gameengine/GameLogic/SCA_IController.cpp b/source/gameengine/GameLogic/SCA_IController.cpp index 5cb62678c6b..bbe5a51db3c 100644 --- a/source/gameengine/GameLogic/SCA_IController.cpp +++ b/source/gameengine/GameLogic/SCA_IController.cpp @@ -29,6 +29,7 @@ #include "SCA_IController.h" #include "SCA_LogicManager.h" #include "SCA_IActuator.h" +#include "SCA_ISensor.h" #ifdef HAVE_CONFIG_H #include @@ -37,6 +38,7 @@ SCA_IController::SCA_IController(SCA_IObject* gameobj, PyTypeObject* T) : + m_statemask(0), SCA_ILogicBrick(gameobj,T) { } @@ -45,6 +47,7 @@ SCA_IController::SCA_IController(SCA_IObject* gameobj, SCA_IController::~SCA_IController() { + UnlinkAllActuators(); } @@ -65,6 +68,14 @@ const std::vector& SCA_IController::GetLinkedActuators() void SCA_IController::UnlinkAllSensors() { + if (IsActive()) + { + std::vector::iterator sensit; + for (sensit = m_linkedsensors.begin();!(sensit==m_linkedsensors.end());++sensit) + { + (*sensit)->DecLink(); + } + } m_linkedsensors.clear(); } @@ -72,6 +83,14 @@ void SCA_IController::UnlinkAllSensors() void SCA_IController::UnlinkAllActuators() { + if (IsActive()) + { + std::vector::iterator actit; + for (actit = m_linkedactuators.begin();!(actit==m_linkedactuators.end());++actit) + { + (*actit)->DecLink(); + } + } m_linkedactuators.clear(); } @@ -95,26 +114,94 @@ void SCA_IController::Trigger(SCA_LogicManager* logicmgr) void SCA_IController::LinkToActuator(SCA_IActuator* actua) { m_linkedactuators.push_back(actua); + if (IsActive()) + { + actua->IncLink(); + } } void SCA_IController::UnlinkActuator(class SCA_IActuator* actua) { std::vector::iterator actit; - std::vector::iterator actfound = m_linkedactuators.end(); for (actit = m_linkedactuators.begin();!(actit==m_linkedactuators.end());++actit) { if ((*actit) == actua) - actfound = actit; + { + break; + } } - if (!(actfound==m_linkedactuators.end())) + if (!(actit==m_linkedactuators.end())) { - m_linkedactuators.erase(actfound); + m_linkedactuators.erase(actit); + if (IsActive()) + { + (*actit)->DecLink(); + } } - } void SCA_IController::LinkToSensor(SCA_ISensor* sensor) { m_linkedsensors.push_back(sensor); + if (IsActive()) + { + sensor->IncLink(); + } } + +void SCA_IController::UnlinkSensor(class SCA_ISensor* sensor) +{ + std::vector::iterator sensit; + for (sensit = m_linkedsensors.begin();!(sensit==m_linkedsensors.end());++sensit) + { + if ((*sensit) == sensor) + { + break; + } + + } + if (!(sensit==m_linkedsensors.end())) + { + m_linkedsensors.erase(sensit); + if (IsActive()) + { + (*sensit)->DecLink(); + } + } +} + +void SCA_IController::ApplyState(unsigned int state) +{ + std::vector::iterator actit; + std::vector::iterator sensit; + + if (m_statemask & state) + { + if (!IsActive()) + { + // reactive the controller, all the links to actuator are valid again + for (actit = m_linkedactuators.begin();!(actit==m_linkedactuators.end());++actit) + { + (*actit)->IncLink(); + } + for (sensit = m_linkedsensors.begin();!(sensit==m_linkedsensors.end());++sensit) + { + (*sensit)->IncLink(); + } + SetActive(true); + } + } else if (IsActive()) + { + for (actit = m_linkedactuators.begin();!(actit==m_linkedactuators.end());++actit) + { + (*actit)->DecLink(); + } + for (sensit = m_linkedsensors.begin();!(sensit==m_linkedsensors.end());++sensit) + { + (*sensit)->DecLink(); + } + SetActive(false); + } +} + diff --git a/source/gameengine/GameLogic/SCA_IController.h b/source/gameengine/GameLogic/SCA_IController.h index 79e956dec4e..f67c0942eb4 100644 --- a/source/gameengine/GameLogic/SCA_IController.h +++ b/source/gameengine/GameLogic/SCA_IController.h @@ -36,6 +36,7 @@ class SCA_IController : public SCA_ILogicBrick protected: std::vector m_linkedsensors; std::vector m_linkedactuators; + unsigned int m_statemask; public: SCA_IController(SCA_IObject* gameobj,PyTypeObject* T); virtual ~SCA_IController(); @@ -47,6 +48,9 @@ public: void UnlinkAllSensors(); void UnlinkAllActuators(); void UnlinkActuator(class SCA_IActuator* actua); + void UnlinkSensor(class SCA_ISensor* sensor); + void SetState(unsigned int state) { m_statemask = state; } + void ApplyState(unsigned int state); }; diff --git a/source/gameengine/GameLogic/SCA_IObject.cpp b/source/gameengine/GameLogic/SCA_IObject.cpp index 6df9e23f3fa..826e7bbdf0e 100644 --- a/source/gameengine/GameLogic/SCA_IObject.cpp +++ b/source/gameengine/GameLogic/SCA_IObject.cpp @@ -40,7 +40,7 @@ MT_Point3 SCA_IObject::m_sDummy=MT_Point3(0,0,0); -SCA_IObject::SCA_IObject(PyTypeObject* T): CValue(T) +SCA_IObject::SCA_IObject(PyTypeObject* T): m_state(0), CValue(T) { m_suspended = false; } @@ -329,6 +329,17 @@ void SCA_IObject::Resume(void) } } +void SCA_IObject::SetState(unsigned int state) +{ + m_state = state; + // update the status of the controllers + SCA_ControllerList::iterator contit; + for (contit = m_controllers.begin(); contit != m_controllers.end(); contit++) + { + (*contit)->ApplyState(m_state); + } +} + /* ------------------------------------------------------------------------- */ diff --git a/source/gameengine/GameLogic/SCA_IObject.h b/source/gameengine/GameLogic/SCA_IObject.h index e8251e0ceaa..07b4310a91e 100644 --- a/source/gameengine/GameLogic/SCA_IObject.h +++ b/source/gameengine/GameLogic/SCA_IObject.h @@ -67,7 +67,12 @@ protected: * Ignore updates? */ bool m_suspended; - + + /** + * current state = bit mask of state that are active + */ + unsigned int m_state; + public: SCA_IObject(PyTypeObject* T=&Type); @@ -111,7 +116,17 @@ public: * Resume progress */ void Resume(void); - + + /** + * Set the object state + */ + void SetState(unsigned int state); + + /** + * Get the object state + */ + unsigned int GetState(void) { return m_state; } + // const class MT_Point3& ConvertPythonPylist(PyObject* pylist); // here come the python forwarded methods diff --git a/source/gameengine/GameLogic/SCA_ISensor.cpp b/source/gameengine/GameLogic/SCA_ISensor.cpp index 9fdee0c19da..1c29eb27be5 100644 --- a/source/gameengine/GameLogic/SCA_ISensor.cpp +++ b/source/gameengine/GameLogic/SCA_ISensor.cpp @@ -52,6 +52,7 @@ SCA_ISensor::SCA_ISensor(SCA_IObject* gameobj, SCA_ILogicBrick(gameobj,T), m_triggered(false) { + m_links = 0; m_suspended = false; m_invert = false; m_pos_ticks = 0; @@ -111,6 +112,25 @@ void SCA_ISensor::Resume() { m_suspended = false; } +void SCA_ISensor::Init() { + printf("Sensor %s has no init function, please report this bug to Blender.org\n", m_name); +} + +void SCA_ISensor::DecLink() { + m_links--; + if (m_links < 0) + { + printf("Warning: sensor %s has negative m_links: %d\n", m_name.Ptr(), m_links); + m_links = 0; + } + if (!m_links) + { + // sensor is detached from all controllers, initialize it so that it + // is fresh as at startup when it is reattached again. + Init(); + } +} + /* python integration */ PyTypeObject SCA_ISensor::Type = { @@ -177,7 +197,8 @@ void SCA_ISensor::Activate(class SCA_LogicManager* logicmgr, CValue* event) { // calculate if a __triggering__ is wanted - if (!m_suspended) { + // don't evaluate a sensor that is not connected to any controller + if (m_links && !m_suspended) { bool result = this->Evaluate(event); if (result) { logicmgr->AddActivatedSensor(this); diff --git a/source/gameengine/GameLogic/SCA_ISensor.h b/source/gameengine/GameLogic/SCA_ISensor.h index e14fb34241a..292b2d160ae 100644 --- a/source/gameengine/GameLogic/SCA_ISensor.h +++ b/source/gameengine/GameLogic/SCA_ISensor.h @@ -64,6 +64,9 @@ class SCA_ISensor : public SCA_ILogicBrick /** Sensor must ignore updates? */ bool m_suspended; + /** number of connections to controller */ + int m_links; + /** Pass the activation on to the logic manager.*/ void SignalActivation(class SCA_LogicManager* logicmgr); @@ -81,6 +84,7 @@ public: void Activate(class SCA_LogicManager* logicmgr,CValue* event); virtual bool Evaluate(CValue* event) = 0; virtual bool IsPositiveTrigger(); + virtual void Init(); virtual PyObject* _getattr(const STR_String& attr); virtual CValue* GetReplica()=0; @@ -114,6 +118,12 @@ public: /** Resume sensing. */ void Resume(); + void IncLink() + { m_links++; } + void DecLink(); + bool IsNoLink() const + { return !m_links; } + /* Python functions: */ KX_PYMETHOD_DOC(SCA_ISensor,IsPositive); KX_PYMETHOD_DOC(SCA_ISensor,GetUsePosPulseMode); diff --git a/source/gameengine/GameLogic/SCA_JoystickSensor.cpp b/source/gameengine/GameLogic/SCA_JoystickSensor.cpp index b0e7fee130d..81938f05af1 100644 --- a/source/gameengine/GameLogic/SCA_JoystickSensor.cpp +++ b/source/gameengine/GameLogic/SCA_JoystickSensor.cpp @@ -64,9 +64,13 @@ std::cout << " button flag "<< m_buttonf << std::endl; std::cout << " hat " << m_hat << std::endl; std::cout << " hat flag " << m_hatf << std::endl; */ - m_istrig=0; + Init(); } +void SCA_JoystickSensor::Init() +{ + m_istrig=0; +} SCA_JoystickSensor::~SCA_JoystickSensor() { diff --git a/source/gameengine/GameLogic/SCA_JoystickSensor.h b/source/gameengine/GameLogic/SCA_JoystickSensor.h index 2fbe1edf1e7..69068da6494 100644 --- a/source/gameengine/GameLogic/SCA_JoystickSensor.h +++ b/source/gameengine/GameLogic/SCA_JoystickSensor.h @@ -95,6 +95,7 @@ public: virtual bool Evaluate(CValue* event); virtual bool IsPositiveTrigger(); + virtual void Init(); /* --------------------------------------------------------------------- */ /* Python interface ---------------------------------------------------- */ diff --git a/source/gameengine/GameLogic/SCA_KeyboardSensor.cpp b/source/gameengine/GameLogic/SCA_KeyboardSensor.cpp index f13b1bcf4c9..c6c06846e3b 100644 --- a/source/gameengine/GameLogic/SCA_KeyboardSensor.cpp +++ b/source/gameengine/GameLogic/SCA_KeyboardSensor.cpp @@ -62,7 +62,7 @@ SCA_KeyboardSensor::SCA_KeyboardSensor(SCA_KeyboardManager* keybdmgr, if (hotkey == SCA_IInputDevice::KX_ESCKEY) keybdmgr->GetInputDevice()->HookEscape(); // SetDrawColor(0xff0000ff); - m_val=0; + Init(); } @@ -71,7 +71,14 @@ SCA_KeyboardSensor::~SCA_KeyboardSensor() { } - +void SCA_KeyboardSensor::Init() +{ + // this function is used when the sensor is disconnected from all controllers + // by the state engine. It reinitializes the sensor as if it was just created. + // However, if the target key is pressed when the sensor is reactivated, it + // will not generated an event (see remark in Evaluate()). + m_val = 0; +} CValue* SCA_KeyboardSensor::GetReplica() { diff --git a/source/gameengine/GameLogic/SCA_KeyboardSensor.h b/source/gameengine/GameLogic/SCA_KeyboardSensor.h index e87eddecd32..b86f6931d27 100644 --- a/source/gameengine/GameLogic/SCA_KeyboardSensor.h +++ b/source/gameengine/GameLogic/SCA_KeyboardSensor.h @@ -114,6 +114,8 @@ public: PyTypeObject* T=&Type ); virtual ~SCA_KeyboardSensor(); virtual CValue* GetReplica(); + virtual void Init(); + short int GetHotkey(); virtual bool Evaluate(CValue* event); diff --git a/source/gameengine/GameLogic/SCA_LogicManager.cpp b/source/gameengine/GameLogic/SCA_LogicManager.cpp index 49f01d643e5..fb1a2c29eb6 100644 --- a/source/gameengine/GameLogic/SCA_LogicManager.cpp +++ b/source/gameengine/GameLogic/SCA_LogicManager.cpp @@ -165,6 +165,11 @@ void* SCA_LogicManager::FindBlendObjByGameMeshName(const STR_String& gamemeshnam void SCA_LogicManager::RemoveSensor(SCA_ISensor* sensor) { + controllerlist contlist = m_sensorcontrollermapje[sensor]; + for (controllerlist::const_iterator c= contlist.begin();!(c==contlist.end());c++) + { + (*c)->UnlinkSensor(sensor); + } m_sensorcontrollermapje.erase(sensor); for (vector::const_iterator ie=m_eventmanagers.begin(); @@ -176,6 +181,8 @@ void SCA_LogicManager::RemoveSensor(SCA_ISensor* sensor) void SCA_LogicManager::RemoveController(SCA_IController* controller) { + controller->UnlinkAllSensors(); + controller->UnlinkAllActuators(); std::map::iterator sit; for (sit = m_sensorcontrollermapje.begin();!(sit==m_sensorcontrollermapje.end());++sit) { @@ -236,7 +243,8 @@ void SCA_LogicManager::BeginFrame(double curtime, double fixedtime) !(c==contlist.end());c++) { SCA_IController* contr = *c;//controllerarray->at(c); - triggeredControllerSet.insert(SmartControllerPtr(contr,0)); + if (contr->IsActive()) + triggeredControllerSet.insert(SmartControllerPtr(contr,0)); } //sensor->SetActive(false); } @@ -273,6 +281,16 @@ void SCA_LogicManager::UpdateFrame(double curtime, bool frame) (*ia)->SetActive(false); //m_activeactuators.pop_back(); + } else if ((*ia)->IsNoLink()) + { + // This actuator has no more links but it still active + // make sure it will get a negative event on next frame to stop it + // Do this check after Update() rather than before to make sure + // that all the actuators that are activated at same time than a state + // actuator have a chance to execute. + CValue* event = new CBoolValue(false); + (*ia)->RemoveAllEvents(); + (*ia)->AddEvent(event); } } diff --git a/source/gameengine/GameLogic/SCA_MouseSensor.cpp b/source/gameengine/GameLogic/SCA_MouseSensor.cpp index 8810b7470ed..11e67eda014 100644 --- a/source/gameengine/GameLogic/SCA_MouseSensor.cpp +++ b/source/gameengine/GameLogic/SCA_MouseSensor.cpp @@ -58,7 +58,6 @@ SCA_MouseSensor::SCA_MouseSensor(SCA_MouseManager* eventmgr, { m_mousemode = mousemode; m_triggermode = true; - m_val = 0; /* stores the latest attribute */ switch (m_mousemode) { case KX_MOUSESENSORMODE_LEFTBUTTON: @@ -79,7 +78,12 @@ SCA_MouseSensor::SCA_MouseSensor(SCA_MouseManager* eventmgr, default: ; /* ignore, no hotkey */ } + Init(); +} +void SCA_MouseSensor::Init() +{ + m_val = 0; /* stores the latest attribute */ } SCA_MouseSensor::~SCA_MouseSensor() diff --git a/source/gameengine/GameLogic/SCA_MouseSensor.h b/source/gameengine/GameLogic/SCA_MouseSensor.h index 86c9d96a800..26a1c5e3fd2 100644 --- a/source/gameengine/GameLogic/SCA_MouseSensor.h +++ b/source/gameengine/GameLogic/SCA_MouseSensor.h @@ -96,7 +96,7 @@ class SCA_MouseSensor : public SCA_ISensor virtual ~SCA_MouseSensor(); virtual CValue* GetReplica(); virtual bool Evaluate(CValue* event); - + virtual void Init(); virtual bool IsPositiveTrigger(); short int GetModeKey(); SCA_IInputDevice::KX_EnumInputs GetHotKey(); diff --git a/source/gameengine/GameLogic/SCA_PropertySensor.cpp b/source/gameengine/GameLogic/SCA_PropertySensor.cpp index f1fcb18d32e..d6eb246ffd2 100644 --- a/source/gameengine/GameLogic/SCA_PropertySensor.cpp +++ b/source/gameengine/GameLogic/SCA_PropertySensor.cpp @@ -57,7 +57,6 @@ SCA_PropertySensor::SCA_PropertySensor(SCA_EventManager* eventmgr, m_lastresult(false), m_range_expr(NULL) { - m_recentresult=false; //CParser pars; //pars.SetContext(this->AddRef()); //CValue* resultval = m_rightexpr->Calculate(); @@ -73,7 +72,12 @@ SCA_PropertySensor::SCA_PropertySensor(SCA_EventManager* eventmgr, { PrecalculateRangeExpression(); } + Init(); +} +void SCA_PropertySensor::Init() +{ + m_recentresult = false; } void SCA_PropertySensor::PrecalculateRangeExpression() diff --git a/source/gameengine/GameLogic/SCA_PropertySensor.h b/source/gameengine/GameLogic/SCA_PropertySensor.h index 81c9b958f25..6871cb3afdc 100644 --- a/source/gameengine/GameLogic/SCA_PropertySensor.h +++ b/source/gameengine/GameLogic/SCA_PropertySensor.h @@ -77,6 +77,7 @@ public: virtual void Delete(); virtual ~SCA_PropertySensor(); virtual CValue* GetReplica(); + virtual void Init(); void PrecalculateRangeExpression(); bool CheckPropertyCondition(); diff --git a/source/gameengine/GameLogic/SCA_RandomSensor.cpp b/source/gameengine/GameLogic/SCA_RandomSensor.cpp index 0e856e0d6bb..3626522e49a 100644 --- a/source/gameengine/GameLogic/SCA_RandomSensor.cpp +++ b/source/gameengine/GameLogic/SCA_RandomSensor.cpp @@ -50,16 +50,9 @@ SCA_RandomSensor::SCA_RandomSensor(SCA_EventManager* eventmgr, PyTypeObject* T) : SCA_ISensor(gameobj,eventmgr, T) { - m_iteration = 0; - m_interval = 0; - m_lastdraw = false; - // m_basegenerator is never deleted => memory leak m_basegenerator = new SCA_RandomNumberGenerator(startseed); - m_currentDraw = m_basegenerator->Draw(); - //registration is done globally, don't do it here - //Note: it was probably done to work around a bug in Evaluate(). It is now fixed - //RegisterToManager(); + Init(); } @@ -69,6 +62,13 @@ SCA_RandomSensor::~SCA_RandomSensor() /* Nothing to be done here. */ } +void SCA_RandomSensor::Init() +{ + m_iteration = 0; + m_interval = 0; + m_lastdraw = false; + m_currentDraw = m_basegenerator->Draw(); +} CValue* SCA_RandomSensor::GetReplica() diff --git a/source/gameengine/GameLogic/SCA_RandomSensor.h b/source/gameengine/GameLogic/SCA_RandomSensor.h index cc54179aa4e..d29bfb6837a 100644 --- a/source/gameengine/GameLogic/SCA_RandomSensor.h +++ b/source/gameengine/GameLogic/SCA_RandomSensor.h @@ -54,6 +54,7 @@ public: virtual CValue* GetReplica(); virtual bool Evaluate(CValue* event); virtual bool IsPositiveTrigger(); + virtual void Init(); /* --------------------------------------------------------------------- */ /* Python interface ---------------------------------------------------- */ diff --git a/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.cpp b/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.cpp index e320453b7aa..027cb2a0ffa 100644 --- a/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.cpp +++ b/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.cpp @@ -58,10 +58,15 @@ KX_NetworkMessageSensor::KX_NetworkMessageSensor( m_NetworkScene(NetworkScene), m_subject(subject), m_frame_message_count (0), - m_IsUp(false), m_BodyList(NULL), m_SubjectList(NULL) { + Init(); +} + +void KX_NetworkMessageSensor::Init() +{ + m_IsUp = false; } KX_NetworkMessageSensor::~KX_NetworkMessageSensor() diff --git a/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.h b/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.h index d051b715aab..6fd92d17be3 100644 --- a/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.h +++ b/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.h @@ -65,6 +65,7 @@ public: virtual CValue* GetReplica(); virtual bool Evaluate(CValue* event); virtual bool IsPositiveTrigger(); + virtual void Init(); void EndFrame(); /* ------------------------------------------------------------- */ diff --git a/source/gameengine/Ketsji/KX_MouseFocusSensor.cpp b/source/gameengine/Ketsji/KX_MouseFocusSensor.cpp index 60b90138abe..f306f0dbfbb 100644 --- a/source/gameengine/Ketsji/KX_MouseFocusSensor.cpp +++ b/source/gameengine/Ketsji/KX_MouseFocusSensor.cpp @@ -69,11 +69,14 @@ KX_MouseFocusSensor::KX_MouseFocusSensor(SCA_MouseManager* eventmgr, m_gp_canvas(canvas), m_kxscene(kxscene) { + Init(); +} +void KX_MouseFocusSensor::Init() +{ m_mouse_over_in_previous_frame = false; m_positive_event = false; m_hitObject = 0; - } bool KX_MouseFocusSensor::Evaluate(CValue* event) diff --git a/source/gameengine/Ketsji/KX_MouseFocusSensor.h b/source/gameengine/Ketsji/KX_MouseFocusSensor.h index 86f32fbf4be..b011ebe1288 100644 --- a/source/gameengine/Ketsji/KX_MouseFocusSensor.h +++ b/source/gameengine/Ketsji/KX_MouseFocusSensor.h @@ -68,6 +68,7 @@ class KX_MouseFocusSensor : public SCA_MouseSensor * @attention Overrides default evaluate. */ virtual bool Evaluate(CValue* event); + virtual void Init(); virtual bool IsPositiveTrigger() { bool result = m_positive_event; diff --git a/source/gameengine/Ketsji/KX_RadarSensor.cpp b/source/gameengine/Ketsji/KX_RadarSensor.cpp index 31fffffa3c1..987e0b946b2 100644 --- a/source/gameengine/Ketsji/KX_RadarSensor.cpp +++ b/source/gameengine/Ketsji/KX_RadarSensor.cpp @@ -71,7 +71,6 @@ KX_RadarSensor::KX_RadarSensor(SCA_EventManager* eventmgr, //sumoObj->setClientObject(&m_client_info); } - KX_RadarSensor::~KX_RadarSensor() { diff --git a/source/gameengine/Ketsji/KX_RaySensor.cpp b/source/gameengine/Ketsji/KX_RaySensor.cpp index a85dc61cac8..02b814105b4 100644 --- a/source/gameengine/Ketsji/KX_RaySensor.cpp +++ b/source/gameengine/Ketsji/KX_RaySensor.cpp @@ -60,17 +60,19 @@ KX_RaySensor::KX_RaySensor(class SCA_EventManager* eventmgr, m_bFindMaterial(bFindMaterial), m_distance(distance), m_scene(ketsjiScene), - m_bTriggered(false), - m_axis(axis), - m_rayHit(false), - m_hitObject(NULL) + m_axis(axis) { - + Init(); } - +void KX_RaySensor::Init() +{ + m_bTriggered = false; + m_rayHit = false; + m_hitObject = NULL; +} KX_RaySensor::~KX_RaySensor() { diff --git a/source/gameengine/Ketsji/KX_RaySensor.h b/source/gameengine/Ketsji/KX_RaySensor.h index 8a317ffaa07..f4305b053d1 100644 --- a/source/gameengine/Ketsji/KX_RaySensor.h +++ b/source/gameengine/Ketsji/KX_RaySensor.h @@ -66,6 +66,7 @@ public: virtual bool Evaluate(CValue* event); virtual bool IsPositiveTrigger(); + virtual void Init(); bool RayHit(KX_ClientObjectInfo* client, MT_Point3& hit_point, MT_Vector3& hit_normal, void * const data); diff --git a/source/gameengine/Ketsji/KX_Scene.cpp b/source/gameengine/Ketsji/KX_Scene.cpp index fff33ca82fd..1526709f425 100644 --- a/source/gameengine/Ketsji/KX_Scene.cpp +++ b/source/gameengine/Ketsji/KX_Scene.cpp @@ -754,8 +754,6 @@ int KX_Scene::NewRemoveObject(class CValue* gameobj) for (SCA_ControllerList::iterator itc = controllers.begin(); !(itc==controllers.end());itc++) { - (*itc)->UnlinkAllSensors(); - (*itc)->UnlinkAllActuators(); m_logicmgr->RemoveController(*itc); } diff --git a/source/gameengine/Ketsji/KX_StateActuator.cpp b/source/gameengine/Ketsji/KX_StateActuator.cpp new file mode 100644 index 00000000000..95a79f0c480 --- /dev/null +++ b/source/gameengine/Ketsji/KX_StateActuator.cpp @@ -0,0 +1,207 @@ +/* + * $Id$ + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL LICENSE BLOCK ***** + * Actuator to toggle visibility/invisibility of objects + */ + +#include "KX_StateActuator.h" +#include "KX_GameObject.h" + +#ifdef HAVE_CONFIG_H +#include +#endif + +KX_StateActuator::KX_StateActuator( + SCA_IObject* gameobj, + int operation, + unsigned int mask, + PyTypeObject* T + ) + : SCA_IActuator(gameobj,T), + m_operation(operation), + m_mask(mask) +{ + // intentionally empty +} + +KX_StateActuator::~KX_StateActuator( + void + ) +{ + // intentionally empty +} + +CValue* +KX_StateActuator::GetReplica( + void + ) +{ + KX_StateActuator* replica = new KX_StateActuator(*this); + replica->ProcessReplica(); + // this will copy properties and so on... + CValue::AddDataToReplica(replica); + return replica; +} + +bool +KX_StateActuator::Update() +{ + bool bNegativeEvent = IsNegativeEvent(); + unsigned int objMask; + + RemoveAllEvents(); + if (bNegativeEvent) return false; + + KX_GameObject *obj = (KX_GameObject*) GetParent(); + + objMask = obj->GetState(); + switch (m_operation) + { + case OP_CPY: + objMask = m_mask; + break; + case OP_SET: + objMask |= m_mask; + break; + case OP_CLR: + objMask &= ~m_mask; + break; + case OP_NEG: + objMask ^= m_mask; + break; + default: + // unsupported operation, no nothing + return false; + } + obj->SetState(objMask); + return false; +} + +/* ------------------------------------------------------------------------- */ +/* Python functions */ +/* ------------------------------------------------------------------------- */ + + + +/* Integration hooks ------------------------------------------------------- */ +PyTypeObject +KX_StateActuator::Type = { + PyObject_HEAD_INIT(&PyType_Type) + 0, + "KX_StateActuator", + sizeof(KX_StateActuator), + 0, + PyDestructor, + 0, + __getattr, + __setattr, + 0, //&MyPyCompare, + __repr, + 0, //&cvalue_as_number, + 0, + 0, + 0, + 0 +}; + +PyParentObject +KX_StateActuator::Parents[] = { + &KX_StateActuator::Type, + &SCA_IActuator::Type, + &SCA_ILogicBrick::Type, + &CValue::Type, + NULL +}; + +PyMethodDef +KX_StateActuator::Methods[] = { + {"setOperation", (PyCFunction) KX_StateActuator::sPySetOperation, + METH_VARARGS, SetOperation_doc}, + {"setMask", (PyCFunction) KX_StateActuator::sPySetMask, + METH_VARARGS, SetMask_doc}, + {NULL,NULL} //Sentinel +}; + +PyObject* +KX_StateActuator::_getattr( + const STR_String& attr + ) +{ + _getattr_up(SCA_IActuator); +}; + + + +/* set operation ---------------------------------------------------------- */ +char +KX_StateActuator::SetOperation_doc[] = +"setOperation(op)\n" +"\t - op : bit operation (0=Copy, 1=Set, 2=Clear, 3=Negate)" +"\tSet the type of bit operation to be applied on object state mask.\n" +"\tUse setMask() to specify the bits that will be modified.\n"; +PyObject* + +KX_StateActuator::PySetOperation(PyObject* self, + PyObject* args, + PyObject* kwds) { + int oper; + + if(!PyArg_ParseTuple(args, "i", &oper)) { + return NULL; + } + + m_operation = oper; + + Py_Return; +} + +/* set mask ---------------------------------------------------------- */ +char +KX_StateActuator::SetMask_doc[] = +"setMask(mask)\n" +"\t - mask : bits that will be modified" +"\tSet the value that defines the bits that will be modified by the operation.\n" +"\tThe bits that are 1 in the value will be updated in the object state,\n" +"\tthe bits that are 0 are will be left unmodified expect for the Copy operation\n" +"\twhich copies the value to the object state.\n"; +PyObject* + +KX_StateActuator::PySetMask(PyObject* self, + PyObject* args, + PyObject* kwds) { + int mask; + + if(!PyArg_ParseTuple(args, "i", &mask)) { + return NULL; + } + + m_mask = mask; + + Py_Return; +} + + diff --git a/source/gameengine/Ketsji/KX_StateActuator.h b/source/gameengine/Ketsji/KX_StateActuator.h new file mode 100644 index 00000000000..8698e51b2c1 --- /dev/null +++ b/source/gameengine/Ketsji/KX_StateActuator.h @@ -0,0 +1,83 @@ +/* + * $Id$ + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL LICENSE BLOCK ***** + * Actuator to toggle visibility/invisibility of objects + */ + +#ifndef __KX_STATEACTUATOR +#define __KX_STATEACTUATOR + +#include "SCA_IActuator.h" + +class KX_StateActuator : public SCA_IActuator +{ + Py_Header; + + /** Make visible? */ + enum { + OP_CPY = 0, + OP_SET, + OP_CLR, + OP_NEG + }; + int m_operation; + unsigned int m_mask; + + public: + + KX_StateActuator( + SCA_IObject* gameobj, + int operation, + unsigned int mask, + PyTypeObject* T=&Type + ); + + virtual + ~KX_StateActuator( + void + ); + + virtual CValue* + GetReplica( + void + ); + + virtual bool + Update(); + + /* --------------------------------------------------------------------- */ + /* Python interface ---------------------------------------------------- */ + /* --------------------------------------------------------------------- */ + + virtual PyObject* _getattr(const STR_String& attr); + //KX_PYMETHOD_DOC + KX_PYMETHOD_DOC(KX_StateActuator,SetOperation); + KX_PYMETHOD_DOC(KX_StateActuator,SetMask); +}; + +#endif + diff --git a/source/gameengine/Ketsji/KX_TouchSensor.cpp b/source/gameengine/Ketsji/KX_TouchSensor.cpp index 3f185359de0..56c2780871b 100644 --- a/source/gameengine/Ketsji/KX_TouchSensor.cpp +++ b/source/gameengine/Ketsji/KX_TouchSensor.cpp @@ -77,18 +77,14 @@ KX_TouchSensor::KX_TouchSensor(SCA_EventManager* eventmgr,KX_GameObject* gameobj :SCA_ISensor(gameobj,eventmgr,T), m_touchedpropname(touchedpropname), m_bFindMaterial(bFindMaterial), -m_eventmgr(eventmgr), +m_eventmgr(eventmgr) /*m_sumoObj(sumoObj),*/ -m_bCollision(false), -m_bTriggered(false), -m_bLastTriggered(false) { // KX_TouchEventManager* touchmgr = (KX_TouchEventManager*) eventmgr; // m_resptable = touchmgr->GetResponseTable(); // m_solidHandle = m_sumoObj->getObjectHandle(); - m_hitObject = NULL; m_colliders = new CListValue(); KX_ClientObjectInfo *client_info = gameobj->getClientInfo(); @@ -98,8 +94,16 @@ m_bLastTriggered(false) m_physCtrl = dynamic_cast(gameobj->GetPhysicsController()); MT_assert( !gameobj->GetPhysicsController() || m_physCtrl ); + Init(); } +void KX_TouchSensor::Init() +{ + m_bCollision = false; + m_bTriggered = false; + m_bLastTriggered = false; + m_hitObject = NULL; +} KX_TouchSensor::~KX_TouchSensor() { diff --git a/source/gameengine/Ketsji/KX_TouchSensor.h b/source/gameengine/Ketsji/KX_TouchSensor.h index f594196628a..056440ccd6c 100644 --- a/source/gameengine/Ketsji/KX_TouchSensor.h +++ b/source/gameengine/Ketsji/KX_TouchSensor.h @@ -72,6 +72,7 @@ public: virtual CValue* GetReplica(); virtual void SynchronizeTransform(); virtual bool Evaluate(CValue* event); + virtual void Init(); virtual void ReParent(SCA_IObject* parent); virtual void RegisterSumo(KX_TouchEventManager* touchman); From 63060128ec1947287cae8ea0a1c041f2cabca87f Mon Sep 17 00:00:00 2001 From: Peter Schlaile Date: Sun, 22 Jun 2008 15:48:12 +0000 Subject: [PATCH 235/246] == Redcode == Doing image comparison revealed, that Kb = Kr = 0.0 for redcode :) --- extern/libredcode/debayer.c | 24 +++++++++--------------- 1 file changed, 9 insertions(+), 15 deletions(-) diff --git a/extern/libredcode/debayer.c b/extern/libredcode/debayer.c index f7f22e1cc54..de7bec510cb 100644 --- a/extern/libredcode/debayer.c +++ b/extern/libredcode/debayer.c @@ -9,8 +9,6 @@ void redcode_ycbcr2rgb_fullscale( int x,y; int pix_max = 4096; int mask = pix_max - 1; - float Kb = 0.0722; - float Kr = 0.2126; float *o; for (y = 0; y < height; y++) { @@ -25,9 +23,9 @@ void redcode_ycbcr2rgb_fullscale( float y2 = (planes[3][i] & mask); float y2p = (planes[3][i_p] & mask); - float b_ = cb * (1.0 - Kb)/(pix_max/2); - float r_ = cr * (1.0 - Kr)/(pix_max/2); - float g_ = (- Kr * r_ - Kb * b_)/(1.0 - Kr - Kb); + float b_ = cb /(pix_max/2); + float r_ = cr /(pix_max/2); + float g_ = 0.0; float y_[4] = {y1 / pix_max, (y2 + y2p)/2 / pix_max, @@ -68,8 +66,6 @@ void redcode_ycbcr2rgb_halfscale( int x,y; int pix_max = 4096; int mask = pix_max - 1; - float Kb = 0.0722; - float Kr = 0.2126; for (y = 0; y < height; y++) { float *o = out + width * (height - y - 1); @@ -80,9 +76,9 @@ void redcode_ycbcr2rgb_halfscale( float cr = (planes[2][i] & mask) - pix_max/2; float y2 = (planes[3][i] & mask); - float b_ = cb * (1.0 - Kb)/(pix_max/2); - float r_ = cr * (1.0 - Kr)/(pix_max/2); - float g_ = (- Kr * r_ - Kb * b_)/(1.0 - Kr - Kb); + float b_ = cb /(pix_max/2); + float r_ = cr /(pix_max/2); + float g_ = 0.0; float y = (y1 + y2)/2 / pix_max; @@ -101,8 +97,6 @@ void redcode_ycbcr2rgb_quarterscale( int x,y; int pix_max = 4096; int mask = pix_max - 1; - float Kb = 0.0722; - float Kr = 0.2126; for (y = 0; y < height; y += 2) { float *o = out + (width/2) * (height/2 - y/2 - 1); @@ -113,9 +107,9 @@ void redcode_ycbcr2rgb_quarterscale( float cr = (planes[2][i] & mask) - pix_max/2; float y2 = planes[3][i] & mask; - float b_ = cb * (1.0 - Kb)/(pix_max/2); - float r_ = cr * (1.0 - Kr)/(pix_max/2); - float g_ = (- Kr * r_ - Kb * b_)/(1.0 - Kr - Kb); + float b_ = cb /(pix_max/2); + float r_ = cr /(pix_max/2); + float g_ = 0.0; float y = (y1 + y2)/2 / pix_max; From 381f15189d8555ff4825917f3f7076bb8524bbc4 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 22 Jun 2008 19:34:18 +0000 Subject: [PATCH 236/246] bugfix, Shift+H would hide unselected objects on unseen layers. --- source/blender/src/editobject.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/src/editobject.c b/source/blender/src/editobject.c index 3c945775b5b..2e5785eaab8 100644 --- a/source/blender/src/editobject.c +++ b/source/blender/src/editobject.c @@ -5942,7 +5942,7 @@ void hide_objects(int select) Base *base; short changed = 0, changed_act = 0; for(base = FIRSTBASE; base; base=base->next){ - if(TESTBASELIB(base)==select){ + if ((base->lay & G.vd->lay) && (TESTBASELIB(base)==select)) { base->flag &= ~SELECT; base->object->flag = base->flag; base->object->restrictflag |= OB_RESTRICT_VIEW; From abda1a9ec17d830396c72d1dccd799509cebaa80 Mon Sep 17 00:00:00 2001 From: Peter Schlaile Date: Sun, 22 Jun 2008 20:39:41 +0000 Subject: [PATCH 237/246] == FFMPEG == Added serious interlacing to movies opened using ffmpeg. (Other video decoders to be done) Rational: deinterlacing, if done seriously _has_ to be done in YUV-space. Since internal interface first converts data to RGB we are pretty much lost (and fall back to IMB_filtery in that case). --- source/blender/imbuf/IMB_imbuf_types.h | 1 + source/blender/imbuf/intern/anim.c | 20 ++++++++++++++++++++ source/blender/src/buttons_scene.c | 2 +- source/blender/src/sequence.c | 14 ++++++++++---- 4 files changed, 32 insertions(+), 5 deletions(-) diff --git a/source/blender/imbuf/IMB_imbuf_types.h b/source/blender/imbuf/IMB_imbuf_types.h index 94203bab447..73ef83393b0 100644 --- a/source/blender/imbuf/IMB_imbuf_types.h +++ b/source/blender/imbuf/IMB_imbuf_types.h @@ -149,6 +149,7 @@ typedef enum { #define IB_zbuffloat (1 << 16) #define IB_multilayer (1 << 17) #define IB_imginfo (1 << 18) +#define IB_animdeinterlace (1 << 19) /* * The bit flag is stored in the ImBuf.ftype variable. diff --git a/source/blender/imbuf/intern/anim.c b/source/blender/imbuf/intern/anim.c index 87d67f5263b..7fc8145c4a7 100644 --- a/source/blender/imbuf/intern/anim.c +++ b/source/blender/imbuf/intern/anim.c @@ -638,6 +638,7 @@ static ImBuf * ffmpeg_fetchibuf(struct anim * anim, int position) { AVPacket packet; int64_t pts_to_search = 0; int pos_found = 1; + int filter_y = 0; if (anim == 0) return (0); @@ -722,6 +723,18 @@ static ImBuf * ffmpeg_fetchibuf(struct anim * anim, int position) { } if(frameFinished && pos_found == 1) { + if (anim->ib_flags & IB_animdeinterlace) { + if (avpicture_deinterlace( + anim->pFrame, + anim->pFrame, + anim->pCodecCtx->pix_fmt, + anim->pCodecCtx->width, + anim->pCodecCtx->height) + < 0) { + filter_y = 1; + } + } + if (G.order == B_ENDIAN) { int * dstStride = anim->pFrameRGB->linesize; @@ -823,6 +836,10 @@ static ImBuf * ffmpeg_fetchibuf(struct anim * anim, int position) { av_free_packet(&packet); } + if (filter_y && ibuf) { + IMB_filtery(ibuf); + } + return(ibuf); } @@ -983,6 +1000,7 @@ struct ImBuf * IMB_anim_absolute(struct anim * anim, int position) { char head[256], tail[256]; unsigned short digits; int pic; + int filter_y = (anim->ib_flags & IB_animdeinterlace); if (anim == NULL) return(0); @@ -1040,6 +1058,7 @@ struct ImBuf * IMB_anim_absolute(struct anim * anim, int position) { case ANIM_FFMPEG: ibuf = ffmpeg_fetchibuf(anim, position); if (ibuf) anim->curposition = position; + filter_y = 0; /* done internally */ break; #endif #ifdef WITH_REDCODE @@ -1052,6 +1071,7 @@ struct ImBuf * IMB_anim_absolute(struct anim * anim, int position) { if (ibuf) { if (anim->ib_flags & IB_ttob) IMB_flipy(ibuf); + if (filter_y) IMB_filtery(ibuf); sprintf(ibuf->name, "%s.%04d", anim->name, anim->curposition + 1); } diff --git a/source/blender/src/buttons_scene.c b/source/blender/src/buttons_scene.c index 3797a92f16f..5ab4e5b6741 100644 --- a/source/blender/src/buttons_scene.c +++ b/source/blender/src/buttons_scene.c @@ -900,7 +900,7 @@ static void seq_panel_filter_video() "Convert input to float data"); uiDefButBitI(block, TOG, SEQ_FILTERY, - B_SEQ_BUT_RELOAD, "FilterY", + B_SEQ_BUT_RELOAD_FILE, "FilterY", 170,110,80,19, &last_seq->flag, 0.0, 21.0, 100, 0, "For video movies to remove fields"); diff --git a/source/blender/src/sequence.c b/source/blender/src/sequence.c index bf519dd6e9c..6851929bbc2 100644 --- a/source/blender/src/sequence.c +++ b/source/blender/src/sequence.c @@ -445,7 +445,10 @@ void reload_sequence_new_file(Sequence * seq) seq->strip->len = seq->len; } else if (seq->type == SEQ_MOVIE) { if(seq->anim) IMB_free_anim(seq->anim); - seq->anim = openanim(str, IB_rect); + seq->anim = openanim( + str, IB_rect | + ((seq->flag & SEQ_FILTERY) + ? IB_animdeinterlace : 0)); if (!seq->anim) { return; @@ -1445,7 +1448,7 @@ static void input_preprocess(Sequence * seq, TStripElem* se, int cfra) seq->strip->orx= se->ibuf->x; seq->strip->ory= se->ibuf->y; - if(seq->flag & SEQ_FILTERY) { + if((seq->flag & SEQ_FILTERY) && seq->type != SEQ_MOVIE) { IMB_filtery(se->ibuf); } @@ -1772,8 +1775,11 @@ static void do_build_seq_ibuf(Sequence * seq, TStripElem *se, int cfra, BLI_join_dirfile(name, seq->strip->dir, seq->strip->stripdata->name); BLI_convertstringcode(name, G.sce); BLI_convertstringframe(name, G.scene->r.cfra); - - seq->anim = openanim(name, IB_rect); + + seq->anim = openanim( + name, IB_rect | + ((seq->flag & SEQ_FILTERY) + ? IB_animdeinterlace : 0)); } if(seq->anim) { IMB_anim_set_preseek(seq->anim, seq->anim_preseek); From dac3434b03976b101435572559ebba7a6d1fc862 Mon Sep 17 00:00:00 2001 From: Martin Poirier Date: Sun, 22 Jun 2008 20:40:13 +0000 Subject: [PATCH 238/246] [#14398] In Object- and EditMode, global rotate manual input is different than mouse The sign of the rotation angle was sometimes different between num input and mouse input. --- source/blender/include/transform.h | 6 +++--- source/blender/src/transform.c | 8 ++++---- source/blender/src/transform_constraints.c | 19 ++++++++++++------- source/blender/src/transform_snap.c | 2 +- 4 files changed, 20 insertions(+), 15 deletions(-) diff --git a/source/blender/include/transform.h b/source/blender/include/transform.h index 7d497dc05ec..4e3b80134f9 100644 --- a/source/blender/include/transform.h +++ b/source/blender/include/transform.h @@ -102,9 +102,9 @@ typedef struct TransCon { /* Apply function pointer for linear vectorial transformation */ /* The last three parameters are pointers to the in/out/printable vectors */ void (*applySize)(struct TransInfo *, struct TransData *, float [3][3]); - /* Apply function pointer for rotation transformation (prototype will change */ - void (*applyRot)(struct TransInfo *, struct TransData *, float [3]); - /* Apply function pointer for rotation transformation (prototype will change */ + /* Apply function pointer for size transformation */ + void (*applyRot)(struct TransInfo *, struct TransData *, float [3], float *); + /* Apply function pointer for rotation transformation */ } TransCon; typedef struct TransDataIpokey { diff --git a/source/blender/src/transform.c b/source/blender/src/transform.c index 4270ce6a069..705a5f868e7 100644 --- a/source/blender/src/transform.c +++ b/source/blender/src/transform.c @@ -2621,7 +2621,7 @@ static void applyRotation(TransInfo *t, float angle, float axis[3]) continue; if (t->con.applyRot) { - t->con.applyRot(t, td, axis); + t->con.applyRot(t, td, axis, NULL); VecRotToMat3(axis, angle * td->factor, mat); } else if (t->flag & T_PROP_EDIT) { @@ -2654,7 +2654,7 @@ int Rotation(TransInfo *t, short mval[2]) snapGrid(t, &final); if (t->con.applyRot) { - t->con.applyRot(t, NULL, axis); + t->con.applyRot(t, NULL, axis, &final); } applySnapping(t, &final); @@ -3314,7 +3314,7 @@ int PushPull(TransInfo *t, short mval[2]) } if (t->con.applyRot && t->con.mode & CON_APPLY) { - t->con.applyRot(t, NULL, axis); + t->con.applyRot(t, NULL, axis, NULL); } for(i = 0 ; i < t->total; i++, td++) { @@ -3326,7 +3326,7 @@ int PushPull(TransInfo *t, short mval[2]) VecSubf(vec, t->center, td->center); if (t->con.applyRot && t->con.mode & CON_APPLY) { - t->con.applyRot(t, td, axis); + t->con.applyRot(t, td, axis, NULL); if (isLockConstraint(t)) { float dvec[3]; Projf(dvec, vec, axis); diff --git a/source/blender/src/transform_constraints.c b/source/blender/src/transform_constraints.c index 2d01c2303fc..796b013cb88 100644 --- a/source/blender/src/transform_constraints.c +++ b/source/blender/src/transform_constraints.c @@ -393,7 +393,7 @@ static void applyObjectConstraintSize(TransInfo *t, TransData *td, float smat[3] * (ie: not doing counterclockwise rotations when the mouse moves clockwise). */ -static void applyAxisConstraintRot(TransInfo *t, TransData *td, float vec[3]) +static void applyAxisConstraintRot(TransInfo *t, TransData *td, float vec[3], float *angle) { if (!td && t->con.mode & CON_APPLY) { int mode = t->con.mode & (CON_AXIS0|CON_AXIS1|CON_AXIS2); @@ -413,9 +413,9 @@ static void applyAxisConstraintRot(TransInfo *t, TransData *td, float vec[3]) break; } /* don't flip axis if asked to or if num input */ - if (!(mode & CON_NOFLIP) && hasNumInput(&t->num) == 0) { + if (angle && (mode & CON_NOFLIP) == 0 && hasNumInput(&t->num) == 0) { if (Inpf(vec, t->viewinv[2]) > 0.0f) { - VecMulf(vec, -1.0f); + *angle = -(*angle); } } } @@ -435,10 +435,15 @@ static void applyAxisConstraintRot(TransInfo *t, TransData *td, float vec[3]) * (ie: not doing counterclockwise rotations when the mouse moves clockwise). */ -static void applyObjectConstraintRot(TransInfo *t, TransData *td, float vec[3]) +static void applyObjectConstraintRot(TransInfo *t, TransData *td, float vec[3], float *angle) { - if (td && t->con.mode & CON_APPLY) { + if (t->con.mode & CON_APPLY) { int mode = t->con.mode & (CON_AXIS0|CON_AXIS1|CON_AXIS2); + + /* on setup call, use first object */ + if (td == NULL) { + td= t->data; + } switch(mode) { case CON_AXIS0: @@ -454,9 +459,9 @@ static void applyObjectConstraintRot(TransInfo *t, TransData *td, float vec[3]) VECCOPY(vec, td->axismtx[2]); break; } - if (!(mode & CON_NOFLIP)) { + if (angle && (mode & CON_NOFLIP) == 0 && hasNumInput(&t->num) == 0) { if (Inpf(vec, t->viewinv[2]) > 0.0f) { - VecMulf(vec, -1.0f); + *angle = -(*angle); } } } diff --git a/source/blender/src/transform_snap.c b/source/blender/src/transform_snap.c index 295cfa4574c..04ca5b08755 100644 --- a/source/blender/src/transform_snap.c +++ b/source/blender/src/transform_snap.c @@ -412,7 +412,7 @@ float RotationBetween(TransInfo *t, float p1[3], float p2[3]) if (t->con.applyRot != NULL && (t->con.mode & CON_APPLY)) { float axis[3], tmp[3]; - t->con.applyRot(t, NULL, axis); + t->con.applyRot(t, NULL, axis, NULL); Projf(tmp, end, axis); VecSubf(end, end, tmp); From d229db61e9f7e7e25a2c9c5cb5f4a8ce1623cc4d Mon Sep 17 00:00:00 2001 From: Peter Schlaile Date: Sun, 22 Jun 2008 20:59:29 +0000 Subject: [PATCH 239/246] == Sequencer == Renamed Filter-Y to De-Interlace and moved F-Key to D-Key. (Also added file reload on D-Key) --- source/blender/src/buttons_scene.c | 2 +- source/blender/src/editseq.c | 3 ++- source/blender/src/space.c | 10 ++++------ 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/source/blender/src/buttons_scene.c b/source/blender/src/buttons_scene.c index 5ab4e5b6741..1c98950080a 100644 --- a/source/blender/src/buttons_scene.c +++ b/source/blender/src/buttons_scene.c @@ -900,7 +900,7 @@ static void seq_panel_filter_video() "Convert input to float data"); uiDefButBitI(block, TOG, SEQ_FILTERY, - B_SEQ_BUT_RELOAD_FILE, "FilterY", + B_SEQ_BUT_RELOAD_FILE, "De-Inter", 170,110,80,19, &last_seq->flag, 0.0, 21.0, 100, 0, "For video movies to remove fields"); diff --git a/source/blender/src/editseq.c b/source/blender/src/editseq.c index fb0fac4489d..b9351f82d1e 100644 --- a/source/blender/src/editseq.c +++ b/source/blender/src/editseq.c @@ -2634,12 +2634,13 @@ void set_filter_seq(void) ed= G.scene->ed; if(ed==0) return; - if(okee("Set FilterY")==0) return; + if(okee("Set Deinterlace")==0) return; WHILE_SEQ(ed->seqbasep) { if(seq->flag & SELECT) { if(seq->type==SEQ_MOVIE) { seq->flag |= SEQ_FILTERY; + reload_sequence_new_file(seq); } } diff --git a/source/blender/src/space.c b/source/blender/src/space.c index c49486a6294..585f6b59ceb 100644 --- a/source/blender/src/space.c +++ b/source/blender/src/space.c @@ -4976,11 +4976,13 @@ static void winqreadseqspace(ScrArea *sa, void *spacedata, BWinEvent *evt) } break; case DKEY: - if (G.qual == (LR_CTRLKEY|LR_SHIFTKEY)) + if (G.qual == (LR_CTRLKEY|LR_SHIFTKEY)) { duplicate_marker(); - else if ((G.qual==LR_SHIFTKEY)) { + } else if ((G.qual==LR_SHIFTKEY)) { if(sseq->mainb) break; add_duplicate_seq(); + } else if (G.qual == 0) { + set_filter_seq(); } break; case EKEY: @@ -4988,10 +4990,6 @@ static void winqreadseqspace(ScrArea *sa, void *spacedata, BWinEvent *evt) if((G.qual==0)) transform_seq('e', 0); break; - case FKEY: - if((G.qual==0)) - set_filter_seq(); - break; case GKEY: if (G.qual & LR_CTRLKEY) transform_markers('g', 0); From 90352534930c6c5619abbed60fdd7cf3688d1657 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 22 Jun 2008 21:48:02 +0000 Subject: [PATCH 240/246] [#14392] C3D Import c3d importer for motion capture data This could do with some improvements but for now its acceptable. - Note, could people please not mix tabs and spaces. -Text copied from the patch submission- The c3d_import with 2.46 was able to import a mocap cloud for some c3d files. I have improved it: Version History: 0.4: PERIN Released under Blender Artistic Licence 0.5: WICKES used marker names, fixed 2.45 depricated call 0.6: WICKES creates armature for each subject 0.7: WICKES constrains armature to follow the empties (markers). Verified for shake hands s 0.8: WICKES resolved DEC support issue see also http://wiki.blender.org/index.php/Tutorials%5CMoCap-Section_3 for how this program gets the mocap data into Blender and creates an armature, like the BVH script does. I'd like someone to test and verify, and if accepted, replace the current c3d_import.py --- See patch url for example files http://projects.blender.org/tracker/index.php?func=detail&aid=14392&group_id=9&atid=127 --- release/scripts/c3d_import.py | 1237 +++++++++++++++++++++++++++++++++ 1 file changed, 1237 insertions(+) create mode 100644 release/scripts/c3d_import.py diff --git a/release/scripts/c3d_import.py b/release/scripts/c3d_import.py new file mode 100644 index 00000000000..d67d56261d1 --- /dev/null +++ b/release/scripts/c3d_import.py @@ -0,0 +1,1237 @@ +#!BPY + +""" +Name: 'Motion Capture (.c3d)...' +Blender: 246 +Group: 'Import' +Tooltip: 'Import a C3D Motion Capture file' +""" +__script__ = "C3D Motion Capture file import" +__author__ = " Jean-Baptiste PERIN, Roger D. Wickes (rogerwickes@yahoo.com)" +__version__ = "0.8" +__url__ = ["Communicate problems and errors, BlenderArtists.org, Python forum"] +__email__= ["rogerwickes@yahoo.com", "c3d script"] +__bpydoc__ = """\ +c3d_import.py v0.8 + +Script loading Graphics Lab Motion Capture file, +Usage:
    + - Run the script
    + - Choose the file to open
    + - Press Import C3D button
    + +Version History: + 0.4: PERIN Released under Blender Artistic Licence + 0.5: WICKES used marker names, fixed 2.45 depricated call + 0.6: WICKES creates armature for each subject + 0.7: WICKES constrains armature to follow the empties (markers). Verified for shake hands s + 0.8: WICKES resolved DEC support issue +""" + +#---------------------------------------------- +# (c) Jean-Baptiste PERIN december 2005, released under Blender Artistic Licence +# for the Blender 2.40 Python Scripts Bundle. +#---------------------------------------------- + +###################################################### +# This script imports a C3D file into blender. +# Loader is based on MATLAB C3D loader from +# Alan Morris, Toronto, October 1998 +# Jaap Harlaar, Amsterdam, april 2002 +###################################################### + +import string +import Blender +from Blender import * +import bpy +import struct +import BPyMessages +Vector= Blender.Mathutils.Vector +Euler= Blender.Mathutils.Euler +Matrix= Blender.Mathutils.Matrix +RotationMatrix = Blender.Mathutils.RotationMatrix +TranslationMatrix= Blender.Mathutils.TranslationMatrix + +#================= +# Global Variables, Constants, Defaults, and Shorthand References +#================= +# set senstitivity for displaying debug/console messages. 0=few, 100=max, including clicks at major steps +# debug(num,string) to conditionally display status/info in console window +DEBUG=Blender.Get('rt') + +# marker sets known in the world +HUMAN_CMU= "HumanRTKm.mkr" # The Human Real-Time capture marker set used by CMU +HUMAN_CMU2="HumanRT.mkr" # found in another file, seems same as others in that series +MARKER_SETS = [ HUMAN_CMU, HUMAN_CMU2 ] # marker sets that this program supports (can make an armature for) +XYZ_LIMIT= 10000 #max value for coordinates if in integer format + +# what layers to put stuff on in scene. 1 is selected, so everything goes there +# selecting only layer 2 shows only the armature moving, 12 shows only the empties +LAYERS_ARMOB= [1,2] +LAYERS_MARKER=[1,12] +CLEAN=True # Should program ignore markers at (0,0,0) and beyond the outer limits? + +scn = Blender.Scene.GetCurrent() +# Why on earth would you rename a scene when importing data??? - Campbell +# scn.name="MoCap" #may want this enterable or derived based on motion being analyzed +#TODO: ultimately, a library of motions to append from means you need good naming of things + +BCS=Blender.Constraint.Settings # shorthand dictionary - define with brace, reference with bracket +trackto={"+x":BCS.TRACKX, "+y":BCS.TRACKY, "+z":BCS.TRACKZ, "-x":BCS.TRACKNEGX, "-y":BCS.TRACKNEGY, "-z":BCS.TRACKNEGZ} +trackup={"x":BCS.UPX, "y":BCS.UPY, "z":BCS.UPZ} + +#=============================# +# Classes +#=============================# +class Marker: + def __init__(self, x, y, z): + self.x=0.0 + self.y=0.0 + self.z=0.0 + + def __repr__(self): #report on self, as in if just printed + return str("[x = "+str(self.x) +" y = " + str(self.y)+" z = "+ str(self.z)+"]") + +class ParameterGroup: + def __init__(self, nom, description, parameter): + self.name = nom + self.description = description + self.parameter = parameter + + def __repr__(self): + return self.name, " ", self.description, " ", self.parameter + +class Parameter: + def __init__(self, name, datatype, dim, data, description): + self.name = name + self.datatype = datatype + self.dim = dim + self.data = data + self.description = description + + def __repr__(self): + return self.name, " ", self.description, " ", self.dim + +class MyVector: + def __init__(self, fx,fy,fz): + self.x=fx + self.y=fy + self.z=fz + +class Mybone: + "information structure for bone generation and posing" + def __init__(self, name,vec,par,head,tail,const): + self.name=name # name of this bone. must be unique within armature + self.vec=vec # edit bone vector it points + self.parent=par # name of parent bone to locate head and form a chain + self.headMark=head # list of 0+ markers where the head of this non-parented bone should be placed + self.tailMark=tail # list of 0+ markers where the tip should be placed + self.const=const # list of 0+ constraint tuples to control posing + self.head=MyVector(0,0,0) #T-pose location + self.tail=MyVector(0,0,0) + def __repr__(self): + return '[Mybone "%s"]' % self.name + + +#=============================# +# functions/modules +#=============================# +def error(str): + Draw.PupMenu('ERROR%t|'+str) + return +def status(str): + Draw.PupMenu('STATUS%t|'+str+"|Continue?") + return +def debug(num,msg): #use log4j or just console here. + if DEBUG >= num: + print 'debug:', (' '*num), msg + #TODO: if level 0, make a text file in Blender file to record major stuff + return + +def names(ob): return ob.name + + +######### +# Cette fonction renvoie la liste des empties +# in : +# out : emp_list (List of Object) la liste des objets de type "Empty" +######### +def getEmpty(name): + obs = [ob for ob in scn.objects if ob.type=="Empty" and ob.name==name] + if len(obs)==0: + return None + elif len(obs)==1: + return obs[0] + else: + error("FATAL ERROR: %i empties %s in file" % (len(obs),ob[0])) +######### +# Cette fonction renvoie un empty +# in : objname : le nom de l'empty recherche +# out : myobj : l'empty cree ou retrouve +######### +def GetOrCreateEmpty(objname): + myobj= getEmpty(objname) + if myobj==None: + myobj = scn.objects.new("Empty",objname) + myobj.layers= LAYERS_MARKER + debug(50,'Marker/Empty created %s' % myobj) + return myobj + +def GetOrCreateCurve(ipo, curvename): + """ + Retrieve or create a Blender Ipo Curve named C{curvename} in the C{ipo} Ipo + + >>> import mylib + + >>> lIpo = GetOrCreateIPO("Une IPO") + >>> laCurve = GetOrCreateCurve(lIpo, "RotX") + + Either an ipo curve named C{curvename} exists before the call then this curve is returned, + Or such a curve doesn't exist before the call .. then it is created into the c{ipo} Ipo and returned + + @type ipo: Blender Ipo + @param ipo: the Ipo in which the curve must be retrieved or created. + @type curvename: string + @param curvename: name of the IPO. + @rtype: Blender Curve + @return: a Blender Curve named C{curvename} in the C{ipo} Ipo + """ + try: + mycurve = ipo.getCurve(curvename) + if mycurve != None: + pass + else: + mycurve = ipo.addCurve(curvename) + except: + mycurve = ipo.addCurve(curvename) + return mycurve + +def eraseIPO (objectname): + object = Blender.Object.Get(objectname) + lIpo = object.getIpo() + if lIpo != None: + nbCurves = lIpo.getNcurves() + for i in range(nbCurves): + nbBezPoints = lIpo.getNBezPoints(i) + for j in range(nbBezPoints): + lIpo.delBezPoint(i) + +def comp_loc(emptyNameList): + myloc=Vector(0,0,0) + for emName in emptyNameList: + myobj = Blender.Object.Get(emName) + for i in range(3): + myloc[i]= myloc[i]+(myobj.loc[i]/len(emptyNameList)) #take the average loc of all marks + return myloc + +def comp_len(head, tail): # computes the length of a bone + headvec=comp_loc(head) + tailvec=comp_loc(tail) + netvec=headvec-tailvec + return netvec.length + +def createHumanCMU(): # human bone structure, makes a node set for CMU MoCap Lab + # order of bones: "spine","chest","neck","head",...face toward you in front view + # pose constraints are tuples of (type,target,influence,other-as-needed) + # constraint stack order is important. for proper bone pointing and orinetation: + # IK, then TT +YZ in world space. then LR XZ to 0 in world space, this points the bone, twists it, but then + # limits the rotation to the sidebar enpty with the Z facing it, and Y pointing along the bone. + nodes=[] # bonename, vector, parent, head targets, tail targets, constraint list + for i in range(23): nodes.append(Mybone("name","vec","par",[],[],[])) + nodes[0]= Mybone("root", "-Y","",["RBWT", "LBWT"],["RFWT", "LFWT", "RBWT", "LBWT"],[("LOC","RBWT",1.0),("LOC","LBWT",0.5),("IK","RFWT",1.0),("IK","LFWT",0.5),("TT","RBWT",1,"+YZ"),("LR","XZ",1)]) + nodes[1]= Mybone("spine","+Z","root",[],["STRN","T10"],[("IK","STRN",1.0),("IK","T10",0.5),("TT","STRN",1,"+YZ"),("LR","XZ",1)]) + nodes[2]= Mybone("chest","+Z","spine",[],["CLAV","C7"],[("IK","CLAV",1.0),("IK","C7",0.5),("TT","CLAV",1,"+YZ"),("LR","XZ",1)]) + nodes[3]= Mybone("neck", "+Z","chest",[],["RBHD","LBHD"],[("IK","RBHD",1.0),("IK","LBHD",0.5),("TT","LBHD",1,"+YZ"),("LR","XZ",1)]) + nodes[4]= Mybone("head" ,"-Y","neck",[],["RFHD","LFHD"],[("IK","RFHD",1.0),("IK","LFHD",0.5),("TT","LFHD",1,"+YZ"),("LR","XZ",1)]) + + nodes[5]= Mybone("shoulder.R","-X","chest",[],["RSHO"],[("IK","RSHO",1.0)]) + nodes[6]= Mybone("toparm.R", "-X","shoulder.R",[],["RELB"],[("IK","RELB",1.0),("TT","RUPA",1,"+YZ"),("LR","XZ",1)]) + nodes[7]= Mybone("lowarm.R", "-X","toparm.R",[],["RWRA","RWRB"],[("IK","RWRA",1.0),("IK","RWRB",0.5),("TT","RFRM",1,"+YZ"),("LR","XZ",1)]) + nodes[8]= Mybone("hand.R", "-X","lowarm.R",[],["RFIN"],[("IK","RFIN",1.0),("TT","RWRA",1,"+YZ"),("LR","XZ",1)]) #missing ,"RTHM" + + nodes[9]= Mybone("hip.R", "-X","root",[],["RFWT","RBWT"],[("IK","RFWT",1.0),("IK","RBWT",0.5)]) + nodes[10]=Mybone("topleg.R","-Z","hip.R",[],["RKNE"],[("IK","RKNE",1),("TT","RTHI",1,"+YZ"),("LR","XZ",1)]) + nodes[11]=Mybone("lowleg.R","-Z","topleg.R",[],["RANK","RHEE"],[("IK","RHEE",1.0),("TT","RSHN",1,"+YZ"),("LR","XZ",1)]) + nodes[12]=Mybone("foot.R", "-Y","lowleg.R",[],["RTOE","RMT5"],[("IK","RTOE",1.0),("IK","RMT5",0.2),("TT","RMT5",1,"+YZ")]) + nodes[13]=Mybone("toes.R", "-Y","foot.R",[],["RTOE"],[("IK","RTOE",1.0)]) + + nodes[14]=Mybone("shoulder.L","+X","chest",[],["LSHO"],[("IK","LSHO",1.0)]) + nodes[15]=Mybone("toparm.L", "+X","shoulder.L",[],["LELB"],[("IK","LELB",1.0),("TT","LUPA",1,"+YZ"),("LR","XZ",1)]) + nodes[16]=Mybone("lowarm.L", "+X","toparm.L",[],["LWRA","LWRB"],[("IK","LWRA",1.0),("IK","LWRB",0.5),("TT","LFRM",1,"+YZ"),("LR","XZ",1)]) + nodes[17]=Mybone("hand.L", "+X","lowarm.L",[],["LFIN"],[("IK","LFIN",1.0),("TT","RWRA",1,"+YZ"),("LR","XZ",1)]) #missing ,"LTHM" + + nodes[18]=Mybone("hip.L", "+X","root",[],["LFWT","LBWT"],[("IK","LFWT",1.0),("IK","LBWT",0.5)]) + nodes[19]=Mybone("topleg.L","-Z","hip.L",[],["LKNE"],[("IK","LKNE",1),("TT","LTHI",1,"+YZ"),("LR","XZ",1)]) + nodes[20]=Mybone("lowleg.L","-Z","topleg.L",[],["LANK","LHEE"],[("IK","LHEE",1.0),("TT","LSHN",1,"+YZ"),("LR","XZ",1)]) + nodes[21]=Mybone("foot.L", "-Y","lowleg.L",[],["LTOE","LMT5"],[("IK","LTOE",1.0),("IK","LMT5",0.2),("TT","LMT5",1,"+YZ"),("LR","XZ",1)]) + nodes[22]=Mybone("toes.L", "-Y","foot.L",[],["LTOE"],[("IK","LTOE",1.0)]) + return nodes + +def createNodes(marker_set): # make a list of bone name, parent, edit head loc, edit tail loc, pose constraints + #ultimately, I want to read in an XML file here that specifies the node trees for various marker sets + if marker_set==HUMAN_CMU: nodes= createHumanCMU() #load up and verify the file has the CMU marker set + elif marker_set==HUMAN_CMU2: nodes= createHumanCMU() + else: nodes=[] + return nodes +def findEntry(item,list): + for i in range(len(list)): + if item==list[i]: break + debug(100,"findEtnry %s is %i in list of %i items" % (item,i,len(list))) + return i +def makeNodes(prefix, markerList, empties, marker_set): #make sure the file has the nodes selected + nodes= createNodes(marker_set) # list has generic marker names; replace them with the actual object names created + #each entry in markerlist has a corresponding entry in empties in the same order + errList=[] + for i in range(len(nodes)): + node= nodes[i] + debug(60,"Adapting node %s to prefix %s" % (node,prefix)) + + #replace generic head markers with actual empty names + for im in range(len(node.headMark)): + marker= node.headMark[im] + mark= prefix+marker + imn= findEntry(mark,markerList) + if imn < len(markerList): + debug(90,"Adapating head marker %s to %s" % (marker,empties[imn].name)) + nodes[i].headMark[im]= empties[imn].name + else: errList.append([node.name,"head location",mark,node,2]) + + #replace generic tail markers with actual empty names + for im in range(len(node.tailMark)): + marker= node.tailMark[im] + mark= prefix+marker + imn= findEntry(mark,markerList) + if imn < len(markerList): + debug(90,"Adapating marker %s to %s" % (marker,empties[imn].name)) + nodes[i].tailMark[im]= empties[imn].name + else: errList.append([node.name,"tail location",mark,node,2]) + + #replace generic constraint markers (if the constraint references a marker) with empty name + for im in range(len(node.const)): + const=node.const[im] + if const[0] in ("LOC","IK","TT"): + marker=const[1] + mark= prefix+marker + imn= findEntry(mark,markerList) + if imn < len(markerList): + debug(90,"Adapating %s constraint marker %s to %s" % (const[0],marker,empties[imn].name)) + if const[0] in ("IK","LR","LOC"): + nodes[i].const[im]=(const[0], empties[imn].name, const[2]) + else: nodes[i].const[im]=(const[0], empties[imn].name, const[2], const[3]) + else: errList.append([node.name,const[0]+" constraint",mark,node,4]) + + if errList!=[]: #we have issues. + for err in errList: + debug(0,"Bone "+err[0]+" specifies "+err[2]+" as "+err[1]+"which was not specified in file.") + #need a popup here to ignore/cleanup node tree, or add the marker(?) or abort + usrOption= 1 + if usrOption==0: #ignore this marker (remove it) + for node in nodes: #find the bone in error + if node.name==err[0]: + print "Before",node + if err[3] in range(2,3): + node[err[3]].remove(err[2]) #find the marker in error and remove it + elif err[3]==4: #find the constraint and remove it + for const in node.const: + if const[1]==err[2]: node.const.remove(const) + print "After",node + elif usrOption==1: #add these markers as static empties, and user will automate them later + #and the bones will be keyed to them, so it will all be good. + #file may have just mis-named the empty, or the location can be derived based on other markers + em= GetOrCreateEmpty(err[2]) + else: abort() #abend + if DEBUG==100: status("Nodes Updated") + return nodes #nodes may be updated + +def makeBones(arm,nodes): + debug(20,"Making %i edit bones" % len(nodes)) + for node in nodes: + bone= Blender.Armature.Editbone() + bone.name= node.name + arm.bones[bone.name]= bone #add it to the armature + debug(50,"Bone added: %s" % bone) + if bone.name <> node.name: + debug(0,"ERROR: duplicate node % name specified" % node.name) + node.name= bone.name #you may not get what you asked for + if node.parent!="": #parent + debug(60,"Bone parent: %s"%node.parent) + bone.parent= arm.bones[node.parent] + bone.options = [Armature.CONNECTED] + #compute head = average of the reference empties + if node.headMark==[]: # no head explicitly stated, must be tail of parent + for parnode in nodes: + if node.parent==parnode.name: break + node.headMark= parnode.tailMark + node.head= parnode.tail + else: node.head= comp_loc(node.headMark) #node head is specified, probably only for root. + + bone.head= node.head + debug(60,"%s bone head: (%0.2f, %0.2f, %0.2f)" % (bone.name,bone.head.x, bone.head.y, bone.head.z)) + mylen=comp_len(node.headMark,node.tailMark) # length of the bone as it was recorded for that person + # for our T position, compute the bone length, add it to the head vector component to get the tail + if node.vec[0]=="-": mylen=-mylen + debug(80,"Bone vector %s length %0.2f" %(node.vec,mylen)) + node.tail= Vector(node.head) + myvec=node.vec[1].lower() + if myvec=="x": node.tail.x+=mylen + elif myvec=="y": node.tail.y+=mylen + elif myvec=="z": node.tail.z+=mylen + else: + debug(0,"%s %s %s %s" % (node.vec,myvec,node.vec[0],node.vec[1])) + error("ERROR IN BONE SPEC ") + bone.tail= node.tail + debug(60,"Bone tail: (%i,%i,%i)" %(bone.tail.x, bone.tail.y, bone.tail.z)) + #Armature created in the T postion, but with bone lengths to match the marker set and subject + #when this is constrained to the markers, the recorded action will be relative to a know Rotation + #so that all recorded actions should be interchangeable. wooot! + #Only have to adjust starting object loc when matching up actions. + return #arm #updated + +def makeConstLoc(pbone,const): + const_new= pbone.constraints.append(Constraint.Type.COPYLOC) + const_new.name = const[0]+"-"+const[1] + const_target=Blender.Object.Get(const[1]) + const_new[BCS.TARGET]= const_target + const_new.influence = const[2] + return + +def makeConstLimRot(pbone,const): + const_new= pbone.constraints.append(Constraint.Type.LIMITROT) + const_new.name = const[0]+"-"+const[1] + for axis in const[1]: + if axis.lower()=="x": const_new[BCS.LIMIT] |= BCS.LIMIT_XROT #set + if axis.lower()=="y": const_new[BCS.LIMIT] |= BCS.LIMIT_YROT #set + if axis.lower()=="z": const_new[BCS.LIMIT] |= BCS.LIMIT_ZROT #set + const_new[BCS.OWNERSPACE]= BCS.SPACE_LOCAL + const_new.influence = const[2] + # fyi, const[Constraint.Settings.LIMIT] &= ~Constraint.Settings.LIMIT_XROT #reset + return + +def makeConstIK(prefix,pbone,const): + #Blender 246 only supports one IK Solver per bone, but we might want many, + # so we need to create a reference empty named after the bone + # that floats between the markers, so the bone can point to it as a singularity + myob= GetOrCreateEmpty(prefix+pbone.name) + # note that this empty gets all the IK constraints added on + myconst= myob.constraints.append(Constraint.Type.COPYLOC) + myconst.name=const[0]+"-"+const[1] + myconst[Constraint.Settings.TARGET]= Blender.Object.Get(const[1]) + myconst.influence = const[2] + + #point the bone once to the empty via IK + success=False + for myconst in pbone.constraints: + if myconst.type == Constraint.Type.IKSOLVER: success=True + if not(success): #add an IK constraint to the bone to point to the empty + #print pbone + myconst= pbone.constraints.append(Constraint.Type.IKSOLVER) + myconst.name = const[1] + myconst[BCS.TARGET]= myob + myconst.influence = const[2] + #const_new[Constraint.Settings.BONE]= ? + myconst[BCS.CHAINLEN]= 1 + myconst[BCS.USETIP]= True + myconst[BCS.STRETCH]= False + return + +def makeConstTT(pbone,const): + myconst= pbone.constraints.append(Constraint.Type.TRACKTO) + myconst.name=const[0]+"-"+const[1] + debug(70,"%s %s" % (myconst,const[3])) + myob= GetOrCreateEmpty(const[1]) + myconst[BCS.TARGET]= myob + myconst.influence = const[2] + #const[3] is the Track and the thrird char is the Up indicator + myconst[BCS.TRACK]= trackto[const[3][0:2].lower()] + myconst[BCS.UP]=trackup[const[3][2].lower()]#up direction + myconst[BCS.OWNERSPACE]= BCS.SPACE_LOCAL + myconst[BCS.TARGETSPACE]= [BCS.SPACE_LOCAL] + if const[3][1]==const[3][2]: debug(0,"WARNING: Track To axis and up axis should not be the same. Constraint is INACTIVE") + return + +def makePoses(prefix,arm_ob,nodes): # pose this armature object based on node requirements + #this is constraint-based posing, not hard-keyed posing. + #we do constraint-based first so that user can adjust the constraints, possibly smooth/tweak motion + # add additional bones or referneces/constraints, before baking to hard keyframes + + pose= arm_ob.getPose() + debug(0,"Posing %s %s" % (arm_ob, pose)) + for node in nodes: + debug(30, "examining %s" %node) + if len(node.const)>0: #constraints for this bone are desired + pbone = pose.bones[node.name] + debug(40,"Posing bone %s" %pbone) + for const in node.const: + debug(50,"Constraining %s by %s" %(pbone,const)) + if const[0]=="LOC":makeConstLoc(pbone,const) + elif const[0]=="IK": makeConstIK(prefix,pbone,const) + elif const[0]=="LR": makeConstLimRot(pbone,const) + elif const[0]=="TT": makeConstTT(pbone,const) + else: + error("FATAL: constraint %s not supported" %const[0]) + break + debug(10, "Posing complete. Cycling pose and edit mode") + pose.update() + return + +def make_arm(subject,prefix,markerList, emptyList,marker_set): + debug(10,"**************************") + debug(00, "**** Making Armature for %s..." % subject) + debug(10, "**************************") + # copied from bvh import bvh_node_dict2armature; trying to use similar process for further integtration down the road + # Add the new armature, + + nodes= makeNodes(prefix, markerList, emptyList, marker_set) #assume everyone in file uses the same mocap suit + # each person in the file may be different height, so each needs their own new armature to match marker location + +## obs= Blender.Object.Get() +## success=False +## for ob in obs: +## if ob.name==subject: +## success=True +## if success: +## menu="Human Armature already exists for this subject." +## menu+="%t|Create another in this scene" +## menu+="%l|Start a new scene" +## menu+="%l|Use this armature" +## menusel= Draw.PupMenu(menu) + + arm= Blender.Armature.New(subject) #make an armature. + debug(10,"Created Armature %s" % arm) + # Put us into editmode + arm.makeEditable() + arm.drawType = Armature.OCTAHEDRON + makeBones(arm,nodes) + scn = Blender.Scene.GetCurrent() #add it to the current scene. could create new scenes here as yaf + arm_ob= scn.objects.new(arm) #instance it in the scene. this is the new way for 2.46 to instance objects + arm_ob.name= subject #name it something like the person it represents + arm_ob.layers= LAYERS_ARMOB + debug(20,"Instanced Armature %s" % arm_ob) + arm.update() #exit editmode. Arm must be instanced as an object before you can save changes or pose it + Blender.Redraw() # show the world + if DEBUG==100: status("T-Bones made.") + + makePoses(prefix,arm_ob,nodes) #constrain arm_ob with these markers + + scn.update(1) #make everyone behave themselves in the scene, and respect the new constraints + return arm_ob + +def setupAnim(StartFrame, EndFrame, VideoFrameRate): + debug(100, 'VideoFrameRate is %i' %VideoFrameRate) + if VideoFrameRate<1: VideoFrameRate=1 + if VideoFrameRate>120: VideoFrameRate=120 + # set up anim panel for them + context=scn.getRenderingContext() + context.startFrame(StartFrame) + context.endFrame(EndFrame) + context.framesPerSec(int(VideoFrameRate)) + Blender.Set("curframe",StartFrame) + Blender.Redraw() + return + +def makeCloud(Nmarkers,markerList,StartFrame,EndFrame,Markers): + debug(10, "**************************") + debug(00, "*** Making Cloud Formation") + debug(10, "**************************") + empties=[] + ipos=[] + curvesX=[] + curvesY=[] + curvesZ=[] + debug(0, "%i Markers (empty cloud) will be put on layers %s" % (Nmarkers,LAYERS_MARKER)) + # Empty Cloud formation + for i in range(Nmarkers): + debug(100,"%i marker %s"%(i, markerList[i])) + emptyname = markerList[i] # rdw: to use meaningful names from Points parameter + em= GetOrCreateEmpty(emptyname) #in this scene + #make a list of the actual empty + empties.append(em) + #assign it an ipo with the loc xyz curves + lipo = Ipo.New("Object",em.name) + ipos.append(lipo) + curvesX.append(GetOrCreateCurve(ipos[i],'LocX')) + curvesY.append(GetOrCreateCurve(ipos[i],'LocY')) + curvesZ.append(GetOrCreateCurve(ipos[i],'LocZ')) + empties[i].setIpo(ipos[i]) + debug(30,"Cloud of %i empties created." % len(empties)) + NvideoFrames= EndFrame-StartFrame+1 + debug(10, "**************************") + debug(00, "**** Calculating Marker Ipo Curves over %i Frames ..." % NvideoFrames) + debug(10, "**************************") + err= index=0 #number of errors, logical frame + for frame in range(StartFrame,EndFrame+1): + if index==0: start=sys.time() + elif index==100: + tmp=(NvideoFrames-100)*(sys.time()-start)/6000 + debug(0,"%i minutes process time estimated" % tmp) + elif index >100: print index*100/(NvideoFrames-1),"% complete\r", + for i in range(Nmarkers): + if Markers[index][i].z < 0: Markers[index][i].z= -Markers[index][i].z + success=True + if CLEAN: #check for good data + # C3D marker decoding may have coordinates negative (improper sign bit decoding?) + myX= abs(Markers[index][i].x) + myY= abs(Markers[index][i].y) + myZ= Markers[index][i].z + if myX > 10000 or myY > 10000 or myZ > 10000: success=False + if myX <.01 and myY <.01 and myZ <.01: success=False # discontinuity in marker tracking (lost marker) + + if success: + curvesX[i].append((frame, Markers[index][i].x)) #2.46 knot method + curvesY[i].append((frame, Markers[index][i].y)) + curvesZ[i].append((frame, Markers[index][i].z)) + if frame==StartFrame: debug(40, "%s loc frame %i: (%0.2f, %0.2f, %0.2f)" % (markerList[i],frame,Markers[index][i].x,Markers[index][i].y,Markers[index][i].z)) + else: + err+=1 # some files have thousands... + #debug(30,"Point ignored for marker:%s frame %i: (%i, %i, %i)" % (markerList[i],frame,Markers[index][i].x,Markers[index][i].y,Markers[index][i].z)) + index += 1 + debug(70, "%i points ignored across all markers and frames. Recalculating..." % err) + + for i in range(Nmarkers): + curvesX[i].Recalc() + curvesY[i].Recalc() + curvesZ[i].Recalc() + Blender.Set('curframe', StartFrame) + Blender.Redraw() + if DEBUG==100: status("Clound formed") + return empties + +def getNumber(str, length): + if length==2: # unsigned short + return struct.unpack('H',str[0:2])[0], str[2:] + sum = 0 + for i in range(length): + #sum = (sum << 8) + ord(str[i]) for big endian + sum = sum + ord(str[i])*(2**(8*i)) + return sum, str[length:] +def unpackFloat(chunk,proctype): + #print proctype + myvar=chunk[0:4] + if proctype==2: #DEC-VAX + myvar=chunk[2:4]+chunk[0:2] #swap lo=hi word order pair + return struct.unpack('f',myvar[0:4])[0] + +def getFloat(chunk,proctype): + return unpackFloat(chunk, proctype), chunk[4:] +def parseFloat(chunk,ptr,proctype): + return unpackFloat(chunk[ptr:ptr+4], proctype), ptr+4 + + +def load_c3d(FullFileName): +# Input: FullFileName - file (including path) to be read +# +# Variable: +# Markers 3D-marker data [Nmarkers x NvideoFrames x Ndim(=3)] +# VideoFrameRate Frames/sec +# AnalogSignals Analog signals [Nsignals x NanalogSamples ] +# AnalogFrameRate Samples/sec +# Event Event(Nevents).time ..value ..name +# ParameterGroup ParameterGroup(Ngroups).Parameters(Nparameters).data ..etc. +# CameraInfo MarkerRelated CameraInfo [Nmarkers x NvideoFrames] +# ResidualError MarkerRelated ErrorInfo [Nmarkers x NvideoFrames] + + Markers=[]; + VideoFrameRate=120; + AnalogSignals=[]; + AnalogFrameRate=0; + Event=[]; + ParameterGroups=[]; + CameraInfo=[]; + ResidualError=[]; + + debug(10, "*********************") + debug(10, "**** Opening File ***") + debug(10, "*********************") + + #ind=findstr(FullFileName,'\'); + #if ind>0, FileName=FullFileName(ind(length(ind))+1:length(FullFileName)); else FileName=FullFileName; end + debug(0, "FileName = " + FullFileName) + fid=open(FullFileName,'rb'); # native format (PC-intel). ideasman says maybe rU + content = fid.read(); + content_memory = content + #Header section + NrecordFirstParameterblock, content = getNumber(content,1) # Reading record number of parameter section + + key, content = getNumber(content,1) + if key!=80: + error('File: does not comply to the C3D format') + fid.close() + return + #Paramter section + content = content[512*(NrecordFirstParameterblock-1)+1:] # first word ignored + #file format spec says that 3rd byte=NumberofParmaterRecords... but is ignored here. + proctype,content =getNumber(content,1) + proctype = proctype-83 + proctypes= ["unknown","(INTEL-PC)","(DEC-VAX)","(MIPS-SUN/SGI)"] + + if proctype in (1,2): debug(0, "Processor coding %s"%proctypes[proctype]) + elif proctype==3: debug(0,"Program untested with %s"%proctypes[proctype]) + else: + debug(0, "INVALID processor type %i"%proctype) + proctype=1 + debug(0,"OVERRIDE processor type %i"%proctype) + + #if proctype==2, + # fclose(fid); + # fid=fopen(FullFileName,'r','d'); % DEC VAX D floating point and VAX ordering + #end + debug(10, "***********************") + debug(00, "**** Reading Header ***") + debug(10, "***********************") + + # ############################################### + # ## ## + # ## read header ## + # ## ## + # ############################################### + + #%NrecordFirstParameterblock=fread(fid,1,'int8'); % Reading record number of parameter section + #%key1=fread(fid,1,'int8'); % key = 80; + + content = content_memory + #fseek(fid,2,'bof'); + content = content[2:] + + # + Nmarkers, content=getNumber(content, 2) + NanalogSamplesPerVideoFrame, content = getNumber(content, 2) + StartFrame, content = getNumber(content, 2) + EndFrame, content = getNumber(content, 2) + MaxInterpolationGap, content = getNumber(content, 2) + + Scale, content = getFloat(content,proctype) + + NrecordDataBlock, content = getNumber(content, 2) + NanalogFramesPerVideoFrame, content = getNumber(content, 2) + + if NanalogFramesPerVideoFrame > 0: + NanalogChannels=NanalogSamplesPerVideoFrame/NanalogFramesPerVideoFrame + else: + NanalogChannels=0 + + VideoFrameRate, content = getFloat(content,proctype) + + AnalogFrameRate=VideoFrameRate*NanalogFramesPerVideoFrame + NvideoFrames = EndFrame - StartFrame + 1 + + debug(0, "Scale= %0.2f" %Scale) + debug(0, "NanalogFramesPerVideoFrame= %i" %NanalogFramesPerVideoFrame) + debug(0, "Video Frame Rate= %i" %VideoFrameRate) + debug(0, "AnalogFrame Rate= %i"%AnalogFrameRate) + debug(0, "# markers= %i" %Nmarkers) + debug(0, "StartFrame= %i" %StartFrame) + debug(0, "EndFrame= %i" %EndFrame) + debug(0, "# Video Frames= %i" %NvideoFrames) + + if Scale>0: + debug(0, "Marker data is in integer format") + if Scale>(XYZ_LIMIT/32767): + Scale=XYZ_LIMIT/32767.0 + debug(0, "OVERRIDE: Max coordinate is %i, Scale changed to %0.2f" % (XYZ_LIMIT,Scale)) + else: debug(0, "Marker data is in floating point format") + if VideoFrameRate<1 or VideoFrameRate>120: + VideoFrameRate= 120 + debug(0, "OVERRIDE Video Frame Rate= %i" %VideoFrameRate) + if proctype not in (1,2): # Intel, DEC are known good + debug(0, "OVERRIDE|Program not tested with this encoding. Set to Intel") + proctype= 1 + + debug(10, "***********************") + debug(10, "**** Reading Events ...") + debug(10, "***********************") + + content = content_memory + content = content[298:] #bizarre .. ce devrait être 150 selon la doc rdw skips first 299 bytes? + + EventIndicator, content = getNumber(content, 2) + EventTime=[] + EventValue=[] + EventName=[] + + debug(0, "Event Indicator = %i" %EventIndicator) + if EventIndicator==12345: #rdw: somehow, this original code seems fishy, but I cannot deny it. + Nevents, content = getNumber(content, 2) + debug(0, "Nevents= %i" %Nevents) + content = content[2:] + if Nevents>0: + for i in range(Nevents): + letime, content = getFloat(content,proctype) + EventTime.append(letime) + content = content_memory + content = content[188*2:] + for i in range(Nevents): + lavalue, content = getNumber(content, 1) + EventValue.append(lavalue) + content = content_memory + content = content[198*2:] + for i in range(Nevents): + lenom = content[0:4] + content = content[4:] + EventName.append(lenom) + + debug(00, "***************************") + debug(00, "**** Reading Parameters ...") + debug(10, "***************************") + subjects=[] # a name would be nice, but human will do + prefixes=[] # added on to mocap marker names, one for each subject + marker_subjects = [] # hopefully will be specified in the file and known to this program + markerList=[] + ParameterGroups = [] + ParameterNumberIndex = [] + + content = content_memory + content = content[512*(NrecordFirstParameterblock-1):] + + dat1, content = getNumber(content, 1) + key2, content = getNumber(content, 1) + + NparameterRecords, content = getNumber(content, 1) + debug(100, "NparameterRecords=%i"%NparameterRecords) + proctype,content =getNumber(content,1) + proctype = proctype-83 # proctype: 1(INTEL-PC); 2(DEC-VAX); 3(MIPS-SUN/SGI) + + for i in range(NparameterRecords): + leparam = ParameterGroup(None, None, []) + ParameterGroups.append(leparam) + ParameterNumberIndex.append(0) + # + Ncharacters, content = getNumber(content, 1) + if Ncharacters>=128: + Ncharacters = -(2**8)+(Ncharacters) + GroupNumber, content = getNumber(content, 1) + if GroupNumber>=128: + GroupNumber = -(2**8)+(GroupNumber) + debug(80,"GroupNumber = %i, Nchar=%i" %(GroupNumber,Ncharacters)) + + while Ncharacters > 0: + if GroupNumber<0: + GroupNumber=abs(GroupNumber) + GroupName = content[0:Ncharacters] + content = content[Ncharacters:] + #print "Group Number = ", GroupNumber + ParameterGroups[GroupNumber].name = GroupName + #print "ParameterGroupName =", GroupName + offset, content = getNumber(content, 2) + deschars, content = getNumber(content, 1) + GroupDescription = content[0:deschars] + content = content[deschars:] + ParameterGroups[GroupNumber].description = GroupDescription + # + ParameterNumberIndex[GroupNumber]=0 + content = content[offset-3-deschars:] + else: + + ParameterNumberIndex[GroupNumber]=ParameterNumberIndex[GroupNumber]+1 + ParameterNumber=ParameterNumberIndex[GroupNumber] + #print "ParameterNumber=", ParameterNumber + ParameterGroups[GroupNumber].parameter.append(Parameter(None, None, [], [], None)) + ParameterName = content[0:Ncharacters] + content = content[Ncharacters:] + #print "ParameterName = ",ParameterName + if len(ParameterName)>0: + ParameterGroups[GroupNumber].parameter[ParameterNumber-1].name=ParameterName + offset, content = getNumber(content, 2) + filepos = len(content_memory)-len(content) + nextrec = filepos+offset-2 + + type, content=getNumber(content, 1) + if type>=128: + type = -(2**8)+type + ParameterGroups[GroupNumber].parameter[ParameterNumber-1].type=type + + dimnum, content=getNumber(content, 1) + if dimnum == 0: + datalength = abs(type) + else: + mult=1 + dimension=[] + for j in range (dimnum): + ladim, content = getNumber(content, 1) + dimension.append(ladim) + mult=mult*dimension[j] + ParameterGroups[GroupNumber].parameter[ParameterNumber-1].dim.append(dimension[j]) + datalength = abs(type)*mult + + #print "ParameterNumber = ", ParameterNumber, " Group Number = ", GroupNumber + + if type==-1: + data = "" + wordlength=dimension[0] + if dimnum==2 and datalength>0: + for j in range(dimension[1]): + data=string.rstrip(content[0:wordlength]) + content = content[wordlength:] + ParameterGroups[GroupNumber].parameter[ParameterNumber-1].data.append(data) + elif dimnum==1 and datalength>0: + data=content[0:wordlength] + ParameterGroups[GroupNumber].parameter[ParameterNumber-1].data.append(data) # ??? + + myParam=string.rstrip(ParameterName) + myGroup=string.rstrip(GroupName) + msg= "-%s-%s-" % (myGroup,myParam) + if myGroup == "POINT": + if myParam== "LABELS": + # named in form of subject:marker. + # the list "empties" is a corresponding list of actual empty object names that make up the cloud + markerList= ParameterGroups[GroupNumber].parameter[ParameterNumber-1].data + debug(0, "%sLABELS = %i %s" %(msg, len(markerList),markerList)) #list of logical markers from 0 to n corresponding to points + elif myParam== "LABELS2": #more labels + # named in form of subject:marker. + # the list "empties" is a corresponding list of actual empty object names that make up the cloud + momarkList= ParameterGroups[GroupNumber].parameter[ParameterNumber-1].data + markerList+=momarkList + debug(0, "%sLABELS2 = %i %s" %(msg, len(momarkList),momarkList)) #list of logical markers from 0 to n corresponding to points + else: debug(70, "%s UNUSED = %s" %(msg,ParameterGroups[GroupNumber].parameter[ParameterNumber-1].data)) + elif myGroup in ["SUBJECT", "SUBJECTS"]: #info about the actor + if myParam in ["NAME", "NAMES"]: + subjects= ParameterGroups[GroupNumber].parameter[ParameterNumber-1].data + debug(0, "%sNames of Subjects = %s" %(msg, subjects)) # might be useful in naming armatures + for i in range(len(subjects)): + subjects[i]=subjects[i].rstrip() + if subjects[i]=="": subjects[i]="Human" + elif myParam == "LABEL_PREFIXES": + prefixes = ParameterGroups[GroupNumber].parameter[ParameterNumber-1].data + debug(0, "%sMarker Prefixes = %s" %(msg, prefixes)) # to xlate marker name to that in file + for i in range(len(prefixes)): + prefixes[i]=prefixes[i].rstrip() + elif myParam== "MARKER_SETS": + marker_subjects= ParameterGroups[GroupNumber].parameter[ParameterNumber-1].data + debug(0, "%sMarker Set = %s"%(msg, marker_subjects)) # marker set that each subject was wearing + elif myParam== "MODEL_PARAM": + action= ParameterGroups[GroupNumber].parameter[ParameterNumber-1].data + debug(0, "%sModel Paramter = %s"%(msg,action)) # might be a good name for the blender scene + elif myParam== "LABELS": + # named in form of subject:marker. + # the list "empties" is a corresponding list of actual empty object names that make up the cloud + markerList= ParameterGroups[GroupNumber].parameter[ParameterNumber-1].data + debug(0, "%sLABELS = %i %s"%(msg, len(markerList),markerList)) #list of logical markers from 0 to n corresponding to points + else: debug(70, "%sUNUSED = %s"%(msg, ParameterGroups[GroupNumber].parameter[ParameterNumber-1].data)) + else: + debug(70, "%sUNUSED = %s"%(msg, ParameterGroups[GroupNumber].parameter[ParameterNumber-1].data)) + elif type == 1: + debug(100,"Block type %i is largely unsupported and untested."%type) + data = [] + Nparameters=datalength/abs(type) + debug(100, "Nparameters=%i"%Nparameters) + for i in range(Nparameters): + ladata,content = getNumber(content, 1) + data.append(ladata) + ParameterGroups[GroupNumber].parameter[ParameterNumber-1].data=data + #print ParameterGroups[GroupNumber].parameter[ParameterNumber-1].data + + #print "type boolean" + elif type == 2 and datalength>0: + debug(100,"Block type %i is largely unsupported and untested."%type) + data = [] + Nparameters=datalength/abs(type) + debug(100, "Nparameters=%i"%Nparameters) + for i in range(Nparameters): + ladata,content = getNumber(content, 2) + data.append(ladata) + #ParameterGroups[GroupNumber].parameter[ParameterNumber-1].data=data + if dimnum>1: + #???? print "arg je comprends pas" + ParameterGroups[GroupNumber].parameter[ParameterNumber-1].data=data + #???ParameterGroups[GroupNumber].parameter[ParameterNumber-1].data=reshape(data,dimension) + else: + ParameterGroups[GroupNumber].parameter[ParameterNumber-1].data=data + #print ParameterGroups[GroupNumber].parameter[ParameterNumber-1].data + #pass + #print "type integer" + elif type == 4 and datalength>0: + debug(100,"Block type %i is largely unsupported and untested."%type) + data = [] + Nparameters=datalength/abs(type) + debug(100, "Nparameters=%i"%Nparameters) + for i in range(Nparameters): + ladata,content = getFloat(content,proctype) + data.append(ladata) + if dimnum>1: + ParameterGroups[GroupNumber].parameter[ParameterNumber-1].data=data + #print "arg je comprends pas" + #???ParameterGroups[GroupNumber].parameter[ParameterNumber-1].data=reshape(data,dimension) + else: + ParameterGroups[GroupNumber].parameter[ParameterNumber-1].data=data + #print ParameterGroups[GroupNumber].parameter[ParameterNumber-1].data + else: + debug(100,"Block type %i is largely unsupported and untested."%type) + #print "error" + pass + deschars, content= getNumber(content, 1) + if deschars>0: + description = content[0:deschars] + content = content[deschars:] + ParameterGroups[GroupNumber].parameter[ParameterNumber-1].description=description + + content = content_memory + content = content[nextrec:] + + Ncharacters,content = getNumber(content, 1) + if Ncharacters>=128: + Ncharacters = -(2**8)+(Ncharacters) + GroupNumber,content = getNumber(content, 1) + if GroupNumber>=128: + GroupNumber = -(2**8)+(GroupNumber) + debug(80,"GroupNumber = %i, Nchar=%i" %(GroupNumber,Ncharacters)) + + debug(00, "***************************") + debug(00, "**** Examining Parameters ...") + debug(10, "***************************") + + if len(subjects)==0: subjects=["Test"] #well, somebody got mocapped! + for i in range(0, len(subjects)-len(prefixes)): prefixes.append("") + for i in range(0, len(subjects)-len(marker_subjects)): marker_subjects.append(subjects[i]) + + #make a markerlist if they didn't + debug(0, "%i Markers specified, %i marker names supplied" %(Nmarkers,len(markerList))) + if len(markerList)==0: + debug(0, "File missing any POINT LABELS marker list. Making defaults") + #I guess just make cloud of empty.xxx + if len(markerList)XYZ_LIMIT or abs(myy)>XYZ_LIMIT or abs(myz)>XYZ_LIMIT: + err+=1 + if err>100: + debug(0, "Warning: 100 data points for markers seem way out there") + debug(0, "data read: (%i, %i, %i)" %(x,y,z)) + debug(0, "Consider revising Scale %0.2f" % Scale) + debug(0, "which now givs coordinates: (%i, %i, %i)" %(x*Scale,y*Scale,z*Scale)) + err=-0 + if abs(myx)>XYZ_LIMIT: myx= XYZ_LIMIT*myx/abs(myx) #preserve sign + if abs(myy)>XYZ_LIMIT: myy= XYZ_LIMIT*myy/abs(myy) #preserve sign + if abs(myz)>XYZ_LIMIT: myz= XYZ_LIMIT*myz/abs(myz) #preserve sign + Markers[i][j].x = myx + Markers[i][j].y = myy + Markers[i][j].z = myz + + a,ptr_read = parseFloat(content, ptr_read, proctype) + a = int(a) + highbyte = int(a/256) + lowbyte=a-highbyte*256 + CameraInfo[i][j] = highbyte + ResidualError[i][j] = lowbyte*abs(Scale) + #Monitor marker location to ensure data block is being parsed properly + if j==0: debug(90,"Frame %i loc of %s: (%i, %i, %i)" % (i,markerList[j],myx,myy,myz)) + if i==0: debug(50, "Initial loc of %s: (%i, %i, %i)" % (markerList[j],myx,myy,myz)) + + ptr_read+=residuals #skip over the following + #for j in range (NanalogFramesPerVideoFrame): + # for k in range(NanalogChannels): + # val, content = getNumber(content, 2) + # AnalogSignals[j+NanalogFramesPerVideoFrame*(i)][k]=val #??? i-1 + #else + # for i=1:NvideoFrames + # for j=1:Nmarkers + # Markers(i,j,1:3)=fread(fid,3,'int16')'.*Scale; + # ResidualError(i,j)=fread(fid,1,'int8'); + # CameraInfo(i,j)=fread(fid,1,'int8'); + # end + # waitbar(i/NvideoFrames) + # for j=1:NanalogFramesPerVideoFrame, + # AnalogSignals(j+NanalogFramesPerVideoFrame*(i-1),1:NanalogChannels)=... + # fread(fid,NanalogChannels,'int16')'; + # end + # end + #end + + else: #Scale is positive, but should be <1 to scale down, like 0.05 + two16= -2**16 + if len(content) < NvideoFrames*(Nmarkers*(6+2)+residuals): + error("%i bytes is not enough data for |%i frames|%i markers|%i residual" %(len(content),NvideoFrames,Nmarkers,residuals)) + #Note: I really tried to optimize this loop, since it was taking hours to process + for i in range(NvideoFrames): + if i==0: start=sys.time() + elif i==10: + tmp=(sys.time()-start)*NvideoFrames/600 + debug(0,"%i minutes remaining..." % tmp) + else: print "%i percent complete. On Frame %i Points procesed: %i\r" % (i*100/NvideoFrames,i,i*Nmarkers), + + for j in range(Nmarkers): + #x, content = getNumber(content,2) + # this is old skool signed int, not but not a short. + x = ord(content[ptr_read+0]) + (ord(content[ptr_read+1])<<8) + if x>32768: x+=two16 + y = ord(content[ptr_read+2]) + (ord(content[ptr_read+3])<<8) + if y>32768: y+=two16 + z = ord(content[ptr_read+4]) + (ord(content[ptr_read+5])<<8) + if z>32768: z+=two16 + +## +## x = ord(content[ptr_read]) + ord(content[ptr_read+1])*(2**8) +## ptr_read+=2 +## if x > 32768: +## x=-(2**16)+(x) +## #y, content = getNumber(content,2) +## y = ord(content[ptr_read]) + ord(content[ptr_read+1])*(2**8) +## ptr_read+=2 +## if y > 32768: +## y=-(2**16)+(y) +## #z, content = getNumber(content,2) +## z = ord(content[ptr_read]) + ord(content[ptr_read+1])*(2**8) +## ptr_read+=2 +## if z > 32768: +## z=-(2**16)+(z) +## +## print "(%i=%i, %i=%i, %i=%i)" %(x,myx,y,myy,z,myz) + + # for integers, I changed Scale above to avoid getting impossible numbers + Markers[i][j].x = x*Scale + Markers[i][j].y = y*Scale + Markers[i][j].z = z*Scale + +## ResidualError[i][j], content = getNumber(content, 1) +## CameraInfo[i][j], content = getNumber(content, 1) + #try to improve performance by: + ResidualError[i][j]= ord(content[ptr_read+6]) + CameraInfo[i][j]= ord(content[ptr_read+7]) + + content= content[ptr_read+8:] + ptr_read=0 + + if j==0: debug(100,"Frame %i loc of %s: %s" % (i,markerList[j],Markers[i][j])) + if i==0: debug(50, "Initial loc of %s: (%s)" % (markerList[j],Markers[i][j])) + + #for j in range (NanalogFramesPerVideoFrame): + # for k in range(NanalogChannels): + # val, content = getNumber(content, 2) + #AnalogSignals(j+NanalogFramesPerVideoFrame*(i-1),1:NanalogChannels)=val + ptr_read= residuals # skip over the above + print "\ndone with file." + fid.close() + + cloud= makeCloud(Nmarkers,markerList,StartFrame,EndFrame,Markers) + + setupAnim(StartFrame, EndFrame,VideoFrameRate) + + debug(10, "**************************") + debug(00, "**** Making %i Armatures" % len(subjects)) + debug(10, "**************************") + for i in range(len(subjects)): + marker_set= marker_subjects[i] + success=False + if len(marker_set)>0: + for trymark in MARKER_SETS: + if trymark[0:len(marker_set)]==marker_set: + marker_set=trymark + success=True + if success: + debug(0, "Armature for %s will be put on layers %s" % (subjects[i],LAYERS_ARMOB)) + debug(0, " based on an markers beginning with %s" % prefixes[i]) + ob= make_arm(subjects[i],prefixes[i],markerList,cloud,marker_set) + else: + debug(00, "Presently, this program can automatically create a constrained armature for marker sets %s" % MARKER_SETS) + debug(00, "%s uses an unknown marker set %s" % (subjects[i],marker_set)) + debug(10, "Have a nice day! If you figure out an armature node system for this cloud, please add it to the program.") + + debug(10, "**************************") + debug(00, "**** Conclusion") + minmax=[0,0,0,0,0,0] + for i in range(NvideoFrames): + for j in range(Nmarkers): + if minmax[0]>Markers[i][j].x: minmax[0]=Markers[i][j].x + if minmax[1]>Markers[i][j].y: minmax[1]=Markers[i][j].y + if minmax[2]>Markers[i][j].z: minmax[2]=Markers[i][j].z + if minmax[3] Date: Sun, 22 Jun 2008 22:46:02 +0000 Subject: [PATCH 241/246] [#14405] New python Script - Bake Constraints AGAIN PLEAST USE TABS, lost quite some time with mixed tab/space adjustments alone. Other then that, patch is very useful ;) ---Text from patch submission --- Using a slightly revised BPy_Armature, this script takes any non-armature object type and creates an Action that keys the object location (by default, for every frame). If it is an Armature, it goes into each bone and keys the locrot of the bone. You can now edit the armature, but the motions still rotate the bones. This enables the next step, re-targeting, which changes bone lengths to fit a mesh. High-level, we are working toward: 1. import mocap (bvh or c3d) 2. bake to make an action library (using this script) 3. re-target and use the actions to drive/deform any character mesh (theeth) --- release/scripts/animation_bake_constraints.py | 800 ++++++++++++++++++ release/scripts/bpymodules/BPyArmature.py | 75 +- 2 files changed, 845 insertions(+), 30 deletions(-) create mode 100644 release/scripts/animation_bake_constraints.py diff --git a/release/scripts/animation_bake_constraints.py b/release/scripts/animation_bake_constraints.py new file mode 100644 index 00000000000..130e93d8591 --- /dev/null +++ b/release/scripts/animation_bake_constraints.py @@ -0,0 +1,800 @@ +#!BPY + +""" +Name: 'Bake Constraints' +Blender: 246 +Group: 'Animation' +Tooltip: 'Bake a Constrained object/rig to IPOs' +Fillename: 'Bake_Constraint.py' +""" + +__author__ = "Roger Wickes (rogerwickes(at)yahoo.com)" +__script__ = "Bake Constraints" +__version__ = "0.6" +__url__ = ["Communicate problems and errors, http://www.blenderartists.com/forum/private.php?do=newpm to PapaSmurf"] +__email__= ["Roger Wickes, rogerwickes@yahoo.com", "scripts"] +__bpydoc__ = """\ + +bake_constraints + +This script bakes the real-world LocRot of an object (the net effect of any constraints - +(Copy, Limit, Track, Follow, - that affect Location, Rotation) +(usually one constrained to match another's location and/or Tracked to another) +and creates a clone with a set of Ipo Curves named Ipo +These curves control a non-constrained object and thus make it mimic the constrained object +Actions can be then be edited without the need for the drivers/constraining objects + +Developed for use with MoCap data, where a bone is constrained to point at an empty +moving through space and time. This records the actual locrot of the armature +so that the motion can be edited, reoriented, scaled, and used as NLA Actions + +see also wiki Scripts/Manual/ Sandbox/Animation/Bake_Constraints (tbd) + +Usage:
    + - Select the reference Object(s) you want to bake
    + - Set the frame range to bake in the Anim Panel
    + - Set the test code (if you want a self-test) in the RT field in the Anim Panel
    + -- Set RT:1 in the Anim panel to create a test armature
    +
    + - Run the script
    + - The clone copy of the object is created and it has an IPO curve assigned to it. + - The clone shadows the object by an offset locrot (see usrDelta) + - That Ipo has Location and Rotation curves that make the shadow mimic the movement of the selected object, + but without using constraints. Bones move identically in relation to the armature as the reference object + + +Version History: + 0.1: bakes Loc Rot for a constrained object + 0.2: bakes Loc and Rot for the bones within Armature object + 0.3: UI for setting options + 0.3.1 add manual to script library + 0.4: bake multiple objects + 0.5: root bone worldspace rotation + 0.6: re-integration with BPyArmature + +License, Copyright, and Attribution: + by Roger WICKES May 2008, released under Blender Artistic Licence to Public Domain + feel free to add to any Blender Python Scripts Bundle. + Thanks to Jean-Baptiste PERIN, IdeasMan42 (Campbell Barton?), Basil_Fawlty/Cage_drei (Andrew Cruse) + much lifted/learned from blender.org/documentation/245PytonDoc and wiki + some modules based on c3D_Import.py, PoseLib16.py and IPO/Armature code examples e.g. camera jitter + +Pseudocode (planned versions): + Initialize + If at least one object is selected + For each selected object, + create a shadow object + remove any constraints on the clone + create or reset an ipo curve named like the object + for each frame + set the clone's locrot key based on the reference object + if it's an armature, + create an action (which is an Ipo for each bone) + for each frame of the animation + for each bone in the armature + set the key + Else you're a smurf + +Test Conditions and Regressions: + 1. (v0.1) Non-armatures (the cube), with ipo curve and constraints at the object level + 2. armatures, with ipo curve and constraints at the object level + 3. armatures, with bones that have ipo curves and constraints + +Naming conventions: + arm = a specific objec type armature + bone = bones that make up the skeleton of an armature + + ob = object, an instance of an object type + ebone = edit bone, a bone in edit mode + pbone = pose bone, a posed bone in an object + tst = testing, self-test routines + usr = user-entered or designated stuff + +Pattern Notes (let me know if I've violated any): + Bergin Starting,Designing, Programming, Coding + Bergin 23 Indent for Structure - I don't like only 2, but the editor is set up that way + Bergin 26 Be Spacey Not Tabby - personal frustraion here. workaround is to Format->convert to whitespace + Bergin 27 Consistent Capitalization - except Blender, because I love it. + Bergin 28 Name Your Constants - not for those I plan on making variable + Python 01 Return Everything - I made this one up, all functions and methods end in return + even though it is decoration in Python, it helps Python throw an indentation error for typing mistakes + Wickes 01 Decorate Your Code - for visual appeal and to ease maintenance, include separators like ######### + to visually distinquish and separate functions, making it quicker to scan through code for methods + Wickes 02 Whitespace helps readability - include blanks around = # and lines (after def, after return) to make it stand out and pretty + +""" +######################################## + +import Blender +from Blender import * +from Blender.Mathutils import * +import struct +import string +import bpy +import BPyMessages +import BPyArmature +# reload(BPyArmature) +from BPyArmature import getBakedPoseData + +Vector= Blender.Mathutils.Vector +Euler= Blender.Mathutils.Euler +Matrix= Blender.Mathutils.Matrix #invert() function at least +RotationMatrix = Blender.Mathutils.RotationMatrix +TranslationMatrix= Blender.Mathutils.TranslationMatrix +Quaternion = Blender.Mathutils.Quaternion +Vector = Blender.Mathutils.Vector +POSE_XFORM= [Blender.Object.Pose.LOC, Blender.Object.Pose.ROT] + +#================= +# Global Variables +#================= + +# set senstitivity for displaying debug/console messages. 0=none, 100=max +# then call debug(num,string) to conditionally display status/info in console window +MODE=Blender.Get('rt') #execution mode: 0=run normal, x=self-test (test error trapping etc) +DEBUG=100 #how much detail on internal processing for big brother to see +BATCH=False #called from command line? is someone there? Would you like some cake? + +#there are two coordinate systems, the real, or absolute 3D space, +# and the local relative to a parent. +COORDINATE_SYSTEMS = ['local','real'] +COORD_LOCAL = 0 +COORD_REAL = 1 + +# User Settings - Change these options manually or via GUI (future TODO) +usrCoord = COORD_REAL # what the user wants +usrParent = False # True=keep parent (if exists), False = breakaway (usually with Real) +usrFreeze = 2 #2=yes, 0=no. Freezes shadow object in place at current frame as origin + #TODO - i wonder if usrFreeze means we should set Delta to the the difference between the original object and parent? +# delta is amount to offset/change from the reference object. future set in a ui, so technically not a constant +usrDelta = [10,10,0,0,0,0] #order specific - Loc xyz Rot xyz +usrACTION = True # Offset baked Action frames to start at frame 1 +usrBAKEobjIPO = False # bake the object Ipo? it is useless for MoCap, as we only want the Action, and the Object does not move + +CURFRAME = 'curframe' #keyword to use when getting the frame number that the scene is presently on +ARMATURE = 'Armature' #en anglais +BONE_SPACES = ['ARMATURESPACE','BONESPACE'] + # 'ARMATURESPACE' - this matrix of the bone in relation to the armature + # 'BONESPACE' - the matrix of the bone in relation to itself + +#Ipo curves created are prefixed with a name, like Ipo_ or Bake_ followed by the object/bone name +#bakedArmName = "b." #used for both the armature class and object instance +#ipoObjectNamePrefix= "" +#ipoBoneNamePrefix = "" +# for example, if on entry an armature named Man was selected, and the object prefix was "a." +# on exit an armature and an IPO curve named a.Man exists for the object as a whole +# if that armature had bones (spine, neck, arm) and the bone prefix was "a." +# the bones and IPO curves will be (a.spine, a.neck, a.arm) + +R2D = 18/3.1415 # radian to grad +BLENDER_VERSION = Blender.Get('version') + +# Gets the current scene, there can be many scenes in 1 blend file. +scn = Blender.Scene.GetCurrent() + +#================= +# Methods +#================= +######################################## +def debug(num,msg): #use log4j or just console here. + + if DEBUG >= num: + if BATCH == False: + print 'debug: '[:num/10+7]+msg + #TODO: else write out to file (runs faster if it doesnt have to display details) + return + +######################################## +def error(str): + debug(0,'ERROR: '+str) + if BATCH == False: + Draw.PupMenu('ERROR%t|'+str) + return + +######################################## +def getRenderInfo(): + context=scn.getRenderingContext() + staframe = context.startFrame() + endframe = context.endFrame() + if endframe 245: debug(0,'WARNING: Programmer check for Bone updates in dupliArmature') + + eboneNames = sortBones(xbones) + + i=0 + # error('bones sorted. continue?') + for abone in eboneNames: #set all editable attributes to fully define the bone. + for bone in xbones: + if bone.name == abone: break # get the reference bone + ebone = Armature.Editbone() #throw me a bone, bone-man! + ebones.append(ebone) #you're on my list, buddy + + ebone.name = bone.name + ebone.headRadius = bone.headRadius + ebone.tailRadius = bone.tailRadius + ebone.weight = bone.weight + ebone.options = bone.options + + ebone.head = bone.head[space] #dictionary lookups + ebone.tail = bone.tail[space] + ebone.matrix = bone.matrix[space] + ebone.roll = bone.roll[space] + + debug(30,'Generating new %s as child of %s' % (bone,bone.parent)) + if bone.hasParent(): +# parent=bone.parent.name +# debug(100,'looking for %s' % parent) +# for parbone in xbones: if parbone.name == parent: break # get the parent bone +# ebone.parent = arm.bones[ebones[j].name] + ebone.parent = arm.bones[bone.parent.name] +# else: +# ebone.parent = None + debug(30,'Generating new editbone %s as child of %s' % (ebone,ebone.parent)) + arm.bones[ebone.name] = ebone # i would have expected an append or add function, but this works + + debug (100,'arm.bones: \n%s' % arm.bones) + debug (20,'Cloned %i bones now in armature %s' %(len(arm.bones),arm.name)) + + myob = scn.objects.new(arm) #interestingly, object must be created before + arm.update() #armature can be saved + debug(40,'dupArm finished %s instanced as object %s' % (arm.name,myob.getName())) + print ob.matrix + print myob.matrix + + return myob + +def scrub(): # scrubs to startframe + staFrame,endFrame,curFrame = getRenderInfo() + + # eye-candy, go from current to start, fwd or back + if not BATCH: + print "Positioning to start..." + frameinc=(staFrame-curFrame)/10 + if abs(frameinc) >= 1: + for i in range(10): + curFrame+=frameinc + Blender.Set(CURFRAME,curFrame) # computes the constrained location of the 'real' objects + Blender.Redraw() + Blender.Set(CURFRAME, staFrame) + +######################################## +def bakeBones(ref_ob,arm_ob): #copy pose from ref_ob to arm_ob + scrub() + staFrame,endFrame,curFrame = getRenderInfo() + act = getBakedPoseData(ref_ob, staFrame, endFrame, ACTION_BAKE = True, ACTION_BAKE_FIRST_FRAME = usrACTION) # bake the pose positions of the reference ob to the armature ob + arm_ob.action = act + scrub() + + # user comprehension feature - change action name and channel ipo names to match the names of the bone they drive + debug (80,'Renaming each action ipo to match the bone they pose') + act.name = arm_ob.name + arm_channels = act.getAllChannelIpos() + pose= arm_ob.getPose() + pbones= pose.bones.values() #we want the bones themselves, not the dictionary lookup + print arm_channels.keys() + for pbone in pbones: + debug (100,'Channel listing for %s: %s' % (pbone.name,arm_channels[pbone.name] )) + ipo=arm_channels[pbone.name] + ipo.name = pbone.name # since bone names are unique within an armature, the pose names can be the same since they are within an Action + + return + +######################################## +def getOrCreateCurve(ipo, curvename): + + """ + Retrieve or create a Blender Ipo Curve named C{curvename} in the C{ipo} Ipo + Either an ipo curve named C{curvename} exists before the call then this curve is returned, + Or such a curve doesn't exist before the call .. then it is created into the c{ipo} Ipo and returned + """ + try: + mycurve = ipo.getCurve(curvename) + if mycurve != None: + pass + else: + mycurve = ipo.addCurve(curvename) + except: + mycurve = ipo.addCurve(curvename) + return mycurve + +######################################## +def eraseCurve(ipo,numCurves): + debug(80,'Erasing %i curves for %' % (numCurves,ipo.GetName())) + for i in range(numCurves): + nbBezPoints = ipo.getNBezPoints(i) + for j in range(nbBezPoints): + ipo.delBezPoint(i) + return + +######################################## +def resetIPO(ipo): + ipoName=ipoObjectNamePrefix + obName + debug(40,'Resetting ipo curve named %s' %ipoName) + numCurves = ipo.getNcurves() #like LocX, LocY, etc + if numCurves > 0: + eraseCurve(ipo, numCurves) #erase data if one exists + return + +######################################## +def resetIPOs(ob): #resets all IPO curvess assocated with an object and its bones + debug(30,'Resetting any ipo curves linked to %s' %ob.getName()) + ipo = ob.getIpo() #may be None + ipoName = ipo.getName() #name of the IPO that guides/controls this object + debug(70,'Object IPO is %s' %ipoName) + try: + ipo = Ipo.Get(ipoName) + except: + ipo = Ipo.New('Object', ipoName) + resetIPO(ipo) + if ob.getType() == ARMATURE: + arm_data=ob.getData() + bones=arm_data.bones.values() + for bone in bones: + #for each bone: get the name and check for a Pose IPO + debug(10,'Processing '+ bone.name) + return + +######################################## +def parse(string,delim): + index = string.find(delim) # -1 if not found, else pointer to delim + if index+1: return string[:index] + return string + +######################################## +def newIpo(ipoName): #add a new Ipo object to the Blender scene + ipo=Blender.Ipo.New('Object',ipoName) + + ipo.addCurve('LocX') + ipo.addCurve('LocY') + ipo.addCurve('LocZ') + ipo.addCurve('RotX') + ipo.addCurve('RotY') + ipo.addCurve('RotZ') + return ipo + +######################################## +def makeUpaName(type,name): #i know this exists in Blender somewhere... + debug(90,'Making up a new %s name using %s as a basis.' % (type,name)) + name = (parse(name,'.')) + if type == 'Ipo': + ipoName = name # maybe we get lucky today + ext = 0 + extlen = 3 # 3 digit extensions, like hello.002 + success = False + while not(success): + try: + debug(100,'Trying %s' % ipoName) + ipo = Ipo.Get(ipoName) + #that one exists if we get here. add on extension and keep trying + ext +=1 + if ext>=10**extlen: extlen +=1 # go to more digits if 999 not found + ipoName = '%s.%s' % (name, str(ext).zfill(extlen)) + except: # could not find it + success = True + name=ipoName + else: + debug (0,'FATAL ERROR: I dont know how to make up a new %s name based on %s' % (type,ob)) + return + return name + +######################################## +def createIpo(ob): #create an Ipo and curves and link them to this object + #first, we have to create a unique name + #try first with just the name of the object to keep things simple. + ipoName = makeUpaName('Ipo',ob.getName()) # make up a name for a new Ipo based on the object name + + debug(20,'Ipo and LocRot curves called %s' % ipoName) + + ipo=newIpo(ipoName) + + ob.setIpo(ipo) #link them + return ipo + +######################################## +def getLocLocal(ob): + key = [ + ob.LocX, + ob.LocY, + ob.LocZ, + ob.RotX*R2D, #get the curves in this order + ob.RotY*R2D, + ob.RotZ*R2D + ] + return key + +######################################## +def getLocReal(ob): + obMatrix = ob.matrixWorld #Thank you IdeasMan42 + loc = obMatrix.translationPart() + rot = obMatrix.toEuler() + key = [ + loc.x, + loc.y, + loc.z, + rot.x/10, + rot.y/10, + rot.z/10 + ] + return key + +######################################## +def getLocRot(ob,space): + if space in xrange(len(COORDINATE_SYSTEMS)): + if space == COORD_LOCAL: + key = getLocLocal(ob) + return key + elif space == COORD_REAL: + key = getLocReal(ob) + return key + else: #hey, programmers make mistakes too. + debug(0,'Fatal Error: getLoc called with %i' % space) + return + +######################################## +def getCurves(ipo): + ipos = [ + ipo[Ipo.OB_LOCX], + ipo[Ipo.OB_LOCY], + ipo[Ipo.OB_LOCZ], + ipo[Ipo.OB_ROTX], #get the curves in this order + ipo[Ipo.OB_ROTY], + ipo[Ipo.OB_ROTZ] + ] + return ipos + +######################################## +def addPoint(time,keyLocRot,ipos): + if BLENDER_VERSION < 245: + debug(0,'WARNING: addPoint uses BezTriple') + for i in range(len(ipos)): + point = BezTriple.New() #this was new with Blender 2.45 API + point.pt = (time, keyLocRot[i]) + point.handleTypes = [1,1] + + ipos[i].append(point) + return ipos + +######################################## +def bakeFrames(ob,myipo): #bakes an object in a scene, returning the IPO containing the curves + myipoName = myipo.getName() + debug(20,'Baking frames for scene %s object %s to ipo %s' % (scn.getName(),ob.getName(),myipoName)) + ipos = getCurves(myipo) + #TODO: Gui setup idea: myOffset + # reset action to start at frame 1 or at location + myOffset=0 #=1-staframe + #loop through frames in the animation. Often, there is rollup and the mocap starts late + staframe,endframe,curframe = getRenderInfo() + for frame in range(staframe, endframe+1): + debug(80,'Baking Frame %i' % frame) + #tell Blender to advace to frame + Blender.Set(CURFRAME,frame) # computes the constrained location of the 'real' objects + if not BATCH: Blender.Redraw() # no secrets, let user see what we are doing + + #using the constrained Loc Rot of the object, set the location of the unconstrained clone. Yea! Clones are FreeMen + key = getLocRot(ob,usrCoord) #a key is a set of specifed exact channel values (LocRotScale) for a certain frame + key = [a+b for a,b in zip(key, usrDelta)] #offset to the new location + + myframe= frame+myOffset + Blender.Set(CURFRAME,myframe) + + time = Blender.Get('curtime') #for BezTriple + ipos = addPoint(time,key,ipos) #add this data at this time to the ipos + debug(100,'%s %i %.3f %.2f %.2f %.2f %.2f %.2f %.2f' % (myipoName, myframe, time, key[0], key[1], key[2], key[3], key[4], key[5])) + # eye-candy - smoothly rewind the animation, showing now how the clone match moves + if endframe-staframe <400 and not BATCH: + for frame in range (endframe,staframe,-1): #rewind + Blender.Set(CURFRAME,frame) # computes the constrained location of the 'real' objects + Blender.Redraw() + Blender.Set(CURFRAME,staframe) + Blender.Redraw() + + return ipos + +######################################## +def duplicateLinked(ob): + obType = ob.type + debug(10,'Duplicating %s Object named %s' % (obType,ob.getName())) + scn.objects.selected = [ob] +## rdw: simplified by just duplicating armature. kept code as reference for creating armatures +## disadvantage is that you cant have clone as stick and original as octahedron +## since they share the same Armature. User can click Make Single User button. +## if obType == ARMATURE: #build a copy from scratch +## myob= dupliArmature(ob) +## else: + Blender.Object.Duplicate() # Duplicate linked, including pose constraints. + myobs = Object.GetSelected() #duplicate is top on the list + myob = myobs[0] + if usrParent == False: + myob.clrParent(usrFreeze) + debug(20,'=myob= was created as %s' % myob.getName()) + return myob + +######################################## +def removeConstraints(ob): + for const in ob.constraints: + debug(90,'removed %s => %s' % (ob.name, const)) + ob.constraints.remove(const) + return + +######################################## +def removeConstraintsOb(ob): # from object or armature + debug(40,'Removing constraints from '+ob.getName()) + if BLENDER_VERSION > 241: #constraints module not available before 242 + removeConstraints(ob) + if ob.getType() == ARMATURE: + pose = ob.getPose() + for pbone in pose.bones.values(): + #bone = pose.bones[bonename] + removeConstraints(pbone) + #should also check if it is a deflector? + return + +######################################## +def deLinkOb(type,ob): #remove linkages + if type == 'Ipo': + success = ob.clearIpo() #true=there was one + if success: debug(80,'deLinked Ipo curve to %s' % ob.getName()) + return + +######################################## +def bakeObject(ob): #bakes the core object locrot and assigns the Ipo to a Clone + if ob != None: + # Clone the object - duplicate it, clean the clone, and create an ipo curve for the clone + myob = duplicateLinked(ob) #clone it + removeConstraintsOb(myob) #my object is a free man + deLinkOb('Ipo',myob) #kids, it's not nice to share. you've been lied to + if usrBAKEobjIPO: + myipo = createIpo(myob) #create own IPO and curves for the clone object + ipos = bakeFrames(ob,myipo) #bake the locrot for this obj for the scene frames + +# staframe,endframe,curframe = getRenderInfo() +# frame = staframe +# Blender.Set(CURFRAME,frame) # computes the constrained location of the 'real' objects +# frame +=1 +# Blender.Set(CURFRAME,frame) # computes the constrained location of the 'real' objects +# frame -=1 +# Blender.Set(CURFRAME,frame) # computes the constrained location of the 'real' objects +# if not BATCH: Blender.Redraw() +# + return myob + +######################################## +def bake(ob): #bakes an object of any type + + debug(30,'Baking %s object %s' % (ob.getType(), ob)) + + myob = bakeObject(ob) #creates and bakes the object motion + + if ob.getType() == ARMATURE: +# error('Object baked. Continue with bones?') + bakeBones(ob,myob) #go into the bones and copy from -> to in frame range + #future idea: bakeMesh (net result of Shapekeys, Softbody, Cloth, Fluidsim,...) + + return + +######################################## +def tstCreateArm(): #create a test armature in scene + # rip-off from http://www.blender.org/documentation/245PythonDoc/Pose-module.html - thank you! + + debug(0,'Making Test Armature') + # New Armature + arm_data= Armature.New('myArmature') + print arm_data + arm_ob = scn.objects.new(arm_data) + arm_data.makeEditable() + + # Add 4 bones + ebones = [Armature.Editbone(), Armature.Editbone(), Armature.Editbone(), Armature.Editbone()] + + # Name the editbones + ebones[0].name = 'Bone.001' + ebones[1].name = 'Bone.002' + ebones[2].name = 'Bone.003' + ebones[3].name = 'Bone.004' + + # Assign the editbones to the armature + for eb in ebones: + arm_data.bones[eb.name]= eb + + # Set the locations of the bones + ebones[0].head= Mathutils.Vector(0,0,0) + ebones[0].tail= Mathutils.Vector(0,0,1) #tip + ebones[1].head= Mathutils.Vector(0,0,1) + ebones[1].tail= Mathutils.Vector(0,0,2) + ebones[2].head= Mathutils.Vector(0,0,2) + ebones[2].tail= Mathutils.Vector(0,0,3) + ebones[3].head= Mathutils.Vector(0,0,3) + ebones[3].tail= Mathutils.Vector(0,0,4) + + ebones[1].parent= ebones[0] + ebones[2].parent= ebones[1] + ebones[3].parent= ebones[2] + + arm_data.update() + # Done with editing the armature + + # Assign the pose animation + arm_pose = arm_ob.getPose() + + act = arm_ob.getAction() + if not act: # Add a pose action if we dont have one + act = Armature.NLA.NewAction() + act.setActive(arm_ob) + + xbones=arm_ob.data.bones.values() + pbones = arm_pose.bones.values() + + frame = 1 + for pbone in pbones: # set bones to no rotation + pbone.quat[:] = 1.000,0.000,0.000,0.0000 + pbone.insertKey(arm_ob, frame, Object.Pose.ROT) + + # Set a different rotation at frame 25 + pbones[0].quat[:] = 1.000,0.1000,0.2000,0.20000 + pbones[1].quat[:] = 1.000,0.6000,0.5000,0.40000 + pbones[2].quat[:] = 1.000,0.1000,0.3000,0.40000 + pbones[3].quat[:] = 1.000,-0.2000,-0.3000,0.30000 + + frame = 25 + for i in xrange(4): + pbones[i].insertKey(arm_ob, frame, Object.Pose.ROT) + + pbones[0].quat[:] = 1.000,0.000,0.000,0.0000 + pbones[1].quat[:] = 1.000,0.000,0.000,0.0000 + pbones[2].quat[:] = 1.000,0.000,0.000,0.0000 + pbones[3].quat[:] = 1.000,0.000,0.000,0.0000 + + frame = 50 + for pbone in pbones: # set bones to no rotation + pbone.quat[:] = 1.000,0.000,0.000,0.0000 + pbone.insertKey(arm_ob, frame, Object.Pose.ROT) + + return arm_ob + +######################################## +def tstMoveOb(ob): # makes a simple LocRot animation of object in the scene + anim = [ + #Loc Rot/10 + # + ( 0,0,0, 0, 0, 0), #frame 1 origin + ( 1,0,0, 0, 0, 0), #frame 2 + ( 1,1,0, 0, 0, 0), + ( 1,1,1, 0, 0, 0), + ( 1,1,1,4.5, 0, 0), + ( 1,1,1,4.5,4.5, 0), + ( 1,1,1,4.5,4.5,4.5) + ] + space = COORD_LOCAL + ipo = createIpo(ob) #create an Ipo and curves for this object + ipos = getCurves(ipo) + + # span this motion over the currently set anim range + # to set points, i need time but do not know how it is computed, so will have to advance the animation + staframe,endframe,curframe = getRenderInfo() + + frame = staframe #x position of new ipo datapoint. set to staframe if you want a match + frameDelta=(endframe-staframe)/(len(anim)) #accomplish the animation in frame range + for key in anim: #effectively does a getLocRot() + #tell Blender to advace to frame + Blender.Set('curframe',frame) # computes the constrained location of the 'real' objects + time = Blender.Get('curtime') + + ipos = addPoint(time,key,ipos) #add this data at this time to the ipos + + debug(100,'%s %i %.3f %.2f %.2f %.2f %.2f %.2f %.2f' % (ipo.name, frame, time, key[0], key[1], key[2], key[3], key[4], key[5])) + frame += frameDelta + Blender.Set('curframe',curframe) # reset back to where we started + return +#================= +# Program Template +#================= +######################################## +def main(): + # return code set via rt button in Blender Buttons Scene Context Anim panel + + if MODE == 1: #create test armature #1 + ob = tstCreateArm() # make test arm and select it + tstMoveOb(ob) + scn.objects.selected = [ob] + + obs = Blender.Object.GetSelected() #scn.objects.selected + debug(20,'Baking %i objects' % len(obs)) + + if len(obs) >= 1: # user might have multiple objects selected + for ob in obs: + bake(ob) + else: + error('Please select at least one object') + return + +######################################## +def benchmark(): # This lets you benchmark (time) the script's running duration + + Window.WaitCursor(1) + t = sys.time() + debug(60,'%s began at %.0f' %(__script__,sys.time())) + + # Run the function on the active scene + in_editmode = Window.EditMode() + if in_editmode: Window.EditMode(0) + + main() + + if in_editmode: Window.EditMode(1) + + # Timing the script is a good way to be aware on any speed hits when scripting + debug(60,'%s Script finished in %.2f seconds' % (__script__,sys.time()-t) ) + Window.WaitCursor(0) + return + +######################################## +# This lets you can import the script without running it +if __name__ == '__main__': + debug(0, "------------------------------------") + debug(0, '%s %s Script begins with mode=%i debug=%i batch=%s version=%i' % (__script__,__version__,MODE,DEBUG,BATCH,BLENDER_VERSION)) + + benchmark() diff --git a/release/scripts/bpymodules/BPyArmature.py b/release/scripts/bpymodules/BPyArmature.py index d0b41dc35c5..63df02d080c 100644 --- a/release/scripts/bpymodules/BPyArmature.py +++ b/release/scripts/bpymodules/BPyArmature.py @@ -11,13 +11,19 @@ # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# Version History: +# 1.0 original release bakes an armature into a matrix +# 1.1 optional params (ACTION_BAKE, ACTION_BAKE_FIRST_FRAME, direct function to key and return the Action import Blender +from Blender import sys import bpy -def getBakedPoseData(ob_arm, start_frame, end_frame): +def getBakedPoseData(ob_arm, start_frame, end_frame, ACTION_BAKE = False, ACTION_BAKE_FIRST_FRAME = True): ''' If you are currently getting IPO's this function can be used to - return a list of frame aligned bone dictionary's + ACTION_BAKE==False: return a list of frame aligned bone dictionary's + ACTION_BAKE==True: return an action with keys aligned to bone constrained movement + if ACTION_BAKE_FIRST_FRAME is not supplied or is true: keys begin at frame 1 The data in these can be swaped in for the IPO loc and quat @@ -77,7 +83,13 @@ def getBakedPoseData(ob_arm, start_frame, end_frame): # --------------------------------- Main loop to collect IPO data frame_index = 0 + NvideoFrames= end_frame-start_frame for current_frame in xrange(start_frame, end_frame+1): + if frame_index==0: start=sys.time() + elif frame_index==15: print NvideoFrames*(sys.time()-start),"seconds estimated..." #slows as it grows *3 + elif frame_index >15: + percom= frame_index*100/NvideoFrames + print "Frame %i Overall %i percent complete\r" % (current_frame, percom), ob_arm.action = backup_action #pose.update() # not needed Blender.Set('curframe', current_frame) @@ -88,9 +100,7 @@ def getBakedPoseData(ob_arm, start_frame, end_frame): for index, parent_index, bone_name, rest_bone, rest_matrix, rest_matrix_inv, pose_bone, ipo in armature_bone_data: matrix= pose_bone.poseMatrix - parent_bone= rest_bone.parent - if parent_index != -1: parent_pose_matrix = armature_bone_data[parent_index][6].poseMatrix parent_bone_matrix_inv = armature_bone_data[parent_index][5] @@ -98,40 +108,45 @@ def getBakedPoseData(ob_arm, start_frame, end_frame): rest_matrix= rest_matrix * parent_bone_matrix_inv matrix=matrix * rest_matrix.copy().invert() - pose_bone.quat= matrix.toQuat() pose_bone.loc= matrix.translationPart() - pose_bone.insertKey(ob_arm, 1, POSE_XFORM) # always frame 1 + if ACTION_BAKE==False: + pose_bone.insertKey(ob_arm, 1, POSE_XFORM) # always frame 1 + + # THIS IS A BAD HACK! IT SUCKS BIGTIME BUT THE RESULT ARE NICE + # - use a temp action and bake into that, always at the same frame + # so as not to make big IPO's, then collect the result from the IPOs - # THIS IS A BAD HACK! IT SUCKS BIGTIME BUT THE RESULT ARE NICE - # - use a temp action and bake into that, always at the same frame - # so as not to make big IPO's, then collect the result from the IPOs + # Now get the data from the IPOs + if not ipo: ipo = armature_bone_data[index][7] = new_action.getChannelIpo(bone_name) - # Now get the data from the IPOs - if not ipo: ipo = armature_bone_data[index][7] = new_action.getChannelIpo(bone_name) + loc = Vector() + quat = Quaternion() - loc = Vector() - quat = Quaternion() + for curve in ipo: + val = curve.evaluate(1) + curve_name= curve.name + if curve_name == 'LocX': loc[0] = val + elif curve_name == 'LocY': loc[1] = val + elif curve_name == 'LocZ': loc[2] = val + elif curve_name == 'QuatW': quat[3] = val + elif curve_name == 'QuatX': quat[0] = val + elif curve_name == 'QuatY': quat[1] = val + elif curve_name == 'QuatZ': quat[2] = val - for curve in ipo: - val = curve.evaluate(1) - curve_name= curve.name - if curve_name == 'LocX': loc[0] = val - elif curve_name == 'LocY': loc[1] = val - elif curve_name == 'LocZ': loc[2] = val - elif curve_name == 'QuatW': quat[3] = val - elif curve_name == 'QuatX': quat[0] = val - elif curve_name == 'QuatY': quat[1] = val - elif curve_name == 'QuatZ': quat[2] = val - - bake_data[frame_index][bone_name] = loc, quat - - + bake_data[frame_index][bone_name] = loc, quat + else: + if ACTION_BAKE_FIRST_FRAME: pose_bone.insertKey(ob_arm, frame_index+1, POSE_XFORM) + else: pose_bone.insertKey(ob_arm, current_frame , POSE_XFORM) frame_index+=1 - + print "\nBaking Complete." ob_arm.action = backup_action - Blender.Set('curframe', backup_frame) - return bake_data + if ACTION_BAKE==False: + Blender.Set('curframe', backup_frame) + return bake_data + elif ACTION_BAKE==True: + return new_action + else: print "ERROR: Invalid ACTION_BAKE %i sent to BPyArmature" % ACTION_BAKE From b22d3e615d75232ba0ac3327acb4c1b0101e77a4 Mon Sep 17 00:00:00 2001 From: Martin Poirier Date: Sun, 22 Jun 2008 23:07:42 +0000 Subject: [PATCH 242/246] Moving Line to Line intersection into arithb --- source/blender/blenlib/BLI_arithb.h | 1 + source/blender/blenlib/intern/arithb.c | 68 +++++++++++++++++++++++ source/blender/python/api2_2x/Mathutils.c | 62 +++------------------ 3 files changed, 78 insertions(+), 53 deletions(-) diff --git a/source/blender/blenlib/BLI_arithb.h b/source/blender/blenlib/BLI_arithb.h index 4d277cf98e1..4fa880c36d1 100644 --- a/source/blender/blenlib/BLI_arithb.h +++ b/source/blender/blenlib/BLI_arithb.h @@ -374,6 +374,7 @@ void LocQuatSizeToMat4(float mat[][4], float loc[3], float quat[4], float size[3 void tubemap(float x, float y, float z, float *u, float *v); void spheremap(float x, float y, float z, float *u, float *v); +int LineIntersectLine(float v1[3], float v2[3], float v3[3], float v4[3], float i1[3], float i2[3]); int LineIntersectsTriangle(float p1[3], float p2[3], float v0[3], float v1[3], float v2[3], float *lambda, float *uv); int RayIntersectsTriangle(float p1[3], float d[3], float v0[3], float v1[3], float v2[3], float *lambda, float *uv); int SweepingSphereIntersectsTriangleUV(float p1[3], float p2[3], float radius, float v0[3], float v1[3], float v2[3], float *lambda, float *ipoint); diff --git a/source/blender/blenlib/intern/arithb.c b/source/blender/blenlib/intern/arithb.c index 322a9e6fd02..2084ab3da5f 100644 --- a/source/blender/blenlib/intern/arithb.c +++ b/source/blender/blenlib/intern/arithb.c @@ -4032,6 +4032,74 @@ int AxialLineIntersectsTriangle(int axis, float p1[3], float p2[3], float v0[3], return 1; } +/* Returns the number of point of interests + * 0 - lines are colinear + * 1 - lines are coplanar, i1 is set to intersection + * 2 - i1 and i2 are the nearest points on line 1 (v1, v2) and line 2 (v3, v4) respectively + * */ +int LineIntersectLine(float v1[3], float v2[3], float v3[3], float v4[3], float i1[3], float i2[3]) +{ + float a[3], b[3], c[3], ab[3], cb[3], dir1[3], dir2[3]; + float d; + + VecSubf(c, v3, v1); + VecSubf(a, v2, v1); + VecSubf(b, v4, v3); + + VecCopyf(dir1, a); + Normalize(dir1); + VecCopyf(dir2, b); + Normalize(dir2); + d = Inpf(dir1, dir2); + if (d == 1.0f || d == -1.0f) { + /* colinear */ + return 0; + } + + Crossf(ab, a, b); + d = Inpf(c, ab); + + /* test if the two lines are coplanar */ + if (d > -0.000001f && d < 0.000001f) { + Crossf(cb, c, b); + + VecMulf(a, Inpf(cb, ab) / Inpf(ab, ab)); + VecAddf(i1, v1, a); + VecCopyf(i2, i1); + + return 1; /* one intersection only */ + } + /* if not */ + else { + float n[3], t[3]; + float v3t[3], v4t[3]; + VecSubf(t, v1, v3); + + /* offset between both plane where the lines lies */ + Crossf(n, a, b); + Projf(t, t, n); + + /* for the first line, offset the second line until it is coplanar */ + VecAddf(v3t, v3, t); + VecAddf(v4t, v4, t); + + VecSubf(c, v3t, v1); + VecSubf(a, v2, v1); + VecSubf(b, v4t, v3); + + Crossf(ab, a, b); + Crossf(cb, c, b); + + VecMulf(a, Inpf(cb, ab) / Inpf(ab, ab)); + VecAddf(i1, v1, a); + + /* for the second line, just substract the offset from the first intersection point */ + VecSubf(i2, i1, t); + + return 2; /* two nearest points */ + } +} + int AabbIntersectAabb(float min1[3], float max1[3], float min2[3], float max2[3]) { return (min1[0]size == 3 || vec1->size == 2) { - float a[3], b[3], c[3], ab[3], cb[3], dir1[3], dir2[3]; - float d; + int result; + if (vec1->size == 3) { VECCOPY(v1, vec1->vec); VECCOPY(v2, vec2->vec); @@ -1477,63 +1477,19 @@ PyObject *M_Mathutils_LineIntersect( PyObject * self, PyObject * args ) v4[1] = vec4->vec[1]; v4[2] = 0.0f; } + + result = LineIntersectLine(v1, v2, v3, v4, i1, i2); - VecSubf(c, v3, v1); - VecSubf(a, v2, v1); - VecSubf(b, v4, v3); - - VECCOPY(dir1, a); - Normalize(dir1); - VECCOPY(dir2, b); - Normalize(dir2); - d = Inpf(dir1, dir2); - if (d == 1.0f || d == -1.0f) { + if (result == 0) { /* colinear */ return EXPP_incr_ret( Py_None ); } - - Crossf(ab, a, b); - d = Inpf(c, ab); - - /* test if the two lines are coplanar */ - if (d > -0.000001f && d < 0.000001f) { - Crossf(cb, c, b); - - VecMulf(a, Inpf(cb, ab) / Inpf(ab, ab)); - VecAddf(i1, v1, a); - VECCOPY(i2, i1); - } - /* if not */ else { - float n[3], t[3]; - VecSubf(t, v1, v3); - - /* offset between both plane where the lines lies */ - Crossf(n, a, b); - Projf(t, t, n); - - /* for the first line, offset the second line until it is coplanar */ - VecAddf(v3, v3, t); - VecAddf(v4, v4, t); - - VecSubf(c, v3, v1); - VecSubf(a, v2, v1); - VecSubf(b, v4, v3); - - Crossf(ab, a, b); - Crossf(cb, c, b); - - VecMulf(a, Inpf(cb, ab) / Inpf(ab, ab)); - VecAddf(i1, v1, a); - - /* for the second line, just substract the offset from the first intersection point */ - VecSubf(i2, i1, t); + tuple = PyTuple_New( 2 ); + PyTuple_SetItem( tuple, 0, newVectorObject(i1, vec1->size, Py_NEW) ); + PyTuple_SetItem( tuple, 1, newVectorObject(i2, vec1->size, Py_NEW) ); + return tuple; } - - tuple = PyTuple_New( 2 ); - PyTuple_SetItem( tuple, 0, newVectorObject(i1, vec1->size, Py_NEW) ); - PyTuple_SetItem( tuple, 1, newVectorObject(i2, vec1->size, Py_NEW) ); - return tuple; } else { return ( EXPP_ReturnPyObjError( PyExc_TypeError, From 7a55f52b1bddc389dca1d456dafb79751abcc9c1 Mon Sep 17 00:00:00 2001 From: Martin Poirier Date: Sun, 22 Jun 2008 23:21:29 +0000 Subject: [PATCH 243/246] Transform Snapping Snap to edges and vertice without have to go through faces. This means you can import floor plans and use the edges as snapping guides and other sort of fun things. The bounding box test still needs padding though. --- source/blender/src/transform_snap.c | 569 ++++++++++++++++------------ 1 file changed, 337 insertions(+), 232 deletions(-) diff --git a/source/blender/src/transform_snap.c b/source/blender/src/transform_snap.c index 04ca5b08755..d16308f17ae 100644 --- a/source/blender/src/transform_snap.c +++ b/source/blender/src/transform_snap.c @@ -737,136 +737,6 @@ void TargetSnapClosest(TransInfo *t) } /*================================================================*/ - -/* find snapping point on face, return 1 on success */ -int snapFace(MFace *face, EditFace *efa, MVert *verts, float *intersect, float *loc, float *no) -{ - MVert *v[4]; - EditVert *eve[4]; - int totvert; - int result = 0; - - v[0] = verts + face->v1; - v[1] = verts + face->v2; - v[2] = verts + face->v3; - - if (face->v4) - { - v[3] = verts + face->v4; - totvert = 4; - } - else - { - v[3] = NULL; - totvert = 3; - } - - if (efa) - { - eve[0] = efa->v1; - eve[1] = efa->v2; - eve[2] = efa->v3; - eve[3] = efa->v4; - } - - switch(G.scene->snap_mode) - { - case SCE_SNAP_MODE_VERTEX: - { - float min_dist = FLT_MAX; - int i; - - for(i = 0; i < totvert; i++) - { - - if (efa == NULL || (eve[i]->f1 & SELECT) == 0) - { - float vert_dist = VecLenf(v[i]->co, intersect); - - if (vert_dist < min_dist) - { - result = 1; - - min_dist = vert_dist; - - VECCOPY(loc, v[i]->co); - NormalShortToFloat(no, v[i]->no); - } - } - } - break; - } - case SCE_SNAP_MODE_EDGE: - { - float min_dist = FLT_MAX; - int i; - - for(i = 0; i < totvert; i++) - { - MVert *v1, *v2; - EditVert *eve1, *eve2; - - v1 = v[i]; - v2 = v[(i + 1) % totvert]; - - eve1 = eve[i]; - eve2 = eve[(i + 1) % totvert]; - - if (efa == NULL || ((eve1->f1 & SELECT) == 0 && (eve2->f1 & SELECT) == 0)) - { - float edge_loc[3]; - float vec[3]; - float mul; - float edge_dist; - - VecSubf(edge_loc, v2->co, v1->co); - VecSubf(vec, intersect, v1->co); - - mul = Inpf(vec, edge_loc) / Inpf(edge_loc, edge_loc); - - VecMulf(edge_loc, mul); - VecAddf(edge_loc, edge_loc, v1->co); - - edge_dist = VecLenf(edge_loc, intersect); - - if (edge_dist < min_dist) - { - float n1[3], n2[3]; - result = 1; - - min_dist = edge_dist; - - VECCOPY(loc, edge_loc); - - NormalShortToFloat(n1, v1->no); - NormalShortToFloat(n2, v2->no); - VecLerpf(no, n1, n2, mul); - Normalize(no); - } - } - } - break; - } - case SCE_SNAP_MODE_FACE: - { - if (efa == NULL || ((efa->f1 & SELECT) == 0)) - { - result = 1; - - VECCOPY(loc, intersect); - - if (totvert == 4) - CalcNormFloat4(v[0]->co, v[1]->co, v[2]->co, v[3]->co, no); - else - CalcNormFloat(v[0]->co, v[1]->co, v[2]->co, no); - } - break; - } - } - - return result; -} - int snapDerivedMesh(Object *ob, DerivedMesh *dm, float obmat[][4], float ray_start[3], float ray_normal[3], short mval[2], float *loc, float *no, int *dist, float *depth, short EditMesh) { int retval = 0; @@ -891,7 +761,7 @@ int snapDerivedMesh(Object *ob, DerivedMesh *dm, float obmat[][4], float ray_sta Mat4Mul3Vecfl(imat, ray_normal_local); - /* If number of vert is more than an arbitrary limit, + /* If number of vert is more than an arbitrary limit, * test against boundbox first * */ if (totface > 16) { @@ -900,117 +770,83 @@ int snapDerivedMesh(Object *ob, DerivedMesh *dm, float obmat[][4], float ray_sta } if (test == 1) { - MVert *verts = dm->getVertArray(dm); - MFace *faces = dm->getFaceArray(dm); - int *index_array = NULL; - int index = 0; - int i; - if (EditMesh) + switch (G.scene->snap_mode) { - index_array = dm->getFaceDataArray(dm, CD_ORIGINDEX); - EM_init_index_arrays(0, 0, 1); - } - - for( i = 0; i < totface; i++) { - EditFace *efa = NULL; - MFace *f = faces + i; - float lambda; - int result; - - test = 1; /* reset for every face */ - - if (EditMesh) - { - if (index_array) + case SCE_SNAP_MODE_FACE: + { + MVert *verts = dm->getVertArray(dm); + MFace *faces = dm->getFaceArray(dm); + int *index_array = NULL; + int index = 0; + int i; + + if (EditMesh) { - index = index_array[i]; - } - else - { - index = i; + index_array = dm->getFaceDataArray(dm, CD_ORIGINDEX); + EM_init_index_arrays(0, 0, 1); } - if (index == ORIGINDEX_NONE) - { - test = 0; - } - else - { - efa = EM_get_face_for_index(index); + for( i = 0; i < totface; i++) { + EditFace *efa = NULL; + MFace *f = faces + i; + float lambda; + int result; - if (efa && efa->f1 & SELECT) + test = 1; /* reset for every face */ + + if (EditMesh) { - test = 0; - } - } - } - - - if (test) - { - result = RayIntersectsTriangle(ray_start_local, ray_normal_local, verts[f->v1].co, verts[f->v2].co, verts[f->v3].co, &lambda, NULL); - - if (result) { - float location[3], normal[3]; - float intersect[3]; - - VECCOPY(intersect, ray_normal_local); - VecMulf(intersect, lambda); - VecAddf(intersect, intersect, ray_start_local); - - if (snapFace(f, efa, verts, intersect, location, normal)) - { - float new_depth; - int screen_loc[2]; - int new_dist; - - Mat4MulVecfl(obmat, location); - - new_depth = VecLenf(location, ray_start); - - project_int(location, screen_loc); - new_dist = abs(screen_loc[0] - mval[0]) + abs(screen_loc[1] - mval[1]); - - if (new_dist <= *dist && new_depth < *depth) + if (index_array) { - *depth = new_depth; - retval = 1; - - VECCOPY(loc, location); - VECCOPY(no, normal); - - Mat3MulVecfl(timat, no); - Normalize(no); - - project_int(loc, screen_loc); - - *dist = new_dist; - } - } - } - - if (f->v4 && result == 0) - { - result = RayIntersectsTriangle(ray_start_local, ray_normal_local, verts[f->v3].co, verts[f->v4].co, verts[f->v1].co, &lambda, NULL); - - if (result) { - float location[3], normal[3]; - float intersect[3]; + index = index_array[i]; + } + else + { + index = i; + } - VECCOPY(intersect, ray_normal_local); - VecMulf(intersect, lambda); - VecAddf(intersect, intersect, ray_start_local); - - if (snapFace(f, efa, verts, intersect, location, normal)) - { + if (index == ORIGINDEX_NONE) + { + test = 0; + } + else + { + efa = EM_get_face_for_index(index); + + if (efa && efa->f & SELECT) + { + test = 0; + } + } + } + + + if (test) + { + result = RayIntersectsTriangle(ray_start_local, ray_normal_local, verts[f->v1].co, verts[f->v2].co, verts[f->v3].co, &lambda, NULL); + + if (result) { + float location[3], normal[3]; + float intersect[3]; float new_depth; int screen_loc[2]; int new_dist; + VECCOPY(intersect, ray_normal_local); + VecMulf(intersect, lambda); + VecAddf(intersect, intersect, ray_start_local); + + VECCOPY(location, intersect); + + if (f->v4) + CalcNormFloat4(verts[f->v1].co, verts[f->v2].co, verts[f->v3].co, verts[f->v4].co, normal); + else + CalcNormFloat(verts[f->v1].co, verts[f->v2].co, verts[f->v3].co, normal); + Mat4MulVecfl(obmat, location); - new_depth = VecLenf(location, ray_start); + new_depth = VecLenf(location, ray_start); project_int(location, screen_loc); new_dist = abs(screen_loc[0] - mval[0]) + abs(screen_loc[1] - mval[1]); @@ -1029,14 +865,283 @@ int snapDerivedMesh(Object *ob, DerivedMesh *dm, float obmat[][4], float ray_sta *dist = new_dist; } } + + if (f->v4 && result == 0) + { + result = RayIntersectsTriangle(ray_start_local, ray_normal_local, verts[f->v3].co, verts[f->v4].co, verts[f->v1].co, &lambda, NULL); + + if (result) { + float location[3], normal[3]; + float intersect[3]; + float new_depth; + int screen_loc[2]; + int new_dist; + + VECCOPY(intersect, ray_normal_local); + VecMulf(intersect, lambda); + VecAddf(intersect, intersect, ray_start_local); + + VECCOPY(location, intersect); + + if (f->v4) + CalcNormFloat4(verts[f->v1].co, verts[f->v2].co, verts[f->v3].co, verts[f->v4].co, normal); + else + CalcNormFloat(verts[f->v1].co, verts[f->v2].co, verts[f->v3].co, normal); + + Mat4MulVecfl(obmat, location); + + new_depth = VecLenf(location, ray_start); + + project_int(location, screen_loc); + new_dist = abs(screen_loc[0] - mval[0]) + abs(screen_loc[1] - mval[1]); + + if (new_dist <= *dist && new_depth < *depth) + { + *depth = new_depth; + retval = 1; + + VECCOPY(loc, location); + VECCOPY(no, normal); + + Mat3MulVecfl(timat, no); + Normalize(no); + + *dist = new_dist; + } + } + } } } + + if (EditMesh) + { + EM_free_index_arrays(); + } + break; + } + case SCE_SNAP_MODE_VERTEX: + { + MVert *verts = dm->getVertArray(dm); + int *index_array = NULL; + int index = 0; + int i; + + if (EditMesh) + { + index_array = dm->getVertDataArray(dm, CD_ORIGINDEX); + EM_init_index_arrays(1, 0, 0); + } + + for( i = 0; i < totvert; i++) { + EditVert *eve = NULL; + MVert *v = verts + i; + + test = 1; /* reset for every vert */ + + if (EditMesh) + { + if (index_array) + { + index = index_array[i]; + } + else + { + index = i; + } + + if (index == ORIGINDEX_NONE) + { + test = 0; + } + else + { + eve = EM_get_vert_for_index(index); + + if (eve && eve->f & SELECT) + { + test = 0; + } + } + } + + + if (test) + { + float dvec[3]; + + VecSubf(dvec, v->co, ray_start_local); + + if (Inpf(ray_normal_local, dvec) > 0) + { + float location[3]; + float new_depth; + int screen_loc[2]; + int new_dist; + + VECCOPY(location, v->co); + + Mat4MulVecfl(obmat, location); + + new_depth = VecLenf(location, ray_start); + + project_int(location, screen_loc); + new_dist = abs(screen_loc[0] - mval[0]) + abs(screen_loc[1] - mval[1]); + + if (new_dist <= *dist && new_depth < *depth) + { + *depth = new_depth; + retval = 1; + + VECCOPY(loc, location); + + NormalShortToFloat(no, v->no); + Mat3MulVecfl(timat, no); + Normalize(no); + + *dist = new_dist; + } + } + } + } + + if (EditMesh) + { + EM_free_index_arrays(); + } + break; + } + case SCE_SNAP_MODE_EDGE: + { + MVert *verts = dm->getVertArray(dm); + MEdge *edges = dm->getEdgeArray(dm); + int totedge = dm->getNumEdges(dm); + int *index_array = NULL; + int index = 0; + int i; + + if (EditMesh) + { + index_array = dm->getEdgeDataArray(dm, CD_ORIGINDEX); + EM_init_index_arrays(0, 1, 0); + } + + for( i = 0; i < totedge; i++) { + EditEdge *eed = NULL; + MEdge *e = edges + i; + + test = 1; /* reset for every vert */ + + if (EditMesh) + { + if (index_array) + { + index = index_array[i]; + } + else + { + index = i; + } + + if (index == ORIGINDEX_NONE) + { + test = 0; + } + else + { + eed = EM_get_edge_for_index(index); + + if (eed && ((eed->v1->f & SELECT) || (eed->v2->f & SELECT))) + { + test = 0; + } + } + } + + + if (test) + { + float intersect[3] = {0, 0, 0}, ray_end[3], dvec[3]; + int result; + + VECCOPY(ray_end, ray_normal_local); + VecMulf(ray_end, 2000); + VecAddf(ray_end, ray_start_local, ray_end); + + result = LineIntersectLine(verts[e->v1].co, verts[e->v2].co, ray_start_local, ray_end, intersect, dvec); /* dvec used but we don't care about result */ + + if (result) + { + float edge_loc[3], vec[3]; + float mul; + + /* check for behind ray_start */ + VecSubf(dvec, intersect, ray_start_local); + + VecSubf(edge_loc, verts[e->v1].co, verts[e->v2].co); + VecSubf(vec, intersect, verts[e->v2].co); + + mul = Inpf(vec, edge_loc) / Inpf(edge_loc, edge_loc); + + if (mul > 1) { + mul = 1; + VECCOPY(intersect, verts[e->v1].co); + } + else if (mul < 0) { + mul = 0; + VECCOPY(intersect, verts[e->v2].co); + } + + if (Inpf(ray_normal_local, dvec) > 0) + { + float location[3]; + float new_depth; + int screen_loc[2]; + int new_dist; + + VECCOPY(location, intersect); + + Mat4MulVecfl(obmat, location); + + new_depth = VecLenf(location, ray_start); + + project_int(location, screen_loc); + new_dist = abs(screen_loc[0] - mval[0]) + abs(screen_loc[1] - mval[1]); + + if (new_dist <= *dist && new_depth < *depth) + { + float n1[3], n2[3]; + + *depth = new_depth; + retval = 1; + + VecSubf(edge_loc, verts[e->v1].co, verts[e->v2].co); + VecSubf(vec, intersect, verts[e->v2].co); + + mul = Inpf(vec, edge_loc) / Inpf(edge_loc, edge_loc); + + NormalShortToFloat(n1, verts[e->v1].no); + NormalShortToFloat(n2, verts[e->v2].no); + VecLerpf(no, n2, n1, mul); + Normalize(no); + + VECCOPY(loc, location); + + Mat3MulVecfl(timat, no); + Normalize(no); + + *dist = new_dist; + } + } + } + } + } + + if (EditMesh) + { + EM_free_index_arrays(); + } + break; } - } - - if (EditMesh) - { - EM_free_index_arrays(); } } } From fcc377e204bd1cb3d474c1e3bbb5e0ae7f267cff Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 23 Jun 2008 00:21:49 +0000 Subject: [PATCH 244/246] [#13635] DirectX8Exporter with vertex colors patch from Masaru Nemoto (mnemoto) Made some modifications to the patch, use reduce() to get total face verts and some speedup for face vcol looping, also don't write vcol alpha since its used by brushes internally and has no useful meaning. --- release/scripts/DirectX8Exporter.py | 34 ++++++++++++++++++++++++++--- 1 file changed, 31 insertions(+), 3 deletions(-) diff --git a/release/scripts/DirectX8Exporter.py b/release/scripts/DirectX8Exporter.py index 2ec42057039..01212545f77 100644 --- a/release/scripts/DirectX8Exporter.py +++ b/release/scripts/DirectX8Exporter.py @@ -6,9 +6,9 @@ # Group: 'Export' # Tooltip: 'Export to DirectX text file format format for XNA Animation Component Library.' """ -__author__ = "minahito (original:Arben (Ben) Omari)" -__url__ = ("blender", "blenderartists.org", "Adjuster's site http://sunday-lab.blogspot.com/, Author's site http://www.omariben.too.it") -__version__ = "3.0" +__author__ = "vertex color exporting feature is added by mnemoto (original:minahito (original:Arben (Ben) Omari))" +__url__ = ("blender", "elysiun", "Adjuster's site http://sunday-lab.blogspot.com/, Author's site http://www.omariben.too.it","Adjuster's site http://ex.homeunix.net/") +__version__ = "3.1" __bpydoc__ = """\ This script exports a Blender mesh with armature to DirectX 8's text file @@ -444,6 +444,7 @@ class xExport: self.writeMeshMaterialList(obj, mesh, tex) self.writeMeshNormals(obj, mesh) self.writeMeshTextureCoords(obj, mesh) + self.writeMeshVertexColors(obj, mesh) self.file.write(" } // End of the Mesh %s \n" % (obj.name)) @@ -464,6 +465,7 @@ class xExport: self.writeMeshMaterialList(obj, mesh, tex) self.writeMeshNormals(obj, mesh) self.writeMeshTextureCoords(obj, mesh) + self.writeMeshVertexColors(obj, mesh) self.file.write(" }\n") self.file.write("}\n") ind = objs.index(obj) @@ -1047,6 +1049,32 @@ template SkinWeights {\n\ self.file.write(",\n") self.file.write("} //End of MeshTextureCoords\n") + + #*********************************************** + #MESH VORTEX COLORS + #*********************************************** + def writeMeshVertexColors(self, name, mesh): + if mesh.hasVertexColours(): + self.file.write("MeshVertexColors {\n") + #VERTICES NUMBER + numvert = reduce( lambda i,f: len(f)+i, mesh.faces, 0) + self.file.write("%d;\n" % (numvert)) + #VERTEX COLORS + + vcounter =0 + for f in mesh.faces: + col = f.col + for i,c in enumerate(col): + # Note vcol alpha has no meaning + self.file.write("%d;%f;%f;%f;%f;" % (vcounter,c.r/255.0, c.g/255.0, c.b/255.0, 1.0)) # c.a/255.0)) + vcounter+=1 + if vcounter == numvert : + self.file.write(";\n") + else : + self.file.write(",\n") + + self.file.write("} //End of MeshVertexColors\n") + #***********************************************#***********************************************#*********************************************** #*********************************************** #FRAMES From cb6fd8927cbdc12b299a1ccaea4321ddf162dd4d Mon Sep 17 00:00:00 2001 From: Joseph Eagar Date: Mon, 23 Jun 2008 07:59:26 +0000 Subject: [PATCH 245/246] An initializer line was missing from the beginning of a loop, causing crashes. --- source/blender/blenkernel/intern/particle_system.c | 1 + 1 file changed, 1 insertion(+) diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c index f06ef221795..458171cc232 100644 --- a/source/blender/blenkernel/intern/particle_system.c +++ b/source/blender/blenkernel/intern/particle_system.c @@ -2596,6 +2596,7 @@ static void precalc_effectors(Object *ob, ParticleSystem *psys, ParticleSystemMo for(ec= lb->first; ec; ec= ec->next) { PartDeflect *pd= ec->ob->pd; + co = NULL; if(ec->type==PSYS_EC_EFFECTOR && pd->forcefield==PFIELD_GUIDE && ec->ob->type==OB_CURVE && part->phystype!=PART_PHYS_BOIDS) { From 75e22a1917fb638a67d475b224cb6e368e821783 Mon Sep 17 00:00:00 2001 From: Benoit Bolsee Date: Mon, 23 Jun 2008 15:32:44 +0000 Subject: [PATCH 246/246] BGE patch #14386: Action Actuator Current Frame Prop. This patch is very usefull for action feedback logic: a sensor on the property can be used to detect a certain moment in the action and trigger more stuff. The property must be on float type for best results --- source/blender/makesdna/DNA_actuator_types.h | 1 + source/blender/src/buttons_logic.c | 23 +++++---- .../Converter/BL_ActionActuator.cpp | 49 +++++++++++++++++++ .../gameengine/Converter/BL_ActionActuator.h | 7 ++- .../Converter/KX_ConvertActuators.cpp | 2 + 5 files changed, 71 insertions(+), 11 deletions(-) diff --git a/source/blender/makesdna/DNA_actuator_types.h b/source/blender/makesdna/DNA_actuator_types.h index 417ba540e2c..70d603a6ed9 100644 --- a/source/blender/makesdna/DNA_actuator_types.h +++ b/source/blender/makesdna/DNA_actuator_types.h @@ -50,6 +50,7 @@ typedef struct bActionActuator { short type, flag; /* Playback type */ int sta, end; /* Start & End frames */ char name[32]; /* For property-driven playback */ + char frameProp[32]; /* Set this property to the actions current frame */ int blendin; /* Number of frames of blending */ short priority; /* Execution priority */ short strideaxis; /* Displacement axis */ diff --git a/source/blender/src/buttons_logic.c b/source/blender/src/buttons_logic.c index c4fc17bc4d0..e7933c10162 100644 --- a/source/blender/src/buttons_logic.c +++ b/source/blender/src/buttons_logic.c @@ -1673,31 +1673,34 @@ static short draw_actuatorbuttons(Object *ob, bActuator *act, uiBlock *block, sh #else str= "Action types %t|Play %x0|Flipper %x2|Loop Stop %x3|Loop End %x4|Property %x6"; #endif - uiDefButS(block, MENU, B_REDR, str, xco+30, yco-24, width-60, 19, &aa->type, 0.0, 0.0, 0.0, 0.0, "Action playback type"); - uiDefIDPoinBut(block, test_actionpoin_but, ID_AC, 1, "AC: ", xco+30, yco-44, width-60, 19, &aa->act, "Action name"); + uiDefButS(block, MENU, B_REDR, str, xco+30, yco-24, (width-60)/2, 19, &aa->type, 0.0, 0.0, 0.0, 0.0, "Action playback type"); + uiDefIDPoinBut(block, test_actionpoin_but, ID_AC, 1, "AC: ", xco+30 + ((width-60)/2), yco-24, (width-60)/2, 19, &aa->act, "Action name"); if(aa->type == ACT_ACTION_FROM_PROP) { - uiDefBut(block, TEX, 0, "Prop: ",xco+30, yco-64, width-60, 19, aa->name, 0.0, 31.0, 0, 0, "Use this property to define the Action position"); + uiDefBut(block, TEX, 0, "Prop: ",xco+30, yco-44, width-60, 19, aa->name, 0.0, 31.0, 0, 0, "Use this property to define the Action position"); } else { - uiDefButI(block, NUM, 0, "Sta: ",xco+30, yco-64, (width-60)/2, 19, &aa->sta, 0.0, MAXFRAMEF, 0, 0, "Start frame"); - uiDefButI(block, NUM, 0, "End: ",xco+30+(width-60)/2, yco-64, (width-60)/2, 19, &aa->end, 0.0, MAXFRAMEF, 0, 0, "End frame"); + uiDefButI(block, NUM, 0, "Sta: ",xco+30, yco-44, (width-60)/2, 19, &aa->sta, 0.0, MAXFRAMEF, 0, 0, "Start frame"); + uiDefButI(block, NUM, 0, "End: ",xco+30+(width-60)/2, yco-44, (width-60)/2, 19, &aa->end, 0.0, MAXFRAMEF, 0, 0, "End frame"); } + + uiDefButI(block, NUM, 0, "Blendin: ", xco+30, yco-64, (width-60)/2, 19, &aa->blendin, 0.0, MAXFRAMEF, 0.0, 0.0, "Number of frames of motion blending"); + uiDefButS(block, NUM, 0, "Priority: ", xco+30+(width-60)/2, yco-64, (width-60)/2, 19, &aa->priority, 0.0, 100.0, 0.0, 0.0, "Execution priority - lower numbers will override actions with higher numbers"); - - - uiDefButI(block, NUM, 0, "Blendin: ", xco+30, yco-84, (width-60)/2, 19, &aa->blendin, 0.0, MAXFRAMEF, 0.0, 0.0, "Number of frames of motion blending"); - uiDefButS(block, NUM, 0, "Priority: ", xco+30+(width-60)/2, yco-84, (width-60)/2, 19, &aa->priority, 0.0, 100.0, 0.0, 0.0, "Execution priority - lower numbers will override actions with higher numbers"); + uiDefBut(block, TEX, 0, "FrameProp: ",xco+30, yco-84, width-60, 19, aa->frameProp, 0.0, 31.0, 0, 0, "Assign this property this actions current frame number"); + #ifdef __NLA_ACTION_BY_MOTION_ACTUATOR if(aa->type == ACT_ACTION_MOTION) { - uiDefButF(block, NUM, 0, "Cycle: ",xco+30, yco-104, (width-60)/2, 19, &aa->stridelength, 0.0, 2500.0, 0, 0, "Distance covered by a single cycle of the action"); + uiDefButF(block, NUM, 0, "Cycle: ",xco+30, yco-84, (width-60)/2, 19, &aa->stridelength, 0.0, 2500.0, 0, 0, "Distance covered by a single cycle of the action"); } #endif + + yco-=ysize; break; } diff --git a/source/gameengine/Converter/BL_ActionActuator.cpp b/source/gameengine/Converter/BL_ActionActuator.cpp index ad126ebf123..83be5d3a14f 100644 --- a/source/gameengine/Converter/BL_ActionActuator.cpp +++ b/source/gameengine/Converter/BL_ActionActuator.cpp @@ -49,6 +49,7 @@ #include "BLI_arithb.h" #include "MT_Matrix4x4.h" #include "BKE_utildefines.h" +#include "FloatValue.h" #ifdef HAVE_CONFIG_H #include @@ -348,6 +349,18 @@ bool BL_ActionActuator::Update(double curtime, bool frame) break; } + /* Set the property if its defined */ + if (m_framepropname) { + CValue* propowner = GetParent(); + CValue* oldprop = propowner->GetProperty(m_framepropname); + CValue* newval = new CFloatValue(m_localtime); + if (oldprop) { + oldprop->SetValue(newval); + } else { + propowner->SetProperty(m_framepropname, newval); + } + newval->Release(); + } if (bNegativeEvent) m_blendframe=0.0; @@ -446,6 +459,7 @@ PyMethodDef BL_ActionActuator::Methods[] = { {"setPriority", (PyCFunction) BL_ActionActuator::sPySetPriority, METH_VARARGS, SetPriority_doc}, {"setFrame", (PyCFunction) BL_ActionActuator::sPySetFrame, METH_VARARGS, SetFrame_doc}, {"setProperty", (PyCFunction) BL_ActionActuator::sPySetProperty, METH_VARARGS, SetProperty_doc}, + {"setFrameProperty", (PyCFunction) BL_ActionActuator::sPySetFrameProperty, METH_VARARGS, SetFrameProperty_doc}, {"setBlendtime", (PyCFunction) BL_ActionActuator::sPySetBlendtime, METH_VARARGS, SetBlendtime_doc}, {"getAction", (PyCFunction) BL_ActionActuator::sPyGetAction, METH_VARARGS, GetAction_doc}, @@ -455,6 +469,7 @@ PyMethodDef BL_ActionActuator::Methods[] = { {"getPriority", (PyCFunction) BL_ActionActuator::sPyGetPriority, METH_VARARGS, GetPriority_doc}, {"getFrame", (PyCFunction) BL_ActionActuator::sPyGetFrame, METH_VARARGS, GetFrame_doc}, {"getProperty", (PyCFunction) BL_ActionActuator::sPyGetProperty, METH_VARARGS, GetProperty_doc}, + {"getFrameProperty", (PyCFunction) BL_ActionActuator::sPyGetFrameProperty, METH_VARARGS, GetFrameProperty_doc}, {"setChannel", (PyCFunction) BL_ActionActuator::sPySetChannel, METH_VARARGS, SetChannel_doc}, // {"getChannel", (PyCFunction) BL_ActionActuator::sPyGetChannel, METH_VARARGS}, {"getType", (PyCFunction) BL_ActionActuator::sPyGetType, METH_VARARGS, GetType_doc}, @@ -502,6 +517,21 @@ PyObject* BL_ActionActuator::PyGetProperty(PyObject* self, return result; } +/* getProperty */ +char BL_ActionActuator::GetFrameProperty_doc[] = +"getFrameProperty()\n" +"\tReturns the name of the property, that is set to the current frame number.\n"; + +PyObject* BL_ActionActuator::PyGetFrameProperty(PyObject* self, + PyObject* args, + PyObject* kwds) { + PyObject *result; + + result = Py_BuildValue("s", (const char *)m_framepropname); + + return result; +} + /* getFrame */ char BL_ActionActuator::GetFrame_doc[] = "getFrame()\n" @@ -763,6 +793,25 @@ PyObject* BL_ActionActuator::PySetProperty(PyObject* self, return Py_None; } +/* setFrameProperty */ +char BL_ActionActuator::SetFrameProperty_doc[] = +"setFrameProperty(prop)\n" +"\t - prop : A string specifying the property of the frame set up update.\n"; + +PyObject* BL_ActionActuator::PySetFrameProperty(PyObject* self, + PyObject* args, + PyObject* kwds) { + char *string; + + if (PyArg_ParseTuple(args,"s",&string)) + { + m_framepropname = string; + } + + Py_INCREF(Py_None); + return Py_None; +} + /* PyObject* BL_ActionActuator::PyGetChannel(PyObject* self, PyObject* args, diff --git a/source/gameengine/Converter/BL_ActionActuator.h b/source/gameengine/Converter/BL_ActionActuator.h index 62edcc7fad7..190f727c9c3 100644 --- a/source/gameengine/Converter/BL_ActionActuator.h +++ b/source/gameengine/Converter/BL_ActionActuator.h @@ -40,6 +40,7 @@ public: Py_Header; BL_ActionActuator(SCA_IObject* gameobj, const STR_String& propname, + const STR_String& framepropname, float starttime, float endtime, struct bAction *action, @@ -67,7 +68,8 @@ public: m_blendpose(NULL), m_userpose(NULL), m_action(action), - m_propname(propname) + m_propname(propname), + m_framepropname(framepropname) { }; virtual ~BL_ActionActuator(); @@ -84,6 +86,7 @@ public: KX_PYMETHOD_DOC(BL_ActionActuator,SetEnd); KX_PYMETHOD_DOC(BL_ActionActuator,SetFrame); KX_PYMETHOD_DOC(BL_ActionActuator,SetProperty); + KX_PYMETHOD_DOC(BL_ActionActuator,SetFrameProperty); KX_PYMETHOD_DOC(BL_ActionActuator,SetBlendtime); KX_PYMETHOD_DOC(BL_ActionActuator,SetChannel); @@ -94,6 +97,7 @@ public: KX_PYMETHOD_DOC(BL_ActionActuator,GetEnd); KX_PYMETHOD_DOC(BL_ActionActuator,GetFrame); KX_PYMETHOD_DOC(BL_ActionActuator,GetProperty); + KX_PYMETHOD_DOC(BL_ActionActuator,GetFrameProperty); // KX_PYMETHOD(BL_ActionActuator,GetChannel); KX_PYMETHOD_DOC(BL_ActionActuator,GetType); KX_PYMETHOD_DOC(BL_ActionActuator,SetType); @@ -138,6 +142,7 @@ protected: struct bPose* m_userpose; struct bAction *m_action; STR_String m_propname; + STR_String m_framepropname; }; enum { diff --git a/source/gameengine/Converter/KX_ConvertActuators.cpp b/source/gameengine/Converter/KX_ConvertActuators.cpp index c02c2a29595..89e2925a6c1 100644 --- a/source/gameengine/Converter/KX_ConvertActuators.cpp +++ b/source/gameengine/Converter/KX_ConvertActuators.cpp @@ -178,10 +178,12 @@ void BL_ConvertActuators(char* maggiename, if (blenderobject->type==OB_ARMATURE){ bActionActuator* actact = (bActionActuator*) bact->data; STR_String propname = (actact->name ? actact->name : ""); + STR_String propframe = (actact->frameProp ? actact->frameProp : ""); BL_ActionActuator* tmpbaseact = new BL_ActionActuator( gameobj, propname, + propframe, actact->sta, actact->end, actact->act,